doctor_ai 1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/README.md +0 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/doctor_ai +5 -0
- data/bin/setup +8 -0
- data/doctor_ai.gemspec +36 -0
- data/lib/doctor_ai.rb +45 -0
- data/lib/doctor_ai/client.rb +25 -0
- data/lib/doctor_ai/commands/age.rb +30 -0
- data/lib/doctor_ai/commands/base.rb +20 -0
- data/lib/doctor_ai/commands/blood_pressure.rb +30 -0
- data/lib/doctor_ai/commands/exit.rb +19 -0
- data/lib/doctor_ai/commands/height.rb +33 -0
- data/lib/doctor_ai/commands/request_diagnosis.rb +58 -0
- data/lib/doctor_ai/commands/verify.rb +17 -0
- data/lib/doctor_ai/diagnoses/eat_more_vegetables.rb +9 -0
- data/lib/doctor_ai/diagnoses/hypertension.rb +9 -0
- data/lib/doctor_ai/diagnoses/unknown.rb +9 -0
- data/lib/doctor_ai/macros/commands.rb +24 -0
- data/lib/doctor_ai/macros/validations.rb +22 -0
- data/lib/doctor_ai/models/patient.rb +26 -0
- data/lib/doctor_ai/parser.rb +20 -0
- data/lib/doctor_ai/responses/base.rb +31 -0
- data/lib/doctor_ai/responses/command_not_found.rb +26 -0
- data/lib/doctor_ai/responses/custom.rb +17 -0
- data/lib/doctor_ai/responses/invalid_usage.rb +20 -0
- data/lib/doctor_ai/responses/value_changed.rb +17 -0
- data/lib/doctor_ai/responses/verifier_not_found.rb +26 -0
- data/lib/doctor_ai/responses/welcome.rb +10 -0
- data/lib/doctor_ai/verifiers/age.rb +21 -0
- data/lib/doctor_ai/verifiers/base.rb +13 -0
- data/lib/doctor_ai/verifiers/blood_pressure.rb +31 -0
- data/lib/doctor_ai/verifiers/height.rb +21 -0
- metadata +224 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e5754da0cb1ce5d4b2be8f2464ed7988f70e4d9c
|
4
|
+
data.tar.gz: 24160bb1ab990008b5492edbf2a727646a257159
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a0711b7aea4f744ac2e44d2bd52e8b482d9e3172a6df03437cbbd71777196c0f7b0178900efc92d40e6c08eba03a4da0b1c7ffec05cd999d7c921a9163038019
|
7
|
+
data.tar.gz: 3fa833270c38fc3d2027f6e3c210223d0cb4ebcd673925cb80d41875e856d100fe1e6b5de7f4c92d756771c90ac55f1f34e39d1e37a23fe1093f68ccceba5f6f
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README.md
ADDED
File without changes
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "doctor_ai"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/doctor_ai
ADDED
data/bin/setup
ADDED
data/doctor_ai.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "doctor_ai"
|
7
|
+
spec.version = '1.0'
|
8
|
+
spec.authors = ["Oskar Lakner"]
|
9
|
+
spec.email = ["oskar.lakner@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Simple doctor bot"
|
12
|
+
spec.description = ""
|
13
|
+
spec.homepage = "https://github.com/haerde/doctor-ai"
|
14
|
+
|
15
|
+
if spec.respond_to?(:metadata)
|
16
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
17
|
+
end
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
20
|
+
f.match(%r{^(test|spec|features)/})
|
21
|
+
end
|
22
|
+
spec.bindir = "bin"
|
23
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_dependency 'attr_extras'
|
27
|
+
spec.add_dependency 'dry-validation'
|
28
|
+
spec.add_dependency 'colorize'
|
29
|
+
spec.add_dependency 'decisiontree'
|
30
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
31
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
33
|
+
spec.add_development_dependency 'guard'
|
34
|
+
spec.add_development_dependency 'guard-rspec'
|
35
|
+
spec.add_development_dependency 'pry'
|
36
|
+
end
|
data/lib/doctor_ai.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'attr_extras'
|
3
|
+
require 'dry-validation'
|
4
|
+
require 'decisiontree'
|
5
|
+
require 'colorize'
|
6
|
+
|
7
|
+
require 'doctor_ai/macros/validations'
|
8
|
+
require 'doctor_ai/macros/commands'
|
9
|
+
|
10
|
+
require 'doctor_ai/verifiers/base'
|
11
|
+
require 'doctor_ai/verifiers/age'
|
12
|
+
require 'doctor_ai/verifiers/height'
|
13
|
+
require 'doctor_ai/verifiers/blood_pressure'
|
14
|
+
|
15
|
+
require 'doctor_ai/models/patient'
|
16
|
+
|
17
|
+
require 'doctor_ai/responses/base'
|
18
|
+
require 'doctor_ai/responses/welcome'
|
19
|
+
require 'doctor_ai/responses/command_not_found'
|
20
|
+
require 'doctor_ai/responses/verifier_not_found'
|
21
|
+
require 'doctor_ai/responses/invalid_usage'
|
22
|
+
require 'doctor_ai/responses/value_changed'
|
23
|
+
require 'doctor_ai/responses/custom'
|
24
|
+
|
25
|
+
require 'doctor_ai/commands/base'
|
26
|
+
require 'doctor_ai/commands/age'
|
27
|
+
require 'doctor_ai/commands/height'
|
28
|
+
require 'doctor_ai/commands/blood_pressure'
|
29
|
+
require 'doctor_ai/commands/verify'
|
30
|
+
require 'doctor_ai/commands/request_diagnosis'
|
31
|
+
require 'doctor_ai/commands/exit'
|
32
|
+
|
33
|
+
require 'doctor_ai/diagnoses/unknown'
|
34
|
+
require 'doctor_ai/diagnoses/hypertension'
|
35
|
+
require 'doctor_ai/diagnoses/eat_more_vegetables'
|
36
|
+
|
37
|
+
require 'doctor_ai/client'
|
38
|
+
require 'doctor_ai/parser'
|
39
|
+
|
40
|
+
begin
|
41
|
+
require 'pry'
|
42
|
+
rescue LoadError; end
|
43
|
+
|
44
|
+
module DoctorAI
|
45
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
class Client
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@running_flag = true
|
7
|
+
end
|
8
|
+
|
9
|
+
def start
|
10
|
+
DoctorAI::Responses::Welcome.new.call
|
11
|
+
while running?
|
12
|
+
input = gets.chomp
|
13
|
+
DoctorAI::Parser.new(input).call
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def running?
|
18
|
+
@running_flag
|
19
|
+
end
|
20
|
+
|
21
|
+
def stop!
|
22
|
+
@running_flag = false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Commands
|
3
|
+
class Age < Base
|
4
|
+
attr_reader_initialize :input do
|
5
|
+
@age = get_value_from_input(@input).to_i
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.example_usage
|
9
|
+
"Age <years>. Example: Age 24"
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
if valid?
|
14
|
+
patient.age = @age
|
15
|
+
DoctorAI::Responses::ValueChanged.new('Age', @age).call
|
16
|
+
else
|
17
|
+
render_errors
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def schema
|
24
|
+
Dry::Validation.Schema do
|
25
|
+
required(:age).filled(gt?: 0, lteq?: 100)
|
26
|
+
end.call(age: @age)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Commands
|
3
|
+
class Base
|
4
|
+
include DoctorAI::Macros::Validations
|
5
|
+
include DoctorAI::Macros::Commands
|
6
|
+
|
7
|
+
attr_reader_initialize :input
|
8
|
+
|
9
|
+
attr_reader :patient
|
10
|
+
|
11
|
+
def self.usage
|
12
|
+
DoctorAI::Responses::InvalidUsage.new(self.example_usage).call
|
13
|
+
end
|
14
|
+
|
15
|
+
def patient
|
16
|
+
@_patient = DoctorAI::Models::Patient.instance
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Commands
|
3
|
+
class BloodPressure < Base
|
4
|
+
attr_reader_initialize :input do
|
5
|
+
@value = get_value_from_input(@input)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.example_usage
|
9
|
+
'Blood Pressure <value>. Example: Blood Pressure 160/60'
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
if valid?
|
14
|
+
patient.blood_pressure = @value
|
15
|
+
DoctorAI::Responses::ValueChanged.new('Blood Pressure', @value).call
|
16
|
+
else
|
17
|
+
render_errors
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def schema
|
24
|
+
Dry::Validation.Schema do
|
25
|
+
required(:value).filled(format?: /^\d{2,3}\/\d{2,3}/)
|
26
|
+
end.call(value: @value)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Commands
|
3
|
+
class Exit < Base
|
4
|
+
|
5
|
+
def self.example_usage; end
|
6
|
+
|
7
|
+
def call
|
8
|
+
exit_message
|
9
|
+
DoctorAI::Client.instance.stop!
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def exit_message
|
15
|
+
DoctorAI::Responses::Custom.new('Thank you.').call
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Commands
|
3
|
+
class Height < Base
|
4
|
+
attr_reader_initialize :input do
|
5
|
+
@value, @unit = get_value_from_input(@input).split
|
6
|
+
@value = @value.to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.example_usage
|
10
|
+
"Height <value> <units>. Example: Height 190 cm"
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
if valid?
|
15
|
+
patient.height = @value
|
16
|
+
patient.height_units = @unit
|
17
|
+
DoctorAI::Responses::ValueChanged.new('Height', @value, @unit).call
|
18
|
+
else
|
19
|
+
render_errors
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def schema
|
26
|
+
Dry::Validation.Schema do
|
27
|
+
required(:value).filled(gt?: 0, lteq?: 250)
|
28
|
+
required(:unit).filled(included_in?: %w(cm))
|
29
|
+
end.call(value: @value, unit: @unit)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Commands
|
3
|
+
class RequestDiagnosis < Base
|
4
|
+
|
5
|
+
def call
|
6
|
+
if valid?
|
7
|
+
decision_tree.train
|
8
|
+
patient_data = [patient.age, patient.height, patient.blood_pressure]
|
9
|
+
diagnose = decision_tree.predict(patient_data) || unknown_diagnose.call
|
10
|
+
|
11
|
+
DoctorAI::Responses::Custom.new(diagnose).call
|
12
|
+
else
|
13
|
+
render_errors
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def decision_tree
|
20
|
+
@_decision_tree ||= DecisionTree::ID3Tree.new(labels, training_data, unknown_diagnose.call, :discrete)
|
21
|
+
end
|
22
|
+
|
23
|
+
def labels
|
24
|
+
['Age', 'Height', 'Blood pressure']
|
25
|
+
end
|
26
|
+
|
27
|
+
def training_data
|
28
|
+
[
|
29
|
+
[20, 190, '140/80', eat_more_vegetables.call],
|
30
|
+
[30, 170, '140/80', eat_more_vegetables.call],
|
31
|
+
[38, 170, '150/80', hypertension.call],
|
32
|
+
[40, 180, '150/80', unknown_diagnose.call],
|
33
|
+
[50, 160, '140/80', hypertension.call],
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
def unknown_diagnose
|
38
|
+
DoctorAI::Diagnoses::Unknown.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def eat_more_vegetables
|
42
|
+
DoctorAI::Diagnoses::EatMoreVegetables.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def hypertension
|
46
|
+
DoctorAI::Diagnoses::Hypertension.new
|
47
|
+
end
|
48
|
+
|
49
|
+
def schema
|
50
|
+
Dry::Validation.Schema do
|
51
|
+
required(:age).value(:filled?)
|
52
|
+
required(:height).value(:filled?)
|
53
|
+
required(:blood_pressure).value(:filled?)
|
54
|
+
end.call(blood_pressure: patient.blood_pressure, height: patient.height, age: patient.age)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Commands
|
3
|
+
class Verify < Base
|
4
|
+
attr_reader_initialize :input do
|
5
|
+
@metric = get_value_from_input(@input)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.example_usage
|
9
|
+
"Verify <metric>. Example: Verify Blood Pressure"
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
patient.verify(@metric)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Macros
|
3
|
+
module Commands
|
4
|
+
AVAILABLE_COMMANDS = ['blood pressure', 'age', 'height', 'verify', 'request diagnosis', 'exit'].freeze
|
5
|
+
|
6
|
+
def find_command(input)
|
7
|
+
AVAILABLE_COMMANDS.find { |command| input.downcase.start_with?(command) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def command_klass(name)
|
11
|
+
name = name.split.map(&:capitalize).join
|
12
|
+
DoctorAI::Commands.const_get(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_value_from_input(input)
|
16
|
+
input.downcase.gsub(find_command(input), '').strip
|
17
|
+
end
|
18
|
+
|
19
|
+
def command_not_found
|
20
|
+
DoctorAI::Responses::CommandNotFound
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Macros
|
3
|
+
module Validations
|
4
|
+
|
5
|
+
def schema
|
6
|
+
raise NotImplementedError
|
7
|
+
end
|
8
|
+
|
9
|
+
def valid?
|
10
|
+
schema.success?
|
11
|
+
end
|
12
|
+
|
13
|
+
def formated_errors
|
14
|
+
schema.errors(full: true).values.flatten.map(&:capitalize).join("\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_errors
|
18
|
+
DoctorAI::Responses::Custom.new(formated_errors).call
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Models
|
3
|
+
class Patient
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
attr_accessor :age, :height, :height_units, :blood_pressure
|
7
|
+
|
8
|
+
AVAILABLE_VERIFIERS = {
|
9
|
+
'age' => DoctorAI::Verifiers::Age,
|
10
|
+
'height' => DoctorAI::Verifiers::Height,
|
11
|
+
'blood pressure' => DoctorAI::Verifiers::BloodPressure
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def verify(metric_name)
|
15
|
+
fetch_verifier_class(metric_name).new.call
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def fetch_verifier_class(name)
|
21
|
+
key = name.downcase
|
22
|
+
AVAILABLE_VERIFIERS.fetch(key, DoctorAI::Responses::VerifierNotFound)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
class Parser
|
3
|
+
include DoctorAI::Macros::Commands
|
4
|
+
|
5
|
+
attr_reader_initialize :user_input
|
6
|
+
|
7
|
+
def call
|
8
|
+
commands.each(&:call)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def commands
|
14
|
+
user_input.split(',').map(&:strip).map do |input|
|
15
|
+
command = find_command(input)
|
16
|
+
command.nil? ? command_not_found.new : command_klass(command).new(input)
|
17
|
+
end.compact
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Responses
|
3
|
+
class Base
|
4
|
+
|
5
|
+
def call
|
6
|
+
puts response
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def response
|
12
|
+
[
|
13
|
+
prefix,
|
14
|
+
message.colorize(output_color)
|
15
|
+
].compact.join(' ')
|
16
|
+
end
|
17
|
+
|
18
|
+
def message
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
def prefix
|
23
|
+
"Doctor: ".light_blue
|
24
|
+
end
|
25
|
+
|
26
|
+
def output_color
|
27
|
+
:green
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Responses
|
3
|
+
class CommandNotFound < Base
|
4
|
+
|
5
|
+
def message
|
6
|
+
"Available commands: #{available_commands}"
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def available_commands
|
12
|
+
DoctorAI::Parser::AVAILABLE_COMMANDS.map do |command|
|
13
|
+
command.split.map(&:capitalize).join(' ')
|
14
|
+
end.join(', ')
|
15
|
+
end
|
16
|
+
|
17
|
+
def prefix
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def output_color
|
22
|
+
:yellow
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Responses
|
3
|
+
class ValueChanged < Base
|
4
|
+
|
5
|
+
attr_reader :metric, :values
|
6
|
+
|
7
|
+
def initialize(metric, *values)
|
8
|
+
@metric = metric
|
9
|
+
@values = values.join(' ')
|
10
|
+
end
|
11
|
+
|
12
|
+
def message
|
13
|
+
"Your #{metric} has been set to #{values}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Responses
|
3
|
+
class VerifierNotFound < Base
|
4
|
+
|
5
|
+
def message
|
6
|
+
"Verifier has not been found. Available commands: #{available_verifiers}"
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def available_verifiers
|
12
|
+
DoctorAI::Models::Patient::AVAILABLE_VERIFIERS.keys.map do |verifier|
|
13
|
+
verifier.split.map(&:capitalize).join(' ')
|
14
|
+
end.join(', ')
|
15
|
+
end
|
16
|
+
|
17
|
+
def prefix
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def output_color
|
22
|
+
:yellow
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Verifiers
|
3
|
+
class Age < Base
|
4
|
+
def call
|
5
|
+
if valid?
|
6
|
+
DoctorAI::Responses::Custom.new("Your Age: #{patient.age}").call
|
7
|
+
else
|
8
|
+
render_errors
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def schema
|
15
|
+
Dry::Validation.Schema do
|
16
|
+
required(:age).value(:filled?)
|
17
|
+
end.call(age: patient.age)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Verifiers
|
3
|
+
class BloodPressure < Base
|
4
|
+
def call
|
5
|
+
if valid?
|
6
|
+
sys, dia = patient.blood_pressure.split(/\D/).map(&:to_i)
|
7
|
+
|
8
|
+
message = if sys > 129 && dia > 84
|
9
|
+
'Your Blood pressure is too high. It should be in 120-129/80-84'
|
10
|
+
elsif sys < 120 && dia < 80
|
11
|
+
'Your Blood pressure is too low. It should be in 120-129/80-84'
|
12
|
+
else
|
13
|
+
'Sorry, I cannot verify your Blood pressure'
|
14
|
+
end
|
15
|
+
|
16
|
+
DoctorAI::Responses::Custom.new(message).call
|
17
|
+
else
|
18
|
+
render_errors
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def schema
|
25
|
+
Dry::Validation.Schema do
|
26
|
+
required(:blood_pressure).value(:filled?)
|
27
|
+
end.call(blood_pressure: patient.blood_pressure)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DoctorAI
|
2
|
+
module Verifiers
|
3
|
+
class Height < Base
|
4
|
+
def call
|
5
|
+
if valid?
|
6
|
+
DoctorAI::Responses::Custom.new("Your Height: #{patient.height} #{patient.height_units}").call
|
7
|
+
else
|
8
|
+
render_errors
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def schema
|
15
|
+
Dry::Validation.Schema do
|
16
|
+
required(:height).value(:filled?)
|
17
|
+
end.call(height: patient.height)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: doctor_ai
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Oskar Lakner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: attr_extras
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-validation
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: colorize
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: decisiontree
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.13'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.13'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: guard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: guard-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: ''
|
154
|
+
email:
|
155
|
+
- oskar.lakner@gmail.com
|
156
|
+
executables:
|
157
|
+
- console
|
158
|
+
- doctor_ai
|
159
|
+
- setup
|
160
|
+
extensions: []
|
161
|
+
extra_rdoc_files: []
|
162
|
+
files:
|
163
|
+
- ".gitignore"
|
164
|
+
- ".rspec"
|
165
|
+
- Gemfile
|
166
|
+
- Guardfile
|
167
|
+
- README.md
|
168
|
+
- Rakefile
|
169
|
+
- bin/console
|
170
|
+
- bin/doctor_ai
|
171
|
+
- bin/setup
|
172
|
+
- doctor_ai.gemspec
|
173
|
+
- lib/doctor_ai.rb
|
174
|
+
- lib/doctor_ai/client.rb
|
175
|
+
- lib/doctor_ai/commands/age.rb
|
176
|
+
- lib/doctor_ai/commands/base.rb
|
177
|
+
- lib/doctor_ai/commands/blood_pressure.rb
|
178
|
+
- lib/doctor_ai/commands/exit.rb
|
179
|
+
- lib/doctor_ai/commands/height.rb
|
180
|
+
- lib/doctor_ai/commands/request_diagnosis.rb
|
181
|
+
- lib/doctor_ai/commands/verify.rb
|
182
|
+
- lib/doctor_ai/diagnoses/eat_more_vegetables.rb
|
183
|
+
- lib/doctor_ai/diagnoses/hypertension.rb
|
184
|
+
- lib/doctor_ai/diagnoses/unknown.rb
|
185
|
+
- lib/doctor_ai/macros/commands.rb
|
186
|
+
- lib/doctor_ai/macros/validations.rb
|
187
|
+
- lib/doctor_ai/models/patient.rb
|
188
|
+
- lib/doctor_ai/parser.rb
|
189
|
+
- lib/doctor_ai/responses/base.rb
|
190
|
+
- lib/doctor_ai/responses/command_not_found.rb
|
191
|
+
- lib/doctor_ai/responses/custom.rb
|
192
|
+
- lib/doctor_ai/responses/invalid_usage.rb
|
193
|
+
- lib/doctor_ai/responses/value_changed.rb
|
194
|
+
- lib/doctor_ai/responses/verifier_not_found.rb
|
195
|
+
- lib/doctor_ai/responses/welcome.rb
|
196
|
+
- lib/doctor_ai/verifiers/age.rb
|
197
|
+
- lib/doctor_ai/verifiers/base.rb
|
198
|
+
- lib/doctor_ai/verifiers/blood_pressure.rb
|
199
|
+
- lib/doctor_ai/verifiers/height.rb
|
200
|
+
homepage: https://github.com/haerde/doctor-ai
|
201
|
+
licenses: []
|
202
|
+
metadata:
|
203
|
+
allowed_push_host: https://rubygems.org
|
204
|
+
post_install_message:
|
205
|
+
rdoc_options: []
|
206
|
+
require_paths:
|
207
|
+
- lib
|
208
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
209
|
+
requirements:
|
210
|
+
- - ">="
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
version: '0'
|
213
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
214
|
+
requirements:
|
215
|
+
- - ">="
|
216
|
+
- !ruby/object:Gem::Version
|
217
|
+
version: '0'
|
218
|
+
requirements: []
|
219
|
+
rubyforge_project:
|
220
|
+
rubygems_version: 2.6.11
|
221
|
+
signing_key:
|
222
|
+
specification_version: 4
|
223
|
+
summary: Simple doctor bot
|
224
|
+
test_files: []
|