input of python calculator - python-3.x

I write project in Python3, which is advanced calculator. It consist of two modules: science calculator and basic calculator. I have a problem with second one. I want to create an input, which doesn't demand spaces between numbers and mathematical symbols. I have no idea, how to do this.
Can you help?
I attached only basic one's part of code, because science module import function from many of my different files.
from os import system
zbior = input().split(" ")
liczby = []
dzialania = []
if zbior[0] == "-" or zbior[0] == "+":
for i in range(1, len(zbior), 2):
try:
zbior[i] = float(zbior[i])
except ValueError:
print("Pamiętaj o poprawnym wprowadzeniu działania (odzziel liczby spacją), zobacz instrukcję.")
# calls the function which loops back code
elif zbior[0]=="m":
#calls menu function from differnet file
print("menu")
elif zbior[0] == "+" or str(zbior[0])[0] in "0123456789":
for i in range(0, len(zbior), 2):
try:
zbior[i] = float(zbior[i])
except ValueError:
print("Pamiętaj o poprawnym wprowadzeniu działania (odzziel liczby spacją), zobacz instrukcję.")
# calls the function which loops back code
else:
print("Pamiętaj o poprawnym wprowadzeniu działania, zobacz instrukcję.")
# calls the function which loops back code
if zbior[0] == "-" or zbior[0] == "+":
for znak in zbior:
if zbior.index(znak) % 2 != 0:
liczby.append(znak)
else:
dzialania.append(znak)
else:
for znak in zbior:
if zbior.index(znak) % 2 == 0:
liczby.append(znak)
else:
dzialania.append(znak)
ind = 0
suma = liczby[0]
while (ind+1) <= (len(dzialania)):
if dzialania[ind] == "+":
suma += liczby[ind+1]
if dzialania[ind] == "-":
suma -= liczby[ind + 1]
if dzialania[ind] == "*":
suma = suma*liczby[ind+1]
if dzialania[ind] == "/":
if liczby[ind+1] == 0:
print("""Pamiętaj cholero, nie dziel przez zero!!!""")
system('cls')
# calls the function which loops back code
else:
suma = suma/liczby[ind + 1]
if dzialania[ind] == "%":
if liczby[ind+1] == 0:
print("""Pamiętaj cholero, nie dziel przez zero!!!""")
system('cls')
#calls the function which loops back code
else:
suma = suma % liczby[ind + 1]
ind += 1
print(suma)

I don't know what some of the words in your script mean, but if I wanted to input something like 2+2 and get ["2", "+", "2"] I would do something like this:
zbior = [x for x in list(input()) if x != " "]
list(input()) splits every character in the input and if x != " " makes sure that whitespaces in the input are ignored.
Example:
>>> zbior = [x for x in list(input()) if x != " "]
1+2*3+4
>>> zbior
['1', '+', '2', '*', '3', '+', '4']

A simple list with skipping spaces then following those characters will work well.
For now.
Once you get into more complex expressions you'll have a lot of problems, write a proper mathematical expression evaluator instead. That is, if you really mean advanced calculator.
Consider following this guide: https://ruslanspivak.com/lsbasi-part1/
By part 6 you'll have a calculator that can evaluate ANY input that has less than a thousand ( left parentheses before they are closed off by ), Python has recursion depth of 1000, it can be increased, but there's a limit for a reason.
What I mean by that, is that it will be fine with an expression that has "(" * 999 before the first ) ever occurs, but I wouldn't expect anyone to write such monstrocity unless they are willing to spend next 3 years thinking about an expression or write a mathematical expression generator which is inverse of this. TL;DR - practically, this thing can evaluate anything you'd ever wish for. Advanced calculator for sure.
If you'll like it, you can even continue following it and make your own interpreter, it's slow, and if you want different syntax you'll have to sit for a bit and think about it, but I think it's worth doing at least once in your life.

Related

Accepting a list, splitting the elements in sublists and printing together

