CSC151 2007S, Class 16: Iterating Over Lists Admin: * DrFu seems to start faster if you use the same computer. * Reading for Thursday: Recursion Basics. (It's even ready.) * No homework during the week of take-home exams. * Are there questions on exam 1? Overview: * Building new lists from old with map. * Doing something with each value in a list with foreach!. * Drawing lists of spots. /Exam Questions/ Can I write (+ 3 (if (test) 2 4)) Yes ... you can nest ifs, just like you nest anythinga > (define x 3) x > (define y 4) y > (+ 10 (if (< x y) x y)) 13 > (define y 1) y > (+ 10 (if (< x y) x y)) 11 > What's the difference between making a color greyer and making an image greyer? * In making a color greyer, you affect just a color (as in rgb.redder) * In making an image greyer, you apply that procedure to every pixel in the image (using image.map or image.map!) * How can you put *that* into a lambda function (define function (lambda (image) (image.map! ___ image))) In drawing a circle, you're going to write some complicated (simple?) test to determine whether or not a point is in the circle You will then use that test as follows: (region.compute-pixels! image __ __ __ __ (lambda (pos) (if (MY_TEST_SHOWS_THAT_THE_POS_IS_IN_THE_CIRCLE) color DONT_DO_ANYTHING))) Use "transparent" for "DONT_DO_ANYTHING" /Parts of an Algorithm/ * Write functions that encapsulate code (lambda (params) body) (define name (lambda (params) body)) * Need to be able to choose between thing ("if it's in the circle, do ..; otherwise, do ...) (if test conseq alt) (cond ...) (and ...) * Name values for clarity (define name value) * Basic operations provided by the system rgb.new * Repeat * Sequence /Bigger Picture/ * To design an algorihtm, you must understand the problem * And figure out a way to approach that problem * Which you best do collaboratively * Try to write code that people can read * Indentation helps * Generalize /Annoying Aspects of Algortihm Assembly/ * Figuring out the syntax (where the parens go in Scheme) /Today: Repeating Actions/ * N techniques for repeating actions * List each action in turn * A pain to write * Not very general * For images * image.map! - change each pixel in an image * image.map - compute a new image by applying some function to each pixel * region.compute-pixels! - build a region of the image * If our repetition is not just for images, we're out of tools * Today: Repeating using lists * Thursday, Friday, Monday, Tuesday, and beyond: General Technique Recursion /Repetition for Lists/ * Do "something" with each element of the list * Build an element of a new list * map * e.g. (map (lambda (x) (+ 2 x)) (list 1 2 3 4 5)) > (map (lambda (x) (rgb.darker x)) (list color.yellow color.green color.blue color.blood-red)) (-269549313 15663359 61439 1442840831) > (map rgb->string (list color.yellow color.green color.blue color.blood-red)) ("255/255/0" "0/255/0" "0/0/255" "102/0/0") > (map rgb.darker (list color.yellow color.green color.blue color.blood-red)) (-269549313 15663359 61439 1442840831) > (map rgb->string (map rgb.darker (list color.yellow color.green color.blue color.blood-red))) ("239/239/0" "0/239/0" "0/0/239" "86/0/0") > * Changing lists is evil, so we won't let you do that * Do something else, that doesn't involve build a new list * Given a series of horizontal offsets, draw a picture at that offset * foreach! We can draw a list of spots with (foreach! (lambda (spot) (image.set-pixel! canvas (spot.col spot) (spot.row spot) (spot.color spot))) spots)