Chris Padilla/Blog


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


    Alt Guitar Idea

    Listen on Youtube

    Shaking that guitar and stretching my barre chords


    Backing Up Data

    Like flossing: really important to do, hard to get in the habit of.

    But I've had too many tragic losses of data growing up. And now my entire life's work happens and is saved on my computer. So I've set up a system for myself!

    I mostly follow Wes Bos' Backup Strategy. It keeps things easy and nearly automatic. Specifically:

    • I backup my computer to a Time machine on a WD My Passport drive.
    • My computer is backed up remotely to Backblaze
    • On a WD Passport I have old files, videos, and photos from older computers that aren't
    • Those older files are also synced with Backblaze.

    Backblaze is great because it runs automatically in the background. It's not at all a resource hog.

    It's only semi automatic because I still have a calendar reminder to actually plug in my drive every Friday morning. All of my ports are usually full with MIDI controllers and other gazmos. Ideally, I'd have some sort of monstrous port that takes in my monitor, midi instruments, guitar audio interface, AND USB to leave my external drive plugged in. Putting it on the wishlist!


    Non-Relational Database is a Misleading Name

    My intro to databases was through MongoDB. Coming from a web development perspective, it was comfy! Documents look and work like JSON objects. They're flexible and can adapt to changing schemas. I've enjoyed it!

    I'm dipping SQL this week to broaden my horizons in data land. The first conceptual overview I got was this:

    • SQL databases are Relational Databases
    • Other database structures are Non-Relational, or NoSQL Databases

    So are relationship structures exclusive to SQL?

    SQL

    The "relational" distinction comes from the fact that data is stored within tables in SQL.

    My e-commerce app would divide its data into three tables:

    • User
    • Items
    • Orders

    Each table for each would have data pertaining specifically to that category of data. They'd then be linked through a relationship.

    Orders, for example, would have a many-to-many relationship with items. Many items can be in many orders. Many orders can have many items.

    Users could have a many-to-one relationship with Orders. A user can have many orders, but an order is tied to only one user.

    So when your querying the items in the user's order, SQL has to travel through a few relationships:

    1. We start with the user ID
    2. We query an order based on the user
    3. We query items based on what's contained in the order
    4. We get massage the data to show what's relevent to our query.

    And thus, SQL gets the relationship monicker.

    MongoDB

    What made this confusing at first is that MongoDB falls under the non-relational database category, but I can make these same queries in MongoDB as well.

    MDN has a terrific guide to Express and Databases. When setting up the DB schema for MongoDB, it's done with a relational structure. In their library example, there are schemas developed for books, authors, book instances, and genre. All of which are tied together through relationships. In mongo, the ID is used to connect these documents.

    So the NoSQL descriptor is a more accurate lead. The query language is different, but relationships are still an offering in Mongo.

    The non-relational categorizing, though, is somewhat fair: The main benefit of Mongo is that you can nest in one document what you would otherwise split between tables.

    A user document can store their orders within a nested object in MongoDB. Depending on your application, you may not be accessing orders outside of the context of a query to the user. Mongo has a clear healthcare example where patient information is stored in their document


    Creativity as Conversation

    Matthew Hinsley's Form & Essence quotes William Stafford's "A Way of Writing" β€”

    A writer is not so much someone who has something to say as he is someone who has found a process that will bring about new things he would not have thought of if he had not started to say them. That is, he does not draw on a reservoir; instead, he engages in an activity that brings to him a whole succession of unforeseen stories...For the person who follows with trust and forgiveness what occurs to him, the world remains always ready and deep, an inexhaustible environment, with the combined vividness of an actuality and flexibility of a dream. Working back and forth between experience and thought, writers have more than space and time can offer. They have the whole unexplored realm of human vision.

    There is no certainty when you sit down to write. That's the magic! It's simultaneously a daunting aspect of the process as much as it is the whole spiritual point of doing it in the first place!

    While explaining the importance of letting go of certainty in creative process, Matt shares this:

    Have you had a good conversation recently? Did you say something interesting, profound even?...If you did, I can almost guarantee that you were accessing your creative self. And I will also suggest that there's no way you could have given that advice, in that way, had you not been having that conversation. It was in the act of conversing, or reacting to energy and idea, that you put thoughts and experiences swirling in your subconscious together into words that became concrete statements in Form as they exited your mouth.

    An anecdote to the blank page then is to make the creative process something other than closing the door, turning off the lights, and staring at a blank page. But instead, a conversation.

    I've been in a rut with writing music. I haven't been brining reference into my practice. I've been sitting at the keyboard and simply waiting for what comes out. While there's an intuition that's part of the process, the energy is muted when starting this way.

    But nothing kick-starts writing music better than listening to something I love, and then wanting to play around with it in my own way. In the same way that visual artists aren't cheating when they draw from reference, it's quite the opposite - the music is more buoyant and fun when it's in conversation with other recordings and musicians.

    This conversation-style of creating is baked into the culture of blogging! Much of blogging is finding something you read that was interesting, then adding your own two cents while connecting it to a particular audience. You're adding your own story to the mix, telling the original author's tale in a way that adds a new dimension, compounding it's message, and creating a new audience for the source material.

    Creatively conversing turns wonder into art.


    Starting a Development Environment from the Command Line

    I have a need for speed when developing. That goes for starting up all of my development applications.

    Here's what needs to happen before I start coding:

    1. Open my repo in VS Code
    2. Load in any environment variables
    3. Start the local server
    4. Open up chrome
    5. Visit localhost:3000

    A short list. But it takes a few key strokes and mouse clicks to get there. I think I can do better!

    Linux Alias Commands are the answer.

    I have a few set up for a few different use cases. Here's the one the runs the recipe for the steps above:

    alias cap="cd /Users/cpadilla/code/my-repo && code . && open http://localhost:3000 && source settings.sh && npm run dev

    I'm adding this to my .zshrc file at the root of my account.

    That turns all five steps into one:

    $ cap

    Another use case: I keep a list of todos in markdown on my computer. Files are named by the current date. I could do it by hand every time, but there's a better way:

    alias dsmd="touch $(date +%F).md && open $(date +%F).md"
    alias todo="cd /Users/cpadilla/Documents/Todos && dsmd"

    There we go! $(date +%F) is a command for delivering a specific date format. The todo alias navigates to the correct folder and then uses dsmd to create and open the file.

    Small quality of life changes! They add up when you do the same commands every day. πŸ™‚


    Integration Testing with Redux

    I'm testing a form on an e-commerce app. I've already looked at testing the components that add an item to the cart. Now I need to setup a test for updating an item in the cart.

    My app leans on Redux to store the cart items locally. As per the React Testing Library Guiding Principles, I'm going to be asserting my app's functionality by checking what shows in the DOM against my expectations. Notably: I'm doing this instead of asserting the redux store state. I'll also be integrating a test store and provider in the mix.

    The "how" today is Redux. The principle, though, is that if you're using a datastore, cache, or any other source, you want to be integrating it in your tests and not simply mocking it. That goes for either app state management or the data layer.

    Mocking

    In my app, to accomplish this, I have to render the whole page with the Layout component included:

      const rendered = renderWithProviders(
        <Layout
          children={
            <CartItemPage
              item={chipsAndGuac}
              itemID={'5feb9e4a351036315ff4588a'}
              onSubmit={handleSubmit}
            />
          }
        />,
        { store }
      );

    For my app, that lead to mocking several packages. Here's the full list:

    jest.mock('uuid', () => ({
      v4: () => '',
    }));
    
    jest.mock('next/router', () => {
      return {
        useRouter: () => ({
          query: {
            CartItemID: '5feb9e4a351036315ff4588z',
          },
          push: () => {},
          events: {
            on: () => {},
            off: () => {},
          },
        }),
      };
    });
    
    jest.mock('@apollo/client', () => ({
      useQuery: () => ({
        data: { itemById: { ...chipsAndGuac } },
      }),
      useLazyQuery: () => ['', {}],
      useMutation: () => ['', {}],
      gql: () => '',
    }));
    
    afterEach(() => {
      cleanup();
    });
    
    jest.mock(
      'next/link',
      () =>
        ({ children }) =>
          children
    );`

    I'm not testing any of the above, so I'm not sweating it too much. It did take some doing to get the right format for these, though.

    Redux Testing Utilities

    You'll notice that my render method was actually renderWithProviders. That's a custom utility method. The Redux docs outline how you can set this up in your own application here.

    That's it! That's the magic sauce. πŸ₯«βœ¨

    The philosophy behind it is this: You don't need to test Redux. However, you do want to include Redux in your test so that you have greater confidence in your test. It more closely matches your actual environment.

    You can take it a step further with how you load your initial state. You could pass in a custom state to your initStore() call below. But, a more natural would be to fire dispatch calls with the values you're expecting from your user interactions.

    Here I'm doing just that to load in my first cart item:

    test('<CartItemPage />', async () => {
      const formExpectedValue = {
        cartItemId: '5feb9e4a351036315ff4588z',
        id: '5feb9e4a351036315ff4588a',
        image: '/guacamole-12.jpg',
        name: 'Guacamole & Chips',
        price: 200,
        quantity: 1,
        selectedOptions: {
          spice: 'Medium',
        },
      };
    
      const store = initStore();
      store.dispatch({
        type: 'ADD_TO_CART',
        payload: {
          ...formExpectedValue,
        },
      });
    
      . . .
    
    }

    From there, you're set to write your test. That's all we need to do with Redux, from here we'll verify the update is happening as it should by reading the values in the DOM after I click "Save Order Changes."

    The details here aren't as important as the principles, but here is the full test in action:

    test('<CartItemPage />', async () => {
      const formExpectedValue = {
        cartItemId: '5feb9e4a351036315ff4588z',
        id: '5feb9e4a351036315ff4588a',
        image: '/guacamole-12.jpg',
        name: 'Guacamole & Chips',
        price: 200,
        quantity: 1,
        selectedOptions: {
          spice: 'Medium',
        },
      };
    
      const handleSubmit = jest.fn();
    
      const store = initStore();
      store.dispatch({
        type: 'ADD_TO_CART',
        payload: {
          ...formExpectedValue,
        },
      });
    
      const rendered = renderWithProviders(
        <Layout
          children={
            <CartItemPage
              item={chipsAndGuac}
              itemID={'5feb9e4a351036315ff4588a'}
              onSubmit={handleSubmit}
            />
          }
        />,
        { store }
      );
    
      const pageTitleElm = await rendered.findByTestId('item-header');
    
      expect(pageTitleElm.innerHTML).toEqual('Guacamole &amp; Chips');
    
      const customizationSection = await rendered.findByTestId(
        'customization-section'
      );
    
      const sectionText = customizationSection.querySelector(
        '[data-testid="customization-heading"]'
      ).innerHTML;
    
      expect(sectionText).toEqual(chipsAndGuac.customizations[0].title);
    
      const spiceOptions = await rendered.findAllByTestId('option');
      const firstOption = spiceOptions[0];
    
      expect(!firstOption.className.includes('selected'));
    
      fireEvent.click(firstOption);
    
      const updateCartItemButtonElm = await rendered.findByTitle(
        'Save Order Changes'
      );
    
      expect(firstOption.className.includes('selected'));
    
      fireEvent.click(updateCartItemButtonElm);
    
      const cartItemRows = await rendered.findAllByTestId('cart-item-row');
    
      const firstItemElm = cartItemRows[0];
    
      const firstItemTitle = firstItemElm.querySelector(
        '[data-testid="cart-item-title"]'
      );
      const customizationElms = firstItemElm.querySelectorAll(
        '[data-testid="cart-item-customization"]'
      );
    
      expect(firstItemTitle.innerHTML).toEqual('1 Guacamole &amp; Chips');
    
      const expectedCustomizations = ['Mild'];
    
      expect(customizationElms.length).toEqual(expectedCustomizations.length);
    
      customizationElms.forEach((customizationElm, i) => {
        expect(customizationElm.innerHTML).toEqual(expectedCustomizations[i]);
      });
    });

    Finishing Sketchbook No. 2

    Another sketchbook down!!

    This go-round, I alternated pages with two kinds of drawing. One page of drawing from imagination (visual journaling, as I've thought of it.) The other pages studies, largely older pieces by Louie Zong. What can I say, I love his work!

    Here's where I started:

    Is mayonnaise an instrument?

    And where I'm leaving this book:

    πŸ‘‹

    The left page is a study on this painting by Louie Zong.

    Big change!! I'm taking less time to get many ideas out at once, and am trying more to methodically get out a detailed character on the page. That tracks for this book!

    Here's my favorite page, following Miranda and I's trip to Denver:

    Looooove using the brush pen!

    On to the next one!

    See ya!


    Faber - Chanson

    Listen on Youtube

    Pretty little tune. ✨

    According to these books, I'm about to go from a level four pianist to a level five! πŸ’ͺπŸ˜‚


    Writing Music is Just Problem Solving

    Writing music is actually just problem solving.

    There are folks on both sides of the left and right brain spectrum as far as music making goes. Free form jazz is on the right brain side. Schoenberg's 12 tone school is on the left side.

    Most of it is actually somewhere in the middle, though.

    The ideas may come from inspiration or from influence. It starts with "I want to write a melody in a Medieval Style." But then, the next statement is "Let me figure out how to do that!"

    And it goes on from there:

    • Let me listen to references.
    • Let me score study a few of them.
    • Let me spend 15 minutes sounding bad in a musical mode until I find a melody I like,
    • Let me find an instrument that matches the sound in my head.
    • Let me try adding this other instrument. Woops! That doesn't fit. Let me try another
    • I want to transition key centers to the subdominant. How can I do that AND make my listeners feel a sense of bewilderment and magic as I do that.

    The fun part is it starts pretty broad and loose, but then gets very technical through the project.

    For me, the hardest part of writing is getting started. Blank canvas syndrome. Once a piece is in motion, though, then it's just solving particular musical and emotional challenges along the way.

    From there, the tune is taking shape, you're getting more limitations, those limitations bread further creativity, and eventually you stop because adding any more takes away from the spirit of the piece. Time to go on to the next problem - writing another one.

    In my mind, this doesn't cheapen the spiritual nature of music making or the mystique of writing music. It's both. When stuck trying to pull a melody out of the materials, eventually there's something that comes out of nowhere to fill in the gap. That's still a part of it too.

    I think it's helpful to dispel the belief that it's talent or a gift to do the whole music writing thing, though. Much of it is a lot more on the ground and just working in the dirt than it's given credit, like any creative art.

    (Also worth saying, in my experience, the process of writing music is WILDY SIMILAR to writing software.)


    Software is Measurably Valuable Creation

    Last year I read Chad Fowler's The Passionate Programmer, and I still think a lot about these lines from his ending essay:

    You could have chosen any number of career paths, but this one is exciting. It's creative. It requires deep thinking and rewards you with a sense of being bale to do something that most of the people you meet each day can't imagine being able to do. We may worry about progressing to the next level, making an impact, or gaining respect from our co-workers or our peers in the industry, but if you really stop to think about it, we've got it really good.

    Here's what really sticks with me:

    Software development is both challenging and rewarding. It's creative like an art-form, but (unlike art) it provides concrete, measurable value.

    It rings true. It doesn't feel like music, art, writing, and software are all that separate. They're all simply different mediums for creation. Funnily, in my experience, they all have similar rhythms when it comes to starting a project to completing it. Thankfully, too, when one feels stagnant, it's easy to jump to another one. Stirring a boiling pot, waiting for the other one to simmer.

    The wonderful thing about software is that it is a concrete service. It's difficult to really pin down the value of art. That doesn't dilute art's true importance and value. That might, in fact, be why music and art are wildly valuable. It's an act of awe and wonder, and you can't measure that.

    What a fantastic creative balance, though, that software is a practice that allows you to directly create something to improve the lives of any number of people.

    Early on in my current role, I met with teammates who walked up to me, shook my hand, and said "WOW, the kanban feature you developed makes my life SO MUCH easier! Thank you!"

    I'm convinced that, in a wholly creative life, our practices need both sides. We need that which is directly beneficial to people, and that which entangles with the spirit of discovery and sensitivity. And I'm thankful for software as the form that balances exploration.

    Here's the opening quote on Chad's essay:

    But I say to you that when you work you fulfill a part of earth's furthest dream, assigned to you when that dream was born, and in keeping yourself with labour, you are in truth loving life, and to love life through labour is to be intimate with life's inmost secret. β€” Kahlil Gibran, The Prophet


    Writing is Efficient Creativity

    I still think regularly about Walt Stanchfield's equation: "Impression minus expression equals depression."

    For me, I've wrestled with what that looks like. All the quirky projects I have going on β€” art, music, software β€” generally stem from the idea of taking in what I love and pouring it back out into the world.

    Producing something to share daily is tough, though.

    Writing music is not fast. At least for me. It takes design, sculpting melodies, mucking with synth settings, sometimes practicing an acoustic instrument to get there, and recording multiple takes. Don't get me wrong, it's fun, but it's not a very immediate mode of expression outside of improvising.

    I picked up art partly because I wanted a quicker means at communication. A line can be expressive. Sketches take only a few minutes in a day to get out. But WOOPS! After a few months of rough doodles, I'm hungry to build my craftsmanship and do some serious study. So there are still expressive elements, but the full spectrum is on the other side of some devoted practice. I'm just too much of a beginner here.

    Blogging, though!

    Writing is simply efficient creativity. Essays in any other form take a lot of time: videos take producing and equipment, podcasts take coordinating and editing, speaking takes an audience.

    Writing is a straight shot from imagination to publication. It's also the most flexible medium - you can write technical articles one day, life posts another, highly sensory poetry and non-fiction essays the next day. All of this is augmentable with links, images, sound, and video.

    And, writing is a terrific way to turn the process of all other art forms into creative pieces themselves.

    Software takes a long time to write, too. But sharing a bit about what I learned along the way helps keep my spirit in motion.

    I've been searching for a creative practice that can be shared daily, and maybe writing is it. Writing is a great sustainer while other dishes are still in the oven.

    I'm tempted to say maybe this only applies to me, but the truth is we're all virtuosos of our own way of speaking and communicating. Writing is an expressive medium that we all have access to.

    So if you have something to say β€” I know you do! β€” then come hang!


    The Gist on Docker

    "As for me, I am tormented with an everlasting itch for things remote. I love to sail forbidden seas, and land on barbarous coasts." - Herman Melville, Moby Dick

    We're learning about Docker this week at work! 🐳

    Here's what I can tell you so far:

    Why Use it?

    Two big reasons:

    1. Consistency of dependencies (namely, node versions in web development)
    2. Easy onboarding for new devs

    To the first point: Node versioning can be a hassle. Even if your application isn't reliant on a specific version of node, perhaps an NPM package you are using is. Any difference between your environment and your hosts could lead to strange issues.

    To the second: swapping between local versions of node or python can also be tricky. And then say you start working on an app where you need to download a specific version. All doable, but Docker can make this smoother.

    Hosts Handle This Usually

    To run your server on another machine, if you were to do it yourself, you would need:

    1. To install an OS
    2. Install your runtime (Node, Python, etc)
    3. Upload you app directory
    4. Initialize the run command

    Vercel, Netlify, Render, even AWS essentially eliminate all the steps except for the third one. You simply send your files up, and these services will take care of the rest in most cases successfully.

    When you need greater flexibility, or your application is more complicated and fussy with it's versioning, Docker can be the tool to reach for.

    Image? Container?

    A Container is a lighter version of a Virtual Machine.

    A virtual machine is what it sounds like. On a computer, you can simulate a full blown PC by using the hardware on the one you're running it on. Think using Bootcamp to run Windows on a Mac.

    A container is a level lower than that. Containers will share the same OS, but will still have separate, self contained resources and file directories. I can have two different containers running different versions of node.

    An image is the recipe for a specific container's environment. Docker takes an image and creates a container with the given OS, runtime environment, packages, and environment variables. You'll set all this up in a Dockerfile in your application.


    The Haps - March 2023

    Valentines, Galentines, and Palentines! February was an A+ month! The grooves are tracked and I'm in them for code, music, art, and people.

    Blogging & Dev

    I'm getting the hand of this blogging daily thing! Lots of tech journals this month from learning testing in React.

    Continuing on with the Tailwind redesigns at work! It's been coming along nicely. πŸ‘Œ We'll be learning Docker at work, so I'm reading up on great quotes from Moby Dick. 🐳

    I went to my first meetup in a while! React Dallas was a great hang. There's a really welcoming and smart community out here!

    Music

    I released Spring this month! I'm impatiently waiting for it to actually feel like Spring outside!!

    Spring Cover

    Good things coming with guitar and piano! I'm learning finger style on guitar and am plugging away at reading jazz lead sheets on piano.

    You can see what I've shared so far through the Music tag on my blog

    Drawing

    Two pears in a pod

    I'm getting close to finishing my second ever sketch book! I'm breaking the threshold of only learning from videos to actually learning through the craft. Like practicing an instrument, the training wheels are coming off and I can just start learning through practice. Exciting!

    I'm still doing drawabox. Also going through the brand new Proko Drawing Basics course. Drawabox is so dense an zeroed in on construction that it's great to have a more general, exploratory curriculum with Proko.

    You can see what I've made so far through the Art tag on my blog. I'm also sharing drawings on Instagram.

    Words and Sounds

    πŸ“š

    🎧

    Life

    Early this month Miranda and I went to Denver, Colorado for The Gate. IYKYN, we both came back lit up and ready to rock and roll!

    Tourist-wise, we got to see the Meow Wolf out there. We loved the original in Santa Fe when we went a couple of years ago. So crazy cool! Can't wait for the Grapevine location to open this summer!

    We also saw Maggie Rogers. That concert was a blast! Great band, great crowd, great music.

    What's up?

    πŸ‘‹


    Louie Zong's Boss Rush & Sketches

    Louie Zong's album Boss Rush and the CUSTOM BLENDER RENDERED 3D VIDEO is a gem.

    I may have actually had nightmares about the school bus guy grouwing up???

    He's the angriest gamer you've ever heard

    My last bit of plant construction for drawabox!

    Reaching out! 🌱


    Faber β€” Grand Central Station

    Listen on Youtube

    Big Rhapsody in Blue Vibes with this one. πŸŒ†