Physics
by Charles Tanner: L6 Age ~17
Introduction
Charles has developed a most user-friendly educational program (now available as a web version to use online). Use the arrow keys then press RETURN to make your selections. Decide first whether to opt for a UVAXT or kinetic energy calculation, then enter the values of the known variables. We show below a screenshot of one of our test runs of the UVAXT procedure. We entered the values for U, A and T:

Input
and obtained the following expected output on pressing RETURN.

Output
Charles makes sophisticated use of enumerated types in this elegant program. You must try out its neat data entry! The source code is in physics.txt.
The Program
program Physics; { Copyright (c) 2011 Charles Tanner Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License, as described at http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/ } {$mode objfpc}{$H+} uses Classes, SysUtils, CRT, StrUtils, Math; var clear, exit, i, choice : integer; key : char; const Up_Key= 'H' ; Down_Key= 'P'; {I decided that for my program, 'readln's and 'read's wouldn't cut it, for multiple reasons. First, if you use one, it stops the code at that point and waits for an input from the user, meaning they couldn't see all of the fields after the one they are in. One way around that would be repeating the field at the bottom, but that wouldn't be intuitive and it would look messy. I could have used the GoTo function with 'read's but that would mean you would have to press enter to finish editing a field, which doesn't provide a seamless experience. My solution was to not use 'read's or 'readln's at all, and instead manually read the inputs, including the arrow keys, backspace and enter. This allowed me to make the viewing of the fields and editing of them one experience. You press the arrow keys to go between the options, and enter the numbers.} procedure UVAXT; type TVars = (p, u, v, a, x, t, q); var again : integer; value : array[u .. t] of string; empty : array[u .. t] of Boolean; z : Tvars; begin clrscr; exit := 0; z := u; //set to top line by default clear := 1; value[u] := ''; value[v] := ''; value[a] := ''; value[x] := ''; value[t] := ''; repeat if z = q then begin z := u; end; if z = p then begin //choice corresponds to selected line z := t; end; if clear = 1 then begin writeln('Please enter 3 values.'); if z = u then write('> ') //printing out fields else write(' '); write('Initial Velocity (m/s): '); writeln(value[u]); if z = v then write('> ') else write(' '); write('Final Velocity (m/s): '); writeln(value[v]); if z = a then write('> ') else write(' '); write('Acceleration (m/s^2): '); writeln(value[a]); if z = x then write('> ') else write(' '); write('Distance (m): '); writeln(value[x]); if z = t then write('> ') else write(' '); write('Time (s): '); writeln(value[t]); writeln('Press Esc to exit'); end; clear := 0; if keypressed then begin key := readkey; if keypressed then begin {reading second digit in keypress to read arrow keys (this method of reading arrow keys also works in DOS :D)} key := readkey; case key of Up_Key : begin dec(z); clear := 1; end; //going up and down Down_Key : begin inc(z); clear := 1; end; end; end else begin if key in ['0' .. '9', '.'] then value[z] := (value[z] + key); clear := 1; end; if key = char(8) then begin value[z] := LeftStr(value[z], (Length(value[z]) - 1)); clear := 1; end; if key = char(13) then begin //enter pressed, starting to calculate for z:= u to t do begin if value[z] = '' then empty[z] := true else empty[z] := false; end; //make unique value of i based on which fields are empty (a.k.a. flagging) i := 0; if empty[u] = false then i := i + 1; if empty[v] = false then i := i + 2; if empty[a] = false then i := i + 4; if empty[x] = false then i := i + 8 ; if empty[t] = false then i := i + 16; for z:= u to t do if value[z] = '0' then value[z] := '0.0000001'; case i of 7 : begin value[t] := floattostr((strtofloat(value[v]) - strtofloat(value[u])) / strtofloat(value[a])); //uva value[x] := floattostr((strtofloat(value[v]) + strtofloat(value[u])) * strtofloat(value[t]) / 2); end; 11 : begin value[t] := floattostr(2 * strtofloat(value[x]) / ((strtofloat(value[v]) + strtofloat(value[u])))); //uvx value[a] := floattostr((strtofloat(value[v]) - strtofloat(value[u])) / strtofloat(value[t])); end; 19 : begin value[x] := floattostr((strtofloat(value[v]) + strtofloat(value[u])) * strtofloat(value[t])/2); //uvt value[a] := floattostr((strtofloat(value[v]) - strtofloat(value[u])) / strtofloat(value[t])); //calculating other values end; 13 : begin value[v] := floattostr(sqrt(strtofloat(value[x]) * strtofloat(value[a]) + sqr(strtofloat(value[u])))); //uax value[t] := floattostr(2 * strtofloat(value[x]) / ((strtofloat(value[v]) + strtofloat(value[u])))); end; 21 : begin value[v] := floattostr(strtofloat(value[u]) + (strtofloat(value[a]) * strtofloat(value[t]))); //uat value[x] := floattostr((strtofloat(value[v]) + strtofloat(value[u])) * strtofloat(value[t]) / 2); end; 25 : begin value[v] := floattostr(strtofloat(value[x]) * 2 / strtofloat(value[t]) - strtofloat(value[u])); //uxt value[a] := floattostr((strtofloat(value[v]) - strtofloat(value[u])) / strtofloat(value[t])); end; 14 : begin value[u] := floattostr(sqrt(sqr(strtofloat(value[v])) - (strtofloat(value[x])) * (strtofloat(value[a])))); //vax value[t] := floattostr(2 * strtofloat(value[x]) / ((strtofloat(value[v]) + strtofloat(value[u])))); end; 22 : begin value[u] := floattostr(strtofloat(value[v]) - (strtofloat(value[a]) * strtofloat(value[t]))); //vat value[x] := floattostr((strtofloat(value[v]) + strtofloat(value[u])) * strtofloat(value[t]) / 2); end; 26 : begin value[u] := floattostr(((2 * strtofloat(value[x])) / strtofloat(value[t])) - strtofloat(value[v])); //vxt value[a] := floattostr((strtofloat(value[v]) - strtofloat(value[u])) / strtofloat(value[t])); end; 28 : begin value[u] := floattostr((strtofloat(value[x]) - (strtofloat(value[a]) * strtofloat(value[t]) * (strtofloat(value[t])) / 2)) / strtofloat(value[t])); //axt value[v] := floattostr(strtofloat(value[u]) + (strtofloat(value[a]) * strtofloat(value[t]))); end; 15 : value[t] := floattostr(2 * strtofloat(value[x]) / ((strtofloat(value[v]) + strtofloat(value[u])))); //uvax 23 : value[x] := floattostr((strtofloat(value[v]) + strtofloat(value[u])) * strtofloat(value[t]) / 2); //uvat 27 : value[a] := floattostr((strtofloat(value[v]) - strtofloat(value[u])) / strtofloat(value[t])); //uvxt For if 4 values are entered 29 : value[v] := floattostr(strtofloat(value[x]) * 2 / strtofloat(value[t]) - strtofloat(value[u])); //uaxt 30 : value[u] := floattostr(strtofloat(value[v]) - (strtofloat(value[a]) * strtofloat(value[t]))); //vaxt end; end; end; if key = char(27) then exit := 1; if clear = 1 then clrscr; until exit = 1; end; procedure KineticEnergy; type TVars = (ke, m, v); var value : array[ke .. v] of string; empty : array[ke .. v] of Boolean; begin clrscr; exit := 0; choice := 1; clear := 1; repeat if choice = 4 then choice := 1; //selecting field if choice = 0 then choice := 3; if clear = 1 then begin writeln('Please enter 2 values.'); if choice = 1 then write('> ') else write(' '); write('Kinetic Energy (J): '); writeln(value[ke]); if choice = 2 then write('> ') //printing fields else write(' '); write('Mass (kg): '); writeln(value[m]); if choice = 3 then write('> ') else write(' '); write('Velocity (m/s): '); writeln(value[v]); end; clear := 0; if keypressed then begin key := readkey; if keypressed then begin key := readkey; case key of Up_Key : begin dec(choice); clear := 1; end; //reading keypresses again Down_Key : begin inc(choice); clear:=1; end; end; end else case choice of 1 : begin if key in ['0' .. '9', '.'] then value[ke] := (value[ke] + key); clear := 1; end; 2 : begin if key in ['0' .. '9', '.'] then value[m] := (value[m] + key); clear := 1; //appending input to field end; 3 : begin if key in ['0' .. '9', '.'] then value[v] := (value[v] + key); clear:=1; end; end; if key = char(8) then begin case choice of 1 : begin value[ke] := LeftStr(value[ke], (Length(value[ke]) - 1)); clear := 1; end; 2 : begin value[m] := LeftStr(value[m], (Length(value[m]) - 1)); clear := 1; //backspacing end; 3 : begin value[v] := LeftStr(value[v], (Length(value[v]) - 1)); clear := 1; end; end; end; if key = char(13) then begin if value[ke] = '' then empty[ke] := true else empty[ke] := false; if value[v] = '' then empty[v] := true else empty[v] := false; if value[m] = '' then empty[m] := true else //calculating empty[m] := false; i := 0; if empty[ke] = true then i := i + 1; if empty[v] = true then i := i + 1; if empty[m] = true then i := i + 1; if i = 1 then begin if empty[ke] = true then begin value[ke] := floattostr(strtofloat(value[m]) * sqr(strtofloat(value[v])) / 2); empty[ke] := false; end; if empty[m] = true then begin value[m] := floattostr(2 * strtofloat(value[ke]) / sqr(strtofloat(value[v]))); end; if empty[v] = true then begin value[v] := floattostr(sqrt(2 * strtofloat(value[ke]) / strtofloat(value[m]))); end; end else begin clrscr; writeln('You must enter 2 values'); clear := 0; end; end; end; if key = char(27) then exit := 1; if clear = 1 then clrscr; until exit = 1; choice := 1; end; begin choice := 1; clear := 1; repeat if choice = 3 then choice := 1; if choice = 0 then choice := 2; if clear = 1 then begin clrscr; writeln('What do you want to do?'); writeln(); write('UVAXT equation'); if choice = 1 then writeln(' <') else writeln(); write('Energy'); if choice = 2 then writeln(' <') end; clear := 0; if keypressed then begin key := readkey; if keypressed then begin key := readkey; case key of Up_Key : begin dec(choice); clear := 1; //selecting line end; Down_Key : begin inc(choice); clear := 1; end; end; end; if (key = char(13)) then begin case choice of 1: UVAXT; 2: KineticEnergy; end; end; end; until 1 = 0; end.
Remarks
Can you modify the code to format the display of the values to two decimal places? Could you write a similar program to perform other calculations?