In response to this post:
const filename = "text.txt"
' This declares and defines a variable called 'earliestdate' of INTEGER type.
' INTEGER datatypes are numbers capable of storing whole numbers from -32768 to
' 32767. Variables that are not declared before they are used (assigned to,
' passed to procedures, PRINTed, etc.) are implicitly declared to be of SINGLE
' type, which can store rational numbers as well as whole numbers. In general,
' it's good to explicitly declare variables and their data types (with DIM)
' rather than just relying on implicit declaration, since it gives you some
' place in the code to look at in case you need to verify the datatype of a
' variable. (Some people use so-called 'type-suffixes' which are symbols
' appended to the end of a variable name that determines its type, but that can
' introduce hard to track down bugs if you forget-to-append-the-symbol/append-
' the-wrong-symbol. Personally I think it makes the code look messy)
dim earliestdate as integer
print "Earliest date to include: " ;
' FREEFILE is a procedure in the QuickBASIC/QBasic runtime library that returns
' a valid file number (of INTEGER type) to use in other I/O procedures. This is
' also a good habit to get into since it provides a way to name the file
' numbers you use, rather than having a bunch of 'magic numbers' (numeric
' literals) floating around everywhere, that make changes to the code difficult.
dim filenum as integer : filenum = freefile
open filename for input as filenum
' Sums are grouped in 9 ranges stored in an array. An array is collection of
' one or more variables all of the same data type. These variable, or elements,
' are accessed via the '()' operator using an index, which is the position of
' the element in the array. Usually it is better to use an array rather than
' many separate variables when they each share a common kind of information to
' be stored - in this case, the total s for sums that fall in a range.
' index: 1 2 3 4 5 6 7 8 9
' sum range: [1-3][4-6][7-9][10-12][13-15][16-18][19-21][22-24][25+]
dim sums(1 to 9) as integer
' It's very important to create clear and helpful variable names too. The more
' descriptive your variable names are, the easier it will be to follow what the
' code is doing. Common sense should kick in about just how descriptive, but
' just remember that well written code will largely document itself and you
' will have less need for comments. BTW, it may help to use a different text
' editor than QB.EXE/QBASIC.EXE, one that supports syntax highlighting. I've
' pasted the code at copy-pasta.com so that all these rants will be colored
' for clarity - it really helps to have the colored text once you start working
' in it, not to mention you have your choice of Windows/Linux text editors so
' you're not stuck in the 25x80/50x80 text mode (I like lots of text on the
' screen and not having to scroll so often). I use Crimson Editor for most of
' my BASIC coding in Windows, gedit in Linux.
dim total as integer
dim sumcount as integer
' The low and high sums are separate variables because they provide a different
' kind of information than the elements in the array.
dim lowestsum as integer : lowestsum = 32767
dim highestsum as integer : highestsum = 0
dim currentsum as integer
' This will be used as an index into the sums array later on.
dim range as integer
' Assume we're reading the whole file..
do until eof(filenum)
' Indentation is good to clearly see the beginning and end of compound
' statements (like DO..LOOP, SELECT..END SELECT, procedure definitions,
' etc.). Code is hard to read in novel form. Whitespace is your friend.
input #filenum, currentdate, n1, n2, n3
' Only accept numbers from at least the earliest date. All of the summation
' and average calculations are inside this IF block, it would be nicer to
' have a CONTINUE DO, QB forces bad habits upon us..
if currentdate >= earliestdate then
' Notice that the sum is only calculated if indeed we accept the date.
' It's good to avoid doing unnecessary calculations whenever possible.
' As programs get more complex, this becomes more essential in creating
' clear and efficient code.
currentsum = n1 + n2 + n3
' Update lowest and highest sums..
if currentsum < lowestsum then lowestsum = currentsum
if currentsum > highestsum then highestsum = currentsum
' Update ranged sums..
if currentsum < 25 then
' For sums under 25, we can use the observation that each element in
' the sums array represents a range of 3 numbers. This is just a
' little math trick that gets the correct index into the array. It's
' good to notice when situations like this come up, it beats long IF
' or SELECT blocks.. get it in your head that code duplication is
' evil, and should be avoided at all costs !
range = int((currentsum + 2) / 3)
sums(range) = sums(range) + currentsum
sums(9) = sums(9) + currentsum
sumcount = sumcount + 1
total = total + currentsum
print "date / numbers / sum / running avg. sum: " ;
print using "### / ###-,###-,### / ### / ###.##" ; currentdate ; n1;n2;n3 ; currentsum ; (total / sumcount)
' Output the average sums. Notice how using an array and a little math has
' reduced the amount of code needed for this. More sum ranges can be added
' without duplicating more PRINT statements. BTW, I'm not really sure what
' information you intended to be outputting here..
for range = 1 to 8
dim upperlimit as integer : upperlimit = range * 3
dim lowerlimit as integer : lowerlimit = upperlimit - 2
print "Total sums from" ; lowerlimit ; "to" ; upperlimit ; ": " ;
print using "###.##" ; (sums(range) / sumcount)
print "Total sums from 25 and above: " ;
print using "###.##" ; (sums(range) / sumcount)
print "Lowest/highest sum: " ; lowestsum ; "/" ; highestsum
print "Average sum for all dates: " ; (total / sumcount)