Bananalogies in Javascryptography

Have you all read Douglas Hofstadter’s beautiful Gödel, Escher, Bach: An Eternal Golden Braid? You should go get your copy. If you don’t have one yet, you can take one home for your very self here. I’ll wait. The internet always waits.

Ok! Remember the terrific inter-chapter dialogues between the Tortoise and Achilles? Remember the one about pushing and popping, meta-Genies, and the Majotaur, “Little Harmonic Labyrinth”? Page 103 in the 20th Anniversary edition. Hofstadter was something of a computer scientist (while being rather disinterested in programming itself), so it’s no surprise that the mathematics of this dialogue (and indeed of the entirety of the delightfully dense GEB) read like a computational theory problem wrapped up in a Lewis Carroll witticism (whom Hofstadter adores and references frequently in the book).

I’m getting lost in the book, as I so often do : ) but my point here, other than urging you to GO! GO! READ THIS BOOK! IT’S HARD AND THAT’S OK! is that javascript’s class inheritance reminds me just a bit of this airy idea of pushing and popping from world to world. Each class is its own world, and pushing from that class is another class that can only come from the initial one.

function Feline = (name, type) {
    this.name = name;
    this.type = type;
};

Now let’s add a method to this class:

Feline.prototype.infoPrint = function() {
    for (var i in Feline) {
        console.log(Feline.i);
    }
};

And now, let’s make a new thing altogether. Notice the third attribute:

function DSH = (name, type) {
    this.name = name;
    this.type = type;
    this.color = color;

And now! Since we know that Domestic Short Haired cats are a kind of Feline, let’s make it so officially, and actually CREATE an animal out of this!!

DSH.prototype = new Feline();

var morris = new DSH("Morris", "ornery", "buff and white");

Also notice that only objects created from constructor DSH will have the attribute color, but the regular Feline class will not. DSH is a push down from Feline, and divining objects from the constructor DSH will only give us specific DSHs, which have all the characteristics of Feline as well (though I believe those are specially mutable even after you’ve defined them, but more on that later, when I understand better too [which I am pretty sure can be strung into the metaphor of popping, perhaps?!] : ))!

So, go ye, and read of Gödel, Escher, Bach: An Eternal Golden Braid and tell me what beautiful mathematic or programmatic relation he makes you think of, and, likely, consider in a whole new way!

Last thing: once, on the train (a multi-day, cross-country trip), I had that book in my hand, waiting to get a morning coffee so I could sit and read it (I’ve still only read up to page ~130), and a gal came up to me and said “I read that book thirty years ago, and I’ve been reading it ever since.” Still the finest commendation for a book that I’ve ever heard.

Rabbit object constructor with nested function

EDIT: no longer private, because the notes are good and I thought back to them this morning, so, good enough for me! This is from Codecademy Introduction to Objects 1 25/33.
Private because a) it’s not my code and b) there’s no commentary but it’s important enough to log

function Rabbit(adjective) {
    this.adjective = adjective;
    this.describeMyself = function() {
        console.log("I am a " + this.adjective + " rabbit!");
    };
}

// now we can easily make all of our rabbits

var rabbit1 = new Rabbit("fluffy");
var rabbit2 = new Rabbit("happy");
var rabbit3 = new Rabbit("sleepy");

rabbit1.describeMyself(); // called with constructed object, NOT constructor name.
rabbit2.describeMyself(); // constructedObject.internalMethod
rabbit3.describeMyself(); // output: "I am a sleepy rabbit!"

More JS Hobgobjects

Oh, wow, javascript object constructors. Cooooooooooool. Let’s dive right in, shall we?

function Expenses(AP,dollarsOut,frequency) {
    this.AP = AP;
    this.dollarsOut = dollarsOut;
    this.frequency = frequency;
    this.goodExpense = "maybe?";
};

var phone = new Expenses("Sprint Cellphone Bill", 160, "monthly")
var restaurants = new Expenses("Restaurant food out", 300, "monthly")

console.log("You spend " + restaurants.dollarsOut + " on " + restaurants.AP + ".")
console.log("Is " + phone.AP + " a good expense? Answer: " + phone.goodExpense)

