Skip to content

Commit

Permalink
tripCounts -> ScheduledServiceDaily (#743)
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrickCleary committed Jul 12, 2023
1 parent 1b9c4aa commit ca7e7f8
Show file tree
Hide file tree
Showing 15 changed files with 69 additions and 69 deletions.
8 changes: 4 additions & 4 deletions common/api/hooks/service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useQuery } from '@tanstack/react-query';
import type { FetchTripCountsOptions } from '../../types/api';
import type { FetchScheduledServiceOptions } from '../../types/api';
import { ONE_HOUR } from '../../constants/time';
import { fetchTripCounts } from '../service';
import { fetchScheduledService } from '../service';

export const useTripCounts = (params: FetchTripCountsOptions, enabled?: boolean) => {
return useQuery(['trips', params], () => fetchTripCounts(params), {
export const useScheduledService = (params: FetchScheduledServiceOptions, enabled?: boolean) => {
return useQuery(['scheduledservice', params], () => fetchScheduledService(params), {
enabled: enabled,
staleTime: ONE_HOUR,
});
Expand Down
16 changes: 8 additions & 8 deletions common/api/service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { FetchTripCountsOptions } from '../types/api';
import { FetchTripCountsParams } from '../types/api';
import type { TripCounts } from '../types/dataPoints';
import type { FetchScheduledServiceOptions } from '../types/api';
import { FetchScheduledServiceParams } from '../types/api';
import type { ScheduledService } from '../types/dataPoints';
import { APP_DATA_BASE_PATH } from '../utils/constants';

export const fetchTripCounts = async (
params: FetchTripCountsOptions
): Promise<TripCounts | undefined> => {
if (!params[FetchTripCountsParams.routeId]) return undefined;
const url = new URL(`${APP_DATA_BASE_PATH}/api/tripcounts`, window.location.origin);
export const fetchScheduledService = async (
params: FetchScheduledServiceOptions
): Promise<ScheduledService | undefined> => {
if (!params[FetchScheduledServiceParams.routeId]) return undefined;
const url = new URL(`${APP_DATA_BASE_PATH}/api/scheduledservice`, window.location.origin);
Object.keys(params).forEach((paramKey) => {
url.searchParams.append(paramKey, params[paramKey]);
});
Expand Down
6 changes: 3 additions & 3 deletions common/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ export enum FetchSpeedsParams {
line = 'line',
}

export type FetchTripCountsOptions = {
[key in FetchTripCountsParams]?: string;
export type FetchScheduledServiceOptions = {
[key in FetchScheduledServiceParams]?: string;
};

export enum FetchTripCountsParams {
export enum FetchScheduledServiceParams {
startDate = 'start_date',
endDate = 'end_date',
routeId = 'route_id',
Expand Down
2 changes: 1 addition & 1 deletion common/types/dataPoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export type ServiceLevels = {
};
};

export type TripCounts = {
export type ScheduledService = {
counts: number[];
start_date: string;
end_date: string;
Expand Down
4 changes: 2 additions & 2 deletions modules/service/PercentageServiceGraphWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import type { SetStateAction } from 'react';
import type { DeliveredTripMetrics, TripCounts } from '../../common/types/dataPoints';
import type { DeliveredTripMetrics, ScheduledService } from '../../common/types/dataPoints';
import { WidgetCarousel } from '../../common/components/general/WidgetCarousel';
import { PercentageWidgetValue } from '../../common/types/basicWidgets';
import { WidgetForCarousel } from '../../common/components/widgets/internal/WidgetForCarousel';
Expand All @@ -14,7 +14,7 @@ import { getPercentageData, getAverageWithNaNs } from './utils/utils';

interface PercentageServiceGraphWrapperProps {
data: DeliveredTripMetrics[];
predictedData: TripCounts;
predictedData: ScheduledService;
config: ParamsType;
startDate: string;
endDate: string;
Expand Down
4 changes: 2 additions & 2 deletions modules/service/ServiceDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { useDelimitatedRoute } from '../../common/utils/router';
import { ChartPlaceHolder } from '../../common/components/graphics/ChartPlaceHolder';
import { useTripCounts } from '../../common/api/hooks/service';
import { useScheduledService } from '../../common/api/hooks/service';
import { Layout } from '../../common/layouts/layoutTypes';
import { PageWrapper } from '../../common/layouts/PageWrapper';
import { getSpeedGraphConfig } from '../speed/constants/speeds';
Expand Down Expand Up @@ -34,7 +34,7 @@ export function ServiceDetails() {
enabled
);

const predictedData = useTripCounts(
const predictedData = useScheduledService(
{
start_date: startDate,
end_date: endDate,
Expand Down
4 changes: 2 additions & 2 deletions modules/service/ServiceGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ import { useBreakpoint } from '../../common/hooks/useBreakpoint';
import { watermarkLayout } from '../../common/constants/charts';
import { ChartBorder } from '../../common/components/charts/ChartBorder';
import { ChartDiv } from '../../common/components/charts/ChartDiv';
import type { DeliveredTripMetrics, TripCounts } from '../../common/types/dataPoints';
import type { DeliveredTripMetrics, ScheduledService } from '../../common/types/dataPoints';
import { getShuttlingBlockAnnotations } from './utils/graphUtils';

interface ServiceGraphProps {
data: DeliveredTripMetrics[];
predictedData: TripCounts;
predictedData: ScheduledService;
config: ParamsType;
startDate: string;
endDate: string;
Expand Down
4 changes: 2 additions & 2 deletions modules/service/ServiceGraphWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import type { DeliveredTripMetrics, TripCounts } from '../../common/types/dataPoints';
import type { DeliveredTripMetrics, ScheduledService } from '../../common/types/dataPoints';
import type { ParamsType } from '../speed/constants/speeds';
import { WidgetCarousel } from '../../common/components/general/WidgetCarousel';
import { TripsWidgetValue } from '../../common/types/basicWidgets';
Expand All @@ -10,7 +10,7 @@ import { getServiceWidgetValues } from './utils/utils';
import { ServiceGraph } from './ServiceGraph';
interface ServiceGraphWrapperProps {
data: DeliveredTripMetrics[];
predictedData: TripCounts;
predictedData: ScheduledService;
config: ParamsType;
startDate: string;
endDate: string;
Expand Down
4 changes: 2 additions & 2 deletions modules/service/ServiceOverviewWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import classNames from 'classnames';
import type { DeliveredTripMetrics, TripCounts } from '../../common/types/dataPoints';
import type { DeliveredTripMetrics, ScheduledService } from '../../common/types/dataPoints';
import { BasicWidgetDataLayout } from '../../common/components/widgets/internal/BasicWidgetDataLayout';
import { PercentageWidgetValue, TripsWidgetValue } from '../../common/types/basicWidgets';
import type { ParamsType } from '../speed/constants/speeds';
Expand All @@ -9,7 +9,7 @@ import { getServiceWidgetValues } from './utils/utils';

interface ServiceOverviewWrapperProps {
data: DeliveredTripMetrics[];
predictedData: TripCounts;
predictedData: ScheduledService;
config: ParamsType;
startDate: string;
endDate: string;
Expand Down
4 changes: 2 additions & 2 deletions modules/service/ServiceWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import dayjs from 'dayjs';
import { useDelimitatedRoute } from '../../common/utils/router';
import { ChartPlaceHolder } from '../../common/components/graphics/ChartPlaceHolder';
import { WidgetDiv } from '../../common/components/widgets/WidgetDiv';
import { useTripCounts } from '../../common/api/hooks/service';
import { useScheduledService } from '../../common/api/hooks/service';
import { OVERVIEW_OPTIONS, TODAY_STRING } from '../../common/constants/dates';
import { useDeliveredTripMetrics } from '../../common/api/hooks/tripmetrics';
import { getSpeedGraphConfig } from '../speed/constants/speeds';
Expand All @@ -25,7 +25,7 @@ export const ServiceWidget: React.FC = () => {
},
enabled
);
const predictedServiceData = useTripCounts({
const predictedServiceData = useScheduledService({
start_date: startDate,
end_date: endDate,
route_id: lineShort,
Expand Down
4 changes: 2 additions & 2 deletions modules/service/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PEAK_SCHEDULED_SERVICE } from '../../../common/constants/baselines';
import type { DeliveredTripMetrics, TripCounts } from '../../../common/types/dataPoints';
import type { DeliveredTripMetrics, ScheduledService } from '../../../common/types/dataPoints';
import type { Line } from '../../../common/types/lines';

export const getServiceWidgetValues = (
Expand Down Expand Up @@ -32,7 +32,7 @@ export const getServiceWidgetValues = (

export const getPercentageData = (
data: DeliveredTripMetrics[],
predictedData: TripCounts,
predictedData: ScheduledService,
line?: Line
) => {
const scheduled = data.map((datapoint, index) => {
Expand Down
2 changes: 1 addition & 1 deletion server/.chalice/policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"arn:aws:dynamodb:*:*:table/DeliveredTripMetrics",
"arn:aws:dynamodb:*:*:table/DeliveredTripMetricsWeekly",
"arn:aws:dynamodb:*:*:table/DeliveredTripMetricsMonthly",
"arn:aws:dynamodb:*:*:table/TripCounts",
"arn:aws:dynamodb:*:*:table/ScheduledServiceDaily",
"arn:aws:dynamodb:*:*:table/Ridership"
]
}
Expand Down
6 changes: 3 additions & 3 deletions server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,14 @@ def get_trips_by_line():
return json.dumps(response, indent=4, sort_keys=True)


@app.route("/api/tripcounts", cors=cors_config)
def get_trip_counts():
@app.route("/api/scheduledservice", cors=cors_config)
def get_scheduled_service():
query = app.current_request.query_params
start_date = parse_user_date(query["start_date"])
end_date = parse_user_date(query["end_date"])
route_id = query.get("route_id")
agg = query["agg"]
response = service_levels.get_trip_counts(
response = service_levels.get_scheduled_service(
start_date=start_date,
end_date=end_date,
route_id=route_id,
Expand Down
4 changes: 2 additions & 2 deletions server/chalicelib/dynamo.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ def query_daily_trips_on_line(table_name, line, start_date, end_date):
return results


def query_trip_counts(start_date: date, end_date: date, route_id: str = None):
table = dynamodb.Table("TripCounts")
def query_scheduled_service(start_date: date, end_date: date, route_id: str = None):
table = dynamodb.Table("ScheduledServiceDaily")
line_condition = Key("routeId").eq(route_id)
date_condition = Key("date").between(start_date.isoformat(), end_date.isoformat())
condition = line_condition & date_condition
Expand Down
66 changes: 33 additions & 33 deletions server/chalicelib/service_levels.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
from typing import List, Dict, TypedDict, Union, Literal
import pandas as pd

from .dynamo import query_trip_counts
from .dynamo import query_scheduled_service
from .data_funcs import index_by, date_range

ByHourServiceLevels = List[int]
DayKind = Union[Literal["weekday"], Literal["saturday"], Literal["sunday"]]
AggTypes = Union[Literal["daily"], Literal["weekly"], Literal["monthly"]]
TripCounts = List[Dict]
ScheduledService = List[Dict]


class ByDayKindServiceLevels(TypedDict):
Expand All @@ -22,7 +22,7 @@ class ByDayKindServiceLevels(TypedDict):
sunday: ByDayKindServiceLevels


class GetTripCountsResponse(TypedDict):
class GetScheduledServiceResponse(TypedDict):
start_date_service_levels: ByDayKindServiceLevels
end_date_service_levels: ByDayKindServiceLevels
start_date: str
Expand All @@ -31,11 +31,11 @@ class GetTripCountsResponse(TypedDict):


def get_next_day_kind_service_levels(
trip_counts: TripCounts,
scheduled_service: ScheduledService,
day_kind: DayKind,
) -> ByDayKindServiceLevels:
def predicate(trip_count):
day_of_week = datetime.fromisoformat(trip_count["date"]).weekday()
def predicate(scheduled_service_day):
day_of_week = datetime.fromisoformat(scheduled_service_day["date"]).weekday()
if day_kind == "weekday":
return day_of_week < 5
elif day_kind == "saturday":
Expand All @@ -44,78 +44,78 @@ def predicate(trip_count):
return day_of_week == 6
return False

for trip_count in trip_counts:
if predicate(trip_count):
for daily_service_count in scheduled_service:
if predicate(daily_service_count):
return {
"date": trip_count["date"],
"service_levels": trip_count.get("byHour", {}).get("totals", []),
"date": daily_service_count["date"],
"service_levels": daily_service_count.get("byHour", {}).get("totals", []),
}
return None


def get_service_levels(
trip_counts: TripCounts,
scheduled_service: ScheduledService,
search_from_end: bool,
) -> ByDayKindServiceLevels:
if search_from_end:
trip_counts = list(reversed(trip_counts))
scheduled_service = list(reversed(scheduled_service))
return {
"weekday": get_next_day_kind_service_levels(trip_counts, "weekday"),
"saturday": get_next_day_kind_service_levels(trip_counts, "saturday"),
"sunday": get_next_day_kind_service_levels(trip_counts, "sunday"),
"weekday": get_next_day_kind_service_levels(scheduled_service, "weekday"),
"saturday": get_next_day_kind_service_levels(scheduled_service, "saturday"),
"sunday": get_next_day_kind_service_levels(scheduled_service, "sunday"),
}


def get_weekly_trip_counts(trip_counts_arr, start_date, end_date):
df = pd.DataFrame({'value': trip_counts_arr}, index=pd.date_range(start_date, end_date))
def get_weekly_scheduled_service(scheduled_service_arr, start_date, end_date):
df = pd.DataFrame({'value': scheduled_service_arr}, index=pd.date_range(start_date, end_date))
weekly_df = df.resample('W-SUN').median()
# Drop the first week if it is incomplete
if datetime.fromisoformat(start_date.isoformat()).weekday() != 6:
weekly_df = weekly_df[1:]
return weekly_df['value'].tolist()


def get_monthly_trip_counts(trip_counts_arr, start_date, end_date):
df = pd.DataFrame({'value': trip_counts_arr}, index=pd.date_range(start_date, end_date))
def get_monthly_scheduled_service(scheduled_service_arr, start_date, end_date):
df = pd.DataFrame({'value': scheduled_service_arr}, index=pd.date_range(start_date, end_date))
monthly_df = df.resample('M').median()
# Drop the first month if it is incomplete
if datetime.fromisoformat(start_date.isoformat()).day != 1:
monthly_df = monthly_df[1:]
return monthly_df['value'].tolist()


def get_trip_counts(
def get_scheduled_service(
start_date: date,
end_date: date,
agg: AggTypes,
route_id: str = None,
) -> GetTripCountsResponse:
trip_counts = query_trip_counts(
) -> GetScheduledServiceResponse:
scheduled_service = query_scheduled_service(
start_date=start_date,
end_date=end_date,
route_id=route_id,
)
trip_counts_by_date = index_by(trip_counts, "date")
trip_counts_arr = []
scheduled_service_by_day = index_by(scheduled_service, "date")
scheduled_service_arr = []
for current_day in date_range(start_date, end_date):
current_day_iso = current_day.isoformat()
if current_day_iso in trip_counts_by_date:
trip_count = trip_counts_by_date[current_day_iso]["count"]
if current_day_iso in scheduled_service_by_day:
scheduled_service_count = scheduled_service_by_day[current_day_iso]["count"]
else:
trip_count = 0
trip_counts_arr.append(trip_count)
scheduled_service_count = 0
scheduled_service_arr.append(scheduled_service_count)
counts = []
if agg == 'daily':
counts = trip_counts_arr
counts = scheduled_service_arr
if agg == 'weekly':
counts = get_weekly_trip_counts(trip_counts_arr, start_date, end_date)
counts = get_weekly_scheduled_service(scheduled_service_arr, start_date, end_date)
if agg == 'monthly':
counts = get_monthly_trip_counts(trip_counts_arr, start_date, end_date)
counts = get_monthly_scheduled_service(scheduled_service_arr, start_date, end_date)

return {
"counts": counts,
"start_date": start_date.isoformat(),
"end_date": end_date.isoformat(),
"start_date_service_levels": get_service_levels(trip_counts, False),
"end_date_service_levels": get_service_levels(trip_counts, True),
"start_date_service_levels": get_service_levels(scheduled_service, False),
"end_date_service_levels": get_service_levels(scheduled_service, True),
}

0 comments on commit ca7e7f8

Please sign in to comment.