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.

Advertisement

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.

ED. NOTE 08/08/2014: One of the biggest problem-solvers our office encountered was to ensure the destination of all of our remotes. After you fork, just type git remote to list all the remotes you have designated, and then look at the destination of each one with git remote show origin and git remote show yourForkName. You ought to designate the upstream as the original repo (with git remote add upstream git@github.com:originaluserororg/RepoName.git) and make sure your origin points to your OWN fork of the material, rather than back to upstream. Note that “upstream” is a conventional term, you may call the original repo whatever you like.

Oh gosh, another thing from this Aug 8 update before I sign off again! Sorry that this is becoming enormous. Theoretically, my friends, you can entirely eliminate merge conflicts on a user level. Before you start work, pull the upstream repo and when done writing, push to your fork and then create a pull request. Then, it is only the person/people approving PRs that resolve/s conflicts, and once it’s approved, each person will then pull ONLY from upstream! LET THE CIRCLE BE UNBROKEN

back to original post:
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.");
}

switch/case

Wow, what a crazy new syntax, switch. It seems like it is some kind of deeply embedded object in javascript itself – I have no analogues mentally for it. Before I try to explain myself into an incorrect hole (now there’s a strange metaphor..), I will just go ahead and junk out the syntax so I’ve got a record of it.

var varName = prompt("you have a choice of several things here.")

switch(varName) {
    case "first choice":
        // here is where stuff happens as a result of the first choice!
    case "second choice":
        // aaannnnd second choice
    default:
        // everything else goes here if the other cases do not happen

I will poke at this and try to see how to manipulate this in different-than-standard ways. Does it need to be a prompt? I bet it can take an element of a random array. Moving on!

While I while away the javascrours

This post is mostly reference, with some thoughts on structure at the end!

Pythonic

while i < 3:
    print "still less than three!"
    i = i + 1                       # i += 1

Javascripture

var i = 0;

var whileloopfunction = function (counter) {
    while (i < counter) {
        console.log("a way more complicated way to do this, it seems!");
        i++;
    }
}

whileloopfunction(3)

Not sure exactly how to simplify this. The reason that I’ve made the parameter counter is because it seems that I must create a function with a parameter so that it can be called.

Ah – I just tried it taking the counter param out altogether and made the while loop’s condition (i < 3), calling whileloopfunction() with no argument and it works just fine. Experimentation! Sliiiightly simpler than previously, though it was a good lesson all the same.

This is looking so much to me like a simplified object, at least, simplified from the perspective of Python. This statement may confuse people – after all, Python is a more human-readable language, right? Well, its objects are a mess if you ask me, though the rest of it is lovely. I was once told that you start to really understand OOP when you learn a second OOP language. I think that is becoming true. What a relief – it's been frustrating not knowing.

Ah, one last thing – I'm pleased to present these posts to you, now written in Markdown instead of the hammer-where-you-need-a-toothpick html formatting! Thanks, WordPress!

javascript and python’s range()

So in python, you can use a function called range() to (conventionally – I know there are other uses) easily iterate over, yknow, a range of numbers or through a list/array/yaddayadda. It works like this:

for i in range(13): # you can also limit it on the lower bound, a la range(7,13), 
    print i         # but be ye wary of yon fenceepostee

While going through some javascript tutorialling, I found a typical learner problem that I found later that I’d been approaching the wrong way, but if you’ll bear with me & restrain thyself from punching angrily through your computer/rotary telephone, COME WITH ME ON THIS JOURNEY:

For a Rock Paper Scissors game, lesson 11 or 12 of the Functions lesson of Codecademy‘s javascript class, it asks the student to use a randomize function (Math.random()) to call “rock” when the first third of the number, “paper” when the second, and “scissors” when the third. My FIRST thought was to use a range function, like if i in range(.33) and if i in range(.34,.66)! So I tried a couple of different syntactial approaches that seemed javascriptey, they didn’t work, so I went a-googlin’ (how you do) and found the following solution:

Array.apply(null, Array(5)).map(function (_, i) {return i;});
[0,1,2,3,4]

I know I’m new to javascript, but that is honestly barely parseable. I’m not here to wail about things that one language does that another doesn’t, but this was a difference that frustrated me – – until (and you patient few, I know you’ve been waiting for this) I realized that there’s another way to solve this problem! And that’s the beautiful thing about programming, particularly learning different languages. I remember using this syntax in other learning situations, back in the day when I first learned Python. The resolution is to use the (javascript) format of:

if (i < .33) {
    return "computer chose rock";
}
else if (i <= .66) {
    return "computer chose paper";
} else {
    return "computer chose scissors";
}

which looks (save the curly braces, ;, & s/else_if/elif) nearly the same as pythonic syntax.

MORAL OF THE STORY: there are many ways to do many different things! fabulous!