<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://robbie.antenesse.net/feed.xml" rel="self" type="application/atom+xml" /><link href="https://robbie.antenesse.net/" rel="alternate" type="text/html" /><updated>2026-05-06T19:33:55+00:00</updated><id>https://robbie.antenesse.net/feed.xml</id><title type="html">Robbie Antenesse</title><subtitle>Professional web developer, hobby game developer, conlang enthusiast, and maker of highly specific niche software.</subtitle><entry><title type="html">How ChatGPT Works (In Simple Terms) and Why You Still Matter</title><link href="https://robbie.antenesse.net/2023/12/09/what-chatgpt-is-and-why-it-cant-replace-you.html" rel="alternate" type="text/html" title="How ChatGPT Works (In Simple Terms) and Why You Still Matter" /><published>2023-12-09T03:15:00+00:00</published><updated>2023-12-09T03:15:00+00:00</updated><id>https://robbie.antenesse.net/2023/12/09/what-chatgpt-is-and-why-it-cant-replace-you</id><content type="html" xml:base="https://robbie.antenesse.net/2023/12/09/what-chatgpt-is-and-why-it-cant-replace-you.html"><![CDATA[<p>There’s an awful lot of hype and fervor around ChatGPT and other impressive chatbots
that reply with very natural-sounding responses being called “Artificial
Intelligence” (AI) these days—though people’s interest already seems to be burning
out because of its omnipresence. AI programs are a truly impressive creation that
have understandably led people to worry about what they’re capable of, but learning
what’s actually being done behind the scenes can help temper your expectations and
alleviate (some of) your concerns. For example, even knowing what “GPT” stands for
can immediately shed some more light on the dark and scary cave that is modern AI.</p>

<p>In this post, I’m going to try to explain what GPTs and LLMs are in the simplest
terms possible. My hope is that, by the end, you’ll have a better understanding
of what’s involved in these tools and what that means for AI’s practical use in
everyday life and business. There will definitely be nuances and details missing,
but I believe that grasping even just the basics of how ChatGPT works is much more
helpful than the existential terror and misguided reverence it fosters now.</p>

<h2 id="terminology">Terminology</h2>

<p>I’ve already used two of the most relevant terms in the introduction, “LLM” and
“GPT.” I also used “AI,” but I’m hoping that concept is already somewhat clear
to you if you chose to read this. Computer software developers love collapsing
phrases into initialisms like this to save time, but this often leaves people
who aren’t already in the know very much out of the loop. In many cases, what
the initialisms stand for doesn’t ultimately matter for most people, but in
this case, I believe that knowing what LLM and GPT stand for and then learning
what the phrases actually <em>mean</em> is more than half of what you need to really
understand what’s going on at the heart of modern AI.</p>

<h2 id="what-is-an-llm-and-why-is-it-important">What is an LLM and Why is It Important?</h2>

<p>“LLM” in the context of modern AI stands for “Large Language Model.” At its
core, an LLM is a big (“large”) list of phrases and sentences (“language”) with
some complicated math applied to rank how each word relates to other words in
the list (“model”).</p>

<p>More specifically, an LLM is a storage space (“database”) containing as many
sample documents as possible. Those documents are split out into individual
phrases and complete sentences (“strings”) depending on a specified number
of letters and punctuation (often resulting in millions to trillions of
strings or more), then those strings are separated into individual words and
analyzed. The analysis checks every word’s proximity to every other word in
every string along with any punctuation used near those words, and it ranks
the probability that one word is likely to appear next to another word in a
particular order.</p>

<p>Additional data (like the topic, mood, tone, source, or any number of other
ways to categorize the documents) can be provided before checking the strings
in the database in order to further identify contexts where certain word
combinations might appear. For example, it might be helpful to know when the
sample string comes from someone’s social media post versus someone else’s
academic journal article versus a movie review website. Typically, an LLM
will cover a single context, e.g. <em>only</em> social media posts or <em>only</em>
information covering a certain topic, because that kind of specialization
reduces the work required to categorize the samples. ChatGPT’s LLM is exemplary
in that the software developers have gone to great lengths to collect an
unfathomable number of sample texts and meticulously categorize those samples
in as many ways as possible.</p>

<aside>
  <details>
  <summary style="cursor:pointer;font-style:italic;">Expand for some more additional advanced context about LLMs</summary>
  <p>Since posting, some concern has been raised about the simplified explanation of
  LLMs in this section, so here's some details about how LLMs specifically use
  sets of numbers (called "vectors") to create context for the words in their database.</p>
  <p>Rather than literally using the text of words and how they are placed in relation
  to each other, every word (called a "token") is represented as a vector, and every
  token vector is associated with other token vectors based on how they have been
  used in the sample data in the database. The text itself is stored in a separate data set
  that the AI pulls from when using the model. Storing words this way removes the problems
  caused by homonymns and also allows very clever manipulation of words. The vector
  representation of tokens even allows mathematical computation between tokens
  to get new words based on how the relationships between vectors has been
  previously seen and used before. These mathematical relationships inevitably
  reveal interesting correlations between words and concepts that additionally shine a
  light on any biases present in the LLM's text samples.</p>
  <p><a href="https://www.understandingai.org/p/large-language-models-explained-with" target="_blank">This article</a>
  does a great job going into even more detail to explain exactly how these
  numerical structures work and gives a good sense of just how overwhelming
  the scope of these connections are. Anyway, while the idea of "word proximity" as
  I use it in this post is indeed an oversimplification of how the text data is used,
  I believe it is plenty to help most people to get a better grasp of the massive
  matrix of word relationships modeled by large language models.</p>
  </details>
</aside>

<h2 id="what-is-a-gpt-and-how-does-it-work">What is a GPT and How Does It Work?</h2>

<p>The “GPT” in “ChatGPT” stands for “Generative Pre-trained Transformer.” To
oversimplify things a little, a GPT uses the words and proximity data stored
in LLMs to determine what words would be most reasonable to place together in
a given context (“pre-trained”) in order to re-combine those words
(“transformer”) into hopefully different resulting text (“generative”).</p>

<p>What makes a GPT impressive is that it does the analysis and reorganization
of words in <em>both directions</em>—you can write <em>to</em> a GPT, and it will inspect
your writing (“input”) to find the most relevant word rankings within its
LLM in relation to what you’ve written in order to determine the appropriate
words to combine as a response (“output”). In addition to word rankings, a
GPT will also attempt to determine the correct context to check word rankings
within based on what you’ve written and where those combinations most commonly
occur. The best ones will have a way to decide if a given input is you
attempting to tell it what context to pull from, again all based on the
previous categorizations and ranking of words provided by the LLM.</p>

<p>GPT programs that I’ve used often have a space where you can give it starting
context to use before considering someone’s requested input. Every additional
word added to the input is used to filter what sample text should be used,
and many GPT chatbots provide that context before letting you write to it.
This context is essentially added to every input to add extra filtering when
generating output. Using these contexts can help ensure that output is created
within a certain set of parameters and pre-filtered options, which is how the
polite and subservient “personality” of ChatGPT is achieved.</p>

<h2 id="its-not-intelligence">It’s Not Intelligence</h2>

<p>With the important definitions out of the way, it’s important to note that GPTs
are not actually thinking or coming up with any unique thoughts. The only
“intelligence” on display is the cleverness of using the word proximity data
to produce output that sounds natural because the data samples were collected
from natural writings. Some have cleverly suggested “Applied Statistics” as a
new name for AI in reference to how GPTs construct output based on word
proximity and positioning, but “AI” is simply too disseminated into the public.
In my opinion, “Automated Inference” would be more fitting because it keeps the
“AI” acronym while also painting a more accurate picture of what the program is
actually doing. The LLMs give the GPTs the connections required between words,
and that helps the program infer what its output should be.</p>

<p>Again, the most important takeaway here is that there’s no real thinking
happening; GPTs are simply combining words. There is no analysis or understanding
of subject matter. And while some GPTs store a short history of input and output
to act as a simple working memory, it’s still just using the stored data as
further filtering. In fact, when GPTs are not configured with enough memory,
the results can be funny at best but frustrating at worst. The responses are
often so natural that it’s easy to forget that it’s not actually thinking and
keeping track of your whole “conversation” unless it’s repeatedly reminded of
what has been said before as the stored memory is cleared out in favor of more
recent input and output.</p>

<p>On top of it all, it’s still only able to combine words in ways that it has
seen before from its LLM. While it’s possible for output to be arranged in
interesting and unexpected ways, it is impossible for it to create something
never seen before. (Though <a href="https://thelanguagecloset.com/2023/02/04/i-asked-chatgpt-to-invent-its-own-language-pt-1/">this article where the author co-creates a constructed language with ChatGPT</a> (<a href="https://web.archive.org/web/20230815201903/https:/thelanguagecloset.com/2023/02/04/i-asked-chatgpt-to-invent-its-own-language-pt-1/">web archive</a>) is
quite an impressive manipulation of the available data in the LLM!)</p>

<h2 id="art-bots-and-how-theyre-related">Art Bots and How They’re Related</h2>

<p>To me, art bots are the most impressive application of these generators. Instead
of using collections of <em>text</em>, they instead use large models of <em>images</em>. Those
images are categorized and collected in a similar way to LLMs, and then those
images are chopped up and reorganized in ways it deems reasonable based on
rankings of different parts of the images. This is impressive because while
text is fairly straightforward for a computer to work with and find connections
within, the mechanism for finding connections between elements of images is
still fairly mysterious to me.</p>

<p>One thing I do know is that image GPTs utilize extensive cataloguing of their
image sets, including sub-categorization of various elements within a single
image. Early AI image identifiers attempted to match various elements of input
images with other elements within its own data sets. Oftentimes, the data sets
would not be big or varied enough to identify things in slightly different poses
or angles than what it had in its model, which would lead to misidentification.
But now with unfathomably more images in the available data set, it’s easier for
matches to be found.</p>

