list index out of range-python - python

I'm trying to make an hangman game where you can type a specific word into it.
I came across a problem when trying to make a code which count the number of same letters in the word. For example, 'taste' will have two ts.
The program would count the letter which will be used for mathematical sums so the letter can be entered twice but no more.
I came across the list index is out of range problem in the code below.
def nolettercheck():
global list45 #list of variable within code (so they can be accessed)
global list1
global countonce
global count0
global count1
global count2
global count3
global count4
global count5
global count6
global count7
global count8
global count9
if len(list1) == 1: #makes sure list is in range
if list1.count(list1[0]) > 1: """count how many letter in word and if above 1 it continues
(although it doesn't work perfectly yet BTW do not spoil
this answer for me unless
you have to)."""
count0 = list1.count(list1[0])#create variable for number of same letters
list45.insert(0,list1[0])#insert the letter into another list for comparison
if len(list1) == 2 or len(list1) < 2: """repeats with next letter until
similar statement =false"""
if list1.count(list1[1]) > 1:
count1 = list1.count(list1[1])
list45.insert(1,list1[1])
if len(list1) == 3 or len(list1) < 3:
if list1.count(list1[2]) > 1:
count2 = list1.count(list1[2])
list45.insert(2,list1[2])
if len(list1) == 4 or len(list1) < 4:
if list1.count(list1[3]) > 1:
count3 = list1.count(list1[3])
list45.insert(3,list1[3])
if len(list1) == 5 or len(list1) < 5:
if list1.count(list1[4]) > 1:
count4 = list1.count(list1[4])
list45.insert(4,list1[4])
if len(list1) == 6 or len(list1) < 6:
if list1.count(list1[5]) > 1:
count5 = list1.count(list1[5])
list45.insert(5,list1[5])
if len(list1) == 7 or len(list1) < 7:
if list1.count(list1[6]) > 1:
count6 = list1.count(list1[6])
list45.insert(6,list1[6])
The code continues so it can do up to a ten letter word. This code is suppose to store the no of letter into a variable (which will be turned into a list later down the line although I might change that further on). It should also store the letter (if there is more than one letter).
The error specifically focuses on similar lines to if list1.count(list[6]) > 1:.
I did come across this error before and if len(list1) == 7 or len(list1) <7: worked (as it stopped checking for imaginary values in the list). So I am quite befuddled about this.

here's a way to get a dictionary of letter counts from a word. there are more 'pythonic' ways of doing this but if you're just getting started, this may help you out.
a = 'somestring'
letter_count_dict = {}
for letter in set(a):
letter_count_dict[letter] = a.count(letter)
the distinct letters in the word are
set(a) #set takes the distinct values. If you want a list of distinct values, an easy way to do it is list(set(a)) but since sets are iterable you don't usually need to do this.
and given a letter, l, the number of times it occurs is
letter_count_dict[l] #if l='s', then this would output 2
once you have the counts, you can choose what to do with them...loop and find the ones with greater than one occurrence, etc.. good luck.

Related

Shadow name error and Local variable not used

