Saturday, August 27, 2016

I Aspire to Be a Second Rate Designer

My goal in this essay is to confront the unfortunate rhetoric that pervades most professional careers, namely that our goal should be to be the very best. Of course, taking any alternative position is a precarious place to occupy, because one would be subject to the criticism of being a slacker, or someone who is satisfied with mediocre work. I stand in neither of those places, but I am very pragmatic and realistic about my abilities and aspirations. As I have worked with both faculty and students at the University of Georgia about designing learning experiences and environments, I've seen too often the paralysis that can occur with just the thought that one's work is no good. I especially want my students to take on the identity of "designer," but this is something many resist. They feel they don't yet quality for such a title. My position is simply you are a designer or you can be a designer by choosing to do so.

The inspiration for the title of this essay comes from a comment I remember Steve Jobs making about Microsoft products. My memory was that he called them, as a whole, second-rate. As it turns out, my memory was kind to Microsoft because Jobs actually called them third-rate:
I guess I am saddened, not by Microsoft's success – I have no problem with their success, they've earned their success for the most part. I have a problem with the fact that they just make really third rate products. (1996) [citation]
I remember thinking at the time how I wish I could design software as good as that sold by Microsoft. Second-rate in this context seemed like an excellent aspiration. Yes, I long admired Steve Jobs' pursuit of perfection and remain very inspired by the excellent products and software produced by Apple. But, his vision within an environment of very talented (and well compensated) people is not one that I can put into practice myself.

Consider the following saying, attributed to Voltaire: "Perfect is the enemy of the good." I first heard this a long time ago in the context was that we should never be satisfied with something just being "good enough." Instead, we should strive for perfection. (An essay by Charles Osgood on being "pretty good" makes the same point.)

In contrast, I interpret this quote in exactly the opposite way. I view the strive for "perfection" as a debilitative or paralyzing state that usually results in a person either not trying at all or just giving up. And, apparently, Voltaire agrees with me, if you can believe the Wikipedia entry.

A more modern version comes from Sir Robert Alexander Watson-Watt, a pioneer in the development of radar during World War II: "Give them the third best to go on with; the second best comes too late, the best never comes." Given the war context of this quote, I can easily imagine the sense of urgency to just get on with it and stop all sniffling about it not yet being good enough.

Design Thinking


I've read a lot of the "design thinking" literature over the past couple of years. A really good book that I use in one of my doctoral design courses is Creative Confidence by Tom Kelly and David Kelly. Here is a link to a great TED talk by David Kelly about this. Here a few good quotes from the book about the potential for everyone to be a creative designer:
"One prerequisite for achieving creative confidence is the belief that your innovation skills and capabilities are not set in stone. If you currently feel that you are not a creative person – if you think, “I’m not good at that kind of thing” – you have to let go of that belief before you can move on." p.30
 On Bandura's concept of self-efficacy:
“Doubts in one’s creative ability can be cured by guiding people through a series of small successes. And the experience can have a powerful effect on the rest of their lives.” p. 40
 On the failure paradox:
“A widely held myth suggests that creative geniuses rarely fail. Yet … the opposite is actually true: creative geniuses, from artists like Mozart to scientists like Darwin, are quite prolific when it comes to failure – they just don’t let that stop them.” p. 40
 On permission to fail:
“…you can get better faster at coming up with new ideas if you give yourself and those around you the leeway to make mistakes from time to time.” p. 49
And finally a good reminder that creativity is an innate human characteristic:
"We forget that back in kindergarten, we were all creative. We all played and experimented and tried out weird things without fear or shame. We didn’t know enough not to. The fear of social rejection is something we learned as we got older. And that’s why it’s possible to regain our creative abilities so swiftly and powerfully, even decades later." p. 6

Me and My Accordion: Love Unrequited


And yes, this is an actual photograph of my accordion!

I think a good way of thinking about this issue is by analogy to writing or music. Just as many resist taking on the identity of designer, people are likewise hesitant to assume the mantle of writer or musician, even if they have been keeping a diary or journal for years, or have long enjoyed playing a guitar or other instrument as a hobby. Many feel the identity of writer or musician is reserved for those special few who have achieved success or acclaim.

Allow me to tell you a little story about me and my accordion. My story mirrors the classic Greek theater experience in that it contains both comedy and tragedy. In the last 30 years or so, I've focused solely on the comedy. I'm the guy at the meeting who says, "I'm not sure that's a good idea, but hey, I play an accordion, so what do I know." But, there was a time when I thought I could be a good, even great, musician if I just practiced hard enough.

I took accordion lessons for four years from the age of about 8-12 from the truly great accordionist Steve Seventy - a legend on the Southside of Pittsburgh who unfortunately died in 1988 at the young age of 61. (His name is not pronounced "70" by the way, it is pronounced "se-VEN-tee".) I paid for these lessons myself with my paper route earnings. I stopped taking lessons at about the time I started high school because practicing had long become a chore, not a passion. But, around my junior year of high school, I regained an interest in music and thought to myself that if I practiced long and hard, I could be good. After all, that was the rhetoric I had heard - you can do anything you want if you just try hard enough. I also tried to conquer my fear of performing in public by actively looking for opportunities to play at my high school and church for various occasions. I really tried to be good. The problem, however, is that I was and am a terrible accordion player. I'm missing whatever gene is needed to be musically skilled. My greatest triumph in playing the accordion was when I was a public school teacher and played for my elementary school students. They didn't care if I good or bad, they just loved the fact that they had a teacher who owned this amazing contraption and something resembling music came out of it when he strapped it on.  I take great satisfaction in thinking that these kids - now in their mid-40s - likely think back fondly to that one teacher who played an accordion. I bet that's one of a handful of things they do remember with a smile from those years.

So, yes, I am a musician, though a poor one. But, I am a better person by having made the attempt. And, making a joyful noise is a noble and honorable endeavor.

Me and LiveCode: 35 Projects in about 40 Months


In my own design work, I know I'll never attain the status of a great designer. But, I love to design and don't want anything to interfere with that passion. I still see the status of a second-rate or even third-rate designer as an aspiration and high achievement. I would only be a step or two away from being a first-rate designer, which would be a tremendous accomplishment.

I actually date my first experiences as a "real" designer to those same years as a public school teacher when I learned how to program in BASIC on the Apple II computer. I actually published two software titles back then. One was a compilation of educational games titled Serendipity, with the most successful being a game to teach fractions titled Mineshaft. The second was a golf game titled rather pretentiously Professional Class Golf. This golf game remains my magnus opus and I keep an old Apple IIe in my office so I can play it occasionally.

Writing this essay gave me some reason to pause and reflect on my experience these past few years learning LiveCode. Using January 1, 2013 - the launch date of this blog - as the starting point, I've designed about 35 LiveCode projects in about 40 months, just about all of which I've written about in this blog. The projects have been big and small, though mostly small. Very few are worth more than the virtual ink I've used to write about them, but that is beside the point. I'm a designer because I design and build.



A collage of "first rate" designers resulting from a Google search of "great designers." (Genius, I know.) A special tribute to Steve Wosniak, one of my personal heroes. "The Woz" gets much too little credit for his contributions to the culture of Apple, in my opinion. I always highlight Frank Lloyd Wright because, well, his middle name is "Lloyd."

Final Thoughts


So, it is with courage and conviction that I hope everyone will replace any aspirations to be the top "anything" in their field with simply being the best you can be, knowing that you will improve only by doing something. This means that you will do your very best, but realize that when you are judged against the best in your field, you will likely not stack up too well. And that's OK. So, instead of striving to be a sport's MVP, strive just to make the team. Become a writer not to make a million dollars with a best-selling novel, but to express yourself or to communicate well with your colleagues and friends. Instead of producing the world's next killer app, design something that will help just a few people in some small way.

Trying to be the best you can be will make you want to try to do things you never did before. The key idea here is that you, and you alone, will be the judge of your success. If someone else judges you and criticizes you, you will know whether or not you did your best. You should accept the criticism, perhaps with an ear or eye toward something useful in the person's feedback. That is, instead of feeling "destroyed," you should be open to some information that will improve what you've already done. This is a very empowering and liberating feeling.

And, if you think your ideas are so obvious as not to have any worth, then check out this video by Derek Sivers:


Reference


Kelley, T., & Kelley, D. (2013). Creative Confidence: Unleashing the Creative Potential Within Us All: New York: Crown Business.


Postscripts


1. I gave a presentation with the same title as this essay on August 19, 2016 at the 3rd annual IDD@UGA Conference in Athens, Georgia.

2. It also just occurred to me that my taking on the identity of designer came at the very same time as my most successful accordion experiences. Hmm, maybe that's a correlation worth exploring and advocating.

Sunday, August 7, 2016

Did You Hear the One About ... Affordances of a Digital Q Sort Activity

I heard a good joke recently. Here goes...

"A rich miser made his wife promise that when he died she would bury all of his money with him. After he died, at the funeral, she placed a box inside the casket with him. Later that day, a good friend asked the widow if she actually put all of his money in that box. The widow replied that she complied fully with her husband's wishes. 'On the day that he died, I put all of his money...'"

I'm going to be a little cruel and not tell you the punch line right away. What gives? Well, I'm doing this to make a point. And don't worry, I'll finish the joke near the end of this post.

Here's the main idea: Like good comedy, timing is important in good teaching and learning. For example, if you are a science geek like me and someone shows you a cool experiment with results that don't match your expectations, you want a full explanation of what's going on right away. (I always refer to this as the "Mr. Wizard Approach," in honor of Don Herbert and his teaching strategy on his popular TV shows of years long ago.) When curiosity and interest are piqued, a teacher has a unique learning opportunity, sometimes referred to as a "teachable moment." The need or wanting to know something is a powerful force that the best teachers leverage. Of course, if the teacher waits too long or doesn't recognize the opportunity, the moment will be lost, perhaps forever. How long is too long? Well, it all depends, doesn't it? Perhaps you've already lost interest in my joke and have moved on to checking Facebook. Or, more likely, you've skipped all this blather to try to find out the punch line below. (Well, maybe it's not there - boy, that would be cruel.)

OK, now let me get to the specific point of all this. I have recently been collaborating with Brandy Walker and Rich McCline of the Fanning Institute here on the University of Georgia (UGA) campus on the topic of using Q sorts within an instructional or learning setting. Brandy and Rich do a lot of outreach to community groups and organizations within the state of Georgia. Their work is not so much instructional as it is facilitative - that is, they try to help groups clarify goals and issues so that these groups can make good decisions. They have been using Q sorts within many of their workshops as a way to help the participants understand their subjective perspectives on the various important issues that the group is facing.

Brandy and Rich have been implementing paper-based Q sorts, so they are interested in the opportunities afforded by the digital tool I've slowly been developing. However, in one of our recent meetings, we began to talk about just what are the affordances of a digital approach, and also what are the affordances of the paper-based approach. To be sure, there are many excellent affordances to the paper-based approach. The tactile and visual elements of having a large Q sort board lying in front of you as you move the small statement cards about are very strong. It's also a very intuitive process. You know exactly what you are doing and it is easy to make quick modifications. The other significant affordance is the ability to have a Q sort with a large number of statements. The most I've seen in the literature is around 65 or so. After all, you have the entire space of the table at which you are sitting to use.

In contrast, my digital version currently only allows a maximum of about 25 statements and this is a real limitation to any serious Q sort researcher. It's not a big limitation for my purposes given my interest in using the Q sort activity as an instructional activity, but I know I need to think about ways to expand the number of statements while remaining true to the original Q sort procedure of having all of the statements available to the user as the sorting activity proceeds. Other electronic versions I've seen perform the activity in a fashion where you group the statements in stages, starting with low, middle, and high piles as step 1, then only work with those piles sequentially in the subsequent steps. I admit that I'm resisting that approach as I think it violates some aspect of the true Q sort approach. (I may be wrong.)

OK, So What Are the Affordances of a Digital Version of the Q Sort Activity?


Despite the charms and history of the paper-based version of the Q sort activity, I firmly believe that my digital tool offers significant advantages over paper-based approaches. As Brandy, Rich, and I quickly discussed the pros and cons, I agreed to come up with a tentative list of affordances for my digital approach. So far I've come up with four main affordances:
  1. The easy preparation of an unlimited number of Q sort activities.
  2. The easy and quick administration of any single Q sort activity either in a face-to-face or online environment (synchronous or asynchronous).
  3. The ability to administer multiple Q sort activities within a single session easily and quickly.
  4. The ability to provide real-time data analysis (suitable for instructional purposes) quickly to the participants during an active Q sort activity.
You should notice my fondness of the words "easily" and "quickly."

To conduct a Q sort with my digital tool, you enter a special code given to you by the instructor to bring up the Q sort activity. This code simply queries an online database that transfers the statements needed for the Q sort and also produces a Q sort board with the right number of slots. After the person finishes the Q sort, the answers are uploaded to the database. If I want everyone to do another Q sort, all I have to do is give them another special code and the app automatically and immediately resets. Creating the Q sort itself takes maybe 10 minutes once you have the list of the statements. I built the database to make it easy to duplicate and revise any Q sort in the library.

