OmniAICreator/Qiita-1.07M huggingface dataset:
vCenter上でクローンした仮想マシンの電源が入らない時のTshoot

##概要##
**vcsa6.0**の既知の問題として、/storage/logパーティションの使用率が100%になるとvmware-vpx-workflowサービスが停止し、仮想マシンの電源が入らなくなるそうです。
既に本件に関するKBや他のエンジニアの皆さんがブログでも発信している通り、解決策は出ておりますのでご参照下さい。

参照URL
https://kb.vmware.com/s/article/2147261?lang=ja
https://kb.vmware.com/s/article/2151450?lang=en_US
https://virtualization24x7.blogspot.com/2016/01/unable-to-power-on-vm-in-vcenter-6.html
https://rin-ka.net/vcenter6_01/#toc7

##環境##
VCSA 6.0
ESXi 6.0
##事象##
vCenter上でクローンした仮想マシンの電源が入らない
エラーメッセージ「一般的なシステム エラーが発生しました」
##Tshoot##
1. TeraTermでVCSAへSSH接続
2. shell有効化
    3. shell.set --enabled True　♯プロンプトが"Command>"から"♯"へ変更
1. 使用状況確認
    2. df -h                     ♯/storage/logの使用率100%
    3. service-control --status  ♯vmware-vpx-workflowのサービス停止
2. ログローテーションを有効化
    3. cd /etc/logrotate.d
    4. Cat > cloudvm_ram_size.log
    5. vim cloudvm_ram_size.log
    6. /storage/log/vmware/cloudvm/cloudvm-ram-size.log{
missingok
notifempty
compress
size 20k
monthly
create 0660 root cis
}
    7. logrotate -f /etc/logrotate.conf #errorは出力されましたが、KBに記載通り無視しました
2. サービスの再起動
    1. service-control --restart vmware-vpx-workflow
2. 仮想マシンの電源が入るのを確認（事象解決）
RailsのGraphQLで`Field xxx doesn't exist on type ???` と怒られたら

# TL;DR
```graphql
{
  house(id: 1) {
    id,
    name,
    # city_name, # Bad!
    cityName, # Good!
  }
}
```

# 現象
Railsで[graphql](https://github.com/rmosolgo/graphql-ruby)を使うとき、下記のタイプを定義しました。

```house_type.rb
module Types
  class HouseType < Types::BaseObject
    field :id, ID, null: false
    field :name, String, null: false
    field :city_name, String, null: false
  end
end
```

そして`query_type.rb`にも追記しました

```query_type.rb
module Types
  class QueryType < Types::BaseObject
    field :house, Types::HouseType, null: true do
      description "Find a house by ID"
      argument :id, ID, required: true
    end
    def house(id:)
      House.find(id)
    end
  end
end
```

query投げてみると

```graphql
{
  house(id: 1) {
    id,
    name,
  }
}
```

戻った結果は

```json
{
  "data": {
    "house": {
      "id": "1",
      "name": "Taro",
    }
  }
}
```

しかし`city_name`に対してもQueryしたら

```graphql
{
  house(id: 1) {
    id,
    name,
    city_name,
  }
}
```

こんなエラーが返されました。

```json
{
  "errors": [
    {
      "message": "Field 'city_name' doesn't exist on type 'House'",
      "locations": [
        {
          "line": 5,
          "column": 5
        }
      ],
      "path": [
        "query",
        "house",
        "city_name"
      ],
      "extensions": {
        "code": "undefinedField",
        "typeName": "House",
        "fieldName": "city_name"
      }
    }
  ]
}
```

# 解決
[公式Doc](https://graphql-ruby.org/getting_started)を読んでみると

```rb
class Types::PostType < Types::BaseObject
  ...
  field :truncated_preview, String, null: false
  ...
end
```

```rb
query_string = "
{
  post(id: 1) {
    id
    title
    truncatedPreview
  }
}"
```

と記載していて、なるほど、**Queryのフィールドはカーメル式**じゃなければいけないですね。

早速試してみると

```graphql
{
  house(id: 1) {
    id,
    name,
    cityName,
  }
}
```

```json
{
  "data": {
    "house": {
      "id": "1",
      "name": "Taro",
      "cityName": "Tokyo",
    }
  }
}
```
無事、成功しました。
tarコマンドで「アーカイブ中に予期せぬ EOF があります」が表示された場合の対応。

## tarで圧縮して別サーバに転送してから展開しよう！
と思っていた時期がありました。
というか現在進行形です。

tarのオプションをググりつつ、アーカイブファイルを作成することに成功し、scpで別サーバに移行。
いよいよ展開して目的を達成できるぞと思った矢先。

```
tar: アーカイブ中に予期せぬ EOF があります
tar: Error is not recoverable: exiting now
```

「こいつァ何を言っているんだ...?」

調べました。

~~google 働かないでお金持ちになる方法 検索~~
google tar アーカイブに予期せぬエラー 検索

はい、出てきますね。流石は現代が誇る技術です。

この現象が起こる理由としては、きちんとtarを遂行したかどうかですね。
途中でEOF(終了)を読み込んでいるので、
何かが起因してtarがうまく成功しなかった可能性があります。

「圧縮する時間長いから待ってる間ゲームでもしよ。」
とか思って、そのまま放置して眠っていませんか？
きちんと完了したことを確認しましょう。

「確認したに決まってるだろ！」とお怒りの矛をぜひ収めていただいて。

稀にですが、以下のコマンドで成功したという報告もあるみたいなので載せておきます。

```
gunzip -d アーカイブ名
tar -xvf アーカイブ名
```
パッケージ管理システムのススメ

# パッケージ管理システムのススメ

## はじめに
自分向けの覚書レベルのメモです。
いろいろ不備があると思いますが、ご容赦くださいませ。

## パッケージ管理システムとは？ 
PCに利用するアプリケーションを導入するとき。
あっちこっちのサイトを
- ググって
- 巡って
- インストーラを起動して
- インストールする
というかき集める手間が大変です。
「パッケージ管理システム」は、この辺を一覧から選んでポチポチしていけば、導入が終わるというもの。

## パッケージ管理システムの恩恵
「パッケージ管理システム」は、利用している有志で管理・更新されていることが多く以下の恩恵もあります。
- ググって巡る際に罠サイトが回避される
- 導入アプリケーションの更新有無状況がするわかる
- 簡単にアプリの更新ができる

## どんなパッケージ管理システムがあるか
これを書いているのは2019/06現在ですが、以下の認識です。

### Mac
Homebrew / MacPorts
→個人的には Homebrewを利用しています。

### Windows10
最近(2019/02)に Homebrewが2.0.0となり、Windows10に対応したそうです。
→自分のPCがまだWindows7なので利用してませんが、大変興味があります。

> 2020/11/12追記
> Windows10だと、PowerShellにてPackage操作できるみたいです。
> Get-Package的な。
> この辺、いづれ記事にしてみます。

### Windows7
Chocolatey
→これを知らない方が多いですが、結構便利です。

## 今後
ほかにも「パッケージ管理システム」はたくさんあるかと思いますので、使ってみてください。
各「パッケージ管理システム」で使ってみている分に関しては、覚書メモ程度ではありますが、今後記事にしていければと思います。
Laravelのpatch/putでハマった話

## トラブル発生
laravelで書かれたAPIの動作検証をpostmanで実行していたのですが、
patchメソッドやputメソッドではリクエストの中身が取得できていない問題が発生しました。

## 調査
```php
dd($request->all());
```

を実行すると結果はnull

phpUnitからのテストは通っているので
サーバ側のログを追ってみると
実際のリクエストはpostで飛んできていて
_methodsというパラメータにpatchが指定されていました。


## 解決
postmanのフォームパラーメータのキーに
_methodを追加
値に patchやputを入れてやると上手く動きました。

axiosはpatchメソッド実行時にペイロードがjsonの場合は問題ないのですが、
ペイロードがFormDataの場合はダメという挙動でしたが
同様にformに_merthodパラメータをappendすることで対応できました。

```javascript
form.append('_method', 'patch')
await axios.post(apiUrl, form)
```

### おまけ
ちなみに、formをbladeで書く場合は

```
 {{ method_field('PATCH') }}
```
または

```
@method('PATCH')
```
をformタグの内部に書く必要があるそうです。
csrfトークンと同じですね。
Slackのリアクションが50人を超えた時の確認方法

■reactions.get　APIを使う
https://api.slack.com/methods/reactions.get

■reactions.getを使う準備

１．リアクションがあったメッセージのURLを取得する
リアクションが50件を超えたのメッセージの[その他]より[リンクをコピー]でURLを取得する
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90537/4f475b56-ea2f-cc29-934f-227a574afafc.jpeg)

![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90537/c2a2a9fa-1e53-817f-48f6-151758132005.jpeg)


２．URLからチャンネルとタイムスタンプを取得する
コピーしたリンクをテキスト等に貼り付けて確認する
（例）
https://****.slack.com/archives/チャンネル/pタイムスタンプ

<font color="red">※タイムスタンプは、APIの形式に合わせる</font>
P1234567890123456　→　1234567890.123456

■reactions.getを実行する
![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90537/77923454-09f5-63f2-4f1d-2ca4066728a5.jpeg)

３．以下を設定する
・token
　ワークスペース名
　　Slackにログインする事でワークスペース名がプルダウンに表示
　　対象のワークスペースを選択
　認証トークン
　　認証トークンを入力
　　未取得の場合は、以下より取得
　　　https://api.slack.com/custom-integrations/legacy-tokens
　　参考URL
　　　https://qiita.com/ykhirao/items/0d6b9f4a0cc626884dbb
・channel
　２の手順で確認したチャンネルを入力
・full
　trueを入力
・timestanp
　２の手順で確認したタイムスタンプを入力
・Test Methodを押して実行

■実行結果の確認
以下のようにユーザーの一覧が表示される（ユーザーIDはマスクしている）
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90537/f2805100-367d-1175-bbe7-b73042528b6a.jpeg)

