danica 2.7.1 → 2.7.6

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.
Files changed (123) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +71 -0
  3. data/.gitignore +6 -1
  4. data/.rubocop.yml +9 -0
  5. data/.rubocop_todo.yml +123 -0
  6. data/Dockerfile +22 -0
  7. data/Gemfile +2 -1
  8. data/README.md +9 -1
  9. data/Rakefile +4 -0
  10. data/config/check_specs.yml +13 -0
  11. data/config/rubycritc.rb +12 -0
  12. data/config/yardstick.rb +13 -0
  13. data/config/yardstick.yml +33 -0
  14. data/danica.gemspec +16 -9
  15. data/docker-compose.yml +14 -9
  16. data/lib/danica.rb +3 -1
  17. data/lib/danica/base_operations.rb +15 -7
  18. data/lib/danica/builder.rb +2 -0
  19. data/lib/danica/common.rb +24 -16
  20. data/lib/danica/dsl.rb +15 -9
  21. data/lib/danica/dsl/builder.rb +40 -0
  22. data/lib/danica/equation.rb +3 -3
  23. data/lib/danica/equation/builder.rb +2 -0
  24. data/lib/danica/exception.rb +14 -2
  25. data/lib/danica/expressable.rb +20 -16
  26. data/lib/danica/expression.rb +4 -2
  27. data/lib/danica/expression/gauss.rb +5 -5
  28. data/lib/danica/formatted.rb +34 -11
  29. data/lib/danica/function.rb +5 -3
  30. data/lib/danica/function/name.rb +2 -0
  31. data/lib/danica/operator.rb +13 -9
  32. data/lib/danica/operator/addition.rb +4 -7
  33. data/lib/danica/operator/chained.rb +4 -8
  34. data/lib/danica/operator/cos.rb +2 -1
  35. data/lib/danica/operator/division.rb +3 -2
  36. data/lib/danica/operator/exponential.rb +2 -1
  37. data/lib/danica/operator/functional.rb +3 -2
  38. data/lib/danica/operator/multiplication.rb +5 -7
  39. data/lib/danica/operator/power.rb +4 -3
  40. data/lib/danica/operator/sin.rb +2 -1
  41. data/lib/danica/operator/squared_root.rb +2 -1
  42. data/lib/danica/variables_holder.rb +27 -24
  43. data/lib/danica/variables_holder/alias_builder.rb +4 -4
  44. data/lib/danica/variables_holder/calculator.rb +2 -0
  45. data/lib/danica/variables_holder/store.rb +3 -2
  46. data/lib/danica/variables_holder/variables_builder.rb +2 -1
  47. data/lib/danica/version.rb +3 -1
  48. data/lib/danica/wrapper.rb +17 -9
  49. data/lib/danica/wrapper/constant.rb +10 -14
  50. data/lib/danica/wrapper/container.rb +4 -4
  51. data/lib/danica/wrapper/group.rb +3 -2
  52. data/lib/danica/wrapper/negative.rb +3 -1
  53. data/lib/danica/wrapper/number.rb +6 -3
  54. data/lib/danica/wrapper/plus_minus.rb +3 -1
  55. data/lib/danica/wrapper/variable.rb +13 -8
  56. data/scripts/check_readme.sh +6 -0
  57. data/scripts/rubycritic.sh +10 -0
  58. data/spec/integration/global/danica/formatted_spec.rb +87 -0
  59. data/spec/integration/global/danica/operator/addition_spec.rb +32 -0
  60. data/spec/integration/global/danica/operator/multiplication_spec.rb +106 -0
  61. data/spec/integration/{power_spec.rb → global/danica/operator/power_spec.rb} +4 -2
  62. data/spec/integration/global/danica/wrapper/negative_spec.rb +56 -0
  63. data/spec/integration/{plus_minus_spec.rb → global/danica/wrapper/plus_minus_spec.rb} +5 -4
  64. data/spec/integration/readme/constant_spec.rb +4 -1
  65. data/spec/integration/readme/danica/formatted_spec.rb +24 -0
  66. data/spec/integration/readme/danica_spec.rb +20 -4
  67. data/spec/integration/readme/equation_spec.rb +4 -2
  68. data/spec/integration/readme/expression_spec.rb +11 -8
  69. data/spec/integration/readme/function_spec.rb +11 -7
  70. data/spec/integration/readme/number_spec.rb +9 -8
  71. data/spec/integration/readme/operator_spec.rb +3 -1
  72. data/spec/integration/readme/variables_spec.rb +8 -6
  73. data/spec/lib/danica/common_spec.rb +79 -8
  74. data/spec/lib/danica/dsl_spec.rb +21 -18
  75. data/spec/lib/danica/equation_spec.rb +10 -8
  76. data/spec/lib/danica/expressable_spec.rb +5 -2
  77. data/spec/lib/danica/expression/gauss_spec.rb +6 -3
  78. data/spec/lib/danica/expression_spec.rb +48 -26
  79. data/spec/lib/danica/formatted_spec.rb +57 -24
  80. data/spec/lib/danica/function/name_spec.rb +3 -1
  81. data/spec/lib/danica/function_spec.rb +14 -10
  82. data/spec/lib/danica/operator/addition_spec.rb +18 -21
  83. data/spec/lib/danica/operator/cos_spec.rb +9 -8
  84. data/spec/lib/danica/operator/division_spec.rb +18 -17
  85. data/spec/lib/danica/operator/exponential_spec.rb +9 -8
  86. data/spec/lib/danica/operator/multiplication_spec.rb +19 -20
  87. data/spec/lib/danica/operator/power_spec.rb +17 -16
  88. data/spec/lib/danica/operator/sin_spec.rb +9 -8
  89. data/spec/lib/danica/operator/squared_root_spec.rb +9 -8
  90. data/spec/lib/danica/operator_spec.rb +13 -4
  91. data/spec/lib/danica/variables_holder/store_spec.rb +19 -13
  92. data/spec/lib/danica/variables_holder_spec.rb +76 -59
  93. data/spec/lib/danica/wrapper/constant_spec.rb +9 -2
  94. data/spec/lib/danica/wrapper/group_spec.rb +4 -1
  95. data/spec/lib/danica/wrapper/negative_spec.rb +4 -1
  96. data/spec/lib/danica/wrapper/number_spec.rb +8 -3
  97. data/spec/lib/danica/wrapper/plus_minus_spec.rb +4 -1
  98. data/spec/lib/danica/wrapper/variable_spec.rb +6 -3
  99. data/spec/lib/danica/wrapper_spec.rb +22 -16
  100. data/spec/lib/danica_spec.rb +6 -5
  101. data/spec/spec_helper.rb +3 -2
  102. data/spec/support/models/expression/baskara.rb +3 -3
  103. data/spec/support/models/expression/parabole.rb +2 -0
  104. data/spec/support/models/expression/quadratic_sum.rb +3 -1
  105. data/spec/support/models/expression/spatial.rb +2 -1
  106. data/spec/support/models/function/my_function.rb +3 -1
  107. data/spec/support/models/function/parabole.rb +1 -1
  108. data/spec/support/models/function/quadratic_sum.rb +2 -0
  109. data/spec/support/models/function/spatial.rb +2 -0
  110. data/spec/support/models/operator/inverse.rb +3 -1
  111. data/spec/support/models/operator/my_operator.rb +3 -1
  112. data/spec/support/models/variables_holder/dummy.rb +3 -1
  113. data/spec/support/shared_contexts/common.rb +4 -2
  114. data/spec/support/shared_examples/base_operations.rb +7 -4
  115. data/spec/support/shared_examples/common.rb +3 -1
  116. data/spec/support/shared_examples/operator/chained.rb +12 -6
  117. data/spec/support/shared_examples/operator/dual_term.rb +9 -8
  118. data/spec/support/shared_examples/operator/single_input.rb +7 -2
  119. data/spec/support/shared_examples/variable.rb +8 -4
  120. metadata +115 -30
  121. data/spec/integration/addition_spec.rb +0 -28
  122. data/spec/integration/multiplication_spec.rb +0 -44
  123. data/spec/integration/negative_spec.rb +0 -25
