Решение на Пета задача - DataModel от Стамен Драгоев

Обратно към всички решения

Към профила на Стамен Драгоев

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 20 успешни тест(а)
  • 5 неуспешни тест(а)

Код

class ArrayStore
attr_reader :storage
def initialize
@storage = []
end
alias_method :format_for_search, :storage
def create(data = {})
@storage.push data
end
def find(data = {})
storage.select do |e|
(e.to_a & data.to_a) == data.to_a
end
end
def update(id, new_data = {})
@storage.each_with_index do |e, i|
@storage[i] = new_data if e[:id] == id
end
end
def delete(data = {})
@storage.length.times do
@storage.each_with_index { |e, i| @storage.delete_at(i) if e == data }
end
end
end
class HashStore
attr_reader :storage
def initialize
@storage = {}
end
def format_for_search
res = []
@storage.each { |_, v| res << v }
res
end
def create(data = {})
@storage[data[:id]] = data
end
def find(data = {})
res = []
@storage.each { |_, v| res << v if (v.to_a & data.to_a) == data.to_a }
res
end
def update(id, new_data = {})
@storage.each { |k, _| @storage[k] = new_data if k == id }
end
def delete(data = {})
@storage.length.times do
@storage.each { |k, v| @storage.delete(k) if v == data }
end
end
end
module ClassMethods
def attributes(*att)
if !@attributes_array
@attributes_array = att
att.each do |var|
work_with_attribute(var)
end
else
@attributes_array
end
end
def work_with_attribute(var)
attr_accessor var
define_singleton_method "find_by_#{var}" do |arg|
where({"#{var}": arg})
end
end
def data_store(*data)
if !@store
@store = data[0]
else
@store
end
end
def where(** attributes2)
attributes2.each do |name, _|
raise UnknownAttributeError unless @attributes_array.include?(name)
end
seek = attributes2.to_a
@store.format_for_search.select do |e|
(e.to_a & seek) == seek
end.map { |k| self.new(k.to_hash) }
end
end
class DataModel
class DeleteUnsavedRecordError < StandardError
end
class UnknownAttributeError < StandardError
end
attr_accessor :attributes_array, :store, :id
extend ClassMethods
def initialize(**attributes2)
@id = nil
self.class.attributes.each { |e| send "#{e}=", nil }
attributes2.each do |name, value|
send "#{name}=", value if self.class.attributes.include?(name)
end
end
def ==(other)
bool_one = self.class == other.class && id == other.id && id != nil
bool_two = equal?other
bool_one || bool_two
end
def delete
raise DeleteUnsavedRecordError if self.class.data_store.find(to_hash).empty?
self.class.data_store.delete(to_hash)
@id = nil
end
def save
if @id
self.class.data_store.update(@id, to_hash)
else
free_id = 0
self.class.data_store.format_for_search.each do |e|
free_id = e[:id] if e[:id] > free_id
end
@id = free_id + 1
self.class.data_store.create(to_hash)
end
end
def to_hash
values = []
(self.class.attributes << :id).each_with_index do |name, i|
values[i] = []
values[i] << name
values[i].push send name.to_s
end
values = values.to_h
end
end

Лог от изпълнението

.....F......FF.....F....F

Failures:

  1) DataModel id generation does not reuse ids
     Failure/Error: expect(georgi.id).to eq 2
       
       expected: 2
            got: 1
       
       (compared using ==)
     # /tmp/d20161202-15620-f3my1w/spec.rb:71:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  2) DataModel.where raises an error if the query is by an unknown key
     Failure/Error: expect { user_model.where(middle_name: 'Ivanov') }.to raise_error(
       expected DataModel::UnknownAttributeError with "Unknown attribute middle_name", got #<NameError: uninitialized constant ClassMethods::UnknownAttributeError> with backtrace:
         # /tmp/d20161202-15620-f3my1w/solution.rb:94:in `block in where'
         # /tmp/d20161202-15620-f3my1w/solution.rb:93:in `each'
         # /tmp/d20161202-15620-f3my1w/solution.rb:93:in `where'
         # /tmp/d20161202-15620-f3my1w/spec.rb:143:in `block (4 levels) in <top (required)>'
         # /tmp/d20161202-15620-f3my1w/spec.rb:143:in `block (3 levels) in <top (required)>'
         # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
         # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-f3my1w/spec.rb:143:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  3) DataModel#delete deletes only the record for which it is called
     Failure/Error: ivan.delete
     ArgumentError:
       wrong number of arguments (given 0, expected 1)
     # /tmp/d20161202-15620-f3my1w/spec.rb:156:in `delete'
     # /tmp/d20161202-15620-f3my1w/spec.rb:156:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  4) HashStore behaves like a data store #delete can delete multiple records with a single query
     Failure/Error: expect(store.find({})).to eq [gosho]
       
       expected: [{:id=>3, :name=>"Gosho"}]
            got: [{:id=>1, :name=>"Pesho"}, {:id=>2, :name=>"Pesho"}, {:id=>3, :name=>"Gosho"}]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>3, :name=>"Gosho"}]
       +[{:id=>1, :name=>"Pesho"}, {:id=>2, :name=>"Pesho"}, {:id=>3, :name=>"Gosho"}]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-f3my1w/spec.rb:235
     # /tmp/d20161202-15620-f3my1w/spec.rb:229:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  5) ArrayStore behaves like a data store #delete can delete multiple records with a single query
     Failure/Error: expect(store.find({})).to eq [gosho]
       
       expected: [{:id=>3, :name=>"Gosho"}]
            got: [{:id=>1, :name=>"Pesho"}, {:id=>2, :name=>"Pesho"}, {:id=>3, :name=>"Gosho"}]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>3, :name=>"Gosho"}]
       +[{:id=>1, :name=>"Pesho"}, {:id=>2, :name=>"Pesho"}, {:id=>3, :name=>"Gosho"}]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-f3my1w/spec.rb:239
     # /tmp/d20161202-15620-f3my1w/spec.rb:229:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.03033 seconds
25 examples, 5 failures

Failed examples:

rspec /tmp/d20161202-15620-f3my1w/spec.rb:62 # DataModel id generation does not reuse ids
rspec /tmp/d20161202-15620-f3my1w/spec.rb:142 # DataModel.where raises an error if the query is by an unknown key
rspec /tmp/d20161202-15620-f3my1w/spec.rb:151 # DataModel#delete deletes only the record for which it is called
rspec /tmp/d20161202-15620-f3my1w/spec.rb:218 # HashStore behaves like a data store #delete can delete multiple records with a single query
rspec /tmp/d20161202-15620-f3my1w/spec.rb:218 # ArrayStore behaves like a data store #delete can delete multiple records with a single query

История (3 версии и 7 коментара)

Стамен обнови решението на 29.11.2016 22:25 (преди около 8 години)

+class ArrayStore
+ def initialize
+ @array = []
+ end
+
+ def storage
+ @array
+ end
+
+ alias_method :format_for_search, :storage
+
+ def create(data = {})
+ @array.push data
+ end
+
+ def find(data = {})
+ storage.select do |e|
+ (e.to_a & data.to_a) == data.to_a
+ end
+ end
+
+ def update(id, newdata = {})
+ @array.each_with_index do |e, i|
+ @array[i] = newdata if e[:id] == id
+ end
+ end
+
+ def delete(data = {})
+ @array.length.times do
+ @array.each_with_index { |e, i| @array.delete_at(i) if e == data }
+ end
+ end
+end
+
+class HashStore
+ def initialize
+ @hash = {}
+ end
+
+ def format_for_search
+ res = []
+ @hash.each { |_, v| res << v }
+ res
+ end
+
+ def storage
+ @hash
+ end
+
+ def create(data = {})
+ @hash[data[:id]] = data
+ end
+
+ def find(data = {})
+ res = []
+ @hash.each { |_, v| res << v if (v.to_a & data.to_a) == data.to_a }
+ res
+ end
+
+ def update(id, newdata = {})
+ @hash.each { |k, _| @hash[k] = newdata if k == id }
+ end
+
+ def delete(data = {})
+ @hash.length.times do
+ @hash.each { |k, v| @hash.delete(k) if v == data }
+ end
+ end
+end
+
+module ClassMethods
+ def attributes(*att)
+ if !@arr
+ @arr = att
+ att.each do |var|
+ work_with_attribute(var)
+ end
+ else
+ @arr
+ end
+ end
+
+ def work_with_attribute(var)
+ attr_accessor var
+ define_singleton_method "find_by_#{var}" do |arg|
+ where({"#{var}": arg})
+ end
+ end
+
+ def data_store(*data)
+ if !@store
+ @store = data[0]
+ else
+ @store
+ end
+ end
+
+ def where(** attributes2)
+ attributes2.each do |name, _|
+ raise UnknownAttributeError unless @arr.include?(name)
+ end
+ seek = attributes2.to_a
+ @store.format_for_search.select do |e|
+ (e.to_a & seek) == seek
+ end.map { |k| self.new(k.to_hash) }
+ end
+end
+
+class DataModel
+
+ class DeleteUnsavedRecordError < StandardError
+ end
+ class UnknownAttributeError < StandardError
+ end
+
+ attr_accessor :arr, :store, :id
+
+ extend ClassMethods
+
+ def initialize(**attributes2)
+ @id = nil
+ self.class.attributes.each { |e| send "#{e}=", nil }
+ attributes2.each do |name, value|
+ send "#{name}=", value if self.class.attributes.include?(name)
+ end
+ end
+
+ def ==(other)
+ bool_one = self.class == other.class && id == other.id && id != nil
+ bool_two = equal?other
+ bool_one || bool_two
+ end
+
+ def delete
+ raise DeleteUnsavedRecordError if self.class.data_store.find(to_hash).empty?
+ self.class.data_store.delete(to_hash)
+ @id = nil
+ end
+
+ def save
+ if !@id
+ free_id = 0
+ ObjectSpace.each_object(self.class).to_a.select { |a| a.id != nil }.each do |e|
+ free_id = e.id if e.id > free_id
+ end
+ @id = free_id + 1
+ self.class.data_store.create(to_hash)
+ else
+ self.class.data_store.update(@id, to_hash)
+ end
+ end
+
+ def to_hash
+ values = []
+ (self.class.attributes << :id).each_with_index do |name, i|
+ values[i] = []
+ values[i] << name
+ values[i].push send name.to_s
+ end
+ values = values.to_h
+ end
+end

Стамен обнови решението на 30.11.2016 09:52 (преди около 8 години)

class ArrayStore
def initialize
- @array = []
+ @base = []
end
def storage
- @array
+ @base
end
alias_method :format_for_search, :storage
def create(data = {})
- @array.push data
+ @base.push data
end
def find(data = {})
storage.select do |e|
(e.to_a & data.to_a) == data.to_a
end
end
- def update(id, newdata = {})
- @array.each_with_index do |e, i|
- @array[i] = newdata if e[:id] == id
+ def update(id, new_data = {})
+ @base.each_with_index do |e, i|
+ @base[i] = new_data if e[:id] == id
end
end
def delete(data = {})
- @array.length.times do
- @array.each_with_index { |e, i| @array.delete_at(i) if e == data }
+ @base.length.times do
+ @base.each_with_index { |e, i| @base.delete_at(i) if e == data }
end
end
end
class HashStore
def initialize
- @hash = {}
+ @base = {}
end
def format_for_search
res = []
- @hash.each { |_, v| res << v }
+ @base.each { |_, v| res << v }
res
end
def storage
- @hash
+ @base
end
def create(data = {})
- @hash[data[:id]] = data
+ @base[data[:id]] = data
end
def find(data = {})
res = []
- @hash.each { |_, v| res << v if (v.to_a & data.to_a) == data.to_a }
+ @base.each { |_, v| res << v if (v.to_a & data.to_a) == data.to_a }
res
end
- def update(id, newdata = {})
- @hash.each { |k, _| @hash[k] = newdata if k == id }
+ def update(id, new_data = {})
+ @base.each { |k, _| @base[k] = new_data if k == id }
end
def delete(data = {})
- @hash.length.times do
- @hash.each { |k, v| @hash.delete(k) if v == data }
+ @base.length.times do
+ @base.each { |k, v| @base.delete(k) if v == data }
end
end
end
module ClassMethods
def attributes(*att)
- if !@arr
- @arr = att
+ if !@attributes_array
+ @attributes_array = att
att.each do |var|
work_with_attribute(var)
end
else
- @arr
+ @attributes_array
end
end
def work_with_attribute(var)
attr_accessor var
define_singleton_method "find_by_#{var}" do |arg|
where({"#{var}": arg})
end
end
def data_store(*data)
if !@store
@store = data[0]
else
@store
end
end
def where(** attributes2)
attributes2.each do |name, _|
- raise UnknownAttributeError unless @arr.include?(name)
+ raise UnknownAttributeError unless @attributes_array.include?(name)
end
seek = attributes2.to_a
@store.format_for_search.select do |e|
(e.to_a & seek) == seek
end.map { |k| self.new(k.to_hash) }
end
end
class DataModel
class DeleteUnsavedRecordError < StandardError
end
class UnknownAttributeError < StandardError
end
- attr_accessor :arr, :store, :id
+ attr_accessor :attributes_array, :store, :id
extend ClassMethods
def initialize(**attributes2)
@id = nil
self.class.attributes.each { |e| send "#{e}=", nil }
attributes2.each do |name, value|
send "#{name}=", value if self.class.attributes.include?(name)
end
end
def ==(other)
bool_one = self.class == other.class && id == other.id && id != nil
bool_two = equal?other
bool_one || bool_two
end
def delete
raise DeleteUnsavedRecordError if self.class.data_store.find(to_hash).empty?
self.class.data_store.delete(to_hash)
@id = nil
end
def save
- if !@id
+ if @id
+ self.class.data_store.update(@id, to_hash)
+ else
free_id = 0
- ObjectSpace.each_object(self.class).to_a.select { |a| a.id != nil }.each do |e|
- free_id = e.id if e.id > free_id
- end
+ self.class.data_store.format_for_search.each do |e|
+ free_id = e[:id] if e[:id] > free_id
+ end
@id = free_id + 1
self.class.data_store.create(to_hash)
- else
- self.class.data_store.update(@id, to_hash)
end
end
def to_hash
values = []
(self.class.attributes << :id).each_with_index do |name, i|
values[i] = []
values[i] << name
values[i].push send name.to_s
end
values = values.to_h
end
end

Стамен обнови решението на 30.11.2016 23:08 (преди около 8 години)

class ArrayStore
+ attr_reader :storage
def initialize
- @base = []
+ @storage = []
end
- def storage
- @base
- end
-
alias_method :format_for_search, :storage
def create(data = {})
- @base.push data
+ @storage.push data
end
def find(data = {})
storage.select do |e|
(e.to_a & data.to_a) == data.to_a
end
end
def update(id, new_data = {})
- @base.each_with_index do |e, i|
- @base[i] = new_data if e[:id] == id
+ @storage.each_with_index do |e, i|
+ @storage[i] = new_data if e[:id] == id
end
end
def delete(data = {})
- @base.length.times do
- @base.each_with_index { |e, i| @base.delete_at(i) if e == data }
+ @storage.length.times do
+ @storage.each_with_index { |e, i| @storage.delete_at(i) if e == data }
end
end
end
class HashStore
+ attr_reader :storage
def initialize
- @base = {}
+ @storage = {}
end
def format_for_search
res = []
- @base.each { |_, v| res << v }
+ @storage.each { |_, v| res << v }
res
end
- def storage
- @base
- end
-
def create(data = {})
- @base[data[:id]] = data
+ @storage[data[:id]] = data
end
def find(data = {})
res = []
- @base.each { |_, v| res << v if (v.to_a & data.to_a) == data.to_a }
+ @storage.each { |_, v| res << v if (v.to_a & data.to_a) == data.to_a }
res
end
def update(id, new_data = {})
- @base.each { |k, _| @base[k] = new_data if k == id }
+ @storage.each { |k, _| @storage[k] = new_data if k == id }
end
def delete(data = {})
- @base.length.times do
- @base.each { |k, v| @base.delete(k) if v == data }
+ @storage.length.times do
+ @storage.each { |k, v| @storage.delete(k) if v == data }
end
end
end
module ClassMethods
def attributes(*att)
if !@attributes_array
@attributes_array = att
att.each do |var|
work_with_attribute(var)
end
else
@attributes_array
end
end
def work_with_attribute(var)
attr_accessor var
define_singleton_method "find_by_#{var}" do |arg|
where({"#{var}": arg})
end
end
def data_store(*data)
if !@store
@store = data[0]
else
@store
end
end
def where(** attributes2)
attributes2.each do |name, _|
raise UnknownAttributeError unless @attributes_array.include?(name)
end
seek = attributes2.to_a
@store.format_for_search.select do |e|
(e.to_a & seek) == seek
end.map { |k| self.new(k.to_hash) }
end
end
class DataModel
class DeleteUnsavedRecordError < StandardError
end
class UnknownAttributeError < StandardError
end
attr_accessor :attributes_array, :store, :id
extend ClassMethods
def initialize(**attributes2)
@id = nil
self.class.attributes.each { |e| send "#{e}=", nil }
attributes2.each do |name, value|
send "#{name}=", value if self.class.attributes.include?(name)
end
end
def ==(other)
bool_one = self.class == other.class && id == other.id && id != nil
bool_two = equal?other
bool_one || bool_two
end
def delete
raise DeleteUnsavedRecordError if self.class.data_store.find(to_hash).empty?
self.class.data_store.delete(to_hash)
@id = nil
end
def save
if @id
self.class.data_store.update(@id, to_hash)
else
free_id = 0
self.class.data_store.format_for_search.each do |e|
free_id = e[:id] if e[:id] > free_id
end
@id = free_id + 1
self.class.data_store.create(to_hash)
end
end
def to_hash
values = []
(self.class.attributes << :id).each_with_index do |name, i|
values[i] = []
values[i] << name
values[i].push send name.to_s
end
values = values.to_h
end
end