using errors in conditions in python - python-3.x

I need help with my quadratic calculating program. I used an expression in an If, the expression will result in a math error obviously. But I don't want the code to break down when the error occurs instead, I want something else to happen.
import math
def quad(a, b, c):
# creating a variable for all the parts that make the expression
first_nu = int(a)
second_nu = int(b)
third_nu = int(c)
four = 4
two = 2
det = second_nu ** 2 - (four * (first_nu * third_nu))
if math.sqrt(det) == 0:
print(' the discriminant is 0 hence the quadratic has no real roots')
else:
# calculating the roots
root_det = math.sqrt(det)
def printing():
option1 = (-third_nu + root_det) / (two * first_nu)
option2 = (-third_nu - root_det) / (two * first_nu)
print(option1, option2)
if det < 0:
printing()
print('The roots are not real roots')
elif det == 0:
print('mathematical error in a situation where there is root of 0')
print('The roots has just one real root')
elif det > 0:
printing()
print('The roots has two real roots')
first_num = input("enter your first number of the quadratic")
second_num = input("enter your second number of the quadratic")
third_num = input("enter your third number of the quadratic")
quad(first_num, second_num, third_num)

Use try: on the code you want to test and put the rest of the code in except. I hope this will solve the issue. For more information about Python error handling here or check from w3schools
The try block lets you test a block of code for errors.
The except block lets you handle the error.

Related

I don't understand this rock paper scissors game

I found this code, and I'm having trouble understanding the lines 'user_hand = rps[int(user_input) - 1]' , 'com_hand = choice(rps)' , ' if rps_dict[user_hand]['strong'] == com_hand:' , 'print_result(**game_result)' , '
Why should I subtract 1 from user_input? Why put rps inside brackets next to choice? Why do you win 'if rps_dict[user_hand]['strong'] == com_hand ? Why if user_hand equal to com_hand? It doesnt make sense to me.. I know '**game_result' means it's a kwark, but I dont know why I need to declare it as a kwarg. I'm sorry if these questions seem stupid, but I'm frustrated.
from random import choice
rps = ('rock', 'paper', 'scissors')
rps_dict = {
'rock': {'strong': 'scissors', 'weak': 'paper'},
'paper': {'strong': 'rock', 'weak': 'scissors'},
'scissors': {'strong': 'paper', 'weak': 'rock'}
}
def print_result(user_score, com_score, win, lose, tie):
print('Result:', end=' ')
if user_score > com_score:
print('You win!')
elif user_score < com_score:
print('You lose...')
else:
print('Draw.')
print('--------------------')
# Print scores
print(f'Your score: {user_score}')
print(f'Computer score: {com_score}')
print('--------------------')
# Print statistics
print(f'Win: {win}')
print(f'Lose: {lose}')
print(f'Tie: {tie}')
def play(rounds):
game_result = {
'user_score': 0,
'com_score': 0,
'win': 0,
'lose': 0,
'tie': 0
}
while rounds > 0:
user_input = input(
'Enter your choice (1: Rock, 2: Paper, 3: Scissors, 0: Quit): ')
# Check whether the input is in the options
if user_input in ('1', '2', '3'):
rounds -= 1
user_hand = rps[int(user_input) - 1]
com_hand = choice(rps)
# user_hand is strong against com_hand
if rps_dict[user_hand]['strong'] == com_hand:
game_result['user_score'] += 1
game_result['win'] += 1
result = 'You win!'
# user_hand is weak against com_hand
elif rps_dict[user_hand]['weak'] == com_hand:
game_result['com_score'] += 1
game_result['lose'] += 1
result = 'You lose...'
# Tie
else:
game_result['tie'] += 1
result = 'Tie.'
print(
f'You -> {user_hand}. Computer -> {com_hand}. {result}')
elif user_input == '0':
break
else:
print('Invalid input!')
print()
print_result(**game_result)
if __name__ == "__main__":
print('Welcome to Rock-Paper-Scissors Game!')
try:
rounds = int(input('How many rounds you want to play? '))
play(rounds)
except ValueError:
print('Please input a valid number!')
This is an interesting question, and I'll do my best to discuss the lines that you said you have trouble with:
user_hand = rps[int(user_input) - 1]
The user_hand variable is used to store the choice the user inputs. user_input is the text the user directley entered. This will be saved as a string, so the code stransforms it into an integer with the int class. Next, it subtracts one from the user input (computers count from zero rather than 1). Then, it grabs the element from the list that has that index. For example, if I entered one, it would grab the list item at index 0 ("rock").
com_hand = choice(rps)
This line here is used to gather the computer's choice. As you can see from the first line, the choice function from the random module is imported directly. This allows you to use the function without specifying the module it came from. The choice function selects a random item from the specified list, which is the same rps list as before.
if rps_dict[user_hand]['strong'] == com_hand:
The if statement here gathers data from the rps_dict and compares it to the computer's hand. The rps_dict is a dictionary that contains data on which hand beats or loses to another. To translate the if statement into simpler english, it means if the hand the user's hand would beat (which can be found with rps_dict[user_hand]["strong"]), is the computer's hand, the user will win. In addition, to avoid confusion, the == operator check's for equality, and doesn't assign the variable to com_hand.
print_result(**game_result)
Here you said that you don't understand why the parameters are passed in this way. You don't really need to do it in this format, but the person who created the script decided to (possibly as it is simpler to read).
Thank you, and if you have any other questions, please comment and I'll do my best to answer them!

