OmniAICreator/Qiita-1.07M huggingface dataset:
Gitでピンチ？落ち着いて、「git reflog」を使用してください

>Gitの操作ミスなら、復旧できる．．． `git reflog`で．．．


## `git reflog` vs `git log`
`git log`、`git status`等は知っているけど`git reflog`は何ですか？
### `log`はブランチのコミットの履歴
`git log`は、現在のブランチに対するrefs（ヘッド、タグ、リモート）からアクセス可能なコミットの洗練された履歴を表示します。
​
別のブランチをチェックアウトすると、別のコミット履歴が表示されます。 
​
※　すべてのブランチのコミット履歴を確認したい場合は、`git log --all`と入力します。
### `reflog`はロカルリポシトリの履歴
`git reflog`は、ロカルリポジトリで指示された、または指示されているすべてのコミットのロカル記録です。
​
コミット又はチェックアウトが行われるたびにエントリがあります。
​
そのため、「破壊的な」操作（ブランチの削除など）を実行するときに、そのブランチによって指示されたSHA1のハッシュを取得するために、`git reflog`（デフォルトで**90日後にプルーニング**されるローカル記録）が使用されます。
## セーフティネット
`reflog`は、修正した内容とリセットしたコミットを追跡するため、くれるコミットIDでコミットを戻って見つけることができます。リポジトリから古いコミットが削除されていなかったら、`log`に表示されなくなったアイテムを復活させることができます。不注意で失ったと思った何かを取り戻す必要があるとき、`git reflog`は時々命の恩人になります。
### 取り戻しの巻
昨日はコミットした後でリモートのプッシュの失敗に気付かなくて別なブランチに代わってハードリセットした後で仕事の一日分を失ったと思たら先輩から「Gitの操作ミスなら、復旧できるかもしれないですよ。 `git reflog`
で、コミットのハッシュを見つければ`checkout`などできるので．．．」と言われました。
​
下記のステップで失ったコードを取り戻しました：
##### 1. `reflog`を表示
```cli:PowerShell
PS C:\Users\owner\My-project-root> git reflog
```
##### 2. コミットに戻る
```cli:PowerShell
PS C:\Users\owner\My-project-root> git checkout x9xx99x
```
##### 3. 新しいブランチ作成
```cli:PowerShell
PS C:\Users\owner\My-project-root> git switch -c feat-dev
```
##### 4. リモートリポジトリにプッシュ
```cli:PowerShell
PS C:\Users\owner\My-project-root> git push -f origin feat-dev
```
##### 5. 助かりました！
## プルーニングの有効期限
 プルーニングの有効期限は、構成設定gc.reflogExpireから取得され、デフォルトで**90日**になります。
​
CDK で API Gateway Mock 統合と Lambda Authorizer を作る

CDK(TypeScript) で API Gateway(REST API) の Mock 統合と、Lambda Authorizer を作ってみました。

ソースコード全体はこちらです。
https://github.com/kazfuku/apigateway-java-lambda-authorizer/blob/master/lib/apigateway-java-lambda-authorizer-stack.ts

## Mock 統合
Mock 統合はこの部分です。

```TypeScript
const mockIntegration = new apigateway.MockIntegration({
  requestTemplates: {
    'application/json': '{"statusCode": 200}'
  },
  integrationResponses: [
    {
      statusCode: '200',
      responseTemplates: {
        'application/json': '{ "message": "mock", "now": "$context.authorizer.now" }'
      }
    }
  ]
});
const method = api.root.addMethod('GET', mockIntegration, {
  methodResponses: [
    {
      statusCode: '200'
    }
  ],
  authorizer: lambdaAuthorizer
});
```

Mock 統合の仕組み上、リクエストテンプレートとレスポンステンプレートが要ります。
リクエストテンプレートでステータスコードを定義して、レスポンステンプレートでそのステータスコードに対応するレスポンス本文を設定します。