<font color="red">※ユーザーIDとユーザー名は、以下のAPIから取得（tokenを設定して実行で取得可）</font>
　https://api.slack.com/methods/users.list/test
　参考URL
　　https://yatta47.hateblo.jp/entry/2016/02/02/215933
キーボード表示時に取得したサイズの誤り

キーボードが表示された時に UITextView の下位置を調整しようとした際に
最初は cgSizeValue で height を取得していたため位置の調整に失敗していた。
cgRectValue で取得でないとダメ。念の為取得結果を検証してみました。

キーボード表示時

```
@objc func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        if let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
　　　　　　　self.textViewBottom.constant = keyboardFrame.cgRectValue.height

            let keyboardRect = keyboardFrame.cgRectValue
            let keyboardSize = keyboardFrame.cgSizeValue
            let keyboardPoint = keyboardFrame.cgPointValue
            
            print("self.view.frame.size[\(self.view.frame.size)] self.view.frame.origin[\(self.view.frame.origin)]")
            print("keyboardFrame.cgRectValue.size[\(keyboardRect.size)] cgRectValue.cgRectValue.origin[\(keyboardRect.origin)]")
            print("keyboardFrame.cgSizeValue[\(keyboardSize)]")
            print("keyboardFrame.cgPointValue[\(keyboardPoint)]")
        }
    }
}
```

iPhone8 で実行

```
self.view.frame.size[(375.0, 667.0)] self.view.frame.origin[(0.0, 0.0)]
keyboardFrame.cgRectValue.size[(375.0, 260.0)] cgRectValue.cgRectValue.origin[(0.0, 407.0)]
keyboardFrame.cgSizeValue[(0.0, 407.0)]
keyboardFrame.cgPointValue[(0.0, 407.0)]
```

cgSizeValue は cgPointValue の値と同じなってしまっているようで、バグっぽいですね。
UbuntuでAWS ECR にログインできない

## ECRにログインする
```
$(aws ecr get-login --no-include-email --region ap-northeast-1)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error saving credentials: error storing credentials - err: exit status 1, out: `Cannot autolaunch D-Bus without X11 $DISPLAY`
```
credential情報が間違っていないか?

```
aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************PXP5 shared-credentials-file
secret_key     ****************ZEee shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config
```

間違っていない。。。

##これで解決

```
$ apt-get remove golang-docker-credential-helpers
```
pacman メモ

トラブルシュートメモ。

ArchLinux な pacman で、久しぶりにシステム更新 `pacman -Syu` しようとしたとき、エラーが出た。

`error:key XXXX could not be looked up remotely" と出ていた。

最終的には [BBS](https://bbs.archlinux.org/viewtopic.php?id=193382) にある方法で解決した。

```
# rm -R /etc/pacman.d/gnupg/
# rm -R /root/.gnupg/  # only if the directory exists
# gpg --refresh-keys
# pacman-key --init && pacman-key --populate
# pacman-key --refresh-keys
```

`pacman-key --refresh-keys` は外部アクセスする。

http_proxy 必須な今の環境ではタイムアウトした。

http_proxy を有効にするために、次のようにした。

gpg コマンドラインでは `gpg --keyserver-option http-proxy=local.proxy.host:8080` とすればよいらしい。

同等にするには、pacman では `/etc/pacman.d/gpg.conf` に次のような行を追加する。

```
keyserver-option http-proxy=http://local.proxy.host:8080
```

あるいは

```
keyserver-option honor-http-proxy
```

でもよさそう。

-----

後から発見。（検索エンジンで出てこないとなぁ…と思って、リンク）

- https://qiita.com/hurou927/items/08778af723b58d3a991b
- https://qiita.com/Arnold/items/449df148249d17bb627b
VScodeで保存時にESlintが自動補正してくれるようにする

## はじめに
vue.jsに触り始めて２日くらい
やっとコンパイルやら開発環境サーバーの立ち上げやら、環境構築周りに慣れてきました。
規則に沿ったコーディングがなるべくできるよう、コンパイル時にESlintを走らせるような設定をしています。

VScodeの方で保存時に自動インデント補正をかけていたら、ESlintのテストと競合し永遠にコンパイルが通らなくなったので、メモ程度に残しておきます。

**2019/06/19 結論のコード部分を加筆しました 
vueファイルに対しEslintが機能してませんでした。。
こちらを参考にさせて頂きました。とてもわかりやすいです・・！
[VSCode上でvueファイルに対してESLintが快適に動作する設定](https://qiita.com/fukasawah/items/cfff8957f3956850dc7e)**

## 環境
* mac os highSierra
* VScode

## 結論
* VScodeにESLintのプラグインを入れる
* settings.jsonに下記を追記

蛇足ですが、何についての設定か忘れないように、無理やりコメントを付けてますw

 ```
    "comments": "eslintの自動保存",
    "eslint.autoFixOnSave": true,
    "eslint.validate": [
      {
        "language": "vue",
        "autoFix": true
      }
    ],
    "comments": "vueファイル内のJavaScriptに対しVeturを無効にする",
    "vetur.format.defaultFormatter.js": "none",
    "comments": "Vscodeの自動保存なし",
    "editor.formatOnSave": fals
 ```

## まとめ
`"editor.formatOnSave": false`を明記しないと、ESlintのオートセーブと競合してしまうそう。
変なところでハマりましたが、なるほどーとなりました。
PHPのAWS-SDKからIAMロールを使用する方法

PHPのAWS-SDKからIAMロールを仕様する方法です。ググっても適切な情報がなかなか見つからなかったので書きました。

## 対応
IAMロールを利用する場合は、インスタンス作成時にprofileを渡さない。（書かない）
→profileを書いているとIAMロールではなく、実行環境のcredentials（を含め実行ユーザーのホームディレクトリの.awsディレクトリ以下のファイル）が参照されるところがハマりどころです。

## コード例

IAMロールを利用する場合は、```$accessKeyId``` と ```$secretAccessKey``` は空の状態とします。

```php
<?php
$accessKeyId = '<AWS IAMアクセスキーID>';
$secretAccessKey = '<AWS IAMシークレットアクセスキー>';

// configのデフォルト
$config = [
  'version' => 'latest',
  'region' => 'ap-northeast-1',
  'profile' => 'default'
];

// AccessKeyとSecretAccressKeyがない場合は、IAMロールを使用する
if (empty($awsAccessKeyId) && empty($awsSecretAccessKey)) {
  // IAMロール認証の場合はprofileをセットしない(unsetする)
  unset($config['profile']);
}

$lambda = new \Aws\Lambda\LambdaClient($config);
```

## 参考
- https://stackoverflow.com/questions/31919316/issue-using-an-iam-role-with-php-sdk
- https://stackoverflow.com/questions/49806405/cannot-read-credentials-from-aws-credentials-php-script-call-aws-sdk
Railsアプリは動いているが望む動作をしていない時の思考プロセス

# コードは正しく書けているので、Viewは返ってくる・・・
やっとRailsのエラーから解放されて、知見も溜まってきていい感じと思いきや、望んだ動作になっていないViewが返ってきている・・・そんな時にどう考え、修正していくかの覚書です。

## URLから考える
Restfulな作りを徹底しているのなら、そのURLに紐づいているcontrollerやViewのshow.htmlのファイルからさらってみる。
基本的なことかもしれないのだが、筆者の場合、Railsエラーを解決することに慣れて、動いているのに望んだ挙動にならない問題はより難易度の高いデバッグ作業に感じることが多い。何と言っても動いてはいるので、エラー文が出ないからである。そんな時の思考プロセスは先の通りです。まず、問題となっているファイルを疑わなければならない、ということです。
そうやってまず、問題になっているファイルを特定しに行きます。ファイルを特定したら、問題の機能に関係しているコードを読みにく・・・という流れを作ることができます。直接コントローラー周りが分からなかったら、viewから使われているインスタンス変数などを特定し、これっぽいなーと当たりをつけながらコントローラーのそのインスタンス変数の中身を見に行ったり、そこをレシーバにして実行しているメソッドを見に行く、利用しているデータをモデルへ見に行く、などによってデバッグすべき箇所を絞り込んでいきます。ここの実行処理をみたいなーというところまで絞り込んだら、binding.pryを埋め込んでみて、変数の中身を見たり、発行されてるクエリを見てみたりします。
【Laravel】マイグレーションファイルからmongoDBのコレクションが作れなかった時の対処

# はじめに
タイトルの通りです。LaravelのマイグレーションファイルからmongoDBのコレクションを作成しようと思ったのですが生成されなかったので、その時の対処方法を備忘録として残そうと思います。

### 環境
* Laravel5.5
* PHP 7.x
* MongoDB 4.0.10

もう一つDBとしてpostgreSQLも使用していましたが、今回の記事では特に記述しません。

# 問題
例として下記のようなマイグレーションファイルを作って、`php artisan migrate`コマンドを動かしてみたところ、コレクションが生成されない:cold_sweat:

※ `config/database.php` にはMongoDBの情報を記載済みです

```php
class Sample extends Migration
{
    // MongoDBのコネクションを指定します
    protected $connection = 'mongodb';
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::connection($this->connection)
            ->table('Sample', function (Blueprint $collection)
            {
                $collection->string('name');
            });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::connection($this->connection)
            ->table('Sample', function (Blueprint $collection)
            {
                $collection->drop();
            });

    }
}
```

これで `Sample`コレクションが出来上がると思っていたのですが、何度確認してもコレクションが見当たりません。

# 対処
upメソッドのカラム記述のところが良くないみたいです。indexを貼るような記述にすると良いみたいです。
なぜindexじゃないとダメなのか分からないですが・・・

```diff
--- $collection->string('name');
+++ $collection->index('name');
```

このコードだと生成されたコレクションの`_id`と`name`にインデックスが貼られます。`_id`にはデフォルトで付くみたいですね。
ここで、「デフォルトで付くならカラム定義の箇所ごっそり要らないやん」と思って削除してマイグレーションしてらコレクションは生成されませんでした。ﾅﾝﾃﾞﾔ・・・

`_id`にだけindexを付ける場合は下記みたいにしっかり明記しないとダメみたいです。

```php
$collection->index('_id');
```

# まとめ
**index使って記述すると良い**
他に何か良い解決方法分かる方いましたら教えて下さい。:bow_tone1:

LaravelからMongoDBを触るのが始めてだったので、これの解決するのに結構時間取られちゃいました。
にしてもどうしてindexじゃないとダメなんだろう・・・。私、気になります！
Python + Redis 接続方法

# Redisとは

物理ディスク（HDD,SSD)などに保存するのではなく、揮発性のメモリーに保存しておく、データベースアプリーケーションです。
物理ディスクのようにデータを拾い上げるためにディスクをサーチする必要がなく、すでにメモリ上にデータがあるため非常にサーチスピードが速いのが特徴です。

揮発性のメモリーに保存しているため、サーバーが落ちてしまったりするとデータは消えてしまいますが、アクセスが速いのは使い勝手がいいですよね。
今回は、Redisを接続するための方法を備忘録として書きました。


#公式のモジュールをインストール
https://pypi.org/project/redis/

```bash
pip install redis
```


```python
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
r.set('foo', 'bar')
foo = r.get('foo')
print(foo)
# bar

```

めちゃくちゃ簡単。

#文字列型データの追加・取得・削除

```python
#値を追加する
r.set('hoge', 'foge')
#保存時間を設定して値を保存する
r.set('foge', 'hogo', 100) #100秒だけ値を保持する
```

```python
#値を取得する
value = r.get('hoge')
print(value)
# >>> b'foge'
# バイナリーデータをUTF-8にデコード
value = value.decode()
print(value)
# >>> foge
```

```python
#値を削除する
r.delete('hoge')
```

#ハッシュ型データの追加・取得・削除

```python
#ハッシュに値を追加する
r.hset('hoge', 'name', 'foge')
r.hset('hoge', 'age', 22)
```

```python
#ハッシュに値を追加する
name = r.hget('hoge', 'name')
age = r.hget('hoge', 'age')
```

```python
#ハッシュに値を削除する
r.hdel('hoge', 'name')
r.hdel('hoge', 'age')
r.delete('hoge')
```
Let's Encrypt の有効期限を延長する。


Let's Encryptは３ヶ月しか有効期限がないので、延長する。

```
$ sudo certbot renew
```

以下は、実行ログ

```
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/xxx.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator apache, Installer apache
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for xxx.com
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of apache server; fullchain is
/etc/letsencrypt/live/xxx.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/xxx.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

