How can i deal a hand in python - python-3.x

im trying to deal a hand in python with random.shuffle and its keeps giving me an error, can some one help me figure out whats wrong with it.
# [import statements]
import q1fun
# [constants]
# [rest of program code]
number = input("howmany cards to you want dealt?")
a = q1fun.deal(number)
print (a)
# [import statements]
import random
# [constants]
def deal(x):
y = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
a = random.shuffle(y(x))
return(a)
howmany cards to you want dealt?5
Traceback (most recent call last):
File "C:\Users\Eddie\workspace\cp104\durb8250_a16\src\q1.py", line 18, in
a = q1fun.deal(number)
File "C:\Users\Eddie\workspace\cp104\durb8250_a16\src\q1fun.py", line 29, in deal
a = random.shuffle(y(x))
TypeError: 'list' object is not callable

random.shuffle(y) shuffles the list y inplace and returns None.
So
def deal(n):
"Return a hand of n cards"
y = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13]
random.shuffle(y)
return y[:n]
might be closer to what you want.
Or omit random.shuffle(y) and just use random.sample:
return random.sample(y, n)

You're trying to reference an element of a list with function call parentheses. You want to use square brackets.
function(x) <-- calls the function with parameter x
list[x] <-- gets the x-th element of the list
Also, your input is going to be returning a string. You'll need to convert it to an integer before using it to reference an index. I.e. random.shuffle(y[int(x)])
And finally, your shuffle call won't work. You want to shuffle first (which shuffles the list in place), then get the element
random.shuffle(y)
a = y[int(x)]

Related

Can anyone explain why I can't concatenate these two matrices?

Here is my matrices and codeline:
d = np.array([[1,2,3],[6,7,8],[11,12,13],
[16,17,18]])
e = np.array([[ 4, 5],[ 9, 10],[14, 15],[19, 20]])
np.concatenate(d,e)
and this is the error that I get:
TypeError: only integer scalar arrays can be converted to a scalar index
You have a syntax mistake in np.concatenate(d,e), the syntax requires d and e to be in a tuple, like: np.concatenate((d,e)). I tested it, and axis=1 is also required for it to work.
np.concatenate((d, e), axis=1)
is the solution
Since those arrays have different dimensions you should specify the axis concatenate you what like the follow:
1) np.concatenate((d,e), axis=1)
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]])
or
2)np.concatenate((d,e), axis=None)
array([ 1, 2, 3, 6, 7, 8, 11, 12, 13, 16, 17, 18, 4, 5, 9, 10, 14,
15, 19, 20])

(pandas) access all rows except for the first 3 for the specific columns at index

I want to access all rows except for the first 3 for the specific columns at index 1, 2, 4, 5, 7, 8, 10, 11, 13, 14 of a csv file. How can I do this? All examples I have found show how to slice (for example 1:14 but I do not want all columns in between but specific ones.
When I try:
p = df[3:, [1, 2, 4, 5, 7, 8, 10, 11, 13, 14]]
I get an error:
p = df[3:, [1, 2, 4, 5, 7, 8, 10, 11, 13, 14]]
File "/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py", line 2139, in __getitem__
return self._getitem_column(key)
File "/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py", line 2146, in _getitem_column
return self._get_item_cache(key)
File "/usr/local/lib/python3.5/dist-packages/pandas/core/generic.py", line 1840, in _get_item_cache
res = cache.get(item)
TypeError: unhashable type: 'slice'
and it does not work with the notation p = df[[3:], [1, 2, 4, 5, 7, 8, 10, 11, 13, 14]]
IIUC you need DataFrame.iloc for filter by positions here all rows without first 3 and columns names by positions:
df.iloc[3:, [1, 2, 4, 5, 7, 8, 10, 11, 13, 14]]
p = df.iloc[[3:],[1, 2, 4, 5, 7, 8, 10, 11, 13, 14]]
you were mostly right except you just had to close the square brackets after "3:".
and using loc, iloc is recommended for indexing.

Swap pair of elements along an axis

I have a 2d numpy array as such:
import numpy as np
a = np.arange(20).reshape((2,10))
# array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]])
I want to swap pairs of elements in each row. The desired output looks like this:
# array([[ 9, 0, 2, 1, 4, 3, 6, 5, 8, 7],
# [19, 10, 12, 11, 14, 13, 16, 15, 18, 17]])
I managed to find a solution in 1d:
a = np.arange(10)
# does the job for all pairs except the first
output = np.roll(np.flip(np.roll(a,-1).reshape((-1,2)),1).flatten(),2)
# first pair done manually
output[0] = a[-1]
output[1] = a[0]
Any ideas on a "numpy only" solution for the 2d case ?
Owing to the first pair not exactly subscribing to the usual pair swap, we can do that separately. For the rest, it would relatively straight-forward with reshaping to split axes and flip axis. Hence, it would be -
In [42]: a # 2D input array
Out[42]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]])
In [43]: b2 = a[:,1:-1].reshape(a.shape[0],-1,2)[...,::-1].reshape(a.shape[0],-1)
In [44]: np.hstack((a[:,[-1,0]],b2))
Out[44]:
array([[ 9, 0, 2, 1, 4, 3, 6, 5, 8, 7],
[19, 10, 12, 11, 14, 13, 16, 15, 18, 17]])
Alternatively, stack and then reshape+flip-axis -
In [50]: a1 = np.hstack((a[:,[0,-1]],a[:,1:-1]))
In [51]: a1.reshape(a.shape[0],-1,2)[...,::-1].reshape(a.shape[0],-1)
Out[51]:
array([[ 9, 0, 2, 1, 4, 3, 6, 5, 8, 7],
[19, 10, 12, 11, 14, 13, 16, 15, 18, 17]])

Change one-dimensional tuple using slicing / object reassignment

I understand that tuples are immutable objects, however, I know tuples support indexing and slicing. Thus, if I have a tuple assigned to a variable, I can reassign the variable to a new tuple object and change the value at the desired index position.
When I attempt to do this using an index slice, I am getting returned a tuple containing multiple tuples. I understand why this is happening, because I am passing comma separated slices of the original tuple, but I can't figure out how (if possible) I can return a one-dimensional tuple with a single element changed when working with larger sets of data.
Example:
someNumbers = tuple(i for i in range(0, 20))
print(someNumbers)
someNumbers = someNumbers[:10], 2000, someNumbers[11:]
print(someNumbers)
Outputs the following:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), 2000, (11, 12, 13, 14, 15, 16, 17, 18, 19))
Can I return a one-dimensional tuple and change only the desired index value?
Use concatenation:
someNumbers = someNumbers[:10] + (2000,) + someNumbers[11:]
You can use tuple concatenation:
someNumbers = tuple(i for i in range(0, 20))
print(someNumbers)
# (2000, ) to differentiate it from (2000) which is a number
someNumbers = someNumbers[:10]+ (2000,) + someNumbers[11:]
print(someNumbers)
Outputs:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 2000, 11, 12, 13, 14, 15, 16, 17, 18, 19)

How to do stable in-place relative reordering of elements in a list

I have this function:
def relative_reorder(my_list, before, after):
backup_of_my_list = list(my_list)
def my_key(item):
if item is after:
return backup_of_my_list.index(before) * 2 + 1
else:
return backup_of_my_list.index(item) * 2
my_list.sort(key=my_key)
That can be used like this:
stack = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]
relative_reorder(stack, 9, 7)
print(stack)
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 9, 9, 8, 8]
But I would like like to improve sorting stability
I would consider outputs such as these preferable:
[1, 2, 3, 4, 5, 6, 8, 9, 1, 2, 3, 4, 5, 6, 8, 9, 7 ,7]
[1, 2, 3, 4, 5, 6, 9, 9, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]
The goal is to reorder the list so that all occurrences of 9 are of a lower index than all occurrences of 7, while maintaining as much stability in the list as possible. One use of this is might be to order some tasks that might need to run, and we know that a certain task should always run before another task...
def last_index(l, value):
"""
Find the last occurance of value in the list
"""
# http://stackoverflow.com/q/522372/693869#comment336488_522401
return len(l) - 1 - l[::-1].index(value)
def move_item(l, old, new):
"""
Move an item from an old index to a new index
"""
l.insert(new, l.pop(old))
def relative_reorder(l, before, after):
"""
reorder list so that all occurrences of before are of a lower
index than all occurrences of after
"""
while last_index(l, before) > l.index(after):
move_item(l, last_index(l, before), l.index(after))
stack = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]
relative_reorder(stack, 9, 7)
print(stack)
[1, 2, 3, 4, 5, 6, 9, 9, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]
If anyone has a cleaner version, ill accept it

Resources