Turing Machine3 - itnett/FTD02H-N GitHub Wiki

For å utvide koden slik at den også håndterer variablene ic, id (nye heltall), og fc, fd (nye flyttall), samt vise operatorrekkefølgen, kan vi inkludere flere operasjoner i koden. I tillegg skal vi sikre at resultatene vises i en ryddig tabell, med operatorrekkefølgen som angitt i bildet.

Plan for utvidelsen:

  1. Legg til variabler: Vi legger til de nye heltallene ic, id og flyttallene fc, fd.
  2. Beregn operasjoner: Vi utfører de samme operasjonene som tidligere (addisjon, subtraksjon, multiplikasjon, divisjon, heltallsdivisjon, modulus, og potensiering) på alle kombinasjoner av variabler.
  3. Vis operatorrekkefølge: Vi tar hensyn til operatorrekkefølge når vi beregner operasjoner, og viser at Python utfører operasjoner fra høyeste til laveste prioritet (eksponentiering, multiplikasjon, divisjon, osv.).
  4. Ryddig utskrift: Vi sørger for å skrive ut operasjonene og resultatene i en ryddig tabell, i stil med "Simple Operations"-bildet.

Utvidet kode:

def explain_operations(ia, ib, fa, fb, ic, id, fc, fd):
    # Print variablene og deres typer først
    print("### Verdiene og deres typer ###")
    print(f"ia = {ia}, type: {type(ia)}")
    print(f"ib = {ib}, type: {type(ib)}")
    print(f"fa = {fa}, type: {type(fa)}")
    print(f"fb = {fb}, type: {type(fb)}")
    print(f"ic = {ic}, type: {type(ic)}")
    print(f"id = {id}, type: {type(id)}")
    print(f"fc = {fc}, type: {type(fc)}")
    print(f"fd = {fd}, type: {type(fd)}")
    print("-" * 50)

    # Definerer operasjoner med unntakshåndtering for alle variabler
    operations = [
        ('ia + ib', lambda: ia + ib),
        ('fa + fb', lambda: fa + fb),
        ('ic + id', lambda: ic + id),
        ('fc + fd', lambda: fc + fd),
        ('ia * ic', lambda: ia * ic),
        ('fa * fc', lambda: fa * fc),
        ('ib / id', lambda: ib / id),
        ('fb / fd', lambda: fb / fd),
        ('ia % ic', lambda: ia % ic),
        ('fa % fc', lambda: fa % fc),
        ('ia ** ib', lambda: ia ** ib),
        ('fa ** fb', lambda: fa ** fb),
        ('ia + ic * id', lambda: ia + ic * id),   # Operatorprecedence (multiplication first)
        ('fa + fc * fd', lambda: fa + fc * fd),   # Operatorprecedence (multiplication first)
        ('ia * (ic + id)', lambda: ia * (ic + id)), # Parentheses precedence
        ('fa * (fc + fd)', lambda: fa * (fc + fd)), # Parentheses precedence
    ]

    # Utskrift av resultatene i tabellformat med unntakshåndtering
    print("\n### Resultater av operasjoner på kombinasjoner av int og float ###")
    print(f"{'Operasjon':<20} {'Resultat':<15} {'Type':<20}")
    print("-" * 50)
    
    for op, func in operations:
        try:
            result = func()
            result_type = type(result)
            # Print resultatet med int uten desimaler og float med desimaler
            if isinstance(result, int):
                print(f"{op:<20} {result:<15} {str(result_type):<20}")
            else:  # Hvis det er et flyttall, vis med 6 desimaler
                print(f"{op:<20} {result:<15.6f} {str(result_type):<20}")
        except ZeroDivisionError:
            print(f"{op:<20} {'Feil: Divisjon med null':<15} {'N/A':<20}")
        except OverflowError:
            print(f"{op:<20} {'Feil: Overflow':<15} {'N/A':<20}")
        except Exception as e:
            print(f"{op:<20} {'Feil: ' + str(e):<15} {'N/A':<20}")

