Seeking feedback: Python for creative coding

Hello all!

It’s been a little while since I last posted but I was the developer who started the fork which became Processing 4 and also the maintainer of the lesser known processing-geopoint. I’m still here as a maintainer but I’m seeking feedback on a new project.

Still have a lot of love for Processing and p5py but work increasingly needs a pure-python library which can operate not just on desktop but on web and inside Jupyter notebooks as well. We also found ourselves in situations needing something BSD licensed… Anyway, Sketching.py is an attempt at offering just one more option for the community where it helps.

Regardless, would love some early feedback. It is still in pre-alpha but hoping to hear from more folks about how best to nurture this forwards. Note the the API is different to support multiple platforms (web, desktop, etc) and “pure Python” execution.

Thanks,
Sam

4 Likes

Very cool project, Sam! I’ll experiment and share some notes. @hx2A @tushar55 @villares @tabreturn what do y’all think?

1 Like

@sampottinger , I like it! I can see the value of this Python library. What is the underlying mechanism for drawing? Is it creating an SVG canvas?

Can you talk a little bit more about your work’s need for a pure python library?

I might be able to help you out with some of py5’s design ideas to help make the API more similar to other Processing libraries. For example you can avoid needing to register the draw() function if the code in sketch.show() looks at the call stack and looks for a draw() function one level up.

2 Likes

Thank you very much @mcintyre and @hx2A! That is very kind of you to take a look and offer your thoughts.

underlying mechanism for drawing

It’s Canvas (CanvasRenderingContext2D) for web, Pygame for app (interactive desktop), and Pillow for static (static desktop and Jupyter). It only supports 2D (which probably wont change for the foreseeable future :sweat_smile:).

talk a little more about your work’s need

Yeah sorry I should have probably lead with that. The three big goals I had in mind:

Portable: In my work, things often iteratively prototype from Jupyter to desktop app to web (recent projects have supported both offline and online access). This adapter approach supports that entire journey without necessitating a (full) rewrite.

Agnostic: I don’t always control the environment. For example, cx_freeze executables, restricted Jupyter environments (like Juno or JupyterLite), and managed servers without privileges. Even in static-only hosting for web apps that cannot access public internet (which we do sometimes need to support), it can operate as a pure Python wheel via self-hosted pyscript without too much fuss.

Embeddable: I sometimes operate adjacent to code I didn’t originally write or may not fully control. So the solution shouldn’t assume anything about the rest of the code’s structure or licensing (we’ve had some situations where partners have good reason for BSD / MIT).

Of course, Python is the Lingua franca in my area so, though I really love Java, putting it into Python allows more of my collaborators to participate.

I might be able to help you out with some of py5’s design ideas

Yes! Please let me know what you think!

For example you can avoid needing to register the draw() function

Thank you! Yeah, I noticed that py5 did that. Due to that “embeddable” objective, I wonder if I might have to have the user opt in by having them call a different method to avoid some accidents but I really like the immediacy you are able to achieve. I’ll take a look around at some options and see what folks think internally! Thanks again!

1 Like

@sampottinger these are great goals! My immediate thought when I saw the reference was “Why is the API so different?”

I’ve wound re-implementing py5’s API twice, more or less. The Raspberry Pi Foundation did too, so I think there’s something to it. Here are my projects:

  • ipycc is a wrapper around ipycanvas. I made it for my K–12 math and data science students. It’s nice being able to point them to a JupyterLite notebook to start sketching/visualizing.
  • proceso is my first attempt to bridge PyScript and p5.js. A design goal is to make the package work seamlessly with both Pyodide (ecosystem) and MicroPython (efficiency).

The MicroPython option excites me because it requires less data transfer and is generally faster than Pyodide. Those features combine for a better user experience, especially in a classroom full of modest Chromebooks. They also wind up being more carbon efficient, which matters to me. MicroPython just fixed a memory bug that should enable the new implementation I’m testing.

At a very high level, what do people think about coordinating a bit on API design? No need for something like POSIX, but it’d be nice to smooth out learning curves and make sketches (mostly) interoperable.

2 Likes

So the renderer changes based on the environment, but provides the same API for all? That is convenient for the end-users and I think it will work well if you can get consistent results across environments. Trying achieve that same standard for a 3D renderer would a serious undertaking. I am currently building a new 3D renderer right now, and I can tell you getting it to work in just one place is a lot of work!

That’s a good compromise. py5’s run_sketch() method also has a sketch_functions parameter, letting you pass a dictionary of functions. I thought there would be times py5’s scheme of inspecting the call stack wouldn’t work quite right and wanted to provide an alternative, but in actual practice, the sketch_functions parameter is rarely necessary.

2 Likes

Very cool, @sampottinger!

I guess I’ll need to update my table at GitHub - villares/Resources-for-teaching-programming: Resources for teaching programming for artists, designers and architects :smiley:

Being able to use the drawing function names on the global namespace helps teaching… even if later people end up liking the freedom from name clashes of using a dot-prefix. Anyway, if you can’t avoid the prefix, how about spy. or sk., as in import sketching as sk for your examples?

Another thing, do you have plans for SVG output? I miss it both in pygame and in pyodide based pyp5js. Teaching in non-formal learning settings, going from drawing to graphic design an then to digital fabrication (Laser cutting, CNC, 3D printing) is something I tap into a lot, and in that case, vector graphics is a must.

2 Likes

Very much appreciate that @mcintyre!

  • Micropython: Thank you for that suggestion! I’ve been watching pyscript’s work on this but it didn’t quite make their latest release. Hopefully the next one will get it and I’ll change the default. I’ll open an enhancement ticket to keep an eye on this! :confetti_ball:
  • API differences: In addition to bridging desktop to web (get_csv / get_json) and helping support different platforms’ capabilities (sound, joystick, etc), some choices (draw_arc vs arc) are pedagogical to use “nouns and verbs” OOP consistent with teaching materials (Python precedence: Cornel, Boston, matplotlib, tkinter, community). I’ve discussed this a bit more in our conventions doc. I’m curious your thoughts as an educator though! Please LMK what you think and thanks. :slight_smile:
  • API standards: I may be interested in an adapter to a standard. LMK if you would be interested in discussing further!
  • ipycc and proceso: Super cool! Thank you for sharing.
2 Likes

Thanks @hx2A!

  • Renderer: That’s right! Adapters (desktop, web, static / jupyter) all conform to the same API. In addition to explicit renderers like Sketch2DWeb, it will try to infer the environment when using Sketch2D.
  • 3D: It’s hard! :sweat_smile: However, I do want to cheer you on in your efforts there. I thought it was already supported in py5. If I may ask, what are you changing? Excited for you!
  • Call stack inspection: I was a little worried about reliability but your note is giving me confidence. Reading the official docs, this seems like a common inspect use case. Thank you so much :partying_face:! Opening an enhancement proposal. Will take this to some folks at work.
1 Like

Really appreciate that @villares!

  • Update table: That’s very kind thank you!
  • SVG: Excellent suggestion. Opening an enhancement ticket. Thank you very much :tada:!
  • Wildcard imports: I’d love your further perspective if you are willing. I may have misunderstood but are you suggesting a wildcard import? They are discouraged by PEP8 and disallowed by some style guides. I’m curious your thoughts from teaching though.
  • Sketch class: Alternatively are you suggesting having drawing methods as top level functions outside a class? In addition to allowing multiple sketches per program (multiple canvases per page for example), the class approach reflects “nouns and verbs” OOP to better fit and common curricula components. This is further discussed in our conventions doc. I would love your perspective as an educator though. What do you think? Thank you!
1 Like

Yes this is an interesting and complex discussion… Processing for 20 years has allowed us to start teaching without OO and with drawing function names on the global namespace, like imperative/structured first, and then you can introduce OO later. This can also be a good fit for Python, people start with structured scripts before the need to define a class. There is this ‘Cognitive Load Theory’ idea that you should reduce introductions to essentials (“scafolding”), to make them more manageable etc. So, in my experience, less typing, less symbols, helps beginners (and Python usually goes on that direction).

Comparing how other tools do it

  • Processing Python mode (sadly dead) … all drawing function names and system variables on global namespace (same as Processing Java, p5js and pyp5js);
  • p5py went for wildcard imports (as you mentioned, it is discouraged and can be trouble etc.);
  • py5 different modes: “imported mode” (using a sketch_runner tool or a Thonny IDE plugin) for beginners, single sketch/canvas, global names; “module mode” with import py5, “class mode” more advanced, for multiple sketches etc… The Five py5 Modes — py5 documentation

