PY-1.1-BP4-MQ31

Our Goal

We will write a Python program that tells us how hot or cold it is based on the temperature. It will say 'hot', 'warm', 'cool', or 'cold'.

Check Your Work

Before we start, let's run the tests to see what we need to fix.

Run this command in your terminal: pytest module-1.1/blueprint-4/quest-31

What you should see:

  • test_very_hot_temperature
  • test_hot_boundary_just_above
  • test_warm_temperature_upper_range
  • test_warm_temperature_mid_range
  • test_warm_boundary_just_above_lower
  • test_cool_temperature_upper_range
  • test_cool_temperature_mid_range
  • test_cool_boundary_just_above_lower
  • test_cold_temperature_at_zero
  • test_cold_temperature_negative

Write Your Code

Now, let's write our Python code to rate temperatures. Remember, you'll need to use 'if', 'elif', and 'else' statements to make decisions.

Here are some helpful code examples from the documentation:

1. Basic 'if/elif/else' statement:

if score > 90:
    print("Excellent!")
elif score > 70:
    print("Good!")
else:
    print("Keep trying!")

2. Comparison Operators:

# greater than
if temp > 30:
    print("Hot!")

# greater than or equal to
if age >= 18:
    print("Old enough!")

3. Printing a message:

print("Your message here!")

Check Your Work Again

Now, let's run the tests again to see if your code works.

Run this command in your terminal again: pytest module-1.1/blueprint-4/quest-31

What you should see:

  • test_very_hot_temperature
  • test_hot_boundary_just_above
  • test_warm_temperature_upper_range
  • test_warm_temperature_mid_range
  • test_warm_boundary_just_above_lower
  • test_cool_temperature_upper_range
  • test_cool_temperature_mid_range
  • test_cool_boundary_just_above_lower
  • test_cold_temperature_at_zero
  • test_cold_temperature_negative

Documentation

Python Fundamentals: Conditions and Nested Structures

This document provides a quick reference for key Python concepts related to conditional execution, comparisons, arithmetic, loops, and functions, as covered in this learning module.

Conditional Execution

Code can be executed selectively based on whether a condition is true or false.

The if Statement

Executes a block of code only if a specified condition is true.

name = "Admin"
if name == "Admin":
    print("Welcome, Administrator!")
# If the condition (name == "Admin") is false, the print statement is skipped.

Flowchart illustrating a single 'if' condition leading to a block or skipping it.

The if/else Statement

Provides two paths of execution: one if the condition is true, and another if it is false.

password_length = 7
if password_length >= 8:
    print("Strong password.")
else:
    print("Weak password. Consider making it longer.")

Flowchart illustrating an 'if/else' condition leading to one of two blocks.

The if/elif/else Statement

Handles multiple distinct conditions in sequence. elif stands for "else if". Python evaluates conditions from top to bottom. The code block associated with the first true condition is executed. If no conditions are true, the else block (if present) runs.

day_number = 6 # Example input

if 1 <= day_number <= 5: # Checks if day_number is between 1 and 5 (inclusive)
    print("It is a weekday.")
elif day_number == 6 or day_number == 7:
    print("It is a weekend day!")
else:
    print("Invalid day number.")

Flowchart illustrating an 'if/elif/else' structure with multiple possible paths.

Comparisons and Logic

Conditions are created using operators that compare values or check relationships.

Comparing Values: Relational Operators

Relational operators are used to compare two values. They evaluate to a Boolean value: True or False.

  • == : Equal to
  • != : Not equal to
  • > : Greater than
  • < : Less than
  • >= : Greater than or equal to
  • <= : Less than or equal to

Example using relational operators in conditions:

temperature = 25 # Example input

if temperature > 30:
    print("It is hot.")
elif temperature > 15: # This condition is checked only if temperature > 30 was false.
                       # It effectively checks if 15 < temperature <= 30.
    print("It is warm.")
elif temperature > 0:  # Effectively checks if 0 < temperature <= 15.
    print("It is cool.")
else:                  # Effectively checks if temperature <= 0.
    print("It is cold.")

The Modulo Operator (%)

The modulo operator (%) returns the remainder of a division.

Example:

remainder_result = 10 % 3    # Result: 1 (10 divided by 3 is 3 with a remainder of 1)
another_remainder = 17 % 5 # Result: 2 (17 divided by 5 is 3 with a remainder of 2)

Checking for even/odd numbers using modulo:

number = 4
if number % 2 == 0:
    print(f"{number} is even.")
else:
    print(f"{number} is odd.")

Working with Numbers

Python supports standard mathematical operations.

Arithmetic Operations

  • + : Addition (e.g., 10 + 3 results in 13)
  • - : Subtraction (e.g., 10 - 3 results in 7)
  • * : Multiplication (e.g., 10 * 3 results in 30)
  • / : True Division (always results in a float, e.g., 10 / 3 results in 3.333...)
  • //: Integer Division (discards the fractional part, e.g., 10 // 3 results in 3; 9 // 3 results in 3)
  • % : Modulo (gives the remainder of a division, e.g., 10 % 3 results in 1)

Example:

num1 = 10
num2 = 3

sum_result = num1 + num2          # Result: 13
difference_result = num1 - num2   # Result: 7
product_result = num1 * num2      # Result: 30
true_div_result = num1 / num2     # Result: 3.3333333333333335
int_div_result = num1 // num2     # Result: 3
remainder_result = num1 % num2    # Result: 1

