OmniAICreator/Qiita-1.07M huggingface dataset:
Elasticsearch > Logstash > データ取り込み時にCSVファイルをLookup




[Translate filter plugin | Logstash Reference [7.9] | Elastic](https://www.elastic.co/guide/en/logstash/current/plugins-filters-translate.html#plugins-filters-translate-field)


```
    filter {
      translate {
        field => "[http_status]"
        destination => "[http_status_description]"
        dictionary => {
          "100" => "Continue"
          "101" => "Switching Protocols"
          "200" => "OK"
          "500" => "Server Error"
        }
        fallback => "I'm a teapot"
      }
    }
```


[Regression using filter with csv file AND a CSV filter in the same config. · Issue #70 · logstash-plugins/logstash-filter-translate](https://github.com/logstash-plugins/logstash-filter-translate/issues/70)


```
input {
  generator {
    lines => ['222101333', '123456789', 'abc103def', 'xyz301mno']
    count => 1
  }
}

filter {
  translate {
    field       => "[message]"
    destination => "[matched]"
    dictionary_path  => "/elastic/tmp/testing/confs/translate-drop.csv"
    exact       => true
    regex       => true
  }
  if [matched] == "drop" {
    drop {}
  }
}

output {
  stdout { codec => rubydebug {metadata => true} }
}
```
Effective Python 学習備忘録 1日目 【1/100】　

## はじめに
Twitterで一時期流行していた 100 Days Of Code なるものを先日知りました。本記事では、初学者である私がデータサイエンティストになるべく、100日の学習を通してどの程度成長できるか記録を残すために書いています。誤っている点、読みにくい点多々あると思います。ご指摘いただけると幸いです！


## 100日間の目標

下記の本、サイトを理解し、忘れてもすぐ思い出せるように記録を残すこと。

- [Effective Python] (https://www.amazon.co.jp/Effective-Python-%E2%80%95Python%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E6%94%B9%E8%89%AF%E3%81%99%E3%82%8B59%E9%A0%85%E7%9B%AE-Brett-Slatkin/dp/4873117569/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=Effective+python&qid=1609408832&sr=8-3)
    - コードが汚く、自身が書いたコードを理解するまでに時間がかかるという経験をよくする。また、来年から社会人として働くため、リーダブルなコードを書けるようにしておきたい。この本では、効率的で優れたプログラムを書くためのノウハウが詰まっており、Pythonの流儀を学べるとのこと。

- [独習Git] (https://www.amazon.co.jp/%E7%8B%AC%E7%BF%92Git-%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A6%E3%83%9E%E3%83%AA-ebook/dp/B01C2TRNUG/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=git&qid=1609408655&sr=8-2)
    - githubを使用する経験はあるが、使用するたびに調べては悩んでの繰り返しで効率わるし。しっかりと基礎を学んで、つっかえることなくgithubを使えるようになりたい。
- [プロゲート　SQL] (https://prog-8.com/languages/sql)
    - データベースの知識を身に着けたい。
- [Kaggleで勝つデータ分析の技術](https://www.amazon.co.jp/Kaggle%E3%81%A7%E5%8B%9D%E3%81%A4%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%81%AE%E6%8A%80%E8%A1%93-%E9%96%80%E8%84%87-%E5%A4%A7%E8%BC%94/dp/4297108437/ref=pd_sim_nf_14_5/355-4294260-1854710?_encoding=UTF8&pd_rd_i=4297108437&pd_rd_r=660f6277-37c6-4fb9-88ee-1e02dc59e867&pd_rd_w=ZTNKj&pd_rd_wg=dJ8VA&pf_rd_p=b0cf8133-9125-47c7-be1e-724ce72acb46&pf_rd_r=F0PEE33RRVJW2VR8GQE9&psc=1&refRID=F0PEE33RRVJW2VR8GQE9)
    - 以前流し読みしたので、今回はじっくり読んで理解を深めたい。
- [ゼロから作るDeep Learning3](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%95%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E7%B7%A8-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873119065/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2UKAG3IG3XXDK&dchild=1&keywords=%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8Bdeep+learning&qid=1609510258&s=books&sprefix=%E3%82%BC%E3%83%AD%E3%81%8B%2Cstripbooks%2C277&sr=1-3)
    - 以前ゼロから作るDeepLearning1 を読み非常に分かりやすかったため、続編であるこちらも読みたい。


## 今回学習する教材

- Effective Python
    - 8章構成
    - 本章216ページ

## 今日の進捗

- 進行状況：1-14ページ
- 本日学んだことの中で、よく忘れるところ、知らなかったところを書いていきます。

### 命名規則はPEP 8 スタイルガイドに従う

- PEP 8 とは Python コードをどのように書くべきかの明確な基準を定めるもの
- [オンラインガイド](https://www.python.org/dev/peps/pep-0008/)

#### 従うべきルールの一例

- 空白
  - 各行の長さ79文字以下
  - 長い式を次の行に続けるときは、通常のインデントに**4個の空白を追加**
  - ファイルでは、関数とクラスは、**2行の空白行で分ける**
  - クラスでは、メソッドは、空白行で分ける
- 名前付け
  - 関数、変数、属性は、lowwercase_underscore のように小文字で下線をはさむ
  - クラスと例外は、CapitalizedWord のように先頭を大文字にする
  - モジュールレベルの定数は、ALL_CAPS のようにすべて大文字で下線をはさむ

### スライスについて

代入するスライスの長さは同じでなくてもよい

``` slice
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print("Before ", a)
a[2:8] = [11, 12, 13]
print("After ", a)
```

実行結果

``` result
Before [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After [1, 2, 11, 12, 13, 9, 10]
```

文字列の反転

``` 文字列の反転
s = 'abcdefg'
reverse_s = s[::-1]
print(reverse_s)
```

実行結果

``` result
gfedcba
```

## おわりに

こちらの記事が初投稿となります。至らぬ点多々あると思いますが、当たって砕けろの精神で投稿していきます。
「おかしなりんご」ゲーム


<h1>1.はじめに</h1>
この記事のターゲットは<b>「HTML、CSS、JavaScriptを一通り学んだけど何をしたらいいかわからない人」</b>向けです。
この記事を見ることで以下の項目の悩みを解決できると思います。

<ul>
<li>プログラミング一通り経験したけど何をしたらいいのか</li>
<li>JavaScriptでできることは？</li>
<li>簡単なゲームを作りたい</li>
</ul>

<h1>2.作者紹介</h1>
プログラミングを初めて２ヶ月の<b>「大学３年生」</b>です。
スキルセットとしては以下のような感じです。
<ul>
<li>HTML&CSSがだいたい分かる</li>
<li>JavaScriptは少しわかる（機能を見てある程度推測できる）</li>
<li>ちょっとしたデータサイエンスに関する知識</li>
</ul>
最近は模写を中心に独学しています。

<h1>3.アプリ概要</h1>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> 　<br>【おかしなりんごゲーム】<br>新しくwebアプリを開発しました！<br>「飲み会などで罰ゲームを受ける人を決める時に使えます」 <a href="https://t.co/TC5QLnLPsF">pic.twitter.com/TC5QLnLPsF</a></p>&mdash; キタシン@✊フロントエンドを目指す体育会系✊ (@kitashinbloger) <a href="https://twitter.com/kitashinbloger/status/1345374048323211266?ref_src=twsrc%5Etfw">January 2, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<h2>使い方</h2>

<ul>
<li>1.HOW TOボタンを押して説明を読む</li>
<li>2.８個のりんごの中から好きなりんごをクリック</li>
<li>3.「おかしな」りんごが出るまで2を繰り返す</li>
</ul>

<h1>4.作成理由</h1>
結論からいうと<b>「居酒屋などのお会計を奢る人を楽しく決めたい」</b>と考えたからです。このアプリの作成者である私は友人とご飯に行く際にたまにご飯のお会計をかけてじゃんけんをしていました。しかし、ある時を堺に友人が「他の決め方はないかな」と違う手段で奢る人を決めたいという意向を示しました。そのときに私はその要望に答えるべくこのアプリを開発しました。

<h1>作成期間</h2>
2日間

<h1>5.設計</h1>
<b>
TODOアプリ（フォルダ）
├── index.html
├── style.css
├── script.js
</b>

<h1>6.使用技術</h1>
フロント：HTML、CSS、JavaScript
データベース：PostgreSQL
バージョン管理：Git hub
エディタ：VSCode

【ソースコード】
https://github.com/ShinKitayama/apple-game　

<h1>7.機能</h1>
1.モーダルの表示
2.addEventListenerを使った表示の切り替え
3.cssでの回転アニメーション

<h1>8.苦労した点</h1>
<ul>
<li>0からの創造</li>
<li>今までの学習してきたこと以外の要素の追加</li>
<li>予期せぬエラーへの対処</li>
</ul>
予期せぬエラー：addEventListenerが一個飛ばしの要素（りんご）にしか反応しない
→対応：document.createElementでdocumentにdivタグを追加し、そのタグにcssのクラスを設けて背景画像をcssで指定し、全て対応するようにした

<h1>9.反省点</h1>
<ul>
<li>一つのエラーに対処するのにすごく時間がかかった</li>
<font color="Blue">【解決策】1つの手段にこだわるのではなく、ニーズ（奢る人を楽しみながら決めたい）を満たす最適な手段を見つける</font>
<li>デザインに関しては全く気にしていなかった</li>
<font color="Blue">【解決策】機能面だけでなく事前にUI/UXを意識する</font>
</ul>

<h1>10.まとめ</h1>
改めて、本記事の冒頭で述べた以下3つの悩みに答えていきます。
<ul>
<li>プログラミング一通り経験したけど何をしたらいいのか</li>
<font color="Blue">→何かしらのアプリを作りましょう</font>
<li>JavaScriptでできることは？</li>
<font color="Blue">→今回のようにweb上で動きをつけることです</font>
<li>簡単なゲームを作りたい</li>
<font color="Blue">→addEventListenerを使用して今回のような「宝探し的なゲーム」を作りましょう</font>
</ul>

今回紹介した「おかしな」りんごゲームですが、実際に「アルバイト先」や「友人との食事」の際に使用しましたが、非常に満足してくれました。そして1人の友人からまた違った面白いアプリを開発をしてほしいと言われたのでいつかその要望に応えようと思います。

最後まで目を通していただきありがとうございました。
【PAY.JP】環境変数の設定について〜困ったときには削除の勇気〜

### 解決したいこと
クレジットカード決済の購入機能実装で、環境変数を設定するとtokenが発行されなくなってしまう。

### 発生している問題・エラー
```
 「　Token can't be blank　」と表示される
```


### 自分で試したこと

仮説1・そもそもトークンが生成されていない

トークンが生成されるまでの流れとしては、

**①ブラウザで入力したカード情報を取得する→
②取得したカード情報と公開鍵をもとにPAY.JP側（API）へアクセスする→
③PAY.JP側でトークンが発行される**

この中のどこかがうまくいっていないのではないか？

まずは①で、JavaScriptのファイルがきちんと読み込めているか確認。


```javascript


const pay = () => {
  console.log("OK")       //⬅️検証ツールでブラウザに「OK」と表示されるか確認

//以下略

```

確認できたので次はカード番号が取得できているか確認。


```javascript


const pay = ()=> {
  Payjp.setPublicKey("pk_test_XXXXXXXXXX");　// PAY.JPテスト公開鍵
  const form = document.getElementById("charge-form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();

    const formResult = document.getElementById("charge-form");
    const formData = new FormData(formResult);
    const card = {
      number: formData.get("number"),
      cvc: formData.get("cvc"),
      exp_month: formData.get("exp_month"),
      exp_year: `20${formData.get("exp_year")}`,
    };
    console.log(card);            //⬅️card情報がコンソールで表示されるか確認

//以下略

// document.getElementById("charge-form").submit();
//⬆️⬆️⬆️コンソールの出力が消えないようにするためコメントアウト
//これをしないとブラウザに一瞬だけ表示されて確認できないので注意。気付かずに3回ぐらいやってイライラした笑
    })
  })
}

window.addEventListener("load", pay);
```


これも問題なくきちんと取得できていた。
ということは環境変数か？ということでターミナルで確認。

```

% env | grep PAYJP
```

確認するときちんと入っている。うーん？
一度リセットしてみるか大作戦で環境変数を一度削除して、ターミナルも⌘Qで終了して再起動。
その後、再度環境変数を再設定して実行。


すると、成功。
原因は一体なんだったんだろう？
PAY.JPの公式HPからコピペして貼り付けたので間違っていたとは思えない。
ビビってなかなかできなかったですが、削除する勇気も大切ですね。
いい勉強になりました。
『OpenCVによる画像処理入門』練習問題4.1

[『OpenCVによる画像処理入門』](https://www.kspub.co.jp/book/detail/1538290.html)の練習問題4.1をやった。
正解かどうかは不明。

# 練習問題4.1
## 1
```1.pgm
P2
10	10
255
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
```
プレビュー画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/e72a98a4-8f48-9216-26fe-1a7df98953ff.png)
プレビューには『irfan view』を使用した。

## 2
```2.pgm
P2
10	10
255
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	255	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
```
プレビュー画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/39b24490-e5d3-d34f-657f-2969ea859751.png)
以降、3～8までプレビューは省略。

## 3
```3.pgm
P2
10	10
255
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	255 255	255	255	255	255	255	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
```
## 4
```4.pgm
P2
10	10
255
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	0	0	0	0	0
```
## 5
```5.pgm
P2
10	10
255
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	255	0	0	0	0	0	0
0	0	0	0	255	0	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	0	255	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	0	0	0	0	0	0
```
## 6
```6.pgm
P2
10	10
255
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	255	255	255	255	255	255	255	0
0	0	255	255	255	255	255	255	255	0
0	0	255	255	255	255	255	255	255	0
0	0	255	255	255	255	255	255	255	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0
```
## 7
```7.pgm
P2
10	10
255
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	255	0	255	0	0	0
0	0	0	0	255	0	255	0	0	0
0	0	0	255	0	0	0	255	0	0
0	0	0	255	0	0	0	255	0	0
0	0	255	0	0	0	0	0	255	0
0	0	255	0	0	0	0	0	255	0
0	255	0	0	0	0	0	0	0	255
0	0	0	0	0	0	0	0	0	0
```
## 8
```8.pgm
P2
10	10
255
0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	255	0	0	0	0
0	0	0	0	255	255	255	0	0	0
0	0	0	0	255	255	255	0	0	0
0	0	0	255	255	255	255	255	0	0
0	0	0	255	255	255	255	255	0	0
0	0	255	255	255	255	255	255	255	0
0	0	255	255	255	255	255	255	255	0
0	255	255	255	255	255	255	255	255	255
0	0	0	0	0	0	0	0	0	0
```
## 9
```9.pgm
P2
10	10
P2
10	10
255
0	0	0	0	255	0	0	0	0	0
0	0	0	255	255	255	0	0	0	0
0	0	0	255	255	255	0	0	0	0
255	255	255	255	255	255	255	255	255	0
0	255	255	255	255	255	255	255	0	0
0	0	255	255	255	255	255	0	0	0
0	0	0	255	255	255	0	0	0	0
0	0	255	255	255	255	255	255	0	0
0	255	255	255	0	0	255	255	255	0
255	255	255	0	0	0	0	255	255	255
```
プレビュー画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/3d934121-d366-855e-5b59-ba01193d4c81.png)

星がむずかしすぎる。
git push でGitHub上のファイルを更新すっぞ

純粋は初投稿です。

頭筋肉的に感覚でリポジトリ上のファイルをターミナルから更新します。
個人の備忘録みたいなものなので、ご愛嬌ください。
初期設定は[こちら](https://hacknote.jp/archives/19110/ "ターミナルでのGitHubの操作まとめ")のサイトを参考にしました。

今回私はローカルのvue.jsのファイルをgithubにアップします。

```
$ cd [アップしたいファイルのディレクトリ]
$ git init //gitの初期化
$ git add -A //面倒くさいのでディレクトリごと追加
$ git push origin master //多分更新するやつ
```
以上になります。

以下が~~パクらせて~~参考にさせていただいたページです。

[キーボードでのバッククォートの入力方法](https://ex1.m-yabe.com/archives/1651 "キーボードでのバッククォートの入力方法")
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d "Markdown記法 チートシート")
[【Git】新人エンジニア、git pushまでの道](https://qiita.com/yukibe/items/9ef9d54f2e7d53cfb51c "【Git】新人エンジニア、git pushまでの道")
Sassを使って簡単なローダーアニメーションを作る。

###はじめに
完成図
https://gyazo.com/a66af4faca7570d3dd4e0bd8b8881986

一例としてページローダーのようなものをCSSで表現してみたいと思います。


Sassと言ってますが、基本的にはscss記法で書いていきます。そちらの方が個人的には見やすいので。




```index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="spinner">
        <div class="bounce1"></div>
        <div class="bounce2"></div>
        <div class="bounce3"></div>
    </div>
</body>
</html>
```
htmlは特に問題なしですね。ローダー部分の要素となるdivを３つ作ります。

```style.css


.spinner {
    text-align: center;

    & div {
        display: inline-block;
        width: 18px;
        height: 18px;
        background-color: black;
        border-radius: 50%;
        animation: sk-bouncedelay 1.4s infinite;
    }

    & .bounce1 {
        animation-delay: -0.32s;
    }

    & .bounce2{
        animation-delay: -0.16s;
    }
}

@keyframes sk-bouncedelay {
    0% {
        transform: scale(0);
    }
    40% {
        transform: scale(1);
    }
    80% {
        transform: scale(0);
    }
    100% {
        transform: scale(0);
    }
}
```
& divで　.spennerの中のdivを選択してあげます。
&は、親要素の.spinnerをさしています。
ここのCSSで３つの黒丸を作りました！  animation:の第一引数はキーフレイム。第二引数のinfiniteで、1.4秒で永遠でループするという意味です！

& .bounce1　のcssでそれぞれの黒丸が別々で動くように設定しています。
animation-delay: -0.32s;で遅延させています！
& .bounce2　も同様にずらしてあげます！

キーフレイムを設定するには@keyframes と記述してあげます！
@keyframes sk-bouncedelay {}の中にアニメーションを定義していきましょう。
キーフレイムは基本的に、０％から１００％のアニメーションの状態を記述します！
３つの黒丸が収縮・拡大を繰り返すので、scale という関数を使っていきます。
0%のときは、scale(0);と設定してあげて、
40%のときは、scale(1);と設定。
80%のときは、scale(0); に戻して、
100%もそのまま。
これで完成しました。

#おわりに
説明がわかりづらかったらすいません！
以上、Saasを使ったローダーっぽいものの作り方でした。
他にもtransformを使っていろんなパターンが作れそうですので、勉強したらアウトプットできたらいいなと思います。
【環境構築】Laravelの初期設定について(Mac版)

#まずはLaravelでプロジェクトを作成する
①Applications/MAMP/htdocs下でlaravelプロジェクトを作成
下記コマンドによって基本的な雛形は作られる。

```csharp:Applications/MAMP/htdocs
$ composer create-project "laravel/laravel=6.*" todo_app
```
実行すると開発に必要な雛形がインストールされていく。
（イメージは下記の通り。長文になるので初めだけ記載)

```csharp
Creating a "laravel/laravel=6.*" project at "./todo_app"
Installing laravel/laravel (v6.20.0)
  - Installing laravel/laravel (v6.20.0): Downloading (100%)  
  <以下省略>
```
②簡易サーバーを立ち上げ、念の為動作確認

```csharp:todo_app
$ php artisan serve
Laravel development server started: http://127.0.0.1:8000
```
上記コマンドを実行し、下記のような画面が出れば正常である。
![スクリーンショット 2021-01-02 22.00.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823188/ecfa43a7-815a-c71f-075a-656996e2b9c4.png)

簡易サーバーを止めるにはターミナル上で"Control + C"を同時押せば止まる。

#Laravelの初期設定について
①時刻と言語設定について
デフォルトだと日本仕様へ適用されていないため、日本仕様へローカライズする。

```csharp:config/app.php
'timezone' => 'Asia/Tokyo', //70行目前後にあります
'locale'   => 'ja', //83行目前後にあります
```

②デバッグバーのインストール(必須ではない)
次に必須ではないが、開発する際に何かと便利なデバッグバーを下記コマンドを実行し、インストールする

```csharp:todo_app
$ composer require barryvdh/laravel-debugbar
```
再度、簡易サーバーを開き、下部に画像のような表示があれば問題なくインストールが完了している。
![スクリーンショット 2021-01-02 22.25.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823188/f360774a-ba64-1285-e4e5-f7dd0cfa5a5c.png)


これにてLaravelの超基本的な初期設定は完了。
別のPCからラズパイにssh接続する

ラズパイ側でコマンドプロンプトを起動し、
ifconfig
を入力する。(読み方はアイエフコンフィグ)

inetの右側のIPアドレスをメモしておく。

別のPCでコマンドプロンプトを起動し、
ssh ユーザー名@ラズパイのIPアドレス
を入力する。

（おまけ）
全画面表示から抜け出せなくてどうしようもない時

まず
ps -aux
次に
kill "ここにプロセス番号を入力"

究極の最終手段
両手の指を広げて全てのキーを一斉に押す。

あなたは救われました。
javascriptとjQuery比較


テストを赤文字に変更する処理をjavascriptとjQueryで書いてみる

```
// javascript
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>テスト</h1>

        <script>
           document.querySelector('h1').style.color = 'red';
        </script>
</body>
</html>
```
```
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>テスト</h1>

    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
            $("h1").css('color', 'red');
    </script>
</body>
</html>
```
###引用
>https://adventar.org/calendars/1075
vue/cli 4.x での Sass 導入まとめ

# はじめに
vue/cli 4.x で Sass を導入する機会があったので、備忘録としてまとめておこうと思います。

# 開発環境について
- @vue/cli: 4.5.4
- node-sass: 5.0.0
- sass-loader: 10.1.0

# ファイル構成について
`vue create [プロジェクト名]`コマンドを利用してベースとなるプロジェクトを作成しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/3be71775-a01c-5cf3-7435-effc66b91079.png)

# ファイルの中身について

```scss:_variables.scss
// 共通スタイル定義
// いわゆるグローバル変数のようなもので、各scssファイルでインポートする
$base-font-size: 16px;
```

```scss:index.scss
// 個別スタイル定義
// _variables.scss の $base-font-size を参照している
.test- {
  &msg- {
    &hoge1 {
      color: #f00;
      font-size: $base-font-size;
    }
    &hoge2 {
      color: #00f;
      font-size: $base-font-size;
    }
  }
}
```

```vuejs:App.vue
<template>
  <HogeComponent1 msg="Hoge1" />
  <HogeComponent2 msg="Hoge2" />
</template>

<script>
import HogeComponent1 from "./components/HogeComponent1";
import HogeComponent2 from "./components/HogeComponent2";

export default {
  name: "App",
  components: {
    HogeComponent1,
    HogeComponent2
  }
};
</script>
```

```vuejs:HogeComponent1.vue
<template>
  <div>
    <p class="test-msg-hoge1">{{ msg }}</p>
  </div>
</template>

<script>
export default {
  name: "HogeComponent1",
  props: {
    msg: String
  }
};
</script>
```

```vuejs:HogeComponent2.vue
<template>
  <div>
    <p class="test-msg-hoge2">{{ msg }}</p>
  </div>
</template>

<script>
export default {
  name: "HogeComponent2",
  props: {
    msg: String
  }
};
</script>
```

```js:main.js
import { createApp } from "vue";
import App from "./App.vue";

// スタイル定義を取り込む
require("./assets/styles/index.scss");

createApp(App).mount("#app");
```

```js:vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      scss: {
        additionalData: `@import "~@/assets/styles/_variables.scss";`
      }
    }
  }
}
```

# 工夫しているところ
`_variables.scss`を各 scss ファイルでインポートする手間を省くために`vue.config.js`を作成して、グローバルな scss ファイルのインポートを可能にしています。

```scss:index.scss
// 本来なら @import 文が必要になるがこれが不要になる！
// @import "./variables";

.test- {
  &msg- {
    &hoge1 {
      color: #f00;
      font-size: $base-font-size;
    }
    &hoge2 {
      color: #00f;
      font-size: $base-font-size;
    }
  }
}
```
今回はあくまで備忘録という位置づけのため`index.scss`に全ての個別スタイル定義を記述しておりメリットを感じづらいかと思いますが、もし`items/index.scss`や`parts/index.scss`や`block/index.scss`等を作成して細かく管理していく場合は、各 scss ファイルにてインポートする手間が省けるためメリットが感じられると思います。（初見者のインポートし忘れを防ぐ、という側面もあるかと思います）

# 最後に
`vue.config.js`についてですが、ネット上の記事では`additionalData`ではなく`prependData`や`data`で紹介されている記事をいくつか見かけました。今回の`sass-loader`のバージョンだと`additionalData`が正解のようですが、今後のバージョンアップによって変更になる可能性があるため、エラーが出た場合は [公式ページ] (https://github.com/webpack-contrib/sass-loader) で確認されると良いかも知れません。

### 追記
`vue.config.js`を編集した場合は再度`npm run serve`を行ってVueアプリケーションを再起動してください。そうしないとconfig情報が反映されません。これに気づくまで少々ハマってしまいました。。。
2020年12月に発見した5つのVim Tips 

# Vimの可能性はすごい 
みなさん、初めまして。 
エンジニアのエディター論争でいつもトップを争う**Vim**ですが、初めて2年ほど経ちますがまだまだ初心者の域を出れません。 
意識的に**Vimのショートカット**を覚えようとしたところ、**生産性が爆上がり**したので得られたTipsを共有したいと思います! 

# 1. 改行の削除 (数字 -> g -> Shift + j)
例えば、縦に並んだa,b,c,d,e,の文字を１行に収めたいとします。 
Vimだとaの直前にCursorを持っていき、``` 5 -> g -> J```です。 

##### スタート  

``` 
a,
b,
c,
d,
e,
```

##### 目標 

```
a,b,c,d,e,
```

# 2. 他のファイルに行をコピー ( yy -> :e FILE_PATH -> p )

1で得られた``` a,b,c,d,e```を別のファイルにコピーさせるとします。 
Vimだと、```a.pyの中でyy -> :e ./b.py -> p```で完了です 

```a.py
a,b,c,d,e,
```

```b.py
a,b,c,d,e,
```

# 3. 大文字->小文字変換 小文字->大文字変換 (guu, gUU)
１行のみの場合は、guu (Upper->Lower) gUU(Lower->Upper) 
複数行は3guuや3gUUのように行数を先頭につけることで可能 
または、
Visual Modeでu(Upper -> Lower) U(Lower->Upper) 

```a.py
a,b,c,d,e,
```
```a.py
A,B,C,D,E,f
```

# 4. Yankの更なる使い方 (yw, y2w, y$) 
[公式Document](https://vimhelp.org/usr_04.txt.html#04.6) 
今までyankは**yy**のみしか使っていませんでしたが、 
削除のdと同様に、
y$, yw, y3wといった使い方ができることを知りました。

```
a b c d e 
```

下のようにa b c dの4つの文字を削除する際には、
aの手前にカーソルを持っていき、4dwや4ywでコピー、削除が可能です。 

```
e 
```

下のようにb c d eの4つの文字を削除する際には、
bの手前にカーソルを持っていき、d\$ or Dやy\$でコピー、削除が可能です。 

```
a 
```

# 5. Bufferのもろもろ 
2に関連してなのですが、 
ファイルを開いたり閉じたりする必要なく、 
Vimで別のファイルを開くことができます. 
詳しくは[公式のBuffer Document](https://vimhelp.org/vim_faq.txt.html#faq-8.1)を参照ください! 

別のFileに飛んだ際に、元々のBufferを自動保存する方法 

```
:set autowrite  
```

Vimを出ることなく、今のBufferから退出する方法 

```
:bd
```

来月はここの[Featured Tips](https://vim.fandom.com/wiki/Vim_Tips_Wiki:Featured_Tip#Previously_featured_tips)を読み進めたいと思います。
【Rails】'ArgumentError (Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true):'が出たときの対処法

## 使用環境
ruby 2.6.5
Rails 6.0.3.4
macOS Catalina 10.15.6

## エラー内容

```
'ArgumentError (Missing host to link to!
Please provide the :host parameter, set default_url_options[:host], 
or set :only_path to true):'
```
ええと、見たこともないエラーにぶち当たりました。はてはて・・・

## やっていたこと

そもそも何をしていてこうなったのかを簡単に説明しておきます。

Ajaxでタイムラインの記事にコメント投稿機能を実装時に、コメント投稿したユーザーのアバター画像を表示させる機能も同時につくっていて、user_serializerをあれこれと調べながらいじっていました。
（以下コード）

```user_serializer.rb

class UserSerializer < ActiveModel::Serializer
    include Rails.application.routes.url_helpers
  
    attributes :profile, :avatar_image, :account_name,  :comment_avatar_image
    has_many :comments
    has_one :profile

    def comment_avatar_image
        rails_blob_path(object.avatar_image) if object.avatar_image.attached?
    end

end
```

このように`comment_avatar_image`を定義して、JavaScript側は動的にユーザーのコメントと画像（とsユーザー名）を表示するために、appendを使ってこのようにコードを書きました。

```timeline.js
const appendNewComment = (comment) => {
      $('.comments-container').append(
        `<div><img class="comments_image"src="${comment.user.comment_avatar_image}"></img></div>
        <div class="comments_name"><p>${(comment.user.account_name)}</p></div>
        <div class="comments_content"><p>${(comment.content)}</p></div>`
      )
  }

```

しかし上記のエラーが出たので、エラー文を読んでみることに。

「'ArgumentError (リンク先のホストがありません
hostパラメータを指定して、default_url_options[:host]を設定してください。
または :only_path を true に設定してください)'」

とありました。これ通りにやってみます。

## 解決策

そもそもこの`default_url_options[:host]`はどこかで見たことあるなと思っていたら、deviseの設定をconfigのdevelopment.rbでした時でした。

```config/environment/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```

私と同じくdeviseを使用してこれを設定した人なら
先ほどの指示の「hostパラメータを指定して、default_url_options[:host]を設定してください。」
これでいうhostはlocalhostになっています。

ではどうすればいいのか？
記事や公式文書を調べていると、以下のような記述をすればいいことがわかりました。

```config/environment/development.rb
 host = 'localhost' #←先ほどの上のコードのhost名と合わせる
 Rails.application.routes.default_url_options[:host] = host
```

これで、一旦サーバーを落としてもう一度起動してリロードしましょう！（意外に忘れがち）
※environment系は一回サーバーを落として立ち上げないと変更が反映されません。

## 疑問

解決はしましたが、似たような記事を見てもAction Mailerの設定がメインでした。上記のように画像を反映させることに関して、なぜこのような設定が必要なのかはまだ疑問が残るので検索中です。

もし、わかる方がいたらご教授いただけると幸いです。

---
### 参考記事

[action-mailerのビューでurlを生成する][1]
[RailsでMissing host to link to!が出たときに。model内でURL組み立てる場合の設定][2]


[1]:#https://railsguides.jp/action_mailer_basics.html#action-mailer%E3%81%AE%E3%83%93%E3%83%A5%E3%83%BC%E3%81%A7url%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B

[2]:https://qiita.com/daik/items/41a9bc8dec5ccec37f40
Wio Terminal の開け方

Wio Terminal の（裏フタの）開け方です。

# 1. ゴム足を2個剥がす

裏から見て、左上と右下のゴム足を取ります。両面テープで張り付いているだけなので、ピンセットなどで強引に剥がしましょう。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/a646734f-2541-8e89-b3a4-6a71d82112a0.png">

# 2. ネジを2本外す

ゴム足の下にある、ネジを2本外します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/9485aec9-09ca-60b0-c8f2-6964eb037d4b.png">

# 3. 表フタの広げて、裏フタを外す

表と裏のフタがツメで引っかかっています。**表フタ**を下図の矢印方向に広げながら、裏フタを持ち上げて外します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/e50d001f-f16f-d174-c6aa-8ee39b12cf28.png">

裏から見て、左下のツメの様子。

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/472bbadc-ef4c-7940-399d-0227faa0514d.png">

# 裏フタを外した様子

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/c034fe86-6868-7376-82a8-bf16b2a59b4d.png">

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/da9ebc59-99b7-9d2b-74f2-213b85b41492.png">
スクロールで要素がふわっと表示される「ScrollReveal.js」を使ったら、動かなかった件を解決した

自身のポートフォリオサイトで、ポートフォリオ作品の部分を、スクロールしたらふわっと表示されるアニメーションを取り入れたかったので、「ScroalReveal.js」を使って実装しようとしました。

## ScroalReveal.jsとは
スクロールして要素が画面に表示されたら、指定したアニメーションを実行してくれるJavascriptライブラリです。
ふわっと要素を表示させたり、下から表示させたり、遅れて表示させたりなどを簡単に実装することができる優れものです。

## ScroalReveal.jsの使い方

まず[こちら](https://liginc.co.jp/500530)の記事を参考に実装しました。
リンク先：[ScrollReveal.jsを使ってスクロールしたらふわっと表示される動きを作ってみよう](https://liginc.co.jp/500530)

### 1.ライブラリを読み込み
まず、ライブラリを`script`タグで読み込み。

```HTML:HTML
<script src="https://unpkg.com/scrollreveal"></script>
```

### 2.アニメーションをつけたい要素にクラスを追加
アニメーションをつけたい要素に、私は`reveal`というクラスを追加しました。

### 3.Javascriptを読み込み

```JavaScript:JavaScript
ScrollReveal().reveal('.reveal');
```
クラスの部分を自分がアニメーションをつけたい要素のクラスにします。


## 動かない。

参考記事のとおりやったのですが、まったく動かないので原因を調べまくったところ
[こちら](https://qiita.com/Hamaboh_younect/items/f5d647f45dfea20ea815)の記事を見つけました。
リンク先：[ScrollReveal.jsを使えば「スクロール後に要素がふわっと浮き上がる」動きを最も少ない記述量で実装できる](https://qiita.com/Hamaboh_younect/items/f5d647f45dfea20ea815)

ライブラリ読み込みの部分で、
>bodyタグの閉じタグ直前にコピペしましょう。

と記述があったので、自身のコードを確認したところ、`head`タグ内で読み込みさせていました。

こちらを`body`の閉じタグの前に配置をまず修正。

そして、
>`ScrollReveal().reveal('.box');`
>1.で読み込んだライブラリとbodyタグの閉じタグの間に、このコードをコピペ。

という記述がありました。

自分のコードでは、script.jsというJSのファイルを別で作って読み込みさせていたので、これをHTMLで下記に修正し、JSの方からは記述を削除。

```HTML:HTML
<script src="https://unpkg.com/scrollreveal">
    ScrollReveal().reveal('.reveal');
</script>
```

これで動くようになりました！！


## オプションで動きを変更できる
```HTML:HTML
<script src="https://unpkg.com/scrollreveal">
   ScrollReveal().reveal('.reveal', { 
   duration: 1000, // アニメーションの完了にかかる時間
   viewFactor: 0.2, // 0~1,どれくらい見えたら実行するか
   reset: true   // 何回もアニメーション表示するか
});
</script>
```

ほかにもいろいろオプションがあるので、
[ScrollReveal.jsを使ってスクロールしたらふわっと表示される動きを作ってみよう](https://liginc.co.jp/500530)
今後実装で使用する際は、こちらの記事を参考にさせていただきたいです。


## まとめ
JSを読み込む記述の場所って重要なんだなと再認識しました。
とりあえず`head`タグに突っ込んでしまうクセがあったので、これを機会になおしていきたいです。
【備忘録】分割代入とスプレッド構文、シャローコピー【TypeScript】

# 分割代入とスプレッド構文、シャローコピー

TypeScript,JavaScript 初学者が関数の**分割代入とスプレッド構文、シャローコピート**について勉強したのでメモを残す。

## 配列のプロパティ名のショートハンド

- まずは下記の例を読んでみる

```typescript
const object1 = { bar: 10, baz: 20, foo: 30 };
const object2 = { foo };
console.log(object2); //  { foo: 30 }
```

- `object1`のキー`foo`を`object2`に代入することで、`object2`がキー`foo`,値`30`のオブジェクトになる

## 分割代入

- 続いて分割代入を見てみる

```typescript
//  分割代入
const [num1, num2] = [10, 20];
console.log(num1, num2); //  10 20

//  オブジェクトの代入
const object = { name: "Yasushi", age: 27 };
const { name, age } = object;
console.log(name, age); //  Yasushi 27
```

## スプレッド構文

- 配列の中身を展開する構文で、**スプレッド構文**というものがある。

```typescript
// 配列のスプレッド構文
> const array01 = ['A', 'B', 'C']
> array01
[ 'A', 'B', 'C' ]
> const array02 = [...array01, 'D', 'E', 'F']
> array02
[ 'A', 'B', 'C', 'D', 'E', 'F' ]

//  オブジェクトのスプレッド構文
> const object01 = { a: 1, b: 2, c: 3, d: 4 }
> const object02 = { ...object1, e: 5, f: 6, g: 7 }
> object01
{ a: 1, b: 2, c: 3, d: 4 }
> object02
{ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7 }
```

- 配列やオブジェクトの名前の前に`...`をつけることで中身が展開される。

## マージとコピー

- オブジェクト型の値は**参照渡し**のため、コピーしてもアドレスが異なるため`true`にはならない。下のコード参照。

  ```typescript
  > const sample = { a: 1, b: 2, c: 3 }
  > const sampleCopy = Object.assign({}, sample);
  > //    sample      { a: 1, b: 2, c: 3 }
  > //    sampleCopy  { a: 1, b: 2, c: 3 }
  > sample==sampleCopy
  false
  ```

  - `Object.assign()`は第１引数がコピー先オブジェクトなのだが、割り当てた後に中身が書き変わってしまうため使うには注意が必要。コツとして第１引数に`スプレッド構文`を使うことでコピー元が書き変わることを防ぐことができる。

### シャローコピーには注意

- オブジェクトをコピーする際に、プロパティ値がオブジェクトだった時にオブジェクトへの参照がコピーされてしまう。そのためコピー先でそのプロパティ値を変えてしまうと、参照元のオブジェクト、つまりコピー元が書き変わってしまう。

  ```typescript
  > const sample = {
      isSample1: true,
      isSample2: false,
      objectProperty: {
        isSample1: true,
        isSample2: false,
      }
    }
  > const sample1 = sample
  //    浅いプロパティを書き換える
  > const sample2 = {...sample, isSample1: false, isSample2: true}
  //    深いプロパティ（オブジェクト）を書き換える
  > sample2.objectProperty.isSample1 = false
  > sample2.objectProperty.isSample2 = true
  > sample2
  {
    isSample1: false,
    isSample2: true,
    objectProperty: { isSample1: false, isSample2: true }
  }
  > sample1
  {
    isSample1: true,
    isSample2: false,
    objectProperty: { isSample1: false, isSample2: true } //  シャローコピーを考慮できていないバグ（書き変わってしまった）
    }
  ```

  - 回避策として、`一旦JSONで文字列に展開してパース`する方法がある。

  ```typescript
  > const sample2 = JSON.perse(JSON.stringify(sample1));
  > sample2.objectProperty.isSmaple1 = false
  > sample2.objectProperty.isSmaple2 = true
  > sample1
  {
    isSample1: false,
    isSample2: true,
    objectProperty: { isSample1: true, isSample2: false } //  参照していないので書き変わらない
    }
  ```

# 参考

- [りあクト！ TypeScript で始めるつらくない React 開発 第 3 版【Ⅰ. 言語・環境編】](https://booth.pm/ja/items/2368045)
- [Object.assign() - MDN - Mozilla](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)

_何か指摘等ございましたら、コメントでお願いいたします。_
[Unity]animatorで設定したモーションを使った後、その他のモーションに移れなかった時の解決例

## どのようなものだったか
下記の図のようにanimatorを設定して、Attackアクションを行うとその後animatorの全てのモーションができなくなってしまった。

![スクリーンショット 2021-01-02 21.35.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/c5eadad8-cccc-7e01-e458-1765db6a72a1.png)



## 原因
Attackモーションを内部で終わらせる処理を設定していなかったため他のモーションに遷移できなかった。

## 解決方法
下記の図のようにanimationの画面で、"Add Animation Event"でモーションが始まる設定と終わる設定を行うことで、次のモーションに遷移することができた。

![スクリーンショット 2021-01-02 21.36.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/8165831b-f718-639c-0323-df4deecdee5d.png)
AlphaPoseをROS化する(PoseTrackingをROSで実装する)

#はじめに
AlphaPoseとはこれ（https://github.com/MVIG-SJTU/AlphaPose）
1.**AlphaPoseをROSで動かしたい．**(Pose TrackingをROSで実装したい)
2.とりあえず動くようなコードができたが(https://github.com/yone-moto/AlphaPose_ros.git) ，β版であり，修正点が多いので，はやめに公開することでコードの改善をしたい．
というモチベーションです．

#AlphaPoseとは
画像or動画内の複数人の**人物の姿勢を推定してくれる深層学習のツール**です．
人物の姿勢を推定してくれる深層学習のツールはAlphaPose以外にもたくさん公開されています．
その中でも一番メジャーなOpenPoseと比べて異なる点を挙げると，
・Realtimeで**Pose Tracking**をしてくれる．
・Human Pose Estimationの一種で，**OpenPoseよりもAPが優れている．**
・**Top-downアプローチ**である．
だと理解しています．
今回はPose estimationとTrackingの実装がしたかったので，AlphaPoseをチョイスしました．

#環境
ubuntu16.04
ROS version kinetic
というところです．
あとはAlphaPoseが動く環境であること．


#AlphaPoseのROS化
##機能の追加
AlphaPoseでは[apiのスクリプト](https://github.com/MVIG-SJTU/AlphaPose/blob/master/scripts/demo_api.py)を公開していますが，私の要求と比べると
・**画像対応のAPIなので動画に対応していない．**
・**トラッキングの実装がない.**
などがなく，追加をしました．[コードはこちら（Alphapose_ros.py）](https://github.com/yone-moto/AlphaPose_ros/blob/master/scripts/Alphapose_ros.py)
動いたらいいという感じなので最適化されてないです．
##Pythonバージョン問題
Kineticはデフォルトでpython2なのでPython3への対応．．．(はやくROS2なりnoeticにしたい．．．)
なのでROSでノード化する場合[こちら](https://qiita.com/tnjz3/items/4d64fc2d36b75e604ab1)を参考にして，AlphaPoseで作成した仮装環境のPython3で動くようにしました．

画像をwebカメラから持ってくるときにpython3からcv_brige使ってtopic化を試みたのですが，どうやらpython3系に対応するにはcv_brigeのBuildのし直しが必要で仮装環境内では他のライブラリとの共存でうまく行きませんでした．[こちらを参考に](https://masato-ka.hatenablog.com/entry/2019/07/17/065000)
そこでいろいろ調べたところ CompressedImageはpython3系に対応しているということでこちらを使ってwebcameraからの画像topicをpython3で受け取れるようにしました．[こちらを参考に](http://wiki.ros.org/rospy_tutorials/Tutorials/WritingImagePublisherSubscriber)

##動かし方
pkgになっているのでsrc直下に置く．

```Bash
catkin_ws/src/ $ git clone https://github.com/yone-moto/AlphaPose_ros.git
catkin_ws/ $ catkin_make
######準備完了・実行######
catkin_ws/src/ $ roslaunch alphapose_ros alphapose_demo.launch
(alphapose) (path to)AlphaPose_ros/scripts/$./alphapose.sh
```

##結果
**Poseestimationの様子（Rvizで可視化）**
![スクリーンショット 2021-01-02 21.09.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514658/b08493cf-1851-9592-22d0-1f19ab5a7776.png)

一人の動画しかなくてトラッキングは見せられない．．．
右半分しか塗られてないのは意図的で，左半分も出力としてでてます．
#オプション
どうしてもトラッキングをみせたかったので速度ベクトル（人物の進行方向）をライダーと組み合わせて算出．
こんな感じ
![スクリーンショット 2021-01-02 21.34.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514658/5d2eaf79-8cb8-6cd0-0f79-c24a5d98b993.png)

以上です．最後まで見ていただきありがとうございました．
**今後もこの記事とコードを追記なり修正なりしたいです！！！！
そしてもっと世の中の役にたちたいです．**
【Ruby】sliceメソッドで要素の取り出し

## 概要

問題を解きながら `slice` メソッドを学習することができます。[前回の記事](https://qiita.com/suzu12/items/95bfc11139ad76aaa236)では 「sliceメソッドとslice!メソッド」 についてまとめていますのでよろしければ御覧ください。

## 目次

- slice

- 実践
    - 問題
    - 解答(解説)
    - 別解

- まとめ
- 参考文献

## slice

sliceメソッドを使うことで文字列や配列から指定した要素を取り出すことができます。添字が `0番` からはじまるので考慮して引数を指定します。

```ruby:例
array = [0,1,2,3,4,5,6] # 配列を作成

array.slice(1..3) # 配列の1~3番目を取り出し
#=> [1, 2, 3]

array.slice(1, 5) # 配列の1から5個分の要素を取り出し
#=> [1, 2, 3, 4, 5]
```

## 実践

#### 問題

>文字列の最後の2文字を3回繰り返し、出力するメソッドを作ってください。

#### 解答（解説）

```ruby:解答
def repeat_char(str)
  char_length = str.length - 2               # 文字列の長さを出し最後から2文字を起点にしたいので-2をしている
  char_slice  = str.slice(char_length, 2)    # 変数char_lengthから2文字取り出し
  p char_slice * 3                           # 3回出力
end

# メソッド呼び出し
repeat_char('apple')
repeat_char('orange')
repeat_char('melon')

# ターミナル出力結果
# "lelele"
# "gegege"
# "ononon"
```

#### 別解

スタート位置を最後から **2番目** にするために、上記の例だと文字列の長さを取得してから `-2` しています。

ここでは `slice` の第1引数に `-2` を指定することで取得しています。

```ruby:別解
def repeat_char(str)
  char_slice  = str.slice(-2, 2)    # 最後から2番目スタートにしている
  p char_slice * 3
end

# メソッド呼び出し
repeat_char('apple')
repeat_char('orange')
repeat_char('melon')
```

## まとめ

- 「slice」 は文字列や配列から引数で指定した要素を取り出すことができる
- **添字が0番**からはじまるので取り出し時に注意する
- 「slice」 の第一引数に `-1` を指定することで任意の**文字列や配列**の「最後を取得」することができる


## 参考文献

- [Ruby 3.0.0 リファレンスマニュアル(Array#slice)](https://docs.ruby-lang.org/ja/latest/method/Array/i/slice.html)

- [Ruby 3.0.0 リファレンスマニュアル(String#slice!)](https://docs.ruby-lang.org/ja/latest/method/String/i/slice=21.html)

- [sliceメソッドとは？slice!との違いを例題を解いて理解しよう！](https://qiita.com/suzu12/items/95bfc11139ad76aaa236)
【Robocode】楽しくお勉強できるJavaScriptの戦車ゲームをWindows環境で動作させる。

#Robocodeとは

『Robocode』は、オープンソースの教育ゲームである。JavaやVer1.7.2以降の.NET Frameworkの熟達に役立つ。 単純なロボットはわずか数分で作成できるが、本格的に完成させる場合は数ヶ月かかることがある。 
出典：https://ja.wikipedia.org/wiki/Robocode

学生時代 Javaが全くかけなかった自分は、RobocodeにハマったのをきっかけにJavaにのめり込むようになりました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/cb4e1f27-4915-ad94-08cf-33aaa90552c8.png)





・・・のJavaScript版を発見したので、手軽に動作させる手順をメモ書きで書いておきます。



　
#前提となる環境
OS：
　Windows10

他：
　node.js(筆者環境はV14)

　
　
#JavaScript版の導入
##githubよりソースコードの入手
###githubにアクセスします
https://github.com/youchenlee/robocode-js

README.mdに詳しい解説がありますが
Windows環境で動作させるのはちょっと手間がいりそうです。



　
　

###gh-pagesブランチに移動します
gh-pagesブランチからコンパイル済のファイルを入手します
※Windows環境で動作させるのはちょっと手間がいりそうなので、あらかじめ動作に必要なファイルがそろっているgh-pagesブランチからファイル一式を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/87509369-c577-aa8e-ae81-1b1592d99498.png)

　
　
　

###cloneするかzipを取得します
Git環境がある方はどちらでも、ないかたはzipで取得するのが良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/af6201e3-95da-16a3-95a4-2cf990a7ed08.png)



　
　


##環境の整備を行います。

<!-- wp:heading {"level":3} -->
###npmコマンドで動作に必要なファイルを取得し、ファイルを整理します
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>コマンドプロンプトを立ち上げて<br>cloneしたフォルダ、若しくは解凍したフォルダに移動して
npm installコマンドを投げます。
<br>※expressはWindows環境でブラウザに依存せずにアプリを動かすために用います</p>
<!-- /wp:paragraph -->



<!-- wp:code -->
<pre class="wp-block-code"><code>npm install
npm install express</code></pre>
<!-- /wp:code -->

　
※gh-pagesやブラウザ依存についてはgithubのreadmeに記載があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/ec861a11-4635-ae0e-ff8e-265040467a0a.png)





　
　
 
 
###expressで静的ファイルを公開するためにファイルの整理を行います。
<!-- wp:code -->
<pre class="wp-block-code"><code>mkdir public
move  /y .\img .\public\
move  /y .\robot .\public\
move  /y .\robot .\public\
move  /y .\base-robot.js .\public\
move  /y .\base-robot.ls .\public\
move  /y .\*.js .\public\
move  /y .\*.ls .\public\
move  /y .\*.html .\public\
move  /y .\Makefile .\public\
echo nul > server.js
</code></pre>
<!-- /wp:code -->


 
 
　
　
###expressでアプリを動かす準備をします
server.jsを開いて下記のコードを上書きします。

```javascript
const express = require('express')
const app = express()
app.use(express.static('public'))
const port = 3000

app.get('/', (req, res) => {
  res.send('index.html')
})

app.listen(port, () => {
  console.log(`listening at http://localhost:${port}`)
})
```




　
　
##動作確認してみます。
<!-- wp:paragraph -->
<p><br>コマンドプロンプトで下記のコマンドを実行します。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>node server.js</code></pre>
<!-- /wp:code -->


ブラウザを開いて、http://localhost:3000/index.htmlにアクセスします。
下記ような画面が出てきたら確認完了です。

次回はRobocodeの遊び方について解説します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/7cbfc490-c1bb-7d3e-8830-f59a279681c7.png)
テンポラリーフォルダを得るにはSystem.tmp_dir!()を使うとよいですよ〜(Elixir)

# はじめに
- [Elixir](https://elixir-lang.org/) 楽しんでいますか :bangbang::bangbang::bangbang:
- テンポラリーフォルダ使いたいことありますよね:interrobang:

# [System.tmp_dir!/0](https://hexdocs.pm/elixir/System.html#tmp_dir!/0)を使うとよいですよ〜

リンク先のドキュメントを読みますと次の順にさがすとのことです。

1. 環境変数 `TMPDIR` に設定されたディレクトリ
2. 環境変数 `TEMP` に設定されたディレクトリ
3. 環境変数 `TMP` に設定されたディレクトリ
4. Windowsの場合は`C:\TMP`、UnixライクのOSの場合は`/tmp`
5. ワーキングディレクトリ

## macOS
```elixir
$ iex

iex> System.tmp_dir!()
"/var/folders/66/dj7rwns53vn4db4_1npvqtrh0000gn/T/"
```

## [Nerves](https://www.nerves-project.org/)
```elixir
$ ssh nerves.local

iex> System.tmp_dir!()
"/tmp"
```

# 参考
- [Get a writable temporary directory in Elixir](https://til.hashrocket.com/posts/8rkl48vqmc-get-a-writable-temporary-directory-in-elixir)

# Wrapping Up 🎍🎍🎍🎍🎍
- Enjoy [Elixir](https://elixir-lang.org/) :bangbang::bangbang::bangbang:
オブジェクトベースUIとタスクベースUI

![EnfgIpyVcAIT_lu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/10f823bd-230d-5a24-0a27-7b2ae6521dec.jpeg)
![EnfgJBoUcAAE89t.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/bbb47ecf-c571-fd53-4057-b33e66813c5c.jpeg)
![EnfgJaHVQAMvkqn.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/d86263d8-7175-41f3-caeb-fecc8f36c735.jpeg)
![Eng9350VkAA54UN.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/d009215e-23e5-7747-4a96-6561939d4135.jpeg)
![Eng94T1VkAI2Yl2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/2f788a0b-eded-42dc-3963-514b146709c4.jpeg)
![Eng94roUwAIcPgf.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/d74c7f25-91f4-c327-4620-5192b043ea2c.jpeg)
![Entdr4wVoAojKC_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/26492272-a715-a06a-9d32-709de0716204.jpeg)
![EntdsZIVkAAwnmO.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/4101fc57-24ac-415c-20df-79d09f537dd9.jpeg)
Linuxにリモートデスクトップで入った時に出るダイアログを消す

# 経緯

前回、[Chrome Remote DesktopをLinuxにインストール](https://qiita.com/HirumaT/items/b79c521bfdf59e95ed91)した記事を書いた。
しかしこのままでは事あるごとに

- カラープロフィアルを作成するには認証が必要です
- カラーマネージメントされたデバイスを作成するには認証が必要です
- Authentication is required to refresh the system repositories

…といったメッセージが頻繁に出る。
一番困ったのはスクリーンセーバ復帰後、これらのダイアログが出てきたので、パスワードを入れたのに消えなかったことがあったこと。
ログインし直すしか方法はなく、解決方法を探すのが必要だった。

# 対策

Polkitの設定を変更する。Polkitそのものが何かについては参考のリンクを参照してほしい。
以下では 45-allow-colord.pkla というファイルにしているが、拡張子が.pklaならファイル名に規則はない模様。
ただPolkitで別のルールを作る時のことを考え、内容を簡潔に表す名前になっていると良さそう。

```bash
$ sudo vi /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla
```

これを新規に作成して、以下のように入力。
カラーマネジメントとパッケージマネジメント（リポジトリ系）の更新を全ユーザに対し許可する内容。

```text
[Allow Colord all Users]
Identity=unix-user:*
Action=org.freedesktop.color-manager.create-device;org.freedesktop.color-manager.create-profile;org.freedesktop.color-manager.delete-device;org.freedesktop.color-manager.delete-profile;org.freedesktop.color-manager.modify-device;org.freedesktop.color-manager.modify-profile
ResultAny=no
ResultInactive=no
ResultActive=yes

[Allow Package Management all Users]
Identity=unix-user:*
Action=org.debian.apt.*;io.snapcraft.*;org.freedesktop.packagekit.*;com.ubuntu.update-notifier.*
ResultAny=no
ResultInactive=no
ResultActive=yes
```

# 注意点

以上の設定は、Polkit version 0.105までの設定で有効である模様。
Polkit version 0.106以降は.confファイルを作成、書式も異なるようだ。
Polkitのバージョンは以下のコマンドで確認できる。Ubuntu 20.04は0.105だった。

```bash
$ pkaction --version
```

# 参考

以下のサイトを参考にさせていただいた。Ubuntuのバージョンは違えど20.04でも同じ方法で消せた。
[Ubuntu 19.04にAndroidのMicrosoft Remote Desktopで接続する](http://ajt.pupu.jp/rayfan/2019/10/09/ubuntu-19-04%E3%81%ABandroid%E3%81%AEmicrosoft-remote-desktop%E3%81%A7%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B/)

そもそもPolkitって何ぞや。
[Polkit - ArchWiki](https://wiki.archlinux.jp/index.php/Polkit)
１から順番に足算をしていく計算

１から１０までを順番に足算をしていく計算をしたいと思います。

```ruby
sum = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
```

これでも出力できますが、かっこよくないので、times文を使用してプログラムを作りたいと思います。

合計値を保存しておく変数sumを用意します。


```ruby
sum = 0
```

変数sumに１から１０を順番に足していきます。

```ruby
sum = 0

sum = sum + 1
sum = sum + 2
sum = sum + 3
sum = sum + 4
sum = sum + 5
sum = sum + 6
sum = sum + 7
sum = sum + 8
sum = sum + 9
sum = sum + 10
```

もしくは、自己代入演算子を使用して、

```ruby
sum = 0

sum += 1
sum += 2
sum += 3
sum += 4
sum += 5
sum += 6
sum += 7
sum += 8
sum += 9
sum += 10
```

とすることで記述を短くできます。

さらにtimes文を利用して繰り返される処理をまとめます。

```ruby
sum = 0
10.times do |i|
  sum += i + 1
end

puts sum
```

times文では変数iのなかに繰り返しの回数が数値として自動で代入されるため、iを使えば繰り返しの回数を変数sumに足していくことができます。１回目のiは０のためi+1にします。
2リンクアームの動力学

ラグランジュの運動方程式を用いて，2次元平面に拘束された2リンクアームの運動方程式を求めてみる．

# 定義

![TwoLinkArm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669185/625813ac-1e33-ff2d-3089-01123de07dd3.png)

一様とは限らない2つの剛体リンクが，ジョイントで接続されている．
リンク1はジョイントと反対側の端もジョイントとなっていて，慣性座標系の原点に固定されている．

リンク1の質量と長さは$m_1$, $l_1$とする．原点から質量中心までの距離を$l_{g1}$とする．質量中心まわりの慣性モーメントを$I_1$とする．
リンク2の質量と長さは$m_2$, $l_2$とする．ジョイントから質量中心までの距離を$l_{g2}$とする．質量中心まわりの慣性モーメントを$I_2$とする．

リンク1とリンク2が$x$軸となす角度をそれぞれ$\theta_1$，$\theta_2$とする．
リンク1とリンク2の質量中心の位置をそれぞれ$(x_1, y_1)$，$(x_2, y_2)$とする．
それぞれのジョイントにはモーターが接続されていて，トルク$\tau_1$と$\tau_2$を発揮することができる．
$y$の負の向きに重力$g$がかかる．

## ラグランジアンの計算

系の運動エネルギーとポテンシャルエネルギーから，系のラグランジアンを求める．

エネルギーを考えるときはまず，座標系としてデカルト座標を用いて書き下すのが簡便である．
それぞれのリンクについて運動エネルギーを求めると，

```math
    T_1 = \frac{m_1}{2}(\dot{x}_1^2 + \dot{y}_1^2) + \frac{I_1}{2}\dot{\theta}_1^2\\
    T_2 = \frac{m_2}{2}(\dot{x}_2^2 + \dot{y}_2^2) + \frac{I_2}{2}\dot{\theta}_2^2
```
それぞれのリンクのポテンシャルエネルギーを考えると，

```math
    U_1 = m_1 g y_1\\
    U_2 = m_2 g y_2
```
となる．
ここではまだジョイントによる拘束は考えていない．**それぞれのリンクは独立なものとして運動エネルギーを求め，あとから拘束条件を考える**ことで思考を単純化することができる．

ジョイントによる拘束条件は以下のように書ける．
ジョイントは幾何的な拘束であり，位置の関係式で完全に表すことができるので，ホロノミックな拘束であるといえる．ホロノミック拘束は計算が簡単になるので，ありがたい条件である．

```math
    x_1 = l_{g1}\cos\theta_1\\
    y_1 = l_{g2}\sin\theta_1
```

```math
    x_2 = l_1\cos\theta_1 + l_{g2}\cos\theta_2\\
    y_2 = l_1\sin\theta_1 + l_{g2}\sin\theta_2
```

すなわち，この系を表すためには，一般化座標として$\theta_1$と$\theta_2$だけを考えれば良いということである．
位置拘束条件の時間微分を行い，速度拘束式を導く．すなわち，

```math
    \dot{x}_1 = -l_{g1}\dot{\theta}_1\sin\theta_1\\
    \dot{y}_1 = l_{g2}\dot{\theta}_1\cos\theta_1
```

```math
    \dot{x}_2 = -l_1\dot{\theta}_1\sin\theta_1 - l_{g2}\dot{\theta}_2\sin\theta_2\\
    \dot{y}_2 = l_1\dot{\theta}_1\cos\theta_1 + l_{g2}\dot{\theta}_2\cos\theta_2
```

である．
上記の関係式をエネルギー関数に代入すると，

```math
T_1 = \frac{1}{2}(I_1 + m_1l_{g1}^2)\dot{\theta}_1^2\\
T_2 = \frac{II_2}{2}\dot{\theta}_2^2 + \frac{m_2}{2} \left\lbrace{{\left(l_1 \dot{\theta}_1 \sin\theta_1+l_{g2} \dot{\theta}_2 \sin\theta_2 \right)}}^2 +{{\left(l_1 \dot{\theta}_1 \,\cos\theta_1+l_{g2} \,\dot{\theta}_2 \cos\theta_2 \right)}}^2 \right\rbrace\\
U_1 = m_1 g l_{g1} \sin\theta_1\\
U_2 = m_1 g l_{1} \sin\theta_1 + m_2 g l_{2} \sin\theta_2\\
```

となる．
ラグランジアン$L$は，

```math
L= T_1 + T_2 - U_1 - U_2
```

で得られる．

## 運動方程式の導出

ラグランジアンが得られたので，あとはこれをラグランジュの運動方程式に代入すればよい．ここで，一般化外力を求める必要があるが，今回は一般化座標$\theta_1$, $\theta_2$に直接モータートルク$\tau_1$, $\tau_2$がそれぞれかかっているので，これらが一般化外力となる．
すなわち，運動方程式は

```math
\frac{{\rm d}}{{\rm d}t}\left(\frac{\partial L}{\partial \dot{\theta}_1} \right) - \frac{\partial L}{\partial \theta_1} = \tau_1\\
\frac{{\rm d}}{{\rm d}t}\left(\frac{\partial L}{\partial \dot{\theta}_2} \right) - \frac{\partial L}{\partial \theta_2} = \tau_2
```

から得られる．

この計算は結構大変であり，まとめるのも骨が折れるので，ここには結果を記載しない．その代わりに，MATLABやMAPLEのシンボリック計算によって上記の計算を実行する方法を次回の記事で解説する．
Azure Static Web Apps (PREVIEW) でWebアプリをデプロイする

昨年末に遊んだテキストの感情分析（ネガポジ判定）を呼ぶだけのWEBアプリを、Azure Static Web Appsを使ってデプロイしてみました。

詳細はこちらに書いています。
https://zenn.dev/ibaraki/articles/fc5844aa4cee87

デプロイしたWEBアプリはこちらです。
https://calm-bay-09fad7000.azurestaticapps.net/

私のAzureの課金とか無料枠の枯渇が怖いので、googleでのログインを必須にしています。
囲みマスのサンプルAIの解説

# 概要
2020年に開催予定だった高専プロコンの競技部門

競技部門のルールは2チーム対戦型の陣取りゲームの[囲みマス](http://www.procon.gr.jp/?p=77044)でした

しかし感染拡大予防のため競技部門は中止になりました

そこで公開されている競技ルールをもとに
競技システムを開発しオンライン対戦会を行うため
[Code for KOSEN 囲みマスプロジェクト](https://codeforkosen.github.io/)が発足しました

開発した競技システムはGitHubで公開されています
好きな時に囲みマスの対戦会を開くことができます
https://github.com/codeforkosen/Kakomimasu

システムには対戦AIを作りたい方のために
いくつかのサンプルAIが含まれています

この記事ではサンプルAI同士を対戦させる手順と
サンプルAIの行動について簡単に解説します

# システムのセットアップ
対戦サーバとサンプルAIはDenoで実装されていますので
まずはDenoをインストールします

Windowsユーザの方はPowerShellを起動して以下のコマンドを実行します

```
iwr https://deno.land/x/install/install.ps1 -useb | iex
```

Macユーザの方はTerminalを起動して以下のコマンドを実行します

```
curl -fsSL https://deno.land/x/install/install.sh | sh
```

次にGitHubのCode for KOSENの囲みマスシステムをダウンロードして解凍します
https://github.com/codeforkosen/Kakomimasu/archive/master.zip

コマンドプロンプトかTerminalで以下のコマンドを入力し
対戦サーバを起動します

```terminal
$ cd apiserver
$ deno run -A apiserver.ts
```
```servest:router listening on :8880```が出力されたら対戦サーバの起動成功です

# 対戦状況ページの表示
Chromeでhttp://localhost:8880/ にアクセスすると対戦状況がみられるページが開きます
「ゲーム一覧はこちらから」をクリックすると観戦したい試合を選択できます
ここでは「最新のゲームビューアーはこちらから」をクリックして最新の対戦を観戦できるようしておいてから対戦AIの起動作業を行います
http://localhost:8880/gamedetails.html

# サンプルAIの起動
まずサンプルAIの接続先をlocalhostに変更します

client_deno/client_util.jsの先頭行にある

```javascript
// const defaulthost = "http://localhost:8880/api";
const defaulthost = "https://practice.kakomimasu.website/api";
```

を以下のように変更します

```javascript
const defaulthost = "http://localhost:8880/api";
// const defaulthost = "https://practice.kakomimasu.website/api";
```

次に新しいターミナルを開き1番目のAIを起動します

```terminal
$ cd client_deno
$ deno run -A client_a1.js
```

新しいターミナルを開き2番目のAIを起動します

```terminal
$ cd client_deno
$ deno run -A client_a4.js
```

2つのAIが揃ったのでブラウザの対戦状況ページでは試合が開始しています

## サンプルAIの簡単な解説

ここではclient_denoフォルダに含まれているサンプルAIの行動を解説します

サンプルAIは以下の2つの事についてターンごとに考えます

1. 未配置エージェントの配置座標
2. 配置済エージェントの移動方向

### client_a1.js
1. 未配置エージェントは最も高い点数のマスに配置します
    * ただし競合を防ぐために点数上位何件かは使いません（ターンごとにランダムに決定）
2. 配置済エージェントの作戦は8方向のうちランダムに1方向に動かします（フィールド外など移動不可の方向でも）

### client_a2.js
1. 未配置エージェントの行動はa1と同じです
2. 配置済エージェントの行動は8方向のうちランダムに動かしますがフィールド外へは移動しないようになっています

### client_a4.js
1. 未配置エージェントの行動はa1と同じです
2. 配置済エージェントの行動は8方向のうち最も高い点数のマスに移動します
    * ただし移動先のマスの状況に応じて点数が加算されます
        * 敵の陣地ならマスの点数に10点加算します
        * 空きマスならマスの点数に5点加算します
        * 敵の壁ならマスの点数に加算しません
    * もし8方向すべてが自分の陣地ならa2と同じように移動します
if文以外の条件分岐を使ってみる

Rubyの条件分岐はif文の他にもunlessという方法もあります。
if文は、条件式がtrueの場合に処理が実行され、falseのときはelseの後に記述した処理が実行されます。

```ruby
if 条件式
  条件式がtrueの時に実行する処理
else
  条件式がfalseの時に実行する処理
end
```

unless文は条件式がfalseの場合に処理が実行され、trueのときはelseの後に記述した処理が実行されます。

```ruby
unless 条件式
  条件式がfalseの時に実行する処理
else
  条件式がtrueの時に実行する処理
end
```

例えば、

```ruby
if a + b > 0
  puts "計算結果は0より大きいです"
end
```

のif文をunless文を使って記述したとすると、

```ruby
unless a + b <= 0
  puts "計算結果は0より大きいです" 
end
```

if文では0が含まれていないので、unless文では0以上とすることで同じような意味になります。