Re: [Tutor] Generate Prime Numbers

2015-05-30 Thread Alan Gauld

On 30/05/15 00:37, Cameron Simpson wrote:


def IsDivisibleBy3(number):#string variable
   return not int(number) % 3


To illustrate that there isn't just One Right Way, I would code the
above like this:

  def IsDivisibleBy3(number): #string variable
  return int(number) % 3 == 0

Alan's code relies on "not" using an expressions "nonzero"ness as a
boolean value. I _much_ prefer to directly state the test instead of
relying on magic numeric=>boolean effects.


In this case I do too.
Especially since my version using the 'not' as well as
implied Truth value is less clear for a beginner such
as the OP. On reflection the explicit test is clearer.

If the 'not' had not been necessary I'd have been happy
without the == test. But introducing the not can be confusing.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


[Tutor] unittest with random population data

2015-05-30 Thread Sydney Shall

MAC OSX 10.10.3
Enthought Python 2.7

I am an almost beginner.

Following advice from you generous people, I have chosen a project that 
interests me, to develop some knowledge of python.

My projest is a simulation of a biological population.
I have a base class and a simulation function, which uses instances of 
the class.
This, after many months of work and lots of advice, now seems to work 
well. It generates sensible data and when I write a small test program 
it gives sensible output.

Now I want to learn to use unittest.
I have written a unittest class which works OK.
But the problem I have is that because I use the random module to 
populate my initial arrays, my data is not strictly predictable even 
though I am using seed(0). So the tests return many *fails* because the 
numbers are not exactly correct, although they are all rather close, 
consistent with the sigma value I have chosen for the spread of my 
population. I do of course use *almostEqual* and not *Equal*.
So, I would be very grateful for guidance. How does one proceed in this 
case? Should I simply create an arbitrary array or value to input into 
the function that I want to test?

I would be grateful for any guidance.

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


Re: [Tutor] unittest with random population data

2015-05-30 Thread Peter Otten
Sydney Shall wrote:

> MAC OSX 10.10.3
> Enthought Python 2.7
> 
> I am an almost beginner.
> 
> Following advice from you generous people, I have chosen a project that
> interests me, to develop some knowledge of python.
> My projest is a simulation of a biological population.
> I have a base class and a simulation function, which uses instances of
> the class.
> This, after many months of work and lots of advice, now seems to work
> well. It generates sensible data and when I write a small test program
> it gives sensible output.
> Now I want to learn to use unittest.
> I have written a unittest class which works OK.
> But the problem I have is that because I use the random module to
> populate my initial arrays, my data is not strictly predictable even
> though I am using seed(0). So the tests return many *fails* because the
> numbers are not exactly correct, although they are all rather close,
> consistent with the sigma value I have chosen for the spread of my
> population. I do of course use *almostEqual* and not *Equal*.
> So, I would be very grateful for guidance. How does one proceed in this
> case? Should I simply create an arbitrary array or value to input into
> the function that I want to test?
> I would be grateful for any guidance.

With the same input your program should produce exactly the same output.
Are you entering data into dicts? Try to set the

PYTHONHASHSEED 

environment variable to get reproducible results.


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


[Tutor] League Secretary Application

2015-05-30 Thread Stephen Nelson-Smith
Hello,

I'm the league secretary for a table tennis league.  I have to generate a
weekly results report, league table, and player averages, from results
cards which arrive by post or email.

The data is of the form:

Division: 1
Week: 7
Home: Some Team
Away: Different Team
Player A: Fred Bloggs
Player B: Nora Batty
Player X: Jim Smith
Player Y: Edna Jones
A vs X: 3-0
B vs Y: 3-2
A vs Y: 3-0
B vs X: 3-2
Doubles: 3-1

>From this I can calculate the points allocated to teams and produce a table.

I've not done any real python for about 6 years, but figured it'd be fun to
design and write something that would take away the time and error issues
associated with generating this manually.  Sure I could build a
spreadsheet, but this seems more fun.

I'm currently thinking through possible approaches, from parsing results
written in, eg YAML, to a menu-driven system, to a web app.  I'm generally
in favour of the simplest thing that could possibly work, but I am
conscious that there's a lot of room for data entry error and thus
validation, if I just parse a file, or make a CLI.  OTOH I have never ever
written a web app, with forms etc.

There's no time constraint here - this is merely for fun, and to make my
life easier.

Any thoughts?

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


Re: [Tutor] League Secretary Application

2015-05-30 Thread Stephen Nelson-Smith
Hullo,

On Sat, May 30, 2015 at 3:49 PM, Laura Creighton  wrote:

>
> 2.  How do you receive your data now?  Do you want to change this,
> perhaps extend the capabilities -- i.e. let people send an sms
> with results to your cell phone?  Or limit the capabilities ("Stop
> phoning me with this stuff!  Use the webpage!)  How you get your
> data is very relevant to the design.
>

I get a physical card, or a photograph of the same.  It'd be possible in
the future to get people to use a website or a phone app, but for now, I
enter the data from the cards, manually.


> 3.  After you have performed your calculation and made a table, what
> do you do with it?  Email it to members?  Publish it in a
> weekly dead-tree newspaper?  Post it to a website?  What you
> want to do with it once you have it is also very relevant to the
> design.
>

ATM I send an email out, and someone else takes that data and publishes it
on a website.

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


Re: [Tutor] League Secretary Application

2015-05-30 Thread Joel Goldstick
On Sat, May 30, 2015 at 12:08 PM, Stephen Nelson-Smith
 wrote:
> Hullo,
>
> On Sat, May 30, 2015 at 3:49 PM, Laura Creighton  wrote:
>
>>
>> 2.  How do you receive your data now?  Do you want to change this,
>> perhaps extend the capabilities -- i.e. let people send an sms
>> with results to your cell phone?  Or limit the capabilities ("Stop
>> phoning me with this stuff!  Use the webpage!)  How you get your
>> data is very relevant to the design.
>>
>
> I get a physical card, or a photograph of the same.  It'd be possible in
> the future to get people to use a website or a phone app, but for now, I
> enter the data from the cards, manually.
>
>
>> 3.  After you have performed your calculation and made a table, what
>> do you do with it?  Email it to members?  Publish it in a
>> weekly dead-tree newspaper?  Post it to a website?  What you
>> want to do with it once you have it is also very relevant to the
>> design.
>>
>
> ATM I send an email out, and someone else takes that data and publishes it
> on a website.
>
> S.

Take a look at django.  The tutorial takes a couple of hours and gives
you a good feel for whether it would suit you.

You could say its overkill, but it makes it very easy to do CRUD stuff
with validation built in.  Displaying the results would be very easy
as well.  You could have your data providers input the data directly
https://docs.djangoproject.com/en/1.8/intro/tutorial01/


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


Re: [Tutor] unittest with random population data

2015-05-30 Thread Laura Creighton
In a message of Sat, 30 May 2015 12:16:01 +0100, Sydney Shall writes:
>MAC OSX 10.10.3
>Enthought Python 2.7
>
>I am an almost beginner.
>
>Following advice from you generous people, I have chosen a project that 
>interests me, to develop some knowledge of python.
>My projest is a simulation of a biological population.
>I have a base class and a simulation function, which uses instances of 
>the class.
>This, after many months of work and lots of advice, now seems to work 
>well. It generates sensible data and when I write a small test program 
>it gives sensible output.
>Now I want to learn to use unittest.
>I have written a unittest class which works OK.
>But the problem I have is that because I use the random module to 
>populate my initial arrays, my data is not strictly predictable even 
>though I am using seed(0). So the tests return many *fails* because the 
>numbers are not exactly correct, although they are all rather close, 
>consistent with the sigma value I have chosen for the spread of my 
>population. I do of course use *almostEqual* and not *Equal*.
>So, I would be very grateful for guidance. How does one proceed in this 
>case? Should I simply create an arbitrary array or value to input into 
>the function that I want to test?
>I would be grateful for any guidance.
>
>-- 
>Sydney

You can mock your random number generator function to return something
that isn't random for the purposes of testing.  Mock is part of
unittest for Python 3.3 or later, but since you are on 2.7 you will
have to import mock as a separate library.

This nice blog post
http://fgimian.github.io/blog/2014/04/10/using-the-python-mock-library-to-fake-regular-functions-during-tests/

gives a whole slew of examples for how to use mock to mock the
random number generator function os.urandom .  But you can use it to mock
any function you like.

If you have trouble getting it to work, come back with code.  It is tricky
the first time you mock anything, to make sure you put the mock in
the correct place, but once you get the hang of this it is dirt simple.

Happy hacking,
Laura

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


Re: [Tutor] League Secretary Application

