I'm trying to create a vector class in Python. I'm not so far yet, and stuck already.
This is my current code:
class vector:
def __init__(self, n, l = []):
self.v = []
if(isinstance(n, int)):
x = int(n)
if (x < 0):
return SyntaxError
else:
self.v += [0.0] * x
else:
self.v += n
def __str__(self):
return str(self.v)
The problem is, that when my input is
>>> u = vector(3,3.14)
>>> print(u)
then my ouput is
[0.0, 0.0, 0.0]
But I want it to be
[3.14,3.14,3.14]
and I also want the following:
>>> v=[3,[2.0,3.14,-5])
>>> print(v)
[2.0,3.14,-5]
What is the problem in my script?
Thanks!
You have [0.0] * x, but I think you mean [l] * x.
It really helps to clear up what kind of cases your code must support and write it down. It also helps to define a clear list of input and output combinations, you can use them as a test:
class Vector(object):
def __init__(self, n, l):
if isinstance(l, (list, tuple)): # l is a list, check length
if len(l) == n: # length as required, keep as is
pass
elif len(l) > n: # to long, use only the first n items
l = l[0:n]
elif len(l) < n: # to short, append zeros
l += [0] * (n - len(l))
elif isinstance(l, (int, float)): # create a list containing n items of l
l = [l] * n
self.v = l
def __str__(self):
return str(self.v)
Add some tests:
def test(a, b):
print 'input: {}, output: {}'.format(a, b)
if str(a) != b:
print('Not equal!')
test(Vector(3, 3.14), '[3.14, 3.14, 3.14]')
test(Vector(3, [4, 4, 4]), '[4, 4, 4]')
test(Vector(2, [4, 4, 4]), '[4, 4]')
test(Vector(4, [4, 4, 4]), '[4, 4, 4, 0]')
test(Vector(3, [2.0, 3.14, -5]), '[2.0, 3.14, -5]')
Related
def fun_lst(lst, a, b):
if min(lst)<b and max(lst)>a:
return True
return False
How do I check if the values in the list are bigger than a and smaller than b? I tried the above, but in this example: fun_lst([-1, 3.5, 6], -2.4, 0)the function returns True and it supposed to return False.
Do this:
def fun_lst(lst, a, b):
if min(lst) > a and max(lst) < b:
return True
return False
print(fun_lst([-1, 3.5, 6], -2.4, 0) )
Output:
False
Doing min(lst) > a ensures every element is bigger than a.
Doing max(lst) < b ensures every element is smaller than b.
Alternate solution:
def fun_lst(lst, a, b):
return all(a < elem < b for elem in lst)
You can try this one liner if you like
all([num < b and num > a for num in lst])
This code here will check each item in the list, if an item is found that is not greater than a and less than b then it returns false, otherwise it returns true.
def fun_lst(lst, a, b):
for item in lst:
if not a < item < b:
return False
return True
myList = [1,2,3,4,5,6,7,8,9]
lower_limit = 3
upper_limit = 8
bool_output = all([i > lower_limit and i < upper_limit for i in myList])
print(bool_output)
False
myList = [1,2,3,4,5,6,7,8,9]
lower_limit = 0
upper_limit = 10
bool_output = all([i > lower_limit and i < upper_limit for i in myList])
print(bool_output)
True
you should try this:
def fun_lst(lst, a, b):
return all(n > a and n < b for n in lst)
If you have a provision to use numpy try this
In [1]: import numpy as np
In [3]: np.array(b)
Out[3]: array([ 3, 1, 4, 66, 8, 3, 4, 56])
In [17]: b[(2<b) & (b<5)]
Out[17]: array([3, 4, 3, 4])
Different a method:
def fun_lst(lis, x, y):
list = [i>x and i<y for i in lis]
return False if False in list else True
It's a little easy:
def fun_lst(lis, x, y):
return x<max(lis)<y
lambda version:
fun_lst = lambda lis, x, y: x<max(lis)<y
Outputs:
fun_lst([-1, 3.5, 6], -2.4, 0) #Output: False
def pack(L, n):
'''Return the subset of L with the largest sum up to n
>>> s = [4,1,3,5]
>>> pack(s, 7)
{3, 4}
>>> pack(s, 6)
{1, 5}
>>> pack(s, 11)
{1, 4, 5}
'''
I'm asked to code this. It takes in a list and an integer and returns the best combination to get that integer less than or equal to.
I used a helper function that takes in the sum, but it's not correct since I don't know how I could replace a number while in recursion.
# doesn't work as intended
def pack_helper(L, n, sum=0):
'''Return the subset of L with the largest sum up to n and the sum total
>>> s = [4,1,3,5]
>>> pack_helper(s, 7)
({3, 4}, 7)
>>> pack(s, 6)
({1, 5}, 6)
>>> pack(s, 11)
({1, 4, 5}, 10)
'''
package = set()
if L == []:
result = (package, sum)
else:
first = L[0]
(package, sum) = pack_helper(L[1:], n, sum)
if sum < n and (first + sum) <= n:
package.add(first)
sum = sum + first
return (package, sum)
Any hints or help? Thx
Here's a simple recursive function that does the job:
def pack(L, n):
'''Return the subset of L with the largest sum up to n
>>> s = [4,1,3,5]
>>> pack(s, 7)
{3, 4}
>>> pack(s, 6)
{1, 5}
>>> pack(s, 11)
{1, 4, 5}
'''
if all(j > n for j in L):
return set()
return max(({j} | pack(L[i+1:], n-j) for i, j in enumerate(L) if j <= n), key=sum)
If you're using Python 3, you can pass the default parameter to max instead:
def pack(L, n):
return max(({j} | pack(L[i+1:], n-j) for i, j in enumerate(L) if j <= n), key=sum, default=set())
The test data here is small enough that brute force is pretty fast. Recursion is not necessary:
from itertools import chain, combinations
# taken from the itertools documentation
def powerset(iterable):
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
def pack(L, n):
best_set, best_sum = (), 0
for candidate in powerset(L):
total = sum(candidate)
if best_sum < total <= n:
best_set, best_sum = candidate, total
return best_set
However, assuming positive weights, the dynamic programming solution is pretty short.
def pack(L, n):
assert all(w > 0 for w in L), 'weights must all be positive'
a = [((), 0)] * (n + 1)
for w in L:
a = [ (a[x - w][0] + (w,), a[x - w][1] + w)
if w <= x and a[x][1] < a[x - w][1] + w
else a[x] for x in range(n + 1) ]
return a[n][0]
How does this work?
a[x] stores the best set of weights processed so far that sum up to x or less (and the sum, just to save time). Before any weights have been processed, these are all empty ().
To process a new weight w at target x, one of the following two sets must be the best.
the best set of weights without this new weight that sum up to x (the old a[x]), or
the best set of weights without this new weight that sum up to x - w, plus this new weight w
Once all the weights are processed, the solution is right there at the end.
By the way, this is the well-known 0/1 knapsack problem. (The Wikipedia article currently has a solution that uses O(len(L) * n) time and O(len(L) * n) space, but it's doable in O(n) space, as I demonstrated here.)
I wanted to be able to divide entire lists by integers, floats, and other lists of equal length in Python, so I wrote the following little script.
class divlist(list):
def __init__(self, *args, **kwrgs):
super(divlist, self).__init__(*args, **kwrgs)
self.__cont_ = args[0]
self.__len_ = len(args[0])
def __floordiv__(self, other):
""" Adds the ability to floor divide list's indices """
if (isinstance(other, int) or isinstance(other, float)):
return [self.__cont_[i] // other \
for i in xrange(self.__len_)]
elif (isinstance(other, list)):
return [self.__cont_[i] // other[i] \
for i in xrange(self.__len_)]
else:
raise ValueError('Must divide by list, int or float')
My question: How can I write this in a simpler way? Do I really need the lines self.__cont_ and self.__len_? I was looking through the list's 'magic' methods and I couldn't find one that readily held this information.
An example of calling this simple class:
>>> X = divlist([1,2,3,4])
[1, 2, 3, 4]
>>> X // 2
[0, 1, 1, 2]
>>> X // [1,2,3,4]
[1, 1, 1, 1]
>>> X // X
[1, 1, 1, 1]
How can I write this in a simpler way?
By using self[i] instead of self.__cont_[i].
Do I really need the lines self.__cont_ and self.__len_?
No. Just use the regular methods of referring to a list, for example: [] and len().
As an aside, you might choose to have .__floordiv__() return a divlist instead of a list, so that you can continue to operate on the result.
class divlist(list):
def __floordiv__(self, other):
""" Adds the ability to floor divide list's indices """
if (isinstance(other, int) or isinstance(other, float)):
return [i // other for i in self]
elif (isinstance(other, list)):
# DANGER: data loss if len(other) != len(self) !!
return [i // j for i,j in zip(self, other)]
else:
raise ValueError('Must divide by list, int or float')
X = divlist([1,2,3,4])
assert X == [1, 2, 3, 4]
assert X // 2 == [0, 1, 1, 2]
assert X // [1,2,3,4] == [1, 1, 1, 1]
assert X // X == [1, 1, 1, 1]
Instead of examining the explicit types of each argument, assume that either the second argument is iterable, or it is a suitable value as the denominator for //.
def __floordiv__(self, other):
try:
pairs = zip(self, other)
except TypeError:
pairs = ((x, other) for x in self)
return [x // y for (x, y) in pairs]
You may want to check that self and other have the same length if the zip succeeds.
When I run this code, nothing shows up. For example I call ind(1, [1, 2, 3]), but I don't get the integer 13.
def ind(e, L):
if (e in L == True):
print('13')
else:
print('12')
Operator precedence. If you put ( and ) around e in L it will work:
def ind(e, L):
if ((e in L) == True):
print('13')
else:
print('12')
ind(1, [1, 2, 3])
But testing for True can be done (and is the usual idiom) done without the True
def ind(e, L):
if (e in L):
print('13')
else:
print('12')
ind(1, [1, 2, 3])
Edit: as a bonus you can even use True and False to keep/nullify things. With your example:
def ind(e, L):
print('13' * (e in L) or '12')
ind(1, [1, 2, 3])
ind(4, [1, 2, 3])
And this ouputs:
13
12
Because e in L has first been evaluated to True and 13 * True is 13. The 2nd part of the boolean expression is not looked up.
But when calling the function with 4, then the following happens:
`13` * (e in L) or '12` -> `13` * False or '12' -> '' or '12' -> 12
Becase and empty string evaluates to False too and therefore the 2nd part of the or boolean expression is returned.
It should be
def ind(e, L):
if (e in L):
print ('13')
else:
print ('12')
Here ind(1,[1,2,3]) will print 13
And here's my proof that the above syntax runs in my machine:
def fib(a, b, f):
fib must generate (using yield) the generalized Fibonacci
sequence, a and b is first and second element. f is function to get the third element instead of a+b as normal Fibonacci sequence. Use take function(which show below) to test it.
my code is below
def fib(a, b, f):
x = a
y = b
yield x
x, y = y, f(x,y)
fib(x,y,f)
I don't know what is wrong of my code, when I try to test it, it show
"TypeError: 'generator' object is not subscriptable"
the test case is:
take(5, fib(0, 1, lambda x, y: x - y))
It should out put:
[0, 1, -1, 2, -3]
and take function as i write is :
def take(n, iterable):
x = []
if n <= 0:
return x
else:
for i in range (0,n):
x.append(iterable[i])
return x
The message means that generators do not support indexing, so iterable[i] fails. Instead, use the next() function to get the next item from the iterator.
def take(n, iterable):
x = []
if n > 0
itr = iter(iterable) # Convert the iterable to an iterator
for _ in range(n): # Repeat n times
x.append(next(itr)) # Append the next item from the iterator
return x
Also, your fib() function will not work. You should not recurse at the end of the function; instead write a loop that yields a value each iteration.
def fib(a, b, f):
x = a
y = b
while True:
yield x
x, y = y, f(x,y)
You can't index into the results coming from a generator function like fib(). This following avoids that by using zip() with a range() argument. zip() stops automatically when one of its arguments reaches then end.
def fib(a, b, f):
x, y = a, b
while True:
yield x
x, y = y, f(x, y)
def take(n, iterable):
return [] if n <= 0 else [v for _, v in zip(range(n), iterable)]
print( take(5, fib(0, 1, lambda x, y: x-y)) )
Output:
[0, 1, -1, 2, -3]
Fibonacci simplest method you'll ever come across:
a , b =0 , 1
for n in range(100):#any number
print(a)
a = a + b
print (b)
b = b + a
def fibo(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibo(n - 1) + fibo(n - 2)
n = int(input("enter the number: "))
for i in range(n):
print(fibo(i))