• OpenSUSE Tumbleweed

    I recently installed OpenSUSE Tumbleweed on an old laptop I had lying around my apartment. I did so to test out my new install script ( https://github.com/danieljaouen/dotfiles/blob/main/install.sh ) which still had some rough edges (and still does). I figured I’d write a blog post about the setup process along with some comments.

    First, I thought the installer was very intuitive. I didn’t keep the old Windows partition, so partitioning was a breeze with the installer. Just a few clicks to get everything partitioned. Overall, the process took about half an hour total. Not bad!

    I also like that SUSE offers a rolling release in the form of Tumbleweed. I have some experience with Arch, so that is a nice touch. Nothing beats not having to upgrade your system every so often.

    One thing I’ve read is that OpenSUSE doesn’t have some popular packages. While most of the packages in my installer script were available, I did notice that duf was not. I recently installed Arch on a server and noticed it did have duf. Not a big deal, but something to watch out for if you do want to install OpenSUSE.

    Overall, my experience so far with OpenSUSE has been pleasant. You can download the installer here: https://get.opensuse.org/tumbleweed/. Hopefully, this has been helpful to you. Have a great day!

  • emacsclient and fzf

    I recently came across Andrew Quinn’s article on fzf: https://andrew-quinn.me/fzf/

    I just thought I’d add that, you can open up a fzf-inded file in emacsclient by typing into your terminal ec <C-t>

    Of course, you will need to have emacsclient aliased to ec: alias ec='emacsclient'.


  • Introducing LouLinks

    Hey there! Tonight I was feverishly working on a basic Phoenix 1.7.0 app that lets me store various links. The goal was to build out a site that would replace having to keep a whole bunch of tabs open in my laptop and mobile browsers. Here it is: https://loulinks.net. Enjoy!

  • ChatGPT and Flask

    I recently used ChatGPT to generate a Flask app that automatically generates the current price of Solana. You can check it out here: https://github.com/danieljaouen/chatgpt-solana-price


  • Happy Holidays!

    Wishing you and your close ones a very Happy Holidays! May the worst times of your 2023 be as the best times of your 2022. 🙂

  • A Brief Introduction to Phoenix and LiveView (Part 2)

    This is a continuation of Part 1, which you can find here:

    Now, let’s navigate to the index.html.heex file, which is located in lib/todo_web/live/todo_item_live/index.html.heex.


    The first thing we encounter is something that looks like an HTML tag, but is actually a LiveView function component. We can tell that it is a function component because it begins with a .. You can find the definition of the header component in lib/todo_web/components/core_components.ex. We can see that it has a class attr, an inner_block, a subtitle, and associated actions slots.

    In :actions, we see that there is a .link. This is defined in LiveView itself (see: deps/phoenix_live_view/lib/phoenix_component.ex — search for “def link“. Feel free to also read the documentation at the top of the file). You can find the documentation for the patch attr in the file listed above (search for "attr.(:patch"). The long and short of it is that /todo_items/new is first translated into a Verified Route (note the ~p sigil), which then will call handle_params with the :new action.


    Next, we have a .table. You can also view this function component in lib/todo_web/components/core_components.ex. Basically, the table function component has three attrs (id, row_click, and rows) and a slot col which takes an optional attr label plus a slot action. The rows attr passes each list item into the :let slot of the associated slot, and the row_click attr calls JS.navigate, which will, in turn navigate the page to the show.ex LiveView. You can learn more about the JS module here: https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.JS.html


    Next, we have the modal function component, which is displayed only when the @live_action is in [:new, :edit]. Basically, it renders a LiveComponent, which you can find in lib/todo_web/live/todo_item_live/form_component.ex. You can read more about LiveView’s LiveComponent’s here: https://hexdocs.pm/phoenix_live_view/Phoenix.LiveComponent.html


    And that’s it! Now we navigated through index.html.heex, so you should have a better understanding of function components and where you can find the docs for them.

    Again, if you gained value from this article, feel free to throw me a dollar or two on my Buy Me a Coffee page, which you can find here: https://www.buymeacoffee.com/danieljaouen

    Thanks for reading!

  • A Brief Introduction to Phoenix and LiveView (Part 1)

    Hello, once again! Today, I am going to introduce you to the basics of the web framework, Phoenix. Phoenix is a web framework that reached 1.0 in 2015 written in the Elixir programming language. It is generally seen as the “successor” to Ruby on Rails, although that can be hotly debated and is not the purpose of this post. It is well known for its use of the real-time package, LiveView, which can help minimize the amount of Javascript that you have to write. It is well-suited for programmers who want a combination of functionality and performance. If that sounds like you, let’s jump right in!


    I will assume that you have Elixir 1.14 installed. We are going to be using Phoenix version 1.7 in this tutorial. To install it, run the following command in your terminal:

    mix archive.install hex phx_new

    You may need to uninstall your previous version first (if you had it installed already):

    mix archive.uninstall phx_new

    Creating the App

    Great! Now, let’s begin our Phoenix project by using the mix phx.new command:

    mix phx.new todo

    Great! Now let’s cd into the new todo directory and run the following commands:

    cd todo
    mix ecto.create

    Great! That created the initial PostgreSQL database for us. Now, let’s run the following command to make sure everything was set up correctly:

    iex -S mix phx.server

    Now browse to localhost:4000 and you should see the Phoenix welcome page. If not, you will need to debug the reason you are getting your specific error.

    Creating the Todos

    First, let’s take a look at the help dialog that ships with Phoenix by running the following command:

    mix help phx.gen.live

    Feel free to read this at your convenience. Now, let’s create the Todos using the following command:

    mix phx.gen.live Items TodoItem todo_items text:string

    Next, follow the instructions printed to your terminal about modifying your router.ex file.

    Next, run the generated database migrations:

    mix ecto.migrate

    Now restart the Phoenix server and re-navigate to localhost:4000/todo_items and you should see the listing page for your TodoItems. Great!

    Navigating the Generated Code

    Now that we have the Todo app up-and-running, let’s navigate through the code to get a glimpse at how things work under the hood.


    First, let’s take a look at index.ex, the generated Elixir code for the index LiveView. We notice five functions:


    mount is called when the client connects and is used to set up the initial socket. You will notice that there is no render function, and that is because Phoenix uses a particular convention to display its templates: if there is an associated index.html.heex adjacent to index.ex, that template will be used.

    handle_params is called whenever we have a live navigation event. These events are what you would normally have separate HTTP requests for. You can learn more about handle_params here:


    handle_event is called whenever we have a JS “delete” event pushed to the page. Finally, list_todo_items simply calls the associated context’s function.

    Next Up

    Join me next time when we dive into index.html.heex. In the mean time, feel free to browse through the additional generated code.

    If you gained value from this post, feel free to throw me a dollar or two on my Buy Me a Coffee page, which you can find here:


    Your support goes to the cost of keeping the server up and is never unappreciated. Thanks!

  • Useful Emacs/Evil Keybindings

    I am a big fan of Emacs. In particular, I use the Spacemacs pre-configuration. However, one thing that bugged me about the defaults is that C-h and C-w don’t map to backspace and backward-word-kill (respectively). One thing I tried was the following:

    (global-set-key "\C-h" 'backward-delete-char)
    (global-set-key "\C-w" 'evil-delete-backward-word)

    Note that I use evil-delete-backward-word rather than the usual backward-word-kill, as (for my purposes) they are equivalent.

    But this misses a few modes, in particular in helm and isearch modes. As a result, I have accumulated a list of these additional modes that need these keybinds.

    Here is the full list. Hopefully, it is useful to you if you came across this article:

    (global-set-key "\C-h" 'backward-delete-char)
    (global-set-key "\C-w" 'evil-delete-backward-word)
    (define-key helm-map "\C-h" 'delete-backward-char)
    (define-key helm-map "\C-w" 'evil-delete-backward-word)
    (define-key helm-find-files-map "\C-w" 'evil-delete-backward-word)
    (define-key iedit-mode-keymap "\C-h" 'backward-delete-char)
    (define-key iedit-mode-occurrence-keymap "\C-h" 'backward-delete-char)
    (define-key isearch-mode-map "\C-h" 'backward-delete-char)
    (define-key isearch-mode-map "\C-w" 'evil-delete-backward-word)

  • Highest Normalized P/E Ratios on the S&P 500

    I wrote a quick script to find the highest (and lowest — email me at daniel@danieljaouendevelopment.com if you’d like a list of those) yearly normalized P/E ratios on the S&P 500. Here are the highest:

    • TWTR (147.99)
    • WELL (171.18)
    • DXCM (174.45)
    • TSLA (178.96)
    • VTRS (186.63)
    • MGM (203.88)
    • UDR (222.29)
    • ENPH (229.87)
    • PPL (397.02)
    • NOW (406.76)

    If you found this information useful, feel free to support me on Buy Me a Coffee. Your support goes to offset the cost of running this site and never goes unappreciated.

    Thanks for reading!

  • The Why of Elixir

    Learning a new language (and a new paradigm: functional programming) can be a lot to take on. That’s why I thought I’d write a short post on why learning Elixir would be a valuable use of your time. In particular, I will go over the various strengths that the Elixir ecosystem has as well as some major benefits. Let’s start with reliability.


    I was recently watching a video by Jonathan Blow (the game developer) and he mentioned how there used to be a concept in tech called “five nines”. What that meant was that a particular service would be “available” (for some definition of the word) 99.999% of the time. Elixir can help you to achieve these numbers using something in the language known as “supervision trees”. Basically what this means is that, if Elixir encounters some error situation, it can simply crash the process and expect the process’s supervisor to either restart the process or handle the crash in an appropriate way. This means that, effectively, if you program things correctly, your application will have very little “downtime”. As you can imagine, this does wonders for your app and is a big reason to learn and use Elixir.

    Next, let’s look at parallelization.


    If you are coming over from Javascript, you might already be familiar with asynchronous programming using Promises. Elixir takes a different approach to parallelization: it uses lightweight processes which can send messages to each other. Basically what this means is that any time you want to start something in the background, you can spawn up a process and send it any message you want. The flip side of this is that the process can also send (asynchronous) messages back to the calling process. What this effectively means is that you can write your code synchronously, then split out the necessary bits into its own process. This makes it easy to both read and write Elixir programs that utilize multiple cores of your machine without the added hassle of callbacks or promises.

    Next, let’s look at extensibility.


    If you’ve programmed in a Lisp (or a C derivative) before, you may be familiar with the concept of a macro. A macro is essentially code that writes code. The reason I mentioned Lisp is that Elixir, though it can look similar to Ruby, actually makes use of macros internally. Essentially, Elixir code only looks like Ruby because it uses some syntactic sugar to hide its Lisp-like structures. I won’t go into too much detail here, but if you are really curious about this aspect of Elixir, I would give Chris McCord’s book, “Metaprogramming Elixir” a read.

    Next, let’s get to the probable reason you are reading this arcticle: Elixir helps you to minimize the amount of Javascript you have to write.

    No Need To Write Javascript (TM)

    I would be remiss if I were to write an article about Elixir without mentioning Phoenix and LiveView. Phoenix is basically a Rails- or Django-like web framework written in Elixir. If you’re not familiar with web frameworks, they are a bit too complicated to go into in detail here, but I will just say that they help you to write and organize code meant for serving browsers web pages. What really piqued my interest when learning Elixir was that Phoenix has an addon called LiveView which lets you write interactive pages without the use of Javascript. Basically, all you do is write Elixir code that handles events on the page, and you’re good to go!


    So those are some of the benefits of learning and using Elixir. If you enjoyed this post, feel free to Buy Me a Coffee. Your support helps to offset the cost of running this site and never goes unappreciated.

    Thanks for reading!