Seite 1 von 1

Logische Verknüpfungen als Variable

Verfasst: Mittwoch 8. Januar 2014, 06:52
von basstscho
Hallo zusammen,

ich bekomme einen Vergleichsoperator aus einer Variable und muss diesen in eine logische Verknüpfung einbauen - wie geht das?

Code: Alles auswählen

varE = 1
varA = 1
varC = 2
vo = "=="
if varE==varA and varC==varA:
    pass

#Wie kann ich das mittels dem dynamischen logischen Operator in der Variable vo realisieren?
coStr = varE + vo + varA + " and " + varC + vo + varA
if doSomeMagic(coStr):
    pass
Danke euch,
Johannes

Re: Logische Verknüpfungen als Variable

Verfasst: Mittwoch 8. Januar 2014, 07:48
von Sirius3
@basstscho: Zu jedem Operator gibt es auch eine entsprechende Funktion. Diese sind im Modul »operator« zusammengefasst:

Code: Alles auswählen

import operator
varA = 1
varC = 2
vo = operator.eq
if vo(varA,varC):
    dosomething
Ich glaube aber nicht, dass das die optimale Lösung ist. Kannst Du Dein Problem noch näher beschreiben?

Re: Logische Verknüpfungen als Variable

Verfasst: Mittwoch 8. Januar 2014, 07:57
von anogayales
Hallo basstscho,

willkommen in Forum. Es gibt Wege wie du das in python realisieren kannst, sowie du es aber über Strings machst ist es sehr unüblich. Am besten sagst du uns was du eigentlich machen willst.

Falls du trotzdem das Ganze über Strings lösen willst musst du eine Abbildung konstruieren, die dir sagt welche String auf welchen Operator abbildet. So zum Beispiel:

Code: Alles auswählen

import operator

operator_mapping = {"==" : operator.eq,
			     "and" : operator.iand}

e = 1
a = 1
c = 2
vo = "=="
vi = "and"

result = operator_mapping[vi](operator_mapping[vo](c,a), operator_mapping[vo](e,a))
print result
Du siehst, dass du die Argumente nach dem Operator schreiben musst, du verlierst also die Infixnotation und nutzt stattdessen die Prefixnotation.

Den folgenden Abschnitt solltest du auf keinen Fall in produkivem Code verwenden! Er löst zwar das Problem, er dient lediglich zur Demonstration.

Code: Alles auswählen

result = eval("e {op1} a {op2} c {op1} a".format(op1="==", op2="and"))
print result
Grüße,
anogayales

Re: Logische Verknüpfungen als Variable

Verfasst: Mittwoch 8. Januar 2014, 08:01
von bwbg
Da Funktionen auch Objekte sind, kann man diese wunderbar in Datenstrukturen packen.

Hier bietet sich eine lookup-table an, welche Zeichenketten auf Funktionen abbildet.

Zusammen mit dem operator-Modul sähe das zum Beispiel so aus:

Code: Alles auswählen

 OPERATOR_LOOKUP = {
    '==': operator.eq,
    '+':  operator.add,
    # ...
    }
    
def main():
    a = 13
    b = 29
    print(OPERATOR_LOOKUP['=='](a, b))
    print(OPERATOR_LOOKUP['+'](a, b))
    
if __name__ == '__main__':
    main()
Edit: Zu langsam.

Wenn es sowas noch nicht gibt, sollte man eine PEP starten mit dem Ziel eval in evil umzubenennen.

Re: Logische Verknüpfungen als Variable

Verfasst: Mittwoch 8. Januar 2014, 08:56
von BlackJack
Und vor allem sollte man Leuten die man nicht einschätzen kann nicht gleich mit der Nase drauf stossen. :?

Re: Logische Verknüpfungen als Variable

Verfasst: Mittwoch 8. Januar 2014, 09:12
von anogayales
Lieber Leute davor explizit warnen, als dass sie selbst mit der Nase drauf stoßen und es gar in produktivem Code einsetzen, weil sie es nicht besser wissen.

Re: Logische Verknüpfungen als Variable

Verfasst: Mittwoch 8. Januar 2014, 09:27
von Sirius3
@anogayales: wie eine Warnung liest sich Dein Beitrag dazu aber nicht gerade.

Re: Logische Verknüpfungen als Variable

Verfasst: Mittwoch 8. Januar 2014, 10:02
von anogayales
Danke Sirius3, ich haben es nun deutlicher formuliert.

Re: Logische Verknüpfungen als Variable

Verfasst: Donnerstag 9. Januar 2014, 06:47
von basstscho
Hallo zusammen,

vielen Dank für eure zahlreichen Antworten. Nochmals kurz zum Hintergrund:
Ich habe in einer csv-Tabelle mehrere Spalten die für eine Variable stehen. In den Zeilen stehen dann jeweils Werte. Es soll nun überprüft werden welche Zeilen auf Grund des aktuellen Variablenstatus erfüllt sind und welche nicht. Zusätzlich kommt hinzu, dass in den Zellen zum Wert vorangestellt die Vergleichsoperatoren >, <, >=, <= stehen können.
Ich habe es nun mit einer Schleife gelöst die über sämtliche Werte in einer Zeile läuft und eine Unterfunktion aufruft die mit einem String-Vergleich überprüft welcher Operator zum Einsatz kommen soll (zunächst die mit zwei Zeichen, dann die mit einem und bei keinem (entsprich das ==)) und dann mittels der entsprechenden Operator-Funktion vergleicht. Bekomme ich einmal im Durchlauf ein False zurück, ist die ganze Zeile nicht erfüllt.

Somit kann ich vorab noch überprüfen ob die Eingabe Sinn macht und gehe nicht direkt aus der Benutzereingabe in den Vergleich.

Habt ihr noch ne bessere Idee?

Beste Grüße,
Johannes

Re: Logische Verknüpfungen als Variable

Verfasst: Donnerstag 9. Januar 2014, 08:42
von Sirius3
@basstscho: sehe ich das richtig, die Datei sieht so aus?

Code: Alles auswählen

123,>9,<=17
4,9,>23
Wer denkt sich denn sowas aus?

Code: Alles auswählen

import csv
import operator
from itertools import imap

OPERATORS = [
    ('<=', operator.le),
    ('>=', operator.ge),
    ('<>', operator.ne),
    ('!=', operator.ne),
    ('==', operator.eq),
    ('<', operator.lt),
    ('>', operator.gt),
    ('=', operator.eq),
    ('', operator.eq),
]

def split_operator(value):
    if isinstance(value, basestring):
        for symbol, operation in OPERATORS:
            if value.startswith(symbol):
                return float(value[len(symbol):]), operation
        raise RuntimeError('Internal Error')
    else:
        return float(value), operator.eq

def validate(values):
    values = iter(values)
    first = float(next(values))
    return all(operation(first, value)
        for value, operation in imap(split_operator, values))
    
def main():
    with open('datei.csv') as data: 
        for row in csv.reader(data):
            print validate(row)
    
if __name__ == '__main__':
    main()