Author Topic: Creating a Random File  (Read 4152 times)

0 Members and 1 Guest are viewing this topic.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Creating a Random File
« on: September 10, 2019, 12:53:26 pm »
I've been trying to create a Random File for 50 Events. Each event has 9 aspects to track. I'm not sure where I'm going wrong. In the following coding I am trying to write to Event #5 and Event #3 only. I'm then trying to retrieve and print to screen only some of the data from each of Event 5 and Event 3. What appears on the screen isn't what I thought was put into the records. Not sure exactly where I'm screwing up here.

  [ You are not allowed to view this attachment ]  
 

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Creating a Random File
« Reply #1 on: September 10, 2019, 01:40:10 pm »
Code: QB64: [Select]
  1. TYPE EventN
  2.     LastEvent AS SINGLE '4
  3.     TotEvent AS SINGLE '8
  4.     EventW AS SINGLE '12
  5.     EventV AS SINGLE '16
  6.     EventRP AS SINGLE '20
  7.     EventRPW AS SINGLE '24
  8.     EventRPV AS SINGLE '28
  9.     EventDec AS STRING * 7 '35
  10.     EventExp AS STRING * 15 '50
  11.  
  12. DIM SHARED EvRecord AS EventN
  13.  
  14. OPEN "EventRecords" FOR RANDOM AS #700 LEN = 50
  15.  
  16. EvRecord.LastEvent = 5 'Fill the UDT with all the data fields at once.
  17. EvRecord.TotEvent = 5
  18. EvRecord.EventW = 5
  19. EvRecord.EventV = 5
  20. EvRecord.EventRP = 5
  21. EvRecord.EventRPW = 5
  22. EvRecord.EventRPV = 5
  23. EvRecord.EventDec = "None"
  24. EvRecord.EventExp = "Value de minimis"
  25. PUT #700, 5, EvRecord 'Put the whole record into position #5
  26.  
  27. EvRecord.LastEvent = 3 'Fill the whole UDT with all the data fields at once.
  28. EvRecord.TotEvent = 3
  29. EvRecord.EventW = 3
  30. EvRecord.EventV = 3
  31. EvRecord.EventRP = 3
  32. EvRecord.EventRPW = 3
  33. EvRecord.EventRPV = 3
  34. EvRecord.EventDec = "Proceed"
  35. EvRecord.EventExp = "Confidence 80%"
  36. PUT #700, 3, EvRecord 'Put the whole record into position #3
  37. CLOSE 700
  38.  
  39. OPEN "EventRecords" FOR RANDOM AS #700 LEN = 50
  40. GET #700, 5, EvRecord
  41. LOCATE 5, 10: PRINT EvRecord.LastEvent
  42. LOCATE 10, 10: PRINT EvRecord.EventDec
  43. LOCATE 10, 30: PRINT EvRecord.EventExp
  44.  
  45. GET #700, 3, EvRecord
  46. LOCATE 15, 10: PRINT EvRecord.LastEvent
  47. LOCATE 20, 10: PRINT EvRecord.EventDec
  48. LOCATE 20, 30: PRINT EvRecord.EventExp
  49. CLOSE 700
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Creating a Random File
« Reply #2 on: September 10, 2019, 02:12:37 pm »
Thanks Steve - in your version of the Type statement there are remarked values of 4,8,12 ...50. What do these values mean.

I didn't realize 1 Put statement writes the entire record. Thanks again for the help.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Creating a Random File
« Reply #3 on: September 10, 2019, 04:06:07 pm »
I do see where each single is 4 bytes but the strings at '*7' and '*15' are a little confusing. The final remark = 50. I gather that's no coincidence that the Random File is to have 50 records. Is 50 records the same thing as 50 bytes?

OH, the light has struck - it's not numbers of records the LEN is calling for but the Length of EACH record.

Sometimes Steve I wonder why I read it over and over again and still don't see the forest for the trees.

Appreciate your patience

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Creating a Random File
« Reply #4 on: September 10, 2019, 04:32:26 pm »
I do see where each single is 4 bytes but the strings at '*7' and '*15' are a little confusing. The final remark = 50. I gather that's no coincidence that the Random File is to have 50 records. Is 50 records the same thing as 50 bytes?

OH, the light has struck - it's not numbers of records the LEN is calling for but the Length of EACH record.

Sometimes Steve I wonder why I read it over and over again and still don't see the forest for the trees.

Appreciate your patience

Anytime.  :)

