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

Input

and obtained the following expected output on pressing RETURN.

Output

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?

Programming - a skill for life!

Student programs to inspire you!