forked from realpython/materials
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpopulation.py
56 lines (43 loc) · 1.77 KB
/
population.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# population.py
import csv
from importlib import resources
import matplotlib.pyplot as plt
class _Population:
def __init__(self):
"""Prepare to read the population file"""
self._data = {}
self.variant = "Medium"
@property
def data(self):
"""Read data from disk"""
if self._data: # Data has already been read, return it directly
return self._data
# Read data and store it in self._data
print(f"Reading population data for {self.variant} scenario")
with resources.open_text(
"data", "WPP2019_TotalPopulationBySex.csv"
) as fid:
rows = csv.DictReader(fid)
# Read data, filter the correct variant
for row in rows:
if int(row["LocID"]) >= 900 or row["Variant"] != self.variant:
continue
country = self._data.setdefault(row["Location"], {})
population = float(row["PopTotal"]) * 1000
country[int(row["Time"])] = round(population)
return self._data
def get_country(self, country):
"""Get population data for one country"""
country = self.data[country]
years, population = zip(*country.items())
return years, population
def plot_country(self, country):
"""Plot data for one country, population in millions"""
years, population = self.get_country(country)
plt.plot(years, [p / 1e6 for p in population], label=country)
def order_countries(self, year):
"""Sort countries by population in decreasing order"""
countries = {c: self.data[c][year] for c in self.data}
return sorted(countries, key=lambda c: countries[c], reverse=True)
# Instantiate the singleton
data = _Population()