# Definerer variabler for heltall og flyttall
ia, ib, ic, id = 10, 3, 5, 2  # Heltall
fa, fb, fc, fd = 10.0, 3.0, 5.0, 2.0  # Flyttall

# Kaller funksjonen og viser resultatene
explain_operations(ia, ib, fa, fb, ic, id, fc, fd)

Forklaring av utvidelsen:

  1. Nye variabler: Vi har lagt til to nye sett med heltall (ic, id) og flyttall (fc, fd).
  2. Operasjonsrekke: Vi har lagt til operasjoner som tar hensyn til operatorrekkefølge (f.eks. multiplikasjon før addisjon), og også eksempler på operasjoner med parenteser som overstyrer standard operatorrekkefølge.
  3. Unntakshåndtering: Programmet håndterer unntak som ZeroDivisionError og OverflowError på samme måte som før.
  4. Tabellvisning: Vi viser resultatene i en ryddig tabell som viser operasjonen, resultatet, og typen av resultatet.

Forventet utdata:

### Verdiene og deres typer ###
ia = 10, type: <class 'int'>
ib = 3, type: <class 'int'>
fa = 10.0, type: <class 'float'>
fb = 3.0, type: <class 'float'>
ic = 5, type: <class 'int'>
id = 2, type: <class 'int'>
fc = 5.0, type: <class 'float'>
fd = 2.0, type: <class 'float'>
--------------------------------------------------

### Resultater av operasjoner på kombinasjoner av int og float ###
Operasjon            Resultat        Type                
--------------------------------------------------
ia + ib              13              <class 'int'>        
fa + fb              13.000000       <class 'float'>      
ic + id              7               <class 'int'>        
fc + fd              7.000000        <class 'float'>      
ia * ic              50              <class 'int'>        
fa * fc              50.000000       <class 'float'>      
ib / id              1.500000        <class 'float'>      
fb / fd              1.500000        <class 'float'>      
ia % ic              0               <class 'int'>        
fa % fc              0.000000        <class 'float'>      
ia ** ib             1000            <class 'int'>        
fa ** fb             1000.000000     <class 'float'>      
ia + ic * id         20              <class 'int'>        
fa + fc * fd         20.000000       <class 'float'>      
ia * (ic + id)       70              <class 'int'>        
fa * (fc + fd)       70.000000       <class 'float'>      

Forklaring av utdata:

  • Heltallsoperasjoner: Operasjoner som involverer kun heltall (ia + ib, ic * id, etc.) gir heltall som resultat, uten desimaler.
  • Flyttallsoperasjoner: Operasjoner som involverer flyttall (fa + fb, fa * fc, etc.) gir flyttall som resultat, og vises med seks desimaler.
  • Operatorrekkefølge: Resultatene viser at Python først utfører multiplikasjon og divisjon før addisjon og subtraksjon (f.eks. ia + ic * id utfører multiplikasjon først).
  • Parenteser: Når vi bruker parenteser, overstyrer vi den vanlige operatorrekkefølgen. For eksempel gir ia * (ic + id) et annet resultat enn ia + ic * id.

Konklusjon:

Denne utvidelsen legger til flere variabler og kombinasjoner av operasjoner, inkludert eksempler på operatorrekkefølge og bruk av parenteser. Resultatene vises i en ryddig tabell, noe som gjør det enkelt å forstå hvordan Python håndterer operasjoner mellom heltall og flyttall, samt hvordan operatorer prioriteres i uttrykk.

For å sikre at koden håndterer potensielle feil, som for eksempel divisjon med null eller andre feil, på en mer kontrollert måte, kan vi legge til manuelle sjekker før operasjonene utføres. Dette gir oss enda mer kontroll over feilene, og vi kan unngå å la unntakene skje i det hele tatt, i stedet for å fange dem med try-except.

Hvordan vi håndterer mulige feil:

  1. Sjekk for divisjon med null: Før vi utfører divisjon (/), heltallsdivisjon (//), eller modulus (%), kan vi sjekke om nevneren er null og unngå å utføre operasjonen dersom det er tilfelle.
  2. Sjekk for overflow: Vi kan ikke forutsi alle mulige tilfeller av overflow, men vi kan håndtere dem ved å fange opp OverflowError i potensielt farlige operasjoner som eksponentiering.
  3. Generell feilsjekk: For alle andre mulige feil kan vi bruke try-except som en generell sikkerhetsmekanisme.

Her er en forbedret versjon av programmet med manuelle sjekker før operasjonene utføres.

Oppdatert program med manuelle sjekker:

def explain_operations(ia, ib, fa, fb, ic, id, fc, fd):
    # Print variablene og deres typer først
    print("### Verdiene og deres typer ###")
    print(f"ia = {ia}, type: {type(ia)}")
    print(f"ib = {ib}, type: {type(ib)}")
    print(f"fa = {fa}, type: {type(fa)}")
    print(f"fb = {fb}, type: {type(fb)}")
    print(f"ic = {ic}, type: {type(ic)}")
    print(f"id = {id}, type: {type(id)}")
    print(f"fc = {fc}, type: {type(fc)}")
    print(f"fd = {fd}, type: {type(fd)}")
    print("-" * 50)

    # Definerer operasjoner med manuelle sjekker for divisjon med null og overflow
    operations = [
        ('ia + ib', lambda: ia + ib),
        ('fa + fb', lambda: fa + fb),
        ('ic + id', lambda: ic + id),
        ('fc + fd', lambda: fc + fd),
        ('ia * ic', lambda: ia * ic),
        ('fa * fc', lambda: fa * fc),
        
        # Sjekk før divisjon for å unngå ZeroDivisionError
        ('ib / id', lambda: "Feil: Divisjon med null" if id == 0 else ib / id),
        ('fb / fd', lambda: "Feil: Divisjon med null" if fd == 0 else fb / fd),
        
        # Sjekk før heltallsdivisjon
        ('ia // ic', lambda: "Feil: Divisjon med null" if ic == 0 else ia // ic),
        ('fa // fc', lambda: "Feil: Divisjon med null" if fc == 0 else fa // fc),
        
        # Sjekk før modulus
        ('ia % ic', lambda: "Feil: Divisjon med null" if ic == 0 else ia % ic),
        ('fa % fc', lambda: "Feil: Divisjon med null" if fc == 0 else fa % fc),
        
        # Sjekk for overflow under eksponentiering
        ('ia ** ib', lambda: "Feil: Overflow" if ib > 100 else ia ** ib),
        ('fa ** fb', lambda: "Feil: Overflow" if fb > 100 else fa ** fb),
        
        # Operatorrekkefølge
        ('ia + ic * id', lambda: ia + ic * id),   # Multiplikasjon før addisjon
        ('fa + fc * fd', lambda: fa + fc * fd),   # Multiplikasjon før addisjon
        
        # Parentessjekk
        ('ia * (ic + id)', lambda: ia * (ic + id)),
        ('fa * (fc + fd)', lambda: fa * (fc + fd)),
    ]

    # Utskrift av resultatene i tabellformat med manuelle sjekker
    print("\n### Resultater av operasjoner på kombinasjoner av int og float ###")
    print(f"{'Operasjon':<20} {'Resultat':<15} {'Type':<20}")
    print("-" * 50)
    
    for op, func in operations:
        try:
            result = func()
            result_type = type(result) if result != "Feil: Divisjon med null" and result != "Feil: Overflow" else 'N/A'
            # Print resultatet med int uten desimaler og float med desimaler
            if isinstance(result, int):
                print(f"{op:<20} {result:<15} {str(result_type):<20}")
            elif isinstance(result, float):
                print(f"{op:<20} {result:<15.6f} {str(result_type):<20}")
            else:
                print(f"{op:<20} {result:<15} {'N/A':<20}")
        except Exception as e:
            print(f"{op:<20} {'Feil: ' + str(e):<15} {'N/A':<20}")

# Definerer variabler for heltall og flyttall
ia, ib, ic, id = 10, 3, 5, 0  # Heltall (med en test for divisjon med null)
fa, fb, fc, fd = 10.0, 3.0, 5.0, 0.0  # Flyttall (med en test for divisjon med null)

# Kaller funksjonen og viser resultatene
explain_operations(ia, ib, fa, fb, ic, id, fc, fd)

Forklaring av forbedringer:

  1. Sjekk for divisjon med null: Før divisjon (/), heltallsdivisjon (//), og modulus (%), sjekker vi om nevneren er null. Hvis det er tilfelle, utføres ikke operasjonen, og vi returnerer en forståelig feilmelding.

    Eksempel:

    ('ib / id', lambda: "Feil: Divisjon med null" if id == 0 else ib / id)
    
  2. Sjekk for overflow: Vi gjør en enkel sjekk for eksponentieringsoperasjoner for å unngå potensielt farlige operasjoner med veldig store eksponenter. Her har vi satt en grense på 100 for eksempelets skyld, men dette kan tilpasses til det som er hensiktsmessig for ditt bruk.

  3. Resultatutskrift: Hvis det oppdages en feil (som divisjon med null eller overflow), returneres en feilmelding i stedet for å la programmet kaste et unntak.

Forventet utdata:

### Verdiene og deres typer ###
ia = 10, type: <class 'int'>
ib = 3, type: <class 'int'>
fa = 10.0, type: <class 'float'>
fb = 3.0, type: <class 'float'>
ic = 5, type: <class 'int'>
id = 0, type: <class 'int'>
fc = 5.0, type: <class 'float'>
fd = 0.0, type: <class 'float'>
--------------------------------------------------

### Resultater av operasjoner på kombinasjoner av int og float ###
Operasjon            Resultat        Type                
--------------------------------------------------
ia + ib              13              <class 'int'>        
fa + fb              13.000000       <class 'float'>      
ic + id              5               <class 'int'>        
fc + fd              5.000000        <class 'float'>      
ia * ic              50              <class 'int'>        
fa * fc              50.000000       <class 'float'>      
ib / id              Feil: Divisjon med null N/A                 
fb / fd              Feil: Divisjon med null N/A                 
ia // ic             2               <class 'int'>        
fa // fc             2.000000        <class 'float'>      
ia % ic              0               <class 'int'>        
fa % fc              0.000000        <class 'float'>      
ia ** ib             1000            <class 'int'>        
fa ** fb             1000.000000     <class 'float'>      
ia + ic * id         10              <class 'int'>        
fa + fc * fd         10.000000       <class 'float'>      
ia * (ic + id)       50              <class 'int'>        
fa * (fc + fd)       50.000000       <class 'float'>      

Hva gjør vi her:

  • Feilmeldinger: Hvis divisjon med null oppstår, viser vi en klar melding: "Feil: Divisjon med null". På denne måten unngår vi unødvendige unntak.
  • Overflow-sjekk: Vi unngår operasjoner som kan forårsake overflow ved eksponentiering

.

  • Ryddig utskrift: Operasjonene og resultatene vises i en ryddig tabell, der feil håndteres eksplisitt.

Konklusjon:

Denne versjonen av koden utfører manuelle sjekker før operasjoner som kan føre til feil. Dette forhindrer unødvendige unntak og gjør at koden håndterer feil på en kontrollert måte. Dette kan være nyttig i situasjoner der du vil ha bedre kontroll over hvilke operasjoner som utføres, og hvordan potensielle feil håndteres.