Re: [Tutor] running more than one python program at the same time

2012-09-03 Thread Oscar Benjamin
On Mon, 03 Sep 2012 18:55:43 +0100, Alan Gauld 
 wrote:

On 03/09/12 16:01, Benjamin Fishbein wrote:
> Hi. I started running the program in the terminal rather than 

IDLE. It
> works, and I can run several programs at the same time. The 

problem is

> that when the program is finished running, it prints:
> exit status: 0
> logout
>
> [Process completed]


What do you mean when you say you ran the program in the terminal? Do 
you mean that you opened a terminal window and then typed 'python 
myprog.py'? Or did you click on the python file and choose 'run in 
terminal' or similar? That output looks to me like what happens on 
OSX when a terminal window is open but the shell has been closed.


I think the instruction to run in a terminal should look like:
1) open the terminal (how to do this depends on your OS).
2) type 'cd /path/to/my/script/folder' and then hit enter.
3) type 'python script.py' and then hit enter.

Is that similar to what you're doing?

Oscar

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] running more than one python program at the same time

2012-09-04 Thread Oscar Benjamin
Hi Ben,

It's best if you can avoid top-posting and put your responses in between
the appropriate parts of the message you are replying to like I have below:

On 4 September 2012 02:53, Benjamin Fishbein  wrote:

> I used Python Launcher and it opened it in the terminal.
> Ben
>
> On Sep 3, 2012, at 2:50 PM, Oscar Benjamin wrote:
>
> > On Mon, 03 Sep 2012 18:55:43 +0100, Alan Gauld <
> alan.ga...@btinternet.com> wrote:
> >> On 03/09/12 16:01, Benjamin Fishbein wrote:
> >> > Hi. I started running the program in the terminal rather than
> > IDLE. It
> >> > works, and I can run several programs at the same time. The
> > problem is
> >> > that when the program is finished running, it prints:
> >> > exit status: 0
> >> > logout
> >> >
> >> > [Process completed]
> >
> > What do you mean when you say you ran the program in the terminal? Do
> you mean that you opened a terminal window and then typed 'python
> myprog.py'? Or did you click on the python file and choose 'run in
> terminal' or similar? That output looks to me like what happens on OSX when
> a terminal window is open but the shell has been closed.
>

So you were using the python launcher on the dock? I guess you are using
OSX, then (it's good to provide this kind of information).

The reason you're not seeing any output is probably because you're not
printing it. If your program has a variable called 'total' that you would
like to see the value of simply put a line like 'print(total)' at the end
of your script. Then you should see the output.



>  >
> > I think the instruction to run in a terminal should look like:
> > 1) open the terminal (how to do this depends on your OS).
> > 2) type 'cd /path/to/my/script/folder' and then hit enter.
> > 3) type 'python script.py' and then hit enter.
>

Have you tried the instructions above. Assuming you're using OSX you can do
step 1 by hitting cmd-space to open spotlight. Then you type 'terminal' and
hit enter and you will have a terminal window.

Oscar.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] making a shortcut in windows

2012-09-04 Thread Oscar Benjamin
On 4 September 2012 02:57, Garry Willgoose  wrote:

> I want to put a shortcut onto the desktop in windows (XP and later) in
> Python 2.6 or later. In Unix its easy using os.symlink but I can't find
> anything equivalent for windows. My searches on the web led me to the code
> below but the code returns the error
>
> AttributeError: function 'CreateSymbolicLinkW' not found
>
> so does anybody have any suggestions?
>

Are you really trying to create a symbolic link? Note that this is not the
same thing as a 'shortcut' in Windows. If you say why you want the shortcut
someone may be able to help you find another way of doing what you want.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to print array without adding newline

2012-09-06 Thread Oscar Benjamin
On Sat, 18 Aug 2012 18:17:16 -0700 (PDT), vickistan 
 wrote:
Hello: I am trying to output an array to another program that takes 

an array
as input, but the print statement adds a newline. If it were adding 

to each
individual element, I could solve it easily, but it is adding one 

at the end
of the array. Is there another way to print an array besides 




print arrayname


Yes. You can use:

print arrayname,

Note the trailing comma ',' character at the end of the print 
statement. In python 2 this is the normal way to stop print from 
adding a newline. It's a silly syntax that has been fixed in python 
3. If your using python 3 then it looks like


print(arrayname, end='')

which makes a bit more sense to me.

By the way what your calling an array, python calls a list. In python 
the word array is usually used to refer to a number of other things.


As a more general comment: are you the author of both programs? If so 
then you can choose a different format for outputting your data. My 
default choice would be to print out each url on a separate line, 
without the square brackets or commas. You can do that with:


for url in arrayname:
   print url

Note that I want print to add the newlines. This is a common way of 
working with text files and this is the reason that print adds a 
newline.


Oscar

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making big 'uns into little 'uns

2012-09-06 Thread Oscar Benjamin
On 2012-09-06, Ray Jones  wrote:
>
> Basically it's as simple as ensuring that an array consists of integers,
> and that those integers fall within a certain range. Rather than using
> multiple 'if' statements, I was (am, at this point) using multiple tests
> within a single 'if' statement. Nothing earth-shatteringly difficult,
> but I was simply looking for a way to shorten the overall test
> expression with a recursive(? is that the term) variable. No problem though.
>
> Thanks.

How about using a generator expression with all()? For example:

>>> def isint(n):
... return int(n) == n
...
>>> def isinrange(n, a, b):
... return a <= n <= b
...
>>> numbers = [11, 12, 14, 15]
>>> all(isint(x) and isinrange(x, 10, 20) for x in numbers)
True
>>> numbers[0] = 9
>>> numbers
[9, 12, 14, 15]
>>> all(isint(x) and isinrange(x, 10, 20) for x in numbers)
False
>>> numbers[0] = 14.5
>>> all(isint(x) and isinrange(x, 10, 20) for x in numbers)
False


Oscar

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Print List

2012-09-12 Thread Oscar Benjamin
On Sep 12, 2012 4:53 PM, "Ashley Fowler" 
wrote:
>
> I am trying to complete the following below:
>
>
> You also need to write a function "printList" of one parameter that
> takes a list as its input and neatly prints the entire contents of the
> list in a column. Each student in the list should be printed using
__str__.
>
>
> So far i have:
>
>
> def printList(lists):
> print("First Name\tLast Name\tCredits\tGPA")
> for i in lists:
> print (i)
>
>
> Any Suggestions or Corrections?

Looks good to me.

My only suggestion is to use more descriptive names. I would have called it
'students' instead of 'lists' and 'student' instead of 'i'. I don't really
like 'printList' either but I guess your stuck with that.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] index of elements in numpy array

2012-09-13 Thread Oscar Benjamin
On 13 September 2012 21:16, Bala subramanian wrote:

> Friends,
> I have a 2D matrix (a numpy array) and i am looping over each row in
> the matrix. I would like to know how i can find the index of each
> element in a while looping a row. Is there any function in numpy.
>

Your question could mean several things. Could you post a small piece of
example code and clarify what it is you're unable to do?

Here's an example that loops over all elements of a 2D Matrix:

>>> import numpy
>>> M = numpy.array([[1, 1], [2, 3], [5, 8]])
>>> M
array([[1, 1],
   [2, 3],
   [5, 8]])
>>> numrows, numcols = M.shape
>>> for i in range(numrows):
...   for j in range(numcols):
...  print M[i, j]
...
1
1
2
3
5
8

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] index of elements in numpy array

2012-09-14 Thread Oscar Benjamin
On 14 September 2012 11:05, eryksun  wrote:

> On Fri, Sep 14, 2012 at 4:36 AM, Bala subramanian
>  wrote:
> >
> >  10 # loop over each row
> >  11 for i1, d1 in enumerate(b):
> >  12 # each x in d1 - value in z corresponding to index of x in d1
> >  13 d1=[x-z[d1.index(x)] for x in d1]
> >
> > If d1 is a simple list, i can fetch the index of its element as
> > d1.index(x). So i would like to know how can achieve the same with
> > numpy array.
>

Whether you use a list or a numpy array, iterating over the elements and
then trying to get the index of each value from the value itself is
inefficient. It's also leads to problems when the array/list contains
duplicate values. I think the way to replace your line 13 would be to use:

d1 = [x - z[n] for n, x in enumerate(d1)]

There is another problem though which is that you're assigning to d1 which
is the same name that you've used for your loop variable in the outer loop.
This means that you're throwing away the values you compute. Are you hoping
that by assigning to d1, the values would get stored in b?

Perhaps what you need to do is:

b[i1, :] = [x - z[n] for n, x in enumerate(d1)]

This way the values will get stored in b. If you actually want them to be
stored in another array, say c, then create that array before the loop with

c = np.zeros_like(b)

If this is what you're trying to do, though you would be better off just
using Peter's suggestion:

c = b - np.array(z[:b.shape[1]])

so that you don't need a loop at all.


> In general you don't want to loop over and enumerate a NumPy array.
> That's a lot slower than using vectorized operations (just like in
> MATLAB) and broadcasting. See Peter Otten's answer.
>
> For an 'index' operation you have a couple of options. To begin with,
> a test returns a bool array:
>
>
> >>> d = np.array([1,2,1,2,1])
>
> >>> d == 1
> array([ True, False,  True, False,  True], dtype=bool)
>
>
> You can use this bool array to index the source array:
>
>
> >>> d[d == 1]
> array([1, 1, 1])
>
> >>> d[d == 1] = 3
> >>> d
> array([3, 2, 3, 2, 3])
>
>
> To get the indexes, use "nonzero" or "where":
>
>
> >>> np.nonzero(d == 2)
> (array([1, 3]),)
>
> >>> np.where(d == 2)
> (array([1, 3]),)


The suggestions above from eryksun are closer to what actually happens when
you use the index function on a list, but you should consider whether or
not that is really what you want to do.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reducing a list evenly when deleting elements by index

2012-09-16 Thread Oscar Benjamin
On 17 September 2012 02:15, Pete O'Connell  wrote:

> Hi, I have a bezier line with 20 points on it and I am trying to reduce
> this to a line with 4 points, keeping the first and last points and 2
> evenly spaced points in between like so:
> **
> becomes:
> *. .  . .*
>
> These points are removable only by index, so if I remove point 2,
> point 3 then becomes point 2 in the next iteration, so I end up having a
> spacing like this which is not what I want:
> *.  . . .*


But removing item 19 doesn't affect the position of item 2. The trick is to
start the loop at the end of the list and work back to the beginning.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reducing a list evenly when deleting elements by index

2012-09-17 Thread Oscar Benjamin
On 2012-09-17, Steven D'Aprano  wrote:
> On 17/09/12 11:15, Pete O'Connell wrote:
>> Hi, I have a bezier line with 20 points on it and I am trying to reduce
>> this to a line with 4 points, keeping the first and last points and 2
>> evenly spaced points in between like so:
>
> In general in Python, it is faster and much easier to create a new list
> rather than to mess about deleting items from a list.
>
> So instead of calling del 16 times, which has to move list items around,
> it will be faster and simpler to create a new list:
>
> new = [old[0], old[6], old[13], old[19]]
>
> then just use the new list. If you really need to modify the old list in
> place (perhaps because other parts of the code need to see the same
> change) then you can do a slice-assignment:
>
> old[:] = new  # note the [:] slice
>

I certainly agree with Steven's comments here that there are much less
convulated ways to replace a list with a new list containing a subset of its
elements. I would also like to add, though, that I'm not sure if what you're
doing makes sense from a mathematical/geometrical viewpoint. It's not totally
clear to me from your original post what you're trying to do. I can think of
two interpretations:

1) You have a Bezier curver consisting of 20 control points and would like to
approximate it with a simpler cubic Bezier curve consisting of only 4 points.
I would call this "approximating a Bezier with a lower order Bezier".

2) You have a line that goes through 20 points and you would like to represent
it as a cubic Bezier with 4 control points. I would call this "fitting a
cubic Bezier to a sequence of points along a line".

In either case I think that choosing 4 of the points and using them as a cubic
Bezier is incorrect. For case 1) I don't think it's possible to approximate a
Bezier using a subset of its control points. I'm not sure how to prove it but
I think that typically a significantly higher order Bezier will have control
points that are closer to the curve than an equivalent lower order Bezier.

For case 2) it's not appropriate to think of a Bezier as interpolating its
control points because it doesn't go through it's control points (except for
the two at the ends).

In either case I would expect a good method to use information from all of the
original sequence of points rather than ignoring all but a small subset.

Oscar

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to run this block of code dozens of times

2012-09-17 Thread Oscar Benjamin
On 2012-09-17, Emile van Sebille  wrote:
>
> Be sure you don't at some point depend on _ having a specific value 
> however, as return values of functions are given the _ name in the 
> absense of a designated label for the returned value:
>
> ActivePython 2.6.6.15 (ActiveState Software Inc.) based on
> Python 2.6.6 (r266:84292, Aug 24 2010, 16:01:11) [MSC v.1500 32 bit 
> (Intel)] on win32
> Type "help", "copyright", "credits" or "license" for more information.
> >>> def test(): return True
> ...
> >>> _
> Traceback (most recent call last):
>File "", line 1, in 
> NameError: name '_' is not defined
> >>> test()
> True
> >>> _
> True
> >>>

This only happens as a convenience in interactive mode. In scripts or modules
the _ identifier has no significance except for the convention that it is a
value you don't care about.

$ cat tmp.py
def test(): return True
test()
_
$ python tmp.py
Traceback (most recent call last):
  File "tmp.py", line 3, in 
_
NameError: name '_' is not defined

Oscar

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] combining c and python

2012-09-17 Thread Oscar Benjamin
On 2012-09-17, Bala subramanian  wrote:
> Friends,
> I code in python and so far able to write simple scripts for my needs.
> Now i want to try the combination of c and python.
>
> 1) could someone please suggest me some good documentation on how
> python and C can be combined. Some tutorials with simple examples.
>
> 2) If i know that a specific part (loop in my case) within my python
> script consumes more processing time, is it possible to implement/use
> 'c' only for that part. Precisely using C within python ? Any link for
> documentation on such implementation would be of great help to me.
>

I would use cython for this:
http://www.cython.org/

Cython allows you to write something that looks a lot like a python module but
that gets translated into c, compiled with a c compiler and then turned into
an extension module. Once compiled the extension module can be used from other
scripts/modules just like an ordinary python module. But the code that was
written in that module will often run a lot faster than ordinary python code
particularly if you have an intensive but simple inner loop.

Oscar

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] combining c and python

2012-09-17 Thread Oscar Benjamin
On 2012-09-17, Walter Prins  wrote:
> Hi Chris,
>
> On 17 September 2012 18:43, Chris Fuller 
> wrote:
>> To run C alongside Python, you need to use the API.
>>
>> You can interface Cython with straight C, of course, but not in a way that
>> will work with the standard interpreter.
>
> Just to be clear, one of the main reasons for Cython's existence is to
> allow for the easy writing of CPython extension modules in a more or
> less Python like language which then gets compiled down to C for you
> (rather than you having to write the C yourself.)  Another is to allow
> you to easily wrap C libraries in such a way as to allow you to make
> them accessible from CPython.

Yeah, as a regular Cython user I'm not sure if I really understand Chris'
comments there.

Cython uses precisely that C-API to create the extension modules it makes. If
you've ever used the same C-API manually you'll understand why Cython exists
to make it easier.

Also, Cython *only* works with the standard interpreter (the latest release
claims alpha quality support for PyPy but I haven't tested that myself).

Oscar

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Input handling?

2012-09-18 Thread Oscar Benjamin
On Sep 18, 2012 7:14 AM, "Steven D'Aprano"  wrote:
>
> On Tue, Sep 18, 2012 at 12:04:22AM -0400, Dave Angel wrote:
> > Somehow you managed to put your other message in its own thread, instead
> > of adding to this one.
>
> Not all mail clients support threading, either when receiving or
> sending.
>
> But my mail client, mutt, shows Scott's emails threaded correctly.
> Perhaps your mail client is broken? What are you using?

Mutt goes above and beyond a correct implementation of threading by using
heuristics to fix broken threads. I know it parses the subject line but I'm
not sure what else it uses. The upshot is that if you use mutt you won't
see the same thing that would be shown in a client that has a strict
interpretation of threading (unless you disable the heuristics in your
muttrc).

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Input handling?

2012-09-18 Thread Oscar Benjamin
On Sep 18, 2012 10:02 AM, "Oscar Benjamin" 
wrote:
>
>
> On Sep 18, 2012 7:14 AM, "Steven D'Aprano" 
wrote:
> >

Apologies for gmail screwing up your name. I wish I could use mutt on this
machine.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Storing information as attributes or in a dictionary

2012-09-18 Thread Oscar Benjamin
On 18 September 2012 15:14, Michiel de Hoon  wrote:

> Dear all,
>
> Suppose I have a parser that parses information stored in e.g. an XML
> file. I would like to design a Python class to store the information
> contained in this XML file.
>
> One option is to create a class like this:
>
> class Record(object):
> pass
>
> and store the information in the XML file as attributes of objects of this
> class, as in
>
> >>> handle = open("myxmlfile.xml")
> >>> record = parse(handle) # returns a Record object
> >>> record.name
> "John Doe"
> >>> record.birthday
> "February 1, 1920"
>
> Alternatively I could subclass the dictionary class:
>
> class Record(dict):
> pass
>
> and have something like
>
> >>> handle = open("myxmlfile.xml")
> >>> record = parse(handle) # returns a Record object
> >>> record['name']
> "John Doe"
> >>> record['birthday']
> "February 1, 1920"
>
> I can see some advantage to using a dictionary, because it allows me to
> use the same strings as keys in the dictionary as in used in the XML file
> itself. But are there some general guidelines for when to use a
> dictionary-like class, and when to use attributes to store information? In
> particular, are there any situations where there is some advantage in using
> attributes?
>

Some people find attribute access a bit "nicer" when they are using an
object.

Attributes have the disadvantage that they're a bit awkward if they aren't
valid identifiers, where as any string is ok for a dictionary key.

A valid identifier is any string...
1) consisting only of alphanumeric characters (a-z, A-Z, 0-9) and the
underscore (_)
2) that does not begin with a numeric character (0-9).
3) and that is not a Python keyword (is, not, and, def, class, ...).

To see what happens otherwise:

>>> class A(object): pass
...
>>> a = A()
>>> a.class = 'some value'
  File "", line 1
a.class = 'some value'
  ^
SyntaxError: invalid syntax

Also if your objects are instances of a class that has any methods you'll
need to ensure that the method names don't conflict with the XML keys as
well.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Unzipping a Zip of folders that have zips within them that I'd like to unzip all at once.

2012-09-19 Thread Oscar Benjamin
On 19 September 2012 19:00, Gregory Lund  wrote:

> >>> and then run it from the shell like this:
> On Wed, Sep 19, 2012 at 10:20 AM, Peter Otten <__pete...@web.de> wrote:
> > Gregory Lund wrote:
>
> >>> and then run it from the shell like this:
> ahh, windows shell, not python shell.
>
> from the directions Peter linked to, I shift-right clicked on the
> folder where my script resided
> (hope that was right)
> then after
> D:\D_Drive_Documents\Scripts\Unzip_a_zip_of_zips\Scripts>
> I typed:python unzip_twice.py 2012-09-18 Lab_2.zip
> Student_Work_Sample_usecopy1
> where:
> unzip_twice.py is the script name as suggested by Steve
> 2012-09-18 Lab_2.zip is the zipfile
> Student_Work_Sample_usecopy1 is the folder the zipfile resides and
> where I want the info extracted to.
>
> Lucky me... NOT...:-)
> I got:
> "'python' is not recognized as an internal or external command,
> operable program or batch file" (without the quotes of course)
>

You need to add the folder where python.exe is to your PATH variable.

First you need to find the folder where python is on your computer. You can
do this from within a python script using the following two lines:
import sys
print sys.executable

Once you've found the folder containing python.exe, add that folder to your
PATH variable:
http://code.google.com/p/tryton/wiki/AddingPythonToWindowsPath
http://showmedo.com/videotutorials/video?name=96&fromSeriesID=96

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Populating a list with object to be called by a class

2012-09-20 Thread Oscar Benjamin
On 20 September 2012 15:41, Ara Kooser  wrote:

> Morning,
>
>   I dug out some old code from 5 years ago to clean up and get in working
> order. It's a simple agent based model. I have class called Ant which
> contains all the ant-like functions.
>
> I have a list that tracks the ants but I did this is a very crude way. I
> basically copied and pasted everything in there like this:
>
> ants =
> [Ant("Red_1","Red","yellow_food"),Ant("Yellow_1","Yellow","red_food"),
>
> Ant("Red_2","Red","yellow_food"),Ant("Yellow_2","Yellow","red_food"),
>
> Ant("Red_3","Red","yellow_food"),Ant("Yellow_3","Yellow","red_food"),
>
> Ant("Red_4","Red","yellow_food"),Ant("Yellow_4","Yellow","red_food"),
>   ...]
>
> I couldn't figure out how to populate the list from a user input. Say if
> the user wanted 50 Red and 50 Yellow ants. So it's hardcoded at 500 which
> is not an elegant solution.
>
> I went back to work on this over the past couple of days but still can't
> figure out how to populate the list so I end up with Red_1 then Red_2 etc...
>
> What would be a good python way to do this?
>

How about this:

numants = 500

ants = []
for i in range(1, numants+1):
ants.append(Ant('red_%i' % i, 'Red', 'yellow_food'))
ants.append(Ant('yellow_%i' % i, 'Yellow', 'red_food'))

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] np array.any() question

2012-09-21 Thread Oscar Benjamin
On Sep 21, 2012 4:09 PM, "Bala subramanian" 
wrote:
>
> Friends,
> May i know why do get a Valuerror if i check any value in a is between
> 3.0 to 5.0 ?
> >>> import numpy as np
> >>> a=np.array([ 2.5,  2.6,  3.0 ,  3.5,  4.0 ,  5.0 ])
> >>> (a > 7).any()
> False
> >>> (a > 4).any()
> True
> >>> (3 < a < 5).any()
> Traceback (most recent call last):
>   File "", line 1, in 
> ValueError: The truth value of an array with more than one element is
> ambiguous. Use a.any() or a.all()

You need to use ((3 < a) & (a <5)).any()

The problem is not with any(). The problem is that the multiple binary
comparison needs to convert its intermediate results to bool. So (3 < a <
5) is processed as:

(3 < a) and (a < 5)

To process the 'and' operator python needs to know if the first expression
is True. This means calling bool(3 < a). But, since (3 < a) is an array of
booleans it cannot be said to be True or False. This is what gives the
ValueError that you see.

If you use bitwise-and '&' instead of logical-and 'and' it will perform the
and operation separately on each element of each array which is what you
want.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Unzipping a Zip of folders that have zips within them that I'd like to unzip all at once.

2012-09-23 Thread Oscar Benjamin
On Sep 21, 2012 8:10 PM, "Gregory Lund"  wrote:
> print zipContents
>
> z.close

You need to have round brackets to actually call the close method, i.e.:

z.close()

> 
>
> It works, I get the following in the Python Shell:
>
> '>>>  RESTART
'
>
> '>>>'
>
> ['Lab_2/aforker/', 'Lab_2/aforker/aforker_Lab2.zip',
> 'Lab_2/allisw99/', 'Lab_2/allisw99/allisw99_Lab2.zip',
> 'Lab_2/allisw99/allisw99_Lab2_Bonus.pdf', 'Lab_2/allisw992/',
> 'Lab_2/allisw992/allisw99_Lab2_Bonus.pdf', 'Lab_2/btaylor7/',
> 'Lab_2/btaylor7/2nd_btaylor7_Lab2.zip',
> 'Lab_2/btaylor7/btaylor7_Lab2.zip', 'Lab_2/']

Did you mean to have the paths of folders (e.g. 'Lab_2/aforker') in the
same list as the paths of zip-files (e.g. 'Lab_2/aforker/aforker_Lab2.zip')?


>
> '>>> '
>
> But, what I can't figure out is how to get 'into' each unique folder:
> aforker, allisw99, etc. and then extract any and all zips within
> 'aforker', 'allisw99', etc.
>
> I have no doubt that the suggestions posted here will work, but they
> all seem to get away from a single .py file and
>  a) I can't get them to work, and
> b) it doesn't really help me because I need ONE stand alone .py file
> to make this all work in ArcGIS.

I don't know what ArcGIS is but if it runs Python then I'm sure that it can
be done with a stand alone .py file.

>
>  I will be using this to create an ArcGIS 'tool' that requires one
> script (at least for me to comprehend it) :-)
>
> Thank you in advance for any and all suggestions, tips etc.
>
> For the record, I did try the following  (to at least try
> something) at  the bottom of the code above:
> ---
>
> for item in zipContents:
> itemLoc = os.path.join(outDir,item)
> y = zipfile.ZipFile(itemLoc,'a')
> y.extractall(os.path.aplit(itemLoc)[0])
> y.close
> 
>
> but I get the following error:
>
> Traceback (most recent call last): File
> "D:\D_Drive_Documents\Scripts\Unzip_a_zip_of_zips\Scripts\unzip_a_zip.py",
> line 50, in y = zipfile.ZipFile(itemLoc,'a') File
> "C:\Python26\ArcGIS10.0\lib\zipfile.py", line 687, in init self.fp =
> open(file, modeDict[mode]) IOError: [Errno 13] Permission denied:
> 'D:\D_Drive_Documents\Student_Work_Sample_usecopy1\Lab_2/aforker/'

You're trying to open the directory as if it were a zipfile. You should
pass in the path to a zipfile not to a folder.

Also you're opening the files in append mode 'a'. I think you really want
read-only mode 'r'.

>
> I guess my first issue is to resolve the 'Permission denied' problem.
> And, I know I need an 'if' statement, somehow...

Remove the folder paths from the list of paths.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Unzipping a Zip of folders that have zips within them that I'd like to unzip all at once.

2012-09-23 Thread Oscar Benjamin
On 24 September 2012 02:22, Gregory Lund  wrote:


> > You're trying to open the directory as if it were a zipfile. You should
> > pass in the path to a zipfile not to a folder.
>
> Agreed, but how do I do that "pass in the path to a zipfile'?
> Using an if statement I presume?
>
> > >
> > > I guess my first issue is to resolve the 'Permission denied' problem.
> > > And, I know I need an 'if' statement, somehow...
> >
> Yes, the permission denied problem seems to be the first real
> obstacle, but I can't figure it out.
> I tried searching online but everything I found to try, didn't work.
>

The permission error is because you are trying to open a folder as if it
were a file. The operating system does not give you permission to do this
because it is a nonsensical operation.

> Remove the folder paths from the list of paths.
>
> How can I remove the folder paths from the list of paths?
>

You can do it with a list comprehension:

import os.path
paths = [p for p in paths if os.path.isdir(p)]

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Unzipping a Zip of folders that have zips within them that I'd like to unzip all at once.

2012-09-23 Thread Oscar Benjamin
On 24 September 2012 02:34, Oscar Benjamin wrote:

> On 24 September 2012 02:22, Gregory Lund  wrote:
>
>
>>  > You're trying to open the directory as if it were a zipfile. You should
>> > pass in the path to a zipfile not to a folder.
>>
>> Agreed, but how do I do that "pass in the path to a zipfile'?
>> Using an if statement I presume?
>>
>> > >
>>
>> > > I guess my first issue is to resolve the 'Permission denied' problem.
>> > > And, I know I need an 'if' statement, somehow...
>> >
>> Yes, the permission denied problem seems to be the first real
>> obstacle, but I can't figure it out.
>> I tried searching online but everything I found to try, didn't work.
>>
>
> The permission error is because you are trying to open a folder as if it
> were a file. The operating system does not give you permission to do this
> because it is a nonsensical operation.
>
> > Remove the folder paths from the list of paths.
>>
>> How can I remove the folder paths from the list of paths?
>>
>
> You can do it with a list comprehension:
>
> import os.path
> paths = [p for p in paths if os.path.isdir(p)]
>

Sorry that should be (note the 'not'):
paths = [p for p in paths if not os.path.isdir(p)]

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Unzipping a Zip of folders that have zips within them that I'd like to unzip all at once.

2012-09-23 Thread Oscar Benjamin
On 24 September 2012 03:00, Gregory Lund  wrote:

> >>> > You're trying to open the directory as if it were a zipfile. You
> should
> >>> > pass in the path to a zipfile not to a folder.
> >>>
> >>> Agreed, but how do I do that "pass in the path to a zipfile'?
> >>> Using an if statement I presume?
> >>>
> >>> > >
> >>>
> >>> > > I guess my first issue is to resolve the 'Permission denied'
> problem.
> >>> > > And, I know I need an 'if' statement, somehow...
> >>> >
> >>> Yes, the permission denied problem seems to be the first real
> >>> obstacle, but I can't figure it out.
> >>> I tried searching online but everything I found to try, didn't work.
> >>
> >>
> >> The permission error is because you are trying to open a folder as if it
> >> were a file. The operating system does not give you permission to do
> this
> >> because it is a nonsensical operation.
> >>
> >>> > Remove the folder paths from the list of paths.
> >>>
> >>> How can I remove the folder paths from the list of paths?
> >>
> >>
> >> You can do it with a list comprehension:
> >>
> >> import os.path
> >> paths = [p for p in paths if os.path.isdir(p)]
> >
> >
> > Sorry that should be (note the 'not'):
> > paths = [p for p in paths if not os.path.isdir(p)]
> >
> Ok, but where do I put that?
> Sorry Oscar, I don't know where to put it, nor do I know how to use
> 'paths' once I do that.
>
> I was trying this prior to getting your email about paths...(I put
> this after z.close()
>
> for item in zipContents:
> if item(-4) == ('.zip'):
>

That should be:
if item[-4:] == '.zip'

but a better way to do that is:
if item.endswith('.zip')

x = zipfile.Zipfile(item,'r')
> x.extractall()
> x.close()
>
> but, I kept getting a "TypeError: 'str' object is not callable" error.
>
> then I tried
>
> for item in zipContents:
> if item.lower() .endswith(".zip"):
>

Ok that's better.


> item.extractall()
> item.close()
>
> but got a "item.extractall()
> AttributeError: 'str' object has no attribute 'extractall'" error
>

item is a string object. You need to use that string to create a ZipFile
object and then call extractall() on the ZipFile object (the way you did in
your original post in this thread).

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Unzipping a Zip of folders that have zips within them that I'd like to unzip all at once.

2012-09-23 Thread Oscar Benjamin
On 24 September 2012 03:26, Gregory Lund  wrote:

> >
> > but a better way to do that is:
> > if item.endswith('.zip')
> >
> >> x = zipfile.Zipfile(item,'r')
> >> x.extractall()
> >> x.close()
> >>
> ok, I used that (above)
> typed below:
>
> for item in zipContents:
> if item.endswith('.zip'):
> x = zipfile.Zipfile(item,'r')
> x.extractall()
> x.close()
>
> but now get a   "  x = zipfile.Zipfile(item,'r')
> AttributeError: 'module' object has no attribute 'Zipfile' "
>

Capital F. ZipFile not Zipfile.


>
> error
>
> gr, this is going to send me to the funny farm!
>
> greg
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] running program in terminal

2012-09-24 Thread Oscar Benjamin
On 24 September 2012 17:41, Benjamin Fishbein  wrote:

> Hello. I can run programs in IDLE but when I try to do it in a terminal or
> with textwrangler, it usually just logs out and says it's completed, but
> the program hasn't been run. This is particularly so when the program uses
> urllib. I'm using OS X.
>
> logout
>
> [Process completed]
>

Are you using the python launcher? Or are you opening a terminal and then
typing 'python myscript.py'?

Tell me if the following steps work for you:

1) Open the terminal - you can find it under Applications/Utiltiies (or if
you just type 'terminal' in spotlight). You should see something like:
Last login: Tue Mar 6 17:21:36 on console
Welcome to Darwin!
ibook:~ Alex$

2) Type 'cd name/of/folder' and hit enter to move into the folder that
contains your Python script.

3) Type 'python myscript.py' and hit enter to run the script called
'myscript.py'.

Oscar

About the terminal:
http://macapper.com/2007/03/08/the-terminal-an-introduction/
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Unzipping a Zip of folders that have zips within them that I'd like to unzip all at once.

2012-09-24 Thread Oscar Benjamin
On 24 September 2012 22:15, Gregory Lund  wrote:

> >> but now get a   "  x = zipfile.Zipfile(item,'r')
> >> AttributeError: 'module' object has no attribute 'Zipfile' "
> >>
> >> error
> >>
> >> gr, this is going to send me to the funny farm!
> >>
> >> greg
> >>
> > One way to avoid the "funny farm" is to learn to use the tools that
> > Python provides, built-in.  As soon as you get an error like that one,
> > add a print statement immediately before the one in error, and find the
> > type and attributes of the object that supposedly doesn't have the
> > attribute.  For example, you could have added a dir(zipfile), and then
> > studied the one that seems to be the same as the one you tried to use.
> > Presumably you would have quickly discovered what Oscar pointed out.
> >
> Thank you, I have printed and added to my Python quick hints.
>
> > We all make typos, the difference is in how quickly we find and fix
> > them.  Use the tools.
> >
> must admit, I didn't notice the typo.
>

No but Python did when it ran your code and it tried to tell you. The trick
is to read the error message, see what line of code it occurs at and then
look very closely at that line of code and the surrounding lines of code.
The first thing to check for is a typo.

The error message that Python gives may seem cryptic but it's actually very
informative if you know how to read it. For this reason it's also more
helpful to show the *verbatim* error message when posting to this (or
other) lists.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Unzipping a Zip of folders that have zips within them that I'd like to unzip all at once.

2012-09-24 Thread Oscar Benjamin
On 25 September 2012 00:33, Gregory Lund  wrote:
>
> z.extractall(outDir)
>
> zipContents = z.namelist()
> print zipContents
> z.close()
>
> for item in zipContents:
> if item.endswith('.zip'):
> x = zipfile.ZipFile(item,'r')
> x.extractall()
> x.close()
>
> Traceback (most recent call last):
>   File
> "D:/D_Drive_Documents/Scripts/Unzip_a_zip_of_zips/Scripts/unzip_a_zip_of_zips_rewrite_shortest_of_the_shorts2.py",
> line 18, in 
> x = zipfile.ZipFile(item,'r')
>   File "C:\Python26\ArcGIS10.0\lib\zipfile.py", line 683, in __init__
> self.fp = open(file, modeDict[mode])
> IOError: [Errno 2] No such file or directory:
> 'Lab_2/aforker/aforker_Lab2.zip'
> >>>
>
> Near as I can tell, I got rid of the permissions error, the ZipFile
> error with the missing capital 'F'
> Now I need to 'get into' the non zipped folder of each student and
> unzip any and all zips that are inside of it.
>

The error message says 'No such file or directory'. That means that when
Python tries to open a file with the name you gave it can't find a file
that has that name. In this case I suspect the problem is that you need to
give the full path to each file i.e. instead of
  'Lab_2/aforker/aforker_Lab2.zip'
you need to give
 
'D:\D_Drive_Documents\Student_Work_Sample_usecopy1\Lab_2\aforker\aforker_Lab2.zip'

You can create the full path with:

import os.path   # Put this at the top of your file

for item in zipContents:
  if item.endswith('.zip'):
  # Combine the base folder name with the subpath to the zip file
  fullpath = os.path.join(outDir, item)
  x = zipfile.ZipFile(fullpath,'r')

I just googled to find you a page explaining absolute paths and, by chance,
came up with this from the ArcGIS documentation:
http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=Pathnames%20explained%3A%20Absolute%2C%20relative%2C%20UNC%2C%20and%20URL

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python new window

2012-09-28 Thread Oscar Benjamin
Hi Zack,

On 11 September 2012 22:18, zack dunphey  wrote:

> I have used python a lot at school and am relatively good with it.  I just
> tried to get it on my mac and i try to open a "new window" and every time I
> do  it freezes and i have to either do a forced quit or unplug the whole
> computer.  I have been able to get into a "new window" through programs i
> saved on a jump drive at school and brought home but every time i try to do
> anything from that window it freezes.  i tried re downloading it but that
> didn't help.
> can some one please help me


I'd like to help but I have no idea what you're talking about.

What is a "new window"? Is that something that your script tries to do? Or
do you mean a window to view and run your code?

Could you be more specific about what exactly you're doing? Python does
many things and can be used in many different ways so you cannot assume
that anyone else really has any idea what you are doing.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] floating point rounding inconsistency

2012-09-28 Thread Oscar Benjamin
On 19 September 2012 19:27, Andrew Tritt  wrote:

> Hello,
>
> I am new to python, and I was experimenting with the round function, and
> came across what appears to be a bug in floating point rounding. I am
> guessing there is a valid explanation for it.
>
> When I round the floating points 10.6[0-9]5 to two decimal places, it
> rounds as expected for 6 of the 10, but not for the other 4. When I try the
> same for 10.7[0-9]5, I experience the same problem, but for 5 of the 10
> possibilties, and not for the analogous floats.
>
> Also, python storing the numbers as they are represented at the prompt.
> i.e. 10.665 is stored as 10.665, not something like 10.66501 or
> 10.664.
>
> Can anyone explain to me what's happening?
>

It is because Python (like all programming languages I know) represents
floating point numbers in base 2. This is discussed in the python.orgtutorial:
http://docs.python.org/tutorial/floatingpoint.html

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] assembly language and boot loader

2012-09-28 Thread Oscar Benjamin
On 23 September 2012 05:46, Fit Wii  wrote:

> Is there any IDE or Python interpreter that can show the assembly language
> generated by each line of python code?  Is there any popular boot loader
> written in Python (plus some assembly code)?
>

Python doesn't generate assembly language code. It does, however, compile
python code to bytecode which is like assembly for the Python interpreter
rather than for the CPU. Have a look at the dis module:
http://docs.python.org/library/dis.html

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list all links with certain extension in an html file python

2012-09-28 Thread Oscar Benjamin
On 16 September 2012 08:20, Santosh Kumar  wrote:

