Noch ein Adressbuch

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Ferox
User
Beiträge: 48
Registriert: Dienstag 14. März 2006, 16:34

Noch ein Adressbuch

Beitragvon Ferox » Sonntag 6. Mai 2007, 18:04

Jaja, ich weis das ist alles nichts neues mehr. Aber jetzt wollte ich doch mal Fragen,
ob es noch etwas offensichtliches zu verbessern gibt(insbesondere Codeverkürzungen etc.)

Was ich noch machen wollte(und werde) ist:
- Hinzufügen von eigenen Gruppen
- Eine Detailsuche.

Den Online-Quellcode findet man hier
Die .py-Datei hier

Ich habe es schon ein wenig unter Linux getestet; bzw. soweit, dass ich Einträge gelesen habe^^
Ansonsten würde ich mich über ein Feedback freuen=)

mfg
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Beitragvon EnTeQuAk » Sonntag 6. Mai 2007, 19:03

Also ich habe mir noch lange nicht alles angeschaut, und ihn auch noch nicht komplett ausprobiert. Aber die ersten Zeilen schrecken mich schonmal ab:

Code: Alles auswählen

from Tkinter import *
from os import *
from sys import *


Solche Sternchenimporte sollte man vermeiden, wo es nur geht bzw. gar nicht anwenden... ohne Ausnahmen(?).

Die zweite Sache:

Wie du deinen Code um mehrere Hundert zeilen (hab nicht nachgezählt) verkürzen könntest... ganz einfach ;) nimm die komischen Kreize aus dem Code. Die haben meiner Ansicht nach nichts in einem Quellcode zu suchen.

MfG EnTeQuAk
Ferox
User
Beiträge: 48
Registriert: Dienstag 14. März 2006, 16:34

Beitragvon Ferox » Sonntag 6. Mai 2007, 19:11

Die komischen Kreuze sind zugegebener maßen etwas viele;
Sie dienen der groben Unterteilung. Das Erste befindet sich zwischen den kleinen Programmen, die im Wesentlichen der Vereinfachung dienen und den Definitionen zum Hinzufügen neuer Kontakte.
Die Zweite Kreuzfront(wenn ich das jetzt mal so nennen darf) liegt zwischen den Definitionen zum Hinzufügen und zum Suchen; danach folgen die Optionen und anschließend die Startsequenzen.
Dies hat den Vorteil, dass man sich (meiner Ansicht nach) beim schnellen Runterscrollen besser orientieren kann.

Zu den Sternchenimporten:
Normalerweise benutze ich die nur, wenn ich ein Modul sehr oft benötige(in diesem Falle wäre das Tkinter), die Sternchenimporte für sys und os nehme ich aber gerne sofort raus.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Sonntag 6. Mai 2007, 19:14

Hi Ferox!
Ich hab mal zusammengeschrieben, was ich auf den ersten Blick etwas komisch finde/nicht verstehe.
Ums nicht zu übertreiben schreibe ich deinen Code mal ohne Zitat-Tags.

Code: Alles auswählen

from Tkinter import *
from os import *
from sys import *

    global mf


-> lassen! (import Tkinter as tk ...)


Code: Alles auswählen

Versiontxt='0.9 Final'


-> etwas paradox, oder? Das es Final ist, sehe ich nicht, denn du stellst es ja hier zum Verbessern rein, und dann wäre 1.0 schon besser. Ein programm mit Final abzuschließen ist eh sonne Sache, denn du änderst eh immer noch mal was...

Code: Alles auswählen

    global mf
    try:
        mf.pack_forget()
    except:
        pass
    mf=Frame(hf, bg=sfarbe)

-> global lassen!
Besonders Tkintersachen, aber auch alle anderen komplexeren Strukturen solltest du in Klassen packen. Allein schon, um auf die ganzen Widgets und Variablen zugreifen zu können.

Code: Alles auswählen

sfarbe='black'#Standardfarbe1
sfarbe2='DarkSlateGrey'#Standardfarbe2
sforeground='white'#Vordergrundfarbe
buttonbg='black' #Button Hintergrundfarbe


-> wo nutzt du das? ich find nur sfarbe...guck dir mal tk_SetPallete() an.

Code: Alles auswählen

    if '#' in str(search):
        l=dtspeichern+"?"

-> Ich hab nicht das ganze Script verstanden, aber das sieht echt komisch aus.


Code: Alles auswählen

         #####                      #####
         #####                      #####
         #####                      #####
 #####################      #####################
#######################    #######################
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
         #####                      #####
          ###                        ###
           #                          #
[...]


-> was soll das? künstlerische Codeverlängerung?


Code: Alles auswählen

text=text.encode('cp1252').replace('|', '_/_/').replace('ä', '#ae/').replace('ö', '#oe/').replace('ü', '#ue/').replace('ß', '#ss/').replace('Ä', '#AE/').replace('Ö', '#OE/').replace('Ü', '#UE/')


-> Viel zu lange Zeilen
-> Nicht der beste Weg...

Code: Alles auswählen

           x=x+1

-> kürzer: x+= 1

Code: Alles auswählen

    Vorname=dc(vorname.replace('\n', ''))
    Nachname=dc(nachname.replace('\n', ''))
    Gruppe=dc(gruppe.replace('\n', ''))
    [...]


-> alles in eine Liste packen und eine Schleife drüberlaufen lassen (oder map nehmen)

Code: Alles auswählen

            try:
                mkdir(datapfad)
                y=0
            except:
                pass
            y=1

-> wenn du y eh auf eins setzt, kanst du dir die null vorher sparen, oder?

Auch die Spracheinträge solltest du in eine Liste oder in eine Textdatei auslagern und die dann mit der Variablenliste in
einer Schleife die variablen den Werten zuweisen.

Das ist, was mir grad so aufgefallen ist. Diesen Script ist das perfekte Ausgangsscript um codeverkürzung zu üben. Vlt. wär es einfacher einen zweiten Ansatz mit etwas mehr Struktur zu probieren.

Gruß, jj
Ferox
User
Beiträge: 48
Registriert: Dienstag 14. März 2006, 16:34

Beitragvon Ferox » Sonntag 6. Mai 2007, 19:47

Aaalso erstmal danke für die Antworten=)
Und jetzt der Reihe nach:

schlangenbeschwörer hat geschrieben:Hi Ferox!

Code: Alles auswählen

from Tkinter import *
from os import *
from sys import *

    global mf


-> lassen! (import Tkinter as tk ...)

Ich habe die Sternchenimporte von os und sys inzwischen ersetzt, den mit Tkinter werde ich im Laufe des Abends oder auch morgen noch ersetzen.

Code: Alles auswählen

Versiontxt='0.9 Final'


-> etwas paradox, oder? Das es Final ist, sehe ich nicht, denn du stellst es ja hier zum Verbessern rein, und dann wäre 1.0 schon besser. Ein programm mit Final abzuschließen ist eh sonne Sache, denn du änderst eh immer noch mal was...

Zugegeben, ja^^

Code: Alles auswählen

    global mf
    try:
        mf.pack_forget()
    except:
        pass
    mf=Frame(hf, bg=sfarbe)

-> global lassen!
Besonders Tkintersachen, aber auch alle anderen komplexeren Strukturen solltest du in Klassen packen. Allein schon, um auf die ganzen Widgets und Variablen zugreifen zu können.

Nun, da gibt es so ein Problem...Das Buch, welches ich hatte hat keine Klassen beschrieben :oops:

Code: Alles auswählen

sfarbe='black'#Standardfarbe1
sfarbe2='DarkSlateGrey'#Standardfarbe2
sforeground='white'#Vordergrundfarbe
buttonbg='black' #Button Hintergrundfarbe


-> wo nutzt du das? ich find nur sfarbe...guck dir mal tk_SetPallete() an.

Mach ich gerne. Dort sind die Standardfarben definiert. Da das Programm einen sehr "aufdringlichen" Farbstil hat, dachte ich mir, wär das doch schön wenn man den mit möglichst wenig Aufwand ändern könnte.

Code: Alles auswählen

    if '#' in str(search):
        l=dtspeichern+"?"

-> Ich hab nicht das ganze Script verstanden, aber das sieht echt komisch aus.

Dazu die erklärung:
Wenn man einen Eintrag bearbeitet, der schon existiert werden unter Add() zwei Buttons angezeigt:
Einer, um den Eintrag zu ändern und der andere, um den Eintrag als neuen Eintrag zu speichern.
Wenn der Eintrag als neuer Eintrag gespeichert werden soll, so wird ein "#" an den Pfad des gelesenen Eintrages drangehängt, damit dass Programm noch weis, welchen Eintrag es gerade vor sich liegen hat; l ist der Text, der später in der Messagebox angezeigt wird.
Zuletzt geändert von Ferox am Sonntag 6. Mai 2007, 19:49, insgesamt 2-mal geändert.
Ferox
User
Beiträge: 48
Registriert: Dienstag 14. März 2006, 16:34

Teil 2

Beitragvon Ferox » Sonntag 6. Mai 2007, 19:47

Code: Alles auswählen

         #####                      #####
         #####                      #####
         #####                      #####
 #####################      #####################
#######################    #######################
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
         #####                      #####
          ###                        ###
           #                          #
[...]


-> was soll das? künstlerische Codeverlängerung?

Dient dazu, sich beim schnellen runterscrollen schnell zurechtzufinden. (näheres siehe meinen Beitrag vorher)

Code: Alles auswählen

text=text.encode('cp1252').replace('|', '_/_/').replace('ä', '#ae/').replace('ö', '#oe/').replace('ü', '#ue/').replace('ß', '#ss/').replace('Ä', '#AE/').replace('Ö', '#OE/').replace('Ü', '#UE/')


-> Viel zu lange Zeilen
-> Nicht der beste Weg...

Okay, dass dachte ich mir auch aber weist du einen besseren?

Code: Alles auswählen

           x=x+1

-> kürzer: x+= 1

Danke=) hab ich ersetzt.

Code: Alles auswählen

    Vorname=dc(vorname.replace('\n', ''))
    Nachname=dc(nachname.replace('\n', ''))
    Gruppe=dc(gruppe.replace('\n', ''))
    [...]


-> alles in eine Liste packen und eine Schleife drüberlaufen lassen (oder map nehmen)

Was ist denn map?
Ich wollte erst mal den Code so übersichtlich wie möglich halten, um besser rumbearbeiten zu können. Aber guter Vorschlag, werd ich bei Gelegenheit machen=)

Code: Alles auswählen

            try:
                mkdir(datapfad)
                y=0
            except:
                pass
            y=1

-> wenn du y eh auf eins setzt, kanst du dir die null vorher sparen, oder?

Da haste irgendwie recht^^

Auch die Spracheinträge solltest du in eine Liste oder in eine Textdatei auslagern und die dann mit der Variablenliste in
einer Schleife die variablen den Werten zuweisen.

Das mit der Textdatei ist eine gute Idee. Bei der Liste hat man das Problem dass man im Programm dann nicht mehr ein dtSpeichern (für "Speichern") stehen hat, sondern z.B. ein liste[23], was nicht so aussagekräftig ist.

Das ist, was mir grad so aufgefallen ist. Diesen Script ist das perfekte Ausgangsscript um codeverkürzung zu üben.

Das hatte ich eigentlich nicht vor, aber jetzt weis ich, was ich als Hausaufgabe aufgeben, wenn ich mal Infolehrer werden sollte^^
Vlt. wär es einfacher einen zweiten Ansatz mit etwas mehr Struktur zu probieren.

Das hab ich mir schon sehr oft gedacht und dieses Programm schon sehr oft geschrieben, bis ichs irgendwann leid war(ich glaube, dieses hier ist der 3. oder 4. Anlauf)
Ferox
User
Beiträge: 48
Registriert: Dienstag 14. März 2006, 16:34

Re: Teil 2

Beitragvon Ferox » Sonntag 6. Mai 2007, 20:03

Ferox hat geschrieben:

Code: Alles auswählen

         #####                      #####
         #####                      #####
         #####                      #####
 #####################      #####################
#######################    #######################
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
        #######                    #######
         #####                      #####
          ###                        ###
           #                          #
[...]


-> was soll das? künstlerische Codeverlängerung?

Dient dazu, sich beim schnellen runterscrollen schnell zurechtzufinden. (näheres siehe meinen Beitrag vorher)

Code: Alles auswählen

text=text.encode('cp1252').replace('|', '_/_/').replace('ä', '#ae/').replace('ö', '#oe/').replace('ü', '#ue/').replace('ß', '#ss/').replace('Ä', '#AE/').replace('Ö', '#OE/').replace('Ü', '#UE/')


-> Viel zu lange Zeilen
-> Nicht der beste Weg...

Okay, dass dachte ich mir auch aber weist du einen besseren?

Code: Alles auswählen

           x=x+1

-> kürzer: x+= 1

Danke=) hab ich ersetzt.

Code: Alles auswählen

    Vorname=dc(vorname.replace('\n', ''))
    Nachname=dc(nachname.replace('\n', ''))
    Gruppe=dc(gruppe.replace('\n', ''))
    [...]


-> alles in eine Liste packen und eine Schleife drüberlaufen lassen (oder map nehmen)

Was ist denn map?
Ich wollte erst mal den Code so übersichtlich wie möglich halten, um besser rumbearbeiten zu können. Aber guter Vorschlag, werd ich bei Gelegenheit machen=)

Code: Alles auswählen

            try:
                mkdir(datapfad)
                y=0
            except:
                pass
            y=1

-> wenn du y eh auf eins setzt, kanst du dir die null vorher sparen, oder?

Da haste irgendwie recht^^

Auch die Spracheinträge solltest du in eine Liste oder in eine Textdatei auslagern und die dann mit der Variablenliste in
einer Schleife die variablen den Werten zuweisen.

Das mit der Textdatei ist eine gute Idee. Bei der Liste hat man das Problem dass man im Programm dann nicht mehr ein dtSpeichern (für "Speichern") stehen hat, sondern z.B. ein liste[23], was nicht so aussagekräftig ist.

Das ist, was mir grad so aufgefallen ist. Diesen Script ist das perfekte Ausgangsscript um codeverkürzung zu üben.

Das hatte ich eigentlich nicht vor, aber jetzt weis ich, was ich als Hausaufgabe aufgeben, wenn ich mal Infolehrer werden sollte^^
Vlt. wär es einfacher einen zweiten Ansatz mit etwas mehr Struktur zu probieren.

Das hab ich mir schon sehr oft gedacht und dieses Programm schon sehr oft geschrieben, bis ichs irgendwann leid war(ich glaube, dieses hier ist der 3. oder 4. Anlauf)


Und zu guter letzt die Überarbeiteten Programme:
Onlinecode
Datei
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Sonntag 6. Mai 2007, 20:11

Ferox hat geschrieben:Zu den Sternchenimporten:
Normalerweise benutze ich die nur, wenn ich ein Modul sehr oft benötige(in diesem Falle wäre das Tkinter), die Sternchenimporte für sys und os nehme ich aber gerne sofort raus.

Hallo Ferox!

Sternchenimporte (kurz *-Importe) haben ziemlich schwerwiegende Nachteile.

1.) Es können sich Namensraumüberschneidungen ergeben.

Code: Alles auswählen

from aaa import *
from bbb import *
ccc()

Woher kommt ``ccc()``? Was passiert, wenn in beiden Modulen ``ccc()`` vor kommt? Was passiert, wenn ich aus irgendeinem Grund später einmal ``aaa`` nach ``bbb`` importiere?. Denke an "Murphy´s Law".

Code: Alles auswählen

>>> help(open)
Help on class file in module __builtin__:

class file(object)
 |  file(name[, mode[, buffering]]) -> file object
 | 
 |  Open a file.  The mode can be 'r', 'w' or 'a' for reading (default),
 |  writing or appending.  The file will be created if it doesn't exist
 |  when opened for writing or appending; it will be truncated when
 |  opened for writing.  Add a 'b' to the mode for binary files.
 |  Add a '+' to the mode to allow simultaneous reading and writing.
 |  If the buffering argument is given, 0 means unbuffered, 1 means line
 |  buffered, and larger numbers specify the buffer size.
 |  Add a 'U' to mode to open the file for input with universal newline
 |  support.  Any line ending in the input file will be seen as a '\n'
 |  in Python.  Also, a file so opened gains the attribute 'newlines';
 |  the value for this attribute is one of None (no newline read yet),
 |  '\r', '\n', '\r\n' or a tuple containing all the newline types seen.
 | 
 |  'U' cannot be combined with 'w' or '+' mode.
 | 
 |  Note:  open() is an alias for file().

>>> from os import *
>>> help(open)
Help on built-in function open in module nt:

open(...)
    open(filename, flag [, mode=0777]) -> fd
   
    Open a file (for low level IO).

>>>

Komisch!? Warum funktioniert auf einmal der Code nicht mehr??? :twisted:

2.) Sternchenimporte setzen beim Leser des Codes voraus, dass dieser weiß was alles in den mit Sternchen importierten Modulen drin ist. Denn nur so lässt sich auch der Sinn mancher Programmzeile erahnen. Was jetzt, wenn ich nicht weiß aus welchem Modul eine Funktion importiert wurde? Ganz besonders Anfänger tun sich mit so einem Code extrem hart!

Das genügt. Auf mehr gehe ich gar nicht ein. Vermeide *-Importe wie die Pest. Setze sie nur dann ein, wenn sie wirklich Sinn ergeben. Und "Tkinter" kannst du auch so importieren:

Code: Alles auswählen

import Tkinter as tk

Die zusätzliche Schreibarbeit ("tk.") wird dir durch lesbareren Code vergolten, den du auch nach fünf Jahren noch in kürzester Zeit im Kopf interpretieren kannst.

mfg
Gerold
:-)
Zuletzt geändert von gerold am Sonntag 6. Mai 2007, 20:16, insgesamt 3-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Beitragvon BlackJack » Sonntag 6. Mai 2007, 20:13

Die lange Zeile mit den `replace()` kann man in eine Schleife über (Suchtext, Ersetzung) packen.

Das übliche Vorgehen für mehrsprachige Programme ist das `gettext`-Modul aus der Standardbibliothek zu benutzen.
Ferox
User
Beiträge: 48
Registriert: Dienstag 14. März 2006, 16:34

Beitragvon Ferox » Sonntag 6. Mai 2007, 20:21

Den Nachteil mit den *-Importen habe ich schon des Öfteren festgestellt. (Ursprünglich sollte delete() auch remove() heißen, was aber nicht ging aufgrund des os.remove())
Werd ich in Kürze auf Vordermann bringen.

Auch die Schleife werde ich dann einbauen.=)

mfg

Edit:
Die *-Importe sind jetzt schonmal weg(Link s.o)
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Montag 7. Mai 2007, 15:07

BlackJack hat geschrieben:Das übliche Vorgehen für mehrsprachige Programme ist das `gettext`-Modul aus der Standardbibliothek zu benutzen.

Hi BlackJack!
Bei Tkinteranwendungen kann man aber doch nicht mit gettext im mainloop dynamisch die Sprache ändern, oder? Man könnte natürlich alles speichern, den loop beenden und die __init__ nochmal mit der anderen Sprache aufrufen und in den mainloop schicken, aber das ist doch etws umständlich. Zudem gibts ja Labels mit 'text' und welche mit 'textvariable'n, die man eventuell auch wärend des Programms ändert. Und spätestens bei tix.Balloon (ok, nicht grade das häufigst genutzte Widget) wirds schwierig.

Gruß, jj
BlackJack

Beitragvon BlackJack » Montag 7. Mai 2007, 16:44

Die Sprache in einer laufenden Anwendung zu ändern ist sehr schwierig. Den Aufwand sollte man sich nicht antun. Da die wenigsten Leute ständig die Sprache ändern wollen, reicht es aber normalerweise auch aus, dass man entweder die Sprache des Systems nimmt, oder aus einer Konfigurationsdatei liest und den Anwender auffordert neu zu starten nachdem er die Sprache geändert hat.
Ferox
User
Beiträge: 48
Registriert: Dienstag 14. März 2006, 16:34

Beitragvon Ferox » Montag 7. Mai 2007, 17:27

Ich hab jetzt mal eine Definition zum Neustarten des Programms geschrieben, allerdings funktioniert die nur einmal; sprich:
Programm 1. mal gestartet-->1x Neustart gedrückt-->Nochmal Neustart drücken=Programm schließt sich.
Was ist falsch?

Code: Alles auswählen

def Neustartenx():
   try:
      subhf.destroy()
   except:
      pass
   try:
      hhf.destroy()
   except:
      pass
   try:
      hf.destroy()
   except:
      pass
   
   import ctl.py

(hf, hhf und subhf sind die verschiedenen Fenster)

Oder gibt es eine andere Möglichkeit, dass Programm neu zu starten?
BlackJack

Beitragvon BlackJack » Montag 7. Mai 2007, 17:45

Das Programm aus sich selbst heraus neu starten zu wollen ist falsch. Zumindest von der Idee und meinem Gefühl her. :-)

Ansonsten würde ich das Programm *wirklich* neu starten, also einen neuen Prozess mit `os.exec*()` starten.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Montag 7. Mai 2007, 17:52

Hi!
Importirst du im Modul das Modul selbst? Ist ja klar, das das nicht geht...
Ich würde wie gesagt, den mainloop und somit die Initialisierung neu starten. Da du das ganze jedoch nicht in eine Klasse gepackt hast, geht das nicht. Hättest du es gemacht (oder wenn du es noch machst), kannst du einfach den Mainloop stoppen, das Tk-Hauptfenster schließen, das Klassenobjekt zerstören und neu aufrufen. Das müsste eigentlich gehen - bei einer Klasse.
Gruß, jj

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder