Value overrided after round played, visible when printed out - python

My code:
users = []
users.append({"name" : "",
"numerics" : [],
"score" : 0 })
users[0]["name"] = input("Your name plz: ")
def getNumbers():
for i in range(len(users)):
numbers = input("Assign 8 different numbers (separate each with a comma ','): ")
userNumbers = numbers.split(",")
return userNumbers
users[0]["numerics"] = getNumbers()
scores = []
scores.append(users[:])
print(scores)
users[0]["numerics"] = getNumbers()
scores.append(users[:])
print(scores)
Running example:
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> users = []
>>> users.append({"name" : "",
"numerics" : [],
"score" : 0 })
>>> users[0]["name"] = input("Your name plz: ")
Your name plz: Gladiator
>>> def getNumbers():
for i in range(len(users)):
numbers = input("Assign 8 different numbers (separate each with a comma ','): ")
userNumbers = numbers.split(",")
return userNumbers
>>> users[0]["numerics"] = getNumbers()
Assign 8 different numbers (separate each with a comma ','): 99,23,55,11,19,100,1000,89
>>> scores = []
>>> scores.append(users[:])
>>> print(scores)
[[{'numerics': ['99', '23', '55', '11', '19', '100', '1000', '89'], 'name': 'Gladiator', 'score': 0}]]
>>> users[0]["numerics"] = getNumbers()
Assign 8 different numbers (separate each with a comma ','): 100,56,77,32,99,22,45,2
>>> scores.append(users[:])
>>> print(scores)
[[{'numerics': ['100', '56', '77', '32', '99', '22', '45', '2'], 'name': 'Gladiator', 'score': 0}], [{'numerics': ['100', '56', '77', '32', '99', '22', '45', '2'], 'name': 'Gladiator', 'score': 0}]]
>>>
I want to be able to for each new round in the game, make changes to the user numerics and score, and append it to the score list and then print that out. However, it seems like my current way is just overriding the numerics and the score. But mostly the numerics part.
This doesn't seem to work at all: users[0]["score"].append(getNumbers())
Or should I simply clear the values in the list, e.g. score and numerics for each new round for the player.
Round 1:
Player: Gladiator
Numerics: ['99', '23', '55', '11', '19', '100', '1000', '89']
Round 2:
Player: Gladiator
Numerics: ['100', '56', '77', '32', '99', '22', '45', '2']
But the print out shows:
[[{'numerics': ['100', '56', '77', '32', '99', '22', '45', '2'],
'name': 'Gladiator', 'score': 0}],
[{'numerics': ['100', '56', '77', '32', '99', '22', '45', '2'],
'name': 'Gladiator', 'score': 0}]]
EDIT: I tried resetting the list of numerics:
users[0]['numerics'] = []
TypeError: list indices must be integers or slices, not tuple
Test ran the code example by #Sarathsp
Your name plz: Gladiator
Assign 8 different numbers (separate each with a comma ','): 99,100,1000,4,66,77,11,9
[[{'name': 'Gladiator', 'numerics': ['99', '100', '1000', '4', '66', '77', '11', '9'], 'score': 0}]]
Assign 8 different numbers (separate each with a comma ','): 100,33,44,55,0,1,9,2
[[{'name': 'Gladiator', 'numerics': ['99', '100', '1000', '4', '66', '77', '11', '9'], 'score': 0}], [{'name': 'Gladiator', 'numerics': ['100', '33', '44', '55', '0', '1', '9', '2'], 'score': 0}]]

Assignment statements in Python do not copy objects, they create bindings between a target and an object. You have to use deep copy to copy the users list
there is a module copy
you may use it as
copy.deepcopy(users)
Here is how your program look like
import copy
users = []
users.append({"name" : "",
"numerics" : [],
"score" : 0 })
users[0]["name"] = input("Your name plz: ")
def getNumbers():
for i in range(len(users)):
numbers = input("Assign 8 different numbers (separate each with a comma ','): ")
userNumbers = numbers.split(",")
return userNumbers
users[0]["numerics"] = getNumbers()
scores = []
scores.append(copy.deepcopy(users))
print(scores)
users[0]["numerics"] = getNumbers()
scores.append(copy.deepcopy(users))
print(scores)

Related

Adding a single 'counter' to each element of an array of lists

I've got a .dat file that i I've pulled the data from and i was using the tabulate plug in to tidy it up and put it into tables. However, part of the question is to add a position column or counter. It should be simple enough to add one element at the start of each list in my array but i am having an absolute nightmare...
the code for pulling in the data from the .dat file is:
def readToDictionary():
global dicts
fi = open('CarRegistry.dat', 'r')
dicts = []
buffer = []
while True:
team = fi.readline()
if not team: break
fields = team.split(',')
buffer.append(fields)
fi.close()
dicts = buffer
print(dicts)
return dicts
Im duplicating the array deliberately as i need to do some other functions on it and want to keep the original data intact.
The raw out put is:
[['1', 'BD61 SLU', 'HONDA', 'CR-V', 'SFDR', '5', '1780', '4510', '130', '39', 'True\n'], ['2', 'CA51 MBE', 'CHEVROLET', 'CORVETTE', 'JTAV', '2', '1877', '1234', '194', '24', 'True\n'], ['3', 'PC14 RSN', 'FORD', 'F-150', 'PQBD', '5', '2121', '5890', '155', '20', 'True\n'], ['4', 'MB19 ORE', 'HONDA', 'ACCORD', 'FDAR', '5', '1849', '4933', '125', '47.3', 'False\n'], ['5', 'BD68 NAP', 'HONDA', 'ACCORD', 'FDAV', '5', '1849', '4933', '171', '37.7', 'False\n']...
what i want to get to is:
[['1', '1', 'BD61 SLU', 'HONDA', 'CR-V', 'SFDR', '5', '1780', '4510', '130', '39', 'True\n'], ['2', '2', 'CA51 MBE', 'CHEVROLET', 'CORVETTE', 'JTAV', '2', '1877', '1234', '194', '24', 'True\n'], ['3', '3', 'PC14 RSN', 'FORD', 'F-150', 'PQBD', '5', '2121', '5890', '155', '20', 'True\n'], ['4', '4', 'MB19 ORE', 'HONDA', 'ACCORD', 'FDAR', '5', '1849', '4933', '125', '47.3', 'False\n'], ['5', '5', 'BD68 NAP', 'HONDA', 'ACCORD', 'FDAV', '5', '1849', '4933', '171', '37.7', 'False\n']...
It's basically a counter at the start of each list.
Ive tried all sorts and just keep getting errors, probably because i cant understand the basics of why i cant just do this:
for i in buffer:
buffer.insert(i, i+1)
to go through each entry in the list and add a value equal to the index +1... I know its probably simple but i've been banging my head off the monitor for a good few hours now...
The key is, you don't want to manipulate buffer. You want to manipulate the individual lists within buffer:
for i,row in enumerate(buffer):
row.insert( 0, str(i+1) )

How to automate single line code, with changes in input?

I have created a variable named 'j' which has some values and I want my code to pick one value at a time and execute.
I tried writing code but it does not work. I'm sharing my code please see when it can be improved.
j = ['0', '1', '3', '4', '6', '7', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67']
for i in j:
labels('i') = mne.read_labels_from_annot('sub-CC721377_T1w', parc='aparc', subjects_dir=subjects_dir)['i']
done
According to the MNE documentation, the function read_labels_from_annot returns a list of labels.
Thus, instead of indexing the result with ...)[0] at the end, you should just capture the entire list:
labels = mne.read_labels_from_annot(...)
This would capture a list of labels, rather than a single label, which would have the effect of 'indexing at the end "[0]" from 0 - 67'.
You asked about adding all the results together into a label_all variable. You didn't specify (and I don't know anything about the MNE package), so it's not clear: do the labels ever repeat? Is is possible that "lab123" will occur in every input file? If so, should the label_all store multiple copies of the same value, or just the unique label names?
I think something like this is what you're after:
import mne
def get_labels_for_subject(sub, *, hemi='both', parc='aparc', **kwargs):
"""Get MNE labels for a given subject. **kwargs allows passing named
parameters like subjects_dir, regexp, and others that default to None."""
labels = mne.read_labels_from_annot(sub, hemi=hemi, parc=parc, **kwargs)
return labels
# List of all the subjects
subjects = [
'sub-CC721377_T1w',
'sub-next???',
]
label_all = []
for s in subjects:
label_all.extend(get_labels_for_subject(s, subjects_dir='.'))
print("Got labels:", label_all)

Python set remove Non Numeric values

I have set value like below:
set(['Virtual', '120', 'P', '130', '90', '250', '100', '10', 'Mar', 'indicates', '18', '50', '40', '1', '|'])
How do i remove all Non Numeric value?
Output expected:
set(['120', '130', '90', '250', '100', '10','18', '50', '40', '1'])
You can create a new set:
number_set = set()
for object in old_set:
try:
number_set.add(int(object))
except ValueError:
print("Not a number")
print(number_set)
You can also try removing all non-numeric objects from the set:
for object in old_set:
try:
x = int(object)
execpt ValueError:
old_set.remove(object)
You can use a filter to clean your set:
s = set(['Virtual', '120', 'P', '130', '90', '250', '100', '10', 'Mar', 'indicates', '18', '50', '40', '1', '|'])
def isInt(text):
"""Returns True for a text that is convertable to int() else False."""
try:
_ = int(text)
return True
except ValueError:
return False
# apply filter:
filteredSet = set( filter(lambda x:isInt(x), s))
print(filteredSet)
Output:
{'18', '90', '130', '120', '40', '50', '10', '1', '100', '250'}
This output differs from your want's - but thats how python prints a set with print.

Python - List of unique sequences

I have a dictionary with elements as lists of certain sequence:
a = {'seq1':['5', '4', '3', '2', '1', '6', '7', '8', '9'],
'seq2':['9', '8', '7', '6', '5', '4', '3', '2', '1'],
'seq3':['5', '4', '3', '2', '1', '11', '12', '13', '14'],
'seq4':['15', '16', '17'],
'seq5':['18', '19', '20', '21', '22', '23'],
'seq6':['18', '19', '20', '24', '25', '26']}
So there are 6 sequences
What I need to do is:
To find only unique lists (if two lists contains the same elements (regardless of their order), they are not unique) - say I need to get rid of the second list (the first founded unique list will stay)
In unique lists I need to find unique subsequences of elements and print
it
Bounds of unique sequences are found by resemblance of elements order - in the 1st and the 3rd lists the bound ends exactly after element '1', so we get the subsequence ['5','4','3','2','1']
As the result I would like to see elements exactly in the same order as it was in the beginning (if it`s possible at all somehow). So I expect this:
[['5', '4', '3', '2', '1']['6', '7', '8', '9']['11', '12', '13', '14']['15', '16', '17']['18', '19', '20']['21', '22', '23']['24', '25', '26']]
Tried to do it this way:
import itertools
unique_sets = []
a = {'seq1':["5","4","3","2","1","6","7","8","9"], 'seq2':["9","8","7","6","5","4","3","2","1"], 'seq3':["5","4","3","2","1","11","12","13","14"], 'seq4':["15","16","17"], 'seq5':["18","19","20","21","22","23"], 'seq6':["18","19","20","24","25","26"]}
b = []
for seq in a.values():
b.append(seq)
for seq1, seq2 in itertools.combinations(b,2): #searching for intersections
if set(seq1).intersection(set(seq2)) not in unique_sets:
#if set(seq1).intersection(set(seq2)) == set(seq1):
#continue
unique_sets.append(set(seq1).intersection(set(seq2)))
if set(seq1).difference(set(seq2)) not in unique_sets:
unique_sets.append(set(seq1).difference(set(seq2)))
for it in unique_sets:
print(it)
I got this which is a little bit different from my expectations:
{'9', '5', '2', '3', '7', '1', '4', '8', '6'}
set()
{'5', '2', '3', '1', '4'}
{'9', '8', '6', '7'}
{'5', '2', '14', '3', '1', '11', '12', '4', '13'}
{'17', '16', '15'}
{'19', '20', '18'}
{'23', '21', '22'}
Without comment in the code above the result is even worse.
Plus I have the problem with unordered elements in the sets, which I get as the result. Tried to do this with two separate lists:
seq1 = set([1,2,3,4,5,6,7,8,9])
seq2 = set([1,2,3,4,5,10,11,12])
and it worked fine - elements didn`t ever change their position in sets. Where is my mistake?
Thanks.
Updated: Ok, now I have a little bit more complicated task, where offered alghorithm won`t work
I have this dictionary:
precond = {
'seq1': ["1","2"],
'seq2': ["3","4","2"],
'seq3': ["5","4","2"],
'seq4': ["6","7","4","2"],
'seq5': ["6","4","7","2"],
'seq6': ["6","1","8","9","10"],
'seq7': ["6","1","8","11","9","12","13","14"],
'seq8': ["6","1","8","11","4","15","13"],
'seq9': ["6","1","8","16","9","11","4","17","18","2"],
'seq10': ["6","1","8","19","9","4","16","2"],
}
I expect these sequences, containing at least 2 elements:
[1, 2],
[4, 2],
[6, 7],
[6, 4, 7, 2],
[6, 1, 8]
[9,10],
[6,1,8,11]
[9,12,13,14]
[4,15,13]
[16,9,11,4,17,18,2]
[19,9,4,16,2]
Right now I wrote this code:
precond = {
'seq1': ["1","2"],
'seq2': ["3","4","2"],
'seq3': ["5","4","2"],
'seq4': ["6","7","4","2"],
'seq5': ["6","4","7","2"],
'seq6': ["6","1","8","9","10"],
'seq7': ["6","1","8","11","9","12","13","14"],
'seq8': ["6","1","8","11","4","15","13"],
'seq9': ["6","1","8","16","9","11","4","17","18","2"],
'seq10': ["6","1","8","19","9","4","16","2"],
}
seq_list = []
result_seq = []
#d = []
for seq in precond.values():
seq_list.append(seq)
#print(b)
contseq_ind = 0
control_seq = seq_list[contseq_ind]
mainseq_ind = 1
el_ind = 0
#index2 = 0
def compar():
if control_seq[contseq_ind] != seq_list[mainseq_ind][el_ind]:
mainseq_ind += 1
compar()
else:
result_seq.append(control_seq[contseq_ind])
contseq_ind += 1
el_ind += 1
if contseq_ind > len(control_seq):
control_seq = seq_list[contseq_ind + 1]
compar()
else:
compar()
compar()
This code is not complete anyway - I created looking for the same elements from the beginning, so I still need to write a code for searching of sequence in the end of two compared elements.
Right now I have a problem with recursion. Immidiately after first recursed call I have this error:
if control_seq[contseq_ind] != b[mainseq_ind][el_ind]:
UnboundLocalError: local variable 'control_seq' referenced before assignment
How can I fix this? Or maybe you have a better idea, than using recursion? Thank you in advance.
Not sure if this is what you wanted, but it gets the same result:
from collections import OrderedDict
a = {'seq1':["5","4","3","2","1","6","7","8","9"],
'seq2':["9","8","7","6","5","4","3","2","1"],
'seq3':["5","4","3","2","1","11","12","13","14"],
'seq4':["15","16","17"],
'seq5':["18","19","20","21","22","23"],
'seq6':["18","19","20","24","25","26"]}
level = 0
counts = OrderedDict()
# go through each value in the list of values to count the number
# of times it is used and indicate which list it belongs to
for elements in a.values():
for element in elements:
if element in counts:
a,b = counts[element]
counts[element] = a,b+1
else:
counts[element] = (level,1)
level+=1
last = 0
result = []
# now break up the dictionary of unique values into lists according
# to the count of each value and the level that they existed in
for k,v in counts.items():
if v == last:
result[-1].append(k)
else:
result.append([k])
last = v
print(result)
Result:
[['5', '4', '3', '2', '1'],
['6', '7', '8', '9'],
['11', '12', '13', '14'],
['15', '16', '17'],
['18', '19', '20'],
['21', '22', '23'],
['24', '25', '26']]

Random data generator mathing a regex in python

In python, I am looking for python code which I can use to create random data matching any regex. For example, if the regex is
\d{1,100}
I want to have a list of random numbers with a random length between 1 and 100 (equally distributed)
There are some 'regex inverters' available (see here) which compute ALL possible matches, which is not what I want, and which is extremely impracticable. The example above, for example, has more then 10^100 possible matches, which never can be stored in a list. I just need a function to return a match by random.
Maybe there is a package already available which can be used to accomplish this? I need a function that creates a matching string for ANY regex, not just the given one or some other, but maybe 100 different regex. I just cannot code them myself, I want the function extract the pattern to return me a matching string.
If the expressions you match do not have any "advanced" features, like look-ahead or look-behind, then you can parse it yourself and build a proper generator
Treat each part of the regex as a function returning something (e.g., between 1 and 100 digits) and glue them together at the top:
import random
from string import digits, uppercase, letters
def joiner(*items):
# actually should return lambda as the other functions
return ''.join(item() for item in items)
def roll(item, n1, n2=None):
n2 = n2 or n1
return lambda: ''.join(item() for _ in xrange(random.randint(n1, n2)))
def rand(collection):
return lambda: random.choice(collection)
# this is a generator for /\d{1,10}:[A-Z]{5}/
print joiner(roll(rand(digits), 1, 10),
rand(':'),
roll(rand(uppercase), 5))
# [A-C]{2}\d{2,20}#\w{10,1000}
print joiner(roll(rand('ABC'), 2),
roll(rand(digits), 2, 20),
rand('#'),
roll(rand(letters), 10, 1000))
Parsing the regex would be another question. So this solution is not universal, but maybe it's sufficient
Two Python libraries can do this: sre-yield and Hypothesis.
sre-yield
sre-yeld will generate all values matching a given regular expression. It uses SRE, Python's default regular expression engine.
For example,
import sre_yield
list(sre_yield.AllStrings('[a-z]oo$'))
['aoo', 'boo', 'coo', 'doo', 'eoo', 'foo', 'goo', 'hoo', 'ioo', 'joo', 'koo', 'loo', 'moo', 'noo', 'ooo', 'poo', 'qoo', 'roo', 'soo', 'too', 'uoo', 'voo', 'woo', 'xoo', 'yoo', 'zoo']
For decimal numbers,
list(sre_yield.AllStrings('\d{1,2}'))
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99']
Hypothesis
The unit test library Hypothesis will generate random matching examples. It is also built using SRE.
import hypothesis
g=hypothesis.strategies.from_regex(r'^[A-Z][a-z]$')
g.example()
with output such as:
'Gssov', 'Lmsud', 'Ixnoy'
For decimal numbers
d=hypothesis.strategies.from_regex(r'^[0-9]{1,2}$')
will output one or two digit decimal numbers: 65, 7, 67 although not evenly distributed. Using \d yielded unprintable strings.
Note: use begin and end anchors to prevent extraneous characters.
From this answer
You could try using python to call this perl module:
https://metacpan.org/module/String::Random

Categories

Resources