1 クラスメイトの作品のクローンと実行
課題07としてGitHubに公開されているクラスメイトの制作物を、各自のローカルPCに「クローン」して実行するための手順について解説します。
1.1 リポジトリのクローン
ここでは久しぶりに Git Bash ターミナルを使用します。Windows のスタートボタンを右クリックして「ターミナル」を起動し、ターミナルタブを Git Bash に切り替えください。
Git Bash ターミナルで、ドキュメント
(C:\Users\xxxx\Documents)
などの適当なフォルダに移動して Classmates-Dev-Hub
というフォルダを新規作成して、そのなかに移動してください。このフォルダの内部に、クラスメイトが制作した
課題07
のリモートリポジトリをクローンしていきます。
cd c:Users/xxxx/Documents
mkdir Classmates-Dev-Hub
cd Classmates-Dev-Hub/
GoogleClassroomに配置している「ポートフォリオ一覧」から、各ポートフォリオにアクセスし、さらにそこからGitHub のリモートリポジトリ (=制作物を公開しているプロジェクトのトップページ) にアクセスしてください。
プロジェクトのトップページにアクセスしたら、次の図のように
[Code] - [Code] - [HTTPS] -
の順にたどって「リモートリポジトリのURL」をクリップボードにコピーしてください。「リモートリポジトリのURL」とは
https://github.com/Xxxx/Yyyy.git のように アドレスの末尾が「.git」
となっているものです。また、トップページに表示されている
README.md
についても同時に確認しておいてください。
README.mdの確認
第14回講義で学習したように、プロジェクトフォルダのトップ階層に
README.md という名前のファイル (マークダウン形式)
を配置しておくと、リポジトリのトップページに、その内容が表示されるようになります。一般には、プロジェクトの概要、制作期間、実行方法、ライセンス、操作方法などを記載します。
GitHub で公開するプロジェクトには、原則として
README.md を配置するようにしてください。
Git Bash ターミナルに戻ります。
次のコマンドを入力して「クローン」を実行し、さらに、そのフォルダのなかに移動してください。ここでは「だれが制作したプロジェクトなのか」が分かりやすいようにクローン先(展開先)のフォルダを
38-Yamada のように変更しています
(クローンの手順については第15回講義のなかで学習しました)。
git clone https://github.com/Xxxx/Yyyy.git 38-Yamada
cd 38-Yamada
ls
コマンドなどでフォルダの内容を確認してください。
次に、これらのプログラムを実行するため、pip
を最新版にしてから仮想環境を構築して有効化します。ただし、現在使用中のターミナル
(シェル) は VSCode
でデフォルト使用している「PowerShell」
ではなく、「Bash」であるため、いつものように
.venv/Scripts/Activate.ps1
を実行しても、仮想環境は有効化されません( 拡張子 .ps1
はPowerShellスクリプトの拡張子です)。
Bash 環境において仮想環境を有効化するためには
source .venv/Scripts/activate
ようにコマンドを実行してください。sourceコマンドは 引数に与えたファイルに記述されたシェルスクリプトを実行
するためのコマンドで、主に Linuxで使用される Bash、tcsh、zsh
などのシェル環境で利用ができます。
python -m pip install --upgrade pip
python -m venv .venv
source .venv/Scripts/activate
Git Bash
ターミナルで仮想環境が有効化されると、入力プロンプトの前に
(.venv)
の文字列が付きます。なお、この仮想環境を抜けるためには、単に
deactivate
とコマンドと打ち込みます。仮想環境が無効化されれば
(.venv) の文字列は消えます。
1.2 ライブラリのインストール
ls でファイルを一覧表示して
requirements.txt
が存在すれば、pip install -r requirements.txt
でライブラリを 一括インストールします。requirements.txt
は、プログラムの実行に必要なライブラリの一覧を示したテキストファイルで、第22回講義のなかで詳細を説明しています。
pip install -r requirements.txt
もし、フォルダのなかに requirements.txt
が存在しなければ、各Pythonファイルの冒頭に記述される
imoport
から必要なライブラリを判断して、個々にインストールしてください。このような作業は、非常に面倒であるため、通常は
requirements.txt を用意します。
今後、GitHub
などのリモートリポジトリにPythonプロジェクトを公開する際は (
課題08 を含む)、原則として
requirements.txt
を含めるようにしてください。requirements.txt
の作成方法は第22回講義を参照してください。
1.3 プロジェクトの実行
プログラムの エントリポイント (=開始点)
となる Pythonファイル
を対象に、次のコマンドを実行します。プログラムが複数のファイルから構成される場合、エントリーポイントとなる
Pythonファイル には慣例的に main.py や
app.py のような名前をつけます。
python main.py
基本的には、以上の手順でプログラムが起動するはずです。うまく動作しない場合は 制作者に、直接、質問や相談 してください。
また、Git Bashターミナルからは code . &
コマンドでプロジェクトをVSCodeでオープンすることができるので、プログラムそのものを読むこともできます。自分が以外が書いたプログラムを読むことは、非常に勉強になるので、それも是非トライしてください。
演習1:「課題07」において
requirements.txt
を作成していない場合は、それをプロジェクトフォルダのトップ階層
(ルート) に作成して GitHub にプッシュせよ。
演習2 (Ex) :「課題07」において
README.md
を作成していない場合は、それプロジェクトフォルダのトップ階層
(ルート) に作成して GitHub にプッシュせよ。
演習3: 実際に誰かのプロジェクトをローカルPCにクローンして、プログラムを実行せよ。
(Ex) の演習は、授業時間外に取り組んでください
2 ライセンス
前々回の講義で説明したように PySide6 は Lesser General Public License 3.0 (LGPLv3) というライセンスのもとで公開・配布されています。このため、PySide6 を使用して開発したアプリケーションを公開・配布 する際には、LGPLv3 と互換性のあるライセンスを選択して、そのライセンスを適用する必要があります。
具体的には「LGPLv3」「MIT License」「GPLv3」「Apache License 2.0」などの互換性があるライセンスの下で自作のアプリを公開・配布する必要があります。各ライセンスの概要については ウェブ検索やChatGPTなど で把握してください。
ここでは、PySide6 と同じ LGPLv3 ライセンス で自作アプリを公開・配布する手順を解説します。これによりライセンス違反を指摘されることを避けることができます。
2.1 ライセンスファイルの追加
プロジェクトフォルダのトップ階層 (ルート) に
LICENSE.txt という名前のファイルを作成してGNU公式ウェブサイトから「LGPLv3
ライセンス全文」をコピーして貼り付けます。
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. https://fsf.org/
(中略)
If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy’s public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
ここでは、(中略) としていますが、実際の
LICENSE.txt では文章を略さないでください。
2.2 REAMDE.md に記載
プロジェクトフォルダのルートに配置した REAMDE.md
の最後に以下のような内容を記載します。
(略)
# ライセンス
このアプリケーションは GNU Lesser General Public License v3.0 のもとで公開されています。詳細は `LICENSE.txt` ファイルを参照してください。
このアプリケーションは PySide6 を利用しています。PySide6 は LGPL v3 ライセンスの下で公開されています。詳細は [こちら](https://www.qt.io/licensing/) を参照してください。以上の手順に従えば、ライセンス違反の問題は基本的に回避できます。
個人的な趣味の範囲でアプリを開発して、ひっそりとGitHubで公開しているレベルにおいては、ライセンス違反が指摘されることはほとんどありません。しかし、皆さんは将来的にはプロになる立場であり、いまのうちからライセンスについて意識を持っておくことは非常に重要です。
3 正規表現
正規表現 (Regular Expression) とは、特定のシンボルや記号で構成された特別な文字列 (これを パターン という) を使用し、文字列の 検索、置換、分析 を効率的かつ強力に行なうための仕組みです。正規表現は、Pythonをはじめとして様々なプログラミング言語でライブラリとして利用可能です。また、VSCodeなどのテキストエディタや、データ処理ツールでも対応している製品が多くあります。
例えば、正規表現を使用すると、ユーザが入力する「電話番号」「メールアドレス」「URL」「郵便番号」「IPアドレス」「日付」「時刻」などが 適切な形式で記述されているかどうかを、複雑なロジックを構築することなく確認すること、つまり、バリデーション (Validation) が可能になります。
さらに、文章中から特定の規則を持った文字列を検索・抽出することや、それらを一定の規則で置き換えることも可能です。例えば、テキストファイルのなかから「R29001」「r29031」「r29158」のように「大文字と小文字」「半角と全角」が混在した学籍番号の文字列を検索し、それらを全て半角大文字の学籍番号、つまり「R29001」「R29031」「R29158」のように置換する処理も可能です。
このように正規表現は、かなり強力なツールになりますが、利用に際しては 適切にパターンを記述 する必要があります。パターンの記述は経験と知識を必要とするものでしたが、現在では、複雑なパターンも ChatGPT などの 生成AI を活用して、自然言語を用いた対話的な方法で生成することが可能になりました。
ここでは、PySideと組み合わせて正規表現について学んでいきます。
3.1 バリデーション
ウェブアプリやGUIアプリにおける バリデーション (検証) とは、ユーザからの入力 (例えば電話番号や郵便番号、メールアドレス、パスワードなど) が「期待される形式や条件を満たしているか」を確認する手続きを意味します。
ウェブサービスの登録フォームなどで見かけることがあると思います。
ここでは、以下のようなGUIアプリの「携帯電話番号の入力」に関するバリデーションを 正規表現 (Regular Expression)を利用して実装してみたいと思います。
前々回に作成したPySideのプロジェクトフォルダに
qt-11.py
というファイルを新規作成して、以下の内容を貼付けて実行してください。
import sys
import PySide6.QtCore as Qc
import PySide6.QtWidgets as Qw
import re
# 都道府県タプル (末尾の「空欄」を含む)
pref_list = ('北海道','東京都','大阪府','鹿児島県','沖縄県','')
# 電話番号のバリエーション (検証)
def validate_tel_number(tel:str)->bool:
pattern = r'^\d{3}-\d{4}-\d{4}$' # 正規表現パターン
if re.match(pattern, tel):
return True
else:
return False
class MainWindow(Qw.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('MainWindow')
self.setGeometry(100, 50, 640, 130)
# 都道府県コンボボックスの見出し
self.lb_pref = Qw.QLabel(self)
self.lb_pref.setGeometry(15,10,300,25)
self.lb_pref.setText('都道府県')
# 都道府県コンボボックスの本体
self.cmb_pref = Qw.QComboBox(self)
self.cmb_pref.setGeometry(15,35,80,25)
self.cmb_pref.setEditable(False)
for p in pref_list:
self.cmb_pref.addItem(p)
# pref_list の末尾の「空白」を初期値にセットする。
self.cmb_pref.setCurrentIndex(len(pref_list)-1)
self.cmb_pref.currentIndexChanged.connect(self.pref_changed)
# 都道府県の検証ラベル vm: Validation Message
self.lb_pref_vm = Qw.QLabel(self)
self.lb_pref_vm.setGeometry(105,35,200,25)
self.lb_pref_vm.setText('必須項目')
self.lb_pref_vm.setStyleSheet('color: red;')
self.lb_pref_vm.setVisible(True)
# 電話番号テキストボックスの見出し
self.lb_tel = Qw.QLabel(self)
self.lb_tel.setGeometry(15,65,300,25)
self.lb_tel.setText('携帯電話番号')
# 電話番号テキストボックスの本体
self.tb_tel = Qw.QLineEdit(self)
self.tb_tel.setGeometry(15,90,110,25)
self.tb_tel.setPlaceholderText('XXX-XXXX-XXXX')
self.tb_tel.setAlignment(Qc.Qt.AlignmentFlag.AlignCenter)
self.tb_tel.textChanged.connect(self.tel_changed)
# 電話番号の検証ラベル vm: Validation Message
self.lb_tel_vm = Qw.QLabel(self)
self.lb_tel_vm.setGeometry(135,90,300,25)
self.lb_tel_vm.setText('必須項目')
self.lb_tel_vm.setStyleSheet('color: red;')
# 都道府県コンボボックスが変更
def pref_changed(self):
idx = self.cmb_pref.currentIndex()
if idx == len(pref_list)-1 :
self.lb_pref_vm.setVisible(True)
print(f'都道府県が未選択になりました。')
else :
self.lb_pref_vm.setVisible(False)
print(f'「{pref_list[idx]}」が選択されました。')
# 電話番号テキストボックスが変更
def tel_changed(self):
tel = self.tb_tel.text()
if len(tel) == 0:
self.lb_tel_vm.setText('必須項目')
else:
if validate_tel_number(tel):
self.lb_tel_vm.setText('')
else:
self.lb_tel_vm.setText('書式に誤りがあります')
# 本体
if __name__ == '__main__':
app = Qw.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec())ここでは、分かりやすさを優先して 第12行目 から
第15行目 のように記述していますが、実際には
return re.match(r'^\d{3}-\d{4}-\d{4}$', tel)
のように1行で記述することができます。
3.2 正規表現
正規表現 (Regular Expression) を使うために
第04行目 で re
ライブラリを読み込んでいます。また、バリデーションのコアとなる処理は
第09行目 から 第15行目 の
validate_tel_number 関数です。この関数は型ヒントから読み取れるように、文字列型の引数
tel を受け取って、それが携帯電話番号のパターン
XXX-XXXX-XXXX にマッチしているかどうかをバリデーション (検証)
して、True か False を返すものです。
第11行目 において携帯電話番号を表すパターンを
pattern = r'^\d{3}-\d{4}-\d{4}$'
のように記述しています。まず、先頭の r
ですが、これは、エスケープシーケンス (例えば \n
で改行を意味するなど) を適用しない Raw String (生の文字列)
であることを指示をするものになります。正規表現では バックスラッシュ (環境によっては円マーク)
を多用
するため、一般には「r文字列」を使用してパターンを記述します。なお、「r文字列」は、正規表現だけではなく
Python
で広く使われる文法です。もし、「r文字列」を使用しない場合は、エスケープ処理されないように
'^\\d{3}-\\d{4}-\\d{4}$'
のようにパターンを記述する必要があります
(読みづらくなります)。エスケープシーケンスについてはウェブを参照してください。
以下、パターンを構成する文字列の意味です。
^(ハット) : この文字は、文字列の始まりを表します。つまり、このパターンは文字列の先頭からマッチする必要があります。\d: これは「任意の数字(0-9)」にマッチする特殊文字です。{3}: これは直前の文字(この場合は\d)がちょうど3回繰り返されるべきことを示します。従って、\d{3}は3桁の数字にマッチします。-(ハイフン) : これはハイフン記号に直接マッチします。\d{4}: これは4桁の数字にマッチします。$: この文字は文字列の終わりを表します。つまり、このパターンは文字列の最後で終わる必要があります。
ここで注意してほしいのは ^ と $
の取り扱いです。これを取り除いて '\d{3}-\d{4}-\d{4}'
のようなパターンを使用すると「電話番号は090-1111-1111です。」のような文字列、つまり
文字列の内部に XXX-XXXX-XXXX を含む
ような場合も、バリデーションを通過してしまうようになります。
以上のように正規表現のパターンの記述には ある程度の知識と経験 が必要になります (使えるようになると非常に便利なもののの、使えるようになるまで大変でした)。しかし、最近では「生成系AI」を利用することで、自然言語で情報を与えて、適切な正規表現パターンを簡単に得ることができるようになりました。例えば、次のように質問してパターンを得ることができます。
質問
Pythonの正規表現に関する質問です。携帯電話番号 XXX-XXXX-XXXX の形式にマッチするようなパターンを教えてください。ただし、番号の先頭は「090」「080」「070」のどれかからはじまっている必要があります。
回答 はこちらを参照してください。
なお、正規表現には、プログラミング言語によって方言 があるので、AIに質問する場合は、Pythonにおける正規表現についての話題であること を必ず指示してください。
演習1: 第11行目
を通常の文字列に変更すると、つまり、先頭の r
を削除するとどのようになるか確認してください。
演習2: 第11行目 を
r文字列を使わずに pattern = '^\\d{3}-\\d{4}-\\d{4}$'
のように記述しても正常に機能することを確認せよ。
演習3: 第11行目 を
pattern = '\d{3}-\d{4}-\d{4}' のように ^
と $
を除いた場合、「090-1111-1111」もバリデーションを通過するが、「xxx090-1111-1111zzzz」でもバリデーションを通過してしまうことを確認してください。
演習4: 次のようにプログラムを拡張してください。なお、電子メールアドレスのバリデーションを設定してください (ChatGPTなどを活用すること)。
演習5: メールアドレスのバリデーションとして
ac.jp および ed.jp
ドメインのみを許可するように設定せよ。
3.3 コンボボックス
第25行目から第45行目 および 第65行目から第73行目 では、新規のウィジェットとして「コンボボックス」を組み込んでいます。ラジオボタンと同じように1個の選択肢を得るものですが、選択候補が多数の場合に有効なウィジェットになります。
この他、PySide6 (Qt6) で使用可能なウィジェットの一覧は公式リファレンスから確認することができます。どのようなウィジェットがあるか必ず確認してください。
4 OpenCV と PySide6 の組合せ
OpenCVと PySide6 を組み合わせた例を以下に示します。これらを組み合わせると簡単な画像処理アプリ(GUI)を作成することができます。
OpenCV では画像を numpy.ndarray
オブジェクトとして扱いました。この numpy.ndarray
オブジェクトを PySide6 で表示するためには
第29行目 の手順で
PySide6.QtGui.QImage'
に変換して、第37行目
のようにQLabelウィジェットに貼り付けて表示します。
実行するためには pip install opencv-python
でライブラリをインストール後、qt-12.py
と同じフォルダににimg-01.jpgを配置してください。
import sys
import PySide6.QtWidgets as Qw
import PySide6.QtGui as Qg
import cv2
import numpy as np
class MainWindow(Qw.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('MainWindow')
self.setGeometry(100, 50, 685, 280)
# OpenCVで画像ファイルを読込み
img1 = cv2.imread('img-01.jpg')
print(type(img1)) # => <class 'numpy.ndarray'>
# img1を320x240にリサイズ
img1 = cv2.resize(img1,(320,240),interpolation=cv2.INTER_LANCZOS4)
height, width, ch = img1.shape
# img1をimg2に複製。加工。
img2 = img1.copy()
img2[105:115,65:110] = np.array([0,0,0],dtype=np.uint8)
# np.ndarray オブジェクトを QImageオブジェクトに変換
bpl = ch * width # bpl : bytes_per_line
qimg1 =Qg.QImage(img1.data, width, height,
bpl, Qg.QImage.Format.Format_BGR888)
qimg2 =Qg.QImage(img2.data, width, height,
bpl, Qg.QImage.Format.Format_BGR888)
print(type(qimg1)) # => <class 'PySide6.QtGui.QImage'>
# QLabelに画像 qimg_1 を設定する
self.lb_img1 = Qw.QLabel(self)
self.lb_img1.setPixmap(Qg.QPixmap.fromImage(qimg1))
self.lb_img1.setGeometry(15,10,width,height)
# QLabelに画像 qimg_2 を設定する
self.lb_img2 = Qw.QLabel(self)
self.lb_img2.setPixmap(Qg.QPixmap.fromImage(qimg2))
self.lb_img2.setGeometry(350,10,width,height)
# ラベル1
self.lb_title1 = Qw.QLabel(self)
self.lb_title1.setText('加工前')
self.lb_title1.setGeometry(15,250,100,25)
# ラベル1
self.lb_title2 = Qw.QLabel(self)
self.lb_title2.setText('加工後')
self.lb_title2.setGeometry(350,250,100,25)
# 本体
if __name__ == '__main__':
app = Qw.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec())4.1 単純な画像表示
プログラムのなかで複雑な画像処理をせず、画像を表示するだけであれば、以下のようにシンプルに記述することができます。
import sys
import PySide6.QtCore as Qc
import PySide6.QtWidgets as Qw
import PySide6.QtGui as Qg
class MainWindow(Qw.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('MainWindow')
self.setGeometry(100, 50, 350, 280)
# PySideの機能で画像の読込みとリサイズ
width, height = 320, 240
pm1 = Qg.QPixmap('img-01.jpg')
pm1 = pm1.scaled( width, height,
Qc.Qt.AspectRatioMode.KeepAspectRatio)
# QLabelに「画像」をセット
self.lb_img1 = Qw.QLabel(self)
self.lb_img1.setPixmap(pm1)
self.lb_img1.setGeometry(15,10,width,height)
# QLabelに「文字列」をセット
self.lb_title1 = Qw.QLabel(self)
self.lb_title1.setText('加工前')
self.lb_title1.setGeometry(15,250,100,25)
# 本体
if __name__ == '__main__':
app = Qw.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec())5 EXEファイル化
Python で開発されたアプリを実行するには、実行環境に Python や ライブラリ がインストールされている必要があります。しかし、Python 環境をセットアップすることは、一般のPCユーザーにとってはかなりハードルが高い作業 になります。アプリを開発しても、他者に利用してもらえなければ、開発の意欲・モチベーションを保つこと は難しくなります。この問題を解決法として、Python プログラムを 実行ファイル (EXEファイル) に変換して配布する という手段があります。
EXE化するためのツールにはpy2exeやpy2app、Nuitkaなど様々なものがありますが、ここではpyinstallerというツールを使用します。EXE化したいアプリを開発している
VSCode でターミナルを開き、pip で
pyinstaller をインストールします。
pip install pyinstaller
次に、エントリーポイントとなるPythonファイル (この例では
main.py )
を第1引数に与えて以下のコマンドを実行します。
pyinstaller main.py --onefile
しばらく処理がつづき、成功すると
xxxxxx INFO: Building EXE from EXE-00.toc completed successfully.
のようなメッセージが表示されます。これは、変換プロセスが成功したことを意味します。
プロジェクトフォルダに dist
というフォルダが作成され、そこに main.exe
のようなファイルが生成されます。dist は Distribution (配布・配給)
の略語になります。また、プロジェクトフォルダに build
という中間ファイルを収納するファルダも作成されます
(このフォルダの内容は消しても問題ありません)。
なお、次のように --noconsole オプションをつけると
コンソールが非表示 になります。完全
GUI アプリの場合はこのオプションを設定してください。
pyinstaller main.py --onefile --noconsole
実行ファイルに変換すると (EXEファイル内に
Pythony環境 や 関連ライブラリ を内包するため)
非常にファイルサイズが大きく
なります。小規模なアプリでも数十MB以上になります。そのため、通常、GitHub
などのリモートリポジトリには dist や
build を含めません。.gitignore
にこれらを除外するように設定します (dist
は目的に必要に応じてプッシュ対象に含めることがあります)。
ただし、GitHub では、ファイルサイズが 100 MB を超えるファイルをプッシュすることは基本的にできません。PythonプログラムをEXE化すると、このファイルサイズの制限に引っかかる可能性があります。そのときは、GitHub ではなく別の方法での配布を検討する必要があります。
Google Drive は、その選択肢となります。ただし、Google Drive では「EXEファイルの直接アップロードができない」あるいは「セキュリティ上の警告が表示されること」があります。そのため、EXE ファイルを ZIP 形式で圧縮してアップロードすることが推奨されます。これにより、ファイルのアップロードが容易になり、ダウンロード者も安全にファイルを受け取ることができます。
演習 : Pythonプログラム qt-11.py
をEXEファイルに変換せよ。
6 課題08
プログラミング1の課題としては「最終の課題」となります。「PySide を利用した GUIアプリ (自由作品)」を作成し、そのプログラムを GitHubに公開 するとともに 課題06で作成したポートフォリオに概要を掲載してください。
- 提出物・提出先 :
GitHubリポジトリのURL をGoogleClassroomに提出してください。「
追加または作成」から「
リンク」を選んで提出してください。
- ポートフォリオの内容は、以前に課題06で提出いただいたURLから確認します。もし、URLが変更されている場合は、個別にTeamsChatで連絡をください。
- 提出された課題 (ポートフォリオ) は 知能情報コースの学生と教員、保護者に公開 します。
- 提出期限 : 2025年02月20日
(木) 23時
- 取組みの目安となる時間: 10時間以上
- 本科目には中間試験や期末試験などの筆記試験がありません。それらの試験勉強時間の代替として本課題に取り組んでください。
- 評価 :「8点」を標準として「10点満点」で評価します (学年末の成績評価の際には「重み」が付けられます)。
- 注意-1 : GitHubリポジトリ
(プロジェクトフォルダ) には、必ず
README.mdとrequirements.txtを含めてください。一方で、.venvや.vscodeなどは含まれないように.gitignoreで設定してください (詳細は第16回講義を参照)。 - 注意-2 :
プログラムは必ず2個以上のファイルに分割して構成し、エントリポイント
となるファイルは
main.pyとしてください (ターミナルからpython main.pyでアプリが起動するようにしてください) 。ファイル分割については第22回講義を参考にしてください。
ポートフォリオに作品として掲載する際、必ず、次の内容を含めてください。これらに漏れがあると 6点以下の評価 になります。細かな書式や形式については自由です。
- 制作時期として「2025年2月」のような情報を明記してください。日付のフォーマットは自由です
(例えば「2025/02」や「February
2025」などでもOKです)。この制作時期の情報から、それが本科目の「課題08」であることを識別します。
- およその 制作時間 も記載してください。開発時間などの表現でも問題ありません。例:「約10時間」「約13時間」など。
- 作品の「タイトル」と「説明文章」を書いてください。説明文章は 200文字以上 を記載してください。なお、タイトルに「課題09」のような言葉は 不要です。
- 3枚以上のスクリーンショットを載せてください。スクリーンショットの代わりに動画やGIFアニメーションなどでも可です。ただし、GitHubには 25MB を超える動画はアップできないので注意してください (必要に応じてYouTubeなどにアップして、それをページに埋め込みしてください)。
- GitHubリポジトリへのリンクを載せてください。