OmniAICreator/Qiita-1.07M huggingface dataset:
【超基本】カウントアップで学ぶ①if文

## はじめに
本記事はプログラミング初学者の筆者が、備忘録として作成した記事である。

## ゴール
・カウントアップ機能を持ったアプリの完成。
・簡単なif文が使えるようになる。

## 内容
・Upボタン...Labelの数字が+1される。
・Downボタン...Labelの数字が-1される。
・Resetボタン...Labelなどの表示が初期化される。

if文の利用
・Labelが5になった時、画像が表示される。(謎要素)※UIImageViewを設定
・Labelが5になった時、Labelが赤色になる。
・Labelが10以上になった時、Labelが黄色になる。
・Labelが0以下になった時、Labelが黒色になる。

## 完成：Simulator画像
①初期画面。Label=0
<img width="375" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-06-05 at 15.01.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642055/5e183f7c-cee5-c903-84ad-33c8739023cd.png">

②5になった時。Label=5,色=red,imageViewを表示。
<img width="375" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-06-05 at 15.00.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642055/2a3c9dee-e1cb-f4f5-fbc4-2866fa531d11.png">

③10になった時。Label=10,色=yellow。
<img width="375" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-06-05 at 15.01.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642055/054c2ae0-c60d-2928-2db2-cecb65a4bdb3.png">

④resetボタン→①の状態へ。

## 完成：実際のコード

```php:countUp.Swift
import UIKit

class ViewController: UIViewController {
    
    
    @IBOutlet weak var countLabel: UILabel!
    @IBOutlet weak var imageView: UIImageView!
    
    var count = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        //初期ラベルの文字に”０”と表示する
        countLabel.text = "0"

    }
    
    @IBAction func UPButton(_ sender: Any) {
        
        count = count + 1
        //.textに合わせるため、count(int型)をString型にしなければならない。
        countLabel.text = String(count)
        
        if count >= 10  {
            //10以上になったらcountTextColerが呼ばれる=yellow
            countTextColer()
        }
            else if count == 5 {
            //5の場合は文字色=赤色になり、画像が表示される。
            redTextColor()
            imageView.image = UIImage(named: "画像ファイル名")
            }
        
    }
    
    @IBAction func DOWNButton(_ sender: Any) {
        
        count = count - 1

        countLabel.text = String(count)
        
        if count <= 0 {

            //0以下になったらresetTextColerが呼ばれる=0
            resetTextColor()

            //imageViewの画像を非表示。
            imageView.image = UIImage()
            
        }
            else if count == 5 {
            redTextColor()
            }
        
    }
    @IBAction func ResetButton(_ sender: Any) {
        resetButton()
    }
    
    
    //func 自分で決めたメソッド名(){動かしたいメソッド}
    
    func countTextColer() {
        countLabel.textColor = .yellow
        
    }
    func  resetTextColor(){
        countLabel.textColor = .black

    }
    func redTextColor(){
        countLabel.textColor = .red
    }
    func resetButton(){
        //imageViewの画像を非表示にする。
        imageView.image = UIImage()
        count = 0
        //Labelに0を表示する。
        countLabel.text = String(0)
        countLabel.textColor = .black
    }
    
}
```
## 結果
簡単なif文が使えるようになる...かもしれない。
Mac MySQL 起動に失敗する

# 目的

- `$ mysql.server start`を実行したがエラーがでて起動できない問題を解決した話をまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| MySQLバージョン | 8.0.19 | Homwbrewを用いて導入 |

# 問題までの経緯

- 下記コマンドを実行してMacローカルのMySQLを起動しようとした。

    ```terminal
    $ mysql -u root -p
    ```

# 問題

- 先コマンドの実行結果でエラーが発生した。

    ```terminal
    >Starting MySQL
    >.. ERROR! The server quit without updating PID file (/usr/local/var/mysql/MacBook-Pro.local.pid).
    ```

# 問題解決までの道のり

1. MySQLのインストール直後に発生したので下記コマンドを実行してMySQLのアンインストールを行う。

    ```terminal
    $ brew uninstall mysql
    ```
1. 下記コマンドを実行してMySQLを再インストールする。

    ```terminal
    $ brew install mysql
    ```
1. 再度確認のためにMySQL起動コマンド実行した。

    ```terminal
    $ mysql.server start
    ```
1. 問題発生時と同じエラーが出力された。

    ```terminal
    >Enter password: 
    >ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
    ```
1. 下記コマンドを実行してMySQLのファイルを削除してから再度アンインストールする。

    ```terminal
    $ sudo rm -rf /usr/local/var/mysql
    ```
1. MySQLのインストール直後に発生したので下記コマンドを実行してMySQLのアンインストールを行う。

    ```terminal
    $ brew uninstall mysql
    ```
1. 下記コマンドを実行してMySQLを再インストールする。

    ```terminal
    $ brew install mysql
    ```
1. 再度確認のためにMySQL起動コマンド実行した。

    ```terminal
    $ mysql.server start
    ```
1. 問題発生時と同じエラーが出力された。

    ```terminal
    >Enter password: 
    >ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
    ```
1. 下記を実行して

    ```terminal
    $ sudo touch /tmp/mysql.sock
    ```

1. 下記コマンドを実行して先のコマンドで作成したファイルの権限を変更する。

    ```terminal
    $ sudo chown 現在ログインしているユーザ名 /tmp/mysql.sock
    ```
1. 下記コマンドを実行してMySQLにログインする。

    ```terminal
    $ mysql -u root -p
    ```
1. 正常にログインすることができた。
go getしてきたライブラリのコマンドが実行できない場合（例：wire）

# 困ったこと
wireライブラリの説明についてはこちらが参考になります。
[GoのDIライブラリgoogle/wireの使い方](https://user-first.ikyu.co.jp/entry/google-wire)

こちらのライブラリを使うためには、`wire` コマンドを実行する必要があります。

しかし、以下の要領で実行しても `command not found`と言われてしましました。。

```
$ go get github.com/google/wire
(wire.goを作成)
$ wire
wire: command not found
```

まあこの時点で間違っているんですけどね。

# 解決方法
以下のように、`cmd/wire`ディレクトリを指定してgo getします。
wireの場合、このディレクトリにmainパッケージがあるためです。

```
$ go get github.com/google/wire/cmd/wire
```

こうすると、`$GOPATH/bin`配下に`wire.exe`が作成されます。（Windows）

# かんそう
`command not found`の時点でパスが通っていない可能性が高いので、まずは`$GOPATH/bin`に実行ファイルがあるか調べるべきでした。。
自分で`github.com/google/wire/cmd/wire`に移動して`go build`してしのいでいたのですが、`cmd/wire`ディレクトリまで指定して`go get`すると勝手に実行ファイル作ってくれるんですね。
ましゅの内外理論入門

#あいさつ
みなさんこんにちは、[ゆずっこ](https://twitter.com/pawakun)です。五月祭や駒場祭、パズルスクエアなどで細々とパズルを作っております。最近ではパズルボスラッシュでお世話になった方もいると思います。その節はどうもご迷惑をおかけしました。
さて、最近パズルスクエアでアゼンのましゅを連投しているわけですが、これらに大体共通する手筋の解説をしたいと思います。タイトルにあるとおり「内外」と呼んでいるものです。

#導入
マスの中央に線を引きループを作るパズルにおいて、各格子点はループの中と外に分けられます。ここではペンパくんの仕様上「出入」で表記しますが…
![loop1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/76ef6271-2cd1-8bd7-34bd-108b409067d2.png)
このように分けることの何が良いかというと、隣り合う格子点で内外が決まった時に線が引かれる・引かれないということが決定するのです。
つまりこれが…
![loop6.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/bcc62189-f97b-113d-8de9-fd3ff5216df0.png)
このようになります。
![loop6.5.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/488fcec3-dd8f-b851-fd0f-64caf59d46b9.png)
この理論はましゅと非常に相性がいいのです。

#利用
白丸を見てみましょう。
![loop2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/7259473a-f8d1-7552-5e08-bac883353eed.png)
ルールから白丸には線が一本まっすぐに通ります。つまりこれらのどっちかになるというわけです。
![loop3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/979a64ea-67de-ca91-a7de-dab9515bdef4.png)
![loop4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/3729a3fb-5592-398c-8da5-cca59ae3567f.png)
ここで、白丸をナナメにはさむ格子点は内外が反転することがわかります。ここでは中か外かが不明なのでAとBとします。
![loop5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/edd4d185-65d0-fea9-7a92-6d470493ed91.png)
これを利用すると次のようなことができます。このようにナナメにつながった白丸があると、
![loop6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/2444b631-5dba-be60-16fc-6ad7b6810f35.png)
内外が決定し、
![loop7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/3635e588-f786-2b1c-73ee-28f3b33badee.png)
線が引かれないことが決定します。
![loop8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321533/91af5213-770a-4a91-6de8-ed6d1129f7bd.png)

応用は壁際に限らず、出現の仕方も非常に多岐にわたりますが、[ぼくの作ったましゅ](https://puzsq.logicpuzzle.app/?kind=2&author=124)を解くと何か見えてくるかもしれません。
また、[2019年駒場祭](http://puzzletokyo.seesaa.net/article/471718322.html)で出したハバネロましゅ[パズスクのリンクはこちら](https://puzsq.logicpuzzle.app/puzzle/14125)もこれを利用しており**理詰めで**解ける問題となっているので挑戦してみてください。

#雑記
この理論は偶数端点と本質的には同じなのですが、ことましゅにおいては偶数端点と比較して追いやすくまた絶大な効果を発揮する理論となります。
ただし、これが必須であるとまず難易度がアゼン程度になり、ニコリには**絶対に載らない**のでご注意ください。
この理論はループ系パズル全般で使用できますが、その応用はここでは記述しません。

#謝辞
この理論を(めっちゃ昔に)教えてくれたしもりんにこの場を借りて多大な感謝を申し上げます。ありがとうございます。
git flowについて

# はじめに
gitの運用で利用されるgit flowについてまとめます。

# git flowって何？
gitの機能であるブランチを活用したgitの開発手法です。

複数人による開発をする時に、運用ルールを決めずにgitを採用してしまうと、コンフリクトが頻発したりmergeミスが発生したりしてしまいます。
そのような問題を回避し、最大限にgitを活用することができるのがgit flowです。

お恥ずかしながら、今回調べ直して知ったのですが、元は、ディベロッパーのDriessenさんが、ご自身のブログで公開した「A successful Git branching model」という記事から生まれたアイデアだそうです。
（[日本語訳がありました](http://keijinsonyaban.blogspot.com/2010/10/a-successful-git-branching-model.html)）

# 5つのブランチ
詳細な説明は後述します。

**master**
リリースしたデータを置いておくブランチ。

**develop**
開発をおこなうためのブランチ。

**release**
リリース前に準備、微調整をおこなうブランチ。

**feature**
開発をおこなうためのブランチ。個々の機能の実装やバグの解決をおこなう。

**hotfix**
リリースされているデータに、緊急の修正対応をするためのブランチ。


# 各ブランチの詳細・説明
## メインブランチ
### master
サイトとして完全なもの。
masterブランチと公開された本番環境が同じソースということが多い。
前職ではmasterにmergeをすると本番環境に反映されていた。（本番環境＝master）
mercurialではdefaultと同じ。

### develop
開発中（更新案件なら次のリリース分）のものが完全な状態で反映されている。
開発作業の主軸となるブランチであり、各開発者が新規作成・修正したソースがこのブランチに集まる。
更新案件でいうと、masterとの差分は、「次のリリース」分のみ。

## サポートブランチ
機能の追加や修正・準備、何かあったらすばやく修正するブランチをまとめて「サポートブランチ」といいます。

### release
developでの開発作業が完了後、リリース時の微調整を行うブランチ。
releaseブランチはdevelopブランチから作成される。

分岐元：develop
marge先：developとmaster

### feature
主に新機能などの開発・修正を行うブランチ。
ブランチ名は「feature/news」など、feature/の後に実装する機能などを記載する。
リリース前に新機能などににバグなどが見つかった場合、developからfeature/bug_xxなど修正用のブランチを切り、修正が終わったらdevelopにmergeする。
デバッグが終わるまでdevelopにmergeするのはNG。

分岐元：develop
marge先：develop

### hotfix
リリース後に不具合が見つかったら作成されるブランチ。
（作成されない方がいいブランチでもある・・・）

分岐元：master
marge先：developとmaster

# 全体像
![グループ 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316486/4a7c9590-6379-7cec-6d54-9576c044eedd.png)

# まとめ
- 分岐元やmerge先をミスってしまうと、大事故（そして面倒）になるので、気をつけること！
- LP1ページなどではここまでの運用はいらないと思いますが、小規模〜中規模案件で少しずつ慣れておくといいと感じます。
- master, release, develop, feature, hotfixの各ブランチの役割を把握・運用することが、
案件をスムーズに進めるための重要だと思います。


## 参考にさせていただいた記事
記事を書くにあたり、改めて勉強になりました！
[Atlassian Git Tutorial](https://www.atlassian.com/ja/git/tutorials/comparing-workflows/gitflow-workflow)
[Remotte開発] 管理者モードから開発者モードへ切り替える

これから数回の投稿にわたって、[リモッテ](https://www.remotte.jp "ホームページ") を使ったアプリ開発をするための説明をしていく。リモッテではユーザーを管理者、利用者、開発者の３種類に分けているが、本稿は開発者向けの情報となる。管理者および利用者のための情報は、リモッテのホームページ上の [ユーザーガイド](https://www.remotte.jp/user_guide) ないしは以下の Qiita 上の別の投稿を参考にすると良い。

* [IoT プラットフォーム「リモッテ」をインストールしてみた](https://qiita.com/remotte_jp/items/39278287097a7a25432d)
* [IoT プラットフォーム「リモッテ」でステーションを登録してみた](https://qiita.com/remotte_jp/items/94fb73db9fb98e9e10a2)
* [IoT プラットフォーム「リモッテ」でアプリを実行してみた](https://qiita.com/remotte_jp/items/324f99727c68392b80e5)
* [Remotte（リモッテ）を利用者として使う](https://qiita.com/remotte_jp/items/7ec79a400429738843d0)
* [Remotte（リモッテ）で時系列データの詳細を見る](https://qiita.com/remotte_jp/items/a7b5475176eb133af957)
* [Remotte（リモッテ）でビデオと音声を配信、記録、再生する](https://qiita.com/remotte_jp/items/c520c8b7967ab3e199b4)

### 開発者登録すると何が出来るようになるか？
リモッテは、「だれもが楽しく簡単に」というのをスローガンにして、一般の人達がスマートフォンやタブレットでアプリストアから好きなものをインストールして使うくらいの手軽さで IoT、AI、自動化といったシステムを構築できることを目標にしている。それゆえ、より高度な利用をしたいユーザーや開発者のためのユーザーインタフェースを標準で非表示とし、開発者登録をした場合にだけ、より詳細な機能を表示できるようになっている。

管理ツール上から開発者登録を行なうと、以下の様な機能が利用可能になる。
　　アプリや構成要素の新規作成、情報の編集、ファイル保存、バージョン管理
　　プログラムファイル及びデータファイルの追加・登録
　　ソースコードエディタ
　　デバッグ画面の利用
　　オプション変数の定義・編集
　　多言語化

リモッテのアプリは Python 言語で記述するが、コードエディターやデバッグ時に使用するコンソールなども管理ツールと同じブラウザ画面上で提供されているため作業がしやすい。
### 開発者登録する
開発者登録を行うにはまず、管理ツールのメニューを開き、［ 開発者モード ］を選択します。
![dev_menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/1e6e1c12-823a-478b-d432-9decac83043d.png)
開発者ライセンスの使用許諾契約書が表示されたら、内容を確認した上で問題が無ければ次に進む。
![dev_eula.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/f7795e35-7cdb-80a3-7c41-22b6b577c997.png)
開発者として登録する人の情報を入力します。
![dev_info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/5b15cb7b-0d41-a87e-d8ed-44207b8a62b7.png)
開発者登録が完了すると、アプリの一覧画面の上部に、［ 新規作成 ］メニューが表示されるようになります。
![dev_app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/8dcbb5d7-07bd-f371-2f12-0ba4fb97129a.png)
### まとめ
今回は開発者登録を行なうところまで。[次回](https://qiita.com/remotte_jp/items/093bcb7a9056e870d180)は開発者モードの時だけ表示される機能について見ていきましょう。
【scp】Tera Termのssh scpでLinuxサーバからローカルにファイルをコピーする

#やりたいこと
タイトルの通り。
クラウド上のLinuxサーバにあるデータをローカルPCにダウンロードする。

#前提
・ローカルPCにTera Termがインストールされていること

#SSH SCP
Tera Termにある機能。
SSHでサーバにログインした後、コピー元とコピー先のパスを入力すればファイルコピーができる。

#手順
###1.Tera TermにSSHでログイン
ここは割愛。各々の方法でログインする。

###2.SSH SCPを開き、パスを入力
「ファイル」から「SSH SCP」を選択
ローカル⇒サーバの場合は上の段、サーバ⇒ローカルの場合は下の段を入力。
今回は後者。

「From」にLinuxサーバ上のコピーしたいファイルのパスを記述。
「To」にコピーしたファイルを置きたいローカルPCのパスを記述する。

<img width="363" alt="ssh_scp画面.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649865/d8aac4bb-00a9-f2b1-9f9a-e30637202632.png">

「Send」を押して「To」で指定したローカルPCのパスにファイルがコピーされているいるか確認。

#Permission deniedが出る時
SSHコピーしたいファイルの所有者や権限の問題で「Permission denied」とエラーが出て、失敗するときがある。(私は失敗してこの記事を書いています。)

「root」ユーザにスイッチしてからファイルの受信を行っても、最初にログインしたユーザの権限でしかファイルの受信が出来ないらしい。↓
https://www.j-oosk.com/teraterm/file-transfer/143/

初めからrootでログインできる場合はそれで問題ないと思う。


##対処法
ファイルをサーバ内でコピーし、コピーしたファイルの所有者を変更することで解決した。

###1.rootユーザにスイッチしてファイルをコピー
```
sudo su -
cp 【コピーしたいファイルのパス】【コピー先のディレクトリパス】
```
###2.コピーしたファイルの所有者を変更
```
'chown 【所有者にしたいユーザ】 【所有者を変更したいファイルのパス】
```
###3.所有者が変わったことを確認
```
ls -l
```
この操作を行った後であれば、この記事の初めの手順でコピーができるはず。
Golandでローカルデバッグしたときに fatal error: 'stdlib.h' file not found が出た話

## 概要
Golnadでブレークポイントを設定して、デバッグしたくなったときに、Go Buildの設定をしたら、エラーが出て解消した話

## エラー内容
```
fatal error: 'stdlib.h' file not found
```

## 解消法
ぐぐったら自分の書いた記事が見つかりました
https://qiita.com/airtanker/items/ccedbfb0b505f7fbab88

Golandのデバッグ時の設定で、環境変数に出力した内容をSDKROOTに設定することで解消できました。

```
❯ xcrun --sdk macosx --show-sdk-path
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
```
こんな感じ
<img width="1134" alt="スクリーンショット 2020-06-05 14.12.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243031/6dc218f4-cbfe-814f-3fae-0d79b12381b5.png">

## 感想
とりあえずめでたし
ASP.NET Coreの413 RequestEntityTooLargeエラー対策

`Program.cs`で`.UseKestrel()`をつかってリクエストボディサイズを上限に設定

```csharp:Program.cs

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureLogging((logging) =>
                {
                    logging.AddDebug();
                    logging.AddConsole();
                })
                .UseStartup<Startup>()
                .UseKestrel((context, options) =>
                {
                    // Handle requests up to 5*50 MB
                    options.Limits.MaxRequestBodySize = 5 * 52428800;
                });
```

参考
---
https://mlog.club/article/5139263
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1
https://stackoverflow.com/questions/54722578/issue-with-configurekestrel-method-in-net-core
Anvil(Full stack web apps with Python) で複式簿記アプリ開発を極めたいメモ

## 背景

* テキストで複式簿記をやりたい
  * Python あたりでプログラマティックにやりたい
* でも GUI もほしいところ
  * 他の人に仕分け入力してもらうときとか
* GNUCash とか, UI が古臭すぎてつらい. スクリプト制御できない
* 僕の考えた最高の複式簿記アプリをお手軽に作りたい

## Anvil

Python + double-entry accounting で検索したらでてきました.

Anvil というといろいろ同名のサービスなり製品があってややこしいですが,
ここでいう Anvil はこちらです.

https://anvil.works/

Visual Basic や XCode editor の Python 版という感じでしょうか.
オシャンティな UI が使えます.

Free 版あります.

### 複式簿記サンプル

An Engineer's Guide to Double-Entry Bookkeeping
https://anvil.works/blog/double-entry-accounting-for-engineers

ありがとうございます.


現状処理がもっさり感が否めませんが(Ryzen 1700 で動かしても), 
Anvil でぺろっと複式簿記 UI とロジックつくるのできそうです.

## TODO

* [ ] どこかサーバに publish(deploy) する方法を探す
Rustで文字列から全角カタカナだけを取り出す（`matches!`マクロの実用例）

## はじめに

Rust 1.42.0で`std`に導入された、`matches!`という[マクロ](https://doc.rust-lang.org/stable/std/macro.matches.html)があります。
先日「Rustで文字列の中から全角カタカナだけを取り出して、新たな文字列を生成する」というコードを書く機会があり、この`matches!`マクロを使用することで簡潔に記述することができました。

なので`matches!`マクロを使用した実用的なコード例として、ちょっとした小ネタ的に書き留めておきます。

なお、本コードの検証に使用した環境は`rustc 1.43.1`および`rustc 1.45.0-nightly`です。

## `matches!`マクロとは

Rust 1.42.0以上で使用可能[^crates]なマクロであり、与えられたパターンにマッチするか否かを返します。

[^crates]: それ以前のバージョンでも、[こちらのクレート](https://crates.io/crates/matches)を使用することで`matches!`マクロが使用可能となると思われます（未検証）。

例えば

```rust
let hoge = 'a';
let fuga = matches!(hoge, 'a'|'b');
assert!(fuga); // true
```

のように使用します。

この時`matches!(hoge, 'a'|'b')`は下記のように展開されます。

```rust
match hoge{
    'a'|'b' => true,
    _ => false,
}
```

## 実際に全角カタカナを取り出してみる

```rust
fn main() {

    let txt = "Rust(ﾗｽﾄ)で文字列から全角カタカナだけを取り出す"
        .chars()
        .filter(|&c| matches!(c, 'ァ' ..= 'ー'))
        .collect::<String>();

    assert_eq!(txt,"カタカナ");
}
```

これだけ[^katakana]。

[^katakana]: 本コードでは`ァ`～`ヺ`の全角カタカナに加えて`・`および`ー`の記号も一緒に取り出したかったため、取り出す範囲として`'ァ' ..= 'ー'`を指定しています。

簡単に解説すると、

1. 文字列リテラル`&str`を`chars`で`char`のイテレータに変換する
2. `filter`で条件にマッチする要素のみを取り出す
3. この際に`matches!`を使用し、`ァ` ～ `ー`の範囲に含まれるかを条件として指定する
4. 取り出された要素を`collect`で結合して`String`にする

といった感じの操作を行っています。
【xcode11】swift5 一つのBGMを複数の画面ごと再生したり止めたりする方法。

##やりたいこと
一つのBGMを複数の画面ごと再生したり止めたりしたい。

##コード
AppDelegateにまず、
``import AVFoundation``入れたあと

```
var audioPlayer:AVAudioPlayer! = AVAudioPlayer()
    var sound_data = NSURL(fileURLWithPath: Bundle.main.path(forResource: "bgm", ofType: "mp3")!)
```

と書き

```
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }
```

AppDelegateに元々書かれてある上記のコードのretrunの上に下記のコードを書く。

```

 audioPlayer =  try? AVAudioPlayer(contentsOf:sound_data as URL)
        audioPlayer.play()       //アプリ起動から音楽スタート
        audioPlayer.numberOfLoops = -1      //音楽ループ
```

BGMを再生したいクラスに

```
  var player:AVAudioPlayer?
    
  let appDelegate = UIApplication.shared.delegate as! AppDelegate
```
と書き、``override func viewDidLoad() {``の中に

```
appDelegate.audioPlayer.play()
```
と書いたら音楽が再生され、

```
appDelegate.audioPlayer.stop()
```
と書いたらBGMが止まる。
初心者向けRailsでブログを作ってみるチュートリアルその2

# これはなに？
[初心者向けRailsでブログを作ってみるチュートリアルその1](https://qiita.com/zako-pro/items/1b257112d272046cb043) の続きです。
前回は、何をつくるかを決めました。
今回は実装に移る前にプロジェクトの初期セットアップをします。

# 今回の作業内容
今回は以下のような作業を行います

- Github上でリポジトリを作成する
- railsのインストール
- railsプロジェクトのセットアップ

## rubyの環境構築
Rubyの環境構築がまだの方は以下のページなどを参考にご自分のお手元にRubyの開発環境をセットアップしてください。

- Mac編: https://prog-8.com/docs/ruby-env
- Windows編: https://prog-8.com/docs/ruby-env-win

# Github上でリポジトリを作成する

この際にgitignoreを `rails` に設定しましょう[^1]

[^1]: これをやっておくと、railsで生成されがちだけどgitで管理する必要がない(または管理しないほうがいい)ファイルを無視するようになって便利

# railsのインストール
`gem install rails` これで手元にrailsプロジェクトのセットアップの準備が完了しました。

# railsプロジェクトのセットアップ

## リポジトリをclone
```
git clone https://github.com/アカウント名/rails-blog-sample.git
```

これで手元にリポジトリをclone(コピー)してきます

## railsプロジェクトの初期化
```
cd rails-blog-tutorial
rails new .
```

`rails new` の中でいくつかのファイルを上書きしていいか聞かれるので全てに `y` で答えて大丈夫です

## 試しに動かしてみる
`rails server` でコンソール上に以下のような雰囲気のログが流れたら http://localhost:3000/ にお手元のブラウザでアクセスしてみましょう。
`Yay! You’re on Rails!` みたいな画面が出てきたら成功です。ターミナルから ctrl-c で終了しましょう
逆にこんな感じじゃなかったらなにかおかしそうです。その時はエラーメッセージの一部とかでググってみるとか質問してみるとかしましょう。

```
=> Booting Puma
=> Rails 6.0.3.1 application starting in development 
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.5 (ruby 2.5.5-p157), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop
```

## ここまでの作業内容をpush
これからブログを開発していくためのrailsプロジェクトを作成できたので、作業内容をgithub上にpush(アップロード)します。

```
git add .
git commit -m 'rails new'
git push origin master
```

これで、万が一手元のファイルが消えてもgithubからここまでの作業内容を取得できるようになりました。
このように、作業内容はこまめにcommitしてpushしましょう。


# 今回のまとめ
- Githubでリポジトリを作って手元にcloneした
- railsをインストールした
- `rails new` でプロジェクトを構築してから `rails server` で動作確認までできた

次回は、Webアプリケーション中でデータを扱う上で必要になる「モデル」の部分を実装します。
モジュール・パッケージ・ライブラリの違いがよく分からないので整理してみた

「モジュール」・「パッケージ」・「ライブラリ」はよく聞くワードだが、違いがよく分からなかったので調べてまとめてみた。調べているとPythonを前提にした記事が多かったので、本記事でもPythonを前提に進める。他の言語等に対しても同じ理論が通用するかについては不明だが、おそらく通ずるところはあると思う。


#モジュール
モジュールとは`.py`で作られるファイルのこと。ある程度長いプログラムを書く際に`.py`ファイルに内容を保存。そして使いたい時がきたら、他のPythonファイルからimportでモジュールとして呼び出す。もちろん、呼び出したモジュールに保存されているクラスや関数は呼び出し先でも利用可能。

#パッケージ
パッケージとはいくつかのモジュールをディレクトリに整理し、ひとまとめにしたもの。機能が似通っているモジュール同士が複数あると、それらをまとめた方が扱いやすくなる。importでパッケージを呼び出すと、パッケージ内にある全てのモジュールの内容を利用できるようになる。

#ライブラリ
ライブラリとはいくつかのパッケージをインストールできる形にまとめたもの。ライブラリには、Pythonに付属していてすぐに使える **標準ライブラリ** と、ダウンロードなど追加インストールをしてから利用する **外部ライブラリ** がある。機械学習で用いられる「TensorFlow(テンソルフロー)」、グラフ描画に使われるMatplotlib（マットプロットリブ）、データ解析を支援する機能を提供するPandas（パンダス）などは全て外部ライブラリ。

#階層
ライブラリ > パッケージ > モジュール

#参考
[Pythonのモジュール、パッケージ、ライブラリ徹底解説！](https://ai-inter1.com/python-module_package_library/)
AndroidStudio(kotlin)ボタン押下でダイアログを表示し、選択肢に応じて処理を分ける。


# やりたいこと

* ボタンを押すとダイアログを表示する。
* ダイアログには2つの選択肢が表示される。
* 各選択肢ごとに処理を設定する。

具体的には下記の遷移。ダイアログの「赤にする」を選ぶと、文字の色が赤に変わる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75451/36b4c5ac-7c0e-399d-b0dc-d8965866119b.png)




# 画面の実装

```xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="268dp"
        android:layout_height="94dp"
        android:text="Hello World!"
        android:textSize="36sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
```



# メイン処理の実装

```kotlin

package com.example.yamato200605b

import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val getButton = findViewById(R.id.btn) as Button
        getButton.setOnClickListener(object : View.OnClickListener {
            override
            fun onClick(view: View) {
                AlertDialog.Builder(this@MainActivity)
                    .setTitle("文字色の変更")
                    .setMessage("テキストの色を赤に変更しますか？")
                    .setPositiveButton(
                        "赤にする", { dialog, which ->
                            textView1.setTextColor(Color.RED)
                        }
                    )
                    .setNegativeButton(
                        "キャンセル", { dialog, which ->
                            textView1.setTextColor(Color.BLUE)
                        }
                    )
                    .show()

            }
        })
    }
}
```
Python3 if以外の条件分岐　メモ

#はじめに
マークダウンの書式に慣れていないので見づらいと思いますが、ご容赦ください。

#メモ

`if`以外の条件分岐の方法

サンプルコード

```sample.py
a = True
if a:  # 従来
    b = "A is True"
else:
    b = "A is False"

# if を使わない
b = ["A is False", "A is True"][a]
```

`if`を使わないで書くとスッキリしました。

試しにFizzBuzzを書いてみます.

```fizzbuzz.py
# ifを使わないバージョン
for i in range(1, 100):
    fizzbuzz = ["", "Fizz"][i%3==0]
    fizzbuzz += ["", "Buzz"][i%5==0]
    fizzbuzz += ["", str(i)][i%3!=0 and i%5!=0]
    print(fizzbuzz)

# ifを使ったバージョン
for i in range(1, 100):
    if i%15 == 0:
        print("FizzBuzz")
    elif i%3 == 0:
        print("Fizz")
    elif i%5 == 0:
        print("Buzz")
    else:
        print(i)
```

どうでしょうか？

仕組みとしては、Pythonではbool値（True/False)は (1/0)と等価です.
これとスライスを利用すると、ifを使わないで条件分岐をすることができます.

スライスとはリストの中のオブジェクトを取り出す際に使われます.
以下サンプルコード

```slice.py
list_ = [0,1,2,3,4]
print(list_[0:1])    # -> [0, 1]       # インデックス0~1番までのリスト
print(list_[3])      # -> 3            # list_の左から4番目の数値
print(list_[1:4:2])  # -> [1, 3]       # インデックス1~4番まで2つ飛ばしのリスト
print(list_[:])      # -> [0,1,2,3,4]  # list_と等値

```
Python openpyxlでのコピーシートを最初に表示する方法

# Python openpyxlについて
PythonでのExcelのファイルやシートを作成、書き込みのパッケージ
[official document (http://openpyxl.readthedocs.io/en/default/)](http://openpyxl.readthedocs.io/en/default/)
## シートコピー
ファイルのシートのコピーには以下を用いることが多い

**workbook.copy_worksheet(worksheet)**

```
from openpyxl import load_workbook

#対象のエクセルファイル指定
xls_file='test.xls'

#openpyxlでエクセルファイル（ブック）とアクティブシートを読込
wb=load_workbook(xls_file)
ws=wb.active

#アクティブシートをコピー
ws_copy=wb.copy_worksheet(ws)

#コピーされたシートのタイトルを変更する
ws_copy.title='新シート名'

#リストで量産するなら
list=['シート1','シート2','シート3','シート4']
for sheet_name in list:
    ws_copy = wb.copy_worksheet(ws)
    ws_copy.title=sheet_name

#保存して終わり
wb.save(xls_file)

```
## コピーシートを最初に表示したい
コビーシートでセルの編集などしてデータをアップデートしたいときがある、最新データを次ファイルアクセスした時に出したい。だが...
<img width="361" alt="新しいビットマップ イメージ.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649814/a709f987-9bdc-f62c-aa95-f794878fd91a.jpeg">
実際シートをコピーしただけだと最新のコピーシートを最初に表示してくれない。
## アクティブシートの存在を知る
アクティブシートとは、エクセルを開いたときに表示される画面のことを言います。

 

エクセルの開始

[ スタート ] ⇒　[ 全てのプログラム ] ⇒ [ Microsoft Office ] ⇒ [ Microsoft Excel ]

 ![activesheet1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649814/4273a414-362c-8e64-c202-a6fca40a8b7d.gif)




 

クリックで開始

 

エクセルが開きました。この状態が「アクティブシート」です。

エクセルには複数のシートがあります。

 

![activesheet2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649814/edd1e1dd-0d31-abbc-6ec6-8ad8cee4f57d.gif)


 

初期状態ではSheet1から3まで表示されています。「Sheet1」を選択している場合、アクティブシートは「Sheet1」になります。
参考:[Excel エクセルマクロ・VBA塾(http://kabu-macro.com/)](http://kabu-macro.com/word/a-o/activesheet.html#:~:text=%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%82%B7%E3%83%BC%E3%83%88%E3%81%A8%E3%81%AF%E3%80%81%E3%82%A8%E3%82%AF%E3%82%BB%E3%83%AB,%E3%81%AE%E3%81%93%E3%81%A8%E3%82%92%E8%A8%80%E3%81%84%E3%81%BE%E3%81%99%E3%80%82&text=%E3%82%A8%E3%82%AF%E3%82%BB%E3%83%AB%E3%81%AB%E3%81%AF%E8%A4%87%E6%95%B0%E3%81%AE,%E3%80%8CSheet1%E3%80%8D%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)

##解決
作成したコピーシートをアクティブシートにすればいい

```
#コピーシートをアクティブシートにする
wb.active = wb.sheetnames.index('シート4')
```
Box UI Elementsでエラーが発生した場合のキャッチの仕方


UI Elementsの各コンポーネントには、optionとして、responseInterceptorがあります。
例えば、ContentExplorerだとこんな感じ。
https://developer.box.com/guides/embed/ui-elements/explorer/#Options

UI Elementsは内部でAxiosをつかっていますが、[AxiosはresponseInterceptorに関数を2つ取る](https://github.com/axios/axios#interceptors)のに対し、UI ElementsのresponseInterceptorは、関数を1つしか取りません。

ではどうやってエラーをキャッチするのかというと、エラー発生時にも、エラーオブジェクトをこの関数に戻してくれます。

UI Elementsの該当する箇所はこちら。
https://github.com/box/box-ui-elements/blob/master/src/utils/Xhr.js#L183

responseInterceptorのハンドラは、正常時もエラー発生時も呼ばれるので、渡される引数を見分けて正常かエラーかを判断する必要ありです。たとえばこんな感じでしょうか。。

```js
responseInterceptor: arg => {
    if(arg instanceof Error) {
        // error handling
        alert(arg.message)
    }

    return arg;
}
```
GAS(自作API) ✕ Nuxt で CORSエラーで詰みかけた話

## この記事で分かること

- GASで自作APIを叩いた時のCORSエラーの解決方法

## 悪夢の始まり

自分のポートフォリオサイトを作成していたときのこと・・・

お問合せフォームから、Axiosで自作のGASのAPIを叩いた時に、おなじみのCORSエラー、クロスオリジン問題が起きてしまった。

```
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, 
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

CORSエラーってなんぞや？という方は、こちらの記事に分かりやすくまとまっているので、確認してみると良いでしょう。
[なんとなく CORS がわかる...はもう終わりにする。](https://qiita.com/att55/items/2154a8aad8bf1409db2b)

## GASはレスポンスヘッダーの OPTION をサポートしていない。。

通常、自作APIでCORSエラーが出た時は、サーバーサイド（今回で言えばGAS側）のレスポンスヘッダーに以下の OPTION をつければ解決するはずなのだ。

```
Access-Control-Allow-Origin: {{アクセスする側のURL}}
```

しかし！ 残念ながらGASはどうやら OPTION をサポートしていないらしい。
詳しくは [今から10分ではじめる Google Apps Script(GAS) で Web API公開](https://qiita.com/riversun/items/c924cfe70e16ee3fe3ba#ブラウザからこのapiをたたきたい)

じゃあどうするんだ。。

## 解決方法

当初、GAS側のコードでは `doPost` 関数を使用してPOSTでのデータの受け渡しを想定していた。


どうやら、GASのコードを `doPost` から `doGet` に変更して、Axios のパラメータに `crossDomain: true` を追加してあげると改善される。

POSTでは上手く行かないらしい。。

実際に書いたコードは下の通りになった。

```javascript:index.vue
const params = {
        //任意のパラメータ
        crossDomain: true
      }
const { data } = await axios.get(process.env.GAS_URL, { params })
return data
```
```javascript:main.gs
function doGet(e) {
  const params = e.parameter
  const example = params.example;  // => exampleが取れる
  
  //任意の処理

  const output = ContentService.createTextOutput();
  output.setMimeType(ContentService.MimeType.JSON);
  output.setContent(JSON.stringify({"message":"success"}));
 
  return output;
}
```
GASを使ってGoogleSpreadsheetの内容を呼び出してSlackbotにしゃべらせる

#やってみたいこと

これをslackコマンドで実現したい。

```
> /birthday
あなたの誕生日パートナーはXXさんだよ！ 誕生日はY月Z日です。忘れないでね！
```

## 前提条件

* GoogleSpreadsheetに、メールアドレス、名前、誕生日のリストがある
* ユーザはSlackにGoogleSSOでログインしている（↑のメールアドレスと同一）

## 方針
1. Slackのカスタムコマンドを作成し、GASを呼び出す
2. GoogleSpreadsheetの該当列から必要な情報を取得
3. Slackbotにしゃべらせる

## 実装
### 1. Slackのカスタムコマンドを作成し、GASを呼び出す

こちらの記事を参考にして、まずメッセージのやりとりができるかどうかテスト。
[Slash CommandsとGASでSlackのオリジナルコマンドをつくる](https://qiita.com/chikuwa111/items/7a1a349b82318a5861cc)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649785/8d2f0bea-f507-666a-dc40-a05d82b8b740.png)

**エラー「http_client_error」により失敗しました**
えーっ。

最初からつまづく。
↑の記事のコメント欄でも困っている方がいるようだ。

このエラーは**権限エラー**だと思われる。
うちのGSuiteは自組織内のみでアクセスを許しているため、アクセス権限に「全員」を選ぶことが出来ない。
自組織内の誰か、に設定したものの、ちゃんと動かない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649785/847c8dd8-b490-eb5f-1b11-eb114008df2d.png)

…で終わってしまうのも寂しいので、プライベートアカウントを使って実装までやってみる。
まずは固定で結果を返すプログラムを作る。

```js:コード.gs
function doPost(e) {
  var birthday = get_birthday(e.parameter.text);
  var response = { text: Utilities.formatString("あなたの誕生日パートナーは%sさんだよ！ 誕生日は%sです。忘れないでね！", birthday.name, birthday.date) };

  return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}

function get_birthday(user_name) {
  var name = '山田太郎';
  var birth_date = '01/01';
  
  return {name: name, date: birth_date};
}

```

これで固定メッセージがでるようになった。

### 2. GoogleSpreadsheetの該当列から必要な情報を取得

公式リファレンス
https://developers.google.com/apps-script/reference/

このあたり、参考にさせていただく。
https://www.pre-practice.net/2018/01/blog-post_21.html

* Slackから飛んでくるユーザIDを取得
* そのユーザIDで検索し、列の名前、誕生日を取得
* 誕生日パートナーは複数いるかもしれないので、その対応
* パートナーがいない場合は悲しそうにお知らせする

等の要素を組み込み、最終的にこうなりました。

```js:コード.gs
function doPost(e) {
  // パラメータ指定がある場合はその指定ID、なければログインID
  var birthday = make_message((e.parameter.text) ? e.parameter.text : e.parameter.user_name);
  var response = { text: birthday };

  return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}

function make_message(user_name) {
  // 該当列取得
  var book = SpreadsheetApp.openById('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
  var sheet = book.getActiveSheet();
  var finder = sheet.createTextFinder(user_name);
  var results = finder.findAll();

  // 結果を連結
  names = [];
  results.forEach(function(user_id) {
    index = user_id.getRowIndex();
    name = sheet.getRange(index, 5).getValue();
    date = sheet.getRange(index, 6).getValue();
    names.push(Utilities.formatString("%sさん (%s)", name, Utilities.formatDate(date, 'Asia/Tokyo', 'MM/dd')));
  });
  
  var birthday = names.join(', ');
  return (birthday) ? Utilities.formatString("あなたの誕生日パートナーは%sだよ。 忘れないでね！", birthday) : "あなたの誕生日パートナーは見つかりませんでした…。あれれ？";
}
```

## 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649785/d19d18a0-2af8-6b5a-cd2a-f5f5944f91b4.png)


## まとめ
Spreadsheetまわりの関数を調べるのに時間がかかったが、
それ以外はいたって簡単でした。
アプリ間連携がこんなに簡単になっているとは。

未だGsuiteの制約を突破できていないので、他に実現方法はないか引き続き情報収集していきます。
Rails 『NO FILEのマイグレーションファイルを削除する方法』

##状態
$rails db:migrate 実行後のマイグレーションファイルを削除してしまい、NO FILEのファイルが出来た。

##解決方法
#####1、migrateの状態確認。

```:ターミナル
rails db:migrate:status
```

するとこうのように表示される↓

```:ターミナル
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200602094458  Create messages
   up     20200604080747  ********** NO FILE **********
```


#####2、NO FILEのMigration IDをコピペし、ダミーファイルを作成。(hogeのとこは任意)

```:ターミナル
touch db/migrate/20200604080747_hoge.rb
```

#####3、ダミーファイルの中身を作成。

```ruby:20200604080747_hoge.rb

class Hoge < ActiveRecord::Migration[5.2]
  def change
  end
end
```


#####4、Migration Nameが付与されていることを確認。

```:ターミナル
rails db:migrate:status
```

するとこうのように表示される↓

```:ターミナル
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200602094458  Create messages
   up     20200604080747  Hoge
```


#####5、削除したいマイグレーションファイルのStatusをdownにする。（$ rails db migrate　実行前に戻す）


```:ターミナル
rails db:migrate:down VERSION=20200604080747
```


downになったか確認

```:ターミナル
rails db:migrate:status
```

↓

```:ターミナル
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200602094458  Create messages
  down    20200604080747  Hoge
```

#####6、downを確認したら削除

```
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200602094458  Create messages
```





マイグレーションファイルの扱い要注意ですね。
かなりの時間ロスです。
JavaScriptで位置情報を取得させる方法

## JavaScriptで位置情報を取得する

`手順`

1.JavaScriptで位置情報の取得を促すダイアログを表示させ、ユーザーにクリックしてもらう。
2.成功したら位置情報を取得してビュー(HTML)に現在位置を数値として返す


たったこれだけで位置情報を検知し、表示させることができる。

[![Screenshot from Gyazo](https://gyazo.com/b459a8ab1f2309ceb4bc1e92f3d23ca4/raw)](https://gyazo.com/b459a8ab1f2309ceb4bc1e92f3d23ca4)


## 位置情報許可ダイアログの表示

```javascript

function success(pos){
 console.log('pos');
}

function fail(error){
 window.alert('位置情報の取得に失敗しました。エラーコード：' + error.code
}

//成功した時にsuccess function　失敗した時にfail functionを呼び出せるように定義しておく

navigator.geolocation.getCurrentPosition(success,fail);

//ここで分岐している

```


`navigator` オブジェクトの、`geolocation` オブジェクトの中で`getCurrentPosition` メソッドを使用しています。

getCurrentPositionメソッドの()内のパラメーターの中には先ほど定義しておいたfunctionを呼び出すようにします。

successした時にはデベロッパーツールのコンソールに位置情報オブジェクトposの中に緯度、経度、精度（誤差）を表示させる。
failした時にはアラートでエラーが起きたことを表示させるようにし、errorオブジェクトのcodeプロパティを呼び出しアラート上に表示させる。

errorコードの内容

|エラーコード| 内容 |
|:-------:|:------:|
|1|位置情報を取得する時に許可がない|
|2|何らかのエラーが発生し位置情報が取得できなかった。|
|3|タイムアウト　制限時間内に位置情報が取得できなかった。|


## HTMLを書く
```html
<p>あなたはいま</p>
<p id="loc" class="position"></p>
<p>の場所にいます。ちなみに精度は半径 <span id="accuracy" class="position"></span> mです。</p>
```

あとでid属性を書いたところに位置情報を表示させます。

## JavaScriptを編集する

```javascript

function success(pos){
 //console.log('pos');  先ほど記述したコンソールはコメントアウト
 
 const lat = pos.coords.latitude;   //緯度を取得して定数latに代入
 const lng = pos.coords.longitude;  //経度を取得して定数lngに代入
 const accuracy = pos.coords.accuracy;  //同じく精度を定数accuracyに代入

 $('#loc').text(`緯度：${lat} 経度：${lng}`);
 $('#accuracy').text(accuracy);
} 
```

大体の流れとして理解できたでしょうか？~~わかりにくいんじゃ！~~

位置情報をプロパティで取得して定数化、指定のidがある箇所に`text`メソッドで表示させるという流れでした。

textメソッドはjQueryのメソッドでオブジェクトで指定したテキスト情報を表示させるメソッドです。

完成ソースコードを掲載して終わりにします。

```javascript

function success(pos){
    const lat = pos.coords.latitude;
    const lng = pos.coords.longitude;
    const accuracy = pos.coords.accuracy;

    $('#loc').text(`緯度：${lat} 経度：${lng}`);
    $('#accuracy').text(accuracy);
  }

  function fail(pos){
    alert('位置情報の取得に失敗しました。エラーコード：');
  }

  navigator.geolocation.getCurrentPosition(success,fail);
```

結構簡単に位置情報を取得できるのでいいですね！！！
【Chrome デベロッパーツール】Local Storageのキャッシュをクリアして一度だけ再生のアニメーションを検証

JavaScriptでイベント処理を一度だけに設定しているアニメーションを確認したい、
そんなとき効率的にStorageキャッシュクリアする方法をご紹介します。

強制リロード Cmd+Shift+R では、キャッシュクリアされないので
ChromeデベロッパーツールでLocal Storageのクリアを行います。

# :keyboard:Local Storageクリアの方法

DeveloperTool＞Application＞Storage＞Local Storageを右クリック＞Clear

![Alt text](https://i.gyazo.com/e022559692a76984a95829ee62e2c5cf.png)

これでアニメーション検証が捗っちゃいます:man_tone1:
xcopyで「ファイル名ですか、 またはディレクトリ名ですか」って聞かれるときの対処

自身の備忘を兼ねて記載を行っています。
「とりあえず動いた」程度のソースなどもございますので参考程度にブラシアップ頂けると幸いです。
また、誤りやもっとよいコーディングやきれいな書き方があるなどご指摘頂けるととてもうれしいです。

## 今回のお題
windowsのコマンドプロンプトでxcopyコマンドを使ってファイルやらフォルダやらをコピーする際に、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498822/189ad201-bdc8-d8d0-60f5-21f4901c4849.png)
なんて聞かれることありますよね。。。

その対処法について

## 対処法

### 対処法１：受け側はファイル名を指定しない
同じファイル名ならこれが一番早い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498822/9c874290-0bfe-a5cd-7472-54ac8c45525a.png)

### 対処法２：echoっちゃう
先に回答決めつけが可能ならこれも手ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498822/922b88a6-0ab7-13e3-764f-6e7a6ad0091b.png)

(ちなみに↑の例はフォルダの場合、ディレクトリなら「echo D | 」を)

一応、上記さえ覚えとけば大体が何とかできてます。
特殊ケースやほかのやり方があれば是非教えてください。

## さいごに
そもそもディレクトリの指定なら末尾に「￥」つけるから強制ファイルでよくないかな？っと思う今日この頃です。
【Vue.js】Observerから配列の値を取得する

#はじめに
帰ってくる配列の値が{_____ob_____: observer}になってundefinedになった方が対象です。
Vue.jsを勉強し始めて、一ヶ月ほどなので正しい方法だと保証はできませんですが、動かすための一つの方法として見守ってほしいです。

##環境
・node 12.7.0
・vue-cli 4.3.1

##ソースコード
```js
  import firebase from 'firebase/app';
  import'firebase/database'
  import Vue from 'vue';

  created(){
    this.database = firebase.database();
    this.todosRef = this.database.ref('todos');
    var that = this;
    this.todosRef.on('child_added', function(snapshot){
      that.todos.push(snapshot.val());
    });
    this.todosRef.on('child_removed', function(snapshot){
      //削除された要素が除かれた配列を新しく生成する
      let newTodos = that.todos.filter(function(value) {
        //valueとsnapshot.val()の値が異なるものだけを返す。
        return JSON.stringify(value) !== JSON.stringify(snapshot.val());
      })
      //新しい配列をthat.todosに代入する
      that.todos = newTodos;
    });
  },
  data() {
    return {
      todos: []
    }
  }
```

#困ったこと
filter関数内でvalueとsnapshot.val()の値が異なるものだけ返そうとした時、

```js
  let newTodos = that.todos.filter(function(value) {
    //valueとsnapshot.val()の値が異なるものだけを返す。
    return value!== snapshot.val();
  })
```

valueの値が{_____ob_____: observer}となっており、返り値がundefinedになってしまう。
（console.log(value)で確認してみると{_____ob_____: observer}が吐き出されます。）

#改善策
JSON.stringifyでvalueとsnapshot.val()の値をJSON形式に変換して判定する。

```js
  let newTodos = that.todos.filter(function(value) {
    //valueとsnapshot.val()の値が異なるものだけを返す。
    return JSON.stringify(value) !== JSON.stringify(snapshot.val());
  })
```


あとは{_____ob_____: observer}だけが邪魔でした。
配列の中身を取り出せればよかったのでJSON.stringify()を使いました。

#おわりに
正しい解決方法といえるかわかりません。
でも{_____ob_____: observer}から中身を取り出してとりあえず開発を進めたいという方にはオススメできます。
SSL証明書を3分で解説

エンジニアにとっての2年に一度の儀式..そう、それはSSL証明書更新。
まあ自動更新にしていれば問題ないんでしょうが、まだサービスイン前だったり黎明期だったりすると、とりあえず...2年でとっとくか！みたいなことがよくあるわけです。
そして2年という絶妙なタイミングで怒る証明書の期限切れそう通知。
2年も経てば当時作業したエンジニアでも、証明書更新？なにそれ美味しいの？経費で落ちます？あ、paypay使えます？状態になるわけです。

今回はそんな私のために備忘録も兼ねてという感じで残しておきます。
多分3分くらいあれば読めます。10分で書いたので。てへ

## そもそもSSL証明書とは
このサイトは怪しくないよ〜ちゃんと暗号化されているよ〜と言うのを証明するためのもの
認証機関に**怪しくない認定**してもらうことで、ブラウザに鍵マークがつく


## SSL証明書の適用の流れ

やることは大まかに3つ押さえておけばOK！
何をしているのか把握していないと途中で訳が分からなくなるので注意。

1. CSR（証明してほしい内容をDNS側に投げつける）

2. 証明書の取得（DNS側がCSRを受け入れ、証明書を発行する）

3. 証明書の適用（証明書をサーバに適用する）


## SSL証明書の種類
この証明書ですが、いくつか種類があります。

### 普通の証明書
どこにでもいる普通の証明書。
ドラクエでいうスライムみたいな存在。
###### 特徴
・FQDNと証明書が1vs1（Taiman）で紐付く。
・安い。

### ワイルドカード証明書
ワイルドだぜぇ
###### 特徴
・サブドメインに幾つでも適用可能
　TLDは同じ必要がある
　`to.tomato.jp`
　`ma.tomato.jp `
　つまり `*.tomato.jp` に一気に適用できちゃう。便利
・ただし、料金がお高い。（普通の証明書の3-4倍くらい）
・サブドメインを多く持つサイトには有能

### マルチドメイン証明書
異なるドメインを紐付け可能。カオス！
##### 特徴
・異なるTLDを設定可能
　`sample.com`
　`tomato.oishii`
・なんか便利な気がする。
・どちらかを親ドメインとして、その下に紐づけていくようなイメージ。

ただし..運用上、色々注意点があります。。
例えば、親のドメインが死ぬと、子もお亡くなりになります..
上の例でいうと、`sample.com`を親にした場合、`sample.com`もういらないからドメインごと消そー..
とかやると`tomato.oishii`にも被害が及ぶわけです。
あな恐ろしや！！！！


この辺りも含めて次回はもうちょっと実践的な証明書更新の手順でも書こうかな..やめようかな..
お腹が空いたのでこの辺で🙋‍♂️

## さいごに
ZEROBILLBANKでは一緒に働く仲間を募集中です。
なんとかjsとか、ブロックチェーンとか、kubernetesとかでいろんなAPIを作るお仕事。
今のところエンジニアは5人くらい。スタートアップだけど、結構ホワイトで働きやすいです。

[ZEROBILLBANK JAPAN Inc.](https://zerobillbank.com)
IQ Bot：インスタンスをどう切り分けるか　Vol.1　～基本編～

[IQ Bot](https://qiita.com/IQ_Bocchi/items/fab5f59230ff38a98bbd)を使い始めたばかりのとき、「インスタンスをどういう単位で切り分けるか」で迷う人が多いようです。

この話は「Excelで複数の表を同じシートに載せるか、シートを分けるか、はたまたブックを分けるか」という問題と似ていて、慣れてくれば感覚的に分け方がわかってきます。

言葉で説明すると少し長くなるかもしれませんが、一度感覚をつかんでしまえば簡単です。

……ということで、「インスタンスの切り分け方」を何回かのシリーズに分けてお伝えしたいと思います。

#前提：インスタンスとグループ

そもそもの前提として、IQ Botには「インスタンス」と「グループ」という単位があります。
インスタンスの配下にグループがあり、学習用にアップロードした帳票は、フォーマットに応じてグループごとに分類されます。
![01_インスタンスとグループ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/0a99e262-6f1b-ae50-e9c5-f0cc647319ef.jpeg)
上記の図をもう少し詳しく説明したのが以下の図です。
インスタンスを作るのはユーザーで、インスタンスに学習用の帳票をアップロードするのもユーザーです。
一方、インスタンス配下のグループを分類する作業は、IQ Bot内部のAIが自動で行います。
![02_インスタンスとグループ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/da12ac5c-26eb-1f52-2321-af9bd079e56f.jpeg)

上の図でいうと、インスタンス１にアップロードした帳票1～5のうち、「帳票1～3をグループ1に分類し、帳票4と5をグループ2に分類する」と決めるのはAIです。（分類の仕組みについての詳細は[こちら](https://qiita.com/IQ_Bocchi/items/b9f6bd9abeb4b9925744#iq-bot%E3%81%8C%E5%B8%B3%E7%A5%A8%E3%82%92%E5%88%86%E9%A1%9E%E3%81%99%E3%82%8B%E4%BB%95%E7%B5%84%E3%81%BF)を参照）

ですが、「帳票1～5をインスタンス1に、帳票6～12をインスタンス2にアップロードする」と決めるのはユーザーです。

そこで、実務では以下のようなことが問題になってくるわけです。

- 帳票1～5と6～12を別のインスタンスに切り分けるべきだと、どうやって判断すればいい？
- 帳票1～3と帳票4～5を同じインスタンスにするべきだと、どうやって判断すればいい？

このシリーズで説明するのは、その部分です。

#基本的な考え方：帳票の種類＝インスタンス／フォーマットの種類＝グループ

基本としては、**請求書、注文書などの帳票の種類ごとにインスタンスを分ける**、という考え方でまずはOKです。

請求書のインスタンスを作成し、A社とB社の請求書をまとめてアップロードすると、IQ Bot内蔵のAIがA社の請求書とB社の請求書を自動で分類してくれる。
注文書のインスタンスを作成し、X社・Y社・Z社の注文書をまとめてアップロードすると、IQ Bot内蔵のAIが各社の注文書を自動で分類してくれる。

……というイメージです。以下はその図解です。

![03_インスタンスの分け方.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/fabf235c-71f6-53f4-dc81-20e41c5a68f4.jpeg)

ここではわかりやすいように「A社の請求書」などと言っていますが、IQ Botが帳票を分類する根拠はフォーマット（さらに言えば、定義した項目の分布（さらなる詳細は[こちら](https://qiita.com/IQ_Bocchi/items/b9f6bd9abeb4b9925744#iq-bot%E3%81%8C%E5%B8%B3%E7%A5%A8%E3%82%92%E5%88%86%E9%A1%9E%E3%81%99%E3%82%8B%E4%BB%95%E7%B5%84%E3%81%BF)を参照））です。

なので、A社とB社の請求書のフォーマットが酷似していたり、罫線の色が違うだけで形は同じ、などという場合は、A社とB社の請求書は同じグループに分類される場合もあります。

また、同じA社でも商品に関する請求書と、サービスに関する請求書でフォーマットが違う場合は、それぞれが別のグループに分類される場合もあります。

#基本編は以上！　この先は……

基本編であるこの記事の内容は以上です。

えっ？　これだけ？　と思うかもしれませんが、[80:20の法則](https://www.movin.co.jp/consul/consul_think/pareto.html)でいえば、この内容さえ抑えておけば、インスタンスの切り分けの判断は8割方正しくできます。

ですが、より細かいところで、例えば以下のような疑問にお答えするために、今後もしばらくこのシリーズの続編を書いていいきたいと思います。

- 請求書は請求書でも、請求元の会社によって書いてある項目が全然違う！　それでもインスタンスは同じにした方がいい？
- 電話料金の請求書と、工場の部品の請求書では使い道が全然違う！　それでもインスタンスは同じにした方がいい？
- 請求書は請求書でも、製造部に来る請求書と経理部に来る請求書で参照権限を分けたい！　そんな場合はどうすればいい？
- 表紙と出荷指示書と貨物の明細が束になって１部となっているような書類も、「表紙のインスタンス」「出荷指示書のインスタンス」「明細のインスタンス」のように分けなきゃダメ？

シリーズ続編の情報をいち早くキャッチしたい方は、[IQぼっち](https://qiita.com/IQ_Bocchi)や[IQ Botタグ](https://qiita.com/tags/iqbot)をぜひフォローしてください！
[技術メモ] ログイン、ログアウトの仕組み


認証にメールアドレスとパスワードを利用する場合、ログインはユーザ情報を保存している
テーブルからユーザが入力したメールアドレスとパスワードがマッチするデータがあるか
どうかを判定します。

ログインするとセッションに既定のデータが保存されるので、ログアウト時には
そのセッションデータを削除することでログイン状態を解除するという仕組みです。
node v12 puppeteer-coreとChromeでWEBページからスクリーンショットを取る

node.js v12.10で座標での画面キャプチャを取得するサンプルを書きました。

探してもあまりネタが無かったので、お試しです。


[Git hub：node_puppeteersample](https://github.com/ajitama/node_puppeteersample)

puppeteerを使用するに当たり、ブラウザが必要になるようです。
AWSで利用する場合は、puppeteer（chrome付き）ではサイズオーバーみたいなので、
puppeteer-coreと、AWSの提供？するChromeアプリを指定してあげないと駄目みたいですね。

ソースはほとんど、他のサイトからのコピペです。
【MySQL】DBの削除方法:Mac

# 概要
アプリを作成していくとDBも溜まっていく。。。。
古いDBは削除してスッキリさせたい:sparkles:
そんな方、必見！DBを簡単に削除する方法です

# 手順
①MySQLへログイン

```Terminal:ターミナル
$ mysql -uroot
```

②削除のコマンドを打つ

```Terminal:ターミナル
$  drop database データベース名;
```
:warning:DB名に"-"(ハイフン)がついている場合は下記のコマンドです

```Terminal:ターミナル
$  drop database 'データベース名';
```
''を忘れずに！！

# おまけ
●データベース一覧を表示

```Terminal:ターミナル
$  show database;
```
●データベースの作成

```Terminal:ターミナル
$  create database データベース名;
```

# 参考
●データベース削除
https://qiita.com/nanatsu/items/33b57238b0e9ae0a1c78
●MySQLへのログイン
https://qiita.com/fuwamaki/items/194c2a82bd6865f26045
●-を含めたDBの処理
https://www.na3.jp/entry/20090128/p1
postgresqlでupsert

Postgresql 9.5以上でCONFLICTというUPSERTができる機能が使えるということで、便利だなと思ったのでやり方をメモしておきます。

```sql
-- test_table_wk のデータで test_table を upsert する
INSERT INTO test_table
    SELECT * FROM test_table_wk
ON CONFLICT
    ON CONSTRAINT test_table_pkey
DO UPDATE SET
    name = excluded.name,
    gender = excluded.gender,
    age = excluded.age;
```

とてもスッキリ書けますね！
OWASP ZAPの使い方

無償で使用できるWebアプリケーション脆弱性ツールのOWASP ZAPのインストール方法などについて備忘兼ねて記述

1.インストール
　(1)以下のURLからインストーラをダウンロード
　　　https://github.com/zaproxy/zaproxy/wiki/Downloads

　(2)ダウンロードしたインストーラを起動
　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/af48112c-1c80-6c3f-4ff5-22970a73d888.png)

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/d8c88917-6ced-504f-1646-270899e2f074.png)

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/a4f1d123-4459-6e8e-7fc6-e07d47ff38b9.png)

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/78c649d1-74d6-31db-021f-06948fdff57a.png)

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/64743b35-a58a-602a-d2af-6fe4f6bded22.png)

2.OWASP ZAPの設定
　(1)ローカルプロキシの設定
　　　「ツール」>「オプション」でダイアログを開き、左ペインでローカル・プロキシを選択する
　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/8724236b-80ce-0bc1-0725-6424d3dce448.png)

　　　ここでポート番号に「55555」を指定する。(8080だとかぶる可能性があるため)

　(2)外部プロキシの設定(プロキシ利用の場合)
　　　左側ペインのネットワークを選択する

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/39c8dcc0-d148-ecf8-24ca-23787bcbb25c.png)

　　　開発環境にプロキシが設定されていれば、「外部プロキシサーバ利用」をチェックし、アドレス、ポートにプロキシサーバーの情報を入力する

　(3)スパイダーの設定
　　　左側ペインのスパイダーを選択する

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/bc49cba6-35fd-b8f0-c607-d012076b1612.png)

　　　今回は以下の通り設定した
　　　　・「クロールする最大の深さ」：15～19程度
　　　　・「並列スキャンスレッド数」：1
　　　　・「新しいURIのSVNのメタデータを解析」：ON
　　　　・「新しいURLのGitのメタデータを解析」：ON
　　　　・「OData固有のパラメータを処理」：ON

　(4)動的スキャンの設定
　　　左側ペインの動的スキャンを選択する

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/54afa69d-abc3-b3e9-4d87-639efa437b96.png)

　　　今回は以下の通り設定した
　　　　・並列スキャンするホスト数：1
　　　　・並列スキャンスレッド数：1
　　　　・スキャン中にミリ秒単位の遅延：1000

　(5)スキャンポリシーの設定
　　　「ポリシー」>「スキャンポリシー」を選択しダイアログを表示する

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/7f85b78c-5211-86a6-c0f0-de245c112df8.png)


　　　追加ボタンを押下

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/45da524f-5ffb-a08a-9efe-079b7a66bf94.png)

　　　今回は以下の通り設定した
　　　　・ポリシー：任意の名称
　　　　・適用：Off→開始ボタン押下
　　　　・適用：低→開始ボタン押下

　　　左側ペインのインジェクションを選択

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/db5cbc73-9223-dcdc-fc69-379a1072b056.png)


　　　今回は以下の通り設定した
　　　　・SQLインジェクション：しきい値「低」、強度「低」
　　　　・クロスサイト・スクリプティング(反射型)：しきい値「低」、強度「低」

　　　一度OKボタンを押下して再度ダイアログを表示して確認する

　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/876a13ff-fc84-8b7a-ae31-0308e8d140a2.png)


3.オートスキャンの実行
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/1c62066b-af93-c5ca-2a2d-7b62ee583608.png)

　　Automated Scanボタンを押下

　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/dba605d6-3877-35dd-89c5-54288d5a31d8.png)


　　以下の通り設定
　　　・URL to attack：検索するサイトへのURL
　　　・Use ajax spider：Chromeを選択

　　「攻撃」ボタンを押下してスキャン実行
【WordPress】LigthningにカスタムCSSを導入する手順

無料のWordPressテーマである「**Lightning**」
こちらのテーマの更新をしても消えないようにカスタムCSSを導入する際の
手順についてです。(導入だけ)


[![Image from Gyazo](https://i.gyazo.com/6e0b333bb341e2482893c4d9010157ee.png)](https://gyazo.com/6e0b333bb341e2482893c4d9010157ee)


# 1. プラグインを追加する
「Simple Custom CSS」を追加し、カスタムCSSを導入可能にします。
[![Image from Gyazo](https://i.gyazo.com/7b937dea6e292c31df77c3d012221373.png)](https://gyazo.com/7b937dea6e292c31df77c3d012221373)

# 2. カスタムcssを記述する
「外観」に「カスタムCSS」が追加されるのでそちらに書き込みます。
試しにヘッダーの背景色を赤にします。
[![Image from Gyazo](https://i.gyazo.com/23b69172f7cb7070055966a7b6d54e9a.png)](https://gyazo.com/23b69172f7cb7070055966a7b6d54e9a)

## 3. 適用を確認
先ほどのcssが当たっているか確認します。
[![Image from Gyazo](https://i.gyazo.com/f0306ca36ae0f1b8f8f6d62ccc5dc095.png)](https://gyazo.com/f0306ca36ae0f1b8f8f6d62ccc5dc095)

_________________________________________________
以上で終了です。
ご覧いただきありがとうございました。