madbernard: a long angled pier (Default)
I've built a fair few open-source projects with small teams of four, and now I'd like to sling code as part of a company! I work with JavaScript presently, though I'd like to branch out into Java and Python (or should I do Ruby instead of Python? Some other language altogether? Feel free to advocate at me in the comments). I like both front-end and back-end work... It's nice that thanks to Node and MongoDB it's possible to be 100% JavaScript in your apps these days, though the API interfaces to other languages/databases generally feel very natural as well.

More project info & links, previous posts )

One of the neat things about the interviewing I've been doing is that I get to see a wide cross-section of the people who work in software development: there are people who have been working in the field since 1978 and have used every language that's come along in that time, and there are people who graduated their bootcamp last summer. Excited founders, people from other fields who learned rudimentary Python to desperately try to surf their wave of data, recruiters who seem to be honestly thrilled about their company....

I'm a meticulous, user-focused, communicative, easy-going, steely-eyed reliable developer, and I'd love it if you phoned or emailed or commented about Bay Area jobs that you'd like to see me at. Here's my resume with my contact info!
madbernard: a long angled pier (Default)
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! )
madbernard: a long angled pier (Default)
I was reworking some code caught in the wild to learn it, and it used both console.error() and console.info(). I'd heard that there were console methods beyond just our old friend console.log(), but I didn't know the details, so I turned to that beacon of righteousness: the Mozilla Developer Network. But wait: both had big red warning messages at the top of the page... And going up a level, console itself did also!
! Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
Even console.log() has a warning! What? What does Stack Overflow say? I checked, and saw that most questions about console.log were from 2010/2011. I asked my housemate Ben the developer, and he said "check caniuse.com"...

Looks like in Internet Explorer 8 & 9, unless the console was open, it was undefined and console.log() would throw an error. Furthermore, caniuse.com has links to the GitHub where, in October 2013, a group got together and laid out how console should be used. I'm betting the MDN just has warnings because this Developer Tools Working Group isn't official, and the reason console.anything exists is entirely because the various browser coders decided to each do it with no prompting from, say, the W3C or ECMA.

The upshot is, console.log(), console.info(), console.warn(), and console.error() are all pretty much good to go if you don't need to support IE 9 or below. Also, this is why some ancient "learn Javascript" tutorials had all the reporting done with window.alert()... They come from the before times
madbernard: a long angled pier (Default)
Two great tastes... ...Not so much.

One part of the Hack Reactor program that my developer friends say is really accurate, in terms of preparing you for the real world, is the "Legacy" project. For four days, you and a team of three to four other people get to build anything you like, using any techs you like. Then comes the "Legacy": for four days, your team picks up another team's project and builds cool stuff out from their starting point. How do they techs they chose work for different people going in a different direction?

In my case, not 100% perfectly. So there was this day that I wasn't sure about how to dynamically generate a dropdown menu with Angular... I tried various methods and they weren't working... Eventually I tried just a straight-up, bog-standard <select></select> tag... Even that didn't show up...!

As you can probably guess from the title, the answer is, MaterializeCSS was not the right fancy CSS framework to use with a constantly shifting thing like Angular. Here's the Stack Overflow answer where someone gives a proper sermon about how MaterializeCSS falls short.

CSS/front-end frameworks make it easier to build a website that shrinks and bends well on a mobile phone, and that looks fine without a lot of poking. In fact, often these days you can look at a website and tell what it was made with, because developers are pretty happy to leave it as it came out of the box. MaterializeCSS is an attempt to look like Google's "Material Design" styles... Same paper-airplane-looking arrow for Submit/Send, etc.

However, apparently, MaterialzeCSS does some of its magic by overwriting normal HTML tags with its own... And any of its own things that require JavaScript to open or drop down or pop up must be initialized when the page loads... And anything that changes after the page loads LIKE SAY when a call to a database returns and populates a dropdown menu with options... Just doesn't happen.

Good times, good times.

You can see the website we worked on here: http://teslalegacy.herokuapp.com/ (If it takes many seconds to load, that's just because we're hosting it for free, and Heroku takes awhile to find it if no one has been there for half an hour). To see the glorious hand-crafted pop-up-div-full-of-checkboxes that I used instead of a drop down menu, you have to log in with GitHub. (Setting up a GitHub account will be worthwhile for you, anyway, but that's a story for another day.)
madbernard: a long angled pier (Default)
You 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:
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
those '&' 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/. 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'},".
madbernard: a long angled pier (Default)
Woop! 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):
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,
console.log('line 233', thing)
The comma is the separator to use in this instance.
He didn't say what made comma the best.

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.
madbernard: a long angled pier (Default)
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; 
}
madbernard: a long angled pier (Default)
Here'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.
madbernard: a long angled pier (Default)
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.
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... )
madbernard: a long angled pier (Default)
Challenge 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)?
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.
madbernard: a long angled pier (Default)
Remembering 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.
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... )
madbernard: a long angled pier (Default)
I was just reading my friend Anneke's blog from before she did Hack Reactor. In this post she says
"I’m wrapping my head around Javascript’s call() and apply() methods. These get used a lot, and it’s important to understand just how they work. More immediately, these get used in the Hack Reactor pre-course work that I’m working my way through ..."
That crystallized an opinion in me: I want my learning materials to have opinions, because opinions are context.

Eloquent Javascript presents as a textbook, ie "neutral", but since Marijn Haverbeke is a guy with strong opinions they sometimes leak through and make the book way more valuable to me. Codecademy, on the other hand, just presents one thing after another. Last year I asked Ben-the-housemate to help troubleshooting a switch statement project there, and he had to look up the syntax, despite coding JavaScript every day. He explained that switch statements are almost never used. That kind of thing is gold! I'm happy to learn about switch statements, but knowing what the actual bread and butter of a language is is far more helpful. Anneke passed me the Functional Programming in JavaScript page, where Jafar Husain says,
"[map, filter, concatAll, reduce, & zip] will probably be the most powerful, flexible, and useful functions you'll ever learn."
That's what I'm talking about! I'd love to know enough to be able to debate about what is best in JavaScript. Wrangling in forums (well moderated forums that don't allow personal attacks), or watching such wrangles, is the best way to see all sides of a thing.
madbernard: a long angled pier (Default)
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:
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);   
madbernard: a long angled pier (Default)
I 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...
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.
madbernard: a long angled pier (Default)
The 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');
madbernard: a long angled pier (Default)
So, 4 was trivial, which was great: make a function that factorializes numbers. Like, 5! is 1 * 2 * 3 * 4 * 5 = 120.

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");
madbernard: a long angled pier (Default)
I 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!

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?
madbernard: a long angled pier (Default)
I'm grimly slogging through the Javascript track of Codecademy again. Ticking off the boxes for Free Code Camp. The "address book" bit with Bill Gates etc was particularly annoying. Did they ever explain For/In loops? Every other thing Codecademy does is massively slow and information sparse, and then suddenly they expect you to know For/In?

But! Plus side, the people behind the Free Code Camp Twitter account let me know they're building their own Javascript course, so someday Codecademy will be back in its own box for people who are happy with how it works!

Also, I've been taking breaks by reading the massive "What is Code" article at Bloomberg that was going around a few weeks back. It pointed out a quirk in Javascript that I hadn't seen elsewhere, which you can recreate right now (in at least Chrome and Firefox)... F12 to get the Developer Tools open, go to the Console tab, type in 0.2 + 0.4, hit enter. Answer: 0.6000000000000001

I found this page that explains Floating Point errors in Javascript. The upshot is, the computer stores decimal fractions as binary fractions, and sometimes there's no exact match, so it uses the closest binary fraction it has. And you get around this by rounding. I wonder if this is something that people who code JS for a living do all the time?
madbernard: a long angled pier (Default)
I've been through the first few chapters of the Aquent Gymnasium Javascript Foundations course, but that's momentarily on hold due to the Grim Flash Bugs of Hacking Team... Before that, I had some fun learning how to screw around with developer tools: F12 toggles the modern update of "view source", where you can look if webpages you visit have scripts that log things to the console, look at the scripts and how they're written, interesting stuff like that.

Around the 4th I had the idea that it would be fun to make a program that would show you the layout of the stars on the American flag (the star area is called the "union", apparently) once we added Puerto Rico as a state... And for any number of states, really. My thought was to use the brute-force ability of programs, find every rectangle that contains the right number of stars (like, for 9: 1x9, 4+5, 3x3, 5+4, 9x1) and then compare their proportions to the proportions of the union, and I got all the sub bits working. However, I've gotten hung up on the math, and looping, that breaks the number of stars into possible rectangles. I need something that will return an array of every grouping that adds to the correct number of stars, where the groupings are an even number of rows of length "X" plus any number of rows of length "X-1". (The flag has, in the past, looked like an I-beam).

A friend of mine at Amazon pointed out this online thing for learning to code Javascript, Free Code Camp. The idea is that once you know just enough to be useful, you start being of use by coding actual projects for nonprofits that sign up with them; and then you have a portfolio of work to use to get a job. Sounds pretty great, though today I hit the JQuery section and it popped me over to Codecademy... I did that last year, when it was Code Year ("Learn to code in a year!"), and it's not my style. It takes minutes of cutting and pasting at their direction to be able to shake out a bit of actual information, and they rarely explain the reasons behind anything. I vastly prefer just reading everything at once and having more freedom to build a thing...

But I know much more about CSS, now, so woo!

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.

May 2016

S M T W T F S
1234567
8910 11121314
15161718192021
22232425262728
293031    

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 27th, 2017 06:34 am
Powered by Dreamwidth Studios