OmniAICreator/Qiita-1.07M huggingface dataset:
Terraform:構成についての意訳（随時更新）

# 本記事について
ここではTerraformを使う予定の筆者が、使った構成について理解した内容をアウトプットしていきます。

## 使用するプロバイダーについて
TerraformはAzureやGCPなどのクラウド、他にもGitHubでも使用できますが、ここでは主にAWSで使用した際のアウトプットを行います。

## 記載バージョンについて
* Terraform:0.12.0
* AWSプロバイダー：1.60.0

※今後別バージョンのものも記載するかもしれませんが、Terraform0.12.0以降であれば大きな違いは今の所ありません。

##記載方法について
Terraformは下記のように{}の前に記載するブロックとそのブロックに対して何を実行するかを記載します。
下記だと、`providerをawsで指定し、使用リージョンはアジアパシフィック (東京)`を意味します。

```tf
provider "aws" {
  region  = "ap-northeast-1"
}
```

この記事では、ブロック毎に、ブロックの説明とブロック内で使用する引数について記載していきます。

## provider


```tf
記載例
provider "aws" {
  version = "~> 2.0"
  region  = "ap-northeast-1"
}
```

| 構成 | 説明 | 備考 |
| --- | --- | --- |
| provider |記載するコードが何に対応しているかを記載する箇所。<br>Terraformは暗黙的にプロバイダを検出する為、記載がなくても起動はする。| 対応プロバイダーは[公式参照](https://www.terraform.io/docs/providers/index.html) |
| version | プロバイダーバージョンを固定するのに使用。 | バージョンを変更したら`terraform init`コマンドを使用してプロバイダーのダウンロードをすること。 |
| region | 使用する物理サーバの地域を指定。AWSで東京リージョンを使用する場合は`ap-northeast-1` | リージョンの種類は[公式参照](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) 

## resource

| 構成 | 説明 | 備考 |
| --- | --- | --- |
| resource | インスタンスリソースの定義に使用 | |
| count | 作成するインスタンスの数 | |
| ami | マシンイメージの選定 | |
| instance_type | インスタンスタイプの指定 | |
Leetcode Easy 572. Subtree of Another Tree

２つの木構造S,Tを比較する。
SのNodeを一つずつ走査し、Tと比較する。

つまり２回再帰（深さ優先探索）を使って走査する。
ーRootとなるSを一つずつ走査する
ーそのSのRootとTのRootを順に比較する

```cpp
class Solution {
public:
    bool check(TreeNode* s, TreeNode* t) {
        if (s == NULL && t == NULL) {
            return true;
        }
        else if (s == NULL && t != NULL) {
            return false;
        }
        else if (s != NULL && t == NULL) {
            return false;
        }

        if (t->val != s->val) {
            return false;
        }

        return check(s->left, t->left) && check(s->right, t->right);
    }

    bool S_Scan(TreeNode* s, TreeNode* t) {
        if (s == NULL)return false;

        if (s->val == t->val) {
            if (check(s, t)) {
                return true;
            }
        }

        return S_Scan(s->left, t) || S_Scan(s->right, t);
        
    }

    bool isSubtree(TreeNode* s, TreeNode* t) {
        if (t == NULL) return false;
        if (s == NULL) return false;

        return S_Scan(s, t);
    }
};
//    TreeNode* s = new TreeNode(1);
//    s->left = new TreeNode(NULL);
//    s->right = new TreeNode(1);
//    s->right->left = new TreeNode(NULL);
//    s->right->right = new TreeNode(2);
//
//    TreeNode* t = new TreeNode(1);
//    t->left = new TreeNode(NULL);
//    t->right = new TreeNode(2);
//
//
//    cout << Sol->isSubtree(s,t);
Leetcode Easy 994. Rotting Oranges

解法
腐っている状態を１として腐った状態を２とする。
１秒毎に腐ったミカンの周囲を腐らせる。
While(1)で１秒毎の処理を記述する
状態２の周囲が状態１であれば状態２にする。

１秒ごとに変化が起きているかどうかをBool型でチェックする
変化が起きなくなった時、すべて状態２になれば終了
その時、状態１のオレンジが存在する場合は-1を返す





```cpp
using namespace std;
#include <iostream>
#include <algorithm>
#include <vector>
#include <random>
typedef long long  ll;
#define rep(i,s,n)for(ll i=s;i<n;i++)
#define repe(i,s,n)for(ll i=s;i<=n;i++)

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) {
        int row = grid.size();
        int col = grid[0].size();
        bool v[100][100];
        rep(i, 0, 100) {
            rep(j, 0, 100) {
                    v[i][j] = false;
            }
        }

        int ans = 0;
        int x[4] = {1,0,0,-1};
        int y[4] = {0,1,-1,0};
        while (1)
        {
            bool changed = false;
            rep(i, 0, row) {
                rep(j, 0, col) {
                    if (grid[i][j] == 2 && !v[i][j]) {
                        v[i][j] = true;
                        rep(k, 0, 4) {
                            int ny = i + y[k];
                            int nx = j + x[k];

                            if (ny >= 0 && nx >= 0 && ny < row && nx < col && !v[ny][nx] && grid[ny][nx] == 1) {
                                changed = true;
                                grid[ny][nx] = 2;
                                v[ny][nx] = true;
                            }
                        }
                    }
                }
            }
            if (changed) {
                ans++;
                rep(i, 0, 100) {
                    rep(j, 0, 100) {
                        v[i][j] = false;
                    }
                }
            }
            else {
                rep(i, 0, row) {
                    rep(j, 0, col) {
                        if (grid[i][j] == 1) {
                            return -1;
                        }
                    }
                }
                return ans;
            }
        }

        return -1;
    }
};

//int main()
//{
//    Solution* Sol = new Solution();
//    random_device rnd;
//    mt19937 mt(rnd());
//
//    vector<int> v1(300);
//    for (int i = 0; i < 100; ++i) v1[i] = (mt() % 1000);
//
//    cout << endl;
//    vector<int> v2(100);
//    for (int i = 0; i < 100; ++i) v2[i] = mt() % 1000;
//
//    //vector<vector<int>> grid = { { 2, 1, 1} ,{1, 1, 0},{0, 1, 1} };
//    vector<vector<int>> grid = { { 2, 1, 1} ,{0, 1, 1},{1, 0, 1} };
//    cout <<Sol->orangesRotting(grid);
//}
初心者のためのRESTful

#概要
web APIを設計するためのシンプルな標準の方法であるRESTfulの概要をメモとして残す。
またその際に重要となるhttpStatusCodeやCRUDの概要も追記する。

#参考資料
オライリージャパン出版　Jonathon Rasmusson 著　玉川紘子 訳
「初めての自動テスト　webシステムのための自動テスト基礎」

#RESTfulとは
参考資料p67より
>「ねえみんな、Webのリソースにアクセスする方法をそれぞれ独自に定義するんじゃなくて、探しているリソースの名前をURLとして定義して、リソースと通信するための操作を４つの動詞に絞ったらどうだろうか、つまり、GET、POST、PUT、DELETEの４つだ。」

RESTfulとはwebAPIを設計するときの方法またはその定石のことである。
| リソースに対する動作 | リソースの場所 |
|:-:|:-:|
| HTTP GET | /users/:id |
| HTTP POST | /users |
| HTTP PUT | users/:id |
| HTTP DELETE | users/:id |

リソースの場所に対してURLを決め、そのリソースに対する動作をするIDをつけることで、APIが完成する。これがRESTである。

#HTTP ステータスコード
httpStatusCodeとはリソースに対しての動作が行われたとき、それをユーザに「正常に終了したのか」、「要求された情報が見つからなかったのか」、「サーバー側で何らかのエラー発生したのか」等をレスポンスに括り付けてユーザに教えるものである。

```javascript:app.js
app.get('/users/:id', async (req, res) => {
 try{
　//ユーザーのリストからidを用いて探す
  const user = await Users.findById(req.params.id)
  if(!user){
   //見つからなかったら
   res.status(404).send()
  }
  //正常に終了した
  res.status(200).send(user)
 }catch(e){
  //何らかのエラーが発生した
  res.status(500).send(e)
 }
})
```
>コードはNode.jsサーバーにおいて、URL内のidを用いてMongoDB内のリソースから該当するユーザを探し、該当する者がいれば200を返し、見つからなければ404を返し、何らかのエラーが発生すれば500を返している。

このようにステータスコードを理解することによって、サーバーがリクエストに対してどのような処理をしたのかがわかるようになる。
この３つのほかにも様々なhttpStatusCodeがある。

HTTPレスポンスステータスコード
https://developer.mozilla.org/ja/docs/Web/HTTP/Status

ここには様々なhttpStatusCodeが載っている。百の位の数字によって意味が分かれている。
初心者ながら他に私がよく使うもの、よく見るものは新しくユーザ登録をしたときに成功したことを示す「201 created」やコードが間違っているときに返される「400 bad request」である。

#CRUDとは
CRUDとはcreate(作成)、read(読み出し)、update(更新)、delete(削除)という４つの動作を表すものである。

これはREASTfulにおいては下記のように対応している。

| GET | read |
| POST | create |
| PUT | update |
| delete | delete |

CRUD操作を行うAPIをもつとはこれらの操作を可能とするwebアプリケーションであるということである。

#まとめ
RESTful、HTTPStatusCode、CRUDを理解することでどういったAPIを持ったwebアプリケーションを作っていよいかという作る前の疑問を解消してくれる。あとはこれらのAPIを備えたwebアプリケーションを作成するだけである。
Leetcode Easy 1099. Two Sum Less Than K

問題：
与えられた数列のうち、２つの要素の合計値が
Kを超えない最大の合計値を求める。

解法：
２重ループで一つずつ比較して条件を満たす最大値を返す。


```cpp
using namespace std;
#include <iostream>
#include <algorithm>
class Solution {
public:
    int twoSumLessThanK(vector<int>& A, int K) {
        int maxV = -1;
        for (int i = 0; i < A.size(); i++) {
            for (int j = i + 1; j < A.size(); j++) {
                if (A[i] + A[j] < K) {
                    maxV = max(maxV, A[i] + A[j]);
                }
            }
        }
        return maxV;
    }
};
【初心者向け】Rubyでバイトの日給を計算し、1万以下ならもっと頑張らせるアプリ

#バイトの時給と労働時間を計算し、1万以下なら明日は死ぬ気で頑張れと言ってくれるアプリ

#条件
・時給を入力
・労働時間を入力
・日給1万以上なら、日給額と頑張ったねと表示させる
・日給1万未満なら、日給額と明日は死ぬ気で頑張れと表示させる

#擬似コード

```
puts "時給を入力してね"
hw = 時給を入力させる

puts "何時間働いたかを入力してね"
wt = 労働時間を入力させる

if  1万以上なら日給額と、頑張ったねと表示
  else
    1万未満なら日給額と、明日は死ぬ気で頑張れと表示
end
```

※時給＝hourly wage
※労働時間＝working time
※日給=daily salary



#実際にコーディングしてみる
```
puts "時給を入力してください"
  hw = gets.to_i

puts "労働時間を入力してください"
  wt = gets.to_i
#時給を計算
  ds = hw * wt

if ds >= 10000
  puts "あなたの日給は#{ds}です、頑張りましたね。"
   else
  puts "あなたの日給は#{ds}です、明日は死ぬ気で頑張れ。"
end
```

※時給＝hourly wage
※労働時間＝working time
※日給=daily salary

#動作確認

1万以上のパターン

```
時給を入力してください
2000
労働時間を入力してください
9
あなたの日給は18000です、頑張りましたね。
```

1万未満パターン

```
時給を入力してください
900
労働時間を入力してください
8
あなたの日給は7200です、明日は死ぬ気で頑張れ
```
ちょっとプログラムちっくに自分を褒めたりモチベーション上げたいときとかに良いのかもっと思って作ってみました。


明日はもうちょっと難しいやつに挑戦しよう。
挑戦自体がモチベーションをあげるためのもの by 羽生結弦
一年ほどMinecraft鯖運営をして思ったこと

# はじめに
あくまでこの書き手の意見です。

それがすべてではありません。

このページのいい回し

|オーナー|鯖最高権限者|
|:------------------:|:------------------:|
|運営|鯖最高権限者（一個下）|

運営 = スタッフ

# 鯖運営を始めたきっかけ
わたしはもともととある鯖のスタッフ（**[私の鯖](http://monster2408.html.xdomain.jp)で言う運営**）でした。

素性などは隠していましたし声も出してなかったのでこいつだ！！っていう決定打は残していないつもりです。

ですが、ある時にその鯖の鯖主さんとスタッフさんが口論になり半ば強引に鯖スタッフから外すということになりました。

私はその件には一切関係なかったのですがその鯖の運営グループは最悪の空気になっていたのでそこを抜けました。
　**※実は最近連絡を取っていたりいなかったり・・・**

心機一転MCアカウントを再購入し１からスタートすることに！！

そんな中ある人に話しかけられ鯖運営を手伝ってほしいとのこと・・・
（後にわかる、この子が小学生であることが）

そして手伝っていたのですが、知識量的に自分がメインで作業することに・・・
↓
彼とのやり取りが徐々にめんどくさくなる

そのうち、ほかの運営が入ってきて、ほかの人が軽くこの小学生を攻撃するように・・・
↓
小学生あるあるのもうやめる！！で一度抜ける・・・

この後、戻ってきて他にもいろいろあったけどそこらへんは省略

などなどがあり、**自分がオーナーをすることになる**
# 鯖運営をするうえでめんどくさかったこと
- ホームページ読まない
- ルール読まない
- 小学生
- アンチ 
 
## ◇ ホームページを読まない
鯖のルール（利用規約）などは鯖が独断で決める権限のあるものです。
そこまでめちゃくちゃじゃない限り文句を言われることがありません。

そして利用規約や鯖ルールのとても便利な文言を入れておけば鯖運営はとても簡単になります。

わたしの鯖でも過去・現在使っている文言ですが

```:鯖ルール
運営陣が違反と判断する行為を禁ずる
```
これは要するに「**運営の独断で処罰できます**」という意味。

```:利用規約
第X条（利用規約の変更）
当鯖は、必要と判断した場合には、ユーザーに通知することなくいつでも本規約を変更することができるものとします。

なお、本規約の変更後、本サービスの利用を開始した場合には、当該ユーザーは変更後の規約に同意したものとみなします。
```
これは要するに「**利用規約が変更されても利用する限り通知せずとも守らないといけない**」という意味。

わざわざ鯖ルールにしたけどあくまで参考であって鯖ルールの内容を利用規約に反映すれば独断で処罰するよ宣言ができるんですな。。。

**ここには大きな問題点があるがその点は後に話すね？**

## ◇ ルールを読まない
利用規約を用意すると当たり前だけど読まない人がいるんです。
そんな人が鯖のルールをしってるわけもなく、鯖があれる原因になるんです。

でも、ここで「**利用規約に書いてるしあなた利用してるし罰則規定通り罰則するね**」という態度で罰するとほかの読んでいない人がこれは罰せられると分かる、ちょっとした抑止力になるということです。

かといって、むちゃくちゃな罰し方は論外ですが・・・

## ◇ 小学生
まあ、これは小学生すべてが面倒っていうわけじゃなくて一部ですね。
（実際、一部の小学生が優秀なんだけどそこは掘り下げないよ？）

まあ、利用規約とかを用意すると小学生には理解できない言い回しが出てきます。

なので、厄介になったりするというだけです。

## ◇ アンチ
この存在の何が面倒って今まで書いてきた３つの項目すべてを行うのがアンチなんですね。

もう、これに関しては即BANするなどの対策をとるのが楽だと思います。

一番厄介なのがグループアンチです。

「**塵も積もれば山となる**」というように「**アンチも集まれば壁となる**」と言いましょうか・・・

で、特にグループのリーダー始まりのアンチはとても面倒です。

某国でもやってるようなそういう思想を持った人をつぶす的な処置が特例でOKということにするのが得策だと考えられます。

# 大変なこと
ただのバニラ鯖なら関係ないだろうけど私の鯖はPlugin鯖なのでPluginが必須なんですね。

そして配布されているPluginは自分たちのやりたいことをすべて実現させるには役に立たないんですよ・・・

よってPlugin開発者が必要なわけですが・・・


これには今もそうですが苦戦します。
「自分で勉強しろよ」って？

ばーか。それで追い付かねーんだよ・・・

ってのが現実だと思います。

ハッキリ言って鯖運営も開発者は複数人いないと難しいんですよね・・・

ということで私が運営している鯖ではPlugin開発者を募集(((

すみません・・・ｗ

# さいごに
ここに記述したのは深夜テンションで書き始めて「ああ、もうここまで書いたのに消すのはもったいない」と思い最後まで書ききっただけのものですので、大して参考にしないでください。

言っておくけど

**ここに書いてる内容で鯖運営して失敗したって怒らないでね？
　　責任は取りかねます**
表の結合にconcatを使ったのですがうまくいきません

（例）pythonでアヤメの分類のプログラムを作っています。
表を作る作業中に、以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ
TypeError                                 Traceback (most recent call last)
<ipython-input-98-63b3307811e6> in <module>
17 
18 import pandas
---> 19 iris_test=concat([tt_ind,X_test,y_test],axis=0)
20 print(iris_test)

~\Anaconda3\lib\site-packages\pandas\core\reshape\concat.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, sort, copy)
253         verify_integrity=verify_integrity,
254         copy=copy,
--> 255         sort=sort,
256     )
257 

~\Anaconda3\lib\site-packages\pandas\core\reshape\concat.py in init(self, objs, axis, join, join_axes, keys, levels, names, ignore_index, verify_integrity, copy, sort)
330                     " only Series and DataFrame objs are valid".format(type(obj))
331                 )
--> 332                 raise TypeError(msg)
333 
334             # consolidate

TypeError: cannot concatenate object of type '<class 'numpy.ndarray'>'; only Series and DataFrame objs are valid

該当のソースコード
Python

from sklearn import datasets
from sklearn.model_selection import ShuffleSplit as SS
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score as a_score

アヤメのデータセットを読み込む
iris=datasets.load_iris()
X=iris.data
y=iris.target

データを分割するインデックスを作る
iris_ss=SS(test_size=0.3)
tr_ind,tt_ind = next(iris_ss.split(X))

データを学習データと評価データに分割する
X_train,X_test,y_train,y_test=X[tr_ind],X[tt_ind],y[tr_ind],y[tt_ind]

import pandas
iris_test=concat([tt_ind,X_test,y_test],axis=1)
print(iris_test)

試したこと
他のメソッドもいろいろ試しましたがうまくいきません。上のエラーに対する対策がもっとも根本的ではないかと思いました。

補足情報（FW/ツールのバージョンなど）
markdawnがまだ使えなくてすみません。
【Rails】Gemのバージョンエラー「Bundler could not find compatible versions for gem」が出てきたときの対処法

#エラー発生
Railsチュートリアル１０章の10.3.2「サンプルのユーザー」で「リスト10.42: GemfileにFaker gemを追加する」で以下のようにgemを追加した。

```:Gemfile
source 'https://rubygems.org'

gem 'rails',          '5.1.6'
gem 'bcrypt',         '3.1.12'
gem 'faker',          '1.7.3'
```

そしてbundle installすると、以下のエラーが発生。

```
Warning: the running version of Bundler (2.0.2) is older than the version that created the lockfile (2.1.0). We suggest you upgrade to the latest version of Bundler by running `gem install bundler`.
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Bundler could not find compatible versions for gem "i18n":
  In snapshot (Gemfile.lock):
    i18n (= 1.6.0)

  In Gemfile:
    rails (= 5.1.6) was resolved to 5.1.6, which depends on
      activesupport (= 5.1.6) was resolved to 5.1.6, which depends on
        i18n (>= 0.7, < 2)

    faker (= 1.7.3) was resolved to 1.7.3, which depends on
      i18n (~> 0.5)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
```

#解決方法
調べていたところ、以下の投稿を発見。
https://teratail.com/questions/199869
「Fakerはi18nと依存関係にあります。（Fakerはi18を使って文字列を保存します） 

それぞれのGemのバージョンが、良くない組み合わせであったために発生しているエラーかと思われますので、bundle updateをすることで解決するかもです！」

そこでbundle update後、bundle installすると無事インストール成功！

確かにエラー文の最後にもbundle updateをするとコンフリクトが解決するかもと書いてあった...
エラー文もよく読もう。反省。

#まとめ
ちなみにbundle updateとは「Gemfile.lockの記述を無視して、GemfileでのGemの指定やそのバージョン指定などに基づいて、gemを更新する。 更新時にGemfile.lockを更新する。」ことだそう。コンフリクトしたらupdateしてみましょう。

参照
https://athomegeek.com/rails_bundleupdate/
Mac Catalinaからホームシェアリングの設定方法が変わっていた

## はじめに

正月、Macに貯めてあるホームビデオを、リビングのテレビに繋いだAppleTVで再生しようとするとできない、、！
Catalinaにアップデート後、設定方法が変更になったようなので調べてみました。

## 設定方法

iTunesが「解体」されたため、ホームシェアリング設定が「システム環境設定」に移されていました。

システム環境設定ー＞共有　より「メディア共有」をオンにし、ホームシェアリング設定すればOKです。

![スクリーンショット 2020-01-05 17.15.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545858/af5f0c43-b63d-5225-56a2-6c9c6babfa9b.png)
JavaのsubstringとC#のSubstringの違い、移植方法を整理してみる

#はじめに
既存資産をJavaからC#へ移植をしているが、文字列の一部を切り出すメソッドの仕様の違いによりバグがでているため今後のためにメモ。

# 文字列の一部を切り出すメソッド
Java, C#ともに2種類ずつある。説明は参考文献の引用である。

#JavaのString#substringメソッド
| メソッド       |       説明                          |
|:------------------------------|:------------------------------------|
| public String substring(int beginIndex) | この文字列の部分文字列である文字列を返します。部分文字列は指定されたインデックスで始まり、この文字列の最後までになります。  |  
| public String substring(int beginIndex, int endIndex) | この文字列の部分文字列である文字列を返します。部分文字列は、指定されたbeginIndexから始まり、インデックスendIndex - 1にある文字までです。したがって、部分文字列の長さはendIndex-beginIndexになります。   |

#C#のString#Substringメソッド
| メソッド       |       説明                          |
|:------------------------------|:------------------------------------|
| public string Substring (int startIndex); |インスタンスから部分文字列を取得します。 部分文字列は、文字列中の指定した文字の位置で開始し、文字列の末尾まで続きます。 |  
| public string Substring (int startIndex, int length); |インスタンスから部分文字列を取得します。 この部分文字列は、指定した文字位置から開始し、指定した文字数の文字列です。    |

#JavaからC#へ移植する場合の作業
以下のように変換すればよい。

| Javaメソッド  |   変換前Javaコード    |  変換後C#コード                     |
|:------------------------------|:-----------------------|:-----------------------|
| public String substring(int beginIndex) |"文字列".substring(beginIndex)|"文字列".Substring(beginIndex)|
| public String substring(int beginIndex, int endIndex) |"文字列".substring(beginIndex, endIndex)|"文字列".Substring(beginIndex, endIndex - beginIndex) |

#C#からJavaへ移植する場合の作業
以下のように変換すればよい。

| C#メソッド       |    変換前C#コード    |変換後Javaコード                           |
|:------------------------------|:-----------------------|:-----------------------|
| public string Substring (int startIndex); |"文字列".Substring(beginIndex)| "文字列".substring(beginIndex) |
| public string Substring (int startIndex, int length); |"文字列".Substring(beginIndex, length)|"文字列".substring(beginIndex, beginIndex + length)|

#参考
- [Java クラスString#substring](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html#substring-int-)
- [C# String.Substring メソッド](https://docs.microsoft.com/ja-jp/dotnet/api/system.string.substring?view=netframework-4.8)
PHP switch文まとめ

## 目的

- PHPのswitch文の書き方をまとめる

## 書き方の例

- 下記にswitch文の書き方を記載する。

```php

switch (変数){
  case 変数に入っている可能性のある値A:
    変数に値Aが入っている時の処理;
    brake;
  case 変数に入っている可能性のある値B:
    変数に値Bが入っている時の処理;
    brake;
  default:
    変数に値Aと値B以外のものが入っていた時の処理;
    brake;
}
```

## より具体的な書き方の例

- 変数`flag`に入っている値で処理を変更したい時の処理を下記に記載する。

```php
switch ($flag){
  case 0:
    echo "flagには0が格納されています。";
    break;
  case 1:
    echo "flagには1が格納されています。";
    break;
  default:
    echo "flagには0と1以外が格納されています。"
    break;
}
```

- 信号機の色で出力を変更するcase文を使用した処理を記載する。
- 変数`$signal`に格納された値を元にメッセージを変更する処理を下記に記載する。

```php
switch ($signal) {
    case "red":
        echo "stop";
        break;
    // 条件が二つある場合は並列して記載できる
    case "blue":
    case "green":
        echo "go";
        break;
    case "yellow":
        echo "caution";
        break;
    default:
        echo "no signal";
        break;
}
```

## 型厳密に比較する

実はswitch文の値比較は`===`の型も含めた厳密比較ではなく、`==`となっている。
つまり、先のswitch文で下記の様なことが起きてしまう。

```php
switch ($flag){
  case 0:
    echo "flagには0が格納されています。"; // $flagに数値の0か文字列の'0'が入っていた場合
    break;
  case 1:
    echo "flagには1が格納されています。"; // $flagに数値の1か文字列の'1'が入っていた場合
    break;
  default:
    echo "flagには0と1以外が格納されています。"
    break;
}
```

ただ、コードを書いているとswitch文で型も含めた厳密比較をしたい場合も当たり前のように存在する。
そういうときは下記のようにすることで解消する。下記は`$flag`が数値の0か1かをチェックしたい場合なので`$flag === 0`や`$flag === 1`のようにしている。文字列の0か1かをチェックしたい場合は`$flag === '0'`や`$flag === '1'`になる。

```php
switch (true){
  case $flag === 0:
    echo "flagには数値の0が格納されています。";
    break;
  case $flag === 1:
    echo "flagには数値ｎ1が格納されています。";
    break;
  default:
    echo "flagには0と1以外が格納されています。"
    break;
}
```
Cloudwatch eventでRDSを止める

##定時が来たらRDSをまとめて落としたい


開発環境とか開発中のRDSとか、使わないときは止めておきたい。~~「とにかく金使うな」という空気感を読んで~~
ちょっとハマったのでメモ。

----------

### Cloudwatch eventを開いてcronを設定する

時間が来たら止めたいので、スケジュールからcron式で設定してあげる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322955/1974d349-c311-f39e-8a14-d2cb31cf6c5e.png)

------

### 止めたいRDSを指定する

SSM AutomationでRDSを止めてあげる。
定数に止めたいRDSのインスタンス識別子を入力する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322955/ea8dec40-8fcc-e455-320f-2dfddd24e79f.png)

-------

##### ここでハマった

**RDSのinstanceidは複数指定できない**
EC2はできるのに…。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322955/ef32a06e-3ffa-4f1b-d09b-2323b07fb0d1.png)

[AWS-StopRDSInstanceのリファレンス]
(https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/automation-aws-stoprdsinstance.html)
instanceidの型が文字列になってる...。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322955/fb4a3cde-8141-05c5-88b0-fa3f8e116e75.png)

[AWS-StopEC2Instanceのリファレンス](
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/automation-aws-stopec2instance.html)
EC2はstringlistなのに...。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322955/79f191c4-f843-1075-1735-faff815b5ca4.png)

-------

### 名前決めて説明入れる

ここはお好きに。
入れたら「ルールの作成」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322955/202b2609-f399-a908-6849-46e7b32078c3.png)

------

### 完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322955/68e6a0c9-6a5e-f5eb-023d-11460130d915.png)

------

### まとまらないまとめ
1. 複数RDSを落としたいときは、いちいちルール作んなきゃだめなのか…？
それカッコ悪くない…？

2. リファレンスは大事
マークアップエンジニアから見た、デザインツール「STUDIO」

コードを書かずにWebサイトを作成できる、**STUDIO**を使ってみた所感です。
HTML、CSSのプロであるマークアップエンジニア目線で書いてみます。

## STUDIOとは？
[STUDIO](https://studio.design/ja)とは、ノーコーディングでWebサイトのデザインから公開までを完結できるWeb制作ツールです。ブラウザ上で動作します。

ちなみに、ブラウザは、

- Chrome
- Firefox
- Safari
- IE11

に対応しているようです。

参照：[STUDIOで作成されたWebサイトの対応環境](https://help.studio.design/en/articles/2401764-studio%E3%81%A7%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%81%9Fweb%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AE%E5%AF%BE%E5%BF%9C%E7%92%B0%E5%A2%83)

## STUDIOでできること
- WebデザインをGUIで作成
    - モーダル
    - ハンバーガーメニュー
    - `iframe`埋め込み
- 各UIに適切なHTMLタグを指定
    - id属性も付与可能
    - ドラッグ・アンド・ドロップで入れ子にできる
- `title`や`description`等のmeta情報の設定
    - OGイメージやファビコンも設定可能
- お問い合わせフォーム設置
- 独自ドメインの設定（有料）
- 公開

詳しくは、[公式のチュートリアル](https://help.studio.design/en/collections/1532967-%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB)をご確認ください。

いくつかピックアップして解説してみます。

### WebデザインをGUIで作成
ドラッグ・アンド・ドロップで各セクションやテキスト、画像等を配置した後、細かい余白やボーダー等を調整していきます。調整の項目がCSSライクで、GUIでCSSを書いているような感覚になりました。

- `display: flex;`ライクなレイアウト
- CSSの単位は`px` `%` `vw (vh)` `auto` `flex`で指定可能
- `positon`プロパティは、`relative` `absolute``fixed`が指定可能
- `background` `opacity` `border`系（角丸とかも） `box-shadow`あたりを調整できる

疑似クラスは、`:hover` `:focus` `:active`が使えました。

レスポンシブWebデザインに対応しいて、ブレークポイントごとにデザインを調整できます。（ブレークポイントは、SP・TB・PCの2箇所くらいあるみたい）

また、モーダルやハンバーガーメニュー、`iframe`埋め込みによるマップや動画も対応しています。

### 各UIに適切なHTMLタグを指定
各UIのHTMLタグをGUIで指定・変更できます。たとえば、見出しレベルを`h2`から`h3`に変更したり、`div`を`article`に変更したり。

`id`属性も指定できるので、アンカーリンクとかも対応できます（`id`を指定したUIパーツをコピペすると、`id`属性が重複してしまうので注意が必要という豆知識）。`img`要素の`alt`属性も指定できました。

ドラッグ・アンド・ドロップでUIパーツの中にUIパーツを入れると、HTMLが入れ子になりました。逆に、外に出すと兄弟要素になったりします。

### お問い合わせフォーム設置
お問い合わせフォームのUIが用意されているので、ドラッグ・アンド・ドロップで配置し、配信先を設定するだけで使えます。楽。

### 独自ドメインの設定（有料）
独自ドメインの設定は有料です。無料版ですと、`{subdomein}.studio.design`になります。

また、無料版では左下に広告が表示されるようです。

参照：[料金設定](https://studio.design/ja/pricing)

## STUDIOでできないこと
2020年1月の時点で、以下は未対応でした。

- 一部の擬似クラス、疑似要素の指定
- `transition`や`animation`での、細かいマイクロインタラクションの設定
    - `:hover`時、`transition`が設定されていますが、一律っぽいです
- JavaScript全般の操作
- **Google Lighthouse**では、パフォーマンスにやや難あり

## 所感
JavaScriptや細かいマイクロインタラクションが使えない点がネックですが、提供されてるモーダルやフォームの範囲内で十分なWebサイトであれば、特に問題なく使えるツールだと思います。

マークアップの知識があるデザイナーさんと相性が良さそうです。

逆に、HTML・CSSが書けます程度のマークアップエンジニアは、このままでは淘汰されてしまいそうですね。。がんばりましょう(^^)
echobotを作成し、Slackに通知する

#はじめに

AWSアカウントを作成したので、料金管理のため料金通知botを作成したい。
そのため、まずはechobotを作成してbotを試してみる。

#Lambdaを作成する
「AWSマネジメントコンソール」から「Lambda」を作成する。
諸々の設定を行い、以下のようにコードを書きかえる。

```HTTPステータス200(OK)と本文にeventをJSON形式にしたものを返す.
import json

def lambda_handler(event, context):
    # TODO implement
    return { 'statusCode': 200, 'body': json.dumps(event) }
```

#API Gatewayの作成
「AWSマネジメントコンソール」から「API Gateway」を作成する。
「APIの作成」をクリックする。
「アクション」→「メソッドの作成」から「POST」を選択し、以下のようにセットアップする。

- 統合タイプ「Lambda関数」
- Lambdaプロキシ統合の使用→チェックを入れる
- Lambdaリージョン→さっき作ったLambdaのリージョンを指定。(デフォルト)
- Lambda関数→さっき作ったLambdaの名前「echobot」を入力
- デフォルトタイムアウトの使用→チェックを入れたままで良い。

「保存」をクリックし、「Lambda関数に権限を追加する」とか出るので、「OK」をクリックする。

#Slackの発信Webhook (Outgoing Webhooks)の準備
[こちら](https://slack.com/apps/manage/custom-integrations)にアクセスし、「発信Webhook」(英語UIだとOutgoing Webhooksかも)をクリック、「設定を追加」をクリックする。

「発信ペイロードとレスポンス」をクリックすると、どんなデータがやってくるのか分かるのでコピーし、メモ帳か何かに貼り付ける。
貼り付けたデータの改行を&に置き換え、AWSのAPI Gatewayテスト画面にて「リクエスト本文」に貼り付けて、テストする。
テスト後、「レスポンス本文」に出てきた結果をコピーする。
コピーした内容をLambdaのテストイベントとして設定する。

#Lambdaのコーディング
Slackからの発言に対してLambdaに無限ループを起こさせないよう以下のようのコードを修正する。

```修正版.
import json
import os
from urllib.parse import parse_qs

def lambda_handler(event, context):
    token = os.environ['SLACK_TOKEN']
    query = parse_qs(event.get('body') or '')
    if query.get('token', [''])[0] != token:
        # 予期しない呼び出し。400 Bad Requestを返す
        return { 'statusCode': 400 }
    slackbot_name = 'slackbot'
    if query.get('user_name', [slackbot_name])[0] == slackbot_name:
        # Botによる書き込み。無限ループを避けるために、何も書き込まない
        return { 'statusCode': 200 }
    # textの内容をそのまま書き込む
    return {
        'statusCode': 200,
        'body': json.dumps({
            'text': query.get('text', [''])[0]
        }) }
```
次に、「関数コード」の下の「環境変数」のところに、Slackのtokenとしてやってくる文字列を指定する。

- キー「SLACK_TOKEN」
- 値: Slackの発信Webhookの「発信ペイロードとレスポンス」にあったtoken=...の行の=より後の文字列

「テスト」をして、statusCodeが200、bodyがJSON形式でtextにリクエストの本文と同じようなものが記述されれば良い。

#API GatewayエンドポイントURLの作成
API Gatewayのページの「リソース」の右側、「アクション」をクリックし、「APIのデプロイ」をクリックする。
以下のように入力し、「デプロイ」をクリックする。

- デプロイされるステージ「新しいステージ」
- ステージ名：適当。ここでは「prod」
- ステージの説明、デプロイメントの説明: 書きたければ書く

#Slack Webhookの設定
「インテグレーションの設定」までスクロールし、以下のように設定します。

- チャンネル: 全チャンネルだと迷惑なので、botを入れるチャンネルを選ぶか作成します。今回、botチャンネルを新たに作成しました。
- 引き金となる言葉: ここに指定した単語で始まる行があったときのみbotをAPIを叩きます。全チャンネルの場合は必須ですが、今回はチャンネルを指定したので不要です。何も指定しません。
- URL: 先ほどAPI GatewayをデプロイしてできたURLを貼り付けます
- トークン: 変えずにそのまま。Lambdaの方で設定した環境変数SLACK_TOKENと同じかどうか、念のため確認する。(違っていた場合はLambdaの方を変えて保存する)
- それ以外の項目: 特にさわる必要はない。変えたいものがあったら変える。

「設定を保存する」をクリック。

#おわりに
作成したbotが正常に動作するか発言してみる。
<img width="409" alt="スクリーンショット 2020-01-05 17.27.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472784/d5672b07-faef-4983-5220-241d1c5190d5.png">
同じ内容が帰ってきたので正常に動作した事が確認できた。
後はLambdaの内容を変更して料金通知botに変更する。
今回はここまでとする。
Unityメモ【Terrain ペイントブラシの色追加】

Terrainのペイントブラシですでに入っている草や岩のテクスチャーではなく，単色やネットにある画像から色を使う方法をメモる．

## 画像をダウンロードする
こんな感じのテクスチャーを使ってもいいですし，
![スクリーンショット 2020-01-05 15.45.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/4ca1ad8c-2981-ae42-41dd-4d0e261d0111.png)

こんな感じの単色でもOKです．今回は単色でいきます．
![スクリーンショット 2020-01-05 15.57.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/9a4d8218-a35a-8b43-2281-2b505e19e802.png)

緑色と茶色の単色画像をダウンロードします．
UnityのAssetsからImport New Assetsで画像をインポートします．
![スクリーンショット 2020-01-05 16.05.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/0cdd475b-4f50-d8a4-f2c1-18cc8dde8e28.png)
![スクリーンショット 2020-01-05 16.10.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/9c20e388-b725-9228-0786-2789dabf62bd.png)
![スクリーンショット 2020-01-05 16.11.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/ae61de02-4af7-5ff4-e788-3e786a84dc59.png)

## Terrainを作る
Hierarchyの 3DObjectから Terrainを作成します．
![スクリーンショット 2020-01-05 16.35.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/ffeb0892-96c7-5115-b948-30dc025c53fe.png)

Terrainのインスペクターから筆のアイコンをクリックし，Raise or Lower Terrainを選択し地形を変形させます．
![スクリーンショット 2020-01-05 16.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/9491738e-d6fa-30b2-7ee4-338e2acbc71c.png)
![スクリーンショット 2020-01-05 16.57.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/53108474-f0cf-f81a-08dd-51120702c09f.png)

## 色をつける
色をつけるには，下の画像の2番のようにPaint Textureを選び，3番のEdit Terrain Layersから，Create Layerを選択します．
![スクリーンショット 2020-01-05 16.39.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/0b1c61d7-436d-0af2-b46e-e46827aef4b3.png)
すると，Select Texture2D画面が開き，インポートした画像が入っているのが確認できます．まずは下地のベースとなるGrrenの画像を選びEnterを押します．
![スクリーンショット 2020-01-05 17.03.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/709ff351-8340-2580-2ce3-a00cc417ebda.png)
インスペクターのTerrain LayersにGreenの画像が追加されます．
![スクリーンショット 2020-01-05 17.08.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/de32c8c5-c1d3-e769-df1e-f5d401633085.png)
下の画像のように1（Layer），2（ブラシの形），3(ブラシのサイズ)を選択します．地面全体を塗るので，サイズは大きくしましょう．選択したブラシでTerrainをドラッグすると色が塗れるので，前面を塗りましょう．
![スクリーンショット 2020-01-05 17.10.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/f0424302-f21b-f950-bad5-9e0e25711b1a.png)
![スクリーンショット 2020-01-05 17.15.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/d39cdbe4-a25f-e490-9113-1deaecf0e75f.png)
Edit Terrain Layers，Create Layer から次はBrownの画像を追加します．
そしたら先ほど同様，1（Layer(Brawn)），2（ブラシの形），3(ブラシのサイズ)を選択し,Terrainに色を塗っていきます．今度はサイズは少し小さめに調整しましょう．
![スクリーンショット 2020-01-05 17.17.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/2a625fc3-fff2-0d88-1d37-9e106b1b2418.png)
![スクリーンショット 2020-01-05 17.32.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/bacf94d1-45b9-90a3-3237-745a4c1cb0c2.png)

こんな感じで山の岩肌が表現できました！
C#でControlとShiftが両方押されたかを判断する

#はじめに
大した話ではないが、備忘録。

#方法
## Shiftが押されたかの判定
```
(ModifierKeys & Keys.Shift)>0
```

## Controlが押されたかの判定
```
(ModifierKeys & Keys.Control)>0
```

## ControlとShiftが両方押されたかの判定
```
(ModifierKeys & Keys.Shift)>0 && (ModifierKeys & Keys.Control)>0
```

#参考
- [Keyboard.Modifiers プロパティ](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.input.keyboard.modifiers?view=netframework-4.8)
Gitの取り消しいろいろまとめ

#注意事項
完全に個人用メモです。公式情報でもなんでもありません。ググってこの記事に来てしまった方はお気をつけください。違っていたら即直しますのでガンガンご指摘ください。（個人用メモなので追加もしていきます）

## addしてないファイルとフォルダ削除

`git clean -n`・・・どのファイルが削除対象になるか確認するだけ。削除はされない

`git clean -f`・・・addしてないファイル削除

`git clean -fd`・・・addしてないファイルとフォルダ削除

##ワークツリー変更内容を取り消し

`git checkout .`・・・全てのファイルのワークツリー変更内容を取り消し

`git checkout hoge.txt`・・・hoge.txtのワークツリー変更内容を取り消し

新しく作ったファイルとかフォルダは消されないのでご注意。

##addを取り消し

`git reset HEAD^ .`・・・全てのファイルのaddを取り消し

##commitを取り消し

`git reset --soft HEAD^`・・・HEADのコミットだけ取り消し

`git reset --mixed HEAD^`・・・HEADのadd、コミット取り消し

`git reset --hard HEAD^`・・・HEADのワークツリー変更内容、add、コミット全て取り消し

##pushを取り消し

`git push -f origin master`・・・上記の方法でローカルでコミット取り消した後に無理やり（-fオプション）歴史を改変してリモートのmasterにプッシュする。

##番外編①（git fetch, git pull, git cloneについて）

`git fetch`・・・リモートのリポジトリの内容をローカルのリモート追跡ブランチに反映(git pushの逆)

`git pull`・・・git fetchした後にローカルのリモート追跡ブランチをローカルブランチにmergeする(git pushの逆ではない)

`git clone`・・・git pullするための下準備（git init）とかをやっといてくれる。んで、git pull 。新規に開発に参加するときとかはこっちでいいと思う。
[iOS/Swift] アプリ開発の実務的アプローチで学ぶデザインパターン ～Decorator～

この記事シリーズは、iOS/Swiftエンジニアである執筆者個人が、
**ごく普通のiOSアプリ開発でよくある状況**や
**Swiftのコアライブラリやフレームワークで使われているパターン**に
着目してデザインパターンを学び直してみた記録です。

**関連記事一覧**
[[iOS/Swift] アプリ開発の実務的アプローチで学ぶデザインパターン](https://qiita.com/y-some/items/96db5f24ded4a1fab48f)

# Decoratorパターン概要

- **継承を使わずに振る舞いやプロパティを付け足す**手法です。
- 実務で陥りがちな問題として、親クラス ＞ 子クラス ＞ 孫クラス のような継承のネスト構造では、孫クラスでの機能追加/変更が子クラス・親クラスまで影響してしまうことがあります。Decoratorパターンは、それを避けるための手法です。
- Decorator（拡張する側）オブジェクトのコンストラクタでラップ対象のオブジェクトのインスタンスを受け取り、変数に保持して、それに対して新しい振る舞いやプロパティを追加（＝Decorate）します。
- 一段階Decorateしたオブジェクトをさらにもう一段階Decorateできる、という再帰的な構造も特徴です。
- GoFのでデザインパターンでは**構造に関するパターン**に分類されます。

# 使い所

- 正直、ごく普通のiOSアプリ開発での利用場面は思いつきませんでした。
- Swiftには「継承を使わずに拡張する」ための言語機能としてextensionやprotocol extensionがありますし…
- iOSの世界の一例としては、 **NSAttributedString/NSMutableAttributedString** がDecorateパターンになっています。

# サンプルコード

Swiftバージョンは 5.1 です。

```swift
let attrStr = NSAttributedString(string: "Decoratorパターンのサンプルです",
                                 attributes: [.foregroundColor: UIColor.blue])
let mutableAttrStr = NSMutableAttributedString(attributedString: attrStr)
mutableAttrStr.setAttributes([.font : UIFont.systemFont(ofSize: 24.0)],
                             range: NSRange(location: 0, length: 13))
```

- NSAttributedStringはStringのインスタンスを受け取り、変数に保持して、新しい振る舞いやプロパティを提供してくれます。
- NSMutableAttributedStringはNSAttributedString（あるいはString）のインスタンスを受け取り、以下同文です。
Rails　SNSの基本機能実装　エンジニア戦記#4

Progateでお勉強したことまとめ

学習コースⅡとⅢを完走

Twiiterを模したクローンSNSの作成
全体ページと詳細ページの作成

ガイダンスに従って、下記機能を実装しました。

★全体
投稿一覧ページを表示する機能
新規投稿ページへのリンクの貼り付け

★投稿詳細
投稿詳細ページにcreate_atを表示する機能

★新規投稿ページ

新規投稿ページを表示する機能
新規投稿ページに文字入力する機能
新規投稿ページにおける投稿ボタンから投稿一覧ページにリダイレクトする機能
新規投稿ページにおける投稿ボタンからデータベースに保存する機能
保存した投稿を一覧ページに表示する機能
保存した投稿をcreated_idの降順で表示する機能

【感想】

何気なく実現していた操作をプログラム単位で見ていくのは、
人間の行動を心理学、もしくは脳科学という単位で理解できるときと同じような快感がある
C言語は所詮高級アセンブラ

# C言語をセルフコンパイル出来るようになったらやっとC言語を習得できたと言っても良いんじゃないかな

レジスタ変数かメモリに割り付けられた変数かと最適化の具合によってで吐き出されるコードは異なりますが、C言語での演算子で `i++`とか`i += 2`、`i <<= 2`なんて構文はまるでアセンブリ言語みたいです。

```nasm
; i++
    inc     ax      ; ax = ax + 1

; i += 2
    add     ax, 2   ; ax = ax + 2

; i <<= 2
    shl     ax, 2   ; axを左に2ビットシフト
```

## コンパイルされた結果のアセンブリ言語を眺めてみる

昔話で申し訳ないのですが、Z80、MC68000、i8086とかの時代にC言語のコンパイル結果をアセンブリ言語で見るということをしていました。関数呼び出しでのスタックフレームの生成とか、オート変数がレジスタ割当でどのように実装されているかとか、関数の戻り値は必ずアキュームレータ (or 言語系で決めたレジスタ) に入れるとか、そのあたりを「ふむふむ」と眺めたり…。「そんなことの何が楽しいの？」と問われてもどうしようもないのですが、一人で「なるほど」と悦に入っていました。

## 自分でスタックフレームとか考えてみる

個人的にはC言語を初めて触ったのは、もうウン十年前ですが、学習当初はポインタの考え方を理解するのが大変でした (ポインタへのポインタとか、云々)。それもそのはず、C言語を高級言語と思い込んでいたからなんですね。カーニハンとリッチーの言ではないとは思うのですが、「**C言語は高級言語ではなくて高級アセンブリ言語である**」ということが理解できると、その辺りの誤解が氷解できると思うのです (CPUは何でも良いからアセンブリ言語をある程度理解していることが前提なのですが…。)。ポインタへのポインタの配列とかstructとかも、実際にどうメモリに配置されているかが想像できるようになると目からウロコが落ちる思いができるのではないかと思います。そして、スタックフレーム上に `char[100]` とかの配列を配置して、その操作を誤るとリターンアドレスを書き換えてしまってバッファーオーバーランが起こることとかも…。

いかに機械語 (アセンブリ言語) でCPUがメモリから値を読み出すか。それが理解できれば、実はポインタなんてお茶の子さいさいです。ポインタの概念が理解できると、もっと高級言語で登場するオブジェクトへのリファレンスなんて概念も、それぞれが、個々のオブジェクト変数はオブジェクト実体へのリファレンスのアドレスを持っていて、開放されるときにデストラクタで実体の参照数がデクリメントされて、参照数がゼロになったらオブジェクトそのものが開放される (説明のためものすごくはしょって言っていますし、この辺りは、個人的な妄想でUnixenのファイルシステムでリンク数が0になったら本当に削除されるという概念も引っ張ってきています) ということも想像が出来るようになるのではと思います。

C言語は、いささか解りにくいニーモニック (アセンブリ言語) を高級言語っぽく表記したもの + 関数やループとか条件分岐という構文を導入したものくらいに思っておけば理解が進むのではないのかなと思った次第です。

### 【余談その1】

扱ったことがないのですが、RISC CPUのパイプラインの最適化などに関しては人手でシコシコとやるよりはコンパイラ任せの方が最適化が効くのではないかと思いますが、個人的には大昔のCISCについては、人間の最適化とコンパイラの最適化とでは大差が出ないと思っています。

### 【余談その2】

若かりし頃に某シャープのX68000という機体を触ったときに、グラディウス (オマケで付属していた2Dシューティングゲーム) 以外にすることがなくなって、オマケの「**福袋**」のアセンブラでハノイの塔をプログラミングしたときはMC68000のアセンブリ言語はZ80やi8086のそれよりも直交性が高くて解りやすいと感動したものです。ついでに、純正のXC (純正のCコンパイラ、X-BasicからのCトランスレーターも付属していたと記憶しています) とGCC (言わずと知れたGNU Compiler Collection) のコードの美しさの違いに泣いた覚え (もちろん、GCCの方が何倍もスマートだったように記憶しています) というのもあります。

### 【余談その3】

アセンブリ言語のニーモニックからマシン語のバイナリに手で変換するのをハンドアセンブルと呼んでいました。でも、ハンドアセンブルすると、なぜか常にジャンプアドレスとかがズレるんですよね。やっぱり、アセンブルはアセンブラに任すべきです。

### 終わりに

今回はいいささかノストラジックで散文的な内容ですが、今でも少なからず需要のある組み込み系ソフトウェア開発の方に少しでも足しになればと思います。
【JavaScript】 call、apply、bindの使い方

thisの値は呼び出し方によって値が変わりますが、3つのメソッドを使ってthisの値を意図的に操作することができます。

##call
```JS
function greeting(func1, func2) {
    console.log(func1 + this.name + func2);
}

var myName = {
    name: 't0shimaru'
}

greeting.call(myName, 'はじめまして！ ', 'です！'); 
// → はじめまして！ t0shimaruです！
```

第1引数をthisの値としたいオブジェクトを引数として指定します。
第2引数以降はgreeting関数の引数になります。

##apply
```JS
function greeting(func1, func2) {
    console.log(func1 + this.name + func2);
}

var myName = {
    name: 't0shimaru'
}

greeting.apply(myName, ['はじめまして！ ', 'です！']);
// → はじめまして！ t0shimaruです！
```

applyはcallと同じように使うことができますが、第2引数以降を**配列として受け取る**ことができます。

##bind
bindは上記2つのメソッドと違い、呼び出されたときに**新しい関数を作成して**、値を操作します。
以下の例では、変数に関数を代入してその変数から呼び出しています。
第2引数以降にも値を指定することで、関数の引数として渡すことができます。


```JS
function greeting(func1, func2) {
    console.log(func1 + this.name + func2);
}

var myName = {
    name: 't0shimaru'
}

var newGreeting = greeting.bind(myName);
newGreeting('はじめまして！ ', 'です！');
// → はじめまして！ t0shimaruです！
```

 以上、自己紹介（？）を兼ねたメソッドの使い方でした！
Jetson Nano を JetPack 4.3 (r32.3.1) へアップデートして Jetson-IO tool を使用してみた。

2019年12月17日（米国時間）に JetPack 4.3（r32.3.1）がリリースされました。
イメージファイル　(nv-jetson-nano-sd-card-image-r32.3.1.zip) をダウンロードして SD カードへ書き込んで起動します。

```bash
$ cat /etc/nv_tegra_release 
# R32 (release), REVISION: 3.1, GCID: 18186506, BOARD: t210ref, EABI: aarch64, DATE: Tue Dec 10 06:58:34 UTC 2019
```

リリースノートは<A HREF="https://devtalk.nvidia.com/default/topic/1068583/jetson-nano/jetpack-4-3-l4t-r32-3-1-released/
">こちら</A>です。
JetPack 4.3 Highlights に気になる記載が・・。

- New easy to use Jetson-IO tool to configure 40-pin header on Jetson developer kits

さっそく Jetson-IO tool の<A HREF="https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fhw_setup_jetson_io.html
">リンク先</A>へアクセスする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/dfcf83d7-e113-c28a-1917-a5a18db693f8.png" width="75%">

手順に従って jetson-io.py を実行すると最初にエラーが出力される。

```bash
$ sudo /opt/nvidia/jetson-io/jetson-io.py
[sudo] password for jetson: 
Traceback (most recent call last):
  File "/opt/nvidia/jetson-io/jetson-io.py", line 25, in <module>
    from Jetson import board
ImportError: cannot import name 'board'
```

注意書き (Note) のとおり、ワークアラウンドを実行する。

```bash
$ sudo find /opt/nvidia/jetson-io/ -mindepth 1 -maxdepth 1 -type d -exec touch {}/__init__.py \;
```

もう一度 jetson-io.py を実行する。

```bash
$ sudo /opt/nvidia/jetson-io/jetson-io.py
$
```

一瞬、画面に何かが表示されて直ぐに終了してしまう。
less でエラー内容を確認する。

```bash
$ sudo /opt/nvidia/jetson-io/jetson-io.py | less
```

画面出力の最後の方に以下のエラーを確認。

```bash
FATAL ERROR!
No DTB found for NVIDIA Jetson Nano Developer Kit!
Press any key to terminate
```

NVIDIA Developer の<A HREF="<A HREF="https://devtalk.nvidia.com/default/topic/1069112/jetson-nano-developer-kit-spi-hell/?offset=9">ページ</A>で解決方法を見つけた。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/67c3bd95-dcea-8de0-803c-babb48ff915d.png" width="75%">

DTB ファイルが /boot ディレクトリ配下に存在しているので、/boot/dtb ディレクトリを作成して、その中にコピーする。

```bash
$ cd /boot
$ sudo mkdir dtb
$ sudo cp *.dtb* dtb/
```

再度、jetson-io.py を実行する。

```bash
$ sudo /opt/nvidia/jetson-io/jetson-io.py
```

ようやく、起動画面を確認できました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5ddbd9ca-dae3-d190-cd8c-9429ecc7f739.png" width="75%">
Githubのwebブラウザ上で手軽にブランチを切る方法

Githubのwebブラウザ上の[Upload files]をクリックし、変更対象のファイルまたはフォルダをドラッグする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/7198aa65-1e7c-a7e4-7f82-836db2e58a14.png)

アップロード後のコミットの画面で、<font color="RED">**[Create a new branch ...]**</font>にチェックを入れてコミットする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/54f727bd-b98b-a6e0-d25f-fee5eb4d4fd9.png)
Glideでの親子関係(リレーション)の持たせ方

# Glideとは
スプレッドシートからノンコーディングでPWAアプリが作れるツワモノツール。
https://www.glideapps.com/

基本的な使い方はPaizaさんの記事でわかりやすく説明されています。
初めてGlide触るよって方はこちらを是非。：[簡単過ぎる！GoogleスプレッドシートからPWAアプリを開発できる「Glide」を使ってみた！](https://paiza.hatenablog.com/entry/2019/04/10/%E7%B0%A1%E5%8D%98%E9%81%8E%E3%81%8E%E3%82%8B%EF%BC%81Google%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88%E3%81%8B%E3%82%89PWA%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E9%96%8B)

# なぜ書くのか
見た感じ絶対できそうなのに、なかなかやり方がわからず苦戦したのでこちらに書き残しておきます。
ソースは公式ヘルプの[こちら](https://docs.glideapps.com/all/guides/quick-starts/intermediate-techniques/introduction-to-references)
(公式にあるやんけ、と言われそうだけど字幕なし英語動画だったんだ察してくれ…)

# 前提：Glideの親子関係(リレーション)
Glideにはリレーション用のコンポーネントが3種類あります。
- Relation：1対1のみ
- Inline List：1対1、1対多(レコードの中にリレーション先の情報を簡易表示させられる)
- List Relation：1対1、1対多(レコード内からリレーション先に移動できる)

※Relationコンポーネントのみ1対1にしか対応していないため、後に出てくるDataメニューでの設定で「Mutch Multiple」にチェックを入れたリレーション列には使えません。 

(この他にも[SubcategoriesとかHierarchies](https://docs.glideapps.com/all/guides/deep-dives/data/subcategories)とかあるっぽいけど今回は触れません。)

##作るもの
今回はTodo管理アプリもどきを作る前提で進めていきます。
ひとつのアプリの中に複数のカテゴリ(親)があり、その中にTodo(子)が格納されるイメージ。

## スプレッドシート(もととなるデータベース)
リレーションを組む時は子となるTodoをひとつのシートにまとめる必要があります。
カテゴリごとにシートを分けたくなりますが我慢です。**親は親、子は子でひとつのシート**です。
また、カテゴリとTodoを紐付けるためのキーとなる項目が必要なので、
カテゴリにはA列に「カテゴリ名」、TodoにはC列に「カテゴリ」で作成しておきます。

**カテゴリシート**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228212/457819ee-6421-cc49-9530-1bcd88e4137e.png)

**Todoシート**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228212/6a30a359-2654-8012-dda2-9c5447c3e347.png)

## Glide Dataでのリレーション設定
Dataメニューを開いてリレーション設定を行います。
※このDataメニューでの列の追加はあくまでGlide内でだけ適用され、元のスプレッドシートへは反映されないので注意。(最初追加した列がスプレッドシート側に出てこなくて混乱した。元データを汚さずにいじれるようにというGlideの配慮…)

親となるシートを開いた状態で右上にある「Add Column」をクリック。
<img width="1916" alt="スクリーンショット 2020-01-05 15.32.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228212/dbd8cdcb-369e-aa96-8fee-dba7fe926b1c.png">

項目を設定します。
Label：適当な名称(後ほどレイアウト設定するときにわかりやすければなんでもOK)
COLUMN TYPE：Relation
CONFIGURATION：キーとなる列をそれぞれ選択(上が現在のシート、下に紐付けたいシート内の列を入れます)
Match multiple：チェック(今回は1対多のリレーションのため。)
<img width="1920" alt="スクリーンショット 2020-01-05 15.35.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228212/3e43e876-f1c8-60a4-0da1-4c5f3a566e47.png">

これでリレーション設定は完了です。

# Glide Layoutにリレーションコンポーネントを追加
実際にアプリ上にリレーションコンポーネントを追加します。

親となるTabを開き、適当なレコードを開く
→ 右上の「+」ボタンを押してコンポーネントを選択。
今回はレコード内の情報も少ないため、コンポーネントは「Inline List」を使います。

<img width="1278" alt="スクリーンショット 2020-01-05 16.04.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228212/ee4ea49f-203c-9322-3055-a1ae4e426a71.png">

Sourceに先ほどDataメニューで作成した列を指定すればリレーションの出来上がりです。
上はスタイルをCompact Listにしていますが、Checklistでもいいかもしれない。
ということで変更。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228212/61486709-160c-8528-0b7d-b5f2796b2a1f.png)
スプレッドシート上で列「完了」を追加して、チェックボックスの受け皿にしてみました。

あとはその他のレイアウトを整えて完成です。

## 完成
完成品はこちら
→ https://qiitatask.glideapp.io
親子階層が使えると一気に使える範囲が広がると思うのでこの記事が参考になれば幸いです。
(アプリそのもののコピーを許可したいのに設定に飛ぼうとすると何故か落ちる…後日いけそうだったら設定変更しておきます。)
Spring BatchでBeanを入れ子にすると正常に処理されない問題の解決方法

# 概要

たとえば、Chunk指向Taskletを表すクラスを作成しようと `FlatFileItemReaderBuilder`, `ItemProcessor`, `JdbcBatchItemWriterBuilder` を保持するクラスを定義したくなるかもしれない。

しかしながら、このクラスを `Bean` として登録しても `JdbcBatchItemWriterBuilder` は下記のようなエラーが出て正常に動作しない。

```:出力されるエラー
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)]; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: SQLステートメントに文法エラーがあります "INSERT INTO PEOPLE (FIRST_NAME, LAST_NAME) VALUES (:[*]FIRSTNAME, :LASTNAME)"; 期待されるステートメント "), DEFAULT, NOT, EXISTS, INTERSECTS, UNIQUE"
Syntax error in SQL statement "INSERT INTO PEOPLE (FIRST_NAME, LAST_NAME) VALUES (:[*]FIRSTNAME, :LASTNAME)"; expected "), DEFAULT, NOT, EXISTS, INTERSECTS, UNIQUE"; SQL statement:
```

なぜか `:firstName` が `?` に変換されていないのである。
（もちろん `JdbcBatchItemWriterBuilder` を直接 `Bean` として登録した場合は正常に動作する。）


# 原因

Bean はすべて登録した時点で、`InitializingBean` を `implements` しているクラスについては `afterPropertiesSet()` が呼ばれることで登録が正常に完了する。
しかし、Bean となるべきオブジェクトを入れ子として保持している場合は、これが呼ばれないために正常に登録完了していない状態となるのだ。

# 解決法

保持している親側のクラス(＝直接 `Bean` として公開されるクラス)で下記のように `InitializingBean` を実装して保持しているオブジェクトに伝播させる。

```java
@Override
public void afterPropertiesSet() throws Exception {
    Object[] objects = new Object[]{this.reader, this.processor, this.writer};
    for (Object object : objects) {
        if (object instanceof InitializingBean) {
            ((InitializingBean) object).afterPropertiesSet();
        }
    }
}
```
emacs25 で list-packages 時に Failed to verify signature となり失敗する

## 環境

* 18.04.3 LTS (Bionic Beaver)
* GNU Emacs 25.2.2

## 症状

emacsのパッケージを追加したくて `list-packages` してインストール済みのものを見たりしていたところ、以下が表示された。

```
Failed to verify signature archive-contents.sig:
No public key for 066DAFCB81E42C40 created at 2020-01-05T07:05:03+0900 using RSA
Command output:
gpg: Signature made 2020年01月05日 07時05分03秒 JST
gpg:                using RSA key C433554766D3DDC64221BFAA066DAFCB81E42C40
gpg: Can't check signature: No public key
```

## 原因と対処

古いバージョンのemacsのsignature keyが期限切れしていたみたいです。
emacs26にしたら解決しました。
(新しいkeyを取得することでも解決できるとのことですが、バージョンアップする方が手っ取り早そうだったので…)

> The signature check failed because you don't have the new key (the old signature key expired on Sep 23). 

https://stackoverflow.com/questions/58202993/emacs-failed-to-verify-signature-archive-contents-sig

### 対応手順

手順は以下を参考にしました。
http://ubuntuhandbook.org/index.php/2019/02/install-gnu-emacs-26-1-ubuntu-18-04-16-04-18-10/

問題が起きていたとき

```
$ emacs --version
GNU Emacs 25.2.2
Copyright (C) 2017 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
rtt min/avg/max/mdev = 91.265/119.994/171.319/31.208 ms
```

使うのはnox版なので、こちらだけinstall

```
$ sudo apt install -y emacs26-nox
```

古いものは削除

```
$ sudo apt remove --autoremove emacs25*
```

version確認

```
$ emacs --version
GNU Emacs 26.3
Copyright (C) 2019 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
```

emacs26になりました、OK。

`Failed to verify signature ...` は無事出なくなりました。
監視論Ⅱ ～外部SREの可能性～

#はじめに
2019年に[監視論](https://qiita.com/qryuu/items/c55b1e8c472eb716f616) を発表し多くの「いいね」を頂きありがとうございました。

システム監視を取り巻く環境は、DevOpsやサーバーレス、Observabilityなど進化を続けている。

2020年はこれらの動向を踏まえて、監視エンジニアやMSP事業者に求められる役割について考察する。

#SREの役割
SRE（Site Reliability Engineering）の役割は性能、可用性、セキュリティーを担保し、サイト（サービス）の信頼性を確保することである。

このためにインフラモニタリングやAPM（Application Performance Management）を行いリソースやアプリケーション実装上の問題点を見つけ出し対応策を策定することが重要となる、

#監視の役割は開発ではない
SREが登場した当時DevOpsの文脈が強くOpsやSREも開発を行うという総員コーダーのような雰囲気が強くなった。
しかし、DevとOpsはそれぞれ適性も異なり、どちらかがどちらかの上位互換という分けでもない。
OpsやSREの本領はパフォーマンスの分析でありそこで求められる能力は統計やログ解析、アプリケーション解析である。

一部のスーパーエンジニアや小規模、少数精鋭のスタートアップであれば開発者兼SRE
一人DevOpsなどのアプローチが可能であるが
大規模SaaSなどであればSREとソフトウェアデペロッパーは別のチームとなる。

そこでSREやOpsに求められる役割はモニタリングに基づいたソフトウェア改修ではなく、
改修するための根拠となるデータを示し、**設計フェイズに対してフィードバックを行う**事である。
#設計と監視 Opsサンドイッチ
ごく小規模な体制でなければ、OpsやSREとDevは別の組織となる。
そこでOpsが行うべきは自分たち自身がDevになることではなく、Devが適切な改修を行えるようにその前段階の設計に対して実装要件としてフィードバックを行う事である。
![監視論Ⅱ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/091799ba-24ae-0fda-9c89-5d16c7d75e9e.png)

インフラモニタリングはマルチスレッドプログラミングの偏りやメモリリークを検知可能であり

ミドルウェアモニタリングはDBコネクションプーリング実装の不備を検知可能であり

APMでは非効率な再帰呼び出し実装や外部SaaSとのデータ連係実装の効率を判別することが可能である。

これらはあくまでも測定値であり値から意味を読み取り設計へとフィードバックすることがこれからのMSP事業者やSREに求められる能力である。

#まとめ
MSP事業者やSREは開発能力ではなく読影能力および設計能力を高める事が重要である。
この能力および設計にフィードバックを行うというモデルであればMSP事業者が社外SREとして機能することが可能となる。

これらのMSPやSREが真に力を発揮するためには分析に基づくフィードバックを適切にソフトウェアの実装に反映する開発体制が必要となる。

旧来からの長期間ウォーターフォール開発ではフィードバックを適切に反映することは困難である。

分析対象となるデータ期間を考慮すればモニタリングからのフィードバックを反映しその効果を確認するまでの期間は1週間以内長くとも1ヶ月以内が理想的である。

そのためにはMSPのレポートサイクルも同様に短縮する必要があり、さらに開発モデルも
同様にショートウォーターフォールあるいはアジャイルモデルが必要となる。

モニタリングデータの読影には経験や専門知識が必要であり、これを全ての開発組織が保有するよりは、MSP事業者が専門家として提供する方が日本においては現実的であると考えられる。

その上でMSPを社外SREとして有効に活用するためには開発組織の進化も必要である。
[Storage] ファイルをアップロードするフォーム

前回Azure StorageのBlob Storageにコンテイナーを作成し、ファイルをアップロードする方法を公開しました。今回は実際にユーザーのフォームからファイルをアップロードするフローをカバーします。

前回の記事はこちら:point_down_tone2:
https://qiita.com/syantien/items/ee8c88c649d5b0617ccd

# フォーム (フロント、Razor)

```html

@using (Html.BeginForm("UploadFiles", "Blob", FormMethod.Post, new { @enctype = "multipart/form-data" }))
{
    @Html.Hidden("container", ViewData["Container"])
    @Html.TextBox("files", "", new { @type = "file", @multiple = "mulitiple" })
    <button type="submit" class="btn btn-primary rounded-0">Upload</button>
}
```

# コントローラー (処理)

```csharp

[HttpPost]
public async Task<IActionResult> UploadFiles(List<IFormFile> files, string container)
{
  var result = await _blobHandlers.UploadFilesAsync(files, container);
  return RedirectToAction("Container", new { @id = container });
}
```

上記にある`_blobHandlers.UploadFilesAsync`は下記のとおりです　

```csharp

/// <summary>
/// Upload files
/// </summary>
/// <param name="FileToUpload"></param>
/// <param name="container"></param>
/// <returns></returns>
/// <summary>
/// Upload files
/// </summary>
/// <param name="FileToUpload"></param>
/// <param name="container"></param>
/// <returns></returns>
public async Task<List<string>> UploadFilesAsync(List<IFormFile> FileToUpload, string container)
{
  var AbsoluteUris = new List<string>();

  // Get azure table storage connection string.  
  string ConnectionString = _config.Value.AzureBlobSettings.connection;
  CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);

  CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();

  var blobContainer = cloudBlobClient.GetContainerReference(container);

  // If container does not exist
  if (!blobContainer.Exists())
  {
    await blobContainer.CreateAsync();

    // Set the permissions so the blobs are public.
    BlobContainerPermissions permissions = new BlobContainerPermissions
    {
      PublicAccess = BlobContainerPublicAccessType.Blob
    };
    
    await blobContainer.SetPermissionsAsync(permissions);
  }

  foreach (var formFile in FileToUpload)
  {
    if (formFile.Length > 0)
    {
      try
      {
        string FileName = Path.GetFileName(formFile.FileName);

        CloudBlockBlob blockBlob;
        // Create a block blob  
        blockBlob = blobContainer.GetBlockBlobReference(FileName);

        // Set the object's content type  
        blockBlob.Properties.ContentType = formFile.ContentType;

        // upload to blob  
        blockBlob.UploadFromStream(formFile.OpenReadStream());

        // get file uri  
        AbsoluteUris.Add(blockBlob.Uri.AbsoluteUri);
      }
      catch (Exception ExceptionObj)
      {
        throw ExceptionObj;
      }
    }
  }
  return AbsoluteUris;
}
```

# 終わり

今回は以上です
Githubのwebブラウザ上でリポジトリのサブフォルダを手軽に作成する方法

PC上で対象のフォルダを作成し、その中にアップロードファイルを1つ以上作成しておく。

Githubのwebブラウザ上の[Upload files]をクリックし、Explorerから作成した<font color="RED">**フォルダをドラッグ**</font>する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/7198aa65-1e7c-a7e4-7f82-836db2e58a14.png)