Currently learning Python through freecodecamp.org and other resources. I have difficulty grasping the concept of splitting a list in sublists and iterating over them. I have an assignment of different exercises that need to be printed in order.
The thing is, I have it working for when the input is only 1 exercise. I just can't seem to make it work by giving it a list. What am I missing?
def arithmetic_arranger(problems, answer=False):
for som in problems:
sumlist = list(som.split())
getal_a=(sumlist[0])
operatie= sumlist[1]
getal_b=(sumlist[2])
#reformat = "{:>9}\n{:>3} {:>2}\n -----".format(getal_a, operatie, getal_b)
getal_1=int(getal_a)
getal_2=int(getal_b)
if answer == False:
antwoord=''
if answer==True:
if operatie.strip() == '+':
antwoord=getal_1 + getal_2
elif operatie.strip() == '-':
antwoord=getal_1-getal_2
elif operatie.strip() == '*' or operatie.strip() == 'x':
antwoord=getal_1*getal_2
elif operatie.strip() == ':':
antwoord=getal_1/getal_2
reformat = "{:>9}\n{:>3} {:>2}\n -----\n {:>8}".format(getal_1, operatie, getal_2, antwoord)
return reformat
For calling the function: I use True when I also want the answer and False for when it has to be hidden.
practise=["32 + 698", "3801 - 2", "45 + 43", "123 + 49"]
print(arithmetic_arranger(practise, True))
My current and preferred result is like this, but it only seems to get the first element in the list. So to me it feels like I am very close, but can't seem to able to fix it without ruining my current results.
32
+ 698
-----
730
expected:
32 3801
+ 698 - 2
----- ----- etc
730 3799
functions take input and return output, the moment they return output they're job is done, they exit, and the interpreter proceeds with the rest of the program.
your function returns the reformat for the first member of the list and exits because your return statement is inside the loop
what you might consider is through each iteration of the loop you print the reformat, or if you want to store it you append the reformat to a list, and after you're done with the list, you return it outside of the loop.
and then you can loop through the returned list to print each member
def arithmetic_arranger(problems, answer=False):
reformat_list = [] #/////////////////////////////////////////////////
for som in problems:
sumlist = list(som.split())
getal_a=(sumlist[0])
operatie= sumlist[1]
getal_b=(sumlist[2])
#reformat = "{:>9}\n{:>3} {:>2}\n -----".format(getal_a, operatie, getal_b)
getal_1=int(getal_a)
getal_2=int(getal_b)
if answer == False:
antwoord=''
if answer==True:
if operatie.strip() == '+':
antwoord=getal_1 + getal_2
elif operatie.strip() == '-':
antwoord=getal_1-getal_2
elif operatie.strip() == '*' or operatie.strip() == 'x':
antwoord=getal_1*getal_2
elif operatie.strip() == ':':
antwoord=getal_1/getal_2
reformat = "{:>9}\n{:>3} {:>2}\n -----\n {:>8}".format(getal_1, operatie, getal_2, antwoord)
reformat_list.append(reformat) #///////////////////////////////
return reformat_list #///////////////////////////////// changed indentation
and then calling the function:
practise=["32 + 698", "3801 - 2", "45 + 43", "123 + 49"]
list_of_reformated_arithmetic= arithmetic_arranger(practise, True)
for i in range(len(list_of_reformated_arithmetic)):
print(something[i], end = "\n\n")
the result of this would be:
32
+ 698
-----
730
3801
- 2
-----
3799
45
+ 43
-----
88
123
+ 49
-----
172
printing them side by side is something more challenging and I don't know how to do it.
Try to work with the new f-stings. Makes you line easier to understand.
reformat = "{:>9}\n{:>3} {:>2}\n -----\n {:>8}".format(getal_1, operatie, getal_2, antwoord)
will become
reformat = f"{getal_1:>9}\n{operatie:>3} {getal_2:>2}\n -----\n {antwoord:>8}"
As you can see, you're outputting one addition. You would need to put it all in a huge reformat string which becomes confusing. Why not writing it into a csv file or parse it into a html?
Some small other hints:
if answer==True:
as your variable answer is a boolean already, it is enough to write
if answer: or if not answer: for the opposite.
No need to put your .split() into a list() as split returns a list already. And the result is striped, too. No need to .strip() neither.
Reconsider your code. Including the input.
def test(a):
results = []
add = lambda x,y: int(x) + int(y)
sub = lambda x,y: int(x) - int(y)
mul = lambda x,y: int(x) * int(y)
div = lambda x,y: int(x) / int(y)
for i in a:
x = i.split(" ")
if x[1] == '+':
v = add(x[0],x[2])
elif x[1] == '-':
v = sub(x[0],x[2])
elif x[1] == '*':
v = mul(x[0],x[2])
elif x[1] == '/':
v = div(x[0],x[2])
# formating output string
dashes = ""
if len(x[2]) > len(x[0]):
x[2], x[0] = (x[0], x[2])
dif = len(x[0]) - len(x[2])
for _ in range(dif):
x[2] = " " + x[2]
for _ in range(len(x[0])):
dashes += "-"
result = f" {x[0]}\n{x[1]} {x[2]}\n {dashes}\n {v}"
results.append(result)
return results
a = ["32 + 698", "3801 - 2", "45 + 43", "123 + 49"]
answers = test(a)
for answer in answers:
print(f"{answer}\n")
Output
698
+ 32
---
730
3801
- 2
----
3799
45
+ 43
--
88
123
+ 49
---
172

