convert string number to real number - ValueError: invalid literal

D

davidj411

i am parsing a cell phone bill to get a list of all numbers and the
total talktime spend on each number.

i already have a unique list of the phone numbers.
now i must go through the list of numbers and add up the totals for
each number.
on the bill, each line has a few fields,one field containing the phone
number, another field containing the number of minutes on that call.
the bill is comma delimited.

here is the function i wrote to get one number at a time's total
talktime.

def getsinglenumbertalktime(number,talktime):
for line in file[0:-2]:
if number in line:
li=line.split(',')
if len(li)==6 and li[5]!="Minutes" :
print "talktime type: " + str(type (talktime))
#li[5]=fpformat.fix(li[5],0)

print li[5] + "li[5] type: " + str(type(li[5]))
newvar = int(li[5])
print (type(newvar))
print li[5]
talktime = talktime + li[5]
return talktime

here is the output with error that i get back.

talktime type: <type 'int'>
"2"li[5] type: <type 'str'>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\path\inprog\all_t_mob_nums.py", line 74, in <module>
getsinglenumbertalktime('"800-218-2644"',talktime)
File "c:\path\inprog\all_t_mob_nums.py", line 66, in
getsinglenumbertalktime
newvar = int(li[5])
ValueError: invalid literal for int() with base 10: '"2"'


here is the question:

How can i convert a string number like "2" to a true number that can
be added.
I have tried using pfformat, float(), and int() - all with no good
results.
this seems like is should be simple, but it just plain isn't.


I actually found a good solution.
basically, take each entry and add it to a list.
then iterate through the list , converting each item to int().
then add them to sum them all up.

FINAL SOLUTION:
def getsinglenumbertalktime(number,talktime):
num_of_calls=0
num_mins=[]
for line in file[0:-2]:
#print "LINE: " + line
#print number in line
if number in line:
num_of_calls += 1
#print number,num_of_calls
li=line.strip("\n")
#print "stripped:" + line
li=li.split(',')
#print "split: " + str(li)
#print "len of li: " + str(len(li)) + str(num_of_calls)
if len(li)==7 and li[5]!="Minutes" :
#print "talktime type: " + str(type (talktime))
#print li[4] + "li[4] type: " + str(type(li[5]))
#newvar = fpformat.fix(li[4],0)
#print (type(newvar))
#print "len 7: " + str(type(li[6]))
num_mins.append(li[6])
#talktime = talktime + int(a)

if len(li)==6 and li[5]!="Minutes" :
#print "talktime type: " + str(type (talktime))
#print li[5] + "li[5] type: " + str(type(li[5]))
#newvar = fpformat.fix(li[4],0)
#print (type(newvar))
#print "len 6: " + str(type(li[5]))
num_mins.append(li[5])
#talktime = talktime + int(a)
#return talktime , num_of_calls
x=0
#print "this" + str(number) + str(num_mins)
for a in num_mins:
b=int(a)
x=x+b
print str(number), str(x), str(type(x))

output should look like this (parts of script are not included)
555-555-5555 replaced the innocent :p):
555-555-5555 19 <type 'int'>
555-555-5555 6 <type 'int'>
555-555-5555 3 <type 'int'>
555-555-5555 3 <type 'int'>
555-555-5555 2 <type 'int'>
555-555-5555 52 <type 'int'>
 
D

D'Arcy J.M. Cain

ValueError: invalid literal for int() with base 10: '"2"'


here is the question:

How can i convert a string number like "2" to a true number that can
be added.

You have to get rid of the double quotes first.
 
L

Larry Bates

davidj411 said:
i am parsing a cell phone bill to get a list of all numbers and the
total talktime spend on each number.

i already have a unique list of the phone numbers.
now i must go through the list of numbers and add up the totals for
each number.
on the bill, each line has a few fields,one field containing the phone
number, another field containing the number of minutes on that call.
the bill is comma delimited.

here is the function i wrote to get one number at a time's total
talktime.

def getsinglenumbertalktime(number,talktime):
for line in file[0:-2]:
if number in line:
li=line.split(',')
if len(li)==6 and li[5]!="Minutes" :
print "talktime type: " + str(type (talktime))
#li[5]=fpformat.fix(li[5],0)

print li[5] + "li[5] type: " + str(type(li[5]))
newvar = int(li[5])
print (type(newvar))
print li[5]
talktime = talktime + li[5]
return talktime

here is the output with error that i get back.

talktime type: <type 'int'>
"2"li[5] type: <type 'str'>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\path\inprog\all_t_mob_nums.py", line 74, in <module>
getsinglenumbertalktime('"800-218-2644"',talktime)
File "c:\path\inprog\all_t_mob_nums.py", line 66, in
getsinglenumbertalktime
newvar = int(li[5])
ValueError: invalid literal for int() with base 10: '"2"'


here is the question:

How can i convert a string number like "2" to a true number that can
be added.
I have tried using pfformat, float(), and int() - all with no good
results.
this seems like is should be simple, but it just plain isn't.


I actually found a good solution.
basically, take each entry and add it to a list.
then iterate through the list , converting each item to int().
then add them to sum them all up.

FINAL SOLUTION:
def getsinglenumbertalktime(number,talktime):
num_of_calls=0
num_mins=[]
for line in file[0:-2]:
#print "LINE: " + line
#print number in line
if number in line:
num_of_calls += 1
#print number,num_of_calls
li=line.strip("\n")
#print "stripped:" + line
li=li.split(',')
#print "split: " + str(li)
#print "len of li: " + str(len(li)) + str(num_of_calls)
if len(li)==7 and li[5]!="Minutes" :
#print "talktime type: " + str(type (talktime))
#print li[4] + "li[4] type: " + str(type(li[5]))
#newvar = fpformat.fix(li[4],0)
#print (type(newvar))
#print "len 7: " + str(type(li[6]))
num_mins.append(li[6])
#talktime = talktime + int(a)

if len(li)==6 and li[5]!="Minutes" :
#print "talktime type: " + str(type (talktime))
#print li[5] + "li[5] type: " + str(type(li[5]))
#newvar = fpformat.fix(li[4],0)
#print (type(newvar))
#print "len 6: " + str(type(li[5]))
num_mins.append(li[5])
#talktime = talktime + int(a)
#return talktime , num_of_calls
x=0
#print "this" + str(number) + str(num_mins)
for a in num_mins:
b=int(a)
x=x+b
print str(number), str(x), str(type(x))

output should look like this (parts of script are not included)
555-555-5555 replaced the innocent :p):
555-555-5555 19 <type 'int'>
555-555-5555 6 <type 'int'>
555-555-5555 3 <type 'int'>
555-555-5555 3 <type 'int'>
555-555-5555 2 <type 'int'>
555-555-5555 52 <type 'int'>

If the file is quote and comma delimited, you should be using the csv module to
do your reading and stripping of the quotes. Should make things MUCH easier.

-Larry
 
S

SPGIMail

You have to get rid of the double quotes first.

you mean replace them with nothing?

li[4].replace('"','')

once i do that, i should be able to use them as numbers.
 
T

Terry Reedy

|i am parsing a cell phone bill to get a list of all numbers and the
| total talktime spend on each number.
|
| i already have a unique list of the phone numbers.
| now i must go through the list of numbers and add up the totals for
| each number.

| here is the function i wrote to get one number at a time's total
| talktime.
|
| def getsinglenumbertalktime(number,talktime):
| for line in file[0:-2]:
....
| | talktime = talktime + li[5]
| return talktime

It would appear that you are calling this function and rescanning scanning
file for each number. It would be more efficient to scan the file once,
for each line parsing out the number and minutes and incrementing the
minutes for that number.

Also, if you had printed repr(li[5]) and len(li[5]) instead of or in
addition to just li[5] (which prints str(li[5]),
"2" '"2"' 3

you might have seen for yourself the problem that the string contains quote
marks and not just digits. Repr and len are useful debugging aids.

tjr
 
D

D'Arcy J.M. Cain

You have to get rid of the double quotes first.

you mean replace them with nothing?

li[4].replace('"','')

Sure, that will do. However, look at the csv module for another way of
handling this.
once i do that, i should be able to use them as numbers.

You still need to apply int() or float() to the result.
 
G

George Sakkis

i am parsing a cell phone bill to get a list of all numbers and the
total talktime spend on each number.

(snipped)

I actually found a good solution.
(snipped)

If you post 1-2 samples of the cell phone bill input, I am sure you'll
get much better solutions in terms of clarity, simplicity and
elegance, commonly known as "pythonicity" :)

George
 
G

Gabriel Genellina

i used the csv module and saved its contents to a list.

['Date', 'No.', 'Description', 'Debit', 'Credit']
['3/17/2006', '5678', 'ELECTRONIC PAYMENT', '', '11.45']
['3/04/2007', '5678', 'THE HOME DEPOT 263 SomeCity FL', '', '25.40']


the credit/debit fields are strings.
what should i have done within the CSV module to make numbers appear as
numbers?
how can i remove the quotes to make them numbers? i realize i posted a
solution to this once before (same posting thread) but i am thinking
there
is a better method.

What do you want to do with those empty strings? Convert them to zeros?
Suppose your list is named `rows`:

for i,row in enumerate(rows):
if not i: continue # skip titles
row[3] = float(row[3] or 0)
row[4] = float(row[4] or 0)
 
K

Kam-Hung Soh

David said:
i used the csv module and saved its contents to a list.

['Date', 'No.', 'Description', 'Debit', 'Credit']
['3/17/2006', '5678', 'ELECTRONIC PAYMENT', '', '11.45']
['3/04/2007', '5678', 'THE HOME DEPOT 263 SomeCity FL', '', '25.40']


the credit/debit fields are strings.
what should i have done within the CSV module to make numbers appear as
numbers?
how can i remove the quotes to make them numbers? i realize i posted a
solution to this once before (same posting thread) but i am thinking
there is a better method.

There doesn't seem to be a way to describe how specific columns should
be processed in the csv module. You could define a conversion function
that "guesses" the best conversion, for example:

def str2num(datum):
try:
return int(datum)
except:
try:
return float(datum)
except:
return datum

for row in csv.reader(file(r'Transaction.csv')):
[str2num(cell) for cell in row]

['Date', 'No.', 'Description', 'Debit', 'Credit']
['3/17/2006', 5678, 'ELECTRONIC PAYMENT', '', 11.449999999999999]
['3/04/2007', 5678, 'THE HOME DEPOT 263 SomeCity FL', '',
25.399999999999999]
 
D

davidj411

David said:
i used the csv module and saved its contents to a list.
['Date', 'No.', 'Description', 'Debit', 'Credit']
['3/17/2006', '5678', 'ELECTRONIC PAYMENT', '', '11.45']
['3/04/2007', '5678', 'THE HOME DEPOT 263 SomeCity FL', '', '25.40']
the credit/debit fields are strings.
what should i have done within the CSV module to make numbers appear as
numbers?
how can i remove the quotes to make them numbers? i realize i posted a
solution to this once before (same posting thread) but i am thinking
there is a better method.

There doesn't seem to be a way to describe how specific columns should
be processed in the csv module.  You could define a conversion function
that "guesses" the best conversion, for example:

def str2num(datum):
        try:
                return int(datum)
        except:
                try:
                        return float(datum)
                except:
                        return datum

for row in csv.reader(file(r'Transaction.csv')):
        [str2num(cell) for cell in row]

['Date', 'No.', 'Description', 'Debit', 'Credit']
['3/17/2006', 5678, 'ELECTRONIC PAYMENT', '', 11.449999999999999]
['3/04/2007', 5678, 'THE HOME DEPOT 263 SomeCity FL', '',
25.399999999999999]

I like the str2num function approach, but then i get left with a float
that has more than 2 decimal spaces , i.e. 11.50 becomes
11.449999999999999 and round will not fix that.
 
M

Matthias Bläsing

Am Wed, 28 May 2008 10:41:51 -0700 schrieb davidj411:
I like the str2num function approach, but then i get left with a float
that has more than 2 decimal spaces , i.e. 11.50 becomes
11.449999999999999 and round will not fix that.

Welcome to the wonderful world of floating point numbers. For your usage
you want 10-based numbers. Have a look at the decimal module:
Decimal("13.00")

HTH

Matthias
 
K

Kam-Hung Soh

Matthias said:
Am Wed, 28 May 2008 10:41:51 -0700 schrieb davidj411:


Welcome to the wonderful world of floating point numbers. For your usage
you want 10-based numbers. Have a look at the decimal module:

Decimal("13.00")

HTH

Matthias

Thanks for the tip, Matthias. I knew that there had to be a way to
handle arbitrary precision numbers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,829
Latest member
PIXThurman

Latest Threads

Top