How to ask a user to input a function in python 3 - python

i´m trying to make a program to find the limit of a function, however, i can´t find any effective way to ask the user to input a function, or convert any kind of user input into one, the best way i found was using:
f= lambda n: eval(input("")
however, using this method, everytime i run into a loop, the user will be asked to input the function over and over, which in this case makes it unusable. I greetly apreciate any feedback
Sorry if the post or my english is bad, i apoligize for it, i am new here and not a native english speaker, if it helps here is the complete code (with everything in french)
from lycee import *
n= int
# Rang actuel
f= lambda n: eval(input("veuillez introduire la fonction avec pour variable n"))
# Fonction introduite par l´usager
m= int(input("veuillez introduire la puisance de la valeur aussi grande, petite, ou proche que l´on veut"))
# Valeur max
l= int(input("veuillez introduire une limite eventuelle de la suite"))
d= int
# Prend une valeur selon la limite trouvé ou non
p= int(input("veuillez intoduire le pas"))
# Pas introduit par l´usager
x=int
# Valeur actuelle de la suite
n=1
d=0
x=0
#La limite est elle −∞?
while l>-10^m and n<10^15+1:
n=n+p
x=f(n)
if n==10^15+1:
print ("Après le calcul d’un billiard de termes, la suite ne semble pas tendre vers −∞")
else:
d=1
n=1
x=0
#La limite est elle +∞?
while l<10^m and n<10^15+1:
n=n+p
x=f(n)
if n==10^15+1:
print ("Après le calcul d’un billiard de termes, la suite ne semble pas tendre vers +∞")
else:
d=2
n=1
x=0
#La limite est elle l?
if l>=0:
while x+l>10^-m and n<10^15+1:
n=n+p
x=f(n)
if n==10^15+1:
print ("Après le calcul d’un billiard de termes, la suite ne semble pas tendre vers l")
else:
d=3
else:
while x-l>10^-m and n<10^15+1:
n=n+p
x=f(n)
if n==10^15+1:
print ("Après le calcul d’un billiard de termes, la suite ne semble pas tendre vers l")
else:
d=3
if d==1:
print ("Après le calcul d’un billiard de termes, la suite semble avoir pour limite −∞")
else:
if d==2:
print ("Après le calcul d’un billiard de termes, la suite semble avoir pour limite +∞")
else:
if d==3:
print ("Après le calcul d’un billiard de termes, la suite semble avoir pour limitel")
else:
print ("Après le calcul d’un billiard de termes, la suite semble ne pas avoir de limite")

You can use the compile function to compile the user's input into an AST object so that your lambda function can eval the AST object instead of asking the user for input again:
func = compile(input("veuillez introduire la fonction avec pour variable n"), '<input>', 'eval')
f = lambda n: eval(func)

Related

SOLVED: My Python code returns None instead of a list

the value which is supposed to be returned is valid!!!!
The print(self.affichage) just above shows that it works!!!!
Why does it not return it ??? (the very last return)
so this code is a Polish Reverse Notation calculus :
you read it from left to right, the numbers are stored in a pile, and the operands apply to the two upper numbers of the pile (the two most recent)
# here comes the actual code :
class Calculatrice():
# création de la mémoire de la calculatrice
def __init__(self):
self.pile = []
self.affichage = []
def traitement(self,element):
# opérateur
if element in "+-*/":
# on vérifie qu'il y a les nombres suffisants pour effectuer ces opérations
if len(self.pile) > 1:
# addition
if element == "+":
resultat = self.pile[-2] + self.pile[-1]
# soustraction
elif element == "-":
resultat = self.pile[-2] - self.pile[-1]
# multiplication
elif element == "*":
resultat = self.pile[-2] * self.pile[-1]
# division
elif element == "/":
resultat = self.pile[-2] / self.pile[-1]
# ATTENTION : dans les cas de ces opérations, seuls deux nombres sont nécessaire,
# donc on peut généraliser les deux actions suivantes, mais ça ne devrait pas forcément être le cas.
# on dépile les nombres traités
del self.pile[len(self.pile)-2:]
# on empile le résultat
self.pile.append(resultat)
return True
elif len(self.pile) == 1:
if element == "*":
# erreur : pas assez de nombres pour effectuer une multiplication
print("Erreur 03 : Pas assez de nombres pour effectuer la multiplication.")
return False
elif element == "/":
# erreur : pas assez de nombres pour effectuer une division
print("Erreur 04 : Pas assez de nombres pour effectuer la division.")
return False
# si c'est une addition, on considère qu'on ajoute le nombre à 0, donc la pile ne change pas
else:
# si c'est une soustraction, on empile son opposé à la place du nombre
if element == "-":
self.pile[-1] = (self.pile[-1] * (-1))
return True
# la taille de la pile = 0, c-à-d. qu'aucun nombre n'a été stocké au préalable
else:
print("Erreur 02 : Pas assez de nombres pour effectuer une opération.")
return False
else:
for car in element:
if car not in "0123456789.":
# erreur : caractère non reconnu
print("Erreur 01 : La commande n'a pas été comprise.")
return False
# si on est arrivé jusqu'ici, on va considérer que c'est bon et que c'est un nombre
# on empile l'élément
self.pile.append(float(element))
return True
def npi(self,chaine):
# si la récurrence n'est pas à sa limite
if len(chaine) != 0:
# on vérifie qu'il y a des espaces
if " " in chaine:
# on parcourt la chaine jusqu'à l'espace suivant
i = 0
temp = ""
while chaine[i] != " ":
temp = temp+chaine[i]
i += 1
# on a fini d'extraire cet élément : on le traite.
traitement = self.traitement(temp)
# si il y a eu des erreurs de traitement : on arrête tout.
if traitement == False:
return ["Erreur"]
else:
# on continue de traiter le reste de la chaîne
self.npi(chaine[i+1:])
else:
# il n'y a pas d'espace, donc il n'y a qu'un seul élément : on le traite.
traitement = self.traitement(chaine)
# si il y a eu des erreurs de traitement : on arrête tout.
if traitement == False:
return ["Erreur"]
# on a fini, on sort du if
self.npi("")
else:
# la chaîne est vide : tous les éléments ont été traités. On renvoie le résultat final et on réinitialise la pile.
self.affichage = self.pile.pop()
print(self.affichage)
return self.affichage
c = Calculatrice()
print(c.npi("2 3 + 4 -"))
# doit retourner 1
You are returning a value only in the base-case. For the recursive cases in npi you are not returning anything (i.e. returning None). The printed value comes from inside a recursive call, the return value from that call is lost once you go back to the calling method.
You need to add return statements for the recursive cases in npi
def npi(self,chaine):
# si la récurrence n'est pas à sa limite
if len(chaine) != 0:
# on vérifie qu'il y a des espaces
if " " in chaine:
# on parcourt la chaine jusqu'à l'espace suivant
i = 0
temp = ""
while chaine[i] != " ":
temp = temp+chaine[i]
i += 1
# on a fini d'extraire cet élément : on le traite.
traitement = self.traitement(temp)
# si il y a eu des erreurs de traitement : on arrête tout.
if traitement == False:
return ["Erreur"]
else:
# on continue de traiter le reste de la chaîne
return self.npi(chaine[i+1:]) # HERE
else:
# il n'y a pas d'espace, donc il n'y a qu'un seul élément : on le traite.
traitement = self.traitement(chaine)
# si il y a eu des erreurs de traitement : on arrête tout.
if traitement == False:
return ["Erreur"]
# on a fini, on sort du if
return self.npi("") # HERE
else:
# la chaîne est vide : tous les éléments ont été traités. On renvoie le résultat final et on réinitialise la pile.
self.affichage = self.pile.pop()
print(self.affichage)
return self.affichage
You call npi recursively. In the last call the traitement variable is True.
But your code looks like the following:
if traitement == False:
return ["Erreur"]
else:
# on continue de traiter le reste de la chaîne
self.npi(chaine[i+1:])
and exits the function without returning anything. Therefore, you get the None object, when trying to print.

how to access a local variable in another function

chose=random.choice(words)
print(chose)
i=0
while i<chance:#ici nous crayons une boucle qui va nous permettre de repeter une instruction 8 fois
guess=input("\n Devinez une lettre qui peut se trouver dans ce truc.")
print("\n")
final_word=""
point=0
if (guess==chose and i<chance):#si cette instruction st remplie on a gagner
point=chance-(i)
print("Vous vennez de gagner\n")
print(point)
break
elif(guess!=chose):
for character in chose:
if character in guess:
final_word +=character
else:
final_word +="*"
print(final_word)
i+=1
#cette fonction nous aide à mettre sur place le nom et le score du jouer
def login():
user=input("Quel est votre nom ? ")
user=user.capitalize()
print("Bonjour monsieur {} et bienvenu dans le jeu.".format(user))
score={
user:point
}
with open('donee','wb') as db:
my_pickler=pickle.Pickler(db)
my_pickler.dump(score)
up there you can see my code, I want the result of my variable 'point' in the function traitement to be desplayed in the dictionary score;
how can i do that?
You don't. Local variables are by definition exactly that. You could use global values, but that is asking for trouble.
You can easily solve the problem by passing parameters to functions, and returning values from those functions.

How to replace " \\u0027 " by " ' " in python?

i am new to python, and im trying to program a scraper.
firstly, i extract this kind of string in a variable (lets call it data[1], because it's contained in an array):
\"description\":\"Alors qu\\u0027ils montaient dans l\\u0027un des
couloirs du versant nord du Hohneck (\\"le premier couloir \u00E0
droite\\"), deux alpinistes ont d\u00E9clench\u00E9 une plaque et ont
\u00E9t\u00E9 emport\u00E9s tous les deux. L\\u0027un sera enseveli et
l\\u0027autre ne pourra d\u00E9clencher l\\u0027alerte qu\\u0027\u00E0
la nuit. La victime ne sera retrouv\u00E9e que d\u00E9but avril.
\u003cbr\u003e Sur la photo prise en f\u00E9vrier 2011, le
trac\u00E9 approximatif de l\\u0027avalanche a \u00E9t\u00E9
repr\u00E9sent\u00E9.\",
then, i use :
data = data[1].encode().decode('unicode-escape')
but it gives me :
"description":"Alors qu\u0027ils montaient dans l\u0027un des couloirs
du versant nord du Hohneck (\"le premier couloir à droite\"), deux
alpinistes ont déclenché une plaque et ont été emportés tous les deux.
L\u0027un sera enseveli et l\u0027autre ne pourra déclencher
l\u0027alerte qu\u0027à la nuit. La victime ne sera retrouvée que
début avril. \u003cbr\u003e Sur la photo prise en février 2011, le
tracé approximatif de l\u0027avalanche a été représenté.",
indeed, char with accent had been replaced but apostrophes stay unprocessed !
It seems the two backslashes are the cause.
i tried several methods :
like decode twice and then "\u0027" become "'", but "é" become "é".
data.replace('é', 'é') or data.replace(u'\u0027', u'é') dont work
So, do you have any idea how i could fix this probleme ?
Problem fixed !
As user2357112 supports Monica said, i tried to process manually a json.
But doing :
data = html_page.find_all("script")
data = re.findall("(?<=JSON\.parse\(')[A-Za-z0-9'.?!/+=;:,()\\\ \"\-{_àâçéèêëíìîôùûæœÁÀÂÃÇÉÈÊËÍÌÎÔÙÛ©´<>]*", str(data))
data = data[0].encode().decode('unicode-escape') + "\"\"}"
data_dict = json.loads(data)
string_data_dict = json.dumps(data_dict)
for cle, val in data_dict.items() :
print(cle + " : " + str(val))
solves the bug.
With this code, an input string like :
<script>
var admin = false;
var avalanche = JSON.parse('{...\"description\":\"Alors qu\\u0027ils montaient dans l\\u0027un des couloirs du versant nord du Hohneck (\\\"le premier couloir \u00E0 droite\\\"), deux alpinistes ont d\u00E9clench\u00E9 une plaque et ont \u00E9t\u00E9 emport\u00E9s tous les deux. L\\u0027un sera enseveli et l\\u0027autre ne pourra d\u00E9clencher l\\u0027alerte qu\\u0027\u00E0 la nuit. La victime ne sera retrouv\u00E9e que d\u00E9but avril. \\u003cbr\\u003e Sur la photo prise en f\u00E9vrier 2011, le trac\u00E9 approximatif de l\\u0027avalanche a \u00E9t\u00E9 repr\u00E9sent\u00E9.\",...
gives an output like :
...
description : Alors qu'ils montaient dans l'un des couloirs du versant nord du Hohneck ("le premier couloir à droite"), deux alpinistes ont déclenché une plaque et ont été emportés tous les deux. L'un sera enseveli et l'autre ne pourra déclencher l'alerte qu'à la nuit. La victime ne sera retrouvée que début avril. <br> Sur la photo prise en février 2011, le tracé approximatif de l'avalanche a été représenté.
...
Thanks you.

How can I get the exact result of 10**20 + 10**-20 in Python? It gives me 1e+20

I am writing a code to solve second-grade equations and it works just well.
However, when I input the following equation:
x^2 + (10^(20) + 10^(-20)) + 1 = 0
(Yes, my input is 10**20 + 10**(-20)
I get:
x1 = 0 x2 = -1e+20
However, it is taking (10^(20) + 10^(-20) as 10e+20 while, if you do the math:
Here is the LaTeX formatted formula:
Which is almost 10^20 but not 10^20.
How can I get the exact result of that operation so I can get the exact value of the equation in x2?
My code is the following:
#===============================Función para obtener los coeficientes===============================
#Se van a anidar dos funciones. Primero la de coeficientes, luego la de la solución de la ecuación.
#Se define una función recursiva para obtener los coeficientes de la ecuación del usuario
def cof():
#Se determina si el coeficiente a introducir es un número o una cadena de operaciones
op = input("Si tu coeficiente es un número introduce 1, si es una cadena de operaciones introduce 2")
#Se compara la entrada del usuario con la opción.
if op == str(1):
#Se le solicita el número
num = input("¿Cuál es tu número?")
#Se comprueba que efectívamente sea un número
try:
#Si la entrada se puede convertir a flotante
float(num)
#Se establece el coeficiente como el valor flotante de la entrada
coef = float(num)
#Se retorna el valor del coeficiente
return coef
#Si no se pudo convertir a flotante...
except ValueError:
#Se le informa al usuario del error
print("No introdujiste un número. Inténtalo de nuevo")
#Se llama a la función de nuevo
return cofa()
#Si el coeficiente es una cadena (como en 10**20 + 10**-20)
elif op == str(2):
#La entrada se establece como la entrada del usuario
entrada = input("Input")
#Se intenta...
try:
#Evaluar la entrada. Si se puede...
eval(entrada)
#El coeficiente se establece como la evaluación de la entrada
coef = eval(entrada)
#Se regresa el coeficiente
return coef
#Si no se pudo establecer como tal...
except:
#Se le informa al usuario
print("No introdujiste una cadena de operaciones válida. Inténtalo de nuevo")
#Se llama a la función de nuevo
return cofa()
#Si no se introdujo ni 1 ni 2 se le informa al usuario
else:
#Se imprime el mensaje
print("No introdujiste n ni c, inténtalo de nuevo")
#Se llama a la función de nuevo
return cof()
#===============================Función para resolver la ecuación===============================
#Resuelve la ecuación
def sol_cuadratica():
#Se pide el valor de a
print("Introduce el coeficiente para a")
#Se llama a cof y se guarda el valor para a
a = cof()
#Se pide b
print("Introduce el coeficiente para b")
#Se llama cof y se guarda b
b = cof()
#Se pide c
print("Introduce el coeficiente para c")
#Se llama cof y se guarda c
c = cof()
#Se le informa al usuario de la ecuación a resolver
print("Vamos a encontrar las raices de la ecuación {}x² + {}x + {} = 0".format(a, b, c))
#Se analiza el discriminante
discriminante = (b**2 - 4*a*c)
#Si el discriminante es menor que cero, las raices son complejas
if discriminante < 0:
#Se le informa al usuario
print("Las raices son imaginarias. Prueba con otros coeficientes.")
#Se llama a la función de nuevo
return sol_cuadratica()
#Si el discriminante es 0, o mayor que cero, se procede a resolver
else:
#Ecuación para x1
x1 = (-b + discriminante**(1/2))/(2*a)
#Ecuación para x2
x2 = (-b - discriminante**(1/2))/(2*a)
#Se imprimen los resultados
print("X1 = " + str(x1))
print("X2 = " + str(x2))
sol_cuadratica()
Ignore the comments, I'm from a Spanish-speaking country.
The limitations of the machine floating point type is the reason why when adding a very small number to a very big number, the small number is just ignored.
This phenomenon is called absorption or cancellation.
With custom floating point objects (like the ones decimal module) you can achieve any precision (computations are slower, because floating point is now emulated, and not relying on the machine FPU capabilities anymore)
From the decimal module docs:
Unlike hardware based binary floating point, the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for a given problem
This can be achieved by changing the following global parameter decimal.getcontext().prec
import decimal
decimal.getcontext().prec = 41 # min value for the required range
d = decimal.Decimal(10**20)
d2 = decimal.Decimal(10**-20)
now
>>> d+d2
Decimal('100000000000000000000.00000000000000000001')
As suggested in comments, for the small number it's safer to let decimal module handle the division by using power operator on an already existing Decimal object (even if here, the result is the same):
d2 = decimal.Decimal(10)**-20
So you can use decimal.Decimal objects for your computations instead of native floats.

Global name is not defined executing a function

I'm coding a project, in which I have 2 files (dataStructure.py and calculUser.py) working together and 1 which is a test file.
In structureDonnees.py I have this function which reads a dataset containing cars and builds data structures :
# -*-encoding:utf-8-*-
import csv
import sys #pour utiliser maximum et minimum du type float
from calculUser import *
from trajetUser import *
def recupVoiture() :
#nom de la base de donnée
nomFichier = 'CO2_passenger_cars_v10.csv'
#on ouvre le fichier en lecture
opener = open(nomFichier, "r")
#On ouvre le fichier nomFichier en lecture
lectureFichier = csv.reader(opener, delimiter='\t')
#le dico contenant les carburants
fuelType = dict()
#le dico contenant les voitures
voiture = dict()
#le dico contenant les émissions de CO2 en g/km
emission = dict()
#minimum et maximum emission
min_emission = sys.float_info.max #initialisé à max(float) pour que l'on soit sûr que toutes les emissions soient plus petites
max_emission = sys.float_info.min #initialisé à min(float) pour que l'on soit sûr que toutes les emissions soient plus grandes
for row in lectureFichier :
#Si la colonne existe
if row:
#construction du dictionnaire voiture
if voiture.has_key(row[10]) :
if row[11].upper() not in voiture[row[10]] : voiture[row[10]].append("%s" %row[11].upper()) #on ajoute le modèle
else :
voiture[row[10]] = [] #on crée une liste vide contenant les modèles et leurs versions
voiture[row[10]].append("%s" %row[11]) #on ajoute le modèle et sa version
#construction du dictionnaire fuelType
if fuelType.has_key(row[10]) : fuelType[row[10]].append(row[19].upper()) #ajout du type de carburant utilisé par la voiture correspondante dans voiture{}
else :
fuelType[row[10]] = [] #on crée une liste vide contenant les carburants
fuelType[row[10]].append(row[19]) #ajout du type de carburant utilisé par la voiture correspondante dans voiture{}
#construction du dictionnaire emission
if emission.has_key(row[10]) :
emission[row[10]].append(row[14]) #ajout de la quantité de CO2 émise par la voiture correspondante dans voiture{}
min_emission = minEmission(float(row[14]), min_emission)
max_emission = maxEmission(float(row[14]), max_emission)
else :
emission[row[10]] = [] #on crée une liste vide contenant les émissions en CO2
fuelType[row[10]].append(row[14]) #ajout de la quantité de CO2 émise par la voiture correspondante dans voiture{}
min_emission = minEmission(float(row[14]), min_emission)
max_emission = maxEmission(float(row[14]), max_emission)
#On ferme le fichier
opener.close()
#La valeur de retour est un tableau contenant les structures de données générées.
res = [voiture, fuelType, emission, min_emission, max_emission]
return res
In the calculUser.py, I defined the minEmission and maxEmission function :
def minEmission(emissionFichier, min_emission) :
if emissionFichier < min_emission :
min_emission = emissionFichier
return min_emission
def maxEmission(emissionFichier, max_emission) :
if emissionFichier > max_emission :
max_emission = emissionFichier
return max_emission
When I'm executing test.py, I get an error with this line :
table = recupVoiture()
Traceback (most recent call last):
File "test.py", line 13, in <module>
tableau = recupVoiture()
File "/home/user/Polytech/ge3/ProjetPython/structureDonnees.py", line 60, in recupVoiture
min_emission = minEmission(float(row[14]), min_emission)
NameError: global name 'minEmission' is not defined
I don't understand why I get this error. By executing everything except test.py I get no error but when I do it doesn't execute due to this minEmission and maxEmission not defined.
Is it because I'm calling a function when I'm defining a function?
How could I fix it?
I fixed the problem, it seems like my functions minEmission() and maxEmission() couldn't do a reference to max_emission and min_emission since those variables are declared in structureDonnees.py and not in calculUser.py.
I fixed it by creating an intermediary variable which takes the value of min_emission and max_emission and which is returned, instead of min_emission and max_emission.
Plus, I had to do a : from calculUser import minEmission, maxEmissiondirectly in the recupVoiture() function. I know that's awful but it solved the problem. I'll use it until I find a better, cleaner solution.
Thanks for the help guys, I'll do a better post/code if I have to ask any other help ! :)

Categories