Transport Tool

blog

commentary on data structures

I'm going to take a break from this for a while as I will be traveling. This could be a good time to talk about the "architecture" of this tool so far.

I make use of OOP, like a class for Locations to store the name, and importantly the latitude and longitude. The other information may come in handy next time.

The Recurring fares and Single fares are also classes with pretty much the same methods (wow so polymorphic?? hahahaha). Recurring fare is simple enough, it wraps around an array of size 7, which corresponds to the fares on each day of the week. It lines up with the day indexing of the Javascript Date object, which puts Sunday at index 0, Monday at 1, and so on.

Single fares is more interesting, as it makes use of the dynamic-sized trait of Javascript arrays. Index 0 represents the fares on the first day, which would be the current day, index 1 representing fares tomorrow, so on. I figured there's not much need (at the moment) to track fares on days that have passed (but from an expenditure-tracking perspective, possibly).

I began with a naive approach. Each array element is undefined until it is randomly accessed to have a value written in. Upon retrieval, a zero is returned if it's undefined or zero, which is why having a "get" method is important and having the class wrap around the data.

This naive approach works to me, because there are only so many days in a year, and if one were to track expenses for the next decade, it would still take a trivially small amount of memory, with each item in the array storing a float, multiplied by 365 and however many years... though practically, one wouldn't go so far.

More can be done in the future... currently the mechanism for translating the date to index is still performed imperatively. I could include another layer of processing to take in a Date object and find the fare from a given date. It might make it more scalable and adjustable.

some user experience improvements

As I make my way into making a more usable tool, I will need to improve the interface. To start, I had to add more fields into the calendar representation. I think this would really help visualise how much one spends on a particular day.

The next step is to make the calendar interactable, because I want the user to be able to click any day and set it as a starting point, allowing them to calculate the fares spent in a 30-day span starting from that day.

A stretch goal would be to allow the user to plan far ahead. Say, they may have more trips planned next month. The calendar is currently limited to display up to 6 weeks' worth of days. To extend it to an entire year wouldn't be impossible, but representing that data visually might be the challenge. I cannot at the moment justify cases where one might want to calculate, say, 4 months in the future, but I can see how planning into the next 2 months makes sense. If you mostly have trips planned in the later half of month 1, and the earlier half of month 2, it makes sense to activate your pass only in the half of month 1 and have it carry over its duration to month 2.

If you look into the source HTML, you will see that the table columns and rows are not dynamically generated; they are given IDs instead. (fortunately, I didn't type it all out myself, I used AI...) This is a very rudimentary approach, but scaling up might need me to generate table rows using JavaScript. That is worth exploring.

the usable update

The concession pass calculator is somewhat usable now, even without an API key! Just input the fare yourself. I will one day consider exposing the token so that this page can work perfectly fine as a static page. It should be fine because the key itself expires every 3 days (meaning there's no point storing it...), and is rate-limited to 250 requests per minute. I should hope none of my users are malicious!

I will of course seek to improve the algorithm and user experience. Some refactoring is due, too. haha... But I'm happy to have come this far in such short time, even though everything was rather simple.

A core functionality will be to calculate not just how much you spend in the next 30 days, but also to find the 30-day period where you spend the most, in essence, optimising your purchase to make the MOST value. Maybe also have a way to show how much you spend in any 30-day period anyway.

feeling motivated

I'll let you know that my initial school project began back in late 2023, and public transport fares were due for an increase in Dec '23. Now, we're here again, news broke that there'll be a big increase in fares by card only (concession passes are untouched again!).

Ten whole cents per journey! That's roughly a 10% increase, if the starting fare for a journey is $0.99. Wow... all the more I should seek to get this project done.

calendar

I have created a simple calendar. You should be able to calculate your fares for the next 30 days. It is at this point where I really need to hit the drawing board on the user experience, and at the same time consider how difficult it is to implement it.

The main sticking point is trying to create the UI for the calendar. It seems I may need to expand on it, if I want a more visual representation of trips and fares in a day/month. Golly...

the fare update

Using the OneMap API, I am able to, following the PROPER steps, retrieve public transport directions between two locations, also searched with the service.

I am not particularly concerned about the directions itself, but at this stage how much they cost. So, I'm just taking the "fare" out of the first public transport route the API returns.

We now move on to the calendar, because I believe the use case would be that most have regular commutes (school, work) that are relatively consistent. It also helps to visualise which days one is spending fare money on.

I ideally want the output to be "if you buy the concession pass starting on DAY (not necessarily today), you will get full value out of it for the next 301 days". So, it is not necessary the calculator only starts counting from the current day. The UI will definitely take a long time to perfect.

1 - Based on personal anecdotal information, I believe the duration of the pass is not one month but rather 30 days. To confirm.

hello world!

I am re-starting from scratch my initial idea for a tool that assists with public transport related problems in Singapore, starting with a calculator to see if one should purchase a monthly concession pass.

I have started using the OneMap API, as previously I tried using GoThere but it seems to have some issues. This began as a UI/UX design school project for a mobile app, but this time round I will focus on building a working prototype before jumping into designing. More accurately, I have already done up some designs in the school project, so I should now take a step back and explore implementation before narrowing my design down.

So far, I am quite pleased with what OneMap offers. Some features are free to access without authorisation, but for the others, I will cross that bridge when I get to it.

Yes, it's a calculator to tell you if you're spending more or less than $128 (as of this post) a month on transport.