<p>Extrapolating from this, an image GPT must use this identification strategy to
piece together images from its data set and smooth them together using some
kind of pre-defined method. When the number of available images is so vast and
its cataloguing and organization so thorough, piecing together images that match
an arbitrary input follows an extremely similar structure to regular text GPTs,
except “proximity” now needs to take “up” and “down” into consideration in
addition to “left” and “right” as with a sentence.</p>

<h2 id="gpt-ais-are-extremely-impressive-and-useful">GPT AIs are Extremely Impressive and Useful</h2>

<p>Even though I’ve broken down modern AI into its basic parts to help you
understand how it works, it’s still important to recognize just how impressive
the things that developers like OpenAI do with ChatGPT really are. They’re
working with, analyzing, categorizing, and organizing gigabytes (possibly
terabytes) of text samples that are processed and used based on prompts that
<em>anyone</em> can supply. For reference, one letter is a <em>byte</em> and a <em>gigabyte</em>
is roughly a <em>billion</em> bytes while a terabyte is <em>one thousand gigabytes</em>—the
average novel is around 50 <em>thousand</em> words totaling only a few hundred thousand
bytes total.</p>

<p>Add in the fact that ChatGPT stores previous input and output to create a
working memory for itself to reference and contextualize future responses,
and you’ve got quite a formidable machine. Having a tool that you can ask
questions of in the same way you’d ask a friend is incredibly helpful for
brainstorming new ideas. Not many people are able to figure out how to ask
computers for things, so using a simpler, more intuitive input structure to
solicit a response will result in a more appropriate output. I know many people
including myself prefer asking a question directly to someone who would know
the answer over trying to figure out the best search query to put into a search
engine.</p>

<h2 id="but-current-ai-usage-is-a-problem">But Current AI Usage is a Problem</h2>

<p>The fact that Large Language Models used by GPTs are composed entirely of
previously created content, however, should give you a hint about why using
AI in anything but a hobby or strictly inspirational context is extremely
dangerous. The sheer quantity of sample texts provided by the LLM helps reduce
the odds of it repeating some unique phrase verbatim, but it’s far from impossible
for a GPT to generate its output in a way that’s identical to some of its sample
texts simply because the ranking of the word order seemed most reasonable. All
of that previously created content within the LLM was produced by someone, and
if the content used isn’t strictly and thoroughly vetted, a GPT can quickly and
easily steal someone’s work without the original creator, the GPT’s developers,
or the person <em>using</em> the GPT ever knowing until it’s too late.</p>

<p>Prominent examples of this can be found in various art bots. More than one bot
<a href="https://stablediffusionlitigation.com/">appears to</a> (<a href="https://web.archive.org/web/20230815200959/https:/stablediffusionlitigation.com/">web archive</a>)
source their art from an unimaginably large collection of artwork posted publicly
by the artist community on DeviantArt.com. The collected art is then used freely
by the GPT to construct remixed art, at least according to <a href="https://web.archive.org/web/20230815200643/https:/www.newyorker.com/culture/infinite-scroll/is-ai-art-stealing-from-artists">some posts</a>
I’ve seen about those who have noticed their (rather specific) art styles
reflected in some generated art. The fact that the artist is never informed
that their art is being used can at the <em>very least</em> be considered unethical if
not outright copyright infringement.</p>

<p>Likewise, ChatGPT itself has been known to source code snippets from the
ubiquitous home of software developers, GitHub, in order to produce (often
functional) code for software. Unfortunately, just because the code on GitHub
is <em>publicly visible</em>, most projects use one of a huge number of licenses that
dictate how the code may and may not be used. Unfortunately, it seems that these
various licenses were completely ignored when the code samples were collected
for ChatGPT, which has resulted in some hilarious outputs that
<em>include the text of the restrictive license and the name of the writer of the original code!</em></p>

<p>In addition to plagiarizing content, most of the output that GPTs produce is
also factually inaccurate because, again, words are simply being combined in
plausible ways based on how they have previously been used; there’s no analysis
of those words nor understanding of the topics. Likewise, biases and opinions
of previous writers are assimilated into the word proximity data, so the output
must always be checked for accuracy, tone, and underlying assumptions, and only
a person can do that.</p>

<p>There are infinitely many other ways that a GPT can fall short when its LLM is
not carefully curated and its output is not rigorously reviewed. Since LLMs are
not carefully curated in this way, it falls to the users to be extremely
diligent in massaging the output into something truly unique and correct
instead of just the amalgamation of billions of things produced before.</p>

<p>Beyond plagiarism, many employers and content producers have already attempted
to <a href="https://blog.dropbox.com/topics/company/a-message-from-drew">cut costs</a>
(<a href="https://web.archive.org/web/20231204190826/https:/blog.dropbox.com/topics/company/a-message-from-drew">web archive</a>)
by <a href="https://www.businessinsider.com/microsoft-news-cuts-dozens-of-staffers-in-shift-to-ai-2020-5">replacing their employees</a>
(<a href="https://web.archive.org/web/20231103174038/https:/www.businessinsider.com/microsoft-news-cuts-dozens-of-staffers-in-shift-to-ai-2020-5">web archive</a>)
with AI powered by GPTs. This misguided overreliance on AI is a huge problem,
not only for the real human experts losing their jobs but also for users of
the end product, which quite possibly contains wildly inaccurate information.
Search engine results were already clogged with pointless SEO articles, and now
they’re being flooded with blatantly false information that has been generated
by AI and has not been vetted at all. Relying on a GPT to do work that only a
thinking person can do is not only unethical but also results in content that
is low quality, derivative, and uninspired by the very nature of what LLMs are.</p>

<h2 id="how-to-use-ai-properly">How to Use AI Properly</h2>

<p>AI is a tool, and it must be treated as such, guided by an intelligent hand.
Recall that GPT stands for “generative pre-trained transformer,” and remember
that it is only transforming previously created content. Considering how GPTs
function and how they construct an output, it’s clear that the most useful
applications of ChatGPT and other tools like it are <em>brainstorming</em> and <em>templating</em>.</p>

<p>Many writers will attest to the value of talking to someone when they need help
finding the right word or phrase while writing, and ChatGPT can be an effective
stand-in to help conjure up the needed word combinations. Likewise, the monotony
of some repetitive writing tasks can be alleviated; for example, asking ChatGPT
to construct a sample thank-you note that you can fill in with accurate personal
details after a job interview. One clever tool (<a href="https://goblin.tools/">Goblin Tools</a>)
uses ChatGPT to help expand to-do lists into smaller pieces, analyze text for tone,
and perform other helpful actions specifically to help people with executive
dysfunction issues or other neurodivergent traits.</p>

<p>The important thing is that you treat everything it produces as a <em>starting point</em>
that you then mold into a final product. Simply using what ChatGPT outputs without
making changes is only asking for trouble. This is especially true when you’re
making content that people rely on to be accurate. The only exception is when
using GPT output for personal entertainment—fun doesn’t need to be accurate.</p>

<p>Moving forward, it is critical to be conscious of what AI is <em>for</em> and to
understand when and when not to use it. Asking an AI to generate a story
about your child’s favorite characters going on an adventure will always be
more appropriate than using it to write an entire novel you plan on distributing.
Using ChatGPT to give you a to-do list when packing for a trip to another country
will always be more ethical than using it to replace people who make content for
your website. Just as GPTs rely on context to produce output, you must also
understand what context AI output is useful for. When in doubt, tidy up the
output anyway—the results can be good, but they are rarely great.</p>

<h2 id="humans-are-not-obsolete">Humans are Not Obsolete</h2>

<p>At the end of the day, ChatGPT and the impressive things modern AI is doing
truly can’t replace you. The words they write with are only what you have
written in the past, and their assertions only reflect what you have asserted
before. They cobble together coherent sentences only because of how you have
previously used words, and they disregard the truth because they can’t analyze
what they write. A tool is only as good as the hand that wields it, and ChatGPT
is only as effective as the creative mind that directs it. AI can help you find
different ways to express ideas, but only you can create original and authentic
content.</p>]]></content><author><name></name></author><category term="chatgpt" /><category term="artificial intelligence" /><category term="ai" /><category term="technology" /><category term="large language models" /><category term="text generators" /><category term="machine learning" /><category term="chatbots" /><category term="big data" /><category term="plagiarism" /><category term="tools" /><category term="responsibility" /><category term="writing" /><category term="content creation" /><category term="natural language" /><summary type="html"><![CDATA[There’s an awful lot of hype and fervor around ChatGPT and other impressive chatbots that reply with very natural-sounding responses being called “Artificial Intelligence” (AI) these days—though people’s interest already seems to be burning out because of its omnipresence. AI programs are a truly impressive creation that have understandably led people to worry about what they’re capable of, but learning what’s actually being done behind the scenes can help temper your expectations and alleviate (some of) your concerns. For example, even knowing what “GPT” stands for can immediately shed some more light on the dark and scary cave that is modern AI.]]></summary></entry><entry><title type="html">toki pona li pona mute a!</title><link href="https://robbie.antenesse.net/2021/12/07/toki-pona.html" rel="alternate" type="text/html" title="toki pona li pona mute a!" /><published>2021-12-07T03:19:00+00:00</published><updated>2021-12-07T03:19:00+00:00</updated><id>https://robbie.antenesse.net/2021/12/07/toki-pona</id><content type="html" xml:base="https://robbie.antenesse.net/2021/12/07/toki-pona.html"><![CDATA[<blockquote>
  <p>toki! mi jan Lapi li kama sona e toki pona! <br />
 ⬇ <br />
“Hi! I’m Robbie, and I’m learning toki pona!”</p>
</blockquote>

<p><a href="https://tokipona.org">toki pona</a> is a fully usable constructed language with just 120 created words by Sonja Lang in 2001 that has since grown to 137 essential words with thousands of speakers and writers around the world! I wanted to try learning toki pona ever since I first heard about it, but I never had any particular reason to (the same reason most of my language learning endeavors have stalled in the past). But now I’ve decided to ignore my ingrained apprehensions about its practicality and <em>just learn it</em> for the sake of knowing it.</p>

