【学習ノート】Pythonオフィスオートメーション - タスク01 ファイルの自動処理とメールの自動送信

この学習プロセスでは、主にコピーではなく練習を使用し、特定の問題を解決するためにコードを手書きする過程でさまざまな基本的な操作方法を使用して習熟するように努めます。
このノートは主に、演習を解決するためにコーディングする際のアイデア、遭遇した問題、解決策を記録します。

問題 1: ランダムなクイズ問題用紙の生成
あなたはクラスに 35 人の生徒を抱える地理教師で、米国の州都に関するクイズを出題するとします。残念ながら、クラスに数人の悪い奴がいると、生徒がカンニングをしないという確信は持てません。各テストが一意になるように質問の順序を入れ替えて、他の人の回答をコピーできないようにしたいとします。もちろん、これを手作業で行うのは時間がかかり、退屈です。幸いなことに、あなたは Python についてある程度の知識を持っています。

import os
import random

#America 各州对应首府字典
capitals = {
    
    'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado': 'Denver',
'Connecticut': 'Hartford', 'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta', 'Hawaii': 'Honolulu', 'Idaho': 'Boise', 'Illinois':
'Springfield', 'Indiana': 'Indianapolis', 'Iowa': 'Des Moines', 'Kansas':
'Topeka', 'Kentucky': 'Frankfort', 'Louisiana': 'Baton Rouge', 'Maine':
'Augusta', 'Maryland': 'Annapolis', 'Massachusetts': 'Boston', 'Michigan':
'Lansing', 'Minnesota': 'Saint Paul', 'Mississippi': 'Jackson', 'Missouri':
'Jefferson City', 'Montana': 'Helena', 'Nebraska': 'Lincoln', 'Nevada':
'Carson City', 'New Hampshire': 'Concord', 'New Jersey': 'Trenton', 'New Mexico': 'Santa Fe', 'New York': 'Albany', 'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck', 'Ohio': 'Columbus', 'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem', 'Pennsylvania': 'Harrisburg', 'Rhode Island': 'Providence',
'South Carolina': 'Columbia', 'South Dakota': 'Pierre', 'Tennessee':
'Nashville', 'Texas': 'Austin', 'Utah': 'Salt Lake City', 'Vermont':
'Montpelier', 'Virginia': 'Richmond', 'Washington': 'Olympia', 'West Virginia': 'Charleston', 'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}

# 获取各州和对应首府的名称列表
questions = list(capitals.keys())
answers = list(capitals.values())

#创建存放试卷和答案的文件夹
if os.path.exists('./papers')==False:
    os.makedirs('./papers')
if os.path.exists('./keys')==False:
    os.makedirs('./keys')

#为第stu(1-35)位同学生成试卷
for stu in range(1,36):
    random.shuffle(questions)
    #新建试卷文件paper[stu]和对应答案文件key
    paper_name = 'paper['+str(stu)+'].txt'
    key_name = 'key['+str(stu)+'].txt'
    paper = open(os.path.join('./papers',paper_name),'w',encoding='utf-8')
    key = open(os.path.join('./keys',key_name),'w',encoding='utf-8')
    #向paper写入50道试题和对应选项
    for i in range(1,51):
        paper.write(str(i)+'.where is the capital of '+questions[i-1]+'?\n')  #第i个题目
        sele_num = ['A','B','C','D']                #选项序号
        selections = []                             #选项内容列表
        right_ansewer = capitals[questions[i-1]]    #正确答案
        selections.append(right_ansewer)            #将正确答案加入选项列表

        # # 在控制台输出题目和正确答案
        # print(str(i)+'.where is the capital of '+questions[i-1]+'?')
        # print('answer is:'+right_ansewer+'\n')
		
		#随机打乱答案顺序
		random.shuffle(answers)
        #添加3个随机错误答案进入选项列表
        for _ in range(0,50):
            if len(selections) == 4:
                break
            if answers[_] != right_ansewer:
                selections.append(answers[_])
        random.shuffle(selections)  #打乱答案排序
        right_ansewer_num = selections.index(right_ansewer)     #保存正确答案序号
        #输出4个选项
        for _ in range(0,4):
            paper.write(sele_num[_]+'.'+selections[_]+'\n')
        #向答案文件中写入第i题的答案
        key.write('第'+str(i)+'道题答案为:'+sele_num[right_ansewer_num]+'\t'+right_ansewer+'\n')
    #关闭试卷和答案文件
    paper.close()
    key.close()
1. トピックのアイデア:
(1) まず、質問(州名)と回答(大文字名)のリストを2つ作成します。
(2) 各テスト用紙を作成する前に、質問のリストをシャッフルし、順番に 50 個の質問を作成します。
(3) 問題が生成されるたびに、解答リストをシャッフルし、選択肢リストを作成し(4 つの解答を含み、辞書で正しいものを 1 つ見つけ、解答リストに従って間違ったものを 3 つ見つける)、選択肢リストをスクランブルします。 。
(4) 解答一覧から正解の通し番号を見つけ、該当する試験用紙の解答ファイルに記入してください。

2. ローカル パス区切り文字としてのスラッシュとバックスラッシュの使用:
(1) スラッシュ: [/] [正の傾きのスラッシュとして記録できる]      Windows でのみ使用できます
         バックスラッシュ: [\] [負の傾きのスラッシュとして記録できます]     Windows と UNIX で使用できます
(2) Python プログラミングでは、「D:/Python/data」のように、すべてのスラッシュ [/] を直接使用してアドレス パスを分割できます。これは Windows プラットフォームと UNIX プラットフォームの両方で使用できます。Windows 環境でパスをマークするためにバックスラッシュ [\] を使用する場合は、`D:\\Python\\data` のような 2 つのバックスラッシュを使用する必要があります。最初のバックスラッシュはエスケープに使用されます。

トピック 2: ランダムなクイズ ファイルの生成
ディレクトリ ツリーを探索して、特定の拡張子 (.pdf や .jpg など) を持つファイルを検索するプログラムを作成します。これらのファイルが存在する場所であれば、新しいフォルダーにコピーします。

import os
import shutil

rootPath = 'F:\\pycharm\\work\\OfficeAutomation'    #设置遍历根路径
fileType = 'txt'                                    #设置遍历文件后缀类型
destination = 'F:\\copy'                            #设置文件复制后地址
for curFolder,subFolder,files in os.walk(rootPath):
    # print('The current folder is ' + curFolder)
    for file in files:
        if(file.split('.')[-1]==fileType):
            print("copy "+os.path.join(curFolder,file)+" to "+destination+"...")
            shutil.copy(os.path.join(curFolder,file),destination)



1. トピックのアイデア:
(1) os.walk() を使用してルート ディレクトリとサブディレクトリ内の各ファイルを走査します。
(2) 文字列分割メソッド split を使用してサフィックス名を分割します。必要に応じて、shutil.copy メソッドを通じてファイルを対応するファイルにコピーします。目標位置

2. コピー先のターゲット フォルダーは、事前に手動で生成するのが最善です。そうしないと、コピー後に拡張子のない不明なドキュメントになります。
3. rootPath の下にコピー先を設定しないように注意してください。そうしないと、コピーしたばかりのファイルもスキャンされ、元の場所にコピーするときに shutil.SameFileError というエラーが報告されます。


トピック 3: 不要で巨大なファイルやフォルダーがハード ディスクのスペースを占有することは珍しくありません。コンピュータのスペースを解放したい場合は、不要な巨大ファイルを削除するのが最適です。しかし、まずそれらを見つけなければなりません。ディレクトリ ツリーをたどって、たとえば 100 MB を超える、特に大きなファイルやフォルダを探すプログラムを作成します (ファイルのサイズを取得するには、os モジュールを使用できることを思い出してください) os.path.getsize()これらのファイルの絶対パスを画面に出力します。

import os
import send2trash

rootPath = 'F:\\pycharm\\work\\OfficeAutomation'    #设置遍历根路径
threshold = pow(2,20)*100                           #删除大于阈值(100M)的文件

for curFolder,subFolder,files in os.walk(rootPath):
    for file in files:
        fileSize = os.path.getsize(os.path.join(curFolder,file))
        if(fileSize>threshold):
            print("The size of "+os.path.join(curFolder,file)+" is "+str(fileSize)+",which > "+str(threshold)+" , deleting...")
            send2trash.send2trash(os.path.join(curFolder,file))



1. トピックのアイデア:
(1) os.walk() を使用して、ルート ディレクトリおよびサブディレクトリ内の各ファイルを走査します。 (
2) os.path.getsize() メソッドを使用して、ファイル サイズと設定されたしきい値との関係を判断し、それが大きい場合は、しきい値、印刷および削除

2. os.path.getsize()メソッドで取得するファイルサイズの単位はByteですが、通常は1MB = 2^10KB = 2 ^20Byteを使用しますので、比較する際は換算関係に注意してください。


トピック 4: フォルダー内の指定されたプレフィックスを持つすべてのファイル (spam001.txt、spam002.txt など) を検索し、欠落している番号を見つけるプログラムを作成します (たとえば、spam001.txt と spam003.txt は存在​​しますが、 spam002.txt ではありません)。後続のすべてのファイルの名前をプログラムに変更させ、欠落している番号を削除します。追加の課題として、連続した番号が付けられたファイルの一部の番号を空のままにし、新しいファイルを追加できるようにする別のプログラムを作成します。

import os
import shutil

rootPath = 'F:\\pycharm\\work\\OfficeAutomation\\files'    #设置遍历根路径
prefix = 'spam'                                            #设置文件名前缀
fileList = []                                              #旧文件名列表
fileList_New = []                                          #新文件名列表

# #生成测试文件
# for i in range(11,21):
#     file = open(os.path.join(rootPath,'spam{:03d}.txt'.format(i)),'w')
#     file.write('Name of this file is spam{:03d}.txt'.format(i))
# file.close()

count = 1

for name in os.listdir(rootPath):                           #遍历rootPath下所有文件或文件夹
    if os.path.isfile(os.path.join(rootPath,name)):         #找到文件类型的文件(非文件夹)
        if name.startswith(prefix):                         #将所有含有前缀名的文件名加入旧列表
            fileList.append(name)
            newName = prefix+'{:03d}'.format(count)+'.txt'  #将当前文件的正确文件名加入新列表
            fileList_New.append(newName)
            count+=1
fileList.sort()                                             #将旧文件名列表排序

#将错误序号之后的所有文件夹重命名为正确的文件名
for old,new in zip(fileList,fileList_New):
    if(old!=new):
        print("change the name ["+old+"] to ["+new+"]")
        shutil.move(os.path.join(rootPath,old),os.path.join(rootPath,new))



1. トピックのアイデア:
(1) os.listdir() を使用して、現在のパスにあるすべてのファイル (フォルダーを除く) を取得します。
(2) ファイルがプレフィックス名と一致する場合、古い名前リストに追加され、ファイルに対応する正しい名前が付けられます。新しい名前リストに追加されます
( 3) 古いファイル リストと新しいファイル リストを調べ、それらが等しくない場合は shutil.move メソッドを使用して名前を修正します。

2. for a,b in zip(X,Y) は、効率を向上させることができる一般的な走査方法であり、将来的にはさらに使用される可能性があります。


おすすめ

転載: blog.csdn.net/qq_41794040/article/details/117966446