💡

8/17の記事と8/25の記事の処理をまとめました!!

2023/08/31に公開
1

気に入っていただけた方は、ぜひ

  • 「バッジ」の贈呈
  • X(Twitter)のフォロー

よろしくお願いします!!

X(Twitter)のアカウントはこちら

https://twitter.com/0ca00118726208m


目次

はじめに
作成した経緯
ソースコード
結果
工夫した点
まとめ

はじめに

8/17の記事はこちらです

https://zenn.dev/blueman/articles/0c74c460ae53d0

この記事では、日付を条件としてフォルダにファイルを振り分けていました。

一方で、8/25の記事はこちらです

https://zenn.dev/blueman/articles/bb11f8929a0dad

この記事では、ファイルの拡張子を条件としてフォルダにファイルを振り分けていました。

今回は、この2つの記事の処理を統合させて日付&ファイルの拡張子を条件としてフォルダにファイルを振り分けることができたので紹介したいと思います。


よろしければこちらもどうぞ!!

マイページについて

https://qiita.com/blueman


X(Twitter)について

https://twitter.com/0ca00118726208m


Qiitaについて

作成した経緯

GitHubのディレクトリの階層は次の通りです!!

GitHubディレクトリ
GitHubのディレクトリ

画像のように日付(画像だと7_28) のディレクトリの中にソースコード(拡張子が.pyのもの)result(結果と素材が入っているディレクトリ) があります。

  • 8/17の記事では、この画像の階層での7_28の中身を作る処理
  • 8/25の記事ではこの画像の階層でのソースコードresultディレクトリの振り分け

を実装していました!!
今回は、8/17の記事8/25の記事を統合させることでよりGitHubのディレクトリに近いフォルダを作成していきたいと考え作成しました。

ソースコード

下にソースコードを示します。おそらく8/17の実行環境
8/25の実行環境で示した環境では動くはず。

ソースコード
data_separate.py
import glob
import os                                                                                             #ファイル操作のためにインポート
import datetime                                                                                       #ファイルの更新月日を取得するためにインポート
from tkinter import *                                                                                 #tkinterライブラリのすべてのモジュールをインポート
from tkinter import filedialog
from tkcalendar import DateEntry                                                                      #tkcalendarの入力を取得するためにインポート

dir = filedialog.askdirectory(initialdir='C:\\')                                                      #-*追加部分*-フォルダの指定(tkinter.filedialogを使ったフォルダダイアログで指定(初期フォルダをC:\としている))

root=Tk()                                                                                             #tkinterのセットアップ
root.title("カレンダー")                                                                              #「カレンダー」という名前のウインドウを作成

date_form = DateEntry(locale='ja_JP')                                                                 #tkcalendarをデータ取得用のカレンダー形式の要素(ウィジェット)を作成(locale='ja_JP'と指定することで日本語形式で設定)

def func(event):                                                                                      #tkinterの処理関数を定義
	date_get = date_form.get_date()                                                                   #tkcalendarから日付を取得
	month = date_get.month                                                                            #date_get中の月(month)の部分を取得
	day = date_get.day                                                                                #date_get中の日(day)の部分を取得
	files=os.listdir(dir)                                                                             #「python」フォルダの中のすべてのファイル一覧を取得
	for file in files:                                                                                #すべてのファイルについて処理を実行
		date = datetime.datetime.fromtimestamp(os.path.getmtime(dir+"/"+file))                        #最終更新日時をタイムスタンプ形式で取得
		if ((date.month == month-1 and date.day > day) or (date.month == month and date.day <= day)):
			'''
			date中の月(date.month)がdate_get中の月(month)-1でありdate中の日(date.day)がdate_get中の日(day)より大きいか、date中の月(date.month)がdate_get中の月(month)であり
			date中の日(date.day)がdate_get中の日(day)以下である場合
			ex)
			「8」月「2」日と入力された場合 → 「7」月「3」日以降から「8」月「2」日まで
			※この処理だと順番に日付を指定しないとすべてのデータが指定した日付のフォルダに格納されてしまうという問題が発生する
			'''
			os.makedirs(dir+"/"+str(month)+"_"+str(day),exist_ok=True)                                #フォルダが存在しない場合には、指定した日付のフォルダを「python」フォルダの下に配置
			if(os.path.isfile(dir+"/"+file)):                                                         #上のフォルダがある場合に処理を実行
				os.rename(dir+"/"+file,dir+"/"+str(month)+"_"+str(day)+"/"+file)                      #条件に一致したファイル(指定した日付までのファイル)を作成したフォルダ
				                                                                                      #(指定した日付のフォルダ)の配下に移動させる

date_form.bind("<<DateEntrySelected>>",func)                                                          #tkcalendarでのカレンダーで任意の日付が押されたときに処理関数(func)を実行

date_form.pack()                                                                                      #カレンダー形式で作成したウィジェット(date_form)を画面上に配置
root.mainloop()                                                                                       #GUIの表示(この処理がないと一瞬表示されて消えるので表示されていないように見える)

path_list=glob.glob(dir+'/*_*/*')                                                           #正規表現を用いて各フォルダにアクセス(「文字の真ん中に_がある」フォルダにアクセス)

for i in path_list:                                                                         #それぞれの「文字の真ん中に_がある」フォルダについて処理を実行
	file = os.path.basename(i)                                                              #フォルダ内の拡張子ありのファイル名を取得
	name = os.path.splitext(file)                                                           #ファイル名の.について文字を分割(これで拡張子を取得)

	if name[1] == ".JPG" or name[1] == ".jpg" or name[1] == ".png" or name[1]==".mp4":      #拡張子が「.JPG」、「.jpg」、「.png」、「.mp4」の場合に処理を実行
	                                                                                        #(画像ファイルか動画ファイルの場合)
		os.makedirs(os.path.dirname(i)+"/結果・素材",exist_ok=True)                         #拡張子が「.JPG」、「.jpg」、「.png」、「.mp4」であるファイルがあるフォルダ内に
		                                                                                    #「結果・素材」フォルダを(ない場合に)作成
		if(os.path.isfile(i)):                                                              #「文字の真ん中に_がある」フォルダの直下に拡張子が「.JPG」、「.jpg」、「.png」、「.mp4」
	                                                                                        #であるファイルがある場合に処理を実行
			os.rename(i,os.path.dirname(i)+"/結果・素材/"+file)                             #「文字の真ん中に_がある」フォルダの直下にある拡張子が「.JPG」、「.jpg」、「.png」、「.mp4」
			                                                                                #であるファイルを「結果・素材」フォルダ内に移動

	if name[1] == ".py":                                                                    #拡張子が「.py」の場合に処理を実行
		os.makedirs(os.path.dirname(i)+"/ソースコード",exist_ok=True)                       #拡張子が「.py」であるファイルがあるフォルダ内に「ソースコード」フォルダを(ない場合に)作成
		if(os.path.isfile(i)):                                                              #「文字の真ん中に_がある」フォルダの直下に拡張子が「.py」であるファイルがある場合に処理を実行
			os.rename(i,os.path.dirname(i)+"/ソースコード/"+file)                           #「文字の真ん中に_がある」フォルダの直下にある拡張子が「.py」であるファイルを「ソースコード」

結果

下に結果を示します。

元のフォルダ内

元のフォルダ内
元のフォルダ内


元のフォルダ内をGitHubのディレクトリのような階層にしたもの(処理実行後)がこちらです!!

処理実行後のフォルダ内

処理実行後のフォルダ内
処理実行後のフォルダ内


例えば、「7_28」 フォルダ内は次のようになります。

「7_28」フォルダ内

「7_28」フォルダ内
「7_28」フォルダ内


「ソースコード」 フォルダ内は次のようになります。

「ソースコード」フォルダ内

「ソースコード」フォルダ内
「ソースコード」フォルダ内


「結果・素材」 フォルダ内は次のようになります。

「結果・素材」フォルダ内

「結果・素材」フォルダ内
「結果・素材」フォルダ内


フォルダ内がGitHubのディレクトリの階層に近くなりました!!

工夫した点

工夫した点は次の通りです。

工夫した点
  1. filedialog.askdirectoryでの初期ディレクトリをC:\\(ローカルディスク(C:)) としている
  2. Tkinterのセットアップの前(root=Tk()の前)filedialog.askdirectoryでフォルダダイアログを表示
  3. Tkinterの処理が終わった後 に拡張子でファイルを振り分ける処理を実行
  4. filedialog.askdirectoryで得られたフォルダの階層をもとにglob.globを用いてフォルダにアクセス

それぞれの理由は次の通りです。

理由
  1. ローカルディスク(C:)とすることでデスクトップ以外にも簡単にアクセスできるようにするため
  2. filedialog.askdirectoryTkinterの処理でありroot=Tk()の中に入れると2重で処理することになってしまい filedialog.askdirectoryでフォルダダイアログを表示できない というトラブルが発生したため
  3. 日付を条件にして振り分けられたフォルダ内のすべてのファイルに対し拡張子を条件として振り分けるため
  4. Tkinterのメインループで filedialog.askdirectoryで得られたフォルダの階層 からフォルダを作っており、同一のフォルダにglob.globでアクセスするため

まとめ

今回は、8/17の記事8/25の記事を統合させた処理を紹介しました。
この記事のようなQiitaで取り上げたテーマに関連した記事も投稿予定です。
この記事が実際に役に立つかどうかは分かりませんが、誰かの役に立ってくれると嬉しいです。
次回の予定としては、Twitter(X)のアンケートでトップだった動画像処理から画像の画素ごとの補色で色変換を行いその結果とネガポジ反転から得られた結果とオリジナル画像を並べて表示させ補色による色変換とネガポジ反転の画素値によるヒストグラムを表示させるプログラムを作成できたのでそれに関する記事を投稿予定です。

Discussion