More wins

Jun. 2nd, 2015 12:51 pm
madbernard: a long angled pier (Default)
Last week I was working on a problem that my housemate Ben suggested: the Animal Guessing game, where the code asks you to think of an animal, then builds up a tree of potential animals that you could guess and yes or no questions that would lead there, taking inputs you give it. He remembered it from some 101 class he took, and it turned out to be pretty great, since it has a lot of small bits that you can check as you go, and it creates something that's (arguably) actually worth having. Below is my solution. Maybe sometime I'll come back to it to add the ability to save games, or I'll put it on a website and wean it away from Prompt and Alert. I'd also like to make functions out of the stuff I'm repeating... Like function positiveWords, negativeWords, unrecognizedInput...

function Guess(animal, question, nextYes, nextNo) {
this.animal = animal;
this.question = question;
this.nextYes = nextYes;
this.yesPath = 0;
this.nextNo = nextNo;
}

var thisGameTree = [];
var start = new Guess();
var animalMessage = ["Welcome to the animal guessing game! Teach the program to guess what animal you're thinking of!", "Think of an animal. Can be an animal you've thought of before, can be a new animal."];
var avoidRestartMessage = 0;

var questionGame = function () {
if (avoidRestartMessage === 0) alert(animalMessage[thisGameTree.length]);
if (!start.animal) {
start.animal = prompt("What is the animal you are thinking of?");
start.question = prompt("Please write a yes or no question that would help figure out what your animal is.");
var yesIsForThisAnimal = prompt("Is \"yes\" the right answer for \"" + start.question + "\" for " + start.animal + "?").toLowerCase();
if (yesIsForThisAnimal == "yes") {
start.yesPath = 1;
}
if (yesIsForThisAnimal == "no") {
start.yesPath = 2;
}
alert("Ok, new try!");
avoidRestartMessage = 0;
if (thisGameTree.length === 0) {
thisGameTree.push(start);
}
start = thisGameTree[0];
questionGame();
} else {
var questionAnswer = prompt(start.question).toLowerCase();
//yes path
if (questionAnswer == "yes" && start.yesPath === 1) {
var routingYesAnswer = prompt("Is " + start.animal + " your animal?").toLowerCase();
if (routingYesAnswer == "yes") {
alert("You win! You taught the computer to read your mind!");
} else if (routingYesAnswer == "no") {
//route deeper in
avoidRestartMessage = 1;
if (start.nextYes === undefined) {
start.nextYes = new Guess();
start = start.nextYes;
questionGame();
} else {
start = start.nextYes;
questionGame();
}
} else {
alert("I'm confused! Please only type yes or no!");
questionGame();
}
}
//yes path
else if (questionAnswer == "yes") {

//route deeper in
avoidRestartMessage = 1;
if (start.nextYes === undefined) {
start.nextYes = new Guess();
start = start.nextYes;
questionGame();
} else {
start = start.nextYes;
questionGame();
}
}

//no path, on the right track
else if (questionAnswer == "no" && start.yesPath === 2) {
var routingNo2Answer = prompt("Is " + start.animal + " your animal?").toLowerCase();
if (routingNo2Answer == "yes") {
alert("You win! You taught the computer to read your mind!");
} else if (routingNo2Answer == "no" || routingNoAnswer == "yes") {
//route deeper in
avoidRestartMessage = 1;
if (start.nextNo === undefined) {
start.nextNo = new Guess();
start = start.nextNo;
questionGame();
} else {
start = start.nextNo;
questionGame();
}
} else {
alert("I beg your pardon. Please only type yes or no!");
questionGame();
}

}
//no path
else if (questionAnswer == "no") {
//route deeper in
avoidRestartMessage = 1;
if (start.nextNo === undefined) {
start.nextNo = new Guess();
start = start.nextNo;
questionGame();
} else {
start = start.nextNo;
questionGame();
}
}
//mop up path
else {
alert("Sorry, what? Please only type yes or no!");
questionGame();
}
}
console.log(thisGameTree);
};

Second win: today I was poking around to find a Javascript MOOC, and came across this. In lesson 1.2, He starts talking about Sublime Text, an editor I downloaded last week because JSBin wasn't any good for tidying up the indenting as I shifted if statments around. It turns out that one needs to download a separate package to make Sublime do that... So today I added the Package Handler, and then the jsFormat package. Like a boss! Thanks Stack Overflow!

Third win: I use Opera as a secondary browser, with the idea being that I can be logged into Facebook on Opera and not pollute normal browsing with Facebook's messes. But since Firefox was clogged with tabs, I'm using Opera for posting to Dreamwidth also, and with the increased use, it became intolerable that I couldn't Ctrl-PgUp and -PgDwn to shift tabs. Finally thanks to this link I determined that in Settings, with Advanced Keyboard Shortcuts clicked, it's possible to change or add Keyboard Shortcuts. Wooooooo!

Mad Out.
madbernard: a long angled pier (Default)
Going by on my Twitter feed was a "Yay look at this coolness" link to a Kathy Sierra talk about how to learn quickly. "OMG sounds great!" I thought, since I've heard a lot about Kathy Sierra's abilities to show the path of glory in tech. But I found the talk incredibly depressing. These were the gloom-inducing points:

-If you can't master a thing in about three 45-90 minute sessions, it's too big and you should break it up into littler things to learn.

But... So obviously "programming" and "javascript" are too big to learn. But it's fairly cruel to put it on me to figure out how to do anything that tends towards learning with a smaller unit. Say I focused on for loops, that might be small enough, but what other stuff do I also need to be able to have a useful for loop learning environment?

-If you spend a long time being crummy at something you learn that being crummy is how to be

Wheee.

-The best way to learn is to stab at like 2-300 examples of a good thing, over the course of like 2-3 hours. But in web development training, these collections of 2-300 good snippets don't exist.

Ok, then.

I am disappoint. But whatever, I already felt like I should just copy over the Gordon Zhu 6.3 answer to study it and then go try to get some wins elsewhere (either redoing EJ up to this point, or heading into new areas). I suppose a takeaway here is, Yes, go find new code snippets to examine.
madbernard: a long angled pier (Default)
I've been sick this past week, which didn't stop me vs. 6.1 and 6.2, but when I hit 6.3 I couldn't even figure out what he was asking. It's like he's saying, design a protuberance on the center of your face, then use that protuberance to detect a scent. ...Does he mean find your nose, or does he mean build yourself a new nose? That second one seems a bit unnecessary. Or to be less metaphorical, what am I missing? Iterating over arrays and objects seems like a major portion of what we've been doing so far. The emphasis on interface has got to be meaningful, but the gap between that text analysis and understanding the reason behind the question is fairly daunting.

I'm posting now because I at least figured out something, though I'm fairly sure I'm deep in the weeds heading in a direction that would baffle and amaze all who came after me.

I wondered what methods came baked in to objects, like forEach does on arrays. So I googled, and found this StackExchange bit, http://stackoverflow.com/questions/5842654/javascript-get-objects-methods

which lead me to screw around in JSBin seeing what came included in the Object package,
console.log(Object.getOwnPropertyNames(Object)); and
console.log(Object.getOwnPropertyNames(Object.prototype));

And then there were all sorts of interesting things to look up:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object

Moving forward with Object.keys, I tried this out as a start of an attack on 6.3, adding the console.log stuff in the midst of the program when it initially didn't return what I expected. Thanks to my housemate Ben for that general technique! What I was trying to do here is to get it to pull out a value from a Seq object at any given point:

var Seq = function(object) {
this.object = object;
};
Seq.prototype.valueAtI = function(i) {
var keyArray = [];
keyArray.push(Object.keys(Seq));
console.log(keyArray);
for (var j = 0; j < (i || keyArray.length); j++) {
if (j == i)
return keyArray[i];
else
return "There are fewer things in the sequence than that";
}
};

var foo = new Seq;
foo.bar = "baz";
foo.bear = "bearz";
foo.pear = "pearz";

