Flow Control
Introduction
This chapter covers Python's conditional logic and iteration constructs: if/elif/else, the boolean operators and, or, and not, and the for/while loops. The running example throughout is date processing — validating a day, month, and year, and iterating over every date in a given month.
Python's remainder operator % is a useful tool for these kinds of problems. For example, a year is a leap year if it's evenly divisible by 4 and not evenly divisible by 100, or if it's evenly divisible by 400 — a classic use of % combined with and/or.
Concepts
Boolean logic
year = 2024
is_leap_year = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
print(is_leap_year)
if / elif / else
day, month, year = 29, 2, 2024
if month < 1 or month > 12:
print("Invalid month")
elif day < 1 or day > 31:
print("Invalid day")
else:
print(f"{day:02d}/{month:02d}/{year}")
for loops and range()
for day in range(1, 32):
print(day)
while loops
count = 0
while count < 5:
print(count)
count += 1
Examples
def is_leap_year(year):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def days_in_month(month, year):
days = [31, 29 if is_leap_year(year) else 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31]
return days[month - 1]
year = 2016
month = 2
for day in range(1, days_in_month(month, year) + 1):
print(f"{day}/{month}/{year}")
Challenges
1. Is it a leap year?
- Ask the user to enter a day, month, and year.
- Determine whether the year is a leap year using the remainder operator, and print a message.
- Test your logic against several known leap years and non-leap years (e.g. 2000, 1900, 2024, 2023).
💡 Show Answer
year = int(input("Enter a year: "))
is_leap_year = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
if is_leap_year:
print(f"{year} is a leap year")
else:
print(f"{year} is not a leap year")
2. Validating a date
- Ask the user for a day, month, and year.
- Validate that the month is between 1 and 12, the year is between 0 and 2099, and the day is valid for that month (taking leap years into account for February).
- Print a single message saying whether the date is valid, in
dd/mm/yyyyformat.
💡 Show Answer
def is_leap_year(year):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def days_in_month(month, year):
days = [31, 29 if is_leap_year(year) else 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31]
return days[month - 1]
day = int(input("Enter the day: "))
month = int(input("Enter the month: "))
year = int(input("Enter the year: "))
if month < 1 or month > 12:
valid = False
elif year < 0 or year > 2099:
valid = False
elif day < 1 or day > days_in_month(month, year):
valid = False
else:
valid = True
date_str = f"{day:02d}/{month:02d}/{year:04d}"
if valid:
print(f"{date_str} is a valid date")
else:
print(f"{date_str} is not a valid date")
3. Listing all dates in a month
- Ask the user for a month and a year.
- Print every date in that month, one per line, in
d/m/yyyyformat (taking leap years into account for February).
💡 Show Answer
def is_leap_year(year):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def days_in_month(month, year):
days = [31, 29 if is_leap_year(year) else 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31]
return days[month - 1]
month = int(input("Enter the month: "))
year = int(input("Enter the year: "))
for day in range(1, days_in_month(month, year) + 1):
print(f"{day}/{month}/{year}")
4. Verbose date output
- Extend the previous challenge so that dates are printed in a verbose format, e.g.
1 February 2016. - Add the correct ordinal suffix to the day number, e.g.
1st,2nd,3rd,4th.
💡 Show Answer
MONTH_NAMES = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
def is_leap_year(year):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def days_in_month(month, year):
days = [31, 29 if is_leap_year(year) else 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31]
return days[month - 1]
def day_suffix(day):
if 11 <= day <= 13:
return "th"
return {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th")
month = int(input("Enter the month: "))
year = int(input("Enter the year: "))
for day in range(1, days_in_month(month, year) + 1):
print(f"{day}{day_suffix(day)} {MONTH_NAMES[month - 1]} {year}")