Diagnostic 1: Solutions and Learning

October 9th, 2020


The purpose of the Diagnostic was to help you self assess where you can improve. Every single person in this class has some area of the material where they could use some extra practice. In this document we are going to go over each of the problems in the diagnostic.

Here is a link to your answers:
http://cs106a.stanford.edu/cgi-bin/purplebookauth/diagnostic1.cgi

Here is the full distribution:

Regrade Requests
We try to grade as consistently as possible, but we are human and we might make mistakes. If you feel like one of your problems was misgraded, please file a regrade request on this form before Saturday October 17th at 1pm. Note that this is the only way to have your regrade request considered; in particular, asking your section leader to take a quick look to see whether a problem was misgraded isn't a way of short circuiting this process. We want you to have the credit you deserve, but filing a formal request helps us make sure that your request goes to the right person.

Can I get extra help?
Yes! We are hosting two live sessions to discuss the midterm where folks from the teaching team go over the problems and you can ask questions live. They will be recorded!
Thursday, 10-11pm PDT: zoom link(Password: 228769)
Friday, 9-10am PDT: zoom link (Password: 349944)
If those are in high demand we are happy to host more.

How can I check my answers?
With this document you can check your answer. For each problem we include

  1. Several common solutions
  2. Comments which explain the solutions
  3. The major concepts that the problem covers
  4. Which readings and which lecture videos relate to the problem

I wasn’t able to solve many of the problems on the diagnostic. Should I panic?
Absolutely not! It is normal to find these problems hard. If you didn’t do as well as you would have liked you have a two step procedure. Step 1: make sure you know the underlying concepts (for example, using the i variable in a for loop). Then if you know the concepts but you weren’t able to come up with solutions in time the simple solution is practice and review! Many people incorrectly think that they are not good at this. False! We all can code. You just need more experience. Check out the review session.

My answer is different from the provided solution. Is my answer wrong?
Not necessarily. You will learn a lot by looking at the difference between the teaching team solution and your work. Your answer might be great. There are many solutions.

Can I discuss my solution on ed?
Yes! You are free to share your solutions


Problem 1: Debugging & Tracing

Part A: The print in the second line of main is not showing the value that the user entered because the function get_user_number() does not return anything.
Part B: A call to count_to_zero(5) would not print what is expected, because the variable value is not reassigned in the function. So, it will continually print 5.
# Part C:
# fix part a
def get_user_number():
  value = int(input('Enter an int: '))
  return value
 
# fix part b
def count_to_zero(value):
  print(value) # fencepost! Must print one more time
  while value != 0:
    if value > 0:
      # decrease value
      value = value - 1  # or value -= 1
    else:
      # increase value
      value = value + 1 # or value += 1
    print(value)
Concepts:

Part A focuses on functions and return values. Part B focuses on variables and updating them. If you found it confusing, here are a few resources: This chapter covers functions and return values. Return values are notoriously one of the hardest concepts in the first half of CS106A. These lecture slides and video cover functions and return values:
Lecture 7 Slides
Lecture 7 Video

Problem 2a: Square Table

# There are several ways to solve this problem:

# Solution 1: Using index of a for loop
def main():
    print("x    x^2")
    print("--------")
    for i in range(100):
        print(i, i*i) # same as: print(str(i) + "    " + str(i*i))
        

# Solution 2: Using a while loop
def main():
    print("x    x^2")
    print("--------")
    x = 0
    # its ok to use a while loop, but make sure you
    # understand the for loop solution
    while x < 100:
        print(x, x*x) # same as: print(str(x) + "    " + str(x*x))
        x += 1
Concepts:

The major concept here is "using the index of a for loop". This was covered at the end of Lecture 6, control flow revisited. You might want to also check out the for loop chapter in the reader. This is a 10/10 important problem. If you missed any points here this is a great place to start for review.

Problem 2b: When is CS106A

# The unit of time zones in "hours ahead of London"
STANFORD_TIME_ZONE = -7

# Units are, hours after midnight. CS106A starts at 1pm
CS106A_STANFORD_START_TIME = 13 