```
動画と画像に関連するよく使う技術メモ (ffmpeg とか ImageMagick とか)

自分用メモ。随時更新。

## JPEGを連結してPDFにする

```bash
convert -verbose -quality 80 -page a4 `ls -v *.jpg` output.pdf
```

## EXIF情報を消す

```bash
convert in.jpg -strip out.jpg 
```

## 画質とFPSを設定する

30fps/2Mbps

```bash
ffmpeg -i input.mp4 -r 30 -b:v 2M output.mp4
```

## 回転させる

右90度回転

```bash
ffmpeg -i input.mp4 -vf transpose=1 output.mp4
```

左90度回転

```bash
ffmpeg -i input.mp4 -vf transpose=2 output.mp4
```

## 複数のMP4を連結する

concat.txt を用意する

```bash
find . -type f -name '*.mp4' | awk '{print "file "$1}' > concat.txt
```

```
file 01.mp4
file 02.mp4
```

```bash
ffmpeg -f concat -i concat.txt -c:v copy -c:a copy -c:s copy -map 0:v -map 0:a -map 0:s? aaa.mp4
```

`v`, `a`, `s` はそれぞれ映像、音声、字幕

## エンコーダを指定

h264

```bash
ffmpeg -i input.mp4 -c:v h264 output.mp4
```

h264 NVENV (GPU)

```bash
ffmpeg -i input.mp4 -c:v h264_nvenc output.mp4
```

## トリミング

00:30-00:45 を切り取り

```bash
ffmpeg -ss 00:00:30 -i input.mp4 -t 00:00:45 -vcodec copy -acodec copy output.mp4
```

`-vcodec copy -acodec copy` を取るとエンコードがかかる
その分遅くなるが時間は正確になる (copy だと多少ずれる)
https://qiita.com/kitar/items/d293e3962ade087fd850

## 動画投稿・ストリーミングサービスのコーデック

### 各サイトのヘルプ

- [YouTube 動画](https://support.google.com/youtube/answer/1722171?hl=ja)
- [ニコニコ動画](https://qa.nicovideo.jp/faq/show/5685?site_domain=default)
- [YouTube 放送](https://support.google.com/youtube/answer/2853702?hl=ja)
    - 4K対応, 1080p なら上限 9Mbps
- [ニコニコ生放送](http://blog.nicovideo.jp/niconews/57697.html)
    - 1080p 非対応, 60fps 非対応, 上限 720p, 6Mbps
- [Mixer](https://watchbeam.zendesk.com/hc/en-us/articles/210090606-Stream-Settings-the-basics)
    - 1080p 対応, 上限 10Mbps
- [OPENREC](https://openrec.zendesk.com/hc/ja/articles/115001718828-%E9%85%8D%E4%BF%A1%E3%83%84%E3%83%BC%E3%83%AB%E8%A8%AD%E5%AE%9A)
    - 1080p 対応, 上限 5Mbps

### 個人的なプリセット (妥協点)

#### 生放送 (1080p)

YouTube と Mixer 用

- 解像度 : 1080p
- FPS : 60fps
- ビットレート : 9Mbps
- キーフレーム : 2sec

#### 生放送 (720p 60fps)

YouTube と Mixer 用

- 解像度 : 720p
- FPS : 60fps
- ビットレート : 6Mbps
- キーフレーム : 2sec

#### 生放送 (720p 30fps)

OPENREC とニコニコ用

- 解像度 : 720p
- FPS : 30fps
- ビットレート : 5Mbps
- キーフレーム : 2sec
自分用にADBコマンドのGUI操作ツールを作ってみた


#経緯
　「OculusQuestにオレオレのアプリをUnityからインストールまでは良いとして、アンインストール出来ないって・・・本当・・・？ コマンドプロンプトでADBコマンド打ってアンインストールするの・・・？え？本当に？え？何言ってるの・・・？」

というわけで作りました。

https://github.com/divide-by-zero/ADBB/
※申し訳ありませんがwindows専用です

#出来る事
- APKファイルのインストール（ファイルダイアログからの選択またはパッケージ一覧部分へのドラッグアンドドロップ）
- インストールされている（サードパーティー製）アプリのパッケージ名一覧表示（及びフィルタ）
- パッケージ指定によるアプリのアンインストール
- パッケージ指定によるアプリの強制起動・停止
- 端末へのIPアドレス接続・切断
- 端末強制シャットダウン
- 端末強制再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37184/e420bb7e-5798-db8c-e2c8-0a01a580ac36.png)

#言い訳
あくまでも自分用なので、UIもアレな感じですし、ソースコードもお察しですが、しばらく使ってみてそこそこ便利（手前味噌）だったので、公開することにしました。
また、大体のAndroid端末でも使用できると思いますが、**基本はOculusQuest用**です。
というのも、内部では`adb shell`によって情報取得しているんですが、そこで `grep` や `sed` を使っており、**ADB Shell で使用出来るコマンドが全てのAndroid端末で共通とはとても思えない** ので、そこはグレーゾーンにならざるを得ない感じです。

#起動方法
gitでcloneしてビルド または release (https://github.com/divide-by-zero/ADBB/releases/) でダウンロードできるzip 
 または exe(自己解凍形式) を解凍して、フォルダ内の `ADBB.EXE` を起動してください。
初回起動の際には`adb.exe`へのパス設定が開きますので、（インストールされているであろう)`adb.exe`を指定してください。

通常はAndroidSDKをインストールしたフォルダ\android-sdk\platform-tools の中です。

#仕組み
上記に書いた「出来る事」は全て `adb` (Android Debug Bridge) で出来る事です。
設定したadb.exeのパスを使用し、コマンドを肩代わりしている(Bridgeしている）に過ぎません。
そのため（理論上は）adb.exeで出来ることは全部できますし、逆にadb.exeに出来ないことは手が出せないです。

#ソース構成
ものすごい雑に、ValueObjectとして、接続されたAndroid端末を担当する `Device`クラス、インストールされているアプリを`PackageData`クラス。
UI部分は`MainForm`、Adbコマンド処理クラスとして `AdbCommand`クラスです（まんま）　どシンプル。

#ちょっと頑張ったところ
普通にADBコマンドを `Process`クラス で実行するとUIが固まります。　ブロック処理なので。
そのため、内部的に `Task.Run` と `TaskCompletionSource` を使って非同期（スレッドプール実行）にしてあります。
それだけなら良いんですが、 `adb install [パッケージ名]` および `adb uninstall [パッケージ名]` のコマンドはDeviceが接続されてない状態で実行すると

```
c:\>adb install test.apk
error: no devices/emulators found
adb: error: failed to get feature set: no devices/emulators found
- waiting for device -
```

このように `- waiting for device - ` と出て、デバイスが接続されるまで待ち状態になってしまいます。
コマンドラインでこの状態になったなら `Ctrl+C` など打って止めるだけですが、Processクラスを使用しての実行の場合は**外部から`Kill()` を呼んであげる必要**があります。

今回のようにTask化されている処理を外部から停止 ＝ `CancellationToken` の出番ですね。

そんなわけで、 `CancellationToken` を渡す事が出来る版の非同期Process実行が実装されています（多分）

それ以外は、ものすごい地味にadbのコマンド（およびadb shell上でのコマンド)から標準出力で得られる情報を頑張ってスクレイピングしてます。涙ぐましい。

#もっとやりたいこと
- 「Device更新」を押さずとも、自動で接続／切断されたAndroidデバイスが検出できれば。今は心がこもった手動駆動。
- パッケージ名から、アプリケーション名やアイコン画像などを取得して、画面に表示したい。（adbコマンド越しで取得する方法が見つからず・・・。　）

どなたか方法ご存知でしたら教えていただけるとありがたいです（プルリクも大歓迎です）

ではでは。
React.js 学習メモ　第1回

最近Reactの勉強を始めたので、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#学習を始める前に
新しく言語を学ぶ事になるのですが今までの学習方法はあまり効率的ではなかったので何か良い方法をまずは探し、学習スタイルを決めてから始めようと思いました！

[新しく言語を学ぶときに心がけていること-Qiita](https://qiita.com/hiraike32/items/40ef06f85f6a63828985)
個人的に、この方法で実際にやってみてどうなるかと考えて、この記事を参考に学習スタイルを決めました！

公式チュートリアルをやる前にこの記事をざっと読んでもらった方が良いかもしれません
この方が言うように、僕もいきなり公式チュートリアルに挑戦してもややこしいポイントが多いためです。
[【progateの次はこれ！】reactの勉強手順まとめ](https://dragon-taro.com/technology/post-298/)

#初めてのReact
まずは公式ドキュメントを読もうと思いましたが学習のロードマップ的なものがないかとググってみたら、どうやってReactを勉強していくのかのロードマップを書いているサイトがあったのでその通りスタートしてみました！
[How to Learn React — A roadmap from beginner to advanced](https://medium.freecodecamp.org/learning-react-roadmap-from-scratch-to-advanced-bff7735531b6)

#React公式チュートリアル
ありがたいことに日本語にも対応していたので、ドキュメントを読みつつ言語の歴史と特性を知るというのを行なってみました。
[React公式チュートリアル](https://ja.reactjs.org/)
[Reactチュートリアル: Intro To React【日本語翻訳】](https://mae.chab.in/archives/2943)

個人的に三目並べゲームの内容などであまり理解できない点があったのでこの記事を参考に理解を深めました。
[React チュートリアル](https://qiita.com/o_sol06/items/dce7b6c99ecb3abf7ec1)

三目並べゲーム追加課題の参考サイト
https://fukatsu.tech/react-tutorial-additional-challenges

##振り返り
こんな感じの流れでやってます、学習してなるほどと思ったことはSlackでメモをとったりしてるんですが振り返りにくくなったのでQiitaに残していきます！しかし、やってみてReactってこんな感じかというのはふわっと分かってきたのですがいざ、これってどう言うこと何ですかと聞かれた時に上手く説明できなかったので理解を深めて言語化をしていきます。
セッション管理の不備

## セッション管理機構
webアプリケーションでは認証結果の情報を記憶しておく手段として、セッション管理機構がある。その代表的な方法がクッキーなどにセッションIDという識別子を記憶させ、このセッションIDをキーとしてサーバー側で情報を記録する方法。セッションIDをもっていればサーバー側は誰が問い合わせてきたのかがすぐにわかる為、毎回認証行為をする必要がなくなる。

## セッションハイジャック
他人がセッションIDを悪用して成りすますこと。第三者がセッションIDを手に入れる方法は主に三つ
- セッションIDの推測
- セッションIDの盗み出し
- セッションIDの強制

### セッションIDの推測
これはセッションIDの生成方法が予想しやすいのが原因です。例えばセッションIDが連番になっている、ユーザーIDや日時がセッションIDの元となっている、乱数に規則性があり複数のセッションIDを集めることで規則性を見つけ、結果セッションIDの推測に繋がる、オープンソースのソフトウェアだとセッションIDの生成ロジックがわかってしまい、解読される恐れがある。

### セッションIDの盗み出し
セッションIDを外部から盗み出すこと。
- クッキー生成の際のセキュリティ上重要な属性であるDomain、Secure、HttpOnlyに不備があると漏洩してしまう
- ネットワーク的にセッションIDが盗聴される
- クロスサイト・スクリプティングなどアプリケーションの脆弱性により漏洩する
- PHPやブラウザなどプラットフォームの脆弱性による漏洩
- セッションIDをURLに保持してる場合ヘッダから漏洩する

### セッションIDの強制
セッションIDを利用者のブラウザに設定することで、攻撃者は自分で設定したため利用者のセッションIDを知っているのと同じ状態になります。これをセッションIDの固定化攻撃という。
コマンドプロンプトで sleep するためのテクニック

# 概要

PowerShell の Start-Sleep コマンドレットを使えば簡単に sleep はできますが、PowerShell を使わずにコマンドプロンプトで sleep するためのテクニックについて記載しておきます。

# 方法

方法はいくつかあります。
コマンドはそれぞれ異なりますが、以下の方法により結果として 3 秒間の sleep が実現できます。

## (1) 無効なIPアドレスへの ping による sleep

無効なIPアドレスへ ping して sleep します。
-n オプションで再試行回数 1 を指定し、タイムアウト時間を 3000 ms で指定します。

```
ping 1.2.3.4 -n 1 -W 3000 > nul
```

## (2) localhost への ping 再試行による sleep

ping コマンドは 1 秒で応答することを利用して sleep します。
localhost に対して -n オプションで再試行回数 4 (sleep したい秒数 - 1) を指定します。

```
ping 127.0.0.1 -n 4 > nul
```

## (3) timeout による sleep

Windows 7 以降であれば timeout コマンドで sleep できます。
引数へ sleep 秒数として 3 を指定します。

```
timeout 3
```

## (4) choice のタイムアウトによる sleep

choice コマンドはユーザーに選択肢を選んでもらうためのコマンドです。
choice は何も選択せずに一定時間が経過するとタイムアウトを発生させることができるため、このタイムアウトの時間を利用して sleep します。
タイムアウトの時間を指定するため /t オプションへ 3 を指定します。

```
choice /C YN /D Y /t 3
```
remote: Repository not found.となった時の対応方法

# 事象:SourceTreeでGitHubからリポジトリをCloneしたら怒られた

- 環境
    - Winsows10 64bit
    - SourceTree v3.0.8
        - 既に他のアカウントでGitHubからcloneしたリポジトリがある

```bash
コマンド: git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks -c credential.helper= -c credential.helper="C:/Users/ponsuke/AppData/Local/ATLASS~1/SOURCE~1/GIT_EX~1/GIT-CR~1.EXE" ls-remote https://github.com/ponsuke/repository.git
出力: 
エラー: remote: Repository not found.
fatal: repository 'https://github.com/ponsuke/repository.git/' not found

