Quiz 01 Practice


Questions

The quiz itself will be similar in difficulty to these practice questions. In addition to these questions, you should review all of your lesson responses on Gradescope. The kinds of questions you responded to on Gradescope could also be on the quiz.

Solutions for each problem can be found at the bottom of this page. (But if you’re unsure, before looking up the solution, try figuring it out on your own or testing it out in Visual Studio!)

Memory Diagrams

Make sure to practice the memory diagrams through “While loops” and “Functions” on the practice page.

While Loops

  1. Produce a memory diagram for the following code snippet, being sure to include its stack and output.

     WORD: str = "happy"
     l1_idx: int = 0
     l2_idx: int = 0
     t1: str = ""
     t2: str = ""
     n_appearances: int = 0
    
     while l1_idx < len(WORD):
         t1 = WORD[l1_idx]
         n_appearances = 1
         l2_idx = 0
    
         while l2_idx < len(WORD):
             t2 = WORD[l2_idx]
    
             if (t1 == t2) and (l1_idx != l2_idx):
                 n_appearances = n_appearances + 1
             l2_idx = l2_idx + 1
         print(f"{WORD[l1_idx]} appears {n_appearances} times.")
         l1_idx = l1_idx + 1

1.1 What would happen if while l1_idx < len(WORD) in line 8 was replaced with while l1_idx < len(WORD) - 1? Why?

1.2 What would happen if l2_idx=0 was moved to inside the second while loop? In other words, what if lines 11-13 were changed to:

while l2_idx < len(WORD):
    l2_idx = 0

1.3 What would happen if, in line 16, if (t1 == t2) and (l1_idx != l2_idx): was replaced with if (t1 == t2):? Why?

1.4 What would happen if line 18 (l2_idx = l2_idx + 1) was removed? Why?

1.5. What would happen if the < symbol in line 8 was replaced with <=? (In other words, what if it was changed to while l1_idx <= len(WORD):)? Why?

Solutions

Functions

  1. The following questions will be in reference to this code block:
    def greet(name: str, friendly: bool) -> str:
        print(f"Hello {name}!")
        if friendly:
            return f"I'm so happy to see you {name}!" 
        else:
            return "Bye!"
    
    def main():
        greet("Lizzie", True)
    
    if __name__ = "__main__":
        main()

1a. On what line(s) is there a return type declaration?

1b. On what line(s) is there a signature?

1c. On what line(s) are there arguments?

1d. On what line(s) are there parameters?

1e. On what line(s) is something returned?

1f. On what line(s) is something printed?

Solutions

  1. The following questions will have you practice signature writing.

2a. Write the signature for a function called name_eval that takes as input someone’s name as a string and returns True if the name has an even amount of letters and False if it has an odd amount of letters.

2b. Write the signature for a function called name_size that takes as input someone’s name as a string and returns the length of their name as an integer.

2c. Write the signature for a function called gcd that takes two floats as input and returns the integer that is their greatest common divisor.

Solutions

While loops and functions

  1. Produce a memory diagram for the following code snippet, being sure to include its stack and output.
    def main() -> None:
        """Main Function"""
        y: int = g(1)
        f(y)
        print(g(f(3)))
        
    def f(x: int) -> int:
        """Function 0"""
        if x % 2 == 0:
            print(f"{x} is even")
        else:
            x += 1
        return x
        
    def g(x: int) -> int:
        """Function 1"""
        while x % 2 == 1:
            x += 1
        return x

    main()

1.1 Why is it that main() is defined above f() and g(), but we are able to call f() and g() inside main() without errors?

1.2 On line 5, when print(g(f(3))) is called, is the code block inside of the while loop ever entered? Why or why not?

1.3 What would happen if a line was added to the end of the snipped that said print(x). Why?

Solution

Solutions

While Loops Solutions

  1. The memory diagram includes a box on the top labeled Output and a box on the bottom labeled Stack, next to an empty area labeled Heap. 
The Stack contains the variables WORD, l1 underscore idx, l2 underscore idx, t1, t2, and n underscore appearances. The WORD variable contains the value happy in quotes. 
The variable l1 underscore idx has the value of 5, with previous values of 0, 1, 2, 3, and 4 all crossed out. L2 underscore idx has the final value of 5, with previous values of 0, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, and 4 all crossed out. T1 has the final value of y with previous values of an empty string, h, a, p, p, and y all in quotes and crossed out. T2 has the final value of y (in quotes) with previous values of an empty string, h, a, p, p, y, h, a, p, p, y, h, a, p, p, y, h, a, p, p, y, h, a, p, and p all in quote and crossed out. Finally, the variable n underscore appearances has the final value of 1 with previous values of 0, 1, 1, 1, 2, 1, and 2 all crossed out. 
The output box contains the sentence h appears 1 times. Below that, on a separate line is the output a appears 1 times. Next, is the line p appears 2 times., p appears 2 times., and y appears 1 times. each on separate lines.

(We do not require that you write out all interim values as long as the initial and final values are correct like in the solution below. However, writing the interim values will help for practice purposes and to avoid mistakes!)

The memory diagram has three columns, labeled from left to right Stack, Heap, and Output. Under the stack, there is a frame labeled Globals. 
The globals frame contains the variables WORD, l1 underscore idx, l2 underscore idx, t1, t2, and n underscore appearances. The WORD variable contains the value happy in quotes. The variable l1 underscore idx has the value of 5 with the previous value of 0 crossed out. The variable l2 underscore idx has the value of 5 with the previous value of 0 crossed out. The variable t1 has the final value of y in quotes, with the previous value an empty string in quotes crossed out. The variable t2 has the final value of y in quotes, with the previous value of an empty string in quotes crossed out. Finally, the variable n underscore appearances has the value 1 with the previous value 0 crossed out.
The heap column is empty.
The output column contains the sentence h appears 1 times. Below that, on a separate line is the output a appears 1 times. Next is the line p appears 2 times., p appears 2 times., and y appears 1 times. each on separate lines.

Here’s a link to a video of the solution!

1.1 “y appears 1 times.” would not print. This is because l1_idx will not enter the while loop for l1_idx = 4. (For more practice, it’d be good to diagram this instance out to see how it would impact the final values of other variables.)

1.2 An infinite loop would occur because l2_idx would always equal 1 when returning to the top of the loop, and therefore l2_idx < len(WORD) will always be True.

1.3 If l1_idx != l2_idx is no longer required, this means that each letter can count itself twice. For example, WORD[0] == WORD[0] is true, so n_appearances for "h" would increase to 2.

1.4 There would be an infinite loop because l2_idx will never increase, and therefore l2_idx < len(WORD) will always be True.

1.5 There would be an index error because there would be the case where l1_idx = 5, so on line 9 WORD[5] would be searching for the element at index 5 in "happy", when the indexes only go up to 4.

Functions Solutions

1a. 1 (optional: 8)

1b. 1, 8

1c. 9 (optional: 12)

1d. 1 (optional: 8)

1e. 4, 6

1f. 2

2a. def name_eval(id: str) -> bool:

(Note that I chose to call the parameter id, but you could’ve chosen any valid name!)

2b. def name_size(id: str) -> int:

(Note that I chose to call the parameter id, but you could’ve chosen any valid name!)

2c. def gcd(number_a: float, number_b: float) -> int:

(Note that I chose to call the parameters number_a and number_b, but you could’ve chosen any valid name!)

While loops and functions Solution

  1. The memory diagram includes a box on the top labeled Output and a box on the bottom labeled Stack, next to an area labeled Heap.
The first frame in the Stack is labeled Globals and contains the variables main, f, and g. The variable main points to a small box on the heap that says fn 1-5. The variable f points to a small box on the heap that says fn 7-13. The variable g points to a small box on the heap that says fn 15-19.
The next frame on the stack is labeled main and contains a return address and a variable y. The return address is 21 and y has a value of 2. The next frame is labeled g and contains a return address, return value, and a variable x. The return address is 2, the variable x has a value of 2 with the previous value of 1 crossed out, and the return value is 3. The next frame is labeled f and contains a return address, return value, and a variable x. The return address is 4, the variable x has a value of 2, and the return value is 2. The next frame is labeled f and contains a return address, return value, and a variable x. The return address is 5, the variable x has a value of 4 with the previous value of 3 crossed out, and the return value is 4. The final frame is labeled g and contains a return address, return value, and the variable x. The return address is 5, the variable x has a value of 4, and the return value is 4.
The output box contains a line that says (in quotes) 2 is even. Then, on the next line it says (in quotes) 4.
Video

1.1 Even though main is defined before f and g, it isn’t called until after f and g are defined.

1.2 No because x = 4, so x % 2 == 1 is False, and therefore the code block inside is never run.

1.3 There would be an error because x is a local variable inside both f and g. In other words, x is NOT a global variable. Therefore, the program does not recognize that x exists in this context.

Contributor(s): Megan Zhang, David Karash, Alyssa Lytle