OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel+SPA+JTWAuthで認証ありの投稿アプリをつくる ~パート2~

# はじめに
サーバーサイドの処理はLaravelでクライアントサイドはSPAで認証、新規会員登録、記事の投稿を一括で作成しましたので、自分用のメモ含め紹介いたします。

# 前提
Laravel5.5
Vagrant環境
認証はJTWAuth使用
SPAはVue、Vue Router

前回のパート１の続き
https://qiita.com/ProgramingDai/items/403ee4fbc0971827f160

# 今回作るもの
認証ユーザーで記事の投稿する機能実装

# 手順レシピ
1.記事リストの編集

```html:resorces/asset/js/components/pages/List.vue
<template lang="html">
  <div class="container">
    <div class="list-group">

      <!-- 追加③ -->
      <router-link
      v-for="( item, key, index ) in items"
      :key="key"
      :to="{ name: 'detail', params: { id: item.id } }"
      class="list-group-item"
      v-if="user.id == item.user_id">
        {{item.title}}
        <button class="btn" @click.stop.prevent="onDelete(item.id, key)">削除</button>
      </router-link>
      
    </div>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      items: null,
      user: {} // 追加②
    }
  },
  mounted: function() {
    // 中略
  },
  methods: {
    // 中略
  },

  // 追加①
  created() {
    axios.get('/api/me').then(res => {
      this.user = res.data;
    });
  }

}
</script>
```
追加①
`axios.get('/api/me')`でAuthControllerのmeメソッドからデータを取得
取得したデータをuser変数に格納

追加②
dataの中のuserプロパティに配列で格納
そうするとtemplate内で{{ user.id }}や{{ user.name }}などで表示可能

追加③
認証ユーザーのみ記事を表示させる
`v-if="user.id == item.user_id"`

user.id = 認証UserのID（主キー）
item.user_id = その記事が誰が投稿したかを示す値（外部キー）

2.詳細ページの編集

```html:resorces/asset/js/components/pages/Detail.vue
<form v-else>
<!-- 追加 -->
<input type="hidden" name="user_id" id="TopicUserId" class="form-control" v-model="item.user_id">

<!-- 中略 -->

<script>
// 追加
onUpdate: function() {
            axios.put('/api/topics/' + this.item.id, {
                // 追加
                user_id: this.item.user_id,
                title: this.item.title,
                content: this.item.content
            })
// 追加
</script>
```

3.フォームページの編集

```html:resorces/asset/js/components/pages/Form.vue
<template>
<!-- 中略 -->
</template>

<script>
export default {
    data: function() {
        // 中略
    },
    methods: {
        create : function() {
            axios.post('/api/topics', {
                user_id: this.user.id, // 追加
                title: this.title,
                content: this.content,
            })
            .then((res) => {
                this.title = '';
                this.content = '';
                this.saved = true;
                console.log('created');
            });
        }
    },
    // 追加
    created() {
        axios.get('/api/me').then(res => {
        this.user = res.data;
        });
    }
}
</script>
```

これで、認証ユーザーで記事の投稿、認証ユーザーのみの描画が可能です。

あとは新規会員登録のみです。
次回はこちらを実装する方法を実装したいと思います。

# 補足
js側を変更した場合は
`npm run dev`しないと更新されませんので、ご注意ください。
JSON.parse() しても 文字列 が返ってくる問題を調べた話

## 経緯と問題

こんな感じのコードを書いていた


```.js
const test_data = '{ "id": 1, "comment": "foo" }';
const str = JSON.stringify(test_data);
const myobj = JSON.parse(str);
console.log(typeof myobj) // 期待 : object, 結果 : string
```

ここで出力されるのは `object` を期待。
しかし実際は `string` でした。

