The Beginning and End.

Some Things Hacker School Taught Me

Yesterday was my final day of Hacker School as part of the Summer 2014 Batch.

Here are some things being a Hacker Schooler has taught me:

Getting Past My Fear of Asking Questions


One of my biggest fears has been asking questions to people with more experience and understanding than me, because I had felt that I would be judged for the things I didn’t know. I’ve had experiences with programmers in the past who have said things such as: “You wouldn’t have understood [the talk] anyway,” to blantant condescension about my lack of knowledge on the subject matters I was asking about. As a result, I had developed an aversion to “outing” myself as an idiot.

At Hacker School, I found myself asking questions on Zulip, tapping on shoulders, and exposing my ignorance. And pretty much every time, people were happy to share their knowledge with me, saving me hours of frustration that came with trying to figure things out on my own. StackOverflow and Google Fu can only get you so far. I do believe that this wouldn’t have been possible without the Hacker School social rules, but my time around other Hacker Schoolers has definitely lessened the general fear of seeking help. A good rule of thumb is that if you can’t figure something out on your own in 15 minutes, go look for help and save yourself from yourself. And if someone is rude to you for asking a question, then I’m not sure if I would want that person’s help — though it is quite possible they are having an off day.

Hardware is Not Scary


Before Hacker School, I had probably blinked an LED a few times and made a synthesizer of sorts with an Arduino, but was otherwise hesitant to touch hardware.

This past summer, I got to hack on Arduino, Raspberry Pi, and BeagleBone projects, with lots and lots of help from the lovely Dana. I made a surveillance camera to spy on my cat and stream it to the web, a light-reactive LED diplay with Adafruit NeoPixels, and helped build LED-bot.

Just as with software, you end up following tutorials, looking up documentation for pieces (and how to correctly connect them following circuit diagrams), and tinkering. It’s just with physical parts! And there’s something rather cool about building something tangible.

I ended up doing much more hardware than I had intended, but I am so grateful for the things that I learnt.

Learning to Tackle Projects (and understanding when to let go)


At Hacker School, I found myself getting curious about Haskell’s type inference system, found that the algorithms used theory that I didn’t understand, and spent a few weeks going down a type theory rabbit hole, eventually learning the Coq programming language (Coq is a Proof Assistant) through a UPenn grad course called Software Foundations. And I also decided to put my type theory learning on the back burner, so I could focus on exploring other things during my batch.

Anything difficult is going to have many stepping stones, and acknowledging that getting where you want to be might take several tries is totally ok. I am planning on continuing to tackle the type theory stuff in little chunks so that I don’t get overwhelmed by all of the information. This meant that I couldn’t just start and finish my stint into type theory in a week, but that it will take dedication and commitment that might take a year, or several years.

I think the notorious BitTorrent client project falls into this category. It’s quite a difficult project to see through to the very end (many HSers start, and eventually abandon their clients — myself included), and it was important to understand that many of got to a point where the project wasn’t bringing us joy anymore, and that we had grown tired of it (but wanted to finish at some point). Taking a break and putting the project somewhere out of mind for a while helped me feel rejuvenated after weeks spent on the BitTorrent client. I hope to revisit it at some point.

Some HSers even decided to create a BT Support Group.


This list is in no way complete. HS has taught me so many things about being a good programmer and a human being that I have trouble articulating at the moment.

Saying good-byes yesterday was overwhelming and there were many emotions; I don’t think it will quite sink in that the batch is over until we go back to the real world/school on Tuesday.

Never graduate. :‘)

Sipping on Elixir

1
2
3
4
5
6
7
8
 __________
< holy cow >
 ----------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

It’s almost the end of my batch at Hacker School, but it’s okay because I’m never [ever] graduating. ❤


This past week José Valim has been in residence at Hacker School! José is the creator of the Elixir programming language, which is built on top of the Erlang Virtual Machine. (Joe Armstrong has said that Elixir “is good shit.” Seriously!). José is also a core contributor to Rails. So. Rad.

