• Emacs in the Browser Using Codespaces

    Using codespaces, you can open a web-based VSCode session, open a terminal and install emacs.

    sudo add-apt-repository ppa:kelleyk/emacs && sudo apt install emacs27
    

    Then set the option for using the option key as meta in Settings.

    Install dependencies for vterm:

    sudo apt install cmake libtool libtool-bin
    

    Then clone my .emacs.d:

    git clone https://github.com/alexkehayias/emacs.d && mv emacs.d .emacs.d
    

    Then open emacs (which installs packages with use-package):

    emacs
    

    Now there is a full emacs with my config and a vterm running in the browser using GitHub Codespaces.

    Other tweaks

    • Add your ssh key so you can push/pull to a remote git repository.
    • Fix M-BKSPC not working like it does in macOS
    • Fix magit can’t open the commit dialogue
    • Install other OS dependencies needed for writing (e.g. efm-langserver, aspell)
    • Go full screen CTRL-CMD-P (there’s still no way of removing the top heading, but it’s close to fully full screen)

    Alternatives

    It’s possible to run a Linux container and run it through the browser using Kasm (an easier remote desktop kindof thing). It can be customize to launch emacs directly. I haven’t tried it but seems promising for self-hosting and running privately behind tailscale.


  • There Are Surprisingly Few Product Engineers

    Product engineers solve user problems, but why are there so few of them?

    As recently as 1999, The Inmates are Running the Asylum told the tech industry that engineers were the reason websites and products were bad. Engineers were not trusted with knowing about users and their problems and yet, they are blamed for poor solutions to solving them.

    The way we organize engineering doesn’t help. As companies grow, engineers specialize and are closely managed by project managers and product managers. It’s difficult to build anything significant that requires action across teams and departments.

    Altogether that means we lack the trust in engineers to understand users and the experience pool to cultivate a strong product engineering discipline. Status quo preserving behavior will continue to keep engineering as they are, which doesn’t bode well for users.

    See also:


  • SQLite Workaround for Find_in_set

    SQLite doesn’t have a FIND_IN_SET operator to test whether or not a string exists in set value. To work around it, you can do string comparison using LIKE.

    However, to handle all cases of a string in a comma joined array of strings (e.g. a collection of tags related to a post aggregated using GROUP_CONCAT) you need to prepare the value by adding preceding and trailing commas.

    For example:

    select * from (select post_id, group_concat(tags.tag) as alltags from tags group by tags.post_id) where ','||alltags||',' like '%,food,%';
    

    This returns the correct result whether the food tag was first, last, or somewhere in the middle.


  • The Downside of Using Org-Id Links in Org-Roam

    In org-roam v2, a new requirement was added for all notes to have an org ID. This has a few notable downsides.

    It duplicates unique identifiers. Notes already have a unique ID, the file name which is enforced to be unique by the file system. Changing a file name should be equivalent to changing a unique IDβ€”you probably don’t want to do that (and it’s a sign you should probably delete it and start a new note).

    It clutters the note. The preamble alone is a minimum of 4 lines compared to 1 before due to the addition of the :PROPERTIES: drawer.

    It hurts portability. Previously, org-roam files used to ‘just work’ in Working Copy, including links to other files. It doesn’t anymore because of ID links. It also further locks the implementation in with org-mode which is lacking parsers to make it more ubiquitous (go-org is a good option, but many more are started and abandoned).


  • SUTA Dumping

    SUTA dumping is fraudulent arbitrage of State Unemployment Tax where fraud-y PEOs put employees from high insurance rate companies into a new entity with a low insurance rate and pocketed the difference. This was made illegal by the SUTA Dumping Protection Act of 2004 which is why you typically get asked questions when signing up for payroll whether or not you are trying to do this.


  • Notion Rollup Count by Month

    Notion has limited support for counting rows in a table using rollups. Unfortunately rollups don’t allow you to count by any other grouping (like month) out of the box (ala group by in sql). Instead you need to prepare your database by normalizing the data, extracting grouping data using a formula, and then modifying the rollup criteria.

    Normalizing the field you want to group by

    Let’s say you have a list of tasks that have different types and you want to count how many were completed by month.

    You might start with a single database that looks like this (where Task type is a select column).

    Task name Task type Date completed
    Todo 1 Writing 2021-07-05
    Todo 2 Chores 2021-07-12
    Todo 3 Reading 2021-07-18
    Todo 4 Reading 2021-08-02

    Now you want to count but a rollup field won’t work. You need normalize the data by changing Task type into a relational column that points to another database.

    Task type name
    Writing
    Chores
    Reading

    Now change the Task type column from a select column to a relational column that points to the Task Type database.

    To count the number of tasks by type, add a rollup column where the relation is the Tasks database, the property is Task name, and choose count all.

    Task type name Count
    Writing 1
    Chores 1
    Reading 2

    Now there is a count for each task type. However, we need to add a few more columns if we want to count by month.

    Extract the month using a formula

    Add a formula column named ‘Month’ to the Tasks database to extract the month from the date completed.

    if(empty(prop("Date completed")), "", formatDate(prop("Date completed"), "YYYY-MM"))
    

    Now you will see this:

    Task name Task type Date completed Month
    Todo 1 Writing 2021-07-05 2021-07
    Todo 2 Chores 2021-07-12 2021-07
    Todo 3 Reading 2021-07-18 2021-07
    Todo 4 Reading 2021-08-02 2021-08

    Counting by task type by month

    This is the tricky part needed to work around the limitations of rollups. Add another formula column named ‘July 2021’ to the Tasks database that will indicate if the task was completed in that month.

    Note: You will need to add a column for each month because rollups don’t allow grouping. Yes it’s very manual, but it works.

    prop("Month") == "2021-07"
    
    Task name Task type Date completed Month July 2021
    Todo 1 Writing 2021-07-05 2021-07 [βœ“]
    Todo 2 Chores 2021-07-12 2021-07 [βœ“]
    Todo 3 Reading 2021-07-18 2021-07 [βœ“]
    Todo 4 Reading 2021-08-02 2021-08 [ ]

    Now in the Task type database, we can count the number of tasks completed in July by adding rollup column (let’s name it ‘July’) where the relation is the Tasks database, the property is ‘July 2021’, and choose count ‘Checked’.

    The result should look like this:

    Task type name Count July
    Writing 1 1
    Chores 1 1
    Reading 2 1

    Now we have a count by type by month! You can follow this pattern to add more rollups for each month.


  • Engineering as Delivery or Engineering as Product

    Organizations tend to set up their engineering organization in one of two ways. Either engineering is considered the delivery mechanism for the company’s plans or engineering is considered to be leading the product. Many organizational problems arise from mismatches of expectations between these two camps.

    Engineering as delivery is first and foremost optimizing for predictable schedules. Work needs to be broken down into specified chunks and distributed to engineers. Teams are coordinated via a project management function. Promotions happen because of a track record of delivering on time.

    Engineering as product is first and foremost concerned with solving user problems. Work needs to be shaped and discovered by having a deep understanding of their usersβ€”teams often talk to users directly. Roadmaps evolve as understanding of the user, the problem, and the solution evolves. Promotions happen because of consistent ability to make good product decisions and ship features that users love.

    Issues arise when expectations are not clear. For example, a team at an engineering as delivery company that comes up with a product idea will likely get dismissed because it won’t fit into the schedule.


  • Jump to a Random Page Using a Static Site Generator

    To implement a ‘jump to random page’ in a static site (like this website) can be done using a template that loads a JavaScript function to redirect the browser. Static site generators typically have a way of iterating over all pages. You can use this same functionality to generate the random page function.

    For example, using hugo:

    <!--
         This is a way of redirecting the user to a random note. This requires
         a full index of all notes and so it's on its own page. To take a user
         to a random note, simply link to this page.
    -->
    <script>
     const pages = [{{ range .Site.AllPages }}{{ if not .IsHome }}"{{ .Permalink }}",{{ end }}
       {{ end }}
     ];
     let random_idx = Math.floor(Math.random() * (pages.length - 1));
     window.location = pages[random_idx];
    </script>
    {{ end }}
    

    See also:


  • Space Exploration Led to Earth Day

    The US space program led to the first color photographs of the Earth taken from the Moon in 1969. No one had ever seen it from so far away and it moved people. In fact, it resulted in a new conservation movement which eventually led to Earth Day in 1970.

    Conservationists and environmental activists at the time based the space program as being frivolous (“we need to solve problems here on Earth first”). However, the space program has done more to further their goals than any other single act could have.

    See also:


  • Pickup-Only Stores Are the Future for Fast Food and Drinks

    In Manhattan, I found a Starbucks that was pick-up only and you had to order online. It had no seating, just a counter to pick up your order. It didn’t even have a cash register.

    In the COVID-19 world, this is the future of fast-food. No one wants to stand around while their order is being made on the spot (for health reasons and boredom). We’ve all been trained to order food online. Pick-up only stores makes perfect sense.