2025

Feb - Mar

Resources

Incredible Budget Home Server! 2/12/2025

Projects


2/12/2025

Where Things Stand

Already, this year has progressed very differently from last year, for which I had outlined three goals: get a new job, start the CU Boulder Masters program, and build important side projects.

I didn’t get a new job, but I learned how to write a ton of cover letters and receive a ton of automated rejection emails. Confidently, I am far closer to getting a new job than I was six months ago. I didn’t start a Masters degree; instead, I started a Bachelors with WGU, and I’m very happy with that decision. I had a lot of false starts with my side projects. Looking back on my notes, I see several times when I intended to start a lengthy project only to pivot a couple weeks later. I think starting school was the culprit. My Hasse Diagram Generator was a great little project that I worked on from start to finish, learning the nuances of Rust in the process. I’m proud of that one.

This year is different because my goals are much more ironclad. They are as follows: get a new job or internship, aim to finish my CS program, and build projects that directly improve my way of living. I have clear prospects in all three goals: I’ve got a second interview coming up, I’m making swift progress in my degree, and this last month, I’ve been hacking away at projects like a madman.

I’ve been keeping myself so busy with CS coursework, side projects, and worky work that I didn’t find time to update this log — elsewhere, I’ve called attention to the irony of writing little when there’s much to say and writing much when there’s little to say. Well, there has been much to say, and I’ve finally gotten around to it.

Media and SFTP Servers

A confluence of many events finally produced in me a deep appreciation for open source, internet privacy, and keeping things practical in life. I decided it was time to fully ditch streaming music and rebuild a collection of music that I own, fully DRM-free. I dusted off the old desktop machine with Ubuntu installed and I began configuring a server with plex. I used a tutorial video, Incredible Budget Home Server!, to help with the process. All told, my first setup involved an SMB connection with samba to load files onto the server from another machine and a plex server exposed to the internet via port forwarding.

From there, I wanted to give myself access to my files remotely, creating an FTP server that could replace my cloud storage providers. I ditched the SMB connection since I found it is too insecure to use over the internet. Instead, I simply used SSH with SFTP clients like FileZilla on Windows and Linux, and FE File Explorer on iOS.

SSH is not without security risks, so to harden my server, I changed the default SSH port away from 22, replaced password access with RSA key access, and configured an obscure DDNS domain on my router both to make sure that remote connection isn’t lost on account of DHCP, and to add just a little extra security.

I’m very pleased with my final setup, which includes a fully functioning media server and SFTP server that works just as well as cloud services. Awesome!

Next Steps

Now that I have a functioning server setup, I want to streamline it. First, I'll replace Ubuntu 24.04.1 LTS with Ubuntu Server. Second, I'll containerize each server microservice with Docker. Third and in conjunction with the second, I'll probably switch from Plex to Jellyfin for my media server; Jellyfin has a nice Docker image that I can use quite easily. I think this new organization with make everything more orderly, and it will make it easier to transfer all my services to a new machine if and when I upgrade my hardware. Lots to do and learn. I'm excited!


2/27/2025

Ubuntu Server

Earlier this week, I transferred all my server files over to external storage before replacing Ubuntu Desktop with Ubuntu Server. Installing Ubuntu has never been terribly complicated compared to other distros, and this was no different. I did have to fuss over Wi-Fi connection a little more though, creating a config file /etc/netplan/50-cloud-init.yaml that specifies the SSID and password of the router, and that dhcp4 would be used. Later, I modified this file to create a connection via static ip, setting dhcp4: false, declaring the static ip, the default gateway, and the nameservers to use.

Ubuntu Server reduces the overhead of my server by omitting a desktop environment and gui, streamlining the kernel with low latency features, and including frame pointers, which harkens to a time when they were omitted from gcc to optimize the i386 processor, a fix that later caused problems — I want to learn more about this.

At any rate, I was already interfacing with my server almost exclusively via the terminal through ssh, but now terminal access is the only option. I think this will further increase learning opportunities!


