33This works for some of us but fails for others.
44"""
55
6- from datetime import UTC , datetime , timedelta
6+ from datetime import UTC , date , datetime
77
88import requests
99from rich import box
1010from rich import console as rich_console
1111from rich import table as rich_table
1212
1313LIMIT = 10
14- TODAY = datetime .now ()
15-
14+ TODAY = datetime .now (tz = UTC )
1615API_URL = (
1716 "https://www.forbes.com/forbesapi/person/rtb/0/position/true.json"
1817 "?fields=personName,gender,source,countryOfCitizenship,birthDate,finalWorth"
1918 f"&limit={ LIMIT } "
2019)
2120
2221
23- def calculate_age (unix_date : float ) -> str :
24- """Calculates age from given unix time format.
22+ def years_old (birth_timestamp : int , today : date | None = None ) -> int :
23+ """
24+ Calculate the age in years based on the given birth date. Only the year, month,
25+ and day are used in the calculation. The time of day is ignored.
26+
27+ Args:
28+ birth_timestamp: The date of birth.
29+ today: (useful for writing tests) or if None then datetime.date.today().
2530
2631 Returns:
27- Age as string
28-
29- >>> from datetime import datetime, UTC
30- >>> years_since_create = datetime.now(tz=UTC).year - 2022
31- >>> int(calculate_age(-657244800000)) - years_since_create
32- 73
33- >>> int(calculate_age(46915200000)) - years_since_create
34- 51
32+ int: The age in years.
33+
34+ Examples:
35+ >>> today = date(2024, 1, 12)
36+ >>> years_old(birth_timestamp=datetime(1959, 11, 20).timestamp(), today=today)
37+ 64
38+ >>> years_old(birth_timestamp=datetime(1970, 2, 13).timestamp(), today=today)
39+ 53
40+ >>> all(
41+ ... years_old(datetime(today.year - i, 1, 12).timestamp(), today=today) == i
42+ ... for i in range(1, 111)
43+ ... )
44+ True
3545 """
36- # Convert date from milliseconds to seconds
37- unix_date /= 1000
38-
39- if unix_date < 0 :
40- # Handle timestamp before epoch
41- epoch = datetime .fromtimestamp (0 , tz = UTC )
42- seconds_since_epoch = (datetime .now (tz = UTC ) - epoch ).seconds
43- birthdate = (
44- epoch - timedelta (seconds = abs (unix_date ) - seconds_since_epoch )
45- ).date ()
46- else :
47- birthdate = datetime .fromtimestamp (unix_date , tz = UTC ).date ()
48- return str (
49- TODAY .year
50- - birthdate .year
51- - ((TODAY .month , TODAY .day ) < (birthdate .month , birthdate .day ))
46+ today = today or TODAY .date ()
47+ birth_date = datetime .fromtimestamp (birth_timestamp , tz = UTC ).date ()
48+ return (today .year - birth_date .year ) - (
49+ (today .month , today .day ) < (birth_date .month , birth_date .day )
5250 )
5351
5452
55- def get_forbes_real_time_billionaires () -> list [dict [str , str ]]:
56- """Get top 10 realtime billionaires using forbes API.
53+ def get_forbes_real_time_billionaires () -> list [dict [str , int | str ]]:
54+ """
55+ Get the top 10 real-time billionaires using Forbes API.
5756
5857 Returns:
5958 List of top 10 realtime billionaires data.
@@ -66,21 +65,22 @@ def get_forbes_real_time_billionaires() -> list[dict[str, str]]:
6665 "Country" : person ["countryOfCitizenship" ],
6766 "Gender" : person ["gender" ],
6867 "Worth ($)" : f"{ person ['finalWorth' ] / 1000 :.1f} Billion" ,
69- "Age" : calculate_age (person ["birthDate" ]),
68+ "Age" : years_old (person ["birthDate" ]),
7069 }
7170 for person in response_json ["personList" ]["personsLists" ]
7271 ]
7372
7473
75- def display_billionaires (forbes_billionaires : list [dict [str , str ]]) -> None :
76- """Display Forbes real time billionaires in a rich table.
74+ def display_billionaires (forbes_billionaires : list [dict [str , int | str ]]) -> None :
75+ """
76+ Display Forbes real-time billionaires in a rich table.
7777
7878 Args:
79- forbes_billionaires (list): Forbes top 10 real time billionaires
79+ forbes_billionaires (list): Forbes top 10 real- time billionaires
8080 """
8181
8282 table = rich_table .Table (
83- title = f"Forbes Top { LIMIT } Real Time Billionaires at { TODAY :%Y-%m-%d %H:%M} " ,
83+ title = f"Forbes Top { LIMIT } Real- Time Billionaires at { TODAY :%Y-%m-%d %H:%M} " ,
8484 style = "green" ,
8585 highlight = True ,
8686 box = box .SQUARE ,
0 commit comments