You’re correct, the LEN is looking for the length of the records — which is why you need to have fixed length strings for your TYPE.  When looking at your previous code, it seemed as if you were expecting a 50 byte record, so I tried to decipher what was needed for your example records 3 and 5, so I guessed at the size 7 and 15 for the string’s limit. 

Usually, instead of hard coding a value, it’s often better to just set the record length with the LEN statement.

Open “my file.rnd” FOR RANDOM AS #1 LEN = LEN(ReferenceVariable)

(In this case, it’d be LEN = LEN(EvRecord).)

The main advantage to do it like so?

1) You don’t have to manually count the byte size of your records.
2) You can change the record type and not have to skip around in the code and change hard coded values later.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Creating a Random File
« Reply #5 on: September 10, 2019, 04:40:09 pm »
I see - so how then would a REDIM work?

Type EventN
  Redim LastEvent as Double
  Redim etc
  EventDec as string * 25
End Type

or Redim doesn't work with UDT's, would need to create and whole new Type?



Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Creating a Random File
« Reply #6 on: September 11, 2019, 09:11:26 am »
I see - so how then would a REDIM work?

Type EventN
  Redim LastEvent as Double
  Redim etc
  EventDec as string * 25
End Type

or Redim doesn't work with UDT's, would need to create and whole new Type?

REDIM works great for UDT's when you want a Dynamic array that can change it's size, say when you want to add more records to an array of records.

REDIM myEvents(1 to 20) as EventN  'and now you have 20 records ready to be filled with data or loaded from a file.

Use DIM myArray(1 to 20) 'a Static array, when you know for sure you don't have to change size of array, I think it's a bit faster processing things when it's Static. Now days not a big difference until you get into huge arrays.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Creating a Random File
« Reply #7 on: September 11, 2019, 09:27:20 am »
Thanks very much Mark. With Steve's help and yours I have much better understanding of the How To's for Random access files.
It's very, very much appreciated.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Creating a Random File
« Reply #8 on: September 11, 2019, 09:45:24 am »
Hi Dimster,

My quess is that you've not used UDT arrays yet? Brave New World!

To access the .LastEvent element in your 5th record:

Code: QB64: [Select]
  1. REDIM myArrayName(1 to 20) as  eventN
  2. ...
  3. LE5th = myArrayName(5).LastEvent

or to set 10th record .LastEvent element
Code: QB64: [Select]
  1. myArrayName(10).LastEvent = x!

or set all .LastEvent elements to 100
Code: QB64: [Select]
  1. FOR i = LBOUND(myArrayName) to UBOUND(myArrayName)
  2.    myArrayName(i).LastEvent = 100
   
« Last Edit: September 11, 2019, 09:48:42 am by bplus »

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Creating a Random File
« Reply #9 on: September 11, 2019, 04:27:25 pm »
You are partially correct. I know of them and have seen coding using them but I tended to avoid them like the plague. I have found for accuracy of data which undergoes multiple calculations and updates, the simpler I kept the arrays the better accuracy results. But now I find I'm at the point where I need to explore Random Access of the data and UDT's, as confusing as they are for me, are in fact that Brave New World (you nailed it).

I will go back over this forum's history and review everything about UDT's in QB64.

