OmniAICreator/Qiita-1.07M huggingface dataset:
こわくない英語（初級編）

### はじめに
グローバルなプロジェクトやOSSコミュニティへの参加などで、英語を書く機会が増えている人も多いかと思います。
そんな時にちょっとだけ気を付けると良い感じに見えるポイントがあるので、つらつらと紹介してみます。
※個人の経験に基づいたネタなので`ガチな英語スキル`は期待しないでください

### 気を付けると良いポイント
実はどれも中学生の英語で習う内容ですが、意外と適当に書いている人が多いです。
違っていても問題なく意味は通じますが、かなり『英語苦手』感が出てきます。
日本語で言う『てにをは』みたいな感じです。
逆にこの辺がきちんと書かれていると『英語慣れてる』感が出てとても良いです。

#### 1. 三人称単数形

注意するのは以下の2点です。

##### 1-1. 一般動詞の語尾に`s`を付ける
いわゆる『三単現のs』です。

```:誤り
He play guitar.
```

『彼』は三人称で単数なので動詞には`s`を付けましょう。

```:こう書く
He plays guitar.
```

『`s`じゃなくて`es`を付ける』とか
『`y`を`i`に変えて`es`を付ける』とか
いくつか変化パターンがありますが、迷ったらググれば良いので無理して覚えなくて良いです。


##### 1-2. `do` と `does` を使い分ける
『否定文は`don't`を使う』という教えが強烈なのか、こういう例を良く見かけます。

```:誤り
My computer don't work.
```

『私のパソコン』は三人称単数なので`does`が正解です。

```:こう書く
My computer doesn't work.
```

これの逆パターンも多くて、自分（一人称）、あなた（二人称）、それ以外は三人称という覚え方のせいか、こんな風に書いちゃうことがあります。

```:誤り
They doesn't work.
```

『彼ら』は三人称ですが複数なのでこちらは`do`が正解です。

```:こう書く
They don't work.
```

そもそも`does`は`do`に三単現の`s(es)`を付けたもの、と覚えると良いです。


#### 2. 自動詞と他動詞

日本語だとあまり意識しないのですが、英語では`自動詞`と`他動詞`を明確に区別します。
辞書を引いても動詞には必ず自動詞か他動詞なのか明記されています。

[英次郎で『run』を引いた場合の例](https://eow.alc.co.jp/search?q=run)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15083/b33acb33-8d29-9a08-fbf0-8ed4403a6117.png" width="700">

例えば『問題が解決した』という文を英語で書きたい場合、問題（problem）が解決する（solve）なので反射的に

```:誤り
The problem solved.
```

と書いちゃうことがありますが、`solve`は他動詞なので『（主語が）他の何かを解決する』というパターンで使うのが正しいです。

なので、こんな風に主語を補完して問題が目的語になるように書くか

```:こう書く
We solved the problem.
```

もしくは、ひっくり返して受動態で書くと良いです。
このパターンだと無理に主語を補完しなくてもいいので自然な形になることが多いです。

```:こう書いても良い
The problem was solved.
```
    
ここから派生するいくつかのポイントがあります。

##### 2-1. 能動態と受動態
[日本語はとてもハイコンテクストな言語](https://www.crimsonjapan.co.jp/blog/translation-issues-context/)なので、先の『問題が解決した』のように字面からだけでは能動なのか受動なのかは区別できない（しない）ことが多く、文脈を読み取って解釈することが求められます。

一方で英語はキッチリ区別したい言語なので、文章は能動態（普通に一般動詞を使う）か、それとも受動態（わざわざbe動詞＋過去形にする）を使い分け、これに合わせて使える動詞も自動詞なのか他動詞なのか決まってきます。

英語で書く場合には、自分の言いたい事が『能動態なのか受動態なのか』を意識すると良い感じに書ける場合が多いです。

```:能動態で書くと良い例
問題を調査する。
I'll investigate that problem.
```


```:受動態で書くと良い例
問題が解決した。
The problem was solved. 
```


##### 2-2. 隠れた主語
同じく日本語はとてもハイコンテクストな言語なので、先の『（我々が）問題が解決した』のように本当の意味での主語を省略することも多いです。

英語で書く場合には、自分の言いたい事が『だれ（何）が主語なのか』を意識して、足りない場合には補完してあげると良い感じに書ける場合が多いです。

```:主語を補完すると良い例
アーキテクチャを決定した。
    ↓
（我々は）アーキテクチャを決定した。
    ↓
We have decided that architecture.
```

#### 3. 複数形
日本語はとてもハイ（中略）、特に物については数が単数なのか複数なのかを区別しません。
人の場合はさすがに使い分けます。（『私』と『私たち』とか）

例えば『私は本を買いました』と『私はたくさん本を読みます』はどちらも『本』ですが、普通に日本語的に考えると前者は単数で後者は複数です。



一方で英語では人や物の数が単数か複数かをかなり神経質に区別します。
特に三人称の場合だと、先の例で挙げたように単数か複数化で動詞の形が変わってきたりします。

なので英語で書く場合には、登場する人や物が単数なのか複数なのかを意識してみると良いです。

```:単数
私は本を買いました。
I bought a book.
```

```:複数
私は本をたくさん読みます。
I read many books.
```

### 最後に
色々と偉そうに書きましたが
『こう書かなくちゃダメ』
というよりも
『こう書いたら自己満足できて気持ち良い』
程度に受け取ってもらえればと思います。

気が向いたら続編も考えてみます。

__Have a happy writing !!__
情報共有の手段に迷った時のフローを独断と偏見で作ってみた

最近ではSlackやTeamsといったグループウェアが頭角を現し、情報共有の手段も多様化しています。

グループウェアが流行っているといってもまだまだ過渡期なので、疎い上司や年配社員などは見向きもしてくれないこともしばしば。

そうなってくると、従来のメールや電話といった手段との使い分けが重要になってきます。

そこで、私が自分の経験を元に、フローにまとめてみました。

うちの会社だけの偏った部分もありますので、完全に企画向けのネタぐらいに思っていただければ幸いです。

（好評だったら、うちの会社の新人教育資料に使ってしまうかも）

では、早速フローです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267148/2b8f0490-b16b-54f7-3478-1357ebebd01e.png)
AWS ソリューションアーキテクトアソシエイト９

##IAMによるIDフェデーション
**IDフェデーション**とは。企業や組織などですでに導入されている認証の仕組みとAWSの認証を紐付け、シングルサインオンを実現する機能です。
この機能により、AWSのIAMに全社員のユーザー認証情報を登録する必要はなく、企業ですでに導入されているLDAPなどの認証の仕組みと連携することで、AWSサービスを簡単に利用できます。
たとえば、企業ですでに導入されているLDAPの認証基盤で認証された社員に対しては、AWSのS3へのアップロードも許可するといった認証連携が可能となります。
また、GoogleやFacebookなどのソーシャルサービスで使われている認証情報とも連携が可能です。

###SAML2.0を使用したIDフェデレーション
IAMでは、SAML（Security Assertion Markup Language）2.0やOpenID Connectと互換性のある認証プロトコルをサポートしています。
SAML2.0やOpenID Connectは、IDフェデレーションによるシングルサインオンを簡単に実現するためんいのプロトコルです。認証したユーザーごとに一時的なアクセスキー（Temporary Security Token）を発行することで認証連携を実現します。
AWSへの一時的なアクセスキーは、AWSのSecurity Token Service（STS）と呼ばれるサービスで管理・発行されます。

###Web IDフェデレーションによるソーシャルサービスとの連携
GoogleやFacebookなど、OpenID ConnectをサポートしているソーシャルサービスとIDフェデレーションすることで、AWSへのシングルサインオンが可能です。
これを**「Web IDフェデレーション」**と呼びます。
なお、Webアプリケーションやモバイルアプリからの認証では、Amazon Cognitoサービスを利用することで、各ソーシャルサービスとの認証連携が簡単に実現できます。

###Directory ServiceによるMicrosoft ADとの認証連携
AWS Directy Service (Directory Service)は、AWSのクラウド内で管理されるマネージド型のMicrosoft ADです。
主に以下の３つのディレクトリタイプを提供します。

- Microsoft AD
- Simple AD
- AD Connector

Microsoft ADでは、AWS上でActive Directoryサービスを利用できます。
Simple ADでは、AWS上でActive Directory互換のSambaサービスを利用できます。
AD Connectorは、既存のActive Directory環境へ接続するためのプロキシサービスです。たとえば、企業内の認証基盤としてすでにMicrosoft ADを使用している場合、Directory Serviceが提供するAD Connecorを利用することで、AWSで必要となる認証を既存のActive Directoryへ接続して認証連携を行うことができます。
取り違えは何通り？


![Q.1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/73c95bcb-c114-d1eb-1d1a-21678dca4d92.png)

# 出題
一人一台のパソコンを支給されている社員N人全員が、他人のパソコンを使う組み合わせは何通りあるか？

# 考え方
これは場合の数における完全順列(攪乱順列とも呼ぶ)と言うもの
Nが2～4までなら手動で解いた方が楽だが、それ以上の場合は漸化式を使う必要がある。
もし総当たりで解こうとすれば非常に難問となる。

ここはありがたく過去の偉人の英知にすがる事にします。
完全順列の総数を求める漸化式はこれ。
![ざんか式.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/7aa241ff-45ac-f1f9-12aa-25ec5f21bd31.png)

これを見るとA1 or A2 になるまで再帰的に呼び出せば良い事がわかる。

# 回答
以上の内容によりこんな感じにしてみた。

```C
/* 完全順列の個数(モンモール数) */
long long montmort_number(int n) {

    if (n == 1) {
        return 0;
    }
    else if (n == 2) {
        return 1;
    }
    return (n - 1) * (montmort_number(n - 1) + montmort_number(n - 2));
}

int main() {
    int i, l, N;
    char s[80];

    for (; ~scanf("%s", s);) {
        l = strlen(s);
        for (N = 0, i = 0; i < l ; i++)
            N = (N * 10) + s[i] - '0';

        sprintf(s, "%lld", montmort_number(N));

        puts(s);
    }
    return 0;
}
```


```C
[結果]
montmort_number(1) => 0
montmort_number(2) => 1
montmort_number(3) => 2
montmort_number(4) => 9
montmort_number(5) => 44
montmort_number(6) => 265
montmort_number(7) => 1854
```

# 感想
4人までなら手動で試すのもありだけど5人以降だと難しいかな。
7人だと**1854/5040**通りもあるのか。

ソースの動作は再帰を使っているので非常に遅い。
繰り返しの処理を使えればもう少し早くなると思う。
Python超初心者の超初心者のためのPython #リスト

環境
windows7　（Mac Book Pro 16inch欲しい）
Visual Studio Code
chrome
python ver3.8.3

この記事はプログラミング初心者かつPython初心者に向けて記述します。

##リスト（配列）

リストとは例えると箱の中に値（数値、文字列）を入れるモノです。
どのようにその箱（リスト）を作るかというと、Pythonでは角括弧の`[  ]`です。
この`[   ]`の中に値（数値、文字列）を入れてあげます。

```python:list.py
[1,2,3,4,5]

['peach','princess','kuppa','mario']

```

このように個々の値を,(カンマ)で区切り箱（リスト）の中に入れていきます。

箱（リスト）を作っただけでは機能しないので、使い方は下記のように`変数`
と一緒に使います。

```python:list.py
num_list=[1,2,3,4,5]

mmaker=['peach','princess','kuppa','mario']

print(num_list)
#[1, 2, 3, 4, 5]

print(mmaker)
#['peach', 'princess', 'kuppa', 'mario']

```

###多重リスト
箱（リスト）の中にはもう一つの箱（リスト）も入れることが出来ます。
これを`多重リスト`と言います。
`多重リスト`の作り方は直感的で簡単です。
[   ]の中にもう一つ[   ]を作ってあげます。

```python:list.py
['peach', 'princess', 'kuppa',[1, 2, 3, 4, 5], 'mario']

```

気をつけるところは新たに追加した`[   ]`の前後には`,`の記述を忘れないことでしょう。
例：変数名　＝　[1,2,3`,[9,8,7],`4,5,6]のようにです。

```python:list.py
mmaker_num = ["peach", "princess", "kuppa", [1, 2, 3, 4, 5], "mario"]

print(mmaker_num)
#['peach', 'princess', 'kuppa', [1, 2, 3, 4, 5], 'mario']
```

####ちょこっと応用
箱（リスト）は様々な使い方がありますが、変数に代入された値を要素として指定することも出来ます。
何言ってるかというと、下記の通りです。

```python:list.py
x='mario'
p='peach'

hero=[x,p]

print(hero)
#['mario', 'peach']

```

途中で変数に代入された値を邪魔（変更）されても箱（リスト）の値は変わりません。

```python:list.py
x='mario'
p='peach'

hero=[x,p]

print(hero)
#['mario', 'peach']

x='luigi'
print(hero)
#['mario', 'peach']

```

fin

##目次

[Python超初心者の超初心者のためのPython #Hello World](https://qiita.com/Macchino5/items/ddc0f4abc6168bab3448)

[Python超初心者の超初心者のためのPython #こんがらがりやすいとこ](https://qiita.com/Macchino5/items/25862df5f851d09e55d4)

[Python超初心者の超初心者のためのPython #型（type）と型（type）の確かめ方](https://qiita.com/Macchino5/items/caf4d6936f274cd7502a)

[Python超初心者の超初心者のためのPython #型（type）を変換する方法：str編](https://qiita.com/Macchino5/items/23183f8b2a945d8ecc5e)

[Python超初心者の超初心者のためのPython #型（type）を変換する方法：int、float編](https://qiita.com/Macchino5/items/9d14ab0c50d228464eac)

[Python超初心者の超初心者のためのPython #.txtファイルを作業中の.pyで読み込む](https://qiita.com/Macchino5/items/6675f1079e9c9ed945bb)

[Python超初心者の超初心者のためのPython #関数1](https://qiita.com/Macchino5/items/c403a2a997a0247adc96)

[Python超初心者の超初心者のためのPython #関数2](https://qiita.com/Macchino5/items/95750957b6ce266add50)

[Python超初心者の超初心者のためのPython #len関数]
(https://qiita.com/Macchino5/items/a64347f9e832406d3c24)
オライリー本　入門監視を読んで

#はじめに
オライリーの[「入門　監視　モダンなモニタリングのためのデザインパターン」](https://www.oreilly.co.jp/books/9784873118642/)を読んでみた。今回はその中の第Ⅰ部　監視の原則についての要約と感想を書きたい。

#要約
第Ⅰ部　監視の原則の構成は１章監視のアンチパターン、２章監視のデザインパターン、３章アラート、オンコール、インシデント管理、４章統計入門となっている。

１章監視のアンチパターン　
そもそもアンチパターンとは
「ソフトウエア開発が失敗に陥る際に多く見られる、間違ったソリューション（解決策）をパターンとして整理し、さらには失敗を避けるにはどうしたらいいのかを示してくれるもの」https://thinkit.co.jp/article/929/1

監視におけるよくない例を示している。
・ツール依存をしすぎてはいけない。
・監視とは他の仕組みと複雑と複雑に組み合わさった運用のため、全員がやるべき仕事であり、チームや部署内での役割ではない。
・監視するだけで壊れたものは直せない。
・手順書が単に手順を追って解決できるものであれば、その手順を自動化できないか検討すべき。

2章監視のデザインパターン
・リスクヘッジ等を考えて組み合わせ可能な監視の仕組みにした方が良い。
・ユーザー視点に立って監視の可視化を考える
・監視の仕組みを作るのではなくSaaSを使うことを考えるべき
・仕組みを作ったら終わりではなく、改善し続けよう

３章アラート、オンコール、インシデント管理
・効果的な監視システムの管理について言及されていた

４章統計入門
・ データに対してどんなアプローチが最適なのかを見つけるためには、統計分野で多くの作業が必要である。統計的手法を解説してあり、どのデータの場合うまく適用できるのかまとめてあった

詳しい内容については本を参照してください。

#この本の主な対象者
入門とだけあって、「監視に興味がある人、多少監視の知識・経験はあるが体系的に学びたい人」におすすめ。
逆に監視に詳しい人はこんな事はすでに知っているという内容が大半だと思うので、上記の要約で特に読む必要がないと感じたら、[ソフトウェアエンジニアのためのITインフラ監視［実践］入門](https://www.amazon.co.jp/gp/product/B01ARADUEU?pf_rd_r=252RFBX50YEHPXN821M3&pf_rd_p=7392bae8-7129-4d1a-96a9-1cfe0aa13ab3)など別の本がよいかもしれません。

#まとめ
基本的に監視は複雑なシステムの塊なので、幅広い知識が必要で色々な人とコミュニケーションを取らなければいけない。監視というと狭い分野だと思われるが、全てのシステムで行われている運用であり、様々な可能性を考える必要があるとこの本を見て気づけた。

また監視頼みにしてシステム自体の変更を行わなかったり、一度監視体制を作成したら終わりではいけない。常にPDCAをして改善し続ける必要がある。

どのITの分野でも言えるかもしれないが、コミュニケーションやPDCAを回して改善することの大切さに改めて気付かせてくれる一冊であった。
Google Spreadsheetのセル内にあるリッチテキストをHTMLへ変換したい

# 背景

Google Spreadsheetのセルにはテキストスタイル付きのリッチテキストを入力することができます。このリッチテキストをHTMLに変換したいとき、残念ながら今のところ直接変換するようなメソッドは用意されていません。そこでセル内のリッチテキストをHTMLに変換するためのスクリプトを作成しました。これは以前作成したライブラリ[RichTextApp](https://github.com/tanaikech/RichTextApp)へ追加メソッドとして使用できるようにしました。

リポジトリは[こちら](https://github.com/tanaikech/RichTextApp)です。

# ライブラリのプロジェクトキー

```
1Ka6RcIG6G9P8AhkJtjy1DAnHk1_rShFPWtdCQ2bxwMsrRE8cfn0cDXBv
```

インストール方法は[こちら](https://developers.google.com/apps-script/guides/libraries)でご確認いただけます。

# 使用方法

ご使用中の GASプロジェクトへライブラリをインストールした後、下記のサンプルスクリプトを使用することができます。

## サンプルスクリプト

下記のサンプルスクリプトは、セル"A1:A2"のリッチテキストをHTMLに変換し、結果は2次元配列として返されます。セルが一つの場合は、配列には入らず、文字列としてHTMLが返されます。デフォルトの文字が入ったセルを変換すると、そのフォントのサイズや種類などが入ったHTMLが作成されます。

```javascript
function RichTextToHTMLForSpreadsheet() {
  var ss = SpreadsheetApp.openById("###");
  var sheet = ss.getSheets()[0];
  var range = sheet.getRange("A1:A2");
  var res = RichTextApp.RichTextToHTMLForSpreadsheet({ range: range });
  console.log(res);
}
```

- 変換後のサンプルの結果はこちらでご覧いただけます。[https://jsfiddle.net/7e3mc10p/](https://jsfiddle.net/7e3mc10p/)

## 注意点

このライブラリは、V8 が有効であることを前提としています。
【学習メモ】Strong Parameters と accepts_nested_attributes_for

#目次
1.背景
2.Strong Parametersについておさらい
3.モデルに、accepts_nested_attributes_forを使っている場合
4.参考

##1.背景

Railsでオリジナルアプリを開発しているが、「Unpermitted parameter: :_destroy」という表示が出てしまい、それをRailsガイドを確認しながら解決させたので、その学びをアウトプットするため、記載する。


##2.Strong Parametersについておさらい

Railsガイドの説明によると、Strong Parametersとは、

>strong parametersを用いることで、Action Controllerのパラメータが許可されるまでActive Modelの「マスアサインメント」に利用されることを禁止できます。つまり、多くの属性を一度に更新したい場合は、どの属性のマスアップデートを許可するかを開発者が明示的に指定しなければなりません。大雑把にすべての属性の更新を一括で許可してしまうと、外部に公開する必要のない属性まで誤って公開してしまう可能性が生じるため、そのような事態を防ぐための機能です。

>さらに、パラメータの属性に「必須 (required)」を指定することで、事前に定義したraise/rescueフローによって、渡された必須パラメータが不足している場合に「400 Bad Request」で終了させることもできます。

そして、Controllerの例について、こちらもRailsガイドの例を参照。

```ruby:controller.rb
class PeopleController < ActionController::Base
  # 以下のコードはActiveModel::ForbiddenAttributesError例外を発生します
  # 明示的な許可を行なわずに、パラメータを一括で渡してしまう
  # 危険な「マスアサインメント」が行われているからです。
  def create
    Person.create(params[:person])
  end

  # 以下のコードは、パラメータにpersonキーがあれば成功します。
  # personキーがない場合は
  # ActionController::ParameterMissing例外を発生します。
  # この例外はActionController::Baseにキャッチされ、
  # 400 Bad Requestを返します。
  def update
    person = current_account.people.find(params[:id])
    person.update!(person_params)
    redirect_to person
  end

  private
    # 許可するパラメータはprivateメソッドでカプセル化します。
    # これは非常によい手法であり、createとupdateの両方で使いまわすことで
    # 同じ許可を与えることができます。また、許可する属性をユーザーごとにチェックするよう
    # このメソッドを特殊化することもできます。
    def person_params
      params.require(:person).permit(:name, :age)
    end
end
```

##3.モデルに、accepts_nested_attributes_forを使っている場合

accepts_nested_attributes_for（クラスメソッド）を使っている場合、下記のように記述することで、Relation関係にあるレコードの更新・削除が可能。このメソッドは、``id``と``_destroy``パラメータに基づいて動作する。


＜Railsガイドの事例＞

```ruby:controller.rb
params.permit(:name, { emails: [] },
              friends: [ :name,
                         { family: [ :name ], hobbies: [] }])
```

＜私のオリジナルアプリ開発の事例＞

```ruby:controller.rb
[省略]
  def create
    @record = Record.new(record_params)
    if @record.save
      flash[:success] = "練習内容の登録が完了しました。"
      redirect_to records_url
    else
      flash[:alert] = "登録に失敗しました。"
      render :new
    end
  end

[省略]

  def record_params
    params.require(:record).permit(:record_id, :training_date, :learning_point, outputs_attributes:[:output_name, :id, :_destroy], practices_attributes:[:practice_item, :practice_time, :id, :_destroy], tasks_attributes:[:task_name, :id, :_destroy]).merge(user_id: current_user.id)
  end
```
子テーブルにある属性を、

```rb
params.require(:model).permit(:models_attributes:[:id,:arg, :arg2, :_destroy]
```
の形でまとめると実装できる。
**※モデルに「has_many」「belongs_to」を忘れないこと**

##4.参考

[Railsガイド　Strong Parameters](https://railsguides.jp/action_controller_overview.html#strong-parameters)
突然VSCodeが英語表示になってしまった時の対処法

# 拡張機能でVSCodeを日本語化したのに、突然英語で表示されてしまっていた。
　・拡張機能のJapanese Language Pack for Visual Studio Codeはインストール済み
　・VSCodeを再起動してもなおらない

# 原因はバージョンアップ時？
　バージョンアップ時に、日本語化したものが英語表記される場合があるらしい。
　https://neos21.hatenablog.com/entry/2017/06/27/080000

　この方がいなかったら私は何時間もさまよっていたかもしれない（感謝感激）

# 日本語化に成功した事例

VSCode上で

①Shift+Command+P
②Configure Language　と入力し、検索
③拡張機能の日本語化パッケージがインストールされていれば、enかjaが表示されているのでjaを選択
④日本語表示にかわる

# 日本語化したことによってemmetの不具合も改善した

VSCodeのタブのボタンでインデントを合わせることは頻繁に使用するが、これが効かなくなった。
コード上でTabのボタンを押すと、


```
command 'emmet.expand Abbreviation' not found
```

と表示される。
コマンド「emmet.expand Abbreviation」が見つかりませんとのこと。

emmetの機能がfaulsになってる部分があるのかな？っと思って調べた（下記の記事参考）
https://qiita.com/bushi/items/82cc7133f809d34c0da1


# VSCodeでTabが効かない事象が発生したが、日本語化したら改善
"emmet.triggerExpansionOnTab": falseではなく、trueのままだった。

しかし、上記のように日本語化したことによってemmetは通常通り使えるようになった。
日本語化したことによる改善したことは謎でした・・・・

もし詳しい方いらっしゃいましたら教えていただけますと幸いです。
最後までみていただき、ありがとうございます。
LINE Messaging API を使って、リッチメニューを作ってスマホのカメラを起動するまでやってみた

LINE Messaging API を使って、リッチメニューを作ってスマホのカメラを起動するまでやってみた備忘録です。

# 実行画面
メニューをタップするとカメラが起動して写真を撮影することができます。

![IMG_1165.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/d6a60da6-07b0-1ba2-df65-3b8dd51f1f6a.png)


![IMG_1168.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/95648a4a-70f9-55ee-9d04-5246ac530eb4.png)


# 手順

下記LINE公式の手順に沿って作成してください
[Messaging APIでリッチメニューを作成する](https://developers.line.biz/ja/docs/messaging-api/using-rich-menus/#creating-a-rich-menu-using-the-messaging-api)

# リッチメニューの設定方法

公式のままですが、bashのコードを載せておきます。

```menu.bash
CHANEL_ACCESS_TOKEN='チャネルアクセストークン'
curl -i -v -X POST https://api.line.me/v2/bot/richmenu \
-H "Authorization: Bearer ${CHANEL_ACCESS_TOKEN}" \
-H 'Content-Type: application/json' \
-d \
'{
    "size": {
      "width": 800,
      "height": 250
    },
    "selected": false,
    "name": "Nice richmenu",
    "chatBarText": "Tap here",
    "areas": [
      {
        "bounds": {
          "x": 0,
          "y": 0,
          "width": 800,
          "height": 250
        },
        "action": {
            "type":"uri",
            "label":"Camera",
            "uri":"https://line.me/R/nv/camera/"
        }
      }
   ]
}'
```

cURLからの戻り値にリッチメニューIDが入っているので、それを下記のURLにセットしてください。


```image.bash
# CHANEL_ACCESS_TOKEN='チャネルアクセストークン'
# RITCH_MENU_ID='リッチメニューID'
curl -i -v -X POST "https://api-data.line.me/v2/bot/richmenu/${RITCH_MENU_ID}/content" \
-H "Authorization: Bearer ${CHANEL_ACCESS_TOKEN}" \
-H "Content-Type: image/jpeg" \
-T image.png

curl -v -X POST "https://api.line.me/v2/bot/user/all/richmenu/${RITCH_MENU_ID}" \
-H "Authorization: Bearer ${CHANEL_ACCESS_TOKEN}"
```

# 参考

* https://developers.line.biz/ja/news/tags/rich-menu/
* https://developers.line.biz/ja/docs/messaging-api/using-rich-menus/#creating-a-rich-menu-using-the-messaging-api
* https://developers.line.biz/ja/reference/messaging-api/#create-rich-menu

# 次の展開

* 撮影した画像の情報をWebhookで送って、Botサーバーで取得。ログに書き込む
* Botサーバーで画像情報を取得したら、Googleドライブに保存する
* Googleドライブに保存したらkinoneに画像情報と画像を添付ファイルとして保存する
* kinoneに保存した画像をランダムに取得してLINEで表示する
go修行6日目 for文とか

## for

```golang

package main

import "fmt"

func main() {
	for i := 0; i < 10; i++ {
		if i == 3 {
			fmt.Println("continue")
			// ループ内のcontinue以降は実行されず、次のループへ行く
			continue
		}

		if i > 5 {
			fmt.Println("break")
			// ループ終了
			break
		}
		fmt.Println(i)
	}

	// 省略版
	sum := 1
	for sum < 10 {
		sum += sum
		fmt.Println(sum)
	}
	fmt.Println(sum)
}
```

```
0
1
2
continue
4
5
break
2
4
8
16
```

## range

- 要素数分ループ

```golang

package main

import "fmt"

func main() {
	l := []string{"python", "go", "java"}

	for i := 0; i < len(l); i++ {
		fmt.Println(i, l[i])
	}

	// 短縮版 lの中身のインデックスを入れてくれる
	for i, v := range l {
		fmt.Println(i, v)
	}

	// vだけ使いたい場合
	for _, v := range l {
		fmt.Println(v)
	}

	// map型
	m := map[string]int{"apple": 100, "banana": 200}

	for k, v := range m {
		fmt.Println(k, v)
	}

	// keyだけ取り出す
	for k := range m {
		fmt.Println(k)
	}

	// valueだけを取り出す
	for _, v := range m {
		fmt.Println(v)
	}
}
```

```
0 python
1 go
2 java
0 python
1 go
2 java
python
go
java
apple 100
banana 200
apple
banana
100
200
```

## switch文

```
package main

import "fmt"

func getOsName() string {
	return "windows"
}
func main() {
	// os := "windows"
	os := getOsName()
	switch os {
	case "mac":
		fmt.Println("Mac")
	case "windows":
		fmt.Println("Windows")
		// defaultなくても大丈夫
	default:
		fmt.Println("Default")
	}
}
```

```
Windows
```

```
package main

import (
	"fmt"
	"time"
)

func getOsName() string {
	return "linux"
}
func main() {
	// switch文の中だけ変数が有効 短縮版
	switch os := getOsName(); os {
	case "mac":
		fmt.Println("Mac")
	case "windows":
		fmt.Println("Windows")
	default:
		fmt.Println("Default", os)
	}

	// timeオブジェクトのメソッド部分も利用できる
	t := time.Now()
	fmt.Println(t.Hour())
	switch {
	case t.Hour() < 12:
		fmt.Println("Morning")
	case t.Hour() < 17:
		fmt.Println("Afternoon")
	}
}
```

```
Default linux
8
Morning
```
コードレビュー 観点

#目的
コードレビューは見る人によって観点が異なる。
汎用的な内容をまとめる

#見るべき項目

機能
バグ
セキュリティ
可読性
テスト
パフォーマンス
ドキュメント
設計
……などなど


##機能
・機能要件を過不足なく実装・動作しているか
・仕様が明確ではない部分を勝手に実装してないか

##コード
・コーディング規約に準拠しているか
・一時的に使用した不要なコードが残ってないか
・ネストが深くなりすぎていないか(3重くらいまで?)
・ハードコーディングしてないか
・同一のロジックが2箇所以上で書かれていないか(例外あり)
・適切な例外処理が入っているか
・実装が適切か(特にクラス分割など)
・設計レベルの指摘はコメント残すより直接話した方が早い?

##命名
変数
・変数名から内容が予測できる名称になっているか
・長さはあまり気にしないが、安易に長い名前はつけない
関数
・関数名は機能を明確に表したものになっているか
・メソッド名からは予測しにくい副作用が入っていないか
　get〇〇なのに、内部でsetしている

##コメント
・コメントが適切か
・コードからすぐわかることを書いていないか
・特殊なロジックが入っている場合処理の内容ではなく「なぜ」や「意図」を書いているか
・複雑な処理の場合はコードブロックでの要約は書いた方がよい

##画面
・利用者視点(特に誰が、どのように使うか)という点で適切な文言・動作になっているか
・操作する上で足りてない情報、多すぎる情報がないか
・視覚情報として見やすいかどうか(違和感のある表示じゃないか)

##レビュー粒度
・できる限り小さい粒度で依頼すること
※差分が多すぎると、レビュワーの負担が大きくなり細かいところまで見切れなくなる可能性があります。
一つの機能追加のチケットでも画面毎や区切りのつく単位毎にする。

##遠慮しない
・特に自分はできていないけど・・・みたいなときでも改善すべき点があるなら指摘する。
・違和感がある箇所があれば「なぜこのように書いたのか？」を質問するだけでも良い。

以上
Macで雑にインターネット接続の死活監視を行う

![thumbnail_internet.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70638/4b23b2ff-3fea-4095-d1b8-957f3ee5f405.jpeg)
## はじめに
時節柄、現在もリモート勤務が続いている今日このごろです。

自宅のルーターの調子が悪いのか、気がつくといつのまにかネットに繋がらなくなっていることがときどき起こります。

大して気にも留めていませんでしたが、もし気がつかずに長時間作業していると外部から連絡がつかないことにも気がつかなかったり、大事な連絡を受信できなかったりする恐れがあると思いました。(コード書いてたりするとインターネット接続できなくてもすぐには困らないのでなかなか気がつかなかったりする)

そこで、簡易的ではありますが自分のパソコンがインターネットに繋がっているかをスクリプトで監視するようにしてみました。今日はそんな話です。

## 実行環境
- macOS Mojave(バージョン 10.14.6)

## スクリプト

ping コマンドを実行して、失敗するようなら Mac のアラートを出す、というシンプルなものです。今回は特にログ出力を行っていません。pingの送信先はひとまず自分のWEBサイトで試しました。

```sh:monitoring.sh
#!/bin/bash

/sbin/ping -c1 {任意のIP/URL}
if [ $? -ne 0 ]; then
  osascript -e 'display notification "インターネット接続が切れてませんか？確認してください。" with title "pingエラーです"'
fi
```

## 定時実行

Mac は cron が使えるので下記のジョブを登録しました。今回は平日の9時から18時まで5分おきに動くように設定しています。スクリプトのパスは適宜置き換えてください。

```sh:cron
*/5 9-18 * * 1-5 sh /Users/{username}/.scripts/monitoring.sh > /dev/null 2>&1
```

## 実行結果

pingが失敗するとこんな通知がでます。これでもし仮にネットが切れたりしていても5分以内には気がつけるはずです。(僕がよほどぼーっとしてない限りは)
<img width="372" alt="alert2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70638/8f3eab0a-1687-8fd7-48c4-5680b16e33e9.png">

あんまりこれが続くようならルーターの買い替えも視野ですが、発生頻度もそれほど高くないのでいったんこれで様子をみてみようとおもいます。

Mac 使っている方なら導入は簡単なので、似たようなことをやってみたい方はよかったら参考にしてください。

## 参考リンク
- [終了ステータス | UNIX & Linux コマンド・シェルスクリプト リファレンス](https://shellscript.sunone.me/exit_status.html)
- [How to show a notification on macOS with a script](https://www.addictivetips.com/mac-os/show-a-notification-on-macos-with-a-script/)
postfix とgmail を連携させる

# 目次
- はじめに
- postfix のインストール
- postfix の設定
- gmail の設定
- 検証
- おわりに


# はじめに
メール通知を実装したくて，テストで試したものを備忘録的に書き下す．
OS はCent OS 8，postfix のバージョンは3.3.1 です．

# postfix のインストール

自分が使っているCent OS 8 には，postfix がプリインストールされていなかったので，まずはインストールを実施．

```sh:実行コマンド
dnf -y install postfix
```

# postfix の設定

## main.cf の設定

main.cf に以下のように設定を追記する．

```conf:/etc/postfix/main.cf
#Gmail
relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_tls_CApath = /etc/pki/tls/certs/ca-bundle.crt
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
```

## 認証ユーザーの設定

上記設定で記述した，sasl_passwd ファイルを作成する．

```conf:/etc/postfix/sasl_passwd
[smtp.gmail.com]:587  [ユーザー名]@gmail.com:[アプリパスワード]
```

アプリパスワードについては後述する．

パーミッションの変更とdb化を実施する．

```sh:実行コマンド
chmod 600 /etc/postfix/sasl_passwd
postmap hash:/etc/postfix/sasl_passwd
```

## 設定の有効化

```sh:実行コマンド
systemctl restart postfix
```


# gmail の設定

「Gmail > Google アカウントを管理する > セキュリティ > アプリパスワード」を選択する．アカウントのパスワードを聞かれるので，パスワードを入力する．

- アプリを選択する   → メール
- デバイスを選択する → その他 (名前を入力) 適当な名前を入力する

<img width="601" alt="app_passwd.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/f456bd62-190b-242d-f427-71827d93b8e5.png">


そうすると，アプリパスワードが生成されるので，そのパスワードを上記の設定ファイルに記述すると，gmailを利用したメール送信が可能になる．

# 検証
メール送信検証するため，以下のコマンドを実行する．

```sh:実行コマンド
sendmail [宛先メールアドレス]
Subject: test
This is a test mail.
.
```

最後の「.」は，本文入力の終わりを意味する．

このコマンドを実行することで，設定ファイルで指定したメールアドレスから宛先メールアドレス宛に件名がtest，本文がThis is a test mail. のメールが送信される．

#おわりに
これを利用して，自宅のサーバの異常を検知した際に通知するプログラムを作成する予定．
今回はその予行練習になった．
PyTorch参考書　OpenPoseのサンプルコードの追加フラグメント

「つくりながら学ぶ! PyTorchによる発展ディープラーニング」の「第4章 姿勢推定（OpenPose）」の「Stageモジュール」の各Stageの出力を可視化するフラグメントを作成しました。

##参照書籍
つくりながら学ぶ! PyTorchによる発展ディープラーニング
小川雄太郎

https://book.mynavi.jp/ec/products/detail/id=104855
https://github.com/YutaroOgawa/pytorch_advanced
https://qiita.com/sugulu/items/07253d12b1fc72e16aba

##目的
Stageが複数ある理由の調査（lossを複数回算出する理由。特徴量を複数回入力する理由。）。
⇒1段目～6段目で、推定結果がどの程度異なるか、目視で確認する。

##各Stageの出力可視化フラグメント
「4-7_OpenPose_inference.ipynb」を以下の通り、修正・追記ください。

セル修正前

```python
predicted_outputs, _ = net(x)
```

セル修正後

```python
predicted_outputs, intermediate_outputs = net(x)
```

セル追加

```python
def convert_to_numpy_and_resize(val, size, size2):
    # 画像をテンソルからNumPyに変化し、サイズを戻します
    val = val.detach().numpy().transpose(1, 2, 0)
    val = cv2.resize(val, size, interpolation=cv2.INTER_CUBIC)
    val = cv2.resize(val, size2, interpolation=cv2.INTER_CUBIC)
    return val
```

セル追加

```python
size2 = (oriImg.shape[1], oriImg.shape[0])
pafs_list = []
heatmaps_list = []
for i in range(6):
    pafs_list.append(convert_to_numpy_and_resize(intermediate_outputs[i*2][0], size, size2))
    heatmaps_list.append(convert_to_numpy_and_resize(intermediate_outputs[i*2+1][0], size, size2))
```

セル追加

```python
def display_overlay_img(featImg, oriImg, anoNo, i):
    featImg = featImg[:, :, anoNo]
    featImg = Image.fromarray(np.uint8(cm.jet(featImg)*255))
    featImg = np.asarray(featImg.convert('RGB'))

    # 合成して表示
    blend_img = cv2.addWeighted(oriImg, 0.5, featImg, 0.5, 0)

    plt.subplot(1,3,i+1)
    plt.imshow(blend_img)
    # plt.show()

def display_heatmap_and_paf(heatmaps, pafs, oriImg, anoNos):
    plt.figure(figsize=(6.4*3, 4.3*1))
    display_overlay_img(heatmaps, oriImg, anoNos[0], 0)
    display_overlay_img(heatmaps, oriImg, anoNos[1], 1)
    display_overlay_img(pafs, oriImg, anoNos[2], 2)
    plt.show()
```

セル追加

```python
print("左肘heatmap、左手首heatmap、PAF")
for i in range(6):
    print("Stage" + str(i+1))
    display_heatmap_and_paf(heatmaps_list[i], pafs_list[i], oriImg, (6, 7, 24))
```

セル追加

```python
print("右膝heatmap、右足首heatmap、PAF")
for i in range(6):
    print("Stage" + str(i+1))
    display_heatmap_and_paf(heatmaps_list[i], pafs_list[i], oriImg, (9, 10, 5))
```

## 出力結果（1例目：左肘heatmap、左手首heatmap、PAF）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493607/912b54d6-5dad-7b03-1c3f-23fcaae42805.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493607/83357ae3-d813-5308-e1ac-dfed0f27ef1a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493607/19f0d4f4-49e0-6d28-5f9b-9c9cf2eb13d6.png)

## 出力結果（2例目：右膝heatmap、右足首heatmap、PAF）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493607/5434e2f9-2a32-5ec1-cb3d-bae23b397dfd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493607/069e37e6-1284-799a-e468-ccfd56d9f95d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493607/483d928c-52cf-63f3-252e-e475797fb563.png)
Djangoプロジェクトをデプロイするまでの練習　２回目　TerraformとECS準備編

# Terraformの準備
前回までは、開発環境を構築するためのDockerの準備、IAMの作成などを行った。
今回は、準備運動としてTerraformの操作を試してみる。

## Terraformのコマンド

```
# Terraformの作業ディレクトリを初期化する。
# awsを操作するためのpluginなどをダウンロードして、planできる状態にする。
terraform init

# 実行したディレクトリ内の.tfファイルを適用した場合の差分を表示する。
terraform plan

# .tfファイルをもとにインフラを構築する。一度planした結果を表示し、
# yesを入力することで実際にインフラが構築される。
terraform apply
```

## tfstate
terraform applyを完了すると、ディレクトリ内にterraform.tfstateというファイルが作成される。このファイルは、terafform applyをした結果、現在のインフラの状態が保存されている。
このtfstateは、ディレクトリをまたいだリソースの参照を行う際に必要となる。作成されたtfstateをremote_stateで指定することで別ディレクトリのリソースを参照できる。今回の内容では、S3に保存して進めていく。

## remote_state
Terraformは同じディレクトリ内の.tfファイルであれば、apply時にすべてまとめて適用してくれる。ただ、通常はリソース毎にファイルをディレクトリで分割して管理していきたいことが多い。そう言った場合は、remote_stateを使用することで異なるディレクトリに分かれたリソースを参照することができる。

まずは、下記のディレクトリ構成で試してみる。
test
  |--vpc
      - vpc.tf
  |--ec2
      - ec2.tf

```vpc.tf
resource "aws_vpc" "vpc" {
  cidr_block	= "10.10.0.0/16"
  instance_tenancy = "default"
}

resource "aws_subnet" "public_subnet" {
  vpc_id		= "${aws_vpc.vpc.id}"
  cidr_block		= "10.10.1.0/24"
  availability_zone	= "ap-northeast-1a"
}

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

# outputのセクションの追記
# subnetのidをvalueにセットしている
output "public_subnet_id" {
  value = "${aws_subnet.public_subnet.id}"
}

terraform {
  backend "s3" {
  bucket = "terraform-test-20200506"
  key 	 = "test/vpc/terraform.tfstate"
  region = "ap-northeast-1"
  }
}
```

★この時、terraform initを実施したところ、エラーが発生してしまった。
`terraform s3 bucket does not exist`
はまってしまったが、同じフォルダに.tfstate(だったかな？）が作成されており、それを削除することで解決できた。

```ec2.tf
resource "aws_instance" "sandbox" {
  ami			= "ami-785c491f"
  instance_type		= "t2.micro"
  # remote_state���w��
  subnet_id		= data.terraform_remote_state.vpc.outputs.public_subnet_id
}

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

# remote_state を設定する。vpcという名前で参照できるようにする。
data "terraform_remote_state" "vpc" {
  backend = "s3"

  config = {
    bucket	= "terraform-test-20200506"
    key		= "test/vpc/terraform.tfstate"
    region	= "ap-northeast-1"
  }
}

terraform {
  backend "s3" {
    bucket	= "terraform-test-20200506"
    key		= "test/ec2/terraform.tfstate"
   region	= "ap-northeast-1"
  }
}
```

作業が終わったら、特に必要なければ今回作成したものは
`terraform destroy`
で削除しておく。
translation missing: ja.activerecord〜のエラー対応

### エラー状況
RSpecにてモデルのテストを実行していたとき、下記エラーが発生。

```
translation missing: ja.activerecord.errors.models.post.attributes.user.required
```

###調べた内容
**①誤字脱字の確認**
**②作業ファイルの指定漏れ**
**③ググる**
**④エラー文の解析**

①、②は問題なし。そもそも①と②が該当する場合のエラー文では無いよね!?
③を一通り試したが、該当する情報は出てこず。

ということは④から導き出すしか無ので解析開始！

## 仮説
**translation missing**というエラー文を翻訳すると**[欠訳]**となる。

この[欠訳]というキーワードから立てた仮説は、翻訳がかけているということ。
となると、日本語が対応していないとも仮説できる。

さらに深掘りすると、**[deviseを日本語訳したファイルがない]**というエラーだった。

## 解決方法
仮設検証結果は、おおよそ的中しているようなので解決方法を記述。

```config>application.rb
class Application < Rails::Application
    ~省略~
    #以下で日本語化の設定をする
    config.i18n.default_locale = :ja 
  end
```

次に**deviseの日本語化**。

「config/locales」フォルダに、「devise.ja.yml」および「ja.yml」という名前のファイルを新規作成します。

下記のサイトに記述内容が掲載されているので、それぞれ中身を丸ごとコピーして貼り付け、保存しましょう。

devise.ja.yml▼
https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml

ja.yml▼
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml

以上で解決です！
ただ、日本語化したのでテストの際のエラー文言も日本語で書く必要があるので注意。
温度調整がヘタクソなエアコンを温度センサー＋赤外線リモコンでバッチリ快適にする

そもそも温度センサーがエアコン本体についてるからうまくいかないのではないか、という記事を読みまして。つい。

# 1. BLE温度計
https://qiita.com/takeru@github/items/f42381e8482c3bf484e7


# 2. 温度と湿度を記録する
M5StickCで取得した温度と湿度をRaspberryPiのNode-REDにMQTTで飛ばして保存しようと思います。

https://qiita.com/takeru@github/items/5103eb6f190c287d6fc5



# 3. 赤外線リモコン
温度と風量を指示する。


# 4. 制御アルゴリズム
- 入力は温度計のデータ、出力はエアコンの設定(温度+風量)
- PID制御
windowsでiverilog その28

#概要

windowsでiverilogやってみた。
ステートマシン、書いてみる。

#サンプルコード


```

module state(input clk, rst, output [3:0] out);
	parameter max = 3;
	parameter state_max = 5;
	reg [3:0] out;
	reg [6:0] cnt;
	reg [2:0] state;
	always @(posedge clk or negedge rst)
	begin
		if (!rst)
		begin
			out <= 4'b0101;
			state <= 0;
			cnt <= 0;
		end
		else
		begin
			cnt <= (cnt == max) ? 0 : cnt + 1;
			if (cnt == 0)
			begin
				state <= (state == state_max) ? 0 : state + 1;
				case (state)
				0:
					out <= 4'b0001;
				1:
					out <= 4'b0010;
				2:
					out <= 4'b0100;
				3:
					out <= 4'b1000;
				4:
					out <= 4'b0100;
				5:
					out <= 4'b0010;
				default:
					out <= 4'b0000;
				endcase
			end
		end
	end
endmodule

module test();
	reg clk;
	reg rst;
	wire [3:0] out;
	state u(.clk(clk), .rst(rst), .out(out));
	initial
	begin
		$monitor("%b", out);
		clk = 0;
		rst = 1;
		#10
			rst = 0;
		#10
			rst = 1;
		#300
			$finish;
	end
	always
	begin
		#5
			clk = 1;
		#5
			clk = 0;
	end
endmodule




```

#実行結果


```


xxxx
0101
0001
0010
0100
1000
0100
0010
0001
0010


```

以上。
SSH接続できるが、SFTP接続できない

機械学習などでGPUを利用するソフトウェアパッケージを使うには環境整備が面倒です。
そこで、Dockerを使うことで、パッケージに適した環境を簡単に作ることができます。とりわけ、既に構築済みのdocker imageが[Dockerhub](https://hub.docker.com)から無料でダウンロードできるため、環境構築は非常に便利にできるようになりました。しかし、Dockerhubで提供される環境では、必要最小限のものしか入っていない場合があり、例えばSSH用のパッケージが入っていない場合があり、これを自分でインストール・設定しなければいけません。ここでは、備忘録として、SSH構築できたが、SFTPサーバーに接続できない時の対処法を記録しておきます。

# Docker container の構築
例えば、ここからTensorflowの公式Docker imageをダウンロードできます。
https://hub.docker.com/r/tensorflow/tensorflow

指示に従ってdocker containerを立ち上げます。

```bash
$ docker run -it --rm -p 8022:22 tensorflow/tensorflow:1.15.2-gpu-py3-jupyter bash
```

上記コマンドを実行すると、docker containerの中に入ります。（このcontainerは一度外に出る(exit)と、自動的に消去されます。消去したくない場合は、`--rm`を消してください。）
`-p 8022:22`はポート番号`8022`からこのcontainerに入れることを意味します。複数のcontainerを構築して、それぞれにSSHで接続したい場合は、異なるポート番号を振り分けることで、接続したいcontainerを指定できます。


# SSHサーバーの構築
今インストールされているパッケージ一覧をみると、SSH関連のものが入っていません。
`apt list --installed`

そこで、openssh-serverをインストールします。

```
# apt update  # インストール情報を最新版に更新します。
# apt install openssh-server  # インストール実行
```

パスワードを設定します。

```terminal
# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
```

もし`root`ユーザーでsshを使いたい場合は、`sshd_config`をそのように書き換える必要があります。

```terminal
# sed -i.bak 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
```

最後にSSHサーバーを起動します。

```terminal
# /etc/init.d/ssh start
```

これでSSHサーバーの構築は完了です。
Containerの外から、SSHでこのcontainerに接続してみましょう。

```terminal
$ ssh -p 8022 root@localhost
Bad owner or permissions on ~/.ssh/config
# もし上記メッセージが表示された場合は、下記コマンドを実行してください。
$ chmod 600 ~/.ssh/config
$ ssh -p 8022 root@localhost
The authenticity of host '[localhost]:8022 ([::1]:8022)' can't be established.
ECDSA key fingerprint is SHA256:
Are you sure you want to continue connecting (yes/no)?
```

これで今作った、docker containerに入ることができます。

しかし、SFTPサーバーには接続できません。

```terminal
$ sftp -oPort=8022 root@localhost
root@localhost's password: 
Received message too long 458961211
```

そこで、またsshd_configを書き換えます。

```terminal
$ apt install vim
$ vim /etc/ssh/sshd_config 
```

下の方にこの行の部分を
`Subsystem     sftp    /usr/lib/openssh/sftp-server`
これに書き換えます。
`Subsystem      sftp    internal-sftp`
これで、sftpサーバーに接続できるようになります。
vimを終了するときは、【Esc】を押した後、`:wq!` と入力してEnterを押すと、上書き保存して終了します。

```terminal
$ sftp -oPort=8020 root@localhost
root@localhost's password: 
Connected to localhost.
sftp>
```
CakePHP4 の開発環境をDockerを使って構築する

## はじめに

CakePHPの勉強を始めて1日目の初学者です。
CakePHP的におかしいところがあればご指摘いただけると嬉しいです。

## やること

Docker Composeを使って、php-fpm(アプリケーションサーバ)、nginx(ウェブサーバ)、MySQL(データベースサーバー)のDockerコンテナを構築してCakePHP4の環境を作成します。

今回はCakePHP4のウェルカム画面が表示されるまでをゴールとします。

## CakePHPとは

https://cakephp.org/jp

PHPのフレームワーク。

## Macの環境

```
$ git --version
git version 2.27.0
$ docker -v
Docker version 19.03.8, build afacb8b
$ docker-compose -v
docker-compose version 1.25.5, build 8a1c60f6
```

## 実際のソースコード

- [https://github.com/ucan-lab/docker-cakephp](https://github.com/ucan-lab/docker-cakephp)

スターを貰えたらとても嬉しいです！

## CakePHP4のシステム要件

https://book.cakephp.org/4/ja/installation.html

- HTTP サーバー。例: Apache。mod_rewrite が推奨されますが、必須ではありません。
- PHP 7.2 以上 (PHP 7.4 も含む)
- mbstring PHP 拡張
- intl PHP 拡張
- simplexml PHP 拡張

## 構築するDocker環境

```
├── app
├── web
└── db
```

- app コンテナ(php-fpm)
  - ベースイメージ
     - [php](https://hub.docker.com/_/php):7.4-fpm-buster
     - [composer](https://hub.docker.com/_/composer):latest
- web コンテナ(nginx)
  - ベースイメージ
     - [nginx](https://hub.docker.com/_/nginx):1.18-alpine
     - [node](https://hub.docker.com/_/node):14.2-alpine
- db コンテナ(mysql)
  - ベースイメージ
     - [mysql](https://hub.docker.com/_/mysql):8.0

詳細は実際のソースコードをご参照ください。

## CakePHPの環境を構築する

```shell-session
$ git clone git@github.com:ucan-lab/docker-cakephp.git
$ cd docker-cakephp/infrastructure
$ make create-project
```

http://127.0.0.1

![ScreenShot 2020-06-17 0.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/40f416f8-25a3-e828-c4f1-59ab3ae95ba3.png)

簡単にインストールできました！

## 参考

- [最強のLaravel開発環境をDockerを使って構築する【新編集版】](https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4)
- [https://github.com/ucan-lab/docker-laravel](https://github.com/ucan-lab/docker-laravel)
初心者によるプログラミング学習ログ 347日目

#100日チャレンジの347日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
347日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>346日目　2.5h<br>・前にやった課題サイトレイアウト見直し　1h<br>・架空LP15日目1.5h(<a href="https://twitter.com/ririru_123?ref_src=twsrc%5Etfw">@ririru_123</a>)<br>・架空LPのハンバーガーメニュー、ナビの下線<br>・hover時のボタンのアニメーション<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1272985991347793920?ref_src=twsrc%5Etfw">June 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Python学習中に出会った記法

# Python学習中に出会った見知らぬ記法たち

## 配列の中にコロン　[スライス]

hairetu = ["a","b","c","d","e"]

という配列がある状態で、

hairetu[1:3]

と指定すると、

"b","c","d"　と帰ってくる。

また

hairetu[:2]とすると
"a","b","c"　と帰ってくる。

コロンはコロン前のインデックスからコロン後のインデックスまでの配列を切り出せる。

Pythonではスライスと呼ぶらしい。
Rust†超†初心者によるRust備忘録 †型†

# おしながき
- 自己紹介
- 概要
- Result
- Option

## 自己紹介
どうも、***†限界開発鯖†***に住んでいる高専生、いっそうです。
最近は~~課題を放り投げて~~コーディングしています。
[twitter](https://twitter.com/kousou4129)にも住んでます。

## 概要
最近Rustの勉強を[このリポジトリ](https://github.com/isso0424/TaskManagerRust)での開発を通して始めました。

その中でRustで結構躓いてた(躓いている)点について**自分なり**の認識をまとめていきたいと思います。

## Result
### 定義
関数の返り値として返して、成功、失敗を表す型。
定義としては

```rust
pub enum Result<T, E> {
  Ok(T),
  Err(E),
}
```
となっており、Tが成功したときに返す型、Eが失敗したときに返す型となっています。
特徴としては、エラー処理をしないと値が取り出せないということが挙げられます。

### 実際の使い方
多分あれこれ言っててもわからんと思うので実際のコードから見ていきましょう。

``` rust
fn calc(a: i32, b: i32, c: &str) -> Result<i32, String> {
  if c == "fail" {
    return Err(c.to_string());
  }
  Ok(a + b)
}

fn main() {
  let result = match calc(3, 2 "fail") {
    Ok(number) => number,
    Err(_) => 0
  };
}
```

今回の場合は`calc`は`a`,`b`,`c`の3つの変数を受取り、`c`が`fail`である場合である時に`Err("fail")`を返します。

そして、`c`が`fail`以外である場合はaとbを足し合わせた結果を`Ok(result)`という形で返します。

今回は、Ok、Errの2種類のどちらかが返ってくるので、`match`でそれぞれについて処理を行います。
この場合だと`Err`が返ってくると`result`は0になります。

### 便利な書き方
正直上の書き方を何回もやるのは面倒です。
`match`なんてなんどもなんども書きたくありません

というわけで?の出番です。

#### ?
これは別に伏せ字にしてるわけではありません。
?はもし、Err()が返ってきた場合にErr(`帰ってきたErrの中身`)としてErrを返すものです。

訳わかりませんね。
でも使ってると便利さがわかってきます。
というか先駆者様の記事に書いてあるのでそっち読んだほうが早いです。

危険な方法としては`unwrap`があります。
これはResultにErrが入っていたら即パニックになりますが、Ok(value)のvalueを取り出せます。

## Option
えっOptionalじゃないの?って思ったかも知れません。

はい、Optionです。
基本の考え方はOptionalと同じです。

### 定義
とりあえず定義を見てみましょう。

```rust
enum Option<T> {
  None,
  Some(T)
}
```

まあよくあるOptionalですね。
値がある場合はSome(T)が入ります。

### 値の取り出し方
値の取り出しには`match`が使えます。

```rust
let hoge = match somethingOption {
  Some(fuga) => fuga,
  None => INITIAL_VALUE
};
```

こんな感じですね。

危険な方法としてはこれまた`unwrap`があります。
これはOptionにNoneが入っていたら即パニックになりますが、Some(value)のvalueを取り出せます。

## まとめ
- 関数でエラーが発生するときは`Result<T, E>`を返す
    - エラーの処理は呼び出し元で`?`や`match`で行う
- 関数で値が返ってこない可能性がある場合は`Option<T>`を返す
    - エラーの処理は呼び出し元で`match`で行う
- ~~面倒になったらunwrap~~
ブラウザでのフォームをcurlしたい

ブラウザでのPOSTとかGETとかなんかそういうやつもcurlでやりたいんや！
って人

おもむろにChromeのデベロッパーツールを立ち上げてNetworkタブを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285581/31b1ef7d-23a9-223d-41f3-2af46beb2a31.png)

例として
Qiita内をtestで検索してみたりする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285581/cafa3f22-1daa-1066-ca6a-81f8c5072516.png)

なんかそれっぽいやつを `Copy as cURL`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285581/12bc8f85-4e42-7b12-218e-32edc92c29a3.png)

こんな感じでcurlコマンドをコピれる（わー便利）

```
curl 'https://qiita.com/search?q=test' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36' \
  -H 'Referer: https://qiita.com/' \
  --compressed
```
【AWS Organizations】OUから別のOUへAWSアカウントを移動させる

## はじめに
※個人的備忘録です。

AWS CLIがめちゃめちゃ便利ということを最近知りました。
shellスクリプト自体全然書いたことがないので変なスクリプトかもしれませんが。。

## 本題
jqコマンドを使用しています。

### 実装

```sh
#!/bin/bash
AWS_PROFILE_NAME=        # aws cliのプロファイル
CURRENT_OU_ID=           # 移動元OUのID
AFTER_OU_ID=             # 移動先OUのID
GET_ACCOUNT_LENGTH=      # 移動したいアカウント数

declare -a result=()
for account in $(
    aws organizations list-accounts-for-parent \
        --parent-id ${CURRENT_OU_ID} \
        --profile=${AWS_PROFILE_NAME} \
        --max-items=${GET_ACCOUNT_LENGTH} |
        jq -r '.Accounts[].Id' |
        sed -e "s/[\r\n]\+//g"
); do
    aws organizations move-account \
        --account-id=$account \
        --source-parent-id=${CURRENT_OU_ID} \
        --destination-parent-id=${AFTER_OU_ID} \
        --profile=${AWS_PROFILE_NAME}
done
:
```

### 解説
```sh
aws organizations list-accounts-for-parent  
```

で取得したAWSアカウントIDを使用して、

```sh
 aws organizations move-account  
```
でOUの移動をしています。
それだけです。

## おわりに
SDKで使用する時のように最大返却数などを気にしなくていいのは非常に助かりますね。
しばらくCLIにハマるかもしれないです笑
【仮】Windows + Discord.pyで発生してるSSL関連のエラーの解決策([SSL: CERTIFICATE_VERIFY_FAILED])

**注: この記事はとりあえず見つけた解決策を記したものです。これが安全であるという保証はできませんので何が起きても自己責任でお願いします。またこの記事が正確である保証もいたしません。**

### 概要
Discord.pyのbotをWindows上で動かそうとしたらSSL関連のエラーを吐いた。

```
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1108)
```

### 環境
- Windows 10 Ver 1903 (Build 18362.900)
- Python 3.8.2
- Discord.py 1.3.3

### 原因・解決方法
https://github.com/Rapptz/discord.py/issues/4159 を見た。
5/30日にルート証明書が切れてたらしい。(参考: https://crt.sh/?id=1)

本来アプデで入るはずの証明書4つが、何かしらの要因で1つだけ入ってなかったんじゃないかと推測してる人もいる。
何にしろ、見た感じ皆欠けてる証明書は同じっぽい？
ということでこちらからDLする。→ https://crt.sh/?id=2835394
ちなみにcrt.shはSectigo(COMODO CAのブランド)が運営してるサイトなので信頼できる。

画像左下の"Download Certificate: PEM"から"2835394.crt"をDL。
![SnapCrab_NoName_2020-6-17_1-47-15_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310556/8744404e-8611-cf77-2e1b-38dbd4ea57b3.png)
ダブルクリックで実行し、証明書をインストールする。
出てきたウィザードに従ってインストールを進めていく。
ローカルコンピュータにインストールするかユーザーにインストールするかはお好みで良いと思うけどコンピュータにインストールしたほうがよさそう。

これで解決。

まあでもWindowsかSectigoのアプデミスってことなら今後適切にアップデートしていけば治るんじゃないかな？

### 追記
IEでdiscord.comに行って鍵マーククリックして云々という方法もあるのだが、件のIssueではこの方法は良くないとい書かれていたので解説しなかった。
Maps SDK for Unity を使って、Google Maps の三次元情報を Unity で表示する

Google Maps のプラットフォームがこれまでは限定的な公開しかされていませんでしたが、[全人類に開放されるとのアナウンス](https://cloud.google.com/blog/products/maps-platform/google-maps-platform-gaming-services-now-available-everyone)が出て、Unity 用のSDKも出たみたいですね。

早速使って、新宿駅周辺の情報を取得してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/f91dbd29-9d3b-d867-b8a7-46132278b2cf.png)
見た目がちょっともっさりしていてますが、地理情報（lat, lng）入れただけで、これだけの情報が表示されるってすごくないですか？しかも結構早い全世界の情報が三次元データとしてUnityで使えてしまうなんて・・・。AR で表示することも、VR でこの世界に入ることも、カスタマイズも思いのままです。

以下、前提と手順です。

# 前提
名前                | バージョン/備考
-------------------|-----------------------------------------------------
Mac                |10.15.5
Unity              |2019.3.0f6
GCP                |登録、今回の範囲では料金はかかりませんが、クレジットカードが必要です
Maps SDK for Unity |Unity2019_2_v1.0.1202.0

# 手順
たったこれだけで、Google Map の三次元データが使えるようになります。
1. GCP での準備
2. Unity での作業

## GCP での準備
### 1. Semantic Tile API 有効化 
画面上部の `プロダクトとリソースの検索` に Semanteic Tile API を入力すれば、検索結果に出てきます。そこで選択し、遷移先の画面で有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/98ab01d2-2712-a253-1e8d-db9663b81e60.png)

### 2. APIキーを作成します
左側ペインの認証情報を選択して、認証情報を作成を選択します。この [YouTube](https://youtu.be/A8bsgHUYsq8) 見たらよりわかりやすいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/bc114713-e9a1-4b7f-13c6-e6aecaa5206a.png)

## Unity での作業
### 1. SDK のダウンロードとインポート
1. [Install the Maps SDK for Unity SDK] (https://developers.google.com/maps/documentation/gaming/install_sdk) を開くと、`Maps SDK for Unity 2019 here, and the Maps SDK for Unity 2018 here.` とあるので、自分が使っている Unity のバージョンに合わせて here をクリックしてダウンロードしてください。
2. zip ファイルがダウンロードされたら、解凍します。Unity から、`Assets` → `Import Package` → `Cusotom Package` を選択し、解凍したファイルのGoogleMaps.unitypackage を選択してインポートします。

### 2. Unity での設定
1. `Hierarchy` ペインで `Create Empty` を選択します。
2. 1 で作ったオブジェクトに `Inspector` 上で `Add Component` して、 `Maps Service` を追加します。
3. 1 で作ったオブジェクトに `Inspector` 上で `Add Component` して、 `Basic Example` を追加します。
4. 2 で追加した `Map Service` に Api Key があるので、GCP での準備で作っておいたキーを設定します。
5. Unity を実行して、自由の女神が出てきたら成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/2082066c-e71d-6df5-7a07-595116135632.png)


# その他
## ハンズオンクイックスタート
`ステップ 2: SDK をインポートする` のスタートガイドのリンクが切れていたりするので、ここでは割愛しました。とは言え、日本語翻訳だけだったので、英語に切り替えて [Install the Maps SDK for Unity SDK] (https://developers.google.com/maps/documentation/gaming/install_sdk)からダウンロードできたりします。英語が得意な人はこっちの方がいいかもしれません。

## Maps SDK for Unity の注意
* Unity2019 or 2018 ver があるので注意
* このワードで Google 検索すると、他の OSS に合致する可能性があるので注意
【Amplify】Unhandled Rejection (Error): Federation requires either a User Pool or Identity Pool in configの対処法

#課題
下記のようなエラーが表示される

```
Unhandled Rejection (Error): Federation requires either a User Pool or Identity Pool in config
AuthClass.<anonymous>
C:/Users/higuz/Documents/src/Auth.ts:1749
  1746 | case 2:
  1747 |     _b.trys.push([2, 6, , 7]);
  1748 |     return [4 /*yield*/, this._oAuthHandler.handleAuthResponse(currentUrl)];
> 1749 | case 3:
       | ^  1750 |     _a = _b.sent(), accessToken = _a.accessToken, idToken = _a.idToken, refreshToken = _a.refreshToken, state = _a.state;
  1751 |     session = new CognitoUserSession({
  1752 |         IdToken: new CognitoIdToken({ IdToken: idToken }),
View compiled
▶ 5 stack frames were collapsed.
onClick
C:/Users/higuz/Documents/fingers-crossed/src/App.js:17
  14 |       <p>
  15 |         Edit <code>src/App.js</code> and save to reload.
  16 |       </p>
> 17 |       <button onClick={() => Auth.federatedSignIn()}>Sign In</button>
     | ^  18 |     </header>
  19 |   </div>
  20 | )
```

#解決策
`index.js` にconfigを追加する。

```javascript:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import Amplify from 'aws-amplify' // 追記
import config from './aws-exports' // 追記
Amplify.configure(config) // 追記
```
flutterでcocoapodsのバージョンを更新する方法

sudo gem install cocoapods -v 1.9.3
sudo gem uninstall cocoapods -v 1.9.2

flutterのプロジェクトでiosフォルダに移動して、pod install

これでいけました。
正しいやり方なのかは怪しいので、分かり次第更新します
lessコマンドこれだけは確実に覚えたい【linux コマンド】

動画はこちらから（画像クリックでyoutubeへ.2020/06/18 8:00公開）
[![lessコマンドの使い方。catだけだときついよ【linux コマンド】](https://i9.ytimg.com/vi/nl8M2CWghOU/mqdefault.jpg?time=1592323017624&sqp=CNTWo_cF&rs=AOn4CLDSo5gnaqar4cU5u-ipxTqKVRMUrw)](http://www.youtube.com/watch?v=nl8M2CWghOU)
# ざっと説明

## lessってなに？
ファイルの中身を表示する。catやmoreでも表示できるが、
基本lessが一番使う。

## ユースケース
・画面に収まらないファイルの中身を見たいとき。
・grepやその他コマンドでの標準出力をじっくり見たいとき。

## 構文
less オプション ファイル名

## オプション
-N：行番号表示
-m：進捗表示

## 基本操作（確実に覚えておきたい）
q：終了
g：ファイルの先頭に移動
G：ファイルの終端に移動
SPACE：1画面進む
b：1画面戻る
/：検索 n→進む、N→戻る
F：ファイルの入力をまちうけて表示
(ctrl+cで終了。「tail -f」でもできる)

## サンプルコマンド
less sample.tsv
less -Nm sample.tsv
grep a sample.txt | less

# 実際の動作

## 普通に打つと

```shell
less sample.tsv
```

```text
file_name       category_id
train_0.jpg     4
train_1.jpg     21
train_2.jpg     16
train_3.jpg     20
train_4.jpg     24
train_5.jpg     23
train_6.jpg     4
train_7.jpg     23
train_8.jpg     5
train_9.jpg     20
train_10.jpg    20
train_11.jpg    11
train_12.jpg    8
```

## -Nオプション

```shell
less -N sample.tsv
```
先頭に行番号がつく

```text
      1 file_name       category_id
      2 train_0.jpg     4
      3 train_1.jpg     21
      4 train_2.jpg     16
      5 train_3.jpg     20
      6 train_4.jpg     24
      7 train_5.jpg     23
      8 train_6.jpg     4
      9 train_7.jpg     23
     10 train_8.jpg     5
     11 train_9.jpg     20
     12 train_10.jpg    20
     13 train_11.jpg    11
     14 train_12.jpg    8
     15 train_13.jpg    12
     16 train_14.jpg    9
```

## -mオプション

```shell
less -m sample.tsv
```
下部に今どこにいるか、%で表示される。

```text
train_320.jpg   21
train_321.jpg   14
train_322.jpg   18
train_323.jpg   17
train_324.jpg   15
train_325.jpg   3
train_326.jpg   6
train_327.jpg   2
train_328.jpg   0
train_329.jpg   5
train_330.jpg   22
train_331.jpg   7
train_332.jpg   2
train_333.jpg   13
train_334.jpg   16
31%
```

## /ワード　で検索

less表示して、

```shell
less sample.tsv
```
下部/24で検索。２４の箇所が反転表示される。（以下だと色つけれないのでそのまま表示させてますが。。）

```text
    239 train_237.jpg   16
    240 train_238.jpg   24
    241 train_239.jpg   2
    242 train_240.jpg   17
    243 train_241.jpg   13
    244 train_242.jpg   15
    245 train_243.jpg   16
    246 train_244.jpg   6
    247 train_245.jpg   2
    248 train_246.jpg   24
    249 train_247.jpg   13
    250 train_248.jpg   14
    251 train_249.jpg   23
    252 train_250.jpg   17
    253 train_251.jpg   14
    254 train_252.jpg   10
    255 train_253.jpg   14
    256 train_254.jpg   21
    257 train_255.jpg   15
/24
```

# 最後に
基本操作のところは文字にしてもしょうがないので、動画で確認してみてください。
【Javascript】即時関数でグローバルオブジェクトを定義する。

メモとして残します。

レガシーではありますが、**トランスパイル抜き**にした場合で、**IEにも対応する**グローバルオブジェクトの定義をメモ。


#■やり方
```javascript
(function (global) {
    var HogeObject = (function () {
      function HogeObject() {
        //コンストラクタ
      }
  
      HogeObject.prototype.setHoge = function (value){
        this.hoge = value
      }
      HogeObject.prototype.getHoge = function (){
        return this.hoge
      }
    
  
      return HogeObject;
    })();
  
    global.HogeObject = HogeObject;
  }(this));
  
```
上記のコード読み込み後は任意の場所で下記のように呼び出せばOK。

```javascript
const  hogeobj = new HogeObject() 'IE10の場合はconstをvarに
```

#■さいごに
今時であれば、トランスパイルしていい感じにコードをビルドしてデプロイする方がいいと思いますが、
たまたまレガシーな案件があったため、せっかくなので、投稿しました。
IEガン無視していいのであれば、他の言語同様にclassで定義できるののに。。。