Laboration 7

Laboration 7 - Molekylgrafik

Det här programmet ska fullborda det som den föregående labben har påbörjat. Det gör formelkoll som tidigare och ritar sedan upp molekylen. På skärmen kan det se ut så här (användarens inmatning i fetstil):

   Molekyl: Si(C3(COOH)2)4(H2O)7
   Molekyl:

och i molekylfönstret ritar programmet ut formelstrukturen: molekylträd

Förberedelse: Rita syntaxträd

Plocka fram syntaxen i labb 6, och rita med hjälp av den upp syntaxträd för följande molekyler:

O
CO2
(CH3)2(CH2)4

Låt ditt program bygga ett molekylträd

Du ska komplettera formelkollsprogrammet till att samtidigt bygga ett träd som ser ut som ovan. Varje ruta motsvaras av ett objekt:

class Ruta:
    def __init__(self, atom="( )", num=1):
        self.atom = atom
        self.num = num
        self.next = None
        self.down = None

Funktionen readgroup skapar först en sådan tomruta med

   rutan = Ruta() 

och anropar readatom och readnum för att kunna sätta in rätt värden på atom och num. Om det är en parentesgrupp ska readgroups anrop till readmol returnera en delmolekyl som sätts under rutan.down.

När readgroup är klar returnerar den rutan till anropet

    mol = readgroup()

som görs allra först i readmol. Vad som ska göras med mol.next får du själv tänka ut. Slutligen returnerar readmol den färdiga strukturen till readformel som returnerar den till huvudprogrammets anrop

    mol = readformel()

där mol pekar högst upp till vänster på syntaxträdet.

Rita molekylträdet

Huvudprogrammet ska nu rita upp den färdiga molekylen. Använd molgrafik.py från labb 5. Skapa ett objekt av den klassen:

   mg = molgrafik()

Sedan ska

   mg.show(mol)

rita upp molekylbilden i ett eget fönster. Bilden ritas förstås rekursivt, och du ska formulera den rekursiva tanke som används. Om du inte kommer på den själv kanske det hjälper att kolla molgrafikkoden. Om programmet avslutas direkt hinner man inte se grafiken blinka förbi. Se därför till att ha en slinga för inmatning av flera formler.

Molekylvikten

Molekylvikten ska beräknas rekursivt med anropet weight(mol). Formulera först en mycket rekursiv tanke för vikten och programmera den sedan! Låt programmet skriva ut vikten av molekylen i terminalfönstret.

betyg E: Du ska ha löst uppgifterna ovan, och kunna

  • Rita hur trädet byggs upp av funktionsanropen.
  • Visa med ett exempel hur funktionen weight() beräknar molekylvikten.
  • Förklara hur ditt anrop till molgrafikens show() fungerar (men du behöver inte kunna förklara hur Tkinter fungerar).

betyg C: Kraven för E uppfyllda +

  •  Labben inlämnad via KTH Social i tid ch redovisad i tid (se datum under Laborationer).

betyg A: Kraven för C uppfyllda +

  • Modifiera molgrafiken så att vikten skrivs ut i samma fönster.

Gratulerar till avklarad labbkurs! Glöm inte att fylla i kursenkäten

Tryck här för att hämta kursenkäten:

Alexander Baltatzis skapade sidan 14 januari 2014

kommenterade 12 mars 2014

Hörde ett rykte om att denna kanske skulle strykas.

Vore bra om ni gav besked om den gör det eller ej snart, innan jag börjar jobba på den.

Lärare kommenterade 13 mars 2014

Vi har inga planer på att stryka denna labb. 

kommenterade 4 april 2014

@Linda

Hej,
när jag stänger ner grafiken i molgrafik får jag ett felmeddelande typ "cant invoke "destroy" command". Eftersom grafiken är mer eller mindre färdigprogrammerad, är att fixa detta utanför labben eller bör det fixas för att bli godkänd?

Mvh
Stefan

kommenterade 4 april 2014

Hej

Hur ska molvikten skrivas ut i molgrafiken? Skall endast den totala molvikten skrivas ut eller skall varje enskild atoms vikt skrivas ut?

Mvh Edvard

Lärare kommenterade 4 april 2014

Totala vikten!

kommenterade 6 april 2014

@Stefan:

QUICK FIX:
Kommentera ut:

if self.root!=None:
    self.root.destroy()

i show funktionen i molgrafik modulen. Eftersom vi inte försöker öppna fler en ett fönster så kommer detta inte behövas.

kommenterade 6 april 2014

Det här är dock irriterande.
Problemet med "can't invoke destroy.." beror på att root inte är None trots att grafiken är förstörd. Jag har försökt lösa problemet med att definiera en exit funktion som ser till att root = None då den förstörs, med hjälp av root.protocol('WM_DELETE_WINDOW', exit).
Men det här fungerar inte, istället när jag trycker på krysset i Tkinter grafikrutan, så slutar mitt program att köras, utan att någon error raisas. Varför blir det såhär?

kommenterade 6 april 2014

Okej, insåg nu att jag bara hade gjort några enkla fel. Den snygga lösningen ser ut såhär:
gör en exit metod i molgrafik klassen:

def exit(self):
  self.root.destroy()
  self.root = None

Sedan lägger du till raden:
self.root.protocol('WM_DELETE_WINDOW', self.exit)
efter root skapas "self.root = TK()" i show metoden.

kommenterade 6 april 2014

@Didrik

Ja precis! Jag hade gjort så, men hade strulat till en annan grej.
Men tack för hjälpen!

Mvh
Stefan

kommenterade 7 april 2014

Hej,

Jag försöker boka redovisning på onsdag, men det finns inga lediga tider. Kommer det upp fler tider?

Lärare kommenterade 7 april 2014

Jag lägger upp fler tider!

kommenterade 8 april 2014

Jag kommer inte åt att boka - det går inte att komma in på sidan.

Feedback Nyheter