SZIMP2 Ruby

A MathWikiből
A lap korábbi változatát látod, amilyen SzaboPeter (vitalap | szerkesztései) 2007. május 10., 00:25-kor történt szerkesztése után volt.

A tárgy főoldala: SZIMP2

Tartalomjegyzék

8. előadás (2007-04-06)

Az objektum-orientált programozás elméleti bevezetője hangzott el, és a matmul feladat megoldása felkerült a táblára Ruby nyelven.

Néhány új fogalom:

  • osztály (a C-beli struktúratípusnak felel meg)
  • objektum (a C-beli struktúrának felel meg)
  • attribútum (a C-beli struktúramezőnek felel meg)
  • metódus (a C-beli függvénynek felel meg)

9. gyakorlat (2007-04-10, 2007-04-13)

lepcso.rb:

n=7
l=[[1],
   [2,3],
   [4,5,6],
   ...
  ]
# l.size==n
p l

9. előadás (2007-04-13)

Objektum-orientáltan kezdtünk programozni Ruby nyelven, a Sikidom, BBox és Kor osztályok kerültek fel a táblára. Megismertük a szemétgyűjtést (garbage collection) is. Láttunk példát rá, hogy két változó mutathat ugyanarra az objektumra.

class BBox
  attr_accessor :llx, :lly, :urx, :ury
end

class Sikidom
  def bbox()
    fail  # még nem tudjuk megírni, a Sikidom túl absztrakt
  end
  def kerulet()
    fail  # még nem tudjuk megírni, a Sikidom túl absztrakt
  end
  def terulet()
    fail  # még nem tudjuk megírni, a Sikidom túl absztrakt
  end
end

class Kor <Sikidom
  attr_accessor :cx, :cy, :r
  def bbox()
    b=BBox.new
    b.llx=@cx-@r; b.lly=@cy-@r
    b.urx=@cx+@r; b.ury=@cy+@r
    return b  # a return fölösleges
  end
  def kerulet()
    Math::PI*2*@r
  end
  def terulet()
    Math::PI*@r*@r
  end
end

10. gyakorlat (2007-04-17, 2007-04-20)

A Szórt Spektrum a Háztetőn Csillagjós és Rádióamatőr Klub holnap Guinness-rekordkísérletre készül: annyi űrturistával kívánják felvenni a kapcsolatot egy nap alatt, amennyivel csak lehet. Az internetről letöltötték a holnapi űrturista-áthaladási időpontokat. Minden áthaladáshoz három adat tartozik: az űrturista neve (szóközt nem tartalmaz), mikortól (hány órától) kezdve tartózkodik a klub rádiójának vételkörzetében, és mikor hagyja el a vételkörzetet. E két időpont egy balról zárt, jobbról nyílt intervallum végpontjai. Példa áthaladási időpontok (~/szimp2/urturista1.in):

Pirx_pilota 5 7
Leia_hercegno 7 9
Dalek_42 6 10
Kis_herceg 1 6

Írjon programot Ruby nyelven, ami beolvassa az áthaladási időpontokat, és kiválaszt a benne levő űrturisták közül egy olyan maximális részhalmazt, melynek bármely két eleméhez tartozó intervallumok diszjunktak. (A diszjunktságot azért kell kikötni, mert a klubnak csak egy rádiója van, és szerencsétlen esetben előfordulhat, hogy a teljes intervallumban próbálkozniuk kell, hogy végre összejöjjön a kapcsolat.)

Ötlet: Használja ki, hogy ha az intervallumok végpont szerint növekvő sorrendbe vannak rendezve, akkor a mohó algoritmus jó és optimális eredményt ad. A mohó algoritmus veszi sorra az intervallumokat, és egy intervallumot akkor választ ki, ha az ő metszete az utoljára kiválasztott intervallummal üres halmaz.

Mintamegoldás (Ivett és Viktor, ~/szimp2/urturista.rb):

class Intervallum
  attr_accessor :nev, :a, :b
end

p=[]
STDIN.each_line { |s|
  t=s.split(/\s+/)
  h=Intervallum.new
  h.nev=t[0]
  h.a=t[1].to_i
  h.b=t[2].to_i

  #p[p.size]=h
  #p.push(h)
  p << h
}

p.sort!{|ha,hb| ha.b<=>hb.b}

q=[]
h0=nil
p.each { |h|
  if (h0==nil || [h.a,h0.a].max >= [h.b,h0.b].min);
    q.push(h)
    h0=h    
  end
}
q.each { |h|
  STDOUT.puts h.nev
}

10. előadás (2007-04-20)

Megtanultuk:

  • konstruktor (initialize)
  • példányváltozó (@)
  • metódus, amely beállít egy példányváltozót (attr_writer)
  • metódus, amely visszaad egy példányváltozót (attr_reader)
  • fekete doboz

11. gyakorlat (2007-04-24, 2007-04-27)

A keddi gyakorlat sportnap miatt elmaradt.

A gyakorlatot Bácsi László, LacKac (e-mail: lackac@) tartotta stringfeldolgozásról. Ezt a programot (~lackac/ruby/backup.rb) magyarázta:

require 'net/http'
require 'iconv'

class String
 def to_latin2
    Iconv.iconv('iso-8859-2', 'utf-8', self)[0]
  end
end

class Feed
  def initialize url
    @url = url
    @items = []
  end

  def get_content
    @content = Net::HTTP.get(URI.parse(@url))
  end

  def parse
    get_content
    @content.gsub(/<item.*?>.*?<\/item>/m) do |match|
      item = {}
      match =~ /<title>(<!\[CDATA\[)?(.*?)(\]\]>)?<\/title>/m
      item[:title] = $2
      match =~ /<link>(.*?)<\/link>/m
      item[:link] = $1
      match =~ /<description>(<!\[CDATA\[)?(.*?)(\]\]>)?<\/description>/m
      item[:desc] = $2
      @items << item
    end
  end

  def parse_by_xml
    require 'rexml/document'
    get_content
    xml = REXML::Document.new(@content)
    xml.elements.each('//item') do |match|
      item = {}
      item[:title] = match.elements['title'].text
      item[:link]  = match.elements['link'].text
      item[:desc]  = match.elements['description'].text
      @items << item
    end
  end

  def list
    @items.each do |item|
      puts item[:title].to_latin2
      puts item[:link].to_latin2
      l=0
      item[:desc].split.each do |w|
        print "  " if l == 0
        print w.to_latin2+" "
        l+=w.length+1
        if l > 60
          print "\n"
          l = 0
        end
      end
      print "\n"
    end
  end
end

feed = Feed.new(ARGV[0])
feed.parse_by_xml
feed.list

Így próbáltuk:

$ ruby backup.rb 'http://24ora.index.hu/?rss&keres=&szerzokeres=&rovatkeres=osszes&order=1'
$ ruby backup.rb 'http://origo.hu/contentpartner/rss/hircentrum/origo.xml'

11. előadás (2007-04-27)

Az előadást Bácsi László, LacKac (e-mail: lackac@) tartotta stringfeldolgozásról. Az IRB-be ezt írta be:

$ irb
irb(main):001:0> 
irb(main):002:0* 
irb(main):003:0* n=42
=> 42
irb(main):004:0> n.class
=> Fixnum
irb(main):005:0> f=3.14
=> 3.14
irb(main):006:0> f.class
=> Float
irb(main):007:0> s="alma"
=> "alma"
irb(main):008:0> s.class
=> String
irb(main):009:0> 
irb(main):010:0* 
irb(main):011:0* 
irb(main):012:0* s.methods
=> ["methods", "instance_eval", "%", "rindex", "map", "<<", "split", "any?", "dup", "sort
", "strip", "size", "instance_variables", "downcase", "min", "gsub!", "count", "include?"
, "succ!", "instance_of?", "extend", "downcase!", "intern", "squeeze!", "eql?", "*", "nex
t", "find_all", "each", "rstrip!", "each_line", "+", "id", "sub", "slice!", "hash", "sing
leton_methods", "tr", "replace", "inject", "reverse", "taint", "unpack", "sort_by", "lstr
ip", "frozen?", "instance_variable_get", "capitalize", "max", "chop!", "method", "kind_of
?", "capitalize!", "scan", "select", "to_a", "display", "each_byte", "type", "casecmp", "
gsub", "protected_methods", "empty?", "to_str", "partition", "tr_s", "tr!", "match", "gre
p", "rstrip", "to_sym", "instance_variable_set", "next!", "swapcase", "chomp!", "is_a?", 
"swapcase!", "ljust", "respond_to?", "between?", "reject", "to_s", "upto", "hex", "sum", 
"class", "object_id", "reverse!", "chop", "<=>", "insert", "<", "tainted?", "private_meth
ods", "==", "delete", "dump", "===", "__id__", "member?", "tr_s!", ">", "concat", "nil?",
 "untaint", "succ", "find", "strip!", "each_with_index", ">=", "to_i", "rjust", "<=", "se
nd", "index", "collect", "inspect", "slice", "oct", "all?", "clone", "length", "entries",
 "chomp", "=~", "public_methods", "upcase", "sub!", "squeeze", "__send__", "upcase!", "cr
ypt", "delete!", "equal?", "freeze", "detect", "zip", "[]", "lstrip!", "center", "[]=", "
to_f"]
irb(main):013:0> s+" korte"
=> "alma korte"
irb(main):014:0> s
=> "alma"
irb(main):015:0> s.methods.class
=> Array
irb(main):016:0> s.methods.find_all {|m| m =~ /case/}
=> ["downcase", "downcase!", "casecmp", "swapcase", "swapcase!", "upcase", "upcase!"]
irb(main):017:0> 
irb(main):018:0* 
irb(main):019:0* 
irb(main):020:0* a=[1,2,3,4,5,6]
=> [1, 2, 3, 4, 5, 6]
irb(main):021:0> a.clas
NoMethodError: undefined method `clas' for [1, 2, 3, 4, 5, 6]:Array
        from (irb):21
        from :0
irb(main):022:0> a.class
=> Array
irb(main):023:0> a.methods
=> ["methods", "instance_eval", "rindex", "map", "<<", "any?", "&", "dup", "sort", "join"
, "pack", "reverse_each", "size", "instance_variables", "min", "include?", "collect!", "r
assoc", "instance_of?", "extend", "at", "compact!", "eql?", "*", "find_all", "each", "+",
 "reject!", "flatten", "slice!", "pop", "hash", "id", "singleton_methods", "-", "transpos
e", "replace", "inject", "reverse", "indexes", "sort_by", "taint", "map!", "uniq", "max",
 "frozen?", "instance_variable_get", "fetch", "method", "kind_of?", "values_at", "|", "se
lect", "to_a", "display", "type", "shift", "protected_methods", "empty?", "clear", "parti
tion", "indices", "grep", "instance_variable_set", "is_a?", "flatten!", "first", "respond
_to?", "reject", "to_s", "delete_at", "nitems", "class", "reverse!", "<=>", "unshift", "i
nsert", "object_id", "tainted?", "private_methods", "==", "delete", "fill", "===", "__id_
_", "member?", "uniq!", "concat", "find", "nil?", "untaint", "compact", "each_with_index"
, "last", "send", "delete_if", "index", "collect", "inspect", "slice", "all?", "clone", "
=~", "each_index", "length", "entries", "sort!", "assoc", "public_methods", "__send__", "
to_ary", "equal?", "freeze", "detect", "zip", "[]", "[]=", "push"]
irb(main):024:0> n.size
=> 4
irb(main):025:0> a.size
=> 6
irb(main):026:0> a.nitems
=> 6
irb(main):027:0> n
=> 42
irb(main):028:0> 
irb(main):029:0* 
irb(main):030:0* a=[1,2,3,4]
=> [1, 2, 3, 4]
irb(main):031:0> b=["egy","ketto",harom"]
irb(main):032:1" "
irb(main):033:1> b=["egy","ketto","harom"]
irb(main):034:1> 10000000.size
irb(main):035:1> 10_000_000.size
irb(main):036:1> "
irb(main):037:1" "
irb(main):038:1> 
irb(main):039:1* 
irb(main):040:1* 
irb(main):041:1* n=10_000_000_000
irb(main):042:1> n.class
irb(main):043:1> SyntaxError: compile error
(irb):31: parse error, unexpected tSTRING_BEG, expecting kDO or '{' or '('
b=["egy","ketto",harom"]
                       ^
        from (irb):42
        from (null):0
LacKac@LacKacMB:~> irb
irb(main):001:0> n=10_000_000_000
=> 10000000000
irb(main):002:0> n.size
=> 8
irb(main):003:0> n=1_000_000_000
=> 1000000000
irb(main):004:0> n.size
=> 4
irb(main):005:0> a=[1,2,3,4]
=> [1, 2, 3, 4]
irb(main):006:0> b=["egy","ketto","harom"]
=> ["egy", "ketto", "harom"]
irb(main):007:0> a+b
=> [1, 2, 3, 4, "egy", "ketto", "harom"]
irb(main):008:0> [1,2,3]+[3,4,5]
=> [1, 2, 3, 3, 4, 5]
irb(main):009:0> [1,2,3]|[3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):010:0> [1,2,3]-[3,4,5]
=> [1, 2]
irb(main):011:0> [1,2,3]^[3,4,5]
NoMethodError: undefined method `^' for [1, 2, 3]:Array
        from (irb):11
        from :0
irb(main):012:0> [1,2,3]&[3,4,5]
=> [3]
irb(main):013:0> [1,2,3]*3
=> [1, 2, 3, 1, 2, 3, 1, 2, 3]
irb(main):014:0> [1,2,3]==[1,2,3]
=> true
irb(main):015:0> [1,2,3]==[2,1,3]
=> false
irb(main):016:0> a=[1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):017:0> a[0]
=> 1
irb(main):018:0> a[4]
=> 5
irb(main):019:0> a[-1]
=> 5
irb(main):020:0> a[-3]
=> 3
irb(main):021:0> a[-3]="harom"
=> "harom"
irb(main):022:0> a
=> [1, 2, "harom", 4, 5]
irb(main):023:0> a[23423]
=> nil
irb(main):024:0> a.sort
ArgumentError: comparison of Fixnum with String failed
        from (irb):24:in `sort'
        from (irb):24
        from :0
irb(main):025:0> a.sort_by^C
irb(main):025:0> a=[3,6,2,89,42
irb(main):026:1> ]
=> [3, 6, 2, 89, 42]
irb(main):027:0> a=[3,6,2,89,42]
=> [3, 6, 2, 89, 42]
irb(main):028:0> a.sort
=> [2, 3, 6, 42, 89]
irb(main):029:0> b
=> ["egy", "ketto", "harom"]
irb(main):030:0> b.sort
=> ["egy", "harom", "ketto"]
irb(main):031:0> c=a.map! {|i| i.to_s}
=> ["3", "6", "2", "89", "42"]
irb(main):032:0> a.has?(4)
NoMethodError: undefined method `has?' for ["3", "6", "2", "89", "42"]:Array
        from (irb):32
        from :0
irb(main):033:0> a.include?(4)
=> false
irb(main):034:0> a.include?(89)
=> false
irb(main):035:0> a
=> ["3", "6", "2", "89", "42"]
irb(main):036:0> a.include?("89")
=> true
irb(main):037:0> a.sort
=> ["2", "3", "42", "6", "89"]
irb(main):038:0> a.sort_by {|i| i.to_i}
=> ["2", "3", "6", "42", "89"]
irb(main):039:0> a
=> ["3", "6", "2", "89", "42"]
irb(main):040:0> b
=> ["egy", "ketto", "harom"]
irb(main):041:0> b=["alma","korte","dio"]
=> ["alma", "korte", "dio"]
irb(main):042:0> b.sort_by {|s| s.length}
=> ["dio", "alma", "korte"]
irb(main):043:0> b.sort_by {|valami| valami.length}
=> ["dio", "alma", "korte"]
irb(main):044:0> s="alma korte dio"
=> "alma korte dio"
irb(main):045:0> s.length
=> 14
irb(main):046:0> s[6]
=> 111
irb(main):047:0> s[6].class
=> Fixnum
irb(main):048:0> s[6] == "a"
=> false
irb(main):049:0> s[6] == "k"
=> false
irb(main):050:0> s[6] == ?k
=> false
irb(main):051:0> ?k
=> 107
irb(main):052:0> ?o
=> 111
irb(main):053:0> s[6] == ?o
=> true
irb(main):054:0> 
irb(main):055:0* s
=> "alma korte dio"
irb(main):056:0> s.split
=> ["alma", "korte", "dio"]
irb(main):057:0> mac="16:ef:3d:3a:56:dc"
=> "16:ef:3d:3a:56:dc"
irb(main):058:0> mac.split(":")
=> ["16", "ef", "3d", "3a", "56", "dc"]
irb(main):059:0> mac="16:ef 3d.3a:56.dc"
=> "16:ef 3d.3a:56.dc"
irb(main):060:0> mac.split(":")
=> ["16", "ef 3d.3a", "56.dc"]
irb(main):061:0> mac.split(":. ")
=> ["16:ef 3d.3a:56.dc"]
irb(main):062:0> mac.split(/[:\. ]/)
=> ["16", "ef", "3d", "3a", "56", "dc"]
irb(main):063:0> "alma"+"korte"
=> "almakorte"
irb(main):064:0> "alma"+" "+"korte"
=> "alma korte"
irb(main):065:0> 'alma'
=> "alma"
irb(main):066:0> print "alma\n"
alma
=> nil
irb(main):067:0> print "alma"
alma=> nil
irb(main):068:0> print "alma\n"
alma
=> nil
irb(main):069:0> print "alma\tkorte\tdio\n"
alma    korte   dio
=> nil
irb(main):070:0> print 'alma\tkorte\tdio\n'
alma\tkorte\tdio\n=> nil
irb(main):071:0> 
irb(main):072:0* n=42
=> 42
irb(main):073:0> s="egy"
=> "egy"
irb(main):074:0> s="ertelme"
=> "ertelme"
irb(main):075:0> print "az elet "+s+" "n
SyntaxError: compile error
(irb):75: parse error, unexpected tIDENTIFIER, expecting $
        from (irb):75
        from :0
irb(main):076:0> print "az elet "+s+" "+n
TypeError: can't convert Fixnum into String
        from (irb):76:in `+'
        from (irb):76
        from :0
irb(main):077:0> print "az elet "+s+" "+n.to_s
az elet ertelme 42=> nil
irb(main):078:0> print "az elet "+s+" "+n.to_s+"\n"
az elet ertelme 42
=> nil
irb(main):079:0> print "az elet #{s} #{n}\n"
az elet ertelme 42
=> nil
irb(main):080:0> print "az elet #{s.upcase} #{n}\n"
az elet ERTELME 42
=> nil
irb(main):081:0> 
irb(main):082:0* 
irb(main):083:0* 
irb(main):084:0* s.upcase
=> "ERTELME"
irb(main):085:0> s="LacKac"
=> "LacKac"
irb(main):086:0> s.upcase
=> "LACKAC"
irb(main):087:0> s.downcase
=> "lackac"
irb(main):088:0> s.swapcase
=> "lACkAC"
irb(main):089:0> s
=> "LacKac"
irb(main):090:0> s.upcase!
=> "LACKAC"
irb(main):091:0> s
=> "LACKAC"
irb(main):092:0> s.methods
=> ["methods", "instance_eval", "%", "rindex", "map", "<<", "split", "any?", "dup", "sort
", "strip", "size", "instance_variables", "downcase", "min", "gsub!", "count", "include?"
, "succ!", "instance_of?", "extend", "downcase!", "intern", "squeeze!", "eql?", "*", "nex
t", "find_all", "each", "rstrip!", "each_line", "+", "id", "sub", "slice!", "hash", "sing
leton_methods", "tr", "replace", "inject", "reverse", "taint", "unpack", "sort_by", "lstr
ip", "frozen?", "instance_variable_get", "capitalize", "max", "chop!", "method", "kind_of
?", "capitalize!", "scan", "select", "to_a", "display", "each_byte", "type", "casecmp", "
gsub", "protected_methods", "empty?", "to_str", "partition", "tr_s", "tr!", "match", "gre
p", "rstrip", "to_sym", "instance_variable_set", "next!", "swapcase", "chomp!", "is_a?", 
"swapcase!", "ljust", "respond_to?", "between?", "reject", "to_s", "upto", "hex", "sum", 
"class", "object_id", "reverse!", "chop", "<=>", "insert", "<", "tainted?", "private_meth
ods", "==", "delete", "dump", "===", "__id__", "member?", "tr_s!", ">", "concat", "nil?",
 "untaint", "succ", "find", "strip!", "each_with_index", ">=", "to_i", "rjust", "<=", "se
nd", "index", "collect", "inspect", "slice", "oct", "all?", "clone", "length", "entries",
 "chomp", "=~", "public_methods", "upcase", "sub!", "squeeze", "__send__", "upcase!", "cr
ypt", "delete!", "equal?", "freeze", "detect", "zip", "[]", "lstrip!", "center", "[]=", "
to_f"]
irb(main):093:0> s.reverse
=> "CAKCAL"
irb(main):094:0> a
=> ["3", "6", "2", "89", "42"]
irb(main):095:0> a.reverse
=> ["42", "89", "2", "6", "3"]
irb(main):096:0> "bacsi laszlo".capitalize
=> "Bacsi laszlo"
irb(main):097:0> nev = "bacsi laszlo istvan"
=> "bacsi laszlo istvan"
irb(main):098:0> nev.splite
NoMethodError: undefined method `splite' for "bacsi laszlo istvan":String
        from (irb):98
        from :0
irb(main):099:0> nev.split
=> ["bacsi", "laszlo", "istvan"]
irb(main):100:0> nev.split.map {|i| i.capitalize}
=> ["Bacsi", "Laszlo", "Istvan"]
irb(main):101:0> nev.split.map {|i| i.capitalize}.join
=> "BacsiLaszloIstvan"
irb(main):102:0> nev.split.map {|i| i.capitalize}.join(" ")
=> "Bacsi Laszlo Istvan"
irb(main):103:0> a=["alma", "korte", "szilva"]
=> ["alma", "korte", "szilva"]
irb(main):104:0> a.each {|i| puts i}
alma
korte
szilva
=> ["alma", "korte", "szilva"]
irb(main):105:0> a.each_with_index {|v,i| puts "#{i}: #{v}"}
0: alma
1: korte
2: szilva
=> ["alma", "korte", "szilva"]
irb(main):106:0> a.each_with_index {|v,i| print "#{i}: #{v}"}
0: alma1: korte2: szilva=> ["alma", "korte", "szilva"]
irb(main):107:0> a.each_with_index {|v,i| print "#{i}: #{v}\n"}
0: alma
1: korte
2: szilva
=> ["alma", "korte", "szilva"]
irb(main):108:0> s="alma\nkorte\nszilva"
=> "alma\nkorte\nszilva"
irb(main):109:0> print s
alma
korte
szilva=> nil
irb(main):110:0> s.each_line {|l| puts l}
alma
korte
szilva
=> "alma\nkorte\nszilva"
irb(main):111:0> 
irb(main):112:0* 
irb(main):113:0* 
irb(main):114:0* s
=> "alma\nkorte\nszilva"
irb(main):115:0> s="alma korte szilva"
=> "alma korte szilva"
irb(main):116:0> s.split
=> ["alma", "korte", "szilva"]
irb(main):117:0> a=["alma", "korte", szilva"]
irb(main):118:1" ["]
SyntaxError: compile error
(irb):117: parse error, unexpected tSTRING_BEG, expecting kDO or '{' or '('
a=["alma", "korte", szilva"]
                           ^
(irb):118: parse error, unexpected ']', expecting $
        from (irb):118
        from :0
irb(main):119:0> a=["alma", "korte", "szilva"]
=> ["alma", "korte", "szilva"]
irb(main):120:0> a= %w{ alma korte szilva }
=> ["alma", "korte", "szilva"]
irb(main):121:0> a= %w{alma korte szilva}
=> ["alma", "korte", "szilva"]

12. gyakorlat (2007-05-01, 2007-05-04)

A keddi, május elsejei gyakorlat az ünnep miatt elmaradt. Énekszó és tánc köszöntse. A pénteki gyakorlat anyaga következik.

A tanult C beépített függvények:

  • printf()
  • scanf()
  • putchar()
  • getchar()
  • abort()

A tanult Ruby beépített osztályok:

  • Object
  • Float
  • Fixnum
  • Bignum
  • Integer
  • String
  • Array
  • Module
  • Class
  • TrueClass
  • FalseClass
  • NilClass
  • Hash
  • Regexp

Próbálkozások:

$ irb
1.2.class
42.class
42.class.class
42.class.class.class
2**42.class  # hiba
(2**42).class
(2**61).class
(2**62).class
"".class
.class
[].class
{}.class
42.class.superclass
42.class.superclass.superclass
42.class.superclass.superclass.superclass
42.kind_of?(Fixnum)   #: true
42.kind_of?(Integer)  #: true
42.kind_of?(String)   #: false
true.class
false.lass
nil.class
Float.superclass
String.methods

Az összes beépített osztály listázása (pl. String):

Object.constants.sort.select { |c| Object.const_get(c).kind_of?(Class) }

Az összes beépített modul listázása (pl. Math):

Object.constants.sort.select { |c| Object.const_get(c).kind_of?(Module) &&
  !Object.const_get(c).kind_of?(Class) }

Osztályhiearachia-részlet:

Object
  String
  Array
  Hash
  Regexp
  Numeric
    Float
    Integer
      Fixnum
      Bignum

A program (listastszamol.rb), amely megszámolja, hogy az aktuális felhasználó levelesládájában a mat06 levelezési listára ki hány levelet küldött, és a küldések számának növekvő sorrendjében nyomtatja ki a feladó e-mail címeket:

r=/^List-Id: *mat06[.]lists[.]math[.]bme[.]hu$/
# p r.class #: Regexp
f=File.open(ENV["MAIL"])
listas=false; fejlecben=false
froml=nil
h={}
f.each_line { |l|
  if fejlecben && l =~ r; then
    listas=true
  end
  if fejlecben && l =~ /^From: *(.*)/
    froml=$1
    if froml=~/<(.*?)>/;
      froml=$1
    end
    if froml !~/[@]/;
      froml=nil
    end
  end
  if fejlecben && l =~ /^$/;
    if listas and froml;
      if h.has_key?(froml);
        h[froml]+=1
      else
        h[froml]=1
      end
      #p froml
    end
    froml=nil; listas=false; fejlecben=false
  end
  if l =~ /^From /;
    fejlecben=true
  end
}

h.sort { |a,b|
  a[1]<=>b[1]
}.each { |k,v|
  print "#{v} #{k}\n"
}

12. előadás (2007-05-04)

Kivételkezelésről volt szó.

begin
  f=File.open("bableves.txt")
  p f.readline
  p f.readline
rescue Errno::ENOENT
  print "A fájl nem létezik!\n"
rescue SystemCallError => e
  print "Rendszerhiba\n"
  p e
ensure
  f.close if f && !f.closed?
end

Osztályhiererchia-részlet:

 Object
   Exception
     StandardError
       SystemCallError
         Errno::ENOENT

Saját kivétel definiálása:

class NemPozitivHiba <Exception; end

def feldolgoz(sor)
  f=sor.to_f
  raise NemPozitivHiba, "valami üzenet" if f<=0.0
  print "#{Math::sqrt(f)}\n"
end

STDIN.each_line { |l|
  begin
    feldolgoz(l)
  rescue NemPozitivHiba
    print "NEM POZITIV\n"
  end
}

13. gyakorlat (2007-05-08, 2007-05-11)

Ezen a pénteken lesz a ZH.

13. előadás (2007-05-11)

Ezen a pénteken lesz a ZH.

14. gyakorlat (2007-05-15, 2007-05-18)

Nyomkövetésről és hibakeresésről lesz szó mind C, mind Ruby nyelven. printf, kdevelop, valgrind, strace.

14. előadás (2007-05-18)

Mivel a március 15. előtti szombaton plusz egy előadást tartottunk, ezért a félévben egy előadást ki kell hagyni. Ez lesz az. Pontosabban: az előadás meg lesz tartva, és továbbmegyünk az anyagban, de nem kötelező eljönni. Ennek az előadásnak az anyaga nem lesz számonkérve (nem is lehet, mivel a ZH-t az előző héten már megírtuk). Az előadás előtti gyakorlat természetesen kötelező.

A második ZH

A második ZH időpontja: 2007. május 11. péntek, 12:00. A teremfogalásról időben gondoskodunk. PótZH a vizsgaidőszak első hetében lesz. A ZH témája objektum-orientált programozás Ruby nyelven. A ZH-n 1 db, kézzel, kék tollal írt A4-es lapnyi puskát lehet használni. A ZH-n kb. 50% programozási és 50% elméleti feladat lesz. Aki a programozási feladatokat számítógéppel szeretné írni, az jelentkezzen e-mailben a tárgy előadójánál. A számítógépes megoldás lehetőségét technikai okokból csak abban az esetben tudjuk biztosítani, ha max. 10 jelentkező lesz.

Időpontok:

  • elmaradt keddi gyakorlatok pótlása: 2006. május 8. kedd, 12:00--14:15.
  • konzultáció: 2007. május 10. csütörtök, 14:14--19:19. H.27. A konzultáció korábban is véget érhet a meghirdetettnél: ha 15 percen belül nem hangzik el kérdés.
  • ZH papíron: 2007. május 11. péntek, 12:00--14:00. Terem foglalás alatt.
  • ZH programozás (opcionális): 2007. május 11. péntek, 12:00--14:00, H.57.

Mintafeladatok

Az alábbiakhoz hasonló és másféle feladatok is várhatók a második ZH-n.

Elméleti feladatok:

  • Az x.foo() hívás esetén mely osztályokban és milyen sorrendben keresi a Ruby a meghívandó metódust?
  • Hozzon létre egy olyan x objektumot, melyre x.kind_of?(Alma) && x.class!=Alma
  • Mikor áll a C-beli int i=1; while (i!=0) i*=2; ciklus? Mikor áll le a Ruby-beli i=1; while i!=0; i*=2; end ciklus?
  • Írjon egy olyan osztályt Ruby nyelven, amely paraméteres konstruktorral rendelkezik, és hozzon létre két példányt. Hányszor hívódik meg a konstruktor?
  • Mutasson példát arra, hogy az x.leszed() hívás nem a Gyumolcs osztályon belül definiált leszed metódust hívja, noha x.kind_of?(Gyumolcs)
  • Mit ad vissza a self egy metóduson belül?
  • Mi a különbség egy metóduson belül a foo=5, @foo=5 és a self.foo=5 értékadások között?
  • Írjon egy olyan metódust, melyben a p foo hívás kétszer szerepel, de csak az egyik esetben írja ki a foo nevű lokális változó értékét, a másik esetben mást ír ki.
  • Írja át az alábbi kódot úgy, hogy @a<=@b mindig teljesüljön. Ha a hívó olyan helyzetet akarna előidézni, amely megsérti a fenti feltételt, akkor dobjon kivételt fail-lel. (Segítség: 3 db metódusba kell fail-t tenni.)
class Intervallum
  attr_accessor :a, :b
  def initialize(a, b)
    @a=a; @b=b
  end
end
  • Az alábbi kód végrehajtása után a a Ruby lefuttatja a szemétgyűjtést. Rajzolja fel az # itt sor végrehajtásakor az objektumokat, és azt, hogy az a és b változók mely objektumra mutatnak. Mely objektumok maradnak meg, és melyeket szabadítja fel a szemétgyűjtés?
class Gyerek
  attr_accessor :nev, :kov
  def initialize(nev) @nev=nev; @kov=nil; end
end

def egyik()
  pal=Gyerek.new("Pal")
  kata=Gyerek.new("Kata")
  peter=Gyerek.new("Peter")
  pal.kov=kata; kata.kov=peter; peter.kov=pal
end

def masik()
  sandor=Gyerek.new("Sandor")
  jozsef=Gyerek.new("Jozsef")
  benedek=Gyerek.new("Benedek")
  sandor.kov=jozsef; jozsef.kov=benedek
end

a=egyik
b=masik
# itt
a=nil

Programozási feladatok:

  • Írjon Ruby-programot sorhosszcsokkeno.rb néven, amely beolvassa a bemenet sorait, majd a sorhossz szerinti csökkenő sorrendben kiírja a sorokat. Az egyenlő hosszúságú sorok sorrendje tetszőleges.
  • Írjon Ruby-programot abszoluterteknovekvo.rb néven, amely beolvassa a bemenet sorait (a sorok egész számokat tartalmaznak), és kiírja a sorokat az abszolút értékek növekvő sorrendjében. Az egyenlő abszolútértékű számok sorrendje tetszőleges.
  • Írjon Ruby-programot palindrom.rb néven, amely beolvassa a bemenet sorait, és kiírja a palindrom sorokat. Egy string palindrom, ha a megfordítása önmaga. Segítség: beolvasás után, de még összehasonlítás előtt az s.chomp! hívással törölje a soremelést a string végéről.
  • Írjon Ruby-programot palindromlehet.rb néven, amely beolvassa a bemenet sorait, és kiírja azokat a sorokat, melyekben a betűk átvarálásával palindrom string készíthető. Egy string palindrom, ha a megfordítása önmaga. 1. segítség: beolvasás után, de még összehasonlítás előtt az s.chomp! hívással törölje a soremelést a string végéről. 2. segítség: rendezze a string karaktereit az s=s.split("").sort.join hívással.
  • Írjon Ruby-programot rendszamtobbszor.rb néven, amely beolvassa a bemenet sorait, és kiírja azokat a rendszámokat, melyek 2-szer vagy többször szerepelnek. A rendszám három betűből, egy kötőjelből és három számjegyből áll. Segítség: egy sort szavakra lehet bontani a s.split hívással, ami stringekből álló tömböt ad vissza.
  • Írjon Ruby-programot egyszer.rb néven, amely beolvassa a bemenet sorait, és csak azokat a sorokat írja ki (tetszőleges sorrendben), melyek pontosan egyszer szerepelnek.
  • Melyik az a legkisebb kettőhatvány, ami már nem Fixnum? Írjon programot (marnemfixnum.rb néven), ami megadja a választ.
  • Adott két objektum: a és b. Írjon Ruby-függvényt, amely visszaadja azt a legmélyebb osztályt, amely mindkét objektumnak szülőosztálya. Deklaráció: def kozosos(a,b)
  • Készítsen egy Teglalap nevű osztályt Ruby nyelven a teglalap.rb fájlba, amely egy tengélypárhuzamos téglalapot tartalmaz. Létrehozására példa: t=Tegalalap.new(3,4,1,2), ahol a bal alsó sarok a (3,4), a szélessége 1, a magassága 2, tehát a jobb felső sarok a (4,6).
    • Tegye lehetővé a szélső koordináták lekérdezését, például p t.llx, t.lly a bal alsó sarkot p t.urx, t.ury jobb felső sarkot írja ki.
    • Tegye lehetővé a téglalap méretének lekérdezését, például p t.width, t.height a szélességet, majd a magasságot írja ki.
    • Tegye lehetővé a téglalap méretének megváltoztatását, például p.width=42 a téglalap szélességét, a p.height=137 pedig a téglalap magasságát változtatja meg. A változtatás a bal alsó sarkot helybenhagyja, a többi csúcsot pedig értelemszerűen mozgatja.
    • Tegye lehetővé az egyes csúcspontok lekérdezését: t.ul a bal felső, t.ur a jobb felső, t.lr a jobb alsó, t.ll a bal alsó sarkot adja vissza. Egy csúcspont egy kételemű tömb: [x,y].
    • Tegye lehetővé a téglalap eltolását: a t.eltol!(dx,dy) hívás dx-et hozzáad minden pont x koordintájához, és dy-ot adjon hozzá minden pont y koordinátájához, a t.eltol(dx,dy) hívás pedig egy új téglalapot adjon vissza, amely t-hez képest (dx,dy)-nal van eltolva.
    • Tegye lehetővé a súlypont lekérdezését: a t.sulypont hívás adja vissza a súlypontot [cx,cy] tömbként, a t.cx hívás adja vissza a súlypont x koordinátáját, a t.cy hívás pedig adja vissza a súlypont y koordinátáját.
    • Tegye lehetővé a téglalap eltolását a súlypont mozgatásával. A t.cx=42 hívás x irányban, a t.cy=137 hívás pedig irányban mozgassa a téglalapot úgy, hogy a súlypont a megadott koordinátára kerüljön.
    • Tegye lehetővé a téglalap nagyítását: a t.nagyit!(m) hívás a tömegközéppontból m-szeresére nagyítsa a téglalapot, a t.nagyit(m) hívás pedig egy új téglalapot adjon vissza, amely az eredetihez képest a fenti módon van kinagyítva.
    • A téglalap méretét megváltoztató t.width=() és t.height=() függvényeket módosítsa úgy, hogy negatív méretet ne lehessen megadni. Definiáljon egy kivételosztályt NegativMeretHiba néven, és dobja ezt a kivételt, ha a hívó negatív méretet akar beállítani.
    • A téglalap létrehozásakor meghívott függvényt módosítsa úgy, hogy negatív méretű téglalapot ne lehessen megadni. Dobjon NegativMeretHiba kivételt, ha a hívó negatív méretű téglalapot akar létrehozni.
    • Tegye lehetővé a téglalap szélső koordinátáinak megváltoztatását. A megvalósítandó hívások: t.llx=1; t.lly=2; t.urx=3; t.ury=4. Ha a hívó olyan értéket akar beállítani, hogy a téglalap mérete negatív lenne, dobjon NegativMeretHiba kivételt.
    • Írjon függvényt sulypontok néven, amely soronként beolvassa a bemenetet, minden sorban 4 számot várjon (elemekre bontás: s.split hívással), ezek a számok a bal alsó sarok x majd y koordinátája, a szélesség és a magasság. A kimenetre a téglalap súlypontját írja (soremeléssel lezárva), a sulypont metódus hívásával. A NegativMeretHiba kivételt kapja el, ekkor a kimenetre egy N betű és egy soremelés kerüljön.
  • Készítsen Szamegyenes néven osztályt Rubyban. A számegyenes olyan, mint egy tömb, de nem csak pozitív, hanem negatív irányban is tetszőlegesen bővíthető. Az adatok tárolásához használjon 2 tömböt: @p és @n. Például a számegyenes 5-ödik elemét @p[5]-ben, a -5-ödik elemét pedig @n[4]-ben tárolja. Kezdetben mindkét tömb legyen üres.
    • Írja meg a def [](i); ... end metódus törzsét, mely visszaadja a számegyenes i-edik elemét.
    • Írja meg a def []=(i,uj); ... end metódus törzsét, mely a számegyenes i-edik elemét megváltoztatja uj-ra, és visszaadja uj-t.
    • Írja meg a def size(); ... end metódus törzsét, amely visszaadja a számegyenes elemeinek összszámát, vagyis a @p és @n tömbök összméretét.
    • Írja meg a def tukroz!(); ... end metódus törzsét, amely a számegyest tükrözi az origóra, vagyis minden i-re az i-edik elem helyet cserél a -i-edik elemmel.
  • Készítsen KorlatosTomb néven osztályt Rubyban. A KorlatosTomb egy olyan tömb, amelynek kezdeti mérete később nem változtatható meg. Megvalósításához a @t Ruby tömböt (Array) használja.
    • Írja meg a konstruktort, amely paraméterben várja azt az m méretet, melyre korlátozva van a tömb.
    • Írja meg a paraméter nélküli size metódust, amely visszaadja a konstruktornak átadott m méretet.
    • Írja meg a def [](i); ... end metódus törzsét, mely visszaadja a korlátos tömb i-edik elemét.
    • Írja meg a def []=(i,uj); ... end metódus törzsét, mely a korlátos tömb i-edik elemét megváltoztatja uj-ra, és visszaadja uj-t.
Személyes eszközök