Repeating Actions: Loops

Loops allow a block of code to be executed multiple times.

The for Loop and range()

A for loop is often used to iterate over a sequence (like a list or string) or to repeat an action a specific number of times using the range() function.

range(n) generates a sequence of numbers from 0 up to (but not including) n. range(start, stop) generates numbers from start up to (but not including) stop.

Example: Repeating an action 3 times

for i in range(3):
    print("Repeat")
# This will print "Repeat" three times, with i being 0, then 1, then 2.

Patterns and Grids: Nested Loops

A loop can be placed inside another loop. This is known as nesting. Nested loops are often used for tasks like processing 2D data (e.g., grids or tables). The inner loop completes all its iterations for each single iteration of the outer loop.

Example: Printing a 3x4 grid of asterisks.

rows = 3
cols = 4

for r_idx in range(rows):      # Outer loop iterates 3 times (for rows 0, 1, 2)
    for c_idx in range(cols):  # Inner loop iterates 4 times (for columns 0, 1, 2, 3) for each row
        print("*", end="")     # Print an asterisk. 'end=""' prevents moving to a new line.
    print()                    # After the inner loop completes for a row, print a newline character.

Output:

****
****
****

Flowchart illustrating the execution path of nested loops.

Functions

Functions are blocks of reusable code that perform a specific task.

Defining and Calling Functions

Functions are defined using the def keyword. They can take parameters (inputs) and can return a value (output).

def greet(name): # 'name' is a parameter
    print(f"Hello, {name}!")

# Calling the function
greet("Alice") # "Alice" is the argument passed to the 'name' parameter

Return Values

The return statement sends a value back from a function. If a function doesn't have a return statement, it implicitly returns None.

def add(a, b):
    sum_result = a + b
    return sum_result # Return the calculated sum

result = add(5, 3) # The value 8 is returned and stored in 'result'
print(result) # Prints 8

A function can return multiple values by packaging them into a tuple.

def get_stats(x, y):
    sum_val = x + y
    diff_val = x - y
    return sum_val, diff_val # Returns a tuple (sum_val, diff_val)

s, d = get_stats(10, 5) # Unpacks the tuple into two variables
print(f"Sum: {s}, Difference: {d}") # Prints "Sum: 15, Difference: 5"

Enhancing Readability: Type Hints (A Brief Look)

Type hints are annotations that suggest the expected data types for function parameters and return values. They do not affect how the code runs (Python remains dynamically typed), but they improve code readability and can be used by static analysis tools.

Syntax:

  • For parameters: parameter_name: type
  • For return values: -> return_type

Example:

def add_numbers(a: int, b: int) -> int:
    return a + b

result: int = add_numbers(5, 3) # result is 8
# The hints suggest 'a' and 'b' are integers, and the function returns an integer.

Diagram showing import random and random.randint(1, 10) with an arrow indicating a random number output.

Using External Code: Modules

Python's functionality can be extended using modules. Modules are files containing Python definitions and statements. Python comes with a standard library of modules, and many more are available from third parties.

To use functions or variables from a module, you first need to import it.

import random # Imports the 'random' module

Once imported, you can access its contents using dot notation (module_name.item_name).

# Generate a random integer between 1 and 10 (inclusive)
random_number = random.randint(1, 10)
print(random_number) # Prints a random number, e.g., 7

Output

Printing to the Console

The print() function displays output to the console.

print("Hello, world!") # Prints "Hello, world!" followed by a newline
print("Sum:", 10 + 5) # Prints "Sum: 15"

# Using f-strings for formatted output
num1 = 5
num2 = 10
result = 15
print(f"The sum of {num1} and {num2} is {result}") # Prints "The sum of 5 and 10 is 15"

The print() function has an optional end parameter which specifies what to print at the end. By default, end is \n (a newline). Setting end="" prevents the newline.

print("This is on one line", end="")
print(" and this continues it.")
# Output: This is on one line and this continues it.

Turtle Graphics Commands Used

This module utilizes several commands from the turtle module for drawing:

  • turtle.Turtle(): Creates a new turtle object.
  • t.speed(speed): Sets the turtle's speed (0 is fastest).
  • t.hideturtle(): Makes the turtle cursor invisible.
  • t.penup(): Lifts the pen so the turtle moves without drawing.
  • t.pendown(): Puts the pen down so the turtle draws when it moves.
  • t.goto(x, y): Moves the turtle to the specified coordinates.
  • t.forward(distance): Moves the turtle forward by the specified distance.
  • t.right(angle): Turns the turtle right by the specified angle (in degrees).
  • t.left(angle): Turns the turtle left by the specified angle (in degrees).
  • t.color(color_name): Sets both the pen color and fill color.
  • t.pencolor(color_name): Sets only the pen color.
  • t.fillcolor(color_name): Sets only the fill color.
  • t.begin_fill(): Starts the process of filling a shape.
  • t.end_fill(): Finishes the fill process, coloring the shape drawn since begin_fill.
  • t.circle(radius): Draws a circle with the given radius.
  • t.dot(size, color): Draws a dot with the given diameter and color.
  • turtle.Screen(): Creates a drawing window.
  • screen.tracer(n): Turns turtle animation on/off and set delay for updates (0 turns off animation).
  • screen.update(): Performs a turtle screen update when animation is off.
  • turtle.done() or screen.exitonclick(): Keeps the turtle window open until manually closed or clicked.