Pages

Sunday 10 January 2016

Intermediate level Python workshop.

I've got 7 days until the workshop. Man, I thought I could put a fair bit of time in and get some decent quality out of this workshop.

I have the feeling that this happens to teachers everywhere from all around the world.

 Basically, I'm part of the volunteer student organization (the same one from compass, right?), and I volunteered for one last workshop. Kind of a throwback to the old days. I kind of want to teach a final workshop, a really polished one, just to prove to myself that my teaching skills have progressed. Is that kind of selfish? I don't know. But I do want to make this workshop better than the ones I've taught before.

This is the workshop description:
Python can draw graphs, send emails, and even visit web pages for you! Learn to use Python to its fullest capacity.
I came up with this workshop idea to replace a crappy previous workshop idea (teach unix tools and regex to high school students? you've got to be joking). Let's see what we can make out of this!




----------------------

The workshop is an intermediate level workshop. That doesn't mean much different from a beginner workshop, though. The students most likely will need a tonne of revision, especially when you have to account for the variable skill quality in a high school workshop. It just means that you will be able to progress faster and move onto more advanced topics more quickly as the students pick up concepts.

Additionally, you'll be able to explain complex concepts with greater ease, since the students already have a kind of 'programming schema' in their minds that helps programming concepts make sense to them.

 One really important tenet of teaching these high school workshops is that you shouldn't assume any pre-requisite workshop. I've seen too many 'advanced-level' workshops that try to assume pre-requisite knowledge from the students, and they always have a few students who aren't able to keep up, and are left behind. Often, the content is too advanced and the entire class gets left behind. Not good.

No man left behind, a wise man once said.


First task of the day is to identify a suitable topic or set of topics that fit under the theme of the workshop. The premise behind the workshop is that the students are slightly more advanced than beginners, and they would be able to do far more powerful things with their programming.

My programming education principles center around producing the greatest results for minimal effort. For example, let's suppose you're teaching an intermediate level student web development. You could choose, as workshop presenters have in the past, to teach the students fucking Django so they can run webpages on Django.

This, as you know, is literally the worst idea anyone could have come up with for a workshop. The learning curve of Django, not to mention MVC, is absolutely ridiculous. The students would spend their time blindly following instructions and not knowing what is going on (Trust me. I tried learning Django and I had no idea what was going on either.) Even Flask is not much better.

The learning curve is not the worst part of this idea, however. Suppose that the students manage to keep up, and in 6 hours they've completed their first Django project. What is the result they've obtained? Some crappy-looking webpage which lets you create an account, login, and post to a forum  or something. Worse, everyone has the same project because there is no creativity involved in following instructions. No one has any idea what is going on. Account creation isn't even cool! This isn't something you can show off to your friends.

The whole point of the web platform is so that other people can easily access your work and you can show people your website. What the hell are you going to get the students to do? Pay for a digitalocean account and teach them server management? Holy crap.

This is why you shouldn't have Django workshops, or Unix workshops, or Git workshops, or Flask workshops, or any of the litany of crappy workshop ideas people have implemented in the past.

For web development, teaching students to create static html pages is millions of times better. They're learning a tool that they can use to make their own creations, rather than blindly following python manage.py runserver or whatever. For advanced level, including basic javascript would launch each student into their own unique world with different possible behaviour. Finally, you can host it on Dropbox and give them a custom Kissr domain each so that it's easy to show off to their friends.

I don't understand. Seriously.


Going back onto topic, the idea behind my Python Power workshop was to leverage a high-level Python library to do cool things. If they could make an email bot, for example, to send them reminder emails, that would be really cool, and it's very customizable to each student. I wrote down a list of possible topics:

- Graph plotting/data visualization
- Email (sending or receiving)
- Web scraping (Google Maps, Youtube, Google Search, Google Dictionary, Google Images, Facebook, Twitter)
- Chat bot (facebook messenger?)
- Music generation
- Image generation (PIL?) Similar to mandelbrot
- Sentence generation

Discarded topics:
- Pygame (already covered in another workshop, risks overlap)
- Cryptography (results not impressive enough, not everyone is interested in code and maths)
- Chat client (networking too hard)
- Web server (don't want to turn this into advanced web dev)
- Scipy (functionality too advanced and mathematical)
- Date calculations with the datetime module (could integrate this into another topic. Too small otherwise)
- Image recognition/AI/Sympy (too complex. don't know what I was thinking)



I asked my friend about music generation. She gave a pretty good class a few months ago which I was listening to. She has this to say:
Composing? Most of the classical style follows the general rule of going from the tonic key to the dominant key Through progressions like I IV V I for example
Thanks Haohang. I have no idea what that means, but I'll do my best.

Man, these topics are all pretty good. I don't know what to do. I think I'll chuck sentence generation. It doesn't produce as impressive results as the other topics. You can make up a random sentence whenever you want. For similar reasons, I think I'll drop chatbot too. Results are kind of crap. Email is too hard to make work, and computers aren't much better than humans at sending emails anyway. But automating email could be viable. Hmm, maybe as a last resort.

I can combine data visualization with web scraping. There's no point visualizing insignificant data.

1. Visualizing scraped data (Google Maps, Youtube, Google Search, Google Dictionary, Google Images, Facebook, Twitter)
2. Image generation
3. Music generation

Unfortunately, I haven't done a lot of these topics before, though I can imagine well how they are accomplished. I'm going to try to come up with minimal examples for each topic and see how they compare to each other.

One trap I (and too many other teachers) fall into is being far too ambitious with content. For the vanilla example that you expect students to accomplish, it should be simple and easy to understand so that they can be creative and modify it into their own versions. That way, you also make the content flexible to be able to deal with faster and slower students, who will be doing the same topics but will not be held back or be pressured by students who are working at different speeds.

I really pair programming for high school students, especially for particularly challenging tasks where one student might be unnecessarily pressured. However, the social aspects are particularly difficult to manipulate.

A lot of libraries aren't installed by default with python. I'll definitely need some kind of fallback if it doesn't work out.

1. Scraping + visualization. 


It would be nice if we could use the requests library and matplotlib so I'll see if I can get System Support to install requests.

Requests (needs installation):
import requests
response = requests.get("http://example.com")
print(response.text)

Urllib2 (fallback):
import urllib2
response = urllib2.urlopen("http://example.com").read()

Gnuplot, Matplotlib (both need installation):
from matplotlib import pyplot
# y = x**2

pyplot.plot([1, 2, 3, 4], [1, 4, 9, 16], 'o')  # 'o' is for dots instead of lines 
pyplot.show()

If the graphing doesn't work out, we'll fall back on text scraping, which is pretty decent in itself. Trying to make the students construct a graph using PIL would be too painful for my liking. Better to leave that to a potential image generation workshop. Graphing using matplotlib is pretty damn cool. The simple interface is what makes it so suitable for this workshop.

It looks like scraping social media like Facebook is way too hard (APIs are authenticated and too complex in request and response format), but I did some googling on common scraping exercises and it turns out scraping public statistics data and collating it in some way is really interesting. I think that's a good lead for the future.

Twitter API might be doable.


2. Image generation.


I'm thinking of starting with colour experiments where they colour a block of certain size. And then they can progress to gradients and differently coloured blocks. PIL is the obvious choice since it was installed the last time I checked. Pixel colouring would be an interesting exercise. Then they could experiment with different mathematical formulae to produce different colours.

I checked out the PIL docs and made this minimal example:

from PIL import Image
image = Image.new("RGB", (500, 500))
image.show()

Unfortunately it seems like image.show() has some problems. It doesn't display that well on Windows, but I feel like it should be ok on Mac OSX. I'll have to check this. Without image.show() we'll have to just save it to a file each time. Which is acceptable.

I'm worried about the speed when generating large images and we might need the extra image.load() and stuff.

Alternative 1 (slower):
image.putpixel((400, 400), (200, 255, 50)

Alternative 2 (faster):
pixels = image.load()
pixels[400, 400] = (200, 255, 50)  # 1.1.6 and upwards. I don't know how to do this pre-1.1.6. Maybe using putpixel?


3. Audio generation.


Wave (installed by default!!!):
noise_output = wave.open('noise.wav', 'w')
noise_output.setparams((1, 1, 44100, 0, 'NONE', 'not compressed'))

for i in range(0, LENGTH):
        value = random.randint(-32767, 32767)
        packed_value = wave.struct.pack('h', value)
        noise_output.writeframes(packed_value)

noise_output.close()


I need to work on making the example more minimal so less information-dense. Audio generation is looking pretty dire atm.

Technical check:

Looks like CSE computers have both PIL and matplotlib! great! Looks like we can make something work. I'll have to double-check the particular lab, since we're using the Mac lab so the installation might be different. We can always fallback to going to the Linux labs as a fallback plan as well.

We even have requests! Life literally could not be better.

I'm super damned glad I checked out the examples earlier. Because my human brain is crappy, I don't realise some of the complexities of teaching a certain concept until I've tried out the actual example myself. It's kind of like how people always underestimate the time it takes to complete a certain programming task.

I don't have nearly enough expertise or experience to be able to make accurate estimations.

I have re-learned a lesson I've learned so many times - Preparation is the most important part of teaching. Maybe you can skip preparation if you become a huge baller. I think I could skip preparation for my Introduction to Programming course, for example, because I've taught it so many times.

Never underestimate the cost of teaching foreign content.

No comments:

Post a Comment