CS21 Lab 4: functions and while loops

Due Saturday, Feb 22, before midnight

Goals

  • Write programs with multiple functions.

  • Solve problems using indefinite while loops.

  • Learn to use pseudo-random numbers.

Function Comments

All functions should have a top-level comment! Please see our function example page if you are confused about writing function comments.

1. alldigits function

In previous programs, when getting an integer from the user, we have usually done something like this:

number = int(input("number: "))

This will crash if the user enters something that can’t be converted to an integer (e.g., "zebra"). It would be nice if we could test the user input before we try to convert it to an integer. Something like this:

number = input("number: ")
if alldigits(number):
   number = int(number)
else:
   print("please enter an *integer*!")

In the alldigits.py file, write an alldigits(string) function that, given a string, returns True if all of the characters in the string are digits ("0","1","2",…​"9"). For example, calling alldigits("1234") would return True, and calling alldigits("zebra") would return False.

This function won’t work for negative integers, since the negative sign isn’t one of the digit characters, but it is good enough for now.

We have already provided some simple test cases for you in main(). Once you finish your function, make sure the tests all show the correct values:

$ python3 alldigits.py
0:    123   True
1:  1 2 3  False
2:  zebra  False
3:     99   True
4:    99!  False
5:    -99  False

2. menu function

In the file called menu.py write a menu(opts) function that, given a python list of strings (user options), displays the strings as a numerical menu and asks the user for their choice. The function should return the option number (an integer) chosen by the user.

This function should work with any list of string options. For example, if the list of options is ["yes","no"], your function will display a simple menu with two options:

 1. yes
 2. no

and then ask the user to choose one of the options (1 or 2). Similarly, if the list of options is ["sit","stay","bark"], your function will display:

 1. sit
 2. stay
 3. bark

Your function needs to work for any size python list (2 options, 5 options, 27 options, etc), and should return an integer in the range 1-len(opts).

Furthermore, your function needs to check that the user entered a valid number. You can copy your alldigits(string) function into this file and use that to make sure the user enters a positive integer. Just copy the alldigits(string) function — make sure you don’t copy a second main() function into your program.

Once you know you have an integer, make sure the user enters a number from the displayed menu, asking again if they enter a number too high or too low. Once the function gets a valid number, it should return that number as an integer to main().

Here’s an example of the full program, with the user entering invalid integers at first. Note how the function continues to ask again and again until the user enters a valid choice (hint: use a while loop for that part).

$ python3 menu.py
 1. yes
 2. no

your choice --> 0
please enter a valid choice!!!

your choice --> zebra
please enter a positive integer...

your choice --> -1
please enter a positive integer...

your choice --> 99
please enter a valid choice!!!

your choice --> 1
You chose: 1

In menu.py we’ve already written a simple main() function to test your menu function.

def main():
    opts = ["yes","no"]
    choice = menu(opts)
    print("You chose:", choice)

Once your function is working, please add at least one additional option ("maybe"?) to opts in main() to make sure your function works with more than two options.

$ python3 menu.py
 1. yes
 2. no
 3. maybe

your choice -->

3. patterns

This program will use various functions to draw patterns in the terminal window. We’ll write and test each function as we go, then use the menu(opts) function from above to allow the user to pick which function to run.

Start by writing and testing each of the following functions (in patterns.py).

3.1. write the block(n,ch) function

This function takes a number (n) and a character (ch) and prints a block of nxn characters. For example, calling block(5,"X") would display this to the terminal:

XXXXX
XXXXX
XXXXX
XXXXX
XXXXX

and calling block(10,"Q") would display a 10x10 block of Qs.

In patterns.py add your block(n,ch) function and call it with a simple main() function to test that it works:

def main():
    n = int(input("n: "))
    block(n,"X")

3.2. write the triangle(n,ch) function

Similar to the block() function, this function takes a number and a character, and displays a triangle pattern. Calling triangle(7,"Y") would display this:

Y
YY
YYY
YYYY
YYYYY
YYYYYY
YYYYYYY

In patterns.py add your triangle(n,ch) function and call it from main() to test that it works.

3.3. write the reverse(n,ch) function

Similar to the triangle() function, this function takes a number and a character, and displays a reverse triangle pattern. Calling reverse(5,"P") would display this:

    P
   PP
  PPP
 PPPP
PPPPP

In patterns.py add your reverse(n,ch) function and call it from main() to test that it works.

3.4. write the diamond(n,ch) function

Last one! Calling diamond(5,"J") would display this:

    JJ
   JJJJ
  JJJJJJ
 JJJJJJJJ
JJJJJJJJJJ
JJJJJJJJJJ
 JJJJJJJJ
  JJJJJJ
   JJJJ
    JJ

Notice that, for the above example, the first 5 lines just look like the output of reverse() and triangle() put together. You can’t call them together to make those 5 lines, but you can use code similar to what’s in those functions to display the first 5 lines. Then the bottom 5 lines can be done with a separate for loop.

In patterns.py add your diamond(n,ch) function and call it from main() to test that it works.

3.5. add the menu(opts) function

Finally, copy your menu(opts) and alldigits(string) functions from the previous program to patterns.py. Then rewrite main() to allow the user to pick which pattern to draw, or to quit the program. If the user decides to display a pattern, pick the number (n) and the character (ch) using the random library. Make the number from 5-15, and the character an uppercase letter from A-G. If you haven’t used random numbers in class yet, see our random library help page for info on using the random library in python (hint: see the randrange() and choice() functions).

Your final program should allow the user to continue selecting patterns to draw, until they select the "quit" option.

Here’s one possible run of the final program:

$ python3 patterns.py
 1. block
 2. triangle
 3. reverse
 4. diamond
 5. quit

your choice --> 1
CCCCCCCCCC
CCCCCCCCCC
CCCCCCCCCC
CCCCCCCCCC
CCCCCCCCCC
CCCCCCCCCC
CCCCCCCCCC
CCCCCCCCCC
CCCCCCCCCC
CCCCCCCCCC

 1. block
 2. triangle
 3. reverse
 4. diamond
 5. quit

your choice --> 2
F
FF
FFF
FFFF
FFFFF
FFFFFF
FFFFFFF
FFFFFFFF
FFFFFFFFF
FFFFFFFFFF
FFFFFFFFFFF

 1. block
 2. triangle
 3. reverse
 4. diamond
 5. quit

your choice --> 1
BBBBBB
BBBBBB
BBBBBB
BBBBBB
BBBBBB
BBBBBB

 1. block
 2. triangle
 3. reverse
 4. diamond
 5. quit

your choice --> 1
GGGGGGGGG
GGGGGGGGG
GGGGGGGGG
GGGGGGGGG
GGGGGGGGG
GGGGGGGGG
GGGGGGGGG
GGGGGGGGG
GGGGGGGGG

 1. block
 2. triangle
 3. reverse
 4. diamond
 5. quit

your choice --> 3
              A
             AA
            AAA
           AAAA
          AAAAA
         AAAAAA
        AAAAAAA
       AAAAAAAA
      AAAAAAAAA
     AAAAAAAAAA
    AAAAAAAAAAA
   AAAAAAAAAAAA
  AAAAAAAAAAAAA
 AAAAAAAAAAAAAA
AAAAAAAAAAAAAAA

 1. block
 2. triangle
 3. reverse
 4. diamond
 5. quit

your choice --> 5

4. Answer the Questionnaire

Each lab will have a short questionnaire at the end. Please edit the Questions-04.txt file in your cs21/labs/04 directory and answer the questions in that file.

Once you’re done with that, run handin21 again.

Turning in your labs…​.

Remember to run handin21 to turn in your lab files! You may run handin21 as many times as you want. Each time it will turn in any new work. We recommend running handin21 after you complete each program or after you complete significant work on any one program.