404 Page not found
This is not the page you're looking for <(-_-)> .
diff --git a/404.html b/404.html new file mode 100644 index 0000000..481806b --- /dev/null +++ b/404.html @@ -0,0 +1,27 @@ +
I’m pretty pedantic about the quality of my code, and I like to keep my projects +organized and maintainable. One of the tools that I use to achieve this is +GNU Make, which is a powerful build system +that can be used to automate the process of compiling and linking C programs. In +this post, I will show you how to create a simple and robust Makefile template +that can be used in your C projects.
First, create a new file called Makefile
in the root directory of your
+project. Let’s start by defining the name of the program that we will be
+building.
# The name of the program to build.
+TARGET := example
+
The first thing we need to do is define the compiler and shell that we will be
+using. In this example, we will be using gcc
and /bin/bash
, respectively. We
+will also define the compiler flags that we will be using.
# The compiler executable.
+CC := gcc
+# The compiler flags.
+CFLAGS := -Wall -Wextra -Werror -pedantic -std=c99
+# The linker executable.
+LD := gcc
+# The linker flags.
+LDFLAGS := -Wall -Wextra -Werror -pedantic -std=c99
+# The shell executable.
+SHELL := /bin/bash
+
Next, we will define some variables that will be used for testing and debugging +our project. We will define the name of the test executable, the name of the +debug executable, and provide some flags that will be used by the memory checker +and debugger.
# The memory checker executable.
+MEMCHECK := valgrind
+# The memory checker flags.
+MEMCHECK_FLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes
+# The debugger executable.
+DEBUGGER := gdb
+# The debugger flags.
+DEBUGGER_FLAGS :=
+
+# The name of the test input file
+TEST_INPUT :=
+# The name of the test output file
+TEST_OUTPUT :=
+# The name of the reference executable
+REF_EXE :=
+# The name of the reference output file
+REF_OUTPUT :=
+
One of the cool things about make is we can set varibles to be the output of
+shell commands by using the :=
operator. This way, we can define variables
+that refer to directories related to the root directory of the project. We are
+going to work under the assumption that the project has the following directory
+structure:
.project/ # root directory of the project
+├── include/ # header files
+├── lib/ # external libraries
+├── obj/ # object files
+├── src/ # source files
+└── target/ # build artifacts
+ ├── debug/ # debug build
+ └── release/ # release build
+
To achieve this, we can define the following variables:
# top directory of project
+TOP_DIR := $(shell pwd)
+# directory to locate source files
+SRC_DIR := $(TOP_DIR)/src
+# directory to locate header files
+INC_DIR := $(TOP_DIR)/include
+# directory to locate external libraries files
+LIB_DIR := $(TOP_DIR)/lib
+# directory to locate object files
+OBJ_DIR := $(TOP_DIR)/obj
+# directory to place build artifacts
+BUILD_DIR := $(TOP_DIR)/target/release/
+
Now that we have defined all the necessary variables, we can start defining the
+targets that will be used to build our project. The first target that we will
+define is the all
target, which will build the program.
# The default target.
+.PHONY: all
+all: $(BUILD_DIR)/$(TARGET)
+
An ssh client is required to connect to remote servers. Fortunately, ssh is already installed on most Linux distributions and macOS. As of Windows 10, OpenSSH is included in Windows. To check whether you have +it installed, run the following command:
ssh -V
+
If ssh is not installed on your machine, you can install it by running the +following command:
sudo apt-get install openssh-client openssh-server
+
Once ssh is installed on your machine, you can connect to remote servers and +interface with them via the commands line. To connect to the server, use the +following command:
ssh <username>@<server_ip>
+exit # to exit the server
+
Normally, connecting to a server via ssh requires you to enter your password. +This is called password-based authentication.
However, you can set up SSH key-based authentication so that you do not have to +enter your password every time you connect to a server.
To set up SSH key-based authentication, follow the steps below.
Note Do not change the default name or location of the key. Using a +passphrase is optional but not recommended.
# If the host was previously used for ssh and the host key has changed, remove the old host key
+ssh-keygen -f "~/.ssh/known_hosts" -R "<server_ip>"
+# Generate a new ssh key
+ssh-keygen -t rsa -b 4096
+
# Ssh into the server
+ssh <username>@<server_ip>
+# Create ssh directory
+mkdir ~/.ssh
+cd ~/.ssh
+# exit server
+exit
+
scp ~/.ssh/id_rsa.pub <username>@<server_ip>:~/.ssh/authorized_keys
+
sh # Ssh into the server ssh <username>@<server_ip> # Restrict read, write, and execute permissions to the `~/.ssh` directory to only the owner (`username`) chmod 700 ~/.ssh/ # Restrict read and write permissions to the contents of the `authorized_keys` directory to only the owner (`username`) chmod 600 ~/.ssh/authorized_keys # exit server exit
After completing the steps above, you should be able to connect to the server
+without entering your password.Since SSH key-based authentication is more convenient and more secure than +password-based authentication, we will restrict the server to only use SSH +key-based authentication.
To do this, we will edit the server’s SSH configuration file. This file is
+located at /etc/ssh/sshd_config
.
Warning Password-based authentication and challenge-response +authentication will be disabled. If you do not have password-based +authentication already configured, +you will not be able to connect to the server.
To configure the server to only use SSH key-based authentication via +ssh-copy-id, follow the steps below.
# Copy the public key to the server
+ssh-copy-id -i ~/.ssh/id_rsa.pub <username>@<server_ip>
+# Ssh into the server
+ssh <username>@<server_ip>
+# exit server
+exit
+
To manually configure the server to only use SSH key-based authentication, run +the following commands:
Warning the location of the SSH configuration file is assumed to be +located at
/etc/ssh/sshd_config
. If this is not the case, you will need to +modify the commands below to reflect the location of the SSH configuration +file. You can find the location of the SSH configuration file by executing a +script I wrote found in my dotfiles’s > +/scripts
folder# make find_sshd_config executable +chmod +x find_sshd_config.sh +./find_sshd_config.sh +
# Ssh into the server
+ssh <username>@<ip>
+# /etc/ssh/sshd_config = ssh config of server
+# Disable password-based authentication
+sudo sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
+# Disable challenge-response authentication
+sudo sed -i 's/^#ChallengeResponseAuthentication yes/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config
+# Enable public key authentication on the server
+sudo sed -i 's/^#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
+# Restart the server's SSH service to apply the new configuration
+if [[ $(ps -p 1 -o comm=) == "systemd" ]]; then
+ ## On systemd-based systems
+ echo "System is systemd-based. Restarting sshd."
+ sudo systemctl restart sshd
+else
+ ## On SysV init systems
+ echo "System is SysV init-based. Restarting ssh."
+ sudo service ssh restart
+fi
+echo "SSH configuration completed. Disconnecting from server."
+# exit server
+exit # exit server
+
Storing your SSH keys and authentication tokens on the internet might seem like +a bad idea, but if they are properly secured, storing them in a public GitHub +repository can be a convenient and secure way to sync your SSH keys and +authentication tokens across multiple machines. Luckily for us, ansible-vault’s +encryption engine is based on the AES-256 cipher, which is a symmetric cipher +that is quantum resistant. This ensures that sensitive information remains +protected, even in a public repository.
To encrypt files, including your SSH keys and authentication tokens on the +internet, run the following command:
# Encrypt files using ansible-vault
+ansible-vault encrypt <path_to_file>
+
Enter an encryption key when prompted.
To decrypt files, run the following command:
# Decrypt files using ansible-vault
+ansible-vault decrypt <path_to_file>
+
Enter the encryption key when prompted.
Install tmux
sudo apt install tmux
+
Install tpm (Tmux Plugin Manager)
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
+
Reload TMUX environment so TPM is sourced:
# type this in terminal if tmux is already running
+tmux source $XDG_CONFIG_HOME/tmux/tmux.conf
+
To enter commands into tmux, you must enter a specific keybind, which is called +the prefix key, followed by the command. My prefix key is ctrl + +space.
To refresh tmux and install new plugins, type prefix + I +(capital i, as in Install)
Command Keybind | Command Description |
---|---|
prefix + c | create new window and switch to it |
prefix + # | switch to window # |
prefix + n | switch to next window |
prefix + p | switch to previous window |
prefix + : | swap window with next window |
prefix + ; | swap window with previous window |
prefix + & | kill window and all panes in it |
Command Keybind | Command Description |
---|---|
prefix + % | split a pane horizontally into two panes |
prefix + " | split a pane vertically into two panes |
prefix + { | swap pane with previous pane |
prefix + } | swap pane with next pane |
prefix + h / ← | switch to pane on the left |
prefix + j / ↓ | switch to pane below |
prefix + k / ↑ | switch to pane above |
prefix + l / → | switch to pane on the right |
prefix + q + # | switch active pane to pane # |
prefix + z | zoom in/out of pane to take up full window |
prefix + ! | break pane into a new window |
prefix + x | kill pane |
Command Keybind | Command Description |
---|---|
v | start selection in copy mode |
y | yank (copy) selection to system clipboard |
ctrl + v | toggle between rectangular and line selection mode |
prefix + r | refresh tmux configuration |
When I was a beginner at programming, I would often find myself struggling with +the implementation of for loops. The amount of times I would need to iterate +through an array, dictionary, iterable, or any given data structure would always +be one more or one less than I anticipated. As a result, I became quite familiar +with the following error message:
IndexError: list index out of range
+
I recently discovered this problem I dealt with had a name: the off-by-one +error. An off-by-one error is a +type of error that occurs when an loop is iterated one more or one less than +intended. Off-by-one errors are typically caused by a mistake in the either +initial value of the loop variable or in the end condition of the loop. +Mathematically this can be represented by
$$ +n \pm 1 +$$
There two types of off-by-one errors: undershooting and overshooting. +Undershooting occurs when the loop iterates one less time than intended, while +overshooting occurs when the loop iterates one more time than intended. Let’s +look at an example of each case, where $n$ represents the amount of times we +intend to loop and $i$ represents the current iteration:
// Case Study A
+for (int i = 1; i < n; i++) {
+ /* Body of the loop */
+}
+
Case A is an example of undershooting, and it will be executed $(n - 1)$ times. +In Case A, $i$ is defined to be one more than intended, which can be proven with +experimentation. For example, if $n$ was defined to be $10$ (and each value of +$i$ was printed), then the following numbers would be the resulting output:
$$1, 2, 3, 4, 5, 6, 7, 8, 9$$
This is because, at that point where $i$ becomes $10$, the conditional statement +$i < n$ becomes false and the loop subsequently terminates one iteration less +than intended. This scenario can be fixed by changing the initial value of $i$ +to be $0$ instead of $1$. A good example of overshooting is with the following +brain teaser:
// Case Study B
+for (int i = 0; i <= n; i++) {
+ /* Body of the loop */
+}
+
Case B is an example of overshooting, amd it will be executed $(n + 1)$ times. +In Case B, $i$ is defined to be one less than intended, which can also be proven +with experimentation. Following our previous thought experiment, the following +would be the resulting output:
$$0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \text{error}$$
This is because, at that point where $i$ becomes $10$, the conditional statement +$i \leq n$ still remains true, resulting in the loop iterating one more than +intended. This scenario can be fixed by changing the initial value of $i$ to be +$1$ instead of $0$. A good example of overshooting is with the following brain +teaser:
Note that a for loop is simply a special case of a while loop where the number +of iterations to be done is already known, whereas a while loop has an +indefinite number of iterations. This means that an off-by-one error can occur +in while loops, although it is less common, as while loop definitions are based +around the output of logical expressions, whereas for loop definitions are based +around the repetition of an iterable object. One of the correct ways to write +the loop is:
for (int i = 0; i < n; i++) {
+ /* Body of the loop */
+}
+
If you found this post interesting, I would recommend the following as further +reading to learn more about off-by-one errors:
We choose to go to the Moon. We choose to go to the Moon in this decade and do +the other things, not because they are easy, but because they are hard; +because that goal will serve to organize and measure the best of our energies +and skills, because that challenge is one that we are willing to accept, one +we are unwilling to postpone… And, therefore, as we set sail we ask God’s +blessing on the most hazardous and dangerous and greatest adventure on which +man has ever embarked.
— John F. Kennedy1
This page was last edited on August 14, 2023
The impossible list traces its origins to its creator, +Joel Runyon. It’s essentially an +aspirational catalog of personal challenges, goals, and experiences that push +the boundaries of what an individual believes they can achieve.
The impossible list is not a bucket list, but very is similar to one. The bucket +list has this stigma attached to it which is that if the creator of it does not +complete it, they have “failed” themselves. I would not like to self impose this +pressure onto myself, but have a dynamic long-term roadmap for myself, that +changes and evolves along with me.
I will attempt to update this list regularly, in the case where I complete +something or have something to add, with the later being most likely.
If you are someone who can help me make one of these a reality, please get in +touch with me. I would love to hear from you.
The above quote is excerpted from former President John F. Kennedy’s +Address at Rice University on the Nation’s Space Effort, +on September 12, 1962 ↩︎
This is an archive of my journey to explore and conquer the inner workings of +computers, from the subatomic particles in transistors to the cool stuff we do +with processors, operating systems, and web browsers. Occasionaly, I’ll also +give my two cents on philosophy. All opinions are my own.
This article offers a sample of basic Markdown syntax that can be used in Hugo +content files, also it shows whether basic HTML elements are decorated with CSS +in a Hugo theme.
The following HTML <h1>
—<h6>
elements represent six levels of section
+headings. <h1>
is the highest section level while <h6>
is the lowest.
Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, +voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma +dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as +cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin +porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? +Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit +ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda +veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore +eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata +tiustia prat.
Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne +sapicia is sinveli squiatum, core et que aut hariosam ex eat.
The blockquote element represents content that is quoted from another source,
+optionally with a citation which must be within a footer
or cite
element,
+and optionally with in-line changes such as annotations and abbreviations.
Tiam, ad mint andaepu dandae nostion secatur sequo quae. Note that you can +use Markdown syntax within a blockquote.
Don’t communicate by sharing memory, share memory by communicating.
— +Rob Pike1
Tables aren’t part of the core Markdown spec, but Hugo supports supports them +out-of-the-box.
Name | Age |
---|---|
Bob | 27 |
Alice | 23 |
Italics | Bold | Code |
---|---|---|
italics | bold | code |
<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>Example HTML5 Document</title>
+ </head>
+ <body>
+ <p>Test</p>
+ </body>
+</html>
+
<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Example HTML5 Document</title>
+</head>
+<body>
+ <p>Test</p>
+</body>
+</html>
+
<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Example HTML5 Document</title>
+</head>
+<body>
+ <p>Test</p>
+</body>
+</html>
GIF is a bitmap image format.
H2O
Xn + Yn = Zn
Press CTRL+ALT+Delete to end the +session.
Most salamanders are nocturnal, and hunt for insects, worms, and +other small creatures.
When I was a beginner at programming, I would often find myself struggling with +the implementation of for loops. The amount of times I would need to iterate +through an array, dictionary, iterable, or any given data structure would always +be one more or one less than I anticipated. As a result, I became quite familiar +with the following error message:
IndexError: list index out of range
+
I recently discovered this problem I dealt with had a name: the off-by-one +error. An off-by-one error is a +type of error that occurs when an loop is iterated one more or one less than +intended. Off-by-one errors are typically caused by a mistake in the either +initial value of the loop variable or in the end condition of the loop. +Mathematically this can be represented by
$$ +n \pm 1 +$$
There two types of off-by-one errors: undershooting and overshooting. +Undershooting occurs when the loop iterates one less time than intended, while +overshooting occurs when the loop iterates one more time than intended. Let’s +look at an example of each case, where $n$ represents the amount of times we +intend to loop and $i$ represents the current iteration:
// Case Study A
+for (int i = 1; i < n; i++) {
+ /* Body of the loop */
+}
+
Case A is an example of undershooting, and it will be executed $(n - 1)$ times. +In Case A, $i$ is defined to be one more than intended, which can be proven with +experimentation. For example, if $n$ was defined to be $10$ (and each value of +$i$ was printed), then the following numbers would be the resulting output:
$$1, 2, 3, 4, 5, 6, 7, 8, 9$$
This is because, at that point where $i$ becomes $10$, the conditional statement +$i < n$ becomes false and the loop subsequently terminates one iteration less +than intended. This scenario can be fixed by changing the initial value of $i$ +to be $0$ instead of $1$. A good example of overshooting is with the following +brain teaser:
// Case Study B
+for (int i = 0; i <= n; i++) {
+ /* Body of the loop */
+}
+
Case B is an example of overshooting, amd it will be executed $(n + 1)$ times. +In Case B, $i$ is defined to be one less than intended, which can also be proven +with experimentation. Following our previous thought experiment, the following +would be the resulting output:
$$0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \text{error}$$
This is because, at that point where $i$ becomes $10$, the conditional statement +$i \leq n$ still remains true, resulting in the loop iterating one more than +intended. This scenario can be fixed by changing the initial value of $i$ to be +$1$ instead of $0$. A good example of overshooting is with the following brain +teaser:
Note that a for loop is simply a special case of a while loop where the number +of iterations to be done is already known, whereas a while loop has an +indefinite number of iterations. This means that an off-by-one error can occur +in while loops, although it is less common, as while loop definitions are based +around the output of logical expressions, whereas for loop definitions are based +around the repetition of an iterable object. One of the correct ways to write +the loop is:
for (int i = 0; i < n; i++) {
+ /* Body of the loop */
+}
+
If you found this post interesting, I would recommend the following as further +reading to learn more about off-by-one errors:
One of the things I value the most when it comes to when it comes to writing +software I publish is its maintainability, from the obscure and simple bash +scripts to the large and complex programing pillars packed with passion that are +placed in my programming portfolio.
For most people, this is limited to writing consise comments in the codebases +with the hope that they work once and never need to be touched again. This +approach
falls flat
the big picture, as in what
modules do on their own and what are the consequences of its execution with +respect to the entire codebase
most important aspects of any software project is its documentation.
.
+├── .github/
+│ └── workflows/
+│ └── sphinx-pipeline.yml
+├── source/
+│ ├── _static/
+│ │ ├── css/
+│ │ ├── favicons/
+│ │ ├── img/
+│ │ └── pdf/
+│ ├── conf.py
+│ └── index.rst
+├── .gitignore
+├── Make.bat
+├── Makefile
+└── requirements.txt
+
name: CI/CD Pipeline for Sphinx
+# Controls when the workflow will run
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+ workflow_dispatch:
+
+# The sequence of runs in this workflow:
+jobs:
+ deploy:
+ name: Build and Deploy Documentation
+ runs-on: ubuntu-latest
+ steps:
+ - run: lsb_release -a
+ - run: uname -a
+ - name: Check out Repository Code
+ uses: actions/checkout@v4
+ - name: Setup Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: "3.10"
+
+ # pip caching
+ - name: Locate pip's cache
+ id: pip-cache
+ run: echo "::set-output name=dir::$(pip cache dir)"
+
+ - name: Cache dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.pip-cache.outputs.dir }}
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+ restore-keys: |
+ ${{ runner.os }}-pip-
+
+ # Install runtime dependencies
+ - name: Upgrade pip
+ run: pip install --upgrade pip
+ - name: Install dependencies
+ run: pip install -r requirements.txt
+
+ # Build sphinx source files
+ - name: Build sphinx files
+ run: make html
+
+ # Publish build files
+ - name: Deploy to GitHub Pages
+ uses: peaceiris/actions-gh-pages@v3
+ if: github.ref == 'refs/heads/main'
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./build/html
+
+ # Upload for introspection, useful for pull requests and debugging
+ - uses: actions/upload-artifact@v3
+ with:
+ name: generated-site
+ path: public/
+
# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Sphinx documentation
+build/
+
+# Environments
+.env
+.venv
+
# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+github:
+ @make html
+ @cp -a build/html/. ./docs
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ # Maintain dependencies for GitHub Actions
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+
+ # Maintain dependencies for pipenv
+ - package-ecosystem: "pip" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "daily"
+
Getting closer to how your environment actualy works will only expand your +mind
— Michael B. Paulson, otherwise known as +ThePrimeagen
This page was last edited on March 29, 2024
My former college roomate and good friend, +Hayden Buscher, recently made a +post about the things he +uses to stay productive. Giving credit where its due, I thought it was a great +idea, so I decided to give my own spin on it.
This list is the fruits of my due diligence and research into finding the right +tools for my use cases. I hope it helps you find the right tools for you.
The laptop I use is a is a Gigabyte AERO 16 OLED creator laptop, which features +a Intel 12th Gen i7 Processor, and a NVIDIA GeForce RTX 3070 Ti Graphics Card. I +love the anodized alumnium finish on the chasis, its sturdy, aesthetically +pleasing, and easy to clean. The OLED screen is gorgeous, I have become spolied +by such beautiful screens and stuggle looking at normal High Definition LED +screens. People passing by or in class will look at my screen and compliment it +(that’s how you know its good, who in their right mind would do that). As with +all OLED screens, scren burn is a real and legitmate concern I struggle with at +times, but it is a skill issue I have solved by autohiding my dock and with +screen savers, and in dire situations this +video. The keyboard is a joy to type on, and the trackpad is smooth and +responsive, but both get dirty quickly. The dongle provided by Gigabyte was +filmsy, and cheaply made, so I replaced it with a USB-C hub from Amazon. The +battery lasts about 3-4 hours on a full charge, which is fine for my use cases, +but I wish it lasted longer. I’ve had this laptop for about a year now, and I’m +very happy with it and would recommend it to anyone looking for a new laptop.
My phone isn’t anything special, so I’m not going to talk about it. I use a iPad +of the 10.2" variety (9th generation). I use it for reading and taking notes in +class. Honestly, this felt like a missing piece of my workflow, and I’m glad I +got it. With a paper-type screen protector, I get the feel of writing on paper, +the clarity and beauty of a digital screen, and the syncing and backup of the +cloud on a screen the size of a notebook. I use a knockoff Apple Pencil, and it +works fine. For note taking, I use the app +Goodnotes with the lifetime subcription.
Wow, what an easy and not at all controversial topic to answer… Welp, here we +go. I technically dual boot Windows 11 (ew) and +Ubuntu 22.04.2 LTS, also known as Jammy +Jellyfish, but so much of my time is spent on Ubuntu that I’m just going to talk +about that. My only gripes with it are the graphics drivers for my Nvidia GPU, +but this is resolved by the proprietary drivers from Nvidia provided by Ubuntu.
I’ve come to notice that when it comes to the tools I use (especially when it +comes to software), usage time and maintainance/stability are inversely +proportional to the customizability the tool provides. The more customization is +provided in software, the more time is spent configuring and mataining it, and +in worst-case scenarios, the more unstable it becomes. Because of this, less +time is spend actually using it.
My operating system is a tool, and as all good tools should, the distro I use +should be one that leverages this relationship, so I can manage how the software +is used, and not how it works. This is why I am probably not ever going to be an +Arch Linux user. Its very impressive how quickly Arch Linux packages maintainers +innovate and release changes, and pacman is a great package manager, but I do +not have the time nor the patience to maintain my broken system when I forget to +update after a week.
On the other end of the spectrum, Ubuntu works out of the box, but its quite +bloated with software I will never use or need. I used to be a bit of a distro +hopper, but like an old pair of jeans, I always come back to Ubuntu for its ease +of use and stability. For the most part, it just works.
One distro that has caught my eye and I’ve been meaning to try is Debian, +specifically Debian 12 (Bookworm) . Its +seems to hit the sweet spot of stability and customizability between Arch and +Ubuntu, and I’ve heard great things about from Hayden and +Noah Oveson.
I’m not a fan of the default GNOME desktop environment, I’m a tiling window +enjoyer. I like to have full control over my windows, so I use the +i3 window manager. However, I plan on switching to dwm in +the future, as I’ve heard it is more stable and faster than i3.
I cannot stress how elgalant and beautiful the font +MonoLisa is. I use it for everything, from my code +editor to my terminal. MonoLisa definately lives up to its branding of “font +follows function”. Being a monospaced font, each of the characters are the same +width and its ligatures, which is the combination of two or more characters into +a single character, provide a great reading experience and look cool. I patch +MonoLisa into a Nerd Font by using this custom +patching script. I +highly recommend it.
Pied Piper is a multi-platform technology based on a proprietary universal compression algorithm that has consistently fielded high Weisman Scores™ that are not merely competitive, but approach the theoretical limit of lossless compression.
4.0
Global movement of free coding clubs for young people.
There is no spoon.
Innovative middle-out compression algorithm that changes the way we store data.
Web Development (Master)
HTML, CSS, Javascript
Compression (Master)
Mpeg, MP4, GIF
It is my pleasure to recommend Richard, his performance working as a consultant for Main St. Company proved that he will be a valuable addition to any company.
— Erlich Bachman
GoogleMaps, Chrome Extension, Javascript
I’m an engineer & entrepreneur focusing on applied robotics & embedded systems. +I’m also currently researching Large Language Models and building AI projects in +stealth. I also write occasionally about +philosophy and computers.
I’m a sophomore at Cal Poly studying Computer +Engineering. I am currently writing drivers and firmware for electric vehicles +at Cal Poly Racing. Here are some of the +projects I’ve work on at Cal Poly.
This past summer, I worked at DeepWater Exploration to ship +some streaming software, which outperformed +OBS, and drivers and firmware for their products which are used in various +applications spanning across academia, enterprise, and defense.
This upcoming summer I will be working at NVIDIA, +working on their internal platform used for end-to-end testing of their +products, from the modular down to the transistor level.
See more on my resume or contact me at +mavillaf@calpoly.edu.