Random's randint won't work in a for-loop - for-loop

I'm trying to create a list with random length filled with lists of random lengths by using this code:
import random
solitaire = [None]*(random.randint(1,5))
for pile in solitaire:
number = random.randint(0, 10)
solitaire.append(number)
print(solitaire)
Easy enough I thought but when I ran this code my powershell window froze as it was expecting an input or something, I had to cancel the script with ctr+c and then got the message:
Traceback (most recent call last):
File "sparakod.py", line 254, in <module>
number = random.randint(0, 10)
File "C:\Python34\lib\random.py", line 218, in randint
return self.randrange(a, b+1)
File "C:\Python34\lib\random.py", line 170, in randrange
def randrange(self, start, stop=None, step=1, _int=int):
KeyboardInterrupt
What does this mean? Why won't the code run?
number = random.randint(0, 10)
Seems to work just fine so why won't it inside the for-loop?

you don't say anything about the content of the lists, supposing that they also contain random integers, then a possible solution could be the following:
"""
It creates a list with random length filled with lists of random lengths containing random integers
"""
import random
MIN_LIST_OF_LISTS_LENGTH = 1
MAX_LIST_OF_LISTS_LENGTH = 10
MIN_LIST_LENGTH = 1
MAX_LIST_LENGTH = 5
MIN_LIST_ELEMENT = 1
MAX_LIST_ELEMENT = 10
#This is the list which will containt all the lists
solitaire = list(range(random.randint(MIN_LIST_OF_LISTS_LENGTH,MAX_LIST_OF_LISTS_LENGTH)))
for i, pile in enumerate(solitaire):
solitaire[i] = [
random.randint(MIN_LIST_ELEMENT, MAX_LIST_ELEMENT) for x in
range(0, random.randint(MIN_LIST_LENGTH, MAX_LIST_LENGTH))
]
print(repr(solitaire))
It will generate outputs like these:
[[10, 3], [5, 2, 7, 7, 6], [5], [9, 3, 2, 6], [2, 4, 4], [4, 5, 10, 9, 10]]
or
[[5, 1], [5, 1, 1], [1, 1, 7, 3, 1]]
or
[[9, 1, 6, 7], [10, 7, 1, 7, 4]]

Related

I need to convert a 3 column array into a square matrix?

I am looking to convert my data to a square matrix:
Say your input is a list; you can then convert it to a list of lists (i.e., a proxy to a matrix) with list comprehension:
>>> x = [0, 5, 10, 5, 0, 2, 10, 2, 0]
>>> [x[3*k:3*k+3] for k in range(3)]
[[0, 5, 10], [5, 0, 2], [10, 2, 0]]
To help you parse the line: you are building a list by iterating over k from 0 to 2, where each element will be a slice of x that starts from index 3*k and ends at index 3*k+3. Thus, your list is [x[0:3], x[3:6], x[6:9]].
That said, it's much better to use numpy for all such needs. There, you would do:
>>> import numpy as np
>>> x = np.array([0, 5, 10, 5, 0, 2, 10, 2, 0])
>>> x.reshape(3, 3)
array([[ 0, 5, 10],
[ 5, 0, 2],
[10, 2, 0]])
The reshape() function converts your 1D array into the requested 2D matrix.

how to speed up sympy-matrix of matrics calculation runtime

I've checked my code, there are no syntax error popping in the console, my matrix structures are correct, hence, mathematical operations are feasible.
if i run my code it takes forever, the console never get to print out the result. I broke the matrix to chokes of smaller code, its still taking time to compute.
from sympy import Symbol,Matrix
az = Matrix([[1, 2, 3, 4,5, 6],
[2, 3, 5, 6, 8, 6],
[4, 5, 6, 4, 8, 5],
[5, 6, 5, 8, 9, 9],
[4, 5, 6, 7, 8, 5],
[5, 6, 5, 8, 3, 9]])
fz = Matrix([[1,0,0,0,0,0],
[0,1,0,0,0,0],
[0,0,1,0,0,0],
[0,0,0,1,0,0],
[0,0,0,0,1,0],
[0,0,0,0,0,1]])
aa = Symbol('aa')
ff = Symbol('ff')
gen = Matrix([[aa, ff, 0, 0, 0, 0],
[ff,aa,ff,0,0,0],
[0,ff,aa,ff,0,0],
[0,0,ff,aa,ff,0],
[0,0,0,ff,aa,ff],
[0,0,0,0,ff,aa]])
inverse_genn = gen**-1
bz = Matrix([[2],
[3],
[3],
[4],
[5],
[5]])
bzz = Matrix([[bz],[bz],[bz],[bz],[bz],[bz]])
solution = inverse_genn*bzz
_1st_displacement = solution[0][0]
_1st_solution = _1st_displacement.subs({aa:az,ff:fz})
print('type',solution[0].shape)
print('solution',solution[0][0])
print('##'*100)
print('displacement matrix', _1st_solution)
Try make it easier to compute. Although an expression may be correct, it is not necessarily efficient for computation.
>>> eq=solution[0][0]
>>> count_ops(eq)
426
>>> s=eq.simplify()
>>> count_ops(s)
10
>>> s
2*(aa**2 - 1)/(aa**3 + aa**2 - 2*aa - 1)
>>> numer(s)/horner(denom(s))
(2*aa**2 - 2)/(aa*(aa*(aa + 1) - 2) - 1)
>>> h = _
>>> from time import time
>>> t=time(); e = h.subs(aa, az);print(time()-t)
0.0860941410065
Since horner does not apply itself to the numerator and denominator automatically, you have to use as_numer_denom to break up your simplified expression. Then you have to rebuild the expression. All together it looks like:
>>> be = zip(solution[0][0].simplify().as_numer_denom(), (1, -1))
>>> _1st_displacement = Mul(*[horner(b)**e for b,e in be])
CAUTION: this was written for an older version of SymPy. See comments below for modifications needed for newer SymPy.

count the number of consecutive integer elements in an array

Given I have an array such as follows:
arr = [8, 13, 14, 10, 6, 7, 8, 14, 5, 3, 5, 2, 6, 7, 4]
I would like to count the number of consecutive number sequences. Eg in the above array the consecutive number sequences (or array-slices) are:
[13,14]
[6,7,8]
[6,7]
And hence we have 3 such slices. What is an efficient Algorithm to count this? I know how I can do it O(N^2) but I'm looking for something which is better than that.
arr = [8, 13, 14, 10, 6, 7, 8, 14, 5, 3, 5, 2, 6, 7, 4]
p arr.each_cons(2).chunk{|a,b| a.succ == b || nil}.count #=> 3
nilhas a special meaning to the chunk-method: it causes items to be dropped.
arr = [8, 13, 14, 10, 6, 7, 8, 14, 5, 3, 5, 2, 6, 7, 4]
result = []
stage = []
for i in arr:
if len(stage) > 0 and i != stage[-1]+1:
if len(stage) > 1:
result.append(stage)
stage = []
stage.append(i)
print result
Output:
[[13, 14], [6, 7, 8], [6, 7]]
The time complexity of this code is O(n). (There's only one for loop. And it's not hard to see that each iteration in the loop is O(1).)
I would do as below using Enumerable#slice_before:
a = [8, 13, 14, 10, 6, 7, 8, 14, 5, 3, 5, 2, 6, 7, 4]
prev = a[0]
hash = Hash[a.slice_before do |e|
prev, prev2 = e, prev
prev2 + 1 != e
end.map{|e| [e,e.size] if e.size > 1}]
hash # => {[13, 14]=>2, [6, 7, 8]=>3, [6, 7]=>2}
hash.size # => 3
I think this can be done in O(N) time. If you just want the count,
Iterate through the array. Initialize counter to 0.
If next element is one more or one less than current element, increment the counter.
Continue iterating till the next element is not one more or one less than current element.
Repeat steps 2 and 3 until you reach the end.
If you want sections of continuously increasing consecutive elements (not clear from your question)
Iterate through the array. Initialize counter to 0.
If next element is one more than current element, increment the counter.
Continue iterating till the next element is not one more than current element.
Repeat steps 2 and 3 until you reach the end.

how to get an order-specified subset of an array of variable length from an array of variable length?

I have an array of objects of variable length n. Defined by the number of records in my database.
I need a function to grab subsets (keeping the objects in order and always beginning at index 0) of the array of specified length m where m can be any integer I pass in.
e.g. if n = 10 and m = 4
array foo = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
subset a = [0, 1, 2, 3]
subset b = [4, 5, 6, 7]
subset c = [8, 9]
So, I need to programmatically be able to say, "Give me the i-th subset of length m from an array, given the array is length n." Using the previous example: "Give me the second subset of length four from foo" => returns the items at positions [4, 5, 6, 7].
I hope that made sense. Assistance with a ruby solution would be much appreciated! thx!
foo.each_slice(subset_length).to_a[subset_index]
e.g. foo.each_slice(4).to_a[2] returns "the second subset of length four from foo".
You can use Enumerable#each_slice:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].each_slice(4).to_a
#=> [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]

Pythonic way of summing lists and lists of lists

I'm trying to find a neat way of summing a list and a list of lists in the same function, so far I've got:
import operator
"""
Fails late for item = ['a', 'b']
"""
def validate(item):
try:
return sum(item) == sum(range(1, 10))
except TypeError:
return sum(reduce(operator.add, item)) == sum(range(1, 10))
"""
Not valid for item = [1,2,[3,4,5]]
"""
def validate2(item):
if isinstance(item[0], int):
return sum(item) == sum(range(1, 10))
else:
return sum(reduce(operator.add, item)) == sum(range(1, 10))
print validate([1, 2, 3, 4, 5, 6, 7, 8, 9])
print validate([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print validate2([1, 2, 3, 4, 5, 6, 7, 8, 9])
print validate2([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
...but neither of these seem quite right to me (reasons in the doc strings). What I want to know is if there is a better way of summing lists and lists of lists that doesn't require me to catch exceptions or actually analyse the list before the function decides what to do.
Obviously, I'm still expecting ['a', 'b'] to be invalid.
Perhaps you'd find it easier to flatten the list first?
def flatten(xs):
for x in xs:
try:
sub = iter(x)
except TypeError:
yield x
else:
for y in flatten(sub):
yield y
With the above, you can do this:
In [4]: fs = flatten([1,2,[3,4,[5,6],7],8,[9,10]])
In [5]: list(fs)
Out[5]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Don't forget to describe exactly what you're trying to do. I'm assuming you mean to sum all values to a single value, and not to get eg. [[1,2],[3,4]] -> [3,7]. Here's simple recursion; five lines of code if you skip the tests:
def sums(it):
"""
>>> sums(1)
1
>>> sums([1,2,3])
6
>>> sums([1,2,3,[4,5]])
15
>>> sums(['a','b'])
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'int' and 'str'
"""
if getattr(it, "__iter__", None):
return sum(map(sums, it))
else:
return it
if __name__ == "__main__":
import doctest
doctest.testmod()
The external numpy module has many operations (including sum()) which work similarly on scalars, vectors, matrices and even higher-dimensional arrays...
Note however that it doesn't work on mixed lists like [1,2,[3,4,5]], only square matrices! So it doesn't exactly answer your question.

Resources