Course:CPSC312-2021/Flight Recommender

From UBC Wiki

Authors: Hannah Le Bouder, Clement Rugwiro, Emma Nakamoto

What is the problem?

When planning a trip to an exotic destination (post-pandemic, of course), we always want to find the best priced deal for our specific preferences. However, filtering through multiple flight websites and comparing prices on your own can be overwhelming.  A program that does this for us would make planning trips so much easier. We plan to design a flight recommender that uses information on available flights/prices/destinations from existing websites to allow the program to recommend the best priced flight for a user, given a destination and date, and other preferences.

What is the something extra?

We retrieved real-life flight data from an existing website via API calls, rather than manually entering these into our program. The results are then parsed and returned in a way that is concise and easy to understand. As part of this, we also used user-specified constraints to filter the query provided to the API and to filter API-provided results. It will also offer to recommend some hotels in your destination if you wish.

What did we learn from doing this?

Prolog made it easy to process natural language which made it easy to build up queries used to call our api. The ability to set rules locally and parse user input  based on these rules made parsing very straightforward.

Prolog also made working with lists relatively easy. It was intuitive and easy to handle lists differently when you could specifically check the head of a list for certain facts: to be specific, Prolog’s extremely powerful pattern-matching abilities. This also made it easy to extract variables within an atom (or a list), and perform specific functionality on each variable, if desired.

However, Prolog did force us to think differently than we intuitively wanted to for certain problems. For example, there were many problems where we would have used something like an if-else statement to solve it had we had the option. Instead, we were forced to find alternative methods to achieve this functionality, which included using built-in predicates like dif, cut, or even paying close attention to the order in which functions are defined.

Furthermore, debugging in Prolog was relatively straightforward because of its top-down nature. For many of our key functions, there were many helper functions involved. However, if the main function was failing, it was very simple to test each helper function individually, until the bug was found.

Building off of this same idea, yet another positive learning aspect fueled by Prolog is how it lends itself beautifully to breaking down a larger problem into many simpler sub-problems. While the initial problem we were trying to tackle felt overwhelming, by focusing on each very small subpart, we were able to stitch together many working subparts to create a cohesive whole.

Prolog also provided functions to handle making http requests. This was very useful when using API calls to provide the program with facts. However, figuring out how to use the built in library was not as straightforward as it could have been. For example, there were different ways of providing authentication and it was difficult to tell which way was correct based on the documentation and error messages. It was also made more difficult getting built-in libraries when single quotes and double quotes were processed differently.

Links to code etc