numberscope / frontscope

Numberscope's front end and user interface: responsible for specifying sequences and defining and displaying visualizers
MIT License
7 stars 14 forks source link

Add a template for p5 visualizers #293

Closed Vectornaut closed 2 months ago

Vectornaut commented 2 months ago

By submitting this PR, I am indicating to the Numberscope maintainers that I have read and understood the contributing guidelines and that this PR follows those guidelines to the best of my knowledge. I have also read the pull request checklist and followed the instructions therein.


This update adds a new visualizer directory, src/workbench, whose contents don't normally show up in the visualizer list. To use the visualizers in this directory, you serve Frontscope in "workbench mode" by calling npm run dev:workbench.

If this pull request looks generally okay, I'll go on to document the workbench feature.

Right now, there's only one workbench visualizer: "p5 Visualizer Template", also added in this update.

katestange commented 2 months ago

I just tried to run it and got an error. Not sure if this is helpful:

Error: Cannot find module '@vue/tsconfig/tsconfig.dom.json'
Require stack:
- /home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/@volar/vue-typescript/out/utils/ts.js
- /home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/@volar/vue-typescript/out/index.js
- /home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/vue-tsc/out/proxy.js
- /home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/typescript/lib/tsc.js
- /home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/vue-tsc/bin/vue-tsc.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1028:15)
    at Function.resolve (node:internal/modules/cjs/helpers:125:19)
    at createParsedCommandLine (/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/@volar/vue-typescript/out/utils/ts.js:16:41)
    at Object.createParsedCommandLine (/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/@volar/vue-typescript/out/utils/ts.js:18:34)
    at getVueCompilerOptions (/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/vue-tsc/out/proxy.js:63:39)
    at Object.createProgramProxy (/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/vue-tsc/out/proxy.js:19:36)
    at Object.createProgram (/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/typescript/lib/tsc.js:93637:238)
    at performCompilation (/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/typescript/lib/tsc.js:101972:26)
    at executeCommandLineWorker (/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/typescript/lib/tsc.js:101857:17)
    at Object.executeCommandLine (/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/typescript/lib/tsc.js:101902:20) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/@volar/vue-typescript/out/utils/ts.js',
    '/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/@volar/vue-typescript/out/index.js',
    '/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/vue-tsc/out/proxy.js',
    '/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/typescript/lib/tsc.js',
    '/home/katestange/data/projects/numberscope/frontscope-backscope/frontscope/node_modules/vue-tsc/bin/vue-tsc.js'
  ]
}
gwhitney commented 2 months ago

@katestange you forgot to npm install

gwhitney commented 2 months ago

@Vectornaut given the amount of feedback here I am going to forge ahead with the dependabot updates, so you will have to merge again. Really sorry, but we are under the gun. :-/

katestange commented 2 months ago

@katestange you forgot to npm install

Thanks! (duh) It works as advertised on my machine. The simple visualizer of just showing the terms is a nice choice.

gwhitney commented 2 months ago

The keypresses all worked?

katestange commented 2 months ago

The keypresses all worked?

Indeed, yes, all three.

gwhitney commented 2 months ago

Changed to draft because I believe there is more to come, and it will have to be rebased once #297 lands anyway. @Vectornaut please remove the draft designation when you feel it is ready for further review.

Vectornaut commented 2 months ago

I've reorganized and revised the instructions for how to build a visualizer. My main goals were:

Changes that especially need feedback

Since our convention is to call super.draw() at the beginning of the draw() function, it's effectively a default background, and I've described it that way in the documentation. If we accept that description, we'll have to make sure that P5Visualizer.draw() never has side effects, but I think that's a reasonable restriction. On this principle, I've removed super.draw() from the Differences visualizer, which draws its own background.

Why does Differences implement inhabit(), instead of doing its sequence-specific consistency checks in setup()? More generally, what kinds of code should go in inhabit() rather than setup()? I have the feeling that a visualizer should only implement inhabit() if it needs access to the element it's inhabiting.

The previous revision said that when constructing a VisualizerExportModule, "[y]ou can also reference the name of the visualizer to maintain consistency". However, when I tried it, passing P5VisualizerTemplate.name to the constructor gave me the name "P5VisualizerTemplate" instead of the value I actually set name to.

gwhitney commented 2 months ago

I haven't had a chance to look at what you wrote yet, but here is my two cents on the three items you raised in particular:

(A)

Since our convention is to call super.draw() at the beginning of the draw() function, it's effectively a default background, and I've described it that way in the documentation. If we accept that description, we'll have to make sure that P5Visualizer.draw() never has side effects, but I think that's a reasonable restriction. On this principle, I've removed super.draw() from the Differences visualizer, which draws its own background.

Since there was boilerplate setup, I imagined there might be boilerplate draw code (e.g, p5 itself maintains a frame count; maybe P5Visualizer would eventually have some sort of housekeeping it wanted to do on every draw().) If you feel that is super unlikely, then we could make draw() an empty abstract method that must be implemented (with no super.draw()) in order for a visualizer class to be instantiable. In this scheme, for example, a SquareVisualizer would have no draw, indicating that it is solely a baseclass that visualizers who want a square canvas only can build on.

(B)

Why does Differences implement inhabit(), instead of doing its sequence-specific consistency checks in setup()? More generally, what kinds of code should go in inhabit() rather than setup()? I have the feeling that a visualizer should only implement inhabit() if it needs access to the element it's inhabiting.

Yes well, in the prior design, visualizer had initialize() and setup(), and there was a similar confusion, but in practice the convention was things that did not need access to the sketch were done in initialize and things that did in setup. Now inhabit implicitly calls setup, so the distinction has become even blurrier. But the fact is, setup is a p5 method and inhabit is an underlying visualizer method, so it might make organizational sense to use the same division as before. Certainly it is still the case that anything that needs the sketch must be in setup. So the question is, where do we want to promote rank-and-file visualizers doing other startup type things that don't need the sketch? Inhabit() or setup()? I don't see much to choose between them... but yes, we don't want this to be a confusing point.

There's one other thing I am worried about: with a click-free, parameters-modified-on-the-fly UI like we want, there will be a distinction between restarting a visualizer and departing/reinhabiting it, that doesn't exist now. For example, imagine changing the stroke color of a Turtle visualizer in progress. Does that just make the rest of the path (from where the turtle currently was) the new color, or does it erase everything, and go back to the start location and start drawing from the first term again with the new color? Conceptually I would like there to be the option of visualizers that can be altered midstream. But then that raises the question of who decides? Is it purely internal to the visualizer, or can the Vue app tell a visualizer to "take it from the top"? If so, there needs to be a visualizer method that corresponds to this directive, and then there will be a very practical distinction between one-time prep and stuff that needs to be done every time you take it from the top. When I started with numberscope, I presumed that setup() was the "take it from the top" method, but no, p5 is very clear that setup is to be called once in the lifetime of a sketch. So that blurs the distinction between inhabit and setup, and it means we will at some point soon likely need a third method for "take it from the top".

I guess I am OK with, for p5-based visualizers, saying that any startup stuff that doesn't have to do with the DOM should be in setup(), and modifying all existing visualizers that way. If that seems like the best plan, you could document it that way in this PR and change Differences to conform (so it would have no inhabit method, I think think), and then in a second PR we could conform all the others. I don't think this PR should be altering visualizers across the board. Let me know your thinking on (B) in light of all the above background and discussion.

(C)

The previous revision said that when constructing a VisualizerExportModule, "[y]ou can also reference the name of the visualizer to maintain consistency". However, when I tried it, passing P5VisualizerTemplate.name to the constructor gave me the name "P5VisualizerTemplate" instead of the value I actually set name to.

Yeah this is mysterious to me, too. It has just been left alone since before I came on the scene, since I never really understood what's going on here with these comments. But if we are doing a cleanup that extends to this, then I would love as part of this PR to remove the redundancy between name in the visualizer class and in the exportModule. It's not DRY. Thoughts on how to do so?

gwhitney commented 2 months ago

OK, Aaron and I had an in-depth discussion today and we reached the following conclusions on (A) and (B) above:

(A) Since there already is a boilerplate wrapper around the draw method, there will never be a need for a common P5Visualizer.draw(). Therefore, we will make it abstract, and hence required to be implemented in all instantiable derived classes.

(B) Since setup() is the designated initialization place for p5 sketches, we will adopt the convention that any startup code that does not need to deal with the DOM directly or the call to new p5 itself should be in setup() rather than inhabit. We expect actual visualizers will rarely need to implement their own inhabit() method as a result.

I am about to submit a PR making these changes. As a bonus, I will deal with (C) as well: make visualizer files DRY in only having their name in one place in the code.

gwhitney commented 2 months ago

OK, all of the streamlining we discussed on the VisualizerInterface/P5Visualizer is now submitted in PR #310. I think the best way forward is to merge that into main (so feel free to go ahead and review it and once you are satisfied, merge it), and then for you to rebuild this on top of the changes, tweaking your documentation (and template visualizer) to reflect the changes. But if you have another plan that you think would work better, just let us know.

gwhitney commented 2 months ago

