Hayden Shuker
Philadelphia, PA
Reading, PA
I am a sophomore mechanical engineering student at Temple University. All code here is artisanal and handcrafted. I have no analytics, trackers, cookies, javascript, SEO or ads.
Philadelphia, PA
Reading, PA
I am a sophomore mechanical engineering student at Temple University. All code here is artisanal and handcrafted. I have no analytics, trackers, cookies, javascript, SEO or ads.
What is programming like? This is me speaking from the construction of the website, its supporting tools, a bunch of little games and scripts from back to the 8th grade, and ten million stupid little Matlab exercises from engineering school.
Programming is probably the most flexible craft made by humanity. You can solve a problem in an whatever way using whatever set of abstracting tools. Any given process is easy to solve at least to a minimally functional level. That part is some tool knowledge and maybe some math chops. Any given (non-trivial) program is made of sub-processes and sub-processes and companion processes triggered between different conditions timed between each other and pointing to everything else. The hard part is the organization, comprehending all these pieces, sticking them together, keeping them inline and boiling off the redundancy until the whole thing can be a relatively cohesive unit. It feels like being the big mob boss and the little processes are your idiot goons.
If the problem becomes that big and zoomed out, the code just looks like colorful shapes. The idea as a whole is in plain english. Solving a problem for the first time means charts and documentation that get revised and replenished as the code does.
I got good at this method from engineering class. We loved complaining about this level of formality.
A lot more papers full come out of me now. Most of them these sloppy to-do lists and notes, anything to keep the structure from falling into a wash of letters and parenthesis.
Programming has a lot of craftwork and nuance, but its also the thing where principle of operation can be most separated from experience. You can’t tell how your programs work by looking at them; You don’t need to care about what a program does to work on it. They call it ‘front end’ and ‘back end’. The divorce makes two problems: programs that feel good but run like hot garbage, and programs that run good but feel like hot garbage (most web apps and most Linux apps respectively). The former is just regular consumerist wasteful abundance squandering. The later is ‘technologist brain’: the obsession with tools and mechanisms, their tight inner workings with their purity and power to the extent that when we take off our navy blue jumpsuits and zoom out— we never considered what the machine does.
The unhelpful technologist mindset is process and paraphernalia, not for some intrinsic joy, but for a quest of abstract detached quality. These are the guys who made and bought cryptocurrency, and a similar affliction takes our Linux bro friends.
The blue collar is only as good as the white collar is only as good as the system is only as good as the blue collar. Their severance is doable and hideable, but not good.
I don’t want to be a programmer because that title seems deeply incomplete and what they do seems deeply superfluous.
Not just programming, but using a computer (at least a good one like mine) can be damn peaceful. I focus on pressing the keyboard with as little force as possible, I use inputs that keep my hands still and relaxed. The screen falls out of favor. Every mechanism literally happens at subvisible scale. Perception of the machine is limited to tools of the machine. The scenes become cloudy and the imagination becomes sharp, using the computer means developing a working model for what its doing. Bug fixing is bringing that model back to reality, drafting theories and sending out probes to see this untouchable object.
This will be the first article posted with it.
Over the past three seasons, I built this website from the most minimal form. My process was very manual. This website is made of only static web pages. It is a pile of documents stored on GitHub servers and downloaded in their entirety (compare that to the built up ‘web-apps’ where every bit of content is shuffled in and out by the server). This has been very easy to make and scale. Early versions were one giant wizard scroll I would append new articles to. Since then I’ve added all the beloved front-end nuance.
My method didn’t changed though. I literally wrote each document by hand using a text editor even as I expanded to a few dozen pages. Old pages fell out of standard, and syndication got tedious (and skipped) as my archive and RSS feed took manual updating per every post.
My objective was to create a static site generator that can preserve and populate my content (prose and hypertext writing) with clean uniform code for other features (navigation bars, metadata etc.). Additionally I would automate the process of updating feeds.
I created a folder of my hand-written pages. I wrote a python script that cuts out everything between a pair of tags, usually ‘article’ or ‘main’. I approved each file processed. Of 30+ files, my code failed twice, requiring manual cleaning. One time was due to a lack of tag wrapping in the original file, the other had mismatched tags (I would use regular expressions now, more on that in ‘Educational Value’). This produced the desaturated content pages made of pure media text. In the future I will write posts directly as these desaturated files.
import os, glob
selectPath = input("path? leave blank for root.")
outputPath = 'desat/' + selectPath
path = 'handmade/' + selectPath
#for each file in directory 'path'
for filename in glob.glob(os.path.join(path, '*.html')):
with open(os.path.join(os.getcwd(), filename), 'r') as f: # open in readonly mode
#print the current file
os.system('clear')
print(f.read())
f.seek(0)
#create a word to carve out with. Only works if there is only one set of
#splitable tags
splitword = input("splitword?, or 's' for skip")
if splitword == "s":
continue
#extract everything between the split word tags
fraction = f.read().split("<" + splitword + ">\n")
fraction = fraction + fraction[1].split("</" + splitword + ">\n")
fraction.pop(1)
output=fraction[1]
os.system('clear')
print(output)
#optionally incase the new content as an article
if input("incase in article tages?") == "y":
output="<article>\n" + output + "</article>\n"
os.system('clear')
print(output)
#save to file (optional)
if input("save?") == "y":
outfile = open(outputPath + vf.name.split("/")[-1], "w")
outfile.write(output)
I wrote a reverse script that takes all the desaturated articles and appends a template header and footer. These include the functional stuff that every file needs (head, closing tags etc.). There isn’t a reason to differentiate these bummers too much between articles so I standardized them. Visually this process manifests as the new uniform nav bar and footer. Now I can change these standards for all files quickly. The header of a file includes the title (the text on the browser tab) so the saturating script extracts the first (and ideally only) h2 tag of the content and copies it into the header.
In this code there is a comment about tags messing up the code and clearing them out. That’s because I didn’t know regular expressions yet (more on that later).
import os, glob, re
selectPath = input("path? leave blank for root.")
outputPath = 'sat/' + selectPath
path = 'desat/' + selectPath
headerFile = input("headerfile? Blank for defult. ")
if headerFile == '':
headerFile = "header"
#import template files
header = open('templates/' + headerFile +'.html').read()
footer = open('templates/footer.html').read()
#for each file in directory 'path'
for filename in glob.glob(os.path.join(path, '*.html')):
with open(os.path.join(os.getcwd(), filename), 'r') as f: # open in readonly mode
#extract article title
#this curently has the problem of the depreciated 'headline' tag. Running
#this program will clear that. Then I will rebuild the program.
splitFile = re.split('<h2.*?>', f.read(), 1)
f.seek(0)
splitFile = splitFile + re.split('</h2>', splitFile[1], 1)
splitFile.pop(1)
#extract title
title = splitFile[1]
#reconstruct
output = splitFile[0] + "<h2>" + title + "</h2>" + splitFile[2]
#add header and footer templates
output = header + output + footer
#replace title placeholder with extracted title and title template
output = output.replace("<!--TITLE-->", title + ", Hayden Shuker")
os.system('clear')
print(output)
#save to file
outputPathSpecific = open(outputPath + f.name.split("/")[-1], "w")
outputPathSpecific .write(output)
A third script extracts the title of an article and appends it to the various feeds I need to maintain: blog roll, RSS, and archive. This was the last script I wrote and it is visibly more elegant then the others (I made a function).
import os, glob, re
##Inject some text in the middle of a text.
#insertText is inserted at breakText of rawText
#breakText is reinserted after if beforeToggle is
#positive otherwise inserted before
def insertText(rawText, breakText, insertText, beforeToggle):
t = rawText.split(breakText, 1)
return t[0] + insertText * beforeToggle +
breakText + insertText * (not beforeToggle) + t[1]
directory = 'desat/'
#select a page. Use a desaturated file
fileToPush = input("Select post to publish: ") + '.html'
##LOAD FILES
#extract and write title. Use a regular expression to find it burried in h2
f = open(directory + fileToPush)
title = re.search(r"<h2.*?>(?P<title>.*?)</h2>", f.read())['title']
url = 'https://www.haydenshuker.com/'+ fileToPush
f.close()
rss = 'desat/rss.xml'
rssAppendText = '\n<item>\n<title>' + title + '</title>\n '+ '<link>' + url + '</link>\n</item>\n'
rssText = insertText(open(rss).read(),'</channel>', rssAppendText, True)
print(rssText)
if input("save new rss Text? y/N") == "y":
open(rss, "w").write(rssText)
blog = 'desat/blog.html'
blogAppendText = '</heading>\n\n<article>\n<h2>' + title + '</h2>\n</article>'
blogText = insertText(open(blog).read(), '</heading>', blogAppendText, False)
print(blogText)
if input("save new blog Text? y/N") == "y":
open(blog, "w").write(blogText)
archive = 'desat/archive.html'
archiveAppendText = '\n<li><a href=\'' + fileToPush + '\'>' + title +'</a></li>'
archiveText = insertText(open(archive).read(), '<h4>2024</h4>\n<ul>', archiveAppendText, False)
print(archiveText)
if input("save new archive Text? y/N") == "y":
open(archive, "w").write(archiveText)
Now updating the site takes the use of two scripts, plus a some manual copying for the new RSS and other non-HTML files. A completed tool could cut that down to a single combined action. The text splicing code I made could be repurposed for other mass editing actions such as updating hyperlinks and fixing HTML formatting. A similar tool could process my images and other files to decrease file size.
Furthermore, I could make the updater script syndicate to proprietary social media and industrial printing press.
Accumulate wisdom and experience rather than codebase.
Permacomputing Principles
Some programming firsts for me were:
With these I could do some real fundamental IT stuff. My heart is open for more projects.
Apparently text manipulation sucks entirely if you can’t be fuzzy with it. Until I parsed how to use these all my text cuts would be at risk for error if I left in extra spacing or something. Now that I these I see them everywhere.
I like to write software like I would an essay. I outline the whole structure, imagine what thing I’m trying to create in its entirety, then the details just flow into place. For software this means comments then code. I learned this method doing the MATLAB projects in engineering class. The documentation and formality isn’t for anyone other than me while I construct the code. Though when I am done, I have chewed up every idea I’ve expressed to my greatest extent. Does documenting make me learn more? So long as it makes me make more.
As this was my first python project, I got dramatically better at writing python code as I wrote it. This created an awkward tendency to write in circles, cleaning up my output and redoing it to better standard. The mental game in such a project is sitting still and powering forward. The whole phase must be executed at once and quality may be judged afterward. Some bad code is better than no good code.
I like my styling optional or interchangeable. That means using the human readable sematic HTML components to make the content thick and signposted in the HTML rather than sloppy prose and intention dressed up with information buried in the ethereal CSS. Use the layered headings earnestly and wrap everything in articles, sections and mains.
Website footers are for fine print (technical info, organizational info, contacts etc). I know that if I need something serious and practical, that’s where convention dictates it will be.
I cleaned my room. Not an impressive activity but most aren't. I’ve got a whole month to post. Not everyday can be an excursion.
This isn’t an epic moment from a domestic perspective ether. I just took this room from fine to good. If I mopped too that could have been something.
Anyway I’ve been thinking about the room as a shrine. Literally and religiously. I drew this hex sign to ward off evil from my website.
I’m okay with other places having more evil than this room. It proves at least that I’ve done something here. Everyone’s finite power and responsibility and all. I need to find some quality charms and artifacts. No dubious ones sent again by treacherous demons. Engineers have a tendency to take soul damage. I believe this is because WD40 dissolves aether. In any case I must take proper precautions.
I have this tendency to fall into overly formal commercial habits. That's the engineer brain. For example, I keep a set of yearly journals dating back to middle school. They came with spine labels which I used as a library would with years, descriptions, and even myself written in as the author. My ugly handwriting was screaming at me. I don’t need that level of formal archival. These books grew from my body like hair. I know each one in fine temporal detail. These things were my life back in each of their times. So I removed the labels. Now the shelf is a nice series of colors like a weird washed out flag pride flag.
Today I learned how to bunny hop.
Now the world opens to me, the whole bike skill tree. I could learn to track stand and pair it with my little euro hop and get technical. I could up my power and learn the full J hop and those manuals. I could take my little hop to the trails and learn to use it for real speed for men. I love that about bikes. They are almost a basic archetypal human tool. Its a shame they didn’t get invented earlier. It pairs so well with the human body in ways we explore like the hammer or sword.
I actually did fencing for a bit. Fencing has no tricks that's the problem with the sport. You can’t flex your fencing kata. Everything you learn has to be against a guy to mean anything, and then your guy goes and does something else and your tricks are ruined. You are bound to your guy, and you are both bound to this rectangle on the ground. You put your thick sweaty white clothes back in the bag and you go home and its like nothing ever happened. Call that practicality, or versatility, transferability, flexibility, fencing has none of them. It is a small little game.
I have nothing against swords. They encompass the world, you can die by one. Grind and sharpen the blade until there is nothing left and you get ‘modern sport fencing’— a phenomenon split and excreted from the great rich asshole duels us white people used to like.
So that is my problem. When I’m teaching somebody a skill or hobby I try to stay away from ‘when you’ or ‘once you’ statements. Like “when you practice enough, you’ll be able to…” because those sorts of lines are daunting. Its like looking your entire future in the mouth. Will I stick with this skill enough to practice that thoroughly? Will I find some reason to do this? Do I want to commit to this that long? Will I live that long? Respect the cannon and the commitment, but please don’t toss me into it just yet. Just give me the moment. “Hey kid now you know algebra you can do all kinds of accounting”, not “this will come back in differential equations so you better remember it.”