rubylabs 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.3
1
+ 0.9.0
data/lib/bitlab.rb CHANGED
@@ -590,7 +590,6 @@ module BitLab
590
590
  Canvas.move(tree.drawing.rseg, dx, dy)
591
591
  move_tree(tree.right, dx, dy)
592
592
  end
593
- Canvas.sync
594
593
  end
595
594
 
596
595
  def draw_root(node, left, right)
@@ -598,8 +597,10 @@ module BitLab
598
597
  x = (left.coords.x + right.coords.x) / 2
599
598
  y = left.coords.y - 2 * @@unit
600
599
  draw_node(node, x, y)
601
- node.drawing.lseg = Canvas.line(x, y, left.coords.x, left.coords.y).lower
602
- node.drawing.rseg = Canvas.line(x, y, right.coords.x, right.coords.y).lower
600
+ node.drawing.lseg = Canvas::Line.new(x, y, left.coords.x, left.coords.y)
601
+ node.drawing.rseg = Canvas::Line.new(x, y, right.coords.x, right.coords.y)
602
+ node.drawing.lseg.lower
603
+ node.drawing.rseg.lower
603
604
  # [left, right].each do |desc|
604
605
  # desc.drawing.ftext.delete
605
606
  # desc.drawing.ftext = nil
@@ -610,9 +611,9 @@ module BitLab
610
611
  return nil unless @@drawing
611
612
  opts = @@drawing.options
612
613
  d = @@unit
613
- circ = Canvas.circle( x, y, d / 2, :fill => opts[:nodefill] )
614
- text = Canvas.text( node.char, x, y, :anchor => :center )
615
- ftext = Canvas.text( node.freq.to_s, x, y-d, {:font => opts[:freqfont], :anchor => :center} )
614
+ circ = Canvas::Circle.new( x, y, d / 2, :fill => opts[:nodefill] )
615
+ text = Canvas::Text.new( node.char, x, y, :anchor => :center )
616
+ ftext = Canvas::Text.new( node.freq.to_s, x, y-d, {:font => opts[:freqfont].name, :anchor => :center} )
616
617
  node.drawing = NodeView.new(circ, text, ftext, nil, nil)
617
618
  node.coords = NodeCoords.new(x, y, x, 0, x, 0)
618
619
  end
@@ -626,17 +627,23 @@ module BitLab
626
627
  Canvas.init(options[:width], options[:height], "BitLab")
627
628
  @@drawing = QueueView.new(pq, options)
628
629
  options[:nodefill] = "lightgray"
629
- options[:freqfont] = Canvas.font(:family => 'Helvetica', :size => 10)
630
+ options[:freqfont] = Canvas::Font.new('freqfont', :family => 'Helvetica', :size => 10)
630
631
  pq.on_canvas = true
631
632
  x = options[:qx]
632
633
  pq.each_with_index do |node, i|
633
634
  draw_node(node, x, options[:qy])
634
635
  x += 3 * @@unit
635
636
  end
636
- Canvas.sync
637
637
  return true
638
638
  end
639
639
 
640
+ # def test_setup
641
+ # vf = read_frequencies(:hvfreq)
642
+ # pq = init_queue(vf)
643
+ # view_queue(pq)
644
+ # return pq
645
+ # end
646
+
640
647
  @@unit = 24 # pixels per "tree unit"
641
648
 
