You are viewing a read-only archive of the Blogs.Harvard network. Learn more.

What edX isn’t

I’m not sure where this has come from, but most of the discussion about edX on the webs is discussing how it’s going to take over residential education. How you don’t need a college education anymore because edX is free.

Perhaps the misconception comes from the poorly titled nytimes article. The article gets things right, but the title is misleading.

#edx on twitter

edX is advertising itself as the biggest thing since white bread, but what are they actually saying about their service?

What is edX?

MITx and Harvardx courses will not be offered for credit at either university.

… such certificates would not be issued under the name of Harvard or MIT.

And that’s really the big deal, that’s supposedly the big step forward from opencourseware. But it doesn’t exist. So I guess the point is to market the edX name so its certificates can someday have perceived value, or maybe that policy will be changed; but for now, based on what they have released, people seem to be ill-informed.

In contrast, Coursera links the name of the providing university to the cert. But the cert is available only through Coursera and will be released upon user request similarly to the way a university will release records to an inquiring employer. Maybe edX will adopt the same methodology, only time will tell as edX is too immature to intelligently speculate over currently. There’s some mitx software that was probably not written with open source in mind and 3 guys in a dark room somewhere feverishly trying to produce something that doesn’t embarrass the Cambridge community before fall. I’m confident they’ll come out with something nice, the problem is Coursera has a head start, a larger staff, possibly less politicking (grass is greener), and they already have a very nice feel to their product.

edX presents a wonderful opportunity to find a solution for the quandary that has been plaguing the educational community for a while. i.e. how to best leverage the webs for education. Education online has been clumsy at best, and this is another attempt to capture what works best. That’s what I’m excited about, the research of the successes and failures of these online classes. And to get that research, maybe it’s best for people to have an overreaching idea of what edX is so more people are interested.. so on second thought, nevermind.

Posted in Uncategorized. Tags: , , , , . Comments Off on What edX isn’t »

Using Smarty variables inside Javascript

I looked for appropriate answers for this on the smarty site, and the resounding answer was escaping javascript’s {}s with {literal}’s

Smarty template vars and Javascript functions
How to use Javascript codes in template files?
Access Smarty value with javascript

They basically all say to do something like this:

// $question_ids_json = ["1","2","3","4","5"]
{literal}
<script>
$(document).ready(function(){
	var question_ids = {/literal}{$question_ids_json}{literal};
	
	alert(question_ids[0]);

});
</script>
{/literal}

So they want to put everything in a literal tag, and then basically escape that literal tag when smarty needs to be used.

I didn’t like this, so I put the value in a hidden input and then just retrieved that input in the javascript, thereby keeping the js clean of smarty shenanigans:

<input type="hidden" id="question_ids" value='{$question_ids_json}'/>

<script>
$(document).ready(function(){
	//var question_ids = {$question_ids_json};
	var question_ids = eval($('#question_ids').val());
	
	alert(question_ids[0]);


});
</script>

But this is just a matter of personal preference.

Gamificationating Education

I’ve been hearing people talk about gamification ever since I entered academia as a workplace. At first I thought of it as a joke. I mean, obviously a joke.

The problem is the minimal amount of success with it. People keep trying and failing. More to the point they talk about it but are unable to implement anything with confidence. I keep seeing conferences throwing forward the gamification buzz word, but nothing comes of it. Why aren’t people doing it? Why hasn’t it revolutionized education as some keep promising.

The options for gamifying education are:

  • Make a game with educational content
  • Give badges or achievements for whatever
  • Leaderboards
  • Experience / Levels
  • Unlocking content

The primary problem is people want to make entire games centered around their content. And that is a wonderful idea, except it requires people to build the initial content and add content. It would basically require someone who knows the content inside and out to design it properly. Same with unlocking content. Someone has to create that content. That will die out very fast unless you have a zealot very into it.

Slime Forest is a perfect example of this. I was made aware of this project very early on and I LOVED it. It took a game from my childhood and made it all about learning japanese. This would have made a wonderful open source project, but it has a zealot behind it who wanted to make some cash, so good for him.

Badges and achievements are fairly new for games, and only work on certain personalities, completionists. Leaderboards work for people who want to be the best at something, and want everyone else to know it. Experience / Levels is hard to qualify. What do you get experience for, what do you get when you level up…

I used to be really into experts-exchange. That was the site that used to pop up whenever you googled a tech question. A simple forum that let people answer the questions and they would be rewarded points for their answer. This had leaderboards based on the points you got from answering the questions. The best part was everything was managed by the users. (The worst part was they tried to fool people into paying for it.) Stack Overflow took over this market probably because EE got too greedy. SO does have badges and tracks reputation points, but they don’t have topics with a list of the top 100 experts in that field. So it sort of has experience points and badges but no leaderboard.

Posted in Uncategorized. Tags: . Comments Off on Gamificationating Education »

Bootstrap Alerts with Backbone Views

One of the nice things about Bootstrap is that it provides reusable HTML/CSS components for common tasks such as displaying buttons, tabs, forms, and alerts (among other things). The markup for an alert is very simple:

<div class="alert alert-error">
<a href="#" class="close">&times;</a>
<strong>Oops!</strong> Something went terribly wrong.
</div>

A jQuery plugin that comes with Bootstrap is used for the close button. I found myself duplicating this markup in a Backbone.js project with various Underscore templates scattered around the view classes, so for the sake of DRYness, I decided to whip up a simple view to encapsulate the markup and behavior. Here’s the result:

var AlertView = Backbone.View.extend({
	className: 'alert fade in',
	alerts: ['success', 'error', 'info'],
	template: _.template([
		'<a href="#" class="close">&times;</a>',
		'<%= message %>'
	].join('')),
	initialize: function(options) {
		var message = options.msg || '';
		var alert = options.hasOwnProperty('alert') ? options.alert : 'info';

		if(_.indexOf(this.alerts, alert) === -1) {
			throw new Error('Invalid alert: [' + alert + '] Must be one of: ' + this.alerts.join(', '));
		}

		this.alert = alert;
		this.message = message;
	},
	render: function() {
		var output = this.template({ message: this.message });
		this.$el.addClass('alert-'+this.alert).
			html(output).
			alert(); // jquery plugin
		return this;
	}
});

AlertView.msg = function($el, options) {
	var alert = new AlertView(options);
	$el.html(alert.render().el);
	return alert;
};

Now I can use it from my other views for simple alert messages like this:

AlertView.msg(this.$el, { 
     alert: 'error', 
     msg: 'Something went terribly wrong.' 
});

Of course, it can still be improved with shortcut methods and general cleanup, but the goal is not to make it work for every possible alert, just the most common ones.

Posted in ATG, Backbone, Bootstrap, Javascript. Tags: , , . Comments Off on Bootstrap Alerts with Backbone Views »

Abstracting schemas for MySQL and Oracle with Yii Migrations

Yii migrations are an interesting way to keep track of your database changes.  I was originally looking for a tool that would abstract the schema SQL — with something like the Yii ActiveRecord — so I wouldn’t have to write duplicate code for Oracle and MySQL.  I mean, that’s kind of the point of going with the PDO abstraction.

So more than a few forum question/answers led me to Yii migration:

http://www.yiiframework.com/doc/guide/1.1/en/database.migration

I seriously have that page open 3 times in my tabs and I have read it top to bottom probably 20 times.  I keep going back to it over and over hoping it will have more information.  It’s just a little short on answers to all of my questions.

As I said, all I wanted was a way to abstract the schema, so the original premise of “migrations” was a little different than what I was looking for, but it being the only non-custom option, I went forward with it.  The point of migrations is to make sure the state of your database matches the revision of your code.  So it’s sort of like its own hokey versioning system.  As such, it doesn’t function as simply as I might like it.  It’s not easy to focus on one migration if it’s not the last migration.  Because the point of migrations is that you’re moving forward and editing a past migration would be like editing revision X without it effecting all of the future revisions.  So it makes sense for what it is, it’s just awkward.  For one the file structure HAS to include the timestamp.  And it has to include that timestamp at the front of the filename, so autocompleting these migration filenames is a pain in the ass.