<p>This is notable because I very rarely consider learning to use a conlang, including any of my own! Conlangs have always been an intellectual interest for me—I love seeing how people choose to communicate different things and what kinds of sounds they use to do it. It comes from the same roots as my interest in linguistics and how languages work and are formed even though I don’t often go out and try to learn a new language. But toki pona is special… And only 137 words.</p>

<p>There are now 2 books written and compiled, respectively, by Sonja Lang for learning the language, <a href="http://www.amazon.com/gp/product/0978292308"><em>Toki Pona: The Language of Good</em></a> and <a href="https://www.amazon.com/dp/0978292367/"><em>Toki Pona Dictionary</em></a>, but there are so many excellent resources for learning the language available online that these books are essentially just insightful resources for further understanding the language. <em>Toki Pona Dictionary</em> was released in July 2021 and contains around 400 pages of toki pona phrases that have been used by the community and references for how various English phrases can be communicated in toki pona.</p>

<p>Here is an example of what toki pona looks like:</p>

<blockquote>
  <p>mi kama sona e toki pona la, mi kepeken e toki pona lon tenpo ale tawa ijo lili. kin la, jan ale li wile toki e toki pona tawa musi!</p>
</blockquote>

<p>It says, “When I learn toki pona, I will use it all the time for little things. Indeed, everyone should speak toki pona for fun!” <small>I’m still working on learning the grammar and vocabulary, but I’m pretty sure I got it roughly correct.</small></p>

<p>Anyway, it’s a fun language that forces you to simplify how you think in order to communicate what you want to say. There is no distinction between happy, satisfied, content, or fine—it’s all <em>pona</em>, “good.” There’s no distinction between sad, depressed, angry, or evil—that’s all <em>ike</em>, “bad.” At the same time, the words and how you combine them do a lot of interesting things together that can communicate a lot. Perhaps you can’t directly say that you’re sad, but you can say that you’re <em>pilin ike</em>, “feeling bad.” Suppose you’re not sad, but your stomach hurts? You could still say you’re <em>pilin ike</em>, or you can specify that <em>insa mi li pilin ike</em>, “my stomach feels bad.”</p>

<p>See what I mean? It’s a little puzzle to figure out how to communicate, and context is king. You need to know at least a little bit of context to know exactly what’s being communicated in many cases. That’s what I love about it though. You can’t talk about advanced programming topics or math, but you can talk about your day or things you did in a simplified way.</p>

<h2 id="the-master-list">The Master List</h2>

<p>When I decided I wanted to learn toki pona for real, I started watching a very good <a href="https://www.youtube.com/playlist?list=PLjOmpMyMxd8T9lZjF36c4mn4YgwZ4ToT6">video lesson series by jan Misali on YouTube</a> that introduced 10 words at a time with grammar rules in roughly 3-minute chunks, and it was very helpful for getting me up to speed very quickly (with lots of pausing to copy down words). I have since gotten a copy of <em>Toki Pona: The Language of Good</em> (called <em>pu</em> in toki pona), and I learned that the <em>Toki Pona Dictionary</em> (called <em>ku</em> in toki pona) was released just a couple months before I started learning! In doing research on that, I learned (from <a href="https://www.youtube.com/watch?v=n3p4-GFXrkM">this video by the same person who did the lessons</a>) that 17 new words were made official to the language!</p>

<p>Unfortunately, it’s so new that all of the dictionaries online were only of the “classic list” included in <em>pu</em> plus a small handful of other words that were somewhat commonly used. So I set out to compile a master list of all 137 official words that also included some helpful word combinations to help me study. Using the dicitonary in <em>pu</em> and 2 other websites that had expanded and altered word meanings, I compiled the ultimate toki pona word list! (Those lists are from <a href="http://tokipona.net/tp/ClassicWordList.aspx">tokipona.net</a> and <a href="https://devurandom.xyz/tokipona/dictionary.html">devurandom.xyz/tokipona</a> plus <a href="https://devurandom.xyz/tokipona/13.html">this page from the same site</a>, in addition to some definitions from jan Misali’s video on <em>ku</em> linked above.) Using my sources, I jammed every meaning and part of speech into the list to help make sure I knew not just the meanings of the words but also certain nuances on them.</p>

<p>Once it was compiled into a text document, I went through and copied all the words and definitions into the only flash card study app I could find for iOS that was fully free, flashcards.io. <del>Lucky for you, the app is primarily web-based, so if you want to study toki pona vocabulary with all of the words, you can check out the flash card deck here:</del></p>

<p><del><a href="https://flashcards.io/app?deck=d-17438-2021-12-06T20%3A21%3A38.051Z17">toki pona ku (en nimi ilo) on flashcards.io</a></del></p>

<p>Unfortunately when I checked on the link above a month after posting this, the link no longer appears to work! So I went ahead and moved it to <a href="https://apps.ankiweb.net">Anki</a>, the most popular flash card app that I know of, which may be more helpful for you:</p>

<p><a href="https://ankiweb.net/shared/info/1075479788">toki pona ku (en nimi ilo) on Ankiweb</a><br />
<em>(Note: Only the desktop and Android versions of the Anki app are free, but if you create an <a href="https://ankiweb.net">Ankiweb</a> account, you can sync your progress with the desktop app and access your decks from your iPhone for free in the browser!)</em></p>

<p>I intend to expand the list as I learn more toki pona and common word combinations, but the official 137 words are in there, and they won’t change.</p>

<p>So go learn a new little language! o tawa kawa sona e toki pona!</p>]]></content><author><name></name></author><category term="toki pona" /><category term="conlang" /><category term="learning" /><category term="languages" /><category term="linguistics" /><category term="constructed language" /><summary type="html"><![CDATA[toki! mi jan Lapi li kama sona e toki pona! ⬇ “Hi! I’m Robbie, and I’m learning toki pona!”]]></summary></entry><entry><title type="html">How to Leave Google Photos</title><link href="https://robbie.antenesse.net/2020/11/25/exporting-google-photos.html" rel="alternate" type="text/html" title="How to Leave Google Photos" /><published>2020-11-25T21:10:00+00:00</published><updated>2020-11-25T21:10:00+00:00</updated><id>https://robbie.antenesse.net/2020/11/25/exporting-google-photos</id><content type="html" xml:base="https://robbie.antenesse.net/2020/11/25/exporting-google-photos.html"><![CDATA[<p><em><a href="#getting-started">Skip to Guide</a></em></p>

<h2 id="table-of-contents">Table of Contents</h2>

<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#getting-started">Getting Started</a></li>
  <li><a href="#getting-your-export">Getting Your Export</a></li>
  <li><a href="#extracting-your-export">Extracting Your Export</a></li>
  <li><a href="#processing-your-export">Processing Your Export</a></li>
  <li><a href="#youve-done-it">You’ve done it!</a></li>
  <li><a href="#other-options-and-more">Other Options and More</a></li>
</ul>

<h2 id="introduction">Introduction</h2>

<p>Google is amazing, and they have provided many great services for many years. Google also has a <a href="https://killedbygoogle.com/">history of shutting down projects</a> that many people rely on with very little warning. While Google isn’t <em>shutting down</em> its Photos system by any means, they are <a href="https://blog.google/products/photos/storage-changes/">ending free high quality uploads on June 1, 2021</a> (<a href="https://support.google.com/photos/answer/6220791?co=GENIE.Platform%3DAndroid&amp;oco=1#storage">except for Google Pixel phones exclusively</a>); at that time, photos uploaded to Google Photos will start counting toward your (still very generous) 15GB of free cloud storage that’s shared with Google Drive and Gmail.</p>

<p>If you’re like me, you’ve enjoyed Google’s free photo upload system as a wildly convenient backup platform for all the photos on your phone, but with the free version getting cut and storage space shared with Google Drive, I suddenly find myself with a very small amount of storage space remaining! First, I do need to make it clear that Google’s <a href="https://one.google.com/about#upgrade">pricing for storage</a> is <em>very good</em> at about $2 per month or $20 per year for 100 GB, and if you’re able to pay the monthly or yearly fee, Google Photos is (in my experience) unmatched in its convenience and features! Just keep it in the back of your mind that Google may shut down this system at any time in the future as well. :)</p>

<p>If you’re not willing to pay Google and/or you’re concerned about your <a href="https://en.wikipedia.org/wiki/Privacy_concerns_regarding_Google">data privacy</a> (or maybe you just want to get your photos off Google to put on a different cloud hosting platform), read on! Do be warned, Google doesn’t <em>want</em> you to switch platforms, so they make it as inconvenient as possible to accomplish your goal. It’s annoying and it takes a long time, but you stick with it, you can do it and this guide will help you!</p>

<aside>I also packaged up my own Google Photos export organizer so you can get your photos exported and sorted into a more usable and easier to view format. That's be covered <a href="#processing-your-export">further down in the guide</a>, but after more than 2 years, it's likely that Google has changed their metadata format and made the organizer obsolete.</aside>

<h2 id="getting-started">Getting Started</h2>

<div class="card callout">
<p>Be aware, this guide is recommended for people who are comfortable using a computer and following instructions. There may be concepts here that are not fully explained and will require some of your own researching if you don't already know how to do it! If you're not comfortable with that, try to find someone who can do this for you instead.</p>
</div>

<p>The first thing you need to do is tell Google you want to initiate a data export from <a href="https://takeout.google.com">Google Takeout</a>. As far as I can tell, Google Takeout lists <em>every</em> Google service that stores data of some kind, but this guide only covers Google Photos.</p>

<blockquote>
  <p><strong>Optional Recommendation:</strong> Before exporting your photos, take the time to go through your Google Photos collection and <em>delete as many unwanted or duplicate photos as possible</em>! This will make the process <em>so much easier</em> because you’ll have that many fewer photos to deal with down the line.</p>
</blockquote>

<h3 id="google-takeout">Google Takeout</h3>

<p>When you get to the Google Takeout page, first click “Deselect all” to uncheck all the checkboxes, then scroll down to find Google Photos and check the box next to it:</p>

