**[**Back to TUTOR SWAG index**]** **[**Back to Main SWAG index**]** **[**Original**]**

` Turbo `**Pascal for **DOS Tutorial
by Glenn Grotzinger
Part 7 -- Records usage **and **Mathematics Concepts **of **Computers
All parts copyright 1995 (c) by Glenn Grotzinger
Here **is **a solution **to **part 6...
*{$B+}
***program **part6;
**type
**ltrtype = **array**['A'..'Z'] **of **longint; *{type dec for arrays}
***var
**ltrstorage, sums: ltrtype; *{ hold array and sums array }
*filelist, counts: text;
filename: **string**;
filenums: integer;
ltrs: longint;
**procedure **countletters(str: **string**; **var **ltrstorage, sums: ltrtype);
**var
**i: integer; *{65..90}
*j: char;
**begin
for **i := 1 **to **length(str) **do ***{ for length of string }
***for **j := 'A' **to **'Z' **do ***{ for 26 letters }
***if **upcase(str[i]) = j **then
begin
**inc(ltrstorage[j]); *{var = var + 1 }
*inc(sums[j]);
ltrs := ltrs + 1;
**end**;
**end**;
**procedure **countfile(filename: **string**; **var **ltrstorage:ltrtype; **var
**filenums: integer);
**var
**cntfile: text;
chkstr: **string**;
**begin
**writeln('Processing ', filename);
filenums := filenums + 1;
assign(cntfile, filename);
reset(cntfile);
readln(cntfile, chkstr);
**while not **eof(cntfile) **do
begin
**countletters(chkstr, ltrstorage, sums);
readln(cntfile, chkstr);
**end**;
countletters(chkstr, ltrstorage, sums);
close(cntfile);
**end**;
**procedure **writefdata(filename: **string**; **var **ltrstorage: ltrtype);
**var
**i: integer;
j: char;
**begin
***{ write headers }
*writeln(counts, 'Alphabetical Count Data':53);
writeln(counts, 'for ':40, filename);
writeln(counts);
writeln(counts, 'Letter':10, 'Count':10, 'Letter':25, 'Count':10);
**for **i := 1 **to **13 **do
**writeln(counts, chr(i+64):8, ltrstorage[chr(i+64)]:12,
chr(i+77):23, ltrstorage[chr(i+77)]:12);
writeln(counts);
writeln(counts);
**for **j := 'A' **to **'Z' **do
**ltrstorage[j] := 0; *{ zero back out storage array }
***end**;
**procedure **doend(filenums: integer; ltrstorage: ltrtype);
**var
**i: integer;
j: char;
**begin
**writeln(counts, filenums, ' files processed.');
writeln(counts, ltrs, ' letters processed.');
writeln(counts);
writeln(counts);
writefdata('all files', sums);
**end**;
**begin
**assign(filelist, 'FILES.TXT');
reset(filelist);
assign(counts, 'FRNDDATA.TXT');
rewrite(counts);
readln(filelist, filename);
filenums := 0;
**while **(**not **eof(filelist)) **and **(filenums < 9) **do
begin
**countfile(filename, ltrstorage, filenums);
writefdata(filename, ltrstorage);
readln(filelist, filename);
**end**;
countfile(filename, ltrstorage, filenums);
writefdata(filename, ltrstorage);
doend(filenums, ltrstorage);
**if not **eof(filelist) **then
**writeln(counts, 'You gave me more than 10 files to process!');
close(filelist);
close(counts);
**end**.
**On with **the show....
Records Definition
==================
You can group up different types **of **data using records. We MUST
use the **type **statement pretty well **to **use this **record type**. Here **is **an
example **of **the defining **of **a **record type in **the **type **section.
**type
**employeerecord = **record
**number: longint;
surname: **string**[18];
firstname: **string**[10];
position: **string**[10];
yrsworked: integer;
**end**;
**As **you can see, we are grouping many different types **of **information into
one **record type**. **Then for **the **var **section, all we need **to do is **define
ONE variable **to **be **of type **employeerecord **and **we'll have the record variable.
Accessing Records **in **a **Program
**==============================
You can work **with **sections **of **a **record **variable, **or **the whole **record
**variable. The whole **record **variable can be accessed just by calling the
**record **variable used. The parts **of **it require the use **of **a . followed by
the name **of **the part **as **specified **in **the **type **statement. Also, the **WITH
**command may be used **to **simplify typing **in **working **with **a specific **record**.
The **WITH **command specifies a specific **record **variable **to **work **with**. An
example can be seen below.
**program **tutorial18;
**type
***{Employeerecord as above}
***var
**workrecord: employeerecord;
**begin
***{ get workrecord into memory here. }
*writeln(workrecord.number);
writeln(workrecord.surname);
writeln('I''m getting sick of typing workrecord all the time!');
**with **workrecord **do
**writeln(firstname);
writeln(position);
writeln(yrsworked);
**end**;
**end**.
Hopefully, you can see what exactly **is **going **on in **working **with **records.
**WITH **only reduces typing. It's good to use to reduce clutter if you do
a lot **with **one **type of record in **a section **of **code. Also, keep **in **mind
that **record **types can be used **in **an **array**....
**var
**workinfo: **array**[1..10] **of **employeerecord;
Each section **of **the **record **works just like ordinary variables, **and **are
addressable like ordinary variables. Also the whole **record **itself can
be addressable **and **moved around (written possibly **to **binary files?) **to
**other like records....The above **array **can be addressed like this:
3rd **record in array**, surname: workinfo[3].surname
Mathematics Concepts **in **Computers
=================================
Hopefully, you got the mathematics lesson from someone, **or **are already
familiar **with **conversion **of **number bases. **If not**, I will run through
a quick example...
Convert 10 (base 10) **to **base 2.
A base tells us how many numbers are used **in **counting. Typical numerical
usage **is **base 10 (we use the numbers 0-9 **in **that order -- we always start
from zero **in **counting. **To **look at this problem, we look at the right
**and **move **to **the left **with **regards **to **number bases. **To **use the example **of
**543 **in **base 10, it's 5X10^2+4X10^1+3X10^0. Remember, anything to the 0th
power **is **1. All number bases work this way. The exception **is **the changing
**of **the multiple. We use 10 **in **the example above. Using that background,
10 **in **base 10 **is **1X10^1+0x10^0. So, **if **we go through the process **of **actually
converting a base from base 10....
10 / 2 = 5 rem 0. (we keep going **until **the quotient **is **0. Right now it **is **5.)
5 / 2 = 2 rem 1.
2 / 2 = 1 rem 0.
1 / 2 = 0 rem 1. (We quit here. **Then **look at the remainders from down **to
**up **to **get our converted base).
1010 **is **10 **in **base 2....Now, **if **we want **to **go **to **base 10 from another number.
Convert 4A (base 16 **to **base 10).
Here, since we want **to **go **to **base 10, all we need **to do is **extend **out **the
base into something we can understand...
4 X 16 + A(10) X 1 = 64 + 10 = 74 (base 10)
What does all **of **this have **to do with **computers **in **programming. Let's
analyze a few things...
**If **you've seen $ and # and what do they mean?
---------------------------------------------
$ **is **a typical designator **in **computers that a number **is in **base 16. # **is
**a typical designator **in **computers that a number **is in **base 10. You
probably have seen it by now **in **the ASCII table studies we have done.
**For **example, Z **is **ASCII character $5A **and **#90. These are both one **in **the
same. **As **we see below:
5X16^1+A(10)X16^0 = 80 + 10 = 90 (base 10).
9x10^1+0x10^0 = 5x16^1+10(A)x16^0 (base 16). *{90/16 = 5 rem 10}
*How does my computer store data?
================================
Why **do **we bother **to **mess **with **the different number systems **in **computing?
base 10 **is **human-understandable, so we use it sometimes. Base 2 **is
**obvious, since this **is **how the computer talks. (hence BI-nary) All
computer storage **is **actually a series **of **1's and 0's **or ON**'s and OFF's.
(2 possible combinations, hence base 2). **For **example, lets convert #65 **to
**base 2 **and **see how our computers store an A. Let's start from the highest
we know we can **on **the power list **for **2's. There are 256 ASCII characters
because it was decided sometime **in **the computer stone age that there would be a
total **of **8 bits, the elementary **unit of **storage **in **a computer, per byte,
**or **next major **unit **that you all should be familar **with in **using DOS/
Windows/whatever. **If **we analyze that using a good permutation scheme..
2 possible orientations, 8 positions...2^8 **or **256 total combinations.
So, we will start from 7, since there **is **no byte #256. 128 goes into 65
0 times. 64 goes into 65 one time **with **1 left. 32 goes into 1 0 times.
16 goes into 1 0 times. 8 goes into 1 0 times. 4 goes into 1 0 times.
2 goes into 1 0 times. 1 goes into 1 one time. (stepping down powers **of
**2.). So typically **in **expressing a list **of **bits **for **a byte, we use 0's
**for **the filler **for **all 8 spaces, since we NEED **to **work **for **8 bits **with
**a respective byte. So an ASCII related system (there are others) would
represent #65 **as **0 1 0 0 0 0 0 1. 8 bits, all 0 **or **1. **If **your computer
deals **with **an A, it actually deals **with **the bit series 01000001.
**In **using a computer, we don't need to know about bits, since each
completely meaningful **unit to **most **of **us comprises 8 bits. We don't
need **to **normally think **of **01000001, the way the computer does it. But
**for **some things **in **programming, we **do**, though.
Base 16 **is **also used a lot. Reason? It's a real handy way to define
a byte. Let's look at the A. According to the ASCII table, A is $41.
16 = 2^4 so we can see it's a lot handier way to tag around the implied
bits **of **a byte **with **this... **If **we look at the bit sequence, a high **end
of **4 bits would have **to **be multiplied by 16. So **if **we look at the meaning
**of **0100 **and **0001, we will see why we use base 16... 0100 **is **4. 0001 **is **1.
Concenate them together, we get 41...Neat, eh?
We don't really have all that much concern for base 16 in this tutorial,
because **in pascal**, base 10 will work **as **well. we **do **need **to **be concerned
about base 2, though, because the computer **uses **it.
Reasons **for **knowing what this stuff **is**...
=========================================
We have reasons that we need **to **know how **to **convert between the number
bases, **and **be familar **with **what a bit **is**...You may be familiar **with **what
**is **called the high **and **low orders **of **a byte. **To **use the example **of **the A
bit series we converted earlier:
0 1 0 0 0 0 0 1
high order low order
There are **pascal **commands which use the bits **for **things. Also, some
fixed **file **formats use these (such **as **compression -- that's actually whats
going **on **-- it works at bit level **to **compress the number **of **bytes used) **and
if **you wish **to if **you ever develop something....) One must have an idea
**of **where the bits are coming from, hence all the stuff I was going through
before. **If **you read through your TP programmer's reference and see it
talking about orders **of **bytes **and **what goes **on with **those particular
commands, now, you should have the background **to **know about it **and **predict
what would happen **on **those commands.
First good commands **to **know about **for **working **with **bits
=======================================================
We always want **to **go **for **the most efficient code available. **If **we
ever need **to **work **with **multiplying **or **dividing powers **of **2, we can **do **it
much speedier **and **easier by having the computer **do **bit shifts instead **of
**doing an actual multiply **or **divide command when we are dealing **with **small
numbers. Shifting information around **is **much easier **for **the CPU than
actually doing the computation. Let us demonstrate.
00000010 (base 2) = 2 (base 10)
00000010 (shift 1 byte **to **the left) => 00000100 **or **4 (base 10)
00000010 (shift 1 byte **to **the right) => 00000001 **or **1 (base 10)
Going one way **or **the other **in **shifting bytes have the effect **of **multiplying
**or **dividing by 2^(# **of **bytes we move). Play **with **these commands **and **you
will see. It's a bit shift that it does, and is MUCH faster than an actual
divide when it comes **to **any power **of **2. Examples:
writeln(2 **shl **1); *{or 2 X 2^1}
*writeln(2 **shr **1); *{or 2 / 2^1}
*Those two commands work this way: <number> command <# **of **bits **to **shift>
# **of **bytes **to **shift turns **out to **be the power **of **2 we **do **the work **on**...
HI(byte) pulls the high order **of **the expression.
LO(byte) pulls the low order **of **the expression.
swap(byte) swaps the orders.
These are all functions.
Other Math Functions offered by **Pascal
**======================================
Abs(X) Takes **absolute **value **of **X.
Arctan(X) Takes arctangent **of **X.
Cos(X) Takes cosine **of **X.
Exp(X) Takes exponential (base e) **of **argument.
Frac(X) Returns fraction **of **X.
Int(X) Returns integer part **of **X.
Ln(x) Takes base e logarithm **of **X.
Pi Returns value **of **pi.
Round(X) Rounds X(real) **to **an integer.
sin(X) Takes sine **of **X.
sqr(x) Takes square **of **X.
sqrt(x) Takes square root **of **X.
trunc(x) Truncates X w/o rounding.
It **is **a good idea **to **learn basic trigonometry **and **analytical geometry **in
**programming. **For **example, I know from my studies that Tan(x) would be
1/Arctan(x) **or **sin(X) / cos(X). This stuff **is **good **to **know. The reasons?
Graphics. All one needs **to **draw anything, really, **is **a good spot placement
**procedure and **knowledge **of **trigonometry, **and **analytical geometry. Just
know **and **define a resolution **and then **start drawing knowing your knowledge.
**As **a test, **to **help **out**....How would one draw a circle given a central point
**and **radius? (Gotoxy **in **the CRT **or **WinCRT **unit **will be **of **use. It will
place the cursor at a specified position so you can write something.).
**If **anyone wants a text-based solution **on **this one **if **they can't figure
it **out**, e-mail ggrotz@2sprint.net. I will place one **in **the next part.
Other stuff that may prove useful
=================================
**In **your programming experience, you may have wondered **if **there **is **a way
**to **get a **string to **an integer, **or **an integer **to **a **string to do **things
**with **it? Well, there **is**. VAL **and **STR.
Val **is **used like this: Val(**string**, integer, errorinteger);
**string is **the **string **you want **to try and **convert **to **an integer.
integer **is **the integer that holds the successful conversion.
errorinteger **is **<> 0 when there **is **an error **in **conversion (always check
this before you move **on **after using a VAL!!!
Str **is **used like this: **string **:= str(integer);
**string is **the **string **you want **to **hold the conversion **in**...
integer **is **the integer that we want **to **convert...
Another good command **to **know **is **POS: integer := pos(substr, str);
It returns 0, **if **substr isn't there, but it returns a positive value
corresponding **to **the start **of **the substring **in **the **string**, **if **it's there.
**For **example, **if **we want **to **find the first use **of **the word AT **in **a **string**...
int := pos('AT', 'THAT');
int will be 3.
Conclusion
==========
I know all **of **this mathematics, **and **talk **of **bits **is **probably confusing.
**If **you don't understand it right now, don't worry about it **and **go back
at leisure **and **study it. It **is **the basic extent **of **mathematics behind
the actual operation **of **a computer **and **what we all **as **programmers need
**to **keep **in **the back **of **our minds **for **some things. You should know what
a bit **is**, an order **of **a byte **is**, **and **that there are 8 bits **in **a byte.
These things should help **out in **some matters. You should know the why
parts **of **these things **in **some cases...You should especially, though,
understand the parts about the commands **SHR**, **SHL**, HI, LO, **and **SWAP,
**and **the concepts **of **orders based **on **the storage **of **a byte, **as**, though
we will **not **see these **in **this part, we will undoubtedly see them some-
time before this tutorial **is **over, more than likely, even we may **not
**see them. But you may need **to **work at bit level **with **bytes sometime,
so this information **is **present here now **for **both the novices **and **the
experts that may see this. Also, converting the number bases **is **a
needed thing.
Practice Programming Problem #7
===============================
The concept **of **a **record is **relatively straight **forward**. So I
will **not try to **come up **with **a problem **for **basic usage **of **records.
But the concept **of **writing code **to do **some **of **the number conversions
**is not**. These functions can be very useful **for **later use **in **your
programming (save them after you write them!). Write a **function for
**your code **library **that will perform a base 10 **to **base X number
conversion (X being a variable we can define **in **the **function **header **to
**be an integer.) **on **an integer. Also write a **function **that will perform a
base x **to **a base 10 conversion. Inbed these two functions **in **a **program
**that will take a number from the keyboard (you can use whatever prompt
you deem **to **be the least confusing **as **possible) **and **a base **to **convert
the number **to**. Put **out **a prompt **as to **the answer **of **what the new base
number **of **the input **is**, **as **well **as **a restatement **of **the original number
inputted using a reverse conversion **of **base (Show us that both **of **the
functions work **and **are correct. **If **the 2nd computed statement DOES
**not **equal what **is **put **in**, there **is **an error.), **not **a direct reprint **of
**the input variable. **To **prove we are **not **writing **out **the original input
number that we placed **in **the keyboard, place a 0 **in **the keyboard input
variable after you perform the **function to **convert it **to **the user's
desired base.
Sample Output
-------------
Enter a number: 10
What base **do **you want **to **convert it **to**? 5
10 (base 10) **is **20 (base 5).
**To **check: 20 (base 5) **is **10 (base 10).
Notes:
1) You will have **to **build the converted number base **as **a **string**,
because any base beyond 10 **requires **the use **of **the alphabet **for **parts
**of **the number.
2) The best way I see **to **handle the "What **do **we use **for **the number
**in **the result?" question **is to **define a constant **string in **the **function
to **be something like '0123456789ABC...', **and **address a proper part
**of **the constant **string **when we build the converted number **for **conversion.
3) Remember we count from x^0 units **on **the right!!!!!
4) You will need **to **probably make the high **end **limit **to **be base 36.
5) Hint: the base x **to **base 10 **function **will need **to **input a **string
for **the input number **and **output a longint, **while **the base 10 **to **base
x **function **will need **to **input a longint **and **output a **string**.
6) A side note **for **usage. You can link these two **to **get from any base
**to **any base using base 10 **as **the intermediary.
Next Time
=========
We will cover the DOS **file function **commands **out of **TP. Hold **on to
**your newsreaders because part 8 (right now) **is **531 lines, **and **I'm not
through yet. This will be one **of **our special topics. **If **you **not
**familiar **with **the following concepts **in **DOS, look up **in **your DOS
manual **and try and **pick it up before next time: Read-only **file**,
hidden **file**, system **file**, volume **label**, command-line parameter, MD,
RD, delete (**or **erase), the use **of *** **and **? **as **wildcards. **As **always,
any comments, questions, gripes, etc, send them **to **ggrotz@2sprint.net.

**[**Back to TUTOR SWAG index**]** **[**Back to Main SWAG index**]** **[**Original**]**