Is there any way of eliminating the nested loops to prevent time execution error

how to make the code more efficient by using list comprehension or using itertools in python because this program gives timeexecution error for large input datasets.
n=0
k=0
v='AEIOU'
for i in range(0,len(string)):
for j in range(i+1,len(string)+1):
a = string[i:j]
#print(a)
if (a[0] == 'A') or (a[0] == 'E') or (a[0] == 'I') or (a[0] == 'O') or (a[0] == 'U'):
n+= 1
else:
k+=1
if n>k:
print('Kevin'+' '+str(n))
elif n<k:
print('Stuart'+' '+str(k))
else:
print('Draw')
if __name__ == '__main__':
s = input()
minion_game(s)
Please check the question from this link
https://solution.programmingoneonone.com/2020/06/hackerrank-the-minion-game-problem-solution-python.html
I would appreciate it if you please explain the solution to the program as I am totally new to programming.
Basically what you have to do is:
def isVowel(c):
if c in ['A', 'E', 'I', 'O', 'U']:
return True
return False
Kevin=0
Stuart=0
for i in range(len(s)): #s is the input string
a=len(s)-i
if isVowel(s[i]):
Kevin+=a
else :
stuart+=a
#check who has scored more he is the winner.
This works because, suppose for a string BANANA:
B is consonant so, we have to include all the strings starting with B.
B,BA,BAN.... so we will have total of (n-indexOf(B)) numbers of strings = 6-0 = 6 pts for stuart
A is vowel,
all strings with A = n-indexOf(A)=6-1=5 so 5 pts for kevin.
You dont have to explicitly check the numbers of times current substrings appear in the string as you will be iterating over all of them.
for example,
total pts for Kevin =
pts for A at : Index(1) + Index(3) + Index(5)
total pts = (6-1) + (6-3) + (6-5) = 9

Problem with my small dictionary quiz. can someone explain this error please

d = {'Red': 1, 'Green': 2, 'Blue': 3}
for color_key, value in d.items():
userinput == (input(color_key))
if userinput == (d[color_key]):
print("correct")
else:
print("wrong")
Hi everyone, i am trying to simulate a quiz with this dictionary. I want to iterate through the dictionary and prompt the user for the questions (which is the key) (i.e what is the number for the colour: color_key). I then want the user to put the value for the key that corresponds to the right colour.
I am getting this error:
userinput == input(color_key)
NameError: name 'userinput' is not defined
Can anyone help me please.
Based on assumptions that you want to make kind of "memory" game with colors and integers, code proposal for your game would be something like this:
import random
d = {'Red': 1, 'Green': 2, 'Blue': 3}
while 1==1:
rand1 = random.choice(list(d))
user_input = input("Please guess the code of "+rand1+" color:\n")
try:
int(user_input)
if(int(user_input) == d[rand1]):
print("Color code is correct!")
else:
print("Color code is incorrect!")
except ValueError:
if(user_input.lower() == "quit"):
print("Program will terminate now")
else:
print("Invalid input provided.")
Take in consideration few things important for these kind of exercises:
Despite python is not strictly typizied language, you have to take
care of exceptions in the user input
"While 1==1" generates something
called "dead loop". Make sure you always have exit condition for this
one - In our case out here, that is keyword "quit" on the input.
In case of keyword "quit" on the input, it has to be validated for both
upper and lowercase
EDIT:
According to your newest update, I am providing you the example of simple 3-operations based game:
import random
def detect_string_operation(elem1, elem2, operator):
result = ""
if(operator == "+"):
result = str(elem1 + elem2)
elif(operator == "-"):
result = str(elem1 - elem2)
elif(operator == "*"):
result = str(elem1 * elem2)
elif(operator == "/"):
result = str(elem1/elem2)
return result
operators_list = ["+", "-", "*"]
while 1==1:
elem1 = random.randint(0, 10)
elem2 = random.randint(0, 10)
operator_index = random.randint(0, len(operators_list)-1)
result_operation = detect_string_operation(elem1, elem2, operators_list[operator_index])
user_input = input("Please calculate following: "+str(elem1)+str(operators_list[operator_index])+str(elem2)+"=")
try:
int(user_input)
if(user_input == result_operation):
print("Result is correct!")
else:
print("Result is incorrect!")
except ValueError:
if(user_input.lower() == "quit"):
print("Program will terminate now")
break
else:
print("Invalid input provided.")
Note that I didn't implement division for a reason: for division totally random choice of values is not an option, since we need an integer as a result of division. Algorithm for generating divisor and divider pair is quite simple to be implemented in iterative way, but it is out of scope of your initial question.

iteration over a sequence with an implicit type in Python 3.6

I am trying to iterate over a sequence of numbers. I have this:
from itertools import islice, count
handle = int(input("Please enter a number:")
handler = str(handle)
parameter = []
for i in handler:
parameter.append(i)
print(parameter) #This was for debugging
revised = parameter(count(1[2])) #I'm not sure I'm using the correct syntax here, the purpose is to make revised == parameter[0] and parameter[2]
Ultimately, what I am trying to achieve is to take a sequence of numbers or two, and compare them. For instance, if i[0] == i[1] + i [2] I want to return True, or for that matter if i[0] == i[1] - i[2]. I want the program to iterate over the entire sequence, checking for these types of associations, for instance, 23156 would == true because 2*3 = 6, 2+3 = 5, 5+1 = 6, 2+3+1=6; etc. It's strictly for my own purposes, just trying to make a toy.
When I utilize
revised = parameter(count(1[2])
I am getting an error that says builtins. TYPEERROR, type int is not subscriptable but I explicitly turned the integer input into a string.
Albeit unclear, what you have attempted to describe is hard to explain. It appears to be akin to a Running Total but with restrictions and of various operations, i.e. addition, subtraction and products.
Restrictions
The first two numbers are seeds
The following numbers must accumulate by some operation
The accumulations must progress contiguously
Code
import operator as op
import itertools as it
def accumulate(vals):
"""Return a set of results from prior, observed operations."""
adds = set(it.accumulate(vals)) # i[0] == i[1] + i[2]
muls = set(it.accumulate(vals, op.mul)) # i[0] == i[1] * i[2]
subs = {-x for x in it.accumulate(vals, func=op.sub)} # i[0] == i[1] - i[2]
#print(adds, muls, subs)
return adds | muls | subs
def rolling_acc(vals):
"""Return accumulations by sweeping all contiguous, windowed values."""
seen = set()
for i, _ in enumerate(vals):
window = vals[i:]
if len(window) >= 3:
seen |= accumulate(window)
return seen
def is_operable(vals):
"""Return `True` if rolling operations on contiguous elements will be seen."""
s = str(vals)
nums = [int(x) for x in s]
ahead = nums[2:]
accums = rolling_acc(nums)
#print(ahead, accums)
return len(set(ahead) & accums) == len(ahead)
Tests
assert is_operable(23156) == True
assert is_operable(21365) == False # {2,3} non-contiguous
assert is_operable(2136) == True
assert is_operable(11125) == True

Using Recursive Functions in Python to find Factors of a Given Number

Have tried searching for this, but can't find exactly what I'm looking for.
I want to make a function that will recursively find the factors of a number; for example, the factors of 12 are 1, 2, 3, 4, 6 & 12.
I can write this fairly simply using a for loop with an if statement:
#a function to find the factors of a given number
def print_factors(x):
print ("The factors of %s are:" % number)
for i in range(1, x + 1):
if number % i == 0: #if the number divided by i is zero, then i is a factor of that number
print (i)
number = int(input("Enter a number: "))
print (print_factors(number))
However, when I try to change it to a recursive function, I am getting just a loop of the "The factors of x are:" statement. This is what I currently have:
#uses recursive function to print all the letters of an integer
def print_factors(x): #function to print factors of the number with the argument n
print ("The factors of %s are:" % number)
while print_factors(x) != 0: #to break the recursion loop
for i in range(1,x + 1):
if x % i == 0:
print (i)
number = int(input("Enter a number: "))
print_factors(number)
The error must be coming in either when I am calling the function again, or to do with the while loop (as far as I understand, you need a while loop in a recursive function, in order to break it?)
There are quite many problems with your recursive approach. In fact its not recursive at all.
1) Your function doesn't return anything but your while loop has a comparision while print_factors(x) != 0:
2) Even if your function was returning a value, it would never get to the point of evaluating it and comparing due to the way you have coded.
You are constantly calling your function with the same parameter over and over which is why you are getting a loop of print statements.
In a recursive approach, you define a problem in terms of a simpler version of itself.
And you need a base case to break out of recursive function, not a while loop.
Here is a very naive recursive approach.
def factors(x,i):
if i==0:
return
if x%i == 0:
print(i)
return factors (x,i-1) #simpler version of the problem
factors(12,12)
I think we do using below method:
def findfactor(n):
factorizeDict
def factorize(acc, x):
if(n%x == 0 and n/x >= x):
if(n/x > x):
acc += [x, n//x]
return factorize(acc, x+1)
else:
acc += [x]
return acc
elif(n%x != 0):
return factorize(acc, x+1)
else:
return acc
return factorize(list(), 1)
def factors(x,i=None) :
if i is None :
print('the factors of %s are : ' %x)
print(x,end=' ')
i = int(x/2)
if i == 0 :
return
if x % i == 0 :
print(i,end=' ')
return factors(x,i-1)
num1 = int(input('enter number : '))
print(factors(num1))
Recursion is a functional heritage and so using it with functional style yields the best results. This means avoiding things like mutations, variable reassignments, and other side effects. That said, here's how I'd write factors -
def factors(n, m = 2):
if m >= n:
return
if n % m == 0:
yield m
yield from factors(n, m + 1)
print(list(factors(10))) # [2,5]
print(list(factors(24))) # [2,3,4,6,8,12]
print(list(factors(99))) # [3,9,11,33]
And here's prime_factors -
def prime_factors(n, m = 2):
if m > n:
return
elif n % m == 0:
yield m
yield from prime_factors(n // m, m)
else:
yield from prime_factors(n, m + 1)
print(list(prime_factors(10))) # [2,5]
print(list(prime_factors(24))) # [2,2,2,3]
print(list(prime_factors(99))) # [3,3,11]
def fact (n , a = 2):
if n <= a :
return n
elif n % a != 0 :
return fact(n , a + 1 )
elif n % a == 0:
return str(a) + f" * {str(fact(n / a , a ))}"
Here is another way. The 'x' is the number you want to find the factors of. The 'c = 1' is used as a counter, using it we'll divide your number by 1, then by 2, all the way up to and including your nubmer, and if the modular returns a 0, then we know that number is a factor, so we print it out.
def factors (x,c=1):
if c == x: return x
else:
if x%c == 0: print(c)
return factors(x,c+1)

Resources