<p><img src="/images/exporting-google-photos/takeout-photos-checked.jpg" alt="The Google Photos option checked in Google Takeout" /></p>

<blockquote>
  <p><strong>Note:</strong> Using the button in the Google Photos section for “All photo albums included,” you can customize what albums you want to include in the export; the “Multiple formats” button simply explains the types of files that will be included in the export. In my case, <em>every individual day</em> that a photo was taken got separated into <em>its own album</em>.</p>

  <p><img src="/images/exporting-google-photos/takeout-photos-albums.jpg" alt="My album selection list for Google Photos in Google Takeout" /></p>

  <p>If you’re exporting all your photos, this doesn’t really matter, but just be aware that choosing specific albums can take quite a bit of time…</p>
</blockquote>

<p>After checking the box, scroll all the way down and click the “Next step” button near the bottom of the page. This will take you to the “Choose file type, frequency &amp; destination section” where you have a few options.</p>

<h4 id="export-settings">Export Settings</h4>

<p>The first option is “Delivery method,” which lets you choose whether to have Google email you links to your files when you download them or to have Google directly upload the messy Takeout folders directly to a different cloud storage service. This guide will be covering the Email method so you can get the files directly onto your computer and subsequently organize them into usable folders.</p>

<p>The next option is “Frequency,” which is useful if you plan to continue using Google Photos, have a ton of storage space for backing everything up multiple times, and want to perform this process multiple. Otherwise, just choose “Export once” and move on.</p>

<p>Last in this section is the “File type &amp; size” section. If you’re not technically inclined, don’t have any long videos stored, and don’t want to think too hard about things, just use the default selections of “.zip” and “2 GB” and click the “Create export” button—we’ll meet back up in a couple paragraphs. If you want to explore these options (or do have large video files), read on! The file type options are “.zip” (the format just about every computer can handle) and “.tgz” (the format that results in smaller file sizes but takes more effort to extract). If you’re just exporting a backup for storage and <em>do not</em> need to look at your pictures, go ahead and use that <code class="language-plaintext highlighter-rouge">.tgz</code> format—it should provide more efficient storage on your external drive. Otherwise, you should use <code class="language-plaintext highlighter-rouge">.zip</code> for the convenience.</p>

<p>The file size option is an interesting one with a very important and unstated consequence for choosing a size that’s too small. If you’re using Google Photos like me, then you probably have a lot of photos stored on there (or example, I had about 61 GB of photos and videos)! This option lets you choose how you want Google to package up your photos—your export will result in however many <code class="language-plaintext highlighter-rouge">.zip</code> (or <code class="language-plaintext highlighter-rouge">tgz</code>) files it takes to chunk up your photos into your selected file size. I originally chose the default 2 GB, so my 61 GB of files resulted in 30 <code class="language-plaintext highlighter-rouge">.zip</code> files that were 2 GB each and 1 file that was about 128 MB or something. This is an interesting choice because this means that you will need to <em>download that many files</em> to your computer and manually unzip them all! The tradeoff here is faster download times versus longer processing time, where smaller <code class="language-plaintext highlighter-rouge">.zip</code> size will result in faster downloads but more processing and vice-versa!</p>

<div class="card callout">
<p>That being said, there <em>is one <strong>very important</strong> caveat</em>: large video files will be <em>silently excluded</em> from your export if the file size you choose is smaller than the size of the video!</p>
<p>If you have any long videos or large files in your Google Photos account, be sure you choose an export size large enough for the video to fit inside or else it will not be exported at all, and you will <em>not be told if your files are excluded</em>! So be sure to choose a large enough file size to contain your videos if you know you have them stored there.</p>
</div>

<p>Once you’ve made your choices, click “Create export” to move on.</p>

<h2 id="getting-your-export">Getting your Export</h2>

<p>Google will begin processing your export, and this can take anywhere from 10 minutes to an hour to a day depending on how many photos you have! My export only took about 20 minutes, but allow more time if Google’s servers are busy or you’re a professional photographer with hundreds of thousands of photos. Either way, you’ll get one email telling you that the export has started and another telling you when it’s ready to download!</p>

<p><img src="/images/exporting-google-photos/takeout-export-processing.jpg" alt="Google Takeout's export warning that it may take a long time" /></p>

<p>Once you get your email telling you your export is ready (or if you stay on the page until it’s done), you’ll get a link to the “Manage your exports” page. Unless you’ve done an export before, it should only show one item with a clear “Download” button. When you click it, Google may ask you to re-enter your password to log in. It will do this if you don’t complete your work within a comparably small amount of time (maybe every 5 or 10 minutes?), so keep your password handy if your browser doesn’t fill it in for you automatically!</p>

<p><img src="/images/exporting-google-photos/takeout-export-manager.jpg" alt="Google Takeout's &quot;Manage your exports&quot; page with one export available to download" /></p>

<p>Click that download button, and depending on the size of your export, you’ll get a popup on the screen with a list of files to download. Just download each of them one by one—every time you click the download for one of the items, it will refresh the page and initiate the download. Just confirm the download if your browser asks for confirmation and do this for each file in the list.</p>

<p>Each time the page reloads, the icons inside the buttons next to previously downloaded items will change from a download icon to a checkmark icon.</p>

<p><img src="/images/exporting-google-photos/takeout-export-downloading.jpg" alt="Google Takeout's download list" /></p>

<p>For most people, this download process will be long and tedious. Just stick with it and keep downloading until you’ve got all of them. You <em>need</em> every single one of the downloads because your photos and the associated files are just randomly scattered among them. This is one of the things I was talking about when I said Google made it as inconvenient as possible.</p>

<h2 id="extracting-your-export">Extracting Your Export</h2>

<p>Now that you’ve got all of your export files, you get to begin the “fun” process of extracting and merging them all into a single folder! This process is different for MacOS than it is for Windows, but I’ve got you covered. You don’t need any extra software if you’re using <code class="language-plaintext highlighter-rouge">.zip</code> files on MacOS or Windows, but I do recommend you use the most recent version of <a href="https://www.7-zip.org/">7-Zip</a> on Windows (or <a href="https://sourceforge.net/projects/p7zip/files/">p7Zip for Linux</a>)! 7-Zip is free (and safe!), and it can handle an outrageously wide variety of different compression formats!</p>

<p>Like I mentioned before, it is important that you have <em>all</em> of the files from Google and that the downloads are all complete, because you need to extract the contents of these files and merge them together. Your operating system should handle the merging process for you, but this guide will show you <em>how</em> to do that.</p>

<aside>Alternatively, I wrote a <a href="#processing-your-export">handy program</a> that will do this step and all of the following steps <em>for you</em> with just a little bit of setup! Use that link for instructions on how to use it if you'd rather go the semi-automatic route.<br />
Note that you do still need to have all of the <code>.zip</code> files from your Google Takeout export downloaded in one place for this method.</aside>

<h3 id="on-windows">On Windows</h3>

<p>All of my screenshots will be from Windows 10, but it should be a similar process for older versions (XP, Vista, 7, or 8) when using 7-Zip, linked above. (The process should be similar for Linux too, as long as you’re using a graphical UI like Unity in Ubuntu.)</p>

<p>Ok, this process is not difficult, it’s just mind-numbing and tedious—just pay attention and try to make sure you click and drag as precisely as you can with your mouse. All you need to do is open the 7-Zip File Manager and navigate to where you downloaded the <code class="language-plaintext highlighter-rouge">.zip</code> files from Google and double-click the first file. 7-Zip will open the file and show the contents—the first folder will be a folder named “Takeout”. If you open that folder, you’ll find a Google Photos folder, and then within that are folders with a random set of your albums, <em>but</em> you shouldn’t need to worry about that!</p>

<p>In a File Explorer window, open up or create an empty folder and put that window side-by-side with 7-Zip:</p>

<p><img src="/images/exporting-google-photos/side-by-side-empty.jpg" alt="A windows File Explorer window next to a 7-Zip window" /></p>

<p>Then click the Takeout folder in 7-Zip to highlight it and then click and drag the Takeout folder into the empty folder in the File Explorer window! 7-Zip will first extract the Takeout folder, then Windows will copy the contents into your empty folder.</p>

<p>And that’s what we’re going to be doing with every single file you downloaded from Google until you’ve done it with all of them!</p>

<p>Every time you repeat this click and drag process, Windows will start asking if you want to merge folders. Answer Yes, and when possible check the box that says “Do this for all current items” to prevent Windows from asking you multiple times.</p>

<p><img src="/images/exporting-google-photos/merge-request.jpg" alt="A pop-up window above 2 other windows asking if Windows should merge the folders" /></p>

<p><img src="/images/exporting-google-photos/merge-request2.jpg" alt="Another window asking about merging with a &quot;Do this for all current items&quot; box checked." /></p>

<blockquote>
  <p>If you accidentally extract the same folders twice, Windows may warn you that there are files with the same names and ask if you want to “Replace the files in the destination” or “Skip these files”. Typically this only comes up when you’ve already extracted the folder before and you’ve accidentally initiated the copy again, so it is safe to choose “Skip these files” to shorten the time it takes to extract. But if you don’t trust yourself, choosing “Replace the files in the destination” won’t hurt anything, it’ll just lengthen the time it takes to finish extracting a little.</p>

  <p><img src="/images/exporting-google-photos/replace-or-skip.jpg" alt="A Windows prompt window asking to replace or skip files with the same name" /></p>
</blockquote>

<h3 id="on-linux">On Linux</h3>

<p>The process on a GUI Linux using p7Zip will be nearly identical, with the main difference being the way your operating system asks you about merging the files. The process of clicking and dragging from p7Zip into a folder should be exactly the same, though!</p>

<h3 id="on-macos">On MacOS</h3>

<p>The process is a bit different in MacOS because of how MacOS opens extracts things from <code class="language-plaintext highlighter-rouge">.zip</code> files: instead of opening in a new window where you can preview the contents first, it just extracts the files <em>immediately</em> into the same folder! So after you download your export files, I recommend you create a new, empty folder and move all of the <code class="language-plaintext highlighter-rouge">.zip</code> files into that new folder.</p>