Another question: Should the MouseTester visualizer from the discussion of #277 go into the workbench created in this PR? If so, in this PR or a subsequent one?

katestange commented 2 months ago

Another question: Should the MouseTester visualizer from the discussion of #277 go into the workbench created in this PR? If so, in this PR or a subsequent one?

I think that's a good idea, but priority isn't high, so I don't have a strong opinion when. And another issue to request that the MouseTester be expanded to show each type of interaction even, if anyone were to find that useful someday.

katestange commented 2 months ago

I think that's a good idea, but priority isn't high, so I don't have a strong opinion when. And another issue to request that the MouseTester be expanded to show each type of interaction even, if anyone were to find that useful someday.

Maybe EventTester would be a better name, or something like that.

gwhitney commented 2 months ago

Great then, for expediency, once this is merged let's just file an issue to add a visualizer into the workbench that exercises every type of interaction.

Vectornaut commented 2 months ago

I think this is ready to go!

gwhitney commented 2 months ago

Sorry about the inundation of comments, but, well, introductory templates and guides are I think crucial bits of making a system accessible and successful. I think I've gotten through all the material for now. It's really shaping up, and I think it behooves us to try to hone it as much as possible. Thanks!

gwhitney commented 2 months ago

[An aside re: recommended git practices: I understand you prefer merge, and we can have a fuller discussion another time. Our existing docs do recommend merge. But clearly you are doing something different and better than what they say, or at least different and better than what prior students were doing in practice based on what they say. Specifically, this PR is now a good example of a PR with an extended lifetime, going through multiple cycles of revision and having to adapt to multiple changes underneath itself. But your commit history is only becoming "linearly cluttered" with merge commits, i.e., there are something like four "merge main into p5_template" commits. The students' commit histories were routinely becoming quadratically cluttered, with numerous reiterated merges of their own earlier commits. It got to a point in a few cases that we had to have students grab their current working files, stuff them somewhere outside of git, pull main and create a new empty branch on top of it, and then just paste in all their working files, creating a new PR with just a single commit of everything so far, and then abandon their original PR. But at least that isn't happening under your git habits. So at the very least, if we decide to stick with merge as the recommended workflow, we will have to have you look over our git-use doc pages and see if your work habits diverge with them at any point that might explain why your clutter level is distinctly lower.

For me, the charm of the "rebase" workflow is that it maintains a zero-clutter PR: at all times, the commits you see in the PR are exactly the successive changes made as part of the PR's effort.]

Vectornaut commented 2 months ago

I think I've addressed all the comments except the ones on the visualizer-building guide. While I work on the guide, could you review the other changes? Sorry about the time pressure! (@gwhitney @katestange)

katestange commented 2 months ago

The "down" arrow key isn't working in the Entries visualizer.

katestange commented 2 months ago

The doc http://localhost:5050/doc/doc/onboarding/ should have a link to the new visualizer docs being made here.

katestange commented 2 months ago

When I do npm run doc:serve:workbench I get a slightly strange thing. It opens up to the main doc webpage with only one other item in the lefthand menu, which is the Entries visualizer. When I click on that, I get that (good) but then there's no way to go back to the main doc webpage (I'm stuck there forever). In the numberscope tool workbench, the other visualizers are there, just the workbench ones are additionally listed first. Should it not be the same in the doc workbench? Meaning all the regular docs are there, but the workbench visualizers are also shown at the top of the visualizer list?

katestange commented 2 months ago

Also on the Entries doc page, the down arrow key is not listed under controls. BTW, I approve of 1729.

Vectornaut commented 2 months ago

The "down" arrow key isn't working in the Entries visualizer.

I removed it to simplify the example! Nice to see that it's gone, as intended.

Vectornaut commented 2 months ago

When I do npm run doc:serve:workbench [... and] I click on [the Entries visualizer page] there's no way to go back to the main doc webpage

I've added the "Overview" page to the navigation bar in workbench mode. Is that the page you're trying to get back to?

In the numberscope tool workbench, the other visualizers are there, just the workbench ones are additionally listed first. Should it not be the same in the doc workbench? Meaning all the regular docs are there, but the workbench visualizers are also shown at the top of the visualizer list?

I'd like to do this eventually, but I couldn't figure out a quick way to do it through mkdocs configuration inheritance.

Vectornaut commented 2 months ago

All right, I think this is ready for review again. Thanks for poring so carefully over all the changes this PR has made. (@katestange @gwhitney)

I changed the interface of the template visualizer to make the code simpler and more informative. I think the interface came out more elegant and informative too.

katestange commented 2 months ago

I've added the "Overview" page to the navigation bar in workbench mode. Is that the page you're trying to get back to?

I don't see "Overview" (I don't see any change despite pulling), but I realize now I can get back to the main doc page by clicking "Documentation" in the header. Here are the two things I can access when running npm run doc:serve:workbench, shown here:

Screenshot from 2024-04-24 09-10-56

Screenshot from 2024-04-24 09-12-13

In the numberscope tool workbench, the other visualizers are there, just the workbench ones are additionally listed first. Should it not be the same in the doc workbench? Meaning all the regular docs are there, but the workbench visualizers are also shown at the top of the visualizer list?

I'd like to do this eventually, but I couldn't figure out a quick way to do it through mkdocs configuration inheritance.

That's fine, in the interests of time I'm totally happy to merge this as is and file an issue. But I think it makes sense for doc:serve:workbench to be a superset of doc:serve.

In a separate note, however, when you click on the image on the Entries visualizer doc page (the big 1729) it opens up the wrong image.

katestange commented 2 months ago

Emojis not working here: http://127.0.0.1:8000/doc/doc/making-a-visualizer/ Screenshot from 2024-04-24 09-17-31

katestange commented 2 months ago

Thank you Vectornaut for all your hard work! This is a huge review process, this one. :)

gwhitney commented 2 months ago

All right, I think this is ready for review again. Thanks for poring so carefully over all the changes this PR has made. (@katestange @gwhitney)

I changed the interface of the template visualizer to make the code simpler and more informative. I think the interface came out more elegant and informative too.

Hmm, did you perhaps forget to push your latest commits? I am not seeing anything different than when I wrapped up last night, and there are the same number of commits listed in this PR (25) as then, and the last commit shown here is "avoid linter conflict (de232f8)" which is the same as the top commit in git log on the copy I pulled around the time of our meeting last night. So however it happened, I think we're not seeing your last batch of work.

Vectornaut commented 2 months ago

Hmm, did you perhaps forget to push your latest commits?

Yes, I did. Should be up to date now! (@katestange @gwhitney)

Vectornaut commented 2 months ago

I don't see "Overview" (I don't see any change despite pulling)

Whoops, this was in one of the commits I forgot to push. It should be there now.

I don't see anywhere that the user is instructed to create markdown documentation for the visualizer. Am I missing it?

No, I didn't put any explicit instructions. This should definitely go in the visualizer-building guide, but I feel like it might clutter the template code itself, since docblocks and regular comments aren't very visually distinct in most syntax coloring systems. Any suggestions on where to put this in the visualizer-building code? I've added a sketch of where these instructions could go in the visualizer-building guide.

katestange commented 2 months ago

Whoops, this was in one of the commits I forgot to push. It should be there now.

Got it

No, I didn't put any explicit instructions. This should definitely go in the visualizer-building guide, but I feel like it might clutter the template code itself, since docblocks and regular comments aren't very visually distinct in most syntax coloring systems. ~Any suggestions on where to put this in the visualizer-building code?~ I've added a sketch of where these instructions could go in the visualizer-building guide.

I was thinking about this, and I agree it should go in the guide and not in the template code. You put it at the top there, and that seems fine to me. I gather you will expand it a little.

katestange commented 2 months ago