642
649
  @@queueViewOptions = {
@@ -732,7 +739,7 @@ class PriorityQueue
732
739
  # end
733
740
  return res
734
741
  end
735
-
742
+
736
743
  end
737
744
 
738
745
  class Fixnum
@@ -768,17 +775,5 @@ class Fixnum
768
775
 
769
776
  end
770
777
 
771
- =begin
772
- TODO delete this
773
- =end
774
-
775
- def test_view
776
- vf = read_frequencies(:hafreq)
777
- pq = init_queue(vf)
778
- view_queue(pq)
779
- Canvas.sync
780
- return pq
781
- end
782
-
783
778
 
784
779
 
data/lib/hashlab.rb CHANGED
@@ -14,7 +14,7 @@ module RubyLabs
14
14
 
15
15
  module HashLab
16
16
 
17
- TableView = Struct.new(:table, :nrows)
17
+ TableView = Struct.new(:cells, :buckets, :nrows, :options)
18
18
 
19
19
  =begin rdoc
20
20
 
@@ -131,6 +131,7 @@ Ruby magic defines three new methods just for the new object:
131
131
  @@hash_functions = [:h0, :h1, :hr]
132
132
 
133
133
  attr_reader :table
134
+ attr_accessor :drawing
134
135
 
135
136
  def initialize(n, f = :hr)
136
137
  raise "HashTable: hash function must be one of #{@@hash_functions.inspect}" unless @@hash_functions.include?(f)
@@ -155,6 +156,16 @@ Ruby magic defines three new methods just for the new object:
155
156
  i = send(@hash, s, @table.length)
156
157
  @table[i] = Array.new if @table[i].nil?
157
158
  @table[i] << s
159
+ if @drawing
160
+ options = @drawing.options
161
+ if @drawing.buckets[i]
162
+ @drawing.buckets[i].update( @table[i].join(", ") )
163
+ else
164
+ y0 = options[:tableY] + i * (options[:cellHeight] + options[:cellYSpace])
165
+ @drawing.buckets[i] = Canvas::Text.new(@table[i], options[:textX], y0, {:font => :bucketfont})
166
+ @drawing.cells[i].fill = 'white'
167
+ end
168
+ end
158
169
  return i
159
170
  end
160
171
 
@@ -239,28 +250,31 @@ Ruby magic defines three new methods just for the new object:
239
250
  end
240
251
 
241
252
  =begin rdoc
242
- Initialize the canvas with a drawing of an hash table +t+ (a table is
243
- just an array augmented with a hash method)
253
+ Initialize the canvas with a drawing of an hash table +t+
244
254
  =end
245
255
 
246
256
  def view_table(t, userOptions = {} )
247
257
  options = @@tableOptions.merge(userOptions)
248
- Canvas.init(300, 500, "HashLab")
258
+ Canvas.init(400, 500, "HashLab")
259
+ Canvas::Font.new('bucketfont', :family => 'Helvetica', :size => 11)
249
260
  tbl = t.table
250
261
  x0 = options[:tableX]
251
262
  x1 = x0 + options[:cellWidth]
252
- # if nil, color = gray, else color = white and draw text
253
- # todo -- arrow
254
- # todo -- save text, update with call to insert
263
+ cells = []
264
+ buckets = []
255
265
  nrows = min(tbl.size, options[:maxRows])
256
266
  nrows.times do |i|
257
267
  y0 = options[:tableY] + i * (options[:cellHeight] + options[:cellYSpace])
258
268
  y1 = y0 + options[:cellHeight]
259
- Canvas.rectangle(x0, y0, x1, y1, :fill => options[:cellColor])
260
- # Canvas.text(tbl[i].inspect, textx, y0)
269
+ cells << Canvas::Rectangle.new(x0, y0, x1, y1)
270
+ if tbl[i]
271
+ buckets << Canvas::Text.new(tbl[i].join(", "), options[:textX], y0, {:font => :bucketfont})
272
+ cells[i].fill = 'white'
273
+ else
274
+ cells[i].fill = options[:cellColor]
275
+ end
261
276
  end
262
- @@drawing = TableView.new(t, nrows)
263
- Canvas.sync
277
+ t.drawing = TableView.new(cells, buckets, nrows, options)
264
278
  return true
265
279
  end
266
280
 
data/lib/marslab.rb CHANGED
@@ -34,6 +34,8 @@ to assemble a program call MARS.assemble(foo).
34
34
  module RubyLabs
35
35
 
36
36
  module MARSLab
37
+
38
+ MARSView = Struct.new(:cells, :palettes, :options)
37
39
 
38
40
  class MARSRuntimeException < StandardError
39
41
  end
@@ -243,7 +245,7 @@ module MARSLab
243
245
  end
244
246
  end
245
247
 
246
- # Major ambiguity here -- what does it mean for an word A to be "less than"
248
+ # Major ambiguity here -- what does it mean for a word A to be "less than"
247
249
  # word B? First assumption, don't compare opcodes. Second, we're just going
248
250
  # to implement one-field comparisons of B fields. Otherwise for full-word operands
249
251
  # we'd need to do a lexicographic compare of A and B fields of both operands, skipping
@@ -394,7 +396,7 @@ module MARSLab
394
396
 
395
397
  To help visualize the operation of a program the class keeps a history of memory
396
398
  references made by each thread. A call to next automatically records the program counter
397
- value, but a semantic routine can also all log(x) to append location x to a history.
399
+ value, but a semantic routine can also call log(x) to append location x to a history.
398
400
  Call history to get the history vectors for all threads.
399
401
  =end
400
402
 
@@ -612,91 +614,7 @@ module MARSLab
612
614
  end
613
615
 
614
616
  end # MiniMARS
615
-
616
- =begin rdoc
617
- Make a window to display the state of the machine
618
- =end
619
-
620
- class Draw
621
-
622
- @@cellSize = 8
623
- @@cellRows = 32
624
- @@cellCols = 128
625
- @@padding = @@cellSize
626
- @@traceSize = 10
627
- @@cellColor = '#CCCCCC'
628
-
629
- def paintCell(i, color)
630
- @cells[i]['fill'] = color
631
- end
632
-
633
- def fillCanvas(mem)
634
- @cells = []
635
- mem.each_with_index do |val, i|
636
- x = (i % @@cellCols) * @@cellSize + @@padding
637
- y = (i / @@cellCols) * @@cellSize + @@padding
638
- @cells << TkcRectangle.new( @canvas, x, y, x+@@cellSize, y+@@cellSize, :outline => "#888888", :fill => @@cellColor )
639
- end
640
- end
641
-
642
- def reset
643
- @cells.each do |cell|
644
- cell['fill'] = @@cellColor
645
- end
646
- end
647
-
648
- # Make a range of colors starting from first and going to last in n steps.
649
- # First and last are expected to be 3-tuples of integer RGB values. The
650
- # result is an array that starts with first, has n-1 intermediate colors,
651
- # and ends with last. Example:
652
- # makePalette( [255,0,0], [0,0,0], 10)
653
- # makes 11 colors starting with red and ending with black.
654
-
655
- def makePalette(first, last, n)
656
- d = Array.new(3)
657
- 3.times { |i| d[i] = (first[i] - last[i]) / n }
658
- a = [first]
659
- (n-1).times do |i|
660
- a << a.last.clone
661
- 3.times { |j| a.last[j] -= d[j] }
662
- end
663
- a << last
664
- a.map { |c| sprintf("#%02X%02X%02X",c[0],c[1],c[2]) }
665
- end
666
-
667
- def updateCells(pc)
668
- id = pc.id
669
- a = pc.history[pc.current[:thread]]
670
- d = @palette[id].length - a.length
671
- a.each_with_index do |x, i|
672
- paintCell(x, @palette[id][i+d])
673
- end
674
- end
675
-
676
- def initialize(parent)
677
- content = TkFrame.new(parent)
678
- @canvas = TkCanvas.new(content, :borderwidth => 1,
679
- :width => @@cellCols*@@cellSize+@@padding, :height => @@cellRows*@@cellSize+@@padding)
680
- fillCanvas(Array.new(4096))
681
-
682
- @canvas.grid :column => 0, :row => 0, :columnspan => 4, :padx => 10, :pady => 10
683
- content.pack :pady => 20
684
-
685
- # initialize palettes with blends from a dingy color to gray, then
686
- # add a bright color as the last item
687
-
688
- @palette = [
689
- makePalette( [204,204,204], [204,100,100], @@traceSize ),
690
- makePalette( [204,204,204], [100,100,204], @@traceSize ),
691
- makePalette( [204,204,204], [100,204,100], @@traceSize ),
692
- ]
693
- @palette[0] << "#FF0000"
694
- @palette[1] << "#0000FF"
695
- @palette[2] << "#00FF00"
696
- end
697
-
698
- end # class Draw
699
-
617
+
700
618
 
701
619
  =begin rdoc
702
620
  The MARS module is a package that has the methods used to assemble, load, and execute
@@ -890,7 +808,7 @@ module MARSLab
890
808
  printf("%04d: %s\n", pc.current[:addr], instr) if @@params[:tracing]
891
809
 
892
810
  if @@drawing
893
- @@drawing.updateCells(pc)
811
+ MARS.updateCells(pc)
894
812
  sleep(@@params[:pace])
895
813
  end
896
814
 
@@ -967,63 +885,89 @@ module MARSLab
967
885
  only when no programs are loaded)
968
886
  =end
969
887
 
970
- def MARS.set_option(key, val)
971
- if ! @@entries.empty?
972
- puts "Options can be set only when no programs are loaded (call 'reset' to clear programs)"
973
- return false
974
- end
975
- case key
976
- when :memSize
977
- if val.class != Fixnum || val < 1024 || val > 16536
978
- puts ":memSize must be an integer between 1024 and 16536"
979
- return nil
980
- end
981
- when :maxRounds, :buffer
982
- if val.class != Fixnum
983
- puts ":#{key} must be an integer"
984
- return nil
888
+ def MARS.set_option(key, val)
889
+ if ! @@entries.empty?
890
+ puts "Options can be set only when no programs are loaded (call 'reset' to clear programs)"
891
+ return false
985
892
  end
986
- when :pace
987
- if val.class != Float
988
- puts ":#{key} must be an floating point number (e.g. 0.05)"
989
- return nil
990
- end
991
- when :tracing
992
- if ! (val.class == TrueClass || val.class == FalseClass)
993
- puts ":tracing must be true or false"
893
+ case key
894
+ when :memSize
895
+ if val.class != Fixnum || val < 1024 || val > 16536
896
+ puts ":memSize must be an integer between 1024 and 16536"
897
+ return nil
898
+ end
899
+ when :maxRounds, :buffer
900
+ if val.class != Fixnum
901
+ puts ":#{key} must be an integer"
902
+ return nil
903
+ end
904
+ when :pace
905
+ if val.class != Float
906
+ puts ":#{key} must be an floating point number (e.g. 0.05)"
907
+ return nil
908
+ end
909
+ when :tracing
910
+ if ! (val.class == TrueClass || val.class == FalseClass)
911
+ puts ":tracing must be true or false"
912
+ return nil
913
+ end
914
+ else
915
+ puts "Unknown option: #{key}"
994
916
  return nil
