CS51A - Fall 2019 - Class 8

Example code in this lecture

   scope.py
   scope2.py
   debugging.py
   debugging_with_prints.py

Lecture notes

  • What will be printed out when we run scope.py code?
       - When we run the file, the first two functions will get defined
       - Then, it will execute the three statements at the end of the file
       - The first print statement will print out 20
       - The second print statement will print out 30
          - Why not 60? I.e., in double_input, we assigned 20 to val as the first line.
             - val = 2*val updates the value of the parameter *NOT* the variable outside the function

  • The "scope" of a variable is the portion of the code we can reference that variable in and have it be valid
       - Scope diagrams
       - When we declare a variable in the interpreter, what is its scope?
          >>> x = 10

          - the scope is any shell statements/expressions typed after it
       - When we declare a variable (outside a function) in a file, what is its scope?
          - anywhere below it in the file
             - remember, running a program is very similar to typing those commands into the shell
       - When we declare a variable inside a function, what is its scope?
          - anywhere below it in the FUNCTION
       - What is the scope of the parameters?
          - anywhere in the FUNCTION
          - it doesn't really make sense outside of the function since we wouldn't have a value for it

       - Additionally, the scope also defines the context for a variable reference.

       - What would be printed out if we ran scope2.py code?
          - the program starts at the top and declares three "global" variables x, y and z
          - then it declares two functions
          - then it calls mystery1 with 10 and 20
             - the parameter a gets the value 10
             - the parameter z gets the value 20
                - notice that this is *different* than the global variable z!
                - in particular, when we execute z = 100, this reassigns the value of the local z, but not the global
             - The program prints out s, x, y and z
                - s is a local variable
                - x and y are global
                - z is the parameter
             - and then sets the value of the global variable z to 100
          - After mystery1 returns we print out the values of the global variables x, y and z
             - all three are unchanged!
                 - x and y weren't changed anywhere
                - z was changed in mystery1, but the z being changed was the parameter, not the global z

       - What would happen if we added a call to mystery2 at the end and ran scope2.py code?
          - Error. The scope of a is only defined within mystery1, so it cannot be accessed anywhere outside the function.

       - Why do programming languages limit a variable's scope?

  • debugging
       - The quatruple_input function in debugging.py code attempts to quadruple the inputs value by adding it four times
       - However, if you run it, say with 5:
          >>> quadruple_input(5)
          6

          we get the wrong answer

          (In fact, no matter what you run it with, you always get the same answer!)

          >>> quadruple_input(2)
          6
          >>> quadruple_input(10)
          6

       - A "bug" is a behavior in the code that is not intended. Debugging is the practice of trying to find and fix bugs.
       - You might be able to look at the code and find the bug in this example. However, if you can't, you can try and add more information to your program to figure out what the problem is.
       - Adding print statement is one good way to figure out what your function is doing
       - Look at debugging_with_prints.py code
          - If we run this version, we start to see what the problem is:
          >>> quadruple_input(5)
          A: T 0 I 5
           --
           B: T 0 I 0
           C: T 0 I 0
           --
           B: T 0 I 1
           C: T 1 I 1
           --
           B: T 1 I 2
           C: T 3 I 2
           --
           B: T 3 I 3
           C: T 6 I 3
          D: T 6 I 3
          6


       - The problem is that we've used the input parameter as the variable in the for loop and the value is getting lost!
       - The fix is to use a different variable name here (e.g., 'i')
       - When you're all done debugging and your code works, make sure to remove the print statements!
       - It's worth taking ten seconds to make your print formatting nice
        - In loop vs out of loop
        - Iteration boundaries
        - Labels for positions


  • string methods
       - a few that might be useful (though there are many there)
          - lower

          >>> s = "Banana"
          >>> s.lower()
          'banana'

          >>> s
          'Banana'

              - Remember, strings are immutable!

          - replace
          >>> s.replace("a", "o")
          'Bonono'

          >>> s
          'Banana'

             - remember that strings are immutable
             - if you want to update a variable after the method has been applied, you can do the following:

             >>> s
             'Banana'
             >>> s = s.replace("a", "o")
             >>> s
             'Bonono'

          - find

          >>> s.find("a")
          1
          >>> s.find("q")
          -1
          >>> s.find("a", 2)
          3

          - count

          >>> s.count("a")
          3
          >>> s.count("b")
          0

  • write a function find_letter(string, letter) which returns the index of the first occurrence of letter in string

  • Brief introduction to the debugger
       - Step in/step out/step over
       - View call stack
       - View stack frame, i.e. variables in local scope