How to remove a certain string before printing? - python

answer = input('Enter a number: ')
x = 10**(len(answer) - 1)
print(answer, end = ' = ')
for i in answer:
if '0' in i:
x = x//10
continue
else:
print('(' + i + ' * ' + str(x) + ')' , end = '')
x = x//10
print(' + ', end = '')
so i have this problem, when i enter any number, everything is great but at the end there is an extra ' + ' that i do not want. Now normally this wouldnt be an issue with lists and .remove function, however i am not allowed to use these for this problem. I cannot come up with any sort of solution that does not involve functions
I tried matching the length but it didnt work because of '0'

you can insert an extra condition in the else block:
else:
print('(' + i + ' * ' + str(x) + ')' , end = '')
x = x//10
if x:
print(' + ', end = '')
this will help not to insert the last plus when it is not needed

The error is that there is an extra '+' at the end of the output. This can be fixed by adding an 'if' statement to the end of the code that checks if the last character in the output is a '+' and, if so, removes it.

Well Valery's answer is the best just add one more condition in case the answer was a 10 multiple
if x and int(answer)%10 != 0:

This kind of problem is best solved using the str.join() method.
answer = input("Enter a number: ")
x = 10**(len(answer) - 1)
terms = []
for i in answer:
if i == "0":
x = x//10
continue
else:
terms.append(f"({i} * {x})")
x = x//10
print(f"{answer} =", " + ".join(terms))
Sample interaction:
Enter a number: 1025
1025 = (1 * 1000) + (2 * 10) + (5 * 1)
Notes
We build up the terms by appending them into the list terms
At the end of the for loop, given 1025 as the input, the terms looks like this
['(1 * 1000)', '(2 * 10)', '(5 * 1)']
Update
Here is a patch of your original solution:
answer = input('Enter a number: ')
x = 10**(len(answer) - 1)
print(answer, end = ' = ')
for i in answer:
if '0' in i:
x = x//10
continue
else:
print('(' + i + ' * ' + str(x) + ')' , end = '')
x = x//10
if x == 0:
print()
else:
print(' + ', end = '')
The difference is in the last 4 lines where x (poor name, by the way), reaches 0, we know that we should not add any more plus signs.

answer = input('Enter a number: ')
#finds length of answer
length = 0
for n in answer:
length += 1
loop_counter = 0
##
zero_counter = 0
multiple_of_ten = 10
#finds if answer is multiple of 10 and if so by what magnitude
while True:
if int(answer) % multiple_of_ten == 0:
#counts the zeroes aka multiple of 10
zero_counter += 1
multiple_of_ten = multiple_of_ten*10
else:
break
#finds the multiple of 10 needed for print output
x = 10**(length - 1)
print(answer, end = ' = ')
for i in answer:
# if its a 0 it will skip
if '0' in i:
x = x//10
#still divises x by 10 for the next loop
pass
else:
print('(' + i + ' * ' + str(x) + ')' , end = '')
x = x//10
#if position in loop and zeroes remaining plus one is equal to
#the length of the integer provided, it means all the reamining
#digits are 0
if loop_counter + zero_counter + 1 == length:
break
else:
#adds ' + ' between strings
print(' + ', end = '')
# keeps track of position in loop
loop_counter += 1
ended up implementing a counter to see how many zeroes there are, and a counter to see where we are in the for loop and stop the loop when its the same as amount of zeroes remaining

I tested this code and it worked fine
if x and int(answer)%10 != 0:
Enter a number: 25
25 = (2 * 10) + (5 * 1)
Enter a number: 1000
1000 = (1 * 1000)
Enter a number: 117
117 = (1 * 100) + (1 * 10) + (7 * 1)

Related

Python arithmetic calculator printing incorrect number of dashes [duplicate]

This question already has answers here:
How to find length of digits in an integer?
(31 answers)
Closed 1 year ago.
I am presently finishing a course in python and I came across this glitch which has stumped me for a few days. The result should resemble this:
32 3801 45 123
+ 698 - 2 + 43 + 49
--- ---- -- ---
730 3799 88 172
However, it instead prints out this:
32 3801 45 123
+ 698 - 2 + 43 + 49
--- ---- -- --
730 3799 88 172
Please notice the sum of dashes in the fourth equation. In the correct version, the number of dashes correlates to the length of the max number. However, in the incorrect version (my version) the number of dashes is 2 when the length of the max number is 3.
Here is the entire code
equations = ["32 + 698", "3801 - 2", "45 + 43", "123 + 49"]
def arithmetic_equation(arr):
stepOne = ''
stepTwo = ''
stepThree = ''
stepFour = ''
finalLine = ''
anotherLine = ''
thirdLine = ''
fourthLine = ''
space = 4
for item in equations:
parts = item.split()
x = parts[0]
y = parts[2]
c = parts[1]
if c == '+': z = (int(x) + int(y))
else: z = (int(x) - int(y))
n = len(x) if (x > y) else len(y)
stepOne = x.rjust(n + 2)
stepTwo = c + ' ' + y.rjust(n)
stepThree = ' ' + '-' * n
stepFour = str(z).rjust(n + 2)
finalLine += str(stepOne) + ' ' * space
anotherLine += str(stepTwo) + ' ' * space
thirdLine += str(stepThree) + ' ' * space
fourthLine += stepFour + ' ' * space
print(finalLine.rstrip() + '\n' + anotherLine + '\n' + thirdLine + '\n' + fourthLine)
arithmetic_equation(equations)
just a minor change - you'll know why this works.
instead of
n = len(x) if (x > y) else len(y)
use
n = len(x) if len(x) > len(y) else len(y)
In the line n = len(x) if (x > y) else len(y) you forgot to add len() while comparing if x > y.
Try this:
n = len(x) if (len(x) > len(y)) else len(y)
Or better use this:
n = max(len(y), len(x))

Forming a polynomial from the input

I need to write a program that, when provided inputs by the user, will create a polynomial based on the position of the input order.
For example, if the user input: 1 2 3
The polynomial should be printed x^2 + (2.0)x^1 + 3 and this answer should be in float form. How do I do that?
This is what I have done so far
def get_expression(x1):
x1=""
power = len(x1) - 1
for i in range(len(x1)):
if x1[i] < 0:
x1 += str(x1[i])
else:
x1 += "+" + str(x1[i])
if x1[i] == 0:
continue
if power == 1:
x1 += "x"
elif power == 0:
x1 = x1
else:
x1 += "x" + str(power)
power = power - 1
if sum(x1)==0:
return float(0)
return x1
The code should satisfy the code below and give results correctly in the form: -4.5x - 5 & 2x^2 - 3
p1=[-4.5,-5.0]
print(get_expression(p1))
p2=[2.0,0.0,-3.0]
print(get_expression(p2))
Please help me and advise how I could correct my code and get an answer in float form.
You could build the string naively and then make it look nicer with string replacements:
def poly(*C):
result = "+".join(f" {c}x^{-p} " for p,c in enumerate(C,1-len(C)) if c)
result = result.replace("+ -","- ") # subtract for negative coefficient
result = result.replace("^1 "," ") # implicit x^1
result = result.replace("x^0","") # implicit x^0
result = result.replace(" 1x"," x").replace("-1x","-x") # implicit 1x
return result.strip()
for example: poly(-1,0,3,-1,5)
result = ' -1x^4 + 3x^2 + -1x^1 + 5x^0 ' # naive build (skips zero coeff.)
result = ' -1x^4 + 3x^2 - 1x^1 + 5x^0 ' # subtract for negative coefficient
result = ' -1x^4 + 3x^2 - 1x + 5x^0 ' # implicit x^1
result = ' -1x^4 + 3x^2 - 1x + 5 ' # implicit x^0
result = ' -x^4 + 3x^2 - x + 5 ' # implicit 1x
return '-x^4 + 3x^2 - x + 5' # strip extra space for return
output:
print(poly(1,2,3)) # x^2 + 2x + 3
print(poly(-4.5,-5)) # -4.5x - 5
print(poly(2,0,-3)) # 2x^2 - 3
print(poly(-1,0,-1.5,5,0,-32)) # -x^5 - 1.5x^3 + 5x^2 - 32
print(poly("a","b","-c")) # ax^2 + bx - c
Sort of follow your logic and re-write your code, FYI.
def get_expresultsion(x1):
result = "" # use another variable instead of x1
power = len(x1) - 1
for i in range(len(x1)):
if x1[i] < 0:
result += str(x1[i])
elif x1[i] == 0:
# put this into the same IF logic since this part is checking x1[i] as well
power = power - 1
continue
else:
result += "+" + str(x1[i])
# check power then
if power == 1:
result += "x"
elif power == 0:
pass
else:
# add "^"
result += "x^" + str(power)
power = power - 1
if sum(x1) == 0:
return float(0)
return result
At the time of viewing your question, I couldn't understand the logic you were following so I wrote it from scratch as simple as I can.
def get_expression(coefficient_list):
power = 0
expression = "" #Our final result (instead of x1)
if len(coefficient_list) == 1: #For the case having just the constant
return(coefficient_list[0])
elif len(coefficient_list) > 1:
for coefficient in reversed(coefficient_list): #We reverse the list
if power == 0: #Dealing with constant
expression += str(coefficient)
else: #Here it puts the coeff and power together and adds to the left side of expression
expression = f"({coefficient})x^{power} + " + expression
power += 1
return expression

How to increment alphanumeric number in python?

I am creating a passkey of 16 alphanumeric characters where I am generating starting 4 digits with A001, A002, A003 till A999. Once it goes till A999, the alphabet will auto increase to B and digits will again start with 001. And the same process will go till Z999. Once the A-Z series will over, then it will start with AA01 and so on. How to do this thing in python? As I am new in python so I tried it on my own and also tried some examples but I am unable to make the increment of characters.
Any ideas or thoughts would be greatly appreciated.
Many thanks
rec=0
new_list16 = []
def autoIncrement():
global rec
first = 'A'
i = chr(ord(first))
new_list16.append(i)
while True:
pStart = 1 #adjust start value, if req'd
pInterval = 1 #adjust interval value, if req'd
if (rec == 0):
rec += pStart
else:
rec = rec + pInterval
return str(rec).zfill(3)
#print(autoIncrement())
new_list16.append(autoIncrement())
print(*new_list16, sep = '')
Going from A999 to B001 instead of B000 really messes things up a bit, but you can still use this for the A-Z part, and a simple modulo operation for the numbers.
def excel_format(num):
# see https://stackoverflow.com/a/182924/1639625
res = ""
while num:
mod = (num - 1) % 26
res = chr(65 + mod) + res
num = (num - mod) // 26
return res
def full_format(num, d=3):
chars = num // (10**d-1) + 1 # this becomes A..ZZZ
digit = num % (10**d-1) + 1 # this becomes 001..999
return excel_format(chars) + "{:0{}d}".format(digit, d)
for i in range(10000):
print(i, full_format(i, d=2))
Number of digits in the numeric part is controlled with the optional d parameter. I'll use 2 for purpose of demonstration, but 3 works just as well.
0 A01
...
98 A99
99 B01
...
2573 Z99
2574 AA01
...
9998 CW99
9999 CX01
def auto_increment(number):
if number == 'ZZZZ':
return 'ZZZZ'
digits = "".join([i for i in number if i.isdigit()])
chars = "".join([i for i in number if not i.isdigit()])
if int(digits) == int('9' * len(digits)):
digits = "000"
new_char = [ord(i) for i in chars]
if new_char[-1] % ord('Z') == 0:
new_char = "".join([chr(i) for i in new_char]) + 'A'
else:
new_char[-1] = new_char[-1] + 1
new_char = "".join([chr(i) for i in new_char])
else:
new_char = chars
new_digit = int(digits) + 1
l = len(new_char)
ll = len(str(new_digit))
new_digit = (("0" * (3-ll)) + str(new_digit))[(l-1):]
return f"{new_char}{new_digit}"
This function return you the next number, given any number.
for example: A999 will return AB01.
you can now just use this function in a loop.
This probably needs to be tested and refactored more, but here's a start for you:
def leadingZeros(number, digits):
numberString = str(number)
for digit in range(1, digits):
if number < 10**digit:
numberString = '0' + numberString
return numberString
def autoIncrement(oldNumber):
order = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!'
lastDigitOrder = order.find(oldNumber[3])
newNumber = ''
if order.find(oldNumber[1]) <= 9:
# 3 digit number
number = int(oldNumber[1:]) + 1
letter = oldNumber[0]
if 1000 == number:
letterOrder = order.find(oldNumber[0])
letter = order[letterOrder + 1]
newNumber = letter + leadingZeros(number % 1000, 3)
elif order.find(oldNumber[2]) <= 9:
# 2 digit number
number = int(oldNumber[2:]) + 1
letters = oldNumber[0:2]
if 100 == number:
letterOrder = order.find(oldNumber[1])
letter = order[letterOrder + 1]
letters = oldNumber[0] + letter
newNumber = letters + leadingZeros(number % 100, 2)
elif order.find(oldNumber[3]) <= 9:
# 1 digit number
number = int(oldNumber[3]) + 1
letters = oldNumber[0:3]
if 10 == number:
letterOrder = order.find(oldNumber[2])
letter = order[letterOrder + 1]
letters = oldNumber[0:2] + letter
newNumber = letters + leadingZeros(number % 10, 1)
else:
# just letters
print(oldNumber)
letterOrder = order.find(oldNumber[3])
letter = order[letterOrder + 1]
newNumber = oldNumber[0:3] + letter
# if one of the digits has gone past Z then we need to update the letters
if '!' == newNumber[3]:
# past Z in 4th digit
letterOrder = order.find(oldNumber[2])
newNumber = newNumber[0:2] + order[letterOrder + 1] + 'A'
if '!' == newNumber[2]:
# past Z in 3rd digit
letterOrder = order.find(oldNumber[1])
newNumber = newNumber[0:1] + order[letterOrder + 1] + 'A' + newNumber[3]
if '!' == newNumber[1]:
# past Z in 2nd digit
letterOrder = order.find(oldNumber[0])
newNumber = order[letterOrder + 1] + 'A' + newNumber[2:]
return newNumber
print(autoIncrement('A999'))
print(autoIncrement('AA99'))
print(autoIncrement('AAA9'))
print(autoIncrement('AAAA'))
print(autoIncrement('AZZ9'))
This is not quite what you are asking for, but if your requirement is for 4-character "sequential" strings, let me suggest a far more simpler approach. Why not simply used base 36 numbers? That is, have your numbers go from 0, 1, 2, ... A, B, C, ... Z, 10, 11, 12, ... 1Z, ... Then to convert one of the base 36 strings to an int it is simply:
n = int('12AV', 36)
And to convert an int to a base n string:
def baseN(num, base, numerals="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
return ((num == 0) and numerals[0]) or (baseN(num // base, base, numerals).lstrip(numerals[0]) + numerals[num % base])
Putting it all together:
n = int('12AV', 36)
s = baseN(n + 1, 36)
print(s)
Prints:
12AW
You can, of course, start with 'A001' if you need to. You will then go to A00Z after 35 iterations. You will end up generating the same numbers as in your original method, just in a different order.
Thank you for the solutions you had provided. But I tried something exactly which I want for my question. Please check it and give your comments on it.
def full_format(i):
# limit of first range is 26 letters (A-Z) times 999 numbers (001-999)
if i < 26 * 999:
c,n = divmod(i,999) # quotient c is index of letter 0-25, remainder n is 0-998
c = chr(ord('A') + c) # compute letter
n += 1
return f'{c}{n:03}'
# After first range, second range is 26 letters times 26 letters * 99 numbers (01-99)
elif i < 26*999 + 26*26*99:
i -= 26*999 # remove first range offset
cc,n = divmod(i,99) # remainder n is 0-98, use quotient cc to compute two letters
c1,c2 = divmod(cc,26) # c1 is index of first letter, c2 is index of second letter
c1 = chr(ord('A') + c1) # compute first letter
c2 = chr(ord('A') + c2) # compute second letter
n += 1
return f'{c1}{c2}{n:02}'
else:
raise OverflowError(f'limit is {26*999+26*26*99}')
for i in range(92880, 92898):
print(full_format(i))

getting into infinite loop when using a while loop

I am using this code to use a dataframe lookup for every single record in the first dataframe.
for i in range(len(a1)):
title_derived = []
k = 100000
print(i)
for j in range(len(b1)):
print(j)
while j < (k + 6):
#print(b1.iloc[i][10], a1.iloc[j][3])
if b1.iloc[j][10] == a1.iloc[i][3]:
print(j,k)
print('1st if ' + str(j))
print (b1.iloc[j][1], a1.iloc[i][11], b1.iloc[j][5])
if (((pd.to_datetime(b1.iloc[j][1]) <= pd.to_datetime(a1.iloc[i][11]) <= pd.to_datetime(b1.iloc[j][5]))) or ((pd.to_datetime(b1.iloc[j][1]) <= pd.to_datetime(a1.iloc[i][8]) <= pd.to_datetime(b1.iloc[j][5])))) :
print('2nd if' + str(j))
title_derived.append(b1.iloc[j][15])
print('inserted ' + b1.iloc[j][15] + ' in ' + str(i) + ' th record ')
a1.iat[i,65] = title_derived
It prints,
0
0
and then goes into a an infinite loop.
May be it is because you are length of "b1" in lesser than value of "k + 6". And in that case you will never get out of while loop and in the last it will throw and error.
In this case you should first check the least possible length of "b1" and then decide your wile condition.

How to draw this bow tie pattern using Python 2.7?

I need to draw the following pattern using Python While Loops.
I have spent quite a lot of time and came up with this code which prints it perfectly but this code is so much long and I feel like it is not one of those good codes.
If anybody here can help me out shrinking this code or suggesting a better way to output?
here is the code:
#Question 10, Alternate Approach
temp = 1
pattern = ""
innerSpace = 7
starCount = 1
while temp <= 5:
st = 1
while st <= starCount:
pattern = pattern + "*"
if st != starCount:
pattern = pattern + " "
st = st + 1
sp = 0
if temp == 5:
innerSpace = 1
while sp < innerSpace:
pattern = pattern + " "
sp = sp + 1
st = 1
while st <= starCount:
if temp == 5:
st = st + 1
pattern = pattern + "*"
if st != starCount:
pattern = pattern + " "
st = st + 1
temp = temp + 1
innerSpace = innerSpace - 2
pattern = pattern + "\n"
if temp % 2 == 0:
pattern = pattern + " "
else:
starCount = starCount + 1
starCount = 2
innerSpace = 1
while temp > 5 and temp <= 9:
st = 1
while st <= starCount:
pattern = pattern + "*"
if st != starCount:
pattern = pattern + " "
st = st + 1
sp = 0
while sp < innerSpace:
pattern = pattern + " "
sp = sp + 1
st = 1
while st <= starCount:
pattern = pattern + "*"
if st != starCount:
pattern = pattern + " "
st = st + 1
temp = temp + 1
innerSpace = innerSpace + 2
pattern = pattern + "\n"
if temp % 2 == 0:
starCount = starCount - 1
pattern = pattern + " "
print pattern
Since this looks like an assignment, I'll give you a hint how I would do it.
Take advantage of the symmetry of the bow. It is symmetrical about the horizontal and vertical axis. Therefore, you really only need to solve 1 corner, then copy/mirror the results to get the rest.
This code gives one way of looking at the problem, which is just shifting a initial string (the middle of the bow) to get the desired shape:
m = '*'
size = 4
n = 5 # must be odd
pad = ' ' * n
middle = (m + pad) * size
half = int(n / 2) + 1
print middle
print middle[half*1:]
print middle[half*2:]
print middle[half*3:]
print middle[half*4:]
print middle[half*5:]
print middle[half*6:]
Which yields this:
* * * *
* * *
* * *
* *
* *
*
*
Good luck!
I would use list comprehensions and strings and would exploit the symmetry of the figure.
Not a complete solution, but could be a part of a loop body
In [2]: a = '*' + ' '*8
In [3]: a
Out[3]: '* '
In [24]: result = ''
In [25]: result += a
In [26]: result
Out[26]: '* '
In [27]: result += a[-1::-1]
In [28]: result
Out[28]: '* *'
In [29]: result += '\n'
In [30]: a = ' '+'*' + ' '*7
In [31]: a
Out[31]: ' * '
In [32]: result += a
In [33]: result += a[-1::-1]
In [34]: result += '\n'
In [36]: print result
* *
* *
IMHO you use while loop much as if they where for loops.
I don't think that's what your teacher wants.
The idea behind while is to run until a certain condition is met, not
necessarily when the number of iterations exceed a certain limit.
The condition does not need to be included in the while statement, you can check it later and use the break command to escape the loop
Try for example this:
start = '*'
while True:
print start
if start[0] == '*':
start = ' ' + start
else:
start = '*' + start
if (start == '* * *'):
break
output is just a part of your assignment, think you should be able to work it out to the final, expected result!
Hopefully by this time HW is done. Since I solved this using dynamic programming, I thought I would list solution here.
Observations:
While looking at pattern its observed that bottom half is palindrome of top half. Hence we need to calculate only the top half.
Next we see that for every row count,we have pattern like,
row 1 = 1 , n
row 2 = 2 , n -1
row 3 = 1,3, n-2, n
row 4 = 2, 4 , n-3, n-1
.. and so on.
With iteration index as row count and n as input value we can dynamically calculate remaining values very efficiently.
Source-Code
def get_list(bound, alist):
tmp_list = []
for i in xrange(1,bound + 1):
tmp_list.append(star if i in alist else dot)
return tmp_list
star = "*"
dot = " "
n = 20 #How large of BowTie do you want?
m = (n * 2) - 1
#get top half list
th = []
for idx,k in enumerate(xrange(1,n+1)): #run through 1 - n
row = idx + 1
tmplst = []
if row % 2 != 0:
tmplst.append(i for i in xrange(1,row + 1) if i % 2 != 0)
tmplst.append(i for i in xrange(m, m-row, -1) if i % 2 != 0)
else:
tmplst.append(i for i in xrange(1,row + 1) if i % 2 == 0)
tmplst.append(i for i in xrange(m, m-row, -1) if i % 2 == 0)
#append each row value to top half list.
th.append(sorted(set([j for i in tmplst for j in i])))
#create palindrome of top half which is our bottom half
th = th + th[len(th) -2::-1]
#create list of * and blanks
final = [get_list(m, i) for i in th]
#Print BowTie
for i in final:
print ' '.join(i)
Using a stars and spacing and counting variable
counting=1
star_amount=1
space_amount=6
loop_var=7
while loop_var>0:
loop_var-=1
if space_amount==0:
counting*=-1
stars=" * "*star_amount
spaces=" "*space_amount
print(stars+spaces+stars)
star_amount+=counting
space_amount-= counting*2

Categories

Resources