3
\$\begingroup\$

My code works, but it looks very bad.

I need to move .xlsx files from the previous days from one folder to another, but I should'nt move the files with today's date, just the files from previous days.

In my current code, I am moving the files by specifying each one of them with a Minus X days, but I think the code is not in the best 'shape' nor the best performance/quality.

Any one can help me improve it?

import datetime,os, glob, shutil
from pathlib import Path

dir_carteiras = r"C:\Users\GuilhermeMachado\Documents\Carteiras"
test = os.listdir(dir_carteiras)

for item in test:
    if item.endswith(".jpg"):
        os.remove( os.path.join(dir_carteiras, item))

#get todays  date and a calculation for today -1 day
today=datetime.date.today()
minus_one_day=datetime.timedelta(days=-1)

#use the calculation to get previous 5 days strings
d_N1=today+minus_one_day
d_N1_ = d_N1.strftime('%Y.%m.%d')
d_N2=d_N1+minus_one_day
d_N3=d_N2+minus_one_day
d_N4=d_N3+minus_one_day
d_N5=d_N4+minus_one_day

#format dates for the files formats
Date_Carteira_N1 = d_N1.strftime('%d_%m_%Y')
Date_Carteira__0 = today.strftime('%d_%m_%Y')
Date_Carteira_N2 =d_N2.strftime('%d_%m_%Y')
Date_Carteira_N3 =d_N3.strftime('%d_%m_%Y')
Date_Carteira_N4 =d_N4.strftime('%d_%m_%Y')
Date_Carteira_N5 =d_N5.strftime('%d_%m_%Y')
Alocacao_0 = today.strftime('%Y%m%d')
Alocacao_N1 = d_N1.strftime('%Y%m%d')
Alocacao_N2 = d_N2.strftime('%Y%m%d')
Alocacao_N3 = d_N3.strftime('%Y%m%d')
Alocacao_N4 = d_N4.strftime('%Y%m%d')
Alocacao_N5 = d_N5.strftime('%Y%m%d')

#folder destination
NewFolderPath = dir_carteiras+"\Historico"
Path(NewFolderPath).mkdir(parents=True, exist_ok=True)

#Move the "Carteira" files from previous 5 days
Carteiras_move_N1 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Date_Carteira_N1+'.xlsx', recursive=True)
for f in Carteiras_move_N1:
        shutil.move(f,NewFolderPath)
Carteiras_move_N2 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Date_Carteira_N2+'.xlsx', recursive=True)
for f in Carteiras_move_N2:
        shutil.move(f,NewFolderPath)
Carteiras_move_N3 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Date_Carteira_N3+'.xlsx', recursive=True)
for f in Carteiras_move_N3:
        shutil.move(f,NewFolderPath)
Carteiras_move_N4 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Date_Carteira_N4+'.xlsx', recursive=True)
for f in Carteiras_move_N4:
        shutil.move(f,NewFolderPath)
Carteiras_move_N5 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Date_Carteira_N5+'.xlsx', recursive=True)
for f in Carteiras_move_N5:
        shutil.move(f,NewFolderPath)

#Move the "Alocacao" files from the previous 5 days
Alocacao_move_N1 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Alocacao_N1+'.xlsx', recursive=True)
for f in Alocacao_move_N1:
        shutil.move(f,NewFolderPath)
Alocacao_move_N2 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Alocacao_N2+'.xlsx', recursive=True)
for f in Alocacao_move_N2:
        shutil.move(f,NewFolderPath)
Alocacao_move_N3 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Alocacao_N3+'.xlsx', recursive=True)
for f in Alocacao_move_N3:
        shutil.move(f,NewFolderPath)
Alocacao_move_N4 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Alocacao_N4+'.xlsx', recursive=True)
for f in Alocacao_move_N4:
        shutil.move(f,NewFolderPath)
Alocacao_move_N5 = glob.glob(r'C:\Users\GuilhermeMachado\Documents\Carteiras\*'+Alocacao_N5+'.xlsx', recursive=True)
for f in Alocacao_move_N5:
        shutil.move(f,NewFolderPath)
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

First, if you are using Python 3, you can use pathlib to make your life regarding paths a lot easier (especially if you want your scripts to work on both Windows and Linux). If you are not using Python 3 by now, well, you should.

While your approach works (and could be made a bit shorter maybe using a complex RegEx), you might want to look into different methods of doing this. Instead of manually using the format of your file names, you can use the time the file was last modified (or accessed) and just filter on that:

from datetime import datetime, timedelta
from pathlib import Path
import shutil
from typing import Iterable

def old_files(dir: Path, pattern: str, start: int = -5, end: int = -1) -> Iterable[Path]:
    """List all files in `dir` matching `pattern` modified between
    `start` and `end` (both inclusive) days from today.
    """
    today = datetime.today()
    start = (today.replace(hour=0, minute=0, second=0, microsecond=0)
             + timedelta(days=start)).timestamp()
    end = (today.replace(hour=23, minute=59, second=59, microsecond=999999)
           + timedelta(days=end)).timestamp()
    return (file for file in dir.glob(pattern)
            if file.is_file() and start <= file.stat().st_mtime <= end)

Which you can use like this:

if __name__ == "__main__":
    dir = Path(r"C:\Users\GuilhermeMachado\Documents\Carteiras")
    new_dir = dir / "Historico/"
    new_dir.mkdir(exist_ok=True)
    for file in old_files(dir, "*.xlsx", start=-5, end=-1)
        shutil.move(str(file), new_dir)

Note that I used the fact that when you divide a path by a string (`dir / "Historico") it just joins the path (with the correct path separator depending on your OS).

I also added a if __name__ == "__main__": guard to allow importing from this script without the code running, made the number of days to select parameters of a function to which I also added typing hints and a docstring and followed Python's official style-guide, PEP8, by having spaces around the = for assignments.

Of course this assumes that you have no other Excel spreadsheets modified during the last five days in that folder. In that case you might be able to adapt the pattern to only match the files you want, or you will have to use a different method for filtering the files. But that would just mean modifying the function, not your whole script. This way the changes are localized, which makes it easier to track.

\$\endgroup\$
8
  • \$\begingroup\$ "The preferred way of wrapping long lines is by using Python's implied line continuation inside parentheses, brackets and braces." - PEP 8. Interesting, could this have time-zone problems? \$\endgroup\$
    – Peilonrayz
    Commented Mar 13, 2020 at 16:05
  • \$\begingroup\$ @Peilonrayz: That would mean another set of parenthesis... Regarding the timezones: I'm not sure what happens if your internal system clock is automatically set, you modify a file, move to a different timezone and then run this script. But I think the data is saved in UTC time and using timestamps this should be true also for start and end. \$\endgroup\$
    – Graipher
    Commented Mar 13, 2020 at 16:08
  • \$\begingroup\$ @Peilonrayz: Got it using only one set of parenthesis by moving stuff around :) \$\endgroup\$
    – Graipher
    Commented Mar 13, 2020 at 16:10
  • \$\begingroup\$ @Peilonrayz There could be Timezone problems if the files were created by someone else, in a different timezone. Then it depends on whose definition of days you use. \$\endgroup\$
    – Graipher
    Commented Mar 13, 2020 at 16:12
  • 1
    \$\begingroup\$ Yeah, either way it's going to look bad to someone 😕 Hmm, I don't know enough, about FS stats. Eh 🤷‍♀️‎ \$\endgroup\$
    – Peilonrayz
    Commented Mar 13, 2020 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.