Stanford, Winter 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:
>>> 10 - 2 * 3 - 2 + 1 ??? >>> 52 % 10 ??? >>> s = 'Python' >>> s[:3] ??? >>> s[3:] ???
b. What 3 numbers print when the caller() function runs? This code runs without error.
def foo(a, b): a = 2 * a b = 2 return a + b def caller(): a = 2 b = 3 c = foo(b, 1) print(a, b, c)
# What 3 numbers print ???
Bit is facing the right side of the world. Below bit is empty space. Move bit forward 1 or more squares until solid ground appears below. This is the top of a flat mesa. Move bit forward across the top of the mesa until empty space appears below. Turn bit to face the bottom of the world. Move bit forward until blocked.
Bit before and after:
def do_mesa(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) a blank rectangle a pixels high and the same width as the original image at the upper left of the output image. (2) a horizontally flipped copy of the original image immediately below the blank rectangle. (3) To the right of the rectangle and image, a vertical aqua stripe b pixels wide, running down the height of the output image. Please try to avoid writing too close to the right edge of the paper.
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. It's ok if you need to put the parameters on multiple lines to make it fit.
3. Write the loops and other needed code to produce the aqua stripe at the right side. These are separate loops, not nested inside the earlier loops. You can change a white pixel to aqua by setting its red 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 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" pixel_out.red = pixel.red pixel_out.green = pixel.green pixel_out.blue = pixel.blue #### 3. Fill aqua rectangle
a. Given a string s, return a string such that: for every alphabetic char in s, the result has 2 copies of that char. Omit non-alphabetic chars.
'#abc6' -> 'aabbcc' | def double_alpha(s): 'Yo' -> 'YYoo' | ',,X,Y' -> 'XXYY' |
b. Given a string s. Find the first dot '.'
in s. If there is a digit immediately before the '.'
, such as the '1'
in 'x1.c24z'
, call that the first digit. Look for a second digit exactly 3 chars after the dot, such as the '4'
in 'x1.c24z'
. If the first and second digits are both present, return their arithmetic sum. If only the dot and first digit are present, return the first digit's value squared. If there is no dot or no first digit, return -1.
'x1.c246z' -> 5 | def digit_dot(s): 'ab12.cc71cc' -> 9 | 'x1.aa91b' -> 10 | 'abc9.zz5' -> 14 | 'a23.zzz' -> 9 'bb5.zz' -> 25 'aa.zzz' -> -1 '.' -> -1 'zzz' -> -1
c. Given a string s, find the first '^^^^'
in s. Then find the first '^^'
that comes after the '^^^^'
, returning None
if either is not found. For an input like 'xx^^^^aaaa^^bb'
return 'bbaaaa'
. That is, return a string made of the chars after the '^^'
followed by the chars between the '^^^^'
and the '^^'
. Use s.find() and slices.
'xx^^^^aaaa^^bb' | def hat_str(s): -> 'bbaaaa' | 'xx^^^^ it^^so be' | -> 'so be it' | '^^^^1^^2' -> '21' | '^^^^xyz' -> None 'nopexyz' -> None
In this problem, every square is one of these four values: empty None
, squirrel 's'
, apple 'a'
, or banana 'b'
. The 'a'
and 'b'
are the "food" squares. As usual, you can get full credit for each part independently of what you write on the other parts.
a. Write a helper function same_food(s1, s2) that takes 2 values representing grid contents. The s1 and s2 parameters will always be drawn from the four values: None, 's', 'a', 'b'
. Return True if both s1 and s2 are 'a'
, or they are both 'b'
, i.e. s1 and s2 are the same food. In all other cases, return False. Here are example cases expressed as Doctests:
>>> same_food('a', 'a') True >>> same_food('b', 'b') True >>> same_food('a', 'b') False >>> same_food(None, None) False >>> same_food('s', 's') False
def same_food(s1, s2):
(b) The function de_squirrel(grid, x, y, n)
will be called with an in-bounds x, y. This function will attempt a "de-squirrel" action to make a squirrel disappear. Write code for the de-squirrel action with these steps:
1. There must be a squirrel at x, y for the action to proceed.
2. Consider the 2 squares: (1) the square immediately above the squirrel, and (2) the square 1 column to the right and exactly n squares below the squirrel. The parameter n will be an int, 1 or greater.
3. Call the helper from part (a) to check if the two squares identified in the previous step contain the same food. If so, change the square containing the squirrel to None so the squirrel disappears, and return the changed grid. The foods are not removed.
4. In all other cases, leave the grid unchanged and return it.
def de_squirrel(grid, x, y, n):
(c) Add the two lines to complete the following Doctest for a call to de_squirrel() where the de-squirrel action succeeds and the squirrel disappears. The first Grid.build() line is provided which builds a small grid suitable for this Doctest.
>>> grid = Grid.build([['a', None], ['s', None], [None, 'a']]) >>>
This problem uses an encryption scheme somewhat like the homework. As a simplification, assume the char to encrypt is not uppercase. The encryption uses a source list of lowercase chars, a slug list with both lowercase chars and digits, and an additional "digital" list of lowercase chars. The source and slug lists are the same length. (The example lists below show just 4 source chars as a simplification):
source = ['a', 'b', 'c', 'd'] slug = ['d', '2', 'b', '0'] digital = ['k', 'm', 'e', 'w'] indexes 0 1 2 3
Write code to encrypt an input char with the following algorithm:
1. If the input ch is not in the source list, its encrypted form is simply the char itself, e.g. '$' -> '$'
2. As on the homework, consider the index of the input ch in the source list, and the slug char at the same index. For example, for input ch 'a'
, the index is 0
, and the slug char is 'd'
.
3. If the slug char is a digit, e.g. '2'
, the encrypted form is the char at that digit index in the digital list. For example, for the input 'b'
, the slug char is '2'
, so the encrypted form is at index 2
in the digital list, e.g. 'e'
. The digital list is guaranteed to be sufficient length to support all the digit chars which appear in the slug list. Note that the elements in all the lists are strings.
4. Otherwise, if the slug char is not a digit, the slug char itself is the encrypted form.
Encryption examples 'a' -> 'd' 'b' -> 'e' (via '2') 'c' -> 'b' 'd' -> 'k' (via '0') '$' -> '$"
def encrypt_char(source, slug, digital, ch): # Your code here
### 1 Short Answer 3 2 Pyt hon Function call: 2 3 8 ### 2 Bit def do_mesa(filename): bit = Bit(filename) # Move to mesa top while bit.right_clear(): bit.move() # Move across the top while not bit.right_clear(): bit.move() # Down to the bottom bit.right() while bit.front_clear(): bit.move() ### 3 Image out = SimpleImage.blank(image.width + b, image.height + a) pixel_out = out.get_pixel(image.width - 1 - x, y + a) # or equivalently pixel_out = out.get_pixel(out.width - b - 1 - x, y + a) for y in range(image.height + a) # or out.height for x in range(b): # Need to shift over by image.width out_pix = out.get_pixel(image.width + x, y) out_pix.red = 0 ### 4 Strings def double_alpha(s): result = '' for ch in s: # or for/i/range if ch.isalpha(): result += ch + ch return result def digit_dot(s): dot = s.find('.') # Screen out bad-dot cases if dot == -1 or dot == 0: # dot == 0 -> no char to its left return -1 if s[dot - 1].isdigit(): # Second digit? make sum of both digits if dot + 3 < len(s) and s[dot + 3].isdigit(): return int(s[dot - 1]) + int(s[dot + 3]) # Otherwise first digit squared return int(s[dot - 1]) * int(s[dot - 1]) return -1 def hat_str(s): first = s.find('^^^^') second = s.find('^^', first + 4) # Search after first if first == -1 or second == -1: return None return s[second + 2:] + s[first + 4:second] ### 5 Grid def same_food(s1, s2): # v1 - maybe the most straightforward if s1 == 'a' and s2 == 'a': return True if s1 == 'b' and s2 == 'b': return True return False # v2 shorter if s1 == s2 and (s1 == 'a' or s1 == 'b'): return True return False # v3 "or" detect the ways it can be False if s1 != s2 or s1 == None or s1 == 's': return False return True def de_squirrel(grid, x, y, n): if grid.get(x, y) != 's': return grid if grid.in_bounds(x, y - 1) and grid.in_bounds(x + 1, y + n): # Not required, but putting grid contents in vars s1 = grid.get(x, y - 1) # above squirrel s2 = grid.get(x + 1, y + n) # to the right and below if same_food(s1, s2): grid.set(x, y, None) return grid # Doctest >>> grid = Grid.build([['a', None], ['s', None], [None, 'a']]) >>> de_squirrel(grid, 0, 1, 1) [['a', None], [None, None], [None, 'a']] ### 6 Cryptography def encrypt(source, slug, digital, ch)" if ch in source: # Find slug char at same index idx = source.index(ch) crypt = slug[idx] # What if it's a digit? if crypt.isdigit(): num = int(crypt) return digital[num] return crypt return ch