Text aus tkinter.Label

Fragen zu Tkinter.
Antworten
Kaewien
User
Beiträge: 4
Registriert: Samstag 6. Februar 2016, 18:01

Hallo liebes Forum,

ich bin ganz neu hier und versuche mich ein wenig an Python ran und habe mit dem Buch "Programmieren SuperEasy" angefangen. :mrgreen:

Mein Vorhaben: Ich bastel mir ein Hexwandler (Hexadezimal -> Dezimal)
Das wandeln Funktioniert schon einfandfrei, nur hapert es an kleinigkeiten.

Mein Problem:
Hier ein Beispiel.

Code: Alles auswählen

Text1 = Label(Abschnitt1, text='ABC')
Wobei 'Abschnitt1' ein Frame ist, was Ihr vermutlich alle wisst.

Wie kann ich den text aus diesen Label auslesen?
Ich möchte an den Text mehr Zeichen ranhängen.
Welchen Befehl muss ich verwenden.
BlackJack

@Kaewien: Man kann auf die Tk-Optionen wie bei einem Wörterbuch (`dict`) zugreifen: `text['text']`.

Hör bitte sofort auf Nummern an Namen anzuhängen! Das ist entweder ein Zeichen, dass man sich nicht die Zeit genommen hat einen sinnvollen Namen zu wählen, oder das man eigentlich keine einzelnen Namen verwenden möchte, sondern die Werte in eine Datenstruktur stecken sollte. Oft eine Liste. In diesem Fall gehe ich aber eher von schlecht gewählten Namen aus. Gute Namen sind wichtig! Das entscheidet darüber ob jemand anders, oder Du in ein paar Monaten, leicht versteht was der Code macht.

In der Regel sollte man das Problem welches Du zu lösen versuchst, gar nicht erst haben. Die GUI ist zur Interaktion mit dem Benutzer da, nicht um darin Werte zu speichern, die man später dort wieder heraus holt. Warum hast Du diese Daten nur in der GUI?

Wichtiger Lesetipp: Style Guide for Python Code.
Kaewien
User
Beiträge: 4
Registriert: Samstag 6. Februar 2016, 18:01

Hallo BlackJack,

Danke für deine schnelle Antwort.
Jetzt funktioniert das auslesen auch.

Ich habe mir mit der GUI ein Zahlenfeld erstellt, womit ich die Hexadezimalen Zahlen eintippe. (So können keine Falscheingaben passieren)
Und mit einem Button möchte ich diese dann umwandeln.

Ist ein reines Experiment für mich um Python besser kennenzulernen.

Mit den Variablennamen.. Ich habe ihn geändert in einen verständlichen Namen. Guter Tipp nochmal Danke :)

Gruß Kevin
Kaewien
User
Beiträge: 4
Registriert: Samstag 6. Februar 2016, 18:01

Das wäre jetzt mein persönlicher Hexadezimalwandler

Für's erste bin ich zufrieden.
Es gibt sicherlich noch einfachere Lösungen dafür.

Code: Alles auswählen

# Umwandler von Hexadezimal nach Dezimal

from tkinter import *

# Fenster aufbauen
window = Tk()
window.title('Hexwandler')
window.configure(height=220, width=200, bg='gray')
window.resizable(height=NO, width=NO)

# Die Funktion 'hexe' macht aus ein eingegebenes
# Hex-Zeichen eine Dezimalzahl
def hexe(s):
    s = s.upper()
    if s == '0':
        z = '0'
    elif s == '1':
        z = '1'
    elif s == '2':
        z = '2'
    elif s == '3':
        z = '3'
    elif s == '4':
        z = '4'
    elif s == '5':
        z = '5'
    elif s == '6':
        z = '6'
    elif s == '7':
        z = '7'
    elif s == '8':
        z = '8'
    elif s == '9':
        z = '9'
    elif s == 'A':
        z = '10'
    elif s == 'B':
        z = '11'
    elif s == 'C':
        z = '12'
    elif s == 'D':
        z = '13'
    elif s == 'E':
        z = '14'
    elif s == 'F':
        z = '15'
    else:
        z = 'F'
    return z

