Re: [Tutor] need help generating table of contents

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

> Hello,
> 
> I have Ghostscript files with a table of contents (toc) and I would like 
to use this info to generate a human-readable toc. The problem is: I can't 
get the (nested) hierarchy right.
> 
> import re
> 
> toc = """\
> [ /PageMode /UseOutlines
>   /Page 1
>   /View [/XYZ null null 0]
>   /DOCVIEW pdfmark
> [ /Title (Title page)
>   /Page 1
>   /View [/XYZ null null 0]
>   /OUT pdfmark
> [ /Title (Document information)
>   /Page 2
>   /View [/XYZ null null 0]
>   /OUT pdfmark
> [ /Title (Blah)
>   /Page 3
>   /View [/XYZ null null 0]
>   /OUT pdfmark
> [ /Title (Appendix)
>   /Page 16
>   /Count 4
>   /View [/XYZ null null 0]
>   /OUT pdfmark
> [ /Title (Sub1)
>   /Page 17
>   /Count 4
>   /OUT pdfmark
> [ /Title (Subsub1)
>   /Page 17
>   /OUT pdfmark
> [ /Title (Subsub2)
>   /Page 18
>   /OUT pdfmark
> [ /Title (Subsub3)
>   /Page 29
>   /OUT pdfmark
> [ /Title (Subsub4)
>   /Page 37
>   /OUT pdfmark
> [ /Title (Sub2)
>   /Page 40
>   /OUT pdfmark
> [ /Title (Sub3)
>   /Page 49
>   /OUT pdfmark
> [ /Title (Sub4)
>   /Page 56
>   /OUT pdfmark
> """
> print('\r\n** Table of contents\r\n')
> pattern = '/Title \((.+?)\).+?/Page ([0-9]+)(?:\s+/Count ([0-9]+))?'
> indent = 0
> start = True
> for title, page, count in re.findall(pattern, toc, re.DOTALL):
> title = (indent * ' ') + title
> count = int(count or 0)
> print(title.ljust(79, ".") + page.zfill(2))
> if count:
> count -= 1
> start = True
> if count and start:
> indent += 2
> start = False
> if not count and not start:
> indent -= 2
> start = True
> 
> This generates the following TOC, with subsub2 to subsub4 dedented one 
level too much:

> What is the best approach to do this?
 
The best approach is probably to use some tool/library that understands 
postscript. However, your immediate problem is that when there is more than 
one level of indentation you only keep track of the "count" of the innermost 
level. You can either use a list of counts or use recursion and rely on the 
stack to remember the counts of the outer levels.

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)))



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


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-24 Thread Mats Wichmann
On 08/24/2018 03:02 AM, Alan Gauld via Tutor wrote:
> CCing list, please always use Reply-All or Reply-List when responding
> to the tutor list so that everyone gets a chance to reply.
> 
> 
> On 24/08/18 00:35, Roger Lea Scherer wrote:
>>
>> Lots of code missing, but the line I'm interested in is this:
>> print("Your number  " + str(numerator) + "/" + str(denominator) + " 
>> is approximately  " + str(fractions[ranges[i][0]][0]) + "/" +
>> str(fractions[ranges[i][0]][1]))
>> I get this output:
>> Your number  37/112  is approximately  1/3
>>
>> From this line:
>> print("Your number ",  numerator, "/",  denominator, " is
>> approximately ", fractions[ranges[i][0]][0], "/",
>> fractions[ranges[i][0]][1])
>> I get this output:
>> Your number  37 / 112  is approximately  1 / 3
>>
>> I'm being picky. I don't like the spaces between the 37 and 112 and 1
>> and 3...
> 
>> my question is: Is there another way other than these two to
>> print without all the str nonsense and not get the spaces
> 
> Yes, use string formatting. 

In addition, let's understand what is happening above.


print("Your number ",  numerator, "/",  denominator, " is approximately
", fractions[ranges[i][0]][0], "/", fractions[ranges[i][0]][1])

You are doing two things in this line
1. construct a string
2. print the string

The constructed string is never assigned a name, so it is not saved
after the print function is done with it (no more references), but
that's what is happening. In constructing the string, there are about a
zillion options, in this case it is "adding" smaller string pieces together.

Try:

s = "hello" + "world"
print(s)

no spaces :)

the string class provides a "+" operator which is just concatenation.
So when building up a new string this way, put spaces in if you want
them, and don't put spaces in if you don't.   If your intent it to
nicely format a string for visual display on your terminal or to a file,
then string concatenation is a more cumbersome route than tools which
are designed for the purpose, but there are plenty of good uses for it
as well.

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