One important thing they don’t talk about in the documentation is that the list of what’s been migrated is added automatically to your database via the “tbl_migrations” — and please remember the “s as it will insert it as lowercase, which could be annoying for Oracle users, though Yii seems to handle it “appropriately”.

The only major hurdle here is dealing with autoincrement. The way this was dealt with was I created an Autoincrement class that I plopped in the migrations directory:
protected/migrations/Autoincrement.php

This meant that I could just create the tables like so:

class m120402_194059_Quizes extends CDbMigration
{
	public function up()
	{

		$this->createTable('QUIZES', array(
			'ID' => 'pk',
			'COLLECTION_ID' => 'integer NOT NULL',
			'TITLE' => 'string NOT NULL',
			'DESCRIPTION' => 'string',
			'VISIBILITY' => "integer NOT NULL",
			'STATE' => 'string',
			'SHOW_FEEDBACK' => 'integer',
			'START_DATE' => 'datetime',
			'END_DATE' => 'datetime',
			'DATE_MODIFIED' => 'datetime',
			'DELETED' => "integer NOT NULL",
		));	

		Autoincrement::up('QUIZES', Yii::app()->db->driverName);


	}

	public function down()
	{

		Autoincrement::down('QUIZES', Yii::app()->db->driverName);

		$this->dropTable('QUIZES');

	}
Posted in ATG, Databases, MySQL, Oracle, PHP, Quizmo, Yii. Tags: , , , , , . Comments Off on Abstracting schemas for MySQL and Oracle with Yii Migrations »

Writing a Style Guide

I took a look at the style guides of all of the most popular frameworks.

Yii Style Guide
Codeigniter Style Guide
Zend Style Guide
Symfony Style Guide
CakePHP Style Guide

Yii is the simplest. They just tell you what should go in the Model, Controller and View. I actually believe that’s the best thing when thinking of a framework as a framework, since a framework shouldn’t be telling you how to write your code, and you should never be mixing your code within the framework. A framework is a tool, but it should be on the primary developer to decide on the style that’s right for them and their team. However, I do understand that most of these style guides are talking about their framework as a project, which of course it is

There are a lot of topics to consider in a style guide. A lot of things popped up as I looked at the different style guides that I hadn’t even considered.

File Names
Class Names
Method Names
Method Definition
Class and File Names Using Common Words
Database Table Names
Constants
Variable Names
Member Visibility (Private / Protected)
Indentation
Commenting
Control Structures
The PHP Tag
Comparing Return Values and Typecasting
Logical Operators
Debugging Code
PHP Errors
Whitespace
Linebreaks
Compatibility
One File per Class
Bracket and Parenthetic Spacing
Localized Text
One Statement per Line
Strings (When to use Single or Double quotes)
SQL Queries
Default Function Arguments
Associative Arrays
Unit Tests

Some of the style guides got so long I kind of got angry. Trying to enforce things like whitespace, logical operators or indentation is foolish. It’s just too much and it takes away from the things that are actually important.

So what’s actually important?

What’s important is what people are going to read. Nobody wants to read through a 30 page style guide, and they won’t. The best solution I’ve found is to have 2 style guides. The first, important style guide is to outline the very essential rules you want for your project. Try to keep it short enough to fit on one page so someone may actually read the whole thing. Then, if you choose, you can have a nitty gritty style guide that outlines how you want your variables named and if you’re an indent nazi. You can always refer back to the nitty gritty if someone is submitting code that you find repugnant.

My style guide for Quizmo
My nitty-gritty style guide for Quizmo

Posted in ATG, PHP. Tags: , , , , , , , . Comments Off on Writing a Style Guide »

Yii fixtures with Foreign Keys

CDbException: CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 2292 OCIStmtExecute: ORA-02292: integrity constraint (QUIZMO_DEV.FK_ANSWERS_QUESTIONS) violated – child record found
(/web/quizmo/PDO_OCI-1.0/oci_statement.c:142). The SQL statement executed was: DELETE FROM “QUESTIONS”

Totally annoying. Now I’m not one who has a ton of experience with foreign keys as most places seem to have relations with tables but never explicitly link them as such.

So a FK just doesn’t let you add a record when the record it’s linking to doesn’t exist and won’t let you delete a record when there is some other record linking to it.

The problem is I don’t think Yii thought about these when they did fixtures. They built in a way to deal with it, but it’s a little annoying.

Let’s ignore the fact that all of my tables are in caps because I want this to work in Oracle without having to throw single quotes around everything all the time. Let’s take a look at the fixtures of a section of my tables in a project I’m working on right now.

fixtures/
USERS.php
COLLECTIONS.php
USERS_COLLECTIONS.php
QUIZZES.php
QUESTIONS.php
ANSWERS.php

First I need an init.php in the fixture directory. This is called from /yii/framework/test/CDbFixtureManager.php


	public function prepare()
	{
		$initFile=$this->basePath . DIRECTORY_SEPARATOR . $this->initScript;

		$this->checkIntegrity(false);

		if(is_file($initFile))
			require($initFile);
		else
		{
			foreach($this->getFixtures() as $tableName=>$fixturePath)
			{
				$this->resetTable($tableName);
				$this->loadFixture($tableName);
			}
		}
		$this->checkIntegrity(true);
	}

So the init file just needs to do this:

foreach($this->getFixtures() as $tableName=>$fixturePath)
			{
				$this->resetTable($tableName);
				$this->loadFixture($tableName);
			}

The issue is the resets and loads need to be done in the right order. So the way I went about this is I put in an array of the tables, using that and a reversed version of the array.

$reset_order = array(
	'USERS_COLLECTIONS',
	'ANSWERS',
	'QUESTIONS',
	'QUIZES',
	'USERS',
	'COLLECTIONS',
);

$load_order = array_reverse($reset_order);

foreach($this->getFixtures() as $tableName=>$fixturePath){
	if(!in_array($tableName, $reset_order)){
		throw new CException("Table '$tableName' is not in the reset_order.");
	}
	if(!in_array($tableName, $load_order)){
		throw new CException("Table '$tableName' is not in the load_order.");
	}
}

foreach($reset_order as $tableName){
	//echo("resetting $tableName\n");
	// this runs the TABLE.init.php if it exists
	// otherwise it just does a $this->truncateTable($tableName);
	$this->resetTable($tableName);
}
foreach($load_order as $tableName){
	//echo("loading $tableName\n");
	$this->loadFixture($tableName);
}

That’s not all though, because EVERY table needs a TABLE.init.php file that will be run when “resetTable()” is run in the above script.

fixtures/
init.php
USERS.php
USERS.init.php
COLLECTIONS.php
COLLECTIONS.init.php
USERS_COLLECTIONS.php
USERS_COLLECTIONS.init.php
QUIZZES.php
QUIZZES.init.php
QUESTIONS.php
QUESTIONS.init.php
ANSWERS.php
ANSWERS.init.php

Without these scripts, each table will just DELETE FROM MYTABLE when resetTable is called. The problem with this is if you DELETE FROM COLLECTIONS without deleting the QUIZZES first, you get an integrity constraint violation. So a table init file needs to truncate all tables that are “children” of that table in the order of smallest to largest. COLLECTIONS.init.php looks like this:

truncateTable('USERS_COLLECTIONS');
$this->truncateTable('ANSWERS');
$this->truncateTable('QUESTIONS');
$this->truncateTable('QUIZES');
$this->truncateTable('COLLECTIONS');
?>