In Modeling Instruction and Advanced Placement science courses, students must be able to analyze data to determine the relationship between two variables. To make this easier, I created a Data Analysis Tool.

I’ve tried a few ways for students to graph data:

Method | Pros | Cons |

Graph Paper | * Requires a firm grasp of scales, slope, and y-intercept * Students gain a better grasp of the meaning of these quantities and where they come from * Flexible — few limitations * No technology quirks to learn | * Time-consuming * Requires multiple iterations to linearize non-linear relationships * Difficult to test several analysis methods to determine the best fit * Best-fit lines, slopes, and y-intercepts are not as accurate |

TI-84 Calculator | * Can be used on the AP Exam & ACT! * Manual window-setting requires students to consider how they will view their data * Students can create their own best-fit line by writing a linear equation in Y1 * OR, it has LinReg capabilities * A bit quicker than graphing by hand | * Data entry, turning stat-plots on, and graphing is not as intuitive as it could/should be * Regressions are also not very intuitive, and getting the linear fit to display on the graph is another hurdle * Doesn’t handle units at all — that’s up to the student * No easy way to get a printout of the graph for inclusion in reports * Not all students have this calculator (it’s expensive) |

Vernier LoggerPro | * Quick * Takes care of units, labels, and titles * Easily adjust what is graphed on each axis * Support for force, motion, and other sensors * Linear fit is available with 1 button click * Supports graphing multiple data sets, a secondary y-axis scale, and many advanced features | * Linearizing with calculated columns is somewhat cumbersome; requires quite a few steps * For novices, the large number of features make it difficult to remember the correct steps to get the desired results * Not likely to use this software in other contexts * Not widely available (though the site license is generous) |

Microsoft Excel or Google Sheets | * Powerful and flexible * Supports graphing multiple data sets, secondary y-axis scale, and many advanced features * Likely to be used in college, industry, etc. * Widely available (and for Google Sheets, free) | * Need to set up own data table * New versions of Excel do not label axes by default * Google Sheets graphs lack some features and are not the most intuitive (though I haven’t used them in a couple years so perhaps they’ve improved) * Again, the huge number of features often make it hard to find the desired functions |

To start the year, I always have students graph data using graph paper for a couple weeks. I think students need to be able to do it themselves and understand the basic considerations of choosing scales, deciding what to plot where, and finding slopes and y-intercepts manually before having a device/computer do it for them.

In the past, after students got more comfortable graphing things by hand, I showed them how to use some tools (in the past, this tool has been LoggerPro). But, after having to guide students through the LoggerPro linearization process time and time again for each lab, I wanted to find a better solution. My current version works pretty well, but I’d welcome your feedback. I also have a version with linearization tools hidden.

In June of 2016, I wrote a quick online data analysis tool (using the graphing capabilities of CanvasJS). Check it out here. It does most of what I need it to, which is to take a set of data, graph it, allow students to linearize it (graph y vs. x^{2}, y vs. 1/x, etc.), and output the best-fit line equation.

I also created a version with the linearization capabilities hidden (to require students to do this manually).

Improvements I may try to implement in the future:

- Data input improvements (arrow keys for navigating) –
**implemented though still has some quirks** - Improve linearization interface somehow – still thinking about this
- Display the squared, cubed, or inverse of a column in the data table (?)
- Graph multiple data sets simultaneously

This year, my school is beginning virtually. It will be a challenge to transform our chemistry lab activities to the online format until we are able to resume in-person classes (and even then, we will be limited in the types of activities that we can do while “socially distant”). As I thought about facilitating my class online, I discovered Construct.net, which is typically used to produce online games. I found that it can be adapted to simulate labs like this one. I created a couple different versions. Check them out!

Chemistry Mass-Volume Lab Simulation

Chemistry Mass-Volume Lab Simulation with Water Displacement

It simply allows students to measure the mass and volume of several samples of a material (currently, it has steel, aluminum, and wood). The first sample is always the same size for everybody, but subsequent samples are random sizes/masses (so encourage students to include a wide range of sample sizes in their data). Students can then use whatever graphing tools desired to analyze the data. A few years ago, I made a simple data analysis tool that would work well for this.

I like that the water displacement version shows which substances sink and float. Also, you can produce some samples that, because of their size or density (wood) do not completely submerge. This provides a chance to discuss what the water displacement measurement represents.

The water displacement version can also be used to show the relationship between cm^{3} and ml.
Just measure a sample with the ruler and then dunk it in the water.

Leave a comment about any issues you find or requests for features. Here are some things I’m thinking about:

- More realistic interactions: an on-screen ruler to measure length, width, and height would build measurement skills. But, Contruct.net is really a 2-dimensional tool, so measuring that third dimension would be a challenge.
- UPDATE July 27, 2020:
- Added zinc, copper, and lead to the substances.

- Changed the button text to say “New Size”
- Clarified the instructions.

The source files are available for anyone wanting to modify or extend. Just promise not to chide me too severely–it was my first time with Contruct! I do encourage anyone else working on this or similar lab simulations to share what you come up with.

]]>The applet used by PLTW is a Shockwave applet by Serendip, but Shockwave hasn’t been well-supported in a long time, and now that my students use Chromebooks, it definitely won’t work. It now appears that the shockwave app has been removed, and the PLTW curriculum now uses a much more basic reaction time app.

So, I set out to recreate this great applet in a more portable and cross-platform language (HTML and JavaScript). The functionality is similar. My attempt is definitely not as refined as the original, but it gets the job done. Also, students are responsible for recording their own times, because my version discards all times when changing between parts of the activity.

- Snaky springs – ($13.50/ea from Amazon and comes with slinky and rope, $17/ea from Arbor Sci, $18/ea from PASCO) – Students can set up standing waves in the spring, then measure frequency and wavelength. It’s very tactile and when it works, it works well — data is reliable. It is difficult to get a feel for how to oscillate at the correct frequency for the standing waves (and some groups weren’t really successful doing so in the time we had). Only allows for 4 or 5 harmonics before it becomes very difficult to introduce such high-frequency oscillations.
- Computer Simulation – PhET – Allows adjustment of amplitude, frequency, end type, damping, etc. and measurement of wavelength. A fine option, though not as tactile. I use it for students to investigate wave reflections, but have not used it for wavelenth & frequency. I would prefer a real-world, more tactile method if possible — I question whether students always make the connection to real-world situations when their primary experience is a computer simulation.
- Wave drivers – (Vernier: $115, but also need a power amplifier, $199; PASCO: $249, but also need a function generator, $259+; CPO $400, there are probably other systems available, but they all seem to be very expensive) – allows students to adjust the frequency of vibrations in a string until a standing wave is set up, then measure wavelength. Using this method, students are very interested and engaged, and they get to see a real-world physics phenomenon. The data produced is very reliable. But this would be a very expensive set-up to provide for 6 lab groups.

I set out to see if I could make my own wave driver for less $$$.

For my first iteration, I used some Logitech computer speakers ($20 on Amazon). Essentially, I removed the grille covering the speaker and hot-glued a bent paper clip to the speaker cone, that allows the speaker to drive a string.

I tie the string to a solid object on one end (ring stand) and run it across a table and off the end over a pulley. Then, hang a weight off the pulley end of the string to introduce a known tension.

I connect the speaker system to a laptop, have students go to an online function generator (like this one, though there are many available), and adjust the frequency until a standing wave is set up. Then they measure the wavelength and record the frequency/wavelength pair.

By graphing wavelength vs. frequency, students can determine that an inverse relationship exists, which they can then linearize (possibly by using my data analysis tool). The slope then comes out to be a speed, which we determine to be the wave speed in the string.

The speaker works wonderfully. The wave amplitude isn’t great, but the standing waves are clearly visible.

I also tried this with a cheaper speaker system, but the speaker cone barely moved, so it didn’t produce visible standing waves in the string. You need a speaker for which the cone moves with a decent amplitude to drive the waves in the string.

I wanted to see if I could further cut down on the cost. I obtained the following supplies:

Description | Source | Cost/each |

TDA7297 Audio Power Amplifier *(There are many similar versions available. Try to find one with a 5.5 mm OD barrel/coaxial power plug and a 3.5mm aux audio connector. The one I bought had a 3-pin audio connector, so I had to buy some of those and solder it to a 3.5mm aux cord. You only need a single channel or just use 1 of a 2-channel amplifier) | eBay (search) | $2.65 (more or less) |

DC 12V AC Adapter *(You may be able to find them more cheaply – just need a 5.5 mm OD / 2.1 mm ID plug. I went with a 2-amp output to ensure enough power, but probably 1A is enough.) | eBay or Amazon | $5.00 or $4.00 |

5′ Aux cord (3.5mm headphone plug) *(one cord will make 2 wave drivers – you can use both ends) | eBay | $0.50 |

3 pin board connector plug *(This was needed for mine to connect the signal in to the board, but depends on the board you bought) | eBay | $0.35 |

2″ or 3″ speaker A Logitech 3W 4-ohm speaker worked ok. A 50W car speaker worked ok also, but I’ll probably need to use a heavier string. Around a 10W speaker seems to be ideal. | eBay eBay 2 Amazon Amazon 2 | $5.00 – $7.00 |

Speaker wire – Used scraps I had available | ||

Screws – I have an assortment, but here’s what I used (3) tiny screws to attach PCB amplifier board to wood board (2) 2″ drywall screws (or similar) to attach speaker to board (?) I also screwed down the audio cable with a piece of plastic to keep it from being accidentally pulled off and damaging stuff. | ||

1×4 mounting board (about 6″ long) – From scraps | ||

Total | $12.50 – $15.50 |

The initial prototype works great.

- Cut a piece of 1×4 board in about 6 inch long pieces to serve as a base.
- Use 3 tiny screws to secure the amplifier PCB to the 1×4. Arrange it so the power connector hangs off one side of the board.
- Cut a 3.5mm aux cord in half. Strip the insulation from the end you cut. There are 2 wires inside that carry the left and right channel signal (carefully strip about 1/4″ of insulation from these as well), and bare wires which are neutral. Of course, not all cables are made the same way, so yours may be different.
- Cut a fan extension cable in half so you have the female pin end (shown). Strip the ends you cut.
- Twist together the black fan connector wire with the neutral aux cord wire. Similarly, connect the red fan connector wire with one channel from the aux cord. And the yellow fan connector wire with the other channel from the aux cord. Solder these connections, then cover each one with heat-shrink tubing (or easier: electrical tape). Sorry, I forgot to take a picture of this…
- Plug the female pin connector into the amplifier board. I also used an electrical cord staple, removed the nails, and screwed it down on top of the aux cord wires to hopefully prevent some jerk from jerking the cord and destroying my wave driver.
- Run a wire from the amplifier output (+) to one terminal on the speaker.
- Run another wire from the amplifier output (-) to the other terminal of the speaker. (Doesn’t matter which is which)
- Tighten the screw-connectors on the amplifier output terminals.
- Solder these other ends on the wires to the speaker.
- Use the 2″ screws to attach the speaker to the 1×4. Depending on the size of your speakers, you may need longer/shorter screws.
- Bend a paper clip and hot glue or epoxy it to the speaker cone as shown:

The cord or string being driven sits in the loop on the paper clip. - Plug it into a computer speaker output, plug in AC adapter, and go to http://www.szynalski.com/tone-generator/ (or any other similar tone/frequency generator).
- Run a horizontal string as described in the “Speaker Version” section above.
- Adjust the frequency until standing waves are produced….

Any questions? Comment below.

UPDATE: One of my modeling heroes, Mark Schober, has built something similar (though much nicer looking) – read about it and sign up for the workshop if you’re in the NYC area.

]]>– Trigonometric functions will use degrees or radians as set in the Settings for (file name) in the File menu.

– For more information about Savitsky-Golay methods see Numerical Recipes in C: http://lib-www.lanl.gov/numerical/bookcpdf.html chapter 15

Function | Description |

analysis | (“X”, startRow, endRow) Takes all columns named “X” and extracts startRow to endRow for each of those columns, appending the values into a single column. |

dataSets | datasets(“X”) Appends the dataset names of all datasets that have a column named “X”. Use analysis and datasets together to create a graph (analysis on the vertical axis and datasets on the horizontal). for example, if you had 3 datasets as follows: DS1 DS2 DS3 X X Y 1 11 21 2 12 22and then added analysis(“X”, 1, 1) and datasets(“X”) you would get:datasets analysis DS1 1 DS2 11 |

beats per minute | BeatsPerMinute(“Signal”, “Time”, intervalInSeconds, minPercent, maxPercent, noise) Returns the number of beats per minute of the values in “Signal” vs. “Time”. This function is similar to the rate function except that the interval given here is always in seconds and the returned value is always in minutes. For example, if “Time” is in seconds then: beatsPerMinute(“Signal”, “Time”, interval, min, max, noise) = 60 * rate(“Signal”, “Time”, interval, min, max, noise) |

diastolic | The measured arterial pressure when the heart is at rest. “Pressure” and a “Time” column as inputs and return a single number. diastolic(“Pressure”, “Time”) “Pressure”: Pressure values from the BPS “Time”: Time the pressure values were recorded Returns the smaller number of blood pressure |

meanArterialPressure | meanArterialPressure(“Pressure”, “Time”)“Pressure”: Pressure values from the BPS “Time”: Time the pressure values were recorded Returns the pressure value at the max peak used for blood pressure calculations. |

Oscillations | Oscillations(“Pressure”, “Time”) “Pressure”: Pressure values from the BPS “Time”: Time the pressure values were recorded Returns the Oscillations of the peaks and valleys used to calculate systolic and other blood pressure values. |

OscillatoryPeaks | OscillatoryPeaks(“Pressure”, “Time”) “Pressure”: Pressure values from the BPS “Time”: Time the pressure values were recorded Returns the peaks used to calculate systolic, diastolic, and pulse (the “high” values in “Oscillations”). |

pulse | pulse(“Pressure”, “Time”) “Pressure”: Pressure values from the BPS “Time”: Time the pressure values were recorded Returns the pulse using the inputs from the Blood Pressure Sensor (similar results, different algorithm as the other beats-per-minute functions) |

systolic | systolic(“Pressure”, “Time”) “Pressure”: Pressure values from the BPS “Time”: Time the pressure values were recorded The measured arterial pressure when the heart contracts. Returns the larger number of blood pressure |

For the boolean functions a 1 is considered true, 0 false and anything else an invalid input | |

AND | AND(X, Y) return 1 if and only if X and Y are both 1 |

NOT | NOT(X) return 1 if X is 0; 0 if X is 1 |

OR | OR(X, Y) return 1 if X or Y is 1 |

XOR | XOR(X, Y) return 1 if X or Y is 1 but not both |

calculus > | |

derivative | derivative(“Y”, “X”) “Y”: A column of real numbers “X”: Optional. A column of real numbers The numerical derivative is the weighted average of the slope of ‘n’ points around each point. You can set ‘n’ in Settings for (Name). If you don’t supply an “X” column, the program will find one. |

derivativeSG | derivativeSG(“Y”, “X”) “Y”: A column of real numbers “X”: Optional. A column of real numbers Savitsky-Golay derivative. Fits a polynomial to ‘n’ points around each point and computes the derivative of the polynomial at that point. You can set ‘n’ in Settings for (Name). If you don’t supply an “X” column, the program will find one. |

derivativeTimeShift | derivativeTimeShift(“Y”, “X”) Returns the derivative of “Y” with respect to “X”. This function is specifically designed to be used with photogate and picket fence data. The derivatives returned are adjusted to estimate values at the start of the timing interval, instead of the midpoint. For details see The Physics Teacher, Vol 35, April 1997, p. 220. The article written by William Leonard is entitled “The Dangers of Automated Data Analysis.” Average velocity during the time interval is equal to the instantaneous velocity at midpoint of the time interval. Where |

integral | integral(“Y”,”X”) “Y”: A column of real numbers “X”: Optional. A column of real numbers The numerical integral is the running sum of the areas of rectangles calculated by the midpoint rule. The i’th rectangle is (Yi – Y(i-1)) / (Xi – X(i-1)). If you don’t supply an “X” column, the program will find one. |

secondderivative | secondDerivative(“Y”, “X”) “Y”: A column of real numbers “X”: Optional. A column of real numbers Calculates the numerical second derivative of “Y” with respect to “X”. If you don’t supply an “X” column, the program will find one. |

secondderivativeSG | secondDerivativeSG(“Y”, “X”) “Y”: A column of real numbers “X”: Optional. A column of real numbers Savitsky-Golay second derivative. Fits a polynomial to ‘n’ points around each point and computes the second derivative of the polynomial at that point. You can set ‘n’ in Settings for (Name). If you don’t supply an “X” column, the program will find one. |

secondderivative Time Shift | secondDerivativeTimeShift(“Y”, “X”) “Y”: A column of real numbers “X”: Optional. A column of real numbers Numerical time-shifted second derivative. Calculates the second numerical derivative of “Y” with respect to “X”. The values are shifted so that the derivatives are calculated at the midpoints between each two values. If you don’t supply an “X” column, the program will find one. |

collapse | collapse(“X”) Returns a column with all non-numerical cells (blanks and text) removed. |

collapseIndirect | collapseIndirect(X, Y) Returns a column of only the rows in “X” corresponding to rows in “Y” that have valid numerical cells. |

constant | Constant(x, num) x: A real number num: A real number or a column Generates a constant column filled with the value ‘x’. The number of values in the returned column is num, or if a column was passed in, the size of the passed-in column. |

delta | delta (“X”) “X”: A column of real numbers Returns a column of values where the i’th value is the i’th value in “X” minus the (i-1)’th value in “X”. |

lowPassFilter | (“Y”, “X”, “ripple”, “freqCutoff”) “Y”: The data column to be filtered “X”: The associated time column for “Y” “ripple”: The ripple allowed in the pass-band “freqCutoff”: Cut-off frequency (-3dB), in hertz Applies a Chebyshev low-pass filter. For “ripple”, enter a value that is a percent of the pass-band. To apply a Butterworth low-pass filter, set “ripple” to 0. |

highPassFilter | (“Y”, “X”, “ripple”, “freqCutoff”) “Y”: The data column to be filtered “X”: The associated time column for “Y” “ripple”: The ripple allowed in the pass-band “freqCutoff”: Cut-off frequency (-3dB), in hertz Applies a Chebyshev high-pass filter. For “ripple”, enter a value that is a percent of the pass-band. To apply a Butterworth high-pass filter, set ripple to 0. |

bandPassFliter | (“Y”, “X”, “lowFreq”, “highFreq”) “Y”: The data column to be filtered “X”: The associated time column for “Y” “lowFreq”: Low frequency cut-off (-3dB), in hertz “highFreq”: High frequency cut-off (-3dB), in hertz Ripple is automatically set to zero and is not adjustable. The function returns the signal with the frequencies outside the designated frequency range removed. |

bandStopFliter | (“Y”, “X”, “lowFreq”, “highFreq”) “Y”: The data column to be filtered “X”: The associated time column for “Y” “lowFreq”: Low frequency cut-off (-3dB), in hertz “highFreq”: High frequency cut-off (-3dB), in hertz Ripple is automatically set to zero and is not adjustable. The function returns the signal with the frequencies inside the designated frequency range removed. |

timeDecayFilter | (“Y”, “X”, “decayConstant”) “Y”: The data column to be filtered “X”: The associated time column for “Y” “decayConstant”: A value in seconds that determines the decay of “Y” Applies an exponential time decay to the signal. |

ElectrophoresisInterpolate | ElectrophoresisInterpolate(“Std. Dist”, “Std. BP”, “Dist”) “Std. Dist”: Distances from the standard “Std. BP”: Base Pair Counts from the standard “Dist”: Distances to interpolate Returns a column of base pair counts based on the Electrophoresis curve fit for “Std. Dist” vs. “Std. BP” given “Dist”. Will NOT work if curve fit has been deleted. This function is used automatically when doing a Gel Analysis (Electrophoresis). |

exp | exp(“X”) “X”: A column of real numbers Returns the exponent, exp(x) = e^x, where e is the natural log base (2.17…). |

integer | integer(“X”) Extracts the integral part of values in “X”. |

interpolate | interpolate(“X”) Fills in missing values using linear interpolation. |

ln | ln(“X”) “X”: A column of real numbers larger than 0 Returns the natural logarithm. If b = ln(a) then e^b = a (Where e is the constant 2.17…). |

log | log(“X”) “X”: A column of real numbers larger than 0 (Log base 10) If b = log(a) then 10^b = a. |

modulo | modulo(“X”, n) “X”: A column of integers n: An integer larger than 0 Returns the remainder of each of the numbers in “X” when divided by n. |

Blocked MidTimes | BlockedMidTimes(“Time”, “Gate1”, “Gate2”) “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) “Gate2”: Optional. A column of photogate states (1’s and 0’s) Calculate the average times between blocked events from Gate 1 to Gate 2. If you don’t enter a “Time” column, the program will find one. If you don’t enter “Gate2”, “Gate1” will be used. |

Blocked to Blocked | BlockedToBlocked(“Time”, “Gate1”, “Gate2”) “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) “Gate2”: Optional. A column of photogate states (1’s and 0’s) Returns a column of the times between successive blocked events in gate 1 and blocked events in gate 2. If you don’t enter a “Time” column, the program will find one. If you don’t enter “Gate2”, “Gate1” will be used. |

Blocked to Unblocked | BlockedToUnblocked(“Time”, “Gate1”, “Gate2”) “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) “Gate2”: Optional. A column of photogate states (1’s and 0’s) Returns a column of the times between successive blocked events in gate 1 and unblocked events in gate 2. If you don’t enter a “Time” column, the program will find one. If you don’t enter “Gate2”, “Gate1” will be used. |

Blocked to Unblocked MidTimes | Blocked to Unblocked MidTimes “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) “Gate2”: Optional. A column of photogate states (1’s and 0’s) Calculate the average time between the blocked events in gate 1 and unblocked events in gate 2. If you don’t enter a “Time” column, the program will find one. If you don’t enter “Gate2”, “Gate1” will be used. |

derivativeTimeShift | DerivativeTimeShift (“Y”, “X”) Returns the derivative of “Y” with respect to “X”. This function is specifically designed to be used with photogate and picket fence data. The derivatives returned are adjusted to estimate values at the start of the timing interval, instead of the midpoint. For details see The Physics Teacher, Vol 35, April 1997, p. 220. Average velocity during the time interval is equal to the instantaneous velocity at midpoint of the time interval. Where |

Pendulum Period | PendulumPeriod(“Time”, “Gate1”) “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) Calculate the time between every other blocked event on Gate 1. If you don’t enter a “Time” column, the program will find one. |

secondDerivativeTimeShift | secondDerivativeTimeShift(“Y”, “X”) “Y”: A column of real numbers “X”: Optional. A column of real numbers Numerical time-shifted second derivative. Calculates the second numerical derivative of “Y” with respect to “X”. The values are shifted so that the derivatives are calculated at the midpoints between each two values. If you don’t supply an “X” column, the program will find one. |

Unblocked to Blocked | UnblockedToBlocked(“Time”, “Gate1”, “Gate2”) “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) “Gate2”: Optional. A column of photogate states (1’s and 0’s) Returns a column of the times between successive unblocked events in gate 1 and blocked events in gate 2. If you don’t enter a “Time” column, the program will find one. If you don’t enter “Gate2”, “Gate1” will be used. |

Unblocked to Unblocked | UnblockedToUnblocked(“Time”, “Gate1”, “Gate2”) “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) “Gate2”: Optional. A column of photogate states (1’s and 0’s) Returns a column of the times between successive unblocked events in gate 1 and unblocked events in gate 2. If you don’t enter a “Time” column, the program will find one. If you don’t enter “Gate2”, “Gate1” will be used. |

Unblocked to Blocked MidTimes | Unblocked to Blocked MidTimes “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) “Gate2”: Optional. A column of photogate states (1’s and 0’s) Calculate the average time between unblocked events in gate 1 and blocked events in gate 2. If you don’t enter a “Time” column, the program will find one. If you don’t enter “Gate2”, “Gate1” will be used. |

Unblocked MidTimes | UnblockedMidTimes(“Time”, “Gate1”, “Gate2”) “Time”: Optional. A column of real numbers (the times of events) “Gate1”: A column of photogate states (1’s and 0’s) “Gate2”: Optional. A column of photogate states (1’s and 0’s) Calculate the average times between unblocked events from Gate 1 to Gate 2. If you don’t enter a “Time” column, the program will find one. If you don’t enter “Gate2”, “Gate1” will be used. |

rate | rate(“Y”, “X”, t, m1, m2, n) “Y”: A column of real numbers “X”: Optional. A column of real numbers t: Optional. Time interval m1: Optional. Minimum threshold m2: Optional. Maximum threshold n: Optional. Noise threshold Returns the rate of “Y” with respect to “X”, where t is the time interval measured, m1 is min percentage threshold, m2 is max percentage threshold, and n is noise threshold. “X”, t, m1, m2, and noise are all optional with default values “X” is time column, t = 1/10 the range, m1 = 40%, m2 = 60%, and noise = 0. Details |

amplitude | (“Data Column”, “Time Column”, “Min Percent”, “Max Percent”, “Time Interval”) “Data Column”: Data for which you want to calculate amplitude “Time Column”: Associated time column for “Data Column” “Min Percent”: Threshold used to detect valleys “Max Percent”: Threshold used to detect peaks “Time Interval”: Period of time over which amplitude is calculated (in the time units of the experiment) Calculates peak to peak amplitude. For Min and Max Percent, enter values between 0 and 100. Smaller values are more sensitive to noise and thus more sensitive to real cycles. Larger values are less sensitive to noise; too large of a value may filter out real cycles. “Time Interval” ends at the row at which the value is calculated (the current time). |

period | (“Data Column”, “Time Column”, “Min Percent”, “Max Percent”, “Time Interval”) “Data Column”: Data for which you want to calculate period “Time Column”: Associated time column for “Data Column” “Min Percent”: Threshold used to detect valleys “Max Percent”: Threshold used to detect peaks “Time Interval”: Period of time over which period is calculated (in the time units of the experiment) Calculates the period of an oscillating function. For Min and Max Percent, enter values between 0 and 100. Smaller values are more sensitive to noise and thus more sensitive to real cycles. Larger values are less sensitive to noise; too large of a value may filter out real cycles. “Time Interval” ends at the row at which the value is calculated (the current time). |

round | round(“X”) “X”: A column of real numbers Round. Returns the closest integer to x. If x is equidistant to two integers, round(x) gives the largest of the two (e.g., round(0.5) = 1). |

smoothAve | smoothAve(“X”) “X”: A column of real numbers Returns a column of moving averages of the values in “X”. The width of the “window” to use when averaging points can be set in Settings for (Name)… |

abs | abs(“X”) “X”: A column of real numbers Absolute value. If x less than 0, then abs(x) = -x. Otherwise, abs(x) = x. |

ceiling | ceiling(“X”) “X”: A column of real numbers Returns the smallest integer larger than or equal to x. |

floor | floor(“X”) “X”: A column of real numbers Returns the largest integer smaller than or equal to x. |

max | max(“X”) “X”: A column of real numbers Compares all the values in a single column and returns a single number-the largest number in the column. |

max2 | max2(“X”, “Y”) “X”: column of real numbers “Y”: A column of real numbers or a single number. Compares all the values in a column against a real number (e.g max2(“X”, 5.1)) |

mean | mean(“X”) “X”: A column of real numbers Arithmetic mean. Returns the sum of all the values in “X” divided by the number of values. |

median | Median(“X”). “X”: A column of real numbers If m = median(“X”), then half the numbers in “X” are greater than (or equal) to m, and half are less than or equal. |

min | min(“X”) “X”: A column of real numbers Compares all the values in a single column ,and returns a single number-the smallest number in the column. |

min2 | min(“X”, “Y”) “X”: A column of real numbers “Y”: A column of real numbers or a single number Compares all the values in a column against a real number (e.g min2(“X”, 5.1)) |

numRows | NumRows(“X”) “X”: A column of real numbers Returns a single value-the number of rows in the column. |

randInt | randInt(min, max, num): min: A real number max: A real number num: A real number or a column Random Integer. Returns a column of random integers between min and max (inclusive). The size of the returned column is num. If num is a column, then the size will be the number of rows in that column. |

randReal | randReal(min, max, num) min: A real number max: A real number num: A real number or a column Random Real. Returns a column of random real numbers between min and max (inclusive). The size of the returned column is num. If num is a column, then the size will be the number of rows in that column. |

stddev | stddev(“X”) “X”: A column of real numbers Standard Deviation. Returns a column representing the standard deviations of each of the numbers in a column. |

step | step(start, increment, num, first, skip) start: Start value increment: Increment value num: Number of values to generate first: Optional. First non-empty row skip: Optional. Rows to skip between each value Generates a column “num” rows long starting with “start” and incrementing by “increment”. “num” can be a positive integer or a column name. Optional parameters: “first” is the first non-empty row and “skip” is the number of rows to skip between each value. |

StepColumnBase | stepColumnBased(“X”, start, increment, first, skip) start: Start value increment: increment value first: Optional. First non-empty row skip: Optional. Row to skip between each value Generates a column based on non-empty values in column “X” starting with “start” and incrementing by “increment.” “First” is the first non-empty row and “skip” is the number of rows to skip between each value. |

subset | subset(“X”, startRow, step) “X”: A column of real numbers startRow: An integer larger than 0 step: An integer larger than 0 Extract a subset. Returns a column extracted from “X” starting with ‘startRow’ by ‘step’. For example, subset(“X”, 1, 2) will get every second row of “X” starting with row 1. |

sum | Sum(“X”) “X”: A column of real numbers Returns a column whose n’th value is the sum of the values in “X” from row 1 to n. |

sqrt | Square root. “X”: A column of non-negative real numbers. If x is the square root of y, then x*x = y. |

sin | sin(“X”) “X”: A column of real numbers In a right triangle with angle between two sides ‘x’, sin(x) is the length of the opposite side divided by the hypotenuse. |

cos | cos(“X”) “X”: A column of real numbers In a right triangle with angle between two sides ‘x’, cos(x) is the length of the adjacent side divided by the hypotenuse. |

tan | tan(“X”) “X”: A column of real numbers In a right triangle with angle between two sides ‘x’, tan(x) is the length of the opposite side divided by the adjacent side. |

asin | asin(“X”) “X”: A column of real numbers between -1 and 1 Arcsine function. asin(x) = the angle whose sine is x. |

acos | acos(“X”) “X”: A column of real numbers between -1 and 1 Arccosine function. acos(x) = the angle whose cosine is x. |

atan | atan(“X”) “X”: A column of real numbers Arctangent function. atan(x) = the angle whose tangent is x. The result will be between -pi/2 and pi/2. |

sinh | sinh(“X”) “X”: A column of real numbers Hyperbolic sine. |

cosh | cosh(“X”) “X”: A column of real numbers Hyperbolic cosine. |

tanh | tanh(“X”) “X”: A column of real numbers Hyperbolic tangent. |

Value | Value(n, “X”) n: Number of rows backwards (when n < 0) or forwards (n >0) in column “X” to extract a value from. “X”: Column from which to extract values . Create a new column from another column by extracting offset values. |

If data are imported from an experiment file, you may want to specify the independent column. For example, if the imported data included “time” in the first column but you wanted to calculate the derivative of pH with respect to volume, you have to define the derivative as derivative(“pH”,”Volume”).

]]>To try to remove some of the difficulties while still using the data analysis to develop model for electrostatic force interactions, I developed a simulation that allows a more direct “measurement” of charge, distance, and force.

Simulation 1: Using a Spring as a Measure of Force

Simulation 2: Direct Measurement of Force

This simulation is great to use in combination with my data analysis tool to analyze the relationship between distance, charge, and forces.

]]>We worked with a small sample group, but we had some promising results. Spreadsheets allowed students to solve more complex problems than can typically be solved in a first-year physics course. Spreadsheets freed students a bit to think about the problem rather than focusing on the computation, though learning to graph and write equations in excel was challenging.

You can find our complete report here.

]]>Athletic.net is a great resource for track athletes and coaches. It’s an excellent tool for posting times/distances and tracking athletes’ progress. Many meets I attend upload their meet results, and they appear automatically for my athletes. I can enter other meets manually.

For hosting a meet, which you *can* do for free (though becoming a site supporter was only $45/year and grants you access to many features unavailable to free users). I also considered using Direct Athletics to collect entries for the meet, but they charge 0.50 cents per athlete (when I asked if he meant 50 cents or half-a-cent, they guy just repeated that it costs 0.50 cents — I really don’t think he knows what that means). So, not wanting to engage in a big debate when I received a bill for $100 instead of $1, I went with Athletic.net. Coaches register at Athletic.net and submit entries to each event. Definitely beats what we’ve done in the past, which is to receive FAXES (um, it’s 2014, let’s move past the fax) of barely legible hand-written names for entries.

The majority of the visiting coaches don’t use athletic.net, so they all had to create (free) accounts. It does take some time once you create your account to be approved and assigned to your school, especially if there’s already a coach assigned to that team from previous years. So, those coaches that waited until the last minute ran into an obstacle there, but they were all able to submit entries fine. Having all the times and distances right there for seeding was excellent.

Once entries were in, I could just download them to my meet management software. They offer many different download formats, and it worked flawlessly. When the meet was over last night, I just exported the results from RaceTab and uploaded them to athletic.net. Now, the results are available online for anyone interested, and visiting coaches have them at their disposal. Now, when I go to register for my next meet, Athletic.net will use their best marks for their entries.

In the past, I’d just used an Excel spreadsheet to do results and scoring, which worked well. But, since athletic.net offers the RaceTab format to download entries, I thought I’d try it, since RaceTab is free to download and use. It was painless to import entries. Then, seeding heats and flights wasn’t bad, once I figured out what all the preferences and options meant. I was able to get a printout of events, heats, entries, etc. to coaches the morning of the meet so they could come ready with any errors or scratches.

During the meet, all timing was done by hand, so we manually entered results. With one computer, we were able to keep up (there were only 6 schools, so not a huge job). I recruited some of my students to help enter times and distances in the computer. I had to leave the press box to handle lots of other issues at the meet, but they managed to enter everything while I was gone with about 5 minutes of training. A couple lessons learned:

- On high jump or pole vault where ties were broken by number of missed attempts, you must enter places by hand – don’t click “Score” or it will change them back to a tie.
- When we had some athletes finish but we only timed the top 6 places, RaceTab was doing something weird by placing those “no-time” runners first… Still not sure why. But, if you left them blank it scratched them. Not sure how to enter that someone finished but wasn’t timed.
- My students weren’t terribly conscious of the difference between 1:55:33 and 1:55.33 (decimal instead of colon). Coaches’ entries also had this problem occasionally. I think possibly RaceTab or athletic.net should integrate some validation–there’s no way an 800m run would take almost 2 hours… However, I understand there are a huge number of events and variations therein with cross country, road races, 5Ks, 10Ks, indoor track, etc. that these programs are used for, so I guess for the time being we just have to be careful about how we input data.

RaceTab calculated team scores on-the-fly, so the minute the last event finished we had team scores and places ready to go. I exported a results report to send to our media outlets. And I was able to export a set of results to upload back into athletic.net.

Definitely a positive experience for me. Athletic.net removed many of the headaches of receiving entries and sending out results and performances. RaceTab, once entries were imported, made seeding quick and required minimal training for my volunteers to learn to use.

]]>- Agenda
- PPT Presentation slides 2013-12-12
- PPT Presentation – handouts (with notes)
- Standards.Summary – a
*very*abbreviated summary of the CCSS and NGSS standards

- A set of CTE tasks correlated with CCSS math standards: http://www.achieve.org/ccss-cte-classroom-tasks
- A sample Ag task: http://www.isbe.state.il.us/ils/career_develop/agriculture/math_8DH.pdf

- BIE.org – Freebies
- Source for rubrics, articles, guidance, and project ideas and resources

- Restaurant Project Video

http://www.achieve.org/CCSS-CTE-BridgingtheDivide

http://www.achieve.org/ccss-cte-workshop-planning-tools