Lewis909 Lewis909 - 1 month ago 17
Ruby Question

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?

Answer

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)

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')