Spaces:
Sleeping
Sleeping
| from typing import Callable | |
| import streamlit as st | |
| import pandas as pd | |
| import plotly.graph_objects as go | |
| import datetime | |
| class UserView: | |
| """ | |
| A class to handle all user interface elements. | |
| """ | |
| def show_current_data(self, merged_data_df: pd.DataFrame) -> None: | |
| """ | |
| Show the current pollutant concentrations along with WHO guidelines. | |
| Args: | |
| merged_data_df (pd.DataFrame): A pandas DataFrame containing the current pollutant concentrations and WHO guidelines. | |
| """ | |
| st.sidebar.markdown( | |
| f"Today's Date: **{datetime.date.today().strftime('%B %d, %Y')}**" | |
| ) | |
| st.sidebar.markdown("### Current Pollutant Concentrations and WHO Guidelines") | |
| st.sidebar.dataframe(merged_data_df, hide_index=True) | |
| def data_not_available(self) -> None: | |
| """ | |
| Show an error message indicating that data is not available. | |
| This is shown when the current time is between 00:00 and 04:15, when the measurements aren't accurate enough to produce a prediction. | |
| The data will be automatically updated at 04:15 with the prediction for the next three days. | |
| """ | |
| st.markdown("### Data Not Available") | |
| error_message = "🚨 Between 00:00 and 04:15, the measurements aren't accurate enough to produce a prediction or have an informative summary for today's air pollution. The data will be automatically updated at 04:15 with the prediction for the next three days." | |
| self.two_columns_layout(0.7, lambda: st.error(error_message), lambda: None) | |
| def success(self, message: str) -> None: | |
| """ | |
| Show a success message. | |
| Args: | |
| message (str): The message to be displayed. | |
| """ | |
| st.success(message) | |
| def error(self, message: str) -> None: | |
| """ | |
| Show an error message. | |
| Args: | |
| message (str): The message to be displayed. | |
| """ | |
| st.error(message) | |
| def display_predictions_lineplot(self, fig: go.Figure) -> None: | |
| """ | |
| Show a line plot of the predictions. | |
| Args: | |
| fig (go.Figure): The plotly figure to be displayed. | |
| """ | |
| st.plotly_chart(fig) | |
| def display_predictions_gaugeplot(self, gauge_plots: list) -> None: | |
| """ | |
| Show a gauge plot of the predictions. | |
| Args: | |
| gauge_plots (list): A list of tuples containing the day, formatted date, and two plotly figures (for NO2 and O3). | |
| """ | |
| for day, formatted_date, fig_no2, fig_o3 in gauge_plots: | |
| st.markdown(f"#### Day {day}: {formatted_date}") | |
| col1, col2 = st.columns([1, 1]) | |
| with col1: | |
| st.plotly_chart(fig_no2) | |
| with col2: | |
| st.plotly_chart(fig_o3) | |
| def view_option_selection(self, plot_type: list) -> str: | |
| """ | |
| Ask the user to select a plot type. | |
| Args: | |
| plot_type (list): A list of strings containing the options to be displayed. | |
| Returns: | |
| str: The selected option. | |
| """ | |
| st.markdown("### Visualizing Air Quality Predictions") | |
| return st.selectbox("Select a plot type:", plot_type) | |
| def compare_to_who(self, warnings: list) -> None: | |
| """ | |
| Compare the current pollutant concentrations with WHO guidelines and display the results. | |
| Args: | |
| warnings (list): A list of tuples containing the pollutant, message, and level (error or success) of the warning. | |
| """ | |
| for pollutant, message, level in warnings: | |
| if level == "error": | |
| st.sidebar.error(message) | |
| elif level == "success": | |
| st.sidebar.success(message) | |
| def two_columns_layout( | |
| self, ratio: float, left_function: Callable, right_function: Callable | |
| ) -> None: | |
| """ | |
| Divide the page into two columns and call the left and right functions within them. | |
| Parameters | |
| ---------- | |
| ratio : float | |
| The ratio of the left to the right column. | |
| left_function : Callable | |
| The function to be called in the left column. | |
| right_function : Callable | |
| The function to be called in the right column. | |
| """ | |
| left, right = st.columns([ratio, 1 - ratio], gap="large") | |
| with left: | |
| left_function() | |
| with right: | |
| right_function() | |
| def raise_awareness( | |
| self, random_fact: str, awareness_expanders: list, health_message: dict | |
| ) -> None: | |
| """ | |
| Raise awareness about air quality issues and provide health recommendations. | |
| Args: | |
| random_fact (str): A random fact about air quality. | |
| awareness_expanders (list): A list of tuples containing the title and content of the expanders. | |
| health_message (dict): A dictionary containing the health recommendation message and type (error or success). | |
| """ | |
| st.markdown("### Air Quality Awareness") | |
| # Awareness sections | |
| for expander_title, expander_content in awareness_expanders: | |
| with st.expander(expander_title): | |
| st.write(expander_content) | |
| # Fact section | |
| st.markdown("### Did You Know?") | |
| st.info(random_fact) | |
| # Health recommendation section | |
| st.markdown("### Health Recommendations Based on Current Levels") | |
| if health_message["type"] == "error": | |
| st.error(health_message["message"]) | |
| else: | |
| st.success(health_message["message"]) | |
| def quiz(self, question: str, options: list) -> tuple: | |
| """ | |
| Ask a quiz question and return the answer and whether the answer was correct. | |
| Args: | |
| question (str): The question to be asked. | |
| options (list): A list of strings containing the options. | |
| Returns: | |
| tuple: A tuple containing the answer and a boolean indicating whether the answer was correct. | |
| """ | |
| st.markdown("### Quick Quiz: How Much Do You Know About Air Pollution?") | |
| with st.form(key="quiz_form"): | |
| st.write(question) | |
| answer = st.radio("Choose an option:", options) | |
| submit_button = st.form_submit_button("Submit Answer") | |
| return submit_button, answer | |
| def print_sources(self, sources: list) -> None: | |
| """ | |
| Print the sources used in the application. | |
| Args: | |
| sources (list): A list of tuples containing the source text and URL. | |
| """ | |
| st.markdown("### Learn More") | |
| for source_text, source_url in sources: | |
| st.markdown(f"[{source_text}]({source_url})") | |