Problem mit Überprüfung auf Umlaute

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.
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Problem mit Überprüfung auf Umlaute

Beitragvon Evil4President » Mittwoch 21. Mai 2008, 17:27

Hallo Leute,

ich habe noch ein einziges kleines Problem mit meinem Programm.
Und zwar:
Ich überprüfe einen eingegebenen Text auf ungültige Zeichen etc. Allerdings sind in meiner Überprüfung bisher keine Umlaute gültig. Daher habe ich eine Liste

Code: Alles auswählen

Umlaute=['Ä','ä','Ü','ü','Ö','ö']

erstellt sowie eine Zeichenliste...
Hier mal der Teil der Abfrage...

Code: Alles auswählen

word=wort_eingabe.get()
        for i in range(0,length_w):
            if not(word[i]>='a' and word[i]<='z'):
                if not(word[i]>='A' and word[i]<='Z'):
                    if word[i] != ' ':
                        if word[i] not in Zeichen:
                            if word[i] not in Umlaute:
                                raise
        else:
            WORT=word
            wort_eingabe.config(state=DISABLED)
    except:
        showerror('Fehler!!!',u'Sie dürfen keine Sonderzeichen außer den folgenden eingeben!\n{     , ; . : ? ! " & / ( )     }')
        WORT=''
        wort_eingabe.delete(0,END)


Die Variable "length_w" ist hier die Länge des eingegebenen String. So wie es jetzt ist, sind Umlaute angeblich ungültig, d.h. er springt zu except.
Bitte nicht meckern, weil der Teil mit den if's wahrscheinlich schöner gehen würde. Es geht über diesen Teil alles außer die Umlaute; sobald ich diese Liste mit zur Prüfung einbeziehe und einen Umlaut eingebe, erscheint die Fehlermeldung.
Wäre schön, wenn mir jemand helfen könnte.

MFG evil4president
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Re: Problem mit Überprüfung auf Umlaute

Beitragvon Leonidas » Mittwoch 21. Mai 2008, 17:32

Evil4President hat geschrieben:Wäre schön, wenn mir jemand helfen könnte.

Nimm reguläre Ausdrücke. Den Code verstehst du doch selbst in einer Woche nicht mehr.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
OldBoy
User
Beiträge: 34
Registriert: Samstag 12. Januar 2008, 20:39

Beitragvon OldBoy » Mittwoch 21. Mai 2008, 18:27

Keep it simple, es geht auch ohne regex:

Code: Alles auswählen

import string

valid = set(string.ascii_letters + '������')

for c in word:
    if c in valid:
        print c, 'is valid'
    else:
        print c, 'is invalid'


Gruss

OldBoy
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Mittwoch 21. Mai 2008, 19:37

Warum hast du set benutzt? Es würde reichen, wenn es ein tuple ist oder sogar nur ein string...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Beitragvon Evil4President » Mittwoch 21. Mai 2008, 20:20

Habs jetzt mal versucht mit der ASCII-Liste....
Entweder verknüpf ich dauernd meine ASCII Liste falsch mit de Umlauten, oder ich mach sonstwas falsch.

Code: Alles auswählen

valid = [string.ascii_letters]  #+Umlaute + 'Ü' + 'ü' + 'Ä' + 'ä' + 'Ö' + 'ö'#
for i in word:
            #if not(word[i]>='a' and word[i]<='z'):
                #if not(word[i]>='A' and word[i]<='Z'):
                    #if word[i] != ' ':
                        #if word[i] not in Zeichen:
                            #if word[i] not in Umlaute:
                                #raise
                            #raise
            if i in valid:
                WORT=word
                wort_eingabe.config(state=DISABLED)
            else:
                raise


Habe jetzt die valid-Liste schon auf allen mir denkbaren Weisen zusammengesetzt. Jedoch werden die Umlaute nie angenommen...
Rein mit der ASCII-Liste gehts auch nicht. Kann das eventuell an dem Entry-Widget liegen?
Ich habe schon versucht zu der Gültigkeitsliste die Umlaute einzeln zu addieren, die Liste Umlaute zu addieren. Alles ohne Erfolg.
Ich versteh das einfach nicht...
OldBoy
User
Beiträge: 34
Registriert: Samstag 12. Januar 2008, 20:39

Beitragvon OldBoy » Mittwoch 21. Mai 2008, 20:48

1. Umlaute im Programmtext

werden Umlaute im Programmtext verwendet muss am Programmanfang das Encoding einstellen (je nach Rechner z.B. 'cp1252', 'mac-roman', 'iso8859-1' etc.)

Code: Alles auswählen

# -*- coding: <encoding-name> -*-

umlaut = 'äöüÄÖÜ'


2. warum verwende ich set

geht (in diesem Fall etwas) schneller. Das Suchen in einem String oder einer Liste dauert länger wenn String/Liste sehr lang sind. Das Suchen in einem Set ist immer gleich schnell

3.

ich will überprüfen, ob ein einzelner Buchstabe gültig ist:

if c in valid: ...

möglich:

valid = set(string.ascii_letters) ist ein Set von einzelnen Buchstaben
valid = list(string.ascii_letters) ist eine Liste von einzelnen Buchstaben
valid = string.ascii_letters ist ein einzelner String, in dem ich aber auch problemlos suchen kann

nicht möglich:

valid = [string.ascii_letters] ist eine Liste mit nur einem Element, und dieses ist derString aller Buchstaben.

HTH

OldBoy
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 21. Mai 2008, 20:48

So wird das nicht funktionieren, da bei dir valid eine liste ist. Nimm die Klammern weg, dann wird auch innerhalb string.ascii-letters gesucht 8also das was du eigentlich vor hast).
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Beitragvon Evil4President » Mittwoch 21. Mai 2008, 21:29

So, habe das mit der Liste schonmal behoben, vielen Dank für die Erklärung, wieso es dort nicht ging, habe das nicht berücksichtigt.
Meine valid-Liste sieht jetzt so aus (Das coding war übrigens schon drin).

Code: Alles auswählen

#-*- coding: cp1252 -*-
import string
valid = string.ascii_letters + 'ÜüÄäÖö'

Allerdings werden immernoch keine Umlaute akzeptiert.
Ich bin ratlos... Desweiteren hätte ich noch ein kleines weiteres Problem, was allerdings evtl behoben wird wenn die Umlaute akzeptiert werden...
Nachdem meine Fehlermeldung über die errorbox angezeigt wird, erscheint in der IDLE immer der Traceback, dass der Buchstabe (in meinem Fall speziell der eingegebene Umlaut) nicht im vorgegebenen Wertebereichs des ASCII Codes liegt...

Code: Alles auswählen

for a in range(0,length_w):
        if 90<(ord(WORT[a])+zahl)<97:

Allerdings habe ich noch einen "elif" ergänzt, der abfrägt, ob der Buchstabe in der Liste Umlaute liegt... Dann tritt eine andere Operation ein... Jedoch verbleibt der Ablauf immer im angegebenen if...
Allerdings wäre mir momentan wichtiger, dass ich die Umlaute überhaupt gültig einlesen kann.

MFG
BlackJack

Beitragvon BlackJack » Mittwoch 21. Mai 2008, 22:24

Wenn Umlaute im Spiel sind, sollte man IMHO auf Unicode setzen. Dieses Byteketten-Gefrickel mit `str()` fällt spätestens dann auf die Nase, wenn man Kodierungen verarbeiten will, bei denen nicht mehr ein Zeichen == ein Byte gilt.
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Beitragvon Evil4President » Mittwoch 21. Mai 2008, 22:35

Ich weiß, ich stelle mich wahrscheinlich gerade etwas dumm an, aber wie kann man die gesamten Strings auf Unicodezeichen umstellen? wenn es das ist, was du meinst...
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 22. Mai 2008, 01:50

Evil4President hat geschrieben:Ich weiß, ich stelle mich wahrscheinlich gerade etwas dumm an, aber wie kann man die gesamten Strings auf Unicodezeichen umstellen?

Vor alle Strungs ein ``u`` setzen. Etwa ``u"Hallo Welt"``.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Donnerstag 22. Mai 2008, 07:06

