Author: CapnPilot

  • Refactoring & Rewriting

    So in the past couple of days I’ve been making a lot of… I suppose I’d call them tweaks, because nothing feels big enough to consider it a major change. Could I even make major changes in a two day timespan without just hunkering down and doing nothing else? Probably not.

    So what have I been doing? Mostly refactoring, honestly. Initially I had a couple of methods for updating the wordcount, checking whether to update the day, etc., but I was running a lot of them in multiple lines the __main__ function rather than calling a single clean method. So I wrote a method, getUpdate(), and then subsequently retooled that method to make it more versatile.

    Before getUpdate() would ask you for how many words you’d added to your total, then staple those on to whatever your current total was already (right now it’s always 0, because the program doesn’t retain information between sessions). Now the method will ask you whether you want to add words or give your new total (so, stapling words onto the preexisting total, or replacing that preexisting number entirely); then it calls one of two helper methods based on that, in order to do what you want.

    Those helper methods also ended up having me refactor and split off more helper methods, which has honestly been a good exercise in thinking through what each line is doing and where it might end up getting reused.

    The other biggest “change” has mostly been clearing up my comments, which refactoring has also helped with. Python doesn’t render multi-line comments natively, so the convention is to enclose them in “””s (triple quotation marks), which causes it to register as a multi line string that the computer will just sort of ignore when it comes time to parse. I’ve been using my pre-method comments both as a place to describe what a method is supposed to do — this is good practice — and a place to keep notes about questions/concerns/functionality I might add (this is messy practice). But hey, this project is only for me, right?

    Well, a different problem arose, and it feels a little superficial. My text editor, Atom, color-codes everything in order to help with readability, and it renders all of Python’s strings in a bright green. This works great to offset strings from other things, but when I have lines and lines and lines of green, it makes it hard to see anything else, because it draws the eye so much. Refactoring and tweaking has been as much a way for me to strip down my notes to a point where I can use one or two single-line comments and get rid of the green, as it is to improve my code.

    The next big questions (that I’m scared to answer) will probably be: how do I store information between sessions? And how do I test multi-day streaks? The multi-day streaks will have to come after the storing-between-sessions question, just on account of I can’t have multi-day updates if I can’t store between sessions, but once I’ve got that… hopefully more things will start falling into place.

    More potential avenues for the future, non-immediate: can I/should I practice test driven development with this (might be a bit close to my Model/View/Controller thoughts from last time, haha)? How do I integrate a Python app with Javascript (am I going to need to figure out Flask, which I don’t even know what that is)? Is it possible that I’ll have to “finish” the program, then rewrite it in Java to make it compatible (eek, but I sort of miss Java’s structure compared to Python’s spaghetti-noodle flexibility)? How do cookies work? Should I take a day to just work on building really basic HTML sites with interactive fields and buttons (yes)?

    And, just for the sake of long-term organization and consistency, I should probably a) make a more structured planning document and b) get a GitHub where I can keep better records of what I’ve been doing day-to-day.

  • Messing Around with Python

    In my ongoing saga of “How do I build a web app?” I decided that a good first start would be to build just a regular program that does the things I’d ideally like my first web app to do. In this case, in the spirit of National Novel Writing Month, I’ve been thinking about what’s needed to make a wordcounter/streak tracker/maybe some other things. You know, a cohesive idea like that.

    The wordcounter and streak tracker will probably be fairly easy to implement just on my machine, as it’s pretty much all numbers, so I’m starting there (famous last words?). I’ve actually already started with them. Once I’m happy with them, I’ll try setting them up to work as a really basic, no-styling web app locally, and then we’ll take a crack at deploying using Docker. Probably still without styling, because the longer I can put off untangling the horrible spaghetti that is CSS, the better.

    Why Python? Some pretty superficial reasons, honestly:

    1. I have prior experience in it, though not for a while;
    2. I own a textbook that’s designed to teach you programming using the Python language, which should be useful considering it’s been a while since I’ve really made any significant projects;
    3. and I don’t have to install any new languages on my computer to make it work.

    I considered Java, which fulfills condition 1 and makes up for condition 2 by having JavaDocs (JavaDocs is a work of art), but which doesn’t fulfill condition 3; then I considered Ruby, which is something that I’ve wanted to become proficient in for a while, but which doesn’t actually fulfill any of those conditions. Sad face. Better, I think, not to try to learn two things at once if I don’t have to (especially when I’ll need one to learn the other).

    So far I’ve only implemented three methods: one for getting an updated wordcount & changing the total, one for setting the most recent day updated if needed, and one for checking whether the most recent update requires the most recent day to also be updated. (That’s a lot of recents and updates – I may need to adopt better terminology.) There’s also a main function for getting input through the command line & using it to update the words total & most recent day.

    Plans for the future:

    • methods for tracking the total number of days a person has updated their wordcount
    • methods for tracking the number of days in a row a person has updated their wordcount
    • working out how to make this work with HTML/Javascript to create a local web app
    • Potentially: working out how to effectively backdate updates and integrate them into the streak; working out how to store all this w/ cookies on the user’s machine

    Questions for the future:

    • How/where am I going to store info in between sessions?
    • Can I implement this using the MVC model, or is that too much while I’m getting back in the swing of things? (Potentially I could do the whole thing, then refactor all of it into MVC, but that sounds like a huge pain.)
    • What even is the relationship between Python & Javascript for this stuff? It’s been a very long time since I used Javascript.
    • Probably more things that’ll come up soon!
  • Docker for Beginners: Hello, World!

    Today I got started exploring Docker for the first time, using A Docker Tutorial for Beginners. Reclaim Cloud runs using Docker containers, and a few of us will be doing some research on it in the next month or so, so it seemed like a good thing to try.

    Docker is, as I understand it, a system for running containers, which are a less resource-intensive alternative to virtual machines. You can spin up a container using a particular system, run it while you’re using it and pause it while you’re not, and interact with it through the command line.

    I spent most of today messing around with the Docker Desktop interface, which I found extremely frustrating — the tutorial itself was lovely, but… essentially, I understand that documentation is usually aimed at the lowest common denominator, but today I wish they had aimed a bit lower. Specifically, nearly all of the features that the documentation offered instructed you to click on a button shaped like a tiny whale, which would open a pulldown menu of options that you could then choose from. It took me forty-five minutes and another person’s help to find the tiny whale, which turned out to have been placed not anywhere in the actual window of Docker Desktop, but in my menu bar at the very top of the page, where it could blend in neatly with my clock, my battery and my Wi-Fi indicator.

    Today I worked up through the Hello, World! section of the tutorial, which got me through both how to set up Docker & Docker Desktop, and what some of the basic concepts and tools of Docker are. To the best of my understanding, Images are a bit like modules or applications – they tell Docker what any container modeled on that image will be capable of doing. Meanwhile, Containers are individual instances in which to run your programs.

  • JavaScript with LinkedIn Learning, Day 4

    Just a short post today. I’ve been following up on the practice exercises from last time, building a class and using it to create objects. I ran into some issues with it, though — I can’t access my new class and its constructor from the browser console.

    My first suspicion is that it’s because I switched browsers (formerly using the Firefox console, now using Chrome). Maybe Firefox is more forgiving in some way — but I can’t think of why this would be. Might be some way in how I imported my code into the HTML doc, but I’d be very surprised about that. I checked the template to see whether I was missing something and saw a statement of export default [ClassName], so I added that to my new class, but it didn’t make a difference.

    I went into an older example of script.js from one of the non-practice lessons, which showed how to import classes, and made sure I’d set everything up right (having different JS modules imported in the right order, etc.), but still couldn’t make it work.

    That’s all for today, but I think next steps will be to go through the ES6 import syntax and see if there’s anything else I can do to fix this.

  • JavaScript with LinkedIn Learning, Day 3

    Another day, another example of JavaScript doing things strangely, where strange is defined in the self-centered manner of “not how I would expect, based on what I learned”. This time it’s the flexible method of creating a class: either using a declaration:

    class ClassName { properties }

    Or using an expression:

    const ClassName = class { properties }

    According to the lesson the trend is towards using an expression, but the instructor uses a declaration, and it seems to me to line up with other languages’ way of doing things a bit better.

    You can also create a “class” of objects just by creating a constructor function, which will contain all the properties including other functions (in the declaration and expression options, the constructor function is separated out from the other methods of the “class”), like so:

    function ClassName ( attributes ) { properties }

    Here attributes are the variables passed into the constructor and properties are any work done to set the instance variables, any other variables, and any other functions the “class” might have.

    The tutorial makes a point of saying that creating a “class” by just using the object constructor function is not the same as making a real class, and that real classes are much more flexible and extendable than just using a function, so the third option is not recommended; it’s just that JavaScript didn’t have classes for a while, so older code and tutorials might use object constructor functions.

    That’s going to be all for today — hoping I get some time to put this into practice soon.

  • JavaScript with LinkedIn Learning, Day 2

    Bracket Notation

    The first big thing today was learning about accessing the properties of different objects. The standard notation – aka, what I’m used to – is dot notation (object.property), but today I discovered bracket notation, which looks like object["property"]. This is used for cases where the property is a variable rather than a constant, or the property might not conform to JavaScript naming conventions (basically, there’s nothing preventing an object or variable from being named in a way that breaks the rules, so the code will only break at runtime, and even though you would never write such messy code, you might end up using data that wasn’t meant for JavaScript). It’s a safety valve.

    Object Practice

    It looks like I actually worked a little bit ahead last time when I decided to design my own soup objects. There’s actually a built-in stopping point in the tutorial where you’re encouraged to pause and put into practice what’s just been covered. I ended up having to go back a little bit to last week’s exercises, as over the weekend my memory of the syntax got foggy, but I ended up building a JavaScript “earring box” object (the tutorial encouraged making a container object, so that you could have smaller objects inside your object).

    const box = {
      name: "Earring Box",
      material: "velvet",
      color: "black",
      pairs: 1,
      earrings: {
        material: "gold",
        style: "dangly",
        length: 1,
        gems: "rubies",
      },
    };
    
    console.log(
      "My earrings are",
      box.earrings.material,
      "and I keep them in a",
      box.color,
      box.material,
      "box."
    );

    And a quick screenshot to fix those readability issues:

    So far, so good. I’m sure I’m not breaking any new ground when I say that, for all that it’s based on Java, JavaScript has some major stylistic differences that are tripping me up. Most primarily the way it’s having me declare variables, though I’m currently willing to suspend judgement as the tutorial acknowledges that it’s doing things a little bit out of order for the sake of learning.

    Functions

    The next step, after making an object and giving it properties, was to work ahead on functions. This bit was also something I skipped ahead on last week, as knowing how objects and methods work means that I could recognize the patterns early. Interesting to me, though, was that in the same way that JavaScript has an alternative to dot notation, it also has an alternative syntax for declaring functions (and one which the instructor said was considered more common and better practice).

    The difference is between method(arguments), what I would consider the conventional way of doing things, and method: function (arguments), where the method is listed as a property of the overall object in the same way that other variables and constants might be. In my example code, box might have openBox: function (lidUp) as a property alongside name and material.

    Making My Own Functions

    The function practice exercise didn’t involve adding functions to the object I designed (though I might go back and do that anyway); it gave a template backpack object and asked us to create functions to change the properties the backpack already had, and describe those changes. I also ended up creating an extra method called introduceMe() in order to save a little time on the sentence describing the changes:

    introduceMe: function () {
        console.log(
          `This ${this.color} backpack is named ${this.name}. It has ${this.pocketNum} pockets and holds ${this.volume} liters.`
        );
      }

    In doing so I figured out how to insert variable names into strings, which will save tons of time in the future.

    End-of-day reflections: this tutorial isn’t doing a lot to teach me new principles of coding, but it is getting me more familiar with JavaScript syntax and getting me back into the rhythm of writing code, which is honestly all that I’d hoped for from it.

  • JavaScript with LinkedIn Learning, Day 1(ish)

    As per usual, the “first” day was all setup, and the real day one is where the learning starts. I’m following along with this tutorial in LinkedIn Learning, to get familiar with some of the basics of JavaScript.

    Fun Little Tidbits

    Special Commenting Trick: First, I learned that you can put your cursor on a line of code (or highlight multiple lines) hit CTRL+/ in order to comment out those line(s). Probably old news for some people, but absolutely magic to me, I’m a very big fan.

    Special Editing Packages: Part of the tutorial was also installing ESLint and Prettier, two packages that will automatically check for syntax and formatting errors and either call your attention to them or clean them up (so, ESLint will flag errors, and Prettier will enforce rules about semicolons and spacing in order to make your code more human-readable).

    Now I Know

    Order of Operations

    JavaScript works in concert with HTML and CSS. If HTML is the skeleton and the muscles, and CSS is the skin, JavaScript is the brain and the nerves that can make it all move (I made this metaphor up myself, so if it’s inaccurate or just plain gross, that one’s on me). In an HTML document, it might look like this:

    <script src="script.js"></script>

    It’ll be located somewhere in the <head> section of the HTML document, alongside the CSS source and other metadata information, for purposes of well-organized code.

    If your HTML script tag written like this, then as the page loads, the browser will read through the document, hit the script section, and start working through whatever’s in script.js. Which is great, unless script.js needs to act on code that hasn’t loaded yet.

    Okay, so we put script.js at the end, outside <head>, in the <body>. But no, wait — that’s bad for code organization, and what if we want script.js to be referenced by stuff that needs to load after it?

    <script src="script.js" async></script>

    The way to fix this is the HTML terms defer and async. async means that, rather than running the document, hitting JavaScript, loading the whole script, then running the whole script, it’ll run the document, hit JavaScript, and then load the script while continuing to run the document/load the page; once it’s done loading the script, it’ll stop loading the page, run the JavaScript, and then go back to loading the page; defer is similar, but it saves running the script until the entire page is loaded. This way you can have the code organized neatly and run at the right times.

    The difference between the two is in part down to render time (or, how long it takes for the page to fully load). Without async, the page stops loading in order to both load and run the JavaScript, seriously impacting render time; async impacts render time slightly by loading the script in parallel with the page, then stopping momentarily to run the Javascript before continuing with the page; and defer doesn’t impact render time (because it doesn’t run until the page is all loaded) but does make you wait on your JavaScript.

    What I Made

    After messing around with the tutorial on how to create objects and declare their properties and methods, I decided to mess around a little in the console and create my own. What I learned is that if you create a constant object, run the code to see if it works, clear the console, add in some more properties and functions, and then re-run the code to see if it works, that doesn’t necessarily actually get rid of the original object, and you will get error messages telling you that you can’t re-create the object, because it already exists as a constant.

    I ended up just renaming the object, because it was simpler.

    Anyway, if you want to try my code, here you go! See if you can guess what it does before running it.

    const beefSoup = {
      broth: "beef",
      numPotatoes: 6,
      noodles: true,
      strain: function () {
        this.numPotatoes = 0;
        this.noodles = false; },
      tellMeAboutIt: function () {    console.log(this.broth, this.numPotatoes, this.noodles); }
    }
    
    beefSoup.tellMeAboutIt();
    beefSoup.strain();
    beefSoup.tellMeAboutIt();

    The formatting’s a little funky because WordPress doesn’t respect line breaks, so here’s a screencap of it as well.

  • Rails Girls, Day 3

    Been a while, hasn’t it? Anyway, I’ve finally had a bit of time now to sit down and revisit the tutorial.

    The next steps in the tutorial (the link is here if you’re interested) are regarding adding picture/file uploads to the server (so, section 4). This bit started off pretty simple. I did hit that one error they warn you about, where the uploader cannot be found and you need to add another gem, but that only added a step that was basically identical to the one before it, so it was fine.

    The only major snag I hit was in the step which has you add the code showing the picture (rather than just its filepath).

    They ask you to change

    <%= idea.picture %>

    to

    <%= image_tag idea.picture_url, width: '100%' if idea.picture.present? %>

    Which for some reason generated astronomical amounts of errors. The reason is probably that I did a lot of things wrong. The first error was caused by referring to a local variable as an instance variable (Ruby differentiates these by starting instance variables with an @), but I tried to fix that by using some of the formatting from a different edit RailsGirls had me make, assuming that they had just messed up their second instruction.

    <%= image_tag(@idea.picture_url, width: 600) if @idea.picture.present? %>

    Doing this did not actually fix the problem. It made it worse.

    I decided to debug by adding this as an extra list item, rather than replacing a list item already present, so that I could narrow down where the issue might be coming from. Naturally, I messed up the HTML tags immediately and caused a new issue.

    But! I found that problem almost right away, got that cleared up, double checked why/how the parentheses might be working or not working, realized that the @ symbol shouldn’t be there, removed that and the parentheses, and everything started working again.

    Verdict: I need to review Ruby syntax.

    The static pages and routes finetuning were very easy, and I didn’t run into any issues there, which means that I finished that section of the tutorial today! The next section is about pushing your work to GitHub, but I don’t think I’ll do that right away; I want to do a bit of monkeying around with HTML, CSS and Javascript before I push anything.

    Onward!

  • Rails Girls, Day 2

    It took me a little while to come back to this, as I was never really able to properly figure out what was going wrong with Yarn. Eventually I decided that, since I also have an Ubuntu terminal and Linux running on my machine, I’d get set up over there instead, which let me bypass a lot of the issues I was running into with SQLite3 and Yarn.

    So, onto the next section: Building Your First App.

    Setting Up

    The first steps were to make a directory to store a Rails app in (pretty easy), per their instructions, and then use Rails’ scaffolding setup to generate some ideas.

    This was where I ran into my first hurdle (well, with the design of the tutorial itself — I’m not counting all the technical hoops of the first day): this tutorial is designed to augment a public workshop. What this means is that there are sections that essentially say “Here we’re going to learn about scaffolding. Run this command, and then the coach will tell you what scaffolding is.”

    And then there’s no explanation of scaffolding.

    Which — not the end of the world. Google is free. But it does mean at least a few minutes get expended on sorting through the first couple of results, figuring out which ones are documentation, which are explanations and which are ads, and trying to parse these as quickly as possible without having to do a whole ‘nother tutorial to try and figure them out.

    (For the record, scaffolding is essentially running a command that will quickly write up the basic Model-View-Controller framework of your app for you, which you can then build on. It does exactly what a scaffold should.)

    Working with the Scaffold

    So the first thing, setting up the scaffold, looks a little like this:

    rails generate scaffold idea name:string description:text picture:string

    Guess what was not explained in this tutorial. If you guessed “any of those arguments”, you guessed correctly. I ended up finding the answer in one of the Ruby on Rails Getting Started guides, section 6.1. The quick answer is that this forms a table for storing “ideas” where each idea has three attributes (ideas are rows, attributes are columns). The arguments are the name of each attribute, and its datatype. Simple enough concept, and again something that would probably have come across better in a live workshop.

    [a brief intermission while I check if Rails Girls has recorded any workshops]

    [none that I can find]

    [intermission over, we proceed]

    After setting up the scaffold, updating the database, and running the server, I opened the site and found an empty table with a “New Ideas” button. The button opened a field looking like this:

    The new ideas form and its fields.

    Hey, presto! A couple of ideas later, and the table is beginning to look a little fuller.

    The ideas table, now populated with two ideas: “Add Bear” and “Destroy Bear”.

    And yes, I tested “Show”, “Edit” and “Destroy”. They do about what you’d expect.

    Design

    The next section (again headed off by “The coach will explain this part”) talks about the ‘View’ part of a MVC model, and which part of a view is HTML versus which part is Embedded Ruby (ERB). It doesn’t really explain how the two connect up, nor which part of a view is made of which. I have some familiarity with MVC from my computer science classes, if I didn’t, this would probably be another place where Pilot Stops to Google.

    Went through the design bit; it was semi-easy, semi-interesting. When I’m working in HTML I’m always aware that there’s lots I don’t know, but it all follows so easily from what I do know that it feels like it goes almost too smoothly. I did learn about how ERB works in this context:

    <% %>
    <=% %> 

    and presumably some other similar related ones are the tags one uses to embed Ruby into the page. I found that one out on StackExchange, where I was also assured that Haml is a far superior alternative for embedding Ruby into web pages.

    Saved the code; ran the code.

    I got surprised when saving the code and visiting the main page (localhost:3000) didn’t do anything, though – the styling only appeared on the page for the Ideas app (localhost:3000/ideas). I don’t know why that is yet. Right now my guess is something to do with the idea that there’s only dummy content on the main page, and the scaffold generated is just for the /ideas page. To be investigated.

  • Rails Girls, Day 1

    Well, day 1.5? Day 2? The point is, I did a (very little) bit of the setup yesterday, but ran into a roadblock that I couldn’t resolve until now.

    I’ve been working for a while on how to learn/run Ruby, and for now I’m settled on following some of the Rails Girls guides for creating web apps. Rails Girls is an organization that runs events teaching girls how to code in Ruby on Rails, but they also have tutorials online here.

    So far, this has been an exercise in Googling a lot of stuff to see whether my computer will run things compatibly. The biggest two hurdles have been SQLite3 and Yarn (out of Ruby, Git, Node.js, SQLite3 and Yarn).

    For the former, the issue has been determining whether they have a toolkit for 64-bit computers (they don’t), whether they have SQLite3 itself for 64-bit computers (they do), whether I can run the 32-bit toolkit on my computer (I can), and whether I can mix the 32-bit toolkit with the 64-bit version (I decided not to bother, since I can run the 32-bit version as well).

    For the latter, it’s been trying to figure out why I could successfully install/update Yarn over and over again using Node.js, which was determined to be running, but not actually use any of Yarn’s commands (apparently you have to restart your computer. No one told me).

    Update from several hours later: restarting did not fix it. I think I’ll need to add the folder to my PATH in order to be able to use the commands. Will investigate tomorrow & hopefully be able to write up a little more about what is happening.

css.php