SlideShare a Scribd company logo
1 of 108
IN THE BACK OF YOUR MIND
  beanstalkd and 0MQ through the Dominic System
THE DOMINIC SYSTEM
LEARN HOW
 TO IMPROVE
 YOUR MIND
A book I am currently reading
MEMORY TECHNIQUES
MEMORY TECHNIQUES

• The   book includes various techniques for improving memory
MEMORY TECHNIQUES

• The   book includes various techniques for improving memory

• Ithelps to translate abstract data (the brain is weak with) into
  vivid images (a strength of the brain)
MEMORY TECHNIQUES

• The    book includes various techniques for improving memory

• Ithelps to translate abstract data (the brain is weak with) into
  vivid images (a strength of the brain)

• The Dominic System is used to translate numbers into
  characters and actions

  • It   can help you memorize large numbers
SINGLE DIGITS
SINGLE DIGITS


• Just
     count through the
 alphabet

  • But   replace F with S

  • And     skip to N when you
    hit 9
SINGLE DIGITS
                                 1   A
                                 2   B
• Just
     count through the           3   C
 alphabet                        4   D
                                 5   E
  • But   replace F with S
                                 6   S
  • And     skip to N when you   7   G
    hit 9                        8   H
                                 9   N
                                 0   O
DOUBLE DIGITS
DOUBLE DIGITS

• Convert   digit pairs into letters

 • 15   = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA
DOUBLE DIGITS

• Convert    digit pairs into letters

 • 15   = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA

• Use   the letters as initials for a character

 • AE    = Albert Einstein, BG = Bill Gates, CN = Chuck Norris
DOUBLE DIGITS

• Convert    digit pairs into letters

 • 15   = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA

• Use   the letters as initials for a character

 • AE    = Albert Einstein, BG = Bill Gates, CN = Chuck Norris

• Or   use letters to indicate characters in other ways

 • BC    = Jesus Christ, HO = Santa Claus, HA = Julia Sweeney
IMAGERY IS KEY
IMAGERY IS KEY

• Each   digit pair should create an image in your mind
IMAGERY IS KEY

• Each   digit pair should create an image in your mind

• The   image need to be a character doing their signature action

 • Chuck     Norris performing a roundhouse kick

 • Santa    Claus delivering presents

 • Julia   Sweeney dressing asexually
FOUR DIGIT NUMBERS
FOUR DIGIT NUMBERS

• Tohandle four digit numbers, use the first two for the
 character and the second two as the action

 • 2339   = BCCN = Jesus Christ performing a roundhouse kick

 • 8081   = HOHA = Santa Claus dressing asexually
FOUR DIGIT NUMBERS

• Tohandle four digit numbers, use the first two for the
 character and the second two as the action

  • 2339   = BCCN = Jesus Christ performing a roundhouse kick

  • 8081   = HOHA = Santa Claus dressing asexually

• You’re   up to a 10,000 number memory at this point!
LARGER NUMBERS
LARGER NUMBERS


• “Chunk” up   bigger numbers into two and four digit groups
LARGER NUMBERS


• “Chunk” up    bigger numbers into two and four digit groups

• Build   wacky stories using those characters and actions

  • 27808039  = 2780 8039 = BGHO HOCN = Bill Gates
   started delivering presents, but this angered Santa Claus
   who gave him a roundhouse kick.
A CAST OF CHARACTERS
A CAST OF CHARACTERS
http://ron.ludism.org/mnemonics_public.txt

…
40 = DO = Fred Flintstone, breaking rocks in the quarry (Yabba dabba
      DOo!)
41 = DA = Douglas Adams, putting a Babelfish into his ear (_The Hitch
      Hiker's Guide to the Galaxy_)
42 = DB = PERSONAL
43 = DC = George Washington, chopping down cherry tree (Washington DC)
44 = DD = Danny Dunn (fictional character), descending in a
      bathysphere
45 = DE = PERSONAL
46 = DS = Ivan Stang (a.k.a. Doug Smith), ranting on a soapbox
47 = DG = PERSONAL
48 = DH = Douglas Hofstadter, recursively holding a picture of himself
49 = DN = Dan (_Roseanne_ TV show), wearing sunglasses to switch on
      Christmas lights
…
A CAST OF CHARACTERS
http://ron.ludism.org/mnemonics_public.txt

…
40 = DO = Fred Flintstone, breaking rocks in the quarry (Yabba dabba
      DOo!)
41 = DA = Douglas Adams, putting a Babelfish into his ear (_The Hitch
      Hiker's Guide to the Galaxy_)
42 = DB = PERSONAL
43 = DC = George Washington, chopping down cherry tree (Washington DC)
44 = DD = Danny Dunn (fictional character), descending in a
      bathysphere
45 = DE = PERSONAL
46 = DS = Ivan Stang (a.k.a. Doug Smith), ranting on a soapbox
47 = DG = PERSONAL
48 = DH = Douglas Hofstadter, recursively holding a picture of himself
49 = DN = Dan (_Roseanne_ TV show), wearing sunglasses to switch on
      Christmas lights
…
BEANSTALKD (VIA STALKER)
BEANSTALKD
BEANSTALKD


•A   simple but highly effective message queue
BEANSTALKD


•A   simple but highly effective message queue

• I’ve   used it many times, including to do moves in Go vs Go
BEANSTALKD


•A   simple but highly effective message queue

• I’ve   used it many times, including to do moves in Go vs Go

• It’s   definitely one of my favorite tools for background jobs
CHARACTER LOOKUPS
CHARACTER LOOKUPS
require "open-uri"

def lookup_table
 return @lookup_table if defined? @lookup_table
 @lookup_table = { }
 open("http://ron.ludism.org/mnemonics_public.txt") do |page|
  page.each do |line|
    if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/
      @lookup_table[$1] = $2
    elsif line =~ /As+(.+)/
      @lookup_table.values.last << " #{$1}"
    end
  end
 end
 @lookup_table
end
CHARACTER LOOKUPS
require "open-uri"

def lookup_table
 return @lookup_table if defined? @lookup_table
 @lookup_table = { }
 open("http://ron.ludism.org/mnemonics_public.txt") do |page|
  page.each do |line|
    if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/
      @lookup_table[$1] = $2
    elsif line =~ /As+(.+)/
      @lookup_table.values.last << " #{$1}"
    end
  end
 end
 @lookup_table
end
CHARACTER LOOKUPS
require "open-uri"

def lookup_table
 return @lookup_table if defined? @lookup_table
 @lookup_table = { }
 open("http://ron.ludism.org/mnemonics_public.txt") do |page|
  page.each do |line|
    if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/
      @lookup_table[$1] = $2
    elsif line =~ /As+(.+)/
      @lookup_table.values.last << " #{$1}"
    end
  end
 end
 @lookup_table
end
ENCODING CHUNKS
ENCODING CHUNKS

def encode(n, as = :both)
 if n.size == 4 and as == :both
   "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}."
 elsif as == :both
   "#{encode(n, :character)} #{encode(n, :action)}."
 elsif as == :character
   lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1]
 elsif as == :action
   lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1]
 end
end
ENCODING CHUNKS

def encode(n, as = :both)
 if n.size == 4 and as == :both
   "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}."
 elsif as == :both
   "#{encode(n, :character)} #{encode(n, :action)}."
 elsif as == :character
   lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1]
 elsif as == :action
   lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1]
 end
end
ENCODING CHUNKS

def encode(n, as = :both)
 if n.size == 4 and as == :both
   "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}."
 elsif as == :both
   "#{encode(n, :character)} #{encode(n, :action)}."
 elsif as == :character
   lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1]
 elsif as == :action
   lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1]
 end
end
ENCODING NUMBERS
ENCODING NUMBERS
job "number.encode" do |args|
  number = args["number"].to_s.delete("^0-9")
  number = "0#{number}" if (number.size % 2).nonzero?
  chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2)

 encodings = [ ]
 chunks.permutation.to_a.uniq.each do |grouping|
  encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/)
              .captures
              .map { |n| encode(n) }
              .join(" ")
              .tr("_", '"')
 end

 Stalker.enqueue( "number.display", number: args["number"],
                      encodings: encodings )
end
ENCODING NUMBERS
job "number.encode" do |args|
  number = args["number"].to_s.delete("^0-9")
  number = "0#{number}" if (number.size % 2).nonzero?
  chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2)

 encodings = [ ]
 chunks.permutation.to_a.uniq.each do |grouping|
  encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/)
              .captures
              .map { |n| encode(n) }
              .join(" ")
              .tr("_", '"')
 end

 Stalker.enqueue( "number.display", number: args["number"],
                      encodings: encodings )
end
ENCODING NUMBERS
job "number.encode" do |args|
  number = args["number"].to_s.delete("^0-9")
  number = "0#{number}" if (number.size % 2).nonzero?
  chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2)

 encodings = [ ]
 chunks.permutation.to_a.uniq.each do |grouping|
  encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/)
              .captures
              .map { |n| encode(n) }
              .join(" ")
              .tr("_", '"')
 end

 Stalker.enqueue( "number.display", number: args["number"],
                      encodings: encodings )
end
ENCODING NUMBERS
job "number.encode" do |args|
  number = args["number"].to_s.delete("^0-9")
  number = "0#{number}" if (number.size % 2).nonzero?
  chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2)

 encodings = [ ]
 chunks.permutation.to_a.uniq.each do |grouping|
  encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/)
              .captures
              .map { |n| encode(n) }
              .join(" ")
              .tr("_", '"')
 end

 Stalker.enqueue( "number.display", number: args["number"],
                      encodings: encodings )
end
DISPLAYING ENCODINGS
DISPLAYING ENCODINGS


  job "number.display" do |args|
    Array(args["encodings"]).each do |encoded|
     puts "#{args['number']}:"
     puts encoded
     puts
    end
  end
QUEUING NUMBERS
QUEUING NUMBERS


abort "USAGE: #{$PROGRAM_NAME} NUMBER" if ARGV.empty?

require "stalker"
Stalker.enqueue("number.encode", number: ARGV.shift)
RUNNING JOBS
RUNNING JOBS
$ beanstalkd
RUNNING JOBS
$ beanstalkd


$ ruby encode_number.rb 405-285-0536
RUNNING JOBS
$ beanstalkd


$ ruby encode_number.rb 405-285-0536


$ rvm 1.9.2
$ RUBYLIB=. stalk jobs.rb number.encode
[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ]
[2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)
[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
RUNNING JOBS
$ beanstalkd


$ ruby encode_number.rb 405-285-0536


$ rvm 1.9.2
$ RUBYLIB=. stalk jobs.rb number.encode
[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ]
[2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)
[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
RUNNING JOBS
$ beanstalkd


$ ruby encode_number.rb 405-285-0536


$ rvm 1.9.2
$ RUBYLIB=. stalk jobs.rb number.encode
[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ]
[2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)
[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
RUNNING JOBS
$ beanstalkd


$ ruby encode_number.rb 405-285-0536


$ rvm 1.9.2
$ RUBYLIB=. stalk jobs.rb number.encode
[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ]
[2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)
[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
RUNNING JOBS
$ beanstalkd


$ ruby encode_number.rb 405-285-0536


$ rvm 1.9.2
$ RUBYLIB=. stalk jobs.rb number.encode
[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ]
[2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)
[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
RUNNING JOBS
$ beanstalkd


$ ruby encode_number.rb 405-285-0536


$ rvm 1.9.2
$ RUBYLIB=. stalk jobs.rb number.encode
[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ]
[2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)
[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
RUNNING JOBS
$ beanstalkd


$ ruby encode_number.rb 405-285-0536


$ rvm 1.9.2
$ RUBYLIB=. stalk jobs.rb number.encode
[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ]
[2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)
[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms


$ RUBYLIB=. stalk jobs.rb number.display
…
405-285-0536:
Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!).
Stuart Little (tiny fictional mouse wearing street clothes) releasing
helium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping into
the Wardrobe.
…
FOR MORE INFORMATION
      See Railscasts #243
FOR MORE INFORMATION
      See Railscasts #243
BEANSTALKD PROS
BEANSTALKD PROS

• Extremely   lightweight (especially if you drop the Rails stack)
BEANSTALKD PROS

• Extremely   lightweight (especially if you drop the Rails stack)

• Ridiculously   fast
BEANSTALKD PROS

• Extremely   lightweight (especially if you drop the Rails stack)

• Ridiculously   fast

• Designed    to be a queue
BEANSTALKD PROS

• Extremely   lightweight (especially if you drop the Rails stack)

• Ridiculously   fast

• Designed    to be a queue

• “Tubes” make     it trivial to divide work or pipeline jobs
BEANSTALKD PROS

• Extremely    lightweight (especially if you drop the Rails stack)

• Ridiculously   fast

• Designed    to be a queue

• “Tubes” make     it trivial to divide work or pipeline jobs

• Really   easy to spread across ruby versions and environments
BEANSTALKD CONS
BEANSTALKD CONS


• Not ideal for durable queuing needs (though it does have a
 binlog)
BEANSTALKD CONS


• Not ideal for durable queuing needs (though it does have a
 binlog)

• Missing
        niceties like logging (though Stalker adds logging above
 beanstalkd)
BEANSTALKD CONS


• Not ideal for durable queuing needs (though it does have a
 binlog)

• Missing
        niceties like logging (though Stalker adds logging above
 beanstalkd)

• Needs     job introspection
0MQ
(AKA ZEROMQ OR ZMQ)
0MQ
0MQ


•A   high-level socket API over an asynchronous message queue

 • Request   and reply, publish subscribe, and pipeline models
0MQ


•A   high-level socket API over an asynchronous message queue

  • Request    and reply, publish subscribe, and pipeline models

• This   was my first time using it (I was curious about it)

  •I   don’t think it’s well suited to this task
THE END OF THE PIPELINE
THE END OF THE PIPELINE


     require "zmq"

     zmq = ZMQ::Context.new
     up = zmq.socket(ZMQ::UPSTREAM)
     up.bind("tcp://127.0.0.1:5000")

     while message = up.recv
      puts message
     end
THE END OF THE PIPELINE


     require "zmq"

     zmq = ZMQ::Context.new
     up = zmq.socket(ZMQ::UPSTREAM)
     up.bind("tcp://127.0.0.1:5000")

     while message = up.recv
      puts message
     end
THE END OF THE PIPELINE


     require "zmq"

     zmq = ZMQ::Context.new
     up = zmq.socket(ZMQ::UPSTREAM)
     up.bind("tcp://127.0.0.1:5000")

     while message = up.recv
      puts message
     end
THE END OF THE PIPELINE


     require "zmq"

     zmq = ZMQ::Context.new
     up = zmq.socket(ZMQ::UPSTREAM)
     up.bind("tcp://127.0.0.1:5000")

     while message = up.recv
      puts message
     end
NUMBER LOOKUPS
NUMBER LOOKUPS

# same lookup_table() as before…

def lookup
 lookup_table.each do |number, character_and_action|
   return number if yield character_and_action
 end
 nil
end

def character_number(msg)
 lookup { |ca| msg.start_with? ca[/As*([^,]+(?:([^)]+))?)/, 1] }
end

def action_number(msg)
 lookup { |ca| msg.end_with? ca[/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] }
end
NUMBER LOOKUPS

# same lookup_table() as before…

def lookup
 lookup_table.each do |number, character_and_action|
   return number if yield character_and_action
 end
 nil
end

def character_number(msg)
 lookup { |ca| msg.start_with? ca[/As*([^,]+(?:([^)]+))?)/, 1] }
end

def action_number(msg)
 lookup { |ca| msg.end_with? ca[/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] }
end
A DECODER
A DECODER


def decode(message)
 message.to_s.strip.split(/.(?:s{2}|n|z)/).map { |chunk|
   chunk.gsub!(/s+/, " ")
   character = character_number(chunk)
   action = action_number(chunk)
   character == action ? character : "#{character}#{action}"
 }.join
end
THE MIDDLE PIPE
THE MIDDLE PIPE

require "zmq"

zmq = ZMQ::Context.new
up = zmq.socket(ZMQ::UPSTREAM)
down = zmq.socket(ZMQ::DOWNSTREAM)
up.bind("tcp://127.0.0.1:5001")
down.connect("tcp://127.0.0.1:5000")

while message = up.recv
 down.send(decode(message))
end
THE MIDDLE PIPE

require "zmq"

zmq = ZMQ::Context.new
up = zmq.socket(ZMQ::UPSTREAM)
down = zmq.socket(ZMQ::DOWNSTREAM)
up.bind("tcp://127.0.0.1:5001")
down.connect("tcp://127.0.0.1:5000")

while message = up.recv
 down.send(decode(message))
end
THE MIDDLE PIPE

require "zmq"

zmq = ZMQ::Context.new
up = zmq.socket(ZMQ::UPSTREAM)
down = zmq.socket(ZMQ::DOWNSTREAM)
up.bind("tcp://127.0.0.1:5001")
down.connect("tcp://127.0.0.1:5000")

while message = up.recv
 down.send(decode(message))
end
THE MIDDLE PIPE

require "zmq"

zmq = ZMQ::Context.new
up = zmq.socket(ZMQ::UPSTREAM)
down = zmq.socket(ZMQ::DOWNSTREAM)
up.bind("tcp://127.0.0.1:5001")
down.connect("tcp://127.0.0.1:5000")

while message = up.recv
 down.send(decode(message))
end
THE PIPELINE OPENING
THE PIPELINE OPENING


   require "zmq"

   zmq = ZMQ::Context.new
   down = zmq.socket(ZMQ::DOWNSTREAM)
   down.connect("tcp://127.0.0.1:5001")

   down.send(ARGF.read)
A DATA PIPELINE IN ACTION
A DATA PIPELINE IN ACTION

$ ruby queue_message.rb
Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!).
Stuart Little (tiny fictional mouse wearing street clothes) releasing
helium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping into
the Wardrobe.
^d
A DATA PIPELINE IN ACTION

$ ruby queue_message.rb
Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!).
Stuart Little (tiny fictional mouse wearing street clothes) releasing
helium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping into
the Wardrobe.
^d


                                                              $ ruby decoder.rb
A DATA PIPELINE IN ACTION

$ ruby queue_message.rb
Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!).
Stuart Little (tiny fictional mouse wearing street clothes) releasing
helium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping into
the Wardrobe.
^d


                                                              $ ruby decoder.rb


                                                   $ ruby decoder_display.rb
                                                   4052850536
0MQ PROS
0MQ PROS


• Asynchronous   messaging primitives for constructing networks
0MQ PROS


• Asynchronous    messaging primitives for constructing networks

• Extremely   versatile (can be made to fit most any model)
0MQ PROS


• Asynchronous    messaging primitives for constructing networks

• Extremely   versatile (can be made to fit most any model)

• Supports   many to many connections
0MQ PROS


• Asynchronous    messaging primitives for constructing networks

• Extremely   versatile (can be made to fit most any model)

• Supports   many to many connections

• Automatically   load balanced
0MQ CONS
0MQ CONS


• Very   low-level (really just a platform to build on)

 • Missing   all the conveniences: logging, message formats, etc.
0MQ CONS


• Very   low-level (really just a platform to build on)

  • Missing   all the conveniences: logging, message formats, etc.

• Best   for asynchronous networks you design and build
THANKS!

More Related Content

Similar to In the Back of Your Mind

Thinking Functionally In Ruby
Thinking Functionally In RubyThinking Functionally In Ruby
Thinking Functionally In RubyRoss Lawley
 
Basics of Dynamic programming
Basics of Dynamic programming Basics of Dynamic programming
Basics of Dynamic programming Yan Xu
 
ScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyGautam Rege
 
Locality sensitive hashing
Locality sensitive hashingLocality sensitive hashing
Locality sensitive hashingSEMINARGROOT
 
How i won a golf set from reg.ru
How i won a golf set from reg.ruHow i won a golf set from reg.ru
How i won a golf set from reg.runobull
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
 
Introduction to R
Introduction to RIntroduction to R
Introduction to Rvpletap
 
RadixSort.ppt
RadixSort.pptRadixSort.ppt
RadixSort.pptnalavuolu
 
Python Variable Types, List, Tuple, Dictionary
Python Variable Types, List, Tuple, DictionaryPython Variable Types, List, Tuple, Dictionary
Python Variable Types, List, Tuple, DictionarySoba Arjun
 
Week-2: Theory & Practice of Data Cleaning: Regular Expressions in Practice
Week-2: Theory & Practice of Data Cleaning: Regular Expressions in PracticeWeek-2: Theory & Practice of Data Cleaning: Regular Expressions in Practice
Week-2: Theory & Practice of Data Cleaning: Regular Expressions in PracticeBertram Ludäscher
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 

Similar to In the Back of Your Mind (20)

P3 2018 python_regexes
P3 2018 python_regexesP3 2018 python_regexes
P3 2018 python_regexes
 
Thinking Functionally In Ruby
Thinking Functionally In RubyThinking Functionally In Ruby
Thinking Functionally In Ruby
 
Ggplot2 v3
Ggplot2 v3Ggplot2 v3
Ggplot2 v3
 
Basics of Dynamic programming
Basics of Dynamic programming Basics of Dynamic programming
Basics of Dynamic programming
 
ScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyScotRuby - Dark side of ruby
ScotRuby - Dark side of ruby
 
Locality sensitive hashing
Locality sensitive hashingLocality sensitive hashing
Locality sensitive hashing
 
How i won a golf set from reg.ru
How i won a golf set from reg.ruHow i won a golf set from reg.ru
How i won a golf set from reg.ru
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
Introduction to R
Introduction to RIntroduction to R
Introduction to R
 
Number system
Number systemNumber system
Number system
 
RadixSort.ppt
RadixSort.pptRadixSort.ppt
RadixSort.ppt
 
Perl_Tutorial_v1
Perl_Tutorial_v1Perl_Tutorial_v1
Perl_Tutorial_v1
 
Perl_Tutorial_v1
Perl_Tutorial_v1Perl_Tutorial_v1
Perl_Tutorial_v1
 
Python Variable Types, List, Tuple, Dictionary
Python Variable Types, List, Tuple, DictionaryPython Variable Types, List, Tuple, Dictionary
Python Variable Types, List, Tuple, Dictionary
 
Week-2: Theory & Practice of Data Cleaning: Regular Expressions in Practice
Week-2: Theory & Practice of Data Cleaning: Regular Expressions in PracticeWeek-2: Theory & Practice of Data Cleaning: Regular Expressions in Practice
Week-2: Theory & Practice of Data Cleaning: Regular Expressions in Practice
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Strings and Symbols
Strings and SymbolsStrings and Symbols
Strings and Symbols
 

More from James Gray

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A KeynoteJames Gray
 
Regular expressions
Regular expressionsRegular expressions
Regular expressionsJames Gray
 
Counting on God
Counting on GodCounting on God
Counting on GodJames Gray
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)James Gray
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHubJames Gray
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in RailsJames Gray
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And RenderingJames Gray
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with RailsJames Gray
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in RailsJames Gray
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersJames Gray
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails InterfaceJames Gray
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on RailsJames Gray
 

More from James Gray (18)

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A Keynote
 
I Doubt That!
I Doubt That!I Doubt That!
I Doubt That!
 
Regular expressions
Regular expressionsRegular expressions
Regular expressions
 
Counting on God
Counting on GodCounting on God
Counting on God
 
Unblocked
UnblockedUnblocked
Unblocked
 
Module Magic
Module MagicModule Magic
Module Magic
 
API Design
API DesignAPI Design
API Design
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHub
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in Rails
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And Rendering
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with Rails
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in Rails
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and Controllers
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails Interface
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
Ruby
RubyRuby
Ruby
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on Rails
 

Recently uploaded

Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

In the Back of Your Mind

  • 1. IN THE BACK OF YOUR MIND beanstalkd and 0MQ through the Dominic System
  • 2.
  • 4. LEARN HOW TO IMPROVE YOUR MIND A book I am currently reading
  • 6. MEMORY TECHNIQUES • The book includes various techniques for improving memory
  • 7. MEMORY TECHNIQUES • The book includes various techniques for improving memory • Ithelps to translate abstract data (the brain is weak with) into vivid images (a strength of the brain)
  • 8. MEMORY TECHNIQUES • The book includes various techniques for improving memory • Ithelps to translate abstract data (the brain is weak with) into vivid images (a strength of the brain) • The Dominic System is used to translate numbers into characters and actions • It can help you memorize large numbers
  • 10. SINGLE DIGITS • Just count through the alphabet • But replace F with S • And skip to N when you hit 9
  • 11. SINGLE DIGITS 1 A 2 B • Just count through the 3 C alphabet 4 D 5 E • But replace F with S 6 S • And skip to N when you 7 G hit 9 8 H 9 N 0 O
  • 13. DOUBLE DIGITS • Convert digit pairs into letters • 15 = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA
  • 14. DOUBLE DIGITS • Convert digit pairs into letters • 15 = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA • Use the letters as initials for a character • AE = Albert Einstein, BG = Bill Gates, CN = Chuck Norris
  • 15. DOUBLE DIGITS • Convert digit pairs into letters • 15 = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA • Use the letters as initials for a character • AE = Albert Einstein, BG = Bill Gates, CN = Chuck Norris • Or use letters to indicate characters in other ways • BC = Jesus Christ, HO = Santa Claus, HA = Julia Sweeney
  • 17. IMAGERY IS KEY • Each digit pair should create an image in your mind
  • 18. IMAGERY IS KEY • Each digit pair should create an image in your mind • The image need to be a character doing their signature action • Chuck Norris performing a roundhouse kick • Santa Claus delivering presents • Julia Sweeney dressing asexually
  • 20. FOUR DIGIT NUMBERS • Tohandle four digit numbers, use the first two for the character and the second two as the action • 2339 = BCCN = Jesus Christ performing a roundhouse kick • 8081 = HOHA = Santa Claus dressing asexually
  • 21. FOUR DIGIT NUMBERS • Tohandle four digit numbers, use the first two for the character and the second two as the action • 2339 = BCCN = Jesus Christ performing a roundhouse kick • 8081 = HOHA = Santa Claus dressing asexually • You’re up to a 10,000 number memory at this point!
  • 23. LARGER NUMBERS • “Chunk” up bigger numbers into two and four digit groups
  • 24. LARGER NUMBERS • “Chunk” up bigger numbers into two and four digit groups • Build wacky stories using those characters and actions • 27808039 = 2780 8039 = BGHO HOCN = Bill Gates started delivering presents, but this angered Santa Claus who gave him a roundhouse kick.
  • 25. A CAST OF CHARACTERS
  • 26. A CAST OF CHARACTERS http://ron.ludism.org/mnemonics_public.txt … 40 = DO = Fred Flintstone, breaking rocks in the quarry (Yabba dabba DOo!) 41 = DA = Douglas Adams, putting a Babelfish into his ear (_The Hitch Hiker's Guide to the Galaxy_) 42 = DB = PERSONAL 43 = DC = George Washington, chopping down cherry tree (Washington DC) 44 = DD = Danny Dunn (fictional character), descending in a bathysphere 45 = DE = PERSONAL 46 = DS = Ivan Stang (a.k.a. Doug Smith), ranting on a soapbox 47 = DG = PERSONAL 48 = DH = Douglas Hofstadter, recursively holding a picture of himself 49 = DN = Dan (_Roseanne_ TV show), wearing sunglasses to switch on Christmas lights …
  • 27. A CAST OF CHARACTERS http://ron.ludism.org/mnemonics_public.txt … 40 = DO = Fred Flintstone, breaking rocks in the quarry (Yabba dabba DOo!) 41 = DA = Douglas Adams, putting a Babelfish into his ear (_The Hitch Hiker's Guide to the Galaxy_) 42 = DB = PERSONAL 43 = DC = George Washington, chopping down cherry tree (Washington DC) 44 = DD = Danny Dunn (fictional character), descending in a bathysphere 45 = DE = PERSONAL 46 = DS = Ivan Stang (a.k.a. Doug Smith), ranting on a soapbox 47 = DG = PERSONAL 48 = DH = Douglas Hofstadter, recursively holding a picture of himself 49 = DN = Dan (_Roseanne_ TV show), wearing sunglasses to switch on Christmas lights …
  • 28.
  • 31. BEANSTALKD •A simple but highly effective message queue
  • 32. BEANSTALKD •A simple but highly effective message queue • I’ve used it many times, including to do moves in Go vs Go
  • 33. BEANSTALKD •A simple but highly effective message queue • I’ve used it many times, including to do moves in Go vs Go • It’s definitely one of my favorite tools for background jobs
  • 35. CHARACTER LOOKUPS require "open-uri" def lookup_table return @lookup_table if defined? @lookup_table @lookup_table = { } open("http://ron.ludism.org/mnemonics_public.txt") do |page| page.each do |line| if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/ @lookup_table[$1] = $2 elsif line =~ /As+(.+)/ @lookup_table.values.last << " #{$1}" end end end @lookup_table end
  • 36. CHARACTER LOOKUPS require "open-uri" def lookup_table return @lookup_table if defined? @lookup_table @lookup_table = { } open("http://ron.ludism.org/mnemonics_public.txt") do |page| page.each do |line| if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/ @lookup_table[$1] = $2 elsif line =~ /As+(.+)/ @lookup_table.values.last << " #{$1}" end end end @lookup_table end
  • 37. CHARACTER LOOKUPS require "open-uri" def lookup_table return @lookup_table if defined? @lookup_table @lookup_table = { } open("http://ron.ludism.org/mnemonics_public.txt") do |page| page.each do |line| if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/ @lookup_table[$1] = $2 elsif line =~ /As+(.+)/ @lookup_table.values.last << " #{$1}" end end end @lookup_table end
  • 39. ENCODING CHUNKS def encode(n, as = :both) if n.size == 4 and as == :both "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}." elsif as == :both "#{encode(n, :character)} #{encode(n, :action)}." elsif as == :character lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1] elsif as == :action lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] end end
  • 40. ENCODING CHUNKS def encode(n, as = :both) if n.size == 4 and as == :both "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}." elsif as == :both "#{encode(n, :character)} #{encode(n, :action)}." elsif as == :character lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1] elsif as == :action lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] end end
  • 41. ENCODING CHUNKS def encode(n, as = :both) if n.size == 4 and as == :both "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}." elsif as == :both "#{encode(n, :character)} #{encode(n, :action)}." elsif as == :character lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1] elsif as == :action lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] end end
  • 43. ENCODING NUMBERS job "number.encode" do |args| number = args["number"].to_s.delete("^0-9") number = "0#{number}" if (number.size % 2).nonzero? chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2) encodings = [ ] chunks.permutation.to_a.uniq.each do |grouping| encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/) .captures .map { |n| encode(n) } .join(" ") .tr("_", '"') end Stalker.enqueue( "number.display", number: args["number"], encodings: encodings ) end
  • 44. ENCODING NUMBERS job "number.encode" do |args| number = args["number"].to_s.delete("^0-9") number = "0#{number}" if (number.size % 2).nonzero? chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2) encodings = [ ] chunks.permutation.to_a.uniq.each do |grouping| encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/) .captures .map { |n| encode(n) } .join(" ") .tr("_", '"') end Stalker.enqueue( "number.display", number: args["number"], encodings: encodings ) end
  • 45. ENCODING NUMBERS job "number.encode" do |args| number = args["number"].to_s.delete("^0-9") number = "0#{number}" if (number.size % 2).nonzero? chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2) encodings = [ ] chunks.permutation.to_a.uniq.each do |grouping| encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/) .captures .map { |n| encode(n) } .join(" ") .tr("_", '"') end Stalker.enqueue( "number.display", number: args["number"], encodings: encodings ) end
  • 46. ENCODING NUMBERS job "number.encode" do |args| number = args["number"].to_s.delete("^0-9") number = "0#{number}" if (number.size % 2).nonzero? chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2) encodings = [ ] chunks.permutation.to_a.uniq.each do |grouping| encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/) .captures .map { |n| encode(n) } .join(" ") .tr("_", '"') end Stalker.enqueue( "number.display", number: args["number"], encodings: encodings ) end
  • 48. DISPLAYING ENCODINGS job "number.display" do |args| Array(args["encodings"]).each do |encoded| puts "#{args['number']}:" puts encoded puts end end
  • 50. QUEUING NUMBERS abort "USAGE: #{$PROGRAM_NAME} NUMBER" if ARGV.empty? require "stalker" Stalker.enqueue("number.encode", number: ARGV.shift)
  • 53. RUNNING JOBS $ beanstalkd $ ruby encode_number.rb 405-285-0536
  • 54. RUNNING JOBS $ beanstalkd $ ruby encode_number.rb 405-285-0536 $ rvm 1.9.2 $ RUBYLIB=. stalk jobs.rb number.encode [2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ] [2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536) [2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • 55. RUNNING JOBS $ beanstalkd $ ruby encode_number.rb 405-285-0536 $ rvm 1.9.2 $ RUBYLIB=. stalk jobs.rb number.encode [2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ] [2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536) [2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • 56. RUNNING JOBS $ beanstalkd $ ruby encode_number.rb 405-285-0536 $ rvm 1.9.2 $ RUBYLIB=. stalk jobs.rb number.encode [2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ] [2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536) [2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • 57. RUNNING JOBS $ beanstalkd $ ruby encode_number.rb 405-285-0536 $ rvm 1.9.2 $ RUBYLIB=. stalk jobs.rb number.encode [2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ] [2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536) [2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • 58. RUNNING JOBS $ beanstalkd $ ruby encode_number.rb 405-285-0536 $ rvm 1.9.2 $ RUBYLIB=. stalk jobs.rb number.encode [2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ] [2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536) [2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • 59. RUNNING JOBS $ beanstalkd $ ruby encode_number.rb 405-285-0536 $ rvm 1.9.2 $ RUBYLIB=. stalk jobs.rb number.encode [2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ] [2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536) [2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • 60. RUNNING JOBS $ beanstalkd $ ruby encode_number.rb 405-285-0536 $ rvm 1.9.2 $ RUBYLIB=. stalk jobs.rb number.encode [2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ] [2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536) [2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms $ RUBYLIB=. stalk jobs.rb number.display … 405-285-0536: Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!). Stuart Little (tiny fictional mouse wearing street clothes) releasing helium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping into the Wardrobe. …
  • 61. FOR MORE INFORMATION See Railscasts #243
  • 62. FOR MORE INFORMATION See Railscasts #243
  • 64. BEANSTALKD PROS • Extremely lightweight (especially if you drop the Rails stack)
  • 65. BEANSTALKD PROS • Extremely lightweight (especially if you drop the Rails stack) • Ridiculously fast
  • 66. BEANSTALKD PROS • Extremely lightweight (especially if you drop the Rails stack) • Ridiculously fast • Designed to be a queue
  • 67. BEANSTALKD PROS • Extremely lightweight (especially if you drop the Rails stack) • Ridiculously fast • Designed to be a queue • “Tubes” make it trivial to divide work or pipeline jobs
  • 68. BEANSTALKD PROS • Extremely lightweight (especially if you drop the Rails stack) • Ridiculously fast • Designed to be a queue • “Tubes” make it trivial to divide work or pipeline jobs • Really easy to spread across ruby versions and environments
  • 70. BEANSTALKD CONS • Not ideal for durable queuing needs (though it does have a binlog)
  • 71. BEANSTALKD CONS • Not ideal for durable queuing needs (though it does have a binlog) • Missing niceties like logging (though Stalker adds logging above beanstalkd)
  • 72. BEANSTALKD CONS • Not ideal for durable queuing needs (though it does have a binlog) • Missing niceties like logging (though Stalker adds logging above beanstalkd) • Needs job introspection
  • 73.
  • 75. 0MQ
  • 76. 0MQ •A high-level socket API over an asynchronous message queue • Request and reply, publish subscribe, and pipeline models
  • 77. 0MQ •A high-level socket API over an asynchronous message queue • Request and reply, publish subscribe, and pipeline models • This was my first time using it (I was curious about it) •I don’t think it’s well suited to this task
  • 78. THE END OF THE PIPELINE
  • 79. THE END OF THE PIPELINE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) up.bind("tcp://127.0.0.1:5000") while message = up.recv puts message end
  • 80. THE END OF THE PIPELINE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) up.bind("tcp://127.0.0.1:5000") while message = up.recv puts message end
  • 81. THE END OF THE PIPELINE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) up.bind("tcp://127.0.0.1:5000") while message = up.recv puts message end
  • 82. THE END OF THE PIPELINE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) up.bind("tcp://127.0.0.1:5000") while message = up.recv puts message end
  • 84. NUMBER LOOKUPS # same lookup_table() as before… def lookup lookup_table.each do |number, character_and_action| return number if yield character_and_action end nil end def character_number(msg) lookup { |ca| msg.start_with? ca[/As*([^,]+(?:([^)]+))?)/, 1] } end def action_number(msg) lookup { |ca| msg.end_with? ca[/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] } end
  • 85. NUMBER LOOKUPS # same lookup_table() as before… def lookup lookup_table.each do |number, character_and_action| return number if yield character_and_action end nil end def character_number(msg) lookup { |ca| msg.start_with? ca[/As*([^,]+(?:([^)]+))?)/, 1] } end def action_number(msg) lookup { |ca| msg.end_with? ca[/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] } end
  • 87. A DECODER def decode(message) message.to_s.strip.split(/.(?:s{2}|n|z)/).map { |chunk| chunk.gsub!(/s+/, " ") character = character_number(chunk) action = action_number(chunk) character == action ? character : "#{character}#{action}" }.join end
  • 89. THE MIDDLE PIPE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) down = zmq.socket(ZMQ::DOWNSTREAM) up.bind("tcp://127.0.0.1:5001") down.connect("tcp://127.0.0.1:5000") while message = up.recv down.send(decode(message)) end
  • 90. THE MIDDLE PIPE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) down = zmq.socket(ZMQ::DOWNSTREAM) up.bind("tcp://127.0.0.1:5001") down.connect("tcp://127.0.0.1:5000") while message = up.recv down.send(decode(message)) end
  • 91. THE MIDDLE PIPE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) down = zmq.socket(ZMQ::DOWNSTREAM) up.bind("tcp://127.0.0.1:5001") down.connect("tcp://127.0.0.1:5000") while message = up.recv down.send(decode(message)) end
  • 92. THE MIDDLE PIPE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) down = zmq.socket(ZMQ::DOWNSTREAM) up.bind("tcp://127.0.0.1:5001") down.connect("tcp://127.0.0.1:5000") while message = up.recv down.send(decode(message)) end
  • 94. THE PIPELINE OPENING require "zmq" zmq = ZMQ::Context.new down = zmq.socket(ZMQ::DOWNSTREAM) down.connect("tcp://127.0.0.1:5001") down.send(ARGF.read)
  • 95. A DATA PIPELINE IN ACTION
  • 96. A DATA PIPELINE IN ACTION $ ruby queue_message.rb Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!). Stuart Little (tiny fictional mouse wearing street clothes) releasing helium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping into the Wardrobe. ^d
  • 97. A DATA PIPELINE IN ACTION $ ruby queue_message.rb Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!). Stuart Little (tiny fictional mouse wearing street clothes) releasing helium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping into the Wardrobe. ^d $ ruby decoder.rb
  • 98. A DATA PIPELINE IN ACTION $ ruby queue_message.rb Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!). Stuart Little (tiny fictional mouse wearing street clothes) releasing helium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping into the Wardrobe. ^d $ ruby decoder.rb $ ruby decoder_display.rb 4052850536
  • 100. 0MQ PROS • Asynchronous messaging primitives for constructing networks
  • 101. 0MQ PROS • Asynchronous messaging primitives for constructing networks • Extremely versatile (can be made to fit most any model)
  • 102. 0MQ PROS • Asynchronous messaging primitives for constructing networks • Extremely versatile (can be made to fit most any model) • Supports many to many connections
  • 103. 0MQ PROS • Asynchronous messaging primitives for constructing networks • Extremely versatile (can be made to fit most any model) • Supports many to many connections • Automatically load balanced
  • 105. 0MQ CONS • Very low-level (really just a platform to build on) • Missing all the conveniences: logging, message formats, etc.
  • 106. 0MQ CONS • Very low-level (really just a platform to build on) • Missing all the conveniences: logging, message formats, etc. • Best for asynchronous networks you design and build
  • 107.

Editor's Notes

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