SQL: the godzilla of database languages! Knex/Bookshelf: a SQL query builder and a JavaScript ORM that works with it, built by Tim Griesser, supported through the issue tracker for each project at https://github.com/tgriesser/ . The Knex/Bookshelf pair make setting up and querying most of the SQL flavors of databases (Postgres, MySQL, MariaDB, SQLite3, and Oracle) more simple and readable, but I'm going to show the table creation mechanism below that I think is the best combination of the two:( click to see lots of code! )
I made a presentation on Basics of Web Accessibility to give to the 70-some people currently studying at Hack Reactor Remote with me! You can look at the slides here: http://slides.com/madelinebernard/webaccessibility/#/
The presentation went well, and I hope I left people with some good thoughts about the wealth of different people out there who could use our things on the web, and how to build for those people.
The next day, coding away on a bit.ly clone, my pair and I came to the point where we had to build a login form, and I realized that since I had literally just given the talk, I would have to walk the walk... I say on the slides, "Labels: if you do them right, clicking the word will tick the box (or whatever)". There are two ways to do this right, and over last week and next I've used both of them. Here they are:
The result, though, where you wave your hand, vaguely clicking in the area, and you get the cursor focused in the box... That's what the web oughtta be!
The presentation went well, and I hope I left people with some good thoughts about the wealth of different people out there who could use our things on the web, and how to build for those people.
The next day, coding away on a bit.ly clone, my pair and I came to the point where we had to build a login form, and I realized that since I had literally just given the talk, I would have to walk the walk... I say on the slides, "Labels: if you do them right, clicking the word will tick the box (or whatever)". There are two ways to do this right, and over last week and next I've used both of them. Here they are:
<label for="login">Type your handle here!</login> <input id="login" type="text"></input> <label>Type your handle here!<input type="text"></input></label>In the first, you have an "id" attribute on the labelled element, and the label's "for" attribute points to it. In the second, the <label> and </label> tags wrap the input element. I like the first better, since I can then lay out my code however I like; but the second is still there, for cases where everything's all in one place and it won't be messy to nest the tags but it would be messy to have a bunch of attributes.
The result, though, where you wave your hand, vaguely clicking in the area, and you get the cursor focused in the box... That's what the web oughtta be!
A thing I learned about URLs
Dec. 8th, 2015 10:34 pmYou probably know that when you have a URL like this, https://frontendmasters.com/hi/courses/crash-course?utm_source=bsa&utm_medium=ppc&utm_term=2015-12&utm_content=why-not-xmas&utm_campaign=crash-course, the weird mangled bit is not necessary for loading the page. I just learned why that is: the ? in the URL signifies that that's where the URL is starting to pass along info to receiving programs, and the info references something set up on the receiving end. And there's more to learn from the structure:
The guy I was paired with and I were having a time of it, figuring out how to tell a Parse server (https://parse.com/docs/rest/guide#queries-query-constraints) how to sort and shape the data we wanted it to return to us. It turns out that we could do it by sending our request to a URL different than the usual URL, which was https://api.parse.com/1/classes/. We instead sent a GET request (the normal "bring me a website, please") request to https://api.parse.com/1/classes/?order=-createdAt&limit=1000. Parse's documentation points out that it will accept parameters like "order" and "limit" and those take values like "field to sort by" and "number up to 1000", so with this URL we're telling Parse that we wanted the 1000 most recently created things... And it worked.
That was pretty great! It turns out that we were supposed to be using jQuery to make things tidier, though, so in the end we went with http://api.jquery.com/jquery.ajax/, filling the data: part of that with "data: {'order':'-createdAt', 'limit':'1000'},".
https://frontendmasters.com/hi/courses/crash-course? utm_source=bsa& utm_medium=ppc& utm_term=2015-12& utm_content=why-not-xmas& utm_campaign=crash-coursethose '&' are joining different references. The stuff before the equals sign references already-built containers to catch the possibly-varying info that is to the right of the equals sign. This is what I saw when rolling my own:
The guy I was paired with and I were having a time of it, figuring out how to tell a Parse server (https://parse.com/docs/rest/guide#queries-query-constraints) how to sort and shape the data we wanted it to return to us. It turns out that we could do it by sending our request to a URL different than the usual URL, which was https://api.parse.com/1/classes/
That was pretty great! It turns out that we were supposed to be using jQuery to make things tidier, though, so in the end we went with http://api.jquery.com/jquery.ajax/, filling the data: part of that with "data: {'order':'-createdAt', 'limit':'1000'},".
In Hack Reactor! Debugging note
Nov. 17th, 2015 07:09 pmWoop! I've been silent because, some months back, I got into Hack Reactor Remote. It started Monday, and now I have a better sense of what they mean by their "please don't leak our secrets" note in their initial communications... They even suggested some things that make for possibly good blog posts.
Sidenote: I take paper notes because they served me well in college, and I've got vague impressions of research that indicates that things you hand write are things you remember better. (I should buy myself a notebook instead of doing archaeologically interesting things ie reusing paper that only has one side printed on.)
Next to me is a note of something Robin Kim, our technical mentor, said offhandedly (not his exact words):
So this is neat because 1. obviously smart and useful idea and 2. wooo, even advanced coders still use console.log to debug! Putting break points in to the Chrome Dev Tools console has been great, also, but nice to know that Chrome Dev Tools are not necessarily the Only True Path.
Sidenote: I take paper notes because they served me well in college, and I've got vague impressions of research that indicates that things you hand write are things you remember better. (I should buy myself a notebook instead of doing archaeologically interesting things ie reusing paper that only has one side printed on.)
Next to me is a note of something Robin Kim, our technical mentor, said offhandedly (not his exact words):
When you have a bunch of console.log() reporters in your code to help debug it, include in them some indication of where they're coming from. So, like,He didn't say what made comma the best.console.log('line 233', thing)The comma is the separator to use in this instance.
So this is neat because 1. obviously smart and useful idea and 2. wooo, even advanced coders still use console.log to debug! Putting break points in to the Chrome Dev Tools console has been great, also, but nice to know that Chrome Dev Tools are not necessarily the Only True Path.
Just did a Coderbyte challenge that was, "given an array of numbers that could be positive or negative but which will not include 0, return 'Arithmetic' for arrays where there's the same distance between all the numbers, 'Geometric' for arrays where there's the same multiple between all the numbers, and -1 for everything else." My answer isn't the best it could possibly be (I feel that I'm using Math.abs poorly, and I should have taken a moment more to make the reduce part bring back the biggest number in the difference array... averages can be deceiving), but looking at answers from unnamed other people, several of them don't even work. This one only compares the gap in numbers of the first two and last two in the array:
function ArithGeo(arr) { var isArithmetic=(arr[1]-arr[0]==arr[arr.length-1]-arr[arr.length-2]); var isGeometric=(arr[1]/arr[0]==arr[arr.length-1]/arr[arr.length-2]); // code goes here if(!isArithmetic&&!isGeometric){//is not special return -1; }else{ return (isArithmetic)?'Arithmetic':'Geometric'; } }It can be defeated with [1,2,45,99,100]. I saw this same pattern three times in like six answers I looked over. Interesting to catch stuff that the tests don't. When I started this post I was feeling a cheerful about not being at the bottom of the heap, but now I'm a bit sad. Anyway, here's my answer. Tell me about better ways of checking that every number in an array is the same... I could have done another for loop, "if difference array [i] !== difference array [0] return false"...
function ArithGeo(arr) { var geo = []; var arith = []; for (var i = 0; i < arr.length - 1; i++) { geo.push(Math.abs(arr[i + 1] / arr[i])); arith.push(Math.abs(arr[i + 1] - arr[i])); } var sumGeo = geo.reduce(function(prev, curr){ return prev + curr; }); var sumArith = arith.reduce(function(prev, curr){ return prev + curr; }); if (sumGeo / geo.length === geo[0]) {return 'Geometric';} if (sumArith / arith.length === arith[0]) {return 'Arithmetic';} return -1; }
More Regex Complications!
Aug. 12th, 2015 04:52 pmHere's one I thought would be simple, which wasn't. The problem is, "return a count of all the vowels (not y) in a string." I thought I'd use regex.exec to capture an array of vowels and find the length of the array... But it only ever returned length 2. I see in the Mozilla Developer Network info page that RexExp.length is 2, but I don't know why I'm getting that here. Can someone troubleshoot?
function VowelCount(str) { var re = /([aeiou])/ig; var arr = re.exec(str); console.log(arr); return arr.length; } console.log(VowelCount('moooo'));So I pivoted to for loops and came up with this,
function VowelCount(str) { var re = /[aeiou]/i; var count = 0; for (var i = 0; i < str.length; i++) { if (re.test(str.charAt(i))) { count += 1; console.log(i); } return count; }This also took some troubleshooting, since the count was wrong when I was using the 'g' flag in the regex. I'm also not sure why that was. Other people I looked at also had mangled looking answers, though of course Matt Larsh has something good,
function VowelCount(str) { var vowels = str.match(/[aeiou]/g); return vowels.length; }Looks like I need to bone up on str.match.
Last evening I had a moment and tried the Coderbyte challenge "when given a string of single letters, plusses, and equals signs, return true only if every letter has a plus on both sides". I came up with a four part if statement reliant on regexes.
Ben, who does JS for a living, gave me the learning that if there's more than one regex, it's probably not ideal... "There's so many edge cases". Makes sense. So, later, the Coderbyte challenge appears, "when given a string of lowercase letters, if there is an a followed by a b three spots later, return true". And I'm like, "I'll use a for loop, like we were talking about last night!"( Read more... )
function SimpleSymbols(str) { if (/(\+\w\+)+/g.test(str) && !/^\w/g.test(str) && !/=\w/g.test(str) && !/\w(?!\+)/g.test(str)) {return true;} else {return false;} }In English, that's if there is a plus on either side of a letter, and if there is no letter at the start of the string, and if there is no letter with an equals sign immediately in front of it, and if there is no letter that is not followed by a plus sign... Then true.
Ben, who does JS for a living, gave me the learning that if there's more than one regex, it's probably not ideal... "There's so many edge cases". Makes sense. So, later, the Coderbyte challenge appears, "when given a string of lowercase letters, if there is an a followed by a b three spots later, return true". And I'm like, "I'll use a for loop, like we were talking about last night!"( Read more... )
Coderbyte easy 5 and 6
Aug. 11th, 2015 05:10 pmChallenge 5 was, given a number between 1 and 1000, add up all the numbers inclusive in that set. Obviously I could repurpose Matt Larsh's recursive function to do this, so I did so, and it worked first try. Woo! Though, no one else seems to be doing +=. I wonder if this would be super wrong if I wasn't recursing and thus seeing it only once each function call? Or do they just like num + SimpleAdding(stuff)?
One of my abandoned paths was to do a str.replace(regex, function) but I wasn't getting the function to work... So I was super curious to see what Matt Larsh did, and sure enough he did something cool:
function SimpleAdding(num) { if (num === 1) { return 1; } else { return num += SimpleAdding(num - 1); } }Challenge 6 was one I hadn't yet solved in Free Code Camp: Capitalize every word in a string. I abandoned a couple different paths while trying for speed, and eventually came up with this answer that seems cludgy:
function LetterCapitalize(str) { var foo = str.split(''); var bar = []; bar.push(foo[0].toUpperCase()); for(var i = 1; i < foo.length; i++) { if (foo[i - 1] === ' ') { bar.push(foo[i].toUpperCase()); } else { bar.push(foo[i]); } } console.log(bar.join('')); return bar.join(''); } LetterCapitalize('to see how to enter arguments in JavaScript');I tried replacing the space in the if statement with /\s/ and that didn't work, nor did /\s/g; I'm not sure why not.
One of my abandoned paths was to do a str.replace(regex, function) but I wasn't getting the function to work... So I was super curious to see what Matt Larsh did, and sure enough he did something cool:
function LetterCapitalize(str) { return str.replace(/\b[a-z]/g,function(c){return c.toUpperCase()}); }That "\b" was something I thought should exist, but didn't find: the signal for "match a word boundary". I just tried /\b\w/g and that works, too; I suppose his way is better, though, since it limits the capitalization to only things that we absolutely know need capitalizing. Unless if \w includes accented letters and other slightly less usual things? My RegEx skillz are not yet l33t and m4d.
Easy Coderbyte challenges 3 & 4
Aug. 11th, 2015 01:29 pmRemembering these from last week: Challenge 3 was another I'd done before, "find the longest word in the sentence", and I got a few more refinements in my answer: I used a regular expression to create the first array; and (having discussed it with Ben) I used an empty string as the initializing value. The previous stab at this Reduce, where I was trying to initialize with 0, was comparing apples and oranges in the form of numbers and strings.
Challenge 4 was ...a journey. ( Read more... )
function LongestWord(sen) { var arr = sen.split(/(\w+)/g); var foo = arr.reduce(function(prev, curr){ if(prev.length < curr.length){ return curr; } else {return prev;} }, ''); return foo; }Looking over other answers, I think reduce is by far the most elegant path. Wooo! Arrays FTW!
Challenge 4 was ...a journey. ( Read more... )
Factorial happened last week, also; the CoderByte challenge was, we'll test on numbers between 1 and 18, give us that number multiplied by every non-0 integer less than it. Ben-the-housemate suggested that this could be done recursively, so I tried that first, but didn't hack it; so, given the ticking clock, I aborted to the exact same decreasing for-loop plan I'd used last week. Looking through other answers was gratifying... I was among the most elegant! I found the recursive method from user mattlarsh, in a tiny tidy package:
My first pass on recursion was the below, and I got stack overflow (infinite program), which I can see now is because the num kept getting bigger but the recursion would only end when the num got to 0.
function FirstFactorial(num) { return num<=1?1:num*(FirstFactorial(num-1)); }He's using the ternary operator there, the shortest possible way to say if/then. IF: the num is less than or equal to 1, DO THIS: return 1, AND IF IT'S NOT: multiply the num by FirstFactorial num-1. So once he has a stack of not-quite-resolved functions and the num gets to 1, it returns 1 and then the rest of the stack has all the numbers it needs to work with and can resolve the final return.
My first pass on recursion was the below, and I got stack overflow (infinite program), which I can see now is because the num kept getting bigger but the recursion would only end when the num got to 0.
function FirstFactorial(num) { if (num > 0) { num *= (num - 1); FirstFactorial(num); } return num; } FirstFactorial(5);
Beginning CoderByte easy tests
Aug. 4th, 2015 05:19 pmI looked at the Hack Reactor suggestions for what one should be able to do before applying, and headed over to http://www.coderbyte.com to try their easy track. They score submissions based not only on correctness, but on time, which is not at all my bag. I think when I saw that a year ago I just turned away, even though a friend suggested doing it on my own time and then pasting the answer in... I might do that in the future.
Their first question was the exact same as I saw last week; reverse a string. I came up with this, which, amusingly, is not what I did last week. It uses the join method of arrays that I was searching for last week, so I'm pleased that knowledge is in me...
Anyway, a good thing about CoderByte: they let you see what other people did, after, answering the socrating question of my friend Catherine about whether I looked at other people's solutions. There's a solution like mine above, but relying on methods of strings and arrays that I wasn't aware of; and that solution lets one do everything in a single line!
Their first question was the exact same as I saw last week; reverse a string. I came up with this, which, amusingly, is not what I did last week. It uses the join method of arrays that I was searching for last week, so I'm pleased that knowledge is in me...
function FirstReverse(str) { var hold = []; for(var i = str.length - 1; i >= 0 ; i--){ hold.push(str[i]); } var foo = hold.join(""); return foo; } FirstReverse("stuff");Also, heeey, check out the respect of spacing in that code block. I thought there were HTML tags about code, and found <code> and thought that was it... Ben the housemate says code isn't really a HTML tag and turned me on to <pre>. Thanks!
Anyway, a good thing about CoderByte: they let you see what other people did, after, answering the socrating question of my friend Catherine about whether I looked at other people's solutions. There's a solution like mine above, but relying on methods of strings and arrays that I wasn't aware of; and that solution lets one do everything in a single line!
function FirstReverse(str) { return str.split('').reverse().join(''); }Way more elegant.
Don't quite understand Reduce
Jul. 30th, 2015 03:11 pmThe next Free Code Camp exercise is to find the length of the longest word in a string (and all of their test strings are free of anything but letters and single spaces). Good points: I had no trouble getting the shape of the solution, and split totally worked great. Actually doing the proper syntax for Reduce required a lot of searching, though, and eventually I basically copied a bit from this webpage about getting comfy with arrays. I should work through that website sometime... Most of the failed reduce trials I don't have copies of, but one that I don't understand is that when I had a 0 in the place I thought was for initial value, right after the anonymous function and before the console.log error-catching readout, here:
}, 0);
console.log(foo.length);
what I got out of the function was only 0. Baffling. Below is code that works. :)
function findLongestWord(str) {
var words = str.split(' ');
var foo = words.reduce(function(prevWord, thisWord){
if (thisWord.length > prevWord.length) {
return thisWord;
}
else {
return prevWord;
}
});
console.log(foo.length);
return foo.length;
}
findLongestWord('The quick brown fox jumped over the lazy dog');
Free Code Camp Bonfire 4 and 5
Jul. 29th, 2015 05:20 pmSo, 4 was trivial, which was great: make a function that factorializes numbers. Like, 5! is 1 * 2 * 3 * 4 * 5 = 120.
But 5... I feel like I shouldn't have to make my own function that takes an array and jams it all into a single string without commas separating the bits. But the concat stuff I was looking at in the Mozilla Developer Network wasn't working that way (even though their example shows it should. So baffled).
And I feel like there must be some way to not declare like 7 variables... But I couldn't figure out how to chain these methods/functions. Anyway: here it is, a function that checks if a statement is a palindrome (ignoring all the non-letter things! The RegEx stuff was honestly fun learning).
function factorialize(num) {
for (var i = (num - 1); i > 0; i--) {
num *= i;
}
return num;
}
factorialize(5);
But 5... I feel like I shouldn't have to make my own function that takes an array and jams it all into a single string without commas separating the bits. But the concat stuff I was looking at in the Mozilla Developer Network wasn't working that way (even though their example shows it should. So baffled).
And I feel like there must be some way to not declare like 7 variables... But I couldn't figure out how to chain these methods/functions. Anyway: here it is, a function that checks if a statement is a palindrome (ignoring all the non-letter things! The RegEx stuff was honestly fun learning).
function reverseString(str) {
var reverseStr = '';
for (var i = str.length - 1; i > -1; i--){
reverseStr += str[i];
}
return reverseStr;
}
function arrToRevStr(arr) {
var str = '';
for (var i = arr.length - 1; i > -1; i--){
str += arr[i];
}
return str;
}
function palindrome(str) {
var cleanStrArray = /(\w)/g.exec(str);
var cleanStr = arrToRevStr(cleanStrArray);
var cleanStrLow = cleanStr.toLowerCase();
var reverseStr = reverseString(str);
var cleanReverseStrArray = /(\w)/g.exec(reverseStr);
var cleanReverseStr = arrToRevStr(cleanReverseStrArray);
var cleanReverseStrLow = cleanReverseStr.toLowerCase();
if (cleanStrLow == cleanReverseStrLow) {return true;}
else {return false;}
}
palindrome("eye");
Reversed a string woo!
Jul. 29th, 2015 03:35 pmI feel like I've reversed a string before... I vaguely remember something about halving the length and swapping things around the middle. But this time, when Free Code Camp asked for it as their very first JavaScript coding exercise, I just looped through the entire thing. Woooo!
...I suspect this is a terrible implementation of reversing a string. Any takers?
The Free Code Camp at this point suggests I should be pairing, and a nice guy in the chat room linked me up with a copy of Screenhero (they've joined Slack and are not taking new signups unless someone already inside invites you in), which they suggest is good for being able to remotely cowork and see everything on another screen... Another guy in the chat suggested coderpad.io or another .io solution instead, as less dangerous and better functioning. What do people think, re: screen sharing programs?
function reverseString(str) {
var reverseStr = '';
for (var i = str.length - 1; i > -1; i--){
reverseStr += str[i];
console.log(reverseStr);
}
return reverseStr;
}
reverseString('hello');
At first I had just defined the reverseString variable as "var reverseStr;", and the readout I was getting from that console.log in the loop was "NaNo" "NaNol" etc. Second debugging step, when I made the start point of the loop i = str.length - 1 instead of i = str.length, I got "undefinedo" "undefinedol" "undefinedoll" etc. So in the first case it was trying to add the nothing in "hello"[5] to NaN, since why, the sensible programming language thinks, would I be trying to use an addition operator, +, on anything but a number? I'm not sure why trying to add "o" worked; I suppose JavaScript decided that the o it was getting meant that it should be adding to a string or object or some non-number thing, but that string or object or whatever wasn't defined. It's nice that when it failed at adding it relapsed to concatenating....I suspect this is a terrible implementation of reversing a string. Any takers?
The Free Code Camp at this point suggests I should be pairing, and a nice guy in the chat room linked me up with a copy of Screenhero (they've joined Slack and are not taking new signups unless someone already inside invites you in), which they suggest is good for being able to remotely cowork and see everything on another screen... Another guy in the chat suggested coderpad.io or another .io solution instead, as less dangerous and better functioning. What do people think, re: screen sharing programs?
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...
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.
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.
Eloquent Javascript problem 6.3
May. 14th, 2015 08:11 pmI'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,
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:
The results were
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.
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.
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.
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.)
I tabbed over to the annotated book: https://docs.google.com/document/d/1aa2-HtUglQrAps31s4LdTPVsiFb1BxhyjZolxeezzcI/edit?_escaped_fragment_=#!
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,
The working answer,
And "some" is trivial from there.
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.