Skip to content

Instantly share code, notes, and snippets.

@al-the-x
Last active May 4, 2016 20:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save al-the-x/73a9252b3c5bfc99d58688e8d65a9dab to your computer and use it in GitHub Desktop.
Save al-the-x/73a9252b3c5bfc99d58688e8d65a9dab to your computer and use it in GitHub Desktop.
Bloc.io Teacher Assessment

Algorithms

Hey mentor,

I hope you're doing well. I'm really enjoying learning algorithms, but I'm pretty confused by this Big O Notation thing. Can you explain how I'm supposed to figure out which notation my algorithm uses?

-Student


Hey mentor,

I'm really excited about starting on learning Angular. I'm having a problem understanding what angular is. Up until this point we've used jQuery, which we've called a library. Now we are using Angular, which is a framework. What's the difference? What are the drawbacks/benefits of using a framework like Angular vs a library like jQuery?

-Student


CSS

Hey mentor,

I'm having a really hard time with some CSS. I've been given a PSD in an assignment. I know what the document should look like, but I'm getting this instead.

Can you help me with this? Here is my code!

-Student

<header>

</header>
<section class="pricing">
  <div class="pricing-tiers">
    <div class="tier">
      <h1>The plan</h1>
      <ul>
        <li>You get all the things</li>
        <li>plus more!!</li>
      </ul>
    </div>

    <div class="tier">
      <h1>The plan</h1>
      <ul>
        <li>You get all the things</li>
        <li>plus more!!</li>
      </ul>
    </div>

    <div class="tier">
      <h1>The plan</h1>
      <ul>
        <li>You get all the things</li>
        <li>plus more!!</li>
      </ul>
    </div>
  </div>
</section>
header {
  width: 100%;
  height: 60px;
  background-color: #333;
}

.pricing {
  width: 100%;
  padding: 20px;
  background-color: tomato;
}

.pricing-tiers {
  width: 960px;
  margin: 0px auto;
  background-color: #ddd;
}

.pricing-tiers .tier {
  width: 260px;
  margin: 20px;
  padding: 10px;
  background-color: white;
  float: left;
}

.tier h1 {
  font-family: "Helvetica", sans-serif;
  font-weight: bold;
  font-size: 2em;
  margin-bottom: 20px;
  text-align: center;
}

.pricing-tiers > .tier:last-child {
  margin-right: 0px;
}

Hey mentor,

I was working through an assignment last night and came across a bug. I'm so confused!

The text in the alert is showing up as "undefined" instead of either "A Unicorn", "A hug", or "Fresh Laundry" and I'm not quire sure what's going on. Can you point me in the right direction?

-Student

<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>

<script type="text/javascript">
  var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
  for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
      // for each of our buttons, when the user clicks it...
      document.getElementById('btn-' + btnNum).onclick = function() {
          // tell her what she's won!
          alert(prizes[btnNum]);
      };
  }
</script>

Oh hey, Student. You caught one! This is one of those quirky things about JavaScript that we've talked about in our sessions; one of those "gotchas" that's hard to explain before you see it in the wild. It has to do with the way JavaScript functions enclose nearby identifiers, like the variable btnNum. We called that "lexical scope", remember?

Let me give you some steps to work through, and we'll explore what's happening together.

First, in addition to the alert inside the callback function, let's add a simple console.log statement. We called those "tracer bullets", right? The value we want to see is the value of btnNum, because it's value at the time the button is clicked will probably surprise you. Additionally, put a tracer bullet inside the for loop and immediately after the for loop that prints btnNum, too.

What does our output look like now? What happens when you click on the buttons? What would cause those values of btnNum? Are they what you would expect? Can you think of any reason for that behavior? Does that help explain why your alert prints undefined...?


Those are some great answers, Student.

You may be starting to figure this out on your own, but let me also explain it a little.

The value of btnNum is always 3 when we click the buttons, right? Why would the value ever be 3...? When the for loop is done, what's the value of btnNum...?

What's happening here?

Why isn't the value of btnNum what we want?

By the time that we click on the button, the for loop has done it's job, and the value of btnNum is 3, right? That's what the callback function sees, too, when you trigger it by clicking on the button. It didn't remember the value of btnNum when it was created, just the name btnNum, which it uses to look up the value when it does its job.

This is one of the big problems with using callbacks inside of a for loop, when we need the value of our counter variable inside the callback. Can you think of any ways to get around that? How could we use the value of btnNum instead of the name...?


Interesting ideas. Here's another to consider: don't use for loops! Remeber the lesson on forEach and friends? What do we know about the way that forEach works? Here's a little memory jog, if you need it:

Array.prototype.forEach(callback);

function callback(item, index, all){
  // Do something?
}