https://github.com/ponsuke/repository.git/
```

## 原因:認証できないから
[Githubにhttpsでgit cloneできない時やったこと - Qiita](https://qiita.com/t-sagiri/items/79535fc5a8f0c89409f7)

### 対応:ユーザ名とパスワードを指定してCloneする
Cloneするリポジトリを以下の形式で指定する

```bash
https://{ユーザ名}:{パスワード}@github.com/ponsuke/repository.git
```

やってないけど`remote account`リンクから設定してもできそう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/e49defa2-fc9c-96e5-f726-0384864411b2.png)

### GitHubの2段階認証を設定している場合
1. GitHubにログイン > 右上にある自分のアイコンをクリック > [Settings]
2. [Developer settings] > [Personal access tokens] > [Generate new token]ボタンでトークンを生成する
2. Cloneするリポジトリを以下の形式で指定する

```bash:2段階認証を設定している場合
https://{ユーザ名}:{トークン}@github.com/ponsuke/repository.git
```

# 事象 : 既にCloneしていたGitHubのリポジトリをフェッチしたら怒られた
```bash
$ git fetch --all --prune
Fetching origin
remote: Repository not found.
fatal: repository 'https://github.com/ponsuke/repository.git/' not found
error: Could not fetch origin
```
## 原因 : Windows Credential Managerがおかしいから
なぁぜか、昨日までフェッチできていたのにぃ・・・

> Gitのログインに必要なユーザ名とパスワードが、Windows Credential Manager (資格情報マネージャ)に格納され、Git のアカウントを複数利用した場合に問題が発生するということが書いてあった。
> [Github へ  push しようとしたら Repository not found というエラーが出るようになった](https://kunsen.net/2020/11/16/post-3388/)

そういえば、さっき違うGitHubアカウントでクローンとかやったなぁ・・・

### 対応 : システム全体用の設定を修正する
```bash
# 1. システム全体用のconfigをエディタで開く
$ git config --edit --system
# 2. エディタで以下を削除する(※[credential]にhelper以外の設定があったら[credential]は残す)
[credential]
    helper = manager
# 3. 保存してconfigを閉じる
# 4. もう一回フェッチしたらできた
$ git fetch --all --prune
Fetching origin

$
```

## 原因:認証できないから
先に書いた事象と原因は同じ。
2段階認証をかけているアカウントなのになんで、Cloneも1回目のpushもできたんだろう？と不思議に思っていたら怒られた。

### 対応 : configファイルのurlに認証情報を追記する
設定を修正すればfetchもpullもpushもできるようになる

```config:.git/config
:...省略...
[remote "origin"]
    url = https://{ユーザ名}:{トークン}@github.com/ponsuke/repository.git
:...省略...
```
Azure App Service が30秒でタイムアウトしてしまう

# はじめに
はじめてのAzure App Serviceで手探り状態で色々試している中で、
Azureの公式ドキュメントだけでは解決しなかった情報を残しておきます。

# Azure App Serviceのリクエストタイムアウト設定が30秒なのか？
**リクエストタイムアウト設定は230秒**になっているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240903/089bbeec-4460-c758-2ef5-503aef976149.png)
[Azure での Web アプリのアプリケーションパフォーマンスに関するよくあるご質問 - 230 秒後に要求がタイムアウトになるのはなぜですか?](https://docs.microsoft.com/ja-jp/azure/app-service/faq-availability-performance-application-issues#why-does-my-request-time-out-after-230-seconds)

# 30秒でタイムアウトするのはなぜ？
デフォルト設定のままデプロイすると**30秒経過で502エラー**が返ってきます。
最終的にこれが気付くポイントでした。

下記の設定で動いているとばっかり思っていて、**600秒**の設定かと思ってたら違いました。
こう書いてあったからここは疑わずに時間を取られてしまった。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240903/bb2513f2-549c-3f5f-fcb6-dbc7a225eb11.png)
[Azure App Service 向けの Linux Python アプリを構成する - Flask アプリ](https://docs.microsoft.com/ja-jp/azure/app-service/containers/how-to-configure-python#flask-app)

もしやと思いgunicornのドキュメントを見ると、
gunicornのworkerのタイムアウト設定は**デフォルト30秒**です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240903/05eab7b5-cab4-9683-970d-fb680b1f28eb.png)
[gunicorn - Settings - timeout](http://docs.gunicorn.org/en/stable/settings.html#timeout)

え？もしかしてデフォルト設定なのでは？

# 解決
下記に従い、timeout設定を50秒にしてみたところ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240903/cda14556-ce28-b00e-e9c1-935abd749650.png)
[Azure App Service 向けの Linux Python アプリを構成する - スタートアップ コマンドのカスタマイズ](https://docs.microsoft.com/ja-jp/azure/app-service/containers/how-to-configure-python#customize-startup-command)

time.sleep(40)を仕込んでみたけど、30秒で502エラーが返らなくなった！

# 最後に
英語サイトとかも調べまくったけど、
公式を鵜呑みにしてはいけないという教訓を得ました。
最終的には状況証拠をもとにいろいろ試すことが大事ですね。
実体とドキュメントが合致していないことは間々あります。
CentOS7 で Subversion 1.9 系をインストールする方法

# 概要

CentOS 7 で yum コマンドから Subversion をインストールすると以下のように 1.7 系の svn がインストールされます。

```
# yum install -y subversion
# svn --version
svn, version 1.7.14 (r1542130)
   compiled Apr 11 2018, 02:40:28
```

ケースとしては少ないと思いますが、Windows の Tortoise SVN からチェックアウトした作業コピーを CentOS 7 へ転送し、svn コマンドを実行した場合、以下のようなエラーが発生することがあります。

```
# svn propget -R svn:externals .
svn: E155021: This client is too old to work with the working copy at
'/data/test' (format 31).
You need to get a newer Subversion client. For more details, see
  http://subversion.apache.org/faq.html#working-copy-format-change
