Monday, September 25, 2017

What I've done so far

I started on 16th of September. I installed Ruby on my Windows machine along with Sublime. I created a small to-do program initially to refreshen up on Ruby (I had done a couple of programs in Ruby before, but it had been a while) and coding in general. The to-do app was nothing special - it is run from the console and has basic functionality for adding and removing items in the list, and the data doesn't persist.

I had a feeling that 20 lines of code wasn't enough as a refresher. I enrolled on a codecademy Ruby course, which was sufficient. It included everything basic, and made me feel good with its achievements that I earned throughout. I haven't gone back.

How I usually focus is that I start a timer with 60 minutes on the clock and work on the task at hand. After, I have a break - I try to break for 5-15 minutes. Sometimes for an hour... I like it. Having a set amount of time put aside for a task does wonders for my focus. What is more, I like to log the time in my notebook: start and end time with date, and a short comment what I did or learned. Good for reviewing.

After codecademy I looked for another small project to tackle. So I've been using a count-down timer, and thought: "I could make this myself!". It seemed simple... It took me 4 hours to make this buggy piece of shit, that I still use. Most of the time went into making it parse time. I wanted it to accept a format 'XXhXXmXXs' or its substrings. I made it work with a solution, that makes me feel inadequate. I won't go into it, but I'll post the code below. Playing a sound is with a hardcoded filepath and only works on a Linux machine, since it uses a terminal command 'play': '%x'play ~/Desktop/Ruby/alarm.wav'. '%x' in front let me use terminal commands in Ruby. What was good about the project, is that I found out about a gem named 'optparse', which let me implement CL arguments easily. And the program itself is in use!

I also found out about The Odin Project(ToD), which has a nice curriculum, and I've read great about it on the internets. It's more like self-study and less about walking me through. Taking this with a grain of salt still, since I've only completed small parts of it. Last part I completed was this, I skipped some parts in the beginning and jumped straight there. Once I complete my Udemy course or I feel like I need a change of pace, I will continue with ToD. There's also this huge RoR book by Michael Hartl, that has caught my attention.

I wanted to switch things up after doing that part on ToD, and I found a Udemy course to follow: Dissecting Ruby on Rails 5 - Become a Professional Developer. For 10€ it's been OK. He goes quite in-depth which I like, but at the same time, it is very hand-holdy, since it's a walk-through, and gets boring at times (1.5x speed is a lifesaver), since I'm not tackling any problems on my own going through this. At the same time though, I still feel lost when I try to build a site on my own. My current progress with Udemy is 59 of 214 items complete - somethingsomething 25% maybe.


According to my logbook, everything above took about 30 hours to accomplish.
I will be continuing with Udemy, and at some point return to ToD. 

timer.rb code:
  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
# Program: "Countdown timer"
## Program needs a CL argument for time, or defaults to 1h. Input can be in hours, minutes, or seconds.
## Example: 'ruby timer.rb -t 1h30m50s' or '1h50s' or '30m'
## When the timer reaches to end, a sound will play
#BUGS: '$ruby timer.rb -h' shows the help message, but will also start the timer with 1h on the clock
#      alarm.wav is hardcoded
require 'optparse'

options = {}

OptionParser.new do |parser|

 parser.banner = "Usage: timer.rb [options]"

 parser.on("-t", "--time XXhXXmXXs", "Amount of time to countdown. ") do |v|
  options[:time] = v
 end

  parser.on("-h", "--help", "Show this help message") do ||
    puts parser
  end
end.parse!

class Timer
 # Argument :String in format "XXhXXmXXs"
 def initialize(time)
  @time = time
  @total_seconds = parse_time(time)
  timer(@total_seconds)
 end

 private
 ## Starts the countdown timer
 # Argument :Integer 
 def timer(seconds)
  starttime = Time.now
  seconds.times do |s|
   sleep(1)
   puts "#{s} seconds" if s % 60 == 0
  end
  endtime = Time.now
  puts "Alarm started at #{starttime}"
  puts "ran for #{endtime - starttime}"
  puts "and stopped at #{endtime}"
  alarm
 end

 def alarm
  %x'play ~/Desktop/Ruby/alarm.wav'
 end
 ## Converts user input into total seconds
 # Argument :String
 # Return :Integer
 def parse_time(time) 
  time_hash = { 
   "h" => 0,
   "m" => 0,
   "s" => 0,
  }

  # split the string up into an array
  time_array = time.split("")
  # convert strings containing integers into Integer type
  time_array.map! { |x| number_or_string(x) }

  # Sort hours, minutes and seconds to hash
  counter = 0
  current_number = 0
  time_array.each do |x|
   if x.is_a? Integer
    current_number = current_number * 10**counter + x
    counter += 1
   elsif x.is_a? String
    time_hash[x] += current_number
    counter, current_number = 0, 0
   end
  end

  return time_hash["h"] * 60**2 + time_hash["m"] * 60 + time_hash["s"] 
 end #

 ## Converts string to an integer
 ## If the string is not convertible, returns the string
 # Argument :String
 # Return :Integer || :String
 def number_or_string(string)
  num = string.to_i
  if num.to_s == string
   num
  else
   string
  end
 end
end
puts "Alarm.wav path is hardcoded!"
if options != {}
 timer = Timer.new(options[:time]) 
else
 timer = Timer.new("1h")
end
I used hilite.me to create this pretty embed.

2 comments:

  1. Thanks for linking to the Odin Project.

    ReplyDelete
  2. Wanna try something Ruby like? Something that have a similar syntax. Like really close to the point that either of the code will work with both Ruby and Crystal.

    Crystal is just for performance.

    ReplyDelete