On Monday night, José gave us a quick introduction to Elixir and explained that Elixir is a functional, concurrent, but most importantly, a distributed language. He gave us a bit of background on Erlang and its origins as a language used for telecommunication. Erlang provides support for fault tolerent, non-stop, real-time applications. Also, hot swapping is pretty cool (which José did a demo of in Elixir). For these reasons (and many more), Erlang is the language used in messaging systems like Facebook messenger and WhatsApp.

I’ve been spending the past few days working through Etudes for Elixir in order to get a quick introduction to the language, and get myself up and running.

Some quick first impressions/takeaways:

Elixir is compatible with Erlang code, but it has a nice Ruby-like syntax. It’s kinda like the love child of Ruby and Erlang. Elixir has all the goodies like pattern matching, list comprehensions, anonymous functions that I heart from Haskell. There aren’t quite type signatures; instead, there are these things called specs. Specs are mostly used for documenting code, but on some occasion, people use tools like Dialyzer to find type errors (I will probably check this out at some point).

One thing I find super cool about iex, the Elixir repl, is the h command to read documentation.

Also, Elixir has SUPERB documentation. I’ve been very pleased with how well explainations are written out, and that there are examples! Examples!

I’m making my way through most of the topics in Elixir’s getting started section through études (currently getting acquainted processes), and I’m excited to learn about Mix and OTP next. In general, I’m excited to get deeper into Elixir since I don’t know much about concurrent and distributed programming.

Today, José did a seminar on how Iterators are implemented in Elixir, going over eager map, eager filter, the idea of inlining and so on before introducing us to the idea of lazy map, etc. It was a very informative session and I will write about that more in a different blog post.

And just throwing this out there: HOW COOL IS IT TO BE ABLE TO ASK QUESTIONS IN PERSON TO THE CREATOR OF THE LANGUAGE YOU’RE LEARNING? Thanks a ton to Hacker School for this amazing opportunity.

So far, learning Elixir has been quite nice, and the transition from Haskell to Elixir has been pretty smooth.

Looking forward to all of the things I learn before the end of my batch.

Whiteboarding to Unconfuse Myself

A few days ago, I stumbled on a repository on GitHub that was exploring category theory through the use of Coq, formalizing Edware Kmett’s Hask library. Curious, I wondered what Hask was and read the description: “Category theory for Haskell with a lens flavor”.

But… what are lenses?

I remembered that I had bookmarked a blog post that Steve Klabnik tweeted a while ago because it was related to Haskell. And now it was relevant to my interests.

Lenses are, at a high level, something like “getters” and “setters” that are used in imperative programming languages. It’s not uncommon to see something like book.author.name. Lenses provide an abstraction like this for Haskell.

I spent a long time staring at the explanations in this blog post, and after pairing with Alan a bit on a simple Lens implementation, felt blown away by the weirdness and how elegant of an idea this was.

A realization that I had about working with Alan (after ten weeks…) is that he is the type of person to think things out by writing on a white board. Up until this point, I had never really thought about whiteboarding as a way of getting my thoughts out so that I could actually look at them. And the act of writing type signatures out instead of staring at them on a screen made a lot of difference for me. (I do write on scratch paper, but I generally do so very disorganizedly).

After Thursday demo presentations, I spent about thirty minutes whiteboarding out my thought process for the implementations of over and set:

whiteboarding 1

whiteboarding 1

I guess moral of the story for me is that I should whiteboard more to figure out what I’m doing when I’m confused before jumping straight to code. A very simple epiphany, but a very helpful one.

Building a Cat Cam

I recently purchased my first Raspberry Pi (the Model B+ whooho!)

"PI"

I decided that my first RaspPi project would be to build a Cat Cam to monitor Kitkat while I am away from the apartment. Occasionally he’s being doing a few weird things like pooping outside of his litter box while I’m not home. Basically, this is me spying on my cat.

After a couple of component orders (PS3Eye webcam, MicroSD card) arrived, I was ready to start setting up my new Pi.

Dana lent me her serial cable so I could access the Pi without an external display. However, this meant that NOOBS wouldn’t work (it seems to require an external display), and we had to mount Raspbian Wheezy onto the SD card. There are always bumps along the way to setting up new hardware… Soon after this though, I was able to SSH into the Pi, which was great!

But more complications followed… RaspPi is developed in the UK, so the locale was set to en-GB.UTF8. I had some problems figuring out how to get it to be en-US.UTF8 and was going crazy trying to figure it out, because I SWEAR I was selecting install new locales when I tried to generate and update them. (Lol, no I wasn’t). Luckily, Paul was able to help me troubleshoot and not pull my hair out.

Then, I was ready to set up the PS3Eye camera and motion detection snapshots using the motion package and following along with this tutorial. The set up with the camera was incredibly straightforward, and things just worked! I was able to view the stream from within the local network of the Pi. But as it turned out, only the local network. When I excitely told Matt to view the stream (after I had pushed a simple Python-Flask app to Heroku), he told me that the stream was empty.

Slightly deflated, I started looking around RaspPi forums and found out that my problem was because the RaspPis, as a default, only allow connections from a local network due to security reasons. Basically all of the suggestions pointed to enabling port forwarding, which seemed like a super insecure move, even for someone who has barely any knowledge of security practices. Basically, I would have to open up the Pi to the outside world so the stream could be viewable on the Internet. This meant that anyone could try to SSH into it; even if it has no sensitive information on it, I still don’t want people in my Pi :/.

(I took a break at this point to create a script that emailed my personal email account the IP address of the RaspPi every time it was booted to make it easy to SSH into it. Whoo!)

I wanted to avoid port forwarding if I could. I thought about it a bit, and last night, I remembered the awesome AWESOMENESS that is ngrok. Ngrok creates a tunnel between localhost and the Internet. This totally solved my problem! So this morning, I played around with ngrok on the Pi, creating a tunnel that would allow the webcam feed to be viewable from the Internet, and used that in the Flask app feed source. To double check that this worked, I asked Matt to view it from Minnesota (he’s on vacay visiting family). AND VICTORY, IT WORKS!

My next steps are to create a start script that runs the motion daemon, and a script to auto start ngrok. I have created a cronjob to delete the contents of a tmp file that takes a picture everytime the webcam detects motion (this can mean A LOT of pictures depending on where it is placed). At midnight every night, the script just deletes the day’s worth of pictures, assuming that I will be able to look through them for any suspicious Kitkat behavior before the day is up.

I’m really excited to set this up at home and spy on my cat >:D Next, I want to build a toy component so I can play with Kitkat remotely.

Why I Love My Cat, an Anecdote About Depression

Depression is a lying sack of shit asshole.



I think most people know that I love my cat, Kitkat, quite a lot. But I don’t think most people know why.

I took a break from college last September due to something that was eventually diagnosed as a severe case of Major Depressive Disorder (Single Episode). For some reason, after a perfectly happy summer, I started to experience a deep, unfathomable sadness and sense of self-loathing. I was back on campus for the fall semester of my third year of university, and I couldn’t focus. I slept more than I usually did, and I started crying from exhaustion, and sometimes, for no reason. But mostly, it was because of these cyclic thoughts that kept telling me how worthless of a person I was, and seriously, what was the point? Crazy to think about it now but I reacted to this by simply believing that I was feeling burnt out.

I was able to take a year off from school, a leave of absence as they call it. About a month passed with me sleeping in with all the shades drawn. I didn’t see light for several days at a time, and had a hard time doing anything without sobbing for hours (literally hours). One time Matt, my boyfriend, found me in the shower fully clothed and I just remember thinking that I had to get clean. Whatever the compulsion, I’m still not sure what exactly I was thinking.

