Stanford, Fall 2023-24
# CS106A Exam Reference Reminder # [square brackets] denote functions listed here that we have not used yet # Exam questions will not depend on functions we have not used yet Bit: bit = Bit(filename) bit.front_clear() bit.left_clear() bit.right_clear() bit.get_color() bit.move() bit.left() bit.right() bit.paint('red') [bit.erase()] General functions: len() int() str() range() [list() sorted()] String functions: isalpha() isdigit() isspace() isupper() islower() find() upper() lower() strip() List functions: append() index() [extend() pop() insert()] SimpleImage: # read filename image = SimpleImage(filename) # create blank image image = SimpleImage.blank(width, height) # foreach loop for pixel in image: # range/y/x loop for y in range(image.height): for x in range(image.width): pixel = image.get_pixel(x, y) Grid 2D: grid = Grid.build([['row', '0'], ['row', '1']]) grid.width, grid.height - properties grid.in_bounds(x, y) - True if in bounds grid.get(x, y) - returns contents at that x,y, or None if empty grid.set(x, y, value) - sets new value into grid at x,y
a. By each ???
, write what value comes from the Python expression:
>>> 1 + 2 * 3 - 4 - 1 ??? >>> 26 % 5 ??? >>> s = 'Python' >>> s[:2] ??? >>> s[3:] ???
b. What 3 numbers print when the caller() function runs? This code runs without error.
def foo(a, b): a = 2 * a return a + b def caller(): a = 3 b = 4 c = foo(b, 1) print(a, b, c)
# What 3 numbers print ???
For this problem, the add_green() function is provided. The precondition for add_green() is that bit is facing a lone black block, a block with clear squares all around it. The add_green() function moves bit to the opposite side of the block, paints that square green, and finally moves bit back to the initial start square and facing direction. Assume that this function is correct and can be called from the function you implement below.
def add_green(bit): ...
Write code for the green_above() function, calling the add_green() function: Bit is facing the right side of the world. There are lone black blocks in the row above bit's path. Move bit forward until blocked. For each moved-to square, if there is a block immediately above bit, paint the square on the opposite side of the block green.
Bit before and after:
def green_above(filename): bit = Bit(filename) # Your code here
Given an image filename and ints a and b which are 1 or more. Produce a new out image with three features: (1) at the top, a blank stripe 10 pixels high forming the top of the output image. (2) a vertically flipped copy of the original image, with a blank margin area a pixels wide on both sides. (3) At the bottom of the output, a yellow stripe b pixels high running across the width of the output. Add your code in the 3 indicated places to complete the function.
1. Write one line of code to create the out image.
2. Almost all of the code to write the flipped image is provided — looping over the original image, writing the colors at each "pixel" to "pixel_out". Write the one line of code which sets the "pixel_out" variable used by the later lines in this loop.
3. Write the loops and other needed code to produce the yellow rectangle. These are separate loops, not nested inside the earlier loops. You can make a white pixel yellow by setting its blue value to 0. We'll assume there is a return out
as the last line.
def do_image(filename, a, b): image = SimpleImage(filename) #### 1. Create "out" image (Write one-line below) # Write flipped image to out for y in range(image.height): for x in range(image.width): pixel = image.get_pixel(x, y) #### 2. Set "pixel_out" (Write one-line below pixel_out.red = pixel.red pixel_out.green = pixel.green pixel_out.blue = pixel.blue #### 3. Fill yellow rectangle # (Your code here)
a. Given a string s, return a new string made of all the chars from s which are 'd'
or 'o'
or 'g'
(not case sensitive).
'xdxggy' -> 'dgg' | def doggy(s): 'DOggy' -> 'DOgg' | 'abdGxo' -> 'dGo' | 'xyz' -> '' |
b. Given a string s. Find the first '@'
in s. If there is a digit 3 chars after the '@'
, such as the '6'
in 'x@106'
, then return the numeric value of that digit doubled. If there is no '@'
or no digit, then return -1. Use the s.find() function.
'x@106x' -> 12 | def digit2x(s): 'xx@ab51' -> 10 | 'x@abx' -> -1 | 'abc@' -> -1 | 'abc' -> -1 |
c. Given a string s, find the first double left-bracket '[['
in s, and the first double right-bracket ']]'
. If the double left-brackets are before the double right-brackets, then return a new string where the text between the brackets is replaced by the string 'NOPE'
. If the left or right double brackets are missing or they are in the wrong order, then return the empty string. Do not use loops. Use s.find() and slices.
'xx[[hi there!]]zzz' -> | def nope(s): 'xx[[NOPE]]zzz' | 'a[[]]b' -> 'a[[NOPE]]b' | 'xx[[abc' -> '' | 'xx]]abc' -> '' | 'x]]ab[[' -> '' |
This problem has two parts, and you can get full credit for each part regardless of what you did on the other part. We have a Grid representing Stanford campus and every square is either a squirrel 's'
, a tree 't'
, an acorn 'a'
, or empty None
. The function squirrel_magic(grid, x, y, n)
will be called with an in-bounds x, y, to attempt a squirrel "move" to make an acorn disappear. (a.) Write code for the move with these steps:
1. There must be a squirrel at x, y for the move to proceed.
2. If there is an acorn in the square immediately below the squirrel, then the acorn disappears and the move is over.
3. Otherwise, if there is an acorn in the row immediately above the squirrel and exactly n squares to the left of the squirrel, then the acorn disappears and the move is over. The parameter n will be an int value 1 or greater.
In all cases, the function should return the grid (changed or not) when done.
def squirrel_magic(grid, x, y, n):
(b.) Write one Doctest for a call to squirrel_magic() where an acorn disappears. As a reminder of the syntax, here is a working Doctest from the movie scroll_left() lecture example which shifts each letter one square to the left.
>>> grid = Grid.build([['a', 'b', 'c'], ['d', None, None]]) >>> scroll_left(grid) [['b', 'c', None], [None, None, None]] # squirrel_magic() Doctests:
This problem uses an encryption scheme somewhat like the homework. As a simplification, assume the char to encrypt is not uppercase. The encryption uses 3 lists of lowercase chars: source1, source2, and slug (the example shows the alphabetic chars 'a'-'d'
as a simplification):
source1 = ['a', 'b', 'c', 'd'] source2 = ['d', 'c', 'b', 'a'] slug = ['c', 'd', 'a', 'b'] indexes 0 1 2 3
Write code to encrypt a char with the following algorithm:
1. To use the slug, the char (ch) must be in both source1 and source2. If it is not in both lists, its encryption is simply the char itself, e.g. '$' -> '$'
2. Consider the index of ch in both source1 and source2. If the index in source1 is smaller or equal to the index in source2, then the encryption will use the index in source1: the encryption is the slug char at the source1 index. e.g. 'b' -> 'd'
and 'a' -> 'c'
3. Otherwise the index in source2 is the smaller index. In that case, the encryption is the slug char at the source2 index, converted to uppercase, e.g. 'd' -> 'C'
and 'c' -> 'D'
def encrypt_char(source1, source2, slug, ch): # Your code here
#### 1 Short Answer 2 1 Py hon 3 4 9 #### 2 Bit # key idea: using helper properly # to add green to each block def green_row(filename): bit = Bit(filename) while bit.front_clear(): bit.move() if not bit.left_clear(): # detect block bit.left() # pre-fn add_green(bit) # call helper bit.right() # post-fn #### 3 Image # (1) out image out = SimpleImage.blank(image.width + 2 * a, image.height + 10 + b) # (2) vertical flipped image pixel_out = out.get_pixel(a + x, 10 + image.height - 1 - y) # or pixel_out = out.get_pixel(a + x, out.height - b - 1 - y) # (3) yellow rectangle for y in range(b) for x in range(out.width): # or (image.width + 2 * a) pixel_yellow = out.get_pixel(x, 10 + image.height + y) pixel_yellow.blue = 0 #### 4 Strings def doggy(s): result = '' for ch in s: # for/i/range also fine low = ch.lower() if low == 'd' or low == 'o' or low == 'g': result += ch return result def digit2x(s): at = s.find('@') if at == -1: return -1 if at + 3 < len(s) and s[at + 3].isdigit(): return int(s[at + 3]) * 2 return -1 def nope(s): left = s.find('[[') right = s.find(']]') if left == -1 or right == -1: return '' # Right before left = wrong order if right < left: return '' # Slice for each side, 'NOPE' in the middle! return s[:left + 2] + 'NOPE' + s[right:] #### 5 Grid def squirrel_magic(grid, x, y, n): if grid.get(x, y) != 's': return grid # Acorn below if grid.in_bounds(x, y + 1) and grid.get(x, y + 1) == 'a': grid.set(x, y + 1, None) return grid # Acorn - up and to the left if grid.in_bounds(x - n, y - 1) and grid.get(x - n, y - 1) == 'a': grid.set(x - n, y - 1, None) return grid # No acorn return grid # squirrel first row, acorn below it (smaller grid fine too) >>> grid = Grid.build([[None, 's', None], [None, 'a', None]]); >>> super_snack(grid, 1, 0, 1) # Squirrel at 1,0 [[None, 's', None], [None, None, None]] # Acorn gone #### 6 Encryption def encrypt_char(source1, source2, slug, ch): if ch in source1 and ch in source2: # Index numbers in each source i1 = source1.index(ch) i2 = source2.index(ch) # source1 index smaller -> use it if i1 <= i2: return slug[i1] # Otherwise the other index, uppercased return slug[i2].upper() return ch