Do you find it difficult to get started with a day of coding, or just to find inspiration to do anything at all? Two things generally work quite well for me:
Write some simple code in a language I already know.
Learn an advanced feature of a language I know, or a simple feature of a language I know less.
For 1) I pick a simple code exercise from any programming book, or make one up myself, and proceed to solve it entirely; the key here is that I know all the “ingredients” well, and just need to go through the motions. My go-to ones are usually Python or C exercises as simple as “sort an array” or “plot a chart with some data points”; just something to get me started with opening an IDE or vim, start typing some raw code, execute – then lather, rinse, repeat, until I'm happy with the results. It's usually a matter of minutes.
For 2) I pick a language feature I don't know too much about, a small one, and come up with an example program to make use of it. For example, it can be a Python module I do not often use, or a basic feature or module in a language I do not use every day (usually Clojure, Julia, or Prolog). The key here is to pick something easy to learn about, and make something out of it.
I have a young friend who dreams of becoming a novelist, but who never seems to be able to complete his work.
According to him, his job keeps him too busy, and he can never find enough time to write novels, and that's why he can't complete work and enter it for writing awards. But is that the real reason?
No! It's actually that he wants to leave the possibility of “I can do it if I try” open, by not committing to anything. He doesn't want to expose his work to criticism, and he certainly doesn't want to face the reality that he might produce an inferior piece of writing and face rejection.
He wants to live inside that realm of possibilities, where he can say that he could do it if he only had the time, or that he could write if he just had the proper environment, and that he really does have the talent for it. In another five or ten years, he will probably start using another excuses like “I'm not young anymore” or “I've got a family to think about now”.
This is a quote from The Courage to Be Disliked by Ichiro Kishimi. The part on the “realm of possibilities” strikes particularly close: in this realm, you can be as great as you think you are for as long as you want – there is no effort to spend in making plans, and no chance of failing.
A couple days ago I opened a new board game I got as a present for Christmas, to play with some friends. It looked very promising, so we took all the pieces out of the box and I started going through the instructions.
As I was reading, a paragraph mentioned a difference between a 2-player game and a 3+-player game, which I thought would be the only difference (in many games you just deal a different number of cards, or you remove some special cards, and so on). The problem is that the following sections all assumed a 3+-player game, but it was never clear until the very end, when a clearly-marked paragraph stated how each of the preceding sections would be different in a 2-player game. This was frustrating, because it meant I had to read the whole manual before being able to play correctly.
This is not good design, and it's true for game instructions as well as technical docs.
After taking a look at both PyQtGraph and VisPy, I started to think about alternative 3D libraries mainly for two reasons:
I use Jupyter Notebooks way more than standalone apps for data visualization, so I'd prefer a library that integrates well with notebooks.
I would prefer well-maintained libraries, and VisPy's main maintainer has issued a call for help to continue supporting the project. Furthermore, there are not many references to any of the two libraries when looking for Python 3D libraries.
A few alternatives I have found:
Mayavi, which I already mentioned in another post.
“When you do things right, people won't be sure you've done anything at all.”
In the Futurama episode where Bender meets God, this quote is from God itself: it means that God's intervention in human life should be light-touch. I take it to mean: when you do something the way it's supposed to be done, the best possible way, nobody will notice because it will just seem part of the “natural order” of things. In other words: doing things wrong is immediately noticeable, while the contrary is not.
Although I wholeheartedly agree when I think of this quote, I can't help but think: Doesn't this leave you in the shadow of someone else who does the right thing but goes out of their way to let the world know?
I've decided to try VisPy by adapting my previous PyQtGraph example. In the process I have figured out something I got wrong about the update function: I thought the loop that updates the points for the scatterplot had to be inside the update, and this works with PyQtGraph but doesn't with VisPy. (A GitHub Issue gave me the idea.) This brought me to reconsider the role of update as a function that should include the changes to data as a timer-controlled operation too. In other words, there should not be a loop inside update; rather, the loop (or the condition) variable has to be updated inside but declared outside.
Beside this important realization (which I would have probably come across had I read more about Qt and timers), for this use case I haven't seen any big differences between VisPy and PyQtGraph except that VisPy has an easier API to work with, for example:
The main application in VisPy can just be imported from the main module with from vispy import app.
Views are added to a SceneCanvas in VisPy.
There are no specific “GL widgets” in VisPy, so a PyQtGraph GLScatterPlotItem is just a Markers “visual element”.
There are no “Qt modules” in VisPy, so a QTimer from pyqtgraph.Qt.QtCore in PyQtGraph is just an app.Timer.
One of the experiments I did as part of the old project I have recently written about was about animating a 3D plot using OpenGL from PyQtGraph. The code was inspired pretty much to one of the PyQtGraph examples from its GitHub repository, where – for future memory – the main components are the following:
A Qt QApplication as the container Qt app.
A GLViewWidget as the main OpenGL view component.
A GLGridItem to visualize a grid (not essential).
A GLScatterPlotItem as the actual scatterplot graph.
A QTimer to repeatedly call an update function, which includes two actions:
setData to plot the data points
orbit to make the camera spin around the view center (neat!)
I've recently revisited the example to put everything in a class rather than relying on globals. I'll publish it at some point.
While looking again at some code I wrote quite some time ago to animate a graph with OpenGL in PyQtGraph, I learned that some OpenGL libraries (including PyQtGraph) still use the Fixed Function Pipeline. Apparently, VisPy is a good replacement as it is based on the more modern shaders instead.
I haven't looked at any other Python OpenGL packages yet, but I might give VisPy a try.
An aspect I liked about the wxPython toolkit I recently rediscovered is the separation of GUI design from GUI functionality implementation. This is achieved through the usage of XRC files, which are XML files describing the appearance of a GUI. XRC files can be created through XRC editors such as wxGlade, then imported in Python code with functions from the wx and wx.src modules.
I haven't been writing or using GUIs in Python for a while since I started using Jupyter Notebook, but I consider this kind of toolkits very useful for standalone applications not based on a browser (which, admittedly, may be less and less nowadays).
I have loved fractals since I first learned about them as a kid, thanks to my mother. At first I loved the colors and the variety of shapes, then the generative aspect (a simple formula can generate such a complex pattern!), and finally the math behind (complex numbers, non-linearity, fractal dimension, and so on).
The software I was using as a kid was called Winfract, the Windows version of Fractint, which was and is itself very flexible and feature-rich. I am very grateful to Fractint developers for having created such a great software, as when I first learned Python and NumPy more than 10 years ago, I attempted to replicate some of its features. This resulted in a lot of research on NumPy, GUIs, and graphics (including Matplotlib and OpenGL), some of which I mentioned in the previous post.
I am resurrecting and refurbishing this very old code, which I will make available soon. It is by no means a complete product, for which there are much more advanced solutions such as XaoS; it's more a collection of experiments. Yet, I am happy that, back then, I managed to replicate many of the formulae that Fractint provided, and also that I ventured into 3D data visualization and GUI design.