Eventually, I realized that I had a problem. I was scaring myself and I was scaring Matt. I started seeing a therapist and was put on a steady dose of anti-depressants. Around this time, I also decided to foster a cat that was about to be euthanized (Animal Care and Control centers in NYC run out of room due to the amount of animals they take in every day, and so they have to euthanize animals to make room for the incoming animals). Kitkat was on the list of cats to be euthanized. Matt and I put in a request to foster a cat, and because I knew black cats had a smaller chance of being saved, I picked Kitkat.

I was still mostly apartment-ridden at this point, and Matt was working during the day, which meant that I had to go to the East Harlem AC&C to pick up Kitkat. It gave me a reason to leave the apartment, when most days I stayed shut in. Kitkat came into my life when I was feeling completely worthless, and the realization that even someone worthless like me could take care of an animal meant that maybe I actually wasn’t worthless. Getting food and toys for Kitkat gave me even more reason to leave and re-enter society, at least see sun for 30 minutes a day. Gradually, Kitkat stopped being a shy shelter cat, and has proven himself a funny and cuddly companion. Supporting evidence: his vet said he was “funny and charming” :). Becoming Kitkat’s human has been just as helpful in my convalescence as support from loved ones, yoga, medication, and cognitive therapy.

"kitkat"

This post was prompted by the news of Robin Williams’ suicide. RIP.

Gayle Laakman McDowell Talk Recap

On Wednesday evening, a couple of us headed to a talk by Gayle Laakman McDowell, the author of Cracking the Coding Interview.

She gave us some redundant information, but also some great insights that I had never thought about before.

First some things before the ~technical~ aspect of the interivew:

  • Try to keep your resume to one page because most resume readers spend maybe 5 – 15 seconds looking at it. There are no fast and hard rules for how it should be formatted, but it should be scannable in that amount of time.
  • Put your outside of school/work projects on your resume! Many candidates don’t put their projects on their resume for whatever reason.
  • Ask your recruiter what to expect from the interview. There is no reason to be afraid to ask about what you might encounter. However, take this with a grain of salt because the recruiter isn’t going to be the one interviewing you.
  • Coming off a bit weird to a recruiter is okay. As long as you aren’t being as asshole, don’t worry too much.

Other pre-interview stuff to know:

  • Struggling during an interview is normal. The whole point is to see how you reason through difficult questions.
  • How you do is relative to people who are asked the same question. (This in particular was something that made so much sense, but was something I had never realized. I always quantified my success by how many questions I got correct.)
  • Hashtables go a long way.
  • Know linked lists, arrays, arraylists, binary search trees, merge sort, and quicksort well.
  • Know Big O like the back of your hand.
  • Try to recode data structures from scratch.
  • Write code on paper so you don’t freak out when you have to white board and don’t have nice things like syntax highlighting.

During the interview:

  • LISTEN for the little details. If you’re given a list, is it sorted already? Are the elements distinct? Repeat the question back to make sure you understood it.
  • Work through the question using a good example.

But what is a good example? Let’s work with this question Gayle gave us:

Given two sorted arrays, compute the intersection.

What about:

1
2
[1, 5, 9, 15]
[2, 3, 9, 20]

This is bad because this is a special case, in several ways. The two arrays are the same length, and the element that appears in both arrays are in the same index. These are also too small.

In general, try to come up with examples that avoid special cases, and are about 50% larger than your initial instinct. So if you think about three element arrays, try working with six element arrays.

Brute force a solution first; you can optimize it later but it’s better to have a solution to work with. Walk through the brute force solution using your example. Remember the small details when implementing your algorithm, ie: is the input sorted? is the information cached? etc.

The brute force approach to solving this is go through the elements of the first array, and check all elements of the second array to see if they match. Move onto the next element in the first array and do the same thing. Keep doing this until you’ve gone through the entire first array.

After this, try to imagine what the fastest you can imagine an algorithm being for the problem you have been given. She called this the best conceivable runtime. Was your solution O(nlogn)? Can you see it being solved in linear time? Try to get there.

Let’s go back to the example question and see how we can optimize it.

1
2
[1, 5, 6, 8, 9, 15]
[2, 3, 4, 5, 9, 20, 31, 33, 34]

You will have to go through every element in the first array, but not for the second. Why? Well, we know these arrays are sorted. So if we’re looking to see if 1 is in both arrays, we look at 1 in the first, but we hit a 2 in the second. Since these are sorted, anything after 2 is going to be greater than 2. We can stop looking here.

Think about spacetime trade offs. Also always keep in mind hashtables because apparently they can be used to solve a lot of algorithms questions in optimal ways. This particular problem can be solved using a hashtable. I have solved it in Python here.

Some whiteboarding tips:

  • Code far top left corner.
  • Write small and straight.
  • If it helps, write pseudocode. But don’t write psuedocode that uses syntax that looks too much like a programming language’s because it’ll just look like shitty code.

Code breadth first:

  • Modularize from the very beginning.
  • Go level by level, top down.
  • Hit the most interesting thing first, then move down.
  • You’re most likely to screw up on something like shifting bits around, but that isn’t very interesting, so just save it for last. Interviewers will not care if you messed up on something like that if you got the bigger picture correct.

If you’re ever confused, stop, and recoup. Don’t push through when confused. Walk through your example again.

When you’re done writing your algorithm, test your code with an example, but NOT the example you used to understand the question. Good examples are long but not necessarily good test cases. Go with something shorter so if you hit a bug, you’ll hit the bug faster. Start with small general test cases, then go to special cases.

Look at your code for interesting lines; what lines are most probable for errors?

After this, follow up with your recruiter!

Also, always keep in mind that interviewers are people too, and they all have varying personalities. If one is being really quiet, that doesn’t mean you aren’t doing well. Sometimes interviewers act harsher if you are doing well! What. They don’t think you need their help and they’re thinking about ways to push you.

Cool. Once you get an offer, negotiate, because it’s a win-win. 30 minutes isn’t a lot, but hey, you might get a couple thousand dollars out of it. Counter offer their offer by bumping it up $20k. They’ll probably throw you a bone and meet you in the middle.

Obviously Gayle’s advice should also be taken with a grain of salt.

Re-learning Math With Coq

The last time I was doing a lot of inductive proofs was during my third year of high school. I did a few in my Discrete Mathematics class, but to be quite honest, I hardly remember anything from that it (I should really revisit the material at some point…).

Considering that it has been more than four years —I took a gap year between my second and third year of university, I am now going into third year— I was a bit unsure of my math chops. But working through Software Foundations has been an absolute blast. And it’s been so cool to see the Curry-Howard correspondence in action through writing proofs in Coq.

Rntz gave a great presentation on Curry-Howard, presenting formal logic, a lambda-calculus, and then showing the connection between formal logic proofs and typed expressions/programs.

So far, I’ve been spending time proving some mathematical axioms such as the additive identity, multiplicative communtativity, right distributive property of multiplication over addition of numbers, and so on.

Coq has various proof tactics, intros, destruct, and induction, to name a few.

To show you the kind of stuff I’ve been doing, let’s work through an example.

Let’s prove that n + 0 = 0.

First we define the theorem (adding a 0 to the right side of a natural number gives us the original natural number):

1
Theorem plus_0_r : forall n:nat, n + 0 = n.

So how do we prove this?

Well, first we need to introduce n into the scope of the proof.

1
2
Proof.
    intros.

Coq shows us that we can now work with n, and that our subgoal is to prove that n + 0 = n.

1
2
3
4
5
1 subgoals, subgoal 1 (ID 88)

n : nat
============================
n + 0 = n

Cool. And now we can induct on n. In induction, you must prove the base case of n = 0, and for n = S n'; S n' can be read as the successor of n’, which is equivalent to n.

So now, we use the induction tactic in Coq:

