You can control what to put between several values (print(1,2,3,4, sep="#"
) using sep="#"
and what to put at the end of the printed line with 'end='\n'
.
Changing
print(1, end=" ") # some space instead of \n
and
print(Mult, end=" ") # after each column should work
in combination with the loops you got should get you started (see this answer for more in depth explanation or review the official documentation of print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) for details.
You can solve your task with some creative formatting, generator expressions, joining of generator decompositions in a single print statement:
rows_up_to_X_times = 12
columns_up_to_X = 12
max_width = len(str(rows_up_to_X_times * columns_up_to_X ))
# 99*99 max - need to adapt formatting otherwise
print( *(' '.join((f"{b:2}*{a:2} = {a*b:{max_width}}"
for a in range(1,rows_up_to_X_times+1)))
for b in range(1,columns_up_to_X+1)), sep="\n")
Output:
1* 1 = 1 1* 2 = 2 1* 3 = 3 1* 4 = 4 [...] 1*10 = 10 1*11 = 11 1*12 = 12
2* 1 = 2 2* 2 = 4 2* 3 = 6 2* 4 = 8 [...] 2*10 = 20 2*11 = 22 2*12 = 24
3* 1 = 3 3* 2 = 6 3* 3 = 9 3* 4 = 12 [...] 3*10 = 30 3*11 = 33 3*12 = 36
4* 1 = 4 4* 2 = 8 4* 3 = 12 4* 4 = 16 [...] 4*10 = 40 4*11 = 44 4*12 = 48
5* 1 = 5 5* 2 = 10 5* 3 = 15 5* 4 = 20 [...] 5*10 = 50 5*11 = 55 5*12 = 60
6* 1 = 6 6* 2 = 12 6* 3 = 18 6* 4 = 24 [...] 6*10 = 60 6*11 = 66 6*12 = 72
7* 1 = 7 7* 2 = 14 7* 3 = 21 7* 4 = 28 [...] 7*10 = 70 7*11 = 77 7*12 = 84
8* 1 = 8 8* 2 = 16 8* 3 = 24 8* 4 = 32 [...] 8*10 = 80 8*11 = 88 8*12 = 96
9* 1 = 9 9* 2 = 18 9* 3 = 27 9* 4 = 36 [...] 9*10 = 90 9*11 = 99 9*12 = 108
10* 1 = 10 10* 2 = 20 10* 3 = 30 10* 4 = 40 [...] 10*10 = 100 10*11 = 110 10*12 = 120
11* 1 = 11 11* 2 = 22 11* 3 = 33 11* 4 = 44 [...] 11*10 = 110 11*11 = 121 11*12 = 132
12* 1 = 12 12* 2 = 24 12* 3 = 36 12* 4 = 48 [...] 12*10 = 120 12*11 = 132 12*12 = 144
See
for more on formatting strings with numbers etc.