I find most “OO upfront” CS curriculums (like the International Baccalaureate, which pushes Java) very problematic. But mind you, I’m an activist for teaching programming for people who might not want become professional programmers, so my inspirations are Code As Creative Medium or if you want something more formal Guzdial’s Media Computation Course.

3 Likes

Thanks @villares! I really appreciate you walking through this.

I apologize for taking more of your time but I’m curious if you have thoughts on some of the OOP-centric creative coding options that were developed for education? I’m thinking of Alice and stagecast (RIP) or even game maker? It seems they have had fairly good research-based outcomes. I’ve used some to some success.

I should acknowledge that I feel a little weird making the counter argument because I’ve been contributing to the Processing codebase for years and, specifically, did a lot of work on the preproc which enables Processing to put those methods into global namespace for Java mode. Anyway, I really respect and thank you for sharing your thoughts on this. I will chat with some colleagues who are helping guide the design of the API and make a final decision in a bit. All that said, I feel torn:

  • Similar to strings and files being objects in Python, many of Sketching’s methods return objects for things like images and joysticks as a necessary part of OOP patterns to achieve uniformity across web, desktop, notebook, etc so users would encounter objects fairly quickly regardless of if they are in global namespace.
  • Not that it should in any way dissuade its use in educational settings, I worry PEP8 discourages wildcard imports because it pollutes global namespace (“make it unclear which names are present in the namespace, confusing both readers and many automated tools”). So I’m not sure if my putting Sketching’s members there is compliant regardless of mechanism and the project will be going into some professional spaces where those criticisms could be more likely or could impact adoption. Perhaps this is avoidable if optional though.

Regardless, I know this is a bigger debate and I don’t think we will settle it here :sweat_smile: - I’ll leave that to College Board to fight over. I think the question for Sketching is how to balance its objectives and how it can be additive to the Python ecosystem that exists today. Thank you again very much for your time and thoughts! No matter what, I hope to get you that SVG support soon :smiley:

Happy New Year!

1 Like

Hey @villares! Thank you again for your input. After some thought I think I will propose using the (still in development) online editor to resolve this. My hope is to have an optional mode where these get placed into global through preprocessing. I think that may help achieve the balance we are looking for. What do you think of that? Thanks again for all of your help! This could have a CLI equivalent as well though the editor will be a PWA so one could install it for offline use either way.

EDIT: that also has the nifty benefit that one can convert from this global to OOP mode to see how the code would change in adopting object orientation.

2 Likes

Happy New Year!

I’m really interested in this discussion, my ongoing PhD is about teaching programming, but I don’t have any definitive answer. I thank you for the opportunity to think and talk about it.

I’m not sure about the names in global namespace, I also worry about the namespace pollution, I have heard conflicting things from students. I think having it helps to reduce cognitive load for beginners, but as they progress they want to know “what is from Python vs. what is from this drawing library?”. So I see benefits from it being optional/gradual.

Then, it worries me a lot that expectations from professional programmers can spoil completely the educational experience of beginners. I’ve seen people wanting to impose type annotation discipline to exploratory coding by beginners and it is madness.

I think maybe we can decouple the namespace discussion from the OO issue, and, I think OO can be presented in a “first consume, then produce” style. As it happens with Python generally, people start using lists, they learn the list .append() and some string methods before they can define classes, etc.

I find most of these OOP-centric tools have so much complexity upfront compared to Processing, even pygame, I find it very hard to use them in introductory classes. For me it is critical for the student to be able write 2-to-4 lines of code and see some result. And it gets more important on non-formal settings where I have to try and reach a very varied public, so it is Papert’s “low floor, high ceiling” challenge for tools, always.

How to balance the immediacy of something like Bernardo’s py5pjs (here adapted to have the same function names as py5) and teaching something more sophisticated like geopandas, shapely, trimesh, etc? I don’t know. And you are trying to make something for multiple platforms/backends… it is very hard.