```

これは TortoiseSVN の SVN バージョンが 1.9 系で CentOS 7 の SVN バージョンが 1.7 系のため作業コピーのバージョン差異によって svn のコマンドが使えない状態を示しています。

本記事では CentOS 7 で Subversion 1.9 系をインストールする方法について記載します。

# 手順

以下のファイルを編集または新規作成します。

```
# vi /etc/yum.repos.d/subversion.repo
```

以下の内容を追加して上書き保存します。

```
[subversion]
name=subversion
baseurl=http://opensource.wandisco.com/rhel/7/svn-1.9/RPMS/
enabled=1
gpgcheck=1
gpgkey=http://opensource.wandisco.com/RPM-GPG-KEY-WANdisco
```

yum コマンドから Subversion をインストールします。

```
# yum install -y subversion
# svn --version
svn, version 1.9.9 (r1835931)
   compiled Jul 25 2018, 12:41:27 on x86_64-redhat-linux-gnu
```

CentOS 7 に 1.9 系の Subversion がインストールされました。
[iOS13]接続中のWi-FiのSSIDを取得するCNCopyCurrentNetworkInfo()がnilになった？

## iOS12までSSIDを取得する方法

[Stack Overflow](https://stackoverflow.com/a/37856496/4063462)から参照。

```swift
import Foundation
import SystemConfiguration.CaptiveNetwork

func getSSID() -> String? {
    var ssid: String?
    if let interfaces = CNCopySupportedInterfaces() as NSArray? {
        for interface in interfaces {
            if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary? {
                ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
                break
            }
        }
    }
    return ssid
}
```

iOS12以降、Capablitiesで `Access Wifi Information` を追加する必要があります。
参考記事：[iOS12以降でCNCopyCurrentNetworkInfo() の注意点](https://qiita.com/nomadmonad/items/85f57615bf2b53a91e29)

## iOS13はどうなった？

`CNCopyCurrentNetworkInfo()`が`nil`になりました。

Apple Developer Forumsに[`CNCopyCurrentNetworkInfo()`が使えない報告](https://forums.developer.apple.com/thread/117371)があります。

## 原因

Wi-Fi情報からユーザーの位置を推測できます。Appleがユーザーのプライバシーを守るため、iOS13以降、`CNCopyCurrentNetworkInfo()`でSSIDなどの情報を取得するには、位置情報の使用許可が必要になりました。

WWDC19 Session 713: [Advances in Networking, Part 2](https://developer.apple.com/videos/play/wwdc2019/713/)から抜粋。

>Now you all know the important privacy to Apple. And one of the things we realized. Is that... Accessing Wi-Fi information can be used to infer location.
>So starting now, to access that Wi-Fi information. You'll need the same kind of privileges that you'll need to get other location information.

## 対処法

位置情報を取得する許可をリクエストします。

参考記事：[【CoreLocation】位置情報を取得する](https://qiita.com/chino_tweet/items/db3a536234a43a3c31d9)

CoreLocationフレームワークをインポートします。

```swift
import CoreLocation
```

iOS13であれば、位置情報の許可をリクエストします(ここで「使用中のみ許可」)。
すでに許可された場合又はiOS12までの場合は`updateWiFi()`を呼び出します。

```swift
if #available(iOS 13.0, *) {
    let status = CLLocationManager.authorizationStatus()
    if status == .authorizedWhenInUse {
        updateWiFi()
    } else {
        locationManager.requestWhenInUseAuthorization()
    }
} else {
    updateWiFi()
}
```

ユーザーが許可した場合は、`updateWiFi()`メッソドを呼び出します。

```swift
class ViewController: UIViewController, CLLocationManagerDelegate {
    ...
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedWhenInUse {
            updateWiFi()
        }
    }
    ...
}
```

メソッド`updateWiFi()`の中身

```swift
func updateWiFi() {
    print("SSID: \(getSSID())")
    ssidLabel.text = getSSID()
}
```

## サンプルプロジェクト

[iOS13-WiFi-Info](https://github.com/HackingGate/iOS13-WiFi-Info)

## アプリをアップデートする

この対策法は新しいAPIを使用していないため、Xcode 11 GM版を待つ必要はありません。
Xcode 10で今すぐ不具合を修正しましょう。

## 追記

iOS 13.0から13.2までの端末が位置情報を取得できても、`CNCopyCurrentNetworkInfo()`が`nil`になって使えない報告がたくさんありました。
iOS 13.3 beta 1 (17C5032d)に修正されたそうです。アップデートしてお試しください。
関連 GitHub コメント：
https://github.com/HackingGate/iOS13-WiFi-Info/issues/7#issuecomment-550164579
GitHubにSSH接続する

コマンドラインからssh接続してGitHubの操作をするためには、鍵の作成・登録が必要。
鍵の作成はGitHubには限らないので、コマンドとか流れをまとめてみた。

# 鍵の作成〜登録
## 鍵の作成
ssh-keygenコマンドで鍵を作ることができる。

```
$ cd ~/.ssh
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/ユーザ名/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

とりあえず作るときはEnterを押しておけば大丈夫。
名前をつけたいときは、1回目に聞かれたときに入力する。

