Re: String/Number Conversion

2008-09-06 Thread Scott David Daniels

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

2008-09-06 Thread Andreas Hofmann

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

2008-09-06 Thread bearophileHUGS
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

2008-09-06 Thread John Machin
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

2008-09-06 Thread John Machin
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

2008-09-06 Thread Wojtek Walczak
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

2008-09-06 Thread josh logan
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

2008-09-06 Thread Andreas Hofmann

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