Req. for comments section "Basic Data" in intro book

2009-11-28 Thread Alf P. Steinbach
I added a section on "basic data" to ch 2 of my writings, an introduction to 
programming (with Python as main language).


The intended reader is someone who is intelligent and wants to learn programming 
but knows little or nothing about it.


As before it would be nice with feedback on this.


  Format: PDF
  http://preview.tinyurl.com/ProgrammingBookP3>


Current contents:

1  Getting started.1
1.1  Python variants, implementations and distributions. 1
1.2  Download and install a Python implementation.   2
1.3  Test-drive the Python interpreter.  2
1.4  Create and run a Python console program.4
1.5  Syntax highlighting and programmers' editors.   6
1.6  Create and run a Python GUI program.7
1.7  About compilation.  9
1.8  About  standalone Windows programs & other kinds.   10
1.9  Browse the local documentation. 11
EOT 12

2  Basic concepts. 1
2.1  Super-basic concept: why programming is not DWIM.   1
2.2  Reported errors.4
2.2.1  Case-sensitity. 4
2.2.2  Syntax / compilation errors.4
2.2.3  Runtime errors / crashes.   5
2.3  A programming exploration tool: turtle graphics.6
2.4  Naming things.  8
2.4.1  Naming actions: routines.   8
2.4.2  Naming data part I: variables.  11
2.4.3  Naming data part II: routine arguments. 13
2.5  Controlling the flow of execution.  14
2.5.1  Repeating actions automatically: loops. 14
2.5.2  Basic comparisions & boolean values.16
2.5.3  Interlude I: a function graph program / about types.17
2.5.4  Automated action choices.   21
2.5.5  Value-producing (function-like) routines.   23
2.5.6  Interlude II: a graph with zeroes marked / about program structure. 26
2.5.7  Dynamically nested actions: recursive routines. 28
2.6  Basic data. 36
2.6.1  Basic fundamental types / strings & concatenation.  36
2.6.2  Indexing and single characters (+ vaguely about sequences in general). 39
2.6.3  Interlude III: a ROT-13 encryption/decryption program, refactoring. 40
2.6.4  Attributes, methods, objects.   43
2.6.5  Doc strings.44
2.6.6  Interlude IV: attribute names as strings, listing str attributes. 45
2.6.7  References. 46
EOT 49

The section on "References", 2.6.7, is about references in Python, it's not a 
list of references. :-)



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-29 Thread Alf P. Steinbach

* markolopa:


On 18 Sep, 10:36, "markol...@gmail.com"  wrote:

On Sep 11, 7:36 pm, Johan Grönqvist  wrote:

I find several places in my code where I would like tohavea variable
scope that is smaller than the enclosing function/class/module definition.

This is one of the single major frustrations I have with Python and an
important source of bugs for me. Here is a typical situation


Here is another bug that I just got. Twenty minutes lost to find it...

class ValueColumn(AbstractColumn):
def __init__(self, name, header, domain_names):
if type(domain_names) != tuple:
raise ValueError('a tuple of domain names must be given')
for name in domain_names:
if type(name) != str:
raise ValueError('a tuple of domain names must be
given')
self.domain_names = domain_names
super(ValueColumn, self).__init__(name, header)

The upper class was initialized with the wrong name, because the for
loop to check
domain_names used "name" which is also the argument to be passed.

If is an old thread but I am reopening to present real situation where
this Python
"feature" bothers me...


I think if one could somehow declare names as const (final, readonly, whatever) 
then that would cover the above plus much more.



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: semantics of ** (unexpected/inconsistent?)

2009-11-29 Thread Alf P. Steinbach

* Esmail:

Ok, this is somewhat unexpected:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.


 >>> -3**2
-9

 >>> x = -3

 >>> x**2
9
 >>>

I would have expected the same result in both cases.

Initially I would have expected -3**2 to yield 9, but I can accept
that ** binds tighter than the unary -, but shouldn't the results
be consistent regardless if I use a literal or a variable?


It is.

>>> -3**2
-9
>>> x = 3
>>> -x**2
-9
>>>

:-)


I guess you expect your expression "x**2" to somehow be evaluated as "-3**2". 
But x doesn't contain text, it contains an integer value that presumably (I 
don't know) is represented in the binary number system, so it's evaluated as 
"(-3)**2". If x contained text and was evaluated as such, pure text replacement, 
then you should be able to write 2 x and have that evaluated as "2 -x"...



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating a local variable scope.

2009-11-30 Thread Alf P. Steinbach

* Jean-Michel Pichavant:

Steven D'Aprano wrote:

On Mon, 30 Nov 2009 02:11:12 +0100, Alf P. Steinbach wrote:

 

I think if one could somehow declare names as const (final, readonly,
whatever) then that would cover the above plus much more.



Having real constants is one feature that I miss. Because Python 
doesn't have constants, I find I've lost the discipline to avoid 
"magic numbers" (and strings) in my code.



  
I don't get you, this can be easily avoid with a strong naming 
convention. I mean, despite they are not really constants, you can still 
use variables to name your numbers and string, to give the reader a 
usefull hint on the meaning of your code. Yet it is still a matter of 
discipline, it is sometimes very tempting to put the string directly 
(unlike numbers string can be meaningful sometimes)


It may be surprising how many things turn out to be readonly.

Consider the OP's code:



class ValueColumn(AbstractColumn):
def __init__(self, name, header, domain_names):
if type(domain_names) != tuple:
raise ValueError('a tuple of domain names must be given')
for name in domain_names:
if type(name) != str:
raise ValueError('a tuple of domain names must be given')
self.domain_names = domain_names
super(ValueColumn, self).__init__(name, header)



Here the arguments should ideally be read only names, which would have cought 
the bug of reusing 'name' in the for loop.


But you really wouldn't code this as



class ValueColumn(AbstractColumn):
def __init__(SELF, NAME, HEADER, DOMAIN_NAMES):
if type(DOMAIN_NAMES) != tuple:
raise ValueError('a tuple of domain names must be given')
for name in DOMAIN_NAMES:
# Argh, at this point 'name' is readonly, but cannot express that.
if type(name) != str:
raise ValueError('a tuple of domain names must be given')
SELF.domain_names = domain_names
super(ValueColumn, SELF).__init__(NAME, HEADER)



Or, at least I wouldn't do that.

It's ugly.

And you have to /change the names/ as the readonly-ness changes.


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Req. for comments section "Basic Data" in intro book

2009-11-30 Thread Alf P. Steinbach

* Alf P. Steinbach:
I added a section on "basic data" to ch 2 of my writings, an 
introduction to programming (with Python as main language).


The intended reader is someone who is intelligent and wants to learn 
programming but knows little or nothing about it.


As before it would be nice with feedback on this.


  Format: PDF
  http://preview.tinyurl.com/ProgrammingBookP3>


Current contents:

1  Getting started.1
1.1  Python variants, implementations and distributions. 1
1.2  Download and install a Python implementation.   2
1.3  Test-drive the Python interpreter.  2
1.4  Create and run a Python console program.4
1.5  Syntax highlighting and programmers' editors.   6
1.6  Create and run a Python GUI program.7
1.7  About compilation.  9
1.8  About  standalone Windows programs & other kinds.   10
1.9  Browse the local documentation. 11
EOT 12

2  Basic concepts. 1
2.1  Super-basic concept: why programming is not DWIM.   1
2.2  Reported errors.4
2.2.1  Case-sensitity. 4
2.2.2  Syntax / compilation errors.4
2.2.3  Runtime errors / crashes.   5
2.3  A programming exploration tool: turtle graphics.6
2.4  Naming things.  8
2.4.1  Naming actions: routines.   8
2.4.2  Naming data part I: variables.  11
2.4.3  Naming data part II: routine arguments. 13
2.5  Controlling the flow of execution.  14
2.5.1  Repeating actions automatically: loops. 14
2.5.2  Basic comparisions & boolean values.16
2.5.3  Interlude I: a function graph program / about types.17
2.5.4  Automated action choices.   21
2.5.5  Value-producing (function-like) routines.   23
2.5.6  Interlude II: a graph with zeroes marked / about program 
structure. 26

2.5.7  Dynamically nested actions: recursive routines. 28
2.6  Basic data. 36
2.6.1  Basic fundamental types / strings & concatenation.  36
2.6.2  Indexing and single characters (+ vaguely about sequences in 
general). 39
2.6.3  Interlude III: a ROT-13 encryption/decryption program, 
refactoring. 40

2.6.4  Attributes, methods, objects.   43
2.6.5  Doc strings.44
2.6.6  Interlude IV: attribute names as strings, listing str attributes. 45
2.6.7  References. 46
EOT 49

The section on "References", 2.6.7, is about references in Python, it's 
not a list of references. :-)


Based on feedback I received in private communications I've improved (I hope) 
the wording in various places, and expanded a bit on the last section.


I've placed the latest version also in Google Docs, without yet removing the 
original  --  the file names are the same but they have different dates.


Comments welcome.


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: [Edu-sig] teaching python using turtle module

2009-11-30 Thread Alf P. Steinbach

* Edward Cherlin:

On Sun, Nov 29, 2009 at 11:34, Brian Blais  wrote:


After a bit of playing, I realized that I couldn't think of many exaples
which use turtle with conditional structures (if- and while- statements),


Repeat is used much more often. but of course we can provide examples
of any behavior you like. I like to use the turtle to generate
sequences, where I can use a conditional to stop when the turtle would
go off the screen. Fibonacci numbers, for example, or exponentials.
Similarly for spirals of various types. Simple cases like those are
easy to do in TA, while more complex sequences could use Python. There
are several fractal examples using loops provided with Sugar on a
Stick, including variations on Siepinksi constructions, and the Koch
Snowflake.


In ch 2 of

  http://preview.tinyurl.com/ProgrammingBookP3>

I use a turtle-generated spiral as the first example of a while loop.

I haven't got that far yet with that chapter, but I halfway plan on including a 
turtle graphics solve-a-maze example, which would/will be an example of 
conditionals with the turtle as a kind of actor making decisions.




or
functions that return values, as opposed to "procedures" like:
def square(length):
forward(length)
right(90)
forward(length)
right(90)
forward(length)
right(90)
forward(length)
right(90)


Plotting a graph. Some examples of that in ch 2 of aforementioned URL.


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Formatting logically nested actions -- Pythonic way?

2009-12-03 Thread Alf P. Steinbach

Hi.

I discovered with tkinter the registration of widgets with layout managers 
(tkinter "geometry" managers, e.g. calls to pack()) needs to be done very 
hierarchically.


And this leads to hierarchical code, which would be nice to indicate by 
indenting, but oops, indenting in Python is syntactically significant...


So first I thought of one routine per widget creation & layout registration, but 
that was very ugly and verbose. Then thought of simply using semicolons but I 
didn't even try that, because I imagined the sheer ugliness. Then I sort of 
landed on the solution below, but although using the language to define a kind 
of special purpose mini-language is common in C++ and Lisp I haven't seen so 
much of that in Python examples, and so I wonder whether this is Pythonic or 
perhaps so extremely un-Pythonic (unconventional) that it's scary  --  I mean, 
calls that do nothing whatsoever, but I think of *visual structure* as very 
important here and IMHO (disregarding Pythonicity issues) worth the overhead...



import tkinter as tk
import contextlib

@contextlib.contextmanager
def this( object ):
yield object

window = tk.Tk()
window.title( "Picture presentation test" )

with this( tk.Frame() ) as display_area:
pic = tk.PhotoImage( file = "lightbulb_off.gif" )
with this( tk.Label( display_area, image = pic ) ) as pic_display:
pic_display.pack( side = "left" )
with this( tk.Frame( display_area, width = 500 ) ) as interaction_area:
with this( tk.Label( interaction_area ) ) as status_line:
status_line.config( text = "The switch is OFF" )
status_line.pack( anchor = "w" )
with this( tk.Button( interaction_area ) ) as toggle_button:
toggle_button.config( text = " Toggle it " )
toggle_button.pack( anchor = "w" )
interaction_area.pack( side = "left" )
display_area.place( relx = 0.5, rely = 0.5, anchor = "center" ) # Centered

window.mainloop()



Cheers,

- Alf

PS: I see a non-functional width specification in there. Just forgot to remove 
that. And better with code as-is straight from editor than fixing up manually!

--
http://mail.python.org/mailman/listinfo/python-list


Are routine objects guaranteed mutable & with dictionary?

2009-12-04 Thread Alf P. Steinbach

Is this guaranteed to work in Python 3.x?


>>> def foo(): pass
...
>>> foo.blah = 222
>>> foo.blah
222
>>> _


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Are routine objects guaranteed mutable & with dictionary?

2009-12-04 Thread Alf P. Steinbach

* Marco Mariani:

Alf P. Steinbach wrote:



Is this guaranteed to work in Python 3.x?


 >>> def foo(): pass

 >>> foo.blah = 222
 >>> foo.blah
222
 >>> _


I don't see why it shouldn't work.


For example,

  (42).blah = 666

The question is what guarantees or absence thereof the language specification, 
PEPs, intentions, whatever gives/has.




BTW, it's a function, not a "routine"


Wikipedia is your friend, http://en.wikipedia.org/wiki/Subroutine>.


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Are routine objects guaranteed mutable & with dictionary?

2009-12-05 Thread Alf P. Steinbach

* Raymond Hettinger:

On Dec 4, 2:03 am, "Alf P. Steinbach"  wrote:

Is this guaranteed to work in Python 3.x?

 >>> def foo(): pass
...
 >>> foo.blah = 222
 >>> foo.blah
222


Yes, function attributes are guaranteed to be writable:
http://www.python.org/dev/peps/pep-0232/


Thanks to all, especially you and Terry.

To quote a suspected bot once rampaging the Microsoft groups, "my question has 
been answered!" :-)


Thread morphing:

Regarding my terminology, "routine" instead "function" that everybody except you 
remarked on, it is of course intentional. After all, my main language is C++. 
And nobody (well, very few) would accuse me of not knowing my C++. :-)


I use the term "routine" because I think the terminology influences what we can 
easily think of and what we therefore tend to use and/or discuss. In that 
respect I think people need to be educated to use more language independent, or 
Eiffel-like, or just historically original, terminology, because


  * "function" is misleading in itself (due to the hijacking of this term in
mathematics), and

  * it gets worse when you can't reasonably talk about "co-functions" or
"function-like functions". :-)

The devolution of terminology has been so severe that now even the Wikipedia 
article on this subject confounds the general concept of "routine" with the far 
more specialized term "sub-routine", which is just one kind of routine. It is of 
course OK with me that there is a default meaning, and that there are several 
different context dependendent meanings. I'm just mentioning this as an example 
that the terminology effectively constrains one's thinking, to the degree that 
even a moderately long encyclopedia article on the subject fails to mention or 
focus on the important aspects. Perhaps modern programmers should be forced to 
study Donald Knuth's TAOCP. Or something.



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Can't print Chinese to HTTP

2009-12-05 Thread Alf P. Steinbach

* Lie Ryan:

On 12/5/2009 2:57 PM, Gnarlodious wrote:

On Dec 1, 3:06 pm, Terry Reedy wrote:

def print(s): return sys.stdout.buffer.write(s.encode('utf-8'))


Here is a better solution that lets me send any string to the
function:

def print(html): return sys.stdout.buffer.write(("Content-type:text/
plain;charset=utf-8\n\n"+html).encode('utf-8'))


No, that's wrong. You're serving HTML with Content-type:text/plain, it 
should've been text/html or application/xhtml+xml (though technically 
correct some older browsers have problems with the latter).



Why this changed in Python 3 I do not know, nor why it was nowhere to
be found on the internet.

Can anyone explain it?


Python 3's str() is what was Python 2's unicode().
Python 2's str() turned into Python 3's bytes().

Python 3's print() now takes a unicode string, which is the regular string.

Because of the switch to unicode str, a simple print('晉') should've 
worked flawlessly if your terminal can accept the character, but the 
problem is your terminal does not.


The correct fix is to fix your terminal's encoding.

In Windows, due to the prompt's poor support for Unicode, the only real 
solution is to switch to a better terminal.


A bit off-topic perhaps, but that last is a misconception. Windows' [cmd.exe] 
does have poor support for UTF-8, in short it Does Not Work in Windows XP, and 
probably does not work in Vista or Windows7 either. However, Windows console 
windows have full support for the Basic Multilingual Plane of Unicode: they're 
pure Unicode beasts.


Thus, the problem is an interaction between two systems that Do Not Work: the 
[cmd.exe] program's practically non-existing support for UTF-8 (codepage 65001), 
and the very unfortunate confusion of stream i/o and interactive i/o in *nix, 
which has ended up as a "feature" (it's more like a design bug) in a lot of 
programming languages stemming from *nix origins, and that includes Python.


Windows' "terminal", its console window support, is INNOCENT... :-)

In Windows, as opposed to *nix, interactive character i/o is separated at the 
API level. There is integration with stream i/o, but the interactive i/o can be 
accessed separately. This is the "console function" API.


So for interactive console i/o one solution could be some Python module for 
interactive console i/o, on Windows internally using the Windows console 
function API, which is fully Unicode (based on UCS-2, i.e. the BMP).


Cheers,

- Alf



Another workaround is to use a real file:

import sys
f = open('afile.html', 'w', encoding='utf-8')
print("晉", file=f)
sys.stdout = f
print("晉")

or slightly better is to rewrap the buffer with io.TextIOWrapper:
import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
print("晉")

--
http://mail.python.org/mailman/listinfo/python-list


Re: Are routine objects guaranteed mutable & with dictionary?

2009-12-05 Thread Alf P. Steinbach

* Steven D'Aprano:

On Sat, 05 Dec 2009 11:26:34 +0100, Alf P. Steinbach wrote:


Regarding my terminology, "routine" instead "function" that everybody
except you remarked on, it is of course intentional. [...]


I think you failed to realise that your use of the term was ambiguous. It 
wasn't clear that you were using "routine" as a noun, it seemed like you 
were using it as an adjective, that is, "routine objects" meaning 
"ordinary, common objects one would use routinely".


Your second example was:

(42).blah = 666

(which of course fails, because ints are immutable and you cannot add 
attributes to them). It isn't surprising that we failed to realise you 
were talking about callable objects when exactly 50% of your examples 
were not callable objects.


One example and one counter example. I can't think of why anyone should lump 
these together as examples of the same thing.



Given the context, I think we were completely 
justified in thinking that you meant routine in the sense of commonly 
used.


Bah.



I use the term "routine" because I think the terminology influences what
we can easily think of and what we therefore tend to use and/or discuss.
In that respect I think people need to be educated to use more language
independent, or Eiffel-like, or just historically original, terminology,
because

   * "function" is misleading in itself (due to the hijacking of this
   term in mathematics), and


"Function" in the mathematical sense dates back to Leibniz and Johann 
Bernoulli in the late seventeenth century. I'm not sure, but I think that 
may have pre-dated computers by a couple of years *wink*


Yes, that was my point. Wink.



http://www.gap-system.org/~history/HistTopics/Functions.html



   * it gets worse when you can't reasonably talk about "co-functions"
   or "function-like functions". :-)


"Co-function" is specifically a mathematical term, from trigonometry. 
Sine and cosine are co-functions, because they are related via 
complementary angles: the sine of an angle is equal to the cosine of the 
complementary angle.


That's the only definition Google has found:
http://www.google.co.uk/search?q=define%3Aco-function&ie=UTF-8&oe=UTF-8

Webster's dictionary agrees this is the only definition:
http://www.merriam-webster.com/dictionary/Cofunction

So I have no idea what you think a co-function (or cofunction) is, or why 
you can't talk about it.


Right. That was my point. Wink. Heh heh. :-) Try substituting "routine". That 
is, s/function/routine/g.



As for "function-like functions", I can't think why you would want to use 
that term!


See above. ;-)


If something is a function, it's obviously function-like, in 
the same way that cats are cat-like and chairs are chair-like.


Right, that was my point.

Including that with the C/Python terminology it isn't.


If you want to talk about "function-like objects", or "function-like 
data", or "things that behave like functions but aren't actually 
functions", that is reasonable. We have names for such things: functor 
(from C++, different from functors in Haskell), or callable, or 
(verbosely, in Python) "any object with a __call__ method". But function-

like functions? That would just be a function.


Right.



The devolution of terminology has been so severe that now even the
Wikipedia article on this subject confounds the general concept of
"routine" with the far more specialized term "sub-routine", which is
just one kind of routine.


I'm not sure how to reply to that, since I'm not sure what you think a 
"routine" is in computing.


See the Wikipedia article and allow for some confusion on the part of the 
authors. Or, if you have TAOCP handy, look it up there. However, you may 
disregard Donald Knuth's definition of "reel time" :-), I'm not invoking him as 
an authority on terminology, just a handy accessible source for the general 
meaning of "routine" (disclaimer: haven't looked it up for this posting, so I 
can't guarantee that you'll find it, although as I recall in volume I).



In my experience (which dates back to the early 80s), "routine" has never 
been anything but a generic term without any specific technical meaning. 
That is, one might talk about the "print routines" without caring whether 
they are external programs (say, printer drivers) or internal sub-
routines (functions, procedures, co-routines, methods, or even just a 
chunk of code you GOTO).


Well, my experience is perhaps a bit longer, but not much. And you're on the 
right track. It's a more general term, *and* it has context dependent meanings.




It is of course OK with me that there is a
default meani

Re: Are routine objects guaranteed mutable & with dictionary?

2009-12-06 Thread Alf P. Steinbach

* Dennis Lee Bieber:

On Sat, 05 Dec 2009 11:26:34 +0100, "Alf P. Steinbach" 
declaimed the following in gmane.comp.python.general:

The devolution of terminology has been so severe that now even the Wikipedia 
article on this subject confounds the general concept of "routine" with the far 
more specialized term "sub-routine", which is just one kind of routine. It is of 


Well, if this were a FORTRAN IV text from the mid-70s you'd be
talking about

function subprograms
and
subroutine subprograms


It's in that direction yes, but the distinction that you mention, which is 
essentially the same as Pascal 'function' versus 'procedure', or Visual Basic 
'function' versus 'sub', is just a distinction of two variants of subroutines.


Up above there is the more general concept of a routine, where there are more 
possibilites than just subroutines; Python generators are one example.


As I mentioned earlier, in Eiffel, which is a more modern language than Fortran, 
routines are still called routines. And specialized terms include "routine". So 
it's not like that language independent terminology has been phased out in 
general; it's mostly only in the C syntax family (e.g. Python operators come 
mostly from C) that "function" is, misleadingly and with associated severe 
constraints, used as a general term.



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Are routine objects guaranteed mutable & with dictionary?

2009-12-06 Thread Alf P. Steinbach

* MRAB:

Alf P. Steinbach wrote:
 > * Dennis Lee Bieber:
 >> On Sat, 05 Dec 2009 11:26:34 +0100, "Alf P. Steinbach"
 >>  declaimed the following in
 >> gmane.comp.python.general:
 >>
 >>> The devolution of terminology has been so severe that now even the
 >>> Wikipedia article on this subject confounds the general concept of
 >>> "routine" with the far more specialized term "sub-routine", which
 >>> is just one kind of routine. It is of
 >>
 >> Well, if this were a FORTRAN IV text from the mid-70s you'd be
 >> talking about
 >>
 >> function subprograms
 >> and
 >> subroutine subprograms
 >
 > It's in that direction yes, but the distinction that you mention,
 > which is essentially the same as Pascal 'function' versus
 > 'procedure', or Visual Basic 'function' versus 'sub', is just a
 > distinction of two variants of subroutines.
 >
 > Up above there is the more general concept of a routine, where there
 > are more possibilites than just subroutines; Python generators are
 > one example.
 >
 > As I mentioned earlier, in Eiffel, which is a more modern language
 > than Fortran, routines are still called routines. And specialized
 > terms include "routine". So it's not like that language independent
 > terminology has been phased out in general; it's mostly only in the C
 > syntax family (e.g. Python operators come mostly from C) that
 > "function" is, misleadingly and with associated severe constraints,
 > used as a general term.
 >
In C there were originally only functions; if you didn't specify a
return type then it would default to 'int' ('void' was a later
addition).

In Python there are only functions; if you don't explicitly return a
value then None is returned.

The distinction between functions and procedures can be helpful in
deciding whether something is Pythonic (for example, in the use of list
comprehensions), but in reality they are all still functions.


I'm sorry, but, first, looking at ways to emulate a syntax, thinking about 
whether something looks like mathematical functions, the eye-candy, is pretty 
irrelevant, at least IMO. To see that it is irrelevant you might consider how 
that works in assembly language. Or you might consider that a call of a C++ 
'void' routine can be used in C++ expressions. I think that even by your mainly 
visual syntax criterion that must be difficult to think of as a "function". 
Another way of looking at it is that the information conveyed by a result 
restricted to N=1 possible significant values, such as Python None or C 
arbitrary value (all possible return values of a non-result-producing routine to 
be treated as the same), is log(N)/log(2) = log(1)/whatever = 0, i.e., the 
routine then produces zero information via its expression result.


Second, what's discussed isn't the distinction between various kinds of 
subroutines, so that wrt. to the earlier thread it's at best a detail.


Although I think that the distinction that you and Dennis raise *is* a useful 
discussion! :-)



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


More stuff added to ch 2 of my programming intro

2009-12-09 Thread Alf P. Steinbach

  Format: PDF
  http://preview.tinyurl.com/ProgrammingBookP3>

The new stuff, section 2.7, is about programs as simulations and handling data, 
focusing on modeling things. It includes some Python GUI programming. The plan 
is to discuss containers like lists and dictionaries in perhaps two more 
subsections of 2.7, but I'm not quite sure about how to approach that or exactly 
how much to cover, since the intent of ch 2 is to introduce mostly general 
concepts and enable the reader to try out (more or less) interesting things.



Cheers,

- Alf

PS: comments welcome!
--
http://mail.python.org/mailman/listinfo/python-list


Re: Python for Newbies

2009-12-09 Thread Alf P. Steinbach

* rm:

Here is a new tutorial that may be a good starting point for learning
Python.

http://www.themaemo.com/python-for-newbies/


Looks nice.

I have two comments: (1) what is "the N900"?, and (2) the naming convention, 
using 'Num' for a variable and 'clsAddress' for a class, is opposite of the 
usual Python convention where one'd write 'num' and 'Address'.


Shameless plug for my own writings, an introduction to /programming/ for 
newbies, using Python  --  this work is progressing slowly but steadily:


  http://preview.tinyurl.com/ProgrammingBookP3>

which is in Google Docs; a table of contents available as text file (it's not 
complete wrt. to latest stuff I added) and also in the PDF files themselves.


Comments very welcome! :-)


Cheers,

- Alf

PS: The last three or four paragraphs in ch 2 were sort of negative so I've 
replaced them with one single short much more upbeat paragraph. Working...

--
http://mail.python.org/mailman/listinfo/python-list


Re: Python for Newbies

2009-12-09 Thread Alf P. Steinbach

* rm:

On Dec 9, 9:46 pm, "Alf P. Steinbach"  wrote:

* rm:


Here is a new tutorial that may be a good starting point for learning
Python.
http://www.themaemo.com/python-for-newbies/

Looks nice.

I have two comments: (1) what is "the N900"?, and (2) the naming convention,
using 'Num' for a variable and 'clsAddress' for a class, is opposite of the
usual Python convention where one'd write 'num' and 'Address'.

Shameless plug for my own writings, an introduction to /programming/ for
newbies, using Python  --  this work is progressing slowly but steadily:

   http://preview.tinyurl.com/ProgrammingBookP3>

which is in Google Docs; a table of contents available as text file (it's not
complete wrt. to latest stuff I added) and also in the PDF files themselves.

Comments very welcome! :-)

Cheers,

- Alf

PS: The last three or four paragraphs in ch 2 were sort of negative so I've
replaced them with one single short much more upbeat paragraph. Working...


One of the reasons I started writing this tutorial was because I found
the lot of existing tutorials lacking in their approachability by
people new to programming.  Just about all of them were either not
comprehensive enough, or seemed written by geniuses for geniuses. I
hope you will allow me to quote a little excerpt from your tutorial
that makes my point quite eloquently:

"I have to use as-yet-unexplained language features in order to
present examples that do relevant things, because it would be too much
to explain the language features & concepts here.  These features are
explained in later chapters, so for now you can just adopt a very
casual attitude, hey, it works!"

Don't get me wrong, your approach probably works for a certain type of
people.  But there are a lot of us that find this approach very
difficult to follow.  The approach of this tutorial is gradually
introduce new concepts so that the student can follow along at a
logical and pleasant pace.


Well, we agree on that. :-)

You just quoted the above a little out of context. It's about the code examples 
in ch 1. Ch 1 is /not/ about programming: it's about tool usage, getting 
started, and next to nothing about the language or programming is discussed.


So from my POV as author that criticism is like criticizing a bus driver for not 
explaining the technical workings of the bus when he's taking potential new bus 
drivers on a tour of the bus routes they may/will be driving later.


Of course if the potential new drivers expect to be educated about the bus' 
technical stuff on that tour, just ignoring or not registering the up-front 
information about the tour, then they may grumble about only being shown some 
scenery, and what's this all about places and distances and routes?


So, I think you read that with wrong expectations.



 Yes, it has a disadvantage.  The examples
can't be too elaborate.


But here we disagree somewhat.

If you look at ch 2 you'll see that with Python examples can be quite impressive 
without using more than just the tiniest little subset of the language.


That is, when one has room to discuss things (difficult in an web based tutorial 
like yours, or like my once-upon-a-time C++ tutorial, but now I do have that 
room for discussion and guidance!) then a student's first examples do not need 
to be text only or dry academic. :-)




 But, the purpose of tutorial, to teach the
language, is better accomplished this way.  If I was teaching a group
of people the English language, I would not go about doing so with a
George Gordon Byron poem.


Oh, I think you should!

Especially considering that his daughter Augusta Ada was the world's first 
programmer and could be suspected of having an affair with Augustus de Morgan 
(who together with George Boole invented boolean logic, they published their 
works in the same week, and anyway was Augusta's private math tutor).


Or perhaps start more easy, with Augustus de Morgan's infamous recursive fleas 
poem (ah, one may suspect some connection to Lord Byron there)!



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: insert unique data in a list

2009-12-13 Thread Alf P. Steinbach

* mattia:
How can I insert non-duplicate data in a list? I mean, is there a 
particular option in the creation of a list that permit me not to use 
something like:

def append_unique(l, val):
if val not in l:
l.append(val)



How about using a set instead?

  >>> a = {1, 2, 3}
  >>> a
  {1, 2, 3}
  >>> a |= {4}
  >>> a
  {1, 2, 3, 4}
  >>> a |= {4}
  >>> a
  {1, 2, 3, 4}
  >>> _


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: More stuff added to ch 2 of my programming intro

2009-12-13 Thread Alf P. Steinbach

* Alf P. Steinbach:

  Format: PDF
  http://preview.tinyurl.com/ProgrammingBookP3>

The new stuff, section 2.7, is about programs as simulations and 
handling data, focusing on modeling things. It includes some Python GUI 
programming. The plan is to discuss containers like lists and 
dictionaries in perhaps two more subsections of 2.7, but I'm not quite 
sure about how to approach that or exactly how much to cover, since the 
intent of ch 2 is to introduce mostly general concepts and enable the 
reader to try out (more or less) interesting things.



Cheers,

- Alf

PS: comments welcome!


Well, I posted the current doc. It has a not yet quite complete section 2.7.7 
about arrays, and that will be the last subsection of the chapter.  I thought 
using the Josephus circle problem as example was pretty neat... :-)


But anyway, comments welcome, even if that last section's not yet finished.


Cheers,

- Alf

PS: Oh, I changed the manuscript title to "Intelligent Person's Intro to 
Programming"  --  is that good?

--
http://mail.python.org/mailman/listinfo/python-list


Re: More stuff added to ch 2 of my programming intro

2009-12-16 Thread Alf P. Steinbach

* Alf P. Steinbach:

* Alf P. Steinbach:

  Format: PDF
  http://preview.tinyurl.com/ProgrammingBookP3>

The new stuff, section 2.7, is about programs as simulations and 
handling data, focusing on modeling things. It includes some Python 
GUI programming. The plan is to discuss containers like lists and 
dictionaries in perhaps two more subsections of 2.7, but I'm not quite 
sure about how to approach that or exactly how much to cover, since 
the intent of ch 2 is to introduce mostly general concepts and enable 
the reader to try out (more or less) interesting things.



Cheers,

- Alf

PS: comments welcome!


Well, I posted the current doc. It has a not yet quite complete section 
2.7.7 about arrays, and that will be the last subsection of the 
chapter.  I thought using the Josephus circle problem as example was 
pretty neat... :-)


But anyway, comments welcome, even if that last section's not yet finished.


Well, what's a programming introduction without Lena Söderberg and Blaise Pascal 
 --  the beauty & the beast? :-)


So I added them. Examples with some Sierpinsky triangles (from Pascal's 
triangle) and simple photo processing (of Lena). With Lena, Josephus and Blaise 
in the examples it's almost like the Good, the Bad and the Ugly...


Comments very welcome.

Especially, from the Python community, I'm pretty sure that there must be more 
Pythonic ways of copying things like my Matrix in section 2.7.7, or conventions 
established for that. Although Python details aren't essential  --  since this 
is about programming and so far only about concepts, notwithstanding the photo 
processing not yet delving into actually technical stuff  --  it would be Bad to 
teach very inferior ways of using the language. So, Better Ways (considering 
that I've endavoured to introduce only a minimal subset of the language in order 
to teach concepts cleanly!) would be good!


Current contents listing below (it's now also as PDF on Google Docs).


Cheers,

- Alf



Contents:

1 Getting started ... 1
1.1 Python variants, implementations and distributions. 1
1.2 Download and install a Python implementation. 2
1.3 Test-drive the Python interpreter. 2
1.4 Create and run a Python console program. 4
1.5 Syntax highlighting and programmers’ editors. 6
1.6 Create and run a Python GUI program. 7
1.7 About compilation. 9
1.8 About  standalone Windows programs & other kinds. 10
1.9 Browse the local documentation. 11
– EOT – ... 12

2 Basic concepts ... 1
2.1 Super-basic concept: why programming is not DWIM. 1
2.2 Reported errors. 4
2.2.1 Case-sensitivity. 4
2.2.2 Syntax / compilation errors. 4
2.2.3 Runtime errors / crashes. 5
2.3 A programming exploration tool: turtle graphics. 6
2.4 Naming things. 8
2.4.1 Naming actions: routines. 8
2.4.2 Naming data part I: variables. 11
2.4.3 Naming data part II: routine arguments. 13
2.5 Controlling the flow of execution. 14
2.5.1 Repeating actions automatically: loops. 14
2.5.2 Basic comparisions & boolean values. 16
2.5.3 Interlude I: a function graph program / about types. 17
2.5.4 Automated action choices. 21
2.5.5 Value-producing (function-like) routines. 23
2.5.6 Interlude II: a graph with zeroes marked / about program structure. 26
2.5.7 Dynamically nested actions: recursive routines. 28
2.6 Basic data. 36
2.6.1 Basic fundamental types / strings & concatenation. 36
2.6.2 Indexing and single characters (+ vaguely about sequences in general). 39
2.6.3 Interlude III: a ROT-13 encryption/decryption program, refactoring. 40
2.6.4 Attributes, methods, objects. 43
2.6.5 Doc strings. 44
2.6.6 Interlude IV: attribute names as strings, listing str attributes. 45
2.6.7 References & automatic garbage collection. 46
2.7 Programs as simulations / handling data. 51
2.7.1 Real system, model, user illusion. 51
2.7.2 Scopes  –  global versus local variables. 53
2.7.3 Attribute collections & models with accessor and modifier routines. 57
2.7.4 Defining your own data types: classes. 63
2.7.5 Using optional and named actual arguments (Python “keyword” arguments). 68
2.7.6 Interlude V: a GUI light switch simulation (+ about delegates and MVC). 71
2.7.7 Indexable collections (arrays). 84
– EOT – ... 98
--
http://mail.python.org/mailman/listinfo/python-list


Re: More stuff added to ch 2 of my programming intro

2009-12-16 Thread Alf P. Steinbach

* Mensanator:

On Dec 16, 4:41 pm, Mensanator  wrote:

On Dec 14, 1:23 am, "Alf P. Steinbach"  wrote:






* Alf P. Steinbach:

  Format: PDF
  http://preview.tinyurl.com/ProgrammingBookP3>
The new stuff, section 2.7, is about programs as simulations and
handling data, focusing on modeling things. It includes some Python GUI
programming. The plan is to discuss containers like lists and
dictionaries in perhaps two more subsections of 2.7, but I'm not quite
sure about how to approach that or exactly how much to cover, since the
intent of ch 2 is to introduce mostly general concepts and enable the
reader to try out (more or less) interesting things.
Cheers,
- Alf
PS: comments welcome!

Well, I posted the current doc. It has a not yet quite complete section 2.7.7
about arrays, and that will be the last subsection of the chapter.  I thought
using the Josephus circle problem as example was pretty neat... :-)
But anyway, comments welcome, even if that last section's not yet finished.
Cheers,
- Alf
PS: Oh, I changed the manuscript title to "Intelligent Person's Intro to
Programming"  --  is that good?

Sure. After all, "Idiot's Guide to Programming" and "Programming for
Dummies" are probably already taken, albeit more appropriate


Oh, and about Chapter 1.

If you're going to use version 3.1.1 as your standard, shouldn't
you also point out that 3.1.1 is NOT bundled with Mac OS X?

How about devoting a section on downloading the source files
and compiling it on a Mac?


Learn to read.

At the top of every second page it tells you that this is an introduction based 
on Windows.




Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: More stuff added to ch 2 of my programming intro

2009-12-16 Thread Alf P. Steinbach

* Mensanator:

On Dec 16, 5:45 pm, "Alf P. Steinbach"  wrote:

* Mensanator:






On Dec 16, 4:41 pm, Mensanator  wrote:

On Dec 14, 1:23 am, "Alf P. Steinbach"  wrote:

* Alf P. Steinbach:

  Format: PDF
  http://preview.tinyurl.com/ProgrammingBookP3>
The new stuff, section 2.7, is about programs as simulations and
handling data, focusing on modeling things. It includes some Python GUI
programming. The plan is to discuss containers like lists and
dictionaries in perhaps two more subsections of 2.7, but I'm not quite
sure about how to approach that or exactly how much to cover, since the
intent of ch 2 is to introduce mostly general concepts and enable the
reader to try out (more or less) interesting things.
Cheers,
- Alf
PS: comments welcome!

Well, I posted the current doc. It has a not yet quite complete section 2.7.7
about arrays, and that will be the last subsection of the chapter.  I thought
using the Josephus circle problem as example was pretty neat... :-)
But anyway, comments welcome, even if that last section's not yet finished.
Cheers,
- Alf
PS: Oh, I changed the manuscript title to "Intelligent Person's Intro to
Programming"  --  is that good?

Sure. After all, "Idiot's Guide to Programming" and "Programming for
Dummies" are probably already taken, albeit more appropriate

Oh, and about Chapter 1.
If you're going to use version 3.1.1 as your standard, shouldn't
you also point out that 3.1.1 is NOT bundled with Mac OS X?
How about devoting a section on downloading the source files
and compiling it on a Mac?

Learn to read.

At the top of every second page it tells you that this is an introduction based
on Windows.


Still, no excuse for giving out mis-information. It's just as easy
to get these things right.


Why are you not concrete?

I'd be glad to hear of any concrete mis-information or inaccuracy; that's much 
of the point of asking for public feedback (did you even think about that?).


Unfortunately one then also get responses from trolls, small kids, idiots, etc..



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Either IDLE Can't Start a subprocess or a firewall software firewall is blocking the connection (Win)--Battlin McAfee

2009-12-16 Thread Alf P. Steinbach

* W. eWatson:
See Subject msg from Python 2.5 Win XP. It is preceded by a "Socket 
Error". It happened while I had a simple program displayed, and I wanted 
to see the shell. The msg occurred when I pressed Shell on Run from the 
menu. I played around for awhile, but got nowhere. Same msg. I did 
remove my McAfee firewall protection, and it worked once, but reverted 
to not working.


I rebooted and the first time I could use Shell, it succeeded. After 
that it failed. Comments? Geeze! Mcaffe turned on the firewall again 
after the reboot.


All seems well now. Nope. McAfee turned the firewall back on. It decided 
to warn me it was off, but now has allowed me to ignore the fact it is 
"no longer protecting me". I'll just let Win firewall do that, thank you.


Nope it's back. I'll just stop here and let anyone who wants to just 
chime in. If I get it to stop, I'll be back.


I recall vaguely some similar problem caused by a program attempting to connect 
to localhost, and the solution then was to edit the hosts file (don't ask me for 
details, but perhaps that'll help you search: that problem had entirely to do 
with Windows' very over-zealous "security" measures).



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: shouldn't list comprehension be faster than for loops?

2009-12-17 Thread Alf P. Steinbach

* Carlos Grohmann:

Hello all

I am testing my code with list comprehensions against for loops.

the loop:

dipList=[float(val[1]) for val in datalist]
dip1=[]
for dp in dipList:
if dp == 90:
dip1.append(dp - 0.01)
else:
dip1.append(dp)

listcomp:

dipList=[float(val[1]) for val in datalist]
dip1=[(dp, dp-0.01)[dp==90.0] for dp in dipList]


Tenting the time spent by each approach (using time.clock()), with a
file with about 100,000 entries, I get 0.03s for the loop and 0.05s
for the listcomp.

thoughts?


In the list comprehension you're constructing n tuples that you're not 
constructing in the loop.


Have you tried this with

  dip1 = [dp - 0.01 if dp == 90 else dp for dp in dipList]

?


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-18 Thread Alf P. Steinbach

I finally finished (draft), I believe!, chapter 2...

Chapter 1 gets the reader up & running, i.e. it's "Hello, world!", basic tool 
usage, without discussing anything about programming really. One reaction to 
this chapter, based on the two example programs in it, was that it wasn't 
gradual and slow enough; hey, those examples are far too advanced, and 
unexplained! But that reader misunderstood: the progression is actually *slower* 
than one might expect. This chapter is only about tool usage. I.e., it's about 
getting those programs running, for the reader who can't rely on teachers or 
fellow students or, as Kernighan & Ritchie put it, "your local guru" (IIRC).


Chapter 2 is about Basic Concepts (of programming). It's the usual: variables, 
basic types and arrays, loops, decision, routines, classes, events, although not 
presented in that order. I make heavy use of complete, concrete examples, many 
of them graphical, and everything is in support of what's actually needed for 
such concrete examples. The intent is to enable the reader to experiment and try 
things out  --  since the only way to really learn is by doing! As best I could 
I've labored to apply this minimalism also to the Python language, using only a 
"minimal" subset (to the degree of not even introducing boolean ops :-) ).


Chapter 3 will, by my current plan, delve into the Python language and such 
things as how integers and floating point works on the inside, and that includes 
those in chapter 2 not even mentioned boolean operations. One important issue, 
introducing exceptions, and in support of that, type hierarchies. After chapter 
3 I have only much vaguer notions about what to introduce in what order, but a 
main issue, assuming that I go on with this writing, will be to apply and teach 
methodology all the way, integrated into the examples and text.


A table of contents + chapters 1 and 2 is available in PDF format at Google 
Docs, at

  http://tinyurl.com/programmingbookP3>

Comments are very welcome!

Re comments: there are two deviations from current Python practice in chapter 2. 
First, that I use spaces inside argument parentheses, which makes the code more 
readable when one gets used/trained to it because it gives the eye more direct 
information (with some training visual structure can be processed unconsciously 
& effortlessly, but purely logical structure has to be processed analytically). 
The second deviation is that since most names are constants, I do not follow PEP 
8's recommendation to use uppercase names of constants. In fact almost no Python 
code does, but then it seems that people are not aware of how many of their 
names are constants and think that they're uppercasing constants when in fact 
they're not. E.g. routine arguments and in particular routine names are usually 
constants, absolutely not meant to be modified, but it would be silly to UC...


So both these two deviations from Python practice are /intentional/, since this 
is a book about programming, not about Python the language & how to conform to 
idiosyncratic language-specific conventions.


But, if there are other deviations from Python practice I'd be very glad to hear 
of it! I'm very hopeful that any such convention deviations can be fixed. :-)



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: iterators and views of lists

2009-12-18 Thread Alf P. Steinbach

* Carl Banks:

On Dec 17, 10:00 pm, Brendan Miller  wrote:

On Thu, Dec 17, 2009 at 6:44 PM, Steven D'Aprano

 wrote:

On Thu, 17 Dec 2009 12:07:59 -0800, Brendan Miller wrote:

I was thinking it would be cool to make python more usable in
programming competitions by giving it its own port of the STL's
algorithm library, which needs something along the lines of C++'s more
powerful iterators.

For the benefit of those of us who aren't C++ programmers, what do its
iterators do that Python's don't?

Python iterators basically only have one operation:

next(), which returns the next element or throws StopIteration.

In C++ terminology this is a Input iterator. It is good for writing
"for each" loops or map reduce operations.


Hmm.  I guess the main thing that's bothering me about this whole
thread is that the true power of Python iterators is being overlooked
here, and I don't think you're being fair to call Python iterators
"weak" (as you did in another thread) or say that they are only good
for for-else type loops.

The fact is, Python iterators have a whole range of powers that C++
iterators do not.  C++ iterators, at least the ones that come in STL,
are limited to iterating over pre-existing data structures.  Python
iterators don't have this limation--the data being "iterated" over can
be virtual data like an infinite list, or data generated on the fly.
This can be very powerful.


It's good that Python iterators can do things.

However, it's not the case that C++ iterators can't do those things.

C++ iterators very much routinely do such things.

However, C++ iterators are flawed in a way that Python iterators are not.

You might say, in an analogy with control structures, that this flaw gives C++ 
iterators the power of "goto" but also with all the negative baggage...


I'm too lazy to Google, but you might search for Alexandrescu and "ranges", and 
possibly throw in "iterators" among the search terms.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: iterators and views of lists

2009-12-18 Thread Alf P. Steinbach

* Carl Banks:

On Dec 18, 11:08 am, "Alf P. Steinbach"  wrote:

* Carl Banks:




On Dec 17, 10:00 pm, Brendan Miller  wrote:

On Thu, Dec 17, 2009 at 6:44 PM, Steven D'Aprano
 wrote:

On Thu, 17 Dec 2009 12:07:59 -0800, Brendan Miller wrote:

I was thinking it would be cool to make python more usable in
programming competitions by giving it its own port of the STL's
algorithm library, which needs something along the lines of C++'s more
powerful iterators.

For the benefit of those of us who aren't C++ programmers, what do its
iterators do that Python's don't?

Python iterators basically only have one operation:
next(), which returns the next element or throws StopIteration.
In C++ terminology this is a Input iterator. It is good for writing
"for each" loops or map reduce operations.

Hmm.  I guess the main thing that's bothering me about this whole
thread is that the true power of Python iterators is being overlooked
here, and I don't think you're being fair to call Python iterators
"weak" (as you did in another thread) or say that they are only good
for for-else type loops.
The fact is, Python iterators have a whole range of powers that C++
iterators do not.  C++ iterators, at least the ones that come in STL,
are limited to iterating over pre-existing data structures.  Python
iterators don't have this limation--the data being "iterated" over can
be virtual data like an infinite list, or data generated on the fly.
This can be very powerful.

It's good that Python iterators can do things.

However, it's not the case that C++ iterators can't do those things.

C++ iterators very much routinely do such things.


STL Iterators?  No.  Maybe if you're talking about boost or homemade
iterators or something I could buy it, though I'd still bs suspicious
of "routinely".


The intersection of STL and the C++ standard library is of nearly the same size 
as the STL, but I don't understand why you're limiting yourself to the STL.


After all, the STL was first developed for the Ada language, IIRC.

Using the standard C++ library, per the 1998 first (and current!) C++ standard, 
below is an idiomatic "copy Carl Banks to output" C++ program where, you might 
note, the "ostream_iterator" has a sister "istream_iterator" that definitely 
does not only iterat over a "pre-existing data structure", as you wrote.


Of course, mostly one defines iterators in the source code or by using Boost or 
similar libraries; that's how C++ works.


There's no special language support for iterators in C++; it's wholly a library 
and application defined concept.




#include 
#include 
#include 
#include 

int main()
{
using namespace std;
static char const* constwords[] =
{ "Carl", "Banks", "is", "wrong", "on", "the", "Internet", "!" };

copy(
words, words + sizeof(words)/sizeof(*words),
ostream_iterator( cout, "\n" )
);
}



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-18 Thread Alf P. Steinbach

* Mensanator:

The second deviation is that since most names are constants,


Really? Does that mean you don't use literals, to save the time
required to convert them to integers? Isn't that done at compile
time?

So, instead of doing the Collatz Conjecture as

while a>1:
  f = gmpy.scan1(a,0)
  if f>0:
a = a >> f
  else:
a = a*3 + 1

You would do this?

zed = 0
one = 1
two = 2
twe = 3
while a>one:
  f = gmpy.scan1(a,zed)
  if f>zed:
a = a >> f
  else:
a = a*twe + one


That seems to have no relation to what you quoted / responded to.

On the other hand, if there is some specific rôle played by the 3 above, where 
some other value (like e.g. 5) might be used instead, then a self descriptive 
name for that rôle might be good.


Such reasonable naming (not what you did above) then allows easier modification 
of and makes it easier to understand the code.


That said, and a bit off-tangent to your comment's main thrust, the time spent 
on coding that repeated-division-by-2 optimization would, I think, be better 
spent googling "Collatz Conjecture"  --  avoiding writing /any/ code. ;-)




Does this really save any time?


If by "it" you mean the silly naming, no it doesn't.

On the contrary, it wastes time, both for writing the code and reading it.

Generally, IMO, think about the clarity of your code. If naming something 
increases clarity, then name the thing. If it doesn't increase clarity, don't.




Now, it's a different story if you're using the gmpy module.
You DON'T want to use literals in loops involving gmpy, because
they would have to be coerced to .mpz's on every pass through the
loop.

In that case, you DO want to use constants as opposed to literals:

ZED = gmpy.mpz(0)
ONE = gmpy.mpz(1)
TWO = gmpy.mpz(2)
TWE = gmpy.mpz(3)
while a>ONE:
  f = gmpy.scan1(a,0) # int used here, so it can be a literal
  if f>ZED:
a = a >> f
  else:
a = a*TWE + ONE

And yes, the time savings can be tremendous, especially when 'a'
has over 50,000 decimal digits.


Yeah, good point. Few languages have compile time evaluation of logically 
constant expressions. C++0x will have that feature (called 'constexpr' IIRC) but 
in Python, current C++ etc. it's just a good idea to precompute values, and name 
them, rather than computing them again and again where they're needed.




. I do not follow PEP

8's recommendation to use uppercase names of constants. In fact almost no Python
code does,


Mine does when I use gmpy. Otherwise, the notion that "most names
are constants" is generally false.


No, it depends on what you mean by "constant". The problem with Python, as 
Google noted, is that the language is so excessively dynamic: even names of 
routines are variables, and there /are/ no named user defined constants except 
logically, in the programmer's mind. And logically (that is, at the "in the 
programmer's mind" level), if you define "constant" as a name whose value will 
not change after initialization, then routine names are constants.


However, if you define "constant" as only a global scope (that is, module scope) 
name that denotes a boolean, numerical or string or Null value and that doesn't 
change after initialization, then your statement about the scarcity of constants 
appears to be true, but using a practically useless definition.


I think for such constants exported by modules it's a good idea to at least 
provide uppercase names so as conform to very firmly established convention. 
There might even be tools that rely on that convention. But for application code 
the uppercase names are just distracting, and they don't help you...



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-18 Thread Alf P. Steinbach

* Steven D'Aprano:

On Fri, 18 Dec 2009 19:00:48 +0100, Alf P. Steinbach wrote:


In fact almost no Python
code does, but then it seems that people are not aware of how many of
their names are constants and think that they're uppercasing constants
when in fact they're not. E.g. routine arguments 


Routine arguments are almost never constants, since by definition they 
will vary according to the value passed by the caller.


I'm sorry, but that requires a definition of "constant" that explicitly excludes 
routine arguments, which is like saying horses are not mammals, just "because".


There are two sensible definitions of "constant": compile time constant, and 
constant-after-initialization.


And since Python doesn't have or support user defined compile time (named) 
constants even in the way that a programmer views the execution of a program, 
only the const after initialization meaning can /reasonably/ apply.


I hope you see that with the constant-after-initialization meaning it's rather 
irrelevant that an argument's value "will vary according to [the actual 
argument]"  --  for an argument A, id(A) does in general not vary after 
initialization, after creation of A; and it can certainly not vary before!


Consider some C++ code:

  void foo( SomeType const v )
  {
  // Here the name v is constant: that name's value can't change.
  // (Except that in C++ you can do anything by using low-level stuff.)
  }

As the comment there exemplifies, in addition to the 2 main meanings of 
constness one can differentiate between constness at different levels of an 
expression, e.g., in Python, with respect to what the language enforces,


  s = "blah"

is a non-constant name referring to a constant (immutable value), while

  a = ["blah"]

is a non-constant name referring to a non-constant value (a Python 'list') 
containing a constant value  --  but with respect to intended constness there 
might be more constness here, although there can't be less.


Since Python doesn't support constness enforcement, your statement that routine 
arguments are almost never constants must refer to their actual usage, i.e. 
intention. It may be the case that in most code you're familiar with routine 
arguments are generally modified. And/or it may be that in code you're familiar 
with routines regularly modify the objecs that their arguments refer to, i.e. 
that the arguments are constant names referring to mutable objects.


In code that I'm familiar with, but that's admittedly mostly in other languages, 
most argument names are constant at the top level of constness, i.e., translated 
to Python, id(A) does generally not change when A is a formal argument.



(The exception is that some formal parameters in Python are given default 
values and flagged as "do not use", e.g. some methods in the random 
module. One might argue that they are constants in the sense that the 
caller is warned not to use them at all.)


Huh.



and in particular
routine NAMES are usually constants, absolutely not meant to be
modified, but it would be silly to UC...

[emphasis added by me]


The only thing sillier than uppercasing routine names is to confuse the 
name of a thing for the thing it represents. The names of *all* entities, 
whether of constants, variables or routines, are "not meant to be 
modified". As a general rule, programs will no more work if you rename a 
variable 'x' to 'y' than if you rename a function 'f' to 'g' -- that's 
why refactoring requires that any renamings be done carefully. There's no 
need to single out routines for special treatment in that regard.


To be pedantic, original routine names are usually absolutely not meant to be 
assigned to.


If you have

  def foo(): whatever()

you simply shouldn't, in general, do

  foo = bar

I think you understood that, i.e., that the above comment of yours is just 
rhetoric?


As far as I know, no programming language provides a standard facility 
for renaming entities, be they data or routines:


Eiffel (IIRC) and C++ come pretty close.

E.g., in C++:

  int a;
  int& b = a;// A new name for a.

  b = 123;  // Assigns to a.


the closest we have is 
something like Python where you can do this:


# make an entity x
x = 23
# use it
x += 1
# make a new name that refers to the same entity as x
y = x  
# delete the old name

del x
# now use the new name
y += 1


Well, you're off on the wrong track as far as convincing me about something is 
concerned. First, your belief about renaming not being supported by any 
languages is largely incorrect, as shown above. Secondly, I was not talking 
about renaming things  --  that creative interpretation is pretty meaningless...



[snipped the rest, irrelevant]

Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-18 Thread Alf P. Steinbach

* Steven D'Aprano:

On Sat, 19 Dec 2009 01:25:48 +0100, Alf P. Steinbach wrote:


That said, and a bit off-tangent to your comment's main thrust, the time
spent on coding that repeated-division-by-2 optimization would, I think,
be better spent googling "Collatz Conjecture"  --  avoiding writing
/any/ code. ;-)


That's a strange thing to say. 


No. The code shown was like attacking Fermat's last theorem with a little Python 
script checking out number triplets. It's already been done (not to mention that 
that theorem's been proven, although that's, AFAIK, not the case for Collatz').




Now, it's a different story if you're using the gmpy module. You DON'T
want to use literals in loops involving gmpy, because they would have
to be coerced to .mpz's on every pass through the loop.

[...]

Yeah, good point. Few languages have compile time evaluation of
logically constant expressions. 


Surely that's an implementation issue rather than a language issue.


No, it isn't.

An optimizer can only do so much, as you yourself note below!

With language support it's a very different matter because guarantees propagate 
so that sophisticated analysis is no longer necessary: the compiler /knows/, 
because it's explicitly being told.




C++0x will have that feature (called
'constexpr' IIRC) but in Python, current C++ etc. it's just a good idea
to precompute values, and name them, rather than computing them again
and again where they're needed.


CPython 2.5 and on has a keyhole optimizer that replaces many constant 
expressions with pre-computed values.


# Python 2.4

dis.dis(compile('1+1', '', 'eval'))

  0   0 LOAD_CONST   0 (1)
  3 LOAD_CONST   0 (1)
  6 BINARY_ADD
  7 RETURN_VALUE

# Python 2.5

dis.dis(compile('1+1', '', 'eval'))

  1   0 LOAD_CONST   1 (2)
  3 RETURN_VALUE


Unfortunately it doesn't help Mensanator's case, because there's no way 
to tell the compiler to generate mpz objects instead of int objects, and 
expressions such as gmpy.mpz(0) are not recognised as compile-time 
constants.


See?

;-)



Mine does when I use gmpy. Otherwise, the notion that "most names are
constants" is generally false.
No, it depends on what you mean by "constant". 


All names are constant. Always. The Python language does not support 
renaming names -- as far as I know, no language does.


No-ones been talking about renaming names. I think that's purely rhetorical on 
your part but it may be that you really believe so. In the latter case, just try 
to interpret statements so that they're meaningful instead of meaningless. :-)




The problem with Python,
as Google noted, is that the language is so excessively dynamic: even
names of routines are variables, 


Don't say that, that is confusing the name with the value.


Nope.


The terms 
"constant" and "variable" refer to the values bound to a name, not the 
name itself:


I'm sorry, that's incorrect.

Quote from §4.1 "Naming and binding" of the Python 3.1.1 language spec:

"If a name is bound in a block, it is a local variable of that block, unless 
declared as nonlocal. If a name is bound at the module level, it is a global 
variable. (The variables of the module code block are local and global.) If a 
variable is used in a code block but not defined there, it is a free variable."




what you mean is that even routines are variables.


I'm sorry but I can't make sense of what you write here. In addition I'm not 
sure what you mean because there are two main interpretations.


If you mean that user defined Python routines are mutable, yes that's right, but 
not what I was talking about (which you can easily see by checking whether it 
makes sense in context; it doesn't).


If you mean that a routine of itself is a variable, no it isn't, but the name of 
a routine, like "foo" in


   def foo: print( "uh" )

or "bar" in

   bar = lambda: print( "oh" )

is a variable, per the language specification's definition quoted above (and 
also by any reasonable meaning of "variable"!).


The meaning of "variable" for Python terminology is specified by the language 
specification, as quoted above: a variable is a name.



[snipped rest, irrelevant]


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Creating Classes

2009-12-18 Thread Alf P. Steinbach

* Dave Angel -> seafoid:


One other point:  you should always derive a class from some other 
class, or 'object' by default.  So you should being the class definition 
by:


class Seq(object):

Why?  It mainly has to do with super().  But in any case if you omit the 
'object' it's an "old style" class, and that's not even supported in 
3.x, so it's better to just get in the habit before it matters.


I think it's best to mention that the above applies to Python 2.x.

In Python 3.x, writing

   class Seq:

is equivalent to writing

   class Seq( object ):

E.g.,

  >>> class A: pass
  ...
  >>> A.__bases__
  (,)
  >>>
  >>> class B( object ): pass
  ...
  >>> B.__bases__
  (,)
  >>> _


Curiously I can't find anything about 'object' in the language spec, but in the 
3.1.1 standard library spec §2 "Built-in functions" it says "object is a base 
for all classes."



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-18 Thread Alf P. Steinbach

* Mensanator:


That said, and a bit off-tangent to your comment's main thrust, the time spent
on coding that repeated-division-by-2 optimization would, I think, be better
spent googling "Collatz Conjecture"  --  avoiding writing /any/ code. ;-)


Ha! I know more about Collatz than you can ever find by Googling!
And how did I achieve that? By writing such code. Be a good boy and
maybe I'll show you how to do Ulam's Spiral with Turtle Graphics.


It's probably good for you that you know so much about Collatz.

I fail to see the relevance to anything.


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-18 Thread Alf P. Steinbach

* Steven D'Aprano:

On Sat, 19 Dec 2009 04:04:51 +0100, Alf P. Steinbach wrote:


* Steven D'Aprano:

On Fri, 18 Dec 2009 19:00:48 +0100, Alf P. Steinbach wrote:


In fact almost no Python
code does, but then it seems that people are not aware of how many of
their names are constants and think that they're uppercasing constants
when in fact they're not. E.g. routine arguments

Routine arguments are almost never constants, since by definition they
will vary according to the value passed by the caller.

I'm sorry, but that requires a definition of "constant" that explicitly
excludes routine arguments, 


/s/explicitly/implicitly



which is like saying horses are not mammals, just "because".


No, it's like saying that horses are not apes, because the definition of 
apes excludes horses.


On the contrary. Apes are not superclass of horses.


But in any case, rather than continue my argument (which was absolutely 
brilliant and flawless, I might add... *wink*), I'm going to skip ahead 
to the place where the penny drops and I understand what you were trying, 
but failed, to say.




Consider some C++ code:

   void foo( SomeType const v )
   {
   // Here the name v is constant: that name's value can't change.
   // (Except that in C++ you can do anything by using low-level
   stuff.)
   }


*penny drops*

Ahaha!!! Now I get it! You want to make the *parameter* of the function a 
constant, rather than the *argument* passed to the function. In other 
words, you want to prohibit something like this:


def f(x):
y = x + 1  # do something with the value passed by the caller
x = 0  # changing the binding will fail INSIDE the function

while still allowing the caller to call the function with variables.


I would want the possibility of having that enforced, of course, because the 
more you know about what can't take place in the code, i.e. the more easy-to-see 
constraints there are, the easier it is to understand and reason about the code, 
not to mention modifying it without breaking original assumptions.


But I wasn't talking about such a language feature (which I believe could also 
greatly improve Python's efficiency by removing the need for many lookups).


Rather, I was remarking that in the absence of such a language feature, to be 
consistent those who insist on using naming conventions to indicate design level 
constraints should use those naming conventions also for this case and others. 
For there's little point in making some occurrences of a constraint visually 
explicit and others not. That just means that one cannot rely on the convention 
to tell where the constraint is (meant to be) in effect or not.



Right -- now what you say makes sense, and is a perfectly reasonable 
thing to do in languages that support constants.


You weren't clear about what you wanted, and the only thing I could think 
of which matched your description was something completely bizarre: given 
some function f with one parameter, you wanted to declare that parameter 
as a constant with some value (say 42), so that calling the function with 
an argument of any other value would be an error, e.g.:


x = 42
f(x)  # succeeds
x = 43
f(x)  # fails

E.g. implemented something like this:

def f(x):
if x != 42:
raise ConstantError('x is not the constant 42')
...

except that the test is done automatically by the compiler.



To be pedantic, original routine names are usually absolutely not meant
to be assigned to.

If you have

   def foo(): whatever()

you simply shouldn't, in general, do

   foo = bar

I think you understood that, i.e., that the above comment of yours is
just rhetoric?


First of all, I think you're underestimating the usefulness and frequency 
of rebinding names to functions. I'll accept that it's uncommon, but it's 
not *that* uncommon to justify "absolutely not meant to be assigned to".


Yeah, hence the weasel term "in general".


In fact, it's so common that we have special syntax for one special case 
of it. Instead of:


def f():
...

f = g(f)

we can write:

@g
def f():
...

While decorator syntax can only be used at function-definition time, the 
concept of function decoration is far more general. You can decorate any 
function, at any time, and doing so is very, very useful for (e.g.) 
debugging, logging, monkey-patching, introspection, error-checking, and 
others. And decoration itself is only one special case of function 
rebinding.


But usually this wrapping occurs before the function is first used by other 
code, i.e. it's usually part of initialization  --  isn't it?


For debugging purposes you might want to replace a function on-the-fly, in the 
middle of the program execution.


But debugging does all sorts of things not commonly accepted for normal 
execution.


As for your second poin

Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-18 Thread Alf P. Steinbach

* Steven D'Aprano:

On Sat, 19 Dec 2009 04:29:22 +0100, Alf P. Steinbach wrote:


* Steven D'Aprano:

On Sat, 19 Dec 2009 01:25:48 +0100, Alf P. Steinbach wrote:


That said, and a bit off-tangent to your comment's main thrust, the
time spent on coding that repeated-division-by-2 optimization would, I
think, be better spent googling "Collatz Conjecture"  --  avoiding
writing /any/ code. ;-)

That's a strange thing to say.

No. The code shown was like attacking Fermat's last theorem with a
little Python script checking out number triplets. It's already been
done (not to mention that that theorem's been proven, although that's,
AFAIK, not the case for Collatz').


You're assuming that Mensanator's motive for writing code is to challenge 
the Collatz Conjecture, rather than to just have fun doing maths and 
programming, or to build up his skills for a serious effort at extending 
the domain of values for which it is known to be true. Or just because he 
needs a function that calculates the hailstone numbers.


I would rather not speculate about motives.

I can say things about the code that was presented, and I did, but as for the 
motives that went into creating it or presenting it in this thread, well I'm not 
telepathic.




Now, it's a different story if you're using the gmpy module. You
DON'T want to use literals in loops involving gmpy, because they
would have to be coerced to .mpz's on every pass through the loop.

[...]

Yeah, good point. Few languages have compile time evaluation of
logically constant expressions.

Surely that's an implementation issue rather than a language issue.

No, it isn't.

An optimizer can only do so much, as you yourself note below!


You make no sense here. What I note below is the existence of an 
implementation-specific optimizer. And your conclusion? That such 
optimization is language specific! How does that make sense?


No, I meant exactly what I wrote, that an optimizer only can do so much, which 
you also noted yourself; that language support facilitates this optimization; 
and that few languages have that support (but e.g. C++0x will have it).



[snip]


With language support it's a very different matter because guarantees
propagate so that sophisticated analysis is no longer necessary: the
compiler /knows/, because it's explicitly being told.


Of course if a language makes a certain guarantee (for example, that 
calls to math.exp(0) will be replaced at compile-time with 1.0) then the 
compiler can make that substitution.


Yes, that's what C++0x 'constexpr' is about.

But I've lost the context here, not sure what this is all about.


[snip]


(1) It's not meaningless to talk about renaming names.


Well, as good as meaningless, IMHO. In fact, earlier, when you wrote under the 
assumption that I was talking about such renaming, you seemed to maintain that 
it was pretty meaningless. I conclude from that that also this is relative.



(2) I will not try to guess what you mean on the basis of what I consider 
sensible, rather than respond to what you actually say.


I rather hoped you would try to employ the "sensible" heuristic.

The problem so far has, apparently, been that you refuse to accept the language 
specification's definition, in §4.1, of variable as name and vice versa.


An "is-it-sensible" heuristic could have cleared that up, I think.


(3) I've already gone over the name/value thing to death in another post, 
so I'll do everyone a favour and not continue it here.


But when that is the problem, a basic misunderstanding of what a word means, 
then it's worth uh, harping on the issue, I think:




[...]

The terms
"constant" and "variable" refer to the values bound to a name, not the
name itself:

I'm sorry, that's incorrect.

Quote from §4.1 "Naming and binding" of the Python 3.1.1 language spec:

"If a name is bound in a block, it is a local variable of that block,
unless declared as nonlocal. If a name is bound at the module level, it
is a global variable. (The variables of the module code block are local
and global.) If a variable is used in a code block but not defined
there, it is a free variable."


Since the above quote doesn't mention "constant", how on earth can you 
use it as evidence for what "constant" refers to?


I don't. I use it as evidence for what "name" refers to. A constant "name" is 
then, logically, a constant such thing, to wit, a constant variable. You may 
find that terminology paradoxical. For C++, which has the means of enforcing it, 
it's a FAQ (many novices have some trouble accepting constant /variables/...). 
If it helps let's adopt Java's terminology and talk about "final" variables. Or, 
as Bjarne had it in original C++

Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-19 Thread Alf P. Steinbach

* John Posner:
On Fri, 18 Dec 2009 13:00:48 -0500, Alf P. Steinbach  
wrote:




Chapter 2 is about Basic Concepts (of programming). It's the usual: 
variables, ...


1. Overall suggestion

You have a tendency to include non-pertinent asides [1]. But then, 
rambling a bit endows a manuscript with the author's distinctive voice. 
Fortunately, we live in a hypertext-enabled world, where you can have 
your cake and eat it, too. I suggest that you go over your manuscript 
with a ruthless eye, and turn your rambles into hypertext-accessible 
"sidebars". See how much you can reduce the length of Chapter 2, which 
current runs 98 pages!


He he. :-)

You're right, although the examples you chose were not as I see it rambles, just 
short asides within sentences; useful concrete examples; and general background.


I do have a tendency to apparently ramble, especially about technical details 
and consequences  --  it's not arbitrary but an attempt to bring in important 
consequences and/or some more fundamental unifying view. I tried to discipline 
myself to not do that, to just let go, to let /the reader/ replace arbitrary 
rules with understanding, in time. Like, you don't really need to understand the 
physics to do hammering. Even though even a rough understanding of the physics 
can help you avoid looking like an effeminate Hollywood movie star acting out 
hammering, can help you avoid getting hurt, can get the job done much faster, 
and can help you in other situations! But I'll try even harder. :-)




2. Comments on Section 2.6.7, "References & automatic garbage collection"

There's a spell-check evader on page 2:49: "trough" s.b. "through". And 
your spell-checker should have caught "adressable" on page 2:48.


Sad to say, I'm not using a spell checker. The reason is that for me, in /most/ 
cases the speling erors marked by Word's spell checker are not speling erors. 
The beast is Just Wrong. And it's Wrong-Headed, insisting on "fixing" perfectly 
correct text. For example, replacing "southeast" with "southwest" (now, what the 
 does Word's spell checker know about geography? Nothing!) Even worse, as 
soon as that beast just gets its little toe inside the door, it tends to invite 
in its friends the Grammar Checker and the Auto Formatter. Which feel free to 
not only report what they see as improvements, but to just change the text!


So, thanks!

Will be fixed.


I find your sequence-of-attribute-lookups approach to the topic of 
"variable assignment" interesting. The directed-graph illustration on 
page 2:49 even hints at the fact that in the world of Python, names 
("turtle", "forward", etc.) and objects (various kinds of yellow boxes) 
are very different things.


(I suggest getting rid of the callout "Very small fixed size variable". 
That way, only objects, not names, have the italicized callouts.)


But using the term "references" and the directed-graph metaphor has its 
drawbacks. Avoiding the term "reference" will make it easier to navigate 
the turbulent waters of call-by-reference vs. call-by-value vs. 
call-by-name. (You don't even stick a toe in those waters in Section 
2.7.5.) Combining memory addresses with the directed graph metaphor 
invites the reader to think at way too low a level, IMHO.


Uhm, discussing call-by-name would really be rambling & anecdotal. AFAIK no real 
programming language has had that since Algol, where it was introduced by a too 
unclear spec implemented literally (i.e., lack of 2-way communication within the 
team introduced a "feature"!). Or am I misunderstanding what you mean?


It's True, as you note, that people tend to get confused. I recently (just weeks 
ago) was astounded to see that a C++ "expert" thought that Java had pass by 
reference, apparently because in Java only references are passed around. But I 
think the cure for that is not to draw a veil over the things that can confuse, 
such as avoiding the word "reference", but rather to just discuss the reality.


That is, I think argument passing & associated terminology is not more 
complicated than even my mom could understand, if she put her politician's mind 
to it. Certainly, anyone young enough won't have any problem. I believe... ;-)



[snip]


I hope these comments help.


Yes, thanks,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-20 Thread Alf P. Steinbach

Hi, 10 details I forgot in my first response...

* John Posner:

[...] Chapter 2, which current runs 98 pages!


The chapter 2 PDF I posted on

  http://tinyurl.com/programmingbookP3>

was and is (it's not been updated) 101 pages, with an "-EOT-" at page 102.

I suspect you may have read the previous version.

However, I believe the only difference from the previous version is the added 
text, the last three pages, about dictionaries (associative arrays). Did your 
PDF have Lewis Carrol's Jabberwocky nonsense poem somewhere in the last three 
pages? I used that poem as an example text for word counting?



[snip]
As I've said in this forum (and the edu-sig forum) before, I think the 
best metaphor for understanding Python variable assignment is John 
Zelle's yellow-sticky-note metaphor. [2]

[snip]


[2] "Python Programming: An Introduction to Computer Science" by John 
Zelle (Franklin, Biddle & Associates, 2004) See Section 2.5.1, "Simple 
Assignment"


I'm unable to find anything about yellow sticky-notes there! However, I can 
guess what it was about :-), and I only looked in a PDF I downloaded, which 
probably was illegal and manually typed in by some kid. He he, they do a great 
service for us who don't have ready continuous access to a university library!



Cheers,

- Alf

PS: Argh! Someone did it  --  serious programming intro based on Python  -- 
already! However, there's a difference between computer science and programming, 
as very clearly explained by Bjarne Stroustrup in his latest book; Zelle uses 
Python 2.x in Linux, while I use 3.x in Windows, more accessible to the average 
reader; Zelle's book seems to be at least partially assuming a school 
environment while what I'm writing is /meant/ to be sufficient for unassisted 
self study; and of course I think my progression is better, e.g. introducing 
loops and decisions very early. However, all those exercises... I wish 
Someone(TM) could cook up Really Interesting exercises for my manuscript! :-P

--
http://mail.python.org/mailman/listinfo/python-list


Re: Windows, IDLE, __doc_, other

2009-12-20 Thread Alf P. Steinbach

* W. eWatson:
When I use numpy.__doc__ in IDLE under Win XP, I get a heap of words 
without reasonable line breaks.


"\nNumPy\n=\n\nProvides\n  1. An array object of arbitrary 
homogeneous items\n  2. Fast mathematical operations over arrays\n  3. 
Linear Algebra, Fourier Transforms, Random Number

...

Is there a way to get this formated properly.


print( numpy.__doc__ )

(For Python 2.x you can and best should leave out the parenthesis)



If I use dir(numpy), I get yet a very long list that starts as:
['ALLOW_THREADS', 'BUFSIZE', 'CLIP', 'DataSource', 'ERR_CALL', 
'ERR_DEFAULT', 'ERR_DEFAULT2', 'ERR_IGNORE', 'ERR_LOG', 'ERR_PRINT', 
'ERR_RAISE', 'ERR_WARN', 'FLOATING_POINT_SUPPORT', 'FPE_DIVIDEBYZERO', 
'FPE_INVALID', 'FPE_OVERFLOW', 'FPE_UNDERFLOW', 'False_', 'Inf', 
'Infinity', 'MAXDIMS', 'MachAr', 'NAN', 'NINF', 'NZERO', 'NaN', 'PINF', 
'PZERO', 'PackageLoader', 'RAISE', 'RankWarning', 'SHIFT_DIVIDEBYZERO', 
'SHIFT_INVALID', 'SHIFT_OVERFLOW', 'SHIFT_UNDERFLOW', 'ScalarType', 
'Tester', 'True_', 'UFUNC_BUFSIZE_DEFAULT'

...
I see this might be a dictionary. What can I do to make it more readable 
or useful, or is that it? Is there a more abc as in Linux?


Something like (off the cuff, fix if eroRs!)

  for name in dir[numpy]:
  if name.startswith( "_" ):
  pass
  else:
  doc_lines = getattr( numpy, name ).__doc__.split()
  print( format( "{0:25} {1}".format( name, doc_lines[0] ) )

Should ideally work whether you use Python 2.x or 3.x.

But as mentioned I just typed that in so there may be eroRs.


It the IDLE shell, it's not possible to retrieve lines entered earlier 
without copying them. Is there an edit facility?


I suggest you download a programmers' editor (like Notepad++ or PsPad) for 
programming work and use the basic Python interpreter for interactive work. The 
basic interpreter lives in a standard Window console window where you can use up 
and down arrow keys, F8 completion, F7 for list of earlier commands, etc (as 
documented by the doskey command in the Windows command interpreter). Just 
forget IDLE in windows: while Windows console windows are something from the 
middle ages, IDLE seems to stem from a period before that! 



Cheers & hth.,

- Alf

PS: Shameless plug: take a look at http://tinyurl.com/programmingbookP3>, 
it's for Windows.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Windows, IDLE, __doc_, other

2009-12-21 Thread Alf P. Steinbach

* Alf P. Steinbach:

* W. eWatson:
When I use numpy.__doc__ in IDLE under Win XP, I get a heap of words 
without reasonable line breaks.


"\nNumPy\n=\n\nProvides\n  1. An array object of arbitrary 
homogeneous items\n  2. Fast mathematical operations over arrays\n  3. 
Linear Algebra, Fourier Transforms, Random Number

...

Is there a way to get this formated properly.


print( numpy.__doc__ )

(For Python 2.x you can and best should leave out the parenthesis)



If I use dir(numpy), I get yet a very long list that starts as:
['ALLOW_THREADS', 'BUFSIZE', 'CLIP', 'DataSource', 'ERR_CALL', 
'ERR_DEFAULT', 'ERR_DEFAULT2', 'ERR_IGNORE', 'ERR_LOG', 'ERR_PRINT', 
'ERR_RAISE', 'ERR_WARN', 'FLOATING_POINT_SUPPORT', 'FPE_DIVIDEBYZERO', 
'FPE_INVALID', 'FPE_OVERFLOW', 'FPE_UNDERFLOW', 'False_', 'Inf', 
'Infinity', 'MAXDIMS', 'MachAr', 'NAN', 'NINF', 'NZERO', 'NaN', 
'PINF', 'PZERO', 'PackageLoader', 'RAISE', 'RankWarning', 
'SHIFT_DIVIDEBYZERO', 'SHIFT_INVALID', 'SHIFT_OVERFLOW', 
'SHIFT_UNDERFLOW', 'ScalarType', 'Tester', 'True_', 
'UFUNC_BUFSIZE_DEFAULT'

...
I see this might be a dictionary. What can I do to make it more 
readable or useful, or is that it? Is there a more abc as in Linux?


Something like (off the cuff, fix if eroRs!)

  for name in dir[numpy]:
  if name.startswith( "_" ):
  pass
  else:
  doc_lines = getattr( numpy, name ).__doc__.split()


Uh oh, 'splitlines' not 'split' !



  print( format( "{0:25} {1}".format( name, doc_lines[0] ) )

Should ideally work whether you use Python 2.x or 3.x.

But as mentioned I just typed that in so there may be eroRs.


It the IDLE shell, it's not possible to retrieve lines entered earlier 
without copying them. Is there an edit facility?


I suggest you download a programmers' editor (like Notepad++ or PsPad) 
for programming work and use the basic Python interpreter for 
interactive work. The basic interpreter lives in a standard Window 
console window where you can use up and down arrow keys, F8 completion, 
F7 for list of earlier commands, etc (as documented by the doskey 
command in the Windows command interpreter). Just forget IDLE in 
windows: while Windows console windows are something from the middle 
ages, IDLE seems to stem from a period before that! 



Cheers & hth.,

- Alf

PS: Shameless plug: take a look at http://tinyurl.com/programmingbookP3>, it's for Windows.

--
http://mail.python.org/mailman/listinfo/python-list


Ch 3 of my writings, first few sections posted

2009-12-21 Thread Alf P. Steinbach

Tentatively titled "Foundations".

Also, these first 2/3 sections may be moved to some later point, i.e. even the 
structure is tentative, but I'd value comments!


  http://tinyurl.com/programmingbookP3>

Table of contents:

3  Foundations 1
3.1  Some necessary math notation & terminology. 2
3.1.1  The vocabulary and notation of basic arithmetic, including Σ and Π. 2
3.1.2  Quadratic and exponential time & memory (also introducing timeit). 5
-EOT_ 9


Cheers,

- Alf

PS: Hm, Open Office's PDF generation does funny things with Greek sigmas inside 
formulas! I don't mind so much that it makes table divider lines very fat and 
bold and that it can't handle certain figures (which I have to paste in manually 
as bitmaps), but really it should be able to handle simple text. Grr.

--
http://mail.python.org/mailman/listinfo/python-list


Re: How to validate the __init__ parameters

2009-12-21 Thread Alf P. Steinbach

* Denis Doria:


I thought in something like:

class A:
def __init__(self, foo = None, bar = None):
set_foo(foo)
self._bar = bar
def  set_foo(self, foo):
if len(foo) > 5:
 raise 
_foo = foo
foo = property(setter = set_foo)

But looks too much like java


Yeah.

If member _foo has this constraint regardless then it's logically part of that 
member's type, so make it a type:


  class _Foo:
def __init__( self, seq ):
  if seq is None:
self.items = []
  elif len( seq ) > 5:
raise 
  else:
self.items = seq

  class A:  # Your example
def __init__( self, foo = None, Bar = None ):
  self._foo = _Foo( foo )
  self._bar = bar
def set_foo( self, foo ):
  self._foo = _Foo( foo )
foo = property( setter = set_foo )


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Ch 3 of my writings, first few sections posted

2009-12-21 Thread Alf P. Steinbach

This is an introduction to programming based on Python 3.x in Windows.

It's posted as PDFs on Google Docs.

Currently 2 full chapters plus a little of chapter 3, about 120 pages in total; 
chapters 1 and 2 reviewed by [comp.programming] and [comp.lang.python] residents 
(although I have no doubt that there are many errors etc., all mine!).



* Alf P. Steinbach, in [comp.lang.python]:

Tentatively titled "Foundations".

Also, these first 2/3 sections may be moved to some later point, i.e. 
even the structure is tentative, but I'd value comments!


  http://tinyurl.com/programmingbookP3>

Table of contents:

3  Foundations 1
3.1  Some necessary math notation & terminology. 2
3.1.1  The vocabulary and notation of basic arithmetic, including Σ and 
Π. 2

3.1.2  Quadratic and exponential time & memory (also introducing timeit). 5
-EOT_ 9


Cheers,

- Alf

PS: Hm, Open Office's PDF generation does funny things with Greek sigmas 
inside formulas! I don't mind so much that it makes table divider lines 
very fat and bold and that it can't handle certain figures (which I have 
to paste in manually as bitmaps), but really it should be able to handle 
simple text. Grr.


I forgot to cross-post this to [comp.programming], the quoted article above was 
only posted to [comp.lang.python]. I now cross-posted it also to 
[comp.lang.c++]. I know, it's a bit OT in clc++, but it makes a nice contrast, 
and can be relevant for all those threads about "how do I learn programming"...


And I've now posted an updated and full table of contents to Google Docs site, 
URL above.


Comments very welcome  --  now it's Christmas and I'll probably not be able to 
respond or fix anything until early January, but still comments very welcome!



Cheers,

- Alf


PS: For clc++: why did I give up writing a beginner's book based on C++? Well, 
for one, in C++ it got too complicated and long the way I wanted it, "real". And 
secondly, Francis, Andrew & Barbara and Bjarne have by now got that covered!


PPS: Also for clc++: where is my C++ tutorial, referenced from the FAQ (§29.21)? 
Well, first it moved to another URL, since [start.no] discontinued their 
service. Then that new free provider ceased to exist, so that now it's nowhere, 
and I've forgotten all about it. And probably will, yet again! I've CC-ed this 
to Marshall Cline so that perhaps he can update the FAQ to e.g. 
[http://cplusplus.com/doc/tutorial/], which by now is, well, acceptable quality!

--
http://mail.python.org/mailman/listinfo/python-list


Re: Python (and me) getting confused finding keys

2009-12-22 Thread Alf P. Steinbach

* Steven D'Aprano:



[snip]

The obvious follow-up is to ask how to make an immutable class.

http://northernplanets.blogspot.com/2007/01/immutable-instances-in-python.html


Thanks, I've been wondering about that.

By the way, the link at the bottom in the article you linked to, referring to an 
earlier posting by Alex Martelli, was broken.


I believe it was the posting available here: http://www.opensubscriber.com/message/python-list@python.org/2659890.html>.



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: How do you configure IDLE on a Mac, seeing as there's no Configure Option...

2010-01-04 Thread Alf P. Steinbach

* Mensanator:

...because there's no [Options] menu on the shell window?

Or at least give me a clue to how to use Courier New font?

For some inscrutable reason, depite the plethora of formatting tools,
someone decided that proportional spaced fonts ought to be the
default for IDLE.


Why not just use the Python interpreter, a reasonable programmer's editor and, 
if you need it, some debugger.


The source code level debugging in IDLE is nothing to write home about.

In Windows XP it is just silly: it marks the current line by ordinary text 
selection, which (depending on your config, but I think this is default) is 
invisible when you're looking at the debugger window for single stepping. You 
can see it by switching back to the source code window but that's annoying, not 
very practical. Invisible highlighting of the current line, he he...



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: PIL how to display multiple images side by side

2010-01-09 Thread Alf P. Steinbach

* Lie Ryan:

On 1/9/2010 8:43 AM, suresh.amritapuri wrote:

Hi,

In PIL, how to display multiple images in say m rows and n colums when
I have m*n images.

suresh


Tkinter has PhotoImage widget and PIL has support for this widget:
http://www.pythonware.com/library/pil/handbook/imagetk.htm


Maybe I've misunderstood something (in that case glad to learn!), but I believe 
PhotoImage is not a widget, and that a PhotoImage has to be presented in e.g. a 
Label widget or some other widget that's able to display images.



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: how to duplicate array entries

2010-01-11 Thread Alf P. Steinbach

* Paul Rudin:

Sebastian  writes:


I have an array  x=[1,2,3]


In python such an object is called a "list".

(In cpython it's implemented as an automatically resizable array.)


I don't think the OP's terminology needs correction.

A Python "list" is an array functionality-wise.

If one isn't observant of that fact then one ends up with O(n^2) time for the 
simplest things.


Using the term "array" accentuates and clarifies this most important aspect.

Using the misleading term "list", even if that's the type's name in Python, 
hides this most important aspect, and so is not, IMHO, a Good Idea except where 
it really matters that it's a 'list' array as opposed to, say, a 'tuple' array.




Is there an operator which I can use to get the result
[1,1,1,2,2,2,3,3,3] ?


There's no operator that will give you that directly - but there are
plenty of one-liners that will yield that list.
e.g:


list(itertools.chain(*([x]*3 for x in [1,2,3])))

[1, 1, 1, 2, 2, 2, 3, 3, 3]


And I think it's worth noting that, for the general case, this notation is also 
hiding a gross inefficiency, first constructing sub-arrays and then copying them 
and joining them.


It doesn't even buy clarity.

So, just

>>> def repeat_items_in( s, n ):
...   a = []
...   for item in s:
... for i in range( n ):
...   a.append( item )
...   return a
...
>>> repeat_items_in( [1, 2, 3], 3 )
[1, 1, 1, 2, 2, 2, 3, 3, 3]
>>> _

And if one absolutely feels like trading some efficiency and clarity for some 
more functional-programming expression like thing (I don't understand why people 
desire that!), just replace the 'append' line with a 'yield' and then write


  list( repeat_items_in( [1, 2, 3], 3 ) )

Re the thing I don't understand: it's the same in C++, people using hours on 
figuring out how to do something very simple in an ungrokkable indirect and 
"compiled" way using template metaprogramming stuff, when they could just write 
a simple 'for' loop and be done with in, say, 3 seconds, and much clearer too!



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: how to duplicate array entries

2010-01-11 Thread Alf P. Steinbach

* Steven D'Aprano:

On Mon, 11 Jan 2010 08:56:36 +0100, Alf P. Steinbach wrote:


* Paul Rudin:

Sebastian  writes:


I have an array  x=[1,2,3]

In python such an object is called a "list".

(In cpython it's implemented as an automatically resizable array.)

I don't think the OP's terminology needs correction.

A Python "list" is an array functionality-wise.

If one isn't observant of that fact then one ends up with O(n^2) time
for the simplest things.


Well that's certainly not true. Some operations may be O(N**2), but 
others are not: list.append() is amortized O(N) and for individual 
appends, may be can be as fast as O(1).


The second sentence may or may not be true. I don't know of any fundamental 
'list' operations that have quadratic time. Is there?


The first sentence is just baffling  --  what on Earth is the "that" that you 
think is not true?


OK, I can guess (correct me if I'm guessing wrong, please): you think I'm 
talking about elementary operations. I'm not. I'm talking about algorithmic 
complexity for loops doing e.g. insertions.




Using the term "array" accentuates and clarifies this most important
aspect.


But Python lists are designed to behave as lists.


No, I'm sorry, they're not.

A Python 'list' has de facto constant time indexing, or "random access".

A linked list  --  what the informal "list" means in programming  --  does not 
have constant time indexing.


A linked list has constant time insertion.

A Python 'list' has de facto linear time insertion (except when used as cursor 
gap array, of course, or e.g. implementing a linked list on top, such things).


So in short, a Python 'list' has all the properties of arrays, and none of the 
properties of linked lists.



Just because CPython 
implements them using arrays doesn't make them arrays. Other Python 
implementations might use other implementations... 


No, I'm sorry, not without screwing up existing Python programs. Indexing is 
assumed as constant time in every CPython program. That is, in your own words, 
but here correct, that's "certainly not true". ;-)


No (sensible) programming language allows a language implementation to change 
the running time of common loops from linear to quadratic.


It would be decidedly un-pythonic. ;-)


If the creator of CLPython is out there, perhaps might like to comment on 
whether he uses Lisp linked-lists for the Python list type?


If he does then you're talking about a different language than the one that 
CPython implements: constant time indexing is very different from linear time. 
It doesn't matter if some bananas are called oranges. They don't turn into 
oranges no matter what they're called.




Using the misleading term "list", even if that's the type's name in
Python, hides this most important aspect, and so is not, IMHO, a Good
Idea except where it really matters that it's a 'list' array as opposed
to, say, a 'tuple' array.


Or an "array" array.


For example, yes. These different kinds of arrays have different restrictions: 
can't be used as dictionary key, can't be modified, has fixed item type. And 
when talking about such characteristics the type name can be relevant.




from array import array
array






Is there an operator which I can use to get the result
[1,1,1,2,2,2,3,3,3] ?

There's no operator that will give you that directly - but there are
plenty of one-liners that will yield that list. e.g:


list(itertools.chain(*([x]*3 for x in [1,2,3])))

[1, 1, 1, 2, 2, 2, 3, 3, 3]

And I think it's worth noting that, for the general case, this notation
is also hiding a gross inefficiency, first constructing sub-arrays and
then copying them and joining them.


I wouldn't call that a gross inefficiency -- that's a gross exaggeration 
unless count is very large, and even then, possibly not that large. Only 
one such sub-array (sub-list) exists at any time. (Unless I am grossly 
misinformed.)


I'm sorry but to the best of my knowledge you're misinformed.

Unless there's some pretty advanced lazy evaluation involved the * operator has 
to collect the subarrays into an array formal argument for the 'chain' routine.


And at that point they all exist at the same time.


>>> def knurre( *poff ):
...print( type( poff ) )
...print( poff )
...
>>> a = [1, 2, 3]
>>> knurre( *(3*[x] for x in a) )

([1, 1, 1], [2, 2, 2], [3, 3, 3])
>>> _




It doesn't even buy clarity.


Not if you're unused to the functional, iterator-based idioms, no.

But if you are, it does.


He he  --  see above, with 99.x certainty you *misunderstood* the code.

That's *not* clear code.

That's, hereby (almost) 

Re: how to duplicate array entries

2010-01-11 Thread Alf P. Steinbach

* Chris Rebert:

On Mon, Jan 11, 2010 at 1:03 AM, Alf P. Steinbach  wrote:

* Steven D'Aprano:

On Mon, 11 Jan 2010 08:56:36 +0100, Alf P. Steinbach wrote:


* Paul Rudin:

Sebastian  writes:


I have an array  x=[1,2,3]

In python such an object is called a "list".

(In cpython it's implemented as an automatically resizable array.)

I don't think the OP's terminology needs correction.

A Python "list" is an array functionality-wise.

If one isn't observant of that fact then one ends up with O(n^2) time
for the simplest things.

Well that's certainly not true. Some operations may be O(N**2), but others
are not: list.append() is amortized O(N) and for individual appends, may be
can be as fast as O(1).

The second sentence may or may not be true. I don't know of any fundamental
'list' operations that have quadratic time. Is there?

The first sentence is just baffling  --  what on Earth is the "that" that
you think is not true?

OK, I can guess (correct me if I'm guessing wrong, please): you think I'm
talking about elementary operations. I'm not. I'm talking about algorithmic
complexity for loops doing e.g. insertions.



Using the term "array" accentuates and clarifies this most important
aspect.

But Python lists are designed to behave as lists.

No, I'm sorry, they're not.

A Python 'list' has de facto constant time indexing, or "random access".

A linked list  --  what the informal "list" means in programming


Eh, it's a bit context-dependent. The abstract data type definition is
a superset that includes both linked lists and dynamic arrays.


Assuming you're talking about some abstract type definition that's in some PEP 
somewhere (there's no abstract data type in the language specification, it's all 
informal) then that's a deficiency of the specification, since the type is 
designed around indexing operations. Perhaps the designers thought it would be 
"obvious", that no-one could mistake it for other than what it is? Anyway, that 
doesn't make it context-dependent: if true, it only makes it poorly specified.




FWIW, Java likewise uses "list" in its ADT sense.


I'm sorry, I'm unfamiliar with that Java terminology (but then, reportedly, many 
Java programmers think that Java has "pass by reference", so nothing coming from 
that direction will surprise me very much!). The Java language specification has 
a section about arrays, none about lists AFAICS. Do you have a reference?



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: how to duplicate array entries

2010-01-11 Thread Alf P. Steinbach

* Chris Rebert:

On Mon, Jan 11, 2010 at 2:20 AM, Alf P. Steinbach  wrote:

* Chris Rebert:

On Mon, Jan 11, 2010 at 1:03 AM, Alf P. Steinbach  wrote:

* Steven D'Aprano:

On Mon, 11 Jan 2010 08:56:36 +0100, Alf P. Steinbach wrote:

* Paul Rudin:

Sebastian  writes:



Using the term "array" accentuates and clarifies this most important
aspect.

But Python lists are designed to behave as lists.

No, I'm sorry, they're not.

A Python 'list' has de facto constant time indexing, or "random access".

A linked list  --  what the informal "list" means in programming

Eh, it's a bit context-dependent. The abstract data type definition is
a superset that includes both linked lists and dynamic arrays.

Assuming you're talking about some abstract type definition that's in some
PEP somewhere


No, I mean the computer science definition/term:
http://en.wikipedia.org/wiki/List_(computer_science)


Note that the default meaning is a list with the characteristics of a linked 
list.

The abstract data type specified in that article is a bit more restricted than 
the usual meaning of list -- as the article notes, the ADT it presents is 
equivalent to an abstract stack, and it's essentially the Lisp view of lists, 
not only just linked list but a restricted view of linked lists. To understand 
it you have to keep in mind that such an ADT is a simplification, for the 
purpose of specifying logical functionality and nothing else. The algorithmic 
efficiency is simply not specified, but is implied.


Unfortunately, as noted there, the article doesn't cite any references or 
sources...

Here's one:

http://www.itl.nist.gov/div897/sqg/dads/HTML/list.html



FWIW, Java likewise uses "list" in its ADT sense.

I'm sorry, I'm unfamiliar with that Java terminology (but then, reportedly,
many Java programmers think that Java has "pass by reference", so nothing
coming from that direction will surprise me very much!). The Java language
specification has a section about arrays, none about lists AFAICS. Do you
have a reference?


http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html


Thanks. I didn't know that. It's a very dirty hodgepodge interface with 
*optional* methods that throw exceptions if not implemented and apparently no 
constraints on algorithmic complexity for various methods. As such, it's a very 
good example why 'list' should not be conflated with 'array'. It leads to such 
monstrosities where neither correctness nor any kind of efficiency is guaranteed 
 :-)


Cheers, & thanks,


- Alf

PS: Please do not mail me copies of your replies to the group. A mail copy means 
that I may have to answer your article twice, as in this case.

--
http://mail.python.org/mailman/listinfo/python-list


Re: PIL how to display multiple images side by side

2010-01-11 Thread Alf P. Steinbach

* suresh.amritapuri:

On Jan 9, 9:51 pm, "Alf P. Steinbach"  wrote:

* Lie Ryan:


On 1/9/2010 8:43 AM, suresh.amritapuri wrote:

Hi,
In PIL, how to display multiple images in say m rows and n colums when
I have m*n images.
suresh

Tkinter has PhotoImage widget and PIL has support for this widget:
http://www.pythonware.com/library/pil/handbook/imagetk.htm

Maybe I've misunderstood something (in that case glad to learn!), but I believe
PhotoImage is not a widget, and that a PhotoImage has to be presented in e.g. a
Label widget or some other widget that's able to display images.

Cheers,

- Alf


Hi,
Let me paste the code I have adapted from somewhere. I dont get a clue
on how to go further so that all the images would stay in their
respective positions.


I suggest you use the grid layout manager.

Uh, "geometry mangler".


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Fractional Hours from datetime?

2010-01-11 Thread Alf P. Steinbach

* W. eWatson:

Ben Finney wrote:

"W. eWatson"  writes:


See my post about the datetime controversy about 3-4 posts up from
yours.


This forum is distributed, and there's no “up” or “3-4 messages” that is
common for all readers.

Could you give the Message-ID for that message?

Sort of like outer space I guess. No real direction. How would I find 
the message ID?


In Thunderbird (the newsreader that you're using) there's a little '+' to the 
left of the message subject line.


That shows the headers.

You can alternatively use [View -> Message Source], or keyboard [Ctrl U].

From that you find that the message id is

  hifkh3$br...@news.eternal-september.org

Then, kicking and cajoling your web browser to turn in the direction of Google 
Groups' Usenet archive,


  groups.google.com

you click the "Advanced search" button, paste the message id, and find that 
Google is unable to find your article, he he.


It's common, it's a very very unreliable archive.

However, as with most things, the "Great Wall of Google" prevents you from 
reporting this. There's no known way to report any bug to Google. As with 
Microsoft in the old days (reportedly Microsoft employees weren't even allowed 
to use the words "bug" or "error" with customers, only, at worst, "problems"), 
there are Google web forms and whatnot, but they all end up in cul-de-sacs, so 
that, together with the total impossibility of reaching any human at Google, one 
very very strongly suspects that it's Google *policy* to never admit to bugs, or 
waste time on fixing them. And so, I suspect, Google Earth still places Norway 
in the middle of Sweden, and I know for a fact that Google Groups still actively 
removes the space at the end of a valid signature delimiter, and Google Talk 
acts up in various ways, and so on: quite serious bugs, but no way to report 
them (thousands upon thousands have tried, at one time a movement was founded 
with its own web site, but the "Great Wall of Google" lets no-one through).


And considering this, and the fact that Google's archive is now the main Usenet 
archive, message id's are not that useful, really.


So asking for a Usenet article's message id is just showing off  --  that one is 
not up-to-date on current technology (it gets more unreliable year by year).




It's easier to place the comment here:

There seems to be some controversy about this and other matters of 
datetime. 
 


No, not at all. :-)

Instead, just ignore silly requests for message id's.


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Fractional Hours from datetime?

2010-01-11 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* W. eWatson:

Ben Finney wrote:

"W. eWatson"  writes:


See my post about the datetime controversy about 3-4 posts up from
yours.

This forum is distributed, and there's no “up” or “3-4 messages” that is
common for all readers.

Could you give the Message-ID for that message?


Sort of like outer space I guess. No real direction. How would I find
the message ID?

In Thunderbird (the newsreader that you're using) there's a little '+'
to the left of the message subject line.

That shows the headers.


It shows a very limited subset of the headers ...


Really? My Thunderbird shows all headers. Perhaps you need to configure 
something.

Or do as I wrote next and you snipped, use [View -> Message Source].


Cheers & hth. (even if rather off-topic by now, not even direct response!),

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach
Argh! This was really annoying! Much time wasted (one naturally thinks that 
silly error must be one's own).


But, anyway:

Lines:

  244  nitems = (chunk.chunksize - chunk.size_read) / self._sampwidth
  464  self._nframes = initlength / (self._nchannels * self._sampwidth)

Need to use Python 3.x "//" integer division.

As a workaround, at least for writing wav-files (I haven't tested reading), one 
may just set the number of frames exactly before writing them.


That should also fix any problems with piping (avoiding file pos seek to patch 
up header).


Also, the unit test should best be improved to check that updating and 
backpatching of number of frames actually works.



PS: It would be nice if someone(TM) could describe here in detail how to 
properly report errors like this. Of course I'm not going to do it if it 
involves establishing Yet Another Account somewhere. But hopefully it doesn't?



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:
[...]

PS: It would be nice if someone(TM) could describe here in detail how to
properly report errors like this. Of course I'm not going to do it if it
involves establishing Yet Another Account somewhere. But hopefully it
doesn't?


That's not very public-spirited, is it? Python is open source, remember.
You wouldn't be able to use it if Guido had said "you know, I'm just
going to write this language for myself. It's so much trouble building a
development community ..."

Give a little something back - create the account, and log the bug. I
promise you'll feel better about yourself ;-)


"You will shortly receive an email to confirm your registration. To complete the 
registration process, visit the link indicated in the email."


Yeah, still waiting...

And I don't feel better. :-(

Oh, mail arriving!

Bah, no, t'was from my travel company.


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Alf P. Steinbach:

* Steve Holden:

Alf P. Steinbach wrote:
[...]

PS: It would be nice if someone(TM) could describe here in detail how to
properly report errors like this. Of course I'm not going to do it if it
involves establishing Yet Another Account somewhere. But hopefully it
doesn't?


That's not very public-spirited, is it? Python is open source, remember.
You wouldn't be able to use it if Guido had said "you know, I'm just
going to write this language for myself. It's so much trouble building a
development community ..."

Give a little something back - create the account, and log the bug. I
promise you'll feel better about yourself ;-)


"You will shortly receive an email to confirm your registration. To 
complete the registration process, visit the link indicated in the email."


Yeah, still waiting...

And I don't feel better. :-(

Oh, mail arriving!

Bah, no, t'was from my travel company.


Hm, similar to Google's feedback forms this, just cul de sac: still no mail!

Trying registration again...

For perhaps I wrote incorrect mail address? No. Correct. Anyway...

"Your request is being processed. Please be patient."

Well how f*g darn patient do they expect me to be?

I've decided: I'm not.

Oh sh**, just as I typed the period above the mail finally arrived. It's been, 
let's see,  about 20+ minutes!


And still some miles to go.

Somebody should say THANK YOU for all this effort, pointing out not just the bug 
but exactly what needs fixing, not whining about me not wasting half an hour on 
going through proper channels after already wasting much time on that bug!



- Alf (grumble)
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Stefan Behnel:

Alf P. Steinbach, 12.01.2010 12:51:

Well how f*g darn patient do they expect me to be?

I've decided: I'm not.

Oh sh**, just as I typed the period above the mail finally arrived. 
It's been, let's see,  about 20+ minutes!


And still some miles to go.

Somebody should say THANK YOU for all this effort, pointing out not 
just the bug but exactly what needs fixing, not whining about me not 
wasting half an hour on going through proper channels after already 
wasting much time on that bug!


Maybe you should just stop using the module. Writing the code yourself 
is certainly going to be faster than reporting that bug, don't you think?


It's part of the standard Python distribution.

Don't you think bugs in the standard library should be fixed?

Anyways, is there any alternative for wave output in Windows except writing the 
thing from scratch?



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Stefan Behnel:

Alf P. Steinbach, 12.01.2010 13:10:

* Stefan Behnel:
Maybe you should just stop using the module. Writing the code 
yourself is certainly going to be faster than reporting that bug, 
don't you think?


It's part of the standard Python distribution.

Don't you think bugs in the standard library should be fixed?


Sure. I was just emphasizing the fact that it might be a larger 
contribution to write such a module in the first place than to fix a bug 
in it.


I'm not interested in credits.

But regarding contributions to the programming community I've done my share, 
including writings and moderating [comp.lang.c++.moderated]. I do not feel I've 
done too little and I almost take offense at that suggestion.



The mere fact that the existing module seems valuable enough for 
you to want to use it suggests that the effort that you are putting into 
getting your bug fixed in the mainline distribution is worth it.


Well, this is for my Python (actually, beginning programmer) writings, at

  http://tinyurl.com/programmingbookP3

(I hope I spelled that right), which is why it "has" to use standard library 
functionality only, and why implementing the thing from scratch is not an option 
 --  otherwise, if this was something I needed, I'd probably do that.


It's just to have a concrete real world example of modular arithmetic and two's 
complement representation.


The example code looks like this, so far  --  might of course be of help to 
others :-)




"Lets you generate simple mono (single-channel) [.wav] files."
import wave
import array
import math

default_sample_rate = 44100 # Usual CD quality.

def sample_square( freq, t ):
linear = freq*t % 1.0
if linear < 0.5:
return -1.0
else:
return 1.0

def sample_sawtooth( freq, t ):
linear = freq*t % 1.0
if linear < 0.5:
return 4.0*linear - 1.0
else:
return 3.0 - 4.0*linear

def sample_sine( freq, t ):
return math.sin( 2*math.pi*freq*t )

def _append_int_to( a, i ):
if i < 0:
i = i + 65536
assert( 0 <= i < 65536 )
a.append( i % 256 )
a.append( i // 256 )

class Writer:
"Writes samples to a specified [.wav] file"
def __init__( self, filename, sample_rate = default_sample_rate ):
self._sample_rate = sample_rate
self._writer = wave.open( filename, "w" )
self._writer.setnchannels( 1 )
self._writer.setsampwidth( 2 )  # 2 bytes = 16 bits
self._writer.setframerate( sample_rate )
self._samples = []

def sample_rate( self ):
return self._sample_rate

def write( self, normalized_sample ):
assert( -1 <= normalized_sample <= +1 )
self._samples.append( normalized_sample )

def close( self ):
data = array.array( "B" )   # B -> unsigned bytes.
for sample in self._samples:
level = round( 32767*sample )
_append_int_to( data, level )
self._writer.setnframes( len( self._samples ) )
self._writer.writeframes( data )
self._writer.close()




import simple_wave

sample_rate = simple_wave.default_sample_rate
total_time  = 2
n_samples   = sample_rate*total_time

writer = simple_wave.Writer( "test.wav" )
for i in range( n_samples ):
t = i/sample_rate
samples = (
simple_wave.sample_sine( 440, t ),
simple_wave.sample_sawtooth( (3/2)*440, t ),
)
sample = sum( samples )/len( samples )
writer.write( sample )
writer.close()



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* André:

On Jan 12, 9:33 am, "Alf P. Steinbach"  wrote:


Well, this is for my Python (actually, beginning programmer) writings, at

   http://tinyurl.com/programmingbookP3



Thanks for writing this book.  I just had a quick look at the
beginning of it where you write:
===
As of this writing two main variants of the Python language are in
use, namely
Python 2.x and Python 3.x (versions 3.0 and greater). Mostly they’re
the same but the
effect of e.g. the / division operator changed in 3.0, so in practice
it’s hopeless to try
to create programs that work the same – or even just work – with both
variants.
===
Notwithstanding your experience (finding a bug in wave.py), this
statement is false.  There are plenty of non-trivial applications that
have been ported so that they work "as is" with both Python 2.x and
Python 3.x.


I'm sorry but your conclusion does not follow from the fact that you point out.

It is hopeless, especially for a newbie, to create correct Python 2.x+3.x 
compatible code, except totally trivial stuff of course.


This due most of all to the language differences, but also to the fact that 
there are PLENTY of libraries that haven't yet been ported, like PIL...




  If you do a google search, I am sure that you can find
many examples proving this point.  For example, you may want to read:
http://mail.mems-exchange.org/durusmail/qp/441/  or try out
Crunchy  (http://code.google.com/p/crunchy).   It may be required to
isolate some small parts and do conditional imports ... but this is
fairly straightforward to do if one writes a new application.


If it were straightforward then it wouldn't be darned difficult, would it?`:-)

The problem isn't just writing code that runs with both Python languages.

The problem is writing code that is correct with both languages, which is 
hopeless when e.g. integer division changes underfoot, like "/" meaning two 
different things depending on the language, print syntax changing, so forth.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Stefan Behnel:

Alf P. Steinbach, 12.01.2010 12:51:

Well how f*g darn patient do they expect me to be?

I've decided: I'm not.

Oh sh**, just as I typed the period above the mail finally arrived.
It's been, let's see,  about 20+ minutes!

And still some miles to go.

Somebody should say THANK YOU for all this effort, pointing out not
just the bug but exactly what needs fixing, not whining about me not
wasting half an hour on going through proper channels after already
wasting much time on that bug!

Maybe you should just stop using the module. Writing the code yourself
is certainly going to be faster than reporting that bug, don't you think?

It's part of the standard Python distribution.

Don't you think bugs in the standard library should be fixed?

Anyways, is there any alternative for wave output in Windows except
writing the thing from scratch?


For what it's worth, reporting the bug is the right decision. Had you
gone to the trouble of a rewrite and proposed your new module for the
standard library the first discovery you would have made is that nothing
gets accepted without a commitment of maintenance.

Clearly that would have been too much to accept when you merely wish to
correct a small-ish bug in an already satisfactory module.

Thanks again, and I hope the change gets into 3.2, and also the next 3.1
maintenance release. The only remaining requirement is some developer
time, but that is our scarcest resource.

regards
 Steve

PS: Next time it would have helped to include a URL to the issue.

http://bugs.python.org/issue7681

FYI there is already some feedback in the tracker.


Yeah, someone who had the bright idea that maybe there isn't a bug, thinking 
instead that maybe a "wrong" name in *a comment* might be the culprit  --  of 
all things!


He was probably just trying to be helpful.

But what do you say to someone who tries to help but is really just making a 
mess of things? Obama tackled that nicely when he got Thorbjørned (Thorbjørn 
Jagland applying some heavy pressure to give him the Nobel Peace Price). But I'm 
not Obama...



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

If you have any suggestions for improving things (and the same goes for
any other readers) I will be happy to listen to them. I do agree that
the bug tracker is a rather high hurdle for people to have to jump over
just to offer feedback on software faults, but the PSF doesn't have the
resources to man customer service lines and the like, so we do what we
can with web-based automation.


Well, regarding the bug tracker register-an-account process, checking headers of 
a duplicate confirmation mail that arrived even later than what I already 
commented on,



Received: from mr1.start.no (unknown [195.159.73.42])
by mail6.start.no (Postfix) with ESMTP id 54EFE1534F8
for ; Tue, 12 Jan 2010 12:56:05 +0100 (CET)
Received: from psf.upfronthosting.co.za (bugs.python.org [88.198.142.26])
by mr1.start.no (Postfix) with ESMTP id B24C92B2035
for ; Tue, 12 Jan 2010 12:53:53 +0100 (CET)
Received: from psf.upfronthosting.co.za (localhost [10.0.0.1])
by psf.upfronthosting.co.za (Postfix) with ESMTP id AE98D786B3
for ; Tue, 12 Jan 2010 12:25:53 +0100 (CET)


As you can see the mail spent exactly 28 minutes (to the second) whirring about 
within "psf.upfronthosting.co.za" before being sent on to my ISP, where it used 
about 3 minutes on orienting itself towards my machine.


I think that mail hang-up may be easiest to fix...

Perhaps use other SMTP server (would be easiest solution).

Perhaps change to CAPTCHA instead of mail confirmation.

Other suggestions I have would, I think, require a lot of work. And I'm not sure 
it's worth it. But my experience is that Google scores 0 on bug reporting, not 
even allowing you to report anything, at all; Microsoft scores 8 or so, up from 
1 on my scale (they used to have lead-you-around-in-circles forms leading to 
punch-you-in-the nose server errors etc., like Google now, but worse because you 
were paying for this!, but they totally changed their tune a few years back, now 
really good, *except* for the worst most bloated MS software/malware ever, the 
Microsoft installer, which unfortunately CPython uses, a light-weight installer 
would be much better!); and then the GNU g++ team scores top marks, 10+, because 
I've had a g++ bug reported and fixed within just hours! :-)



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Steve Holden:

[...]

FYI there is already some feedback in the tracker.

Yeah, someone who had the bright idea that maybe there isn't a bug,
thinking instead that maybe a "wrong" name in *a comment* might be the
culprit  --  of all things!

He was probably just trying to be helpful.

But what do you say to someone who tries to help but is really just
making a mess of things? Obama tackled that nicely when he got
Thorbjørned (Thorbjørn Jagland applying some heavy pressure to give him
the Nobel Peace Price). But I'm not Obama...


You do just what I am doing now.


No, as I stated, I'm not into politics.


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Steven D'Aprano:

On Tue, 12 Jan 2010 23:42:28 +0100, Alf P. Steinbach wrote:


* André:

On Jan 12, 9:33 am, "Alf P. Steinbach"  wrote:


Well, this is for my Python (actually, beginning programmer) writings,
at

   http://tinyurl.com/programmingbookP3



Thanks for writing this book.  I just had a quick look at the beginning
of it where you write:
===
As of this writing two main variants of the Python language are in use,
namely
Python 2.x and Python 3.x (versions 3.0 and greater). Mostly they’re
the same but the
effect of e.g. the / division operator changed in 3.0, so in practice
it’s hopeless to try
to create programs that work the same – or even just work – with both
variants.
===
Notwithstanding your experience (finding a bug in wave.py), this
statement is false.  There are plenty of non-trivial applications that
have been ported so that they work "as is" with both Python 2.x and
Python 3.x.

I'm sorry but your conclusion does not follow from the fact that you
point out.

It is hopeless, especially for a newbie, to create correct Python
2.x+3.x compatible code, except totally trivial stuff of course.


So you allege, but André points out that there are existing, non-trivial 
applications that work unmodified under both Python 2.x and 3.x. For 
example, CherryPy:


http://www.cherrypy.org/wiki/WhatsNewIn32

You're welcome to your own opinion, of course, but not your own reality, 
and the reality is that it is NOT "hopeless" to write correct Python code 
that operates under both 2.6 and 3.x. It's not hopeless because it's been 
done. You might even be able to target versions older than 2.6 if you 
really work at it, as CherryPy does.


Continuing to assert something which is demonstrably untrue simply means 
you lose credibility among those who are familiar with Python.


You're confusing the existence of special cases where something has been done, 
at great cost, with a belief that it's practical to do so in general.


It's not exactly like confusing existential versus universal quantification, but 
it's close.


Thus, your demonstration amounts to "it's not hopeless to walk on the moon: 
look, Louis Armstrong did!"  --  uh, Neil, whatever.


He he. :-)

No, sorry, I apologize, I'm unkind now.

*Slapping my keyboard hand*

But it gets to me how often people here sort of rise to the defense of Python as 
if it needed defending.


It's a great language, it needs no defense, especially not of the kind where one 
tries to suppress facts and silence critique. Indeed, what it needs seems to 
instead be the opposite, a good dose of reality and openness. The reality is 
that the divide between 2.x and 3.x is still very wide, and utterly hopeless for 
a newbie to cross (professionals can do so at great cost).


Over in C++-land it's opposite.

Even the most enhusiastic C++ programmers almost revel in finding faults with 
the language and its standard library, tools etc. And I think that's because 
there's no inferiority complex, or very little of it. So, repeating: Python is a 
great language, it really is, but There Are Issues, of course there are issues, 
and the best way or at least a good way to go about it is adopt that (great, but 
of course has issues) as one's basic view, and be critical.




This due most of all to the language differences, but also to the fact
that there are PLENTY of libraries that haven't yet been ported, like
PIL...


Right, and if your application requires PIL, then it is impossible, but 
for the countless applications that *don't* require PIL, it makes no 
difference at all.


They require other stuff. :-)

Plus, the basic language issues are at the core of all these problems.

But see above.



[...]

The problem is writing code that is correct with both languages, which
is hopeless when e.g. integer division changes underfoot, like "/"
meaning two different things depending on the language, print syntax
changing, so forth.


from __future__ import division
from __future__ import print_function
from future_builtins import hex, map  # or whatever


Not even close to hopeless.


You might consider that I'm very much aware of the above facilities.

Then be a little critical and think about, what problems could it be that, in 
spite of that to you apparent simplicity, hinders the widespread adoption of 
Python 3.x?


Repeating, Python is a great language. I'm not about dissing the language. I 
think it's rather silly when people believe that, and it's rather sad when they 
then employ negative sum thinking: think positive!


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Steven D'Aprano:

On Tue, 12 Jan 2010 23:47:31 +0100, Alf P. Steinbach wrote:


PS: Next time it would have helped to include a URL to the issue.

http://bugs.python.org/issue7681

FYI there is already some feedback in the tracker.

Yeah, someone who had the bright idea that maybe there isn't a bug,
thinking instead that maybe a "wrong" name in *a comment* might be the
culprit  --  of all things!

He was probably just trying to be helpful.

But what do you say to someone who tries to help but is really just
making a mess of things? 


Before pointing out the mote in another person's eye, you should consider 
the enormous beam in yours. You initially reported a completely bogus 
error (NameError: name 'framerate' is not defined) and Brian responded to 
that.


I don't know why you're claiming he was responding to a name that was 
commented out, when you included a traceback clearly showing that the 
line was executed.


No, the out-commented line was not executed and was not shown in any traceback.

Comments are not executed.


If we're supposed to think Brian "is really just making a mess of 
things" (your words) for responding to incorrect information, what are we 
supposed to think of the person who submitted the incorrect information 
in the first place?


I'm sorry but you're trying to make people believe something that you know is 
false, which is commonly called lying.


The error report included the line numbers of the buggy lines, plus a correction 
of the output: I first pasted incorrect error message, then corrected that 
*immediately*. But I just found no way to edit the original message, so both 
that and the correction ended up present. The correction with "Sorry, here's the 
correct message", or words to that effect. In the one and only original submission.


So it's not like the person responding should have any problem at all, and it's 
not like he was presented with incorrect information. To top it off he did not 
respond to the output that was corrected. He believed the problem was a name in 
a comment.



I think you need to chill out and stop treating a simple bug report as a 
personal slight on you.


I'm sorry but you're again trying to make people believe something that you know 
is false, which is commonly called lying: it is not the case that I have strong 
feelings or any feelings at all about that bug report or any other.


But you're starting to annoy me.

I think it's OK when you respond to technical issues where you have 
misunderstood something basic, even when you do that by assertion, as you 
usually do (it would be better if you just asked about things that you don't 
understand). But it's not OK when you're trying to create impressions that are 
false, and it's not OK when you try to demonstrate telepathic powers and discuss 
others' emotions and motivations. I tell you straight.



- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Terry Reedy:

On 1/12/2010 6:31 PM, Alf P. Steinbach wrote:


Perhaps change to CAPTCHA instead of mail confirmation.


I disagree. The point of mail confirmation is not just to assure that a 
human is registering, but that we have a valid email for responses to be 
sent to. Many issues are filed with inadaquate info (platform, Python 
version, full traceback, adequate code snippet, or whatever). So we need 
to be able to reach a person.


Besides which, automated image recognition + barely paid human captcha 
farms have made letter image increasingly useless. Many are now so 
obscure that *I* usually get them wrong.


If there were to be a 'human verifier' system, it might be better based 
on file-in-the-blank questions about Python.


What might be changed more easily is to accept a report but impound it 
until the confirmation reply. Being able to spit out what one has to say 
while it is still fresh in the mind should make the email wait more 
tolerable. What do you think?


I think those are all good points. :-)


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-12 Thread Alf P. Steinbach

* Stefan Behnel:

Alf P. Steinbach, 13.01.2010 06:39:

* Steven D'Aprano:

On Tue, 12 Jan 2010 23:42:28 +0100, Alf P. Steinbach wrote:

It is hopeless, especially for a newbie, to create correct Python
2.x+3.x compatible code, except totally trivial stuff of course.


So you allege, but André points out that there are existing, 
non-trivial applications that work unmodified under both Python 2.x 
and 3.x. For example, CherryPy:


http://www.cherrypy.org/wiki/WhatsNewIn32

You're welcome to your own opinion, of course, but not your own 
reality, and the reality is that it is NOT "hopeless" to write 
correct Python code that operates under both 2.6 and 3.x. It's not 
hopeless because it's been done. You might even be able to target 
versions older than 2.6 if you really work at it, as CherryPy does.


Continuing to assert something which is demonstrably untrue simply 
means you lose credibility among those who are familiar with Python.


You're confusing the existence of special cases where something has 
been done, at great cost, with a belief that it's practical to do so 
in general.


Unless you can prove that it's *not* practical in general, you will have 
to live with the fact that it was, and continues to be, practical for 
existing code bases (and certainly for new code), so it clearly is not 
hopeless to do so, not even "in general".


Simple proof: Python 3.x still lacks widespread usage. :-)


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-13 Thread Alf P. Steinbach

* Stefan Behnel:


Alf P. Steinbach, 13.01.2010 06:55:

* Steven D'Aprano:
I think you need to chill out and stop treating a simple bug report 
as a personal slight on you.


I'm sorry but you're again trying to make people believe something 
that you know is false, which is commonly called lying: it is not the 
case that I have strong feelings or any feelings at all about that bug 
report or any other.


Then why don't you just stop blaming the world for that terrible doom 
that was laid upon you by running into a bug?


I'm sorry but as Steven did in the quoted material above you're trying to make 
people believe something that you know is false: I haven't blamed the world, nor 
described the bug as terrible or a doom, and you know that.


On the other hand, I did let out some steam here, at the start of thread. :-)

While making sure that nobody else would have to waste time on that bug.

It shouldn't be anything to get upset by.

However, that happens. In Norway in the week that was a woman died because the 
emergency services got upset about the nephew's strong language. They decided 
that instead of an ambulance let's send the police, so the poor woman died while 
the police where shackling all the relatives (with force) outside the house...




But you're starting to annoy me.


Funny that it's you writing that.


Yeah, it's understandable if you harbor Negative Feelings about me. I have the 
annoying habit of seeing that something's wrong and saying it, and as I recall 
there was a very poular movie about such a guy once, where many of the laughs 
came from just how incredibly annoying it was that he was right all the time in 
spite of his social position at the bottom of the ladder, sort of exremely 
incongruous. Happily *I* am often wrong, perhaps 40% of the contested issues, so 
if you focus on that then perhaps all may still be well. :-)



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-13 Thread Alf P. Steinbach

* Steven D'Aprano:


Nobody is trying to understate the complexity of writing a large 
application that supports both 2.6 and 3.x, or of taking an existing 
library written for 2.5 and upgrading it to support 3.1. But the 
magnitude of these tasks is no greater (and potentially smaller) than 
supporting (say) 2.3 through 2.5. To describe it as "hopeless" is simply 
mistaken and weakens your credibility.


It seems that people here put a lot of meaning into "hopeless"...

Would it be better to say that it's "hard" or "very hard" or "impractical for 
the novice"?


After all, the bug that this thread is about demonstrated that unit tests 
designed for 2.x do not necessarily uncover 3.x incompatibilities.


Even at the level of Python's own standard library.

But, regarding reformulations that don't imply untrue things to anyone (or 
nearly), I'd like the text on that page to still fit on one page. :-)



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-13 Thread Alf P. Steinbach

* Steven D'Aprano:

On Wed, 13 Jan 2010 06:55:27 +0100, Alf P. Steinbach wrote:


* Steven D'Aprano:

On Tue, 12 Jan 2010 23:47:31 +0100, Alf P. Steinbach wrote:


PS: Next time it would have helped to include a URL to the issue.

http://bugs.python.org/issue7681

FYI there is already some feedback in the tracker.

Yeah, someone who had the bright idea that maybe there isn't a bug,
thinking instead that maybe a "wrong" name in *a comment* might be the
culprit  --  of all things!

He was probably just trying to be helpful.

But what do you say to someone who tries to help but is really just
making a mess of things?

Before pointing out the mote in another person's eye, you should
consider the enormous beam in yours. You initially reported a
completely bogus error (NameError: name 'framerate' is not defined) and
Brian responded to that.

I don't know why you're claiming he was responding to a name that was
commented out, when you included a traceback clearly showing that the
line was executed.

No, the out-commented line was not executed and was not shown in any
traceback.


I have no idea what commented lines NOT shown you are talking about, but 
you attacked Brian for referring to the NameError relating to framerate. 


Well, first, let me state that this is debating details of something irrelevant 
to anything.



Now, that said, Brian responded (first response, Brian subsequently made a patch 
which fixed not just the bugs but also the unit test, so very good everything!),




  In your example, the "n_frames" name does not exist, which is causing the
  problem. In your first comment, "framerate" also did not exist.

  I don't know what a proper frame rate value is, but I just put 10 in there
  and it worked fine. Can you confirm?



Note that the "n_frames" that Brian here thinks "is causing the problem" is a 
name only used in a comment in the demo code.




You claimed that he was:

thinking instead that maybe a "wrong" name in *a comment* 
might be the culprit


But in fact your initial error report included this traceback, which 
displays a very much uncommented line of code:


Traceback (most recent call last):
  File "C:\Documents and Settings\Alf\sound\error.py", line 6, in 
writer.setframerate( framerate )
NameError: name 'framerate' is not defined


Note (1) that "n_frames" does *not* occur here  --  or anywhere.

And that (2) the error report included this correction:


  Sorry, here's correct error message:

Traceback (most recent call last):
  File "C:\Documents and Settings\Alf\sound\error.py", line 8, in 
writer.writeframes( b"\0"*2*4 )
  File "C:\Program Files\cpython\python31\lib\wave.py", line 432, in writeframes
self.writeframesraw(data)
  File "C:\Program Files\cpython\python31\lib\wave.py", line 416, in 
writeframesraw
self._ensure_header_written(len(data))
  File "C:\Program Files\cpython\python31\lib\wave.py", line 459, in 
_ensure_header_written

self._write_header(datasize)
  File "C:\Program Files\cpython\python31\lib\wave.py", line 472, in 
_write_header
self._sampwidth * 8, 'data'))
struct.error: required argument is not an integer
Exception struct.error: 'required argument is not an integer' in Wave_write.__del__ of 
ject at 0x00FE87F0>> ignored


Which you can see that Brian was very well aware of, since he referred to In 
your first comment, "framerate" also did not exist., as opposed to this 
corrected output.


But again, even though he did get off on the wrong foot, probably assuming that 
it was a novice posting (and regarding Python I'm still a novice!), after that 
he did superb job. So very much thanks to him, people will not have to struggle 
with this bug. And perhaps the [wave] module will start getting more used! :-)



Alf, I know you are able to read tracebacks, because you've demonstrated 
the ability in the past. And I'm pretty sure that you're aware that can 
too, because you're not an idiot.


So what puzzles me is, given that you can read the traceback you posted, 
and we can too, why on earth do you claim that the reference to framerate 
was commented out? The line that was executed is right there.


I don't claim and haven't claimed that framerate was commented out.

I referred to the fact that Brian (at first) thought that "n_frames" was, quote, 
"causing the problem", and that that name only occurred in a comment.




Comments are not executed.


Really? Well, that explains why none of my programs do anything!

*wink*




The error report included the line numbers of the buggy lines, plus a
correction of the output: I first pasted incorrect error message, then
corrected that *immediately*. But I just found no way to edit th

Those two controversial 2nd & 3rd paragraphs of my ch 1

2010-01-13 Thread Alf P. Steinbach

Referring to http://tinyurl.com/programmingbookP3>

Due to especially Steven D'Aprano's comments I've replaced "hopeless" with "very 
hard" in paragraph 1 of section 1.1  --  I know he'll disagree with that also 
but I think any more downplaying of the difficulties would be misleading.


According to Mensanator's comments I've changed paragraph 2 in section 1.1 to 
point out that the latest version of Python is typically not bundled with an OS.


The two paragraphs now read:



As of this writing two main variants of the Python language are in use, namely 
Python 2.x and Python 3.x (versions 3.0 and greater). Mostly they’re the same 
but the effect of e.g. the / division operator changed in 3.0, so  in practice 
it’s very hard to create programs that work the same  –  or even just work  – 
with both variants. The examples and discussion in this book assume Python 
version 3.1.1 or later.


Python implementations, the tools etc. that you need to create and run Python 
programs  –  at least for some earlier version of Python!  –  are bundled with 
many operating systems such as Linux and Mac OS X, but unfortunately not with 
Windows.




It's said that the hardest part of a book is the opening sentence  --  "It was a 
dark and stormy night; the rain fell in torrents, except at occasional 
intervals, when it was checked by a violent gust of wind which swept up the 
streets (for it is in London that our scene lies), rattling along the housetops, 
and fiercely agitating the scanty flame of the lamps that struggled against the 
darkness"  --  but in my case, not 1st sentence but the 2nd and 3rd paragraphs!


Comments welcome.


Cheers,

- Alf

PS: Now more stuff added to ch 3 but I've not updated the separate TOC since 
that's a bit of work.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-13 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Steven D'Aprano:

Nobody is trying to understate the complexity of writing a large
application that supports both 2.6 and 3.x, or of taking an existing
library written for 2.5 and upgrading it to support 3.1. But the
magnitude of these tasks is no greater (and potentially smaller) than
supporting (say) 2.3 through 2.5. To describe it as "hopeless" is
simply mistaken and weakens your credibility.

It seems that people here put a lot of meaning into "hopeless"...


Because they are programmers, so they tend to read your meaning quite
literally. Would you have them do anything else?


When you write "literally" you're referring to choosing *a* meaning that does 
not make sense in general.


In some cases that's relevant because to choose a more reasonable meaning may 
require knowledge that a reader doesn't have, and it's good when that's pointed 
out, because it can increase the clarity of the text.


But yes, I would rather have those few people who consistently choose generally 
meaningless interpretations, and they're just a few people, let that be said, to 
rather point out some technical errors or e.g. ways that things can be explained 
so they're more easy to grok.




Would it be better to say that it's "hard" or "very hard" or
"impractical for the novice"?


What would a novice want with writing portable code anyway?


My point is that the (perhaps to be) book is *not* based on that approach, so I 
find it difficult to understand the point of your question.


But treating it as a sort of theoretical question I can think of some reasons, 
including not having to unlearn, easy availability of tools, and the same 
reasons as for a professional, increasing the usability of the code.


But those reasons are all outweighted by the difficulty of doing it.



After all, the bug that this thread is about demonstrated that unit
tests designed for 2.x do not necessarily uncover 3.x incompatibilities.

Even at the level of Python's own standard library.

But, regarding reformulations that don't imply untrue things to anyone
(or nearly), I'd like the text on that page to still fit on one page. :-)


Modulo the smiley, what on earth is supposed to be funny about the way
you waste people's time with trips down semantic ratholes?


Regarding "waste of time" I would love some more substantial comments, pointing 
out e.g. technical errors. But so far nearly all comments have been about 
terminology, how things can be misunderstood by a non-knowledgable reader. To me 
these comments, while not the kind that I would most prefer, are still useful, 
while it appears that in your view it is a waste of time and about semantic 
ratholes  --  but if it is, then you're characterizing-by-association the 
persons here bringing up those issues, not me.


Are you sure that that's what you wanted to express?



You say something is "hopeless", which can generally be taken to mean
that nobody should even bother to try doing it


Almost so: a novice should not bother trying to do it.



, and then retreat into
argument when a counter-example is provided.


I'm sorry but that's meaningless.

This thread is an example that even with the most extensive effort and the 
presumably best programmers one doesn't necessarily manage to get 2.x code to 
work /correctly/ with 3.x  --  even when 2.x compatibility is not required!


That's the kind of example that matters.



Just for once, could you consider admitting you might have been wrong?


That's what a change means, what this thread that you're replying in means: an 
admission that my formulation wasn't perceived the way I thought it would be.


And I thank those people who insisted that I change this.

But it's very untrue that I'm always right, or that I have some problem 
admitting to wrongs. For example, this thread is a counter example to your 
implication. And one needs only one counter example, but there are many. It 
seems that you're objecting to me being competent, and would rather have me make 
a lot more errors. Which is a bit silly. However, discussing persons is IMHO 
generally off-topic here. In technical forums it's what people do when they 
don't have any good arguments.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Bugs in CPython 3.1.1 [wave.py]

2010-01-13 Thread Alf P. Steinbach

* Alf P. Steinbach:

* Steve Holden:

Alf P. Steinbach wrote:

* Steven D'Aprano:

Nobody is trying to understate the complexity of writing a large
application that supports both 2.6 and 3.x, or of taking an existing
library written for 2.5 and upgrading it to support 3.1. But the
magnitude of these tasks is no greater (and potentially smaller) than
supporting (say) 2.3 through 2.5. To describe it as "hopeless" is
simply mistaken and weakens your credibility.

It seems that people here put a lot of meaning into "hopeless"...


Because they are programmers, so they tend to read your meaning quite
literally. Would you have them do anything else?


When you write "literally" you're referring to choosing *a* meaning that 
does not make sense in general.


In some cases that's relevant because to choose a more reasonable 
meaning may require knowledge that a reader doesn't have, and it's good 
when that's pointed out, because it can increase the clarity of the text.


But yes, I would rather have those few people who consistently choose 
generally meaningless interpretations, and they're just a few people, 
let that be said, to rather point out some technical errors or e.g. ways 
that things can be explained so they're more easy to grok.




Would it be better to say that it's "hard" or "very hard" or
"impractical for the novice"?


What would a novice want with writing portable code anyway?


My point is that the (perhaps to be) book is *not* based on that 
approach, so I find it difficult to understand the point of your question.


But treating it as a sort of theoretical question I can think of some 
reasons, including not having to unlearn, easy availability of tools, 
and the same reasons as for a professional, increasing the usability of 
the code.


But those reasons are all outweighted by the difficulty of doing it.



After all, the bug that this thread is about demonstrated that unit
tests designed for 2.x do not necessarily uncover 3.x incompatibilities.

Even at the level of Python's own standard library.

But, regarding reformulations that don't imply untrue things to anyone
(or nearly), I'd like the text on that page to still fit on one page. 
:-)