Evil4President hat geschrieben:Allerdings werden immernoch keine Umlaute akzeptiert.
Allerdings wäre mir momentan wichtiger, dass ich die Umlaute überhaupt gültig einlesen kann.


Aus deinem Code oben kann man schließen, dass du eine GUI mit Tkinter verwendest. Zeig doch mal den Codeausschnitt und den Traceback zu den Umlauten, dann kann dir konkreter geholfen werden.

Ohne GUI funktioniert es nämlich problemlos, z.B. so:

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-
import string

def neueszeichen(ch):
    # mach irgendwas mit dem Zeichen
    return "#"

zeichenvorrat = string.ascii_letters+"ÄÖÜäöü"
textalt = raw_input("Gib den Text ein: ")
textneu = ""
for ch in textalt:
    if ch in zeichenvorrat:
        ch = neueszeichen(ch)
    textneu += ch
print textneu


Ausgabe:

Code: Alles auswählen

Gib den Text ein: Bist du 17? Nöö, älter!
#### ## 17? ###, #####!
BlackJack

Beitragvon BlackJack » Donnerstag 22. Mai 2008, 08:41

@Pütone: Funktioniert aber auch nur wenn Skript-Kodierung und die Kodierung der Eingabe übereinstimmen und wenn es sich um eine Kodierung handelt, bei der jedes Zeichen durch ein Byte dargestellt wird.
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Beitragvon Evil4President » Donnerstag 22. Mai 2008, 08:56

Wie ich die Ausgabe als Unicode setze wusste ich, ich hab das so verstanden dass bem Auslesen des Entry-Feldes direkt als Unicode ausgelesen werden soll. Das weiß ich nicht...
Habe jetzt mal meine try und excepts rausgemacht. Vorher bekam ich nie einen Traceback, da der Fehler über mein except abgefangen wurde...
Muss ich mir mal merken, dass ich dann am besten die excepts mal wegmache, um das genauer aufzuschlüsseln.
Hier der Codeausschnitt und der Traceback:

Code: Alles auswählen

valid = string.ascii_letters + 'ÜüÄäÖö'
for i in word:
        if i in valid:
            WORT=word
            wort_eingabe.config(state=DISABLED)
        else:
            print 'Fehler'

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python25\lib\lib-tk\Tkinter.py", line 1403, in __call__
    return self.func(*args)
  File "C:/Users/Lukas/Schule/Informatik/20.05.2008/Hausaufgabe/Tests/Hausaufgabe ohne Zerlegung in Definitionen3.py", line 75, in chiffrieren
    if i in valid:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xdc in position 52: ordinal not in range(128)


Soweit ich das verstanden habe, kann er den eingegebenen Umlaut im Entry-Feld nicht verarbeiten und stößt deshalb auf diesen Fehler. Ich schätze man müsste wirklich einstellen, dass er den String direkt als Unicode einliest. Aber korrigiert mich, falls ich falsch liege.
Wäre gut, wenn mir jemand einen Tipp geben könnte, wie sich der Fehler beheben lässt.

MFG
BlackJack

Beitragvon BlackJack » Donnerstag 22. Mai 2008, 09:31

Es ist genau umgekehrt. Der Inhalt vom `Entry` kommt als Unicode-Objekt wenn ein Umlaut enthalten ist und `valid` macht Probleme, weil das *kein* Unicode ist.

Code: Alles auswählen

In [249]: valid = 'abc...aöü'

In [250]: u'a' in valid
---------------------------------------------------------------------------
<type 'exceptions.UnicodeDecodeError'>    Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

<type 'exceptions.UnicodeDecodeError'>: 'ascii' codec can't decode byte 0xc3 in position 7: ordinal not in range(128)


Wenn man Zeichenketten und Unicode-Objekte mischt, dann versucht Python die Zeichenkette in Unicode um zu wandeln und nimmt dabei ASCII als Kodierung an. Was zu der Ausnahme da oben führt, wenn die Zeichenkette etwas enthält, was nicht im ASCII-Zeichensatz enthalten ist.

Wer ist online?

Mitglieder in diesem Forum: martinjo