Quicksort in Ruby

One of the fastest sorting algorithms is quicksort. To sort a list of items via quicksort:

(1) Pick a random element from the list; this is the pivot.

(2) Go through each of the other elements of the list. For each element, if it’s smaller than the pivot, it goes into a new “left array” to the left of the pivot; if it’s larger than the pivot, it goes into a new “right array” to the right of the pivot.

(3) After that, if the new arrays each contain only one element, you’re basically done: the sorted list consists of the left array + pivot + right array.

(3) If the new arrays each contain more than one element, recursively perform steps 1-3 on the new arrays.

Essentially, a quicksort involves breaking the array into smaller and smaller pieces, and then sorting each of these smaller pieces until you work your way up to a complete sorted array.

Which element should you use as the pivot in order to perform quicksort the fastest? It depends. If you choose the first element of the array as the pivot, and the array is sorted in reverse order, you’re in the worst-case scenario, because every single element will go into an array to the left of the pivot, and you’ll have to perform the recursive function n times, where n is the number of elements in the array. In this worst-case scenario, checking n elements n times gives a runtime of n * n, or O(n2) – very slow.

It turns out the best way to even out the extremes is to pick a random pivot. This gives you an average-case runtime of O(n log n). Why? Because you’re checking each element of the array, but in each round on average, you’re cutting the length of the left and right arrays in half. If the array has 8 elements, it will take 3 rounds to get down to sub-arrays of 1 element each: starting from 8, you go to 4, then 2, then 1. That’s log2 8, or log n. So you’re checking n element of the array and you’re doing it log n times, or n * log n, for a runtime of O(n log n).

I decided to try implementing quicksort via Ruby. Here’s my program:

def quicksort(array)
  return array if array.length < 2
  pivot = array.delete_at(rand(array.length))
  left_array = []
  right_array = []
  array.each do |item|
    if item < pivot
      left_array << item
    else
      right_array << item
    end
  end
  return quicksort(left_array) + [pivot] + quicksort(right_array)
end

That's quicksort.

Binary Search in Ruby

I just started reading Grokking Algorithms, by Aditya Bhargava, which has really user-friendly explanations of common programming algorithms.

One basic algorithm every programmer should know is binary search. Binary search is the most efficient way to search through an array of sorted data to find what you’re looking for. (It’s crucial that the data be sorted first.) Here are the steps:

(1) Compare the item you’re looking for to the median value of the array. If your item is the median, congrats, you’ve found it! Otherwise:

(2) If your item is higher than the median, chop off the lower half of the array (since it won’t be in there). If it’s lower, chop off the upper half.

(3) Go back to step 1, comparing the item with the median of the new, smaller array.

The nice thing about binary search is that its runtime is O(log n), i.e. logarithmic. If your array has 128 items, it will take at most 7 steps to find your item; double the array to 256 items, and you need only add one more step.

I decided to implement binary search in Ruby. My program accounts for the possibility that your item is not in the data. Here’s my program, assuming the data is already sorted:

def in_list?(item, array)
  median = array[array.length/2]
  if item == median
    return true
  elsif array.length == 1
    return false
  elsif item < median
    array = array[0...array.length/2]
    in_list?(item, array)
  elsif item > median
    array = array[array.length/2..-1]
    in_list?(item, array)
  end
end

If the array is not already sorted, it’s a little longer:

def in_list?(item, array)
  check(item, array.sort)
end

def check(item, array)
  median = array[array.length/2]
  if item == median
    return true
  elsif array.length == 1
    return false
  elsif item < median
    array = array[0...array.length/2]
    check(item, array)
  elsif item > median
    array = array[array.length/2..-1]
    check(item, array)
  end
end

That’s binary search.

How to Implement Counting Sort in Ruby

There are various ways to sort data in computer programming: bubble sort, quick sort, merge sort. Another method, which I recently learned about, is counting sort. This method is useful when the data you’re sorting has a relatively small range of values between the minimum and maximum – for instance, if you’re sorting individual letters or individual digits. There are only 26 digits – not a very large range. For large data sets of this type, counting sort can be faster than merge sort.

Here’s a visualization of counting sort. Here are the steps, which are kind of hard to understand without the visualization:

(1) Create an empty array of n elements, where n is the range of possible values. If we’re sorting letters, we create an empty array with a length of 26 (lowest index is 0, highest index is 25).

(2) Into each space in the empty array, put the total number of that element that exists in the original unsorted list. For instance, suppose the original unsorted list contains 3 g‘s. Since g is the 7th letter of the alphabet, the seventh index of the array – array[6] – should be assigned the value 3.

(3) Take this newly-populated array. Starting from the beginning, add the value of each index to the value of the index after it. If you do this correctly, the last index of the array will contain the number of all elements in the unsorted list. (This is easier to understand if you look at the visualization linked above.)

(4) Finally, create another empty array the same length as the number of elements in the original unsorted list. Then, for each value in the original unsorted list, find the element in the array that has that index value. Confusing? In other words, if a value in the original unsorted list is the letter g, go to array[6].

Then reduce that value by 1. Next, whatever value array[6] holds, go to the new array at new_array[that_value]. For instance, if array[6] contains 4, reduce it to 3, then go to new_array[3].

Now, assign new_array[3] the value 6.

Do that for every element in the original unsorted list, and you will now have an array containing all the elements, sorted.

Here’s how I implemented counting sort in Ruby, where init_string is the original unsorted data. I created a key array to use to convert letters to their numerical equivalents.

key = "abcdefghijklmnopqrstuvwxyz".split("")

init_string = "zyxwvutdcba"

init_array = init_string.split("")

mid_array = Array.new(26, 0)   #[0,0,0,0,0,0...]
final_array = Array.new(init_array.length, 0)   #[0,0,0,0,0,0...]

# put each character in the array at its proper index
init_array.each do |letter|
  i = key.index(letter)
  mid_array[i] += 1
end

# increment each value in the array by the sum of the number before it
mid_array.each_with_index do |value, index|
  mid_array[index] = mid_array[index-1] + mid_array[index] if index > 0
end

# for each value in init_array:
init_array.each do |value|
  # take the value (init_array[i])
  i = key.index(value)
  # find the value in mid_array that has the index of that first value; decrement that value in mid_array by 1
  mid_array[i] -= 1
  final_index = mid_array[i]
  # go to final_array with the index of that new decremented value; put the initial value there
  final_array[final_index] = value
end

final_array = final_array.join

print final_array

Reducing Big O Runtime: An Example

I recently came across a coding challenge that required writing some code and then making it run more efficiently. The question was as follows:

Given an array of numbers, find the largest difference between an element and any larger element that occurs later in the array.

For example, given [5, 3, 2, 6, 8, 1, 4], the largest difference would be between 2 and 8, or 6. (The difference between 8 and 1 doesn’t qualify, because 1 is smaller than 8.)

One way to find this would be through brute force: compare all possible pairs of numbers, and return the largest difference. In other words, compare:

5-3, 5-2, 5-6, 5-8, 5-1, 5-4,

3-2, 3-6, 3-8, 3-1, 3-4,

2-6, 2-8, 2-1, 2-4,

6-8, 6-1, 6-4,

8-1, 8-4,

1-4

Here’s one way to write this in Python:

def max_difference(array):
    differences = []
    for i in range(len(array)):
        for j in range (i+1, len(array)):
            differences.append(array[j] - array[i])
    return max(differences)

While this would find the correct solution, it’s not the fastest. Furthermore, the longer the array, the exponentially longer this code takes to run. The runtime of this code, expressed in Big O notation, is O(n2). This is usually the case when code contains nested loops, as above.

Here’s a way to visualize this: the array above contains 7 elements. The pyramid above is about half of a 7×6 square, so it contains (7×6)/2 pairs. So for an array of length n, this code needs to compare (n*n-1)/2 pairs, or approximately n2/2 pairs. Constants aren’t counted when determining runtime, so this simplifies to n2. In other words, the runtime is O(n2).

Is there a way to reduce the runtime to O(n)? In other words, can we code this solution so that adding elements to the array increases the runtime at a slower rate – say, linearly instead of exponentially? Yes. If we could write code that would traverse through the array just once, instead of continually backtracking to compare new pairs, that would do it:

def max_difference(array):
    current_min = array[0]
    current_max_diff = 0
    for i in range(len(array) - 1):
        current_min = array[i] if array[i] < current_min else current_min
        current_max_diff = (array[i+1] - current_min) if (array[i+1] - current_min) > current_max_diff else current_max_diff
    return current_max_diff

While this code looks longer, it actually runs more quickly, especially for larger n.

This code keeps track of the current minimum value and the current maximum difference. It sets the initial minimum value to the first element of the array and the initial max difference to 0, If it encounters a smaller minimum value or a larger difference, it sets those as the new bases for comparison. Using our example array, [5, 3, 2, 6, 8, 1, 4], it starts with these values:

current_min: 5, current_max_diff: 0

It then starts the iteration. The current_min is 5. The difference between 5 and the next element (3) is -2, which is less than 0, so current_max_diff stays 0.

In the next iteration, it compares 3 to 5; since 3 is smaller, it sets current_min to 3. The difference between 3 and 2 is -1, so current_max_diff still stays 0:

current_min: 3, current_max_diff: 0

In the next iteration, it compares 2 to current_min (3) and sets current_min to 2. The difference between 2 and 6 is 4, so current_max_diff gets set to 4:

current_min: 2, current_max_diff: 4

Next, it compares 6 to current_min (2), and it compares the difference between 2 and 8 (6) to current_max_diff (4), resulting in:

current_min: 2, current_max_diff: 6

These values stay the same until near the end, when current_min becomes 1. Since 4-1 (3) is still less than the current_max_diff of 6, the code ends with current_max_diff equal to 6.

Why does this code run more quickly, and how do we know? Because instead of nesting a loop inside another loop for each element, it uses only only loop per element. It runs n loops, while the original code runs n*(n-1) loops, which is many more loops.

This new code has a runtime of O(n), which is much faster than O(n2), especially as the array increases in size.

This makes for more efficient, faster code, which makes for happier users.

A Lesson From Fixing a Bug

I was looking over my Presidential Data Charts site in order to get it ready for the next president. (No matter what I happen to think of that next president, there will be one.)

And I found an error in my existing code!

One of the drop-down charts is “Length of presidency.” Most of these are four years (1461 days) or eight years (2922 days). The length of Obama’s presidency should appear today as 2908 days (2922 minus the 14 days left in his term). But it was about a year too short. What had happened? I first made these charts a year ago, but somehow Obama’s “length of presidency” had never updated since then.

I eventually realized the problem: I had originally seeded my database incorrectly. In my seeds.rb file, I had scraped all the stats from a Wikipedia chart (using Nokogiri). I scraped the “left office” date for a president from president.elements[5].children[0]. But if a president didn’t have a “left office” date in the chart (i.e. Obama), I had defaulted to today’s date:

president.elements[5].children[0] ? prez.left_office = president.elements[5].children[0].text : prez.left_office = Date.today

What I forgot, of course, is that seeds.rb only runs once. So Obama’s “left office” date was “baked in” a year ago, when I first uploaded the project to Heroku. (I have other code that uses Date.today, but since it’s in a file that runs each time a chart gets displayed, that “today” is always correct.)

It was a simple fix. I changed the above line of code to:

prez.left_office = president.elements[5].children[0].text if president.elements[5].children[0]

Now when seeds.rb runs, a president won’t be given a “left office” date unless there is one.

This led me to simplify my code in another place as well. Previously, I had calculated a president’s retirement_in_days as follows:

def retirement_in_days
  if self.left_office > Date.parse("2009-01-20")
    0
  elsif alive?
    (Date.today - self.left_office).to_i
  else
    (self.death_date - self.left_office).to_i
  end
end

That particular if line, to account for Obama, always bothered me. The date of 2009-01-20 was tailored to Obama, but if you didn’t know that, it would seem arbitrary. And it was brittle, because once Obama left office, it wouldn’t be accurate anymore. But now that I’d just changed the seed file so that a sitting president wasn’t given a left_office attribute, I could change the if line:

def retirement_in_days
  if !self.left_office
    0
  elsif alive?
    (Date.today - self.left_office).to_i
  else
    (self.death_date - self.left_office).to_i
  end
end

0
elsif alive?
(Date.today – self.left_office).to_i
else
(self.death_date – self.left_office).to_i
end

Now that method works for whoever the sitting president happens to be, and it’s one less thing I’ll have to change when the new president takes office.

And the moral is: sometimes, when fixing a bug, it helps you improve other parts of your code!

How I Made Etymologizer, Part 2

In a previous post I explained how I made the Rails API for my Etymologizer app. Now for the next part – the AngularJS front-end component that interacts with the Rails API, gets the correct type of data, and displays it to the user.

For example, the user might type in We hold these truths to be self-evident: that all men are created equal:

etymologizer-user-input

Here is the code that takes the input:

<form ng-submit="getEtymologies()">
    <textarea ng-model="inputText" ng-model-options="{ updateOn: 'submit' }" class="form-control" rows="3" cols="50" id="textArea" placeholder="Enter text here"></textarea>
    <button class="btn btn-primary">
    Show etymology
    </button>
</form>

When the user submits the form, two things happen: the “getEtymologies” function gets called, and the data model updates. (The “ng-model-options” directive means that instead of updating immediately upon the user’s typing some text, it waits until the event specified by “updateOn” occurs – here, the submission of the form.)

The “getEtymologies” function is contained in the controller. (Here’s the whole function.) This function interacts with the Rails API, but before that, it does a few things:

  • creates an empty array to contain the data of all words;
  • calls a “sanitize” function that removes any punctuation, non-letters, line breaks and extra spaces via the JavaScript replace method;
  • combines the words into a space-separated string, which will be the params that get passed to the Rails API;
  • sets “loading” to true, which triggers the display of a spinner on the page while the user waits for the job to complete (via the “ng-show” directive here).

After these preliminaries, it uses $http.get to send the params to the Rails API, with resourceURL previously assigned as the API’s URL:

    $http.get($scope.resourceURL, {
      params: { words: $scope.wordParams }
    })

The response it gets back contains a JSON object for each word typed by the user. The function then iterates through each object, calling three functions each time, but only if the response contains relevant data. The conditionality is expressed with the ternary operator:

this.entry_list.entry ? etymology = etymologyService.findEtymology(this) : etymology = null;

etymology ? etymology = etymologyService.getValidHTML(etymology) : etymology = null;

etymology ? language = originLanguageService.getLanguage(etymology) : language = null;

The functions are contained in a separate services.js file. The findEtymology function digs through the data to find the etymology; the getValidHTML function adds appropriate HTML for displaying on the page; and the getLanguage function determines which language the word comes from by looking for the appropriate keyword in the etymology. (It assigns the newest language first; for example, if a word comes from Latin via Greek, it will be classified as Latin, which is newer than Greek; if a word comes from Anglo-French via Latin, it will be classified as Anglo-French, which is newer than Latin.)

Once it’s found all the appropriate data, the function creates a hash entry for each word, which will be added to the array of etymologies. Finally, now that the data is ready for display, it sets “loading” to false, so the spinner disappears and makes way for the color-coded etymology results.

Back in home.html, the AngularJS code displays the appropriate color for each word. The color classes are defined in the CSS, and ng-class=”entry.language” assigns the correct class for each word’s color.

The final chunk of code displays the detailed etymology of a word when the user mouses over the word.

I enjoyed creating this app, and perhaps eventually I’ll add more features!

How I Made Etymologizer, Part 1

I recently created a web app called Etymologizer. The site allows a user to enter a word or series of words. It then color-codes the words by language of origin and displays the etymology when the user mouses over a word.

Here’s an example of how it looks when you type in We hold these truths to be self-evident: that all men are created equal, and then mouse over the word self:

Screen Shot 2016-04-28 at 12.53.22 PM

I created the back end of this project with Rails, and the front end with AngularJS. In this post, I’ll describe how the Rails back end works, and why I decided to create it in Rails.

I wanted to create the project entirely in Angular, but the etymology data comes from Merriam-Webster’s Dictionary API. Unfortunately, the Dictionary API outputs its data in XML, and Angular needs the data to be JSON. At first I considered using this Angular-XML module, but then I decided it would just be easier (and more fun) to create my own Rails API that could act as a go-between: it could transform the Dictionary API’s data from XML to JSON, and then my Angular app could access that JSON from my own Rails API.

So I created a new Rails project, and the first thing I did was install the rails-api gem. (I used Rails 4; Rails 5 actually lets you create APIs without any additional gems.) I also installed the HTTParty gem, which I could use to interact with the Dictionary API.

I then created a new adapter that I could use elsewhere:

module Adapters
  class DictionaryApiConnection
    include HTTParty

    attr_reader :connection

    def initialize
      @connection = self.class
    end

    def base_URL
      "http://www.dictionaryapi.com/api/v1/references/collegiate/xml"
    end

    def URL(word)
      "#{self.base_URL}/#{word}?key=#{ENV['API_key']}"
    end

    def query(word)
      result = connection.get(self.URL(word))
    end

  end
end

In the adapter, I include the HTTParty gem, initialize the adapter with a connection instance variable, and then define my query. The query URL includes the Dictionary API’s base URL, the desired word, and my API key (which is defined elsewhere in my app and is hidden from the public using the figaro gem).

Next, I access the adapter from my controller:

class WordsController < ApplicationController

  def index
    client = Adapters::DictionaryApiConnection.new

    words = params["words"].split
    json_object = []

    words.each do |word|
      json_word = Crack::XML.parse(client.query(word))
      json_object.push(json_word)
    end

    render json: json_object

  end

end

Here’s how this works. The controller creates a new instance of the adapter, which includes a new connection. The API takes in params from the input that the user has typed into the front-end Angular app. The words variable takes the “words” params and splits it into an array of separate words. Then, for each word, I use the crack gem, a terrific little gem that converts XML to JSON very easily with the format Crack::XML.parse([something]). The something in this case is client.query(word), which goes to the adapter, creates a query URL for a word, gets back the XML, and converts it to JSON.

So json_word is the JSON output for a word, and json_object is an array of all the JSON for all the words the user typed in.

The Angular app accesses this JSON, and then it does its magic… which I’ll explain in another post!

Displaying API Data in a View in Node/Express

Lately I’ve been teaching myself Node and Express. I’ve been enjoying how it lets you tinker with things on a more granular level than Rails does; it’s more like Sinatra in that way.

As part of a project I’m working on, I needed to figure out how to display content from another website’s API in a view page on my project. It took a bit of stumbling around online to figure out exactly how to do this, so I thought I’d show how I got it to work.

Typically, in the main application file of an Express project (that file is often called app.js but it could be whatever-you-want.js), this is how you set up a route to a particular view:

app.get('/', function(req, res){
  res.render('index');
});

This will route GET requests for the default path — for example, localhost:3000/ or mywebsite.com/ — to the index view file. This means Express will be looking for a view file in your project named “index” followed by the appropriate file extension for the templating system you’re using: index.jade, index.handlebars, index.hbs, etc. Your index view page might just look like this:

<h1>Welcome to the Index Page</h1>

For my project, on the index page I wanted to display data from the TouringPlans.com API. The API has a list of all rides at Walt Disney World’s Magic Kingdom, and I wanted to display that list. (I’m a Disney theme park geek.) To do something like this, you can install the request package via npm:

npm install request

Then put the following near the top of the app.js file:

var request = require('request');

The previous app.get call expands to the following:

app.get('/', function(req, res){
  var url = 'https://touringplans.com/magic-kingdom/attractions.json';
  request(url, function(error, response, APIdata) {
    if (!error && response.statusCode == 200) {
      var data = JSON.parse(APIdata);
      res.render('index', {rides: data});
    };
  });
});

To explain this: the “request” function (third line) takes a URL (in this case, the URL of the API) and a callback function with three arguments. The third of those arguments represents the data contained in the API, which I’ve called “APIdata.” Assuming there is no error (“!error”) and we get an A-OK 200 status code (fourth line), we set a variable (here called “data”) to the parsed API JSON data (fifth line).

What about the sixth line — what is “{rides: data}”?

Well, the data in the API starts off like this:

[
  - {
        name: "Astro Orbiter",
        short_name: "Astro Orbiter",
        permalink: "astro-orbiter"
},
  - {
        name: "Big Thunder Mountain Railroad",
        short_name: "Big Thunder Mtn",
        permalink: "big-thunder-mountain-railroad"
},
[etc.]

I want to somehow pass the name of each ride to the view. This is done by creating a template in the index view page that will iterate through the data (in my case, using handlebars templating):

<ul>
{{#each rides}}
  <li>{{this.name}}</li>
{{/each}}
</ul>

This creates a template called “rides” and iterates through each element (“this”) it contains, displaying the value of the “name” key in each element, which is the ride’s name.

But how does the view know that “rides” should represent the API data? That happens here:

res.render('index', {rides: data});

This tells Express to render the “index” view, and if it sees a template in that view called “rides”, replace it with “data,” which we’ve already set to “JSON.parse(APIdata)”, i.e. the parsed JSON data.

And, we’re done. The list of rides now appears on the web page:

Screen Shot 2016-03-31 at 4.21.55 PM

Data displayed!

Delegation in jQuery, or Why Isn’t My New HTML Responding to Click Events?

I was recently working on a project that lets a user add items to a list. The HTML for each new item appears on the page via jQuery. I ran into a problem, though. I had created several jQuery methods allowing the user to edit, delete, and do other things to the list items by clicking on buttons associated with each item. But newly-added items were not responding to click events. They would start responding to clicks only after I reloaded the page. Everything in my code seemed to be working properly; the newly-added HTML was in the right place; why weren’t the clicks working?

Then I remembered event delegation.

Here’s an example of how event delegation works. A user of my project can change the name of a task by clicking on the name, typing the new name, and clicking away from the name. My original code for changing the name looked like this:

$(".edit_task").on("ajax:success", function(event, data, status, xhr){
    newName = $(data.template).find(".task_name").html();
    $(this).parents(".task_parent").find(".task_name").html(newName);
}

Each task is inside a class called edit_task. When the name is clicked, the new name is saved to the database and then an Ajax request is made. If it’s successful, the edit_task class is targeted, and the new task name is displayed inside that class on the screen.

That works fine for tasks that already exist when the page first loads. That’s because the “ajax:success” event listener gets bound to elements when the page first loads, including all existing instances of the edit_task class. If a new task is added after the page has loaded, the event listener is not listening to the newly-added instance of edit_task.

How to solve this problem? You can just delegate the event listener to an element further up the hierarchy that already exists.

In my project, a div with a container class wraps around the entire task list. This class exists even if there are no tasks yet; it will always be there. Therefore, I changed my code to use the container class as the event listener. I just changed the first line of the above code to the following:

$(".container").on("ajax:success", ".edit_task", function(event, data, status, xhr){

There are just two changes here. The DOM element at the beginning gets changed to “.container”, and then, inside the parentheses, after “ajax:success” (the event we’re listening for, which might also be something like “click” or “select” or “blur”), we add the actual element that’s being targeted, the one that originally appeared at the beginning – in this case, edit_task.

Simply put, just replace:

target.on(event, function)

with:

higher-element.on(event, target, function)

It’s that simple. You’ve now future-proofed your jQuery. Thanks, event delegation!

My Top Ten Pieces of Advice for New Flatiron School Students

I’m nearly done with my 12 weeks as a Web Development Immersive student here at the Flatiron School. I thought I’d share the top ten things I’ve learned — the things I’d tell new students.

1. Relax. You might have read that Flatiron requires a commitment of up to 70 hours per week. But much of the time, you’ll be having fun! The typical Flatiron day is only loosely structured. When you’re not in lecture, you’ll most likely be working on labs. This gives lots of opportunity to be social. In the evenings and on the weekends, you’ll probably be working on labs and doing some reading assignments. But this is fun, too, because you’re learning.

2. You don’t have to finish every lab. On many days, you’ll be assigned more labs than most students can possibly complete in a day. The point of doing labs is not to get green lights; it’s to learn, and to get coding practice. You won’t be penalized for not finishing every lab. There are no grades here! You can always come back to some labs on the weekends or later in the course. A corollary to this is:

3. Get enough sleep. A good night’s sleep is important. You’ll learn and retain more during the school day if you get a good night’s sleep. There’s no need to sacrifice sleep for labs or assignments. You don’t need to be a hero.

4. Go easy on yourself. Don’t worry about how well you’re doing compared to your classmates. Some people might finish labs faster than you; so what? It’s not about speed. You’ll all make it to the end of the course. Lots of us tend to focus on people who are doing better than us instead of on those who are doing as well as us. There will be some super-speedy folks in your class. That’s okay. You’re smart, too, otherwise you wouldn’t have gotten accepted to Flatiron.

5. Ask lots of questions. Don’t be afraid to ask questions during lecture if you don’t fully understand what’s going on. If you don’t grasp something, you’re probably not the only one. Your classmates will be grateful that you asked. Plus, you’re paying a lot of tuition — ask questions and get your money’s worth! That said:

6. Let yourself struggle sometimes. When you’re unsure about something on a lab, try to figure it out on your own or from a classmate before asking an instructor for help — not because the instructors are busy, but because you’ll learn more if you try to figure something out on your own first. Google is your friend. If you’re still stuck after a while, definitely talk to an instructor or classmate. You can’t learn if have no clue what to do.

7. Step away from the computer. Take breaks. This is really important. There are many times when I’ve been frustrated by a lab and kept metaphorically banging my head against my computer. If this happens to you, it’s best to clear your mind and go for a walk. Exercise helps your brain. The solution to your problem might pop into your head when you’re doing something else, or you might come back to your computer refreshed and ready to figure it out. It’s better than getting mad.

8. Make friends! This should be easy. My classmates are terrific. At the end of just one week, I felt like I’d known them for months. You’re all in the same boat — you can commiserate, drink together, empathize with them. Everything in life is better when you’re around good people. Hang out after class on Friday.

9. Enjoy Feelings Friday. Every Friday afternoon, your class will sit on chairs in a circle and everyone will say how they feel about the past week. I happen to love Feelings Friday, but some people don’t like talking about their feelings. If you’re one of the latter, remember that someone else might benefit from hearing what you have to say. It’s great when someone expresses something that you yourself are feeling.

10. Take time to appreciate being here. It’ll go by fast. You’ll be at Flatiron for only about three months. One day you’ll realize that half the program has gone by, and then the next thing you know, you’ll be working on final projects and your resume. Don’t let the whole thing be a blur. Stop and take a mental photograph every so often. You’re lucky to be here.