Falling Into Place

September 22, 2024

Happy first day of fall. We're about 3 weeks into classes so things are starting to ramp up, plus I've been on a bit of a fermenting spree since finishing the hot sauce (which turned out great by the way. Especially the fig/blackberry/habanero, it has a great funky smoke flavor that I wasn't really expecting). Last week I finished up some red cabbage sauerkraut, carrots and bell peppers. I'm going to do a large batch of sauerkraut next because I finished both jars on the day they were done. It's been a fun little experiment and I'm going to branch into some crazier things after this round. I've heard great things about lactofermented strawberries.

But this is supposed to be a technical blog, so I'll get technical for a minute. I'm sorry about flexicon - I really do plan to have it up soon but I've been loving my classes this semester and got a job on campus doing IT and some web design so there isn't a lot of time to play around with containerization/deployment, even though it shouldn't take too long to set up on the (free, nice!) NYU linux servers. Also I'm taking the Goethe C1 this Friday so I've been reading and watching German as much as possible. My cybersecurity and cryptography class in particular has been lots of fun. I'm not sure I've been this excited about a CS class since algorithms so it's refreshing after a rather dragging combination of operating systems and linear algebra last semester (not that I don't like linear algebra, I just barely wrote any code. And that never feels good). Beside the lectures I've been following along with a graduate textbook to read some of the great proofs that go along with cryptography. It scratches that itch for discrete math but feels like a game the whole time. I think if software engineering doesn't work out I see a future for myself doing a master's in cybersecurity in Germany, but that's a long way away.

My other CS class this semester is applied internet technologies, which is a winded way of saying fullstack JS development. It's alright so far - lots of Javascript (if you know me, you know how I feel about that) - but it's exposure to web protocols and practices which is nice experience. With these I'm taking a German seminar on Hannah Arendt's political philosophy. I'd like to write a whole post about that eventually, especially how her approach holds up to modern foreign policy sentiment. It's always fun to drag old essays 80-some years into the future and I think you'd be hard-pressed to find a better candidate than Arendt right now.

In other news: I finished Berlin Alexanderplatz. Not my favorite, I'll get into it another time. I'm loving Ulysses, the chapter on the rocks (Nausicaa?) is probably the best prose I've ever read and maybe even the best I will ever read. I've also been working through Hegel's Phenomenology and On Food and Cooking during my anthropology lectures. I'll be starting Die Ringe des Saturn by Sebald (who would have guessed?) once I get it later today. My two 45-minute subway trips per day have basically tripled my reading intake, which I'm happy about. I've averaged something like 20,000 steps a day this month too. And I joined the bridge (like, the card game) club? Life is busy but good. Until next time.

    Tags:
  • #german
  • #general
  • #food
  • #reading
  • #javascript

A Jarring Transition

August 24, 2024

Long time, no see. It's been hectic, but I'm settled into my apartment in Brooklyn now and should be able to start again with regular posts. I'm going to skip talking about flexicon (which I promise I've been working on) because I expect to have it up and running by the end of the month and figure I should just save my efforts for one large post that covers everything I did and learned over the course of the project.

I thought instead I'd share a little about my latest culinary project, fermented hot sauce. I had a Whole Foods gift card sitting around and was inspired, so I figured I'd give it a shot. I could have just made the mash, sealed the jars and burped them occasionally but that wouldn't have been over-engineered enough for me. Instead, I decided to make a homemade airlock rig out of cheap hardware store supplies. The premise isn't super complicated; you need a way for excess CO2 to escape (created by the lactofermentation cycle, could cause the jars to explode if not handled properly) without letting oxygen in (causes mold, yeast, etc.). The solution is a one-way airlock, which you can buy for about 2 dollars a piece on Amazon. But I'm not a big fan of shipping in the city and I figured I'd have more fun my way, so I came up with this idea diagrammed beautifully in MS Paint:

A diagram of my fermenting rig

The plastic bag with water acts as a weight to keep the mash under the liquid's surface, maintaining the anaerobic environment that the good bacteria need. Here's what my final rig looked like and a closeup of one of the jars:

My fermenting rig My fermenting rig

From the diagram, the middle two jars are the water locks and the unlabeled jars are empty - I just didn't know where to put them. I paid less than 25 bucks for all the materials including the jars and they'll be very easy to reuse, so it's not a terrible deal. The different batch flavors I've gone with are habenero/fig/blackberry, roasted fresno (I'll mix in some garlic oil at the end), and serrano/ginger/lemon, two of each. This is my first time fermenting so we'll see how it turns out - I'd like to do sauerkraut or rotkohl next if all goes well.

That's it for now. Hopefully I'll have flexicon up and running soon. And I promise to post more now that I'm all moved in. Until then!

    Tags:
  • #general
  • #food

Docked and Loaded

July 30, 2024

It's been a busy few weeks. I'm working right now on the production version of my app flexicon (like, flexible lexicon. Clever?), which has definitely been a trip getting started. So far I've generated a partial but production-worthy dataset from Wikipedia dumps. At time of writing it's 370-something-thousand words and about 27 million word connections (~15 million unique). A fun little thing I implemented was a hashing scheme to create integer keys from a word to speed up searching dramatically. I wanted to stay within Postgres's 8-byte bigint type and also have easy, fast, and platform-independent access to the hashing algorithm. Cryptographic or not was irrelevant, I wasn't hiding any information. I couldn't find anything 64-bit and worthwhile so I played around a bit and discovered that a truncation of 16-byte md5 has zero collisions in the English dictionary I used for the wordlist, and comes prepackaged in Postgres, Python, and Java. I just needed to make sure that my Python or Java byte-to-int translations are signed and big-endian (Postgres default, much easier to convert outside of the convoluted plpgsql) and I'm good to go with lightning-fast word but also relationship searches. The composite two-bigint key does much better than searching for two text columns and was also a fun little dive into cryptography that I didn't expect for this project.

Since then I've worked on my Spring Boot REST API and set up Docker compose schemes for that and the database. Docker feels sort of magic, honestly. I'm excited to see how it fares with deploying since that seems to be the main benefit from what I've read. But it's a nice and mostly intuitive environment for development, maybe not as elegant on Windows but not bad enough to complain about. I do wish there were better documentation though. I'm really doing my best to keep everything tight, clean, and professional, because I hope to scale it a bit past just the word generator and Anki deck creator - maybe add logins to save user flashcard sets or something.

I'm moving back to New York sometime in the next few weeks, so posts might be sparse as things get more hectic. And, more generally, job hunting season starts soon, so expect occasional updates on that.

    Tags:
  • #programming
  • #general
  • #flexicon
  • #python
  • #java

Spring Boot Camp

July 18, 2024

I've been prototyping my next project. The working idea is a generator for word groups where "nets" are created based on user-provided word frequency and correlation strength constraints. It'll help advanced language learners to build subject vocabulary that isn't so direct. So far, it's a PostgreSQL database that I feed with a Python script, a Spring Boot application with a REST API and a React.js page to make use of it all. The Postgres database is filled with words and their relationships from several articles; right now it's based on proximity, where every word within a 5 word radius is considered a "connection," then the strength of the connection is calculated according to the frequency of the word and the number of connections between each pair of words. After just a few Wikipedia articles it's pretty accurate - "species" matches with "animal", "golf" with "ball", etc.

I've never worked with Postgres (or SQL for that matter), so the first SELECT queries I wrote were somewhere in the ballpark of 3s execution time. Not impressive for 40-something-thousand rows, but after some tweaking and a lot of doc research (I got sidetracked with the inner mechanics of compound keys) I realized I'd been summing up the count of the words for each row, which was very obviously not fast. I managed to bring it down to a tenth of a second, which is much better. I also brought down the write time of my Python (psycopg2 is wonderful, by the way) script from an initial 6 minutes to about 15 seconds by using views to fetch data instead of calculating the strength at insert time. I think for the final product I might even do away with the update model I have and instead insert every connection individually, then just count the number of times each appears. I'll be doing some speed tests on both models at some point, but for now I'm satisfied. It doesn't matter much because Spring's JPA library loads the database fully at startup anyways, and any inserts to my database happen behind-the-scenes - but man, it feels good to see the execution time go down on a query.

I'm very happy with Spring Boot as well. The annotations are a lot, but they're mostly intuitive and I appreciate that Spring does my dependency injection and my IDE does all my imports. I find Java to be a relaxing environment because it's so strict and there's never a question of where things went wrong. React, on the other hand, feels like a complete dice roll every refresh. I'm a JS hater (so unique, I know), so it's extra painful, but I'll slog through the dozen or so components I need to add, then be more thorough for the final product. After that, I'll be working with Docker to containerize the prototype, but likely not deploying until I've finished with React, rebuilt everything, included unit tests (being away from Java for so long has me homesick for JUnit), and finalized the read-only database. I'm undecided between trying to host over the AWS free tier or my CS department's free linux server, but that comes after all the things I just mentioned. I've also not forgotten about Anki integration - that will come, but I'd like to get the rest off the ground first.

On the life side, I'm hunting for apartments (spending hours on Excel gimmicks) and planning a tasting menu for 8 or so people this weekend. I'll be posting pictures. Also, Sebald's Austerlitz just got eighth place on NYT's "100 Best Books of the Century" list, which is super cool as both my favorite book and more generally as representation for contemporary German literature. If you haven't read it, I can't recommend it enough - and I've heard great things about the English version.

    Tags:
  • #programming
  • #flexicon
  • #german
  • #general
  • #reading
  • #javascript
  • #python
  • #java

Patcher and the Py(Test)

July 9, 2024

A big week for dictionfairy - yesterday, I released patch 0.2.0, which has some minor bug fixes and a couple of nice new features. It's now possible to edit hotkeys in the settings menu, which is a big step as far as features go, and there's a new edit-in-place capability that is helpful when the selected word doesn't copy completely right. Neither of them are particularly complicated. I've not published it yet, but I also worked with the GNU gettext module to add support for German. I hope to add French soon (my French sucks) and maybe Spanish if I can steal a Spanish-speaking friend for an hour or so. I'm also going to be adding more built-in dictionaries (most likely en->en, fr->fr, maybe en->fr and en->de or es?), sprucing up the GUI with some stylesheets, and adding a generic dictionary tool that should be a major highlight. I picture it as an interface where the user gives a web link and Selenium selection scheme (making it intuitive will be the hard part), then maybe some rules for cleaning up the response. I'll save this and add it into the list of acceptable dictionaries in settings. I'm also working on some unit tests with PyTest, but I'm a bit stuck on testing Selenium and the Keyboard module. I'm not really sure how to even start considering they depend on either user interaction or an instance of a GUI, so I'll be working on that on the side as well.

I've also been doing preliminary research for my next project. I'm hoping to build a full-scale webapp with a stack of SpringBoot, React, AWS(?), and Postgres just to get my feet wet in some (German) industry standard technologies. Probably the best idea I've had so far is an Anki deck builder or vocab practice site designed for advanced language learners that'll skim Wikipedia or a dictionary and load out a database with words and their associations, then create a themed deck with a certain amount of randomness and obscurity. The major problem that this addresses is the lack of vocabulary content for C1+ (I'm taking the Goethe in September). The traditional wisdom is that after B2 you can only study the dictionary. I think it would be nice to have a site to just get concentrated but random words thrown at you, because that sort of thing only really happens in real-world German conversations, which is hard to find in my hometown. I've still not completely decided whether I should start with an Anki deck generator or an interface to practice vocabulary, but I hope to integrate both eventually. Again, I have no idea how to use any of the component parts and I haven't started building, but that's my plan for the rest of summer along with maintaining dictionfairy.

    Tags:
  • #programming
  • #general
  • #dictionfairy

Lake Week Book Report

July 7, 2024

Back from the lake. I finished up Anna Karenina and Herrndorf, then immediately dove into rereading Wildente and first-timing Rosmersholm. Wildente is the classic Ibsen case study for a reason, but it's never really resonated with me. It's maybe the Casablanca effect where the entire time you're watching you're thinking, man, this is just full of clichés, until you remember that everyone else is copying Casablanca - but the clichés are character archetypes, and instead of everyone else, it's Ibsen in the rest of his plays. I was blown away by Rosmersholm, though, and couldn't help but read Rosmer and Beata into still-fresh Wronski/Anna archetypes. I think it might even have a shot at taking down the reigning favorite (Gespenster!) on a second readthrough. I haven't done any Ibsen studies for a while, so I plan to get back to that in the near future.

Another great read from this week was J.D. Salinger's A Perfect Day for Bananafish, which, wow, is a great case study for pulling you into a story with just a few pages. Raw and captivating writing to its core. I picked it up at its mention in Herrndorf. I'm not going to make any claims or analyses because it feels grossly inappropriate, but I'm thankful that I was made aware of it. Rüther never forces an interpretation of Herrndorf's story or Herrndorf's connection to the works he studied, which I think is probably the greatest biographical imperative - that's likely why the final product comes out so refreshing and pure.

Looking forward, I'm starting Ulysses and Sebald's Die Ausgewanderten. I'm reading Ulysses with the Gilbert companion, so I see it as more of a study, and the Sebald stories more as reading for pleasure. I'd forgotten how much I liked Sebald's prose - he's got such a fantastic rhythm to just every sentence he writes. I hope to go back through Austerlitz soon for the style alone. But Joyce first, of course.

    Tags:
  • #german
  • #general
  • #reading

Beach Week R and D

June 30, 2024

Back from the beach. You may have noticed some changes around here - I spent a frankly embarrassing amount of time thinking about the site. I don't know if I've been this invested in a personal project since high school, so it's refreshing to have a bit of drive back as far as that goes. I really am starting to love this stuff, which I never thought I'd say. I always saw myself as the gruff, no-fun backend type.

The first thing I did was look for examples of personal sites that I felt like had the pull that mine didn't. Of course when you search it up you get a bunch of ridiculous three.js projects, but in between the showboating I found Martine Myrup's site, which I was completely blown away by. To be fair, she's on the complete opposite end of the design spectrum from a developer, but I just couldn't get over how much I liked the way all her pieces fit together. The little bouncing aardvark(?) on the right and fullscreen-fit title are stupidly compelling for how simple they are. I'm pretty sure it's the layered-ness of it all. And as gimmicky as the hover-to-show images are, I appreciate that it's still pretty clear what's happening on my screen and it doesn't touch the layout. Anyways, I wanted to try and imitate the title (without the layers, which I would have loved to attempt but couldn't find anything that fit the look) and the effectiveness of the landing screen.

So there's the new homepage, but also a new nav bar. It scales much better to screen size and has some neat little socials links that cover up some of the gaping whitespace that was there before. The blog also takes url query strings for preset tags now, so the links leading out of project pages will already have the relevant tags applied. Also, I got rid of the photos page and changed it to just food. Honestly, I was sort of insecure about the weird photo viewers even though they were fun to experiment with. I opted for a horizontal scrolling page that I think looks alright but I'll clean up once I've had some time to sit with it. I went back and forth a lot but eventually found this site which convinced me that horizontal scrolling can be done tastefully. I'd like to also put a more effective landing page on that tab, but that's a project for another time. My first priority going forward will be updating the contacts page to something more effective, maybe even adding a contact form?

    Tags:
  • #programming
  • #general
  • #isaac-fisher.com
  • #css

v0.1.0 and the Virus Issue

June 21, 2024

The last few days have gone exclusively to Dictionfairy. There's a lot more new technology involved there than I expected. I've worked with PyQt6 (mostly templates and lots of prayer) and Selenium before, so I figured I'd be breezing through development. But wow, have there been a lot of things that have just halted the process completely. I've also been experimenting with Figma for app designs. I really am new to the whole thing so it's been a lot of fun to play around with some ideas. This is how it stands now. I don't love any of the new ideas yet so I haven't gone through with the settings pages, but I thought I'd show this just for the fun of looking back on it later. Keep in mind that the default size for the app is 200x300 pixels, so I barely have any space to work with before it becomes completely unreadable.

That's the fun part of the report for Dictionfairy. The not-so-fun part is about PyInstaller (oh my god, oh my god) and some other exciting issues w/r/t keyboard's threading. I released the first alpha version of Dictionfairy through GitHub today. But PyInstaller, apparently, is prone to flagging Windows Defender as malware, which is not something I want on my name when the unsuspecting language enthusiast tries out my program. The bootloader gets recognized from other programs compiled through PyInstaller that may have done some not-so-good things. My workaround was grabbing an older (<6.0.0) version of PyInstaller, then manually recompiling the bootloader through VSCode's C++ compiler, then pip installing the local version of the library. After that it only got flagged on 3/75 malware detectors and ran on my machine, which is much better than 15/75 and a complete block without an exclusion. So anyways, I don't imagine I'll be doing desktop app development through Python probably ever again. This whole mess is making me look rather fondly on web development, so that's an exciting thing to explore after I wrap the pre-release phase of Dictionfairy up.

The threading issue was a fun one because it was a nice nod to some of the techniques from my operating systems class this past semester. Although, to be honest, I didn't really fix the problem in a way that was best-practice for threads. But it works, so I'll take it. The issue is that the callback on Keyboard's add_hotkey() executes in a new thread, and I use a ctrl+c hotkey to copy to the clipboard when the hotkey is triggered. Even though the hotkey is supposed to suppress all other uses of its keys, it was registering the shift modifier from my keybind (because it triggers on release, this is after I left go of the non-modifier key) while simultaneously calling ctrl+c, and switching to the Windows International Keyboard. I played with some threading tricks for a bit and ultimately ended up just releasing every key once the hotkey is registered, which isn't anything elegant but certainly works.

If you'd like to test it out, you can download the .exe from my GitHub, but I wouldn't blame you if the malware warning turns you away. The source code is probably the better option anyways. Apparently you can contact the antivirus developers to have your program whitelisted, so I'll look at that for the future. I'm going away for two weeks though, so it will have to be after that. Because Dictionfairy only works on Windows right now, I'll likely just be doing a blog post here and there on some readings. I've got some good Ibsen content lined up and I'll be starting Ulysses once I get through Herrndorf, so you have that to look forward to.

    Tags:
  • #programming
  • #general
  • #dictionfairy
  • #python

JavaScript and the Plateau

June 18, 2024

There's a moment of realization in every project where you put it down for once, look at what you've done and what you have to do and come up empty. Two days ago I started with JavaScript, in which I have little experience - especially not in a web design context. I fiddled with some ideas: a cutesy spellcheck-mimic for my name on the homepage, fade-ins with scrolling elements, a dozen different slider formats for the photos subpages. The spellcheck was thankfully thrown out early, the slider eventually settled on.

I also put a tags system on the blog that I'm pretty proud of. It's the first JavaScript functionality that I've added that I can say I wrote 100% of. It's a pretty simple concept - compare a set of active tags to the tags of each post, and get rid of the posts that don't match. I was shocked at how similar some of the syntax is to Python. The .forEach() method stuck out to me as especially Pythonic, and I ended up with this beast of a line to fill out a Map object with each post and its tags that looks something like Google Translate tried translating Python into JavaScript: postTags.set(post.id, [...document. querySelectorAll("#" + post.id + " .tags li")].map(x => x.innerHTML)). Oh yeah, and how weird is that => operator anyways? No idea how you JS people do it. Anyways, check it out on the right. It's probably the last major feature I'll add for a while, which brings me to my final topic:

I've plateaued. I'm at a loss for ideas. I've got some administrative stuff to do, writing docs for a couple of projects and the like. But I've reached the limit of my own raw creativity. The plan: research and development. I'm going to take a week or two, look over some examples, mark down the things I like. Maybe even go through some UX/UI courses. I'm announcing this so that it's no surprise when I don't touch the site for a moment. You'll probably see a post or two related to some German readings or Dictionfairy, maybe a couple of minor changes to font sizes or borders or whatever. Know that I've not abandoned you, my loyal readers. I'll be back and inspired eventually, I promise.

    Tags:
  • #isaac-fisher.com
  • #programming
  • #javascript
  • #general
  • #python

The State of Things

June 14, 2024

It's done! The website. Or almost done, I need to add docs for a couple projects and clean up the look on mobile. But those are their own things. For now, go check out the portfolio page, or the photos page. I'm happy enough with how they turned out, and I think I can finally move on from building out the website and instead focus on cleaning up the look and doing a bit of work with Dictionfairy. Sometime in the next few days I'll write entries about my earlier projects too and some of their specifics.

The website's been smooth. Most of my effort lately has gone to standardizing page stylings and setups for the portfolio and photos sections of the site. I'm very happy with the portfolio for now and ok with the photo subpages. The photo landing page looks fantastic though, and I think I used a neat little trick that I'd like to talk about briefly. It's a div with three equally-sized square images cut with the clip-path CSS property, and there's some math involved in the cuts that I don't think is worth diving into here but was fun to work out. I opted for a grid display and split the div into 10, with each cut image taking up 4 columns in the same row, where the split happens in the 4th and 7th columns of the whole thing. Then I just styled the div and ended up with a sort of retro-Apple look that I'm a big fan of.

While I have the chance, I'm going to talk a bit about the state Dictionfairy as well. All the functionality I need is there, which is nice. From here it's a few simple steps: One, I need to set up an easy way to do hotkey configuration if it's realistic. I think I should be able to just use the keyboard monitoring technique I already have but we'll see. Two, I need to make a page for the user to customize their own dictionary, which I think should be as simple as asking for a base website and a CSS selector to collect the results. Besides the docs and styling, that's about it - then, of course, testing and deployment. I use the tool a bunch in my own life, so it's nice to see it come along to the point where it might help others in the same way.

    Tags:
  • #isaac-fisher.com
  • #programming
  • #css
  • #dictionfairy
  • #python

Time to Get Technical

June 8, 2024

The website is coming together. I wanted to take the time today to get a little technical and start to describe some of the things I've learned from this project. As a major amateur in the webdev/UI field I imagine this will read like a kindergartner's first picture book, but that's ok.

The first major issue I faced was on the contact page with the smaller browser window format for the site. The menu for this sized viewport relies on continuing to hover over the menu to keep it open, but this failed around the bottom left corner of my side tab in the contacts page, right where the h2 and p elements overlap the menu. Ok, alright. Should be a quick and easy z-index fix. But of course this didn't work. I figured I had to set my menu dropdown to position: relative for the z-index to work (not the case - again, I'm new). And now my links are gone. At this point, it's about 2am and I am not happy. I grabbed the properties of the menu link elements with both position: relative and absolute. Just one thing's changed: the offset parent.

I actually didn't think anything of it at the time. I changed back to absolute and looked for a fix elsewhere. 3am. StackOverflow points me to this article about the pitfalls of z-index. Scrolling, scrolling, WAIT! Haven't I seen that offsetParent name before? I ran back to the elements and sure enough, the offsetParent of my dropdown menu was as far back as div.navigation. I was working in the wrong stacking context, and a quick z-index: 99 to that parent div let me go to bed content.

    Tags:
  • #isaac-fisher.com
  • #programming
  • #css

Lots and Lots of CSS

June 6, 2024

Third day of the website. My brain is complete mush from the StackOverflow CSS dives. I can't wait to get back to DictionFairy but I know that if I stop now I won't finish, and I'd really like to see this thing come together so that I can use it in the future.

I spent today working on a mobile port for the site. I discovered far too long into the process that the modern developer starts with mobile and builds out from there. Not me, clearly - thank god I probably won't have to do anything like this again for a while. Tomorrow I think I'll put more content up, especially on the portfolio page.

Also, I cooked a nice Chipotle-clone barbacoa beef today. It took hours to find the oxtails. Life is harder without a C-Town down the street.

I figure I'll be showing this to a few people in the next few days. If you're one of them, hello! Welcome, I'll probably forget I have this thing by the end of the month.

    Tags:
  • #isaac-fisher.com
  • #programming
  • #css
  • #food
  • #general

Discovering Web Design and Starting a New Book

June 3, 2024

I've made a routine of going to the coffee shop this summer right around noon every day. Today I was late; I stopped by Dickinson College's library to pick up a copy of Herrndorf, a biography of Wolfgang Herrndorf, author of Tschick and Sand. I'll be reading his bio this summer with Dickinson's Dr. McGaughey, a professor who I reached out to about a shared interest in Herrndorf's work.

I also decided rather impulsively to build this website. I've tried before, but it was much more amateurish and I was not very capable. I'll be working from the ground up with an HTML/CSS/JS stack, but I am honestly not entirely sure where the JS will come in with how static the website should be. Either way, I'm excited to get back into web design and see what I can get done before the end of summer.

Outlier work picked back up again today - I've been moved to a math project, which is a nice change of pace. Hoping to make some decent money for a trip to Berlin in August.

    Tags:
  • #isaac-fisher.com
  • #programming
  • #css
  • #javascript
  • #german
  • #general
  • #reading