Thanks for info on working within the elements of a UDT array. It will be very handy.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Creating a Random File
« Reply #10 on: September 11, 2019, 04:50:34 pm »
A quick and simple Random Access File demo: 
Code: QB64: [Select]
  1. _TITLE "Random Access File Demo"
  2.  
  3. TYPE Person_Type 'a type to hold your records
  4.     FirstName AS STRING * 20
  5.     LastName AS STRING * 20
  6.     Phone AS _UNSIGNED _INTEGER64
  7.  
  8. DIM PhoneRecord AS Person_Type 'and a variable to reference that type
  9.  
  10. OPEN "Phone Database" FOR RANDOM AS #1 LEN = LEN(PhoneRecord) 'open file at the length of one of those records.
  11.  
  12.     CLS
  13.     RecordLimit = LOF(1) \ LEN(PhoneRecord) 'the number of records in your file.
  14.     PRINT "Record"; TAB(5); "Last Name"; TAB(30); "First Name"; TAB(55); "Phone Number"
  15.     FOR i = 1 TO RecordLimit
  16.         GET #1, i, PhoneRecord 'get the whole record
  17.         PRINT i; TAB(5); PhoneRecord.LastName; TAB(30); PhoneRecord.FirstName; TAB(55); PhoneRecord.Phone
  18.     NEXT
  19.     PRINT
  20.     PRINT "What to do: 1)Add a record"
  21.     PRINT "            2)Delete a record"
  22.     PRINT "            3)Edit a record"
  23.     PRINT "            4)QUIT"
  24.     DO
  25.         a = VAL(INPUT$(1))
  26.     LOOP UNTIL a > 0 AND a < 5
  27.     PRINT a
  28.     PRINT
  29.  
  30.     SELECT CASE a
  31.         CASE 1 'add a record
  32.             RecordLimit = RecordLimit + 1
  33.             PRINT "Adding Record #"; RecordLimit
  34.             INPUT "Enter Last Name:"; PhoneRecord.LastName
  35.             INPUT "Enter First Name:"; PhoneRecord.FirstName
  36.             INPUT "Enter Phone Number:"; PhoneRecord.Phone
  37.             PUT #1, RecordLimit, PhoneRecord
  38.         CASE 2 'delete a record
  39.             INPUT "Which record to delete?"; DeleteRecord
  40.             FOR i = DeleteRecord TO RecordLimit - 1 'shift all records from deletion point on back one spot
  41.                 GET #1, i + 1, PhoneRecord
  42.                 PUT #1, i, PhoneRecord
  43.             NEXT
  44.             CLOSE #1
  45.             a$ = SPACE$(LEN(PhoneRecord) * (RecordLimit - 1)) 'soace for all but the last record
  46.             OPEN "Phone Database" FOR BINARY AS #1
  47.             GET #1, 1, a$ 'get the whole database (minus the deleted record)
  48.             CLOSE #1
  49.             OPEN "Phone Database" FOR OUTPUT AS #1: CLOSE 'delete the old database
  50.             OPEN "Phone Database" FOR BINARY AS #1 'save the new database to the drive.
  51.             PUT #1, 1, a$
  52.             CLOSE #1
  53.             OPEN "Phone Database" FOR RANDOM AS #1 LEN = LEN(PhoneRecord) 'open file at the length of one of those records.
  54.         CASE 3 'edit a record
  55.             INPUT "Which Record to edit?"; editrecord
  56.             IF editrecord > 0 AND editrecord <= RecordLimit THEN
  57.                 PRINT "Editing Record #"; editrecord
  58.                 INPUT "Enter Last Name:"; PhoneRecord.LastName
  59.                 INPUT "Enter First Name:"; PhoneRecord.FirstName
  60.                 INPUT "Enter Phone Number:"; PhoneRecord.Phone
  61.                 PUT #1, editrecord, PhoneRecord
  62.             ELSE
  63.                 PRINT "Invalid record number."
  64.             END IF
  65.         CASE 4 'system
  66.     END SELECT
  67.  
  68.  
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Creating a Random File
« Reply #11 on: September 12, 2019, 10:43:20 am »
Steve - if we assume the person has more than 1 phone number. It would be the Type Person_Type that would handle this, correct? And if so is the change:

Phone (1 to 3) AS _UNSIGNED _INTEGER64

or

Phone1 AS _UNSIGNED _INTEGER64
Phone2 AS _UNSIGNED _INTEGER64
Phone3 AS _UNSIGNED _INTEGER64


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Creating a Random File
« Reply #12 on: September 12, 2019, 11:10:09 am »
Steve - if we assume the person has more than 1 phone number. It would be the Type Person_Type that would handle this, correct? And if so is the change:

Phone (1 to 3) AS _UNSIGNED _INTEGER64

or

Phone1 AS _UNSIGNED _INTEGER64
Phone2 AS _UNSIGNED _INTEGER64
Phone3 AS _UNSIGNED _INTEGER64



Hi Dimster,

I am not Steve but can answer your question now:

The first will not work as arrays can't be used in types. The 2nd will work.

There is a 3rd option, caution might be confusing but WTH might be clarifying?

You could setup another TYPE

Code: QB64: [Select]
  1. TYPE phonesType
  2.   Emergency AS _UNSIGNED _INTEGER64
  3.   AltEmergency AS _UNSIGNED _INTEGER64
  4.  
  5. 'and install this type in your Person_Type
  6. TYPE Person_Type 'a type to hold your records
  7.     FirstName AS STRING * 20
  8.     LastName AS STRING * 20
  9.     Phones AS phonesType
« Last Edit: September 12, 2019, 11:23:52 am by bplus »

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Creating a Random File
« Reply #13 on: September 12, 2019, 12:37:39 pm »
OH, a TYPE within a TYPE - clever Mark, clever