Senach Posted December 5, 2008 Share Posted December 5, 2008 Greetings all. I'm having a bit of trouble and have exhausted my troubleshooting abilities. I've done some searching in the forums and while I found several post similar to what I'm trying I was unable to adapt the given code to make it work for me. Basically, I have two text files. One is a list of book titles, the other is a list of some of the titles on the first list. All the titles on the second list are in the fist, and the formatting is identical on both lists. I'm trying to basically combine the two lists and make note (in the case of my script below putting a * in front of them) of the titles that are on the second list. Here's what I have (I have it outputting to a third file because I just going for the simplest way I knew): #include <File.au3> $filea = FileOpen("C:\script\alltitles.txt", 0) $file8 = FileOpen("C:\scripts\goodtitles.txt", 0) $fileZeta = FileOpen("C:\scripts\totaltitles.txt", 10) While 1 $line = filereadline($file8) if @error = -1 then ExitLoop if @error <> -1 then readwrite() WEnd FileClose($filea) FileClose($file8) FileClose($fileZeta) Func readwrite() While 1 $line2 = FileReadLine($filea) If @error = -1 then ExitLoop If $line = $line2 Then FileWriteLine ($fileZeta, "*" & $line2 & @CRLF) If $line <> $line2 Then FileWriteLine ($fileZeta, $line2 & @CRLF) WEnd EndFunc Any thoughts or suggestions to where I'm messing up would be greatly appreciated. Thanks! "The three rules of the Librarians of Time and Space are: 1) Silence; 2) Books must be returned no later than the date last shown; and 3) Do not interfere with the nature of causality." Terry Pratchett - The Light Fantastic Link to comment Share on other sites More sharing options...
BugFix Posted December 5, 2008 Share Posted December 5, 2008 Hi,i think this may help you: _GetIntersection() Best Regards BugFix Link to comment Share on other sites More sharing options...
Senach Posted December 8, 2008 Author Share Posted December 8, 2008 Thanks Bugfix - that is a very sweet function, but either Im missing something or I wasnt making myself clear. Let me explain my quandary in a bit more detail: I run a homebound patron service at my library where we take books to people who cant come in. when we pick up these books the patrons have rated them on a scale a 1-10. We enter those numbers into our library computer system. However the library system will only give us lists of the patrons books that they rated X number or above. Well, we can get a list of books they like (say that they rated 8 and above), and a list of all the books weve taken them (they dont like it when we take the same book twice). But not a list of all the books we've taken the patron with what they'd rated them. So naturally all the books on the 8+ list are on the list of all of them. So when were picking new books we either have to have both lists and check both as we pick new books, or take to list of all the books and go through and highlight ones on that list that are on the 8+ list. While this works, when the list of all items is over 600 books, and the list of 8+ has over 200, it takes a while. I was trying to figure out a way to automate the highlighting chore basically mark all the ones on the 8+ list on the all books list. Anyway, does that make sense? Your _GetIntersection function seems to be designed to either pull out the differences or similarities between two arrays. Well, I know everything on the 8+ list is on the all book list, but not vice versa. So is there a way that Im just missing with that function to get all the ones on one list marked on the other? Or did I just not explain my original question well enough? Thanks! "The three rules of the Librarians of Time and Space are: 1) Silence; 2) Books must be returned no later than the date last shown; and 3) Do not interfere with the nature of causality." Terry Pratchett - The Light Fantastic Link to comment Share on other sites More sharing options...
picaxe Posted December 9, 2008 Share Posted December 9, 2008 @BugFix - congrats, very nice. @Senach - something like this, using GetIntersection by BugFix expandcollapse popup#include <array.au3> #include <GUIConstants.au3> #include <GuiListView.au3> #include <ListViewConstants.au3> #include <Misc.au3> #include <WindowsConstants.au3> $sAll = 'book one,book two,title three,book four,title five,book six,title 7,book eight,tile nine' $sPlus8 = 'title 7,book one,book 1,book 5,title 8,title three,book two' $aFirstSet = StringSplit($sAll, ",") $aPlus8 = StringSplit($sPlus8, ",") $aRet = _GetIntersection($sAll, $aPlus8, 1, ',') ;_ArrayDisplay($aRet) $Form1 = GUICreate("Intersect Items Ticked", 300, 270) $hListView = GUICtrlCreateListView("Items", 10, 10, 280, 250, _ BitOR($LVS_REPORT, $WS_HSCROLL, $WS_VSCROLL, $WS_BORDER), _ BitOR($WS_EX_CLIENTEDGE, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT)) $j = 0 For $i = 1 To $aFirstSet[0] GUICtrlCreateListViewItem($aFirstSet[$i], $hListView) If $aFirstSet[$i] = $aRet[$j][0] Then GUICtrlSetState(-1, $GUI_CHECKED) $j += 1 EndIf Next GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 0, 270) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE ExitLoop EndSelect WEnd Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView $hWndListView = $hListView If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView) $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode Case $NM_CLICK, $NM_DBLCLK, $NM_RCLICK, $NM_RDBLCLK Return 1 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY ;================================================================================================== ; Function Name: _GetIntersection($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]]) ; Description:: Detect from 2 sets ; - Intersection (elements are contains in both sets) ; - Difference 1 (elements are contains only in $Set1) ; - Difference 2 (elements are contains only in $Set2) ; Parameter(s): $Set1 set 1 (1D-array or delimited string) ; $Set2 set 2 (1D-array or delimited string) ; optional: $GetAll 0 - only one occurence of every different element are shown (Default) ; 1 - all elements of differences are shown ; optional: $Delim Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") ) ; Return Value(s): Succes 2D-array [i][0]=Intersection ; [i][1]=Difference 1 ; [i][2]=Difference 2 ; Failure -1 @error set, that was given as array, is'nt 1D-array ; Note: Comparison is case-sensitiv! - i.e. Number 9 is different to string '9'! ; Author(s): BugFix (bugfix@autoit.de) ;================================================================================================== Func _GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll = 0, $Delim = Default) Local $o1 = ObjCreate("System.Collections.ArrayList") Local $o2 = ObjCreate("System.Collections.ArrayList") Local $oUnion = ObjCreate("System.Collections.ArrayList") Local $oDiff1 = ObjCreate("System.Collections.ArrayList") Local $oDiff2 = ObjCreate("System.Collections.ArrayList") Local $tmp, $i If $GetAll <> 1 Then $GetAll = 0 If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar") If Not IsArray($Set1) Then If Not StringInStr($Set1, $Delim) Then $o1.Add($Set1) Else $tmp = StringSplit($Set1, $Delim, 1) For $i = 1 To UBound($tmp) - 1 $o1.Add($tmp[$i]) Next EndIf Else If UBound($Set1, 0) > 1 Then Return SetError(1, 0, -1) For $i = 0 To UBound($Set1) - 1 $o1.Add($Set1[$i]) Next EndIf If Not IsArray($Set2) Then If Not StringInStr($Set2, $Delim) Then $o2.Add($Set2) Else $tmp = StringSplit($Set2, $Delim, 1) For $i = 1 To UBound($tmp) - 1 $o2.Add($tmp[$i]) Next EndIf Else If UBound($Set2, 0) > 1 Then Return SetError(1, 0, -1) For $i = 0 To UBound($Set2) - 1 $o2.Add($Set2[$i]) Next EndIf For $tmp In $o1 If $o2.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp) Next For $tmp In $o2 If $o1.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp) Next For $tmp In $o1 If $GetAll Then If Not $oUnion.Contains($tmp) Then $oDiff1.Add($tmp) Else If Not $oUnion.Contains($tmp) And Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp) EndIf Next For $tmp In $o2 If $GetAll Then If Not $oUnion.Contains($tmp) Then $oDiff2.Add($tmp) Else If Not $oUnion.Contains($tmp) And Not $oDiff2.Contains($tmp) Then $oDiff2.Add($tmp) EndIf Next Local $UBound[3] = [$oDiff1.Count, $oDiff2.Count, $oUnion.Count], $max = 1 For $i = 0 To UBound($UBound) - 1 If $UBound[$i] > $max Then $max = $UBound[$i] Next Local $aOut[$max][3] If $oUnion.Count > 0 Then $i = 0 For $tmp In $oUnion $aOut[$i][0] = $tmp $i += 1 Next EndIf If $oDiff1.Count > 0 Then $i = 0 For $tmp In $oDiff1 $aOut[$i][1] = $tmp $i += 1 Next EndIf If $oDiff2.Count > 0 Then $i = 0 For $tmp In $oDiff2 $aOut[$i][2] = $tmp $i += 1 Next EndIf Return $aOut EndFunc ;==>_GetIntersection Link to comment Share on other sites More sharing options...
Senach Posted December 10, 2008 Author Share Posted December 10, 2008 Thank you both for your help and patience with me. I must be denser than usual, but even with you all laying it out for me I cant get it to work. Picaxe, Ive tried $filea = FileOpen("C:\scripts\homebound\homebound_textfiles\homebound_a1.txt", 0) $file8 = FileOpen("C:\scripts\homebound\homebound_textfiles\homebound_81.txt", 0) $sAll = $filea $sPlus8 = $file8 And got the box with the check box and line 1 but I was unable to get it to give me anything. (i.e. it wouldnt let me right click or anything to retrieve the data) Then I tried just pasting the text files in for the $sAll and $sPlus8. But I guess they were too large because AutoIt errored out with a Unterminated string. (I double checked but I had removed all and from the file before I pasted it in so the only ones were before and after the text.) Anyway, Thanks again for your help, but this is apparently beyond my ken. I think Im going to put it on the shelf for now and maybe come back to it later. Maybe then I can get my head wrapped around it. "The three rules of the Librarians of Time and Space are: 1) Silence; 2) Books must be returned no later than the date last shown; and 3) Do not interfere with the nature of causality." Terry Pratchett - The Light Fantastic Link to comment Share on other sites More sharing options...
picaxe Posted December 10, 2008 Share Posted December 10, 2008 (edited) Try this, error checking/handling for missing files etc needs to be added. I'm assuming the file format is one book title per line.expandcollapse popup#include <array.au3> #include <GUIConstants.au3> #include <GuiListView.au3> #include <ListViewConstants.au3> #include <Misc.au3> #include <WindowsConstants.au3> #Include <String.au3> $sPlus8 = FileRead("C:\scripts\homebound\homebound_textfiles\homebound_81.txt") $aFirstSet = _StringSplit(FileRead("C:\scripts\homebound\homebound_textfiles\homebound_a1.txt"), @CRLF, 1) $aRet = _GetIntersection($aFirstSet, $sPlus8, 1, @CRLF) $Form1 = GUICreate("Intersect Items Ticked", 300, 270) $hListView = GUICtrlCreateListView("Items", 10, 10, 280, 250, _ BitOR($LVS_REPORT, $WS_HSCROLL, $WS_VSCROLL, $WS_BORDER), _ BitOR($WS_EX_CLIENTEDGE, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT)) $j = 0 $iUbound = UBound($aFirstSet) -1 For $i = 0 To $iUbound GUICtrlCreateListViewItem($aFirstSet[$i], $hListView) If $aFirstSet[$i] = $aRet[$j][0] Then GUICtrlSetState(-1, $GUI_CHECKED) $j += 1 EndIf Next GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 0, 270) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE ExitLoop EndSelect WEnd Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView $hWndListView = $hListView If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView) $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode Case $NM_CLICK, $NM_DBLCLK, $NM_RCLICK, $NM_RDBLCLK ; to prevent select hilite , $LVN_ITEMCHANGING Return 1 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY ;================================================================================================== ; Function Name: _GetIntersection($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]]) ; Description:: Detect from 2 sets ; - Intersection (elements are contains in both sets) ; - Difference 1 (elements are contains only in $Set1) ; - Difference 2 (elements are contains only in $Set2) ; Parameter(s): $Set1 set 1 (1D-array or delimited string) ; $Set2 set 2 (1D-array or delimited string) ; optional: $GetAll 0 - only one occurence of every different element are shown (Default) ; 1 - all elements of differences are shown ; optional: $Delim Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") ) ; Return Value(s): Succes 2D-array [i][0]=Intersection ; [i][1]=Difference 1 ; [i][2]=Difference 2 ; Failure -1 @error set, that was given as array, is'nt 1D-array ; Note: Comparison is case-sensitiv! - i.e. Number 9 is different to string '9'! ; Author(s): BugFix (bugfix@autoit.de) ;================================================================================================== Func _GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll = 0, $Delim = Default) Local $o1 = ObjCreate("System.Collections.ArrayList") Local $o2 = ObjCreate("System.Collections.ArrayList") Local $oUnion = ObjCreate("System.Collections.ArrayList") Local $oDiff1 = ObjCreate("System.Collections.ArrayList") Local $oDiff2 = ObjCreate("System.Collections.ArrayList") Local $tmp, $i If $GetAll <> 1 Then $GetAll = 0 If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar") If Not IsArray($Set1) Then If Not StringInStr($Set1, $Delim) Then $o1.Add($Set1) Else $tmp = StringSplit($Set1, $Delim, 1) For $i = 1 To UBound($tmp) - 1 $o1.Add($tmp[$i]) Next EndIf Else If UBound($Set1, 0) > 1 Then Return SetError(1, 0, -1) For $i = 0 To UBound($Set1) - 1 $o1.Add($Set1[$i]) Next EndIf If Not IsArray($Set2) Then If Not StringInStr($Set2, $Delim) Then $o2.Add($Set2) Else $tmp = StringSplit($Set2, $Delim, 1) For $i = 1 To UBound($tmp) - 1 $o2.Add($tmp[$i]) Next EndIf Else If UBound($Set2, 0) > 1 Then Return SetError(1, 0, -1) For $i = 0 To UBound($Set2) - 1 $o2.Add($Set2[$i]) Next EndIf For $tmp In $o1 If $o2.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp) Next For $tmp In $o2 If $o1.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp) Next For $tmp In $o1 If $GetAll Then If Not $oUnion.Contains($tmp) Then $oDiff1.Add($tmp) Else If Not $oUnion.Contains($tmp) And Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp) EndIf Next For $tmp In $o2 If $GetAll Then If Not $oUnion.Contains($tmp) Then $oDiff2.Add($tmp) Else If Not $oUnion.Contains($tmp) And Not $oDiff2.Contains($tmp) Then $oDiff2.Add($tmp) EndIf Next Local $UBound[3] = [$oDiff1.Count, $oDiff2.Count, $oUnion.Count], $max = 1 For $i = 0 To UBound($UBound) - 1 If $UBound[$i] > $max Then $max = $UBound[$i] Next Local $aOut[$max][3] If $oUnion.Count > 0 Then $i = 0 For $tmp In $oUnion $aOut[$i][0] = $tmp $i += 1 Next EndIf If $oDiff1.Count > 0 Then $i = 0 For $tmp In $oDiff1 $aOut[$i][1] = $tmp $i += 1 Next EndIf If $oDiff2.Count > 0 Then $i = 0 For $tmp In $oDiff2 $aOut[$i][2] = $tmp $i += 1 Next EndIf Return $aOut EndFunc ;==>_GetIntersection Edit: Use _StringSplit for zero based array so difference sets do not contain array count, in case they are used later. Edited December 10, 2008 by picaxe Link to comment Share on other sites More sharing options...
Senach Posted December 10, 2008 Author Share Posted December 10, 2008 Picaxe, That works beautifully! You Sir/Madam are a saint! And almost as important as it working, I think I understand why its working now. Thank you again, very, very much. *bow* "The three rules of the Librarians of Time and Space are: 1) Silence; 2) Books must be returned no later than the date last shown; and 3) Do not interfere with the nature of causality." Terry Pratchett - The Light Fantastic Link to comment Share on other sites More sharing options...
picaxe Posted December 11, 2008 Share Posted December 11, 2008 And almost as important as it working, I think I understand why its working now.You're welcome. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now