Two Face-to-Face @Coursera Office Hours – Orlando Florida

I will be having two face-to-face @Coursera office hours in Orlando Florida this week. One in Universal Studios near Harry Potter World and another at the hotel where I will be attending a meeting.

The first Orlando face-to-face office hours for my Internet History and Python for Everybody courses will be Sunday Jan 24 – 3:00PM – 4:00PM at Moe’s Tavern in Universal Studios.

I wish we could have met at the Leaky Cauldron, but people tell me it is too crowded. But the Leaky Cauldron is a five minute walk away so at the end of the office hours we can walk to Diagon Alley and take a video.

The second face-to-face office hours will be at Holiday Inn Express & Suites – Orlando International Drive Tue Jan 26 – 6:00PM – 7:00PM in the lobby / breakfast area.

7276 International Drive
Orlando, Florida 32819

I hope to see you at one or the other of the office hours.

Contributing to Python 3.0 for Informatics

After many years as a successful Open Python 2.0 textbook, the time has come to update Python for Informatics to be Python 3.0. There will be a lot of work since the Python 2.0 textbook and slides have been translated into so many languages and there are five courses on Coursera all built around the textbook.

Since there is so much work to do, I welcome any and all assistance in the conversion and review of the book. If I can get help in converting the core book, I will have time to add three new chapters that have been requested by the students (see the TODO list for details).

While there are several groups that will likely translate the book and/or slides into Python 3.0, lets wait until the book is relatively solid to make sure that all of the variations of these materials are well aligned.

Temporary Copyright

While I am in the process of drafting a book, I do not put it up with a Creative Commons license. I don’t want anyone grabbing the half-completed text and publishing it prematurely. Once the book is in reasonably good shape I switch the copyright to my normal CC license (CC-BY-NC for print books and CC-BY for all electronic copies). I expect the book to be ready to release in early 2016.

Contributing to the Book

The entire text of the book is in GitHub in this repository:

There are two basic ways to contribute to the book:

  • Create a GitHub account, then navigate to one of the files for the book in the repository like
    Press the pencil icon to edit the text, and then when you “save” the text, it sends me a “pull request” where I can review your changes, approve them, and apply them to the master copy. Once you get going, it is really easy.
  • If you have more tech-skillz, you can “fork” the repository and send me pull requests the normal way. If you use this approach, please send pull requests quickly so we all stay synchronized. Don’t worry about trying to squeeze a bunch of work into a single comment (like many projects prefer). Lots of little commits avoid merge conflicts.

Make sure to take a look at the TODO list to figure out where you can help. We are only working in the book and code3 folders. We will not be converting the code folder as that will be maintained as Python 2.0.

We have a build server that re-builds the entire book every hour at:

So you can see your contributions appearing in the final book within an hour of me approving your pull request. GitHub tracks your contribution and gives you credit for everything you do. Once the book is ready to publish, I will go through the GitHub history and add acknowledgements for all of the contributions to the text of the book.

If you send in a pull request and it seems like I am not moving quickly enough for you, simply send a tweet with the URL of the pull request and mention @drchuck. That will make sure I see it and get working on it.

Thanks in Advance

I appreciate your interest, support, and effort in helping make this open book a success for all these years.

I want to make sure to acknowledge the contributions from authors of
Think Python: How to Think like a Computer Scientist” by
Allen B. Downey, Jeff Elkner and Chris Meyers. Their original groundbreaking work in building an open and remixable textbook in 2002 has made the current work possible.

Tsugi – Non-Upwards-Compatible Change – Using Composer

I made a non-upwards compatible change to Tsugi to move towards refactoring the current monolithic Tsugi code base into separate components. I already factored out the static content (tsugi-static) which is shared between the PHP and Java implementations.

Now I am moving the code that was formerly under lib/vendor into its own repository and have it included using Composer and Packagist.

When you do your next “git pull” or check out a fresh copy, you will need to change your config.php and replace one line:

Remove this line:


Add this line:


If your Tsugi code explicitly includes anything from lib/vendor/Tsugi (it should not) the fix is to simply remove those includes and allow auto-class loading do work its magic. If you include config.php the auto class loader is in effect.

This makes it so we are loading all the Tsugi classes using the auto loader pattern. Interestingly this allows me to make use of the Tsugi utility code in projects that are not even using LTI.

At this point, I am including the composer.lock file and vendor folder in the Tsugi GitHub repo so that it is a one-stop check out that has the files in their new locations and uses autoloading.

In the long run, I will keep a one-stop-check-it-all out repo but eventually get to the point where a Tsugi tool can stand alone in a repo and have all its dependencies fulfilled by Composer.

If you don’t fix the config.php as described above after you r next git pull, you will see the following error:

Warning: require_once(/Applications/MAMP/htdocs/tsugi/lib/vendor/Tsugi/Config/ConfigInfo.php): failed to open stream: No such file or directory in /Applications/MAMP/htdocs/tsugi/config.php on line 15

Fatal error: require_once(): Failed opening required ‘/Applications/MAMP/htdocs/tsugi/lib/vendor/Tsugi/Config/ConfigInfo.php’ (include_path=’.:/Applications/MAMP/bin/php/php5.5.10/lib/php’) in /Applications/MAMP/htdocs/tsugi/config.php on line 15

Of course the fix is trivial.

Face-to-Face @Coursera Office Hours 2.0 Barcelona, Spain Wed Dec 16 – 6:30PM – 7:30PM

I had office hours Sunday in Barcelona and I made a mistake when I was making my video and lost the recording. Since I am still in Barcelona, I will have another face-to-face office hours and this time I will make sure the video camera works.

I will have a face-to-face office hours for my Internet History and Python for Everybody courses at Four Points by Sheraton Barcelona Diagonal, Wednesday Dec 16 – 6:30PM – 7:30PM in the lobby bar.

Four Points by Sheraton Barcelona Diagonal
Avenida Diagonal 161-163,
Barcelona, 8018, Spain

I hope to see you there.


Face-to-Face @Coursera Office Hours Barcelona Sun Dec 13 – 6PM – 7PM

I will have a face-to-face office hours for my Internet History and Python for Everybody courses at Four Points by Sheraton Barcelona Diagonal, Sunday Dec 13 – 6PM – 7PM in the lobby bar.

Four Points by Sheraton Barcelona Diagonal
Avenida Diagonal 161-163,
Barcelona, 8018, Spain

Here is a video from the previous office hours in Bletchley Park

I hope to see you there.

Coursera Face-to-Face Office Hours, Bletchley Park, October 31, 2015

I am pleased to announce that the next face-to-face office hours for my Coursera Python for Everybody and Internet History, Technology, and Security courses will be at:

Location: Bletchley Park, Hut 4 Cafe
Date: Saturday, October 31, 2015, 3PM-4PM

This office hours will be a little different than usual. I want to encourage everyone to arrive at Bletchley Park early in the day and spend the day taking tours, visiting exhibitions and generally enjoying the park. This one of is the last days of the “Imitation Game” exhibition – so I want to see that.

I myself will be arriving around noon and spending the entire afternoon wandering around so if you come early we can run into each other. Then at 3PM we can meet up in the Hut 4 Cafe for some face-to-face time and perhaps some tea.

If you are planning to attend and would not mind, please give me your name and email in case I need to email any updates regarding the plans for the visit using the following form:

I am looking forward to meeting you at Bletchley Park.

Here is a link to my collection of office hours videos:

Here is a video from one of my other visits to Bletchley Park

A Mersenne_Twister Implementation in PHP

I am confused. I found this great Mersenne_Twister implementation to compensate for the fact the at mt_srand() and mt_rand() don’t generate predictable sequences since PHP 5.2.1. From

The Mersenne Twister implementation in PHP now uses a new seeding algorithm by Richard Wagner. Identical seeds no longer produce the same sequence of values they did in previous versions. This behavior is not expected to change again, but it is considered unsafe to rely upon it nonetheless.

What confuses me is that I cannot figure out where I found this code. In my notes have it at in the comments – but I cannot re-find that comment on mt_srand() entry – perhaps it was deleted.

So that it is not lost, I reproduce it here.

class Mersenne_Twister
  private $state = array ();
  private $index = 0;

  public function __construct($seed = null) {
    if ($seed === null)
      $seed = mt_rand();


  public function setSeed($seed) {
    $this->state[0] = $seed & 0xffffffff;

    for ($i = 1; $i < 624; $i++) {
      $this->state[$i] = (((0x6c078965 * ($this->state[$i - 1] ^ ($this->state[$i - 1] >> 30))) + $i)) & 0xffffffff;

    $this->index = 0;

  private function generateTwister() {
    for ($i = 0; $i < 624; $i++) {
      $y = (($this->state[$i] & 0x1) + ($this->state[$i] & 0x7fffffff)) & 0xffffffff;
      $this->state[$i] = ($this->state[($i + 397) % 624] ^ ($y >> 1)) & 0xffffffff;

      if (($y % 2) == 1) {
        $this->state[$i] = ($this->state[$i] ^ 0x9908b0df) & 0xffffffff;

  public function getNext($min = null, $max = null) {
    if (($min === null && $max !== null) || ($min !== null && $max === null))
      throw new Exception('Invalid arguments');

    if ($this->index === 0) {

    $y = $this->state[$this->index];
    $y = ($y ^ ($y >> 11)) & 0xffffffff;
    $y = ($y ^ (($y << 7) & 0x9d2c5680)) & 0xffffffff;
    $y = ($y ^ (($y << 15) & 0xefc60000)) & 0xffffffff;
    $y = ($y ^ ($y >> 18)) & 0xffffffff;

    $this->index = ($this->index + 1) % 624;

    if ($min === null && $max === null)
      return $y;

    $range = abs($max - $min);

    return min($min, $max) + ($y % ($range + 1));

I also wrote a PHP Mersenne_Shuffle() function called that produces a predictable shuffle using the Mersenne_Twister().

function Mersenne_Shuffle($arr, $seed=-1)
    if ( $seed == -1 ) return $arr;
    $mt = new Mersenne_Twister($seed);
    $new = $arr;
    for ($i = count($new) - 1; $i > 0; $i--)
        $j = $mt->getNext(0,$i);
        $tmp = $new[$i];
        $new[$i] = $new[$j];
        $new[$j] = $tmp;
    return $new;

Why PHP chose to break this in the name of progress I don’t understand. Ah well. Here is the workaround. If I need to acknowledge someone – let me know.

Using git subtrees in Tsugi

I am starting to build PHP and Java implementations of my Tsugi libraries and I want to share the static content (JavaScript, CSS, etc) between them all so they all are effectively testing the same core code as much as possible and I don’t want to change things two places. Here are my repos:

I toyed with submodules – but adding “–recursive” to all “git clones” seemes icky and it seemed ike “git pull” in the world of submodules was clunky – I did not even bother to figure it out before I gave up on submodules.

Goodbye git submodules hello git subtrees.

I read these blog posts to learn up:

Conviently in the modern version of git – it knows how to blast submodules so undoing my use of sub modules was a simple matter of:

git rm static
git push

Of course my repo was broken at this point so I quickly needed to add the static folder back as a subtree in with these commands. Note that I did not do the “remote-add” and just put hte full URL if the repo in place of the remote on the subtree commands. I will add the remote if I start pushing from tsugi to tsugi-static.

$ git subtree add --prefix=static/ master
git fetch tsugi-static master
warning: no common commits
remote: Counting objects: 159, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 159 (delta 3), reused 0 (delta 0), pack-reused 150
Receiving objects: 100% (159/159), 1.14 MiB | 0 bytes/s, done.
Resolving deltas: 100% (31/31), done.
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> tsugi-static/master
Added dir 'static'

$ git push
Counting objects: 160, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (125/125), done.
Writing objects: 100% (160/160), 1.20 MiB | 0 bytes/s, done.
Total 160 (delta 32), reused 149 (delta 30)
   55ec2c7..87c5f1d  master -> master
0587388153:tsugi csev$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Just to be sure I putched my clone and re-cloned tsugi and poof! My static content was there in a folder just like I like it – no –recursive required.

On to the git pull when the subtree repo is updated..

In general I will make changes in a separately checked out version of tsugi-static, push them up there and then do a pull into tsugi using these commands. It is a merge – but as long as you keep your local copy of the subtree clean – it is a trivial merge. Of course then you need to push to origin master since subtrees have a full copy of the subtree in the repo:

$ git subtree pull --prefix=static master
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 2), reused 3 (delta 2), pack-reused 0
Unpacking objects: 100% (3/3), done.
 * branch            master     -> FETCH_HEAD
Merge made by the 'recursive' strategy.
 static/ | 8 --------
 1 file changed, 8 deletions(-)

$ git push origin master
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 858 bytes | 0 bytes/s, done.
Total 5 (delta 2), reused 0 (delta 0)
   87c5f1d..6397cb5  master -> master

And that is all there is to it.

This tricky subtree pull is only for the repo that pulled in the subtree initially. Any forks of that repo are unaware that the “static” folder is a subtree and for them “git pull” updates both the repo and the subtree automatically.

Transition from Programming for Everybody (Python) to Python For Everybody

This blog post is to summarize the steps we are taking to transition students who have previously taken or are currently enrolled in our Coursera Programming for Everybody (Python) (PR4E) course now that we have converted the course to the new Coursera platform and made it part of our Python for Everybody (PY4E) specialization.

  • For students who earned a certificate in Programming for Everybody (Python) prior to September 2015: These students will be given credit for the first two courses in the Python specialization and can simply purchase certificates for courses 3, 4, and the capstone to complete the specialization. If you sign up for the first or second course, you should see a price of $0 for the course (screenshot) and if you sign up for the specialization, you a reduced price for the specialization if you sign up for the whole specialization from the specialization page.
  • For students who completed Programming for Everybody (Python) prior to September 2015 but did not pay for a certificate: These students can start in the third course in the specialization (still completely free) and complete courses 3 and 4 in the specialization.
  • For students who registered for the upcoming October 5 session of Programming for Everybody course and paid for a verified certificate: These students will be given a refund and voucher will be added to your account so they can register for verified certificates in the first two courses in the Python Specialization for the exact same cost as registering for the single course verified certificate in Python for Everybody. If you enroll in either of the first two courses in the specialization, you will see a price of $24 (half of the original $49 you paid for the October 15 session). (screenshot)
    Please be patient with the refund: It will take 2-3 days for your refund to show up in your bank account. If after 2-3 days you still do not think that your refund has arrived, contact Coursera Technical Support.
  • For students who registered for the upcoming (October 5) session of Programming for Everybody course but did not pay for the certificate: These students can start at course 1 in the specialization – which is free to enroll.
  • For students who registered for the upcoming October 5 session Programming for Everybody course and were given financial aid: You will need to apply for financial aid for verified certificates in the first two courses in the Python Specialization. Coursera assures me that those who received financial aid in Programming for Everybody will be given financial aid for the courses in the specialization.

The Courses in the Specialization

Here are the courses in the specialization:

  1. Getting Started with Python Chapters 1-5
  2. (Starts September 15, and every six weeks thereafter)

  3. Python Data Structures – Chapters 6-10
  4. (Starts September 15, and every six weeks thereafter)

  5. Using Python to Access Web Data – Chapters 11-13 (Students who have completed PR4E start here)
  6. (Starts October 27, and every six weeks thereafter)

  7. Using Databases with Python – Chapter 14-15
  8. (Starts December 8, and every six weeks thereafter)

For those who are just getting started, the best strategy is sign up for the first course now and the second course in six weeks. For those who know all the material from Programming for Everybody – they can wait until October 27 to start course #3.

Teaching Four Free Python Courses on Coursera, Reflecting on Specializations

In interacting with my current students from Programming for Everybody (Python) – (a.k.a. #PR4E), there are clearly a lot of questions about how Specializations work on Coursera.

Specializations are multi-course sequences with a Capstone. All of the courses that make up the specialization except the Capstone remain free. Here are my four free Python courses that cover all the material in my Python for Informatics textbook (now available in English, Spanish, Korean, and Chinese). The first two courses are six weeks long and cover the same material as my 11-week Programming for Everybody (Python) course on Coursera.

These four Python courses continue to be free and the rest of the non-Capstone courses taught at the University of Michigan are also free. The best places to find links to all the courses that are taught by the University of Michigan are at Every course on that list is free except for the Capstone courses.

You can find all of Colleen van Lent’s free Web Design for Everybody courses here on her instructor page. You can also find all my classes at my Coursera instructor page.

The Specializations and Capstones

The specializations are multi-course sequences that require you to earn and pay for certificates in all of the courses that make up the specialization and then enroll in and pay for the Capstone course. As an example, it costs around $400 to pay for the four courses and capstone certificates for my Python for Everybody specialization. Colleen’s Web Design for Everybody specialization is also around $400. Both specializations have “pay up front” discounts.

A key element of the capstone course is that it is not “new material” – all the material that you need to know is available in the free classes. You are supposed to have already learned the skills in the courses that led up to the capstone. The capstone is more project-oriented with more feedback and a smaller group of students who we know already have pre-requisite information and so are well-prepared to take the capstone. By the time you get to the capstone, you might even know some of the other students in your class. Study groups may have formed and have been functioning for months. Capstones may have industry participation or other benefits.

My Thinking on Specializations and Capstones

When I started with Coursera back in 2012, all I ever dreamed of was to teach one course and have fun with it and engage with people around the world. I chose Internet History, Technology, and Security because I could showcase all my interviews of famous innovators and create a very special course. I wanted to get students who were afraid of technology to the point where they liked technology. This course was very successful with close to 200,000 enrollments since 2012.

I also felt very lucky to be allowed to teach a second course called Programming for Everybody (Python) where I was able to build a dream course that would focus on teaching programming to those who had absolutely no prior experience. PR4E was also a great success, with over 3/4 million students taking the course since 2014. It also was very successfull in meeting my goal of getting people *into* technology even if they were scared or had no experience.

But, from the beginning, there has been a constant demand for more courses. Both online and in my face-to-face office hours around the world there was a constant push for “more courses”. Students did not want to just get a taste and lose their fear, they wanted real skills that they could use to make real changes in their careers.

Moving from “one great course” to “job-applicable skills” is not as easy as it seems on the surface. It requires a willingness to stick to something for more than a few weeks. In college, courses build upon one another – not all courses can be “prerequisite free”.

So if we are to build online activities that begin to move students through 20-30 weeks of course material, there needs to be some structure and some buy in – and an ultimate goal that helps put all the work into some perspective. There needs to be some kind of “graduation” – some kind of light at the end of the tunnel.

Because as you progress through the material in a “curriculum”, the material gets more difficult and the likleyhood of dropout goes up dramatically. So educators build structures to help students make it all the way to the end.

The specializations are that needed structure and the capstone is the light at the end of the tunnel – that graduation – that goal that makes all the effort worthwhile.

And if you imagine that you are going to invest 6-9 months of effort in a sequence of increasingly difficult courses – having to pay for them is a motivational plus in a way. When we think about “paying” for these courses, remember that Coursera has a very active financial aid program that makes sure that we are not blocking access to these courses (including the specialization and capstone) for those unable to pay. For those able to pay, you can pay as you go or pay up front. You can take a course and choose to get the certificate after you know you will succeed in the course.


I personally am 100% committed to making all my courses and material free to everyone. If my goal is to truly “teach everyone” I cannot and will not hide my content behind a paywall.

I think that the approach that Coursera is taking balances free access and pay access in a way that makes sure that all have access to the learning they want. And Coursera and University of Michigan need some way to justify the significant expense in putting out all of this free material. For those who can afford to pay, I hope that you do pay. For those that cannot pay, take a look at financial aid options. And for those who just want to pick and choose courses for a more easy-going pace of professional and personal development, you should be thankful for the effort that Coursera and the University of Michigan have put into specializations over the summer. Because of specializations, the number of free courses available has nearly doubled in the past six months.

It took me three years to get to providing two courses on Coursera. Over the summer, my colleague Colleen van Lent built four completely new free courses on web design and a web design specialization. The pace of creating better ways to learn is accellerating and specializations are just one important part of the mix.

We all fear change – I sure know that I do. But if we know one thing about change it is that the more things change the more things stay the same. I am pretty sure that Coursera now provides more high-quality free courses to the world than the rest of the MOOC providers combined. And we are moving up the value chain from courses that lead to wonderful personal growth to specializations that change your career arc.