Exclusive: unveiling the elusive sight of my foot after a delightful strut through the enchanting Tiveden! 🌲

    I love the woods of Tiveden, which lie just half an hour from our cabin. It’s like entering the world of John Bauer. You expect to see a magical being around every giant stone.

    @sod and I walked for hours and relished the April sun. A fabulous Friday. A great start to the weekend.

    A couple sitting outdoors, sipping coffee from thermos mugs. Only their arms and legs are visible in the frame. The view over a lake is magnificent.

    So, @sannalund surprised me with a gift-for-no-special-reason the other day (aren’t those the best kind of gifts?): Moonbound by Jonathan Fetter-Vorm. Looks stellar! Can’t wait to read it. 📚

    A gritty illustrated comic book cover, featuring the moon on the bottom and an upside-down astronaut on the top.

    It’s #FeedReaderFriday again! 🥳 Rachel Simone Weil makes wonderful art like Hello Kitty Land (a Super Mario Bros. ROM-hack) and connectedNES (a Wi-Fi “modem” for the NES). She also curates the FEMICOM Museum. Follow her blog and Mastodon feed (they are RSS too).

    Six years ago, I built a WiFi "modem" and live Twitter feed cartridge for the Nintendo NES. With Twitter's relevance on the decline, what other kind of live text feed would you like to see on the NES? Reply here with your ideas—maybe I'll port one of them to ConnectedNES!

    It’s Tuesday evening. I just had coffee, emptied my feed reader, and learned that:

    The 2023 spring issue of the html review is out, and I’m eager to dive into it! 🫨

    To me, one of the more unbelievable scenes in Tetris is when Henk asks

    This game is programmed in C, yeah?

    gets an affirmative answer, goes on to produce some original 2-bit graphics, and ports Tetris to the Game Boy in like 10 seconds.

    There are C compilers for the Game Boy today, but back then, the games were written in assembly for the Sharp LR35902. Of course, I wasn’t a programmer at Nintendo R&D1 in the 80s – I wish! – but I did have some fun reverse engineering Tetris for Game Boy to get rid of Bullet-Proof Software’s copyright screen. 🤓

    The movie? It was a fun ride. 🍿🕹️

    A frame from the movie Tetris. Henk stares at a prototype Game Boy. The subtitles says: this game is programmed in C, yeah?

    🔭 Search Space is out of beta! 🥂 New in version 1.0.0:

    • 🎙️ Transcripts can be indexed!
    • 🪚 Post content in search results is truncated at 300 characters.
    • 🗂️ Indexing replies and transcripts are optional.
    • 👋 The greeting text (Welcome to Search Space …) can be edited in the settings.

    One wikipedian had fun with today’s Did you know … section. 🙃 Love it! Via Molly White.

    Screenshot from Wikipedia. Did you know … that after one of Piet Mondrian’s paintings (shown) was discovered to have been hanging upside down for decades, the museum left it as is? The photo of the painting and the following text is presented upside down by the Wikipedia editor: New York City I (1941), upside down.

    Remember! There’s no such thing as having too many book-related newsletter subscriptions. If you’re a fan of sci-fi and/or horror, subscribe to Frights, Flights, and Literary Delights. Curated by @sannalund and yours truly.

    Or read our first issue on the web. 📚

    In a fantastical black and white illustration, a person sits on a hill, reading, aided by the moonlight. In the stars above, a hideous, Kaiju-like creature manifests. Is it for real or the reader’s imagination?

    Stil frame from a movie. A man is looking out a window at the woman next door, looking out her window. They’re having a conversation.

    – I do a nude scene. Do you want to see it?
    – Huh? Did I say yes?
    – You didn’t say anything.
    – I meant yes, my mouth didn’t speak.

    🤩 From the trailer for Wes Anderson’s Asteroid City.

    I’ve just rolled out a new version of my ✍️ Reply by Email plug-in. Now with email obfuscation to combat email harvesting & keep your inbox safer! 🛡️

    Remember, no solution is 100% foolproof against web scraping spam bots. For best protection, combine with a service like Apple’s Hide My Email!

    📚 Great advice from Oliver Burkeman:

    [Treat] your “to read” pile like a river (a stream that flows past you, and from which you pluck a few choice items, here and there) instead of a bucket (which demands that you empty it). After all, you presumably don’t feel overwhelmed by all the unread books in the British Library – and not because there aren’t an overwhelming number of them, but because it never occurred to you that it might be your job to get through them all.

    For those of you using my 🦄 Magic Preview plug-in in Safari, force clicking the 🔍 Preview link gives you a quick preview of what your post will look like. Works on handheld devices as well, just tap and hold the link to see a preview without opening the page. Like magic! ✨

    A text editor in Safari is partially obscured by a page preview. The preview is a styled version of the text in the text editor.

    Instead of manually adjusting hundreds of Markdown formatted microblog posts when migrating my blog from Jekyll to Hugo (Micro.blog), I asked ChatGPT to do it for me. How did it go?

    👀 Read How ChatGPT made my migration from Jekyll to Hugo a breeze to find out.

    How ChatGPT made my migration from Jekyll to Hugo a breeze

    The other day, after running my blog on Jekyll for 13 years, I switched to Hugo. Moving from one static site generator to another involves a lot of things to take care of. Among them was this directory with hundreds of microblog posts written in Markdown. The posts published dates encoded as Unix timestamps in the filenames: 1665322487.md etc.

    Micro.blog hosts my new Hugo blog, and their import tools do not support Unix timestamps in file names. Instead, publish dates should be put in the YAML front matter, as follows:

    1
    2
    3
    4
    
    ---
    date: 2022-10-09 13:34
    ---
    Had a great day in the forest with friends. Grilling sausages, roasting marshmallows, and taking a short hike. Hair smells like a campfire now. 🥰
    

    So, I basically had two options. I could manually fix this by snatching the timestamp from the filename, converting it to the right date-time format, and pasting that into the file’s YAML front matter. Rinse and repeat. Hundreds of times.

    Or I could just write a script that automated the process for me. As a programmer, this is what I usually do. Even when it won’t actually save me any time in the end. 😅

    But, instead, I tried a third option and asked ChatGPT to do it for me. I’ve played a lot with the chatbot and had it generate code for me in the past. But just toy examples, not, you know, anything useful in the real world. This task, though, seemed like a perfect fit. Easy to define and limited in scope. So, without further ado, here’s me and ChatGPT programming away. Complete with lazy typing and spelling mistakes (mostly mine).

    My pair programming session with ChatGPT (GPT-4)

    Sven: Write a Ruby script that loops thorough all files in the directory provided and adds the filename to yaml frontmatter without extension.

    For example the file named 1676537577.md should end up like this in the frontmatter:

    -–
    date: 1676537577
    -–

    ChatGPT: Here is a Ruby script that loops through all files in a specified directory and adds the filename without the extension as the date field in the YAML frontmatter.

    ruby

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    require 'yaml'
    require 'fileutils'
    
    def process_file(file)
      frontmatter = { 'date' => File.basename(file, '.*') }
      content = File.read(file)
      content.sub!(/---\s*\n.*?---\s*\n/m, '') # Remove existing frontmatter if present
      File.open(file, 'w') do |f|
        f.write(YAML.dump(frontmatter) + "---\n" + content)
      end
    end
    
    dir = ARGV[0] || '.'
    
    raise "Directory #{dir} not found" unless Dir.exist?(dir)
    
    Dir.glob(File.join(dir, '*.md')) do |file|
      process_file(file)
      puts "Processed: #{file}"
    end
    
    puts 'All files have been processed.'
    

    Save this script as add_date_to_frontmatter.rb and run it with the desired directory path as an argument:

    bash

    1
    
    ruby add_date_to_frontmatter.rb /path/to/directory
    

    If no argument is provided, the script will default to the current working directory. This script assumes that your files have the .md extension.

    Sven: Great! Now make is so that the file name (without extension) is processed as a unix timestamp and converted to a iso-8601 formatted date and time instead.

    ChatGPT: To modify the script to process the filename as a UNIX timestamp and convert it to an ISO-8601 formatted date and time, you can use Ruby’s built-in Time class.

    Here’s the updated script:

    ruby

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    require 'yaml'
    require 'fileutils'
    
    def process_file(file)
      filename_without_ext = File.basename(file, '.*')
      timestamp = filename_without_ext.to_i
      iso_date = Time.at(timestamp).utc.iso8601
    
      frontmatter = { 'date' => iso_date }
      content = File.read(file)
      content.sub!(/---\s*\n.*?---\s*\n/m, '') # Remove existing frontmatter if present
      File.open(file, 'w') do |f|
        f.write(YAML.dump(frontmatter) + "---\n" + content)
      end
    end
    
    dir = ARGV[0] || '.'
    
    raise "Directory #{dir} not found" unless Dir.exist?(dir)
    
    Dir.glob(File.join(dir, '*.md')) do |file|
      process_file(file)
      puts "Processed: #{file}"
    end
    
    puts 'All files have been processed.'
    

    Save this script as add_iso_date_to_frontmatter.rb and run it with the desired directory path as an argument:

    bash

    1
    
    ruby add_iso_date_to_frontmatter.rb /path/to/directory
    

    If no argument is provided, the script will default to the current working directory. This script assumes that your files have the .md extension.

    Sven: Okay, I changed my mind, instead of ISO-8601 make it on the format yyyy-mm-dd hh:mm. For example 2020-03-28 22:10.

    ChatGPT: Sure, you can modify the script to format the date and time as “yyyy-mm-dd hh:mm” by using Ruby’s strftime method. Here’s the updated script:

    ruby

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    require 'yaml'
    require 'fileutils'
    
    def process_file(file)
      filename_without_ext = File.basename(file, '.*')
      timestamp = filename_without_ext.to_i
      formatted_date = Time.at(timestamp).utc.strftime('%Y-%m-%d %H:%M')
    
      frontmatter = { 'date' => formatted_date }
      content = File.read(file)
      content.sub!(/---\s*\n.*?---\s*\n/m, '') # Remove existing frontmatter if present
      File.open(file, 'w') do |f|
        f.write(YAML.dump(frontmatter) + "---\n" + content)
      end
    end
    
    dir = ARGV[0] || '.'
    
    raise "Directory #{dir} not found" unless Dir.exist?(dir)
    
    Dir.glob(File.join(dir, '*.md')) do |file|
      process_file(file)
      puts "Processed: #{file}"
    end
    
    puts 'All files have been processed.'
    

    Save this script as add_formatted_date_to_frontmatter.rb and run it with the desired directory path as an argument:

    bash

    1
    
    ruby add_formatted_date_to_frontmatter.rb /path/to/directory
    

    If no argument is provided, the script will default to the current working directory. This scrit assumes that your files have the .md extension.

    Closing thoughts

    The final output from ChatGPT just worked and successfully completed the task at hand. That’s pretty cool! Is the implementation perfect? No, but it gets the job done. For a one-off script, I can’t complain.

    The resulting program is short, and I could’ve come up with a solution and typed it out myself. But it’s fascinating to program in plain English. And I doubt I would have come up with the solution as fast as ChatGPT. I didn’t time our session, but estimate it took ChatGPT about a minute to generate each answer. So, from my first prompt to a job well done, it took no more than five minutes.

    By the way, the first draft of the program ran fine as well. In the second draft, ChatGPT didn’t require 'time' at the top, but after human intervention, that version also ran correctly.

    So, March 22, 2023 was the first time I paired programmed with a large language model to successfully solve a real world problem. And I’m certain we’ll team up again in the future to solve even bigger and more complicated problems.

    Okay, everybody, today is a big day because my bff/gf/wife @sannalund just joined Micro.blog! She’s way cooler, smarter, funnier, and definitely prettier than me, so give her a follow and a warm welcome. 🥳

    We’re doing wine, pizza, and newslettering again. If you’re at all interested in books – especially in the horror and sci-fi genres – you should stop what you’re doing right now and sign up for Frights, Flights, and Literary Delights. The first issue will arrive tomorrow.

    A hand holding an opened wine bottle. It's totally wrapped in paper, lovingly illustrated with leaves, that also act as the bottle's label. The label reads Villarini Nero d’Avola Sicilia, organic wine.

    A gpt-3.5-turbo powered poet-clock. Cute idea! Matt goes into some details in his post My new job is AI sommelier and I detect the bouquet of progress.

    An e-ink screen on a shelf with the text: eleven-thirty eight, don't hesitate, Time to savor life, don't be late.

    I made an AI clock for my bookshelves! It composes a new poem every minute using ChatGPT and mysteriously has this enthusiastic vibe which I am totally into

    Here’s 3 × Game Boy (again):

    A person holds a Game Boy with a camera accessory attached. The screen (acting as a viewfinder) shows a bird chilling in the water.

    Gameboy Camera, a lifestyle choice . . . . . . . . . 😂😂😂

    Bill Gates on The Age of AI has begun:

    First, we should try to balance fears about the downsides of AI—which are understandable and valid—with its ability to improve people’s lives. …

    Second, market forces won’t naturally produce AI products and services that help the poorest. The opposite is more likely. …

    Finally, we should keep in mind that we’re only at the beginning of what AI can accomplish. Whatever limitations it has today will be gone before we know it. …

    The Age of AI is filled with opportunities and responsibilities.

    Despite some slippery spots, we had a lovely Sunday stroll at Dumme mosse.

    A foggy winter day, a deserted planked trail goes of into the wetlands.

    Then

    Updated from my home in Jönköping.

    💚 Sanna and I are having a blast furbishing up our study. The room is now very green, cozy, and inviting! We’re still ticking stuff off the to-do list, though. Those baseboards won’t install themselves. 😅

    🤖 I’m deep down the large language model rabbit hole. Exploring, poking around, learning about, and teaming up with them. I see a lot of potential! But also risks. I might come around to jotting down some of my thoughts…

    📚 I just read The Three-Body Problem (三体) by Liu Cixin (刘慈欣). This has been on my to-read list for a long time, and now I wonder why I didn’t pick it up sooner. I’ll definitely read the next book in this series, but first: The Kaiju Preservation Society by John Scalzi as a palate cleanser.

    📺 When it comes to tv, I’m fanboying all over The Last of Us. Craig and Neil don’t mind switching things up, and I love it. Pedro Pascal and Bella Ramsey are just perfect. Great show!

    (This page is inspired by Derek Sivers’s now page idea. You should make one, too.)

    This post is just a test to see if we can abuse the newly introduced 600 characters limit for quotes, without actually, you know, quoting anything. Maybe we can! As I write this, I don’t know, and I have to keep typing to reach the 600-character limit. If you, dear reader, can read this post in its full glory on the Micro.blog timeline, it means I’ve succeeded. Let’s celebrate that:

    🎉🥳

    You might wonder how this tiny trick is achieved? I’m glad you asked! There’s this saying that a screenshot is worth more than a thousand words (or is it 600 characters?), so without further ado, here it comes:

    Screenshot of Micro.blog’s new post view, with the content of this very post in the text area. The text begins with an opening span element with the class attribute set to: less-than sign blockquote.

    My new Micro.blog plug-in is a minimal, no-frills post editor. But it has one pretty magical feature: live previews!

    See it in action below, try it on my blog, or look up 🦄 Magic Preview in the plug-in directory. ⚠️ Read the important notice there before installing. Have fun!

    I will not harm you unless you harm me first

    Here are some hilarious (AI-powered) Bing encounters compiled by Simon Willison.

← Newer Posts Older Posts →