At this point, we're leaning towards making our own library to satisfy our purposes. We're still looking at other options though - hey, if you have one, feel free to suggest it :)
At this point, we're leaning towards making our own library to satisfy our purposes. We're still looking at other options though - hey, if you have one, feel free to suggest it :)
The insane stuff we teach in CS1 is why so many students choose other majors.
Sell your students on the magic of computers. Don't teach them arcane rules and formalisms. They'll learn that later, once they've been hooked.
Teaching ahead of the curve is a great way to confuse and bore the hell out of your students. This is why I hate intro CS education so much.
It sounds like you are hypothesizing that my students have a motivation problem and proposing that I use an intervention of "Selling students on the magic of computers". Based on survey data collected during my past few semesters, I do not believe that my students are disinterested in the subject. This is true at the beginning and end of my course - I cannot claim that my assignments and course design (some of which is particularly oriented towards making the students interested in CS) has a big impact here, but I do not think they are being hurt by that aspect of the course design. There are potentially motivational issues related to self-efficacy, community interaction/isolation, and help-seeking behavior. However, I don't think your proposed intervention would solve those problems.
Instead, I disagree that my CS1 here at the University of Delaware is not the place to discuss the topic of avoiding global mutable state. My curriculum has several learning objectives explicitly oriented around these topics (largely agreed by my colleagues) and I have several projects that I think can authentically justify their importance (particularly with regards to testing and getting enhanced compiler support). I have many anecdotal supports from friends in industry and my own experiences teaching upper division courses that students struggle with issues that can be solved by avoiding global mutable state where possible. Personally, Therefore, since CS1 is not an agreed upon well-defined subject, I think I am perfectly justified including it in my learning objectives, alongside many other important topics and objectives.
If you have demonstrable evidence relevant to my teaching context that teaching global state early could impact areas where my students have other known issues (either motivational or cognitive), then I'd be very happy to read up on those. However, for now, I am doubtful that teaching global state is a serious issue.
I was a "CS1" TA my throughout my entire undergraduate career (modulus my first semester), so this is something I have direct knowledge and frustration about.
One of the courses I oversaw comprised of mostly non-CS engineering majors, but the curriculum was the same as the CS-track students. These students were forced to learn in Java, force fed the dogma of object oriented design (cats and cows and animals that moo), and tested on arcane Java-specific errata that had little to do with getting core concepts across and actually being able to express thoughts and ideas in code.
People will naturally discover how to organize their code. They'll either read about it or find out in code review. I think a better time to broach this subject is in a "software engineering principles" or equivalent course.
It's the same rationale that general chemistry "CHEM1" is not the place to talk about iterative solutions for non-ideal gasses, molecular orbital theory, LCAO, chemical activity, or any of that organic business. You're introducing too much information too early on and without context. You wouldn't teach students dynamic programming or ER diagrams in CS1. The students barely know how to handle the basics and you're already telling them how to anticipate and solve complex future-them problems.
Give them Python and let them have fun. If they produce a dozen nested if statements and improper for loops, so be it. At least they're learning to express themselves. If and when you see your students hit the "global state is bad" problem in lab, then turn it into a 1:1 teaching moment. It'll have way more impact, and it won't distract them from the core foundational concepts.
I do a lot of interviewing and hiring now, and I see so many fresh-out-of-college grads that simply do not have the ability to analyze a problem and structure their thoughts in code. They might be able to pass a university exam, but they haven't spent enough time using programming concepts on their own time to let them sink in and become muscle memory.
I think the biggest discriminator for success is that good students spend their free time programming on hobby projects of interest. And the only way you engender a desire to do that is to get the students interested in programming in their spare time outside of the context of homework and projects. Make programming fun and relevant; make it something they can use to do fun self-directed projects. Such students will excel, and the only thing you have to change is their interest level and attitude.
"I want a CS degree and career" is quite different from "I want to write my own game or app or website". And I can tell when I interview candidates which ones spent more time actually programming.
In terms of global state, I don't see much of a distinction between Pygame Zero's globals and a god-singleton like `World`. Both feature large amounts of implicit state, just off by one layer of indirection. For the vast majority of games, it wouldn't make sense to have more than one `World`. You might want more than one game scene/level/etc. but that's distinct from the overall windowing system, graphics state, etc. which would be stored in `World`.
Their concerns are not specific to pygame. They are trying to teach their students to not have global state and are afraid that using pygame in its current form would undermine those teachings.
That'd be pretty odd naming, usually 'World' would own all your game objects and scene, but have no relation to the windowing system or swap chain.
Regardless though, I wouldn't make the windowing system or swap chain or d3dcontext global either, I mean all of that is literally designed to be wrapped into some object. (Well, the window requires some trickery, but it's still prettier than a global handle in the end.) There's really no reason for a game to have actually global state, even if most games are only going to need one window.
Obviously, global data is powerful and allows us to do a lot. I let my students define top-level functions and use them globally throughout their programs, and as you say the import mechanism also gives us useful constants and functions to be used anywhere. We talk about how great global constants are for this reason.
The problem is mutation. When you have global mutable state, it becomes difficult to reason about the program. Code written in one part of the program can cause issues hundreds of lines later even though they are seemingly unrelated. You can no longer easily write simple unit tests to confirm that your program works as intended. Global mutable state also frustrates my attempts to use program analysis to give enhanced autograded feedback.
As a concrete example early in the course, we use the Turtle library to define a bunch of functions to write letters, and then they use those functions to write out their names. Difficulty ensues when I ask them to swap definitions and reuse the functions. One kind of issue they encounter is the Turtle library's reliance on global state, which makes it difficult to reason about where the cursor should be after you call a function.
You are thinking about the World example, but what about when they make a list of Coin objects? With global state, they start encountering very mysterious bugs related to the shared coin instances. When its all contained within the World object being passed around, we can write more coherent unit tests to debug this kind of trouble. In a class of 150, it's helpful to give them mechanisms like that.
How does this change when functions accept big singletons like "World"? At some point you'd have to break it down into smaller objects - at which point you may as well introduce proper OO factoring and design.
I do see the point though - global state is easy to mutate by accident in a function that should otherwise not need to mutate global state (say, a function like "def apply_gravity(cur_velocity)" should not be able to accidentally change the gravitational constant or the object position).
The example with the Turtle library is an interesting one, but I'd argue the problem is that the function contracts are not fully defined, rather than a problem with global state. A function needs to clearly specify what state it expects and what state it will produce - whether that state is in the ether (global) or whether the state is explicitly provided as a big object. For example, a function to draw a letter might logically be expected to place the cursor at the right edge of the current character (facing right, say), so that another function can advance the x-position for the next character. If it's contractually specified then there shouldn't be an issue.
The `World` (which is based on the concept from Racket's Universe library) does indeed get broken down into smaller objects. We talk about how to do that too. The idea is to lead this naturally into more OO stuff next semester, but we talk for a while about how we can use dictionaries to structure data at least.
You can introduce subject as another execution environment like OS and keep globals-free "clean" code. Actually it's a great lesson.
Also you can give mind-bending article[1] as alternative study material.
[1] https://blog.cleancoder.com/uncle-bob/2015/07/01/TheLittleSi...
If the objective is to teach the benefits of avoiding global state, it may be more effective to pick a project type for which that is a correct design choice.
the same goal as pygame zero but with a very different approach.
and no WIDTH and HEIGHT variables...
https://github.com/CoderDojoZH/resources/blob/master/cards-p...
i really liked it, but i don't consider it a mature product i would use "in production".
because of our approach, we can't really adopt it until it's natively supported by a "package" like mu-editor or thonny
my conclusion was:
as a "senior" programmer, who grew up with procedural programming, i'm still "scared" about relying on annotations and async programming.
but, for kids coming from scratch and without much other experiences, i'm not sure that it will be a big stumbling stone.
they will simply "learn" it in a different way: at the beginning, programming is (mostly) black magic anyway : - )
it might be even easier for them to use play, than relying on the magic update() and draw() functions...
(and, no, i don't think it makes a big difference to call those function from a main loop like in pygame or having them implicit like in pygame zero)
probably, the biggest issue would be that the founding blocks of play do not match what the kids will learn in most python tutorials and books (they probably won't find any reference to async or annotations in most programming books for kids or even for beginners!)
all in all: i like play and i think it could be a good match if the focus is more on computer science topics...
in our case, the focus is on the kids having a good time on sunday afternoons and getting them to learn to be an (active) actor in front of their computer, not just a (passive) consumer. we are not too picky about the concepts : - )
It's not branded as an actual game framework, but it's based on OpenGL ES and that's pretty much what it is - I mean, even their first tutorial is a mini game https://kivy.org/doc/stable/tutorials/pong.html .