2015-05-30 Thread Laura Creighton
In a message of Sat, 30 May 2015 13:32:09 +0100, Stephen Nelson-Smith writes:
>Hello,
>
>I'm the league secretary for a table tennis league.  I have to generate a
>weekly results report, league table, and player averages, from results
>cards which arrive by post or email.
>
>The data is of the form:
>
>Division: 1
>Week: 7
>Home: Some Team
>Away: Different Team
>Player A: Fred Bloggs
>Player B: Nora Batty
>Player X: Jim Smith
>Player Y: Edna Jones
>A vs X: 3-0
>B vs Y: 3-2
>A vs Y: 3-0
>B vs X: 3-2
>Doubles: 3-1
>
>>From this I can calculate the points allocated to teams and produce a table.
>
>I've not done any real python for about 6 years, but figured it'd be fun to
>design and write something that would take away the time and error issues
>associated with generating this manually.  Sure I could build a
>spreadsheet, but this seems more fun.
>
>I'm currently thinking through possible approaches, from parsing results
>written in, eg YAML, to a menu-driven system, to a web app.  I'm generally
>in favour of the simplest thing that could possibly work, but I am
>conscious that there's a lot of room for data entry error and thus
>validation, if I just parse a file, or make a CLI.  OTOH I have never ever
>written a web app, with forms etc.
>
>There's no time constraint here - this is merely for fun, and to make my
>life easier.
>
>Any thoughts?
>
>S.

1.  There is no better reason to do things.

2.  How do you receive your data now?  Do you want to change this,
perhaps extend the capabilities -- i.e. let people send an sms
with results to your cell phone?  Or limit the capabilities ("Stop
phoning me with this stuff!  Use the webpage!)  How you get your
data is very relevant to the design.

3.  After you have performed your calculation and made a table, what
do you do with it?  Email it to members?  Publish it in a
weekly dead-tree newspaper?  Post it to a website?  What you
want to do with it once you have it is also very relevant to the design.

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


Re: [Tutor] League Secretary Application

2015-05-30 Thread Alan Gauld

On 30/05/15 17:08, Stephen Nelson-Smith wrote:

3.  After you have performed your calculation and made a table, what
 do you do with it?  Email it to members?  Publish it in a
 weekly dead-tree newspaper?  Post it to a website?  What you
 want to do with it once you have it is also very relevant to the
design.



ATM I send an email out, and someone else takes that data and publishes it
on a website.


You showed us sample input but what exactly does the output look like?

In any data based program you should try to separate the
presentation from the processing. So what does the output
data look like(in content terms)? It might seem self evident
to you because you are doing this already but it isn't so
obvious to us.

Once we know what the output data looks like we can decide
how to present it (web table, excel spreadsheet, CSV file,
PDF, whatever...)


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


Re: [Tutor] Generate Prime Numbers

2015-05-30 Thread Mirage Web Studio


On 2015-05-29 11:18 PM, Alan Gauld wrote:

On 29/05/15 16:28, George wrote:


Below is a sample code i created.

Can i better it any way?


Of course. There is always improvements that can be made.
But in your case there are quite a few!


def IsDivisibleBy3(number):#string variable
 v=0
 for c in number:
 v=v+int(c)
 if v%3==0:
 return True
 else:
 return False


def IsDivisibleBy3(number):#string variable
return not int(number) % 3


def IsDivisibleBy7(number):#string variable


See above, but maybe better still

def isDivisibleByN(number, N):
   return not int(number)%N


def IsPrime(number):


Google for the "sieve of eratosthenes"
Or look it up on wikipedia.

That will give one of several possible
improvements to your algorithm.


primelist=[]

for i in range (11,20,2):
 number=str(i)
 print "checking ",i

 if IsPrime(number):


Note, you are starting with a number, then converting
it to a string then in your functions converting it
back to a number.
That's crazy!

Also where do you store the primes less than 11?
ie. 1,3,5,7

HTH


Hello,

I thank u all for the replies.  I have checked  sieve of Eratosthenes 
and have at first devised a solution using class-object, thinking it 
easier, but it proved to be slower than my basic algorithm which i 
submitted earlier,  results were my algorithm processed 100 thousand 
numbers in 80 or so sec but class based algorithm produced same result 
in about 230 sec. After putting some thought i used dict for a change 
with the sieve method and am able to produce primes for 1 million nos in 
about 10 sec, which is better than both earlier algorithms.  I am 
submitting both.


My query is does using classes slowed it or the python hardcoded 
algorithm for dicts was better?

and
if you had to implement the sieve algorithm how would u have done it.

Thank u


George

-
class based algorithm
-

import time

starttime=time.time()

class Number:
def __init__(self,number,p=None,n=None):
self.no=number
self.marked=None
self.p=p
self.n=n


node=Number(2,None,None)
start=node

counter=1
for i in range(3,11):
counter+=1
newnode=Number(i,node)
node.n=newnode
node=newnode

node=start


while start != None:
if start.marked==True:
start=start.n
continue
else:
newprime = start.no
print ("\nNewPrime",newprime,"\nMarking no:")
tmpnode=start
while tmpnode !=None:
for i in range (newprime):
tmpnode=tmpnode.n
if tmpnode==None:
break
if tmpnode==None:
break
#print ( tmpnode.no, end=" ")
tmpnode.marked=True
start=start.n

print ("primes")
counter=0
while node!=None:
if not node.marked:
counter+=1
print(node.no)

node=node.n

print("--- %s seconds ---" % (time.time() - starttime), counter)


---
dict based algorithm
-



import time

starttime=time.time()

max=600

nodict={}

for i in range(2,max):
nodict[i]=0

for no in sorted(nodict.keys()):
x=no+no
while xhttp://www.avast.com

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


Re: [Tutor] Generate Prime Numbers

2015-05-30 Thread Danny Yoo
I'll review the code a bit.


> import time
>
> starttime=time.time()
>
> class Number:
> def __init__(self,number,p=None,n=None):
> self.no=number
> self.marked=None
> self.p=p
> self.n=n

It would be helpful to document what the types of 'p' and 'n' are
here.  Without any comments, I don't have good expectations on what to
expect yet.  And without types, documentation in Python is doubly
crucial to help folks understand what to expect.



> node=Number(2,None,None)
> start=node
>
> counter=1
> for i in range(3,11):
> counter+=1
> newnode=Number(i,node)
> node.n=newnode
> node=newnode


Ok, I see.  Your structure earlier is meant to represent a
doubly-linked linked data structure.  The fields 'n' stands for
"next", and 'p' stands for "previous", and you're constructing a
linked list of numbers, each of which should have links to the next
and previous elements.  You're basically building up a thread of
nodes:

3 -> 4 -> 5 -> 6 -> ...

The code above doesn't seem to do the backwards linking with the 'p'
previous attribute.  You might want to remove that from your data
structure definition if you're not using it.


... but that being said: do you need to represent linked structure
here?  Linked structure is very flexible, but with certain costs:
"random" access is slower because you have to keep following links to
get from one end of the list to another point.  If you want to mark
every 5th element in the collection, a linked list will force you to
walk every intermediate element in between, as you do later on in your
'while' loop.  In contrast, an array-like structure will let you
access nodes by index very quickly: you can jump to every fifth
element directly, skipping over the other ones.


That is, it's important to note that the version with linked lists
isn't slow because it's using classes: it's slow fundamentally because
it's not actually taking advantage of the structure of numbers and the
ability to do quick, random access based on numbers.


You should see improvement by using an array-like list.  Something like:

###
class Number:
def __init__(self,number):
self.no=number
self.marked=None

numbers = []
for i in range(11):
newnumber = Number(i)
numbers.append(newnumber)
###

to initialize the basic structures.  Here, numbers[3] will be the
Number(3), numbers[6] will be the Number(6), and so on.  This direct
correspondence between index and the value at that index is what makes
array-like structures very useful.  With this ability to directly
index, the code that does the sieving no longer needs to manually
march down links: it can index over the multiples of n.

Try it with the array-like list.  You should find it instructive.
You've pretty much got the rest of the code ready: it should be almost
identical with the dict-based code you present later.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Generate Prime Numbers

2015-05-30 Thread Alan Gauld

On 30/05/15 19:14, Mirage Web Studio wrote:


and have at first devised a solution using class-object, thinking it
easier, but it proved to be slower than my basic algorithm which i
submitted earlier,


I'm not surprised. You seem to have a talent for finding complex 
solutions to fairly simple problems :-)



in about 230 sec. After putting some thought i used dict for a change
with the sieve method and am able to produce primes for 1 million nos in
about 10 sec, which is better than both earlier algorithms.


Yes, using built in data structures (implemented in highly
optimised C) will nearly always be faster than building
your own in interpreted Python.


My query is does using classes slowed it or the python hardcoded
algorithm for dicts was better?


See above.
classes are great for modelling concepts that are not available
in the language. But both numbers and collections are well
provided for in Python.


if you had to implement the sieve algorithm how would u have done it.


Similarly to your dict approach but probably using lists.
After all lists are naturally indexed by numbers so using
a dict keyed by numbers doesn't add much value.

There are also a few tweaks you can do to improve efficiency
but you are pretty much there.


-
class based algorithm
-

import time

starttime=time.time()

class Number:
 def __init__(self,number,p=None,n=None):
 self.no=number
 self.marked=None
 self.p=p
 self.n=n


A class with no methods other than init() is usually a bad sign.
You should always think very carefully whether another data
structure might not be more suitable. The whole point of
objects is that you do things to them. That means you need
methods to make them useful.


node=Number(2,None,None)


Note the extra work you make Python do to initialise a number
each time compared to just assigning a built-in integer object.


start=node

counter=1
for i in range(3,11):
 counter+=1
 newnode=Number(i,node)
 node.n=newnode
 node=newnode

node=start


while start != None:
 if start.marked==True:
 start=start.n
 continue
 else:
 newprime = start.no
 print ("\nNewPrime",newprime,"\nMarking no:")
 tmpnode=start
 while tmpnode !=None:


Notice you now have a loop within a loop. If you  are
looking for speed that's another bad sign. Compare with
your dict version there are two loops but they are not
nested, they run one after the other (and the first one
could be avoided using a list)


 for i in range (newprime):


And now you have a third nested loop. Oh dear!


 tmpnode=tmpnode.n
 if tmpnode==None:
 break
 if tmpnode==None:
 break
 #print ( tmpnode.no, end=" ")
 tmpnode.marked=True
 start=start.n

print ("primes")
counter=0
while node!=None:
 if not node.marked:
 counter+=1
 print(node.no)

 node=node.n

print("--- %s seconds ---" % (time.time() - starttime), counter)


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


Re: [Tutor] unittest with random population data

2015-05-30 Thread Steven D'Aprano
On Sat, May 30, 2015 at 12:16:01PM +0100, Sydney Shall wrote:

> I have written a unittest class which works OK.
> But the problem I have is that because I use the random module to 
> populate my initial arrays, my data is not strictly predictable even 
> though I am using seed(0).

Please show us how you populate your arrays, because what you describe 
sounds wrong. Seeding to the same value should give the same sequence of 
values:

py> import random
py> random.seed(0)
py> a = [random.random() for i in range(10**6)]
py> random.seed(0)
py> b = [random.random() for i in range(10**6)]
py> a == b
True


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


Re: [Tutor] unittest with random population data

2015-05-30 Thread Cameron Simpson

On 30May2015 12:16, Sydney Shall  wrote:

Following advice from you generous people, I have chosen a project >that 
interests me, to develop some knowledge of python.
My projest is a simulation of a biological population.
I have a base class and a simulation function, which uses instances of 
the class.
This, after many months of work and lots of advice, now seems to work 
well. It generates sensible data and when I write a small test program 
it gives sensible output.

Now I want to learn to use unittest.
I have written a unittest class which works OK.
But the problem I have is that because I use the random module to 
populate my initial arrays, my data is not strictly predictable even 
though I am using seed(0). So the tests return many *fails* because 
the numbers are not exactly correct, although they are all rather 
close, consistent with the sigma value I have chosen for the spread of 
my population. I do of course use *almostEqual* and not *Equal*.


First of all, several people have posted suggestions for getting identical 
results on every run.


However, there is another approach, which you might consider. (And use in 
addition, not inseadt of, the reproducable suggestions).


It is all very well to have a unit test that runs exactly the same with a test 
set of data - it lets you have confidence that algorithm changes do not change 
the outcome. But on for that data set.


You say that your results are "all rather close, consistent with the sigma
value I have chosen for the spread of my population". I would advocate making 
some "contraint" tests that verify this property for _any_ input data set.


Then you can run with random and _changing_ input data sets to verify that your 
code produces the expected _kind_ of results with many data sets.


So you would have one test which ran with a fixed data set which confirms 
preidctable unchanging results. And you have other tests with run with randomly 
chosen data and confirms that outcomes fall within the parameters you expect.  
You can apply those checks ("outcome in range") to both sets of tests.


As an exmaple, I have a few classes which maintain data structures which are 
sensitive to boundary conditions. The glaring example is a numeric range class 
which stores contiguous ranges efficiently (a sequence of (low,high) pairs). It 
has a few add/remove operations which are meant to maintain that sequence on 
ordered minimal form. cutting and merging adjacent ranges is very easy to get 
wrong, very sensitive to off-by-one logic errors.


So my tests for this class include some random tests which do random 
unpredictable add/remove operations, and run a consistency check on the object 
after each operation. This gives me good odds of exercising some tricky 
sequence which I have not considered explicitly myself.


You can see the test suite here:

 https://bitbucket.org/cameron_simpson/css/src/tip/lib/python/cs/range_tests.py

It has a bunch of explicit specific tests up the top, and then the random 
consistency test down the bottom as "test30random_set_equivalence".


Cheers,
Cameron Simpson 

MS-Word is Not a document exchange format - Jeff Goldberg
http://www.goldmark.org/netrants/no-word/attach.html
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor