lib/eulim/chemistry/compound.rb in eulim-0.0.6 vs lib/eulim/chemistry/compound.rb in eulim-0.0.7

- old
+ new

@@ -1,65 +1,53 @@ module Eulim::Chemistry class Compound VALID_COMPOUND_REGEXP = /[A-Z][a-z]{0,2}\d*|\((?:[^()]*(?:\(.*\))?[^()]*)+\)\d*/ - VAILD_ELEMENT_REGEXP = /[A-Z][a-z]{0,2}\d*/ + attr_accessor :molecular_mass, :constituents, :formula + def initialize(arg) @formula = arg + @constituents = get_constituents + @molecular_mass = get_molecular_mass end - def molecular_mass - mass = 0 - element_atom_count = get_element_atom_count - element_atom_count.each do |symbol, count| - mass += Element.get_by_symbol(symbol).atomic_mass * count + private + def get_molecular_mass + mass = 0 + @constituents.each do |constituent| + mass += constituent[:element].atomic_mass * constituent[:atom_count] + end + mass end - mass - end - def elements - elements = [] - element_atom_count = get_element_atom_count - element_atom_count.each do |symbol, count| - elements << Element.get_by_symbol(symbol) + def get_constituents + constituents = [] + get_constituent_atoms.each do |symbol, count| + constituents << {element: Element.get_by_symbol(symbol), atom_count: count} + end + constituents end - elements - end - private - def get_element_atom_count formula = @formula, group_multiplier = 1, result = {}, groups = [] - formula - elements_n_groups = formula.scan VALID_COMPOUND_REGEXP - loop do - break if !elements_n_groups.last - elements = elements_n_groups.last.scan VAILD_ELEMENT_REGEXP - if elements.first === elements_n_groups.last - element_multipler = elements.first.match(/\d*$/).to_a.first.to_i - element_multipler = element_multipler > 0 ? element_multipler : 1 - element_symbol = elements.first.match(/[A-Z][a-z]{0,2}/).to_a.first - if result[element_symbol] - result[element_symbol] += (element_multipler * group_multiplier) - else - result[element_symbol] = (element_multipler * group_multiplier) - end + def get_constituent_atoms formula=@formula, result={} + constituents = formula.scan VALID_COMPOUND_REGEXP + constituents.each do |constituent| + multipler = get_multipler constituent + if constituent[0] != '(' && multipler == 0 + result[constituent] = result[constituent] ? result[constituent] + 1 : 1 else - groups << elements_n_groups.last - end - elements_n_groups.pop + (multipler == 0 ? 1 : multipler).times do + sub_constituents = constituent.match(/^\(?(.*?)\)?($|\d*$)/).to_a + idx = constituent == sub_constituents.first ? 1 : 0 + get_constituent_atoms sub_constituents[idx], result + end + end end - loop do - break if !groups.last - group = groups.pop - grml = get_group_multiplier(group) - get_element_atom_count group[1..-(grml.to_s.length+1)], grml*group_multiplier, result, groups - end result end - def get_group_multiplier formula - group_multiplier = formula.scan(VALID_COMPOUND_REGEXP).first.match(/\d*$/).to_a.first.to_i - group_multiplier > 0 ? group_multiplier : 1 + def get_multipler constituent + multipler = constituent.match(/\d*$/).to_a.first.to_i end end end