Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ web_modules/
.env
.env.*
!.env.example
.week11-streamlit/.env

# parcel-bundler cache (https://parceljs.org/)
.cache
Expand Down Expand Up @@ -156,3 +157,4 @@ dist
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

week11-streamlit/.env
36 changes: 20 additions & 16 deletions AI_ASSIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,38 @@
Document one place you used an LLM during this assignment.

## The problem
i did not know how to record myself using teams or zoom

<!-- TODO: describe the specific problem you asked an LLM about.
Example: "My Streamlit KPI panel kept re-querying Postgres on every
sidebar interaction even though I wrapped run_query in @st.cache_data." -->
## The prompt

TODO
how to record my screen and voice with my computer using teams or zoom

## The prompt
## The response
🎥 Recording in Microsoft Teams
Takeaway: You can record any meeting, even if you're alone, and Teams will capture your screen, microphone, and system audio (if enabled).

<!-- TODO: paste the exact prompt you sent to the LLM. -->
How to do it
Open Teams and start a meeting

TODO
Click Calendar → Meet now, or open an existing meeting.

## The response
Join the meeting

<!-- TODO: summarise or paste what the LLM returned. -->
Turn on your microphone if you want your voice recorded.

TODO
Share your screen

## Reflection
Click Share (the square-with-arrow icon).

Choose Screen, Window, or PowerPoint Live.

<!-- TODO: what did you change, keep, or discard after reviewing the LLM's answer?
Be specific: "I kept the cache_data suggestion but changed ttl from 60 to 300
to match the mart's once-a-day refresh cadence." -->
Start recording

TODO
Click More (···) → Start recording.

## Reflection

---
I need to join a meeting even if by myself there is no other way of recording and need to upgrade to premium so i switched to OBS.

> Remember: never paste real connection strings, passwords, or PII into an LLM.
> The NYC TLC dataset is public so sample rows are safe here, but practise the habit.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ Fill in `week11-streamlit/metric_definitions.md`: a five-field definition (name,
2) Paste its link below, plus screenshots or a PDF export in this repo.
3) Paste your 5-minute presentation recording link (keep it PRIVATE). -->

- Metabase dashboard (in the **Week 11 Submissions** collection): TODO
- Screenshots / PDF export: TODO
- Presentation recording (private, hosted in the Azure `student-submissions` container): TODO
- Metabase dashboard (in the **Week 11 Submissions** collection):
https://metabase-hyf.politepebble-abd3ebc2.westeurope.azurecontainerapps.io/dashboard/46-nyc-taxi-analytics-hannah
- Screenshots / PDF export: screenshots are in the docs folder
- Presentation recording (private, hosted in the Azure `student-submissions` container):
https://hyfstoragedev.blob.core.windows.net/student-submissions/week-11/hannahwn.mp4

> ⚠️ **Keep the recording private.** It shows your screen and voice. Never make it public and never commit the `.mp4` (git history is forever). Check the frame for passwords, `.env` contents, or connection strings before uploading.

Expand Down
Binary file added docs/metabase screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/streamlit screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions week11-streamlit/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PostgreSQL connection string (your Week 9/10 login)
# Keep the database name as team1 and the ?sslmode=require suffix; only swap
# in your own user, password, and host.
POSTGRES_URL=postgresql://your-pg-user:your-pg-password@your-pg-host:5432/team1?sslmode=require
POSTGRES_URL=postgresql://hannahwn:HhRHmt469pEm3Ou0@hyf-data-pg.postgres.database.azure.com:5432/team1?sslmode=require
# Your dev schema name (e.g. dev_jana)
DB_SCHEMA=dev_yourname
DB_SCHEMA=dev_hannahwn
78 changes: 68 additions & 10 deletions week11-streamlit/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,86 @@
load_dotenv() # reads .env file if present

POSTGRES_URL = os.environ["POSTGRES_URL"]
DB_SCHEMA = os.environ.get("DB_SCHEMA", "dev_yourname")
DB_SCHEMA = os.environ.get("DB_SCHEMA", "dev_hannahwn")

st.set_page_config(page_title="NYC Taxi Metrics", layout="wide")
st.title("NYC Taxi Metrics")




@st.cache_data(ttl=300)
def run_query(sql: str) -> pd.DataFrame:
engine = sqlalchemy.create_engine(POSTGRES_URL)
with engine.connect() as conn:
return pd.read_sql(sql, conn)

st.sidebar.header("Filters")

payment_types = run_query(f"""
SELECT DISTINCT payment_type_label
FROM {DB_SCHEMA}.fct_trips
WHERE payment_type_label IS NOT NULL
ORDER BY payment_type_label
""")["payment_type_label"].tolist()

selected_payment_type = st.sidebar.selectbox(
"Payment type",
["All"] + payment_types
)

if selected_payment_type == "All":
where_clause = ""
else:
where_clause = f"WHERE payment_type_label = '{selected_payment_type}'"


st.subheader("Headline KPIs")
KPIs= run_query(f"""
SELECT
COUNT(*) AS total_trips,
AVG(trip_distance) AS avg_trip_distance,
AVG(fare_per_mile) AS avg_fare_per_mile
FROM {DB_SCHEMA}.fct_trips
{where_clause}
""").iloc[0]

col1, col2, col3 = st.columns(3)
col1.metric("Total Trips", f"{KPIs['total_trips']:,}")
col2.metric("Avg Trip Distance (miles)", f"{KPIs['avg_trip_distance']:.2f}")
col3.metric("Avg Fare per Mile ($)", f"{KPIs['avg_fare_per_mile']:.2f}")


# TODO: query total trip count, average trip_distance, and average
# fare_per_mile from {DB_SCHEMA}.fct_trips through run_query(), then
# render three tiles side by side with st.columns(3) and .metric().
# This is deliberately not the total-trips/avg-fare/total-revenue trio
# from the chapter: trip_distance and fare_per_mile are different columns,
# so copying the chapter's SQL verbatim will not answer this.
raise NotImplementedError(
"TODO: implement the headline KPIs panel (total trips, avg trip "
"distance, avg fare per mile) from fct_trips."


st.subheader("Trip Distance Distribution")
hourly_dist = run_query(f"""
SELECT
EXTRACT(HOUR FROM pickup_datetime) AS hour_of_day,
COUNT(*) AS trip_count
FROM {DB_SCHEMA}.fct_trips
GROUP BY 1
ORDER BY 1
""")

if hourly_dist.empty:
st.warning("No data available for the selected filters.")
else:
st.bar_chart(hourly_dist.set_index("hour_of_day")["trip_count"])


st.subheader("Data Freshness")
freshness = run_query(f"""
SELECT
MAX(pickup_datetime) AS last_pickup,
MAX(dropoff_datetime) AS last_dropoff
FROM {DB_SCHEMA}.fct_trips
""").iloc[0]

col1, col2 = st.columns(2)

col1.metric("Row count", f"{KPIs['total_trips']:,}")
col2.metric(
"Last pickup", str(freshness["last_pickup"])[:16] if freshness["last_pickup"] else "unknown"
)

51 changes: 51 additions & 0 deletions week11-streamlit/metric_definitions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Metric definitions

Five fields per metric: Name, Description, Calculation, Data source, Refresh frequency. One block per panel. Copy this file to `metric_definitions.md` inside your `week11-streamlit/` folder and fill it in.

## Metabase panels

<!-- One block per Question: trip count by payment type, average fare per
mile by dropoff borough, average trip duration by hour of day. -->

### Panel 1:

- **Name**: Trip count by payment type
- **Description**: Helps identify which payment type is preffered
- **Calculation**: sum of payments grouped by type of payment
- **Data source**: fct_trips
- **Refresh frequency**: every time fct_trips is built

### Panel 2:

- **Name**: Average fare per mile by dropoff borough
- **Description**: Helps show the average money paid per mile in every borough
- **Calculation**: finding the average of of fare paid by mile and grouping per borough
- **Data source**: the fct_trips
- **Refresh frequency**: every time fct_trips is built

### Panel 3:

- **Name**: Average trip duration per hour
- **Description**: Shows which hours are busiest by average
- **Calculation**: we deduct the pickup time time from dropoff time and then find average
- **Data source**: fct_trips
- **Refresh frequency**: every time fct_trips is run

## Streamlit panels

<!-- Headline KPIs panel: total trips, average trip distance, average
fare per mile. -->

### Panel 1:

- **Name**: Headline KPIs
- **Description**: total trips,average_trip distance,average fare per mile
- **Calculation**: COUNT(*) AS total_trips,
AVG(trip_distance) AS avg_trip_distance,
AVG(fare_per_mile) AS avg_fare_per_mile
- **Data source**: fct_trips
- **Refresh frequency**: when data is cached

<!-- Add more ### Panel blocks under either section if you build more (the Required tier adds
an hour-of-day trend and a freshness panel to Streamlit; a Metabase date filter is Extra,
bonus credit, not required). -->