Unsetting an element from a PHP array

This is something extremely basic that, for some reason, I find myself looking up every time I need to do it. How do I remove an element from a PHP array?

Perhaps I am overly suspicious but I find myself retesting that this actually works every time I need to do it. To avoid that in the future I am now recording how it is done for posterity.

function printArray($array) {
	foreach($array as $k => $v) {
		echo "$k == $v<br>";
	}
}

$array = array(1 => 'first', 2 => 'second', 3 => 'third');
echo '<br>Array with 3 elements with set indexes<br>';
printArray($array);

unset($array[2]);
echo '<br>After unsetting element with key 2<br>';
printArray($array);

$array = array();
$array[] = 'added string 1';
$array[] = 'added string 2';
$array[] = 'added string 3';

echo '<br>Contents of array without specifying indexes<br>';
printArray($array);
unset($array[1]);
echo '<br>After removing the middle element<br>';
printArray($array);

That code produces the following output.


Array with 3 elements with set indexes
1 == first
2 == second
3 == third

After unsetting element with key 2
1 == first
3 == third

Contents of array without specifying indexes
0 == added string 1
1 == added string 2
2 == added string 3

After removing the middle element
0 == added string 1
2 == added string 3

Note that PHP is clever enough to maintain array indexes when you start unsetting elements even if you didn’t actually specify indexes when you created the array.

Edit a C# table adapter and get hundreds of duplicate attribute errors

Today I ran into a rather bizarre problem that appears to be a bug in Visual Studio itself. It is always fun when the auto-magical functionality of Visual Studio breaks down.

After editing a table adapter in a dataset I hit compile and was greeted with several hundred compilation errors all suggesting that I was redefining things. The locations in the code were relatively nonsensical plus this code compiled 30 seconds ago. Lots of lots of errors like these…

Error CS0579 Duplicate ‘global::System.Serializable’ attribute

Error CS0579 Duplicate ‘global::System.ComponentModel.DesignerCategoryAttribute’ attribute

Digging through the uncommitted changes revealed that the csproj file of the project containing the dataset had been modified in an unusual way. The dataset’s dataset.designer.cs had been joined by a newly created dataset1.designer.cs. For an unknown reason rather than editing the original designer file Visual Studio had left the original alone and created a duplicate designer file alongside it. Both were included in the project and both were essentially identical which explained all of the “already defined” type errors.

After some googling here is how I fixed it.

1) Close Visual Studio

2) Delete dataset.designer.cs

3) Rename dataset.designer1.cs to dataset.designer.cs

4) Using notepad or similar open the affected csproj file. In one or two places I changed a reference to dataset.designer1.cs to instead reference dataset.designer.cs. There was one section that I simply deleted. I entirely removed the Compile block that was including the erroneously created designer file. Below you can see the one we want and the one that has to be removed.

<Compile Include="DataSet.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>DataSet.xsd</DependentUpon>
</Compile>
<Compile Include="DataSet1.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>DataSet.xsd</DependentUpon>
</Compile>

5) Make sure that there are absolutely no references to dataset.designer1.cs left in the csproj file. Close and save it.

6) Reopen Visual Studio. Successfully compile.

A very odd problem. Fiddly but simple enough to fix once you know how. Hopefully I will not have to do it too often.

An Attempt At Postgres Support In Moodle Elis 2.6

ELIS doesn’t currently support Postgres, which is kind of annoying. As well as annoying its a little concerning. So I decided to use a little of my spare time to see what is going on.

A big part of the reason why applications often run into problems with Postgres is because its so much more strict than other databases. MySql essentially says “yeah, that’s probably fine” and lets your slightly malformed queries slide. Not Postgres though. If your query isn’t completely correct it throws an error and you’re done.

That means that errors in Postgres aren’t just a case of an unsupported database, they can indicate undetected problems with your queries. Something is wrong and you just haven’t noticed it yet. Its a big part of the reason why I do my Moodle development in Postgres these days.

Often these problems occur in large complex queries but here is a simple illustration of a common type of error that Postgres flushes out.

Select columnA, columnB
From tableName
Group By columnA

The problem here is that you are selecting two columns, one grouped, one coming from individual rows. Theoretically you could get several values for columnB squished into a single columnA grouped row so what exactly is the database meant to return you?

Typically there will be a join condition or where condition which, in practice, probably ensures that each grouped columnA only has a single value of columnB but you can’t be entirely sure. The simple solution is this…

Select columnA, columnB
From tableName
Group By columnA, columnB

Postgres forces you to go through your queries and think about whether this solution works for you or whether there is something fundamentally wrong with the query. Large queries, particularly those involving grouping, can easily contain subtle errors that can go undetected for quite some time.

So what did I do to make ELIS work with Postgres? All I’ve done is gone through ELIS attempting to flush out and fix the various errors I encountered by making the simplest fix possible.

Note that I don’t claim to have any real knowledge of the (often complex) queries involved. I have made naive fixes that resolve the error but someone with a deeper knowledge of ELIS needs to review and test these fixes.

Some of the fixes will likely be fine. Some of the queries potentially need to be substantially rewritten. I don’t currently possess sufficient knowledge of ELIS to determine which is which.

Standard caveats apply. Do not apply these fixes to a production site. I cannot offer any kind of guarantee that these changes won’t subtly alter the data retrieved by the various queries or even outright break your site.

Ok, all of that said, here are the changes for consideration by whoever considers such things.

https://github.com/andyjdavis/moodle-local_elisprogram/compare/MOODLE_26_STABLE…postgres

https://github.com/andyjdavis/moodle-local_elisreports/compare/MOODLE_26_STABLE…postgres

How To Install Moodle ELIS 2.6

I recently had to install the shiny new version of ELIS, version 2.6.1.2, as part of my work with Moodle. For the previous version one of my coworkers kindly produced a single git repository that included both Moodle itself and ELIS. This time though I was on my own.

ELIS 2.6 sees the ELIS code converted into a set of plugins to make them easier to install. Sounds good. The only issue is that there doesn’t seem to be any documentation telling me exactly what plugins I require out of the large set of repositories available on the Remote Learner github account.

I will very likely have to install ELIS again at some point so, for the sake of saving myself some time in the future, here is the process.

#If you don’t have an existing Moodle installation
git clone https://github.com/moodle/moodle.git elis
cd elis

#From within the Moodle directory
git clone https://github.com/remotelearner/moodle-local_eliscore.git local/eliscore
git clone https://github.com/remotelearner/moodle-local_elisprogram.git local/elisprogram
git clone https://github.com/remotelearner/moodle-local_elisreports.git local/elisreports
git clone https://github.com/remotelearner/moodle-local_datahub.git local/datahub

git clone https://github.com/remotelearner/moodle-block_elisadmin.git blocks/elisadmin
git clone https://github.com/remotelearner/moodle-block_courserequest.git blocks/courserequest
git clone https://github.com/remotelearner/moodle-block_enrolsurvey.git blocks/enrolsurvey

git clone https://github.com/remotelearner/moodle-enrol_elis.git enrol/elis

I’m not actually sure if all of these are actually required. I’m suspicious of some of the blocks if nothing else. I got the list of components from the Remote Learner forums and figured that I was better of having extra components rather than missing something I needed, getting mysterious errors and generally wasting time.

Fixing TypeError: Object #<Queue> has no method ‘replace’

While attempting to get Shifter to work on my laptop I ran into the following error. The fix is below.

By day I am a humble Moodle developer. Moodle uses YUI Shifter to bundle up its Javascript. Shifter seems to work happily for everyone else but I am recording this here for when it next doesn’t work for me.

When doing anything Shifter related I was getting the below.

/usr/local/lib/node_modules/shifter/lib/module.js:324
queue.replace(replaceOptions);
^
TypeError: Object #<Queue> has no method ‘replace’
at Object.buildJS [as js] (/usr/local/lib/node_modules/shifter/lib/module.js:324:11)
at /usr/local/lib/node_modules/shifter/lib/module.js:690:21
at /usr/local/lib/node_modules/shifter/lib/stack.js:24:38
at CB (/usr/local/lib/node_modules/shifter/node_modules/rimraf/rimraf.js:42:5)
at /usr/local/lib/node_modules/shifter/node_modules/rimraf/rimraf.js:61:16
at Object.oncomplete (fs.js:97:15)

Googling that error led me to https://github.com/yui/shifter/pull/111. That explains the problem but how exactly do I fix it… Just making that file change on its own doesn’t do anything… Making the change then re-installing Shifter just resets that file… After some trial and error I fixed it like this.

  1. Find Shifter’s package.json. For me its at /usr/local/lib/node_modules/shifter. If you aren’t sure where it is, note that the path is in the error message 😉
  2. Change the required gear version as shown in the commit of that github pull https://github.com/yui/shifter/pull/111/files
  3. In the Shifter directory run npm update
  4. Get on with the actual work that you are meant to be doing.

Game Portal Post Mortem

A month ago I posted my first HTML5 game Blue Ball Defender to three different web game portals. Game Jolt, New Grounds and Kongregate. A month has passed and I thought it was time I reported what’s happened.

Number of Plays

How many view/plays did each portal deliver.

Game Jolt – 37 views 10 plays
New Grounds – 1403 views
Kongregate – 76 plays

I’m not entirely sure what the deal is with Game Jolt providing two numbers. Perhaps they’re detecting the user moving focus to the game. I haven’t investigated.

The clear winner here is New Grounds. New games on New Grounds go through an initial period called “under judgement”. During the under judgement phase your game is rated by users interested in seeing the newest games. Eventually your game is either accepted into the main collection of games or “blammed” and removed from the site.

During the judgement process Blue Ball Defender had approximately 1000 plays in 3 days. After that the number of people playing it took a major dive. This may not have occurred if my game was better and thus received higher ratings (I’m realistic about the game).

Feedback

Which site provided useful feedback?

Game Jolt – No comments. Absolutely nothing.
New Grounds – 8 comments. These included some useful suggestions for improvements.
Kongregate – 1 comment.

Again, New Grounds comes out in front. The New Grounds commenters made meaningful suggestions and even returned after I had acted on their suggestions.

Cold Hard Cash

All of these sites provide revenue sharing for game makers. I was never expecting much and given the modest results that was probably a good thing.

Game Jolt – $0.02
New Grounds – $0.0
Kongregate – $0.05

New Grounds is in last place here but you’ll notice that the amounts of revenue are so small that it’s pretty much a tie. We’re talking about the difference between zero and one ad click. All of them have a minimum payout threshold of around $25 so I’m not holding my breath to see any money appear in my bank account.

Final Thoughts

Overall New Grounds appears to be the most useful portal however there’s no reason not to use all 3 sites. I’m not suggesting you use only one.

The initial big surge of views on New Grounds during judgement followed by a big drop was interesting. Given the constructive nature of the comments I received during judgement I suspect that New Ground’s users consist of, in large part, fellow game makers. Fellow game makers who periodically check in to try out the latest submissions. After the game was past judgement they moved on.

Coursera. How I Love Thee.

I’ve previously written about my experiences with Khan Academy and Udacity over on Magic Travel Blog. Today I’m going to talk about Coursera.

 

The next chapter in my tour of free online courses was “An Introduction To Interactive Programming In Python” followed by “Calculus One” on Coursera.org. Coursera’s courses are provided by a large coalition of universities. The Python programming course is provided by Rice University. The Calculus course is provided by Ohio State University.

Just looking at Coursera, how it looks, the page layout is noticeably clean and well laid out. Your name appears in the top right of the screen. Clicking on it expands a drop down that contains everything not directly related to the course you’re currently in. Prior to expanding that drop down, 100% of the screen is devoted to the current course. The end result is very uncluttered and free of distractions. It’s really hard to get lost.

The course format for Python Programming is to watch video lectures, do 1 or more quizzes interleaved between the videos, then do a weekly mini-project. Calculus One has a similar weekly cycle made up of videos, free pdf textbook chapters to read, rounded out by an end of week quiz. Periodically the end of week quiz is replaced by a larger exam.

The video lectures are all very professionally put together. They’re not as fancy as the videos on udacity.com which feature lots of animation and a presenter who apparently travelled around Europe visiting locations relevant to the topic. They are however watchable and informative. The presenters are charismatic and enthusiastic about the material they’re teaching.

The quizzes and exams in the Calculus course are all automatically marked as you would expect with a course of this size. The grading of the mini-projects in the Python programming course is more involved. There are apparently around 50,000 students in the course. Far too many for the staff at Rice University to deal with and computer programs often do not lend themselves to automatic marking.

To deal with the volume of student projects they’ve opted for peer assessment. After everyone has handed in their assignment each student marks 5 other people’s projects using the grading rubric provided. No doubt there will be tuning required and problem cases to deal with however the experience of assessing your peers is almost as informative as completing the project yourself.

The feedback I received was often surprisingly thorough. Looking back on my time attending a bricks and mortar university I suspect the feedback provided by my peers during this course may have be more useful than the scrawled feedback I frequently received from overworked tutors plowing through great piles of assignments.

It’s worth noting how much software has been produced specifically for these courses.

An Introduction To Interactive Programming In Python

All programming for the mini-projects is done in a tool called Code Skulptor. It means you can do everything in your browser with no need to install any software. Very handy for a course populated with students running every kind of computer imaginable.

Code Skulptor was apparently built by one of the gentlemen running the course specifically for the course. It’s a very nice tool that allows you to write, run, save and share your Python code. It even has a simple versioning system built in.

Interestly Code Skulptor has no Internet Explorer (IE) support. A flat ban on IE is a bold move although admittedly it’s one with the general feeling of many computer science types. The requirement to use a non-IE browser will certainly be far more easily accepted in the computer science department than it might be elsewhere. Note that this browser restriction only affects this particular course as it is heavily reliant on Code Skulptor. Coursera itself has no such limitation.

Calculus One

The quizzes and exams are, I believe, being run on software borrowed from Khan Academy. Calculus One’s demand for large equations is evidently exceeding anything required by Khan Academy itself. Inputting complex equations is particularly painful and error prone although the process is evolving rapidly. They’re working hard on this and, at the pace the system is evolving, hopefully we can soon say goodbye to messages like this…

You can enter this as (((-( (((csc (((e)^((((-( ((3 * x)))) + 1)))))))^(2)))) * ((e)^((((-( ((3 * x)))) + 1)))) * -3))

 

Despite encountering some teething problems my experience with Coursera has been overwhelming positive. It’s amazing how smoothly it all works given the newness of it all. I’m learning a lot and having a great time doing it. So are hundreds of thousands of people all over the world.

If you haven’t yet done a course on Coursera go and enrol right now. Seriously. Do it now. Coursera.org.

Rounding down is more complicated than I thought

Another day, another learning opportunity. While working on a platform game I noticed my characters movement was a little off. It was subtle but it seemed to move faster to the left than to the right… Very odd.

I spent a few hours going through the movement code, debugging, experimenting, constructing theories about causes, disproving my theories and generally going around in circles. Eventually I figured it out and it was kind of interesting.

Somewhere in the code when dealing with velocities I was calling math.floor(). floor() rounds down, which sounds simple. So simple that I overlooked it repeatedly while reviewing the code looking for the problem.

The problem is that velocity can be either positive or negative. It’s positive when you’re moving to the right. Negative when you’re moving to the left. If you have a positive velocity, say 2.4, it gets rounded down to 2. However if you’re velocity is -2.4 is gets rounded down to -3. When moving to the right velocity was reduced. When moving to the left velocity was increased. Bingo.

For some silly reason I was thinking of rounding down as rounding towards zero rather than sliding to the left on the number line. If you ask me whether -3 or -1 is less than -2 my first impulse is to say -1. Damn brain.

Packaging a Pygame Game as a Windows Exe: a Lesson in Fail

For my first #1GAM game Yet Another Space Shooter I didn’t bother figuring out how to make the game easily installable and playable. I was focussed on just getting my first game over the finish line. As a result only a handful of people have played it and one of them was my brother.

Here in month two it is time to make things easy for anyone wanting to play my games. To that end it’s time to figure out how to distribute my python/pygame games as a Windows executable.

First of all, why do I have to do this? Well, without a windows exe someone wanting to play the game currently has to retrieve the game from github (no simple task for anyone unfamiliar with Git), install Python and Pygame if they don’t already have them, then run “python main.py”. It’s not super complicated but if someone asked me to do all this before I could play their game I probably wouldn’t do it. With a Windows exe anyone running Windows can simply download the exe and run it.

Along the way to Windows executable nirvana I ran into some problems which I thought I’d document. Partly for the education and amusement of others. Partly so future Andrew can read this when he forgets everything he’s learned.

Step 1, check that I can manually run the game under Windows. I use Ubuntu ie Linux as my primary operating system. Before I even get to packing my game into an executable I need to check it works in Windows at all.

I rebooted into Windows, downloaded and installed both Python and Pygame. Then I tried to run my game…

Learning Opportunity 1: Be aware of Python versions

The Python world is divided into 2.x and 3.x and never the twain shall meet. I didn’t realize it but Ubuntu ships with 2.x pre-installed. I just started using it without even checking what version I had. When I had to manually install Python in Windows I saw 2.7 and 3.3, thought “newer is better right?” and installed 3.3.

When I ran my program I got a syntax error. That’s weird. I rebooted into Linux, ran it there and it ran fine. Some Googling later I discovered that this was because I had written the code using 2.7 but was running 3.3 in Windows.

Uninstall Pygame (just in case), uninstall Python 3.3, download and install Python 2.7, reinstall Pygame.

Around about here I realized that both notepad and wordpad suck for reading code. Notepad++ seems like a viable alternative.

Learning Opportunity 2: Be aware of 32 Vs 64 bit Python

Running my game again I got a weird error about a DLL failing to load and something not being a valid executable. It was coming from within Pygame itself.

Some more googling later I discovered something else. Pygame is 32 bit and does not play nice with 64 bit Python. I have a 64 bit laptop so I automatically grabbed the 64 bit version of Python. More bits is better right?

Uninstall Pygame (just in case), uninstall Python 2.7 64 bit, download and install Python 2.7 32 bit, reinstall Pygame.

Huzzah! I can now manually run my game under Windows.

Step 2, bundle it all up as an exe.

Once I could actually run my Python game the rest was relatively easy. Documentation for the various Python packing systems is pretty sparse but my needs are not complicated.

I spent several hours tinkering with py2exe, PyInstaller and cx_freeze. They were all fine to spit out an exe that didn’t need any files. As soon as you needed files things got a little more interesting. In the end I focussed my attention on cx_freeze.

Rather than telling you what’s involved I’ll just show you. It’s pretty self explanatory.

Cx Freeze requires a little script that you can then rerun whenever you want to regenerate your exe. You can find my first cx freeze script in my github account. https://github.com/andyjdavis/yet-another-space-shooter/blob/master/setup.py

I now possess the magic of exe generation!

The Dangers of Floating Point Numbers

As I’ve mentioned previously I’m participating in One Game a Month. My January game was Yet Another Space Shooter. My February game is a platform game that doesn’t yet have a name. It’s coming along nicely but I have run into some interesting problems along the way.

As it turns out platform games can be broadly classified into two groups. Tile based and vector based.

In a tile based game the world is internally represented as a big grid. Each cell of that grid can be empty or it can be filled with platform, monster, a player or whatever. Elements, such as the player, may occupy a single cell or they may occupy several, for example being 2 cells wide and 6 cells tall. Typically nothing can occupy less than one cell.

In a vector based game the world consists of a big bag of objects. Each object has a size, a position and a velocity. It’s this big, it’s at this location and it’s moving in this direction at this speed. Due to my experience with Yet Another Space Shooter this was the model that I was familiar with and thus the model I chose. At the time I wasn’t even really aware that most platform games are actually tile based.

Platform games often go for the tile based approach because it makes determining when two objects are touching and whether the player’s movement is blocked quite simple. If the cell directly below the player is occupied by platform then the player is sitting on a platform. If the cell to the right of the player isn’t empty then the player can’t move to the right. Determining this stuff in a vector based world is a little more complex.

Without being aware of what I was doing at the time I compounded this complexity by representing positions in the world as floating point numbers. I’m using Python and in Python, be default, decimal numbers are floats. Thinking back on my time at university I do vaguely recall learning that floating point numbers are approximations and should not be relied upon for precise calculations. I don’t think this has ever come up during my years as a professional computer programmer. Until now.

It finally came up when dealing with interactions between the player and the platforms. Sometimes the player would just fall through a platform for no apparent reason. Sometimes the player would fall into the floor and get stuck. It was all very mysterious.

The problem was, of course, my use of floating point numbers. For the player to be on a platform the gap between the player and the platform must be zero. Not very small, zero. Every once in a while the approximate nature of floating point numbers would cause the player’s position to be slightly below the surface of the platform and the player would then fall through.

This took me quite some time to figure out. That it was a symptom of the computer’s internal representation of decimal numbers was not the first thing that came to mind when debugging this.

Fortunately the fix was actually very simple. While I still store velocities as floats I now store positions as integers. Positions no longer look like (127.00000001, 520.99999999990). Now they look like (127, 520). When the player is sitting on a platform the gap between the player and the platform is now precisely exactly zero.

Once I switched positions from floats to ints all of these weird little events went away. It was pretty magical actually. It’s still nowhere near a finished game but just being able to bounce around the world with confidence that you won’t spontaneously fall into the floor has done wonders. It actually feels like something approaching a proper platformer.

For my next game I think I’m going to try out a tile based platform game. I’d like to see what things are like on the other side of the tile vs vector fence.