OmniAICreator/Qiita-1.07M huggingface dataset:
[Go 1.13~] errors.Is と errors.As の違いについてお気持ちを理解する 

## TL;DR
これまで Go 1.13 から登場した `errors.As` の使い所があまり良くわからなかったのですが，
全ての答えは[公式 Doc](https://blog.golang.org/go1.13-errors) にありました．

>In the simplest case, the errors.Is function behaves like a comparison to a sentinel error, and the errors.As function behaves like a type assertion.

- `errors.Is`: 特定のエラーとの比較
- `errors.As`: エラーに対する型アサーション

ここでは実例をもとに理解を深めていきたいと思います．

## 実例 `error.Is`
`errors.Is`はあるエラーが特定のエラーを Wrap したものかを判別するためのものです．

```go
import (
	"fmt"
	"errors"
)

ErrFoo := errors.New("foo error")

func main() {
	wrapped := fmt.Errorf("wrapped woo: %w", ErrFoo)
	if errors.Is(wrapped, ErrFoo) {
		fmt.Println("this error is caused by %v", ErrFoo)
	}
}
```
こんな感じで特定のエラーの起源をたどって，例外処理ができます．
比較的単純で「なるほど，便利．」という感じです．

## 実例 `errors.As`
`errros.As` は冒頭でも書いたとおり，エラーに対する型アサーションです．
言い換えると自前でエラー interface を書いたときに，ビルトインのエラーなのか自前で用意したエラーなのかを判別するときに使えます．
また，その付加効果として（こっちがメインかもしれないが），動的に自前のエラー独自のメソッドを利用することができます．

少し長いですがここでは [go-playground/validator](https://github.com/go-playground/validator) を用いた例について紹介します． 
コード自体は基本的に `main` 部に注目してくれればよいです．

```go
import (
	"fmt"
	"errors"

	"github.com/go-playground/validator/v10"
)

type Foo struct {
	NaturalNumber int `validate:"gt=0"`
}

func validateFoo(f *Foo) error {
	v := validator.New()
	return v.Struct(f)
}

func buildFoo(n int) (*Foo, error) {
	foo := &Foo{NaturalNumber: n}
	if err := validateFoo(foo); err != nil {
		return nil, fmt.Errorf("cannot build Foo: %w", err)
	}
	return foo, nil
}

func main() {
	foo, err := buildFoo(-1)
	if err != nil {
		var verrs validator.ValidationErrors
		if errors.As(err, &verrs) {
			for _, verr := range verrs {
				fmt.Println(verr)
			}
			return
		}
		fmt.Printf("unknown error is occurred: %v", err)
		return
	}
	fmt.Printf("this is %v", foo)
}
```

`go-playground/validator` はいわゆる validation エラーを扱うためのパッケージで， `ValidationErrors` という独自のエラーを内部で持っています．

ここで `buildFoo` は `Foo` インスタンスを作成するための関数で，validation エラーが起きた場合はそれを Wrap して返すものとします．
よって，返ってくるエラーは特定のエラーインスタンスを Wrap したものではなく， `ValidationErrors` という interface を満たしたものを Wrap していることに注意してください．つまり，エラーインスタンスに対する比較である `errors.Is`はここで用いることはできません．

そこで型アサーションの役割を果たす `errors.As` を使います．
`errors.As` では `err` を UnWrap していくと `verr` (`ValidationErrors`) として扱うことができるかということをチェックします．
もし可能なのであれば， `errors.As` は `true` を返しつつ，`verr` に Wrap して出てきた `ValidationErrors` を代入します．このため if 文の中では `verrs` は `err` から抽出された実態を持たせて扱うことができ，動的に `ValidationErrors` の機能を用いることができます．
実際に上記コードの if 文内の for 文は `ValidationErrors` が持っている機能です．

## まとめ
実例を見てみると，

- `errors.Is`: 特定のエラーとの比較
- `errors.As`: エラーに対する型アサーション

というのはかなりしっくりきます．
加えて `errors.As` は動的に interface 独自の処理を扱えるようになるので良いですね．

## 参考
- [公式 Doc](https://blog.golang.org/go1.13-errors)
- [Go 1.13時代のエラー実装者のお作法](https://qiita.com/shibukawa/items/e633e426a6e67ea2e830): 実装面の解説でとてもわかりやすかったです！
CentOS8でsloccountがインストールできない

# 環境
- CentOS Linux release 8.1.1911 (Core)

# 現象
dnfでsloccountがインストールできない。

```bash:shell
dnf install sloccount
```
ないよって言われる。

# 原因
CentOS8は新しすぎてsloccountのパッケージがないようだ。

# 対策
rpmでcentos7から借りてくる。

```bash:shell
rpm -Uvh http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/s/sloccount-2.26-14.el7.x86_64.rpm
```
脱メモ帳。Chromeとcontenteditableで頑張る

# tl;dr
* これまでちょっとしたテキストは、Win+Rからnotepadでメモ帳を起動してメモってきた。
* でも、Chromeは常に起動してるし、Chromeをメモ帳代わりに使った方が効率的だと考えた。

# 基本的な使い方
```
data:text/html, <html contenteditable style="color:Azure;background:rgb(32,32,32)">
```
* 上記のURLをEditorなどの名前でブックマーク登録する。Styleは好みに合わせて変更してほしい。
* 以降、URLにEditorと入力しこのブックマークを呼び出して、HTMLのBodyをノート代わりに使っていく
* ここまでは、よく聞く話。

# ちょっとしたデータ加工をやる
* Editorを開いた後に、例えばBodyに下記のようなCSVを書き込んだとする。

```csv
10, 30, 20
50, 40, 15
```
* おもむろにDeveloper Consoleを開き、下記Scriptを実行すると、値が2倍になる。

```JavaScript
document.body.innerText = document.body.innerText.split("\n").map(line=>line.split(",").map(col=>2*col).join(",")).join("\n")
```

* こんな感じで、CSV(やTSV)を加工したり出来る。
* いじった後の内容は、下記Scriptを実行して、ファイルに保存することも出来る(間髪入れずにダウンロードされる)。

```JavaScript
(f=>{let a=document.createElement('a');a.href=window.URL.createObjectURL(new Blob([document.body.innerText],{type:'text/plain'}));a.download=f;a.click()})("edit.txt");
```

* また、header付きのCSVを読み込んでConsole.logする場合は、こんな感じで

```JavaScript
{let b=$x('//text()');let h=b.shift(0).data.split(",");b.map((l,x)=>l.data.split(",").map((r,y)=>console.log(`${x}-${h[y]}: ${r}`)))}
```

* ほかにもcsvをJSONに変換したりと、スクリプト次第で如何様にも出来て、エクセルより楽しい。

# JSON を編集する
* csvが編集できるとなれば、JSONを編集したくなるのが人の性だが、一点注意がある。BodyにJSONを書き込んだとする。

```JavaScript
{
  "a": 1
}
```

* Developer Consoleで下記を実行する

```JavaScript
let j = JSON.parse(document.body.innerText.replace(/\xa0/g, ""));
```

* 改行末尾に \&nbsp; が何故か付与されてしまうため、それを消してからJSON.parseする必要がある点に注意。
* まぁJSONなら最初からDeveloper Consoleにペーストした方が早いのだが。

# 最後に
* 自分はよく、AsciiTableを参照したくなる時があるのだが、その場合は

```JavaScript
document.body.innerText=[...Array(127-32).keys()].map(n=>`${[n+32,"(0x",(n+32).toString(16),"):",String.fromCharCode(n+32)].join("")}`).join("\n");
```

* などとしている。。。。これはcontenteditable関係ないけど。
* こんな感じでメモ帳で出来ることのたいがいは、Chromeでも出来るし、なんならそれ以上のことが出来て便利、という話。
【編集中】ASP.NETアプリケーションのCoverage取得

# TODO
- [ ]  クライアント/サーバ毎に考えた案を記載してない...


# はじめに
タイトルに書いた通り。
サーバ側の単体テストは取得できているが、テストコード自体がそんなにないから、SeleniumでのE2Eテストで実行されたWebAPIのカバレッジを取得できるようにしたい。

# 参考サイト
まずは、下記を参考に試してみる。
◆IIS Support
　https://github.com/OpenCover/opencover/wiki/IIS-Support

◆OpenCover - 実行中のASP.NETアプリケーションに対するカバレッジを測定する - asp.net、opencover
　https://living-sun.com/ja/aspnet/81522-opencover-measuring-coverage-against-running-aspnet-application-aspnet-opencover.html

```bat:coverage.bat
OpenCover.Console.exe -target:C:\Windows\System32\inetsrv\w3wp.exe 
-targetargs:"-debug -s 1" 
-targetdir:%WebSite_Path% 
-filter:+[*]* 
-register:user 
-output:%CoverageResult_Path%
```

# 結果
Coming Soon...　※上記コマンドで試してみて、後で結果を記載...
基本情報技術者　マネジメント系　第3章 システム監査①


# ①システム監査の基礎
第三者から評価のことがシステム監査のこと

## システム監査の目的と内容

システム監査基準の前文に置いて気になる単語は以下になります。

* 情報システムリスク
* 独立から専門的な立場の監査法人
* 点検・評価・検証
* 組織体の経営活動と業務活動の効果的かる効率的な遂行
* 変革の支援
* 目標達成に寄与
* 利害関係者に対する説明責任

## システム監査の種類

### 保証型監査
JISなど各評価基準に合致していること保証すること

### 助言型監査
改善点のアドバイス

## 監査人の独立性
監査人が中立的ないといけません

### 外観上の独立性
身分、組織的に独立

### 精神上の独立性
恣意的な判断はなし

### システム監査基準の記述

* 監査対象の領域または活動
* 独立かつ客観的な立場
* 外観に十分に配慮
* 客観的な視点から公正な判断

## 監査員の慎重な姿勢と倫理の保持

### 慎重な姿勢

### 守秘義務

## システム監査報告とフォローアップ

### 監査報告書の提出

### フォローアップ

## 可監査性
可能であるか
下記の二つの条件を満たしているか

* コントロールが存在
* 監査証跡が存在していること

## 監査証跡
処置過程を追跡できる仕組み、記録

業務日誌やログのこと

## 監査証拠
監査人の意見を立証する事実のこと

### 物理的証拠
書類など

### 文書的証拠
監査人が内容を検証した文書
マニュアル、契約書など

### 口頭的証拠
当事者にインタビューなど

## 監査長所
収集した情報や事実をまとめた文書

## ITシステムの内部統制
ミスが出ないよう統制機能を設ける必要があります。

主に下記のようになります。

### 予防牽制機能
警告などの予防

### 誤謬適時機能
問題発生の早期検知、警告機能

### 修正回復機能
問題検出と同時に修正して影響範囲を最小限にすること。
Laravel migrationで文字列型カラムから数値型への変更でハマった解決策


マイグレーションで数値型→文字列型へのカラム変更が必要になり、変更時は問題なかったものの、rollback時に以下のエラーが発生。


```
 Doctrine\DBAL\Driver\PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1064
 You have an error in your SQL syntax; 
check the manual that corresponds to your MariaDB server version for the right syntax to use near 
'CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE fax fax BIGI' at line 1")
```

原因がわからず困っていたが、よく読むとcharsetが云々書いてあったので、↓で文字列型の時に残っているcahrsetを`null`にして解決！

```

class AddStelToUsersTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('s_tel')->nullable()->after('tel');
            $table->string('tel')->change();
            $table->string('fax')->nullable()->change();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('s_tel');
            $table->bigInteger('tel')->charset(null)->change();
            $table->bigInteger('fax')->charset(null)->nullable()->change();
        });
    }
}

```
Docker on WSL

Windows10のWSL上にDockerをインストールしたメモ

#ソフトウエア環境
Windows 10 Home Ver. 1809 (build 17763.1039)
Ubuntu 18.04.02 LTS (on Windows subsystem for Linux)

#手順
### WSLとUbuntuのインストール
割愛

### Dockerのインストール
**※以下の作業はWSLを管理者権限で実行すること**
(net stop LxssManagerでサービス停止後に管理者権限で起動すると確実？)

```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
 "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
 $(lsb_release -cs) \
 stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce=18.06.1~ce~3-0~ubuntu
$ sudo usermod -aG docker $USER
```
aptでインストールするパッケージにdocker.ioを選択しても動作している人もいるみたいですが、うちの環境ではダメでした。
docker-cdでも最新バージョンではうまく動かず18.06.1で動作確認できました。

この後WSLを一度再起動してから下記のようにDockerデーモンを起動します。

```
$ sudo cgroupfs-mount
$ sudo service docker start
$ docker version
Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:24:51 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:23:15 2018
  OS/Arch:          linux/amd64
  Experimental:     false
```

WSLを管理者権限で動作していないと

```
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```
というエラーが表示され、デーモンが起動しません。
明示的に右クリックから管理者権限で起動してもたまにこのエラーが出ることがあります。
その時はPowerShellで下記のサービスを一旦落としてから起動するとうまくいきます。

```
PS C:\Windows\system32> net stop LxssManager
LxssManager サービスを停止中です.
LxssManager サービスは正常に停止されました。
```

また、Docker.ioパッケージでインストールした場合は
サービスの起動まではできるもののイメージをpullしようとすると

```
Error response from daemon: OCI runtime create failed: container_linux.go:346 (以下略)
```
というエラーが出て使えませんでした。

#その後
個人的な環境づくりのメモです。

```
$ docker run -v /c/usr:/var/c/usr -it ubuntu:latest

// 以下はコンテナ内で
# apt-get update
# apt-get install language-pack-ja git
```

#参考
* [Windows Subsystem for Linux（Hyper-Vなし）でDockerを動かす](https://www.nuits.jp/entry/docker-on-wsl)
* [Windows10でDockerを使うための最短コースをご案内](https://www.orangeitems.com/entry/2019/01/10/143859)
* [Get Docker Engine - Community for Debian](https://docs.docker.com/install/linux/docker-ce/debian/#install-docker-ce)
* [WSL(Debian GNU/Linux)にdockerを入れた](https://qiita.com/lhormace/items/30ed00cd45779f9fcc82)
Dockerで起動したJupyterLabでvimキーバインドを使う

# 概要
前回Jupyter Notebookでvimのキーバインドが使えるようにしましたが、
JupyterLabの存在を完全に忘れていたので、、同様にDockerでJupyterLabを起動してvimのキーバインドが使えるようなやり方をまとめました。

参考：[Dockerで起動したJupyter Notebookでvimキーバインドを使う](https://qiita.com/hikarut/items/b3bd9344dc217e1918c4)

# Jupyter NotebookとJupyterLabの違い
Jupyter notebookの後継機がJupyterLabになってまして、基本的に出来ることはどちらでも同じですが、JupyterLabの方が高機能になっています。
Jupyter notebookの開発は一旦終了して今後はJupyterLabに置き換わるようです。

# 環境
||バージョン|
|:--|:--|
|Mac|10.15.3|
|Docker|19.03.4|
|docker-compose|1.24.1|

# 環境構築手順
Dockerfileとdocker-composeを使ってvimのキーバインドが使えるJupyterLabを起動します。
※以下ファイルはGitHubにもまとめているのでご参考ください。
https://github.com/hikarut/Data-Science

##### 1. notebook保存用のディレクトリ作成
```
$ mkdir notebooks
```

##### 2. Dockerfileの作成

```dockerfile:Dockerfile
FROM jupyter/datascience-notebook
USER root

RUN pip install jupyterlab==1.0
RUN jupyter serverextension enable --py jupyterlab
RUN jupyter labextension install jupyterlab_vim

EXPOSE 10000
CMD ["bash"]
```
※`jupyterlab_vim`が`jupyterlab 1.0`にしか対応してないようなのでバージョンを指定してインストールしてます
jupyterlab-vim：https://github.com/jwkvam/jupyterlab-vim

##### 3. docker-compose.ymlの作成

```yml:docker-compose.yml
version: '3'
services:
  data-science:
    restart: always
    build: .
    container_name: 'data-science'
    ports:
      - "10000:10000"
    working_dir: '/root/'
    tty: true
    volumes:
        - ./notebooks:/root/notebooks/
```

##### 4. コンテナのビルド
```bash
$ docker-compose up -d --build
```

##### 5. コンテナにログイン
```bash
$ docker-compose exec data-science bash
```

##### 6. Jupyter Notebookの起動
```bash
/root# jupyter lab --port 10000 --allow-root
```
表示される`http://127.0.0.1:10000/?token=xxxxxxxxxxxxxxxx`にアクセスします。

Jupyter Notebookの時のように設定変更する必要もなく、そのままの状態でnotebook上でvimが使えるようになります
<img width="1273" alt="スクリーンショット 2020-02-17 22.34.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110485/cb573e1a-3673-8a28-2544-ed29028bcf8b.png">


# 最後に
JupyterLabの方がJupyter Notebookよりも気持ちセットアップが楽でした！
(今回もユーザーを全てrootにしちゃったのでその辺は変えた方が良いかもです。。。)
ただjupyterlab-vimのビルドがめちゃくちゃ遅いのが気になりましたが、、今後改善されると嬉しいなと思います。


##### 参考
* [JupyterLabのすゝめ](https://qiita.com/kirikei/items/a1639954ce5ccaf7ac3c)
* [DockerでJupyterLabを構築する](https://qiita.com/muk-ai/items/a147cfd2cafc57420b15)
* [jupyter lab - jupyterlab-vimのインストールエラーを解決する方法](https://tutorialmore.com/questions-969856.htm)
vue.js内で使うaxiosで複数APIリクエストをまとめて行う方法

vue.js内でaxiosを使う場合複数のAPIリクエストをしたい場合があります。その時にきれいにやる方法です。

```vuejs:index.vue
<template>
省略
</template>

<script>
import axios from 'axios'

function getData () {
  return Promise.all([
    axios.get(process.env.API_URL + '/posts'),
    axios.get(process.env.API_URL + '/services'),
    axios.get(process.env.API_URL + '/shops'),
  ]).then(([posts, services, shops]) => {
    const data = {}
    data.posts = posts.data
    data.services = services.data
    data.shops = shops.data
    return Promise.resolve(data)
  })
}

export default {
 async asyncData () {
    const data = await getData()
    return {
      posts: data.posts,
      shops: data.shops,
      services: data.services
    }
  }
}

</script>

<style>
省略
</style>
```
[git]git revert（あるコミットの内容を打ち消すコミットをする）

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

# ■やりたいこと

gitで、間違えてコミットしてしまった内容を元に戻したい。
その際に、間違えてコミットしたこと、それを元に戻したことをログ上に残しておきたい。

で、調べたところ、gitには`git revert`という便利なコマンドがあるようなのだが、自分が使っている`Tortoise Git`というgitのGUIツールではそんなコマンドがなさそうに見える。
(というか、TortoiseGit上にも`revert`という表示はあるが、なんかそれとはちがうことしてそう？な感じがする)

TortoiseGit上で、本来の`git revert`をしたい。

# ■やったこと

色々調べたところ、TortoiseGitではgitコマンドでいうところの`git revert`はできない様子。
TortoiseGitの`revert`は、gitコマンドでいうところの`git checkout`と同じらしい。([参照](http://kaepapa.hateblo.jp/entry/2013/04/17/131152))
→ローカルで変更して、コミットする前の変更(作業ツリー上だけの変更)をなかったことにする、という意味で使っていた。
**私はこれが`revert`だと思っていた。**

本来の`git revert`はそうではなく**「打ち消しコミット」**をするもののようで、まさにそれが今回やりたいことだった。
([ココ](http://www-creators.com/archives/2020) の 「git  revert で取り消しコミットを作成する」)

## Windows上に作ったリポジトリでのgit revertのやり方

コマンドプロンプトを開いて、リポジトリのフォルダまで行って`revert`のコマンドを入れればよい。
具体的には、下記のようにした。

- エクスプローラで、リポジトリのフォルダ(=`.git`フォルダのあるところ)を開く
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/1a02b609-6258-00a1-3f7b-85dc697b3fb2.png)
- パスの窓に、`cmd`と入れてEnterを押し、コマンドプロンプトを開く。(これで、コマンドプロンプトで`cd そのフォルダ`としたのと同じになる)
- TortoiseGitでログを表示し、打ち消したいCommitのコミット番号を見る。
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/0f2ac3f9-a3a6-9587-1439-13ab6d6e793d.png)
- 開いた黒窓に`git revert <コミット番号>`と入力し、Enterする
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/d7994325-63d6-220e-b45c-70cbc158ece8.png)

これで、revertが実行される。
実行された後にTortoiseGitでログを見ると、「revert <打ち消したコミットのコミットコメント>」と表示され、打ち消した内容がコミットされている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/2c405fc3-afd3-6fd2-a7f3-a72dc93521cc.png)


これで打ち消しコミット完了。

# 余談

エクスプローラのアドレスバーで「cmd」と打ってEnterすると、コマンドプロンプトを開いてそのフォルダに`cd`したのと同じになる、というのも実は今回知った。

# ■参照

TortoiseGitのrevertについて
http://kaepapa.hateblo.jp/entry/2013/04/17/131152

git push の取り消し方法
http://www-creators.com/archives/2020
tableauで県/州/省を可視化する

 tableauで県/州/省レベルで可視化ができずあれ？と思ったのでメモ

# 元データ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573747/fc7cb366-57d7-0012-3a74-4b9311b16a09.png)


# 単純にやったらこうなった
国毎しか県州省を認識してくれない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573747/ee8ed06d-dfa1-c0df-a17a-3e693080d6bf.png)

# こうすればよかった
国と県州省で階層化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573747/a6375749-a598-9a99-f922-32765292e2b3.png)
Flutter StatefulWidgetのライフサイクル

# はじめに

Flutterで多用する`StatefulWidget`のライフサイクルについてまとめています。
Flutterのライフサイクルというと、

 * アプリ (`AppLifecycleState`)
 * 画面 (`StatefulWidget`) ←　今回の内容

の2種類がありますが、今回は下の`StatefulWidget`のライフサイクルについての内容です。 
アプリのライフサイクルについては、[Flutterアプリのライフサイクル](https://qiita.com/kurun_pan/items/0c6de1313844a8cc1603)を参照してください。

# StatefulWidgetのライフサイクル

最初にライフサイクルの状態遷移図を以下に示します。

グレーの四角が`StatefulWidget`の状態遷移時に呼ばれるメソッド名を示しており、それ以外が`StatefulWidget`の状態名を示しています。
<img width="859" alt="スクリーンショット 2020-02-17 22.31.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/6e09cd1f-6fbf-bba5-a9ae-aee9042baac3.png">

`StatefulWidget`の[ソースコード](https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/widgets/framework.dart)を見てみると、以下のように内部では4状態が定義されています。

```Dart:
/// Tracks the lifecycle of [State] objects when asserts are enabled.
enum _StateLifecycle {
  /// The [State] object has been created. [State.initState] is called at this
  /// time.
  created,

  /// The [State.initState] method has been called but the [State] object is
  /// not yet ready to build. [State.didChangeDependencies] is called at this time.
  initialized,

  /// The [State] object is ready to build and [State.dispose] has not yet been
  /// called.
  ready,

  /// The [State.dispose] method has been called and the [State] object is
  /// no longer able to build.
  defunct,
}
```

## created状態

`StatefulWidget`.`createState`によりstateクラスの状態が`created`になります。ウィジェットが親ウィジェットに接続される (`mount`される) と、`initState()`がコールされ、状態が`initialized`に遷移します。

`initState()`はWidget初期化時に最初に一度だけ呼ばれるメソッドですが、この時点では`BuildContext`の情報は構築されておらず、利用することは出来ません。

`BuildContext`とは親ウィジェットの状態や情報などの描画制御のための情報を管理しているコンテキストのことです。グラフィックスやUIフレームワークではよく出てくる考え方に近いですが、これについては別途解説したいと思います。

```Dart:
@override
void initState() {
  super.initState();
  // todo: ここに処理を書く
}
```

## initialized状態

`initState()`完了後、すぐにこの`initialized`状態に遷移します。ここで親ウィジェットのElement (BuildContext) が生成されたあとで、`didChangeDependencies()`をコールします。この時点で`BuildContext`が利用できるようになる (ただし、引数で) ため、それが必要な初期化処理をここで行います。

```Dart:
@override
void didChangeDependencies() {
  super.didChangeDependencies();
  // todo: ここに処理を書く
}
```

## ready状態

`didChangeDependencies()`完了後、`ready`状態に遷移します。
初回構築時には`build()`がすぐにコールされ、初回の描画対象のウィジェットが構築されます。

`setState()`を行うことで、強制的にウィジェットの再構成 (`build`) が行われ、再描画が行われます。

また、親ウィジェットが再構築された時には、`didUpdateWidget()`がコールされます。このコールの後、再構築 (`build`) が行われますので、`setState()`は不要です。それ以外の更新処理が何かあれば、ここで対応します。

```Dart:
@override
void didUpdateWidget(MyHomePage oldWidget) {
  super.didUpdateWidget(oldWidget);
  // todo: ここに処理を書く
}
```

## defunct状態

ウィジェットが完全に破棄された状態です。
この状態に来る前に`dispose()`がコールされますので、このタイミングでウィジェット破棄に伴う終了処理を行うと良いです。

```Dart:
@override
void dispose() {
  // todo: ここに処理を書く
  super.dispose();
}
```
プロになるためのWeb技術入門～Webアプリの発展編～

<h1>概要</h1>
Webアプリ開発を続けていくにあたり、そもそもの基礎知識不足を痛感。
名著『プロになるためのWeb技術入門』を毎日の昼休みに読んで生きた知識にしていこう企画です。完全に自分用ですが、業界に入る前までの自分が「これ知りたかった！」と感じたであろう部分を超端的に抜粋しています。復習も兼ねてメモメモ。
(全解説ではありませんが、数回にわたって記事にしていこうと思いますのでお時間のある方は是非。)

<h3>アプリの種類</h3>
**〇デスクトップアプリケーション**
・手元のPC上で処理が完結するよ。
・画面はOSの機能を利用して表示しているよ。
・アプリをPCにインストールしないとダメだよ。

**〇Webアプリケーション**
・サーバー上で処理が行われるよ。
・画面はHTMLで表現されてWebブラウザに表示されるよ。
・アプリをPCにインストールする必要はないよ。

<h3>Webのはじまり</h3>
もともとインターネット自体は研究機関の関係者などの限られた人たちしか使ってなかったよ。
でも、**WWW(World-Wide Web)**や**NCSAMosaic(Webブラウザの原型)**の発展で状況が一変するよ。この頃にHTMLやHyper Textも生み出されるようになったよ。

<h3>Webを支える技術の発明</h3>
・**Webサーバー：レスポンス返してくれる**
・**Webクライアント：リクエスト送る**
上記の2つがお互いやり取りして成り立つよ。
サーバーは大量のコンテンツを1箇所にまとめて管理をしやすくするため、クライアントは多くの人が自由にコンテンツを閲覧できるようにするために存在してるよ。

<h3>HTTP</h3>
WebサーバーとWebクライアントで「通信プロトコル」が決められているよ。プロトコルは情報をやり取りするためのルールみたいなものだよ。共通の言語やジェスチャーでやり取りしないと意思疎通が取れないイメージだよ。

<h3>CGIの誕生</h3>
・**動的コンテンツ：Webサーバー上で動作するプログラムがHTMLを返してくれる**
・**静的コンテンツ：あらかじめ用意されたHTMLを返す**
動的なコンテンツは静的なコンテンツに対して、Webサーバーと連携をとってくれるものが必要だよ。そのための仕組みを**CGI(Common Gateway Interface)**って呼ぶよ。プログラムは当然言語で組むよ。
これらが普及したことで今の「検索エンジン」や「ECサイト」みたいな便利機能が実現可能になったよ。

<h1>まとめ</h1>
細かい説明や大事なとこすっ飛ばしてますがご了承を。。。
PCやネットワーク内部の動きは趣味的な範囲で実務とは切り離されがちらしいですが、超絶勉強になりますね。
読み進めるだけで楽しいです。休み時間が潤います。(続く)
基本情報技術者　マネジメント系　第2章 プロジェクトマネジメント

[基本情報技術者試験](https://qiita.com/savaniased/items/d3f94da4f087e178cb69)
こちらより

まとめた内容を載せます。


# ①ITサービスマネジメントの基礎
ITIL (IT Infrastructure Library):体系的にまとめた物として有名

##  SLA (Servise Level Agreement)
顧客(受け手)とプロバイダ(提供側)で合意したサービスの内容とレベルについて
詳細を記した文書です。

## ITILの概要
PDCAサイクルの考え方を取り入れており
サービスライフサイクルという概念で実践することにしています。

下記の五つの冊子で構成されています。

* サービスストラテジ(サービス戦略)
* サービスデザイン(サービス設計)
* サービストランジション(サービス移行)
* サービスオペレーション(サービス運営)
* 継続サービス改善

### サービスストラテジ(サービス戦略)

* 財務管理
* 需要管理
* サービスポートフォリオ管理

### サービスデザイン(サービス設計)
* サービスレベル管理
* キャパシティ管理
* ITサービス継続性管理
* 可用性管理
* サプライヤ管理

### サービストランジション(サービス移行)
* サービス資産及び構成管理
* 変更管理
* リリース及び展開管理

### サービスオペレーション(サービス運営)
* サービスデスク
* インシデント管理
* 問題管理


### 継続サービス改善(SLAより)
* サービスレベル管理
* サービス測定
* サービス報告



# ②サービスストラテジ、サービスデザイン
* サービスストラデジ: サービス提供方針を戦略的に定義
* サービスデザイン: サービス提供計画作成、インフラ整備

## 財務管理
下記の役割があります。

* 予算管理
* 会計
* 課金: 顧客ごとにコストを配分し、料金を設定する
* 報告

## サービスレベル管理
SLAの管理です。
下記の作業があります。

* 識別
* 定義
* 契約
* 監視
* 報告
* レビュー


### SLR (Service Level Requirement)
顧客の要求をまとめた文書

### サービスカタログ
サービス提供について、わかりやすく顧客に説明した物

## キャパシティ管理
システム全体のサービス提供能力

* 監視
* 分析
* チューニング
* 実装

## ITサービス継続性管理 (ITSCM)
災害時の事業継続能力(BCM)の一環のことです.

下記の作業があります。

* 開始
* 要件と戦略
* 導入
* 運用管理

## ITサービスの復旧
下記の復旧オプションがあります。

* 何もしない
* 手作業に戻る
* 相互協定の合意
* 段階的復旧(コールドスタンバイ)
* 中間的復旧(ウォームスタンバイ)
* 即時的復旧(ホットスタンバイ)

### RTO
Recovery Time Objective: 復旧目標時間
システムが停止してから何時間で復旧させるかという目標時間

### RPO
Recovery Point Objective: 復旧時点目標
いつの時点のデータにまで復旧できるか

### バックアップ方式
RTO,RPOの短時間化には定期的なバックアップが重要です。

上から順に復旧時間が長くなり
バックアップ取得時間が短くなります。

* フルバックアップ
* 差分バックアップ
* 増分バックアップ

## 可用性管理
継続的サービス利用管理

### UPS(無停電電源装置)
予備電源装置、5~10分程度行えます。

### ミラーリング
ディスク装置の二重化です。
代表的なのにRAID-1があります。

### デュプレシング
システムの二重化です。

# ③サービストランジション、サービスオペレーション


## サービス資産及び構成管理
これの役割はITインフラを構成する要素について最新情報を管理することです。
下記の管理があります。

* 計画立案
* 識別
* 状態の監視
* コントロール
* 検証と監査

### CMDB
Configuration Management DataBase: 構成管理データベース
サービス資産及び構成管理の情報の記録をしています。


### CI
ConfigurationItem
サービス資産及び構成管理の対象となる要素

## 変更管理
変更手続きを定めることです。
RFCの検討から主に進めます。

下記の作業があります。

* 記録
* 受入
* 分類
* 計画立案
* 調整
* 評価

### RFC
Request For Change
ITインフラに変更を加える場合に提出する文書

## リリース及び展開管理
本番環境に投入すること

主な作業は以下です。

* 計画立案
* 設計、構築、設定
* 切り戻し計画
* テスト、リリースの受入
* 導入計画
* コミュニケーションと準備
* 配布とインストール

### メジャーリリース
新機能など大規模改修の場合

### マイナーリリース
バグ修正など小規模の場合

### 緊急リリース
セキュリティなど緊急の場合

## サービスデスク
最初の窓口

主な作業はこちらです。

* 質問、問合せ対応
* 情報提供
* サプライヤへの連絡
* 運用管理
* ITインフラの管理

## サービスデスクの形態

* 中央サービスデスク: 一箇所集中
* ローカルサービスデスク: 拠点ごと
* バーチャルサービスデスク: 複数拠点に設置し通信回線で相互に接続した形式

## インシデント管理
インシデント: 障害や事象

管理とはインシデント発生時に応急策を迅速に指示することです。

根本原因究明は後回しです。

下記の作業があります。

* 受付と記録
* 分類
* 照合
* 調査と判断
* 解決と復旧
* 終結
* 進捗の追跡を監視


## 問題管理
インシデントの根本原因解決

いきなりは修正はせず、一度提案してから
余計な悪影響が出ないか確認してから行います。

下記の作業があります。

* 問題の識別と記録
* 問題の分類を割当
* 問題の調査と診断
* 応急修正
* 解決と復旧
* 終結
* 進捗の追跡と監視

### プロアクティブ問題管理
予防的に問題管理を行う

### 既知のエラー
解決と復旧に至ってるエラー

### 未知のエラー
問題そのものがわかってない
Rails_マイグレーション関連

## モデル作成(create_table)
```ruby:command
bundle exec rails g model User
```
User.rbとマイグレーションファイルが作成される。

```ruby:create_users.rb
class CreatePosts < ActiveRecord::Migration[6.0]
  create_table :users do |t|
    t.integer :code, null: false, default: 0
    t.string :name, limit: 30, default: ""
    t.string :password, default: ""
    t.text :description, default: ""
    t.date :hire_date
    # t.timestampsで以下2つを追加
    t.datetime :created_at
    t.datetime :updated_at
  end
end
```

## カラム追加、削除、変更
```ruby:command
bundle exec rails g migration change_columns_to_users(※適当なファイル名）
```

```ruby:change_columns_to_users.rb
class ChangeUsersColumns < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :password_digest, :string, after: :name # 追加
    remove_column :users, :password, :string                   # 削除
    change_column :users, :name, limit: 20, default: ""        # 変更
  end
end
```

## マイグレーション実行
```ruby:command
bundle exec rails db:migrate
            or
bundle exec rake db:migrate
```

## コントローラ作成
```ruby:command
bundle exec rails g controller Users index
```
users_controller.rbとusers/index.html.erbが作成される。
その他にもjs、scss、helper、ルーティングなどが作成される。
カスケード分類器を用いた顔検出

#1. 背景
現在，私はディープラーニングを用いて，顔を認識するプログラムを作成している．まず，学習データとして，大量の顔画像を用意した．この際，人物が映った画像から，顔を検出し，顔の部分だけを切り取る処理をした．このうち，顔を検出する手法として，カスケード分類器を用いた．この記事では，カスケード分類器について説明する．
#2.カスケード分類器とは
 カスケード分類器は，複数の単純な分類器によって構成される分類器である．対象画像に対し，これらの単純な分類器が順番に適用される．すべての分類器を通過したら，検出される．一方で，単純な分類器に1回でも拒否されたら，その時点で検出はされない．よって，検出対象に明らかに該当しない画像は初期の段階で拒否されるため，高速である．
 OpenCVでは，HAAR-Like特徴量を使ったカスケード分類器が用意されている．
>OpenCVのcascadeファイル
https://github.com/opencv/opencv/tree/master/data/haarcascades

HAAR-Like特徴量とは，画像の明暗による特徴量である．画像の局所領域における白領域と黒領域の差を特徴としている．よって，画像をグレースケールに変換してから用いるのが一般的である．
# 3.OpenCVにおけるカスケード分類器
OpenCVにおいては，カスケード分類器が含まれるcascadeファイルを読み込んだ後，detect.MultiScake()によって検出を行う．detect.MultiScake()の返り値はN×4行列となっていてNは検出した数，4は[x,y,width,height]の4要素である．この4要素は，検出した領域を矩形で囲んだ範囲である．xが矩形の左上のx座標，yが矩形の左上のy座標,widthが矩形の幅，heightが矩形の高さである，よって，検出した部分に印を付けたい場合は，OpenCVの描画関数rectangle()を用いて，rectangle(image,(x,y),(x+width,y+height),(255,0,0),2)などと書けば良い．
以下の画像に対して，試してみる．
![PB1-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581527/ab3b6cfa-2af9-b7b9-8771-2e2c108a9a55.jpeg)

ソースコードを以下に示す．

```python:face_detect.py
import cv2

#画像を読み込む
image = cv2.imread('sample.jpg')

#画像をグレースケールに変換する
image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

#ファイルから分類器を読み込む
cascade = cv2.CascadeClassifier("/opencv/data/haarcascades/haarcascade_frontalface_alt.xml")

#分類器を用いて検出を行う
faces = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(1, 1))

#detectMultiScale()の返り値を出力する(確認用)
print(faces)

#検出した顔画像の部分を矩形でマークする
for (x,y,width,height) in faces:
    cv2.rectangle(image,(x,y),(x+width,y+height),(255,0,0),2)

#画像を表示する
cv2.imshow('result',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
実行結果は以下のようになった．1個だけ誤認識があるが，顔は全て検出できている．
![nogizaka.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581527/0fb207f6-42ac-32f9-fe3d-25e3c6274611.jpeg)
ちなみに，detectMultiScale()の返り値を出力したので，出力結果も見てみると...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581527/92ec9eda-849c-33b8-d1d6-75dce2ef7691.png)
上のように，検出された領域(矩形)における，左上の座標，幅，高さの情報が返されている．
#4.余談
前回の記事では，imreadで返される配列を利用して，画像から一部分だけを切り取る手法を学んだ．
>[OpenCV]imreadで返される配列について
https://qiita.com/Castiel/items/53ecbee3c06b9d92759e

そして，今回は顔を検出する手法を学んだ．これらを利用すれば，ディープラーニングにおける，顔画像の学習データを集められるはずだ．今度は，顔画像の学習データを作成することに取り組もうと思う．
Railsのwhere句でプレースホルダを使用する

## なぜプレースホルダを使用するのか

主な理由は以下の2つです。

1. クエリに変数を書くため
2. SQLインジェクションを防ぐため


## 書き方

### where句の基本形
```rb
モデル名.where(条件)
```

### プレースホルダを使用しない記述
```rb
Category.where("name = 'fashion'")
# SELECT "categories".* FROM "categories" WHERE (name = 'fashion')
```

categoriesテーブルのnameカラムにfashionが入っているレコードを取得しています。

### プレースホルダを使用する記述
```rb
Category.where('name = ?', 'fashion')
# SELECT "categories".* FROM "categories" WHERE (name = 'fashion')
```

プレースホルダの有無に関わらず、同じクエリが出力されていますね。上記の例はハードコーディングですが、変数を使用する場合は以下のような記述となります。

```rb
Category.where('name = ?', params[:category_name])
```

### プレースホルダ＋IN句の記述
```rb
Category.where('name IN (?)', ['fashion', 'vehicles', 'food'])
# SELECT "categories".* FROM "categories" WHERE (name IN ('fashion','vehicles','food'))
```

同カラム内でのOR検索をしたい場合、こちらの方がすっきりした記述ですね！

## おまけ

### ハッシュを使用して同カラムでOR検索する記述
```rb
Category.where(name: ['fashion', 'vehicles', 'food'])
# SELECT "categories".* FROM "categories" WHERE "categories"."name" IN ($1, $2, $3)  [["name", "fashion"], ["name", "vehicles"], ["name", "food"]]
```

こちらはプレースホルダを使用していませんが、さらに短い記述になりましたね！

## 参考
- [SQLインジェクション](https://railsguides.jp/security.html#sql%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)
- [Active Record クエリインターフェイス(2.2 配列で表された条件)](https://railsguides.jp/active_record_querying.html#%E9%85%8D%E5%88%97%E3%81%A7%E8%A1%A8%E3%81%95%E3%82%8C%E3%81%9F%E6%9D%A1%E4%BB%B6)
R リテラルなしquit

# 「No」と言えない人がワークスペースを保存しないで終了したいときに
Raclett3さんの[文字列と数値と真理値のリテラルに親を殺されたPythonプログラミング](https://qiita.com/Raclett3/items/9e0fec83800e62dd631d)に触発されてやってみました
リテラルについてはあまりなじみがありませんでしたが、一応使わない形にできていると思います
他にもいろいろな方法があると思いますが一例として見ていただければ

参考：

- [リテラル (literal)](https://wa3.i-3-i.info/word15346.html)
- [The R Base Package](https://stat.ethz.ch/R-manual/R-devel/library/base/html/00Index.html#H)

# コード
```r
q(rawToChar(as.raw(as.hexmode(as.numeric(c(paste0(length(length({})), length(length({})), length({})), paste0(length(length({})), length(length({})), length(length({})))))))))
```
コピペすればRが終了します

# 解説
## 0と1の取得
`{}`でNULLを取得し、`length({})`と`length(length({}))`でnumericの0と1を取得

## 110と111を含むベクトルを作成
`paste0`でcharacterの110と111を作成し、ベクトルにしてから、`as.numeric`でnumericに変換

## 110と111を16進数に変換
`as.hexmode`で110と111を6eと6fに変換

## バイトコードに変換し"no"を取得
`as.raw`で上記のベクトルをバイトコードに変換してから、`rawToChar`でcharacterの"no"に変換

## "no"をqに渡して終了
上記の"no"を`q`に第一引数として渡して、`save="no"`として実行させると終了する

# 備考
[文字列・数値リテラルを使わずに Hello World](https://blog.recyclebin.jp/archives/4044)の方法に倣ってやった方が簡単かもしれません
PostgresのDockerImageに変更があって起動ができなくなった話

## はじめに
DockerでLocalの開発環境としてPostgresの環境を構築していたんですが、
急に動かなくなってしまったのでメモがわりに残しておきます。

## 環境

```bash

$ docker version

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea
 Built:             Wed Nov 13 07:22:34 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea
  Built:            Wed Nov 13 07:29:19 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
```

## 問題発生

docker-composeでPostgresのimageを設定してLocalで開発環境を構築していました。
ところが今日(2020/02/17)起動した際に急に動かなくなる自体が発生。

```yml:docker-compose.yml(抜粋)
services:
  db:
    image: postgres
```

`docker-compose up`で起動した際に以下のエラーが出ました。

```bash

Error: Database is uninitialized and superuser password is not specified.
       You must specify POSTGRES_PASSWORD for the superuser. Use
       "-e POSTGRES_PASSWORD=password" to set it in "docker run".

       You may also use POSTGRES_HOST_AUTH_METHOD=trust to allow all connections
       without a password. This is *not* recommended. See PostgreSQL
       documentation about "trust":
       https://www.postgresql.org/docs/current/auth-trust.html
```

## 調査

エラーの内容をみる限りはスーパーユーザーのパスワードが指定されていなかったことに起因するもので、
対応すべき内容も書いてあります。
一応該当のエラーで検索してみると以下のページにたどり着きました。
ちょうどこのページも3日前にopenされた内容です。

https://github.com/docker-library/postgres/issues/681

どうやら以下のコミットが5日ほど前にマージされた影響のよう。

#### 該当のコミット
https://github.com/docker-library/postgres/commit/42ce7437ee68150ee29f5272428aa4fc657dc6dc#diff-ba37482f8f538bee02287ee127ffe99fR109

#### マージされたPR
https://github.com/docker-library/postgres/pull/658


今回は開発環境でパスワードが設定されていない状態でDBに接続していたので、
上記の改修で繋がらなくなってしまった模様。

## 解決

今回は自分のlocal環境で開発する際に確認のために一度だけ繋がればよかったので
`POSTGRES_HOST_AUTH_METHOD`オプションを`trust`にすることで対応しました。

本来はきちんとパスワードを設定した方が良いです。

```yml:docker-compose.yml(抜粋)
services:
  db:
    image: postgres
    environment:
      POSTGRES_HOST_AUTH_METHOD: 'trust'
      # POSTGRES_PASSWORD: 'postgres' ← envファイルに外出ししても良い
```

## 終わり

今回は

* パスワードが設定されていなかった
* ちょうど週末にimageを整理した際にpostgresのimageを一回削除していた

ことからこの状況が発生してしまいました。

開発環境であってもきちんとパスワードを設定しておく、imageのversionをロックしておくことは大事だと言う教訓ですね。
(ちなみにpostgresのバージョンを`postgres:9.5.10`で指定した場合は発生せず)
Lightningのレポートからレコードの作成・更新をしてみた

##はじめに
以前の会社ではClassicのレポート上でよく条件に合致した一覧からレコードを作成・更新を行っていました。

Lightningへ移行した当初はClassicで動作していたレポート上でレコード作成・更新項目が出来なかったためになかなかLightningに移行できなかったことをよく覚えています。

ではLightningのレポート上でレコード作成・更新ができないかといえばできます！
**フローを使えば同じような形でレコードの作成・更新が可能になります**。

フローの作り方は色々お伝えしていますので、まだ作成できていない方は簡単なフローを作成していただいてから以下の内容を読んで活用していただければと思います。

![レポートで商談更新.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/ce1d91a4-d638-0266-f317-ba6467d68691.png)


![Lightningのレポートで商談更新.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/16fc7038-4c04-b5f2-a97a-fe291c1027e9.gif)


##フローURLを取得する
フローは保存すると、URLが生成され、それを使うことができます。

フローの一覧画面の右側の▼をクリックすると「詳細とバージョンの表示」があります。それをクリックすると以下の場所にURLがあるのでそちらをコピーしてカスタム項目作成画面に移ります。

![フローURL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/1f119531-95f9-fe16-285a-bf3018bb036c.png)


##カスタム項目にフローURLと変数を追加する
例えば実用的で一番シンプルな形の数式は次のようになるかと思います。

HYPERLINK("/flow/Change_Opp_From_Report?Opp_Id="& Id,"商談更新")

公式的にまとめると
`HYPERLINK("[フローURL]?[変数名]="& [項目の指定],"[任意の表示ラベル]")` 

フローURLの後には「?」をつなげます。続いて[変数名]はフロービルダー側で作成した変数の名前を記入します。またURLと項目をつなげるときは「"」のあとに「&」を記入してから項目を指定してあげます。

ただこれを実行してもらうとわかりますが、フローが完了したあと、一番初めのフローに戻ってしまいます。フロー終了後の動作を指定するには「retURL」を使います。

上記を発展させてフロー終了後、指定レコード画面に戻る設定を加えると次のような形になります。

![レポート用フロー項目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/bc0ba4e6-d468-6819-0d1f-76eb6000e167.png)


HYPERLINK("/flow/Change_Opp_From_Report?Opp_Id="& Id & "&retURL=/lightning/r/Opportunity/" & Id & "/view", Account.Name & "の商談更新")

同じように公式的にまとめると
`HYPERLINK("[フローURL]?[変数名]="& [項目の指定] & "&retURL=/lightning/r/[オブジェクトのAPI参照名]/" & Id & "/view",[項目の指定] & "[任意の表示ラベル]") `

複数の変数や戻り値を指定する場合「"」の先頭に「&」を付ける必要があります。
また文字列と項目の指定の前後にも「&」が必要です。

上記のretURLはLightningしか組織で使っていない場合は有効だと思いますが、まだ併用しているところは単に"&retURL=" & Idとします。

上記に「flowLayout=twoColumn」を追加すると2列の表示も可能です。

参考URL
フロー URL の共有、またはカスタムボタン、リンク、Web タブの作成（https://help.salesforce.com/articleView?id=flow_distribute_internal_url.htm&type=5）
Pythonのstaticmethodはどう実装されているのか？

同僚と「デコレータの実装って難しい」という話から、「Pythonの組み込みのデコレータ、例えば `staticmethod` はどう実装されているの？」という話になりました。私もけっこう長い間Pythonを使っているのですが、そういえば挙動を知らなかったので調べてみることにします。

話していた間は、`self`を穴埋めするような実装（[このドキュメント](https://github.com/python/cpython/blob/03acba6f1a851064ba1fa78965ece4354d499c04/Doc/howto/descriptor.rst)にあるような以下の実装）を想定していたのですが、ただオーバーヘッドを作っているだけなので、もっと良い実装をしているはずです。

```python
# Using the non-data descriptor protocol, a pure Python version of :func:`staticmethod` would look like this:

class StaticMethod:
    "Emulate PyStaticMethod_Type() in Objects/funcobject.c"

    def __init__(self, f):
        self.f = f

    def __get__(self, obj, objtype=None):
        return self.f
```


# staticmethodとは

次のコードのように、クラス定義のメソッドの `self` を省略するためのデコレータです。詳しくは[公式ドキュメントを読んでください](https://docs.python.org/ja/3/library/functions.html?highlight=staticmethod#staticmethod)。

```python
class C:
    @staticmethod
    def f(arg1, arg2, ...): ...
```

ちなみに私自身はあまり `staticmethod` は使いません。[スタティックメソッドは要らない子？](https://atsuoishimoto.hatenablog.com/entry/20100807/1281169026)という記事も2010年の時点で書かれている不憫な印象があります😅

# ドキュメントによると

[組み込み関数のドキュメント](https://docs.python.org/ja/3/library/functions.html?highlight=staticmethod#staticmethod)には以下のように記載されています。

> 静的メソッドについて詳しい情報は [標準型の階層](https://docs.python.org/ja/3/reference/datamodel.html#types) を参照してください。

リンク先のドキュメントにはこのように書かれています。

> 静的メソッド (static method) オブジェクト
>
> 静的メソッドは、上で説明したような関数オブジェクトからメソッドオブジェクトへの変換を阻止するための方法を提供します。静的メソッドオブジェクトは他の何らかのオブジェクト、通常はユーザ定義メソッドオブジェクトを包むラッパです。静的メソッドをクラスやクラスインスタンスから取得すると、実際に返されるオブジェクトはラップされたオブジェクトになり、それ以上は変換の対象にはなりません。静的メソッドオブジェクトは通常呼び出し可能なオブジェクトをラップしますが、静的オブジェクト自体は呼び出すことができません。静的オブジェクトは組み込みコンストラクタ staticmethod() で生成されます。

どうやら通常のメソッド定義では「クラス内で関数からメソッドに変換」していて、 `staticmethod` でラップするとその変換が行われないようです。

実際に試したところ、現状のPython3.8では次のような挙動になっています。

```python
# メソッドと静的メソッドを持つクラスを定義
class C:                                                                                                                                    
    def method(self):
        pass

    @staticmethod
    def stmethod(self):
        pass

# クラスの場合は両方ともfunction
print(type(C.method))
# => <class 'function'>
print(type(C.stmethod))
# => <class 'function'>

# インスタンスの場合はメソッドはmethodに変換されていて、静的メソッドはfunctionのまま
c = C()
print(type(c.method))
# => <class 'method'>
print(type(c.stmethod))
# => <class 'function'>
```

ただ、そのすぐ上、「内部型」のドキュメントには以下のようにも書かれています。

> これらの定義は将来のインタプリタのバージョンでは変更される可能性がありますが、ここでは記述の完全性のために触れておきます。

実際のコードを見てみようと思ってCPythonのリポジトリを見たのですが、[構造体の定義箇所](https://github.com/python/cpython/blob/ffd9753a944916ced659b2c77aebe66a6c9fbab5/Objects/funcobject.c#L995)を見つけた以上は読み解けませんでした。ここから実際に初期化されるときに上記のような挙動に実装されているのが確認できたら面白かったのですが…。

# まとめ

「（現行のPython3.8では）クラス内で定義された関数が、methodに変換されており、`staticmethod` でラップするとその変換処理を打ち消すことができる」ようです。ただ、過去のバージョンや、今後のバージョンでは実装方法が違う可能性があります。

CPythonの実装がどうなっているのか、もし詳しく調べられる方がいたらコメントを頂けると嬉しいです。
handy-spannerを使ってspannerのテストをしよう

# はじめに

こんにちわ、すえけん（[@sueken5](https://twitter.com/Sueken51)）です。この記事ではspannerのエミュレータであるhandy-spannerを使ってspannerのコードをテストするやり方を紹介します。

# handy-spanner

handy-spannerはgcpugで管理されているプロジェクトで非公式ではありますがspannerをエミュレートするツールです（[リンク](https://github.com/gcpug/handy-spanner)）。

できることとできないことが[README.md](https://github.com/gcpug/handy-spanner)に書かれているのでチェックしておきましょう。

# built in server

handy-spannerはgolangで書かれていてテストプロセスの中でエミュレータを起動して使うことができます。なのでDockerなどを用意する必要がないためとても簡単にテストできます。

```go

//https://github.com/gcpug/handy-spanner/blob/master/fake/example_test.goより抜粋

func ExampleSpannerClient() {
	ctx := context.Background()
	dbName := "projects/fake/instances/fake/databases/fake"

	// Run fake server
	srv, conn, err := fake.Run()
	if err != nil {
		log.Fatal(err)
	}
	defer srv.Stop()
	defer conn.Close()

	// Prepare spanner client
	client, err := spanner.NewClient(ctx, dbName, option.WithGRPCConn(conn))
	if err != nil {
		log.Fatalf("failed to connect fake spanner server: %v", err)
	}

	// Use the client
	_, _ = client.Apply(ctx, []*spanner.Mutation{
		spanner.Insert("Test",
			[]string{"ColA", "ColB"},
			[]interface{}{"foo", 100},
		),
	})

	// output:
}
```

# 実際のテストコード

```go

//init_test.go
package spanner_test

import (
	"fmt"
	"log"
	"os"
	"testing"

	"github.com/gcpug/handy-spanner/fake"
	"google.golang.org/grpc"
)

var (
	testServer     *fake.Server
	testConnection *grpc.ClientConn
)

func TestMain(m *testing.M) {
	fmt.Println("test main")

	// Run fake server
	server, conn, err := fake.Run()
	if err != nil {
		log.Fatal(err)
	}
	
	defer server.Stop()
	defer conn.Close()

	testServer = server
	testConnection = conn

	ret := m.Run()
	os.Exit(ret)
}
```

`TestMain`でhandy-spannerサーバーを起動しておきます。

```go

func TestGet_OK(t *testing.T) {
	databaseID := "get-ok"
	dbName := fmt.Sprintf(dbFormat, projectID, instanceID, databaseID)

	ctx := context.Background()
	testCase := struct {
		input  []byte
		key    string
		expect []byte
	}{
		input:  []byte("OK"),
		key:    "test",
		expect: []byte("OK"),
	}

	if err := createDatabase(context.Background(), dbName); err != nil {
		panic(err)
	}

    //fakeサーバー起動時に渡されたコネクションを使ってクライアント生成
	client, err := spanner.NewClient(ctx, dbName, option.WithGRPCConn(testConnection))
	require.Nil(t, err)

	s := &spanner.Store{
		PKey:  testCase.key,
		Value: testCase.input,
	}

	mut := s.Insert(ctx)
	_, err = client.Apply(ctx, []*libspanner.Mutation{mut})
	require.Nil(t, err)

	actual, err := Get(ctx, testCase.key)
	require.Nil(t, err)
	assert.Equal(t, testCase.expect, actual)
}
```

`TestMain`でサーバーを起動した時に生成されたコネクションを使ってspannerのクライアントを生成します。あとはいつも通りテストするだけです。

# まとめ
簡単にテストできたのでとてもよかったです。
Visual Studio 2019でnumpyをインストールする

### はじめに
* Anacondaの使用経験しかなかったために、Visual Studioにてnumpyをインストールする際に困った際の備忘録を残します。

### 操作方法
1. [表示]->[その他のウインドウ]->[Python環境]を選択する。
![numpy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298199/313a527f-b736-85d0-a065-6d436eb7dc8a.png)

2. 右側ペインにて「パッケージ(PyPI)」を選択し、すぐ下のテキストボックスに「numpy」と入力する。
![numpy2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298199/4a5b3344-1a13-a0e4-8d5d-1dbc1fdf40cb.png)

3. 「次のコマンドを実行する: pip install numpy」をクリックする。

---
### 参考情報
> https://docs.microsoft.com/ja-jp/visualstudio/python/tutorial-working-with-python-in-visual-studio-step-05-installing-packages?view=vs-2019
「小説家になろう」バックアップファイルからメタデータを抽出する

#はじめに
「[「小説家になろう」バックアップファイルをTeX変換する](https://qiita.com/hiro_literal/items/6a8d06b7782eac2fc6cb)」のとおり、TeX化は実現できましたが、この際にざっくり切り捨てている部分があります。　
せっかくなのでこちらも何かならないかと考えたところ、ちょうどSchema.orgのBookに近いことに気づいたので、下記のとおりメタデータをJSON-LD形式で抽出するシェルスクリプトを書いてみました。

#説明
「小説家になろう」には評価の項目があるのですが、評価者の名前がなく記載に迷ったため、評価については今回は切っています。Reviewを使えば表現はできそうです。
##Code
```bash
#!/bin/bash
LANG=C
FILE=Desktop/result.json
cat << EOF > $FILE
{
 "@context":"https://schema.org",
 "@type":"Book",
 "@id":"https://ncode.syosetu.com/`w='【Nコード】';grep -A 1 $w $1|grep -v $w|tr '[:upper:]' '[:lower:]'`/",
 "name":"`w='【タイトル】';grep -A 1 $w $1|grep -v $w`",
 "author":{
   "@type":"Person",
   "name":"`w='【作者名】';grep -A 1 $w $1|grep -v $w`",
   "sameAs":"https://mypage.syosetu.com/`grep 'ユーザID:.*' $1|sed 's/[^0-9]//g'`/"
  },
 "dateCreated":"`w='【初回掲載日時】';grep -A 1 $w $1|grep -v $w|sed 's/ /T/'`+09:00",
 "dateModified":"`w='【最終掲載日時】';grep -A 1 $w $1|grep -v $w|sed 's/ /T/'`+09:00",
 "genre":"`w='【ジャンル】';grep -A 1 $w $1|grep -v $w`",
 "keywords":"`w='【キーワード】';grep -A 1 $w $1|grep -v $w`",
 "sameAs":"https://ncode.syosetu.com/`w='【Nコード】';grep -A 1 $w $1|grep -v $w|tr '[:upper:]' '[:lower:]'`/",
 "abstract":"`w='【あらすじ】';sed -n /$w/,'$p' $1|sed -n '/【掲載部分数】/q;p'|sed -e /$w/d -e '/\n/d'`"
}
EOF
```

##処理対象例
下記の例示は実際の私の作品のバックアップファイルを一部改変したものです。

```ソース
【ユーザ情報】
ユーザID: 286206
ユーザ名: hiroliteral

【Nコード】
N6070DD

【タイトル】
十歳アリスちゃんは元大魔王でした

【作者名】
hiroliteral

【種別】
連載小説

【完結設定】
連載中

【年齢制限】
年齢制限なし

【ジャンル】
ハイファンタジー〔ファンタジー〕

【登録必須キーワード】
残酷な描写あり

【キーワード】
年の差 日常 冒険 ラブコメ 異世界 兄妹 ほのぼの 大魔王 ファンタジー

【あらすじ】
大魔王リルは側近に裏切られ殺害されたが、予め転生呪文を仕込んでいたため最高潮の若い肉体で転生した。
だがリルは、自身の魔力最高潮が十歳だったことを知らず、最高値の年齢で不老化する呪文まで仕込んでいたので、永遠の十歳アリスちゃんに。

【掲載部分数】
47

【初回掲載日時】
2016-02-21 23:55:06

【最終掲載日時】
2020-02-11 16:58:23

【感想受付】
感想を受け付ける（制限なし）

【レビュー受付】
レビューを受け付ける

【評価受付】
評価を受け付ける

【開示設定】
すべての一覧で表示

【評価】＜以下省略＞
```

##結果
```JSON
{
 "@context":"https://schema.org",
 "@type":"Book",
 "@id":"https://ncode.syosetu.com/n6070dd/",
 "name":"十歳アリスちゃんは元大魔王でした",
 "author":{
   "@type":"Person",
   "name":"hiroliteral",
   "sameAs":"https://mypage.syosetu.com/286206/"
  },
 "dateCreated":"2016-02-21T23:55:06+09:00",
 "dateModified":"2020-02-11T16:58:23+09:00",
 "genre":"ハイファンタジー〔ファンタジー〕",
 "keywords":"年の差 日常 冒険 ラブコメ 異世界 兄妹 ほのぼの 大魔王 ファンタジー",
 "abstract":"大魔王リルは側近に裏切られ殺害されたが、予め転生呪文を仕込んでいたため最高潮の若い肉体で転生した。だがリルは、自身の魔力最高潮が十歳だったことを知らず、最高値の年齢で不老化する呪文まで仕込んでいたので、永遠の十歳アリスちゃんに。"
}
```

##その他
TeXファイルにメタデータを埋め込むのであれば、commentパッケージを使ってコメントとして入れてしまうのが現実的に楽かと思います。

```TeX
\usepackage{comment}
\begin{comment}
メタデータ
\end{comment}
```

#参考
[Schema.org/Book](https://schema.org/Book)
Unityのシェーダーができることを初心者視点で調査＠202002

Unityでシェーダーしてデスストみたいなレーダーできるかを
シェーダー未経験が調べるメモ
「おっ」って感じたサイトまとめになった。。


###A not very handy echolocation effect.

ロケーションソナーてきなことができそう、GC書き換えれば

http://www.shaderslab.com/demo-22---echolocation.html

![NoName_2020-2-17_21-30-29_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/17b0b7f5-0712-0c8d-e1ee-9a6e39bfddd9.png)


###While the player is moving, textures change around him.

マテリアルを指定オブジェクト中心に切り抜きできる便利

http://www.shaderslab.com/demo-97---texture-switch-depending-player-pos.html

![NoName_2020-2-17_21-31-5_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/26ee4fec-fde3-4fe6-fd9f-ed395904bfb7.png)



###【Unity】Shaderことはじめ【Shader : 0】
booth参考文献が良さそう
https://qiita.com/Nekomasu/items/6620ab19bfdaeb7743f2

###Unityを利用した空間スキャンライン表現
これをベースにCG言語できればできそう
![NoName_2020-2-17_20-41-49_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/e8b06732-33c9-d83d-395b-8670cd886ec9.png)

https://styly.cc/ja/tips/unity-shader-worldscanline/#x

###HoloShield
いろいろエフェクトつくから今後に使ってみたい
https://github.com/AdultLink/HoloShield#getting-started

![NoName_2020-2-17_20-39-17_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/00be31db-82cd-d8c6-3e3a-bdeb9d6d3025.png)

##ShadersLaboratory

以下はShadersLaboratoryで気になったやつのメモ
Unityで使えるので助かります

###Tessellation depending distance from camera

カメラからの奥行き具合で描画の細かさを変更
http://www.shaderslab.com/demo-46---tessellation-depending-distance-camera.html

###Discard faces depending normal and camera

カメラからの奥行き具合で描画する三角形を変化
http://www.shaderslab.com/demo-51---discard-faces-depending-normal-and-camera.html

###Section

切り口が描画されるからなにかに使えそう
http://www.shaderslab.com/demo-45---section.html


###Volumetric sphere in a cube


矩形中心に円形を描画できる、地形データでもできたら良さそう
http://www.shaderslab.com/demo-32---volumetric-sphere-in-a-cube.html


###Object pit wit a stencil buffer


重なり部を消して、裏側のマテリアル表示できるようです
http://www.shaderslab.com/demo-16---pit-an-object-with-stencil-buffer.html

###Textures depending the normal

テクスチャ　角度などで表示切り替え　一枚のプレーンにまとまるので管理しやすそう？

http://www.shaderslab.com/demo-54---textures-depending-normal.html

###Wireframe

ワイヤーフレームで描画
http://www.shaderslab.com/demo-93---wireframe.html
http://www.shaderslab.com/demo-94---wireframe-without-diagonal.html
ワイヤーフレームっぽい感じ
http://www.shaderslab.com/demo-23---wireframe-like.html

###Moss on rock,Snow effect

岩に草でてくる具合の調整
http://www.shaderslab.com/demo-27---moss-on-rock.html
岩に雪つもる具合の調整
http://www.shaderslab.com/demo-04---snow-effect.html


###Circle on terrain

地形データに直接に描画、ロケーション表現に使えそう

http://www.shaderslab.com/demo-08---circle-on-terrain.html

###Triplanar mapping

地形データに複数のテクスチャ
http://www.shaderslab.com/demo-56---triplanar-mapping.html


###参考サイト

Shaders Laboratory
http://www.shaderslab.com/shaders.html
【UE4】IKで地面の傾きに合わせる／第13回UE4ぷちコン進捗 - 2020/02/17

[1]:http://historia.co.jp/ue4petitcon13

[株式会社ヒストリアさん主催の第13回UE4ぷちコン][1]の作業進捗を書いていきたい。
最後まで続けたいが、締め切り間近でも続けられるのか…

> テーマが決まりましたね！

# 歩き／走りの動きを地面の傾きに合わせたい

![20200217_2155.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/3bb33606-dc68-10bb-1968-052752f8e909.gif)

IKの距離が長すぎて足が伸び切るとか、IKの距離が短すぎてひっくり返るとか、その辺は明日考えるとして、おおむねうまくいった。

大雑把には：

- rootボーン直下でLine Traceして(実際はSphere Traceだが)、コリジョンの法線から地面の傾きを算出している。
    - 足首のボーン(foot_l, _r)から地面に向かってコリジョンをとっているわけではない。なので、地面に凸凹があると埋まったり空中に浮いたりはする。
- 地面の傾きとik_foot_rootボーンの傾きを一致させて、あとはLegIKしている。

…という感じ。

> やはりSkeletal Meshの前方がY軸だというのが面倒くさかった…
> くだらない勘違いでかなり時間を使ってしまった。悔しい。

私のオリジナル手法だと思っているが、他に同じようなことやってる人がいたらすみません。
雑な手法な割にそれなりの見た目が得られて、費用対効果がかなり良いと自画自賛。

※Blueprintのスクショを載せるとか、詳しい話を書くとかすると、この進捗を毎日続けられる気がしないので、大雑把な話だけで済ませます。すみません。
気が向けば（暇ができれば）改めて記事にするかもしれません。

今日はここまで。
TermuxでHugo入門の段

スマホでエンジニアのような事をしたいという目標を達成するー。
素晴らしいアプリ、その名は [Termux](https://termux.com/) です。

2021年5月現在、Google Play内のTermuxは技術的な問題で更新が止まっています。
公式サイトにも書いてありますが、F-Droidで[配布中](https://f-droid.org/en/packages/com.termux/)です。
***
## 1 初期設定
```bash
termux-setup-storage 
# 端末内へのアクセス許可で画像等を使う場合に必要です

pkg upgrade
# アップグレード

pkg install hugo git vim openssh
# インストール
```

### 操作性UPのため .bashrc を変更する
```bash
vim ~/.bashrc
# .bashrcを開く
```

以下、変更点

```bash
alias hgs="hugo -s ~/DIR server"
# "~/DIR" は "hugo new site DIR" をした時の"DIR"を指定
# "hgs" と入力すれば、どの場所にいてもローカルサーバーを起動可能

alias cc="cd && cd DIR"
# "cc" でHugoのディレクトリに移動
```
編集後はアプリの再起動、または

```bash
source .bashrc
```
で、反映させる。こちらの方がエンジニアっぽい。
***
## 2 GithubにSSHで接続する方法
```bash
cd
# 一応もどる
```
意識高い ECDSA 521bit にて

```bash
ssh-keygen -t ecdsa -b 521 -C "your@email"
# メルアドはGithubに登録したアドレス等、お好みで？
# 保存先1回(変えるなら入力)、パスフレーズ2回の入力あり(今回は未設定)
```

```bash
cd .ssh/
cat id_ecdsa.pub
# id_ecdsa.pub の内容をコピーする
```
### Github に id_ecdsa.pub の内容を追加する
1. GitHubにログイン
1. Settings → SSH and GPG keys → New SSH key をぽちっと
1. Titleはお好みで、Keyは **id_ecdsa.pub** の内容をペースト
1. Add SSH key で完了

### 接続する前に

```bash
vim ~/.ssh/config
```

```bash
Host github github.com
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_ecdsa
  User git
# id_rsa_ecdsa の部分は、自分のKey次第で変更を
```

### ssh-agentの設定

```bash
eval `ssh-agent -s`
> Agent pid 32669
# 動作中

ssh-add ~/.ssh/id_ecdsa
# プライベートキーの追加
```

### 接続！
```bash
ssh -T git@github.com
```
Hi 云々のメッセージが出れば無事接続完了

fingerprintsがどうのこうの言われたら、下記のサイトを確認して問題なければ yes と入力で終わり。

https://docs.github.com/en/github/authenticating-to-github/githubs-ssh-key-fingerprints


***
## 3 gitの初期設定忘れがち
```bash
git config --global user.name "yourID"
git config --global user.email "your@email.com"
```
メールアドレスは、

https://ryoichi0102.hatenablog.com/entry/2017/10/12/000713

という訳で

https://docs.github.com/ja/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address

## 3.5 gitのコマンドメモ
```bash
git init 
# Hugoのディレクトリで初期化実行

git branch -m master(main etc)
# ブランチ名決めて？

git remote add origin git@github.com:yourID/yourREPO.git
# リモートレポジトリ追加(SSH接続の場合)

git pull origin master(ブランチ名)
# プル！！

git add .
# ローカルフォルダ内全部追加

git commit -m "hogehoge"
# hogehogeはお好みのコメント

git push origin master(例: main)
# プッシュ！
```

***

## 4 Hacker's Keyboard お好みで
Google Playからダウンロード可能です
![15819430806570_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583839/100ab580-fa4d-7fea-0437-52babf69ab39.jpeg)
ESC右側の矢印か、スペースキー左側の矢印がTab機能を果たします。当然、コマンドの補完もできるので最高に便利。

## こちらの記事で解決しました、感謝！
### Qiita内

https://qiita.com/wnoguchi/items/a72a042bb8159c35d056

https://qiita.com/0ta2/items/25c27d447378b13a1ac3

https://qiita.com/suthio/items/2760e4cff0e185fe2db9

https://qiita.com/yutat93/items/b5bb9c0366f21bcbea62

### 外部サイト

https://maku77.github.io/hugo/command/source-dir.html

### おまけ

https://qiita.com/Qiita/items/c686397e4a0f4f11683d#%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%AB%E3%83%BC%E3%83%89

リンクカード、素敵。