How to fix this loop for special cases in Python

So I got assigned a homework where I have to do the convexHull problem by brute force (this is to then later compare the complexity vs the normal complexHull), and I have this code:
def determineSideLocation(A,B,P):
#Takes point A and B and creates a vector (A ---> B), direction sensitive
d = ((P[0] - A[0])*(B[1] - A[1])) - ((P[1] - A[1])*(B[0] - A[0]))
if d < 0:
#To the left of AB
return -1
elif d > 0:
#To the right of AB
return 1
elif d == 0:
#On AB
return 0
And now I determine if all the points I want to compare are on one side or not:
def isAllPointsOnOneSide(vector, pointList):
pointSideList = []
print("vector: " + str(vector))
print("pointList: " + str(pointList))
for i in pointList:
pointSideList.append(determineSideLocation(vector[0], vector[1], i))
print("pointSideList: " + str(pointSideList))
for j in range(0, len(pointSideList) - 1):
if pointSideList[j] == 0:
continue
elif pointSideList[j+1] == 0:
#2 options:
#1. pointSideList[j+1] is at the end of the list (j+1 = len(pointSideList) - 1)
#2. pointSideList[j+1] is not at the end of the list
if j+1 == (len(pointSideList) - 1):
continue
else:
if pointSideList[j+2] == 0:
if j+2 == (len(pointSideList) - 1):
continue
else:
if pointSideList[j] != pointSideList[j+3]:
return False
else:
continue
elif pointSideList[j] != pointSideList[j+2]:
return False
else:
continue
elif pointSideList[j] != pointSideList[j+1]:
return False
else:
continue
return True
There is the convexHull function but its not where the problem lies. The thing is: in the isAllPointsOnOneSide function, it takes the list of points and makes a list of values relative to the vector, which can only be 1 (to the right), -1 (to the left) and 0 (in the vector).
I got an ankward case where the relative values were this: [-1,0,0,0,0] and the function breaks itself and gives a False value despite being True (all points are on the vector or on one side). I know its in the exception part, where it tries to skip comparing the current value to a 0, but I know its not ideal to keep writing more exceptions to that part.
How can I fix it to avoid the cases where the function breaks? Where it has to compare with 0 at the end of the list
#Heike gave me the answer, and it was rather simple :P
def isAllPointsOnOneSide(vector, pointList):
pointSideList = []
for i in pointList:
pointSideList.append(determineSideLocation(vector[0], vector[1], i))
minValue = min(pointSideList)
maxValue = max(pointSideList)
#If max - min is higher than 1, its a False result.
if maxValue - minValue > 1:
return False
else:
return True
I'm sorry, and after all it was a rather simple problem, but I have been on this for several hours now (brute forcing the convexhull) and it frustated me.
Thanks to Heike again

Dynamic Programming Primitive calculator code optimization

I am currently doing coursera course on algorithms. I have successfully completed this assignment. All test cases passed. My code looks messy and I want to know if there is any thing availiable in Python which can help run my code faster. Thanks
The problem statement is as follows: You are given a primitive calculator that can perform the following three operations with
the current number 𝑥: multiply 𝑥 by 2, multiply 𝑥 by 3, or add 1 to 𝑥. Your goal is given a
positive integer 𝑛, find the minimum number of operations needed to obtain the number 𝑛
starting from the number 1.
# Uses python3
import sys
def optimal_sequence(m):
a=[0,0]
for i in range(2,m+1):
if i%3==0 and i%2==0:
a.append(min(a[i//2],a[i//3],a[i-1])+1)
elif i%3==0:
a.append(min(a[i//3],a[i-1])+1)
elif i%2==0:
a.append(min(a[i//2],a[i-1])+1)
else:
a.append((a[i-1])+1)
return backtrack(a,m)
def backtrack(a,m):
result=[]
result.append(m)
current = m
for i in range(a[-1],0,-1):
if current%3==0 and a[current//3]==(i-1):
current=current//3
result.append(current)
elif current%2==0 and a[current//2]==(i-1):
current = current//2
result.append(current)
elif a[current-1]==(i-1):
current = current-1
result.append(current)
return result
n = int(input())
if n == 1:
print(0)
print(1)
sys.exit(0)
a= (optimal_sequence(n))
print(len(a)-1)
for x in reversed(a):
print(x,end=" ")
I would use a breadth first search for number 1 starting from number n. Keep track of the numbers that were visited, so that the search backtracks on already visited numbers. For visited numbers remember which is the number you "came from" to reach it, i.e. the next number in the shortest path to n.
In my tests this code runs faster than yours:
from collections import deque
def findOperations(n):
# Perform a BFS
successor = {} # map number to next number in shortest path
queue = deque() # queue with number pairs (curr, next)
queue.append((n,None)) # start at n
while True:
curr, succ = queue.popleft()
if not curr in successor:
successor[curr] = succ
if curr == 1:
break
if curr%3 == 0: queue.append((curr//3, curr))
if curr%2 == 0: queue.append((curr//2, curr))
queue.append((curr-1, curr))
# Create list from successor chain
result = []
i = 1
while i:
result.append(i)
i = successor[i]
return result
Call this function with argument n:
findOperations(n)
It returns a list.

input of python calculator

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.

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

Resources