2013-05-16 4 views
1

У меня возникла проблема со следующим кодом. В настоящее время это происходит, но большая проблема, с которой я сталкиваюсь, заключается в том, что мой ввод функции возвращает ошибку независимо от того, какой тип ввода я попробовал. Он либо возвращается с проблемой с типом ошибки, либо проблема с x не определяется, если я ввожу такую ​​функцию, как x.Метод Эйлера Python Variable Тип ввода

f = raw_input("Please enter function: y' = ") 
x0 = float(raw_input("Please enter the initial x value: ")) 
y0 = float(raw_input("Please enter the initial y value: ")) 
xmax = float(raw_input("Please enter the value of x at which to approximate the solution: ")) 
h = float(raw_input("Please enter the step size: ")) 
showall = int(raw_input("Would you like to see all steps (1) or only the approximate solution (2)? ")) 

def f(x,y): 
    value = f 
    return (value) 

def euler(x0,y0,h,xmax): 
    x=x0; y=y0; xd=[x0]; yd=[y0]; 

    while x<xmax: 
     y = y + h*f(x,y) 
     yd.append(y) 
     x=x+h 
     xd.append(x) 
    return(xd,yd) 

(xvals,yvals) = euler(x0,y0,h,xmax) 



if showall == 1: 
    print "" 
    print "x_n y_n" 
    for uv in zip(xvals, yvals): 
     print uv[0],uv[1] 
elif showall == 2: 
    print "" 
    print "x_n y_n" 
    print xvals, yvals 
else: 
    print "" 
    print "There has been an error with your choice of what to see; showing all steps." 
    print "" 
    print "x_n y_n" 
    for uv in zip(xvals, yvals): 
     print uv[0],uv[1] 

print " "  
plotask = int(raw_input("Would you like to see a plot of the data? Yes (1); No (2) ")) 

if plotask == 1: 
    print "1" 
elif plotask == 2: 
    pass 
else: 
    print "" 
    print "Could not understand answer; showing plot." 

Любая помощь будет принята с благодарностью.

Ошибка и трассировки заключается в следующем:

File "C:\Users\Daniel\Desktop\euler.py", line 25, in <module> 
     (xvals,yvals) = euler(x0,y0,h,xmax) 
    File "C:\Users\Daniel\Desktop\euler.py", line 19, in euler 
     y = y + h*f(x,y) 
TypeError: unsupported operand type(s) for *: 'float' and 'function' 
+0

Показать точное сообщение об ошибке и трассировку стека, пожалуйста. – Patashu

+0

Сообщение обновлено, чтобы показать ошибку и трассировку – danielunderwood

+0

Я новичок здесь и не знал об этом. Благодаря! – danielunderwood

ответ

1

Проблема, с которой вы сталкиваетесь, заключается в том, что ваша функция f используя то же имя, что и строка формулы, которую вы собираете в первой строке вашего кода. Однако простое исправление имени не будет делать то, что вы хотите, я не думаю.

Функция f должна будет оценить формулу, чтобы получить числовой результат. Я думаю, что вы хотите:

formula = raw_input("Please enter function: y' = ") 

def f(x, y): 
    return eval(formula) 

В то время как это работает, я хочу отметить, что использование eval, как правило, не рекомендуется практик, особенно когда строка вы оценка приходит от пользователя. Это потому, что он может включать в себя произвольный код Python, который будет запущен. eval('__import__(os).system("rm -Rf *")') может погубить ваш день (не запускайте этот код!).

+0

Спасибо, это исправило мою проблему! Что касается использования eval, было бы в порядке, если бы пользователь не вводит какой-либо тип кода python, правильно? – danielunderwood

+0

@ danielu13 Если вы хотите сделать калькулятор, который не использует eval (-> is safe), найдите PLY для python. Это лексер/парсер и отлично подходит для делая такие вещи, как написание выражений парсеров (я написал один в нем) – Patashu

+0

@Patashu Спасибо за предложение, я рассмотрю его. – danielunderwood

2

Эта функция:

def f(x,y): 
    value = f 
    return (value) 

Можно увидеть, чтобы вернуть функцию. В частности, он ничего не делает, кроме самого возврата, f. (Обратите внимание, что f отличается от f() или f(x,y)

y = y + h*f(x,y) 

вычисляет

y = y + h*f 

, которая является ошибкой, поскольку f является функцией, и вы не можете умножить функцию числом (в отличие от РЕЗУЛЬТАТ оценки вызова функции - например, если f(x,y) возвращает номер, то ваш код будет работать)

+0

Я думал, что это проблема, но если я попробую подставить функцию непосредственно для значения, как в 'value = x * y' вместо' f = x * y; value = f' работает. Есть ли другой способ сделать это, когда я могу запросить ввод? – danielunderwood

+0

Это потому, что когда вы делаете 'value = x * y'' value' - это число (результат вычисления 'x * y', но' value = f' делает 'значение' функцией (результат вычисления' f 'to return' f', которая является функцией). Чтобы превратить функцию в результат, который она возвращает, вы должны ее оценить, что требует ее вызова, как в 'f()' или 'f (x + y) ' – Patashu

+0

Спасибо. Это просто ударил меня, что вы пытались объяснить, как только я отправил комментарий. Теперь я понимаю. – danielunderwood

Смежные вопросы