Files
basic-computer-games/95_Weekday/python/weekday.py
Martin Thoma c500424956 Simplify Python Code
print_with_tab / print_with_whitespace is trivial with Python
string formatting and was mostly used in only 2 lines.
2022-04-02 07:32:09 +02:00

253 lines
6.3 KiB
Python

"""
WEEKDAY
Calculates which weekday an entered date is.
Also estimates how long a person has done certain activities, if they
entered their birthday.
Also calculates the year of retirement, assuming retiring at age 65.
Ported by Dave LeCompte.
"""
import datetime
GET_TODAY_FROM_SYSTEM = True
def get_date_from_user(prompt: str):
while True:
print(prompt)
date_str = input()
try:
month_num, day_num, year_num = (int(x) for x in date_str.split(","))
except Exception:
print("I COULDN'T UNDERSTAND THAT. TRY AGAIN.")
return month_num, day_num, year_num
def get_date_from_system():
dt = datetime.datetime.today()
return dt.month, dt.day, dt.year
def get_day_of_week(weekday_index, day):
day_names = {
1: "SUNDAY",
2: "MONDAY",
3: "TUESDAY",
4: "WEDNESDAY",
5: "THURSDAY",
6: "FRIDAY",
7: "SATURDAY",
}
if weekday_index == 6 and day == 13:
return "FRIDAY THE THIRTEENTH---BEWARE!"
return day_names[weekday_index]
def previous_day(b):
if b == 0:
b = 6
return b - 1
def is_leap_year(year: int) -> bool:
if (year % 4) != 0:
return False
if (year % 100) != 0:
return True
if (year % 400) != 0:
return False
return True
def adjust_day_for_leap_year(b, year):
if is_leap_year(year):
b = previous_day(b)
return b
def adjust_weekday(b, month, year):
if month <= 2:
b = adjust_day_for_leap_year(b, year)
if b == 0:
b = 7
return b
def calc_day_value(year, month, day):
return (year * 12 + month) * 31 + day
def deduct_time(frac, days, years_remain, months_remain, days_remain):
# CALCULATE TIME IN YEARS, MONTHS, AND DAYS
days_available = int(frac * days)
years_used = int(days_available / 365)
days_available -= years_used * 365
months_used = int(days_available / 30)
days_used = days_available - (months_used * 30)
years_remain = years_remain - years_used
months_remain = months_remain - months_used
days_remain = days_remain - days_used
while days_remain < 0:
days_remain += 30
months_remain -= 1
while months_remain < 0 and years_remain > 0:
months_remain += 12
years_remain -= 1
return years_remain, months_remain, days_remain, years_used, months_used, days_used
def time_report(msg, years, months, days):
leading_spaces = 23 - len(msg)
print(" " * leading_spaces + f"{msg}\t{years}\t{months}\t{days}")
def make_occupation_label(years):
if years <= 3:
return "PLAYED"
elif years <= 9:
return "PLAYED/STUDIED"
else:
return "WORKED/PLAYED"
def calculate_day_of_week(year, month, day):
# Initial values for months
month_table = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]
i1 = int((year - 1500) / 100)
a = i1 * 5 + (i1 + 3) / 4
i2 = int(a - int(a / 7) * 7)
y2 = int(year / 100)
y3 = int(year - y2 * 100)
a = y3 / 4 + y3 + day + month_table[month - 1] + i2
b = int(a - int(a / 7) * 7) + 1
b = adjust_weekday(b, month, year)
return b
def end():
for _ in range(5):
print()
def main() -> None:
print(" " * 32 + "WEEKDAY")
print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n")
print("WEEKDAY IS A COMPUTER DEMONSTRATION THAT")
print("GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.")
print()
if GET_TODAY_FROM_SYSTEM:
month_today, day_today, year_today = get_date_from_system()
else:
month_today, day_today, year_today = get_date_from_user(
"ENTER TODAY'S DATE IN THE FORM: 3,24,1979"
)
# This program determines the day of the week
# for a date after 1582
print()
month, day, year = get_date_from_user(
"ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST) (like MM,DD,YYYY)"
)
print()
# Test for date before current calendar
if year < 1582:
print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.")
end()
return
b = calculate_day_of_week(year, month, day)
today_day_value = calc_day_value(year_today, month_today, day_today)
target_day_value = calc_day_value(year, month, day)
is_today = False
if today_day_value < target_day_value:
label = "WILL BE A"
elif today_day_value == target_day_value:
label = "IS A"
is_today = True
else:
label = "WAS A"
day_name = get_day_of_week(b, day)
# print the day of the week the date falls on.
print(f"{month}/{day}/{year} {label} {day_name}.")
if is_today:
# nothing to report for today
end()
return
print()
el_years = year_today - year
el_months = month_today - month
el_days = day_today - day
if el_days < 0:
el_months = el_months - 1
el_days = el_days + 30
if el_months < 0:
el_years = el_years - 1
el_months = el_months + 12
if el_years < 0:
# target date is in the future
end()
return
if (el_months == 0) and (el_days == 0):
print("***HAPPY BIRTHDAY***")
# print report
print(" " * 23 + "\tYEARS\tMONTHS\tDAYS")
print(" " * 23 + "\t-----\t------\t----")
print(f"YOUR AGE (IF BIRTHDATE)\t{el_years}\t{el_months}\t{el_days}")
life_days = (el_years * 365) + (el_months * 30) + el_days + int(el_months / 2)
rem_years = el_years
rem_months = el_months
rem_days = el_days
rem_years, rem_months, rem_days, used_years, used_months, used_days = deduct_time(
0.35, life_days, rem_years, rem_months, rem_days
)
time_report("YOU HAVE SLEPT", used_years, used_months, used_days)
rem_years, rem_months, rem_days, used_years, used_months, used_days = deduct_time(
0.17, life_days, rem_years, rem_months, rem_days
)
time_report("YOU HAVE EATEN", used_years, used_months, used_days)
label = make_occupation_label(rem_years)
rem_years, rem_months, rem_days, used_years, used_months, used_days = deduct_time(
0.23, life_days, rem_years, rem_months, rem_days
)
time_report("YOU HAVE " + label, used_years, used_months, used_days)
time_report("YOU HAVE RELAXED", rem_years, rem_months, rem_days)
print()
# Calculate retirement date
e = year + 65
print(" " * 16 + f"*** YOU MAY RETIRE IN {e} ***")
end()
if __name__ == "__main__":
main()