The SplFixedArray Class

Another type of data structure that is unique to PHP is the SplFixedArray. This is a class that embodies much of the same functionality as an indexed array, but performs slightly different.

Arrays in PHP, while functionally similar to arrays in other languages, like Ruby, more closely resemble hashes, as both indexed and associative arrays both use key => value pairs, where the key can be either an integer or a string. However, SplFixedArrays are not unlike arrays found within Ruby. Their indexes are fixed integers, and their performance is better on a large scale than an associative array.

An SplFixedArray has a fixed size (other arrays in PHP can be any size) that is determined in the instantiation. Below, I’ve instantiated a new SplFixedArray (remember, it’s a class!) and set four of the values.

1
2
3
4
5
$cats = new SplFixedArray(4);
$cats[0] = "Maru";
$cats[1] = "Grumpy Cat";
$cats[2] = "Nala Cat";
$cats[3] = "Chairman Meow";

To increase the size of $cats:

1
$cats->setSize(5);

The value of $cats[4]; will be NULL until it’s set. (Note that setSize(); is a class function.)

The SplFixedArray is a great data structure that is more optimal in some cases, and for the Rubyists who love Ruby arrays, very familiar. :)

Arrays in PHP, Continued

In continuing to learn about arrays and data structures in PHP, I’ve been playing around with a few cool functions.

array_column(); is a handy method in PHP5.5 that returns all of the values of a single column, given the key.

Let’s say I had the following associated array:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$catCelebs = array(
    array(
        'name' => 'Maru',
        'breed' => 'Scottish Fold',
        'age' => 6
    ),
    array(
        'name' => 'Nala Cat',
        'breed' => 'Siamese mix',
        'age' => 3
    ),
    array(
        'name' => 'Lil Bub',
        'breed' => 'Domestic Shorthair',
        'age' => 2
    ),
    array(
        'name' => 'Tardar Sauce',
        'breed' => 'Siamese',
        'age' => 1
    )
);

If I wanted all of the cat’s names, I would write:

1
$catNames = array_column($catCelebs, 'name');

array_key_exists(); is a function that checks if an array contains a given key, returning true or false.

From $catCelebs above, if I wanted to check if age was an included column, I would write:

1
2
3
if (array_key_exists('age', $catCelebs)) {
  echo "We know the ages of the celebrity cats!";
}

Similar to this are two other useful functions that allow you to search arrays: in_array(); searches an array for a value and returns true or false if it exists, and array_search(); looks for a value and returns its key if it exists, and false otherwise.

array_unique();, much like the name suggests, will remove duplicates from a given array, the return of that being a new array. This function does not change the original array, so reassignment would be necessary.

Forms in PHP

Today I continued in my exercise in familiarizing myself with PHP’s syntax. I rewrote an old program I did two months ago in Ruby, a Roman Numerals Converter, drilling in classes, array iterations, and few new methods and tricks (like the end(); method that gives you the last element in an array).

I decided to turn this converter into something interactive, using good ol’ HTML forms. One of the cool things about PHP is that you can get a dynamic website up and going pretty quick, without a framework in place, so making a converter where a user can enter a number and get back the Roman numeral for that was relatively quick and clean. In fact, rendering HTML forms with PHP is not unlike ERB (embedded Ruby).

In a .php file, you set up your HTML as you like, and if your logic isn’t in the file (I think best practices is to keep logic and rendering separate), you be sure to include(); the file you wish to use. Be sure to include(); above where you want to work with it on the page.

I’ll admit that my time in Rails led me to momentarily forget how to write a traditional form. Mine is relatively simple:

1
2
3
4
  <form action="romanconverter.php" method="get">
    Number: <input type="text" name="number">
    <input type="submit" value="convert!">
  </form>

Next comes the rendering of that get request. PHP makes this relatively easy:

1
2
3
4
5
6
7
8
9
10
11
  <?php if (!isset($_GET["number"])): ?>
  <?php elseif (isset($_GET["number"]) && is_numeric($_GET["number"]) && $_GET["number"] >= 1): ?> 
    <p>Your Number: <?php echo htmlentities($_GET["number"], ENT_QUOTES); ?></p>
    <?php
    $myRoman = new Roman($_GET["number"]);
    $mynumber = $myRoman->toRoman();
    ?>
    <p>Roman Number: <?php echo htmlentities($mynumber, ENT_QUOTES); ?> </p>
  <?php else: ?>
    <p>Error! Please enter a valid number.</p>
  <?php endif; ?>

