OmniAICreator/Qiita-1.07M huggingface dataset:
作って学ぶ Spring Boot アプリケーション (1) -準備編-

#はじめに

現在必要に迫られて英語の勉強をしており、せっかくなら勉強も兼ねて自分にあった学習記録サービスを自分で作ってみよう、と考えてこの記事を書いています。
今回はSpring Bootアプリケーションを作りながら学んでいくというスタンスで開発を進めていきます。
複数回に分けて記事にする予定です。

#前提
必須
- Javaの基本的な知識
- Javaの開発環境
- 基本的なSpringの知識(大体の雰囲気でOK)


あればGood
- Mavenの基本的な知識
- webアプリケーションの入門レベルの知識
- h2データベースの基礎知識
- lombokの使い方

全ての知識がほぼ0の状態から始めます。
よって、上記の初歩的な知識のみを持っている状態から進めていきます。

#環境
開発言語：Java８
フレームワーク：Spring（Springを学ぶのが目的のため確定）
データベース：H2（なんとなく）
ビルドツール：Maven(なんかよく分からんくても大丈夫)
開発環境：IntelliJ(お好きな開発環境でどうぞ)

#要件定義
今回は学習記録システムを開発します。

###### データベース
学習教材と学習記録をデータとして保持して、それぞれ下記の要素を持っているものとします。

- 教材テーブル(Subject)
    - 項目ID(Long)
    - 学習項目(String)
    - タイプ(教科等)(String)
- 学習記録テーブル(Record)
    - 記録ID(Long)
    - 日付(Date)
    - 項目(Subject)
    - 時間(Double)
    - 備考(String)

######要件
以下の操作ができるようにします。

- 項目一覧の取得 () -> (List<Subject>)
- 項目の追加 (SubjectName, Type) -> (Subject)
- 項目の削除 (SubjectID) -> ()
- 記録一覧の取得 () -> (List<Record>)
- 記録の追加 (Date, SubjectID, Hours) -> (RecordID)
- 記録の削除 (RecordID) -> ()

#開発
## アプリケーションの作成
まず、雛形となるアプリケーションをSpring Initializerを利用して作成する。
Spring Initializer : Springアプリケーションの雛形を簡単に作成してくれるサービス
https://start.spring.io/

Spring Initializerのページに行ったら以下の項目を編集してください。
Groop名：パッケージ名になります。好きな名前でどうぞ
Artifact名：アプリケーション名になります。好きな名前で
Dependencies：以下を追加してください
- Spring Web
- Spring Data JPA
- H2 Database
- Lombok

![スクリーンショット 2020-05-18 20.33.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271486/9423db7b-1020-c451-1a59-4e9cdb40fde1.png)

これでGenerateを押すとダウンロードが始まります。
終わったらzipを解答して、プロジェクトを好きなディレクトリに配置してください。

# 初期設定
ここまで出来たら、開発環境から先ほどのプロジェクトを開いてください。
その後、application.propertiesファイルを開き、${...}の中を適宜書き換えて以下の情報を追記してください。

```application.properties
# datasource
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:./h2db/${プロジェクト名}
spring.datasource.username=${好きな名前}
spring.datasource.password=

# h2 for debug tool
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.web-allow-others=true

# データをベースのデータを永続化したい(起動時に消したくない)場合はこのコメントアウトを外す
# spring.jpa.hibernate.ddl-auto=update
```


ここまで来たらメイン関数があるクラスを開き、実行してみてください。
エラーがでなければ、これで下準備は終了です。

次からはいよいよ開発を行って行きます。

[作って学ぶ Spring Boot アプリケーション(2) -開発編-](https://qiita.com/sgr0416st/items/8efd4acdb529f0304067)
gzip 圧縮されたテキストファイルを書き出す

こんにちは。
Python で gzip 圧縮されたテキストファイルを書き出しました[^1]。

[^1]: 参考："[Using csv.DictWriter to output an in-memory gzipped csv file?](https://stackoverflow.com/questions/54559843/using-csv-dictwriter-to-output-an-in-memory-gzipped-csv-file)" (Stack Overflow) 

今回例は CSV データを中身としました（csv モジュール利用）。

```console
$ ./write_csv_gzfile.py temp.csv.gz
$ gzip -dc temp.csv.gz
a,b
1,2
3,4
```

```write_csv_gzfile.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import io, csv, gzip, sys
from pathlib import Path

def writeCSV(f, newline='\n'):
    dat = [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]
    w = csv.DictWriter(f, dat[0].keys(), lineterminator=newline)
    w.writeheader()
    w.writerows(dat)

buffer = io.BytesIO()
with gzip.GzipFile(fileobj=buffer, mode='wb') as compressed:
    with io.TextIOWrapper(compressed, encoding='utf-8', newline='\n') as wrapper:
        writeCSV(wrapper)
p = Path(sys.argv[1])
p.write_bytes(buffer.getvalue())
```
GarageBandでフェードイン、フェードアウト


#GarageBandでフェードイン、フェードアウト
曲を作ったり編集するとき、雰囲気を出すためにだんだん音量を上げるかっこいいイントロや、しっとりと曲を終わらせるために少しずつ音量を下げたい場合ってありますよね？

GarageBandでは、そのような操作がとても簡単にできるので、備忘録として置いておきます。
##操作方法
ミックス > オートメーションの表示
![スクリーンショット 2020-05-18 23.38.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630426/3334c0e4-3373-9f5d-f720-bdfcd62ccbdb.png)


トラックに黄色の線が入る。
赤枠のアイコンはONの状態にする。（現在はONです）
![スクリーンショット 2020-05-18 23.41.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630426/2f12f181-0974-e932-2a76-a4973e83ab98.png)


線上をクリックすると点を打つことができる。
点は任意の箇所にいくつも打つことができて、再度クリックすること削除。

あとは、点を上下に移動することで、フェードイン、フェードアウトが設置できる。
![スクリーンショット 2020-05-18 23.49.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630426/fb55ce47-cb4a-a61c-2f9f-19349500d7c8.png)
AWS EC2でAWS SDK for PHPインストール（PHP7.2＋Apache2.4.41 + OPCashe + Composer）


AmazonLinuxEC2でAPI叩いて、DynamoDBにデータを保存する流れを、
PHPでやりたかったので、[AWSSDKforPHP](https://docs.aws.amazon.com/ja_jp/sdk-for-php/v3/developer-guide/welcome.html)を入れようとしました。

しかし、色々課題が発生したので、自分用、備忘録として書き起こします。
助力になれば、幸いです。

#AmazonLinuxのバージョン
```
$ cat /etc/system-release
Amazon Linux release 2 (Karoo)
```

#AmazonLinux2　ExtrasLibraryで　PHP7.2をインストール
```
＄ sudo amazon-linux-extras install php7.2
$ sudo yum install php php-mbstring

$ sudo yum list installed | grep php
php-cli.x86_64                        7.2.30-1.amzn2                 @amzn2extra-php7.2
php-common.x86_64                     7.2.30-1.amzn2                 @amzn2extra-php7.2
php-fpm.x86_64                        7.2.30-1.amzn2                 @amzn2extra-php7.2
php-json.x86_64                       7.2.30-1.amzn2                 @amzn2extra-php7.2
php-mysqlnd.x86_64                    7.2.30-1.amzn2                 @amzn2extra-php7.2
php-pdo.x86_64                        7.2.30-1.amzn2                 @amzn2extra-php7.2
```
参考：https://qiita.com/owlbeck/items/20f3e5402cb782f6291e

#Apache　をインストール
```
$ sudo yum install httpd
$ systemctl start httpd
$ systemctl status httpd
● httpd.service - The Apache HTTP Server
   Active: active (running) 
```

#OPCashe　をインストール
```
sudo yum install php-opcache
```
#Composer をインストール

```
$ curl -sS https://getcomposer.org/installer | php
$ ls
composer.phar

$ php　composer.phar
$ mv composer.phar /usr/local/bin/composer
$ composer
```
最後の二行はPATHが通っている場所に引っ越しただけです。これでかっこいいロゴを表示できます。
参考：https://getcomposer.org/doc/00-intro.md
参考：https://qiita.com/kakijin/items/02364adacf36410f449e

#AWS SDK for PHP　の使用開始

プロジェクトのルートフォルダでやってください。

```
$ sudo -i
$ cd /usr/local/bin/composer
$ vi composer.json //jsonに書き込み
```

```json:composer.json
{
    "require": {
        "aws/aws-sdk-php": "3.*"
    }
}
```
PHP7.2系に対応しているのが、AWSSDKforPHP3系でした。

```
$ php composer.phar install
$ composer require aws/aws-sdk-php
```

```php:phpのファイルに書き込んで終了
require '/path/to/sdk/vendor/autoload.php';
```

#終了
Node.jsでエラー: No valid exports main found for '/SOME_PATH/node_modules/uuid'

# 原因
Node.jsのバージョンが不具合のあるものなため
バージョンを`14.1.0`に上げたら解決しました。

# 環境

```bash
sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.4
BuildVersion:	19E287
```
オフラインで Python 環境構築

インターネットに接続していない端末に Python パッケージをインストールしたいときのやり方メモ。

インストールしたいパッケージの一覧は `requirements.txt` にまとまっているものとする。

Windows 10 (x86_64) + Anaconda3 環境で検証したが、他のプラットフォームでも同様にできる気がする。

## オンライン端末でパッケージをダウンロードする
``` console
$ pip download --dest=src -r requirements.txt
```

このオンライン端末はオフライン端末 (インストール先) とプラットフォームが同じものを使う。 `pip download` には `--platform` というオプションがあるので、これをうまく指定すると異なるプラットフォームでもできるのかもしれないが未検証。
参考： [pip download — pip documentation](https://pip.pypa.io/en/stable/reference/pip_download/)

`src` ディレクトリを見ると、パッケージが wheel や tarball の形式でダウンロードできていることがわかる。

## オフライン端末でパッケージをインストールする
オンライン端末でダウンロードしたパッケージファイルをオフライン端末にコピーし、 `src` ディレクトリ以下に置いてあるものとする。

``` console
$ pip install --no-index --find-links=src -r requirements.txt
```

これで `requirements.txt` をもとにパッケージのインストールを試みるが、PyPI (インターネット) からではなく `src` ディレクトリにあるパッケージを探しに行くようになる。
AWS IP アドレスの範囲

#はじめに
セキュリティグループのInBound、OutBoundにてAWSのサービス（API Gateway、S3など）を許可するように設定したい場合は、AWS IP アドレスの範囲を見て設定可能です。

#AWS IP アドレスの範囲
https://ip-ranges.amazonaws.com/ip-ranges.json

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/f1022093-2714-77ab-0a72-32b7f0a59213.png)

#AWS の IP アドレス範囲の変更通知
AWS の IP アドレス範囲に変更がある際に、SNS通知設定をし、受信したら差分をメンテする。

設定方法：https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-ip-ranges.html#subscribe-notifications

#PythonであるサービスのIPを取り出す例
```python
import urllib.request
import json

def get_ip_groups_json(url):

    response = urllib.request.urlopen(url)
    ip_json = response.read()

    return ip_json

def get_ranges_for_service(ip_range_url, service, subset):

    ip_ranges_json = json.loads(get_ip_groups_json(ip_range_url))

    service_ranges = list()

    for prefix in ip_ranges_json['prefixes']:
        if prefix['service'] == service and subset == prefix['region']:
            service_ranges.append(prefix['ip_prefix'])

    return service_ranges


ip_ranges = get_ranges_for_service('https://ip-ranges.amazonaws.com/ip-ranges.json', 'S3', 'ap-southeast-1')

for ip in ip_ranges: print(str(ip))
```

結果：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/002eda28-82a5-188b-e419-1a87f2911f1d.png)


#Lambdaで自動更新
メンテ作業を自動化にしたい場合は、Lambdaでセキュリティグループを更新することも可能です。
サンプル：[update-security-groups](https://github.com/aws-samples/aws-cloudfront-samples/tree/master/update_security_groups_lambda)

参考Doc：[AWS IP アドレスの範囲](https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-ip-ranges.html)

以上
Vim のプラグインマネージャ Volt で plugconf に記述した処理が実行されない

## 問題点

下記のサイトを見て Vim のカスタマイズをしていました。

[Vimのプラグインマネージャ「Volt」を使おう - BLog](https://eivy.github.io/2018/02/19/vim-volt.html)

プラグイン毎の設定は plugconf/ 内の foo.vim に記述する事ができるので、 .vimrc の記述量を減らし、プラグインに依存した設定を書かなくて良くなります。

今回、とあるプラグインが読み込まれた後の設定を記述したかったので、 foo.vim 内の s:on_load_post() に処理を記述しましたが、どうも処理が走っていないようでした。

## 解決方法

色々調べた結果、下記サイトを見て解決しました。

[plugconf is not read - gitMemory](https://gitmemory.com/issue/vim-volt/volt/274/478779150)

plugconf/ 内の処理を反映させるには、 volt build する必要があるようです。

```zsh:zsh
% volt build
```

これで無事に処理が反映されました。
Excel におけるSUMIF関数とSUMIFS関数の判定差異

ちょっと仕事で相談を受けて調べていたら、不具合っぽい動きを見つけたのでメモ代わりに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25184/e3f884eb-3627-c986-4eb2-d87f06ae7a31.png)


こんな感じの表があって、各商品に対する数量合計を行いたいとき。
通常であればSUMIF関数を使うことになります。
このケースで言えば

> =SUMIF(D3:F8,"リンゴ",G3:H8)

のような形ですね。
上記関数は正常に動作し、この例でいうと11を返します。

ところが、ここでSUMIFではなく、SUMIFSを使うとエラー（#VALUE!）になるということでした。

> =SUMIFS(G3:H8, D3:F8, "リンゴ")

条件式としては1つしかないためにわざわざSUMIFSを使う必要はないのですが、かといって、SUMIFS関数は必ず条件を複数用意しなければならないわけではないはず。

## 結合セルの差異
結論から言うと、商品列は3列の結合セル。数量セルは2列の結合セルであることが原因でした。

これが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25184/dda2db8c-da1b-d183-7cb5-f7e807a04758.png)

のように、同じ数の結合であれば正常に動作しますが、異なる場合にはエラーを返してしまいます。

[エラー値 #VALUE! エラーは、SUMIF または SUMIFS 関数](https://support.office.com/ja-jp/article/%E3%82%A8%E3%83%A9%E3%83%BC%E5%80%A4-value-%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AF%E3%80%81sumif-%E3%81%BE%E3%81%9F%E3%81%AF-sumifs-%E9%96%A2%E6%95%B0-e65ce689-978e-44b1-a649-160ed5f13b5a)

公式の上記ページには「条件範囲引数と合計対象範囲引数が一致しない。」という形で紹介されているのが、結合セルに対しても有効ということでしょうか…。
若干、SUMIFとSUMIFSとで判定が異なるというのは不具合なのではないだろうか？という気がしないでもないですが。。

ちなみに、結合セルをマウスで選択してしまうと複数列の範囲選択になってしまいますが、これを手動で

> =SUMIFS(G3:G8, D3:D8, "リンゴ")

という形に先頭列だけを選ぶ形にすることで問題なく動作するようになります。
これも、条件範囲と合計範囲の差をなくすという意味では同じことですね。
Mac で Homebrew をインストールする

# 概要

Proxy 経由で [Homebrew](https://brew.sh/) をダウンロードしようとした所、色々面倒臭かったのでメモ

# 環境

機種: MacBook Pro 16
OS: macOS Catalina 10.15.3

# 解決方法

[Homebrew](https://brew.sh/) のサイトからコピペしてターミナル上で実行すると下記のエラーが出てインストールできなかった。

```zsh:エラー
Failed to connect to raw.githubusercontent.com port 443: Operation timed out
```
下記サイトを参考にしてプロキシを設定した。
curl だけでなく git も設定が必要。

whirlpoolup’s diary - [homebrewがインストールできなかった](http://whirlpoolup.hatenablog.com/entry/2017/05/28/222404)

プロキシ設定は今後も必要になるので、下記を参考にして設定を追加した。

[proxy設定まとめ(Mac開発環境)](https://qiita.com/coa00/items/c28d74485e1057c59595)

```zsh:.zshenv
export http_proxy=http://$your_proxy
export https_proxy=$http_proxy
export HTTP_PROXY=$http_proxy
export HTTPS_PROXY=$http_proxy
```
```git:git
git config --global http.proxy $http_proxy
git config --global https.proxy $http_proxy
```
```curl:.curlrc
proxy=http://$your_proxy
```
【Rails】Railsチュートリアルでの学び

# 【Rails】Railsチュートリアルでの学び
## 文字数の制限をするバリデーションをかける

```:***.rb
class *** < ApplicationRecord
  validates :カラム名,length: { maximum: 140 }
end
```

## 空欄のまま投稿するのを制限するバリデーションをかける

```:***.rb
class *** < ApplicationRecord
  validates :カラム名,presence: true
end
```
GitLabとSourceTreeを連携させる手順と参考リンク(SSH認証)

## GitLabとSourceTreeを連携させるのに苦労した
　会社でGitLabとSourceTree(GitGUI操作ツール)を用いて開発を行っている。趣味でコーディングするにあたり、自宅にもその環境を構築しようとしたが、必要手順が分からず結構手間取った。そのため、GitLabからSoureTreeを連携させるまでに必要な手順を解説する。趣味でもGitとSourceTreeで快適な開発ライフを！
※ここでは、SSH認証で連携する手法を記述する。HTTP認証については触れない

### GitLabとSourceTreeを連携させるまでの手順と参考リンク
　手順とその参考になるリンクをまとめていく。
#### 1. GitLabアカウント作成
　当然、GitLabのアカウントが無ければならない。特に詰まることはないので解説は省略。

#### 2. クライアントPCでSSHキーを生成。GitLabにSSHキーを登録
　次に、GitLabからソースをクローンするためのSSHキーを登録する。SSHとは、クライアントPCとWebサーバー側でセキュアに通信を行うための仕組み。Webサーバー上にあるレポジトリとクライアントPCのデータを安全にやり取りするには欠かせない。
##### 参考にさせていただいた記事
- Windows ：[GitLabにSSHで接続するまでの手順](https://qiita.com/kyamawaki/items/07fb3332cf3c2f47728a)
- Mac：[SSH認証キーをGitLabに登録・設定手順 覚書](https://qiita.com/redamoon/items/07e445d1fce360cb5fa3)

SSHKEYの発行後、configファイルの作成も忘れずに。


#### 3. SoureTreeをインストール
　SoureTreeをインストールする。ここでは、特段詰まることは無いかと。インストール時に、製作元のアトラシアンのGit WebサービスであるBitBuketのアカウントを作らされる。デフォルトの連携アカウントがBit Buketとなるので、後でGitLabに変える。

##### 参考にさせていただいた記事
[SourceTree(3.0.15)をインストールしてみた](https://qiita.com/tetsu831018/items/bb6ecf15ca5f67e5879a)
　
#### 4. SourceTreeにSSHKEYを登録する
　先ほど、GitLabに登録するために作成したSSHを、SourceTree側にも設定する。手順は参考リンクに。SSHキーをすでに作成している場合は、Generateの必要は無く、既に作成したものをLoadする。
##### 参考にさせていただいた記事
[SourceTreeでGithubの認証に秘密鍵を使う (Windows)](https://qiita.com/reflet/items/4f7b5c4a312bc27df10e)
記事題目に「GitHub」とあるが、GitLabも同一手順で可能。
#### 5. SourceTreeがGitLabにアクセスするためのトークンを発行
　次に、SourceTreeがGitLabにアクセスするためのトークンを発行する。これをしないと、GitLabのアカウントをSourceTree上で連携させることができない。手順は参考リンクに。ここで発行したパスワードをSoureTree側に入力する。
##### 参考にさせていただいた記事
[GitLabアカウントをSourceTreeに登録する方法] (https://qiita.com/TakuyaHara/items/0424e188f5073aa362a5)

#### 6.SoureTree上でトークンを用いてGitLabアカウントを登録
　上記リンクにも参考がある。
SoureTree上で、GitLabアカウントを登録する。アカウント設定のパスワード入力欄には、4. で発行したGitLabのPersonal Access Tokensを入力する。発行画面を開いたまま行う。ログインに成功すれば、自分のGitLabのプロジェクト、ソースが即座に連携される。

---
以上、GitLabとSource Tree連携させる手順を紹介した。各手順の詳細は優秀なリンク先を参考されたい。
[excel] エクセルの表で、特定の曜日だけセルの色を自動で変えたい

**もくじ**
→https://qiita.com/tera1707/items/4fda73d86eded283ec4f

# やりたいこと
エクセルの表で日付を扱うときに、特定の曜日だけセルの色を自動で変えたいときがある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/be64bae7-47ed-1a2e-3774-95f8a389e346.png)

条件付き書式を使えば、簡単に実現できる。
いつもやっていて大した話ではない。が、だいたいは覚えているのだが、毎回細かいところで具体的にどういう設定とか書き方すればよかったか忘れてしまうので、いっぺん書き留めておく。

# 忘れること

以下の３点を、大体忘れる。

1. 曜日を取得する関数がなんだったか？たしかWEEKがどうとか、DAYがどうとか？
- WEEKがどうとかDAYがどうとかいう関数は、曜日ごとに値を返してくれるんだった気がするが、どんな値が返るんだったか？
- 条件付き書式の「数式を使用して、書式設定するセルを決定」に式を書いてやればよいことは覚えてるが、具体的にどう書けばよかったのか？？

# やり方

### 1.WEEKDAY関数を使う
`WEEKDAY`関数を使えば、曜日ごとの値をとってこれる。

### 2.基本は、日曜=1、月曜=2 ～ 土曜=7
ただし、WEEKDAYに渡す第二引数の値によって、戻ってくる値が変わる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/50ccd94b-cc29-c751-5ab2-4fd35876e705.png)

### 3.「=WEEKDAY(色を変えたいセル)=曜日の値」と書く
例えば下記のようにしたかったら、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/134bf091-d6ec-84a3-1c4c-3f8ed8ae1aa4.png)

下記のように書く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/023d3d29-554d-897f-def2-c997e613d1a4.png)

あとは、横にコピーしていけばOK。

# メモ(書式ルールの編集)まで行くには

- [ホーム] > [条件付き書式] > [新しいルール]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/4b284ffb-ff2d-af93-a4e6-f28200063ac2.png)
- [新しい書式ルール]ダイアログで[数式を使用して、書式設定するセルを決定]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/193ef8c7-29c3-dbbc-e195-09cca8800ac4.png)
- ここに入れればOK。
【Python】【BFS】AtCoder Beginner Contest 168-D [.. Double Dots]

※競技プログラミングででてくるアルゴリズムの実装方法をまとめる自分用備忘録です。

#問題文　(.. Double Dots)


[ABC168-D Double Dots](https://atcoder.jp/contests/abc168/tasks/abc168_d)

>あるところに、洞窟があります。
洞窟にはN個の部屋とM本の通路があり、部屋には1からNの、通路には1からMの番号がついています。
通路iは部屋Aiと部屋Biを双方向につないでいます。どの2部屋間も、通路をいくつか通って行き来できます。
部屋1は洞窟の入り口がある特別な部屋です。
洞窟の中は薄暗いので、部屋1以外の各部屋に1つずつ道しるべを設けることにしました。
各部屋の道しるべは、その部屋と通路で直接つながっている部屋の1つを指すように置きます。
洞窟の中は危険なので、部屋1以外のどの部屋についても以下の条件を満たすことが目標です。
その部屋から出発し、「いまいる部屋にある道しるべを見て、それが指す部屋に移動する」ことを繰り返すと、
部屋1に最小の移動回数でたどり着く。
目標を達成できる道しるべの配置が存在するか判定し、存在するならばそのような配置を1つ出力してください。

#解答
```python
from collections import deque

mi = lambda:list(map(int,input().split()))
mix = lambda x:list(mi() for _ in range(x))
##########
def main(n,m,l):
    #グラフの作成
    g = creategraph(n,l)
    #独立した部屋がある場合はNG
    for i in range(1,len(g)):
        if len(g[i]) == 0:
            print("No")
            return
    #BFSで道標を作成
    navi = bfs(n,g)
    #部屋1を除く部屋の道標が更新されていなければNG
    if min(navi[2:]) == 0:
        print("No")
    else:
        print("Yes")
        for i in navi[2:]:
            print(i)
    
#BFS幅優先探索
def bfs(n,g):
    navi = [0]*(n+1)
    navi[1] = -1
    q = deque()
    q.append(1)
    while len(q) > 0:
        #キューから現在地を取り出す
        cp = q.popleft()
        #現在地の隣接点リストを取得
        np = g[cp]
        #隣接点が未探索ならキューに入れる＋道標更新
        for i in np:
            if navi[i] == 0:
                navi[i] = cp
                q.append(i)
    return navi
    
#各Nodeの隣接点を保持するリストを生成する
def creategraph(n,l):
    g = {i:[] for i in range(n+1)}
    for a,b in l:
        g[a].append(b)
        g[b].append(a)
    return g

def resolve():
    n,m = mi()
    l = mix(m)
    main(n,m,l)

if __name__ == "__main__":
    resolve()
```
Python入門　開発環境を整えよう

以下のサイトの手順で行いました。
https://prog-8.com/docs/python-env

③pyenvのインストールでコマンドを実行する際に
　~/.bash_profile に権限（ロック）がかかっていたためコマンドを認識してくれませんでした。以下を実行してからコマンドを実行したところ正しくインストールできました。

1.ルートフォルダを表示する
command + shift + G
2.隠しファイルを表示する
command + shift + .（コマンド + シフト ＋ ピリオド）
3.bash_profileをクリックし、「情報を見る」からロックを解除
【Golang】defer(遅延処理)

#【Golang】defer(遅延処理)
Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。

```
package main 
//defer 遅延実行
//goroutinやファイルの書き込み、読み込みでよく使われる
//Pythonのwithのよう

import (
	"fmt"
	"os"
)



func main(){
	//
	defer fmt.Println("最後に実行される")
	fmt.Println("最初に実行")

	//3,2,1で実行される
	fmt.Println("run")
	defer fmt.Println(1)
	defer fmt.Println(2)
	defer fmt.Println(3)
	fmt.Println("success")

	//主な使われ方
	//fileを開く
	//_はエラーハンドリング
	file, _ := os.Open("./if.go")
	//最後に閉じる
	defer file.Close()
	//バイト配列作成(文字数)
	data := make([]byte, 100)
	//バイト配列分読み込む
	file.Read(data)
	//文字列に変換して出力
	fmt.Println(string(data))
}
```
ミルクボーイをjavascriptのclass記述にしてみた。

お題を決めたら、すぐネタが作りやすいミルクボーイの漫才。
自分の知識定着のために、javascriptのclass記述で書いてみました。

コーンフレークと最中の振りの部分だけを記述。
正しいことならtrueと記述しました。

```html:milkboy.html
 <body>
    <div id="container">
      <p class="cornflakes true">
        あのー甘くてカリカリしてて　で　牛乳とかかけて食べるやつやって言うねんな
      </p>
      <p class="cornflakes">
        オカンが言うには　死ぬ前の最後のご飯もそれで良いって言うねんな
      </p>
      <p class="cornflakes true">
        なんであんなに栄養バランスの五角形デカイんか分からんらしいねん
      </p>
      <p class="cornflakes">
        オカンが言うには　晩ご飯で出てきても全然良いって言うねんな
      </p>

      <p class="monaka">スーパーで子どもがそれ欲しくて泣いてた言うねんな</p>
      <p class="monaka true">食べたら、皮がぜんぶ上あごにひっつくらしいねん</p>
      <p class="monaka">
        オカンが言うにはな、1個食べ出したら止まらへんって言うねん
      </p>
      <p class="monaka true">皮の模様がなんか怖いらしい</p>
    </div>
    <script src="milkboy.js"></script>
  </body>
```

cssの取ってくるクラスと日本語名を引数として
forEachでひとつずつに分けて、そのテキスト部分を出力。
そのテキストがtrueのクラスが含むか含まないかで処理を変えます。

```javascript:milkboy.js
class mother_forget {
  constructor(keyword, kana) {
    this.kana = kana;
    this.furis = document.querySelectorAll(keyword);
  }
//掛け合い処理
  kakeai() {
    this.furis.forEach((furi) => {
      console.log(furi.innerText);
      if (furi.classList.contains("true")) {
        console.log(this.kana + "やないかい");
      } else {
        console.log("ほな" + this.kana + "ちゃうやないかい");
      }
    });
  }
}

const milkboy1 = new mother_forget('.cornflakes', 'コーンフレーク')
milkboy1.kakeai();

const milkboy2 = new mother_forget('.monaka', '最中')
milkboy2.kakeai();

```

出力結果
確かにできてる。

![kakeai.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376165/6c2d375a-52fb-e13b-d96b-60434dd0af86.jpeg)

FUJIWARAのフジモンの
「顔でかいからや」関数ならもっと簡潔にできる。全く意味がない。。
AtCoder Beginner Contest 168

3回目の挑戦。
##A問題
case文を使うための例題、なのだが全部書き下ろしてパス

```ruby:abc168a.rb
n = gets.chomp.to_s[-1,1]
#puts n
#puts n[-1,1]
if n=="3"
    puts "bon"
else
    if  n== "0"
    puts "pon"
    else
        if n== "1"
        puts "pon"
        else
            if n== "6"
                puts "pon"
            else
                if n=="8"
                    puts "pon"
                else
                    puts "hon"
                end
            end
        end
    end
end
```
ちゃんとcase文で書き直し。

 ```ruby:case.rb
n = gets.chomp.to_s[-1,1]
case n 
when "3"
    puts "bon"
when "0","1","6","8"
    puts "pon"
else
    puts "hon"
end
```
##B問題
出力を場合分けするより、長い場合は切り取って末尾に３点ドット付け足した方がスマートですね。

```ruby:abc168b.rb
k = gets.chomp.to_i
s = gets.chomp.to_s
if s.length <= k
    puts s
else
    print s[0..k-1]
    print "..."
end 
```
##C問題
2針とも先端の座標が求まるので、２点間の距離を直接計算。
各数値を整数のまま扱ってテストケースの半分AC半分WAとなったので、しばらく考えてfloatに変換してAC.
解説にあったように余弦定理で解くと三角関数3個分計算量減るけど、ループないからこれでも良いかな?

```ruby:abc168c.rb
imput = gets.chomp.split(" ").map!{|item| item.to_i}
a = imput[0].to_f
b = imput[1].to_f
h = imput[2].to_f
m = imput[3].to_f

hang = Math::PI*(30*h + m/2)/180
mang = Math::PI*m*6/180

hy = Math.sin(hang)*a
hx = Math.cos(hang)*a
my = Math.sin(mang)*b
mx = Math.cos(mang)*b
puts Math.sqrt((hy-my)**2 + (hx-mx)**2)
```
短針を座標軸とすれば三角関数2つ分の計算は減る。

```ruby:abc168c.rb
imput = gets.chomp.split(" ").map!{|item| item.to_f}
a = imput[0]
b = imput[1]
h = imput[2]
m = imput[3]

hang = Math::PI*(30*h + m/2)/180
mang = Math::PI*m*6/180
ang = mang - hang

mx = Math.cos(ang)*b
my = Math.sin(ang)*b

puts Math.sqrt((a-mx)**2 + (my)**2)
```

この辺りで60分超えてD問題読んで解けそうにないので断念。
D/E/Fに挑むにはアルゴリズムの例題解いて身に付けるしかないか。
今回のA問題のように力技依存しないように定番過去問の数こなす必要ありそう。
Nuxt/Componentsモジュールを使ってみた 

## Nuxt/componentsとは

解説によれば、「importなどしなくても自動的にコンポーネントを読み込んでくれる」モジュールです。
便利そうなので早速使ってみましょう。

## Nuxtインストールとモジュールのインストール

```bash
# Nuxt
yarn create nuxt-app <project-name>

# Nuxt/Components
yarn add --dev @nuxt/components

```

## nuxt.config.jsに追加

```javascript
export default {
  buildModules: [
    // TODO: Remove when upgrading to nuxt 2.13+
    '@nuxt/components'
  ]
}
```

※TypeScript使用している方は、すでに`@nuxt/typescript-build`モジュールが入っていると思うので消さないようにご注意を

※Nuxt v2.13はまだ(2020/05/18現在)リリースされていないので大丈夫ですが、
今後は標準でこのモジュールがインストールされるようなので、アップグレードの際はご注意を。

## Hello,world!してみる

```vue:index.vue
<template>
  <div class="container"><HelloWorld /></div>
</template>

```

index.vueに上記のようにテンプレートブロックだけ書きます。普通はscriptブロック内でimportしないと使えませんが、今回は書きません。

カスタムタグに合わせて`HelloWorld.vue`という名前のファイルを`components`に入れてみましょう。

```vue:/components/HelloWorld.vue
<template>
  <div>
    <h1>Hello, world!</h1>
  </div>
</template>
```

`HelloWorld.vue`もかなり簡単に書いてみました。やはりテンプレートブロックしか書きません。

## 結果
![コメント 2020-05-18 225121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294146/aa5fefb4-9c31-fa9e-bd9b-5c44f5939cb6.png)

できました！
importしていないにも関わらず自動的にカスタムタグと同じvueファイルを読み取っています！



## 終わりに

最速紹介ということで使い方だけ紹介しましたがとても便利です
早く安定版標準になってほしいものです。
PowerPointのFontをすべて変更するVBA (グループ化されていても!)

### やりたいこと
PowerPointで、すべてのフォントを一括で変更したい。
オートシェイプや図形、表、グラフなどを想定。
グループ化されていると、処理できなくなるので、グループ内のシェイプを再帰的に探しに行く。
とりあえず、下記のマクロで、テスト環境ではすべてのフォントがMeiryo UIに変更される。
nameFontの内容を、他のフォントに変更すれば、他のフォントへの変更も可能。

```vb:Module1
'   FontをMeiryo UIに変更する
Public Sub makeFontMeiryoUI()
    Const nameFont As String = "Meiryo UI"

    Dim col As Collection
    Dim shp As Shape
    
    Set col = New Collection
    
    Call getColShapeFromPresentation(col)   '   Presentation全体のShapeに対して処理する場合
    Call getColShapeFromSlideMaster(col)   '   SlideMasterに対しても処理をする場合
    
    For Each shp In col      '各Shapeに対して処理
        Call changeFont(shp, nameFont) 'Fontを変更する
    Next
    
End Sub

' Fontを変更する
Private Sub changeFont(ByRef shp As Shape, ByVal nameFont As String)
    Dim s As Shape
    If shp.HasTextFrame Then
        Call setFontName(shp.TextFrame.TextRange.Font, nameFont)
    ElseIf shp.HasSmartArt Then
        For Each s In shp.GroupItems
            Call changeFont(s, nameFont)
        Next
    ElseIf shp.HasTable Then
        Dim c As Cell, r As Row
        For Each r In shp.Table.Rows
            For Each c In r.Cells
                Call changeFont(c.Shape, nameFont)
            Next
        Next
    ElseIf shp.HasChart Then
        Call setFontName(shp.Chart.Format.TextFrame2.TextRange.Font, nameFont)
        For Each s In shp.Chart.Shapes
            Call changeFont(s, nameFont)
        Next
    End If
End Sub

Private Sub setFontName(ByRef f As Object, ByVal nameFont As String)
    If TypeName(f) = "Font" Or TypeName(f) = "Font2" Then
        f.Name = nameFont
        f.NameFarEast = nameFont
        f.NameAscii = nameFont
        f.NameComplexScript = nameFont
    Else
        Debug.Print "font type:", TypeName(f)
    End If
End Sub

'   Presentation全体のShapeに対して処理する場合
Public Sub getColShapeFromPresentation(ByRef col As Collection)
    Dim sld As Slide
    Dim shp As Shape
    For Each sld In ActivePresentation.Slides
        For Each shp In sld.Shapes
            Call putShapeIntoCol(shp, col)
        Next
    Next
End Sub

'   選択されたSlide内のShapeに対して処理する場合
Public Sub getColShapeFromSlide(ByRef col As Collection)
    Dim shp As Shape

    If ActiveWindow.Selection.Type < ppSelectionSlides Then Exit Sub
    For Each shp In ActiveWindow.Selection.SlideRange.Shapes
        Call putShapeIntoCol(shp, col)
    Next
End Sub

'   Group化されている場合も、個別のShapeをcolコレクションに格納
Public Sub putShapeIntoCol(ByRef shp As Shape, ByRef col As Collection)
    Dim s As Shape
    If shp.Type <> msoGroup Then
        col.Add shp
    Else
        For Each s In shp.GroupItems
            Call putShapeIntoCol(s, col)
        Next
    End If
End Sub

'   SlideMasterに対して処理する場合
Public Sub getColShapeFromSlideMaster(ByRef col As Collection)
    Dim shp As Shape
    Dim d As Design
    For Each d In ActivePresentation.Designs
        For Each shp In d.SlideMaster.Shapes.Placeholders
            Call putShapeIntoCol(shp, col)
        Next
    Next
End Sub
```

### 参考
フォントを一括変更するPowerPointマクロ
https://www.relief.jp/docs/powerpoint-macro-replace-fonts.html

*リンク先のマクロは、グループ化されているときや、表やグラフが含まれているときにうまくフォントが変わらない。
VPC エンドポイントとは

#VPC エンドポイント
> VPC のインスタンスは、サービスのリソースと通信するためにパブリック IP アドレスを必要としません。VPC と他のサービス間のトラフィックは、Amazon ネットワークを離れません。

## インターフェイスエンドポイント
> インターフェイスエンドポイントは、サポートされるサービスを宛先とするトラフィックのエントリポイントとして機能するサブネットの IP アドレス範囲のプライベート IP アドレスを持つ Elastic Network Interface です。インターフェイスエンドポイントは、プライベート IP アドレスを使用してサービスにプライベートにアクセスできるようにするテクノロジである AWS PrivateLink を使用します。

<img width="713" alt="スクリーンショット 2020-05-18 22.46.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321923/82f29e29-6600-9a35-f748-b747796a4c02.png">

プライベート DNS を使用するには、VPC 属性のenableDnsHostnames および enableDnsSupport を true に設定する必要があります。

## ゲートウェイエンドポイント
> ゲートウェイエンドポイントは、サポートされる AWS のサービスを宛先とするトラフィックのルートテーブルで、ルートのターゲットとして指定するゲートウェイです。以下の AWS のサービスがサポートされています。

* S3
* DynamoDB

<img width="613" alt="スクリーンショット 2020-05-18 22.48.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321923/7f2da0eb-5dec-8f82-3bab-2a4d1659a588.png">

###VPC エンドポイント によるサービスのアクセスコントロール
> エンドポイントを作成するときは、接続先のサービスへのアクセスを制御するエンドポイントポリシーを、エンドポイントにアタッチできます。エンドポイントのポリシーは、JSON 形式で記述される必要があります。

>VPC エンドポイントポリシーは、エンドポイントの作成時または変更時にエンドポイントにアタッチする IAM リソースポリシーです。エンドポイントの作成時にポリシーをアタッチしない場合、サービスへのフルアクセスを許可するデフォルトのポリシーがアタッチされます。

> デフォルトでは、特にアウトバウンドアクセスを制限していない限り、Amazon VPC セキュリティグループですべてのアウトバウンドトラフィックが許可されます。

#参考文献
* VPC エンドポイント
    * https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-endpoints.html
VSC issue with "prettier" to not formatting in Html

問題：prettierのextensionを使って整形したら、htmlの場合はうまく行かない

私の場合むしろhtmlのソースを整形しようとしたら、以下のようにずれちゃった。(prettier適用中)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209211/6b069e39-7c89-2d9c-982e-b95df6b99f41.png)


https://stackoverflow.com/questions/57907645/prettier-not-formatting-html-files-in-vs-code
上のサイト参照したら結構前から18年度からずっとある問題そうだ。

それだ、

解決：htmlに限っては、Prettierを利用せず、内臓のVSCを使えば一旦ずれはなくなるそうだ。。。。。

settings.jsonのファイルの設定を変える
1) settings.jsonのパスは %APPDATA%\Code\User\setteing.json
2) File->preference->settingに入って、settingsと検索したら、
どこかに（←？よくないな。。）Edit in settings.jsonと書いている　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209211/f6941f1d-a1fe-c373-5aa6-f7ca4487d5e5.png)


settings.jsonのファイルの中で

```json
"prettier.disableLanguages": ["html"]
"[html]": {
    "editor.defaultFormatter": "vscode.html-language-features"
}

```
追加または修正すれば、Prettierはhtmlでは効かなくなる


結果：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209211/eb56d25e-69d0-c77b-00d5-86b9cc53cfa5.png)

ずれはなくなったけど、じゅるじゅる並ぶのが本当に嫌で。。。。どっちにしろよくないな。。。。😿
NLP4J - Java で 形態素解析（kuromojiを利用）

[Index](https://qiita.com/oyahiroki/items/ba79a759c599d3459d29)

# kuromoji とは

Javaで開発したオープンソース日本語形態素解析エンジンです。

kuromoji | Atilika
https://www.atilika.com/ja/kuromoji/


| 項目 | 説明 |
|:-----------|:------------|
| 提供者       | アティリカ Atilika        |
| 提供形式       | Java ライブラリ        |


# Maven

```xml
<!-- https://mvnrepository.com/artifact/org.nlp4j/nlp4j-kuromoji -->
<dependency>
    <groupId>org.nlp4j</groupId>
    <artifactId>nlp4j-kuromoji</artifactId>
    <version>1.3.4.0</version>
</dependency>
```

# コード
```java
package example;

import nlp4j.Document;
import nlp4j.Keyword;
import nlp4j.impl.DefaultDocument;
import nlp4j.krmj.annotator.KuromojiAnnotator;

public class HelloKuromojiNLP1 {

	public static void main(String[] args) throws Exception {
		// 自然文のテキスト
		String text = "今日はいい天気です。";

		Document doc = new DefaultDocument();
		// 属性「text」としてセットする
		doc.putAttribute("text", text);

		// kuromoji アノテーター
		KuromojiAnnotator annotator = new KuromojiAnnotator();
		// 処理対象の属性を指定
		annotator.setProperty("target", "text");
		// 形態素解析処理
		annotator.annotate(doc); // throws Exception

		// キーワードの出力
		for (Keyword kwd : doc.getKeywords()) {
			System.err.println(kwd);
		}
	}
}
```

# 結果

```
今日 [facet=名詞, str=今日]
は [facet=助詞, str=は]
いい [facet=形容詞, str=いい]
天気 [facet=名詞, str=天気]
です [facet=助動詞, str=です]
。 [facet=記号, str=。]
```

---


[Index](https://qiita.com/oyahiroki/items/ba79a759c599d3459d29)
Amazon VPC とは?

#Amazon VPC とは?
> 定義した仮想ネットワーク内で AWS リソースを起動できます。

## IPV6設定
### 1 つのパブリックサブネットを持つ VPC

<img width="661" alt="スクリーンショット 2020-05-18 19.06.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321923/117143a1-edb6-26f9-0ecb-a1299bc587b4.png">

### パブリックサブネットとプライベートサブネットを持つ VPC (NAT)
<img width="642" alt="スクリーンショット 2020-05-18 22.13.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321923/391bed84-0e6d-4643-13a3-2b5608bb3ae6.png">

### パブリックサブネットとプライベートサブネット、および AWS Site-to-Site VPN アクセスを持つ VPC
 
<img width="549" alt="スクリーンショット 2020-05-18 22.18.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321923/1bc551fd-dede-6858-8451-6418c6256cdd.png">

### プライベートサブネットのみおよび AWS Site-to-Site VPN アクセスを持つ VPC

<img width="624" alt="スクリーンショット 2020-05-18 22.19.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321923/7e327d01-621d-fcf0-f193-144346fdbd5d.png">

## Amazon VPC のネットワーク間トラフィックプライバシー
<img width="461" alt="スクリーンショット 2020-05-18 22.26.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321923/2e78763e-eb59-d7ac-34b8-b51cfc0cfb08.png">

##NAT インスタンスと NAT ゲートウェイの比較

トラフィックをセキュリティグループで制御できないくらい

#VPC ピア機能について
* VPCピアリングを作りながら学んでみた
    * https://dev.classmethod.jp/articles/handson-vpc-peering/

#参考文献
* Amazon VPC とは?
    * https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html
* VPC ピア機能とは
    * https://docs.aws.amazon.com/ja_jp/vpc/latest/peering/what-is-vpc-peering.html
* VPCピアリングを作りながら学んでみた
    * https://dev.classmethod.jp/articles/handson-vpc-peering/
lessコマンドでよく使う使い方ベスト3

## はじめに
ログ調査する時にlessコマンドを使っています。
自分がよく使う使い方のベスト３をまとめます。


## よく使う使い方・オプション
```shell
# 1. 特定の文言で検索して、ファイル内容を確認したいとき
grep 検索したい文言 ファイル名 | less

# 2. ログの１文が長い時に折り返さないで表示したいとき
less -S ファイル名

# 3. 行番号を表示したいとき
less -N ファイル名
```

## lessで表示中のキー操作
| キー |説明 |
|:--:|:--:|
| / | 検索する |
| n | 次を検索する |
| F | 末尾に追加があった場合更新する |
4次元行列と透視行列

主に3DCG関係で自分がよく使用する4次元行列関係の数式の自分用メモです。

#表記
```math
M = \begin{pmatrix}
M_{00} & M_{01} & M_{02} & M_{03}\\
M_{10} & M_{11} & M_{12} & M_{13}\\
M_{20} & M_{21} & M_{22} & M_{23}\\
M_{30} & M_{31} & M_{32} & M_{33}
\end{pmatrix}
```

#行列式
4次元行列の行列式は少し複雑です。
疑似コードで表現します。

```
function determinat(M)
  d := 0
  for i=0 to 3
    j := (i == 0) ? 1 : 0
    k := (i <= 1) ? 2 : 1
    l := (i <= 2) ? 3 : 2
    a := M[1,j] * (M[2,k]*M[3,l] - M[3,k]*M[2,l])
    a += M[1,k] * (M[2,l]*M[3,j] - M[3,l]*M[2,j])
    a += M[1,l] * (M[2,j]*M[3,k] - M[3,j]*M[2,k])
    if (i mod 2) == 0
      d += M[0,i] * a
    else
      d -= M[0,i] * a
    endif
  next
  return d
end
```

#逆行列
4次元行列の逆行列も少し複雑です。
疑似コードで表現します。

```
function inverse(M)
  R := ( 1, 0, 0, 0,
         0, 1, 0, 0,
         0, 0, 1, 0,
         0, 0, 0, 1 )
  d := 1.0 / determinat(M)
  for i=0 to 3
    j0 := (i == 0) ? 1 : 0
    j1 := (i <= 1) ? 2 : 1
    j2 := (i <= 2) ? 3 : 2
    for j=0 to 3
      i0 := (j == 0) ? 1 : 0
      i1 := (j <= 1) ? 2 : 1
      i2 := (j <= 2) ? 3 : 2
      a := M[i0,j0] * (M[i1,j1]*M[i2,j2] - M[i2,j1]*M[i1,j2])
      a += M[i0,j1] * (M[i1,j2]*M[i2,j0] - M[i2,j2]*M[i1,j0])
      a += M[i0,j2] * (M[i1,j0]*M[i2,j1] - M[i2,j0]*M[i1,j1])
      if ((i + j) mod 2) == 0
        R[i,j] := a * d
      else
        R[i,j] := -a * d
      endif
    next
  next
  return R
end
```

#透視変換（z遠方制限なし）
ほとんど使用しないですが、ｚが無限遠までクリップされない視錐台
z = zs/2 ～ ∞
z座標の手前側の制限については注意が必要。手前側の制限についてはｚ制限付きの一般的な透視変換式から任意の値を導出可能

width : 画面幅
height : 画面高
x0 : 画面の中心ｘ座標
y0 : 画面の中心ｙ座標
zs : 投影面のｚ座標（透視座標と等倍になるｚ）

```math
\begin{align}
ws &= 0.5 \cdot width\\
hs &= 0.5 \cdot height\\
xs &= zs / ws\\
ys &= -zs / hs\\
xo &= (x0 - ws) / ws\\
yo &= -(y0 - hs) / hs\\
Proj &= \begin{pmatrix}
xs & 0 & xo & 0 \\
0 & ys & yo & 0 \\
0 & 0 & 1 & -zs \\
0 & 0 & 1 & 0
\end{pmatrix}
\end{align}
```

※俺々エンジンの座標系から OpenGL への変換なので注意
　俺々エンジンはｙ座標は下に延びていて上下反転している。


#透視変換
一般的な視錐台。
但し、俺々エンジンの座標系のためｙ座標が反転することに注意。

width : 画面幅
height : 画面高
x0 : 画面の中心ｘ座標
y0 : 画面の中心ｙ座標
zs : 投影面のｚ座標（透視座標と等倍になるｚ）
near : 視錐台の手前側ｚ座標
far : 視錐台の奥側ｚ座標

```math
\begin{align}
ws &= 0.5 \cdot width\\
hs &= 0.5 \cdot height\\
xs &= zs / ws\\
ys &= -zs / hs\\
xo &= (x0 - ws) / ws\\
yo &= -(y0 - hs) / hs\\
zn &= near\\
zf &= 2 \cdot far\\
Proj &= \begin{pmatrix}
xs & 0 & xo & 0 \\
0 & ys & yo & 0 \\
0 & 0 & \frac{zf+zn}{zf-zn} & -\frac{2 \cdot zf \cdot zn}{zf - zn} \\
0 & 0 & 1 & 0
\end{pmatrix}
\end{align}
```
深さ優先探索(DFS)と幅優先探索(BFS)をpythonで実装する

# やったこと
AtCoder Typical Contest 001 の A - 深さ優先探索 をpythonで実装してみた。  
この問題は、深さ優先探索(DFS: Depth First Search)でも幅優先探索(BFS: Breadth First Search)でも解くことができるため、両方実装した。  
また、深さ優先探索については、再帰関数を用いるパターンとスタック(LIFO)を用いるパターンでそれぞれ実装した。

# DFS
## 再帰関数を用いるケース

```python

# A 深さ優先探索 再帰関数
import sys
sys.setrecursionlimit(10**7) #再帰関数の呼び出し制限

def dfs(v_x, v_y, seen_list, c_list):
    if v_x < 0 or v_y < 0 or v_x >= w or v_y >= h:
        return
    if seen_list[v_y][v_x]:
        return
    if c_list[v_y][v_x] == "#":
        return
    seen_list[v_y][v_x] = True
    dfs(v_x+1,v_y,seen_list,c_list)
    dfs(v_x-1,v_y,seen_list,c_list)
    dfs(v_x,v_y+1,seen_list,c_list)
    dfs(v_x,v_y-1,seen_list,c_list)
    
h, w = map(int, input().split())
seen_list = [[False] * w for i in range(h)]
c_list = []
s = []
g = []
for i in range(h):
    _tmp = list(input())
    if "s" in _tmp:
        s = [_tmp.index("s"),i]
    if "g" in _tmp:
        g = [_tmp.index("g"),i]
    c_list.append(_tmp)

dfs(s[0],s[1],seen_list,c_list)

if seen_list[g[1]][g[0]]:
    print("Yes")
else:
    print("No")
```

## スタックを用いるケース

```python
# A 深さ優先探索 スタック(LIFO)
from collections import deque

def dfs(stack, seen_list, c_list):
    while len(stack)>0:
        v_x, v_y = stack.pop()
        if v_x < 0 or v_y < 0 or v_x >= w or v_y >= h:
            continue
        if seen_list[v_y][v_x]:
            continue
        if c_list[v_y][v_x] == "#":
            continue
        seen_list[v_y][v_x] = True
        stack.append([v_x+1,v_y])
        stack.append([v_x-1,v_y])
        stack.append([v_x,v_y+1])
        stack.append([v_x,v_y-1])
    
h, w = map(int, input().split())
seen_list = [[False] * w for i in range(h)]
c_list = []
s = []
g = []
stack = deque()

for i in range(h):
    _tmp = list(input())
    if "s" in _tmp:
        s = [_tmp.index("s"),i]
    if "g" in _tmp:
        g = [_tmp.index("g"),i]
    c_list.append(_tmp)

stack.append(s)
dfs(stack,seen_list,c_list)

if seen_list[g[1]][g[0]]:
    print("Yes")
else:
    print("No")
```

# BFS

```python
# A 深さ優先探索 幅優先探索で解く　キュー(FIFO)
from collections import deque

def bfs(que, seen_list, c_list):
    while len(que)>0:
        v_x, v_y = que.pop()
        if v_x < 0 or v_y < 0 or v_x >= w or v_y >= h:
            continue
        if seen_list[v_y][v_x]:
            continue
        if c_list[v_y][v_x] == "#":
            continue
        seen_list[v_y][v_x] = True
        que.appendleft([v_x+1,v_y])
        que.appendleft([v_x-1,v_y])
        que.appendleft([v_x,v_y+1])
        que.appendleft([v_x,v_y-1])
    
h, w = map(int, input().split())
seen_list = [[False] * w for i in range(h)]
c_list = []
s = []
g = []
que = deque()

for i in range(h):
    _tmp = list(input())
    if "s" in _tmp:
        s = [_tmp.index("s"),i]
    if "g" in _tmp:
        g = [_tmp.index("g"),i]
    c_list.append(_tmp)

que.append(s)
bfs(que,seen_list,c_list)

if seen_list[g[1]][g[0]]:
    print("Yes")
else:
    print("No")
```
Docker内でMySQLにPythonで接続する 

DocekrもMySQLも初心者用のメモ

github url: https://github.com/kenjiSpecial/docker_mysql_python_beginner

docker-compose.yml

```yml:docker-compose.yml
version: "3"

services:
  mysql_db:
    container_name: "mysql_db"
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    volumes:
      - db_volume:/var/lib/mysql
    environment: # Set up mysql database name and password
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: employees
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    networks:
      - app-tier

  python3:
    restart: always
    build: ./python
    container_name: "python3"
    working_dir: "/root/"
    tty: true
    depends_on:
      - mysql_db
    networks:
      - app-tier
    volumes:
      - ./python:/root
      - pycache_volume:/root/.cache

networks:
  app-tier:
    driver: bridge

volumes:
  db_volume:
  pycache_volume:

```

DockerfileにPythonのコンテナ情報を入力する

```yml:Dockerfile
FROM python:3.7


# ADD . /root
COPY . /opt
WORKDIR /opt

RUN pip install -r requirements.txt
```

main.py

```python:main.py
import mysql.connector as mysql
user_name = "user"
password = "password"
host = "mysql_db"  # docker-composeで定義したMySQLのサービス名
database_name = "employees"


conn = mysql.connect(
    host="mysql_db",
    user="user",
    passwd="password",
    port=3306,
    database="employees"
)

conn.ping(reconnect=True)

print(conn.is_connected())
```
ubuntuでのComposerインストール方法を簡潔に

## 背景
インターンで案件のレビューをすることになったが、PHPのソースレビューでコーディング規約とソースを見比べながら細かな部分を見つけ出すのはかなり骨の折れる作業だと思った。
そんなとき、自分が受けたソースレビューで、**コーディング規約違反でCodeSnifferでエラーが出ています**とコメントをいただいたことを思い出した。
**CodeSniffer**を入れればソースがPSR-2に準拠した書き方なのかが自動でわかるのか！と感動し、VSCodeに導入することにした。
今回はその前提のComposerインストールまでのお話です。
解説サイトがたくさんヒットしたのですが、インストール手順がどれもバラバラで情報が散らかっている感じだったので、簡潔にまとめてしまおうと投稿しました。

## 環境
- Ubuntu 18.04LTS

## 1. 依存関係のインストール
まずはお約束

```
$ sudo apt update -y
```

続いて依存関係のインストール

```
$ sudo apt install curl php-cli php-mbstring git unzip
```
依存関係を簡単に説明すると、
- **curl**: `php-cli`をインストールするのに必要
- **php-cli**: Composerのインストールと実行に必要
- **php-mbstring**: 使用するライブラリに機能を提供
- **git**: 言わずもがな。ここではComposerの依存関係をダウンロードするのに必要
- **unzip**: 圧縮されたパッケージの解凍に必要

いくつか既に入っているライブラリもあると思うので、全部打つ必要はないかと。
とはいえ、確認がめんどうだったので私はそのまま実行しましたw﻿

## 2. Composerのインストール
依存関係がインストールできたところで、Composer本体のインストールです。
このインストール方法が一番記事によってやり方が違うと感じたのは私だけでしょうか？
今回は王道中の王道、[公式](https://getcomposer.org/download/)のコマンドからインストールします。

```
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php -r "if (hash_file('sha384', 'composer-setup.php') === 'e0012edf3e80b6978849f5eff0d4b4e4c79ff1609dd1e613307e16318854d24ae64f26d17af3ef0bf7cfb710ca74755a') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
$ php composer-setup.php
$ php -r "unlink('composer-setup.php');"
```

## 3. どこからでもComposerを実行できるように
最後の仕上げです。Composerをどの階層からでも実行できるように設定します。

```
$ # まずはcomposer.pharの確認
$ ls ./
composer.phar

$ # 続いてPHP 本体（ランタイム）の保存先ディレクトリを確認
$ dirname $(which php)
/usr/bin/php

$ # PHP と同じディレクトリに拡張子なしで移動し、実行権限を与える
$ mv ./composer.phar $(dirname $(which php))/composer && chmod +x "$_"

$ # 動作確認
$ composer --version
```

ほとんどこちらから引用させていただいております。ありがとうございます。
[逆引き！Composer コマンド・ライン一覧（と基礎知識）](https://qiita.com/KEINOS/items/86a16b06af6e936a1841)

以上です。
私は`1`と`2`の手順でどの記事を参考にすればよいかわからず、迷ってしまいました。
これからComposerをインストールする方の助けになれば幸いです。

## 参考文献
- [Ubuntu 18.04にComposerをインストールして...](https://www.codeflow.site/ja/article/how-to-install-and-use-composer-on-ubuntu-18-04)
- [Composer](https://getcomposer.org/download/)
- [逆引き！Composer コマンド・ライン一覧（と基礎知識）](https://qiita.com/KEINOS/items/86a16b06af6e936a1841)
ファイルを保存時に自動でテストを実行する

テスト駆動開発において、「ファイルを更新」 -> 「コンソールでテストコマンドを実行」 というプロセスが面倒でした。
そこで、このプロセスを自動化する方法を記載します。

## 動作イメージ

![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496366/8243c84d-ab6e-a6dc-3bd6-57e10f74b947.gif)


## 環境
- Ubuntu 18.04

## 準備

```bash
sudo apt install inotify-tools
```

## コード

以下のスクリプトを作成し、プロジェクトのルートに配置します。

```bash:autorun.sh
#!/usr/bin/env bash

TEST_RUNNER="pytest -s tests" # 実行したいテストコマンドを指定
TARGETS="./src ./tests" # 監視したディレクトリを指定

while inotifywait -r -e modify -e create -e delete $TARGETS; do
  $TEST_RUNNER
done
```

実行権限も付与。

```bash
chmod +x ./autorun.sh
```

## 実行

```bash
./autorun.sh
```

## 参考

- [inotifywaitコマンドの使い方](https://qiita.com/hana_shin/items/9e03ad7a40b4fd7afb67#4-%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9-m)
ゼロから始めるLeetCode Day29「46. Permutations」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day28「198. House Robber」](https://qiita.com/KueharX/items/ad01fc743042cf2fdb2a)

基本的にeasyのacceptanceが高い順から解いていこうかと思います。

[Twitter](https://twitter.com/kueharx)やってます。

# 問題
[46. Permutations](https://leetcode.com/problems/permutations/)
難易度はMedium。
Top 100 Liked Questionsからの抜粋です。

異なる数字を集めたリストが与えられるので、全ての順列を返しなさい、という問題です。
タイトルのPermutationは順列という意味らしいですよ。

>Example:

>Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

これが全ての順列を返している例ですね。

# 解法

```Python
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        return list(itertools.permutations(nums))
# Runtime: 36 ms, faster than 87.99% of Python3 online submissions for Permutations.
# Memory Usage: 14.1 MB, less than 5.36% of Python3 online submissions for Permutations.
```

はい。
あっけないですね。Python様の前ではLeetCodeのMediumも赤子同然です。

これにて終了です、対戦ありがとうございました。
























ごめんなさい、流石にこれだとあまりにもひどいので他に解法を考えました。


 ```Python
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        ans = []
        self.dfs(nums, [], ans)
        return ans
    
    def dfs(self, nums, emp, ans):
        if not nums:
            ans.append(emp)
        for i in range(len(nums)):
            self.dfs(nums[:i]+nums[i+1:], emp+[nums[i]], ans)
# Runtime: 32 ms, faster than 96.70% of Python3 online submissions for Permutations.
# Memory Usage: 13.9 MB, less than 5.36% of Python3 online submissions for Permutations.
```

`dfs`を別個に考えて実装しました。
numsの要素数が尽きるまで再起関数で回し続けるというものです。

スライスを使えば実装できます。

念のために書いておきますが、nums[:i]の場合は最初の要素からi番目までを取得し、nums[i+1:]の場合はi+1番目から最後の要素まで取得します。

そして、要素が無くなったときにempを元々用意していたリストの`ans`に追加することで二次元配列にしています。

こちらの方が若干速くなりました。

良さげな解答があれば追記します。
WioTerminalの裏蓋を改良しGroveコネクタを利用可能にする

# どんな内容か？
話題のWioTerminalを使ってみたところ、Groveコネクタがささる口が２か所あるのですが、ツメのついているGroveコネクタは使えないので、使えるように３Dプリンタで裏蓋を自作した話です。
最後にSTLファイルも公開しているので、もしご興味あるかたはプリントしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/ab791ebe-012a-c7bc-2149-bd38da1d1ac0.png)

# 現象
先ほども述べたGroveコネクタなのですが、実はツメのついたケーブルを挿すことができません。本体の裏蓋にあたってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/07611ed0-0014-09b8-995d-e1ca4abfa609.png)


Groveコネクタは２種類あり、ツメ付とツメ無の２タイプあるのですが、今のところツメ付きタイプは、WioTerminalにそのままでは使うことができません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/c4c8d317-a913-6d18-14da-86ae2b72af0a.png)

写真の左は、ツメ無のコネクタで、右がツメ付のタイプです。

# 解決策１
Groveコネクタのツメをカットする方法です。ニッパーで簡単に切ることができます。
※個人的には、一番簡単でオススメです。ただし、元に戻すことはできません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/c1ba8fe3-675f-4dfe-5ea3-ef3746880e3a.png)

# 解決策２
Groveコネクタが挿せるWioTerminalの裏蓋を３Dプリンタで作る。
Fusion360でサクッと？デザインして、裏蓋完成！寸法データが公開されてれば楽だったのですが、無かったのでノギスで頑張りました。※１度印刷して失敗しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/3e65acec-b8d6-a81b-bc1a-6c80173c002d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/b87f4331-d073-2493-421d-897708edba13.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/074cef2c-3979-5ff3-3d90-fc58d3971ccc.png)

プリントデータは、[こちら](https://drive.google.com/uc?export=download&id=1rwR8108236x3ptDRPHav7bdinuXw3WpQ
)からダウンロードできます。
権利は放棄しますのでご自由にどうぞ。ただし、自己責任でおねがいします。
プリンタの性能により、上手くプリントできない可能性もあります。
※当方は、AfiniaのH400のFDMでプリントしました。

以上です。
SQLBoilerでhas both field and method named IDエラーになる場合の対処法

## SQLBoilerの使い方

`has both field and method named ID`のエラーが出る場合、
あるテーブル同士のリレーションが`hasOne`になっているケースです。

```
                            Table "public.spans"
     Column     |           Type           | Collation | Nullable | Default 
----------------+--------------------------+-----------+----------+---------
 id             | character varying(40)    |           | not null | 
 highlight_text | text                     |           | not null | 
 category_id    | character varying(40)    |           | not null | 
 page_num       | integer                  |           | not null | 
 corrdinate     | character varying(255)   |           |          | 
 created_at     | timestamp with time zone |           | not null | now()
Indexes:
    "spans_pkey" PRIMARY KEY, btree (id)
    "idx_spans_category_id" btree (category_id)
Foreign-key constraints:
    "spans_annotation_id_fkey" FOREIGN KEY (id) REFERENCES annotations(id)
    "spans_category_id_fkey" FOREIGN KEY (category_id) REFERENCES categories(id)
```

これは`spans`というテーブルが`annotations`のIDをprimary keyとして参照しています。
これだと、`sqlboiler`で生成した、モデルが`ID`がfieldとmethodがかぶってしまうというケースが起こります。
これはこれで修正されれば良いですが、対処法としては、

`spans`テーブルの`id`を`annotation_id`というように、参照しているテーブルの名前に変更してやるのが一番簡単な解決策となります。

よって

```
                            Table "public.spans"
     Column     |           Type           | Collation | Nullable | Default 
----------------+--------------------------+-----------+----------+---------
 annotation_id  | character varying(40)    |           | not null | 
 highlight_text | text                     |           | not null | 
 category_id    | character varying(40)    |           | not null | 
 page_num       | integer                  |           | not null | 
 corrdinate     | character varying(255)   |           |          | 
 created_at     | timestamp with time zone |           | not null | now()
Indexes:
    "spans_pkey" PRIMARY KEY, btree (annotation_id)
    "idx_spans_category_id" btree (category_id)
Foreign-key constraints:
    "spans_annotation_id_fkey" FOREIGN KEY (annotation_id) REFERENCES annotations(id)
    "spans_category_id_fkey" FOREIGN KEY (category_id) REFERENCES categories(id)
```

このような`id`だったprimary keyが`annotation_id`という名前に変更したテーブル設計になればエラーも起こらなくなります。
Railsのエラー　undefined method `image_name' for nil:NilClass　の対処

#発生した問題
Progate学習のアウトプットのため学習したアプリを同じように作成。
投稿一覧画面に投稿者とその投稿者の画像を表示させる内容。

見本通り入力したところ、`undefined method 'image_name' for nil:NilClass`のエラー
が。

#試したこと
・post.rb、views/posts/index.html.erb、関連部分のメソッド、srcの値等の入力ミスがないか確認→問題なし

#解決方法
ググったり色々試した結果、rails db:migrateしたらなおりました。