tushifire commited on
Commit
1118be3
·
verified ·
1 Parent(s): 0b97be9

initial commit

Browse files
Files changed (1) hide show
  1. app.py +154 -0
app.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ from datetime import datetime
4
+ import matplotlib.pyplot as plt
5
+ from pywaffle import Waffle
6
+ import math
7
+
8
+ # Load the life expectancy data from the World Bank
9
+ # This is a direct link to the CSV data for life expectancy at birth, total (years)
10
+ file = "/Users/tushar/Documents/tushar_task/life_expectancy_2023_world_back_data.csv"
11
+
12
+ # Read the CSV data, skipping the first 4 rows of metadata
13
+ try:
14
+ df = pd.read_csv(file)
15
+
16
+ life_expectancy_data = df[['Country','Life Expectancy at Birth']].copy()
17
+ # life_expectancy_data.columns = ['Country', 'Life Expectancy']
18
+ life_expectancy_data.dropna(inplace=True)
19
+ countries = sorted(life_expectancy_data['Country'].unique())
20
+ except Exception as e:
21
+ print(f"Error loading data: {e}")
22
+ countries = ["Error loading country data"]
23
+ life_expectancy_data = pd.DataFrame(columns=['Country', 'Life Expectancy'])
24
+
25
+
26
+ def create_life_calendar(name, birth_year, country):
27
+ """
28
+ Creates a graphical calendar of life, with each year represented
29
+ as a row of 52 dots (weeks).
30
+ """
31
+ # --- Input Validation and Data Fetching ---
32
+ if not all([name, birth_year, country]) or country.startswith("Error"):
33
+ return None, "Please provide your name, birth year, and select a country."
34
+
35
+ if life_expectancy_data.empty:
36
+ return None, "Life expectancy data is unavailable. Cannot generate calendar."
37
+
38
+ try:
39
+ birth_year = int(birth_year)
40
+ country_data = life_expectancy_data[life_expectancy_data['Country'] == country]
41
+ if country_data.empty:
42
+ return None, f"Sorry, life expectancy data for {country} is not available."
43
+ life_expectancy = int(country_data['Life Expectancy at Birth'].iloc[0])
44
+
45
+ except (ValueError, TypeError):
46
+ return None, "Please enter a valid birth year."
47
+
48
+ # --- Calculations ---
49
+ now = datetime.now()
50
+ current_year = now.year
51
+ current_week = now.isocalendar()[1]
52
+ age = current_year - birth_year
53
+
54
+ # --- Plotting Setup ---
55
+ fig, ax = plt.subplots(figsize=(10, life_expectancy / 10), dpi=120)
56
+
57
+ # Define colors
58
+ past_color = '#d9534f' # Red
59
+ future_color = '#5cb85c' # Green
60
+
61
+ dot_size = 10
62
+ weeks_in_year = 52
63
+
64
+ # --- Main Loop to Plot Dots ---
65
+ for year in range(1, life_expectancy + 1):
66
+ for week in range(1, weeks_in_year + 1):
67
+ # Determine color
68
+ if year < age:
69
+ color = past_color
70
+ elif year == age:
71
+ color = past_color if week < current_week else future_color
72
+ else:
73
+ color = future_color
74
+
75
+ # Plot a single dot (week)
76
+ # We plot from top to bottom, so we reverse the y-coordinate
77
+ ax.scatter(week, life_expectancy - year, c=color, s=dot_size)
78
+
79
+ # --- Formatting and Labels ---
80
+ # Add year/age labels to the y-axis
81
+ ax.set_yticks(range(0, life_expectancy, 5))
82
+ ax.set_yticklabels([str(life_expectancy - i) for i in range(0, life_expectancy, 5)])
83
+ ax.set_ylabel("Age", fontsize=12)
84
+
85
+ # Configure x-axis for weeks
86
+ ax.set_xticks([1, 13, 26, 39, 52])
87
+ ax.set_xticklabels(["Week 1", "Week 13", "Week 26", "Week 39", "Week 52"])
88
+ ax.set_xlabel("Week of the Year", fontsize=12)
89
+ ax.xaxis.tick_top()
90
+ ax.xaxis.set_label_position('top')
91
+
92
+ # Remove the plot frame/spines for a cleaner look
93
+ for spine in ['left', 'right', 'bottom']:
94
+ ax.spines[spine].set_visible(False)
95
+
96
+ # Set plot limits
97
+ ax.set_xlim(0, weeks_in_year + 1)
98
+ ax.set_ylim(-1, life_expectancy)
99
+
100
+ # Create a custom legend
101
+ legend_elements = [
102
+ plt.Line2D([0], [0], marker='o', color='w', label='Past Week', markerfacecolor=past_color, markersize=10),
103
+ plt.Line2D([0], [0], marker='o', color='w', label='Future Week', markerfacecolor=future_color, markersize=10)
104
+ ]
105
+ ax.legend(handles=legend_elements, loc='center left', bbox_to_anchor=(1.02, 0.5), fontsize=12)
106
+
107
+ fig.tight_layout()
108
+
109
+ weeks_left = (life_expectancy - age) * 52 - current_week
110
+ message = f"Hello {name}, based on a life expectancy of {life_expectancy} in {country}, you have approximately {weeks_left:,} weeks remaining."
111
+
112
+ return fig, message
113
+
114
+
115
+ # Create the Gradio interface
116
+ with gr.Blocks(css=".center-text {text-align: center;}",theme=gr.themes.Soft()) as demo:
117
+ gr.Markdown(
118
+ """
119
+ # Last Sunday
120
+ Get reminded of how many Sundays remain :)
121
+
122
+ This app shows you a visualization of how many Sunday are remaining in your life. It's created to remind oneself that time in life is limited and is not to be wasted.
123
+
124
+ It's very easy to use. You simply enter your name and date of birth. Taking life expectancy as 80 years, it tells you how many weeks are left until you die.
125
+
126
+ Inspired by the PARAS CHOPRA [Last Sunday](https://chromewebstore.google.com/detail/the-last-sunday-reminder/aiojhapcgfgmiacbbjfgedhlcchmpelh?hl=en) app.
127
+ """
128
+ ,elem_classes="center-text"
129
+ )
130
+ with gr.Row():
131
+ name_input = gr.Textbox(label="Your Name")
132
+ birth_year_input = gr.Number(label="Your Birth Year", minimum=1900, maximum=datetime.now().year)
133
+ country_input = gr.Dropdown(choices=countries, label="Your Country")
134
+
135
+ # output_text = gr.Textbox(label="Your Remaining Sundays")
136
+
137
+ # with gr.Row():
138
+ # expired_input = gr.Number(label="Expired Sundays (Red Dots)", value=1560)
139
+ # remaining_input = gr.Number(label="Remaining Sundays (Green Dots)", value=2600)
140
+
141
+ generate_button = gr.Button("Generate My Life Calendar", variant="primary")
142
+
143
+ with gr.Column():
144
+ output_plot = gr.Plot()
145
+ output_text = gr.Label()
146
+
147
+ generate_button.click(
148
+ fn=create_life_calendar,
149
+ inputs=[name_input, birth_year_input, country_input],
150
+ outputs=[output_plot, output_text]
151
+ )
152
+
153
+ demo.launch()
154
+