As a Beginner, I was trying to make 1-line Calculator using Python... And I come to this.
I converted the user input into list and then used the list elements to get the result.
For example in case if multiplication I took the elements before the sign, combined them and then the elements after the sign and combined them.Then Multiply the together.
question = list(input("Enter Your Question: "))
def convert(list):
s = [str(i) for i in list]
combined = int("".join(s))
list = combined
return(combined)
multiply = "*"
add = "+"
substract = "-"
divide = "/"
if multiply in question:
for multiply in question:
position1 = question.index("*")
before_num = question[0: int(position1)]
aft = len(question)
after_num = question[int(position1) + 1: int(aft)]
num_before = convert(before_num)
num_after = convert(after_num)
print(int(num_before) * int(num_after))
break
elif add in question:
for add in question:
position1 = question.index("+")
before_num = question[0: int(position1)]
aft = len(question)
after_num = question[int(position1) + 1: int(aft)]
num_before = convert(before_num)
num_after = convert(after_num)
print(int(num_before) + int(num_after))
break
elif substract in question:
for substract in question:
position1 = question.index("-")
before_num = question[0: int(position1)]
aft = len(question)
after_num = question[int(position1) + 1: int(aft)]
num_before = convert(before_num)
num_after = convert(after_num)
print(int(num_before) - int(num_after))
break
elif divide in question:
for divide in question:
position1 = question.index("/")
before_num = question[0: int(position1)]
aft = len(question)
after_num = question[int(position1) + 1: int(aft)]
num_before = convert(before_num)
num_after = convert(after_num)
print(int(num_before) / int(num_after))
break
else:
print("Check Your Question Again")
end_program_ans = input("Press Enter to continue")
This Works Perfect but is there a simpler way.
read_data = input("Enter Your Question: ")
if "*" in read_data:
data1,data2 = read_data.split("*")
print(float(data1)*float(data2))
elif "+" in read_data:
data1,data2 = read_data.split("+")
print(float(data1)+float(data2))
elif "-" in read_data:
data1,data2 = read_data.split("-")
print(float(data1)-float(data2))
elif "/" in read_data:
data1,data2 = read_data.split("/")
print(float(data1)/float(data2))
else:
print("Please Enter Proper data")
Related
I am trying to make a calculator that doesn't use eval() and take the whole equation as a string. Also I can't use any libraries, modules, etc. I've managed to make something but I can't figure out how to make it to first do the multiplication and division and then the rest.
It doesn't give me an error but it does this:
4 + 4 = 8
4 + 4 * 4 = 20
4 + 4 * 4 + 4 = 4
Edit: So I found where the problem was, but it still doesn't function right. The problem was that the code doesn't even reach the part where it finds the "*". I'll mark with an arrow where it doesn't reach it.
Here is the code and thanks in advance:
print("Calculator")
# All the numbers
def numbers(num):
return(
num == "0"
or num == "1"
or num == "2"
or num == "3"
or num == "4"
or num == "5"
or num == "6"
or num == "7"
or num == "8"
or num == "9"
)
# All the operators
def operator(oprt):
return(
oprt == "+"
or oprt == "-"
or oprt == "*"
or oprt == "/"
)
# Removes all the spaces
def remove_spaces(string):
string = string.replace(" ", "")
return string
# Does the math between two numbers
def operation(string, num1, num2):
if string == "+":
return num1 + num2
if string == "-":
return num1 - num2
if string == "*":
return num1 * num2
if string == "/":
return num1 / num2
# Tests how long the number is
def test_number(numstr):
n = 0
num = ""
try:
while numbers(numstr[n]):
num += numstr[n]
n += 1
except:
pass
return(int(num), n)
# Solves the equation
def eval_equation(eq):
negative = False
# Removes the spaces
eq = remove_spaces(eq)
while True:
try:
# Checks if the first number is negative
if eq[0] == "-":
negative = True
eq = eq[1:]
# Solves the multiplication first
i = 0
eqTemp = ""
if "*" in eq:
try:
while i < len(eq):
if eq[i] == "+" or eq[i] == "-" or eq[i] == "/":
eqTemp = eqTemp + eq[:i + 1]
print(f"eqTemp = {eqTemp}")
eq = eq[i + 1:]
print(f"eq = {eq}")
elif eq[i] == "*": # <-------this is the problem----
break
print(f"eqTemp = {eqTemp}")
print(f"eq = {eq}")
i += 1
except:
i = 0
# Checks the lenght of the number
number1 = test_number(eq)[0]
# Returns the "-" in the negative number
if negative == True:
number1 = -number1
negative = False
# Removes the first number from the string to continue with the next
endNumber1 = test_number(eq)[1]
eq = eq[endNumber1:]
# Checks for any more numbers
if eq == "":
return number1
# This is the operator sign
op = eq[0]
eq = eq[1:]
# Repeats the same process with the other number
number2 = test_number(eq)[0]
endNumber2 = test_number(eq)[1]
result = operation(op, number1, number2)
# Takes the result and passes it as to the first number along with the rest of the equation
number1 = result
eq = str(number1) + eq[endNumber2:]
eq = eqTemp + eq
except Exception as error:
print(error)
break
return number1
# Main function
if __name__ == "__main__":
while True:
equation = input(": ")
print(eval_equation(equation))
Edit: Sorry, gotta get back to work, wasn't able to figure out your exact problem. I would suggest starting over on the eval_equation function as it's quite messy, and will be prone to bugs if you continue adding to it.
Unrelated to the actual question, here's an example of how you might improve a couple of functions a bit. Note the use of in, the docstrings, as well as a more clear function name.
def is_num(num):
"""Determine if the character is a number."""
return num in '0123456789'
def is_oprt(oprt):
"""Determine if the character is an operator."""
return oprt in '+-*/'
Your test_number function also can be optimised a little by iterating over the string rather than using while with try/except. It's a bit more personal preference but this is how I'd do it:
def get_num(numstr):
"""Gets the number at the start of a string."""
num = []
for i, c in enumerate(numstr):
if not is_num(c):
break
num.append(c)
try:
return int(''.join(num)), i + 1
except ValueError:
return 0, 0
One other syntax suggestion:
number2 = test_number(eq)[0]
endNumber2 = test_number(eq)[1]
Is the same as:
number2, endNumber2 = test_number(eq)
So I fixed it. I'm not sure how... but I fixed it. I just need to figure out how to add variables to the equation now :) . Here is the code and thanks to everybody who gave ideas:
print("Calculator")
# All the numbers
def numbers(num):
return num in {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
# All the operators
def operator(oprt):
return oprt in {"+", "-", "*", "/"}
# Removes all the spaces
def remove_spaces(string):
string = string.replace(" ", "")
return string
# Does the math between two numbers
def operation(string, num1, num2):
if string == "+":
return num1 + num2
if string == "-":
return num1 - num2
if string == "*":
return num1 * num2
if string == "/":
return int(num1 / num2)
# Tests how long the number is
def test_number(numstr):
n = 0
num = ""
try:
while numbers(numstr[n]):
num += numstr[n]
n += 1
except:
pass
return(int(num), n)
# Solves the equation
def eval_equation(eq):
negative = False
# Removes the spaces
eq = remove_spaces(eq)
while True:
try:
# Checks if the first number is negative
if eq[0] == "-":
negative = True
eq = eq[1:]
# Solves the multiplication first
i = 0
eqTemp = ""
if "*" in eq:
try:
while i < len(eq):
if eq[i] in {"+", "-", "/"}:
eqTemp = eqTemp + eq[:i + 1]
#print(f"eqTemp = {eqTemp}")
eq = eq[i + 1:]
#print(f"eq = {eq}")
pass
if numbers(eq[i]) == True:
pass
if eq[i] == "*":
break
i += 1
except IndexError:
i = 0
# Solves the division first
i = 0
eqTempDiv = ""
if "/" in eq:
try:
while i < len(eq):
if eq[i] in {"+", "-", "*"}:
eqTempDiv = eqTempDiv + eq[:i + 1]
#print(f"eqTemp = {eqTemp}")
eq = eq[i + 1:]
#print(f"eq = {eq}")
pass
if numbers(eq[i]) == True:
pass
if eq[i] == "/":
break
i += 1
except IndexError:
i = 0
# Checks the lenght of the number
number1 = test_number(eq)[0]
# Returns the "-" in the negative number
if negative == True:
number1 = -number1
negative = False
# Removes the first number from the string to continue with the next
endNumber1 = test_number(eq)[1]
eq = eq[endNumber1:]
# Checks for any more numbers
if eqTempDiv == "":
if eqTemp == "":
if eq == "":
return number1
# This is the operator sign
op = eq[0]
eq = eq[1:]
# Repeats the same process with the other number
number2 = test_number(eq)[0]
endNumber2 = test_number(eq)[1]
result = operation(op, number1, number2)
# Takes the result and passes it as to the first number along with the rest of the equation
number1 = result
eq = str(number1) + eq[endNumber2:]
eq = eqTemp + eqTempDiv + eq
#print(f"eqTemp final = {eqTemp}")
#print(f"eq final = {eq}")
except Exception as error:
print(error)
break
return number1
# Main function
if __name__ == "__main__":
while True:
equation = input(": ")
print(eval_equation(equation))
I am a beginner in Python and I think I need some help with my program. Any kind of help or advice would be appreciated:)
You can see the program below, when I run it it gets stuck on the part of comparing the random ticket with the winning ticket(win_combination).
from random import choice
#Winning ticket
win_combination = input("Enter the winning combination of 4 numbers(1-digit-numbers): ")
while len(win_combination) != 4:
if len(win_combination) > 4:
win_combination = input("Reenter a shorter combination(4 one-digit-numbers): ")
elif len(win_combination) < 4:
win_combination = input("Reenter a longer combination(4 one-digit-numbers): ")
print(f"Winning combination is {win_combination}.")
#Specifying range of numbers to choose from
range = range(0, 10)
#Making a fake comparison-ticket to start of the loop
random_ticket = [0, 0]
random_ticket_string = f"{random_ticket[0]}{random_ticket[1]}{random_ticket[2]}{random_ticket[3]}"
#Params for the loop
n_tries = 0
n_guesses = 1
while random_ticket_string != win_combination:
while n_tries > 4:
random_ticket.clear()
number = choice(range)
random_ticket.append(number)
n_tries += 1
n_guesses += 1
random_ticket_string = f"{random_ticket[0]}{random_ticket[1]}"
if random_ticket_string == win_combination:
chance_to_win = f"{(1 / n_guesses) * 100}%"
print("Estimated percent to win is " + chance_to_win + ", it took " + f"{n_guesses} to match the winning combination.")
else:
n_tries = 0
As a computer science student we were given an assignment to do binary search in python. I don't know what's wrong with my code everything seems just fine
when the searched item is in the middle everything works just fine but whenever I enter a different index position it gets stuck in the while loop.
def binary_search():
ordered_list = [0,1,2,3,4,5,6,7,8,9]
lower_bound = 0
upper_bound = 10
index = int((lower_bound + upper_bound) / 2)
item_f = int(input("please enter the number you want to find (1-10): "))
t = True
while t:
if ordered_list[index] == item_f:
print(f"number {item_f} is found at index position {index}")
t = False
elif item_f > ordered_list[index]:
lower_bound = index + 1
elif item_f < ordered_list[index]:
lower_bound = index - 1
if t == False:
print("number found")
else:
pass
binary_search()
I have added 1 line of code, please check it should working
def binary_search()
ordered_list = [0,1,2,3,4,5,6,7,8,9]
lower_bound = 0
upper_bound = 10
index = int((lower_bound + upper_bound) / 2)
item_f = int(input("please enter the number you want to find (1-10): "))
t = True
while t:
if ordered_list[index] == item_f:
print(f"number {item_f} is found at index position {index}")
t = False
elif item_f > ordered_list[index]:
lower_bound = index + 1
elif item_f < ordered_list[index]:
upper_bound = index - 1#Edit line
index = int((lower_bound + upper_bound) / 2) #Added line
if t == False:
print("number found")
else:
pass
binary_search()
Hi having trouble trying to fix an error that occurs when I put just a '#' or rogue value in case someone doesn't want to add any data. I don't know how to fix it and I'm hoping to just end the code just like I would with data.
#Gets Data Input
def getData():
fullList = []
inputText = checkInput("Enter the students first name, last name, first mark, and second mark (# to exit): ")
while inputText != "#":
nameList = []
nameList2 = []
nameList = inputText.split()
nameList2.extend((nameList[0],nameList[1]))
nameList2.append((float(nameList[2]) + float(nameList [3]))/2)
fullList.append(nameList2)
inputText = checkInput("Enter the students first name, last name, first mark, and second mark (# to exit): ")
print("\n")
return fullList
#Calculates Group Average
def calc1(fullList):
total = 0
for x in fullList:
total = total + x[2]
groupAverage = total/(len(fullList))
return(groupAverage)
#Finds Highest Average
def calc2(fullList):
HighestAverage = 0
nameHighAverage = ""
for x in fullList:
if x[2] > HighestAverage:
HighestAverage = x[2]
nameHighAverage = x[0] + " " + x[1]
return (HighestAverage, nameHighAverage)
#Returns Marks above average
def results1(groupAverage,r1FullList):
r1FullList.sort()
print("List of students with their final mark above the group average")
print("--------------------------------------------------------------")
print("{:<20} {:<12}".format("Name","Mark"))
for x in r1FullList:
if x[2] > groupAverage:
name = x[0] + " " + x[1]
print("{:<20} {:<12.2f}".format(name,x[2]))
def calc3(x):
if x[2] >= 80:
return 'A'
elif x[2] >= 65:
return 'B'
elif x[2] >= 50:
return 'C'
elif x[2] < 50:
return 'D'
else:
return 'ERROR'
def results2(fullList):
print("List of Studens with their Final Marks and Grades")
print("-------------------------------------------------")
print("{:<20} {:<12} {:<12}".format("Name","Mark","Grade"))
for x in fullList:
grade = calc3(x)
name = x[0] + " " + x[1]
print("{:<20} {:<12.2f} {:<12}".format(name,x[2],grade))
#Checks for boundary and invalid data
def checkInput(question):
while True:
textInput = input(question)
if textInput == "#":
return textInput
splitList = textInput.split()
if len(splitList) !=4:
print("Invalid Format, Please Try Again")
continue
try:
a = float(splitList[2])
a = float(splitList[3])
if float(splitList[2]) < 0 or float(splitList[2]) > 100:
print("Invalid Format, Please Try Again")
continue
if float(splitList[3]) < 0 or float(splitList[3]) > 100:
print("Invalid Format, Please Try Again")
continue
return(textInput)
except ValueError:
print("Invalid Input, Please Try Again")
continue
#Main Program
#Input Data
fullList = getData()
#Process Data
groupAverage = calc1(fullList)
HighestAverage, nameHighAverage = calc2(fullList)
#Display Results
print("The group average was %.2f" % groupAverage)
print("The student with the highest mark was: %s %0.2f" %(nameHighAverage,HighestAverage))
results1(groupAverage,fullList)
print("\n")
results2(fullList)
Your program works OK for me, unless you enter a # as the first entry, in which case fullList is [] and has length 0. Hence, DivisionByZero at this line: groupAverage = total/(len(fullList)).
You could modify your code to check for this and exit:
import sys
fullList = getData()
if not fullList:
print('No Data!')
sys.exit()
I am working on a Hangman game, but I am having trouble replacing the dashes with the guessed letter. The new string just adds on new dashes instead of replacing the dashes with the guessed letter.
I would really appreciate it if anyone could help.
import random
import math
import os
game = 0
points = 4
original = ["++12345","+*2222","*+33333","**444"]
plusortimes = ["+","*"]
numbers = ["1","2","3"]
#FUNCTIONS
def firstPart():
print "Welcome to the Numeric-Hangman game!"
def example():
result = ""
ori = random.choice(original)
for i in range(2,len(ori)):
if i % 2 == 0:
result = result + ori[i] + ori[0]
else:
result = result + ori[i] + ori[1]
return ori
# def actualGame(length):
#TOP LEVEL
firstPart()
play = raw_input("Do you want to play ? Y - yes, N - no: ")
while (play == "Y" and (points >= 2)):
game = game + 1
points = points
print "Playing game #: ",game
print "Your points so far are: ",points
limit = input("Maximum wrong guesses you want to have allowed? ")
length = input("Maximum length you want for the formulas (including symbols) (must be >= 5)? ")
result = "" #TRACE
ori = random.choice(original)
for i in range(2,len(ori)):
if i % 2 == 0:
result = result + ori[i] + ori[0]
else:
result = result + ori[i] + ori[1]
test = eval(result[:-1])
v = random.choice(plusortimes) #start of randomly generated formula
va = random.choice(plusortimes)
formula = ""
while (len(formula) <= (length - 3)):
formula = formula + random.choice(numbers)
formula2 = str(v + va + formula)
kind = ""
for i in range(2,len(formula2)):
if i % 2 == 0:
kind = kind + formula2[i] + formula2[0]
else:
kind = kind + formula2[i] + formula2[1]
formula3 = eval(kind[:-1])
partial_fmla = "------"
print " (JUST TO TRACE, the program invented the formula: )" ,ori
print " (JUST TO TRACE, the program evaluated the formula: )",test
print "The formula you will have to guess has",length,"symbols: ",partial_fmla
print "You can use digits 1 to 3 and symbols + *"
guess = raw_input("Please enter an operation symbol or digit: ")
a = 0
new = ""
while a<limit:
for i in range(len(formula2)):
if (formula2[i] == partial_fmla[i]):
new = new + partial_fmla[i]
elif (formula2[i] == guess):
new[i] = guess
else:
new[i] =new + "-"
a = a+1
print new
guess = raw_input("Please enter an operation symbol or digit: ")
play = raw_input("Do you want to play ? Y - yes, N - no: ")
The following block seems problematic:
elif (formula2[i] == guess):
new[i] = guess
else:
new[i] =new + "-"
Python does not allow modification of characters within strings, as they are immutable (cannot be changed). Try appending the desired character to your new string instead. For example:
elif formula2[i] == guess:
new += guess
else:
new += '-'
Finally, you should put the definition of new inside the loop directly under, as you want to regenerate it after each guess.