Miscellaneous programs and tools I recently made for personal use.
--Small and simple articles that are not enough to stand individually. --Language is Python, Powershell, Excel VBA. --The usage environment is - Windows10。 - Powershell5.1。 - Python3.7.0。 - Office2016。
https://github.com/dede-20191130/CreateToolAndTest
1.Python
If you don't consciously organize folders with names like old, they will be stored forever. I wanted to declutter.
Crean_OldNamed_Folders.py
import glob
import os
import tkinter as tk
import tkinter.simpledialog as sim
from tkinter import messagebox
import send2trash
def Main():
root = tk.Tk()
root.withdraw()
tmpPath = sim.askstring("old folder search folder specification", "Please specify the folder path to search the old folder", initialvalue="")
if tmpPath not in (None, ''):
ThrowAwayOld(tmpPath)
def ThrowAwayOld(baseFolderPath):
"""Recursively search for old folders and send their contents to the trash"""
if not os.path.isdir(baseFolderPath):
messagebox.showerror("error", "A folder path that does not exist.")
exit(1)
rmNum = 0
for f in glob.glob(baseFolderPath + '\\**', recursive=True):
if os.path.isdir(f) and os.path.basename(f).lower() in ('old', 'old', 'Old'):
send2trash.send2trash(os.path.abspath(f))
rmNum += 1
messagebox.showinfo("Successful completion", "The process is complete.\n" + str(rmNum) + "I sent the old folders to the Trash.")
if __name__ == '__main__':
Main()
for f in glob.glob(baseFolderPath + '\\**', recursive=True):
if os.path.isdir(f) and os.path.basename(f).lower() in ('old', 'old', 'Old'):
send2trash.send2trash(os.path.abspath(f))
rmNum += 1
Recursive file search is possible by setting recursive in the glob.glob function.
Send the folder containing words such as "old" and "old" to the trash.
I wanted to put a cushion in the form of sending it to the trash can because it cannot be restored when it is removed.
When publishing the source code to SNS such as Qiita, I somehow didn't want to include my personal file path or filename. Therefore, I created a program that can replace file paths at once.
ChangePrivatePathsOfText.py
import os
import pathlib
import re
import chardet
def Main():
with pathlib.Path(os.getenv("HOMEDRIVE") + os.getenv(
"HOMEPATH") + r'\PycharmProjects\CreateToolAndTest\PrivateTool\ChangedString.txt') as pp:
#Detect character code
with open(pp.absolute(), "rb") as f:
temp = chardet.detect(f.read())['encoding']
#Input characters
allText = pp.read_text(encoding=temp)
# ///Regular expression replacement
#File path replacement
allText = re.sub(r'"[a-zA-Z]:[\\/].*\.', r'"C:/Users/UserName/MyFolder/Foo.', allText)
allText = re.sub(r"'[a-zA-Z]:[\\/].*\.", r"'C:/Users/UserName/MyFolder/Foo.", allText)
#Replace folder path
allText = re.sub(r'"[a-zA-Z]:[\\/](?!.*\.).*"',r'"C:/Users/UserName/MyFolder/Foo."',allText)
allText = re.sub(r"'[a-zA-Z]:[\\/](?!.*\.).*'",r"'C:/Users/UserName/MyFolder/Foo.'",allText)
#Output after replacement
pp.write_text(allText, encoding=temp)
if __name__ == '__main__':
Main()
Using the read_text / write_text functions and with syntax of the pathlib module File input / output is simplified.
#Detect character code
with open(pp.absolute(), "rb") as f:
temp = chardet.detect(f.read())['encoding']
#Input characters
allText = pp.read_text(encoding=temp)
The entire character string is read using the character code detected in advance.
# ///Regular expression replacement
#File path replacement
allText = re.sub(r'"[a-zA-Z]:[\\/].*\.', r'"C:/Users/UserName/MyFolder/Foo.', allText)
allText = re.sub(r"'[a-zA-Z]:[\\/].*\.", r"'C:/Users/UserName/MyFolder/Foo.", allText)
#Replace folder path
allText = re.sub(r'"[a-zA-Z]:[\\/](?!.*\.).*"',r'"C:/Users/UserName/MyFolder/Foo."',allText)
allText = re.sub(r"'[a-zA-Z]:[\\/](?!.*\.).*'",r"'C:/Users/UserName/MyFolder/Foo.'",allText)
Regarding the file path,
--First starts with "" "or"'" --Next comes the alpha bed character +: + (either \ or /) --Finally, "." Comes
Regular expression substitution is used under the condition.
Regarding the folder path,
--First starts with "" "or"'" --Next comes the alpha bed character +: + (either \ or /) --Does not include "." Characters after that --Ends with "" "or"'"
Regular expression substitution is used under the condition.
Almost the same as 1-2
ChangeURLPartsOfText.py
import os
import pathlib
import re
import chardet
def Main():
with pathlib.Path(os.getenv("HOMEDRIVE") + os.getenv(
"HOMEPATH") + r'\PycharmProjects\CreateToolAndTest\PrivateTool\ChangedString.txt') as pp:
#Detect character code
with open(pp.absolute(), "rb") as f:
temp = chardet.detect(f.read())['encoding']
#Input characters
allText = pp.read_text(encoding=temp)
# print(allText)
#Regular expression replacement
allText = re.sub(r'"https?://.*"', r'"http://foobar.com"', allText)
allText = re.sub(r"'https?://.*'", r"'http://foobar.com'", allText)
#Output after replacement
pp.write_text(allText, encoding=temp)
if __name__ == '__main__':
Main()
#Regular expression replacement
allText = re.sub(r'"https?://.*"', r'"http://foobar.com"', allText)
allText = re.sub(r"'https?://.*'", r"'http://foobar.com'", allText)
It supports character strings enclosed in both single quotes and double quotes.
The message box display of python is Since various preparations such as setting the root frame are troublesome I wanted to be able to display a message with a single call to a static method.
TkHandler_MsgBox_1.py
import tkinter as tk
from tkinter import messagebox
class TkHandler_MsgBox_1:
"""
Message box handling class_1
"""
def __init__(self):
self.root = tk.Tk()
self.root.withdraw()
def __del__(self):
self.root.destroy()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
def normalMsgBox(self, title='message', content='ここにmessageが表示されます。'):
messagebox.showinfo(title, content)
def errorMsgBox(self, title='error', content='errorが発生しました。'):
messagebox.showerror(title, content)
@staticmethod
def showStandardMessage(title, content, isError=False, errorTitle=None, errorContent=None):
"""
Used when displaying a message in standard usage.
Release the Tk object immediately without reusing it.
:arg
(error)title:(error)title
(error)content:(error)Message content
isError:If an error occurs, an error message will be displayed.
"""
with TkHandler_MsgBox_1() as objMsg:
myTitle = title if not isError else errorTitle
myContent = content if not isError else errorContent
calledFunc = objMsg.normalMsgBox if not isError else objMsg.errorMsgBox
calledFunc(title=myTitle, content=myContent)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
The above is the context manager when using the with syntax. Reference: https://python.keicode.com/lang/context-manager.php
I will not do anything this time.
def normalMsgBox(self, title='message', content='ここにmessageが表示されます。'):
messagebox.showinfo(title, content)
def errorMsgBox(self, title='error', content='errorが発生しました。'):
messagebox.showerror(title, content)
When each is called, a message is displayed under the conditions set in the argument. This time, only the functions corresponding to the information message and error message are implemented.
myTitle = title if not isError else errorTitle
myContent = content if not isError else errorContent
calledFunc = objMsg.normalMsgBox if not isError else objMsg.errorMsgBox
calledFunc(title=myTitle, content=myContent)
Conditionally branch a variable with a ternary operator according to the value of isError.
The final function calledFunc will be either normalMsgBox or errorMsgBox.
Use it like this. It can be called in one line without the need to set the root frame.
from Commons.TkHandler_MsgBox_1 import TkHandler_MsgBox_1
TkHandler_MsgBox_1.showStandardMessage('Processing completed', 'The file move is complete.')
Photos taken with a smartphone etc. I wanted to move it to both the pictures on my PC and the G drive folder.
CopyPicsToFolders.py
import glob
import os
import sys
#Reset module search path
#Make it possible to start by double-clicking
sys.path.append(os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + r"\PycharmProjects\CreateToolAndTest")
import shutil
import send2trash
# Common parts in dede-20191130's GitHub
# https://github.com/dede-20191130/CreateToolAndTest
from Commons.TkHandler_MsgBox_1 import TkHandler_MsgBox_1
def Main():
isSuccess = True
try:
mySrcPath = r'C:/Users/UserName/MyFolder/Foo'
myDestpathList = [r'C:/Users/UserName/MyFolder/Bar', r'C:/Users/UserName/MyFolder/Dede']
movedFileList = []
#Get all image files directly under the specified folder
if os.path.isdir(mySrcPath):
for file in glob.glob(mySrcPath + '\\*', recursive=False):
if os.path.isfile(file):
movedFileList.append(file)
else:
print('No Directory')
exit(0)
#Copy to specified output destination folder
for dst in myDestpathList:
[shutil.copy(os.path.abspath(file2), dst) for file2 in movedFileList]
except:
isSuccess = False
finally:
if isSuccess:
TkHandler_MsgBox_1.showStandardMessage('Processing completed', 'The file move is complete.')
for file in glob.glob(mySrcPath + '\\*', recursive=False):
send2trash.send2trash(os.path.abspath(file))
if __name__ == '__main__':
Main()
except:
isSuccess = False
finally:
if isSuccess:
TkHandler_MsgBox_1.showStandardMessage('Processing completed', 'The file move is complete.')
for file in glob.glob(mySrcPath + '\\*', recursive=False):
send2trash.send2trash(os.path.abspath(file))
If you don't catch the exception Display a message assuming that it is a normal judgment, Send the files in the original folder to the Trash.
If you get the time at the nanosecond level Is it possible to get random numbers at the human experience level? I made it.
DiceAppWithoutRandomLibrary.py
import time
import tkinter as tk
from tkinter import messagebox
def diceResult():
#Random variable acquisition depending on the time (in human experience time)
temp = int((time.time_ns() % 100000000) / 100)
#Get the remainder divided by 6
myTempRmd = temp % 6
if myTempRmd == 0:
myTempRmd = 6
return myTempRmd
if __name__ == '__main__':
#Get dice results
result = diceResult()
#Displayed as a message as a result of rolling the dice
root = tk.Tk()
root.withdraw() #Don't show small windows
messagebox.showinfo("Dice", "The result is" + str(result) + "is")
2.Powershell
before sleep, When I try to sleep after transferring files to G drive You have to wait for the transfer to complete. I created a script to put it to sleep after some time (after the transfer is complete).
hibernationTimer.ps1
Param(
[long]$waitTime = 300 #Wait time (s)
)
sleep $waitTime
#Hibernate
shutdown -h
#Close only the console window that executed this script (PID is an automatic variable that sets the process ID of the running PowerShell)
Stop-Process -Id $PID
Specify the number of seconds specified in the argument (default is 300 seconds) Run on the console.
Automatically closes the console screen when entering hibernation.
If you can start with the folders that you always compare (old and new project folders, etc.) compared Created thinking that it is not necessary to specify it on the folder specification screen each time.
Add the following to the Powershell profile file.
powershell:Microsoft.PowerShellISE_profile.ps1
Sal wmg C:\Tool_nonInstall\winmerge-2.16.4-x64-exe\WinMerge\WinMergeU.exe
function wtmp() {
wmg $HOME\Documents\Dif_1 $HOME\Documents\Dif_2
}
When you run "wtmp" on the console Start WinMerge with Dif_1 and Dif_2 compared.
3.ExcelVBA
When handing an Excel book to the other party The sheet is the leftmost sheet, Some people complain that the cursor isn't pointing to cell A1.
A tool to prevent such people from saying anything.
tool
'******************************************************************************************
'*Function name: formatForSubmission
'*Function: You can do it quickly when you need to arrange the appearance when submitting an Excel book to the other party.
'Move the cursor of all sheets to the upper left cell (A1 cell) and make the leftmost sheet active.
'*argument(1):None
'******************************************************************************************
Public Sub formatForSubmission()
'constant
Const FUNC_NAME As String = "formatForSubmission"
'variable
Dim cntObj As Object 'Loop counter
On Error GoTo ErrorHandler
'---Describe the process below---
'Move the cursor of all sheets to the upper left cell (A1 cell)
For Each cntObj In Worksheets
'Skip hidden cells
If cntObj.Visible = True Then
cntObj.Select
cntObj.Range("A1").Select
End If
Next
'Select the lowest numbered visible sheet
For Each cntObj In Worksheets
If cntObj.Visible = True Then
cntObj.Select
Exit For
End If
Next
ExitHandler:
Exit Sub
ErrorHandler:
MsgBox "An error has occurred, so exit" & _
vbLf & _
"Function name:" & FUNC_NAME & _
vbLf & _
"Error number" & Err.Number & Chr(13) & Err.Description, vbCritical
GoTo ExitHandler
End Sub
When creating markdown text Insert quotation marks ">" and strikethrough decoration "(before and after sentences) ~" I wanted a tool that would make it easy.
tool
'For a particular object or value
'Represents the position to perform function processing
Public Enum ProcessingPosition
Front = 1
Back = 2
Both = 3
End Enum
'******************************************************************************************
'*Function name: insertStrToSelection
'*Function: Inserts a character string at the specified position of the value of all cells in the selected range.
'*Designated position: Front / rear or both front and back
'*argument(1):None
'******************************************************************************************
Public Sub insertStrToSelection()
'constant
Const FUNC_NAME As String = "insertStrToSelection"
'variable
Dim insertedStr As String
Dim insertPosition As Long
Dim positionStr As String
Dim cnt As Variant
On Error GoTo ErrorHandler
'---Describe the process below---
'◆◆◆ Where to insert characters: Change here for each purpose of use.
insertPosition = ProcessingPosition.Back
'◆◆◆◆◆
'Express the insertPosition with characters
Select Case insertPosition
Case ProcessingPosition.Front
positionStr = "Before the value"
Case ProcessingPosition.Back
positionStr = "Behind the value"
Case Else
positionStr = "Both before and after the value"
End Select
'Enter the insertion string
insertedStr = InputBox("Please enter the character string to be inserted here." & _
vbNewLine & _
"The current insertion position is [" & _
positionStr & _
"】is.", "Specify the character string to insert", "")
'Insert a string into the value of each cell
For Each cnt In Selection
Select Case insertPosition
Case ProcessingPosition.Front
cnt.Value = insertedStr & cnt.Value
Case ProcessingPosition.Back
cnt.Value = cnt.Value & insertedStr
Case Else
cnt.Value = insertedStr & cnt.Value & insertedStr
End Select
Next
ExitHandler:
Exit Sub
ErrorHandler:
MsgBox "An error has occurred, so exit" & _
vbLf & _
"Function name:" & FUNC_NAME & _
vbLf & _
"Error number" & Err.Number & Chr(13) & Err.Description, vbCritical
GoTo ExitHandler
End Sub