1
2
Proof.
    intros. induction n as [| n'].

Now we have two subgoals to prove, the base case and the successor case:

1
2
3
4
5
6
7
2 subgoals, subgoal 1 (ID 91)

============================
0 + 0 = 0

subgoal 2 (ID 94) is:
S n' + 0 = S n'

For my own benefit, I like to write out what case I am proving, which in this case is for when n = 0. As we see, Coq gives us 0 + 0 = 0. We can simplify this expression by writing simpl, and Coq will reduce this to 0 = 0. And we know 0 = 0. It’s a fact. We can simply write reflexivity to finish proving this subgoal.

As a sidenote, reflexivity will simplify for you, so it wasn’t necessary to do the simpl step. However, I found it helps my thought process to write out all of the steps.

1
2
3
Proof.
    intros. induction n as [| n'].
    Case "n = 0". simpl. reflexivity.

Coq now tells us we have one subgoal remaining:

1
2
3
4
5
6
1 subgoals, subgoal 1 (ID 94)

n' : nat
IHn' : n' + 0 = n'
============================
S n' + 0 = S n'

As you can see, we are given IHn', an induction hypothesis to work with. So let’s prove our second subgoal for case “n = S n’”:

We can simplify this down to S (n' + 0) = S n by using the simpl tactic. Adding a 0 to n’, and then calling a successor on it is no different from adding 0 to the successor of n’.

1
2
3
4
5
6
7
1 subgoals, subgoal 1 (ID 101)

Case := "n = S n'" : String.string
n' : nat
IHn' : n' + 0 = n'
============================
S (n' + 0) = S n'

But what’s this? We have an induction hypothesis that tells us that n' + 0 = n'. Oh, this looks familiar. So let’s rewrite S (n' + 0) using our induction hypothesis:

1
2
3
4
Proof.
    intros. induction n as [| n'].
    Case "n = 0". simpl. reflexivity.
    Case "n = S n'". simpl.  rewrite -> IHn'.
1
2
3
4
5
6
7
1 subgoals, subgoal 1 (ID 102)

Case := "n = S n'" : String.string
n' : nat
IHn' : n' + 0 = n'
============================
S n' = S n'

Omg, the left and the right are equivalent. And now we can say, this is true by reflexivity, and end our proof by writing Qed.

Our full proof:

1
2
3
4
5
Proof.
    intros. induction n as [| n'].
    Case "n = 0". simpl. reflexivity.
    Case "n = S n'". simpl.  rewrite -> IHn'. reflexivity.
Qed.

HOW COOL IS THAT???

Exploring Type Theory

I started off today with a specific goal in mind. By the end of the day, I was pretty off my mark.

My original intent was to work through a tutorial, Algorithm W Step by Step, for implementing the classic Algorithm W (proposed by Robin Milner) for type inference in Haskell. I was stoked to finally take a closer look at Hindley-Milner and foolishly thought I would spend a few days on it.

In reality, I had started my descent down the rabbit hole. I found myself reading, and while I felt comfortable with the actual Haskell code itself, the reasons for why the tutorial was implementing things by using sets, or talking about free type variables and type schemes made me feel that yeah, maybe(?) I could infer something from my understanding of Haskell, but I was still lacking appropriate knowledge for this literature.

So, I asked this silly question on Zulip:

Stream Subject: Category Theory/Type Theory/Set Theory

Message: Hi hi. I’m delving into Hindley-Milner for type inference and I’m finding lots of terminology that I don’t understand. Are there any friendly introductions to all of the theories? AM I WAY IN OVER MY HEAD?

Rntz pointed me to Types and Programming Languages as a resource and I was intrigued. I started reading it, and of course my attention started to wane because textbooks. After some googling, and remembering back to my first week at Hacker School, I was reminded of a UPenn grad course called Software Foundations. The course uses TAPL but also utilizes an interactive book of Coq proofs as its main text. Interactive? Sign me up.

Two ways to run Coq are through the CoqIDE or through Proof General Coq mode in Emacs. I found to my chagrin that CoqIDE was ugly and slow and in general, not something that I wanted to use. But that meant that I had to learn… Emacs. So for about two hours, I went through the Emacs tutorial and fiddled with my .emacs file, thinking about the time I saw Richard Stallman dressed as a saint from the Church of Emacs and resigned myself to learning a new text editor/operating system/whatever (plz don’t hurt me, I’m new to emacs).

After this, I couldn’t figure out how to run Coq through Proof General, and time passed while I grew increasingly frustrated. Then Alan to the rescue! He helped me figure out that emacs wasn’t correctly loading my path, and once that was fixed, I was able to write Coq and do cute stuff like:

1
Proof. reflexivity. Qed.

Yay!

Tomorrow I will continue working through Software Foundations. Aki, an alum, has also kindly pointed me to some resources for implementing type inference algorithms which I plan to hit up once I have gotten a feel for the theory behind it. Excited to see where this leads.

Oh, and I remapped Caps Lock from ESC to CTRL. So, uh, yeah.

A Working Gunzip and Soldering

Yesterday was a super productive day for me. In the morning, I was in the midst of debugging my gunzip implementation in Haskell. I have a function addItem that adds a node to a HuffmanTree by writing an IORef val because I needed mutability. When I’m creating the HuffmanTree, I need to add a whole slew of values (from a code table) into the tree, so I mapped the addItem function over the list of codes, which returned [IO()]. My problem here was that despite having added items to an initial empty tree, I was returning an unaltered tree. I was confused because I was sure I had allowed for mutability! But why?!

Luckily, Alan happened to be running an impromptu session on Monads where he covered the IO Monad, and attending that helped me figure out what my problem was, I think.

I’m still not precisely sure if I’m understanding correctly but [IO()] is a list of IO()s. And things in the IO monad won’t evaluate until run-time. So basically I had a list of thunk-like things that wouldn’t write until evaluated.

This does not work

1
let added =  map (\(label, codes) -> addItem root label codes) code_table

but this works

1
added <- sequence $ map (\(label, codes) -> addItem root label codes) (code_table)

As an aside, added is actually a useless value (it’s just a list of ()s). I don’t care about it. All I care about is the value of root because I have mutated it to add nodes to it.

After this, I spent some time fixing off by one errors because I was translating Julia code to Haskell and Julia is 1-indexed while Haskell is 0-index. Lol. THEN IT WORKED. HUZZAH!

In the afternoon into the evening, I worked with Dana, Minnie, and Sophia on soldering chips, wires, and LEDs together. It was loads of fun and will continue today, I suspect.

Halfway, What???

Wow, wow, wow. This week marked the halfway point of my time at Hacker School. It’s been an exciting time, with the incoming of the new batch (28 new Hacker Schoolers!) and 455 Broadway is much more lively than it was before. It’s been harder to find a place to sit, which is a good problem to have. :)

I haven’t blogged since last week, so a lot has happened since then:

  • Very proud to say that I made the cats stream on Zulip.
  • My implementation of gunzip is undergoing debugging, so hopefully I can have that done by the end of the week.
  • Dana taught me how to solder! I soldered wires onto a strip of NeoPixels.
  • Dana and I checked out HackManhattan, a space for hardware hackers. They were kind enough to let us go through their extra parts and we found the power sources we were looking for for the party on Friday.
  • Mel Chua, our first resident, gave us very informative talks on different learning styles and how to maximize our time at Hacker School. I do sort of wish this happend on the first week for “seconds” since I feel like some of us floundered at figuring out how to get used to self-directedness.
  • I missed my first Friday session to go visit my mom in North Carolina.
  • I am back to being addicted to coffee. Porto Rico Importing Co. is my vice.

Here’s to another six weeks! Well, more like 5 and a half weeks. :D:D:D:D:D:D: <— Some alums taught me this happy/sad combo face.