Modulo the smiley, what on earth is supposed to be funny about the way
you waste people's time with trips down semantic ratholes?


Regarding "waste of time" I would love some more substantial comments, 
pointing out e.g. technical errors. But so far nearly all comments have 
been about terminology, how things can be misunderstood by a 
non-knowledgable reader. To me these comments, while not the kind that I 
would most prefer, are still useful, while it appears that in your view 
it is a waste of time and about semantic ratholes  --  but if it is, 
then you're characterizing-by-association the persons here bringing up 
those issues, not me.


Are you sure that that's what you wanted to express?



You say something is "hopeless", which can generally be taken to mean
that nobody should even bother to try doing it


Almost so: a novice should not bother trying to do it.



, and then retreat into
argument when a counter-example is provided.


I'm sorry but that's meaningless.

This thread is an example that even with the most extensive effort and 
the presumably best programmers one doesn't necessarily manage to get 
2.x code to work /correctly/ with 3.x  --  even when 2.x compatibility 
is not required!


That's the kind of example that matters.



Just for once, could you consider admitting you might have been wrong?


That's what a change means, what this thread that you're replying in 
means: an admission that my formulation wasn't perceived the way I 
thought it would be


Oops sorry, wrong thread.

The thread I thought this was in: "Those two controversial 2nd & 3rd paragraphs 
of my ch 1"




