










Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
The concept of methods and functions in software engineering, emphasizing their importance in abstracting complex code and allowing for parameterized generalization. The document also covers the concept of instance variables and their role in storing values between method calls, contrasting them with local variables. Additionally, the document introduces the concept of generating random numbers using a pseudo-random number generator and the importance of seeds in generating consistent sequences of random numbers.
Typology: Study notes
1 / 18
This page cannot be seen from the preview
Don't miss anything!











Programming Methodology-Lecture
Instructor (Mehran Sahami): Alrighty. Welcome back to yet another day of CS106a. Couple quick announcements before we start – so first announcement, there is one handout which I’m not sure if it’s here yet, but it will be here momentarily if it’s not here now. You can pick it up on the way out. I think Ben might have just been delayed on the way in. So there is one handout; hopefully, you can pick it up on the way out if you didn’t see it back there now. It’s already posted online as well. So if you don’t get it in class, you can get it online, or you can get it – there’s the Handout Hangout as we like to refer to it, which is a bunch of file folders on the first floor of Gates where there’s hardcopies of all the handouts that get left over from class.
So another quick point, it’s still a little early to talk about plus pluses because some of the programs that you’ve written are, sort of, simple enough that it’s difficult to, sort of, way overshoot what we’re expecting, which is what we want for the plus plus, but I just want to say a little note about plus pluses just because pretty soon that’s, hopefully, what you’re gonna be going for. If you think you’re gonna add extensions to an assignment beyond the basic functionality, what we ask is that you do two versions.
You do one version that is your nice, clean, well-decomposed, commented version that is everything that you would need to do to do the assignment well done just as the specification suggests, and then do another – create another file, or you can just copy this file that you started with and start working on that. You might need to give it a slightly different name for the class like, “My extended version of this,” or whatever, and that’s where you should add all your extensions.
And the reason we do that is because sometimes in the past when people have added extensions to their assignments, they’ve inadvertently made things, in terms of software engineering, really ugly that they didn’t mean to, or they ended up actually breaking some piece of the basic functionality because they were trying to do something way more complicated. And so that’s why we ask for two versions if you’re gonna go for the plus plus, so we know you were able to do all the basic stuff and do it cleanly, and then if you want to add extensions, we can look at those extensions, and if the extension happen to break something along the way, you won’t get penalized because we’ll have your basic version as well. So if you’re going for the plus plus, two versions of the program that you want to submit for the plus plus, the basic version that has all the functionality, everything nice and clean, and then whatever you’re gonna do for the extension.
Alrighty. So with that said, time to get into the real meat of things, and we’re gonna do a little bit of review of what we talked about last time. Remember last time we talked about our friend, the method, and one of the things we said about method was, like, a CD player was like a method, and part of the idea was it had this generalization capability, that it had some parameter of the CD you put in, and out came music, and the music that came out depended on the CD that you actually put in.
Now part of the reason, besides just getting generality, is this notion of information hiding. So when we think about having – this is, kind of, the software engineering principle for the day – when we think about having methods, part of the reason to have a method, and to give it a good name, and to generalize it with parameters is because you don’t want the person who’s using that method to have to worry about all of the internals of that method.
Here is a simple example. Most of you have seen the readInt function or the readInt method, and it reads information from the user, and we did a little example in class where the user typed in something that wasn’t an integer, and it said, “Illegal format,” and it asked for it again. It does all of that for you. Do you need to know any of the internals of readInts? No. You can just use it because it’s hiding information from you. It’s hiding all of the complexity of being able to get some data from the user, do error checking on that data, give the data back to you.
And so, as a result, you can write your programs where you just have this one line in there. You get data from the user, and you don’t care what all is going on in order to get that data from the user. That’s the same kind of mindset you should be thinking about when you write your methods. Your methods should basically think about solving one problem each, and you want to think about that problem, sort of, being something general that makes sense to hide that information from the user. So when the user called your method, for example, there’s a nice comment that explains what it does, that explains what the parameters are, so they don’t need to go into the code of you method to actually figure out what it does, okay?
Let me give you a simple, real life example, okay? There is this thing that most of you are probably familiar with that looks, oh, like this, and has two slots in it up here, and a little thing that looks like a plunger over here, and it’s something we happen to affectionately – anyone that can identify what this object is?
Student: A toaster.
Instructor (Mehran Sahami): Toaster, rock on. That’s a social. A toaster is essentially doing information hiding, right? And you’re like, “No, really? Like, my – ” yeah, your toaster’s alive. It’s sitting on the counter, and it is hiding information from you, and it’s information you don’t care about, right? It’s got a parameter. The parameter you stick in is bread. You can stick in lots of different bread, but the type that you stick in is bread, right? There can be some specialization of that type like rye bread, or wheat bread, or whole bread, or whatever it is, but you gotta stick in bread. You call the method by sticking the plunger, and some amount of processing later, what you get out of this thing is toast.
You don’t care how the toast is produced. One way the toast is produced is there’s coils in here that head up, that, sort of, bake the bread, and bread comes out, that’s great. Another way the toast is produced is there’s Keebler Elves inside here, and they’re like, “Hey, we got bread.” And they eat the bread, and they excrement toast, right? And that’s
excruciating detail. Hopefully, it won’t be too excruciating, but enough detail that, hopefully, you will know how it works. As we talked about last time, right, you can have some method over here Run. So we’ll say Private, Void, Run, and inside here we might have some Integer I that we do something with, and over here we might have some other method, Private – I’ll make this one Void too, and we’ll call this, just for lack of a better name, Word Cal, and over here Cal might also have in it some other Integer I, and it might do something with it, and these two Integer I’s are not the same because the lifetime of a variable exists only in the method in which it is defined for these kind of variables, and I’ll show you some different kinds of variables in just a second, but a variable like this that is declared inside of a method is what we refer to as a local variable.
It’s, kind of, a variable that, kind of, hangs out in its little hood, and its hood is the method that it’s declared in, so it’s local to its hood. It’s like, yeah, I’m just hanging out with the boys and girls in run, and that’s where I live, and so if Run happens to call Cal somewhere inside here, well, I don’t live in Cal, so I’m not going over to Cal, right? And Cal comes, and it gets called, and there’s some other I here, and it doesn’t know about this I. It’s, like, hanging out in a different hood. Like, this is Manhattan, and there’s an I over here, and this is Brooklyn, and there is another I over there, and they just don’t need to know about each other, and, as a matter of fact, they don’t know about each other because if they did, life would be bad. Like, they’d get in fights, knives would come out, the whole deal.
So these two things are actually separate. Now, what does that mean in terms of the mechanics of when we call functions parameters? For example, what would happen if Cal actually expected some parameter over here, let’s call it N, and I passed into it I; what does that mean? Is that gonna conflict with this I over here; what’s actually going on? So to understand what’s going on, let’s actually go through an example in excruciating detail of what’s going on inside the computer, and you can see exactly what’s going on.
So let’s come to the slides, and here is a program that you saw last time. This is just our little factorial program that we computed last time that you saw an example of different methods, and we have the run method that calls this factorial method a bunch of times, up to four times, right? Because maximum happens to be four, and inside here we have an I, and over here we have an I, and here we have this things called Result, and we’re like, “Hey, what’s going on with all this?”
Well, here let’s trace it through. So let’s actually start with Run because that’s where the computer starts executing things, right? So it comes to Run, and it says, okay, inside Run I have this four loop, and it’s got an I in there. So in the hood or in the method for Run, we have our own little I, and when we start off, we set I equal to zero. We check to make sure that’s less than Max Num, which is four, which it is. So we say, oh, we enter the loop, and now we come to execute this line. Well, to execute this line, we need to make a method call over here to factorial because we need to figure out what’s the factorial of I in order to be able to print it out on the line, right?
So we call factorial, and we say, hey, factorial, what I’m going to give you is I. Now, I’m not actually going to give you I because I is my little friend. What I’m gonna give you is a copy of I, okay? So when factorial gets called, we get what’s called a new Stack Frame, and the reason why it’s called a Stack Frame is that these things get stacked on top of each other. Notice the box for back here or the box for Run, sort of, gets occluded by a new box or a new frame for factorial. That’s why this is called a Stacked Frame because we frame it inside a box, and we’re gonna stack these things together as functions or methods get called, okay?
So when factorial gets called, it’s expecting a parameter called N. What it got passed back here was I. What we did at this point was we said what’s the value of I? It’s zero. We make a copy of that value and pass it over to factorial as its parameter. Factorial says, hey, my parameter’s called N. What value did you give me? You gave me a zero. I’m gonna stick that in N, okay? So it’s got this thing in here, N, which is totally distinct from I. It’s gonna have its own I in here, and this I is in a different hood than the I in Run. So they’re completely separate variables. They just happen to have the same name, but they have the same name in different context, so they’re actually different. It’s just like if we had someone named Mary in this room, and there is someone named Mary taking Psych 1, you’re different Marys. That’s just the way life is, right? You’re in different context even though you have the same name, so same thing going on here.
So factorial fires up and says you gave me that zero, that’s N. I start off by having result, which is a local variable. It is a variable that is only defined in my context, and I set that equal to one, and then I have my own variable I, which is only defined in my context, and I start off setting that to one, and it comes in here, and this is a real short loop because it does the test, and it says is one less than or equal to zero? No. So the body of the loop never gets executed, and it immediately returns a result, okay? So what value’s gonna come back? What’s gonna come back is basically a copy of this one. So the value one gets passed back, and we come back, this whole Stack Frame that we had over here goes away because factorial’s now done.
Factorial says, hey, I computed my results; here you go. I’m going away. So what we say is it gets popped off the stack. It and everyone in its hood, we, sort of, say thanks factorial. You did your work. Thanks for playing. You’re done. Blammo, you’re gone. The only thing that remains of you is the value you returned, okay? So that one gets returned, and we say, hey, now I can actually write something out to the screen because I got a value of one back from factorial of zero, and that’s what I write out – zero factorial equals one. All right?
One more time, just for good measure, so – whoa. That was bad measure. Sometimes these things just never work right. You have to hate technology. All right. So we add one to I. I now becomes one, right? I was zero over here. We add one. I becomes one. I is still less than four, so we execute this line once again. Now we’re calling factorial passing at the value one. It gets a copy of that one. Where does that one go? That one goes into the parameter that it’s expecting, the N. So it gets a one because that’s the value we passed
Frame for Run, so I’m just gonna draw it manually up here so you can see it as these things are happening. When run actually runs, it’s got its own local variable X, and X is getting set to the value three, okay? Then it calls Add Five. What happens when it calls Add Five? We get a new Stack Frame. I’m not gonna erase Run; I’m just gonna draw down here. We get Add Five. What is Add Five expecting? It’s expecting a parameter called X. So it says, oh, I have my own box for X down here. What are you giving me? I’m giving you a copy of the value passed in. What’s the value passed in? Three. You get a copy of three. That’s great.
Now, Add Five is over here. It has its X in its own hood that is not the same as this X, and you say, “But you passed X as a parameter.” Yeah, the parameter happened to have the same name in terms of the argument that I passed in and the parameter I was expecting, but they live in different hoods. They’re actually separate, and what you get is a copy even if the name’s the same.
So this guy happily comes along and says, ooh, ooh, I’m gonna Add Five – all kinds of excitement going on. It adds five. This three turns into an eight, and then it says, hey, I’m done. Good times. I don’t even need to return anything. Thanks for playing, and I’m like hearty handshake, Add Five, you added five to your X, and now you’re done. Thank you for playing. It goes away. We come over here to Run, and now Run is going to do a print on X, okay? So what it’s going to print out is three, all right? That’s the place where it seems counterintuitive. What you are passing when you are passing parameters are copies. You are not passing the actual variable, all right?
So one way you can potentially fix this – I pressed the wrong button. All right. So this was bad times. Here is good times with methods. Anyone remember the show, Good Times, J.J. Walk – Good Times. All right. I’m old. How can we change it? What we need to do is think about information flow through our program. We need to think about that value that we computed in Add Five, somehow we want to pass it back out so Run can get it. So let’s trace through this code, right? Run starts, it has a Stack Frame. It has X equals three in it, and what it says is I’m gonna call Add Five, and I’m gonna pass it X. So Add Five once again happily comes along and says, hey, I’m Add Five. I have a value X which you gave me was three.
It adds five to that three, and it gets the value eight, but now what did it do? It returns that eight, which means when it’s going away, this puppy basically goes away, but what it says is, hey, what I’m giving you back, in my dying gasp, is this return value eight. What are you gonna do with it, Run, huh, huh? And it gets a little ornery, but Run says, hey, I’m just gonna assign it to X. Which X am I dealing with? I’m dealing with the X in my hood. So that eight that you just gave me – thanks for giving me the eight; I’ll assign it to my X. And now, when I print it out, I actually have what I care about because the computation that happened inside the method that got called, the value that I cared about got returned and assigned to the place I cared about. That’s what we refer to as information flow, okay? Question?
Student: Could you do the same thing – instead of having a return, just have in the print line method it concatenated with Add Five of X instead of with X?
Instructor (Mehran Sahami): I’m not sure what you’re saying, but – oh, you’re saying
Student: Yeah.
Instructor (Mehran Sahami): Yeah, but then we wouldn’t have actually changed the value of X, okay? We would have just printed it out. All right. So one way you can actually think about this, this is the way I like to remember it is when I was a wee tyke in the days of yore, my momma and daddy took me to a place called the Louvre. Anyone actually been to the Louvre? A fair number of people, it’s a museum in Paris, and this thing there called the Mona Lisa, which is probably actually smaller than this square, but it happens to be a woman, very famous, who’s smiling. That’s my rendition of the Mona Lisa, okay?
And so when we went there, here was mommy Sahami, and here was little Mehran, and little Mehran, when he was small, there was two things. One is he had a ponytail, which I would not recommend. It was the ‘70s; what can I say? The other thing that little Mehran had was he had a chainsaw, and so when we went to the Louvre, what happened was I said, “Hey, mommy, what I want to do is I want to do some computation on the Mona Lisa with my chainsaw.” And what mommy said was, “Oh, that’s great, but what we’re gonna do is we’re gonna call the method for you. That method’s called gift shop.”
So we went down to the gift shop, and in the gift shop, somewhere along the way, they had said, “Hey, here’s the copy of the Mona Lisa; make some prints of it.” And so what the gift shop has down here, every time you call the gift shop method is you get a copy of the Mona Lisa. And so when happy Mehran comes along and says, “Oh, that’s great. You know what? Mona Lisa looks a lot better split in half.” And now what I’ve done is changed my copy of the Mona Lisa, and, luckily, when you go to the Louvre, you still see the original, okay? So that’s the way to think about it. When you are in a method, you are getting a copy. If you somehow do something to that copy, you are not changing the original, and it’s a good time for everyone involved, all right?
Student: Is this true for non-primitive data types, like –
Instructor (Mehran Sahami): We’ll get into that when we get into objects, but yeah, that’s a good question. Right now we’re just dealing with things like Ints and Doubles, and we’ll talk about other stuff when we get there. All right. So, with that said, it’s time to think of eventually writing our own whole classes, right? So, so far, we’ve been writing, like, classes that have been, like, one program, and now we want to think about writing multiple classes, but before we actually write multiple classes, we need to have a little bit more idea about using classes, okay?
RandomGenerator.GetInstants, there is no parameters here, instants, and what that means is give me an object of the Random Generator type, and what you’re gonna assign that to is somewhere you’re gonna have some private variable of type Random Generator, and you need to give it a name; we’ll call it Rgen for Random Generator, equals RandomGenerator.GetInstants. So what RandomGenerator.GetInstants gives you is an object that is a Random Generator, so it’s type is Random Generator. You’re only going to use it inside your own class, which is why it’s private, and because you’re actually declaring a variable, you need to give it a name. So the name of the object is Rgen, okay? That’s the thing you would have control over.
Now, the funky thing that comes up when we think about these things, all right, is that sometimes what we actually want to have is we want to use this same object inside all of our methods, right? And so you just say, “Hey, Mehran, you just told me that when I declare a variable, that variable only lives inside the method in which it is declared. So what’s going on there? And if I want to have one of these objects, do I need to actually get one of these inside every one of my methods?” And the answer is no. There is a way that you can actually say I want to have some object or some variable that is shared by all of the methods in my class, okay? And that’s what we refer to as an Instance Variable.
So the variables we had before were called Local Variables when they live in a particular hood. So like X over there inside Run is a Local Variable because it’s local to that particular class, but – let me erase this. We can have a notion of an Instance Variable, and an Instance Variable refer to as affectionately, an Ivar. So if you’re a big fan of seafood, that’s probably familiar with you. Ivar for Instance Variable, it’s just short for it, all right, is just basically a way of saying what I want to have is a variable that lives for everything in the object, so all methods can refer to the same variable.
Now, let’s contrast the notion of an Instance Variable with a Local Variable in terms of how they’re declared, how we use them, what’s going on, why we use them. So here is Instance Variable over here; here is Local Variable over here, which I’ll just call the Local Var. We don’t call local variable Lvars, we just call them locals, and Instance Variables are Ivars. So a Local Variable, as we talked about, this is declared – it’s declared in a method, okay? Instance Variables are declared in a class but not a method. So what else have you seen that’s declared inside a class but not inside a method? Uh huh, Constants. It turns out those Constants are actually Instance Variables, sorry. They’re Instance Variables whose value is final. So we say they do not change, but those Instance Variables are visible to everyone inside that object; all the methods can see it. So Constants were an example of Instance Variables. We just didn’t tell you at the time they were Instance Variables.
So this guy is only visible in terms of its visibility, which we’ll just call Vis in the method, and, as a matter of fact, it’s lifetime – it only lives in the method, and when the method is done, the scope of this variable is basically gone, and it goes away. These puppies are visible in entire object. So in the class in which they are declared, when you create an object of that class, you get an Instance Variable; for every Instance Variable declared, you get one, and it’s visible in the entire object. That means its lifetime is it
lives as long as the object lives, which means once you call some particular method, if that method has local variables, they come into being, and when the method is done, they go away. When you create an object, its Instance Variables come into being, and they stay around until that object goes away, you’re done using the object. That’s how long they live.
So you might say, “When do I use one versus the other? What’s the point of having these two kinds of variables?” What you want to think about is you use Local Variables when the computation that you’re gonna do only lives for the lifetime of the method that you actually care about, so you’re doing some local computation, okay? So think of this local variable local computation. An Instance Variable is something where you need to store some value in between method calls. You can think of this as the state of the object; what state is actually in?
So let me give you an example to, sort of, make this concrete because I think sometimes a specific example makes it a little more clear. Here’s two water bottles. These are objects which were lovingly provided to me by the Stanford Computer Forum, okay? I have some class which is water bottle, and I say, “Oh, get me a new water bottle.” So this is Water Bottle 1, and I say, “Get me another new water bottle.” This is Water Bottle 2.
Now, sometimes there are some methods I might want to call on this water bottle like unscrew the cap, and when I unscrew the cap, it turns out if I do four rotations of the cap, so I have a four loop, and I do four rotations of the cap – one, two, three, four, five – four, sub two, the cap comes off. I needed an Index Variable to keep track of how many times I turned the cap on the bottle, but I don’t care about the value of that Index Variable after the cap is off, or if I say, “Put cap back on,” and I screw it on four times, I did some local computation to figure out for the four loop how many times I went through it, but I don’t care about that value if I go do something else with the water bottle now.
But there are things I do care about the water bottle in between method calls, which is let’s say I had some unnamed soda, and so I have Water Bottle 1, which I might have called unscrew on, and Water Bottle 2 that I called unscrew on, and so I said let me – I don’t know if this is actually covered by copyright or not. Let me fill up the water bottles, oh, yay, much over here and a whole bunch over here, okay? So I call fill, the fill method, on each of the respective water bottles. Know that they have different amounts in them because the Instance Variables that I have, each object gets its own version of the Instance Variable. So I have some Instance Variable that basically tells me, let’s say, a double what percentage of the bottle is full.
When I say put the cap on, that percentage should still stick around, and when I take the cap off, that percentage better still stick around. That’s part of the state of this object. In between method calls, when I send other messages to this object like put the cap on or take the cap off, I still need to be able to store how much is actually in the bottle between method calls. Whereas, how many times I unscrew it is a local computation. I don’t care about storing that value after I’ve finished unscrewing or putting it back on. That would be something I would use the Local Variable. So think of Instance Variable as the thing
Int just giving it a single value like ten, and what you’ll get back is a number between zero and N minus one, or in that case, you would get a value back between zero and nine because, as computer scientists, we always start counting from zero.
Besides integers, sometimes you want doubles or real values, so a similar sort of thing. There is next double where you give it a range, and you get a value, strangely enough, between less than or equal to low but strictly less than high. It’s like an open interval kind of thing, but really, for all intensive purposes, you’re getting real values, you don’t really care because the chance of hitting the interval is not a big deal. So it’s inclusive of the low interval but exclusive of the high range of the interval, but what it gives you is a double basically in the range from low to high, and you can also call next double without giving it a range, and you’ll get a value based between zero and one, okay? Just if you want because a lot of times people ask for values between zero and one.
There is also next Boolean, which just gives you – if you don’t call with any parameters it’s basically like flipping a coin. It’ll give you back true or false 50/50, but if you care about having your coin be biased, right? There’s actually some people in the world, including some professors in our statistics department who can actually flip a coin where they can flip it in such a way that they can affect the probability of how often it comes up heads and tails – pretty frickin’ cool, but we won’t talk about that. Next Boolean you give it a double, and so what it says is it will return true with probability P. So if you set P to be .5, it’s the same thing as this case up here, but you can set it to be different if you want. P has to be between zero and one because it’s probability.
Last, but not least, just to be funky there’s something called Next Color. So you can, sort of, say, oh, I’m feeling adventurous, and I want to just paint the world random colors. Get me a random color. So just next color and it has no parameters, and it just gives you a random color. It’s like there you go, good times. It’s fun every once – if you have no fashion sense, like me, that’s, like, what I do every morning when I wake up, and I put on clothes. I’m just like, “Next color,” and I walk out, and my wife’s like, “No, no, no, no, no, no.” And she actually has a deterministic algorithm for dressing me. All right.
So here is a little example of how that actually works. So all I did was I took our program that we had before, our simple random, and filled in the Run method. What’s going on when this, an object of simple random gets created or when this program is run, Rgen gets initialized to be an instance of the Random Generator, and now I can refer to it, because it’s an Instance Variable, in any method, right? So Run is just some other method. I can say Int die roll is a random generated number. Give me the next Int between one and six, and then it will just print out, “You rolled,” and whatever the random value was. So it’s just simulating one die roll. Not a lot of excitement going on there, but this is just to show you how the syntax actually looks for generating a random number. Okay? So any question about that?
Let me show you a slightly more involved program. So we can get rid of this craziness, and here’s a little program that rolls some dice. So what this does – notice now I have the imports and everything in here. I need to import acm.util.star if I actually want to use the
random number generator, and now just to be a little bit more complicated, I’m gonna show you an example of having Constants and Instance Variables together because just where we put them and what the convention is in the book is just a little bit funky.
So here’s the whole class. Let me extend the window a little bit so you can see the whole class. Well, you can almost see the whole class. Let’s just assume you saw the top line up there, okay? What we have up at the top is a Constant, which is the number of sides on some dice we’re gonna roll. So I should just ask anyone here ever, like, you know, played a game that involved 20-sided dice? Anyone? You can admit it. It’s okay. I did too. 12- step program, you’ll be fine.
Num Sides, in this case, happens to be six. So we say, “Private Static Final Ints,” all the garbage that we have to save for having a Constant. It’s not garbage, it’s just lovely syntax that’s of type integer. It’s Num Sides is six. So inside this program, what it’s gonna do is simulate rolling some number of dice until you get the maximal value on all the dice. So if you’re rolling one die, it keeps rolling until it gets a six, and it tells me how many times it has to roll to get a six. If I’m rolling three dice, the maximum value’s 18 because I need three six’s. So it keeps rolling until it gets an 18 and tells me how many rolls are involved.
So what’s going on here is I first get the number of dice, the local variable, from the user by asking the user for the number of dice. They give me the number of dice, and I compute what’s the maximum roll? Well, it’s just the number of dice times the number of sides on the dice because that’s the maximum value for each die, which is the singular form of dice if you’re wondering. But that’s the maximum value. I have another local variable, Num Rolls, that I initialized to be zero, and I’m gonna have a loop and a half, basically, where I say, “While true.” It’s not an infinite loop because we’re gonna have a break inside. Int roll equals roll dice, the number of dice I want you to roll.
So over here, I have some other method down here, which I’ll just scroll down to down here so you can see the whole method, called Roll Dice. Roll Dice takes in a parameter called Num Dice. It’s getting a copy of that value. It says I’m gonna have sum totaled at zero. What I’m going to do is have a four loop that counts up from I up to the number of dice you told me to roll, and every time I’m just gonna generate a random number between one and the number of sides on the die, and add it to my total. So that simulates rolling the dice, Num Dice number of times, and when I’m done, I’ve gotten the total, and I’m gonna return that to you.
So up here, when I roll dice, what I get back from my roll is a number that is just the sum of that number of dice rolled in terms of random numbers. I say, okay, now that I’ve rolled the dice, increment my number of rolls by one. If the roll that I got was the maximum roll, then I’m done. Hey, I just rolled an 18 if I have three dice or whatever, and I break out of this loop. If I’m not yet done, I say, hey, you rolled whatever your roll was, and I go through this loop again, and roll the dice again, and write out the value again until I finally get Max Roll, and when I get Max Roll I say, hey, you rolled
Student: [Off mic].
Instructor (Mehran Sahami): Yeah, these names, as long as they’re consistent, could be anything else. This could be X here and X there because all this guy cares about is I’m getting some value passed into me. What am I getting passed in? I happen to be getting passed a copy of Num Dice, but I don’t have to name it the same thing; I could name it whatever I want. The reason why I named it the same thing is I wanted you to know that even if you name it the same thing, you’re not getting a copy of the variable you’re – yeah, you’re getting beamed with a piece of candy. You’re just getting a copy; you’re not getting the actual variable.
So one other thing I want to mention to you real quickly is when random values come up, it becomes real hard, sometimes, to write programs because every time you run the program, you get a different set of random numbers, right? That’s just the whole point of random numbers. If they were the same every time you ran the program, that would be, sort of, bad times, right? You’d be playing the same game over and over.
So how do we actually generate random numbers? What’s the random number all about? Well, remember the old black box. The way this black box works – this is the Random Generator, which I’ll just say RG. It’s, sort of, weird. When you ask it for a number, it gives you back a number like five, and then secretly, sort of, secretly we’ve replaced our Random Generator’s regular coffee with our new flaked coffee. Secretly, what it does – anyone remember that commercial? God, I am so old. All right.
It secretly saves that number and uses that number through some complicated equation that you don’t need to worry about because this is the black box, to generate the next number when you need the next number, and when you say next number again, it does the same thing. So when you ask for next number, it might’ve given you six. It stores that six, and the next time you ask for a number, it does something with the six, and scrambles it, and chops it up, and reformulates it, and it says, oh, 17. okay?
So the thing is, you don’t know what number this thing actually started with to begin with. As a matter of fact, the number that it starts with has to do with the time on your computer in sixtieth of a second, or actually, in thousandths of a second. So most people don’t know what that was, and to the extent that you don’t know what that was, you can’t figure out what the sequence is. The only problem is if you don’t know what that was, and you run your program, and it’s got a bug.
First time you run your program it crashes because you got 17, and you’re like, “Oh, I need to go find that bug.” So you run your program again, but this time instead of getting 17, you get a six, and your program works just fine. So you’re like, “Oh, bummer.” And you run it again, and you get eight, and your program works just fine. You say, “Oh, it must just work. Let me get ready to submit it.” And the last time you’re ready to submit it, you get a nine, and it crashes. That’s real frustrating. That makes you want to kill. I don’t want anyone to kill, right, because if there’s 300 of you and one of me, one of the people who might get killed in this process is me.
So what you can do is you can say I want you to generate the same sequence of random numbers ever time. How do I do that? I need to tell you that the number that you’re gonna start with the very first time is some specific value so you will always generate the same sequence given that first number, and that first number is something we refer to as the Seed. It’s like the number from which all other numbers sprout, and how do I set this seed? It’s extremely complicated – actually, not at all.
If I had Rgen, which is my random number generator, this is my Instance Variable, which is my random number generator, I say .SetSeed, and I give it the value of the seed. A real fun seed to use, by the way, in case you’re wondering, and you’re having difficulty coming up with a seed is one, okay? So set seed equal to one. You do this somewhere at the beginning of your program, and all the random numbers you generate in each run of your program will be the same set. You won’t always get the same random number each time you call for next random; what you’ll get is the same random sequence. So if you happen to get the sequence seven, five, then nine, two, three – I don’t know, you know, whatever, the next time you run your program, you’ll get the same sequence, and that makes it much easier for debugging.
So let me show you a quick example of a program that actually uses that which will take our simple random program, which you saw in a previous slide, and add the little seed, okay? So now if we happen to run this program – we’re running; we’re feeling good. We want to run simple random. It’s a good time. You rolled a five, and we’re like, oh, that’s great. That’s wonderful. Let me run this again. So we run it again. We, sort of, do the quick – well, you rolled a five, right? Notice that the seed was actually set to one, so I’m not getting a one; I’m getting whatever would’ve happened after I put one through this complicated function.
I could go in here and change the seed to something else if I wanted to. I could change it to three, and the next time I run this program, I’ll just happen to get a different initial value for that random number, but the sequence of random numbers I get will be the same based on the number three. So if I do simple random based on three, you rolled five. It just turns out one and three give you the same thing. That’s life in the city. Maybe Mehran should’ve done a little more testing before class. All right. Uh huh, question?
Student: [Off mic].
Instructor (Mehran Sahami): The sequence is always based on whatever that first value was. So if it was one and then you changed it to three and got a different sequence, and you changed it back to one, you’re gonna get that same sequence based on one. Uh huh?
Student: [Off mic].
Instructor (Mehran Sahami): No, the seed always just sets one number. It’ll automatically do the appropriate conversions to whatever you want, but you should always just set the seed, like, one or whatever you want it to be. Uh huh?