Permalink
Browse files

First commit. Only the core functionality exists here.

  • Loading branch information...
0 parents commit 5b8857bc06f72337e0f316bd1efd7bea95f831b7 @therealplato committed Feb 25, 2012
Showing with 392 additions and 0 deletions.
  1. +70 −0 dashboard.rb
  2. +54 −0 lib/crawler.rb
  3. +110 −0 lib/test_trustcore.rb
  4. +150 −0 lib/trustcore.rb
  5. +8 −0 readme.txt
70 dashboard.rb
@@ -0,0 +1,70 @@
+#!/usr/bin/ruby
+$LOAD_PATH << './lib'
+require 'trustcore'
+include TrustCore
+require 'crawler'
+include Crawler
+
+class Dashboard
+ attr_accessor :web
+ def initialize()
+ self.setupTestData#.runCrawler.displayResults
+ end
+
+ def setupTestData3
+ @a=Nym.new("alice")
+ @b=Nym.new("bob")
+ @nyms = [@a,@b]
+ @links=Link.new(@a,@b, BinaryRating.new(true))
+ @web=Web.new(@links)
+ end
+ def setupTestData
+ #would be nice to do $ crawler new --nymcount=8 --behaviour=random
+ @nyms=[]
+ @links=[]
+ @nyms << Nym.new("andrea")
+ @nyms << Nym.new("briana")
+ @nyms << Nym.new("claire")
+ @nyms << Nym.new("diana")
+ @nyms << Nym.new("erica")
+ @nyms << Nym.new("fergie")
+ @nyms << Nym.new("giana")
+ @nyms << Nym.new("helga")
+
+ # andrea through diana are legitimate businessppl
+ #what a shitty way to build new links!
+ #fix: links share instances of ratings
+ #@links<<Link.new(Andrea, Erica, BinaryRating.new(true))
+ @plus = BinaryRating.new(true)
+ @minus = BinaryRating.new(false) # SOURCE SINK RATING
+ @links << Link.new(@nyms[0], @nyms[1], @plus) # alice briana +
+ @links << Link.new(@nyms[0], @nyms[2], @plus) # alice claire +
+ @links << Link.new(@nyms[0], @nyms[3], @plus) # alice diana +
+ @links << Link.new(@nyms[1], @nyms[0], @plus) # briana alice +
+ @links << Link.new(@nyms[1], @nyms[2], @plus) # briana claire +
+ @links << Link.new(@nyms[2], @nyms[1], @plus) # claire briana +
+ #Totals: alice.sink 1
+ # briana.sink 2
+ # claire.sink 2
+ # diana.sink 1
+ @web = Web.new(@links)
+ end
+
+ def listParticipants
+ @nyms.sort{|a,b|a.nick.downcase <=> b.nick.downcase}.each do |thisnym|
+ puts thisnym.to_s
+ end
+ end
+ def crawl1
+ #puts "passing web into crawler:\n"+@web.inspect
+ myCrawler=ExhaustiveBinaryCrawler.new(@web)
+ puts myCrawler.crawl
+ end
+
+ def displayResults
+
+ end
+end
+
+
+
54 lib/crawler.rb
@@ -0,0 +1,54 @@
+require 'trustcore'
+include TrustCore
+
+module Crawler
+class Crawler
+ def initialize(web)
+ fail "need a Web to crawl" unless web.is_a?(Web)
+ @web=web
+ @links=@web.links
+ end
+end
+
+class ExhaustiveBinaryCrawler < Crawler
+ # Checks every single combination of nodes
+ # Returns an array of hashes [ {Nym => Score}]
+ def initialize(web)
+ super(web)
+ #puts "after super, @web.inspect:\n"+@web.inspect
+ @scores={} #We'll return this
+ end
+ def crawl
+ #Count up the number of received positive ratings, then subtract the
+ #number of negative ratings, for each nym.
+ puts @scores
+ @links.each do |thislink|
+ #puts "entered crawl do loop for link\n"+thislink.inspect
+ unless thislink.is_a?(Link)
+ fail "found a non-Link object in this Crawler's @web"
+ end
+ #puts thislink.rating.class
+ unless thislink.rating.is_a?(BinaryRating)
+ fail "this binary crawler only handles binary ratings"
+ end
+
+ if !@scores.include?(thislink.sink) #sink Nym is not yet in scores
+ @scores.merge!({thislink.sink => 0}) #add it
+ #puts "added #{thislink.sink.to_s} to @scores, scores now is:\n"+@scores.inspect
+ end
+
+ case thislink.rating.score #Positive rating
+ when true
+ @scores[thislink.sink] += 1 #increment score for this rating
+ when false
+ @scores[thislink.sink] -= 1 #Negative rating, decrement score
+ when nil
+ else fail "unexpected non-trinary rating"
+ end
+ end
+ @scores.each_pair do |nym, score|
+ puts nym.to_s + ": " + score.to_s
+ end
+ end
+end
+end #of module Crawler
110 lib/test_trustcore.rb
@@ -0,0 +1,110 @@
+require File.expand_path(File.dirname(__FILE__) + '/trustcore')
+include TrustCore
+require "test/unit"
+class Nymtest < Test::Unit::TestCase
+ def test_default_nick
+ a=Nym.new
+ assert_equal "alice", a.nick
+ end
+ def test_nondefault_nick
+ b=Nym.new("bob")
+ assert_equal "bob", b.nick
+ end
+end
+
+class Ratetest < Test::Unit::TestCase
+ def test_create_rating
+ testnil1 = Rating.new
+ testnil2 = Rating.new(nil)
+ testtrue = Rating.new(true)
+ testfalse= Rating.new(false)
+
+ assert_equal nil, testnil1.score
+ assert_equal nil, testnil2.score
+ assert_equal true, testtrue.score
+ assert_equal false, testfalse.score
+ end
+ def test_binary_rating
+ testnil1 = BinaryRating.new()
+ testnil2 = BinaryRating.new(nil)
+ testtrue = BinaryRating.new(true)
+ testfalse = BinaryRating.new(false)
+
+ assert_raise TypeError do
+ testbad = BinaryRating.new(7)
+ end
+
+ assert_raise TypeError do
+ testbad2 = BinaryRating.new("A++")
+ end
+ assert_equal nil, testnil1.score
+ assert_equal nil, testnil2.score
+ assert_equal true, testtrue.score
+ assert_equal false, testfalse.score
+ end
+ def test_integer_rating
+ testnil1 = IntegerRating.new(1,5)
+ testnil2 = IntegerRating.new(1,5,nil)
+ test3 = IntegerRating.new(1,5,3)
+ test4 = IntegerRating.new(nil,nil,500)
+
+ assert_raise ArgumentError do
+ test5 = IntegerRating.new(1,5,10)
+ end
+
+ assert_raise ArgumentError do
+ testbad = IntegerRating.new(false)
+ end
+
+ assert_raise TypeError do
+ testbad2 = IntegerRating.new(5,4,"A++")
+ end
+ assert_equal nil, testnil1.score
+ assert_equal 1, testnil1.min
+ assert_equal 5, testnil1.max
+ assert_equal nil, testnil2.score
+ assert_equal 3, test3.score
+ assert_equal 500, test4.score
+ end
+end
+
+class Linktest < Test::Unit::TestCase
+ def test_link_defaults
+ a=Nym.new("alice")
+ b=Nym.new("bob")
+ r=BinaryRating.new(true)
+ ln=Link.new(a,b,r)
+
+ assert_equal ln.source, a
+ assert_equal ln.sink, b
+ assert_equal ln.rating, r
+
+ assert_equal ln.source.object_id, a.object_id
+ assert_equal ln.sink.object_id, b.object_id
+ assert_equal ln.rating.object_id, r.object_id
+
+ assert_equal ln.source.nick, "alice"
+ assert_equal ln.sink.nick, "bob"
+ assert_equal ln.rating.score, true
+ end
+end
+
+class Webtest < Test::Unit::TestCase
+ def setup
+ a=Nym.new("alice")
+ b=Nym.new("bob")
+ r=BinaryRating.new(true)
+ @ln=Link.new(a,b,r)
+ @ln2=Link.new(b,a,r)
+ end
+ def test_web_creation
+ w1 = Web.new()
+ w2 = Web.new(@ln)
+ w3 = Web.new(@ln, @ln2)
+ assert_equal false, w1==nil
+ assert_equal w1.links, []
+ assert_equal w2.links[0].source.nick, "alice"
+ assert_equal w2.links[0].rating.score, true
+ assert_equal w3.links[1].source.nick, "bob"
+ end
+end
150 lib/trustcore.rb
@@ -0,0 +1,150 @@
+#!/usr/bin/ruby
+module TrustCore
+class Nym
+#Holds information for a single identity
+#Params:
+#+nick+::Nickname for this nym
+
+ attr_accessor :nick
+ def initialize(nick="alice")
+ @nick=nick
+ end
+ def inspect
+ "#<Nym: #{@nick}>"
+ end
+ def to_s
+ "#{@nick}"
+ end
+end
+
+class Link
+#Creates a single trust link between two nyms
+#Params:
+#+source+:: +Nym+ object sending the rating
+#+sink+:: +Nym+ object receiving the rating
+#+rating+:: +Rating+ object associated with this link
+ attr_reader :source #read only, create a new link if nyms change
+ attr_reader :sink
+ attr_accessor :rating #rating between one source and sink may change
+ def initialize(source, sink, rating)
+ unless (source.is_a?(Nym)) && (sink.is_a?(Nym))
+ fail TypeError, "source and sink must both be Nym objects"
+ end
+ unless rating.is_a?(Rating)
+ fail TypeError, "rating must be a Rating object"
+ end
+ @source = source
+ @sink = sink
+ @rating = rating
+ end
+ def inspect
+ "#<Link: #{@source.to_s} -> #{@sink.to_s} (#{@rating.to_s})>"
+ end
+ def to_s
+ if @rating.score == nil
+ "#{@source.to_s} -> #{@sink.to_s}: [no rating]"
+ else
+ "#{@source.to_s} -> #{@sink.to_s}: [#{@rating.to_s}]"
+ end
+ end
+end
+
+class Rating
+#Abstract class for trust ratings
+#One rating shouldn't be used by multiple links
+#Params:
+#+score+::the trust score for this rating. extended in children classes
+ attr_reader :score
+ def initialize(score=nil)
+ @score=score
+ end
+end
+
+class BinaryRating < Rating
+#A true/false/nil rating
+#Params:
+#+score+:: must be true/false/nil, else raises +TypeError+
+#This only checks the type upon creation. It won't break if
+#+score+ is somehow modified after object creation.
+ def initialize(score=nil)
+ if ![true,false,nil].include? score
+ fail TypeError, "Only true/false/nil allowed in BinaryRating"
+ end
+ super(score)
+ end
+ def to_s
+ case @score
+ when true then "+"
+ when false then "-"
+ when nil then " "
+ else "?"
+ end
+ end
+ def inspect
+ case @score
+ when true then "+"
+ when false then "-"
+ when nil then " "
+ else "?"
+ end
+ end
+end
+
+class IntegerRating < Rating
+#An integer rating. Can be used with or without a range.
+#Usage: IntegerRating.new(nil,nil,9001); IntegerRating.new(1,10,8)
+#Params:
+#+min+::the minimum score allowed. nil means no upper bound.
+#+max+::the maximum score allowed. nil means no lower bound.
+#+score+::the integer rating. Raises ArgumentError if outside
+#and non-nil bounds. (i.e. <min or >max.)
+#Passing non-Fixnum, non-nil values into min or max will raise TypeError.
+ attr_reader :min
+ attr_reader :max
+ def initialize(min, max, score=nil)
+ if ![Fixnum, NilClass].include? score.class
+ fail TypeError, "Passed non-Fixnum, non-nil score into IntegerRating"
+ end
+ if ![Fixnum, NilClass].include? min.class
+ fail TypeError, "Passed non-Fixnum, non-nil minimum bound into IntegerRating"
+ end
+ if ![Fixnum, NilClass].include? max.class
+ fail TypeError, "Passed non-Fixnum, non-nil maximum bound into IntegerRating"
+ end
+ #The following only tests when the rating is created
+ if score && max && (score > max)
+ fail ArgumentError, "Score exceeds maximum bound"
+ elsif score && max && (score < min)
+ fail ArgumentError, "Score less than minimum bound"
+ end
+ super(score)
+ @min=min
+ @max=max
+ end
+ def inspect
+ if @score
+ ret=@score.rjust(4," ") #pad score to 4 characters, unless it's too long.
+ end
+ end
+end
+
+
+class Web
+ attr_accessor :links
+ #def links; @links; end
+ def initialize(*mylinks)
+ @links=[]
+ self.addLinks(*mylinks) if mylinks.length > 0
+ end
+ def addLinks(*mylinks)
+ [*mylinks].flatten.each do |thislink|
+ if thislink.is_a?(Link)
+ @links << thislink
+ else
+ wrong = thislink.class.to_s
+ fail "tried to add a non-Link to this Web (#{wrong})"
+ end
+ end
+ end
+end #of Web class
+end #of TrustCore module
8 readme.txt
@@ -0,0 +1,8 @@
+Usage:
+
+cd personae
+irb -I . #to launch an IRB session in this folder
+require 'dashboard'
+
+d=Dashboard.new
+d.crawl1

0 comments on commit 5b8857b

Please sign in to comment.