995
917
  end
996
- else
997
- puts "Unknown option: #{key}"
998
- return nil
918
+ @@params[key] = val
999
919
  end
1000
- @@params[key] = val
1001
- end
1002
920
 
1003
921
  =begin rdoc
1004
922
  view() -- open a visual view of the machine state
923
+
924
+ initialize palettes with blends from a dingy color to gray, then
925
+ add a bright color as the last item
1005
926
  =end
1006
927
 
1007
- def MARS.view
1008
- require 'tk'
1009
-
1010
- if ! defined? @@tkroot
1011
- @@tkroot = TkRoot.new { title "MARS" }
1012
- end
1013
-
1014
- if @@drawing == nil
1015
- @@drawing = Draw.new(@tkroot)
1016
- @@threads = []
1017
- @@threads << Thread.new() do
1018
- Tk.mainloop
1019
- end
1020
- end
928
+ def MARS.view(userOptions = {} )
929
+
930
+ options = @@viewOptions.merge(userOptions)
931
+
932
+ cellsize = options[:cellSize]
933
+ padding = options[:padding]
934
+
935
+ width = options[:cellCols] * cellsize + 2*padding
936
+ height = options[:cellRows] * cellsize + 2*padding
937
+ Canvas.init(width, height, "MARSLab")
938
+
939
+ cells = []
940
+ for i in 0...@@displayMemSize
941
+ x = (i % options[:cellCols]) * cellsize + padding
942
+ y = (i / options[:cellCols]) * cellsize + padding
943
+ cells << Canvas::Rectangle.new( x, y, x+cellsize, y+cellsize, :outline => "#888888", :fill => options[:cellColor] )
944
+ end
945
+
946
+ palettes = [
947
+ Canvas.palette( [204,204,204], [204,100,100], options[:traceSize] ),
948
+ Canvas.palette( [204,204,204], [100,100,204], options[:traceSize] ),
949
+ Canvas.palette( [204,204,204], [100,204,100], options[:traceSize] ),
950
+ ]
951
+ palettes[0] << "#FF0000"
952
+ palettes[1] << "#0000FF"
953
+ palettes[2] << "#00FF00"
954
+
955
+ @@drawing = MARSView.new(cells, palettes, options)
956
+ return true
957
+
1021
958
  end
1022
959
 
1023
960
  def MARS.close_view
1024
- @@threads[0].kill
1025
- @@tkroot.destroy
1026
- @@drawing = nil
961
+ Canvas.close
962
+ end
963
+
964
+ def MARS.updateCells(pc)
965
+ id = pc.id
966
+ a = pc.history[pc.current[:thread]]
967
+ d = @@drawing.palettes[id].length - a.length
968
+ a.each_with_index do |x, i|
969
+ @@drawing.cells[x].fill = @@drawing.palettes[id][i+d]
970
+ end
1027
971
  end
1028
972
 
1029
973
  =begin rdoc
@@ -1052,7 +996,12 @@ module MARSLab
1052
996
  @@mem = Memory.new(@@params[:memSize])
1053
997
  @@entries = Array.new
1054
998
  Warrior.reset
1055
- @@drawing.reset if @@drawing
999
+ if @@drawing
1000
+ @@drawing.cells.each do |x|
1001
+ x.fill = @@drawing.options[:cellColor]
1002
+ end
1003
+ end
1004
+ return true
1056
1005
  end
1057
1006
 
1058
1007
  =begin rdoc
@@ -1100,7 +1049,7 @@ module MARSLab
1100
1049
  end
1101
1050
  return nil
1102
1051
  end
1103
-
1052
+
1104
1053
  end # class MARS
1105
1054
 
1106
1055
 
@@ -1136,6 +1085,15 @@ module MARSLab
1136
1085
  :pace => 0.01,
1137
1086
  }
1138
1087
 
1088
+ @@viewOptions = {
1089
+ :cellSize => 8,
1090
+ :cellRows => 32,
1091
+ :cellCols => 128,
1092
+ :padding => 20,
1093
+ :traceSize => 10,
1094
+ :cellColor => '#DDDDDD',
1095
+ }
1096
+
1139
1097
  @@drawing = nil
1140
1098
 
1141
1099
  @@pcs = Array.new
data/lib/randomlab.rb CHANGED
@@ -86,7 +86,20 @@ module RandomLab
86
86
  def new_deck
87
87
  (0..51).map { |i| Card.new(i) }
88
88
  end
89
+
90
+
91
+ =begin rdoc
92
+ Compute the probability of a duplicate item in a collection of n items
93
+ drawn from the range [1..d]. Example: call pdup(5,52) to compute the
94
+ probability if drawing the same card twice when sampling with replacement
95
+ 5 times from a deck of 52 cards.
96
+ =end
89
97
 
98
+ def pdup(n, d)
99
+ return 1.0 if n > d
100
+ return 1.0 - (1..(n-1)).inject(1.0) { |p, k| p * (1.0 - (k / 52.0)) }
101
+ end
102
+
90
103
  =begin rdoc
91
104
  A "helper method" that can be called via a probe, to print the contents
92
105
  of an array during the execution of the permute! method
@@ -272,7 +285,7 @@ module RandomLab
272
285
  def view_numberline(npoints, userOptions = {})
273
286
  Canvas.init(500, 100, "RandomLab::NumberLine")
274
287
  options = @@numberLineOptions.merge(userOptions)
275
- line = Canvas.line(0, 70, 500, 70, :width => options[:lineThickness], :fill => options[:lineColor])
288
+ line = Canvas::Line.new(0, 70, 500, 70, :width => options[:lineThickness], :fill => options[:lineColor])
276
289
  @@drawing = NumberLine.new(line, npoints, options)
277
290
  return true
278
291
  end
@@ -286,7 +299,7 @@ module RandomLab
286
299
  x0, y0, x1, y1 = @@drawing.line.coords
287
300
  tx = (i.to_f / @@drawing.npoints) * (x1-x0)
288
301
  ty = y0 - @@drawing.options[:tickHeight]
289
- Canvas.line(tx, y0, tx, ty, :width => @@drawing.options[:tickWidth], :fill => @@drawing.options[:tickColor])
302
+ Canvas::Line.new(tx, y0, tx, ty, :width => @@drawing.options[:tickWidth], :fill => @@drawing.options[:tickColor])
290
303
  sleep(@@delay)
291
304
  end
292
305
  return true
@@ -321,7 +334,7 @@ module RandomLab
321
334
  binTop = 280
322
335
  nbins.times do |i|
323
336
  x = i * binWidth + binWidth/2
324
- bins << Canvas.rectangle( x + binBorder, binTop, x + binWidth - binBorder, binTop + binHeight, :outline => options[:binColor], :fill => options[:binColor] )
337
+ bins << Canvas::Rectangle.new( x + binBorder, binTop, x + binWidth - binBorder, binTop + binHeight, :outline => options[:binColor], :fill => options[:binColor] )
325
338
  end
326
339
 
327
340
  @@drawing = Histogram.new(bins, max.to_f, keys, counts, binTop, options)
@@ -364,6 +377,7 @@ module RandomLab
364
377
  end
365
378
  @@drawing.options[:boxIncrement] /= 2
366
379
  end
380
+ sleep(@@delay)
367
381
  return true
368
382
  end
369
383
 
@@ -393,7 +407,7 @@ module RandomLab
393
407
  py = (y.to_f / @@drawing.max) * Canvas.height
394
408
  r = @@drawing.options[:dotRadius]
395
409
  color = @@drawing.options[:dotColor]
396
- Canvas.circle( px, py, r, :outline => color, :fill => color )
410
+ Canvas::Circle.new( px, py, r, :outline => color, :fill => color )
397
411
  end
398
412
  return nil
399
413
  end
@@ -422,7 +436,7 @@ module RandomLab
422
436
  }
423
437
 
424
438
  @@drawing = nil
425
- @@delay = 0.1
439
+ @@delay = 0.01
426
440
 
427
441
  end # RandomLab
428
442