You've added a cool slider, which is visually appealing. You didn't document it, however, in the visualizer description -- would be good to do. Especially since I tried to grab it with my mouse (it doesn't work that way). I gather it works on one of those exponential scales like the "installation" completion bars you see in windows installers. ;)

gwhitney commented 2 months ago

Especially since I tried to grab it with my mouse (it doesn't work that way).

I was worried about this, but I hadn't had a chance to try it yet. I would say having something that looks like a control but actually isn't is a "UI gotcha" that we should start trying to avoid in general, so I am pretty reluctant to model it in the template. I know you could re-code the template visualizer to allow the slider to work as a control, but I think that would make the template too complicated for its primary purpose. So I would strongly recommend some other display of the location in the sequence that does not at all appear to be a control. For example, a display that looks like a typical "progress bar" instead of a slider would, I think, be something that people would not expect to be able to manipulate.

gwhitney commented 2 months ago

FYI I am working on a commit so that run doc:serve:workbench will be just like doc:serve but with the workbench visualizers at the top of the user guide list. It is almost ready. Let me know when a good time to push it to your branch will be.

gwhitney commented 2 months ago

OK, having heard nothing, I just went ahead and pushed it. Please pull your branch from your fork to your working clone asap, thanks.

gwhitney commented 2 months ago

Should it not be the same in the doc workbench? Meaning all the regular docs are there, but the workbench visualizers are also shown at the top of the visualizer list?

@katestange I believe I accomplished this, please pull and give it a try, thanks!

gwhitney commented 2 months ago

In a separate note, however, when you click on the image on the Entries visualizer doc page (the big 1729) it opens up the wrong image.

This now appears to work correctly for me. Is it working now for you, too, Kate, after a pull?

gwhitney commented 2 months ago

Emojis not working here: http://127.0.0.1:8000/doc/doc/making-a-visualizer/

Yeah, all I see is :key: too, not :key: . But, ah, if I reorganize the markdown extensions block in mkdocs.yml like so:

markdown_extensions:
    - mdx_math
    - pymdownx.emoji
    - pymdownx.superfences

then images appear - but they're huge (see the screenshot below). Please see if there is a way to either (a) control the size of the emojis with pymdownx.emoji; or (b) simply insert the Unicode characters for the desired emojis into the markdown file instead of using markdown emoji -- presumably then they will be normal-character sized. Or use text colors instead of emojis in the headings, like green for required, yellow for often, and red for advanced (you don't have to worry about color blindness because the information is reiterated in the parenthetical italicized text labels). In fact, you could color just those labels. Screenshot_2024-04-24_13-30-04

gwhitney commented 2 months ago

OK, once again, I think I have gotten through all open items and looked at the new stuff since the last batch, so I think it's back over to you, @Vectornaut, but let me know if you need a hand. I really think we should try to put this to bed tonight, so to speak.

katestange commented 2 months ago

The workbench docs are weird. Here's my screenshot. The Chaos vis has a + that doesn't do anything, and the Entries visualizer is under "Src" for no reason. Screenshot from 2024-04-24 15-50-17

gwhitney commented 2 months ago

The Chaos vis has a + that doesn't do anything, and the Entries visualizer is under "Src" for no reason.

Yeah, that's how they look for me, too. I am not really sure why and didn't want to spend a lot of time tracking it down. Also because I didn't really mind, in that (A) this is just the "workbench" visualizer, not the real one, and (B) the funny treatment of the workbench ones definitely helps you find them in the navigator bar, which is kind of good because those are the ones you are likely to be focused on when you are using help:doc:workbench.

However, if you feel it is important that the workbench docs look as polished as the real ones, just let me know and I will track down what weird thing is going on and fix it.

Vectornaut commented 2 months ago

In a separate note, however, when you click on the image on the Entries visualizer doc page (the big 1729) it opens up the wrong image.

Whoops! Fixed.

katestange commented 2 months ago

The Chaos vis has a + that doesn't do anything, and the Entries visualizer is under "Src" for no reason.

Yeah, that's how they look for me, too. I am not really sure why and didn't want to spend a lot of time tracking it down. Also because I didn't really mind, in that (A) this is just the "workbench" visualizer, not the real one, and (B) the funny treatment of the workbench ones definitely helps you find them in the navigator bar, which is kind of good because those are the ones you are likely to be focused on when you are using help:doc:workbench.

However, if you feel it is important that the workbench docs look as polished as the real ones, just let me know and I will track down what weird thing is going on and fix it.

I don't want to just make work for you, but I think it's a little broken looking, so it bugs me... and it may confuse people who think it's supposed to indicate something?

Vectornaut commented 2 months ago

if I reorganize the markdown extensions block in mkdocs.yml like so [...] then images appear - but they're huge

I switched the emoji in the builder's guide to unicode, and they now display property both on GitHub and in the doc page.

gwhitney commented 2 months ago

OK, I have pushed the fix to doc:serve:workbench; make sure to npm install when you have pulled it. Aaron asked for re-review, which I will do now. Oh and PS @Vectornaut, if it works for you please verify that the workbench docs now look OK (or just resolve the associated conversation), thanks.

gwhitney commented 2 months ago

OK, I can see at a glance that there are still numerous unresolved review items. @Vectornaut, I think you need to unhide all of the comments and then look through them for unresolved conversations and address those things -- at least that's my guess, that you are missing things because GitHub is hiding them for you because this PR discussion has become so long.

But in the meantime, I will go through everything to find ones where there has been action and resolve or comment further on those, and post again when that's done so that you can take it further from there.

gwhitney commented 2 months ago

The doc http://localhost:5050/doc/doc/onboarding/ should have a link to the new visualizer docs being made here.

This has not yet been addressed, probably because it is not in a "review conversation" that formally requires hitting a "resolve" button. (Not sure if there is a way to turn a random comment into such a conversation??) But nevertheless, it does require resolution.

gwhitney commented 2 months ago

I switched the emoji in the builder's guide to unicode, and they now display property both on GitHub and in the doc page.

Check. If this were one of those conversations, I'd resolve it.