CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Regular Expressions:
trying to input chemical element and get back weight

 



yatinhat
Novice

Nov 4, 2004, 12:01 AM

Post #1 of 9 (6545 views)
trying to input chemical element and get back weight Can't Post

I am trying to do a program whereby the user inputs a chemical abbreviation, and gets the atomic weight back. I am learning and teaching myself perl. Any input apreciated.
_________________________________________

#!/usr/bin/perl

use strict;
use warnings;

print "Enter a chemical element abbreviation, or type quit";
my $line = <STDIN>;
chomp ($line);
my @Formula;
my ($weight, $string, $moleweight);

while ($line = <>)
{
chomp($line)
@Fields = split /, /, $line;

$weights {$symbol} = $weight;

$string = CO2;

@Formula = $string =~ /[A-Z][a-z]? | \d+ /g;

$moleweight = getweight (@Formula);


sub getweight
{my @Form = @_;
return $weight;
}


davorg
Thaumaturge / Moderator

Nov 4, 2004, 2:24 AM

Post #2 of 9 (6543 views)
Re: [yatinhat] trying to input chemical element and get back weight [In reply to] Can't Post

Can you give examples of the input you're expecting, the results you want and how you calculate the results.

Bear in mind that it's a long time since some of us studied any chemistry.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


yatinhat
Novice

Nov 4, 2004, 9:38 AM

Post #3 of 9 (6540 views)
Re: [yatinhat] trying to input chemical element and get back weight [In reply to] Can't Post

Periodic table elements are entered by the usr and are expected, to start with an upper case letter followed by zero or more lower case letters or numbers.

Here is what the data file looks like:

Actinium,Ac,227.00
Aluminium,Al,26.98
Americium,Am,243.00
Antimony,Sb,121.76
Argon,Ar,39.95
Arsenic,As,74.92
Astatine,At,210.00
Barium,Ba,137.33
Berkelium,Bk,247.00
Beryllium,Be,9.01
Bismuth,Bi,208.98
Bohrium,Bh,264.00
Boron,B,10.81
Bromine,Br,79.90
Cadmium,Cd,112.41
Caesium,Cs,132.91
Calcium,Ca,40.08
Californium,Cf,251.00
Carbon,C,12.01
Cerium,Ce,140.12
Chlorine,Cl,35.45
Chromium,Cr,51.99
Cobalt,Co,58.93
Copper,Cu,63.55
Curium,Cm,247.00
Dubnium,Db,262.00
Dysprosium,Dy,162.50
Einsteinium,Es,252.00
Erbium,Er,167.26
Europium,Eu,151.96
Fermium,Fm,257.00
Fluorine,F,18.99
Francium,Fr,223.00
Gadolinium,Gd,157.25
Gallium,Ga,69.72
Germanium,Ge,72.61
Gold,Au,196.97
Hafnium,Hf,178.49
Hassium,Hs,256.00
Helium,He,4.00
Holmium,Ho,164.93
Hydrogen,H,1.01
Indium,In,114.82
Iodine,I,126.90
Iridium,Ir,192.22
Iron,Fe,55.85
Krypton,Kr,83.80
Lanthanum,La,138.91
Lawrencium,Lr,262.00
Lead,Pb,207.20
Lithium,Li,6.94
Lutetium,Lu,174.97
Magnesium,Mg,24.31
Manganese,Mn,54.94
Meitnerium,Mt,268.00
Mendelevium,Md,258.00
Mercury,Hg,200.59
Molybdenum,Mo,95.94
Neodymium,Nd,144.24
Neon,Ne,20.18
Neptunium,Np,237.00
Nickel,Ni,58.69
Niobium,Nb,92.91
Nitrogen,N,14.01
Nobelium,No,259.00
Osmium,Os,190.23
Oxygen,O,15.99
Palladium,Pd,106.42
Phosphorus,P,30.98
Platinum,Pt,195.08
Plutonium,Pu,244.00
Polonium,Po,209.00
Potassium,K,39.09
Praseodymium,Pr,140.91
Promethium,Pm,145.00
Protactinium,Pa,231.04
Radium,Ra,226.00
Radon,Rn,222.00
Rhenium,Re,186.21
Rhodium,Rh,102.91
Rubidium,Rb,85.47
Ruthenium,Ru,101.07
Rutherfordium,Rf,261.00
Samarium,Sm,150.36
Scandium,Sc,44.96
Seaborgium,Sg,263.00
Selenium,Se,78.96
Silicon,Si,28.09
Silver,Ag,107.87
Sodium,Na,22.99
Strontium,Sr,87.62
Sulfur,S,32.07
Tantalum,Ta,180.95
Technetium,Tc,98.00
Tellurium,Te,127.60
Terbium,Tb,158.93
Thallium,Tl,204.38
Thorium,Th,232.04
Thulium,Tm,168.93
Tin,Sn,118.71
Titanium,Ti,47.87
Tungsten,W,183.84
Uranium,U,238.03
Vanadium,V,50.94
Xenon,Xe,131.29
Ytterbium,Yb,173.04
Yttrium,Y,88.91
Zinc,Zn,65.39
Zirconium,Zr,91.22


davorg
Thaumaturge / Moderator

Nov 5, 2004, 1:36 AM

Post #4 of 9 (6516 views)
Re: [yatinhat] trying to input chemical element and get back weight [In reply to] Can't Post

I said "Can you give examples of the input you're expecting, the results you want and how you calculate the results" and you don't seem to have addressed that at all :)

Here's the kind of explaination that I expecting to see (trying to remember the chemistry I studied 25 years ago).

User inputs a chemical formula, e.g. H20.

This is split into elements and numbers, e.g. H, 2, 0. An element name is a capital letter followed by an optional lower case letter. An optional integer follows each element name. A missing integer is assumed to be 1.

A molecule's weight is then calculated by looking up the weights of the individual elements in the attached table, multiplying by the integer from the formula and summing all these weights.

For example in H20, the weight of oxygen (O) is 15.99 and the weight of hydrogen (H) is 1.01. The total weight is therefore 2 * 1.01 + 15.99 = 18.01.

Does that accurately reflect your requirements?

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


ShipOfFools
Novice

Nov 5, 2004, 6:35 AM

Post #5 of 9 (6510 views)
Re: [yatinhat] trying to input chemical element and get back weight [In reply to] Can't Post

Assuming all the records in the file are unique constants, and the file will only be updated when new elements are discovered, wouldn't it be better to place the data in memory along with your program? Then you wouldn't have to open/lock/read/search/close the file from disk. You can just jump straight to it using the user input.


Code
 my %chemElements = qw( Cobalt 58.93 Co 58.93 Copper 63.55 Cu 63.55 Curium 247 Cm 247 ); 
print "$chemElements{$ARGV[0]}\n";



where $ARGV[0] is a chemical name or symbol.

Otherwise if your file will be modified in such a way to make the size unacceptable to memory, you could do something like this...


Code
my $file = 'PATH\TO\data.txt';  

open FILE, "$file" or die "Can't open file for read. $!\n";
flock FILE, 1;
while( <FILE> )
{
my @members = split ',';
if( $members[0] eq $ARGV[0] || $members[1] eq $ARGV[0] )
{
print "$members[2]\n";
last;
}
}
close FILE;



Dave


yatinhat
Novice

Nov 5, 2004, 8:02 AM

Post #6 of 9 (6504 views)
Re: [davorg] trying to input chemical element and get back weight [In reply to] Can't Post

Yes, that accurately describes my programs requirements. I studied chemistry in high school.

I have discovered OptiPerl program and downloaded the free trial. Is this a good program for novices?

Thanks,
Mary


davorg
Thaumaturge / Moderator

Nov 5, 2004, 9:01 AM

Post #7 of 9 (6498 views)
Re: [yatinhat] trying to input chemical element and get back weight [In reply to] Can't Post

My solution is listed below. Assuming it's in a file called "chem", you run it like this:

Code
$ ./chem H2O 
H2O = 18.01
$ ./chem H2O H2SO4
H2O = 18.01
H2SO4 = 98.05
$ ./chem H2O H2SO4 HCl
H2O = 18.01
H2SO4 = 98.05
HCl = 36.46

I've never heard of OptiPerl so I can't say how good it is.

My program...

Code
#!/usr/bin/perl 

use strict;
use warnings;

my %chem;
while (<DATA>) {
chomp;
my ($n, $s, $w) = split /,/;
$chem{$s} = $w;
}

foreach (@ARGV) {
my $weight = 0;
my @parts = /([A-Z][a-z]?)(\d*)/g;

while (my ($elem, $num) = splice @parts, 0, 2) {
next unless $chem{$elem};
$num ||= 1;

$weight += $chem{$elem} * $num;
}
print "$_ = $weight\n";
}

__END__
Actinium,Ac,227.00
Aluminium,Al,26.98
Americium,Am,243.00
Antimony,Sb,121.76
Argon,Ar,39.95
Arsenic,As,74.92
Astatine,At,210.00
Barium,Ba,137.33
Berkelium,Bk,247.00
Beryllium,Be,9.01
Bismuth,Bi,208.98
Bohrium,Bh,264.00
Boron,B,10.81
Bromine,Br,79.90
...etc...


--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


yatinhat
Novice

Nov 8, 2004, 10:48 AM

Post #8 of 9 (6479 views)
Re: [yatinhat] trying to input chemical element and get back weight [In reply to] Can't Post

Thank you so much for your help and feedback. I am a novice Perl Programmer.

I find this block of code confusing...

while (my ($elem, $num) = splice @parts, 0, 2) {
next unless $chem{$elem};
$num ||= 1;


davorg
Thaumaturge / Moderator

Nov 9, 2004, 1:36 AM

Post #9 of 9 (6469 views)
Re: [yatinhat] trying to input chemical element and get back weight [In reply to] Can't Post


In Reply To
I find this block of code confusing...

Code
while (my ($elem, $num) = splice @parts, 0, 2) {


This uses the "splice" function to pull elements from @parts two at a time. You can read the docs for splice by typing "perldoc -f splice" at your command line.


In Reply To

Code
next unless $chem{$elem};


$elem contains the next chemical element from the formula. %chem contains a table of elements togther with their atomic weight. If $elem isn't found as a key in %chem then it's not a real chemical element and we ignore it. We use "next" to skip to the next iteration of the innermost loop.


In Reply To

Code
$num ||= 1;


If the chemical symbol didn't have an integer after it then we need to treat it as 1. If the integer is missing then $num will contain the special value "undef" which evaluates as false. This code basically says that if $num doesn't contain a value(*) then set it to 1.

(*) To be picky, it actually says, if $num doesn't contain a _true_ value - so if $num contains a zero, it will also be set to 1. But I think that's probably the correct behaviour in this case.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives