Eradicate the error - 'bool' obj can't be iterated - python

The code intends to print a frequency table for a random input discrete data. Here's the code :
from math import log10
from random import randint
N = int(input("Enter number of observations:\n"))
l = [ randint(1,100) for var in range (N) ]
print(l)
l.sort()
print(l)
k = 1 + (3.332*log10(N))
k1 = round(k)
print ("Number of intervals should be = ",k1)
x = N//k1 + 1
print("S.No\t\tIntervals\t\tFrequency")
c = 1 #count
while c <= k:
a = (c-1)*x
b = c*x
count = 0
for v in range(a,b) in l:
count += 1
print(c,"\t\t","{}-{}".format(a,b),"\t\t",count)
c += 1
This shows the above cited error, how to resolve this?

The issue is that range(a,b) sets up a list of integers from a to b-1. What you are asking for is for the code to go through l and pick out numbers matching those criteria, which looks instead like:
for v in l:
if ((v>=a) and (v<b)):
count += 1
If you really want to use range, and your data are going to stay integers, then it would look like:
for v in l:
if v in range(int(a),int(b)):
count += 1
Also
x = N//k1 + 1
should be
x = 100//k1 + 1

Related

Python print each iteration of a while loop

I've created a summation function that takes in a start number and an end number and returns a summed answer between those two points
def print_sum_equations(start_number,end_number):
mySum = 0
num = start_number
while num <= end_number:
mySum += num
num += 1
print (mySum)
print_sum_equations(3,5)
It returns 12 which is correct, however, I want my output to look like the following
3 + 4 + 5 = 12
rather than just returning the answer. Im still new to python and learning how to iterate while loops so any help is appreciated
def print_sum_equations(start_number,end_number):
vals = [i for i in range(start_number,end_number+1)]
s = sum(vals)
for ind,i in enumerate(vals):
print(f'{i}',end='')
if ind != end_number-start_number:
print(' + ',end='')
else:
print(f' = {s}')
print_sum_equations(3,5)
Use the join method to get the series from a list of values.
val_list = list(range(start_number, end_number+1))
lhs = ' + '.join(val_list)
print ( lhs + ' = ' + str(sum(val_list)) )
You could also use a list comprehension to get val_list:
val_list = [ n for n in range(start_number, end_number+1) ]
... but list(range(... is more direct.
Pretty new to programming in python, my solution, is pretty simple and easy to read.
def print_sum_equations(start_number,end_number):
mySum = 0
num = start_number
num_list = []
num_list.append(num)
while num <= end_number:
mySum += num
num += 1
num_list.append(num)
print (mySum)
num_list.pop()
print(*num_list, sep="+",end="")
print("="+str(mySum))
print_sum_equations(2,5)

Im printing my value but it appends the initial value

I have this code, which runs an algorithm called Tomkins-Paige algorithm. The algorithm creates permutations of a sequence.
The problem is that the code prints the different permutations p, but when i try to append it to a list, it only appends the initial p, i.e. p = [1,2,3,4].
import numpy as np
n = 4
p = [i for i in range(1,n+1)]
c = [1 for i in range(1,n+1)]
i = 2
print(p)
listp = []
while i <= n:
shift = np.roll(p[:i],-1)
for k in range(len(shift)):
p[k] = shift[k]
if c[i-1] < i:
c[i-1] += 1
i = 2
print(p, c, i )
listp.append(p)
else:
c[i-1] = 1
i += 1
more information about the algorithm: https://en.wikipedia.org/wiki/Tompkins%E2%80%93Paige_algorithm
Thanks in advance :)

Python List Index Error

Here is my version of the code right now and I keep getting list index error.
n = 0
y = len(list1)-1
while n < y:
for k in list1:
if list1[n]+ k == g:
print("The 2 prime numbers that add up to ",g,"are ", list1[n]," and ",k,".")
break
else:
n = n+1
You are incrementing n in the for loop but testing its contraint in the outer while loop.
Perhaps this is what you wanted:
n = 0
y = len(list1)-1
found = 0
while n < y:
for k in list1:
if list1[n]+ k == g:
print("The 2 prime numbers that add up to ",g,"are ", list1[n]," and ",k,".")
found = 1
break # for loop
if found:
break # while loop
n = n + 1
A much better way to do it is using itertools.combinations_with_replacement:
import itertools
for (v1,v2) in itertools.combinations_with_replacement(list1, 2):
if v1 + v2 == g:
print("blah blah blah")
break
combinations_with_replacement(list1,2) will return all the unordered combinations of two elements of list1. For instance, combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
You left a few bits of information out, but I gather that you are trying to find 2 primes that match a target. In order to access a list in this manner, you need to enumerate it.
y = len(list1) - 1
while n < y:
for n, k in enumerate(list1):
if list1[n]+ k == g :
print("The 2 prime numbers that add up to ",g,"are ", list1[n]," and ",k,".")
break
However, you don't really need the index, two for loops would accomplish the same thing.
target = 8
primes = [2, 3, 5, 7, 11, 13, 17, 19]
message = 'The 2 prime numbers that add up to {target} are {value1} and {value2}'
for index1, value1 in enumerate(primes):
for value2 in primes[index1 + 1:]:
if value1 + value2 == target:
print(message.format(target=target, value1=value1, value2=value2))

Longest arithmetic progression with a hole

The longest arithmetic progression subsequence problem is as follows. Given an array of integers A, devise an algorithm to find the longest arithmetic progression in it. In other words find a sequence i1 < i2 < … < ik, such that A[i1], A[i2], …, A[ik] form an arithmetic progression, and k is maximal. The following code solves the problem in O(n^2) time and space. (Modified from http://www.geeksforgeeks.org/length-of-the-longest-arithmatic-progression-in-a-sorted-array/ . )
#!/usr/bin/env python
import sys
def arithmetic(arr):
n = len(arr)
if (n<=2):
return n
llap = 2
L = [[0]*n for i in xrange(n)]
for i in xrange(n):
L[i][n-1] = 2
for j in xrange(n-2,0,-1):
i = j-1
k = j+1
while (i >=0 and k <= n-1):
if (arr[i] + arr[k] < 2*arr[j]):
k = k + 1
elif (arr[i] + arr[k] > 2*arr[j]):
L[i][j] = 2
i -= 1
else:
L[i][j] = L[j][k] + 1
llap = max(llap, L[i][j])
i = i - 1
k = j + 1
while (i >=0):
L[i][j] = 2
i -= 1
return llap
arr = [1,4,5,7,8,10]
print arithmetic(arr)
This outputs 4.
However I would like to be able to find arithmetic progressions where up to one value is missing. So if arr = [1,4,5,8,10,13] I would like it to report that there is a progression of length 5 with one value missing.
Can this be done efficiently?
Adapted from my answer to Longest equally-spaced subsequence. n is the length of A, and d is the range, i.e. the largest item minus the smallest item.
A = [1, 4, 5, 8, 10, 13] # in sorted order
Aset = set(A)
for d in range(1, 13):
already_seen = set()
for a in A:
if a not in already_seen:
b = a
count = 1
while b + d in Aset:
b += d
count += 1
already_seen.add(b)
# if there is a hole to jump over:
if b + 2 * d in Aset:
b += 2 * d
count += 1
while b + d in Aset:
b += d
count += 1
# don't record in already_seen here
print "found %d items in %d .. %d" % (count, a, b)
# collect here the largest 'count'
I believe that this solution is still O(n*d), simply with larger constants than looking without a hole, despite the two "while" loops inside the two nested "for" loops. Indeed, fix a value of d: then we are in the "a" loop that runs n times; but each of the inner two while loops run at most n times in total over all values of a, giving a complexity O(n+n+n) = O(n) again.
Like the original, this solution is adaptable to the case where you're not interested in the absolute best answer but only in subsequences with a relatively small step d: e.g. n might be 1'000'000, but you're only interested in subsequences of step at most 1'000. Then you can make the outer loop stop at 1'000.

Euler Project No. 2 with Python

Can somebody tell me why this should be wrong?
#Each new term in the Fibonacci sequence is generated
#by adding the previous two terms. By starting with 1 and 2,
#the first 10 terms will be:
#1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
#Find the sum of all the even-valued terms in the sequence
#which do not exceed four million.
sum=2
list = [1,2]
for x in range(2,100):
a = list[x-2]+list[x-1]
print(a)
list.append(a)
if a % 2 == 0:
sum += a
print('sum', sum)
if sum >= 4000000:
break
Here's a completely different way to solve the problem using a generator and itertools:
def fib():
a = b = 1
while 1:
yield a
a, b = b, a + b
import itertools
print sum(n for n in itertools.takewhile(
lambda x: x <= 4000000, fib()) if n % 2 == 0)
Output:
4613732
So your code, even though it is wrong (see other answers), happens to give the correct answer.
replace
sum += a
print('sum', sum)
if sum >= 4000000:
break
with
if a > 4000000:
break
sum += a
print('sum', sum)
You should compare "a" with 4000000, not "sum", like Daniel Roseman said.
The question asked for the sum of even terms which do not exceed four million. You're checking if the sum doesn't exceed 4m.
I'm trying to solve the same problem - although I understand the logic to do it, I don't understand why this works (outputs the right sum)
limit = 4000000
s = 0
l = [1,2]
while l[-1]<limit:
n = l[-1]+l[-2]
l.append(n)
print n
And then then moment I put in the modulo function, it doesn't output anything at all anymore.
limit = 4000000
s = 0
l = [1,2]
while l[-1]<limit:
n = l[-1]+l[-2]
if n % 2 == 0 :
l.append(n)
print n
I'm sure this is fairly simple...thanks!
This is the code I used. It is very helpful and teaches you about generators.
def fib():
x,y = 0,1
while True:
yield x
x,y = y, x+y
def even(seq):
for number in seq:
if not number % 2:
yield number
def under_a_million(seq):
for number in seq:
if number > 4000000:
break
yield number
print sum(even(under_a_million(fib())))
-M1K3
Keep it simple and it should take you less than 0.1 seconds.
from datetime import datetime
x, y = 1, 1
total = 0
for i in xrange (1, 100):
x = x + y
if x % 2 == 0 and x <= 4000000:
total += x
y = y + x
if y % 2 == 0 and x <= 4000000:
total += y
print total
starttime = datetime.now()
print datetime.now() - starttime

Categories