#!/bin/perl #if your program doesn't begin with this, you deserve to fail... use strict; # Data::Dumper not used in example, # but you always need it when you expand the module :-) use Data::Dumper; # you can either hardcode all atomic weights in ... # ..or read them from a data file/ database my %weights = ( 'C' => 12.0, 'O' => 16.0, 'Co' => 58.933195, 'H' => 1.008 ); my @test = ( 'C12H22O11' ); for my $form (@test) { my @array = $form =~ /[A-Z][a-z]*\d*/ig; my $weight = getweight(@array); print "Weight of @array : $weight\n"; } sub getweight { my @atoms =@_; my $weight = 0.0; for my $element (@atoms) { if ($element =~ /([A-Z][a-z]*)(\d*)/) { my $eweight = $weights{$1}; my $mult = $2 || 1; $weight += ($eweight*$mult); print STDERR "Adding $1 ($eweight)* $mult\n"; } } print STDERR "Molecule: @atoms\n"; return $weight; }
Feel free to modify for your purposes and correct naming,read atomic weights from a file etc.
Output from above program:
Updated to reflect the fact that some transuranic elements have 3 letter identifiers, not just two. :-)Adding C (12)* 12 Adding H (1.008)* 22 Adding O (16)* 11 Molecule: C12 H22 O11 Weight of C12 H22 O11 : 342.176
Also updated to reflect suggestions by Kenosis and others below....
Whilst adequate for the indicated input, the method of parsing and atomic weight calculation is a little lightweight and basic, and doesn't handle more complex molecules, so consider using Chemistry::Mol or a similar package if you want to get round the flaws that have been indicated below....
In reply to Re: subroutine help
by space_monk
in thread subroutine help
by perlguru22
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |