Guten Abend!
Ich bin gerade dabei, ein "virtuelles" Hackspiel zu programmieren, das ausschließlich in der Shell abläuft. Nun habe ich mir ein Dictionary angelegt, in dem jeweils der Wert eines Ordners oder einer Datei das Parentverzeichnis ist. Nun soll man über "CD Ordner" in den Ordner gelangen:
ordner ist die Eingabe nach CD, self.comp das Dictionary, in welchem jeweils der Schlüssel ein/e Ordner/Datei und der Wert das Parentverzeichnis ist. self.path ist der Arbeitspfad links des blinkenden Cursors im Cmd.
if ordner in self.comp.keys() and self.comp[ordner]==self.path.split('/')[-2] and ordner.count('.')==0:
self.path+=ordner+'/'
Erst wird geprüft, ob ordner als Unterverzeichnis existiert, danach ob sein Parentverzeichnis dem aktuellen Arbeitsverzeichnis entspricht und dann, ob ordner keine Datei ist.
Das ganze funktioniert ja prima, wenn ich einfach alle Ordner im Dictionary groß bzw. klein schreibe und dann die Eingabe ordner auch per .upper() oder .lower() groß- bzw. klein mache. Doch wie sollte ich am klügsten vorgehen, dass ich die Groß- und Kleinschreibung als "Hacker" ignorieren kann, ohne meine Ordner nur aus Groß- oder Kleinbuchstaben zusammensetzen zu müssen? Natürlich könnte ich immer mit einer for-Schleife self.comp.keys() etc. vorübergehend lowern oder uppern, aber dies würde eine Menge Code produzieren.
Gibt es eine Möglichkeit, eine Liste bzw. ein Dictionary ähnlich .lower() und .upper() von der Schreibweise zu ändern oder ist es möglich, eine Bedingung in folgendem Format aufzustellen:
if re.compile(ordner, re.IGNORECASE) in self.comp.keys()...
Danke für euer Interesse,
Pythonierer!
list.lower() oder dict.upper() etc.
-
- User
- Beiträge: 41
- Registriert: Samstag 13. Januar 2007, 15:26
Danke audax für die Antwort, jedoch bringt mich letztere nicht wirklich weiter.
Einerseits benötige ich case-insensitive Kommandos, da es ja CMD simulieren soll, in welchem es nunmal so ist. Ich selbst finde case-sensitive Befehle auch viel besser, doch will ich nun mal die Windows System-Shell simulieren, nicht die von Linux.
Andererseits hilft auch der Tipp mit dem uppern des Userinputs nicht, da ja weiterhin die Ordner im Dictionary groß- bzw. klein geschrieben sind. Und dass ich letztere nicht auch standardisiert groß- bzw. klein schreiben will, hab ich ja schon erwähnt. Es soll eben alles wie in der cmd.exe ablaufen.
Ich hoffe, dass ihr noch ein paar kreative Ratschläge auf Lager habt und verbleibe mit freundlichen Grüßen,
Pythonierer!
Einerseits benötige ich case-insensitive Kommandos, da es ja CMD simulieren soll, in welchem es nunmal so ist. Ich selbst finde case-sensitive Befehle auch viel besser, doch will ich nun mal die Windows System-Shell simulieren, nicht die von Linux.
Andererseits hilft auch der Tipp mit dem uppern des Userinputs nicht, da ja weiterhin die Ordner im Dictionary groß- bzw. klein geschrieben sind. Und dass ich letztere nicht auch standardisiert groß- bzw. klein schreiben will, hab ich ja schon erwähnt. Es soll eben alles wie in der cmd.exe ablaufen.
Ich hoffe, dass ihr noch ein paar kreative Ratschläge auf Lager habt und verbleibe mit freundlichen Grüßen,
Pythonierer!
Wenn ich mich richtig erinnere, unterscheidet Windows - und damit auch cmd - nicht zwischen "verzeichnis" und "Verzeichnis". Demzufolge wäre es möglich, sowohl die Eingabe als auch den Verzeichnisnamen für den Vergleich (und nur dort) mit upper() oder lower() zu behandeln.
Code: Alles auswählen
class Directory (dict):
def __init__(self, *data):
super(Directory, self).__init__(data)
self.list = [i.upper() for i in self.keys()]
def __contains__(self, key):
return key.upper() in self.list
Code: Alles auswählen
>>my_dict = Directory(('foo', ['bar', 'foo']), ('bar', ['fooz']))
>>print my_dict.list
['FOO', 'BAR']
>>print 'FoO' in my_dict
True
>>print my_dict.keys()
['foo', 'bar']
Ja ich weiß, man müsste die Liste immer updaten...Aber meine Güte: Das kommt dann halt in die Funktionen Directory.mkdir() und Directory.addFile()
Mit einem `set()` statt einer Liste ist der ``in``-Test bei vielen Verzeichnissen schneller. Und `self.list` sollte einen Namen bekommen der ausdrückt wozu das Ding da ist, und nicht welchen Typ es hat. Würde bei einem `set` ja sowieso nicht mehr stimmen.
Auf `super()` würde ich verzichten. Zu kompliziert ohne echten Gewinn.
Auf `super()` würde ich verzichten. Zu kompliziert ohne echten Gewinn.
Bargh...Meckerbacke :p
Code: Alles auswählen
class Directory (dict):
def __init__(self, *data):
self.update(data)
self._upperKeys = set([i.upper() for i in self.keys()])
def __contains__(self, key):
return key.upper() in self._upperKeys
Code: Alles auswählen
In [2]: from directory import Directory
In [3]: my_dict = Directory(('foo', ['bar', 'foo']), ('bar', ['fooz']))
In [4]: print my_dict._upperKeys
set(['FOO', 'BAR'])
In [5]: print 'FoO' in my_dict
True
In [6]: print my_dict.keys()
['foo', 'bar']
Code: Alles auswählen
class Directory (dict):
def __init__(self, *data):
self.update(data)
self._upperKeys = set(i.upper() for i in self.keys())
def __contains__(self, key):
return key.upper() in self._upper_keys
Code: Alles auswählen
In [1]: from directory import Directory
In [2]: my_dict = Directory(('foo', ['bar', 'foo']), ('bar', ['fooz']))
In [3]: print 'FoO' in my_dict
True
€dit:
Grad gefunden: Seit 2.4
Genau genommen ist es `set((.. for .. in ..))`, womit analog zu List Comprehensions runde statt eckiger Klammern verwendet werden. Allerdings können die inneren runden Klammern entfallen, sofern - wie eben bei bei Übergabe an Callables - äußere runde Klammern vorhanden sind.