Chris Padilla/Blog

My passion project! Posts spanning music, art, software, books, and more
You can follow by Newsletter or RSS! (What's RSS?) Full archive here.

    Hippo!! 🦛

    Happy as a hippo with how this guy turned out!

    Not going to lie, I can see the difference of spending nearly 6 months on lines with the Proko course!

    This photo sounds like a gargled "Waaaah"

    MVC in ASP.NET Core

    This week's edition of ASP.NET adventures: kick starting an MVC app with ASP.NET Core!

    On the front-end side of things: Two things that make this a really delightful and smooth process are Razor Pages and Tag Helpers.

    My MVC experience up to this point has been with templating engines in Express. What they do well is make it dead simple to get data into the template. The limitation is flexibility and reactivity. (Especially coming from working mostly in React.)

    ASP.NET MVC apps have a really nice in between through these two tools.

    I'll show the setup with Models and Controllers first, then on to views in action!

    (Code samples and all of my info here are coming from this great introductory video to MVC in ASP.NET Core 6)

    Models

    Here's a look at the model I'm using:

    using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    namespace BulkyBookWebDotNet6MVC.Models
    {
        public class Category
        {
            [Key]
            public int Id { get; set; }
            [Required]
            public string Name { get; set; }
            [DisplayName("Display Order")]
            [Range(1, 100, ErrorMessage = "Display Order must be between 1 and 100")]
            public int DisplayOrder { get; set; }
            public DateTime CreatedDateTime { get; set; } = DateTime.Now;
        }
    }

    Nothing fancy! The code in square brackets are used by Entity Framework for field validation. DisplayName will affect what's rendered in the view, for example. Otherwise DisplayOrder would be the defaut.

    Controller

    Setting up controllers is a straight-shot. Grab what's needed from the database and send it the view.

    // GET: /<controller>/
    public IActionResult Edit(int? id)
    {
        if (id == null || id == 0)
        {
            return NotFound();
        }
    
        var CategoryFromDb = _db.CategorySet.Find(id);
        //var CategoryFromDb = _db.CategorySet.FirstOrDefault(u=>u.Id == id);
        //var CategoryFromDb = _db.CategorySet.SingleOrDefault(u=>u.Id == id);
    
        if (CategoryFromDb == null)
        {
            return NotFound();
        }
    
        return View(CategoryFromDb);
    }
    
    // Post: /<controller>/
    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Edit(Category obj)
    {
        if (obj.Name == obj.DisplayOrder.ToString())
        {
            ModelState.AddModelError("name", "Display order cannot match the name.");
        }
    
        if (ModelState.IsValid)
        {
            _db.CategorySet.Update(obj);
            _db.SaveChanges();
            TempData["success"] = "Category updated successfully";
            return RedirectToAction("Index");
        }
    
        return View(obj);
    }

    View

    Here's an example of a "Create Category" page for an app:

    @model Category
    
    
    <h1>Create</h1>
    
    <form method="post">
        <div class="border p-3 mt-4">
            <h2 class="text-primary">Create Category</h2>
            <div asp-validation-summary="All"></div>
            <div class="row pb-2">
                <label asp-for="Name"></label>
                <input asp-for="Name" class="form-control" />
                <span class="text-danger">@Html.ValidationMessageFor(m => m.Name)</span>
            </div>
            <div class="row pb-2">
                <label asp-for="DisplayOrder"></label>
                <input asp-for="DisplayOrder" class="form-control" />
                <span class="text-danger">@Html.ValidationMessageFor(m => m.DisplayOrder)</span>
            </div>
            <button type="submit" class="btn btn-primary" style="width: 150px;">Create</button>
            <a asp-controller="Category" asp-action="Index" class="btn btn-secondary" style="width: 150px;">
                Back To List
            </a>
        </div>
    </form>
    
    @section Scripts{
        @{
            <partial name="_ValidationScriptsPartial" />
        }
    
    }

    At the top, we're bringing in my Category model with @model Category. The controller takes care of sending this to the view both on GET and POST requests:

    For the most part, I'm just writing regular html. If I needed to include anything from the model, I could throw @Category.Name anywhere and it will render to the page. Any C# that I wanted to write just requires the @ symbol.

    Tag Helpers

    The killer part of the example for me are the asp- attributes. These are Tag Helpers that inject a lot of functionality automatically.

    Take a look at the name field:

    <div class="row pb-2">
        <label asp-for="Name"></label>
        <input asp-for="Name" class="form-control" />
        <span class="text-danger">@Html.ValidationMessageFor(m => m.Name)</span>
    </div>

    asp-for on the label and input will know to populate the name input with the value from name, as well as pull from it when the form is submitted. Also included is client side validation automatically. When an error is found, the message is then passed to the @Html.ValidationMessageFor(m => m.Name)

    That's it! It's a fair bit of magic, but it saves a lot of code that would normally be done by hand in JavaScript, or requiring a heavy library.

    Learning the Neck on Guitar

    Guitar has hands down been the hardest instrument I've played as far as getting familiar with the notes.

    Saxophone, admittedly, is one of the easiest. You really only have to learn 20 different finger combinations, and then you know most of the instrument.

    Piano is even easier!! You learn 12 notes and you can apply that to all 88 keys. Maybe you could say it's more like 24, since you're also reading bass clef.

    Here's the thing about those instruments: They are two dimensional. You play up the piano, and gradually go up. Same with sax and most wind instruments.

    Guitar, though, is three dimensional. You can go up the instrument by following a string up or by hopping to another string.

    Wicked.

    If you're like me, you can go surprisingly far on guitar without knowing too many notes, too. A trained ear and know that a scale is a series of whole and half steps does wonders.

    But! It doesn't take me far enough. So here's how I'm going about actually learning where every single note is on this instrument:

    1. Reading Sheet Music over tabs.

    For bettor or worse, I learned to read music from the page.

    If you're learning and you don't already read music, I'm not sure it's that necessary depending on what you want to do. If you already do, making the notes visual is a pretty great first step

    2. Barre Chords

    A two for one: Once you can play barre chords, there's no better way to get familiar with the thickest two strings than with playing this across the instrument.

    3. Hardcore Memorization

    The least sexy, but the most effective. A professor of mine from undergrad, while learning Portuguese, said it plainly: "There's a lot of romanticizing around immersive learning. While that's all fine and well, nothing beats buying a dictionary and memorizing the words."

    The point isn't one is better than the other, you need both, but guitar players (especially me) can be guilty of only playing and putting off learning the notes through a more rote approach.

    Thankfully, it's infinitely easier in 2023 with apps and online tools.

    At the risk of this blog sounding like a sponsored post: My favorite is Justin Guitar's Note Finder App. It's what you'd expect and a little more: Finding the note on a nice GUI, an option to try and identify what note is being shown. It even feels like a game, so it can be addictive to study the neck this way.

    4. Triads

    My next step is moving on to playing triads to bridge the theory to actual music making. More improv on it coming soon. 😁

    250 Box Challenge and Repetition

    I'm doing the 250 box challenge right now. It's the namesake for the website drawabox.com.

    The gist: You draw lots of boxes in 3 point perspective. In pen. And you extend your lines at the end to check that the points converge towards a vanishing point.

    Brutal.

    The exercise looks like this:

    📦

    The point is to get familiar with perspective. And every now and then I stop and ask "am I doing this wrong? Are there any tips? Am I just not looking at it the wrong way. Maybe if I find another guide..." It's a question I've had for most art. If I find the right strategy, I'll just know how to do the thing.

    But, in my experience so far, there is just some intuition that comes from repetition. There's no real strategy aside from "do it again, but try another approach."

    On a practical level, what helps me is to plot a dot for where I think a line will go and then ghost it like crazy. I'll intentionally plot one that I know is parallel as a reference if I'm really unsure.

    But, for the most part, it's like learning a sport or an instrument: the more you do it, the more your brain will learn the fine-motor control of what you're trying to do.

    That's what really struck me! Just like I have to practice scales, I have to warm up on drawing lines.

    I kind of wish the challenge was called "Draw 250 boxes (mostly badly!)" since that's the intention behind it!

    All this to say: Art, especially at the beginning, is just as much a physical skill as it is a design skill.

    My First Website from 2005

    Table layouts, table layouts everywhere!

    Like many folks born in the early 90s, I grew up with the web. You could say we both grew up alongside each other! I was right on that edge of entering elementary school just as the internet became a household utility.

    I was coding my first few webpages at 8 years old, which is wild to think about looking back. I played lots of Neopets at the peak of its heyday. The platform exposed a way for player's to add custom HTML for their shop pages and profiles. With the help of some kid-friendly HTML resources, I was able to add midis, custom cursors, and all sorts of Geocities-era site features!

    Fast forward into my teens, on the other side of the early rise in Youtube's popularity. I took up video making and sketch writing for fun. And most of the "pros" (at least, the larger channels) had their own websites.

    I was already drawing comics at the time, too. I would pass a four-panel strip around and share them with friends in class. Like a daily syndication, but on notebook paper and in No.2 pencil. I wasn't aware of the rise of webcomics online at the time, but it occurred to me all the same that having a home for those doodles and videos would be a pretty neat idea.

    And so, moomoofilms.com was born.

    Unfortunately, most of the site has been lost to time. The HTML was coded directly on my hosting service's platform, which shut down years ago. I still have the videos on a hard drive (too juvenile to share publicly, but endearing all the same!) The comics are gone, maybe in a folder back in my parents' attic. And a few small technical experiments and widgets have been lost too. (Moral of the story: Back up your files!)

    Thanks to the Way Back Machine, I was able to recover the landing page!

    Technical Comparisons

    A few fun observations comparing this to modern websites:

    • Photoshop was a required skill for making sites at the time. The main banner and featured videos section were probably made in MS Paint, tough.
    • When a new post went up, I simply edited the HTML by hand. I didn't realize many sites had a CMS behind them! I would have been blown away by WordPress
    • A missed opportunity: Those posts could have had an RSS feed!
    • Tables layouts! Without flex or grid, this was how most developers were creating placing their content/
    • No CSS file, really. Any CSS is done inline or with an HTML tag, like the deprecated <font /> and <center /> tags.
    • No JavaScript, ethier! I would have earned a perfect score for performance in my web core vitals.
    
    <table border="0" cellpadding="2" cellspacing="1" style="border-collapse:" width="505" bordercolor="#666666" valign="top">
     <tr>
          <td width="503" colspan="2" background="./assets/news.jpeg">
            <b><font size="2">Happy Belated New Year! - 1/20/08</font></b>
          </td>
      </tr>
      <tr>
            <td width="51">
                <img border="0" src="./assets/aimbagelboyfield.jpeg" width="50" height="50"></font>
            </td>
    
    
            <td width="451">
                <p align="left">
    
                    Good News, everyone!
    
                    ...
    
                </p>
            </td>
        </tr>
    </table>

    The Good Ol' Days

    My site pre-dated widespread social media. If you wanted an online profile, you had a few options like Livejournal, Blogger, WordPress, etc. Or you did what I did and rolled up your sleeves to put the HTML together.

    That lent the internet to so much customization and ownership! Compare that to the cookie-cutter profiles across social media now.

    Making sites was a unique, widespread way for a broad audience to be introduced to programming. (Calling HTML programming is a stretch to some, but I say it counts!) I know plenty of developers that got their start customizing MySpace, Tumblr, and WordPress pages.

    Today, It's great that anyone can make a profile on any platform and start sharing. I'm nostalgic, though, for the inherent ownership and creativity that was baked into the early days of the web.

    Especially for kids! In passing, I think about how my future-kids will develop their own technical literacy. Impossible to say now, things continue to change so quickly. But, so long as there are platforms for them to get their hands dirty, play, and really mess around with what's under the hood, I'm sure there will be a way.