I included some validation on the $_GET to make sure that something is in the input (isset();), the input is a number (is_numeric();), and that it is greater than 0, as the Roman numerals system does not have a zero. Encapsulated is the calling of a new instance of the Roman class, and the calling of a function within that class converts the number (in PHP, the syntax for calling a class function is different than calling a regular one: $myRoman->toRoman();). The <?php ?> brackets around the if, elseif, else, and endif are just one way of embedding PHP into a page (you can instead echo your HTML tags and text within one big PHP block); I think this looks cleaner.

In the lines that render the number, for example: <p>Roman Number: <?php echo htmlentities($mynumber, ENT_QUOTES); ?> </p>, htmlentities(); is a best practices function within PHP that makes sure the dynamic data you’re rendering is escaped and always rendered as HTML. The ENT_QUOTES included in the function’s parameters is a flag that let’s PHP know how to handle quotes: in this case it will convert double and single quotes.

One cool thing about PHP is the $_GET variable; this is called a superglobal array. There is also $_POST, $_REQUEST, $_SERVER, $_ENV, $_SESSION, and $_COOKIE. These superglobal arrays are very similar to params[] found in Ruby on Rails and Sinatra. These arrays are where PHP stores values sent into a script from an HTML from the GET, POST, etc methods. Whereas params[] can hold data from any type of action, the differentiation between get, post, etc gives some added security.

If you want to play with my Roman Numerals Converter, it’s here!

Arrays in PHP

In Ruby, arrays and hashes are two separate types of data structures. Arrays have elements with corresponding indexes, whereas hashes you can set you own key => value pairs. In PHP, arrays and hashes exist, but are not so mutually exclusive. There are two types of arrays, indexed and associative. Indexed arrays, much like their name suggests, are much like Ruby’s arrays, and associative arrays operate much like hashes.

What’s interesting about the value of an indexed array is that it resembles that of an associative array: the keys are automatically assigned for you as an index for the values.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
//an indexed array of cat breeds
$myArray = array("siamese", "scottish fold", "calico", "ragdoll");
/* → array(
  0 => 'siamese',
  1 => 'scottish fold',
  2 => 'calico',
  3 => 'ragdoll'
) */

//an associative array of one cat
$maruCat = array("name" => "Maru", "age" => 6, "breed" => "scottish fold", "country" => "Japanese");
/*  → array(
  'name' => 'Maru',
  'age' => 6,
  'breed' => 'scottish fold',
  'country' => 'Japanese'
) */
?>

Arrays in PHP can also be nested. Below, I’ve taken an exercise we did during the first few weeks at Flatiron that gives a nested array of data about some pigeons ($rawPigeonData) and transforms the structure of it into a more organized list with each pigeon’s name being the key in the associative array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$rawPigeonData = array(
  "color" => array(
    "purple" => array("Theo", "Peter Jr.", "Lucky"),
    "grey" => array("Theo", "Peter Jr.", "Ms .K"),
    "white" => array("Queenie", "Andrew", "Ms .K", "Alex"),
    "brown" => array("Queenie", "Alex")
  ),
  "gender" => array(
    "male" => array("Alex", "Theo", "Peter Jr.", "Andrew", "Lucky"),
    "female" => array("Queenie", "Ms .K")
  ),
  "lives" => array(
    "Subway" => array("Theo", "Queenie"),
    "Central Park" => array("Alex", "Ms .K", "Lucky"),
    "Library" => array("Peter Jr."),
    "City Hall" => array("Andrew")
  )
);
?>

$pigeonList is the new associative array I’m going to create by iterating through $rawPigeonData:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
$pigeonList = array();

foreach ($rawPigeonData as $property => $valueArray) {
  foreach ($valueArray as $value => $pigeonNames) {
    foreach ($pigeonNames as $name) {
      if (isset($pigeonList[$name])) {
        if (isset($pigeonList[$name][$property])) {
          array_push($pigeonList[$name][$property], $value);
        } else {
          $pigeonList[$name][$property] = array($value);
        }
      } else {
        $pigeonList[$name] = array($property => array($value));
      }
    }
  }
}

/* The array looks like this once it's structured:
 → array(
  'Theo' => array(
    'color' => array(
      0 => 'purple',
      1 => 'grey'
    ),
    'gender' => array(
      0 => 'male'
    ),
    'lives' => array(
      0 => 'Subway'
    )
  ),
  'Peter Jr.' => array(
    'color' => array(
      0 => 'purple',
      1 => 'grey'
    ),
    'gender' => array(
      0 => 'male'
    ),
    'lives' => array(
      0 => 'Library'
    )
  ),
  'Lucky' => array(
    'color' => array(
      0 => 'purple'
    ),
    'gender' => array(
      0 => 'male'
    ),
    'lives' => array(
      0 => 'Central Park'
    )
  ),
  'Ms .K' => array(
    'color' => array(
      0 => 'grey',
      1 => 'white'
    ),
    'gender' => array(
      0 => 'female'
    ),
    'lives' => array(
      0 => 'Central Park'
    )
  ),
  'Queenie' => array(
    'color' => array(
      0 => 'white',
      1 => 'brown'
    ),
    'gender' => array(
      0 => 'female'
    ),
    'lives' => array(
      0 => 'Subway'
    )
  ),
  'Andrew' => array(
    'color' => array(
      0 => 'white'
    ),
    'gender' => array(
      0 => 'male'
    ),
    'lives' => array(
      0 => 'City Hall'
    )
  ),
  'Alex' => array(
    'color' => array(
      0 => 'white',
      1 => 'brown'
    ),
    'gender' => array(
      0 => 'male'
    ),
    'lives' => array(
      0 => 'Central Park'
    )
  )
)
*/
?>

Adventures in PHP

LAF (“Life after Flatiron”) has been a mixture of emotions, but has primarily meant that I’m exploring new technologies, languages and stacks. I’m currently learning PHP, among other things, for my LAF job. I’m finding that PHP isn’t very different from Ruby; they’re both scripting languages, so logically very similar. Problems I’m familiar with in Ruby can be easily solved in PHP, just with a different syntax.

I happily breezed through Codecademy’s PHP Track, at a pace that made me feel quite pleased with myself. :) Three months ago, the Ruby Track took more than twice as long to go through.

Once I became familiar with the basic syntax of PHP, I decided to expand my learning by writing some simple programs that I had previously done in Ruby.

First, naturally, was FizzBuzz, written procedurally. For my own clarity and practice, I pushed the fizzes, buzzes, and fizzbuzzes into an array:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
  function fizzbuzz() {
    $myFizzBuzzes = array();
    foreach (range(1, 50) as $num) {
      if ($num % 3 == 0 && $num % 5 == 0){
        array_push($myFizzBuzzes, "FIZZBUZZ");
      } elseif ($num % 3 == 0) {
        array_push($myFizzBuzzes, "fizz");
      } elseif ($num % 5 == 0) {
        array_push($myFizzBuzzes, "buzz");
      }
    }
    return $myFizzBuzzes;
  }
?>

Next, practicing switch statements (like case statements in Ruby), I wrote a vowel checker program. I included some syntactic sugar with the endswitch;:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
  function isVowel($letter) {
    switch(strtolower($letter)):
      case "a":
      case "e":
      case "i":
      case "o":
      case "u":
        return "'{$letter}' is a vowel.";
        break;
      default:
        return "'{$letter}' is not a vowel.";
    endswitch;
  }

  echo isVowel("A");
?>

As a fan of object orientation (being an organizational freak, I guess it makes sense that I would love classes), I created a Triangle class which will return the type of triangle, given the sides. Additionally, I tried my hand at some Exception throwing, which throws an error if the sides do not make a valid triangle. Exceptions, like in Ruby, are classes that your custom class can inherit from.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
  class TriangleError extends Exception {}

  class Triangle {
    public $side1;
    public $side2;
    public $side3;

    public function __construct($side1, $side2, $side3) {
      $this->side1 = $side1;
      $this->side2 = $side2;
      $this->side3 = $side3;
      $this->validate();
    }

    public function validate() {
      if ($this->side1 <= 0 || $this->side2 <= 0 || $this->side3 <= 0) {
        throw new TriangleError("error; not valid triangle");
      } elseif ($this->side1 + $this->side2 <= $this->side3 ||
    $this->side1 + $this->side3 <= $this->side2 || $this->side2 + $this->side3 <= $this->side1) {
        throw new TriangleError("error; not valid triangle");
      }
    }

    public function kind() {
      if ($this->side1 == $this->side2 && $this->side2 == $this->side3) {
        return "equilateral";
      } elseif ($this->side1 == $this->side2 || $this->side2 == $this->side3 || $this->side1 == $this->side3) {
        return "isosceles";
      } else {
        return "scalene";
      }
    }
  }

  $myTriangle = new Triangle(6, -2, 7);
  echo $myTriangle->kind();
 ?>