<p>Once you navigate to the folder with all your <code class="language-plaintext highlighter-rouge">.zip</code> files inside, simply double-click each file, and its contents will be extracted for you! It may take a while to extract the large exported files from Google, but just be patient and let the computer do its thing.</p>

<figure class="src-replace">
  <img src="/images/exporting-google-photos/macos-unzipping-files_still.jpg" data-src-replace="/images/exporting-google-photos/macos-unzipping-files.gif" alt="A MacOS window extracting several ZIP files" />
  <figcaption class="primary button" title="Click to Load GIF">Click to Load Animation (1.5 MB)</figcaption>
</figure>

<p>Next, you’re going to merge each of the “Google Photos” folders into the first “Takeout” folder. Pay attention, because merging folders in MacOS is not as straightforward as in Windows!</p>

<p>To enable the option for merging folders, you need to perform a <em>Copy</em> of the folder in question. You can do this in one of two ways:</p>

<ol>
  <li>Select the folder, use the Copy function, and Paste it into the correct folder (more steps)</li>
  <li>Hold down the <code class="language-plaintext highlighter-rouge">alt option</code> key <em>as you click and drag</em> your folders into the target folder (one step)</li>
</ol>

<h4 id="copymerge-method-1">Copy/Merge Method 1</h4>

<p>Method 1 (using Copy and Paste) might be more familiar to most people, but you have to make sure you’re copying the right folder and pasting it into the correct place or else you’ll just be duplicating many gigabytes of data onto your hard drive.</p>

<p>There are at least 3 different ways to access the Copy and Paste function on MacOS:</p>

<ol>
  <li>Select the folder you want to copy, click <code class="language-plaintext highlighter-rouge">Edit</code> at the top of the screen, choose the <code class="language-plaintext highlighter-rouge">Copy "Folder Name"</code> option, select the folder you want to paste into, click <code class="language-plaintext highlighter-rouge">Edit</code> at the top of the screen again, and choose the <code class="language-plaintext highlighter-rouge">Paste Item</code> option.</li>
  <li>Select the folder you want to copy, hold <code class="language-plaintext highlighter-rouge">⌘ command</code>, and then press <code class="language-plaintext highlighter-rouge">C</code> to copy, open the folder you want to paste into, hold <code class="language-plaintext highlighter-rouge">⌘ command</code>, and press <code class="language-plaintext highlighter-rouge">V</code> to paste.</li>
  <li>Right click the folder you want to copy, choose the <code class="language-plaintext highlighter-rouge">Copy "Folder Name"</code> option, then right click the folder you want to paste into and choose the <code class="language-plaintext highlighter-rouge">Paste Item</code> option.</li>
</ol>

<p>To use this method, open the “Takeout 2” folder, copy the “Google Photos” folder, navigate to the first “Takeout” folder, and paste into that folder. The computer will prompt you whether you want to cancel, replace, or merge the folders—choose “Merge” and the computer will handle the rest!</p>

<blockquote>
  <p>Just make sure you are copying and pasting into the correct folder and getting the “Merge” option. If you are pasting into the wrong place, you might accidentally use up a lot of space on your hard drive by accident! To help manage your computer’s storage space (and to help you remember which folders you’ve already merged), go ahead and delete the Takeout folder you just merged from after the merge is complete!</p>
</blockquote>

<h4 id="copymerge-method-2">Copy/Merge Method 2</h4>

<p>Method 2 (using <code class="language-plaintext highlighter-rouge">alt option</code> with a click and drag) takes a little bit more precision, but in my opinion is a lot easier to do right if you’re careful!</p>

<p>So expand the “Takeout 2” folder so you can see the files in one window, highlight the “Google Photos” folder within, hold down the <code class="language-plaintext highlighter-rouge">alt option</code> key on your keyboard (it’s the button next to the <code class="language-plaintext highlighter-rouge">⌘ command</code> key on your Apple keyboard, in case you’ve never noticed it), and click and drag the “Google Photos” up until it highlights the first “Takeout” folder. Then just release your click! The computer will prompt you whether you want to cancel, replace, or merge the folders—choose “Merge” and the computer will handle the rest!</p>

<figure class="src-replace">
  <img src="/images/exporting-google-photos/macos-merge-folders_still.jpg" data-src-replace="/images/exporting-google-photos/macos-merge-folders.gif" alt="A MacOS window merging folders with the same name" />
  <figcaption class="primary button" title="Click to Load GIF">Click to Load Animation (1 MB)</figcaption>
  <span class="info label" style="position:absolute;bottom:0;left:0;margin-left:0;font-size:11pt;font-style:italic;">Hold the `alt option` key while clicking and dragging</span>
</figure>

<p>Repeat this merge process with each extracted Takeout folder, remembering always to hold down the <code class="language-plaintext highlighter-rouge">alt option</code> key while clicking and dragging! If you <em>ever</em> get a prompt from your computer that does <em>not</em> include a “Merge” option, cancel and try again! If you’re sure you’re doing it right, you may have already merged that folder in. Feel free to cancel or replace if you don’t trust that the merge happened.</p>

<p>To help you remember which folders you’ve already merged (and to help manage your computer’s storage space), go ahead and delete the Takeout folder you just merged from after the merge is complete!</p>

<blockquote>
  <p>I can’t stress enough the importance of getting your aim right when doing this. Make sure you are dragging the “Google Photos” folder from each Takeout folder into the first “Takeout” folder! The Takeout folder will highlight when you are hovering over it correctly. If you accidentally drop the folder into the wrong place, it will create a <em>copy</em> of the folder in that other folder!</p>
</blockquote>

<p>Another note, the view I’m using in the example is “as List”. If you’re not seeing the files in your folder on individual lines like in the screenshots, make sure the Finder window with your files is selected, click “View” in the top bar, and choose “as List” from the menu.</p>

<style>
figure.src-replace, figure.src-replace img {
  position: relative;
}
figure.src-replace figcaption {
  position: absolute;
  top: 45%;
  left: 45%;
  transform: translate(-50%);
  z-index: 1;
}
</style>

<script>
(function() {
  const srcReplace = document.querySelectorAll('figure.src-replace');
  for (let i = 0; i < srcReplace.length; i++) {
    const figure = srcReplace[i];
    const figcaption = figure.querySelector('figcaption');
    figcaption.addEventListener('click', () => {
      figcaption.parentNode.removeChild(figcaption);
      const img = figure.querySelector('img');
      const replacement = img.getAttribute('data-src-replace');
      img.src = replacement;
      console.log(replacement);
      img.removeAttribute('data-src-replace');
    });
  }
})();
</script>

<h2 id="processing-your-export">Processing Your Export</h2>

<p>When you’re finally done extracting and merging, you’ll have all of your images from Google Photos in one place on your own computer! You did it!</p>

<div class="card callout">
<p><strong>Please note:</strong> the Google Photos Export Organizer app linked here is at least 2 years out of date, and some have reported that it does not work correctly for them anymore.</p>
<p>I do not plan to do significant work to get it working again, so the rest of this post may no longer be helpful!</p>
</div>

<p>But if you actually want to be able to look through your pictures in any reasonable way, you’ll need to do something about the bonkers folder structure that Google left you with. To do that, you would need to go through and organize things yourself, which is commendable and perfectly respectable, but it’s a huge pain in the butt and takes absolutely forever.</p>

<p>Luckily, I made a script for myself during the process, and I’ve tweaked it and made it into a user-friendly little program for others partaking in this unfortunate journey after me!</p>

<p>The program goes through your extracted Google Photos folder and moves every image and video it finds into nicely-organized folders based on the year and month the photo was taken (or created)! It can also extract <em>and</em> merge the files for you to save you the effort of doing that manually!</p>

<p><a href="https://alamantus.github.io/GooglePhotosExportOrganizer/" class="primary button tinystats">
  Get the Google Photos Export Organizer
</a></p>

<p>On the page linked in the button above, download the file labeled for your operating system (Window, MacOS, or Linux), extract the folder, and run the program inside to get started.</p>

<p>It will take you through a series of 4 steps to help you get your Google Photos export taken care of. Step 1 points you back to this post for how to export and download your files, then Step 2 will extract your exported files for you! Just tell the program where you downloaded your <code class="language-plaintext highlighter-rouge">.zip</code> files and where you want to extract them, and it will do it for you! Step 3 will move the files from your extracted folders into new folders organized by year and month that the photo was created. Finally, Step 4 reminds you to delete the exported files to help you clean up.</p>

<p>I think it’s fairly straightforward and easy to follow, but if you run into issues or have any questions, please <a href="https://github.com/Alamantus/GooglePhotosExportOrganizer/issues">submit an issue on GitHub</a> so I can work on fixing it as soon as possible! If any fixes need to be made, the program will alert you about any available updates to download when it loads.</p>

<p>After running the program on your folder…</p>

<h2 id="youve-done-it">You’ve done it!</h2>

<p>You can now do whatever you want with your nicely organized photos! You can upload it to a new cloud platform, you can keep it on your computer… Whatever you want! Your photos and videos are just plain computer files, and you can do whatever you want with them.</p>

<p>Don’t forget to delete all those <code class="language-plaintext highlighter-rouge">.zip</code> files if you don’t need them anymore! They probably take up an awful lot of space on your computer.</p>

<p>Just one last reminder: all of the files you just downloaded and processed <em>are</em> still on Google’s servers, so if you want to completely cut the Google cord, you’ll have to delete them from there.</p>

<p>Enjoy being disconnected from Google Photos!</p>

<h2 id="other-options-and-more">Other Options and More</h2>

<p>Since posting this, I’ve seen a lot of great discussion and suggestions around this subject. I’ll use this section to add more tips and options for exporting and organizing your Google Photos that might be more effective depending on your specific needs as I am able to compile them!</p>

<p>In the meantime, check out the comments below and the comments where I <a href="https://old.reddit.com/r/selfhosted/comments/k1i0bw/i_wrote_a_detailed_guide_to_help_people_get_their/">posted on Reddit</a> for some good discussions about alternative options to Google Photos and potential issues with using the Google Takeout system.</p>]]></content><author><name></name></author><category term="Google Photos" /><category term="export" /><category term="guide" /><category term="files" /><category term="digital freedom" /><category term="pictures" /><category term="images" /><category term="Windows" /><category term="Linux" /><category term="MacOS" /><category term="OSX" /><summary type="html"><![CDATA[Skip to Guide]]></summary></entry><entry><title type="html">One Year of Readlebee</title><link href="https://robbie.antenesse.net/2020/09/11/one-year-of-readlebee.html" rel="alternate" type="text/html" title="One Year of Readlebee" /><published>2020-09-11T03:05:00+00:00</published><updated>2020-09-11T03:05:00+00:00</updated><id>https://robbie.antenesse.net/2020/09/11/one-year-of-readlebee</id><content type="html" xml:base="https://robbie.antenesse.net/2020/09/11/one-year-of-readlebee.html"><![CDATA[<p>About one year ago, give or take a few days, I started development on <a href="https://gitlab.com/Alamantus/Readlebee">Readlebee</a> after realizing that there is absolutely no alternative to the Amazon-owned <a href="https://goodreads.com">GoodReads</a> that does <em>everything</em> that GoodReads does. GoodReads is a social network for readers, a reading tracker, a wishlist manager for books, a way to stay informed about authors, a place to learn about books (usually by seeing what your friends have been reading), and more. There are a handful of apps that do one thing or another from that list, but nothing fully encompasses what GoodReads offers. Readlebee is my project that aims to fill that glaring hole as a real alternative to GoodReads.</p>

<p>I knew from the start that such a project would be incredibly ambitious and take a lot of work, but I was sure that if I didn’t start working on it, I would never see the alternative that I wanted so badly (thankfully <a href="https://github.com/mouse-reeve/bookwyrm">other</a> <a href="https://beta.thestorygraph.com/">projects</a> have begun since then). I’ve been a part of the <a href="https://fediverse.party/en/fediverse">Fediverse</a> for a few years now, so I wanted to build an application that could interact with other apps via the <a href="https://activitypub.rocks/">ActivityPub protocol</a>. I also am a huge fan of making software that’s easy to maintain and use, so I wanted the app I built to be as easy as possible for a tech-minded person to contribute code to and run their own instance of. These things all resulted in me leaning hard into setting up the Readlebee project as a “real deal” Open Source project that used frameworks that are relatively easy to learn that could be run using just <a href="https://nodejs.org">NodeJS</a> and the user’s choice of database manager (as opposed to requiring a suite of specific software). I looked into community guidelines, researched the appropriate software license, and set up the repository on the best platform for easy contribution (<a href="https://gitlab.com">GitLab</a>, because allows logging in with a good number of popular social media accounts).</p>

<p>My goal was to do things “right” from the start instead of my normal way of just getting it done quickly and going back to clean things up when it was working (if I got to it). My main reason for doing this is because this project is supposed to be open source and therefore easy for others to read and contribute to (instead of my normal personal project that’s easy for just <em>me</em> to follow). While I do believe that this approach is a good thing, it is the biggest reason that my progress has been so slow. Well, that and the fact that I ended up reacting unexpectedly poorly to the COVID-19 pandemic—that had me out of commission in a negative spiral for some time at the beginning of 2020—but I digress. Doing things the “right” way meant <a href="https://cybre.space/@Alamantus/104086357287694578">using code frameworks</a> that I was not familiar with, so I had to learn new systems while also building my own. I’m also trying to ensure that Readlebee has multi-language support and the best accessibility I can provide from the get-go, which has further slowed things down. All this extra learning on top of <a href="https://floss.social/@Readlebee/104592468805955667">occasional hangups</a> (plus actual full-time work) has led to an extremely slow development cycle without a lot to show for it after a year, and that’s super discouraging to me.</p>

<p>I’ve been doing my best to recognize that this lack of visible progress is okay because I’ve been doing a lot of learning and planning in addition to writing code for the project. Plus trying to account for doing things “right” the first time should mean less going back to fix things in the future, which will theoretically save time later. It’s just a very different development process than I’m used to, so it feels wrong to not have more done.</p>

<p>I’m hoping that the coming year will see at least a beta release of Readlebee so I can start getting some help from other developers plus feedback and ideas everyday users. I’m itching to have something to show for all my efforts, but no matter how hard I try, I can’t seem to rush this project. But maybe that’s a good thing in the end.</p>

<hr />

<p>If you’d like to keep track of Readlebee’s development process, feel free to star the code repository on <a href="https://gitlab.com/Alamantus/Readlebee">GitLab</a> or <a href="https://gitlab.com/Alamantus/Readlebee">GitHub</a> (mirror) to see how you can contribute and follow my <a href="https://floss.social/@Readlebee">Readlebee Mastodon account</a> to see occasional updates about my progress on the project as well as other <a href="https://en.wikipedia.org/wiki/Free_and_open-source_software">FLOSS</a>- and tech-related topics!</p>]]></content><author><name></name></author><category term="open source" /><category term="development" /><category term="FLOSS" /><category term="Readlebee" /><category term="GoodReads" /><category term="software" /><summary type="html"><![CDATA[About one year ago, give or take a few days, I started development on Readlebee after realizing that there is absolutely no alternative to the Amazon-owned GoodReads that does everything that GoodReads does. GoodReads is a social network for readers, a reading tracker, a wishlist manager for books, a way to stay informed about authors, a place to learn about books (usually by seeing what your friends have been reading), and more. There are a handful of apps that do one thing or another from that list, but nothing fully encompasses what GoodReads offers. Readlebee is my project that aims to fill that glaring hole as a real alternative to GoodReads.]]></summary></entry><entry><title type="html">Free Ideas</title><link href="https://robbie.antenesse.net/2018/05/01/free-ideas.html" rel="alternate" type="text/html" title="Free Ideas" /><published>2018-05-01T17:14:00+00:00</published><updated>2018-05-01T17:14:00+00:00</updated><id>https://robbie.antenesse.net/2018/05/01/free-ideas</id><content type="html" xml:base="https://robbie.antenesse.net/2018/05/01/free-ideas.html"><![CDATA[<p><strong>UPDATE August 12, 2018:</strong> Added an Ideas section to the site below Posts, where I will be adding ideas.</p>

<p>Today, I decided to end development on a board game I’ve been working on for about a year. It’s gone through many iterations, and even though I think the idea might be <em>interesting</em>, I don’t believe that the game can ever be <em>enjoyable</em>. While I usually think that’s totally fine to make games just because the idea is interesting (I’ve released my fair share of “interesting” game ideas), I feel like this case is different because I intended for it to be an enjoyable. As a general rule, I make games that I think I will enjoy, and after a lot of thought, I realized that even I wouldn’t enjoy my board game.</p>

<p>After making the decision, I’ve been looking back through some of my old game ideas, realizing that a lot of the ideas I love are far outside of my skillset to create effectively. The thought of simply throwing the ideas away is too painful, since I’ve already written so much about them, but I’ll probably never do anything with them. This dichotomy let me to the thought of publishing my game ideas—if I’m not gonna be able to do anything with my ideas, maybe someone else will! If I publish them under a Creative Commons license, then maybe I can work with someone who might want to use the ideas.</p>

<p>I’m under no illusions that anyone would ever <em>want</em> to use my ideas, let alone that anyone might actually ever discover them, but the thought of simply letting the ideas rot in Google Drive until the service goes offline is just as absurd. If my ideas could even have the potential of being used, then that would be very exciting to me. (It would also be nice to prove to myself that I’m not just sitting around doing nothing—I can look at my ideas cache and know that I’m at least thinking of things.)</p>

<p>So very soon, I’m going to be updating this website to make viewing my game ideas possible. I’m not sure exactly how I’ll style it yet, but as long as I have them visible, I think I’ll be happier.</p>

<p>I hope you enjoy the ideas as much as I do!</p>]]></content><author><name></name></author><category term="gamedev" /><category term="game development" /><category term="ideas" /><category term="creative commons" /><category term="video games" /><category term="board games" /><category term="thoughts" /><category term="writing" /><summary type="html"><![CDATA[UPDATE August 12, 2018: Added an Ideas section to the site below Posts, where I will be adding ideas.]]></summary></entry><entry><title type="html">Hosting Hobo</title><link href="https://robbie.antenesse.net/2018/03/22/hosting-hobo.html" rel="alternate" type="text/html" title="Hosting Hobo" /><published>2018-03-22T17:20:00+00:00</published><updated>2018-03-22T17:20:00+00:00</updated><id>https://robbie.antenesse.net/2018/03/22/hosting-hobo</id><content type="html" xml:base="https://robbie.antenesse.net/2018/03/22/hosting-hobo.html"><![CDATA[<p>My web hosting account expired a couple months, and it would have cost over $120 per year to renew it. This isn’t a terrible price for a full web host, but I really don’t want to spend the money for another shared hosting solution. So I researched how I could host my apps and websites for free using a number of different free services, and I landed on a number of good options.</p>

<p>For regular static HTML sites or apps that only use JavaScript, it’s hard to go wrong with <a href="https://pages.github.com/">GitHub Pages</a>. By default, GitHub Pages allows you to host either raw/pre-compiled HTML/CSS/JavaScript or a <a href="https://jekyllrb.com/">Jekyll</a> site, and this website is using GitHub Pages with a Jekyll setup—you can see the source code <a href="https://github.com/Alamantus/robbie.antenesse.net">here</a>, if you’d like! The one thing you need to be aware of is that only <em>public</em> code repositories are free on GitHub (actually, as of 2019 this isn’t true anymore!), which means that you have to be OK with the source code of anything you host being 100% visible and findable.</p>

