It is officially spring! No more freezing when I get out of bed due to the 0ºC weather!
Because this is my senior year, spring is more than just flowers blooming and nice weather. For me, it means perfecting my resume and applying for jobs so that I will be prepared for when graduation rolls around.
After graduation, I wish to move to the Pacific Northwest (Washington, Oregon maybe?) and become a developer. It will be a big move, but I am excited to make it and to see new places.
Over the past week, Arkansas (and much of the South) has been hit with one of the worst snowstorms in quite some time. At Hendrix, we have had ankle-deep snow and weather as low as -17°C. With weather conditions as unusual as these, several things have occurred.
Going out to enjoy the temporary nature of conditions such as these during a snow day is a thing of the past. We are living in a strange new world where technology is allowing us to become more and more productive, but at what cost? Will our children know what it is like to take a day off of school or work, or will we be permanently tied to those places (be it rain, sickness, or otherwise), unable to escape?
On the topic of other less philosophical and more concrete changes, it was announced last night that there would likely be rolling blackouts in the area. For most people, this means charging their devices, bundling up, and unplugging any devices that they aren’t using. Because I manage a small server in the affected area, I needed to find a way to maintain uptime of the applications even if power was cut. This led to a frantic mission to transfer data between the physical server and Amazon EC2 instances, during which the physical server could go down at any time.
During this time, I made several interesting discoveries:
Debian on EC2 ships with a different version of Python than the ISO’s you can download. No triple quote support here.
Ubuntu has a but with systemd which wouldn’t allow me to run my init scripts :(
RHEL has depreciated the screen package, leading me to reconfigure my systemd services that require it in order to use tmux. In addition, SELinux prevents you from running systemd files outside of a certain location.
After all of this was done, I went to straight to bed because it was far past my bedtime. May I sleep well knowing my uptime will be much higher now.
Over the weekend, I worked on implementing a mockup of the Positive Vibes app in Flutter. At first, I was very confused about the documentation, because I didn’t quite understand the concept of widgets at first, nor the concept of stateless and stateful widgets. This initially clicked when I realized the similarities between Swift UI and Flutter, which are libraries that can be used to programmatically create objects to make stuff on the screen.
There isn’t a scene builder or a markup language, you must program every action that you see. For some things, it can become quite a time-consuming process, but for other things, it can be much quicker since it automatically adapts based on the device that you are using it on, so that you do not need to use constraints to resize UI.
This week I streamed Portal, a puzzle-platformer game by Valve Software. In this game, the player must control a character named Chel to transverse a number of Aperture Science testing chambers with the use of a portal gun that can create portals.
Within a school setting, there are connections to be made with momentum because momentum is conserved when passing through portals, and it is a required skill in the completion of some levels.
Portal can also be used as a team exercise that builds upon communication skills, designing instructions, and teamwork.
As a part of the classroom, one student will be assigned as the “driver” and will be given the controls of the game. However, the driver is not to simply play the game by themselves. The other team members must work together to come to a solution to the puzzle and relay the solution to the driver in order to complete the puzzle. Team members can take turns being the driver.
I had several issues streaming the game (OBS pinned my computer at 100% GPU and was dropping frames), but I will try Twitch Studio next time.
This week I streamed Putt-Putt Saves the Zoo! It is a point and click adventure game developed by Humongous Entertainment directed towards young children (3-8 years old) in which the player takes control of an anthropomorphic car named Putt-Putt and solve puzzles in order to save zoo animals.
By scattering required items and goals throughout the map, the player is required to use critical thinking skills in order to find each required item and use them in the proper location.
For instance, while visiting Articland for the first time an avalanche will occur which prevents the player from progressing further through the area until a tool is found. In order to continue, the player must find a shovel in the Grasslands area and recognize that the shovel can be used to clear the fallen snow in the Artic area.
In order to prevent player frustration about “why isn’t this item that I’m clicking pick up or do anything”, nearly every object in PPStZ and other Humongous Entertainment games provides direct feedback through a unique animation and sound effect.
Additionally, the game may teach young players several facts about animals that they may not know such as that snakes are not very active in cold climates.
In order to increase interoperability and to create a unified build environment, I decided to implement Docker for the Hendrix Assessment project 🐳.
At first glance, I thought this would be a much easier task than it turned out to be. In order to reduce the complexity with build commands, I needed to simplify the ASP.NET project from three seperate solutions into one solution.
This involved creating a new solution and moving various files around, as well as generating a new .csproj file using commands and through manual editing.
Next, I needed to Dockerize the project.
At first, I began with a Dockerfile similar to the CityOfHope Dockerfile, but because of issues I tried various other configurations (argh networking!) and landed back at the CoHo file.
Finally, I needed to create an environment file and create a script to run the Docker project.
When testing out the City Of Hope website, I got strange errors when clicking “Show Yearly Reports”:
2020-11-05T22:02:56.834519285Z �[41m�[30mfail�[39m�[22m�[49m: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
2020-11-05T22:02:56.834578486Z An unhandled exception has occurred while executing the request.
2020-11-05T22:02:56.834584386Z System.InvalidOperationException: Sequence contains no elements
2020-11-05T22:02:56.836087407Z at System.Linq.ThrowHelper.ThrowNoElementsException()
2020-11-05T22:02:56.836100207Z at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
2020-11-05T22:02:56.836104807Z at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
2020-11-05T22:02:56.836108608Z at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
2020-11-05T22:02:56.836112308Z at System.Linq.Queryable.Last[TSource](IQueryable`1 source, Expression`1 predicate)
2020-11-05T22:02:56.836116208Z at CoHO.Pages.AdminIndexModel.OnPostYearReport()
2020-11-05T22:02:56.836119808Z at lambda_method(Closure , Object , Object )
2020-11-05T22:02:56.836123308Z at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.ActionResultHandlerMethod.Execute(Object receiver, Object arguments)
2020-11-05T22:02:56.836136008Z at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
2020-11-05T22:02:56.836140608Z at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
2020-11-05T22:02:56.836144108Z at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
2020-11-05T22:02:56.836148008Z at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
2020-11-05T22:02:56.836152308Z at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
2020-11-05T22:02:56.847402167Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
2020-11-05T22:02:56.847418568Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
2020-11-05T22:02:56.847423868Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
2020-11-05T22:02:56.847428268Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
2020-11-05T22:02:56.847432068Z --- End of stack trace from previous location where exception was thrown ---
2020-11-05T22:02:56.847442968Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
2020-11-05T22:02:56.847464868Z at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
2020-11-05T22:02:56.847469568Z at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
2020-11-05T22:02:56.847483869Z at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
2020-11-05T22:02:56.847487269Z at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
Turns out, the value of hours was not set and the website was crashing because it was trying to call last on an empty list of values. This was very hard to debug because I wasn’t able to run the project locally and for a long time I was unable to view logs from the Azure App Service. Once I added a value of hours, this issue was resolved.
Deploying Azure SQL for Hendrix assessment has been relatively difficult this week. For some reason, Hendrix’s network blocks all connections to Azure SQL databases, which means that when you try to connect to the database over the school’s connections, you are hit with the following error:
provider: TCP Provider, error: 40 - Could not open a connection to SQL Server
It took me quite a while to discover that it was the network blocking the connection, rather than configuration issues. I tried everything: checking and rechecking the server’s firewall, checking my connection string, etc, and nothing seemed to work. I tried pinging the server, and all of my pings appeared to just drop.
Because of this, I knew something was up. To get around this error, I needed to use a mobile hotspot to get around the blockage. As soon as I did this, the errors were resolved.
Github Actions Breaking
While attempting to switch branches for CI/CD, I needed to disconnect the current GitHub actions and create a new set of actions. In order to do this, Azure needed to generate a new pair of secrets for it to use. For some reason, each time that I ran the build after switching branches, the build would fail. When I checked the logs, it read Publish Profile does not contain kudu URL.
I have tried several methods to fix this issue such as renaming the publishURL, but none of the fixes appear to work. I believe that the recent Active Directory permission restrictions may be to blame because whenever I run the commands to manually grab the secrets GitHub Actions, it gives me an error regarding AD permissions.
Because of this, I have switched the projects to the Kudu build server, and I haven’t had any issues with them.
City Of Hope Deployment
Using the knowledge gained from the Hendrix Assessment project, I was able to successfully deploy the City of Hope website on Azure with an Azure SQL database!
In addition, I have learned a few things:
Implenting your own logging system to write to files is useless, as Azure handles it much more elegantly. Because of this, have all logging write to the console and then have Azure write it to disk.
Either wrap your DB calls in await tags or close the reader for easier times regarding DB locks.
Adding authentication has greatly complicated the deployment process, and has created a learning curve for deploying the website. Instead of simply deploying the website, one must now create a seperate Authentication Application using the proper redirect URLs for deployment, load the keys into the environmental variables on the server, and then deploy.
While exploring authentication and ways to differentiate teachers from students from people in the Office of Assessment, I explored Active Directory and the various types of groups and structures.
During this time, my senior seminar project has taken over my life, and I have ended up spending more time on it than I have on more important things because I was so into what I was doing and I also felt like I needed to work hard on it or I wouldn’t complete it. Besides this, is important to maintain a healthy work-life balance. If you can’t do this, the project is worthless and you will be burnt out from the project.
Because of this, I decided to take a temporary break from the project and catch up on other classwork and get some much needed rest and relaxation.
iOS Development and Senior Seminar
In Senior Seminar, I needed to (mostly) completely restart on my Manuscript project, as both TensorFlow and Android Studio were both proving to be much more complicated systems than I initially believed.
TensorFlow was a board with billions of confusing knobs, and each time I turned one of them, my results would drastically change. I was getting strange results such as my models only predicting 1 class or extremely high overfitting, and between changing my preprocessing, adjusting my layers, activation functions, and loss functions, I was completely at a loss.
I decided to set this aside for a moment and work on the Android app side of things.
Problems quickly arose. In order to draw a picture of a symbol that I created in Lightroom, I needed to first create a Drawable of the image file. This makes sense.
Next, you must place this Drawable on a Canvas. Rather than a Canvas being something that you can create in the Layout Editor, you must create a class that extends View, override onDraw(), and make Canvas as a parameter.
Because of this, I decided to switch my project back to my original plan of an iOS app. After I installed Xcode and began doing research into CoreML, I was surprised to learn that you did not need a developer license to use Apple’s machine learning toolkit.
Training my new model was extremely easy compared to TensorFlow, as CoreML does most of the tweaking for you. Even though my overall accuracy was lower (~76%) than TensorFlow, I did not get the pesky single-class prediction issues or signs of overfitting such as failing to recognize symbols from outside of the dataset. Overall, I see this as a net positive, as I don’t think I could have fixed even with all of the capabilities of TensorFlow, just because I didn’t know enough about it.
Creating the UI itself was easy through the use of SwiftUI, though I’m still having issues with sizing on different devices.
Here’s my progress as viewed on an iPad Pro 12.9” simulator:
This week began with the test deployment of the Razor Pages demo on Azure. Several things were discovered during this process that were not present during the original MVC deployment.
I am still having issues viewing repositories in the Disco Tray Studios repositories in Github, so I needed to make a fork on Github.
Whenever I tried to use the default build script generated by Azure, I got the following error:
MSBUILD : error MSB1003: Specify a project or solution file.
The current working directory does not contain a project or solution file.
Error: Process completed with exit code 1.
After some discussion in the Teams meeting, I came to discover that this was due to the structure of the repository. Rather than the code being in the base directory, it is stored in a directory within the base level directory. This causes a lot of issues for build pipelines unless you tweak them to use this format.
Initially, I decided to resolve this issue by modifying the build file using a cd command before the build command.
However, modifying the build script does not give a good example for future projects, as if we use the same template with other pipeline software we will have to also modify those scripts.
Because of this, I decided to restructure the project to eliminate the base level folder and the cd command in the build script.
Porting Hendrix Assessment to ASP.NET
Porting the Hendrix Assessment frontend webpages to ASP.NET has been relatively easy so far. To port the code over, I first must decide if a Laravel Blade is a section of a shared page. If it is a section of a shared page, I create an associated Razor page in the Shared directory. Examples of these include the general layout blade.
Next, I copy over the blade files into the Razor pages file that I have created. Then, I replace any of the PHP code with C# code. This is because a majority of the page content is in HTML, and only a minority of the code is in PHP that must be replaced. For some of the code such as authentication and databases, I will need to wait until later in the project to connect these up.
Finally, I add the expected ASP.NET front matter to the pages. This includes details such as what layout to use and what title to use.
The deployment for My Life In Months went smoothly! We received positive feedback from users, and we received traffic from around the globe.
It was very interesting learning how to poke around in Google Analytics to view the different traffic sources. We gained a large amount of traffic through our original Hacker News post, but later on, we gained an additional boost in traffic through a post that someone made on Reddit about our site.
Once My Life In Months was gaining users, it was time to begin on our next project. In order to do this, I needed to research Azure hosting, as well as CI/CD. Previously, I didn’t have the best experiences with this, as whenever I hosted an ASP.NET project, Azure would give me an error message.
However, once I started again from our blank template project, I had much better luck setting up the project. Because of the integration with Github and ASP.NET, this was very easy to deploy. I just had to point Azure to the project on Github, and it would automatically create the build scripts, as well as keep the deployment up to date with the master branch.
I’m excited to start working on heavier applications.