OmniAICreator/Qiita-1.07M huggingface dataset:
Railsチュートリアル（第8章）

# はじめに
Railsチュートリアルの第8章が終わりました。
ポイントだけメモしておきます。

# Sessionsコントローラー
セッションを管理するためのSessionsコントローラーを作成します。

```
rails generate controller Sessions new
```

# form_for
前回の`form_for(@user)`のように、モデルを持たない場合は、以下のように`form_for("リソース名", "URL")`の形式で記述します。

```erb
    <%= form_for(:session, url: login_path) do |f| %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.submit "Log in", class: "btn btn-primary" %>
    <% end %>
```

このformから送られたデータを取得する際は、ハッシュの形式でparamsから取得できます。

```rb
params[:sessions][:email]
params[:sessions][:password]
```
ハッシュの内容は以下のイメージです。

```rb
{ session: { password: "", email: "" } }
```

# ユーザーの検証
以下のように、メールアドレスからユーザーを取得し、パスワードで検証します。
`authenticate`はモデルに`has_secure_password`を記述することで使用できます。
if文は、「ユーザーが存在する かつ パスワードが正常」をチェックします。

```rb
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
 ```

# flashメッセージ
以下のように、リダイレクトではなくrenderで画面を表示する場合は、flashメッセージが消えません。

```rb
    flash[:danger] = 'error'
    render 'new'
```
そのため、以下のように`flash.now`を使用します。

```rb
    flash.now[:danger] = 'error'
```

# Sessionsヘルパー
以下のように、Application_controllerにSessionsHelperを読み込ませることで、全てのコントローラーで使用できるようになります。

```rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper
end
```

# sessionの保持
sessionメソッドを使用することで、一時的に値を保持することができます。ブラウザを閉じることで削除されます。
このメソッドはハッシュのように使用します。

```rb
session[:user_id] = "ユーザーID"
```
以下のように記述することで、ログインユーザーを取得できます。

```rb
@current_user ||= User.find_by(id: session[:user_id])
# @current_user = @current_user || User.find_by(id: session[:user_id])と同じ
```
`||=`と書くことで、データがない場合だけ右のデータを格納するという処理を簡潔に記述できます。

# sessionの破棄
以下のように`delete`を使用することでデータを削除できます。

```rb
session.delete(:user_id)
```
tailwindcssのプラグインを使って、文字に影をつける

# 文字に影つけたいときありますよね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169861/21557e4d-d33a-9381-5655-a18f5cc50f3c.png)

```html
  <div class="p-4 text-left m-4 shadow">
    <div class="text-shadow mb-2">この文字は、</div>
    <div class="text-shadow-md mb-2">だんだん、、</div>
    <div class="text-shadow-lg mb-2">浮いてきます。。</div>
    <div class="text-shadow-xl mb-2">お。。。</div>
    <div class="text-shadow-2xl mb-2">おおお！？</div>
  </div>
```

`.text-shadow`とかがカスタムのクラスです。

## [Tailwindcss](https://tailwindcss.com/)で作る

こんな感じで、５段階つくるとします。

- `.text-shadow`
- `.text-shadow-md`
- `.text-shadow-lg`
- `.text-shadow-xl`
- `.text-shadow-2xl`

だんだん浮いてきますが、`-2xl`に至っては、半分悪ふざけですね。

やり方は簡単で、`tailwind.config.js`の`plugins`プロパティに関数を追加します。

```javascript
module.exports = {
  theme: {
    extend: {}
  },
  variants: {},
  plugins: [
    function({ addUtilities }) {
      const newUtilities = {
        ".text-shadow": {
          textShadow: "0px 2px 3px darkgrey"
        },
        ".text-shadow-md": {
          textShadow: "0px 3px 3px darkgrey"
        },
        ".text-shadow-lg": {
          textShadow: "0px 5px 3px darkgrey"
        },
        ".text-shadow-xl": {
          textShadow: "0px 7px 3px darkgrey"
        },
        ".text-shadow-2xl": {
          textShadow: "0px 10px 3px darkgrey"
        },
        ".text-shadow-none": {
          textShadow: "none"
        }
      };

      addUtilities(newUtilities);
    }
  ]
};
```

解説すると、`plugins`に関数を足して、その引数の`addUtilities`メソッド[^1]を使って、独自のクラスを足しています。

[^1]: 独自のクラスを作成する方法は、このほかにも`addComponents`や`addBase`があります。[詳しくはこちらへどうぞ](https://tailwindcss.com/docs/plugins/#app)。

これだけです、お手軽ですね。

### パッケージとして公開する

作ったプラグインを、[npm](https://www.npmjs.com/)に公開したい場合、下記みたいな感じになります。

パッケージ名を、`tailwindcss-text-shadow-plugin`とした場合

```index.js
module.exports = function({ addUtilities }) {
  const newUtilities = {
    ".text-shadow": {
      textShadow: "0px 2px 3px darkgrey"
    },
    ".text-shadow-md": {
      textShadow: "0px 3px 3px darkgrey"
    },
    ".text-shadow-lg": {
      textShadow: "0px 5px 3px darkgrey"
    },
    ".text-shadow-xl": {
      textShadow: "0px 7px 3px darkgrey"
    },
    ".text-shadow-2xl": {
      textShadow: "0px 10px 3px darkgrey"
    },
    ".text-shadow-none": {
      textShadow: "none"
    }
  };

  addUtilities(newUtilities);
};
```

この`index.js`を作って、`package.json`の`main`にして、`publish`したら、

```javascript
module.exports = {
  theme: {
    extend: {}
  },
  variants: {},
  plugins: [
    require('tailwindcss-text-shadow-plugin')
  ]
};
```

という感じで、プラグインを適用することができます。

シンプルでいいですね。

最後の方が急ぎ足で~~ルー大柴みたいになってま~~したが、伝わったでしょうか。

皆さんもぜひ、便利なプラグインを作って、公開しましょう。
秘密鍵、公開鍵を他のPCに移す手順

#概要
古いMacbookから新しいMacbookへの秘密鍵の移動、公開鍵を秘密鍵から生成

#手順
まず古いMacbookを起動し、リモート接続できるようにします。
System Preferences -> Sharing
<img width="677" alt="Screen Shot 2019-08-16 at 23.39.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357677/7ed40788-9d44-8add-3480-262de9c820c4.png">

<img width="678" alt="Screen Shot 2019-08-16 at 23.21.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357677/f745899b-2035-89d9-9681-f4ef72e88170.png">
画像のようにRemote Loginにチェックを入れます。

次に新しいMacで画像にある古いPCへのSSH接続コマンドをTerminalに入力し、古いPCにログインします。

### 秘密鍵転送の一連の流れ

```
# 新しいPCでの作業
ls ~/.ssh # 秘密鍵があるか確認

exit # 新しいPCに戻る。

#　ユーザー名とホスト名は古いPCで確認したsshコマンドに ユーザー名@古いPCのホスト名 と書いてある
# 新しいPCの~/.sshに転送
scp ユーザー名@古いPCのホスト名:古いPCの秘密鍵のパス ~/.ssh
```
### 秘密鍵から公開鍵を生成
なんと公開鍵は秘密鍵から生成できます。

```
ssh-keygen -y -f ~/.ssh/公開鍵名 > ~/.ssh/公開鍵名.pub
```
Vue cli 環境構築

Laravelでnpm installするのではなく、単独でSPAを作るときに使うときに便利そうです。


```bash
// これを入れる
npm install -g @vue/cli
npm install -g @vue/cli-service-global

// 設定を聞かれるがデフォルトでOK

// projectを作成する
vue create test_app

// serveで起動できる
cd test_app/
npm run serve

// コンパイルされてdistというディレクトリが作成されて、そこにコンパイルされたファイルが格納される
npm run build

// guiはこちら
vue ui
```

参考文献
[Vue.js&Nuxt.js超入門
掌田津耶乃
出版社: 秀和システム (2019/02/05)]
(https://www.shuwasystem.co.jp/book/9784798056593.html)
Gitについて Part3

## はじめに
Gitについて調べたことを全3回でまとめていきます。

Part3のゴールは、GitとSourceTreeの連携です。
前提として[Back Number](#Back Number)の内容については理解するものとします。

## 準備するもの
・SourceTree
　(https://www.sourcetreeapp.com) の最新バージョンをインストール
　(2019.08.16時点ではVer3.1.2)

## SourceTreeのインストールについて
1. Bitbucket Server と Bitbucket　の選択肢があるが、「Bitbucket」をインストール
2. BitBucketにログインし、「アクセスを許可する」をクリック
3. ツールをインストールする。<br> ※Mercurialのインストールのチェックは外す
4. SSHキーの読み込みはいいえを選択
5. SourceTreeを起動

以下、SourceTreeの各操作について記載する。

## Remote ～リモートリポジトリ(GitHub)の追加～
1. Remote内のアカウントの追加を押下
2. Hostのホスティングサービスを「GitHub」に変更
3. Credentialsの認証を「Basic」に変更
4. 「パスワードを読みこみ」を押下
5. ハスワードを入力
6. GitHub連携できる

## Clone ～リモートリポジトリのクローン～
1. Remote内の対象のリポジトリを選択
2. clone先のフォルダを選択
3. clone先のフォルダ名を記載
4. クローンを押下して完了

## Create ～リポジトリの作成～
### ローカルリポジトリの作成
1. Createからパス、フォルダ名を指定
2. 名前が自動入力される
3. Gitを選択して、作成を押下

### リモートリポジトリの作成
1. Createからパス、フォルダ名を指定
2. 名前が自動入力される
3. Gitを選択
4. 次のアカウントでリポジトリを作成にチェック
5. アカウントをGitHubの名前に選択
6. 所有者の名前が自動入力される
7. 作成を押下

## add ～ローカルにある既存のリポジトリを追加～
1. 作業コピーのパスにgitディレクトリを選択
2. 名前を付ける
3. 追加を押下

## ブランチの管理
### ローカルブランチの作成
1. ブランチを押下
2. 新規ブランチ名を入力
3. ブランチを作成する場所を決める <br> 最新のコミット　or 指定の古いコミット
4. 新規ブランチを作成してチェックアウトにチェックを入れたままでブランチを作成

### リモートブランチの作成
1. 設定を押下
2. 追加を押下
3. リモート名、URLを入力
4. ホストタイプを「GitHub」にし、ユーザ名を入力
5. OKを押下

### ブランチの削除
1. ブランチを押下
2. 削除したいブランチを選択
3. ブランチを削除を押下

## リモートリポジトリへpush
1. WORKSPACEのファイルステータスを押下
2. 変更を確認したのち、インデックスに追加、または「＋」を押下 <br> もし変更を破棄したい場合は、破棄を押下して破棄したいファイルを選択する
3. Indexにステージしたファイルをコメントを記載してコミット
4. 変更をプッシュ
5. プッシュするローカルブランチ、及びリモートブランチを選ぶ <br>リモートブランチは任意の名前に可能
6. プッシュする

## リモートリポジトリからのpull
1. プルを押下
2. プルを行うリモートブランチを選ぶ
3. マージした変更を即座にコミットにチェックを入れたままでOKを押下

## スタッシュの使い方
1. スタッシュを押下
2. スタッシュ名を入力し、OKを押下
3. 左下のスタッシュに格納されているので適用/削除したスタッシュを選択

## おわりに
とりあえず、Part 1 ～ Part 3 で最低限のGitの使い方については言及したと思います。
今後、使用して発見があれば追記したいと思います。

## Back Number
[Gitについて Part1](https://qiita.com/Shohei_miyasako/items/b353273f5941278241d9)
[Gitについて Part2](https://qiita.com/Shohei_miyasako/items/011d17bbb33ac1e5e34c)
湯婆婆は参照で落ちるから名前を書かない方がいい

###千と千尋の神隠し
2019/08/16の金曜ロードショーでノーカットの『千と千尋の神隠し』が放送されました
いや〜よかった！
いつ見てもあれはいいですね！

````
「契約書だよ。そこに名前を書きな。働かせてやる。
その代わり嫌だとか、帰りたいとか言ったらすぐ子豚にしてやるからね。 

あの、名前ってここですか？ 

そうだよもぅぐずぐずしないでさっさと書きな！ 

まったく……つまらない誓いをたてちまったもんだよ。
働きたい者には仕事をやるだなんて…… 書いたかい？ 

はい……あっ。 

フン。千尋というのかい？ 

はい。 

贅沢な名だねぇ。 今からおまえの名前は千だ。
いいかい、千だよ。分かったら返事をするんだ、千！！」
````
というシーンを知っていますか？
Twitterを見つつ鑑賞していたら
https://twitter.com/SabanikiTofu/status/1162323952309424134?s=20<img width="603" alt="スクリーンショット 2019-08-16 23.12.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263501/330b9412-968a-4d03-92f7-6c3b81c7eacf.png">
というツイートを目にしました
「これは面白い。たぶん湯婆婆は文字列の一文字目だけにしてるんだろう」と考えました
###湯婆婆を作る
じゃあとりあえず湯婆婆を作ります

````hot_water_old_lady.py
print("契約書だよ。そこに名前を書きな。働かせてやる。\nその代わり嫌だとか、帰りたいとか言ったらすぐ子豚にしてやるからね。\nそうだよもぅぐずぐずしないでさっさと書きな!\n\nまったく……つまらない誓いをたてちまったもんだよ。働きたい者には仕事をやるだなんて…… 書いたかい？")
name = input()
short_name = name[0]
print("はい…あっ。 \n\nフン。%sというのかい？ \n\nはい。 \n\n贅沢な名だねぇ。 今からおまえの名前は%sだ。\nいいかい、%sだよ。分かったら返事をするんだ、%s！！"% (name, short_name, short_name, short_name))
````
はい終わり

````
$ python hot_water_old_lady.py
契約書だよ。そこに名前を書きな。働かせてやる。
その代わり嫌だとか、帰りたいとか言ったらすぐ子豚にしてやるからね。
そうだよもぅぐずぐずしないでさっさと書きな!

まったく……つまらない誓いをたてちまったもんだよ。働きたい者には仕事をやるだなんて…… 書いたかい？
千尋
はい…あっ。 

フン。千尋というのかい？ 

はい。 

贅沢な名だねぇ。 今からおまえの名前は千だ。
いいかい、千だよ。分かったら返事をするんだ、千！！
````
はい、ちゃんと湯婆婆してますね
じゃあ名前を書かないでいきましょう

````
python hot_water_old_lady.py 
契約書だよ。そこに名前を書きな。働かせてやる。
その代わり嫌だとか、帰りたいとか言ったらすぐ子豚にしてやるからね。
そうだよもぅぐずぐずしないでさっさと書きな!

まったく……つまらない誓いをたてちまったもんだよ。働きたい者には仕事をやるだなんて…… 書いたかい？

Traceback (most recent call last):
  File "hot_water_old_lady.py", line 3, in <module>
    short_name = name[0]
IndexError: string index out of range
````
はい、湯婆婆が落ちましたね
文字列の""の0番目を参照したからですね
###結論
湯婆婆は落ちる
cでやった人もいるらしいのでみなさんも湯婆婆作りましょう〜
https://twitter.com/cmpl_error/status/1162330445683412992?s=20

###追記
2019/08/17　プログラム内のミスをご指摘いただき少し修正しました
圧倒的非プログラマーがDeep Learningを学ぶ

##プロフィール
機械メーカにて電気回路エンジニア（2018年入社）
大学院では洋上風力発電の電力制御について従事。
プログラム経験としてはCを用いてマイコンを制御したくらい。
業務では全くソフトウェアには触れない。

##なぜ今からDeep Learningを学ぶのか
入社してから世の中がAIブームであることを知った。
経済誌などで情報を集めると
AI/IoT技術などを活用したインダストリー4.0であったり、
VUCA社会という、正解への道筋が見えにくい社会に突入しているらしい。

シンギュラリティが仮にきたとして、
環境の変化に対応する力を培っておこうと思った。
そんなノンプログラマの争うところを記事としてみようと決意。

##目標
最終的には簡単な機械学習モデルを組み、
構造の理解ができればいいと思っている。（2019年内）

まずは[「ゼロから作るDeep Learning: Pythonで学ぶディープラーニングの理論と実装」](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585)を読み、理解できるようにしたいと思う。
ほかに具体的な達成目標が思いつかないのがちょっと悩みである。
バッチメモ

サンプル1

@echo off

rem ファイルの存在を確認して、ファイルがあればファイルを削除する

rem 検索対象のファイルを定義する

SET filename=C:\Users\Kanat\Desktop\*ファイルシステムについて.txt

IF EXIST %filename% (GOTO FILE_TRUE) ELSE GOTO FILE_FALSE

:FILE_TRUE

ECHO "ファイルが見つかりました"

SET pushKey=""
SET /P pushKey=ファイルの削除を実行しますか(y/n)？：

IF "%pushKey%" == "y" (
del /p *ファイルシステムについて.txt
) ELSE (
GOTO BAT_END
)

GOTO BAT_END

:FILE_FALSE

ECHO "ファイルが見つかりません"

GOTO BAT_END

:BAT_END

pause

サンプル2

@echo off
 
rem 「date」の確認
echo date=%date%
 
rem 「date」から切り出した数字をそれぞれ変数に代入
set YYYY=%date:~0,4%
set MM=%date:~5,2%
set DD=%date:~8,2%
 
rem 切り出した数字の表示
echo 年=%YYYY%
echo 月=%MM%
echo 日=%DD%

IF EXIST C:\Users\Kanat\Desktop\テスト\2019年\%MM%月\OVST.txt (GOTO FILE_TRUE) ELSE GOTO FILE_FALSE

:FILE_TRUE

ECHO "ファイルが見つかりました"
SET file=OVST.txt
ECHO "ファイル名は%file%"です。

SET pushKey=""
SET /P pushKey=ファイルの削除を実行しますか(y/n)？：

IF "%pushKey%" == "y" (
del /p *ファイルシステムについて.txt
) ELSE (
GOTO BAT_END
)

GOTO BAT_END

:FILE_FALSE

ECHO "ファイルが見つかりません"

GOTO BAT_END

:BAT_END

pause

サンプル3

@echo off
 
rem 「date」の確認
echo date=%date%
 
rem 「date」から切り出した数字をそれぞれ変数に代入
set YYYY=%date:~0,4%
set MM=%date:~5,2%
set DD=%date:~8,2%
 
rem 切り出した数字の表示
echo 年=%YYYY%
echo 月=%MM%
echo 日=%DD%

IF EXIST C:\Users\Kanat\Desktop\テスト\2019年\%MM%月\OVST.txt (GOTO FILE_TRUE) ELSE GOTO FILE_FALSE

:FILE_TRUE

ECHO "ファイルが見つかりました"
SET file=OVST.txt
ECHO "ファイル名は%file%"です。

SET pushKey=""
SET /P pushKey=ファイルのコピーを実行しますか(y/n)？：

IF "%pushKey%" == "y" (
copy C:\Users\Kanat\Desktop\テスト\2019年\%MM%月\OVST.txt C:\Users\Kanat\Desktop\コピー先
) ELSE (
GOTO BAT_END
)

GOTO BAT_END

:FILE_FALSE

ECHO "ファイルが見つかりません"

GOTO BAT_END

:BAT_END

pause
RxSwift学びの過程〜tableViewCellの操作編〜

# 背景
既存コードを`RxSwift`にて書き直していたとき、cellの操作で詰まりましたので備忘録的にアウトプット。
やはりこいつはすごくクセが強い。


# cell上に配置したUIButtonの操作

## Issue 1 : cell番号を取得したかった
MVVMで開発をしていて`cell`は`CustomCell`として作成していたとき、`UIButton`をセル上に配置していたのでボタンタップの検知を`CustomCellView`に記載していました。
ちなみに`UIButton`のタップ検知は

- `UIButton.rx.tap`

となります。

ここで、`UIButton`をタップした時にその`cell`のindex（tag）を取得したかったのですが、どのセルのボタンをタップしても0しか取得できませんでした。

```swift
func favButtonSetup() {
    favButton.rx.tap.asDriver().drive(onNext: { [weak self] _ in
                                               
        let row = self!.tag
        print(row) // 選択されたセルのインデックス（tag）を取得したかったが、いつも0
                                               
    }).disposed(by: disposeBag)
}
```

`RxSwift`を使わないプレーンな書き方だと`@IBOutlet buttonTapped(_:)`にて`self.tag`で任意のセルに乗っかっているボタンのイベントを取得できるんですよね。

## Issue2 : お気に入りボタンのon/off切り替えが上手くいかない

お気に入りボタンのon/off、データの整合などで操作対象の`cell`を取得したいときにも`tag`で操作対象の番号を取得するやり方は使えます。

セルの位置に応じてお気に入りボタンをon/off処理（画像を切り替える）ものも実装していましたが、取得できる番号が0のみなのでどのボタンを押しても切り替わるのは一番上のセルだけでした。

コードは大したことないのを上に追加するだけなので割愛します。

# 原因・解決法

まず調べた中での解決法として、

- `tap.asDriver()`を`ViewController`にあるセルをどうこうする場所で呼ぶ。（`cellForRowAt`とか`RxTableViewSectionedReloadDataSource`とか人によって違うと思います）
- `override func prepareForReuse()`にて`DisposeBag()`を毎度作成し、これでDisposeする

```swift
// ViewController内
dataSource = RxTableViewSectionedReloadDataSource<SectionModel>(configureCell: {(_, tableView, indexPath, item) in
    let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell

    cell.configure(item: item)

    cell.favButton.rx.tap.asDriver().drive(onNext: { [weak self] _ in
                                                    
        //TableViewCell内での記述ではないので indexPath　にて rowを取得
        let row = indexPath.row
    
    //cell側で作成したdisposeBag()を呼ぶ
    }).disposed(by: cell.disposeBag)

    return cell
})



// CustomCellView内
var disposeBag = DisposeBag()
    
override func prepareForReuse() {
    disposeBag = DisposeBag()
}
```

これにはTableViewCellというオブジェクトを作成するライフサイクルに元付いた問題があり、毎度セルを作成する際に作る`DisposeBag()`で`Dispose`する必要があるようです。

# 終わりに

問題は解決されました。
が、設計上CellViewにある操作はCustomCellViewで行った方がいいんだろうなぁと思うので、このようにViewControllerにcellの操作を書くのはナンセンス？と思います。

CellView内でUIButton時にcellの番号が取得できたりする方法があれば教えていただければ嬉しいです。

参考URL
[How to use rx_tap on UIButton of UITableViewCell · Issue #288 · ReactiveX/RxSwift · GitHub](https://github.com/ReactiveX/RxSwift/issues/288)
[what is best way i can handle button tap in UITableViewCell using RX. · Issue #119 · RxSwiftCommunity/RxDataSources · GitHub](https://github.com/RxSwiftCommunity/RxDataSources/issues/119)
[RxSwift UITableViewCell上に配置したボタンの動作 - Qiita](https://qiita.com/katafuchix/items/5909fa2d38b5f5455df1)
laravelのcookieで一日血迷ったこと#解決したので備忘録(*_*;

# laravel Cookieの落とし穴？

- laravelで今話題のLeague Of Legendsのtftのビルドサイトを作ろうとしていて  
 Cookieで閲覧回数を記録したいなーと思って
 色々やってみたけど、なかなかCookieが保存されず... 
 
     __※home_cookieが今回保存したいcookie名です__

chromeのデベロップツールのApplicationタグには保存されていないが
![2019081601.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423122/22f9ba5d-220c-37bf-a652-921095cc7b2c.png)


chromeのデベロップツールのNetworkタグには保存されている！？！？！？！？？！？！？:cold_sweat:
![2019081602.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423122/abaef147-be75-f4fc-8647-08f1c90e8dbe.png)




　　
  
  
  
  
  
  
  
  
  
  
  
   
 
  
- 原因は`php artisan serve`だった！
xammpで起動してみると
![2019081603.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423122/91fdbb63-c955-3194-e219-1c59b851968b.png)

保存されている！！！  
無事解決！！

## 勉強になりました...:sob:
PowerAppsとflowで入力チェック処理

#概要
PowerAppsのキャンバスアプリケーションで入力チェック処理を実装する。
チェク処理自体はFlowで実施する。
PowerAppsからFlowに画面の入力値をJSONメッセージにして引数で渡す。
Flowで入力チェック処理結果を応答メッセージとして、処理結果コード値とエラーメッセージを文字列で
返却する。
エラー表示はラベルコントロールを使う。
ラベルコントロールの値を動的に変更するために、ローカル変数を使用する。
PowerAppsとFlowとの引数と応答メッセージの値は文字列のみを使用する。

#PowerAppsの画面の作成

キャンバスアプリを新規作成し、Screen1にラベル、入力テキスト、ラベル、ボタンを順に貼り付ける。

|コントロール|名前|テキスト|
|---|---|---|
|ラベル|Label1|理由：|
|入力テキスト|TextInput1|（空白）|
|ラベル|LblErrorMessage|（空白）|
|ボタン|BtnCommit|入力チェックテスト|

##テスト用の画面レイアウト
![InputValidateImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197947/2b002f44-3bfb-64de-9354-0f38ea81a3f4.png)

##画面の表示イベントでエラー表示用変数を初期化する。

Screen1のOnVisibleに下記の式を入力する。

```
UpdateContext({ErrorMessage:""});
```
UpdateContextは変数を更新する処理を行う。
引数はJSONメッセージで指定する。
上記はErrorMessage変数を空白文字列で初期化している。

##LblErrorMessageと変数を紐付ける
LblErrorMessageのText属性に下記の変数名を入力する。

```
ErrorMessage
```
この設定によりErrorMessage変数の値がLblErrorMessageコントロールに表示される。

##CheckValueフローの作成
![CheckValueFlow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197947/8728c045-b3ff-7d7c-f1f1-89d64bbb424d.png)

PowerAppsボタンをトリガーとするCheckValueフローを作成し、上記のようにアクション追加する。
変数の初期化はPowerApps応答で返却する変数の初期化を行っている。
JSONの解析はPowerAppsからの引数をJSONメッセージとして受け取るため、受け取ったJSONメッセージ
を変数に解析する。
条件アクションはチェック処理を実施する。

##JSON解析
![JSON.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197947/c3e30c1c-1f6d-d0c4-f6ed-76da68957ca1.png)

##判定処理
![hantei.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197947/ba363793-15d0-89f8-0391-be88c5acb500.png)

JSONから取得したwhyの値が空文字列の場合はresult=1、messageにエラーメッセージを設定する。

##FlowからPowerAppsへの値の返却
![flowresponse.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197947/32b59c01-98d5-24e5-b967-ac2f56843cbe.png)

resultとmessageを返却する。
ともに文字列とする、Flowの型とPowerAppsの型がBoolや数値だとうまく判定処理で一致しないため、
文字列を使用する。

また、Flowで使用する変数を追加、更新した場合はPowerAppsからFlowの参照がうまくいかない場合がある。
その場合は一旦、PowerAppsからFlowへの参照を削除してから追加しなおす必要がある。

##PowerApps側のボタンのOnSelectの処理
BtnCommitびOnSelectに下記の式を入力する。

```
UpdateContext({params:JSON({why:If(IsBlank(TextInput1.Text),"",TextInput1.Text)})});
UpdateContext({result:CheckValue.Run(params)});
UpdateContext({ErrorMessage:If(result.result="0","",result.message)});
If(result.result="0",KintaiFlow.Run(params),"");
```

１行目：params変数にJSONメッセージを設定。未入力の時にNullを渡すとFlow側のJSON解析処理でエラーになるため、空文字を渡す。
２行目：params変数を引数としてCheckValueフローを起動し、応答メッセージをresult変数に設定。
３行目：resultメッセージのresultの値が０の場合は正常終了なので、ErrorMessage変数を空文字列で初期化。０以外の場合はresult.messageを設定。
４行目：チェック処理が正常終了の場合に本来の起動したい処理（KintaiFlow)を起動。

##実行例

###未入力の場合
![minyuryoku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197947/dd63b75c-1ffb-c427-8b58-14590f9658a7.png)
###入力した場合
![nyuryoku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197947/33758c94-8cdc-f995-df84-f6d912f21efc.png)

##フロー側の処理ログ
Flow側の呼び出し履歴からFlowの処理ログが確認できる。
![flow_log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197947/d9a69319-29b5-67c7-d2a6-3fd70a1d1817.png)

##バージョン

|アプリ|バージョン|
|---|---|
|powerapps|3.19081.20|
iPhoneでWEBページのソースコードを見たいとき

**はじめに**
---
～通勤中の電車内にて～

今度、日経平均株価をスクレイピングしてCSVに記録しよう。
早速、サイトのソースコードを見てみよー。
って、あれ？iPhoneじゃ見れないの？困った…通勤時間１時間もあるのに…
もうマジ無理…これだからiPhoneは…

と思ったそこの君！そんなあなたに解決策を享受しよう。

**必要なアプリ**
---
Apple Storeから「View Source」をインストールしよう。
無料だがシンプルで使いやすい。
検索機能もありこちらがオススメだ。


<img width="375" alt="IMG_3020.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/7a86ebe0-3678-1ee2-86e8-4e09747deceb.png">




通信料がかかるって？それぐらい我慢しなさい！！


**使い方**
---
１.まずは、ソースコードを見たいサイトをSafariで開き、共有ボタンを押そう。
<img width="375" alt="IMG_3026.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/f23d1672-1fd3-c52d-6328-b645c937cd0e.jpeg">


---
２.右端にあるその他を選択する。
<img width="375" alt="IMG_3023.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/22547f2f-5bc2-8699-3c48-ac7f88c5b197.jpeg">


---
３.View Sourceを有効にする。
<img width="375" alt="IMG_3028.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/f990221b-29f0-d78b-fccb-52a341dc58e3.jpeg">


---
４.View Sourseを選択する。

<img width="375" alt="IMG_3024.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/45200e3a-7fb8-26ea-5eb3-c2effc2690fa.jpeg">

---
５.するとアプリが起動されソースコードを確認出来る。
<img width="375" alt="IMG_3031.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/2e0b0dec-d82c-4fa0-3c64-a73bf822888c.png">

このように簡単に見ることができる。
---


**検索方法**
---
１.共有ボタン？を押そう。
<img width="375" alt="IMG_3034.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/aefbfa4c-b5a1-a4fb-e0b2-529930a12464.jpeg">
---
２.Findを選択する。
<img width="375" alt="IMG_3037.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/dae1a294-f710-db36-802d-a67a086114d9.jpeg">
---
３.キーパットが表示されるので、検索したい内容を入力する。
<img width="375" alt="IMG_3038.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/36a09c06-c1c0-c98f-c94a-18bf04358f55.png">

---
ね、簡単でしょ？




**まとめ**
---
今回はiPhoneでWEBページのソースコードが見れるアプリを紹介と簡単に使い方を紹介しました。
筆者は、通勤時間が長くpcも使用できないため紹介したアプリと[Google Colaboratory](https://colab.research.google.com/)に大変お世話になっています。
移動中などでPCが使用できない時間がある方はぜひ使ってみてください。
[Swift]ストーリーボートでオブジェクトが重なってしまって編集できない時の解決方法

swiftのストーリーボートを使用している時にオブジェクトが重なってしまって下に紛れ込んだLabelが編集できないことが起きたことはないだろうか。

この解決方法を今回は説明する。

##ドキュメントアウトラインを表示
<img width="827" alt="スクリーンショット 2019-08-16 22.37.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/356a5021-3194-7274-87ee-0b779ac42504.png">
ドキュメントアウトラインとはオブジェクトの詳細が一覧で確認できるもので、
今回はLabelとImageViewがオブジェクトとして入っている。

この画像を見たらImageViewの下にLabelが紛れ込んでいる。
このLabelを編集するためには、ドキュメントアウトラインの見方を解説しなければならない。

##ドキュメントアウトラインの見方

<img width="389" alt="スクリーンショット 2019-08-16 22.46.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/2995d8e3-bd3f-1420-f48f-46221dfcea05.png">

##解決
Labelと双眼鏡.ｊｐｇを入れ替えLabelを一番上に配置するとLabelが編集できた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/41d64940-bbd8-59f2-3851-81cf41b90cd6.png)

##まとめ
Swiftは、これどうやるの？って思って調べても英語の文献しか出てこない場合が多いので、こういった基礎的な所で詰まってしまいがちだが一個一個覚えて行くしか上達の道はないので地道に頑張る。この記事がいろんな人の助けになればと思います！
【PowerApps Tip's】コンパス＝方位 と 注意点

スマートフォンで方位を取る方法のメモです。最後に記載する注意点を自分が忘れそうだったので備忘録のために記事を書いておきます。

# 動作イメージ
<blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a> Compass.Heading <a href="https://t.co/XeZZeOJv9j">pic.twitter.com/XeZZeOJv9j</a></p>&mdash; やま (@yamad365) <a href="https://twitter.com/yamad365/status/1162346723613655040?ref_src=twsrc%5Etfw">August 16, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# Compass.Heading
方位は「Compass.Heading」で取得できます。

> 0 を北として、0 ～ 360 の数値を返します。

とありますが、0 ＝ 360 ＝ 北 なので、360という値は取れなさそうです。

[PowerApps の Acceleration、App、Compass、Connection、Location の各シグナル](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/signals)

# アイコンを回転させる方法
アイコンを挿入した後で、プロパティを確認してください。
[回転]（Rotation）というプロパティが存在しているハズです。こちらに前述の Compass.Heading を設定すれば方位によってアイコンが回転します。

# 注意点？
PCブラウザーで実行しても方位は取得できませんでした。（PCで方位を取得できる機種あるのかな？）

スマートフォンの機種にも依存するのでしょうが、おそらく大半は「スマートフォンを縦にした時の上になる部分がどの方向を向いているか？」で値を取得していると考えられます。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/973c0bb3-613f-f72f-4a16-82afc4c4b326.png)
このため、横画面だったり、タブレット レイアウトで作成したアプリをiPhoneなどで表示（画面が横と同じようになる）する場合は、デザインやUXに注意が必要になるかな、と思いました。
スマートフォンを横に持って操作するUIで提供された場合、無意識に「上になってる部分がどの方向か？（＝横持ちしてる時の画面上部が上（方位）でしょ？）」という感覚になりがちです。が、前述どおり「スマートフォン縦方向時の上になる部分」が指している方向が方位になります。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/db6dd45d-1605-a8b4-bc95-1c923434b268.png)

方位を使うアプリをデザインにする場合など、アプリの用途・設計によっては上記の特性は意識しておかないとハマりそうだ、と思った次第。そして、この点は忘れちゃいそうですよね！ｗ
なので、自分のために明記しておきたかったのです。

それでは、皆さま。素晴らしい Power Platform Life を！
シリアライズの語意味を腹落ちさせた備忘録

#概要
web開発を初めて1ヵ月が経過した頃、サーバーとデータのやり取りを行う処理にてserializeという処理が求められた。
検索しても、文中の1単語として用いられたり、VB.Netや、Javaなどの特定の言語内での説明ばかりがHitし、言葉の意味、目的、実際の動きなどがイマイチ把握できなかった。
この記事は、検索の最中で断片的に拾った知識を組み合わせて理解した備忘録です。

#シリアライズの語意味①　逐次化
逐の漢字の意味が頭に馴染んでいないせいか、イマイチすっと入ってこないので対義語から推察したい。

逐次化　⇔　並列化（parallelize）
パラレルなら、SFとか遊戯王とかスキーとかで聞いたことがありますけど、
平行して複数の状態が進行する的な意味だったはず。
「複数の物事が、同時に進行する」　⇔　「一度には一個ずつ処理する」ってことっぽい。

この用法は「サーバーとデータのやり取りを行う処理」の中で用いられてるものではないと判断したので横に置いておくとする。

#シリアライズの語意味②　直列化
小学校の理科で聞いた言葉だけど電池とは関係ない・・・はず。
とりあえず対義語から見ても・・・
直列化　⇔　直列化復元(deserialize)
手がかりなし。
ということでWikipediaさんに聞く。
>直列化（ちょくれつか）は、オブジェクト指向プログラミングにおいて使われる用語で、ある環境において存在しているオブジェクトを、バイト列やXMLフォーマットに変換することをいう。
(中略)
これにより、オブジェクトの表すデータを、ファイルとしてセーブしたり、ネットワークで送信したりすることができるようになる。このようにして得られたバイト列やXMLフォーマットは、直列化復元ないしデシリアライズによって、元のオブジェクトに復元される。
また、オブジェクトを直列化してファイルなどの永続記憶に保存することを永続化という。
https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%BA

つまり、細い回線を通じてデータをやりとりする上で、オブジェクトは大きすぎるので、いったん単純な構造に解いてから通信を行うよってことでよさそう。

使い方としては、クライアント・サーバー共に、送信前にシリアライズ、受信後にデシリアライズを行う感じ、
つまりイメージ的に、回線を流れるデータは常にシリアライズされている状態となる・・・ってこと

#javascriptでシリアライズした記憶が・・・
本当にシリアライズしないと送信できないの？
でもシリアライズなんてした覚えないのに、サーバーにデータ送信できてるけど・・・
と思って調べました。
多くのjavascriptフレームワークには、自動でjson形式にシリアライズしてから送信する機能が搭載されており、私はそれに甘やかされてきただけなようです。
生のjavasncriptを用いる開発では、`JSON.stringify()`などを用いて手動でシリアライズする必要があるということでした。

#注意点
シリアライズ自体には、送信データを暗号化したりなどの機能はないため、情報漏洩対策上では特に意味なし！
引数の基礎

引数がとても苦手でしたので、復習のためにまとめておきます。

rubyではメソッド内で定義していないものを使うことはできません。そのため、以下の記述はエラーになります。

```ruby:ruby
def hoge
  puts huga
end

huga = "眠い"

hoge    #エラーになる
```

hogeメソッドはhugaをputsしたいわけなのですが、hugaはhogeメソッドの中で定義されたものではありません。もちろんhugaの定義をhogeの中ですればOKです。が、それだと引数の説明にならないのでこのまま引数を使ってエラーを解決します。

引数には本引数と仮引数があリます。

```ruby:ruby
def hoge(仮引数)
  puts huga
end

huga = "眠い"

hoge(本引数)
```

本引数は、メソッドを呼ぶ方に書きます。仮引数は呼ばれたメソッドの方に書きます。

実際に本引数と仮引数を入れてみます。

```ruby:ruby
def hoge(huga)
  puts huga
end

huga = "眠い"

hoge(huga)
```

今回のhogeメソッドはputs hugaをしたいわけですが、hugaがメソッド外で定義されているせいでエラーが起きていましたので、メソッドを呼び出す方の本引数にhugaを入れて、仮引数の方にもhugaを入れました。これによって最終行の引数の全てにhugaが入った状態になります。なのでエラーが出ずにターミナルには「眠い」と表示されます。


ここまでは、本引数と仮引数を同じ名前にしましたが、名前が異なっていても使えます。


```ruby:ruby
def hoge(kotoba)
  puts kotoba
end

huga = "眠い"

hoge(huga)
```

本引数 : huga
仮引数 : kotoba

hogeメソッド内のputsの右側が「kotoba」に変わりました。これは、メソッドの中で引数として渡ってきたものを使うためには仮引数と同じ名前でないと使えないからです。例えば以下のようにするとエラーになります。

```ruby:ruby
def hoge(kotoba)
  puts huga
end

huga = "眠い"

hoge(huga)    #エラーになる
```

仮引数はkotobaなのにputsの右側がhugaになってます。やっぱりhugaはhogeメソッドの中で当然ながらこれもダメです。

```ruby:ruby
def hoge(huga)
  puts kotoba
end

huga = "眠い"

hoge(huga)    #エラーになる
```

相変わらずputsの右側のkotobaはhogeメソッドで定義されていません。

1.メソッドで使いたいメソッド外部の変数名など本引数の名前が一致していること
2.仮引数とメソッド内において仮引数で渡されたものを使いたいところの名前が一致していること

上記2点が守れていれば、本引数と仮引数の名前が異なっていても問題なく動きます。

```ruby:ruby
def hoge(name2)
  puts name2
end

name1 = "眠い"

hoge(name1)
```

name1同士は同じ名前
name2同士も同じ名前

こうなっていればOKです。

追記：
1.本引数は実引数ということの方が多いようです。

2.本引数の中にはローカル変数だけでなく式を書くこともできます。なので何か変数名をいれなくても仮引数を書いたメソッドで使いたいものを本引数の部分に式として書いても使えます。

```ruby:hoge.rb
def hoge(name)
  puts "私の名前は#{name}です"
end

puts hoge("ヤマダ")

```
```ruby:ターミナル
ruby hoge.rb
私の名前はヤマダです
```

本引数の部分には変数名などではなく文字列をそのままいれていますが、問題なく結果が出ています。
Dockerで使うコマンドのメモ

こんにちは、[未来電子](https://www.miraidenshi-tech.jp/intern-content/program/)のインターンでプログラミングを勉強している者です。
今週はDockerについて少し学んだので、Dockerで使われるコマンドをメモします。

##Dockerとは

Dockerとは、Docker社が提供している仮想化技術のことです。
Dockerでは、コンテナと呼ばれる仮想環境の中でアプリケーションを操作できます。
コンテナは、ホストマシンのカーネルを共有しており、複数のコンテナを一つのホスト上で同時に動かすことができます。
そのため、Dockerは、ハイパーバイザの上に別々のゲストマシンを置くVirtualBoxとは違い、動作が軽いことが特徴です。


##Dockerで使われるコマンド

Dockerでは、コマンドを用いてイメージ（コンテナを操作するための設定をまとめたもの）やコンテナの操作をします。
ここでは、主に用いられるコマンドを挙げていきます（親コマンドのdockerは省略）。

|コマンド  |　　　　　　　　　　　　意味|
|:-------:|:--|
|login|レジストリにログインする|
|logout|レジストリからログアウトする|
|pull|イメージやリポジトリをレジストリから取得する|
|push|イメージやリポジトリをレジストリに追加する|
|images|イメージを一覧表示する|
|build|Dockerfileからイメージをビルド（ベースイメージに機能を付け加える）する|
|tag|イメージにタグをつける|
|create|新規のコンテナを作る|
|run|新しいコンテナを起動する|
|attach|起動しているコンテナを操作する|
|start|コンテナを起動する|
|stop|コンテナを停止する|
|rm|コンテナを削除する|
|ps|コンテナを一覧表示する|




##まとめ

今回は、Dockerで主に使われるコマンドをまとめてみました。
他にもコマンドはたくさんありますので、勉強したら追加したいと思います。
Dockerについて少し勉強しましたが、まだまだ理解不足な部分が多く、間違って記述している部分もあるかと思います。
間違いがありましたら、訂正したいと思いますので、ご指摘のほどよろしくお願いします。
rails_helper.rb内でrake taskを実行する方法

# 環境

- Rails 5.2.3

# やり方

## その一： 特定のファイルを読み込んで、それを実行する。

```ruby:spec/rails_helper.rb
require 'rake'

load Rails.root.join('lib', 'tasks', 'foo.rake') # 実行したいrakeファイル
Rake::Task.define_task(:environment)
Rake::Task['foo:bar:buz'].invoke
```

## その二： 全てのrakeタスクを読み込んで、特定のタスクを実行する。

```ruby:spec/rails_helper.rb
require 'rake'

Rails.application.load_tasks
Rake::Task['foo:bar:buz'].invoke
```
オプショナル、nil関連まとめ[Swift]

あとで追記

# guard
**・[guard letとif letの使い分け - Qiita](https://qiita.com/solty_919/items/8b22c8b30cd1a5596c83)**
**・[Swift の guard は正しく使いましょう - Qiita](https://qiita.com/satoshin2071/items/08b8b7bf901df4173495)**
**・[Swift 2.0 で追加された guard のいいところ - Qiita](https://qiita.com/mishimay/items/75fb0958f33079ff0e8a)**
#### まとめ
・`guard let`は値が`nil`かどうかのチェック・アンラップを同時に行える
・`guard let {}`で`nil`ならスコープ内で処理を止められる

# 型?
#### エラー文

```before.swift
.map { [weak self] huga -> String in
           guard let hoge = huga else { return nil } //ここなんでnilつけるん
           //省略
           return hogehogeString
     }
```

```
'nil' is incompatible with return type 'String'
```
`String`だと`nil`は存在できません(許容できません)

```after.swift
.map { [weak self] huga -> String? in
           guard let hoge = huga else { return nil } //ここなんでnilつけるん
           //省略
           return hogehogeString
     }
```
→`nil`が入っても大丈夫な`String?`にすることでエラー解消
Pythonでaws-sam-cliをローカル実行するまで

AWSコンソールでポチポチしてみたのですが
ローカル環境での実行をしてみたいなとおもい、その備忘録です。

環境：
macOS High Sierra 10.13.6
AWS SAM CLI
pip 19.2.2
Python 3.7.2
Docker for macOS

---

##目次
1. AWS SAM CLIをインストールする
2. sam init
3. テストを実行
4. ローカルでLambda関数を呼び出す

---
##1. AWS SAM CLIをインストールする

pip を使用して AWS SAM CLI をインストール

```
$ pip install aws-sam-cli
```
バージョンの確認

```console
$ sam --version
SAM CLI, version 0.19.0
```

##2. sam init

sam init コマンドで python3.7のサンプルアプリケーションを作成

```console
$ sam init --runtime python3.7
[+] Initializing project structure...


Project generated: ./sam-app


Steps you can take next within the project folder
===================================================
[*] Invoke Function: sam local invoke HelloWorldFunction --event event.json
[*] Start API Gateway locally: sam local start-api


Read sam-app/README.md for further instructions


[*] Project initialization is now complete
```
Readとのこと =>　https://github.com/yoshiyoshifujii/sam-app/blob/master/README.md

ツリーで見てみる

```
$ tree sam-app/
sam-app/
├── README.md
├── event.json
├── hello_world
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   └── app.cpython-37.pyc
│   ├── app.py
│   └── requirements.txt
├── template.yaml
└── tests
    └── unit
        ├── __init__.py
        ├── __pycache__
        │   ├── __init__.cpython-37.pyc
        │   └── test_handler.cpython-37.pyc
        └── test_handler.py

5 directories, 12 files
```

##3. テストを実行

テストを実行してみる

```
$ cd sam-app
```

```console
$ python -m pytest tests/ -v
========================================== test session starts ==========================================
platform darwin -- Python 3.7.2, pytest-5.1.0, py-1.8.0, pluggy-0.12.0 -- /Library/Frameworks/Python.framework/Versions/3.7/bin/python3
cachedir: .pytest_cache
rootdir: /Users/suwa/sam-app
plugins: mock-1.10.4
collected 1 item                                                                                        

tests/unit/test_handler.py::test_lambda_handler PASSED                                            [100%]

=========================================== 1 passed in 0.07s ===========================================
```
ビルドします

```
$ sam build
```

##4. ローカルでLambda関数を呼び出す

まずDockerを起動する
ローカルで API Gateway 経由で Lambda 関数を呼び出す

```
$ sam local start-api
```
ブラウザで下記URLにアクセスするとコンテナイメージがダウンロードされ、コードが実行されてブラウザに出力が表示されます。
http://127.0.0.1:3000/hello
{"message": "hello world”}

他のblogではLocationが表示されていたのですが

```console
$ vi ./hello_world/app.py
```
で、下にある

```
# "location": ip.text.replace("\n", "")
```
の、コメントアウトを外せばLocationも表示されます。
VirtualBoxでSSH接続して色々作業（npm installとか）した時、あっちに逝ったまま帰ってこなくなる問題の対策

## 環境概要
JamstackやWordPressの開発専用環境として[VirtualBox](https://www.virtualbox.org/)にlinux(Ubuntu 18.0.4)をインストールして、ターミナルや[Vs CodeのRemote-SSH機能](https://blog.masahiko.info/entry/2019/06/15/202003)でSSH接続してコマンド操作しています。
## 問題
SSHで重たいコマンド操作（npm installなど）をする際に冗長だったり処理が重かったり時間掛かり過ぎると、そのままハングして反応が無くなる。
##解決方法
"/etc/security/limits.conf"でリソース制限をした。

詳しくは[ulimitでユーザリソースの制限（Linux）](http://g-network.boo.jp/wiki/2017/04/post-483/)(インフラ勉強wiki)で。

上述の"limits.conf"を以下の様に設定。coderがユーザ名です。再ログインするだけで設定が反映されます。

``` bash
coder hard nofile 1024
coder hard nproc 1000000
coder hard stac 1024
```

これで快適にnpm installやgridsome build / developなどをぶんまわせる様になりました。時々怪しくなる時もありますが、少し待てば動き始める事が殆どです。

なお"ulimit -a"をターミナルで叩けば、現在の設定値が一覧表示されます。

<img width="502" alt="Screen Shot 2019-08-16 at 12.21.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145550/c9789693-07b2-2e0a-08c8-f5ad35faed7d.png">

この設定はうちの会社（の様なもの）のレンタルサーバにSSHで接続して、ターミナルから"ulimit -a"して出てきた設定を参考にしました。
## 雑記
Macの黒い画面でnpmやったりとか色々してウエブ開発やるには[homebrew](https://brew.sh/index_ja)をインストールしておけば、快適に開発できるものの、最近アップルがMacOSのセキュリティに力を入れ始めて面倒臭くなってまいりました。こんどのMacOSのバージョンアップでさらに面倒になりそうですし。

こんどのMacOS 10.15 Catalinaでは、[デフォのシェルがzshに変わる](https://news.mynavi.jp/article/osxhack-241/)らしい。[10.16以降はPythonやRuby、Perlを同梱しなくなる](https://applech2.com/archives/20190606-apple-deprecations-python-ruby-perl.html)とも。OSのアップグレードの度に、色々と無駄な作業が増えそうです。

Dockerを試してみました。お手軽なdocker環境が欲しい場合は、[laradock](https://qiita.com/J_Shell/items/695a30fd38444d065ae5)がよかったです。WordPressとかも動かせます。ただし、dockerは肥大なキャッシュ（64GBとかそんな感じ）が障壁に。最近のお高いマックのSSDには負担すぎる。外部接続ディスクにキャッシュを移動できる事はできますが、少し使っているうちに色々ダルくなってきた。

というわけで、linuxの開発環境をそのままポータブルに扱える様に、Ubuntuで開発環境を作ってVirtualBoxで動かす事にしました。本体のSSDになるべく依存したくないのと、本体のSSDの空き容量を常に確保しておきたいため、開発環境は全てUSB3.0接続の外部SSDに置いています。管理作業はVirtualBoxからWindow ManagerでGUIを使えるので色々とお気楽。

<img width="2560" alt="Screen Shot 2019-08-16 at 14.03.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145550/b59d0e03-84ad-b3f7-c791-043bdc3907e5.png">

VirtualBoxのUbuntuに、nodeやらアパッチやらを好きなだけインストールして、MacOS側からはsshやsambaで接続して操作する感じです。

念の為。時折切りが良い時に、開発環境が入った[仮想マシンをエキスポートしておく](https://selifelog.com/blog-entry-1579.html)のは必須です。たまに具合おかしくなりますから。
ポインタとは？構造体とは？　

#ポインタとは？

###ポインタとは、方向指示器(→,←,↓,↑)のこと！
①方向指示器のマークにするには？　→　変数の前に&を付ける！
②方向指示器を入れる箱は少し特殊な形？　→　＊を型名の後に付ける！
③方向指示器の先に何があるか見たい時は？　→　②の箱の変数名の前に＊を付ける！

```c
#include<bits/stdc++.h>
using namespace std;

int main(){
    int myhouse_id=12345;
    //12345(方向指示器の中身)
    int* myhouse=&myhouse_id;
    //①と②を行っている！
    cout << *myhouse;
    //③を行っている！
}
```
#ポインタをイメージ化してみた！
```c

#include<bits/stdc++.h>
using namespace std;

int main(){
    int x,y;
    int* p=&x;
    //int*型 変数名pの箱に変数xの中身が分かる矢印(&x=→)を保管する！
    
    printf("%p\n",p); 
    //0x28ac54と出力される
    
    *p=8;
    //xの中身を見て、更にを8に書き換えた！
    y=*p+x;
    //この時点で*p=8 , x=8となる！
    
    printf("%d\n",y);
    //16と出力される
    return 0;
}
```
#ポインタを使ったswap関数を作ってみた
```c
#include<bits/stdc++.h>
using namespace std;

int swap(int* X, int* Y){
//方向指示器を入れ替えるswap関数
    int tmp;
    tmp=*X;
    *X=*Y;
    *Y=tmp;
    return 0;
}

int main(){
    int a,b;
    int* A=&a;
    int* B=&b;
    
    cin >> a >> b;
    swap(A,B);
    cout << a << " " << b;
    return 0;
}
```

#構造体とは？

###構造体とは、複数の型の変数をひとまとめにできる配列のこと！
(※通常、配列とは同じ型の変数しかまとめることはできない)

#構造体を宣言するには？(型名&変数名)
①バラバラな型(int,char,string,..)のメンバ変数に対して、統一した型名を付ける！(構造体名(型))
※構造体の中にある変数をメンバ変数という→型がバラバラな変数のこと

```c

struct abc{
    //abcという型を作った！
    string name;
    int id;
    int age;
    string e_mail;
    double GPA;
};
```
②変数名がバラバラなメンバ変数を一つずつ箱に入れるための配列名を付ける！(構造体変数名)


```c
struct abc{
    string name;
    int id;
    int age;
    string e_mail;
    double GPA;
} student;
///studentという変数を作った！
```

#構造体のメンバ変数にアクセスするには？

```c
#include<bits/stdc++.h>
using namespace std;

struct abc{
    string name;
    int id;
    int age;
    string e_mail;
    double GPA;
} student;


int main(){
    student.id = 2014;
    student.name = "wakamatsu";
    //構造体変数名とメンバ変数名を.(ドット)で繋げるだけ！
    
    cout << student.id << " " << student.name << endl;
    return 0;
}
```

#構造体配列を使ってみた
学生の名前,メールアドレス,学籍番号,年齢,GPAをまとめて一つの要素にして配列を作る！

```c
#include<bits/stdc++.h>
using namespace std;

struct abc{
    string name,e_mail;
    int id,age;
    double GPA;
} student[1000];

void printStudent(abc s){
    cout << s.name << " " << s.GPA << endl;
}

int main(){
    int n;
    cin >> n;
    
    for (int i=0; i<n; i++){
        cin >> student[i].id >> student[i].age >> student[i].name >> student[i].e_mail >> student[i].GPA;
    }
    
    for (int i=0; i<n; i++) printStudent(student[i]);
    
    return 0;
}
//入力
3

1 10 naoki 101.docomo 4.5
2 20 miki  202.docomo 5.0
3 30 sai   303.au 3.0

//出力
naoki 4.5
miki 5
sai 3
```
最初にGithubに新規レポジトリを作った時に、merge: origin/master - not something we can merge　が出た時の解決策[Git merge]

# 状況
新しくGithubにGUIで新規レポジトリを作り、すでにローカルにあるフォルダをリモートに移したい。[前回の記事](https://qiita.com/Adaachill/items/5f448aba941dd30e7079)を参考

前回は、git push でリモートにあるファイルやディレクトリがローカルにはないことが原因でエラーが起きたため、push前にmergeをする必要があった。

今回も同様にmergeをすると、

```
git fetch 
git merge --allow-unrelated-histories origin/master
merge: origin/master - not something we can merge
```

というエラーが出た。

https://qiita.com/somarihair/items/8580e9964099e6923bde　
などを見ると、ブランチ名がタイポしているとこういうエラーが出るらしいが、タイポはしていない。

# 結果
README.txtを用意せずに新規レポジトリを作ると、何もファイルがないリモートのレポジトリが生成されるので、空のレポジトリをマージしようとしてエラーが出ていた。

そのため、mergeは無視して、git push -u origin master　をすれば良い。

```
git push -u origin master
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
```
ShellScript Bash 終了コード で 詰まったところ

# 目的

- パイプを使用したときのコマンドの終了コードについて詳しく知る。  
※本記事の内容はbashの環境に依存します。同じbashでもこの方法だと解決しないことがあります。

# この記事のターゲット

- ログを出力しているShellScriptの終了コードが欲しい方
- パイプより前の処理の終了コードが欲しい方

# 自分が困ったエピソード

- `test.sh`という名前のShellScriptのファイルを書いた。
- 実行するときのコンソールログと終了コードが欲しかった。
- 下記の様に当該スクリプトを実行した。  
`./test.sh 2>&1 | tee result.txt`
- 実行後に`test.sh`が正常終了したか知りたかったため下記の終了コードを返すコマンドを実行  
`echo $?`
- 終了コードは0が返ってきた。
- しかし`result.txt`を確認したところ、エラー終了していた。
- パイプを用いたコマンドを使用した場合に`echo $?`を実行すると`tee result.txt`の終了コードが返ってきてしまう。

# 解決方法

- パイプで区切られた範囲の処理の終了コードが特定の配列に入るようになっているらしい。  
${PIPESTATUS}という配列に結果が入っている。
- その配列から欲しい処理の終了コードを抜き取ってあげればOK

# 詳細

- 下記の様なパイプを多用した処理を例にする。

``` shellscript
$ 処理1 | 処理2 | 処理3
```

- 一連の処理の終了コードはそれぞれ下記の様に配列${PIPESTATUS}に格納されている。
  - 処理1の終了コード → 配列${PIPESTATUS}の0番目に格納
  - 処理2の終了コード → 配列${PIPESTATUS}の1番目に格納
  - 処理3の終了コード → 配列${PIPESTATUS}の2番目に格納
  
- 一連の処理の終了コードを出力したいときは下記の様に出力する。
  - 処理1の終了コードをコンソールに表示 → `echo "${PIPESTATUS[0]}"`
  - 処理2の終了コードをコンソールに表示 → `echo "${PIPESTATUS[1]}"`
  - 処理3の終了コードをコンソールに表示 → `echo "${PIPESTATUS[2]}"`
  
  
# まとめ

- パイプを使用した処理の終了コードについてまとめた。
- パイプで区切られた処理の終了コードは配列${PAPESTATUS}に順に格納される。
EC2でdigdagを動かすチュートリアル

# 記事の目的
- EC2へdigdagを導入して、GUIを表示するまでの方法について説明
- digdagはインメモリで実行する前提

# EC2へのdigdag導入
## 前提
- パブリックアクセス可能なEC2(Amazon Linux 2)にssh接続できること

## digdagのDL

- EC2へssh接続後、下記コマンドを実行
- 適宜sudoで実行する必要

```bash

# digdagのDL
$ curl -o /usr/local/bin/digdag -L "https://dl.digdag.io/digdag-latest"

# digdagの権限を変更
$ chmod +x /usr/local/bin/digdag

# digdagのインストール成功を確認
$ digdag —version


```

## (javaをインストールしていない場合のみ、下記を実行)

```bash

$ sudo yum install java-1.8.0-openjdk-src.x86_64

#1.8を選択
$ sudo alternatives —config java

#インストール成功を確認
$ java -version

```

## digdag serverのサービス化(Unitファイルの作成)

```bash

# サービスを新規作成
$ vi /etc/systemd/system/digdag.service

#以下を記載する

[Unit]
Description=digdag

[Service]
Restart=always
ExecStart=/bin/sh -c "/usr/local/bin/digdag server -b 0.0.0.0 --memory"

[Install]
WantedBy=multi-user.target

```
                   
## digdag起動&自動起動設定

```bash

# 設定ファイルの再読み込み
$ systemctl daemon-reload 

# サービス自動起動設定
$ systemctl enable digdag

# サービス起動
$ systemctl start digdag

```

## 動作確認
http://EC2のIPアドレス:65432

- 上記にアクセスし、digdagのGUI画面が表示されていれば成功

※GUI画面が表示されない場合、AWSのセキュリティグループで65432番のポートのインバウンドが開放されていることを確認してください。


# 参考
[Ubuntu で Digdag サーバを作るまでの手順 - Qiita](https://qiita.com/hoto17296/items/b73b605033fb79473024#systemd-%E8%A8%AD%E5%AE%9A)
SymPyでラプラス変換

# 先駆者様

Qiitaでは

[Python: ラプラス変換（数式通り実装してみた）](https://qiita.com/sai-sui/items/3afe2ccaa430b6494158)

という記事がありました。しかしインターネット上を調べてみると[SymPy](https://www.sympy.org/en/index.html)なる便利なモジュールがあるようなので、それでラプラス変換をしてみましょう。

# ラプラス変換

`SymPy`のラプラス変換機能を用いるためには`laplace_transform`関数を用います。

```python
>>> import sympy as sp
>>> s, t = sp.symbols('s, t')
>>> w = sp.symbols('w', real=True)
>>> sp.laplace_transform(sp.cos(w*t), t, s)
(s/(s**2 + w**2), 0, Eq(Abs(periodic_argument(polar_lift(w)**2, oo)), 0))
```

上述の最終行の先頭がラプラス変換結果です。ここでは$\cos (wt)$を変数$t$から変数$s$の関数に変換しています。

# ラプラス逆変換

$\frac{s}{s^2+w^2}$が逆変換によって$\cos$関数に戻ることも確認してみましょう。そのためには`inverse_laplace_transform`関数を用います。変数$s$から変数$t$への変換であることに留意しましょう。

```python
>>> expression = sp.laplace_transform(sp.cos(w*t), t, s)
>>> print(expression)
(s/(s**2 + w**2), 0, Eq(Abs(periodic_argument(polar_lift(w)**2, oo)), 0))
>>> sp.inverse_laplace_transform(expression[0], s, t)
cos(t*w)*Heaviside(t)
```

となり、無事に$\cos$関数に戻ってくることができました。

# 結言

なんとなく我が家にラプラス変換の本が転がっていたので、「これをPythonで行うにはどうすればよいのか？」という暇つぶし程度に考えていましたが、結果`SymPy`の威力を思い知らされた、そんな記事の仕上がりになりました。
Flask で後始末メソッドが呼ばれる順序

（この記事は私の blog の http://umezawa.dyndns.info/wordpress/?p=7337 の転載です）

## 概要

Flask で、後始末メソッドである `teardown_appcontext` `teardown_request` `after_request` が呼ばれる順序。ググってもそのものズバリがヒットしなかったので。

```python
from flask import Flask

app = Flask(__name__)

@app.after_request
def after_request(x):
	print("after_request")
	return x

@app.teardown_request
def teardown_request(x):
	print("teardown_request")

@app.teardown_appcontext
def teardown_appcontext(x):
	print("teardown_appcontext")

@app.route("/")
def view():
	return ""

app.run(debug=True, host="0.0.0.0")
```

結果

```
[umezawa@devubuntu:pts/0 ~]$ python3 flask_teardown_order.py
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 702-370-689
after_request
teardown_request
teardown_appcontext
192.168.0.4 - - [16/Aug/2019 20:31:53] "GET / HTTP/1.1" 200 -
```

## 環境

- Ubuntu 18.04 LTS
- Flask 0.12.2
Unity勉強メモ ～Collider～

## はじめに
この記事は1日前にUnityを触り始めた人の勉強メモです。過度な期待はしないでください。
誤った内容が含まれる可能性が多々あります。誤りに気付いた方は、コメントにて脇腹をつついてください。

### Unityをはじめたきっかけ
Vtuber配信面白いなぁ → VR世界体験したいなぁ → Oculus買うか → Unity勉強しよ（←今ココ
~~驚くべき単細胞！良い子の皆はUnity勉強してからOculus買おうな！おじさんとの約束だ！~~

### チュートリアルとか見ながらやってみるじゃん？
Plane置いて、MMDモデル読み込ませて、Standard Assetsからアニメーションとか持ってきて・・・。
よし、できた！動く動く！（Kawaii!!!!!!!!!!!!!!
![1_ガバガバCollider.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483109/7ff7d9bf-e218-14b2-70c1-b148e4cd1ad0.png)


## Colliderとの闘い
### うわっ…私のCollider、ガバガバすぎ…？
上図の緑色の線がCollider（物理衝突判定の領域）なのですが、明らかにガバガバです。~~抱き枕やん。~~
愛しのOculusちゃんが届いたとして、手に衝突判定ないのは致命的なので、ええ感じのもの探しました。

### SAColliderBuilder
色々なところを見て、ええ感じのものを探していたところ、SAColliderBuilderを発見しました。
早速Asset Storeでダウンロード＆インポート。
~~（互換性がないみたいな文言が出た気がするけど、見て見ぬふり）~~

SAColliderBuilder-Scripts-SABoneColliderBuilderでMesh Colliderを生成してくれるらしい。
早速BuilderでMesh生成して、Capsule Collider消してっと・・・。
![2_MeshCollider.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483109/4f30318e-3b54-d0c8-b3f6-1dc24c1ca9c6.png)

ええやん・・・。ちょっと動かしてみよ・・・。
![3_ツッパリCollider.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483109/ae351d62-3243-8e65-7a2d-6a6998a91366.png)

！？！？！？！？！？！？！？！？！？！？！？！？！？！？
MMDモデルがぐれました。完全にヤンキー座りのオラオラモードです。（Kowaii!!!!!!!!!!!!!!!!!!!!

![4_KawaiiCollider.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483109/52b3a514-0d5e-f2f7-8a25-616d2b8a96c3.png)

あっ、でも可愛い・・・。
とはいえ、さすがにヤンキー座りの超低速オラオラ歩きをさせておくわけにもいきません。

Standard Assetsから引っ張ってきたアニメーション、コントロール周り自体が
単一のCapsule Colliderを対象にした作りであるため、
そのあたりが何層にも分かれているMesh Colliderに対応できていないような感じがします。

今回のメモはこの辺りにして、裏で調査、解決方法の模索をしていこうかな、と思います。
【スプシ】QUERY関数の備忘録~whereで日付を指定~

#　whereで日付を条件指定するには
　whereで日付を指定しようと以下のように書いたら正しく機能しなかった…
```=query(範囲, "select A where A = 2019/08/01")```
*エラーは起こさなかった

#　日付の指定方法
　条件の前に```date```をつければOK
上記の例をもとにすると、
```=query(範囲, "select A where A = date 2019/08/01")```
とすれば正しく機能する。

#　応用編～日付を変数にする~
　実際に使う場合には、変更を加えたり汎用性を高めるためにも、条件は変数を使うことが多い
単純に日付を変数に置き換えるだけでは、機能しない。

変数を使う場合には以下のように書く必要がある。
```=query("範囲", "select A where A = date '"& text(参照セル,"YYY-MM-DD") &"'")```

**'"& text(参照セル,"YYY-MM-DD") &"'"**
ようは、text関数を使って、日付形式に変更しているだけのことである。

これで日付を変数に変えることができる。

# 応用編~年・月・日だけを条件指定する~
　次は○○年を条件にしたいなど、年月日の一部を条件にする方法について

- 年だけを指定

```=QUERY(範囲,"where YEAR(列) = "& text(参照セル,"YYYY") &"")```

- 月だけを指定
 
```=QUERY(範囲,"where MONTH(列) +1 = "& text(参照セル,"MM") &"")```
**月は1月が0からスタートするため、+1をする必要がある**

- 日だけを指定する

```=QUERY(範囲,"where DAY(列) = "& text(参照セル,"DD") &"")```
# 参照サイト
[【スプレッドシート】QUERY関数で条件に日付を指定する方法](https://strategy-conference.com/analysis/spreadsheet/540/)
#ruby の Timecop.freeze で Date を渡すと日付がずれるので Time.local を渡した方が良いかも

Passing Date with # ruby's Timecop.freeze will cause the date to shift, so it may be better to pass Time.local


```rb
Timecop.freeze Date.new(2019, 01, 01)
# => 2018-12-31 15:00:00 +0000

Date.today
# => Mon, 31 Dec 2018

Timecop.freeze ::Time.local(2019, 01, 01)
# => 2019-01-01 00:00:00 +0000

Date.today
# => Tue, 01 Jan 2019

```


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2297








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
DockerでChainer+JupyterLabを構築してみた

機械学習やディープランニングのChainerというフレームワークがあると知ったので、
遊びでDockerで構築してみた。

## GitHub

できたやつ
https://github.com/tubutubumustard/chainer_docker.git

## Dockerfile

```:Dockerfile
FROM ubuntu:16.04

WORKDIR /workdir

RUN apt-get update -y && \
    apt-get install -y --no-install-recommends \
    python3-dev \
    python3-pip \
    python3-wheel \
    python3-setuptools \
    git \
    g++ \
    make \
    cmake \
    libblas3 \
    libblas-dev \
    && \
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*

RUN pip3 install --upgrade pip

RUN export CHAINER_BUILD_CHAINERX=1
RUN export CHAINERX_BUILD_CUDA=1

RUN pip3 install -U --no-cache-dir \
    'ideep4py<2.1' \
    cupy-cuda92==6.2.0 \
    chainer==6.2.0 \
    scikit-learn \
    pandas \
    matplotlib \
    jupyterlab
```

Dockerfileは下記を参考にして作成しました。
https://hub.docker.com/r/chainer/chainer/dockerfile
https://github.com/chainer/chainer/blob/master/docker/intel/python3/Dockerfile

`WORKDIR /workdir`は`JupyterLab`で作業するためのディレクトリになります。

`iDeep`と`CuPy`をインストールしていますが、
僕のノートパソコンには`NVIDIA`の`GPU`は入ってないので、
`iDeep`を使って、計算することになります。

`Docker`で`CuPy`を使用したい場合は、色々設定しないといけないみたいです。
（気が向いたらやってみよう〜）

## docker-compose.yml

```:docker-compose.yml
version: '3'
services:
  chainer:
    build: ./
    volumes:
      - ./workdir:/workdir
    command: jupyter lab --port 8000 --ip=0.0.0.0 --allow-root --NotebookApp.token=''
    ports:
      - 50020:8000
```

docker-compose.ymlでは、遊び用なので、
`JupyterLab`を`root`の起動の許可と、`token`を無効にしています。

## コンテナを起動して、JupyterLabにアクセスする

```:sh
$ docker-compose up -d
```

ブラウザでアクセスする

![スクリーンショット 2019-08-16 20.19.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272551/505311b1-14cf-5155-1543-89989bc35d2a.png)

`Chainer`のバージョンや実行環境を確認

<img width="960" alt="スクリーンショット 2019-08-16 20.22.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272551/b27ab6c2-11d0-d5c9-537f-928a371f67f2.png">

`Chainer`のチュートリアルを動かしてみる

<img width="960" alt="スクリーンショット 2019-08-16 20.27.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272551/dd696f50-9757-6748-43e6-6435c5239956.png">

<img width="960" alt="スクリーンショット 2019-08-16 20.28.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272551/1f09874e-b661-4a3b-cee8-1523b98f3fd2.png">

<img width="960" alt="スクリーンショット 2019-08-16 20.31.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272551/ba0b6066-8770-f535-c3bb-a7db3583a667.png">

ちなみに`CuPy`を使おうとすると、怒られる

<img width="960" alt="スクリーンショット 2019-08-16 20.32.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272551/69900e07-fa93-d612-a0e5-634f5e954503.png">

## 終わり

本格的に機械学習やディープランニングの練習するなら、専用のサイトが用意しているみたいなので、そっちを使った方がいいかな〜
【ExtJS】参考サイト

Ext JSに関する参考サイトのurlを一覧にしました。特にグリッド関係を中心に。
始めたばかりですが、随時更新していきます。

■Sencha Ext JSトライアル版を使うための日本語ドキュメントがダウンロードできます。
　[「Senchaで始めるWebアプリケーション開発」](https://www.sencha.com/blog/sencha-evaluation-guide-ja/)
■ExtJSの基礎的なトピックが解説されています。
　[「Sencha Frameworkの利用（基礎編）｛Senchaタブ｝」](https://www.xenophy.com/learning_place/)
■ExtJSのサンプルがソースコード付きで掲載されています。
　[「EXT JS Examples｛V6.5.3選択時｝」](https://examples.sencha.com/extjs/6.5.3/)
■GridPanelの詳細な構造がわかりやすく解説されています。
　[「Ext JS 入門者の最初の壁～Ext.grid.GridPanel へのデータの読み込み～」](https://www.ibm.com/developerworks/jp/web/library/j_wa-aj-extjs/index.html)



■英語ですが、QAサイトです。
　[Sencha Forum](http://www.sencha.com/forum/)
　[Stack Overflow](http://stackoverflow.com/)