So I am trying to create a grid that can have it's individual "grid squares" replaced by any given symbol. The grid works fine but it is made of lists within lists.
Here's the code
size = 49
feild = []
for i in range(size):
feild.append([])
for i in range(size):
feild[i].append("#")
feild[4][4] = "#" #This is one of the methods of replacing that I have tried
for i in range(size):
p_feild = str(feild)
p_feild2 = p_feild.replace("[", "")
p_feild3 = p_feild2.replace("]", "")
p_feild4 = p_feild3.replace(",", "")
p_feild5 = p_feild4.replace("'", "")
print(p_feild5)
As you can see that is one way that I have tried to replace the elements, I have also tried:
feild[4[4]] = "#"
and
feild[4] = "#"
The first one replaces all "#" 4 elements in from the left with "#"
The second one gives the following error
TypeError: 'int' object is not subscriptable
The make a grid of # with row 3, column 3 replaced with #:
>>> size = 5
>>> c = '#'
>>> g = [size*[c] for i in range(size)]
>>> g[3][3] = '#'
>>> print('\n'.join(' '.join(row) for row in g))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
May be you're looking for this :-
size = 49
feild = []
for i in range(size):
feild.append([])
for i in range(size):
map(feild[i].append, ["#" for _ in xrange(size)])
i = 4
feild[i][0] = "#"
Related
I want to print a square pattern with "#", the output should look something like this:
# # # # #
# #
# #
# #
# # # # #
The code I was able to write is this:
n=10
for i in range (1,6):
for j in range(1,6):
if i ==1 or 1==n or j==1 or j==n:
print("#", end= ' ')
else:
print(" ", end="")
print()
The output that came is this:
# # # # #
#
#
#
#
I also would like to know if it's possible to only have one print statement instead of many.
Thank you.
This works!
s=5
print(" ".join("#"*s))
for i in range(0,s-2):
print("#"+" "*(s+2)+"#")
print(" ".join("#"*s))
>>>
# # # # #
# #
# #
# #
# # # # #
Single line:
print(" ".join("#"*s)+"\n"+("#"+" "*(s+2)+"#"+"\n")*(s-2)+" ".join("#"*s))
>>>
# # # # #
# #
# #
# #
# # # # #
A simple one-liner for this with a whole square filled in could be
size = 6
print('\n'.join([' '.join('#' * size)] * size))
Or if you want the same pattern in the original
print(' '.join('#' * size))
print('\n'.join('#' * (size - 1)))
I noticed the empty spaces in between the hashtags, use this function it should give you custom dimensions too
def createSquare(xLen,yLen):
for i in range(1,yLen):
if i == 1 or i == yLen-1:
print("# "*xLen)
else:
print("#"+" "*int(xLen*2-3)+"#")
createSquare(10,10)
MFCC_coeffs = 12
train_data = []
current_block = []
MAX_ROWS = 29
row_counter = 0
for line in f:
element = line.split(' ')
if(len(element) == MFCC_coeffs+1):
row_counter = row_counter + 1
element = element[:-1]
element = [float(i) for i in element]
current_block.append(element)
# print("HERE")
# print(f"element = {element}, length = {len(element)}")
elif(len(element) == 1):
if row_counter<MAX_ROWS:
padding = MAX_ROWS-row_counter
while(padding):
pad_row = [0]*MFCC_coeffs
current_block.append(pad_row)
padding = padding-1
row_counter = 0
# print(f"element = {element}, length = {len(element)}")
# print(f"current_block = {current_block}, shape = {np.shape(current_block)}")
train_data.append(current_block)
# print(f"train_data shape = {np.shape(train_data)}") ## PRINTS CORRECT SIZE AT THE END OF THE FILE. E.G. (370,29,12)
current_block.clear()
continue
else:
assert("Wrong Data")
print(f"train_data = {train_data}, shape = {np.shape(train_data)}") ## SIZE TO (370,0)
In the previous block of code, I am reading a text file and storing to a train_data variable. As I keep going through a text file line by line, the train_data is appended and reaches size (370*29*12) by the end which is correct. However once I get out of the file read block of code, the final size of train_data gets reset to (370*0). I have commented in block letters the part where the output is correct and where it is wrong.
The issue is, that you're appending the same reference to current_block to train_data. Consider this example:
current_block = []
train_data = []
current_block = [1]
train_data.append(current_block) # train_data = [[1]]
current_block.clear() # train_data = [[]]
current_block.append(2) # train_data = [[2]]
train_data.append(current_block) # train_data = [[2], [2]]
current_block.clear() # train_data = [[], []]
As you see, current_block.clear() will the list - and subsequently all references in train_data.
The solution is to append a copy to train_data:
train_data.append(current_block[:])
That way, the next current_block.clear() won't clear any data already inside train_data.
EDIT:
Thanks for fixing it! Unfortunatelly, it messed up the logic. I'll explain what this program does. It's a solution to a task about playing cards trick. There are N cards on the table. First and Second are numbers on the front and back of the cards. The trick can only be done, if the visible numbers are in non-decreasing order. Someone from audience can come and swap places of cards. M represents how many cards will be swapped places. A and B represent which cards will be swapped. Magician can flip any number of cards to see the other side. The program must tell, if the magician can do the trick.
from collections import namedtuple
Pair = namedtuple("Pair", ["first", "second"])
pairs = []
with open('data.txt', 'r') as data, open('results.txt', 'w') as results:
n = data.readline()
n = int(n)
for _ in range(n):
first, second = (int(x) for x in data.readline().split(':'))
first, second = sorted((first, second))
pairs.append(Pair(first, second)) # add to the list by appending
m = data.readline()
m = int(m)
for _ in range(m):
a, b = (int(x) for x in data.readline().split('-'))
a -= 1
b -= 1
temp = pairs[a]
pairs[a] = pairs[b]
pairs[b] = temp
p = -1e-9
ok = True
for k in range(0, n):
if pairs[k].first >= p:
p = pairs[k].first
elif pairs[k].second >= p:
p = pairs[k].second
else:
ok = False
break
if ok:
results.write("YES\n")
else:
results.write("NO\n")
data:
4
2:5
3:4
6:3
2:7
2
3-4
1-3
results:
YES
YES
YES
YES
YES
YES
YES
What should be in results:
NO
YES
The code is full of bugs: you should write and test it incrementally instead of all at once. It seems that you started using readlines (which is a good way of managing this kind of work) but you kept the rest of the code in a reading one by one style. If you used readlines, the line for i, line in enumerate(data): should be changed to for i, line in enumerate(lines):.
Anyway, here is a corrected version with some explanation. I hope I did not mess with the logic.
from collections import namedtuple
Pair = namedtuple("Pair", ["first", "second"])
# The following line created a huge list of "Pairs" types, not instances
# pairs = [Pair] * (2*200*1000+1)
pairs = []
with open('data.txt', 'r') as data, open('results.txt', 'w') as results:
n = data.readline()
n = int(n)
# removing the reading of all data...
# lines = data.readlines()
# m = lines[n]
# removed bad for: for i, line in enumerate(data):
for _ in range(n): # you don't need the index
first, second = (int(x) for x in data.readline().split(':'))
# removed unnecessary recasting to int
# first = int(first)
# second = int(second)
# changed the swapping to a more elegant way
first, second = sorted((first, second))
pairs.append(Pair(first, second)) # we add to the list by appending
# removed unnecessary for: once you read all the first and seconds,
# you reached M
m = data.readline()
m = int(m)
# you don't need the index... indeed you don't need to count (you can read
# to the end of file, unless it is malformed)
for _ in range(m):
a, b = (int(x) for x in data.readline().split('-'))
# removed unnecessary recasting to int
# a = int(a)
# b = int(b)
a -= 1
b -= 1
temp = pairs[a]
pairs[a] = pairs[b]
pairs[b] = temp
p = -1e-9
ok = True
for k in range(0, n):
if pairs[k].first >= p:
p = pairs[k].first
elif pairs[k].second >= p:
p = pairs[k].second
else:
ok = False
break
if ok:
results.write("YES\n")
else:
results.write("NO\n")
Response previous to edition
range(1, 1) is empty, so this part of the code:
for i in range (1, 1):
n = data.readline()
n = int(n)
does not define n, at when execution gets to line 12 you get an error.
You can remove the for statement, changing those three lines to:
n = data.readline()
n = int(n)
I am trying to generate combination of ID's
Input: cid = SPARK
oupout: list of all the comibnations as below, position of each element should be constant. I am a beginner in python any help here is much appreciated.
'S****'
'S***K'
'S**R*'
'S**RK'
'S*A**'
'S*A*K'
'S*AR*'
'S*ARK'
'SP***'
'SP**K'
'SP*R*'
'SP*RK'
'SPA**'
'SPA*K'
'SPAR*'
'SPARK'
I tried below, I need a dynamic code:
cid = 'SPARK'
# print(cid.replace(cid[1],'*'))
# cu_len = lenth of cid [SPARK] here which is 5
# com_stars = how many stars i.e '*' or '**'
def cubiod_combo_gen(cu_len, com_stars, j_ite, i_ite):
cubiodList = []
crange = cu_len
i = i_ite #2 #3
j = j_ite #1
# com_stars = ['*','**','***','****']
while( i <= crange):
# print(j,i)
if len(com_stars) == 1:
x = len(com_stars)
n_cid = cid.replace(cid[j:i],com_stars)
i += x
j += x
cubiodList.append(n_cid)
elif len(com_stars) == 2:
x = len(com_stars)
n_cid = cid.replace(cid[j:i],com_stars)
i += x
j += x
cubiodList.append(n_cid)
elif len(com_stars) == 3:
x = len(com_stars)
n_cid = cid.replace(cid[j:i],com_stars)
i += x
j += x
cubiodList.append(n_cid)
return cubiodList
#print(i)
#print(n_cid)
# for item in cubiodList:
# print(item)
print(cubiod_combo_gen(5,'*',1,2))
print(cubiod_combo_gen(5,'**',1,3))
For every character in your given string, you can represent it as a binary string, using a 1 for a character that stays the same and a 0 for a character to replace with an asterisk.
def cubiod_combo_gen(string, count_star):
str_list = [char0 for char0 in string] # a list with the characters of the string
itercount = 2 ** (len(str_list)) # 2 to the power of the length of the input string
results = []
for config in range(itercount):
# return a string of i in binary representation
binary_repr = bin(config)[2:]
while len(binary_repr) < len(str_list):
binary_repr = '0' + binary_repr # add padding
# construct a list with asterisks
i = -1
result_list = str_list.copy() # soft copy, this made me spend like 10 minutes debugging lol
for char in binary_repr:
i += 1
if char == '0':
result_list[i] = '*'
if char == '1':
result_list[i] = str_list[i]
# now we have a possible string value
if result_list.count('*') == count_star:
# convert back to string and add to list of accepted strings
result = ''
for i in result_list:
result = result + i
results.append(result)
return results
# this function returns the value, so you have to use `print(cubiod_combo_gen(args))`
# comment this stuff out if you don't want an interactive user prompt
string = input('Enter a string : ')
count_star = input('Enter number of stars : ')
print(cubiod_combo_gen(string, int(count_star)))
It iterates through 16 characters in about 4 seconds and 18 characters in about 17 seconds. Also you made a typo on "cuboid" but I left the original spelling
Enter a string : DPSCT
Enter number of stars : 2
['**SCT', '*P*CT', '*PS*T', '*PSC*', 'D**CT', 'D*S*T', 'D*SC*', 'DP**T', 'DP*C*', 'DPS**']
As a side effect of this binary counting, the list is ordered by the asterisks, where the earliest asterisk takes precedence, with next earliest asterisks breaking ties.
If you want a cumulative count like 1, 4, 5, and 6 asterisks from for example "ABCDEFG", you can use something like
star_counts = (1, 4, 5, 6)
string = 'ABCDEFG'
for i in star_counts:
print(cubiod_combo_gen(string, star_counts))
If you want the nice formatting you have in your answer, try adding this block at the end of your code:
def formatted_cuboid(string, count_star):
values = cubiod_combo_gen(string, count_star)
for i in values:
print(values[i])
I honestly do not know what your j_ite and i_ite are, but it seems like they have no use so this should work. If you still want to pass these arguments, change the first line to def cubiod_combo_gen(string, count_star, *args, **kwargs):
I am not sure what com_stars does, but to produce your sample output, the following code does.
def cuboid_combo(cid):
fill_len = len(cid)-1
items = []
for i in range(2 ** fill_len):
binary = f'{i:0{fill_len}b}'
#print(binary, 'binary', 'num', i)
s = cid[0]
for idx, bit in enumerate(binary,start=1):
if bit == '0':
s += '*'
else: # 'bit' == 1
s += cid[idx]
items.append(s)
return items
#cid = 'ABCDEFGHI'
cid = 'DPSCT'
result = cuboid_combo(cid)
for item in result:
print(item)
Prints:
D****
D***T
D**C*
D**CT
D*S**
D*S*T
D*SC*
D*SCT
DP***
DP**T
DP*C*
DP*CT
DPS**
DPS*T
DPSC*
DPSCT
I have a python program which does a SOAP request to a server, and it works fine:
I get the answer from the server, parse it, clean it, and when I am done, I end up with a string like that:
name|value|value_name|default|seq|last_modify|record_type|1|Detail|0|0|20150807115904|zero_out|0|No|0|0|20150807115911|out_ind|1|Partially ZeroOut|0|0|20150807115911|...
Basically, it is a string with values delimited by "|". I also know the structure of the database I am requesting, so I know that it has 6 columns and various rows. I basically need to split the string after every 6th "|" character, to obtain something like:
name|value|value_name|default|seq|last_modify|
record_type|1|Detail|0|0|20150807115904|
zero_out|0|No|0|0|20150807115911|
out_ind|1|Partially ZeroOut|0|0|20150807115911|...
Can you tell me how to do that in Python? Thank you!
Here's a functional-style solution.
s = 'name|value|value_name|default|seq|last_modify|record_type|1|Detail|0|0|20150807115904|zero_out|0|No|0|0|20150807115911|out_ind|1|Partially ZeroOut|0|0|20150807115911|'
for row in map('|'.join, zip(*[iter(s.split('|'))] * 6)):
print(row + '|')
output
name|value|value_name|default|seq|last_modify|
record_type|1|Detail|0|0|20150807115904|
zero_out|0|No|0|0|20150807115911|
out_ind|1|Partially ZeroOut|0|0|20150807115911|
For info on how zip(*[iter(seq)] * rowsize) works, please see the links at Splitting a list into even chunks.
data = "name|value|value_name|default|seq|last_modify|record_type|1|Detail|0|0|20150807115904|zero_out|0|No|0|0|20150807115911|out_ind|1|Partially ZeroOut|0|0|20150807115911|"
splits = data.split('|')
splits = list(filter(None, splits)) # Filter empty strings
row_len = 6
rows = ['|'.join(splits[i:i + row_len]) + '|' for i in range(0, len(splits), row_len)]
print(rows)
>>> ['name|value|value_name|default|seq|last_modify|', 'record_type|1|Detail|0|0|20150807115904|', 'zero_out|0|No|0|0|20150807115911|', 'out_ind|1|Partially ZeroOut|0|0|20150807115911|']
How about this:
a = 'name|value|value_name|default|seq|last_modify|record_type|1|Detail|0|0|20150807115904|zero_out|0|No|0|0|20150807115911|out_ind|1|Partially ZeroOut|0|0|20150807115911|'
b = a.split('|')
c = [b[6*i:6*(i+1)] for i in range(len(b)//6)] # this is a very workable form of data storage
print('\n'.join('|'.join(i) for i in c)) # produces your desired output
# prints:
# name|value|value_name|default|seq|last_modify
# record_type|1|Detail|0|0|20150807115904
# zero_out|0|No|0|0|20150807115911
# out_ind|1|Partially ZeroOut|0|0|20150807115911
Here is a flexible generator approach:
def splitOnNth(s,d,n, keep = False):
i = s.find(d)
j = 1
while True:
while i > 0 and j%n != 0:
i = s.find(d,i+1)
j += 1
if i < 0:
yield s
return #end generator
else:
yield s[:i+1] if keep else s[:i]
s = s[i+1:]
i = s.find(d)
j = 1
#test runs, showing `keep` in action:
test = 'name|value|value_name|default|seq|last_modify|record_type|1|Detail|0|0|20150807115904|zero_out|0|No|0|0|20150807115911|out_ind|1|Partially ZeroOut|0|0|20150807115911|'
for s in splitOnNth(test,'|',6,True): print(s)
print('')
for s in splitOnNth(test,'|',6): print(s)
Output:
name|value|value_name|default|seq|last_modify|
record_type|1|Detail|0|0|20150807115904|
zero_out|0|No|0|0|20150807115911|
out_ind|1|Partially ZeroOut|0|0|20150807115911|
name|value|value_name|default|seq|last_modify
record_type|1|Detail|0|0|20150807115904
zero_out|0|No|0|0|20150807115911
out_ind|1|Partially ZeroOut|0|0|20150807115911
There are really many ways to do it. Even with a loop:
a = 'name|value|value_name|default|seq|last_modify|record_type|1|Detail|0|0|20150807115904' \
'|zero_out|0|No|0|0|20150807115911|out_ind|1|Partially ZeroOut|0|0|20150807115911|'
new_a = []
ind_start, ind_end = 0, 0
for i in range(a.count('|')// 6):
for i in range(6):
ind_end = a.index('|', ind_end+1)
print(a[ind_start:ind_end + 1])
new_a.append(a[ind_start:ind_end+1])
ind_start = ind_end+1
The print is just to saw the results, you remove it:
name|value|value_name|default|seq|last_modify|
record_type|1|Detail|0|0|20150807115904|
zero_out|0|No|0|0|20150807115911|
out_ind|1|Partially ZeroOut|0|0|20150807115911|