Ввод чисел с плавающей запятой, целых чисел или уравнений в raw_input для определения переменной

Я написал эту программу, чтобы решить два уравнения на основе значений, определенных пользователем. Константы kx и ky я определил как числа с плавающей запятой. Для диапазона - начало и конец переменных - я бы хотел, чтобы пользователь либо ввел число, либо что-то вроде 6 * np.pi (6Pi). Как и сейчас, я получаю следующую ошибку. Как я могу определить эту переменную, чтобы пользователи могли вводить несколько типов ввода? Спасибо!

    Traceback (most recent call last):
  File "lab1_2.py", line 11, in <module>
    x = np.linspace(start, end, 256, endpoint=True)
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-  packages/numpy/core/function_base.py", line 80, in linspace
    step = (stop-start)/float((num-1))
  TypeError: unsupported operand type(s) for -: 'str' and 'float'

Вот код:

from pylab import *
import numpy as np

kx = float(raw_input("kx: "))
ky = float(raw_input("ky: "))

print "Define the range of the output:"
start = float(raw_input("From: "))
end = float((raw_input("To: "))

x = np.linspace(start, end, 256, endpoint=True)
y = np.linspace(start, end, 256, endpoint=True)

dz_dx = ((1 / 2.0) * kx * np.exp((-kx * x) / 2)) * ((2 * np.cos(kx *x)) - (np.sin(kx * x)))
dz_dy = ((1 / 2.0) * ky * np.exp((-ky * y) / 2)) * ((2 * np.cos(ky *y)) - (np.sin(ky * y)))

plot(x, dz_dx, linewidth = 1.0)
plot(y, dz_dy, linewidth = 1.0)
grid(True)


show()

person Jonathan Fry    schedule 28.01.2013    source источник


Ответы (3)


Вам нужно будет либо самостоятельно проанализировать строку (возможно, будет полезен модуль ast), либо использовать eval:

>>> s = '6*pi'
>>> eval(s,{'__builtins__': None, 'pi': np.pi})
18.84955592153876

Обратите внимание, что есть некоторые неприятные вещи, которые пользователи могут делать с eval. Мое решение защищает вас от большинства из них, но не от всех — предварительная проверка строки на отсутствие __ сделает ее еще безопаснее (что устраняет все уязвимости, которые я известны, но могут быть и другие)

person mgilson    schedule 28.01.2013

Я хотел бы, чтобы пользователь либо ввел число, либо что-то вроде 6 * np.pi (6Pi).

Чтобы реализовать это, вам нужно сделать две вещи:

  • Во-первых, проверьте, является ли ваш ввод int или float

    Это просто. Вы можете проверить это несколькими isinstance проверками

  • Если нет, то вам нужно выполнить ввод как команду и сохранить вывод в переменной

    Как только вы убедитесь, что это команда, вы можете использовать команду exec или eval для выполнения ввода и сохранения вывода в переменной.

    Пример: exec("""v = 6*2""") или v = eval("6*2") оба присваивают 12 v.

person asheeshr    schedule 28.01.2013


Я использую Python 2.7 и рабочее пространство Ecplise. Этот исходный код отлично работает для меня, используя raw_input.

import time

startTime = time.clock()
print "{0:*^80}".format(" Begins ")

name = raw_input('Please give the name : ')
print "Name is : ".ljust(40, '.'), name
print "Length of name : ".ljust(40, '.'), len(name)

print
radius = float(raw_input('Please enter the radius of circle : '))
print "Radius is : ".ljust(40, '.'),radius
diameter = float(2 * radius)
print "Diameter of circle is : ".ljust(40, '.'), diameter

print "\n{0:*^80}".format(" End ")

print "\nElapsed time : ", (time.clock() - startTime)*1000000, "microseconds"

Здесь введите :
имя : "Сэр! Гвидо фон Россум" и
радиус : 1,1

Вывод:

************************************ Begins ************************************
Please give the name : Sir! Guido von Rossum
Name is : .............................. Sir! Guido von Rossum
Length of name : ....................... 21

Please enter the radius of circle : 1.1
Radius is : ............................ 1.1
Diameter of circle is : ................ 2.2

************************************* End **************************************

Elapsed time :  3593748.49903 microseconds

Подумал, может быть, это поможет вам или кому-то еще.
Спасибо.

person akD    schedule 26.10.2016