# Example exam problems for Part A (Pitfalls) # Tip: Try to add 4-5 of your own syntax, semantic, style errors # in code you've done on assignments (refer to grading feedback for ideas!) # Reminder: For full credit, you must clearly identify the distinct # errors and justify why they are an error/issue. # Pitfalls 1: Syntax Errors # The following code has 5 distinct Python _syntax_ errors. # What are they? from math import sqrt def is_prime(n): "" Return True if 'n' is prime; else return False. "" if n == 2 or == 3: return True elif n % 2 = 0: return False else for i in range(5, int(sqrt(n) + 1), 2): # odd #s >= 5 if n % i == 0: return False return True # Syntax errors: - 1. On Line 17, n % 2 = 0 should be n % 2 == 0 because = is the operator for assignment, but elif syntax expects a boolean evaluation (n % 2 == 0 evaluates to a boolean) - 2. - 3. - 4. - 5. # Pitfalls 2: Semantic Errors # The following code has 5 distinct _semantic_ (behavior) errors. # What are they? def factorial(n): """ Compute and return the factorial of n i.e. n * (n - 1) * (n - 2) * ... * 1, or 1 if n == 0. """ assert n >= 0 while True: n -= 1 if n <= 0: return result = n * result print(result) def e(limit): """ Estimate the constant e (2.71828...) by the series expansion: e = sum (i from 0 to infinity) (1 / factorial(i)), except we use a limit to cut off the expansion (OK if the limit is large enough). """ result = 0 for i in range(0, limit + 1): # 0 to limit, inclusive result += 1 / factorial(i) return result print(e(20)) # should print 2.7182818284590455 # Pitfalls 2: Semantic Errors - 1. - 2. - 3. - 4. - 5. # Pitfalls 3: Style Errors # The following code has 5 distinct _style_ errors. # What are they? def w(x, y, z): "rt es in x in [y-z,y+z]." v=[] for i in x: if i >= y - z and i <= y + z: v+=[i] else: i=i return v # Style Errors - 1. - 2. - 3. - 4. - 5. - 6. # Another example exercise for style (from 23fa Lecture 26 demo) 1 def count_shared(dict1, dict2): 2 """ 3 Returns the number of key/value pairs in dict1 that are 4 also in dict2. e.g. {'a': 'x', 'b': 'y', 'c': 'x', 'e': 'x'} shares 5 2 key/value pairs with {'a': 'x', 'b':'x', 'c':'x', 'd':'x'} 6 ('a':'x' and 'c':'x'). 7 """ 8 count = 0 9 keys = list(dict1.keys()) 10 for i in range(len(keys)): 11 key = keys[i] 12 for key2 in dict2: 13 if keys[i] == key2: 14 a = dict1[key] 15 b = dict2[key2] 16 if a == b: 17 count += 1 18 return count # Style Errors - 1. Various variable names are undescriptive, such as a, b, key, key2 This is a style issue because it detracts from readability (for others or the author reading it later) and can lead subtle bugs. - 2. - 3. - 4. - 5. - 6. # Example of a solution a student may provide to support their answer # (we came up with this at the end of class); we won't deduct on minor issues # since you aren't allowed to use any debugger/tools or run the program, # and it can help justify your written answers more clearly (e.g. this problem # in particular has a lot of logical redundancy that can be cleaned up in # multiple lines) Improved code: 1 def count_shared(dict1, dict2): 2 """ 3 Returns the number of key/value pairs in dict1 that are 4 also in dict2. e.g. {'a': 'x', 'b': 'y', 'c': 'x', 'e': 'x'} shares 5 2 key/value pairs with {'a': 'x', 'b':'x', 'c':'x', 'd':'x'} 6 ('a':'x' and 'c':'x'). 7 """ 8 count = 0 # Loop through dict1's keys to see if the key is also in dict2 for key in dict1: # same as list(dict1.keys()) if key in dict2: val1 = dict1[key] val2 = dict2[key] if val1 == val2: count += 1 return count