Wrapping up Calculus and what’s next

It’s been a long time since my last post, so I thought I should give an update and close the book on my summer studies.

As I wrote about before, I decided to take a step back from coding earlier this summer and focus on learning Calculus.  I am the long term goal of creating projects using computer vision, machine learning, and natural language processing.  As I got deeper into the subject matter, I realized I really did need the math if I wanted to create my own algorithms rather than rely on libraries.

So I went back to the drawing board and re-learned Calculus over the last 5 weeks using MIT’s OCW materials.  Two days ago I took the online placement exam at Harvard extension school and I’m happy to say I was placed into multivariable calculus.  In other words, I successfully learned the course material for single-variable calculus. (Side note: the placement exams are free to take if you’re ever curious to get a quick assessment of your math, science, or writing skill level, you just need to sign up to their online system for access.)

I’m planning on taking multivariable calculus this fall for credit via the extension school’s online system.  It’s pricey ($1600), but it was the best option I could find that worked with my schedule.  (Community college would have been the best option as it’s in person and comparable cost-wise, but classes didn’t meet at a time that worked for me.)

My goal is to build up the pre-reqs I’d need to get into a CS masters program.

In the short term, I’m attending two residency programs – one for tech and art this fall and the second for programming in the spring.

Maybe I won’t end up applying to CS masters programs, but I’d like to at least give myself that option.  And I’m sure I’ll learn a ton along the way!

Learning to learn (more!)

Hello everyone!

In a previous post I talked about how I’ve started looking into new learning techniques to help me on my learning quest.  I’m currently teaching myself math and programming, and it’s been tough.  Progress comes in fits and starts, and I’ve been down several dead end paths.

  1. I tried a purely project based approach.  I sat down and thought of interesting projects I’d like to make and then jumped into coding to make them.  That was a good way to get a taste of what programming is about and to confirm that it’s something I’d like to do more of.  However, the projects I was dreaming up were waay out of the scope of my beginner’s ability.  I could have scoured github for similar projects and mashed together a frankenstein project that more-or-less did what I wanted it to do, but I didn’t think this would be a good way to actually learn the concepts.  I didn’t think this would help me to generalize skills and learn to do more interesting work in the long run.
  2. So I turned to classes.  I signed up for some advanced online classes through Udacity and EdX on machine learning, robots, and AI.  I started programming in February 2017 so it’s no wonder that by April I was NOT ready to take these types of classes.  I muddled through most of a Udacity course (they give you generous starter code) and got halfway through the EdX course before I hit a wall.  Again, I didn’t think I was really getting the concepts.  I could hack together a project that would spit out the right answer, but I didn’t really get what I was doing.
  3. So I took a step back.  I started taking linear algebra and then realized I needed to go back further, and started Calculus.

Learning Calculus

For the past two weeks, I’ve been teaching myself Calculus using the amazing resources from MIT OCW and Professor Paul Dawkins’ online notes.  I also bought a big book of calculus problems for additional practice.  The first week was pretty good.  I was chugging along and felt I was making good practice.

This past week has been less than great.  On Wednesday when I sat down to do practice problems, I got every single problem I tried before lunch wrong.  That means I spent four hours bashing away ineffectively at problems and feeling more frustrated and despondent as the minutes ticked by.  I had been unwilling to move on from the work I was doing (applications of derivatives) to new material (integrals) because I wanted to master the first thing first.  But it was clear this wasn’t working.  I moved on, and found a groove again with integrals.

But it was clear that I was missing something.  I wasn’t learning effectively.  Something just wasn’t clicking and I wasn’t sure what.  I had done calculus in HS and did well, I had done problems the day before and gotten them right.  Why suddenly did it feel like my brain was mud?

I was reading through Professor Dawkins’ post on how to study math and it was obvious to me that I was in category 2 of students who don’t do well in calculus.  I was studying for hours each day but not doing well on my problem sets.  It was clear to me that I had inefficient study habits and unless something changed, I was just going to end up wasting more time.

Around the same time, I stumbled across this gihub community of Open Source Computer Science learners.  And from there, I found the subreddit for the group, which led me finally to this QA mysteriously and intriguingly titled “looking for alternatives.”

And there, I found this amazing resource for a self-learning CS curriculum.  What I love about this list is that it has a bunch of helpful resources for laying the groundwork for your self learning endeavor.

I don’t plan to go through this whole curriculum, but I did start with the learning to learn course on coursera and it’s AMAZING.

There are some things I knew or practiced when I was in school, but this time around because I’m older and feeling pressure to see results faster, I haven’t been doing, to my own detriment.  Some of the key points:

On learning/chunking

  • Chunking is the idea of grouping together related ideas/concepts in order to improve learning.  If we are memorizing a song we chunk the tune and the lyrics which make it easier to remember both.
  • When we learn something new, we lay down new neural pathways for the material.  We need to strengthen those neural pathways in order to truly understand something.
  • To strengthen neural pathways, it’s better to learn the material over time.  If we study for one hour a day for five days instead of five hours in one day we’re more likely to remember the material and to understand it more deeply.
  • It’s best to work in small chunks of time.  For example, do 25 min of focused work, then take a break, then 25 min more etc.  It’s also helpful to review material right before bed as we commit things to long term memory while we sleep.
  • An easy technique to improve retention and learning is to try to write down the key points that you learned right after learning them (without notes/looking – which is what I’m trying to do right now!)

On procrastination

  • Focus on process instead of product to beat procrastination.  Instead of thinking, I’m going to finish those five homework problems think, I’m going to work on my homework for 25 min.
  • Every night before bed, write down the tasks you plan to accomplish the next day.  Don’t go too crazy!  5-6 tasks is more than enough.  Keep them focused on process.
  • Keep all this in a journal and take note of what worked, what didn’t, and how long things actually take.  Over time you’ll get a better feel for what you can accomplish in that time.
  • Plan your quitting time.  It’s important to pace yourself and it’s also not effective to just keep on studying past a certain point.  You won’t learn more or better this way.
  • Procrastination starts with a cue, try to change that cue.  For example, if your cue to procrastinate is hearing the ping of a new email, turn off your phone.  Removing the cue will make it easier to avoid procrastinating.
  • Reward yourself for completing tasks.  Rewards can be emotional (I draw a smiley face and write ‘yay’! on my paper when I finish something) or external.
  • Lastly, believe that you can change.  Belief that you can break the cycle of procrastination is important!

On memory

  • Humans have good spatial memory.  Use this to your advantage by building a memory palace
  • The weirder or funnier your mnemonic devices, the better you’ll be able to remember the information.
  • It might seem silly, but these devices can help you as you’re starting to form memories.  Over time, this will help strength those neural pathways!

Eep!  And that’s all I have for right now.  I’m sure I’m forgetting a lot.  :/  Will need to review tomorrow (as per the suggested way of learning!)

Changing my tactics

All of this is to say that I have a lot of bad habits to unlearn and new habits to form.  Instead of going the Scott Young route and trying to cram a whole bunch of learning (ie a semester of Calculus into one week), I’m going to spread things out a bit more.

Starting this week, I’m going to concurrently do my algorithms, calculus, and linear algebra coursework.  I plan to spend ~1 hour in the morning reviewing the material, and then dedicate the afternoon to practice problems or other study techniques (e.g. making flashcards, building my memory palace etc.  🙂

I’m not sure how this will go, but my rough goals are:

  • Finish all three courses by the end of August
  • Be comfortable with applications of Calculus and Linear Algebra
  • Be able to write the pseudocode for all the algorithms covered in the course
  • Be able to analyze running time of algorithms (which is an application of calculus, I believe, so….two in one!)

Having fun!

Lastly, while math and coding is fun, it’s important to give my brain a break and do something I enjoy!

I LOVE puzzles so another book I picked up is The Art and Craft of Problem Solving.  It’s aimed at HS students (and teachers) who are interested in the math olympiads.  While I’m definitely not in the right age group for that, it has a bunch of fun brain teaser math problems like the classic census taker problem.

A census-taker knocks on a door, and asks the woman inside 
how many children she has and how old they are. 
"I have three daughters, their ages are whole numbers, 
and the product of the ages is 36," says the mother. 

"That's not enough information," responds the census-taker. 
"I'd tell you the sum of their ages, but you 'd still be stumped." 
"I wish you 'd tell me something more." 
"Okay, my oldest daughter Annie likes dogs." 

What are the ages of the three daughters?

Enjoy!

 

Building a practice of deliberate practice

I’ve been thinking a lot about how to get the most bang for my buck out of my time away from work.

Finding my path

It took me a little while to find my feet and my path to programming.

Z and I were chatting the other day about recognizing our emotional / anxiety / stress cycles and something she said made a lightbulb go off for me.

I realized that every time I feel frustrated or down, I decide to start a company and/or get an MBA.  It’s not because I’m frustrated by some big problem and have a brilliant idea of what to do about it.  It’s because I’m frustrated with myself and think that getting the stamp of approval of an prestigious MBA or saying f-you to my job/crappy manager/whatever by starting my own company will be the panacea to my ills.

I wanted to be respected.  I wanted to be successful.  And I wanted to fit in.

I have a tendency to do what my friends do (a terrible, terrible habit!) due to a desire to fit in and gain their respect.  I started out college as a math/bio major and then in my junior year switched to international relations since all my friends were history and poly sci majors.  Math/science was considered dull and very un-hip.

I didn’t really enjoy the work, but I found a niche that I did enjoy – theory of technology – and exploited that the best I could.  My thesis advisor senior year even asked me point blank: how is what you’re doing international relations?  And to be honest I didn’t have a great defense.

Later, even though I felt I was on the wrong path and was unhappy with my job, I felt paralyzed from making any changes.  In my early-mid 20s I still felt young enough to defer any difficult decisions to my older self (I hate my job now but by 35 I’ll be a wildly successful businesswoman.).

By the time I hit 29 the magical thinking stopped working.  29 to 35 isn’t a whole lot of time for me to start loving my work.  However, I was worried I was too old to make a change and figured I should stay the course and find a way to make peace with my job. But I just couldn’t.  I flip flopped between googling ‘am I too old to start over?’ and feeling young and exuberant and ready to take on the world.  And, of course, all the while I was anxiously scouring the internet for hope time kept right on ticking by.

So it’s no shocker, with all this brewing, that when I finally took the plunge to quit my job in Feb to focus on learning to program, within a week I was researching competitors and interviewing potential users to validate an idea I had for a company.

I was scared.  I was scared that I was suddenly on my own and that my friends would all think I was a failure.  Saying I was starting a company made sense to people.  Saying I was learning to program because I wanted to make art robots did not.

Luckily, I realized within a few weeks that I had no interest in being an entrepreneur.  And with that out of the way, I finally recognized the cycle for what it was – my fear and need for outside recognition – and was able to move on.

Learning to learn

Now that I had found my path and realized that I really did want to learn to program, I had to learn how to learn.

The next struggle was to tackle the feeling of being too late to the game.

I felt years behind where I wanted to be, and felt I needed to catch up.  I had a million ideas of projects to build, but zero skills whatsoever.  My first instinct was to dive in and start building projects, figuring that I would be driven to learn things in order to bring my ideas to life.

This kind of worked.  But with each project I realized a bit more how much I didn’t know.

So next came a recalibration period.  I learned what I didn’t know and how far I needed to go.  But still I felt anxious at my slow pace of progress.

Was I actually getting better?  I had no measuring stick.  No way of knowing.  And the more I realized I didn’t know, the harsher my inner critic became.

Deliberate practice

The second half of last week I felt pretty lost.  I had a great tutoring session last Tuesday.  I then spent Wednesday preparing for an interview for the Recurse Center on Thursday.  After my interview, I felt a little deflated.  I was off track with my Calculus and Algorithms classes, I had homework from my tutor, and I just felt all over the place.

I tried to get back into the next week’s Calculus lecture on Friday, but after I watched the videos I didn’t feel like I had truly understood the material.

I had planned on working over the weekend, but ended up taking both Saturday and Sunday completely off.  I spent time with my family, went to an art show, went for a nice long walk, and just relaxed.

I thought a lot about what the next month(s) might look like.  I heard on a podcast recently the quote by Bill Gates that people tend to overestimate what they can accomplish in one year and underestimate what they can accomplish in five.

I thought a lot about quitting.  And how the reason the above is likely true is because we give up when we don’t see results as quickly as we’d like.

I thought a lot about committing to change.  There’s a line in Dr. Tim Pychyl’s procrastination podcast that really hit home for me about changing habits being a lifelong pursuit and, if that sounds like too much to bother with, what is life if not the pursuit of bettering ourselves?

Finally, I thought about committing to learning.  I didn’t just want to watch all the Calculus videos on 2x speed and pump out exams a la Scott Young.  I wanted to deeply understand the material so that I could apply concepts from one area to problems in a completely different area.  For example, I was recently trying to analyze the running time of algorithms by taking the limits of the formulas, but I was getting funky answers.  I knew I needed to take limits (using my Calculus hooray!) but I couldn’t figure out how.  The form of the equations for big O notation was different from the form equations take in my Calculus class and I was having trouble applying the concepts.

So what’s the point of all my rambling?

All this is to say that I decided earlier this week to really commit to learning.  But, I wasn’t just going to do a lot of practice problems.  I didn’t think that was the best use of my time.  Instead, I spent a few hours researching learning strategies and formulating a real, achievable plan.

I also realized that mixing subjects just doesn’t work for me.  In other words, doing Calculus for a day and then switching to Algorithms for a day doesn’t work.  It was putting pressure on me to finish a week’s material in a day so I could feel that I had wrapped up a lesson before moving on.  This meant I wasn’t taking the time to really dive into concepts since I was more focused on the output (getting a good score on the quiz, getting the right answers from the programming project) instead of the process.

I listed out some general concepts I didn’t feel I had a good grasp on:

  • limits
  • general info about proofs (e.g. what is a proof by induction?)
  • proofs of trigonometric derivatives
  • rusty on some basic algebra/geometry like completing the square, solving trig equations
  • tree traversal
  • priority queues
  • etc etc etc

I plan to spend at least 3 hours per concept.  This includes writing out proofs, solving them by hand on my own, doing practice problems, and whatever else it would take to develop an instinct for the material.  I want to get to a place where things just ‘felt’ right or wrong.

Giving up on shortcuts

I listened this morning to this old Freakonomics episode about How to be great at anything.  It dives into the idea of deliberate practice, and the story about the psychologist – singer is such a great example.

I used to approach learning as a goal-oriented practice.  I wanted to learn concrete thing X which would then allow me to do concrete thing Y.  The goal was to be able to do Y.  Not to understand X.

Now I’m thinking of it more as a lifestyle.  I’m committing myself to “slow learning” and mastery, and also to the knowledge that I may never get ‘there.’  No more of this learn X in 30 days BS!

This is not to be equated with lackadaisical learning.  It’s not that I’m slowing down and only studying an hour or two a day.  If anything, I’m ramping up and getting more intense.  I’m reorienting my mindset and digging in for the long haul.

 

Asking for help

** If anyone is interested in trying Wyzant (reviewed below), please use my code and get $40 of tutoring for free!**

Sometimes going it alone is great.  And sometimes you need help.

I’ve been teaching myself to code and backtracking to more and more basic subjects to give myself a solid foundation in programming.

I’m still not 100% sure what I’d like to specialize in, but I’m leaning towards data science and/or AI.  (Will write more on my love of cyborgs and why AI later…)

But I have to start at the basics.  For now,  I’m doing simple toy programs (tictactoeAI) and working through several Coursera courses on algorithms.

While the code I write works, I just know it’s ugly.  It feels brittle and ungainly and while I wanted to fix it, I didn’t know how.  One of my biggest fears about being a self-taught programmer is that my code might work, but it’ll be a hot mess and I’ll have locked in bad habits.

If I were in school, I’d be getting design feedback, but going it alone that’s hard to get.  I’ve been submitting code snippets to codereview stackexchange and while that’s been hugely helpful it doesn’t go far enough.

I really needed someone to sit down with me, walk through my code line by line, and give me feedback.

Looking into tutoring options

After a week or two of fretting over what to do I finally decided to try an online tutor.

Ideally, you could ask a friend or coworker for help, but I don’t have any close friends that code and felt bad asking someone I didn’t know very well for such a big favor.  Since I’m a beginner, I need a lot of patient explanation and I thought that was just too much to ask someone who wasn’t a close friend or family member.

I looked into various meetup options, but ruled them out for much the same reason. The ones I found were group study sessions where peers helped one another – basically stackexchange IRL.

Online tutoring with Wyzant

So I took a chance in a tutor on Wyzant. I was worried about the cost ($40/hr for the tutor I chose), but since the first session is free I decided to try it out.

I met my tutor for the first time this afternoon.  She was amazing!  It’s incredibly helpful to have someone who knows what they’re doing walk with you through your code.  I’ve done crit sessions with writing and art before, and I would put codereview closer to the crit side of the spectrum vs. the tutoring side.

We discussion some foundational CS concepts like layers of abstraction, scope, and the stack (and how/when it gets cleared out).  She clarified a lot of concepts I had read about and vaguely understood.  She also pointed out some problems with my code that I never would have noticed on my own.

For example, in my tictactoe AI when the user plays more than one game, I create a new instance of the board/AI objects for each new play.  She told me that if a user were to play a whole bunch of games in a row, that my current setup would lead to stack overflow issues.  This isn’t something I ever would have caught since I never played more than one or two games in testing.

All in all, it was great to be able to ask all the why questions that I never get to ask on online forums or when asking a quick question to a friend.  When she first pointed out the issue with my tictactoe game, instead of just saying ‘ok, got it’ and fixing it, I asked why it was a problem.  That led to a 10 min tangent on stacks and scopes, but it clarified the concepts I needed to know.

All in all, it was time well spent.  I’m reworking the programs we looked at together now and am planning on making our sessions a regular (weekly?) occurrence.  I figure $40 a week on tutoring is still waaaay less $$ than school and a worthwhile investment to learn to write legible and strong code!

Going back to basics: Calculus

There are a lot of great things about being an adult student. Today I started (re)learning calculus and I have to say it’s way easier this time around. I barely remember anything from high school, so it’s not easier because it’s review. It’s because I’m learning it because I want to and I know why it’s useful.
Those two reasons are tightly linked.  I’m learning it because I want to, and I want to because I know why it’s useful.
In school, we’re often told we need to learn things “just because.”  Because we need to get a good grade.  Because we need it for college.  Because that’s what people do.  None of these reasons are very compelling.  They might be enough to get you to study so you can ace a test, but they’re not enough to keep you going when things get tough.
And they’re not enough to get you curious to find out why.  And it’s knowing the why that makes things really interesting.

My love-hate relationship with math

I loved math when I was a little kid.  I took math courses (kumon?) when I was really little and I used to do the problems in my little paper booklet, then erase the answers so I could do them again.
In HS, I fell in love with calculus.  It was my favorite subject my senior year.  I worked really hard in the class and did well.  At first, I kind of tricked myself into liking it because I knew it was going to be hard.  I decided that because it was hard, I was going to love it twice as hard and make it ‘cool’ to keep myself motivated.  As Amy Chua wrote in Battle Hymn of the Tiger Mother, “Nothing is fun until you’re good at it.”  I worked my ass off in that class, got good at it, and had fun.
However, that wasn’t enough to carry me through in college.  I couldn’t stay awake during linear algebra (it was at 1pm, the dreaded post-lunch slump…) and I walked out after 30min of the first lecture of multivariable calculus.  On day 1 the prof jumped straight into the material saying he expected everyone to have the right background.  I thought I was in over my head and I just didn’t want to work hard for something that I wasn’t sure I needed.
I decided I just wasn’t a math person and gave up.
I gave myself permission to be bad at math, and bad I was!  I got a C in linear algebra – my final exam was like a nightmare.  I was staring at the paper and had no idea what anything was about.  I’m shocked I even got a C.  My senior year I took statistics and barely got a B.  I don’t remember anything about the class except that I would bring a homemade egg bagel sandwich for breakfast on those days.
I rationalized it by thinking I wasn’t a math person and moved on.  The thing is, most of us aren’t math people.  Or writing people.  Or drawing people.  We have to work to acquire those skills.  Some of us get started on that skill acquisition process earlier, so have a leg up when they get to HS/college/wherever, and that extra level of mastery makes it more fun for them.
Sure, there are the Maryam Mirzakhani‘s out there who probably do have some underlying natural ability, but I’m going to guess that most people just worked hard until it clicked.

Re-discovering math (and other basics)

This time around, I had a reason to learn.  As I’ve written about earlier, I’ve been falling down the rabbit hole of programming.  I’ve learned a lot, it’s been a ton of fun, but I’ve been hitting walls when it comes to the basics.
I started my journey wanting to make a robot.  I started two intro to AI courses (one on Udacity, one on EdX) but I had to quit both.  The Udacity course breezed through the interesting and complicated content and gave you way too much starter code so I didn’t feel as if I was learning anything.  The EdX course was better, slower paced with in-depth proofs and projects where you had to write programs from scratch, but a little over halfway in I felt stuck.  While my code was outputting the correct answers, I didn’t feel like I understood the material.
I decided to take a step back and spent a week on an Intro to Algorithms course on coursera. That was super helpful for understanding the value of primitives and the importance of running time, but it also made me realize I needed stronger math skills.

Calculus or Linear Algebra?

I vacillated a while between taking calculus and linear algebra.  I started watching the highly recommended Gilbert Strang lectures for linear algebra but kept feeling like I was falling into old patterns.
I was dragging my heels on calculus.  I had already taken it twice (once in HS and once two years ago when I blazed through the Khan Academy Calculus series with the thought of placing into a higher level continuing ed math class.  I didn’t end up doing that since I got a new job and got busy :/).  I was also starting to feel discouraged about my progress.
Five months into my learning sabbatical and instead of becoming a programmer I was going back to HS math.  Bummer.
But this has been my downfall time and time again.  I try to skip ahead because I’m impatient, but later regret not taking the slow and steady route.
I’m happy to say I learned from my past mistakes and am taking the slow route, which means taking single variable calculus.
There’s a lot of rust for SURE and as the prof said in one lecture, the calculus is the easy part. It’s all the geometry, trig, and algebra you need to do everything around the calculus that’s hard.

To binge or not to binge?

Today was my first full day of calculus.  I got through a few days of lectures and half of the first problem set.  I even caught an error in the homework solutions (and another one on the blackboard in the lecture…I emailed MIT to suggest a correction for that…we’ll see if they respond!) 🙂
I’m trying out binging to see how it goes.  I find it difficult as a full-time self learner to toggle between courses.  In school, you easily take 3-4 classes a semester.  The schedule is imposed on you from the outside.  With online lectures, I end up doing about a week’s worth of material in a day.  It just seems easier to click on to the next video than to stop and change gears to a different subject.
So I did 4 weeks of an algorithms course in ~4 days, and have finished 3 lectures worth of calculus in a day. If you think about it, it adds up.  The algorithms class suggested working 8-10 hrs a week (about a day’s work) and the MIT class is about the same.
So far I haven’t had any major stumbling blocks where I have to pound away at one problem set for 10+ hrs, but I’m sure those days will come and the 1week = 1day ratio will slip.
I’m also planning to experiment with different learning methods.  I’m concerned that binging will lead to poor retention.  I’ll finish the calculus class in two weeks, but then a month later if I try to do multivariable calculus I’m worried I’ll have forgotten everything.
One thought is to try binges by day instead of by course, e.g. Monday = calculus, Tuesday = algorithms, just to give a little time for things to sink in.
In any case, it’s all an experiment!  We’ll see where it goes!

Falling down the rabbit hole

Hello again world!  It’s been a *very* long time since my last post and I apologize profusely for that.

Since I last wrote about my chrome extension, I’ve been busy jumping from project to project, chasing whatever captures my interest.

It all started with the Google FooBar challenge.  Right after I published my chrome extension I felt listless.  Anytime after a big project or event is finished I always feel a bit let down and lost.  I wonder, now what?  After days of waking up each day with purpose and direction, I’m back again at square one.  Needing to find a new project to capture my interest, but not really knowing where to start.  I keep a lot of notes jotted down with project ideas to avoid staying in these doldrums for too long, but it’s hard not to find myself there for a least a little while.

In any case, I was at the library googling around and trying to figure out my next move when I stumbled across the Google FooBar challenge.  The challenge is a semi-secret easter egg that gets unlocked when you google a specific term.  For me, it was ‘list comprehensions python.’  The search results page dropped away and I was invited to try this coding game.

Screen Shot 2017-05-02 at 3.17.13 PM

The first level was quick and easy, a simple list comprehension.  From there, I plodded my way through level two, and barely eeked by level three.  I haven’t started level four yet as I know it’ll be a disaster.  I’m waiting to build up a bit more knowledge before opening up that Pandora’s box.  I won’t go into implementation details, but if you’re curious a few of my FooBar solutions are on my GitHub here.

My solutions aren’t always pretty, in particular the matrix transformations in doomsday fuel is embarrassing, but they worked!

Screen Shot 2017-05-02 at 3.46.10 PM

The big side effect of FooBar was getting me into the backend of code.  Up until that point, I had been mostly doing projects with a visual component.  I hesitate to say front end since it was hardly that (e.g. a custom designed form with an automated backend, or a chrome extension that changed words on the page).

Google FooBar, in the guise of an adventure game, gets you working on algorithms.  I read up on Dijkstra’s shortest path and breadth first search.  I discovered matrices and dot products.  And I realized I really preferred this stuff to JavaScript and GUIs.  A little extra context: right before I came across FooBar I had been trying to learn Three.js but my heart just wasn’t in it.

Alongside all this, I had been taking a MIT course in order to learn about state machines.  I had wanted to do this in order to improve the performance of my robot.

Through the MIT course, I was forced to figure out virtual environments (I ended up with conda as venv was a disaster for me) and learned a bit of object oriented programming.

I wasn’t loving the MIT course format so I wandered over to Udacity and began taking a class that covered many of the same concepts titled Artificial Intelligence for Robotics.

I got almost to the final project but was, once again, unsatisfied with the course format.  The Udacity class provided the bulk of the code for each assignment, so I didn’t feel like I was actually learning the concepts.  I could get the right answers on the quizzes and programming projects, but if asked to write the code from scratch I wouldn’t have known where to begin.

So I abandoned yet another course (so much for quitting quitting haha!) and tried instead an EdX course Introduction to AI.  For me, this hit the sweet spot.  The class was hard but not impossible.  Some assignments provided startercode, but most asked you to write programs from scratch.

The course kicked off with breadth first, depth first, and a star search.  Next, we were asked to program a 2048 solving AI.

While banging my head against the wall trying to figure out whether my implementation of minimax was wrong, or whether my heuristics were wrong, I took a little detour and coded up a tictactoe AI.  Through this exercise, I learned that my minimax was just fine but my heuristics were terrible.

The long and short of it is, I have been negligent in my posting but I’ve been busy!

This post focused on the mechanics of what I’ve been doing.  Next time, a bit about what I’ve learned about myself 🙂

(Oh, and I also took a glassworking class – photos of my terrible glass sculptures to come soon!)

Taking a step back

The past few days I’ve been banging my head against the wall trying to learn object-oriented programming.

Here’s what happened:

Monday

I sat down and decided to convert my teleabsence robot code to a ‘finite state machine.’  But I didn’t really know what that meant.  All I knew was that I wanted my robot to do a bunch of things at the same time, and I discovered the idea of a finite state machine via this Adafruit tutorial on multitasking the Arduino.  I followed the tutorial and got my lights blinking at different rates, but I just couldn’t understand how to translate what I had learned to my robot.

I decided to take a step back and learn wtf a finite state machine was.  I read a bunch of tutorials, but still didn’t get it.  I decided to go even further back and watch some lectures.  I settled on this MIT course, Introduction to Electrical Engineering and Computer Science.  I finished the lecture on Object Oriented Programming (OOP) and did the design exercises.  You can see my code here.

Tuesday

I’m feeling a little disheartened at this point.  I spent all of Monday reading and studying and doing problems, but I still wasn’t understanding how to apply any of this to my robot project.  I was feeling my enthusiasm dip just as I described in my learning with context post.

But I powered on!  I finished the next lecture on state machines and did the associated software lab (you can see my code here) and quiz (code here).

Then I tried giving my robot another stab and was totally stumped.

Feeling discouraged

I felt completely discouraged.  When I looked at my robot code it was like looking at it through a fog.  Who was I kidding trying to learn this stuff at 31?  These kids I see in the audience at the MIT lecture at half (ish) my age.  I’m 15 years too late to the game.

I had to remind myself that I had been learning OOP for TWO DAYS and I just needed to keep at it.  Of course it was hard!  Plus the class is in Python and my robot is in Arduino (kind of like C++).  This meant there was be an extra step of learning new syntax on top of new programming concepts.

Wednesday (Today)

Today I woke up redetermined to figure it out.  Of course it was going to take longer than two days to learn this stuff.  What I needed to do was figure out what exactly I wanted to learn and focus on that.  I need to stop jumping back and forth between projects and focus on what exactly I need to learn.  And I need to give myself enough TIME to learn this stuff.  I need to forgive myself for not magically understanding everything right away.

My mini-crisis last night, though, made me want to write a psychoanalytical post.  I think about this a lot, my mindset, how I learn, what I want, why I want it, etc., and I thought it might help to get it all out.

Fixed vs. Growth mindset

If you’ve never heard of Carol Dweck, go watch her TED talk now.  And read her book. She studies mindsets and learning.

I’ve thought a lot about my own mindset and approach to learning, what’s served me well, and what’s changed over the years.  I think it’s simplistic to say I have a fixed mindset and that’s why I’m not focused enough to learn this stuff.

Dweck also notes that mindsets change over time and depending on the subject matter.  You might have a fixed mindset when it comes to math, but a growth mindset when it comes to running.

I’ve thought about how my mindset has changed over time.  I often think about how focused I was in HS.  I would go to the art studio and stay there for hours painting or sculpting.  I’d forget to eat.  I’d do problem sets for math over and over.  Erase the answers and do them again.

I kind of had a growth mindset in high school, but only insofar as my grades were concerned.  I would believe I could get an A if I studied hard (and study hard I did!) but I didn’t believe I was ‘smart enough’ to really do subject X.

For example, I got a 5 on the BC AP Calculus exam, and a perfect score on my BC Calc final, and a very high grade in the class overall.  Part of the reason is because I wasn’t admitted to the class to begin with.  I was told my math skills weren’t good enough for BC, that I was placed into AB Calc.  My first day of senior year the AB Calc teacher caught me in the cafeteria and asked why I was in his class.  You should be in the BC class, he said.  I showed up for BC Calc and the teacher wasn’t happy I was there, but said he’d let me have a try.

I took that challenge and ran with it.  I aced the class.  But I never thought to myself, hey, I’m really good at this.  I should be a mathematician.  I thought ‘real’ mathematician’s got the material right away.  They didn’t have to study and struggle.

It took me many, many years to realize that I was wrong.  Yes, some people struggle less with some things, but everybody struggles with something.  And if you do something over and over again for long enough (build enough context) you can be good at nearly anything.

Fuck you mindset

I didn’t really have a ‘real’ growth mindset.  I wasn’t intrinsically motivated to learn this stuff, though I did believe that with effort I could do anything.  What I really had was a fuck you mindset.

In HS, what I really loved was showing people they were wrong about me.  I loooved upturning expectations.  My parents like to tell this story about when I was a kid how they were worried I was a slow learner.  I was terrible at spelling and was put into a remedial class in the 4th grade.  They didn’t think I’d amount to much.  I think that story stuck with me.  I incorporated it into the narrative of who I was.  I was someone you weren’t expecting.  I was smarter than I looked.  I wasn’t a typical girl.  Whatever.

However, that part of me, the “fuck you” part kind of died off as I got older.

As an adult, nobody cares.  Nobody has particular expectations of you.  There are no grades.  Markers of success are in your mind.  The external markers that do exist don’t have a linear path to obtaining them like good grades in HS.  You might want to make the Forbes 30 under 30 list (I know people who wanted to make it, and people who did make it).  But you can’t just work hard and make the list.  It doesn’t work like that.  You have to work hard, but you also have to be well connected, noticed by whoever it is that’s putting that list together, etc etc etc.  It’s luck as much as it is hard work.

So as I got older I realized that nobody really cares and learning something or getting good at something just to prove somebody wrong isn’t really a sustainable motivator.  I needed to figure out what it is exactly that I enjoy.

Figuring out what I like to do

From the first coding class I took back in 2011, I fell in love.  This was something that I could do for hours on end and not get bored.  This was something I really enjoyed.

As an adult, though, it’s a lot harder to throw yourself into learning a new skill.  You don’t have external motivators (my fuck you mindset wasn’t going to serve me here!), you have other responsibilities (job, relationship), you don’t have a clear path (take these 16 classes and become an engineer!).

I KNOW all this.  I know it so hard.  It’s embedded in my fucking bones.  But I still need to remind myself of it now and again.  When I hit my wall yesterday, I needed to take a step back and remind myself, Ann.  It’s been TWO DAYS.  You’re discouraged because there is no purpose, no degree at the end of the tunnel, there’s not even an end to the damn tunnel.  And that’s ok.

It’s ok because this time I’m doing it because I LIKE doing it.  I like programming.  I like seeing my robot run around and I want to make it run around even better.  So that’s what I’m going to do.  I’m going to slog through learning OOP.  I’m going to figure it out in python and figure it out on Arduino.  And at the end of the day I have no idea if any of this will lead to a job or an award or anyone caring at all, but none of that matters.  I’m going to keep my head down and figure this shit out.

Coding Part III: Design

Hi there!  Read Part I of my coding journey here, Part II here, and get the chrome extension here!

The dreaded “D” word (Design)

I am a terrible graphic designer.  I draw, paint, and sculpt and people always think because I “do” art I must be good at design.  They apply this to everything from graphic design to interior design.  However, these are totally different disciplines and I am a terrible designer.  So I won’t even pretend that I came up with some fancy design.  Instead, I googled around a whole bunch until I found a layout that I liked and copied it.

The design my tabs are based off of is from Jen Simmons’ blog.  I LOVED her big fat serif font so I found a similar free font from Google Open Fonts called Abril Fatface.  I used this for the names of the women.  For my body font, I picked a regular looking serif called Lora, also from Google.

Jen Simmon’s very helpfully had an example in her blog post that was exactly what I wanted my page to look like.  However, I wanted to use the new CSS grid layout system that had just launched (March 2017!).

I used her page as a visual template, but did my CSS from scratch.  I’m not very familiar with CSS.  I can never make floats and spans and whatever else do what I want them to do.  The Grid layout system is AMAZING.  It’s soooo easy to use and intuitive.  I was thanking my lucky stars this had just come out.

The key design decisions for me here were:

  1. I needed three layout options: 1. text-only, 2. text+image from Wikipedia, and 3. backup local image.
  2. I wanted a responsive page.

Below is what I came up with.  As you can see, the layout is heavily influenced by Jen Simmons’.

Here is the code for my styles.css layout!

Screen Shot 2017-04-20 at 2.53.39 PM  Screen Shot 2017-04-20 at 2.53.31 PM  Screen Shot 2017-04-20 at 2.53.21 PM.png

text and image from Wikipedia

Screen Shot 2017-04-20 at 2.57.29 PM  Screen Shot 2017-04-20 at 2.57.36 PM Screen Shot 2017-04-20 at 2.57.43 PM

text only from Wikipedia

Screen Shot 2017-04-20 at 3.00.52 PM.png

backup image from local directory

The code

Now that I knew what I wanted my page to look like, I had to code it.

My img variable was the key.  I had three options:

  1. Wikipedia did not return an img.  Img = “”
  2. Used a local image (no Wikipedia image or text).  Img = /imgs/X.jpg.  Img[0] is always “/”
  3. Wikipedia returned an image (and text).  All other options.

I used two classes in my CSS.  One for one column and one for two.  In my javascript I added an if statement to look to see which of these three options above was in my img variable.  Then I added the appropriate class to my html using jQuery.

if (img == "") {
   $(".tab").addClass("onecol");
   $("#imgdiv").remove();
 } else if (img[0] == "/") {
   $(document.body).css("background", "url(" + img + ") no-repeat center center fixed");
   $("#imgdiv").remove();
 } else {
   $(".tab").addClass("twocol");
   $("#img").attr("src", img);
 }

Trimming text length

I also did a few other checks to account for other funkiness that came up in testing.  For example, really long Wikipedia extracts would go off the page.  I didn’t like that the user needed to scroll to get to the “Read more on Wikipedia” link.  However, I couldn’t just put in a character limit because I didn’t like the idea of the summary getting cut off mid-sentence or mid-paragraph.  This was a bit of a pain, but I added a loop that counted up to 1200 characters to be displayed, and then when it reached the limit trimmed the extract to the nearest full paragraph.

I did this instead of just displaying the first or first and second paragraphs because paragraph length on Wikipedia is super inconsistent.  I didn’t want to just display the first paragraph since some women had a one sentence first paragraph and I wanted to capture more content from those cases.

// extract is the string from Wikipedia of the summary section. 
// It includes html tags.
if (extract.length > 1200) { 
  extractArray = extract.split(/(]*>)/);
  extract = "";
  var chars = 0;
  var stop = 0;
  // display up to 1200 chars of content - disregard html tags
  extractArray.forEach(function(item) {
  chars = chars + item.length;
  if (item == "" || item[0] == "<") {
    extract = extract + item;
    chars = chars - item.length;
  } else if (chars <= 1200 && stop == 0) {
    extract = extract + item;
    chars = chars + item.length;
  } else {
    stop = extractArray.indexOf(item);
    };
 });

Final thoughts & to dos

This was a really great learning experience.  I used jQuery, html, CSS Grids and lots of other new skills.  The whole thing is far from perfect, I wish I could detect faces and dynamically position the images so this wouldn’t happen:

Screen Shot 2017-04-20 at 4.53.39 PM.png

Since most of the images are portrait, when the page scales down to a single column and the image area is landscape, photos can get cut off in weird places.

I also didn’t make the local file option responsive.

I would like a dynamic way to have the list of women.  That way I wouldn’t need to update the files in the chrome store if I want to add or change any names.

I have many other “I wish” and “Next time”‘s, but for now, that’s pretty much it!

Here is the complete code for my chrome extension!  You can install the extension from the chrome store here.

Thanks for reading!

Other random things I learned:

  • If you don’t specify the data type of the result you want from your .get request, jQuery will try to guess it and it might not be right.  I was banging my head against the wall trying to figure out why I was getting back a string and then I read this:
    • The type of data that you’re expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string). source
  • I tried using the wikiblurb library since CS50 is all about standing on the shoulders of others and using good libraries.  I really liked that they had the links in the Wikipedia blurbs they got back, but I wanted more customization and it seemed like a bigger pain to customize around their library than to not use it.
  • I looked at stars.chromeexperiments.com to try to see how they used wikipedia extracts.  However, the blurb wasn’t matching up to what I was seeing in wikipedia, so I’m guessing that the blurb wasn’t getting pulled dynamically.  When I dug up the code (can’t seem to get to it again!) it looked like the blurb data was being held in a file somewhere as opposed to coming from a json request to the wikipedia API.  See screenshot below of the difference.

Screen Shot 2017-04-17 at 5.40.45 PM.png

  • Object-fit was key to replicating Jen Simmons’ image behavior (filling it’s portion of the screen).
  • Some useful documentation of named grid areas.  This was very helpful in using CSS grids to do my layout.

Coding Part II: Radfems

 

Hi there!  Read Part I of my coding journey here and get the chrome extension here!

Part of what reignited my desire to code was a project I did in December 2016 called He to She.  It was a simple chrome extension that changed instances of masculine pronouns (he, his, him) to feminine ones (she, hers, her).  It was pretty janky (code is here) and was largely written with the help of tutorials.

But it was SO much fun to write!

And I wanted to do more.

For my next project, I wanted to create a chrome extension that brought up a new woman in STEM with each new tab.  There are plenty of new tab extensions out there and I figured it should be within my realm of understanding.

Nope!

It was way beyond my capabilities.  So I headed back to the drawing board with CS50.  This time, I was determined to finish.  I had projects to create!

Granted, it wasn’t a straight shot.  I got distracted and built a shelf and a robot, but I got through the course in the end.

So there I was with a blank sublime text page, an idea for a project, and no idea how to start.

Sketching out the plan

I began by sketching out the user experience of my project:

  1. User opens a new tab.  A page with a random woman to know in STEM appears.  There is a picture, her name, and a short bio pulled from Wikipedia.  At the bottom of the page, there is a link to read more on Wikipedia.

Then, I broke down the actions I would need to figure out:

  1. Get the name of a woman in STEM
    1. I decided to put a pre-determined list of names in a txt file since I couldn’t find a good RSS feed or other such list of women in STEM
  2. Get info on the woman from Wikipedia
  3. Get picture of the woman from Wikipedia
  4. Add Wikipedia information to the new tab page
  5. Add some sort of backup option if the user is offline or Wikipedia doesn’t work
  6. Format the page so it looks pretty!

Using the Wikipedia API

I decided to tackle the info from Wikipedia first.  This was, in my mind, the meat of the program and so it was important to get it working.

To do this, I knew I would need to get a JSON object from Wikipedia.  JSON (JavaScript Object Notation) is basically an easily readable bundle of information from a website.

To get a JSON object, you need to request it.  One way to do this is to use JQuery to request a JSON object from an API.

Side note: We had used JQuery in CS50, so I understood the basic concepts, but I hadn’t sat down and read the documentation.  Like I said in Part I, I like getting context then going back for the foundation.  For me, it’s much easier to write a program using JQuery then go back and read the documentation than to read the documentation top to bottom and sit down to write a program.

CS50 is set up in to facilitate that style of learning.  They give you serious training wheels so you don’t really need to understand what you’re writing.  It’s up to you to follow up and read documentation to truly understand what you’re doing.

Back to my project: I started looking into whether Wikipedia had an API and found this page.  I also found this page about parsing JSON responses from JQuery and this one about Wikipedia extracts.  I used the URL from the Wikipedia extract page and some of the code from the parsing JSON page to put together a first working version of my javascript code.  A screenshot of my first successful grab of Wikipedia info below!

Screen Shot 2017-04-14 at 9.59.41 AM.png

link to v1 js code on Github

Seeing the words appear on the page was IMMENSELY satisfying, but I was a long way from a launch ready extension.

Making my JSON request dynamic

My next step to make my JSON request dynamic.  In v1, I had hard-coded in a single URL that retrieved the summary info for the wikipedia page for “Weather.”  I looked around for how I might build the wikipedia request and had an a-ha moment after re-reading the JQuery documentation on .getJSON.

I realized that “Data that is sent to the server is appended to the URL as a query string.”  This meant I could pass a number of parameters into “data” as an object, and the output would be url.com?A=B&X=Y for the object {A: B, X: Y}.

So I looked again at my wikipedia URL and translated the query string into a data object like so:

https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=Weather&redirects=1
{ "format" : "json",
  "action" : "query"
  // etc etc etc
}

You’ll notice that the empty parameters like exintro=& are linked to empty strings in my data object like this –> {“exintro” : “”}

