chemistry_paradise 1.4.2
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/README.md +657 -0
- data/bin/chemistry_paradise +7 -0
- data/bin/wetter +7 -0
- data/chemistry_paradise.gemspec +46 -0
- data/doc/README.gen +595 -0
- data/doc/bugs/BUGS.md +16 -0
- data/doc/formulas/biochemical_calculations.md +5 -0
- data/doc/todo/todo_for_the_chemistry_paradise_project.md +33 -0
- data/doc/todo/todo_for_the_wetter_project.md +7 -0
- data/lib/chemistry_paradise/base/base.rb +215 -0
- data/lib/chemistry_paradise/base/colours.rb +93 -0
- data/lib/chemistry_paradise/commandline/help.rb +40 -0
- data/lib/chemistry_paradise/commandline/menu.rb +88 -0
- data/lib/chemistry_paradise/commandline/parse_commandline.rb +94 -0
- data/lib/chemistry_paradise/constants/constants.rb +77 -0
- data/lib/chemistry_paradise/constants/constants_for_chemical_formulas.rb +16 -0
- data/lib/chemistry_paradise/constants/file_constants.rb +33 -0
- data/lib/chemistry_paradise/constants/german_names_of_elements_to_element_symbol.rb +157 -0
- data/lib/chemistry_paradise/converters/celsius_to_fahrenheit.rb +143 -0
- data/lib/chemistry_paradise/converters/celsius_to_kelvin.rb +125 -0
- data/lib/chemistry_paradise/converters/fahrenheit_to_celsius.rb +132 -0
- data/lib/chemistry_paradise/converters/shared.rb +21 -0
- data/lib/chemistry_paradise/gui/gtk3/calculate_molecular_weight/calculate_molecular_weight.rb +34 -0
- data/lib/chemistry_paradise/gui/gtk3/show_periodic_table/show_periodic_table.rb +34 -0
- data/lib/chemistry_paradise/gui/gtk3/temperature_converter/temperature_converter.rb +112 -0
- data/lib/chemistry_paradise/gui/gtk3/wetter/wetter.rb +119 -0
- data/lib/chemistry_paradise/gui/libui/temperature_converter/temperature_converter.rb +100 -0
- data/lib/chemistry_paradise/gui/libui/wetter/wetter.rb +47 -0
- data/lib/chemistry_paradise/gui/shared_code/calculate_molecular_weight/calculate_molecular_weight_module.rb +171 -0
- data/lib/chemistry_paradise/gui/shared_code/show_periodic_table/show_periodic_table_module.rb +318 -0
- data/lib/chemistry_paradise/gui/shared_code/temperature_converter/temperature_converter_module.rb +192 -0
- data/lib/chemistry_paradise/gui/shared_code/wetter/wetter_module.rb +349 -0
- data/lib/chemistry_paradise/gui/swing/TemperatureConverter$1.class +0 -0
- data/lib/chemistry_paradise/gui/swing/TemperatureConverter.class +0 -0
- data/lib/chemistry_paradise/gui/swing/TemperatureConverter.java +133 -0
- data/lib/chemistry_paradise/gui/unified_widgets/wetter/wetter.rb +62 -0
- data/lib/chemistry_paradise/images/show_periodic_table.png +0 -0
- data/lib/chemistry_paradise/images/vienna_map.png +0 -0
- data/lib/chemistry_paradise/interactive_chemistry_shell.rb +246 -0
- data/lib/chemistry_paradise/project/project.rb +24 -0
- data/lib/chemistry_paradise/requires/common_external_requires.rb +17 -0
- data/lib/chemistry_paradise/requires/require_the_project.rb +21 -0
- data/lib/chemistry_paradise/requires/require_the_project_including_the_graphical_user_interface.rb +7 -0
- data/lib/chemistry_paradise/requires/require_the_project_including_the_web_interface.rb +4 -0
- data/lib/chemistry_paradise/shared.rb +130 -0
- data/lib/chemistry_paradise/show_electron_configuration.rb +250 -0
- data/lib/chemistry_paradise/show_element.rb +145 -0
- data/lib/chemistry_paradise/sinatra/sinatra.rb +131 -0
- data/lib/chemistry_paradise/sinatra/wetter/app.rb +68 -0
- data/lib/chemistry_paradise/sinatra/wetter/start_sinatra_interface.rb +31 -0
- data/lib/chemistry_paradise/split_molecule_names.rb +228 -0
- data/lib/chemistry_paradise/toplevel_methods/atomgewichte.rb +31 -0
- data/lib/chemistry_paradise/toplevel_methods/convert_parens.rb +64 -0
- data/lib/chemistry_paradise/toplevel_methods/display_where_the_molmasses_are_kept.rb +24 -0
- data/lib/chemistry_paradise/toplevel_methods/e.rb +16 -0
- data/lib/chemistry_paradise/toplevel_methods/kelvin.rb +34 -0
- data/lib/chemistry_paradise/toplevel_methods/language.rb +50 -0
- data/lib/chemistry_paradise/toplevel_methods/misc.rb +228 -0
- data/lib/chemistry_paradise/toplevel_methods/periodic_table.rb +16 -0
- data/lib/chemistry_paradise/toplevel_methods/remove_this_molecule_from.rb +63 -0
- data/lib/chemistry_paradise/toplevel_methods/roebe.rb +16 -0
- data/lib/chemistry_paradise/toplevel_methods/show_electron_negativity_chart.rb +26 -0
- data/lib/chemistry_paradise/utility_scripts/calculate_atomic_mass.rb +559 -0
- data/lib/chemistry_paradise/utility_scripts/combustion_analysis.rb +207 -0
- data/lib/chemistry_paradise/utility_scripts/electron_negativity_chart.rb +78 -0
- data/lib/chemistry_paradise/utility_scripts/equalize_chemical_formula.rb +84 -0
- data/lib/chemistry_paradise/utility_scripts/equation_solver.rb +130 -0
- data/lib/chemistry_paradise/utility_scripts/orbitals.rb +70 -0
- data/lib/chemistry_paradise/utility_scripts/show_electron_negativity_of_this_element.rb +103 -0
- data/lib/chemistry_paradise/utility_scripts/show_periodic_table.rb +996 -0
- data/lib/chemistry_paradise/verbose_chemical_calculation.rb +21 -0
- data/lib/chemistry_paradise/version/version.rb +19 -0
- data/lib/chemistry_paradise/wetter/wetter.rb +539 -0
- data/lib/chemistry_paradise/www/wetter/embeddable_interface.rb +78 -0
- data/lib/chemistry_paradise/www/wetter/wetter.cgi +28 -0
- data/lib/chemistry_paradise/yaml/atomgewichte.yml +139 -0
- data/lib/chemistry_paradise/yaml/colours_for_the_elements.yml +13 -0
- data/lib/chemistry_paradise/yaml/dichte.yml +21 -0
- data/lib/chemistry_paradise/yaml/electron_negativity_chart.yml +111 -0
- data/lib/chemistry_paradise/yaml/molecular_formula_of_different_molecules.yml +13 -0
- data/lib/chemistry_paradise/yaml/periodic_table_of_the_elements.yml +125 -0
- data/lib/chemistry_paradise.rb +1 -0
- data/test/testing_chemistry_paradise.rb +49 -0
- metadata +175 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# require 'chemistry_paradise/toplevel_methods/periodic_table.rb'
|
|
6
|
+
# =========================================================================== #
|
|
7
|
+
module ChemistryParadise
|
|
8
|
+
|
|
9
|
+
# ========================================================================= #
|
|
10
|
+
# === ChemistryParadise.periodic_table?
|
|
11
|
+
# ========================================================================= #
|
|
12
|
+
def self.periodic_table?
|
|
13
|
+
'/Users/x/DATA/SCIENCE/YAML/periodic_table.yml'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# require 'chemistry_paradise/toplevel_methods/remove_this_molecule_from.rb'
|
|
6
|
+
# =========================================================================== #
|
|
7
|
+
require 'chemistry_paradise/split_molecule_names.rb'
|
|
8
|
+
|
|
9
|
+
module ChemistryParadise
|
|
10
|
+
|
|
11
|
+
# ========================================================================= #
|
|
12
|
+
# === ChemistryParadise.remove_this_molecule_from
|
|
13
|
+
#
|
|
14
|
+
# The first argument is the molecule that should be deducted from
|
|
15
|
+
# the formula.
|
|
16
|
+
# ========================================================================= #
|
|
17
|
+
def self.remove_this_molecule_from(
|
|
18
|
+
this_molecule = 'OH',
|
|
19
|
+
from = 'C2H5NO2'
|
|
20
|
+
)
|
|
21
|
+
array_big_molecule = ::ChemistryParadise.split_this_molecular_formula_into_a_hash(from)
|
|
22
|
+
array_this_molecule = ::ChemistryParadise.split_this_molecular_formula_into_a_hash(this_molecule)
|
|
23
|
+
# ======================================================================= #
|
|
24
|
+
# Next, iterate over the small molecule.
|
|
25
|
+
# ======================================================================= #
|
|
26
|
+
array_this_molecule.each {|this_compound|
|
|
27
|
+
unless this_compound =~ /\d+/
|
|
28
|
+
this_compound << '1' # Must be at the least one.
|
|
29
|
+
end
|
|
30
|
+
# ===================================================================== #
|
|
31
|
+
# Select the entry that is the correct one.
|
|
32
|
+
# ===================================================================== #
|
|
33
|
+
this_entry = array_big_molecule.find {|entry|
|
|
34
|
+
entry[0,1] == this_compound[0,1]
|
|
35
|
+
}
|
|
36
|
+
begin
|
|
37
|
+
n_times_in_the_big_molecule = /(\d{1,3})/.match(this_entry)[1].to_i
|
|
38
|
+
n_times_in_the_small_molecule = /(\d{1,3})/.match(this_compound)[1].to_i
|
|
39
|
+
new_n_times = n_times_in_the_big_molecule - n_times_in_the_small_molecule
|
|
40
|
+
new_entry = this_compound[0,1]+new_n_times.to_s
|
|
41
|
+
# ===================================================================== #
|
|
42
|
+
# Now we have the new entry; we need to re-insert it into the big
|
|
43
|
+
# original Array.
|
|
44
|
+
# ===================================================================== #
|
|
45
|
+
proper_index = array_big_molecule.index {|entry|
|
|
46
|
+
entry[0,1] == this_compound[0,1]
|
|
47
|
+
}
|
|
48
|
+
array_big_molecule[proper_index] = new_entry
|
|
49
|
+
rescue NoMethodError => error
|
|
50
|
+
pp error
|
|
51
|
+
end
|
|
52
|
+
}
|
|
53
|
+
return array_big_molecule.join # Join it up again.
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if __FILE__ == $PROGRAM_NAME
|
|
59
|
+
puts 'Deducting OH from C2H5NO2 next:'
|
|
60
|
+
puts ::ChemistryParadise.remove_this_molecule_from('OH', 'C2H5NO2')
|
|
61
|
+
puts 'Deducting H2O from C2H5NO2 next:'
|
|
62
|
+
puts ::ChemistryParadise.remove_this_molecule_from('H2O', 'C2H5NO2')
|
|
63
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# require 'chemistry_paradise/toplevel_methods/roebe.rb'
|
|
6
|
+
# =========================================================================== #
|
|
7
|
+
module ChemistryParadise
|
|
8
|
+
|
|
9
|
+
# ========================================================================= #
|
|
10
|
+
# === ChemistryParadise.is_on_roebe?
|
|
11
|
+
# ========================================================================= #
|
|
12
|
+
def self.is_on_roebe?
|
|
13
|
+
ENV['IS_ROEBE'].to_s == '1'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# require 'chemistry_paradise/toplevel_methods/show_electron_negativity_chart.rb'
|
|
6
|
+
# =========================================================================== #
|
|
7
|
+
require 'chemistry_paradise/constants/constants.rb'
|
|
8
|
+
|
|
9
|
+
module ChemistryParadise
|
|
10
|
+
|
|
11
|
+
# ========================================================================= #
|
|
12
|
+
# === ChemistryParadise.show_electron_negativity_chart
|
|
13
|
+
# ========================================================================= #
|
|
14
|
+
def self.show_electron_negativity_chart
|
|
15
|
+
Constants::ELECTRON_NEGATIVITY_CHART.each_pair {|key, value|
|
|
16
|
+
value = value.to_f
|
|
17
|
+
value = '%.2f' % value
|
|
18
|
+
puts key.ljust(2)+' -> '+value.to_s.rjust(2)
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if __FILE__ == $PROGRAM_NAME
|
|
25
|
+
ChemistryParadise.show_electron_negativity_chart
|
|
26
|
+
end
|
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# === ChemistryParadise::CalculateAtomicMass
|
|
6
|
+
#
|
|
7
|
+
# This class will calculate the atomic mass of a compound.
|
|
8
|
+
# =========================================================================== #
|
|
9
|
+
# require 'chemistry_paradise/utility_scripts/calculate_atomic_mass.rb'
|
|
10
|
+
# ChemistryParadise::CalculateAtomicMass.new(ARGV)
|
|
11
|
+
# =========================================================================== #
|
|
12
|
+
require 'chemistry_paradise/base/base.rb'
|
|
13
|
+
|
|
14
|
+
module ChemistryParadise
|
|
15
|
+
|
|
16
|
+
class CalculateAtomicMass < Base # === ChemistryParadise::CalculateAtomicMass
|
|
17
|
+
|
|
18
|
+
require 'chemistry_paradise/split_molecule_names.rb'
|
|
19
|
+
|
|
20
|
+
# ========================================================================= #
|
|
21
|
+
# === NAMESPACE
|
|
22
|
+
# ========================================================================= #
|
|
23
|
+
NAMESPACE = inspect
|
|
24
|
+
|
|
25
|
+
# ========================================================================= #
|
|
26
|
+
# === ARRAY_HELP_OPTIONS
|
|
27
|
+
# ========================================================================= #
|
|
28
|
+
ARRAY_HELP_OPTIONS = %w(
|
|
29
|
+
HELP help --help --h -h
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# ========================================================================= #
|
|
33
|
+
# === ATOMGEWICHTE
|
|
34
|
+
# ========================================================================= #
|
|
35
|
+
_ = Constants::FILE_ATOMGEWICHTE
|
|
36
|
+
if File.exist? _
|
|
37
|
+
ATOMGEWICHTE = YAML.load_file(_)
|
|
38
|
+
elsif File.exist? File.expand_path('~')+File.basename(_)
|
|
39
|
+
ATOMGEWICHTE = YAML.load_file(File.expand_path('~')+File.basename(_))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# ========================================================================= #
|
|
43
|
+
# === ChemistryParadise::CalculateAtomicMass::DEFAULT_INPUT
|
|
44
|
+
# ========================================================================= #
|
|
45
|
+
DEFAULT_INPUT = 'P2O5'
|
|
46
|
+
|
|
47
|
+
# ========================================================================= #
|
|
48
|
+
# === initialize
|
|
49
|
+
# ========================================================================= #
|
|
50
|
+
def initialize(
|
|
51
|
+
optional_input = ARGV,
|
|
52
|
+
run_already = true
|
|
53
|
+
)
|
|
54
|
+
reset
|
|
55
|
+
set_input(optional_input)
|
|
56
|
+
case run_already.to_s
|
|
57
|
+
when 'do_not_report'
|
|
58
|
+
@report_result = false
|
|
59
|
+
run_already = true
|
|
60
|
+
end
|
|
61
|
+
# ======================================================================= #
|
|
62
|
+
# === Handle blocks next
|
|
63
|
+
# ======================================================================= #
|
|
64
|
+
if block_given?
|
|
65
|
+
yielded = yield
|
|
66
|
+
case yielded
|
|
67
|
+
# ===================================================================== #
|
|
68
|
+
# === :do_not_exit
|
|
69
|
+
# ===================================================================== #
|
|
70
|
+
when :do_not_exit
|
|
71
|
+
@may_we_exit = false
|
|
72
|
+
else
|
|
73
|
+
if yielded.is_a? Hash
|
|
74
|
+
_ = yielded
|
|
75
|
+
if _.has_key? :verbosity
|
|
76
|
+
@report_result = _[:verbosity]
|
|
77
|
+
end
|
|
78
|
+
if _.has_key? :may_we_exit
|
|
79
|
+
@may_we_exit =_[:may_we_exit]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
run if run_already
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# ========================================================================= #
|
|
88
|
+
# === reset
|
|
89
|
+
# ========================================================================= #
|
|
90
|
+
def reset
|
|
91
|
+
super()
|
|
92
|
+
# ======================================================================= #
|
|
93
|
+
# === @commandline_arguments
|
|
94
|
+
# ======================================================================= #
|
|
95
|
+
@commandline_arguments = []
|
|
96
|
+
# ======================================================================= #
|
|
97
|
+
# === @show_more
|
|
98
|
+
# ======================================================================= #
|
|
99
|
+
@show_more = true
|
|
100
|
+
# ======================================================================= #
|
|
101
|
+
# === @show_the_steps
|
|
102
|
+
#
|
|
103
|
+
# If the following variable is set to true then we will display,
|
|
104
|
+
# on the commandline, what is done when. This gives the user more
|
|
105
|
+
# information about what is going on, and it may also help during
|
|
106
|
+
# debugging this class/project.
|
|
107
|
+
#
|
|
108
|
+
# Note that @show_the_steps is a bit different to @show_more, so
|
|
109
|
+
# these two variables are presently kept separate.
|
|
110
|
+
# ======================================================================= #
|
|
111
|
+
@show_the_steps = false
|
|
112
|
+
# ======================================================================= #
|
|
113
|
+
# === @individual_components
|
|
114
|
+
# ======================================================================= #
|
|
115
|
+
@individual_components = []
|
|
116
|
+
# ======================================================================= #
|
|
117
|
+
# === @output_string
|
|
118
|
+
# ======================================================================= #
|
|
119
|
+
@output_string = ''.dup
|
|
120
|
+
# ======================================================================= #
|
|
121
|
+
# === @report_result
|
|
122
|
+
# ======================================================================= #
|
|
123
|
+
@report_result = true
|
|
124
|
+
# ======================================================================= #
|
|
125
|
+
# === @may_we_exit
|
|
126
|
+
# ======================================================================= #
|
|
127
|
+
@may_we_exit = true
|
|
128
|
+
# ======================================================================= #
|
|
129
|
+
# === @molecular_formula_of_different_molecules
|
|
130
|
+
# ======================================================================= #
|
|
131
|
+
@molecular_formula_of_different_molecules = YAML.load_file(
|
|
132
|
+
FILE_MOLECULAR_FORMULA_OF_DIFFERENT_MOLECULES
|
|
133
|
+
)
|
|
134
|
+
set_input
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# ========================================================================= #
|
|
138
|
+
# === set_input
|
|
139
|
+
# ========================================================================= #
|
|
140
|
+
def set_input(i = DEFAULT_INPUT)
|
|
141
|
+
if i.is_a? Array
|
|
142
|
+
@commandline_arguments = i[1..-1] # Set the remaining as commandline arguments.
|
|
143
|
+
i = i.first # And re-assign the first input.
|
|
144
|
+
end
|
|
145
|
+
i = DEFAULT_INPUT if i.nil?
|
|
146
|
+
case i.to_s
|
|
147
|
+
when 'do_not_report'
|
|
148
|
+
@report_result = false
|
|
149
|
+
i = nil
|
|
150
|
+
when 'harnstoff'
|
|
151
|
+
i = @molecular_formula_of_different_molecules['harnstoff']
|
|
152
|
+
end
|
|
153
|
+
i = ARRAY_TEST_THESE_MOLECULES if i == :test_default_molecules
|
|
154
|
+
i = i.to_s.dup
|
|
155
|
+
# if i.include? ', '
|
|
156
|
+
# i = i.split(',').map(&:strip)
|
|
157
|
+
# end
|
|
158
|
+
# i = [i] unless i.is_a? Array
|
|
159
|
+
@input = i
|
|
160
|
+
sanitize_input
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# ========================================================================= #
|
|
164
|
+
# === input?
|
|
165
|
+
# ========================================================================= #
|
|
166
|
+
def input?
|
|
167
|
+
@input
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# ========================================================================= #
|
|
171
|
+
# === sanitize_input_for_element_names
|
|
172
|
+
# ========================================================================= #
|
|
173
|
+
def sanitize_input_for_element_names(array)
|
|
174
|
+
result = []
|
|
175
|
+
if array.any? {|entry| entry == entry.downcase }
|
|
176
|
+
array.each {|entry|
|
|
177
|
+
case entry
|
|
178
|
+
when *ARRAY_HELP_OPTIONS
|
|
179
|
+
show_help :then_exit
|
|
180
|
+
end
|
|
181
|
+
if entry == entry.downcase
|
|
182
|
+
result[-1] = result[-1]+entry
|
|
183
|
+
else
|
|
184
|
+
result << entry
|
|
185
|
+
end
|
|
186
|
+
}
|
|
187
|
+
else
|
|
188
|
+
result = array
|
|
189
|
+
end
|
|
190
|
+
return result
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# ========================================================================= #
|
|
194
|
+
# === calculate_compound
|
|
195
|
+
#
|
|
196
|
+
# This method will attempt to calculate the given input.
|
|
197
|
+
#
|
|
198
|
+
# The input to this method will usually be something like "Pb3".
|
|
199
|
+
# ========================================================================= #
|
|
200
|
+
def calculate_compound(i)
|
|
201
|
+
result = 0
|
|
202
|
+
if i =~ /\d+/ # if input has a number
|
|
203
|
+
splitted = i.split(/(\d+)/)
|
|
204
|
+
else # else assume that the number is one.
|
|
205
|
+
splitted = [ i, 1 ]
|
|
206
|
+
end
|
|
207
|
+
if atomgewichte?.has_key? splitted[0]
|
|
208
|
+
result = splitted[1].to_i * ATOMGEWICHTE[splitted[0]]
|
|
209
|
+
end
|
|
210
|
+
gather_individual_components(i, result)
|
|
211
|
+
return result
|
|
212
|
+
end; alias ba calculate_compound # === ba
|
|
213
|
+
alias summenformel calculate_compound # === summenformel
|
|
214
|
+
alias atomgewicht calculate_compound # === atomgewicht
|
|
215
|
+
alias molmasse calculate_compound # === molmasse
|
|
216
|
+
alias molare_masse calculate_compound # === molare_masse
|
|
217
|
+
alias calculcate_molecular_weight calculate_compound # === calculcate_molecular_weight
|
|
218
|
+
|
|
219
|
+
# ========================================================================= #
|
|
220
|
+
# === atomgewichte?
|
|
221
|
+
# ========================================================================= #
|
|
222
|
+
def atomgewichte?
|
|
223
|
+
ATOMGEWICHTE
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# ========================================================================= #
|
|
227
|
+
# === set_result
|
|
228
|
+
# ========================================================================= #
|
|
229
|
+
def set_result(i)
|
|
230
|
+
@result = i
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# ========================================================================= #
|
|
234
|
+
# === report_result
|
|
235
|
+
# ========================================================================= #
|
|
236
|
+
def report_result
|
|
237
|
+
e @output_string
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# ========================================================================= #
|
|
241
|
+
# === gather_individual_components
|
|
242
|
+
# ========================================================================= #
|
|
243
|
+
def gather_individual_components(name, weight)
|
|
244
|
+
array = [name, weight]
|
|
245
|
+
@individual_components << array
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# ========================================================================= #
|
|
249
|
+
# === bold_red
|
|
250
|
+
# ========================================================================= #
|
|
251
|
+
def bold_red(i)
|
|
252
|
+
swarn(i)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# ========================================================================= #
|
|
256
|
+
# === nice_result
|
|
257
|
+
# ========================================================================= #
|
|
258
|
+
def nice_result
|
|
259
|
+
@result.to_f.round(3).to_s
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# ========================================================================= #
|
|
263
|
+
# === is_included?
|
|
264
|
+
# ========================================================================= #
|
|
265
|
+
def is_included?(i = input?)
|
|
266
|
+
i = i.dup
|
|
267
|
+
# ======================================================================= #
|
|
268
|
+
# First remove all numbers from the input:
|
|
269
|
+
# ======================================================================= #
|
|
270
|
+
i.delete!('0-9')
|
|
271
|
+
i = i[0,2] if i.size > 2 # Take only the first two characters, in the event that we have more than two characters in the supplied input.
|
|
272
|
+
atomgewichte?.has_key?(i)
|
|
273
|
+
end; alias include? is_included? # === include?
|
|
274
|
+
|
|
275
|
+
# ========================================================================= #
|
|
276
|
+
# === report_result?
|
|
277
|
+
# ========================================================================= #
|
|
278
|
+
def report_result?
|
|
279
|
+
@report_result
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# ========================================================================= #
|
|
283
|
+
# === result?
|
|
284
|
+
# ========================================================================= #
|
|
285
|
+
def result?
|
|
286
|
+
@result
|
|
287
|
+
end; alias result result? # === result
|
|
288
|
+
alias masse? result? # === masse?
|
|
289
|
+
|
|
290
|
+
# ========================================================================= #
|
|
291
|
+
# === menu (menu tag)
|
|
292
|
+
#
|
|
293
|
+
# The @commandline_arguments will be checked against the internal menu.
|
|
294
|
+
# ========================================================================= #
|
|
295
|
+
def menu(i = @commandline_arguments)
|
|
296
|
+
if i.is_a? Array
|
|
297
|
+
i.each {|entry| menu(entry) }
|
|
298
|
+
else
|
|
299
|
+
case i # case tag
|
|
300
|
+
# ===================================================================== #
|
|
301
|
+
# === molmasse C5H6N2O2 --english
|
|
302
|
+
# ===================================================================== #
|
|
303
|
+
when /^-?-?english$/
|
|
304
|
+
do_use_the_english_language
|
|
305
|
+
# ===================================================================== #
|
|
306
|
+
# === molmasse C5H6N2O2 --show-steps
|
|
307
|
+
# ===================================================================== #
|
|
308
|
+
when /^-?-?show(-|_)?steps$/
|
|
309
|
+
do_show_the_steps
|
|
310
|
+
# ===================================================================== #
|
|
311
|
+
# === molmasse C5H6N2O2 --show-details
|
|
312
|
+
# ===================================================================== #
|
|
313
|
+
when /^-?-?show(-|_)?details?$/,
|
|
314
|
+
'--detail'
|
|
315
|
+
do_show_details
|
|
316
|
+
# ===================================================================== #
|
|
317
|
+
# === molmasse --help
|
|
318
|
+
# ===================================================================== #
|
|
319
|
+
when *ARRAY_HELP_OPTIONS
|
|
320
|
+
show_help
|
|
321
|
+
exit_the_program
|
|
322
|
+
# ===================================================================== #
|
|
323
|
+
# === molmasse SUM
|
|
324
|
+
# ===================================================================== #
|
|
325
|
+
when 'SUM',
|
|
326
|
+
'SHOW',
|
|
327
|
+
'MORE'
|
|
328
|
+
do_show_details
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
end; alias check_against_menu menu # === check_against_menu
|
|
332
|
+
|
|
333
|
+
# ========================================================================= #
|
|
334
|
+
# === do_show_details
|
|
335
|
+
# ========================================================================= #
|
|
336
|
+
def do_show_details
|
|
337
|
+
@show_more = true
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# ========================================================================= #
|
|
341
|
+
# === opnn
|
|
342
|
+
# ========================================================================= #
|
|
343
|
+
def opnn
|
|
344
|
+
super(NAMESPACE)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
# ========================================================================= #
|
|
348
|
+
# === determine_output_string
|
|
349
|
+
#
|
|
350
|
+
# This method will determine the String that will be shown to the
|
|
351
|
+
# user on the commandline.
|
|
352
|
+
# ========================================================================= #
|
|
353
|
+
def determine_output_string
|
|
354
|
+
_ = nice_result
|
|
355
|
+
if do_we_use_english?
|
|
356
|
+
@output_string = "#{rev}The molecular mass of #{sfancy(@input)} is "\
|
|
357
|
+
"#{simp(_+' u (g / mol)')}."
|
|
358
|
+
else # then we probably use german
|
|
359
|
+
@output_string = "#{rev}Die molekulare Masse von #{sfancy(@input)} "\
|
|
360
|
+
"beträgt #{simp(_+' u (g / mol)')}."
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
# ========================================================================= #
|
|
365
|
+
# === show_help
|
|
366
|
+
# ========================================================================= #
|
|
367
|
+
def show_help(
|
|
368
|
+
i = :then_exit
|
|
369
|
+
)
|
|
370
|
+
opn; e 'Pass -SUM to show the individual sub-steps as well.'
|
|
371
|
+
exit_the_program(i)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# ========================================================================= #
|
|
375
|
+
# === consider_modifying_the_output_string
|
|
376
|
+
# ========================================================================= #
|
|
377
|
+
def consider_modifying_the_output_string
|
|
378
|
+
if @show_more # This can modify the output string.
|
|
379
|
+
_ = ''.dup
|
|
380
|
+
Hash[@individual_components].each_pair {|key, value|
|
|
381
|
+
key = key.scan(/./).map {|entry|
|
|
382
|
+
# if entry =~ /^\d+/ # Starts with a number.
|
|
383
|
+
# entry << 'x'
|
|
384
|
+
# end # Disabled as of July 2021. May be re-enabled at a later time.
|
|
385
|
+
entry
|
|
386
|
+
}
|
|
387
|
+
key = key.join
|
|
388
|
+
_ << key+': '+value.round(7).to_s+' | '
|
|
389
|
+
}
|
|
390
|
+
@output_string = @output_string.dup if @output_string.frozen?
|
|
391
|
+
@output_string << "#{N}#{bold_red(' (The individual components were: ').dup}#{rev}"
|
|
392
|
+
_.strip!
|
|
393
|
+
splitted = _.split('|').map {|entry|
|
|
394
|
+
Colours.kde_colour_palette_plasma_blue(entry)
|
|
395
|
+
}
|
|
396
|
+
joined = splitted.join(teal('|'))
|
|
397
|
+
@output_string << joined+
|
|
398
|
+
bold_red(')')
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# ========================================================================= #
|
|
403
|
+
# === do_show_the_steps
|
|
404
|
+
# ========================================================================= #
|
|
405
|
+
def do_show_the_steps
|
|
406
|
+
@show_the_steps = true
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# ========================================================================= #
|
|
410
|
+
# === sanitize_input (sanitize tag)
|
|
411
|
+
#
|
|
412
|
+
# This method will presently sanitize the input, by working on ₂ and
|
|
413
|
+
# on ₃, and replace these with the corresponding numbers. This may
|
|
414
|
+
# be useful depending on the chemical formula at hand, such as
|
|
415
|
+
# carbon dioxide (CO₂).
|
|
416
|
+
# ========================================================================= #
|
|
417
|
+
def sanitize_input
|
|
418
|
+
@input.tr!('₂','2') if @input.include? '₂'
|
|
419
|
+
@input.tr!('₃','3') if @input.include? '₃'
|
|
420
|
+
@input.tr!('₄','4') if @input.include? '₄'
|
|
421
|
+
if @input.include? '∙'
|
|
422
|
+
@input.tr!('∙','|')
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
# ========================================================================= #
|
|
427
|
+
# === run (run tag)
|
|
428
|
+
# ========================================================================= #
|
|
429
|
+
def run
|
|
430
|
+
check_against_menu
|
|
431
|
+
use_this_input = input?
|
|
432
|
+
if use_this_input.to_s.size < 3
|
|
433
|
+
unless is_included?
|
|
434
|
+
report_that_this_element_does_not_exist(use_this_input)
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
calculate_result
|
|
438
|
+
consider_modifying_the_output_string
|
|
439
|
+
report_result if report_result?
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
# ========================================================================= #
|
|
443
|
+
# === report_that_this_element_does_not_exist
|
|
444
|
+
# ========================================================================= #
|
|
445
|
+
def report_that_this_element_does_not_exist(
|
|
446
|
+
i, may_we_exit = @may_we_exit
|
|
447
|
+
)
|
|
448
|
+
opnn; e 'The given element at `'+sfancy(i.to_s)+'` does not exist.'
|
|
449
|
+
exit_the_program(may_we_exit)
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
# ========================================================================= #
|
|
453
|
+
# === exit_the_program
|
|
454
|
+
# ========================================================================= #
|
|
455
|
+
def exit_the_program(
|
|
456
|
+
may_we_exit = @may_we_exit
|
|
457
|
+
)
|
|
458
|
+
case may_we_exit
|
|
459
|
+
when :then_exit
|
|
460
|
+
may_we_exit = true
|
|
461
|
+
end
|
|
462
|
+
exit if may_we_exit
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
# ========================================================================= #
|
|
466
|
+
# === calculate_result
|
|
467
|
+
#
|
|
468
|
+
# Use this method to calculate the result (the molecular mass).
|
|
469
|
+
#
|
|
470
|
+
# Keep in mind that the input may be somewhat complex, such as
|
|
471
|
+
# "(NH₄)₂SO₄". This has to be expanded first.
|
|
472
|
+
# ========================================================================= #
|
|
473
|
+
def calculate_result(
|
|
474
|
+
i = input?
|
|
475
|
+
)
|
|
476
|
+
mass_number = 0 # This will become the result eventually.
|
|
477
|
+
i.squeeze!(' ')
|
|
478
|
+
# ======================================================================= #
|
|
479
|
+
# Let class SplitMoleculeNames split the components next.
|
|
480
|
+
# ======================================================================= #
|
|
481
|
+
splitted = SplitMoleculeNames.new(i).result
|
|
482
|
+
splitted = sanitize_input_for_element_names(splitted)
|
|
483
|
+
splitted.each {|entry|
|
|
484
|
+
add_this_amount = calculate_compound(entry)
|
|
485
|
+
if @show_the_steps
|
|
486
|
+
e "#{rev}Now adding #{royalblue(add_this_amount)} for the "\
|
|
487
|
+
"compound #{steelblue(entry)}."
|
|
488
|
+
end
|
|
489
|
+
mass_number += add_this_amount
|
|
490
|
+
}
|
|
491
|
+
set_result(mass_number)
|
|
492
|
+
determine_output_string
|
|
493
|
+
end; alias calculate calculate_result # === calculate
|
|
494
|
+
|
|
495
|
+
# ========================================================================= #
|
|
496
|
+
# === ChemistryParadise::CalculateAtomicMass[]
|
|
497
|
+
# ========================================================================= #
|
|
498
|
+
def self.[](i)
|
|
499
|
+
parse(i)
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
# ========================================================================= #
|
|
503
|
+
# === ChemistryParadise::CalculateAtomicMass.parse
|
|
504
|
+
# ========================================================================= #
|
|
505
|
+
def self.parse(i)
|
|
506
|
+
_ = new(i, false)
|
|
507
|
+
_.calculate
|
|
508
|
+
return _.nice_result
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
# =========================================================================== #
|
|
514
|
+
# === ChemistryParadise.atomic_mass_of
|
|
515
|
+
#
|
|
516
|
+
# This method is a shortcut, to quickly calculate the molecular mass of
|
|
517
|
+
# a compound. See the usage example that follows.
|
|
518
|
+
#
|
|
519
|
+
# Usage examples:
|
|
520
|
+
#
|
|
521
|
+
# ChemistryParadise.atomic_mass_of 'C10H13N5O3' # => "251.245"
|
|
522
|
+
# ChemistryParadise.atomic_mass_of 'H2O' # => "18.015"
|
|
523
|
+
#
|
|
524
|
+
# =========================================================================== #
|
|
525
|
+
def self.atomic_mass_of(i)
|
|
526
|
+
ChemistryParadise::CalculateAtomicMass.parse(i)
|
|
527
|
+
end; self.instance_eval { alias return_molmasse atomic_mass_of } # === Chemistry.return_molmasse
|
|
528
|
+
self.instance_eval { alias molmass_of? atomic_mass_of } # === Chemistry.molmass_of?
|
|
529
|
+
self.instance_eval { alias compound_mass? atomic_mass_of } # === Chemistry.compound_mass?
|
|
530
|
+
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
if __FILE__ == $PROGRAM_NAME
|
|
534
|
+
include ChemistryParadise
|
|
535
|
+
if ARGV.empty?
|
|
536
|
+
alias e puts
|
|
537
|
+
opn; e 'Running some tests now as no input was given to us.'
|
|
538
|
+
# ======================================================================= #
|
|
539
|
+
# === test_me
|
|
540
|
+
# ======================================================================= #
|
|
541
|
+
def test_me(i)
|
|
542
|
+
puts sprintf(' The mass number of %-4s is %3s',
|
|
543
|
+
i,
|
|
544
|
+
CalculateAtomicMass.new(i).result.to_s
|
|
545
|
+
)
|
|
546
|
+
end
|
|
547
|
+
cliner {
|
|
548
|
+
e 'Nun berechnen wir einige Atomgewichte:'
|
|
549
|
+
ARRAY_TEST_THESE_MOLECULES.each {|entry| test_me(entry) }
|
|
550
|
+
}
|
|
551
|
+
e 'Das Atomgewicht von C12H12N2 ist: '
|
|
552
|
+
e ' → '+test_me('C12H12N2').to_s
|
|
553
|
+
else
|
|
554
|
+
_ = CalculateAtomicMass.new(ARGV)
|
|
555
|
+
end
|
|
556
|
+
end # mmasse T
|
|
557
|
+
# mmasse C16H12N2
|
|
558
|
+
# mmasse CH₃Cl
|
|
559
|
+
# mmasse CaCO3 --show-steps
|