PreTeXtBook / pretext

PreTeXt: an authoring and publishing system for scholarly documents
https://pretextbook.org
Other
265 stars 208 forks source link

sample article example of making lines for Sage cells short enough to fit on a page when they wouldn't normally #88

Open kcrisman opened 9 years ago

kcrisman commented 9 years ago

And it would be useful to have an example in the article showing a newbie how to do your suggestion about making the lines short enough, as they are certainly likely to write poorly conceived long line code like mine :)

Yes, the subject of this issue is intentionally meta.

kcrisman commented 9 years ago

Here is the current verbiage:

Our maximum width for text, designed for readability, suggests you should format your Sage code with a maximum of about 54 characters. On a mobile device, the number of displayed characters might be as low as 28 in portrait orintation, and again around 50 in landscape. You can use a variety of techniques to shorten long lines, such as using intermediate variables. Since Sage is just a huge Python library, you can use any of Python's facilities for handling long lines. These include a continuation character (which I try to avoid using) or natural places where you can break long lines, such as between entries of a list. Also, if writing loops or functions, you may wish to have your indentation be only two characters wide (rather than, say, four).

So to be specific, examples of this would be great - especially one showing why the continuation character isn't so hot.

davidfarmer commented 9 years ago

The continuation character isn't so hot for the same reasons that apply to all of Python. To quote from one of several stackoverflow questions on this topic: "Implicit continuation is preferred, explicit backslash is to be used only if necessary."

The PEP8 style guide used to say "sometimes using a backslash looks better", but it does not say that any more.

So, take this as settled law.

On Thu, 18 Jun 2015, kcrisman wrote:

Here is the current verbiage:

  Our maximum width for text, designed for readability, suggests you should format your Sage
  code with a maximum of about 54 characters. On a mobile device, the number of displayed
  characters might be as low as 28 in portrait orintation, and again around 50 in landscape. You
  can use a variety of techniques to shorten long lines, such as using intermediate variables.
  Since Sage is just a huge Python library, you can use any of Python's facilities for handling
  long lines. These include a continuation character (which I try to avoid using) or natural
  places where you can break long lines, such as between entries of a list. Also, if writing
  loops or functions, you may wish to have your indentation be only two characters wide (rather
  than, say, four).

So to be specific, examples of this would be great - especially one showing why the continuation character isn't so hot.

— Reply to this email directly or view it on GitHub.[AAM6LGs6m79EBdaSOrDchenvfElzMqlQks5oUumygaJpZM4EMIaH.gif]

kcrisman commented 9 years ago

Sure, I understand that, but sometimes it's hard to avoid. Example - interacts. You HAVE to put the arguments in the

def _(argument1=2,argument2=3):

format, but since one also wants the names of the selectors to be meaningful, it's pretty challenging to fit that all in one line. If someone has ideas for avoiding that, that can be the first example for this ticket :)

Plots with a lot of options are another example - I suppose one could make a dictionary and one-by-one add plot options to it and then pass in the dict with **, but I would say that for pedagogical purposes that tends to obfuscate the code, since I do want my students to read the code if they have sufficient background.

davidfarmer commented 9 years ago

If you provide an example where you are having trouble fitting it to the suggested line length, then that would be a good start on the example you are requesting.

On Thu, 18 Jun 2015, kcrisman wrote:

Sure, I understand that, but sometimes it's hard to avoid. Example - interacts. You HAVE to put the arguments in the

def _(argument1=2,argument2=3):

format, but since one also wants the names of the selectors to be meaningful, it's pretty challenging to fit that all in one line. If someone has ideas for avoiding that, that can be the first example for this ticket :)

Plots with a lot of options are another example - I suppose one could make a dictionary and one-by-one add plot options to it and then pass in the dict with **, but I would say that for pedagogical purposes that tends to obfuscate the code, since I do want my students to read the code if they have sufficient background.

— Reply to this email directly or view it on GitHub.[AAM6LIZBMnEUE81HLApNDcfsNlatjpFaks5oUvtPgaJpZM4EMIaH.gif]

kcrisman commented 9 years ago

I thought that it was clear enough, but for reference:

@interact
def _(a=slider(-10,10,1,6),b=slider(-10,10,1,4),c=slider(-20,20,1,2),viewsize=slider(3,20,1,5)):
    p = plot(-(a/b)*x+c/b,-viewsize,viewsize,plot_points=200)
    lattice_pts=[[i,j] for i in [-viewsize..viewsize] for j in [-viewsize..viewsize]]
    plot_lattice_pts = points(lattice_pts,rgbcolor=(0,0,0),pointsize=2)
    if mod(c,gcd(a,b))==0:
        line_pts = [coords for coords in lattice_pts if a*coords[0]+b*coords[1]==c]
        if line_pts==[]:
            plot_line_pts = Graphics()
        else:
            plot_line_pts = points(line_pts,rgbcolor=(0,0,1),pointsize=20)
        html("Showing solutions to $%sx+%sy=%s$ in this viewing window"%(str(a),str(b),str(c)))
        show(p+plot_lattice_pts+plot_line_pts, figsize=[5,5],xmin=-viewsize,xmax=viewsize,ymin=-viewsize,ymax=viewsize)
    else:
        html("The gcd of $%s$ and $%s$ is $%s$, which does not divide $%s$,"%(str(a),str(b),str(gcd(a,b)),str(c)))
        html("so no solutions to $%sx+%sy=%s$"%(str(a),str(b),str(c)))
        show(p+plot_lattice_pts, figsize=[5,5],xmin=-viewsize,xmax=viewsize,ymin=-viewsize,ymax=viewsize)

I'm not referring to the show commands, which could probably be shortened some, e.g.

G = p+plot_lattice_pts+plot_line_pts
show(G, figsize=[5,5],xmin=-viewsize,xmax=viewsize,ymin=-viewsize,ymax=viewsize)

though even that could be longish. I mean the def part, primarily. Though I also refuse to name my viewsize something that the student can't understand. I guess I could then do vs = viewsize in the command itself, but to me that's obfuscation. In any case, the first line seems challenging to rewrite in a way that (again) isn't introducing lots of new variables for the sole purpose of line length (since they won't be used anywhere but in the def).

Similarly,

@interact(layout=[['a_1','n_1'],['a_2','n_2'],['a_3','n_3']])
def _(a_1=('a_1',1),a_2=('a_2',2),a_3=('a_3',3),n_1=('n_1',5),n_2=('n_2',6),n_3=('n_3',7)):
    try:
        answer = CRT_list([a_1,a_2,a_3],[n_1,n_2,n_3])
        string1 = "<ul><li>$x\equiv %s \\text{ mod }(%s)$</li>"%(a_1,n_1)
        string2 = "<li>$x\equiv %s \\text{ mod }(%s)$</li>"%(a_2,n_2)
        string3 = "<li>$x\equiv %s \\text{ mod }(%s)$</li></ul>"%(a_3,n_3)
        html("The simultaneous solutions to ")
        html(string1+string2+string3)
        html("all have the form $%s$ modulo $%s$"%(answer,n_1*n_2*n_3))
    except ValueError, e:
        html("Make sure the moduli are appropriate for using the CRT!")
        html("Sage gives the error message:")
        html(e)

If I'm doing the CRT allowing up to five or six congruences, yikes. Again, unless I use the dictionary approach or something...

In any case, hopefully one way or another this will provide grist for Rob to put some examples in of how to avoid such messes :smiley_cat: which was the point of the issue.

kcrisman commented 9 years ago

By the way, the following should overflow but doesn't, it wraps instead in LaTeX. Is there special processing for #? Or maybe because it's only one line? For me it's in an exercise, but I found a similar example where does the same thing outside an exercise, so I don't think that's the relevant piece.

    <sage>
      <input>gcd([3800,7600,1900]) # By the way, Sage allows you to calculate arbitrary gcds like this</input>
      <output></output>
    </sage>
kcrisman commented 9 years ago

Aha, I see. It turns out that the LaTeX keeps these but auto-indents to the previous level when there is a space. That looks fine, and in some sense is the best example (works with no effort in pdf, and in html you would just be evaluating anyway), except such code cannot be cut and pasted from pdf (I tried).

Though in any case cutting might be dodgy, given that strings turn into weird stuff like this:

'Showing\xe2\x90\xa3solutions\xe2\x90\xa3to\xe2\x90\xa3'
rbeezer commented 9 years ago

This is under the control of the "listings" package, so that would be the place to determine what is possible.

It'd be nice if it was cut-and-pasteable from PDF. I went to a lot of effort to make inline code in not have "smart quotes" etc, and thus be faithfully cut-and-pasteable.

Maybe there is a better package than listings?

On 06/22/2015 01:10 PM, kcrisman wrote:

Aha, I see. It turns out that the LaTeX keeps these but auto-indents to the previous level when there is a space. That looks fine, and in some sense is the best example (works with no effort in pdf, and in html you would just be evaluating anyway), except such code cannot be cut and pasted from pdf (I tried).

