can't iterate through element not with range() nor with len() - python

i tried to use for loop to iterate through the length of input (string) but when i tried using len() OR range() they gave me error saying that the type is wrong.
this code is a start of Cows and Bulls game.
tried changing object type to list.
switched between sublime text and idle.
i checked the type of the input using the type() method
import random
target = [random.randint(0, 9) for i in range(4)]
turns = 0
all_cows = False
while not all_cows:
guess = input('Cows and Bulls!\nguess 4 numbers: ')
turns += 1
#tried doing range(guess) does not work! *type of guess is string
#len(guess) - error cant iterate through int
#range(guess) error cannot be interpreted as an integer
for item in len(guess):
if guess[item] == target[item]:
print('cow')
elif guess[item] in target:
print('bull')`
Program output:
Cows and Bulls!
guess 4 numbers: 1111
Traceback (most recent call last):
File "D:\Computers\Programming\Python\Codes\Exercises\17.py", line 8, in <module>
for item in len(guess):
TypeError: 'int' object is not iterable
Cows and Bulls!
guess 4 numbers: 1111
Traceback (most recent call last):
File "D:\Computers\Programming\Python\Codes\Exercises\17.py", line 8, in <module>
for item in range(guess):
TypeError: 'str' object cannot be interpreted as an integer

You need to combine range() and len(). By using
for index in range(len(guess)):
# your code here
you can iterate over the length of the guess.
You can also directly iterate over guess, but since you also need the index of each character, you need to use enumerate(). This will return two values for each character, the first is the index, the second is the character itself. So you would do:
for index, c in enumerate(guess):
# your code here with index as the index and c as the character

input() Function in python3 takes eac value as str
So you need to convert it into int by using int() Function
Check with following Code :
import random
target = [random.randint(0, 9) for i in range(4)]
turns = 0
all_cows = False
while not all_cows:
guess = input('Cows and Bulls!\nguess 4 numbers: ')
turns += 1
#Iterate String Directly
for item in guess:
#Convert Substring into int for using as Indices
if guess[int(item)] == target[int(item)]:
print('cow')
elif guess[int(item)] in target:
print('bull')

Thanks everyone for helping my out on that case.
seems like the problem is in me not understanding len() right, i forgot it returns the length as int and got confused when the err said object type int.
solution 1: using range(len(guess)) to iterate through through the length of the string.
solution 2: iterating through the string directly - wasn't what i searched for since i wanted to use the 'item' to index the string.
solution 3: using enumerate(guess) which i never heard of (so if someone is bored and want to explain it ill accept the explanation gratefully!
edit: got my answer.

Your problem is that your guess acquired by input is of type string (as are inputs). Then, the type of len(guess) is obviously int. You can't iterate over an int as it is not a sequence. You have a few options to overcome this problem:
iterate over the indices using range:
for i in range(len(guess)):
if int(guess[i]) == target[i]:
you could use enumerate:
for i, c in enumerate(guess):
if int(c) == target[i]:
Turn your input from the user to a list of ints:
guess = input('Cows and Bulls!\nguess 4 numbers: ')
guesses = [int(c) for c in guess]
for i in range(len(guess)):
if guess[i] == target[i]:
could also be done using map: guesses = list(map(int, guess))

Related

Why is i in my code not considered an integer?

Im new to Python and am trying to write a function that returns the amount of 1s in a binary number (i.e if the input is 12, then it should return 2, since 12 is 1100 in binary. However I keep getting the error "TypeError: list indices must be integers, not str" and I don't know whats wrong, I have googled the problem but havent understood what the answers meant.
Heres the code (I know it could be shorter I'm just asking the question because I get this error often and don't know why it comes):
def count_ones(num):
x=0
for i in bin(num):
if list(bin(num))[i] ==1:
x += 1
return x
Simply, bin(x) returns a string representing the binary number, as the docs point out.
So for i in bin(num): iterates over the characters in that string.
You can achieve what you want by checking if i == '1' instead, so your code would be
def count_ones(num):
x=0
for i in bin(num):
if i == '1':
x += 1
return x
Consider simplifying your function, however, by using the count method to count the occurrences of '1' in the binary representation, as follows:
def count_ones(num):
return bin(num).count('1')
bin returns a string, where you are iterating over each bit as a string. You should use int(i). You should probably use format or str.format to remove the 0b prefix as b is not an integer.
for i in format(num, 'b'):
I would just use a generator expression for this.
def count_ones(num):
return sum(1 for digit in bin(num) if digit == '1')
Example
>>> count_ones(50)
3
>>> bin(50)
'0b110010'
For what it's worth, the reason your code is not working is that bin returns a string, so each element you loop over will by of type str not int.

program that among the given numbers finds one that is different in evenness, and return a position of this number

Bob is preparing to pass IQ test. The most frequent task in this test is to find out which one of the given numbers differs from the others. Bob observed that one number usually differs from the others in evenness. Help Bob — to check his answers, he needs a program that among the given numbers finds one that is different in evenness, and return a position of this number.
! Keep in mind that your task is to help Bob solve a real IQ test, which means indexes of the elements start from 1 (not 0)
Examples :
iq_test("2 4 7 8 10") => 3 // Third number is odd, while the rest of the numbers are even
iq_test("1 2 1 1") => 2 // Second number is even, while the rest of the numbers are odd
My Code:
def iq_test(a):
b=[]
c=[]
for i in range(len(a)):
if a[i]%2 == 0:
b.append(a[i])
else:
c.append(a[i])
if len(b)==1:
for i in range(len(a)):
if [a[i]]==b:
return i+1
if len(c)==1:
for i in range(len(a)):
if [a[i]]==c:
return i+1
This works for the given inputs in my IDE, but when I put it in webpage IDE I obtain
Traceback (most recent call last):
File "main.py", line 3, in <module>
Test.assert_equals(iq_test("2 4 7 8 10"),3)
File "/home/codewarrior/solution.py", line 6, in iq_test
if a[i]%2 == 0:
TypeError: not all arguments converted during string formatting
What is the mistake here? Is my code correct?
The parameter given to your function is "2 4 7 8 10". You're iterating over that string and applying a modulo operation, which throws the error you're seeing since Python doesn't do automatic type conversion and can't apply a module to the string "2" (and, if it did, would throw an error at the second iteration when it'd try to apply the modulo operation to " ").
The simplest fix here is to check if it's not a space, then convert to int before the module:
for (i in range (len(a)):
if a[i] != " ":
if int(a[i])%2 == 0:
b.append(a[i])
...
By the way, the index, and range above is not neccessary for strings. You can also iterate over the string directly:
for char in a:
if char != " ":
if int(char)%2 == 0:
b.append(char)
...
You could also split the string into an array and iterate over that:
array = a.split(" ") # results in ["2","4","7","8","10"]
for (item in array):
if int(item)%2 == 0:
b.append(item)
...
In a real world application, I would also opt to check if the character at the current position is convertible to int, but for your case this solution is sufficient.
Also, as someone who recently looked over their own assignments from the first two semesters, get into the habit of using explicitly named variables. e.g instead of b use evenNumbers and instead of c use oddNumbers. This makes your code a lot more readable and better to understand what you did and why.
def iq_test(numbers):
lst = numbers.split()
evens = []
odds = []
for i in lst:
if int(i) % 2 == 0:
evens.append(int(i))
else:
odds.append(int(i))
if len(evens) == 1:
for i in lst:
if int(i) == evens[0]:
return lst.index(i)+1
if len(odds) == 1:
for i in lst:
if int(i) == odds[0]:
return lst.index(i)+1
I got it right

Initializing list of ints. Interpreter returns "ValueError: invalid litteral for int()"

Trying to make a list of ints the user inputs. Inerpreter is returning "ValueError: invalid literal for int() with base 10:"
I'm somewhat new to python and I'm practicing on a website called "geeks for geeks". Here is a link to the problem I'm working on.
The goal of the exercise is to print the first negative integer in a sub array of user specified size. When I try to append the user inputs to the list, the interpreter is giving me a value error. It's obviously not a type error but I can't figure out what kind of input could be given to the program to give it that error. The inputs are on a file on geeks for geek's servers so I can only test on inputs I've made.
# This file is for a programing practice exercise of geeksforgeerks.org
# The exercise is first negative int in window of size k
# selecting number of test cases
T = int(input())
for t in range(T):
# initializing array
n = int(input())
arr = []
while n > 0:
arr.append(int(input().strip()))
n-=1
k = int(input())
win = 0 # index of first element in widow subarray
# terminate loop when the window can't extend further
while win < len(array) - k -1:
# boolean for no negatives found
noNeg = True
for i in range(win, k):
if arr[i] < 0:
print(arr[i])
noNeg = False
break
elif i == k-1 and noNeg:
# 0 if last sub arr index reached and found no negs
print(0)
win+=1
The interpreter is giving the following error on line 11:
print(int(input().strip()))
ValueError: invalid literal for int() with base 10: '-8 2 3 -6 10'
The input data contains multiple numbers on the same line. input() returns a whole line of input, and when you call int(input().strip()) you're trying to parse that whole line as a single number.
You need to split it at whitespace. So instead of a while loop, you can use:
arr = map(int, input().strip().split())
Looks like you're inputting multiple integers, int() won't know how to convert them - it expects a single integer to be contained in the string. You'll want to split up the string and then convert:
Ts = [int(word) for word in input().strip().split(" ")]
Note that this will give you a list instead of a single integer.
you are feeding the input with multiple integers, you can extend your array at line 11 with your desired values:
arr = []
arr.extend(map(int, input().strip().split()))
# input: -8 2 3 -6 10
output:
[-8, 2, 3, -6, 10]

lndexError: list index out of range

I need to generate a string from random letters given in list take_from. The first time the function was executed it generated a phrase but all my following tries prompted an error "list index out of range". I can`t understand this error in my case and I tried while loop instead of for loop but it did not work either.
from random import randint
def make_a_phrase():
random_string = ''
take_from = ['a','b','c','d','e','f','g','h','i','j','k','l',
'm','n','o','p','q','r','s','t','v','u','w','x',
'y','z',' ']
for i in range(28):
random_string = random_string + take_from[randint
(0,len(take_from))]
return random_string
From the docs
random.randint(a, b)
Return a random integer N such that a <= N <= b.
Alias for randrange(a, b+1).
Therefore you can get values from 0 to len(take_from) - inclusive the endpoints - which in case of the upper bound would be out of list's index range as it is zero based and as such only has len(take_from) - 1 elements
In Python, lists are indexed with integers ranging from 0 to 1 less than the length of the list. E.g., a list with 10 items in it would have indexes from 0 to 9.
Your call to randint() attempts to get indexes from zero to the full length of the list, which will cause this exception. Change it to:
for i in range(28):
random_string = random_string + take_from[randint
(0,len(take_from)-1)]
The reason this happens, is because the len returns the length, but the last index is always the length - 1 (since indices start from 0).
So eventually, the random integer that comes up is the length, and of course, there is no element at that number.
Here is a simple example:
>>> i = [1,2,3]
>>> len(i)
3
>>> i[len(i)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
However, if you -1 from the length you will get the last item:
>>> i[len(i)-1]
3
You should change your loop to say:
for i in range(0, len(take_from)):
You are currently experiencing an off-by-one error because you only have 27 elements in your list, not 28.
You could try something like this instead
from string import ascii_lowercase
import random
def make_a_phrase():
return ''.join(random.choice(ascii_lowercase + ' ') for i in range(28))

Python 3 k-mers count errors

I have to solve a problem (problem and the code is given below) and I'm getting errors on executing this program.
Traceback (most recent call last):
File "C:/Python33/exercise1.py", line 9, in <module>
for n in range[len(string) - k]:
TypeError: unsupported operand type(s) for -: 'int' and 'list'
-
Frequent Words Problem: Find the most frequent k-mers in a string.
Input: A string Text and an integer k. [XGMcKJXnoMhmuXcsjswaejVunrrsDhoiWEzXbiKoiYBEpVmhJszFWCFJAHLPzKfKBhWbCABPCTqASGvgquUtnwSeeYkXtLcbzMxvcsUwjmhHfexpEEhjhjzKvYdODZeCgrehxUnYqDwYMBxaFsYAqIFsBSZslMmTNXPovRtRbqFOhMXMUErCnRgjiBIovOWXxlkYInG]
Output: All most frequent k-mers in Text.
My designed code is:
k=open("dataset_3_6.txt").readlines()
import string
string = str()
for k in string:
k = int(k)
kmer_count = {}
for n in range(len(string) - k):
c = string[n:n+k]
kmer_count[c] = kmer_count[c] + 1 if kmer_count.has_key(c) else 1
max = 0
max_kmer = []
for k,v in kmer_count.iteritems():
if v > max:
max_kmer = [k]
max = v
elif v == max:
max_kmer += [k]
print("max_kmer")
There are a huge number of problems right at the top:
import string
Why are you importing this module? Are you planning to use it?
string = str()
This hides the string module so you can never use it again, and creates a default (that is, empty) string (which is easier to do with string = '').
for k in string:
k = int(k)
Since string is an empty string, this loops zero times.
Even if it weren't empty, k = int(k) wouldn't have any effect; you're just rebinding the loop variable over and over again. If you wanted to replace the string string with a list of numbers, where each number is the integer value of the corresponding character in the string, you'd need to build a list, either by creating an empty list and calling append, or by using a list comprehension (e.g., string = [int(k) for k in string]). I have no idea whether that's what you're actually trying to do here.
Anyway, if string weren't empty, after the loop, k would be the int value of the last character in the string. But since it is, k is still the result of calling open("dataset_3_6.txt").readlines() earlier. That is, it's a list of lines. So, in this:
for n in range(len(string) - k):
You're trying to subtract that list of lines from the number 0. (Remember, you set string to an empty string, so its len is 0.)
I have no idea what you expected this to do.
Part of the confusion is that you have meaningless variable names, and you reuse the same names to refer to different things over and over. First k is the list of lines. Then it's a loop variable. Then… you apparently intended it to be something else, but I don't know what. Then, it's each key in a dictionary.

Categories