> I want to extract (no I don't want to download) all links that end in
> a certain extension.
>
> Suppose there is a webpage, and in the head of that webpage there are
> 4 different CSS files linked to external server. Let the head look
> like this:
>
> http://foo.bar/part1.css
> ">
> http://foo.bar/part2.css
> ">
> http://foo.bar/part3.css
> ">
> http://foo.bar/part4.css
> ">
>
> Please note that I don't want to download those CSS, instead I want
> something like this (to stdout):
>
> http://foo.bar/part1.css
> http://foo.bar/part1.css
> http://foo.bar/part1.css
> http://foo.bar/part1.css
>
> Also I don't want to use external libraries. I am asking for: which
> libraries and functions should I use?
>

If you don't want to use any third-party libraries then the standard
library has a module urllib2 for downloading a html file and htmlparser for
parsing it:
http://docs.python.org/library/urllib2.html#examples
http://docs.python.org/library/htmlparser.html#example-html-parser-application

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Lotka-Volterra Model Simulation Questions

2012-09-28 Thread Oscar Benjamin
On 28 September 2012 21:32, Jim Apto  wrote:

> Hello folks,
>
> I'm relatively new to python, and was asked to program a lotka-volterra
> model (predator and prey relation) simulator.  The program basically will
> basically have a menu that takes user input, collect data, and then create
> a graph.  Currently i've been working on the simulator section; I can't
> seem to get the lists right.  I've assigned the following variables and
> parameters to the model for the program:
>
> x represents prey population
> y represents predator population
> dy/dt and dx/dt represents growth rate of the two populations over time
> t represents time
>
> a is the growth rate of prey
> b is the rate at which predators kill prey
> g is the death rate of predators
> d is the rate at which the predators population increases by consuming prey
>
> The equation:
> dx/dt = x(a-by)
> dy/dt = -y(g-dx)
>
> The code I have for this section is:
> def deltaX(a,b,x,y):
> dx = x*(a-b*y)
>
> def deltaY(g,d,x,y):
> dy = -y*(g-d*x)
>

The normal way to program an ODE solver is to define a function that takes
a vector input X and returns a vector dX/dt. The idea is that rather than
keeping a separate state for x and y you keep a combined state [x, y]. This
makes sense since the state of your system at any time is defined by both
values. Keeping that in mind I would write a function like

def derivative(Z):
x, y = Z
   dxdt = ...
   dydt = ...
   dZdt = [dxdt, dydt]
   return dZdt

This function uses lists of numbers to represent the state vector. You can
then plug this into a function that uses a particular ODE solving algorithm:

def euler(f, Z1, dt):
dZdt = f(Z1)
Z2 = []
for i in range(len(Z1)):
Z2.append(Z1[i] + dt * dZdt[i])
return Z2

Or a shorter version:

def euler(f, Z1, dt):
return [z + dt * dz for z, dz in zip(Z, f(Z))]

You then get the new state by plugging the old state into the euler
function repeatedly, e.g.:

dt = .001
Z0 = [0.5, 0.5]   # Initial condition
Z1 = euler(derivative, Z0, dt)
Z2 = euler(derivative, Z1, dt)
...

Once you can get all the simulation values you will be in a position to
think about how to rearrange the lists so that you can plot them.

By the way, this sort of thing is usually done with numpy (that makes a few
of these things a bit easier).

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Lotka-Volterra Model Simulation Questions

2012-09-29 Thread Oscar Benjamin
On Sep 29, 2012 2:25 AM, "Alan Gauld"  wrote:
>
> On 28/09/12 21:32, Jim Apto wrote:
>
>> I'm relatively new to python, and was asked to program a lotka-volterra
>> model (predator and prey relation) simulator.
>
>
> No idea what that means in practice but commenting purely on the code
provided...
>
>
>> x represents prey population
>> y represents predator population
>
>
> so use names that say so, like preyPop and predatorPop
> Its only a few extra letters typing but makes things much more readable.

As a mathematician I'd have to disagree with you there Alan. This model
already has an established notation:
http://en.m.wikipedia.org/wiki/Lotka%E2%80%93Volterra_equation
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Lotka-Volterra Model Simulation Questions

2012-09-29 Thread Oscar Benjamin
On Sep 29, 2012 9:41 AM, "Oscar Benjamin" 
wrote:
>
>
> On Sep 29, 2012 2:25 AM, "Alan Gauld"  wrote:
> >
> > On 28/09/12 21:32, Jim Apto wrote:
> >
> >> I'm relatively new to python, and was asked to program a lotka-volterra
> >> model (predator and prey relation) simulator.
> >
> >
> > No idea what that means in practice but commenting purely on the code
provided...
> >
> >
> >> x represents prey population
> >> y represents predator population
> >
> >
> > so use names that say so, like preyPop and predatorPop
> > Its only a few extra letters typing but makes things much more readable.
>
> As a mathematician I'd have to disagree with you there Alan. This model
already has an established notation:
> http://en.m.wikipedia.org/wiki/Lotka%E2%80%93Volterra_equation

Accidentally sent that prematurely.

I meant to say that changing the notation will only lead to confusion.

Also there are good reasons for using short names in equations. It makes it
much easier to see the whole equation at once, which makes it easier to
understand the equations and easier to check your code. If you make the
variable names too long, even simple equations like these will have to
split over several lines and be more difficult to read/check.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Lotka-Volterra Model Simulation Questions

2012-09-29 Thread Oscar Benjamin
On Sep 29, 2012 11:52 AM, "Steven D'Aprano" 
wrote:
>
> On 29/09/12 19:16, Alan Gauld wrote:
>>
>> As to using short names to keep things on a single line, there is a huge
>> body of research in Comp Science that shows that meaningful names
outweigh
>> single line expressions every time in terms of reliability,
comprehension,
>> ease of maintenance etc.
>
> If somebody doesn't understand:
>
> p = m*v*(1-(c/v)**2)**-0.5

It should be v/c not c/v. To give some relevance to this otherwise pedantic
post I'll say that I find it much easier to spot the mistake in the line
above than the line below. This is precisely because the line above
resembles the way the equation would normally be written in a book or on
the blackboard etc.

>
> they aren't likely to be much enlightened by:
>
> momentum = rest_mass*velocity*(1-(speed_of_light/velocity)**2)**-0.5
>

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Lotka-Volterra Model Simulation Questions

2012-09-29 Thread Oscar Benjamin
On 28 September 2012 21:32, Jim Apto  wrote:

> Hello folks,
>
> I'm relatively new to python, and was asked to program a lotka-volterra
> model (predator and prey relation) simulator.  The program basically will
> basically have a menu that takes user input, collect data, and then create
> a graph.  Currently i've been working on the simulator section; I can't
> seem to get the lists right.
>

Jim, I apologise if the responses to your original post seem to have gotten
distracted from the problems you're having. Also I'm sorry if my first post
was a bit abstract.

Have the responses so far been helpful?

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Lotka-Volterra Model Simulation Questions

2012-09-29 Thread Oscar Benjamin
On 29 September 2012 22:57, Alan Gauld  wrote:

> On 29/09/12 11:42, Steven D'Aprano wrote:
>
>> On 29/09/12 19:16, Alan Gauld wrote:
>>
> Totally agree.
> My point is that we should not choose short names just to keep an
> expression on a single line. The evidence suggests that the advantages of
> longer names outweigh the advantage of a single line. But in the cases here
> where single letters evidently have expressive power in their own right the
> familiar term is preferable over a longer descriptive name.
>
> Of course, care is needed when splitting an expression over multi lines
> to keep the readability so if the terms can be naturally split by operator
> then that's the place to split them. But this is the same in written math
> too. (Most of the equations I remember reading from my quantum mechanics
> days were split over at least 3 lines... trying to force them into a single
> line would not have made them any more palatable!)


I wouldn't advocate forcing an equation onto a single line if it doesn't
fit on a single line. However, I'm sure that the equations you're refering
to would have already been using lots of symbols described by very succinct
single-greek/latin-letters and other simple glyphs. Naturally, these
equations would not be meaningful to someone lacking prior experience of
quantum mechanics.

Now imagine replacing each of those single letter symbols with English
underscore-separated words so instead of letter capital psi you would have
'time_dependent_wave_function' and instead of hbar you would have
'planks_constant_over_twopi' and so on. Your equation would go from three
lines to thirty and noone would be able to understand it *even if they were
familiar with the subject*.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] generic repr method?

2012-09-29 Thread Oscar Benjamin
On 29 September 2012 21:15, Albert-Jan Roskam  wrote:

> Hi,
>
> I've written a __repr__ method that is supposed to *always* work. That is,
> it returns an eval-able text representation of any class instance.
> Will this really always work?


No.


> I'd find it useful is this is standard behavior of Python. Or am I
> overlooking something?
>

Yes.


>
>
> import inspect
>
> class X (object):
>
> def __init__(self, x=1, y='n'):
> self.x = x
> self.y = y
>
> def __repr__(self):
> code = self.__class__.__name__ + "("
> for arg in inspect.getargspec(self.__init__).args [1:]  :
> if isinstance(eval("self." + arg), basestring):
>

I'd prefer getattr(self, arg) to eval("self." + arg).


> code += ("%(" + arg + ")r, ")
> else:
> code += ("%(" + arg + ")s, ")
> code = code[:-2] + ")"
> return code % self.__dict__
>
> x = X()
> eval(repr(x))
>

This repr method assumes that every argument to __init__ is stored as an
attribute with the same name as the parameter to __init__. Consider:

def __init__(self, name):
self.other_name = name

Also how do you handle:

def __init__(self, *args, **kwargs):

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Lotka-Volterra Model Simulation Questions

2012-09-30 Thread Oscar Benjamin
On 30 September 2012 09:37, Alan Gauld  wrote:

> On 29/09/12 23:57, Oscar Benjamin wrote:
>
>> On 29 September 2012 22:57, Alan Gauld >
>
>  My point is that we should not choose short names just to keep an
>> expression on a single line
>>
>>
>> in written math too. (Most of the equations I remember reading from
>> my quantum mechanics days were split over at least 3 lines... trying
>>
>> I wouldn't advocate forcing an equation onto a single line if it doesn't
>> fit on a single line. However, I'm sure that the equations you're
>> refering to would have already been using lots of symbols described by
>> very succinct single-greek/latin-letters and other simple glyphs.
>>
>
> Yes which made them even more difficult to understand.


Quantum mechanics is hard for anyone. I don't think that an alternative
notation will make it any easier for people in the business of
learning/teaching/using quantum mechanics (there are already several
notations developed specifically for quantum mechanics). I also don't think
that it is possible to find a notation that will make quantum mechanics
intelligible to a layperson: whether you call it psi or
time_dependent_wave_function you will still be assuming that the reader
knows what a wave function is.


>
> > Now imagine replacing each of those single letter symbols
> > with English underscore-separated words so instead of letter
> > capital psi you would have 'time_dependent_wave_function'
> > and instead of hbar you would have 'planks_constant_over_twopi'
> > and so on. Your equation would go from three lines to thirty
>
> One of the things I like about programming is that I can take those types
> of equations and break them into chunks and put them in
> separate named functions. Then each term gets evaluated separately
> and has a name that represents what it means in physical terms.
>

I often write scripts like the one that the OP is tasked with writing.
While I can write a script like the OP's in less than 5 minutes, in
practise it takes longer to convince myself that the code is correct (if it
is important for it to be so). I spend most of the time when developing
such a script simply looking at the code and comparing it with the
mathematical problem I was trying to solve. The further your code diverges
from the original problem statement the harder it becomes to really
convince yourself that the code is correct. Renaming all of your variables
(any more than you need to) so that cross-referencing always requires a
mental table would be a waste of time and would increase the likelihood of
bugs.


>
> 
> One of the things that makes math hard for people to grasp is its
> insistence on abstracting functions/values to single letter names etc.
> (especially when those names are in a foreign language/symbology,
> like Greek!) Of course, the abstraction is powerful in its own right
> because it can then be applied in multiple domains, but that abstraction is
> often the barrier to people understanding the
> principle. Those that are "good at math" are often really those
> who are "good at abstraction".
> 


I'll agree with the last sentence. The  conventions used in mathematical
symbols convey a lot of meaning (to me). If you look at the Lotka-Volterra
equations on Wikipedia, you'll see that the letters x and y are used for
the variables and greek letters are used for the constants. That
distinction between the variables and constants ("parameters" in dynamics
jargon) is very important when trying to understand the model. It is also
the only thing you need to know about this model to correctly write the
code that solves the system (and is obscured by renaming the variables).

In any case I guess you won't be pleased by my discovery that, thanks to
PEP 3131, the following is valid code in Python 3 (I've attached the code
in case it doesn't display properly):

'''
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-

# Parameters
α = 1
β = 0.1
γ = 1.5
δ = 0.075

# Initial conditions
xₒ = 10
yₒ = 5
Zₒ = xₒ, yₒ

# Solution parameters
tₒ = 0
Δt = 0.001
T = 10

# Lotka-Volterra derivative
def f(Z, t):
x, y = Z
ẋ = x * (α - β*y)
ẏ = -y * (γ - δ*x)
return ẋ, ẏ

# Accumulate results from Euler stepper
tᵢ = tₒ
Zᵢ = Zₒ
Zₜ, t = [], []
while tᵢ <= tₒ + T:
Zₜ.append(Zᵢ)
t.append(tᵢ)
Zᵢ = [Zᵢⱼ+ Δt*Żᵢⱼ for Zᵢⱼ, Żᵢⱼ in zip(Zᵢ, f(Zᵢ, tᵢ))]
tᵢ += Δt

# Output since I don't have plotting libraries in Python 3
print('t', 'x', 'y')
for tᵢ, (xᵢ, yᵢ) in zip(t, Zₜ):
print(tᵢ, xᵢ, yᵢ)
'''

Oscar


sim.py
Description: Binary data
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Tutor Digest, Vol 103, Issue 145

2012-09-30 Thread Oscar Benjamin
On 30 September 2012 12:47, Afzal Hossain  wrote:

> unsubscribe
>
>
Apologies if we're boring you. You need to click the link at the bottom of
the email to unsubscribe:


> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Lotka-Volterra Model Simulation Questions

2012-10-01 Thread Oscar Benjamin
On Oct 1, 2012 12:26 AM, "Alan Gauld"  wrote:
>
> On 30/09/12 11:50, Oscar Benjamin wrote:
>> While I can write a script like the OP's in less than 5 minutes, in
>> practise it takes longer to convince myself that the code is correct (if
>> it is important for it to be so). I spend most of the time when
>> developing such a script simply looking at the code and comparing it
>> with the mathematical problem I was trying to solve.
>
>
> Which is great if you understand the problem domain and the math
involved. If you don't you have to rely on getting the algorithm from the
experts and then translating it into something you can work with after the
expert has moved on.

I guess we won't get to find out but I assumed that the OP understood what
he was doing mathematically but was struggling with the Python code: his
code is correct in it's description of the mathematical model but the
integration algorithm had not been implemented. If I was correct about that
then it would have been bad advice to change the variable names. Also (even
if I was correct) it's still very likely that my own post went over his
head because of the level of assumed Python experience.

>> # Lotka-Volterra derivative
>> def f(Z, t):
>
>
> Although I would argue that 'f' is still a rotten name
> for any function!
>
> def lotka_volterra(Z,t):
>
> would be better. :-)

I'm not sure I would really use f in a real problem but I should say that
it is the mathematical convention to call this particular function f. I'll
meet you (sort of)half way:

def f_lotka_volterra(x, t):

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help for Python Beginner with extracting and manipulating data from thousands of ASCII files

2012-10-01 Thread Oscar Benjamin
On Sep 30, 2012 11:10 PM, "Cecilia Chavana-Bryant"
 wrote:
>
> Hola again Python Tutor!

Hi Cecilia

>
> With a friend's help I have the following code to extract reflectance data 
> from an ASCII data file, do a bit of data manipulation to calibrate the data 
> and then write the calibrated file into an out file.
>
> import numpy
> # import glob - use if list_of_files is used
>
>
> dataFile = "1SH0109.001.txt"
> #list_of_files = glob.glob('./*.txt') to replace dataFile to search for all 
> text files in ASCII_files folder?
> caliFile1 = "Cal_File_P17.txt" # calibration file to be used on data files 
> created from July to 18 Sep
> caliFile2 = "Cal_File_P19.txt" # calibration file to be used on data files 
> created from 19 Sep onwards
> outFile = "Cal_" + dataFile # this will need to change if list_of_files is 
> used
> fileDate = data[6][16:26] # location of the creation date on the data files

The variable data used in the line above is not created until the
lines below run. I think you need to move this line down. What format
does fileDate have? I guess it's a string of text from the file. If
you can convert it to a datetime (or date) object it will be easy to
compare with the dates as required for your calibration file. Can you
show us how it looks e.g.

'12-Nov-2012'
or
'12/11/12'
or something else?

>
> #extract data from data file
> fdData = open(dataFile,"rt")
> data = fdData.readlines()
> fdData.close()


Python has a slightly better way of writing code like this:

with open(dataFile, 'rt') as fdata:
data = fdata.readlines()

This way you don't need to remember to close the file. In fact Python
will even remember to close it if there is an error.


>
> #extract data from calibration file
> fdCal = open(caliFile,"rt")
> calibration = fdCal.readlines()
> fdCal.close()

Where is caliFile set? If your going to load all the data files you
might as well load both calibration files here at the beginning.

>
> #create data table
> k=0 #just a counter
> dataNum = numpy.ndarray((2151,2))

Does dataNum store integers or floating point numbers? Numpy won't let
you do both in the same array. You should always specify the type of
the numpy array that you want to create:

dataNum = numpy.ndarray((2152, 2), float)

or

dataNum = numpy.ndarray((2152, 2), int)

As it happens you are creating an array floats. That means that when
you try to store an integer in the array below it gets converted to a
float.

>
> #the actual data (the numbers) in the data file begin at line 30
> for anItem in data[30:]:
> theNums = anItem.replace("\r\n","").split("\t")
> dataNum[k,0] = int(theNums[0])
> dataNum[k,1] = float(theNums[1])
> k+=1 #advance the counter

You should look into using numpy.fromfile. This function is
specifically designed for this purpose.

For example:

with open(dataFile) as fdata:
header_lines = [fdata.readline() for _ in range(30)]
dataNum = numpy.fromfile(fdata, float, sep='\t')


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] generic repr method?

2012-10-01 Thread Oscar Benjamin
On 1 October 2012 13:16, Albert-Jan Roskam  wrote:
>
>> On Sat, Sep 29, 2012 at 4:15 PM, Albert-Jan Roskam 
>> wrote:
>>>
>>>  def __repr__(self):
>>>  code = self.__class__.__name__ + "("
>>>  for arg in inspect.getargspec(self.__init__).args [1:]  :
>>>  if isinstance(eval("self." + arg), basestring):

Please don't use eval for this. Python has a much better function that is
explicitly designed to use what you want., e.g.:

eval("self." + arg)  # Bad
getattr(self, arg)# Good


>>>  code += ("%(" + arg + ")r, ")
>>>  else:
>>>  code += ("%(" + arg + ")s, ")
>>>  code = code[:-2] + ")"
>>>  return code % self.__dict__
>>
> It seems that for my current project I could still use the code, though
I'd find it more readable if the keywords are also included in the string.

Is it so hard to write a repr for each class that needs one (most don't)?

I think most repr functions I've written have been very short and easy to
write.

def __repr__(self):
return 'MyClass(x={0}, y={1})'.format(self.x, self.y)

It's also good to think about each individual class and whether or not the
repr really makes sense.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] 1d to 2d array creation

2012-10-01 Thread Oscar Benjamin
On 1 October 2012 22:04, Bala subramanian  wrote:

> Friends,
> I have an 1d array like a=[1, 1, 2, 2, 2, 3, 3, 1, 1, 1], i have to
> convert it to 2d array for plotting as follows. The 2d array is filled
> by a[colum index] to obtain the new array shown below.
>
> [ [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.],
>   [ 0.,  0.,  2.,  2.,  2.,  0.,  0.,  0.,  0.,  0.],
>   [ 0.,  0.,  0.,  0.,  0.,  3.,  3.,  0.,  0.,  0.] ]
>
> I wrote the following simple code for the conversion. However i guess
> there should be more fancy/speeder way to do that. Also i need to
> create such 2d-array from larger 1d arrays of size 2,3 items
> etc. Hence i would like to request hints for a better code for the
> purpose.
>
> Here no. rows in my case is always = no. of discrete values in array a.
>
> >>>my=1
> >>>for i in range(3):
> >>>  for j in range(10):
> >>> if a[j] == my : b[i,j]=my
> >>> else: b[i,j]=0
> >>>  my +=1
>

Instead of

my = 1
for i in range(3):
   # stuff
   my += 1

why not do

for my in range(1, 4):
# stuff

But actually it makes more sense to eliminate one of the loops and do:

for i, ai in enumerate(a):
b[i, ai] = ai

It may be that you get better speed with something like

for j in range(max(a.max)):
b[j, a==j+1] = j

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Civil discourse from a newbie's perspective

2012-10-02 Thread Oscar Benjamin
On 2 October 2012 11:16, Cecilia Chavana-Bryant
 wrote:
>
> In my case, I am a complete beginner not only to python but programming in 
> general, a complete beginner to internet forums (this is my third post ever) 
> and I am also not a native English speaker. So, I feel triply ignorant when I 
> post a question. Not only do I find it difficult to articulate my problem, as 
> being a beginner to programming, I basically don't know what the hell I'm 
> talking about, but after reading other posts where people have been corrected 
> on their formatting I am also very insecure about this.

Please don't be nervous about posting because you are not sure about
the best way to write your post. Nobody will really get upset with you
for top-posting or not including all of the relevant information (on
other mailing lists they might).

The comments that are sometimes made about formatting posts or
providing extra information should not be interpreted as criticism.
They are intended to help everyone communicate on this list. They are
also good advice for posting on other mailing lists.

If someone makes a comment like that to you, consider it a piece of
advice (that you can ignore if you like). The point is that if your
own communication is better then you will get more out of this mailing
list.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] getattr works sometimes

2012-10-02 Thread Oscar Benjamin
On 2 October 2012 18:44, Tino Dai  wrote:
> Hi All,

Hi Tino

>
>   I'm using the get_class from:
>
> http://stackoverflow.com/questions/452969/does-python-have-an-equivalent-to-java-class-forname

Can you show the relevant portion of your code please?

>
> and the get_class class works sometime for finding modules within a
> certain directory. If the get_class
> doesn't work, it throws an AttributeError.

I don't really understand what you mean by this. Can you copy and
paste the actual error message (all of it)?

>
> The module exists in the directory, and I'm trying to debug this. Does
> anybody have any hints to go about debug
> this?

Not really as you haven't provided enough information.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] getattr works sometimes

2012-10-02 Thread Oscar Benjamin
On 2 October 2012 19:27, Tino Dai  wrote:
> On Tue, Oct 2, 2012 at 2:20 PM, Tino Dai  wrote:
 and the get_class class works sometime for finding modules within a
 certain directory. If the get_class
 doesn't work, it throws an AttributeError.
>>>
>>> I don't really understand what you mean by this. Can you copy and
>>> paste the actual error message (all of it)?
>>>

 The module exists in the directory, and I'm trying to debug this. Does
 anybody have any hints to go about debug
 this?
>>>
>>
>> get_class('etl.transfers.bill_subject')  #
>> etl.transfers.bill_subject does exist under the transfers directory
>> > './leg_apps/etl/transfers/bill_subject.pyc'>

It shouldn't be returning a module. Is there a class in the
bill_subject module that you wanted to get? What happens if you do:

get_class('etl.transfers.bill_subject.BillSubject')

where BillSubject is the name of the class in the module.

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help for Python Beginner with extracting and manipulating data from thousands of ASCII files

2012-10-02 Thread Oscar Benjamin
Hi Cecilia, I'm sending this again as the first message was sent only
to you (I hadn't realised that your own message was sent only to me as
well). If you want to reply please reply-all to this message.

On 1 October 2012 17:42, Cecilia Chavana-Bryant
 wrote:
> On Mon, Oct 1, 2012 at 11:02 AM, Oscar Benjamin 
> wrote:
>>
>> On Sep 30, 2012 11:10 PM, "Cecilia Chavana-Bryant"
>>  wrote:
>> >
>> > fileDate = data[6][16:26] # location of the creation date on the data
>> > files
>>
>> What format does fileDate have? I guess it's a string of text from the file. 
>> If
>> you can convert it to a datetime (or date) object it will be easy to
>> compare with the dates as required for your calibration file. Can you
>> show us how it looks e.g.
>>
>> '12-Nov-2012'
>> or
>> '12/11/12'
>> or something else?
>
>
> Date is in the following format: dd/mm/

The standard way to work with dates is to turn the date strings into
Python datetime objects. You can read about those here:
http://docs.python.org/library/datetime.html

datetime objects can be create directly:

>>> from datetime import datetime
>>> start_date = datetime(year=2012, month=11, day=3)
>>> print start_date
2012-11-03 00:00:00

You can also create them from a string:

>>> datestring = '10/11/2012'
>>> experiment_date = datetime.strptime(datestring, '%d/%m/%Y')
>>> print experiment_date
2012-11-10 00:00:00

Once you have two datetime objects you can compare them directly:

>>> experiment_date > start_date
True
>>> print experiment_date - start_date
7 days, 0:00:00

Using this you can check whether the date from the data file is in
between the start and end dates for each of the calibration files and
then choose which calibration file to use.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] "ImportError: _strptime not supported"

2012-10-02 Thread Oscar Benjamin
On 2 October 2012 23:19,   wrote:
> The following code was recently suggested as an example of how the
> datetime module could be used to solve a problem.  Not having access to
> Python at work, I found
> http://pythontutor.com/visualize.html
> thinking it would allow me to "play with Python" when I have a free moment.

There are a few websites like this. You have to bear in mind that they
usually disable some functionality for security. I would expect the
datetime module to work though.

>
> from datetime import datetime
> start_date = datetime(year=2012, month=11, day=3)
> print(start_date)
>
> datestring = '10/11/2012'
> experiment_date = datetime.strftime(datestring, '%d/%m/%Y')

The example I posted uses strptime not strftime. Note the 'p' in the
middle instead of the 'f'. These two functions are opposites: strptime
turns string objects into datetime objects and strftime does the
inverse.

Yes, it is silly to have functions with such similar names that are
hard to distinguish visually. Unfortunately Python inherited these
names from the C programming language where it was more difficult to
use good names for functions.

> print(experiment_date)
>
> if experiment_date > start_date:
> print("Experiment_date comes after start_date.")
> else:
> print("Expriment_date does not come after start_date.")

Otherwise you've got the right idea. Although I think for the original
problem it should be:

   if experiment_date >= start_date:

Note the '>=' instead of '>'.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] [Tkinter-discuss] displaying an image

2012-10-04 Thread Oscar Benjamin
On 4 October 2012 20:31, Matthew Ngaha  wrote:
>> You need to install PIL to use the tutorial you are doing.
>>
>> http://www.pythonware.com/products/pil/
>
> the site says
> "
> The current free version is PIL 1.1.7. This release supports Python
> 1.5.2 and newer, including 2.5 and 2.6. A version for 3.X will be
> released later.
> "
>
> i have python 3. all the downloads below it only show python 2
> versions. am i stuck?:(

Yes.

Well actually, no. You can just install Python 2.7 and use PIL with
that. It might be better though to focus on things that do work in
Python 3 and find a tutorial that doesn't need PIL.

It's possible that PIL will never be available for Python 3. Here's a
message from 2009 on the PIL mailing list (it looks like not much has
changed since then):
'''
The plan is to get 1.1.7 out of the door (early april) and then make a
version of that available for 3.x. There's also a preliminary port of 1.1.6
available from a third party; see the mailing list archives for pointers.
'''

http://mail.python.org/pipermail/image-sig/2009-March/005498.html

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Through a glass, darkly: the datetime module

2012-10-05 Thread Oscar Benjamin
On 5 October 2012 14:47, Richard D. Moores  wrote:
> I thought it would be useful to have a script that would tell me what
> the date n days from today would be. The docs
> ()
> seem to get me almost there. I can compute the number of days between
> 2 dates, and the number of days between a date and today:
>
> Python 3.2.3 (default, Apr 11 2012, 07:12:16) [MSC v.1500 64 bit (AMD64)]
>
> import time
> from datetime import date, timedelta
 date1 = date(2001, 9, 11)
 date1
> datetime.date(2001, 9, 11)
 date2 = date(2003, 4, 15)
 date2
> datetime.date(2003, 4, 15)
 date2 - date1
> datetime.timedelta(581)
 days_delta = date2 - date1
 days_delta.days
> 581
 today = date.today()
> today
> datetime.date(2012, 10, 5)
 print(today)
> 2012-10-05
 time_to_date = today - date1
 time_to_date
> datetime.timedelta(4042)
 print(time_to_date)
> 4042 days, 0:00:00
 print(time_to_date.days)
> 4042
>
> However, brick wall:
>
> timedelta.days = 100
> Traceback (most recent call last):
>   File "", line 1, in 
> builtins.TypeError: can't set attributes of built-in/extension type
> 'datetime.timedelta'

timedlta objects are immutable. Once an object is created it's values
cannot be changed (much like a tuple). You need to create a new
timedelta object:

>>> from datetime import datetime, timedelta
>>> dt = datetime.now()
>>> print dt
2012-10-05 15:14:55.841000
>>> d = dt.date()
>>> print d
2012-10-05
>>> td = timedelta(days=7)
>>> print dt + td
2012-10-12 15:14:55.841000
>>> print d + td
2012-10-12

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] modulo

2012-10-07 Thread Oscar Benjamin
On 8 October 2012 00:07, Dave Angel  wrote:
> On 10/07/2012 06:49 PM, Esteban Izaguirre wrote:
>> Hi, I'm following coursera's learn to program: the fundamentals, which
>> teaches programming basics in python. Our first assignement involves the
>> modulo operator with a negative divident, and while I've managed to get to
>> understand it enough for the purposes of the assignement with help from
>> othe rstudents, I still don't know how the hell it works, I wouldn't know
>> how to use modulo in another situation if it ever arised. So, i undertand
>> how modulo works when only positive numbers are used, but how does modulo
>> determine, that, say -15 % 14 is equal to 13? Or -20 % 100 is 20? I just
>> don't get how modulo works, all explanations I've found online only seem to
>> be in relation of how this applies to perl or something, can someone
>> explain it to me?
>>
>>
>
> There is one perfectly reasonable definition for how modulo should
> behave if the denominator (modulus) is positive. Python does it 'right',
> so I'll try to explain it in a couple of ways.
>
> (If the modulus (denominator) is negative, it makes no sense to me, so I
> can't even recall what Python does, and I have to look it up each time.
> Fortunately this is rare, and in my code, I just avoid it)

The sign of the modulo operation is always the same as the sign of the
denominator:


>>> 3%5
3
>>> 3%(-5)
-2
>>> (-3)%5
2
>>> (-3)%(-5)
-3


That way you can say that the result of the a % b is always in the
range from 0 to b (not including b itself).


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] string rules for 'number'

2012-10-08 Thread Oscar Benjamin
On 8 October 2012 03:19, eryksun  wrote:
> As a supplement to what's already been stated about string
> comparisons, here's a possible solution if you need a more 'natural'
> sort order such as '1', '5', '10', '50', '100'.
>
> You can use a regular expression to split the string into a list of
> (digits, nondigits) tuples (mutually exclusive) using re.findall. For
> example:
>
> >>> import re
> >>> dndre = re.compile('([0-9]+)|([^0-9]+)')
>
> >>> re.findall(dndre, 'a1b10')
> [('', 'a'), ('1', ''), ('', 'b'), ('10', '')]
>
> Use a list comprehension to choose either int(digits) if digits is
> non-empty else nondigits for each item. For example:
>
> >>> [int(d) if d else nd for d, nd in re.findall(dndre, 'a1b10')]
> ['a', 1, 'b', 10]
>
> Now you have a list of strings and integers that will sort 'naturally'
> compared to other such lists, since they compare corresponding items
> starting at index 0. All that's left to do is to define this operation
> as a key function for use as the "key" argument of sort/sorted. For
> example:
>
> import re
>
> def natural(item, dndre=re.compile('([0-9]+)|([^0-9]+)')):
> if isinstance(item, str):
> item = [int(d) if d else nd for d, nd in
> re.findall(dndre, item.lower())]
> return item
>
> The above transforms all strings into a list of integers and lowercase
> strings (if you don't want letter case to affect sort order). In
> Python 2.x, use "basestring" instead of "str". If you're working with
> bytes in Python 3.x, make sure to first decode() the items before
> sorting since the regular expression is only defined for strings.
>
> Regular sort:
>
> >>> sorted(['s1x', 's10x', 's5x', 's50x', 's100x'])
> ['s100x', 's10x', 's1x', 's50x', 's5x']
>
> Natural sort:
>
> >>> sorted(['s1x', 's10x', 's5x', 's50x', 's100x'], key=natural)
> ['s1x', 's5x', 's10x', 's50x', 's100x']

For simple cases like this example I tend to use:

>>> natural = lambda x: (len(x), x)
>>> sorted(['s1x', 's10x', 's5x', 's50x', 's100x'], key=natural)
['s1x', 's5x', 's10x', 's50x', 's100x']


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] managing memory large dictionaries in python

2012-10-16 Thread Oscar Benjamin
On 16 October 2012 21:03, Prasad, Ramit  wrote:
> Abhishek Pratap wrote:
>> Sent: Tuesday, October 16, 2012 11:57 AM
>> To: tutor@python.org
>> Subject: [Tutor] managing memory large dictionaries in python
>>
>> Hi Guys
>>
>> For my problem I need to store 400-800 million 20 characters keys in a
>> dictionary and do counting. This data structure takes about 60-100 Gb
>> of RAM.
>> I am wondering if there are slick ways to map the dictionary to a file
>> on disk and not store it in memory but still access it as dictionary
>> object. Speed is not the main concern in this problem and persistence
>> is not needed as the counting will only be done once on the data. We
>> want the script to run on smaller memory machines if possible.
>>
>> I did think about databases for this but intuitively it looks like a
>> overkill coz for each key you have to first check whether it is
>> already present and increase the count by 1  and if not then insert
>> the key into dbase.
>>
>> Just want to take your opinion on this.
>>
>> Thanks!
>> -Abhi
>
> I do not think that a database would be overkill for this type of task.

Neither do I but I think that there are also ways to make it more
memory efficient without the use of disk storage. I suspect that the
bulk of the memory usage is for the strings and there are often ways
to store them more efficiently in memory.

For example, are you using Python 3? You might be able to reduce the
memory consumption by 25-50% by using byte strings instead of unicode
strings (assuming that the keys are ascii).

Further gains are possible if your strings only use a subset of ascii
characters, as is the case for e.g. hex strings. If you can map the
strings reversibly to integers with a function (rather than a dict)
then you should be able to achieve a significant reduction in memory
usage by using ints as the dictionary keys.

A 20 character hex key can theoretically be stored with 80 bits or 10
bytes. If you could hit this limit then you would only need 4-8 GB of
memory for the strings themselves (which may still be too much).

> Your process may be trivial but the amount of data it has manage is not 
> trivial. You can use a simple database like SQLite. Otherwise, you
> could create a file for each key and update the count in there. It will
> run on a small amount of memory but will be slower than using a db.
>
> # Pseudocode
> key = get_key()
> filename = os.path.join(directory, key)
> if os.path.exists(filename):
> # read and update count
> else:
> with open(os.path.join(directory, key), 'w') as f:
> f.write('1')

Depending on the file system this could require a large amount of disk
space. If each file needed 4096 bytes of disk space then you would
need around 2-3 TB of disk space with this solution.

>
> Given that SQLite is included in Python and is easy to use, I would just
> use that.

I would also try this. A standard database solution will likely give
the least headaches in the long run.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Which is better Practice and why

2012-10-22 Thread Oscar Benjamin
On 22 October 2012 12:54, Devin Jeanpierre  wrote:
> On Mon, Oct 22, 2012 at 7:45 AM, Matthew Ngaha  wrote:

Hi Devin, your context was missing the crucial part showing the "2nd one":

>> they call the main program by simply calling the main function. I've also
>> seen a more complcated:
>>
>> if __name__ == '__main__':
>> main()

>> the 2nd one usually includes a lot more code then i showed. can you please
>> tell me why different methods are used to access the main code? is it just
>> preference or is one way actually better coding practice?
>
> The second one is used if your importable modules are also scripts
> that can be executed.
>
> That's a bad idea, because it results in the same source file being
> executed twice, producing distinct classes that break typechecking. If
> you have "myprogram.py" containing the following source code, and
> execute it as a program, it will terminate with an uncaught MyError.

There is nothing wrong with having a script that can also be imported
(or a module that can also be executed). I do this often, particularly
when I have a number of related scripts in the same folder as one
another.

Python allows a .py file to represent a script or a module. Python
itself maintains no formal distinction between scripts and modules.
Adding if __name__ == "__main__" allows your script/module to
determine whether it is being executed or imported and do different
things in each case.

One case where this is good is to add a test suite to a module. For
example my module defines some functions that can be imported by other
modules. It also defines some code to test that the functions it
defines are working properly. I don't want to run the tests every time
I import the module but I can run them conveniently if I put them in a
__name__ == "__main__" block and then execute the module as a script
every now and then. Both the unittest and doctest modules supply
functions specifically for use in this way.

Another common case is that your module defines some functions that
are of general use but you also make it possible to run the module as
a script in order to perform some of the most common operations that
your module performs. There are several examples in the Python
standard library that do this for example pdb and cProfile.

It is also sometimes useful to define a number of scripts that are in
the same directory but share some code by importing one another. You
need the if __name__ =="__main__" block for this.

The problem that Devin is referring to only happens in certain odd
situations where the script that you run ends up importing itself
(perhaps indirectly). I have never personally had that problem though.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Which is better Practice and why

2012-10-22 Thread Oscar Benjamin
On 22 October 2012 16:14, eryksun  wrote:
> On Mon, Oct 22, 2012 at 9:35 AM, Oscar Benjamin
>  wrote:
>>
>> It is also sometimes useful to define a number of scripts that are in
>> the same directory but share some code by importing one another. You
>> need the if __name__ =="__main__" block for this.
>>
>> The problem that Devin is referring to only happens in certain odd
>> situations where the script that you run ends up importing itself
>> (perhaps indirectly). I have never personally had that problem though.
>
> Just to clarify that I'm following you, would you count the following
> as a script importing itself 'indirectly'?

Yes.

> Assume two modules in the same directory, mod1.py and mod2.py, can
> both act as the main entry point, and both import each other (assume
> no circular import problem).

They both import each other. That is a circular import and it can
create problems. My advice for this issue is not "avoid importable
scripts" but rather "avoid circular imports" (a good idea anyway).

> Then if mod1.py runs as __main__ and
> imports mod2, and mod2.py imports mod1, there are 2 copies of the
> classes and functions defined in mod1.py. For example, there's
> __main__.MyError vs mod1.MyError.

I agree that this would be problematic. However, if mod1.py and
mod2.py both import each another then neither of them is really an
independent script. There is no reason why any common code should not
be moved into a third module to avoid the circular import.

I have used importable scripts many times and never had this problem
because I have never used them with circular imports. Typically the
action of running the module as a script provides a command line
interface that does some common but useful thing with the code in that
same module (rather than code imported from other modules).

An example from a recent project: I have a module that defines
functions for interacting with a particular database. It can be
imported by scripts that perform computations based on the contents of
the database. It can also be run as a script in which case it provides
a command line interface to query/export the contents of the database.
This particular module does not import any other modules within the
same project so it will never have the circular import problem. There
are other importable scripts that depend on the database module but
they also don't use circular imports.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help - Using Sort and Join

2012-10-22 Thread Oscar Benjamin
On 22 October 2012 20:57, Daniel Gulko  wrote:
> Hi Python Tutor,

Hi Daniel,

> I have an issue trying to figure out how to print out final answers using
> sort and join functions.

Do you know how to use sort and join to print a list of strings in
alphabetical order?

>
> Assignment Specification:
> make a function that is a magic eight ball emulator. emulator will be a
> function that returns one of the possible answers. Make another function
> that runs the emulator over and over again until user wants to quit,
> printing answer each time. When user quits, present all answers that the
> user got again, but present them in alphabetical order. Use the join()
> function available for strings for this.
>
> As my code is written when user presses enter I simply break and print this
> current output:
> Have a nice day
>
> What I want is when user exits for my code to take all previous answers,
> joining them and sorting them like below:
> ask a question (or press 'enter' to quit):
> You may rely on it. It is decidedly so. Better not tell you now.

The problem is that your not saving the answers so at the point where
your program ends they aren't available for you to print them. You
should use a list to collect the answers as they are generated. Then
you can think about how to use the sort and join functions

>
> My code works right now but I am missing the final part in how to join and
> sort all answers. Any suggestions or examples is helpful as I
> am very new with Python.
>
> Current code is attached for viewing.

Your code is not too long to be pasted directly into the email:

'''
import random

def AskMagicEightBall():

answers = ("As I see it, yes.",
   "It is certain.",
   "It is decidedly so.",
   "Most likely.",
   "Outlook good.",
   "Signs point to yes.",
   "Without a doubt.",
   "Yes.",
   "Yes – definitely.",
   "You may rely on it.",
   "Reply hazy, try again.",
   "Ask again later.",
   "Better not tell you now.",
   "Do not count on it.",
   "My reply is no.",
   "My sources say no.",
   "Outlook not so good.",
   "Very doubtful.")

return random.choice(answers)

def RunEmulator():

while True:
question = raw_input("ask a question (or press 'enter' to quit): ")
if question:
answers=AskMagicEightBall()
print answers
elif not question:
print "Have a nice day"
break

RunEmulator()
'''


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Iterators, example (need help)

2012-10-22 Thread Oscar Benjamin
On 23 October 2012 01:43, Steven D'Aprano  wrote:
> In general, your __iter__ method will be trivially simple:
>
> def __iter__(self):
> return self
>
> and most of the logic will be in __next__. I see your __iter__
> method is a little more complicated, but I haven't studied it
> in detail to see if the extra complication is justified.

The __iter__ method performs the same operation that is already
performed in __init__ and __next__ so it is redundant. Probably it
should reset the counter to restart iteration. However, in the
provided code it is never called since the Env instance is never used
in a for loop or iter() call.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Which is better Practice and why

2012-10-23 Thread Oscar Benjamin
On 23 October 2012 02:17, Devin Jeanpierre  wrote:
> On Mon, Oct 22, 2012 at 8:42 PM, Steven D'Aprano  wrote:
>> If you do that, and the module directly or indirectly imports itself
>> while it is running as a script, you may run into trouble. But writing
>> a dual-purpose module that is usable as an importable module or as a
>> stand-alone script is not problematic in itself.
>
> Yes. However, it is somewhat hard to guarantee that a module won't
> indirectly import itself for a large codebase. It certainly sometimes
> happens by accident.

I guess this is the crux of the issue. If your script is part of and
depends on a large codebase then you may as well place all of its code
elsewhere in the codebase. The script then serves simply as an entry
point and its presence in the project won't hinder your ability to
move all the code it uses around to suit its relationship to the rest
of the codebase.

Importable scripts are useful when you have a codebase that is
smaller. In particular if your codebase is one single script (a common
case) then you should always use if __name__ == "__main__" unless the
script is trivial and/or, as Steven says, you're feeling lazy. Doing
this means that you can test your script and its functions by
importing the script in the interactive interpreter and that you can
reuse the script as a module in some other project

If your codebase is a single module rather than a script, giving it an
if __name__ == "__main__" block allows someone to perform a common
task with the module (or perhaps run its tests) using the -m
interpreter option without needing to turn a single file project into
a double file project:

$ python -m mymodule arg1 arg2

This is often better than creating a separate script to serve as a
redundant entry point (redundant since the module can already serve as
its own entry point).

Once you have one importable script A.py you can then place another
script B.py in the same folder have B import and use some of A's code.
As Eryksun has said making this work both ways (having B also import
from A) can lead to problems. If you find yourself wanting to do that
then you have probably organised your code badly. As a solution
consider moving all of the common code into one of A or B or into a
new module/script C.

Another factor not mentioned yet is that the use of if __name__ ==
"__main__" is so ubiquitous that using it in your own script
communicates something to most people who read it (including
yourself). If I know that X.py is intended to be used as a script and
I want to read it to find out how it works, one of the first things I
would do is search for that line. My natural assumption is that no
non-trivial execution occurs outside of that if-block (this is almost
always true if I wrote the script and it is longer than about 10
lines).


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help on Remote File Copy & Exection

2012-10-25 Thread Oscar Benjamin
On 25 October 2012 10:26, Arumugam N  wrote:
> Hi All,
>
> First of the big thanks and congrats for managing such a brilliant online
> community. I am new to Python and have started getting the taste of python
> on my day to day work.
>
> I have a requirement and i am trying to solve it using python.
>
> I am from QA. Here is what i do daily and wanted to do with python
> automatically.
>
> 1. Revert the snapshot of a VM used for testing. - i have automated using
> pysphere
> 2. Copy the build from share location to the VM - here i can have a python
> script run from the VM but is it possible to run it remotely? for example.
> if i run the script from Machine A, it should revert the snapshot of machine
> B and copy the build to Machine B from shared location.
> 3. Run the installer and clikc Next Button of the installation GUI. - Any
> idea how to automate this ?

These questions are probably more suited to a different mailing list
as this one is predominantly for helping in learning the elementary
aspects of programming in Python.

If you can perhaps ask a more specific Python question it might be
appropriate here. Otherwise I suggest that you either:
a) Ask on the pysphere mailing list (I have no idea what pysphere is
so this may not be appropriate)
b) Use a search engine to find a project that already does what you want
c) Ask for general help on python-list where people may know of a good
way to do what you want in Python


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] For - if - else loop; print selective output

2012-10-25 Thread Oscar Benjamin
On 25 October 2012 21:16, eryksun  wrote:
> On Thu, Oct 25, 2012 at 3:46 PM, Prasad, Ramit
>  wrote:
>>
>> Do you happen to know offhand if there is a difference between
>> `in ` vs. `in ` vs. `in `?
>
> The "in" comparison (__contains__ method) is equivalent for list and
> tuple. It has to search through the sequence item by item, which makes
> it an O(n) operation. On the other hand, a set/dict uses the hash() of
> an object to map it to a known location in a table (performance
> degrades if there are many collisions). On average, you can check if a
> set/dict contains an item in constant time, i.e. O(1). The amortized
> worst case is O(n).

Why do you say "*amortized* worst case"? Is there an occasional worse
than O(n) operation that is insignificant when amortised?

At first I assumed that was a slip of the tongue but you generally
seem to know an incredible amount about the implementation of CPython,
so now I'm curious.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] For - if - else loop; print selective output

2012-10-25 Thread Oscar Benjamin
On 26 October 2012 00:08, Steven D'Aprano  wrote:
> On 26/10/12 07:16, eryksun wrote:
>>
>> On Thu, Oct 25, 2012 at 3:46 PM, Prasad, Ramit
>>   wrote:
>>>
>>>
>>> Do you happen to know offhand if there is a difference between
>>> `in` vs. `in` vs. `in`?
>>
>>
>> The "in" comparison (__contains__ method) is equivalent for list and
>> tuple. It has to search through the sequence item by item, which makes
>> it an O(n) operation. On the other hand, a set/dict uses the hash() of
>> an object to map it to a known location in a table (performance
>> degrades if there are many collisions). On average, you can check if a
>> set/dict contains an item in constant time, i.e. O(1). The amortized
>> worst case is O(n).
>
>
> To be precise: dict lookup, deletion and insertion are amortized O(1)
> (on average, constant time) assuming there are no hash collisions.
>
> When there are collisions, they are O(k) where k is the number of
> colliding items. So in the worst case where k=n (the number of items
> in the dict), dicts perform a little worse than lists, but in the
> typical case, they are usually much, much faster.

The use of big-O notation above seems strange to me. The average value
of k is (assuming non-pathological inputs) a constant that is
independent of n (for large n). So O(k) really means average case
O(1).

> "Amortized" strictly only refers to deletion and insertion. Since
> lookups don't modify the dict, a lookup always takes the same time.
> But deletions and insertions will occasionally trigger a resize of
> the dict, which obviously takes a lot longer than the non-resizing
> cases. But if you spread the average cost of the resize over many
> insertions or deletions, you get amortized O(1) time.

You mean that the cost is only considered to be "amortised" when
averaging over the cost of the qualitatively distinct operation of
resizing the dict among the cost of the non-resizing insertions (does
deletion ever trigger a resize?). When averaging over the cases where
there are more or less hash collisions but no possibility of resizes
we refer to the cost as "average case" but not "amortised". Is that
what you mean?


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] run with default value if input not given

2012-10-29 Thread Oscar Benjamin
On 29 October 2012 06:06, Saad Javed  wrote:
> Hi,
>
> #!/usr/bin/env python
>
> import sys
>
> x = 'Saad is a boy'
>
> def main(x):
> a = []
> b = x.split(' ')
> for item in b:
> a.append(item)
> print a
> if __name__ == '__main__':
> x = sys.argv[1]
> main(x)
>
>
> How can I make this program run with the default value of x if I don't
> specify an argument at the command line?

My preference is to use Python's default function argument mechanism
to fill in the missing values:

def main(x, y='default'):
print(x)
print(y)

if __name__ == "__main__":
main(sys.argv[1:])

This is the quickest way to get what you want. For a proper script,
though, I would use an argument parser such as argparse.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] run with default value if input not given

2012-10-29 Thread Oscar Benjamin
On 29 October 2012 13:32, Oscar Benjamin  wrote:
>
> def main(x, y='default'):
> print(x)
> print(y)
>
> if __name__ == "__main__":
> main(sys.argv[1:])

A quick correction. That should be (note the *):

if __name__ == "__main__":
main(*sys.argv[1:])


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] greater precision?

2012-10-29 Thread Oscar Benjamin
On 29 October 2012 10:19, Dave Angel  wrote:
> On 10/29/2012 05:49 AM, John Collins wrote:
>>
>> Sorry to bother, but if I can squeeze out *at least* 15 sig figs, (30
>> or more would be better!) I'd be a happy camper!
>> XNumbers addon for Excel allows over 200 sig figs by switching to base
>> 256 IIRC. It is this with which I'd like to examine the output of these
>> pyto scripts at finer resolution, if that can be done in python???
>>
>> Best Regards,
>> John Collins.
>>
>>
>
> 18 digits is what you should get if the code is as I describe.  But if
> there are lots of fp operations you're not showing, then an error can
> gradually get larger.  And with any finite precision, you have the risk
> from things such as subtracting two nearly-equal values, which will
> reduce the final precision.

I wouldn't describe it as 18 digits of precision since it fails for
computations that require only 17 digits of precision:

>>> 1e-16
1e-16
>>> 1 + 1e-16 - 1
0.0

>
> If you need more than 18, then go to the Decimal module, which lets you
> set the precision to arbitrary levels.  You will see a substantial
> slowdown, of course, if you set the precision very high.  if that
> becomes a problem, consider CPython 3.3, which has optimized that
> module.  But try not to change too many things at once, as there are
> lots of changes between 2.7 and 3.3.

I don't really understand why so much precision is needed but if I
were trying to improve it I would use the fractions module. The
Fraction type from the fractions module has unlimited precision:

>>> from fractions import Fraction
>>> 1 + Fraction('1e-16')  - 1
Fraction(1, 1)
>>> 1 + Fraction('1e-256')  - 1
Fraction(1, 
1)

To use this you would do the same as for the decimal module: convert
all of your numbers to Fraction type and pass the Fraction objects
into the function that performs computation with them. Of course if
you start out with floats and convert them to fractions then you will
still only have 15 digits of precision so if you really want unlimited
precision you need to convert the numbers to fractions at the point
when their values are known exactly and not use floats anywhere.

This means that your computations are exact but you still need to
choose a precision to output the numbers in decimal (unless you're
happy with fractions as output). If you want 256 digit decimal output
you can do:

>>> import decimal
>>> decimal.getcontext().prec = 256
>>> f = 1 + Fraction('1e-255')
>>> d = decimal.Decimal(f.numerator) / decimal.Decimal(f.denominator)
>>> print(d)
1.001


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] running multiple concurrent processes

2012-10-30 Thread Oscar Benjamin
On 30 October 2012 19:18, richard kappler  wrote:
> As I sit through the aftermath of Sandy, I have resumed my personal quest to
> learn python. One of the things I am struggling with is running multiple
> processes. I read the docs on threading and am completely lost so am turning
> to the most excellent tutors here (and thanks for all the help, past,
> present and future btw!).
>
> In what ways can one run multiple concurrent processes and which would be
> considered the "best" way or is that case dependent?
>
> Example:
>
> I'm working on programming a robot in Python. The bot has an Arduino board
> that receives sensor input and sends the data to a laptop which is the
> "brain" of the bot via pySerial and uses this incoming sensor data to help
> determine state. State is used in decision making. The laptop runs a program
> that we'll call the Master Control Program in a nod to Tron. The bot also
> has a chat program, computer vision, some AI it uses to mine the web for
> information, several other functions. Each of these  concurrent programs
> (thus far all python programs) must run continuously and feed data to the
> MCP which receives the data, makes decisions and sends out appropriate
> action commands such as for movement, change of state, conversation
> direction, what to research, etc.
>
> So, to return to the original question, how does one run multiple concurrent
> processes within python?

The obvious way would be to use the multiprocessing module:
http://docs.python.org/2/library/multiprocessing.html


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] running multiple concurrent processes

2012-10-30 Thread Oscar Benjamin
On 30 October 2012 21:10, richard kappler  wrote:
> Oscar, thanks for the link, though I must say with all due respect, if it
> was "obvious" I wouldn't have had to ask the question. Good link though. I
> suspect the reason I didn't find it is I did my searches under threading as
> opposed to multi-processing.

Sorry Richard, I think you may have misunderstood. I didn't mean "this
is obvious so why ask the question?". Rather I meant "there are a
number of ways to do this but to me the obvious choice is
multiprocessing". I probably should have added more explanation but I
realised I needed to get back on with cooking dinner and thought I'd
just send a quick pointer.

Of course when I say it's the obvious choice that assumes that you are
sure that concurrent processes is what you want. You can achieve
similar things in a number of ways as Dave has described.

If you're not sure which of threads and processes you want then I'll say that
normally in Python threads are used to run IO-bound operations
concurrently. Python's threads are no good for CPU-bound operations so
multiprocessing is used in that case. Do you know which case your
application falls under?


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] running multiple concurrent processes

2012-11-03 Thread Oscar Benjamin
On 3 November 2012 20:20, richard kappler  wrote:
> To all, especially Dave, Oscar and Ramit, thanks for the discussion and
> help. Tino, as soon as I have something to put up, I will gladly put it up
> on Github. At the moment I only have a few snippets I've written in trying
> to learn the various bits everyone has been helping me with.
>
> Just for the record, I did use subprocess quite successfully in one of my
> preliminary programs earlier this summer as I started to learn python, used
> it to send out the text from the old chatbot to Festival TTS, so I am
> comfortable with the idea of running multiple processes from python to the
> command line. I'm not quite sure that's the way to go with the sensors and
> other bits though.

You may be right. The problem is that this is not a situation where
anyone can really tell you the definitive way of doing things. There
are many ways to do what you're doing and which is best depends on
details that are currently unknown (by you or by the rest of us).

>
> I'm wondering if I'm asking the wrong question. I have read and re-read your
> posts, and have read and re-read the documentation on multi-processing and
> threading. I have also read several tutorials on both. I feel that I
> understand the concepts a wee bit better, though not enough to come up with
> some workable processing or threading code. I have, however, still not
> figured out an answer to my question, which leads me to believe I have not
> asked the question properly. The alternative is that I'm just too damned
> dense to wrap my arms around this and I both think and hope that is not the
> case, so I will try to do a better job of articulating what I'm looking for.
> (Again, I suspect its in multiprocessing and threading, but I can't quite
> put my finger on a good approach).

The example below shows how to use multiprocessing to run two
different operations concurrently. Each operation is run in its own
process.

#!/usr/bin/env python

from multiprocessing import Process
from time import sleep

def update_brain():
while True:
sleep(1)
print 'thinking...'

def chat_with_friends():
while True:
sleep(.3)
print 'chatting...'

p1 = Process(target=update_brain)
p2 = Process(target=chat_with_friends)

p1.start()
p2.start()


>
> SO... while the bot program is running, I would like it to be continuously
> cognizant of the sensor data and any changes in that data. Let's distill it
> down to a single sensor to simplify the discussion. If I have a temperature
> sensor feeding data to the arduino, which feeds that data through serial to
> the Python program (let's call that pyBrain) that "is" the bot, (here's the
> meat of the question:) how do I make the pyBrain constantly aware of the
> temperature while doing other stuff?

It depends on how pyserial works. This sounds like the kind of
situation where a separate thread would be used. I say a thread rather
than a process because this is most likely an IO-bound operation. This
means that it consumes very little CPU and spends most of its time
waiting for the serial port to produce data.

I've never used pyserial but I imagine that it has a function called
something like get_data that returns data read from the device. I also
imagine that this function "blocks". That means that it causes
execution to pause until data is ready and then returns the data. It
is precisely this blocking that makes people want to use threads.
While one thread blocks execution of the others can resume so that
waiting for data in one operation does not cause every other operation
to pause.

The downside of using multiple threads or processes though is that it
makes it harder to share data between the different operations. Here's
an extension of the above that shows how to share an integer between
the two processes:

#!/usr/bin/env python

from multiprocessing import Process, Value
from time import sleep
from random import randint

def update_brain():
global how_many_spams
while True:
sleep(1)
n = randint(1, 5)
print 'thinking...', n
how_many_spams.value = n

def chat_with_friends():
global how_many_spams
while True:
sleep(.3)
print 'chatting:' + how_many_spams.value * ' spam'

how_many_spams = Value('i', 1)

p1 = Process(target=update_brain)
p2 = Process(target=chat_with_friends)

p1.start()
p2.start()

>
> Befuddled and bewildered while learning at an alarming rate, Richard
>

I suggest that you just write the application and divide pieces off
into threads/processes later if needed. Avoid sharing data between
different operations except when strictly necessary (then breaking out
one part into a separate process or thread won't be so painful).

I'll rephrase the rule of thumb from before:

Use separate threads to separate out operations that involve
blocking-IO calls that would otherwise cause the whole application to
suspend.

Use separate processes to separate out CPU-heavy ope

Re: [Tutor] running multiple concurrent processes

2012-11-03 Thread Oscar Benjamin
On 4 November 2012 01:03, richard kappler  wrote:
> Oscar, that was positively brilliant! Now I get it, I understand how to do
> it, and I think this has rearranged my entire plan for the "MCP." If the MCP
> is basically just a program that calls several other programs(processes) and
> does that bit of coordination between each, then my life just got measurably
> easier. I think. I did some reading after my last post, and manager seems
> like it would be a good tool for a lot of this, or at least what we're
> calling the MCP for purposes of this discussion. Thoughts?

I didn't really understand the above. Is 'manager' some kind of library?

>
> I am reluctant to usurp any more of your time, but you are such a phenomenal
> teacher, might I ask for a quick example of threading like you did with the
> two multiprocessing snippets?

It looks almost exactly the same. The key difference is that you can
just share the value of an integer without needing to do explicitly do
anything. (This is also a big source of problems since sharing the
same data structures directly only works if all objects/operations are
thread-safe http://en.wikipedia.org/wiki/Thread_safety).

#!/usr/bin/env python

from threading import Thread
from time import sleep
from random import randint

def update_brain():
global how_many_spams
while True:
sleep(1)
n = randint(1, 5)
print 'thinking...', n
how_many_spams = n

def chat_with_friends():
global how_many_spams
while True:
sleep(.3)
print 'chatting:' + how_many_spams * ' spam'

how_many_spams = 1

t1 = Thread(target=update_brain)
t2 = Thread(target=chat_with_friends)

t1.start()
t2.start()

>
> Bill, I appreciate your comment and have given it much thought, Ramit made
> one much the same the other day. Here lies the potential problem, though it
> might not be one at all, I need to do some experimenting. While I am a fan
> of monolithic programming, I'm wondering if what I'm trying to do would work
> on, say an old netbook. That might be a requirement. I'd prefer it not to
> be, but it might. Also, thanks for reminding my addled old brain that event
> driven is called interrupts. I knew that at one point, but seem to have
> flushed it somehow.

Who's Bill? Alan was referring to Twisted that is an event driven
framework. Event driven or asynchronous processing is a third option
(after threads or processes). The Twisted library is also capable of
launching threads and (I think) processes for you so it could
accommodate for all of the possibilities you want in one framework.

>
> eryksun, I am using Linux, not a big fan of Windows, though have to use one
> at work, so thanks for breaking down forking on both platforms for me.
>
> This probably falls into the dumb question category, but I'd rather look
> dumb than be dumb. Other than as limited by CPU and memory (eg: hardware) is
> there any limit to the number of processes that can be run using processing?
> In other words, are there any constraints within Python?

As far as I know Python will allow you to come close to the
OS/hardware limit for both threads and processes. Unless I've
misunderstood what you're planning to do though these limits are high
enough for you to simply not worry about them.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] running multiple concurrent processes

2012-11-03 Thread Oscar Benjamin
On 4 November 2012 01:05, richard kappler  wrote:
> I notice no one has mentioned asyncore. Is that something I should stay away
> from? I just started digging through the doc file.

I've only briefly looked at asyncore. I've never heard anyone
recommend it: the recommendations for asynchronous processing in
Python seem to go to Twisted, Tornado, gevent and others. As far as I
can tell few people are using asyncore over the third party variants.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Fraction - differing interpretations for number and string - presentation

2015-04-17 Thread Oscar Benjamin
On 17 April 2015 at 03:29, Steven D'Aprano  wrote:
> On Thu, Apr 16, 2015 at 03:11:59PM -0700, Jim Mooney wrote:
>
>> So the longer numerator and denominator would, indeed, be more accurate if
>> used in certain calculations rather than being normalized to a float - such
>> as in a Fortran subroutine or perhaps if exported to a machine with a
>> longer bit-length? That's mainly what I was interested in - if there is any
>> usable difference between the two results.

If it's okay to use float and then go onto machines with higher/lower
precision then the extra precision must be unnecessary in which case
why bother with the Fraction type? If you really need to transfer your
float from one program/machine to another then why not just send the
decimal representation. Your 64-bit float should be able to round-trip
to decimal text and back for any IEEE-754 compliant systems. Writing
it as a fraction doesn't gain any extra accuracy. (BTW Python the
language guarantees that float is always an IEEE-754 64-bit float on
any machine).

When you use floats the idea is that you're using fixed-width floating
point as an approximation of real numbers. You're expected to know
that there will be some rounding and not consider your computation to
be exact. So the difference between 1.64 and the nearest IEEE-754
64-bit binary float should be considered small enough not to worry
about.

It's possible that in your calculations you will also be using
functions from the math module such as sin, cos, etc. and these
functions cannot be computed *exactly* for an input such as 1.64.
However they can be computed up to any desired finite precision so we
can always get the nearest possible float which is what the math
module will do.

When you use the fractions module and the Fraction type the idea is
that floating point inexactness is unacceptable to you. You want to
perform *exact* arithmetic and convert from other numeric types or
text exactly. You won't be able to use functions like sin and cos but
that's no loss since you wouldn't be able to get an exact rational
result there anyway.

Because the Fractions module is designed for the "I want everything to
be exact" use case conversion from float to Fraction is performed
exactly. Conversion from string or Decimal to Fraction is also exact.
The Fraction will also display its exact value when printed and that's
what you're seeing.

If you really want higher accuracy than float consider ditching it
altogether in favour of Fraction which will compute everything you
want exactly. However there's no point in doing this if you're also
mixing floats into the calculations. float+Fraction coerces to float
discarding accuracy and then calculates with floating point rounding.
If that's acceptable then don't bother with Fraction in the first
place. If not make sure you stick to only using Fraction.

> You're asking simple questions that have complicated answers which
> probably won't be what you are looking for. But let's try :-)
>
> Let's calculate a number. The details don't matter:
>
> x = some_calculation(a, b)
> print(x)
>
> which prints 1.64. Great, we have a number that is the closest possible
> base 2 float to the decimal 164/100. If we convert that float to a
> fraction *exactly*, we get:
>
> py> Fraction(1.64)
> Fraction(738590337613, 4503599627370496)
>
> So the binary float which displays as 1.64 is *actually* equal to
> 738590337613/4503599627370496, which is just a tiny bit less than
> the decimal 1.64:
>
> py> Fraction(1.64) - Fraction("1.64")
> Fraction(-11, 112589990684262400)
>
> That's pretty close. The decimal value that normally displays as 1.64 is
> perhaps more accurately displayed as:
>
> py> "%.23f" % 1.64
> '1.63990230037'
>
> but even that is not exact.

Just to add to Steven's point. The easiest way to see the exact value
of a float in decimal format is:
>>> import decimal
>>> decimal.Decimal(1.64)
Decimal('1.6399023003738329862244427204132080078125')

> The reality is that very often, the difference
> isn't that important. The difference between
>
> 1.64 inches
>
> and
>
> 1.63990230037 inches
>
> is probably not going to matter, especially if you are cutting the
> timber with a chainsaw.

I once had a job surveying a building site as an engineer's assistant.
I'd be holding a reflector stick while he operated the laser sight
machine (EDM) from some distance away and spoke to me over the radio.
He'd say "mark it 10mm to the left". The marker spray would make a
circle that was about 100mm in diameter. Then I would get 4 unevenly
shaped stones (that happened to be lying around) and drop them on the
ground to mark out the corners of a 1500mm rectangle by eye.
Afterwards the excavator would dig a hole there using a bucket that
was about 1000mm wide. While digging the stones would get moved around
and the operator would end up just vaguely guessing where the original
marks had been.

The engineer was absolutely insistent that it h

Re: [Tutor] bin to dec conversion puzzlement

2015-04-20 Thread Oscar Benjamin
On 20 April 2015 at 08:44, Jim Mooney  wrote:
> I can't seem to get my head around this 'simple' book example of
> binary-to-decimal conversion, which goes from left to right:
>
> B = '11011101'
> I = 0
> while B:
> I = I * 2 + int(B[0])
> B = B[1:]


Follow through the loop and see what happens. To begin I is zero and B
is the full string. Consider B_orig to be the original string. After
the first iteration we have that
 I = B[0]   and   B = B_orig[1:]
then
 I = 2*B[0] + B[1]  and B = B_orig[2:]
then
I = 2*(2*B[0] + B[1]) + B[2]  = 4*B[0] + 2*B[1] + B[2]
then
I = 8*B[0] + 4*B[1] + 2*B[2] + B[3]
and eventually
I = 128*B[0] + 64*B[1] + ... + 2*B[6] + B[7]
which is the desired result.


Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python tkinter. Opening another script from main window stop main window from functioning. Looking for Help

2015-04-27 Thread Oscar Benjamin
On 26 April 2015 at 04:23, Spencer For Friends  wrote:
> Hi all. I'm new to Python and I'm trying my best to learn, but I'm really
> struggling with some problems.
>
> I'm using a tkinter window with a button on it to open another Python
> script. When the button is clicked and the new script loads it opens up
> it's own window over top of my tkinter window. The problem is, when I
> switch back to my tkinter window, none of the buttons are click-able
> anymore. The whole windows is unresponsive. The click animation on the
> button doesn't even function. Any help to resolve this would be greatly
> appreciated. Here is my code.

Hi Spencer,

The problem is that you're trying to run a long running task within
your applications event loop. You have to understand that the main
loop in a GUI program looks something like this:

while True:
event = get_event_from_queue()
if event == button_pressed:
call_button_callback()
elif event == key_pressed:
respond_to_keypress()
elif event == close_button_clicked:
close_windows()
break
   # etc.

Your callback function takes a long time to run and during that time
the event loop is still waiting for call_button_callback() to finish.
The result is that it doesn't respond to anything during that time.

You can test the same effect with a simpler program:

from Tkinter import Tk, Button, S
from tkMessageBox import showinfo

def callback():
total = sum(1 for _ in xrange(10**8)) # <-- slow
showinfo(str(total))

root = Tk()

button1 = Button(text='Click me', command=callback)
button1.config(height=3, width=25)
button1.grid(row=1, column=0, sticky=S)

root.mainloop()

When you run this program and click the button it will freeze for 5-10
seconds while running the slow callback() function. If you click
something during this time then your click will go into the event
queue. The event loop will retrieve that click message once it has
finished waiting for the callback function to finish. You can test
this by clicking the 'Click me' button and then clicking the close
button before it has finished. As soon as the callback finishes the
program will close.

The solution to this is to use threads or subprocesses. On the face of
it this is quite simple but actually writing multi-threaded code is
quite tricky. Here's how to modify the above program to run the slow
callback function in a thread:

from Tkinter import Tk, Button, S
from tkMessageBox import showinfo
from threading import Thread

def callback_threaded():
Thread(target=callback).start()

def callback():
total = sum(1 for _ in xrange(10**8)) # <-- slow
showinfo(str(total))

root = Tk()

button1 = Button(text='Click me', command=callback_threaded)
button1.config(height=3, width=25)
button1.grid(row=1, column=0, sticky=S)

root.mainloop()

This program will create a separate execution thread to run the
callback. It's quite simple if you just want to run execfile in
parallel with your GUI. Where it gets trickier is if you need the
threads to interact and you need to pass data between them.


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Fwd: circular movement in pygame

2015-04-28 Thread Oscar Benjamin
On 28 April 2015 at 16:38, diliup gabadamudalige  wrote:
>
> Looking at the code on this page lines 47 & 48
>
> http://programarcadegames.com/python_examples/show_file.php?file=sprite_circle_movement.py
>
> is there a way to do
> self.rect.x +*= some value*
> self.rect.y += some value
>
> rather than
>
> self.rect.x = self.radius * math.sin(self.angle) + self.center_x
> self.rect.y = self.radius * math.cos(self.angle) + self.center_y

There's no way to do that. The second version ignores the previous
value of self.rect.x/y.

I'm going to guess that the angle has only changed by a small amount
delta_angle between iterations in which case there would be a way to
do it approximately.

The real question is just why though? The second version is correct
and will be correct for ever. The first version would only be
approximately correct and over time you'd probably find that the
position would drift so that the ball was effectively at a different
radius.

In any case if
 x = r * sin(theta)
then
dx/dt = r * cos(theta) * dtheta/dt.
Since
y = r * cos(theta) that's
dy/dt = x * dtheta/dt.
So you could update y approximately with:
y += x * dtheta/dt * deltat
where deltat is your timestep. In your code that would be:
self.rect.x += self.rect.y * self.speed
self.rect.y -= self.rect.x * self.speed

Really what you have now is better though.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Fwd: circular movement in pygame

2015-04-28 Thread Oscar Benjamin
On 28 April 2015 at 19:37, diliup gabadamudalige  wrote:
>
> I thank all those who responded to my question
>
> Here is the code that I had written.
>
> When updating is applied to a surface object the rotation works but when it
> is applied through a class to an object it goes wrong in about 3 rotations.
> As far as I can see the code is the same. What is wrong? If you can correct
> some code and show me would help.

Your code is too long and complicated for me to read through it all.
You should simplify your problem before posting it somewhere like
this. Make a simpler program that does something similar but without
all the pygame stuff. For example your program might just loop through
printing out the positions of the object at different times e.g.:

# game.py
#
# This program simulates a ball moving at constant speed
# in a two dimensional space.
#

# Initial position of ball
xpos = 0
ypos = 0

# Horizontal and vertical speed
xspeed = 1
yspeed = 2

# Timestep
deltat = 0.125

# Run through 10 iterations of simulation
for n in range(10):
# Update state
xpos += xspeed * deltat
ypos += yspeed * deltat

# Output current state
print('Position = (%.3f, %.3f)' % (xpos, ypos))

$ python game.py  # Show the output
Position = (0.125, 0.250)
Position = (0.250, 0.500)
Position = (0.375, 0.750)
Position = (0.500, 1.000)
Position = (0.625, 1.250)
Position = (0.750, 1.500)
Position = (0.875, 1.750)
Position = (1.000, 2.000)
Position = (1.125, 2.250)
Position = (1.250, 2.500)

Once you have made a simpler program carefully explain what it is that
you want it to do and show us how what it does is different. Don't
expect people on this list to download your code and run it.

Also please put your code in the email and not in an attachment and
please reply back to the tutor list rather than directly to me.


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Integrating TDD into my current project work-flows

2015-05-05 Thread Oscar Benjamin
On 4 May 2015 at 20:04, WolfRage  wrote:
> I would like some help integrating TDD into my current projects.
> My chosen TDD framework is unittest from the standard library.
> My system details are: Linux Mint 17.1 64-bit, Python 3.4, bzr(for version
> control).
>
> My projects are structured like:
> Project > develop > Project > Project > __main__.py
>   tests   > __main__.py
> I want to be able to execute my Project from a cwd of:
> Project/develop/Project
> as: Python3 -m Project
> That currently works.

That will only work if there is also a file __init__.py under the
Project/develop/Project/Project directory (alongside the __main__.py
file). Adding a __main__.py file allows the directory to be treated as
a Python script e.g.:

$ python3 Project/develop/Project/Project
$ python3 Project  # Assuming cwd is Project/develop/Project

The -m switch searches for a script as if it were a module using the
module search path. In this case the directory containing the package
Project must be on sys.path and one way to achieve this is to change
directory to the Project/develop/Project directory. Then the Project
folder in this directory is on sys.path.

However a directory is not considered a package unless it contains a
file __init__.py. So if the directory is on sys.path (e.g. in the cwd)
AND their is an __init__.py file then you can do

$ python3 -m Project

and the code in __main__.py will run.

Assuming you have the same setup in the
Project/develop/Project/Project/tests directory (both __init__.py and
__main__.py and Project is on sys.path) then you can run
tests/__main__.py using the module search path as

$ python3 -m Project.tests

Note that this is the same name that you would use to import from the
tests package in interpreter e.g.

>>> from Project.tests import test_stuff

imports from the __init__.py in the tests folder.

> But executing my tests as: Python3 -m tests
> requires that test_Project.py has this hack to import the Project module:
> sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
> do you consider that OK? Is there a better way?
> I call it a hack because every testcase file will have to have this line
> added to it in order to work.

I'm not 100% sure I understand what you're doing but hopefully what
I've written above leads to a better solution.

> I am also using coverage.py and it is good but seems to be testing the
> coverage of my tests, which is not desired, how can I stop this behaviour.
> Or is it really OK.

I don't see any problem with it since it shows how many of your tests
are being run. If you're not running all of your tests then that's a
problem. I don't know how involved your projects are but often large
projects will have tests that run conditionally for example they
only/don't run on certain platforms. In that case it could be useful
each time you run your tests to get a loose idea of how many tests are
being skipped.

Of course it may just be a distraction from the main goal which is
ensuring good coverage of the exported code. You can control which
files coverage tracks and reports the coverage of. I don't know how to
do it the way that you're running coverage (from within Python code).
I've always run coverage from the command line interface using a
configuration file. See here for more on that:

http://nedbatchelder.com/code/coverage/cmd.html#cmd
http://nedbatchelder.com/code/coverage/config.html#config
http://nedbatchelder.com/code/coverage/source.html#source


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reading lines from a list of files

2015-05-12 Thread Oscar Benjamin
On 12 May 2015 at 11:46, Peter Otten <__pete...@web.de> wrote:
>
> > although the reason
> > for my inquiry was more to diminish levels of indentation
> > than number of lines.
>
> You usually do that by factoring out the loops into a generator:
>
> def lines(files):
> for file in files:
> with open(files) as f:
> yield from f  # before python 3.3: for line in f: yield line
>
>
> for line in lines(files):
> ...
>
>
> Also possible, but sloppy as files are closed on garbage collection rather
> than explicitly:
>
> lines = (line for file in files for line in open(file))
> for line in lines:
>...

The lines generator function above relies on __del__ as well if the
loop exits from break, return or an exception in the loop body. This
happens whenever you yield or yield-from from inside a with block. The
chain of events that calls your context manager if I break from the
loop is:

1) Once the for loop discards the generator it has a zero reference count.
2) generator.__del__() called.
3) __del__() calls close()
4) close() throws GeneratorExit into the generator frame.
5) The GeneratorExit triggers the __exit__() methods of any context
managers active in the generator frame.

Try the following:

$ cat test_gen_cm.py
#!/usr/bin/env python3

class cleanup():
def __enter__(self):
pass
def __exit__(self, *args):
print("__exit__ called")__del__.

def generator_with_cm():
with cleanup():
yield 1
yield 2
yield 3

g = generator_with_cm()
for x in g:
break

print('Deleting g')
del g
print('g is now deleted')

$ ./test_gen_cm.py
Deleting g
__exit__ called
g is now deleted

A generator cannot guarantee that execution continues after a yield so
any context manager used around a yield is dependent on __del__. I
think a good rule of thumb is "don't yield from a with block".

Alex I apologise if what I've written here is confusing but really
what you started with is just fine. It is not important to fully
understand what I wrote above.


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reading lines from a list of files

2015-05-13 Thread Oscar Benjamin
On 12 May 2015 at 19:08, Peter Otten <__pete...@web.de> wrote:
>>
>> A generator cannot guarantee that execution continues after a yield so
>> any context manager used around a yield is dependent on __del__. I
>> think a good rule of thumb is "don't yield from a with block".
>
> Uh-oh, I am afraid I did this quite a few times. Most instances seem to be
> context managers though. Is something like
>
> @contextmanager
> def my_open(filename):
> if filename == "-":
> yield sys.stdin
> else:
> with open(filename) as f:
> yield f
>
>
> OK?

Yeah that's fine. A generator cannot guarantee that execution
continues after a yield since the controller of the generator decides
that. In this case the only controller that has access to your
generator is the contextmanager decorator which guarantees to do
next(gen) or gen.throw().

You can see the code for that here:
https://hg.python.org/cpython/file/4b5461dcd190/Lib/contextlib.py#l63


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Yielding from a with block

2015-05-27 Thread Oscar Benjamin
On 23 May 2015 at 10:52, Peter Otten <__pete...@web.de> wrote:
> import csv
>
>

I'm just wondering what other people think about this. Should code
like make_lines below be discouraged?

> def make_lines():
> with open('co2-sample.csv') as co2:
> yield htbegin
> for linelist in csv.reader(co2):
> yield from fprint(linelist)
> yield htend
>
>
> def fprint(linelist):
> yield ("{}{}{}"
>"{}{}{}\n").format(*linelist)
> yield '\n'

There's a fundamental contradiction between the with and yield
statements. With means "don't exit this block without running my
finalisation routine". Yield means "immediately exit this block
without doing anything (including any finalisation routines) and then
allow anything else to occur".

Using yield inside a with statement like this renders the with
statement pointless: either way we're really depending on __del__ to
execute the finalisation code. So it with or without the with
statement it will work fine on CPython. On other implementations it
may or may not close the file with or without the with statement. IOW
the with statement is not able to provide the guarantees normally
expected of it when used this way.

It's usually fairly trivial to rearrange things so that this doesn't happen:

def wrap_header_footer(fin):
yield htbegin
for linelist in csv.reader(fin):
yield from fprint(linelist)
yield htend


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Yielding from a with block

2015-05-28 Thread Oscar Benjamin
On 28 May 2015 at 03:12, Steven D'Aprano  wrote:
> On Wed, May 27, 2015 at 11:27:46PM +0100, Oscar Benjamin wrote:
>
>> I'm just wondering what other people think about this. Should code
>> like make_lines below be discouraged?
>>
>> > def make_lines():
>> > with open('co2-sample.csv') as co2:
>> > yield htbegin
>> > for linelist in csv.reader(co2):
>> > yield from fprint(linelist)
>> > yield htend
> [...]
>> There's a fundamental contradiction between the with and yield
>> statements. With means "don't exit this block without running my
>> finalisation routine". Yield means "immediately exit this block
>> without doing anything (including any finalisation routines) and then
>> allow anything else to occur".
>
> No, I think you have misunderstood the situation, and perhaps been
> fooled by two different usages of the English word "exit".
>
>
> Let me put it this way:
>
> with open(somefile) as f:
> text = f.write()  # here
> ...
>
> In the line marked "here", execution exits the current routine and
> passes to the write method. Or perhaps it is better to say that
> execution of the current routine pauses, because once the write method
> has finished, execution will return to the current routine, or continue,
> however you want to put it. Either way, there is a sense in which
> execution has left the with-block and is running elsewhere.
>
> I trust that you wouldn't argue that one should avoid calling functions
> or methods inside a with-block?
>
> In this case, there is another sense in which we have not left the
> with-block, just paused it, and in a sense the call to write() occurs
> "inside" the current routine. Nevertheless, at the assembly language
> level, the interpreter has to remember where it is, and jump to the
> write() routine, which is outside of the current routine.
>
> Now let us continue the block:
>
> with open(somefile) as f:
> text = f.write()
> yield text  # here
>
>
> Just like the case of transferring execution to the write() method, the
> yield pauses the currently executing code (a coroutine), and transfers
> execution to something else. That something else is the caller. So in
> once sense, we have exited the current block, but in another sense we've
> just paused it, waiting to resume, no different from the case of
> transferring execution to the write() method.
>
> In this case, the with block is not deemed to have been exited until
> execution *within the coroutine* leaves the with-block. Temporarily
> pausing it by yielding leaves the coroutine alive (although in a paused
> state), so we haven't really exited the with-block.