Though in any case cutting might be dodgy, given that strings turn into weird stuff like this:

'Showing\xe2\x90\xa3solutions\xe2\x90\xa3to\xe2\x90\xa3'

— Reply to this email directly or view it on GitHub https://github.com/rbeezer/mathbook/issues/88#issuecomment-114244878.

kcrisman commented 9 years ago

Maybe there is a better package than listings?

That I do not know.

It'd be nice if it was cut-and-pasteable from PDF.

In which event perhaps line continuations are better, after all?

rbeezer commented 9 years ago

Sorry to be slow on this one. Observations:

(a) It is great to show students how to craft an interact.

(b) Well-designed interacts with lots of details are an excellent thing to add to a book.

At some point, I think (b) supersedes (a). In other words, the end product of a whiz-bang interact with lots of detailed code is more important than displaying the underlying code to your audience.

So there should be Sage cells which hide their input and are easy to run (maybe automatically). I worked on this once, and I cannot recall what the obstacle was (there is a note in the HTML source to do this). So now at #122

rbeezer commented 9 years ago

I will eventually include an example. But here are some of my tricks. I got about 75% of the way through this several days ago, so better to show that much than to wait forever to finish. Note argument as one per line, list comprehensions spread across lines, output using format() and a preliminary string, and I did some minor variable renaming.

Last I checked, this ran in the Sage Cell in a seemingly identical manner to original.

Could I use this as a before/after demonstration in the sample article? I'd put more work into it first.

@interact
def _(a=slider(-10,10,1,6),
      b=slider(-10,10,1,4),
      c=slider(-20,20,1,2),
      viewsize=slider(3,20,1,5)):
    p = plot(-(a/b)*x+c/b,-viewsize,viewsize,plot_points=200)
    lattice_pts=[[i,j] 
                 for i in [-viewsize..viewsize] 
                 for j in [-viewsize..viewsize]]
    lattice_plot = points(lattice_pts,rgbcolor=(0,0,0),pointsize=2)
    if mod(c,gcd(a,b))==0:
        line_pts = [coords 
                    for coords in lattice_pts 
                    if a*coords[0]+b*coords[1]==c]
        if line_pts==[]:
            plot_line_pts = Graphics()
        else:
            plot_line_pts = points(line_pts,rgbcolor=(0,0,1),pointsize=20)
        heading = "Showing solutions to ${}x+{}y={}$ in this viewing window"
        html(heading.format(str(a),str(b),str(c)))
        fig = p + lattice_plot + plot_line_pts
        show(fig,figsize=[5,5],xmin=-viewsize,xmax=viewsize,ymin=-viewsize,ymax=viewsize)
    else:
        msg = "The gcd of ${}$ and ${}$ is ${}$, which does not divide $%s$,"
        html(msg.format(str(a),str(b),str(gcd(a,b)),str(c)))
        msg = "so no solutions to ${}x+{}y={}$"
        html(msg.format(str(a),str(b),str(c)))
        show(p+plot_lattice_pts, figsize=[5,5],xmin=-viewsize,xmax=viewsize,ymin=-viewsize,ymax=viewsize)
kcrisman commented 9 years ago

I bet that the last one still will be too long for pdf. Will this copy and paste? But yes, this formatting looks nice, that's for sure.

rbeezer commented 9 years ago

Yes, I didn't finish.

More work (or a new package) will be needed to make the cut-pasteable from a PDF. Mostly I was trying to show what Python allows.

On 06/27/2015 07:00 PM, kcrisman wrote:

I bet that the last one still will be too long for pdf. Will this copy and paste? But yes, this formatting looks nice, that's for sure.

— Reply to this email directly or view it on GitHub https://github.com/rbeezer/mathbook/issues/88#issuecomment-116182620.

kcrisman commented 9 years ago

Sorry I didn't mention earlier that I agree with this. I don't mind some of these not being in pdf, or even visible much in html, though it should be configurable.

In other words, the end product of a whiz-bang interact with lots of detailed code is more important than displaying the underlying code to your audience.

kcrisman commented 8 years ago

I think that I now think that the actual solution is to just put in a few extra spaces. E.g. instead of

show(p+plot_lattice_pts, figsize=[5,5],xmin=-viewsize,xmax=viewsize,ymin=-viewsize,ymax=viewsize)

do

show(p+plot_lattice_pts, figsize=[5,5], xmin=-viewsize,xmax=viewsize, ymin=-viewsize,ymax=viewsize)

and now it works fine. But this should be mentioned somewhere in the author guide.