Lab 5: I'm Thinking of a Number

Thu Oct 27 20:03:02 EDT 2022

This lab is meant to help you learn the rudiments of the Python programming language and to write a Python program that implements a simple but important algorithm. You will probably also begin to develop some appreciation of why programming is not entirely trivial. It really does require orderly thinking and meticulous attention to detail. On the other hand, it's a great feeling when your program works. Enjoy.

Please read these instructions through before beginning the lab.
Please follow the instructions about program format, variable names, etc.
Please pay attention to syntax and grammar of language constructs.
Please read and understand the Python examples here, especially sign.py.

One other bit of advice: it often takes longer than you thought to write a program, so

Please don't leave this to the last minute.
Part 1: Introduction
Part 2: The Python language
Part 3: Writing your own Python program
Part 4: Finishing up

Part 1: Introduction

Programming languages provide a way to express computer algorithms in a form that is convenient for humans and can be translated into a computer's instruction repertoire. Programming languages are the way that we tell computers how to perform a task.

In class, we have studied the very low-level instructions that the computer itself understands (for example, the Toy), and talked about a variety of programming languages, easier for people to use, that are translated into native machine instructions by programs like compilers and assemblers. There are many such languages, each with its own good and bad points, and often with noisy adherents and detractors.

Python, the topic of this lab and the next, is one of the most widely used programming languages. It's easy to learn, easy to use, and it comes with an enormous library of useful code for almost any application area you might think of. We don't expect you to become a full-fledged Python programmer, but you will do enough in this lab and the next to get some understanding of what programs look like and what is involved in converting a process into a program.

There is an enormous amount of Python information on the Web, and thousands of books. You might start by searching for "python tutorial" or take a look at Codecademy, which has an interactive walk through Python basics. W3schools is very good for syntax and small examples that you can experiment with.

Python has three major components:

In this lab, we're going to concentrate on programming, not on fancy input and output. This will mean using variables, arithmetic, loops and decisions, and functions, while doing only minimal interaction with the environment, just enough to get data from a user and to display results. The focus is on figuring out what the pieces are and how to combine them into logic that does a computational task.

Although a programming language provides a way for you to tell a computer what to do, you have to spell out the steps in precise detail. You have at your disposal statements for:

Programming languages provide a number of piece-parts that you can use to help create a program quickly; in fact, you couldn't do much without some of these, and it would be very time-consuming to create others from scratch. In effect, these component are like prefabricated components for houses -- windows, doors, kitchen cupboards -- that can be used even by beginners to create polished products.

Some of the components are basic computational units: functions for mathematical operations (computing a square root or generating a random number, for example), or processing strings of characters (like finding or replacing a word within a sentence, or converting between upper and lower case).

Other building blocks let you interact with a user, with the environment on the computer, and with the Internet.

Normally you would run Python on your own computer, and if that's possible for you, it's good experience for this lab. But if not, you can use services like Google's Colab notebook, which provides an interactive web-based environment for running Python code. When Python runs within the confines of a browser, there are some limitations on what you can do. For example, it may not be possible to read information from the file system on your computer or to store information there, but you can usually access anything on the Internet.

Do your programming in small steps, and make sure that each step works before moving on to the next. Pay attention to error messages from the Python compiler; they may be cryptic and unfamiliar, but they do point to something that's wrong.

 


Part 2: The Python language

Here we will provide a very brief overview of some of the commands and syntax available in Python. This is by no means a complete reference, however, so you will want to look at some of the web sites we suggested above, and review what was covered in class. We are using Python 3. Version 2 is still around (it seems to be the default on macOS) but it doesn't do what we want; in particular the input function that we use for fetching input from a user doesn't work right, and print now requires parentheses, so the code in the xkcd cartoon above doesn't run.

In a terminal window (Terminal on a Mac, Powershell on Windows), you can test which version of Python you have by typing the command name python or perhaps python3:

$ python
It will respond with something like
Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 03:13:28) 
or
Python 2.7.10 (default, Feb 22 2019, 21:55:15) 
or
python: command not found
If you don't have Python 3, use Colab.

Displaying text with print

Step 1 is to create and run a minimal program to be sure that you have Python available and can run programs; this is traditionally called Hello World. Here's the simplest version, which calls the function print to display text:

print("Hello, world")
Put this in a file called lab5.py and run Python:
$ python lab5.py
Hello, world
This is the basic framework that you will now flesh out -- the single print will gradually be replaced by more and more statements. You should create this file with whatever text editor you used for the earlier labs, using plain ASCII text. [Mac TextEdit users: be careful to save as plain text.] Be sure to save your code often, and rerun it after each change so you can be sure that your changes are working. Frequent small steps is the best strategy programming.

If you are using Colab, you will edit and run your Python code in a browser window. This is described in Chapter 7 of Understanding the Digital World. It will look something like this:

Input with the input function

The function input is a sibling to print; it displays a message and waits for you to type a value. Whatever you type is returned as a sequence of characters that can be used in the rest of the program.

reply = input("Type your name: ")
print("Hello", reply)

The first statement calls the function input and stores the resulting value (what the user typed) in the variable reply. The second statement calls print to display Hello and the reply text, separated by a space.

If you press Return or Enter without typing anything, input returns an empty (zero-length) sequence of characters, which is represented in Python as "". Otherwise, input returns the characters that the user typed. This sequence tests whether the reply was empty:

reply = input("Type your name: ")
if reply == "":
   print("Hello, you nameless person")
else:
   print("Hello", reply)

Variables

A variable is a name that refers to a place in your program where information is stored; it ultimately corresponds to a location in memory. Variables can hold different types of information, but you don't generally have to worry much about that -- Python handles the details for you. The main types are integers (like 123), floating point numbers (with a decimal point and optional fractional part, like 3.14159), and string (a sequence of characters, like "hello, world" or "3.1415" or "").

Before you can use a variable in a Python program, you must assign a value to it. For example:

name = "Joe College"
year = 2025
GPA = 2.1
Python distinguishes between upper case and lower case, so gpa and GPA are two different and unrelated variables. Names must begin with a letter or underscore, followed by zero or more letters, digits and underscores.

A variable is a place to store a value so it can be used later in a program. To store a particular value in a variable, write variable = value. For example, to save the name typed by a user, you would write this:

fullname = input("What's your full name? ")
Then you can use the full name later on in the program by referring to the variable fullname.

Quotes and quoting

If you need a literal string of characters in your program, enclose it in either single ' quotes or double " quotes. If the string contains one kind of quote, you can quote it with the other, like "Don't do that!". If you inadvertently omit a quote or don't balance quotes properly, the Python compiler will complain.
Make sure that your editor (e.g., Notepad, TextEdit) preserves the ASCII quote characters (the regular single- and double-quote characters on the keyboard); word processing programs think they are doing you a favor by using so-called "smart" quotes.

Arithmetic Operators, Expressions and Statements

Operators are special symbols like the + and - of ordinary arithmetic. An operator acts on values and variables to compute a new value. An expression is a legal combination of values, operators and parentheses, like (my_height+your_height)/2 or area = pi * r * r. These are the most important Python operators:

