eval() woes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • rdrink

    eval() woes

    n.n.h. (noob needs help)
    Ok, I've been beating my head against this for a day... time to ask
    others.
    To explain things as simply as possible:
    I am trying to use eval() to evaluate some simple equations, such as--
    pow(AB,2)
    pow(AB,2)+A
    pow(A+B,2)
    pow(A+B,2)+A
    and so forth... for a variety of math operations (+,-,*) and a variety
    of variables, all of which have been genrated by a script, written to
    a .txt file., then recalled sequentially and passed to eval().

    The variables (A,B,C,D) are generated elsewhere [Note: AB is a concat,
    e.g. A=2,B=7,AB=27] , so both are passed into a function e.g.
    def (equation, list):
    A=list[0]
    B=list[1]
    ...etc.
    return eval(str(equati on))
    Where 'equation' is one of the above, selected from the "equations
    file"

    So here's the rub:
    With the above examples everything works fine... up to the last
    (pow(A+B,2)+A), then it bombs with:
    ValueError: invalid literal for int(): -
    And I have tried 'hard typing' the vars e.g. A=str(list[0]) and
    A=int(str(list[0]))... which only leads to it breaking in the other
    expressions.
    I have also tried 'compile()', which bombs the same way, and have also
    looked at 'pickle' (but I don't think I really need to go that far)...

    All of which leaves me wondering... Could it simply be that eval()
    can't handle the progressive order of math operations? Because
    pow(AB,2) + A works, as does pow(A+B,2)... but then adding pow(A+B,2)+A
    (the result, *plus* A) doesn't?
    Or is the problem deeper (like at the dictionary level)?

    Either way I'm stumped, and could use some help.
    Thanks
    Robb Drinkwater

  • Simon Forman

    #2
    Re: eval() woes

    rdrink wrote:
    n.n.h. (noob needs help)
    Ok, I've been beating my head against this for a day... time to ask
    others.
    To explain things as simply as possible:
    I am trying to use eval() to evaluate some simple equations, such as--
    pow(AB,2)
    pow(AB,2)+A
    pow(A+B,2)
    pow(A+B,2)+A
    and so forth... for a variety of math operations (+,-,*) and a variety
    of variables, all of which have been genrated by a script, written to
    a .txt file., then recalled sequentially and passed to eval().
    >
    The variables (A,B,C,D) are generated elsewhere [Note: AB is a concat,
    e.g. A=2,B=7,AB=27] , so both are passed into a function e.g.
    def (equation, list):
    A=list[0]
    B=list[1]
    ...etc.
    return eval(str(equati on))
    Where 'equation' is one of the above, selected from the "equations
    file"
    >
    So here's the rub:
    With the above examples everything works fine... up to the last
    (pow(A+B,2)+A), then it bombs with:
    ValueError: invalid literal for int(): -
    And I have tried 'hard typing' the vars e.g. A=str(list[0]) and
    A=int(str(list[0]))... which only leads to it breaking in the other
    expressions.
    I have also tried 'compile()', which bombs the same way, and have also
    looked at 'pickle' (but I don't think I really need to go that far)...
    >
    All of which leaves me wondering... Could it simply be that eval()
    can't handle the progressive order of math operations? Because
    pow(AB,2) + A works, as does pow(A+B,2)... but then adding pow(A+B,2)+A
    (the result, *plus* A) doesn't?
    Or is the problem deeper (like at the dictionary level)?
    >
    Either way I'm stumped, and could use some help.
    Thanks
    Robb Drinkwater
    You must be doing something weird, that equation works for me:

    |>A, B = 2, 7
    |>eq = 'pow(A + B, 2) + A'
    |>eval(eq)
    83

    Try posting the minimal code example that causes the error and the
    full, exact traceback that you get. (Or even just post the full
    traceback that you're getting now, it would probably contain enough
    information itself to solve your problem. And it's a good idea to do
    that anyway, post the whole traceback, not just the final line.)

    (Also, assuming your equations are already strings, there's no reason
    to call str() on them again. And you mention a "dictionary level" but
    don't mention using a dict.)

    FWIW, the error "ValueError : invalid literal for int()" occurs when
    you, uh, pass an invalid literal to the int() function (actually int
    type.. but not important here), and includes the invalid input so you
    don't have to guess at it:

    |>int('wombat' )

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    int('wombat')
    ValueError: invalid literal for int(): wombat

    So, from what's visible in your post, it looks like int is getting
    passed a bare '-', i.e. at some point you're calling int('-')...

    HTH


    Peace,
    ~Simon

    Comment

    • rdrink

      #3
      Re: eval() woes

      Hey Simon, Thanks for the reply.

      Simon Forman wrote:
      You must be doing something weird, that equation works for me:
      Try posting the minimal code example that causes the error and the
      full, exact traceback that you get.
      I appreciate the offer... but at this point my code is too recursive
      and deeply nested to send a "simple" example
      (Also, assuming your equations are already strings, there's no reason
      to call str() on them again.
      This is an interesting point: I AM putting them into the file as
      strings, and then pulling them back out as such and you are right, they
      do not need to be re-cast as strings. I think as some point I was
      getting errors there, but for now I can omit that....
      And you mention a "dictionary level" but
      don't mention using a dict.)
      Sorry, that was a spurious thought... No I'm not using a dict (although
      I am still not sure if I should be)...
      FWIW, the error "ValueError : invalid literal for int()" occurs when
      you, uh, pass an invalid literal to the int() function (actually int
      type.. but not important here), and includes the invalid input so you
      don't have to guess at it:
      >
      |>int('wombat' )
      HTH
      Yes that is helpful.
      I am still getting errors... which leads me to belive that it all has
      to do with how I am casting, and re-casting, things as strings and
      ints.
      I need a little more time to try to suss this all out; after which, if
      I still can't get it to work, I'll post some more code.

      Thanks again for your thoughts and comments.

      Robb

      Comment

      • rdrink

        #4
        Re: eval() woes

        Ok, maybe now I can make some more sense of this, with an example of
        real code (sorry if it's a bit dense):
        This is the basic function...

        def equate(parts,ne w_eq):

        oL = int(parts[0])
        iL = int(parts[1])
        iR = int(parts[2])
        oR = int(parts[3])
        oLoL = int(str(oL)+str (oL))
        oLiL = int(str(oL)+str (iL))
        oLiR = int(str(oL)+str (iR))
        oLoR = int(str(oL)+str (oR))
        iLoL = int(str(iL)+str (oL))
        iLiL = int(str(iL)+str (iL))
        iLiR = int(str(iL)+str (iR))
        iLoR = int(str(iL)+str (oR))
        iRoL = int(str(iR)+str (oL))
        iRiL = int(str(iR)+str (iL))
        iRiR = int(str(iR)+str (iR))
        iRoR = int(str(iR)+str (oR))
        oRoL = int(str(oR)+str (oL))
        oRiL = int(str(oR)+str (iL))
        oRiR = int(str(oR)+str (iR))
        oRoR = int(str(oR)+str (oR))

        new_seed = eval(new_eq)
        return new_seed

        .... into which is passed two items:
        - 'parts' , which is a list e.g ['12','34','56', '78'] (of strings)
        - and 'new_eq',which is also a string read from a text file, e.g.
        "pow(oLiL,2 )"

        And so...for the first 9 entries (of 480) in the text file where...
        pow(oLiL,2)
        pow(oLiL,2) - oL
        pow(oLiL,2) - iL
        pow(oLiL,2) - iR
        pow(oLiL,2) - oR
        pow(oLiL,2) + oL
        pow(oLiL,2) + iL
        pow(oLiL,2) + iR
        pow(oLiL,2) + oR
        pow(oLiL,2)
        pow(oL - iL,2)
        .... eval() works fine.
        But on the 10th...
        pow(oL - iL,2) - oL
        .... it bombs with the error:
        pow(oL - iL,2) - oL
        Traceback (most recent call last):
        File "the_farmer2.py ", line 264, in ?
        seed = equate(parts,eq uation)
        File "the_farmer2.py ", line 112, in equate
        iL = int(parts[1])
        ValueError: invalid literal for int(): -

        And what is interseting/odd is:
        - For the third, '- iL' evaluates fine...
        - as well as the 9th, [where it is nested, oL - iL, inside pow()] ...
        - but in the 10th, where a subtraction is called twice, it doesn't.
        Which leads me to believe that the problem is either inside eval() it's
        self, or in the way these variables are being cast... but I can't tell
        which.

        (BTW, as a footnote: For each of the above 'equations' the function
        equate() was called 500 times... in some cases with the list 'parts'
        equaling things like ['0',2','3','0'], so I have no reason to believe
        that the problem is with the way the list is being passed in... but I
        could be wrong)

        Can anyone see something I can't?

        Robb

        Comment

        • John McMonagle

          #5
          Re: eval() woes

          On Mon, 2006-08-28 at 21:13 -0700, rdrink wrote:
          >
          (BTW, as a footnote: For each of the above 'equations' the function
          equate() was called 500 times... in some cases with the list 'parts'
          equaling things like ['0',2','3','0'], so I have no reason to believe
          that the problem is with the way the list is being passed in... but I
          could be wrong)
          >
          Can anyone see something I can't?
          Why don't you simply "print parts" as the first statement of your equate
          function to check what its value is. Then work out where in your code
          parts is being modified (especially parts[1]).

          Regards,

          John



          --
          This message has been scanned for viruses and
          dangerous content by MailScanner, and is
          believed to be clean.

          Comment

          • Simon Forman

            #6
            Re: eval() woes

            rdrink wrote:
            Hey Simon, Thanks for the reply.
            >
            Simon Forman wrote:
            You must be doing something weird, that equation works for me:
            Try posting the minimal code example that causes the error and the
            full, exact traceback that you get.
            >
            I appreciate the offer... but at this point my code is too recursive
            and deeply nested to send a "simple" example
            That's not an offer, it's a request. There's not enough information in
            your original post to know what you're doing, let alone what you're
            doing wrong.

            If you explain for fully what's actually going on (i.e. tracebacks and
            code) then it's much more likely that I or someone else on this list
            will be able to help you figure out what's wrong.
            >
            (Also, assuming your equations are already strings, there's no reason
            to call str() on them again.
            >
            This is an interesting point: I AM putting them into the file as
            strings, and then pulling them back out as such and you are right, they
            do not need to be re-cast as strings. I think as some point I was
            getting errors there, but for now I can omit that....
            >
            And you mention a "dictionary level" but
            don't mention using a dict.)
            >
            Sorry, that was a spurious thought... No I'm not using a dict (although
            I am still not sure if I should be)...
            >
            FWIW, the error "ValueError : invalid literal for int()" occurs when
            you, uh, pass an invalid literal to the int() function (actually int
            type.. but not important here), and includes the invalid input so you
            don't have to guess at it:

            |>int('wombat' )
            HTH
            >
            Yes that is helpful.
            I am still getting errors... which leads me to belive that it all has
            to do with how I am casting, and re-casting, things as strings and
            ints.
            I need a little more time to try to suss this all out; after which, if
            I still can't get it to work, I'll post some more code.
            >
            Thanks again for your thoughts and comments.
            >
            Robb

            Comment

            • Gabriel Genellina

              #7
              Re: eval() woes

              At Tuesday 29/8/2006 01:13, rdrink wrote:
              File "the_farmer2.py ", line 112, in equate
              iL = int(parts[1])
              >ValueError: invalid literal for int(): -
              So parts[1] is '-'.
              Try adding a few print statements; I'd add a try/except around those
              lines, printing parts, I bet it's not what you expect it to be.
              The problem appears to be in the calling code, not on this function.
              >equate() was called 500 times... in some cases with the list 'parts'
              >equaling things like ['0',2','3','0'], so I have no reason to believe
              >that the problem is with the way the list is being passed in... but I
              >could be wrong)
              ....like above, where you missed a quote.
              Can anyone see something I can't?
              Not on the code fragment you posted.


              Gabriel Genellina
              Softlab SRL





              _______________ _______________ _______________ _____
              Preguntá. Respondé. Descubrí.
              Todo lo que querías saber, y lo que ni imaginabas,
              está en Yahoo! Respuestas (Beta).
              ¡Probalo ya!


              Comment

              • Simon Forman

                #8
                Re: eval() woes

                rdrink wrote:
                Ok, maybe now I can make some more sense of this, with an example of
                real code (sorry if it's a bit dense):
                This is the basic function...
                >
                def equate(parts,ne w_eq):
                >
                oL = int(parts[0])
                iL = int(parts[1])
                iR = int(parts[2])
                oR = int(parts[3])
                oLoL = int(str(oL)+str (oL))
                oLiL = int(str(oL)+str (iL))
                oLiR = int(str(oL)+str (iR))
                oLoR = int(str(oL)+str (oR))
                iLoL = int(str(iL)+str (oL))
                iLiL = int(str(iL)+str (iL))
                iLiR = int(str(iL)+str (iR))
                iLoR = int(str(iL)+str (oR))
                iRoL = int(str(iR)+str (oL))
                iRiL = int(str(iR)+str (iL))
                iRiR = int(str(iR)+str (iR))
                iRoR = int(str(iR)+str (oR))
                oRoL = int(str(oR)+str (oL))
                oRiL = int(str(oR)+str (iL))
                oRiR = int(str(oR)+str (iR))
                oRoR = int(str(oR)+str (oR))
                >
                new_seed = eval(new_eq)
                return new_seed
                >
                ... into which is passed two items:
                - 'parts' , which is a list e.g ['12','34','56', '78'] (of strings)
                That's a lot of calls to str() to change the parts of parts *back* into
                strings after changing them into ints. Why don't you just say
                something like:

                soL, siL, siR, soR = parts
                oL, iL, iR, oR = map(int, parts)
                oLoL = int(soL + soL)
                oLiL = int(soL + siL)
                ..
                ..
                ..
                etc...
                ?

                If you're calling this function as many times as you indicate below
                (just under a quarter of a million(!) if I understand you correctly,
                480*500 = 240,000) , it might even result in a human-noticeable speed
                up. ;-)
                - and 'new_eq',which is also a string read from a text file, e.g.
                "pow(oLiL,2 )"
                >
                And so...for the first 9 entries (of 480) in the text file where...
                pow(oLiL,2)
                pow(oLiL,2) - oL
                pow(oLiL,2) - iL
                pow(oLiL,2) - iR
                pow(oLiL,2) - oR
                pow(oLiL,2) + oL
                pow(oLiL,2) + iL
                pow(oLiL,2) + iR
                pow(oLiL,2) + oR
                pow(oLiL,2)
                pow(oL - iL,2)
                ... eval() works fine.
                But on the 10th...
                pow(oL - iL,2) - oL
                ... it bombs with the error:
                pow(oL - iL,2) - oL
                Traceback (most recent call last):
                File "the_farmer2.py ", line 264, in ?
                seed = equate(parts,eq uation)
                File "the_farmer2.py ", line 112, in equate
                iL = int(parts[1])
                ValueError: invalid literal for int(): -
                Ok, so there you go. At this point in the program parts[1] is '-',
                which isn't an int literal, so the script raises an exception. One
                very good thing to do here, as others have already mentioned, would be
                to "print parts" at the beginning of your equate() function. That way
                you could see exactly which data are causing the problem.
                >
                And what is interseting/odd is:
                - For the third, '- iL' evaluates fine...
                - as well as the 9th, [where it is nested, oL - iL, inside pow()] ...
                - but in the 10th, where a subtraction is called twice, it doesn't.
                None of this has anything to do with the error you posted. You're not
                even getting as far as calling eval() or pow().

                If you read the traceback carefully, starting at the last line in it
                and working backwards, you'll see that you're calling int() with an
                invalid literal '-', and that this occurs on line 112, in file
                "the_farmer2.py ", in the equate() function. The traceback even
                presents you with a copy of the line in question: "iL = int(parts[1])"
                so you know where the '-' is coming from. It's coming from parts[1].
                Which leads me to believe that the problem is either inside eval() it's
                self, or in the way these variables are being cast... but I can't tell
                which.
                The traceback tells you, unambiguously, that it's the latter, the
                variable cast. That's *why* tracebacks exist, and why python prints
                them by default: to tell you as much as it can about exactly what went
                wrong.
                >
                (BTW, as a footnote: For each of the above 'equations' the function
                equate() was called 500 times... in some cases with the list 'parts'
                equaling things like ['0',2','3','0'], so I have no reason to believe
                that the problem is with the way the list is being passed in... but I
                could be wrong)
                >
                Can anyone see something I can't?
                Learn to read tracebacks. They're your friends.

                Peace,
                ~Simon

                Comment

                • rdrink

                  #9
                  Re: eval() woes

                  Thanks everyone for you thoughtful replies...

                  And yes Simon you are right... I do need to learn how to read
                  'tracebacks' (and de-bugging tools in general)... but you are the first
                  person to give me a step-by-step explination, thank you.

                  And LOL you all caught my dropped single-quote ;-) ....
                  but unfortunately that was just a typo, not generated by my code.

                  And Simon thanks for this....
                  That's a lot of calls to str() to change the parts of parts *back* into
                  strings after changing them into ints. Why don't you just say
                  something like:
                  >
                  soL, siL, siR, soR = parts
                  oL, iL, iR, oR = map(int, parts)
                  oLoL = int(soL + soL)
                  oLiL = int(soL + siL)
                  .
                  .
                  .
                  etc...
                  ?
                  .... I've never used mapping before, so this will be a good start.
                  If you're calling this function as many times as you indicate below
                  (just under a quarter of a million(!) if I understand you correctly,
                  480*500 = 240,000) , it might even result in a human-noticeable speed
                  up. ;-)
                  Oh it get's worse that that... it'll be (possibly) up to 500 times per
                  equation, for 334 equations, for 480 'seed numbers'... 500 * 334 * 480
                  = 80,327,000 calculations =:-o
                  So every little speed up helps!

                  ----
                  Ok, so there you go. At this point in the program parts[1] is '-',
                  which isn't an int literal, so the script raises an exception. One
                  very good thing to do here, as others have already mentioned, would be
                  to "print parts" at the beginning of your equate() function. That way
                  you could see exactly which data are causing the problem.
                  Ok guys I'm not such a noob I didn't try that ;-)
                  but unfortunately it didn't enlighten anything.
                  However, as Simon points out...
                  None of this has anything to do with the error you posted. You're not
                  even getting as far as calling eval() or pow().
                  The traceback tells you, unambiguously, that it's the latter, the
                  variable cast.
                  the one thing I didn't mention (in trying to spare everyone having to
                  read *all* my code) is that the above mentioned list 'parts' of which I
                  am trying to use parts[1] etc, is passed in from another function...
                  and though I have gone over it repaetedly, looking for possible sources
                  of errors, Simons suggestion points to the problem originating there...
                  so I'll just have to keep looking.

                  Unfortunately I am going to have to put this project* away for a while
                  now, so let me just thank everyone again for helping a newcomer (I hope
                  someday I can return the favor) and let's retire this thread.

                  * BTW If any of you are interested in details of the project it's self
                  feel free to email me.

                  Thanks again!

                  Comment

                  Working...