CS99 Homework 4 Answers to common questions (1) Comments Things you should comment/explain in a program: + Describe each major variable: - Put comments to the right. - explain all variables near the top of the program. + Describe each control structure (selection/repetition statements): - The person reading your code should be able to look at the comments and know what the control structure will do, how it will update certain major variables, and how it will end. - There tends to be about 1-3 lines for a "small" control structure. + Describe each function/M-file at the top: - Explain the state of the program before entering the function. This comment is called the PRECONDITION. - Explain what the function actually does. - Explain the state of the program after the function ends This comment is called the POSTCONDITION. - Sometimes it suffices to explain the role of the function, the input values, and the return value(s). + Other things to comment? - Something "weird" in your code, like some rarely used function that someone might not recognize or some bizarre trick you use to calculate something. - Changes/revisions you have made to someone else's code. - Changes/revisions you have to your own code. Generally, comments should explain enough of the program that someone should know what the code does without having to read each statement. However (and this is the tricky part) comments should not over-explain the details of the code to the point of translating each statement into English. If you develop an appropriate algorithm, usually the English statements in the algorithm should suffice as comments in your code. Want more information on commenting and style? I have a document that is a work-in-progress. See MATLAB STYTLE on the MATLAB RESOURCES link on the website. (2) Selection statements + Logical operators: NOT, OR, EXCLUSIVE OR, logical functions >> 1 % MATLAB thinks of 1 as true >> 0 % MATLAB things of 0 as false >> ~1 % NOT true is false >> ~0 % NOT false it true >> xor(1,1) % xor asks if one item is true, but not both as true >> xor(0,1) % xor asks if one item is true, but not both as true We'll deal with logical functions at another point. See (4) on Lecture 5 notes. + What is the difference between selection and nested selection? A selection statement is an instruction that you provide to the computer to make a choice between one or many options. These options are further statements to execute. Given that a selection statement is indeed a statement itself, the statements that a selection statement will execute can be other selection statements. When you see the syntax if condition statement ... statement end the implication is that each "substatement" is any legal MATLAB, including another selection statement. The ellipsis (...) implies that you may have one to many statements as part of the "outer" selection statement. + Why use a nested selection statement? Imagine that you wish to pick only MacIntosh apples from a basket of items. Perhaps you would pick a particular item in this order: + Pick an item. If it's fruit, remove it from the basket. + If the item is an apple, inspect it further otherwise put it back. + If the apple is MacIntosh, then eat it. Otherwise put it back. You could feasibly write these statements as if (fruit & apple & Mac) then eat But what if you want to do *different* actions for different conditions? For instance, if it's a fruit and an apple but not a Mac, then perhaps you will cook with it. if (fruit & apple & ~Mac) cook if (fruit & apple & Mac) eat But, what if you want to do something different with the fruit and non-fruit items? The conditions for the if-statements become even more ponderous and complex. Sometimes it's more clear to provide more choices using the nested form: if (~fruit) put in non-fruit basket else if (~apple) store in fruit basket else if (Mac) eat else cook What happens is that there's an implicit AND/OR each time you use such a structure. If something is true AND something else is true AND something else is true, do a task. Say the above example in English and you will see. Of course, if you go many, many levels in nesting your code might become more confusing. So, it becomes a style choice sometimes. + How to use switch? I'm more interested in students learning how to learn an "untaught" function/ feature on their own, since that what happens most often with programming. So rather than "saving now, suffering later," I am going to encourage that you "suffer now, save later" by encouraging the following practice for this case: Step 1: Look up help on the item. See MATLAB's Help Browser (which is very informative) or go for broke with $help switch$. Step 2: Read the contents. Usually, I'm impatient, so I look for a brief example. Step 3: Write and test one of the small examples. Make sure it works! Step 4: Read the explanation again. It will be more clear this time. Step 5: Write an example on your own. Likely it won't work because you didn't really follow Step 4 as closely as you should have done. Step 6: Debug your example. Step 7: Write a new example now that you have a sense of how the item works. Generally, writing a bunch of small, simple examples will greatly clarify how some item of code does indeed work. Especially with MATLAB there are many help features to assist as well. (3) Plots + subplots? + complex plots? Don't worry about these for now. We're not doing anything with them for now, if at all, in CS99. (4) $num2str$ (and related) >> help num2str NUM2STR Convert number to string. T = NUM2STR(X) converts the matrix X into a string representation T with about 4 digits and an exponent if required. This is useful for labeling plots with the TITLE, XLABEL, YLABEL, and TEXT commands. T = NUM2STR(X,N) converts the matrix X into a string representation with a maximum N digits of precision. The default number of digits is based on the magnitude of the elements of X. T = NUM2STR(X,FORMAT) uses the format string FORMAT (see SPRINTF for details). Example: num2str(randn(2,2),3) produces the string matrix '-0.433 0.125' ' -1.67 0.288' See also INT2STR, SPRINTF, FPRINTF. So, what does all of this mean? $num2str(x)$ converts whatever $x$ is into a string with the exact same digits that appear in $x$. But, those digits are now characters and not numerical values. If that is unclear, try to distinguish between '1' and 1. The character (and string) '1' refers to the ASCII character 1 and not the numerical value 1. What are ASCII characters? See ascii.txt on Lecture 3. So, sometimes we want to talk about numerical labels without relying on what their values might be. For instance, think of your student ID. Does Cornell ever add or multiply your ID with someone else's? There would be no reason to do so. In fact, althoguh Cornell likely stores your ID initially as in integer, your ID is reported a string. The $disp$ function requires an array of *strings*. How do I know that? I looked up $help disp$. So if you want to report something like, The value of x is 10! you need to convince $disp$ that $x$ is a string, not a number. And yes, you now know a useful function for making that conversion: $num2str$. >> x = 10; >> disp(['The value of x is ',num2str(x)]); The other function $str2num$ is handy if you have received string input from somewhere and you know that the user entered only numerical digits in the string. Generally, $str2double$ is a bit more useful. (5) modulus and remainder >> help mod MOD Modulus (signed remainder after division). MOD(x,y) is x - y.*floor(x./y) if y ~= 0. By convention, MOD(x,0) is x. The input x and y must be real arrays of the same size, or real scalars. The statement "x and y are congruent mod m" means mod(x,m) == mod(y,m). MOD(x,y) has the same sign as y while REM(x,y) has the same sign as x. MOD(x,y) and REM(x,y) are equal if x and y have the same sign, but differ by y if x and y have different signs. See also REM. >> help rem REM Remainder after division. REM(x,y) is x - y.*fix(x./y) if y ~= 0. By convention, REM(x,0) is NaN. The input x and y must be real arrays of the same size, or real scalars. REM(x,y) has the same sign as x while MOD(x,y) has the same sign as y. REM(x,y) and MOD(x,y) are equal if x and y have the same sign, but differ by y if x and y have different signs. REM is a built-in function. An M-file for REM would be the same as MOD with "floor" replaced by "fix". See also MOD. ************** The point of these functions is to divide two values and find their remainder. For instance 10/3 gives a quotient of 3 and a remainder of 1. What does that mean? 3*3 + 1 = 9 + 1 = 10. So, you can divide 10 by 3, but you will be left with 1. I can see why people have trouble with this one. Generally, I recommend that you stick with REM for negative values. If both values are positive, you get the same result: >> mod(10,3) % Divide 10 by 3, find remainder ans = 1 >> rem(10,3) % Divide 10 by 3, find remainder ans = 1 But if you start putting in negative values, MOD gives what you might think is unexpected: >> rem(-10,3) % This seems OK. ans = -1 >> mod(-10,3) % This seems bizarre! ans = 2 (6) try/catch We won't be dealing with this selection statement in CS99. (7) arrays and matricies We won't be dealing with matricies in CS99, though for the purposes of this course they're almost identical to arrays. So, what's an array? An array is a rectangular (or "box-like") arrangement of data. The array holds multiple values, which are generally the same type. Think about tables and spreadsheets. You could effectively implement them as arrays. Because you need to maintain the rectangular grid, each item as a coordinate, which is specified as a row and column index for 2D arrays. Yes, you can actually have multidimensional arrays, but CS99 will focus mostly on 1D and 2D. (You might wonder what 0D is: that's a scalar, or individual, value!) 0D array: >> x = 1 1D array: >> x = [19, -201] % you can leave out the commas >> y = 1:10 2D array: >> x = [1 2 ; 3 4] Indexing: >> y = [10 20 -10 0]; >> y(3) ans = -10 Indexing starts at 1 and goes to the length of the array. Each index (3 in this example) must be an integer or an expression that evaluates to an integer. (8) General + How do you which is the best way to solve a problem given there are many ways to do it? Often it's a matter of taste if the alternatives are all clear. Usually, you need to resort to which approach is most clear to *someone else*, and which approach uses better style. The question of good style is discussed a bit in (1). + solve Exercise 3.6 w/o strcmp? You essentially need to work out a way to look at each day and determine how the names differ. You could count the letters, look for certain patterns, perhaps even write your own version of strcmp. + dealing with impatience in writing algorithms Small programs generally don't need an algorithm. But as you develop larger and larger programs with multiple components, it becomes increasingly difficult to remember how each component interacts let alone what it actually does. There is a "saying," where "sooner to code, longer to program" applies. The more earlier you can figure out what you need and want to do, the less time you will ultimately spend coding and debugging. Plus, jobs that require many people often enforce "though-work" in advance of any develop to prevent wasting of programming resources. The best trick to dealing with the urge to program is to type out your algorithm as a comment block. You will feel as if you're programming, and you are indeed, but not actually coding yet. Plus, your algorithm will eventually become comments that you can cut and paste later on, which saves even more time in the long run. + how to decrease the amount of time spent doing homework Review the lecture notes and examples first. If you are already familiar with the necessary concepts and understand the new material, you will work a lot faster. See also above concerning dealing with impatience. + where are readings posted? See lecture notes document and individual files. They've been there all semester. + statement that stops execution of remaining program You could use $return$. For example, >> 1 == 2, return , 1+1 ans = 0 Generally, you should avoid breaking from your program unless absolutely necessary. It would be a lot better to put your code into a control structure to control what happens if something goes wrong. Actually, the person who asked about try/catch might have been thinking about this, but I want to make sure everyone gets "if" first. + what is point of bits/bytes problem and how does it relate to the course? The problem itself isn't as important as the concepts it requires a student to develop: learn about how to think about a sequential problem, learn how to develop specifications and test cases, form an algorithm, convert the algorithm into control structures to solve the problem. This problem hits so many things, I think it's quite good. However, there are many other problems, so pretty much any would suit. An introductory level, it is often difficult to justify *why* the early skill development is important. You need to build up skills upon skills to eventually solve more complex problems. At some point, you would be asked something like, "We need you to design a widget that does something. Go to it!" What would you do? Years of learning and experience would help you to write programs to analyze the widget and build actual models to run the tests. Few people "higher up" will actually take the time and explain how to write the while and if statements in your code.... If you would like a bit more justfication, check out MATLAB's demos. You can find the actual code in the MATLAB toolboxes if you're curious to see how basic concepts get used. + strings and arrays: what's the connection? An array is a rectangular collection of data. A string is collection of characters, which coincidentally, forms a "line," which you can also think of as a rectangular collection. So, 'hello' is really 'h','e','l','l','o'. What's my proof? Try the following: >> x = ['h' 'i'] >> strcmp(x,'hi') ans = 1 % MATLAB reports true! So, you can actually do something like this: >> x = 'hello' >> x(1) ans = h If you want to be fancier, you can actually replace elements in an array with new values: >> x(1) = 'j' % Make first character in x be 'j' ans = jello + meaning of term INITIALIZE? Give a variable an initial value. + fprintf Doing file I/O in MATLAB can be a bit bonkers because you have so many choices. We will actually deal with this function later for what I think will be the final project. + how to get only integers from rand? See e2solcs99fa02.txt. Short version: take the floor of a random number. The problem is that $rand$ gives a value between 0 and 1, so if you do $floor(rand)$ you will always get zero. To fix that problem, do $floor(rand*something)$, which produces a number that gets it's decimal portion chopped off.