I'm sure you understand the fundamental difference between calling a
function and yielding inside a with statement: when calling a function
the new frame is *appended* to the call stack keeping the current
frame and all of its exception traps and context managers in place
ready for unwinding. When yielding the current frame is *removed* from
the call stack (along with its exception traps and context managers).

When a with block is used without a yield it is not possible (barring
unrecoverable failure of the runtime itself) to leave the block
without calling its finaliser. It doesn't matter if we call a function
that in turn calls a generator. As long as there is no yield inside
the with block in the current frame then the finalisation guarantee is
maintained. When using yield we don't have this guarantee and in fact
there are common non-exceptional cases (break/return) where the
undesirable occurs.

>> Using yield inside a with statement like this renders the with
>> statement pointless: either way we're really depending on __del__ to
>> execute the finalisation code.
>
> No, that's not correct. __del__ may not enter into it. When you run the
> generator to completion, or possibly even earlier, the with-statement
> exits and the file is closed before __del__ gets a chance to run.
[snip]

Obviously there is this case in which the with achieves its purpose
but I mean this in a more general context than the specific example. I
consider that it is generally best to avoid doing this. In the same
way that I would advise someone to always use with when working with
files (even though it often doesn't matter) I would advise someone
generally not to yield from a with statement.


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Yielding from a with block

2015-05-28 Thread Oscar Benjamin
On 28 May 2015 at 09:16, Peter Otten <__pete...@web.de> wrote:
> ...but the obvious route is of course
>
>> It's usually fairly trivial to rearrange things so that this doesn't
>> happen:
>>
>> def wrap_header_footer(fin):
>> yield htbegin
>> for linelist in csv.reader(fin):
>> yield from fprint(linelist)
>> yield htend
>
> which in this case also has the advantage of better separation of concerns
> (I'd probably move the csv.reader() out of the generator, too).

Agreed. In practise you would at least want to be able to pass the
filename in and then it's almost always better to be able to pass in a
file object.

> PS: I'm still looking for a fairly elegant rewrite of the problematic
>
> def lines(files):
> for file in files:
> with open(files) as f:
> yield from f

This was mentioned in the previous thread but a fileinput.input object
can be used as a contextmanager so:

import fileinput

filenames = 'f.py', 'wrap.py'

with fileinput.input(filenames) as joined:
for line in joined:
print(line, end='')

The behaviour of fileinput in the corner case of an empty file list
(reading from stdin) is annoying in this usage though.

You can also just wrap your lines generator in a context manager:

from contextlib import contextmanager

@contextmanager
def catfiles(filenames):
def lines():
for filename in filenames:
with open(filename) as fin:
yield from fin
gen = lines()
try:
yield gen
finally:
gen.close()

filenames = 'f.py', 'wrap.py'

with catfiles(filenames) as joined:
for line in joined:
print(line.upper(), end='')


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question About Image Processing in Python

2015-05-28 Thread Oscar Benjamin
On 28 May 2015 at 11:34, Serge Christian Ibala
 wrote:
> Hello All,
>
> I want to know which version of Python is compatible (or can be associated
> with which version of which "tools or package" for image processing)
>
> I am working under Window and it is so complicated to find out which version
> of which tool goes with which other version?
>
> I want to use the following package
>
> “numpy, matplotib, mahotas, ipython   OpenCV and SciPy"

I would just install the most recent released versions unless I saw
some information that suggested a problem with that.

You may want to consider installing something like the Anaconda Python
distribution which includes most of these packages (all except
mahotas) with a single installer:
http://docs.continuum.io/anaconda/install.html

You can see the list of packages included here:
http://docs.continuum.io/anaconda/pkg-docs.html

It will also install the mingw compiler that you could use to install
mahotas using pip/conda.


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Yielding from a with block

2015-05-29 Thread Oscar Benjamin
On 29 May 2015 at 13:38, Steven D'Aprano  wrote:
>
> Otherwise I stand by my earlier position that you are misinterpreting
> what it means to exit a with block. Pausing it to yield is not an exit.
>
> I did an experiment, where I tried to break the finalisation
> guarantee using break, return and raise:
>
> class CM:
> def __enter__(self):
> return self
> def __exit__(self, *args):
> print("exiting")
>
> def test(n):
> for i in range(1):
> with CM():
> if n == "break": break
> if n == "return": return
> if n == "raise": raise RuntimeError
> yield 1
>
>
>
> Falling out the bottom of the generator finalises correctly. So do
> break, return and raise.
>
> it = test("")
> x = next(it)
> next(it, None)  # prints "exiting"
>
> it = test("break")
> next(it, None)  # prints "exiting"
>
> it = test("return")
> next(it, None)  # prints "exiting"
>
> it = test("raise")
> try: next(it)
> except: pass  # prints "exiting"
>
> Under what circumstances can execution leave the with block without the
> finalisation method __exit__ running?

The break/return should take place in the loop that controls the generator e.g.:

$ cat gencm.py

class CM:
def __enter__(self):
print("Entering")
return self
def __exit__(self, *args):
print("Exiting")

def generator():
with CM():
yield 1
yield 2
yield 3

g = generator()

def f():
for x in g:
break  # Or return

f()

print("End of program")

$ python3 gencm.py
Entering
End of program
Exiting

The context manager was triggered by the end of the program. CPython
tries to call all the __del__ methods for all live objects at process
exit. Now run the same under pypy:

$ pypy --version
Python 2.7.2 (1.8+dfsg-2, Feb 19 2012, 19:18:08)
[PyPy 1.8.0 with GCC 4.6.2]

$ pypy gencm.py
Entering
End of program

The __exit__ method was not called at all under pypy. Even if I don't
keep a reference to g outside of f the __exit__ method is not called
under this version of pypy (I don't have another to test with).


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Yielding from a with block

2015-05-29 Thread Oscar Benjamin
On 29 May 2015 at 14:29, Steven D'Aprano  wrote:
> On Thu, May 28, 2015 at 10:16:00AM +0200, Peter Otten wrote:
>
>> Even if you limit yourself to CPython there is another effect: the order of
>> execution may not meet one's expectations/requirements:
>
> [snip example]
>
> That's an interesting example, and I can't tell if that's a
> problem with your (and my) expectations, or a bug in the context
> manager implementation.

I think that this behaviour is consistent with the generally
unspecified language-level behaviour of deallocation and __del__.
Consider the language specification for this version of Python (and
note the last sentence in particular):

"""
object.__del__(self)

Called when the instance is about to be destroyed. This is also called
a destructor. If a base class has a __del__() method, the derived
class’s __del__() method, if any, must explicitly call it to ensure
proper deletion of the base class part of the instance. Note that it
is possible (though not recommended!) for the __del__() method to
postpone destruction of the instance by creating a new reference to
it. It may then be called at a later time when this new reference is
deleted. It is not guaranteed that __del__() methods are called for
objects that still exist when the interpreter exits.
"""
https://docs.python.org/2/reference/datamodel.html#object.__del__

> PEP 343 clearly warns that the finally clause may not run immediately:
>
> Note that we're not guaranteeing that the finally-clause is
> executed immediately after the generator object becomes unused
>
> https://www.python.org/dev/peps/pep-0343/
>

The rest of that sentence says "..., even though this is how it will
work in CPython." To me that clearly and deliberately permits other
implementations to behave differently.

> but the documentation for the with-statement suggests strongly that the
> __exit__ method will run immediately after the block is exited, before
> any additional code (including before any exception is raised. E.g.:
>
> 5. The suite is executed.
>
> 6. The context manager’s __exit__() method is invoked. If an
>exception caused the suite to be exited, its type, value, and
>traceback are passed as arguments to __exit__(). Otherwise,
>three None arguments are supplied.
>
> https://docs.python.org/2/reference/compound_stmts.html#the-with-statement

But the with statement is not "exited" as the suite is unfinished. The
generator has suspended itself and removed itself from the call-stack
so that it is no longer permitted to catch exceptions etc. Also note
that the removal from the call stack is not an implementation detail.
The interpreter can implement the call stack how it likes but it must
be semantically equivalent to a call stack with exception unwinding in
order to meet the general definition of the language.

>> PS: I'm still looking for a fairly elegant rewrite of the problematic
>>
>> def lines(files):
>> for file in files:
>> with open(files) as f:
>> yield from f
>>
>> (see Oscar's comment in
>> )
>
> Oscar's comment includes a syntax error, which makes it hard to run his
> code:
>
> print("__exit__ called")__del__.
>
> I can't even begin to guess what that is supposed to be, and reading the
> next few messages in the thread doesn't enlighten.

Some kind of editing error. It should be:

 print("__exit__ called")


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Problem in packages

2015-07-01 Thread Oscar Benjamin
On 1 July 2015 at 07:11, megha garg  wrote:
> Python version 2.7.10.
> I have problem in installing .whl format packages.
> what version of setuptools is required for .whl format packages.
> I have installed Setuptools version 0.6.0 and upgraded pip to 7.0.3.
> wndows 7 powershell 1.
> I tried installing setuptools 18.0 but it is also in .whl format.
> and installing wheel requires greater than 0.8 versions.
> so how can i install setuptools and wheel to install .whl format packages.
> please reply as soon as possible.
> thanks

If you have pip can you run pip from the command line? If so you
should be able to update setuptools with:

pip install -U setuptools

It's hard to provide better help without more information:

What operating system are you using (Windows?).

How did you install Python or which Python distribution did you
install? (Can you a post a link to where you got it from?)

Did you install for all users or just you?

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Are the methods in a class copied or just linked to?

2015-07-03 Thread Oscar Benjamin
On 3 July 2015 at 02:17, Steven D'Aprano  wrote:
> On Thu, Jul 02, 2015 at 12:30:23PM -0700, Jim Mooney Py3.4.3winXP wrote:
>
>> When an instance uses a class method, does it actually use the method that
>> is in the class object's memory space, or is the method copied to the
>> instance?
>
> The first. And it is not just an implementation detail, it is part of
> Python's programming model.
>
> When you define a class in you define methods and other attributes in
> the class namespace:
>
> class C:
> attr = 23
> def method(self, arg):
> pass
>
[snip]
>
> When you call a method, c.method(), Python does a name look-up.
> Simplified, it looks in c.__dict__, then C.__dict__, then the __dict__s
> of each of C's parents (if any).

To expand on this slightly. The expression c.method() is calculated as
(c.method)(). So the expression c.method must be evaulated first. To
evaluate this the name lookup occurs and a bound method object is
created. The bound method object wraps together the instance with the
method that was found during lookup. Having evaluated the expression
c.method the resulting bound method is then called to complete the
evaluation of the expression c.method(). Subsequently replacing the
method in the class does not affect the bound method since the lookup
has already occurred:

>>> class A:
... def foo(self):
... print('Original foo')
...
>>> a = A()
>>> afoo = a.foo
>>> A.foo = lambda self: print('New foo')
>>> afoo
>
>>> afoo()
Original foo
>>> a.foo()
New foo

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Inheritance, superclass, ‘super’

2015-07-03 Thread Oscar Benjamin
On 3 July 2015 at 00:47, Ben Finney  wrote:
>> That depends on what you mean by break it., MI should allow the
>> inheriting class to specify which, if any, of its direct superclasses
>> methods are invoked.
>
> That “should” is contrary to Python's collaborative multiple inheritance
> model. Instead, multiple inheritance in Python entails that any class
> should allow the methods of the same name, in all superclasses of this
> one, to execute in the sequence determined by ‘super’.
>
> So, if you want behaviour as you describe there, you want something that
> Python's mutliple inheritance explicitly won't give you.

I guess you mean something that it won't *implicitly* give you. Python
makes it possible to construct whatever method dispatch system you
like in MI but super is designed with the implicit intention that you
would use this particular convention that the same method is called in
all superclasses.

The particular model of multiple inheritance for which super is
designed requires the classes involved to have been designed for that
use case. Simply using super instead of explicitly invoking the
expected superclass does not make a class suitable for this or any
other MI method-calling convention. It is a necessary but not
sufficient condition to make it suitable for the convention you
describe.

You seem to be advocating that "everyone should always use super()
because everyone should always assume that someone else will want to
use their class in a particular style of multiple inheritance setup."
I would rather say that "no one should ever use classes in multiple
inheritance unless the classes involved were designed for that usage
together." (The everyone/always etc. are meant loosely.)

I guess a different point is that it's not really harmful to just use
super() so you may as well "just do it" without giving it much
thought. This argument makes more sense in Python 3 than Python 2
though since 2's super is a little tricky to get right in some cases
(e.g. __new__).

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Pytest help

2015-07-07 Thread Oscar Benjamin
On Tue, 7 Jul 2015 at 09:51 Sahil Chauhan  wrote:

> Hi,
>
> I am trying to use py.test for writing some selenium webdriver tests. I
> wrote my first test and
> pytest is deselecting that test even though I didn't mark any test.
>
> How can I resolve this issue?  Is there some default setting used by
> py.test,
>
>
I don't know as that's never happened to me and you haven't shown any code
for me to check. Try breaking your problem down to a small example
module+test that still exhibits the same behaviour. You may find that you
solve the problem in the process. If not then post the small example code
here so that someone else can see what the problem is.

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Shading Between Curves with Different Colour Over Specified X value Range

2015-07-28 Thread Oscar Benjamin
On Mon, 27 Jul 2015 at 20:53 Colin Ross  wrote:

> *Goal:* Shade between I_2 (curve 1) and I_3 (curve 2) with following
> conditions:
>   - Green for 0 < x < 4
>   - Red for 4 < x < 12
>
> *Code: *
>
> *Note: Code currently only attempting to shade green for 0 < x < 4 *
>
> import numpy as np
> import pylab
> from pylab import *
> import matplotlib.pyplot as plt
> import csv
>
>
> # Load data from .txt file
>
> with open('current_mirror_output_swing.csv', 'rb') as f:
>reader = csv.reader(f)
>your_list = list(reader)
>
> data = np.asarray(your_list)
>
> I_ref = np.asarray(data[1:,0])
> I_1 = data[1:,1]
> I_2 = data[1:,2]
> I_3 = data[1:,3]
>
> # Create an array of x values to fill b/w curves with a certain color.
>
>
Here you specify the X values for the fill shape as going from 0 to 4:


> X1 = np.linspace(0.,4.,len(I_3))
>
> I_ref = I_ref.astype(float)*1000.
> I_1 = I_1.astype(float)*1000.
> I_2 = I_2.astype(float)*1000.
> I_3 = I_3.astype(float)*1000.
>
>
> # Plotting commands.
>
>
Here you specify the X values for the line plots as being whatever I_ref is
(I don't know what it is since I can't see your csv file):


> plot(I_ref, I_2, 'r-')
> plot(I_ref, I_3, 'b-')
> title('Current Mirror Output Swing')
> xlabel('$I_{ref}$ (mA)')
> ylabel('I (mA)')
>
>
Try changing this line:


> plt.fill_between(X1, I_2, I_3, color = 'g', alpha = '0.5')
>

to:

plt.fill_between(I_ref, I_2, I_3, color = 'g', alpha = '0.5')

and then the filled area should have the same X range as the lines.

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text

2015-08-02 Thread Oscar Benjamin
On 1 Aug 2015 16:28, "boB Stepp"  wrote:
>
> I apologize for the noise, but I felt it better to get this question
answered definitively prior to posting questions from my iPad.
>
> I am on a brief vacation and only brought my iPad.  I have been having a
devil of a time searching the Internet for an iPad app that will truly send
and display in plain text emails.  If someone would tell me if I have been
successful or not, I would be very appreciative!  If successful, Python
questions will soon follow.
>

Have you tried using the Gmail app?

I'm using the Gmail app here on my phone. I've just looked at your message,
hit reply-all and then "respond inline". Then I can see/edit the
attribution line and your message. I've not had complaints with using the
list this way (perhaps I'm inviting them now though!)
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] find pickle and retrieve saved data

2015-08-05 Thread Oscar Benjamin
On 4 August 2015 at 23:09, Quiles, Stephanie
 wrote:
> I am still struggling with this one.

Hi Stephanie, Alan has already raised a few issues with your code so
I'm just going to address the one that's showing in your error
message.

These two lines are generating the error message:

> infile = open("emails.dat", "r")
> name = infile.readline()
>
> This is the error i am getting:
>
> enter a name in the file for info: sarah
> Traceback (most recent call last):
>   File "/Users/stephaniequiles/Downloads/findemails.py", line 28, in 
> main()
>   File "/Users/stephaniequiles/Downloads/findemails.py", line 9, in main
> name = infile.readline()
>   File 
> "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/codecs.py", 
> line 319, in decode
> (result, consumed) = self._buffer_decode(data, self.errors, final)
> UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: 
> invalid start byte

The interpreter is assuming that your file 'emails.dat' is a text file
using the utf-8 encoding. This is because you didn't specify an
encoding when opening the file. To specify that the encoding is e.g.
ascii you would do:

infile = open('emails.dat', 'r', encoding='ascii')

The error occurs because the bytes read from the file are not valid
for utf-8. What program did you use to write the emails.dat file? Does
it look reasonable when you open it in a text editor e.g. your code
editor or notepad?

If you show the output of the following command then someone may be
able to guess the encoding that you should be using for this file:

infile = open('emails.dat', 'rb')  # b for binary mode
print(repr(infile.read(100)))

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Creating lists with definite (n) items without repetitions

2015-09-07 Thread Oscar Benjamin
On 5 September 2015 at 23:28, Mark Lawrence  wrote:
> On 05/09/2015 10:09, Peter Otten wrote:
>>
>>> the 5 lists above do not match my task insofar as every of the 5 lists
>>> contains  'a' and 'b' which should occur only once, hence my count of a
>>> maximum of 301 lists, which might nor be correct 100%. My be one could
>>> put
>>> it in Python as follows:

 ('a', 'b', 'c') = True
 ('a', 'b', 'd')= False
 ('a', 'b', 'e')= False
 ('a', 'b', 'f')= False
 ('a', 'b', 'g')= False
>
> So for completeness it follows that:-
>
> ('a', 'c', 'd') == False
> ('b', 'c', 'd') == False
>
> yes?

I think so.

>>> I should probably tell you the real task are a series (maximum ~ 301)
>>> lists in which real names  of people are assigned to the items/letters
>>> for
>>> 2 people(golfers) can be in  the same list(flight)  only once for an
>>> extended period of time.
>>
>
>> It's probably a good idea to ask your question in a mathematics forum --
>> this problem looks common enough to have a name and some brain power spent
>> on it.
>>
>
> To me this is clearly an example of a Steiner Triple system
> associated with Balanced Incomplete Block Design.  Which means I found this
> http://mathforum.org/library/drmath/view/52263.html which got me to
> https://en.wikipedia.org/wiki/Steiner_system and also
> http://oeis.org/A137348/a137348.txt.  Just one minor little question, am I
> actually correct?

It sounds like the social golfer problem (or Kirkman's schoolgirl
problem, both of which Steiner systems):
http://mathworld.wolfram.com/SocialGolferProblem.html

The problem is that there are 26 people and they are divided into
groups of 3 each day. We would like to know if it is possible to
arrange it so that each player plays each other player exactly once
over some period of days.

It is not exactly possible to do this with 26 people in groups of 3.
Think about it from the perspective of 1 person. They must play
against all 25 other people in pairs with neither of the other people
repeated: the set of pairs they play against must partition the set of
other players. Clearly it can only work if the number of other players
is even.

I'm not sure but I think that maybe for an exact solution you need to
have n=1(mod6) or n=3(mod6) which gives:
n = 1, 3, 7, 9, 13, 15, 19, 21, 25, 27, ...

The formula for the number of triples if the exact solution exists is
n*(n-1)/6 which comes out as 26*25/6 = 108.3 (the formula doesn't
give an integer because the exact solution doesn't exist).

The question is what do you want to do with the leftovers if it's not
possible for every player to play exactly once? Also what do you want
with these triples? Are you just trying to count them?

Are you interested to know which triples come out? It's not unique and
the number of possible sets of triples is massive.

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Creating lists with definite (n) items without repetitions

2015-09-09 Thread Oscar Benjamin
On 9 September 2015 at 12:05, Francesco Loffredo via Tutor
 wrote:
> Oscar Benjamin wrote:
>
> The problem is that there are 26 people and they are divided into
> groups of 3 each day. We would like to know if it is possible to
> arrange it so that each player plays each other player exactly once
> over some period of days.
>
> It is not exactly possible to do this with 26 people in groups of 3.
> Think about it from the perspective of 1 person. They must play
> against all 25 other people in pairs with neither of the other people
> repeated: the set of pairs they play against must partition the set of
> other players. Clearly it can only work if the number of other players
> is even.
>
> I'm not sure but I think that maybe for an exact solution you need to
> have n=1(mod6) or n=3(mod6) which gives:
> n = 1, 3, 7, 9, 13, 15, 19, 21, 25, 27, ...
>
> The formula for the number of triples if the exact solution exists is
> n*(n-1)/6 which comes out as 26*25/6 = 108.3 (the formula doesn't
> give an integer because the exact solution doesn't exist).
> 
>
> A quick solution is to add one "dummy" letter to the pool of the OP's
> golfers.
> I used "!" as the dummy one. This way, you end up with 101 triples, 11 of
> which contain the dummy player.
> But this is better than the 25-item pool, that resulted in an incomplete set
> of triples (for example, A would never play with Z)
> So, in your real-world problem, you will have 11 groups of 2 people instead
> of 3. Is this a problem?
>
>
> import pprint, itertools
> pool = "abcdefghijklmnopqrstuvwxyz!"
>
> def maketriples(tuplelist):
> final = []
> used = set()
> for a, b, c in tuplelist:
> if ( ((a,b) in used) or ((b,c) in used) or ((a,c) in used) or ((b,a)
> in used) or ((c,b) in used) or ((c,a) in used) ):
> continue
> else:
> final.append((a, b, c))
> used.add((a,b))
> used.add((a,c))
> used.add((b,c))
> used.add((b,a))
> used.add((c,a))
> used.add((c,b))
> return final
>
> combos = list(itertools.combinations(pool, 3))
> print("combos contains %s triples." % len(combos))
>
> triples = maketriples(combos)
>
> print("maketriples(combos) contains %s triples." % len(triples))
> pprint.pprint(triples)

I don't think the code above works. For n=27 it should count 117
(according to the formula I showed) but instead it comes up with 101.

I tried it with a smaller n by setting pool to range(1, 9+1) meaning
that n=9. The output is:

combos contains 84 triples.
maketriples(combos) contains 8 triples.
[(1, 2, 3),
 (1, 4, 5),
 (1, 6, 7),
 (1, 8, 9),
 (2, 4, 6),
 (2, 5, 7),
 (3, 4, 7),
 (3, 5, 6)]

However I can construct a set of 12 triples containing each number
exactly 4 times which is the exact Steiner triple system:

1 6 8
1 2 3
1 5 9
1 4 7
2 6 7
2 4 9
2 5 8
3 5 7
3 6 9
3 8 4
4 5 6
7 8 9

This is the number of triples predicted by the formula: 9*(9-1)/6 = 12

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Creating lists with definite (n) items without repetitions

2015-09-14 Thread Oscar Benjamin
On 10 September 2015 at 08:45, Francesco Loffredo via Tutor
 wrote:
>
> I wrote a small routine (below) to check when and if my code and the formula
> do match. It easily shows that
> they only match for len(pool) == (2 ** N) - 1, with N greater or equal to 2.

That's interesting. I'm not sure exactly why that would happen.

> My problem remains: WHY don't they match for every length?

Your algorithm is not generally guaranteed to find a full solution.

> How did you build your 12-triples set?

I took it from this diagram:
https://upload.wikimedia.org/wikipedia/commons/e/eb/Hesse_configuration.svg

> What's wrong with my algorithm? And, most of all (and on topic, too): how can 
> you build a Python program that builds your triples list?

Perhaps if we compare this problem to a different problem then we can
see how your algorithm may not be optimal. Imagine solving a sudoku
puzzle.

Your algorithm loops through all triples and accepts any triple if it
doesn't immediately conflict with any of the triples already accepted.
If you were solving a sudoku puzzle then an analogous algorithm would
take each empty square and fill it with any number that doesn't
contradict any of the currently filled squares. If you try this on a
real puzzle then you will reach a dead end and you won't fill the
grid. The problem is that some of the squares you filled in could have
had a number of possible values and you've just chosen them
arbitrarily (and incorrectly).

The solution for a sudoku solving algorithm would be to back-track.
One of the previously filled squares was filled incorrectly so go back
and change what you had before. As a recursive algorithm you would
take an unfilled square, loop over the possible values that it can
take and for each of those values attempt to fill the remainder of the
sudoko grid.

The analogous backtracking algorithm for this problem would mean
deciding first to include a particular triple if it is compatible with
the already accepted triples and then continuing with the remaining
triples to see if it leads to a full set (you know how big a full set
should be). If it does not lead to a full set then you were wrong to
include one of your current triples so now decide not to include it
and again loop through the remaining triples looking for a full set.

I imagine that the complexity of this algorithm will grow rapidly as N
increases. For N=9 you have thousands of triples, so the powerset of
this has 2**N members meaning that this binary backtracking algorithm
has a very large space to explore. The space is heavily pruned by the
pairing constraint though so it may not work out as badly as I expect.

Also there will be many possible solutions and you only really need to
find one. Up to isomorphism there is 1 solution for N=9 but that means
there will be 9! isomorphic solutions (the number of ways of
relabelling the numbers 1 through 9). This means that you may not have
to go far in the search before coming across a solution.

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Creating lists with definite (n) items without repetitions

2015-09-22 Thread Oscar Benjamin
On 21 September 2015 at 22:54, Francesco A. Loffredo  wrote:
>>
> Still thinking about it. I have read about Steiner systems and the Social
> Golfer problem, and I'm afraid this will remain an Unsolved Problem despite
> my efforts. Up to now, I thought that backtracking can't be a solution,
> unless I can rethink my algorithm as a tree traversal.
> Problem is, when you arrive at the end of the combos list and you discover
> you hit a dead end, how can you choose which triple you should change?

I would remove the last one added and then loop over all triples
starting from the one after that. I have written a simple
implementation below. The problem is that it's really slow for
anything more than N=9. There are many ways it can be improved though
if you want it to scale to higher levels:

#!/usr/bin/env python

from itertools import permutations, combinations
import pprint, itertools

def get_triples(labels):
Nlabels = len(labels)
if Nlabels % 6 not in (1, 3):
raise ValueError("No exact solution")

target = (Nlabels * (Nlabels - 1)) // 6

all_triples = list(combinations(labels, 3))
Ntriples = len(all_triples)

triples = []
pairs = set()

start_index = 0
while True:
for index in range(start_index, Ntriples):
triple = all_triples[index]

# If the triple fits try it out and see what happens...
if not any(p in pairs for p in combinations(triple, 2)):
triples.append((triple, index))
pairs.update(permutations(triple, 2))

# Success!
if len(triples) == target:
return [triple for triple, _ in triples]
else:
# We tried every combination of the current triples
# and all subsequently available triples. Time to
# pop off the triple at the top and look for another
# one to replace it.
triple, start_index = triples.pop()
pairs.difference_update(permutations(triple, 2))
# Start from the triple after the popped one.
start_index += 1


if __name__ == "__main__":
import sys
Nlabels = int(sys.argv[1])
labels = range(1, Nlabels + 1)
triples = get_triples(labels)
pprint.pprint(triples)


To improve on this I would probably work on it as a constraint
propagation problem rather than looping over all the combinations. The
problem with backtracking on the full set of combinations is that it
grows combinatorially which means it gets complicated very quickly as
N increases. For N=9 this ran in 50ms. At the time of writing I'm
still waiting for it to finish N=13 under pypy (it's only been a
couple of minutes). I don't know if I expect it to finish in a few
seconds or take longer than the age of the universe.


--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] stx, etx (\x02, \x03)

2015-09-22 Thread Oscar Benjamin
On 22 September 2015 at 15:44, richard kappler  wrote:
>>
>>>
>> Reread my original post and you'll see that your "s" isn't set the same
>> way mine was
>
>
> No.  My implementation of your code:
>
> #!/usr/bin/env python
>
> with open('input/PS06Test_100Packages.xml', 'r') as f1:
> with open('mod1.xml', 'a') as f2:
> for line in f1:
> s = '\x02' + line[:-1] + '\x03\n'
> f2.write(s)
>
> gives me:
> line 1 starts with the \x02 hex then the line
> line 2 is the \xo3 hex alone
> line 3 starts with the \x02 hex then the line
> line 4 is the \x03 hex alone

The 4th part is both the \x03 character and the \n newline character
as a single string. Your version doesn't have a newline character at
the end of s:

#!/usr/bin/env python

stx = '\x02'
etx = '\x03'

with open('input/PS06Test_100Packages.xml', 'r') as f1:
with open('mod1.xml', 'a') as f2:
for line in f1:
s = stx + line[:-1] + etx
f2.write(s)

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Creating lists with 3 (later4) items occuring only once

2015-09-28 Thread Oscar Benjamin
On 27 September 2015 at 12:39, marcus lütolf  wrote:
> Hello Martin.
> I never exspected to get such motivating comments and advice !!! Thank you
> again.
> Referring to my statments below
>
> 1. I explain my task in plain text:
> Flights (in golfers language) or Triples (in computer language)  composed of
> 3 golfers  (in golfers language)  or 3 letters (in
>  computer language)  play once a day for n days.
> Each golfer or letter should only once be combined with another, meaning a
> combination of 2 golfers/letters should never
> be>1  for n days.
>
> 2. I considered ['a +b', 'a + c', 'b+c'] == ['a','b','c']
>
> 3. I'am glad that it can be done with all letters. However, with Triples I
> need a number dividable by 3 so the maximum would be
> 24 golfers or letters. I hope to get a program allowing to change the
> varables like number of days played(n) and number of
> golfers/letters, up to a max of 24 according to different situations.
>
> That is why I limited my samples to 9 and 15. 5 and 7 would not work since
> ther are prime numbers.

Ah okay. This is what I thought your problem was but with an
additional constraint. I will spell out the two constraints formally:

You want a set of triples where each triple consists of three distinct
players and:
1) Each player plays each other player exactly once.
2) It is possible to arrange the triples so that every player plays
once on each day.

Constraint 1 means that you need N=1mod6 or N=3mod6. Constraint 2
means that you need N to be a multiple of three so we cannot have
N=1mod6. This means that we must have N=3mod6 or in other words:

N = 3, 9, 15, 21, 27, ...

If I understand correctly you are only interested to know how to find
a solution to constraints 1) and 2) for these values of N. You do not
care what happens for values of N where a perfect solution is
impossible.

> The posting of your sample with 5 letters below is correct. Having discarded
> the subsequences with "already seen's"
> 4 Triples/sequences are left but a variance of the contained letters:
>  'a' occurs 3 times
>  'b' occurs 1 time
>  'c' occurs 3 times
>  'd' occurs 3 times
>   'e' occurs 2 times
>  which of course does not fit my task. That  made me think itertools might
> not be the right tool.
> However, I noticed  variance gets smaller with bigger samples and might turn
> 0 with 24 letters.

So you want every player to play the same number of times? That's
reasonable. Is it also important that every player plays every other
player exactly once (i.e. constraint 1) )?

Unfortunately you will not be able to meet constraint 1) for N=24
since it is an even number.

> But I don't know how to eliminate the "already seen's" by code.
>
> You are absolutely right that one has to write down first exactly his task
> to be accomplished. But my knowledge goes only
> as far as "Python for Infomatics" (by MOOC/Coursera) and "Practical
> Programming" . I know there are a myriad of other
> modules and tools etc. and there I need the help of "Pythonistas".
>  To where should I proceed now ?

I would suggest that you begin working on pen and paper. How can you
construct a solution for N=3, N=9 etc?

An algorithm occurs to me as follows. Consider N=9 so we have golfers ABCDEFGHI.

We know that player A needs to play some games so let's begin there

(A...
...

Player A will at some point need to play both B and C and has not
played them yet so

(ABC)
...

Player A has not played everyone and will need to play players D and E so

(ABC)
(ADE)
...

Continuing we have

(ABC)
(ADE)
(AFG)
(AHI)
...

Now player A has played everyone but player B hasn't so

(ABC)
(ADE)
(AFG)
(AHI)
(B...)
...

Player B has already played both A and C which leaves the
possibilities DEFGHI. At some point player B must play D so let's
assume that's what happens:

(ABC)
(ADE)
(AFG)
(AHI)
(BD...)
...

Who can play with B and D? Well B has played A and C and D has played
A and E. So that leaves FGHI. We now loop through those possibilities
trying each out. This is where the algorithm recurses:

(ABC)
(ADE)
(AFG)
(AHI)
(BDF) - F could be GHI
...

Now B has still not played everyone and at some point B must play G so
let's try that out:

(ABC)
(ADE)
(AFG)
(AHI)
(BDF) - F could be GHI
(BG...)
...

Okay so who can play with B and G. Well B has played ACDF and G has
played AF so we need something that is not ABCDFG which leaves EHI as
possibilities. Let's loop through these trying them out. We'll begin
with E:

(ABC)
(ADE)
(AFG)
(AHI)
(BDF) - F could be GHI
(BGE) - E could be HI
...

Now B still hasn't played everyone and there's only two possibilities
H and I. which gives

(ABC)
(ADE)
(AFG)
(AHI)
(BDF) - F could be GHI
(BGE) - E could be HI
(BHI) <- conflict!!
...

Oh dear H and I have already played each other. Now we need to back
track. Maybe we were wrong to choose E? We'll try H instead:

(ABC)
(ADE)
(AFG)
(AHI)
(BDF) - F could be GHI
(BGH) - H could be I  (E was already rejected on backtrack)
...

Now B h

Re: [Tutor] Regarding installing a python package

2015-09-29 Thread Oscar Benjamin
On Tue, 29 Sep 2015 at 10:47 Chirag Shahani 
wrote:

> Hi,
>
> Could any one please help me understand the following:
>
> Suppose I install a python package using python setup.py install provided
> by the developer of a package. I need to track that changes in my file
> system.. meaning what new directories and files got created? Also, what is
> the concept of the egg file that gets created? What would be the location
> of this egg file and how would it be named .egg? Also, the ***.egg-info
> directory?
>

It really depends. The setup.py script is really just an arbitrary program
that can do anything and can create files in any location it chooses.
Mostly setup.py files have a standard behaviour which is to install files
in the site-packages folder for your Python installation (unless you
provide command line options indicating an alternative location) and to
install executables so that they will be available on PATH.

So usually if I have a project called project_name then it will create a
folder called project_name in the site-packages folder and then fill that
folder with Python files and maybe some other data files. Really though it
could do anything so if you need to know exactly what it's doing then
you'll need to read the setup.py and understand distutils and setuptools.

For example in my system the site-packages folder is called

/usr/lib/python2.7/dist-packages

For some reason Ubuntu calls it dist-packages but in most Python
installations it is called site-packages. If I install ipython by running
its setup.py then I will have an egg-info file called:

/usr/lib/python2.7/dist-packages/ipython-0.12.1.egg-info

and also a folder called

/usr/lib/python2.7/dist-packages/IPython

which contains all of the Python files for ipython. It also installs an
executable file called ipython which is found at

/usr/bin/ipython

The exact details of what files are installed and where they go can vary
depending on what operating system and Python version you are using.

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to calculate the cumulative normal distribution

2015-10-02 Thread Oscar Benjamin
On Wed, 30 Sep 2015 10:14 Laura Creighton  wrote:

In a message of Wed, 30 Sep 2015 09:12:20 +0300, Michel Guirguis writes:
>Good afternoon,
>
>How to calculate the cumulative normal distribution function CND in order
to use this figure to calculate the call option based on the Black and
Scholes model.

The easy way is to install scipy



Michel, It sounds like you probably do want to install scipy for the work
that you're doing  and Laura's correct that anaconda is the easiest way to
do that.

However I want to point out that your specific problem is easily solved
with the stdlib. The CDF of the standard normal distribution is easily
expressed in terms of the error function erf which is available in the math
module:

fron math import erf

def phi(z):
return 0.5 * (1 + erf(z))

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Mutable data type in python

2015-10-06 Thread Oscar Benjamin
On 4 October 2015 at 00:13, Alan Gauld  wrote:
> On 03/10/15 23:20, C Smith wrote:
>>
>> On Sat, Oct 3, 2015 at 11:55 AM, Alan Gauld 
>> wrote:
>>>
>>> On 03/10/15 19:10, C Smith wrote:
>
> Here is my modified version which I think works as you want:
>
> def findMinDepthPath(n):
>   if n <= 0: raise ValueError
>   elif n==1:
>   return 0
>   elif n==2 or n==3:
>   return 1
>   else:
>   d1 = findMinDepthPath(n-1)+1
>   d2 = d3 = (d1+1) # initialize to higher than d1
>
>   if n%3 == 0:
>   d3 = findMinDepthPath(n/3)+1
>   if n%2 == 0:
>   d2 = findMinDepthPath(n/2)+1
>
>   return min(d1,d2,d3)
>>
>> What I meant was that the algorithm assumes that the lowest value from
>> one "action" (minus one, divide by 2, divide by 3) is the best
>> possible branch in the tree. That seems intuitively correct, but is it
>> necessarily so?
>
> I see. The answer is I don't know mathematically speaking.
> But I figured that the minimum path for (n-1|n/2|n/3)  plus 1
> must be the minimum path for n. But that was an entirely
> inuitive assumption.
>
> Also because the minimum path is being figured from the
> bottom to the top - ie it finds the minimum path for 1..3
> first, then for 4 via n/2 then 5 via n-1 and so on. It *feels* like
> that it should always select the minimum path. But I have learnt
> that in math intuitive is not always right :-)
>
> So if anyone can mathematically  prove my hunch right
> or wrong that would be interesting...

Your intuition is fine Alan. Of course it's correct!

Starting from a number n there are three possibilities for the first
step -1, /2, and /3 each of which counts as one action. Each of those
gives a new starting point n1, n2 or n3. Whichever of the ni has the
shortest path will also be the shortest path for n except that for n
you also need to include the action that gets from n to ni increasing
the count by 1.

A side point is that the algorithm is incredibly inefficient because
the 3 way branching will traverse the same routes many times over. It
is analogous to the dumb recursive Fibonacci sequence calculator:

def fib(n):
if n in (0, 1):
return n
else:
return fib(n-1) + fib(n-2)

A typical solution for the inefficiency is to either use a memoisation
decorator or to roll it out into an explicit loop instead of a
recursive call:

def fib(n):
   n1, n2 = 0, 1
   if n in (n1, n2):
return n
else:
for _ in range(1, n):
n1, n2 = n2, n1 + n2
return n2

To do the same for this problem you would have something like:

def shortest_path(n):
paths = [None, 0]
for i in range(2, n+1):
d1 = paths[i-1] + 1
d2 = paths[i // 2] + 1 if i % 2 == 0 else float('inf')
d3 = paths[i // 3] + 1 if i % 3 == 0 else float('inf')
paths.append(min(d1, d2, d3))
return paths[n]

This way the algorithm is O(n) instead of O(3**n). Also if you
actually just want a list of all of the shortest paths you can adjust
this to simply return the full list at no extra cost. OTOH if you want
to be able to call this function repeatedly with random input values a
memoisation decorator may be preferable.

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


  1   2   3   4   >