## Githubに鍵を登録する
作成した鍵の登録はここから。
[SSH and GPG keys](https://github.com/settings/keys)

鍵の中身をコピーして貼り付けて登録する。

```
# 鍵の中身をクリップボードにコピー(Macの場合、pbcopyコマンド)
pbcopy < ~/.ssh/id_rsa.pub
```

鍵を登録したら、sshで接続を確認する。

```
$ ssh -T git@github.com
Hi アカウント名! You've successfully authenticated, but GitHub does not provide shell access.
```


# リンク
- [GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)
celeryconfig.pyを使わずにCeleryのbackendを指定するときの注意点

いやceleryconfig.pyを使えっていう話なんですが、直接指定する場合の注意点について書きます。

# 結論

`result_backend`ではなく`backend`を指定しましょう。

```python
app = Celery('run', broker='redis://localhost:6379/0', backend='redis://localhost:6379/1')
```

# `result_backend`と`backend`

Celeryの[ドキュメント](https://docs.celeryproject.org/en/latest/userguide/configuration.html)なんかを見てると、処理したタスクの結果を指定するには`result_backend`を指定するように記述があります。
`celeryconfig.py`を使う場合にはこれで問題無いですが、上記のようにコード中に直接記述する場合は`result_backend`ではなく`backend`を指定する必要があります。

設定してるはずなのに結果が出力されないなーとしばらく悩んでいたんですが、[githubのCeleryクラス](https://github.com/celery/celery/blob/master/celery/app/base.py)を見ると、コンストラクタで`result_backend`なんて引数は受け取ってくれないことが判明しました。

```python:base.py
def __init__(self, main=None, loader=None, backend=None,
                 amqp=None, events=None, log=None, control=None,
                 set_as_current=True, tasks=None, broker=None, include=None,
                 changes=None, config_source=None, fixups=None, task_cls=None,
                 autofinalize=True, namespace=None, strict_typing=True,
                 **kwargs):
```

こんなところで詰まるのは私だけかもしれませんが、メモとして残しておきます。
誰かの役に立てば幸いです。
webpackを改めて調べた

## はじめに
webpack をなんとなく使っていて、ちゃんと理解していないなと思ったので改めて調べてみました。
備忘録として残します。

## webpack とは
「webpack」 = 「モジュールを束ねるツール」

「モジュールバンドラー」ともいう。

モジュールとは？
→プログラム内のJSファイルやsassファイル等のこと。

## webpackで何ができる？
下記の 1〜4 を全て1つのJSファイルにまとめてくれます。
1. 自分で書いたJS
2. ライブラリとして読み込んでいるJS
3. 2で読み込む必要があるCSS
4. 3で読み込む画像

## 何が嬉しいの？

「1つのJSファイルにまとめてくれる」とは、すなわち
**「JSファイルを細かく分けて管理ができるようになる」**
ということ。

1ファイル1クラスとか1ファイル1モジュールとか細かく分けて作れるようになる。

　↓
　↓ すると、こんな嬉しいことが！
　↓

- コードが読みやすくなる
- テストがしやすくなる（保守性が高い）
- 他のプロジェクトに転用しやすくなる
- 担当分担ができるようになる

しかも、HTML側が呼ぶファイルは1つにまとめたJSファイルのみ。
→ファイル読み込み時間の短縮にもなる。

## おわりに
webpackを改めて調べてみたら、すごく便利なものということがわかりました。
調べてスッキリした。
AWS FargateとEC2 c5.large系のコスト比較

Node.js を使う想定で、Docker コンテナを実行するインスタンスを AWS が管理してくれる Fargate と、従来の EC2 のコストを比較してみたところ、案外 Fargate も安かった。t2/t3 系以外のオンデマンドインスタンスを並べる用途なら、Fargate を選択してもコスト観点の問題はなさそう。（2019年6月）

＜シミュレーション条件＞

- node.js の 1プロセスあたり 1vCPU・メモリ 2GB を使う。
- 間欠実行するバッチ処理ではなくて、24時間稼働し続ける。
- 多数の node.js プロセスを並列実行して、負荷分散する構成。

![fargate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12419/66246fac-2afa-0eba-6c00-fa9bc342be8a.jpeg)

## ＜価格表＞

Fargate の価格表↓

|  | 料金 |
|:--|:--|
| per vCPU per hour | 0.05056USD |
| per GB per hour | 0.00553USD |

5セントとか0.5セントと言われても、さすがに比較しづらいので、『c5系・t2系を1台、24時間稼働させた場合』の月額と、Fargate の月額を比較してみます。通信費などは除きます。

| vCPU | メモリ |  c5系 | c5系 | t2系 | t2系 |Fargate |
|--:|--:|:--|--:|:--|--:|--:|
| 1 | 2GB | なし | - | t2.small | $22 |$44 | 
| 2 | 4GB | c5.large | $77 | t2.medium | $44 | $89 |
| 4 | 8GB |  c5.xlarge | $154 | なし | - |$177 |
| 8 | 16GB | c5.2xlarge | $308 | なし | - |$355 | 
| 16 | 32GB |  c5.4xlarge | $616 | なし | - |$710 |

※ 2019年6月現在。東京リージョン。

## ＜価格差まとめ＞

- Fargate は、t2 系の +100% 増し。
- Fargate は、c5 系の +15% 増し。

## ＜用途別お買い得パターン＞

（１）t2/t3 系で済む用途の場合：

- Fargate を使うよりも、t2/t3 系を使ったほうが、だいぶ安い。（半額）

（２）非 t 系が必要で、リザーブドインスタンス・スポットインスタンスが使える場合：

- Fargate を並べるより、c5 を並べた方が、だいぶ安い。

（３）非 t 系のオンデマンドインスタンスが必要で、プロセス数が8本未満の場合：

- Fargate でも c5 系でも、大差ない。

（４）非 t 系のオンデマンドインスタンスが必要で、プロセス数が9本以上の場合：

- 台数を抑えたまま『L→XL→2XL→4XL』とスケールアップさせる方針は、無駄できるのでイマイチ。
- c5.large の台数を2台→4台→8台→とスケールアウトさせる方針は、Fargate より 5〜15％程度安い。

## ＜参考ページ＞

- https://aws.amazon.com/jp/fargate/pricing/
- https://aws.amazon.com/jp/ec2/pricing/on-demand/
- https://dev.classmethod.jp/cloud/aws/compare-fees-for-fargat-and-ec2-2019-1/

---

［追記］
https://qiita.com/nabeken/items/69b47e2d346a61d34176#考察 によると、vCPUが1でも実CPUが2つ見えるとのこと。シングルスレッドの node.js 生だと 2 CPU を使えないので、片方がガラ空きでも他方を使い切ってくれるのかは、不詳。
Javaの学習（０）

#はじめに
皆さんこんにちは。初投稿になります。

これからJavaの学習をしていくにあたり、学習の内容を忘備録としてここに記載していこうかと思います。
まずはQiitaの書き方から慣れていかないと…笑

#学習方法
今のところ主に下記の書籍を使っていこうかと思います。
「スッキリわかるJava入門　第2版」（著：中山清喬/国元大悟）

#今後の展望
基本的には文法などをまとめていこうかと思います。

普段の業務では使っていないのでのんびり投稿になると思いますが、温かい目で見守ってください。
よろしくお願いしますm(__)m
VS Codeでgrepしようとしたら文字コードでつまった

# 環境
- Windows 10
- VS Code v1.35.0

# 概要
```Ctrl``` + ```Shift``` + ```F```でワークスペースにあるファイルの文字検索、置換が行える。正規表現も使えるし、とても重宝していた。
しかし、デフォルト設定ままの場合、文字コードがUTF-8のファイルしかひっかからず、Shift-JISやEUC-JPが文字コードのファイルは抜け漏れてしまう。
# どういうこと？
別々の文字コードを使った同じ文字列のファイルを3個用意して...
![origin.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326103/fee29045-1c1f-d86e-2be4-0e622b55daa6.png)

日本語の「チト」で検索してみる。
![3file.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326103/b0a7f817-731a-9d9f-a0c2-1dcfd20af295.png)
引っかかるじゃん！とおもったけど...

UTF-8とEUC-JPのファイルを閉じて再度検索してみると、
![single.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326103/69ae1f50-4d9c-f7ec-8d59-1171b4643f5b.png)
EUC-JPでひっかからなくなった。
# なんで？
https://qiita.com/EbXpJ6bp/items/e6a0ed52bdcb60bfd145
>検索するときエンコードを自動的に判別しない問題

ここにすべてが書いてあった。
どうやら設定がデフォルトだと、全てのファイルの文字コードをUTF-8として開き、grepしているために引っかからない...とのことである。
だが、検索するとき文字コードを自動的に判別しないだけで、エディタでそのファイルの適切な文字コードで開けている状態であれば、UTF-8でなくても検索にはひっかかるようだ。上の例では、EUC-JPのファイルは、閉じて文字コードを指定しなかったためにUTF-8としてgrepし、ひっかからなかったが、Shift-JISのファイルはエディタ上でしっかりとShift-JISで指定してあげていたので、ひっかかった。

（基本的に半角アルファベットであれば、文字化けを起こすことはないので、grepに問題はないはず。）
![eng.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326103/b9727ca7-8ba3-d31e-ad07-fff980ff2d7b.png)
# 対策
日本語をgrepしたいときには、引っかからないので、どうにかして検索する。
## VS Codeでどうにかする
拡張子別には文字コードを指定できるようだけど、ファイルの量が膨大かつ、拡張子が同じでも文字コードが違うこともある環境だったのでそういうわけにはいかなかった。
今のところ、VS Codeで他ファイルと文字コードが異なるファイルをすべて開いて指定してあげるか、拡張子別に文字コードを指定するのを拡張子の数だけgrepする方法以外思いつかない。
ファイル数が少ない場合のみ有効。
面倒だし『VS Codeでどうにかする』のは正直オススメしない。

VS Codeだけで完結するなにか良い方法があれば教えてください。
## あきらめて他ツールでどうにかする
###TresGrep
http://hp.vector.co.jp/authors/VA055804/TresGrep/
文字コードが異なっていても問題なくgrepできた。
# 感想
grepするときだけ別のソフトを開くのもなんかバカバカしいので、複数の文字コードがあっても検索できるようになってほしい。

~~過去の作業に不備のあった可能性が...~~
__絶望と仲良く__
Python3で任意の範囲の整数の中の素数を全て求める。

こんにちは。今回も[Pythonのお勉強　問題集](http://python.rdy.jp/wiki.cgi?page=%CC%E4%C2%EA%BD%B8)というサイトの問題を解いてみたので、知識の整理を兼ねてアウトプットしたいと思います。
今回は、任意の範囲の整数の中の素数を全て求める問題です。
#素数を求める
**整数はその平方根よりも大きい素数では割ることができない**という性質があります。今回はこの性質を利用していきます。

```python:exmple.py
import math


prime_number_list = list()

def prime_number(start, end):
    for i in range(start, end+1):
        prime = True
        if i == 1:
            prime = False
        for j in range(2, math.floor(math.sqrt(i))+1):
            if i%j == 0:
               prime = False
               break
        if prime:
            prime_number_list.append(i)

    return prime_number_list

print(prime_number(2, 1000))
```
**math.sqrt**を利用してiの平方根を算出し、j（2~√i+1の間の整数）でiを割ることでiが素数か否かを判定し、primeをTrue or Falseにします。prime=Trueのときにiは素数なので、prime_number_listにappendします。
**iが1のとき**に関しては、iが素数と判定されると困る（1は2以上の整数で割り切れないため、prime=Trueと判定されてしまうから）ので、強制的にprime=Falseとセットしています。
###偶数を除外して処理スピードを速くする
一つ目のforループの時点で偶数を除外したいと思います。ただし、2は素数なので、startが1 or 2のときに2が素数になるようにセットしています。

```python:exmple.py
import math

prime_number_list = list()

def prime_number(start, end):

    ##追加
    if start < 3:
        prime_number_list.append(2)
    if start % 2 == 0:
        start = start + 1
    else:
        start = start

    ##1つずつスキップしてrangeを設定
    for i in range(start, end+1, 2):
        prime = True
        if i == 1:
            prime = False
            continue
        for j in range(2, math.floor(math.sqrt(i))+1):
            if i%j == 0:
                prime = False
                break
        if prime:
            prime_number_list.append(i)
    return prime_number_list

print(prime_number(1, 1000))
```
#おわりに
偶数を飛ばすときに2を素数判定させるのが冗長になってしまったので、そこを改善したいです。なにか意見があればコメントよろしくお願いいたします！
Djangoの初期データをfixtureで作成する

# 概要
Djangoでデータベースを利用する際に初期データが必要になる場合があります。
今回はfixtureを利用して初期データを作成し、データベースにインポートする手順について説明します。
以前作成したToDoアプリケーションに対して、fixtureを利用して初期データのインポートを行います。
[Djangoで作るToDoリスト](https://qiita.com/acecrc/items/a4302ca6cf0897c45302)

# 開発環境
開発環境は下記を利用しています。
Python 3.6.7
Django 2.1.8
SQLite 3.7.17

# GitHub
ベースにしたToDoアプリケーションは下記のURLになります。
https://github.com/acecrc/django-todo

今回fixtureを追加した物は下記の下記のURLになります。
https://github.com/acecrc/django-fixture

# Djangoの初期データをfixtureで作成する
## ToDoアプリケーションをGitHubからダウンロード
下記のコマンドでGitHubからベースとなるToDoアプリケーションをクローンしてください。

```
$ git clone git@github.com:acecrc/django-todo.git
$ cd django-todo
```

## 仮想環境の構築
下記のコマンドでpythonの仮想環境を構築してください。

```
$ virtualenv ~/eb-virt  
$ source ~/eb-virt/bin/activate  
(eb-virt) $ pip3 install -r requirements.txt  
```

## fixture用のディレクトリ作成
fixtureを保存するためのディレクトリを作成しましょう。
Djangoではfixture用のディレクトリは各アプリケーション内のfixturesディレクトリに作成するという決まりがあるため、下記のようにディレクトリを作成してください。

```
(eb-virt) $ mkdir todo/fixtures
```

```
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── README.md
├── requirements.txt
└── todo  #todoアプリケーションのディレクトリ
    ├── admin.py
    ├── apps.py
    ├── fixtures  #作成したディレクトリ
```

## fixtureファイルの作成
fixture用のディレクトリの中にfixtureファイルを作成しましょう。
fixtureはxml, yaml, jsonの3種類を使用することができます。
今回はfixture1.jsonというfixtureファイルを作成することとします。
5件分のToDoデータを作成してみましょう。

```todo/fixtures/fixture1.json
[
  {
    "model": "todo.todo",
    "pk": 1,
    "fields": {
        "todo": "todo1",
        "created_at": "2019-01-01T12:34:56.789Z",
        "updated_at": "2019-01-01T12:34:56.789Z"        
    }
  },
  {
    "model": "todo.todo",
    "pk": 2,
    "fields": {
        "todo": "todo2",
        "created_at": "2019-01-02T12:34:56.789Z",
        "updated_at": "2019-01-02T12:34:56.789Z"        
    }
  },
  {
    "model": "todo.todo",
    "pk": 3,
    "fields": {
        "todo": "todo3",
        "created_at": "2019-01-03T12:34:56.789Z",
        "updated_at": "2019-01-03T12:34:56.789Z"        
    }
  },
  {
    "model": "todo.todo",
    "pk": 4,
    "fields": {
        "todo": "todo4",
        "created_at": "2019-01-04T12:34:56.789Z",
        "updated_at": "2019-01-04T12:34:56.789Z"        
    }
  },
  {
    "model": "todo.todo",
    "pk": 5,
    "fields": {
        "todo": "todo5",
        "created_at": "2019-01-05T12:34:56.789Z",
        "updated_at": "2019-01-05T12:34:56.789Z"        
    }
  }
]
```

## マイグレーションの実施
fixtureファイルからデータをインポートする前に、データベースのテーブルを作成する必要があります。
下記のコマンドでデータベースのテーブルを作成してください。

```
(eb-virt) $ python3 manage.py migrate
```

## 初期データの読み込み実施
fixtureファイルからデータをインポートするために下記のコマンドを実行してください。
インポートに成功すると「Installed 5 object(s) from 1 fixture(s)」というメッセージが表示されます。

```
(eb-virt) $ python3 manage.py loaddata fixture1.json
Installed 5 object(s) from 1 fixture(s)
```

## アプリケーションの起動
アプリケーションを起動するため下記のコマンドを実行してください。

```
(eb-virt) $ python3 manage.py runserver 8080  
```

## 動作確認
ブラウザでToDoの一覧を表示させてみましょう。
http://127.0.0.1:8080/todo/list/
下記のように5件のToDoが表示されていれば成功です。

![django-fixture_list.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131520/43b40c72-7a1e-8f6f-bd91-4fab1ec89363.png)

以上
Microsoft FlowでGraphを叩いて結果をCSVに入れるまで

本稿ではタイトルの通りMicrosoft Flowで叩いたGraphの結果をCSVに出力する方法を記載します。

出来上がったFlowは以下のようになります。
![コメント 2019-06-13 042443.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/7355f686-5771-25e1-d82d-125a90691586.png)
Microsoft FlowからGraphを叩いてJSONを受け取り取り解析するところまでは前出の
[Microsoft FlowでGraphを叩いて結果をExcelに入れるまで](https://qiita.com/hazigin/items/646d57fe9feefbd24da8)
と同じになりますので本稿では割愛します。

MicrosoftFlowでCSVを作成するにはCSVテーブルを作成しそれをファイルに保存するというステップをFlowに定義していくことになります。
ポイント(であると同時にはまったところ)はExcelの時と同じように「Apply to each」の扱い方でした。
![コメント 2019-06-13 042416.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/0e30bc9b-f123-5430-fd4f-cb8727c5ac71.png)
Flowへの定義の順序としては「JSONの解析」を定義の後に
1.「CSVテーブルの作成」アクションを追加、「開始」に「value」を設定。
2.「Apply to each」が自動的に設定される。
3.自動的に設定された「Apply to each」の中の「CSVテーブルの作成」の後に「ファイルの作成」を追加する。

となります。
「CSVテーブルの作成」について。
「CSVテーブルの作成」ではヘッダーを追加するということも出来ますが、今回は上手くいきませんでした。
理由はヘッダーを追加しヘッダーを定義、値を設定していくと「Apply to each」が自動で追加され、「Apply to each」のネストされます。
するとCSVが行毎に生成される結果となりひとまとまりのCSVとして作成されませんでした。
結果、ヘッダは無いものの連続したデータを取得できる今の形に落ち着きました。

また「列」を「自動」にしてテストを実行すると「カスタム」に変わり、自動で全列が定義されます。一旦テスト的に実行、その後に欲しいカラムだけ残した結果がキャプチャです。
![コメント 2019-06-13 044221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/bfe8dd99-ed57-ac0a-dcfe-554da66d79d1.png)

CSVファイルは時系列に結果を残したいというケースではファイル名を作成時間とすることも多いかと思います。
その際はファイル名に「動的なコンテンツの追加」の式で

```
formatDateTime(utcnow(),'yyyy-MM-dd_hh_mm_ss')
```
と入力、その後にキャプチャのように「.csv」を追加すると目的通りのファイル名が得られます。
What is class in python

*A memorandum for myself. Focused on understanding at the cost of accuracy.*

# *class* is
**A blue print for creating objects.**

# Introduction
As introduced in [the previous post](https://qiita.com/li-li-qiita/items/b8fe50d29fa60d421d35), object is a package of methods and data. `class` is a blue print or template to create those objects. Every time you call a `class`, you will create a new object (which is called `Instance`.

# Example
```class.py
# declare that this is a blue print of "glass_of_water"
class glass_of_water: 
    # first, you have water as your data
    my_data = 'water'
    # this is called attribute

    # then, define the method
    def pour(self):    
        # this is the actual action of the method
        print('pour ' + self.my_data)   
```

Let's try to run this code.
First, create an object with the blue print of `glass_of_water`.

```python
object1 = glass_of_water()
```
Now you run it.

```python
>>> object1
<__main__.glass_of_water at 0x7f7fb0a76198>
```
You get nothing because you didn't specify what to do, i.e. the method.
Let's do it again.

```python
>>> object1.pour()
pour water
```

# Reference
https://www.hackerearth.com/practice/python/object-oriented-programming/classes-and-objects-i/tutorial/
https://qiita.com/lamplus/items/351145a81f798ecec80b
https://qiita.com/hiroyuki_mrp/items/140d47df01553091d59a