忙しい方への [オチ](#原因) はこちら。

## 実験

ぐぐったらこんな記事が。
2回 JSON.parse() するの？

https://stackoverflow.com/questions/42494823/json-parse-returns-string-instead-of-object

あ、マジでうまくいった。

```.js
const test_data = '{ "id": 1, "comment": "foo" }';
const str = JSON.stringify(test_data);
const not_obj_str = JSON.parse(str);
const myobj = JSON.parse(not_obj_str);
console.log(typeof obj) // 期待 : object, 結果 : object
```

## 原因

```.js
const test_data = '{ "id": 1, "comment": "foo" }';
const str = JSON.stringify(test_data);
```

ダメだったのはここ。
すでに文字列な状態のものに (輪をかけて) JSON.stringify() してしまっていた。

`JSON の完全な構文は以下のとおりです` に続く定義に書かれている通り、
文字列を文字列にするみたいなのは別におかしくなさそう。

```.js
JSONString = ""
          or " StringCharacters "
```
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON

 (個人的には、文字列が入ったら「文字列を文字列にするの？　意味なくね？」的なエラーが来ると思っていた...)
stringify の箇所だけ try-catch しても普通に動くのは確認済み。


## 最終的な対応

```.js
const testData = { "id": 1, "comment": "foo" };
const str = JSON.stringify(test_data);
const myobj = JSON.parse(str);
console.log(typeof myobj) // 期待 : object, 結果 : object
```

もちろん、 そもそもの入力として、素直にJSONを入れればよいです。
あたり前田のクラッカー。

## 実験と余談

```.js
const test_data = '{ "id": 1, "comment": "foo" }';
const str = JSON.stringify(test_data);
const str_two = JSON.stringify(str);
const myobj = JSON.parse(str_two);
const myobj_two = JSON.parse(myobj);
const myobj_three = JSON.parse(myobj_two);
console.log(typeof myobj_three); //object
```

例外が出力されない。うーむ、そういうものかー。

## 参考文献

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
【UiPath】Excelアプリケーションスコープで開いたファイルを開いたままにする


前提条件：
UiPath Studio Community Edition 2019.5.0
UiPath.Excel.Activities v2.6.0

# Excelアプリケーションスコープのプロパティ値による方法
Excelアプリケーションスコープのプロパティ「Output > Workbook」に変数を指定する。
こうすると、**ロボットが実行されている間は**ファイルが閉じない。ロボットの実行が終わるとExcelファイルが閉じる。

![excel01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/1e3df284-ae0e-2259-c873-5753feeb811e.png)

## 自動保存するかどうかは開いたときに決まる
たとえば、以下のように、1つ目のExcelアプリケーションスコープで開いたExcelファイルを、2つめのExcelアプリケーションスコープで書き込みを行い、保存させたいとする。
![excel03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/f9067651-cdf4-c509-716e-121fd646f9f4.png)

この場合、2つ目のExcelアプリケーションスコープで書き込んだ値が保存されるかどうかは、1つ目のExcelアプリケーションスコープのプロパティによる。1つ目のところで「自動保存」にチェックを入れていれば、2つ目の「自動保存」がオフでも、書き込みの後で内容が保存されている。
逆に、1つ目の「自動保存」がオフの場合、2つ目でオンにしても自動保存されない。

# 「プロセスを開始」でExcelファイルを開く方法
アプリケーションなどの起動に使う「プロセスを開始」アクティビティで、直接Excelファイルのパスを指定すればファイルを開くことができる。この方法の場合、ロボットが完了してもExcelファイルは閉じない。
![excel04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/17a70e0e-17ab-a69b-61b4-73ce7bac2aaf.png)

## 後続のExcelアプリケーションスコープのやり方
「プロセスを開始」でExcelファイルを開く場合、そのファイルをExcelアプリケーションスコープで扱うには注意点がある。
人が操作するときと同じようにExcelが起動するため、スプラッシュ画面が出たりして、即座にExcelアプリケーションスコープでファイルを捕まえられなかったりする。
![excel05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/1dd87149-7532-d911-1c1a-db4ff4ba7274.png)
上記のように、Excelファイルを開いた直後にExcelアプリケーションスコープを実行すると、Excelが起動しきる前にExcelアプリケーションスコープへ処理が移ってしまう。実行中によく見てるとExcelファイルが二重で開かれていて、意図した動作にならない。

それを解消するためには、「プロセスを開始」の後に「要素を検出」などを挿入すればよいとされている。

↓どうにかしてExcelファイルの起動を待とうとしているサンプル
![excel06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/3de53ea3-7c42-320e-d642-d39b8d97765f.png)

しかし実際は「要素を検出」や「待機」を挟んでも、Excelアプリケーションスコープで開いているファイルを認識できず、二重起動することが多い。
もしロボット起動後もExcelファイルを開いたまま残したい場合は、一度Excelアプリケーションスコープで編集したファイルを閉じ、フローの最後に「プロセスを開始」でExcelファイルを開くだけにした方が良さそう。

↓Excelアプリケーションスコープで編集してから、Excelファイルを開くサンプル
![excel07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/c76e2e18-3850-f074-509a-ea9319585884.png)
Lesson2: まとめ How to Use Git and GitHub＠Udacity

#概要
Lesson2では自分一人のプロジェクトでGitを使用することを想定して、リポジトリ作成・コミットを学ぶ。
それに伴って、マージ・ブランチの考え方を使って、実験的にコーディングしながら進めるやり方を学ぶ。


#詰まったところ
ほぼほぼLesson1の復習の内容だったが、詰まったところをまとめる。
Quiz12でのpappu-pakiaゲームのバグフィックスの体験。

>git clone https://github.com/udacity/pappu-pakia.git

でまずはローカルリポジトリを作成。
現状だと下記2点不具合がある。
・かわすべき障害物出てこない
・操作する鳥(Pappu)が画面上に点滅しながら飛び回っている。

手順としては
1, git log で履歴を見る
2, git checkout commit IDで各コミットでゲームをプレイしながら、どのコミットでバグが出てきたか調べる。
【トラブル】
ここで、checkout後にgit log を入力すると、checkoutしたコミットよりも以前のコミットしか出てこず。。。。最新版のコミット番号が表示されなかった。。。
色々調べると、checkout とはブランチを切り替えるもので、そのコミットのbranchを一時的に作成し、そちらに切り替えるのがcheckoutらしい。

[【Git入門】チェックアウト(checkout)とは？使い方を基礎から解説！](https://www.sejuku.net/blog/71457#checkout)を参考にさせていただきました。

>git branch
で現状のブランチを表示させると
>$ git branch
>* (HEAD detached at 71d5270)
>  master

masterに星がついていなかったので、

>git checkout master

コマンドで、masterブランチに切り替えると、最新のコミットを表示できた。


3, git diff でバグ(差分)を見つける。
>git diff commitID(旧) commitID(新：バグが入ったコミット)

で今回は
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333380/f6652496-e80f-0179-4da9-8acdf548339e.png)

utils.jsファイルから赤字のマイナスの部分が消えていることがわかったので、sublimeでutils.jsファイルを開き、緑のプラスの部分に赤のマイナスの部分を上書きして保存。

4, 動作確認


5, コミット
>git add -A

でリポジトリすべてのファイルをコミットする場所へadd -Aは全ファイルオプション
この時点ではまだコミットしていない。

>git commit -m "bag fixed"

でコミットして完了。




#調べた英単語
culprit・・・n, 犯人、犯罪者

#感想
最初は全然楽勝だったが、Quiz13から結構調べた。
おかげで勉強になった。
テスト3

```vb
'ブックB
Sub Sample()
Dim p As String
Dim wb As Object
 
p = "C:\Users\user\Desktop\A.xlsm"
Set wb = Workbooks.Open(p)
 
wb.VBProject.VBComponents("UserForm1").Designer.Controls("textbox1").Value = "テスト"
MsgBox wb.VBProject.VBComponents("UserForm1").Designer.Controls("CommandButton1").Caption
 
Application.Run "A.xlsm!フォームを開く"
Application.Run "A.xlsm!コマンドボタンクリック"
End Sub

'-----------------------------------------------------------
'ブックA
Sub コマンドボタンクリック()
Call UserFormA.CommandButton1_Click
End Sub

Sub CommandButton1_Click()
MsgBox "メッセージ"
End Sub

```
Python print()のメモ

これは初心者が書いたメモ
#そのまま出力
```python
print("Hello World")
print('Hello World')
print(1)
```
```:出力結果
Hello World
Hello World
1
```
文字列はダブルクォーテーションかシングルクォーテーションでくくって()の中に入れる。
数値はそのまま()の中に入れる。


#変数に入れてから出力
```python
hoge1="Hello"
hoge2="World"
moge1=1
moge2=2
print(hoge1)
print(moge1)
```
```:出力結果
Hello
1
```
変数を()の中に入れる。


#文字列の結合
```python
print(hoge1+hoge2)
print(moge1+moge2)
#print(hoge1+moge1)#これはエラー
```
```:出力結果
HelloWorld
3
```
2行目は数値なので結合にはならず足し算の結果が出力される。
文字列と数値の結合は出来ないので3行目はエラーが出る。


#並べて出力
```python
print(hoge1,hoge2)
print(moge1,moge2)
print(hoge1,moge1)#これはエラーにならない
```
```:出力結果
Hello World
1 2
Hello 1
```
間が半角スペースで区切られて出力される。


#区切りを指定
```python
print(hoge1,hoge2,sep=",")
print(hoge1,hoge2,sep="")
```
```:出力結果
Hello,World
HelloWorld
```
sep=","でコンマを指定。半角スペースだった区切りがコンマになる。デフォルトではsepの値が半角スペースになっているのを変更しているということ。
sep=""にすると結合した時と結果は同じになる。


#末尾を指定して改行させたりさせなかったり
```python
print(hoge1)
print(hoge2)
```
```:出力結果
Hello
World
```
こう書くと改行されて出力される。

```python
print(hoge1,end=",")
print(hoge2)
```
```:出力結果
Hello,World
```
end=","でコンマを指定。末尾にコンマを付け足して改行しない。デフォルトではendの値が改行コードになっているのを変更しているということ。

```python
print(hoge1,end=",\n")
print(hoge2)
```
```:出力結果
Hello,
World
```
だからこうすると末尾にコンマを付け足して改行する。

```python
print(hoge1,end="")
print(hoge2)
```
```:出力結果
HelloWorld
```
これはただ単に改行しないし何も付け足さない。


#逆に1行で改行したい場合
```python
print("Hello\nWorld")
```
```:出力結果
Hello
World
```
間に改行コードの\nを入れる。

```python
print(hoge1+"\n"+hoge2)
print(hoge1,"\n",hoge2,sep="")
```
変数を使うならこう。

#公式
[Python 3.7.3 ドキュメント](https://docs.python.org/ja/3/library/functions.html#print)
不要なリソースグループを削除するスクリプト備忘録

検証などでazureサブスクリプションにリソースを作っていると、リソースが一つもないのに残っているリソースグループが複数できていたりする。そんなサブスクリプション上のゴミリソースグループをまとめて削除するAzure Powershell スクリプト

```powershell
$resourceGroups = Get-AzureRmResourceGroup
foreach ($rg in $resourceGroups)
{
    $resources = Get-AzureRmResource -ResourceGroupName $rg.ResourceGroupName

    if($resources.count -le 0)
    {
        Remove-AzureRmResourceGroup -Name $rg.ResourceGroupName -AsJob
    }
}
```
パッケージ管理コマンド aptとapt-getの違い

aptもapt-getも、Debian用に開発されたパッケージ管理システムです。
Debianの派生ディストリビューションであるUbuntuにも採用されています。

Debian管理者ハンドブック( https://debian-handbook.info )に以下の記述があります。

> APT は巨大なプロジェクトで、当初の予定ではグラフィカルインターフェースを含んでいました。APT はライブラリに基づいており、そのライブラリにはコアアプリケーションが含まれています。
apt-get は最初のコマンドラインベースフロントエンドで、APT プロジェクト内で開発されました。
apt は APT から提供されているもう一つのコマンドラインベースフロントエンドで、apt-get の持っていた設計上のミスを克服しています。

なお、Ubuntuにおいては、バージョン14.04よりaptコマンドの使用が推奨されています。
Common LispからVimを起動する

# 概要

Common LispからVimを起動してGitでcommitするときのあの動作を再現する。

# 前提

* OS : Ubuntu 18.04.1 LTS
* 処理系 : SBCL 1.4.5.debian
* Vim : Vim 8.0

# 実装方法

## 起動するだけ

```cl
(sb-ext:run-program "/usr/bin/vim" nil :output t :input t)

; Nanoを起動したければ以下のようにする
; (sb-ext:run-program "/bin/nano" nil :output t :input t)
```

## ファイルを開いて起動

```cl
(sb-ext:run-program "/usr/bin/vim" (list "/path/to/some/file") :output t :input t)
```

## 終了コードを取得する

`:wq`、`:q`で終わったときは`0`が返る。
`:cq`で終わったときは`1`が返る。

```cl
(sb-ext:process-exit-code 
  (sb-ext:run-program "/usr/bin/vim" nil :output t :input t))
```

# 用途

例えばGitのようにコミットメッセージのような文章を入力させたい場合に使える。
y/nの質問のような単純なものであれば標準入力からそのまま入力させてもいいけど、
テキストで色々な情報を見せながら、いくつかの項目を入力させたい場合とかに良い。

# 改善するべき点

Vimのパスを絶対パスで指定しているので環境によっては動かないかもしれない。
この点は改善が必要だと思う。
【視聴メモ】AMP for Email: Coming Soon to an Inbox Near You (Google I/O'19)

この記事は Google I/O '19 のセッションの視聴メモです。
想定読者は自分なので正確性や網羅率には問題があるかもしれません。

---

## References

https://www.youtube.com/watch?v=BFgC7WfbWjY
Speaker(s): Filip Stanis, Aakash Sahney, and Isaac Kim

## Abstract

> Last year, we announced AMP for Email, a powerful way to create more engaging, interactive, and actionable email experiences. Learn about AMP for Email and what’s possible in email when up-to-date content, quick actions, and interactivity are added through live implementations and demos. 

訳

> 昨年、私達はメール体験をより魅力的でインタラクティブでアクション可能なものにする強力な方法であるAMP for Emailについてお知らせさせていただきました。AMP for Emailが提供する最新のコンテンツの表示、クイックアクション、インタラクションについて実装のライブデモを通して学びましょう。

## Contents

* Emailの見た目は実は2000年から殆ど変わっていない
* ケーススタディ
    * GoogleDocsではドキュメントに来たコメントにその場で返信できる
    * Pinterestでは写真をブラウジングできてその場でピンできる
    * OYOでは部屋の一覧や詳細がWebページに近い形でブラウジングできる
    * IndeedではJob紹介をAMPにしたらクリック率が2倍になった
* デザインガイドライン
    * 以下の6つの項目に注意しよう
    * 1. 目的: メールの内容を伝えることを補助するような拡張になっているか？
    * 2. 発見: ユーザーはその要素がインタラクティブだと感じるか、もしくは最新のコンテンツだと気づくか
    * 3. ナビゲーション: ナビゲーションがある場合、それはメールの理解を助けるためになっているか
    * 4. 確認: アクションが存在する場合、その結果がフィードバックされるか
    * 5. 適切な短さ: メールのコンテンツから外れるときに適切にリンク先が案内されるか
    * 6. アクセシビリティ: アクセシビリティのベストプラクティスに沿っているか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387/62467cf0-1f4e-fc81-285d-1218718d3875.png)

* 様々なサービスがAMP for Emailのために使える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387/90700994-b379-634a-51f4-1e88537df84a.png)

**Demo**

* Playground
    * https://amp.gmail.dev/playground
* cdn.ampproject.org のJSだけインポートが許可される
* Gmailの設定でDynamic emailを有効にしないとAMPバージョンは表示されない
* formでは`action-xhr`を使う（普通の`action`だとページ遷移してしまうので）

**SparkPost**

* SparkPostはEmailを送信し分析するためのプラットフォーム
* Emailのテンプレートを書ける
* AMPに対応、どころかかなりの部分を勝手に書いてくれる

## Memo

* 自社のサービスでも是非取り入れたいが、アプリベースのサービスの場合、どれぐらいメールからの流入があるかをまず測定しなくちゃいけないかな？
* 「何ができるか」だけでなく「どうするべきか」というガイドラインが公開されているのでやりやすい
* SparkPostみたいなサービスを知らなくて自分でこういう仕組みを作ったことがあったのでそれをSparkPostにリプレースしたい…
「ソフトが作れる」ようになるためには

# はじめに

先日まで新卒社員向けの研修を行っていました。グループワークをやらせている間暇だったので（ぉぃ）、「どうしたら、書籍等でプログラミング言語学びました！な段階から次のステップに進めるか」を考えていました。
以下、研修中の出来事も踏まえて所見を述べます。研修の題材がC言語とArduino（組み込みシステム）だったので例に偏りがありますがそこそこ一般化しているはずです。

# データの構造化

グループワークのお題は「Arduino使って何かおもしろいもの作れ」です。
おもしろいものと言われると大体ゲームを作ります。その際、「自分のHP、自分の残弾、敵のHP、敵の残弾、・・・」
ここで、「あれ？HPと残弾まとめられるな」と構造体を作ろうと思った人は合格。こちらが「データの構造考えて、ちゃんと設計書に書いてね」と言っても結構な数がべたに「構造化してない」変数を羅列したプログラムを書きます。

# モジュール化（ファイル分割）

バージョン管理システム導入してない理由なんでだっけ？まあそれはともかく、「複数人でプログラムを作る」というのに、「それぞれが書いたコードを一つのファイルにマージ」するチームがいます。ここ数年同じようなグループワークをしていますが大体毎年います。
これはつまり、**処理を意味のあるまとまりごとに分ける**モジュール化の概念がないということだと思います。よく思うとモジュール分割はカリキュラムに入ってない気がしますが（ぉぃ

# 言語機能の使い方

プログラミング言語の研修をしていると鉄板で聞かれる質問は「これ（言語機能）って実務でどのように使われるのですか？」です。
答えも鉄板で「無茶苦茶使う。だが今の君では具体的な使用例を説明しても理解できん（と、直接的には言いませんがｗ）。だからとりあえずこんなものがあるってだけ覚えてくれ」と言うのですが大体納得されません。
で、「自分でシステム作れ」と言うと、「やり方がわからない・・・」という状況になることが多いです。以下に例を示します。

## ビット演算

組み込みではビット操作の理解は必須です。グループワークで使っていた機材で言うとLCD（HD44780互換）を**ドット単位**で制御するにはビットをシフトしたりアンドしたりが必要になります。
暇だったので私が「ドット単位でキャラをスクロールするサンプル」を作りましたがｗ、「こういうことをしたい」「こんな処理をすればいい」「この言語で言うとこう書けばいい」という思考の流れと実装力を身に付けることができれば初心者は脱出だと思います。

## ポインタとはなんなのかを理解しているか

受講生から呼ばれたので行ってみたところ、「ゲームを一回終えてタイトルに戻るとキャラ表示がおかしくなる」とのことでした。とりあえずゲームのフローに沿ってプログラムを読み進めていくと、

```c
recvMsg(&id); // 実際のコードではありません
```

のように書くべきところを

```c
recvMsg(0x106); // 待ち受けるID書いてた
```

と書いていたため、ArduinoのRAMは0x100から始まる＆そこにキャラのドットパターンがあるというコンボでメモリ内容が破壊されていました。
APIの使い方が間違っていたのが原因ですが、「何故かおかしくなる」というときに「メモリ内容が変になっているのでは？」という推論とそれに沿った調査ができるとだいぶ上級者かなと思います。

また、別のグループではmemcpyにアドレス渡す時に

```c
memcpy(data[2], value, 2); // 正しくはmemcpy(&data[2], value, 2);
```

のように書いており[^1]、「アドレスとはなんなのか」はやはり初心者の方には難しいのだなと思いました。
**ポインタは一回メモリをぶっ壊したらよくわかる**というのが持論なわけですがｗ

[^1]: Arduinoはデフォルトで「警告オフ」なので「型がおかしい」ワーニングが表示されません。

# おわりに

以上、「プログラミング言語習った」から、「プログラム中級者、上級者」になるにはどのようなことが必要かを事例ベースで述べてきました。まとめると以下のようになります。どの言語でも大体当てはまることかなと思います。

- データの構造を考える
- モジュール構造を考える
- 言語機能（ライブラリ含む）を一通り把握していて適用できる

最後に、「じゃあどうやったらこれが身に付くのか」という質問に対する回答。
「優秀なソフトのコードを読め。そして感じろ」
dotfile で設定ファイルを管理できるようになって嬉しいので晒す

# dotfiles でファイル管理できるようになって嬉しいので晒す

以前からずっとやろうやろうと思っていたが、後回しにしていた dotfiles でのファイル管理  
今回は、ついに、dotfiles でファイル管理を出来るようになって嬉しいので中身を晒します。

## 対象ファイル

* .zshrc
* .zshenv
* Brewfile
* settings.json(vscode)

### ディレクトリ構成

```
dotfiles/
 ├─ zsh/
 │   ├─ .zshrc
 │   └─ .zshenv
 ├─ dotfile.sh
 ├─ Brewfile
 ├─ settings.json
 └─ dotfile.sh
```

## GitHub Repository

[dotfiles](https://github.com/yasudanaoya/dotfiles)  

## 覚えたこと

* シンボリックリンク
* shell script での条件分岐
* zsh 設定ファイルのこと少し
* Homebrew でアプリ管理することのメリット

## 内容

### .zshrc

以下の記事を参考にしました。  
[zshの設定ファイルの読み込み順序と使い方Tipsまとめ](https://qiita.com/muran001/items/7b104d33f5ea3f75353f)

zsh は、ログイン時に `$ZDOTDIR/ ` にある設定ファイル `.zshrc` を読み込み、起動してくれるそうで、
その `$ZDOTDIR` のデフォルトは `$HOME` となっています。
なので、色々な記事で、 
> .zshrc はルートページに配置しましょう！

と書いてあるんですね。

つまり、 `$ZDOTDIR` の場所を変更することで、 `.zshrc` の保存場所を変更できます。

では、 `$ZDOTDIR` はどこで定義し直すことが出来るのかですが、
それは、 `$HOME/.zshenv` によって定義することができます。

...何だか、問題が帰ってきた感じがします。。

ただ、私が調べた限り、これは固定で `.zshenv` の場所は変えられないようです。

よって、 `.zshenv` なるものをルートパスに置いて、`ZDOTDIR=${HOME}/git管理するフォルダ` とすることで、 `.zshrc` を git 管理できます。

```:.zshenv
export ZDOTDIR=${HOME}/dotfiles/zsh
```

### Brewfile

Homebrew でインストールしたアプリケーションをリスト化して管理できます。

Homebrew をインストールするだけでは、Brewfile での管理は出来ないので、 Brewfile をするアプリを Homebrew でインストールする必要があります。

インストールコマンド

```
$ brew install rcmdnk/file/brew-file
```

[こちらの記事](https://startappdevfrom35.com/homebrewinstall/)を参考に .zshrc の中で、Homebrew のコマンド実行時に、 `Brewfile` を更新してくれるようにしました。

```
# brew

# brewfile を自動で更新する
if [ -f $(brew --prefix)/etc/brew-wrap ];then
  source $(brew --prefix)/etc/brew-wrap
fi
```

また、これだけだと `~/Brewfile` となり、 dotfiles での管理ができません。

ZDOTDIR の要領で、 Brewfile の場所を変えます。

```:.zshrc
# brew

# brewfile を自動で更新する
if [ -f $(brew --prefix)/etc/brew-wrap ];then
  source $(brew --prefix)/etc/brew-wrap
fi

# brewfile の場所を変更する
export HOMEBREW_BREWFILE=~/dotfiles/Brewfile
```

### vscode

vscode の setting.json も、せっかくなので git で管理したいです。

ここでシンボリックリンクを使います。

```
$ ln -s ${DOT_DIR}/settings.json $HOME/Library/Application\ Support/Code/User
```

vscide の setting.json の場所にシンボリックリンクで、 dotfiles の setting.json を貼り付けます。

これで終わり。

### shell

最後に、これらを1つのコマンドで完結させるために shell script を作ります。

```shell:dotfile.sh
# なんどもこのディレクトリを指すことがあるので、このファイルの場所を先に宣言しておきます。
DOT_DIR=${HOME}/dotfiles

# Brewfile を見てアプリをインストール
brew bundle

# zsh インストールされて、使えるようになっているはずなので、 zsh 構成ファイルのシンボリックリンクを作成
ln -s ${DOT_DIR}/zsh/.zshenv ${HOME}/.zshenv

# ないとは思うが、念のため、 setting.json のシンボリックリンクを作成する前に、 VScode が入っているかを確認、
if [ -e ${HOME}/Library/Application\ Support/Code/User ]; then
  rm -f ${HOME}/Library/Application\ Support/Code/User/settings.json

  ln -s ${DOT_DIR}/settings.json $HOME/Library/Application\ Support/Code/User
fi
```

これでおしまいです。
他にも .gitignore_global や、スクリーンショットの保存先などなど、もっと色々な設定も、このファイルで管理できるようにしていきたいですね。
AlamofireとSwiftyJSONでサーバーと通信（サーバー側はPHPで実装）

サーバー側も実装しなければいけなかったので覚書きです。

環境は以下の通りです。

iOS側
言語：Swift
ライブラリ：Alamofire,SwiftyJSON

サーバー側
言語：PHP
SQL：MySQL

サーバー側はロリポップのレンタルサーバーです。

サーバー側で持っているユーザー情報をiPhoneから更新する処理を実装します。

まずはPHP側から
UserIDとUserNameをPostで受け取り、以下の流れで更新処理をかけています。

1.PostでUserIDとUserNameを受信
2.受け取ったUserIDでDBを検索
3.UserIDでレコードがヒットしたら対象レコードをアップデート

```updateUserInfo.php

require('connect_db.php');
$user_id = $_POST['user_id'];
$user_name = $_POST['user_name'];

$selectQuery = "SELECT COUNT(*) AS num FROM USER_ACCOUNT WHERE USER_ID = '" . $user_id . "'";

$result = SELECT($selectQuery);
while ($row = $result->fetch_assoc()) {
   if($row["num"]>0){
     $updateQuery = "UPDATE `USER_ACCOUNT` SET `USER_NAME`='".$user_name."',`UPDATE_TIMESTAMP`=CURRENT_TIMESTAMP WHERE `USER_ID`='".$user_id."'";
     echo UPDATE($updateQuery);
   }
}

$ary = array('USER_NAME'=>$user_name);
// 配列をjson_encode関数でJSON形式に変換します。
$json = json_encode($ary);
// 変換したJSON形式である$jsonを表示します。
print($json);

```

```connect_db.php
function SELECT($query){

  //$server,$user,$pass,$databaseには自分のサーバーの接続情報を入力して下さい。
  $mysqli = new mysqli($server, $user, $pass, $database);
  if ($mysqli->connect_error) {
    echo $mysqli->connect_error;
    exit();
  } else {
    $mysqli->set_charset("utf8");
  }
  $sqlSelect = $query;
  if ($result = $mysqli->query($sqlSelect)) {
   return $result;
  }else{
    printf("Errormessage: %s\n", $mysqli->error);
  }

}

```


Swift側の処理は以下の通りです。

```updateUserInfo.swift
func updateUserName(userID:String,userName:String){
        //createNewUserIDUrlには自分のサーバーのURLを入力
        //サーバー側の処理はUserNameを受け取り、更新した後、そのままJSON形式で返却する処理になっています。
        Alamofire.request(createNewUserIDUrl, method: .post, parameters:["user_id":userID,"user_name":userName]).responseData(completionHandler: { response in
            do{let json = try! JSON(data:response.result.value!)
                for (key,results):(String, JSON) in json {
                    let userName = results.string as! String
                    //データを受け取った後の処理
                }
                
            }catch{
                print(error)
            }
        })
    }

```
平成31年(2019年)春期 プロジェクトマネージャ試験　午後１ 我が解答備忘録（その2）

問1は [こちら](https://qiita.com/putti/items/3091634ef44c73f2f1cb)

問1より遥かにシンプルに書いてあるのは~~飽きたから~~試験会場で考えたことを忘れてしまったから[^1]

## 問2 IoTを活用した工事管理システムの構築
##### 設問1 H課長(PM)が、下線①の確認を行ったのはなぜか。(30字以内)
|下線① これらの六つの要素に関わる作業を全て完了すれば、G社プロジェクトは確実に完了しているといえる関係であることを確認した |
|:--|

:pencil2:私の解答　WBSに漏れなく作業を洗い出して確実に納期を守るため(26)

:thought_balloon:ふりかえり
自信度　C
上記に上げた通り解答したかは失念しました（汗
今、見ても根拠を見つけられないので、不正解になっている可能性もありそうかな、と思う。。

##### 設問2(1)　下線②について、H課長が考えた、G社プロジェクトが遅延するリスクがG社に与える非常に大きな影響とは、具体的に何を指すか(35字以内)
|下線② G社プロジェクトが遅延するリスクがG社に非常に大きな影響を与えると考えた |
|:--|

:pencil2:私の解答　X国の契約の慣例に従い多額の損害賠償金を支払うこといなること(30)

##### 設問2(2)　下線③について、H課長が、G社プロジェクトの特性を考慮して行った人選とはどのような人選か(30字以内)
|下線③ 図1から確認できるG社プロジェクトの特性を考慮した人選を行った |
|:--|

:pencil2:私の解答　プログラムマネジメントの経験や能力の有無を確認できる人選(28)

:thought_balloon:ふりかえり
自信度　A
複数プロジェクトの監視・コントロールできる人＝プログラムマネージャ以外ありえないと思うけど。

##### 設問3(1)　下線④について、H課長が工事スケジュール管理機能以外にソフトウェアパッケージが備えるべきと考えた、G社プロジェクトの要求事項を満たす機能とは何か(35字以内)
|下線④ G社プロジェクトの要求事項を満たす機能 |
|:--|

:pencil2:私の解答　サーバ上のデータを分析して工事進捗レポートを作成する機能(28)

:thought_balloon:ふりかえり
自信度　B
IaaS上のサーバの　と書いたかも。しかもIaaSで2マスにしてしまったかも。
"工事進捗レポート"と書かずに"レポート"と書いてしまったかも。

##### 設問3(2)　下線⑤について、H課長が、G社の競争力強化の方向性から、G社で内製化する必要はないと判断した理由は何か(30字以内)
|下線⑤ G社の競争力強化の方向性から判断して、ドローンなどの新技術への対応をG社で内製化する必要はないと考え |
|:--|

:pencil2:私の解答　技術習得しても工事遂行力の更なる強化にはならないから(26)

##### 設問3(3)　下線⑥について、H課長が新技術への対応に対する別の観点のリスクを回避したいと考え、事前にX国の関係機関に確認したことは何か(30字以内)
|下線⑥ 新技術への対応に対する別の観点のリスクを回避するために |
|:--|

:pencil2:私の解答　個人情報保護法等の法規制に違反することはないか
(23)

##### 設問4　H課長が本文中の下線⑦で考えた従来のシステム開発プロジェクトと比較して、IoTを活用したシステム開発プロジェクトのマネジメントを難しくする特性とは何か(35字以内)
|下線⑦ IoTを活用したシステム開発プロジェクトの場合、従来のシステム開発プロジェクトと比較して、マネジメントを難しくする特性があると考えた |
|:--|

:pencil2:私の解答　調整が必要となるステークホルダが幅広く多岐に渡ること(26)

問1は [こちら](https://qiita.com/putti/items/3091634ef44c73f2f1cb)

[^1]: やっぱりすぐにやらないと振り返れないですねー ><;
Kaggle Titanic　おすすめkernel


# おすすめkernel
## Titanic Data Science Solutions
https://www.kaggle.com/startupsci/titanic-data-science-solutions

- グラフによる可視化が多く行われている。
- 多くのモデルの実装例がある。

## A Data Science Framework: To Achieve 99% Accuracy
https://www.kaggle.com/ldfreeman3/a-data-science-framework-to-achieve-99-accuracy

- 3.22 Clearn Data の章でPandasでの前処理について紹介
- 5.11 Model Performance with Cross-Validation (CV)で交差検証について紹介

##Titanic: Guide with sklearn and EDA
https://www.kaggle.com/samsonqian/titanic-guide-with-sklearn-and-eda

- 正規化の例がある。
dockerで構築したFlaskアプリの開発環境にRedisを導入してみる

#はじめに

機械学習やら色々な新しい事を実践的に試すべく
エロサイトを開発中。[モトダチ](http://motodachi.me/)
開発実践用にオープンしているので広告は入っておりませんのでお気軽にどうぞ。
色々工夫したアプリケーションの作りになっているのでレスポンスは速いはず。

#概要
docker運用しているFlaskアプリケーションの開発環境にredisを組み込む

#作業
環境周りの作業は、docker-composeとconfig.pyの編集のみです。

```
#docker-composeに以下を追記
redis:
    image: redis:alpine
    ports:
      - "6379:6379"
    restart: unless-stopped
```


```
# config.pyに以下を追記
REDIS_HOST = 'redis'
REDIS_TIMEOUT = '60'
REDIS_PORT = '6379'
```

これで環境の設定をOK
これさえやってしまえば、あとはアプリ内で必要なライブラリを入れてしまえばOKです。
Flaskで必要なライブラリに関しては、[以前の記事](https://qiita.com/yamanaka1213/items/98339277cc26bad60173)を参照。

#基本コマンド
+ redisコンテナに入る。
`docker-compose exec redis /bin/sh`

+ redis-cli起動
`redis-cli`

+ keyに対応する値取得
`keys [hoge]`

+ キーと値の登録
`set key value`

+ 更新不可のキーと値の登録
`setnx key value`

+ 値の取得
`get key`

+ キーの有効期限を設定して登録
`setex key seconds value`
`psetex key milliseconds value`

+ 値の取得と更新
`getset key value`

+ 値の長さを取得する
`strlen key`

+ 一度に複数のキーと値を登録する
`mset key value [key value ...]`
`msetnx key value [key value ...]`

+ 一度に複数のキーの値を取得する
`mget key [key ...]`

#最後に
最初に挙げた[モトダチ](http://motodachi.me/)ではRedisを使っています。で構築してます。
Pythonのウェブアプリケーションは初めてでしたがサクサクと進める事ができました。

色々意見頂けると開発のモチベーションが上がります。
何かあればぜひコメント下さい。
jupyter notebookコマンドについて


# jupyter notebookとは何か？
<img width="1440" alt="スクリーンショット 2019-06-01 15.23.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275145/f58f94b0-28fa-a76a-36dd-5f2fe83ebd3d.png">

>Jupyter Notebook (読み方は「ジュパイター・ノートブック」または「ジュピター・ノートブック」) とは、ノートブックと呼ばれる形式で作成したプログラムを実行し、実行結果を記録しながら、データの分析作業を進めるためのツールです。
プログラムとその実行結果やその際のメモを簡単に作成、確認することができるため、自分自身の過去の作業内容の振り返りや、チームメンバーへ作業結果を共有する際に便利なほか、スクール形式での授業や研修などでの利用にも向いています。

[Jupyter Notebook を使ってみよう – Python でデータサイエンス](https://pythondatascience.plavox.info/python%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83/jupyter-notebook%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86)

私はもともとanacondaをダウンロードしてjupyter notebookをインストールした。そのため、jupyter notebookを使う時には、anacondaを起動し、anacondaの機能の1つであるjupyter notebookを起動する、という手順でやっていた。

jupyter notebookを起動すると自動的にsafari上で上の画面になっていたのだが、諸事情から、chromeからjupyter notebookを使わなければならなくなった。

`jupyter notebook --generate- config`というコマンドを使えば、ブラウザを設定できるらしい。

しかし、これを打ったところ、`command not found` とでる。

そもそも、anacondaでダウンロードしたjupyterはターミナル上ではコマンドを打てないのか？

`pip install jupyter`で再びダウンロードすることで`jupyter notebook --generate- config`
に成功。

```
c.NotebookApp.browser = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome %s'
```

.jupyterディレクトリ内の設定ファイルで上のように書き込み。

jupyter起動時にchromeを開くことに成功した。
Laravel+SPA+JTWAuthで認証ありの投稿アプリをつくる ~パート1~

# はじめに
サーバーサイドの処理はLaravelでクライアントサイドはSPAで認証、新規会員登録、記事の投稿を一括で作成しましたので、自分用のメモ含め紹介いたします。

# 前提
Laravel5.5
Vagrant環境
認証はJTWAuth使用
SPAはVue、Vue Router

# 今回作るもの
Laravel+SPAでログイン認証画面と記事投稿アプリを各単体で実装。
基本は別の方があげていただいているドキュメントが良くできているので
そちらを読み進めて行ってください。
[一部変更]の箇所に変更点をまとめています。

完全コピペでつくれるチートシート版も作成しました。
https://qiita.com/ProgramingDai/items/0cbd704d51a7353c4681

# 手順レシピ
1.JTWAuthでログインのSPAを作成
Laravel + JWTAuth + Vue.js でAPIログイン認証の実装
https://www.webopixel.net/php/1444.html

[一部変更]
①「resources/js/components/App.vue」の
「`<router-view></router-view>`」を
「resources/views/app.blade.php」に移動
②Home.vueのコンポーネントが設定されていますが
コンポーネントファイルを生成する指示がないので、適当に作成しておく。
※しないとコンパイルエラー出ます

2.記事のSPAを作成
Laravel5.6とVue.jsで簡単なシングルページアプリケーション
https://qiita.com/shin1kt/items/8c98fb209de5caa9076d

[一部変更]
①Userテーブルと関連づけたいので１カラム追加

```php:database/migrations/****_**_**_******_create_topics_table.php
public function up()
{
    Schema::create('topics', function (Blueprint $table) {
        $table->increments('id');

        // 外部キーカラム追加
        $table->text('user_id');

        $table->text('title');
        $table->text('content');
        $table->timestamps();
    });
}
```
これ以降の外部キー（user_id）に関する部分はパート2で編集しますのでマイグレーションのみ追加してください。ただし、外部キー以外のカラムにおいて追加・変更した際は、その都度、読み替えて作成してください。

②npm installとnpm install vue-router、bladeの作成、Laravel側のルーティングは「1.JTWAuthでログインのSPAを作成」でおこっなっているのでしなくて良い（名称もJTWAuthドキュメントに合わす）。

③app.blade.phpに「`<navbar></navbar>`」は追加
記事のページを表示させる部分
app.jsにも追加


```js:resources/assets/js/app.js
Vue.component('navbar', require('./components/Navbar.vue'));
```

④「2.記事のSPAを作成」ドキュメントではapp.jsに集約されているが、
「router.js」をすでに作っている思いますので、`const router = new VueRouter`部分はそちらに書く

```js:resources/assets/js/router.js
// 中略
import List from './components/pages/List'
import Form from './components/pages/Form'
import Detail from './components/pages/Detail'

//中略
const routes = [
    // 中略
    { path: '/list', component: List, meta: { requiresAuth: true }, name: 'list' },
    { path: '/create', component: Form, meta: { requiresAuth: true }, name: 'create' },
    { path: '/:id', component: Detail, meta: { requiresAuth: true }, name: 'detail' },
];
```

⑤componentの階層注意
components/pages/〜内に設定されているのでこちらに各コンポーネント配置

⑥標準のルーティングコメントアウト

```php:routes/web.php
// Route::get('/', function () {
//     return view('welcome');
// });

// Auth::routes();
```

ここまでで、ログイン認証と記事投稿のベースデータが完成できたかと思います。ここで記事を投稿しようとしてもuser_idをpostしていないので投稿できません。
次回は、認証ユーザーで記事投稿できるようにしたいと思います。

# 補足
js側を変更した場合は
`npm run dev`しないと更新されませんので、ご注意ください。
windowsでiverilog

# 概要

windowsでiverilogやってみた。
xor, and, orやってみた。

# xor

```
module test;
   reg a, b;
   wire c;
   integer i, j;
   xor(c, a, b);
   initial 
   begin
      $dumpfile("test.vcd");
      $display("a b c");
      $monitor("%b %b %b", a, b, c);
      for(i = 0; i < 2; i = i + 1) 
      begin
         for(j = 0; j < 2; j = j + 1) 
         begin
            a = i;
            b = j;
            #1;
         end
      end
      $finish;
   end
endmodule
```

```
vvp a.out
a b c
0 0 0
0 1 1
1 0 1
1 1 0
```

# and

```
module test;
   reg a, b;
   wire c;
   integer i, j;
   and(c, a, b);
   initial 
   begin
      $dumpfile("test.vcd");
      $display("a b c");
      $monitor("%b %b %b", a, b, c);
      for(i = 0; i < 2; i = i + 1) 
      begin
         for(j = 0; j < 2; j = j + 1) 
         begin
            a = i;
            b = j;
            #1;
         end
      end
      $finish;
   end
endmodule
```

```
vvp a.out
a b c
0 0 0
0 1 0
1 0 0
1 1 1
```

# or

```
module test;
   reg a, b;
   wire c;
   integer i, j;
   or(c, a, b);
   initial 
   begin
      $dumpfile("test.vcd");
      $display("a b c");
      $monitor("%b %b %b", a, b, c);
      for(i = 0; i < 2; i = i + 1) 
      begin
         for(j = 0; j < 2; j = j + 1) 
         begin
            a = i;
            b = j;
            #1;
         end
      end
      $finish;
   end
endmodule
```

```
vvp a.out
a b c
0 0 0
0 1 1
1 0 1
1 1 1
```

以上。
任意のTraceIdをログに埋め込みたい

# この記事の概要
- バッチ処理で、並列処理や連続で処理を行った時にどこからどこまでが同じ処理のログなのかすぐ検索したい
- @Slf4jを使う前提で記述します

# 早速実装方法
- Javaクラスでは、MDCを使用してログに出力したい情報を登録（MDC.put）
    - 最後はremoveでキーを削除しておく
- logback.xmlでMDCで登録したキーを`%X{＜キー＞}`の形式で取得できる

```xml:logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE logback>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>traceID: [%X{traceId}] message: %msg%n</pattern>
        </encoder>
    </appender>

    <root>
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
```

```java
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;

@Slf4j
public class Traceid {
    public static void main(String[] args) {
        log.info("dummy1");

        String uuid = UUID.randomUUID().toString();
        MDC.put("traceId", uuid.substring(0, uuid.indexOf("-")));
        log.info("dummy2");
        MDC.remove("traceId");

        log.info("dummy3");
    }
}
```


```text:コンソールログ
traceID: [] message: dummy1
traceID: [4f9c9243] message: dummy2
traceID: [] message: dummy3
```

# その他
MDC.putがstaticメソッドなので、複数スレッドで使用する時に同じ値を使ってしまうのでは？
→MDCがキーを保管するMapをThreadLocalで保管しているため、スレッド間で同じ値を使ってしまう心配はなし！
pythonの画像処理ライブラリpillowでgifアニメを作成する


# 環境
- Windows10 Pro
- Python 3.6.4 :: Anaconda 
- numpy 1.14.0
- pillow 6.0.0

# 概要
### フェルマーらせん

```math
r=a*sqrt(\theta)
```

aを変えてアニメーションさせてみます

# コード

```python:spiral.py
import numpy as np
import random
import colorsys
from PIL import Image, ImageDraw

#フェルマーらせんを描く関数
def radF(a, t):
    return a * np.sqrt(t)

images = []

#aを変化させてgifアニメ作成
for a in range(60, 20, -2):
    im = Image.new('RGB', (size, size), (0, 0, 0))
    draw = ImageDraw.Draw(im)
    theta = 0
    step = 2 * np.pi * 0.0001
    size = 400
    offset = size/2
    i = 0

    while i < 100000:
        i += 1
        #HSVのHのみ、iとaに応じて変化させる
        color=colorsys.hsv_to_rgb((i/2000+a/50),0.5,0.9)
        draw.line((radF(a,theta) * np.cos(theta) + offset, radF(a,theta) * np.sin(theta) + offset, radF(a,(theta + step)) * np.cos(theta + step) + offset, radF(a,(theta + step)) * np.sin(theta + step) + offset), fill=(int(color[0]*255),int(color[1]*255),int(color[2]*255)), width=2)    
        theta += step

    images.append(im)

for im in reversed(images):
    images.append(im)
    
images[0].save('./spiral.gif', save_all=True, append_images=images[1:], optimize=False, duration=45, loop=0)
```

# 出力
![spiral.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244405/8a8f14f5-37b8-4397-097c-cbea7ad2c4bf.gif)

# bibriography
- Pillow documentation
 - https://pillow.readthedocs.io/en/stable/
- Qiitaの数式チートシート
 - https://qiita.com/PlanetMeron/items/63ac58898541cbe81ada
Python モジュールを使う

# 目的
　Pythonの基本文法を得ること(初心者向け)

# 内容
　モジュールの概要を学ぶ。

# モジュールとは
　Pythonは、関数のような機能をまとめ、必要な時に読み込んで使える
**モジュール**という仕組みを持っています。簡単に言えば、機能追加のことです。

# モジュールをインポートする

```
import モジュール名
```
試しに、Pythonの標準ライブラリに搭載されている**モジュール**を使ってみましょう。乱数に関連する処理を集めた**random**というモジュールを使ってみます。

```python:random_list.py
import random

a_list = [1, 2, 3, 4, 5, 6]

# リストをランダムに入れ替える
random.shuffle(a_list)
print(a_list)

# リストの要素を1つランダムに選ぶ
print(random.choice(a_list))
```

結果は、randomモジュールを使って(正確にはrandomモジュールのshuffle関数で)リストをランダムに入れ替えた戻り値が返ってきました。

```
# ランダムに入れ替えた結果 
[3, 1, 6, 5, 2, 4]
# リストの要素を1つランダムに選んだ結果
6
```

上記のプログラムのように、インポートした**モジュールの関数**を
```random.shuffle()```などのように呼び出しています。
モジュールと関数のように、何かの区切りにドットを使うのもPythonの流儀です。

# import文のfrom
```
from モジュール名 import 関数名など
```
**from**というキーワードを組み合わせると、モジュールにある関数などを直接インポートすることができます。せっかくなので先ほどのプログラムで使ってみましょう。

```python:random_list.py
from random import shuffle, choice

a_list = [1, 2, 3, 4, 5, 6]
shuffle(a_list)
print(a_list)
print(choice(a_list))
```
　気づきましたか？
そう！実行時に**モジュール名を書く必要がなくなる**のです。
またimportでモジュールを読み込むということは、そのモジュールに含まれているプログラムでは使わない関数もいくつか読み込んでしまっているということです。
不必要なものは余分にインポートしないのは、今後プログラマとしては大切なので習慣をつけましょう。プログラム完成時に**from**に変えられるなら変えましょう。


# import文のas
- 
```
import モジュール名 as 読み込む名前
```

長い名前のモジュールをインポートするときに一時的に名前を変更します。
```matplotlib.pyplot```をインポートするときasを使ってpltに変更するというのは、
言ってみれば慣例です。人にコードを見せることを考えて使う用途を決めましょう。

# モジュールの探し方
次のサイトにまとまっています。検索機能もあり便利です。
[https://docs.python.org/ja/3/](https://docs.python.org/ja/3/)
AWS S3 (Simple Storage Service)とは？②


更新版を個人ブログに掲載しています。

- https://in-thepink.com/s3/

# 概要

AWS S3のデータの暗号化・データの整合性・バージョニング機能についてまとめました。

本記事は[前回](https://qiita.com/reoisym/items/226b3e728648155b19de)の続きです。


##S3の暗号化  
S3にはサーバーサイド暗号化とクライアントサイド暗号化の2の形式があります。

### クライアントサイド暗号化
AWS SDKを使用してデータをS3に送信する前にデータの暗号化を行います。
復号時には暗号化されたデータのメタデータから、データを復号させるためのキーの判別を行います。

### サーバーサイド暗号化

データがストレージに書き込まれる時に暗号化を行い、読み出されるときに復号化を行います。
S3で鍵の生成・暗号化・復号化を行います。

### どう違うの？

クライアントサイドとサーバーサイドで暗号化する違いは、ユーザー側で暗号化を行うかAWS側で暗号化を行うかが大きな違いとなります。

クライアントサイドで暗号化を行った場合、鍵の管理や手間が少しかかる分、セキュアにデータを扱うことができます。
サーバーサイドで暗号化を行った場合はAWS側に管理・作成・復号を任せることができるため、手間がかかりません。




## データの整合性

S3のデータは結果整合性モデルを採用しています。
S3は高可用性を実現するためにデータを複数の場所に保存されており、これらのデータを**更新・削除**した時に順次、データが更新されていきます。
そして「**最終的に**コピーされたデータが更新されればいい」と言った考え方が結果整合性モデルです。

データの新規登録を行った場合は**即時に反映**されますが、更新削除を行った場合については新規登録時に比べて、反映までに時間がかかります。

## バージョン管理機能

**バケットに対して**バージョン管理機能を有効にすることで、Gitのバージョン管理機能と同じく、意図しない操作で削除をしてしまった場合、データを復元できるといったことができます。
ライフサイクル機能と合わせてバージョン管理されているデータの保存期間を指定することができます。
バージョン管理されているオブジェクト分も追加で課金されます。

### 参考
- [これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（初心者向け20時間完全コース）](https://www.udemy.com/aws-associate/)
-  [Amazon S3 の結果整合性と読み取り一貫性](https://dev.classmethod.jp/cloud/amazon-s3-eventually-consistent-and-consistent-read/)
- [【AWS Black Belt Online Seminar】Amazon S3/Glacier](https://www.youtube.com/watch?v=oFG5kMZjKtc)
vertical-alignの役割

#vertical-alignの役割
ブロック要素を縦方向中央に配置させるために、vertical-alignを用いたが失敗した。どうやらvertical-alignはブロック要素に適用できないとのこと。そこでvertical-alignの役割について疑問に思い調べたのでメモとして残しておく。
[こちらのサイト](https://haniwaman.com/vertical-align/)を参考にした。

####html
~~~html
<div class="outer">
    <div class="inner">center</div>
</div>
~~~

####CSS
~~~css
.outer {
    width: 100px;
    height: 100px;
}

.inner {
    vertical-align: middle;
}
~~~

div.innerにvertical-alignを適用しても中央に配置されない。では、以下のようにインライン要素にしたら、、、

~~~css
.inner {
    display: inline;
    vertical-align: middle;
}
~~~

これも配置されない。インライン要素になら適用できるんじゃないの？？？と疑問に思い、さらに調べたところ解決した。
vertical-alignはボックス内の位置を決めるプロパティではなく、同じブロック内のインライン要素どうしの位置関係を決めるものらしい。
LINE WORKS のトーク BOT を利用したワークフローで外部連携有効化を自動化

##LINE WORKS のトーク BOT を利用したワークフロー

LINE WORKS Bot との対話で、利用者からの LINE 連携有効化の申請を受けて、管理者が審査の上で有効化を実行するしくみを作成してみました。

申請ベースで利用許可を付与するような場合に、その都度に管理画面にアクセスする必要なく、チャットボットとのやり取りで申請から権限付与まで行うことができます。

##LINE WORKS 上でのながれ
1.利用者が LINE 連携申請用 BOT から連携の申請を行う。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/345e55fa-594b-5bae-48fe-4e13834b51cc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/cdc82d3b-3c8e-49af-d4f0-ea139a642995.png)

2.管理者に連携申請の可否の確認のメッセージが届く。管理者は申請に対する可否の応答をする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/6d727afc-96d7-ad1a-2773-6fa89e92f4b4.png)

3.応答に応じて連携の有効化が行われる。
4.有効化が完了すると利用者に通知が届く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/da7e540d-c6c7-b32e-5a6a-5bbaf317e6c1.png)

##Microsoft Flow
一連の処理は Microsoft Flow で行っています。
###LINE 連携申請受付用 BOT のフロー
BOT の利用開始時に送られる postback の "start" をトリガーに、ボタン テンプレート形式で利用開始申請の意思確認のメッセージを送っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/d9367f3b-029c-9b22-15ae-564c686f5e0b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/d79440cb-118b-23bd-d2fc-f49c881dd97e.png)

ボタンテンプレート メッセージの JSON ペイロードは次のようにしています。

```
{
    "botNo": $botNo,
    "accountId": "$accountid",
    "content": {
    "type": "buttonTemplate",
    "contentText": "$contentText",
    "buttons": [{
      "text": "はい",
      "postback": "ButtonTemplate_Yes"
        }, {
      "text": "いいえ",
      "postback": "ButtonTemplate_No"
    }]
    }
}
```

このメッセージに「はい」を返すことで postback の "ButtonTemplate_Yes" を受けて、管理者宛に以下のボタン テンプレートを含むメッセージが送られます。

```
{
    "botNo": $botNo,
    "accountId": "$accountid",
    "content": {
    "type": "buttonTemplate",
    "contentText": "$contentText",
    "buttons": [{
      "text": "LINE連携を承認します",
      "postback": "$userid"
        }, {
      "text": "却下します",
      "postback": "ButtonTemplate_No"
    }]
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/c8404b31-6e3a-cc53-1b00-73052640f5b3.png)


###管理者による確認用 BOT のフロー
管理者が承認のボタンをタップすることで、次のフローの処理に移ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/92ef85e7-c700-8da6-da51-45743580b3c7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/dea850f8-6a83-44b7-cf7e-cb0c95d9121f.png)

LINE WORKS 外部連携を有効化 API を実行する AzureAutomation のジョブにより有効化処理を行います。

有効化 API については、こちらを参照。

TITLE: API で LINE WORKS の外部トーク連携を有効化する
URL: https://qiita.com/iwaohig/items/715c86ba8b0c216c0b3a
Enterキーでonclickと同じ動作を行う。

HTMLのformのテキスト(`<input type="text">`)などは入力し、エンターを押したとき、submitが押されたのと同じ状態になり、ページがリロードされてしまいます。そこでエンターを押したときにbuttonのonclickを押したときと同じ状態にできるようにする方法をメモします。

``` html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Sample</title>
    <script>
        function abc(){
            document.getElementById("a").textContent = "あ";
            return false;
        }
    </script>
</head>
<body>
    <form onsubmit="return abc()">
        <input type="text">
    </form>
    <div id="a"></div>
</body>
</html>
```

form要素の開始タグに「onsubmit="return abc()"」のようにイベントハンドラを追加し、関数abc()にreturn falseを指定することでフォームが送信されず、ページが再読み込みされなくなります。よって「あ」という文字をdiv要素に書き込めます。

このページを参考にしました。
https://www.tagindex.com/javascript/form/submit.html
UiPathについての雑多なメモ

参考情報や、1つの記事にするまでもなさそうな情報のまとめ。

# 画面からテキストを取得する
[出力メソッドまたは画面スクレイピングメソッド](https://docs.uipath.com/studio/lang-ja/docs/output-or-screen-scraping-methods)

Get Full Text と Get Visible Text のどちらか、目的に適しているか調べながら利用する感じ。

# UiPathとATOK
相性が悪い。
IMEをATOKにしてUiPath Studioで日本語入力していると、強制終了することが多々ある。
Microsoft IMEではほとんどこの現象は起こらない。そのため、UiPath使用中はMSIMEへ切り替える方が良い。
そのほか相性の悪い環境やソフトウェアはいくつかあるらしい。

# OrchestratorをAzure上に構築
https://www.uipath.com/ja/company/info/2019-04-15
Azureを利用しているなら、サーバーを立てて構築するよりは手軽そう。

# Azure DevOpsで自動デプロイ
Azure DevOpsにUiPath用のインテグレーション機能が追加されていた。
https://marketplace.visualstudio.com/items?itemName=uipath.vsts-uipath-package
 
デプロイ先はOrchestratorのみらしいので、Orchestratorを導入した後ならとても便利になりそう。

# UiPath 製品版インストール
Robotのみをインストールした場合、ライセンス認証はコマンドラインで実行する。
手順：[Regutil を使ったコマンド記述](https://robot.uipath.com/lang-ja/docs/regutil-command-descriptions)

# Attended Robot導入構成について考えたこと
Attended Robot1台あたりの年間ライセンス料：約25万円(2019/6月時点)
Robot用共有PCを用意し、リモート接続なり、実物のところへ行くなりで運用してもらうのがひとまず思い浮かぶ案。
メリット：ライセンス料節約。
デメリット：共有PCへのアクセスがひと手間かかるので、そこで工数が増えるんじゃないか疑惑がある。

これに対し、個人PCへRobotをインストールしてしまう案もある。
UiPath社は1人1台でRPAを使うことを理想としているっぽいので、それに沿う案でもある。
メリット：
・自PCで動かせるので、起動までの手間が少ない。
デメリット：
・お金がかかる。
・ロボットが少ないうちは、稼働率が低くて無駄に感じそう。

25万円/年 → 約20,833円/月 → 時給2,000円として約10時間分。
月10時間以上の削減効果を生み出せるならOK？ 効果は時間だけではないが。

# ロボット稼働率取得(Attended Robotで)

ロボット稼働率取得
https://qiita.com/UmegayaRollcake/items/2dfd681a84e1c0cfce4d
PowerBIでJson
https://qiita.com/usomaru/items/cdafbe0b45c98c7aa059
 
PowerBIでjsonを読み込める。ただし連続データは配列になっている必要がある。
(UiPathのログはJSONが並んでいるだけで、配列にはなっていない。

PowerShellでログ取得＆Json配列へ変換。
ファイルサーバーにログファイルをコピー。
　日付ごとにすれば、既存有無の判断もできる。
 
稼働率＝実働時間(拘束時間ー休憩時間)÷拘束時間
 
ログファイル収集と変換のツール：logstash
https://www.slideshare.net/miyaichi/lightning-talk-rpalt-713
ReFrameworkに関する資料だが、最後の方にログについて載っている。
 
# AIで画面認識(Computer Vision)

2019年2月時点でパブリックベータが公開。
https://www.uipath.com/newsroom/introducing-new-uipath-ai-computer-vision
https://activities.uipath.com/docs/about-the-ai-computer-vision-activities-pack
 
まだ万能とは行かなさそうだが、リモート接続での操作が捗るかもしれない。
 
# カスタム入力アクティビティ

入力画面用HTMLを置く場所のパスに日本語が含まれていると、HTMLファイルが見つからないと言われてエラーになる。
(UiPathの不具合？)
(2018/11時点)

# 参考になりそうな記事
 
とある企業のUiPath豆知識が載ったブログ
https://www.cresco.co.jp/blog/entry/category/rpa/
 
【UiPath】オートメーション作成10箇条
https://qiita.com/UmegayaRollcake/items/7803726e7ddd542b2770
開発標準の参考になりそう。
 
【UiPath】ログイン情報（ユーザーID/パスワード）の持たせ方
https://qiita.com/UmegayaRollcake/items/f2d423c5055f6cbc2c48
ReFrameworkでもこの方法をとっている。

UiPathのコードの品質を上げる – Yoshihiko Miyaichi – Medium
https://medium.com/@miyaichi/uipath%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%93%81%E8%B3%AA%E3%82%92%E4%B8%8A%E3%81%92%E3%82%8B-3bdcc408bb47

RPAガバナンス構築のためのガイドラインおよびRPAガバナンスハンドブック | PwC Japanグループ
https://www.pwc.com/jp/rpa-guideline.html

 
# UiPath 技術サポート Twitterアカウント

Q&Aまとめ
https://togetter.com/li/1332101
Kaggle : Sberbank Russian Housing Marketについて (ロシアの不安定な経済における不動産価格の変動を予測できますか?)

Sberbank Russian Housing Market
Can you predict realty price fluctuations in Russia’s volatile economy?
(ロシアの不安定な経済における不動産価格の変動を予測できますか?)
についてです。

https://www.kaggle.com/c/sberbank-russian-housing-market/overview

# Overviewの訳(Google翻訳を少し修正)

住宅費は、消費者と開発者の両方から多大な投資を要求します。 個人予算でも企業予算でも、予算の計画に関して、だれかもが必要とする最後のことは、予算のうちの1つについての不確実性です。 ロシアで最も古く最大の銀行であるSberbankは、不動産価格について予測することで顧客を支援しています。それにより賃貸人、開発者、および貸し手は、リースに署名するときや建物を購入するときに自信を持てるようになります。

ロシアでは住宅市場が比較的安定していますが、不安定な経済のため、アパートの特性に応じて価格を予測することは非常に困難です。 寝室の数や場所などの住宅の特徴間の複雑な相互作用は、価格予測を複雑にします。 不安定な経済をミックスに追加することは、Sberbankとその顧客が彼らの備品に単純な回帰モデル以上のものを必要とすることを意味します。

このコンペでは、Sberbankは不動産価格を予測するために広範囲の特徴を使用するアルゴリズムを開発することをKagglersに挑戦しています。 参加者は住宅データとマクロ経済パターンを含む豊富なデータセットに頼るでしょう。 正確な予測モデルにより、Sberbankは不確実な経済の中で顧客により確実に対応することができます。

# Evaluation
「price_doc」がターゲット

- RMSLE 
対数をとって誤差を２乗したもの

いまさら聞けない機械学習の評価関数
https://data.gunosy.io/entry/2016/08/05/115345

RMSLE (Root Mean Squared Logarithmic Error)
例えば、売り上げが100円の商品を10,000円と予測した場合の差が小さく評価されます。 個人の資産の額などの桁が大きくなり対数正規分布に近い分布において有用です。

# DATA
トレーニングデータは2011年8月から2015年6月まで、テストセットは2015年7月から2016年5月までです。

データセットには、ロシアの経済および金融部門の全体的な状況に関する情報も含まれているため、景気循環がどうなるかを推測することなく、個々の物件の正確な価格予測を作成することに集中できます。

# kernels
## 「simple-exploration-notebook-sberbank」
EDAを行っているkernel
・価格(price)のlogを取ると分布が正規分布に近くなる。
・価格の中央値(median)が年数につれて増加傾向。
・xgboostで特徴量の重要度(feature importance)を出すと、以下の重要度となった。
　1.占有面積(バルコニー等含む) 
　2.占有面積(バルコニー等除く) 
　3.階 
　4.建物の高さ 
　5.築年数
　「2.占有面積(バルコニー等除く) 」については0に近くても価格が高いことがある。

## feature-engineering-validation-strategy
特徴量を追加した後で重要度順に並べている。
(関係のない特徴量は除いた方がモデルの精度が良くなることを解説してくれている。)



## lgbm-lb-0-3093-0-3094
LightGBMですべての変数をトレーニングしている。

## Basic Time Series Analysis & Feature Selection

・日付の文字列をstrptime()でdate型にしてxgboostのモデルにいれている。(文字列から日付、時間への変換)
・feature importanceで重要度
・欠損の多いカラムは使っていない。
漠然と理解している機能一覧 復習しよう！

##① コントローラ名は モデルの複数形
##②　form_with
##③　model
##④  local true
 コラム：local: trueについて
local: true を抜かした場合、画面遷移しない通信（非同期通信）が発生します。form_with ではデフォルトで、画面遷移を伴わない非同期通信にてフォームデータを送信するようになりました。主に外部サイトへの通信で効果を発揮しますが、今回はサイト内での遷移であること、ならびに画面遷移を伴う同期通信のみで構わないため local: true をつけています。
##⑤　link_to
   Rails が提供する便利メソッドで、 link_to 表示文字列, リンク先 という形で記述する。 
##⑥　path
##⑦  <%= yield %> があるところ（つまりbody要素内）に index.html.erb や show.html.erb などの各ページの内容が代入されると考えてください。
##⑧  private
それ以降に定義されたメソッドがアクションではなく、このクラス内のみで使用することを明示する。
##⑨  redirect_to 
リンク先を指定して強制的に飛ばすメソッド  
##⑩  redirect_to と render の違い
redirect_to @message は、 処理を messages#show のアクションへと強制的に移動させるもので、create アクション実行後に更に show アクションが実行され、show.html.erb が呼ばれます。render :new は、単に messages/new.html.erb を表示するだけです（messages#newのアクションは実行しない）。
##⑩  before_action 
アクションが実行される前に、前もって実行すべきメソッドを指定。
Python 関数とはなにか

# 目的
Pythonの基本文法を得ること(初心者向け)

# 内容
関数の概要を学ぶ。

# 関数とは
- **関数**を簡単に説明すると、**入力に対して出力を返す仕組み**のことです。
- **特定の目的を実現するための機能を提供する仕組み**のことを**関数**と言い換えることもできます。

# 関数の利便性
　例えば、数値のリストの合計を計算したいとします。
変数と、for文を組み合わせた簡単なプログラムが以下となります。

```python:sum_list.py
the_list = [100, 200, 300, 400]
summary = 0
for item in the_list:
  summary = summary + item
  
summary
```
　実行結果は以下のようになりました。正しいですね。

```
1000
```

　数値の合計を計算するたびに、このようなコードを書いていては面倒です。

　そこで本記事のメイン(**関数**)を使う方法で見通しの良いプログラムを以下に作成します。

```python:sum_list.py
the_list = [100, 200, 300, 400]
sum(the_list)
```
　なんと**関数**を使うとこれだけです。実行した結果も同じく正しいですね。

```
1000
```

　今回は、Pythonに用意されている**組み込み関数**の```sum()```を使いました。
Pythonには、```sum()```のような関数がたくさん装備されているので活用しましょう。

# 関数を呼び出す
　Pythonで関数を呼び出すときには、関数名に添えて**丸括弧()**を使います。

```
関数名(引数1, 引数2, ...)
```

　例として、組み込み関数```abs()```を呼び出してみましょう。
```abs()```は、絶対値を求めるのに利用する関数です。

```python:abs.py
abs(-500)
```

結果は、以下のように正の数値に変換した結果が返ってきてます。

```
500
```

# 関数の補足
- **引数**
関数を呼び出すとき、丸括弧の中に数値や文字列のようなデータを入れます。
丸括弧の中に入れるデータのことを**引数(ひきすう)**と呼びます。
どのような種類のデータを**引数**として渡すかは、関数ごとに決まっています。
また、いくつの関数を渡すかも、関数によって決まっています。関数によっては、引数を渡す必要のないものもあります。

- **戻り値**
関数が処理をした結果、関数から出力されるデータのことを**戻り値**と呼びます。
どんな種類のデータが返ってくるかは、関数ごとに決まっています。

- **関数を定義する**
Pythonをはじめとするプログラミング言語では、自分の関数を作ることができます。
自分の関数を作ることを**関数を定義する**と言います。
Pythonで関数を定義するには**def文**を使います。ぜひ試してください。
「かめはめ波」を支える技術

ディープラーニングを使って「かめはめ波」を打ってみました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">かめはめ波、打ち放題です。<br>【ディープラーニング×OpenCV×ラズパイ】 <a href="https://t.co/FqpszBBF5C">pic.twitter.com/FqpszBBF5C</a></p>&mdash; shinmura0 (@shinmura0) <a href="https://twitter.com/shinmura0/status/1135050040685125632?ref_src=twsrc%5Etfw">2019年6月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

※こちらは[ディープラーニングガジェット品評会](https://connpass.com/event/129065/)の発表資料です。

#使った技術
今回は自分の持っている技術を総動員しました。

+ [弱異常検知](https://qiita.com/shinmura0/items/1af83f5a5857d50cabc2)(MobileNetV2で実行)
+ [OpenVINO](https://qiita.com/shinmura0/items/07d976fc13ce774036b8)(ラズパイで実行)
+ [PCACA](https://qiita.com/koshian2/items/78de8ccd09dd2998ddfc)(データ水増し)
+ [OpenCV](https://qiita.com/shinmura0/items/1f82e28ed2967bc8d0bf)(物体検出で使用)

#環境
+ Raspberry Pi 3 model B
+ NCS2
+ USB camera

#処理の流れ
+ OpenCVで物体検出
+ 検出した物体が正常かどうか判定（手の形）
+ 正常であれば、かめはめ波を打つ。
+ 異常であれば、かめはめ波は打たない。

詳しくは品評会で発表します。興味のある方は是非ご参加ください。
コードの公開は、品評会の反応を見て決めたいと思います。
不要なログファイルのサイズを0にする方法

**サーバーの容量が100%になってしまい、ログファイルを削除したときのメモ**

#容量確認コマンド
```
$ du -sh /path/to/application_file/current/log/*
```

#空にするコマンド
```
: > /path/to/application_file/current/log/file_name.log
```
【初心者】引数の使い方

<h1>結論</h1>
引数とはメソッド内で外部の値を使用したいときに使うもの

<h1>説明</h1>

メソッドを使用したときに”ねこ”と表示させたい。

```ruby:hikisuu.rb
def kansuu()
  puts #”ねこ”と表示したい
end
 
#実行
kansuu()
```

下記のようにメソッド内に値をそのまま入れてしまうと汎用性に欠ける

```ruby:hikisuu2.rb
def kansuu()
  puts "ねこ"
end
 
#実行
kansuu()
```

変数を定義して使用してみる

```ruby:hikisuu3.rb
def kansuu()
  puts hikisuu
end

hikisuu = "ねこ"
 
#実行
kansuu()

#これだとエラーがでる
```

結論でも述べたとおり、外部の値を使う時に引数を入れる

```ruby:hikisuu4.rb
def kansuu(hikisuu)
  puts hikisuu
end

hikisuu = "ねこ"
 
#実行
kansuu(hikisuu)

```

<h1>まとめ</h1>
引数を使うことによって汎用性が高く、外部の値を扱えるようになる。