How to print math operations vertically? - python

I want to print strings like children in solving math operations, which is like this
32 3801 45 123
+ 698 - 2 + 43 + 49
----- ------ ---- -----
I have tried it as follows
def arithmetic(problems):
# pisahkan setiap value
atas = [i.split()[0] for i in problems]
bawah = [i.split()[2] for i in problems]
operator = [i.split()[1] for i in problems]
output_atas = ""
output_bawah = ""
for j in range( len(problems) ):
output_atas += f"{atas[j]:>8}"
output_bawah += f"{operator[j]} {bawah[j]:>5}"
print(output_atas)
print(output_bawah)
arithmetic(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"])
how to tidy up the string and adjust the line ---- according to the length of the number?

Add a new line /n in after first value and then operation and next value will be on anew line

Related

Arrange output vertically and side-by-side in python

So I want to arrange arithmetic problems vertically in a nice column.
Code:
`def arithmetic_arranger(problems, calculate = False):
for problem in problems:
problem = problem.split()
first_number = problem[0]
second_number = problem[2]
sign = problem[1]
try:
first_number = int(first_number)
second_number = int(second_number)
except:
print('Error: Numbers must only contain digits.')
break
if calculate is True:
if sign == '+':
result = first_number + second_number
else:
result = first_number - second_number
print(f'{first_number}\n{sign} {second_number}\n-----')
if calculate is True:
print(result)
arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"], True)`
This is the current output:
+ 8
-----
40
1
- 3801
-----
-3800
9999
+ 9999
-----
19998
523
- 49
-----
474
And I want to turn that into:
32 1 9999 523
+ 8 - 3801 + 9999 - 49
---- ------ ------ -----
40 -3800 19998 474
I have tried adding first numbers to list and then displaying them in the row but that didn't really work.
Here is a proposition (based on your code) with a little help from tabulate.
#pip install tabulate
from tabulate import tabulate
​
def arithmetic_arranger(problems, calculate=False):
problem_lists = [problem.split() for problem in problems]
if calculate:
results = [eval(" ".join(problem)) for problem in problem_lists]
problem_lists = [problem_lists[i] + [result]
for i, result in enumerate(results)]
problem_lists = list(map(list, zip(*problem_lists)))
problem_lists[1:3] = [[" ".join(x)
for x in zip(problem_lists[1], problem_lists[2])]]
​
print(tabulate(problem_lists, tablefmt="simple", showindex=False,
numalign="right", stralign="right"))
Output :
​
arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"], True)
​
--- ------ ------ ----
32 1 9999 523
+ 8 - 3801 + 9999 - 49
40 -3800 19998 474
--- ------ ------ ----
I'd approach this by creating a function that takes the two numbers to add/subtract as numbers, not strings. Then using len(str(x)) to infer the printed length of the number as a string, we can print the appropraite number of leading spaces and dashes.
def long_op(x, y, op="+"):
if op == "+":
result = x + y
elif op == "-":
result = x - y
else:
raise ValueError("op must be + or -")
width = max([len(str(i)) for i in [x, y]])
first = " " * (2 + width - len(str(x))) + str(x)
second = op + " " * (1 + width - len(str(y))) + str(y)
bar = "-" * (2 + width)
last = " " * (2 + width - len(str(result))) + str(result)
return "\n".join([first, second, bar, last])
def multi_ops(*args):
long_ops = [long_op(*arg).split("\n") for arg in args]
transpose = list(map(list, zip(*long_ops)))
return "\n".join([" ".join(l) for l in transpose])
print(long_op(32,8))
print()
print(multi_ops([32,8], [1,3801,"-"], [9999,9999], [523,49,"-"]))
Output:
32
+ 8
----
40
32 1 9999 523
+ 8 - 3801 + 9999 - 49
---- ------ ------ -----
40 -3800 19998 474
Demo at SageCell.SageMath.org.

how can I align the output horizantally with python?

can anyone take a look to my code and tell me what I'm missing?
I am trying to solve a freecodingcamp project called arithmetic formatter
this is my code:
def arithmetic_arranger(lst):
for x in lst:
if '+' in x:
x = x.split('+')
a = int(x[0])
b = int(x[1])
upa = str(a)
downb = str(b)
total = str(a + b)
s_total = str(total)
plusAndB = '+ ' + downb
line = '---------'
print('{:>8}'.format(upa),'\n','{:>7}'.format(plusAndB),'\n', '{:>8}'.format(line[0:len(s_total)]),'\n','{:>7}'.format(s_total))
if '-' in x:
y = x.split('-')
c = int(y[0])
d = int(y[1])
substracion = c - d
s_sub = str(substracion)
subAndD = '- ' + str(d)
line = '---------'
print('{:>8}'.format( c),'\n','{:>7}'.format(subAndD),'\n', '{:>8}'.format(line[0:len(s_sub) + 2]),'\n','{:>7}'.format(s_sub))
print('')
print(arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"]))
I want the results to be aligned as follows:
32 1 9999 523
+ 8 - 3801 + 9999 - 49
---- ------ ------ -----
40 -3800 19998 474
no matter what I have tried I always get this output:
32
+ 8
--
40
1
- 3801
-------
-3800
9999
+ 9999
-----
19998
523
- 49
-----
474
I left inline comments to explain what the code does
def output(seq):
final = [] # final output list
for expression in seq:
op = "+" if "+" in expression else "-" # op will represent the operator
top,bottom = [i.strip() for i in expression.split(op)] # split equation
ibottom = int(bottom) if op == "+" else int(bottom) * -1 # make bottom
# negative if
# operater is a
# minus
solution = str(sum([i for i in [int(top), ibottom]])) # sum solution
bottom = op + " " + bottom # add operator to bottom
out = [] # formated output list
mx = max(int(i) for i in [top, bottom, solution]) # largest string
for val in [top, bottom, solution]:
out.append(str(val).rjust(mx, " ")) # pad with spaces
out.insert(2, ("-" * mx)) # insert line before answer
final.append(out)
return final # return all solutions
out = output(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"])
# join lines from each solution into their own lines to print them one at a time
print('\n'.join([(' '.join([out[i][j] for i in range(len(out))])) for j in range(len(out))]))
output
32 1 9999 523
+ 8 - 3801 + 9999 - 49
--- ------ ------ ----
40 -3800 19998 474

Algebraic pyramid python challenge- more efficient way?

I'm doing a python challenge where you have to create an upside-down algebraic pyramid based on a list. Each level (going down) needs to be the sum of the numbers above it.
I created the code to do this for 4 layers.
The challenge part 2 was to do it for any length of list, so I added the len(list) code to accommodate. You can see my code below.
I just wondered if there was a more efficient way to do this for long lists, or would I just need to type out more code for the remaining layers.
Also, I wondered how the return statement is meant to fit into it (you're given the hint written in the code below to update the return statement).
def drawPyramid(list):
layer = ""
layer2 = " "
layer3 = " "
layer4 = " "
for i in range(len(list)):
layer = layer + " " + str(list[i])
for i in range(len(list)-1):
layer2 = layer2 + " " + str(list[i]+list[i+1])
for i in range(len(list)-2):
layer3 = layer3 + " " + str(list[i]+(list[i+1]*2)+list[i+2])
for i in range(len(list)-3):
layer4 = layer4 + " " + str(list[i]+(list[i+1]*3)+(list[i+2]*3)+list[i+3])
print(layer)
print(layer2)
print(layer3)
print(layer4)
#Update this code to generate all 4 layers of the pyramid
#Update this return statement to return the value of the single brick on the last layer of the pyramid
return 0
#Main code starts here
list = [30,12,10,22]
drawPyramid(list)
Here this function will calculate your pyramid using list:
def calcul_pyramid(base):
pyramid = [base]
for i in range(len(base) - 1):
actual_layer = []
last_layer = pyramid[i]
for j in range(len(last_layer) - 1):
actual_layer.append(last_layer[j] + last_layer[j + 1])
pyramid.append(actual_layer)
return pyramid
This function will get your pyramid as string:
def print_pyramid(pyramid):
lines = []
for layer in pyramid:
line = ""
for brick in layer:
line += str(brick)
line += " "
lines.append(line)
pyramid_len = max([len(layer) for layer in lines])
txt = ""
for line in lines:
diff = (pyramid_len - len(line)) / 2
txt += " " * int(diff + 0.5)
txt += line
txt += " " * int(diff - 0.5)
txt += "\n"
print(txt)
Now you can enter every base you want, it will work
print_pyramid(calcul_pyramid([30,12,10,22])))
You can use zip to add up the values, then it's just a question of formatting:
def pyramid(A):
indent = ""
width = len(str(sum(A)))
while A:
print(indent,*(f"{a:{width}}" for a in A))
A = [a+b for a,b in zip(A,A[1:])]
indent += " "*max(1,width-1)
output:
L = [30,12,10,22]
pyramid(L)
30 12 10 22
42 22 32
64 54
118
L = [30,12,10,22,23,43]
pyramid(L)
30 12 10 22 23 43
42 22 32 45 66
64 54 77 111
118 131 188
249 319
568

How would I reverse this? Python 3.8

So I've created a very... odd little caesar cipher using python. Very simple. Except, I'm not really all that great at math and am wondering how I'd reverse this?
def encrypt(text,s):
result = ""
for i in range(len(text)):
char = text[i]
if (char.isupper()):
result += chr((ord(char) + s - 23+213**3) % 26 + 713)
else:
result += chr((ord(char) + s - 23+213**3) % 26 + 715)
return result
text = input("Message: ")
s = 964
print ("Text: " + text)
print ("Shift: " + str(s))
print ("Cipher: " + encrypt(text,s))
Any form of help would be appreciated.
Edit:
I'M SO CLOSE!
I did that math as to how the shift works:
if the letter is a capital:
1. 964 - 23+213^3, which ends up as -9662656
2. Get the remainder of that divided by 26 (modulo operator) -9662656 % 26 = 10
3. 10 + 714 = 724
4. 724-63 I got the 63 just through trial and error...
ONLY PROBLEM!
It all works up until the letter M, in which case the last 13 letters shift backward 26 characters. How would I solve this?
def decrypt(text,s):
result = ""
for i in range(len(text)):
char = text[i]
result += chr((ord(char) - s))
return result
text = input("Message: ")
s = 724-63
print ("Text: " + text)
print ("Shift: " + str(s))
print ("Cipher: " + decrypt(text,s))
Text: ˖˗˘˙˚˛˜˝˞˟ˠˡˢˉˊˋˌˍˎˏːˑ˒˓˔˕
Shift: 661
Cipher: ABCDEFGHIJKLM456789:;<=>?#
I rewrote your encrypt function to show the individual piece of the calculation. Then I wrote the decrypt function to show how to "undo" them.
Note that -23+2133 is equivalent to 24 when working mod 26.
def encrypt(text, s):
cipher = ""
for pt_char in text:
val = ord(pt_char) # 65 <= val < 91
t0 = val % 26 # 0 <= t0 < 26, with A=>13, B=>14, ... N=>0 etc.
t1 = (t0 + s + 24) % 26 # 0 <= t1 < 26
t2 = t1 + 715 # 715 <= t2 < 741
cipher += chr(t2)
return cipher
def decrypt(ct, s):
plain = ""
for ct_char in ct:
t2 = ord(ct_char) # 715 <= t2 < 741
t1 = t2 - 715 # 0 <= t1 < 26
t0 = (t1 - s - 24 + 13) % 26 # 0 <= t0 < 26
val = t0 + 65 # 65 <= val < 91
plain += chr(val)
return plain
Again, this only works for upper case ASCII letters. Pay attention to the comments, they are telling you something.
Here are shorter one-liner just to show you something about how generators can produce compact code.
def encrypt_one_liner(text, s):
return ''.join(chr((ord(x) + s + 24) % 26 + 715) for x in text)
def decrypt_one_liner(text, s):
return ''.join(chr((ord(x) + 2 - s) % 26 + 65) for x in text)

How to return a string without /n, as printing it

I am doing an homework and I need to return a tree as string. I have solved the problem and when I print is all right. The problem is that the homework asks to return the string and when I return, it prints /n chars without considering them as new line.
If I print it this is the result:
04
|
05
|
01
|
06
|
03
And this should be the string I have to return.
But if I use the return instead the print it returns this:
04 \n | \n 05 \n | \n 01 \n | \n 06 \n |
\n 03
This is the class I'm using:
class Albero:
def __init__(self,V):
self.id=V
self.f=[]
n=Albero("04")
n1=Albero("05")
n2=Albero("01")
n3=Albero("06")
n4=Albero("03")
n.f=[n1]
n1.f=[n2]
n3.f=[n4]
def treeLines(node,getInfo):
nodeId,nodeChildren = getInfo(node)
subNodes = [treeLines(child,getInfo) for child in nodeChildren]
widths = [ len(childText[0]) for childText in subNodes ]
totalWidth = sum(widths) + 2*len(widths) - 1
totalWidth = max(totalWidth,len(nodeId))
nodeLine = nodeId.center(totalWidth," ")
result = [nodeLine]
if not nodeChildren: return result
linksLine = " ".join("|".center(width," ") for width in widths)
linksLine = linksLine.center(totalWidth," ")
leftIndent = linksLine.index("|") + 1
rightIndent = linksLine[::-1].index("|") + 1
spanWidth = totalWidth - leftIndent - rightIndent - 1
leftSpan = nodeLine.index(nodeId)-leftIndent+(len(nodeId)-1)//2
rightSpan = spanWidth - leftSpan
spanLine = " "*leftIndent + "_"*leftSpan + "|" + "_"*rightSpan + " "*rightIndent
if len(nodeChildren) > 1 : result.append(spanLine)
result.append(linksLine)
maxHeight = max(len(subNode) for subNode in subNodes)
subNodes = [ subNode + [" "*len(subNode[0])]*(maxHeight-len(subNode)) for subNode in subNodes ]
result += [" ".join([subNode[i] for subNode in subNodes]).center(totalWidth," ") for i in range(maxHeight) ]
return result
def treeText(node,getInfo): return "\n".join(treeLines(node,getInfo))
print( treeText(Albero.radice,lambda n:(n.id,n.f)) )
How can I return the string format as in the print ?

Categories

Resources