unexplainable python
Dave Angel
davea at ieee.org
Sun Sep 27 00:58:30 EDT 2009
dads wrote:
> When creating a script that converts digits to words I've come across
> some unexplainable python. The script works fine until I use a 5 digit
> number and get a 'IndexError: string index out of range'. After
> looking into it and adding some print calls, it looks like a variable
> changes for no reason. The example beneath is using the digits 34567,
> the _5digit function slices 34 off and passes it to the _2digit
> function, which works with 2 digit strings but the IndexError is
> raised. Please accept my apologies for the explanation, I'm finding it
> hard to put into words. Has anyone any idea why it's acting the way it
> is?
>
> enter number: 34567
> _5digit function used
> 34 before sent to _2digit
> 34 slice when at _2digit function
> 34 before sent to plus_ten function
> 7 slice when at _2digit function
> 7 before sent to plus_ten function
>
>
> from __future__ import print_function
> import sys
>
> class number(object):
>
> def __init__(self, number):
>
> #remove any preceding zero's
> num = int(number)
> self.num = str(num)
> self.num = number
>
> self.single =
> {'0':'zero','1':'one','2':'two','3':'three','4':'four',
>
> '5':'five','6':'six','7':'seven','8':'eight','9':'nine'}
> self.teen = {'11':'eleven','12':'twelve','13':'thirteen',
> '14':'fourteen','15':'fifteen','16':'sixteen',
>
> '17':'seventeen','18':'eighteen','19':'nineteen'}
> self.plus_ten =
> {'10':'ten','20':'twenty','30':'thirty','40':'forty',
> '50':'fifty','60':'sixty','70':'seventy',
> '80':'eighty','90':'ninety'}
> self._translate()
>
> def _translate(self):
>
> fns = [ i for i in number.__dict__ if 'digit' in i ]
> fns.sort()
> fn_name = fns[len(self.num)-1]
> print(fn_name,'function used')
> fn = number.__dict__[fn_name]
> print(fn(self, self.num))
>
>
> def _1digit(self, n):
>
> return self.single[n]
>
> def _2digit(self, n):
>
> print(n, 'slice when at _2digit function')
> if '0' in self.num:
> return self.plus_ten[n]
> elif self.num[0] == '1':
> return self.teen[n]
> else:
> print(n,'before sent to plus_ten function')
> var = self.plus_ten[n[0]+'0'] + ' ' + self._1digit(n[1])
> return var
>
> def _3digit(self, n):
>
> var = self._1digit(n[0]) + ' hundred and ' + self._2digit(n
> [1:])
> return var
>
> def _4digit(self, n):
>
> var = self._1digit(n[0]) + ' thousand ' + self._3digit(n[1:])
> return var
>
>
> def _5digit(self, n):
>
> print(n[:2],'before sent to _2digit')
> var = self._2digit(n[:2]) + ' thousand ' + self._4digit(n[2:])
> return var
>
> class control(object):
>
> def __init__(self):
> pass
>
> def data_input(self):
>
>
> while True:
> i = raw_input('enter number: ')
> if i == 's':
> break
> #try:
> n = number(i)
> #except:
> # print('not a number')
>
>
> if __name__ in '__main__':
> c = control()
> c.data_input()
>
>
This program would be much simpler if you didn't use classes. So far,
they don't contribute anything but obfuscation.
Random observations:
in _2digit(), line:
if '0' in self.num
test makes no sense. Presumably what you really are trying to check is
whether the low digit of n is zero. But in fact you're checking whether
any of the 5 digits of the whole number is 0.
in _5digit(), line:
var = self._2digit(n[:2]) + ' thousand ' + self._4digit(n[2:])
should be calling self._3digit(), not self._4digit(). I presume that's
the immediate cause of your error. You'll notice that _4digit() calls
_2digit(), but by that time the problem has already been triggered.
DaveA
More information about the Python-list
mailing list