3/5/2025

WGU Discrete Math 2 and Bubble Sort

I just started the second Discrete Math class today, a class that is supposed to be quite difficult. So far, chapter one is mainly a review and meant to establish some of the basic vocabulary for the course. I can already see that the ensuing chapters will kick it up a notch.

For now, I’m having a good time reviewing the likes of Algorithm Complexity and inspecting the pseudocode of trivial algorithms like Bubble Sort. As a matter of fact, when I noticed that the chapter I was reading was about to cover the paeudocode for Bubble Sort, I looked away and determined I would both write the pseudocode and C code myself since I was pretty certain I fully understood the algorithm from study a couple years ago.

Sure enough! I remembered it fully and had a blast hacking it out in the vim editor through an ssh connection to my Ubuntu server. Here’s the code I wrote: bubble_sort.c

/*
 * Date: 2025-03-05
 * Goal: Write Bubble Sort from scratch as an exercise.
 * Pseudocode:
 *
 * For i = 1 to n
 * 	For j = 1 to n - i
 * 		if ( a[j] > a[j + 1] ) Swap(a[j], a[j + 1])
 * 	End-for
 * End-for
 */

#include <stdio.h>
#include <stdlib.h>

void bubble_sort(int arr[], int size);
void print(int arr[], int size, char *message);

int main() {
	// Initialize and print unsorted array 
	int arr[10] = { 6, 4, 2, 8, 3, 9, 1, 10, 5, 7 };
	print(arr, 10, “Unsorted Array:”);

	// Call bubble_sort on unsorted array
	bubble_sort(arr, 10);
	
	// Print sorted array
	print(arr, 10, “Sorted Array:”);
	return 0;
}

void bubble_sort(int arr[], int size) {
	for (int i = 0; i < size; i++) {
		for (int j = 0; j < size - 1 - i; j++) {
			if (arr[j] > arr[j + 1]) {
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}	
	} 
}

void print(int arr[], int size, char *message) {
	printf(“%s\n”, message);
	for (int i = 0; i < size; i++) {
		printf(“%d “, arr[i]);
	}
	printf(“\n\n”);
}

3/15/2025

TI-83+ Calculator Program

This isn’t a serious update; I was sick this weekend, and since I’m currently taking Discrete Math 2 and using my TI-83+ calculator a lot, I found myself writing a couple small programs for it. The first was an easy modulo function since it is surprisingly absent from the built-in math functions. The second was a decimal to binary conversion. It works with values that can be represented with 32 bits, signed or unsigned. I had way too much fun writing it!

A video of the program running


3/21/2025

Discrete Mathematics II - WGU

I forgot how much I enjoy writing proofs! Here's an inductive proof of the closed form of the arithmetic sequence summation:

Prove $\displaystyle\sum_{i=0}^{n-1} (a + di) = an + d(\frac{n(n-1)}{2}$, where $d \in \mathbb{Z}^+$.

Base Case: $n=1$

$\displaystyle\sum_{i=0}^{0} (a + di) = a \cdot 1 + d \cdot 0$

Inductive Step: If $\displaystyle\sum_{i=0}^{k-1} (a + di) = ak + d \cdot \frac{k(k-1)}{2}$,
then $\displaystyle\sum_{i=0}^{k} (a + di) = a(k+1) + d \cdot \frac{(k+1)k}{2}$

$$ \begin{aligned} \displaystyle\sum_{i=1}^{k} (a + di) &= a + dk + \displaystyle\sum_{i=1}^{k-1} (a + di) \newline &= a + dk + ak + d \cdot \frac{k(k-1)}{2} \newline &= a(k+1) + d[k + \frac{k(k-1)}{2}] \newline &= a(k+1) + d(\frac{k^2 - k + 2k}{2}) \newline \displaystyle\sum_{i=1}^{k} (a + di) &= a(k+1) + d(\frac{k(k+1)}{2}) \quad \blacksquare \end{aligned} $$