$context.authorizer.now の部分は、[Lambda Authorizer が返している現在日時](https://github.com/kazfuku/apigateway-java-lambda-authorizer/blob/master/lambda/authorizer/src/main/java/com/kazfuku/aws/MapLambdaAuthorizer.java#L29) を指しています。

## Lambda Authorizer
Lambda Authorizer はこの部分です。

```TypeScript
const authorizerFunction = new lambda.Function(this, 'AuthorizerFunction', {
  runtime: lambda.Runtime.JAVA_8,
  handler: 'com.kazfuku.aws.MapLambdaAuthorizer::handleRequest',
  code: lambda.Code.fromAsset('lambda/authorizer/target/apigateway-java-lambda-authorizer-1.0.jar')
});

const lambdaAuthorizer = new apigateway.RequestAuthorizer(this, 'Authorizer', {
  handler: authorizerFunction,
  identitySources: [IdentitySource.header('Authorization')]
});
```

Lambda 関数と、API Gateway の Lambda Authorizer (REQUEST タイプ) を定義してます。

最後に、Method に設定するのを忘れずに。

```TypeScript
const method = api.root.addMethod('GET', mockIntegration, {
  methodResponses: [
    {
      statusCode: '200'
    }
  ],
  authorizer: lambdaAuthorizer // <----
});
```

## 参考
* [CDK API Gateway Overview](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-apigateway-readme.html)
* [CDK Lambda Overview](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-readme.html)

## 関連記事
この記事は、[Java Lambda で API Gateway の Lambda Authorizer を実装する](https://qiita.com/kazfuku/items/1f04d374cbd3ddd2b30e) と関連しています。
Java Lambda に興味がある方は、ぜひこちらもご覧ください。
Next.jsでトークン設定済みのAxiosを使えるようにしてみた

# 経緯

* Axiosに認証トークンを設定する処理を共通化したい
* 何ならAxiosを使用する際にトークン設定済みの状態にしたい

# 方法

* Axiosのインスタンスを生成→ヘッダーの設定→そのインスタンスの返却、を行うラッパー?ソースファイルを用意する。

* 各ソースファイルでAxiosを使用したいときは、そのラッパーファイルから呼ぶようにする。

# 実装

* ラッパーファイル（例：customAxios.ts）

```ts
import axios from 'axios'; // Axios本体をインポート

const instance = axios.create(); // Axiosインスタンスを生成

instance.interceptors.request.use(
  (config) => {
    // 認証トークンをヘッダーに付与
    config.headers.common['Authorization'] = 'Bearer ' + process.env.TOKEN; // この例ではBearerトークンを設定
    return config;
  }
);

export default instance; // デフォルトエクスポート!!

```

* 使用例

```ts
import axios from '@/.../customAxios'

// ヘッダーがセットされた状態で送信される！！
axios.get('<path>')
.then(res => {...});

```
# 備考

以下のような引数も取れるのでエラー時の処理も共通化できそう。（試してはいない）

```ts
import axios from 'axios';

const instance = axios.create();

instance.interceptors.request.use(
  (config) => {
    config.headers.common['Authorization'] = 'Bearer ' + process.env.TOKEN;
    return config;
  },
  (error) => {
    // エラー時の処理
    return Promise.reject(error);
  }
);

export default instance;

```

# 後書き

NuxtだとAxiosが最初からモジュール化されているから良い感じにやる方法あるみたいだけど、
Nextだとこれくらいしかスマートな方法がないような。

Nextに限らず色々応用はできそう。

他に良い案があればご意見いただければと。
SpringBoot/Gradle で Hello World

# 環境
* Windows10
* IntelliJ IDEA
* Git Bash

# ディレクトリ構成
以下参照。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534222/f00a11b3-c398-ec8f-3093-3994bfb2d7ab.png)

# build.gradle
[ここ](https://spring.io/guides/gs/spring-boot/) を参考に build.gradle に定義を記載していきます。

``` build.gradle
plugins {
    id 'org.springframework.boot' version '2.3.3.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

def defaultEncoding = 'UTF-8'
tasks.withType(AbstractCompile) each { it.options.encoding = defaultEncoding }

compileTestJava {
    options.encoding = defaultEncoding
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

test {
    useJUnitPlatform()
}
```

右側ペイン Gradle で Reimport します。
![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534222/1b6a5003-5349-5148-074c-fc62b047a9e7.png)

# Hello World
2つのクラスに記載します。

``` BootApp.java
package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BootApp {

    public static void main(String[] args) {
        SpringApplication.run(BootApp.class, args);
    }
}
```

``` Controller.java
package org.example;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class Controller {

    @RequestMapping("/")
    public String index() {
        return "\nHello World!";
    }
}
```

BootApp.java を実行し、GitBash で確認します。

```
$ curl http://localhost:8080/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    13  100    13    0     0    149      0 --:--:-- --:--:-- --:--:--   149
Hello World!
```

# 参考
[gradleで文字コードをutf8に統一](https://qiita.com/toyama0919/items/a91cfcc10826a2d2efc1)
ios14でinputタグの１文字目が大文字になる

# 問題点

```
<input type="text"/>
```
 例えば上記のコードで Iphone(ios14)でみた場合、
下の図のように デフォルトで1文字目が大文字になってしまう
![iOS の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223280/d99f40fa-1879-1a34-b1f6-fca90b4f3ee5.jpeg)

## 解決策

inputタグに、 `autocapitalize="off"` `autocorrect="off"`
というiosのデフォルトの挙動を防ぐコードを追加する

```:結果
 <input type="text" autocapitalize="off" autocorrect="off"/>
```
![Image from iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223280/0f7e36f6-20a9-27d6-4461-1b66a5c50cf7.jpeg)

※ios14で確認済
コマンドラインで テキストファイルを PDF に変換

テキストファイルをPDFに変換する方法です。
Ubuntu 25.04 で確認しました。

必要なコマンドのインストール

```bash
sudo apt install nkf
sudo apt install e2ps
sudo apt install ghostscript
```

入力ファイル: UTF-8 で書かれた file_a.txt
出力ファイル: file_a.pdf

```bash
nkf -e file_a.txt > file_a_euc.txt
#
e2ps -p -nh file_a_euc.txt | ps2pdfwr - > file_a.pdf
```

一旦、EUC_JP に変換しています。

## 確認したバージョン

```text
$ nkf --version
Network Kanji Filter Version 2.1.5 (2018-12-15) 
Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).
Copyright (C) 1996-2018, The nkf Project.

$ e2ps --version
e2ps's version is 4.34 (08/21/2002).
```
チームでWeb開発を行う際に決めておきたいことまとめ

# はじめに
チームで `Web` 開発を始める際に決めておいた方が良いものを自分用にまとめています。
気付きがあり次第、追加・修正していきます。
もしこういうのあった方がいいよとかこれは違うくない？ってのがあればコメントお願いします。

## ライブラリ
  - `UI`ライブラリ
      - `React.js` ?
      - `Vue.js` ?
      - `AngularJS` ?
      - `Flutter` ?
      - `etc...`
  - テストライブラリ
      - `Jest` ?
      - `Cypress` ?
      - `Mocha` ?
      - `etc...`

  - 状態管理ライブラリ (ex, `React.js`)
      - `Redux` ?
      - `ContextAPI` ?
      - `mobx` ?
      - `Recoil` ?
      - `etc...`


## 命名規則
  - フォルダ名、ファイル名
  - イベントハンドラー名
  - コンポーネント名
  - クラス名
  - 型定義 (`TypeScript`)
      - `ViewModel` ?
      - `Model` ?
      - `Entity` ?
      - `Props` ?

命名の揺れをなくす


## テスト
  - `Unit Test`
  - `Integration Test`
  - `E2E Test`

どこまでやって何を担保するか？


## 設計
  - ディレクトリ構造
  - ソフトウェア設計
      - `Onion Architecture` ?
      - `Clean Architecture` ?
      - `DDD` ?
      - `TDD` ?
      - `etc...`
  - コンポーネント設計
      - `Atomic Design`
      - 共通化の認識
  - `CSS`設計
      - `BEM` ?
      - `FLOCSS` ?
      - `OOCSS` ?
      - `etc...`
  - `CSS`管理
      - `Sass` ?
      - `CSS in JS` ?
      - `CSS Module` ?
  - `API`設計
      - `REST API` ?
      - `GraphQL` ?
  - インフラ設計
      - モノリシック ?
      - マイクロサービス ?
      - サーバーレス ？
      - etc...


## ソースコード管理
- `Git` ? `SVN` ?
- ブランチフロー
  - `Git-flow` ?
  - `GitHub-flow` ?
  - `Git feature flow` ?
- コミット規約
  - `Prefix` ?
  - `Issue`番号の付与等
- `Linter` の有無


## タスク管理
- `GitHub issue` ?
- `Backlog` ?
- `Redmine` ?
- `etc...`


## 共有すべきこと
- メンバーの技術スタック
- メンバーのやりたいこと・やりたくないこと
app/v1になってからのdeployment.yamlの書き方のサンプル


- `selector`が必須になったと思う

```nginx-deployment.yaml
apiVersion: apps/v1                                                                               
kind: Deployment
metadata:
  name: deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
```


```centos-deployemnt.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: centos
  template:
    metadata:
      labels:
        app: centos
    spec:
      containers:
        - name: centos
          image: centos:latest
          tty: true
```
PHPで少し捻った問題を解く。

例えば、ループ処理で,
1から10までを順番に並べるという事は、誰でも出来ると思う。

```index.php
for($i=1; $i<=10; $i++){
echo $i."\n";
}

/*
1
2
3
4
5
6
7
8
9
10
*/
```
これは、問題なかろう。
ただし、１０以降の数字を一の位だけで、表示しろと言われたら、分からなくなってしまう方も
いらっしゃると思う。ちなみにメソッドや既存の関数は使用しないという前提条件があるとする。


```index.php
<?php
//$n(数値)の個数をカウントする
for($i = 0; $i < 10; $i++){
$n = (int)trim(fgets(STDIN));
if($n >10){
$answer = $n - 10;
echo $answer."\n";
}else{
echo $n."\n";
}
}
?>

```
この問題を解くのに、2時間は当時要したが、問題が解けた時に、とても感動を覚えた。まずは、10より大きくなった場合と、そうで無い場合の２パターンを条件分岐で考える。ifとelseifがここで頭にパッと思い浮かぶ訳である。さらに、nが10より大きい場合は、nから10を引いた数字をanswerにいれて、それを表示させてやる必要がある。
反対に、nが10より小さい場合は、そのまま値を出力してあげればいいので、上のようなコードに仕上がった。

まとめ
---
プログラミングとは、論理的思考が求められる。このロジカルシンキングを大事にして、プログラミングを通して鍛えていきたい。まだまだひよっ子だけども、エンジニアになりたい。


誰かの参考になれば、嬉しいです。アディオス！
numpy.arrayで連続してTrueであるものを探す

よくあるアレですがせっかく書いたんでコードをメモしておきます

## やりたいこと

numpy.arrayについてN回連続してTrueのところだけ残します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/1f00fc53-a740-76d4-0aa3-abddf8d55643.png)

## やり方

1つずらしてandすることで2つ連続している起点を見つけ、1つずらしてorすることで終点までTrueで埋めます。

andの部分を2回やると3つ連続した起点、3回やると4つ連続した起点が見つけられますので、これを再起で書いてやれば任意の回数連続した部分を見つけられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/401a3548-9f88-e571-c319-d0e1e708902f.png)


## 1. 行列を準備

```python:python
import numpy as np
arr = np.array([[True,  False, False, True,  False, False, False],
                [False, False, True,  True,  True,  True,  False],
                [False, True,  True,  False, True,  False, True ],
                [False, False, False, False, True,  True,  False],
                [True,  True,  False, False, False, False, False]])
arr
```
## 2. 連続しているところだけ残す

```python:python
def is_continuous(arr, left_cnt):
    if left_cnt >= 1:
        arr2 = arr[:, :-1] & arr[:, 1:]
        arr2 = is_continuous(arr2, left_cnt - 1)
    else:
        arr2 = arr
    return arr2

def check_continuous(arr, continuous_cnt):
    arr2 = is_continuous(arr, continuous_cnt - 1)
    arr3 = np.tile(np.full(continuous_cnt - 1, False), arr2.shape[0]).reshape(-1, arr2.shape[0]).T
    arr2 = np.hstack([arr2, arr3])
    for _ in range(continuous_cnt - 1):
        arr2[:, 1:] = arr2[:, 1:] | arr2[:, :-1]
    return arr2

print(arr)
check_continuous(arr, 2)
```

これで以下のような出力が得られるはずです
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/2f3584c4-b6fd-7b05-6400-f0c5e3766102.png" width=80%>
Windows10でUSキーボードとJISキーボードを共存させる方法（2020）

#これはプログラミングの話ではない

**そもそもUSキーボードのノートが欲しかった**

途端に選択肢が狭くなり、仕方なくJISキーボードのノートを購入
Macならこんなことはない

外付けキーボードを購入（もちろんUS）、付けてみるが当然JISレイアウト

ググってみると案の定、数多くの記事が見つかり、レジストリ操作を試してみた

うまくいかない

さらに記事をみると、２０１９年くらいにレジストリ方式は潰された様だ

その中で、

[英語言語を追加し、Windows＋Spaceキーで切り替える](https://enjoypclife.net/2016/10/17/windows-10-us-keyboard-layout-japan-tips/)

というものがあった。
つまり、
**USキーボードを使う場合は、英語言語に**
**JISキーボードを使う場合は日本語言語に**
設定すれば良い、ということである。

正直、レジストリ操作に比べて容易だし、そもそもそんなにキーボードを入れ替えない
（外出するときくらいである）

早速この方法を試したところ、想定通りの動作になった。これで安心して家ではUSキーボードが使える

そもそもなんでUSキーボードなのよ、ってのもあるんだけどね。

問題発覚

当たり前だが英語言語だと日本語はいらないじゃん。。。
英語モードで日本語入れられないんだっけか。
むかしのWindowsは英語版Windowsで入力だけマルチとかできたんだが。。。
There is no security.output_filter defined in your application config file

## 背景

サクっとwebサイト立ち上げたかったので、php5.4(centos7のデフォルト)をインストールして、fuelPHPで作成。
fuelPHPを選択したのは、他のプロジェクトで使用していたため。

## There is no security.output_filter defined in your application config file

fuelPHPのエラー
エラーメッセージをマルっとググれば解決できだろうと思ったら2時間ハマる
どのサイトも解決に至らなかったため、ここに記載する

## 解決策

### php.ini の修正

```php:php.ini

< memory_limit = 3072M
---
> memory_limit = 128M

```

他にもいくつか直しましたが、関係ある項目に絞りました。


## その他の解決策

### config.php の記述が間違ってる

APPPATH/config/config.php の カッコが閉じてない、ダブルクォーテーションで囲んでいないなど。
コピーしたので、ありえないと思いつつ確認したら、
やっぱり合ってた

### SELinux がEnableになっている

いつもDisableにしてるので、ありえないと思いつつ確認したら、
やっぱり合ってた

```linux:linux_command
$ getenforce
Disabled
```

### フォルダのパーミッション誤り

あるサイトに「適切なディレクトリにパーミッションを与えましょう」と書いてあり、777を設定していたので、ありえないと思いつつ設定したら、
やっぱり動かなかった

パーミッションは下記の設定に戻しました

```linux:linux_command
chown apache. -R
find ./ -type d -exec chmod 755 {} \;
find ./ -type f -exec chmod 644 {} \;
```


## あとがき

![あせりすぎた](https://ctrlzr.sakura.ne.jp/img/ameblo/aseru.gif)

#### サクっと立ち上げたいために、あせりすぎた・・・ 
#### 解決策は昼休入れたあとピンときました
Power Apps, Azure SQL, Power BI で スマホバーコードスキャン 在庫管理 WMS システムを半日で構築してみた

#在庫の入と出を管理しなければならないことに・・・

紙とExcelをやめて少し現代的にしたいと依頼があった。
あまりお金をかけずにWMSもどきのシステムを構築した事例。
初期投資不要、月額数千円レベルで構築できた。

データ入力：Power Apps（シングルユーザー、カタログ価格￥1,090/月）
データ格納場所： Azure SQL（ストレージ2GB、東南アジアリージョン、カタログ価格￥549/月のBasic DTUで）
データ出力：Power BI（シングルユーザー、カタログ価格￥1,090/月）

データをSQLに溜め込んでPower BIでプラスマイナスをさまったレポートを出力。計カタログ価格￥2,729/月(税抜)なり。

#Power Appsのスマホアプリでバーコードは何がスキャンできるのか？　AndroidやiOSで・・・

![BarcodeType.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/9e6019fa-324c-7772-97e6-d3a774cfe9a8.png)

Auto ・・・ 自動、通常はこちらで問題ないはずだが誤認識を避けるために以下の読み込みフォーマットの指定もできる
Aztec
Codabar
Code 128
Code 39
Code 93
Data Matrix
EAN
Interleaved 2 of 5
Pdf 417　・・・　航空券で見かける仕様
QR Code　
RSS 14
RSS Expanded
UPC

今回はQR Codeを利用している

#利用者IDや在庫管理のバーコードをスキャンするボタンを配置
![InventoryRecordSystem1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/a19c2978-2b76-196f-a0d8-ec7a47441bdb.png)

#QRコードに文字セパレーターを入れ込み（縦棒）各フィールドにデータをばらした
![InventoryRecordSystem2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/b1967b09-fdd8-f531-af22-07c41f8e38dc.png)

#ある文字列の場合はプラスとカウント、ある場合はマイナスとカウントして合計

Power BIでサマルときに"+ Warehouse IN"という記録ではプラス、"- Warehouse OUT"という記録ではマイナスの受け払いとして集計するよう集計用の列を定義
![Warehouse In Out Quantity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/9b807dcd-30e7-72af-c068-7eb13ca199e4.png)

#感想

バーコードスキャンしてデータ格納しレポート出力まで半日程度でできました。初期投資不要、月額3,000円程度の使用料でアドホックなシステムが開発できるのは大きいです。特にスマホでバーコードスキャンができるのはうれしい。安価なAndroidスマホを工場生産ラインに投入し情報記録でどしどし使う予定です。状況可視化とペーパーレスが直ぐにできた事例でした。CDS(Common Data Service) を使うか悩みましたがAzure SQL Database が安価に使えることがわかったので(第三者による)保守運用性を考えるとCDSではなくAzure SQLの方が良い気がしました。普通のSQLで出し入れできますし拡張が容易ですので・・・
3分で簡単ニュースフィードをIFTTTとSlackで作ってみた

#Twitterで検索するのがめんどい
Twitterって情報が豊富にあるから検索で便利ですよね。
僕はストリートピアノが好きで、ピアノ情報をTwitterから拾うことがあるんですが、__Twitter開く⇒検索する⇒情報選抜__のフローが少しめんどくさく感じてきました。

この辺自動化しようとすると、Twitter APIを使う必要があり正直すごい面倒。
そこでIFTTT先輩のthisを使えばラクラクTwitterが使えるということで、ちょっとハンズオンしてみました。
UIはSlackを使いましたﾍﾞﾝﾘｨｨｨ

#完成デモ
検索で「画像付きで"ストリートピアノ""設置"が本文中にあるツイート」を送るようにしました。
最初は「画像付きで"ストリートピアノ"が本文中にあるツイート」にしていたんですが、あつまれどうぶつの森のレシピにもストリートピアノがあり、そのツイートも拾ってしまい通知が鳴りやまなくなってしまいました。
この辺はやってみて都度都度という感じですな
<img width="600" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666990/ad0293d1-a782-6a8f-b741-7a78afded0cc.png">


#実装こまごま
##IFTTTのアプレット
実装するというかもう設定するだけでﾗｸﾗｸｩ
filter:imagesのお作法は結構便利そうです。
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666990/f45ba11d-550d-5fe7-c438-f029ae216def.png">

送る情報の中身はこちら。


Tweet情報何々取れるんかなと思い、見てみるとこんな感じ。
UserImageUrlとかなんかに使えそう。
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666990/ac2afd09-1e98-9b5a-3e2b-386ceafaee35.png">


#おわりに
IFTTT有料化ということで衝撃が走っていますが、そのほかのものについても色々触ってみたい。
Integromatなどのとの比較は[こちらが優秀そう](https://qiita.com/mnr68/items/f7a2cc352c02af3882a5)。
色々使ってみたいですね。

最後までご覧いただきありがとうございます！
LGTMつけていただけると励みになります、よろしくお願いします！
macのfishでjupyternotebookが起動しない

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# 症状

anaconda3をosx(catalina)に入れて，AnacondaーNavigator.appからjupyter notebookをlaunchしたところ，terminalで以下のようなerrorが出て死にました．

    $ /****/****/anaconda3/bin/jupyter_mac.command ; exit;
    Failed to execute process '/****/****/anaconda3/bin/jupyter_mac.command'. Reason:
    exec: Exec format error
    The file '/****/****/anaconda3/bin/jupyter_mac.command' is marked as an executable 
    but could not be run by the operating system.


# 解決法

terminalのdefault shellをfishにしたためです．jupyter\_mac.commandの先頭に以下のshebang

    #!/bin/bash

を追加して解決しました．

zshでも多分同じ(未検証).

-   [ContinuumIO/anaconda-issues jupyter\_mac.command is not executable with fish. #8222](https://github.com/ContinuumIO/anaconda-issues/issues/8222)



------
 - **source** ~/Desktop/lecture_20f/math_python/jupyter_notebook_on_fish.org
【MySQL】テーブルロックが発生するか確認する方法

# tldl;
- EXPLAIN SELECTして`type=ALL`ならテーブルロックが発生します！

# update

例えばこういうupdateSQLのときに

```sql
UPDATE users
SET field2    = CONCAT(field1, field2),
    field1     = NULL,
    updated_at = NOW()
WHERE field1 IS NOT NULL
  AND field1 != '';
```

`EXPLAIN SELECT`で実行してみてください

```sql
EXPLAIN SELECT * from users WHERE field1 IS NOT NULL
  AND field1 != '';
```

すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/7cc37409-de89-8d87-0fac-e6ea08af3264.png)

typeがSELECTされるので、`ALL`になっていたらフルスキャン＝テーブルロックが発生します！

## Ref

- https://doruby.jp/users/abennu/entries/Mysql_InnoDB_
- http://bluerabbit.hatenablog.com/entry/2013/12/07/075759
PHPでインデックス処理問題解いたので、コード晒す。

Paiza CランクレベルアップメニューPHP『forループ』編　STEP3：index取得　を解いてみました！
---
*こちらはスキルチェック問題では御座いませんので、コード公開は、問題にならないそうです。

問題文は、今回は省略します。解答コードのみ晒します。

入力値は、
4

3
4
3
3
3
と設定してます。

```index.php
<?php
$num = trim(fgets(STDIN));
for($i=1; $i<=$num; $i++){ // 1からの番号を添え字にする
$a = trim(fgets(STDIN));
$list[$i] = $a;
}
$k = trim(fgets(STDIN));

// 検索処理
foreach ($list as $key => $value) {
if ($value !== $k) {
continue;
/*$value == $kの場合、$keyを取得して、
それ以降は、breakしてしまう */
echo $key;
break;
}
}

?>
```
今回の問題は、continueとbreak、foreachが理解できていれば、解けると思いますが、
個人的にDランクでは無いと思っています笑

paizaサイトはこちら(https://paiza.jp/)
【Docker】コンテナの起動、コンテナ内で bash を起動、イメージを削除


#はじめに

ターミナルでコンテナ内に入り、コマンドを試したいときの流れについて改めてまとめた。

#流れ
##docker build

```shell
docker build -t test .
```


`docker build`: Dockerfileを基に、Dockerコンテナーの起動、構成、Dockerイメージの作成まで一気に実行

`-t test`: -tオプションで任意のイメージ名をつける

` . `: 最後についているピリオドは、Dockerfileのあるディレクトリを指定する為。ピリオドはカレントディレクトリを示す



##docker run

```shell
docker run --rm -it test bash
```

`--rm`： コンテナ実行後に削除
`-it`：　コンソールに結果を出力
`bash`：　bashを起動


##docker rmi

```shell
docker rmi test
```
でイメージを指定して削除





##参考にさせて頂いた記事
- 
[Docker-docs-ja](https://docs.docker.jp/engine/reference/commandline/rmi.html)

- [いまさら聞けないDocker入門（3）：
Dockerfileとdocker buildコマンドでDockerイメージの作成 (1/2)](https://www.atmarkit.co.jp/ait/articles/1407/08/news031.html)

##終わりに。
最後まで読んで頂きありがとうございます:bow_tone1:
転職の為、未経験の状態からReact,Railsを学習しております。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。
ありがとうございます！
【製造業】出張申請をデジタル化してみたpart1【GAS×フォーム×スプレッドシート】

# はじめに
初めての投稿になります。お手柔らかにお願いします。

Googleのアプリを使って出張申請ツールを作ってみたところ、瞬く間に部署内に広がりびっくりしました。
こうなるということは、多分いいツールなんだろうなぁと思いましたので、
皆さんにお披露目したいと思います。

ソースは次回、公開いたします。

※ここでいう出張申請とは、いつ、どこに、だれと行くというものを申請するものになります。
※注：旅費などの精算処理機能はありません。

#仕掛け
私がお世話になっている会社は130年の歴史があります。なので同じ年数だけ紙文化があります。
それは、ひぃおばあちゃんにスマホを勧めるような感じでした。
だから、「あら～いいわね～♪」とするためにある仕掛けが必要かと思いました。

##仕掛け1:簡単なお試し番を作ろう！
今までの仕事内容を変えるには、相当なエネルギーと不安があるかと思われます。本当にちゃんと使えるか、動作するか、運用出来るかなど、考えちゃうはずてす。

なのでまずは、Googleフォームを使ってエスカレーション用ツールを作成し、上位者へメールを飛ばすフローを作成しました。

このツールで操作に慣れて貰いました。使う機会もあまりないけど、あったら便利みたいな。
気軽に使えるからいいね！って感じになりました。

##仕掛け2:デジタル化したい人にデータを見せる
ここからがちょっとしたポイントです。
グラフやデータの結果を興味がある人に見せます。すると、もっとこういうのと組み合わせたり、このデータが欲しいといった要望が出てきます。

そこで、昨今のコロナ対策として出張申請が出てきました！

##仕掛け3:さっさと作ってお披露目
こうなれば、要望した人がその気持ちになってる間に作ることが出来ると勝ちです！
そこで、Googleのアプリを使ってGASで繋げるだけといったシンプルな方法を考えました。




# 構成
（構成図の書き方ってこんな感じでいいと＞＜？
![図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546465/1103a8fd-b496-379e-b5a0-083a9d65fb07.png)



簡単に解説すると・・・

１．Googleフォームに出張内容と承認依頼先（名前）を選択して送信！

２．承認依頼先のメールアドレスをスプレッドシートの情報から取得し依頼先へメールを送信。
※申請者には別途、申請が実行されたメールが飛びます。

３．承認者はメールに記載されているフォームの編集用URLからアクセスして、選択欄を承認に変更。

--承認フローが終わるまで繰り返し

４．承認フローが終わると、承認完了メールが送信される。

#ツール作成
GAS（GoogleAppsScriot）を使って作成しました。
（感激ポイント：フォームが送信されたイベントを受け取ったりできるなんて！
比較的短期間で構想と実装をしてテストを行いました。

#いよいよ紹介へ！
同調圧力を掛けたかったのですが、その日、まさかの1番のエバンジェリストが出張！
案の定、たくさんのご意見や議論があり、
しぶしぶ使うことになったという形でした。

#ITの魔法
ただ、ここまでは予想通り。（震え声）
ITは仕事に取り入れて、日々使ってこそ力を発揮すると実感しました。
しぶしぶ了解した人たちから出た言葉は、
「明日から使いたい」でした。

#終わりに
拙い構成、文章のなか、ご覧いただきありがとうございます。
ご察しの通り、これからIT化していくところがたくさんありますが、
逆に考えるとレガシーシステムがないところが強みかなと感じます。
LGTMなどしていただけると励みになります！
【React】イベントとstate

Reactでカウントアップなどの機能を作る時は二つの記述をしていく。

１.イベントの設定
２.stateの設定

stateの設定は三段階に別れる。
stateの定義　→　stateの表示　→　stateの変更


```App.js
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 0};
  }
  
  // handleClickメソッドを定義してください
  handleClick(){
    this.setState({count: this.state.count + 1});
  }
  
  render() {
    return (
      <div>
        <h1>
          {this.state.count}
        </h1>
        {/* <button>タグ内でonClickイベントを追加してください */}
        <button onClick = {() => {this.handleClick()}}>+</button>
        
      </div>
    );
  }
}

export default App;
```

実際にブラウザに表示されるのはreturnの中身である。


この記事は備忘録です。
Cascade検出器のインストール方法と使ってみての感想

今回は顔検出に使うCascade検出器のインストール方法について紹介したいと思います。

# 実行環境
MacOS, Python3.6(anaconda), VSCode

# Cascade検出器のインストール手順

①[Githubのレポジトリ](https://github.com/opencv/opencv/tree/master/data/haarcascades)の中にある必要なCascadeファイルを選ぶ
②そのファイルを開き、Rawというところをクリック
③開いた画面で、右クリックをして、好きな場所に保存する

こういった手順になります。

今回参考にさせてもらった記事はこちらになります。
[Python, OpenCVで顔検出と瞳検出（顔認識、瞳認識）](https://note.nkmk.me/python-opencv-face-detection-haar-cascade/)

# 実装してみての感想

```python

xml_path_list = ["./haarcascade_frontalface_default.xml", 
               "./haarcascade_frontalface_alt.xml",
               "./haarcascade_frontalface_alt_tree.xml",
               "./haarcascade_frontalface_alt2.xml"]

```
今回は、この4つを使おうと思ったのですが、**"./haarcascade_frontalface_alt_tree.xml"**だけはファイルサイズが大きすぎてインストールできなかったので、残りの３つを使いました。

defaultが1番精度は良くなかったかなと思います。
altは顔じゃない部分までを余分に認識していることがあるという印象で、alt2は顔なのに認識していないことがあるという印象でした。

# 顔を四角で囲む方法
今回は顔を検出した場所を四角で囲むようにしたので、その方法も記載しておきます。

```python

if len(face_points) == 0:
    quit()
for x, y, width, height in face_points: # 顔領域の座標点取得
    color = (0, 0, 100)
    pen_w = 9
    cv2.rectangle(img, (x, y), (x+width, y+height), color, thickness = pen_w)
    cv2.imwrite('mosaic' + str(mosaic_num) + str(cnt) + '.jpg', img)    # 画像を保存 

```

まず、if文を使い、`detectMultiScale`で顔の検出ができているかを判定します。
できていなければ、そこで終わりです。

そして、四角で囲むコードはfor文の中にあります。
**cv2.rectangle**でどのような線で囲むかを指定します。

ちなみに、**colorとpen_w**は`四角の色と太さ`になります。

# まとめ
今回はCascade検出器のインストール方法について説明していきました。
自分で顔検出のコードを書かなくても自動で検出してくれるので便利ですよね。
自分も初めての実装ではこちらを使わせてもらいました。

さらに、四角で囲むという実装もできました。これで顔がきちんと検出できているのかを一目で判断できるので便利ですね。
画像処理は実行したらすぐにその結果を見れるので楽しいなと感じました。
netstat

（よく忘れるのでメモ）
ポートの使用状況を確認する。

```
# netstat -na
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address               Foreign Address             State
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN
tcp        0      0 172.xxx.xxx.xxx:22          xxx.xxx.xx.xxx:50533        ESTABLISHED
```

##「State」の意味について
ESTABLISHED・・・接続が確立したソケット
SYN_SENT・・・接続を試みているソケット
SYN_RECV・・・接続要求を受信しているソケット
FIN_WAIT1・・・切断中のソケット
FIN_WAIT2・・・リモートからの切断を待っているソケット
TIME_WAIT・・・リモートからの切断が再送されるのを待っているソケット
CLOSED・・・未使用なソケット
CLOSE_WAIT・・・リモート側から切断され，ソケットがクローズされるのを待っているソケット
LAST_ACK・・・すでに切断されており，ソケットもクローズされているソケット
CLOSING・・・ソケットが切断されているか，すべてのデータが転送されていないソケット
UNKNOWN・・・状態が不明なソケット

（参考）
[【 netstat 】 ネットワーク関連の統計情報を表示する](https://xtech.nikkei.com/it/article/COLUMN/20060227/230845/)

## ルーティングテーブルを確認
-n をつけると、ホスト名を名前解決せず、IPアドレスのままで表示する。
Destination が宛先に指定されている場合に Gateway に向かって転送する。

```
# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         172.31.0.1      0.0.0.0         UG        0 0          0 eth0
169.254.169.254 0.0.0.0         255.255.255.255 UH        0 0          0 eth0
172.31.0.0      0.0.0.0         255.255.240.0   U         0 0          0 eth0
```

-r のみだと、ホスト名を名前解決して表示させる。

```
# netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
default         ip-172-31-0-1.a 0.0.0.0         UG        0 0          0 eth0
instance-data.a *               255.255.255.255 UH        0 0          0 eth0
172.31.0.0      *               255.255.240.0   U         0 0          0 eth0
```

## netstatで出てきたIPアドレスをカウントする
ステータスがLAST_ACKなIPアドレスだけ抽出したい。

```
LAST_ACKとなっている部分だけ抽出
$ netstat -na | grep LAST > mmm.txt

IPアドレス部分だけ抽出
$ cat mmm | awk '{print $5}' > mmm1.txt

ポート番号だけ消しつつ、数のカウントもする
$ cut -d . -f1,2,3,4 mmm1.txt | sort | uniq -c

      2 xxx.52.93.136
      2 xxx.55.186.49
      2 xxx.55.47.205
      4 xxx.55.92.135
      →こんな風に出る
```
アップグレードされたデータポータルの日付・日時型は、nullが含まれるデータには適用できない

# 問題
データポータルに新しく追加された日付・日時型は`null`が含まれるデータには適用できない！
困る！
旧日付・日時型なら`null`が含まれててもOKだったから、それを使おう！
…と思ったけど、型選択欄に旧日付・日時型がない！

どうしよう…

# 解決策
1. 旧日付・日時型に設定したいフィールドを、テキスト型に設定しておく。
2. レポート作成かなんかで、そのフィールドがテキスト型でどんなフォーマットになるか確認する。  
（ここでは`%Y%m%d`とします）
3. [TODATE関数](https://support.google.com/datastudio/answer/7037300)で**無理くり旧日付型に変換！**

```
TODATE(旧型にしたい日付フィールド,"%Y%m%d","%Y-%m-%d")
```

# 経緯
2020/9/17にGoogleデータポータルの日付と時刻の関数が新しく改善されました。
（TODAY関数がやっと追加されました。ヤッター）
加えて、これら新しい関数に対応するために新しい日付・日時型が追加されました。
そして、**旧日付・日時型を設定できなくなりました**。

この新機能が追加される以前から旧日付・日時型を設定しているフィールドは、そのまま旧型で使えます。
しかし、型を新日付・日時型に設定してしまうと旧型に戻せません。[^1]
加えて、新しいフィールドを作成した時も旧型に設定できません。

公式ヘルプだと、新型を使うのをオススメされてますし、大人しく新型にアップグレードするしかなさそう。
と思って、アップグレードしようとしたら…

新日付・日時型を選択できない！！

しかし、新日付・日時型をちゃんと設定できるフィールドもありました。
新日付・日時型を選択できないフィールドとの違いを探った所、
データ内の`null`の有無でした。

`null`が含まれていると新日付・日時型を選択できないようです。
(＊月型とか、日型とか、四半期型とかは選択できました。でも意図したものではない)

旧日付・日時型なら`null`が含まれてても適用できました。
でも、もう旧型は新たに設定できません。
**新しく追加した日付フィールドをなんとかして日付型に設定したいのに…**

でも、とりあえず上記の[解決策](#解決策)で`null`が含まれる日付フィールドもデータポータルで扱えるようになりました。
もっと良い方法あるよ！元のデータのフォーマットがこうだと新型も使えるよ！、なんて知ってる方がいたら教えて下さい。

参考: [新機能 - データポータルのヘルプ](https://support.google.com/datastudio/answer/6311467?hl=ja)
[^1]: データソースのバージョン履歴から、一応は元に戻せます。
NginxとRoute53を使ってドメインでアプリを表示させる

# 問題
アプリを本番環境にデプロイし終えたところ。
Elastic IPアドレスではブラウザにアプリが表示されるが、ドメインでは表示されない。

![スクリーンショット 2020-10-01 午後1.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/a2e65d09-aa29-53f9-d570-65d1deebd6d5.png)

# 解決法

vimでNginxの設定ファイルを開いて


```
// pfc-masterはアプリ名です

[naota@ip-10-0-0-32 ~]$ cd /etc/nginx/conf.d/
[naota@ip-10-0-0-32 conf.d]$ sudo vi pfc-master.conf    
```

```:アプリ名.conf
//before 
server_name Elastic IPアドレス;
　↓　
//after
server_name ドメイン名;
```

Nginxの設定ファイル`アプリ名.conf`の`server_name`をElastic IPアドレスからドメイン名に変更する。

その後Nginxをreloadして設定の変更を反映させる。

```
sudo nginx -s reload
```

# 参考記事
- [AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得](https://www.udemy.com/course/aws-and-infra/)
- [【超初心者向け】AWSでたてたnginxサーバーにドメインを設定する](https://qiita.com/ryuchan00/items/3e172fbfd1044e093c52)
docker-composeでPostgreSQL作成時の注意

docker-composeでPostgreSQLを作ろうとした時に、以下のエラーが出た場合の対策

> 元ネタ
> https://stackoverflow.com/questions/51168558/how-to-mount-a-postgresql-volume-using-aws-ebs-in-kubernete

```log
postgres-db | initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
postgres-db | It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.
postgres-db | Using a mount point directly as the data directory is not recommended.
postgres-db | Create a subdirectory under the mount point.
postgres-db exited with code 1
```

`/var/lib/postgresql/data`にデータを作成しようとして失敗しています。

解決策は、環境変数`PGDATA`を指定するとデータベースの本体の保存場所を指定できるので、これをデフォルトの`/var/lib/postgresql/data`から`/var/lib/postgresql/data/pgdata`（pgdataは他の名前で可）のように１層深くすることで解決できる可能性があります。

次の例の、`volumes / postgres_root` でコンテナの`/var/lib/postgresql/data`をマウントさせて、　`environment / PGDATA` で、 `/var/lib/postgresql/data/pgdata` で一層深い場所にデータを作成します。。

20-10-23修正

volumes:postgres_root:driver_opts:type: noneはMacとwindowsではうまくいかないっぽいので、修正

```yaml
version: '3'
services:
  postgres:
    image: postgres:12.2
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 'pass'
      POSTGRES_DB: 'pg'
      PGDATA: /var/lib/postgresql/data/pgdata
    ports:
      - 5432:5432
    container_name: postgres-db
    volumes:
      - ./db/postgres:/var/lib/postgresql/data
      - ./db/logs:/var/log
```
[PowerAutomate]スケジュール実行が指定時間通りに起動しない場合（タイムゾーンが機能しない場合）

## どんな時に？

以下の様に毎月実行する様にスケジュールを指定します。

![スクリーンショット01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145504/43b0fe73-506b-39ee-1e69-e8d0a8a53021.png)


タイムゾーンを日本に設定しているので普通に考えると、
「**（日本時間で）毎月１日のAM3:00**」に実行されると思いますよね。

### 実際のところ

上記で設定した場合、「**（日本時間で）毎月１日のAM12:00**」に実行されます。
**9時間ずれます。**

察しの良い方はわかったかと思います。
「タイムゾーンが効いてない？」

## 対処方法

対処方法というより、実は入力が間違っていました。
正しくは以下の通りです。

![スクリーンショット02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145504/305f5233-923a-f648-1c31-e22dd5cd1d59.png)

違いに気づきましたか？
開始時刻が「2020-10-01T03:00:00.000<font color="red">Z</font>」から「2020-10-01T03:00:00.000」に変わっています。

この日付フォーマットの末尾「Z」はUTC時間であることを表しています。
https://support.microsoft.com/ja-jp/help/4557244/converting-time-zone-in-microsoft-power-automate
（注意事項の欄）

## まとめ

指定した開始時刻をタイムゾーンで強制的に解釈して実行してくれると思ってましたが、実際は時刻内に指定（末尾Z）がある場合は解釈しないということでした。
罠みたいな現象ですよね。

ちなみに「毎週」「毎日」実行の場合は、「設定時刻（時間）」「設定時刻（分）」と起動する時間を個別に指定できる様になっています。
「毎月」の場合も同じだったらこんなミスしないと思うんですけどね・・・
KubernetesのStorageClassとは

# StorageClass
- 永続ストレージを動的プロビジョニングをするために必要
- ストレージのタイプと構成を定義する
- pv、pvcを利用する場合、その先にStorageClassがあり、必要になる


## デフォルトで定義されているStorageClass
- EKS ver1.7

```
yuta:~ $ kubectl get storageclass gp2
NAME            PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
gp2 (default)   kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  9d
```


## EBSを展開するためのStorageClass

```
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: app-ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
```
centos8にwine5系をインストールできるrepositoryの登録

# 動機

ついこないだ自宅鯖のOSドライブにセクターエラーが出始めたので、これを機会にSSDに入れ替え
ついでにOSもcentos7から8へ入れ替える。快適。
wineも入れようと思ったがepel repositoryにあるものは4.0xなので
5.x系をインストール出来るrepoがないものかと検索(ソースコンパイルは最終手段に置いておく性分)。

CentOS 8 - Raven Extras x86_64 https://centos.pkgs.org/8/raven-extras-x86_64/

お、5.14系のrpmが存在するじゃないですか。Raven Extrasのrepoを探そう

Репозитории пакетов для el8 - Форум системных администраторов
https://sysadmins.ws/viewtopic.php?f=96&t=22598

ロシア語です。
ので日本語でざっとまとめる。

# repositoryの登録

```
vi /etc/yum.repos.d/raven.repo
```
で以下の内容をペーストする

```
[raven]
name=Raven packages
baseurl=https://pkgs.dyn.su/el8/base/x86_64/
gpgcheck=0
enabled=1 

[raven-extras]
name=Raven extra packages
baseurl=https://pkgs.dyn.su/el8/extras/x86_64/
gpgcheck=0
enabled=0

[raven-multimedia]
name=Raven multimedia packages
baseurl=https://pkgs.dyn.su/el8/multimedia/x86_64/
gpgcheck=0
enabled=0

```

"extras と multimedia の両方をenabledにするとコンフリクトするのでデフォルトではオフにしといてね"とのこと。

# バージョン確認

```
dnf info wine
```

すると

```
メタデータの期限切れの最終確認: 0:20:57 時間前の 2020年10月01日 13時31分47秒 に実施しました。
インストール済みパッケージ
名前         : wine
バージョン   : 5.14
リリース     : 1.el8.8_2
Arch         : i686
サイズ       : 0.0  
ソース       : wine-5.14-1.el8.8_2.src.rpm
リポジトリー : @System
repo から    : raven-extras
概要         : A compatibility layer for windows applications
URL          : https://www.winehq.org/
ライセンス   : LGPLv2+
説明         : Wine as a compatibility layer for UNIX to run Windows applications. This
             : package includes a program loader, which allows unmodified Windows
             : 3.x/9x/NT binaries to run on x86 and x86_64 Unixes. Wine can use native system
             : .dll files if they are available.
             : 
             : In Fedora wine is a meta-package which will install everything needed for wine
             : to work smoothly. Smaller setups can be achieved by installing some of the
             : wine-* sub packages.

名前         : wine
バージョン   : 5.14
リリース     : 1.el8.8_2
Arch         : x86_64
サイズ       : 0.0  
ソース       : wine-5.14-1.el8.8_2.src.rpm
リポジトリー : @System
repo から    : raven-extras
概要         : A compatibility layer for windows applications
URL          : https://www.winehq.org/
ライセンス   : LGPLv2+
説明         : Wine as a compatibility layer for UNIX to run Windows applications. This
             : package includes a program loader, which allows unmodified Windows
             : 3.x/9x/NT binaries to run on x86 and x86_64 Unixes. Wine can use native system
             : .dll files if they are available.
             : 
             : In Fedora wine is a meta-package which will install everything needed for wine
             : to work smoothly. Smaller setups can be achieved by installing some of the
             : wine-* sub packages.

```

# インストール

```
dnf --enablerepo=epel-testing,raven-extras,raven-multimedia install  wine.i686 wine-core.i686 wine-pulseaudio.i686 wine-capi.i686 wine-cms.i686 wine-ldap.i686 wine-openal.i686 wine wine-core wine-pulseaudio wine-capi wine-cms wine-ldap wine-openal
```

以上。
ac-library-rb で解く AtCoder UnionFind(DSU)

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

# 今回のお題
*[AtCoder Beginner Contest C - Connect Cities](https://atcoder.jp/contests/abl/tasks/abl_c)*
<font color="gray">Difficulty: 363</font>

*[AtCoder Beginner Contest D - Friends](https://atcoder.jp/contests/abc177/tasks/abc177_d)*
<font color="brown">Difficulty: 676</font>

今回のテーマ、UnionFind

*[ac-library-rb](https://github.com/universato/ac-library-rb)* は、AtCoder Library (ACL)のRuby版です。

今回はその中の`UnionFind(DSU)`を使用しています。
# C - Connect Cities
```ruby.rb
  
# Disjoint Set Union
class DSU
  def initialize(n = 0)
    # root node: -1 * component size
    # otherwise: parent
    @parent_or_size = Array.new(n, -1)
  end

  def merge(a, b)
    x = leader(a)
    y = leader(b)
    return x if x == y

    x, y = y, x if -@parent_or_size[x] < -@parent_or_size[y]
    @parent_or_size[x] += @parent_or_size[y]
    @parent_or_size[y] = x
    x
  end
  alias unite merge

  def same(a, b)
    leader(a) == leader(b)
  end
  alias same? same

  def leader(a)
    @parent_or_size[a] < 0 ? a : (@parent_or_size[a] = leader(@parent_or_size[a]))
  end
  alias root leader
  alias find leader

  def size(a)
    -@parent_or_size[leader(a)]
  end

  def groups_with_leader
    h = Hash.new { |hash, key| hash[key] = [] }
    @parent_or_size.size.times do |i|
      h[leader(i)] << i
    end
    h
  end

  def groups
    groups_with_leader.values
  end
end

n, m = gets.split.map(&:to_i)
u = DSU.new(n)

m.times do
  a, b = gets.split.map(&:to_i)
  u.merge(a - 1, b - 1)
end

puts u.groups.size - 1
```
# D - Friends
```ruby.rb
  
# Disjoint Set Union
class DSU
  def initialize(n = 0)
    # root node: -1 * component size
    # otherwise: parent
    @parent_or_size = Array.new(n, -1)
  end

  def merge(a, b)
    x = leader(a)
    y = leader(b)
    return x if x == y

    x, y = y, x if -@parent_or_size[x] < -@parent_or_size[y]
    @parent_or_size[x] += @parent_or_size[y]
    @parent_or_size[y] = x
    x
  end
  alias unite merge

  def same(a, b)
    leader(a) == leader(b)
  end
  alias same? same

  def leader(a)
    @parent_or_size[a] < 0 ? a : (@parent_or_size[a] = leader(@parent_or_size[a]))
  end
  alias root leader
  alias find leader

  def size(a)
    -@parent_or_size[leader(a)]
  end

  def groups_with_leader
    h = Hash.new { |hash, key| hash[key] = [] }
    @parent_or_size.size.times do |i|
      h[leader(i)] << i
    end
    h
  end

  def groups
    groups_with_leader.values
  end
end

n, m = gets.split.map(&:to_i)
u = DSU.new(n)

m.times do
  a, b = gets.split.map(&:to_i)
  u.merge(a - 1, b - 1)
end

puts u.groups.map { _1.size }.max
```
一番目のソースに比べ、最後の一行だけ修正しています。
# まとめ
+ UnionFind(DSU) を解いた
+ ACL に詳しくなった
+ Ruby に詳しくなった

参照したサイト
*[ac-library-rb - GitHub](https://github.com/universato/ac-library-rb)*
*[Ruby で解く AtCoder ACL Beginner Contest C UnionFind(DSU) - Qiita](https://qiita.com/superrino130/items/30cdfbb3beec361b599e)*
*[Ruby で解く AtCoder ABC177 D UnionFind - Qiita](https://qiita.com/superrino130/items/086c2f192cc741196680)*
GCSのキャッシュ

なんでかよくわからないけど、GCSに格納したファイルを更新してアクセスしてもキャッシュが残っているせいで更新されない！
no-cacheの設定しても反映されない！
AndroidアプリからGCSに格納したJSONを見たいのに反映されないなんて、困る！

そんな時は、パスの最後に`?uuid=適当な文字列`をつけたら更新される裏技を教えてもらったので、早速やってみると見事最新データが取得できましたよ:relaxed:

```
var path = getString(R.string.json_path) + "?uuid=" + getDate("yyyyMMddhhmmss")
```
Google Adwords API

未来の自分が忘れそうなので備忘録。

Google MCCアカウントが２つ以上ある際、１つのアプリケーションから同じディベロッパートークンを使用しAPIを叩く方法は２つある。

1. 親MCCアカウントに子MCCアカウント情報を紐づける。（ユーザーにメールアドレス追加）
2. 1の手法をとりたくない場合は、子MCCアカウントにてプロジェクトを作成し、親とは別のOAuth２ credentialを使用する。
kibanaで、3σ（3シグマ）を扱う


## 背景

kibanaで3σ（3シグマ,3sigma）のことを検索しても全く検索に引っかかってこないので
検索用として書きました。


## 結論

こんな形でできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/37b7c228-0d8d-f4a2-732f-ff15d873942b.png)


で、落ちなんですが、3sigmaでは検索されないんですが
普通にkibanaで「Standard Deviation（標準偏差）」は扱えるんですよね。

標準偏差と、68–95–99.7則、3シグマの関係は下記でも参照で。

[wiki 68–95–99.7則](
https://ja.wikipedia.org/wiki/68%E2%80%9395%E2%80%9399.7%E5%89%87#:~:text=%E6%AD%A3%E8%A6%8F%E5%88%86%E5%B8%83%E8%BF%91%E4%BC%BC%E3%81%AB%E3%81%8A%E3%81%84%E3%81%A6%E5%B9%B3%E5%9D%87,%E7%B4%84%2099.7%25%E3%81%8C%E5%90%AB%E3%81%BE%E3%82%8C%E3%82%8B%E3%80%82)

標準偏差と言われると、「データや確率変数の散らばり具合（ばらつき）」のほうだと思っており、1σとか、-1σがレンダリングされると思ってなかったので、はまってた感じです。

## やり方

では、詳細なやり方です。

何も意識せずに、「Standard Deviation」を指定しますと、1σと-1σがレンダリングされます。
（わかりやすくするために、averageの追加してます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/c256158e-a226-a321-815a-9cbf74a96bf8.png)

で、どうやって、2σと-2σ,3σと-3σを追加するかというと、
別途、「Standard Deviation」を追加し、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/ac63b3cd-d723-4cf8-7dbf-51293d580a1a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/095f153c-2fb5-5b95-2499-a50a20bc2f54.png)

とやるだけです。advanced -> json inputで、sigmaの設定が必要なのがポイントです。

## 感想

ということで、わかってしまえば非常に簡単な話ですが、 
「Standard Deviation」を指定しますと、1σと-1σがレンダリングされるっていうところになかなか気が付かなかった
（分散そのものなんか表示してどうするんだろ？ってずっと思ってました）
のが辛かったので記事化してみました。



## 参考
[elasticsarch 公式 Extended Stats Aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-extendedstats-aggregation.html)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/88790224-b51c-abc5-b91f-025c540cdfab.png)
Slackの通知音を「スポポポ」から変える方法

### Slackのデフォルトの通知音って、イライラしませんか？

デフォルトの通知音「スポポポ」に「うるせ〜〜〜」ってなったので通知音を変えたら少し心が穏やかになりました。

1. Slack開く
2. 右上のプロフィールアイコンをクリック
3. 「環境設定」をクリック
4. 「通知音」のところで通知音を変更。おすすめはPlink。

（デフォルトはKnock Bruch）

参考
-
[Slack デスクトップ通知ガイド](https://slack.com/intl/ja-jp/help/articles/201355156-Slack-%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E9%80%9A%E7%9F%A5%E3%82%AC%E3%82%A4%E3%83%89)
Vue.js~Vuex~JestでTest~

#はじめに
Vue.jsのメソッドのテストのみしています。
本当は描画部分もするべきなのでしょうが徐々にしていく予定です。
もし間違いがあったら教えていただけると嬉しいです。

#テスト対象

```javascript
export default {
  data() {
    return {
      age: 0,
    };
  },
  methods: {
    greeting(name) {
      return `Hello!!${name}`;
    },
    
    ageCheck() {
      if (this.age < 20) {
        return "20歳未満";
      } else {
        return "20歳以上";
      }
    },
  },
};
```

``name``を引数の取って挨拶を返す``greeting``メソッドと``age``に入った値をチェックして
条件分岐したのち値を返すメソッド

#テストコード

```javascript
import {createLocalVue, shallowMount} from '@vue/test-utils'
import test2 from '../test2.vue'

describe('test2.vueのテスト', () => {

 const wrapper =shallowMount(test2)//wrapperでコンポーネントをラップする
 const vm = wrapper.vm

  it('methods-greeting', () => {
    expect(vm.greeting("Jon")).toBe("Hello!!Jon")
  })
  it('methods-ageCheck', () => {//component内のdataを使ってる場合
    expect(vm.ageCheck()).toBe("20歳未満")//初期値は0になっている
    vm.age = 19//this.ageの部分に代入
    expect(vm.ageCheck()).toBe("20歳未満")
    vm.age = 20
    expect(vm.ageCheck()).toBe("20歳以上")    
  })
})
```

こんな感じでテストできます。
``wrapper.vm``とすることでラップしたコンポーネントにアクセスできる。
なので``wrapper.vm.greeting('Jon')``としたらコンポーネント内で``this.greeting('Jon')``
としているのと同じ様な感じになる。
``data``の``age``にアクセスする場合も``wrapper.vm.age``で値を入れたりできる。

#Vuexを使用してる場合

```javascript
import { createLocalVue, shallowMount } from '@vue/test-utils'
import Vuex from 'vuex'
import { state, mutations, actions, getters } from '@/store/index.js'//使用する部分だけでOK
import Component from '@components/Component.vue'

const localVue = createLocalVue()
localVue.use(Vuex)

describe('Componentのテスト', () => {
 
beforeEach(() => {
    store = new Vuex.Store({
      state,
      mutations,
      actions,
      getters
    })
    const wrapper = shallowMount(Component, { store, localVue })
    const vm = wrapper.vm
  })
  it('テスト', () => {
   //テスト項目
  })
})
```
##Vuex(store)

```javascript
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export const state = {}
export const mutations = {}
export const actions = {}
export const getters = {}

export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters
})
```
こんな感じになるのかなと
``store``の値とか``メソッド``を使う場合は``wrapper.vm.$store``とします。
仮に``state``に``name``という値があったとして何かする場合は
``wrapper.vm.$store.state.name``となります。
``getters``を使う場合``wrapper.vm.$store.getters.メソッド名(引数)``
になります。

以上です。
初期データを注入したDocker imageをdocker-composeで立ち上げる

```yaml:docker-compose.yml
version: "3.8"

services:
  DB:
    image: mysql ← ここに初期データ投入してくれるimageを書きたい
    environment: 
      MYSQL_ROOT_PASSWORD: パスワード
    ports: 
      - ポート
    ....
    ....
    ....
    ....

 ```


>image: mysql ← ここに初期データ投入済みのimageを書きたい

imageをDockerHubとかGithubPackagesに上げて
上記の方法でそのimageを指定さえしていれば、どの環境でもそのテストデータを使える。

そもそも初期データを投入するimageのDockerfileから

```docker:Dockerfile
FROM mysql

ENV MYSQL_ROOT_PASSWORD=パスワード ← これないと怒られました

COPY sqlファイルのpath /docker-entrypoint-initdb.d
```
ここのcopyの部分も最初『sqlファイルがないですよ！』と怒られました。
Dockerfileがある階層から相対パスで書いたらいけるっぽい

これをbuildして、GithubPackagesにpushする。
ここらへんは[GithubPackagesの公式](https://docs.github.com/ja/free-pro-team@latest/packages/using-github-packages-with-your-projects-ecosystem/configuring-docker-for-use-with-github-packages)の通りでいけると思います！

今回はGithubPackagesに上げたのでこんな感じ

```yaml:docker-compose.yml
version: "3.8"
services:
  DB:
    image: docker.pkg.github.com/username/repository名/image名:tag
    environment: 
      MYSQL_ROOT_PASSWORD: パスワード
    ports: 
      - ポート
    ....
    ....
    ....
    ....
```
で、実際にコンテナを立ち上げると
見事に落ちてしまいます。

なので
```docker-compose up -d```
で立ち上げていたところを
```docker-compose up```
で立ち上げて見てみることに。

すると, sqlファイルが ```permission denied``` でした。
なので、Dockerfileで権限周りもいじる。

```docker:Dockerfile
FROM mysql

ENV MYSQL_ROOT_PASSWORD=パスワード

COPY sqlファイルのpath /docker-entrypoint-initdb.d
RUN chown mysql:mysql /docker-entrypoint-initdb.d/*.sql
```
これでもう一回buildとpushをして
imageを指定してあるdoker-compose.ymlを```docker-compose up -d```したら

見事にデータが入っていました！！！

#参考記事
https://www.xlsoft.com/jp/blog/blog/2019/10/09/post-7617/
https://github.com/docker-library/postgres/issues/722
大きなトピックブランチでPull Request を出す際に利用したGitコマンド

# はじめに
前に書いた、[コードレビューを実施する際の流れ](https://qiita.com/na-777/items/5f7a87744744d33fa99d)の記事の中で、[レビューをもらいやすい細かいプルリクの切り分け方](https://khigashigashi.hatenablog.com/entry/2018/03/09/020359)のページを参照しました。大きな機能は一度トピックブランチに切り出して、更にそこから小さな派生ブランチを作成していくという運用です。そもそも小さくできないPull Requestでありがちな内容として

- 古いフレームワーク、ライブラリの置き換え
- GUIのデザインリニューアル

等があるんですが、この作業って、派生ブランチの名称を毎回変更できるような特徴って少なかったりするんですよね。どうしても「**feature/xxx_version_up__part1**」「**feature/xxx_version_up__part2**」みたいな単調な名称になります。また、

- そもそも、派生ブランチを都度作るのが面倒
- レビューなどで指摘部分があった時、後続の派生ブランチに差分を適応するのが面倒

だったりします。何度も派生ブランチ作るのが面倒なので、1つの派生ブランチをずっと使えないかなと思って考えたのが今回の運用になります。
# 想定するブランチ運用
![スクリーンショット 2020-10-07 12.29.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/53fb3c18-c963-a93c-da06-765ded522944.png)

基本、記事通りですが、今回の運用は派生ブランチ「feature/xxx_yyy」をずっと使い続けます。複数人で作業する場合は、派生ブランチが1人の開発者に付き1つあるみたいな感じですね。
# Gitコマンド
今回は「**development**」「**feature/version_up**」「**feature/version_up/developer_1**」というブランチがある想定で進めていきます。ただ、「**feature/version_up/developer_1**」でしか作業しないので、上記のような開発ブランチと、トピックブランチがあるんだなー程度に思ってもらえば大丈夫です。
## Pull Requestに過去のコミットをpush
開発は**feature/version_up/developer_1** で基本的な作業を行います。作業が一段落したらPull Requestを投げるため、リモートリポジトリにpushします。しかし、最新のブランチをpushすると大きくなりすぎるので過去のコミットをpushしたい時は、下記のコマンドを実行します。

```
$ git log
commit xxxxxxxxxxxxxxxxxxxx
Author: John Doe
Date:   Tue Jul 2 18:30:00 2020 ＋0900

    現在の作業

commit yyyyyyyyyyyyyyyyyyyy
Author: John Doe
Date:   Tue Jul 2 18:20:00 2020 ＋0900

    pushしたい作業
```
リビジョン番号は、**commit** の横にある文字列です。それを使って

```
$ git checkout [REVISION_ID]

$ git push origin [REVISION_ID]:[ORIGIN_BRANCH]
```
このコマンドで過去のコミットをリモートリポジトリにpushできます。今回のケースだとREVISION_IDは「**yyyyyyyyyyyyyyyyyyyy**」で、ORIGIN_BRANCHは「**feature/version_up/developer_1**」になります。

## レビューで指摘された部分を修正
```
$ git log

$ git checkout [REVISION_ID]
```
pushしてあるコミットを選択します。選択した状態でファイルの修正を実施します。

```
$ git add [FILE_PATH]

$ git commit -m 'ミスタイプの修正'
```
その後、現在のリビジョン番号を確認し、pushします。

```
$ git log
commit zzzzzzzzzzzzzzzzzzzz
Author: John Doe
Date:   Tue Jul 2 18:45:00 2020 ＋0900

    ミスタイプの修正

commit yyyyyyyyyyyyyyyyyyyy
Author: John Doe
Date:   Tue Jul 2 18:20:00 2020 ＋0900

    pushしたい作業

$ git push origin [REVISION_ID]:[ORIGIN_BRANCH]
```

今回のケースだとREVISION_IDは「**zzzzzzzzzzzzzzzzzzzz**」で、ORIGIN_BRANCHは「**feature/version_up/developer_1**」になります。
## 修正したコミットの統合
修正を差し込んだら、その修正を現在のブランチにも適応する必要があります。

```
$ git rebase -p [REVISION_ID] [BRANCH]
```
このコマンドで修正した内容を、現在のブランチに適応できます。今回のケースだとREVISION_IDは「**zzzzzzzzzzzzzzzzzzzz**」で、BRANCHは「**feature/version_up/developer_1**」になります。

pオプションなしだと、過去のマージコミットが消えるので必ずpオプションつけてください。
参照：[git rebase時にマージコミットを保持する](https://qiita.com/reoring/items/2e022cb5248559f98d6f)
# 終わりに
当初想定していた運用を形にできましたが、ローカルとリモートブランチでどうしても差分が出てしまうのがデメリットですね。また実行しているコマンドがややトリッキーなので、慣れてないとミスしたときのリカバリが面倒な感じはします。