Closed SergeyAnufriev closed 7 months ago
I'm not a Python expert, but I believe this code
#Define a function to extract single ticket price from a TimeFilterResult object
def extract_single_ticket_price(result):
for location in result.locations:
for property in location.properties:
for fare in property.fares.breakdown:
for ticket in fare.tickets:
if ticket.type == 'single':
return ticket.price
will take the first single ticket price of the first reachable locations from the breakdown and return it. There is a fares.tickets_total object that has the total sum.
there are still bugs in ticket prices including if fares.tickets_total are used. code below shows tickets_total for 3 h journey returns 3.5 pounds
from traveltimepy import Location, Coordinates, TravelTimeSdk,PublicTransport,Property
import asyncio
from datetime import datetime
import os
sdk = TravelTimeSdk(os.environ.get("TRAVEL_TIME_LOGIN"), os.environ.get("TRAVEL_TIME_PASSWORD"))
ids_from = [298202,296933,297600]
ids_to = [297684,298669,298400]
'''Input coordinates from and to travel'''
coords_start = [
[52.6265 , -1.71263 ],
[52.0728 , -0.631566],
[52.5806 , -2.11686 ]]
coords_end = [
[53.6056, -2.39163],
[52.8258, -2.00097],
[53.3642, -2.29783]]
coords_from = [Coordinates(lat= x, lng= y) for x,y in coords_start]
coords_to = [Coordinates(lat= x, lng= y) for x,y in coords_end]
locations_from = [Location(id='s'+str(x),coords = y) for x,y in zip(ids_from,coords_from)]
locations_to = [Location(id='e'+str(x),coords = y) for x,y in zip(ids_to,coords_to)]
locations = list(set(locations_from + locations_to))
search_dict = {'s'+str(x):['e'+str(y)] for x,y in zip(ids_from,ids_to)}
async def travel_times(search_dict,locations):
locations = locations
search_ids = search_dict
results = await sdk.time_filter_async(
locations = locations,
search_ids = search_ids,
transportation = PublicTransport(),
properties=[Property.TRAVEL_TIME, Property.FARES],
departure_time=datetime(2023, 9,27,13,0),
travel_time=14400)
return results
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
res = asyncio.run(travel_times(search_dict,locations))
#Define a function to extract single ticket price from a TimeFilterResult object
def extract_single_ticket_price(result):
for location in result.locations:
for property in location.properties:
travel_time = 0 # Initialize total travel time
for prop in location.properties:
if prop.travel_time:
travel_time += prop.travel_time
return property.fares.tickets_total, property.fares.breakdown, travel_time
return None
for result in res:
tickets_total, breakdown , travel_time = extract_single_ticket_price(result)
print('tickets_total',tickets_total)
print('breakdown',breakdown)
print('travel_time',travel_time/3600)
OUTPUT: tickets_total [Ticket(type='single', price=9.15, currency='GBP'), Ticket(type='week', price=187.8, currency='GBP'), Ticket(type='month', price=721.1519999999999, currency='GBP'), Ticket(type='year', price=7512.0, currency='GBP')] breakdown [FareBreakdown(modes=['rail_national'], route_part_ids=[10], tickets=[Ticket(type='single', price=0.05, currency='GBP'), Ticket(type='week', price=141.6, currency='GBP'), Ticket(type='month', price=543.7439999999999, currency='GBP'), Ticket(type='year', price=5664.0, currency='GBP')]), FareBreakdown(modes=['rail_national'], route_part_ids=[11], tickets=[Ticket(type='single', price=9.1, currency='GBP'), Ticket(type='week', price=46.2, currency='GBP'), Ticket(type='month', price=177.40800000000002, currency='GBP'), Ticket(type='year', price=1848.0, currency='GBP')])] travel_time 3.825 tickets_total [Ticket(type='single', price=3.4499999999999997, currency='GBP'), Ticket(type='week', price=148.3, currency='GBP'), Ticket(type='month', price=569.472, currency='GBP'), Ticket(type='year', price=5932.0, currency='GBP')] breakdown [FareBreakdown(modes=['rail_national'], route_part_ids=[13, 14], tickets=[Ticket(type='single', price=0.05, currency='GBP'), Ticket(type='week', price=148.3, currency='GBP'), Ticket(type='month', price=569.472, currency='GBP'), Ticket(type='year', price=5932.0, currency='GBP')]), FareBreakdown(modes=['bus'], route_part_ids=[7], tickets=[Ticket(type='single', price=3.4, currency='GBP')])] travel_time 2.561111111111111 tickets_total [Ticket(type='week', price=194.7, currency='GBP'), Ticket(type='month', price=687.36, currency='GBP'), Ticket(type='year', price=7160.0, currency='GBP'), Ticket(type='single', price=4.25, currency='GBP')] breakdown [FareBreakdown(modes=['rail_national'], route_part_ids=[20, 19, 18], tickets=[Ticket(type='single', price=0.05, currency='GBP')]), FareBreakdown(modes=['bus'], route_part_ids=[9, 13], tickets=[Ticket(type='single', price=4.2, currency='GBP'), Ticket(type='week', price=15.7, currency='GBP')]), FareBreakdown(modes=['rail_national'], route_part_ids=[19, 18], tickets=[Ticket(type='week', price=148.8, currency='GBP'), Ticket(type='month', price=571.392, currency='GBP'), Ticket(type='year', price=5952.0, currency='GBP')]), FareBreakdown(modes=['rail_national'], route_part_ids=[20], tickets=[Ticket(type='week', price=30.2, currency='GBP'), Ticket(type='month', price=115.96799999999999, currency='GBP'), Ticket(type='year', price=1208.0, currency='GBP')])] travel_time 3.4516666666666667
Process finished with exit code 0
in addition rail segments often cost 5pence
just take a glance at the data
we get 15% of all trains cost 5p
Hi Sergey, William
Thanks for flagging this, we will need to take a deeper look into the data to work out what is going on. I'll let you know once we know more.
Thanks, Chris
Hey Sergey, William
Thanks for you patience on this. We found a couple of ticket types that were returning the 5p fare, but it took some investigation to establish whether they were valid or not.
It turns out they were not (they were related to things like a staff only discounted fare) so we have removed them from the dataset.
Chris
Does that mean we can use current versions of APIs, since the bug in dataset or do we have to update TravelAPI package?
Apologies I got slightly ahead of myself and I didn't realise that we are still waiting to merge the fix and will then need to redeploy the maps.
I will let you know once this is done. You won't need to change anything at your end, the API will then use the updated data.
I have found that quite often API returns single tickets price at 5p. The following code reproduces the error in traveltimepy 3.4.0
from traveltimepy import Location, Coordinates, TravelTimeSdk,PublicTransport,Property,FullRange import asyncio from datetime import datetime
sdk = TravelTimeSdk(' ', ' ')
ids_from = [298555,298331,296932,297784,298405,298121,298202,296933,297600] ids_to = [298285,298229,298571,296052,298574,298179,297684,298669,298400]
'''Input coordinates from and to travel'''
coords_start = [[52.4974 , -2.01641 ], [53.6002 , -2.28587 ], [52.0728 , -0.631566], [52.5806 , -2.11686 ], [53.5737 , -2.42206 ], [51.5271 , -0.238967], [52.6265 , -1.71263 ], [52.0728 , -0.631566], [52.5806 , -2.11686 ]]
coords_end = [[52.8258, -2.00097], [52.6265, -1.71263], [52.8258, -2.00097], [53.1598, -2.66918], [52.8258, -2.00097], [52.6738, -1.75808], [53.6056, -2.39163], [52.8258, -2.00097], [53.3642, -2.29783]]
coords_from = [Coordinates(lat= x, lng= y) for x,y in coords_start] coords_to = [Coordinates(lat= x, lng= y) for x,y in coords_end]
locations_from = [Location(id='s'+str(x),coords = y) for x,y in zip(ids_from,coords_from)] locations_to = [Location(id='e'+str(x),coords = y) for x,y in zip(ids_to,coords_to)]
locations = list(set(locations_from + locations_to)) search_dict = {'s'+str(x):['e'+str(y)] for x,y in zip(ids_from,ids_to)}
async def travel_times(search_dict,locations):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) res = asyncio.run(travel_times(search_dict,locations))
Define a function to extract single ticket price from a TimeFilterResult object
def extract_single_ticket_price(result): for location in result.locations: for property in location.properties: for fare in property.fares.breakdown: for ticket in fare.tickets: if ticket.type == 'single': return ticket.price return None
Extract and print the single ticket prices for each result
for result in res: single_ticket_price = extract_single_ticket_price(result) if single_ticket_price is not None: print(f"Search ID: {result.search_id}, Single Ticket Price: {single_ticket_price} GBP") else: print(f"Search ID: {result.search_id}, Single Ticket Price not found")
OUTPUT:
Search ID: s296932, Single Ticket Price: 0.05 GBP Search ID: s296933, Single Ticket Price: 0.05 GBP Search ID: s297600, Single Ticket Price: 0.05 GBP Search ID: s297784, Single Ticket Price: 0.05 GBP Search ID: s298121, Single Ticket Price: 0.05 GBP Search ID: s298202, Single Ticket Price: 0.05 GBP Search ID: s298331, Single Ticket Price: 0.05 GBP Search ID: s298405, Single Ticket Price: 0.05 GBP Search ID: s298555, Single Ticket Price: 0.05 GBP