The fourth affordance is one that I've worked on quite a bit this summer with the two online courses I've been teaching at the University of Georgia. Up until the most recent version, only the instructor (aka me) could do the "quickee analysis" and then share the results with the group. The latest version of my Q Sort Tool puts these analysis features into the hands of the students. As soon as they complete a Q sort, they can then begin checking the results. I made several videos demonstrating and explaining all this for my students, but I'm not able to share these here because they contain personal data. Soon, I'll create some videos with the personally identifying information removed or masked in order to demonstrate how this feature works.

Why are these affordances so noteworthy? Again, you have to consider all this from a teaching and learning point of view. It's one thing to conduct a research study using Q methodology where the data are collected, analyzed, and reported. This involves a process that can take weeks or even months. The goal of traditional Q methodology is to better understand what are the different profiles within a group describing their subjective interpretations of a particular issue or topic. For instructional purposes, the goal is to get people to think deep and hard about a particular topic, followed by having some good discussions, reflections, and more discussions and reflections during a period of time when people actually care about the topic. These reflections are enhanced if you also know and consider your classmates' points of view.

Comparing the Digital to Paper-Based Q Sorts for Instructional Purposes


When Brandy and Rich conduct their Q sorts in their workshops, they have to prepare sufficient copies of the paper-based statements for every person attending the workshop. They also have to prepare a paper-based Q sort board for each person to use. The materials then have to be carefully assembled and distributed during the workshop. Brandy and Rich also prepare and post the statements on large flip chart paper mounted on walls around the room. Everyone then completes the Q sort individually. When finished, everyone is prompted to write down the statements they placed at the extreme ends of the Q sort scale. They are given a sheet of sticky green dots and red dots and told to find those statements on the flip chart paper on the walls, putting a green dot beside those statements they agreed with the most and red dots by those statements they agreed with the least. Then, Brandy and Rich use the flip chart paper and pasted dots to lead and facilitate a reflective discussion about the topic with the group.

It should be noted that the Q sort topic that Brandy and Rich conduct is based on a well-researched survey instrument that Rich has produced and validated over the years. Therefore, the statements they use in the Q sort are not submitted by the participants. Obviously, if the procedure was to engage the participants first in producing their own individual statements, they would have to figure out a way to get those statements far in advance of the workshop in order to have enough time to prepare the statement cards. In their case, they recycle the cards for the next workshop. I don't know if they would ultimately find tiresome the labor needed to constantly produce new statement cards for a new Q sort for each workshop group. That is, I wonder if they would abandon the Q sort activity under those circumstances. The other consideration is that the number of Q sort statements would have to vary, which would mean having at the ready Q sort boards with the right number of slots.

Most of the comparisons we could make between a paper-based and digital Q sort boil down to logistics, but there are cognitive issues at play here too. For example, I think it makes a profound difference if the Q sort statements are based on the participants' own views. I think this makes the Q sort itself much more meaningful and authentic because each participant is given a window into the thinking of their peers as they complete the activity. It's also quite meaningful and motivating to see your statement among the list. But, I think there is another important cognitive issue that relates (finally) to the issue of timing.

The Clock is Ticking


There are many things one can conclude from comparing paper-based and digital Q sorts. Let's say that you are perfectly willing to spend whatever time it takes to prepare the paper-based materials. But, consider the time it takes between a single person completing the Q sort and the start of the reflection and then the small- and large-group discussion. I assert that if too much time transpires then the "teachable moment" is seriously threatened. That is, people may either lose interest or forget the point of the exercise. Of course, knowing that Brandy and Rich are expert workshop leaders, they likely use the time well and engage people in conversations while everyone is up and about putting their red and green dots on the mounted flip charts. And, I can see some real affordances to the social aspect of this milling about that an expert workshop leader can leverage. Still, I think reducing the time between completing a Q sort individually, reviewing the group results, and then holding the reflective discussions is overall the preferred approach.

The point - again - is that timing is everything. Which reminds me...

"On the day that he died, I put all of his money in a bank account and I wrote him a check."

Yes, that is the punch line to the joke that began this blog post. Hmm, do you remember the set up?

(I heard this joke from Professor Young-Suk Kim of Florida State during her excellent talk at the 2016 AERA Conference in Washington, DC.)

Final Thoughts


I'm obviously a little biased here given the many, many hours I've spent developing my little digital Q sort tool and the web site with the database backend I've designed to support it. To be sure, there are many limitations to my digital approach. The most noteworthy is one I've already mentioned - the relatively limited number of statements that can be used. Another limitation is the fact that my tool is not web-based. You have to download and install a client-based app on your computer, which many people are reluctant to do, or simply find very bothersome to do. There is also a certain level of opaqueness in using any digital tool when compared to the totally intuitive nature of moving slips of paper around on a table, a difference that is not trivial.

As I end this posting, I think an additional and noteworthy point to be made is that my tool can also be used for traditional Q sort research. That is, my digital tool quickly and easily collects data in the needed format for uploading into a bona fide Q sort analysis program. Brandy and Rich also collect the full data for subsequent analyses. The IRB procedures they follow start with taking a photo of each person's completed Q sort (with the participant's permission). Later, someone from Brandy's research team manually enters each Q sort into an Excel spreadsheet. The steps Brandy and Rich need to complete to get to the point where they can run a statistical analysis is time-consuming and - from my perspective at least - arduous and cumbersome. Of course, I could not think of a better way to do it.

As I hope is evident, getting all of the Q sort data collected and ready for analysis in a paper-based approach is no small chore. The choice is either to convince each participant to accurately record their Q sort results to yet another medium (paper or a spreadsheet), or having the researchers move around the room to record the data in some fashion. The Q researcher yearns for "quickly and easily."

An aside, but it's also been on my mind that an interesting research study would be to compare the outputs of my "quickee analyses" with the traditional Q-style factor analyses. I hope to either focus some research on that question myself or support an enterprising doctoral student who would like to take it up.

The other thing that I always find fascinating about producing digital tools is the ability to come up with small, but important variations in the tool or what it can do. These are often made in combination with creative changes or enhancements to the instructional approach. It's amazing how many times an idea comes up with the preface "If only your tool could do this..." It's usually very easy to make these sorts of small revisions or enhancements.  But, again, I don't want to discount the hands-on tactile feel of moving paper or cardboard around on the table, or having a reason to get up and move about the room and having some short or long conversations with other people doing the same thing. I don't want to live life only in front of a screen. But, I think creative and innovative teachers always take full advantage of the affordances of all of the available resources available to them.

Monday, July 4, 2016

Lloyd's Physics Simulation: Prototype 1

I'm a real physics geek. If I see a cord hanging from a ceiling light swaying back or forth, I'm immediately enthralled with the physics of the motion. I can easily imagine Galileo using this pendulum as a timing device. I can quickly conjure up Einstein's thought experiment about the equivalence principle. This principle imagines one being sealed in a little rocket ship without windows and wondering - is this light cord swaying back and forth the way it is because my rocket ship is accelerating somewhere deep in space, or is my rocket ship still sitting on the launch pad and therefore in earth's gravitational field? The cord will produce the exact same pendulum swing in both scenarios.

I'm a proud owner of the three volume set of "Lectures on Physics" by Richard Feynman - also known as the "red books," and many of his other "less technical" publications, such as his book "Surely You're Joking, Mr. Feynman!" (A real Feynman fan knows the story behind the title; hint: it's about being subjected to another's pretentiousness.) Perhaps my favorite little anecdote in one of his writings is the example of why flanges on railroad car wheels are unnecessary - it's because the inner surfaces of all the wheels are curved. This causes the wheels to always "fall back" toward the center of the track - the flanges are there just as a precautionary, safety device, but really are not necessary. In fact, you should stop reading this blog right now and immediately begin watching part 1 of the recording of The Character of Physical Law at Cornell in the 1960s. (The introduction of Professor Feynman by then provost Dale B. Corson in this very first video is very funny.)

I could go on and on. In short, I may not be a physicist, but I know what "matters."

So, why didn't I become a physicist? Simply put, learning physics is really hard and, honestly, the mathematics of it all is beyond me.

So, what to do? Well, retreat to what I understand, of course, and that takes me to Newton's Laws of motion. I barely understand Newton's Laws of Motion, but I find them a constant source of inspiration and wonder. They seem so simple at first glance - an object in motion stays in motion, etc., but it gets complicated in a hurry as you consider that these laws of motion explain the orbits of the planets and were used to get Neil Armstrong, Buzz Aldrin and Michael Collins to the moon. (I've always had a fondness for poor Michael stuck in the command module orbiting the moon as Neil and Buzz were walking around about 70 miles below. So close.)

One other very timely example of the importance of Newton's Laws of Motion is happening right now. As I finish writing this blog posting on July 4, the Juno spacecraft is scheduled to reach its destination - Jupiter - this evening. In order to attain an orbit around Jupiter for the spacecraft to carry out its mission, it must slow down sufficiently for Jupiter's gravity to snag it. For that to happen, Juno's engine must fire for about 35 minutes at just the right time. If that fails to happen perfectly, Juno will just fly by Jupiter and the mission will end in failure.

Lloyd's Physics Simulation


A really good starting point for applying the laws of motion to everyday events is understanding the relationship between acceleration, velocity, and distance. This relationship has fascinated me since I was in high school. It's one of those sets of principles that seems perfectly easy to understand - until you really try. Then, when you finally get it, the understanding opens all kinds of doors to other learning. Differential calculus is a good example. Velocity is the first derivative of distance and acceleration is the second derivative of distance. This means that acceleration is the first derivative of velocity. Well, of course.

Wait, don't close that browser window! Let's explore acceleration, velocity, and distance by playing the first prototype of "Lloyd's Physics Simulation." This app is the result of only about five hours of work.

One of the most exciting developments in the LiveCode world is the option to export projects as HTML5, so I thought I would use this option to share this project, but you can also choose to download one of the standalone versions, or just watch a very informal video demonstration I made for my summer design course I'm teaching for the University of Georgia.

HTML5 Alert! It will likely take awhile to load the first time you run it. Depending on your Internet speed, it might even take a minute or two. So, be patient.




 Video Demo


If you ran the HTML5 version, you may have noticed some "weirdness" in how the simulation runs on the second or third try. The simulation speeds up for reasons I cannot explain. At some point, the simulation becomes unplayable. This does not happen when you run it as a standalone app. One simple solution is just to reload the web page in the browser. (This won't take as long as the initial download.) I plan on submitting this problem to one of the LiveCode user forums.

If you have been able to play the simulation, I hope you begin getting the gist of the relationship between distance, velocity, and acceleration. Distance is simply the how far the marble has gone in either direction in a given time. Velocity is the change in distance, such as 20 pixels per second toward the top at any particular moment in time. Acceleration is just the change in velocity, though it is usually expressed with the odd sounding phrase of "per second per second." But, that apparent redundancy actually explains acceleration well because if the velocity is changing (i.e. acceleration is not zero) the change in the ball's speed is likewise changing constantly. You get those really beautiful parabolic curves when the marble is accelerating. You will notice that the distance graph is a straight line whenever acceleration is 0 because only then is the velocity constant. These are just some of the patterns that will emerge if you pay close attention as you run the simulation.

OK, It Was Kind of Fun Trying Out the Simulation, But I Got Bored Quickly


Yes, unless you are a physics geek too, you will probably get bored quickly with this little simulation. There is the little challenge of keeping the marble from sliding off of the yellow track, but that gets old quickly. What to do about this? Well, that's where the design possibilities can get very interesting. I actually did a bunch of research about simulations as a learning tool some years ago. I always considered it a fundamental question of how much structure to overlay onto a simulation. I was keen on understanding to what degree completely free and open-ended exploration within a simulation would result in learning and motivation about the content of the simulation. Most people do get bored quickly when there is no structure. So, I began to experiment with overlaying simple design elements, such as little games. I wanted to see to what degree people needed more and more structure, which would culminate eventually with the ultimate in most structured designs, namely instruction. Some of my early work led to the design of a software package titled "Space Shuttle Commander" where the player was asked to do just that - be the commander of the space shuttle. To be successful, you had to know, or learn about, Newton's laws of motion. I gave it away for free and NASA actually published it among their free educational resources. Alas, this was many years ago and it only ran on the Apple IIe platform.

Here's a link to one of my "classic" (aka old) research articles about this (the complete reference to Rieber, Tzeng, & Tribble, 2004 is below). In other research studies I conducted specifically on the relationship between acceleration and velocity, I took advantage of that special moment when the marble changes direction. I called it a "flip flop" and built a little game around it.  I won't go into the details of that game now, but imagine what kind of games could be designed with this little simulation. For example, I can imagine having targets placed within the area of the line graphs that you have to try to hit with one of the graph lines.

Final Thoughts


You may have noticed my use of thick, thin, and dashed lines for the various graphs. We have been reading about accessibility issues in my UGA design class. If you are color blind, you would have difficulty taking advantage of the fact that I color coded the various graphs. But, by varying the line styles, you should be able to distinguish each of the graphs.

So, the laws of motion may not be as sexy as Einstein's relativity, Heisenberg's Uncertainty Principle, or Schrödinger's cat. But, for just about everything you and I observe in the world around us, they work very, very well. And, as my good friend and former Texas A&M colleague Ron Zellner is fond of saying ... "Action - Reaction. It's not just a good idea, it's the law."

Reference


Rieber, L. P., Tzeng, S., & Tribble, K. (2004). Discovery learning, representation, and explanation within a computer-based simulation:  Finding the right mix. Learning and Instruction, 14, 307-323.

Postscript


I've never been very certain about Heisenberg's Uncertainty Principle. As far as I can tell, I can either know where I am or where I'm going. Which would you prefer?


Monday, May 30, 2016

Lloyd's Video Analysis Tool: Now in the Mac App Store




Yes, Lloyd's Video Analysis Tool, an app I started over two years ago was just accepted by Apple and is now in the Mac App Store. It took three tries to get it in and although there was much frustration and anxiety associated with the first two rejections, I learned a great deal about many things, some of which I'll try to summarize briefly in this post.

First, some words of thanks to two people in the LiveCode community who helped me get through the last grueling quarter mile on this project: Klaus Major and Jacqueline Landman Gay. I also need to send special thanks to Sam Rowlands of Ohanaware. Apple found a bug in my app the second time they reviewed it which led me to a very confusing journey into the world of Apple's sandboxing approach to apps. I was finally able to understand the problem well enough to come up with a workaround thanks to their help. While on the subject of Ohanaware, they make a fantastic product called App Wrapper 3 that I heartily endorse. It "wraps" your app with Apple's developer certificates and automatically gets the app ready for uploading to Apple's iTunesConnect. I'll be purchasing a yearly subscription from here on out at a very reasonable cost of only $49.99. (Please note that was an unsolicited and unpaid endorsement!)

A Question I Had Long Pondered: Do I Even Want to Submit to the Mac App Store?


To be honest, I knew submitting to the Mac App Store would probably be a hassle given my previous experience submitting iOS apps to Apple. One has to figure out the whole "Apple certificate thing." Plus, I knew already that it was going to be a struggle to figure out how to then add the proper certificates to my Mac app because, unlike iOS apps, LiveCode does not provide a way to do it as part of the standalone creation process. (As it turned out, App Wrapper 3 made this step incredibly easy.) I also didn't know if my $99 annual Apple developer fee for iOS apps would count for Mac App (as it turns out, it did). In anticipation of all of this, I had done some research on "alternatives to the Mac App Store" and found a company called FastSpring. I like the company and so far they have provided great support. Now that my app is in the Mac App Store, I'm reviewing my options at this point. I still might offer the app for purchase at FastSpring also, assuming it doesn't violate some Apple policy. I already know that FastSpring is fine with me selling on the Mac App Store. FastSpring also did not require the Apple developer certificates, though I knew this would tremendously impact my sales as the app would then not be "recognized" by anyone Macintosh as coming from a "trusted" source due to way Apple's Gatekeeper software works. My point here is that FastSpring has been very easy to work with and flexible. I think further exploring a relationship with them will teach me more about the business side of app development, which I think my students will be interested in knowing more about.

But, I'm getting ahead of myself in telling this story. To back up, I was pleasantly surprised to be able to successfully acquire the needed development and distribution certificates from Apple. And, thanks to App Wrapper 3, I was able to easily add these to my app and produce a downloader file suitable for uploading to iTunesConnect. So, I decided I would just to submit a "lite" version of my app to Apple and sell the app itself on FastSpring.

I was also ambivalent about what to do for Windows users. Almost all of the problems reported by my beta testers over the past year have been about the Windows version. I didn't want to sell something to people if I wasn't confident it would work. All my development and testing of the app was on the Macintosh for the Macintosh, but it's obviously very easy just to also export a standalone version of the app to Windows with LiveCode. And, it did work for Windows users most of the time (as my students who are Windows users reported). So, a few months ago I decided that I would sell only the Macintosh version but the purchase would also come with a free (though unsupported) copy of the Windows version. That is, I would make it clear you were buying the Macintosh product and the "toy inside" (to use a breakfast cereal metaphor) was a free Windows copy. I felt this was ethical and met my own standard of "truth in advertising."

Mac App Store Rejection 1


First, I want to point out that I received feedback from Apple within about two hours of submitting the app the first time. Despite the fact that the app was rejected, I was very grateful for the quick turnaround.

Two reasons were given for the rejection. First, it appeared to the reviewer that it was a demo app and these are not allowed by Apple. I knew that going in and actually made the case in my "Notes to the Reviewer" when I submitted the app that this "lite" version was not a demo in that one could use the app to do real work even though the app intentionally had limited functionality. However, the reviewer still felt I was in violation of Apple's policy, but also gave me feedback that this objection could be overcome simply by indicating that another app would have to be purchased for complete functionality. Even though I felt had already done this, I apparently put this information in the wrong place. OK, so that objection could be easily surmounted.

The second reason for rejecting the app was that "the app enables additional functionality in a non-standard manner. Enabling features within the app with mechanisms outside of the App Store is not permitted." The reviewer is referring to the "unlocking" strategy I created on my own (click here to read about that). I obviously wasn't surprised that this strategy was termed a "non-standard manner," but I didn't think it would be a show stopper. I think the key phrase is "outside of the App Store" because obviously Apple wants all purchases to be made inside so that Apple gets their share.

After sleeping on it, I decided to just go ahead and submit a fully functional app to the Mac App Store. I submitted it around Noon last Sunday.

Mac App Store Rejection 2


Apple responded that they had rejected the app at about 10 pm Sunday evening. Three reasons were given: 1) the app wasn't "sandboxed appropriately"; 2) there was some discrepancy in how I named the app in various places in the submission process; and 3) "Apps that exhibit bugs will be rejected." Reasons 1 and 2 were easy to deal with, but a bug? The reviewer was nice enough to send me a screenshot of the error with a description of what s/he was doing at that moment, which was very helpful. Here's the screenshot:



This screenshot shows LiveCode's "Bug Report" dialog box that I wisely incorporated into the app some time back. Unfortunately, the Apple reviewer did not actually choose to send me the bug report. So, I spent the next day trying to recreate the error.

I actually was able to recreate the error rather quickly given that I knew where to look based on the reviewer's feedback. It was a "division by zero" error, something I had seen before when the video didn't load properly. The reason for the error is that I use a little custom formula that uses the duration of the movie in the denominator. If the movie doesn't load, this value is 0, hence the error. But, I had never seen the error before under these circumstances. Thus began a three day journey into discovering why.

Troubleshooting the Bug


Although I'm tempted to really get "into the weeds" at this point, I'll just jump to the cause and the solution. This is again where I need to thank Klaus, Jacque, and Sam. Without their timely responses to my calls for help, I would still be scratching my head. (If you want to read my detailed description of the error and the troubleshooting that ensued with Klaus, Jacque, and Sam, you can click here to read all about it in my posting to LiveCode's Mac OS forum.)

The problem was rooted in how Apple's sandboxing technology works. I already knew that all "apps were islands" in iOS and Mac OS, so I wasn't trying to write anything outside of the app's sandbox area. But the app does need to read outside the sandbox to get the path to the project video. This path is then stored correctly within the walls of the sandbox. But here was the really confusing part - the app successfully "found" the video outside of the sandbox, but it wouldn't load it. I just couldn't wrap my head around this because the user obviously had successfully been able to get the video to work when the project was first created. Why wouldn't it work now? I became even more confused when I discovered (after a few hours) that if I created a second video analysis project from scratch using exactly the same video, the first, older project would now work! But, if I quit the app and restarted, both stopped working ... unless I created a third project from scratch that also used the same video.

So, I figured the problem had something to do with Apple's sandbox technology. I initially put the blame on LiveCode's Player object. Sam explained to me what was needed to solve this problem, namely the programming some some key "entitlements" into the to allow it to access to the user's main area on the hard drive. Unfortunately, Jacque explained that this solution wasn't possible with LiveCode. I am so grateful to have learned this from Jacque because I likely would have spent many more days trying to figure it out. The solution I finally used is really just a workaround. I discovered that I could "reconnect" an old project to the video simply by asking the user to "confirm" the location and name of the project's video using LiveCode's "answer file" command. It was easy to include in the script the name of the video plus opening the video's enclosing folder in a dialog box. The user simply had to click to confirm the video. This re-established the link to the video and the link was sustained as long as the app was running. Yes, this added a little bit of inconvenience to the user, but there really was no other way to solve the problem.

Third Time's a Charm


I made the modifications along with a few last minute improvements to other parts of app, then submitted my third version to iTunesConnect around 1:00 pm on Friday. I tried to do other work after that, but I found myself checking for email from Apple every few minutes. As the afternoon rolled into the evening, I began to think those earlier speedy turnarounds from Apple were flukes. And, this was the Friday before Memorial Day weekend - the unofficial start to summer here in the USA - so I worried I might have to wait until Tuesday at the earliest to get a reply.

Interestingly, I mentioned to my wife around 7:30 pm that given that Apple's headquarters were in Cupertino, California, perhaps the reviewer was also on "California time" making it was only 4:30 there. I joked that the reviewer would say to him/herself "Maybe I'll review just one more app before my long weekend" with my app being the next one in line. Well, at 7:49 pm, I received an email indicating that my app was now "In Review." Then, at 8:50 pm I received word that my app had been approved!

Giving Out Free Copies


I've also updated the Web site for "Lloyd's Video Analysis Tool" where people can download the free version of the app to check it out before purchasing. This free version still has the "upgrade" feature that unlocks the app with the right secret code to give it full functionality. As I long planned, this will be my way to give out free copies of the app to people of my choice, such as my beta testers, all students and faculty in the College of Education at the University of Georgia, and definitely to Klaus, Jacque, and Sam. I designed the free version so that it would likely be more than sufficient for use by my colleagues who are requiring some sort of video analysis by their students as a course requirement. Having a functional, free version that teachers could use was important to me. I'm not worried about making money on this app, but then again, I'm not opposed to it either.

Final Thoughts


There is so much else I learned that I could write about here. And maybe I will since I took good notes (as always). My understanding of Apple certificates is clearer to me than before, though this still remains fuzzy. This process, at least to me, is about 5% intuitive and 95% memorization (hence the need for good notes). This is the kind of process one tends to learn by repetition. Fortunately, I have several other apps I'd like to wrap with certificates so that Gatekeeper will "trust" them when I ask my students to download and install them.

Now you might be asking how you can get a free copy of the app. Well, if you buy me a beer or two (or three) the next time we meet, that might do it. But, given that the app only costs $7.99 you will probably save quite a bit of money by just buying the app outright!


Sunday, April 17, 2016

Creating a Web Page Pinging Tool with LiveCode to Check a Web Site's Status

Recently, I've been experiencing a lot of trouble with my web hosting company. I won't identify the company... yet ... as I think they may have finally solved the problem. But, suffice it to say that the problem was chronic and severe to the point that I was considering dropping this company after about 10 years of being a loyal customer. The problem was that my web site was experiencing frequent, intermittent periods of down time. Everything was working fine one minute, then the next I was getting the message "Service Unavailable." Two minutes later, all was fine. To the company's credit, each time I submitted a problem ticket they got on it right away and reported back within an hour or two that they had "found the problem and fixed it." To their discredit, they hadn't. I was submitting help tickets over and over with the company coming back each time to tell me that now all was well, when it really wasn't.

The seriousness reached its peak for me when my web site failed to work properly during a research session about two weeks ago while using my Q Sort tool. I had been experiencing system outages the day before and the morning of the research session. A few hours before the research session was scheduled to take place, the company reported that they had "really" found the cause of the problem this time and all was well. For the next few hours, it did seem like all was working fine. But, during the roughly 20 minutes of the research session, about half of the participants experienced Internet problems. This research session was done during a graduate class and everyone -- including me -- thought that the problem was likely due to some bug in my software. (I had made major updates to the software in preparation for this research session. Happily, my Q sort tool actually seemed to work perfectly.) There is nothing worse to a researcher than to lose data after all the time it took to arrange and plan the session.

I again reported the problem to the company and again looked they into it and again they said they had fixed the problem. I then traveled to attend the AERA conference in Washington, DC and put this issue on the back burner. But when I returned to Georgia and began working on the web site, I found the site was down -- very frustrating. Again, to the company's credit, they steadfastly looked into the problem. Perhaps due to an angst-filled trouble ticket message, they moved my site to a different "application pool," and so far everything has been working fine. Of course, given my lack of confidence I found myself obsessively checking the web site over and over throughout the day. And then it occurred to me -- I could program my own tool to "ping" the web site repeatedly and review the result later. If the web site wasn't working at some point, I could then share my data log with the company to aid in their troubleshooting.

Lloyd's Web Site Pinging Tool


I created a LiveCode stack that pings a given URL every so many seconds to see if it returns an expected result or an error. It's important to remember that if you ping just any old web page, you are going to get a bunch of HTML code as the result, and probably a lot of it. So, I created a very simple PHP page that pulled one small piece of data from the mySQL database along with the following message: "Ping Successful." I also did not use any HTML formatting, so the result was a single line of text. Getting this result let me know that everything on my site was likely working fine.

I also put a date/time stamp at the beginning of each result line. If there was a problem, this would tell me exactly when and for how long the problem persisted.

The great thing about this little app is that even though I might check the web site manually and find everything was working, given the intermittent nature of the problem the thought quickly entered my head "Sure, it's working now, but just wait a minute!" Seeing a data log that ran all night or all day showing no problems is real evidence that the problem has indeed been fixed.

Here's a screen shot of the program after pinging my site every 15 seconds for just two minutes:



You can enter any URL you want and any time interval you want. When you start pinging, the live data stream is shown in the field "Live Pinging Data." When you stop the pinging, the data are automatically copied and pasted into the field "All Data." If you start pinging again, all the "live data" are cleared out as the new pinging session begins. The phrase "New Session" is added at the beginning of any new pinging data session to make each session's data easier to spot.

How It Works


The main code is in the button "Start Pinging:"

 global varDataURL, varCheckResponses, varTime  
   
 on checkResponses  
   put the internet date&comma&URL varDataURL after field "log"  
   if varCheckResponses is true then   
    send checkResponses to me in varTime seconds  
   else  
    put "New Session"&return&return after field "log2"  
    put field "log" after field "log2"  
   end if  
 end checkResponses  
   
 on mouseUp  
   put line 1 of field "time to check" into varTime  
   put empty into field "log"  
   put field "URL" into varDataURL  
   put true into varCheckResponses  
   checkResponses  
 end mouseUp  

I created a custom procedure called "checkResponses" that loops as long as the variable "varCheckResponses" is true.  The loop is based on the "send to me" strategy.

All the button "Stop Pinging" does is set "varCheckResponses" to false.

So Far So Good


I'm happy to report that based on the data collected by my pinging tool, my web site has been completely stable for about 48 hours. I ran my program overnight the first day and for a few hours here and there over the next day. My web site might be -- just maybe -- fixed.

So, for now, I'm sticking with the company.

Oh, one more thing. This problem motivated me to learn how to move mySQL data from one web site to another, something I've never done before. I have a PHP/mySQL web site account on one of the servers at my University, so I was going to move everything there if the problem persisted. I had always wondered how difficult it would be to migrate a mySQL site, but never actually learned the steps.

Saturday, March 26, 2016

Lloyd's Weekend STEAM Project Using LiveCode

It was Friday around 5 pm after a long day of meetings and I again had the urge to do something creative as I ended the week. I had seen a compelling video on the Physics & Astrophysics facebook page a few days earlier that captured my attention and the thought occurred to me that I could recreate it with LiveCode. That became my weekend project. I think this is a nice example of a small STEAM (science, technology, engineering, arts, and mathematics) project. I'm a big advocate of adding the arts to STEM initiatives because, as humans, we yearn for beauty and there is much beauty in mathematics and science.

Here's an animation of my project:

I titled the project "circle within circle" because that's exactly what it looks like. However, amazingly, the red marbles are moving in straight lines, not curves. Here is a second animation to prove it:


I See the "A," But Where is the Rest of "STEM"?


The challenge to creating this project - and what was most fun - was figuring out where each marble should start and end. The circle has a radius of 200 pixels with its center located at the screen location of 400,300. (It's important to remember that the 0,0 origin of the computer screen is not the center of the screen, but the top left corner. And, unlike the traditional cartesian coordinate system, the vertical y-axis is positive in the downward direction.) It's easy enough to figure out where the marbles should start and end on the vertical and horizontal lines, but what about those at the various angles, such as 45 degrees? Ah, this calls for a quick refresher of sine and cosine. If just the mention of these two math concepts brings back horror-filled days from high school geometry, then it is high time you revisit them and see them instead as things of beauty. Here's a nice illustration of what they are all about:



As you can see, the cosine is simply the horizontal distance from the center of the circle to the point on the circle matching a given angle. The sine is just the vertical distance. Notice the right triangle that gets formed with the hypotenuse shown in red depicting the angle. We can use the good 'ol Pythagorean Theorem - a2 + b2 = c2 to figure out the lengths of the horizontal and vertical lines. And voilĂ , we have the x and y coordinates.  Most people are a little surprised that a 45 degree angle does not produce x and y coordinators of half the distance of the radius, but instead the distance is .707 of the radius.

Here's an illustration of my LiveCode screen that shows how to figure the starting point for the marble at the 45 degree mark:



Using a radius of 200, the length of the x and y (horizontal and vertical) is 141.4 (i.e. 200 X .707). Figuring the x coordinate is straightforward: 400 + 141.4, or 541 rounded to the whole number. Calculating the y coordinate is a little trickier because of that pesky detail of the 0,0 origin being in the top left corner of the screen. We actually need to figure out how to much to add to the top boundary of the circle, which is 100. So, we have to subtract 141.4 from 200 to get 58.6. We add 58.6 to 100 to get a y coordinate of 159 (again rounded to the nearest whole number).

I then had to use the same logic to figure out all of the other locations for the remaining marbles given their respective angles. Yes, lots of great math going on here! 

My use of a computer programming language (i.e. LiveCode) is the technology part of my STEAM project. And, I'll admit I don't have any engineering or science components yet, but I'm sure you could come up with a few ideas. What comes to my mind is how an internal combustion engine works - the pistons are going in straight lines, which then turn the crankshaft:


But It Doesn't Look Quite Right


Now, you might say: "Lloyd, those marbles aren't exactly creating a circular motion. There is a bit of a hump. And I took a look at the video link you provided above - great background music, by the way - and its animation looked like a perfect circle." Alas, you are correct, and I'm a little befuddled as to how to smooth out the hump. I thought it might have something to do with the timings, but I don't think so. Of course, you might see immediately what needs to be done to make the marbles seemingly move in a perfect circle, so do remember to email me after you figure it out. (Below is my code to help you.)

But hey, this was only a weekend project and I think there is just as much beauty in my imperfect version. 


   put 2 into varTotalSeconds  
   put .25 into varHoldSeconds  
   repeat until the mouseclick  
    //motion 1  
    move graphic "ball1" to 400,500 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball2" to 324,486 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball3" to 258.6,441 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball4" to 216,376 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball5" to 200,300 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball6" to 216,224 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball7" to 258.6,158.6 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball8" to 324,116 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    //motion 2        
    move graphic "ball1" to 400,100 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball2" to 476,116 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball3" to 541,158.6 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball4" to 584,224 in varTotalSeconds seconds without waiting     
    wait varHoldSeconds second  
    move graphic "ball5" to 600,300 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball6" to 584,376 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball7" to 541,441 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
    move graphic "ball8" to 476,484 in varTotalSeconds seconds without waiting  
    wait varHoldSeconds second  
   end repeat  

Thursday, March 17, 2016

The Best and Worst of LiveCode Troubleshooting

I am very behind in writing about my various LiveCode projects, particularly my Q Sort project. So I'll use this post to write about a few experiences I have had lately. Yes, this blog post is all about the art and science of troubleshooting. I'll start with a shining example, and then close with a problem that I remain unable to resolve. However, this problem has nudged me into a new direction for my Q Sort tool that really was inevitable, namely moving from an FTP approach to using text files to store data to the use of a mySQL database.

Troubleshooting Example 1: The Case of the Missing Data


In almost all of my field tests using my Q Sort tool, I had been experiencing an unusual problem of missing data. The problem was very spotty. The data from most responses were fine, but there would always be a handful (i.e. 2 or 3 out of 20 people) with missing data. Most of the time, only one data point would be missing, but it was possible that 2, 3, or even 4 data points could be missing. At first, I thought it might be some artifact of the FTP process, such as some data getting "lost in transmission," but that seemed like a weak and unlikely theory.

Also, another person who completed a Q sort - a doctoral student in my department - was also adamant that a statement she rated one way was subsequently rated a different way when she reviewed her data. No one else had ever noted this before, so I knew it was possible she was just mistaken or confused. However, she sounded very sure of herself, so I was careful to note her observation because if she was right, then the accuracy of all the Q sort data would be in question. (I now think she was right. The fix I explain here solves that problem too.)

It wasn't clear to me how to go about troubleshooting this problem, given the rareness of its occurrence. I had never experienced the problem myself in all of my testing. My first idea was to set aside an hour in my design studio course at the University of Georgia and have the students do several Q sorts in a row with the hope that the problem would appear in someone's data. Then, I could compare the data uploaded to the web server with the data saved to their local computer. However, I solved the problem on my own in a relatively short amount of time.

My Solution: Make All Data Visible


To help figure this out, I made a copy of the Q Sort tool just for troubleshooting. I turned off all of the FTP and other data storing commands and made visible the key hidden fields that collected and managed the data while the Q sort was in progress. As I played with doing a bunch of Q sorts, I discovered the problem.

Basically, here is what was happening. Two statements in adjacent slots would be appropriately "locked" into their slots. Then, the user would move one of these statements into the other slot. The just emptied slot would correctly then register "empty." But, if I then moved the other "locked in" statement into the now vacated slot, both slots would register that statement. The other consequence to this would be that if all other slots were filled, the "Submit" button would be activated, thus allowing the user to then quit and upload their data. This problem wouldn't occur, or would resolve itself if it had, if the person moved one of these statements back to the main area of the screen. So, the problem only occurred under these fairly rare situations.

To fix this, I added some code to the "on mouseUp" script in the button "statement template" to check for duplicate statement numbers in the field "slot contents." Even this was a little tricky as I had to make sure that the correct slot showed where the statement now resided. To do this, I first added this code to look for EVERY occurrence of the button number and replaced it with "empty":

    //First check for duplicate statement numbers in field "slot contents" (the cause of the missing data problem) - February 21, 2016  
    //I adapted this code from the button "Check for Duplicates" from the Q sort analysis tool  
    put the number of lines in field "slot contents" into L  
    repeat with i = 1 to L  
      put item 1 of line i of field "slot contents" into varName  
      if SN = varName then  
       put "empty" into line i of field "slot contents"  
      end if  
    end repeat  
   
The key was to put this code BEFORE this existing line of code (near at the end of the mouseUp script) because this line then puts the button's location into the correct slot:

put SN into item 1 of line varSlotNumber of field "slot contents"

In summary, if a duplicate was found the appropriate one would remain but the other would be replaced with "empty."

Improving the Usability


But, I wasn't finished. As I played with the program I could sense a usability problem. As I moved statements previously locked into a slot to an adjacent slot, it was often not obvious which statement was no longer "locked" into a slot. I decided the best thing to do would be to "snap" the unrated statement out of the "slot zone" to the original starting x screen coordinate, but leaving it at the current y screen coordinate. To do this, I adapted the script that already existed in the "To far left" button and added it to the custom function "checkForEmptySlots" on the card "sort":

    //First check for duplicate statement numbers in field "slot contents" (the cause of the missing data problem) - February 21, 2016  
    //I adapted this code from the button "Check for Duplicates" from the Q sort analysis tool  
    put the number of lines in field "slot contents" into L  
    repeat with i = 1 to L  
      put item 1 of line i of field "slot contents" into varName  
      if SN = varName then  
       put "empty" into line i of field "slot contents"  
      end if  
    end repeat  


A key idea was to put this script near the end of the function and right before other script that checked to see if all statements were accounted for. If all statements were accounted for, only then would the "Submit" button be activated.

Note this important line (line 7):

 if not intersect (graphic "statement background", button locStatementName) then next repeat  

This line is important because I only wanted to "snap" out of the way those statements that were in the "slot zone."

The result is now a very clear user interface that shows which statements are "locked" into place and which are not.

Troubleshooting Example 2: The Case of the Deleted Data


OK, great. I solved a thorny problem all on my own. Just as I was finishing my victory lap, complete with champagne, another recurring problem surfaced. This problem remains unresolved and really has me stumped: Data that I know were correctly FTPed to my web server have subsequently vanished. I really have no explanation for this. It has happened occasionally and rarely. The first few times it happened, I blamed myself for just not remembering deleting the data. This was a reasonable explanation because in my early field trials, I would occasionally wipe the text file clean on my server. However, the last time it happened, I know I did no such thing.

To be honest, I know I haven't been using the preferred LiveCode libURL commands, such as libURLftpUploadFile, for the data transfer (here is a link to a good tutorial). Instead, I've simply been using the simple "put" command in tandem with the URL function:

 put field "ftp scores"&return after URL varUploadSite  

However, I don't see how this is at all related to the problem given that I know the data were in fact saved to the web server. So, I remain stymied. Perhaps someone reading this blog post with more experience than I knows what to look for. If so, I hope they will contact me.

But, as I mentioned at the start of this blog post, my inability to solve this problem has persuaded me to abandon the FTP method altogether and instead use a mySQL database for all data storage. I knew I would eventually make the jump to using a real database, but there was a certain charm and elegance to just using simple text files for all data storage. Interestingly, I reread one of my own blog posts from last year to relearn how to do this titled "Desperately Seeking Middleware." I hope to finish this transition to mySQL in the next week or so.

Final Thoughts


These two examples are good reminders of how coding can bring the "thrill of victory" and the "agony of defeat." Just when I thought I was rather clever in figuring out one problem, another jumps up and bites me. No worries, though, as this is all part of the learning experience. One day, I know I'll figure out that deleted data problem, or bump into someone who can help me.