No Concessions
I recently deployed a web application called No Concessions that allows users to find new movies based on shared taste with other users.
The application was built with React, TypeScript, Express, Tailwind, PostgreSQL, and Docker.
Finding Focus Comic Strip
I host my comics on my art website findingfocus.art
The site is built using React, TypeScript, Tailwind, and Nginx. I have over 200 more comics still needing to be exported and added to the site.
Bitrate Calculator
Enter the duration and filesize of a video to calculate its bitrate with this web application.Python Programming
# This app generates .docx files and zips them for video deposition preparation
# Currently deployed to the web at trattel.xyz
from docxtpl import DocxTemplate
import os
import zipfile
from datetime import datetime
import shutil
OUTPUT_FOLDER = "Output"
def clear_output_folder(folder_path):
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print(f'Failed to delete {file_path}. Reason: {e}')
def perform_task(year, videographer, month_str, day, start_time, deponent, case_name, plaintiff_attorney, defense_attorney):
# Convert month to integer and validate
try:
month = int(month_str)
if month < 1 or month > 12:
raise ValueError("Month must be between 1 and 12.")
except ValueError as e:
return str(e), None
month_text = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][month - 1]
def get_day_suffix(day):
if 10 <= day <= 20:
return 'th'
last_digit = day % 10
return {1: 'st', 2: 'nd', 3: 'rd'}.get(last_digit, 'th')
try:
day = int(day)
if day < 1 or day > 31:
raise ValueError("Day must be between 1 and 31.")
except ValueError as e:
return str(e), None
day_suffix = get_day_suffix(day)
# Clear the output folder before generating new files
clear_output_folder(OUTPUT_FOLDER)
# Define file paths
date_str = f"{year}-{month:02}-{day:02}"
readon_path = f"{OUTPUT_FOLDER}/READON {deponent} {month}-{day}-{year}.docx"
videolog_path = f"{OUTPUT_FOLDER}/{deponent} {month}-{day}-{year}.docx"
zip_filename = f"{OUTPUT_FOLDER}/{date_str} {deponent} Video Worksheets.zip"
# Create Output directory if it doesn't exist
os.makedirs(os.path.dirname(readon_path), exist_ok=True)
# Create and save .docx files
try:
subject_line = f"{month}-{day}-{year} {deponent} Deposition"
doc = DocxTemplate("readonTemplate.docx")
context = {
'year': year,
'videographer': videographer,
'month': month_text,
'day': day,
'suffix': day_suffix,
'start_time': start_time,
'deponent': deponent,
'case_name': case_name,
'plaintiff_attorney': plaintiff_attorney,
'defense_attorney': defense_attorney,
'subject_line': subject_line
}
doc.render(context)
doc.save(readon_path)
# Use videologTemplate
videolog_template_path = "videologTemplate.docx"
doc = DocxTemplate(videolog_template_path)
doc.render(context)
doc.save(videolog_path)
# Create the ZIP file
with zipfile.ZipFile(zip_filename, 'w') as zipf:
zipf.write(readon_path, os.path.basename(readon_path))
zipf.write(videolog_path, os.path.basename(videolog_path))
except Exception as e:
return f"Error generating files: {e}", None
return zip_filename, None
Sonic Pi Programming
# Music for my programming streams
with_fx :reverb do
live_loop :kick do
sample :drum_heavy_kick, rate: 0.5, amp: 0.5
sleep 8
end
live_loop :hihats do
sample :drum_tom_hi_soft, rate: 1, amp: 0.3
sleep 1
end
live_loop :guitar do
sample :guit_em9, rate: 0.5, amp: 0.3
sleep 16
end
end
use_synth :hollow
with_fx :reverb, mix: 1 do
live_loop :note1 do
play choose([:E4,:B5]), attack: 6, release: 6
sleep 8
end
live_loop :note2 do
play choose([:G4,:D5]), attack: 4, release: 5
sleep 10
end
live_loop :note3 do
play choose([:A5, :Fs4]), attack: 5, release: 5
sleep 11
end
end
Artist's Prayer in C
#include
#define LINES 25
const char *Prayer[LINES];
int main()
{
printf("%s\n", Prayer[0]);
char input;
for (int i = 1; i < LINES; i++)
{
scanf("%c", &input);
if (input == 10)
{
printf("%s\n", Prayer[i]);
}
}
}
const char *Prayer[] = {
"O Great Muse",
"Gift us with your presence",
"And we shall commit to the work of showing up",
"Let us handle the quantity, and you handle the quality",
"Help us love ourselves so we can love others",
"Help us grow so we can help others grow",
"Please alert us when we are on the wrong path",
"By showing us interesting new directions to follow",
"Let us not get wrapped up in the end product, but in the process itself",
"Help us love the present and work out of it not for an imaginary future",
"But to make art for its own sake and its own beauty",
"Grant us the courage to try, and the confidence for having done so",
"Help us unite with other creators so we can encourage each other",
"If we are depressed, help us cling to what is beautiful in the moment",
"And help nudge us towards contentment even in difficult times",
"We promise to offer our work to you consistently",
"And we will listen to where our hearts tell us to go",
"We dedicate our creations to you and they do not belong to us",
"For we were only gifted the idea through the ether",
"And we are merely forging it and returning it to the universe",
"Allow us to realize we all deserve love",
"And that we are all the same divine light",
"We cannot be alone when we realize this",
"We create in honor of each other's divinity",
"Please accept our gifts as they are only made possible through your grace"
};