Categories
Dev Bootcamp

Improperly-Used Variable Scopes are No Vacation

What Is Scope?

Scope refers to the reach or visibility of variables. In the object-oriented world, scope is very important. There are five types of variables/constant, each with varying levels of scope.

The different variable scopes are (in order of highest to lowest level of scope):

  • global variables
  • constants
  • class variables
  • instance variables
  • local variables

In objected-oriented design, you want classes and methods to have only single responsibilities. We don’t want to expose everything to everything. It would be a tangled mess to have all variables and methods available to all objects. This also creates a lot of dependencies. When you change one part of the code, you may need to change ten other parts of the code if they are all depending on the code that you are changing, creating a rippling effect. Using correct variable scopes to only expose what is needed helps reduce this problem.

Besides restricting access to other components of the code, scopes also keep the name space open. Since the variable is limited to its scope and is non-existent outside of it, you don’t have to worry about creating a variable with the same name and accidentally overwriting the previous assignment.

Let’s talk about each variable scope in more detail

Global Variables

Global variables have a global scope. They are available anywhere in the program. It is defined and called with a $ in front of the name (i.e. $global_variable = "I am a global variable").

Try not to use global variables unless it is absolutely necessary. There is almost always a way to substitute using global variables with something else. It is used often in functional programming, but is counter-intuitive to object-oriented programming (OOP) because it is doing exactly what OOP is designed to get rid of. Relying on global variables causes the program to become less flexible and harder to make changes to in the future. In OOP, each object should only expose what is needed; nothing more and nothing less (only expose what it does, not how it does it).

Constants

Constants also have a global scope. They start with a capital letter. The Ruby convention is to write it with in all caps and underscore (i.e. CONSTANT = "I am a constant"). If they are called from self, you only need to write the name of the constant, like local variables and methods. If you are calling from outside of self, you can still access it if you know the path of the block that defined the constant and :: (i.e. Math::PI).

Constants are not meant to be changed, but Ruby will allow it. If you choose to change a constant, Ruby will give you a warning and then make the change right afterwards.

Local Variables

Let’s jump to local variables before we talk about class and instance variables. If you’ve played with Ruby, then you’re probably already familiar with it. Local variables have a local scope and they start with a lowercase letter (i.e. local_variable = "I am a local variable"). Local variables are the most often used variables and are limited to the specific block it’s in and the blocks inside that block. They can’t be access from anywhere outside of the block.

For example:

class Destination
  def dest_1
    x = "Barcelona"
    puts x
  end
  def dest_2
    puts x
  end
end

trip = Destination.new 
trip.dest_1 # => "Barcelona"
trip.dest_2 # => undefined local variable or method `x' for #<Destination:0x007fe284058ae8> (NameError)

Or:

trip = ["Barcelona","Rome","Amsterdam"]
trip.each { |city| x = city; print x } # => BarcelonaRomeAmsterdam
print x # => undefined local variable or method `x' for main:Object (NameError)

