-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpractice.py
More file actions
267 lines (211 loc) · 9.51 KB
/
practice.py
File metadata and controls
267 lines (211 loc) · 9.51 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
import csv
from datetime import datetime
DEGREE_SYMBOL = u"\N{DEGREE SIGN}C"
def format_temperature(temp):
"""Takes a temperature and returns it in string format with the degrees
and Celcius symbols.
Args:
temp: A string representing a temperature.
Returns:
A string contain the temperature and "degrees Celcius."
"""
return f"{temp}{DEGREE_SYMBOL}"
def convert_date(iso_string):
"""Converts and ISO formatted date into a human-readable format.
Args:
iso_string: An ISO date string.
Returns:
A date formatted like: Weekday Date Month Year e.g. Tuesday 06 July 2021
"""
# %A Weekday, full version -> Wednesday
# %d Day of month 01-31 -> 31
# %B Month name, full version -> December
# %Y Year, full version -> 2018
date = datetime.fromisoformat(iso_string)
return date.strftime("%A %d %B %Y") # strftime changes the actual date instance to a different format
def convert_f_to_c(temp_in_fahrenheit):
"""Converts a temperature from Fahrenheit to Celcius.
Args:
temp_in_fahrenheit: float representing a temperature.
Returns:
A float representing a temperature in degrees Celcius, rounded to 1 decimal place.
"""
# round(3.2) -> Output: 3
# round(3.8) -> Output: 4
# round(3.14159, 2) -> Output: 3.14
# round(2.71882, 3) -> Output: 2.719
return round(((float(temp_in_fahrenheit) - 32) * 5/9), 1) # Formula: (32°F − 32) × 5/9 = 0°C
def calculate_mean(weather_data):
"""Calculates the mean value from a list of numbers.
Args:
weather_data: a list of numbers.
Returns:
A float representing the mean value.
"""
# sum(iterable, start - optional) -> sum([1, 2, 3]) = 0 + 1 + 2 + 3 = 6 or sum([1, 2, 3], 10) = 10 + 1 + 2 + 3 = 16
return sum(weather_data)/len(weather_data)
def load_data_from_csv(csv_file):
"""Reads a csv file and stores the data in a list.
Args:
csv_file: a string representing the file path to a csv file.
Returns:
A list of lists, where each sublist is a (non-empty) line in the csv file.
"""
lst = []
with open(csv_file, encoding="utf-8") as data:
file = csv.reader(data)
for row in file:
if len(row) > 0: # I think sublist should have exactly 3 elements not just non-empty for the best practice..
lst.append(row)
return lst
def find_min(weather_data):
"""Calculates the minimum value in a list of numbers.
Args:
weather_data: A list of numbers.
Returns:
The minimum value and its position in the list. (In case of multiple matches, return the index of the *last* example in the list.)
"""
min = weather_data[0]
index = 0
for i, val in enumerate(weather_data):
if val <= min:
min = val
index = i
return min, index # Both saved in a tuple
def find_max(weather_data):
"""Calculates the maximum value in a list of numbers.
Args:
weather_data: A list of numbers.
Returns:
The maximum value and its position in the list. (In case of multiple matches, return the index of the *last* example in the list.)
"""
max = weather_data[0]
index = 0
for i, val in enumerate(weather_data):
if val >= max:
max = val
index = i
return max, index # Both saved in a tuple
def generate_summary(weather_data):
"""Outputs a summary for the given weather data.
Args:
weather_data: A list of lists, where each sublist represents a day of weather data.
Returns:
A string containing the summary information.
"""
# ─────────────────────────────
# 🪐 PLANS 🪐
# ─────────────────────────────
# ─────────────────────────────
# 💜 Function call order
# - load_data_from_csv(file_path) -> maybe not coz we're given the data to work with as an argument?
# - find_min(min_temps)
# - find_max(max_temps)
# - calculate_mean(temp_list)
# - convert_date(iso_date)
# - convert_f_to_c(temp_in_fahrenheit)
# - format_temperature(temp)
# ─────────────────────────────
# ─────────────────────────────
# 💜 Overall structure of the summary output
# Line 1: <N> Day Overview
# -> N = number of lists (rows) in the CSV that have exactly 3 elements (date with 2 temps) in it
# Line 2: The lowest temperature will be <lowest temp>, and will occur on <lowest date>.
# -> lowest temp = a return value of find_min()
# -> find_min() requires a list of temps so this should be a list of all the min temps and that means I need to put all 3rd element of each list together
# -> ❓❓❓ where would I use the index returned from find_min() though?!
# -> Oh!!! because the temp is associated with the date!!!
# -> but then how am I going to get the respective date? All the dates should be collected in a list as well?
# -> date = first element of a list that has lowest temp among all the min temps.
# Line 3: The highest temperature will be <highest temp>, and will occur on Saturday <highest date>.
# -> Same logic as Line 2.
# Line 4: The average low this week is <avg low>.
# -> sum of min temps list devided by length of the list => use calculate_mean()
# Line 5: The average high this week is <avg high>.
# -> Same logic as Line 4.
# Line 6: empty
# ─────────────────────────────
# ─────────────────────────────
# 🤔⁉️ Questions
# - When should I convert the dates?
# - When should I convert temps from f to t?
# -> After getting it
# - When should I format with the celcius sign?
# ─────────────────────────────
# For Line 1
n_day = len(weather_data) - 1
dates = [lst[0] for lst in weather_data[1:]] # Collect the element of index [0] (i.e. date) from each list
min_temps = [float(lst[1]) for lst in weather_data[1:]]
max_temps = [float(lst[2]) for lst in weather_data[1:]]
# For Line 2
min_and_index = find_min(min_temps)
lowest_temp = format_temperature(convert_f_to_c(min_and_index[0])) # Assigning value of lowest temp
# lowest_date = dates[min_and_index[1]] # Accessing the date of lowest temp using the index number of lowest temp
# lowest_date = convert_date(lowest_date)
lowest_date = convert_date(dates[min_and_index[1]])
# For Line 3
max_and_index = find_max(max_temps)
highest_temp = format_temperature(convert_f_to_c(max_and_index[0]))
highest_date = convert_date(dates[max_and_index[1]])
# For Line 4
avg_low = format_temperature(convert_f_to_c(calculate_mean(min_temps)))
# For Line 5
avg_high = format_temperature(convert_f_to_c(calculate_mean(max_temps)))
return f"""{n_day} Day Overview
The lowest temperature will be {lowest_temp}, and will occur on {lowest_date}.
The highest temperature will be {highest_temp}, and will occur on {highest_date}.
The average low this week is {avg_low}.
The average high this week is {avg_high}.
"""
# file_paths = [
# "./tests/data/example_one.csv",
# "./tests/data/example_two.csv",
# "./tests/data/example_three.csv"
# ]
# for path in file_paths:
# print(generate_summary(load_data_from_csv(path)))
# print()
def generate_daily_summary(weather_data):
"""Outputs a daily summary for the given weather data.
Args:
weather_data: A list of lists, where each sublist represents a day of weather data.
Returns:
A string containing the summary information.
"""
# ─────────────────────────────
# 🪐 PLANS 🪐
# ─────────────────────────────
# ─────────────────────────────
# 💜 Function call order
# - convert_date(iso_date)
# - convert_f_to_c(temp_in_fahrenheit)
# - format_temperature(temp)
# ─────────────────────────────
# ─────────────────────────────
# 💜 Overall structure of the summary output
# Line 1: ---- <date> ----
# Line 2: Minimum Temperature: <min_temp>
# Line 3: Maximum Temperature: <max_temp>
# Line 4: empty
# -> Repeat until the last sublist in weather_data.
# ────────────────────────
for date, min, max in weather_data[1:]:
date = convert_date(date)
min = format_temperature(convert_f_to_c(float(min)))
max = format_temperature(convert_f_to_c(float(max)))
print(f"""---- {date} ----
Minimum Temperature: {min}
Maximum Temperature: {max}
""")
######## Fuction Calls ########
file_paths = [
"./tests/data/example_one.csv",
"./tests/data/example_two.csv",
"./tests/data/example_three.csv"
]
for path in file_paths:
print(generate_summary(load_data_from_csv(path)))
print("=" * 50)
for path in file_paths:
generate_daily_summary(load_data_from_csv(path))
print("=" * 50)