Endlos schleife

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Joe-Waschl
User
Beiträge: 20
Registriert: Freitag 12. November 2010, 20:18

hi zusammen,
ich habe ein kleines problem, komm aber nicht drauf wo der hacken ist.
In meinem Programm sind 2 Funktionen, die jenachdem auf welchem system sie gestartet wurden
ausgeführt wird, also einmal Linux und Win.
System erkennung habe ich mit dem modul sys erreicht. (sys.platform)
Wenn ich das Programm unter win7 starte dann führt er auch die entsprechende Funktion aus (main_win32), jedoch
in einer endlos schleife :( ich find den fehler nicht warum er das macht, vllt sehe ich vor lauter Bäumen den Wald nicht mehr.
Unter Linux läuft alles ohne probleme
Das programm is noch nicht kompett fertig, befehle für win7 etc ...

Gruß Joe

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
Created on 06.06.2012

@author: user1
'''

import os
import subprocess
import sys

#anzeigen    = '\nls rezepte\n'
#anzeigen    = None
loeschen    = 'rm rezepte/%s'
erstellen   = 'gedit rezepte/%s'
pfad        = os.getcwd()
pfad2       = 'rezepte/'
system	    = sys.platform


def main_linux2(): # Linux Funktion
    
    anzeigen    = '\nls rezepte\n'
    
    while True:
        
        print '\033[33m \n1 = alle Rezepte anzeigen'
        print '2 = Rezept erstellen'
        print '3 = suchen'
        print '4 = ein Rezept anzeigen'
        print '5 = Löschen'
        print '0 = \033[31mBeenden\033[m'
        
        eing = raw_input('\nwas möchten sie tun?: ')
        
        if eing == '0':
            print '\033[36mENDE\033[m'
            sys.exit()
            
        elif eing == '1':
            #os.system(anzeigen)
            for entry in os.listdir('rezepte/'):
                print entry
            
            
        elif eing == '2':
            name = raw_input('bitte Namen für das Rezept eingeben: ')
            os.system(erstellen % name)
            
            
        elif eing == '3':
            suche = raw_input('suche: ')
            if os.path.exists(os.path.join(pfad2, suche)):
                print 'vorhanden'
                eing = raw_input('Rezept öffnen?\033[31m(ja/nein)\033[m:')
                
                if eing == 'ja':
                    subprocess.Popen(['gedit', suche])
                    
                elif eing == 'nein':
                    continue
                    
                elif eing == len(''):
                    print 'eingabe nicht erkannt'
                    continue
                
                
            else:
                print '\033[31mnicht vorhanden\033[m'
                
            
                
        elif eing == '4':
            name = raw_input('welches Rezept möchten sie öffnen?: ')
            subprocess.Popen(['gedit', name])
            
            
        elif eing == '5':
            name = raw_input('welches Rezept möchten sie Löschen?: ')
            os.system(loeschen % name)
            
            
        else:
            print '\033[31meingabe nicht erkannt!\033[m'

def main_win32(): # Windows Funktion
    
        anzeigen = '\ndir rezepte'
            
        while True:
        
            print '\n1 = alle Rezepte anzeigen'
            print '2 = Rezept erstellen'
            print '3 = suchen'
            print '4 = ein Rezept anzeigen'
            print '5 = Loeschen'
            print '0 = Beenden'
        
        eing = raw_input('\nwas möchten sie tun?: ')
        
        if eing == '0': 
            print 'ENDE'
            sys.exit()
            
        elif eing == '1': 
            #os.system(anzeigen)
            for entry in os.listdir('rezepte/'):
                print entry
            
            
        elif eing == '2':
            name = raw_input('bitte Namen für das Rezept eingeben: ')
            os.system(erstellen % name)
            
            
        elif eing == '3':
            suche = raw_input('suche: ')
            if os.path.exists(os.path.join(pfad2, suche)):
                print 'vorhanden'
                eing = raw_input('Rezept öffnen?(ja/nein)')
                
                if eing == 'ja':
                    subprocess.Popen(['gedit', suche])
                    
                elif eing == 'nein':
                    pass
                    
                elif eing == len(''):
                    print 'eingabe nicht erkannt'
                    pass
                
                
            else:
                print 'nicht vorhanden'
                
            
                
        elif eing == '4':
            name = raw_input('welches Rezept möchten sie öffnen?: ')
            subprocess.Popen(['gedit', name])
            
            
        elif eing == '5':
            name = raw_input('welches Rezept möchten sie Löschen?: ')
            os.system(loeschen % name)
            
            
        else:
            print 'eingabe nicht erkannt!'


    
if sys.platform.startswith('linux2'):
    main_linux2()
    
elif sys.platform.startswith('win32'):
    main_win32()
    
else:
    print 'fehler!!! Platform nicht erkannt'
    print 'Windows oder Linux?'
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Erst einmal ist eine grundsätzliche Anmerkung zum Code fällig. Es kommt durchaus vor, dass für unterschiedliche Betriebssysteme unterschiedlicher Code erforderlich ist. Die logische Lösung ist es dann, den betriebssystemabhängigen Code gezielt an der benötigten Stelle aufzurufen. In deinem Programm doppelst du aber alles, selbst die Ausgabe des Auswahlmenüs. Zudem verwendest du bisweilen Kommandos des Betriebssystems ohne dass das erforderlich wäre. Aus Python heraus ein rm aufzurufen statt das in der Standardbibliothek vorhandene os.remove() zu verwenden ist unnötig komplex und fehlerträchtig.

Kurz und knapp: Das ist Mist, bau das um.

Kommen wir jetzt zu dem eigentlichen Fehler: Schau dir mal an, was die while-Schleife in deinem Windows-Block umfasst - und vor allem was nicht.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Als Ergänzung zu /me verweise ich auch noch auf ein Tutorial in unserem wiki: Textmenüs erstellen :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Code: Alles auswählen

def main_win32(): # Windows Funktion
    
        anzeigen = '\ndir rezepte'
            
        while True:
        
            print '\n1 = alle Rezepte anzeigen'
            print '2 = Rezept erstellen'
            print '3 = suchen'
            print '4 = ein Rezept anzeigen'
            print '5 = Loeschen'
            print '0 = Beenden'

        # ...
Im while-True-Block sind nur print-Statements enthalten, nichts anderes. Du hast also eine Endlosschleife und in dieser Endlosschleife werden Sachen ausgegeben. Vielleicht ist es durch die Code-Verkürzung für dich deutlicher geworden und du hast einfach den Überblick verloren.
Joe-Waschl
User
Beiträge: 20
Registriert: Freitag 12. November 2010, 20:18

erst mal danke für die schnelle antwort :)

@ /me: danke werd ich gleich machen, wenn ich mir den code nochmal anschaue dann ist es schon Logisch, fast alles doppelt :oops:
werds gleich ändern.

@ Hyperion: danke werds gleich mal anschauen :)

@ derdon: ja jetzt sehe ichs :roll: danke
wie gesagt, vor lauter Bäume den Wald nicht gesehn

gruß Joe
Joe-Waschl
User
Beiträge: 20
Registriert: Freitag 12. November 2010, 20:18

moin,

so habs jetzt geändert, funktioniert auch soweit alles :)
und dürfte auch kein code doppelt sein.
einzige problem ist, das er unter win7 die umlaute nicht richtig anzeigt,
statt äö wird ein Divisions zeichen angezeigt :roll:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: iso-8859-15 -*-

'''
Created on 24.07.2012
Version: 2.0
@author: user1
'''

import os
import sys
import subprocess


system  = sys.platform
pfad    = 'rezepte/'

def anzeigen():
    for entry in os.listdir('rezepte/'):
        print entry
    
def oeffnen():
    if system == 'linux2':
        editor = 'gedit rezepte/%s'
    else:
        editor = 'notepad.exe rezepte\%s'
        
    name = raw_input('welches Rezept möchten Sie öffnen?: ')
    
    if os.path.exists(os.path.join(pfad, name)):
        if system == 'linux2':
            os.popen(editor % name)
        else:
            os.system(editor % name)
    else:
        print 'nicht vorhanden'
        
def erstellen():
    if system == 'linux2':
        erstellen = 'gedit rezepte/%s'
    else:
        erstellen = 'notepad.exe rezepte/%s'
        
    name = raw_input('Namen für das Rezept eingeben: ')
    os.system(erstellen % name)

def suchen():
    if system == 'linux2':
        editor = 'gedit'
    else:
        editor = 'notepad'
        
    suche = raw_input('suche: ')
    if os.path.exists(os.path.join(pfad, suche)):
        print 'vorhanden'
        eing = raw_input('Rezept öffnen (ja/nein)?: ')
        if eing == 'ja':
            subprocess.Popen([editor, suche])
        elif eing == 'nein':
            pass
        elif eing == len(''):
            print 'eingabe nicht erkannt'
            pass
    else:
        print 'nicht vorhanden'

def loeschen():
    name = raw_input('welches Rezept möchten sie Löschen?: ')
    eing = raw_input('sicher Löschen? (ja/nein): ')
    if eing == 'ja':
        os.remove('rezepte/%s' % name)
    else:
        pass
    
def beenden():
    print 'ENDE'
    sys.exit()

menu = [
        ['Beenden', beenden],
        ['Alle Rezepte anzeigen', anzeigen],
        ['Ein Rezept öffnen', oeffnen],
        ['Erstellen', erstellen],
        ['Suchen', suchen],
        ['Löschen', loeschen]
        
        ]




def handle_menu(menu):
    while True:
        for index, item in enumerate(menu):
            print '{} {}'.format(index, item[0])
        choice = int(raw_input('\nBitte Zahl eingeben: ')) 
        if choice < len(menu):
            menu[choice][1]()
        else:
            print 'Eingabe nicht erkannt!'
        
if __name__ == '__main__':
    handle_menu(menu)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Joe-Waschl hat geschrieben: und dürfte auch kein code doppelt sein.
Hm... das springt einen doch an!

Code: Alles auswählen

    if system == 'linux2':
        editor = 'gedit rezepte/%s'
    else:
        editor = 'notepad.exe rezepte\%s'
;-)

Und zudem kommt dann weiter unten noch mal etwas ähnliches. Du solltest das irgend wo global hinterlegen; oder zu Beginn (in der `main` feststellen und dann als Parameter durch reichen).

Wobei ich den Aufruf eines fixen Editors auch nicht besonders glücklich finde - ich habe kein gedit installiert ;-) Unter Linux wird es da schwer, da es keinen Standard-(GUI)-Editor gibt.

Zum Thema Umlaute verweise ich auf die Links in meiner Signatur. Du gibst vermutlich eine falsche Codierung aus... Unter Windows wird doch dieses "cp1251" (?) verwendet o.ä. Du codierst sie aber in einem ISO-Format - sofern Du die Datei auch wirklich in diesem Encoding gespeichert hast...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Joe-Waschl
User
Beiträge: 20
Registriert: Freitag 12. November 2010, 20:18

ok, ich werds versuchen :)

das mit den umlauten haut irgendwie nicht hin, mal schauen, vllt klappts ja noch ;)
Malachite
User
Beiträge: 34
Registriert: Sonntag 24. Juni 2012, 13:43
Wohnort: Berlin

Hyperion hat geschrieben:Wobei ich den Aufruf eines fixen Editors auch nicht besonders glücklich finde - ich habe kein gedit installiert ;-) Unter Linux wird es da schwer, da es keinen Standard-(GUI)-Editor gibt.
Da müsste man eben die gängigen Editoren durchgehen und wenn keiner davon installiert ist, den User fragen:

Code: Alles auswählen

import sys
import os

checkTpl = 'which %s'
editorNotFound = "Kein grafischer Texteditor gefunden. Bitte bestimmen Sie einen: "

# Linux
if sys.platform.startswith('linux'):
    for editor in ('gedit', 'kate', 'mousepad', 'leafpad', 'gvim', 'xemacs'):
        if not os.system(checkTpl % editor): # which gibt 0 (erfolgreich) zurück
            break # editor wurde der richtige Befehl zugewiesen
    else:
        editor = raw_input(editorNotFound)
# Windows
elif sys.platform.startswith('win'):
    editor = 'notepad.exe'
# Mac OS X
elif sys.platform.startswith('darwin'):
    editor ='dontknow' # ich weiß zwar, dass das Teil TextEdit heißt, aber nicht, wie man es aufruft
else:
    editor = raw_input(editorNotFound)
BlackJack

Ich würde unter Linux als erstes ``xdg-open`` probieren. Dann wird der Editor beziehungsweise das Programm verwendet, dass der Anwender in seiner Desktop-Umgebung eingestellt hat. Ich habe zum Beispiel ein KDE-System, aber trotzdem auch ``gedit`` installiert, obwohl ich ``kate`` vorziehe.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Man kann mich altmodisch nennen, aber von einem Konsolenprogramm erwarte ich eigentlich nicht, dass es mir einen Editor öffnet! Das kann man dann doch auch per Hand machen.

Wenn schon, würde ich ein GUI-Programm draus stricken und dem eine Editor-Komponente mitgeben.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Joe-Waschl
User
Beiträge: 20
Registriert: Freitag 12. November 2010, 20:18

moin,

@ Malachite: Gute idee, darauf bin ich noch nicht gekommen, danke :)

@ BlackJack: werds versuchen einzubauen, thx

@ Hyperion: Mit GUI - Programmen habe ich mich noch nicht befasst :oops: , wäre aber mein nächster schritt gewesen.

Gruß Joe
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Joe-Waschl hat geschrieben: @ Hyperion: Mit GUI - Programmen habe ich mich noch nicht befasst :oops: , wäre aber mein nächster schritt gewesen.
Sollte man als Anfänger auch nicht wirklich ;-) Konzentriere Dich doch lieber erst einmal auf die Grundlagen. Dein Script macht ja nicht viel mehr als "Rezepte" in einem externen Editor anzuzeigen.

Versuche Dich doch eher auf Metainformationen zu Rezepten zu konzentrieren. Evtl. gibt es sogar spezielle Formate für Rezepte, die man nutzen könnte? Also Suche nach Stichwörtern, Bewertung, "gekocht"-Zähler, usw. eben eine richtige "Datenbank" mit Infos zu den Rezepten. Dabei lernst Du sicherlich mehr, als wenn Du alle Eventualitäten von Editoren auf Plattformen runter programmierst...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Joe-Waschl
User
Beiträge: 20
Registriert: Freitag 12. November 2010, 20:18

ja das stimmt natürlich,
werds mir zu herzen nehmen ;)
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für einen Texteditor im Terminal dürfte unter einigen Linux-Systemen (inkl. Ubuntu) übrigens die Nutzung des Kommandos `editor` ausreichen. Das öffnet bei mir z.B. automatisch `nano`. Falls später zwischen Ansehen und Bearbeiten unterschieden werden soll, würde ich hinsichtlich des Ansehen sogar eher das Kommando `pager` empfehlen, welches in den meisten Fällen `less` benutzen wird.

Analoge Funktionalität unter Windows erhält man mittels os.startfile(), wo man auch explizit "edit" mitgeben kann, um eine Datei im Editor (hier natürlich in der GUI) öffnen zu lassen. Wieviele Nutzer von Kochrezept-Programmen unter Windows einen anderen Standard-Editor als Notepad eingestellt haben, weiß ich allerdings nicht... ^^
Antworten