diff options
Diffstat (limited to 'tests/examplefiles/pleac.in.rb')
-rw-r--r-- | tests/examplefiles/pleac.in.rb | 1223 |
1 files changed, 0 insertions, 1223 deletions
diff --git a/tests/examplefiles/pleac.in.rb b/tests/examplefiles/pleac.in.rb deleted file mode 100644 index d1dea9f4..00000000 --- a/tests/examplefiles/pleac.in.rb +++ /dev/null @@ -1,1223 +0,0 @@ -# -*- ruby -*- - -# Local variables: -# indent-tabs-mode: nil -# ruby-indent-level: 4 -# End: - -# @@PLEAC@@_NAME -# @@SKIP@@ Ruby - -# @@PLEAC@@_WEB -# @@SKIP@@ http://www.ruby-lang.org - - -# @@PLEAC@@_1.0 -string = '\n' # two characters, \ and an n -string = 'Jon \'Maddog\' Orwant' # literal single quotes - -string = "\n" # a "newline" character -string = "Jon \"Maddog\" Orwant" # literal double quotes - -string = %q/Jon 'Maddog' Orwant/ # literal single quotes - -string = %q[Jon 'Maddog' Orwant] # literal single quotes -string = %q{Jon 'Maddog' Orwant} # literal single quotes -string = %q(Jon 'Maddog' Orwant) # literal single quotes -string = %q<Jon 'Maddog' Orwant> # literal single quotes - -a = <<"EOF" -This is a multiline here document -terminated by EOF on a line by itself -EOF - - -# @@PLEAC@@_1.1 -value = string[offset,count] -value = string[offset..-1] - -string[offset,count] = newstring -string[offset..-1] = newtail - -# in Ruby we can also specify intervals by their two offsets -value = string[offset..offs2] -string[offset..offs2] = newstring - -leading, s1, s2, trailing = data.unpack("A5 x3 A8 A8 A*") - -fivers = string.unpack("A5" * (string.length/5)) - -chars = string.unpack("A1" * string.length) - -string = "This is what you have" -# +012345678901234567890 Indexing forwards (left to right) -# 109876543210987654321- Indexing backwards (right to left) -# note that 0 means 10 or 20, etc. above - -first = string[0, 1] # "T" -start = string[5, 2] # "is" -rest = string[13..-1] # "you have" -last = string[-1, 1] # "e" -end_ = string[-4..-1] # "have" -piece = string[-8, 3] # "you" - -string[5, 2] = "wasn't" # change "is" to "wasn't" -string[-12..-1] = "ondrous" # "This wasn't wondrous" -string[0, 1] = "" # delete first character -string[-10..-1] = "" # delete last 10 characters - -if string[-10..-1] =~ /pattern/ - puts "Pattern matches in last 10 characters" -end - -string[0, 5].gsub!(/is/, 'at') - -a = "make a hat" -a[0, 1], a[-1, 1] = a[-1, 1], a[0, 1] - -a = "To be or not to be" -b = a.unpack("x6 A6") - -b, c = a.unpack("x6 A2 X5 A2") -puts "#{b}\n#{c}\n" - -def cut2fmt(*args) - template = '' - lastpos = 1 - for place in args - template += "A" + (place - lastpos).to_s + " " - lastpos = place - end - template += "A*" - return template -end - -fmt = cut2fmt(8, 14, 20, 26, 30) - - -# @@PLEAC@@_1.2 -# careful! "b is true" doesn't mean "b != 0" (0 is true in Ruby) -# thus no problem of "defined" later since only nil is false -# the following sets to `c' if `b' is nil or false -a = b || c - -# if you need Perl's behaviour (setting to `c' if `b' is 0) the most -# effective way is to use Numeric#nonzero? (thanks to Dave Thomas!) -a = b.nonzero? || c - -# you will still want to use defined? in order to test -# for scope existence of a given object -a = defined?(b) ? b : c - -dir = ARGV.shift || "/tmp" - - -# @@PLEAC@@_1.3 -v1, v2 = v2, v1 - -alpha, beta, production = %w(January March August) -alpha, beta, production = beta, production, alpha - - -# @@PLEAC@@_1.4 -num = char[0] -char = num.chr - -# Ruby also supports having a char from character constant -num = ?r - -char = sprintf("%c", num) -printf("Number %d is character %c\n", num, num) - -ascii = string.unpack("C*") -string = ascii.pack("C*") - -hal = "HAL" -ascii = hal.unpack("C*") -# We can't use Array#each since we can't mutate a Fixnum -ascii.collect! { |i| - i + 1 # add one to each ASCII value -} -ibm = ascii.pack("C*") -puts ibm - - -# @@PLEAC@@_1.5 -array = string.split('') - -array = string.unpack("C*") - -string.scan(/./) { |b| - # do something with b -} - -string = "an apple a day" -print "unique chars are: ", string.split('').uniq.sort, "\n" - -sum = 0 -for ascval in string.unpack("C*") # or use Array#each for a pure OO style :) - sum += ascval -end -puts "sum is #{sum & 0xffffffff}" # since Ruby will go Bignum if necessary - -# @@INCLUDE@@ include/ruby/slowcat.rb - - -# @@PLEAC@@_1.6 -revbytes = string.reverse - -revwords = string.split(" ").reverse.join(" ") - -revwords = string.split(/(\s+)/).reverse.join - -# using the fact that IO is Enumerable, you can directly "select" it -long_palindromes = File.open("/usr/share/dict/words"). - select { |w| w.chomp!; w.reverse == w && w.length > 5 } - - -# @@PLEAC@@_1.7 -while string.sub!("\t+") { ' ' * ($&.length * 8 - $`.length % 8) } -end - - -# @@PLEAC@@_1.8 -'You owe #{debt} to me'.gsub(/\#{(\w+)}/) { eval($1) } - -rows, cols = 24, 80 -text = %q(I am #{rows} high and #{cols} long) -text.gsub!(/\#{(\w+)}/) { eval("#{$1}") } -puts text - -'I am 17 years old'.gsub(/\d+/) { 2 * $&.to_i } - - -# @@PLEAC@@_1.9 -e = "bo peep".upcase -e.downcase! -e.capitalize! - -"thIS is a loNG liNE".gsub!(/\w+/) { $&.capitalize } - - -# @@PLEAC@@_1.10 -"I have #{n+1} guanacos." -print "I have ", n+1, " guanacos." - - -# @@PLEAC@@_1.11 -var = <<'EOF'.gsub(/^\s+/, '') - your text - goes here -EOF - - -# @@PLEAC@@_1.12 -string = "Folding and splicing is the work of an editor,\n"+ - "not a mere collection of silicon\n"+ - "and\n"+ - "mobile electrons!" - -def wrap(str, max_size) - all = [] - line = '' - for l in str.split - if (line+l).length >= max_size - all.push(line) - line = '' - end - line += line == '' ? l : ' ' + l - end - all.push(line).join("\n") -end - -print wrap(string, 20) -#=> Folding and -#=> splicing is the -#=> work of an editor, -#=> not a mere -#=> collection of -#=> silicon and mobile -#=> electrons! - - -# @@PLEAC@@_1.13 -string = %q(Mom said, "Don't do that.") -string.gsub(/['"]/) { '\\'+$& } -string.gsub(/['"]/, '\&\&') -string.gsub(/[^A-Z]/) { '\\'+$& } -"is a test!".gsub(/\W/) { '\\'+$& } # no function like quotemeta? - - -# @@PLEAC@@_1.14 -string.strip! - - -# @@PLEAC@@_1.15 -def parse_csv(text) - new = text.scan(/"([^\"\\]*(?:\\.[^\"\\]*)*)",?|([^,]+),?|,/) - new << nil if text[-1] == ?, - new.flatten.compact -end - -line = %q<XYZZY,"","O'Reilly, Inc","Wall, Larry","a \"glug\" bit,",5,"Error, Core Dumped"> -fields = parse_csv(line) -fields.each_with_index { |v,i| - print "#{i} : #{v}\n"; -} - - -# @@PLEAC@@_1.16 -# Use the soundex.rb Library from Michael Neumann. -# http://www.s-direktnet.de/homepages/neumann/rb_prgs/Soundex.rb -require 'Soundex' - -code = Text::Soundex.soundex(string) -codes = Text::Soundex.soundex(array) - -# substitution function for getpwent(): -# returns an array of user entries, -# each entry contains the username and the full name -def login_names - result = [] - File.open("/etc/passwd") { |file| - file.each_line { |line| - next if line.match(/^#/) - cols = line.split(":") - result.push([cols[0], cols[4]]) - } - } - result -end - -puts "Lookup user: " -user = STDIN.gets -user.chomp! -exit unless user -name_code = Text::Soundex.soundex(user) - -splitter = Regexp.new('(\w+)[^,]*\b(\w+)') -for username, fullname in login_names do - firstname, lastname = splitter.match(fullname)[1,2] - if name_code == Text::Soundex.soundex(username) - || name_code == Text::Soundex.soundex(firstname) - || name_code == Text::Soundex.soundex(lastname) - then - puts "#{username}: #{firstname} #{lastname}" - end -end - - -# @@PLEAC@@_1.17 -# @@INCLUDE@@ include/ruby/fixstyle.rb - - -# @@PLEAC@@_1.18 -# @@INCLUDE@@ include/ruby/psgrep.rb - - -# @@PLEAC@@_2.1 -# Matz tells that you can use Integer() for strict checked conversion. -Integer("abc") -#=> `Integer': invalid value for Integer: "abc" (ArgumentError) -Integer("567") -#=> 567 - -# You may use Float() for floating point stuff -Integer("56.7") -#=> `Integer': invalid value for Integer: "56.7" (ArgumentError) -Float("56.7") -#=> 56.7 - -# You may also use a regexp for that -if string =~ /^[+-]?\d+$/ - p 'is an integer' -else - p 'is not' -end - -if string =~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ - p 'is a decimal number' -else - p 'is not' -end - - -# @@PLEAC@@_2.2 -# equal(num1, num2, accuracy) : returns true if num1 and num2 are -# equal to accuracy number of decimal places -def equal(i, j, a) - sprintf("%.#{a}g", i) == sprintf("%.#{a}g", j) -end - -wage = 536 # $5.36/hour -week = 40 * wage # $214.40 -printf("One week's wage is: \$%.2f\n", week/100.0) - - -# @@PLEAC@@_2.3 -num.round # rounds to integer - -a = 0.255 -b = sprintf("%.2f", a) -print "Unrounded: #{a}\nRounded: #{b}\n" -printf "Unrounded: #{a}\nRounded: %.2f\n", a - -print "number\tint\tfloor\tceil\n" -a = [ 3.3 , 3.5 , 3.7, -3.3 ] -for n in a - printf("% .1f\t% .1f\t% .1f\t% .1f\n", # at least I don't fake my output :) - n, n.to_i, n.floor, n.ceil) -end - - -# @@PLEAC@@_2.4 -def dec2bin(n) - [n].pack("N").unpack("B32")[0].sub(/^0+(?=\d)/, '') -end - -def bin2dec(n) - [("0"*32+n.to_s)[-32..-1]].pack("B32").unpack("N")[0] -end - - -# @@PLEAC@@_2.5 -for i in x .. y - # i is set to every integer from x to y, inclusive -end - -x.step(y,7) { |i| - # i is set to every integer from x to y, stepsize = 7 -} - -print "Infancy is: " -(0..2).each { |i| - print i, " " -} -print "\n" - - -# @@PLEAC@@_2.6 -# We can add conversion methods to the Integer class, -# this makes a roman number just a representation for normal numbers. -class Integer - - @@romanlist = [["M", 1000], - ["CM", 900], - ["D", 500], - ["CD", 400], - ["C", 100], - ["XC", 90], - ["L", 50], - ["XL", 40], - ["X", 10], - ["IX", 9], - ["V", 5], - ["IV", 4], - ["I", 1]] - - def to_roman - remains = self - roman = "" - for sym, num in @@romanlist - while remains >= num - remains -= num - roman << sym - end - end - roman - end - - def Integer.from_roman(roman) - ustr = roman.upcase - sum = 0 - for entry in @@romanlist - sym, num = entry[0], entry[1] - while sym == ustr[0, sym.length] - sum += num - ustr.slice!(0, sym.length) - end - end - sum - end - -end - - -roman_fifteen = 15.to_roman -puts "Roman for fifteen is #{roman_fifteen}" -i = Integer.from_roman(roman_fifteen) -puts "Converted back, #{roman_fifteen} is #{i}" - -# check -for i in (1..3900) - r = i.to_roman - j = Integer.from_roman(r) - if i != j - puts "error: #{i} : #{r} - #{j}" - end -end - - -# @@PLEAC@@_2.7 -random = rand(y-x+1)+x - -chars = ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!@$%^&*) -password = (1..8).collect { chars[rand(chars.size)] }.pack("C*") - - -# @@PLEAC@@_2.8 -srand # uses a combination of the time, the process id, and a sequence number -srand(val) # for repeatable behaviour - - -# @@PLEAC@@_2.9 -# from the randomr lib: -# http://raa.ruby-lang.org/project/randomr/ -----> http://raa.ruby-lang.org/project/randomr/ - -require 'random/mersenne_twister' -mers = Random::MersenneTwister.new 123456789 -puts mers.rand(0) # 0.550321932544541 -puts mers.rand(10) # 2 - -# using online sources of random data via the realrand package: -# http://raa.ruby-lang.org/project/realrand/ -# **Note** -# The following online services are used in this package: -# http://www.random.org - source: atmospheric noise -# http://www.fourmilab.ch/hotbits - source: radioactive decay timings -# http://random.hd.org - source: entropy from local and network noise -# Please visit the sites and respect the rules of each service. - -require 'random/online' - -generator1 = Random::RandomOrg.new -puts generator1.randbyte(5).join(",") -puts generator1.randnum(10, 1, 6).join(",") # Roll dice 10 times. - -generator2 = Random::FourmiLab.new -puts generator2.randbyte(5).join(",") -# randnum is not supported. - -generator3 = Random::EntropyPool.new -puts generator3.randbyte(5).join(",") -# randnum is not supported. - - -# @@PLEAC@@_2.10 -def gaussian_rand - begin - u1 = 2 * rand() - 1 - u2 = 2 * rand() - 1 - w = u1*u1 + u2*u2 - end while (w >= 1) - w = Math.sqrt((-2*Math.log(w))/w) - [ u2*w, u1*w ] -end - -mean = 25 -sdev = 2 -salary = gaussian_rand[0] * sdev + mean -printf("You have been hired at \$%.2f\n", salary) - - -# @@PLEAC@@_2.11 -def deg2rad(d) - (d/180.0)*Math::PI -end - -def rad2deg(r) - (r/Math::PI)*180 -end - - -# @@PLEAC@@_2.12 -sin_val = Math.sin(angle) -cos_val = Math.cos(angle) -tan_val = Math.tan(angle) - -# AFAIK Ruby's Math module doesn't provide acos/asin -# While we're at it, let's also define missing hyperbolic functions -module Math - def Math.asin(x) - atan2(x, sqrt(1 - x**2)) - end - def Math.acos(x) - atan2(sqrt(1 - x**2), x) - end - def Math.atan(x) - atan2(x, 1) - end - def Math.sinh(x) - (exp(x) - exp(-x)) / 2 - end - def Math.cosh(x) - (exp(x) + exp(-x)) / 2 - end - def Math.tanh(x) - sinh(x) / cosh(x) - end -end - -# The support for Complex numbers is not built-in -y = Math.acos(3.7) -#=> in `sqrt': square root for negative number (ArgumentError) - -# There is an implementation of Complex numbers in 'complex.rb' in current -# Ruby distro, but it doesn't support atan2 with complex args, so it doesn't -# solve this problem. - - -# @@PLEAC@@_2.13 -log_e = Math.log(val) -log_10 = Math.log10(val) - -def log_base(base, val) - Math.log(val)/Math.log(base) -end - -answer = log_base(10, 10_000) -puts "log10(10,000) = #{answer}" - - -# @@PLEAC@@_2.14 -require 'matrix.rb' - -a = Matrix[[3, 2, 3], [5, 9, 8]] -b = Matrix[[4, 7], [9, 3], [8, 1]] -c = a * b - -a.row_size -a.column_size - -c.det -a.transpose - - -# @@PLEAC@@_2.15 -require 'complex.rb' -require 'rational.rb' - -a = Complex(3, 5) # 3 + 5i -b = Complex(2, -2) # 2 - 2i -puts "c = #{a*b}" - -c = a * b -d = 3 + 4*Complex::I - -printf "sqrt(#{d}) = %s\n", Math.sqrt(d) - - -# @@PLEAC@@_2.16 -number = hexadecimal.hex -number = octal.oct - -print "Gimme a number in decimal, octal, or hex: " -num = gets.chomp -exit unless defined?(num) -num = num.oct if num =~ /^0/ # does both oct and hex -printf "%d %x %o\n", num, num, num - -print "Enter file permission in octal: " -permissions = gets.chomp -raise "Exiting ...\n" unless defined?(permissions) -puts "The decimal value is #{permissions.oct}" - - -# @@PLEAC@@_2.17 -def commify(n) - n.to_s =~ /([^\.]*)(\..*)?/ - int, dec = $1.reverse, $2 ? $2 : "" - while int.gsub!(/(,|\.|^)(\d{3})(\d)/, '\1\2,\3') - end - int.reverse + dec -end - - -# @@PLEAC@@_2.18 -printf "It took %d hour%s\n", time, time == 1 ? "" : "s" - -# dunno if an equivalent to Lingua::EN::Inflect exists... - - -# @@PLEAC@@_2.19 -#----------------------------- -#!/usr/bin/ruby -# bigfact - calculating prime factors -def factorize(orig) - factors = {} - factors.default = 0 # return 0 instead nil if key not found in hash - n = orig - i = 2 - sqi = 4 # square of i - while sqi <= n do - while n.modulo(i) == 0 do - n /= i - factors[i] += 1 - # puts "Found factor #{i}" - end - # we take advantage of the fact that (i +1)**2 = i**2 + 2*i +1 - sqi += 2 * i + 1 - i += 1 - end - - if (n != 1) && (n != orig) - factors[n] += 1 - end - factors -end - -def printfactorhash(orig, factorcount) - print format("%-10d ", orig) - if factorcount.length == 0 - print "PRIME" - else - # sorts after number, because the hash keys are numbers - factorcount.sort.each { |factor,exponent| - print factor - if exponent > 1 - print "**", exponent - end - print " " - } - end - puts -end - -for arg in ARGV - n = arg.to_i - mfactors = factorize(n) - printfactorhash(n, mfactors) -end -#----------------------------- - - -# @@PLEAC@@_3.0 -puts Time.now - -print "Today is day ", Time.now.yday, " of the current year.\n" -print "Today is day ", Time.now.day, " of the current month.\n" - - -# @@PLEAC@@_3.1 -day, month, year = Time.now.day, Time.now.month, Time.now.year -# or -day, month, year = Time.now.to_a[3..5] - -tl = Time.now.localtime -printf("The current date is %04d %02d %02d\n", tl.year, tl.month, tl.day) - -Time.now.localtime.strftime("%Y-%m-%d") - - -# @@PLEAC@@_3.2 -Time.local(year, month, day, hour, minute, second).tv_sec -Time.gm(year, month, day, hour, minute, second).tv_sec - - -# @@PLEAC@@_3.3 -sec, min, hour, day, month, year, wday, yday, isdst, zone = Time.at(epoch_secs).to_a - - -# @@PLEAC@@_3.4 -when_ = now + difference # now -> Time ; difference -> Numeric (delta in seconds) -then_ = now - difference - - -# @@PLEAC@@_3.5 -bree = 361535725 -nat = 96201950 - -difference = bree - nat -puts "There were #{difference} seconds between Nat and Bree" - -seconds = difference % 60 -difference = (difference - seconds) / 60 -minutes = difference % 60 -difference = (difference - minutes) / 60 -hours = difference % 24 -difference = (difference - hours) / 24 -days = difference % 7 -weeks = (difference - days) / 7 - -puts "(#{weeks} weeks, #{days} days, #{hours}:#{minutes}:#{seconds})" - - -# @@PLEAC@@_3.6 -monthday, weekday, yearday = date.mday, date.wday, date.yday - -# AFAIK the week number is not just a division since week boundaries are on sundays -weeknum = d.strftime("%U").to_i + 1 - -year = 1981 -month = "jun" # or `6' if you want to emulate a broken language -day = 16 -t = Time.mktime(year, month, day) -print "#{month}/#{day}/#{year} was a ", t.strftime("%A"), "\n" - - -# @@PLEAC@@_3.7 -yyyy, mm, dd = $1, $2, $3 if "1998-06-25" =~ /(\d+)-(\d+)-(\d+)/ - -epoch_seconds = Time.mktime(yyyy, mm, dd).tv_sec - -# dunno an equivalent to Date::Manip#ParseDate - - -# @@PLEAC@@_3.8 -string = Time.at(epoch_secs) -Time.at(1234567890).gmtime # gives: Fri Feb 13 23:31:30 UTC 2009 - -time = Time.mktime(1973, "jan", 18, 3, 45, 50) -print "In localtime it gives: ", time.localtime, "\n" - - -# @@PLEAC@@_3.9 -# Ruby provides micro-seconds in Time object -Time.now.usec - -# Ruby gives the seconds in floating format when substracting two Time objects -before = Time.now -line = gets -elapsed = Time.now - before -puts "You took #{elapsed} seconds." - -# On my Celeron-400 with Linux-2.2.19-14mdk, average for three execs are: -# This Ruby version: average 0.00321 sec -# Cookbook's Perl version: average 0.00981 sec -size = 500 -number_of_times = 100 -total_time = 0 -number_of_times.times { - # populate array - array = [] - size.times { array << rand } - # sort it - begin_ = Time.now - array.sort! - time = Time.now - begin_ - total_time += time -} -printf "On average, sorting %d random numbers takes %.5f seconds\n", - size, (total_time/Float(number_of_times)) - - -# @@PLEAC@@_3.10 -sleep(0.005) # Ruby is definitely not as broken as Perl :) -# (may be interrupted by sending the process a SIGALRM) - - -# @@PLEAC@@_3.11 -#!/usr/bin/ruby -w -# hopdelta - feed mail header, produce lines -# showing delay at each hop. -require 'time' -class MailHopDelta - - def initialize(mail) - @head = mail.gsub(/\n\s+/,' ') - @topline = %w-Sender Recipient Time Delta- - @start_from = mail.match(/^From.*\@([^\s>]*)/)[1] - @date = Time.parse(mail.match(/^Date:\s+(.*)/)[1]) - end - - def out(line) - "%-20.20s %-20.20s %-20.20s %s" % line - end - - def hop_date(day) - day.strftime("%I:%M:%S %Y/%m/%d") - end - - def puts_hops - puts out(@topline) - puts out(['Start', @start_from, hop_date(@date),'']) - @head.split(/\n/).reverse.grep(/^Received:/).each do |hop| - hop.gsub!(/\bon (.*?) (id.*)/,'; \1') - whence = hop.match(/;\s+(.*)$/)[1] - unless whence - warn "Bad received line: #{hop}" - next - end - from = $+ if hop =~ /from\s+(\S+)|\((.*?)\)/ - by = $1 if hop =~ /by\s+(\S+\.\S+)/ - next unless now = Time.parse(whence).localtime - delta = now - @date - puts out([from, by, hop_date(now), hop_time(delta)]) - @date = now - end - end - - def hop_time(secs) - sign = secs < 0 ? -1 : 1 - days, secs = secs.abs.divmod(60 * 60 * 24) - hours,secs = secs.abs.divmod(60 * 60) - mins, secs = secs.abs.divmod(60) - rtn = "%3ds" % [secs * sign] - rtn << "%3dm" % [mins * sign] if mins != 0 - rtn << "%3dh" % [hours * sign] if hours != 0 - rtn << "%3dd" % [days * sign] if days != 0 - rtn - end -end - -$/ = "" -mail = MailHopDelta.new(ARGF.gets).puts_hops - - -# @@PLEAC@@_4.0 -single_level = [ "this", "that", "the", "other" ] - -# Ruby directly supports nested arrays -double_level = [ "this", "that", [ "the", "other" ] ] -still_single_level = [ "this", "that", [ "the", "other" ] ].flatten - - -# @@PLEAC@@_4.1 -a = [ "quick", "brown", "fox" ] -a = %w(Why are you teasing me?) - -lines = <<"END_OF_HERE_DOC".gsub(/^\s*(.+)/, '\1') - The boy stood on the burning deck, - It was as hot as glass. -END_OF_HERE_DOC - -bigarray = IO.readlines("mydatafile").collect { |l| l.chomp } - -name = "Gandalf" -banner = %Q(Speak, #{name}, and welcome!) - -host_info = `host #{his_host}` - -%x(ps #{$$}) - -banner = 'Costs only $4.95'.split(' ') - -rax = %w! ( ) < > { } [ ] ! - - -# @@PLEAC@@_4.2 -def commify_series(arr) - return '' if not arr - case arr.size - when 0 then '' - when 1 then arr[0] - when 2 then arr.join(' and ') - else arr[0..-2].join(', ') + ', and ' + arr[-1] - end -end - -array = [ "red", "yellow", "green" ] - -print "I have ", array, " marbles\n" -# -> I have redyellowgreen marbles - -# But unlike Perl: -print "I have #{array} marbles\n" -# -> I have redyellowgreen marbles -# So, needs: -print "I have #{array.join(' ')} marbles\n" -# -> I have red yellow green marbles - -#!/usr/bin/ruby -# communify_series - show proper comma insertion in list output - -def commify_series(arr) - return '' if not arr - sepchar = arr.find { |p| p =~ /,/ } ? '; ' : ', ' - case arr.size - when 0 then '' - when 1 then arr[0] - when 2 then arr.join(' and ') - else arr[0..-2].join(sepchar) + sepchar + 'and ' + arr[-1] - end -end - -lists = [ - [ 'just one thing' ], - %w(Mutt Jeff), - %w(Peter Paul Mary), - [ 'To our parents', 'Mother Theresa', 'God' ], - [ 'pastrami', 'ham and cheese', 'peanut butter and jelly', 'tuna' ], - [ 'recycle tired, old phrases', 'ponder big, happy thoughts' ], - [ 'recycle tired, old phrases', - 'ponder big, happy thoughts', - 'sleep and dream peacefully' ], -] - -for list in lists do - puts "The list is: #{commify_series(list)}." -end - - -# @@PLEAC@@_4.3 -# (note: AFAIK Ruby doesn't allow gory change of Array length) -# grow the array by assigning nil to past the end of array -ary[new_size-1] = nil -# shrink the array by slicing it down -ary.slice!(new_size..-1) -# init the array with given size -Array.new(number_of_elems) -# assign to an element past the original end enlarges the array -ary[index_new_last_elem] = value - -def what_about_that_array(a) - print "The array now has ", a.size, " elements.\n" - # Index of last element is not really interesting in Ruby - print "Element #3 is `#{a[3]}'.\n" -end -people = %w(Crosby Stills Nash Young) -what_about_that_array(people) - - -# @@PLEAC@@_4.4 -# OO style -bad_users.each { |user| - complain(user) -} -# or, functional style -for user in bad_users - complain(user) -end - -for var in ENV.keys.sort - puts "#{var}=#{ENV[var]}" -end - -for user in all_users - disk_space = get_usage(user) - if (disk_space > MAX_QUOTA) - complain(user) - end -end - -for l in IO.popen("who").readlines - print l if l =~ /^gc/ -end - -# we can mimic the obfuscated Perl way -while fh.gets # $_ is set to the line just read - chomp # $_ has a trailing \n removed, if it had one - split.each { |w| # $_ is split on whitespace - # but $_ is not set to each chunk as in Perl - print w.reverse - } -end -# ...or use a cleaner way -for l in fh.readlines - l.chomp.split.each { |w| print w.reverse } -end - -# same drawback as in problem 1.4, we can't mutate a Numeric... -array.collect! { |v| v - 1 } - -a = [ .5, 3 ]; b = [ 0, 1 ] -for ary in [ a, b ] - ary.collect! { |v| v * 7 } -end -puts "#{a.join(' ')} #{b.join(' ')}" - -# we can mutate Strings, cool; we need a trick for the scalar -for ary in [ [ scalar ], array, hash.values ] - ary.each { |v| v.strip! } # String#strip rules :) -end - - -# @@PLEAC@@_4.5 -# not relevant in Ruby since we have always references -for item in array - # do somethingh with item -end - - -# @@PLEAC@@_4.6 -unique = list.uniq - -# generate a list of users logged in, removing duplicates -users = `who`.collect { |l| l =~ /(\w+)/; $1 }.sort.uniq -puts("users logged in: #{commify_series(users)}") # see 4.2 for commify_series - - -# @@PLEAC@@_4.7 -a - b -# [ 1, 1, 2, 2, 3, 3, 3, 4, 5 ] - [ 1, 2, 4 ] -> [3, 5] - - -# @@PLEAC@@_4.8 -union = a | b -intersection = a & b -difference = a - b - - -# @@PLEAC@@_4.9 -array1.concat(array2) -# if you will assign to another object, better use: -new_ary = array1 + array2 - -members = [ "Time", "Flies" ] -initiates = [ "An", "Arrow" ] -members += initiates - -members = [ "Time", "Flies" ] -initiates = [ "An", "Arrow" ] -members[2,0] = [ "Like", initiates ].flatten - -members[0] = "Fruit" -members[3,2] = "A", "Banana" - - -# @@PLEAC@@_4.10 -reversed = ary.reverse - -ary.reverse_each { |e| - # do something with e -} - -descending = ary.sort.reverse -descending = ary.sort { |a,b| b <=> a } - - -# @@PLEAC@@_4.11 -# remove n elements from front of ary (shift n) -front = ary.slice!(0, n) - -# remove n elements from the end of ary (pop n) -end_ = ary.slice!(-n .. -1) - -# let's extend the Array class, to make that useful -class Array - def shift2() - slice!(0 .. 1) # more symetric with pop2... - end - def pop2() - slice!(-2 .. -1) - end -end - -friends = %w(Peter Paul Mary Jim Tim) -this, that = friends.shift2 - -beverages = %w(Dew Jolt Cola Sprite Fresca) -pair = beverages.pop2 - - -# @@PLEAC@@_4.12 -# use Enumerable#detect (or the synonym Enumerable#find) -highest_eng = employees.detect { |emp| emp.category == 'engineer' } - - -# @@PLEAC@@_4.13 -# use Enumerable#select (or the synonym Enumerable#find_all) -bigs = nums.select { |i| i > 1_000_000 } -pigs = users.keys.select { |k| users[k] > 1e7 } - -matching = `who`.select { |u| u =~ /^gnat / } - -engineers = employees.select { |e| e.position == 'Engineer' } - -secondary_assistance = applicants.select { |a| - a.income >= 26_000 && a.income < 30_000 -} - - -# @@PLEAC@@_4.14 -# normally you would have an array of Numeric (Float or -# Fixnum or Bignum), so you would use: -sorted = unsorted.sort -# if you have strings representing Integers or Floats -# you may specify another sort method: -sorted = unsorted.sort { |a,b| a.to_f <=> b.to_f } - -# let's use the list of my own PID's -`ps ux`.split("\n")[1..-1]. - select { |i| i =~ /^#{ENV['USER']}/ }. - collect { |i| i.split[1] }. - sort { |a,b| a.to_i <=> b.to_i }.each { |i| puts i } -puts "Select a process ID to kill:" -pid = gets.chomp -raise "Exiting ... \n" unless pid && pid =~ /^\d+$/ -Process.kill('TERM', pid.to_i) -sleep 2 -Process.kill('KILL', pid.to_i) - -descending = unsorted.sort { |a,b| b.to_f <=> a.to_f } - - -# @@PLEAC@@_4.15 -ordered = unordered.sort { |a,b| compare(a,b) } - -precomputed = unordered.collect { |e| [compute, e] } -ordered_precomputed = precomputed.sort { |a,b| a[0] <=> b[0] } -ordered = ordered_precomputed.collect { |e| e[1] } - -ordered = unordered.collect { |e| [compute, e] }. - sort { |a,b| a[0] <=> b[0] }. - collect { |e| e[1] } - -for employee in employees.sort { |a,b| a.name <=> b.name } - print employee.name, " earns \$ ", employee.salary, "\n" -end - -# Beware! `0' is true in Ruby. -# For chaining comparisons, you may use Numeric#nonzero?, which -# returns num if num is not zero, nil otherwise -sorted = employees.sort { |a,b| (a.name <=> b.name).nonzero? || b.age <=> a.age } - -users = [] -# getpwent is not wrapped in Ruby... let's fallback -IO.readlines('/etc/passwd').each { |u| users << u.split(':') } -users.sort! { |a,b| a[0] <=> b[0] } -for user in users - puts user[0] -end - -sorted = names.sort { |a,b| a[1, 1] <=> b[1, 1] } -sorted = strings.sort { |a,b| a.length <=> b.length } - -# let's show only the compact version -ordered = strings.collect { |e| [e.length, e] }. - sort { |a,b| a[0] <=> b[0] }. - collect { |e| e[1] } - -ordered = strings.collect { |e| [/\d+/.match(e)[0].to_i, e] }. - sort { |a,b| a[0] <=> b[0] }. - collect { |e| e[1] } - -print `cat /etc/passwd`.collect { |e| [e, e.split(':').indexes(3,2,0)].flatten }. - sort { |a,b| (a[1] <=> b[1]).nonzero? || (a[2] <=> b[2]).nonzero? || a[3] <=> b[3] }. - collect { |e| e[0] } - - -# @@PLEAC@@_4.16 -circular.unshift(circular.pop) # the last shall be first -circular.push(circular.shift) # and vice versa - -def grab_and_rotate(l) - l.push(ret = l.shift) - ret -end - -processes = [1, 2, 3, 4, 5] -while (1) - process = grab_and_rotate(processes) - puts "Handling process #{process}" - sleep 1 -end - - -# @@PLEAC@@_4.17 -def fisher_yates_shuffle(a) - (a.size-1).downto(1) { |i| - j = rand(i+1) - a[i], a[j] = a[j], a[i] if i != j - } -end - -def naive_shuffle(a) - for i in 0...a.size - j = rand(a.size) - a[i], a[j] = a[j], a[i] - end -end - - |