6 Putting conditionals and words and sentences together | (5 activities) |
Write a procedure named comfort-level that, given a Celsius temperature as argument, returns an indicator of how comfortable the temperature is.
1.Write the procedure comfort-level using cond (without using if) |
2.Write the procedure comfort-level using ifs(without using cond) |
Programs should read like English.Programs are written partly to be run; that's how work gets done with the computer. The Scheme interpreter will run your program regardless of the names you use for procedures and placeholders. For example,(define (foo q) (* q q) )is understood by the Scheme interpreter to be the same thing as (define (square num) (* num num) )Programs are also written to be read by people, however. People might include your instructor or supervisor, your project partner, or even yourself (reading a program a couple of months after you wrote it, and trying to figure out what you meant). Good choices for procedure and placeholder names, as well as good use of comments, can make it significantly easier for someone to understand how to use your program, what it's supposed to do, and how to modify it if necessary. Adding comments to your codeComments start with a semicolon, and are completely ignored by the Scheme interpreter. It is good practice to make an entire line a comment; that is, start the line with a semi-colon. (There are other ways to specify comments we will talk about later). Because comments are ignored by Scheme, they are only relevant for someone reading the program. Programmers typically accompany each procedure they write with a comment that says what the procedure expects as arguments and what it will return for given arguments. Examples of how a procedure is supposed to behave are good to include as part of the explanation. Here is a sample procedure with some comments:;;square: takes a number and squares it ; note: don't use it with anything except numbers ; written by: clint, 18 June 2003 (define (square num) (* num num)) Choosing good names for procedures and variablesGood choices for names depend on the situation. For parameters, a good name gives some idea of the type of value it represents for example, num in the square procedure above. This name explains that you're not expecting to multiply a word by itself. Typically, the name of a procedure that returns a number, a word, or a sentence is a noun that represents the value returned. The name of a predicate procedure one that returns true or falseis conventionally an verb. This is because such procedures are typically used with if, for example:(if (is-legal? x) ... ) (if (is-number? x) ... ) (if (is-word? x) ... )The built-in predicates are not always named as well as they could be. One always has to balance information communicated by a name with the length of that name (a name that's 100 characters long won't be very readable!), and the designers of Scheme valued conciseness a bit more than readability. |
Here's a mystery procedure written by a programmer who chose terrible names. Provide a good comment for the procedure and replace its names with words that communicate much better what the procedure does. Check the other students answers. Did they make the code really easy to understand? Are there comments that don't really explain the code?
; useless comment (define (x y) (word 'un y) ) |
Helper procedures can make a program more readable and more writable.The built-in procedures first, butfirst, sentence, and word are named well enough to tell the reader of a program what it's doing, but not why. Here's an analogy in real life of how terms at this level of detail might not be the best possible way to communicate:You (to your friend): What are you doing? Your friend, responding in obnoxious low-level terms: I'm typing an 's'. Now I'm typing an 'e'. Proper answer: I'm doing my CS 3 homework.A good programmer often defines procedures that don't do much other than provide a good high-level name for a low-level operation. For example, when working with the programs in measurements.scm, you might define helper procedures named feet and inches and use them instead of first and second. Helper procedures are also useful when writing a procedure in the first place. Often a programmer can see how to solve some part of the problem, and writes a helper procedure to do this. Naming that helper procedure can help with designing the rest of the complete procedure to design (and also make the whole solution more readable). |
Analyze and simplify a procedure by defining helper procedures.Here's a procedure that checks whether its arguments represent a valid date in the Gregorian calendar (the one we use in the United States). Simplify it and make it more readable by defining and using well-named helper procedures. When you are done, there should be more code than when you started, but it should be easier to understand. Put you new code, with helper functions, in a file called legal-date.scm.; Return true if the arguments represent a legal date ; in the Gregorian calendar (instituted at the end of 1582). ; (Dates in the future are legal.) (define (valid-date? day month year) (cond ((or (< day 1) (> day 31) (< month 1) (> month 12) (<= year 1582)) #f) ((= day 31) (member? month '(1 3 5 7 8 10 12))) ((= day 30) (not (= month 2))) ((and (= day 29) (= month 2)) (cond ((divisible? year 400) #t) ((divisible? year 100) #f) ((divisible? year 4) #t) (else #f) ) ) (else #t) ) ) (define (divisible? num1 num2) (= 0 (remainder num1 num2))) |
There are many different ways to break down the valid-date? program using helper procedures. Share your code with someone else in the class. Which code do you think is easiest to read and understand? Which do you think is the hardest to read? |
What makes code easy or hard to understand? What will you do to make your own code easier to read? |
Test it to deathWhen programmers simplify code, it is easy to break the code they are supposed to be simplifying. To address this problem, what programmers do in industry is run a ton of tests on the old program and the new program to make sure they do the same thing Give your code a serious testing! When you think you are done, trade code with another group to see if you can break each other's simplified version. What test cases can you think of that the other group might not have. Make sure to explain any bugs you caught in the other team's code. |
The scheme that we use has another way to include comments: surrounding text by #| (at the beginning) and |# at the end. Scheme will ignore anything within these tags. (Most Scheme dialects know about this comment method, but not all do).
Although less simple to use than starting a line with a semicolon, these comments can span multiple lines. As such, they are a convenient way to include test cases in the same file as the procedure you wish to test.
For example:
By including the test cases inside a multi-line comment, they will not be evaluated when the entire file (or emacs buffer) is loaded. However, you can easily copy the individual test cases (or all of them) from your file into your Scheme listener and run them -- simply copy the text just inside the comment tags #| and |#. Adding semicolon comments within a multi-line comment, which is not necessary when the whole file is evaluated, makes copying the test cases easier.;; Square: takes a number and returns its square ; written by Clint, 18 June 2003 (define (square num) (* num num)) #| Test Cases for square ; should return 9 (square 3) ; should return 9 (square -3) ; should give an error (square 'three) |# |
Write an answer procedure. (This will be part of your homework for this lab).Write a procedure named answer that, given a sentence that represents a question, returns a simple answer to that question. (A question's last word ends with a question mark.) If the argument sentence is not a question, answer should merely return the argument unchanged. Here's how the answer procedure should process different kinds of questions.
IMPORTANT: Scheme has some problems with periods. (More correctly, a period means something special in Scheme, and different than punctuation that comes at the end of a english sentence.) You need to put a period in double quotes ("). For example, if you want to put a period at the end of the word "weasel," you would use this code: (word 'weasel ".")For your homework you will put your solution, along with a comprehensive set of test calls for each procedure, into a file named answer.scm inside the lab4 directory. Make sure to use good names and helper procedures to make your program as readable as possible. For this program, you should feel free to collaborate in the initial stages. It will be turned in and graded, but we will be more lenient about collaborative work for this assignment. Certainly, work with your fellow students to understand the problem, and to break it down into logical pieces. You can work together on some of the coding, but you should do the majority of the coding individually. If some of the coding is shared, note with a comment what was shared and with whom. |
Write a time-of-day procedure.Write a procedure named time-of-day that, given a non-negative integer that represents the number of minutes after midnight for that day, returns the time of day in the format described below. Put this procedure, along with a comprehensive set of test calls, in a file named daytime.scm. There are several cases for the format of a time of day.
Note: Don't worry if your answer comes out surrounded by double quotes (like "7:05" instead of 7:05). If you want to get rid of decimal points after numbers, you can use the inexact->exact procedure. As an example, (inexact->exact 1.0) returns 1. |
Homework
|
The first solution presented in the "Difference Between Dates" case study was a dead end. Is it a good idea to study "bad" solutions? Provide an answer and an explanation.
Next homework, we will ask you to comment on the answer of one of your classmates. |