Functional Problem Solving (CSC 151 2015F) : Assignments
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] - [FAQ] [Teaching & Learning] [Grading] [Taking Notes] [Rubric] [Remote Access]
Current: [Assignment] [EBoard] [Lab] [Outline] [Reading]
Sections: [Assignments] [EBoards] [Labs] [Outlines] [Readings] - [Examples] [Handouts]
Reference: [Setup] [VM] [Errors] - [Functions A-Z] [Functions By Topic] - [Racket] [Scheme Report (R5RS)] [R6RS] [TSPL4]
Related Courses: [Curtsinger (2015F)] [Davis (2013F)] [Rebelsky (2015S)] [Weinman (2014F)]
Misc: [Submit Questions] - [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] - [Issue Tracker (Course)]
Part One (Proposal) Due: 10:30 p.m., 16 November 2015
Part Two (Implementation) Due: 10:30 p.m. 24 November 2015
Summary: At this point in your career, you've learned a number of techniques for making images algorithmically. This project is an opportunity for you to explore some techniques in greater depth.
Purposes: To explore some aspect of image generation in depth. To emphasize the more creative components of this course. To encourage more purposeful image creation and reflection on algorithms.
Collaboration: We encourage you to work in groups of size two. You may, however, work alone or work in a group of size three. You may discuss this assignment with anyone, provided you credit such discussions when you submit the assignment.
Submitting: Email your submissions to
<grader-151-01@cs.grinnell.edu>. The title of your email should have
the form Project and should contain
your response to the appropriate part of the assignment. Scheme
code or plain text should be in the body of the message. For part
two, you will also submit two sets of three images and your
statements following the instructions at the bottom of this
assignment.
Some resources:
Warning: So that this assignment is a learning experience for everyone, we will almost certainly spend class time publicly critiquing your work.
We highly recommend that you read and understand all parts of the assignment document before you begin your work on the project.
While the primary focus of this course is on learning how to write, describe, test, and analyze algorithms, our secondary focus is on writing algorithms that generate “interesting” images. We have certainly explored a wide variety of techniques for generating images. We have seen a variety of basic approaches. In particular, you can
image-compute-pixels!;
image-variant and
image-transform!;
You also know a number of other algorithmic techniques that could support creating images, such as various numeric functions, using lists and vectors to store collections of data (e.g., colors and brushes), and techniques for repetition and recursion.
It is now time to challenge yourself to use some of these ideas together to create images of your own design.
Rather than writing code that creates a single image, however, we want to challenge you to think about algorithmic processes that can create many different images depending on the given parameters. Hence the title, “a procedure is worth a thousand pictures.”
You will write a procedure, (, that generates the
image-series
n width
height)nth image in a series of at least 1000
related images. (You should be sure your procedure works for
at least the integers between 0 and 999, inclusive; however, you
may be more successful if you support a larger range of values.)
The images should be reproducible: that is, if a user gives the
same n, width, and
height twice, the resulting images should
be the same. You should not use randomness to vary the images;
instead, the differences should be based solely on the choice of
n.
In creating these images, you should use at least three different techniques for generating images that we have learned this semester (see list above for most of the approaches).
You should strive to make these “interesting” images, images that will hold the viewer's attention. As we have noted, representational images and completely symmetrical images are less likely to hold the viewer's attention. (For example, in a picture of a cat on a landscape, the viewer is likely to say “yup, that's a cat on a landscape” and move on.) You should also be intentional about choosing colors for your images.
Your process should scale appropriately. That is, a 1000x1000 image should look similar to a 100x100 image, just bigger (and probably slower to compute). We will certainly use your procedure to create relatively large images that we could comfortably print on a full page or use as a desktop background. You should also deal with different aspect ratios: an image that is 200x100 should look similar to the one that is 100x100, just twice as wide. (Two exceptions to this scaling rule: you do not have to scale the non-scalable brushes , such as the pattern brushes; and the shapes you draw with a turtle need not accommodate different aspect ratios.)
To begin your project, write a proposal consisting of two major parts.
The first part, which we will call the design statement, is intended for non-programmers and should explain the intent of your series. Are you exploring color? The use of shapes? The illusion of depth or motion? The effects of unpredictability on an image? Why? Incorporate the Elements and Principles of Two Dimensional Design and ideas about Design and Color.
After your design statement, include a sketch of at least two images from the series showing what you intend your images to look like and how they are likely to differ. (We would prefer hand-drawn sketches, although you may also generate them on the computer.)
The second part, which we will call the technique statement, is intended for your peers (that is, folks who know about as much programming as you do). This statement should explain your algorithm at a high level (in English) and how it will create the images you described and sketched in the first part. Be sure to explicitly list the three (or more) algorithmic image-generating techniques from class that you plan to use. Also explain clearly and convincingly how you will ensure that your algorithm creates at least 1000 distinct images.
Your statements should display the hallmarks of quality writing. Given that the paragraph is the “unit of composition” (according to Strunk and White), and each of these statements asks you to address several important considerations, it is likely that each statement will consist of several coherent, unified paragraphs.
We will do our best to respond to your proposal in a timely manner. However, given other constraints, we may not be able to do so.
After finishing your proposal, you should set to work on implementing your design, making sure to meet all of the specifications outlined above.
Once you complete your procedure, update and revise your design and technique statements to reflect how your project actually turned out. If there are points of divergence, you should explain why you changed your approach.
In addition, be certain your final, revised technique statement mentions the three (or more) algorithmic image-generating techniques you are using. It should also explain--via careful, precise reasoning--how you know that your procedure creates at least 1000 distinct images.
Finally, tell us three values of n that, when given as
parameters to your procedure, cause it to produce especially interesting
(and distinct) images.
Copy your proposal into the body of an email message and send
to <grader-151-01@cs.grinnell.edu>; turn in your sketches at the
beginning of class the next day (Tuesday).
Email your program, updated statements, and representative values of
n to <grader-151-01@cs.grinnell.edu> with the subject
Project.
Because it might take a while to create images, you should also provide us with copies of certain images. We would like two sets of images: one giving the three images you've chosen as particularly nice representatives of your series, and the other showing how well your procedure scales the images to different sizes. Here's how.
username1-username2.
.rkt file containing your Scheme
code into this directory.
n and create images of size 50x50, 100x100,
200x200, 100x200, and 200x100 with that n.
username1-username2.nnn.size.png, where
username1, etc., are the usernames of the team members,
nnn is the number used to generate the image, and
size is the size of the image (e.g., 50x50,
100x100, 100x200, 200x100, 200x200, or 500x500).
For example, for the 100x200 image with an n of 32, Professor Davis would use
davisjan.032.100x200.png.
username1-username2.statements.txt.
.tar.gz file you just created to the
email where you turn in your assignment.
Making your image scale correctly is one of the more difficult aspects of this assignment, but the requirement is there to help ensure that you consider important computational aspects of the problem.
Some parts of your image should be relatively straightforward,
if not not necessarily simple. For the Gimp tools
procedures like image-select-ellipse!
and image-draw-line!, you will need
to calculate parameters based on the width and height of
the image. For parts of your drawing based on procedures like
image-compute, you should modify the column and
row in such a way that you take the width and height into account.
And if we scale both width and height by the same amount, your calls
to turtle-forward! can scale by that amount
Other parts may be slightly more difficult, particularly when the aspect ratio changes. For example, suppose we double the width of an image, and keep the height the same. It's hard to take a turtle-generated polygon and make it twice as wide. And it's equally hard to make a brush twice as wide without making it twice as tall. For cases like this, you still need to “scale” your computation, but you can do it in terms of a computed value of the image (e.g., just the width, just the height, the maximum of the two, the minimum of the two, the arithmetic or geometric average, or something similar). Whatever choice you make, you need to document.
A few parts may be essentially impossible to scale. For example, Gimp provides some useful and interesting brushes whose size it seems difficult to change. You may certainly use such brushes, but you should take the time and effort to explain their use and the ways in which their use affects your ability to scale and stretch.
Note that there is a procedure that resizes and rescales any image. You may not use that procedure (except to resize or rescale a source image).
The ( procedure lets you save
an image you've made. By calling it with appropriate parameters, you
can save large swaths of your series (at least until GIMP or
DrRacket crashes).
image-save image
path-to-file)
;;; Procedure:
;;; num->id
;;; Parameters:
;;; num, an integer in the range 0 to 999
;;; Purpose:
;;; Compute a string id (typically for file names)
;;; Produces:
;; id, a string
;;; Preconditions:
;;; [No additional]
;;; Postconditions:
;;; (string-length id) = 3
;;; (string->number id) = num
;;; Practica:
;;; > (num->id 5)
;;; "005"
;;; > (num->id 55)
;;; "055"
;;; > (num->id 555)
;;; "555"
(define num->id
(lambda (num)
(let ([idplus (string-append "00" (number->string num))])
(substring idplus (- (string-length idplus) 3)))))
;;; Procedure:
;;; image-series-file
;;; Parameters:
;;; prefix, a string (e.g., "/home/student/Desktop/student")
;;; n, an integer in the range 0 .. 999, inclusive
;;; width, a positive integer
;;; height, a positive integer
;;; Purpose:
;;; Create the nth image in the series at the specified size,
;;; and save in an appropriate file
;;; Produces:
;;; [Nothing; called for the side effect]
;;; Practica:
;;; > (for-each (lambda (i)
;;; (image-series-file "/home/student/Desktop/student"
;;; i 200 200))
;;; (iota 100))
(define image-series-file
(lambda (prefix n width height)
(let ([filename (string-append prefix
"." (num->id n)
"." (number->string width)
"x" (number->string height)
".png")]
[image (image-series n width height)])
(image-save image filename)
(gimp-image-delete image))))
In class, we will have two discussions, one about the aesthetics of your work and your success in meeting the criteria you have stated for yourself, and another about the techniques you use to create your images.
Your grade will be based on your statements, your code, and your success in combining multiple techniques. We will use this rubric (or a slight variant) to assess your project.
While we appreciate clever and interesting images, if you read the rubric carefully, you'll note that most of the points depend on your success at meeting the basic requirements: Do you have 1000 distinct images? Do your images scale properly? Are you using at least three different techniques? Make sure that you are sure that you've addressed each of these requirements.
Here are some issues that normally lead to teams losing points. Make sure that you check these issues.
(image-series n width height).
The procedure is supposed to return an image id. The procedure is
not supposed to show the image.
image-series procedure is supposed to accommodate
all values of n between 0 and 999. Make sure that you've
checked your procedure with n values of 0, 1, 2, 998, and 999.
image-series procedure on
relatively small images (e.g., 200x200). Make sure that your procedure
functions at that size.
n” is not by itself an argument that you have
1000 different images. We've seen cases in which there are four choices
for one component, five for another, eight for another, and ten for
anouther. 4*5*8*10 is 1600, which is more than 1000. However, the
components were chosen by taking (mod n 4),
(mod n 5), (mod n 8), and (mod n 10).
In that case, the images cycle every 40 values. Work on making more
careful arguments.