How to retain values appended to a python list - python

Please I need help with this code.I want mylist to retain values appended to it next time the function 'no_repeat_rule' is called. I'm pretty new to python. My code is below:
def no_repeat_rule(play_board):
mylist = list()
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
mylist.append(play_board)
return mylist
Output of this code (in part) is:
...
[[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]
Player 1 chose cup 0
[[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]
Player 2 chose cup 6
[[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]]
...
what I want the function 'no_repeat_rule' to do is to grow mylist each time a player plays. I don't know if this is clear enough to get help?

The simplest thing to do would be to add another parameter in the function defintion, such that it looks like:
def no_repeat_rule(play_board, aList):
Before you call the function, declare a list outside of the function. Set this equal to the result of the function, and pass it as a parameter whenever you call the function. For instance:
x = list()
def no_repeat_rule(play_board, aList):
myList = aList
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
myList.append(play_board)
return myList
x = no_repeat_rule(someBoardHere, x)
I believe this should work if I understand what you're asking. If not, please respond and I'll try something else.

what do you need is an object which is associated with the function. It calls attribute. It is very handy in python.
Your code may look like this:
def no_repeat_rule(play_board):
if not hasattr(no_repeat_rule,"mylist"):
no_repeat_rule.mylist = []
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
no_repeat_rule.mylist.append(play_board)
return no_repeat_rule.mylist
I couldn't check this code, but it should work for local atributes. BTW it is for python 2.7

Related

Python Binary Number Class: Numpy Array Manipulation Getting "TypeError: 'bool' object is not iterable"

I am trying to create a class called "Binary" and the main idea of it is to take a string representing a fixed width binary number that is 16 bits as it's only parameter and store it as a numpy integer array into it's one instance variable "bit_array".
If the given string is greater than 16 characters or contains anything other than 0's and 1's, it is to raise a RuntimeError. If "string" is less than 16 characters, it is to pad on the leftmost digit of given string onto the start of the numpy array until the resulting array contains exactly 16 digits. The given string defaults to '0' and accepts an empty string, treating an empty string as '0'. The code I have written for init is as follows (in "hw4.py" - the main file for this assignment):
import numpy as np
class Binary:
def __init__(self, string='0'):
if not string:
string = '0'
else:
if len(string) > 16:
raise RuntimeError
else:
for i in string:
if i != '1' and i != '0':
raise RuntimeError
if len(string) == 16:
int_arr = np.array(tuple(string))
self.bit_array = int_arr
else:
int_arr_inc = np.array(tuple(string))
if int_arr_inc[0] == 0:
pad = np.zeros((16 - len(int_arr_inc)), int)
else:
pad = np.ones((16 - len(int_arr_inc)), int)
self.bit_array = np.concatenate((pad, int_arr_inc))
There is also an eq overloaded method intended to compare the bit_array of another "Binary" object in this class (this passes the spec's test case so there shouldn't be any changes required here, just more for being transparent):
def __eq__(self, other):
if str(self.bit_array) == str(other.bit_array):
return True
else:
return False
The spec requires that there is no use of list() or any form of lists at all in the init method. The method is not to return anything and it's only purpose is to build a Binary object that has a bit_array that converts the string parameter into a numpy integer array. The test cases I have to test against calls the following test case (in a test file "hw4_test.py"):
from hw4 import Binary
import unittest, numpy as np
class TestBinary(unittest.TestCase):
def setUp(self):
self.bin_0 = Binary("")
self.bin_1 = Binary("01")
self.bin_2 = Binary("010")
def test_init(self):
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) == self.bin_0.bit_array))
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) == self.bin_1.bit_array))
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]) == self.bin_2.bit_array))
However, the first test case here fails, giving me :
Traceback (most recent call last):
File "C:\Users\17606\Desktop\ISTA-350\hw4\hw4_test.py", line 30, in test_init
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) == self.bin_0.bit_array))
TypeError: 'bool' object is not iterable
I've tried many ways of creating the numpy arrays, such as fromstring (which is deprecated anyways) and trying with a map of the parameter string, to no avail. As the test case code above shows, I am expecting
Binary("")
To result in a Binary object containing a bit_array of a numpy array like
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
But the TypeError above keeps occuring. Any ideas? I am having trouble understanding where I am even iterating over anything that could be a bool type. I am using Python 3.10 on Windows 10 with PyCharm as my IDE.
P.S
This is for a school course and I am not very concerned about conventions or efficiency for this. Just syntax and logic :)
Thanks!

Unit Testing Sudoku - should the tests try to be independent of the data structure for the Sudoku board?

I'm learning unit testing and TDD in python and have got the basics mastered with pytest.
I've started a learning project of writing a sudoku solver and one thing I'm realising is that at the start I'm not currently sure how I want to store the data for the sudoku board. Many talks warn about testing behaviour over implementation. Would the board data structure count as implementation?
It's very hard to write a test that is independent of the board data structure.
For example you could store the values of each cell as an integer (eg 1) or a string (eg '1') and the board as a whole can be a dict (using cell label like 'A1' or 'C5' etc as keys), list (flat or 2d) or a 81 character string.
So I might start with
hardboard = [
[0, 0, 0, 0, 0, 0, 4, 0, 0],
[0, 0, 1, 0, 7, 0, 0, 9, 0],
[5, 0, 0, 0, 3, 0, 0, 0, 6],
[0, 8, 0, 2, 0, 0, 0, 0, 0],
[7, 0, 0, 0, 0, 0, 9, 2, 0],
[1, 2, 0, 6, 0, 5, 0, 0, 0],
[0, 5, 0, 0, 0, 0, 0, 4, 0],
[0, 7, 3, 9, 0, 8, 0, 0, 0],
[6, 0, 0, 4, 5, 0, 2, 0, 0]
]
but then decide to use a dict
hardboard = {'A1': 0, 'A2': 0, 'A3': 0, ... 'I9': 0}
So how should I start? The only solution I can think of is to commit to one format, at least in terms how I represent the board in tests, even if the actual code uses a different data structure later and has to translate. But in my TDD noobiness I'm unsure if this is a good idea?
I'm not a python developer, but still:
Don't think about the board in terms of implementation details (like, this is a dictionary, array, slice, whatever).
Instead imagine that the board is an abstraction and it has some behaviors - which are in plain words - things you can do with a board:
place a digit in an index(i,j) that should be in 1 to 9 inclusive boundaries
remove a digit by index (i,j)
So its like you have a "contract" - you create a board and can execute some operations on it. Of course it has some internal implementation, but its hidden from everyone who uses it. Its your responsibility to provide a working implementation but this is what you want to test: The implementation is considered working if it "reacts" on all the operations correctly (behavior = operation = function at the level of actual programming implementation)
In this case your test (schematically might look like this):
Board Tests:
Test 1 : Check that its impossible to put a negative i index:
// setup
board = ...
// when:
board.put(-1, 3, 8) // i-index is wrong
// then:
expect exception to be thrown
Test 2 : Check that its impossible to put a negative j index:
// setup
board = ...
// when:
board.put(0, -1, 5) // j-index is wrong
// then:
expect exception to be thrown
Test 3 : Check that its impossible to put a negative number into cell:
// setup
board = ...
// when:
board.put(0, 0, -7)
// then:
expect exception to be thrown
Test 4 : Check that its impossible to put number that alreay contains another number:
// setup
board = ...
// when:
board.put(0, 0, 6)
board.put(0, 0, 5)
// then:
expect exception to be thrown
... and so on and so forth (also cover with tests for getting a cell, and any other additional behavior you create for the board).
Note, that all these tests indeed check the behavior of your abstraction rather than internal implementation.
At the level of implementation you can create a class for the board, internal data fields will contain the state, whereas the behavior will be represented by the methods exposed to the users of the class.

How to convert a string to list using python?

I am working with RC-522 RFID Reader for my project. I want to use it for paying transportation fee. I am using python and used the code in: https://github.com/mxgxw/MFRC522-python.git
On python script Read.py, Sector 8 was read with the use of this code:
# Check if authenticated
if status == MIFAREReader.MI_OK:
MIFAREReader.MFRC522_Read(8) <---- prints the sector 8
MIFAREReader.MFRC522_StopCrypto1()
else:
print "Authentication error"
The output of this was:
Sector 8 [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
So that last part(Sector 8 [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), I convert it to string. I want that to be a list but I can't. Tried to put it on a variable x and use x.split() but the output when I execute print(x) is "None".
x = str(MIFAREReader.MFRC22_READ(8))
x = x.split()
print x #PRINTS ['NONE']
I want it to be like this:
DATA = [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
so that I can use the sum(DATA) to check for balance, and I can access it using indexes like DATA[0]
Thanks a lot!!
Follow these steps:
Open MFRC522.py >> header file for RFID Reader
vi MFRC522.py
look for function
def MFRC522_Read(self, blockAddr)
add this line return backData at the end of function.
Save it.
In read() program, call it like
DATA=(MIFAREReader.MFRC522_Read(8))
print 'DATA :',DATA
I hope this solves the problem.
You can use .split(",") to specify the delimiter ",".
Something like that:
input_string = "[100, 234, 0, 0, 567, 0, 0, 0, 3, 0, 235, 0, 0, 12, 0, 0]"
listed_string = input_string[1:-1].split(",")
sum = 0
for item in listed_string:
sum += int(item)
print(sum)
prints
1151
In line with Moutch answer, using list comprehension:
input='[100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]'
DATA = [int(item) for item in input[1:-1].split(',')]
print(sum(DATA))
If data string is entire output of Read.Py
input="""Card read UID: 67,149,225,43
Size: 8
Sector 8 [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"""
#find index position of 'Sector' text and select from this using slices.
inputn = input[input.index('Sector')+9:]
DATA = [int(item) for item in inputn[1:-1].split(',')]
print(DATA)
print(sum(DATA))
If you have some guarantee about the source and nature of the data in that list (and you know the format will always be the same), Python's eval would work. For example:
original_string = 'Sector 8 [100, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]'
data_start_index = original_string.index('[') # find '['
data_string = original_string[data_start_index:] # extract the list
data = eval(data_string)
print(type(data)) # <class 'list'>
print(sum(data)) # 101
If you don't have these guarantees, you'll have to use the split method as suggested by Moutch, due to the fragility and exploitability of eval - it blindly executes whatever (potentially malicious) code is passed to it.
Edit: Use ast.literal_eval instead of plain old eval for safety guarantees. This still requires that the formatting of the string be consistent (e.g., that it always have square brackets) in order to properly evaluate to a Python list.

adding tuples to a list in an if loop (python)

I'm working in python with symbulate for a probability course and running some simulations.
Setup: Two teams, A and B, are playing in a “best of n” game championship series, where n is an odd number. For this example, n=7, and the probability team A wins any individual game is 0.55. Approximate the probability that Team A wins the series, given that they win the first game.
Here is what I've got so far, which I think is along the right lines:
model = BoxModel([1, 0], probs=[0.55, .45], size=7, replace=True)
test = model.sim(10000)
for x in range(0,10000):
test1 = test[x]
if test1[0] == 1:
print (test1)
test1
The last two lines are where I'm having my difficulty. This 'for' and 'if' combination makes it so only the inputs that start with a '1' (i.e. Team A winning the first game) are displayed. I need to save these inputs into a table so that I can run some further testing on it.
How do I input the value of test1 into a table while those loops are running? Currently, test1 only outputs the x=10,000th value.
Edit: The "test" yields a list, 0-10000, of all the possible game outcomes. I need a list that only has the game outcomes that start with a "1".
Edit2: Output of "test" (before I run a "for" or "if") look like:
Index Result
0 (1, 1, 1, 0, 0, 1, 1)
1 (0, 1, 0, 1, 1, 0, 0)
2 (1, 1, 1, 1, 0, 1, 0)
3 (0, 0, 1, 1, 1, 1, 1)
4 (0, 0, 0, 0, 0, 0, 0)
5 (1, 1, 0, 1, 0, 0, 1)
6 (0, 0, 1, 0, 1, 1, 1)
7 (0, 1, 0, 0, 0, 0, 1)
8 (1, 1, 0, 1, 0, 1, 0)
... ...
9999 (1, 1, 0, 1, 0, 0, 0)
I need a "test' (or another variable) to contain something that looks EXACTLY like that, but only contains lines that start with "1".
So you're looking to store the results of each test? Why not store them in a list?
test1_results = []
for x in range(0,10000):
test1 = test[x]
# check if first element in sequence of game outcomes is a win for team A
if test1[0] == 1: # or '1' if you're expecting string
test1_results.append(test1)
You can the run print(test1_results) to print the entire list of results, but if you want to print the first n results, do print(test1_results[:n]).
If you want your if statement in there, you will have to slightly adjust the placement. What does your test object look like? Could you give us a small sample?
edit: updated if statement to reflect comment below
Based on your comment:
results_that_start_with_one = []
for result in test:
result_string = str(result)
if result_string[0] == "1":
results_that_start_with_one.append(result_string)
This iterates through each of your results in the list "test". It convert each to a string (i'm assuming they are some numeric value). It then takes the first character in the string, and asks if its a 1.

Error regarding list traceback function

I am trying to return the elements starting from the last row which are equal to 1 and not zero.And then traceback the next element by comparing with adjacent elements vertically,horizontally and diagonally.if next element is zero,then return the position,else continue till we reach a position where the next element will be zero and hence return the position.
I have written the following program:
def test():
M=[[0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0, 1],
[2, 1, 0, 0, 1, 0, 0]]
list=[]
for i in range(2,0,-1):
for j in range(6,0,-1):
if M[i,j]!=0 and M[i,j]<=k:
s=max(M[i,j-1],M[i-1,j-1],M[i-1,j])
if s==0:
list.append(j+1)
else:
s=M[i,j]
elif j==0:
for i in range(2,0,-1):
if M[i,j]!=0 and M[i,j]<=k:
s=M[i-1,j]
if s==0:
list.append(j+1)
else:
s=M[i,j]
return list
print(test())
Expected answer will be 1,4,7
It returned me values 4,7 but 1 is not showing,can anyone suggest me the additions that it returns me the value '1' as well ?I have tried editing the code,but still it shows the same result.

Categories