Возможно, у вас возникло желание, например, при просмотре фото в своей папке перемешать их, смотреть их в случайном порядке. Т.к. (как минимум на Windows 7) возможно только отсортировать файлы по их имени, размеру и т.д., я решил создать программу, для перемешивания нужных файлов.
Принцип ее работы:
Переименовывание всех файлов в папке (кроме других папок, находящихся внутри), выбранной пользователем: в случайном порядке присваиваются имена 0, 1, 2… Таким образом, при сортировки файлов по имени получается случайная последовательность.
Разберем же код этой программы (он, кстати, написан на Python 3+). Если есть желание скачать эту программу в расширении .pyw и .exe, то вот ссылки
pyw файл
exe файл.
Итак, для работы нам понадобится импортировать несколько модулей.
import os
import random
from tkinter import *
from tkinter.filedialog import *
Переместимся в конец. Здесь мы прорабатываем оконное приложение, чтобы пользователю было удобнее работать.
root = Tk()
root.geometry('200x100')
root.title('Mix')
pth = Label(root, text = '"Выбранный путь"', font = ('Times', 15))
bt = Button(root, text = "Выбрать папку", command = FoldChoose)
bt2 = Button(root, text = "Перемешать", command = Shuf)
pth.pack()
bt.pack()
bt2.pack()
root.mainloop()
Первая кнопка отвечает за выбор директории, вторая — за само перемешивание всех внутренних файлов (кроме папок). Последняя не будет работать, пока не будет выбрана нужная директория.
В первой кнопке присутствует функция. Разберем ее:
def FoldChoose():
try:
global vvd
#запрашивание папки
vvd = askdirectory()
pth.config(text = vvd)
global msv
msv = os.listdir(path = vvd)
#перемешивание массива
random.shuffle(msv)
if len(vvd) > 20:
s = (len(vvd) - 20) * 10 + 200
root.geometry(str(s) + 'x100')
except Exception:
return
При нажатии на кнопку будет всплывать диалоговое окно для выбора нужной директории. Этот путь отобразится в label'е. После, благодаря прекрасной функции os.listdir(), все содержимое папки заносится в массив msv, после перемешивается. Если путь перестает вмещаться в окно, это окно расширяется до нужных размеров. Если произойдет исключение (например, пользователь ничего не выберет и просто закроет диалоговое окно), то произойдет выход из функции и ничего не поменяется.
Функция второй кнопки, перемешивание:
def Shuf():
#если вдруг будет папка с названием вспомогательной папки
if (os.path.exists(vvd + "/DelThisFold") == True) and (vvd != ''):
pth.config(text = 'Пожалуйста, удалитеnпапку DelThisFold')
return
try:
#создание вспомогательной папки для избежания конфликтов имен
os.mkdir(vvd + "/DelThisFold")
except Exception:
return
#переименовывание файлов, перемещая их во вспомогательную папку
for i in range(len(msv)):
frmt = msv[i].split('.')
g = len(frmt) - 1
if g != 0:
os.rename(vvd + "/" + str(msv[i]),
vvd + "/DelThisFold/" + str(i) + '.' + frmt[g])
elif os.path.exists(vvd + "/" + str(msv[i])) == True:
pass
else:
os.rename(vvd + "/" + str(msv[i]),
vvd + "/DelThisFold/" + str(i))
#новый массив файлов с измененными именами
lst = os.listdir(path= vvd + "/DelThisFold")
#перемещение файлов в их начальную папку
for j in range(len(lst)):
os.rename(vvd + "/DelThisFold/" + str(lst[j]),
vvd + "/" + str(lst[j]))
#удаление вспомогательной папки
os.rmdir(vvd + "/DelThisFold")
#окно выхода
root.destroy()
qt = Tk()
qt.geometry('200x120')
qt.title('Готово!')
qt_txt = Label(qt, text = "Перемешиваниеnзавершено",font = ('Times', 15))
knpk = Button(qt, text = 'OK', command = qt.destroy, width = 15)
qt_txt.pack()
knpk.pack()
Да, она огромна. Что ж, мы имеем перемешанный массив файлов папки. Чтобы избежать конфликта имен, нам нужно создать временную вспомогательную папку DelThisFold. В нее мы будем перекидывать только что переименованные файлы. Если вдруг папка с таким именем уже существует, то программа попросит пользователя удалить эту папку.
#если вдруг будет папка с названием вспомогательной папки
if (os.path.exists(vvd + "/DelThisFold") == True) and (vvd != ''):
pth.config(text = 'Пожалуйста, удалитеnпапку DelThisFold')
return
try:
#создание вспомогательной папки для избежания конфликтов имен
os.mkdir(vvd + "/DelThisFold")
except Exception:
return
Теперь нам нужно каким-то образом сохранить расширения файлов при перемещении, а также игнорировать папки. Для этого создается переменная frmt, в которую записывается формат текущего файла. Если у файла нет расширения, то мы проверяем, папка ли это. Если это не папка, то это просто файл без расширения, который, как и файлы с расширениями, переносится во вспомогательную папку и переименовывается. Имя берется из переменной цикла.
#переименовывание файлов, перемещая их во вспомогательную папку
for i in range(len(msv)):
frmt = msv[i].split('.')
g = len(frmt) - 1
if g != 0:
os.rename(vvd + "/" + str(msv[i]),
vvd + "/DelThisFold/" + str(i) + '.' + frmt[g])
elif os.path.exists(vvd + "/" + str(msv[i])) == True:
pass
else:
os.rename(vvd + "/" + str(msv[i]),
vvd + "/DelThisFold/" + str(i))
После переноса и переименовывания всех файлов, эти файлы вновь заносятся в новый массив. Далее они перемещаются в изначальную папку, а после вспомогательная папка удаляется.
#новый массив файлов с измененными именами
lst = os.listdir(path= vvd + "/DelThisFold")
#перемещение файлов в их начальную папку
for j in range(len(lst)):
os.rename(vvd + "/DelThisFold/" + str(lst[j]),
vvd + "/" + str(lst[j]))
#удаление вспомогательной папки
os.rmdir(vvd + "/DelThisFold")
В конце создается новое окно, уведомляющее пользователя о конце работы программы (предыдущее окно уничтожается).
#окно выхода
root.destroy()
qt = Tk()
qt.geometry('200x120')
qt.title('Готово!')
qt_txt = Label(qt, text = "Перемешиваниеnзавершено",font = ('Times', 15))
knpk = Button(qt, text = 'OK', command = qt.destroy, width = 15)
qt_txt.pack()
knpk.pack()
Скорее всего, этот код можно было написать лучше. Но я все же надеюсь, что информация, данная мною выше, и сама программа были хоть кому-то полезны.
Автор: Леонид Якубович