Skip to content

Commit 227944e

Browse files
vil02pre-commit-ci[bot]cclauss
authored
fix: consider months and days in years_old (#11234)
* fix: do not consider months in `calculate_age` * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update get_top_billionaires.py * Update get_top_billionaires.py * Update get_top_billionaires.py * TODAY = datetime.utcnow() * Update get_top_billionaires.py * Update build.yml --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <[email protected]>
1 parent 9caf478 commit 227944e

File tree

2 files changed

+37
-37
lines changed

2 files changed

+37
-37
lines changed

Diff for: .github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- uses: actions/checkout@v4
13-
- uses: actions/setup-python@v4
13+
- uses: actions/setup-python@v5
1414
with:
1515
python-version: 3.12
1616
allow-prereleases: true

Diff for: web_programming/get_top_billionaires.py

+36-36
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,56 @@
33
This 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

88
import requests
99
from rich import box
1010
from rich import console as rich_console
1111
from rich import table as rich_table
1212

1313
LIMIT = 10
14-
TODAY = datetime.now()
15-
14+
TODAY = datetime.now(tz=UTC)
1615
API_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

Comments
 (0)