def main():
    #get user input 
    user_time_zone = int(input("What is your timezone in hours ahead of UTC? "))
  
    #calculate local time
    local_time = (CS106A_START_TIME - STANFORD_GMT_OFFSET + user_time_zone)
  
    # if it is the next day in their timezone, wrap around
    if local_time >= 24:
        local_time -= 24
    
    print("CS106A starts at "+ str(local_time) +" in your timezone")
Concepts:

The major concept here is input, variables and arithmetic expressions. You can review Lecture 5. Some students will have found timezones themselves confusing. If so that is absolutly fine. We wanted to have one problem with a small application to real life. Learning about timezones in useful in life, but won't show up in future CS106A problems :-).

Problem 3: Flatten Pile

def main():
    move() # get to the pile
    while beepers_present():
        flatten_one_beeper()
        move_to_pile()

def flatten_one_beeper():
    """
    Picks up a single beeper and puts it in the next
    availible slot. 
    Pre: Assumes Karel is standing on the pile
    Post: Karel is on the last flattened beeper
    """
    pick_beeper()
    move()
    while beepers_present():
        move()
    put_beeper()

def move_to_pile():
    """
    Karel moves back to the pile of beepers
    Pre: Karel is at the end of the beeper row
    Post: Karel is standing on the pile
    """
    turn_around()
    while front_is_clear(): # beepers_present() ok
        move()
    turn_around()
    move()

# given in the problem
def turn_around():
    for i in range(2):
        turn_left()

# given in the problem
def turn_right():
    for i in range(3):
        turn_left()
            
Concepts:

The main concept here is while loops. Here is the reader chapter: Python reader chapter covering while loops. Here is the video where we cover while loops: Lecture 2. This problem also required you to come up with a strategy, which can be hard. If you found it time consuming the best bet is to practice with more Karel problems. Did you decompose? While not required it makes the problem much easier to manage and faster to code.

Problem 4: Flatten Pile

import random NUM_FLIPS = 15

# Solution 1:
def main(): 
  last_flip = -1 
  longest_run = 0 
  current_run = 0 
  for i in range(NUM_FLIPS): 
    flip = random.randint(0, 1) 
    print("Flip #", i + 1, ":", flip) 
    if flip == last_flip: 
      current_run += 1 
      if (current_run > longest_run): 
        longest_run = current_run 
    else: 
      current_run = 1 
    
    last_flip = flip 
  
  print("Length of longest run:", longest_run) 

# Solution 2:
def main(): 
  flips = [] 
  for i in range(NUM_FLIPS): 
    flip = random.randint(0, 1) 
    flips.append(flip) 
    print("Flip #", i + 1, ":", flip) 
  
  longest_run = 1 
  current_run = 1 
  for i in range(1, NUM_FLIPS): 
    if flips[i] == flips[i - 1]: 
      current_run += 1 
      if (current_run > longest_run): 
        longest_run = current_run 
    else: 
      current_run = 1 
  print("Length of longest run:", longest_run)
Concepts:

The main concept here is variables and more specifically updating them as you move through different coin flips. If you found it difficult to know which variables to store and when to update them, that is normal. This is a challenging problem. Here is one way to think about it: For each coin flip, there are two cases we are concerned with. Either the flip is the same as the previous flip, or it is different. In the former case, we want to record that this is part of a “run”, so we would want to increase the count of current “run”. In the solutions, we do this in current_run += 1. We then want to ask ourselves, is this the longest run we have seen so far? If it is, we want to store that information somewhere so we can print it out later. In the solutions we store it in a variable called longest_run. If the flip is different from the previous flip, our “run” is over so we reset our variable current_run to be 1.
If you want more practice with variables check out Lecture 4 on variables and Lecture 6 revisting control flow. This problem also asked you to use random numbers. Check out Lecture 5 if you want to review how to generate a random number.

Problem 5: Interesting List

def make_interesting_list(num_list): 
  result = [] 
  for value in num_list: 
    if value >= 0: 
      if (value % 2) == 1: # Check if value is odd 
        result.append(value * 10) 
      else: 
        result.append(value) 
  return result
Concepts:

The main concept in this problem is looping over and modifying elements in a given list. This is a common pattern in programming. Lists were very new at the time that you took the diagnostic, so if you found this problem difficult that is normal. They are an important concept and will be used often throughout the rest of 106A. To review lists check out these lecture slides and video:
Lecture 9 Slides
Lecture 9 Video

That’s all folks! Thanks for your hard work