Chris Padilla/Blog


My passion project! Posts spanning music, art, software, books, and more. Equal parts journal, sketchbook, mixtape, dev diary, and commonplace book.


    Night Lake

    πŸŒ™

    The veil is thin. πŸ‘»

    Squeaked in one Inktober drawing this year! Very much directly inspired by the energetic ink work of Violaine Briat's Lil' Dee.


    TypedDicts in Python

    So much of JavaScript/TypeScript is massaging data returned from an endpoint through JSON. TypeScript has the lovely ability to type the objects and their properties that come through.

    While Python is not as strongly typed as TypeScript, we have this benefit built in to the type hinting system.

    It's easier shown than explained:

    from typing import Union, TypedDict
    from datetime import datetime
    
    
    class Concert(TypedDict):
        """
        Type Dict for concert dictionaries.
        """
    
        id: str
        price: int
        artist: str
        show_time: Union[str, datetime]

    All pretty straightforward. We're instantiating a class, inheriting from the TypedDict base class. Then we set our expected properties as values on that class.

    It's ideal to store a class like this in it's own types directory in your project.

    A couple of nice ways to use this:

    First, you can use this in your methods where you are expecting to receive this dictionary as an argument:

    def get_concert_ticket_details(
            self, concert: UnitDict = None
        ) -> tuple(list[str], set[str]):
        // Do work

    You can also directly create a dictionary from this class through instantiation.

    concert = Concert({
        "id": "28",
        "price": 50,
        "artist": "Prince",
        "show_time": show_time
    })

    The benefit of both is, of course, the suggestion in your editor letting you know that a property does not match the expected shape.

    More details on Python typing in this previous post. Thorough details available in the official docs.


    Sonny Rollins – Oleo

    Listen on Youtube

    Today I learned that this jazz standard is named after margarine. Yum!


    From the Other Side

    πŸŒ‘

    We have bobcats and coyotes on the other side of the lake near our home. You can hear them at night. Every now and then, I see one looking back at me 🐺


    Optimistic UI in Next.js with SWR

    I remember the day I logged onto ye olde facebook after a layout change. A few groans later, what really blew me away was the immediacy of my comments on friends' posts. I was used to having to wait for a page refresh, but not anymore! Once I hit submit, I could see my comment right on the page with no wait time.

    That's the power of optimistic UI. Web applications maintain a high level of engagement and native feel by utilizing this pattern. While making an update to the page, the actual form submission is being sent off to the server in the background. Since this is more than likely going to succeed, it's safe to update the UI on the page.

    There are a few libraries that make this process a breeze in React. One option is Vercel's SWR, a React hook for data fetching.

    Data Fetching

    Say I have a component rendering data about several cats. At the top of my React component, I'll fetch the data with the useSWR hook:

    const {data, error, isLoading, mutate} = useSWR(['cats', queryArguments], () => fetchCats(args));

    If your familiar with TanStack Query (formerly React Query), this will look very familiar. (See my previous post on data fetching in React with TanStack Query for a comparison.)

    To the hook, we pass our key which will identify this result in the cache, then the function where we are fetching our data (a server action in Next), and optionally some options (left out above.)

    That returns to us our data from the fetch, errors if failed, and the current loading state. I'm also extracting a bound mutate method for when we want to revalidate the cache. We'll get to that in a moment.

    useSWRMutation

    Now that we have data, let's modify it. Next, I'm going to make use of the useSWRMutation hook to create a method for changing our data:

    const {mutate: insertCatMutation} = useMutation([`cats`, queryArguments], () => fetchCats(args)), {
            optimisticData: [generateNewCat(), ...(data],
            rollbackOnError: true,
            revalidate: true
        });

    Note that I'm using the same key to signal that this pertains to the same set of data in our cache.

    As you can see, we have an option that we can pass in for populating the cache with our optimistic data. Here, I've provided an array that manually adds the new item through the function generateNewCat(). This will add my new cat data to the front of the array and will show on the page immediately.

    I can then use the mutate function in any of my handlers:

    const {error: insertError} = await insertCatMutation(generateNewCat());

    Bound Mutate Function

    Another way of accomplishing this is with the mutate method that we get from useSWR. The main benefit is we now get to pass in options when calling the mutate method.

    const handleDeleteCat = async (id) => {
        try {
            // Call delete server action
            deleteCat({id});
            
            // Mutate the cache
            await mutate(() => fetchCats(queryArguments), {
                // We can also pass a function to `optimistiData`
                // removeCat will return the current cat data after removing the targeted cat data
                optimisticData: () => removeCat(id),
                rollbackOnError: true,
                revalidate: true
            })
        } catch (e) {
            // Here we'll want to manually handle errors
            handleError(e);
        }
    }

    This is advantageous in situations like deletion, where we want to sequentially pass in the current piece of data targeted for removal. That can then be passed both to our server action and updated optimistically through SWR.

    For even more context on using optimistic UI, you can find a great example in the SWR docs


    AntΓ΄nio Carlos Jobim – Once I Loved... Continued!

    Listen on Youtube

    Finishing out this bossa 🏝️


    Waiting to Be Picked

    πŸŽƒ

    To be someone's pumpkin...


    3 Types of Software Requirements

    This week I'm synthesizing notes from Michael Pogrebinsky's course on Software Architecture and Design. If you like what you read below, you'll love the course!


    When designing a system, especially at higher scales of complexity, it's vital to take the carpenters' motto to heart: "Measure twice, cut once."

    Smaller scale projects, such as feature requests for an already existing system, have very clear restraints. The programming language, platform, and infrastructure of the project have already been laid. It only takes a few questions to get clear on what needs to happen when adding a widget to an existing app.

    Larger solutions, however, can be daunting with the sheer vastness of options. Any software choice can solve any problem. And, in spite of what the discourse on forums may lead you to believe, there isn't one correct solution for any problem.

    So how do you narrow down your choices? Through requirement gathering!

    Requirements As Part of the Solution

    A paradigm shift for anyone pivoting from a small scale environment to thinking broadly is understanding that question asking is part of the solution.

    The client, sometimes not technical, will have an idea of the problem they want to solve, but will be unclear on the solution. Even if they have an idea of what solution they would like to see implemented, you as the technical authority in the room have to ask clarifying questions to find out if their suggestion will work in your system.

    Types of Requirements

    To help ensure time is spent asking the right questions, it's helpful to know that there are three types of requirements you can gather:

    • Functional Requirements: Features of the system. Think inputs and outputs. Listen for "the system must do this"
      • Generally, these do not determine the architecture. Any architecture can solve any problem.
    • Quality Attributes: Non-functional requirements. Deals with performance of the application. Listen for "the system must have".
      • Ex: Scalability, availability, reliability, performance, security. A more comprehensive list here.
      • These dictate the software architecture of our system.
    • System Constraints: Limits and boundaries.
      • Ex: Time, staffing, resources. Can also drive architecture design.

    Example: CD Dad

    Say you're working with a client that is looking to build out an e-commerce platform for musicians. A possible portion of requirements may include the following:

    "CD Dad will host albums from independent musicians. When a customer purchases an album, the customer will receive a digital download of the album and the musician will be paid."

    So far we've heard the Functional requirements. With given inputs, the system hosts the music. When a customer submits a purchase, they receive the digital downloads.

    "Processing uploads should be take no longer than 5 minutes. When an album is purchased, a link should be made available immediately through email."

    The statement above relates to performance of the app, so this is a quality attribute.

    "The system should support mp3, wav, and aif file formats. A team of a dozen full time engineers will be responsible for maintaining the system."

    Now we're talking file formats and engineering support, so we're looking at System Constraints.

    The Joy of Constraints

    For many engineers, an ideal world is one without constraints. However, limitation breeds creativity. A limit on resources, hands on deck, and time are what enables us to ship code regularly.

    In the event that any of this information is missing in your understanding of a system, it's an opportunity to gather more info and clarify what's being built. Doing so will help clear the fog for the next best step.


    Marching In Step

    Many varieties of creative work require a great deal of solitude. Some like software, writing, composing, and art, are often done without an audience when performing.

    It's possible to do any creative act collaboratively. But, I've been realizing lately how important it is to intentionally find time for synchronized movement.

    The move towards working from home, collaborating with people online, and the flexibility to live and work anywhere is undoubtedly a net positive. It's just that we have to be really intentional about carving out time for connection. Not just being around people, but finding activities where you are "marching in step" with other people.

    We are literally wired for it. Jonathan Haidt in The Happiness Hypothesis explores the energizing feeling we get from being in synch:

    ...rituals that involve repetitive movement and chanting, particularly when they are performed by many people at the same time, help to set up "resonance patterns" in the brains of the participants that make this mystical state more likely to happen.

    Oliver Burkeman poses the unique position we're in at this moment in time. Amidst asynchronous work as a writer, he highlights the impact of even ordinary synchronized activity:

    I've felt it as a member of a community choir, when the sharp and flat tones of amateur voices combine into a perfection that few of the singers involved could attain on their own... For that matter, I've felt it in settings that are even more mundaneβ€”working my monthly shift at the food cooperative, for example, slinging boxes of carts and broccoli onto the conveyor belt, in time with other workers I barely know but whit whom, for a few hours, I share a bond that feels deeper than the one I have with some of my real friends. For a while, it's as if we're participating in the communal rhythms of a monastery, in which the synchronized hours of prayer and labor impart coherence and a sense of shared purpose to the day.

    Both books above reference Keeping Together in Time by William McNeill, a whole exploration on synchronized movement across human history.

    For men in particular, who seem to have a knack for distancing themselves in their relationships (guilty as charged), those moments of connection happen in spaces that require coordination. Here's James Hollis on the subject in Under Saturn's Shadow:

    There are few things more rewarding than for a shortstop, deep in the hole, to turn and throw the ball toward second, and see the second baseman intersect base and ball at the exact moment. This is less about practice than about the integration of spirit, the communion of soul. Perhaps this rare sense of oneness is possible in part because the outer challenge occasions a transcendence of the individual ego to serve the joint purpose...

    No matter what, true solitude is required and desired. Nourishment is given, soil is enriched, and roots take hold in solitude. And still, it's a dance.

    This morning, I was talking with Miranda about a music workshop from high school. In reminiscing, I came across this passage from The Musician's Soul by choral conductor James Jordan. This touches on that dance quite nicely:

    Few of us are fortunate enough to be able to understand the rich alchemy that happens when there is a balance between true solitude and true community in one's musical interactions and one's life interactions. Most of us exist as a wild pendulum that swings almost uncontrollably between loneliness and the crowd. This dynamic inertia manifests itself in the music we make, or rather the music we try to make. As musicians, we constantly and dynamically exist in the atmosphere of a larger community. That large community can be defined as small as one or extended to hundreds. The relationship with an accompanist is community. The relationship with an audience is a community....Human beings communicating directly with one another through 'great things' speak powerfully and with one voice. A musician's soul can be explored individually, but it can only grow and deepen through the nourishment of connectedness at every moment. Without the lifeline between souls, there is no art, and more importantly, perhaps, no real life or living.

    Join a cycling class! Make time for pair programingm! Go to a swing dance class! Take up accordion lessons! Especially if you work remotely, find ways to return to the hive and move together.

    For creatives, carve out a part of your practice that requires being in the room with other people and creating together. For me, it's playing in a community concert band. For artists, it could be something as simple as painting in a class together.

    At the end of the day, we create to be a part of something larger than ourselves. Contributing to a scene, a creative lineage, an industry, a craft, a culture. What could enhance that more than creating in true community?


    AntΓ΄nio Carlos Jobim – Once I Loved

    Listen on Youtube

    Because love is the saddest thing when it goes away~


    Gentleman Frog Surveys the Pasture

    🌌

    As the crisp autumn air starts to roll in. πŸ‚


    Street Light

    πŸŒƒ

    Fond memories of wandering quiet streets late at night. πŸŒ™


    New Album β€” My Mix CD πŸ’Ώ

    πŸ’€

    A love letter to burning CDs in the 2000s. Inspired by some soup of punk.

    Details here!


    All The Things You Are Comping

    Listen on Youtube

    Working on leaping through chords!


    Lessons From a Year of Painting

    πŸŒ… 🌸

    Blue Sky Thinking β€” 09/20/24

    I had a blast spending time creating digital paintings this year!

    A couple of years ago, I was overcome with the desire to really learn to draw. I made crude comics as a kid, but I was itching to really figure out how it's done. And so I did, and I learned a lot about art and creativity from it!

    This year I turned my focus to the world of color and texture through digital painting. It was quite the leap! From single toned, line driven analog art making in a sketchbook β€” over to color and shape based painting through a digital medium.

    Much of what I have to say this year is a revisiting of ideas I came across last year. Only this time the context has changed. A bit of a variation on a theme!

    πŸ’‘
    Still Life β€” 5/4/24

    Changing the Way You See the World

    I also love to listen to skaters talk about how they see the world. Skateboarding seems to reconfigure your molecules and changes the way you look and the kind of attention you pay to the world. (Exactly what we hope for when practicing any art.)

    β€” Austin Kleon

    Drawing with line art, especially in a stylized way, involves a great deal of abstraction and reduction. I spent time simplifying a form to only a few strokes and basic shapes. It changed how I saw the world. But more in a way of capturing shorthand. I was looking for the simplified essence.

    Learning to see color through painting had the exact opposite effect! When I started studying color and light as well as doing direct-painting still lifes, it's as if I was starting to see for the first time.

    A pot is just "orange" until you take a closer look at the texture, the lighting, the chips and smudges across its surface. There's a humbling amount of color in everyday life that gets simplified and overlooked.

    Miranda and I went to a couple of art museums this year. Paintings are already captivating when you're not an artist. They're then astonishingly rich and awe inspiring once you know the attention to detail that goes into them!

    The process of painting is great fun. Though, my favorite takeaway from picking up the craft is now how I see the world. You won't believe how something as simple as looking into someone's eyes will bring out a world of beauty hiding in plain sight!

    Sweet little Lucy loving on this pretty sky
    Pup at Twilight β€” 3/9/24

    Balancing Projects with Play

    After a few years, I've largely gotten better about balancing play and study. The boundary for me has become really clear since painting has been an entirely new medium requiring lots of study, master copies, and reading up on how the brush engine works.

    Even still β€” When I work on a digital painting project for myself, I'd call it play. But it's not entirely in that category. I realized something was missing.

    It wasn't until I picked my physical sketchbook back up and started fooling around that things clicked into place. Unsurprisingly, having an analog, private, free space with no large end goal helped keep my spirit up when I returned to the digital canvas.

    I've since deviated from needing a hard boundary, a la the 50% rule. These days my energy level is a good indicator of whether today is painting day or a fool around in the sketch book day.

    If I were to package this up into advice: Be mindful of the project driven work, study, and time spent fooling around.

    Actually, that lines up nicely with Robertryan Cory's recommended routine for artists from his CalArts lecture: "Educational, Disciplinary, Experimental. Drawing should be divided into a sustainable work routine."

    πŸŒ… 🌸
    An early swing at digital painting β€” 09/24/23

    In Pursuit of Truth

    In music, the major scale is derived from the harmonic series: a natural occurring phenomena that represents mathematical divisions of any given frequency. (For one of the best demonstrations of this, look no further than the Bernstein Norton Lectures.)

    It's a major reason why tonal music is universal. It's what makes music a pursuit of Truth. In Harmonic Experience, W. A. Mathieu walks readers through singing exercises where you experience the balance of these sounds firsthand. It's an eye opening journey.

    I'm not as well-read on light as I am acoustics, but I know this much: colors themselves are different wavelengths of light. Violet is a short wavelength, red a long one.

    It's one thing to know that intellectually. And a wholly other thing to experience it.

    At some point, after working at a still life, spending an hour closely trying to match the color of a dull pot, I stepped outside. It was a clear day, mid afternoon. A rich blue sky, I observed. High in saturation today.

    As my gaze came downward, I saw the leaves on the tree. And while it's hard to explain in writing β€” a resonance occured. I started seeing the green of the leaves as a continuation of the blue in the sky. Not in an intellectual way, but on something much more deep and personal.

    In the same way that each tone of music contains a multitude of different sounds, I made the connection that light was working in that same way. Obvious to some, I'm sure, but a revelation to me.

    There are plenty of reasons to paint. Maybe one of the most worthwhile, though, is that β€” just like studying sound β€” you spend time with another Truth in the world. This time, through color and light.

    🌳🌳🌳

    Campion Trail – 07/06/24