プログラミング初心者が はじめてのPythonアプリを完成させるまで

## はじめに
Pythonを学び始めて2か月が経ちました。何かアプリを作りたいと考えていたところ、業務効率化アプリのアイデアが浮かびました。この記事では、具体的なアプリの内容は最小限にとどめ、初心者が何を参考にし、何を学び、どのような流れでアプリを完成させたのかについて書きたいと思います。

## どんなアプリ？
某私鉄のPDF領収書の宛名欄に、社名を自動入力するアプリです。経費申請のため、領収書の宛名欄に自社名を入力する必要があります。この入力作業が地味に苦痛でした。時間はそれほどかからないものの、往復で2枚ありますし入力用のテキストボックスを適切に配置するという感覚的な作業が好きになれませんでした。

![receipt240916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886913/f15e51c6-b0f5-efa4-1e8e-b984e4b7c326.jpeg)

## 開発環境
* **Visual Studio Code**

後述のPython Vtuberサプーの動画を参考にしたため、サプーがおすすめしているPyCharmにも興味がありましたが、プログラミングに慣れていないうちに開発環境を変えるのは得策ではないと考え、いつも使っているVisual Studio Codeを選択。

CWBJ（Code; Without Barriers Japan）に参加しているため、Microsoft派です。

## 参考にしたもの
* 「PythonでPDFファイルを操作しよう！」Python Vtuberサプー

https://www.youtube.com/watch?v=1sjSCH9DhsY

16分ほどの動画に、PythonでPDFを扱うためのエッセンスが詰まっています。サプーのコーディング動画は、初めから完成形を書くのではなく、まずアプリ全体の骨組みを作り、必要に応じて肉付けし、エラーが出たら修正するというスタイルでとてもリアルです。プログラマの思考過程を追体験するようで、とても学びになります。

この動画で学んだのは、PDFに文字を追記したい場合、既存のPDFに直接書き込むのではなく、新しいPDFを作成してそこに自社名を入力し、既存のPDFとマージするということです。（下図参照）

![process240916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886913/ac9bfd8f-5b42-26cb-55dd-951c1906df4a.jpeg)

## アレンジ
動画を参考にしたことで、PDFに宛名を入力するコード自体はすんなり書けました。しかし、特定のファイル名のPDFを読み込み、特定のファイル名で出力するのはあまり実用的でありません。そこで以下のアレンジを加えました。

* **入力仕様の変更：エクスプローラーからファイルを読み込む**
* **出力仕様の変更1：出力ファイルの名前を一意に決める**
* **出力仕様の変更2：出力ファイルの保存先をデスクトップに変更**

ひとつずつ説明します。

### 入力仕様の変更：エクスプローラーからファイルを読み込む
宛名を入力するPDFを、エクスプローラー画面から選択できるようにしました。このコーディングは、Copilotに依頼しました。

![copilot240916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886913/726f46a0-5313-2317-01a5-4a65cdf58c01.jpeg)

ゼロからコードを書く場合はこのように質問してOKです。現在書いているコードをすべてCopilotに共有して「PDFを読み込んでいる部分を、エクスプローラーから任意のファイルを選択する形式に変更したい」と依頼すれば、自分のコードに合った形で書き直してくれます。

書籍やチュートリアルを読んでも、なかなか応用がきかずに挫折してしまうのがこれまでの私のプログラミング学習でした。その点、Copilotは今自分が書いているプログラムに適したコードを提案してくれます。長年、独学プログラミングの入口でつまづいていた私にとってCopilotは本当に革命的です。Copilotがいなければ、今回のアプリは完成できませんでした。

![pic240916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886913/e0c4c35f-a0ed-44d3-b8e6-a250380309bc.jpeg)
無事エクスプローラーが表示されました。

### 出力仕様の変更1：出力ファイルの名前を一意に決める
もともとのプログラムでは、出力ファイル名はoutput.pdfで固定でした。しかし、１度の事務処理で往復２枚の領収書を扱いたい私にとって、これでは上書きのリスクがあります。

はじめは領収書NoをPDF名に使おうと思いました。

![receipt2_240916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886913/737a4ef7-e167-e13d-f0ee-bc8153b6215c.jpeg)

文字列を抽出する関数（page.extract_text関数）を使えば簡単にできると思いましたが、うまくいきませんでした。エラーも出ないし、あれこれ調べてもコードの間違いは見当たりません。ものすごく詰まって挫けそうになりましたが、自分で生成したPDFの文字を抽出できたことで突破口が開きました。問題はコードではなくPDFにありました。このPDFはいわゆる埋め込みがされていて、page.extract_text関数では文字を抽出できなかったのだと思います。

方針を変更して、出力ファイル名には現在時刻から取得した時分秒を使うことにしました。

領収書Noは経費精算時、処理画面に打ち込む必要があります。ファイル名になっているととても楽なので、抽出方法をご存じの方がいればぜひコメントいただければと思います。

