danica 2.4.4 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e650cc12cd4ccaaf7eaebd6f8084ae46211f0cf
4
- data.tar.gz: 7b9cef3c43db7851160e95f6a2700dfde13f5a28
3
+ metadata.gz: dbc5e0d585c75c30257524380ed56a556daa08c5
4
+ data.tar.gz: 429e5c4ed8845329ebd79f9bfa9353b809e1e763
5
5
  SHA512:
6
- metadata.gz: 0acaff19e60a377126d74cfa90441098329f19603b7467e208f672e1ba7a95242beed67125028cd8c1979f5fb9b4443b877aa27ec24bf8e421f6f44970f983b3
7
- data.tar.gz: 3d5be06b0da8ea1569f17354b711ce328f0577b169af1a8a191f6de883d6cbb2b3aab38fe3c2f03511f0f1aa5f72d819146d3bac3107e32364d9e6030d0ace14
6
+ metadata.gz: 4fb11c37df1b65c3b960d5d9cf1fecd828e445171e950b16c9f532190e490d37b733923be0d3fc809e54eb1d8cd27fcf9f05b02af60eb4772d13280ffbf825f0
7
+ data.tar.gz: e737d1f7f965f29bc7d95a44744385400f12c6b863544a52ea06f851cb137b0a0a33ce90d669c5d2effe79e575d4eeb92a1cff49dbd2fc2ebacd6796542e35b3
@@ -5,8 +5,11 @@ module Danica
5
5
  autoload :BaseOperations, 'danica/base_operations'
6
6
  autoload :VariablesHolder, 'danica/variables_holder'
7
7
  autoload :Common, 'danica/common'
8
+ autoload :Expression, 'danica/expression'
9
+ autoload :Equation, 'danica/equation'
8
10
  autoload :Function, 'danica/function'
9
11
  autoload :Exception, 'danica/exception'
12
+ autoload :Expressable, 'danica/expressable'
10
13
 
11
14
  autoload :DSL, 'danica/dsl'
12
15
  autoload :Wrapper, 'danica/wrapper'
@@ -0,0 +1,17 @@
1
+ module Danica
2
+ class Equation
3
+ include Common
4
+ include VariablesHolder
5
+
6
+ variables :left, :right
7
+
8
+ def initialize(*args)
9
+ self.variables = args.flatten
10
+ end
11
+
12
+ def to(format)
13
+ "#{left.to(format)} = #{right.to(format)}"
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,39 @@
1
+ module Danica
2
+ module Expressable extend ::ActiveSupport::Concern
3
+ included do
4
+ include VariablesHolder
5
+
6
+ class << self
7
+ def built_with(block_name)
8
+ self.send(:delegate, :to_f, to: block_name)
9
+
10
+ self.send(:define_singleton_method, :build) do |*vars, &block|
11
+ Class.new(self) do
12
+ variables(*vars)
13
+
14
+ private
15
+
16
+ module_eval("define_method :#{block_name} do
17
+ @#{block_name} ||= instance_eval(&block) if block
18
+ end")
19
+ end
20
+ end
21
+
22
+ self.send(:define_singleton_method, :create) do |*vars, &block|
23
+ build(*vars, &block).new
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def initialize(*args)
30
+ options = args.extract_options!
31
+
32
+ attributes = { variables: args.flatten }.merge(options)
33
+
34
+ attributes.each do |key, value|
35
+ self.public_send("#{key}=", value)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ module Danica
2
+ class Expression
3
+ include Common
4
+ include DSL
5
+ include BaseOperations
6
+ include Expressable
7
+
8
+ autoload :Gauss, 'danica/expression/gauss'
9
+
10
+ delegate :to, :is_grouped?, :priority, to: :expression_block
11
+
12
+ built_with(:expression_block)
13
+ end
14
+ end
@@ -1,5 +1,5 @@
1
1
  module Danica
2
- class Function::Gauss < Function.build(:x, average: { latex: '\mu', gnu: :u }, variance_root: { latex: '\sigma', gnu: :v }) { num(1) / denominator * exponential(exp) }
2
+ class Expression::Gauss < Expression.build(:x, average: { latex: '\mu', gnu: :u }, variance_root: { latex: '\sigma', gnu: :v }) { num(1) / denominator * exponential(exp) }
3
3
 
4
4
  private
5
5
 
@@ -1,80 +1,32 @@
1
1
  module Danica
2
- class Function
2
+ class Function < Equation
3
3
  include Common
4
- include VariablesHolder
5
4
  include DSL
5
+ include Expressable
6
6
 
7
- autoload :Gauss, 'danica/function/gauss'
8
7
  autoload :Name, 'danica/function/name'
9
-
10
8
  attr_accessor :name
11
9
 
12
- default_value :priority, 3
13
- default_value :is_grouped?, false
14
- delegate :to_f, :to, to: :function_block
15
-
16
- def self.build(*vars, &block)
17
- Class.new(self) do
18
- variables(*vars)
19
-
20
- private
21
-
22
- define_method :function_block do
23
- @function_block ||= instance_eval(&block) if block
24
- end
25
- end
26
- end
27
-
28
- def self.create(*vars, &block)
29
- build(*vars, &block).new
30
- end
31
-
32
- def initialize(*args)
33
- options = args.extract_options!
34
-
35
- attributes = { variables: args.flatten }.merge(options)
36
-
37
- attributes.each do |key, value|
38
- self.public_send("#{key}=", value)
39
- end
40
- end
41
-
42
- def calculate(*args)
43
- vars_map = args.extract_options!
44
- vars_map = variables_value_hash.merge(vars_map)
45
- vars_map.each do |k, v|
46
- unless v && (v.is_a?(Integer) || v.valued?)
47
- vars_map[k] = args.shift
48
- end
49
- end
50
-
51
- self.class.new(vars_map).to_f
52
- end
53
-
54
- def describe(format)
55
- "#{name.to(format)} = #{to(format)}"
56
- end
10
+ reset_variables
57
11
 
58
- def describe_tex
59
- describe(:tex)
60
- end
61
-
62
- def describe_gnu
63
- describe(:gnu)
64
- end
12
+ built_with(:function_block)
65
13
 
66
14
  def name
67
- @name_object ||= Name.new(name: @name, variables: containers)
15
+ containers_hash[:left] ||= Danica::Wrapper::Container.new Name.new(name: @name, variables: containers)
68
16
  end
69
17
 
70
- private
18
+ def expression
19
+ @expression ||= Expression.build(:x) do
20
+ x
21
+ end.new(function_block)
22
+ end
71
23
 
72
- def description_variables(format)
73
- non_constant_variables.map { |v| v.to(format) }.join(', ')
24
+ def left
25
+ name
74
26
  end
75
27
 
76
- def non_constant_variables
77
- variables.reject(&:constant?)
28
+ def right
29
+ expression
78
30
  end
79
31
  end
80
32
  end
@@ -8,7 +8,9 @@ module Danica
8
8
  default_value :is_grouped?, false
9
9
 
10
10
  def initialize(*args)
11
- self.variables = args.flatten
11
+ args = args.flatten
12
+ args = args.first if (args.length == 1) && args.first.is_a?(Hash) && args.first.keys == self.class.variables_names
13
+ self.variables = args
12
14
  end
13
15
 
14
16
  def ==(other)
@@ -1,6 +1,8 @@
1
1
  module Danica
2
2
  module VariablesHolder extend ::ActiveSupport::Concern
3
- require 'danica/variables_holder/variables_builder'
3
+ autoload :VariablesBuilder, 'danica/variables_holder/variables_builder'
4
+ autoload :AliasBuilder, 'danica/variables_holder/alias_builder'
5
+ autoload :Calculator, 'danica/variables_holder/calculator'
4
6
 
5
7
  included do
6
8
  class << self
@@ -8,12 +10,25 @@ module Danica
8
10
  VariablesBuilder.new(names, self).build
9
11
  end
10
12
 
13
+ def variable_alias(origin, destiny)
14
+ AliasBuilder.new(origin, destiny, self).build
15
+ end
16
+
11
17
  def variables_names
12
18
  variables_hash.keys
13
19
  end
14
20
 
15
21
  def variables_hash
16
- @variables_hash ||= (superclass.try(:variables_hash) || {}).dup
22
+ @variables_hash ||= superclass_variables_hash.dup
23
+ end
24
+
25
+ def reset_variables
26
+ @superclass_variables_hash = {}
27
+ @variables_hash = nil
28
+ end
29
+
30
+ def superclass_variables_hash
31
+ @superclass_variables_hash ||= (superclass.try(:variables_hash) || {})
17
32
  end
18
33
  end
19
34
  end
@@ -26,6 +41,20 @@ module Danica
26
41
  end
27
42
  end
28
43
 
44
+ def extract_variables
45
+ variables.select do |var|
46
+ var.is_a?(VariablesHolder)
47
+ end.inject({}) do |hash, container|
48
+ hash.merge!(container.content.extract_variables)
49
+ end.tap do |hash|
50
+ containers_hash.select do |_, container|
51
+ container.content.is_a?(Wrapper::Variable)
52
+ end.each do |key, container|
53
+ hash[(container.content.name || key).to_sym] = container
54
+ end
55
+ end
56
+ end
57
+
29
58
  def variables
30
59
  containers.map(&:content)
31
60
  end
@@ -49,5 +78,9 @@ module Danica
49
78
  var.try(:value)
50
79
  end.as_hash(self.class.variables_names)
51
80
  end
81
+
82
+ def calculate(*args)
83
+ Calculator.new(self, *args).calculate
84
+ end
52
85
  end
53
86
  end
@@ -0,0 +1,20 @@
1
+ module Danica::VariablesHolder
2
+ class AliasBuilder
3
+
4
+ attr_reader :clazz, :origin, :destiny
5
+
6
+ def initialize(origin, destiny, clazz)
7
+ @origin = origin
8
+ @destiny = destiny
9
+ @clazz = clazz
10
+ end
11
+
12
+ def build
13
+ clazz.variables_hash.change_keys! { |k| k == origin ? destiny : k }
14
+ VariablesBuilder.new([ destiny ], clazz).build
15
+ clazz.send(:alias_method, "#{origin}=", "#{destiny}=")
16
+ clazz.send(:alias_method, origin, destiny)
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,45 @@
1
+ module Danica
2
+ module VariablesHolder
3
+ class Calculator
4
+ attr_accessor :object, :args
5
+
6
+ def initialize(object, *args)
7
+ @object = object
8
+ @args = args
9
+ end
10
+
11
+ def calculate
12
+ raise Exception::NotDefined unless all_valued?
13
+
14
+ clazz.new(vars_map).to_f
15
+ end
16
+
17
+ private
18
+
19
+ def vars_map
20
+ @vars_map ||= variables_value_hash.tap do |map|
21
+ vars = args.dup
22
+ map.merge! vars.extract_options!
23
+ vars_map = vars.as_hash(map.keys).select { |_, v| valued?(v) }
24
+ map.merge! vars_map
25
+ end
26
+ end
27
+
28
+ def all_valued?
29
+ vars_map.values.all? { |v| valued?(v) }
30
+ end
31
+
32
+ def valued?(value)
33
+ value.is_a?(Integer) || value.try(:valued?)
34
+ end
35
+
36
+ def variables_value_hash
37
+ @variables_value_hash ||= object.variables_value_hash.dup
38
+ end
39
+
40
+ def clazz
41
+ @clazz ||= object.class
42
+ end
43
+ end
44
+ end
45
+ end
@@ -30,13 +30,7 @@ module Danica::VariablesHolder
30
30
 
31
31
  def add_setter(name)
32
32
  instance.send(:define_method, "#{name}=") do |value|
33
- if(containers_hash[name.to_sym].try(:container?))
34
- containers_hash[name.to_sym].content = wrap_value(value)
35
- else
36
- value = wrap_value(value)
37
- value = Danica::Wrapper::Container.new value unless value.container?
38
- containers_hash[name.to_sym] = value
39
- end
33
+ containers_hash[name.to_sym].content = wrap_value(value)
40
34
  end
41
35
  end
42
36
 
@@ -1,3 +1,3 @@
1
1
  module Danica
2
- VERSION = '2.4.4'
2
+ VERSION = '2.5.0'
3
3
  end
@@ -4,7 +4,8 @@ module Danica
4
4
  attr_accessor :content
5
5
 
6
6
  delegate :to_f, :contentd?, :to, :to_tex, :to_gnu, :priority, :grouped?,
7
- :signaled?, :constant?, :valued?, :*, :+, :-, :/, :**, to: :content
7
+ :signaled?, :constant?, :valued?, :*, :+, :-, :/, :**,
8
+ :variables, to: :content
8
9
 
9
10
  default_value :container?, true
10
11
 
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Danica::Equation do
4
+ let(:left) do
5
+ Danica::Expression.create(:y) { y }
6
+ end
7
+ let(:right) do
8
+ Danica::Expression.create(:x) { x ** 2 }
9
+ end
10
+
11
+ subject { described_class.new(left, right) }
12
+
13
+ describe '#to_f' do
14
+ it do
15
+ expect { subject.to_f }.to raise_error(Danica::Exception::NotImplemented)
16
+ end
17
+ end
18
+
19
+ describe '#to_tex' do
20
+ it 'joins the expressions in a equation' do
21
+ expect(subject.to_tex).to eq('y = x^{2}')
22
+ end
23
+ end
24
+
25
+ describe '#to_gnu' do
26
+ it 'joins the expressions in a equation' do
27
+ expect(subject.to_gnu).to eq('y = x**(2)')
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ class Danica::Expressable::Dummy
4
+ include Danica::Expressable
5
+
6
+ built_with :the_block
7
+ end
8
+
9
+ describe Danica::Expressable do
10
+ let(:clazz) { described_class::Dummy }
11
+
12
+ describe '.build' do
13
+ it 'responds to build' do
14
+ expect(clazz).to respond_to(:build)
15
+ end
16
+
17
+ it 'returns a child class object' do
18
+ expect(clazz.build(:x) do
19
+ x
20
+ end.superclass).to be(clazz)
21
+ end
22
+ end
23
+
24
+ describe '.create' do
25
+ it 'responds to create' do
26
+ expect(clazz).to respond_to(:create)
27
+ end
28
+
29
+ it do
30
+ expect(clazz.create(:x) do
31
+ x
32
+ end).to be_a(clazz)
33
+ end
34
+ end
35
+ end