Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to accomplish what eval does without using eval in Python

Tags:

python

eval

I am teaching some neighborhood kids to program in Python. Our first project is to convert a string given as a Roman numeral to the Arabic value.

So we developed an function to evaluate a string that is a Roman numeral the function takes a string and creates a list that has the Arabic equivalents and the operations that would be done to evaluate to the Arabic equivalent.

For example suppose you fed in XI the function will return [1,'+',10] If you fed in IX the function will return [10,'-',1] Since we need to handle the cases where adjacent values are equal separately let us ignore the case where the supplied value is XII as that would return [1,'=',1,'+',10] and the case where the Roman is IIX as that would return [10,'-',1,'=',1]

Here is the function

def conversion(some_roman):
    roman_dict = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M',1000}
    arabic_list = []
    for letter in some_roman.upper():
        if len(roman_list) == 0:
            arabic_list.append(roman_dict[letter]
            continue
        previous = roman_list[-1]
        current_arabic = roman_dict[letter]
        if current_arabic > previous:
            arabic_list.extend(['+',current_arabic])
            continue
        if current_arabic == previous:
            arabic_list.extend(['=',current_arabic])
            continue
        if current_arabic < previous:
            arabic_list.extend(['-',current_arabic])
      arabic_list.reverse()
      return arabic_list

the only way I can think to evaluate the result is to use eval()

something like

def evaluate(some_list):
    list_of_strings = [str(item) for item in some_list]
    converted_to_string = ''.join([list_of_strings])
    arabic_value = eval(converted_to_string)
    return arabic_value

I am a little bit nervous about this code because at some point I read that eval is dangerous to use in most circumstances as it allows someone to introduce mischief into your system. But I can't figure out another way to evaluate the list returned from the first function. So without having to write a more complex function.

The kids get the conversion function so even if it looks complicated they understand the process of roman numeral conversion and it makes sense. When we have talked about evaluation though I can see they get lost. Thus I am really hoping for some way to evaluate the results of the conversion function that doesn't require too much convoluted code.

Sorry if this is warped, I am so . . .

like image 789
PyNEwbie Avatar asked Mar 21 '23 07:03

PyNEwbie


1 Answers

Is there a way to accomplish what eval does without using eval

Yes, definitely. One option would be to convert the whole thing into an ast tree and parse it yourself (see here for an example).

I am a little bit nervous about this code because at some point I read that eval is dangerous to use in most circumstances as it allows someone to introduce mischief into your system.

This is definitely true. Any time you consider using eval, you need to do some thinking about your particular use-case. The real question is how much do you trust the user and what damage can they do? If you're distributing this as a script and users are only using it on their own computer, then it's really not a problem -- After all, they don't need to inject malicious code into your script to remove their home directory. If you're planning on hosting this on your server, that's a different story entirely ... Then you need to figure out where the string comes from and if there is any way for the user to modify the string in a way that could make it untrusted to run. Hackers are pretty clever1,2 and so hosting something like this on your server is generally not a good idea. (I always assume that the hackers know python WAY better than I do).

1http://blog.delroth.net/2013/03/escaping-a-python-sandbox-ndh-2013-quals-writeup/

2http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html

like image 193
mgilson Avatar answered Apr 26 '23 05:04

mgilson