|
Post by johnk1ese on May 6, 2023 6:51:02 GMT -5
I am a ham radio operator. I am trying to extract a list of radio club member callsigns from a list of radio contacts.
The list of club members is about 500 and in this ascii format: G2HKU
G8VG
SM5CCE
LA5HE
G3JUL
The list of contacts is in this ascii format:
QSO: 7021 CW 2023-02-04 0014 K1ESE 599 2079 DK9PY 599 2126
QSO: 7022 CW 2023-02-04 0014 K1ESE 599 2079 OM2VL 599 2162
QSO: 7023 CW 2023-02-04 0015 K1ESE 599 2079 KU8E 599 1870
QSO: 7022 CW 2023-02-04 0016 K1ESE 599 2079 WB0SND 599 2146
QSO: 7023 CW 2023-02-04 0016 K1ESE 599 2079 OK1CF 599 1729
QSO: 7023 CW 2023-02-04 0017 K1ESE 599 2079 K4XU 599 1268
QSO: 7024 CW 2023-02-04 0018 K1ESE 599 2079 K8MFO 599 1186
QSO: 7025 CW 2023-02-04 0019 K1ESE 599 2079 K4QS 599 2125 The callsign of the station contacted is after "2079" in each line. I can also strip the contacts file of all but the callsigns if that would make it easier.
Not being very accomplished at writing code, my first inclination is to
open the club member list file, input the first callsign, open the contacts list file, line input the first record, use instring to see if the member's callsign is there if so, add the callsign to "contacted.txt" if not, go to the next line until at the end of the file close the contacts list file input the second callsign from the member's list continue until the member's list is done close the member's list file
There must be a better way.
Thanks, John K1ESE
|
|
|
Post by Rod on May 6, 2023 9:37:33 GMT -5
There are eleven words in you contacts list, the contact is the 9th word$(
That’s the easiest way to get the contact.
But I think you need to sort everything first. So get the club list onto an array and sort it so that the contact names are in order.
Get the contacts into a multi dimensional array then sort on the 9th array column.
Now do your comparison, get the first contact, go down the list of contacts till you have exhausted that contact name and move onto the next contact.
What happens about duplicates? So what is an example of the output you want to see.
|
|
|
Post by Walt Decker on May 6, 2023 10:12:18 GMT -5
' DIM Members$(1000) DIM NewMembers$(500)
I = 0
MemberCount = -1 OPEN "MemberList" FOR INPUT AS #1 '<--- this file is the contacts list WHILE EOF(#1) = 0 MemberCount = MemberCount + 1 LINE INPUT #1, Members$(MemberCount) WEND CLOSE #1
NewCount = -1 OPEN "Contacts" FOR OUTPUT AS #2 '<--- this file is the contact call sign WHILE EOF(#1) = 0 LINE INPUT #1, Contacts$ Found = INSTR(Contacts$, "2079 " '<--- find the magic number IF Found THEN Contacts$ = MID$(Contacts$, Found + 5) '<--- extract everything following magic number Contacts$ = WORD$(Contacts$, 1) '<--- extract call sign FOR I = 0 TO MemberCount '<--- check if contact is in member list IF Contacts$ = Members$(I) THEN GOTO [INCR.I] NewCount = NewCount + 1 NewMembers$(NewCount) = Contacts$ [INCR.I] NEXT I END IF WEND CLOSE #1
OPEN "MemberList" FOR APPEND AS #1 '<--- store new members at end of list FOR I = 0 TO NewCount PRINT #1, NewMembers$(I) NEXT I CLOSE #1 '
You might want to open the member list, check for duplicates, and remove any found.
|
|
|
Post by meerkat on May 6, 2023 11:07:28 GMT -5
just another possible way using in memory database.
' ----- create in memory DB with contact table and callSign Field sqliteconnect #sql, ":memory:" sql$ = "CREATE TABLE contact(callSign)" ' Make a contact table with callSign #sql execute(sql$)
OPEN "contactList" FOR INPUT AS #f ' Open your contact list WHILE EOF(#f) = 0 LINE INPUT #f, a$ if trim$(a$) <> "" then a1$ = mid$(a$,INSTR(a$,"2079") + 5) ' hold everything after 2079 sql$ = "INSERT OR REPLACE INTO contact VALUES('";a1$;"')" 'Replace will not allow duplicates #sql execute(sql$) end if WEND ' list in callSign sequence sql$ = "SELECT callSign FROM contact ORDER BY callSign" 'sort in callSign Seq #sql execute(sql$) numContacts = #sql ROWCOUNT() ' how many Contacts WHILE #sql hasanswer() #row = #sql #nextrow() callSign$ = #row callSign$() print callSign$ WEND end
** EDIT ** If you need to keep track of duplicates there are several ways. Probably the easiest is to insert duplicates into the database and then group them with a count
' ----- create in memory DB with contact table and callSign Field sqliteconnect #sql, ":memory:" #sql execute("CREATE TABLE contact(callSign)") ' Make a contact table with callSign
OPEN "contactList" FOR INPUT AS #f ' Open your contact list WHILE EOF(#f) = 0 LINE INPUT #f, a$ if trim$(a$) <> "" then a1$ = mid$(a$,INSTR(a$,"2079") + 5) ' hold everything after 2079 sql$ = "INSERT INTO contact VALUES('";a1$;"')" 'will allow duplicates #sql execute(sql$) end if WEND ' list in callSign sequence sql$ = "SELECT callSign,count(*) as callCount FROM contact GROUP BY callSign ORDER BY callSign" 'sort in callSign Seq #sql execute(sql$) numContacts = #sql ROWCOUNT() ' how many Contacts WHILE #sql hasanswer() #row = #sql #nextrow() callSign$ = #row callSign$() callCount = #row callCount() print callSign$,callCount WEND ' ---- show only duplicates sql$ = "SELECT callSign,count(*) as callCount FROM contact WHERE count(*) > 1 GROUP BY callSign ORDER BY callSign" 'only duplicates sorted by callSign #sql execute(sql$) numContacts = #sql ROWCOUNT() ' how many Contacts WHILE #sql hasanswer() #row = #sql #nextrow() callSign$ = #row callSign$() callCount = #row callCount() print callSign$,callCount WEND ' ---- show most to least duplicates with each sequence sorted by callSign sql$ = "SELECT callSign,count(*) as callCount FROM contact WHERE count(*) > 1 GROUP BY callSign ORDER BY count(*) desc,callSign" 'sort count and callSign #sql execute(sql$) numContacts = #sql ROWCOUNT() ' how many Contacts WHILE #sql hasanswer() #row = #sql #nextrow() callSign$ = #row callSign$() callCount = #row callCount() print callSign$,callCount WEND
end
|
|
|
Post by Walt Decker on May 6, 2023 11:16:51 GMT -5
ALTERNATE METHOD (NOT TESTED)
This method adds the contact to the member list so that if there are duplicate contacts in the contact list the duplicate will not be added to the member list.
'
DIM Members$(1000)
Contacts$ = "" Extract$ = ""
MemberCount = -1 Found = 0 NotFound = 0 I = 0
OPEN "MemberList" FOR INPUT AS #1 WHILE EOF(#1) = 0 MemberCount = MemberCount + 1 LINE INPUT #1, Members$(MemberCount) WEND CLOSE #1
NumBytes = 0 OPEN "ContactList" FOR BINARY AS #2 NumBytes = LOF(#2) Contacts$ = INPUT$(#2, NumBytes) '<--- put the contact list in 1 string CLOSE #2
[CHECK.CONTACT] NotFound = 0 FOR I = 0 TO MemberCount Found = INSTR(Contacts$, Members$(I)) '<--- check for member in contact list
IF Found THEN GOTO [INCR.I] <--- find next member in contact list
Spc = INSTR(Contacts$, " ", Found) '<--- find 1st space after call sign Extract$ = MID$(Contacts$, Found, Spc - Found) '<--- extract call sign MemberCount = MemberCount + 1 Members$(MemberCount) = Extract$ '<--- add call sign to member list Extract$ = LEFT$(Contacts$, Found - 1) '<--- these 3 lines reconfigure contact list Contacts$ = MID$(Contacts$, Spc + 1) Contacts$ = Extract$ + Contacts$ NotFound = I '<--- the contact is now in member list EXIT FOR
[INCR.I] NEXT I
IF NotFound THEN GOTO [CHECK.CONTACT]
OPEN "MemberList" FOR OUTPUT AS #1 FOR I = 1 TO MemberCount PRINT #1, Members$(I) NEXT I
CLOSE #1 '
|
|
|
Post by johnk1ese on May 6, 2023 13:18:45 GMT -5
Thanks to all for the suggestions, code, and help. This Forum is why I stick with Liberty Basic.
Walt, your alternate method is the closest to what I want. It is also within my comfort zone. The other methods may be better but I lack the background or understanding to feel comfortable using them.
I don't need duplicates, just a list of unique members I have contacted. On Monday I will have real data to process and will try your code.
Many thanks to all.
73 de K1ESE John
|
|
|
Post by Walt Decker on May 6, 2023 16:00:50 GMT -5
For your record of contacts, do you require the contact info from the end of QSO: up to your call sign?
PS: My son is an operator in New Hampshire and records that information.
|
|
|
Post by Brandon Parker on May 6, 2023 17:49:54 GMT -5
Here is yet another way of doing what I think the OP wants to do. I was trying to get this posted shortly after the OP posted, but my 3 1/2 year old had other plans... I tested this with & without extra blank lines in the hamList file... Global CRLF$ : CRLF$ = chr$(13);chr$(10)
hamListFilePath$ = "Ham List File Path Here" contactListFilePath$ = "Contact List File Path Here"
Open "C:\Users\nukes\OneDrive\Desktop\HamTest.txt" For Input As #HamInfo hamList$ = Input$(#HamInfo, LOF(#HamInfo)) Close #HamInfo
Open "C:\Users\nukes\OneDrive\Desktop\HamContactedListTest.txt" For Input As #HamContacted hamContactedList$ = Input$(#HamContacted, LOF(#HamContacted)) Print "Here is our list of contacted operators:";CRLF$;Trim$(hamContactedList$) Close #HamContacted
Print
i = 2 hamID$ = UpTo$(Word$(hamList$, i, "2079 "), " ") While (hamID$ <> "") If (hamID$ <> "") Then If Instr(hamContactedList$, hamID$) Then Print hamID$;" is already in our list of contacts!" Else hamContactedList$ = (hamID$ + CRLF$ + hamContactedList$) Print "Adding ";hamID$;" to our list of contacts!" End If End If i = (i + 1) hamID$ = UpTo$(Word$(hamList$, i, "2079 "), " ") Wend
Print Print "Here is our new list of contacted operators:";CRLF$;Trim$(hamContactedList$)
Open "C:\Users\nukes\OneDrive\Desktop\HamContactedListTest.txt" For Output As #HamContacted #HamContacted Trim$(hamContactedList$) Close #HamContacted {:0) Brandon Parker
|
|
|
Post by Walt Decker on May 6, 2023 21:09:11 GMT -5
I goofed. I have it basakwards. Should be looking for contacts in the member list instead of members in the contact list; therefore it should be: ' DIM Contacts$(100) NumContacts = -1 NumBytes = 0 Spc = 0 I = 0 M = 0
Members$ = "" NewContact$ = "" Magic$ = "2079 " CallSign$ = ""
CR$ = CHR$(10) + CHR$(13)
OPEN "MemberList" FOR BINARY AS #1 NumBytes = LOF(#1) '<--- get size of file in characters (bytes) Members$ = INPUT$(#1, NumBytes) '<--- put member list in 1 string for searching CLOSE #1
OPEN "ContactList" FOR INPUT AS #2 '<--- get contact list WHILE EOF(#2) = 0 '<--- put contacts in array NumContacts = NumContacts + 1 LINE INPUT #1, Contacts$(NumContacts) WEND CLOSE #2
FOR I = 0 TO NumContacts M = INSTR(Contacts$(I), Magic$) '<--- find magic number M = M + 5 '<--- put string pointer at first chr of call sign Spc = INSTR(Contacts$(I), " ", M) '<--- find space after call sign CallSign$ = MID$(Contacts$(I), Spc - M) '<--- extract call sign Found = INSTR(Members$, CallSign$) '<--- check call sign against member call signs IF Found THEN GOTO [INCR.I] '<--- if call sign found then increment loop NewContact$ = NewContact$ + CallSign$ + CRLF$ '<--- add to new contact list
'<============================== OR =================================>
NewContact$ = NewContact$ + Contacts$(I) + CRLF$
[INCR.I] NEXT I
OPEN "NewContactList" FOR BINARY AS #1 PRINT NewContact$ CLOSE #1 '
|
|
|
Post by Brandon Parker on May 7, 2023 8:40:00 GMT -5
Here is a version that I mocked up with how I thought the OP wanted things. Here is the Ham ID List; save as the file pointed to by hamListFilePath$: Here is the Ham ID Contacted List; save as the file pointed to by contactListFilePath$: Here is the example program. You can double-click on an item in the Member Ham IDs ListBox or click the right arrow button to move it to the Contacted Ham IDs ListBox. Double-clicking on an item in the Contacted Ham IDs ListBox or clicking the left arrow button removes the item from the Contacted Ham IDs ListBox. The Contacted Ham IDs array is updated accordingly during the operations. The Member Ham IDs ListBox and array are never altered during program execution. The user can choose to save the Contacted Ham ID information to file by clicking the Save Contacts button and the program will automatically save the Contacted Ham ID information to file when the window is closed. I am certain there are areas of improvement and error-checking, but this is a start for what I think the OP actually wants to do. Given the example below, it would not be difficult at all to incorporate information into the Contacted Ham Member ID save file to track when the member was first contacted and last contacted. If this is used and that feature would be helpful I can update the code and post it for the OP. NoMainWin WindowWidth = 360 WindowHeight = 335
Global hamListUBound, hamContactedListUBound Global CRLF$ : CRLF$ = chr$(13);chr$(10) Global False : False = 0 Global True : True = 1
Global hamListFilePath$ : hamListFilePath$ = "Ham List File Path Here" Global contactListFilePath$ : contactListFilePath$ = "Contact List File Path Here"
Open hamListFilePath$ For Input As #HamInfo hamList$ = Input$(#HamInfo, LOF(#HamInfo)) Close #HamInfo hamListUBound = (CountSubstring(hamList$, CRLF$, 1, 0) - 1) Dim hamList$(hamListUBound) Call initializeHamIDArray hamList$
Open contactListFilePath$ For Input As #HamContacted hamContactedList$ = Input$(#HamContacted, LOF(#HamContacted)) Close #HamContacted hamContactedListUBound = (CountSubstring(hamContactedList$, CRLF$, 1, 0) - 1) Dim contactedHamIDs$(hamContactedListUBound) Call initializeContactedHamIDArray hamContactedList$
StaticText #HamIDTracker.hamIDs, "Member Ham IDs", 30, 5, 150, 20 StaticText #HamIDTracker.contactedHamIDs, "Contacted Ham IDs", 225, 5, 150, 20 ListBox #HamIDTracker.hamIDs, hamIDs$(), addToContacts, 5, 25, 150, 250 ListBox #HamIDTracker.contactedHamIDs, contactedHamIDs$(), removeFromContacts, 200, 25, 150, 250 Button #HamIDTracker.btnAddToContactList, "->", addToContacts, UL, 165, 117, 20, 20 Button #HamIDTracker.btnRemoveFromContactList, "<-", removeFromContacts, UL, 165, 148, 20, 20 Button #HamIDTracker.btnSaveContacts, "Save Contacts", saveContacts, UL, 5, 280, 95, 20 Button #HamIDTracker.btnExit, "Exit", exitWindow, UL, 300, 280, 50, 20 Open "Contacted Ham Member Tracking" For Window_NF As #HamIDTracker #HamIDTracker "TrapClose quit" Wait
Sub quit handle$ Call saveContacts "#HamIDTracker.btnSaveContacts" Close #handle$ End End Sub
Sub exitWindow handle$ Call saveContacts "#HamIDTracker.btnSaveContacts" Call quit Word$(handle$, 1, ".") End Sub
Sub saveContacts handle$ Open contactListFilePath$ For Output As #HamContacted For i = 0 To hamContactedListUBound #HamContacted Trim$(contactedHamIDs$(i)) Next i Close #HamContacted End Sub
Sub addToContacts handle$ #HamIDTracker.hamIDs "Selection? hamID$" If (hamID$ <> "") Then For i = 0 To hamContactedListUBound If contactedHamIDs$(i) = hamID$ Then alreadyExists = True Next i
If Not(alreadyExists) Then If (contactedHamIDs$(hamContactedListUBound) <> "") Then hamContactedListUBound = (hamContactedListUBound + 1) Dim temp$(hamContactedListUBound) For i = 0 To (hamContactedListUBound - 1) temp$(i) = contactedHamIDs$(i) Next i ReDim contactedHamIDs$(hamContactedListUBound) For i = 0 To hamContactedListUBound contactedHamIDs$(i) = temp$(i) Next i contactedHamIDs$(hamContactedListUBound) = hamID$ ReDim temp$(-1) Else 'We should not need this since we are always keeping the array minimized End If #HamIDTracker.contactedHamIDs "Reload" #HamIDTracker.contactedHamIDs "Select ";hamID$ Else #HamIDTracker.contactedHamIDs "Select ";hamID$ Notice "Notice!";CRLF$;hamID$;" is already a known contact and has been";CRLF$; _ "selected in the Contacted Ham IDs ListBox." End If Else Notice "No Member Ham IDs ListBox item has been selected to add!" End If End Sub
Sub removeFromContacts handle$ #HamIDTracker.contactedHamIDs "Selection? hamID$" If (hamID$ <> "") Then Dim temp$(hamContactedListUBound - 1) For i = 0 To hamContactedListUBound If (contactedHamIDs$(i) <> hamID$) Then temp$(ii) = contactedHamIDs$(i) ii = (ii + 1) End If Next i hamContactedListUBound = (hamContactedListUBound - 1) ReDim contactedHamIDs$(hamContactedListUBound) For i = 0 To hamContactedListUBound contactedHamIDs$(i) = temp$(i) Next i #HamIDTracker.contactedHamIDs "Reload" Else Notice "No Contacted Ham IDs ListBox item has been selected to remove!" End If End Sub
Sub initializeHamIDArray hamList$ i = 2 hamID$ = UpTo$(Word$(hamList$, i, "2079 "), " ") While (hamID$ <> "") If (hamID$ <> "") Then hamIDs$(i - 2) = Trim$(hamID$) End If i = (i + 1) hamID$ = UpTo$(Word$(hamList$, i, "2079 "), " ") Wend End Sub
Sub initializeContactedHamIDArray hamContactedList$ i = 1 hamID$ = Word$(hamContactedList$, i, CRLF$) While (hamID$ <> "") If (hamID$ <> "") Then contactedHamIDs$(i - 1) = Trim$(hamID$) End If i = (i + 1) hamID$ = Word$(hamContactedList$, i, CRLF$) Wend End Sub
Function CountSubstring(string$, substring$, position, CountSubstring) position = Instr(string$, substring$) If position Then CountSubstring = CountSubstring(Mid$(string$, (position + Len(substring$))), _ substring$, (position + Len(substring$)), (CountSubstring + 1)) End Function {:0) Brandon Parker
|
|
|
Post by johnk1ese on May 8, 2023 18:19:34 GMT -5
Thank you all for the help!
I am using Brandon's code and am modifying it to format the results. I appreciate all the suggestions and this is doing the job.
I will save the other suggestions for future reference. There are a lot of talented people on this Forum.
Thank you all, John K1ESE
|
|
|
Post by Brandon Parker on May 9, 2023 17:04:58 GMT -5
John, I am glad that you are finding everyone's suggestions helpful. Let us know if we can be of further assistance specifically if you need help with any of the code that I have provided.
{:0)
Brandon Parker
|
|