SmithLogo

CSC 111

Introduction to Computer Science Through Programming

Smith Computer Science



Lecture Notes 10: More Loops





Before we start: testing in Replit

Let's see the output of an "almost correct" submission for HW02:

(Student "frankpablo" in Replit)

Errors:

  • An "erroneous expected output from a function call" (IMPORTANT)
  • An "erroneous expected output for a print test" (not important)



  • Three concepts: None, in, and is

    None

    If one does not explicitly return a value in a vunction, the default "return" is None.

    None is a python reserved word, used to define a "null value", or "the absence of a value".



    Example:

     1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  
    10  
    11  
    12  
    13  
    14  
    def main():
      num = 5
      
      # If I try to get a return value from no_return
      ret_value = no_return(num)
      
      # I get None
      print (ret_value)
    
    def no_return (num):
      print("only displays num: ", num)
    
    if __name__ == "__main__":
        main()  
    


    Try it Here





    in

    The Membership Operator in returns True if a sequence with the specified value is present in the object.

    Example:

    1  
    2  
    3  
    word = "abracadabra"
    print ("ada" in word) # prints True
    print ("aaa" in word) # prints False
    


    One can also ask the opposite!

    1  
    2  
    3  
    sentence = "the password is 'Cat'"
    print ("Yak" not in sentence) # prints True
    print ("Cat" not in sentence) # prints False
    


    is

  • The Equality operator (==) compares the values of the operands on either side and verifies that they are the same.
  • The Inequality operator (!=) compares the values of the operands on either side and verifies that they are the same.

  • The is operator checks whether both the operands refer to the same object or not (they are located in the same memory location and therefore also have the same value).
  • The is not operator checks whether both the operands refer to different objects or not (they are located in different memory locations... and might or might not have the same value).
  • We will check a clear visual representation of this once we see lists and move on to classes and objects.

    Check out the nice summary on Operators.




    Recap: range

    the usage of range is:
    range(start, stop, step)

    this function returns a sequence of numbers, starting from the indicated start value (or 0 by default), incrementing by the step value (1 by default), and stopping before the indicated stop value.



    Activity 1 [5 minutes]:

    Form groups and, in your Replit Scratchpad, try all of the following ranges inside a for loop (by replacing the section marked as < range here >):

    for i in <range here>:
      print(i, end=" ")
    


  • range(10)
  • range(0, 10)
  • range(1, 10)
  • range(1, 10, 2)
  • range(1, 10, 3)
  • range(-10)
  • range(-10, 0)
  • range(10, 3)
  • range(10, 3, -1)
  • range(10, 3, -2)
  • range(10.5)



  • for loops, the in operator, and strings

    One of the benefits of the versatility of python and the in operator is that we can do the following:

    def main():
      word = "evolutionarily"
      vowels = "aeiou"
      num_v = 0
      num_c = 0
      for char in word:
        if char in vowels:
          print(char,"is a vowel")
          num_v+=1
        else:
          print(char,"is a consonant")
          num_c+=1
    
      print("The word {:s} has {} vowels and {} consonants".format(word, num_v, num_c))
    
    if __name__ == "__main__":
        main()
    




    Try it out here




    Reviewing while and for

    Let's first build a couple of simple loops:

    Activity 2 [2 minutes]:

  • In your Replit Scratchpad, write a for loop that prints all the even numbers from 10 to 0 (in a single line)
  • Now, write a while loop that prints all the odd numbers from 11 to 1 (in a single line)
  • Now, let's convert while loops to for loops and vice-versa:



    Activity 3 [2 minutes]:
    First, analyze the following code and explain what it does (and how!)

    Then, open up your scratch pad (Replit) and transform the following While Loop into a For Loop

     1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  
    10  
    11  
    12  
    13  
    14  
    def main():
      num = 5
      fac = mystery_func1(num)
      print("The result for {:d} is {:d}".format(num, fac))
    
    def mystery_func1(x):
      mult = 1
      while x > 1:
        mult *= x
        x-=1
      return mult  
    
    if __name__ == "__main__":
        main()
    


    Activity 4 [2 minutes]:
    First, analyze the following code and explain what it does (and how!)

    Then, open up your scratch pad (Replit) and transform the following For Loop into a While Loop

    def main():
      word = "evolutionarily"
      li_counts = vowel_counts(word)
      print("The vowel counts in {:s} are {}".format(word, li_counts))
    
    def vowel_counts(word):
      wrd_low = word.lower()
      vowels = "aeiou"
      v_count = 0
      # note the cool way to iterate chars over a string!
      for char in wrd_low:
        if char in vowels:
          idx = vowels.find(char)
          v_count += 1
      return v_count  
    
    if __name__ == "__main__":
        main() 
    







    Nested Loops

    Nested loops are loops done inside of other loops.

    They are useful for many reasons, but a clue that we'll probably need one is when you have multiple dimensions to work through:

    1. For each student, get the average of all their grades
    2. For each word in a paragraph, check each one of its letters
    3. For each inner-list in an outer list, print out the inner-list's elements
    4. etc

    Notation for nested loops

    There is nothing to add!

    You already know how to write a loop, simply write a loop inside a loop!



    Activity 5 [2 minutes]:
  • In your Replit Scratchpad, write a for loop that prints all the numbers from 1 to 5
  • Now, instead of the print statement inside the for loop, insert a properly indented for loop that prints the numbers 1 to 7




  • The important thing to note is that the external for loop causes the internal one to run its code several times.



    Let's see some examples:

    Example 1: a number pyramid



    We wish to generate the following structure:







    First attempt (no nesting)

     1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  
    10  
    11  
    12  
    13  
    14  
    15  
    16  
    17  
    18  
    19  
    20  
    21  
    def main():
      pyramid() # prints 5 levels of numbers
    
    def pyramid():
        for j in range(1):
            print(j+1, end=" ")
        print()        
        for j in range(2):
            print(j+1, end=" ")
        print()    
        for j in range(3):
            print(j+1, end=" ")
        print()    
        for j in range(4):
            print(j+1, end=" ")
        print()    
        for j in range(5):
            print(j+1, end=" ")
    
    if __name__ == "__main__":
        main()
    


    Look at the code Here

    Activity 6 [2 minutes]:
    In the same way we asked before, do you notice any code that is repeated?




    Attempt 2: Nesting!

    Let's use out old friend: a loop to take advantage of "automated repetition!"

    Steps:







    Let's try it:

    Steps:

    You should end up with something like this:

     1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  
    10  
    11  
    12  
    def main():
      pyramid() # prints 5 levels of numbers
    
    def pyramid():
        for i in range(1,5):
            for j in range(i):
                print(j+1, end=" ")
            print()        
       
    
    if __name__ == "__main__":
        main()
    
    You can see it in action Here!

    Attempt 3: Nesting using input parameters

    For greater versatility, we can change the number of times we repeat the outer loop based on some input parameter!

     1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  
    10  
    11  
    12  
    def main():
      pyramid(7) # prints <argument> levels of numbers
    
    def pyramid(lim):
        for i in range(1,lim+1):
            for j in range(i):
                print(j+1, end=" ")
            print()        
       
    
    if __name__ == "__main__":
        main()
    


    Check it out Here!




    Homework

    [Due for everyone]

    Assignment 03 is out (Due 02/18 at 5PM)

    [Optional]
    ZyBooks Sections 4.8 - 4.12