#1
  1. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Meriden, Connecticut
    Posts
    1,797
    Rep Power
    154

    Python Val Function (Resolved)


    Guided by the MSDN description of what Val() does in VB6, I created my own like copy of it in Python. However, I've ran into one error, here is the MSDN dexcription:
    Code:
    Numeric or Currency data type. VAL( ) returns the numbers in the character expression from left to right until a non-numeric character is encountered. Leading blanks are ignored. VAL( ) returns 0 if the first character of the character expression is not a number, a dollar sign ($), a plus sign (+), or minus sign (-). You can control the result of VAL( ) by issuing the SET DECIMALS command before using the VAL( ) function.
    Here is my code:
    Code:
    def val(data):
        not_equal = []
        got_end = [False]
        end_char = [0]
        start_char = [0]
        i_list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '$', '+', '-']
        for i in i_list:
            if got_end[0] == False:
                if data[0] != i:
                    not_equal.append(i)
                    got_end[0] = True
            else:
                if data[0] != i:
                    not_equal.append(i)
        for i in i_list:
            if i not in not_equal:
                start_char[0] = i
        for i in data:
            if i not in i_list:
                end_char[0] = i
                break
        for i in data:
            return int(data[data.find(start_char[0]):data.find(end_char[0])])
            break
    Here is how I tested out my code:
    Code:
    >>> val('45f')
    45
    >>> val('4')
    Traceback (most recent call last):
      File "<pyshell#101>", line 1, in ?
        val('4')
      File "C:\Documents and Settings\Master\Desktop\val.py", line 23, in val
        return int(data[data.find(start_char[0]):data.find(end_char[0])])
    TypeError: expected a character buffer object
    >>> val('b')
    Traceback (most recent call last):
      File "<pyshell#102>", line 1, in ?
        val('b')
      File "C:\Documents and Settings\Master\Desktop\val.py", line 23, in val
        return int(data[data.find(start_char[0]):data.find(end_char[0])])
    TypeError: expected a character buffer object
    As you can see, if I enter in only a number or character, it receives that error, I do not want this. Any help is appreciated.
    You may have noticed, I left our the return as 0 part. I didn't feel that I needed this.

    Update: I figured it out, I just added in a try statement.
    Last edited by †Yegg†; March 26th, 2005 at 03:16 PM.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2005
    Posts
    78
    Rep Power
    10
    Originally Posted by †Yegg†
    Guided by the MSDN description of what Val() does in VB6, I created my own like copy of it in Python.
    A few notes:
    1/ strings are sequences just like lists, so you could use:
    Code:
    for c in  "1234567890$+-":
    That said, you DON'T want to be doing things the way you're doing them since you've got things round the wrong way - At worst, you should be looping on each character of txt, and testing that it is a digit [eg: try printing "1".isdigit()] - the "$+-" is a special case and should only be tested for on the first character.

    2/ If you aren't worried about getting the full functionality of VB'sVal() function (ie: you're not worried about needing to convert hex numbers, comma separated numbers, space separated numbers, etc.) you can explicitly test the first character then just loop the rest:
    Code:
    if txt[0] in "$+-":
        txt = txt[1:]
    while txt:
        try:
            f = float(txt)
            i = int(f)
            if f == i:
                return i
            return f       
        except TypeError:
            txt = txt[:-1]
    return 0
    --OH.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Posts
    624
    Rep Power
    34
    you can explicitly test the first character then just loop the rest:
    What if the string is

    "-$20" ?

    Code:
    f = float(txt)
    i = int(f)
    How much of val() are you giving up?

    "VAL( ) returns the numbers in the character expression from left to right until a non-numeric character is encountered."

    This dies if the string has anything else in it at all.

    Code:
    got_end = [False]
    if got_end[0] == False:
    Why do you seem to make all your boolean tests into a one-element list?

    Code:
    i_list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '$', '+', '-']
    No decimal point allowed?

    Code:
        for i in data:
            return int(data[data.find(start_char[0]):data.find(end_char[0])])
            break
    You can only return once, so putting it in a for loop just makes it return the first time through. Once it has returned, it can never call 'break' afterwards.


    I've attached my attempt, but it's quite long and not great.
    It doesn't handle numbers like 1,000,000 (grouping), nor international currencies (£, etc), nor locales where they use other characters instead of a decimal point (e.g. comma - I tried to google for how to handle this and got nowhere), and it doesn't handle hex / other bases.

    And, on top of that, and despite using unittest, I think it should be much more formal - define an allowable grammar for the input string and build a finite-state-machine parser or something.
  6. #4
  7. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Meriden, Connecticut
    Posts
    1,797
    Rep Power
    154
    I left out the decimal points. I didn't think I would ever come to a time where I would need it. Also, I've already completed this task, here is the new code below:
    Code:
    def val(data):
        not_equal = []
        got_end = [False]
        end_char = [0]
        start_char = [0]
        i_list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '$', '+', '-']
        a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
        for i in i_list:
            if got_end[0] == False:
                if data[0] != i:
                    not_equal.append(i)
                    got_end[0] = True
            else:
                if data[0] != i:
                    not_equal.append(i)
        for i in i_list:
            if i not in not_equal:
                start_char[0] = i
        for i in data:
            if i not in i_list:
                end_char[0] = i
                break
        for i in data:
            if i in a_list:
                return int(data)
                break
            else:
                try:
                    return int(data[data.find(start_char[0]):data.find(end_char[0])])
                    break
                except:
                    return 0
                    break
    I'm sure there can be improvements though. As for me using a list, that's just they first way I thought of how to make this work, so I just left it alone at that.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    1
    Rep Power
    0

    Function val ... I Teste and Work


    I saw your code for the function val () but does not work that way because you're using the int () to convert the result of your function and also these missing something that they teach all the basics programmers is to use unused art anointings or internal, that are made for special situations that meet this need we have x or y moment.

    He visto tu codigo para la funcion val() pero de esa forma no funciona por que estas usando el int() para transformar el resultado de tu funcion y tambien estas omitiendo algo que enseñan a todos los programadores es usar lo basico sin usar unciones prediseñadas o internas, que estan hechas para situaciones especiales que cumplan con esa necesidad que se tiene x ó y momento.

    Code python:
    Code:
    def val(data):
        y=0
        nst=""
        dlist = ['0','1', '2', '3', '4', '5', '6', '7', '8', '9']
        for x in data:
            for i in dlist:
                if x == i:
                    nst=nst+x
        n=len(nst)
        dcont=n
        acum=0
        for z in range(n):
            y=0
            for i in dlist:
                if nst[z] == i:
                    d=y
                    mult=1
                    dcont=dcont-1
                    for j in range(dcont):
                        mult=mult*10
                    acum=acum+(d*mult)
                y=y+1
                
        return acum

IMN logo majestic logo threadwatch logo seochat tools logo