Output:

You spend 300 on Restaurant food out.
Is Sprint Cellphone Bill a good expense? Answer: maybe?

To unpack this a bit, the constructor Expenses up there is defined up top with three attributes, which then makes the template creation of objects a SNAP. So phone and restaurants are whip-fast created. I can even make an attribute, like this.goodExpense, that’s not part of the callable constructor, but which every object created from it retains that defined attribute! AHHHH THAT IS SO COOL flail

And I can just access the attributes of these objects this easily! Seems magical. The this requirement of objects in JS is a little more approachable. Sorry for the flurry of posts – I just really, really want to get this course done, AND OBJECTS COMPLETELY UNDERSTOOD, so that I can move onto my next project which I am so so so excited for : )

Hobgobjects

I want to know OOP. I basically do, but I want to get the syntax all the way down and also ALSO be able to use them, which I’ve only done to the extent that I’ve copied fabulous OOP luminaries’ code. So far, I don’t have much to say, but it is just! so! important! that I make a note of what I learn when I learn it.

var functionName = function (parameter) {
    this.thing = newThing
}
var objectName = new Object();
objectName.methodName = "methodQuality";
objectName.functionName = functionName;  // this is what I'm having trouble understanding.

Hm. That’s.. that’s not really clear. the this piece of the object creation reminds me a bit of the confusing nature of self in Python. Is that a reasonable analogy?

Going to copy this piece from the codecademy lesson: “Then when we say objectName.functionName = functionName; (line 9), it means whenever we type objectName.functionName( ), this.thing in the functionName method will refer to objectName.methodName.” Maybe I just need to whisper that to myself mystically while sailing along on my bike. Yes, that must be the answer!*

*I’ll get there : )

For loops in Javascript

I learned this probably fifty lessons ago, BUT going through the blog I see I hadn’t noted it yet, and it’s just different enough from Python that I ought to at least make a note of it. It also addresses some of my thoughts from my first long-form Javascript post on the range function.

for (var i = 1; i <= 20; i++) {
    console.log(i)
}

That’s all! A bite-sized one today : )

Git Wizardry

We interrupt your irregularly scheduled blog post to brag gently inform the universe about a huge Git problem I just solved here at work.

Yesterday morning, my officemate looked over at me, brow furrowed, despondent, and says, “I think we just need to delete the repo and start over.”

I’ve been down this road before, and it’s the cause of and result of many, many frustrations. Several months ago, while working on Intermediate Python, we came across this issue as well. You may know this story in your own travels/workplaces, but everyone involved in the project had push and pull access. Everyone has push and pull access because then it is equitable and flat*.

The problem with everyone having push and pull access to the master branch is the the technical difficulty of tracking changes, the very problem that Git purports to solve. So Steve and I deleted the repo, preserved it locally (of course), and made a new repo with the same name. You may be cringing – I am too at the memory of it! It kinda-sorta-60% solved our problems, but looking through my local files on the project I really can’t discern which copy of things is the “latest” one. There are other problems in this “fix” that are so alarming I’m not even terribly interested in sussing them out as a completed project.

So, to my officemate, I said that no, we will not be deleting the repo. Rather, we will be changing our workflow. I started by researching ordinary forking systems and how to set them up, but none had any info on how to move from a pushing and pulling workflow to a choked forking system. “Choked forking system” is my term, no one else’s, but it seems descriptive in that access to PR approvals is restricted to owners.

As preparation, I resolved all branch differences. Merges from dev to master should have been done way before they were, but with everyone pushing and pulling, things were getting really murky and entangled. Those merges were really the only “gitched Earth” (à la ‘scorched earth’) actions I took. But because the project is still small – maybe 30 files in total – and because I was familiar with all of the files and major changes that had been done, I was confident in that. I then changed the permissions on the repo to READ ONLY, a crucial step that limits push access to owners only.