# Die Funktion 'hexwandler' rechnet eine eingegebene
# Hexadezimalzahl in eine Dezimalzahl um
def hexwandler(hex):
    h_len = len(hex)
    hl = h_len
    zahl = 0
    zwischenerg = 0
    ergebnis = 0
    for n in range(1, h_len + 1):
        zahl = hexe(hex[int(n-1):int(n)])
        zwischenerg = int(zahl) * (16 ** int(hl-1))
        hl = hl - 1
        ergebnis = ergebnis + zwischenerg
    return ergebnis

# Die Funktionen für die Button's
def A():
    z = (Hexwert['text'])
    z = z + 'A'
    Hexwert.config(text=z)

def B():
    z = (Hexwert['text'])
    z = z + 'B'
    Hexwert.config(text=z)

def C():
    z = (Hexwert['text'])
    z = z + 'C'
    Hexwert.config(text=z)

def D():
    z = (Hexwert['text'])
    z = z + 'D'
    Hexwert.config(text=z)

def E():
    z = (Hexwert['text'])
    z = z + 'E'
    Hexwert.config(text=z)

def F():
    z = (Hexwert['text'])
    z = z + 'F'
    Hexwert.config(text=z)

def Z0():
    z = (Hexwert['text'])
    z = z + '0'
    Hexwert.config(text=z)

def Z1():
    z = (Hexwert['text'])
    z = z + '1'
    Hexwert.config(text=z)

def Z2():
    z = (Hexwert['text'])
    z = z + '2'
    Hexwert.config(text=z)

def Z3():
    z = (Hexwert['text'])
    z = z + '3'
    Hexwert.config(text=z)

def Z4():
    z = (Hexwert['text'])
    z = z + '4'
    Hexwert.config(text=z)

def Z5():
    z = (Hexwert['text'])
    z = z + '5'
    Hexwert.config(text=z)

def Z6():
    z = (Hexwert['text'])
    z = z + '6'
    Hexwert.config(text=z)

def Z7():
    z = (Hexwert['text'])
    z = z + '7'
    Hexwert.config(text=z)

def Z8():
    z = (Hexwert['text'])
    z = z + '8'
    Hexwert.config(text=z)

def Z9():
    z = (Hexwert['text'])
    z = z + '9'
    Hexwert.config(text=z)

def wandel():
    hexwert = (Hexwert['text'])
    dezwert = hexwandler(hexwert)
    Dezwert.config(text=dezwert)

def Clear():
    Hexwert.config(text='')
    Dezwert.config(text='')


##############################################################
Abschnitt1 = Frame(window, height=25, width=200, bg='#4bc8eb')
Abschnitt1.propagate(0)
Abschnitt1.pack()
Abschnitt1_0 = Frame(window, height=25, width=200, bg='#4bc8eb')
Abschnitt1_0.propagate(0)
Abschnitt1_0.pack()
Abschnitt2 = Frame(window, height=34, width=200, bg='#8796b9')
Abschnitt2.propagate(0)
Abschnitt2.pack()
Abschnitt3 = Frame(window, height=34, width=200, bg='#8796b9')
Abschnitt3.propagate(0)
Abschnitt3.pack()
Abschnitt4 = Frame(window, height=34, width=200, bg='#8796b9')
Abschnitt4.propagate(0)
Abschnitt4.pack()
Abschnitt5 = Frame(window, height=34, width=200, bg='#8796b9')
Abschnitt5.propagate(0)
Abschnitt5.pack()
Abschnitt6 = Frame(window, height=34, width=200, bg='#8796b9')
Abschnitt6.propagate(0)
Abschnitt6.pack()
##############################################################

Hexwert = Label(Abschnitt1, bg='#4bc8eb')
Dezwert = Label(Abschnitt1_0, bg='#4bc8eb')

