I have a list of strings in python which are in form of an arithmetic problem. So:
p_list = ['32 + 5', '4 - 1', '345 + 2390']
I would love each of the list to be arranged in this manner
32 4 345
+ 5 - 1 + 2390
---- --- ------
So essentially i want the numbers to be right aligned and four spaces between each expression.
I tried doing something like this
final = f"{final} {problem_list[key]['operand1']}\n{problem_list[key]['operator']} {problem_list[key]['operand2']}"
but i got this instead
213
+ 4 3234
+ 4 3
- 3 5
+ 7
thanks in advance
If your objective is to print out the equations, this function arranges them in your desired way:
def arithmetic_format(eq_list, sep = 4):
top = mid = bot = ""
sep = " " * sep
for eq in eq_list:
chars = eq.split()
width = len(max(chars, key=len)) + 2
top += chars[0].rjust(width) + sep
mid += chars[1] + chars[2].rjust(width - 1) + sep
bot += "-" * width + sep
return f"{top}\n{mid}\n{bot}"
p_list = ['32 + 5', '4 - 1', '345 + 2390']
answer = arithmetic_format(p_list)
print(answer)
Out:
32 4 345
+ 5 - 1 + 2390
---- --- ------
There are many ways to achieve this. Here's one:
plist = ['32 + 5', '4 - 1', '345 + 2390']
spaces = ' ' * 4
def parts(plist):
return [e.split() for e in plist]
def widths(plist):
return [max(map(len, e))+2 for e in parts(plist)]
def get_tokens(plist, idx):
if idx == 0:
return [f'{e:>{w}}' for (e, _, _), w in zip(parts(plist), widths(plist))]
if idx == 1:
return [f'{s}{n:>{w-1}}' for (_, s, n), w in zip(parts(plist), widths(plist))]
return ['-' * w for w in widths(plist)]
for idx in range(3):
print(spaces.join(get_tokens(plist, idx)))
Output:
32 4 345
+ 5 - 1 + 2390
---- --- ------
Try this:
p_list = ['32 + 5', '4 - 1', '345 + 2390']
up= []
down=[]
for op in p_list:
new = op.split(' ')
up.append(new[0] + ' '*4)
if new[1] == '-':
down.append(str(0 - int(new[-1])) + ' '*4)
else:
down.append('+' + new[-1] + ' '*3)
for index,value in enumerate(up):
print(value, end=' ')
print('')
for index,value in enumerate(down):
print(value, end=' ')
# 32 4 345
# +5 -1 +2390
Related
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.
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
I made this code in order that every time it runs once it gives me a list in the correct sequence, I wanted the code to form a list from the repetition forming p1+p2+p3, but the code gives me all the p1 plus all the p2 plus all the p3, I wish every time it ran I was given a list.
p11 = []
p22 = []
p33 = []
for n in range(0, quantidade):
print('EPISÓDIO', n+1)
for g in range(0, prot):
p1 = ' ' + protagonistasn[g] + ' ' + random.choice(açoes) + ' ' + random.choice(coadjuvantesn) + ' ' + random.choice(locais)
if g <= prot/2 :
p1_1 = p1.replace("#","a")
p11.append(p1_1)
print(p1_1)
elif g > prot/2 :
p1_1 = p1.replace("#", "o")
p11.append(p1_1)
print(p1_1)
for j in range(0, vil):
p2 = ' ' +viloesn[j]+ ' ' + random.choice(açoes) + ' ' + random.choice(protagonistasn) + ' ' + random.choice(locais)
if j <= vil/2:
p2_2 = p2.replace("#", "a")
p22.append(p2_2)
print(p2_2)
elif j > vil/2:
p2_2 = p2.replace("#", "o")
p22.append(p2_2)
print(p2_2)
for h in range(0, prot):
p3 = ' ' + protagonistasn[h] + ' ' + random.choice(açoes) + ' ' + random.choice(viloesn) + ' ' + random.choice(locais)
if h <= prot/2 :
p3_3 = p3.replace("#","a")
p33.append(p3_3)
print(p3_3)
elif h > prot/2 :
p3_3 = p3.replace("#", "o")
p33.append(p3_3)
print(p3_3)
p_total = [p11, p22, p33]
p_tot = []
If I understand you right, you want your p_total list to contain all the p1s, p2s, and p3s from the first iteration, and then all the p1s, p2s, and p3d from the second iteration. Is that right? If so:
p_total = []
for n in range(0, quantidade):
p11 = []
p22 = []
p33 = []
print('EPIS?DIO', n+1)
for g in range(0, prot):
...
print(p3_3)
p_total.extend( [p11, p22, p33] )
p_tot = []
So, start each loop with an empty p11, p22, and p33. At the end of each iteration, append those on to your p_total, instead of holding them until the end.
I am trying to write a function that will multiplicate the given number with 1 to 10 and print out the result.
Here is my code:
number = input('Enter a number please: ')
def multiplication(number):
for i in range(1, 10)
return print(number =* i)
multiplication(3)
and here is the error:
SyntaxError: invalid syntax erdoganpc#MacBook-Air-Denis pyShit %
/Library/Frameworks/Python.framework/Versions/3.8/bin/python3
/Users/erdoganpc/Documents/dev/pyShit/main.py File
"/Users/erdoganpc/Documents/dev/pyShit/main.py", line 3
for i in range(1, 10)
can't understand how to solve this problem, please help me :(
Try this
def multiplication(number):
result = []
for i in range(1, 11):
result.append(str(i) + ' * ' + str(number) + ' = ' + str(number * i))
return result
Output:
['1 * 4 = 4', '2 * 4 = 8', '3 * 4 = 12', '4 * 4 = 16', '5 * 4 = 20', '6 * 4 = 24', '7 * 4 = 28', '8 * 4 = 32', '9 * 4 = 36', '10 * 4 = 40']
There is an error in your script, you wrote =* instead of *=, so the correct way is:
number = input('Enter a number please: ')
def multiplication(number):
for i in range(1, 10):
number *= i
return number
print(multiplication(3))
number = int(input('Enter a number please: '))
def multiplication(number):
for i in range(1, 10):
number *= i
print(number)
multiplication(number)
Enter a number please: 3
3
6
18
72
360
2160
15120
120960
1088640
I have a voting system for something where people rate things from one to ten. I am able to get the number of total votes, but not their distribution. I can, however, access the totals for each score (but not what score they are for).
For example, say two people voted 2 and three 4 then I would get [4, 12]. Humanly, it is possibly to work out what the votes were, however as there is a lot of data, I need an algorithm that is able to do it programmatically. To solve this humanly, I would know that there were 5 votes and this I would know that it was either one four and four thees or two twos and three fours. Because this isn't the best example, we can't tell which one it would be and so it this situation, the algorithm should spit out all of the solutions. With the real data, it is very rare that something like this occurs.
The input is in the form of an int representing the total number of votes cast, and a list of all of the vote subtotals. The output should be an array containing pars (x, y) where there are x number of y votes cast. If more than one solution is present, the algorithm should return all of them in an array.
EDIT:
Here's some real data (17 people voted):
Dunkel - 60 + 18 + 8 + 18 + 10 + 4 + 3 + 1 = 122
Satomi - 20 + 14 + 24 + 12 + 3 + 4 + 3 = 80
Bottersnike - 16 + 28 + 5 + 8 + 6 + 4 + 4 = 71
Woon - 40 + 36 + 8 + 21 + 5 + 16 = 126
Limelier - 10 + 18 + 6 + 15 + 8 + 4 + 6 = 67
RandomGamer - 16 + 6 + 10 + 4 + 6 + 4 + 7 = 53
Pillar - 10 + 8 + 21 + 6 + 15 + 4 + 9 + 4 + 2 = 79
EdgedPixel - 8 + 28 + 12 + 4 + 18 + 2 + 2 = 74
Lock - 20 + 24 + 7 + 18 + 10 + 8 + 6 + 2 = 95
Huri - 10 + 8 + 7 + 6 + 15 + 20 + 3 + 2 + 3 = 74
Sean - 18 + 32 + 8 + 5 + 4 + 9 + 2 = 78
And the answers (sorry about the different order):
Woon - 4*10 + 4*9 + 1*8 + 3*7 + 0*6 + 1*5 + 4*4 + 0*3 + 0*2 + 0*1 = 126
Dunkel - 6*10 + 2*9 + 1*8 + 0*7 + 3*6 + 2*5 + 1*4 + 1*3 + 0*2 + 1*1 = 122
Lock - 2*10 + 0*9 + 3*8 + 1*7 + 3*6 + 2*5 + 2*4 + 2*3 + 0*2 + 2*1 = 95
Satomi - 2*10 + 0*9 + 3*8 + 4*7 + 2*6 + 0*5 + 0*4 + 1*3 + 2*2 + 3*1 = 80
Pillar - 1*10 + 0*9 + 1*8 + 3*7 + 1*6 + 3*5 + 1*4 + 3*3 + 2*2 + 2*1 = 79
Sean - 0*10 + 0*9 + 4*8 + 0*7 + 3*6 + 1*5 + 2*4 + 3*3 + 2*2 + 2*1 = 78
EdgedPixel - 0*10 + 0*9 + 1*8 + 4*7 + 2*6 + 0*5 + 1*4 + 6*3 + 1*2 + 2*1 = 74
Huri - 1*10 + 0*9 + 1*8 + 1*7 + 1*6 + 3*5 + 5*4 + 1*3 + 1*2 + 3*1 = 74
Bottersnike - 0*10 + 0*9 + 2*8 + 4*7 + 0*6 + 1*5 + 2*4 + 2*3 + 2*2 + 4*1 = 71
Limelier - 1*10 + 2*9 + 0*8 + 0*7 + 1*6 + 3*5 + 2*4 + 0*3 + 2*2 + 6*1 = 67
RandomGamer - 0*10 + 0*9 + 2*8 + 0*7 + 1*6 + 2*5 + 1*4 + 2*3 + 2*2 + 7*1 = 53
I need an algorithm that is able to do it programmatically
I'd begin by factoring your totals.
What is the most efficient way of finding all the factors of a number in Python?
def factors(n):
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
This will return all of the factors, very quickly, of a number n.
that would get you well on your way; obviously a listed total that doesn't have 5 for a factor did not come from a group that rated 5's
step 1) factor each number in your list of totals
step 2) create dictionary with all possible ratings as the keys; ie keys 1-10; each with empty lists as values.
step 3) check if each list of factors has a factor which matches each rating key; if so append the total it represents to the values list of possibilities for that respective key
from random import randint
from random import shuffle
VOTES = 200
RATINGS = 10
# Generate Test Data
ratings = {}
for i in range(1,(RATINGS+1)):
ratings[i] = []
for i in range(VOTES):
rate = randint(1,RATINGS)
ratings[rate].append(rate)
subtotals = []
for key, values in ratings.iteritems():
subtotals.append(sum(values))
subtotals = [i for i in subtotals if i != 0]
subtotals.sort()
hidden_subtotals = {}
for key, values in ratings.iteritems():
hidden_subtotals[key] = sum(values)
print '==================================='
print 'Generate Hidden Test Data'
print 'unknown actual votes: %s' % ratings
print 'unknown actual subtotals: %s' % hidden_subtotals
print '==================================='
print 'Present Problem'
print 'known vote total: %s' % VOTES
print 'known subtotals: %s' % subtotals
print 'known total: %s' % sum(subtotals)
print 'number of ratings used: %s of %s' % (len(subtotals), RATINGS)
print '==================================='
def factors(n):
f = list(set(reduce(list.__add__, ([i, n//i] for i in range(
1, int(n**0.5) + 1) if n % i == 0))))
f.sort()
return f
# Factor Each
subtotal_factors = {}
for i in subtotals:
subtotal_factors[i]=(factors(i))
print 'process 1: %s' % subtotal_factors
# Remove Factors greater than highest rating
possible_ratings = {}
for i in subtotal_factors:
possible_ratings[i] = [
z for z in subtotal_factors[i] if z<=RATINGS]
print 'process 2: %s' % possible_ratings
# Remove Factors if not enough votes for that possibility; too small relative to subtotal
for i in possible_ratings:
possible_ratings[i] = [
z for z in possible_ratings[i] if i/z < VOTES]
print 'process 3: %s' % possible_ratings
step 4) then you'll have a problem where 2's will fit in 4's, 6's, 8's, 10's; 4's will fit in 8's, and 3's will fit in 6's and 9's. You'll have to apply some logic to clean up the results.
I have now solved my problem. I used litepresence's code as a base, and then implemented what they described as step four. For the future, this is the code I used:
from random import randint
from random import shuffle
import itertools
NUM_RATINGS = 10
RATING = [10, 10, 10, 10, 10, 10, 9, 9, 8, 6, 6, 6, 5, 5, 4, 3, 1]
VOTES = len(RATING)
ratings = {}
for i in range(1, (NUM_RATINGS + 1)):
ratings[i] = []
for i in RATING:
ratings[i].append(i)
subtotals = []
for key, values in ratings.iteritems():
subtotals.append(sum(values))
subtotals = [i for i in subtotals if i != 0]
subtotals.sort()
hidden_subtotals = {}
for key, values in ratings.iteritems():
hidden_subtotals[key] = sum(values)
print '==================================='
print 'Hidden Test Data:'
print 'unknown actual votes: %s' % ratings
print 'unknown actual subtotals: %s' % hidden_subtotals
print '==================================='
print 'Present Problem:'
print 'known vote total: %s' % VOTES
print 'known subtotals: %s' % subtotals
print 'known total: %s' % sum(subtotals)
print 'number of ratings used: %s of %s' % (len(subtotals), NUM_RATINGS)
print '==================================='
def factors(n):
f = list(set(reduce(list.__add__, ([i, n//i] for i in range(
1, int(n**0.5) + 1) if n % i == 0))))
f.sort()
return f
# Factor Each
subtotal_factors = {}
for i in subtotals:
subtotal_factors[i]=(factors(i))
print 'process 1: %s' % subtotal_factors
# Remove Factors greater than highest rating
possible_ratings = {}
for i in subtotal_factors:
possible_ratings[i] = [
z for z in subtotal_factors[i] if z<=NUM_RATINGS]
print 'process 2: %s' % possible_ratings
# Remove Factors if not enough votes for that possibility; too small relative to subtotal
for i in possible_ratings:
possible_ratings[i] = [
z for z in possible_ratings[i] if i/z < VOTES]
print 'process 3: %s' % possible_ratings
end_res = {}
other = {} # (count, [poss])
for i in possible_ratings.items():
if len(i[1]) == 1:
end_res[i[0]] = (i[1][0], i[1][0])
else:
other[i[0]] = (subtotals.count(i[0]), i[1])
combs = {}
for i in other.items():
combs[i[0]] = (i[1][0], []) # (count, [data])
for a in i[1][1]:
for b in i[1][1]:
if (a, b) not in combs[i[0]]:
if a * b == i[0]:
combs[i[0]][1].append((a, b))
lists = []
for i in combs.items():
for j in range(i[1][0]):
lists.append([])
for n in i[1][1]:
lists[-1].append((n[0], n[1], i[0]))
toprocess = itertools.product(*lists)
working = []
for test in toprocess:
works = True
seen = []
tot = 0
for i in test:
if i[1] in seen:
works = False
break
tot += i[0]
if tot > VOTES:
works = False
break
seen.append(i[1])
if not works:
continue
else:
working.append(test)
formattedWs = []
for w in working:
w = list(w)
notseen = [i + 1 for i in range(NUM_RATINGS)]
for i in w:
notseen.remove(i[1])
for i in notseen:
w.append((0, i))
t = ""
def f(x, y):
return y[1] - x[1]
w.sort(cmp=f)
for i in w:
t += "%d*%d + " % (i[0], i[1])
t = t[:-3]
formattedWs.append(t)
seen = []
for w in list(formattedWs):
if w in seen:
formattedWs.remove(w)
else:
seen.append(w)
print "==================================="
for n, w in enumerate(formattedWs):
print "Solution #%d: %s" % (n + 1, w)