Re: [Tutor] How to have unique identifiers for multiple object instances of a given class?

2018-08-27 Thread Alan Gauld via Tutor
On 27/08/18 04:58, boB Stepp wrote:

> So you are saying do something like:
> 
> class SolitaireGame():
> def __init__(self, name):
> self.name = name
> 
> def describe_self(self):
> print("This game of solitaire is called", self.name, ".")
> 
> game_objects = {}
> def make_new_game_object(name):
> global game_objects
> game_objects[name[ = SolitaireGame(name)
> 
> make_new_game_object('Chinese Solitaire')
> make_new_game_object('Ace Mastery')
> make_new_game_object('King Mastery')

Yes, although I'd miss out the function and just populate
the dict directly. A single line function doesn't really
help much unless its a very complicated line or one
that might change regularly (eg storing directly in
a database or file rather than in memory).

game_objects[name] = SolitaireGame(name)

If you are concerned about duplicates just add a
guard when you read the name:

while True:
name = input("Name: ")
if name in game_objects:
   print ("duplicate name, try again")
else:
   break

Maybe put that in a function...


>> Maybe JSON for that? Or even a shelve database?
> 
> I plan to keep this simple.  I will use a ".cfg" file to store game
> configuration information and a ".csv" file to store the actual
> records of hands played.  But I will have to be careful how I generate
> the base filenames to avoid duplicates and potential nasty
> user-generated names.  Though this project is only meant for my use


If you go with a single JSON file or shelve you have
no worries about name clashes. JSON is specifically
designed to store multiple complex object records.
And it retains the readability of CSV (unlike shelve).

-- 
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] need help generating table of contents

2018-08-27 Thread Albert-Jan Roskam


From: Tutor  on behalf of 
Peter Otten <__pete...@web.de>
Sent: Friday, August 24, 2018 3:55 PM
To: tutor@python.org

> The following reshuffle of your code seems to work:
> 
> print('\r\n** Table of contents\r\n')
> pattern = '/Title \((.+?)\).+?/Page ([0-9]+)(?:\s+/Count ([0-9]+))?'
> 
> def process(triples, limit=None, indent=0):
>     for index, (title, page, count) in enumerate(triples, 1):
>     title = indent * 4 * ' ' + title
>     print(title.ljust(79, ".") + page.zfill(2))
>     if count:
>     process(triples, limit=int(count), indent=indent+1)
>     if limit is not None and limit == index:
>     break
> 
> process(iter(re.findall(pattern, toc, re.DOTALL)))

Hi Peter, Cameron,

Thanks for your replies! The code above indeeed works as intended, but: I don't 
really understand *why*.
I would assign a name to the following line "if limit is not None and limit == 
index", what would be the most descriptive name? I often use "is_*" names for 
boolean variables. Would "is_deepest_nesting_level" be a good name?

Also, I don't understand why iter() is required here, and why finditer() is not 
an alternative.

I wrote the bookmarks file myself, and the code above is part of a shell script 
that compiles a large .pdf, with openoffice commandline calls, ghostscript, 
git, pdftk and python. The human-readable toc and the pdf bookmarks will always 
be consistent if I only need to edit one file.

Thanks again!

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


[Tutor] Problem compiling code from GitHub

2018-08-27 Thread Dave Hill

Hi,

As a volunteer on a Welsh Heritage Railway I undertake their Electrical 
Equipment testing, for which I use a Megger PAT420. This device stores 
data in 'sqlite', which using Python I can read and generate a number of 
reports in 'csv' format. I now wish to collate asset data for various 
locations, and as I use OpenOffice I want to generate an 'ods' document 
with a 'sheet' for each location.


At present I generate a 'csv' file for each location, but as there are 
20 locations this is a bit cumbersome. I use the 20 locations as a 
method to make the handing of over 500 assets somewhat manageable.


I have found 'odswriter' on GitHub 
https://github.com/mmulqueen/odswriter which appears to provide what I 
want. However, I have come to a halt, due to the limitation of my knowledge.


I admit that I am confounded as to where/how to access this code.

I am using Python 3.6.4, in IDLE on a PC running windows.

I am using the following code as a starting point , Test_ODS#1.py

   import datetime
   import decimal
   ##import odswriter as ods
   try:
    from OdsWriter import odswriter as ods
   except RuntimeError:
    print("Error importing OdsWriter!")

   # Single sheet mode
   with ods.writer(open("test.ods","wb")) as odsfile:
    odsfile.writerow(["String", "ABCDEF123456", "123456"])
    # Lose the 2L below if you want to run this example code on
   Python 3, Python 3 has no long type.
    odsfile.writerow(["Float", 1, 123, 123.123,
   decimal.Decimal("10.321")])
    odsfile.writerow(["Date/DateTime", datetime.datetime.now(),
   datetime.date(1989, 11, 9)])
    odsfile.writerow(["Time",datetime.time(13,
   37),datetime.time(16, 17, 18)])
    odsfile.writerow(["Bool", True, False, True])
    odsfile.writerow(["Formula", 1, 2, 3,
   ods.Formula("IF(A1=2,B1,C1)")])

   # Multiple sheet mode
   with ods.writer(open("test-multi.ods","wb")) as odsfile:
    bears = odsfile.new_sheet("Bears")
    bears.writerow(["American Black Bear", "Asiatic Black Bear",
   "Brown Bear", "Giant Panda", "Qinling Panda",
 "Sloth Bear", "Sun Bear", "Polar Bear",
   "Spectacled Bear"])
    sloths = odsfile.new_sheet("Sloths")
    sloths.writerow(["Pygmy Three-Toed Sloth", "Maned Sloth",
   "Pale-Throated Sloth", "Brown-Throated Sloth",
 "Linneaeus's Two-Twoed Sloth", "Hoffman's
   Two-Toed Sloth"])

I get the following error

   Traceback (most recent call last):
  File "C:\Code\Python\ODS_Writer\Test_ODS#1.py", line 5, in 
    from OdsWriter import odswriter as ods
  File "C:\Code\Python\ODS_Writer\OdsWriter.py", line 7, in 
    from . import ods_components
   ImportError: attempted relative import with no known parent package

I have put the code from GitHub in various locations subject to my 
limited knowledge of Python, but I have no idea what the following 
extract means, and searching online on & off for two days has proved 
unfruitful.


   from __future__ import unicode_literals
   from zipfile import ZipFile
   import decimal
   import datetime
   from xml.dom.minidom import parseString

   from . import ods_components
   from .formula import Formula

I understand the use of 'import' and have written my own modules, but 
from . import ods_components has me floored.


Thank you in advance for any help.

Dave





import datetime
import decimal
##import odswriter as ods
try:
from OdsWriter import odswriter as ods
except RuntimeError:
print("Error importing OdsWriter!")

# Single sheet mode
with ods.writer(open("test.ods","wb")) as odsfile:
odsfile.writerow(["String", "ABCDEF123456", "123456"])
# Lose the 2L below if you want to run this example code on Python 3, 
Python 3 has no long type.
odsfile.writerow(["Float", 1, 123, 123.123, decimal.Decimal("10.321")])
odsfile.writerow(["Date/DateTime", datetime.datetime.now(), 
datetime.date(1989, 11, 9)])
odsfile.writerow(["Time",datetime.time(13, 37),datetime.time(16, 17, 18)])
odsfile.writerow(["Bool", True, False, True])
odsfile.writerow(["Formula", 1, 2, 3, ods.Formula("IF(A1=2,B1,C1)")])

# Multiple sheet mode
with ods.writer(open("test-multi.ods","wb")) as odsfile:
bears = odsfile.new_sheet("Bears")
bears.writerow(["American Black Bear", "Asiatic Black Bear", "Brown Bear", 
"Giant Panda", "Qinling Panda", 
 "Sloth Bear", "Sun Bear", "Polar Bear", "Spectacled Bear"])
sloths = odsfile.new_sheet("Sloths")
sloths.writerow(["Pygmy Three-Toed Sloth", "Maned Sloth", "Pale-Throated 
Sloth", "Brown-Throated Sloth",
 "Linneaeus's Two-Twoed Sloth", "Hoffman's Two-Toed Sloth"])
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Problem compiling code from GitHub

2018-08-27 Thread Steven D'Aprano
Hi Dave, and welcome!


On Mon, Aug 27, 2018 at 12:14:33PM +0100, Dave Hill wrote:

> I have found 'odswriter' on GitHub 
> https://github.com/mmulqueen/odswriter which appears to provide what I 
> want. However, I have come to a halt, due to the limitation of my knowledge.

[...]


> I get the following error
> 
>Traceback (most recent call last):
>   File "C:\Code\Python\ODS_Writer\Test_ODS#1.py", line 5, in 
>     from OdsWriter import odswriter as ods
>   File "C:\Code\Python\ODS_Writer\OdsWriter.py", line 7, in 
>     from . import ods_components
>ImportError: attempted relative import with no known parent package
> 
> I have put the code from GitHub in various locations

That sounds like the problem. Some libraries are pretty forgiving about 
where they are, some not so much. Some come with detailed installation 
instructions, some don't.

This appears to be in the second category of both cases.

I would start by carefully deleting the code from Github (or at least 
moving it out of the way) first, then installing it again.

Try installing it using the pip command. Open up a command line console. 
I think you do this under Windows by typing Ctrl-R ("Run") then entering 
"cmd", You ought to get a text window with a prompt looking something 
like this:

C:\ %

or similar. (If in doubt, ask.)

Try entering the command

pip --version

and if you get an error like "pip not found" or similar, try this:

   python36 -m ensurepip --default-pip
   python36 -m pip install --upgrade pip setuptools wheel

after which you can then try:

   pip install odswriter

I'll be honest: I don't use pip myself, every time I've tried I get 
frustrated and end up installing things the old-fashioned manual way 
which is theoretically "harder" but it works for me. And everyone else 
swears by pip. (I just swear at it, especially the horrible colours it 
likes to use.)

But if you get any errors, please don't hesitate to copy and paste them 
here (DON'T take a screen shot) so we can read them and advise you.


There's a tutorial here with more detail:

https://packaging.python.org/tutorials/installing-packages/




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


Re: [Tutor] Problem compiling code from GitHub

2018-08-27 Thread Mats Wichmann
On 08/27/2018 05:14 AM, Dave Hill wrote:

> I get the following error
> 
>    Traceback (most recent call last):
>       File "C:\Code\Python\ODS_Writer\Test_ODS#1.py", line 5, in 
>         from OdsWriter import odswriter as ods
>       File "C:\Code\Python\ODS_Writer\OdsWriter.py", line 7, in 
>         from . import ods_components
>    ImportError: attempted relative import with no known parent package
> 
> I have put the code from GitHub in various locations subject to my
> limited knowledge of Python, but I have no idea what the following
> extract means, and searching online on & off for two days has proved
> unfruitful.
> 
>    from __future__ import unicode_literals
>    from zipfile import ZipFile
>    import decimal
>    import datetime
>    from xml.dom.minidom import parseString
> 
>    from . import ods_components
>    from .formula import Formula
> 
> I understand the use of 'import' and have written my own modules, but
> from . import ods_components has me floored.
> 
> Thank you in advance for any help.

the doc bit you're missing to at least tell you what this is is here:

https://docs.python.org/3/tutorial/modules.html#intra-package-references

this is tricky ground, however.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] need help generating table of contents

2018-08-27 Thread Peter Otten
Albert-Jan Roskam wrote:

> 
> From: Tutor  on behalf
> of Peter Otten <__pete...@web.de> Sent: Friday, August 24, 2018 3:55 PM
> To: tutor@python.org
> 
>> The following reshuffle of your code seems to work:
>> 
>> print('\r\n** Table of contents\r\n')
>> pattern = '/Title \((.+?)\).+?/Page ([0-9]+)(?:\s+/Count ([0-9]+))?'
>> 
>> def process(triples, limit=None, indent=0):
>> for index, (title, page, count) in enumerate(triples, 1):
>> title = indent * 4 * ' ' + title
>> print(title.ljust(79, ".") + page.zfill(2))
>> if count:
>> process(triples, limit=int(count), indent=indent+1)
>> if limit is not None and limit == index:
>>  break
>> 
>> process(iter(re.findall(pattern, toc, re.DOTALL)))
> 
> Hi Peter, Cameron,
> 
> Thanks for your replies! The code above indeeed works as intended, but: I
> don't really understand *why*. I would assign a name to the following line
> "if limit is not None and limit == index", what would be the most
> descriptive name? I often use "is_*" names for boolean variables. Would
> "is_deepest_nesting_level" be a good name?

No, it's not necessarily the deepest level. Every subsection eventually ends 
at this point; so you might call it

reached_end_of_current_section

Or just 'limit' ;) 

The None is only there for the outermost level where no /Count is provided. 
In this case the loop is exhausted.

If you find it is easier to understand you can calculate the outer count aka 
limit as the number of matches - sum of counts:

def process(triples, section_length, indent=0):
for index, (title, page, count) in enumerate(triples, 1):
title = indent * 4 * ' ' + title
print(title.ljust(79, ".") + page.zfill(2))
if count:
process(triples, section_length=int(count), indent=indent+1)
if section_length == index:
break

triples = re.findall(pattern, toc, re.DOTALL)
toplevel_section_length = (
len(triples)
- sum(int(c or 0) for t, p, c in triples)
)
process(iter(triples), toplevel_section_length)

Just for fun here's one last variant that does away with the break -- and 
thus the naming issue -- completely:

def process(triples, limit=None, indent=0):
for title, page, count in itertools.islice(triples, limit):
title = indent * 4 * ' ' + title
print(title.ljust(79, ".") + page.zfill(2))
if count:
process(triples, limit=int(count), indent=indent+1)

Note that islice(items, None) does the right thing:

>>> list(islice("abc", None))
['a', 'b', 'c']


> Also, I don't understand why iter() is required here, and why finditer()
> is not an alternative.

finditer() would actually work -- I didn't use it because I wanted to make 
as few changes as possible to your code. What does not work is a list like 
the result of findall(). This is because the inner for loops (i. e. the ones 
in the nested calls of process) are supposed to continue the iteration 
instead of restarting it. A simple example to illustrate the difference:

 >>> s = "abcdefg"
>>> for k in range(3):
... print("===", k, "===")
... for i, v in enumerate(s):
... print(v)
... if i == 2: break
... 
=== 0 ===
a
b
c
=== 1 ===
a
b
c
=== 2 ===
a
b
c
>>> s = iter("abcdefg")
>>> for k in range(3):
... print("===", k, "===")
... for i, v in enumerate(s):
... print(v)
... if i == 2: break
... 
=== 0 ===
a
b
c
=== 1 ===
d
e
f
=== 2 ===
g




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


Re: [Tutor] How to have unique identifiers for multiple object instances of a given class?

2018-08-27 Thread boB Stepp
On Mon, Aug 27, 2018 at 3:44 AM Alan Gauld via Tutor  wrote:
>
> On 27/08/18 04:58, boB Stepp wrote:

> >> Maybe JSON for that? Or even a shelve database?
> >
> > I plan to keep this simple.  I will use a ".cfg" file to store game
> > configuration information and a ".csv" file to store the actual
> > records of hands played.  But I will have to be careful how I generate
> > the base filenames to avoid duplicates and potential nasty
> > user-generated names.  Though this project is only meant for my use
>
>
> If you go with a single JSON file or shelve you have
> no worries about name clashes. JSON is specifically
> designed to store multiple complex object records.
> And it retains the readability of CSV (unlike shelve).

Wouldn't a single JSON file be wasteful?  If I used this program for a
couple of years or so and habitually played a lot of solitaire, that
would be a lot of stuff to load into RAM when on any given solitaire
session I might only play one to three kinds of solitaire.  But
perhaps I am misunderstanding JSON's capabilities as I only have a
cursory knowledge of it from considering it for other projects.

OTOH, even if I loaded into RAM all games I might have ever played I
doubt I would stress out my RAM capacity, so perhaps this is a
non-issue for this type of program on any modern computer.


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