devo realizzare un piccolo programmino che calcoli le derivate. E' un programma semplice, con scopo didattico, quindi la premessa che viene fatta è che accetta espressioni nella forma
Codice: Seleziona tutto
X + X
Ora, incollo il codice che ho scritto, funzionante:
Codice: Seleziona tutto
#
# La funzione principale e' derive(). Accetta in ingresso una stringa e una variabile.
# Trasforma l'espressione da derivare, che e' sottoforma di stringa, in una lista in cui il primo e il terzo elemento sono operandi
# mentre il secondo e' l'operatore.
# Chiama poi la funzione di derivazione vera e propria, derivative() che applica le regole di derivazione sugli operatori.
# Infine, derive_solver() calcola la derivata sui singoli operandi.
#
import string
import re
def exp_split(mystring): # prende in input una espressione matematica (sottoforma di stringa) e la memorizza in una lista, dividendo gli operandi e operatori
exp_splitted = re.split("([+-/*])", mystring.replace(" ", ""), maxsplit = 1)
if len(exp_splitted[0]) > 2:
exp_splitted[0] = exp_split(exp_splitted[0])
if len(exp_splitted) > 2:
if len(exp_splitted[2]) > 2:
exp_splitted[2] = exp_split(exp_splitted[2])
return exp_splitted
def rimuovi_parentesi(lista): # da chiamare solo quando l'intera espressione e' gia' scomposta in liste
lunghezza = len(lista)
for x in range(lunghezza):
if type(lista[x]) == type([]):
rimuovi_parentesi(lista[x])
else:
lista[x] = lista[x].replace("(", "")
lista[x] = lista[x].replace(")", "")
return lista
def derive_solver(elemento, var):
if type(elemento) == type(0):
return "0"
elif elemento == var:
return "1"
else:
return "0"
def derivative(lst, var):
if len(lst) == 1: # Se viene chiamata la funzione derivative() su un singolo elemento, quest'ultimo viene passato a derive_solver() e risolto.
return derive_solver(lst[0], var)
if lst[1] == '+':
return [derivative(lst[0], var), '+', derivative(lst[2], var)]
if lst[1] == '*':
return [[derivative(lst[0], var), '*', lst[2]], '+', [lst[0], '*', derivative(lst[2], var)]]
def lst_to_str(lst): # prende in input una espressione memorizzata in una lista, e la converte in stringa
if type(lst) != type([]):
return lst
elif type(lst[0]) == type([]):
lst[0] = lst_to_str(lst[0])
elif type(lst[2]) == type([]):
lst[2] = lst_to_str(lst[2])
return "(" + str(lst[0]) + " " + str(lst[1]) + " " + str(lst[2]) + ")"
def calculate_result(lst): # data in input una espressione (sottoforma di lista) gia' derivata, effettua i calcoli per semplificarla
if len(lst) == 1: # Se e' gia' un singolo elemento, restituisce l'elemento stesso senza fare nulla.
return lst
letter = string.lowercase + string.uppercase # creo una stringa contenente tutte le lettere (maiuscole e minuscole). La usero' dopo per verificare che l'operando sia un simbolo
if type(lst[0]) == type([]): # Se il primo operando e' una lista, prima risolvo quella
lst[0] = calculate_result(lst[0])
if type(lst[2]) == type([]):
lst[2] = calculate_result(lst[2]) # Se il secondo operando e' una lista, prima risolvo quella
if lst[1] == '+':
if (string.find(string.digits, str(lst[0])) != -1) and (string.find(string.digits, str(lst[2])) != -1): # vero se gli operandi della lista sono numeri
return int(lst[0]) + int(lst[2])
if lst[0] == '0':
return lst[2]
if lst[2] == '0':
return lst[0]
if (string.find(letter, str(lst[0])) != -1) or (string.find(letter, str(lst[2])) != -1): # vero se almeno un operando e' un simbolo
return [lst[0], lst[1], lst[2]]
if type(lst[0]) == type([]): # se il primo operando e' una lista, valuto solo il secondo
if lst[2] == '0':
return lst[0]
else:
return [lst[0], lst[1], lst[2]]
if type(lst[2]) == type([]): # se il secondo operando e' una lista, valuto solo il primo
if lst[0] == '0':
return lst[2]
else:
return [lst[0], lst[1], lst[2]]
if lst[1] == '*':
if (string.find(string.digits, str(lst[0])) != -1) and (string.find(string.digits, str(lst[2])) != -1): # vero se gli operandi della lista sono numeri
return int(lst[0]) * int(lst[2])
if (lst[0] == '0') or (lst[2] == '0'): # se un operando e' 0, ritorna 0
return 0
if (lst[0] == '1'): # se il primo operando e' 1, ritorna il secondo
return lst[2]
if (lst[2] == '1'): # se il secondo operando e' 1, ritorna il primo
return lst[0]
if (string.find(letter, str(lst[0])) != -1) or (string.find(letter, str(lst[2])) != -1): # vero se almeno un operando e' un simbolo
return [lst[0], lst[1], lst[2]]
if type(lst[0]) == type([]): # se il primo operando e' una lista, valuto solo il secondo
if lst[2] == '0':
return '0'
else:
return [lst[0], lst[1], lst[2]]
if type(lst[2]) == type([]): # se il secondo operando e' una lista, valuto solo il primo
if lst[0] == '0':
return '0'
else:
return [lst[0], lst[1], lst[2]]
def derive(exp_raw, var):
lst = exp_split(exp_raw) # Prende la stringa dell'espressione in input e la converte in una lista
lst = rimuovi_parentesi(lst) # Rimuove le parentesi tonde
risultato_lista = derivative(lst, var) # Effettua la funzione di derivazione vera e propria
return lst_to_str(calculate_result(risultato_lista))
print derive('1 + (3 * x)', 'x')
L'idea è che, essendo due operatori, essi vengano derivati in modo parallelo.
Io non ho alcuna esperienza di programmazione multithread. Ho provato a cercare informazioni in rete e ad applicarle, ma con scarso risultato, poichè il codice modificato mi restituisce errore.
Provo a copiare qua sotto la prova che ho fatto io.
Qualcuno riuscirebbe a darmi qualche dritta, a indicarmi dove sbaglio ed eventualmente come correggere?
Codice: Seleziona tutto
#
# La funzione principale e' derive(). Accetta in ingresso una stringa e una variabile.
# Trasforma l'espressione da derivare, che e' sottoforma di stringa, in una lista in cui il primo e il terzo elemento sono operandi
# mentre il secondo e' l'operatore.
# Chiama poi la funzione di derivazione vera e propria, derivative() che applica le regole di derivazione sugli operatori.
# Infine, derive_solver() calcola la derivata sui singoli operandi.
#
import string
import re
import threading
def exp_split(mystring): # prende in input una espressione matematica (sottoforma di stringa) e la memorizza in una lista, dividendo gli operandi e operatori
exp_splitted = re.split("([+-/*])", mystring.replace(" ", ""), maxsplit = 1)
if len(exp_splitted[0]) > 2:
exp_splitted[0] = exp_split(exp_splitted[0])
if len(exp_splitted) > 2:
if len(exp_splitted[2]) > 2:
exp_splitted[2] = exp_split(exp_splitted[2])
return exp_splitted
def rimuovi_parentesi(lista): # da chiamare solo quando l'intera espressione e' gia' scomposta in liste
lunghezza = len(lista)
for x in range(lunghezza):
if type(lista[x]) == type([]):
rimuovi_parentesi(lista[x])
else:
lista[x] = lista[x].replace("(", "")
lista[x] = lista[x].replace(")", "")
return lista
def derive_solver(elemento, var):
if type(elemento) == type(0):
return "0"
elif elemento == var:
return "1"
else:
return "0"
def derivative(lst, var):
t1 = threading.Thread(target = derivative, args=(lst[0], var))
t2 = threading.Thread(target = derivative, args=(lst[2], var))
if len(lst) == 1: # Se viene chiamata la funzione derivative() su un singolo elemento, quest'ultimo viene passato a derive_solver() e risolto.
return derive_solver(lst[0], var)
if lst[1] == '+':
return [t1.start(), '+', t2.start()]
if lst[1] == '*':
return [[t1.start(), '*', lst[2]], '+', [lst[0], '*', t2.start()]]
def lst_to_str(lst): # prende in input una espressione memorizzata in una lista, e la converte in stringa
if type(lst) != type([]):
return lst
elif type(lst[0]) == type([]):
lst[0] = lst_to_str(lst[0])
elif type(lst[2]) == type([]):
lst[2] = lst_to_str(lst[2])
return "(" + str(lst[0]) + " " + str(lst[1]) + " " + str(lst[2]) + ")"
def calculate_result(lst): # data in input una espressione (sottoforma di lista) gia' derivata, effettua i calcoli per semplificarla
if len(lst) == 1: # Se e' gia' un singolo elemento, restituisce l'elemento stesso senza fare nulla.
return lst
letter = string.lowercase + string.uppercase # creo una stringa contenente tutte le lettere (maiuscole e minuscole). La usero' dopo per verificare che l'operando sia un simbolo
if type(lst[0]) == type([]): # Se il primo operando e' una lista, prima risolvo quella
lst[0] = calculate_result(lst[0])
if type(lst[2]) == type([]):
lst[2] = calculate_result(lst[2]) # Se il secondo operando e' una lista, prima risolvo quella
if lst[1] == '+':
if (string.find(string.digits, str(lst[0])) != -1) and (string.find(string.digits, str(lst[2])) != -1): # vero se gli operandi della lista sono numeri
return int(lst[0]) + int(lst[2])
if lst[0] == '0':
return lst[2]
if lst[2] == '0':
return lst[0]
if (string.find(letter, str(lst[0])) != -1) or (string.find(letter, str(lst[2])) != -1): # vero se almeno un operando e' un simbolo
return [lst[0], lst[1], lst[2]]
if type(lst[0]) == type([]): # se il primo operando e' una lista, valuto solo il secondo
if lst[2] == '0':
return lst[0]
else:
return [lst[0], lst[1], lst[2]]
if type(lst[2]) == type([]): # se il secondo operando e' una lista, valuto solo il primo
if lst[0] == '0':
return lst[2]
else:
return [lst[0], lst[1], lst[2]]
if lst[1] == '*':
if (string.find(string.digits, str(lst[0])) != -1) and (string.find(string.digits, str(lst[2])) != -1): # vero se gli operandi della lista sono numeri
return int(lst[0]) * int(lst[2])
if (lst[0] == '0') or (lst[2] == '0'): # se un operando e' 0, ritorna 0
return 0
if (lst[0] == '1'): # se il primo operando e' 1, ritorna il secondo
return lst[2]
if (lst[2] == '1'): # se il secondo operando e' 1, ritorna il primo
return lst[0]
if (string.find(letter, str(lst[0])) != -1) or (string.find(letter, str(lst[2])) != -1): # vero se almeno un operando e' un simbolo
return [lst[0], lst[1], lst[2]]
if type(lst[0]) == type([]): # se il primo operando e' una lista, valuto solo il secondo
if lst[2] == '0':
return '0'
else:
return [lst[0], lst[1], lst[2]]
if type(lst[2]) == type([]): # se il secondo operando e' una lista, valuto solo il primo
if lst[0] == '0':
return '0'
else:
return [lst[0], lst[1], lst[2]]
def derive(exp_raw, var):
lst = exp_split(exp_raw) # Prende la stringa dell'espressione in input e la converte in una lista
lst = rimuovi_parentesi(lst) # Rimuove le parentesi tonde
t = threading.Thread(target = derivative, args=(lst, var))
risultato_lista = derivative(lst, var) # Effettua la funzione di derivazione vera e propria
return lst_to_str(calculate_result(risultato_lista))
print derive('1 + (3 * x)', 'x')
Grazie mille!!