ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/ns_dev/Python/NinoCode/Active_prgs/Redgrave/Amazon_PrivLogQC.py
Revision: 881
Committed: Fri Feb 14 15:54:33 2025 UTC (13 months, 1 week ago) by nino.borges
Content type: text/x-python
File size: 23903 byte(s)
Log Message:
No substantial changes to logic, just adding more header rows.  Going to update logic on next version, so setting this one here as clean.

File Contents

# User Rev Content
1 nino.borges 828 """
2    
3     Amazon-PrivLogQC
4    
5     Created by:
6     Emanuel Borges
7     11.19.2024
8    
9     This program will assist with the process of performing QC on the Amazon privilege logs.
10    
11     """
12    
13     import os, re
14     from collections import namedtuple
15 nino.borges 851 from MyCode.Tool_Box import FileEncodingLib
16 nino.borges 828
17    
18     class QcPrivLog(object):
19     """A class for automating the process of performing QC on the Amazon privilege logs, including names normalization analysis"""
20 nino.borges 852 version = '0.7.1'
21 nino.borges 828
22    
23     def __init__(self, cleanedDatExportFileName, fileEncoding = 'UTF8'):
24     """Initializes the data structures. cleanedDatExportFileName should be the full path to the file. Assumes the first row of the data file is the header and first column is DocID."""
25     print("Initializing data structures...")
26     self.metadataValuesDict = {}
27     self.formattedValuesDict = {}
28 nino.borges 852 self.additionalValuesDict = {}
29 nino.borges 830 self.allPossibleEmailAddressesRegExPattern = r"[\w.+-]+@[\w-]+\.[\w.-]+"
30 nino.borges 828
31     contents = open(cleanedDatExportFileName,encoding = fileEncoding).readlines()
32     self.cleanedInputDataFileHeader = contents[0]
33 nino.borges 832 self.cleanedInputDataFileHeaderList = self.cleanedInputDataFileHeader.split("|")
34 nino.borges 828 contents = contents[1:]
35 nino.borges 832 print (f"There are {len(contents)} rows of data in this input file.\n\n")
36 nino.borges 828
37 nino.borges 851
38 nino.borges 881 ## Floyd
39     ## print (f"The data structure will be made of following field pairs:")
40     ## print(f"{self.cleanedInputDataFileHeaderList[23]} | {self.cleanedInputDataFileHeaderList[24]}")
41     ## print(f"{self.cleanedInputDataFileHeaderList[25]} | {self.cleanedInputDataFileHeaderList[26]}")
42     ## print(f"{self.cleanedInputDataFileHeaderList[27]} | {self.cleanedInputDataFileHeaderList[28]}")
43     ## print(f"{self.cleanedInputDataFileHeaderList[29]} | {self.cleanedInputDataFileHeaderList[20]}")
44     ## print(f"{self.cleanedInputDataFileHeaderList[29]} | {self.cleanedInputDataFileHeaderList[32]}\n\n")
45     ## print(f"{self.cleanedInputDataFileHeaderList[12]} will be used for the date qualifier.")
46     ## print(f"{self.cleanedInputDataFileHeaderList[36]} will be used as the Legal Source field.")
47    
48    
49     ## CAAG
50     ## print (f"The data structure will be made of following field pairs:")
51     ## print(f"{self.cleanedInputDataFileHeaderList[30]} | {self.cleanedInputDataFileHeaderList[31]}")
52     ## print(f"{self.cleanedInputDataFileHeaderList[34]} | {self.cleanedInputDataFileHeaderList[35]}")
53     ## print(f"{self.cleanedInputDataFileHeaderList[36]} | {self.cleanedInputDataFileHeaderList[37]}")
54     ## print(f"{self.cleanedInputDataFileHeaderList[38]} | {self.cleanedInputDataFileHeaderList[39]}")
55     ## print(f"{self.cleanedInputDataFileHeaderList[29]} | {self.cleanedInputDataFileHeaderList[32]}\n\n")
56     ## print(f"{self.cleanedInputDataFileHeaderList[15]} will be used for the date qualifier.")
57     ## print(f"{self.cleanedInputDataFileHeaderList[45]} will be used as the Legal Source field.")
58    
59     ## CAAG Custom 2
60     ## print (f"The data structure will be made of following field pairs:")
61     ## print(f"{self.cleanedInputDataFileHeaderList[22]} | {self.cleanedInputDataFileHeaderList[10]}")
62     ## print(f"{self.cleanedInputDataFileHeaderList[23]} | {self.cleanedInputDataFileHeaderList[11]}")
63     ## print(f"{self.cleanedInputDataFileHeaderList[24]} | {self.cleanedInputDataFileHeaderList[12]}")
64     ## print(f"{self.cleanedInputDataFileHeaderList[25]} | {self.cleanedInputDataFileHeaderList[13]}")
65     ## print(f"{self.cleanedInputDataFileHeaderList[28]} | {self.cleanedInputDataFileHeaderList[29]}\n\n")
66     ## print(f"{self.cleanedInputDataFileHeaderList[2]} will be used for the date qualifier.")
67     ## print(f"{self.cleanedInputDataFileHeaderList[27]} will be used as the Legal Source field.")
68    
69 nino.borges 851 ## VEAS-CAAG
70 nino.borges 881 ## print (f"The data structure will be made of following field pairs:")
71     ## print(f"{self.cleanedInputDataFileHeaderList[26]} | {self.cleanedInputDataFileHeaderList[27]}")
72     ## print(f"{self.cleanedInputDataFileHeaderList[29]} | {self.cleanedInputDataFileHeaderList[30]}")
73     ## print(f"{self.cleanedInputDataFileHeaderList[31]} | {self.cleanedInputDataFileHeaderList[32]}")
74     ## print(f"{self.cleanedInputDataFileHeaderList[33]} | {self.cleanedInputDataFileHeaderList[34]}")
75     ## print(f"{self.cleanedInputDataFileHeaderList[25]} | {self.cleanedInputDataFileHeaderList[28]}\n\n")
76     ## print(f"{self.cleanedInputDataFileHeaderList[15]} will be used for the date qualifier.")
77     ## print(f"{self.cleanedInputDataFileHeaderList[40]} will be used as the Legal Source field.")
78 nino.borges 832
79 nino.borges 881 ## VEAS-CAAG 2
80     ## print (f"The data structure will be made of following field pairs:")
81     ## print(f"{self.cleanedInputDataFileHeaderList[11]} | {self.cleanedInputDataFileHeaderList[5]}")
82     ## print(f"{self.cleanedInputDataFileHeaderList[12]} | {self.cleanedInputDataFileHeaderList[6]}")
83     ## print(f"{self.cleanedInputDataFileHeaderList[13]} | {self.cleanedInputDataFileHeaderList[7]}")
84     ## print(f"{self.cleanedInputDataFileHeaderList[14]} | {self.cleanedInputDataFileHeaderList[8]}")
85     ## print(f"{self.cleanedInputDataFileHeaderList[15]} | {self.cleanedInputDataFileHeaderList[4]}\n\n")
86     ## print(f"{self.cleanedInputDataFileHeaderList[1]} will be used for the date qualifier.")
87     ## print(f"{self.cleanedInputDataFileHeaderList[9]} will be used as the Legal Source field.")
88    
89 nino.borges 851 ## VEAS_custom
90     ## print (f"The data structure will be made of following field pairs:")
91     ## print(f"{self.cleanedInputDataFileHeaderList[2]} | {self.cleanedInputDataFileHeaderList[6]}")
92     ## print(f"{self.cleanedInputDataFileHeaderList[3]} | {self.cleanedInputDataFileHeaderList[8]}")
93     ## print(f"{self.cleanedInputDataFileHeaderList[4]} | {self.cleanedInputDataFileHeaderList[9]}")
94     ## print(f"{self.cleanedInputDataFileHeaderList[5]} | {self.cleanedInputDataFileHeaderList[10]}")
95     ## print(f"{self.cleanedInputDataFileHeaderList[1]} | {self.cleanedInputDataFileHeaderList[6]}\n\n")
96    
97 nino.borges 881 ## FTC-Retail
98     print (f"The data structure will be made of following field pairs:")
99     print(f"{self.cleanedInputDataFileHeaderList[39]} | {self.cleanedInputDataFileHeaderList[40]}")
100     print(f"{self.cleanedInputDataFileHeaderList[41]} | {self.cleanedInputDataFileHeaderList[42]}")
101     print(f"{self.cleanedInputDataFileHeaderList[43]} | {self.cleanedInputDataFileHeaderList[44]}")
102     print(f"{self.cleanedInputDataFileHeaderList[45]} | {self.cleanedInputDataFileHeaderList[46]}")
103     print(f"{self.cleanedInputDataFileHeaderList[37]} | {self.cleanedInputDataFileHeaderList[38]}\n\n")
104     print(f"{self.cleanedInputDataFileHeaderList[27]} will be used for the date qualifier.")
105     print(f"{self.cleanedInputDataFileHeaderList[52]} will be used as the Legal Source field.")
106    
107 nino.borges 831 RecordValues = namedtuple("RecordValues","fromValues toValues ccValues bccValues docAuthor")
108 nino.borges 828 self.recordValuesFieldList = RecordValues._fields
109    
110 nino.borges 852 AdditionalValues = namedtuple("AdditionalValues","dateValue legalSourceValues")
111     self.additionalValuesFieldList = AdditionalValues._fields
112    
113 nino.borges 828 for line in contents:
114     line = line.replace("\n","")
115     line = line.split("|")
116     docID = line[0]
117     ## TODO: These are hard coded for now but change to column header lookup asap.
118 nino.borges 881 ## CAAG_custom 2
119     #self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[22]),self.__SplitAndClean(line[23]),self.__SplitAndClean(line[24]),self.__SplitAndClean(line[25]) ,self.__SplitAndClean(line[28]))
120     #self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[10]),self.__SplitAndClean(line[11]),self.__SplitAndClean(line[12]),self.__SplitAndClean(line[13]),self.__SplitAndClean(line[29]))
121     ## TODO: update code because they now have time values in the family date field.
122     #self.additionalValuesDict[docID] = AdditionalValues(line[2].split(" ")[0],self.__SplitAndClean(line[27]))
123     ## Floyd
124     #self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[30]),self.__SplitAndClean(line[34]),self.__SplitAndClean(line[36]),self.__SplitAndClean(line[38]) ,self.__SplitAndClean(line[29]))
125     #self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[31]),self.__SplitAndClean(line[35]),self.__SplitAndClean(line[37]),self.__SplitAndClean(line[39]),self.__SplitAndClean(line[32]))
126     #self.additionalValuesDict[docID] = AdditionalValues(line[15],self.__SplitAndClean(line[45]))
127 nino.borges 839 ## CAAG
128 nino.borges 833 #self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[30]),self.__SplitAndClean(line[34]),self.__SplitAndClean(line[36]),self.__SplitAndClean(line[38]) ,self.__SplitAndClean(line[29]))
129     #self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[31]),self.__SplitAndClean(line[35]),self.__SplitAndClean(line[37]),self.__SplitAndClean(line[39]),self.__SplitAndClean(line[32]))
130 nino.borges 881 #self.additionalValuesDict[docID] = AdditionalValues(line[15],self.__SplitAndClean(line[45]))
131 nino.borges 839 ## VEAS-CAAG
132 nino.borges 881 #self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[26]),self.__SplitAndClean(line[29]),self.__SplitAndClean(line[31]),self.__SplitAndClean(line[33]) ,self.__SplitAndClean(line[25]))
133     #self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[27]),self.__SplitAndClean(line[30]),self.__SplitAndClean(line[32]),self.__SplitAndClean(line[34]),self.__SplitAndClean(line[28]))
134     #self.additionalValuesDict[docID] = AdditionalValues(line[15],self.__SplitAndClean(line[40]))
135     ## VEAS-CAAG 2
136     #self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[11]),self.__SplitAndClean(line[12]),self.__SplitAndClean(line[13]),self.__SplitAndClean(line[14]) ,self.__SplitAndClean(line[15]))
137     #self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[5]),self.__SplitAndClean(line[6]),self.__SplitAndClean(line[7]),self.__SplitAndClean(line[8]),self.__SplitAndClean(line[4]))
138     ## TODO: update code because they now have time values in the family date field.
139     #self.additionalValuesDict[docID] = AdditionalValues(line[1].split(" ")[0],self.__SplitAndClean(line[9]))
140 nino.borges 839 ## FTC-CID
141     #self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[6]),self.__SplitAndClean(line[7]),self.__SplitAndClean(line[8]),self.__SplitAndClean(line[9]) ,self.__SplitAndClean(line[10]))
142     #self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[3]),self.__SplitAndClean(line[5]),self.__SplitAndClean(line[2]),self.__SplitAndClean(line[4]),self.__SplitAndClean(line[11]))
143     ## VEAS_custom
144 nino.borges 851 #self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[2]),self.__SplitAndClean(line[3]),self.__SplitAndClean(line[4]),self.__SplitAndClean(line[5]) ,self.__SplitAndClean(line[1]))
145     #self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[6]),self.__SplitAndClean(line[8]),self.__SplitAndClean(line[9]),self.__SplitAndClean(line[10]),self.__SplitAndClean(line[6]))
146 nino.borges 839 ## CAAG_custom
147     #self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[3]),self.__SplitAndClean(line[4]),self.__SplitAndClean(line[5]),self.__SplitAndClean(line[6]) ,self.__SplitAndClean(line[2]))
148     #self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[7]),self.__SplitAndClean(line[8]),self.__SplitAndClean(line[9]),self.__SplitAndClean(line[10]),self.__SplitAndClean(line[7]))
149 nino.borges 881 ## FTC-Retail
150     self.metadataValuesDict[docID] = RecordValues(self.__SplitAndClean(line[39]),self.__SplitAndClean(line[41]),self.__SplitAndClean(line[43]),self.__SplitAndClean(line[45]) ,self.__SplitAndClean(line[37]))
151     self.formattedValuesDict[docID] = RecordValues(self.__SplitAndClean(line[40]),self.__SplitAndClean(line[42]),self.__SplitAndClean(line[44]),self.__SplitAndClean(line[46]),self.__SplitAndClean(line[38]))
152     ## TODO: update code because they now have time values in the family date field.
153     self.additionalValuesDict[docID] = AdditionalValues(line[27].split(" ")[0],self.__SplitAndClean(line[52]))
154 nino.borges 828
155     print("Data structures created.")
156    
157    
158    
159     def __SplitAndClean(self, rawVal, delim = ";"):
160     """Pseudo-private method which will take a raw string and split this into a list, removing any leading or trailing whitespace"""
161 nino.borges 833 if rawVal:
162     newVal = [x.strip() for x in rawVal.split(delim)]
163     else: newVal = ""
164     return newVal
165 nino.borges 828
166    
167     def __FieldDedupeByEmailAddress(self, valuesList):
168     """Pseudo-private method which will attempt to deduplicate a list of values from a specific field by pulling out email addresses as the deduplication criteria. Returns deduplicated count."""
169 nino.borges 830 ## This should ONLY be used for deduplication for counting and not for true deduplication because it removes a duplicate value at random and sometimes this will be the value with more information.
170     ## TODO: update this to be case insensitive.
171     tempEmailList = []
172     newList = []
173     for item in valuesList:
174     result = re.findall(self.allPossibleEmailAddressesRegExPattern, item)
175     if result:
176     for r in result:
177     if r.upper() in tempEmailList:
178     pass
179     else:
180     newList.append(item)
181     tempEmailList.append(r.upper())
182     else:
183     newList.append(item)
184     return len(newList)
185    
186 nino.borges 828
187 nino.borges 831 def __FieldFullValueDedupe(self, valuesList):
188     """Pseudo-private method which will attempt to deduplicate a list of values from a specific field using the FULL VALUE. This was created because there appears to be duplicate values int he formatted fields"""
189     ## Going to do this the long way because of possible uppercase-lowercase issues. These should all be uppercase but there shouldnt have been dups either...
190     newSet = set()
191     for item in valuesList:
192     newSet.add(item.upper())
193     return len(newSet)
194 nino.borges 828
195 nino.borges 830
196 nino.borges 828 def PerformValueCountChecks(self, countsOnly = True):
197     """Performs the inital value count checks between the metadata values and formatted values, looking for red flags and warnings. By default reports numbers. Set countsOnly to false to export reports."""
198     workList = self.metadataValuesDict.keys()
199     #misCount = 0
200     #redFlagDocList = []
201     #warningDocList = []
202     #misList = []
203     redFlagDocSet = set()
204 nino.borges 833 redFlagDocMatrix = {}
205 nino.borges 828 warningDocSet = set()
206 nino.borges 833 warningDocMatrix = {}
207 nino.borges 832 #duplicatesInFormattedSet = set()
208     duplicatesInFormattedMatrix = {}
209 nino.borges 828
210     for docID in workList:
211 nino.borges 829 for fieldName in self.recordValuesFieldList:
212     metadataFieldValues = self.metadataValuesDict[docID]._asdict()[fieldName]
213     formattedFieldValues = self.formattedValuesDict[docID]._asdict()[fieldName]
214 nino.borges 833
215 nino.borges 829 if len(metadataFieldValues) - len(formattedFieldValues) == 0:
216     pass
217 nino.borges 828 else:
218 nino.borges 829 if len(metadataFieldValues) == 0:
219 nino.borges 833 ## Have to account for instances where the meta docAuthor is blank because it's an email and the formatted just has the from value in it.
220     if fieldName == 'docAuthor':
221     if self.metadataValuesDict[docID].fromValues:
222     pass
223     else:
224     redFlagDocSet.add(docID)
225     #print(docID)
226     try:
227     redFlagDocMatrix[docID].append(fieldName)
228     except KeyError:
229     redFlagDocMatrix[docID] = [fieldName,]
230     else:
231     redFlagDocSet.add(docID)
232     try:
233     redFlagDocMatrix[docID].append(fieldName)
234     except KeyError:
235     redFlagDocMatrix[docID] = [fieldName,]
236 nino.borges 829 elif len(formattedFieldValues) == 0:
237     redFlagDocSet.add(docID)
238 nino.borges 833 try:
239     redFlagDocMatrix[docID].append(fieldName)
240     except KeyError:
241     redFlagDocMatrix[docID] = [fieldName,]
242 nino.borges 829 else:
243 nino.borges 830 ## try the count again by deduplicating the metadata field values. Never on the formatted field values.
244     deduplicatedFieldCount = self.__FieldDedupeByEmailAddress(metadataFieldValues)
245     if deduplicatedFieldCount - len(formattedFieldValues) == 0:
246     pass
247     else:
248 nino.borges 833 distanceBetween = abs(deduplicatedFieldCount - len(formattedFieldValues))
249     if deduplicatedFieldCount > 30:
250     if distanceBetween > (10 * deduplicatedFieldCount)/100:
251     print(docID,fieldName)
252     redFlagDocSet.add(docID)
253     try:
254     redFlagDocMatrix[docID].append(fieldName)
255     except KeyError:
256     redFlagDocMatrix[docID] = [fieldName,]
257     else:
258     warningDocSet.add(docID)
259     try:
260     warningDocMatrix[docID].append(fieldName)
261     except KeyError:
262     warningDocMatrix[docID]= [fieldName,]
263     else:
264     if distanceBetween > 2:
265     print(docID,fieldName)
266     redFlagDocSet.add(docID)
267     try:
268     redFlagDocMatrix[docID].append(fieldName)
269     except KeyError:
270     redFlagDocMatrix[docID] = [fieldName,]
271     else:
272     warningDocSet.add(docID)
273     try:
274     warningDocMatrix[docID].append(fieldName)
275     except KeyError:
276     warningDocMatrix[docID]= [fieldName,]
277 nino.borges 831
278     ## Perform a separate check for duplicates in the formatted field.
279     if len(formattedFieldValues) == self.__FieldFullValueDedupe(formattedFieldValues):
280     pass
281     else:
282 nino.borges 832 try:
283     duplicatesInFormattedMatrix[docID].append(fieldName)
284     except KeyError:
285     duplicatesInFormattedMatrix[docID] = [fieldName,]
286     #duplicatesInFormattedSet.add(docID)
287 nino.borges 829 ## if len(self.metadataValuesDict[docID].toValues) - len(self.formattedValuesDict[docID].toValues) == 0:
288     ## pass
289     ## else:
290     ## if len(self.metadataValuesDict[docID].toValues) == 0:
291     ## #redFlagDocList.append(docID)
292     ## redFlagDocSet.add(docID)
293     ## elif len(self.formattedValuesDict[docID].toValues) == 0:
294     ## #redFlagDocList.append(docID)
295     ## redFlagDocSet.add(docID)
296     ## else:
297     ## #misCount +=1
298     ## #misList.append(docID)
299     ## #warningDocList.append(docID)
300     ## warningDocSet.add(docID)
301 nino.borges 828
302 nino.borges 830 print(f"There are a total of {len(redFlagDocSet)} red flag documents and {len(warningDocSet)} warnings where the matching field value counts that do not match.")
303 nino.borges 828 if countsOnly == False:
304     warningsOutputFile = open(r"C:\Test_Dir\Amazon\warnings.txt",'w')
305     redFladsOutputFile = open(r"C:\Test_Dir\Amazon\redFlags.txt",'w')
306 nino.borges 831 duplicatesInFormattedOutputFile = open(r"C:\Test_Dir\Amazon\dupesInFormattedFields.txt",'w')
307 nino.borges 833 for x in warningDocMatrix:
308     warningsOutputFile.write(f"{x} | {*warningDocMatrix[x],}\n")
309 nino.borges 828 warningsOutputFile.close()
310 nino.borges 833 for y in redFlagDocMatrix:
311     redFladsOutputFile.write(f"{y} | {*redFlagDocMatrix[y],}\n")
312 nino.borges 828 redFladsOutputFile.close()
313 nino.borges 832 for z in duplicatesInFormattedMatrix:
314     duplicatesInFormattedOutputFile.write(f"{z} | {*duplicatesInFormattedMatrix[z],}\n")
315 nino.borges 831 duplicatesInFormattedOutputFile.close()
316 nino.borges 828
317    
318     if __name__ == '__main__':
319 nino.borges 881 cleanedDatExportFileName = r"C:\Users\eborges\OneDrive - Redgrave LLP\Documents\Cases\Amazon\_PrivLogQCProcess\CAAG-20250131\export_20250131_215508_Converted.txt"
320     #cleanedDatExportFileName = r"C:\Users\eborges\OneDrive - Redgrave LLP\Documents\Cases\Amazon\_PrivLogQCProcess\20250129\VEAS\VEAS_20250130_020124_Converted.txt"
321     #cleanedDatExportFileName = r"C:\Users\eborges\OneDrive - Redgrave LLP\Documents\Cases\Amazon\_PrivLogQCProcess\20241215\PrivLogExports\PrivLogExport_20241211_CAAG_Converted.txt"
322     #cleanedDatExportFileName = r"C:\Users\eborges\OneDrive - Redgrave LLP\Documents\Cases\Amazon\_PrivLogQCProcess\Testing_3\PrivLogExport_20241204_VEAS_Converted.txt"
323 nino.borges 851 #cleanedDatExportFileName = r"C:\Users\eborges\OneDrive - Redgrave LLP\Documents\Cases\Amazon\_PrivLogQCProcess\Data Exports\CAAG\CAAG_Log_Data_Export_Converted.txt"
324 nino.borges 839 #cleanedDatExportFileName = r"C:\Users\eborges\OneDrive - Redgrave LLP\Documents\Cases\Amazon\_PrivLogQCProcess\20241202 - FTC-CID\PLOG All IDs (20241202)\PLOG All IDs (20241202)_Converted_SubSetOnly.txt"
325     #cleanedDatExportFileName = r"C:\Users\eborges\OneDrive - Redgrave LLP\Documents\Cases\Amazon\_PrivLogQCProcess\20241122 - VEAS CAAG 20241206\export_20241122_160117_Converted.txt"
326 nino.borges 833 #cleanedDatExportFileName = r"C:\Users\eborges\AppData\Local\Programs\Python\Python312\MyCode\JN\_Temp2\20241115_PrivLogWorking_CAAG\PrivLogExport_20241113_CAAG_Converted.txt"
327     #cleanedDatExportFileName = r"C:\Users\eborges\AppData\Local\Programs\Python\Python312\MyCode\JN\_Temp2\20241115_PrivLogWorking_CAAG\TEST.txt"
328 nino.borges 828
329     ## Code Testing
330     qcP = QcPrivLog(cleanedDatExportFileName)
331 nino.borges 833 ## print(qcP.metadataValuesDict['H55278-0268-003517'].fromValues)
332     ## print(qcP.metadataValuesDict['H55278-0268-003517'].toValues)
333     ## print(qcP.metadataValuesDict['H55278-0268-003517'].ccValues)
334     ## print(qcP.metadataValuesDict['H55278-0268-003517'].bccValues)
335     ## print(qcP.formattedValuesDict['H55278-0268-003517'].fromValues)
336     ## print(qcP.formattedValuesDict['H55278-0268-003517'].toValues)
337     ## print(qcP.formattedValuesDict['H55278-0268-003517'].ccValues)
338     ## print(qcP.formattedValuesDict['H55278-0268-003517'].bccValues)
339 nino.borges 828
340     qcP.PerformValueCountChecks(countsOnly = False)
341    
342