chemistry_paradise 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of chemistry_paradise might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/README.md +522 -0
- data/bin/chemistry_paradise +7 -0
- data/bin/wetter +7 -0
- data/chemistry_paradise.gemspec +46 -0
- data/doc/README.gen +518 -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/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 +147 -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/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 +113 -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 +173 -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/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
|