Re: String/Number Conversion
Andreas Hofmann wrote: I've got some strings, which only contain numbers plus eventually one character as si-postfix (k for kilo, m for mega, g for giga). I'm trying to convert those strings to integers, with this function: Why bother to always switch the case if you only use a few values? Also, the Python style is to do an operation and handle failures, rather than test first. Try something like: _units = dict(K=1000, M=100, G=10, k=1000, m=100, g=10) def eliminate_postfix(value): try: return _units[value[-1]] * int(value[: -1]) except (TypeError, KeyError): return int(value) If you normally do not have the suffixes, then switch it around: def eliminate_postfix(value): try: return int(value) except ValueError: return _units[value[-1]] * int(value[: -1]) If this is really SI units, you likely are doing real measurements, so I'd consider using "float" instead of "int" in the above. --Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: String/Number Conversion
Thanks a lot, I got it working now. Thanks also to the other guys, your numerous hints were really valuable! Kind regards, Andy John Machin schrieb: On Sep 7, 7:04 am, Andreas Hofmann <[EMAIL PROTECTED]> wrote: Hello Folks! I've got a little problem here, which which really creeps me out at the moment. I've got some strings, which only contain numbers plus eventually one character as si-postfix (k for kilo, m for mega, g for giga). I'm trying to convert those strings to integers, with this function: def eliminate_postfix(value): if type(value) is str: Don't use "is" unless you are really sure that "==" won't do the job. Better idiom: if isinstance(value, str): value.upper() This causes your "mult is always 1" problem. You need: value = value.upper() Why? Because strings are immutable. String methods like upper return a new string, they don't change the existing string. if value.endswith('K'): mult = 1000 elif value.endswith('M'): mult = 100 elif value.endswith('G'): mult = 10 else: mult = 1 if mult is 1: Lose "is". In fact, lose the whole "if" statement. See below. value = string.atoi(value) Don't use deprecated functions from the string module. Use the built- in float function to convert from text. else: value = string.atoi(value[:-1]) * mult return value Those last few statements look somewhat tortuous. Try this: else: # mult would be 1, but we don't need it return float(value) return float(value[:-1]) * mult HTH, John -- http://mail.python.org/mailman/listinfo/python-list
Re: String/Number Conversion
Andreas Hofmann, there are several problems in your code: > if type(value) is str: Better to use isinstance() and to compare it with basestring instead. > value.upper() This does nothing, python strings are immutable, so they don't get changed in-place, so you have to assign that result to some name, possibly a different name. I also suggest you to strip the uppered string, to remove head/tail spaces. Your indenting isn't much good, I suggest you to use only four spaces for each indent (you can also use one tab, but I don't suggest this). > if value.endswith('K'): > mult = 1000 > elif value.endswith('M'): > mult = 100 > elif value.endswith('G'): > mult = 10 > else: > mult = 1 This is okay. You can also put those key-values in a dict, that you can access with the get method with a default 1, but it may be overkill. > if mult is 1: > value = string.atoi(value) > else: > value = string.atoi(value[:-1]) * mult > return value Instead of using string.atoi, use the int() builtin. If you follow my suggestions you will have a function that works in many situations. It will raise exceptions in other situations, but that's good. But to not need much of our help in your future code I suggest you to use the Python shell and test every line you write. I also suggest you to start right now using tests, for example like this: def eliminate_postfix(value): """ >>> el_post = eliminate_postfix >>> el_post(1) 1 >>> el_post("100") 100 >>> el_post("") Traceback (most recent call last): ... ValueError: invalid literal for int() with base 10: '' >>> el_post("100g") 1000L >>> el_post("100G ") 1000L >>> el_post("100 G ") 1000L >>> el_post("100hg") Traceback (most recent call last): ... ValueError: invalid literal for int() with base 10: '100H' >>> el_post(" 100 k ") 10 >>> el_post(" 100m") 1 >>> el_post(u"100m") 1 """ ... function code ... if __name__ == "__main__": import doctest doctest.testmod() print "Doctests done.\n" That will improve your coding a LOT, reducing your bug count, etc. Bye, bearophile -- http://mail.python.org/mailman/listinfo/python-list
Re: String/Number Conversion
On Sep 7, 7:29 am, Wojtek Walczak <[EMAIL PROTECTED]> wrote: > On Sat, 06 Sep 2008 23:04:14 +0200, Andreas Hofmann wrote: > > if mult is 1: > > ^^ > You're testing for identity, not for equality. > Change it to "if mult == 1". Is it alright now? > Although he definitely should not be using "is" here, that can not be the problem if he is using CPython. As an optimisation, small integers are interned i.e. for each small integer, there is only one object. >>> a = 1 >>> b = 1 >>> a is 1 True >>> b is 1 False >>> id(a) 10897704 >>> id(1) 10897704 >>> id(b) 11893004 >>> id(1) 12633044 >>> -- http://mail.python.org/mailman/listinfo/python-list
Re: String/Number Conversion
On Sep 7, 7:04 am, Andreas Hofmann <[EMAIL PROTECTED]> wrote: > Hello Folks! > > I've got a little problem here, which which really creeps me out at the > moment. > I've got some strings, which only contain numbers plus eventually one > character as si-postfix (k for kilo, m for mega, g for giga). I'm trying > to convert those strings to integers, with this function: > > def eliminate_postfix(value): > if type(value) is str: Don't use "is" unless you are really sure that "==" won't do the job. Better idiom: if isinstance(value, str): > value.upper() This causes your "mult is always 1" problem. You need: value = value.upper() Why? Because strings are immutable. String methods like upper return a new string, they don't change the existing string. > if value.endswith('K'): > mult = 1000 > elif value.endswith('M'): > mult = 100 > elif value.endswith('G'): > mult = 10 > else: > mult = 1 > > if mult is 1: Lose "is". In fact, lose the whole "if" statement. See below. > value = string.atoi(value) Don't use deprecated functions from the string module. Use the built- in float function to convert from text. > else: > value = string.atoi(value[:-1]) * mult > return value Those last few statements look somewhat tortuous. Try this: else: # mult would be 1, but we don't need it return float(value) return float(value[:-1]) * mult HTH, John -- http://mail.python.org/mailman/listinfo/python-list
Re: String/Number Conversion
On Sat, 06 Sep 2008 23:04:14 +0200, Andreas Hofmann wrote: Hi, > I've got a little problem here, which which really creeps me out at the > moment. > I've got some strings, which only contain numbers plus eventually one > character as si-postfix (k for kilo, m for mega, g for giga). I'm trying > to convert those strings to integers, with this function: > if mult is 1: ^^ You're testing for identity, not for equality. Change it to "if mult == 1". Is it alright now? -- Regards, Wojtek Walczak, http://tosh.pl/gminick/ -- http://mail.python.org/mailman/listinfo/python-list
Re: String/Number Conversion
On Sep 6, 5:04 pm, Andreas Hofmann <[EMAIL PROTECTED]> wrote: > Hello Folks! > > I've got a little problem here, which which really creeps me out at the > moment. > I've got some strings, which only contain numbers plus eventually one > character as si-postfix (k for kilo, m for mega, g for giga). I'm trying > to convert those strings to integers, with this function: > > def eliminate_postfix(value): > if type(value) is str: > value.upper() > if value.endswith('K'): > mult = 1000 > elif value.endswith('M'): > mult = 100 > elif value.endswith('G'): > mult = 10 > else: > mult = 1 > > if mult is 1: > value = string.atoi(value) > else: > value = string.atoi(value[:-1]) * mult > return value > > The problem is as follows: Everytime a string with a postfix should get > converted, mult does not get set properly. It is always 1. Does anyone > have an idea how to fix this? I just don't see it, maybe because I'm > pretty new to python or because I'm just blind I would be really greatful. > > Kind regards, > Andy Hello, 1. You call value.upper(), but you do not capture the results of that method. Strings are immutable in Python. >> value = value.upper() 2. You should use == instead of "is" in the comparison of mult being 1. >> if mult == 1: -- http://mail.python.org/mailman/listinfo/python-list
String/Number Conversion
Hello Folks! I've got a little problem here, which which really creeps me out at the moment. I've got some strings, which only contain numbers plus eventually one character as si-postfix (k for kilo, m for mega, g for giga). I'm trying to convert those strings to integers, with this function: def eliminate_postfix(value): if type(value) is str: value.upper() if value.endswith('K'): mult = 1000 elif value.endswith('M'): mult = 100 elif value.endswith('G'): mult = 10 else: mult = 1 if mult is 1: value = string.atoi(value) else: value = string.atoi(value[:-1]) * mult return value The problem is as follows: Everytime a string with a postfix should get converted, mult does not get set properly. It is always 1. Does anyone have an idea how to fix this? I just don't see it, maybe because I'm pretty new to python or because I'm just blind I would be really greatful. Kind regards, Andy -- http://mail.python.org/mailman/listinfo/python-list