Last week was very productively spent at Unite 2014 learning about all things Unity.

In case you are not into game development, Unity claims to be used by over a million game developers around the world. While I rather suspect those statistics are up their with Second Life and Twitter counting everyone who ever signed up for an account, there is no denying that one whole hell of a lot of people use Unity for game development, including us. I have to say all of my major objectives in attending were met.

2d Game image

The first thing I wanted to achieve was make a definite decision whether to go with Unity for the 2D game for the iPad that we are going to dive into next month. We have some artwork, a rough design, but we’re coming up on the first point of no return decision. Well, there’s always a return, but if we start with Unity and then switch to solution X it may take us quite a bit of time to re-tool.

The decision was, yes, we definitely want to use Unity. My concerns about performance on lower powered devices were addressed. First, I spoke to some helpful folks from Unity who pointed out that you can set your game’s graphic quality ranging from Fastest through Beautiful to Fantastic. Yeah, those are actually the last two settings. I also attended a session on tips for working with mobile devices that gave me some good ideas, like if we have character that has a sword, instead of having two images, a sword and a character, have that be drawn as one image.

Two other clinchers for unity were

the number of platforms to which we could expand eventually – play station, xbox, android phones, smart TVs. Unity works with all of those. The same would not be true of code we wrote in javascript for the web.( Speaking of javascript, even though Unity supports both C# and javascript, I noted that the examples were overwhelmingly C# ones in the presentations and their seems to be a definite lean in that direction), and

the number of vendors with integrated add-on packages, everything from SpeedTree, which makes drawing trees fascinating to mixamo which offers a much simpler way for making 3-D animated characters. I was so impressed with mixamo that I texted one of our fabulous artists from the presentation, This is something we need to start using, and by we, I mean you, because we both know I suck at art.

The second thing I wanted to achieve was to get more familiar with Unity. That was achieved. I was able to follow the examples in the Training Day and do the Nightmares game, which was pretty fun. The next couple of days, in my spare time, I made another much simpler game from scratch for my grandchildren to play. It won’t win any awards for originality or anything else, but my Unity knowledge definitely spiked up in a week.

Screen shot of nightmares game

One reason I insist on going to events like this, even though people tell me that I am the CEO and should be doing CEO things, is that I would never, ever find 40 hours in a week just to learn  if I stayed back in the office. I’ve written before about the Red Queen’s Race in technology, where you need to run as fast as you can to stay in the same place. I turned 56 last week and more opportunities are coming my way than ever before, which I attribute to refusing to equate age with stagnation.

No brogrammer culture in sight

Speaking of age – I usually go to conferences on statistics – the Joint Statistical Meetings, SAS Global Forum, etc. Sometimes I go to start-up events. This was my first game developer conference and I had heard horrid things about the game industry, that women are sexually harassed, assaulted, disrespected.

As far as horrid brogrammer culture – didn’t see it, and I looked. The demographics were overwhelmingly male, somewhere between 90-95%, I would guess. None of the sessions I attended had a female presenter. On the other hand, I didn’t submit a paper. I suggested it to The Invisible Developer and he didn’t want to do it, and I was too busy with everything else. We decided next year, for sure we would co-author one and submit it. Should be fun.

My point is, I don’t  think they received hardly any submissions from women, just based on the number of women attending.

Despite all of the people who claim to have started coding in the womb and how much VCs supposedly drool over twenty-somethings, I saw about as many people under 20 as I did over 60. That’s based on me eye-balling it, I didn’t actually go around carding people. Given the amount of grey hair and balding, I’m going for the crowd was overwhelmingly in their thirties and forties.

While there were far fewer women than at statistics conferences, there were more than the zero African-Americans and Latinos you usually see at statistics events, although it was clear from the eavesdropping during the coffee breaks (I call it qualitative data collection) that many of these folks were actually from Latin America attending the conference. It was FAR more international than SAS Global Forum or JSM, even though both of those have a smattering of international folks.

As far as the whole sexual harassment, mansplaining, unwelcome thing – didn’t see it. Nada. Zip. Zilch. Every single person we met was nice, polite and interested in talking about game development. No one treated me like I was a second-class citizen and the only person who insisted on explaining stuff to me that I already knew was The Invisible Developer, but he has lots of other non-annoying traits that make up for it, so it doesn’t bother me.

It may be that I am old, plus I was there with my husband, so no one would bother me. However, I really did look, whether it was at cocktails in the evening, at lunch, during the coffee breaks, at the young women sitting around me in conference sessions  - and I did not see a single hint of the kind of bad behavior I’ve been hearing about. I’m a small person and at this conference, I was just there to hang out and learn stuff, so I was wearing jeans and a hoodie most days, my point being, there wasn’t any reason people would be on their best behavior around me.

I’m not saying it doesn’t happen. I’m saying I didn’t see it happen here.

All I can say is — you should go to the next Unite conference. Learn stuff about game development and people will be nice to you. What more can you want? Well, if you want more, I should add that Seattle had some awesome restaurants.

If you want to go next year, do jump on it right away when you see it advertised though, because everything sold out – the conference, training day, nearby hotels.

 

Lately, I’ve been working on a report that uses eight datasets that all have the same problems with the usernames.

In addition to needing to remove every username that contained the word “test” or “intern” we also needed to delete specific names of the classroom teachers who had played the game. We needed to correct names that were misspelled.

Here are a few examples of a very long list of statements:

if username in("MSDMARIA","1ANSWERKEY","MSDELAPAZ","MSCARRINGTON") then delete ;

if username = “GRETBUFFALO” then username = “GREYBUFFALO” ;

else if username = “HALFHORES” then username = “HALFHORSE” ;

else if username =”TTCARLSON18TTCARLSON18″ then username = “TTCARLSON18″ ;

 

These problems occurred in every dataset.

A second problem found when looking at the contents of each of the 8 datasets was that the username variable was not the same length in all of them, which could cause problems later when they were to be merged together or concatenated. Also, now that all of the usernames have been cleaned up, none should be over 12 characters in length.

Wouldn’t it be nice if there was a way to just get the first n characters of a string?

What did I tell you before about when you find yourself saying that with SAS?

Enter our  character function, substr, which returns a substring of a variable beginning at any position and for as many characters as you like. Problem solved.

newid = substr(username, 1, 12) ;

 


It seems pretty inefficient to write this set of statements eight times in eight different data sets. Also, next year we will have another eight data sets, and some will have these same students’ usernames and same problems. Wouldn’t it be a lot easier to have these statements in one place and add to the “fixnames.sas” file whenever we find a new problem?

So, now we have the write once, use anywhere solution of %INCLUDE.

What %INCLUDE does

The %INCLUDE statement references lines from an external file and processes them immediately. It has almost the exact same effect as if you had copied and pasted those lines write into your program. The exception that makes it “almost” is that a %INCLUDE statement must begin at a statement boundary. That is, it has to be either the first statement in your program or occur after a semi-colon ending a statement as in this example.

data studentsf ;

infile inf delimiter = “,” missover ;

attrib teacher length = $12. username length = $ 16. ;

input username $ age sex $ grade school $ teacher $ ;

%include “/courses/u_mine.edu1/wuss14/fixnames.sas” ;

Also, you need to think about it as if you had copied and pasted those lines into your program. Is it still valid code? Whenever using %INCLUDE, you should make sure the code runs in your program as expected, with no errors, before cutting it out and making it an external file.

To source or not to source

The default is not to show the statements that were in the included file. Generally, this is desirable. This is code you have already debugged and if you are using it multiple times (otherwise, why bother with the %INCLUDE), having the same 20 lines repeated 8 times in your log just makes it harder to debug.

Professors might want to use real data but hide all of the messy data handling from the students initially in fear they would run screaming for the door. I meant, professors might want to gradually introduce SAS statements and functions for data handling.

In either case, students could use the %INCLUDE statement as shown in the example above. To see the code include in your log is quite simple, just add a source2 option as shown.

%include “/courses/u_mine.edu1/wuss14/fixnames.sas” /source2 ;

It will be in your log as follows

NOTE: %INCLUDE (level 1) file “/courses/u_mine.edu1/wuss14/fixnames.sas is file “/courses/u_mine.edu1/wuss14/fixnames.sas.

419 +username = compress(upcase(username),”. “) ;

420 +if (index(username,”TEST”) > 0 or index(username,”INTERN”) > 0

 

and so on.

The + signs next to each statement denote it was in the included file.

If you want to know why I think it is so important for new SAS users to learn about the %INCLUDE statement, you should come to the Western Users of SAS Software conference in San Jose next month. Especially if you’re a student, you should come, because they cut you a really good deal.

If you’re not a student and you have a real professional job – well, then, you should be able to afford it. There will be funny hats, beer, coding and cookies. What more could one ask?

wuss_hats

A few years ago, I was at the Western Uses of SAS Software conference  and renowned statistician Stanley Azen played the piano and sang at the closing ceremony.

Briefly, very briefly, I considered beginning my presentation on 10 SAS steps to an annual report, by writing a song, These are a few of my favorite PROCs, and then singing it to the tune of “These are a few of my favorite things.”

This plan was dismissed a nanosecond later when I was reminded by The Perfect Jennifer that my singing bears an uncanny resemblance to the sound Beijing the cat used to make in the middle of the night when fighting with the cat next door.

Beijing the Cat

To make up for my disappointment over my lack of musical rendition, I decided to do a few posts on my favorite PROCS, in no particular order. Today’s contestant is … drum roll please ….

PROC IMPORT

Whenever possible, I try reading in the data using the IMPORT procedure, because, it is very simple and my goal in programming is not impress people with my brilliance – it is to get the job done with maximum efficiency and minimum effort.

As can be seen in the example below, there is no need to declare variable lengths, type or names. Only three statements are required.

PROC IMPORT OUT= work.studentsf DATAFILE= "/courses/u_mine.edu1/wuss14/Fish_students.csv" DBMS = CSV REPLACE;

GETNAMES = YES ;

DATAROW=2;

This PROC IMPORT statement gives the location of the data file, specifies that its format is csv (comma separate values), the output file name is studentsf, in the work directory and that if the file specified in the OUT= option already exists, I want it to be replaced.

The second statement will cause SAS to get the variable names from the first row in the file. Since the variable names are in the first row of the file, the data begins in row 2.

Limitations of PROC IMPORT

As handy as it can be, PROC IMPORT has its limitations. Three we ran into in this project are:

  • Excel files cannot be uploaded via FTP to the SAS server, so , no PROC IMPORT with Excel if you are using the SAS Web Editor,
  • If the data that you want to import is a type that SAS does not support, PROC IMPORT attempts to convert the data, but that does not always work.
  • For delimited files, the first 20 rows are used to determine the variable attributes. You can give a higher value for the number of rows scanned using the GUESSINGROWS statement, but you may have no idea what that higher value should be. For example, the first 300 rows may all have numbers and then the class that was records 301-324 has entered their grade as “4th” instead of the number 4.

Although PROC IMPORT is the first thing I always try, one of my pet peeves about instructors and textbooks is when it is the only thing they teach. It’s smart to try the simplest solution first. It’s dumb not to have a back up plan for the instances when that doesn’t work.

For more on what to do in those cases, you can come to WUSS in San Jose. Just a reminder – regular registration closes August 25. After that date, you’ll have to register on site.

 

Finishing up my second paper for WUSS next month and I have been thinking about the usefulness of character functions in a world where it sometimes seems like everyone is just put on this earth to irritate the hell out of me.

Take this problem, for example,

In analyzing the data for our games, we have all sorts of  beta testers – teachers, staff, interns –  who played the game but their data should be deleted from the datasets for the annual report. We asked them to use the word TEST in their username so it would be easy to pull them from the data. Some of them did and some apparently feel that I just say these things of exercise for my mouth.

There is also a problem with data entry errors. The subjects in this study were children in grades three through six and they frequently mistyped their usernames.

SAS has a wealth of character functions and this is a first opportunity to get to know and love four of them.

The UPCASE function, not surprisingly, changes the value of a variable to upper case. The COMPRESS function, if you give it only the variable as an argument, will remove blanks from a value. You can, however, include additional characters to remove. Since many of the students entered their names on some days as JohnDoe and others as John.Doe , we are removing both blanks and periods using the COMPRESS function, after we have converted them to upper case.

username = COMPRESS(UPCASE(username),'. ') ;

(Also, see my previous post on using COMPRESS to remove character data when your data is numeric-ish (c) )

Then there is the INDEX function. Here is a general tip. Any time you find yourself thinking,

“Gee it would be nice if SAS did thing X”,

it is a pretty good bet that someone else thought the same idea and there is a function for it. The INDEX function is a perfect example of that. Our testers played the games many, many times and used usernames like “tester1”, “this.test”, “skippy the tester” or “intern7”.

“Wouldn’t it be nice if there was way to find out whether a given string appeared anywhere in a value?”

Enter the INDEX function, which does exactly that. This function is case-sensitive, but since we already converted the username to upper case above, that is no problem for us.

IF INDEX(username, “TEST”) > 0 or INDEX(username,”INTERN”) > 0 THEN DELETE ;

will do exactly what we want. The INDEX function returns a number that is the starting position in the string of the substring we are trying to find. So, in “skippy the tester”, the value is 12, in “tester1” it is 1. If the string is not found, the value is 0.

A problem I found when looking at the contents of each of the 8 datasets used for my research project was that the username variable was not the same length in all of them, which could cause problems later when they were to be merged together or concatenated. All of the usernames should have been a maximum of 12 characters but there were data entry problems when students would type mister_rogers instead of mr_rogers.

When the data are read in using PROC IMPORT, “For delimited files, the first 20 rows are scanned to determine the variable attributes. You can increase the number of rows scanned by using the GUESSINGROWS data source statement.”

Wouldn’t it be nice if there was a way to just get the first n characters of a string?

newid = SUBSTR(username, 1, 12) ;

will create a new variable with the first 12 characters of the username, now that we have gone and fixed the problems with it.

 

SAS is chock full of functions and options to make your life easier. If you are just beginning to work with SAS and you spend time working with messy data, you probably couldn’t spend your time much better than taking a few hours to read up on SAS character functions. In fact, I think for someone new to SAS, becoming familiar with a large number of all types of functions – character, statistical, date and time – is probably the fastest way to improve one’s productivity. (Ron Cody’s book, SAS Functions by Example, is a great resource).  I’ve lost count of the number of times when reviewing a student’s program I’ve seen many lines of completely unnecessary code that could have been replaced by a SAS function – if the student only knew that it existed.

The second time I taught statistics, I supplemented the textbook with assignments using real data, and I have been doing it in the twenty-eight years since. The benefits seem so obvious to me that it’s hard to believe that everyone doesn’t do the same. The only explanation I can imagine is that they are not very good instructors or not very confident. You see, the problem with real data is you cannot predict exactly what the problems will be or what you will learn.

For example, the data I was planning on using for an upcoming class came from 8 tables from two different MySQL databases. Four datasets had been read into SAS in the prior year’s analysis and now four new files, exported as csv files were going to be read in.

Easy enough, right? This requires some SET statements and a PROC IMPORT, a MERGE statement and we’re good to go. What could go wrong?

Any time you find yourself asking that question you should do the mad scientist laugh like this – moo wha ha ha .

Here are some things that went wrong -

The PROC IMPORT did not work for some of the datasets. No problem, I replaced that with an INFILE statement and INPUT statement. It’s all good. They learned about FILENAME and file references and how to code an INPUT statement. Of course, being actual data, not all of the variables had the same length or type in every data set, so they learned about an ATTRIB statement to set attributes.

Reading in one data set just would not work, it has some special characters in it, like an obelus (which is the name for the divide symbol  – ÷  now you know). Thanks to Bob Hull and Robert Howard’s PharmaSUG paper, I found the answer.

DATA sl_pre ;

SET mydata.pretest (ENCODING='ASCIIANY');

Every data set had some of the same problems – usernames with data entry errors that were then counted as another user, data from testers mixed in with the subjects. The logical solution was a %INCLUDE of the code to fix this.

In some data sets the grade variable was numeric and in others it was ‘numeric-ish’. I’m copywriting that term, by the way. We’ve all seen numeric-ish data. Grade is supposed to be a number and in 95% of the cases it is but in those other 5% they entered something like 3rd or 5th.  The solution is here:

nugrade=compress(upcase(grade),'ABCDEFGHIJKLMNOPQRSTUVWXYZ ') + 0 ;

and then here

Data allstudentsents ;

set test1 ( rename =(nugrade= grade)) test2  ;

This gives me an opportunity to discuss two functions – COMPRESS and UPCASE, along with data set options in the SET statement.

Kudos to Murphy for a cool paper on the COMPRESS function.

I do start every class with back-of-the-book data because it is an easy introduction and since many students are anxious about statistics, it’s good to start with something simple where everyone can succeed. By the second week, though, we are into real life.

Not everyone teaches with real data because, I think, there are too many adjunct faculty members who get assigned a course the week before it starts and don’t have time to prepare. (I simply won’t teach a course on short notice.) There are too many faculty members who are teaching courses they don’t know well and reading the chapter a week ahead of the students.

Teaching with real, messy data isn’t easy, quick or predictable – which makes it perfect for showing students how statistics and programming really work.

I’m giving a paper on this at WUSS 14 in San Jose in September. If you haven’t registered for the conference, it’s not too late. I’ll post the code examples here this week so if you don’t go you can be depressed about what you are missing,

 

 

 

 

Hint: It’s math!

My last post, I ranted about the need for math if you are going to learn to code.

I was thinking about that again today. Unity is the game engine that claims to be used by over a million developers. That may be true – it seems like everyone I ran into at the Serious Play conference was using Unity, and we do, too.

Unity is great and there are an enormous number of assets you can purchase that make it easier to create games. That being said, at the first step in learning Unity, you are told that to locate your object in this three-dimensional space you set the X, Y and Z values. The default for these is the origin (0,0,0).

If you’re reading this blog, you’re probably the kind of person to whom that is immediately obvious. You’ve looked at charts a thousand times, you know exactly what an X and Y axis are, that the origin is the point at X=0, Y= 0 and it is not much effort at all for you to conceive of a Z axis and generalize from two-dimensional space to three dimensions.

When one of the most basic tutorials begins with discussing a plane, even if you didn’t remember much about geometry, you probably would recognize that as a two-dimensional space.

Concepts like scale and rotation depend on mathematics.

I’ve been trying to think of examples of programming that didn’t use much math. I did come up with one – you could create an application using PHP, MySQL, HTML and CSS to enter data into a database via forms and create simple reports. Not sure how many kids would be interested in that – I don’t find it all that interesting myself and I love programming.

My point is that if we don’t teach kids math, they are going to be limited in the types of coding they can do. Even areas like gaming, where you might think math isn’t so necessary, depend heavily on a level of mathematics that the average American student struggles with.

Now, if people who are promoting teaching kids to code see it as one way to motivate students to learn more math, then I think they might have some success.

On the other hand, overlooking the fact that students will need math is setting them up for failure.

So, that’s why the proposal I’m working on now is to develop games to teach students geometry, statistics, measurement and data. I hope that then, there will be a larger pool of young people prepared to learn to code.

 

 

cake

I’ve spent a good bit of my life living and working in places that many of my colleagues would not drive through in the middle of the day with the windows rolled up and the car doors locked, so you’ll have to excuse me if I am a bit cynical about the latest push to teach everyone to code.

I’m not opposed to coding, in fact, I am greatly in favor of it. It is tied with drinking Chardonnay for favorite activity for which you do not have to get naked.  I was an industrial engineer in 1982 – so I was into STEM before STEM was even a thing.

What makes me roll my eyes and sigh is where many well-meaning people have completely missed the mark when they say that you don’t really need to know much math to write software. Clearly, they can’t mean all kinds of software because obviously if you write software to do statistical analysis, predictive analytics or whatever the phrase du jour is, you very much need math.

Often, these people are talking about games -

“Kids play games, let’s have them make them.”

That doesn’t necessarily follow any more than,

“I have a liver. I should create a dialysis machine.”

Ignoring the faulty logic for a minute, let me point out that most games DO require math. The people saying they don’t are usually people who are quite successful, both professionally and academically and have spent their entire lives around people much like them. What they mean when they say that, “Games don’t require much math” is

“I took three semesters of Calculus and a course in multivariate statistics and I rarely use any of that in making games.”

I, on the other hand, meet many people who can’t multiply two-digit numbers without a calculator and have never given a thought to the concepts of randomization, ceiling, floor or rounding. The vast majority of these people are perfectly intelligent enough to learn those things if ever given the motivation, time and instruction.

Here are a few lines from a super-simple game, “Canoe World”,  I wrote in the past two days. It’s a very common application. You can find it in the Game Design book by Rex van der Spuy and hundreds of other places. You randomly decide who is stronger, the player or “enemy”, one wins the exchange and points change  - a pretty standard game component.

function sink(thing) {
// The player’s strength ;
var playerStrength = Math.ceil((food+ health)/2) ;
var rockStrength = Math.ceil(Math.random()* playerStrength*2) ;
// Find out if the player strength is greater than the rock strength ;
if (rockStrength > playerStrength){
// The rock sinks the canoe ;
var lostFish = Math.round(rockStrength/2) ;
food -= lostFish ;
// Player gains experience ;
experience += 1 ;

 

To compute the player’s strength, I take the average of their food and health points, and round that up. That’s the ceiling function. To understand this, you must have some idea of order of operations – things in parentheses get done first – to understand that first I’m adding the two values and then dividing by 2.

You need to know that having that slash and then a number means to divide by a number.

That is math and not everyone knows it.

A ceiling function rounds up – and to understand that, you need to understand the concept of rounding.

To understand the second statement, you need to know what a random number is, that the * means to multiply. You also need to know that the random function generates a random number between 0 and 1 and realize that is a continuous distribution because there are an infinite number of numbers between 0 and 1.

That is math and not everyone knows that.

You’d have to realize that since the random number function is between 0 and 1, if you just multiply that number by the player strength it is ALWAYS going to be less or equal and the “enemy” will never win. Since, on the average, the random number will be .5, if you multiply by 2, that makes it equally likely the player or enemy will win and gives you a game of chance.

To change the probability of the player winning the exchange, you can make that number larger or smaller.

You need to know that the > means that the thing on the left is greater than the thing on the right.

All of that is math and not everyone knows it.

The people who want to teach kids to code assume that either,

a. Everyone knows this much math – in which case they are OH, SO WRONG!   or …

b. That they will work with the minority of students who do.

There is absolutely nothing wrong with option B. I wish you the best of luck with all my heart and will do whatever I can to help.

Most of what I can do to help is make games to teach math, so that more kids will fit with option B.

There is an option C, which intrigues me, and I have heard very few people discuss, which is to teach the math along with coding. That is certainly not impossible - but it would be hard – you would need students very motivated to put in the time and effort and teachers who were able to step back and start at whatever level of math competency required by an individual student.

This whole thing reminds me yet again of the comment made by Dr. Irv Balow, Dean of the UC Riverside School of Education. Frustrated by reading so much research that said under some conditions class size had an effect, under other conditions, not so much, for some students cooperative learning was a benefit, for others it was detrimental, etc. etc. etc. , a student asked,

“Isn’t there anything in education or psychology we know as absolute, unqualified fact?”

After some reflection, Dr. Balow replied, that the only thing he could be absolutely sure of was this :

“All of the simple answers are wrong.”

Visual literacy, being the word chooser of this blog, I have decided means the ability to “read” graphic information. A post I saw today on Facebook earnings over time gave a prime example of this.

 

Chart of Facebook earnings by region

If you are a fluent “visualizer”, then just like a fluent reader can read a paragraph and comprehend it, summarize the main points and rephrase it, you could easily grasp the chart above. You would say:

  • Over two years, the number of users from the U.S.  & Canada has grown relatively little.
  • The U.S. / Canadian market was the lowest number of users for the past two years
  • Europe was the next smallest market and grew about 20%  over two years.
  • Asia was the second-largest “market”, second only to “the rest of the world”
  • The U.S/Canada and European markets are shrinking as a percentage of Facebook users

My point isn’t anything about Facebook or Facebook users. I don’t really care. What I do want to point out is that if you are reading this blog, you probably found all of those points so obvious that you wonder why I am even mentioning. Of course, you are reading this blog, so no one needs to explain what those black letters on the screen mean, either.

My point, and I do have one, is that somehow, somewhere, you learned to read graphs like that and that is an important skill. Most likely, you are fluent . That is, many people could perhaps puzzle out what that graph means, just like many people who are not proficient readers can sound out words and kind of figure out the meaning of a paragraph or two. Those people do not generally read War and Peace, or The Definitive Guide to Javascript.

The need for visual literacy is all around you – and that’s my real point.

 

 

 

 

 

If I had a clone, all of my code would be beautiful.

St. Paul's butte

Last week, I was a speaker at the Tribal Disability Conference in Turtle Mountain, where I spoke on starting a business. Then, I went for a site visit at Spirit Lake Vocational Rehabilitation followed by another talk on self-employment at the Tribal Disability Awareness conference. In a nutshell, I talked about how having a disability often teaches people to persevere, to not accept when told they can’t do something, to find different ways of meeting goals and solicit other people to help them – and pointed out that all of these traits can be an advantage in starting a business.

Along the way, I was working on a couple of grants, edited a couple of papers – and just this second remembered I have to finish editing a paper I co-authored for something – crap!

There was also the usual matter of approving payroll and invoices, answering email and reviewing work people did while I was gone – new teaching videos to go into the game, artwork, animation, sound files,documentation, bug fixes. Haven’t nearly finished with that.

I’m super-stoked to be on a panel on Monday at the National Council of La Raza conference, “Economic Empowerment in a Wireless World”. I’m planning on going Sunday as well, to a lot of the sessions on education.

Heidi Heitkamp

I got to hear Heidi Heitkamp speak at Turtle Mountain last week and with any luck I’ll be able to attend Elizabeth Warren’s talk on Sunday. Must be my week for Democratic senators.

Somewhere in all of that, I finished my slides and video for the Serious Play conference, also this week, which I am also excited to attend.

Then, there was the meeting people for lunch, stopping in on my daughter who had surgery and checking on her and all of the other general life things. There is a board meeting I have to get up and go to in about nine hours, which I am definitely NOT excited about, but I’m the chair, so I kind of have to show up.

In the midst of all of this, there are 77 fixes and improvements in the Fish Lake game, from “add a better message when the pretest is completed” to “Revise quiz code for re-routing students. This is replicated in many quizzes. Make external file ref & just call it in all of those”.  Some of those are crucial – like I never wrote the quiz for one spot and so that is a dead end.

There are another 47 improvements for Spirit Lake. All of those are to make the game better. For example, we recorded voices from kids at Spirit Lake, and when a student gets a problem wrong, I want to add a video clip that shows one of the game characters and says something like,

“No, 7 x 8 = 56. Now your village burned down.”

The kids did a great job and I think those clips will really help players remember their multiplication tables.

burning village

But … back to my missing quiz. It has to be on mixed fractions, with questions answered using both improper fractions and mixed fractions. There also should be a question with two answers for the numbers that the mixed fraction falls between. Also, at least two word problems, with answers that are whole numbers.

As each question is answered, the program needs to determine if it is the right answer, and, if so, add to the total score, then show a slightly more difficult problem. At the end of the quiz, the student is shown  a success message and the student data written to our database and routed back to the game. If it is the wrong answer, the student is shown a failure message and routed to the appropriate page to study.

In the process of writing this, by the way, I noticed that one of the links on the study page is wrong, so I need to fix that. Apparently, I meant to write something involving turtle eggs. Also, there is a video Diana did on mixed fractions which I have yet to review because I got back at midnight on Wednesday and dived into everything else.

So … back to my no-longer-missing quiz. It is done. I even put in a few comments. As I was writing it, I was thinking, “some of this code is duplicated” and “I bet I could re-write some of these functions so they were more general and then not have so many functions” and a whole lot of other ideas for making it just a better program.

I KNOW that the world is full of code that gets written to be fixed “another day” is still sitting there six years later. In my defense, I will say that I do often loop back around and fix that code – although it might be a year or two later.

Here is my compromise – when I am in town, I try, come hell or high water, to make at least one substantive improvement on one of the games every day – a new video clip, a new quiz. At worst, I may not get any more done than fixing a broken link or touching up a graphic or sound file, but I really try to do more than that. Those 124 fixes are down from 266. It is not perfect but it is progress and it is 1 a.m. In addition to writing this post, I did review one more instructional video and sent feedback, finished the first draft of editing the paper and added improving the code in this quiz as a lower priority game fix.

My code is not perfect but it works, and I will come back and try to do better tomorrow because, at the end of the day, there’s another day. That’s how time works.

 

 

 

When we started the Dakota Learning Project to evaluate our educational games, I wondered if we had bitten off more than we could chew. We proposed to develop the games, pilot them in schools, collect data and analyze the data to see if the games had any impact. We were also going to go back and revise the games based on feedback from the students and teachers.

Some people told us this was far too much and we should just do a qualitative study observing the students playing the game and having them “think aloud”. Another competition we applied to for funding turned us down and one of the reasons they gave is that we were proposing too much.

We ended up doing a mixed methods design, collecting both qualitative and quantitative data and I’m very glad I did not listen to any of these people telling me that it was too much.

There is no substitute for statistics.

When I observed the students in the labs, I thought that perhaps the grade level assigned to specific problems was inconsistent with what the students could really do. For example:

Add and subtract within 1000 … is at the second-grade level 

Multiply one-digit numbers  … is at the third-grade level

It seemed to me that students were having a harder time with the supposedly second-grade problem, but I wasn’t sure if that was really true. Maybe I was seeing the same students miss it over and over. After all, we had 591 students play Spirit Lake in this round of beta testing. It was certainly possible I saw the same students more than once. It is definitely the case that students who were frustrated and just could not get a problem stuck in my mind.

So …. I went back to the data. These data do double-duty because  I’m teaching a statistics class this fall and I am a HUGE advocate of graduate students getting their hands on real data, and here was some actual real data to hand them. (I always analyze the data in advance so it is easy to grade the students’ papers, to give examples in class and so l don’t get student complaining that I am trying to get them to do my work for me, although they still do. Ha! As if.)

We had 1,940 problems answered so, obviously, students answered more than one problem each.  Of those problems, 1,053, or 54.3% were answered on the first attempt. This made me quite happy because it is close to an ideal item difficulty level. Too easy and students get bored. Too hard and they get frustrated.

I used SAS Enterprise guide to produce the chart below:

chart showing subtraction in the middle of difficulty range

You can see that the subtraction problem showed up about mid-range in difficulty. Now, it should be noted that the group gets more selective as you move along. That is, you don’t get to the multiplication problems unless you passed the subtraction problem. Still, it is worth noting that only 70% of fourth- and fifth-grade students in our sample answered correctly on the first try a problem that was supposedly a second-grade question.

Because we want students to start the game succeeding, I added a simpler problem at the beginning. That’s the first bar with 100% of the students answering it correctly. I won’t get too excited about that yet, as I added it later in the study and only a few students were presented that problem. Still, it looks promising.

So, what did I learn that I couldn’t learn without statistics? Well, it reinforced my intuition that the subtraction problem was harder than the multiplication ones and told me that  a substantial proportion of students were failing it on the first try. It was not the same students failing over and over.

The second question then, was whether the instructional materials made any difference. I’m pleased to tell you that they did. On the second (or higher) attempt, 85% of the students answered correctly. If you add the .85 of the 30% who failed the first go-round to the 70% who passed on the first attempt, you get 92% of the students continuing on in the game. This made me happy because it shows that we are beginning at an appropriate level of difficulty. I would have liked 100% but you can’t have everything.

I should note that the questions are NOT multiple choice, and in fact, the answer to that particular problem is 599, so it is not likely the student would have just guessed it on the second attempt.

 

 

Next Page →