int is not an interable? [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
trying to make an average function myself as requested by a book I'm using to learn python. This is what I have and I need it to basically have a requirement of at least 1 argument to avoid division by zero, but to accept any amount of other arguments. But I keep getting this error. Here's my code. Any help is appreciated!
1 def average(x, *args):
----> 2 return sum(x, *args) / len(x, *args)
3
TypeError: 'int' object is not iterable

sum() and len() only take in iterables, which are objects that python can iterate through, like strings, lists, sets, etc.
You need to close the integers with brackets, so it would be a list, and then, you can put the iterable into sum() and len().
def average(x, *args):
return sum([x, *args]) / len([x, *args])
print(average(1, 4, 2, 6))
Output:
3.25

Neither sum nor len take an arbitrary number of arguments. If you want average to do so, you need to pass them all as a single iterable to sum and as a single object (that supports the length protocol) to len.
def average(x, *args):
all_nums = [x]
all_nums.extend(args)
return sum(all_nums)/len(all_nums)
(I suppose all_nums = [x, *args] would work as well; I spend too much time in Python 2 for that to feel natural yet.)
If you wanted average to be more like sum and take an arbitrary iterable, it would be easier to compute the sum and length in parallel, rather than use sum directly (since len does not work with arbitrary iterables)
def average(nums):
length = 0
total = 0
for x in nums:
length += 1
total += x
return total/length

Related

What is wrong with my implementation of the knapsack problem [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
items = [[profit, weight]...]
items = [[44,92], [46,4], [90,43], [72,83], [91,84], [40,68], [75,92], [35,82], [8,6], [54,44], [78,32], [40,18], [77,56], [15,83], [61,25], [17,96], [75,70], [29,48], [75,14], [63,58]]
max_weight = 269
def knapsack_bruteforce(items, max_weight):
def backtrack(i, curr_profit, curr_weight):
if(i+1 >= len(items) or curr_weight + items[i+1][1] > max_weight):
return curr_profit
return max(backtrack(i+1, curr_profit + items[i+1][0], curr_weight + items[i+1][1]), backtrack(i+1, curr_profit, curr_weight))
return backtrack(-1, 0, 0)
knapsack_bruteforce(items, max_weight) should return 550 as the maximum profit but I'm getting
528 instead.
The problem is in the second part of the if condition:
if(i+1 >= len(items) or curr_weight + items[i+1][1] > max_weight):
return curr_profit
When the second condition is true, you should still allow the second recursive call to be done -- the one where this weight is not included -- as there might still be a way to add another item (that has less weight). But as you return immediately here, that attempt is never made.
Without changing more than necessary to your code, you can fix this, by bailing out (returning a negative number) when the weight excess has already been made. So split your if into two:
if curr_weight > max_weight:
return -1
if i+1 >= len(items):
return curr_profit
The problem is that you aren't exhaustively trying all the combinations; each time you remove an item, your recursive call needs to consider all the other items, not just the items after the one you removed.
Here's an example of a working brute-force solution; I added a functools.cache decorator (which requires immutable inputs, hence a tuple of tuples instead of a dict of lists) so I wouldn't have to wait all day for it to return the answer and make sure it works, but it should return the same answer without the memoization (just a lot more slowly). Memoization makes it go faster because otherwise you end up re-computing the exact same intermediate answers (arrived at in slightly different orders) quite a few times.
The thing to pay attention to is that in that max call we're iterating over all of items, and doing the recursive call with items[:i] + items[i+1:], i.e. all the items except the i-th item.
from functools import cache
#cache
def knapsack(items: tuple[tuple[int, int], ...], max_weight: int) -> int:
if all(weight > max_weight for _profit, weight in items):
return 0 # can't add anything to the sack
return max(
profit + knapsack(items[:i] + items[i+1:], max_weight - weight)
for i, (profit, weight) in enumerate(items)
if weight <= max_weight
)
print(knapsack((
(44,92), (46,4), (90,43), (72,83), (91,84), (40,68), (75,92),
(35,82), (8,6), (54,44), (78,32), (40,18), (77,56), (15,83),
(61,25), (17,96), (75,70), (29,48), (75,14), (63,58)
), 269)) # 550

I am getting an error in taking remainder of range ?why is this happening [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
n = int(input())
for x in (range(1,n))%2!=0:
if x % 3 == 0 and x % 5 == 0:
print("SoloLearn")
elif x % 3 == 0:
print("Solo")
elif x % 5 == 0:
print("Learn")
It gives this error---TypeError: unsupported operand type(s) for %: 'range' and 'int'
why can i not divide 2 by range of numbers?
you want odd numbers try this:
for x in (range(1,n,2)):
instead of:
for x in (range(1,n))%2!=0:
Python objects decide for themselves what operations mean by implementing magic methods - see Emulating Numeric Types. range(1,n) % 2 translates to calling range(1,n).__mod__. But that method isn't implemented for range objects because the authors didn't think it made sense to modulo an integer generator. Remember, this is an operation on the generator object, not the integers iterated by the generator.
If you really wanted to divide a range of numbers by 2, you could do it as the numbers are generated
>>> for x in (y % 2 for y in range(10)):
... print(x)
Are you trying to create a list of odd numbers?
YOu could try:
for x in [num for num in range(1,n) if num x%2]:
#do_stuff
note that you can lose the !=0 part of the check because non-zero integers equate to True
As noted by Sujay, there's a quicker way to do it that hides the underlying mechanism.
The example I gave you can be modified to use more complex checks.
ALSO!
Note that you don't really want to do this. You're solving fizzbuzz, you need to iterate over all numbers. Number 30 is even and you want to print 'sololearn' ('fizzbuzz') when you reach it.

how exactly is the recursion working in this code [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have this code , and it is not mine , I saw it online and i am wondering how is the recursion working , can someone please explain !
(this function accepts a list of integers(distances) and a value 'r' lets say 10) and it returns all the possibilities of how we can reach 100 using the distances) lets say the list is [3,5,2,5] and the value r is 10 ! so to make 10 we need [5,5] or [3,2,5] ,this is the code:
def greedy(r, distances):
if r < 0:
return []
if r == 0:
return [[]]
solutions = []
for last_distance in d:
combos = greedy(r - last_distance, d)
for combo in combos:
combo.append(last_distance)
if(not solutions.__contains__(combo)):
solutions.append(combo)
return solutions
i hope i made my self clear
I'd suggest using python print function
print("")
At multiple locations to actually see the recursion happening. You would get a better idea than someone trying to explain it to you.
Although the function itself is quite simple. For every element in distances, the function subtracts the element from the required r value and checks the value with the if conditions.
If r value is zero ie, the for some elements in distance, their sum is r, a multi list is returned, which furthermore has the said elements.
At the end, the complete list of elements whose sum adds to r are appended to solution list and returned.
Say that given a list distances0 of length n, you are able to return all tuples i1,..,infrom the list that sums to a number r for any number r.
You would like to do the same for a list distances of length n+1.
Since you know how to solve the problem for a list of size n, you will do the following: for every element last_distance of distances, return all tuples i1,...,in that sums to r-last_distance from a list distances0 which is similar to distances but without the element last_distance (and hence of length n).
I think there might be some mistakes in the code, here should be a working version:
def greedy(r, distances):
if r < 0:
return []
if r == 0:
return [[]]
solutions = []
for i in range(len(distances)):
d = distances[:i]+distances[i+1:]
last_distance = distances[i]
combos = greedy(r - last_distance, d)
for combo in combos:
combo.append(last_distance)
if(not solutions.__contains__(combo)):
solutions.append(combo)
return solutions

Converting a C function to Python function [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
this function searches the number of an element in an array and returns the number of the element in the array if it exists or returns -1 if the input number does not exist on the array
int iSearch (int st[],int len,int no)
{
int i;
for (i=1;i<=len;i++) //len=lenth of the array , no = the number that we want to search in the array , st[] = the array
if (st[i]==no)
return i;
return -1;
}
and i want to write the python version of this function but since i use lists instead of arrays in python, i dont know how to write it in python.
i wrote the code below in python but it doesn't work
def iSearch(list,lenth,no):
x=0
for x in range (lenth):
if (list(x) == no)
return i
else
return -1
Here's the loop equivalent:
def iSearch(lst,no):
for i,x in enumerate(lst):
if x == no:
return i
return -1
There is, however, function lst.index(no) which is doing what you need, but in a more efficient way:
def iSearch(lst,no):
if no in lst:
return lst.index(no)
return -1
Or with the try/except (probably the fastest):
def iSearch(lst,no):
try:
return lst.index(no)
except ValueError:
return -1
It would help if you included the error you got next time.
Your code has some issues: 1. "list" is the name of an already existing object 2. You're only checking if the first item is the desired object, because at that point, both branches return. 3. accessing an element of a list requires square brackets, not parentheses.
This appears to work:
def linear_search_c(l,length,num):
for x in range(0,length):
if (l[x] == num):
return x
return -1
As an aside, there are better list searching methods than linear search if the array is sorted: binary search

Python list arithmetic [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have a list of integers for example: [30,21,32,32,41,20,21,32,21,20]
I have a variable of X, X has a value within the range of the list.
How can I find the sum of all the elements in the list to the number of X.
For example if x was 4 I would want: 30+21+32+32
Another way to go is to use the takewhile function from itertools:
>>> import itertools
>>> sum(itertools.takewhile(lambda x: x<5, range(10)))
10
In your case:
>>> l = [1,2,3,4,5,6,7,8,9]
>>> x = 5
>>> sum(itertools.takewhile(lambda i: i < x, l))
10
if you want till the 5th element, maybe use enumerate and zip:
>>> sum(zip(*(itertools.takewhile(lambda i: i[0]<x-1, enumerate(l))))[1])
10
If you're a beginner, you should learn that the common way to carry out a task is to define a function
A function needs a name and usually needs one or more arguments, in this example sum_until is the name and l and n are the arguments.
Following the definition, there is some code that does the task for generical values of l and n. Eventually the function returns the result of the computation, here the statement return sum.
Note the commented # return sum at the end of the function definition. You should try to control what to do in exceptional cases, here what we want to do when n is not found into l. One option is to return the sum of all the numbers in l, another one is to return a value that is impossible for a summation, and the second one is exactly my choice.
def sum_until(l,n):
"returns the sum of the numbers in l that occur before the appearance of n"
sum = 0:
for num in l:
if num == n:
return sum
sum = sum + num
# return sum
return None
Now, we have to use the function. This is achieved calling the function, that is you call its name and tell it on which actual values you need to operate the sum:
print(sum_until([2,4,6,8,5,10,12], 5))
print(sum_until([2,4,6,8,5,10,12], 3))
Output
20
None
If you want to sum the x first elements:
>>> l = [1,2,3,4,5,6,7,8,9]
>>> x = 5
>>> result = sum(l[:x])
>>> result
15
My answer may be not efficient, but I it is very straightforward.

Categories

Resources