Another lineage of tools to study is Just van Rossum’s DrawBot, and relatives (nodebox/shoebot). They have a slightly different API. Then, I wish we could all collaborate and focus energy in a smaller set of tools/APIs, so it becomes easier to adapt examples,etc (maybe a Processing bias).

Sorry to take your time blurting these half-cooked impressions! Cheers!

3 Likes

Hey @villares! Once again, I appreciate all of your input on this. Before we finished up, I did want to get your perspective on my editor mode proposal. When activated, it would turn this:

sketch.draw_ellipse(250, 250, 100, 100)

To simply:

draw_ellipse(250, 250, 100, 100)

It feels like it accomplishes a number of the goals:

  • For those taking this approach, students can draw with a single line of code so no import statement and no need to consume objects.
  • The mode is optional so teachers can choose when to introduce the concept of namespaces and objects within the context of their specific instruction.
  • It is, unfortunately, unavoidable that some functionality will require using an object but this isn’t dissimilar to files being an object in Python or even PImage in Processing.
  • The OOP interface is still maintained and the goals for nouns / verbs OOP are still respected. This also supports folks who are using Sketching outside an educational setting where their style guide / employer / community demands it.
  • Sketching’s documentation already acknowledges that users will need to consume objects but it explicitly makes it a goal that the library can be leveraged without requiring that users define their own classes

What do you think?

Finally, I don’t want to get too far into this but I just gently want to say that I work at a university and collaborate with lots of different kinds of academic groups with different backgrounds and skillsets. Even just in the last month, there’s been a project that lent itself better to D3 while another fit better in Processing. I think both were really successful and I think supported those different partners in the right way! Sometimes it’s also not my choice… I’ve been in situations where Processing couldn’t be used in production code because it violated style guides. So, I’m thankful that I have access to different approaches (pygame, processing, p5, d3, raphael, chartjs, straight to canvas, tk, etc) as different options better support different circumstances. I don’t feel like D3 existing hurts Processing for example but both are important for data visualization.

2 Likes

Also I realize I had a great conversation going with @villares but @mcintyre and @hx2A I want to make sure I addressed your thoughts as well. LMK if you have other comments on message 8 and message 9. Thanks everyone!

1 Like

Yeah, this makes total sense! Go for it.

PS: A side note on your conversation about 3D on py5, it supports 3D already via Processing 4 P3D/OpenGL, @hx2A is building a new 3D renderer suited for SVG & pen-plotting outputs. Maybe I’ll try a bit of Ursina, based on Panda3D, this year :wink:

Yes! Thank you, @villares, for for saying that. the Processing’s P3D renderer works just fine with py5. Lately I have been experimenting with building new 2D and 3D renderers with SVG output. The 3D renderer is challenging but I’m learning a lot.

3 Likes
  • MicroPython: Cool to hear you’re considering defaulting to it on the web!

  • API differences: I can appreciate choosing the “nouns and verbs” peg to hang things on. That said, AP CS A isn’t the most helpful source of inspiration for beginner API design. I taught that class for a couple of years–it’s not great as a first course. For a few counterexamples, Matplotlib’s pyplot mode, D3, Bokeh, and Processing/p5.js use nouns such as arc(), circle(), and line(). The APIs generally feel cleaner. I’ve never seen the distinction between noun/verb trip up beginners learning to code in a visual context. It’s a good principle, but I’m not sure it’s relevant for that audience.

  • API standards: What do you think about designing a py5-ish adapter in the spirit of Matplotlib’s pyplot mode? Here’s how they frame it:

“In general, we suggest using the OO style, particularly for complicated plots, and functions and scripts that are intended to be reused as part of a larger project. However, the pyplot style can be very convenient for quick interactive work.”

I don’t want to take @villares out of context, but his note about collaborating on a smaller set of tools resonates. The distinction between D3 and Processing is pretty clear to me. Sketching and existing packages less so.

@sampottinger is there a technical reason you couldn’t swap pygame for Processing? If not, I’d love to hear your thoughts on bridging desktop (Processing/py5) and web (p5.js) with Sketching. I work pretty closely with the p5.js maintainers, so I’m biased here. Some benefits to that approach are library ecosystems, community, and free 3D renderers. I’d totally sign up to work on that project.

2 Likes

One advantage is that those have 3D. And If you don’t want the Java dependency you could use p5py as abackend maybe?