My Roadmap for Learning Web Development

I have been seriously studying computer programming since about March of 2014. Before that, I had dipped my toes in a few times here and there. I am very comfortable as a power user. I use computers all day long at my job, and I’ve taken on a basic tech support role there. I have blogged extensively, and I knew the basics of HTML and CSS. I had tried a couple of times to learn javascript, enough to write a few simple functions. But I could never really push on through.

In early 2014 some time, I began seriously thinking about computer programming and web design. I signed up for Udacity and took a few of their free courses. I enjoyed it quite a bit, but I quickly found myself overwhelmed with the sheer mass of things to learn. Should I learn more advanced mathematics? How computers are built? Statistics? And so many different languages: PHP? Ruby? Python? C? Java? Javascript? SQL? VBA? Should I concentrate on web development? Data Science? And which online resource should I use? Udacity? Coursera? Khan academy?

I consider myself very lucky to have found The Odin Project. This is a free online resource that takes you from zero to developer. It gives you a roadmap, starting with a basic understanding of how the web works, to the main tools you use as a web developer (github, the command line, text editors), on to HTML and CSS, then to basic programming concepts with Javascript. It then moves to the back end, focusing on Ruby and Ruby on Rails. There’s a dash of computer science in there, then back to more advanced HTML, CSS, and Javascript. Finally, it gives you a roadmap for the job search!

It has not been easy, or fast. I have been working steadily since July 2014. At the present (December 2014) I am about 60% through the Ruby section, with sections on Ruby on Rails, HTML, and Javascript left to go.

There have been a few small detours along the way. Because The Odin Project no longer appears to be actively curated or moderated, it has been hard to find mentors. I was lucky enough to find a few guys who are at a similar place in the project to form a study group. We decided as a group to work through Zed Shaw’s excellent book, Learn Ruby the Hard Way. I finished up to exercise 47, at which point I decided to return my focus to the Odin Project a little more. I plan on finishing the remaining 5 lessons in Shaw’s book eventually.

Lately I have been thinking of where I will go next. And I’m beginning to get a feeling that I need to go deeper into computer science and how computers work. With that feeling comes a bit of that overwhelmed feeling I described before I found The Odin Project, with so many different things to learn and courses to choose from.

I am going to put things here that I plan on returning to. In the meantime, I am going to stick it out with the Odin Project.

  • MIT’s Intro to Computer Science: I have been listening to the lectures when I commute to work or travel. I haven’t taken any look at the problem sets or any other material, but I can understand enough (because of my background with Python and Ruby, and because Drs. Grimson and Guttag are excellent teachers) to make a difference in how I think about programming
  • Coursera’s Algorithms course. I also see that MIT has a course on algorithms. Which course I take will depend on which language I am focusing on when I get to that I guess.
  • Harvard’s CS50: I like the focus on multiple languages. I’m really interested in getting my feet wet with Java and C
  • MIT’s intro to Programming in C and C+: I want to study C because I hear it can make you a better programmer overall. I may not go with MIT’s course, but this looks like a good one, which is usually taught over the course of 4 weeks between semesters.

Ruby, Online:

Books:

I Am Determined to Build a Twitter Bot!

I haven’t figured out the problem with the MicroBlogger tutorial that I’ve been posting about. But I’ve become intrigued by the idea of building a twitter bot.

I went through the Codecademy Twitter API course. It was a nice, very basic introduction. A little googling led me to several more tutorials on building a twitterbot, which I’m posting here for reference.

How to Make an eBooks Bot

Five Steps To Build Your Own Random Non-Sequitur Twitter Bot

Create a Twitter Bot Using Ruby

Do You Know How to Create a Bot in Ruby?

Updating OpenSSL on Windows

My last post was about some problems I ran into with authenticating a twitter spam-bot project, using git bash and the twitter API. I finally figured out how to update Open SSL for my git – I just installed the newest version of Git! I had been using Git for Windows. Installing Git, instead of Git for Windows, updated my SSH version.

After hours of searching for a solution, I was happy to find one. I fired up git and ran ruby micro_blogger.rb, and…

certificate verify failed

Again, certificate verify failed.

I guess it could be that I’m running an older version of ruby? Or maybe something has changed about Twitter’s API. I really have no idea.

This is the frustrating part about learning to code. I am getting confident in my ability to bang out some lines of code that will do what I want. But I spend a lot of time trying to figure out how to make the code work, and many of the tutorials online don’t really address these strange little things that pop up, like the LOAD_PATH not working. I suppose it will get easier eventually.

Meanwhile I think I am going to do Codecademy’s Twitter API course and see if that offers any clues.

Updating OpenSSL on Windows… not so simple

So I figured out the problem in my last post. Then, after getting some things working, I ran into another problem and decided to move on to the next project, creating a Twitter spambot.

Here I ran into a problem with OpenSSL. I googled the problem and discovered a solution. The problem is, the solution doesn’t work for Windows.

I have tried to install a linux virtual machine in the past. I spent hours on it and could never get it to work quite right. I could also partition my drive and install linux on my desktop, I suppose. Again, it seems like a lot of work.

xkcd - talk to your kids about linux

I will keep looking. If anyone reading has any solutions, let me know!

LOAD_PATH problem solved, another problem pops up

I’ve been working on the hangman project at the Odin Project.

I had a basic working program. I decided to break it up into some different files to get a better understanding of how classes and files interact with each other.

I had a lot of trouble with getting the dictionary to work once I did this. The game loads a word from a text file containing a long list of random words. Once I put the game into a couple different files, I couldn’t get the text file to load anymore. I was finally able to figure out a solution, although I still don’t completely understand what happened, once I read this blog post.

It seems that once a program has been executed, the file path for that program is set. So when I changed the file structure, the program was still looking for the dictionary (the “5desk.txt” file) in the same old place and couldn’t find it. This is strange, because I didn’t move the dictionary file, just split the ruby code into two different files. I added the following to my code:

File.join(File.expand_path(File.dirname(__FILE__)), "..", "5desk.txt")

and now things work.

I am still not 100% clear on how this works (more like 60%), so if any readers have reading materials or comments that can help me understand, please share!

Once I got the dictionary to work, I had to change the ruby code a little to reference the right instance variables. As it currently stands, the program runs, but the turns are borked. Instead of the turns variable counting up from 0, I can only run one game round, the turns variable gets set to the length of the word, and the program exits. I have pushed the code to github here, and I’ll copy some of it below since the github code will change in the future.

play.rb:

File.join(File.expand_path(File.dirname(__FILE__)), "..", "5desk.txt")
require_relative "lib/hangman.rb"
require_relative "lib/game_engine.rb"

play = GameEngine.new
play.play_game

lib/game_engine.rb:

require_relative "hangman.rb"

class GameEngine

def initialize
@game = Game.new
@turns = 0
@score = 0
end

attr_accessor :turns
attr_accessor :score
attr_accessor :game

def take_guess
puts "Guess a letter!"
print ">"
input = gets.chomp.downcase
@game.guesses.push(input)
i = 0
while i <= @game.word.length
if input == @game.word[i]
puts "The word contains #{input}!"
@game.word_board[i] = input
i += 1
else
i += 1
@turns += 1
end
end
print "#{@game.word_board.join} Guesses: #{@game.guesses.join} "
end

def play_game
print @game.word.join+"n"
print @game.word_board.join
while @turns < @game.word.length
take_guess
puts " Turn #{@turns}"
end
end
#end class
end

lib/hangman.rb:
require_relative "game_engine.rb"

puts "Hangman initialized"

class Game

def initialize
puts "New game initialized"
@word = pick_random.downcase.split(//).slice(0..-2)
@word_board = []
@guesses = []
create_word_board
end

attr_accessor :word_board
attr_accessor :word
attr_accessor :guesses

def pick_random
chosen_line = nil
File.foreach("5desk.txt").each_with_index do |line, number|
chosen_line = line if rand < 1.0/(number+1)
end
return chosen_line
end

def create_word_board
@word.length.times do
@word_board.push("_ ")
end
end
end

Variables and arrays

In IRB, type the following:


a = 8
b = a
puts a
=> 8
puts b
=> 8

Make sense?

Now try this:


a = 9
puts a
=> 9
puts b
=> 8

You can see that a has changed, but b has not. And this makes sense. b was assigned the value of a, not to a itself.

This is pretty close to the basic explanation I have gotten from every basic ruby textbook I have read so far. Chris Pine’s Learn to Program shows almost exactly this example.

Here’s another example:


a = "my string"
b = a
a = a + " this is"
puts a
=>"my string this is"
puts b
=>"my string"

Seems consistent, right?

So, imagine my surprise when I ran a bit of code something like this…


class MyArray
def initialize
@arry = [1,2,3]
puts "initialized"
end

attr_reader :arry

def manipulate_array
temp_arry = @arry
2.times do
temp_arry.pop
end
puts temp_arry
puts @arry
end

end

new_arry = MyArray.new
new_arry.manipulate_array

…and found that the function was emptying out both arrays!

It makes even less sense to me because I created an attr_reader for @arry. I thought this would make @arry “read only” so to speak.

I posted about it on stack overflow, and I kind of know what’s going on, but I still don’t really grok it.