-1

When i get to the last voting section the code seems to continue into the next if statement and i cant seem to understand why it wont just print the last statement and stop? i've had a thorough check through the code and cant seem to find anything wrong especially with the last function as it is the same as the previous three. And is there any faster way to repeat code like this?

def presvote():
    with open("President.txt", "r+") as president:
        president = open("President.txt", "r")
        pres = [line.rstrip('\n', ) for line in open("President.txt")]
        print("Here is a list of the people running for president: ")
        print(pres)
        pvote1(pres)


def pvote1(pres):
    vote1 = input("Who would you like to vote for as the first choice?: ")
    if vote1 in pres:
        pres.remove(vote1)
        print(pres)
        pvote2(pres, vote1)
    else:
        print("That candidate is not running\nPlease enter a valid name")
        pvote1(pres)


def pvote2(pres, vote1):
    vote2 = input("Who would you like to vote for as the second choice?: ")
    if vote2 in pres:
        pres.remove(vote2)
        print(pres)
        pvote3(pres, vote1, vote2)
    if vote2 == vote1:
        print("That candidate has already been chosen, Please choose another")
        pvote2(pres, vote1)
    else:
        print("That candidate is not running please try again")
        pvote2(pres, vote1)


def pvote3(pres, vote1, vote2):
    vote3 = input("Who would you like to vote for as the third choice?: ")
    if vote3 in pres:
        pres.remove(vote3)
        print(pres)
        pvote4(pres, vote1, vote2, vote3)
    if vote3 == vote1 or vote2:
        print("That candidate has already been chosen, Please choose another")
        pvote3(pres, vote1, vote2)
    else:
        print("That candidate is not running please try again")
        pvote3(pres, vote1, vote2)


def pvote4(pres, vote1, vote2, vote3):
    vote4 = input("Who would you like to vote for as the fourth choice?: ")
    if vote4 in pres:
        pres.remove(vote4)
        print(pres)
        # print("Here is the list of your chosen candidates:\n",vote1,"\n",vote2,"\n",vote3,"\n",vote4)
    if vote4 == vote1 or vote2 or vote3:
        print("That candidate has already been chosen, Please choose another")
        pvote4(pres, vote1, vote2, vote3)
    else:
        print("That candidate is not running please try again")
        pvote4(pres, vote1, vote2, vote3)


presvote()```
Sir Shac
  • 3
  • 4
  • Does this answer your question? [How to test multiple variables against a value?](https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-against-a-value) – AMC Jan 20 '20 at 03:04
  • Why are you opening the same file 3 times in `presvote()`? – AMC Jan 20 '20 at 03:04

2 Answers2

0

The or statements are probably causing the issue

if vote4 == vote1 or vote2 or vote3 should be written as:

if vote4 == vote1 or vote4 == vote2 or vote4 == vote3

You'll need to do that for this line too if vote3 == vote1 or vote2

To make it a bit more efficient I downloaded the inflect library, to get the vote placement (i.e. 'First', 'Second', 'Third')

import inflect


def presvote():
   #with open("President.txt", "r+") as president:
        president = open("President.txt", "r")
        pres = [line.rstrip('\n', ) for line in open("President.txt")]
        print("Here is a list of the people running for president: ")
        print(pres) 
        votes = vote(pres)
        print(votes)


def vote(pres):
    votes = []
    p = inflect.engine()  # Start the inflect Engine
    while len(votes) <= 3:  # Will stop asking after 4 votes are placed.
        vote_no = len(votes) + 1
        vote_text = p.ordinal(vote_no)  # Get a string placement 
                                        # (i.e. 'First') based on number of votes
        vote = input("Who would you like to vote for as the {} choice?: ".format(vote_text))
        if vote in pres:
            pres.remove(vote)
            print(pres)
            votes.append(vote)
        else:
            print("That candidate is not running\nPlease enter a valid name")

    return votes
Nebulous29
  • 157
  • 9
0

@Nebulous29 has already touched on a major problem, and perhaps it isn't really worth spelling it out again (because this concept has been explained to death on countless other threads), but here's a refresher anyway.

In Python, strings (including other built-in collections, such as lists) have an implicit "truthyness". That means, when you ask for a string to be evaluated as a boolean (True or False), either implicitly or explicitly, it will evaluate to True if the string is non-empty, and False otherwise (if it is empty. Lists have a similar behavior.)

>>> bool("Hello")
True
>>> bool("HelloWorld")
True
>>> bool("ASDJHDASy3f289YHDUhasdjk3311")
True
>>> bool("")
False
>>> bool("[")
True
>>> bool("d")
True

Notice, the string literal "" is the only string which evaluates to False - because it is empty. All other strings are not empty. One would say this string is "Falsey".

This allows us to do things like this:

>>> string = "Hello"
>>> if string:
    print("We're in!")


We're in!

Implicitly, the string "Hello" is "truthy", because it is not empty, so we enter the body of the if-statement and execute the print-statement.

Taking this one step further (and this is where your code makes some mistakes):

>>> if string == "Something" or "Blah":
    print("We're in again!")


We're in again!
>>> 

String is "Hello", which is neither "Something" nor "Blah", but we still enter the body of the if-statement, so what gives? Let's evaluate this boolean expression as Python sees it:

  • string == "Something" becomes False, because string is not equal to "Something".
  • "Blah" becomes True, because the string literal "Blah" is non-empty, therefore truthy.

The entire condition therefore becomes:

if False or True:

Which evaluates to True, since only one parameter of an or-operation needs to be True in order for the output to be True.

is there any faster way to repeat code like this

It's good that you're using functions! However, functions are meant to reduce the amount of code you write, and yet, four of your functions do practically the same thing...

The four offending functions also use recursion to simulate a loop, which is a bad idea. For any program you write that uses recursion in this way, I can give you an input that would raise a RecursionError. You're better off just using loops:

def main():

    candidates = [
        "Bob",
        "Sam",
        "Tom",
        "Barry"
    ]

    print("Here are all the candidates running for president:")
    print(candidates)

    vote_number_names = [
        "first",
        "second",
        "third",
        "fourth"
    ]

    selected_candidates = []

    for vote_number in vote_number_names:
        while True:
            candidate = input(f"Who is your {vote_number} choice?: ")
            if candidate not in candidates:
                print("That candidate is not running.")
            elif candidate in selected_candidates:
                print("That candidate has already been selected.")
            else:
                break
        selected_candidates.append(candidate)

    print("Here are the candidates, in the order you picked:")
    print(selected_candidates)

main()

Output:

Here are all the candidates running for president:
['Bob', 'Sam', 'Tom', 'Barry']
Who is your first choice?: Bob
Who is your second choice?: jqedfkljdla
That candidate is not running.
Who is your second choice?: Bob
That candidate has already been selected.
Who is your second choice?: Tom
Who is your third choice?: Barry
Who is your fourth choice?: Sam
Here are the candidates, in the order you picked:
['Bob', 'Tom', 'Barry', 'Sam']
>>> 
Paul M.
  • 10,481
  • 2
  • 9
  • 15