Namn:Henrik H 1.0079 E finns inte N 14.0067 R finns inte I 126.9054 K 39.098 Din totala atomvikt är 181.018Sedan ska programmet läsa in molekylformler och kolla att dom är syntaktiskt korrekta. I terminalfönstret ställs frågorna, t ex
Molekyl: Si(C3(COOH)2)4(H2O)7 Formeln är syntaktiskt korrekt Molekyl: Ag7(FyOj6)17 Okänt atomnamn Fy vid radslutet Oj6)17 Molekyl: H1SO4 För litet tal vid radslutet SO4 Molekyl: Ca(OH)NO3 Saknad siffra vid radslutet NO3 Molekyl: Na(OH Saknad högerparentes vid radslutet Molekyl: Nacl Saknad stor bokstav vid radslutet clNär användaren trycker retur utan att ha skrivit någon formel ska slingan brytas och programmet avslutas.
Ag 107.868Du ska läsa in filen i en hashtabell
atomlist
med atombeteckningen
som nyckel och atomvikten som värde, alltså enligt principen
atomlist["Ag"]="107.868"Några tips för personkemiuppgiften:
namn.upper()
för att få stora bokstäver.
atomlist.has_key()
om atomnamnet finns.
float(vikt)
gör om dom till tal att räkna med.
<formel>::= <mol> \n <mol> ::= <group> | <group><mol> <group> ::= <atom> |<atom><num> | (<mol>) <num> <atom> ::= <LETTER> | <LETTER><letter> <LETTER>::= A | B | C | ... | Z <letter>::= a | b | c | ... | z <num> ::= 2 | 3 | 4 | ...Ditt program ska läsa formeln tecken för tecken och med rekursiv medåkning kolla syntaxen. Eftersom det är lättast att läsa hela raden får du göra det och sedan lägga in alla tecken i en kö. Avsluta med returtecknet, så här.
rad=raw_input("Molekyl:) for tkn in rad: q.put(tkn) q.put("\n")Rekursiv medåkning innebär att huvudprogrammet gör anropet
readformel()
, att readformel()
anropar
readmol()
som anropar
readgroup()
och sedan eventuellt sej själv,
att readgroup()
antingen anropar readatom()
eller läser en parentes och anropar readmol()
etc -
allt enligt grammatiken. När ett syntaxbrott upptäcks genereras
ett särfall (raise Exception,msg
) som fångas i
huvudprogrammet och där skrivs hela resten av kön ut.
Man måste ofta tjuvtitta på nästa tecken
för att veta vilken gren man ska följa i syntaxträdet och därför bör du
i klassen Queue
lägga till metoden peek()
som returnerar
första värdet men låter kön vara oförändrad.
Molekylvikten kan din formelkoll samtidigt räkna ut om du låter alla metoder returnera ett tal, nämligen så här
readatom
returnerar en atomvikt med hjälp av hashtabellen
readnum
returnerar ett heltal
readgroup
returnerar vikten av en molekylgrupp, t ex Na eller (OH)2
readmol
returnerar vikten av en delmolekyl
readformel
returnerar hela molekylvikten
Molekyl:Si(C3(COOH)2)4(H2O)7 Formeln är syntaktiskt korrekt Molekylvikt: 658.466
Skriv din egen hashmodul
och använd den i stället för pythons
inbyggda dictionary. I ditt huvudprogram har du
from hash import Hash
och i hashmodulen ska följande finnas.
hash(key,n)
är en funktion som ur key
skapar ett
index mindre än n
. Funktionen kan ligga utanför hashklassen.
__init__(self,n)
i class Hash
tillverkar en
tabell av längd n och fyller den med None.
put(self,key,info)
hashar key till ett index i tabellen,
tillverkar en nod med key och info i och lägger den på detta index.
Noden har en nextpekare för det fall att olika key hashar till samma
index.
get(self,key)
hashar key till ett tabellindex, söker igenom
nodlistan efter rätt key och returnerar info. Om inte key finns
görs raise Exception
class Node
innehåller key
, info
och
next
.
has_key
så huvudprogrammet måste ha
try: - - - except Exception: - - -