### 出力仕様の変更2：出力ファイルの保存先をデスクトップに変更
もともとのプログラムでは、ファイルの出力先はコードの保存先と同じディレクトリでした。実用の際にはデスクトップに生成されると楽なので、保存先を変更します。

この部分もCopilotに書いてもらいました。

## こだわり
はじめてのPythonアプリを作るうえでの裏テーマは「脱・初心者」でした。そのため、プログラミング学習をするなかで理解があいまいだった下記の点をきちんと実用することを自分に課しました。

* **関数を使う**
* **GitHubで開発管理**
* **アプリ化する（実行ファイルにする）**

### 関数を使う
今回のプログラムでは、ファイルを選択するためのエクスプローラーを出す部分を関数化しました。openfile.pyという別ファイルに関数を書きました。関数化の方法はCopilotに教えてもらいました。

openfile.py 全文
```python:openfile.py
# エクスプローラーからファイルを開く
import tkinter as tk
from tkinter import filedialog

def select_file():
    # Tkinterのルートウィンドウを作成
    root = tk.Tk()
    root.withdraw()  # ルートウィンドウを非表示にする

    # ファイルダイアログを開いてファイルパスを保存
    file_path = filedialog.askopenfilename()
    
    return file_path
```
メインファイルで関数を使っている部分（main.py）
```python:main.py
#自分で作った関数のインポート
from openfile import select_file 

# 既存のPDFを読み込む
reader = PdfReader(select_file())
writer = PdfWriter()
```
今回のプロジェクトを通じて最もアドレナリンが出たのは、この関数のimportが通った瞬間です。笑
この瞬間、今までのモヤモヤが晴れて一皮むけた気分になりました。（個人の感想です）

### GitHubで開発管理
今回のプロジェクトは、個人PCと会社PCの両方で進めたかったため、GitHubでの開発管理はマストでした。この書籍に助けてもらいながら、まずはGitに慣れ、それからGitHubに移行しました。

https://www.amazon.co.jp/Visual-Studio-Code%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-Perfect-master/dp/4798067970/ref=sr_1_1_sspa?adgrpid=115242605686&dib=eyJ2IjoiMSJ9.-nTsl35LzJOWcVlN8rI0p6y2civX6K6eybHpzvFqd6zAtz9ZSPlkQcJK4cIHmeTc4T0KwfcrWG3S2uvZ5C7GNPb17vqQEt813PCfRCA4UX4UqG-0jhc_UMGswDru9DePiKlRkHBW34uI14rXSJeGTWY41XimSrkiP-Eg78DNamz3UNHyK1o6TyKXVZi53ySJq_vCQRnnvoQZ7Jr0TGSDjoeW8Y1J6pfAVWsd1jxIJABIubnLg45dfcLvH-XvS29u5vBz3jT5znfBF3VJi51b64e2pqeUzdyzA18ye6j3Ntc.akfwahSzlJLFEgsRhZTnKN6KHbp_QEUbzLuxulRgCHo&dib_tag=se&hvadid=699038606621&hvdev=c&hvqmt=b&hvtargid=kwd-766952181292&hydadcr=15818_13737822&jp-ad-ap=0&keywords=vscode+%E6%9C%AC&qid=1726487705&sr=8-1-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1

全550ページと辞書的な厚さの書籍のなかで、GitHubに触れているのはわずか20ページほどですが、Visual Studio Codeで開発をすすめている私にとってはドンピシャの内容で、大変参考になりました。

![pythonPDF20240916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886913/2292bc51-0872-337a-229e-423bc04b53e2.jpeg)
無事マージできたソース管理グラフを見たときは、２度目のアドレナリンが出ました。笑

### アプリ化する（実行ファイルにする）
さいごに実行ファイルを作りました。方法は、もちろんCopilotに教えてもらいました。ターミナルに
`pyinstaller --onefile --noconsole main.py`
と入力すると、distフォルダの中に実行ファイルmain.exeが生成されます。

## 結果
![output240916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886913/573a01da-2ead-0c32-b26f-a222a01a8535.jpeg)
無事、宛名の自動入力機能が開発できました。

## まとめと今後
つくりたいアプリのイメージが固まれば、Copilotが助けてくれます。Copilotは、コードの生成だけでなく、頼めばコードの解説もしてくれるので、身近にいつでも相談にのってくれるプロのプログラマーがいるようなものです。これからもフル活用していきます。エラーが出たときは、エラーコードの読み方も教えてもらいました。

今回のプログラムは、PDFファイルの入出力、現在時刻の取得など、ごく基本的な機能を組み合わせて作りました。いったん「動くものが出来た」というレベルです。今回作成したプログラムをよく理解して、特に関数の定義やインポートを、もっとすんなり出来るようになるのが当面の目標です。

初心者がCopilotをつかって生成したコードを利用することについては賛否があるかと思いますが、自分としては実用できるアプリをはじめて作ることができて、プログラミング学習のモチベーションがぐっとあがりました。

さいごまでお読みいただき、ありがとうございました。