Skip to content

Homework 6: While Loops

Objectives

  • while loops:
    • User input with sentinel values
    • Until reaching a numerical threshold
    • Iterating over a list
  • using the random module
    • Generating a random integer in a range
    • Simulating probabilities by using random.random()

Notices

Submissions Limited

For HW6, you may submit each exercise up to 20 times. Before you submit to Gradescope, make sure that you:

  1. Test your code, either in the shell or in the __main__ block.
  2. Run !ruff check, and resolve all issues.

Don't Use for

This homework is about while loops. Be sure not to use for loops (next week's topic) in any of the exercises.

Stubs Provided

To save you time on this assignment, we are giving you starter files with all the docstrings already written. Download and unzip HW6-stubs.zip. Don't forget to write your name at the top of each file!

Executable Documentation

๐Ÿ’ก Python's doctest module provides features that facilitate testing code. If function docstrings in your program include example function calls, doctest will notice them, and if you ask it to (see the stubs for the following homework problems), doctest will run your functions with the documented example arguments and alert you if the result doesn't match the docstring.

To try it out, open any of the downloaded "stubs" in Thonny and click Run.

Exercise 6.1 Division Algorithm

Computers aren't born knowing how to perform integer division; they must be programmed to do it. One such method is the division algorithm, described below.

Say you want to divide an integer n โ‰ฅ 0 by an integer d > 0. To find the quotient and remainder, follow these steps:

  1. Initialize the variable q with the value 0.
  2. Initialize the variable r with the value n.
  3. As long as r โ‰ฅ d, repeat the following:
    • Add 1 to q.
    • Subtract d from r.
  4. Then q will be the quotient and r will be the remainder.

You can test you've done it right by checking that n = q * d + r.

In a file named division.py, write a function divide that takes two parameters, number and divisor, in that order, that performs the division algorithm to find number รท divisor and returns the two values q and r in that order.

Warning

The goal of this exercise is to implement the division algorithm using a while loop. Do NOT use the division, integer division, or modulo operators in your solution.

Exercise 6.2 Dice Rolling Simulator

For board games and tabletop RPGs, players often need to roll different kinds of dice to determine their progression in the game. Let's create a program named dice.py that can help!

For this exercise, you will need to use the random module. At the top of your program, after the docstring, make sure to import the module:

import random

Write a program named dice.py. It must contain a function called roll_dice.

The roll_dice function must take in two arguments:

  • num_dice (an integer): The number of dice to roll.
  • num_sides (an integer): The number of sides on each die.

If either num_dice or num_sides are 0 or less, the function must return -1.

Otherwise, this function must simulate rolling num_dice dice, each with num_sides sides, and return the total sum of all the rolls. Use a while loop to accomplish this. Each die has possible values ranging from 1 to num_sides (inclusive). For instance, a die with six sides can give you equally possible outcomes of 1, 2, 3, 4, 5, or 6.

You must call the random.randint function to get a random side for each die. See the Python documentation to understand what arguments and return value this function has.

Warning

Do not call other functions from the random module (or call randint more than once per die – if you have three dice, you must call randint exactly three times), otherwise your code may not pass Gradescope!

Testing: In order to test your code, we will set a "seed" value for the random number generator. These numbers are not truly random; instead the seed value dictates the sequence of numbers that gets generated. Thus, setting a seed will guarantee that the sequence is the same every time. You should not set a seed in your code; we do that in the autograder. See the provided docstring for an example (used by doctest).

Exercise 6.3 Wheel of Fortun…ate Events

You are tasked to create a program for a game show called "Wheel of Fortunate Events". In the game, players spin a large wheel for cash prizes. The wheel is split up into segments, like slices of a pie. The player keeps spinning the wheel and accumulating cash until they land on Game Over and cash out their total. The segments have different sizes, so the probability of each outcome is different:

Outcome Probability
$1 25%
$20 25%
$50 15%
$100 12.5%
$1000 2.5%
Game Over 20%

You must write a program called fortunate.py to simulate this. Your program must have two functions: spin_wheel and play_game.

  1. The spin_wheel function has no parameters. The function must first simulate spinning the wheel and then return the number of dollars won (as an int), or 0 if the wheel landed on Game Over. You must simulate spinning the wheel once by calling random.random(), which will return a number in the range [0.0, 1.0). You must then use this value to determine where the wheel landed.

    For instance, if you were spinning a wheel with four colors, each with equal probabilities, the code would be (note how the probabilities accumulate with each elif):

    result = None
    spin = random.random()
    
    if spin < 0.25:
        result = "red"
    elif spin < 0.5:
        result = "blue"
    elif spin < 0.75:
        result = "green"
    else:
        result = "yellow"
    

    Note

    We are testing your spin_wheel() function by calling it 100,000 times and computing the probability of each outcome. You can write your own test code to call spin_wheel multiple times and keep track of how often each outcome occurs. If you do not use random.random(), your code may fail Gradescope.

  2. The play_game function also has no parameters. This function must simulate spinning the wheel and accumulating cash until the wheel lands on Game Over. Your play_game function must call spin_wheel to get the outcome of each spin. You must keep track of the total amount of cash and total number of spins, until the wheel lands on Game Over.

    The function must return a tuple consisting of the total cash earned, followed by the total spins (including the one that caused the Game Over).

Exercise 6.4 Little Free Library

photo of little free library

A Little Free Library is a community library that lets people borrow and contribute books. The library survives on the "take a book, leave a book" principle. If someone takes a book (like "Project Hail Mary"), they should (eventually) return the book or add another book to the library (like "The Martian"). It's a great way for people to share books!

In this lab, you will create a kiosk.py program to simulate a kiosk that someone might have running on a small computer in their Little Free Library. To conserve power, this program will not use the typical Graphical User Interface features (visual buttons to tap or click), but will rely on a text-based user interface instead.

In your new kiosk.py file, you only need to write 1 function:

main(books)

The main function should define a parameter books which will be a list of strings. Each string is a title of a book in the little library. (There can be duplicates, indicating there is more than one copy of a book in the library [or that there are 2 different books with the same title in the library].)

In the main function:

  1. Initialize action_log as an empty list.
    • as the patron interacts with the program, add any valid selections they make below, with the exception of exit, to the end of this list
  2. Display a welcome message, followed by the menu of actions (functions) this program can perform, and a prompt to the user, inviting them to select an action:
    • welcome message:
      ===================================
      Welcome to the Little Free Library!
      ===================================
      
      This kiosk supports the following actions:
      
      1. List the books
      2. Search for a book by title
      3. Take a book (let us know which title you're taking)
      4. Give a book (let us know that you're donating or returning a title)
      0. Exit
      
      Please enter the number for the action you wish to perform:
      
  3. Perform the selected action:
    • if they entered an invalid action,
      1. print a message to help, "Invalid choice: WRONG THING THEY ENTERED"
      2. repeat from #2
    • otherwise, for valid inputs, call the following function for each selection:
      1. list_books
        1. call the imported list_books function.
        2. list_books will return the number of books that were printed.
        3. print "Listed X books of the Y in inventory." where X and Y are replaced with the actual values
      2. search_books
        1. prompt the patron to: "Enter book title (or part of it) to search for: "
        2. call the imported search_books with their response
        3. print the result
      3. remove_book
        1. prompt the patron to: "Enter the book title you are taking: "
        2. call the imported remove_book with their response
        3. remove_book will return True if the book was present and able to be removed, and False if it wasn't
          1. if they entered a title in the inventory,
            1. print "Enjoy reading 'THE TITLE THEY ENTERED'!"
          2. if they entered a title that is NOT in the inventory,
            1. print "Sorry, we don't have 'THE TITLE THEY ENTERED' right now."
      4. add_book
        1. prompt the patron to enter the title of the book they're depositing, "Enter the title you are donating or returning: "
        2. call the imported add_book with their response
        3. add_book will return the new size of the inventory after adding the new book
        4. print "Thank you for your donation! The Little Free Library now has X books."
  4. If they selected 0 for exit,
    1. print this valediction, "Thank you for visiting the Little Free Library!"
    2. return the action_log
  5. If the selected action wasn't exit, repeat from #2

Note

In the field of Human Computer Interaction, the acronym TUI is overloaded, it can mean Text-based (or Terminal-based) User Interfaces as we mean here, but it can also refer to Tangible User Interfaces, e.g.

HW6 Reflection (required)

Submit the graded survey on Canvas after completing the assignment.