console.log(foo.valueAtI(1));

The results were [[]] / There are fewer things in the sequence than that . I'd varied the value of i, even down to 0 ("undefined"), but it was the second set of brackets that tipped me off. Less broken code below:

Seq.prototype.valueAtI = function(i) {
var keyArray = Object.keys(this);
console.log(keyArray);
for (var j = 0; j < (i || keyArray.length); j++) {
if (j == i)
return keyArray[i];
else
return "There are fewer things in the sequence than that";
}
};

This actually results in an array of the keys of the object. It doesn't do what I meant it to do, and I think I can see why now that I'm writing, but it's pretty late and I'm taking the tiny win.
madbernard: a long angled pier (Default)
People on Amazon and elsewhere seem to agree that they do not grok the Table example, so I was curious to get to it. I also don't read it on first pass. I didn't read the squirrel/phi example last chapter, though, either... This one doesn't seem deeper in the weeds than that, at first pass.

I don't understand polymorphism. Inheritance seems simple, but that may be because I vaguely remember that CodeAcademy Javascript, which I did a year ago, hit that hard. Polymorphism seems like it might be like cell biology... Like, many proteins have zinc fingers, structures that hold out a metal ion to interface with other proteins structures. When you see one, you have an idea what that protein/program is going to be up to. But that's just a guess.

Right now I don't understand something fundamental about wording in Javascript... Like, "line" seemed important in his example, but searching the page, it just suddenly appears in the TextCell constructor. I think it's drawing from the array/object inputs, but I need to track down how. For my own code I suspect I'll be doing a ton of veryLongWordyThingThatExplainsBetter, for awhile.
madbernard: a long angled pier (Default)
There I was on Eloquent Javascript's problem 5.4, http://eloquentjavascript.net/05_higher_order.html#h_jr7hZiuR7+

The for loop seemed simple, but what I came up with wasn't processing "isNaN" as a function.

var every = function (array, compare) {
for (var i = 0; i < array.length; i++) {
if (array.i !== compare)
return false;
else return true;
}
};

console.log(every([NaN, NaN, NaN], isNaN));
// → should be true, but was showing as false
console.log(every([NaN, NaN, 4], isNaN));
// → false


Putting the "compare" in the if condition in () parentheses (because I had a memory that some form of parentheses would make javascript try to find the value of a thing... Thinking about this, that was probably a memory from getting values of keys, done with [], which in this case I believe would flag "compare" as an array) didn't fix it. Trying for != to allow for type conversion didn't fix it.

I looked at the hints, and they didn't talk about making functions do their thing; they talked about setting up the loop like "forEach". I took an abortive stab at redoing the loop to use forEach... This didn't run, and the linter in JSBin was sad about my use of break. (I'm still not sure what's up with break.)

function every (array) {
array.forEach(function(compare) {
if (array !== compare) {
break;
}
else return true;
});
return false;
}


I tabbed over to the annotated book: https://docs.google.com/document/d/1aa2-HtUglQrAps31s4LdTPVsiFb1BxhyjZolxeezzcI/edit?_escaped_fragment_=#!
Predicate functions were never defined in the book so I’ll quickly explain them here.

A predicate function is a function that returns true or false based on some condition. In this problem, we’re using isNaN(testValue), which returns true if testValue is NaN (remember this means not a number), and false otherwise.

Huh. At first that seemed a bit unfair, a new unexplained type of function. But then, a closer reading would have indicated that the compare thing had to be a function; and I'd even previously went back to the appearance of isNaN in Eloquent Javascript and managed to whizz past the part where it was summoned into action like so, isNan("some thing").

The working answer,
var every = function (array, compare) {
for (var i = 0; i < array.length; i++) {
if (!compare(array[i]))
return false;
}
return true;
};

And "some" is trivial from there.

November 2022

S M T W T F S
  12345
6789101112
1314 1516171819
20212223242526
27282930   

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 6th, 2025 10:46 pm
Powered by Dreamwidth Studios