# 知能プログラミング演習 II Grep9
## 1. グループ
グループ 06
グループメンバー
- 33114074 高橋健人
- 33114095 西村光太郎
- 33114113 藤岡拓夢
- 33114141 渡邊修平
## 2. 自己採点
自己採点は S である.
自己採点の理由は以下の通りである.
- 独創的なアイデアを提案したから
- 新規性のあるシステムを開発したから
- 実用的なシステムを開発したから
## 3. 実装したシステムの説明
### 3.1. システムの開発背景
名古屋工業大学の情報工学科の 1 年次には,「理系基礎演習」という講義がある.
この講義は,Excel を用いたデータ分析を題材にグループワークやプレゼンを行い,情報工学科の学生としての基礎的なスキルを身につけることを目的としている.
担当の船瀬先生の人柄も相まって,理系基礎演習は情報工学科の学生にとって印象深い講義となっている.
情報工学科の学生にとって,理系基礎演習はまさに心のバイブル的な存在であると言えるだろう.
プレゼンでは,スライドに対して船瀬先生によるダメだしが行われる.
ダメ出しは,学生はスライドの改善点を学ぶための貴重な教育機会となっている.
その一方で,ダメ出しは学生にとって過度な負担となっている側面がある.
ダメ出しを取り巻く状況を整理すると,以下のようになる.
- 発表者の立場 : ダメだしされたくない
- 聞き手の立場 : ダメ出しをストレスに感じる
- 先生の立場 : ダメ出しを自動化したい
このような状況を踏まえて,船瀬先生の代わりにスライドへのダメ出しを行うシステムを開発することにした.
### 3.2. funase-lint の概要
作成したシステムは,Power Point 用のリンター `funase-lint` である.
リンターとは,プログラムのソースコードに対して,構文やスタイルなどの問題を指摘するツールである.
Power Point のファイル形式である pptx は,XML を ZIP で圧縮したものであるため,これを解凍して XML を解析することによりスライドの静的解析を行うという仕組みになっている.
ルールは過去の理系基礎演習の Moodle のページから集めた.
`funase-lint` は,Java で開発したコマンドラインツールである.
開発にあたっては,`picocli` というライブラリを利用し,様々なコマンドラインオプションを実装した.
また,バージョン管理ツール Git の `.gitignore` を模した `.funaseignore` による無視ファイルの指定機能を実装した.
JavaScript のリンター `ESLint` の `.eslintrc.json` を模した `.funaselintrc.json` によるカスタマイズ機能も実装した.
作成した funase-lint は以下の GitHub のページで公開している.
https://github.com/funamusix/funase-lint
### 3.3. 作成したルール
ルールは理系基礎演習の Moodle ページを参考に作成した.
作成したルールの一覧は以下の通りである.
- TextFontRule
- SlideTitleFontSizeRule
- SlideThemeRule
- SlideAspectRule
- PunctuationMarkRule
- AmbiguousWordRule
- FontMinimumRule
- QuestionMarkRule
- CTRRule
- FontSizeRule
### 3.3.1 TextFontRule
テキストのフォントテーマが船瀬先生の好まない游書体か MS ゴシックのとき,見栄えの良いフォントを使うように警告する.
### 3.3.2 SlideTitleFontSizeRule
スライドタイトルはそのスライドで1番重要であるため、スライドタイトルのフォントサイズが40pt未満のとき大きくするように警告する.
### 3.3.3 SlideThemeRule
見た目の悪いスライドは見る意欲を削いでしまうため,スライドテーマが白紙であったとき殺風景なテーマは使わないよう警告する.
### 3.3.4 SlideAspectRule
船瀬先生のスライドの教えの基本ともいえる内容.
16:9のスライドは文字が横長になって見づらいスライドになりやすいため,スライドサイズが4:3でないとき警告,修正する.
### 3.3.5 PunctuationMarkRule
スライドにおいて本文は箇条書きで書く必要があり,句読点は文章であることの象徴であるため,文中に句読点が含まれているとき警告,修正する.
### 3.3.6 AmbiguousWordRule
工学では可能な限り主観的な評価を省き,客観的な情報のみを使うべきであるため,「かなり」,「とても」などの曖昧な言葉が使われているとき警告する.
### 3.3.7 FontMinimumRule
スライドは見て分かることが重要であり,文字が小さいと読むことが出来なくなってしまうため,本文のフォントサイズが22pt未満のとき警告する.
### 3.3.8 QuestionMarkRule
「?」が文章中にあると稚拙な文章に見えてしまうため,文中に?が含まれているとき警告する.
### 3.3.9 CTRRule
表の文字が上下にセンタリングされていないと見栄えが悪いため,表の文字が上下にセンタリングされていないとき警告,修正する.
### 3.3.10 FontSizeRule
スライドを作るうえで本文のフォントサイズが22~38ptだと見やすいスライドになる.
また,スライドタイトルは文章の中で一番目立たせなければならないため,40pt以上でなければならない.
したがって,本文のフォントサイズが22~38pt,スライドタイトルが40pt以上でないとき警告する.
### 3.4. .funaseignore による除外機能
バージョン管理ツール Git の .gitignore による除外機能を模倣して,.funaseignore による除外機能を実装した.
たとえば,以下の機能を模倣して実現した.
- ディレクトリ単位の指定
- ワイルドカードの利用
- `!` によるホワイトリスト
- `#` によるコメント
また,.funaseignore は,対象のファイルから最も近い上位ディレクトリ内に含まれる .funaseignore を参照するようにした.
### 3.5. .funaselintrc.json によるカスタマイズ機能
## 4. 実装方法
### 4.1. 独自の工夫点
#### 4.1.1. Git / GitHub
Git でバージョン管理を行い,GitHub で共同開発した.
共同開発モデルは,Fork and Pull モデルを採用した.
これは,グループメンバーの Git / GitHub への習熟度を考慮し,ブランチの扱いについて説明することは煩雑になると考えたからである.
#### 4.1.2. 仮想環境
開発環境は,Visual Studio Code の Dev Container による仮想環境を採用した.
開発環境を Dev Container で統一することには以下のメリットがあった.
- ローカルが汚れない
- 開発環境の違いによるトラブルが発生しない
- Docker を直接扱うよりも簡単
- Visual Studio Code の拡張機能も統一できる
知能プログラミング演習 II の Teams のチャンネルを見ていると,ZIP ファイルでソースコードを共有しているグループが散見された.
このようなグループでは,しばしば開発環境の違いによるトラブルが発生していた.
GitHub と Dev Container を利用することで,私たちのグループではこのようなトラブルを回避することができた.
#### 4.1.3. ビルドツール
ビルドツールは,Gradle を採用した.
Maven を利用しなかったのは,Maven における XML を用いた設定が煩雑であると感じたためである.
#### 4.1.4. CLI フレームワーク
CLI フレームワークは,picocli を採用した.
picocli では,コマンドラインオプションの解析をアノテーションで行うことができる.
たとえば,以下のように記述する.
```java
@Option(names = { "--list-rules", "-l" }, //
description = "List all available rules.")
private boolean listRules;
```
`@Option` アノテーションを付けたフィールドはオプションとして認識される.
たとえば,フィールドのクラスが boolean の場合は,オプションが指定された場合のみ `true` が代入される.
また,`parameterConsumer` を利用することで,入力に応じた事前処理を行う仕組みを実現することができる.
たとえば,以下のように記述する.
```java
@Option(names = { "--style", "-s" }, //
description = "Specify output style.", //
parameterConsumer = StyleParameterConsumer.class)
private OutputStyle style;
```
`StyleParameterConsumer` は引数で与えられた文字列から出力形式を表す Enum の値に変換する処理を行うためクラスである.
もし不正な値が与えられた場合には,エラーメッセージを表示して処理を終了する.
また,picosli には以下の組み込みオプションがある.
- -h, --help: ヘルプメッセージの表示
- -V, --version: バージョン情報の表示
特に,ヘルプメッセージはアノテーションで指定した内容から自動で生成されるため便利だった.
ほかにも,今回は利用しなかったがサブコマンドを作成する機能もある.
以上のように,picocli を用いることで高機能なコマンドラインツールを手軽に実現することができた.
#### 4.1.5. ルールの自動インポート機能
`refrections` ライブラリを利用して,`rules` パッケージに含まれる Rule クラスの派生クラスを自動でインポートする機能を作成した.
これにより,以下のことが実現できた.
- ルールの追加における手間の削減
- ルール一覧表示機能の保守性の向上
- `.funaselintrc.json` によるカスタマイズ
### 4.2. 実行例
#### 4.2.1. -h, --help: ヘルプメッセージの表示
-h, --help オプションを用いることで,ヘルプメッセージを表示できる.
コマンドの入力例は以下のとおりである.
```bash
funase-lint -h ./path/to/inputpath
```
実行結果の例は以下のとおりである.
```bash
Usage: funase-lint [-fhlvV] [-s=<style>] <inputPath>
Lints and fixes PowerPoint presentations according to specified rules.
<inputPath> The PowerPoint file or directory to lint.
-f, --fix Automatically fix problems.
-h, --help Show this help message and exit.
-l, --list-rules List all available rules.
-s, --style=<style> Specify output style.
-v, --verbose Enable verbose output for more detailed information.
-V, --version Print version information and exit.
```
#### 4.2.2. -V, --version: バージョン情報の表示
-V, --version オプションを用いることで,バージョン情報を表示できる.
コマンドの入力例は以下のとおりである.
```bash
funase-lint -V ./path/to/inputpath
```
実行結果の例は以下のとおりである.
```bash
funase-lint 1.0
```
#### 4.2.3. 通常の実行
通常の実行のコマンドの入力例は以下のとおりである.
```bash
funase-lint ./path/to/inputpath
```
実行結果の例は以下のとおりである.
```bash
ファイル: /workspaces/funase-lint/docs/regular/ideasketch_06.pptx
スライドテーマが白紙になっています.
スライドサイズの比率が 4:3 ではありません.
文中に句読点が含まれています.
曖昧な言葉が使用されています.
フォントサイズが 22 pt 未満のものがあります.
```
#### 4.2.4. -l, --list-rules: ルールの一覧表示
-l, --list-rules オプションを用いることで,ルールの一覧を表示できる.
コマンドの入力例は以下のとおりである.
```bash
funase-lint -l ./path/to/inputpath
```
実行結果の例は以下のとおりである.
```bash
Available rules:
TextFontRule
SlideTitleFontSizeRule
SlideThemeRule
SlideAspectRule
PunctuationMarkRule
AmbiguousWordRule
FontMinimumRule
QuestionMarkRule
CTRRule
FontSizeRule
```
#### 4.2.5. -s, --style: 出力形式の指定
-s, --style オプションを用いることで,出力形式を指定できる.
指定可能な出力形式は以下の 3 つである.
- japanese : 標準的な日本語
- funase : 船瀬先生の口調の模倣
- json : JSON 形式
コマンドの入力例は以下のとおりである.
```bash
funase-lint -s=funase ./path/to/inputpath
```
実行結果の例は以下のとおりである.
```bash
ファイル: /workspaces/funase-lint/docs/regular/ideasketch_06.pptx
見た目ゴミだとスライドってね,見てもらえないのよ.白紙は殺風景だからやめてね.
16:9 のスライドはやめなさいよ,間延びしすぎて見づらいのよね.
『、』や『。』が出てくるのは文章だからだめだよね.箇条書きで書きなさいな.
可能な限り主観的な評価を取り除くことが工学の文章の考え方です.客観的に得られた情報を使いなさい.
スライド読ませるつもりある?本文のフォントの大きさは最低でも 22 pt 以上にしなさいな.
```
#### 4.2.6. -f, --fix: 自動修正
-f, --fix オプションを用いることで,修正可能なルールについては自動修正できる.
コマンドの入力例は以下のとおりである.
```bash
funase-lint -f ./path/to/inputpath
```
修正前後のスライドの例は以下のとおりである.


#### 4.2.7. -v, --verbose: 詳細出力
-v, --verbose オプションを用いることで,詳細な出力を表示できる.
コマンドの入力例は以下のとおりである.
```bash
funase-lint -v ./path/to/inputpath
```
実行結果の例は以下のとおりである.
```bash
Applying rules to /workspaces/funase-lint/docs/regular/ideasketch_06.pptx...
Applying rule TextFontRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/slide4.xml
Applying rule TextFontRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/slide1.xml
Applying rule TextFontRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/_rels/slide5.xml.rels
Applying rule TextFontRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/_rels/slide3.xml.rels
Applying rule TextFontRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/_rels/slide1.xml.rels
Applying rule TextFontRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/_rels/slide2.xml.rels
Applying rule TextFontRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/_rels/slide4.xml.rels
(中略)
Applying rule FontSizeRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/slide2.xml
Applying rule FontSizeRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/slide3.xml
Applying rule FontSizeRule to file: /tmp/unzippedPptx3136085862347650822/ppt/slides/slide5.xml
ファイル: /workspaces/funase-lint/docs/regular/ideasketch_06.pptx
スライドテーマが白紙になっています.
スライドサイズの比率が 4:3 ではありません.
文中に句読点が含まれています.
曖昧な言葉が使用されています.
フォントサイズが 22 pt 未満のものがあります.
```
#### 4.2.8. .funaseignore による除外機能
.funaseignore による除外設定は,指定されたファイルの親ディレクトリまたは指定されたディレクトリを上限として,リンターでチェックするファイルから最も近い上位ディレクトリに含まれる .funaseignore を自動で参照する.
したがって,コマンドにおいて特に指定する必要はない.
ここでは,例として以下のようなディレクトリ構成を想定する.
```
./funaseignore
├── .funaseignore
├── ideasketch_06_1.pptx
└── ideasketch_06_2.pptx
```
ただし,2 つの pptx ファイルは同一の内容である.
.funaseignore は以下のように指定する.
```txt
*1.pptx
```
コマンドの入力例は以下のとおりである.
```bash
funase-lint ./path/to/inputpath
```
このときの実行結果の例は以下のとおりである.
```
ファイル: /workspaces/funase-lint/docs/funaseignore/ideasketch_06_2.pptx
スライドテーマが白紙になっています.
スライドサイズの比率が 4:3 ではありません.
文中に句読点が含まれています.
曖昧な言葉が使用されています.
フォントサイズが 22 pt 未満のものがあります.
```
実行結果から,`*1.pptx` にマッチする `ideasketch_06_1.pptx` がリンターによるチェックの対象から除外されていることが確認できる.
したがって,たしかに除外ファイルの設定が機能していることがわかる.
#### 4.2.9. .funaselintrc.json によるカスタマイズ機能
.funaselintrc.json によるカスタマイズ機能は,指定されたファイルの親ディレクトリまたは指定されたディレクトリの直下の .funaselintrc.json を自動で参照する.
したがって,コマンドにおいて特に指定すうる必要はない.
ここでは,例として以下のようなディレクトリ構成を想定する.
```
./funaselintrc
├── .funaselintrc.json
└── ideasketch_06.pptx
```
.funaselintrc.json は以下のように指定する.
```js
{
"fixEnabled": false,
"verboseOutput": false,
"outputStyle": "json",
"rules": {
"SlideAspectRule": false,
"SlideThemeRule": false
}
}
```
コマンドの入力例は以下のとおりである.
```bash
funase-lint ./path/to/inputpath
```
このときの実行結果の例は以下のとおりである.
```json
[
{
"filePath": "/workspaces/funase-lint/docs/funaselintrc/ideasketch_06.pptx",
"results": [
{
"ruleName": "PunctuationMarkRule",
"modified": true,
"source": "/tmp/unzippedPptx2548065859524461555/ppt/slides/slide4.xml",
"message": "文中に句読点が含まれています."
},
{
"ruleName": "AmbiguousWordRule",
"modified": false,
"source": "/tmp/unzippedPptx2548065859524461555/ppt/slides/slide1.xml",
"message": "曖昧な言葉が使用されています."
},
{
"ruleName": "FontMinimumRule",
"modified": false,
"source": "/tmp/unzippedPptx2548065859524461555/ppt/slides/slide1.xml",
"message": "フォントサイズが 22 pt 未満のものがあります."
}
]
}
]
```
実行結果から,出力形式が JSON に変更されていることが確認できる.
また,SlideAspectRule と SlideThemeRule が無効になっていることも確認できる.
したがって,たしかにカスタマイズ設定が機能していることがわかる.
### 4.3. 各メンバーの作業内容
開発期間の前半は以下の要領で役割分担をした.
- 西村,高橋 : ルールの調査
- 藤岡,渡邊 : コア機能の実装
開発期間の後半は以下の要領で役割分担をした.
- 西村,高橋,渡邊 : ルールの実装
- 藤岡 : 除外機能やカスタマイズ機能の実装
発表用のスライドおよびデモ動画の作成は藤岡が担当した.
## 5. 考察
### 5.1. 自動修正は難しい
自動修正は見た目に反して難しいことがわかった.
たとえば,自動修正の実行例として示したスライドのアスペクト比の修正について考えてみる.
16:9 のスライドを 4:3 に変更する場合,以下の 3 つの方法が考えられる.
- 全体を引き延ばす
- 背景だけ横方向に短くする
- 背景だけ縦方向に長くする
1 つ目の方法は,画像が含まれていた場合に「画像の縦横比を変更してはいけない」というルールに反する.
また,XML を操作してスライドコンテンツ全体を引き延ばす処理は複雑であり,実装が困難であった.
2 つ目の方法は,画像が見切れてしまうという問題がある.
3 つ目の方法は,スライドサイズが通常よりも大きくなってしまい,フォントサイズ関係のルールがうまく機能しなくなるという問題がある.
自動修正を行った結果別の問題点が生じてしまう場合には,元の問題点を自動修正すべきかという問題がある.
また,もし自動修正するならば,その結果生じた問題点についても自動修正すべきかという問題がある.
さらに,もしそこで自動修正を連鎖的に行う場合,ルールに矛盾があれば無限ループに陥るという問題もある.
このあたりの議論については,既存のリンターの実装を参考にして,適切なアルゴリズムを考える必要があると考えられる.
### 5.2. pptx 形式と自動修正は相性が悪い
pptx 形式は,XML を ZIP で圧縮したものである.
このため,XML を操作することによってスライドの自動修正を行うことができる.
とは言うものの,ZIP の圧縮および展開は処理が重たいので,インタラクティブに修正するのは難しいと考えられる.
たとえば,当初は Visual Studio Code の拡張機能として実装し,ソースコードと同じように「問題」パネルから修正を行えるようにしたいと考えていた.
この場合,問題点を修正するごとに展開と圧縮が実行されるため,処理が非効率になると考えられる.
## 6. 感想
### 6.1. アイデア出し
今回作成したシステムは,ありていに言えば「過激」な部類に該当すると思われる.
そのため,船瀬先生に対して失礼に当たらないように,当初より機能面についてはしっかりと作らなければいけないと考えていた.
結果として,まずまずの完成度までもっていくことができたので,この点については胸をなでおろしている.
その一方で,他のグループを見ていると,もう少しこのような過激なアイデアが増えてもよいのではないかということを感じた.
過激なアイデアが少なかった要因として,「講義前半 2 週で学んだ技術を利用する」という技術的制約があると考えられる.
解決策として,たとえば「講義前半 2 週」ではなく「知能プログラミング演習」とすれば,知能プログラミング演習 I の後半で扱った機械学習を利用することができ,適度な自由度となり面白いアイデアも生まれたのではないだろうか.
### 6.2. 共同開発
今回,チームでプログラミングする際に便利な Git や GitHub を用いた.
Git,GitHub で分からないことをネットを通して調べることでチーム開発で必要な知識を身に着けることができた.
また,チームでプログラミング経験豊富なメンバーと組むことで新たな知識を得ることができた.
知能プログラミング演習 II の Teams のチャンネルを見ていると,ZIP ファイルでソースコードを共有しているグループが散見された.
情報工学科の学生であれば,GitHub などを用いて共同開発を行うことが望ましいと思われる.
共同開発に関する知識は,3 年次前期の「ソフトウェア工学」で学習できる.
ただし,残念ながらこの講義は必修ではない.
したがって,ハッカソンにあたって最低限 GitHub の利用について案内があるとよいのではないかと思う.
また,先ほどの内容に関連して,「自分の環境で動作しない」といったやり取りも散見された.
こうしたトラブルは仮想環境を利用することで解決することができる.
情報工学科の学生であれば,仮想環境を用いて開発を行うことが望ましいと思われる.
しかしながら,CSE では Docker を利用することができないという問題がある.
セキュリティ上の問題などでないのであれば CSE にも Docker をインストールしていただけると嬉しい.
## 7. 参考文献
理系基礎演習の Moodle のページ