<p>If you’d like both a less restrictive hosting setup than just Jekyll <em>and</em> access to free private repositories, <a href="https://about.gitlab.com/features/pages/">GitLab Pages</a> is a great option! GitLab pages are managed via their continuous integration (CI) service, which means that you can set up the CI loader to load <em>any</em> static site generator to process your code. For example, my <a href="https://guts.plus">GUTS+ website</a> is set up to use <a href="https://gohugo.io/">Hugo</a> by using this config to download the target version of the Hugo binary straight from GitHub:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">image</span><span class="pi">:</span> <span class="s">ubuntu</span>

<span class="na">before_script</span><span class="pi">:</span>
<span class="c1"># Download Hugo 0.37.1 release</span>
<span class="c1"># Reminder: Get the release asset id from https://api.github.com/repos/gohugoio/hugo/releases if you change versions</span>
<span class="pi">-</span> <span class="s">apt-get update</span>
<span class="pi">-</span> <span class="s">apt-get install -y curl git</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">curl</span><span class="nv"> </span><span class="s">-LJO</span><span class="nv"> </span><span class="s">-H</span><span class="nv"> </span><span class="s">'Accept:</span><span class="nv"> </span><span class="s">application/octet-stream'</span><span class="nv"> </span><span class="s">'https://api.github.com/repos/gohugoio/hugo/releases/assets/6437077'"</span>
<span class="pi">-</span> <span class="s">tar -xzf hugo_0.37.1_Linux-64bit.tar.gz</span>

<span class="na">pages</span><span class="pi">:</span>
  <span class="na">stage</span><span class="pi">:</span> <span class="s">deploy</span>
  <span class="na">script</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">./hugo --config config.yaml</span>
  <span class="na">artifacts</span><span class="pi">:</span>
    <span class="na">paths</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">public</span>
  <span class="na">only</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">master</span>
</code></pre></div></div>

<p>Or alternatively, this <a href="https://alamantus.gitlab.io/solarpunk-story/">story I’m attempting to write</a> uses a custom-built PHP static site generator that I made because I just needed something quick and easy to throw markdown text into a template:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">image</span><span class="pi">:</span> <span class="s">php:7.1.1</span>

<span class="na">pages</span><span class="pi">:</span>
  <span class="na">stage</span><span class="pi">:</span> <span class="s">deploy</span>
  <span class="na">script</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">php ./site-generator/generate.php</span>
  <span class="na">artifacts</span><span class="pi">:</span>
    <span class="na">paths</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">public</span>
  <span class="na">only</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">master</span>
</code></pre></div></div>

<p>Both GitHub and GitLab Pages allow you to add custom domain names to your hosted site, which can get a little tricky, but it’s well worth it! You can even use <a href="https://www.sslforfree.com/">SSL For Free</a> to generate <a href="http://letsencrypt.org/">Let’s Encrypt</a> SSL for your domains to you can get that coveted <code class="language-plaintext highlighter-rouge">https</code> before your domain name.</p>

<p>If you want something really advanced, <a href="https://www.heroku.com/">Heroku</a> offers free access to full server instances called “Dynos”. You need their Heroku command line app in order to interact with the service, but once you’re set up and you’ve followed a couple tutorials, you can get a full website or API or whatever you need going with just your code and a little bit of config setup! This is what I’m using to control the backend API for my game <a href="https://alamantus.itch.io/radio-silence">Radio Silence</a> along with a couple of other things.</p>

<p>GitHub and GitLab Pages are great options, but it can be a little hard if you don’t already use Git or don’t want to take the time to figure out how to set up GitLab Pages the way you want. If you want something a little more in the vein of traditional web hosting, I found a couple of services that offer 100% free web hosting with PHP and MySQL available with the only catch being a few restrictions and potentially slower websites. And also they’re generally a little bit shady…</p>

<p>Maybe I’ll finish this post someday. But that day is not today, so here’s what I’ve got so far.</p>]]></content><author><name></name></author><category term="hosting" /><category term="heroku" /><category term="github" /><category term="gitlab" /><category term="comments" /><category term="apis" /><summary type="html"><![CDATA[My web hosting account expired a couple months, and it would have cost over $120 per year to renew it. This isn’t a terrible price for a full web host, but I really don’t want to spend the money for another shared hosting solution. So I researched how I could host my apps and websites for free using a number of different free services, and I landed on a number of good options.]]></summary></entry><entry><title type="html">From Scratch</title><link href="https://robbie.antenesse.net/2017/12/15/from-scratch.html" rel="alternate" type="text/html" title="From Scratch" /><published>2017-12-15T15:30:00+00:00</published><updated>2017-12-15T15:30:00+00:00</updated><id>https://robbie.antenesse.net/2017/12/15/from-scratch</id><content type="html" xml:base="https://robbie.antenesse.net/2017/12/15/from-scratch.html"><![CDATA[<p>A few months ago, I <a href="/2017/07/20/incompatible-collaboration.html">posted about</a> the development team we hired at work and how their process was completely incompatible with ours. In October, we cut off their development process and took the code that they had finished on as our own. It took about a week to figure out how it was all put together and how everything worked, but I felt pretty confident that I could work with the test stuites and linters and other monolithic things they had in place for the app. The app was far from complete, but I knew I could finish it with very few issues!</p>

<p>Flash forward to a few days ago—every new feature I add is a huge victory because I have to make so many file changes and test updates just to get one small thing to display correctly, and it’s generally exhausting and not nice. They had so many checks and balances that are great for maybe a 10+ person team but that simply doesn’t work in our 2-person environment. The code is so over-egineered that nothing is easy to change, and that’s not a good thing for our company because sudden small changes are frequent and numerous.</p>

<p>My coworker and I were talking in whispers about how we wish we could just start from scratch to make something simpler. We had hired these other developers because I hadn’t been hired yet and they needed the extra hands, which more or less landed them in the same position as the previous Java cart—someone else wrote it so we had to depend on soeone else. The logic was that Javascript was easy enough to work with, so we wouldn’t be as tethered down! So we ended up landing on “no, we’ve come this far, we’ve just got to power through it” so we could just go the last bit of the way and get it ready for launch.</p>

<p>But that’s just not realistic.</p>

<p>That night, I started researching and found that not only was the cart not finished, the style framework they had chosen doesn’t even support the old browser versions we wanted to support! I did some digging and found that my favorite style framework, <a href="https://bulma.io">Bulma</a>, ended up being more compatible if I used a <a href="https://github.com/jonathantneal/flexibility/releases/tag/v1.0.6">specific version</a> of <a href="https://jonathantneal.github.io/flexibility/">this Flexbox polyfill</a>. So the next day, I started secretly building the cart front end from scratch using the nice, simple <a href="https://choo.io/">choo framework</a> and Bulma. After a day, I had already completed the basic features of adding items to the cart from our API and displaying them.</p>

<p>After a long meeting about the cart’s status yesterday, my coworker comes out and asks if I wanted to simplify the over-engineered code of the cart at all, and I said yes, of course. “Do you want to just try ripping out the complex stuff or just start from scratch”. I said I thought it might be easier to start from scratch and go from there, so he told me that makes sense and that we could just try going in that direction. At which point I let out a sigh of relief and showed him my 2-day progress.</p>

<p>I know it’s not going to be easy starting over, but at least I’ll be a lot happier working with it.</p>]]></content><author><name></name></author><category term="javascript" /><category term="framework" /><category term="react" /><category term="redux" /><category term="choo" /><category term="choojs" /><category term="bulma" /><category term="styles" /><summary type="html"><![CDATA[A few months ago, I posted about the development team we hired at work and how their process was completely incompatible with ours. In October, we cut off their development process and took the code that they had finished on as our own. It took about a week to figure out how it was all put together and how everything worked, but I felt pretty confident that I could work with the test stuites and linters and other monolithic things they had in place for the app. The app was far from complete, but I knew I could finish it with very few issues!]]></summary></entry><entry><title type="html">PHP PDO MySQL Connection for UTF-8</title><link href="https://robbie.antenesse.net/2017/09/29/mysql-php-pdo-connection.html" rel="alternate" type="text/html" title="PHP PDO MySQL Connection for UTF-8" /><published>2017-09-29T17:48:00+00:00</published><updated>2017-09-29T17:48:00+00:00</updated><id>https://robbie.antenesse.net/2017/09/29/mysql-php-pdo-connection</id><content type="html" xml:base="https://robbie.antenesse.net/2017/09/29/mysql-php-pdo-connection.html"><![CDATA[<p><a href="#tldr">Skip to the TL;DR</a></p>

<p>Yesterday, I spent two hours trying to solve a problem I was having with an API I had built to store our products in a unified place. Every single product that I had ever tried to grab from the API had succeeded, but as I was going through the database to update some values, I came across one product that would not load. No matter what I tried, no data was returned and no errors were logged. I was baffled.</p>

<p>I went through the code and was able to narrow it down to one problem method in the API’s class, but when I tried to run that same method in isolation on the product that was failing, it worked fine! After trying to narrow it down even more, I finally decided to try looking at the contents of the product. In our product database, we have both regular products <em>and</em> packages, which can contain any number of other products and/or packages. So I checked every sub-package in the package I was having trouble with, and sure enough, one of the packages inside was also not loading.</p>

<p>I kept digging, and about 5 packages deep, I found the product that was the culprit. When I looked at the product’s data in the MySQL database, I discovered this: <code class="language-plaintext highlighter-rouge">Gabriel García Márquez</code>. I figured that for some reason, these <code class="language-plaintext highlighter-rouge">í</code> and <code class="language-plaintext highlighter-rouge">á</code> Unicode characters <em>had</em> to be the problem. So I replaced them with their non-accented forms, and just as I suspected, every package loaded just fine. For some reason, my PDO connection was unable to comprehend the Unicode that I know actually does work just fine.</p>

<p>Obviously, however, I don’t want to have the data be wrong just because some programming language can’t handle it, so I went ahead and updated the database to contain the accented characters using PDO. Once I did it that way, it was able to load the Unicode without any trouble! But when I looked in the MySQL table again, I discovered this mostrosity: <code class="language-plaintext highlighter-rouge">Gabriel GarcÃ­a MÃ¡rquez</code>.</p>

<p>WHAT!?</p>

<p>Our server, MySQL database and tables, and PHP config were all set to use the <code class="language-plaintext highlighter-rouge">utf-8</code> charset to support Unicode characters, but for some reason, the PDO library is translating the Unicode characters into <em>other Unicode characters</em> in order to store them and re-translating them again when it pulls the data!</p>

<p>WHY</p>

<p>So I went on a Google hunt.</p>

<p>After finding a lot of issues where people had their charsets set to <code class="language-plaintext highlighter-rouge">latin</code> or some other non-unicode set, I finally discovered <a href="https://stackoverflow.com/questions/4475548/pdo-mysql-and-broken-utf-8-encoding/21373793">this StackOverflow article</a> where someone was having a similar problem. The marked answer from 2011 includes an apparent workaround that includes PDO connection options <em>inside</em> the connection call:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$pdo</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PDO</span><span class="p">(</span> 
    <span class="s1">'mysql:host=hostname;dbname=defaultDbName'</span><span class="p">,</span> 
    <span class="s1">'username'</span><span class="p">,</span> 
    <span class="s1">'password'</span><span class="p">,</span> 
    <span class="k">array</span><span class="p">(</span><span class="no">PDO</span><span class="o">::</span><span class="no">MYSQL_ATTR_INIT_COMMAND</span> <span class="o">=&gt;</span> <span class="s2">"SET NAMES utf8"</span><span class="p">)</span> 
<span class="p">);</span> 
</code></pre></div></div>

<p>But the <a href="https://stackoverflow.com/a/21373793">next answer down</a> from <a href="https://stackoverflow.com/users/2157640/palec">Palec</a>, with only 31 upvotes, contains the actual, correct answer—or at least, the correct answer… <em>since PHP 5.3.6</em>:</p>

<blockquote>
  <p>You have to set correct charset for the connection. <a href="http://php.net/manual/en/ref.pdo-mysql.connection.php">Add <code class="language-plaintext highlighter-rouge">charset=utf8</code> option to the DSN</a>. <em><strong>(This is MySQL-specific!)</strong></em></p>
</blockquote>

<p><small>(Emphasis added)</small></p>

<p>When going to his link to the PHP documentation, I discovered this:</p>

<blockquote>
  <p><em>charset</em></p>
  <blockquote>
    <p>The character set. See the character set concepts documentation for more information.</p>

    <p>Prior to PHP 5.3.6, this element was silently ignored.</p>
  </blockquote>
</blockquote>

<p>WHYYYY</p>

<p>When looking at the regular <a href="http://php.net/manual/en/pdo.connections.php">PDO connections page</a>, where every Google search for “PHP PDO Connection” points you, you see nothing but this example, which doesn’t even reveal the fact that you can add PDO options to the connection:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$dbh</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PDO</span><span class="p">(</span><span class="s1">'mysql:host=localhost;dbname=test'</span><span class="p">,</span> <span class="nv">$user</span><span class="p">,</span> <span class="nv">$pass</span><span class="p">);</span>
</code></pre></div></div>

<p>But lo and behold, searching the page for “charset” yields a single comment at the very bottom of the page, downvoted to -3, is <a href="http://php.net/manual/en/pdo.connections.php#118267">the correct answer</a> about specifying the <code class="language-plaintext highlighter-rouge">charset</code> option in the DSN. Why is it downvoted? Why is it so hard to find this charset information? WHY does the charset need to be specified in the connection when EVERYTHING leading up to it has already specified the charset to use??</p>

<p>I have no idea.</p>

<p>In my opinion, the connection should default to the same charset of the database that is being connected to, because that just <em>makes sense</em>.</p>

<p>Anyway, I just want the world to know that the <em>correct</em> way to connect to a MySQL database with any PHP version since 5.3.6 is:</p>

<h3 id="tldr">TL;DR</h3>
<p>If you want to have a clean database with correct Unicode characters, always be sure to specify the <code class="language-plaintext highlighter-rouge">charset</code> you wish to connect with. You can do this with PHP’s PDO as follows:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$pdo</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PDO</span><span class="p">(</span>
    <span class="s1">'mysql:host=hostname;dbname=database;charset=utf8'</span><span class="p">,</span>
    <span class="s1">'username'</span><span class="p">,</span>
    <span class="s1">'password'</span>
<span class="p">);</span>
</code></pre></div></div>

<p>I hope this helps someone the way it surely would have helped me!</p>]]></content><author><name></name></author><category term="php" /><category term="pdo" /><category term="mysql" /><category term="connection" /><category term="unicode" /><category term="utf-8" /><category term="utf8" /><summary type="html"><![CDATA[Skip to the TL;DR]]></summary></entry><entry><title type="html">Incompatible Collaboration</title><link href="https://robbie.antenesse.net/2017/07/20/incompatible-collaboration.html" rel="alternate" type="text/html" title="Incompatible Collaboration" /><published>2017-07-20T17:48:00+00:00</published><updated>2017-07-20T17:48:00+00:00</updated><id>https://robbie.antenesse.net/2017/07/20/incompatible-collaboration</id><content type="html" xml:base="https://robbie.antenesse.net/2017/07/20/incompatible-collaboration.html"><![CDATA[<p>At the end of last year, we hired a development team to build us a new shopping cart to replace our current one. Our current cart worked fine, but is very slow and was written in Java, and thus was not able to be edited or modified from a source-code level because neither me nor my coworker know Java (and we don’t want to either). The new cart is being written in JavaScript using <a href="https://facebook.github.io/react/">ReactJS</a>+<a href="http://redux.js.org/">Redux</a>+<a href="http://reactivex.io/rxjs/">RxJS</a> for the front end and <a href="https://feathersjs.com/">Feathers</a> for the backend. This is good because I already know React, and I can learn the other technologies easily enough, given time. About a month ago, I was added to the daily meeting schedule of this dev team and have been working with them almost daily.</p>

<p>It’s been difficult for us to work with them, though, because they have a larger team than us, and thus use a more structured approach to development, namely Agile. Since my coworker and I are just a two-man team, we don’t have a structure like that because we can simply work to get things done quickly whenever we want. This lack of structure and order has clearly been irritating to the other dev team, but Agile would only slow us down.</p>

<p>Fortunately it’s not too much of a problem, but it has led to some holdups. Earlier in the development timeline, they were waiting on us to deliver an API for our until-recently nonexistent Product Database so they could pull product data, but we were trying to figure out a sustainable way to build product packages in our database so they could be maintained better than they currently were. It took a long time, but we finally got the system up and running for them, and they were able to resume development. The frustrating thing was that it felt like they weren’t doing other things that clearly needed doing that could be done without the product database being finished.</p>

<p>Unfortunately, that attitude and feeling is mainly because we don’t use their development structure—for them, it takes a lot of extra planning and work to even prepare to do things where my coworker and I would be able to simply start working on things and figure it out as we went! We’re on a speedboat while they’re on a battleship, and there are good things about each. It’s been difficult and tricky, but we’ve finally found a way to work together. They’re able to work on other things while we prepare backend and API tools for them to use when they reach where we are. Our speed allows us to prepare for their arrival, and so far it seems to be working out nicely!</p>

<p>I just hope that it’s enough to get them to where we need them to be by October when we finish working with them and take over their project ourselves… Time will tell, I guess.</p>]]></content><author><name></name></author><category term="agile" /><category term="api" /><category term="collaboration" /><category term="collab" /><category term="communication" /><category term="dev" /><summary type="html"><![CDATA[At the end of last year, we hired a development team to build us a new shopping cart to replace our current one. Our current cart worked fine, but is very slow and was written in Java, and thus was not able to be edited or modified from a source-code level because neither me nor my coworker know Java (and we don’t want to either). The new cart is being written in JavaScript using ReactJS+Redux+RxJS for the front end and Feathers for the backend. This is good because I already know React, and I can learn the other technologies easily enough, given time. About a month ago, I was added to the daily meeting schedule of this dev team and have been working with them almost daily.]]></summary></entry><entry><title type="html">Moving Day</title><link href="https://robbie.antenesse.net/2017/07/01/moving-day.html" rel="alternate" type="text/html" title="Moving Day" /><published>2017-07-01T20:00:00+00:00</published><updated>2017-07-01T20:00:00+00:00</updated><id>https://robbie.antenesse.net/2017/07/01/moving-day</id><content type="html" xml:base="https://robbie.antenesse.net/2017/07/01/moving-day.html"><![CDATA[<p>Yesterday, my wife and I closed on our new house. That’s right, it’s official: we have a mortgage! And also a nice house to live in! We have been living in apartments for 5 years, and my new job has finally allowed us to move up to American homeownership. As stressful as having a mortgage is, it is truly delightful to have a place to call our own! We even have a yard for the dogs to play in, plus the previous owners left a ton of yard equipment and other appliances for us so we don’t have to buy our own!</p>

<p>Today, a bunch of our friends helped us move out of our third-floor apartment, and I can’t express how helpful it was. It saved us a boatload of money and it made the whole process go incredibly fast! We had everything out of the apartment and into the house in about 4 or 5 hours! Amazing! We got a 16-foot moving truck from Budget, and we were able to fit everything in that truck and some of the more delicate stuff into a few of our friends’ cars. It ended up being a lot of fun, too, because we all hung out afterward and ate pizza and chatted.</p>

<p>Some friends stayed even later and went to dinner with us! It was amazing that everything went off without a hitch, and I am so glad.</p>]]></content><author><name></name></author><category term="moving" /><category term="house" /><category term="homeownership" /><category term="mortgage" /><category term="friends" /><summary type="html"><![CDATA[Yesterday, my wife and I closed on our new house. That’s right, it’s official: we have a mortgage! And also a nice house to live in! We have been living in apartments for 5 years, and my new job has finally allowed us to move up to American homeownership. As stressful as having a mortgage is, it is truly delightful to have a place to call our own! We even have a yard for the dogs to play in, plus the previous owners left a ton of yard equipment and other appliances for us so we don’t have to buy our own!]]></summary></entry></feed>