As you can see, when the local variable is called outside of its block (in the first example, the Destination#dest_1 method block, and in the second example, the .each iterator block), it will create an error. Since the variable is out of scope, it does not exist in the block from which it is called upon.

Now, lets look at this example:

trip = ["Barcelona","Rome","Amsterdam"]
x = []
trip.each { |city| x = city; print x } # => "BarcelonaRomeAmsterdam"
p x # => "Amsterdam"

Something interested happens here. Notice how the last line now prints "Amsterdam", even though that was assigned inside the .each iterator block. Since x was first defined outside of the .each iterator block, the scope of the variable has changed. Remember what I said earlier: the scope of a local variable is limited to its block and the blocks within that block.

Instance Variables

Instance variables are only accessible to each specific instance. They begin with a @ symbol in front of the name. They are written inside instance methods and can be shared by all instance methods in that class. Since the scope of instance variables are restricted to each instance, different instances can have different values assigned to these variables.

Take this, for example:

class Destination
  def initialize(city)
    @city = city
  end
  def print_city
    puts @city
  end
end

trip_1 = Destination.new("Barcelona") 
trip_2 = Destination.new("Rome")
trip_1.print_city # => "Barcelona"
trip_2.print_city # => "Rome"

There are two things to note here. First, notice how @city is assigned in the Destination#initialize method and the assignment is still available in a different method, Destination#print_city (as evidenced by what the last 2 lines printed). The second thing to note is that @city for trip_1 is different from the @city for trip_2. Instance variables are the second most used variables in Ruby.

Class Variables

Class variables are accessible by the class and all instances of that class, so they have a wider scope than instance variables, but not as much as global variables. These variables have a @@ symbol in front of its name. They are often used if the class or any instance of the class will need to use it.

For example:

class Destination
  @@total_avail_cities = 0
  def initialize(city)
    @city = city
    @@total_avail_cities += 1
  end
  def print_total
    puts @@total_avail_cities
  end
end

trip_1 = Destination.new("Barcelona")
trip_1.print_total # => 1

trip_2 = Destination.new("Rome")
trip_2.print_total # => 2

Every time a new destination is initialized, it adds a count to @@total_avail_cities. Notice that even though trip_2 is a separate instance from trip_1, it still print 2.

Class variables are also avoided unless it is necessary. Similarly to global variables, not realizing its scope can be detrimental to your problem.

Here is an example:

class Destination
  def initialize(city)
    @@city = city
  end
  def print_city
    puts @@city
  end
end

trip_1 = Destination.new("Barcelona")
trip_2 = Destination.new("Rome")
trip_1.print_city # => "Rome"
trip_2.print_city# => "Rome"

Notice how both calls to print @@city returned "Rome". That is because the second instance changed the value of @@city when it was initialized, which carries over to all instances in that class. Be careful when using class variables and only use them when absolutely necessary.

Summary

Ruby has different types of variables that have varying levels of scope. The bigger the scope, the more careful you should be when using it. In object-oriented design, you only want what is absolutely needed to be accessible by others to make your program work, so don’t expose anything in an object that isn’t needed by others. Keep the scope in mind and choose which variables to use accordingly.

This blog has been initially published on tonymai.github.io.

Categories
Dev Bootcamp

How Pair Programming and Great Feedback Helped Guide My Learning

dbc-logoI’m 4 weeks and 3 days into Dev Bootcamp’s Phase 0 virtual prep program (halfway), and I must say, “wow!” The purpose of Phase 0 is to springboard the learning experience and to provide a foundation for programming. Since this phase of the program is remote, I was worried that I would be doing this all by myself, that I would have nowhere to go when I have questions, and that I would feel out of the loop and fall behind. I’ve taken online classes before and the experiences were mediocre at best. It was mostly self-learning and group discussions were not very interactive.

To my surprise, even though DBC’s Phase 0 is remote, not once did I feel alone in this process. Dev Bootcamp created an immersive virtual environment that spans across several platforms. There are fellow classmates almost instantaneously answering the questions I post on Google+, giving feedback on my blogs via Twitter, reviewing my code and submitting issues on GitHub, pair programming with me via Hangout and Skype, and giving me actionable feedback on Socrates (an internal anonymous feedback system). So far, this virtual phase feels more immersive than most of the classes I took when I was in college. I am truly impressed.

pair-programmingOne of the core features of Phase 0 is pair programming. Pair programming is an agile software development technique in which two programmers working together on one workstation. The driver writes code while the navigator guides and review. DBC requires us to pair program at least 2-3 times a week. In these 4 and a half weeks, I have learned how to share my thought process and work effectively with a peer, as both a driver and a navigator.

It was definitely a new experience to pair program. I’ve taken introduction classes to Java, Python, and other programming languages before, and for the most part, I just worked on the challenges on my own. Pair programming forced me to communicate with my peer. I had to adjust the way I work at first. It helped me learn how to express my thought process (which makes sure I know what I’m talking about myself), as well as listen to other methods and ways to solve the problem.

This has been really rewarding. There are times when I over engineer a solution to the problem, but my peer knows of a better and more efficient way to solve it. There are times when I am stuck and don’t understand why something is happening, but my peer does and is there to walk me through it. Of course, there are also times when my peer is not on the same page as me and I would need to explain what is going on, which can make the pairing session a little difficult. It was frustrating at first, but I learned that by teaching, I am also learning and reinforcing my knowledge on the topic as well. Just seeing how others think and different ways to accomplish the same goal is already amazing on its own.

sadWith all these pair programming sessions also comes a lot of feedback, which was overwhelming at first. After each session, we submit anonymous feedback to each other through DBC’s Feedbackinator. Each piece of feedback goes through a peer rating system and doesn’t show up on your dashboard until enough peers agree that it is specific, actionable, and kind (A.S.K.). It is important to note that kind does not mean nice. If you’re saying something just to be nice, but it is not true, it is not kind.

Reading through my feedback, there were a lot of positive feedback, as well as some constructive ones. At first, I was taken aback when I saw these constructive ones. I read them as negative feedback and felt as if I was being attacked. But after reading through them again, I can see it from their point-of-view and realized that they were only being specific, actionable, and most importantly, kind. It is okay to feel vulnerable. They are being truthful in what they observed when working with me, and I can learn from it and better myself. I learned that I am very focused, but sometimes I can get too wrapped up and make the pairing session feel too professional and uptight. I will be more conscious of my pairing style and spend some extra time in the beginning of the session checking in and getting to know the person on a personal level.

Writing feedback to others was harder than I thought. It required me to actively think and make sure it is specific and actionable. The more feedback I give, the easier it becomes. Overall, I think Dev Bootcamp’s use of pairing and feedback to guide our learning is right on the money.

If you have 30 minutes to spare (which is hard to come by these days) and want to learn more on how to give and receive great feedback, take a look at this DBC video:

This blog has been initially published on tonymai.github.io.

Categories
Dev Bootcamp

Ruby Classes, Instances and Inheritance

Launch Your Understanding From 0-60 with Ruby Classes

Just as with any object-oriented programming language, class is an important part of Ruby. Everything in Ruby revolves around objects, and all of these objects belong to a class. Unlike in other languages, where each object can have multiple classes, objects in Ruby can only belong to one class. A class is a structure containing similar properties that each instance in the class share, but each instance can have different characteristics for those properties. Arrays, Hashes, and Strings are all examples of classes!

I threw out a lot of terminology, so let me show you an example:

class SuperCar
  def initialize(make, model, year, horsepower, torque)
    @make = make
    @model = model
    @year = year
    @hp = horsepower
    @tq = torque
  end
  def print_specs
    puts "This #{@year} #{@make} #{@model} has #{@hp} horsepower and #{@tq} lb-ft of torque."
  end
end

car_1 = SuperCar.new('Ferrari','458 Italia',2013,570,398)
car_2 = SuperCar.new('Lamborghini','Aventador',2012,691,508)
car_3 = SuperCar.new('McLaren','MP4-12C',2014,616,443)

There are several pieces of code to look at here. We have a class called SuperCar and three instances called car_1, car_2, and car_3. To define a new class, we began by writing the keyword class and then the constant SuperCar. Note that the constant for a class MUST start with a capitalized letter.

The class SuperCar contains the general structure and functions that each instance of this car has. This means that car_1, car_2, and car_3 each has the variables @make, model, @year, @hp, and @tq; and can use the methods initialize and printer_specs. It is important to note that car_1, car_2, and car_3 are not just limited to just these two methods. There are other ways to add new methods to these objects, which are not covered in this post.

Another thing that you see here are instance variables. They are the “properties” of the class, and each instance of the class has a different set of instance variables (i.e. car_1’s @make is Ferrari while car_2’s @make is Lamborghini). Instance variables can be used anywhere within the instance of the class. In the example, the initialize method stores the 5 parameters from initializing a new SuperCar into 5 instance variable assignments. These instance variables can be used in the print_spec method, as well as any other method you decide to create from within the class.

You’d call an instance method that you’ve created in the new class with the . notation, the same way you’d call an instance method from the built-in classes, such as Integers, Arrays, and Hashes. Here is an example of an instance method call and what is displayed on the console:

car_1.print_spec
>>"This 2013 Ferrari 458 Italia has 570 horsepower and 398 lb-ft of torque."
ar_2.print_spec
>>"This 2012 Lamborghini Aventador has 691 horsepower and 508 lb-ft of torque."

While an object cannot belong to more than one class, a class can be a descendant of another class. Descendant classes inherit all of the instance methods from the ancestor class, as well as the ancestor of the ancestor class, and so on.

For example, a certain super car collector takes a portion of his super cars to the racetracks:

class TrackCar < SuperCar
  def set_laptime=(time)
    @laptime = time
  end
  def get_laptime
    @laptime
  end
end

car_4 = TrackCar.new('Ferrari','458 Italia Speciale',2014,597,398)

Again, we have several pieces of code to look at here. In the first piece, I created a class called TrackCar and used the < notation to specify that TrackCar is a descendant of the SuperCar class. This class has two methods: set_laptime (this is a setter method) and get_laptime (and this is a getter method). A setter method allows you to set an instance variable to a value and a getter method allows you to get the value of an instance variable.

Notice that the set_laptime method looks a little funky. Ruby allows you to use the = notation in instance methods to make calling it look more reader-friendly and consistent with variable assignment conventions (i.e. car_4.set_laptime = 98 as opposed to car_4.set_laptime(98)). There is another shortcut to write setter and getter methods, using attr_ attributes (to learn more about them, you can start here).

In the last piece of the code, I created an instance of TrackCar called car_4. Now, let’s run several methods:

car_4.print_specs
>>"This 2014 Ferrari 458 Italia Speciale has 597 horsepower and 398 lb-ft of torque."
car_4.set_laptime = 98
puts "This car's fastest lap time is #{car_4.return_laptime} seconds."
>>"This car's fastest lap time is 98 seconds."

Notice that the print_specs method works even though it was not written in the TrackCar class. This is because TrackCar is a descendant of SuperCar. Any instance of the class TrackCar can use methods from its ancestor classes. If you do not specify an ancestor class, it will default to the class Object. Object is a descendant of BasicObject, which is at the top of the Ruby class hierarchy. That means that all Ruby classes eventually go up to Object and then BasicObject.

This is a good place to stop. We’ve talked about classes, instances, instance variables, instance methods, and class inheritance. To summarize it all, as tutorialspoint puts it, “A class is essentially a blueprint from which individual objects are created.”

This blog has been initially published on tonymai.github.io.

Categories
Dev Bootcamp

Drug Addiction in the Tech World

“People graduate to doing things that they never thought they would have done.” – Michael Johnson

While doing some research on cultural problems facing the tech world, I found all kinds of issues that are common: women in technology, brogrammers, sexism and sexual harassments, lack of diversity and cultural awareness, lack of respect for public (i.e. Facebook’s mood manipulation experiments), preference of hiring the young and inexperienced, etc. One thing that caught my attention was something that haven’t came up in the news that often; the common use of illicit drugs in Silicon Valley.

This is interesting to me, especially in light of the recent overdose death of an executive at Google, a company that I consider to be an industry leader in the tech world. Forrest Hayes, a Google executive and father of five, was found dead on his yacht in Santa Cruz this past summer. It is not surprising to me that drug abuse is common amongst many in the tech industry, but I don’t hear about it in the news that much, so I decided to do some further research.

Tech workers in the valley are faced with many forces; a fast-paced, overworked environment that values rapid productivity with tight deadlines and intense competition. There is a term called the “10x engineer” (an engineer that is 10x more productive than a 1x engineer) in the startup world. Engineers who are willing to work longer, harder, and produce more capital; engineers who are chasing the high of the win. This, combined with monetary and cultural incentives, leads to tech workers exploring the use of illicit drugs, like Adderall, for performance-enhancing purposes. Adderall is so common in the industry that it is normalized as something that is “at best, a stronger version of caffeine, and at worst, a more socially acceptable alternative to cocaine,” says Cori Johnson

Adderall isn’t the only drug common in the tech industry. Many high-level executives (from companies like Google, Apple, Twitter, Facebook, and Yahoo) are struggling with everything, from cocaine and heroin to black-market painkillers. Detox specialists say that progression up the addiction ladder is predictable. It starts with caffeine, like Red Bulls and Monster energy drinks. When caffeine is not enough, they turn to stimulants, like Adderall, to get amped up, and then depressants, like oxycodone, to take the edge off. Eventually, they would get used to the effects of the pills and then turn to heroin; first smoke/snort, then, as their bodies build up tolerance, inject. “People graduate to doing things that they never thought they would have done,” said Michael Johnson.

Many tech companies do little or no drug testing, and managers look the other way. “They want the results, but they don’t want to know how their employees got the results,” says Steve Albrecht. This is a fundamental culture problem; and it won’t be fixed unless the environment supports it. These problems come from a broken business model that puts results over its employees. The intense competition drives managers to put pressure onto its employees. The tech world has a rampant drug problem and it’s sad to see that it took the death of a high-level executive for the media to bring this problem to the forefront. While I do not see big tech companies or even the numerous funds-strapped startups implement policies to reduce this kind of behavior anytime soon, we have to start somewhere.

Further Reading:

This blog has been initially published on tonymai.github.io.

Categories
Dev Bootcamp

A Tear-Down of the Enumerable map Method

What does map do?

Here is the map method:

map { |item| block }

And here is what it returns:

#=> new_array

Essentially, map is an Enumerable method that runs a code block once for each element of the object and returns a new array of of the results of the block.

If you’re just starting to learn programming, you may be asking, “what does this really mean?” Let me try to break it down.

Enumerable provides collection classes with several searching and sorting methods. Arrays and Hashes are two examples of classes that have Enumerable properties, and therefore, can use Enumerable methods. map is one of those Enumerable methods.

What does it really mean? I work out.

Here is an example senario and code:

benched_weights = [90,140,160,120,165]
benched_weights.map { |wt| wt + 45 } 
#=> [135,185,205,165,210]

One the first line of the code, you’re keeping track of how much weight you are putting onto the barbell when you bench on chest days. You are storing this in an array called benched_weights. On the first day, you put 90lbs on the bar. On the second day, you put 140lbs on the bar. Third day, 160lbs. You had a bad day on the fourth day and only put 120 lbs on the bar. And so forth…

Now, let’s say, you want to see how much weight you are benching in total, including the weight of the barbell itself. The barbell weighs 45lbs. On the second line if the code, you used the map method. You assigned the variable wt in between the pipes as a placeholder for each element in the Array and then a code block that says wt + 45. What the code is doing here is going through each weight that you logged and adding 45 to it.

During the first pass, wt is equal to the first element of the array, which is 90, and then returns wt + 45, which is 135. After the first pass, it loops to the second element, which is 140, and then returns wt + 45, which is 185. Third pass, the wt is 160 and returns wt + 45, which is 205, and so on until it goes through each element in the given array.

When all is said and done, the map method will return all of the values given by the code block in the form of a new Array, which is shown on the third line.

As a side note, you can also use Enumerable#collect interchangeably with #map. They are completely synonymous (i.e. benched_weights.collect { |wt| wt + 45 }.

How does this compare to “each”?

Many beginner’s Ruby books and courses use the each method as an introduction to teach iterators and code blocks. If you are familiar with the Array each method, you’ll notice that the Enumerable map method is very similar to it. Both methods calls the code block once for each element in the object. The key difference between the two methods stop here.

After the each method runs the block for each element, it stops and then returns nil. The map method, on the other hand, stores the results that the code block return for each element into a new array and then return the new array after the method is finished. Using the map method can save you several lines of code if you’re making the each method store the results in a new array. It can also be useful in many other ways.

If you have any questions or what further clarification, please leave a message in the comment box below.

This blog has been initially published on tonymai.github.io.