data/lib/danica.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'darthjee/core_ext'
2
4
 
3
5
  module Danica
@@ -20,10 +22,10 @@ module Danica
20
22
 
21
23
  class << self
22
24
  delegate :build, to: :builder
25
+ attr_accessor :debug
23
26
 
24
27
  def builder
25
28
  @builder ||= Builder.new
26
29
  end
27
30
  end
28
31
  end
29
-
@@ -1,29 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
4
  module BaseOperations
3
5
  def +(other)
4
- return other + self if other.is_a?(Operator::Addition)
5
- addition(self, other)
6
+ formatted_operation other, addition(self, other)
6
7
  end
7
8
 
8
9
  def *(other)
9
- return other * self if other.is_a?(Operator::Multiplication)
10
- multiplication(self, other)
10
+ formatted_operation other, multiplication(self, other)
11
11
  end
12
12
 
13
13
  def /(other)
14
- division(self, other)
14
+ formatted_operation other, division(self, other)
15
15
  end
16
16
 
17
17
  def -(other)
18
- self + negative(other)
18
+ formatted_operation other, (self + negative(other))
19
19
  end
20
20
 
21
21
  def **(other)
22
- power(self, other)
22
+ formatted_operation other, power(self, other)
23
23
  end
24
24
 
25
25
  def -@
26
26
  negative(self)
27
27
  end
28
+
29
+ private
30
+
31
+ def formatted_operation(other, value)
32
+ return other.repack(value) if other.is_a?(Danica::Formatted)
33
+
34
+ value
35
+ end
28
36
  end
29
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
4
  class Builder
3
5
  include DSL
data/lib/danica/common.rb CHANGED
@@ -1,26 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
- module Common extend ::ActiveSupport::Concern
4
+ module Common
5
+ extend ::ActiveSupport::Concern
3
6
  included do
4
7
  include Wrapper
5
8
  include DSL
6
9
 
7
- class << self
8
- def default_value(name, value)
9
- define_method(name) { |*_| value }
10
- end
11
-
12
- def default_values(*names, value)
13
- names.each do |name|
14
- default_value(name, value)
15
- end
16
- end
17
- end
18
-
19
10
  default_values :constant?, :signaled?, :container?, :variable?,
20
11
  :variable_holder?, false
21
12
  default_value :priority, 1
22
13
  end
23
14
 
15
+ class_methods do
16
+ def default_value(name, value)
17
+ define_method(name) { |*_| value }
18
+ end
19
+
20
+ def default_values(*names, value)
21
+ names.each do |name|
22
+ default_value(name, value)
23
+ end
24
+ end
25
+ end
26
+
24
27
  def to_f
25
28
  raise Exception::NotImplemented
26
29
  end
@@ -42,16 +45,20 @@ module Danica
42
45
  when :f
43
46
  to_f
44
47
  else
45
- raise Exception::FormattedNotFound.new
48
+ raise Exception::FormattedNotFound
46
49
  end
47
50
  end
48
51
 
49
52
  def tex(**options)
50
- Formatted.new(self, :tex, options)
53
+ formatted(format: :tex, **options)
51
54
  end
52
55
 
53
56
  def gnu(**options)
54
- Formatted.new(self, :gnu, options)
57
+ formatted(format: :gnu, **options)
58
+ end
59
+
60
+ def formatted(*args)
61
+ Formatted.new(self, *args)
55
62
  end
56
63
 
57
64
  def valued?
@@ -68,6 +75,7 @@ module Danica
68
75
 
69
76
  def wrap_as_group(value)
70
77
  return value if is_grouped? || value.priority >= priority
78
+
71
79
  group(value)
72
80
  end
73
81
  end
data/lib/danica/dsl.rb CHANGED
@@ -1,18 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
4
  module DSL
5
+ autoload :Builder, 'danica/dsl/builder'
6
+
3
7
  class << self
4
- def register_operator(method, clazz=nil)
8
+ def register_operator(method, clazz = nil)
5
9
  register(method, clazz, 'Danica::Operator')
6
10
  end
7
11
 
8
- def register_wrapper(method, clazz=nil)
12
+ def register_wrapper(method, clazz = nil)
9
13
  register(method, clazz, 'Danica::Wrapper')
10
14
  end
11
15
 
12
- def register(method, clazz=nil, base=nil)
13
- define_method method do |*args|
14
- clazz = [base.to_s, method.to_s.camelize].compact.join('::').constantize unless clazz
15
- clazz = [base, clazz.to_s].compact.join('::').constantize unless clazz.is_a? Class
16
+ def register(method, clazz = nil, base = nil)
17
+ Builder.new(method, clazz, base).build
18
+ end
19
+
20
+ def register_class(method, clazz)
21
+ define_method(method) do |*args|
16
22
  clazz.new(*args)
17
23
  end
18
24
  end
@@ -35,14 +41,14 @@ module Danica
35
41
  end
36
42
  end
37
43
 
38
- %i(
44
+ %i[
39
45
  addition multiplication division sin cos power
40
46
  squared_root exponential
41
- ).each do |method|
47
+ ].each do |method|
42
48
  DSL.register_operator(method)
43
49
  end
44
50
 
45
- %i(number group negative plus_minus variable constant).each do |method|
51
+ %i[number group negative plus_minus variable constant].each do |method|
46
52
  DSL.register_wrapper(method)
47
53
  end
48
54
 
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Danica
4
+ module DSL
5
+ class Builder
6
+ attr_reader :method, :claz, :base
7
+
8
+ def initialize(method, claz = nil, base = nil)
9
+ @method = method
10
+ @claz = claz
11
+ @base = base
12
+ end
13
+
14
+ def build
15
+ DSL.register_class(method, clazz)
16
+ end
17
+
18
+ private
19
+
20
+ def clazz
21
+ @clazz ||= build_clazz
22
+ end
23
+
24
+ def build_clazz
25
+ return clazz_from_method unless claz
26
+ return claz if claz.is_a? Class
27
+
28
+ clazz_from_string
29
+ end
30
+
31
+ def clazz_from_method
32
+ [base.to_s, method.to_s.camelize].compact.join('::').constantize
33
+ end
34
+
35
+ def clazz_from_string
36
+ [base, claz.to_s].compact.join('::').constantize
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
4
  class Equation
3
5
  include VariablesHolder
4
-
6
+
5
7
  autoload :Builder, 'danica/equation/builder'
6
8
 
7
9
  class << self
@@ -19,5 +21,3 @@ module Danica
19
21
  end
20
22
  end
21
23
  end
22
-
23
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
4
  class Equation::Builder
3
5
  attr_reader :variables
@@ -1,6 +1,18 @@
1
- class Danica::Exception < ::Exception
1
+ # frozen_string_literal: true
2
+
3
+ class Danica::Exception < RuntimeError
2
4
  class NotDefined < self; end
3
5
  class FormattedNotFound < self; end
4
6
  class NotImplemented < self; end
5
- end
7
+ class InvalidInput < self
8
+ attr_reader :value
9
+ def initialize(value)
10
+ @value = value
11
+ super
12
+ end
6
13
 
14
+ def message
15
+ "invalid input class #{value.class}"
16
+ end
17
+ end
18
+ end
@@ -1,27 +1,31 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
- module Expressable extend ::ActiveSupport::Concern
4
+ module Expressable
5
+ extend ::ActiveSupport::Concern
3
6
  include VariablesHolder
4
7
 
5
- included do
6
- class << self
7
- def built_with(block_name)
8
- self.send(:delegate, :to, :to_f, to: block_name)
8
+ class_methods do
9
+ def built_with(block_name)
10
+ delegate :to, :to_f, to: block_name
9
11
 
10
- self.send(:define_singleton_method, :build) do |*vars, &block|
11
- Class.new(self) do
12
- variables(*vars)
12
+ define_singleton_method(:build) do |*vars, &block|
13
+ Class.new(self) do
14
+ variables(*vars)
13
15
 
14
- private
16
+ private
15
17
 
16
- module_eval("define_method :#{block_name} do
17
- @#{block_name} ||= instance_eval(&block) if block
18
- end")
18
+ module_eval do
19
+ define_method block_name do
20
+ instance_variable_get("@#{block_name}") ||
21
+ block && instance_variable_set("@#{block_name}", instance_eval(&block))
22
+ end
19
23
  end
20
24
  end
25
+ end
21
26
 
22
- self.send(:define_singleton_method, :create) do |*vars, &block|
23
- build(*vars, &block).new
24
- end
27
+ define_singleton_method(:create) do |*vars, &block|
28
+ build(*vars, &block).new
25
29
  end
26
30
  end
27
31
  end
@@ -32,7 +36,7 @@ module Danica
32
36
  attributes = { variables: args.flatten }.merge(options)
33
37
 
34
38
  attributes.each do |key, value|
35
- self.public_send("#{key}=", value)
39
+ public_send("#{key}=", value)
36
40
  end
37
41
  end
38
42
  end
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
4
  class Expression
5
+ autoload :Gauss, 'danica/expression/gauss'
6
+
3
7
  include Common
4
8
  include DSL
5
9
  include BaseOperations
6
10
  include Expressable
7
11
 
8
- autoload :Gauss, 'danica/expression/gauss'
9
-
10
12
  delegate :is_grouped?, :priority, to: :expression_block
11
13
 
12
14
  built_with(:expression_block)
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danica
2
4
  class Expression::Gauss < Expression.build(:x, average: { latex: '\mu', gnuplot: :u }, variance_root: { latex: '\sigma', gnuplot: :v }) { num(1) / denominator * exponential(exp) }
3
-
4
5
  private
5
6
 
6
7
  def denominator
@@ -9,14 +10,13 @@ module Danica
9
10
 
10
11
  def exp
11
12
  - (
12
- ((x - average) ** 2) /
13
+ ((x - average)**2) /
13
14
  (num(2) * variance)
14
- )
15
+ )
15
16
  end
16
17
 
17
18
  def variance
18
- @variance ||= variance_root ** 2
19
+ @variance ||= variance_root**2
19
20
  end
20
21
  end
21
22
  end
22
-
@@ -1,20 +1,45 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Danica::Formatted
2
- attr_reader :content, :format, :decimals
4
+ attr_reader :content, :options
3
5
 
4
- def initialize(content, format, decimals: nil)
6
+ def initialize(content, **options)
5
7
  @content = content
6
- @format = format
7
- @decimals = decimals
8
+ @options = options
8
9
  end
9
10
 
10
11
  def to_s
11
- content.to(format, decimals: decimals)
12
+ content.to(format, options)
12
13
  end
13
14
 
14
15
  def ==(other)
15
16
  return false unless other.class == self.class
16
- return other.content == content &&
17
- other.format == format
17
+
18
+ other.content == content &&
19
+ other.format == format
20
+ end
21
+
22
+ def format
23
+ options[:format]
24
+ end
25
+
26
+ def repack(object)
27
+ self.class.new(
28
+ object,
29
+ options
30
+ )
31
+ end
32
+
33
+ def to_tex(**opts)
34
+ to(:tex, **opts)
35
+ end
36
+
37
+ def to_gnu(**opts)
38
+ to(:gnu, **opts)
39
+ end
40
+
41
+ def to(format, **opts)
42
+ content.to(format, options.merge(opts))
18
43
  end
19
44
 
20
45
  private
@@ -22,9 +47,7 @@ class Danica::Formatted
22
47
  def method_missing(method, *args)
23
48
  value = content.public_send(method, *args)
24
49
  return value unless value.is_a?(Danica::Common)
25
- self.class.new(
26
- value,
27
- format
28
- )
50
+
51
+ repack(value)
29
52
  end
30
53
  end