I also (later on) read on the Wikipedia API documentation page that you can (and should) pass multiple variables to the same parameter using the pipe symbol “|”.

For example, prop=extracts&prop=pageimages became:

{ "prop" : "extracts|pageimages" }

My final query looked like this:

 var wikiAPI = "https://en.wikipedia.org/w/api.php?";
 var test = $.getJSON( wikiAPI, {
 format: "json",
 action: "query",
 prop: "extracts|pageimages",
 exintro: "",        // this is to get just the intro paragraph
 titles: fem,        // variable with name of the random woman to lookup
 piprop: "original", // this is to get the image
 redirects: "true"   // this returns the final page after any redirects

Loading in my ladies

Now that that was done I had to figure out how to load in a list of ladies, and retrieve a random lady to look up.  In CS50, we had used separate text files to hold long lists so I decided that’s what I would do.  I created a .txt file and manually typed in a list of women in STEM.  (The list is basically a mashup of various buzzfeed/wikipedia/other lists, with some women who’s bios are super short removed, so suggestions/edits welcome!).

To do this, I would need to use a GET request.  This is exactly what I had done with the Wikipedia request, so this would be easy!  Also, since my file was local and I didn’t need to send any additional parameters, my GET request was VERY straightforward.  Just $.get(filename).  See below for my code:

 $.get("radfems.txt")
   .done(function(femlist) {
   var femlist = femlist.split(/[\n,]+/);
   console.log("getFemList success");
   randomFem(femlist, callback);
   })
   .fail(function() {
   console.log("getFemList error");
   })
   .always(function() {
   console.log("getFemList complete");
   })

You’ll see there are no additional parameters passed to my GET request outside of the filename.

The next piece was to parse the returned object.  Basically, I got back a big string, and I wanted to split it into an array of names.  Unfortunately, I had formatted my text file so that each woman was separated by both a comma and a newline.  I didn’t want to go back and reformat, so I decided to use a regular expression (regex) to match the comma+newline pattern.

Using an online regex tester, I tested out my regex and got back an array of my women’s names.  Success!

Retrieving a name

Now that I had my list of women loaded in, I needed a way to get a random name to then lookup in Wikipedia.  This part was very straightforward.  I used the built in Math.random() utility to generate a random number, and then used that number as the index to get a woman from my array.

var random = Math.floor((Math.random() * femlist.length));
 var fem = femlist[random];
 while (fem == "") {
 fem = femlist[random];
 };
 getFemInfo(fem, callback);

Local/backup image

The last piece of the puzzle was having some sort of backup image or text for when the user was offline.  I googled around and found this women in STEM bio series jewelry designer aubergdesigns had created.  I pulled a few of these images to use as my backups.

I put these images into their own “imgs” folder, and then linked to a random image in that local folder whenever the Wikipedia request failed.

 var test = $.getJSON( wikiAPI, {
    .... // this part is shown above...trying to keep it concise!
 })

 .done(function(test) {
   .... // this part is really long, see github for code
.fail(function() {
 console.log("getFemInfo error");
 getLocalFem(callback);
 })

// LOCAL FILE RETRIEVAL FUNCTION
var getLocalFem = function(callback) {
 console.log("getLocalFem");
 var random = Math.floor((Math.random() * 3));

 var img = "/imgs/" + random + ".jpg";
 callback("", "", img, "");
}

Callback functions

Up until this point, I had been using a global object container (more here) to store a number of variables – such as the name of the woman I was looking up and the Wikipedia page ID – that I wanted to access from several functions.

However, I had read that it’s generally discouraged to use global variables.  I think using a global object container is less discouraged, but still I wanted to see if there was another way.

Much googling led me to the concept of callback functions.  I wanted certain functions not to execute until the data they needed was ready, so I thought it made sense to use callback functions.  Essentially, a callback function is a function that is passed to another function as an argument.  The callback function is then called/executed WITHIN the other function.

I like examples so I googled around some more and found this code for displaying a quote in each new tab which helped me to understand how callbacks are used in the wild.  (I often find it helpful to look at longer pieces of code in Github, as examples in documentation are often really short snippets and I find it helpful to see more context.)

I then structured my code similarly to the code from csoni111.

  1. updateFem: I called a main updateFem() function once my document (the new tab) loaded.  That function contained the code to actually place my content on the page.
  2. getFemList: In order to be able to place content, I needed to get content.  I passed the function for placing content (my callback) to the next function which loaded the list of fems from my text file.
  3. randomFem: Once the list was loaded, I passed my callback (function to place content) onto the next function – the one that got a random name.
  4. getFemInfo: After I had a random name, I passed my callback over to the next function to get information from Wikipedia.
    1. callback: If I was able to successfully retrieve info from Wikipedia, I passed the info to the callback function to execute.
    2. getLocalFem –> callback: If I was unsuccessful (e.g. if I was offline when I opened a new tab), I retrieved a backup image from a local directory and passed this to the callback function to execute.

The callback was the very last function I wanted to execute.  I thought of it as an empty box with a bunch of gears inside that was getting handed from function to function.  Once all the other functions had executed, the final function handed all the necessary parts to my callback function and told the callback function to execute.

So that was the info retrieval side of things.  Read on to Part III to learn about how I displayed my content!

Coding & learning with context

Hello, world!

I’m incredibly proud of this next project.  It captures perfectly the goal of Zeynep and my quitting quitting project.

I started taking CS50x in December of 2015.  At the time, I thought I could blow through the class in a month if I plugged away at it for 10 hours a day.  I had big plans of taking additional math and CS classes after CS50x and possibly going back to school for a master’s in CS.  What, a master’s in CS?!?  But you majored in Art and International Relations!  Yes, dear reader.  I had the exact same thought.

So then, why a master’s in CS?  I wanted a career change.  I hated my job (project management) and I wanted to make things.  I had taken a Udacity Intro to Python course back in 2011 and loved it.  But I didn’t really know where to go from there.  I ended up writing a bunch of Google Apps Scripts since they were easy to get started with, and useful for my job.  But I wasn’t really learning much else.  I felt I had hit a wall and wanted to be back in a school-like environment.

I spent HOURS reading through reddit and quora blogs about going back for a second bachelor’s in CS, or going to a coding bootcamp.  The consensus seemed to be a second bachelor’s was a waste of money and a bootcamp wasn’t rigorous enough.  Instead, most people suggested taking the core classes on your own and applying directly for a master’s program.  So that’s what I was doing, or so I thought.

My biggest problem, at least in the last few years, has been split attention.  There are SO MANY projects I want to do and not nearly enough time to do them all.  Instead of picking one things and diving into it, I would start down one path, get frustrated that I wasn’t making progress fast enough, and then switch to something else.  The end result was that I got nothing done.

The problem with this approach was that I was a beginner at a lot of the things I wanted to do.  It’s like wanting to play Beethoven’s Symphony #5 on the piano, but not knowing how to play the piano.  You have two options.

  1. Watch a bunch of YouTube tutorials of people playing Symphony #5 and copy their finger movements exactly.  Eventually, you’ll be able to play that one piano piece, but nothing else.  You won’t have really learned to play the piano.  HOWEVER, with every note you hit you could hear Symphony #5 somewhere in there, struggling to get out which kept up your enthusiasm.  Also, you will have learned a LOT about piano playing (though you may not realize it) which will serve as a good foundation to learn to play the piano later.
  2. Start with the basics (reading musical notes, practicing scales) and work your way up to playing Symphony #5.  You’ll actually learn to play the piano, but during the learning process you won’t be playing Symphony #5.  That means you’ll need to keep reminding yourself what all that boring scale playing is leading to.  However, you’ve built a strong foundation about music playing that you can apply beyond Symphony #5.

That’s what it was like for me with programming.  The Udacity course was like starting with method #2, but stopping with scales.  After the course was done, I had no idea how to apply anything I learned to the projects I wanted to create.  I didn’t know how to go from playing scales to playing a real piece of music.

So I shifted to method #1.  I dove into a bunch of Apps Scripts projects, frankenstein-ing programs together using other people’s code, tutorials, and the Apps Scripts documentation.  I didn’t really get half the errors I was seeing.  I didn’t really understand why things worked when they did, but I could generally get things working.

However, this was deeply unsatisfying.  Which is why I came to CS50.  I wanted to be back in a school-like environment.  To learn things the “right way.”

Taking CS50 after having spent two years frankenstein-ing code was GREAT.  Going with method #1 gave me context so that when I saw lessons in CS50, I could think “Oooooohhh, THAT’S why that works” instead of thinking, “Ok, I get the theory now how do I apply it?”  I had already applied it and now I was backing into the theory.

But back to December 2014.  Taking CS50 was great, but it was hard.  I was itching to get started on projects and the thought of having to take 11 weeks of courses was overwhelming.  I got frustrated that I wasn’t making progress fast enough and quit.

This is totally counterintuitive and I know it, but I still do it all the time.  I think it’s going to take too long to learn something, so I quit.  But then 11 weeks later I’m sitting there thinking, why didn’t I just invest in this 11 weeks ago?  The problem?  Learning scales is boooring and I wanted to play the Symphony NOW!

Anyway, I quit the course in Jan 2015.  There was the issue that I wasn’t progressing fast enough coupled with my life getting busy.  I was also taking a sci-fi writing course at the time which I really threw myself into.  It was my 10 hour a day project.  On top of that, I was applying to new jobs.  I started a new job in April 2015 and just got distracted getting up to speed and working hard at the new gig.

But the new job was still in project management so, inevitably, I begin to feel the itch.  I wanted to *make* things.  So I picked the course back up Dec 2016 and really got to it in Feb/March 2017.  I finished the course last week (April 2017) and it was HARD.

I admit there were a few additional stop and starts in there, though not quite as long, and I skipped two problem sets, but I got through it!

My next post is about my final project!  Read on here…