self teaching myself how to code and starting with this book and a Udemy course.
have been working on this practice project for 2 days now and I keep running into "Local variable 'streaks' not used when I have the streak counter placed inside the htcheck function even though I'm Cleary defining the variable, I tried placing the streak variable outside of the function at the top of the code to declare as it a global value but that still doesn't work and then I get the "Shadow name" error.
what the code should be doing is flipping a coin 10000 times then checking for streaks of 6 then present the user with how many streaks of 6 occurred and a percent value of how often a streak of 6 was, I'm sure a lot of you have seen this question been asked before as it's from Al Sweigart's Automate The Boring Stuff with python 2nd edition <- I just cant find the answer to my specific error hence this post.
I just need help with figuring out why my variable ' streaks = 0 ' isn't working as shown below. and why it doesn't work as a global variable declared where I have heads tails and x. I would prefer a solution that keeps streaks inside the htcheck function but i'm open to any and all solutions.
Thank you in advance.
# Automate Python - Coin Flips Streaks
heads = []
tails = []
x = 0
#Flips a coin, then stores result into respective list
def coinflip():
y = random.randint(0, 1)
if y == 0:
heads.append('H')
tails.clear()
elif y == 1:
tails.append('T')
heads.clear()
#checks if list len is 6 then clears and adds +1 to streak
def htcheck():
streaks = 0
if len(heads) == 6:
streaks = streaks + 1
heads.clear()
elif len(tails) == 6:
tails.clear()
streaks = streaks + 1
while x < 10000:
x = x + 1
coinflip()
htcheck()
print('# Streaks of 6: ", streaks)
While you can use global variables for something like this, I generally prefer using return statements and tracking the variables separately for easier debugging and readability
Something like this is an option
# Automate Python - Coin Flips Streaks
heads = []
tails = []
num_streaks = 0
#here we eliminate the need for a counter variable x by using a for loop instead of a while loop below, instead creating a counter for our streaks
#Flips a coin, then stores result into respective list
def coinflip():
y = random.randint(0, 1)
if y == 0:
heads.append('H')
tails.clear()
elif y == 1:
tails.append('T')
heads.clear()
#checks if list len is 6 then clears and adds +1 to streak
def htcheck():
streaks = 0
if len(heads) == 6:
streaks = streaks + 1
heads.clear()
elif len(tails) == 6:
tails.clear()
streaks = streaks + 1
#here we return the local variable instead of trying to use the global scope
return streaks
#using a for instead of a while loop is a bit of a stylistic choice but can prevent problems arising from forgetting a `break` condition or messing up counter incrementation
for x in range(1000):
coinflip()
#here we add to the streak counter we declared in the outer scope by using the local variable returned from the function
num_streaks += htcheck()
print('# Streaks of 6: ', num_streaks)

While loop keeps going back to end condition

I'm just going over some python basics, and wrote some code that I thought would print every even element inside of a list:
def print_evens(numbers):
"""Prints all even numbers in the list
"""
length = len(numbers)
i = 0
while i < length:
if numbers[i] % 2 == 0:
print (numbers[i])
i += 1
print_evens([1, 2, 3, 4, 5, 6])
I'm not sure why but the loop doesn't go past the end condition and just keeps cycling back and forth. I feel I'm missing something very simple.
If I had to guess where the problem lies, I'd say it's with the if statement, though I'm not sure what would be wrong about it.
The problem is that when you start with 1 the variable i never get updated, because it's not even. So the solution is to increment the i every time without a condition:
while i < length:
if numbers[i] % 2 == 0:
print (numbers[i])
i += 1
If you don't want to bother with indexes you can loop directly on the list items.
def print_evens(numbers):
"""Prints all even numbers in the list
"""
for n in numbers:
if n % 2 == 0:
print(n)

Whats the better way of doing this

I've only been coding in python for a month and I tried making something that searches for duplicates in a user made list...
List = []
count = 0
Val = 0
usernum = int(input("How many numbers are in your list: "))
for i in range(0, usernum):
values = int(input("What is the number on the list: "))
List.append(values)
for i in range(0, len(List)):
if List[i] == List[Val]:
print("There are duplicates")
count += 1
if count == len(List):
Val += 1
continue
Your code does not work for various reasons:
You're missing your main variable: the list. Add it like this
List = []
BTW: List with a capital L is not an awesome choice, but still a much better choice than list with a lower case L which could cause all kinds of problems.
With that added, enter 1 and 1 and you'll find that even for a single number it will print "There are duplicates". That is because you compare
List[i] == List[Val]
where both i and Val are 0. The item compares against itself. That must no be the case.
All the if-logic is weird. It's unclear to me what you wanted to achieve. A common approach would be a nested loop in order to compare each item against each following item. Note how j starts at i+1
for i in range(0, len(List)):
for j in range(i+1, len(List)):
if List[i] == List[j]:
print("There are duplicates")
An even better approach would be to not implement that yourself at all but use other techniques like
if len(set(List)) < len(List):
print("There are duplicates")
where set() will give you the unique numbers only. If numbers have been removed because they were not unique (aka. duplicate), that set will have less numbers than the list.

Python code returns nothing after putting input

I am absolutely clueless because I ran this code earlier and it worked fine. I don't remember changing anything. Once I enter my input it returns empty but is still running the program.
import random
print("This program finds the smallest difference between any two elements in"+
" a randomly generated list of integers, using two different algorithms with"+
" different Big-O efficiency.\n")
min_ran = int(input("Enter random min range:"))
max_ran = int(input("Enter random max range:"))
len_list = int(input("Enter length of list:"))
counter = 1
output_list = []
while counter <= len_list:
output_list.append(random.randint(min_ran,max_ran))
def algorithm1():
diff = 10**20
for i in range(len_list-1):
for j in range(i+1,len_list):
if abs(output_list[i]-output_list[j]) < diff:
diff = abs(output_list[i]-output_list[j])
return diff
def algorithm2():
mid = len_list // 2
list1 = output_list[:mid]
list2 = output_list[mid:]
list1.sort()
list2.sort()
ans = 10**20
i = j = 0
while i < len(list1) and j < len(list2):
ans = min(ans,abs(list1[i]-list2[j]))
if list1[i] < list2[j]:
i += 1
else:
j +=1
return ans
print("\nList:",output_list)
print("List length:",len_list)
print(algorithm1())
print(algorithm2())
At line 12 you're creating an infinite loop unless the len_list input is under 1
while counter <= len_list:
output_list.append(random.randint(min_ran,max_ran))
Adding counter += 1 into the loop seems to fix it.
That seemed to be the only bug i ran into running the code.
Though i'd highly suggest using a for loop in this case instead of a while loop to prevent infinite loops such as that
you don't change your counter. it will cause an infinite loop.
counter = 1
output_list = []
while counter <= len_list:
output_list.append(random.randint(min_ran,max_ran))
try:
output_list = [random.randint(min_ran,max_ran) for x in range(0,len_list)]
side note: I'd recommend using some kind of version control software such as git in order to avoid unwanted changes that cause small logical bugs.

How to identify if only a certain amount of numbers in an array are consecutive

I've been making a poker simulator and I've managed to make a function which can identify an array which has consecutive numbers.
def straightCheck(playerHand):
playerHand.sort()
print(playerHand)
for i in range(len(playerHand)-1):
if playerHand[i] != playerHand [i+1] - 1:
return False
print(handstrength)
return True
print(handstrength)
The only problem is that I want the function to identify 5 consecutive numbers in the array when the length of the array is greater than 5. For example: I want the array [1,2,3,4,5,6,7] to return True but i also want the array [1,3,4,5,6,7,9] to return True.
You're returning False too soon. Instead, you could keep a running tally of the amount of consecutive numbers you've seen so far, and reset it when you come across a number that breaks the streak.
def straightCheck(playerHand):
playerHand.sort()
tally = 1
for i in range(len(playerHand)-1):
if playerHand[i] != playerHand [i+1] - 1:
tally = 0
tally += 1
if tally >= 5:
return True
return False
Right now you check if numbers are not consecutive and then return false. I think you could better check if numbers are consecutive and if so raise a counter and if not then reset it. That way you know how many numbers are consecutive. If that is 5 or higher you should return True.
If you have a working function, you could just process all the 5-card sets in a loop:
for i in range(len(values) - 4):
is_straight = straightCheck(values[i:i+5])
if is_straight:
break
print(is_straight)
def straightCheck(playerHand):
playerHand.sort()
print(playerHand)
count = 0;
for i in range(len(playerHand)-1):
if playerHand[i] == playerHand [i+1] - 1:
count += 1
if count >= 5:
return True
else:
count = 0
return False

Categories