Data update
This commit is contained in:
parent
72eb4943cb
commit
4d5544505c
2347 changed files with 62432 additions and 16731 deletions
164
Task/Text-processing-2/ALGOL-68/text-processing-2.alg
Normal file
164
Task/Text-processing-2/ALGOL-68/text-processing-2.alg
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
BEGIN # Test processing/2 - using thee file from Text processing/1, #
|
||||
# verify the format, detect duplicate dates and #
|
||||
# count the number of records with all instruments #
|
||||
# functioning #
|
||||
|
||||
PR read "files.incl.a68" PR # include file utilities: EACHLINE, etc. #
|
||||
|
||||
CHAR tab = REPR 9;
|
||||
|
||||
INT instruments = 24; # expected number of instrument readings #
|
||||
MODE READING = STRUCT( STRING date
|
||||
, [ 1 : instruments ]REAL data
|
||||
, [ 1 : instruments ]INT status
|
||||
, BOOL format ok
|
||||
, STRING message
|
||||
);
|
||||
OP INIT = ( REF READING r )VOID:
|
||||
BEGIN
|
||||
FOR n TO instruments DO ( data OF r )[ n ] := ( status OF r )[ n ] := 0 OD;
|
||||
format ok OF r := TRUE;
|
||||
date OF r := "";
|
||||
message OF r := ""
|
||||
END # INIT # ;
|
||||
|
||||
INT all good count := 0; # number of lines which have all instruments ok #
|
||||
STRING last date := ""; # date of the previous line #
|
||||
|
||||
# return the date and instrument readings and status values on the line #
|
||||
PROC parse readings = ( STRING line )READING:
|
||||
BEGIN
|
||||
BOOL data error := FALSE;
|
||||
# returns v converted to a REAL, returns 0 and sets data error #
|
||||
# to TRUE if v is invalid #
|
||||
OP TOREAL = ( STRING v )REAL:
|
||||
BEGIN
|
||||
REAL value := 0;
|
||||
FILE real value;
|
||||
associate( real value, LOC STRING := v );
|
||||
on value error
|
||||
( real value
|
||||
, ( REF FILE ef )BOOL: # "handles" invalid data and #
|
||||
BEGIN # returns TRUE so processing #
|
||||
value := 0; # can continue #
|
||||
data error := TRUE
|
||||
END
|
||||
);
|
||||
get( real value, value );
|
||||
close( real value );
|
||||
value
|
||||
END # TOREAL # ;
|
||||
# returns v converted to an INT, returns 0 and sets data error #
|
||||
# to TRUE if v is invalid #
|
||||
OP TOINT = ( STRING text )INT:
|
||||
BEGIN
|
||||
INT value := 0;
|
||||
BOOL is numeric := TRUE;
|
||||
FOR ch pos FROM UPB text BY -1 TO LWB text WHILE is numeric DO
|
||||
CHAR c = text[ ch pos ];
|
||||
IF c = "-"
|
||||
THEN value := - value;
|
||||
is numeric := ch pos = LWB text AND ch pos /= UPB text
|
||||
ELSE is numeric := is numeric AND c >= "0" AND c <= "9";
|
||||
IF is numeric THEN ( value *:= 10 ) +:= ABS c - ABS "0" FI
|
||||
FI
|
||||
OD;
|
||||
IF NOT is numeric THEN data error := TRUE FI;
|
||||
value
|
||||
END # TOINT # ;
|
||||
# superficially checks v is in the format yyyy-mm-dd #
|
||||
PROC check date format = ( STRING v )BOOL:
|
||||
BEGIN
|
||||
STRING ymd := v[ AT 1 ];
|
||||
IF NOT ( data error := UPB ymd /= 10 ) THEN
|
||||
# length is correct for yyyy-mm-dd #
|
||||
IF NOT ( data error := ymd[ 5 ] /= "-" OR ymd[ 8 ] /= "-" ) THEN
|
||||
INT d;
|
||||
d := ( TOINT ymd[ 1 : 4 ] * 10000 )
|
||||
+ ( TOINT ymd[ 6 : 7 ] * 100 )
|
||||
+ TOINT ymd[ 9 : 10 ]
|
||||
FI
|
||||
FI;
|
||||
NOT data error
|
||||
END # check date format # ;
|
||||
|
||||
READING result; INIT result;
|
||||
INT c pos := LWB line;
|
||||
INT max pos = UPB line;
|
||||
INT field number := 0;
|
||||
WHILE c pos <= max pos DO
|
||||
# skip leading spaces and tabs #
|
||||
WHILE IF c pos > max pos
|
||||
THEN FALSE
|
||||
ELSE CHAR ch = line[ c pos ]; ch = " " OR ch = tab
|
||||
FI
|
||||
DO c pos +:= 1 OD;
|
||||
IF c pos <= max pos THEN # have a field #
|
||||
INT start pos = c pos;
|
||||
WHILE IF c pos > max pos
|
||||
THEN FALSE
|
||||
ELSE CHAR ch := line[ c pos ]; ch /= " " AND ch /= tab
|
||||
FI
|
||||
DO c pos +:= 1 OD;
|
||||
STRING f := line[ start pos : c pos - 1 ];
|
||||
IF ( field number +:= 1 ) = 1 THEN # the date #
|
||||
IF NOT check date format( f ) THEN
|
||||
format ok OF result := FALSE;
|
||||
message OF result := "Invalid date: " + f
|
||||
FI;
|
||||
date OF result := f
|
||||
ELIF INT instrument = field number OVER 2;
|
||||
instrument > instruments THEN
|
||||
format ok OF result := FALSE; # too many readings #
|
||||
message OF result := "Too many instruments"
|
||||
ELIF ODD field number THEN
|
||||
# field 3, 5, 7... the instrument state of reading #
|
||||
( status OF result )[ field number OVER 2 ] := TOINT f;
|
||||
IF data error THEN
|
||||
format ok OF result := FALSE;
|
||||
message OF result := "Invalid status for instrument " + whole( instrument, 0 )
|
||||
FI
|
||||
ELSE # must be the instrument reading #
|
||||
( data OF result )[ field number OVER 2 ] := TOREAL f;
|
||||
IF data error THEN
|
||||
format ok OF result := FALSE;
|
||||
message OF result := "Invalid reading for instrument " + whole( instrument, 0 )
|
||||
FI
|
||||
FI
|
||||
FI
|
||||
OD;
|
||||
IF format ok OF result AND field number /= 2 * instruments + 1 THEN
|
||||
format ok OF result := FALSE;
|
||||
message OF result := "Incorrect number of readings/status values"
|
||||
FI;
|
||||
result
|
||||
END # parse readings # ;
|
||||
|
||||
# checks the readings and date on line #
|
||||
PROC check readings = ( STRING line, INT line count )BOOL:
|
||||
BEGIN
|
||||
READING data := parse readings( line );
|
||||
IF format ok OF data AND line count > 1 AND date OF data = last date THEN
|
||||
format ok OF data := FALSE;
|
||||
message OF data := "Duplicate date: " + date OF data
|
||||
FI;
|
||||
IF NOT format ok OF data THEN # line has invalid data #
|
||||
print( ( "Line: ", whole( line count, 0 ), ": ", message OF data, newline ) )
|
||||
ELSE # the line appears ok #
|
||||
BOOL all good := TRUE;
|
||||
FOR i TO instruments WHILE all good := ( status OF data )[ i ] > 0 DO SKIP OD;
|
||||
IF all good THEN all good count +:= 1 FI;
|
||||
last date := date OF data
|
||||
FI;
|
||||
TRUE
|
||||
END # check readings # ;
|
||||
|
||||
IF STRING file name = "readings.txt";
|
||||
INT total lines = file name EACHLINE check readings;
|
||||
total lines < 0
|
||||
THEN print( ( "Unable to open ", file name, newline ) )
|
||||
ELSE print( ( whole( total lines, 0 ), " lines in ", file name, ", " ) );
|
||||
print( ( whole( all good count, 0 ), " have all instruments in a good state.", newline ) )
|
||||
FI
|
||||
|
||||
END
|
||||
128
Task/Text-processing-2/FreeBASIC/text-processing-2.basic
Normal file
128
Task/Text-processing-2/FreeBASIC/text-processing-2.basic
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include "datetime.bi"
|
||||
|
||||
Const filename = "readings.txt"
|
||||
Const readings = 24 ' per line
|
||||
Const fields = readings*2 + 1 ' per line
|
||||
Const dateFormat = "%Y-%m-%d"
|
||||
|
||||
Type DateRecord
|
||||
fecha As String
|
||||
hasGoodRecord As Boolean
|
||||
End Type
|
||||
|
||||
' Array to store unique dates
|
||||
Dim Shared As DateRecord dateRecords(Any)
|
||||
|
||||
' Function to check if a fecha exists in our array
|
||||
Function findDate(dateArray() As DateRecord, dateStr As String, count As Integer) As Integer
|
||||
For i As Integer = 0 To count - 1
|
||||
If dateArray(i).fecha = dateStr Then Return i
|
||||
Next
|
||||
Return -1
|
||||
End Function
|
||||
|
||||
Sub main()
|
||||
Dim As Integer ff, flag, dateIndex, i, partCount
|
||||
Dim As Integer allGood = 0, uniqueGood = 0, dateCount = 0
|
||||
Dim As String linea, dateStr, currentPart, c
|
||||
Dim As Double value
|
||||
Dim As Boolean good
|
||||
|
||||
|
||||
ff = Freefile
|
||||
If Open(filename For Input As #ff) <> 0 Then
|
||||
Print "Error: Could not open file '" & filename & "'"
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' Process each line
|
||||
While Not Eof(ff)
|
||||
Line Input #ff, linea
|
||||
|
||||
' Split the line into fields
|
||||
Dim As String parts(0 To fields-1)
|
||||
partCount = 0
|
||||
currentPart = ""
|
||||
|
||||
' Optimized string parsing
|
||||
For i = 1 To Len(linea)
|
||||
c = Mid(linea, i, 1)
|
||||
If c = " " Or c = Chr(9) Then ' Space or Tab
|
||||
If Len(currentPart) > 0 Then
|
||||
parts(partCount) = currentPart
|
||||
partCount += 1
|
||||
currentPart = ""
|
||||
End If
|
||||
Else
|
||||
currentPart &= c
|
||||
End If
|
||||
Next
|
||||
|
||||
' Add the last part if it exists
|
||||
If Len(currentPart) > 0 Then
|
||||
parts(partCount) = currentPart
|
||||
partCount += 1
|
||||
End If
|
||||
|
||||
' Check if we have the expected number of fields
|
||||
If partCount <> fields Then
|
||||
Print "Error: Unexpected format, " & partCount & " fields."
|
||||
Close #ff
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' Get the date
|
||||
dateStr = parts(0)
|
||||
|
||||
' Check if all readings are good
|
||||
good = True
|
||||
For i = 1 To fields-1 Step 2
|
||||
flag = Val(parts(i+1))
|
||||
If flag > 0 Then
|
||||
value = Val(parts(i))
|
||||
If value = 0 And parts(i) <> "0" And parts(i) <> "0.000" Then
|
||||
Print "Error: Could not convert '" & parts(i) & "' to integer."
|
||||
Close #ff
|
||||
Exit Sub
|
||||
End If
|
||||
Else
|
||||
good = False
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
|
||||
If good Then allGood += 1
|
||||
|
||||
dateIndex = findDate(dateRecords(), dateStr, dateCount)
|
||||
|
||||
If dateIndex >= 0 Then
|
||||
Print "Duplicate datestamp: " & dateStr
|
||||
If good And Not dateRecords(dateIndex).hasGoodRecord Then
|
||||
dateRecords(dateIndex).hasGoodRecord = True
|
||||
uniqueGood += 1
|
||||
End If
|
||||
Else
|
||||
' New date
|
||||
If dateCount > Ubound(dateRecords) Then
|
||||
Redim Preserve dateRecords(Ubound(dateRecords) + 100)
|
||||
End If
|
||||
|
||||
dateRecords(dateCount).fecha = dateStr
|
||||
dateRecords(dateCount).hasGoodRecord = good
|
||||
|
||||
If good Then uniqueGood += 1
|
||||
|
||||
dateCount += 1
|
||||
End If
|
||||
Wend
|
||||
|
||||
Close #ff
|
||||
|
||||
Print !"\nData format valid."
|
||||
Print allGood & " records with good readings for all instruments."
|
||||
Print uniqueGood & " unique dates with good readings for all instruments."
|
||||
End Sub
|
||||
|
||||
main()
|
||||
|
||||
Sleep
|
||||
|
|
@ -5,10 +5,7 @@ dates = {}
|
|||
duplicated, bad_format = {}, {}
|
||||
num_good_records, lines_total = 0, 0
|
||||
|
||||
while true do
|
||||
line = io.read( "*line" )
|
||||
if line == nil then break end
|
||||
|
||||
for line in io.lines() do
|
||||
lines_total = lines_total + 1
|
||||
|
||||
date = string.match( line, "%d+%-%d+%-%d+" )
|
||||
|
|
|
|||
42
Task/Text-processing-2/XPL0/text-processing-2.xpl0
Normal file
42
Task/Text-processing-2/XPL0/text-processing-2.xpl0
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
include xpllib; \for Print, StrCmp and StrCopy
|
||||
|
||||
int Records, Invalid, AllGood;
|
||||
char File_name, C, Date(10+1), LastDate(10+1);
|
||||
int N, Flag, Count;
|
||||
real Data;
|
||||
|
||||
[File_name:= "readings.txt";
|
||||
Print("File = %s\n", File_name);
|
||||
Print("\nDuplicated dates:\n");
|
||||
FSet(FOpen(File_name, 0), ^i); OpenI(3);
|
||||
|
||||
Records:= 0; Invalid:= 0; AllGood:= 0;
|
||||
LastDate(0):= 0;
|
||||
loop
|
||||
[for N:= 0 to 10-1 do
|
||||
[C:= ChIn(3);
|
||||
if C = LF then C:= ChIn(3);
|
||||
if C = EOF then quit;
|
||||
Date(N):= C;
|
||||
];
|
||||
Date(N):= 0;
|
||||
if Date(0)#^1 and Date(0)#^2 then Invalid:= Invalid+1;
|
||||
if StrCmp(Date, LastDate) = 0 then
|
||||
Print("%s\n", Date);
|
||||
StrCopy(LastDate, Date);
|
||||
Records:= Records+1;
|
||||
|
||||
Count:= 0;
|
||||
for N:= 0 to 24-1 do
|
||||
[Data:= RlIn(3);
|
||||
Flag:= IntIn(3);
|
||||
if Flag > 0 then
|
||||
Count:= Count+1;
|
||||
];
|
||||
if Count = 24 then AllGood:= AllGood+1;
|
||||
];
|
||||
Print("\nTotal number of records : %d\n", Records);
|
||||
Print("Number of invalid records : %d\n", Invalid);
|
||||
Print("Number which are all good : %d (%1.2f^%)\n",
|
||||
AllGood, float(AllGood)/float(Records)*100.0);
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue