ZAMYLA CHAN: All right, everyone.
Welcome to Walkthrough 1.
This Walkthrough will be on pset 1, which is C. I hope you
all had fun with your Scratch projects.
So now in this Walkthrough, we're actually going to be
able to get into C, get into writing some machine code.
So if you weren't at Walkthrough 0, then these
Walkthroughs really-- we're going to walk through the
problem set, talk through some common tips and techniques
that you can use.
We'll break the assignment up into manageable bites, so that
you guys can get started and hopefully
understand how to do it.
OK.
So pset 1.
The psets this year will have a structure where the first--
there's going to be a section of questions, a series of
questions that will really also help you get started with
the pset, help you practice some techniques that you need.
And so these questions, I'm not going to cover in the
Walkthrough because in your section your assigned teaching
fellow is actually going to walk through those
questions with you.
At the end of your section, you'll walk away with the
answers to those questions but also with the confidence that
you can implement some of the features that you will need
for the latter parts of the pset.
Pset 1 constitutes Mario.
And that's a fun little program where essentially we
write and print a half pyramid in the typical Mario scene.
And then the second part of the pset is called Greedy.
And so in Greedy we essentially act as a greedy
cashier, where if someone gives us an amount of money
that we want, we calculate the minimum amount of coins that
we can return to them to still give them that amount.
All right.
So every Walkthrough will have a toolbox.
And again, you might not use all of the tools in this
toolbox or you might use all of them.
In any case, it's really good to know what
you're equipped with.
So we have the CS50 Appliance, which I'll show you guys and
introduce you to that.
Then also in general good style is definitely one of our
most important tools.
Style essentially pertains to, how readable is your code?
When someone else goes and reads your code, do they have
an easy time?
Can they understand it?
Is it elegant?
Then we'll talk about how to get valid user input in your
program because in both Mario and in Greedy, you'll need to
ask the user to input and give you some kind of number.
So then we want to make sure that number is valid.
Then remember in Scratch we had blocks such as repeat,
repeat until, or wait, or forever.
So we're going to kind of translate that into C now and
look at loops such as for, while, and do while.
Then also we'll also need to display values back on the
screen, whether it's in Mario or in Greedy.
And so we'll talk about how we print things from strings to
integers and floats.
And then finally, we'll talk about pseudocode, a really
important concept to remember throughout this course.
What I find helps me most with problem sets is to think and
describe what I want to do before thinking about any C.
But just describe the action.
So pseudocode is kind of in between English and C, kind of
describing the processes without the correct syntax but
providing a good enough structure.
And so I'll have some examples of pseudocode for you as well
in this Walkthrough.
OK.
So what we'll be working with is the CS50 Appliance.
It's essentially a virtual machine that kind of runs a
computer inside your own computer.
And this has a lot of benefits.
One is that it's preset with a lot of the tools that you'll
need for CS50.
As well, that means that everyone's on the same ground,
whether Mac or PC or another operating system.
We can all run the virtual machine.
And so there are instructions at manual.cs50.net/appliance.
And so if you go to that link and follow the instructions,
then hopefully you'll be able to install the Appliance.
So first, you'll need to install an application, an
actual application to be able to run the virtual machine.
And then you download the appliance.
But again, there are instructions at
manual.cs50.net/appliance.
So I've already downloaded my Appliance, and I've installed
it in VMware Fusion.
And so once I downloaded the Appliance, I went to File.
I went to Open, and then found where I
stored the CS50 Appliance.
And from there, I ran it here.
But I have it up already here, so let's take a closer look.
All right.
So now we're inside CS50 Appliance.
I made it full screen.
You can choose to do that if you wish or just have it as a
smaller window on your desktop.
Here we have just a simple desktop with
a home and a trash.
But if you go to Menu and then to Programming, then you see
that we have something called Terminal.
And so in here, we can navigate around our computer.
We can write code.
But actually, we'll be using a program called gedit or "g
edit," whichever one that is.
So we'll be using that one to write code.
So you have these two tools that you'll be using primarily
to write code.
Then in addition, it's just like a regular computer.
We have a browser.
We chose Google Chrome.
What I've done is I've set up a Dropbox to contain all of
the documents.
And so that's something that's highly encouraged.
Dropbox uses cloud syncing and so if--
so for instance, something by chance-- let's hope not--
happens to your Appliance, then it'll all be
synced on the cloud.
All right.
So those are the applications that you'll be using in the
CS50 Appliance.
Now to navigate around the command line.
The terminal can actually act as kind of a way to actually
type commands into--
like, if you're a Mac, a Finder.
Or if you're in Windows, I believe that's explore my
computer or something like that.
So if we go back to the Appliance, let's open up a
terminal window.
So it has this prompt, jharvardappliance.
Let's just make this bigger.
OK.
So if we type the command ls, then that lists all of the
files in our computer, in our current directory.
Directories are just like folders.
We use those terms interchangeably.
All right, so we've listed the files
that are in this directory.
Now if we want to access, say, our Dropbox, then we can
change directories.
So cd and then Dropbox.
We ls again, and then we see the list of files that are in
this folder.
This is analogous to me going to my home then clicking
Dropbox and then seeing the list here.
All right.
So let's say--
when you guys are going to make your pset 1, let's make a
directory called pset1.
So we're in Dropbox right now, as you can see from this
prompt here.
So let's make a directory.
So mkdir, let's call it pset1.
And so now+ if we ls again, then we
see that pset1 appears.
And so if we want to go inside pset1, then we can go inside
that folder with the command cd.
All right.
So again, let's see if we--
say, let's do it another way.
This is analogous to just saying, Create
a New Folder, pset1.
But as you find, you'll be interacting with
the terminal a lot.
So sometimes it's a lot easier, a lost faster to just
work in the terminal to do those sorts of things.
OK.
And then these other commands.
There's a rm for remove a file.
So you simply type rm and then the name of the
file to delete it.
We'll go into some examples of that later.
And then we have something called the man command, which
brings up a manual for a type of function.
Again, I'll bring up an actual example of that later on.
So another really important tool, as I mentioned briefly
before, is style.
So essentially, style has to do with readability.
Will someone else be able to read, follow, and
understand your code?
This is especially important for you yourself, actually.
If you're staying up late coding, and then later on you
go back and you're like, what does this variable mean?
Say, you're working on a group project with someone, and you
both have to look at each other's code.
It's really important that you name your variables correctly
and make it look nice because that makes all the difference.
But then above all, we are in a course right now.
So for the interest of CS50 and especially for your
teaching fellows and graders who will be looking at your
psets, please, please use correct style.
And your teaching fellows will be quite happy.
So again, style includes indenting things correctly,
especially using your braces and indenting those.
Naming variables, something that makes sense.
Right now we follow the convention, when you have
multiple words in your variable name, then you
connect them with an underscore, as you see in that
name example there.
Then finally, something called magic numbers.
Essentially, when you're reading through code and say
you have a variable--
say, you don't have a variable but just say, OK, until such
and such is less than 10.
Then your grader is going to go, well, wait.
Where did that 10 come from?
So really explaining yourself matters a lot.
To help you explain yourself is comments.
Comments are probably the most important thing to include in
your programs.
And it helps you not only actually explain--
it helps you kind of explain your reasoning as
you're going along.
And so if you do that, again, it's going to be a lot easier
to go back in your code and kind of understand what you're
doing there.
Again, graders really like comments.
So you comment well and--
kind of like free points.
And who doesn't like free points?
You can also have multi-line comments.
And so I included a kind of template up here.
Essentially, usually these are used at the top of your
program to kind of explain in general what
your problem set does.
Include your name, the date, et cetera.
And so, as I said in this multi-line comment,
manual.cs50.net/style_guide has more tips and rules about
style for loops, et cetera.
OK.
So now that I've told you a little about style, let's see
this in action.
All right.
So here, Tommy has written us a delightfully horrible
example of style in a program.
So you see here, all right.
This is actually all right.
You see the multi-line comment here.
You start it with a forward slash and then two asterisks.
You continue along, aligning the asterisks along the line
and then end it with an asterisk and a slash.
All right.
So that's fine.
This here's fine.
He's including his libraries.
But then here he has comments spanning multiple lines.
There are lots of things wrong with this.
Comments spanning multiple lines, right here he's using
the syntax for just single line comments.
He's also melding everything into the same comment.
So we want to avoid that.
Then here we see that these braces, for example, are all
over the place.
The indentation is wrong.
It doesn't really show you definitively where something
starts and another thing ends.
Then as well, we see he has a defined variable i = 5 here.
But then this four comes out of nowhere, and there's no
comment to really explain where that comes from.
OK.
So now let's look at something that is actually just the same
code except with better style.
So again, this is the good style example,
the multi-line example.
And then here it's quite clean.
We see that he starts an if statement here, enters a new
line, has a open brace.
Then he has an indentation.
He keeps this indentation--
he keeps this indication uniform across the whole
program and really shows when one block of code starts, when
one block of code ends.
This may seem a little nitpicky on our part to begin
with, but you'll see as you're writing your code.
It's really useful to be able to separate this out.
And again, your graders really like that.
And so you see, instead of just putting a number in
there, he actually named the variable iterations.
And so we're not actually looking at this code right now
but just kind of seeing an example of
good versus bad style.
And so if you look at them side by side here, you would
definitely prefer to read the one on the right.
All right.
So one last thing before we dive into the real meat of the
pset is how to compile and run your code.
And so essentially when you write C, that's actually not
translated into the real machine code, the zeroes and
ones that the machine can actually read and interpret.
So we have something--
Clang is a compiler that we use for C.
There are many compilers.
But in CS50, we'll be using Clang.
And so Clang basically translates from C to machine
code for you.
So let's look at an example, dive into the Appliance here.
All right.
So right now we're in our home directory.
We actually aren't where any code is.
So let's change our directory to Dropbox/walkthrough1, where
I've stored some code.
So if we press ls, then we see that I have a
couple of files in here.
All right.
So I've already written hello.c, so let's compile it
and then see what it does.
So a basic compile command would be clang then hello.c,
essentially saying, OK, compile hello.c for me.
I click enter, seems to have gone right.
Let's click ls again.
This a.out file has now shown.
And so a.out is an executable file.
So to run it, you do a period slash a.out.
And so we see that this hello.c program apparently
prints out hello five times.
All right.
But say we don't want to use the name a.out.
For instance, we want to run the hello program because that
makes it easier to understand.
So let's say clang, hello.c, and then essentially you need
to pass in some things called flags.
So saying, OK, well I want to name this something else.
You can also pass in a lot of various flags,
which you will see.
So the flag for naming a program something that you
want is -o.
After -o, you write the name of the program.
Let's just call it hello.
So now we see that we actually have a hello executable file.
So we can run it, and it does the same thing as before.
So now that we have hello, we can also remove, for
instance, our a.out.
So rm for remove, a.out, your terminal will prompt you, ask
for you to confirm whether you really want to
delete it or not.
We say y for yes.
And there we go.
A.out is gone.
All right.
But sometimes it gets confusing to remember all the
flags that we need to include and type out clang.
And as we see when we're using more complex programs, we'll
be including different libraries.
And so our commands to Clang will get longer and longer.
So included in the CS50 Appliance is the make command.
So you simply type make hello.
Oops.
We've already made this executable file.
So let me just remove it quickly.
Now let's type make hello.
And you see in this line here that essentially saying make
hello involves all of these commands that
go into it for you.
So included in the CS50 Appliance is the make file.
So simply, when you have a file name.c, then all you do
is say make file name.
And then you'll have an executable
file with that name.
Yes?
SPEAKER 1: For my computer, instead of Clang it says GCC.
Is that like--
ZAMYLA CHAN: Yeah.
So your computer might say GCC as opposed to Clang because
GCC is another type of compiler.
If you're in the CS50 Appliance though, then it
should be using Clang.
If it's not, then maybe come talk to me afterwards or post
on CS50 Discuss and we can sort that out.
All right.
So now that we have our kind of basic tools down, then we
can dive into Mario.
OK.
So Mario is a program where essentially we are going to be
making our own kind of primitive version of the Mario
game background.
You know, Mario usually has a pipe and a
tree and some blocks.
And then there's a kind of half pyramid.
So we're just going to be focusing on that half pyramid,
making code such that it prints out hashes for the kind
of blocks in this format.
So what will happen is the user will input a certain
height of the pyramid, and then you'll print that out
such that the bottom left hash--
so at the very bottom right here-- that one will align
with the bottom left of your terminal.
OK.
So the first thing that you need--
the first little mini problem that we need to tackle is how
to get the user input.
So we need to be dealing with what the user inputs and then
kind of output things there.
So let's look at look a file called apples.c that I wrote
that deals with inputs and outputs.
OK.
So here at the top, I've included some of the libraries
that I need.
The really important one here is Standard I/O. That deals
with standard inputs and outputs because we're going to
be dealing with user inputs.
All right.
So then I start my main function.
And then I ask the user, OK, how many apples do you have?
Then right here, what this line does--
I assign the variable i to the value of GetInt.
So GetInt is a function that is included in Standard I/O.
And so essentially, that will deal with it for you.
It will prompt the user for an int.
Whatever they return, that will be assigned to the
variable i.
And so then it's just a little program that decreases the
value of i by 1 and then prints out the new value.
A nice thing about gedit is actually that there is a mini
terminal right in here.
So instead of having to switch forwards and backwards between
gedit and the terminal, you can actually
just run it from here.
So let's first get into the right directory.
So let's change our directories to
Dropbox/walkthrough1.
All right.
So now let's make apples, compiles it for us.
And so now let's run apples.
How many apples do we have?
I say, I have 3.
And it says, mwahaha I'm going to eat one of them and says,
you now have 2 apples.
All right.
So let's run that again.
And let's say I have 1 apple.
Now I have 0 apples.
OK.
So this program seems to work as expected.
We input a number, it decreases it by 1 and then
prints it out again.
But what if, for instance, I have negative 1 apples?
That doesn't quite make sense.
But it's still an integer, so the program accepts it.
And so it returns you an even further negative number.
So that's one lesson for us that even though the GetInt
function and the other associated ones such as
GetFloat or GetString--
even though those will get us the right data type, for
instance, if I had just said, [TYPING]
then it would tell me to retry.
So this will deal with whatever data type your input
is but won't actually check, well, is it actually a type of
value that I want?
So then one part of Mario is that the user has to input a
number that represents the height of the half pyramid
that you're making.
And so then if we're prompting this user for the height, then
there should be two bounds on this.
Right?
In the spec, it says it shouldn't be more than 23
characters because that's kind of the standard
height of the terminal.
But then, what other bound, perhaps a lower bound, might
we want to include?
If we're actually drawing a pyramid, kind of thinking back
to how high a pyramid can be, can it ever be lower than a
certain number?
SPEAKER 2: Bigger than three.
ZAMYLA CHAN: Hmm?
SPEAKER 2: Bigger than three.
ZAMYLA CHAN: That's a good point.
It could be--
we might want to constrain it to just a three level pyramid.
But let's think--
let's say like a one hash table counts as a pyramid too.
Then what should our actual lower bound be?
Thinking back to apples, we don't want a
negative height pyramid.
Right?
OK.
So when you ask for the user input, then you'll have to
include some way of making sure that the integer that
they provide you with isn't negative because you can't
draw a negative pyramid.
OK.
So there are a couple ways to do this.
Essentially, once you ask for user input, you want to demand
that they provide you with the correct input.
So you want to demand that they provide you with a number
that is not negative but also less than 24.
So we're dealing with zero to 23, inclusive.
All right.
So we want to continuously demand--
if they haven't given us a valid integer, they want to
continuously demand no.
Give me a valid input.
Give me a valid height.
So recall back in Scratch we had the repeat until block or
the forever if block.
Those are loops that are very similar to the while loop and
the do while loop, which we'll get into just in a second.
So the while loop essentially has a condition that you check
that's a Boolean value that you put inside there, like the
blocks in Scratch with the angles.
That's what goes inside the brackets of the while loop.
So you'll have to have some kind of condition there.
And as we just discussed earlier, that condition will
have to do with the bounds of the integer that was inputted.
So the condition would have something to do with whether
the integer is within the appropriate bounds.
So that's a while loop.
For instance, you can prompt for the integer and then
continuously check while this input is not valid.
For instance, keep on re-prompting, keep on asking
the user for an integer.
So that could be one way.
Another way could be a do while loop, which is very
similar to a while loop except what a do while does is--
you can kind of see by the syntax--
is that it has the do and then the actual loop body first.
Then it has the while conditions.
So what do while loops--
what they're useful for is that they actually execute the
code at least once and then check whether the condition is
met or not.
So if you were to do a do while loop, then inside your
statement you can prompt for an integer because you'll at
least have to ask the user once.
And then after you prompt them, then you can say, OK,
well once I've done this, is it valid?
If it is, then you can just keep on going.
But if it isn't, then it'll just act like a regular while
loop and then keep on asking.
OK.
So we're back to Mario.
So we know how to prompt for the correct user input that's
within the right bounds.
So now we actually need to draw this half pyramid.
It looks like simple text characters.
So let's actually open--
let's just open a window and say, OK, well what if I were
actually going to do it manually, type one myself?
OK.
So let's see.
Let's say, for instance, we want to make a pyramid that's
aligned along the left side, then would just do--
in Mario, the top level has two blocks instead of one.
So we start with two.
We click enter.
We do three, and then four, enter, five.
OK.
So that's pretty simple.
Except in this problem set, we want it actually to align with
the right side of our screen.
All right.
So, how might one of you actually type this such that
it's aligned along the right?
Instead of putting the hatch first, how might you kind of
move it along?
SPEAKER 3: Write a line?
ZAMYLA CHAN: Hmm?
SPEAKER 3: Write a line?
ZAMYLA CHAN: Yeah.
Yeah.
You could write like an underscore or something like
that, but we can just say, use a space.
Let's put in like three spaces here.
Then the next line, well, we would have to put two spaces.
The next line, we just put one space.
And then for our last line, we wouldn't put any spaces.
And there we have our pyramid.
So that's kind of--
remember that kind of logic.
And try and figure out some kind of pattern that we can
then translate to C and involve in some kind of loop.
All right.
So say we have a height eight, then our first row will have
two hashes.
But to get those hashes, you would have to write some
spaces before hand.
Right?
What I did is I just went through.
I drew it out myself, a pyramid in my text editor, a
pyramid with a height of eight and then calculated how many
spaces I needed to make.
So I said, OK, well the first row is
going to have two hashes.
But before that, I need to input seven spaces.
The next one has six spaces and then
three hashes, et cetera.
So then let's try and bring this to another layer of
abstraction.
What if we had for the nth row, how many hashes and how
many spaces would we need?
Does anyone see the pattern?
So the first row has two hashes.
The second one has three.
The third has four.
So the nth row would have--
SPEAKER 4: N plus 1?
ZAMYLA CHAN: Yeah.
N plus 1.
Exactly.
So then we see that the number of hashes is going to be--
if we're counting the first row to be one, then the number
of hashes is just going to be one more than that.
OK.
So then what about the number of spaces?
So let's try and express this in terms of the height.
If the height is eight, then the first
row has seven spaces.
So that kind of corresponds to 8 minus 1.
Right?
So then the second row is going to have six spaces,
which is 8 minus 2.
So then I'm going to leave it to you to kind of figure out
the pattern for that.
OK.
But in programming, sometimes we actually index at zero.
So we start at zero instead of one.
So instead of the first row being called the first row,
we're going to be calling it the 0-th row.
So depending on the way that you want to implement it, be
very careful whether you start at zero, whether you start at
one, your pattern's going to be offset by one.
OK.
So now that we kind of figured out the program, we
have to say, OK.
So for every kind of level of the stairs, I'm going to print
such and such number of spaces and then such and
such number of hashes.
That depends on the pattern that we established before.
OK.
So one way of iterating through and kind of going
through a set number of things is a for loop, kind of like
the repeat 10 block or like repeat and you entered a
number in for Scratch.
So essentially, for every level of stairs, we'll want to
print the spaces first.
Then print the number of hashes.
And then we'll want to enter a new line and then repeat it
again for the next block.
OK.
So let's look at for loops for a sec to kind of see one way
that we might go through a set number, go through the number
of steps in this half pyramid.
So for loops are composed of three parts.
First, you have an initialization.
So that essentially sets a variable.
It's going to be set to that value every time
that for loop starts.
Then you're going to have a condition.
Your for loop will only execute as long as that
condition evaluates to true.
And then you'll have an update condition.
So that has to do with the variable that you initialized.
So some way of basically ensuring that we can break out
of the loop, that we don't keep on executing
it forever and ever.
Because unlike Scratch, we actually don't have just a
plain forever loop.
In C, the program has to finish eventually.
So we have to ensure that some way we have it stop.
OK.
So an example of a for loop that you might want to use for
Mario is this.
So you have an integer i that you start at zero.
As long as it is less than the height, you execute the body
of the loop inside here.
After that body of the loop has executed, then you would
increase i by 1.
Then your program would check again, OK, well is i less than
the height?
If it is, then you would continue.
So here's an example of zero indexing, where we start at
zero and then we--
notice that our condition is less than the height.
So say our height is four, for instance, i
will start at zero.
It'll be one.
It'll be two.
It'll be three.
And then once it updates, when the for loop updates, i will
then be set to four.
But four is not less than four, and so then we would
continue to the rest of our loop.
OK.
So that's starting at zero.
But we could also start at one, for instance.
But since we start at one, we kind of have to go one more
time at the end.
So then that's why we add the less than or equal to.
So one of the great things that I like about computer
programming is that there's just so
many ways to do things.
So you can choose whether you start at zero, whether you
start at one.
Also, if you wanted, you could just use a
while loop, for instance.
So you could--
let's actually open hello.c.
So we have a for loop here.
It starts at i = 0, i is less than 5.
I have a comment here telling us what it does.
It prints hello five times using a for loop.
But we could also do that using a while loop as well.
So let's look at how we might do that.
So if we're going to mimic a for loop, then we also want to
mimic the initialization, the condition, and the update.
So the condition should be pretty simple because in the
while syntax, when you look at it, it says, while condition.
So let's just input the condition there.
i is less than 5.
OK.
So we know that we want to print goodbye.
We know that that's the body of our loop.
But we're missing the initialization
and the update, right?
Because we can't have a forever loop.
It has to terminate.
So let's add some kind of initialization here using the
same one that we used in our for loop, int i = 0.
OK.
So we start with an int i.
We repeat this while loop as long as i is less than 5.
So then we're missing one thing, which is the update.
So what update would we need to use if we were essentially
recreating the for loop above?
We have the initialization i is equal to 0.
We have the condition i is less than 5.
And then here's an update, right?
So we want to copy that.
We want to say, OK, i++.
That's the same thing as saying i = i plus 1.
But since it's used so often, shorthand for that is just
saying, i++.
Great.
OK.
Here I actually didn't exit out of my apples program.
So I'm just going to click Control C and that immediately
boots me out of my program and brings
me back to the terminal.
So that, for instance, if you run into a bug where you
forgot to update your while loop such that it would
terminate, and you enter an infinite loop, then you can
use Control C to break out of that.
All right.
So we're in the right directory.
So let's make hello.
And then if we run hello, we see that the goodbye loop does
the exact same thing as our for loop does.
So that's just a hint.
Whether you're more comfortable with for loops or
with while loops, they can be interchangeable.
So whichever one you want to use to iterate through--
in this case--
the height of the Mario pyramid.
And so again, this is just a reminder, if you start at zero
for your variable, then you'll want to have a different
condition than if you started at one.
So this table just kind of shows you a reminder.
If you want to repeat 10 times, for instance, then you
can either start your variable at zero.
And your condition can be less than 10.
And so that kind of shows you the matrix of that.
OK.
So we've gone through Mario.
We've said, OK, well we need to check for correct input,
zero and 23 inclusive.
We're going to find some kind of pattern, some kind of way
of expressing the nth row or the ith row.
And we're going to decide, OK, that we're going to print this
many spaces, this many hashes, new line.
All right.
So we have that.
So now we can move on to Greedy.
Greedy is a program where a user gives you an amount of
cash that essentially you as the cashier need to return.
But you want to use as little coins as possible.
And so this is where a Greedy algorithm comes in, where
we'll want to use the minimum amount of coins possible to
make that amount of change.
OK.
So an example of this in your solution might look
something like this.
You run dot slash greedy.
You're prompted to say, OK, well how much change is owed?
That value is going to be a value in dollars.
So that's going to be a float.
Your program will then calculate the minimum amount
of coins required to make, in this instance, $0.32.
And so the minimum number is four.
So before we figure out what to do, let's kind of walk
through the process that you might go about.
So if the input is 32, then essentially I'm going to use
the least amount of coins if I use as many
big coins as possible.
Right?
So it's a lot easier to use one quarter as
opposed to five nickels.
So let's say, you need to return $0.32.
Well, can I use a quarter in this?
Yeah, you can.
And then you would be decreased to $0.07.
Let's see if I can use another quarter to pay you back.
Well, no.
I can't fit a quarter in that.
So I'm going to move to the next biggest coin.
Can I use a dime?
$0.07, no you can't use a dime to pay $0.07.
So you say no.
Move to the next one, which is a nickel.
Can you use a nickel?
Yes.
Seven is larger than $0.05, so we can use a nickel.
And then we have two cents left over.
Can we use a penny?
Yes we can.
Can we use another penny?
Yes.
Can we use another penny?
No because now we have successfully
paid the user back.
And so that totals four coins used.
So thinking about that process, we every
time decide, OK.
What's the biggest coin that we can use?
Once we use that, we kind of keep a mental note of how much
more money we need to return the user as well as how many
coins we have been using.
OK.
So but again, the first step-- just like Mario-- is to prompt
the user for a monetary amount.
And so this amount is going to be--
it's going to have a decimal value because we're going to
ask them for dollars.
So that data type isn't going to be an integer.
But it's going to be a--
yeah, a float.
But just like apples, floats can be positive or negative.
So then when you check for values, you're going to want
to ensure that your float--
the user input-- is non-negative.
OK.
We could deal with floats in our whole program, represent
quarters by 0.25, dimes by 0.1, et cetera.
But I find it a lot easier to deal in just pure cents.
Also--
and we'll talk about this a bit later--
in C, floating points have something called imprecision.
So when you enter in 0.12, for instance, the computer
actually stores as like 0.1111119 or
something like that.
So it's a lot easier to convert to cents.
So how do we convert a dollar value to cents?
SPEAKER 5: Times it by 100?
ZAMYLA CHAN: Yeah.
Yeah.
So we would times it by 100.
But one tricky thing about floating points is that there
is some imprecision.
So let's just look at an example of that.
So I'm going to open imprecision.c.
OK.
This is a very simple program.
It asks for a float, and it prints it back.
One nice tip in terminal is you can just type clear, and
then you have a clear screen.
And so you don't need to look at any previous output or any
errors or bug reports, something like that.
OK.
So let's make imprecision.
Let's run it.
So I haven't--
in my code, I didn't print any prompt or anything like that.
So it just has a blinking cursor.
So it's just waiting for me to input a float.
So let's--
a random float.
And you see that it prints it back but has some extra
numbers that we definitely didn't include.
So we want to make sure that that doesn't
happen in our program.
So then what we want to do is make sure that we actually
kind of rounded off to the appropriate value.
Right?
And so luckily, we have a function called round included
in the Appliance.
It's in the math library.
If you want to know how to use round, then you actually use
the manual.
You can click man round.
Then here it brings up--
might be a little hard to decipher, but eventually
you'll get the hang of it.
It kind of shows you what the function does and then some
possible uses of that.
So when you eventually get a proper, valid input from the
user, then you want to convert it to cents.
Make sure that you round the value so that you avoid this
floating point imprecision.
OK.
So we've prompted the user for a monetary amount.
Now what we want to do is essentially check, right?
OK, so can I use the biggest coin possible?
If you can, then you use it.
You keep track of how many coins you've used so far and
also the declining amount.
Right?
And then you're going to check.
Once you've kind of exhausted the quarters, you want to go
to the next possible thing.
So what kind of structure or what kind of loop might we
want to use to continuously check whether we can still use
a quarter, for instance?
SPEAKER 6: While value greater than?
ZAMYLA CHAN: Yeah, perfect.
Exactly.
So while value is greater than.
So while the value that we have to give back is still
larger than a quarter, while we can still use a quarter,
use quarters.
Keep track of that.
And then keep on going.
Perfect.
OK.
Oh, here I've just included just some tips on how to print
out values.
So in your printf function, we've usually been just
dealing with strings.
But when you want to print out an int or just any type of
digit, you have to kind of write a kind of place holder.
So that's represented by the percent, %d for integers.
You'll write that, then afterwards you'll actually--
after a comma--
put in what value actually goes in there.
Right.
OK.
So we've determined that we want to check whether--
one way of doing this would be to continuously check whether
we can still use quarters, and then use the quarters, keep
track, and then move on to the next biggest value.
Now another kind of neat way that you could do this is
using the operator modulo.
So we already have the plus, minus, multiply, and divide
available to us.
But the modulo operator is kind of neat.
What it does is it actually returns you the remainder of
dividing two numbers.
So if you remember in long division when you would, say,
do 74 divided by 3, you would write it, carry over,
subtract, and then at the end the number at the bottom is
the remainder.
Well, what modulo does it actually just gives you that.
So 74 modulo 3 would give you 2.
Similarly, 10 modulo 2 gives you 0 because there isn't any
remainder when you divide 10 by 2.
6 modulo 5, well 5 goes into 6 one times and then
it has 1 left over.
Then if you have 7 modulo 9, well 9 is bigger than 7.
So it can't go any other times.
So it makes sense that the return value is 7.
So if you think about modulo, how it gives you the remainder
after you divide something, you can kind of see how you
might be able to use it in Greedy, right?
So if you kind of combine the modulo maybe with the division
operator, something like that, then you might have a cool
kind of mathy way to approach the problem set.
So now that we know that there's a couple of different
ways that we could do this-- there are definitely a lot of
different ways to even write the while loops.
So I've written some pseudocode here.
It might not be identical to the kind of skeleton of your
code that you write.
But essentially, the process and the way of thinking is
just as we discussed.
So first, the first line is saying to get a certain amount
in dollars.
And then implicit there is convert it to cents.
Then while quarters can be used, we want to
increase the count.
And then we want to decrease the amount, the value that
we're returning back.
As you see here, it isn't quite C. But I've also
indented things, I put my conditions inside of
parentheses.
So then that kind of gets me started.
And then later on, I can just look up the syntax.
Often the hardest part really about a problem is to
understand what exactly you need to do.
So once you write that down, then it's a lot easier to then
translate to pseudocode.
And then from pseudocode, syntax comes pretty easy.
So we see while quarters, can be used, increase count,
decrease the amount.
While dimes can be used, then you conduct it so on and so
forth, until you have exhausted all of your pennies.
You print out the number of coins used, which will be the
minimum amount to make the user inputted value.
And there you have your Greedy algorithm.
And then once you finish that, you have also finished pset 0.
Does anyone have any questions about anything?
All right.
Well, I will stick around for a little bit after if you have
any questions.
This was Walkthrough 1.
Thanks for coming.
