Search code examples
rubypython-3.xmoveshutil

Python - Round Robin file move


I am trying to create a Python script that moves files in a round robin into a DIR that has the least amount of files in it so that the files are equally distributed for the source DIR to the two target DIR's.

For example:

If c:\test contains:

test_1.txt test_2.txt test_3.txt test_4.txt

I want these test_1.txt and test_3.txt to be moved to c:\test\dir_a and test_2.txt and test_4.tx to be moved to c:\test\dir_b.

I have been able to successfully do this in Ruby, however when i try to do this in Python when the script runs it moves all the files into the DIR with the least least amount of files in it instead of distributing them in a round robin.

Here is my Ruby example:

require 'fileutils'

def check_file

watchfolder_1 = 'F:/Transcoder/testing/dir_a/'
watchfolder_2 = 'F:/Transcoder/testing/dir_b/'

if !Dir.glob('F:/Transcoder/testing/prep/*.txt').empty?

    Dir['F:/Transcoder/testing/prep/*.txt'].each do |f|

        node_1 = Dir["#{watchfolder_1}"+'*']
        node_2 = Dir["#{watchfolder_2}"+'*']

        nc_1 =  node_1.count
        nc_2 =  node_2.count

        loadmin =[nc_1,nc_2].min

        #puts loadmin

        if loadmin == nc_1

            FileUtils.mv Dir.glob("#{f}"), watchfolder_1

            puts "#{f} moved to DIR A"

        elsif loadmin == nc_2

            FileUtils.mv Dir.glob("#{f}"), watchfolder_2

            puts "#{f} moved to DIR B"

        end

        puts 'Files successfully moved to staging area.'

    end

    else
       puts 'No valid files found'
    end
end
check_file

This outputs the following:

C:\Ruby22-x64\bin\ruby.exe -e  $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)
F:/ruby/transcode_engine/test.rb
F:/Transcoder/testing/prep/test_1.txt moved to DIR A
Files successfully moved to staging area.
F:/Transcoder/testing/prep/test_2.txt moved to DIR B
Files successfully moved to staging area.
F:/Transcoder/testing/prep/test_3.txt moved to DIR A
Files successfully moved to staging area.
F:/Transcoder/testing/prep/test_4.txt moved to DIR B
Files successfully moved to staging area.

The files move as I want them to.

Now here is my Python script:

import shutil
from glob import glob
import os.path


dir_a = os.listdir('F:\\Transcoder\\testing\\dir_a\\')
dir_b = os.listdir('F:\\Transcoder\\testing\\dir_b\\')
t_a = 'F:\\Transcoder\\testing\\dir_a\\'
t_b = 'F:\\Transcoder\\testing\\dir_b\\'


if os.listdir('F:\\Transcoder\\testing\\prep\\'):

    prep = glob('F:\\Transcoder\\testing\\prep\\*.txt')

    for file in prep:

        ac = len(dir_a)
        bc = len(dir_b)

        load = [ac, bc]

        if min(load) == ac:

            print('Moving' + file + 'to DIR A')
            shutil.move(file, t_a)

        elif min(load) == bc:

            print('Moving' + file + 'to DIR B')
            shutil.move(file, t_b)

else:
    print('No Files')

This script returns this:

C:\Users\3A01\AppData\Local\Programs\Python\Python35-32\python.exe   
F:/Projects/python_transcoder/test_2.py
Moving F:\Transcoder\testing\prep\test_1.txt to DIR A
Moving F:\Transcoder\testing\prep\test_2.txt to DIR A
Moving F:\Transcoder\testing\prep\test_3.txt to DIR A
Moving F:\Transcoder\testing\prep\test_4.txt to DIR A

Where am I going wrong with the Python script, why is it not moving the files in a round robin?


Solution

  • dir_a and dir_b are computed at the start of your script so the load is always identical even if you move files in your loop.

    Move this in your for loop:

    dir_a = os.listdir(r'F:\Transcoder\testing\dir_a')
    dir_b = os.listdir(r'F:\Transcoder\testing\dir_b')
    

    fox proposal (with some other small fixes as well, like not repeating paths and using "raw" prefix (r"the\data") to avoid escaping the antislashes.

    import shutil
    from glob import glob
    import os.path
    
    
    t_a = r'F:\Transcoder\testing\dir_a'
    t_b = r'F:\Transcoder\testing\dir_b'
    
    prep = glob('F:\\Transcoder\\testing\\prep\\*.txt')
    if prep:        
    
        for file in prep:
    
            dir_a = os.listdir(t_a)
            dir_b = os.listdir(t_b)
            ac = len(dir_a)
            bc = len(dir_b)
    
            load = [ac, bc]
    
            if min(load) == ac:
    
                print('Moving' + file + 'to DIR A')
                shutil.move(file, t_a)
    
            else:
    
                print('Moving' + file + 'to DIR B')
                shutil.move(file, t_b)
    
    else:
        print('No Files')