Reputation: 21
I'm using Python to open some files in a CAD program. Since the program will crash when I open too many files at once, I want my script to stop opening files from a list I generated when the sum of thier filesize exceeds a certain value.
I'm converting the log file to a list. It contains the filepaths seperated by commas:
fList = []
with open('C:/Users/user/Desktop/log.txt', 'r') as f:
fList = f.read().split(',')
with suppress(ValueError, AttributeError):
fList.remove('')
fcount = len(fList)
This is the Generator that I use to Iterate over the partList:
def partGenerator(partList):
for file in partList:
yield file
Here I try to loop over the files while the sum of thier size is smaller than 2500000 bite:
count = 0
progression = 0
storage = 0
while storage < 2500000:
for file in partGenerator(fList):
name = os.path.basename(file)
storage += os.path.getsize(file)
print(f'Auslastung: {storage} bite / 2500000 bite')
oDoc = oApp.Documents.Open(file)
progression += 1
percent = round(100 * progression / fcount)
print(f'Fortschritt: {progression} / {fcount} ({percent} %) - {name}')
What happens is, that the files open propperly in the CAD Software, but they don't stop after the while condition is exceeded. My guess is, that the while condition is evaluated after the list runs out of entries and not after every entry like I what to.
Help on the correct syntax would be great!
I would like to use this script in a way that it opens some files and whenever I manualy close one in the CAD program, It opens the next one from my list until the list is exhausted.
Upvotes: 2
Views: 292
Reputation: 21
With the input from Martijn Pieters I came up with something that works perfectly for me. I'm a noob in programming so it took me a while to understand the problem. Here is what woked just fine in the end:
fList = []
with open('C:/Users/jhoefler/Desktop/log.txt', 'r') as f:
fList = f.read().split(',')
with suppress(ValueError, AttributeError):
fList.remove('')
fcount = len(fList)
count = 0
progression = 0
for file in fList:
name = os.path.basename(file)
if oApp.Documents.Count < 10:
oDoc = oApp.Documents.Open(file)
else:
pCount = oApp.Documents.LoadedCount
fCount = oApp.Documents.LoadedCount
while fCount == pCount:
time.sleep(1)
pCount = oApp.Documents.LoadedCount
oDoc = oApp.Documents.Open(file)
progression += 1
percent = round(100 * progression / fcount)
print(f'Fortschritt: {progression} / {fcount} ({percent} %) - {name}')
I'm sure there is a more elegant way to solve the problem, but it workes for my needs just fine.
Upvotes: 0
Reputation: 1123360
Your while
condition is never checked, no, because the for
loop never lets Python check. That the for
loop takes elements from a generator function is neither here nor there.
You need to check inside your for
loop if your condition still holds:
for file in partGenerator(fList):
name = os.path.basename(file)
storage += os.path.getsize(file)
if storage >= 2500000:
# wait for input before continuing, then reset the storage amount
input("Please close some files to continue, then press ENTER")
storage = 0
Python doesn't check while
conditions until the full suite (series of statements) in the block under the while ...:
statement has completed running or executes a continue
statement, so a while
condition really isn't suitable here.
In the above example I used the low-tech input()
function to ask whomever is running the script to press ENTER
afterwards. It'll depend on what oDoc.Documents
actually offers as an API to see if you could use that to detect that files have been closed.
If you wanted to use a generator function, have it track file sizes. You can even have it read those from the CSV file. I'd use the csv
module to handle splitting and progress, by the way:
import csv
def parts(logfile):
with open(logfile, newline='') as f:
reader = csv.reader(f)
files = [column for row in reader for column in row if column]
fcount = len(files)
storage = 0
for i, filename in enumerate(files):
storage += os.path.getsize(file)
if storage >= 2500000:
input("Please close some files to continue, then press ENTER")
storage = 0
print(f'Auslastung: {storage} bite / 2500000 bite')
yield file
print(f'Fortschritt: {i} / {fcount} ({i / fcount:.2%}) - {name}')
then just use
for file in parts('C:/Users/user/Desktop/log.txt'):
oDoc = oApp.Documents.Open(file)
Note that the absolute number of files open is what your OS limits on, not how large those files are.
Upvotes: 2