Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: subroutine help

by space_monk (Chaplain)
on Nov 29, 2012 at 07:37 UTC ( #1006179=note: print w/ replies, xml ) Need Help??


in reply to subroutine help

I'm sure it's been done before in the other answers, and maybe even more efficiently, but this is what I think you're trying to get to:

#!/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:

Adding C (12)* 12 Adding H (1.008)* 22 Adding O (16)* 11 Molecule: C12 H22 O11 Weight of C12 H22 O11 : 342.176
Updated to reflect the fact that some transuranic elements have 3 letter identifiers, not just two. :-)

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....

A Monk aims to give answers to those who have none, and to learn from those who know more.


Comment on Re: subroutine help
Select or Download Code
Replies are listed 'Best First'.
Re^2: subroutine help
by tobyink (Abbot) on Nov 29, 2012 at 09:05 UTC

    A few evil examples:

    • Ca(OH)2
    • CH3CH2CH2CH2CH2CH2CH3
    • CH3[CH2]5CH3
    • CH3[CH2]nCH3 - not really calculable, but should be parsable
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      Yes, alright my solution is lightweight, only getting the second of your examples right, lets use Chemistry::Mol to get it right properly :-)
      A Monk aims to give answers to those who have none, and to learn from those who know more.
Re^2: subroutine help
by Kenosis (Priest) on Nov 29, 2012 at 08:22 UTC

    Consider the following minor modifications:

    'Co' => 58.933195 my @array = $form =~ /[A-Z][a-z]*\d*/g; if ($element =~ /([A-Z][a-z]*)(\d*)/) { my $mult = $2 || 1; $weight += ($eweight*$mult); print STDERR "Adding $1 ($eweight)* $mult\n";

    Run on CoCO2:

    Adding Co (58.933195)* 1 Adding C (12)* 1 Adding O (16)* 2 Molecule: Co C O2 Weight of Co C O2 : 102.933195
Re^2: subroutine help
by frozenwithjoy (Curate) on Nov 29, 2012 at 07:51 UTC
    Don't forget your units: g/mol! :P
      Its 30 years since I did Chemistry 'A' Level....be grateful I remembered this much. :-)
      A Monk aims to give answers to those who have none, and to learn from those who know more.
        I was impressed with (and had to google) 'transuranic elements'! (And I was teasing, of course.)
Re^2: subroutine help
by perlguru22 (Acolyte) on Nov 29, 2012 at 08:10 UTC
    Thank you so much this actually explains a lot I was heading the wrong way thanks =)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1006179]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2015-07-31 03:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (274 votes), past polls