[Tutor] need help generating table of contents

2018-08-24 Thread Albert-Jan Roskam
Hello,

I have Ghostscript files with a table of contents (toc) and I would like to use 
this info to generate a human-readable toc. The problem is: I can't get the 
(nested) hierarchy right.

import re

toc = """\
[ /PageMode /UseOutlines
  /Page 1
  /View [/XYZ null null 0]
  /DOCVIEW pdfmark
[ /Title (Title page)
  /Page 1
  /View [/XYZ null null 0]
  /OUT pdfmark
[ /Title (Document information)
  /Page 2
  /View [/XYZ null null 0]
  /OUT pdfmark
[ /Title (Blah)
  /Page 3
  /View [/XYZ null null 0]
  /OUT pdfmark
[ /Title (Appendix)
  /Page 16
  /Count 4
  /View [/XYZ null null 0]
  /OUT pdfmark
    [ /Title (Sub1)
  /Page 17
  /Count 4
  /OUT pdfmark
    [ /Title (Subsub1)
  /Page 17
  /OUT pdfmark
    [ /Title (Subsub2)
  /Page 18
  /OUT pdfmark
    [ /Title (Subsub3)
  /Page 29
  /OUT pdfmark
    [ /Title (Subsub4)
  /Page 37
  /OUT pdfmark
    [ /Title (Sub2)
  /Page 40
  /OUT pdfmark
    [ /Title (Sub3)
  /Page 49
  /OUT pdfmark
    [ /Title (Sub4)
  /Page 56
  /OUT pdfmark
"""    
print('\r\n** Table of contents\r\n')
pattern = '/Title \((.+?)\).+?/Page ([0-9]+)(?:\s+/Count ([0-9]+))?'
indent = 0
start = True
for title, page, count in re.findall(pattern, toc, re.DOTALL):
    title = (indent * ' ') + title
    count = int(count or 0)
    print(title.ljust(79, ".") + page.zfill(2))
    if count:
    count -= 1
    start = True
    if count and start:
    indent += 2
    start = False
    if not count and not start:
    indent -= 2
    start = True

This generates the following TOC, with subsub2 to subsub4 dedented one level 
too much:


** Table of contents

Title 
page.01
Document 
information...02
Blah...03
Appendix...16
  
Sub1.17
    
Subsub117
  
Subsub2..18
  
Subsub3..29
  
Subsub4..37
  
Sub2.40
  
Sub3.49
  
Sub4.56

What is the best approach to do this?

Thanks in advance!

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


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-24 Thread Alan Gauld via Tutor
On 24/08/18 10:02, Alan Gauld via Tutor wrote:
> CCing list, please always use Reply-All or Reply-List when responding
> to the tutor list so that everyone gets a chance to reply.
> 
> 
> On 24/08/18 00:35, Roger Lea Scherer wrote:
>>
>> Lots of code missing, but the line I'm interested in is this:
>> print("Your number  " + str(numerator) + "/" + str(denominator) + " 
>> is approximately  " + str(fractions[ranges[i][0]][0]) + "/" +
>> str(fractions[ranges[i][0]][1]))
>> I get this output:
>> Your number  37/112  is approximately  1/3
>>

> print("Your number  %d/%d is approximately %d/%d" % (numerator,
>  denominator,
> fractions[ranges[i][0]][0],
> fractions[ranges[i][0]][1]))
> 
> The stacked layout is of course optional, I just think it looks clearer.

It would look clearer if the mail hadn't messed it up! :-)
The two fractions() lines were intended to be under the
numerator,denominator values not on the left side!

-- 
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] Accessing a tuple of a dictionary's value

2018-08-24 Thread Alan Gauld via Tutor
CCing list, please always use Reply-All or Reply-List when responding
to the tutor list so that everyone gets a chance to reply.


On 24/08/18 00:35, Roger Lea Scherer wrote:
>
> Lots of code missing, but the line I'm interested in is this:
> print("Your number  " + str(numerator) + "/" + str(denominator) + " 
> is approximately  " + str(fractions[ranges[i][0]][0]) + "/" +
> str(fractions[ranges[i][0]][1]))
> I get this output:
> Your number  37/112  is approximately  1/3
>
> From this line:
> print("Your number ",  numerator, "/",  denominator, " is
> approximately ", fractions[ranges[i][0]][0], "/",
> fractions[ranges[i][0]][1])
> I get this output:
> Your number  37 / 112  is approximately  1 / 3
>
> I'm being picky. I don't like the spaces between the 37 and 112 and 1
> and 3...

> my question is: Is there another way other than these two to
> print without all the str nonsense and not get the spaces

Yes, use string formatting. It gives you much more control over the
content of your string including field width, number of decimal places,
justification, etc.

For example in your case:


print("Your number  %d/%d is approximately %d/%d" % (numerator,
 denominator,

fractions[ranges[i][0]][0],

fractions[ranges[i][0]][1]))

The stacked layout is of course optional, I just think it looks clearer.

See the thread on TimesTable for more on formatting and look at
the documentation :

https://docs.python.org/3/library/stdtypes.html#old-string-formatting
and
https://docs.python.org/3/library/string.html#formatstrings

Use whichever style you prefer.

-- 
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] Times Tables Program that constantly tells you that you are wrong!

2018-08-24 Thread Matthew Polack
Thanks Alan and Peter for all your help with this.

I got it all to work..thank you..

like learning a musical instrument...probably just need some time
consolidating the current skill set...has been a lot to take in...

but getting there steadily...and bit by bit it is starting to make sense..

I'll probably stick with the traditional  %. method too for a while because
that is now what I understand.

thanks...will keep trying things..and then also reading through the various
docs provided...+ your emails.

Thank you.






Matthew Polack | Teacher


[image: Emailbanner3.png]

Trinity Drive  |  PO Box 822

Horsham Victoria 3402

p. 03 5382 2529   m. 0402456854

e. matthew.pol...@htlc.vic.edu.au

w. www.htlc.vic.edu.au

On Thu, Aug 23, 2018 at 10:34 PM, Alan Gauld via Tutor 
wrote:

> On 23/08/18 06:10, Matthew Polack wrote:
>
> > I'm also trying to solve the rounding issue...but can't work out the
> syntax
> > using the example provided...have tried this but I get an error...
> >
>
> > def viewPercent():
> >  percentCalc = score/total*100
> >  percentViewLab["text %.2f"] % percentCalc
>
> OK, the problem here is mixing up your data with TKinter's
> (inherited from Tcl/Tk) mechanism for accessing widget
> attributes.
>
> percentViewLab["text %.2f"]
>
> This tells Tkinter to fetch an attribute of your widget
> called "text %.2f". Of course there is no such attribute,
> it is called just "text".
>
> percentViewLab["text %.2f"] % percentCalc
>
> This tries to insert the percentCalc value into the
> string returned by the widget.
>
> Again that's not what you want. You want to insert
> the data into a string which will then be assigned
> to the widget's text attribute.
>
> val = "%.2f" % percentCalc  # eg. -> val = "0.76"
>
> Now insert val into your widget
>
> percentViewLab["text"] = val
>
> or equivalently:
>
> percentViewLab.config("text", val)
>
> You can of course combine all of that with
>
> percentViewLab["text"] = ".2f" % percentCalc
>
> Personally I tend to separate the creation of the
> string from the widget assignment because it makes
> it easier to debug by printing the string to the
> console.
>
> One final note. When using % to inject data into
> a format string you MUST put the percent immediately
> after the format string. No commas or parentheses
> allowed.
>
> The % formatting style is preferred by old school
> programmers (like me) who came from the world of C and
> its relatives because C uses a very similar style in
> its printf() family of functions. However, new programmers
> may find the format() method of a string more obvious.
> (I'm thinking about your students here)
>
> Using format your case would look like:
>
> val = "{:.2f}".format(percentCalc)
>
> And the previous example would be:
>
> fail_str = """
> Sorry, you got it wrong,
> the correct answer was {:d}
> Your current score is: {:f}""".format(answer,score)
>
> It is quite similar except the placemarkers are {}
> and you call the format() method. The formatting
> characters inside the {} are different too - you
> need to read the docs... There are zillions of examples.
> You might find it more logical.
>
> --
> 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
>

-- 
**Disclaimer: *Whilst every attempt has been made to ensure that material 
contained in this email is free from computer viruses or other defects, the 
attached files are provided, and may only be used, on the basis that the 
user assumes all responsibility for use of the material transmitted. This 
email is intended only for the use of the individual or entity named above 
and may contain information that is confidential and privileged. If you are 
not the intended recipient, please note that any dissemination, 
distribution or copying of this email is strictly prohibited. If you have 
received this email in error, please notify us immediately by return email 
or telephone +61 3 5382 2529** and destroy the original message.*
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor