rpn_party 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d32325fb22bab5f4a740c85edf8209a0356975ff
4
+ data.tar.gz: 9995eb11a6c13ed816b470b80aa9e096351c7550
5
+ SHA512:
6
+ metadata.gz: 1e73c6c03d61a4b606cfc3411cbe920e9759ca9ec0b599a53499c6fd5d9248817891c3e7392de2ae78ba74790609bbd9b51316340bc8154a8ad82db4cb6cc63c
7
+ data.tar.gz: 2d8465d85f678ffa20e7446880ce1a3c606a7f040418765650dd9e80f3026082beeaf50f92ac38aef5bb9b389a39889c0948e7b6bde49b6c4ffc6092b1666e02
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Adds this gem's lib path the the Ruby load path. This allows
4
+ # us to test RPNParty::CLI without the gem being installed.
5
+ # Borrowed from https://stackoverflow.com/a/5294358/918507
6
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
7
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
8
+
9
+ require 'rpn_party/cli'
10
+
11
+ RPNParty::CLI.new
@@ -0,0 +1,90 @@
1
+ require 'rpn_party/errors'
2
+
3
+ module RPNParty
4
+ class Calculator
5
+ def initialize(calculation = '')
6
+ @stack = []
7
+ evaluate(calculation)
8
+ end
9
+
10
+ def result
11
+ if @stack.empty?
12
+ nil
13
+ elsif @stack.length == 1
14
+ @stack[0]
15
+ else
16
+ @stack
17
+ end
18
+ end
19
+
20
+ def evaluate(calculation)
21
+ calculation.split.map do |token|
22
+ case token
23
+ when /\A(?:\-)?\d+(?:\.\d+)?\z/
24
+ @stack.push token.to_f
25
+ when /\A\+\z/
26
+ add
27
+ when /\A\-\z/
28
+ subtract
29
+ when /\A\*\z/
30
+ multiply
31
+ when /\A\/\z/
32
+ divide
33
+ else
34
+ raise UnrecognizedInputError,
35
+ "Unrecognized value/operator: '#{token}'. Valid inputs are numbers (0, 1, 2.5, -3, etc.), or '+', '-', '*', '/'."
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def add
43
+ raise_if_insufficient_operands :addition
44
+
45
+ first_value, second_value = @stack.pop(2)
46
+ @stack.push(first_value + second_value)
47
+ end
48
+
49
+ def subtract
50
+ raise_if_insufficient_operands :subtraction
51
+
52
+ first_value, second_value = @stack.pop(2)
53
+ @stack.push(first_value - second_value)
54
+ end
55
+
56
+ def multiply
57
+ raise_if_insufficient_operands :multiplication
58
+
59
+ first_value, second_value = @stack.pop(2)
60
+ @stack.push(first_value * second_value)
61
+ end
62
+
63
+ def divide
64
+ raise_if_insufficient_operands :division
65
+ raise_if_second_value_is_zero
66
+
67
+ first_value, second_value = @stack.pop(2)
68
+ @stack.push(first_value / second_value)
69
+ end
70
+
71
+ def raise_if_second_value_is_zero
72
+ return unless @stack.last.zero?
73
+
74
+ raise ZeroDivisionError,
75
+ "Cannot divide #{@stack[-2]} by 0."
76
+ end
77
+
78
+ def raise_if_insufficient_operands(operation)
79
+ return if @stack.length >= 2
80
+
81
+ message = if @stack.empty?
82
+ "Could not perform #{operation}. At least two values are required, but there are none."
83
+ else
84
+ "Could not perform #{operation}. At least two values are required, but there is only one: '#{@stack.first}'."
85
+ end
86
+ raise InsufficientOperandsError,
87
+ message
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,40 @@
1
+ require 'rpn_party/calculator'
2
+
3
+ module RPNParty
4
+ class CLI
5
+ def initialize
6
+ @calc = RPNParty::Calculator.new
7
+
8
+ puts 'Welcome to RPNParty!'
9
+ print '> '
10
+
11
+ loop do
12
+ input = gets
13
+
14
+ if input.nil? || input.chomp == 'q'
15
+ puts 'Goodbye!'
16
+ exit
17
+ end
18
+
19
+ begin
20
+ @calc.evaluate(input.chomp)
21
+ rescue RPNParty::UnrecognizedInputError => error
22
+ puts error.message
23
+ rescue ZeroDivisionError => error
24
+ puts error.message
25
+ rescue RPNParty::InsufficientOperandsError => error
26
+ puts error.message
27
+ end
28
+
29
+ if @calc.result.nil?
30
+ puts 'nil'
31
+ elsif @calc.result.is_a? Array
32
+ puts @calc.result.join(', ')
33
+ else
34
+ puts @calc.result
35
+ end
36
+ print '> '
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ module RPNParty
2
+ class UnrecognizedInputError < StandardError
3
+ end
4
+
5
+ class InsufficientOperandsError < StandardError
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rpn_party
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Richard Jones
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: An interactive Reverse Polish Notation calculator for the command line
14
+ email: rico@toasterlovin.com
15
+ executables:
16
+ - rpn_party
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/rpn_party
21
+ - lib/rpn_party/calculator.rb
22
+ - lib/rpn_party/cli.rb
23
+ - lib/rpn_party/errors.rb
24
+ homepage: https://github.com/toasterlovin/rpn_party
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.6.12
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: RPN Party
48
+ test_files: []