Re: [Tutor] Projects (fwd)

2008-01-25 Thread Ricardo Aráoz
Tiger12506 wrote:
 Nope, if you read the code you'll see the only mapping done is up to 20
 and then by tens up to 100, that's all.
 The same code could be used with a list, you'd only have to change the
 exception name.
 
 I see. There were ... in between each of the tens entries which I took to 
 mean that big huge dictionary but left out some values in email for 
 simplicity. I feel ashamed for not recognizing that the ellipses where 
 there for some other purpose. ;-)
 

Checked my mail and yes, it was not outright clear what I meant in the
dictionary, sorry. Anyway if you check the rest of the code you'll see
it works as I said and you don't use the intermediate values between the
tens. As usual I learned something from the exercise, I thought that
indexed access would be faster than list access, didn't think lists
where implemented as C arrays (because they have no fixed size), now I
can see tuples will be faster and will save memory because memory will
not have to be reserved in chunks.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-24 Thread Ricardo Aráoz
Tiger12506 wrote:
 Isn't dictionary access faster than list access? Why are three lists
 'much more efficient'?
 
 Oh no, no, no.  Dictionaries are faster when you are *searching through* for 
 a particular value. If you already know the index of the item in the list, 
 lists are much faster.
 
 Dictionaries are hash based. Somewhere it has to calculate the hash of the 
 key you give it...
 These three lists are more efficient in terms of size/output ratio. It 
 appeared as if the dictionary that was presented as an example was just 
 going to map one to one all of the values from zero to 999,999 (to match my 
 list version capabilities). Not only is that bad programming style, it's 
 just plain unecessary. 

Nope, if you read the code you'll see the only mapping done is up to 20
and then by tens up to 100, that's all.
The same code could be used with a list, you'd only have to change the
exception name.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-23 Thread Danny Yoo
Hi Jason,


Looking back at that Java code:


static String convertDigitToEnglish(int d)  {
switch ( d )
{
   case 1: return one;
   case 2: return two;
   case 3: return three;
   case 4: return four;
   case 5: return five;
   case 6: return six;
   case 7: return seven;
   case 8: return eight;
   case 9: return nine;
   default: return \nFatal Error!\n; // should I abort pgm?
} // end of switch
   } // end of convertDigitToEnglis



Frankly, this seems silly to me.  First, it ignores zero, which is a cardinal 
sin.  I'm being somewhat serious about this: functions should do what they say, 
and that function isn't.


But the code could also be written much more tightly as:


  static String digitToString(int n) {
 String[] words = {zero, one, two, three, four,
  five, six, seven, eight, nine};
 if (0 = n  n  10) {
 return words[n];
 }
 throw new IllegalArgumentException(input not a single digit);
 }


I don't mean to make this post so Java-centric; it just seems a little unfair 
to compare a bad Java routine to a good Python routine.  :) Writing an 
equivalent in Python is also pretty straightforward:

#
## Pseudocode: just a sketch
def digitToString(n):
  words = [zero, one, ...]
  if 0 = n  10:
  return words[n]
 ...
#

Like dictionaries, the list data structure works pretty well for key/value 
lookup if the input key is a small number.


Good luck!

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-23 Thread Ricardo Aráoz
Danny Yoo wrote:
 Hi Jason,
 
 
 Looking back at that Java code:
 
 
 static String convertDigitToEnglish(int d)  {
 switch ( d )
 {
case 1: return one;
case 2: return two;
case 3: return three;
case 4: return four;
case 5: return five;
case 6: return six;
case 7: return seven;
case 8: return eight;
case 9: return nine;
default: return \nFatal Error!\n; // should I abort pgm?
 } // end of switch
} // end of convertDigitToEnglis
 
 
 
 Frankly, this seems silly to me.  First, it ignores zero, which is a cardinal 
 sin.  I'm being somewhat serious about this: functions should do what they 
 say, 
 and that function isn't.
 
 
 But the code could also be written much more tightly as:
 
 
   static String digitToString(int n) {
String[] words = {zero, one, two, three, four,
 five, six, seven, eight, nine};
if (0 = n  n  10) {
return words[n];
}
throw new IllegalArgumentException(input not a single digit);
  }
 
 
 I don't mean to make this post so Java-centric; it just seems a little unfair 
 to compare a bad Java routine to a good Python routine.  :) Writing an 
 equivalent in Python is also pretty straightforward:
 
 #
 ## Pseudocode: just a sketch
 def digitToString(n):
   words = [zero, one, ...]
   if 0 = n  10:
   return words[n]
  ...
 #
 
 Like dictionaries, the list data structure works pretty well for key/value 
 lookup if the input key is a small number.
 
 
 Good luck!
 

up to a thousand (not tested)

words = {0:'zero', 1:'one', 2:'two', 3:'three', ... , 10:'ten',
 11:'eleven', 12:'twelve', ..., 19:'nineteen',
 20:'twenty', , 90:'ninety', 100:'one hundred' }
def digitToString(n) :
try :
retStr = words[n]
except KeyError :
if n  100 :
retStr = (digitToString(n // 100)
 + ' hundred and '
 + digitToString(n % 100))
else :
retStr = (digitToString(n - (n % 10))
 + ' '
 + digitToString(n % 10))

return retStr

HTH
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-23 Thread Tiger12506
 up to a thousand (not tested)

 words = {0:'zero', 1:'one', 2:'two', 3:'three', ... , 10:'ten',
 11:'eleven', 12:'twelve', ..., 19:'nineteen',
 20:'twenty', , 90:'ninety', 100:'one hundred' }
 def digitToString(n) :
try :
retStr = words[n]
except KeyError :
if n  100 :
retStr = (digitToString(n // 100)
 + ' hundred and '
 + digitToString(n % 100))
else :
retStr = (digitToString(n - (n % 10))
 + ' '
 + digitToString(n % 10))

return retStr

This could be written much more efficiently. It can be done with only these 
lists~
ones = 
['zero','one','two','three','four','five','six','seven','eight','nine']
teens = 
['ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen']
tens = 
['','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety']
hundstr = 'hundred'
thousand = 'thousand'

Exercise for reader to make it work ;-) Unless of course you genuinely want 
to see my code...
Current range 0 - 999,999Easily extendable to millions, trillions, 
billions, etc. 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-23 Thread Ricardo Aráoz
Tiger12506 wrote:
 up to a thousand (not tested)

 words = {0:'zero', 1:'one', 2:'two', 3:'three', ... , 10:'ten',
 11:'eleven', 12:'twelve', ..., 19:'nineteen',
 20:'twenty', , 90:'ninety', 100:'one hundred' }
 def digitToString(n) :
try :
retStr = words[n]
except KeyError :
if n  100 :
retStr = (digitToString(n // 100)
 + ' hundred and '
 + digitToString(n % 100))
else :
retStr = (digitToString(n - (n % 10))
 + ' '
 + digitToString(n % 10))

return retStr
 
 This could be written much more efficiently. It can be done with only these 
 lists~
 ones = 
 ['zero','one','two','three','four','five','six','seven','eight','nine']
 teens = 
 ['ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen']
 tens = 
 ['','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety']
 hundstr = 'hundred'
 thousand = 'thousand'
 

Isn't dictionary access faster than list access? Why are three lists
'much more efficient'?

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-23 Thread Tiger12506
 This could be written much more efficiently. It can be done with only 
 these
 lists~
 ones =
 ['zero','one','two','three','four','five','six','seven','eight','nine']
 teens =
 ['ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen']

What is it with me and mistakes lately? These two lists above should be 
combined into one. Saves a couple of range checks in the program.

:-{ 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-23 Thread Tiger12506
 Isn't dictionary access faster than list access? Why are three lists
 'much more efficient'?

Oh no, no, no.  Dictionaries are faster when you are *searching through* for 
a particular value. If you already know the index of the item in the list, 
lists are much faster.

Dictionaries are hash based. Somewhere it has to calculate the hash of the 
key you give it...
These three lists are more efficient in terms of size/output ratio. It 
appeared as if the dictionary that was presented as an example was just 
going to map one to one all of the values from zero to 999,999 (to match my 
list version capabilities). Not only is that bad programming style, it's 
just plain unecessary. 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-23 Thread John Fouhy
On 24/01/2008, Ricardo Aráoz [EMAIL PROTECTED] wrote:
 Isn't dictionary access faster than list access? Why are three lists
 'much more efficient'?

Well, not necessarily.

If you want a dictionary, you could use a list of tuples:

myDict = [('a', 'one'), ('b', 'two), ('c', 'three')]

Then you could do lookup as:

def lookup(key, listDict):
for k, v in listDict:
if k == key:
return v

But, as you say, this would be a lot slower than using a dict (lookup
time is proportional to the length of the list for this naive
dictionary, whereas lookup time is essentially constant with a dict).

However, in this case, the keys are integers starting from 0 with no
holes.  Instead of having to search, our lookup is just:

return digits[i]

which is also constant time.

If you really want to know which is faster, the timeit module is your
friend.  Here's what my computer says:

Morpork:~ repton$ python -m timeit -s 'd = {0:zero, 1:one,
2:two, 3:three, 4:four, 5:five, 6:six, 7:seven, 8:eight,
9:nine}' 'd[5]'
1000 loops, best of 3: 0.127 usec per loop
Morpork:~ repton$ python -m timeit -s 'd = [zero, one, two,
three, four, five, six, seven, eight, nine]' 'd[5]'
1000 loops, best of 3: 0.102 usec per loop

So, if that extra 25 nanoseconds is important to you, definitely go
with the list!

-- 
John.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Projects (fwd)

2008-01-23 Thread bob gailer
Danny Yoo wrote:
 [snip]

 First, it ignores zero, which is a cardinal sin.
Or is it an ordinal sin?

[snip]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor