[222003140010] |Web Experiment Tutorial: Chapter 1, Overview [222003140020] |Several years ago, I wrote a tutorial for my previous lab on how to create Web-based experiments in Flash. [222003140030] |Over the next number of months, I'll be posting that tutorial chapter by chapter. [222003140040] |1. What does this manual cover? [222003140050] |- Methodological considerations [222003140060] |- Creating experiments in Flash [222003140070] |- Implementing those experiments on the Internet [222003140080] |- Collecting and retrieving data [222003140090] |- Recruiting participants online [222003140100] |2. What does this manual not cover? [222003140110] |- Creating experiments in Java or other technologies [222003140120] |- Basic programming skills i. [222003140130] |(You should be familiar with variables, arrays, subroutines, functions, etc. [222003140140] |Familiarity with object-oriented programming is useful but hopefully not necessary.) [222003140150] |3. Who should use this manual? [222003140160] |- Researchers who want to create and use Web-based experiments. [222003140170] |- Those who are simply interested in the methodology should read “Methodolgical Considerations” and “Recruiting participants online” first/only. [222003150010] |Web Experiment Tutorial: Chapter 2, Methodological Considerations [222003150020] |Several years ago, I wrote a tutorial for my previous lab on how to create Web-based experiments in Flash. [222003150030] |Over the next number of months, I'll be posting that tutorial chapter by chapter. [222003150040] |1. Why do an experiment online? [222003150050] |Whenever designing an experiment, it is important to consider your methods. [222003150060] |Explicit measures or implicit? [222003150070] |Is self-report sufficient? [222003150080] |Etc. [222003150090] |Ideally, there is a reason for every aspect of your methods. [222003150100] |So why put an experiment on the Web? [222003150110] |This chapter discusses the pros and cons of Web-based research, as well as when to use it and when to skip it. [222003150120] |Note: I've added an additional section to the end of this chapter to discuss paid systems like Amazon Mechanical Turk. [222003150130] |2. Cost. [222003150140] |Experiments cost both time and money –yours as well as your participants’. [222003150150] |Here, Web-based experiments have an obvious edge. [222003150160] |Participants are not paid, and you don’t have to spend time scheduling or testing them (however, recruiting them may be extremely time-consuming, especially in the beginning). [222003150170] |3. Reliability of the subjects [222003150180] |A common complaint about Web-based experiments is that “who knows what your participants are actually doing?” [222003150190] |It is true that people lie on the Internet. [222003150200] |There is a great deal of unreliable information. [222003150210] |This worry probably stems from this phenomenon. [222003150220] |However, subjects who come to the lab also lie. [222003150230] |Some don’t pay attention. [222003150240] |Others don’t follow the directions. [222003150250] |Some just generally give bad data. [222003150260] |The question becomes whether this phenomenon is more likely on the Web or in the lab. [222003150270] |There are several reasons to favor the Web. [222003150280] |Lab-based subjects are generally coerced by either cash or course credit, while Web-based participants are typically volunteers (although some labs do use lotteries to induce participants). [222003150290] |If a lab-based subject gets bored, s/he is nonetheless stuck with finishing the experiment. [222003150300] |Although they have the right to quit, this is quite rare. [222003150310] |Web-based subjects can and do quit at any time, thus removing themselves and their boredom-influenced data from the analyses. [222003150320] |In addition, good experimental design contains built-in checks to ensure that the subjects are not just randomly pressing buttons. [222003150330] |That’s out of the scope of this manual. [222003150340] |Finally, you might be concerned that the same subject is participating multiple times. [222003150350] |If you have large numbers of subjects, this is probably just noise. [222003150360] |However, there are several ways to check. [222003150370] |You can record IP addresses. [222003150380] |If the participants have DHCP (dynamically-assigned IP addresses), this is imperfect, because the last several digits of the IP address can change every few minutes. [222003150390] |Also, different people may use the same computer. [222003150400] |Nonetheless, IP address inspection can give you an idea as to whether this is a pervasive problem. [222003150410] |If you have very large numbers of subjects, it’s probably not an issue. [222003150420] |You can also require subjects to get usernames and passwords, though this adds a great deal of complexity to your programming and will likely turn away many people. [222003150430] |Also, some people (like me) frequently forget their passwords and just create new accounts every time I go to a website. [222003150440] |Another option is to collect initials and birthdates. [222003150450] |Two people are unlikely to share the same initials and birthdays. [222003150460] |Here, though, there is a particularly high risk that subjects will lie. [222003150470] |You can decrease this by asking only for day of the month, for instance. [222003150480] |Another worry are bots. [222003150490] |Bots are programs that scour the Web. [222003150500] |Some are designed to fill out surveys. [222003150510] |If you are using HTML forms to put together a survey, this is a definite risk. [222003150520] |You should include some way of authenticating that the participant is in fact a human. [222003150530] |The most typical approach is generating an image of letters and numbers that the participant must type back in. [222003150540] |To sign up for a free email address, this is always required. [222003150550] |To my knowledge, bots do not interface well with the types of Flash applications described in this book. [222003150560] |I have not run across any evidence that bots are doing my experiments. [222003150570] |But the day may come, so this is something to consider. [222003150580] |The only real worry is that a single bot will give you large amounts of spurious data, masquerading as many different participants. [222003150590] |Many of the safeguards described above to protect against uncooperative subjects will also help you with this potential problem. [222003150600] |Several studies have actually compared Web-based and lab-based data, and Web-based data typically produces results of equivalent or even better quality. [222003150610] |4. Reliability of the data [222003150620] |Here, lab-based experiments have a clear edge. [222003150630] |Online, you cannot control the size of the stimulus display. [222003150640] |You cannot control the display timing. [222003150650] |You cannot control the distance the subject sits from the screen. [222003150660] |You cannot control the ambient sound or lighting. [222003150670] |If you need these things to be controlled, you should do the experiment in the lab. [222003150680] |Similarly, reaction times are not likely to be very precise. [222003150690] |If your effect is large enough, you can probably get good results. [222003150700] |But a 5 millisecond effect may be challenging. [222003150710] |That said, it may be worth trying anyway. [222003150720] |Unless you think that participants’ environments or computer displays will systematically bias their data, it’s just additional noise. [222003150730] |The question is whether your effect will be completely masked by this noise or not. [222003150740] |The one way in which the Web has an advantage here is that you may be able to avoid fatigue (by making your experiment very short) or order effects. [222003150750] |By “order effect,” I mean that processing of one stimulus may affect the processing a subsequent stimuli. [222003150760] |Online, you can give some subjects one stimulus and other subjects the other stimulus, and simply compensate by recruiting larger numbers of subjects. [222003150770] |Another example includes experiments that require surprise trials (e.g., inattentional blindness studies). [222003150780] |You can only surprise the same subject so many times. [222003150790] |5. Numbers of subjects [222003150800] |Here, Web-based experiments are the run-away winner. [222003150810] |If you wanted to test 25,000 people in the lab, that would be essentially impossible. [222003150820] |Some Web-based labs have successfully tested that number online. [222003150830] |6. Length of the experiment [222003150840] |If you have a long experiment, do it in the lab. [222003150850] |The good Samaritans online are simply not going to spend 2 hours on your experiment out of the goodness of their hearts. [222003150860] |Unless you make it really interesting to do! [222003150870] |If you can make your Web-experiment less than 2 minutes long, do it. [222003150880] |5 minutes is a good number to shoot for. [222003150890] |At 15 minutes, it becomes very difficult (though still possible) to recruit subjects. [222003150900] |The longer the experiment, the fewer participants you will get. [222003150910] |This does interact with how interesting the experiment is: TestMyBrain.org frequently has experiments that run 15 minutes or more, and they still get many, many participants. [222003150920] |That said, if you have a long experiment, consider why it is so long. [222003150930] |Probably, you could shorten it. [222003150940] |In the lab, you may be used to having the same subject respond to the same stimulus 50 times. [222003150950] |But what about having 50 subjects respond only once? [222003150960] |Suppose you have 200 stimuli that you need rated by subjects. [222003150970] |Consider giving each subject only 20 to rate, and get 10x as many subjects. [222003150980] |The only time you may run into difficulty is if you need to insert a long pause into the middle of the experiment. [222003150990] |For instance, if you are doing a long-term memory experiment and you need to retest them after a 1 hour delay. [222003151000] |This may be difficult. [222003151010] |I have run several experiments with short delays (2-10 minutes). [222003151020] |I fill the delay with some of the Web’s most popular videos in the hopes that this will keep the subjects around. [222003151030] |Even so, the experiment with the 10 minute delay attracts very few subjects. [222003151040] |So this is something to consider. [222003151050] |7. Individual differences [222003151060] |Generally, your pool of subjects online will be far more diverse than those you can bring into the lab. [222003151070] |This in and of itself may be a reason for favoring the method, but it also brings certain advantages. [222003151080] |Laughably large numbers of subjects allow you to test exploratory questions. [222003151090] |Are you curious how age affects performance on the task? [222003151100] |Ask subjects’ their ages. [222003151110] |It adds only a few seconds to the experiment, but may give you fascinating data. [222003151120] |I added this to a study of visual short-term memory and was able to generate a fascinating plot of VSTM capacity against age. [222003151130] |Similarly, Hauser and colleagues compared moral intuitions of people from different countries and religious backgrounds. [222003151140] |This may not have been the original purpose of the experiment, but it was by far the most interesting result, and all it required was adding a single question to the experiment. [222003151150] |You could also compare native and non-native English speakers, for instance, just to see if it matters. [222003151160] |Online, you may have an easier time recruiting difficult-to-find subjects. [222003151170] |One researcher I know wanted to survey parents of children with a very rare disorder. [222003151180] |There simply aren’t many in his community, but he was able to find many via the Internet. [222003151190] |Maybe you want to study people with minimal exposure to English. [222003151200] |You are unlikely to find them on your own campus, but there are literally millions online. [222003151210] |8. I have an experiment. [222003151220] |Which should I pick? [222003151230] |This is of course up to you. [222003151240] |Here are the guidelines I use: [222003151250] |Pick lab-based if: The experiment must be long The experiment requires careful controls of the stimuli and the environment [222003151260] |Pick Web-based: The experiment requires very large numbers of subjects You don’t have many stimuli and don’t want to repeat them The experiment is very short You want to avoid order effects You want to look at individual differences You want to study a rare population You want to save money [222003151270] |Note that for most experiments, you could go either way. [222003151280] |9. Amazon Mechanical Turk [222003151290] |Since I originally wrote this tutorial, a number of people have started using Amazon Mechanical Turk. [222003151300] |Turk was designed for all kinds of outsourcing. [222003151310] |You have a project? [222003151320] |Post it on the Turk site, say how much you are willing to pay, and someone will do it. [222003151330] |It didn't take long for researchers to realize this was a good way of getting data (I don't know who thought of this first, but I heard about it from the Gibson lab at MIT, who seem to be the pioneers in Cambridge, at least). [222003151340] |Turk has a few advantages over lab-based experiments: it's a lot cheaper (people typically pay at around $2/hour) and it's fast (you can run a whole experiment in an afternoon). [222003151350] |Comparing it with running your own website like I do is tricky. [222003151360] |First, since participants are paid, it obviously costs more than running a website. [222003151370] |So if you do experiments involving very, very large numbers of participants, it may still be too expensive. [222003151380] |On the flip side, recruitment is much easier. [222003151390] |I have spent hundreds of hours over the last few years recruiting people to my website. [222003151400] |Second, your subject pool is more restricted, as participants must have an Amazon Payments account. [222003151410] |There may be some restrictions on who can get an account, and in any case, people who might otherwise do your experiment may not feel like making an account. [222003151420] |One interesting feature of Turk is that you can refuse to pay people who give you bad data (for instance, get all the catch trials wrong). [222003151430] |Participants know this and thus may be motivated to give you better data. [222003151440] |Currently, I am using Turk for norming studies. [222003151450] |Norming studies typically require a small, set number of participants, making them ideal for Turk. [222003151460] |Also, they are boring, making it harder to recruit volunteers. [222003151470] |I do not expect to switch over to using Turk exclusively, as I think the method described in this tutorial still has some advantages. [222003151480] |Amazon has a pretty decent tutorial on their site for how to do surveys, so I won't cover that here. [222003151490] |More complex experiments involving animations, contingent responses, etc., should in theory be possible, but I don't know anybody doing such work at this time. [222003160010] |Web Experiment Tutorial: Chapter 3, Basic Flash Programming [222003160020] |Several years ago, I wrote a tutorial for my previous lab on how to create Web-based experiments in Flash. [222003160030] |Over the next number of months, I'll be posting that tutorial chapter by chapter. [222003160040] |This and the following two chapters will go over how to produce a basic change-detection experiment. [222003160050] |Necessary materials and the finished example are included. [222003160060] |1. How is a Flash program structured? [222003160070] |If you have ever done any programming, you will find the layout of a Flash program rather odd. [222003160080] |This is because it is designed for animations. [222003160090] |A Flash program is structured around frames. [222003160100] |Frames are what they sound like –a frame in a movie. [222003160110] |A frame may contain images. [222003160120] |It also has attached code. [222003160130] |That code is linked to that frame and that frame only, although subroutines written in one frame’s code can be called by another frame. [222003160140] |Moreover, a frame can contain movie clips. [222003160150] |Movie clips is a very confusing name for these structures. [222003160160] |What you need to know about them for the moment is that they can have their own timeline and their own attached code. [222003160170] |2. Exploring Flash [222003160180] |Note: This tutorial was written for Flash MX with Actionscript 2.0. [222003160190] |I believe everything will work as it should in newer versions of Flash, but if you have any problems, please leave a comment or email me. [222003160200] |Open a new Flash document. [222003160210] |The main window contains two parts. [222003160220] |At the top, there is a timeline. [222003160230] |This timeline shows all the frames in your program. [222003160240] |Currently, the first frame should be highlighted and have a circle in it. [222003160250] |The other frames should all be faded in appearance. [222003160260] |They are just placeholders and will not appear in a movie. [222003160270] |The circle in the first frame indicates that it is a keyframe, which will be discussed below. [222003160280] |At the bottom of the Timeline, you will see the letters “12.0 fps”. [222003160290] |This is the speed of the movie: 12 frames per second. [222003160300] |12 fps is standard. [222003160310] |You can go faster or slower as you wish. [222003160320] |However, this is a ballpark figure –actual speed depends on many factors. [222003160330] |Supposedly there are ways to improve the accuracy of the timing, but I have never tried or tested any of them. [222003160340] |It is also worth noting that there does seem to be a maximum speed. [222003160350] |As the fps increases, the actual speed when running does not necessarily increase. [222003160360] |Also, at high speeds, the program will run faster when run locally (i.e., on your desktop) than when run through the Internet. [222003160370] |The central, larger part, is the stage. [222003160380] |This shows you what is actually displayed in a particular frame (unless those images are dynamically created, which will be discussed below). [222003160390] |There are several popup windows you will want to have at your disposal. [222003160400] |Make sure they are checked off under the “Window” menu item. [222003160410] |These are: [222003160420] |Properties. [222003160430] |The property inspector allows you to modify anything that is selected on the stage or in the timeline. [222003160440] |Click on the stage itself, and you will see several options in the properties window. [222003160450] |The most important one is the stage size. [222003160460] |Default is usually 550 x 400. [222003160470] |In general, it is better to keep your stage small, since you do not know how large the screen of your participants will be. [222003160480] |Select Window->Development Panels->Actions to bring up the Actions window. [222003160490] |This window contains all the code that is linked to whatever you currently have selected, be in frame, movie clip or component. [222003160500] |Note that the search function only searches that code. [222003160510] |Currently, there is no way to search through all the code in a given program. [222003160520] |Select Window->Library to open the library. [222003160530] |The library contains any components used in your program. [222003160540] |This will be important later. [222003160550] |3. Displaying stimuli. [222003160560] |First, change the fps to 4. [222003160570] |This will make the math simpler. [222003160580] |Now, we will create a background layer. [222003160590] |Choose Insert->Timeline->Layer to add a new layer. [222003160600] |In the Timeline, select Layer 1. [222003160610] |Using the drawing tools, draw a rectangle of any size. [222003160620] |In the properties window, click the “fill” icon. [222003160630] |In the popup window, click on the color wheel. [222003160640] |In the new “colors” window, select the “sliders” button. [222003160650] |Below that, change “Gray Scale Slider” to “RGB Slider”. [222003160660] |This allows you to type in exact RGB values. [222003160670] |Type in 145 for Red, Green, and Blue. [222003160680] |Click “OK”. [222003160690] |Now, in the properties window, change the width and height of the rectangle so that it matches the size of the stage. [222003160700] |Make sure the X and Y coordinates are 0. [222003160710] |Now, you can change the foreground layer without affecting the background, and visa versa. [222003160720] |In this example, the background is a neutral gray, but it could be much more complicated and even dynamic. [222003160730] |To lock the background so you don’t accidentally edit it, do the following. [222003160740] |In the timeline, just after the words “Layer 1”, you should see a couple diamonds. [222003160750] |One is under the “Eye” column. [222003160760] |One is under the “lock” column. [222003160770] |Click the diamond under the “Lock” column. [222003160780] |This locks the layer. [222003160790] |(The “Eye” diamond toggles the visibility of the layer.) [222003160800] |Now we want to add some stimuli. [222003160810] |Make sure you have Frame1 and Layer 2 selected. [222003160820] |Go to File->Import->Import To Stage and import Stim1.pic. [222003160830] |If asked to import via QuickTime, click OK. [222003160840] |Click on the image. [222003160850] |Go to the properties inspector and change the X coordinate to 75 and the Y coordinate to 50. [222003160860] |This will center the 400 x 300 image on a 550 x 400 stage. [222003160870] |Now, click on the 2nd frame of Layer 2. [222003160880] |Go to Insert->Timeline->Blank Keyframe. [222003160890] |(Inserting a non-blank Keyframe would make a new keyframe that contains the same images as the current one.) [222003160900] |The second frame should now be a keyframe. [222003160910] |Now, click on the 3rd frame of Layer 2. [222003160920] |Go to Insert->Timeline->Frame. [222003160930] |Now, there should be a box around frames 2 and 3. [222003160940] |You’ve now made frame 3 active, but it is not a keyframe. [222003160950] |This means it cannot be modified independently of the keyframe in frame 2. [222003160960] |Now click Insert->Timeline->Blank Keyframe. [222003160970] |Notice that this converted your frame to a keyframe. [222003160980] |It did not actually “insert” anything. [222003160990] |Notice also that our background does not appear when we select frames 2 or 3. [222003161000] |This is because Layer 1 only has a single frame. [222003161010] |You will need to expand Layer 1. [222003161020] |Click on frame 3 of layer one and click on Insert->Timeline->Frame. [222003161030] |Now the background should appear on all 3 frames. [222003161040] |Now, import Stim2 to the 3rd frame of Layer 2. [222003161050] |Center it as before. [222003161060] |Now, test your “experiment” by clicking Control->Test Movie. [222003161070] |The movie, you will notice, loops. [222003161080] |As soon as it gets to the end, it goes back to the beginning. [222003161090] |This won’t happen when it is run from a website, but it is still annoying. [222003161100] |Let’s add some code to prevent this. [222003161110] |Close the test window and click on the 3rd frame of Layer 2. [222003161120] |Now go to the “Actions” window and type: [222003161130] |stop(); [222003161140] |This ActionScript pauses the timeline in the current frame. [222003161150] |However, code that appears after the “stop” command will still be executed. [222003161160] |Now test the experiment. [222003161170] |You probably will have trouble seeing the first stimulus. [222003161180] |This is because Flash starts playing even before the program is fully loaded. [222003161190] |In the future, we will add a “loader” to fix this problem. [222003161200] |For now, however, just add several blank frames to the beginning of the experiment. [222003161210] |Test the experiment. [222003161220] |It is now a basic change-detection experiment. [222003161230] |It has several problems, however, the first of which is that there is no way for the participant to respond. [222003161240] |4. Getting responses. [222003161250] |There are two ways to input responses: with the mouse and with the keyboard. [222003161260] |Because the experiment is on the Web, the more natural method seems to be using the mouse. [222003161270] |However, to get accurate reaction times, keyboard entry is probably preferred. [222003161280] |That will be discussed below, under “Getting Reaction Time”. [222003161290] |Select the final frame of Layer 2. [222003161300] |In the same floating window as the one that shows the library, expand the “components” window. [222003161310] |Drag the “button” component onto the final frame of Layer 2. [222003161320] |Put it somewhere that it will not interfere with the image itself. [222003161330] |In the property inspector, change the label to “Same”. [222003161340] |The “button” component should now be in the program library. [222003161350] |Drag a new instance of the button component onto the stage and change the label to “Different.” [222003161360] |Select the “same” button. [222003161370] |In the Actions window, add the following ActionScript: [222003161380] |on (release){ _root.correct = 0; _root.gotoAndPlay('feedback'); } [222003161390] |This subroutine will execute when the user clicks on the button and then releases the mouse button. [222003161400] |Then, it sets a variable called “correct” to 0, since the stimuli in fact are not the same. [222003161410] |This variable is attached to the main program, which is why it is prefixed by “_root.”. [222003161420] |Similarly, the command “gotoAndPlay(‘feedback’)” is attached to the main program, since the frame “feedback” is part of the main program. “gotoAndPlay” does what it sounds like: it tells Flash to go to the frame called “feedback” and start playing from that point. [222003161430] |The “AndPlay” part is important, because currently we’ve told Flash to pause playing. [222003161440] |To the “different” button, add: [222003161450] |on (release){ _root.correct = 1; _root.gotoAndPlay('feedback'); } [222003161460] |Of course, there isn’t any frame called “feedback.” [222003161470] |Add a blank keyframe to the end of the experiment. [222003161480] |In the property inspector, name it “feedback”. [222003161490] |In the center of that frame, draw a text box. [222003161500] |In the property inspector, make sure it is dynamic text, not static text. [222003161510] |Under “var”, type “feedback_text”. [222003161520] |In the Actions window for the “feedback” frame, add the following code: [222003161530] |stop(); if (correct==1){ feedback_text='Correct'; }else{ feedback_text='Incorrect'; } [222003161540] |Notice that we don’t need to use _root. [222003161550] |This code is already attached to the “root”. [222003161560] |Also notice the use of the double equals sign. [222003161570] |If you accidentally type: [222003161580] |If (correct=1){ [222003161590] |The variable “correct” will actually be set to 1. [222003161600] |Play this experiment. [222003161610] |If you respond “Same,” you should be told that this response was incorrect. [222003161620] |If you respond “Different,” you should be told that this response is correct. [222003161630] |You may want to compare your work to the demo. [222003161640] |Note: Here and elsewhere, if you'd like the original .fla file to look at, please email me at gameswithwords@gmail.com [222003161650] |Our experiment has only one trial. [222003161660] |You could add trials manually by adding new frames. [222003161670] |This isn’t very efficient, and it also doesn’t allow for any randomization. [222003161680] |In the next part, we’ll add these aspects. [222003161690] |5. Creating a dynamic experiment. [222003161700] |To dynamically choose which stimuli appear, we will need to convert them to symbols. [222003161710] |Go to the frame with Stim1. [222003161720] |Right-click on the copy on the stage and select “Convert to Symbol”. [222003161730] |In the dialogue, name the symbol “Stim1”. [222003161740] |Make it a Movie Clip. [222003161750] |Under “Linkage”, first select “Export for ActionScript”, then change the Identifier to “Stim1”. [222003161760] |This is the name you will use to refer to this Movie Clip in the code. [222003161770] |Now double-click on Stim1. [222003161780] |The Timeline will now show Stim1’s timeline (remember that movie clips have their own timeline). [222003161790] |All our movie clips will consist of a single frame, but remember that you have the option to make a movie clip more dynamic. [222003161800] |In the property inspector, change the X coordinate of Stim1 to “–200” and the Y coordinate to “-150”. [222003161810] |This centers the 400 x 300 image (in the future, you can see what happens if you skip this step). [222003161820] |Now go to Edit->Edit Document. [222003161830] |Repeat this process for Stim2. [222003161840] |Drag Stim3 onto the stage somewhere and repeat the process. [222003161850] |Now, delete the images of Stim1, Stim2 and Stim3 from whatever frames they appear in. [222003161860] |Name the frame where Stim1 was originally presented “stim”. [222003161870] |Name the frame where Stim2 was originally presented “probe”. [222003161880] |In the frame “stim”, the ActionScript should read as follows: [222003161890] |stimulus=random(3)+1; _root.attachMovie("Stim"+stimulus,"Stimulus",1); setProperty(eval("Stimulus"), _x, 275); setProperty(eval("Stimulus"), _y, 200); [222003161900] |First, a random number from 0 to 2 is chosen, to which we add 1. _root.attachMovie attaches a movie clip to the frame. [222003161910] |The first argument (“Stim”+stimulus) names the movie clip. [222003161920] |Notice that possible values are “Stim1”, “Stim2” and “Stim3” –our three stimuli! [222003161930] |The second argument is a name for this instance. [222003161940] |The final argument determines which movie clip level the movie clip is assigned to. [222003161950] |If there is already a movie clip on level 1, this will overwrite it. [222003161960] |Bugs in Flash very often result from overwriting a movie clip in this fashion. [222003161970] |Next, we position the movie clip in the center of the screen (275, 200) by setting the X and Y parameters. [222003161980] |Note that if the movie clip image itself is not centered (as we did above), the outcome will be different. [222003161990] |For instance, if the origin of the movie clip is it’s upper left corner, then you would need to place this instance at (75,50) in order to center the instance on the stage. [222003162000] |In the next frame, add the following code: [222003162010] |removeMovieClip("Stimulus"); [222003162020] |This removes the movie clip we just added. [222003162030] |Note that it removes it using the name we assigned it in the previous frame. [222003162040] |In the “Probe” frame, change the code to the following: [222003162050] |stop(); probe = random(3)+1; if (stimulus==probe){ match=1; }else{ match=0; } _root.attachMovie("Stim"+probe,"Probe",1); setProperty(eval("Probe"), _x, 275); setProperty(eval("Probe"), _y, 200); [222003162060] |Now, the probe is chosen randomly from the 3 stimuli. [222003162070] |When the stimulus and the probe match, this is noted. [222003162080] |Notice that the stimulus and probe will match 1/3 of the time. [222003162090] |2/3 of the time, they do not. [222003162100] |This is done here to simplify the programming, any ratio can be implemented. [222003162110] |We also have to change the code for our response buttons. [222003162120] |It is no longer the case that “different” is always correct and “same” is always wrong. [222003162130] |Modify the code for the “Same” button as follows: [222003162140] |on (release){ if (_root.match==1){ _root.correct = 1; }else{ _root.correct = 0; } _root.gotoAndPlay('feedback'); } [222003162150] |Modify the code for the “Different” button similarly. [222003162160] |Finally, add this code to the top of the Feedback frame: [222003162170] |removeMovieClip("Probe"); [222003162180] |Test the experiment. [222003162190] |There is still only one trial, but the stimuli should now be chosen randomly. [222003162200] |Writing a loop so that there are multiple trials is fairly straight-forward. [222003162210] |First, add a blank keyframe to the beginning on Layer 2. [222003162220] |Add the following code: [222003162230] |total_trials = 5; current_trial = 1; [222003162240] |This initializes two variables. total_trials sets the total number of trials. current_trial tracks how many trials have been completed. [222003162250] |Now, name the second keyframe of Layer 2 “Next_Trial”. [222003162260] |Remove the stop() command from “feedback” and add 2 frames. [222003162270] |Convert the final one to a keyframe (don’t change it to a blank keyframe –we want the feedback_text to continue to display on this final frame). [222003162280] |Add this code to that new keyframe: [222003162290] |if (current_trial==total_trials){ gotoAndPlay('finish'); }else{ current_trial += 1; trace(current_trial); gotoAndPlay('Next_Trial'); } [222003162300] |This code does pretty much what it says. [222003162310] |Now we need to add a final frame to Layer 2 and call it “finish”. [222003162320] |Draw a textbox on the stage and write, “Thank you for participating.” [222003162330] |Your program should now look like this. [222003162340] |We are still not recording any data. [222003162350] |That will be discussed in a future chapter. [222003170010] |Class Notes: A Developmental Paradox [222003170020] |One thing that keeps coming up in artificial grammar studies (in which people are taught bits of made-up languages) is that adults are much better at learning them than kids. [222003170030] |Yet we know that if you wait 20 years, people who started learning a real language as a kid do much better than those who started as adults. [222003170040] |This might mean the artificial grammar studies aren't ecologically valid, but I think it's also the case that in real-life second-language acquisition, adults start out ahead of kids. [222003170050] |Whatever makes kids better language learners seems to be something that happens after the first few weeks/months of learning. [222003180010] |Adoption and Language Development [222003180020] |I just heard that the Boston Globe recently ran an article on my advisor's work. [222003180030] |If you haven't already read it, here's my discussion of the same work in Scientific American Mind. [222003190010] |Class Notes: This field confuses the hell out of me. I want to start from scratch. [222003190020] |I have now read 44 papers in the course of this semester's Language Acquisition seminar. [222003190030] |The only firm conclusion I have come to is that language is so complicated that nobody could ever possibly learn one. [222003190040] |--- (The title of this post comes from the caption of a doodle of a mid-century Harvard psychologist, now enshrined in a display case on the 9th floor of William James Hall. [222003190050] |Based on the time period, I think the doodler was either George Miller or Roger Brown, but I can't recall for sure.) [222003200010] |Class Notes: Why linguistic judgments are fuzzy [222003200020] |Buried towards the end of a 1991 paper by Fisher, Gleitman &Gleitman is a strikingly useful -- and I think, correct -- observation on the limits of grammaticality studies. [222003200030] |In the context of a broader argument that people learn the meanings of verbs partly from the syntactic frames the verbs appear in ("syntactic bootstrapping"), they argue that exactly this "feature" of verb learning makes it sometimes hard to decide if a particular verb is grammatical in a certain context. [222003200040] |Consider the present progressive in English. [222003200050] |Classically, the present progressive can only be used for ongoing activities (1-3), not completed activities (4) or states that aren't typically activities (5): [222003200060] |(1) Sarah is eating the carrot. [222003200070] |(2) Sarah is running to the store. [222003200080] |(3) Sarah is looking at the moon. [222003200090] |(4) *Sarah is breaking the vase. [222003200100] |(5) *Sarah is seeing the moon. [222003200110] |However, a lot of people's judgments about (4) and (5) are iffy. [222003200120] |They don't sound nearly so ungrammatical as (6). [222003200130] |(6) The boys carrot eats. [222003200140] |The idea is that people are influenced by the syntactic frame the verb appears in and reinterpret the verb. [222003200150] |That is, if you think of "breaking" as something that happens in an instant, it isn't an activity and you can't say (4). [222003200160] |However, if you imagine a long, drawn-out process in which Sarah methodically destroys a vase, "break" is now an activity, and (4) is fine. [222003200170] |Similarly, "see" usually describes an end-state of some process, but you can re-imagine it as an activity (maybe Sarah observes the moon regularly as part of her profession). [222003200180] |I run into this constantly in my study of verbs of psychological state. [222003200190] |Influenced by a paper by Liina Pylkkanen's 1991 "On stativity and causation," I've been pursuing the argument that certain psych verbs can't appear in certain syntactic frames. [222003200200] |For instance, "love" and "hate" can't appear in the present progressive. [222003200210] |In a sense, this seems right; (7) and (8) are somewhat more odd than (9) and (10). [222003200220] |(7) *John is loving the Red Sox. [222003200230] |(8) *John is hating the Yankees. [222003200240] |(9) John is frightening the squirrels. [222003200250] |(10) John is angering the chickens. [222003200260] |Unfortunately, one can usually find a way of reinterpreting "love" and "hate" such that they are activities and then (7) and (8) don't sound so bad. [222003200270] |This has made testing the hypothesis difficult. [222003200280] |In addition, English appears to be changing to allow more psych verbs in the present progressive (darn you, McDonalds). [222003200290] |------- Fisher, C., Gleitman, L. R., &Gleitman, H. (1991). [222003200300] |On the semantic content of subcategorization frames. [222003200310] |Cognitive Psychology, 23, 331-392. [222003210010] |Games with Words in Taiwan [222003210020] |I've been in Taiwan for two weeks, and further posts of the Tutorial will probably wait until I get back next week. [222003210030] |I had an excellent two-day visit to Prof. Su Yi-ching's lab at Tsing Hua University (Qinghua for you pinyin-readers), where I was able to collect an absurd amount of data due to the generosity of Prof. Su and her students (over 110 participants in two written studies, plus three in an eye-tracking study). [222003210040] |I also had a great time at Prof. Lee Chia-Ying's very lively lab at Academia Sinica, where I got to observe a kid ERP experiment (something I've never actually seen, though I'm in the process of planning one of my own) and also test several more participants in the eye-tracking study. [222003210050] |I also visited Prof. Chueng Hintat at National Taiwan University. [222003210060] |I was mildly surprised to discover I actually can discuss my research in Mandarin when necessary, though with most people it was possible to use English (thankfully). [222003210070] |I wasn't at all sure how this trip was going to go when I planned it, as at the time I didn't actually know any psycholinguists in Taiwan. [222003210080] |It turns out that there's actually a pretty substantial group of developmental psycholinguists working on interesting problems. [222003210090] |Su and Cheung are both in the process of releasing much-needed new child corpora, with Su focusing on (if I remember correctly) optional infinitives (to the extent such can be recognized in a language with no inflectional morphology) and lexical tone, and Cheung focusing on argument structure alternations. [222003210100] |Lee's lab is producing some really well-considered studies of character-reading (for instance, looking at how phonetic and semantic radicals are processed). [222003210110] |I also heard of several other faculty doing exciting work but whom I didn't have time to visit. [222003210120] |And, of course, I got a lot of data, which is good since Harvard partly funded this trip on the expectation I would run some experiments. [222003210130] |The experiments I was running are all similar to the Pronoun Sleuth project -- that is, looking at factors that affect what people think a pronoun means, and trying to replicate some of my findings in English. [222003220010] |Questions about the tutorial? [222003220020] |Hi folks -- anyone who is trying to use the Web Experiment Tutorial, please do write in (gameswithwords at gmail) or comment with questions. [222003220030] |This tutorial was written for Flash MX, and though I actually still run programs that were based in MX and they work fine, there may be adjustments necessary for people using the latest versions of Flash. [222003220040] |I'd be interested in hearing if you run into any such difficulties. [222003230010] |Web Experiment Tutorial: Chapter 4, Flash: Finishing Touches [222003230020] |Several years ago, I wrote a tutorial for my previous lab on how to create Web-based experiments in Flash. [222003230030] |Over the next number of months, I'll be posting that tutorial chapter by chapter. [222003230040] |1. Getting Reaction Time. [222003230050] |For some experiments, you may wish to record reaction time. [222003230060] |Reaction time will not be very accurate in a Web-based experiment. [222003230070] |A priming experiment, for instance, would probably not be ideal. [222003230080] |However, for larger reaction time effects, this methodology should be sufficient. [222003230090] |You could get a reaction time mouse click in the following manner: [222003230100] |In the “probe” frame, add the following code right after the code that displays the probe: [222003230110] |start_time =new Date().getTime(); [222003230120] |Add this code to the “same” and “different” buttons, just before the gotoAndPlay statement: [222003230130] |_root.RT = new Date().getTime() - _root.start_time; [222003230140] |The variable “RT” will now contains the number of milliseconds that passed between the probe display and the mouse release. [222003230150] |We could change it to the onset of the mouse click by changing the subroutines in the “same” and “different” buttons to on (click). [222003230160] |However, responding with the mouse is slow, and you would probably prefer using key presses. [222003230170] |This is more complicated. [222003230180] |Do not try to understand the following method. [222003230190] |It frankly makes no sense. [222003230200] |Just try to learn how to use it. [222003230210] |First, make an empty text box containing a single space. [222003230220] |Convert it to a movie clip named “keyTrap”. [222003230230] |Select “keyTrap” and attach the following code: [222003230240] |onClipEvent(keyDown) { ResponseKey=Key.getCode(); responseTime=new Date().getTime(); _root.RT=responseTime - _root.start_time; switch (ResponseKey) { case 83: //S if (_root.match==1){ _root.correct = 1; }else{ _root.correct = 0; } break; case 68: //D if (_root.match==1){ _root.correct = 0; }else{ _root.correct = 1; } break; } _root.gotoAndPlay("feedback"); } [222003230250] |The onClipEvent(keyDown) subroutine executes when any key is pressed. [222003230260] |Key.getCode retrieves the ASCII key code for the key that was pressed. [222003230270] |The table for a standard keyboard is reproduced below. [222003230280] |The only other novel piece of code here is the switch statement. [222003230290] |Switch statements in Flash have the following form: [222003230300] |Switch (VARIABLE) { case VALUE-OF-VARIABLE: CODE break; Case ANOTHER-VALUE CODE break; } [222003230310] |Without the “break” command, Flash will execute the next line. [222003230320] |Consider the following code: [222003230330] |Switch (number){ case 1: trace(‘1’); case 2: trace(‘2’); case 3 trace(‘3’); } [222003230340] |This code will count to 3 starting with the value of “number”. [222003230350] |If “number” = 1, then it will count: 1, 2, 3. [222003230360] |If number=3, it will only count: 3. [222003230370] |(the “trace” command outputs to the output window. [222003230380] |This can be seen when running a .fla program within Flash. [222003230390] |The code does nothing when running off a website.) [222003230400] |You should also delete the “same” and “different” buttons. [222003230410] |Now, you can respond by pressing “s” for “same” and “d” for “different”. [222003230420] |Your program should now look like this. [222003230430] |ASCII codes for a standard keyboard: A 65 [222003230440] |B 66 [222003230450] |C 67 [222003230460] |D 68 [222003230470] |E 69 [222003230480] |F 70 [222003230490] |G 71 [222003230500] |H 72 [222003230510] |I 73 [222003230520] |J 74 [222003230530] |K 75 [222003230540] |L 76 [222003230550] |M 77 [222003230560] |N 78 [222003230570] |O 79 [222003230580] |P 80 [222003230590] |Q 81 [222003230600] |R 82 [222003230610] |S 83 [222003230620] |T 84 [222003230630] |U 85 [222003230640] |V 86 [222003230650] |W 87 [222003230660] |X 88 [222003230670] |Y 89 [222003230680] |Z 90 [222003230690] |0 48 [222003230700] |1 49 [222003230710] |2 50 [222003230720] |3 51 [222003230730] |4 52 [222003230740] |5 53 [222003230750] |6 54 [222003230760] |7 55 [222003230770] |8 56 [222003230780] |9 57 [222003230790] |2. The Loader Bar [222003230800] |Ideally, you would like your program to load completely before it starts executing. [222003230810] |If it is a large program, this may mean that participants have to wait. [222003230820] |It’s a good idea to let them know how long they will be waiting. [222003230830] |This is where a loader bar comes in. [222003230840] |I actually don’t understand how loader bars work, so I suggest simply copying the first frame of Part4.fla, including all attached code. [222003230850] |This should work. [222003230860] |Note that when it finishes loading, it goes to and plays a frame called “Initialize.” [222003230870] |You will want to adjust this accordingly. [222003230880] |There are many resources online that discuss loader bars. [222003230890] |However, most of them involve loading one Flash file inside of another one. [222003230900] |3. Arrays [222003230910] |As in other programming languages, you will frequently want to make use of arrays. [222003230920] |One purpose for arrays is determining the order of all the stimuli before beginning the experiment. [222003230930] |Now that you’ve added a loader bar, your second frame (the one called “Initialize” in Part4.fla) should contain the code [222003230940] |total_trials = 5; current_trial = 1; [222003230950] |Change it to the following code: [222003230960] |total_trials = 5; current_trial = 0; var Stimuli = new Array(); for (i=0; i 4. Surveys/Demographics [222003231440] |You may want to ask your subjects a few questions. [222003231450] |This could in theory be done by using buttons as in the examples above, but it’s less than ideal. [222003231460] |There are several more ways of collecting information from participants. [222003231470] |Three include radio buttons, combo boxes and input boxes. [222003231480] |Radio buttons are a group of linked buttons, only one of which can be selected at any one time. [222003231490] |Look at the “Demographics” frame of Part4.fla. [222003231500] |The first and third questions are both examples of radio buttons. [222003231510] |To set up rradio buttons, first drag a radio button from the Flash components window (or from your file’s library, if it already contains radio buttons). [222003231520] |Make as many copies as you need. [222003231530] |Select one of the radio buttons. [222003231540] |In the properties inspector, choose “parameters”. [222003231550] |There are several you will want to change. [222003231560] |“Data” contains the value of that button when selected. [222003231570] |In Part4, the “Female” button’s data is “female”, while the “Male” button’s data is “male”. [222003231580] |This will be more clear shortly. “groupName” is the name of the group. [222003231590] |Radio buttons that share the same groupName are automatically part of the same group. [222003231600] |One one can be selected at a time. [222003231610] |“Label” is the text that is displayed to the subject. [222003231620] |Try changing this and its function will be clear. [222003231630] |A combo box is slightly more complicated to set up. [222003231640] |Again, drag a combo box onto your stage. [222003231650] |In the properties inspector, change it’s name to age_box. [222003231660] |Now, in the code attached to this frame, add the following: [222003231670] |ageData = new Array(101); ageData[0]="Select"; for (i=1; i<101; i++) { ageData[i]=i; } age_box.setDataProvider(ageData); [222003231680] |This creates an array with the values [‘Select’ 1 2 3 4 …99 100]. [222003231690] |This array is then assigned as the values of the combo box. [222003231700] |If you test this frame, you will see that the default for the combo box is the first value (“Select”), and by scrolling you can choose any number from 1 to 100. [222003231710] |The third question is again made of two radio buttons, which have the values of “yes” and “no”. [222003231720] |There is one interesting technique used here. [222003231730] |The question “Do you have normal or corrected to normal vision?” is actually complicated, and not everybody understands it. [222003231740] |However, including the entire explanation involves adding a lot of text, decreasing the chances that the subjects will actually read it. [222003231750] |So I added an invisible button underneath the text “(Click for explanation)”. [222003231760] |The text is a dynamic text box called “explain”. [222003231770] |The button contains the following code: [222003231780] |on (release){ _root.explain = "If your vision is normal when wearing glasses or contacts, answer 'yes'."; } [222003231790] |Thus, if the participant clicks in the vicinity of the text box (to be accurate, if they click the invisible button), the text box’s text changes to a brief explanation. [222003231800] |Finally, we have an example of an input box. [222003231810] |You create an input box the same as a static or dynamic text box, but in the properties inspector, you choose “input text” instead of “static text” or “dynamic text”. [222003231820] |You should type “Initials” into the var box in the property inspector in order to name the data contained in this box, just as you would for a dynamic text box. [222003231830] |You can also type in a default value. [222003231840] |Since I want 3 initials, I typed in “XXX”. [222003231850] |Finally, you need a way for subjects to submit their responses, and you need a way of recording that information. [222003231860] |I have included a button called “continue1_btn”, labeled “Continue”. [222003231870] |Now, let’s look at the full code for this frame: [222003231880] |stop(); [222003231890] |ageData = new Array(101); ageData[0]="Select"; for (i=1; i<101; i++) { ageData[i]=i; } age_box.setDataProvider(ageData); [222003231900] |demoBtn = new Object(); [222003231910] |demoBtn.click = function(evt) { age = age_box.getSelectedItem(); sex = sex_group.getValue(); normal_vision = vision_group.getValue(); initials = Initials; good_form = 1; if (sex == undefined) { good_form = 0; } if (age == "Select") { good_form = 0; } if (normal_vision == undefined) { good_form = 0; } if (initials == "XXX"){ good_form = 0; } if (good_form == 1) { gotoAndPlay("Instructions"); }else{ warning="Please finish all questions before continuing."; } } [222003231920] |continue1_btn.addEventListener("click", demoBtn); [222003231930] |The first part we have already gone over. [222003231940] |Then we define a new object called “demoBtn”. [222003231950] |Then we write an event handler to handle the event that the demoBtn is clicked. [222003231960] |It first retrieves the data from the page. “age” is set to the value of the age_box. [222003231970] |The value is literally whatever the subject selected. [222003231980] |If they selected “74”, then the value is “74”. [222003231990] |Then, “sex” is set to the value of the sex_group. [222003232000] |Recall that using the property inspector, we set the “data” assigned to one radio button to “female” and the other to “male”. [222003232010] |Thus, if “Female” is selected, the value of “sex” will be “female”. “normal_vision” is set by a similar process. [222003232020] |Finally, “initials” is set to the value of whatever is typed into the input text box named “Initials”. [222003232030] |It’s important to make sure that the participants filled everything out. [222003232040] |We make a dummy variable called “good_form” and set it to 1. [222003232050] |Then we check each variable in turn. [222003232060] |If it is undefined (in the case of radio buttons) or still set to its default values (in the case of the input text box or the combo box), we set “good_form” to 0. [222003232070] |Finally, if “good_form” = =1, we go on to the next frame. [222003232080] |If it does not, we don’t. [222003232090] |However, if nothing happens when the subject clicks “continue”, they may not realize it’s because they still have stuff to fill out. [222003232100] |They may think the program is broken. [222003232110] |So in the case that good_form == 0, we set a dynamic text box to “Please finish all questions before continuing.” [222003232120] |That dynamic text box is at the bottom of the screen and is called “warning”. [222003232130] |Notice that it must be set as “multiline” in the property inspector; otherwise, not all the text will be visible. [222003232140] |---- The working version of Part4 in .swf form can be found here. [222003240010] |Empirical English [222003240020] |I'd like to point readers to a brief article in the New York Times today discussing new applications of psychological research methods to the study of literature. [222003240030] |While it sounds like some of it is based on using neuroscientific methods to answer what are actually behavioral questions, the application of empirical methods is always a good thing. [222003240040] |Any statement that makes an empirical claim about the world should be testable in some fashion, and the fact that more and more fields are actually testing the claims they make is progress. [222003250010] |The Video Test: Test Your Visual Memory [222003250020] |There's a new experiment at GamesWithWords.org. [222003250030] |This one focuses on the relationship between short-term and long-term visual memory. [222003250040] |You will watch a video followed by a memory test for the video. [222003250050] |We'll compare those results to those of a short-term memory test. [222003250060] |This is one of my personal favorite experiments, mainly because the video is a clip from one of my all-time favorite short films (I was very lucky to get permission from the creators to use it). [222003250070] |It's also one of my longest-running projects. [222003250080] |Some of you may remember this experiment, as I've run it before. [222003250090] |In fact, there have been something like 12 versions of this experiment run. [222003250100] |The results have been interesting, if confusing, but with each experiment our methods get more refined. [222003250110] |I think this experiment is the best of the bunch. [222003250120] |It will also be the last (it's time to move on to other projects), which means I'll be able to post results for the entire project sometime this summer. [222003250130] |(Some people may wonder why GamesWithWords.org is running a visual memory experiment. [222003250140] |Much of my research focuses on the relationship between language and other components of the mind. [222003250150] |Occasionally this line of work necessitates and excursion beyond language to those other components of the mind.) [222003260010] |Web Experiment Tutorial: Chapter 5, HTML for Flash Experiments [222003260020] |Several years ago, I wrote a tutorial for my previous lab on how to create Web-based experiments in Flash. [222003260030] |Over the next number of months, I'll be posting that tutorial chapter by chapter. [222003260040] |Now you have an experiment, but you can’t retrieve the data from it. [222003260050] |This limits the usefulness of the experiment. [222003260060] |In this chapter, we will finish implementing the experiment. [222003260070] |This includes both recording the data and also presenting the experiment online. [222003260080] |To do this, you will need to learn a small amount of HTML, MySQL and PHP. [222003260090] |1. What is HTML? [222003260100] |HTML is the bread and butter language of the Web. [222003260110] |It is not a programming language in the same sense that C++ or BASIC are. [222003260120] |It’s better described as a “mark-up” language. [222003260130] |That is, an HTML file is essentially a text document with codes interspersed, telling the web browser how to display that text. [222003260140] |An HTML file can have more than just HTML in it. [222003260150] |Frequently, it also contains JavaScript, which are quite different from HTML. [222003260160] |We will use both. [222003260170] |An indepth discussion of HTML and JavaScript is outside the scope of this manual. [222003260180] |Our purpose here is to learn just enough to allow you to display your experiment to participants. [222003260190] |2. Create an experiment homepage. [222003260200] |I use Dreamweaver to create web pages. [222003260210] |Dreamweaver allows a great deal of flexibility in formatting. [222003260220] |Having a pretty webpage is not strictly necessary, but the better your webpage looks, the more participants will take it seriously. [222003260230] |Think about whether you would rather give personal information to a website that looks like it was created by an orangutan or one that looks like it was created by a highly sophisticated team of programmers. [222003260240] |Download and expand VSTM.zip. [222003260250] |Open index.html. [222003260260] |Index.html is the experiment’s homepage. [222003260270] |It has some nice features you could use, such as a scroll bar for the center frame. [222003260280] |You should edit this page as appropriate. [222003260290] |If you have a standard formatting for your website, you can adjust to fit that. [222003260300] |One thing to notice is that the name of the laboratory is prominently displayed. [222003260310] |This is because people may surf directly to this page. [222003260320] |Ideally, you would also have links to the rest of your lab website (that’s what I use the top bar of this page for). [222003260330] |Also, notice that there is very little text. [222003260340] |It's often a good idea to have as little text as possible, but at the same time, be as informative as possible. [222003260350] |Notice also that the link to the experiment (VSTM) is highlighted so that participants don’t have to hunt around for it. [222003260360] |3. The consent form. [222003260370] |There is a link in the center of the page. [222003260380] |The text is “Try the VSTM experiment by clicking here.” [222003260390] |This link opens “consent.html”. [222003260400] |Consent.html is a fairly simple page and as actually created in a text editor. [222003260410] |The participant sees a consent form. [222003260420] |This particular consent form was required by the Harvard IRB. [222003260430] |If you want your experiment to pop up in a new window centered in computer screen, you can do this with some JavaScript, which you can find by looking through consent.html: [222003260440] |This sets up a subroutine called “NewWindow” that does two things. [222003260450] |First, it will open test_in_progress.html. [222003260460] |It will also open another window and center it in the middle of the subject’s screen. [222003260470] |This other window will contain the experiment itself (to be discussed in another chapter). [222003260480] |Generally in vision experiments, you would like the experimental window to be centered. [222003260490] |This subroutine is called by the link itself. [222003260500] |Look towards the bottom of the file: [222003260510] |This code both presents the link to the participant and also causes the new window to appear in the middle of the screen when "Yes, I Agree" is clicked. [222003260520] |Notice that the size of the window is set to 650x500. [222003260530] |You'll want that to match both the size of the Flash file you've created (slightly larger is OK) and also the dimensions specified in the .php file which will be discussed in the next chapter. [222003260540] |3. The other HTML files. [222003260550] |There are two other HTML files included: test_in_progress.html and done.html. [222003260560] |These two are themselves called by PHP files. test_in_progress.html is called by test_popup.php (linked to by Consent.html). [222003260570] |It displays below the experimental window itself while the experiment is running. [222003260580] |It contains some text telling participants what to do if the experimental window doesn’t show up or if they should leave the experiment early. [222003260590] |Done.html is called by the experiment when the subject exits the experiment. [222003260600] |Both are fairly self-explanatory. [222003270010] |Web Experiment Tutorial: Chapter 6, PHP [222003270020] |Several years ago, I wrote a tutorial for my previous lab on how to create Web-based experiments in Flash. [222003270030] |Over the next number of months, I'll be posting that tutorial chapter by chapter. [222003270040] |We've now got an experiment and we have a website -- we need to have a way of actually storing the data we collect. [222003270050] |To do this, you are going to need a web server with a MySQL database. [222003270060] |A decent web hosting company should be able to provide you with this. [222003270070] |The discussion in this tutorial assumes you have a web server and access to a MySQL database. [222003270080] |PHP is another Web language. [222003270090] |It has many purposes, but here we use it as the interface between our experiment and the MySQL database that stores all the recorded data. [222003270100] |1. What is PHP? [222003270110] |I’m not that sure myself, really. [222003270120] |As I understand it, PHP is used to dynamically generate HTML code. [222003270130] |In our Flash experiment, we used dynamic text boxes so that we could display different text depending on the occasion. [222003270140] |PHP does something similar. [222003270150] |The PHP code resides on your web server. [222003270160] |When it is called, the web server uses it to create new HTML code on the fly and then sends that to the user’s browser. [222003270170] |The PHP code itself should never get sent to the user’s browser. [222003270180] |That is, as I understand it, what PHP is for. [222003270190] |However, that is not how we will use it. [222003270200] |We will use PHP as a sort of central link in a bucket brigade. [222003270210] |User data is sent from the Flash file to the PHP file, and from the PHP file to the MySQL database. [222003270220] |In newer versions of Flash, as I understand it, Flash can interact directly with MySQL, but I've never tried that functionality myself. [222003270230] |Flash MX cannot, which is what I started off with. [222003270240] |In any case, this works well enough. [222003270250] |2. Sending data to PHP [222003270260] |Open your FLA file. [222003270270] |You can start with Part4.fla if you like. [222003270280] |The next to last frame should contain the following code: [222003270290] |if (current_trial==total_trials){ gotoAndPlay('finish'); }else{ current_trial += 1; trace(current_trial); gotoAndPlay('Next_Trial'); } [222003270300] |Delete that code and replace it with the following: [222003270310] |stop(); prepareResults(); submitResults(); [222003270320] |Now, after the participant receives feedback on each trial, two subroutines will be run: prepareResults and submitResults. [222003270330] |Now we will write these subroutines. [222003270340] |Go back to the Initialize frame. [222003270350] |At the bottom, type in the following line: [222003270360] |scriptVars = new LoadVars(); [222003270370] |This creates a new variable called scriptVars of type LoadVars. [222003270380] |You will use this variable to pass information to PHP. [222003270390] |function prepareResults() { //demographics scriptVars.subject_age = age; scriptVars.subject_sex = sex; scriptVars.subject_vision = normal_vision; scriptVars.initials = initials; [222003270400] |//experimental data scriptVars.trial = current_trial; scriptVars.correct = correct; scriptVars.stimulus = stimulus; scriptVars.match = match; scriptVars.probe = probe; } [222003270410] |Now, scriptVars contains all the information from the demographic questionnaire as well as the data and stimuli types from the current trial. [222003270420] |Next, we need the code for submitResults. [222003270430] |This involves some fancy maneuvering: [222003270440] |function submitResults() { scriptVars.sendAndLoad("http://URL/submit_vars.php", scriptVars, "POST"); } [222003270450] |scriptVars.onLoad = function() { if (current_trial==total_trials){ gotoAndPlay("finish"); }else{ currenttrial+=1; gotoAndPlay("Next_Trial"); } } [222003270460] |submitResults actually runs a built-in LoadVars function called “sendAndLoad”. [222003270470] |There are 3 arguments: the URL of the php file (you’ll need to adjust this to your actual URL where submit_vars.php is sitting), the name of the data structure being sent, and a flag telling the PHP file what to do with it. [222003270480] |In this manual, we only ever use the “POST” flag. [222003270490] |Here comes the tricky part. [222003270500] |We used the sendAndLoad command, so as soon as the data is sent, Flash runs scriptVars’s “Load” function. [222003270510] |So our next code is exactly this function. [222003270520] |In here, we write the code that prepares the experiment for the next trial and directs it to the appropriate frame. [222003270530] |There are other ways of accomplishing this same feat. [222003270540] |I like this method, because it makes sure the code that iterates trials is easy to find. [222003270550] |The most difficult part of programming in Flash is debugging, mainly because it is hard to find the relevant code. [222003270560] |The more you use functions and define the functions in the same frame, the easier it is to edit and debug your code. [222003270570] |Your Flash file should now look like Part5.fla. [222003270580] |3. Receiving the code in PHP [222003270590] |Let’s take a look a the PHP file we called in our code above (I find it easiest to edit this in a simple text editor): [222003270600] |It looks scary, but it turns out that you can ignore most of this code. [222003270610] |The PHP file first creates a string of MySQL code. [222003270620] |The next line sends runs the mysql_query function with the string as the argument. [222003270630] |Then MySQL is closed and the file ends. [222003270640] |There are only three lines of code you need to modify. [222003270650] |The top two lines will need to be modified so that the host name, username and password are all correct. [222003270660] |This will probably be the same for every experiment, unless different experiments use different databases. [222003270670] |You also need to change the $isql = “INSERT INTO ….” line. [222003270680] |This tells MySQL which table to insert the data into (see the MySQL chapter). [222003270690] |This will probably be different for each experiment. [222003270700] |For this tutorial, you might replace “TABLENAME” with “VSTM”, so that the code reads: [222003270710] |$isql = "INSERT INTO VSTM ($ifields, date, time, ip) VALUES ($ivalues, '$dateStamp', '$timeStamp', '$ip')"; [222003270720] |For those who want more detail, read on below: [222003280010] |Cleaning up the tutorial [222003280020] |The last couple tutorial posts had some formatting problems. [222003280030] |It's difficult to display HTML code within an HTML file. [222003280040] |I've now saved the problematic code as pictures, so they should display correctly now. [222003290010] |Conference Deadlines [222003290020] |Abstract submission deadlines are fast approaching for two of my favorite conference. [222003290030] |The Boston University Conference on Language Development is accepting submissions until May 15. [222003290040] |This is the conference I've been attending longest; this Fall will mark my 5th year running. [222003290050] |Architectures and Mechanisms in Language Processing will be accepting submissions from May 1 to May 28. [222003290060] |AMLaP is the general European conference for research on language processing (typically, language structures at a level higher than a single word), making it the counterpart to America's CUNY Conference on Human Sentence Processing (which, confusingly, doesn't take place at CUNY). [222003290070] |I went to AMLaP for the first time last year and loved it. [222003290080] |Hopefully I'll get something accepted this year so I can attend again. [222003300010] |Max Planck entering South Korea [222003300020] |Germany's Max Planck Institute is starting a partnership with an institution in South Korea. [222003300030] |This comes on the heels of another joint institution in Shanghai. [222003300040] |Max Planck already has other full-fledged institutes in Europe outside Germany proper. [222003300050] |I'm a big fan of the Max Planck institutes, in that I think there is a place for relatively small, focused research institutes outside of academia, and I'm happy to see that they continue to expand. [222003300060] |I hope some day they consider opening Max Planck Boston -- preferably focused on language acquisition, since an institute dealing with particle physics wouldn't be as useful to me. [222003310010] |Video Test -- new and improved [222003310020] |The new experiment that I mentioned recently had a persistent bug. [222003310030] |I finally managed to track it down yesterday and fix it. [222003310040] |So my apologies to anybody who wasn't able to complete the experiment due to the bug (feel free to email me to ask about how it would have ended and what it was about). [222003310050] |For those of you who haven't taken it yet, I think this is one of the most enjoyable experiments in the bunch, so I highly recommend it to everybody. [222003320010] |Web Experiment Tutorial: Chapter 7, MySQL [222003320020] |Several years ago, I wrote a tutorial for my previous lab on how to create Web-based experiments in Flash. [222003320030] |I am currently posting that tutorial chapter by chapter. [222003320040] |MySQL is a very popular and free database program. [222003320050] |We will use it to store your data. [222003320060] |1. What is MySQL? [222003320070] |The pertinent question is: What is a database? [222003320080] |An in depth discussion of databases is beyond the scope of this manual. [222003320090] |For our purposes, you can think of a database as an extremely complicated collection of spreadsheets. [222003320100] |It is in fact much, much more –especially since MySQL in fact implements relational databases. [222003320110] |However, we aren’t going to use any of that functionality. [222003320120] |Each data base contains tables. [222003320130] |For our purposes, you can think of each table as a spreadsheet. [222003320140] |In fact, you can link the data between tables in a database, but you are unlikely to need this capability. [222003320150] |Each table contains rows and columns, just like a spreadsheet. [222003320160] |For all intents and purposes, you can have as many as you want. [222003320170] |The columns are named. [222003320180] |Rows are not. [222003320190] |2. Opening MySQL. [222003320200] |If you have a web interface for your MySQL server, the section below won't be relevant. [222003320210] |The web interface is sufficiently simple that I won't describe it here. [222003320220] |Open a terminal. [222003320230] |Use SSH to log onto your web server. [222003320240] |Here’s what it looks like for me: Last login: Tue Jun 5 13:48:36 on ttyp2Welcome to Darwin!dhcp-0000059136-59-ff:~ josh$ ssh vcognit@research.wjh.harvard.eduPassword: Last login: Tue Jun 5 13:48:17 2007 from dhcp-0000059136Sun Microsystems Inc. SunOS 5.9 Generic May 2002research ~> Now, I change directories to the MySQL bin folder. [222003320250] |If MySQL is in your path, this won’t be necessary. [222003320260] |Open MySQL as follows: research /opt/csw/mysql4/bin> ./mysql -u USERNAME -p DATABASENAMEEnter password: You will need to type in your username and database name as appropriate. [222003320270] |Your database name should have been given to you by your database administrator. [222003320280] |If you are your database administrator, you are going to have to figure this out for yourself. [222003320290] |Once you’ve logged on, you will see the following prompt: Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. [222003320300] |Commands end with ; or \g.Your MySQL connection id is 39203 to server version: 4.1.9-log Type 'help;' or '\h' for help. [222003320310] |Type '\c' to clear the buffer. mysql> 3. [222003320320] |Creating a table. [222003320330] |Although I now have a web interface for MySQL, I continue to use SQL script to create and modify tables, though there are ways of doing some of this through the web interface. [222003320340] |Again, if you can do it the way described below, you should have little difficulty with the web interface. [222003320350] |Now, we are going to create a table to hold the data from our experiment. [222003320360] |Type in the following: mysql> CREATE TABLE VSTM ( -> subject_age INT(3), -> subject_sex VARCHAR(6), -> subject_vision VARCHAR(3), -> initials VARCHAR(5), -> trial INT(3), -> correct INT(1), -> stimulus INT(2), -> match INT(1), -> probe INT(1), -> date DATE, -> time TIME, -> ip VARCHAR(25) -> ); If you are using a web interface, you won't need the "->" codes. [222003320370] |That is something that appears automatically in the terminal to mark that the new line is part of the same command. [222003320380] |The first line names the table “VSTM”. [222003320390] |The following lines create columns. [222003320400] |Note that the names of each column must be EXACTLY the same as the names of the variables in scriptVars. [222003320410] |Otherwise, MySQL can’t figure out which data belongs to which column and nothing will get written. [222003320420] |If MySQL isn’t recording your data, 95% of the time this is because you have a type-o or mismatch in your column and variable names. “date”, “time” and “ip” all come from the PHP file. [222003320430] |Again, the names must match. [222003320440] |INT and VARCHAR are data types. [222003320450] |INT means the column contains integers. [222003320460] |VARCHAR means in contains letters and/or numbers. [222003320470] |The number in parentheses is the size of the column. “match” is always a 0 or a 1, so it only requires a column 1 character wide. “subject_sex” is either 4 letters (“male”) or 6 letters (“female”), so the column size is set to 6. [222003320480] |You can always have bigger columns than are necessary. [222003320490] |DATE and TIME are also data types with rather obvious properties. [222003320500] |Unfortunately this code won’t work. [222003320510] |You’ll get the following response: ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'match INT(1),probe INT(1),date DATE,time TIME,ip VARCHAR(25))' at line 9 MySQL error messages aren’t very useful. [222003320520] |By trial and error, you would figure out that the problem is the name “match”. [222003320530] |“Match” is a restricted name in MySQL, and you can’t give that name to a column. [222003320540] |So we are going to have to change that name here AND in the Flash file. [222003320550] |Change both to “matches”. [222003320560] |This has been done in Part6.fla. [222003320570] |Try again: mysql> CREATE TABLE VSTM ( -> subject_age INT(3), -> subject_sex VARCHAR(10), -> subject_vision VARCHAR(3), -> initials VARCHAR(5), -> trial INT(3), -> correct INT(1), -> stimulus INT(2), -> matches INT(1), -> probe INT(1), -> date DATE, -> time TIME, -> ip VARCHAR(25) -> );Query OK, 0 rows affected (0.01 sec) This time, MySQL says that the table has been successfully created. [222003320580] |4. Deleting a table. [222003320590] |If you want to remove a table, use the drop command: mysql> DROP TABLE VSTM; 5. [222003320600] |Try it out. [222003320610] |Make sure that submit_vars.php is at the URL cited in your Flash file. [222003320620] |Run your experiment once through. [222003320630] |If you have done everything correctly, data will be recorded in your MySQL database. [222003320640] |Now, how do you get to it? [222003320650] |If you run into trouble, use the Flash file Part6.fla. [222003320660] |If there are still problems, then there are probably problems with your table or your PHP file. [222003320670] |In the PHP file, make sure that the username, password, host name, database name and table name are all correct. [222003320680] |In MySQL, make sure you have the right number of columns –12 –and that they are all named the right thing. [222003320690] |You can double check this with the following command: mysql> describe VSTM;+----------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+----------------+-------------+------+-----+---------+-------+| subject_age | int(3) | YES | | NULL | || subject_sex | varchar(10) | YES | | NULL | || subject_vision | char(3) | YES | | NULL | || initials | varchar(5) | YES | | NULL | || trial | int(3) | YES | | NULL | || correct | int(1) | YES | | NULL | || stimulus | int(2) | YES | | NULL | || matches | int(1) | YES | | NULL | || probe | int(1) | YES | | NULL | || date | date | YES | | NULL | || time | time | YES | | NULL | || ip | varchar(25) | YES | | NULL | |+----------------+-------------+------+-----+---------+-------+12 rows in set (0.00 sec) mysql> If yours looks different, fix it. [222003320700] |You can either use the DROP command to remove the table and start over, or you can modify the columns directly. [222003320710] |Here is an example: mysql> alter table VSTM drop column ip;Query OK, 6 rows affected (0.01 sec)Records: 6 Duplicates: 0 Warnings: 0 mysql> alter table VSTM add column ip VARCHAR(25);Query OK, 6 rows affected (0.02 sec)Records: 6 Duplicates: 0 Warnings: 0 There are also commands to simply rename a column, etc. [222003320720] |Google “MySQL alter table” and you should be able to find good explanations of your options. [222003320730] |6. Viewing your data. [222003320740] |You have now run your experiment at least once. [222003320750] |Hopefully MySQL now contains data. [222003320760] |How do you see it? mysql> select * from VSTM;+-------------+-------------+----------------+----------+-------+---------+----------+---------+-------+------------+----------+------+| subject_age | subject_sex | subject_vision | initials | trial | correct | stimulus | matches | probe | date | time | ip |+-------------+-------------+----------------+----------+-------+---------+----------+---------+-------+------------+----------+------+| 2 | male | no | jkh | 0 | 1 | 3 | 1 | 3 | 2007-06-05 | 14:57:06 | NULL || 2 | male | no | jkh | 1 | 1 | 2 | 0 | 3 | 2007-06-05 | 14:57:22 | NULL || 2 | male | no | jkh | 2 | 1 | 3 | 1 | 3 | 2007-06-05 | 14:57:25 | NULL || 2 | male | no | jkh | 3 | 1 | 1 | 0 | 2 | 2007-06-05 | 14:57:27 | NULL || 2 | male | no | jkh | 4 | 1 | 1 | 0 | 2 | 2007-06-05 | 14:57:30 | NULL || 2 | male | no | jkh | 5 | 1 | 3 | 1 | 3 | 2007-06-05 | 14:57:33 | NULL |+-------------+-------------+----------------+----------+-------+---------+----------+---------+-------+------------+----------+------+6 rows in set (0.00 sec) [222003320770] |Everything looks good. [222003320780] |The IP address is NULL because you ran it off of your desktop. [222003320790] |When you run it from the Web, this should change. [222003320800] |Notice that if several people ran this experiment, you would have to use a combination of initials age and sex to tell them apart. [222003320810] |If the same person did the experiment more than once, there would be no easy way to code for that. [222003320820] |What we want is a subject number. [222003320830] |7. Creating a subject number. [222003320840] |Add the following code to the Intialize frame: var getID = new LoadVars();getID.onLoad = function(success) { id = this.id;};getID.load("http://URL/get_next_id.php"); Open get_next_id.php: [222003320850] |$db = mysql_connect ('HOST', 'USERNAME', 'PASSWORD');mysql_select_db ('DATABASE'); $query1 = "INSERT INTO VSTM_id_incrementor VALUES (NULL);";mysql_query($query1); $id = mysql_insert_id ($db); mysql_close(); echo "&id=" . $id; ?> [222003320860] |Again, change the first two lines to match your host name, username, password and database name. [222003320870] |Notice that this file inserts a blank row into the table VSTM_id_incrementor. [222003320880] |We need to create this table: mysql> CREATE TABLE VSTM_id_incrementor ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY);Query OK, 0 rows affected (0.01 sec) This creates the table VSTM_id_incrementor with a single column –id –that automatically increments. [222003320890] |That is, each time a row is added, the value of that column in that row will be one greater than in the previous row. [222003320900] |Try this: mysql> select * from VSTM_id_incrementor;Empty set (0.00 sec) mysql> insert into VSTM_id_incrementor VALUES ('NULL');Query OK, 1 row affected, 1 warning (0.00 sec) mysql> select * from VSTM_id_incrementor;+----+| id |+----+| 1 |+----+1 row in set (0.00 sec) mysql> insert into VSTM_id_incrementor VALUES ('NULL');Query OK, 1 row affected, 1 warning (0.00 sec) mysql> insert into VSTM_id_incrementor VALUES ('NULL');Query OK, 1 row affected, 1 warning (0.00 sec) mysql> select * from VSTM_id_incrementor;+----+| id |+----+| 1 || 2 || 3 |+----+3 rows in set (0.00 sec) 8. [222003320910] |Recording the subject number. [222003320920] |Now, each time the Flash file runs, it will insert a blank row into VSTM_id_incrementor and retrieve the new subject id. [222003320930] |Now we need to record that when data is recorded. [222003320940] |There is only one small change to the Flash file. [222003320950] |Add: scriptVars.subject_id = id; to prepareResults. [222003320960] |You can see this in Part7.fla. [222003320970] |You need to also add a column called “subject_id” to the table VSTM: mysql> alter table VSTM add column subject_id INT(4);Query OK, 6 rows affected (0.01 sec)Records: 6 Duplicates: 0 Warnings: 0 Make sure that the get_next_id.php file in your website has been updated. [222003320980] |Now, run your experiment again. [222003320990] |Afterwards, you should be able to see something like this: select * from VSTM;+-------------+-------------+----------------+----------+-------+---------+----------+---------+-------+------------+----------+---------------+------------+| subject_age | subject_sex | subject_vision | initials | trial | correct | stimulus | matches | probe | date | time | ip | subject_id |+-------------+-------------+----------------+----------+-------+---------+----------+---------+-------+------------+----------+---------------+------------+| 2 | male | no | jkh | 0 | 1 | 3 | 1 | 3 | 2007-06-05 | 14:57:06 | NULL | NULL || 2 | male | no | jkh | 1 | 1 | 2 | 0 | 3 | 2007-06-05 | 14:57:22 | NULL | NULL || 2 | male | no | jkh | 2 | 1 | 3 | 1 | 3 | 2007-06-05 | 14:57:25 | NULL | NULL || 2 | male | no | jkh | 3 | 1 | 1 | 0 | 2 | 2007-06-05 | 14:57:27 | NULL | NULL || 2 | male | no | jkh | 4 | 1 | 1 | 0 | 2 | 2007-06-05 | 14:57:30 | NULL | NULL || 2 | male | no | jkh | 5 | 1 | 3 | 1 | 3 | 2007-06-05 | 14:57:33 | NULL | NULL || 26 | male | yes | jkh | 0 | 1 | 3 | 0 | 1 | 2007-06-05 | 16:01:26 | 140.247.95.39 | 4 || 26 | male | yes | jkh | 1 | 1 | 2 | 1 | 2 | 2007-06-05 | 16:01:28 | 140.247.95.39 | 4 || 26 | male | yes | jkh | 2 | 1 | 2 | 0 | 3 | 2007-06-05 | 16:01:32 | 140.247.95.39 | 4 || 26 | male | yes | jkh | 3 | 1 | 3 | 1 | 3 | 2007-06-05 | 16:01:34 | 140.247.95.39 | 4 || 26 | male | yes | jkh | 4 | 1 | 1 | 1 | 1 | 2007-06-05 | 16:01:37 | 140.247.95.39 | 4 || 26 | male | yes | jkh | 5 | 1 | 3 | 0 | 2 | 2007-06-05 | 16:01:40 | 140.247.95.39 | 4 |+-------------+-------------+----------------+----------+-------+---------+----------+---------+-------+------------+----------+---------------+------------+12 rows in set (0.00 sec) Notice that a subject ID is now recorded. [222003321000] |One problem with this method is that occasionally the same subject number will be given to two different subjects who start at roughly the same time. [222003321010] |You can usually distinguish them by demographic information: they will have different ages. [222003321020] |However, this is not ideal, and I've been experimenting with other options. [222003321030] |9. Exporting data You can now view your data, but you can’t do very much with it. [222003321040] |To export data to a text file, you need to be in the SSH shell (you can’t do it directly from within MySQL). [222003321050] |Type the following: ./mysql –u USERNAME –p PASSWORD –e “SELECT * from VSTM” >/PATH/VSTM_data.txt This will record the output from “SELECT * from VSTM” to the file VSTM_data.txt in the location /PATH/. [222003321060] |You will need to have write privileges for that directory. [222003321070] |10. Screening subjects. [222003321080] |You would probably like to only analyze data from subjects that completed the task. [222003321090] |Unfortunately, not all will complete the task. [222003321100] |You can cull them by hand, but there is a fairly simple method using Microsoft Excel. [222003321110] |Open Results.txt from the Resources folder in Microsoft Excel. [222003321120] |These data are from a VSTM experiment I actually ran. [222003321130] |Not all the columns are included in order to protect privacy. [222003321140] |You will notice that 75 subjects completed the 0th trial, but only 70 completed the 7th and final trial. [222003321150] |We want to eliminate all data from subjects that did not complete the 7th trial. [222003321160] |Sort the rows first by trial and second by subject_id so that it looks like this:Highlight the 70 subject id’s that completed trial 7. [222003321170] |Copy these. [222003321180] |Go to Excel->Preferences->Custom Lists. [222003321190] |Past the subject IDs into the “List entries:” form and then click “Add”. [222003321200] |Then click “OK”. [222003321210] |Select all rows and columns. [222003321220] |Click Data->Sort. [222003321230] |Choose sort by subject_id, ascending, and click “options”. [222003321240] |Under “Sort Order” instead of “normal” choose the new sort order that you just created. [222003321250] |Select “OK” twice. [222003321260] |Now the spreadsheet should be sorted according to your custom sort order. [222003321270] |Now scroll to the bottom of the file. [222003321280] |After subject 721, you will see several rows with subjects 607, 651, 663, 682 and 683. [222003321290] |These are the subjects who did not complete the experiment –all neatly separated from the rest of the data. [222003321300] |As usual, please leave any question in the comments.