chemistry_paradise 1.1.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 +222 -0
- data/bin/chemistry_paradise +7 -0
- data/chemistry_paradise.gemspec +45 -0
- data/doc/BUGS.md +16 -0
- data/doc/README.gen +205 -0
- data/doc/TODO.md +13 -0
- data/lib/chemistry_paradise.rb +6 -0
- data/lib/chemistry_paradise/base/base.rb +101 -0
- data/lib/chemistry_paradise/base/colours.rb +65 -0
- data/lib/chemistry_paradise/calculate_atomic_mass.rb +487 -0
- data/lib/chemistry_paradise/combustion_analysis.rb +181 -0
- data/lib/chemistry_paradise/commandline/help.rb +35 -0
- data/lib/chemistry_paradise/commandline/menu.rb +80 -0
- data/lib/chemistry_paradise/commandline/parse_commandline.rb +94 -0
- data/lib/chemistry_paradise/constants/constants.rb +52 -0
- data/lib/chemistry_paradise/constants/file_constants.rb +27 -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 +134 -0
- data/lib/chemistry_paradise/converters/fahrenheit_to_celsius.rb +122 -0
- data/lib/chemistry_paradise/converters/shared.rb +15 -0
- data/lib/chemistry_paradise/electron_negativity_chart.rb +78 -0
- data/lib/chemistry_paradise/equalize_chemical_formula.rb +82 -0
- data/lib/chemistry_paradise/equation_solver.rb +130 -0
- data/lib/chemistry_paradise/interactive_chemistry_shell.rb +241 -0
- data/lib/chemistry_paradise/orbitals.rb +65 -0
- data/lib/chemistry_paradise/project/project_base_directory.rb +24 -0
- data/lib/chemistry_paradise/requires/common_external_requires.rb +17 -0
- data/lib/chemistry_paradise/shared.rb +162 -0
- data/lib/chemistry_paradise/show_electron_configuration.rb +243 -0
- data/lib/chemistry_paradise/show_electron_negativity_of_this_element.rb +101 -0
- data/lib/chemistry_paradise/show_element.rb +141 -0
- data/lib/chemistry_paradise/split_molecule_names.rb +185 -0
- data/lib/chemistry_paradise/toplevel_methods/atomgewichte.rb +31 -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/periodic_table.rb +16 -0
- data/lib/chemistry_paradise/toplevel_methods/remove_this_molecule_from.rb +63 -0
- data/lib/chemistry_paradise/toplevel_methods/show_electron_negativity_chart.rb +26 -0
- data/lib/chemistry_paradise/verbose_chemical_calculation.rb +21 -0
- data/lib/chemistry_paradise/version/version.rb +19 -0
- data/lib/chemistry_paradise/yaml/atomgewichte.yml +109 -0
- data/lib/chemistry_paradise/yaml/electron_negativity_chart.yml +109 -0
- data/lib/chemistry_paradise/yaml/molecular_formula_of_different_molecules.yml +12 -0
- data/test/testing_chemistry_paradise.rb +49 -0
- metadata +138 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# Encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
# =========================================================================== #
|
5
|
+
# === ChemistryParadise::EqualizeChemicalFormula
|
6
|
+
#
|
7
|
+
# This class will fill in the missing stoichiometric numbers.
|
8
|
+
#
|
9
|
+
# Usage examples:
|
10
|
+
# EqualizeChemicalFormula.new
|
11
|
+
# =========================================================================== #
|
12
|
+
# require 'chemistry_paradise/equalize_chemical_formula'
|
13
|
+
# =========================================================================== #
|
14
|
+
require 'chemistry_paradise/base/base.rb'
|
15
|
+
|
16
|
+
module ChemistryParadise
|
17
|
+
|
18
|
+
class EqualizeChemicalFormula < ::ChemistryParadise::Base # === EqualizeChemicalFormula
|
19
|
+
|
20
|
+
# ========================================================================= #
|
21
|
+
# === DEFAULT_FORMULA
|
22
|
+
# ========================================================================= #
|
23
|
+
DEFAULT_FORMULA = 'Fe(OH)3 + H2SO4 -> Fe2(SO4)3 + H2O'
|
24
|
+
|
25
|
+
# ========================================================================= #
|
26
|
+
# === initialize
|
27
|
+
# ========================================================================= #
|
28
|
+
def initialize(
|
29
|
+
i = nil,
|
30
|
+
run_already = true
|
31
|
+
)
|
32
|
+
set_test_this_formula(i)
|
33
|
+
run if run_already
|
34
|
+
end
|
35
|
+
|
36
|
+
# ========================================================================= #
|
37
|
+
# === set_original_input
|
38
|
+
# ========================================================================= #
|
39
|
+
def set_original_input(i)
|
40
|
+
@original_input = i
|
41
|
+
end
|
42
|
+
|
43
|
+
# ========================================================================= #
|
44
|
+
# === set_test_this_formula
|
45
|
+
# ========================================================================= #
|
46
|
+
def set_test_this_formula(
|
47
|
+
i = DEFAULT_FORMULA
|
48
|
+
)
|
49
|
+
i = DEFAULT_FORMULA if i.nil?
|
50
|
+
i = DEFAULT_FORMULA if i.empty?
|
51
|
+
set_original_input(i) # Call this before parse().
|
52
|
+
i = parse(i)
|
53
|
+
@test_this_formula = i
|
54
|
+
end
|
55
|
+
|
56
|
+
# ========================================================================= #
|
57
|
+
# === analyze_dataset
|
58
|
+
# ========================================================================= #
|
59
|
+
def analyze_dataset
|
60
|
+
splitted = @test_this_formula.split('->')
|
61
|
+
links = splitted[0]
|
62
|
+
rechts = splitted[1]
|
63
|
+
opn; e 'Auf der '+RED+'linken Seite '+WHITE+'finden wir: '+links
|
64
|
+
opn; e 'Auf der '+RED+'rechten Seite '+WHITE+'finden wir: '+rechts
|
65
|
+
pp 'TODO: WIR MÜSSEN NOCH BERECHNEN WIE VIELE'
|
66
|
+
pp 'ELEMENTE DORT VORKOMMEN'
|
67
|
+
pp splitted
|
68
|
+
end
|
69
|
+
|
70
|
+
# ========================================================================= #
|
71
|
+
# === run (run tag)
|
72
|
+
# ========================================================================= #
|
73
|
+
def run
|
74
|
+
analyze_dataset
|
75
|
+
pp self
|
76
|
+
end
|
77
|
+
|
78
|
+
end; end
|
79
|
+
|
80
|
+
if __FILE__ == $PROGRAM_NAME
|
81
|
+
ChemistryParadise::EqualizeChemicalFormula.new(ARGV)
|
82
|
+
end # $RUBY_CHEMISTRY/equalize_chemical_formula.rb
|
@@ -0,0 +1,130 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# Encoding: UTF-8
|
3
|
+
# =========================================================================== #
|
4
|
+
# === ChemistryParadise::EquationSolver
|
5
|
+
#
|
6
|
+
# Usage example:
|
7
|
+
# ChemistryParadise::EquationSolver.new
|
8
|
+
# =========================================================================== #
|
9
|
+
require 'chemistry_paradise/base/base.rb'
|
10
|
+
require 'chemistry_paradise/split_molecule_names.rb'
|
11
|
+
|
12
|
+
module ChemistryParadise
|
13
|
+
|
14
|
+
class EquationSolver < ::ChemistryParadise::Base # require 'equation_solver'; EquationSolver.new
|
15
|
+
|
16
|
+
# ========================================================================= #
|
17
|
+
# === THIS_FORMULA
|
18
|
+
# ========================================================================= #
|
19
|
+
THIS_FORMULA = 'NH3HHH + O2 -> N2 + H2O'
|
20
|
+
|
21
|
+
# ========================================================================= #
|
22
|
+
# === TOKEN_TO_SPLIT_AT
|
23
|
+
# ========================================================================= #
|
24
|
+
TOKEN_TO_SPLIT_AT = '->'
|
25
|
+
|
26
|
+
# ========================================================================= #
|
27
|
+
# === initialize
|
28
|
+
# ========================================================================= #
|
29
|
+
def initialize(
|
30
|
+
i = nil,
|
31
|
+
run_already = true
|
32
|
+
)
|
33
|
+
reset
|
34
|
+
set_input(i)
|
35
|
+
run if run_already
|
36
|
+
end
|
37
|
+
|
38
|
+
# ========================================================================= #
|
39
|
+
# === reset
|
40
|
+
# ========================================================================= #
|
41
|
+
def reset # (reset tag)
|
42
|
+
@token_to_split_at = TOKEN_TO_SPLIT_AT
|
43
|
+
end
|
44
|
+
|
45
|
+
# ========================================================================= #
|
46
|
+
# === set_input
|
47
|
+
# ========================================================================= #
|
48
|
+
def set_input(i = '')
|
49
|
+
i = i.first if i.is_a? Array
|
50
|
+
i = THIS_FORMULA if i.nil?
|
51
|
+
i = i.to_s.dup
|
52
|
+
i.strip!
|
53
|
+
# ======================================================================= #
|
54
|
+
# Next, we will get rid of all ' '.
|
55
|
+
# ======================================================================= #
|
56
|
+
i.tr!(' ','')
|
57
|
+
@input = i
|
58
|
+
end
|
59
|
+
|
60
|
+
# ========================================================================= #
|
61
|
+
# === left?
|
62
|
+
# ========================================================================= #
|
63
|
+
def left?
|
64
|
+
@left_hand_side
|
65
|
+
end
|
66
|
+
|
67
|
+
# ========================================================================= #
|
68
|
+
# === right?
|
69
|
+
# ========================================================================= #
|
70
|
+
def right?
|
71
|
+
@right_hand_side
|
72
|
+
end
|
73
|
+
|
74
|
+
# ========================================================================= #
|
75
|
+
# === ensure_that_the_token_is_correct
|
76
|
+
# ========================================================================= #
|
77
|
+
def ensure_that_the_token_is_correct
|
78
|
+
if @input.include? '=' # In this case we overrule the token.
|
79
|
+
@token_to_split_at = '='
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# ========================================================================= #
|
84
|
+
# === split_into_components
|
85
|
+
# ========================================================================= #
|
86
|
+
def split_into_components
|
87
|
+
@left_hand_side, @right_hand_side = @input.
|
88
|
+
split(@token_to_split_at).map(&:strip)
|
89
|
+
# ======================================================================= #
|
90
|
+
# Ok, we now have our left side, and we have our right side.
|
91
|
+
# We will next get the total content of Elements at the left
|
92
|
+
# and at the right side.
|
93
|
+
# ======================================================================= #
|
94
|
+
p SplitMoleculeNames.new left?
|
95
|
+
p SplitMoleculeNames.new right?
|
96
|
+
if are_both_sides_equal?
|
97
|
+
opn; e 'Both sides are now equal.'
|
98
|
+
else
|
99
|
+
opn; e 'Both sides are not equal.'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# ========================================================================= #
|
104
|
+
# === are_both_sides_equal?
|
105
|
+
# ========================================================================= #
|
106
|
+
def are_both_sides_equal?
|
107
|
+
result = false
|
108
|
+
# ======================================================================= #
|
109
|
+
# We have to eliminate the '+' characters.
|
110
|
+
# ======================================================================= #
|
111
|
+
left = SplitMoleculeNames.new(left?.delete('+')).total?
|
112
|
+
right = SplitMoleculeNames.new(right?.delete('+')).total?
|
113
|
+
result = ( left == right )
|
114
|
+
return result
|
115
|
+
end
|
116
|
+
|
117
|
+
# ========================================================================= #
|
118
|
+
# === run
|
119
|
+
# ========================================================================= #
|
120
|
+
def run # (run tag)
|
121
|
+
ensure_that_the_token_is_correct
|
122
|
+
split_into_components
|
123
|
+
end
|
124
|
+
|
125
|
+
end; end
|
126
|
+
|
127
|
+
if __FILE__ == $PROGRAM_NAME
|
128
|
+
ChemistryParadise::EquationSolver.new(ARGV)
|
129
|
+
end # equation_solver
|
130
|
+
# equation_solver '2 Fe + 3 Cl2 = FeCl3'
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# Encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
# =========================================================================== #
|
5
|
+
# === ChemistryParadise::InteractiveChemistryShell
|
6
|
+
#
|
7
|
+
# Usage examples:
|
8
|
+
# ChemistryParadise::InteractiveChemistryShell.new
|
9
|
+
# =========================================================================== #
|
10
|
+
require 'chemistry_paradise/base/base.rb'
|
11
|
+
require 'chemistry_paradise/calculate_atomic_mass.rb'
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'readline'
|
15
|
+
rescue LoadError; end
|
16
|
+
|
17
|
+
module ChemistryParadise
|
18
|
+
|
19
|
+
class InteractiveChemistryShell < Base # require 'chemistry/interactive_chemistry_shell'; InteractiveChemistryShell.new
|
20
|
+
|
21
|
+
# ========================================================================= #
|
22
|
+
# === PROMPT
|
23
|
+
# ========================================================================= #
|
24
|
+
PROMPT = '> '
|
25
|
+
if File.exist? Shared.periodic_table?
|
26
|
+
PERIODIC_TABLE = YAML.load_file(Shared.periodic_table?)
|
27
|
+
else
|
28
|
+
PERIODIC_TABLE = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# ========================================================================= #
|
32
|
+
# === initialize
|
33
|
+
# ========================================================================= #
|
34
|
+
def initialize(run_already = true)
|
35
|
+
reset
|
36
|
+
run if run_already
|
37
|
+
end
|
38
|
+
|
39
|
+
# ========================================================================= #
|
40
|
+
# === reset
|
41
|
+
# ========================================================================= #
|
42
|
+
def reset
|
43
|
+
@lpad = ' '
|
44
|
+
end
|
45
|
+
|
46
|
+
# ========================================================================= #
|
47
|
+
# === show_welcome_message
|
48
|
+
# ========================================================================= #
|
49
|
+
def show_welcome_message
|
50
|
+
e 'Welcome to the InteractiveChemistryShell.'
|
51
|
+
e 'Input "help" to get a list of options, otherwise'
|
52
|
+
e 'just type in your input now.'
|
53
|
+
print PROMPT
|
54
|
+
end
|
55
|
+
|
56
|
+
# ========================================================================= #
|
57
|
+
# === report_input
|
58
|
+
# ========================================================================= #
|
59
|
+
def report_input(i)
|
60
|
+
ewarn 'Input was: `'+sfancy(i)+'`'
|
61
|
+
end
|
62
|
+
|
63
|
+
# ========================================================================= #
|
64
|
+
# === show_welcome_message_and_help
|
65
|
+
# ========================================================================= #
|
66
|
+
def show_welcome_message_and_help
|
67
|
+
show_welcome_message
|
68
|
+
show_help
|
69
|
+
end
|
70
|
+
|
71
|
+
# ========================================================================= #
|
72
|
+
# === calculate
|
73
|
+
#
|
74
|
+
# To test this, do:
|
75
|
+
# calc C3H5
|
76
|
+
# ========================================================================= #
|
77
|
+
def calculate(i)
|
78
|
+
if i.nil?
|
79
|
+
e 'Please provide proper input to this method now, for instance, `C12H12N2`:'
|
80
|
+
i = $stdin.gets.chomp
|
81
|
+
end
|
82
|
+
CalculateAtomicMass.new(i)
|
83
|
+
end; alias calc calculate # === calc
|
84
|
+
|
85
|
+
# ========================================================================= #
|
86
|
+
# === check_against_menu
|
87
|
+
# ========================================================================= #
|
88
|
+
def check_against_menu
|
89
|
+
_ = @user_input # We can use this now.
|
90
|
+
arguments = nil # Default to denote that we have no arguments.
|
91
|
+
if _.include? ' '
|
92
|
+
splitted = _.split(' ')
|
93
|
+
_ = splitted[0] # Reassign here to the first entry.
|
94
|
+
arguments = splitted[1..-1]
|
95
|
+
end
|
96
|
+
case _ # case tag
|
97
|
+
# ======================================================================= #
|
98
|
+
# === quit
|
99
|
+
# ======================================================================= #
|
100
|
+
when 'quit','exit','q'
|
101
|
+
e 'Bye from the InteractiveChemistryShell.'
|
102
|
+
exit
|
103
|
+
# ======================================================================= #
|
104
|
+
# === show_electron_negativity_chart
|
105
|
+
# ======================================================================= #
|
106
|
+
when '4','show_electron_negativity_chart'
|
107
|
+
ChemistryParadise.show_electron_negativity_chart
|
108
|
+
# ======================================================================= #
|
109
|
+
# === periodic_table?
|
110
|
+
# ======================================================================= #
|
111
|
+
when '3','periodic_table?','show_periodic_table','top','top?',
|
112
|
+
'periodic?','periodic','showperiodictable'
|
113
|
+
show_periodic_table
|
114
|
+
# ======================================================================= #
|
115
|
+
# === help
|
116
|
+
# ======================================================================= #
|
117
|
+
when /-?-?help/,'hel','he','h','?'
|
118
|
+
show_help
|
119
|
+
when '1','calc','calculate'
|
120
|
+
calculate(arguments)
|
121
|
+
when '2','show'
|
122
|
+
e 'Input your element symbol now:'
|
123
|
+
element_symbol = $stdin.gets.chomp
|
124
|
+
ShowElectronConfiguration.new(element_symbol)
|
125
|
+
when '' # pass through
|
126
|
+
else
|
127
|
+
# To test the following, try:
|
128
|
+
# 454 g NH4NO3
|
129
|
+
if @user_input.include?('g') and @user_input =~ /\d+/
|
130
|
+
splitted = @user_input.strip.split('g').map(&:strip)
|
131
|
+
atomic_mass = ChemistryParadise::CalculateAtomicMass[splitted.last].to_f
|
132
|
+
n_times = splitted.first.strip.to_i
|
133
|
+
mass = n_times / atomic_mass
|
134
|
+
e (mass.round(2)).to_s+' mol'
|
135
|
+
else
|
136
|
+
report_input(_)
|
137
|
+
show_help
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# ========================================================================= #
|
143
|
+
# === ecomment
|
144
|
+
# ========================================================================= #
|
145
|
+
def ecomment(i)
|
146
|
+
Colours.ecomment(i)
|
147
|
+
end
|
148
|
+
|
149
|
+
# ========================================================================= #
|
150
|
+
# === run_loop
|
151
|
+
# ========================================================================= #
|
152
|
+
def run_loop
|
153
|
+
loop {
|
154
|
+
fetch_user_input # Get user input first.
|
155
|
+
check_against_menu
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
# ========================================================================= #
|
160
|
+
# === run (run tag)
|
161
|
+
# ========================================================================= #
|
162
|
+
def run
|
163
|
+
show_welcome_message_and_help # Show the help section on startup.
|
164
|
+
run_loop
|
165
|
+
end
|
166
|
+
|
167
|
+
# ========================================================================= #
|
168
|
+
# === show_help
|
169
|
+
# ========================================================================= #
|
170
|
+
def show_help # help tag
|
171
|
+
e 'Available options:'
|
172
|
+
e
|
173
|
+
# ======================================================================= #
|
174
|
+
# Add more documented help-options to this Array here.
|
175
|
+
# ======================================================================= #
|
176
|
+
array = [
|
177
|
+
'calculate the atomic mass',
|
178
|
+
'show the electron configuration of an Element',
|
179
|
+
'show the periodic table',
|
180
|
+
'show electron negativity chart'
|
181
|
+
]
|
182
|
+
array.each_with_index {|entry, index|
|
183
|
+
index += 1
|
184
|
+
ecomment @lpad+index.to_s+' # '+entry
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
# ========================================================================= #
|
189
|
+
# === has_readline?
|
190
|
+
# ========================================================================= #
|
191
|
+
def has_readline?
|
192
|
+
Object.const_defined? :Readline
|
193
|
+
end
|
194
|
+
|
195
|
+
# ========================================================================= #
|
196
|
+
# === fetch_user_input
|
197
|
+
# ========================================================================= #
|
198
|
+
def fetch_user_input
|
199
|
+
if has_readline?
|
200
|
+
@user_input = Readline.readline('', true)
|
201
|
+
else
|
202
|
+
@user_input = $stdin.gets.chomp
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# ========================================================================= #
|
207
|
+
# === show_periodic_table
|
208
|
+
# ========================================================================= #
|
209
|
+
def show_periodic_table
|
210
|
+
e # Add a newline.
|
211
|
+
inverted = PERIODIC_TABLE.invert
|
212
|
+
1.upto(7).each {|periode|
|
213
|
+
range = return_range_for_this_period(periode)
|
214
|
+
# ===================================================================== #
|
215
|
+
# Now we have a proper range.
|
216
|
+
# ===================================================================== #
|
217
|
+
matches = inverted.select {|index_position, value|
|
218
|
+
range.include? index_position
|
219
|
+
}
|
220
|
+
ee colourize_via_kde_konsole(periode.to_s)+': ' # Display the periode here.
|
221
|
+
matches.each_pair {|key, value|
|
222
|
+
ee simp(value)+' ('+key.to_s+') '
|
223
|
+
}; e
|
224
|
+
}
|
225
|
+
end
|
226
|
+
|
227
|
+
# ========================================================================= #
|
228
|
+
# === colourize_via_kde_konsole
|
229
|
+
# ========================================================================= #
|
230
|
+
def colourize_via_kde_konsole(i)
|
231
|
+
if Object.const_defined? :Colours
|
232
|
+
i = ::Colours.lightgreen(i)
|
233
|
+
end
|
234
|
+
i
|
235
|
+
end
|
236
|
+
|
237
|
+
end; end
|
238
|
+
|
239
|
+
if __FILE__ == $PROGRAM_NAME
|
240
|
+
ChemistryParadise::InteractiveChemistryShell.new
|
241
|
+
end # ichem
|