I have a few files to load I want to divide them into those that have a' content ...' line inside and those that don't have it, but my program put everything to a dictionary whose name is empty.
from tkinter import Tk
from tkinter.filedialog import askopenfilenames
Tk().withdraw()
filename = askopenfilenames() # show an "Open" dialog box and return the path to the selected file
print(filename)
content = {}
for file in filename:
fp = open(file, 'r')
lines = fp.readlines()
x ='Content'
content = {'is_in':[],'empty':[]}
with open(file) as myfile:
head = [next(myfile) for x in range(0,4)]
for line in head:
if x in line:
whole_line = line
whole_line = ''.join(whole_line.split())
result = whole_line.replace('Content','')
content['is_in'].append(file)
elif result not in head:
content['empty'].append(file)
CodePudding user response:
The problem here is how you use the scope for result variable.
If on the first iteration the if x in line returns False it will got for elif result not in head but at this point result is not defined yet.
Also, if at first iteration if x in line returns True, it will not even check the elfi statement. Will go forward to next iteration, and let's suppose that the next will reach elfi. Here you still don't have the result defined, since result was defined in the previous loop inside the if statement.
Please read about python scope
CodePudding user response:
As for me all your elif makes no sense.
You should first check all lines in head and set ie. found = True and after for-loop use this variable to add to content['empty']
searched = 'contente' # I will compare with `line.lower()`
# --- before `for`-loop ---
found = False
# --- `for`-loop ---
for line in head:
if searched in line.lower(): # compare lower case
content['is_in'].append(file)
found = True
break # there is no need to search in next lines
# --- after `for`-loop ---
if not found:
content['empty'].append(file)
Eventually you could use content['is_in'] for this
searched = 'contente' # I will compare with `line.lower()`
# --- `for`-loop ---
for line in head:
if searched in line.lower(): # compare lower case
content['is_in'].append(file)
break # there is no need to search in next lines
# --- after `for`-loop ---
if file not in content['is_in']:
content['empty'].append(file)
Python has also special construction for/else/break which runs else when break was not used in for
searched = 'contente' # I will compare with `line.lower()`
# --- `for`-loop ---
for line in head:
if searched in line.lower(): # compare lower case
content['is_in'].append(file)
break # there is no need to search in next lines
else: # in the same column as `for` (not as `if`)
content['empty'].append(file)
# --- after `for`-loop ---
Full working example with other changes.
I keep some ideas in comments.
from tkinter import Tk
from tkinter.filedialog import askopenfilenames
root = Tk()
root.withdraw()
all_filenames = askopenfilenames() # show an "Open" dialog box and return the path to the selected file
print('all_filenames:', all_filenames)
root.destroy() # remove it from memory
content = {
'is_in': [],
'empty': [],
}
searched = 'contente' # I will compare with `line.lower()`
for filename in all_filenames:
with open(filename) as file:
head = [next(file) for _ in range(4)]
# --- befere `for`-loop ---
found = False
# --- `for`-loop ---
for line in head:
#if line.lower().startswith(searched): # compare lower case
if searched in line.lower(): # compare lower case
content['is_in'].append(filename)
found = True
break # there is no need to search in next lines
#else:
# content['empty'].append(filename)
# --- after `for`-loop ---
#if not filename in content['is_in']:
if not found:
content['empty'].append(filename)
# ---
print('is_in:', content['is_in'])
print('empty:', content['empty'])
