Skip to content

Commit

Permalink
Add NY Taxi Trips page and enhance payment type handling
Browse files Browse the repository at this point in the history
- Introduced a new page for NY Taxi Trips with visualizations using Altair.
- Updated payment type and rate code mappings in the NYC TLC trips service.
- Modified the home page to streamline navigation and search functionality.
- Removed unused pages to simplify the project structure.
- Adjusted default date range in the date range picker component.
  • Loading branch information
mkuthan committed Nov 20, 2024
1 parent 7bda59b commit 15e74fe
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 69 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Streamlit is not a typical web framework, so don't try to apply typical web fram
* Authentication skeleton: unauthenticated users see the login page, authenticated users can log out
* Integration with BigQuery
* Share application state via URL
* Vega-Altair for visualizations
* Modular technical layers within a single domain
* Execute tests from the IDE without additional configuration
* Modern Python build tools: uv, ruff
Expand Down
6 changes: 2 additions & 4 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,9 @@ def share(path: str) -> None:
pg = st.navigation(pages=[login_page])
else:
home = st.Page("example/ui/pages/home.py", title="Home", icon=":material/home:", default=True)
p2 = st.Page("example/ui/pages/page2.py", title="Page 2", icon=":material/search:")
p3 = st.Page("example/ui/pages/page3.py", title="Page 3", icon=":material/dashboard:")
p4 = st.Page("example/ui/pages/page4.py", title="Page 4", icon=":material/calculate:")
nyt_tlc_trips = st.Page("example/ui/pages/nyt_tlc_trips.py", title="NY Taxi Trips", icon=":material/local_taxi:")

pg = st.navigation(pages=[home, p2, p3, p4])
pg = st.navigation(pages=[home, nyt_tlc_trips])

if st.sidebar.button("Share", icon=":material/link:"):
share(pg.url_path)
Expand Down
25 changes: 23 additions & 2 deletions example/services/nyc_tlc_trips.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,26 @@

from example.infrastructure import big_query

_PAYMENT_TYPES = {"1": "Credit card", "2": "Cash", "3": "No charge", "4": "Dispute", "5": "Unknown", "6": "Voided trip"}
_PAYMENT_TYPES = {
0: "Unknown",
1: "Credit card",
2: "Cash",
3: "No charge",
4: "Dispute",
5: "Unknown",
6: "Voided trip",
}

_RATE_CODES = {
0: "Unknown",
1: "Standard rate",
2: "JFK",
3: "Newark",
4: "Nassau or Westchester",
5: "Negotiated fare",
6: "Group ride",
99: "Other",
}


@st.cache_data(ttl=600)
Expand All @@ -14,6 +33,7 @@ def get_trips(date_range: tuple[date, date], payment_type: str) -> pd.DataFrame:
SELECT
DATE(pickup_datetime) AS day,
payment_type AS payment_type,
rate_code AS rate_code,
SUM(fare_amount) AS total_fare,
SUM(tip_amount) AS total_tips,
SUM(total_amount) AS total_amount,
Expand All @@ -36,7 +56,8 @@ def get_trips(date_range: tuple[date, date], payment_type: str) -> pd.DataFrame:

results = big_query.query(query, params)

results["payment_type"] = results["payment_type"].map(_PAYMENT_TYPES)
results["payment_type"] = results["payment_type"].fillna(0).astype(int).map(_PAYMENT_TYPES)
results["rate_code"] = results["rate_code"].fillna(0).astype(int).map(_RATE_CODES)

return results

Expand Down
4 changes: 2 additions & 2 deletions example/ui/components/date_range_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import streamlit as st

_START_DATE_DEFAULT = date(2015, 4, 1)
_END_DATE_DEFAULT = date(2015, 4, 30)
_START_DATE_DEFAULT = date(2015, 6, 1)
_END_DATE_DEFAULT = date(2015, 7, 30)

_MIN_DATE = date(2015, 1, 1)
_MAX_DATE = date(2015, 12, 31)
Expand Down
2 changes: 1 addition & 1 deletion example/ui/components/payment_type_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def show(key: str = "payment_type_selector") -> str:

index = _PAYMENT_TYPE_OPTIONS.index(st.session_state[key])

payment_type = st.selectbox("Payment type", _PAYMENT_TYPE_OPTIONS, index=index)
payment_type = st.selectbox("Select Payment Type", _PAYMENT_TYPE_OPTIONS, index=index)
st.session_state[key] = payment_type

return st.session_state[key]
Expand Down
32 changes: 26 additions & 6 deletions example/ui/pages/home.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import pandas as pd
import streamlit as st

from example.ui.components import date_range_picker, payment_type_selector

st.title("Home")
st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
st.write("Page with navigation, filters and search results")

left, center = st.columns([0.2, 0.8])

Expand All @@ -17,15 +16,36 @@
* f
* g
* h
* i
* j
* k
* l
* m
"""
st.caption("Navigation")
st.markdown(navigation_items)

with center:
with st.container():
date_range_picker.show()
payment_type_selector.show()
st.caption("Filters")
st.text_input("Search")
st.multiselect("Options", ["a", "b", "c", "d", "e", "f", "g", "h"])
st.toggle("Include inactive")

st.divider()

with st.container():
st.write("Content")
st.caption("Search results")
sample_data = pd.DataFrame(
{
"A": [1, 2, 3, 4],
"B": [10, 20, 30, 40],
"C": [100, 200, 300, 400],
"D": [1000, 2000, 3000, 4000],
"E": [10000, 20000, 30000, 40000],
"F": [100000, 200000, 300000, 400000],
"G": [1000000, 2000000, 3000000, 4000000],
}
)

st.dataframe(sample_data)
28 changes: 28 additions & 0 deletions example/ui/pages/nyt_tlc_trips.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import altair as alt
import streamlit as st

from example.services import nyc_tlc_trips
from example.ui.components import date_range_picker, payment_type_selector

st.title("NY Taxi Trips")

st.write("New York City Taxi and Limousine Commission (TLC) trips")

st.caption("Filters")

date_range = date_range_picker.show()
payment_type = payment_type_selector.show()

trips = nyc_tlc_trips.get_trips(date_range, payment_type)

st.caption("Search results")
st.dataframe(trips)

trip_count_chart = (
alt.Chart(trips)
.mark_line()
.encode(x="day:T", y="trip_count:Q", color="rate_code:N")
.properties(title="Trip Count Over Time by Rate Code")
)

st.altair_chart(trip_count_chart, use_container_width=True)
16 changes: 0 additions & 16 deletions example/ui/pages/page2.py

This file was deleted.

17 changes: 0 additions & 17 deletions example/ui/pages/page3.py

This file was deleted.

16 changes: 0 additions & 16 deletions example/ui/pages/page4.py

This file was deleted.

6 changes: 4 additions & 2 deletions tests/example/services/test_nyc_tlc_trips.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def test_get_trips(mock_big_query_query):
trips = pd.DataFrame(
{
"day": ["2023-01-01"],
"payment_type": "1",
"payment_type": [1],
"rate_code": [1],
"total_fare": [100.0],
"total_tips": [10.0],
"total_amount": [110.0],
Expand All @@ -26,7 +27,7 @@ def test_get_trips(mock_big_query_query):

results = nyc_tlc_trips.get_trips((any_start_date, any_end_date), any_payment_type)

expected_params = {"start_date": "2015-01-01", "end_date": "2015-01-02", "payment_type": "1"}
expected_params = {"start_date": "2015-01-01", "end_date": "2015-01-02", "payment_type": 1}

mock_big_query_query.assert_called_once()

Expand All @@ -38,6 +39,7 @@ def test_get_trips(mock_big_query_query):
{
"day": ["2023-01-01"],
"payment_type": "Credit card",
"rate_code": "Standard rate",
"total_fare": [100.0],
"total_tips": [10.0],
"total_amount": [110.0],
Expand Down
8 changes: 8 additions & 0 deletions tests/example/ui/pages/test_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ def test_show_title():
at = AppTest.from_file("example/ui/pages/home.py").run()

assert at.title[0].value == "Home"


def test_show_navigation_search_results_sections():
at = AppTest.from_file("example/ui/pages/home.py").run()

assert at.caption[0].value == "Navigation"
assert at.caption[1].value == "Filters"
assert at.caption[2].value == "Search results"
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ def test_show_title(mock_get_trips):
trips = pd.DataFrame()
mock_get_trips.return_value = trips

at = AppTest.from_file("example/ui/pages/page3.py").run()
at = AppTest.from_file("example/ui/pages/nyt_tlc_trips.py").run()

assert at.title[0].value == "Page 3"
assert at.title[0].value == "NY Taxi Trips"


@patch("example.services.nyc_tlc_trips.get_trips")
Expand All @@ -29,6 +29,6 @@ def test_show_trips(mock_get_trips):
)
mock_get_trips.return_value = trips

at = AppTest.from_file("example/ui/pages/page3.py").run()
at = AppTest.from_file("example/ui/pages/nyt_tlc_trips.py").run()

pdt.assert_frame_equal(at.dataframe[0].value, trips)

0 comments on commit 15e74fe

Please sign in to comment.