Inspiration
We love exploring the world beyond Stanford's campus and trying out new restaurants in downtown Palo Alto, but it can be tricky to choose a restaurant that pleases everybody in the group. Enter Yoink: a stress-free way to get restaurant recommendations optimized for the group.
What it does
Yoink is an iMessage App that can be sent in a group chat. Members of the group can enter their preferences for restaurant rating, price level, cuisine, and distance (walking, biking, or driving). The application keeps track of who has responded, and members of the group can request a recommendation at any time. At that point, the algorithm makes a recommendation for a restaurant that weights each person's criteria equally (relative to each person) and finds a restaurant that closely matches an 'average' combination of each person's criteria.
How I built it
In general, for each group, we create a session with a unique code, get each user's preferences, and vectorize/normalize them. From there, we minimize the displacement from an 'average' preference vector to every restaurant candidate and return the minimized result.
We utilized the Google Maps Places API and the Google Maps Distance Matrix API to retrieve each restaurant's rating, driving distance, and price-level. We then cross-referenced these restaurants by a geographically organized distribution of 'cuisines.' In sum, we collected data on over 700 restaurants in the immediate surrounding area. We also employed an unsupervised k-means clustering algorithm for the minimization question.
In the end, we persisted the restaurant data in a text-file for low latency access and to minimize the duplicate calls to the Google Maps API. We created a flask API in Python hosted on Google Cloud App Engine to collect preference data from the front-end, ultimately storing the preferences in Firebase Cloud Firestore.
In the process of developing this algorithm, we relied heavily on Visual Studio's new online workspaces and "Live Share" features, allowing us to work collaboratively on a single file (similar to Google Docs and Word Online). We also were able to share one instance of a development server, which allowed for easy "gluing" of the API to the front-end even in the early stages of development and, overall, a shortened feedback cycle.
On the front-end in particular, our vision for an iMessage application necessitated writing native iOS code. We used Swift and the "Storyboard" MVC pattern, relying heavily upon the principle of delegation to dispatch actions and move data throughout the app. For example, we had to delegate the conversation actions to view controllers deeper in the view stack.
Challenges I ran into
On the backend, we struggled with effectively vectorizing the data. Initially, we had organized our cuisines alphabetically, which resulted in Stanford's Wilbur Dining cafeteria being disproportionately selected by our algorithm. The issue derived from our calculation of the numerical cuisine score, which over-selected for cuisines alphabetically proximal to the average preference (typically near ~0.5).
On the frontend, we ran into threading and parallelism concerns with communicating between the main UI thread and the background worker threads. Our limited experience with Swift only made debugging and researching these issues more challenging. Likewise, the documentation for iMessage App Extensions also challenged us; with limited examples to orient ourselves we struggled to build a reliable foundation and architecture to introduce additional complexity. Finally, we experienced several large UI difficulties, but we patiently and diligently worked to resolve them.
Accomplishments that I'm proud of
We are proud of using our recently obtained knowledge of linear algebra to vectorize and normalize preferences. Also, we feel accomplished knowing that (at our first Hackathon) we were able build something that we would actually use in our regular lives!
We're also proud of our project scoping. We selected a project both sufficiently challenging but within the scope of our abilities. At the same time, however, we gained exposure to many new technologies.
We even managed to get some sleep!
What I learned
While we spent the majority of our time developing the back-end and front-end separately, we learned how to use API calls to interface the back-end with the front-end. We also learned about the intricacies of the k-means machine-learning algorithm and how to effectively apply it. Some of our team members had no prior experience in cloud development and/or iOS development; even just exposure to the terminologies was very valuable.
What's next for Yoink
In the future, we foresee Yoink restricting restaurant results based on the dietary restrictions of members in the group, provided that Google rigorously supports dietary restriction information. We would also like to obtain a more rigorous data set of food categories beyond ethnic cuisines, such as "noodles" or "diner." Finally, we would love to see Yoink deployed globally!
Built With
- firebase
- google-cloud
- google-maps-places-api
- json
- postman
- python
- swift
- visual-studio
- xcode
Log in or sign up for Devpost to join the conversation.