Thinking About Skills

I feel that one of the main challenges I had with of doing liberal arts in college is feeling that given the breadth of my learning, I always felt that my skillset wasn’t easily quantifiable. I remember first seriously writing a resume around sophomore year, having attended a Career Development workshop on the topic. I had just declared my major, Anthropology, and I was applying for an internship at the American Museum of Natural History. Part of writing my first resume, given that my only experience was my high school job at the supermarket, was coming up with a list of skills I had.

I remember writing things like: excellent communication, organized, hardworking. Given my lack of experience, this was all I could muster. But these aren’t necessarily skills, but more like qualities; as in, these are not what I’m capable of, but what I am. Throughout my time in college, and a little while after, this skills section of my resume changed minimally. I added a few things like proficient in Microsoft Office, the ability to work well with others and independently, and 80 WPM, but I still lacked definable skills, albeit I had more experience.

I learned quite a bit studying Anthropology and having taking many different courses, and I don’t regret it for a second that I got to spend 4 years critically engaged in ideas I find fascinating, engaging, and relevant. Still, by senior year of college, I was aware, intrinsically, that I didn’t really have many concrete skills aside from writing and critical thinking. Maybe recent graduates don’t yet, which is expected, but I also didn’t have a good idea of how to really get “skills” to compete in the job market (and, for that matter, what type of job I wanted and that would be fulfilling to me).

Here, more than halfway though our course, I’m finding myself looking back on this period of my life with a mixture of emotions. For one, I think of my life in two phases: before starting Flatiron, and the possibilities beyond. I think about it this way for a number of awesome reasons too long to list in one post, but for one, I feel for the first time that I have real skills that I can point to and say that I know.

Before Flatiron, I had thought I wanted to go to graduate school for anthropology, given my love of studying it in undergrad. Part of my desire to go was from a lack of not knowing what I was capable of doing beyond that, as well as sticking with things I’m good at, and not taking risks in learning things outside of my comfort zone. At the same time, I’ve always loved technology and the internet and thinking about what that all means for our world and society, yet I never thought myself capable of actually building things that would contribute to that. I thought it was magic, and I thought I was only inclined to liberal arts, as a critical thinker, and not a quantitatively capable. I felt like I was taught, implicitly, that studying liberal arts meant I would not be capable of learning a hard skill like programming. Part of that is because these skills are not taught in a traditional academic setting. Part of that as well is attending a women’s college and not knowing many people, especially women, in technology.

It’s hard for me to articulate the feeling of being so utterly wrong about my capabilities, yet so happy about that at the same time. Finishing week 9 out of 12 of our semester, I feel elated by the fact that I have a skillset that I can objectively speak about with enthusiasm and excitement. Further, I can point to things that I’ve made, that can be used by anyone (this week I helped build GuideMe). I’m also consistently inspired to learn more about new topics and to code code code all the time. To enter states of complete flow everyday is invigorating, and to think I can do this for a career is actually magical.

JavaScript vs. Ruby

After beginning JavaScript last Thursday, I’ve been thinking about the differences between this language and Ruby, whom I’ve gotten quite intimate with these last 7 weeks. Coming from Ruby, JavaScript isn’t all that different, yet the syntax is unfamiliar and some logic differs slightly.

typeof vs class

To determine what type of value something is (a number, a fixnum, a string, an Object, an array, etc), in JavaScript you write typeof and then then the object; in Ruby, you append .class to the end of the object.

=== vs ==

In JavaScript, the triple equals sign helps determine if two objects are the same exact object (having the same typeof and the same value). For example: 3 === 3 returns true In Ruby, that is accomplished through the double equals. (3 == 3 returns true)

JavaScript has its own double equals, which shouldn’t be confused with Ruby’s: double equals in JavaScript only determines if the values match. For example: "3" == 3 returns true

parseInt(); vs .to_i

In JavaScript, to turn a string “10” into the integer 10, you write parseInt("10");. In Ruby, you write "10".in_i.

