Monday, January 30, 2017

'Toy Robot' Review by Ryan Bigg (@ryanbigg)

I have started working through a book called Toy Robot by Ryan Bigg, who explains in his introduction:
In this book, I’m going to go through how I would implement the Toy Robot exercise myself in Ruby, just for demonstration purposes. I’ll be building it up piece-by-piece with the overall aim to be to help anyone reading how to think through and implement this problem.
Having just completed "Learn Ruby the Hard Way" I hope to refine my skills by working through Bigg's book.

All my posts about this book will be labeled "toyrobot", so you can call up all the posts to date at your leisure.

As per the book, I used the bundler gem to create a project tree, which is made available on github: https://github.com/clockworkpc/toy_robot

Let's see how it goes!


Finished "Learn Ruby the Hard Way"


Although it took me quite a bit longer than I expected, I am very pleased that I have *just about* finished Learn Ruby the Hard Way.  The final couple chapters are on Sinatra, which I don't strictly need, as I will focus on Rails.

I started working through this book in late November, and were it not for my record on this blog of my progress, it would be difficult to convey how much I have learned.  When I look back at the exercises, things that I couldn't understand make perfect sense; problems that seemed insurmountable are now approachable.  I thoroughly recommend the book to anyone who wants to learn Ruby and feel free to check out my repositories on Github to see how I went about it:

Tree House Prince: A simple text-adventure game demonstrating my grasp of OOP and testing with Rake.

Completed exercises: From the book, mostly by the book, with a few extra details here and there.

Project skeleton generator: a script written in Ruby.  Note that the target directory is ~/Dropbox/Devops/Github_Projects/

Thursday, January 26, 2017

LRTHW Exercise 48 in under 37 lines!

It took me a while, but I just worked through the steps and solved all the problems one by one.






Monday, January 23, 2017

Project Complete!


I have finished re-writing my text adventure game, Tree House Prince, available here: (https://github.com/clockworkpc/tree-house-prince)

It is a very simple game, but I am proud of all the things I learned to get it into this shape.

The game demonstrates my grasp of conditionals, classes, inheritance, and automation testing.  Every scene in the game has full module testing in Rakefile; the integration testing has to be done manually at this stage.  (I will learn about that soon!)

Sunday, January 22, 2017

No Difference Between Boolean Operators AND and OR in Case Conditional in Ruby

I can't see a practical difference between the boolean operators AND and OR in a Ruby case conditional.

For example, I want to get the user to input the sentence:

sudo make me a sandwich

And the case conditional starts as follows:

case user_selection
when /sudo/ && /sandwich/

However, if the user enters:

make me a sandwich

The condition will be a satisfied.

My way around it in this instance is to re-order the conditions:

case user_selection
when /sandwich/ && /sudo/

But that pre-supposes that every time a user thinks to use "sudo" he will include the string "sandwich" in his response.  However, this is functionally no different from this:

case user_selection
when /sudo/

I looked up boolean operators for Ruby conditionals, but have not found a satisfactory answer.

Closed [tree-house-prince] Case Conditional in Kitchen.rb not filtering for both conditions


Closed [tree-house-prince] Case Conditional in Kitchen.rb not filtering for both conditions by clockworkpc via GitHub

Closed [tree-house-prince] Error thrown up by River.rb


Closed [tree-house-prince] Error thrown up by River.rb by clockworkpc via GitHub

Assigned [tree-house-prince] Case Conditional in Kitchen.rb not filtering for both conditions

Case Conditional in Kitchen.rb not filtering for both conditions
By clockworkpc
Closed to

I want the first condition to be satisfied when the user input includes both strings, "sudo" and "sandwich", but at the moment it is satisfied by "sandwich" only. ` def sandwich_selection(user_selection) @choice = false case user_selection when /sudo/ && /sandwich/ puts "The robot happily complies and makes you a sandwich." @status = "success" return @status @choice = true when /give up/ puts "No problem, you're welcome to try again." @status = "failure" return @status @choice = true else puts "Sorry, I can't make you a sandwich, you do not have super-user authority. You can ask again or give up." @status = "try_again" return @status end end `

Labeled:

January 22, 2017 at 07:27PM
via GitHub http://ift.tt/2iZXB5Z

Saturday, January 21, 2017

Assigned [tree-house-prince] Error thrown up by River.rb


Assigned [tree-house-prince] Error thrown up by River.rb by clockworkpc via GitHub Error being thrown up when I play the game and choose to go from the river to the front door. `require_relative "Scene.rb" class River < Scene # def river_choice(user_selection.to_s) # # # end def river_choice(user_selection) @scene_options = { 'live' => 'front_door', 'die' => 'death' } case user_selection.to_s when /1/, /tree/, /house/ puts "You go to the tree house." return 'front_door' @scene_option = 'live' when /2/, /river/ puts "You wade into the river." puts "The strong current pulls you under and you drown." @scene_option = 'die' return 'death' else puts "That does not compute." end end def enter() puts """ You go to the river bank. You feel rather thirsty and decide to have a drink. As you take a few handfuls of fresh water, you realise that the river current is very strong. It would be extremely dangerous to wade into the water. Your thirst quenched, you stand back up and look around. The eclectic tree house is in the centre of the meadow. The river is in front of you. What do you do? 1. Go to the tree house. 2. Wade into the river. """ print "> " user_selection = $stdin.gets.chomp.downcase() river_choice(user_selection) case @scene_option when 'live' return 'front_door' when 'die' return 'death' else puts "Something clearly has gone wrong." end end end `

Assigned [tree-house-prince] Error thrown up by River.rb

Error thrown up by River.rb
By clockworkpc
Closed to

Error being thrown up when I play the game and choose to go from the river to the front door. `require_relative "Scene.rb" class River < Scene # def river_choice(user_selection.to_s) # # # end def river_choice(user_selection) @scene_options = { 'live' => 'front_door', 'die' => 'death' } case user_selection.to_s when /1/, /tree/, /house/ puts "You go to the tree house." return 'front_door' @scene_option = 'live' when /2/, /river/ puts "You wade into the river." puts "The strong current pulls you under and you drown." @scene_option = 'die' return 'death' else puts "That does not compute." end end def enter() puts """ You go to the river bank. You feel rather thirsty and decide to have a drink. As you take a few handfuls of fresh water, you realise that the river current is very strong. It would be extremely dangerous to wade into the water. Your thirst quenched, you stand back up and look around. The eclectic tree house is in the centre of the meadow. The river is in front of you. What do you do? 1. Go to the tree house. 2. Wade into the river. """ print "> " user_selection = $stdin.gets.chomp.downcase() river_choice(user_selection) case @scene_option when 'live' return 'front_door' when 'die' return 'death' else puts "Something clearly has gone wrong." end end end `

Labeled:

January 21, 2017 at 11:38PM
via GitHub http://ift.tt/2jL9Fw9

Friday, January 20, 2017

Closed [tree-house-prince] SpiralStaircase.rb does not pass on its argument to Engine.rb


Closed [tree-house-prince] SpiralStaircase.rb does not pass on its argument to Engine.rb by clockworkpc via GitHub

Assigned [tree-house-prince] SpiralStaircase.rb does not pass on its argument to Engine.rb

SpiralStaircase.rb does not pass on its argument to Engine.rb
By clockworkpc
Closed to

Note: This issue has been solved, this is for the record. `require_relative "Scene.rb" class SpiralStaircase def initialize(current_floor) @current_floor = current_floor @floor_number = current_floor end def selection_text() puts """ You are at a spiral staircase. There is a sign on the landing: 0. Ground Floor: Entrance to the castle 1. First Floor: Machine room 2. Second Floor: Kitchen 3. Third Floor: Library 4. Fourth Floor: Royal Bedroom 5. Penthouse: Study 6. Exit the castle and go back to the meadow. Where would you like to go to? """ end def floor_selector() @exit = { 'ground' => 'ground_floor', 'first' => 'first_floor', 'second' => 'second_floor', 'third' => 'third_floor', 'fourth' => 'fourth_floor', 'fifth' => 'fifth_floor', 'exit' => 'meadow', } # @floor_selection = floor_selection case @floor_selection when /0/, /ground/, /entrance/ if @current_floor == 0 puts "You are already on the ground floor." return 'ground_floor' elsif @current_floor != 0 puts "You descend the stairs to the ground floor." @current_floor = 0 puts "current floor is #{@current_floor}" # return 'ground_floor' else puts "Something has clearly gone wrong." end when /1/, /first/, /machine/ if @current_floor < 1 puts "You ascend the stairs to the first floor." @current_floor = 1 puts "You are now on floor number #{@current_floor}" # return 'first_floor' # @destination = @exit['first'] elsif @current_floor > 1 puts "You descend the stairs to the first floor." @current_floor = 1 # destination = 'first_floor' # return 'first_floor' elsif @current_floor == 1 puts "You are already here. Try another floor." # return 'first_floor' else puts "There has clearly been a mistake somewhere." end when /2/, /second/, /kitchen/ if @current_floor < 2 puts "You ascend the stairs to the second floor." @current_floor = 2 # return 'second_floor' elsif @current_floor > 2 puts "You descend the stairs to the second floor." @current_floor = 2 # return 'second_floor' elsif @current_floor == 2 puts "You are already here. Try another floor." # return 'second_floor' else puts "There has clearly been a mistake somewhere." end when /3/, /third/, /library/ if @current_floor < 3 puts "You ascend the stairs to the third floor." @current_floor = 3 return 'third_floor' elsif @current_floor > 3 puts "You descend the stairs to the third floor." @current_floor = 3 return 'third_floor' elsif @current_floor == 3 puts "You are already here. Try another floor." return 'third_floor' else puts "There has clearly been a mistake somewhere." end when /4/, /fourth/, /bedroom/ if @current_floor < 4 puts "You ascend the stairs to the fourth floor." @current_floor = 4 return 'fourth_floor' elsif @current_floor > 4 puts "You descend the stairs to the fourth floor." @current_floor = 4 return 'fourth_floor' elsif @current_floor == 4 puts "You are already here. Try another floor." return 'fourth_floor' else puts "There has clearly been a mistake somewhere." end when /5/, /fifth/, /study/, /penthouse/ if @current_floor < 5 puts "You ascend the stairs to the fifth floor." @current_floor = 5 return 'fifth_floor' elsif @current_floor == 5 puts "You are already here. Try another floor." return 'fifth_floor' else puts "There has clearly been a mistake somewhere." end when /6/, /leave/, /exit/, /back/, /meadow/ puts "You descend the stairs, walk out the door, and keep going until the you reach the edge of the meadow." @current_floor = 6 return 'meadow' else puts "Spiral staircase doesn't understand your request" end end def enter() floor_number = @floor_number while @current_floor == @floor_number selection_text() print "> " @floor_selection = $stdin.gets.chomp.downcase() floor_selector() case @current_floor when 0 return @exit['ground'] when 1 return @exit['first'] when 2 return @exit['second'] when 3 return @exit['third'] when 4 return @exit['fourth'] when 5 return @exit['fifth'] when 6 return @exit['exit'] else puts "Something has gone wrong" end end end end ` The problem was that the case conditional inside floor_selector() did not pass on the arguments all the way back to the Engine. I solved this by creating a hash with a class-wide scope, from which enter() could retrieve the argument and pass it on to the Engine. The solution to this problem lay in getting the "return" argument out of the case conditional inside the while loop

Labeled:

January 20, 2017 at 02:33PM
via GitHub http://ift.tt/2juxbuN

Assigned [tree-house-prince] SpiralStaircase.rb does not pass on its argument to Engine.rb


Assigned [tree-house-prince] SpiralStaircase.rb does not pass on its argument to Engine.rb by clockworkpc via GitHub

Wednesday, January 18, 2017

Getting the Hang of Rakefile!

There seems to be an error every step of the way, but, inch by inch, I'm getting there.


Tuesday, January 17, 2017

User Testing Update



I've had to hit the books again to improve my understanding of variables, classes, and methods.

I've been re-writing my text adventure game so that every aspect of it is tested by the Rakefile.  This means that I have had to extrapolate the logic of the enter() method in each class, so that a test can be written for it.

The most interesting parts of the game involve somewhat complex conditionals, written as case conditionals, and for some reason it took me a while to understand how to pass on a variable to the method containing a case conditional.  Now that I look at it again, it's very simple, but c'est la vie.

Anyway, the re-written game is nearing completion and the latest code is up on Github.

Wednesday, January 11, 2017

Progress Chart With A Twist (Or Pattern!)

My beloved helped me to create a handy stencil for my white board, with which I make a chart like this:


The chart works like this:
Black = Study, i.e reading about Ruby, learning the concepts.
Green = Code, i.e. working on code that goes to Github.
Blue = Blogging.
Red = Job search, i.e. applying for jobs, calling recruiters, etc.

This is literally a progress chart, in the sense that it represents my progress, rather than how much of a goal I have completed.

The twist of setting up the 10x10 table with a repeating pattern of four colours, instead of a neater set of coloured columns, is that gaps are unsightly.  Each of these four aspects of my mission is equally important, and the discomfort of seeing an uneven distribution of filled cells induces me to turn my attention to activities I have been neglecting.

To be honest, I do not enjoy looking for work, and would much rather be busy coding and studying.  Blogging isn't too bad, but coding is more fun.

Nevertheless, until I get my first gig, my job is looking for work, and so the red cells have to be filled in first.

So far, so good.

Ruby Hack Night Review (2017-01-11)

The first Melbourne Ruby Hack Night, hosted by REA Group, was every bit as good as I had hoped.

Check out Ruby and Rails Melbourne on Meetup.
It was my first proper hacking event since my Linux Victoria days, and it was exciting to sit in a room full of people who really enjoy their code.  The atmosphere at the event was the right mix of serious keyboard tapping and light-hearted conversation, and the venue is really quite comfortable.

We started at 18:00 and worked each of us fairly quietly for about an hour, until the pizzas were delivered.  We downed tools and enjoyed some good food and friendly conversation.  After doing the schmoozing rounds, we drifted back to our computers, and the evening passed by pleasurably and productively until the end of the evening at 21:00.

I was especially pleased to get some much needed help with my test automation, and my vastly improved code will be ready for a push to Github tomorrow, once I've tidied up some loose ends.

(Update: The next version of the code I was working is available)

Many thanks to the organisers and I'm looking forward to the next Melbourne Ruby Hack Night.


Tuesday, January 10, 2017

The Story of My Engagement

NOTE: My fiancée wishes to stay out of the online limelight, and neither her real name nor her image shall appear in this or future posts.

I met my beloved at a libertarian meet-up in Melbourne in early 2015.  We chatted all night and befriended each other on Facebook, but didn't exchange messages for about a week or two thereafter.  At the time I was reading 'Paradise Lost' by John Milton and messaged her to share an especially good passage.  This led to our first date: at the Melbourne City Public Library, where we read from 'Paradise Lost' and some other poetry together -- Blake and Shakespeare, if I recall --, and then spent the rest of the evening at the Oriental Tea House.

Our courtship was not without difficulty, for who is not fallible?, but I believe we fell in love immediately and gradually came to realise that a great shift in our lives had come to pass.


On my birthday, 20th of May 2015, my beloved gave to me a beautiful hard-cover journal featuring etchings of William Blake's poetry.  In truth, the journal was too fine for me to fill with scrawls of incomplete thoughts, and I put it away until such time as I had something worthwhile to write in it.

On the birthday of my beloved last year, the seventh of January 2016, I finally realised what I wanted to write in the journal: a declaration of love and a proposal of marriage.  My first entry was on the twentieth of May 2016, and over the next fifty weeks, I gradually filled the journal with logs, love letters, transcriptions of poetry, original poems, and a short story.  I fell behind schedule during the winter and had to recalculate the number of pages per day to fill in order to have the journal ready by the seventh of January 2017.

In December of 2016 I ordered an engagement ring composed of a silver band and a sparkling emerald, which turned out to be the wrong size, and had a nervous wait for it to be resized by a local jeweller.
On the fifth of January, I had the ring.
On the sixth of January, the journal was complete.

My final Kanban ticket before the big day, now complete.
After eleven-dozen-and-ten pages of writing from the heart, the last two pages were my final declaration of love in French, Hebrew, Lithuanian, and English; and my proposal of marriage in all four languages.

The declaration of love:

Oui, mon amour, je vois bien l'essentiel avec le coeur: tu m'as trouvé et apprivoisé (bien que je suis encore un animal sauvage); tu es ma rose et je suis pour toujours responsable de toi.

כן, אהובתי, רואה אני היטב בלבי את הדבר החשוב באמת: מצאת אותי ואילפת אותי (אומנם נשאר אני חיית פרא): את השושנה שלי וערב אני לשלומתך לנצח.

Jo, mano meilé, aš svarbiausią dalyką matau: tu mane radai ir prisijaukinau (nors aš vis dar laukinis šveris esu); tu mano rože esi ir aš atsikingas amžinai už tave.

Yes, my love, I see the essential with my heart: thou didst find me and tame me (although I remain a savage beast at heart!); thou art my rose and I am forever responsible for thee.

And finally, the proposal of marriage:

[], ma chׂérie, mon miracle, je t'aimerai pour toujours.
Veux-tu m'épouser?

[אהובתי], יקירתי, נשמה שלי, אאהב אותך לנצח.
התהיי לי לאישה?
Progress chart at 100%!

[], mano meilė, mano stebuklas, aš tave amžinai mylėsiu.  Ar tekėsi už manęs?

[], my darling, my miracle, I thee shall forever love.  Wilt thou marry me?

The answers were:
Oui!
כן!
Jo!
Yes!

Where to from here?

My immediate goal is to get a start as a Ruby software developer, and to work in a location that allows me to move to Lara, Victoria, where my fiancée lives.  Our dream is to get married, have a family, and have many children.  My heart's desire is to provide for my future family, and it is the motive that drives all my endeavours.  My beloved is the embodiment of Christian virtue and every line of code I wrote brings me one step closer to the responsible, meaningful, intentional life I have always dreamed of, and which, at times in my despair I thought forever beyond my grasp.

But now it is within my grasp and the thing required of me is to study hard and work smart.

Now back to work and the next chapter of a wonderful life.

Monday, January 2, 2017

Getting started with Rakefile and testing

Up to chapter 47 of Learn Ruby the Hard Way, and I have uploaded version 0.01 of my little text adventure, Treehouse Prince.

https://github.com/clockworkpc/treehouseprince/tree/master/skeleton

The purpose of working on this is to familiarise myself with the fundamentals of testing.  As I put back all the components of the game, I shall get to see how the Rakefile saves me running the game manually a thousand times over.


1,050 hours

It took me 13 working days to complete my first 100 "work" pomodoros as a Junior Software Tester at Profectus Group.  Much of ...