Seite 1 von 1

Verständnisfrage Schleifen und Binäroperator

Verfasst: Sonntag 3. Juni 2018, 10:43
von DrRocket
Hallo zusammen,

ich arbeite zurzeit paar Übungsaaufgaben durch und hänge seit nunmehr einem Tag an einem ansich trivialen Problem.

Aufgabe:
- String mit Zahlen wobei es immer eine Zahl gibt, die gerade (Rest ist dann ungrade) ist oder umgekehrt
- Ich soll die Stelle der Liste ausgeben, wo diese "Ausnahme" vorkommt (also der Key +1 für die einzige gerade oder ungerade Zahl in der Liste)

Vorgehen:
- String wird mit strip und split in eine Liste umgewandelt
- Liste in einer for Schleife durchlaufen und bestimmt, was die Ausnahme ist (gerade oder ungrade Zahl)
- Ausnahme wird mit neuer for Schleife herausgesucht und soll entsprechend ausgegeben werden
- Hierzu verwende ich den Bitoperator "&" mit Verbinung mit 1 oder 0, um zu prüfen, ob es sich um eine gerade oder ungerade Zahl handelt
- Die einzige gerade Zahl mit Index 1 (an der zweiten Stelle) wird nicht wie erwartet gefunden und ausgegeben.
- Obwohl also die Bedingung " if int(value) & 0:" true ist, wird der relevante Programmabschnitt dieser Bedingung im Fall der gerade Zahl in dem Beispiel nicht durchlaufen

hier mein Code:

Code: Alles auswählen

def test_werte(numbers):
    input_as_list = numbers.strip().split(" ")
    odd = 0
    even = 0
    intermediate_even = 0
    intermediate_odd = 0

    for element in input_as_list:
        if int(element) & 1:
            odd += 1
        else:
            even += 1

    print(odd, even)

    if odd > even:
        for key, value in enumerate(input_as_list):
            if int(value) & 0:
                intermediate_even = int(key) + 1
                print(intermediate_even)
    else:
        for key, value in enumerate(input_as_list):
            if int(value) & 1:
                intermediate_odd = int(key) + 1
                print(intermediate_odd)

test_werte("3 28 25 9 5 23 51 15 25 13 41 5 49 21 19 9 35 19 27")
Kann mir einer einen Tipp geben, was hier nicht stimmt?

Re: Verständnisfrage Schleifen und Binäroperator

Verfasst: Sonntag 3. Juni 2018, 11:30
von DrRocket
Konkret:

Warum wird die Bedingung "if int(value) & 0:" für value = "28" nicht erfüllt? Wenn ich das außerhalb der if Bedingung aufrufe, steht da ein true.

Re: Verständnisfrage Schleifen und Binäroperator

Verfasst: Sonntag 3. Juni 2018, 11:33
von sls
Gibt es einen Grund, warum du den Modulo-Operator nicht verwendest?

Eine Lösung könnte folgende sein, vorausgesetzt es gibt immer nur eine gerade oder ungerade Zahl:

Code: Alles auswählen

def test_werte(numbers):
    input_as_list = [int(i) for i in numbers.split(" ")]
    odd = even = 0
    for i in input_as_list:
        if i % 2 != 0:
            odd += i
        else:
            even += i

    if even > odd:
        print("Mehr gerade Zahlen vorhanden. Ausnahme {} an Position {}.".format(odd, input_as_list.index(odd) + 1))
    else:
        print("Mehr ungerade Zahlen vorhanden. Ausnahme {} an Position {}.".format(even, input_as_list.index(even) + 1))


test_werte("3 28 25 9 5 23 51 15 25 13 41 5 49 21 19 9 35 19 27")
test_werte("28 24 22 18 8 10 6 12 14 34 7 42 44 66 88 84 70 8 2")

Re: Verständnisfrage Schleifen und Binäroperator

Verfasst: Sonntag 3. Juni 2018, 12:00
von ThomasL
https://wiki.python.org/moin/BitwiseOperators

x & y " Does a "bitwise and". Each bit of the output is 1 if the corresponding bit of x AND of y is 1, otherwise it's 0."

Also int(irgendwas) & 0 liefert immer 0 zurück und 0 kann man als False interpretieren
Warum wird die Bedingung "if int(value) & 0:" für value = "28" nicht erfüllt? Wenn ich das außerhalb der if Bedingung aufrufe, steht da ein true.
Das kann imho nicht stimmen, s.o.

Re: Verständnisfrage Schleifen und Binäroperator

Verfasst: Sonntag 3. Juni 2018, 12:02
von sls
@DrRocket:

Probier's mal damit:

Code: Alles auswählen

    if odd > even:
        for key, value in enumerate(input_as_list):
            if int(value) & 1 == 0:
                intermediate_even = int(key) + 1
                print(intermediate_even)
    else:
        for key, value in enumerate(input_as_list):
            if int(value) & 1 == 1:
                intermediate_odd = int(key) + 1
                print(intermediate_odd)

Re: Verständnisfrage Schleifen und Binäroperator

Verfasst: Sonntag 3. Juni 2018, 14:13
von Sirius3
@DrRocket: Zum Vorgehen
- strip ist bei einem split ohne Argument überflüssig und hier solltest Du kein Argument verwenden, damit an beliebigem Leerraum gesplittet wird.
- es reicht ein Durchgang der Liste, wo Du einfach jeweils das erste Vorkommen der geraden und ungeraden Zahlen Dir merkst und außerdem, ob es mehrere davon gab.
- es ist immer die erste Bitstelle ›a & 1‹ die entscheidet ob eine Zahl gerade oder ungerade ist, je nachdem ob diese Operation 0 oder 1 ergibt.

Zum Code:
- Variablen sollten immer erst dann initialisiert werden, wenn sie auch gebraucht werden, eines von intermediate_even oder intermediate_odd wird z.B. nie gebraucht.
- `key` ist schon ein Int, die Umwandlung also unnötig.
- Funktionen, die etwas ausgeben, sind schlecht weiterzuverwenden, üblicherweise hat eine Funktion einen Rückgabewert.
- die zwei for-Schleifen sind fast identisch und könnten zu einer zusammengefasst werden.

Code: Alles auswählen

def test_werte(numbers):
    numbers = numbers.split()
    count = [0,0]
    position = [None, None]
    for index, value in enumerate(numbers):
        i = int(value) & 1  # 0 is odd, 1 is even
        count[i] += 1
        position[i] = index
    if count[0] == 1:
        # only one even number
        return position[0]
    elif count[1] == 1:
        # only one odd number
        return position[1]
    raise ValueError("not only one odd or even number found")

Re: Verständnisfrage Schleifen und Binäroperator

Verfasst: Sonntag 3. Juni 2018, 15:57
von DrRocket
Wow, danke für die vielen Rückmeldungen und Tipps! Die Anwendung der Bitoperatoren unterscheidet sich etwas von der Art, wie ich sie bis dato kenne.

@Sirius93: Danke für die ausgezeichnete Erklärung und die ganzen Tipps. Bin das Skript Schritt für Schritt durchgegangen und habe es jetzt auch vestanden :) Funktioniert einwandfrei. Musste nur bei dem Rückgabewert eine 1 addieren, um die tatsächliche Position zu erhalten und nicht den Index.

Re: Verständnisfrage Schleifen und Binäroperator

Verfasst: Sonntag 3. Juni 2018, 16:09
von narpfel
@DrRocket: Die Bitoperatoren funktionieren in Python wie in jeder anderen Sprache auch. Ich hab’ zumindest noch nichts anderes gesehen. Wo testet denn ein `& 0` eine Zahl darauf, dass sie gerade ist?