TVFrame
Technologies used: Python, Swift, Gmail API, Linux
TVFrame is a project that emulates what a "smart" picture frame does but on any display. It's meant to be run on a Raspberry Pi and works completely wirelessly. Pictures can be emailed to the Pi at a Gmail account specified by the user and the device automatically downloads them and adds them to the slideshow. In order to make the project more interesting, I developed a RESTful API to run on the Raspberry Pi to allow control of it wirelessly. Then finally I developed an iOS app to interface with the API and control the Pi. App functionality includes changing modes between slideshow and single photo mode, where the user can select which photo is displayed; updating the device name; viewing the pictures saved to the device as well as the ability to delete them from the devive; and also viewing the device's activity log.
The first challenge I encountered with the app-side of this project was refamiliarizing myself with Xcode and Swift. I took an iOS development course through CodePath at UT my sophomore year but didn't remember much about the language other than Swift optionals were my worst enemy. After a day of Googling and YouTubing though I got comfortable enough to have the settings page of my app laid out. Then all I had to do was submit a GET request to my API and I'd have all my settings data to populate my text fields, or so I thought. It took me a full day to figure out how to save the results of an HTTP request in Swift. I wasn't familiar with function closures in Swift and so anytime I debugged my app I could see that I was getting the data but I couldn't figure out how to assign that data to my instance variable I was trying to use. I finally found a YouTube tutorial on it and got that part working, only to be stumped a day later by asynchronous GET requests not populating my data models for my table views. After finally figuring that out it was relatively smooth sailing to finish up the app.
Challenges for the backend development of this project were not as frustrating as the app challenges because of my higher level of experience with Python. Flask makes it relatively simple to get a REST API up and running quickly, and I have experience working with Google's APIs. One of the tricky part of the backend development was figuring out how to create a GET route for each picture in the pictures directory so that the app could populate the table view. I hadn't ever used Flask's make_response() method before and so I didn't know it was as easy as that. The other challenging part was getting the multithreading part of the backend working. I hadn't ever developed any multithreaded applications before this and so I was completely out of my element at first. Eventually I figured out Python's threading module and got it working like I wanted.
Future features I hope to add:
- The ability for users to rename pictures saved on the Pi and download them to their iOS device
- The ability to create playlists of pictures and allow the user to select one to be played back on the TV
Google Drive CLI
Technologies used: Python, Google Drive API
I primarily use Google Drive to save all of my school work, as it makes it easy to access all my files from anywhere, across multiple devices--that is, when I remember to upload them. The first iteration of this project was my wanting something I could schedule to run every few minutes to upload anything I had forgotten about to Google. In my head it would work like this: I'd give it both the path of the directory on my machine that I want synced with Google Drive, as well as the folder ID of the Google Drive folder with which I want it to be synced. Then each time it runs, it looks at both, determines what's different, and syncs the two folders. The hardest part of this project was developing the algorithm that recursively looks through the Google Drive file system. I was expecting Google Drive to be structured similarly to a normal file system, but it's not. Google Drive uses IDs, not filepaths. Every folder and file has an ID and stores the ID of its parent as well. To traverse the file structure, I had to write an algorithm that takes a starting parent ID representing the folder to be synced (provided by the user), and then iterates through all the children. Each child is analyzed and if it is another folder it is added to a list of folders, which are then subsequently iterated through. To help me design this algorithm I looked into the source code for the os.walk() function within Python's os module. Once I had the algorithm working, it was simple enough to modify it to work on a traditional file structure as well. Once it was working for both platforms, all that was left to do was compare the results of both runs, and either upload or download the dissimilar files.
After this proof of concept, I started to think about adding flexibility. I decided to create a Google Drive command-line interface, which can be used to navigate Google Drive within your terminal as if it was a directory on your computer. You can use the popular Bash commands like pwd, ls, cd, and clear as well as custom ones that have functions specific to Google Drive. Tracked folders can also be set up to make it easy to keep a local folder in sync with a Google Drive folder.
This website
Technologies used: Node.js, HTML, CSS, MySQL, Nginx
Before building this website I had no experience with JavaScript, HTML, or CSS. Part of my motivation to build it was learning these technologies, which is the reason I chose Node.js for my backend instead of a Python framework like Django or Flask, which would've been more comfortable for me. This was also my first time using Git, which comes with its own learning curve. The first step in this project was figuring out whether or not I needed a front-end framework for my site. I had heard about things like React, Angular, and Vue, but I didn't really understand the use case for them. At first I thought I needed one if I wanted my website to have any dynamic elements, and decided to use React as it is more lightweight than Angular and doesn't use TypeScript. I quickly realized, however, that a front-end framework was extreme overkill for my needs. These frameworks are designed with single-page web apps in mind, not for mostly-static personal websites with limited user interaction. This was a relief for me, as it made my job much simpler. The next hurdle I came across was figuring out what a templating engine was--all the tutorials I read about starting a website with Node.js and Express used a different one (Pug, EJS, Mustache, Handlebars, etc.). After some digging though I realized the advantages of using one, namely reducing duplicate code and being able to render the HTML dynamically. I settled on using Handlebars because I wanted to stick as closely to vanilla HTML as possible, while still taking advantage of the aforementioned benefits.
As I mentioned earlier, before building this website I had no experience with CSS. It was already a murky concept for me, and adding to my confusion was the fact that CSS frameworks are implemented with HTML classes--meaning you don't see the CSS at all. I watched a tutorial on how to use Twitter's framework, Bootstrap, but wasn't happy with what it had to offer. Then I stumbled upon a YouTube video on CSS Grid and immediately liked what it had to offer. Once I discovered it I ditched Bootstrap and started working. It took a little while to get comfortable with designing the grid layout and placing elements on it, but after some trial and error I got the home page looking how I wanted. Then I moved on to designing the video page. This is an example of a use case where CSS Grid really shines. As is evident by the name, the technology is best suited to content that naturally fits a grid. In about 30 lines of CSS I managed to create a layout that auto-resizes based on browser width (with each video also auto-resizing), has rounded corners, padding, and a built-in algorithm for placing the videos within the grid to minimize empty space.
MIS 333K Final Project
Technologies used: C#/MVC, Azure SQL Database, Razor, Bootstrap
This was the final project for my MIS 333K class on C# and MVC. For it, my team and I had to create a banking web app where users could login; open various types of accounts including checkings, savings, stock portfolios, and IRA accounts; and manage their money by depositing, withdrawing, transferring, or using existing balances to buy stock. The joke about this class is that the "K" in "333K" stands for killer because of how hard it is and a large part of that is this project. It's equally a test of time management and teamwork skills as it is coding ability and no matter how early you start, the last week before it's due involves a lot of sleepless nights.
Yahoo Finance ETL
Technologies used: C#, SQL
I wrote this script during my internship at Valero during the summer of 2019. The purpose of it is to automate the monthly procedure of downloading the past month's stock price data from Yahoo Finance and uploading it to a local Oracle database. It can be run both from the batch file, as an automated job, and manually. If run manually, additional parameters can be passed in if a different date range is desired.
Note: permission granted by Valero to publish this--some code has been removed for security reasons