Operator Description
=
Assigns the value on right to the variable on left (e.g., next_year = year + 1)
+ - * / %
Arithmetic: add, subtract, multiply, divide, remainder     (// is integer division)
+
Strings: make a new string by joining the two operands
< <= > >=
Comparisons: less than, less than or equals, greater than, greater than or equals
== !=
More comparisons: equals, doesn't equal
and
Conditional AND (true if left and right expressions are both true)
or
Conditional OR (true if either left or right expression is true)

A statement computes a value or does some other operation. For our purposes here, the main kinds of statements are simple function calls like print() and input, and assignments like n = 1. More complicated statements are described below.

Control Flow Statements

Control flow statements like if-else, while, and for determine what the program will do next, depending on the evaluation of some expression. They are the Python versions of statements like goto and ifzero in the Toy computer, but easier to work with.

The if-else Statement

The if statement is used to select which one of two groups of statements to do next:
if it's raining:
    I will stay home
else:
    I will go to class
or in code:
if condition:
   statements 
else: 
   other_statements

If the condition is true, then the statements are performed, otherwise the other_statements are performed. Both groups of statements can be one or more lines. The statements controlled by if and else must be indented consistently, as shown. Python uses indentation to group statements, and will not compile a program that is not indented properly.

The else part is optional; sometimes the logic doesn't require it and you can omit it. You can also string together a sequence of tests with elif clauses:

temp = int(input("What's the temperature? "))
if temp > 212:
   print(temp, "is boiling")
elif temp < 32:
   print(temp, "is freezing")
else:
   print(temp, "is in between")

Make sure you understand how the control flow in this code works. How would you modify it to work with Celsius temperatures?

int() and str()

The result that comes back from calling input is a Python string, that is, a sequence of characters. Even if that is a sequence of digits, it's not interpreted as a numeric value; it's just characters.

That means that if you want to do arithmetic on it, or compare it to other numeric values, you have to convert it into an integer. The conversion is done with the int function, which converts a string of ASCII digits into its internal representation as a binary integer. (You can also use float() if you want to handle non-integral values.)

Try something like this:

s = "123"
print(s)
n = int(s)
print(n)
print(type(s))
print(type(n))
If you get complaints about strings and integers when you run your Python code, it's likely because you didn't handle the types correcty.

Comments

Comments provide a way to add explanatory text to your code, making it more understandable to human readers. In Python, comments are indicated by #. Everything on the line after the # will be ignored by the compiler.

cummings = "e e cummings"  # his preferred spelling
Cummings = "E E Cummings"  # upper-case alternative

The while Loop

The while statement is a loop that causes a group of statements to be repeated while some condition is true:
while my room is a mess:
    pick up junk
    throw it out
In Python, this would look like
while condition:
   statements

As long as the condition is true, then the statements will be repeated. (That is, the condition is tested, and if it is true, then the entire loop body is executed, after which the condition is evaluated again.) As with if-else, the statements of the loop must be indented.

So, for example, you might print a sequence of temperature conversions like this:

fahr = 0
while fahr <= 212:
   celsius = 5 / 9 * (fahr - 32)
   print(fahr, "F is", celsius, "C")
   fahr = fahr + 10
When you use while, watch out for infinite loops. Make sure that you increment or decrement the loop variable, or in some other way ensure that the loop ends eventually.

Functions

A function is a chunk of program that can be used or called from other places in a program to do an operation or compute a value; it's a way to wrap up a computation in a package so it can be easily used just by referring to its name. The Python library includes functions that have already been written for you -- mathematical functions like square root (which is called sqrt in Python) are good examples -- and you can write your own too.

For example, you could write a function to do the Fahrenheit to Celsius temperature conversion; putting the computation in a function makes it easier to change if necessary, and reduces clutter and confusion in the rest of the program. Here is such a function, called ftoc:

def ftoc(fahr):  # convert Fahrenheit to Celsius
   return 5 / 9 * (fahr - 32)
The return statement transfers control back to the function's caller, and sends a value back too if there is one. Notice that the statements of the function are indented.

Functions usually have parameters, so that they can operate on different data values, just like print and input do. Thus ftoc has a single parameter, the temperature to be converted, which will be referred to as fahr within the function.

Now you could use ftoc in a loop like this:

def show_temps(low, high, step):
   f = low
   while f <= high:
      print(f, "F is ", ftoc(f), "C")
      f = f + step
and then call the function in a statement like this:
show_temps(0, 212, 10)
Variables created within a function are only accessible within that function; variables created outside of any function are accessible anywhere in the program.

You won't need to write any functions in this lab, but you will be using functions that others have written for you, so it's important to understand the idea.



Part 3: Writing your own Python program

Your assignment is to implement a program that will play the old guessing game "I'm thinking of a number between 1 and 100". A no-frills version is only about a dozen lines of code. If yours is getting much bigger than that, you're probably off on the wrong track and should review the notes and the Python examples.

Please pay attention to syntax and grammar and language constructs. You can't just throw code fragments around randomly and expect them to work. Read the instructions. All the information you need is right here.

Your program should do the following:

  • When the game starts, it generates a new secret number, then prompts the user to enter a guess.
  • When the user enters a new guess, the program displays the appropriate message (like "50 is too high", "25 is too low", "37 is right"), using print.
  • If the answer was wrong, the user is prompted for another guess.
  • If the answer was right, the user is told that, and the game ends.
  • It's a nicer user interface if you combine the appropriate too high/too low message with the prompt for the next guess, but it's not required. You can add any other embellishments you like as long as the core functionality works.

    Writing the program

    This is the basic structure of the program:
    Generating a secret number

    You will need a variable to hold the secret random number that the user is to guess. Call it secret. At the beginning of your program, you will need to compute a new secret number. Copy these two lines into your Python code.

    import random
    secret = random.randint(1, 100)
    
    The function random.randint produces a different (pseudo-)random number between 1 and (in this case) 100 each time it is called.

    Temporarily add a print statement after this line to display the secret number, then test this part of the program. (It's a lot easier to test your program if you already know the right answer!) Comment out this line of code once everything is working, but leave it in the code.

    Fetching the Guess
    The next step is to fetch the guess that your user makes. This is the value that comes back from calling input. Store it in a variable called guess. Your code should just ask again for a guess if the input is empty.
    Evaluating the guess

    Now you can go on to the real logic of the program: is the user's guess too high, too low, or just right? Your task is to do this test and decide what message to display and what to do subsequently. This will require a while loop that continues while the guess is not equal to the secret value, an if-else sequence inside the loop that compares the guess to the secret number, and another input() to fetch the next guess. Look back at the discussion of control flow and the examples in the class notes and online if you need to. Re-read this paragraph.

    One Step at a Time

    If this is your first Python program you are liable to make mistakes. Finding the bugs (debugging) will not be too hard if, as we suggested above, you write a small section at a time, and test as you go. This approach makes it easier to determine what section of your code has the error: it's probably the one you just added.

    Use print statements to display results as your computation proceeds, or to verify that your program is doing what you think it is. These are easy to add and help narrow down problems quickly.

    Inside your program, literal text values must appear inside quotes (e.g., "What's your guess?"). If the Python compiler complains about comparing strings with integers, use the int function to converts a sequence of ASCII digits into their integer value, as discussed earlier.

    Comments

    Comments are annotations added by programmers but ignored by Python when it is compiling and running your program. Comments are used to make the code more readable for other people that may have to work on it, or to remind you of what you were thinking when you wrote a particular line of code. Python comments start with # and extend until the end of a line. It's a good idea to include comments to remind yourself and others of what you are doing.

    When you prepare your lab for submission, you should leave any debugging statements in the program source code, but "commented out" so they can be easily restored if something goes wrong.

     


    Part 4: Finishing up

    Make sure that you have implemented what we asked for, listed above. If you have time, you could add a line or two to offer the user an upper limit different from 100, or a couple of lines to count the number of guesses, but this is optional. You could also modify it to play multiple games without being restarted; again this is optional, but trying these extensions is a great way to be sure you really understand what you are doing.

    If you used Colab, copy your Python code into a text file called lab5.py. (You can use File / Download / Download .py; you might have to rename the file once downloaded.)

    Upload lab5.py to the CS Tigerfile for Lab 5 at https://tigerfile.cs.princeton.edu/COS109_F2022/Lab5.
    You do not need to upload anything to cpanel for this lab.