The next step is to actually fork the repo – since the access has been restricted, that is now the only way to alter the contents of the repo. Since our team was moving from a universal push/pull system to a forking system, it’s important to note that the contents are local to each contributor’s machine. The only thing that changes from a user’s perspective is the remote pointer. git remote add RachelsFork git@github.com:rachelkelly/RepoName.git is an approximation of how that’s done, with the fork, user & repo names needing personalization, of course.

Here, we use the command line for pushing, pulling, committing, and the github.com GUI for forking and merging. I keep hearing about terrific client-side GUI options, and I suspect those will assist with other Git difficulties as well.

Git is a work in progress, but in the last few days I have come a LONG way. Recently I led a group of PyLadies in a Git exploration because the more I talk to people, the more people I meet who seem genuinely afraid of this tool. I would bet under 10%** of users are confident in ordinary, command-line based usage of Git. My focus in the meetup of the beginning of this month (we’re having another in a few weeks, linked above) is just to explore in a friendly setting, pushing and pulling and forking and merge-conflict-resolution. Even though Git remembers everything, it’s still intimidating to push to something that “works” now, significantly moreso if it’s production code. At the last meetup, others did some forking, merge conflict resolution, and more. It was all quite basic, but I learned a lot, ha ha! Next time, I want to have something to offer, and I think I’m getting closer to that. Someday, ma, I’ll be a git wizard!

*I will write more one day on the myth of “flat” structures.
**Pretty sure it’s much less than that.

Javascript minichoose

With some switch/case and some conditionals, I’ve got a cutie lil game I made for the codecademy class. Load it up if you like!

Edit note, for readability I altered some of the spacing and tabbing.

var user = prompt("You are wandering along Deck 7.  People don't use this one
as much as the others, and doesn't smell as much like gorba root, the principal
trade roughage of The Captaincy.  As you rest your bones to look out the 
viewport onto the planet whose gorba the crew of The Captaincy just acquired, 
your Eye Viewer switches to life:

\n\n'ALERT ---- ALERT ---- ALERT\n\n

SHIP IS BEING INVADED ---- EVACUATE TO ESCAPE SHUTTLES FOR IMMEDIATE DISCHARGE\n\n

SHUTTLES TO DISCHARGE IN THIRTY SECONDS'\n\n

Oh no!!  What do you do?\n
 - If you would like to contemplate a bit more, type 'think'.\n
 - If you would like to look around for something to entertain yourself 
   on the no doubt long, slow voyage to the next system with unknown 
   shuttlemates, type 'look'.\n
 - If you want to just get to da choppah, type 'shuttle'.").toLowerCase();

switch(user) {
    case 'think':
        var thinking = prompt("what do you think about?  you can think 
            about 'escape', your 'cat', or 'cheese'.").toLowerCase();
        if (thinking === 'escape') {
            console.log("excellent!  you get to the shuttle.  you live!");
        } else if (thinking === 'cat') {
            console.log("such a fuzzy whatnot kitty!  too bad you are dead now.");
        } else {
            console.log("you're thinking about WHAT??  ok, you're dead.  imagine that, 
            if the ship is going down, you have to EVACUATE.");
        }
        break;
        
    case 'look':
        var looking = prompt("you look over the ship, and you find your e-reader
         with 500 of your future favorite books and a 4000-pack of eternally 
         shelf-stable, forever delicious squeaky cheese!  HOORAY!  if you take it, 
         type 'true,' if you don't (ya crum-head) type 'false'.");
        var secondThing = prompt("ok, now do you get to the shuttle?  
         type 'true' or 'false'.");
        if (looking && secondThing) {
            console.log("Moments after you and your VERY ATTRACTIVE shuttlemates 
             strap in to your anti-G gel beds, SHWOOMPF K-CHK K-CHK KSHHHHHHHHHHHHHhhh
             hhhhh, you have taken off!  Enjoy the next several years, and your squeaky
             cheese!  You won!");
        } else if (looking || secondThing) {
            console.log("I guess you got one of them?  but not both?  you still 
             win, I guess?");
        } else {
            console.log("not really sure but I guess you lost.");
        }
        break;
        
    case 'shuttle':
        console.log("you made it!  but your tummy's grumbling.");
        break;
        
    default:
        console.log("your unpredictable behavior is reprehensible.");
}