The callback function we pass to forEach gets called -- "invoked" -- for each element in the Array, and it gets passed values for the item, the index of that element, and the whole Array (which we don't usually need) as all. What can we do with that...? Try it! Don't forget to use tracer bullets to look inside the code!

Hey mentor,

I am starting to understand associations, but I'm still confused about through. What's the practical difference between a has_many and a has_many :through? What about has_one :through? When do I use them?

-Student


Hey Student,

Great questions. The has_many and has_one relationships are pretty straight-forward, once you get the hang of them, but then we throw that crazy :through business at you! Why would you ever need that?

Well, here's a simple example that I hope will explain some of the motivations for has_many :through... Suppose you have a Team with a has_many relationship to Player. That's pretty simple, right? But if you know anything about pretty much any game, most players play on a position with that team. The pitcher never goes to the outfield on a baseball team, and the catcher never leaves home plate, right? So to model Player and Team correctly, the Player should know about his position... And then a Player might only play for a Team for a little while, then move on to another. How do we do that with a simple has_many...?

One of the ways is with an intermediate Model: a Position that records the name of the position IRL -- "pitcher", "catcher", "1st base" -- as well as the Team and the Player to which that Position applies. If we wanted, we could also include a from and until field that record the Date that a Player played with that Team in that Position. If we looked at the DB table that Model would create compared to the typical team_player table the has_many relationship normally makes, the only difference we'd see is the name field and the from and until fields.

We don't have to worry about the team_player table or define any Models in the simple has_many situation, because ActiveRecord does all that for us. In the case of our new Position model, though, we need to define the Position class and connect it to Team and Player normally. Doing so allows us to query players from Team, optionally supplying the name of a Position. So we can ask ActiveRecord, "who's on first?"

It also allows us to query teams (plural) from Player. That makes sense, because a Player might be on more than one Team in a career. When we want to know what Team a Player is playing for currently, we have to add some clarification -- via a :scope -- to request a Position where until hasn't been set yet; it's nil.

Sounds complicated? It is. It's called a Many-to-Many Relationship, and it's all over software design. But don't worry, this whole "database relationship" thing seemed pretty weird when you got started with it, didn't it? You'll get over the weirdness soon, I promise.

That has_one :through is a whole other kettle of fish... Let's talk about that one a little later.


Hey Student,

You ready to tackle has_one :through now?

SQL

Hey mentor,

Thanks for the lecture yesterday, it really helped me get motivated again. I've been working through this assignment about databases and I'm confused about "SQL injection." What does that mean and how does it work? How do I prevent it in my apps?

Thanks!

-Student


Yikes, Student. You would pick up on the land mines, wouldn't you? Yeah, SQL Injection is a security flaw that most of our toolkit helps protect us against. It's worth talking about, because you wanna know it when you see it, but using Rails or Django or any of the modern development tools, we shouldn't have to worry about it... unless we do something really dumb.

Which happens.

Here's a funny comic that everyone likes to use to describe SQL Injection. The joke probably doesn't make sense at first, but it gives us a good example to work from:

Exploits of a Mom from XKCD.com

This is from that nerdy web comic I've shown you before, XKCD, and this one is kind of a phenomenon. There's even a website dedicated to explaining SQL Injection called bobby-tables.com. The "About" page on that site is pretty much right on.

Under all the hoods of our tools is a dirty secret: they all just glue strings together and send them as commands to the database, just like the ones that you type into the database console yourself. If you tried to put together a command that performed an INSERT into a table named Students with data that you got from a form... if you ever had to do that without a tool... you could get into some trouble. Consider:

student_name = "Robert Fischer";

insert_statement = "INSERT INTO Students (name) VALUES ('" + student_name + "');"

database.sql(insert_statement) ## INSERT INTO Students (name) VALUES ('Robert Fischer');

That's all fine and dandy until "Little Bobby Tables" comes along with his rather unique apellation. What would that look like? Let's just take a look:

student_name = "Robert'); DROP TABLE Students;--"

insert_statement = "INSERT INTO Students (name) VALUES ('" + request.post.student.name + "');"

database.sql(insert_statement) ## INSERT INTO Students (name) VALUES ('Robert'); DROP TABLE Students;--');

Wait. It looks like Bobby's name did something to our SQL statement. That's... not good.

Yep, the value his mom submitted to our form included a little snippet of SQL, which we injected into our SQL command, assuming the user-provided input to be safe. The computer continued doing exactly what it was told to do, and sent the resulting command to the database. And the database complied by dropping the Students table. Bad times.

Now, the tools that we've shown you almost all universally prevent developers from shooting themselves in the foot like that... if they're used correctly. Sometimes as a developer, though, you really do need the ability to execute a SQL statement from a string, so they usually still have some method for doing so. The real lesson here is:

Always sanitize input!

Don't assume that the data you request from a user through a form or an API request looks exactly like what you'd expect; check it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment