OmniAICreator/Qiita-1.07M huggingface dataset:
PHP 配列に連想配列を入れる

# 目的

- 配列の中に連想配列を入れる方法をまとめる

# 実施環境

- MacOS上のローカル環境にテスト用スクリプトファイルを作成してVisual Studio Codeのデバッグを用いて結果を確認した。
- 下記にVisual Studio CodeでPHPのデバッグ環境を構築する際の手順をまとめた記事へのリンクを記載する。
    - [https://qiita.com/miriwo/items/e0a41308e042e34ebf78](https://qiita.com/miriwo/items/6edd6e1817def4fc11d5)
- 下記に実施環境の詳細な情報を記載する。

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook  Air (11-inch ,2012) |
| プロセッサ | 1.7 GHz デュアルコアIntel Core i5 |
| メモリ | 8 GB 1600 MHz DDR3 |
| グラフィックス | Intel HD Graphics 4000 1536 MB |

# PHPの配列の書き方

- 下記に筆者がまとめた記事へのリンクを記載する。
    - [PHP 配列まとめ](https://qiita.com/miriwo/items/728a3deb59661b1c5b4b)

# PHPの連想配列の書き方

- 下記に筆者がまとめた記事へのリンクを記載する。
    - [PHP 連想配列まとめ](https://qiita.com/miriwo/items/e0a41308e042e34ebf78)

# 書き方の例(配列を連想配列に格納する)

- 下記に配列`$test`に連想配列('num1' => 10, 'num2' => 20, 'num3' => 30)を格納する方法をまとめる。
- 下記が実行されると配列`$test[0]`には'num1' => 10, 'num2' => 20, 'num3' => 30の連想配列が格納される。

    ```php
    $test = [
        [
            'num1' => 10,
            'num2' => 20,
            'num3' => 30
        ]
    ];
    ```

# 書き方の例(配列に入った連想配列を出力する)

- 先の「書き方の例(配列を連想配列に格納する)」のコードを引き継いで説明する。
- `配列名[インデックス番号][連想配列のキー]`と言うように指定することで格納された値を得ることができる。
- 配列`$test`のnum1~num3の値を出力したい時の例を下記に記載する。

    ```php
    $test = [
        [
            'num1' => 10,
            'num2' => 20,
            'num3' => 30
        ]
    ];
    #---これより上は「書き方の例(配列を連想配列に格納する)」のコードと一緒---#

    # num1を出力する
    echo $test[0]['num1'];

    # num2を出力する
    echo $test[0]['num2'];

    # num3を出力する
    echo $test[0]['num3'];
    ```

# 書き方の例(配列に入った連想配列の末尾にデータを追加する)

- 先の「書き方の例(配列を連想配列に格納する)」のコードを引き継いで説明する。
- `array_push(配列名,末尾に追加するデータ`と言うように指定することでデータを追加することができる。
- 下記に配列`$test`の末尾に連想配列('num1' => 40, 'num2' => 50, 'num3' => 60)を格納する方法をまとめる。

    ```php
    $test = [
        [
            'num1' => 10,
            'num2' => 20,
            'num3' => 30
        ]
    ];
    #---これより上は「書き方の例(配列を連想配列に格納する)」のコードと一緒---#

    array_push($test, [
        'num1' => 40,
        'num2' => 50,
        'num3' => 60
    ]);
    ```
shortcut.jsでshortcut.removeしてもコールバック関数がイベントに登録されたままになる

## 環境

os : Windows 7

## バグ内容

以下のコードで`ctrl + s`を押したら`2つ目`と表示されてほしいのに両方のアラートが連続して表示されてしまう。

``` javascript
shortcut.add('ctrl+s', function(){
  alert('1つ目');
});
shortcut.remove('ctrl+s');

shortcut.add('ctrl+s', function(){
  alert('2つ目');
});
```

## 修正方法

[shortcut.js](http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js)
上記リンクがコード全体ですが219行目と220行目を入れ替えれば直ります。

``` patch
shortcut.remove
-		if(ele.detachEvent) ele.detachEvent('on'+type, callback);
-		else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
+		if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
+		else if(ele.detachEvent) ele.detachEvent('on'+type, callback);
 		else ele['on'+type] = false;
 	}
 }

```

## バグの理由

`shortcut.add`では`addEventListener`のチェックを先に行っているのに`shortcut.remove`ではそ`detachEvent`のチェックを先に行っていて対応した`add`と`remove`になっていないため。

``` javascript
// shortcut.add
if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
else ele['on'+opt['type']] = func;

// shortcut.remove
if(ele.detachEvent) ele.detachEvent('on'+type, callback);
else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
else ele['on'+type] = false;
```

## 気づいた経緯

[【HTA】【jquery】【Marked】Markdown版ローカルwiki(v1.6)](http://kazu-s-diary-2.cocolog-nifty.com/blog/2016/07/htajquerymark-1.html)
[MarkdownLocalWiki](https://github.com/ma34s/MarkdownLocalWiki)

上記をフォークしてwiki編集モードでのみ`ctrl + s`で保存できる機能を追加していました。
編集モード移行時に`shortcut.add`、それ以外に移行したら`shortcut.remove`として制限を掛けていたのですが2回以上保存されることがありバグに気づきました。

## その他

このことを本家に伝えたいのですが英語力が皆無なためQiitaに投稿しました。

## リンク一覧

- [shortcut.js](http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js)
- [【HTA】【jquery】【Marked】Markdown版ローカルwiki(v1.6)](http://kazu-s-diary-2.cocolog-nifty.com/blog/2016/07/htajquerymark-1.html)
- [MarkdownLocalWiki](https://github.com/ma34s/MarkdownLocalWiki)
- [自分のMarkdownLocalWiki](https://github.com/hachimitu22/MarkdownLocalWiki)
AWS CDKに触れてみる

# はじめに
CDKを使ってLambdaを作成してみるところまでを目標とします。

# 環境
今回はCloud9を使用します。

```
$ python --version
Python 3.6.10
$ cdk --version
1.27.0 (build a98c0b3)
```

CDKが入っていなければ以下のコマンドでインストールします。

```
$ npm install -g aws-cdk
```

# やってみる

## CDKを使う準備
まずCDKを使うために色々準備します

### プロジェクトフォルダを作成

```
$ mkdir hogehoge
$ cd hogehoge
```

### CDKの初期設定
初期設定をします

```
cdk init --language python
source .env/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
```

AWSユーザーデータの利用設定も行う

```
$ cdk bootstrap
   Bootstrapping environment aws://999.../ap-northeast-1...
   Environment aws://999.../ap-northeast-1 bootstrapped (no changes).
```

これで準備完了です

## CDKを使ってみる
Lambdaを作成していきます

### pythonファイルの準備
Lambdaで使用するpythonファイルを準備します

```
$ mkdir lambda
$ touch lambda/index.py
```

内容はあまり気にしないので適当に

```index.py
import json

def handler(event, context):
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

### スタックを作成

最初に作成した`hogehoge`ディレクトリ下に`hogehoge/hogehoge_stack.py`があるので、ここにリソースを作成するためのコーディングをしていく。
[公式](https://docs.aws.amazon.com/cdk/api/latest/python/index.html)が丁寧でわかりやすい。

```hogehoge_stack.py
import aws_cdk.core as core
import aws_cdk.aws_lambda as aws_lambda

class HogehogeStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        lambda_func = aws_lambda.Function(
            self, 'lambda_func1',
            function_name = "lambda_func1",
            runtime = aws_lambda.Runtime.PYTHON_3_8,
            code = aws_lambda.Code.asset('lambda'),
            handler = 'index.handler'
        )
```

```
$ echo "aws-cdk.aws-lambda" >> requirements.txt
$ pip install -r requirements.txt
```

### AWSリソースの作成

```
$ cdk diff
$ cdk deploy
```

作成完了！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52392/bf693042-b82c-22e0-eb2a-2206a4446220.png)

```
$ cdk destroy
```
消えた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52392/39c711de-8f0f-c4f2-1c84-ed558c0727cb.png)

## 後処理
pushするならしちゃいましょう

```
$ git add .
$ git remote add origin [作成済みのリポジトリを使用]
$ git push -u origin master
```

## まとめ
色々設定しなきゃいけないのかな、と思っていましたが結構簡単に作れちゃうのがいいですね。
他の環境作成ができるサービスとの住み分けはどんな感じなんでしょうかねー

## 補足
複数のstackを作成するには`app.py`を編集する必要があります

```app.py
HogehogeStack(app, "stack_hogehoge")
FugafugaStack(app, "stack_fugafuga") # こんな感じ
```

複数のstackを作成した場合には`cdk deploy`だと怒られるので以下のように書く

```
$ cdk list
stack_hogehoge stack_fugafuga
$ cdk deploy stack_*
```
PIX-MT100に関するメモ

コロナのせいで品薄とか・・・

# Web管理画面で表示されている情報を取得する方法

下記URLを叩くだけ。
JSONじゃなくてシェルでどうぞ！って感じのKey=Value形式できた。

```shell-session
$ curl "http://192.168.0.1/cgi-bin/sysconf.cgi?page=ajax.asp&action=get_status"
3GPP.IMSI=44010321324xxxx
3GPP.UICC-ID=898110005590249xxxx
3GPP.IMEI=35891604636xxxx
3GPP.IMEISV=358916046363xxxx
3GPP.MSISDN=0201795xxxx
3GPP.SINR=4
3GPP.RSSI=-67
3GPP.RSRP=-85
3GPP.RSRQ=-11
3GPP.MCC=440
3GPP.MNC=10
3GPP.PLMN=44010
3GPP.RoamingStatus=0
3GPP.CGI=440102DBC652
3GPP.CI=2DBC652
3GPP.eNBID=2DBC6
3GPP.HNBN=
3GPP.CSGT=
3GPP.CenterFreq=1870000
3GPP.Band=3
3GPP.TxPWR=76
3GPP.SPN=DOCOMO
3GPP.IsIdle=1
InterfaceType=lte
DeviceName=4G Modem
RfVersion=32
AsicVersion=43920
FirmwareVersion=00.00.95.1000 (03/01/2017)
State=Connected
ConnectedTime=108
SessionID=1
IP=100.105.130.xxx
SubnetMask=255.255.255.240
DefaultGateway=100.105.130.17
DHCP=192.168.0.1
DNS=59.190.146.81,59.190.147.17
SentBytes=0
ReceivedBytes=681
MaxDownlinkThroughput=0
MaxUplinkThroughput=0
CurDownlinkThroughput=0
CurUplinkThroughput=0
TotalHandoversCount=0
SucceededHandoversCount=0
WebGuiUrl=
UpdateState=NotStarted
UpdateProgress=0
IsReadyForUpdate=0
SupportsConnectDisabling=0
WifiStatus=On
WifiShareMode=Normal
WifiSecurityMode=Enabled
WifiUsers=0
Firmware_Version=00.00.95.1000 (03/01/2017)
simStatus=READY
System_Uptime=154
```
【heroku】laravelをherokuでデプロイ(github 連携、MySQL使ってる)【heroku #とは】

heroku git でデプロイしてDBを使う方法はたくさん出てくるのですが、
herokuとgit hubを連携してデプロイするのに結構苦労したのでまとめ


間違ってたら教えてください、、、、

#前提

- githubにデプロイしたいアプリケーションがあること
- herokuのアカウントがある


#herokuに新しくappを作る

herokuにログインして、
右上の**new**から**create new app**を選択します。

<img width="1271" alt="スクリーンショット 2020-03-18 23.36.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490844/06b8c483-6570-d413-658e-6524a7ac1393.png">

そしたら、名前を入力する画面が出てくるので、好きな名前を入力してcreat appをポチッ！！！！！！

そうするとappができます。

#githubと連携する

create appのボタンを押すとそのまま下の画面に行くと思うので、
Deployタブの**Deployment method**のところにある**github**を選択します。
<img width="1271" alt="スクリーンショット 2020-03-18 23.39.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490844/9ca06abc-2b8a-4300-7ae1-faf855ca6af2.png">

そうすると、下の方に連携するgithubのレポジトリを選択する画面みたいなのが出てくるので、
連携するレポジトリを選びます。
(githubの連携がはじめての時はアカウント連携みたいなのがある)

#clearDBをくっつける

上の**Resources**タブに移動して**add-ons**から検索でcleardbを見つけて追加します。

無料のやつか有料のやつかみたいなの聞かれるんで無料のやつでいいと思います。

あと、クレカ登録してないとaddon追加できないので、クレカも登録しておくよー！


#環境変数追加

必要な環境変数を追加します。
**settings**タブを押して、**Config Vars**から環境変数を追加します。

環境変数は、laravelだと　**.env** 、Railsだと**.bash_profile**に書いてあるやつです。

私laravelしかわからないのでlaravelで必要な環境変数は


- APP_KEY
- APP_ENV
- LANG 
- TZ 

こんな感じだと思います。
S3とか使ってたらもっと増えるけど

LANGは使用する言語なので、ja_JP.UTF-8
TZはタイムゾーンなのでAsia/Tokyo

後は.envをみて入れてね



あと、**CLEARDB_DATABASE_URL**という環境変数が入ってたと思うのですが、
これはさっきcleardbを追加した時に自動で入れてくれたものです。

なので右側はほったらかしで、左だけ
**CLEARDB_DATABASE_URL**から**DATABASE_URL**に変更する
(laravelの方の環境変数がDATABASE_URLなので)


#migrateする

###herokuにログイン

そうしたら、ターミナルでデプロイするレポジトリに移動して

` $ heroku login`

でherokuにログインします。

###herokuのappと連携

ローカルのレポジトリと、さっき作ったherokuのappを紐付けます。

`$ heroku git:remote --app APPNAME`


これでOK


###migrateを実行

`$ heroku run php artisan migrate`

migrationを実行して、マイグレーションファイルが全て実行されたことを確認

#デプロイする

**Deploy**タブから下のほうに行くと
**Deploy Branch**ボタンがあるのでポチッと押すとデプロイされます


<img width="1271" alt="スクリーンショット 2020-03-19 0.20.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490844/f9388155-ff8d-6574-02b6-96ff053ee014.png">


#多分みれる！！！！！！！

heroku gitじゃなくてgithub連携すると、piplinesが使えるからいいのかな、
(heroku gitでも使えるのかな)

 何か抜けてたら教えてください、、、、、
Wordpressでプラグインを使わずに関連記事を表示する方法 2020年版

関連記事は、関連度やタグもカテゴリも含むなど高度な設定が必要な場合はプラグインを使ったほうが早いかも。

ここでは簡単な関連記事の取得方法をまとめる。

## プラグイン使わず関連記事を実装
functions.phpに以下のコードを追記。

```php
// functions.php
function my_get_related_posts( $post_id, $related_count ) {
  // 記事のカテゴリを取得、タグでも可
  $terms = get_the_terms( $post_id, 'category' );
  
  if ( empty( $terms ) ) $terms = array();
  
  // カテゴリ一覧のslugを作成
  $term_list = wp_list_pluck( $terms, 'slug' );
  
  // クエリの設定、投稿タイプはパラメータで変更できるようにしても良い
  $related_args = array(
    'post_type' => 'post',  // 投稿タイプ
    'posts_per_page' => $related_count, // 表示数
    'post_status' => 'publish', // 公開されてるもののみ表示
    'post__not_in' => array( $post_id ),  // 現在の記事を含めない
    'orderby' => 'rand',  // ランダム、DESCで新着順に変更可能
    'tax_query' => array(
      array(
        'taxonomy' => 'category', // カテゴリから取得
        'field' => 'slug',  // $term_listでslugとってるので合わせる
        'terms' => $term_list // カテゴリ一覧のslugを渡す
      )
    )
  );
  return new WP_Query( $related_args );
}
```

## テンプレートに関連記事
あとはテンプレートの表示したい位置にループ処理を書き込むだけ。

```php
<h1>関連記事</h1>
<ul>
<?php
global $post;
$wp_query = my_get_related_posts( $post->ID, 6 );
if ($wp_query->have_posts()) : while ($wp_query->have_posts()) : 
  $wp_query->the_post(); ?>

    <li>
      <a href="<?php echo get_permalink(); ?>">
        <img src="<?php echo get_the_post_thumbnail_url(); ?>" alt="<?php echo get_the_title(); ?>">
        <p><?php echo get_the_title(); ?></p>
      </a>
    </li>

<?php endwhile; endif; wp_reset_postdata(); ?>
</ul>
```
node.js @line/bot-sdk を使ってAWS lambdaからLINE Messaging APIのpushMessageを使用する時に1時間位右往左往した時の話


https://developers.line.biz/en/reference/messaging-api/#send-push-message
にて

```
const line = require('@line/bot-sdk');

const client = new line.Client({
  channelAccessToken: '<channel access token>'
});

const message = {
  type: 'text',
  text: 'Hello World!'
};

client.pushMessage('<to>', message)
  .then(() => {
    ...
  })
  .catch((err) => {
    // error handling
  });
```

でいけよ、
みたいに書かれていたので、
自分のパソコンからこれを適宜当てはめたら、
普通にpush出来たので、意気揚々とAWS lambdaで使用したら、
なんかエラー出ていた。

connectionが確立されてないよ、
とか言われたけど、なぜそんなエラーがlambdaの時だけ返ってくるのか、
意味が分かってないので、どうしたら良いのか悩んでいたのですが、
試しに、async/await形式にしたら、うまく行きました。という小話です。

結局意味は分かってないのですが、
多分、他の関数で非同期的な処理行うために、関数の頭にasyncを記述しているのに、
`client.pushMessage`をawaitしてなかったからだと思う。
とりあえず動いています。
以下、実際に動いているコード。

```
exports.handler = async function (event){
  const line = require("@line/bot-sdk");
  const config = {
    channelAccessToken: "aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQ",
  }

  const client = new line.Client(config);

  await client.pushMessage("000011112222333344445555666677777",{type:'text',text:'hello!'});
}
```
[Oracle Cloud] Key Management を Object Storage から使って、暗号化してみた

# はじめに

Oracle Cloud Infrastructure(以下OCI)では、Object Storage を提供しています。Object Storage は、何も意識しないで作成すると Oracle 側で管理されている Key でデータの暗号化がされます。Key Management と連携することで、他のキーを使用して暗号化が出来、セキュリティの強化が出来ます。
さらに、ユーザー側で独自に作成した Key を Key Management に Import することで、Oracle 側が Key を生成していない状況を作れます。Oracle 側が Key を持っていないため、ユーザーでしかデータを復元できません。

今回の記事では、Object Storage から Key Management の Key を使用してデータを暗号化する方法を紹介します。



# IAM Policyの設定

Object Storage などの他のサービスから、Key Management を利用するためには、IAM Policy の設定が必要です。サービス同士の連携で IAM Policy が必要なのは面白い概念ですね。

以下のような Policy を設定します。Object Storage の Region は、使用する Region に合わせて適宜変更してください。リージョン名は[こちら](https://docs.cloud.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm)に一覧で書かれています。

```
Allow service blockstorage, objectstorage-ap-tokyo-1, objectstorage-ap-osaka-1, FssOc1Prod, oke to use keys in tenancy
```



![1584542605256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/09a6621b-10c3-cffb-c4d8-4ab62ddab389.png)



# Bucket の作成

Object Storage で Bucket を作成するときに、Key を指定します。もちろん、作成後でも Key の変更が可能です。

Create Bucket を押します

![1584542695090.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/722699f1-28e0-05a9-e46e-5cdf017f0327.png)



適当にパラメータを入力します。ENCRYPT USING CUSTOMER-MANAGED KEYS を選択して、 Key Management 上の Key を指定しています。

![1584542779525.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/cc74ec82-c1dd-3b6c-11ea-669ee6d3cc53.png)



これで、指定した Key でデータが暗号化された Bucket が出来ました。

![1584542988194.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/cbc19775-be75-617f-8181-581988d4e947.png)



# 別のキーを割り当てて、再暗号化

Key Managent 上で別の Key を生成して、Object Storage に紐づけができます。別の Key で再度暗号化することで、Key の漏洩に対してセキュリティを高める効果があります。

再暗号化をするために、最低でも1個以上の Object をアップロードが必要です。適当にアップロードしたあとに、Encryption Key を Edit します。

![1584543804491.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/1018d8f6-c4e6-3ff2-ce02-84bffcc23697.png)



新しい Key2 を指定します。

![1584543820358.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/7f551ec9-6f01-d6ee-61e7-ef4ea0da26c1.png)



新しい Key で再度暗号化をするには、Re-encrypt を押します

![1584543869543.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/28a86f91-58fe-8e32-737f-72a0255703d1.png)



Re-encrypt

![1584543907225.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/1845459a-fbf4-23db-efb2-61c0514bc26c.png)



Work Request の画面で、再暗号化の進捗を確認できます。

![1584543943363.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/4c63b2c0-40e1-5960-07a9-5a7e6bd0dc40.png)



Completed になっていることを確認できます

![1584543977899.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/6465753b-e0f2-b6e4-2529-babc634b0feb.png)



# 参考URL

https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Concepts/commonpolicies.htm#services-use-key
UiPathのディレクトリ構造について考える

# UiPathでディレクトリ構造を考えることは必要か？

個人的には非常に重要だと考えています。
それは、管理コストが下がるからです。

例えば、以下のようなフォルダ構造があったとしましょう。

```
プロジェクト:
    ├─Webアプリケーション
    ├─システム
    ├─入力
    ├─処理
    ├─出力
    ├─経理
    ├─総務
    └─設定
```

あなたは、「経理部が持つ社内システムに領収書を提出し、総務部が持つWebアプリケーションへ経理申請したことを記録する」といった処理が書かれたワークフロー（xamlファイル）を探しているとします。
おそらく、色々なフォルダを開きながら探すことになるでしょう。

そういったコストを下げるためにディレクトリ構造を考えることが必要なのです。

# ディレクトリ構造を考える

ディレクトリ構造は以下の条件を満たさなくてはいけません。

- ディレクトリ名から中身が予想できる
- 階層が深すぎない
- 適度に抽象化されている

一番シンプルなディレクトリ構造の例は下記のようなものでしょうか。

```
プロジェクト:.
│  Config.xlsx
│  GlobalHandler.xaml
│  Main.xaml
│  _Test.xaml
│  
├─Data
│  ├─Input
│  │      Input.xlsx
│  │      
│  └─Output
│      ├─20200317
│      └─20200318
├─Docs
│      要件定義書.pdf
│      設計書.pdf
│      
├─Lib
│  │  LibraryA.xaml
│  │  LibraryB.xaml
│  │  
│  └─Test
│          _Test_LibA.xaml
│          _Test_LibB.xaml
│          
├─Src
│  ├─ResistrationProcess
│  │  │  SystemA.xaml
│  │  │  
│  │  └─Tmp
│  │          Cache.txt
│  │          
│  └─CheckingProcess
│          Customer.xaml
│          
└─Test
        _Test_ProcessA.xaml
        _Test_ProcessB.xaml
```

ルートには、メインワークフローや設定ファイルやグローバルハンドラ、総合テスト用のワークフローなどがあります。
Libフォルダには各処理で共通利用するライブラリが入っています。
Srcフォルダには実際の処理が各工程毎に入っています。
Testフォルダにはワークフローの単体テストを行うためのワークフローが入っています。
Dataフォルダには様々なデータを入れます。
Docsフォルダには設計書や要件定義書など関係する書類をとりあえず入れましょう。

上の例はあくまでも簡単な例であるため、業務で使用する場合はもっと精査する必要がありますが、なんとなく「ここにはこれを入れればいいんだろうなー」とか感じられるはずです。

なんとなくでファイルを探せるということは、管理コストが少なくて済みます。
また、ワークフローの品質を高めるという点でも、コーディング規約などと合わせて定義しておくとよいでしょう。
EC2インスタンスからAWS CLIを実行する際にはインターネットアクセスかエンドポイントが必要

個人的メモになります

#もう一度言いますが、インターネットアクセスかエンドポイントが必要です。

## 対応策

1. EC2インスタンスにパブリックIPを付与する
1. NATゲートウェイを使用する
1. エンドポイントを使用する

## EC2インスタンスにパブリックIPを付与する

-　自動割り当てパブリック IPを利用
-　ElasticIPを付与

パブリックサブネット上に踏み台サーバを配置する構成は、最近は少ないのではないだろうか

## NATゲートウェイを使用する
プライベートサブネット上のEC2インスタンスではこちらの構成
ただ、アウトバウンドを絞りたい為、簡単にインターネットに出れない場合も

## エンドポイントを使用する

CLIで実行するサービスのエンドポイントが必要

### EC2の場合
> インターフェースエンドポイント
> com.amazonaws.ap-northeast-1.ec2

### S3の場合
> ゲートウェイエンドポイント
> com.amazonaws.ap-northeast-1.s3

## 参考
[AWS PrivateLinkの使い方を解説する](https://blog.mmmcorp.co.jp/blog/2017/11/15/aws_privatelink/)
【Day32】積み上げ日記

##予定
■スキプラさんnote②

##完了
■スキプラさんnote②

##学習時間
２h

##学習ポイント
■サイトを作る際の思考順位
①箱の配置を決める
②箱の名前を決める
③箱の大きさを決める
④箱の中身を決めていく

■h1,2,3…タグにはmarginが設定されている。

■棒
borderで書くことできる。

■見出し文の下に線を引く
箱を作り、その中で線を作る。

##疑問点
○擬似要素 :before　が理解できていない。

##計画通り進んだか？
進んだ。だが、前回も一度触れた擬似要素がうまく咀嚼できず落とし込めていない。わかりやすく理解できるコンテンツをyoutubeで探してみる。
【今日のアブストラクト】Adam: A Method for Stochastic Optimization【論文 DeepL 翻訳】

1 日 1 回 (努力目標) 論文の Abstract を DeepL 翻訳の力を借りて読んでいきます.

この記事は自分用のメモみたいなものです.
ほぼ DeepL 翻訳でお送りします.
間違いがあれば指摘していだだけると嬉しいです.

翻訳元
[Adam: A Method for Stochastic Optimization](https://arxiv.org/abs/1412.6980)


# Abstract

### 訳文

低次モーメントの適応的推定に基づく確率的目的関数の1次勾配ベース最適化アルゴリズムである Adam を紹介する. この方法は実装が簡単で, 計算効率が高く, 必要なメモリが少なく, 勾配の対角線再スケーリングに不変で, データやパラメータが大きい問題に適している. この手法はまた, 非定常目的や, 非常にノイズの多い, あるいはスパースな勾配を持つ問題にも適してる. ハイパーパラメータは直感的な解釈が可能で, 通常はほとんどチューニングを必要としない. Adam がインスパイアされた関連アルゴリズムとの関連性がいくつか議論されている. また, アルゴリズムの理論的な収束特性を分析し, オンライン凸最適化フレームワークの下で既知の最良の結果に匹敵する収束率の regret 境界を提供する. 実証的な結果は, Adam が実際にうまく機能し, 他の確率的最適化手法と比較して有利であることを示している. 最後に, 無限大ノルムに基づく Adam の変形である AdaMax について説明する.


### 原文

We introduce Adam, an algorithm for first-order gradient-based optimization of stochastic objective functions, based on adaptive estimates of lower-order moments. The method is straightforward to implement, is computationally efficient, has little memory requirements, is invariant to diagonal rescaling of the gradients, and is well suited for problems that are large in terms of data and/or parameters. The method is also appropriate for non-stationary objectives and problems with very noisy and/or sparse gradients. The hyper-parameters have intuitive interpretations and typically require little tuning. Some connections to related algorithms, on which Adam was inspired, are discussed. We also analyze the theoretical convergence properties of the algorithm and provide a regret bound on the convergence rate that is comparable to the best known results under the online convex optimization framework. Empirical results demonstrate that Adam works well in practice and compares favorably to other stochastic optimization methods. Finally, we discuss AdaMax, a variant of Adam based on the infinity norm.
個人アプリ制作　＃2日目

投稿２回目にしてQiitaの使い方をマスターしましたkoudaiです。

調子乗りまし。

# 本日実施したこと
VScodeを使っていますがerb拡張子で補完機能が使えないのが寂しかったので探していたら見つけました。
　
ですが入力する場所がわからず、苦戦し、やっとの思いで使えるように・・・
４０分以上格闘していました。
でも、一ヶ月前の、何もわからない時では、一時間かけようが、ストレス溜まってやめてるだけです。
一ヶ月でここまで←（まだまだ）成長できたことは、嬉しいしもっと頑張って行きたい。

ちなみにその後bootstrapに苦戦して本日は、終了しました。

大いに伸び代あり😂
頑張っていこう
x-codeでiOSアプリを横画面対応させる

##主旨
iOSの実機を横向きにしたときに画面表示をその向きに対応させるための設定方法。
3つ設定する場所があります。

##1. General > Device Orientation
今回対応させたい向きにチェックを入れます。
<img width="862" alt="スクリーンショット 2020-03-18 23.53.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391115/2923f992-c649-6340-20e9-bcba5c25a3f8.png">

## 2. Info > Custom iOS Target Properties
+ボタンを押し、Supported interface orientationsの項目に今回対応させたい向きを入力します。
<img width="874" alt="スクリーンショット 2020-03-18 23.53.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391115/d1a67db1-7f6f-164a-fc91-7ba861c238b6.png">

## 3. 実機の向き固定の解除
実機の画面固定項目の解除も忘れずに
![IMG_2022.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391115/942f19ef-6c57-5622-995e-794c3b0c6e05.jpeg)
シェルスクリプトで今日の天気予報を見る

# はじめに

シェルスクリプトの練習として、Livedoorの天気予報APIである[Weather Hacks](http://weather.livedoor.com/weather_hacks/webservice)を使って「今日の天気」を調べるスクリプトを作ってみました。

また、所望の地点における天気予報が見られるように、地名を指定して天気予報が見られるようにしてみました。

# スクリプト

## 概要

* 天気予報が公開されている地名のリストである[全国の地点定義表](http://weather.livedoor.com/forecast/rss/primary_area.xml)はXML（RSS）形式ですが、シェルスクリプトでXMLをサクッとパースする方法が見つからなかったので、`sed`コマンドで不要な部分をゴリゴリと削っています。
* 引数で指定した地名が「全国の地点定義表」に存在する時は、その地点の今日の天気をJSON形式で取得して、`jq`コマンドで解析した結果を表示しています。
* 引数で指定した地名が「全国の地点定義表」に存在しない時は、「全国の地点定義表」に定義されている地点名を一覧表示します。

## 使い方

* 以下の`weather.sh`を実行する際に、引数として所望の地名を指定します。

```bash:weather.sh
#!/bin/bash
# http://weather.livedoor.com/forecast/webservice/json/v1?
​
# 全国の地点定義表（RSS）から、入力された地名と合致する地点名とIDを抽出する。
# http://weather.livedoor.com/forecast/rss/primary_area.xml
cityname_id=$(curl -s http://weather.livedoor.com/forecast/rss/primary_area.xml \
    | sed "s/>/>\n/g" \
    | grep city \
    | sed "s/<city title=\"//g" \
    | sed "s/\" source.*>//g" \
    | sed "s/\" id=\"/,/g" \
    | grep $1) \
​
# 該当する地名が存在する時は、その都市の天気予報を取得する。
# 該当する都市が存在しない時は処理を終了する。
if [ -z "$cityname_id" ]; then
    echo 「$1」の天気予報は提供されていません。以下の都市から選択してください。
    echo ----------------------------------------
    echo $(curl -s http://weather.livedoor.com/forecast/rss/primary_area.xml \
        | sed "s/>/>\n/g" \
        | grep city \
        | sed "s/<city title=\"//g" \
        | sed "s/\" id.*>//g")
else
    # {地点名,ID}の文字列からIDだけ抜き出す。
    city_id=$(echo $cityname_id | sed "s/.*,//g")
    city_name=$(echo $cityname_id | sed "s/,.*//g")
​
    echo $city_nameの今日の天気： \
        $(curl -s http://weather.livedoor.com/forecast/webservice/json/v1?city=${city_id} \
            | jq '.forecasts[]' \
            | jq -r 'select(.dateLabel=="今日").telop')
fi
```

## 実行結果

```shell:実行結果（指定した地名の天気予報が存在する時）
[root@akagi ~]# ./weather.sh 東京
東京の今日の天気： 晴れ
```
```shell:実行結果（指定した地名の天気予報が存在しない時）
[root@akagi ~]# ./weather.sh ペンギン村
「ペンギン村」の天気予報は提供されていません。以下の都市から選択してください。
----------------------------------------
稚内 旭川 留萌 網走 北見 紋別 根室 釧路 帯広 室蘭 浦河 札幌 岩見沢 倶知安 函館 江差 青森 むつ 八戸 盛岡 宮古 大
船渡 仙台 白石 秋田 横手 山形 米沢 酒田 新庄 福島 小名浜 若松 水戸 土浦 宇都宮 大田原 前橋 みなかみ さいたま 熊
谷 秩父 千葉 銚子 館山 東京 大島 八丈島 父島 横浜 小田原 新潟 長岡 高田 相川 富山 伏木 金沢 輪島 福井 敦賀 甲府 河口湖 長野 松本 飯田 岐阜 高山 静岡 網代 三島 浜松 名古屋 豊橋 津 尾鷲 大津 彦根 京都 舞鶴 大阪 神戸 豊岡 奈良 風屋 和歌山 潮岬 鳥取 米子 松江 浜田 西郷 岡山 津山 広島 庄原 下関 山口 柳井 萩 徳島 日和佐 高松 松山 新居浜 宇
和島 高知 室戸岬 清水 福岡 八幡 飯塚 久留米 佐賀 伊万里 長崎 佐世保 厳原 福江 熊本 阿蘇乙姫 牛深 人吉 大分 中津 日田 佐伯 宮崎 延岡 都城 高千穂 鹿児島 鹿屋 種子島 名瀬 那覇 名護 久米島 南大東 宮古島 石垣島 与那国島
```

# まとめ

* 簡単にXMLをパースする方法が見当たらなかったため、力任せなコードになってしまいました。
 * 無理してシェルスクリプトで頑張らずに、RubyやPythonなどを使った方が可読性の高いコードになるだけでなく、生産性も高くなると思いました。
* 一方で、シェルスクリプトだけでもある程度の事は出来る...ということも分かりました。
 * シェルスクリプトはどうも苦手ですが、苦手意識がなくなるように時々こういったチャレンジを続けていきたいです。
「ViewControllerをたくさん重ねると、いかにもメモリに悪そう」ということをXcodeを使って視覚的に表現してみた

#1 はじめに
この記事は技術的な内容というよりは、実験系の内容になります。

ViewControllerを重ね合わせると、メモリに悪いというのは周知の事実ですが、視覚的に「いかにも悪そうだ〜」という記事は、私が探した限りでは見つけられなかったので掲載します。


#2 試したこと
まず、最初に3つのViewControllerを用意します。
![MakeManyVC.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471470/855d9073-06a5-172f-c902-7552fe247dd3.png)

次にUIBUttonを用意して、下記のようなコードを書きます。
(UIButtonは省略します)

```swift:ViewCotrollerを一つ用意して、画面遷移する(firstVC→secondVC)
@objc func goSecondVC() {
        //secondVCを実体化させる
        let secondVC = SecondVC()
        //用意したVCへ画面遷移
        self.present(secondVC, animated: true, completion: nil)
       }
```


```swift:ViewControllerを一つ用意して、画面遷移する(secondVC→thirdVC)
@objc func goThirdVC() {
        //thirdVCを実体化させる
        let thirdVC = ThridVC()
        //用意したVCへ画面遷移
        self.present(thirdVC, animated: true, completion: nil)
       }
```

```swift:ViewControllerを1つ用意して画面遷移する(thirdVC→firstVC)
@objc func goFirstVC() {
        //firstVCを実体化させる
        let firstVC = FirstVC()
        //用意したVCへ画面遷移
        self.present(firstVC, animated: true, completion: nil)
       }
```

このコードでXcodeのシミュレターを立ち上げて、次々と画面遷移していきます。
![MakeManyVC.002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471470/4a18ed98-bc65-8ac4-dddc-0c8e67e537df.png)

動画だとこんな感じになります。
![manyViewController.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471470/3eb709f3-1290-84e4-b560-874100e11772.gif)

これを7回繰り返すと、こんな感じにViewが現れます。
<img width="1029" alt="スクリーンショット 2020-03-18 20.53.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471470/eabc2cf3-ed2b-deee-6176-949f45a48b9b.png">

これだけでも、
メモリをたくさん使っているように見えますね。

さらに画面遷移を重ねていきます。
<img width="1318" alt="スクリーンショット 2020-03-18 20.49.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471470/e17fedc8-ae36-a705-6a10-da08666b44f0.png">

ここまでくると、明らかにメモリを使ってそうだというのがわかります。


　
ちなみに下記サイトがメモリに関してわかりやすく説明されていました。
https://wa3.i-3-i.info/word16066.html


#3. メモリを圧迫しないためには

ViewControllerを消す必要があります。

例えば、thirdVCからfirstVCへ画面遷移するときに、このようなコードを書くことでViewControllerが破棄出来ます。
[Swift 二つ前の画面に戻る方法](https://qiita.com/Walkdream24/items/787df7d5b6e85330416a)を参考にさせていただきました。

```swift:２つ前の画面に戻って、ViewControllerを破棄する(thirdVC→firstVC)
@objc func dismissTwoVC() {
    //２つ前のVCへ戻り、子VC(secondVC,thirdVCを削除)
    self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)       }
```

イメージはこのようになります。
（間違っていた場合は、ご教授いただけますと幸いです）
![MakeManyVC.003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471470/724974e2-e2d1-8af0-6878-62b3a337ee11.png)
![MakeManyVC.004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471470/77310360-8cea-0cb2-c782-1c2bb558da51.png)
　
　
こうすることで視覚的にも「メモリに良さそう」な実装になります。
<img width="566" alt="スクリーンショット 2020-03-19 0.23.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471470/e6b36516-719d-5fd1-9f2e-38f25580923c.png">
WSL2,Docker,Studio 3tではまったところ

win10で、WSL2,Docker,Studio 3Tを使用した時にStudio 3TからDocker上のmongodbに繋げなくて、はまったことについて書きます。

#WSL2はlocalhostではない。
基本的なことですが、WSL2をlocalhostだと思っていました。なので、Stdio 3TでCONNECTのhost sererをlocalhost（初期値）に設定して繋げようとしたのですが、「Cnnecting to server」がfalseになって、つながりませんでした。

そこで、下記の事を行いました。

①WSL2のubuntuのipアドレスを知る。
　ubuntuで下記コマンドをたたいて、ipアドレスを知ります。

```ubuntu
$ hostname -I
```

②Studio 3Tのconnectionのseverに①で調べたipアドレス(192.168.0,0みたいなもの)を入力

これでつながりました。

補足ですが、STUDIO 3tでデータをIntelliShellで作成したが、すぐには反映されず、Studio 3Tを再起動しなければ作成したデータが見れませんでした。何かwin10で使用する際に癖があるのでしょうか？

以上です。
【JavaScript】flatMapで配列の配列を平坦化して各要素に親配列のインデックスを付けちゃう

# 経緯
* ページングしろ！一覧なんだから当たり前だろ！
* でもページ数は教えないし、1 ページあたりの件数も合計件数も教えないぞ！

# 解決策
* ページの目次を 0 から順にインクリメントする
* 要素数が 0 件の配列を引くまで繰り返す
* ↑ を非同期で実行し、取得結果をローカルに保持
* 取得結果は以下のような配列の配列となる様にする
* flatMap を使って平坦化していろいろする

```javascript:取得結果
[
  [
    { value: '0 番目の要素です。' },
    { value: '1 番目の要素です。' }
  ],
  [
    { value: '0 番目の要素です。' },
    { value: '1 番目の要素です。' }
  ]
]
```

# flatMapで配列の配列を平坦化するやつ
```javascript
pages.flatMap((page, index) => {
  return page.map(list => {
    return ({ pageNo: `${index} ページ`, ...list });
  });
});

// こう書いてもいい
pages.flatMap((page, index) => page.map(list => ({ pageNo: `${index} ページ`, ...list })));
```

# 実行してみる
```javascript:データを用意
const pages = [];
for (let i = 0; i < 2; i++) {
  const page = [];
  for (let j = 0; j < 2; j++) {
    page.push({ value: `${j} 番目の要素です。` });
  }
  pages.push(page);
}
```

```javascript:実行結果

console.log(pages.flatMap((page, index) => {
  return page.map(list => {
    return ({ pageNo: `${index} ページ`, ...list });
  });
}));

[
  { pageNo: "0 ページ", value: '0 番目の要素です。' },
  { pageNo: "0 ページ", value: '1 番目の要素です。' },
  { pageNo: "1 ページ", value: '0 番目の要素です。' },
  { pageNo: "1 ページ", value: '1 番目の要素です。' }
]
```

[Array.prototype.flatMap() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap)
Azure Site Recoveryの同期ステータスを取得する

Azure Site RecoveryでDRサイトへのレプリケーションを設定し、同期に異常があった場合、監視ツールで検知したい。
このような要望は良くあると思います。
Azure PowerShellを使用することで同期ステータスを取得してログ出力等が可能です。
ここではWindowsサーバのイベントログに出力するサンプルを記載します。

### ASRのステータスを取得
まずはASRのステータスを取得します。

```powershell
# Recover Servicesコンテナのコンテキストを設定
$RSCVault = Get-AzRecoveryServicesVault -Name "containername"
Set-ASRVaultContext -Vault $RSCVault

$fabrics = Get-AzRecoveryServicesAsrFabric
$items = $null

foreach($fabric in $fabrics) {
    $container = Get-AzRecoveryServicesAsrProtectionContainer -Fabric $fabric | Where-Object { $_.Role -eq "Primary"}
    $item = Get-AzRecoveryServicesAsrReplicationProtectedItem -ProtectionContainer $container
    if (!$item){
        continue
    }
    $items += $item
}

```

### Windowsイベントログに出力
上記の処理でステータスが取得できましたので異常があった場合にイベントログに出力します。
イベントソースは事前に任意の名前で登録しておいてください。

```powershell
foreach($item in $items) {
    $LogMessage = "$(${item}.FriendlyName) のASRステータス：$(${item}.ReplicationHealth)"
    Write-Host $LogMessage

    if ($item.ReplicationHealth -eq "Normal") {
        continue
    }
    # イベントログに出力
    Write-EventLog -LogName Application -Source "Azure-ASRStatus" -EventId 1 -EntryType Error -Message $LogMessage
}
```

### 結果
同期が正しく行われている場合はイベントログに出力されません。
ただし、仮想マシンが停止している場合でも異常と検知されますので夜間やメンテナンス時に停止する場合は注意が必要です。

```powershell
xxxxxx のASRステータス：Critical
```
![WindowsEventlog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/c07bfbdb-2c7b-4e41-361c-274cf27c30db.png)

### 最後に
これでステータスの取得とイベントログ出力が出来るようになりました。
あとは、ジョブスケジューラ等を使って定期的にステータスを取得すれば短い時間で異常が検知できるようになります。
Chrome拡張機能でポップアップを表示させる方法


```:フォルダ構造
フォルダ
 ├ manifest.json
 ├ popup.html
 └ icon.png
```

```json:manifest.json
{
  "manifest_version": 2,
  "name": "name",
  "version": "1.0",

  "browser_action": {
    "default_icon": {
      "16": "icon.png"
    },
   "default_popup": "popup.html"
  }
}
```

```html:popup.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
</head>
<body>
  Hello World!
</body>
</html>
```

上記のフォルダを用意した後に拡張機能の画面でフォルダをD&Dすると自作の拡張機能を追加することが可能です。

![2020-03-18_23h17_51.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/8242dd1f-b2d1-7a9c-a6ea-fbd38cb9170f.jpeg)



こちらを拡張機能が追加されると下記のようにそれぞれのmanifect.json
で設定した項目が表示されています。


![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/a92765d2-3190-93a2-c31a-dbb865b461f1.png)


設定したアイコンが表示されていて、アイコンをクリックすると`Hello World!`の文字が表示されます。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/521b1141-952b-0868-489f-0e6560ed9f62.png)


【参考】
[Chrome拡張の作り方](https://www.amazon.co.jp/Chrome%E6%8B%A1%E5%BC%B5%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E5%B1%B1%E6%9C%AC%E6%99%BA%E7%94%B7-ebook/dp/B07ZK2JJQH/ref=sr_1_1?adgrpid=90948694249&gclid=EAIaIQobChMIq6W96Z2k6AIVBqyWCh3IOwxGEAAYASAAEgIX4fD_BwE&hvadid=410095081371&hvdev=c&hvlocphy=1009281&hvnetw=g&hvqmt=b&hvrand=7674224275188723260&hvtargid=kwd-477483538317&hydadcr=2245_11030855&jp-ad-ap=0&keywords=chrome+%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD&qid=1584541702&sr=8-1)
gnome-shellのランチャーにショートカットを登録する

#対象
Ubuntu: 19.10
Gnome: 3.34.2 

#結果
下図のeclipseを追加した。
![Screenshot from 2020-03-18 23-16-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567239/ab859d57-427a-4103-0867-35abd31d147f.png)
#desktopファイルを作成

以下の内容を`適当な名前.desktop`として保存。

```適当な名前.desktop
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=eclipse
Comment=Execute eclipse.

# 実行するファイルのパス
Exec=/home/masato/eclipse/java-2019-12/eclipse/eclipse

# アイコンのパス
Icon=/home/masato/eclipse/java-2019-12/eclipse/icon.xpm

Terminal=false
```

#以下のパスにファイルを配置

```
~/.local/share/applications/
```
遅ればせながら、Flutterを始めてみる。（２）

# とりあえず始めてみよう。

ざっくり触り始めてみた感想。

- Flutter 公式とか幾つかのサイトを見てやってみる。
- Hot Reload で更新されるのに感動した
- Android Studio でも Visual Studio Code でも良いみたい
- [Udacity](https://www.udacity.com/) とかで学習するのがいいらしい
- 最近だと書籍もあるからそれでもいいかも

### まぁ、ちょっとづつやろうか。

# 参考文献
- Flutter公式
  - https://flutter.dev/
- Flutterの効率良い学び方
  - https://medium.com/flutter-jp/flutter-learning-c5640c5f05b9
- Flutter はじめの一歩
  - https://medium.com/flutter-jp/first-step-9b7f2c74fb08
- Udacity
  - https://www.udacity.com/
- Udacity の course の一覧
  - https://www.udacity.com/course/build-native-mobile-apps-with-flutter--ud905
CentOS7にjava（Oracle JDK14）をインストール

CentOS7にjava（jdk14）をインストールした手順を紹介します。
今回は`rpmファイル`を取得しインストールしました。

# Oracle JDK14 のダウンロード

以下のコマンドで`jdk-14_linux-x64_bin.rpm`をダウンロードします。
`curl -OL -b "oraclelicense=accept-securebackup-cookie" "https://download.oracle.com/otn-pub/java/jdk/14+36/076bab302c7b4508975440c56f6cc26a/jdk-14_linux-x64_bin.rpm"`

```console:実行結果
[root@CENTOS7 ~]# curl -OL -b "oraclelicense=accept-securebackup-cookie" "https://download.oracle.com/otn-pub/java/jdk/14+36/076bab302c7b4508975440c56f6cc26a/jdk-14_linux-x64_bin.rpm"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100   527  100   527    0     0    774      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  165M  100  165M    0     0   232k      0  0:12:06  0:12:06 --:--:--  227k
[root@CENTOS7 ~]#
```

# ダウンロードしたファイルのハッシュ値を確認

[Java SE 14 Binaries Checksum](https://www.oracle.com/webfolder/s/digest/14checksum.html "Java SE 14 Binaries Checksum")で`jdk-14_linux-x64_bin.rpm`のハッシュ値を確認します。
ハッシュ値は`sha256: c470c99df36a33274832828475766da3e054e0a12db454c1d7c97ae909a55ecb`となっているので、以下のコマンドでダウンロードしたファイルのハッシュ値を取得し、一致していることを確認します。

`sha256sum jdk-14_linux-x64_bin.rpm`

```console:実行結果
[root@CENTOS7 ~]# sha256sum jdk-14_linux-x64_bin.rpm
c470c99df36a33274832828475766da3e054e0a12db454c1d7c97ae909a55ecb  jdk-14_linux-x64_bin.rpm
[root@CENTOS7 ~]#
```

# Oracle JDK14 のインストール

以下のコマンドでダウンロードした`jdk-14_linux-x64_bin.rpm`をインストールします。

`rpm -ivh jdk-14_linux-x64_bin.rpm`

```console:実行結果
[root@CENTOS7 ~]# rpm -ivh jdk-14_linux-x64_bin.rpm
警告: jdk-14_linux-x64_bin.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID ec551f03: NOKEY
準備しています...              ################################# [100%]
更新中 / インストール中...
   1:jdk-14-2000:14-ga                ################################# [100%]
[root@CENTOS7 ~]#
```

# Oracle JDK14 インストールの確認

以下のコマンドでjdk14がインストールされたことを確認します。

`java -version`
`which java`

```console:実行結果
[root@CENTOS7 ~]# java -version
java version "14" 2020-03-17
Java(TM) SE Runtime Environment (build 14+36-1461)
Java HotSpot(TM) 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)
[root@CENTOS7 ~]# which java
/usr/bin/java
[root@CENTOS7 ~]#
```

# 参考

> [Installation of the JDK on Linux Platforms](https://docs.oracle.com/en/java/javase/14/install/installation-jdk-linux-platforms.html#GUID-737A84E4-2EFF-4D38-8E60-3E29D1B884B8 "Installation of the JDK on Linux Platforms")
> [Java SE 14 Binaries Checksum](https://www.oracle.com/webfolder/s/digest/14checksum.html "Java SE 14 Binaries Checksum")
> [Java SE Development Kit 14 - Downloads](https://www.oracle.com/java/technologies/javase-jdk14-downloads.html "Java SE Development Kit 14 - Downloads")

---
以上
Githubでのプログラム修正の流れ　その2

##はじめに
今回は下記の記事の続きです。
ブランチの作成までやってみようと思います。
[Githubでのプログラム修正の流れ　その1](https://qiita.com/ysda/items/7da00da7fe3d13b7ca6f)

3/25更新　[Githubでのプログラム修正の流れその3](https://qiita.com/ysda/items/b08098aa55db7e2d0fae)を書きました。

##今回の記事に出てくる言葉

| 用語       |       意味 |
|:-----------------|:------------------
| リポジトリ             |ファイルやディレクトリの<br>変更履歴を保管しておくもの|
| ローカルリポジトリ        |自分のPC上にあるリポジトリ|
| リモートリポジトリ        |インターネット上に存在するリポジトリ<br>GitHubやbitbucket等|
| コミット        |ファイルの修正や追加をローカルリポジトリに<br>変更履歴として記録すること|
| プッシュ        |ファイルの修正や追加をリモートリポジトリに<br>変更履歴として記録すること|
| ブランチ        |変更履歴の流れを分岐して記録していく物。<br>masterブランチという大元があり、そこからブランチ（枝）が分かれている、、、というイメージ。修正する機能ごとにブランチを作り、プログラム修正が完了したらmasterブランチに反映する。|


##リモートリポジトリにファイルを反映する
下記の画像の①、②を実行してみましょう。今回はファイルを新規作成したためコメントを「Initial commit」としています。ファイルを修正した場合は、「Fix ~」と書いたり、機能を新規作成した場合は「Add ~」と書いたりします。
![スクリーンショット 2020-03-13 2.29.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/378d6526-3528-d151-398a-2be3103dc49b.png)
上記の手順で作業を行えば、「Publish　reposiitory」を押下することで、GitHub(リモートリポジトリ)に新規作成したファイルがアップされます。
![スクリーンショット 2020-03-13 2.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/e34e9077-ea6d-21ef-8474-4b5c1e0930b9.png)

集団で開発する際には、リポジトリを公開する必要があるためkeep this codeのチェックは外しておきましょう。
![スクリーンショット 2020-03-13 3.08.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/113318ad-a5a0-c359-6aac-9555255a9de7.png)

##GitHubでの確認
GitHubにアクセスして、リポジトリを確認してみましょう。→[GitHub](https://github.com/)
ページの左側に先ほど反映したリポジトリが表示されていると思います。
![itCESgNnLNj8I7i1584449099_1584449230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/be6a89b5-451e-1d7e-f752-9dcb7f19d6f5.png)
新規のプロジェクトを立ち上げる際は、こういった手順でディレクトリ、ファイルをプッシュしましょう。

##ファイル修正の事前作業
ファイルを修正する際には、事前にブランチを切っておきましょう。今回は適当にブランチ名をつけましたが、実際に開発に携わる場合は「fix 機能名」とか「add 機能名」とかにした方がいいです。
![スクリーンショット 2020-03-18 23.23.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/a0ba6be9-8889-ef93-f56f-2724cf07a558.png)
![スクリーンショット 2020-03-18 23.21.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/1ebeddcd-1ef9-db39-97e3-a07a5199c07b.png)
![スクリーンショット 2020-03-18 23.28.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/0e106d25-c7b8-ffa1-2765-f26f7dea5df6.png)

##今回はここまで
次回は実装編です。

・更新
↓実践編を書きました
https://qiita.com/ysda/items/b08098aa55db7e2d0fae
Puttyで作成した秘密鍵をUbuntu19.10で使いたい

#はじめに
タイトルから分かるように、本記事を起こしたきっかけはPuttyで作成した秘密鍵を使ってUbuntuPCからLinuxサーバへログインしようとしたところ、sshログインができなかったことです。

#鍵の作成
鍵の作成はWindowsPCにPuttyをインストールして作成しました。サーバ担当者に公開鍵を設置してもらってログイン、というよくあるパターン。WindowsPCからは問題なくLinuxサーバへログインできていました。
ところが、こちらで作成した秘密鍵をUbuntuPcに設置したところ、ssh接続に失敗しました。以下はその時のメッセージです。

```
$ Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```
権限も合っている、設置場所も間違っていない、その他諸々、基本とされることは確認したのですが、それでもつながリませんでした。そしてようやくたどり着いたのが、秘密鍵の形式の違いです。どうやらOpenSSHとPuttyでは鍵の形式が違うために、sshログインエラーが生じてしまうようです。

#Putty形式からOpenSSH形式への変換
秘密鍵の形式の変換はputtygenコマンドで簡単に行うことができます。
前提として、putyygennのインストールが必要です。インストールは以下のコマンドで行えます。
※ubuntuでのインストールコマンドです。

```
$ sudo apt install putty
```

puttyをインストールすることにより、puttygenコマンドが使えるようになります。形式を変換する前に、秘密鍵の置いてあるディレクトリへ移動しておきましょう。

```
$ cd 鍵のおいてあるディレクトリ
```
以下のコマンドで形式を変換します。

```
$ puttygen private_key.ppk -O private-openssh -o id_rsa
```
「private_key.ppk」はご自身の所有している秘密鍵の名前に置き換えてください。「id_rsa」も変更後に使用したい名前に置き換えてください。

あとは変換した秘密鍵を~/.ssh配下に設置するなりして、サーバへのログインをお試しください。

#あとがき
私はこのあとログインに失敗しましたが、~/.ssh配下にid_rsa.pubを配置していたため、ログイン失敗となりました。id_rsa.pubを削除したら正常にログインができました。


稚拙な文章ではありますが、同様の事象でお困りの方の手助けになれば幸いです。
Xcode11.5でVimを使いたい

## はじめに
「XCodeでVimを使いたいなぁぁぁ」と漠然と考えていましたが、あるんですね。
世の中素晴らしいもので、[XVim2](https://github.com/XVimProject/XVim2/blob/master/README.md)なるものがありました。
ありがたき幸せ。。。
備忘録として手順を残しておきます。

## 環境
* macOS Catalina (バージョン10.15.4）
* Xcode 11.5(11E608c)

## 手順
1. KeychainAccessで自己証明書を作成したら以下を実行する([参考](https://github.com/XVimProject/XVim2/blob/master/SIGNING_Xcode.md))。
（Xcode.appのパスは適当に修正してください）

    ~~~
    $ sudo codesign -f -s XcodeSigner /Applications/Xcode.app
    ~~~

2. [XVim2](https://github.com/XVimProject/XVim2/blob/master/README.md)の`README.md`に従ってcloneしてmakeする。
    
    ~~~
    $ git clone https://github.com/XVimProject/XVim2.git
     ....
    $ xcode-select -p
     /Applications/Xcode.app/Contents/Developer
    $ cd XVim2
    $ make
     ....
     ....
     Touch /Users/xxxx/XVim2/build/Release/XVim2.xcplugin (in target 'XVim2' from project 'XVim2')
     cd /Users/xxxx/XVim2
     /usr/bin/touch -c /Users/xxxx/XVim2/build/Release/XVim2.xcplugin
 
     ** BUILD SUCCEEDED **
    ~~~
3. 使いやすくするために`~/.xvimrc`を作成する。

    ~~~bash:.xvimrc
    # ...
    inoremap jk <Esc>
    inoremap jj <Esc>
   # ...
    ~~~

4. XCodeを起動して確認する。

よいVimライフを！

## 参考
* https://github.com/XVimProject/XVim2/blob/master/README.md
* https://github.com/XVimProject/XVim2/blob/master/SIGNING_Xcode.md
[電子工作]137円の8x8 LEDを光らせてみた。

# 概要
aliexpressで137円の8x8マトリックスを見つけたので光らせてみました。

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/UBbWnNobwkY/0.jpg)](http://www.youtube.com/watch?v=UBbWnNobwkY)


# 利用した機器
[Arduino UNO互換機](https://www.amazon.co.jp/FC-%E5%B7%A5%E5%A0%B4-R3%E9%96%8B%E7%99%BA%E3%83%9C%E3%83%BC%E3%83%89-%E3%83%90%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-ATmega328P-Arduino%E3%81%A8%E4%BA%92%E6%8F%9B%E6%80%A7/dp/B07H4KTVK5/ref=sxbs_sxwds-stvp?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2S335VL3VWB52&cv_ct_cx=arduino+uno&keywords=arduino+uno&pd_rd_i=B07H4KTVK5&pd_rd_r=d31aaf3a-0258-4866-b883-ee3cb37525ae&pd_rd_w=II02q&pd_rd_wg=kzB7i&pf_rd_p=e29507e3-7937-4495-82f4-55b5d5ca8047&pf_rd_r=SN5PWYGF5TQS3EX5XFVB&psc=1&qid=1584128141&s=diy&sprefix=Ard%2Cdiy%2C251)
699円
<img width="400" alt="img.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/47f88a1f-c4ae-cc1d-84cc-12b8cc736b9b.png">

[MAX7219 8*8 ドットマトリックスモジュール](https://ja.aliexpress.com/item/32580532205.html?spm=a2g0s.9042311.0.0.27424c4dLVi6hr)
137円
<img width="400" alt="img.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/0dae34ac-f761-7c77-166e-11f8d6e59b0d.png">

# 手順 
## 1.Libraryのインストール
`MAX72`で検索して出てくる`MatrizLed`というモジュールを利用します。
<img width="400" alt="スクリーンショット 2020-03-18 22.25.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/41b3bf9e-b402-54b6-d7c9-8661cebd37e7.png">

## 2.スケッチ例の取得
スケッチ例から`scroll`という例を取得します
<img width="400" alt="スクリーンショット 2020-03-18 22.15.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/3e87e7bb-6627-20c1-8205-f6eba77aa05d.png">

## 3.スケッチ例確認
スケッチを確認しpin番号を確認します。
<img width="400" alt="スクリーンショット 2020-03-18 22.25.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/19d77c01-3773-647f-7071-a19e5def2ff9.png">

## 4.配線
下記の配線図を参考に配線します。
<img width="400" alt="スクリーンショット 2020-03-18 22.34.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/73abcb2c-1357-94bb-d179-8d449bccd41a.png">

<img width="400" alt="スクリーンショット 2020-03-18 22.34.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/61036148-1ab0-944a-9a06-2f8912701e35.png">

## 5.書き込み動作確認

書き込みを行うとこのように動作します。
![download.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/6497f9b0-474f-4b3a-a571-903908041094.gif)
自分用にiPad Pro 11 inchの第３世代と第４世代の違いだけを抜き出した（11inch Wifiモデルのみ）

自分用iPad Pro 11 inchの第３世代と第４世代の比較表。

# 前提条件
- 11インチ
- Wifiモデル

# リンク
第４世代 https://www.apple.com/jp/ipad-pro/specs/
第３世代 https://support.apple.com/kb/SP784?viewlocale=ja_JP&locale=ja_JP

# 違いがあったものリスト
|  | 第３世代 |    第４世代    |
|-----------------|------------------|------------------|
| 重さ             |468g|471g|
|チップ|Apple A12X Bionic|Apple A12Z Bionic|
|リアカメラ|12MP ƒ/1.8絞り値 最大5倍のデジタルズーム|広角：12MP、ƒ/1.8絞り値<br>超広角：10MP、ƒ/2.4絞り値、125°視野角|
|ビデオ|4Kビデオ撮影（30fpsまたは60fps）<br>1080p HDビデオ撮影（30fpsまたは60fps）<br>720p HDビデオ撮影（30fps）<br>クアッドLED True Toneフラッシュ<br>1080p（240fps）スローモーションビデオに対応|4Kビデオ撮影（広角：24fps、30fpsまたは60fps、超広角：60fps）<br>1080p HDビデオ撮影（30fpsまたは60fps）<br>720p HDビデオ撮影（30fps）<br>より明るいTrue Toneフラッシュ<br>1080pスローモーションビデオ（広角：120fpsまたは240fps、超広角：240fps）に対応<br>4Kビデオの撮影中に8MPの静止画を撮影|
|WiFi|Wi-Fi（802.11a/b/g/n/ac）、同時デュアルバンド（2.4GHz/5GHz）、MIMO対応HT80|Wi-Fi 6（802.11ax）、同時デュアルバンド（2.4GHz/5GHz）、MIMO対応HT80|
|バッテリー|29.37Whリチャージャブルリチウムポリマーバッテリー内蔵<br>Wi-Fiでのインターネット利用、ビデオ再生、オーディオ再生：最大10時間|28.65Whリチャージャブルリチウムポリマーバッテリー内蔵<br>Wi-Fiでのインターネット利用、ビデオ再生：最大10時間|

# まとめ
- チップ、リアカメラはもちろん違うが重さが3グラムだけ第３世代の方が軽い。持ってもわかる気がしないが。
- ディスプレイは輝度も含めて同じスペックだった。
- リアカメラが増えたがfpsは大きな変更なし。
- WiFiはaxに対応。自分の環境でaxの恩恵をどれだけ受けられるのだろうか。。。。
- バッテリーは若干の違いがあるが稼働時間は１０時間で変わらず。

んー、iPadで写真やビデオをとることはないので、自分は第３世代で十分なきがする。
Azure Kubernetes Serviceをバージョンアップする

AKS v1.13のサポートが切れるというメールを受け取ったので、v1.14にバージョンアップしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/f1610669-dac7-e67a-582b-b802a6d54cb0.png)

バージョンアップ手順は [公式ページ](https://docs.microsoft.com/ja-jp/azure/aks/upgrade-cluster) に通りで問題なくできますが、考慮点など補足を書き残したいと思います。

# AKSのバージョンサポートポリシー

AKSでは3つのマイナーバージョンがサポートされています。
詳しくは [Azure Kubernetes Service (AKS) でサポートされている Kubernetes のバージョン](https://docs.microsoft.com/ja-jp/azure/aks/supported-kubernetes-versions)を参照ください。

# バージョンアップ前の確認

* 現在のAKSバージョンを確認しておきます。

```
# az aks show -g [Resource Group Name] -n [AKS Cluster Name] -o table
Name            Location    ResourceGroup        KubernetesVersion    ProvisioningState    Fqdn
------------    ----------  ---------------      -------------------  -------------------  ---------------------------------------------
[Cluster Name]  japaneast   [Resource Group Name]             1.13.5               Succeeded            xxx.hcp.japaneast.azmk8s.io
```

* 現在の各種ステータスを確認しておきます。

```
# kubectl get node -o wide
# kubectl get ns
# kubectl get po -o wide -n [NameSpace]
```

* 利用可能なバージョンを確認します。このときv1.13→v1.15のように2段階のバージョンアップはできません。

```
# az aks get-upgrades -g [Resource Group Name] -n [AKS Cluster Name] -o table
Name     ResourceGroup    MasterVersion    NodePoolVersion    Upgrades
-------  ---------------  ---------------  -----------------  --------------------------------
default  [Resource Group Name]    1.13.5           1.13.5             1.13.11, 1.13.12, 1.14.7, 1.14.8
```

# AKSバージョンアップ

* バージョンアップを実行します。所要時間はノード数によると思いますが、2ノードで40分程掛かりました。

```
# az aks upgrade -g [Resource Group Name] -n [AKS Cluster Name] -k 1.14.8
```

* バージョンアップは、k8sノードをDrainにしてローリングアップデートします。  
  Podの状態が気になって確認コマンドを随時実行するかと思いますが、k8sノードのバージョンアップの前にk8sAPIのバージョンアップが入るため、タイミングによってはkubectlコマンドが失敗します。が、APIバージョンアップ中なので問題ないです。

```
Unable to connect to the server: read tcp xxx.xxx.xxx.xxx:54029->xxx.xxx.xxx.xxx:8080: wsarecv: An existing connection was forcibly closed by the remote host.
```

* しばらく経つとバージョンアップが完了します。

# バージョンアップ後確認

* k8sノードのバージョンが変わっていることを確認します。

```
# kubectl get node -o wide
```

以上
Swift Vapor + Herokuで登録しているデータベースにmigrateやrevertを行う

Swiftのvaporを利用し始め、herokuにデプロイしてアプリを動かせるようになりました！
今日は、HerokuでDBのrevertとmigrateをしたのでそれのメモを書きます。
（3分で書いて、2秒で読み終わる代物になっており、オチもありません）

## 参考文献
[What is Heroku](https://docs.vapor.codes/3.0/deploy/heroku/)
[How to REVERT a migration in Vapor 3 with fluent](https://medium.com/@lenin.martinez123/how-to-execute-revert-migration-in-vapor-3-3800540093fa)

## 基本 
以下のような感じでコマンドを打つのが基本スタイル。
~~ の部分にvaporのコマンドが入ります。

```shell
heroku run Run ~~ 
```

Run がローカルで実行するvaporのrunコマンドに相当するみたいです。
ちなみに、~~の部分では[vaporのcommand](https://docs.vapor.codes/3.0/command/getting-started/)機能で実装した自作のコマンドも指定&実行させれます

## 事前に・・・
configure.swiftにはFluentのコマンドが実行できるように設定しておきましょう。
これを忘れるとFluent系のコマンドはvaporのアプリで利用できません。

```configure.swift
var commands = CommandConfig.default()
commands.useFluentCommands()
services.register(commands)
```

## Herokuでのvaporサンプルのデータベースmigrate
```shell
heroku run Run migrate
```

## Herokuでのvaporサンプルのデータベースrevert
`--all` のオプションでこれまでの全てをrevertできます。

```shell
heroku run Run revert
```

## おまけ
ちなみに、ステージング環境と本番環境をHerokuのアプリで分けてる方は、--remoteや--appのコマンドで環境別にコマンド実行させれます。

### --remoteにstagingとproductionが登録されており、stagingにのみmigrateしたい場合
```shell
heroku run Run migrate --remote staging
```

### 同一のソースをHerokuのhello-worldとnew-worldというアプリにそれぞれ登録されており、new-worldにのみrevertしたい場合
```shell
heroku run Run revert --app new-world
```