-- THE QUESTION --
Input : 3
Output :
A B C
H I D
G F E
Input : 5
Output :
A B C D E
P Q R S F
O X Y T G
N W V U H
M L K J I
-- My progress: --
print("input :")
n = int(input())
alphabet= 65
for i in range(n):
print((n+i)*" ")
for j in range(i, i+n):
print(chr(alphabet), end=" ")
alphabet = alphabet + 1
print()
Input : 5
Output :
A B C D E
F G H I J
K L M N O
P Q R S T
U V W X Y
Input : 3
Output :
A B C
D E F
G H I
This is not so trivial as it may seem. Anyway, here's a very simplistic solution:
build an alphabet long enough (I repeated the ASCII uppercase letters as needed so we can build spirals of any size)
create a matrix in memory with each letter in the right position
print the matrix
The code:
from string import ascii_uppercase
def spiral(n):
alphabet = ascii_uppercase * (n**2//26+1) #repeat ABC..XYZ until needed
alphabet = alphabet[:n**2] #take only n**2 chars
ln = len(alphabet)
grid = []
for _ in range(n):
grid.append([' ']*n)
min_row = 0
min_col = 0
max_row = n
max_col = n
i = 0
while i < ln:
#left to right
row = min_row
for col in range(min_col, max_col):
if i == ln:
break
grid[row][col] = alphabet[i]
i += 1
min_row += 1
#top to bottom
col = max_col-1
for row in range(min_row, max_row):
if i == ln:
break
grid[row][col] = alphabet[i]
i += 1
max_col -= 1
#right to left
row = max_row-1
for col in range(max_col-1, min_col-1, -1):
if i == ln:
break
grid[row][col] = alphabet[i]
i += 1
max_row -= 1
#bottom to top
col = min_col
for row in range(max_row-1, min_row-1, -1):
if i == ln:
break
grid[row][col] = alphabet[i]
i += 1
min_col += 1
#print grid
for row in range(n):
for col in range(n):
print(grid[row][col], end=' ')
print()
>>> spiral(3)
A B C
H I D
G F E
>>> spiral(9)
A B C D E F G H I
F G H I J K L M J
E D E F G H I N K
D C T U V W J O L
C B S B C X K P M
B A R A Z Y L Q N
A Z Q P O N M R O
Z Y X W V U T S P
Y X W V U T S R Q
I'm trying to write a file where you have 2 rows, with the first row being numbers and the 2nd row being letters. As an example, I was trying to do this with the alphabet.
list1=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
list2=list1+list1
abcList = [[],[]]
for i in range(len(list2)):
i+=1
if i % 5 == 0:
if i>=10:
abcList[0].append(str(i) + ' ')
else:
abcList[0].append(str(i) + ' ')
elif i<=1:
abcList[0].append(str(i) + ' ')
else:
abcList[0].append(' ')
for i,v in enumerate(list2):
i+=1
if i > 10:
abcList[1].append(' '+v+' ')
else:
abcList[1].append(v+' ')
print(''.join(abcList[0]))
print(''.join(abcList[1]))
with open('file.txt','w') as file:
file.write(''.join(abcList[0]))
file.write('\n')
file.write(''.join(abcList[1]))
The problem with the above setup is its very "hacky" (I don't know if its the right word). It "works", but its really just modifying 2 lists to make sure they stack on top of one another properly. The problem is if your list becomes too long, then the text wraps around, and stacks on itself instead of the numbers. I'm looking for something a bit less "hacky" that would work for any size list (trying to do this without external libraries, so I don't want to use pandas or numpy).
Edit: The output would be:
1 5 10
A B C D E F G H I J...etc.
Edit 2:
Just thought I'd add, I've gotten this far with it so far, but I've only been able to make columns, not rows.
list1=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
list2=list1*2
abcList = [[],[]]
for i in range(len(list2)):
i+=1
if i % 5 == 0:
if i>=5:
abcList[0].append(str(i))
elif i<=1:
abcList[0].append(str(i))
else:
abcList[0].append('')
for i,letter in enumerate(list2):
abcList[1].append(letter)
for number, letters in zip(*abcList):
print(number.ljust(5), letters)
However, this no longer has the wrapping issues, and the numbers line up with the letters perfectly. The only thing now is to get them from columns to rows.
Output of above is:
1 A
B
C
D
5 E
F
G
H
I
10 J
I mean, you could do something like this:
file_contents = """...""" # The file contents. I not the best at file manipulation
def parser(document): # This function will return a nested list
temp = str(document).split('\n')
return [[line] for line in temp] # List comprehension
parsed = parser(file_contents)
# And then do what you want with that
Your expected output is a bit inconsistent, since in the first one, you have 1, 6, 11, 16... and in the second: 1, 5, 10, 15.... So I have a couple of possible solutions:
print(''.join([' ' if n%5 else str(n+1).ljust(2) for n in range(len(list2))]))
print(''.join([c.ljust(2) for c in list2]))
Output:
1 6 11 16 21 26 31 36 41 46 51
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
print(''.join([' ' if n%5 else str(n).ljust(2) for n in range(len(list2))]))
print(''.join([c.ljust(2) for c in list2]))
Output:
0 5 10 15 20 25 30 35 40 45 50
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
print(''.join(['1 ']+[' ' if n%5 else str(n).ljust(2) for n in range(len(list2))][1:]))
print(''.join([c.ljust(2) for c in list2]))
Output:
1 5 10 15 20 25 30 35 40 45 50
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
If you are wanting to keep variable width strings aligned, you could use string formatting with a width equal to the maximum of the widths of the individual items in that position. (This example will work with more than any number of lists, by the way.)
list1 = ["", "5", "", "10", "", "4"]
list2 = ["A", "B", "C", "D", "EE", "F"]
lists = [list1, list2]
widths = [max(map(len, t)) for t in zip(*lists)]
for lst in lists:
line = " ".join("{val:{width}s}".format(val=val, width=width)
for val, width in zip(lst, widths))
print(line)
gives:
5 10 4
A B C D EE F
I need to print a pattern like this:
C E G I K
D F H J
E G I
F H
G
Here is my code:
Someone please correct this code for me.
alpha=ord('C')
for i in range(5,0,-1):
for j in range(i):
print(chr(alpha+2),end="")
print('')
My current output is:
E E E E E
E E E E
E E E
E E
E
You can add an offset to the ordinal number of C based on the the line number and character number:
for i in range(5):
print(*(chr(ord('C') + i + j * 2) for j in range(5 - i)), sep=' ')
Say I have one of the strings:
"a b c d e f f g" || "a b c f d e f g"
And I want there to be only one occurrence of a substring (f in this instance) throughout the string so that it is somewhat sanitized.
The result of each string would be:
"a b c d e f g" || "a b c d e f g"
An example of the use would be:
str = "a b c d e f g g g g g h i j k l"
str.leaveOne("g")
#// a b c d e f g h i j k l
If it doesn't matter which instance you leave, you can use str.replace, which takes a parameter signifying the number of replacements you want to perform:
def leave_one_last(source, to_remove):
return source.replace(to_remove, '', source.count(to_remove) - 1)
This will leave the last occurrence.
We can modify it to leave the first occurrence by reversing the string twice:
def leave_one_first(source, to_remove):
return source[::-1].replace(to_remove, '', source.count(to_remove) - 1)[::-1]
However, that is ugly, not to mention inefficient. A more elegant way might be to take the substring that ends with the first occurrence of the character to find, replace occurrences of it in the rest, and finally concatenate them together:
def leave_one_first_v2(source, to_remove):
first_index = source.index(to_remove) + 1
return source[:first_index] + source[first_index:].replace(to_remove, '')
If we try this:
string = "a b c d e f g g g g g h i j k l g"
print(leave_one_last(string, 'g'))
print(leave_one_first(string, 'g'))
print(leave_one_first_v2(string, 'g'))
Output:
a b c d e f h i j k l g
a b c d e f g h i j k l
a b c d e f g h i j k l
If you don't want to keep spaces, then you should use a version based on split:
def leave_one_split(source, to_remove):
chars = source.split()
first_index = chars.index(to_remove) + 1
return ' '.join(chars[:first_index] + [char for char in chars[first_index:] if char != to_remove])
string = "a b c d e f g g g g g h i j k l g"
print(leave_one_split(string, 'g'))
Output:
'a b c d e f g h i j k l'
If I understand correctly, you can just use a regex and re.sub to look for groups of two or more of your letter with or without a space and replace it by a single instance:
import re
def leaveOne(s, char):
return re.sub(r'((%s\s?)){2,}' % char, r'\1' , s)
leaveOne("a b c d e f g g g h i j k l", 'g')
# 'a b c d e f g h i j k l'
leaveOne("a b c d e f ggg h i j k l", 'g')
# 'a b c d e f g h i j k l'
leaveOne("a b c d e f g h i j k l", 'g')
# 'a b c d e f g h i j k l'
EDIT
If the goal is to get rid of all occurrences of the letter except one, you can still use a regex with a lookahead to select all letters followed by the same:
import re
def leaveOne(s, char):
return re.sub(r'(%s)\s?(?=.*?\1)' % char, '' , s)
print(leaveOne("a b c d e f g g g h i j k l g", 'g'))
# 'a b c d e f h i j k l g'
print(leaveOne("a b c d e f ggg h i j k l gg g", 'g'))
# 'a b c d e f h i j k l g'
print(leaveOne("a b c d e f g h i j k l", 'g'))
# 'a b c d e f g h i j k l'
This should even work with more complicated patterns like:
leaveOne("a b c ffff d e ff g", 'ff')
# 'a b c d e ff g'
Given String
mystr = 'defghhabbbczasdvakfafj'
cache = {}
seq = 0
for i in mystr:
if i not in cache:
cache[i] = seq
print (cache[i])
seq+=1
mylist = []
Here I have ordered the dictionary with values
for key,value in sorted(cache.items(),key=lambda x : x[1]):
mylist.append(key)
print ("".join(mylist))
I want to print pattern using python and i have done it but i want to
know other solutions possible for the same:-
A B C D E F G F E D C B A
A B C D E F F E D C B A
A B C D E E D C B A
......
....
A A
and here is my code:-
n=0
for i in range(71,64,-1):
for j in range(65,i+1):
a=chr(j)
print(a, end=" ")
if n>0:
for l in range(1,3+(n-1)*4):
print(end=" ")
if i<71:
j=j+1
for k in range(j-1,64,-1):
b=chr(k)
print(b, end=" ")
n=n+1
print()
Here's an alternative method using 3rd party library numpy. I use this library specifically because it allows vectorised assignment, which I use instead of an inner loop.
from string import ascii_uppercase
import numpy as np
n = 7
# extract first n letters from alphabet
letters = ascii_uppercase[:n]
res = np.array([list(letters + letters[-2::-1])] * (n-1))
# generate indices that are removed per line
idx = (range(n-i-1, n+i) for i in range(n-1))
# printing logic
print(' '.join(res[0]))
for i, j in enumerate(idx):
# vectorised assignment
res[i, j] = ' '
print(' '.join(res[i]))
Result:
A B C D E F G F E D C B A
A B C D E F F E D C B A
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