##############################################################
AbstandX1 = Label(Abschnitt2, text='         ', bg='#8796b9')
AbstandX2 = Label(Abschnitt3, text='         ', bg='#8796b9')
AbstandX3 = Label(Abschnitt4, text='         ', bg='#8796b9')
AbstandX4 = Label(Abschnitt5, text='         ', bg='#8796b9')
Abstand1 = Label(Abschnitt2, text='  ', bg='#8796b9')
Abstand2 = Label(Abschnitt2, text='  ', bg='#8796b9')
Abstand3 = Label(Abschnitt2, text='  ', bg='#8796b9')
Abstand4 = Label(Abschnitt3, text='  ', bg='#8796b9')
Abstand5 = Label(Abschnitt3, text='  ', bg='#8796b9')
Abstand6 = Label(Abschnitt3, text='  ', bg='#8796b9')
Abstand7 = Label(Abschnitt4, text='  ', bg='#8796b9')
Abstand8 = Label(Abschnitt4, text='  ', bg='#8796b9')
Abstand9 = Label(Abschnitt4, text='  ', bg='#8796b9')
Abstand10 = Label(Abschnitt5, text='  ', bg='#8796b9')
Abstand11 = Label(Abschnitt5, text='  ', bg='#8796b9')
Abstand12 = Label(Abschnitt5, text='  ', bg='#8796b9')
Abstand13 = Label(Abschnitt6, text='         ', bg='#8796b9')
Abstand14 = Label(Abschnitt6, text='  ', bg='#8796b9')
##############################################################




##############################################################
Knopf_0 = Button(Abschnitt5, text=' 0 ', command=Z0)
Knopf_A = Button(Abschnitt2, text=' A ', command=A)
Knopf_1 = Button(Abschnitt2, text=' 1 ', command=Z1)
Knopf_2 = Button(Abschnitt2, text=' 2 ', command=Z2)
Knopf_3 = Button(Abschnitt2, text=' 3 ', command=Z3)
Knopf_B = Button(Abschnitt3, text=' B ', command=B)
Knopf_4 = Button(Abschnitt3, text=' 4 ', command=Z4)
Knopf_5 = Button(Abschnitt3, text=' 5 ', command=Z5)
Knopf_6 = Button(Abschnitt3, text=' 6 ', command=Z6)
Knopf_C = Button(Abschnitt4, text=' C ', command=C)
Knopf_7 = Button(Abschnitt4, text=' 7 ', command=Z7)
Knopf_8 = Button(Abschnitt4, text=' 8 ', command=Z8)
Knopf_9 = Button(Abschnitt4, text=' 9 ', command=Z9)
Knopf_D = Button(Abschnitt5, text=' D ', command=D)
Knopf_E = Button(Abschnitt5, text=' E ', command=E)
Knopf_F = Button(Abschnitt5, text=' F ', command=F)

KnopfClear = Button(Abschnitt6, text='CLR', command=Clear)
KnopfWandel = Button(Abschnitt6, text='  Umwandeln  ', command=wandel)
##############################################################


##############################################################
Hexwert.pack(side=TOP)
Dezwert.pack(side=BOTTOM)

AbstandX1.pack(side=LEFT)
Knopf_A.pack(side=LEFT)
Abstand1.pack(side=LEFT)
Knopf_1.pack(side=LEFT)
Abstand2.pack(side=LEFT)
Knopf_2.pack(side=LEFT)
Abstand3.pack(side=LEFT)
Knopf_3.pack(side=LEFT)

AbstandX2.pack(side=LEFT)
Knopf_B.pack(side=LEFT)
Abstand4.pack(side=LEFT)
Knopf_4.pack(side=LEFT)
Abstand5.pack(side=LEFT)
Knopf_5.pack(side=LEFT)
Abstand6.pack(side=LEFT)
Knopf_6.pack(side=LEFT)

AbstandX3.pack(side=LEFT)
Knopf_C.pack(side=LEFT)
Abstand7.pack(side=LEFT)
Knopf_7.pack(side=LEFT)
Abstand8.pack(side=LEFT)
Knopf_8.pack(side=LEFT)
Abstand9.pack(side=LEFT)
Knopf_9.pack(side=LEFT)

AbstandX4.pack(side=LEFT)
Knopf_D.pack(side=LEFT)
Abstand10.pack(side=LEFT)
Knopf_E.pack(side=LEFT)
Abstand11.pack(side=LEFT)
Knopf_F.pack(side=LEFT)
Abstand12.pack(side=LEFT)
Knopf_0.pack(side=LEFT)

Abstand13.pack(side=LEFT)
KnopfClear.pack(side=LEFT)
Abstand14.pack(side=LEFT)
KnopfWandel.pack(side=LEFT)
##############################################################

window.mainloop()
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kaewien: Programmierer wollen möglichst keinen Code wiederholen. Jede Zeile die man nicht schreibt kann auch keinen Fehler enthalten. Zumal es für das, was Du da machst, schon eine fertige Funktion gibt, int. *-Importe solltest Du vermeiden, weil Du nicht kontrollieren kannst, welche Namen Du Dir damit in Deinen Namensraum holst. Statt den vielen Frames und Platzhaltern bietet Tk grid, das für genau solche Zwecke wie bei Dir gemacht wurde. Die Knöpfe kann man auch leichter per for-Schleife erzeugen.

Code: Alles auswählen

import tkinter as tk
from functools import partial

class MainWindow(tk.Tk):
    def __init__(self):
       tk.Tk.__init__(self)
       self.title('Hexwandler')
       self.resizable(height=tk.NO, width=tk.NO)
       self.hex_value = ""
       self.hex_label = tk.Label(self, bg='#4bc8eb')
       self.hex_label.grid(row=0,column=0,columnspan=4,stick="EW")
       self.dec_label = tk.Label(self, bg='#4bc8eb')
       self.dec_label.grid(row=1,column=0,columnspan=4,stick="EW")
      
       for row, buttons in enumerate(['A123','B456','C789','0DEF'], 2):
           for col, text in enumerate(buttons):
               tk.Button(self, text=' %s ' % text, command=partial(self.add_digit,text)).grid(row=row, column=col)
      
       tk.Button(self, text='CLR', command=self.clear).grid(row=6, column=0, columnspan=2)
       tk.Button(self, text='Umwandeln', command=self.convert).grid(row=6, column=2, columnspan=2)
      
    def add_digit(self, digit):
        self.hex_value += digit
        self.hex_label.config(text=self.hex_value)

    def convert(self):
        self.dec_label.config(text=str(int(self.hex_value, 16)))

    def clear(self):
        self.hex_value = ""
        self.hex_label.config(text="")
        self.dec_label.config(text="")

def main():
    window = MainWindow()
    window.mainloop()
    
if __name__ == '__main__':
    main()
BlackJack

@Kaewien: Das ist ein furchtbar langer Quelltext mit ganz viel Code der durch kopieren, einfügen, und leicht verändern entstanden ist. Damit man so etwas nicht machen muss, sondern das den Rechner erledigen lässt, programmiert man doch eigentlich. Immer wenn Du so vorgehst, sollte das ein Warnzeichen sein, dass Du sehr wahrscheinlich etwas falsch machst und eigentlich eine Schleife und/oder eine Funktion schreiben möchtest, statt etwas per kopieren im Texteditor wiederholen zu lassen.

Sternchen-Importe holen alle Namen eines Moduls in das importierende Modul. Bei `tkinter` sind das um die 190 Namen, von denen Du nur einen kleinen Bruchteil verwendest. Wenn man das mit mehr als einem Modul macht, verliert man schnell den Überblick welcher Name eigentlich woher kommt. Ausserdem besteht die Gefahr von Namenskollisionen. Das `tkinter`-Modul importiert man deshalb üblicherweise unter dem Namen `tk` mit ``import tkinter as tk`` und greift dann auf die Objekte in dem Modul über diesen Namen zu. Wenn man Modulinhalte mit Sternchen-Importen zusammen matscht, braucht man sich ja nicht die Mühe zu machen Module zu schreiben.

Namen sollte man möglichst nahe an der Stelle definieren wo sie dann auch verwendet werden. Wenn zwischendurch tausend andere Sachen definiert und gemacht werden, hat man an der Stelle wo der Name dann letztendlich verwendet wird, wieder vergessen wie die Definition aussah und man muss wieder im Quelltext weit zurück gehen um das nachzulesen.

Statt vor einer Funktion einen Kommentar zu schreiben was die Funktion tut, sollte man das als Docstring in die Funktion schreiben.

Die vielen ``if``/``elif``-Zweige in der `hexe()`-Funktion kann man durch ein Wörterbuch ersetzen und sowohl die Funktion als auch das Argument könnten deutlich besser benannt sein:

Code: Alles auswählen

def hex_digit_to_int(hex_digit):
    """Die Funktion :func:`hex_digit_to_int` macht aus einem eingegebenen
    Hex-Zeichen eine Zahl.
    """
    return {
        '0': 0,
        '1': 1,
        '2': 2,
        '3': 3,
        '4': 4,
        '5': 5,
        '6': 6,
        '7': 7,
        '8': 8,
        '9': 9,
        'A': 10,
        'B': 11,
        'C': 12,
        'D': 13,
        'E': 14,
        'F': 15,
    }[hex_digit.upper()]
Wie man sieht sind die Zahlen von 0 an aufsteigend. Wenn man also eine Zeichenkette mit den Hex-Ziffern hätte, wäre der Index der Wert der jeweiligen Ziffer, also könne man die übergebene Ziffer auch in so einer Zeichenkette suchen:

Code: Alles auswählen

def hex_digit_to_int(hex_digit):
    """Die Funktion :func:`hex_digit_to_int` macht aus einem eingegebenen
    Hex-Zeichen eine Zahl.
    """
    return '0123456789ABCDEF'.index(hex_digit.upper())
Oder aber man stützt sich auf die bereits existierende `int()`-Funktion ab:

Code: Alles auswählen

def hex_digit_to_int(hex_digit):
    """Die Funktion :func:`hex_digit_to_int` macht aus einem eingegebenen
    Hex-Zeichen eine Zahl.
    """
    return int(hex_digit, 16)
Die `hexwandler()`-Funktion ist ziemlich abenteuerlich, um das mal vorsichtig auszudrücken. Als erstes sind da wieder die Namen. Funktionen (und Methoden) werden üblicherweise nach Tätigkeiten benannt, weil die etwas tun, um sie besser von eher passiven Werten unterscheiden zu können. Das Argument der Funktion trägt den Namen einer eingebauten Funktion (`hex()`), was man nicht machen sollte, weil es den Leser verwirren kann.

Die Beschreibung der Funktion im Kommetar stimmt nicht so ganz, weil das Ergebnis eine Zahl ist, keine *Dezimal*zahl. Die Zahl wird normalerweise in der Dezimaldarstellung ausgegeben, also in eine Zeichenkette umgewandelt, aber das ist eben nur die Zeichenkettendarstellung von so einem `int`-Objekt.

Die lokalen Namen in der Funktion sind teilweise auch nicht gut gewählt. Aus `h_len` und `hl` wird beim lesen nicht so leicht ersichtlich wofür die beiden gut sind. Kryptische Abkürzungen sollte man vermeiden. Auch `zwischenerg` sollte man ausschreiben. `hl` wird nicht wirklich benötigt, weil das mit `h_len` initialisiert wird und in der Schleife verringert wird, wärhrend `n` erhöht wird. Man kann den `hl`-Wert als in der Schleife problemlos aus `h_len` und `n` berechnen. `zahl` und `zwischenerg` werden vor der Schleife sinnlos auf 0 gesetzt. Dieser Wert wird nie irgendwo verwendet. Die Potenz von der 16 ist bereits eine Zahl, der `int()`-Aufruf dort ist überflüssig. Ebenso ist das bei den Ausdrücken mit `n` völlig sinnfrei. Zwischenstand:

Code: Alles auswählen

def hex_string_to_int(hex_string):
    """Die Funktion :func:`hex_string_to_int` rechnet eine eingegebene
    Hexadezimalzahl in eine Zahl um.
    """
    string_length = len(hex_string)
    ergebnis = 0
    for n in range(1, string_length + 1):
        zahl = hex_digit_to_int(hex_string[n - 1:n])
        zwischenergebnis = zahl * 16**(string_length - n)
        ergebnis = ergebnis + zwischenergebnis
    return ergebnis
Programmierer fangen bei 0 an zu zählen. Das `n` von 1 an läuft ist ungewöhnlich, das sollte man ändern und `zwischenergebnis` braucht man auch nicht wirklich. Der Name bringt keinen Erkenntnisgewinn beim Lesen und man bekommt das auch prima ohne in einer Zeile unter:

Code: Alles auswählen

def hex_string_to_int(hex_string):
    """Die Funktion :func:`hex_string_to_int` rechnet eine eingegebene
    Hexadezimalzahl in eine Zahl um.
    """
    string_length = len(hex_string)
    ergebnis = 0
    for n in range(string_length):
        zahl = hex_digit_to_int(hex_string[n:n + 1])
        ergebnis += zahl * 16**(string_length - n - 1)
    return ergebnis
Das „slicing“ mit `n` ist jetzt aber ziemlich überflüssig, denn das ist ja im Grunde nichts anderes als das `n`-te Zeichen in `hex_string`. Desweiteren kann man die Potenzrechnung recht einfach beseitigen und durch eine Multiplikation ersetzen und damit dann auch gleich `string_length` einsparen:

Code: Alles auswählen

def hex_string_to_int(hex_string):
    """Die Funktion :func:`hex_string_to_int` rechnet eine eingegebene
    Hexadezimalzahl in eine Zahl um.
    """
    ergebnis = 0
    for n in range(len(hex_string)):
        zahl = hex_digit_to_int(hex_string[n])
        ergebnis = ergebnis * 16 + zahl
    return ergebnis
Nun wird `n` nur noch als Index in `hex_string` verwendet und das ist in Python ein „anti pattern“, weil man ohne den Umweg über einen Index über die Elemente von Sequenzen iterieren kann:

Code: Alles auswählen

def hex_string_to_int(hex_string):
    """Die Funktion :func:`hex_string_to_int` rechnet eine eingegebene
    Hexadezimalzahl in eine Zahl um.
    """
    ergebnis = 0
    for hex_digit in hex_string:
        zahl = hex_digit_to_int(hex_digit)
        ergebnis = ergebnis * 16 + zahl
    return ergebnis
`hex_digit` gibt es nur weil `hex_digit_to_int()` auf jedes Zeichen von `hex_string` angewendet werden muss. Den Namen wird man mit der `map()`-Funktion leicht los, so das man in der Schleife direkt über die Zahlwerte zu den Hex-Ziffern iterieren kann:

Code: Alles auswählen

def hex_string_to_int(hex_string):
    """Die Funktion :func:`hex_string_to_int` rechnet eine eingegebene
    Hexadezimalzahl in eine Zahl um.
    """
    ergebnis = 0
    for zahl in map(hex_digit_to_int, hex_string):
        ergebnis = ergebnis * 16 + zahl
    return ergebnis
Mit `reduce()` aus dem `functools`-Modul und einem ``lambda``-Ausdruck bekommt man das ganze auch gerade noch so in eine Zeile:

Code: Alles auswählen

def hex_string_to_int(hex_string):
    """Die Funktion :func:`hex_string_to_int` rechnet eine eingegebene
    Hexadezimalzahl in eine Zahl um.
    """
    return reduce(lambda a, b: a * 16 + b, map(hex_digit_to_int, hex_string), 0)
Allerdings ist das alles überflüssig, weil es ja wie wir aus der `hex_digit_to_int()`-Funktion wissen, die `int()`-Funktion gibt, der man eine Basis als optionales Argument übergeben kann, und die kann damit auch mehr als nur eine Ziffer umwandeln. Man muss sich nur um die leere Zeichenkette noch mal gesondert kümmern:

Code: Alles auswählen

def hex_string_to_int(hex_string):
    """Die Funktion :func:`hex_string_to_int` rechnet eine eingegebene
    Hexadezimalzahl in eine Zahl um.
    """
    return int(hex_string, 16) if hex_string else 0
Letztendlich absolute Grössen und Positionen mittels `width`- und `height`-Argumenten und `pack()` und ``propagate(0)`` sehe ich bei Dir zum ersten mal. Da muss man erst mal drauf kommen. Hier der Grund warum das keine gute Idee ist:
Bild
Mir fehlt da eine Spalte und auch die sichtbaren sind nicht alle gleich ausgerichtet. Man sollte weder Grössen oder Positionen hart vorgeben, noch verhindern das Tk selber dafür sorgen kann, dass alles so viel Platz in der Anzeige bekommt wie es benötigt. Sonst sehen GUIs nur auf den Rechnern auf denen sie erstellt wurden vernünftig aus, oder es kann sogar passieren, dass die GUI nicht mehr bedienbar ist, weil Schaltflächen oder Anzeigeelemente gar nicht dargestellt werden. `grid()` hat Sirius3 ja bereits gezeigt.
Kaewien
User
Beiträge: 4
Registriert: Samstag 6. Februar 2016, 18:01

Da merke ich mal wie viel Unsinn aus 3-tägiger Python-Erfahrung herauskommt.

@ Sirius3: Das mit den *-Importen hatte ich noch nicht so bedacht. Das werde ich mir merken.
Was allerdings meinst du mit der grid()-Funktion? Was bewirkt die?
For-Schleifen sollte ich auch mehr verwenden.

'class' habe ich noch nicht verwendet. Da muss ich mich noch einarbeiten. Ich sehe sehr viele Begriffe in den von dir gezeigten Skript, die ich mir ersteinmal beibringen muss. Danke für die Zeit und Hilfe.

@BlackJack:
Das ist ein furchtbar langer Quelltext mit ganz viel Code der durch kopieren, einfügen, und leicht verändern entstanden ist.
Wie hast du das herausgefunden? :D
Damit man so etwas nicht machen muss, sondern das den Rechner erledigen lässt, programmiert man doch eigentlich. Immer wenn Du so vorgehst, sollte das ein Warnzeichen sein, dass Du sehr wahrscheinlich etwas falsch machst und eigentlich eine Schleife und/oder eine Funktion schreiben möchtest, statt etwas per kopieren im Texteditor wiederholen zu lassen.
Das werde ich versuchen im Hinterkopf als Warnsignal zu speichern.
Namen sollte man möglichst nahe an der Stelle definieren wo sie dann auch verwendet werden. Wenn zwischendurch tausend andere Sachen definiert und gemacht werden, hat man an der Stelle wo der Name dann letztendlich verwendet wird, wieder vergessen wie die Definition aussah und man muss wieder im Quelltext weit zurück gehen um das nachzulesen.
An der Übersichtlichkeit und Lesbarkeit habe ich auch nicht nachgedacht. Guter Tipp. Danke.
Statt vor einer Funktion einen Kommentar zu schreiben was die Funktion tut, sollte man das als Docstring in die Funktion schreiben.
Was bedeutet Docstring?
Oder aber man stützt sich auf die bereits existierende `int()`-Funktion ab:
Das heißt, dass die int()-Funktion mit der ', 16' hinten dran aus Hexadezimal = Dezimal wandelt?
So wird aus mein 36-Zeiler (oder so ähnlich) ein 2-Zeiler. Beeindruckend
Die `hexwandler()`-Funktion ist ziemlich abenteuerlich, um das mal vorsichtig auszudrücken. Als erstes sind da wieder die Namen. Funktionen (und Methoden) werden üblicherweise nach Tätigkeiten benannt, weil die etwas tun, um sie besser von eher passiven Werten unterscheiden zu können. Das Argument der Funktion trägt den Namen einer eingebauten Funktion (`hex()`), was man nicht machen sollte, weil es den Leser verwirren kann.
Da hätten wir wieder die Leserlichkeit. Schlecht gewählte Namen kann ich nicht abstreiten.
Die lokalen Namen in der Funktion sind teilweise auch nicht gut gewählt. Aus `h_len` und `hl` wird beim lesen nicht so leicht ersichtlich wofür die beiden gut sind. Kryptische Abkürzungen sollte man vermeiden. Auch `zwischenerg` sollte man ausschreiben. `hl` wird nicht wirklich benötigt, weil das mit `h_len` initialisiert wird und in der Schleife verringert wird, wärhrend `n` erhöht wird. Man kann den `hl`-Wert als in der Schleife problemlos aus `h_len` und `n` berechnen. `zahl` und `zwischenerg` werden vor der Schleife sinnlos auf 0 gesetzt. Dieser Wert wird nie irgendwo verwendet. Die Potenz von der 16 ist bereits eine Zahl, der `int()`-Aufruf dort ist überflüssig. Ebenso ist das bei den Ausdrücken mit `n` völlig sinnfrei. Zwischenstand:
Das alles ist aus einigen Stunden herumprobieren und ziemlich vielen Fehlern entstanden.
Deine Schrittweise Verkürzung des Skript'S ist wirklich sehr hilfreich und gut nachvollziehbar für mich. Auch hierfür Danke.
Nun wird `n` nur noch als Index in `hex_string` verwendet und das ist in Python ein „anti pattern“, weil man ohne den Umweg über einen Index über die Elemente von Sequenzen iterieren kann:
Das habe ich allerdings nicht so ganz verstanden!?

Code: Alles auswählen

 for hex_digit in hex_string:
Auch das ist mir noch unschlüssig, sowie die map()-Funktion.
Aber das zeigt nur, dass ich noch viel lernen muss.
Mir fehlt da eine Spalte und auch die sichtbaren sind nicht alle gleich ausgerichtet. Man sollte weder Grössen oder Positionen hart vorgeben, noch verhindern das Tk selber dafür sorgen kann, dass alles so viel Platz in der Anzeige bekommt wie es benötigt. Sonst sehen GUIs nur auf den Rechnern auf denen sie erstellt wurden vernünftig aus, oder es kann sogar passieren, dass die GUI nicht mehr bedienbar ist, weil Schaltflächen oder Anzeigeelemente gar nicht dargestellt werden. `grid()` hat Sirius3 ja bereits gezeigt.
Auch das ist nützlich zu wissen. Aber wie schon oben erwähnt, weiß ich noch nicht wofür die grid()-Funktion dient.

Vielen Danke für eure Hilfe und eure Zeitaufwendung! :)
Ich bin sicher ich habe mich nicht zum letzten mal an euch gewendet.

Gruß Kevin
BlackJack

@Kaewien: „Documentation Strings“ („docstrings“) haben einen gleichnamigen Abschnitt im Tutorial in der Python Dokumentation: https://docs.python.org/2/tutorial/cont ... on-strings

Und einen Eintrag im Glossar:
https://docs.python.org/2/glossary.html#term-docstring hat geschrieben:A string literal which appears as the first expression in a class, function or module. While ignored when the suite is executed, it is recognized by the compiler and put into the __doc__ attribute of the enclosing class, function or module. Since it is available via introspection, it is the canonical place for documentation of the object.
Das was man dort schreibt verarbeitet die `help()`-Funktion in der interaktiven Python-Shell, das Programm Pydoc macht daraus (hässliches :-)) HTML, und auch andere Dokumentationswerkzeuge können diese Texte aus dem Quelltext extrahieren und Dokumentation in verschiedenen Formaten (HTML, PDF, E-Book, …) erstellen.

Mit Hilfe von Docstrings kann man sich oft auch einen Blick in die Dokumentation sparen wenn einem eine kurze Beschreibung ausreicht. Um das mal auf Deine nächste Frage nach der `int()`-Funktion zu übertragen, dass hier sagt der Docstring von `int`:

Code: Alles auswählen

In [14]: print int.__doc__
int(x[, base]) -> integer

Convert a string or number to an integer, if possible.  A floating point
argument will be truncated towards zero (this does not include a string
representation of a floating point number!)  When converting a string, use
the optional base.  It is an error to supply a base when converting a
non-string.  If base is zero, the proper base is guessed based on the
string content.  If the argument is outside the integer range a
long object will be returned instead.
Die Dokumentation von `int()` geht etwas ausführlicher auf das `base`-Argument ein.

Zum „anti pattern“: `i` ist hier überflüssig…

Code: Alles auswählen

In [17]: s = 'hallo'

In [18]: for i in range(len(s)):
   ....:     print s[i]
   ....: 
h
a
l
l
o
…weil man direkt über die Elemente von Sequenzen wie Zeichenketten, Listen, Tupeln, und so weiter, iterieren kann.

Code: Alles auswählen

In [19]: for character in s:
   ....:     print character
   ....: 
h
a
l
l
o
Antworten