IndexError: Creating two lists from a text file - python

I cannot figure why when I run my code I get an IndexError saying my list is out of range. I run into the error at “ if x[1] == "strongly agree": “. I’ve went through my code many times and I don’t know how to fix..
Here is my code(not including import):
firstList = [0, 0, 0, 0, 0]
secondList = [0, 0, 0, 0, 0]
with open("surveyData.txt", 'r') as f:
answers = f.read().split('\n')
for x in answers:
x = x.split(',')
if x[0] == "very happy":
firstList[0] += 1
elif x[0] == "happy":
firstList[1] += 1
elif x[0] == "neutral":
firstList[2] += 1
elif x[0] == "unhappy":
firstList[3] += 1
else:
firstList[4] += 1
if x[1] == "strongly agree":
secondList[0] += 1
elif x[1] == "agree":
secondList[1] += 1
elif x[1] == "neutral":
secondList[2] += 1
elif x[1] == "disagree":
secondList[3] += 1
else:
secondList[4] += 1
def showHistogram(dataList, bars):
plt.bars(bars, dataList)
plt.show()
question1_freq = ['very happy', ' happy', 'neutral', 'unhappy', 'very unhappy']
showHistogram(firstList, question1_freq)
question2_freq = ['strongly agree', 'agree', 'neutral', 'disagree', 'strongly disagree']
showHistogram(secondList, question2_freq)
Sample text file:
unhappy,strongly agree
very unhappy,strongly agree
happy,agree
neutral,strongly agree
happy,agree
very unhappy,strongly agree
neutral,strongly agree
very happy,disagree

Just change the below line and rest seems ok
answers = f.read().splitlines()

Related

Python Function "Not Defined" in VSCODE [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 days ago.
This post was edited and submitted for review 2 days ago.
Improve this question
class Hand:
def __init__(self, hand):
self.hand = hand
def rank_to_index_converter(rank):
if rank == 2:
return 0
elif rank == 3:
return 1
elif rank == 4:
return 2
elif rank == 5:
return 3
elif rank == 6:
return 4
elif rank == 7:
return 5
elif rank == 8:
return 6
elif rank == 9:
return 7
elif rank == 10:
return 8
elif rank == 'J':
return 9
elif rank == 'Q':
return 10
elif rank == 'K':
return 11
elif rank == 'A':
return 1
else:
raise ValueError
def suit_to_index_converter(suit):
if suit == 'C':
return 0
elif suit == 'D':
return 1
elif suit == 'H':
return 2
elif suit == 'S':
return 3
else:
raise ValueError
def is_consecutive(hand):
### BEGIN YOUR SOLUTION
first = 0
string = ""
count = 0
for x in hand:
#print(x[0])
if x[0] == ("J"):
if first != 10 and (count != 0):
return False
string = x[0]
elif x[0] == ("Q"):
if string != "J" and (count != 0):
return False
string = x[0]
elif x[0] == ("K"):
if string != "Q" and (count != 0):
return False
string = x[0]
elif x[0] == ("A"):
if string != "K" and (count != 0):
return False
string = x[0]
elif x[0] != ("J" or "Q" or "K" or "A"):
if (x[0] != (first + 1)) and (count != 0):
if (hand[0][0] != "A"):
return False
first = x[0]
count = count + 1
return True
def is_suit(hand):
suit = hand[0][1]
for x in hand:
if x[1] != suit:
return False
return True
def is_flush(hand):
return is_suit(hand) and not is_consecutive(hand)
def is_four_of_a_kind(hand):
count = 0
pair_num = 0
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
for x in lst:
if x == 4:
return True
return False
def is_full_house(hand):
count = 0
pair_num = 0
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
three_pair = False
pair = False
for x in lst:
if x == 3:
three_pair = True
if x == 2:
pair = True
if three_pair and pair:
return True
return False
def is_flush(hand):
count = 0
while count < (len(hand) - 2):
if hand[count][1] != hand[count + 1][1]:
return False
count += 1
return True
def is_straight(hand):
if is_consecutive(hand) and not is_suit(hand):
return True
return False
def is_three_of_a_kind(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
three_pair = False
for x in lst:
if x == 3:
three_pair = True
if three_pair and not is_full_house(hand) and not is_suit(hand):
return True
return False
def is_two_pair(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
two_pair = False
counter = 0
switch = 0
while counter != len(lst):
if lst[counter] == 2:
switch = 1
if lst[counter] == 2 & switch == 1:
two_pair = True
if two_pair and not is_full_house(hand) and not is_suit(hand) and not is_four_of_a_kind(hand) and not is_three_of_a_kind(hand):
return True
return False
def is_pair(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
pair = False
for x in lst:
if x == 2:
pair = True
if pair and not is_full_house(hand) and not is_suit(hand):
return True
return False
def maximum_value(hand):
sum = 0
for x in hand:
sum += rank_to_index_converter(x[0])
return sum
The is_full_house function uses the rank_to_index_converter function. The rank_to_index_converter function is defined above the is_full_house function. Why am I receiving an error that the rank_to_index_converter function is not defined?
I am lost on where to proceed; therefore, I haven't tried anything, besides copying and pasting the rank_to_index_converter function into the is_full_house function; however, it is more convenient if the rank_to_index_converter is a separate function. That is why I want to solve this issue.

IndexError: string index out of range - finding out if a letter is in a string

I am trying to code a piece such as the game mastermind, and I am having the IndexError telling me that my string index is out of range. Please ignore the notes in the hashtags - they're for me knowing what part of the assignment that I have completed. [further notes below :D]
#makes a random thingie
import random
l = 0
k = 0
m = 0
r = 0
x = "kkkk"
available_colours = ['G','Y','B','R']
x = list(x)
while l != 4:
random_colour = random.choice(available_colours)
x[l] = random_colour
l = l + 1
x = "".join(x)
#user inputs guesses
print(x)
print('there is a choice from these colours [G,Y,B,R]')
print('guess a pattern [xxxx]')
y = str(input())
while r != 5:
while m != 4:
for i in range (0,3):
if x[k] == y[k]:
m = m + 1
k = k + 1
else:
k = k + 1
#informs the user how many pins they have got correct
if m > 0:
print('You found', m, 'in the correct position')
else:
print('You have found none in the correct position.')
n = 0
o = 0
if m != 4:
if y[0] == x[1] or y[0] == x[2] or y[0] == x[3]:
o = o + 1
elif y[1] == x[0] or y[1] == x[2] or y[1] == x[3]:
o = o + 1
elif y[2] == x[0] or y[2] == x[1] or y[2] == x[3]:
o = o + 1
elif y[3] == x[0] or y[3] == x[1] or y[3] == x[2]:
o = o + 1
#informs the user how many pins they have got correct
if o > 0:
print('You found', o, 'correct letters, but not in the right place')
else:
print('You have found no correct letters in the wrong place')
#user knows they won
if k == 4:
print('You have won!')
else:
r = r + 1
if r == 5:
print('You have used all of your goes.')
else:
q = 5 - r
print('You have' , q ,' rounds left.')
The following error message is displayed:
Traceback (most recent call last):
File "main.py", line 32, in
if x[k] == y[k]:
IndexError: string index out of range
There is also another issue with the code where it will tell me there are 2 letters correct, but in the wrong place if i put that letter once in the pattern_guessed, and it is more than once in the pattern_random. Example:
pattern_random = GGYB
pattern_guessed = GYYB
The computer will tell me that there are 2 colours correctly guessed but not in the right space. However the main problem right now is trying to get the code to work.
Thank you for reading c:

Check if Player X or Player Y has won function/module. Tic Tac Toe

Hello ! I have a question guys.
I was writing my first serious python training project because I'm beginner but I encountered a problem that stops me from further development of my program.
I don't have idea how can I write function/module in my class that check if player X or player Y has won. I tried on so many different ways but it seems to not work. I know that the my code is looking awful. Thank you for your time spent.
import sys
class Tic_tac_toe():
def __init__(self):
self.board = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
'low-L': ' ', 'low-M': ' ', 'low-R': ' '}
self.move_X = None
self.move_0 = None
self.WINNING_MOVE = None
self.loop = None
self.nameX = None
self.nameO = None
self.choice = None
def welcome(self):
try:
print("Welcome ! :)\n\nWho is PLAYER X ? :")
self.nameX = input()
print("\nWho is PLAYER O ? :")
self.nameO = input()
print("\nHello {} and {}, ready to play? (Y/N) :".format(self.nameX.title(), self.nameO.title()))
self.choice = input()
if self.choice.title() == 'N' or '\n':
sys.exit()
print('\n{} is PLAYER X.\n{} is PLAYER Y.'.format(self.nameX.title(),self.nameO.title()))
except ValueError:
print('\nTry again:\n')
def printBoard(self):
print()
print(self.board['top-L'] + '|' + self.board['top-M'] + '|' + self.board['top-R'])
print('-+-+-')
print(self.board['mid-L'] + '|' + self.board['mid-M'] + '|' + self.board['mid-R'])
print('-+-+-')
print(self.board['low-L'] + '|' + self.board['low-M'] + '|' + self.board['low-R'])
print()
def moves_X(self):
try:
self.move_X = int(input("Player X :\nChoose field (1,9) : "))
self.write_on_boardX()
self.printBoard()
except ValueError:
print("\nYOU DIDN'T ENTER NUMBER !\n")
def moves_O(self):
try:
self.move_O = int(input("Player O :\nChoose field (1,9) : "))
self.write_on_boardO()
self.printBoard()
except ValueError:
print("\nYOU DIDN'T ENTER NUMBER!\n")
def mix_XO(self):
self.loop = 0
for x in range(1,10):
if self.loop % 2 == 0:
self.moves_X()
self.loop += 1
elif self.loop % 2 == 1:
self.moves_O()
self.loop += 1
def write_on_boardX(self):
if self.move_X == 1:
self.board['top-L'] = 'X'
elif self.move_X == 2:
self.board['top-M'] = 'X'
elif self.move_X == 3:
self.board['top-R'] = 'X'
elif self.move_X == 4:
self.board['mid-L'] = 'X'
elif self.move_X == 5:
self.board['mid-M'] = 'X'
elif self.move_X == 6:
self.board['mid-R'] = 'X'
elif self.move_X == 7:
self.board['low-L'] = 'X'
elif self.move_X == 8:
self.board['low-M'] = 'X'
elif self.move_X == 9:
self.board['low-R'] = 'X'
def write_on_boardO(self):
if self.move_O == 1:
self.board['top-L'] = 'O'
elif self.move_O == 2:
self.board['top-M'] = 'O'
elif self.move_O == 3:
self.board['top-R'] = 'O'
elif self.move_O == 4:
self.board['mid-L'] = 'O'
elif self.move_O == 5:
self.board['mid-M'] = 'O'
elif self.move_O == 6:
self.board['mid-R'] = 'O'
elif self.move_O == 7:
self.board['low-L'] = 'O'
elif self.move_O == 8:
self.board['low-M'] = 'O'
elif self.move_O == 9:
self.board['low-R'] = '0'
def winning_movesX(self):
pass
def main():
app = Tic_tac_toe()
app.welcome()
app.printBoard()
app.mix_XO()
main()
One way to achieve this is to first create a map of all the possible winning 'lines' and then see if the elements on that line are all the same, by creating a set and checking it contains only 1 item (X or O). For example:
lines = [
['top-L','top-M','top-R'],
['top-L', 'mid-L', 'low-L']
... etc ...
]
for line in lines:
if len(set(self.board[x] for x in line])) == 1:
print("Winner:", self.board[line[0]])
Different Approach might be easier...
A simpler way would be to use a 3x3 matrix, e.g. with:
0 as a default value
-1 for player 1
+1 for player 2
You can then calculate the sum of the rows/columns/diagonals. With -3 as a player 1 win, +3 as a player 2 win. For example by using numpy:
>>> import numpy as np
>>> np.zeros((3, 3), dtype=int)
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
=> self.board = np.zeros((3,3), dtype=int)
and a win check would roughly look like:
d1,d2 = 0,0 #used to calculate sum of diagonal
for i in range(3):
#check row
if sum(self.board[i, :]) in (3,-3):
self.win = True
#check column
elif sum(self.board[:, i]) in (3,-3):
self.win = True
#check diagonal
d1 += self.board[i, i] #diagonal from top left corner to bottom right corner
d2 += self.board[i, 2-i] #diagonal from top right corner to bottom left corner
elif d1 in (3,-3) or d2 in (-3,3):
self.win = True
Note: You know which player has won since you know who's turn it was last.
Well, and since you seem to be rather new to python here a quick overview on how to access elements of an array:
>>> board = np.zeros((3,3), dtype=int)
>>> board[0][1] = 3
>>> board
array([[0, 3, 0],
[0, 0, 0],
[0, 0, 0]])
And in case you keep this board:
"""
[1] | [2] | [3]
-----------------
[4] | [5] | [6]
-----------------
[7] | [8] | [9]
"""
you could use the integer division // and the modulo function % instead of all the elif statements to determine what field/position on the board the user meant:
position = int(input("Choose position:"))
row = (position-1)//3
column = (position-1)%3
self.board[row][column] = 1 #or -1
P.S.:
If you want to implement a "player vs. computer" later on, you might change the value -1 to -3 to get unique sum values. (-1 +1 +0 = 0 +0 +0)

Monty Hall simulator has a wrong outcome

I wanted to do something seemingly simple and at the same time prove Monty Hall by code, and sadly what I got was not a proof of the problem, but the complete opposite. No matter if I switch or not, I get ~33% odds of winning across 10000 simulations. Could you check the code and see what's wrong with it? Keep in mind that I'm a web-dev so my Python skills are not great and the code might not look fantastic (for example, I made a removable_doors list where just a variable would've worked fine). Cheers!
import random
av_doors = [1, 2, 3]
door_v = [1, 2, 3]
removable_doors = [1, 2, 3]
score = 0
loses = 0
door = int(input("Choose your door (1-3)"))
pick = int(door)-1
dec = input("Stay or switch? (0/1)")
n = 0
while n < 10000:
removable_doors = [1, 2, 3]
av_doors = [1, 2, 3]
val = random.randint(1,3)
if val == 1:
door_v[0] = 1
door_v[1] = 0
door_v[2] = 0
removable_doors.remove(1)
elif val == 2:
door_v[0] = 0
door_v[1] = 1
door_v[2] = 0
removable_doors.remove(2)
elif val == 3:
door_v[0] = 0
door_v[1] = 0
door_v[2] = 1
removable_doors.remove(3)
try:
removable_doors.remove(int(door))
except:
pass
av_doors.remove(door)
if len(removable_doors) == 2:
rand_door = random.randint(0,1)
if rand_door == 0:
del av_doors[0]
elif rand_door ==1:
del av_doors[1]
else:
del av_doors[0]
if dec == "1":
door = av_doors[0]
else:
pass
pick = door-1
if door_v[pick] == 1:
score+=1
else:
loses+=1
n+=1
print(score)
print(loses)
Your host sometimes removes a door with the car behind it... Here is a solution that works, and (I think) a bit better written, while keeping your structures (in python3 but that should not raise troubles):
import random
win = 0
lose = 0
switch = int(input("Stay or switch? (0-stay/1-switch):")) == 1
n = 0
while n < 10000:
# Init
door_values = [0, 0, 0]
removable_doors = [0, 1, 2]
available_doors = [0, 1, 2]
# Placing the reward somewhere
car_place = random.randint(0, 2)
door_values[car_place] = 1
removable_doors.remove(car_place)
# Choose a door
door_chosen = random.randint(0, 2)
available_doors.remove(door_chosen)
if door_chosen != car_place:
removable_doors.remove(door_chosen)
# Host removes a door that does not have the car and has not been chosen by the player
door_removed_by_host = removable_doors[random.randint(0, len(removable_doors)-1)]
available_doors.remove(door_removed_by_host)
# Switch if specified
if switch:
assert(len(available_doors) == 1)
door_chosen = available_doors[0]
# Check the result
if car_place == door_chosen:
win += 1
else:
lose += 1
n+=1
print('win=%s'%str(win))
print('lose=%s'%str(lose))
print('ratio=%s'%str(win/(win+lose)))
It gives me 0.3332 when switch=False, 0.6738 for switch=True, I guess this rather confirms Monty Hall's solution :)

Iterating through list (Python)

I have a list that extends on like this and I would like to sort them based on the first 2 digits of the second part of each. I'm really rushed right now so some help would be nice.
collection = ["81851 19AJA01", "68158 17ARB03", "104837 20AAH02",
I tried this and it didn't work. I'm not doing this for a class I'd really appropriate some help
for x in collection:
counter = 0
i=0
for y in len(str(x)):
if (x[i] == '1'):
counter == 1
elif (x[i] == '2'):
counter == 2
elif x[i] == '0' and counter == 2:
counter = 2
elif x[i] == '9' and counter == 1:
counter = 3
elif x[i] == '8' and counter == 1:
counter = 4
elif x[i] == '7' and counter == 1:
counter = 5
i = i + 1
if (counter==2):
freshmen.append(x)
elif (counter==3):
sophomores.append(x)
elif (counter==4):
juniors.append(x)
elif (counter==5):
seniors.append(x)
Use the key function to define a custom sorting rule:
In [1]: collection = ["81851 19AJA01", "68158 17ARB03", "104837 20AAH02"]
In [2]: sorted(collection, key=lambda x: int(x.split()[1][:2]))
Out[2]: ['68158 17ARB03', '81851 19AJA01', '104837 20AAH02']

Categories

Resources