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.

Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +522 -0
  3. data/bin/chemistry_paradise +7 -0
  4. data/bin/wetter +7 -0
  5. data/chemistry_paradise.gemspec +46 -0
  6. data/doc/README.gen +518 -0
  7. data/doc/bugs/BUGS.md +16 -0
  8. data/doc/formulas/biochemical_calculations.md +5 -0
  9. data/doc/todo/todo_for_the_chemistry_paradise_project.md +33 -0
  10. data/doc/todo/todo_for_the_wetter_project.md +7 -0
  11. data/lib/chemistry_paradise/base/base.rb +215 -0
  12. data/lib/chemistry_paradise/base/colours.rb +93 -0
  13. data/lib/chemistry_paradise/commandline/help.rb +40 -0
  14. data/lib/chemistry_paradise/commandline/menu.rb +88 -0
  15. data/lib/chemistry_paradise/commandline/parse_commandline.rb +94 -0
  16. data/lib/chemistry_paradise/constants/constants.rb +77 -0
  17. data/lib/chemistry_paradise/constants/file_constants.rb +33 -0
  18. data/lib/chemistry_paradise/constants/german_names_of_elements_to_element_symbol.rb +157 -0
  19. data/lib/chemistry_paradise/converters/celsius_to_fahrenheit.rb +143 -0
  20. data/lib/chemistry_paradise/converters/celsius_to_kelvin.rb +125 -0
  21. data/lib/chemistry_paradise/converters/fahrenheit_to_celsius.rb +132 -0
  22. data/lib/chemistry_paradise/converters/shared.rb +21 -0
  23. data/lib/chemistry_paradise/gui/gtk3/calculate_molecular_weight/calculate_molecular_weight.rb +34 -0
  24. data/lib/chemistry_paradise/gui/gtk3/show_periodic_table/show_periodic_table.rb +34 -0
  25. data/lib/chemistry_paradise/gui/gtk3/temperature_converter/temperature_converter.rb +112 -0
  26. data/lib/chemistry_paradise/gui/gtk3/wetter/wetter.rb +119 -0
  27. data/lib/chemistry_paradise/gui/libui/temperature_converter/temperature_converter.rb +100 -0
  28. data/lib/chemistry_paradise/gui/libui/wetter/wetter.rb +47 -0
  29. data/lib/chemistry_paradise/gui/shared_code/calculate_molecular_weight/calculate_molecular_weight_module.rb +171 -0
  30. data/lib/chemistry_paradise/gui/shared_code/show_periodic_table/show_periodic_table_module.rb +318 -0
  31. data/lib/chemistry_paradise/gui/shared_code/temperature_converter/temperature_converter_module.rb +192 -0
  32. data/lib/chemistry_paradise/gui/shared_code/wetter/wetter_module.rb +349 -0
  33. data/lib/chemistry_paradise/gui/swing/TemperatureConverter$1.class +0 -0
  34. data/lib/chemistry_paradise/gui/swing/TemperatureConverter.class +0 -0
  35. data/lib/chemistry_paradise/gui/swing/TemperatureConverter.java +133 -0
  36. data/lib/chemistry_paradise/gui/unified_widgets/wetter/wetter.rb +62 -0
  37. data/lib/chemistry_paradise/images/show_periodic_table.png +0 -0
  38. data/lib/chemistry_paradise/images/vienna_map.png +0 -0
  39. data/lib/chemistry_paradise/interactive_chemistry_shell.rb +246 -0
  40. data/lib/chemistry_paradise/project/project.rb +24 -0
  41. data/lib/chemistry_paradise/requires/common_external_requires.rb +17 -0
  42. data/lib/chemistry_paradise/requires/require_the_project.rb +21 -0
  43. data/lib/chemistry_paradise/requires/require_the_project_including_the_graphical_user_interface.rb +7 -0
  44. data/lib/chemistry_paradise/requires/require_the_project_including_the_web_interface.rb +4 -0
  45. data/lib/chemistry_paradise/shared.rb +130 -0
  46. data/lib/chemistry_paradise/show_electron_configuration.rb +250 -0
  47. data/lib/chemistry_paradise/show_element.rb +145 -0
  48. data/lib/chemistry_paradise/sinatra/sinatra.rb +131 -0
  49. data/lib/chemistry_paradise/sinatra/wetter/app.rb +68 -0
  50. data/lib/chemistry_paradise/sinatra/wetter/start_sinatra_interface.rb +31 -0
  51. data/lib/chemistry_paradise/split_molecule_names.rb +228 -0
  52. data/lib/chemistry_paradise/toplevel_methods/atomgewichte.rb +31 -0
  53. data/lib/chemistry_paradise/toplevel_methods/convert_parens.rb +64 -0
  54. data/lib/chemistry_paradise/toplevel_methods/display_where_the_molmasses_are_kept.rb +24 -0
  55. data/lib/chemistry_paradise/toplevel_methods/e.rb +16 -0
  56. data/lib/chemistry_paradise/toplevel_methods/kelvin.rb +34 -0
  57. data/lib/chemistry_paradise/toplevel_methods/language.rb +50 -0
  58. data/lib/chemistry_paradise/toplevel_methods/misc.rb +147 -0
  59. data/lib/chemistry_paradise/toplevel_methods/periodic_table.rb +16 -0
  60. data/lib/chemistry_paradise/toplevel_methods/remove_this_molecule_from.rb +63 -0
  61. data/lib/chemistry_paradise/toplevel_methods/roebe.rb +16 -0
  62. data/lib/chemistry_paradise/toplevel_methods/show_electron_negativity_chart.rb +26 -0
  63. data/lib/chemistry_paradise/utility_scripts/calculate_atomic_mass.rb +559 -0
  64. data/lib/chemistry_paradise/utility_scripts/combustion_analysis.rb +207 -0
  65. data/lib/chemistry_paradise/utility_scripts/electron_negativity_chart.rb +78 -0
  66. data/lib/chemistry_paradise/utility_scripts/equalize_chemical_formula.rb +84 -0
  67. data/lib/chemistry_paradise/utility_scripts/equation_solver.rb +130 -0
  68. data/lib/chemistry_paradise/utility_scripts/orbitals.rb +70 -0
  69. data/lib/chemistry_paradise/utility_scripts/show_electron_negativity_of_this_element.rb +103 -0
  70. data/lib/chemistry_paradise/verbose_chemical_calculation.rb +21 -0
  71. data/lib/chemistry_paradise/version/version.rb +19 -0
  72. data/lib/chemistry_paradise/wetter/wetter.rb +539 -0
  73. data/lib/chemistry_paradise/www/wetter/embeddable_interface.rb +78 -0
  74. data/lib/chemistry_paradise/www/wetter/wetter.cgi +28 -0
  75. data/lib/chemistry_paradise/yaml/atomgewichte.yml +113 -0
  76. data/lib/chemistry_paradise/yaml/colours_for_the_elements.yml +13 -0
  77. data/lib/chemistry_paradise/yaml/dichte.yml +21 -0
  78. data/lib/chemistry_paradise/yaml/electron_negativity_chart.yml +111 -0
  79. data/lib/chemistry_paradise/yaml/molecular_formula_of_different_molecules.yml +13 -0
  80. data/lib/chemistry_paradise/yaml/periodic_table_of_the_elements.yml +125 -0
  81. data/lib/chemistry_paradise.rb +1 -0
  82. data/test/testing_chemistry_paradise.rb +49 -0
  83. 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