Incrementing and Decrementing

To increment or decrement by 1 in JavaScript, you can write ++ or -- (for example, var x = 2; x++; returns 3. In Ruby, it’s x += 1. You can write this as well in JavaScript (which is useful if you want to increment with numbers other than 1), however, you have the handy ++ and -- as well.

Functions

Functions in JavaScript are the same as methods in Ruby. The syntax of declaring a function vs. declaring a method is slightly different. In Ruby, it’s :

1
2
3
def hello
  puts "hello"
end

In JavaScript, the same logic can be written as:

1
2
3
function hello() {
  console.log("hello");
}

Objects

Objects (similar to Ruby’s hash), declared as variables, are a way of organizing key/value pairs. For example, var cat = {color: "grey", name: "Spot", age: "12"}; To access the value of an associated key, you can call that on the variable name: cat.name returns "Spot". You can also easily delete a key/value pair by writing delete cat.name. To declare a new key/value pair, write: cat.gender = "male";. This appends this new data point to the end of the Object.

Arrays

Both Ruby and JavaScript have Arrays, which are more of less logically the same; however, the Object Array functions (JavaScript) and the Class Array methods (Ruby) have different syntax. For example, to find the index of an element in an array, in JavaScript you write arrayName.indexOf("element");. In Ruby, this is accomplished by array_name.index("element")

each

The method each in Ruby is a handy way of iterating through an array of elements in order to change or manipulate them. JavaScript as well as an each function that does the same thing; however, the syntax is slightly different:

1
2
3
4
var arr = [1,2,3,4];
a.forEach(function(n) {
  console.log(n);
});

And in Ruby, the same is written as:

1
2
3
4
5
6
7
8
9
arr = [1,2,3,4]

a.each {|n| puts n}

#or

a.each do |n|
    puts n
end

Falsey Values

One big difference between Ruby and JavaScript is the falsey-ness of certain values. Like in Ruby, null (in Ruby, it’s nil) and false will return false, however, some truthful values in Ruby will return false in JavaScript, like 0, empty strings (""), and undefined.

Object Oriented Programming

JavaScript, like Ruby, can be object-oriented, meaning that objects, their associated methods/functions, can be neatly contained. In JavaScript, a Prototype is much like Ruby’s Class. To create a new Prototype in JavaScript:

1
2
3
4
5
6
7
8
9
10
11
function Cat(name, age, gender){
  this.name = name;
  this.age = parseInt(age);
  this.gender = gender;
  this.meow = function(){
    console.log("meow, my name is "+this.name+"! I am "+this.age+" years old.");
  };
};

var maruCat = new Cat("Maru", "6", "male");
maruCat.meow(); //meow, my name is Maru! I am 6 years old.

The maruCat object is considered a new instance of the Cat prototype. Prototype is essentially the same as Class in Ruby. Note that this in JavaScript is the same concept as self in Ruby.

A Simple Sinatra Buzzer App

This weekend, I wrote a simple door buzzer app that requires authentication before execution. The point of this is to be able to buzz open our downstairs doors from anywhere (particularly useful when hosting airbnb guests). My boyfriend did all of the methanical work: we got a raspberry pi (which we turned into a server to host the app) and a relay to connect that to the door buzzer (there was sautering and wires involved; I just watched). Through that, it’s possible to trigger the buzzer from the command line of the raspberry pi. We (well, mostly my boyfriend; I, again, just really watched) wrote a simple C command to trigger the buzzer for 5 seconds, long enough for someone to get through both doors downstairs:

1
2
3
4
5
6
cd /sys/class/gpio
echo 2 > export
echo out > gpio2/direction
echo 0 > gpio2/value
sleep 5
echo 1 > gpio2/value

I approached this project not necessarily as a big challenge, but as a way to drill in the skills we’ve been working on this week into a cool, useful project. This is the second personal project I’ve worked on during school, but one that was most rewarding. To see all the components come together to make something that is truly useful was super awesome for me. I had been vaguely envisioning writing a door buzzer app for quite sometime, but I didn’t have the skills yet to accomplish that. It was an empowering to realize I was at a point in my learning where I could build something that 4 weeks ago, I wouldn’t have known how to even begin building.

This was an exercise in Sinatra, Ruby, ERB/HTML, SQLite/Sequel/migrations, and general project organization. From scratch I had to set of the program environment and config.ru files, which I can always use some practice with. I won’t bore you with that part, but instead get to the meat of the application.

I have only two models in this application: Buzzer and User.

Buzzer only knows how to do one thing right now, which is trigger the C command that in turn triggers the buzzer itself:

1
2
3
def open_door
      system("/usr/local/sbin/open-buzzer")
  end

User is more advanced, because it interacts with the database, which I created with Sequel and migration methods. User could have used more advanced authentication methods, or even integrated the sinatra-authentication gem, but I thought it was best to keep it simple given the nature of the project.

The app requires you to log in in order to trigger the buzzer, but there’s no way to sign up to that. Usernames and passwords can only be entered manually into the database. So therefore, User’s only tasks are to know if inputed usernames and passwords correspond with that is in the database:

1
2
3
4
5
6
7
8
9
class User < Sequel::Model
  def username?(login_username)
      login_username == username
  end

  def password?(login_password)
      login_password == password
  end
end

Like many of my classmates, I’m a bit in love with Sinatra. I know nothing else to compare it to, so it’s hard to give a solid argument why, but I love it for its simplicity and for its ability to teach me how websites are structured. BuzzerApp is rather simple, but it drives home web app structure for me, and gets the job done, which is great.

There are only three pages in the app: login, which authenticates the username and password input fields, success which lets you know you’re in, and failure, which lets you know you don’t have access. It’s simple for a reason: there’s no way for you to buzz in without entering a username and password, because a) there are no cookie sessions, and b) because an instance of Buzzer is only triggered through /login’s POST. The bulk of the app is within login:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class BuzzerApp < Sinatra::Base
  
  get '/' do
      redirect '/login'
  end

  get '/login' do
      erb :login
  end

  post '/login' do
      login = User.find(username: params[:username])
      if !login.nil?  && login.username?(params[:username]) && login.password?(params[:password])
          buzz = Buzzer.new
          buzz.open_door
          redirect '/success'
      else
          redirect '/failure'
      end
  end

  get '/success' do
      erb :success
  end

  get '/failure' do
      erb :failure
  end
end

Below are the pages rendered by the .erb templates, which could use some styling, although the cats obviously make up for that:

Soon I hope to expand on this project to be able to receive output from the buzzer (to be notified when someone buzzes and then be able to respond with triggering the buzzer). Additionally, I am working on an email notification feature that will notify the administrator each time the buzzer is triggered. My takeaway from this, besides a super useful application, is that sometimes the best tools for a project are the most simple ones. Also, that Sinatra is awesome. :)

Roman Numerals Converter Explained

I’m going to spend this post explaining a roman numeral converter I made for one of our morning todo assignments. I struggled with this assignment, so I thought the best way to really drive it home would be to explain it.

First, within the Integer class, I defined as a constant variable a hash of that is representative of all of the roman numeral characters within their counting system. I cheated a little bit and included instances of 4 and 9, because those are a bit complicated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  NUMERALS =
   {
    1 => "I",
    4 => "IV",
    5 => "V",
    9 => "IX",
    10 => "X",
    40 => "XL",
    50 => "L",
    90 => "XC",
    100 => "C",
    400 => "CD",
    500 => "D",
    900 => "CM",
    1000 => "M"
  }

The instance of the Integer class method is a number, which I called in the initialize method.

1
2
3
def initialize(number)
  @number = number
end

Once I got that out of the way, I began to think about the logic of the roman numerals. Generally, it’s addition and substraction. The number 40, for example is representated as XL. L is 50 and X is 10. 50(L) – 10(X) is 40. Or, the number 13 is XIIII. 10(X) + 1(I) +1(I) +1(I) is 11. The relationship is one of addition and subtraction when you are trying to represent a number that is not a singular character within the roman numeral library.

How to execute this relationship through code is the complicated part. I am at that point in my learning where I know what I want to accomplish with code, but the execution doesn’t come completely naturally. If I compare it to language learning, I am in the recognition stage and still somewhat fumbling with the recollection.

I executed this converter with two methods. The first method, lower_key, takes an instance number as an argument, and returns the largest number below it which has an associated roman numeral. to_roman uses the return of lower_key to help generate the roman numeral associated with the instance of number. I’ll discuss lower_key first.

First, I create a new array, numbers_array, and I .collect all of the numbers in my NUMERALS hash and sort them:

1
numbers_array = NUMERALS.collect {|k,v| k}.sort

This gives me an easy array of the numbers to work with when I compare them to number.

Before I mentioned that the logic of roman numerals is that we’re adding roman numeral characters together to make a number. In order to do that, we need to know the number right below it to work on that. To do this, I iterated over my new numbers_array with .each_with_index. In numbers_array the number (I called it decimal) below number can be found through first determining the number above it. Then, using its index, I can access the number below. Then, returning the .last in numbers_array accounts for if number is greater than the largest number in NUMERALS, like 3000.

1
2
3
4
5
6
numbers_array.each_with_index do |decimal, index|
  if decimal > number
    return numbers_array[index - 1]
  end
end
return numbers_array.last

Onto the to_roman method. First, I confirmed that number is self. I then set a variable roman_numeral = ""; I will be pushing into this string below.

The bulk of the method in enclosed in a while loop. If NUMERALS includes number, set that NUMERALS[number] as roman_numeral. This takes care of instances of number that are simple and already defined in NUMERALS, like 5(V). For more complicated instances, we loop beyond this.

Let’s take a more complicated number like 51(LI) as an example to follow through. It doesn’t apply yet to the if block, but instead is passed into the else first. lower_key(51) is called, which returns 50. “L” is added into roman_numeral (roman_numeral += NUMERALS[50]). Then the remainder of that (number -= 50) is 1, which is passed up and looped through. NUMERALS has that as a key, where the value is “I”, and that is pushed into roman_numeral, right behind the “L” already in there from before. “LI” is returned.

1
2
3
4
5
6
7
8
9
while number > 0
  if NUMERALS.has_key?(number)
    roman_numeral << NUMERALS[number]
    return roman_numeral
  else
    roman_numeral += NUMERALS[lower_key(number)]
    number -= lower_key(number)
  end
end

Below is the entire program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Integer

  NUMERALS =
   {
    1 => "I",
    4 => "IV",
    5 => "V",
    9 => "IX",
    10 => "X",
    40 => "XL",
    50 => "L",
    90 => "XC",
    100 => "C",
    400 => "CD",
    500 => "D",
    900 => "CM",
    1000 => "M"
  }

  def initialize(number)
    @number = number
  end

  def lower_key(number)
    numbers_array = NUMERALS.collect {|decimal, roman| decimal}.sort
    numbers_array.each_with_index do |decimal, index|
      if decimal > number
        return numbers_array[index - 1]
      end
    end
    return numbers_array.last
  end

  def to_roman
    number = self
    roman_numeral= ""
    while number > 0
      if NUMERALS.has_key?(number)
        roman_numeral << NUMERALS[number]
        return roman_numeral
      else
        roman_numeral += NUMERALS[lower_key(number)]
        number -= lower_key(number)
      end
    end
  end
end

One Line at a Time With Ruby Koans

One of the big struggles I’m having with learning to program (there are many, and I’m okay with that!) is taking things slow, one thing at a time, and to not get ahead of myself. I’m often, to sometimes a detriment, a big picture thinker, getting ahead of myself and thinking about things outside the scope of the current concern. Programming, I’ve been learning, requires hyper focus on little things. One method, one, line, one word.

I often find myself, during frustrating moments, failing to do this and going big and wide in search of my program’s bugs and problems, instead of slowing down and moving line by line, word by word, to really focus on each element in my code to learn what is happening.

One thing I believe that has been reinforcing this for me is going through the Ruby Koans. Set up as a series of tests, the koans guide you through learning ruby language, syntax, and structures. In order to move forword on the “path to enlightenment”, you must complete each exercise to pass each test, in order. This has been beyond helpful for me for many reasons. I’m reviewing little things I’ve previously learned about ruby, reinforcing my understanding of the language, all the while learning new things. But equally important, I’m learning to slow down and to hyper focus on one thing at a time, as the program forces you to do.

This is consistently reinforced when running the “path to enlightenment” rspec, which guides you to “meditate on the following code”, pointing you to a specific line in a specific program. In order to pass that test, you must focus on what is happening just on that line/in that method. Nothing more than that.

I work on the koans during my downtime or at lunch, as a break from the project we’re working on in class, or if I want to relax at home and not work on anything heavy, yet still feel like I am accomplishing something code-related. I’ve been, without realizing it at first, treating the koans as a form of meditation.

The Ruby Koans