Python White Space Diamond - python-2.7

I have been stuck on this question for a couple of days. The whole lab question can be found here.
Lab 6: Loopy Lab Part 3
Print the following for any positive integer n. Use an input statement to allow the user to enter the value for n and then print the properly sized box.
E.g. n = 3
1 3 5 5 3 1
3 5 5 3
5 5
5 5
3 5 5 3
1 3 5 5 3 1
E.g. n = 5
1 3 5 7 9 9 7 5 3 1
3 5 7 9 9 7 5 3
5 7 9 9 7 5
7 9 9 7
9 9
9 9
7 9 9 7
5 7 9 9 7 5
3 5 7 9 9 7 5 3
1 3 5 7 9 9 7 5 3 1
Don't worry about handling the spacing for multi-digit numbers.
This is what I have so far:
from __future__ import print_function
for i in range(5):
for j in range(5-i):
print (j, end=" ")
for k in range(i):
print (" "*(2**2-1), end=" ")
for l in range(5-i):
print (l, end=" ")
print()
for i in range(5):
for j in range(i+1):
print (j, end=" ")
print()
I used the import from future function because I am using Python 2.7.3.1. Also, I'm sorry if this seems to be a "noob" question, but I am a beginner and need help. Thank you for all your help! It is appreciated.

This is kind of an interesting question. Here is my solution, not quite optimized but should be straightforward to understand:
n = 5
import string
numberList = string.letters
# uncomment if you want numbers, i prefer letters
#numberList = [i*2-1 for i in range(1, n+1)]
# upper lower
# V V
for n_row in range(0, n) + list(reversed(range(0, n))):
# left number
for number in numberList[:(n-n_row)]:
print number,
# space
for number in range(n_row):
print ' ', ' ',
# right number
for number in reversed(numberList[:(n-n_row)]):
print number,
print
The double digits really screw up the format so i used letters instead.
a b c d e e d c b a
a b c d d c b a
a b c c b a
a b b a
a a
a a
a b b a
a b c c b a
a b c d d c b a
a b c d e e d c b a

Try the following code:
inputValue = int(input('input interger:'))
base = ' '
for i in range(inputValue):
base = ' '+str(2*(inputValue-1-i)+1)+base+str(2*(inputValue-1-i)+1)+' '
length = len(base.strip())
graph = []
for j in range(inputValue):
line = ' '
for k in range(j):
line = ' '+line+' '
for i in range(inputValue-j):
line = ' '+str(2*(inputValue-1-i)+1)+line+str(2*(inputValue-1-i)+1)+' '
line = line.strip()
length_temp = int((length-len(line))/2)
for m in range(length_temp):
line = ' '+line+' '
graph.append(line)
for j in range(inputValue):
graph.append(graph[inputValue-1-j])
for line in graph:
print(line)
Or this code, depending on what your desired output is:
inputValue = int(input('input interger:'))
base = ' '
for i in range(inputValue):
base = ' '+str(2*(inputValue-1-i)+1)+base+str(2*(inputValue-1-i)+1)+' '
length = len(base.strip())
graph = []
for j in range(inputValue):
line = ' '
for k in range(j):
line = ' '+line+' '
for i in range(inputValue-j):
line = ' '+str(2*(inputValue-1-i)+1)+line+str(2*(inputValue-1-i)+1)+' '
line = line.strip()
length_temp = int((length-len(line)))
for m in range(length_temp):
line = line[:int(len(line)/2)]+' '+line[int(len(line)/2)+1:]
graph.append(line)
for j in range(inputValue):
graph.append(graph[inputValue-1-j])
for line in graph:
print(line)

Related

writing to columns in same row in csv file (python)

Im trying to write values to a csv file such that for every two iterations, the result is in the same row and then the next the values print to a new row. Any help would be greatly appreciated. Thank you!
This is what I have so far:
import csv
import math
savePath = '/home/dehaoliu/opencv_test/Engineering_drawings_outputs/'
with open(str(savePath) +'outputsTest.csv','w') as f1:
writer=csv.writer(f1, delimiter='\t',lineterminator='\n',)
temp = []
for k in range(0,2):
temp = []
for i in range(0,4):
a = 2 +i
b = 3+ i
list = [a,b]
temp.append(list)
writer.writerow(temp)
The result I am getting now is
[2 3][3 4][4 5][5 6]
[2 3][3 4][4 5][5 6]
But I would like to get this (without the brackets) where each number in a row is in a separate column:
2 3 3 4
4 5 5 6
Try the following:
import csv
import math
savePath = '/home/dehaoliu/opencv_test/Engineering_drawings_outputs/'
with open(str(savePath) +'outputsTest.csv','w') as f1:
writer=csv.writer(f1, delimiter='\t',lineterminator='\n',)
temp = [2, 3]
for i in range(2):
temp = [x + i for x in temp]
additional = [y+1 for y in temp]
writer.writerow(temp + additional)
temp = additional[:]
This should return:
# 2 3 3 4
# 4 5 5 6
You start with a temporary containing the numbers 2 and 3. Then, you loop from 0 to 2 (excluding). At every iteration, you increment the values of the temporary by the current index and subsequently create an additional list with these new values of your temporary list. Once that's done, you join the two lists together and write the result out to your file. At this point, you can set your temporary list to be equal to the values of the additional list, before moving on to the next iteration.
I hope this helps.
The way you present it you can do it with a simple seed and increment:
import csv
import os
save_path = "/home/dehaoliu/opencv_test/Engineering_drawings_outputs/"
with open(os.path.join(save_path, "outputsTest.csv"), "w") as f:
writer = csv.writer(f, delimiter="\t", lineterminator="\n")
temp = [2, 3, 3, 4] # init seed
increment = len(temp) // 2 # how many pairs we have, used to increase our seed each row
for _ in range(2): # how many rows do you need, any positive integer will do
writer.writerow(temp) # write the current value
temp = [x + increment for x in temp] # add 'increment' to the elements
Resulting in:
2 3 3 4
4 5 5 6
But if your seed is: temp = [2, 3, 3, 4, 4, 5] and you decide to generate 4 rows, it will still adapt:
2 3 3 4 4 5
5 6 6 7 7 8
8 9 9 10 10 11
11 12 12 13 13 14

grepl repetition of upperbound and plus character

I am working on a data frame (df) which looks like this and can contain more than 10000 rows for some cases.
Object Coding Fn Remaining
1 T00055 T 00055_005_<002_+ 2 30
2 T00055 T 00055_008_<002_+ 2 30
3 E00336 E 00336_041_<001_+001_+ 3 0
4 E00336 E 00336_041_<001_+001_+001_+ 4 10
5 E00336 E 00336_041_<001_+001_+002_+ 4 56
6 E00336 E 00336_041_<001_+001_+002_< 4 52
7 T 00054 T 00054_013_<003_<015_+003_<001_< 4 52
I need to grep all rows which contain at least twice _+ in the string of the column Coding in order to get a data frame test.
I am trying :
test<-filter(df,
grepl("_[+].{2,}",Coding))
which cannot exclude the last row. Any idea why? Many thanks
here is the results:
Object Coding Fn Remaining
1 E00336 E 00336_041_<001_+001_+ 3 0
2 E00336 E 00336_041_<001_+001_+001_+ 4 10
3 E00336 E 00336_041_<001_+001_+002_+ 4 56
4 E00336 E 00336_041_<001_+001_+002_< 4 52
5 T 00054 T 00054_013_<003_<015_+003_<001_< 4 52
You can use this command:
subset(df, grepl("(_\\+.*){2,}", Coding))
or, with dplyr,
filter(df, grepl("(_\\+.*){2,}", Coding))
Your current regex, "_[+].{2,}", matches _+ followed by at least two characters. You need to create a group using parentheses in order to correctly apply the quantifier.
Using rex may make this type of task a little simpler.
df <- structure(list(Object = c("T00055", "T00055", "E00336", "E00336",
"E00336", "E00336", "T 00054"), Coding = c("T 00055_005_<002_+",
"T 00055_008_<002_+", "E 00336_041_<001_+001_+", "E 00336_041_<001_+001_+001_+",
"E 00336_041_<001_+001_+002_+", "E 00336_041_<001_+001_+002_<",
"T 00054_013_<003_<015_+003_<001_<"), Fn = c(2L, 2L, 3L, 4L,
4L, 4L, 4L), Remaining = c(30L, 30L, 0L, 10L, 56L, 52L, 52L)), .Names = c("Object",
"Coding", "Fn", "Remaining"), row.names = c(NA, -7L), class = "data.frame")
subset(df, grepl(rex(at_least(group("_+", anything), 2)), Coding))
#> Object Coding Fn Remaining
#> 3 E00336 E 00336_041_<001_+001_+ 3 0
#> 4 E00336 E 00336_041_<001_+001_+001_+ 4 10
#> 5 E00336 E 00336_041_<001_+001_+002_+ 4 56
#> 6 E00336 E 00336_041_<001_+001_+002_< 4 52

Extracting columns with a difference in aligned data

I have some aligned data (something bioinformatic related) as so:
reference_string = 'yearning'
string2 = 'learning'
string3 = 'aligning'
I need to extract only columns showing differences in relation to the reference data.
The output should show only positional information of the columns containing differences in relation to the reference string and the corresponding reference item.
1 2 3 4
y e a r
l
a l i g
My current code does most things okay except that it also reports columns with no difference.
string1 = 'yearning'
string2 = 'learning'
string3 = 'aligning'
string_list = [string1, string2]
reference = reference_string
diffs_top, diffs = [], []
all_diffs = set()
for s in string_list:
diffs = []
for i, c in enumerate(s):
if s[i] != reference[i]:
diffs.append(i)
all_diffs.add(i)
diffs_top.append(diffs)
for d in all_diffs:
print str(int(d+1)),
print
for c in reference:
print str(c),
print
for i, s in enumerate(string_list):
for j, c in enumerate(s):
if j in diffs_top[i]:
print str(c),
else:
print str(' '),
print
This code would give:
1 2 3 4
y e a r n i n g
l
a l i g
Any help appreciated.
EDIT: I have picked some section of real data to make the problem as clearer as possible and my attempt at solving it thus far:
reference_string = 'MAHEWGPQRLAGGQPQAS'
string1 = 'MAQQWSLQRLAGRHPQDS'
string2 = 'MAQRWGAHRLTGGQLQDT'
string3 = 'MAQRWGPHALSGVQAQDA'
string_list = [string1, string2, string3]
reference = reference_string
diffs_top, diffs = [], []
all_diffs = set()
for s in string_list:
diffs = []
for i, c in enumerate(s):
if s[i] != reference[i]:
diffs.append(i)
all_diffs.add(i)
diffs_top.append(diffs)
#print diffs_top
#print all_diffs
for d in all_diffs:
print str(int(d+1)), # retains natural positions of the reference residues
print
for d in all_diffs:
for i, c in enumerate(reference):
if i == d:
print c,
print
The print out will be an output showing the position at which there is any difference to other non-reference strings and the corresponding reference letter.
3 4 6 7 8 9 11 13 14 15 17 18
H E G P Q R A G Q P A S
Then the next step is to write a code that will process non reference strings by printing out the difference with the reference (at that position). If there is no difference it will leave blank (' ').
Doing it manually the output will be:
3 4 6 7 8 9 11 13 14 15 17 18
H E G P Q R A G Q P A S
Q Q S L R H D
Q R A H T L D T
Q R H A S V A D A
My entire code as an attempt to get to the solution above as been messy to say the least:
reference_string = 'MAHEWGPQRLAGGQPQAS'
string1 = 'MAQQWSLQRLAGRHPQDS'
string2 = 'MAQRWGAHRLTGGQLQDT'
string3 = 'MAQRWGPHALSGVQAQDA'
string_list = [string1, string2, string3]
reference = reference_string
diffs_top, diffs = [], []
all_diffs = set()
for s in string_list:
diffs = []
for i, c in enumerate(s):
if s[i] != reference[i]:
diffs.append(i)
all_diffs.add(i)
diffs_top.append(diffs)
#print diffs_top
#print all_diffs
for d in all_diffs:
print str(int(d+1)),
print
for d in all_diffs:
for i, c in enumerate(reference):
if i == d:
print c,
print
# this is my attempt to look into non-reference strings
# to check for the difference with the reference, and print an output.
for d in all_diffs:
for i, s in enumerate(string_list):
for j, c in enumerate(s):
if j == d:
print c,
else:
print str(' '),
print
Your code is working perfectly fine (as per your logic).
What is happening , is that while printing the output, when you come across the reference string, Python looks for the corresponding entry in the diffs_top list and because while storing in diff_top, you have no entry stored for the reference string, Python just prints blank spaces for your reference string.
1 2 3 4
y e a r n i n g #prints the reference string, because you've coded in that way
#prints blank as string_list[0] and reference string are the same
l
a l i g
The question here is how exactly do you define your difference for reference string.
Besides, I also found some fundamental flaws in your code implementation. If you try to run your code by setting string_list[1] as your reference string, you would get your output as :
1 2 3 4
l e a r n i n g
y
a l i g
Is this what you need? Please spend some time in properly defining difference for all cases and then try to implement you code.
EDIT:
As per you updated requirements, replace the last block in your code with this:
for i, s in enumerate(string_list):
for d in all_diffs:
if d in diffs_top[i]:
print s[d],
else:
print ' ',
print
Cheers!
I think there is a general problem in your logic. If you need to extract only columns showing difference in relation to the reference data and string1 is the reference the output should be:
1 2 3 4
l
a l i g
So, 'yearning' shouldn't show any character because it has no difference to string1.
If you delete or put the following lines in comments, you will exactly get what I expect is the right answer:
#for c in reference:
# print str(c),
#print
Consider to review your logic if this solution is not what you actually want.
Update
Here is a shorter solution which solves your task:
from itertools import compress, izip_longest
def delta(reference, string):
return [ '' if a == b else b for a, b in izip_longest(reference, string)]
ref_string = 'MAHEWGPQRLAGGQPQAS'
strings = ['MAQQWSLQRLAGRHPQDS',
'MAQRWGAHRLTGGQLQDT',
'MAQRWGPHALSGVQAQDA']
delta_strings = [delta(ref_string, string) for string in strings]
selectors = [1 if any(tup) else 0 for tup in izip_longest(*delta_strings)]
indices = [str(i+1) for i in range(len(selectors))]
output_data = [indices, ref_string] + delta_strings
for line in output_data:
print ''.join(x.rjust(3) for x in compress(line, selectors))
Explanation:
I defined a function delta(reference, string) which returns the delta between the string and the referenced string. For example: delta("ABFF", "AECF") returns the list ['', E, C, ''].
The variable delta_strings holds all the deltas between each string in the list strings and the reference string ref_string.
The variable selector is a list containing only 1 and 0 values, where 0 specifies the collumns which shouldn't be printed and vice versa.

how to do align outcome values in python

i am having trouble with aligning outcome values.
Alist = ["1,25,999",
"123.4,56.7890,13.571",
"1,23.45,6,7.8"]
c = 0
while c < len(Alist):
r = 0
tokens = Alist[c].split(',')
while r < len(Alist[c].split(',')):
if '.' in tokens[r]:
print "%7.2f" %float(tokens[r]), " ",
else :
print "%3d" %float(tokens[r]), " ",
r += 1
print
c += 1
I want to print such as
1 25 999
123.40 56.79 13.57
1 23.45 6. 7.80
but somehow it is printing
1
25
999
123.40
56.79
13.57
1
23.45
6
7.8
and i cannot figure out what is wrong with my coding.
after the r+1, you have a lone print statement. it is at the wrong indention level - move it to the left by 4 spaces (or one tab) and it should work fine.
The print statement should'nt in the 2nd while loop. just:
Alist = ["1,25,999",
"123.4,56.7890,13.571",
"1,23.45,6,7.8"]
c = 0
while c < len(Alist):
r = 0
tokens = Alist[c].split(',')
while r < len(Alist[c].split(',')):
if '.' in tokens[r]:
print "%7.2f" %float(tokens[r]), " ",
else :
print "%3d" %float(tokens[r]), " ",
r += 1
print
c += 1
In [59]: %paste
myList = ["1,25,999",
"123.4,56.7890,13.571",
"1,23.45,6,7.8"]
rows = [r.split(',') for r in myList]
widths = {i:max(len(c) for c in col) for i,col in enumerate(itertools.izip_longest(*rows, fillvalue=""))}
for row in rows:
for i,val in enumerate(row):
print " "*((widths[i] - len(val))/2), val, " "*((widths[i] - len(val))/2) if not (widths[i]-len(val))%2 else " "*((widths[i] - len(val)+1)/2),
print
## -- End pasted text --
1 25 999
123.4 56.7890 13.571
1 23.45 6 7.8

How to call lists in a for loop?

I am stuck at a failry simple looping exercise through lists and getting error "TypeError: 'list' object is not callable".
I have three lists with n number of records. I want to write first record from all lists in the same line and want to repeat this procedure for n number of records, it will result in n number of lines. Following are lists that I want to use:
lst1 = ['1','2','4','5','3']
lst2 = ['3','4','3','4','3']
lst3 = ['0.52','0.91','0.18','0.42','0.21']
istring=""
lst=0
for i in range(0,10): # range is simply upper limit of number of records in lists
entry = lst1(lst)
istring = istring + entry.rjust(11) # first entry from each list will be cat here
lst=lst+1
Any startup would be really helpful.
This works for any size of lists:
for i in zip(lst1, lst2, lst3):
for j in i:
print j.rjust(11),
print
1 3 0.52
2 4 0.91
4 3 0.18
5 4 0.42
3 3 0.21
>>> lst1 = ['1','2','4','5','3']
>>> lst2 = ['3','4','3','4','3']
>>> lst3 = ['0.52','0.91','0.18','0.42','0.21']
>>> a = zip(lst1, lst2, lst3)
>>> istring = ""
>>> for entry in a:
... istring += entry[0].rjust(11)
... istring += entry[1].rjust(11)
... istring += entry[2].rjust(11) + "\n"
...
>>> print istring
1 3 0.52
2 4 0.91
4 3 0.18
5 4 0.42
3 3 0.21
Try entry = lst1[lst] instead of entry = lst1(lst)
() usually denotes calling a function, whereas
[] usually denotes accessing an element of something.
A list is not a function.
Also, while you can keep your own index, a for loop makes this unnecessary
x = [1,2,3,4,5,7,9,11,13,15]
y = [2,4,6,8,10,12,14,16,18,20]
z = [3,4,5,6,7,8,9,10,11,12]
for i in range(0,10):
print x[i], y[i], z[i]
1 2 3
2 4 4
3 6 5
4 8 6
5 10 7
7 12 8
9 14 9
11 16 10
13 18 11
15 20 12