And I thank those people who insisted that I change this.

But it's very untrue that I'm always right, or that I have some problem 
admitting to wrongs. For example, this thread is a counter example to 
your implication. And one needs only one counter example, but there are 
many. It seems that you're objecting to me being competent, and would 
rather have me make a lot more errors. Which is a bit silly. However, 
discussing persons is IMHO generally off-topic here. In technical forums 
it's what people do when they don't have any good arguments.


Btw., see above. :-)


CHeers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Those two controversial 2nd & 3rd paragraphs of my ch 1

2010-01-13 Thread Alf P. Steinbach

* Daniel Fetchinson:


Nobody is deliberately trying to keep people from porting! I think you
misunderstand what is being said, these two statements are very
different: (1) single code base working on both python versions (2)
creating a second code from a code so that the second code works with
python 3 and the first one with python 2. Statement (2) is about
porting, statement (1) is about something else.

Having said all that I actually seriously doubt (probably in agreement
with you) that Alf is able to write good and helpful material on the
relationship between python 2 and 3, porting, migrating, etc, based on
his emails :)


You're mostly absolutely right. :-)

I think it's OK to write things like "It's possible to travel to the moon" and 
"It's very difficult to travel to the moon", because those are just general 
observations  --  even though an astronaut may disagree with the latter stm.


But in order to write about the design of rockets, planning, economics, the 
physics of it, life support, etc., all the nitty gritty details about traveling 
to the moon so as to enable someone to do it, one needs to have done it.


And so far I haven't done that 2.x/3.x compatible code thing except for some 
very trivial stuff. It so happened that what I wrote in Oct 2009 or whenever it 
was, about "/", was verified just now by stumbling upon the "/" bug in 
[wave.py]. But that apparent detail was again just a general observation based 
on common sense and experience with similar differences in other languages, much 
like "you can expect problems if you have a big hole where your rocket's nose 
tip should be". To write about actual porting, version-compatible code, etc., so 
that it's useful to the reader would or will require far more. I'm probably not 
going to do that.


There are however some comments about 2.x/3.x differences, e.g. about "range" 
and "/", and I'm just now progressing into territory where I'll mention "long".


And I think that those comments constitute good and helpful material on the 
relationship between 2.x and 3.x?



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


A simple-to-use sound file writer

2010-01-13 Thread Alf P. Steinbach
Just as a contribution, since someone hinted that I haven't really contributed 
much to the Python community.


The [simple_sound] code will probably go into my ch 3 at http://tinyurl.com/programmingbookP3>, but sans sine wave generation since I 
haven't yet discussed trig functions, and maybe /with/ changes suggested by you?


Module:



"Lets you generate simple mono (single-channel) [.wav], [.aiff] or [.aifc] 
files."
import collections
import array
import math

DataFormat  = collections.namedtuple( "DataFormat",
"open_func, append_int16_func"
)

default_sample_rate = 44100 # Usual CD quality.

def sample_square( freq, t ):
linear = freq*t % 1.0
if linear < 0.5:
return -1.0
else:
return 1.0

def sample_sawtooth( freq, t ):
linear = freq*t % 1.0
if linear < 0.5:
return 4.0*linear - 1.0
else:
return 3.0 - 4.0*linear

def sample_sine( freq, t ):
return math.sin( 2*math.pi*freq*t )

def _append_as_big_endian_int16_to( a, i ):
if i < 0:
i = i + 65536
assert( 0 <= i < 65536 )
a.append( i // 256 )
a.append( i % 256 )

def _append_as_little_endian_int16_to( a, i ):
if i < 0:
i = i + 65536
assert( 0 <= i < 65536 )
a.append( i % 256 )
a.append( i // 256 )

def aiff_format():
import aifc
return DataFormat( aifc.open, _append_as_big_endian_int16_to )

def wav_format():
import wave
return DataFormat( wave.open, _append_as_little_endian_int16_to )

class Writer:
"Writes normalized samples to a specified file or file-like object"
def __init__( self, filename, sample_rate = default_sample_rate, 
data_format = aiff_format() ):

self._sample_rate = sample_rate
self._append_int16_func = data_format.append_int16_func
self._writer = data_format.open_func( filename, "w" )
self._writer.setnchannels( 1 )
self._writer.setsampwidth( 2 )  # 2 bytes = 16 bits
self._writer.setframerate( sample_rate )
self._samples = []

def sample_rate( self ):
return self._sample_rate

def write( self, normalized_sample ):
assert( -1 <= normalized_sample <= +1 )
self._samples.append( normalized_sample )

def close( self ):
data = array.array( "B" )   # B -> unsigned bytes.
append_int16_to = self._append_int16_func
for sample in self._samples:
level = round( 32767*sample )
append_int16_to( data, level )
self._writer.setnframes( len( self._samples ) )
self._writer.writeframes( data )
self._writer.close()



By the way, the reason that it holds on to data until 'close' and does the 
writing there is to work around a bug in [wave.py]. That bug's now corrected but 
wasn't when I wrote above. And possibly best to keep it like it is?


Ideally should deal with exceptions in 'close', calling close on the _writer, 
but I haven't yet discussed exceptions in the hopefully-to-be book writings 
where this probably will go.


Example usage, illustrating that it's simple to use (?):



import simple_sound

sample_rate = simple_sound.default_sample_rate
total_time  = 2
n_samples   = sample_rate*total_time

writer = simple_sound.Writer( "ringtone.aiff" )
for i in range( n_samples ):
t = i/sample_rate
samples = (
simple_sound.sample_sine( 440, t ),
simple_sound.sample_sine( (5/4)*440, t ),
)
sample = sum( samples )/len( samples )
writer.write( sample )
writer.close()



Utility class that may be used to capture output (an instance of this or any 
other file like class can be passed as "filename" to simple_sound.Writer):



class BytesCollector:
def __init__( self ):
self._bytes = array.array( "B" )
self._pos = 0

def raw_bytes( self ):
return self._bytes

def bytes_string( self ):
return self._bytes.tostring()

# File methods:

def tell( self ):
return self._pos

def seek( self, pos, anchor = 0 ):
assert( anchor == 0 )   # Others not supported
assert( pos <= len( self._bytes ) )
self._pos = pos

def write( self, bytes ):
pos = self._pos
if pos < len( self._bytes ):
s = slice( pos, pos + len( bytes ) )
self._bytes[s] = bytes
self._pos = s.stop
else:
self._bytes.extend( bytes )
self._pos = len( self._bytes )

def flush( self ):
pass

def close( self ):
pass



Cheers & enjoy,

- Alf

PS: Comments welcome, except the BytesCollector which I just hacked together to 
test something, it may contain eroRs but worked for my purpose.

--
http://mail.python.org/mailman/listinfo/python-list


Re: maintain 2 versions of python on my computer

2010-01-14 Thread Alf P. Steinbach

* luis:

Hi

I am not an expert in programming and using Python for its simplicity

I have 2 versions of python installed on my computer (windos xp) to
begin the transition from version 2.4 to 2.6 or 3. maintaining the
operability of my old scripts

Is there any way to indicate the version of the python interpreter
must use a script?


I think the most direct way is to use different filename extensions, and 
associate them with corresponding interpreters via the 'assoc' and 'ftype' 
Windows commands.


An alternative is to associate '.py' and '.pyw' with two dummy programs (console 
and GUI subsystem programs) that in some way determines the Python version of 
the script and invokes the right interpreter.


Offhand I can think of three ways to let such a dummy program know the Python 
version of a script (filename extensions are not a way because with distinct 
filename extensions you don't need the dummy program):


  * version information in comment in the file.

  * version information in the filename, like e.g. 'myscript.python31.py',
or version information in the general path, e.g. 'python31\myscript.py'.

  * version information in some kind of 'database', which might be a
separate file or simply hardcoded in your dummy startup program.

But I think personally I'd go for filename extensions and using 'assoc' and 
'ftype', because while ugly it's simplest, like '.py24', '.py26', 'py31'.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

Just as a contribution, since someone hinted that I haven't really
contributed much to the Python community.

The [simple_sound] code will probably go into my ch 3 at http://tinyurl.com/programmingbookP3>, but sans sine wave generation
since I haven't yet discussed trig functions, and maybe /with/ changes
suggested by you?


I wouldn't hold back on the sine wave just because it would represent a
"forward reference". That's OK sometimes. Why not just put a comment in
to the effect that "The sine wave is created using a function from the
math module, which we'll be looking at in ..."?

Since the sine is the basis for all other waveforms its omission would
seem more than a little strange to anyone knowledgeable about audio, for
example.


I don't know very much if anything about audio. For example, in the code what I 
called "sawtooth" wave is really "triangle" wave. The sawtooth is simpler, what 
I called "linear" in the code.


And if you wonder, I was just checking the terminology now before starting to 
write it up... Perhaps should have done that before posting code. But once I got 
the idea of posting it I just posted it.


Anyway, as I recall any wave can be decomposed into sine waves, or square waves, 
or almost whatever kind of waves. Think about a square wave of frequency f and 
one of frequency 3f and perhaps third the amplitude (not sure), combined that's 
already a good start on a sine wave. With some ugly staircasing but hey. And as 
a matter of programming practicality, a triangle wave sounds almost like a sine 
wave. It's just a little more edgy or "hairy", a slight buzz.




Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: a problem with writing a generator

2010-01-14 Thread Alf P. Steinbach

* Paweł Banyś:

Hello,

Please forgive me if I repeat the subject anyhow. I am trying to write a
simple program in Python which scans a config file in search for
"include" lines. If those lines are found, the files included there are
followed and scanned and if any further "include" lines are found, the
whole procedure repeats itself. The program ends when the whole tree
structure of those "includes" is generated.

I seem to have some blackout in my mind because I cannot understand how
to use a generator functionality to complete the task. If anybody has
already done such thing I would be very grateful for any guidance.


Assuming that include directives are like

  #include "blahblah"

and further that config files do not contain stuff that's not valid as C 
preprocessor tokens, may I suggest to check whether your C or C++ compiler 
offers an option to show the include file hierarchy.


For example, with gcc or g++ use option '-H' (it has other options for 
generating makefiles!), or with Microsoft's Visual C++, '-showIncludes'. You'll 
also have to ask the compiler to only preprocess.


Disclaimer: I haven't used *nix, if that's your environment, since mid 1990's...



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Steve Holden:

Alf P. Steinbach wrote:

Just as a contribution, since someone hinted that I haven't really
contributed much to the Python community.

The [simple_sound] code will probably go into my ch 3 at http://tinyurl.com/programmingbookP3>, but sans sine wave generation
since I haven't yet discussed trig functions, and maybe /with/ changes
suggested by you?


I wouldn't hold back on the sine wave just because it would represent a
"forward reference". That's OK sometimes. Why not just put a comment in
to the effect that "The sine wave is created using a function from the
math module, which we'll be looking at in ..."?

Since the sine is the basis for all other waveforms its omission would
seem more than a little strange to anyone knowledgeable about audio, for
example.

I don't know very much if anything about audio. For example, in the code
what I called "sawtooth" wave is really "triangle" wave. The sawtooth is
simpler, what I called "linear" in the code.

And if you wonder, I was just checking the terminology now before
starting to write it up... Perhaps should have done that before posting
code. But once I got the idea of posting it I just posted it.

Anyway, as I recall any wave can be decomposed into sine waves, or
square waves, or almost whatever kind of waves. Think about a square
wave of frequency f and one of frequency 3f and perhaps third the
amplitude (not sure), combined that's already a good start on a sine
wave. With some ugly staircasing but hey. And as a matter of programming
practicality, a triangle wave sounds almost like a sine wave. It's just
a little more edgy or "hairy", a slight buzz.


It's not clear to me that you can approximate any waveform with a
suitable combination of square waves,


Oh. It's simple to prove. At least conceptually! :-)

Consider first that you need an infinite number of sine waves to create a 
perfect square wave.


The opposite also holds: infinite number of square waves to create a perfect 
sine wave (in a way sines and squares are opposites, the most incompatible).


With the goal of just a rough approximation you can go about it like this:

  1. Divide a full cycle of the sine wave into n intervals. With
 sine wave frequency f this corresponds to n*f sample rate for digital
 representation.

  2. Each interval will be approximated by a rectangular bar extending
 up to or down to the sine wave. As it happens this (the bar's height) is
 the sample value in a digital representation.

  3. In the first half of the cycle, for each bar create that bar as
 a square wave of frequency f, amplitude half the bar's height, and phase
 starting at the bar's left, plus same square wave with negative sign
 (inverted amplitude) and phase starting at the bar's right. And voilà,
 not only this bar generated  but also the corresponding other-way bar in
 second half of cycle.

  4. Sum all the square waves from step 3.

  5. Let n go to infinity for utter perfectness! :-)

And likewise for any other waveform.

After all, it's the basis of digital representation of sound!



though I admit the idea has
intuitive appeal. But I know beyond a shadow of a doubt from my
education that any periodic function with a fundamental frequency f can
be approximated to whatever desired accuracy by the sum of sine and
cosine waves of frequencies Nf (N = 0, 1, 2, 3, ...) of appropriate
amplitudes (the frequency 0 component allows you to insert a "DC shift"
for waveforms that aren't symmetrical about zero). I seem to remember
the Fourier's theorem was the fundamental proof.


Yes, the good Fourier had a thing for roundish curves. He saw them everywhere 
and in anything. Eventually he found an infinite number of them in, to others, 
invisible /sound/.




There is a very pretty discussion of all this, if you are mathematically
inclined, in

  http://press.princeton.edu/books/maor/chapter_15.pdf

with a specific example for the sawtooth waveform.

I would definitely recommend renaming the waveforms you *do* use to
conform with accepted terminology. This will reduce reader confusion.


Yes, thanks.


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Those two controversial 2nd & 3rd paragraphs of my ch 1

2010-01-14 Thread Alf P. Steinbach

* Lie Ryan -> Alf P. Steinbach:

why do you think it is "impossible" to write a complex and portable
python script?


I don't. You're not quoting me.



Though keeping everything in one code base may often be difficult and
only of little practical benefit, it is not impossible. Modern version
control systems makes creating a fork not-so-difficult[2]; and
maintaining two or more codebase is much cheaper nowadays than they used
to be.


Huh.



[1] we're ignoring other python implementations since they haven't
targeted 3.0; but anyway due to the much better defined standard,
alternative implementations doesn't pose much difference except for
occasional lack of the newest feature on many cases
[2] though not, by any definition, "easy"; but at least it's often
easier to fork than to keep things in one code base. Another, better,
alternative is to write a program that transform a human readable code
to portable code; which is what 2to3 is about.


The upshot for 2.x/3.x compatible code base is to write in 2.x and convert 
automatically to 3.x, that is, to write the source code in *one* language.


That's because it's very hard to write code that works directly in both 
languages (or language versions, if you prefer).


The paragraph in the book is about why one, in practice, has to choose one 
version for one's source code, and why one shouldn't automatically think that 
what's learned about that version necessarily applies to the other version.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Mel:

Alf P. Steinbach wrote:

* Steve Holden:



It's not clear to me that you can approximate any waveform with a
suitable combination of square waves,

Oh. It's simple to prove. At least conceptually! :-)

Consider first that you need an infinite number of sine waves to create a
perfect square wave.

The opposite also holds: infinite number of square waves to create a
perfect sine wave (in a way sines and squares are opposites, the most
incompatible).


No, it doesn't.  The infinite set of sine waves that make a square wave 
leave out the sine waves of frequency 2f, 4f, 6f, 8f, ... (2*n*f) ... .  
Once you've left them out, you can never get them back.  So sawtooth waves, 
for example, can't generally be built out of sets of square waves.


The way to build a sine wave out of square waves is not a Fourier transform.

See the post you replied to for a simple procedure to build the sine wave.


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Steve Holden:

[...]

With the goal of just a rough approximation you can go about it like this:

  1. Divide a full cycle of the sine wave into n intervals. With
 sine wave frequency f this corresponds to n*f sample rate for digital
 representation.

  2. Each interval will be approximated by a rectangular bar extending
 up to or down to the sine wave. As it happens this (the bar's
height) is
 the sample value in a digital representation.

  3. In the first half of the cycle, for each bar create that bar as
 a square wave of frequency f, amplitude half the bar's height, and
phase
 starting at the bar's left, plus same square wave with negative sign
 (inverted amplitude) and phase starting at the bar's right. And voilà,
 not only this bar generated  but also the corresponding other-way
bar in
 second half of cycle.

  4. Sum all the square waves from step 3.

  5. Let n go to infinity for utter perfectness! :-)

And likewise for any other waveform.

After all, it's the basis of digital representation of sound!



I'm sorry, but this is merely hand-waving. It looks appealing, but
there's no rigor there.


Bullshit.


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Peter Otten:

Alf P. Steinbach wrote:


Just as a contribution, since someone hinted that I haven't really
contributed much to the Python community.

The [simple_sound] code will probably go into my ch 3 at http://tinyurl.com/programmingbookP3>, but sans sine wave generation since
I haven't yet discussed trig functions, and maybe /with/ changes suggested
by you?



def _append_as_big_endian_int16_to( a, i ):
 if i < 0:
 i = i + 65536
 assert( 0 <= i < 65536 )
 a.append( i // 256 )
 a.append( i % 256 )



 data = array.array( "B" )   # B -> unsigned bytes.


Do you know that array.array() supports 16 bit signed integers?


Yes. I used bytes since that seemed to be what [wave] required. But I tested now 
and at least [aifc] handles 16-bit integers fine.


Hm, nice example down the drain...


There's even 
a byteswap() method to deal with endianess.



Utility class that may be used to capture output (an instance of this or
any other file like class can be passed as "filename" to
simple_sound.Writer):


class BytesCollector:


Are you reinventing io.BytesIO() here?


Probably. :-) Checking... Yes, I was; thanks!


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Grant Edwards:

On 2010-01-14, Alf P. Steinbach  wrote:


It's not clear to me that you can approximate any waveform
with a suitable combination of square waves,

Oh. It's simple to prove. At least conceptually! :-)


[...]


With the goal of just a rough approximation you can go about
it like this:

   1. Divide a full cycle of the sine wave into n intervals.
  With sine wave frequency f this corresponds to n*f
  sample rate for digital representation.

   2. Each interval will be approximated by a rectangular bar
  extending up to or down to the sine wave. As it happens
  this (the bar's height) is the sample value in a digital
  representation.

   3. In the first half of the cycle, for each bar create that
  bar as a square wave of frequency f, amplitude half the
  bar's height, and phase starting at the bar's left, plus
  same square wave with negative sign (inverted amplitude)
  and phase starting at the bar's right. And voil?, not
  only this bar generated but also the corresponding
  other-way bar in second half of cycle.

   4. Sum all the square waves from step 3.

   5. Let n go to infinity for utter perfectness! :-)

And likewise for any other waveform.

After all, it's the basis of digital representation of sound!


Huh?  I've only studied basic DSP, but I've never heard/seen
that as the basis of digital represention of sound.


Oh, you have... The end result above (for finite n) is a sequence of sample 
values of a sine wave. Ordinary digital representation of sound is exactly the 
same, a sequence of sample values.




I've also never seen that representation used anywhere.


Yes, you have. A sequence of sample values is the representation used in any 
direct wave file. Like [.wav]  and, I believe, [.aiff].




 Can you provide any references?


I don't have any references for the above procedure, it's sort of trivial. 
Probably could find some references with an hour of googling. But no point.



Cheers & hth.,

- Alf


PS: To extend the above to a non-symmetric waveform, just first decompose that 
waveform into sine waves (Fourier transform), then add up the square wave 
representations of each sine wave. :-)

--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Steve Holden:

Grant Edwards wrote:

On 2010-01-14, Alf P. Steinbach  wrote:

[bogus hand-waving]

After all, it's the basis of digital representation of sound!

Huh?  I've only studied basic DSP, but I've never heard/seen
that as the basis of digital represention of sound.  I've also
never seen that representation used anywhere.


Just for the record: Grant has seen that representation numerous times, he just 
didn't recognize it.




 Can you provide any references?



Of course he can't.  And it isn't the basis of analog quantization.


Of course it isn't the basis of quantization: it *is* quantization, directly.

Which is the basis of digital representation.



And I suspect Alf has never hear of Shannon's theorem.


It's about 30 years since I did that stuff.



But don't listen to me, apparently I'm full of it.


You're spouting innuendo and personal attacks, repeatedly, so that seems to be 
the case, yes. :-)



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Steve Holden:

Grant Edwards wrote:

On 2010-01-14, Alf P. Steinbach  wrote:

[bogus hand-waving]

After all, it's the basis of digital representation of sound!

Huh?  I've only studied basic DSP, but I've never heard/seen
that as the basis of digital represention of sound.  I've also
never seen that representation used anywhere.

Just for the record: Grant has seen that representation numerous times,
he just didn't recognize it.



 Can you provide any references?
Of course he can't.  And it isn't the basis of analog quantization.

Of course it isn't the basis of quantization: it *is* quantization,
directly.


Nope, quantization is taking the *instantaneous value* of a waveform and
using that as the representation for one sample period. That is nowhere
near the same as summing periodic square waves.


There are two three things wrong with that paragraph. First, quantization can 
not physically be instantaneous. So it's pretty much moot to try to restrict it 
to that.


Second, for the mathematical exercise you can let the measurement be an 
instantaneous value, that is, the value at a single point.


Third, the result of quantization is a sequence of values, each value present 
for an interval of time, and the same is obtained by summing square waves.


I'm beginning to believe that you maybe didn't grok that simple procedure.

It's very very very trivial, so maybe you were looking for something more 
intricate  --  they used to say, in the old days, "hold on, this proof goes by 
so fast you may not notice it!"




Which is the basis of digital representation.


Well at least we agree that quantization is the basis of digital
representations. But I've never seen any summed square wave presentation
of it.


Well, I'm glad to be able to teach something.

Here's the MAIN IDEA in the earlier procedure: a square wave plus same wave 
offset (phase) and negated, produces a set of more rectangular waveforms, which 
I called "bars"  --  in between the bars the two square waves cancel each other:


 _
| |
| |
  __| |__   __
 | |
 | |
 |_|

The bars alternate in positive and negative direction. They can be made as 
narrow as you wish, and when they are as narrow as each sample interval then 
each bar can represent the sample value residing in that interval. Even a sample 
corresponding to a point measurement (if such were physically possible).


And samples are all that's required for representing the sine. And happily the 
alternation of upgoing and downgoing bars is matched by an identical alternation 
of the sine wave. :-) Otherwise it would be a tad difficult to do this.


But then, representing sines is all that's required for representing any wave 
form, since any wave form can be decomposed into sines.




And I suspect Alf has never hear of Shannon's theorem.

It's about 30 years since I did that stuff.


Well me too, but information theory is, after all, the theoretical
underpinning for the way I make my living, so I felt obliged to study it
fairly thoroughly.

But don't listen to me, apparently I'm full of it.

You're spouting innuendo and personal attacks, repeatedly, so that seems
to be the case, yes. :-)


Nothing personal about it. I'm just asking you to corroborate statements
you have made which, in my ignorance, I consider to be bogus hand-waving.


OK.

May I then suggest going through the procedure I presented and *draw* the square 
waves.


I dunno, but maybe that can help.



Nothing about you there. Just the information you are promoting. I don't
normally deal in innuendo and personal attacks. Though I do occasionally
get irritated by what I perceive to be hogwash. People who know me will
tell you, if I am wrong I will happily admit it.


There's a difference between an algorithm that you can implement, and hogwash.


Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Lie Ryan:

On 01/15/10 05:42, Alf P. Steinbach wrote:

I'm beginning to believe that you maybe didn't grok that simple procedure.

It's very very very trivial, so maybe you were looking for something
more intricate  --  they used to say, in the old days, "hold on, this
proof goes by so fast you may not notice it!"


Since you said it's trivial, then...


You can't get it more trivial.



Nothing about you there. Just the information you are promoting. I don't
normally deal in innuendo and personal attacks. Though I do occasionally
get irritated by what I perceive to be hogwash. People who know me will
tell you, if I am wrong I will happily admit it.

There's a difference between an algorithm that you can implement, and
hogwash.


please prove your claim by writing that algorithm in code and post it in
this list. The program must accept a .wav file (or sound format of your
choice) and process it according to your algorithm and the output
another .wav file (or sound format of your choice) that sounds roughly
similar to the input file.


First, the (very very trivial) algorithm I posted does *not* do that: by itself 
it represents a sine wave, not an arbitrary wave form.


And second I'm not about to write Fourier transform code to satisfy someone who 
refuses to do a milligram of thinking.


The Fourier part stuff needed to do what you're requesting is non-trivial, or at 
least it's some work to write the code.




PS: I have near-zero experience with sound processing
PPS: I will be equally delighted seeing either Steve admitting his wrong
or you admit your hogwash
PPPS: An alternative way to convince us is to provide a paper/article
that describes this algorithm.
S: Though I will be quite sad if you choose to reject the challenge


I don't believe any of what you write here.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Lie Ryan:

On 01/15/10 05:42, Alf P. Steinbach wrote:

I'm beginning to believe that you maybe didn't grok that simple procedure.

It's very very very trivial, so maybe you were looking for something
more intricate  --  they used to say, in the old days, "hold on, this
proof goes by so fast you may not notice it!"


Since you said it's trivial, then...


Nothing about you there. Just the information you are promoting. I don't
normally deal in innuendo and personal attacks. Though I do occasionally
get irritated by what I perceive to be hogwash. People who know me will
tell you, if I am wrong I will happily admit it.

There's a difference between an algorithm that you can implement, and
hogwash.


please prove your claim by writing that algorithm in code and post it in
this list. The program must accept a .wav file (or sound format of your
choice) and process it according to your algorithm and the output
another .wav file (or sound format of your choice) that sounds roughly
similar to the input file.


In addition to my earlier reply (that the presented algorithm itself doesn't 
generate arbitrary wave forms but only sines, i.e. that you're totally off the 
mark),


your request is meaningless in another way, namely:

the algorithm does synthesis, which is easy (like computer speech), while you're 
asking for analysis (like computer speech recognition), which is hard.


But maybe you're simply not able to understand the algorithm, trivial as it is.

So, a Python implementation (note, this program takes some time to run!):



# Generating a sine wave as a sum of square waves of various amplitudes & 
phases.
import simple_sound


# Step 1"Divide a full cycle of the sine wave into n intervals."
n = 100


# Step 2-- Just an explanation of the rest


# Step 3"In the first half of the cycle, for each bar create that bar as
#   a square wave of frequency f, amplitude half the bar's height, and 
phase
#   starting at the bar's left, plus same square wave with negative sign
#   (inverted amplitude) and phase starting at the bar's right."

square_waves = []
for i in range( n//2 ):
middle_of_interval = (i + 0.5)/n
amp = simple_sound.sample_sine( 1, middle_of_interval ) / 2
def first_square_wave( t, i = i, amp = amp ):
phase = i/n
return amp*simple_sound.sample_square( 1, t - phase )
def second_square_wave( t, i = i, amp = amp ):
phase = (i + 1)/n
return -amp*simple_sound.sample_square( 1, t - phase )
square_waves.append( first_square_wave )
square_waves.append( second_square_wave )


# Step  4   "Sum all the square waves from step 3."

def sample_squares( f, t ):
samples = []
o_time = f*t
for func in square_waves:
sq_sample = func( o_time )
samples.append( sq_sample )
return sum( samples )


# Finally, generate this is in a [.aiff] file so as to possibly satisfy Lie 
Rian:
if True:
f   = 440
sample_rate = 44100
total_time  = 2
n_samples   = sample_rate*total_time

writer = simple_sound.Writer( "sinewave.aiff" )
for i in range( n_samples ):
t = 1*i/sample_rate
sample = sample_squares( f, t )
writer.write( sample )
writer.close()



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Lie Ryan:

On 01/15/10 05:42, Alf P. Steinbach wrote:

I'm beginning to believe that you maybe didn't grok that simple
procedure.

It's very very very trivial, so maybe you were looking for something
more intricate  --  they used to say, in the old days, "hold on, this
proof goes by so fast you may not notice it!"

Since you said it's trivial, then...

You can't get it more trivial.



Nothing about you there. Just the information you are promoting. I
don't
normally deal in innuendo and personal attacks. Though I do
occasionally
get irritated by what I perceive to be hogwash. People who know me will
tell you, if I am wrong I will happily admit it.

There's a difference between an algorithm that you can implement, and
hogwash.

please prove your claim by writing that algorithm in code and post it in
this list. The program must accept a .wav file (or sound format of your
choice) and process it according to your algorithm and the output
another .wav file (or sound format of your choice) that sounds roughly
similar to the input file.

First, the (very very trivial) algorithm I posted does *not* do that: by
itself it represents a sine wave, not an arbitrary wave form.

And second I'm not about to write Fourier transform code to satisfy
someone who refuses to do a milligram of thinking.

The Fourier part stuff needed to do what you're requesting is
non-trivial, or at least it's some work to write the code.



PS: I have near-zero experience with sound processing
PPS: I will be equally delighted seeing either Steve admitting his wrong
or you admit your hogwash
PPPS: An alternative way to convince us is to provide a paper/article
that describes this algorithm.
S: Though I will be quite sad if you choose to reject the challenge

I don't believe any of what you write here.


Well, it seems quite reasonable to me, but then I'm not the one being
challenged to write a trivial algorithm.


You're again into innuendo, misleading statements and so forth. Lie Ryan's 
challenge is nothing but trivial, because it's about implementing very much more 
than the algorithm. I did implement the algorithm for him, in Python, and posted 
that in this thread.




I will, however, observe that your definition of a square wave is what I
would have to call a "'square' wave" (and would prefer to call a "pulse
train"), as I envisage a square wave as a waveform having a 50% duty
cycle, as in

 ___ ___
|   |   |   |
|   |   |   |
|   |   |   |
+---+---+---+---+ and so on ad infinitum, (though I might allow you
|   |   |   |  to adjust the position
|   |   |   |  of y=0 if you want)
|___|   |___|

as opposed to your

 _
| |
| |
  __| |__   __
 | |
 | |
 |_|



Try to read again, a sufficient number of times, how to generate the latter by 
summing *two instances of the former*.


I'm sorry to say this but I find it hard to explain things simple enough for 
you, because at the level of 2+2 any explanation is far more complex than the 
concept itself.


That is, of course, a challenge to me! :-)

So, thanks for challenging my pedagogical abilities.

I know they're not as good as they should be, and need some exercise!



So I can see how we might be at cross purposes. I could cite authorities
for differentiating between a square wave and a symmetric pulse train,
but will content myself with observing only that my impression is the
common definition of an ideal square wave (one with a zero transition
time) admits of only two instantaneous values, eschewing the zero you
use. If that is the case, we could perhaps agree that we differ merely
on terminology.


No, we don't differ on terminology: we seem to differ in that one of us has 
severe difficulties understanding the very simplest things, such as what graph 
one gets by summing two squares waves of same frequency but out of phase.


The one of us who has trouble understanding that is also apparently too lazy to 
try out the earlier advice given him of graphing this on a piece of paper, and 
instead prefers to spout innuendu, personal attacks and misleading statements.


That's a real challenge to the other person.



Or, best of all, you could show me how to synthesize any waveform by
adding square waves with a 50% duty cycle.  Then I *will* be impressed.


You would, yes?

Perhaps you'd also admit to being wrong, and retract your innuoendo etc.?

Well, just epress the waveform as a sum of sine waves (Fourier transform); 
synthesize each sine wave by a set of 50% duty cycle square waves (I've earlier 
posted Python code for that in this thread); add all the square waves. The hard 
part of this is implementing the Fourier transform, I leave that to you. ;-)



Cheers & htfh.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-14 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:
[...]

Perhaps you'd also admit to being wrong, and retract your innuoendo etc.?


Disregarding any matters of right or wrong (for this post, at least), I
herebe retract anything I have said about you that you consider
innuendo.


OK.



Feel free to remind me what that was.


It would IMHO serve no good purpose to reiterate that. At this point, let's just 
start fresh.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-15 Thread Alf P. Steinbach

* Steven D'Aprano:

On Fri, 15 Jan 2010 05:23:48 +0100, Alf P. Steinbach wrote:


You're again into innuendo, misleading statements and so forth.

[...]

[Steve Holden] prefers to spout innuendu, personal attacks and
misleading statements.


Your constant and repeated accusations that any questioning of you is 
deliberate lying and innuendo (innuendo of what, I wonder?) is getting 
tiresome. You did this to me, accusing me of deliberate lying, and now 
you're doing the same to Steve.


You did lie, that's established. In addition as I recall in the same post you 
went on about my motivations for doing the Terrible Deed that you invented. And 
you named one poor person who'd made a silly mistake, stating that he didn't do 
what the logs clearly showed he did do, and I think that was to force me to 
argue a case against him (but happily he did a superb job after that initial 
mistake, it would have been much harder for me to respond to your egging if not 
for that very good job he did).


And now you're trying to get me to argue a case against another person.

That's not very nice.


Just because people question the (alleged) facts as you report it doesn't 
mean they're deliberately trying to mislead others. Hasn't it occurred to 
you that perhaps we're not deliberately lying to make you look bad but 
actually think you are mistaken? A difference of opinion is not evidence 
that people are lying.


Mostly I assume that people who disagree with me think I'm mistaken, yes.

But when someone writes an article that's mainly or only about me, as has 
happened once earlier in this thread and that now you're doing, then I of course 
assume that it's personal, that the person writing has transferred some 
grievances from the technical domain to the personal domain.



For somebody who fancies himself a writer teaching beginners to 
programming, your communication skills leave something to be desired. I 
hope your book is better than your posts, because from what I have seen 
your writing in this newsgroup is frequently sloppy and hard to 
understand, you tend to use terms in non-standard ways and then take any 
misunderstandings as a personal affront, and if anyone questions what you 
say, you're likely bristle and start looking for a fight.


I'm probably a bad person, he he. :-)


I don't know what your problem is, but I wish you'd deal with it in 
private and stop dumping it on the rest of us. You're a smart fellow who 
brings much of value to the community, but dealing with your posts is 
becoming more trouble than they're worth.


Well please stop posting these silly articles about me, and *please* stop 
dragging other people into it.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-15 Thread Alf P. Steinbach

* Ben Finney:

"Alf P. Steinbach"  writes:


You did lie, that's established. In addition as I recall in the same
post you went on about my motivations for doing the Terrible Deed that
you invented.


None of that matches my (largely disinterested) observations. This is
pure fantasy, as best I can tell.


It's decidedly not kind of you to try to re-open those issues.

Anybody can have a bad day and write something that's untrue or actively 
misleading, whatever.


When it's been dealt with, and it has, it should not be reiterated.



I've tried in private to talk you out of this persecution fantasy;
others have tried in public. It all seems to be in vain.


It's quite normal for people to use ad hominem arguments, especially when they 
have chosen an indefensible position; that's why the technique has a name.


There's no persecution involved in that.

And people are not necessarily bad even when they do that from time to time, as 
you do here: it's human.




You've now passed my twit threshold, so welcome to my kill file.


Goodbye.


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-15 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Ben Finney:

"Alf P. Steinbach"  writes:


You did lie, that's established. In addition as I recall in the same
post you went on about my motivations for doing the Terrible Deed that
you invented.

None of that matches my (largely disinterested) observations. This is
pure fantasy, as best I can tell.

It's decidedly not kind of you to try to re-open those issues.

Anybody can have a bad day and write something that's untrue or actively
misleading, whatever.

When it's been dealt with, and it has, it should not be reiterated.



I've tried in private to talk you out of this persecution fantasy;
others have tried in public. It all seems to be in vain.

It's quite normal for people to use ad hominem arguments, especially
when they have chosen an indefensible position; that's why the technique
has a name.

There's no persecution involved in that.

And people are not necessarily bad even when they do that from time to
time, as you do here: it's human.



You've now passed my twit threshold, so welcome to my kill file.

Goodbye.


Cheers & hth.,

- Alf


How you can possibly hope that helps anyone except you I can't possibly
imagine. It seems that any request to question your own behavior, any
remark about how it might usefully change, is taken to be an ad homime,
attack.

As my wife (who has a colorful Scottish turn of phrase) might say, if
you were chocolate you would eat yourself.

Please, get over this obsession with being "right".


You have (so far) refused to outright admit that you were wrong here, going to 
the extreme half-way measure of using the word "wring" or something, perhaps 
hoping that I'd interpret it one way and most everyone else another way.


I do respond to articles which are technically wrong, especially follow-ups to 
my own articles, as your (at least initial) POV was in this thread: wrong.


That's not an obsession, nor is it a desire to be right, it's the *usual* Usenet 
culture: one is expected to respond and to correct technical issues, and to not 
collect social points at the expense of technical correctness.


And since it's you who brings this up again, and since earlier you wrote ...

  "I herebe retract anything I have said about you that you consider
  innuendo. Feel free to remind me what that was."

... I now feel free to remind you about some of it.

Instead of saying OK or thanks or whatever normal for a simple explanation, you 
pretended that my explanation was some kind of thesis from me and "this is 
merely hand-waving. It looks appealing, but there's no rigor there".


And with our last discussion before this one fresh in mind I told you that that 
was bullshit, using just that single word. But to expand on that: the 
insinuation that the explanation was some kind of thesis from me was bullshit, 
that it was merely "hand-waiving" was bullshit (while informal it was an exact 
algorithm, and later in this thread I posted Python code implementing it), and 
that it had "no rigor" was bullshit since it was an exact algorithm; moreover it 
was a *trivial* algorithm, and as demonstrated, it works.


In short, the insinuation that I was some kind of crank posting a thesis that 
lacked "rigor" and was "hand-waiving" was utter bullshit: it was a trivial and 
exact algorithm, an explanation in response to your own question, and it 
demonstrably works.


In response to someone else you then posted this:



Grant Edwards wrote:
> > On 2010-01-14, Alf P. Steinbach  wrote:
[bogus hand-waving]
>> >> After all, it's the basis of digital representation of sound!
> >
> > Huh?  I've only studied basic DSP, but I've never heard/seen
> > that as the basis of digital represention of sound.  I've also
> > never seen that representation used anywhere.  Can you provide
> > any references?
> >
Of course he can't. And it isn't the basis of analog quantization. And I
suspect Alf has never hear of Shannon's theorem.

But don't listen to me, apparently I'm full of it.

regards
 Steve



* The "of course he can't [provide a reference]"

is the same insinuation you made earlier repeated, that what I posted was 
drivel, when it was a trivial and exact algorithm, one that does work.



* "Isn't the basis of analog quantization"

makes the reader believe I'd written that nonsense "basis of analog 
quantization". I did not write such nonsense but readers get the impression that 
I did. The quote above shows what I wrote instead of the words you put in my mouth.



* "And I suspect Alf has never hear of Shannon's theorem."

is solely about me, an insinuation about my education or competence.


* "But don't listen to me, 

Re: A simple-to-use sound file writer

2010-01-15 Thread Alf P. Steinbach

* Steve Holden:


For the record, yes, summing any waveforms that can be represented as
Fourier Series will necessarily result in another Fourier series, since
any linear combination of Fourier series must itself, be a Fourier
series, and therefore the representation of the sum of the summed waveforms.


As it is I do not know whether the above represents what I've written, or might 
perhaps be /misprepresenting/ the conclusions of this thread.


If I knew a lot more about Fourier series (it's been a long time since college! 
lots forgotten) I might agree or disagree with the above as it applies to 
constructing a sine wave from square waves.


I just note that representing a sine wave as square waves, forming it from 
square waves, in the practical sense works (demonstrated here), even though it's 
totally impractical :-), but just in answer to your original question.


And I note that in the mathematematical sense when n goes to infinity and 
vanishingly thin pulses result from sums of square waves, like *impulse* waves, 
then one is over in some regime where it is not at all clear to me that it is 
valid to talk about Fourier series any more. Perhaps it's valid if the term 
"Fourier series" does not necessarily imply sum of sine waves. I don't know.


I'm guessing that applying the Fourier series view for that is like actually 
dividing by zero to maintain the running product of a collection of numbers when 
an instance of 0 is removed from the collection.


It's no practical problem to maintain a running product (for programmers it's 
interesting to note that polar representation complex numbers can do the job), 
and it's well-defined also mathematically, with any /reasonable/ approach. But 
the simple-minded direct way, just dividing the current product by the number 
removed from the collection, is then invalid. And some people might take that 
limited applicability of the direct simple way as evidence that it's impossible 
to remove numbers, failing to see any of the trivial practical solutions. ;-)



Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-15 Thread Alf P. Steinbach

* Grant Edwards:

On 2010-01-15, Steve Holden  wrote:


I will, however, observe that your definition of a square wave is what I
would have to call a "'square' wave" (and would prefer to call a "pulse
train"), as I envisage a square wave as a waveform having a 50% duty
cycle, as in

 ___ ___
|   |   |   |
|   |   |   |
|   |   |   |
+---+---+---+---+ and so on ad infinitum, (though I might allow you
|   |   |   |  to adjust the position
|   |   |   |  of y=0 if you want)
|___|   |___|


That is a square wave.


as opposed to your

 _
| |
| |
  __| |__   __
 | |
 | |
 |_|


That isn't.

Arguing to the contrary is just being Humpty Dumpty...


Neither I nor Steve has called that latter wave a square wave.

Steve, quoted above, has written that I defined a square wave that way. I have 
not. So Steve's statement is a misrepresentation (I described it as a sum of two 
square waves, which it is), whatever the reason for that misrepresentation.




Or, best of all, you could show me how to synthesize any
waveform by adding square waves with a 50% duty cycle.  Then I
*will* be impressed.


Isn't that what he claimed?  He said that his algorithm for
summing square waves demonstrated the converse of the ability
to construct a periodic function (like a square wave) from a
sine-cosine summation.


Not by itself, no: it just synthesizes a sine.

For the more general case read e.g. the PS in my reply to your earlier (single) 
article in this thread.


For information about what the algorithm does, what you refer to as a "claim" 
(but note that a Python implementation has been posted to this thread, and that 
it works, and that besides the algorithm is trivial so that "claim" is a rather 
meaningless word here), read the article that you then responded to.



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using invalid.com email addresses

2010-01-15 Thread Alf P. Steinbach

* D'Arcy J.M. Cain:

Damn!  I missed the @invalid.com in the address.  I'm not sure why I
just didn't do this before but @invalid.com just went into my
blacklist.

Does anyone else think that that behaviour is just rude, not to mention
in violation of the RFCs?


In RFC violation yes.



   To safely satisfy these needs, four domain names are reserved as
   listed and described below.

   .test
.example
.invalid
  .localhost

  ".test" is recommended for use in testing of current or new DNS
  related code.

  ".example" is recommended for use in documentation or as examples.

  ".invalid" is intended for use in online construction of domain
  names that are sure to be invalid and which it is obvious at a
  glance are invalid.

  The ".localhost" TLD has traditionally been statically defined in
  host DNS implementations as having an A record pointing to the
  loop back IP address and is reserved for such use.  Any other use
  would conflict with widely deployed code which assumes this use.



Rude, no, it's probably someone who thought that /including/ the word "invalid" 
was the way to do it.



Cheers, just my 3 øre,

- Alf

PS: in the same way, not including "OT" in the subject line here might be 
considered rude. But then, if I were to add it, some newsreader might split the 
thread. So it's difficult to please everyone! :-)

--
http://mail.python.org/mailman/listinfo/python-list


Re: maintain 2 versions of python on my computer

2010-01-16 Thread Alf P. Steinbach

* Gertjan Klein:


What I've been thinking about is to write a single [Windows] executable that
gets associated with .py and .pyw (instead of python.exe itself).


Well, you need two: one for console subsystem, and one for GUI subsystem.

Happily you can use the same source code. :-)



This
executable would parse the #! line to look for a specific python
version, or use a configured default if none found (or a parsing error
occurs). It would then invoke the appropriate python version (with
whatever arguments, if any, are supplied).

As far as I can see, this allows both typing the script name and
arguments (i.e., without python31 before it) from a command prompt, and
doubleclicking on a .py or .pyw file from windows explorer. In both
cases, the proper python executable would be used to run the script.

What's been holding me back so far is that probably needs to be written
in C, to prevent the Python runtime's startup overhead. I haven't
written any significant amount of C code in years, if not decades, so
that seems like a daunting task to me at the moment. ;-)


If it's OK with C++, I just sat down and wrote this.

It's not especially well tested (or almost not at all), and it's limited.

It handles or is meant to handle Unicode script file paths, but the path to the 
Python interpreter, specified in a "#!" comment in the script's first line, must 
be single byte per character. And if that path contains spaces must be quoted.




// Note: in order to handle Unicode paths needs to use Windows API command line.
//
// If this code works then it was written (but not tested) by Alf P. Steinbach.
// Otherwise it's someone impersonating me.

#include// std::wstring
#include// std::vector
#include
#include
#include

#undef  STRICT
#undef  NOMINMAX
#undef  UNICODE
#define STRICT
#define NOMINMAX
#define UNICODE
#include // CommandLineToArgvW, GetCommandLine

using namespace std;


//-- Various things ordinarily from libraries...

bool throwX( char const s[] ) { throw std::runtime_error( s ); }

typedef ptrdiff_t   Size;

template< typename Container >
Size n_elements( Container const& c ) { return c.size(); }

// The C++98 standard library doesn't offer Unicode filename functionality.
// Using library extension that works with GNU g++ and Microsoft Visual C++.
class TextFileReader
{
private:
FILE*   f;
TextFileReader( TextFileReader const& );// No copy constructor.
TextFileReader& operator=( TextFileReader const& ); // No assignment.

public:
TextFileReader( wstring const& path )
: f( _wfopen( path.c_str(), L"r" ) )
{
(f != 0) || throwX( "Unable to open file for reading" );
}

~TextFileReader() { fclose( f ); }

wstring line()
{
wstring s;
for( ;; )
{
int const c = fgetc( f );
if( c == EOF || c == L'\n' ) { break; }
s.push_back( wchar_t( c ) );
}
return s;
}
};

wstring substring( wstring const& s, Size const i, Size const n = -1 )
{
wstring::size_type constcount   = (n == -1? wstring::npos : n);
return (i >= n_elements( s )? L"" : s.substr( i, count ));
}

//-- Main

typedef wstring String;
typedef vector  StringVector;


StringVector cmdArguments()
{
struct Args
{
wchar_t**   p;
int n;

Args()
{
p = CommandLineToArgvW( GetCommandLine(), &n );
(p != 0) || throwX( "Unable to obtain command line arguments" );
}

~Args() {  GlobalFree( p ); }
};

Args const  args;
return StringVector( args.p, args.p + args.n );
}

int run( wstring const& prog_path, wstring const& args )
{
wstring cmd_line= prog_path + L" " + args;

cmd_line.c_str();
PROCESS_INFORMATION process_info= {};
STARTUPINFO startup_info= { sizeof( startup_info ) };
bool const ok   = !!CreateProcess(
0,  // application name
&cmd_line[0],   // command line
0,  // process security attributes
0,  // thread security attributes
TRUE,   // inherit handles
0,  // creation flags
0,  // environment, 0 => inherit parent process env.
0,  // current directory
&startup_info,
&process_info
);
(ok)
|| throwX( "Unable to run the interpreter" );


bool const  wait_ok =
(WaitForSingleObject( process_info.hProcess, INFINITE ) != WAIT_FAILED);

DWORD   exit_code   = EXIT_FAILURE;
GetExitCodeProcess( process_info.hProcess, &exit_code );
CloseHandle( process_in

Re: A simple-to-use sound file writer

2010-01-16 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Grant Edwards:

On 2010-01-15, Steve Holden  wrote:


I will, however, observe that your definition of a square wave is what I
would have to call a "'square' wave" (and would prefer to call a "pulse
train"), as I envisage a square wave as a waveform having a 50% duty
cycle, as in

 ___ ___
|   |   |   |
|   |   |   |
|   |   |   |
+---+---+---+---+ and so on ad infinitum, (though I might allow you
|   |   |   |  to adjust the position
|   |   |   |  of y=0 if you want)
|___|   |___|

That is a square wave.


as opposed to your

 _
| |
| |
  __| |__   __
 | |
 | |
 |_|

That isn't.

Arguing to the contrary is just being Humpty Dumpty...

Neither I nor Steve has called that latter wave a square wave.

Steve, quoted above, has written that I defined a square wave that way.
I have not. So Steve's statement is a misrepresentation (I described it
as a sum of two square waves, which it is), whatever the reason for that
misrepresentation.



Or, best of all, you could show me how to synthesize any
waveform by adding square waves with a 50% duty cycle.  Then I
*will* be impressed.

Isn't that what he claimed?  He said that his algorithm for
summing square waves demonstrated the converse of the ability
to construct a periodic function (like a square wave) from a
sine-cosine summation.

Not by itself, no: it just synthesizes a sine.

For the more general case read e.g. the PS in my reply to your earlier
(single) article in this thread.

For information about what the algorithm does, what you refer to as a
"claim" (but note that a Python implementation has been posted to this
thread, and that it works, and that besides the algorithm is trivial so
that "claim" is a rather meaningless word here), read the article that
you then responded to.


Though for what it's worth I wasn't impressed by the results of running
the posted program, since it yielded an AIFF file of mostly zeroes that
produced no audible sound.

$ od -bc sinewave.aiff
000 106 117 122 115 000 002 261 076 101 111 106 106 103 117 115 115
  F   O   R   M  \0 002 261   >   A   I   F   F   C   O   M   M
020 000 000 000 022 000 001 000 001 130 210 000 020 100 016 254 104
 \0  \0  \0 022  \0 001  \0 001   X 210  \0 020   @ 016 254   D
040 000 000 000 000 000 000 123 123 116 104 000 002 261 030 000 000
 \0  \0  \0  \0  \0  \0   S   S   N   D  \0 002 261 030  \0  \0
060 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
 \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0530500 000 000 000 000 000 000
 \0  \0  \0  \0  \0  \0
0530506

Any idea what I did wrong?


That sounds like something I did wrong, not like something you did wrong:

It sounds like a  ...  BUG!  ... in my simple_writer code. :-)

Or, that's perhaps not funny, but it occurred to me that it might, to some at 
least, appear to be sort of incongruous in the context of the earlier thread. Heh.


Checking first 20 sample values generated:


if True:
f   = 440
sample_rate = 44100
total_time  = 2
n_samples   = sample_rate*total_time

writer = simple_sound.Writer( "sinewave.aiff" )
for i in range( n_samples ):
t = 1*i/sample_rate
sample = sample_squares( f, t )
if i < 20: print( sample )# Check 'em
writer.write( sample )
writer.close()



-0.0314107590781
-0.0314107590781
-0.0941083133185
-0.15643446504
-0.218143241397
-0.278991106039
-0.338737920245
-0.397147890635
-0.45399049974
-0.50904141575
-0.562083377852
-0.612907053653
-0.661311865324
-0.707106781187
-0.75011106963
-0.790155012376
-0.827080574275
-0.860742027004
-0.891006524188
-0.917754625684


Checking generated file:


$ od -bc sinewave.aiff | head
000 106 117 122 115 000 001 130 266 101 111 106 106 103 117 115 115
  F   O   R   M  \0 001   X 266   A   I   F   F   C   O   M   M
020 000 000 000 022 000 001 000 000 254 104 000 020 100 016 254 104
 \0  \0  \0 022  \0 001  \0  \0 254   D  \0 020   @ 016 254   D
040 000 000 000 000 000 000 123 123 116 104 000 001 130 220 000 000
 \0  \0  \0  \0  \0  \0   S   S   N   D  \0 001   X 220  \0  \0
060 000 000 000 000 000 000 373 373 373 373 363 364 353 372 344 024
 \0  \0  \0  \0  \0  \0 373 373 373 373 363 364 353 372 344 024
100 334 112 324 245 315 053 305 344 276 330 270 016 261 215 253 133
334   J 324 245 315   + 305 344 276 330 270 016 261 215 253   [



Hm, I'm inclined to think that you used Python 2.x instead of my 3.1.1!

I no longer have Python 2.x installed, I think, so no time to test that now.

But would that be the case?

If so, perhaps changing "t = 1*i/sample_rat

Re: A simple-to-use sound file writer

2010-01-16 Thread Alf P. Steinbach

* Alf P. Steinbach:

* Steve Holden:



Though for what it's worth I wasn't impressed by the results of running
the posted program, since it yielded an AIFF file of mostly zeroes that
produced no audible sound.

$ od -bc sinewave.aiff
000 106 117 122 115 000 002 261 076 101 111 106 106 103 117 115 115
  F   O   R   M  \0 002 261   >   A   I   F   F   C   O   M   M
020 000 000 000 022 000 001 000 001 130 210 000 020 100 016 254 104
 \0  \0  \0 022  \0 001  \0 001   X 210  \0 020   @ 016 254   D
040 000 000 000 000 000 000 123 123 116 104 000 002 261 030 000 000
 \0  \0  \0  \0  \0  \0   S   S   N   D  \0 002 261 030  \0  \0
060 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
 \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0530500 000 000 000 000 000 000
 \0  \0  \0  \0  \0  \0
0530506

Any idea what I did wrong?



[snip]



Hm, I'm inclined to think that you used Python 2.x instead of my 3.1.1!

I no longer have Python 2.x installed, I think, so no time to test that 
now.


But would that be the case?

If so, perhaps changing "t = 1*i/sample_rate" to "t = 
(1.0*i)/sample_rate" will help?


I fixed up two more divisions. Not sure if this is 2.x-compatible, but perhaps:




# Python 3.1.1  --  *probably* works also with 2.x?
# Generating a sine wave as a sum of square waves of various amplitudes & 
phases.
import simple_sound


# Step 1"Divide a full cycle of the sine wave into n intervals."
n = 100


# Step 2-- Just an explanation of the rest


# Step 3"In the first half of the cycle, for each bar create that bar as
#   a square wave of frequency f, amplitude half the bar's height, and 
phase
#   starting at the bar's left, plus same square wave with negative sign
#   (inverted amplitude) and phase starting at the bar's right."

square_waves = []
for i in range( n//2 ):
middle_of_interval = (i + 0.5)/n
amp = simple_sound.sample_sine( 1, middle_of_interval ) / 2.0
def first_square_wave( t, i = i, amp = amp ):
phase = 1.0*i/n
return amp*simple_sound.sample_square( 1.0, t - phase )
def second_square_wave( t, i = i, amp = amp ):
phase = 1.0*(i + 1)/n
return -amp*simple_sound.sample_square( 1.0, t - phase )
square_waves.append( first_square_wave )
square_waves.append( second_square_wave )


# Step  4   "Sum all the square waves from step 3."

def sample_squares( f, t ):
samples = []
o_time = f*t
for func in square_waves:
sq_sample = func( o_time )
samples.append( sq_sample )
return sum( samples )


# Finally, generate this is in an [.aiff] file:
if True:
f   = 440
sample_rate = 44100
total_time  = 2
n_samples   = sample_rate*total_time

writer = simple_sound.Writer( "sinewave.aiff" )
for i in range( n_samples ):
t = 1.0*i/sample_rate
sample = sample_squares( f, t )
writer.write( sample )
writer.close()



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: maintain 2 versions of python on my computer

2010-01-16 Thread Alf P. Steinbach

* Gertjan Klein:

Alf P. Steinbach wrote:


* Gertjan Klein:

What I've been thinking about is to write a single [Windows] executable that
gets associated with .py and .pyw (instead of python.exe itself).

Well, you need two: one for console subsystem, and one for GUI subsystem.


Why? I'd have imagined writing something for the GUI subsystem (without
actually creating a GUI, just to prevent a DOS box popping up), creating
the proper commandline, with either python.exe or pythonw.exe, and
launching that as a separate process. (I have no idea whether this would
actually work though -- I'm just thinking out loud at this stage.)

Thinking about it some more, perhaps that way I can't get at return
codes a python script might provide. I haven't used those, but they may
be useful at some point.


Return codes work OK no matter what.

But it's a hassle for the user to connect up standard input, standard output and 
standard error for a GUI subsystem process.


That's mainly why the distinction between [.py] and [.pyw] is there in Windows: 
the former is associated with console subsystem interpreter ensuring that the 
standard streams are connected up automatically, the latter is associated with 
GUI subsystem interpreter ensuring no automatic console window.




If it's OK with C++, I just sat down and wrote this.


Thanks for that. I won't be using it though; I don't know C++ at all,
and the source looks like complete gobbledygook to me. I wouldn't know
where to begin to change anything in it. ;-)


Ah, well.

Perhaps do this in JScript or VBScript (languages bundled with Windows)? There 
may be less startup overhead than with Python. But I haven't checked.




Cheers,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: maintain 2 versions of python on my computer

2010-01-16 Thread Alf P. Steinbach

* Gertjan Klein:

Alf P. Steinbach wrote:


* Gertjan Klein:

Alf P. Steinbach wrote:

Thinking about it some more, perhaps that way I can't get at return
codes a python script might provide. I haven't used those, but they may
be useful at some point.

Return codes work OK no matter what.


Ok, I won't have to worry about that then. ;-)

But it's a hassle for the user to connect up standard input, standard output and 
standard error for a GUI subsystem process.


Good point. Two executables it is. But out of curiousity, what happens
when a user pipes something into a GUI subsystem executable?


The same as with a console program, I guess.

Indeed piping is one way to connect up the output.

Disclaimer: I can't recall ever actually trying to pipe input to a GUI subsystem 
exe. However, piping output, while not common, at least I've done that! :-)



Perhaps do this in JScript or VBScript (languages bundled with Windows)? There 
may be less startup overhead than with Python. But I haven't checked.


Won't these create a DOS window, always?


No. They're run via the Windows Script Host interface. WSH has two runner 
programs: cscript (console) and wscript (GUI). So you get a console window (it's 
tehnically not DOS although the icon was MS-DOS until and including Windows NT 
4.0) if you run a [.js] or [.vbs] file via cscript, and not via wscript.


wscript is the default.

But you can change that association, or create new associations, via the Windows 
'assoc' and 'ftype' commands (note that after some XP update 'ftype' is no 
longer able to delete associations, it must then be done directly in registry).




Or can they run windowless as well?


Yes, see above.



If so, that might be an option worth exploring as well.




Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-16 Thread Alf P. Steinbach

* Steve Holden:

Alf P. Steinbach wrote:

* Steve Holden:

Alf P. Steinbach wrote:

* Grant Edwards:

On 2010-01-15, Steve Holden  wrote:


I will, however, observe that your definition of a square wave is
what I
would have to call a "'square' wave" (and would prefer to call a
"pulse
train"), as I envisage a square wave as a waveform having a 50% duty
cycle, as in

 ___ ___
|   |   |   |
|   |   |   |
|   |   |   |
+---+---+---+---+ and so on ad infinitum, (though I might allow you
|   |   |   |  to adjust the position
|   |   |   |  of y=0 if you want)
|___|   |___|

That is a square wave.


as opposed to your

 _
| |
| |
  __| |__   __
 | |
 | |
 |_|

That isn't.

Arguing to the contrary is just being Humpty Dumpty...

Neither I nor Steve has called that latter wave a square wave.

Steve, quoted above, has written that I defined a square wave that way.
I have not. So Steve's statement is a misrepresentation (I described it
as a sum of two square waves, which it is), whatever the reason for that
misrepresentation.





[snip]

So here you have an interesting example of a
piece of code that is pathological in Python2. All you have to change is
to add

  from __future__ import __division__

and bingo! It's a multi-language program. But try seeing what 2to3 says
about your Python3 code :)

I will forgive you the omission of the ".0" because I too would assume
that it would be slower.


I did not make any such assumption, no. The *1 just lingered from some testing.


[snip]

and so on, but I still get silence from the Quicktime player.


I don't know, sorry.

It might be that [simple_sound] also needs the "from __future__" treatment.

But anyway, with 2.x compatible code you can now see that the sample values 
produced are correct (just print them, or graph them).



Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list


Re: A simple-to-use sound file writer

2010-01-17 Thread Alf P. Steinbach

* Alf P. Steinbach:

* Steve Holden:

Alf P. Steinbach wrote:

* Steve Holden:

Alf P. Steinbach wrote:

* Grant Edwards:

On 2010-01-15, Steve Holden  wrote:


I will, however, observe that your definition of a square wave is
what I
would have to call a "'square' wave" (and would prefer to call a
"pulse
train"), as I envisage a square wave as a waveform having a 50% duty
cycle, as in

 ___ ___
|   |   |   |
|   |   |   |
|   |   |   |
+---+---+---+---+ and so on ad infinitum, (though I might allow you
|   |   |   |  to adjust the position
|   |   |   |  of y=0 if you want)
|___|   |___|

That is a square wave.


as opposed to your

 _
| |
| |
  __| |__   __
 | |
 | |
 |_|

That isn't.

Arguing to the contrary is just being Humpty Dumpty...

Neither I nor Steve has called that latter wave a square wave.

Steve, quoted above, has written that I defined a square wave that 
way.
I have not. So Steve's statement is a misrepresentation (I 
described it
as a sum of two square waves, which it is), whatever the reason for 
that

misrepresentation.





[snip]

So here you have an interesting example of a
piece of code that is pathological in Python2. All you have to change is
to add

  from __future__ import __division__

and bingo! It's a multi-language program. But try seeing what 2to3 says
about your Python3 code :)

I will forgive you the omission of the ".0" because I too would assume
that it would be slower.


I did not make any such assumption, no. The *1 just lingered from some 
testing.



[snip]

and so on, but I still get silence from the Quicktime player.


I don't know, sorry.

It might be that [simple_sound] also needs the "from __future__" treatment.

But anyway, with 2.x compatible code you can now see that the sample 
values produced are correct (just print them, or graph them).


I have now installed CPython 2.6.4 and the code presented upthread (the one with 
divisions fixed for 2.x compatibility) worked nicely with CPython 2.6.4, even 
though with a deprecation warning.


It produced the exact same sound file (bytes) as with CPython 3.1.1.

And the QuickTime 7.3 player played it with no problem, a base A pure sinewave, 
composed utterly of 50% duty cycle square waves, resounding in my headphones -- 
it also works with WinAmp 5.54, Windows Mediaplayer 10.00 and VLC 0.9.9, i.e. 
I'm unable to reproduce the problem.


So I suspect that you may lack a suitable codec, or it might be a PEBKAC 
problem?


Cheers & hth.,

- Alf

PS: I had expected some jaggies and such since I only divided the cycle into 100 
intervals, but graphing the data in Excel it showed a perfect sine. :-)

--
http://mail.python.org/mailman/listinfo/python-list


  1   2   3   4   5   6   >