OmniAICreator/Qiita-1.07M huggingface dataset:
WebsocketとPhoenixとwscatでチャットの動作確認

# はじめに
PhoenixのChannelを使ったチャットの作成をするとき、jsでフロントの部分を作成していることが多かったが、jsのページを用意したりしなくても動作確認ができるようにしようと思って`wscat`を使ってみました。

まだ１対１のチャットを作成しようとしてる途中なので、１対１のチャットとしてはまだ機能ができていませんが、とりあえずwscatで動いてくれたので記事を書きました。(private_chatなのにlobbyがあって個別のchannelを用意できていない)

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352824/786e9459-32ad-1773-128a-42faaaf0fbc6.gif)

このように、２つのクライアントがChannelに接続されており、チャットの状態を共有しています。
左側のクライアントでチャットを送信すると右側にも反映されます。

## Websocketについて
このチャットで使うような`Websocket`というのは、通信で使われる**プロトコル**の一種です。
いつも使っているような`HTTP`は、クライアントからサーバーへリクエストを送ってデータをもらうというのが基本の型です。
リアルタイムなチャットを作成する際は、リクエストを送らずにデータを受信できるようにしたいので、HTTPではなく双方向通信が可能なWebsocketを使います。


## Phoenix側のコード
`mix phx.new`で何かしらのプロジェクトは作成してあるとして、Channelの部分を書いていきます。

```elixir:web/channels/user_socket.ex
defmodule PappapWeb.UserSocket do
  use Phoenix.Socket

  ## Channels
  # channel "room:*", PappapWeb.RoomChannel
  channel "private_chat:*", PappapWeb.PrivateChatChannel

  ...
end
```

```elixir:web/channels/private_chat_channel.ex
defmodule PappapWeb.PrivateChatChannel do
  use Phoenix.Channel

  # This function is called when client connects to this server.
  def join("private_chat:lobby", _msg, socket) do
    {:ok, socket}
  end

  def join("private_chat:" <> _private_room_id, _auth_msg, _socket) do
    {:error, %{reason: "unauthorized"}}
  end

  def handle_in("new_msg", %{"body" => body}, socket) do
    broadcast!(socket, "new_msg", %{body: body})
    {:noreply, socket}
  end
end
```

Websocketでサーバーに接続するときに、`join/3`が呼び出されます。
`join/3`の第一引数の`"private_chat:lobby"`というのは、**topic**と呼ばれます。
このtopicが一致しているチャンネルに接続すると、いずれかのクライアントが送信したメッセージがもう片方にも送信されます。

## wscat
wscatは、Websocketのサーバー/クライアントで、コマンドラインから利用できます。
`npm`でインストールして利用することができます。

```bash

npm i -g wscat
```

インストールが完了したら、このようにしてwscatを動かしてみることができます。

```bash
wscat -c http://localhost:4000/socket/websocket/
```

オプションの`-c`を指定すると、wscatをwebsocketを利用するクライアントとして動かすことができます。

では、実際にサーバーを起動して動かしてみます。

## 動作確認
まずはPhoenixのサーバーを起動します。

```bash
mix phx.server
```

サーバーが正常に起動できたら、次はwscatを使ってWebsocketでサーバーに接続します。

```bash
wscat -c http://localhost:4000/socket/websocket/
```

<img width="616" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352824/885af759-44d8-cd83-a9c9-663703298d15.png">

このように表示されたら接続成功です。
次は、チャットルームに入ってみます。

```
{"topic":"private_chat:lobby","ref":1, "payload":{},"event":"phx_join"}
```
このリクエストをwscatを使ってサーバーへ送信します。
**topic**の部分が、さっきphoenixに書いた`join/3`の引数のものと一致すれば成功すると思います。
次は、チャットを送信します。

```
{"topic":"private_chat:lobby","ref":1, "payload":{"body": {"msg": "hello"}},"event":"new_msg"}
```

wscatでこのリクエストを送信することで、チャットをサーバーへ送信できると思います。
ターミナルを２つ以上開いて、同時にwscatでサーバーに接続して同じトピックのチャンネルに接続すると、リアルタイムでチャットの様子を見ることができると思います。
ぼくはiTerm2を使っているので、`Command+d`で画面を分割して様子を見ました。

# さいごに
まだ完全なチャットは全然できていませんが、
とりあえずjsのページ以外からWebsocketを動かしてみることができました。

# 参考リンク

> https://qiita.com/south37/items/6f92d4268fe676347160
> https://tricknotes.hateblo.jp/entry/20120227/p1
Ruby でいけていない ヌメロン を作ってみた

# はじめに
とある事情により、いけていない`ヌメロン`を作ってみた。
後悔はしていない。

*[Numer0n - wikipedia](https://ja.wikipedia.org/wiki/Numer0n)*
# いけている ヌメロン
こちらの記事を参照しました。
*[[Ruby]数当てゲームのヌメロン作ってみた](https://qiita.com/wai-doi/items/f47f690cdc787c759d20)*
# ソースコード
```numeron.rb
d = []
while true
  d[102, 2] = rand(0..32767).divmod(10)
  d[101, 2] = rand(0..32767).divmod(10)
  d[100, 2] = rand(0..32767).divmod(10)
  break if d[101] != d[102] && d[102] != d[103] && d[103] != d[101]
end
puts "コールしてください"
while true
  x200 = gets.chomp
  d[111] = x200[0].to_i
  d[112] = x200[1].to_i
  d[113] = x200[2].to_i
  d[300] = 0
  d[400] = 0
  d[300] += 1 if d[101] == d[111]
  d[300] += 1 if d[102] == d[112]
  d[300] += 1 if d[103] == d[113]
  d[400] += 1 if d[101] == d[112]
  d[400] += 1 if d[101] == d[113]
  d[400] += 1 if d[102] == d[111]
  d[400] += 1 if d[102] == d[113]
  d[400] += 1 if d[103] == d[111]
  d[400] += 1 if d[103] == d[112]
  if d[300] == 3
    puts "3 EAT"
    break
  else
    puts "#{d[300]} EAT - #{d[400]} BITE"
  end
end
```
```rand.rb
  d[100, 2] = rand(0..32767).divmod(10)

  d[101] = rand(0..9)
```
`rand(0..9)`とリファクタリングしてはいけない。
こちらにも都合というものがあるです。
# まとめ
+ いけていない ヌメロンを作ってみた
+ 後悔 はしていない
+ Ruby に詳しくなった
Raspberrypiにdockerをインストールして使う

# 環境
RaspberryPi4 + raspbian buster

# Raspberrypiにdockerをインストールする手順

```
$ curl -sSL https://get.docker.com | sh
```

```
$ docker -v
Docker version 19.03.12, build 48a6621
```

```
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
4ee5c797bcd7: Pull complete 
Digest: sha256:49a1c8800c94df04e9658809b006fd8a686cab8028d33cfba2cc049724254202
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...
```

# 参考
[Docker comes to Raspberry Pi](https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/)
leafletを鍛える。その27

#概要

leafletを鍛えてみた。
geojsonを表示してみた。
amedas表示してみた。

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ed0b626b-872d-5d39-d277-3294cc4de20c.png)


#成果物

https://embed.plnkr.co/plunk/IifpWO0rzVX4M663

以上。
個人的によく使いそうなMarkDownメモ




##ナニコレ？
QiitaのMarkDownについて勉強していて、
チートシートのような感じでメモを取ったので、
共有します。

なお、実用性は(知ら)ないです。
Webが開けるなら↓がおすすめ
【Qiita マークダウン記法 一覧表・チートシート】
https://qiita.com/kamorits/items/6f342da395ad57468ae3

##↓こんな感じ


``` C#
/*


【MarkDownメモ】

■見出し、題名
[大]
# 見出し h1
## 見出し h2
※＿＿＿＿＿＿＿＿＿＿↑線がついてる
### 見出し h3
#### 見出し h4
##### 見出し h5
###### 見出し h6
[小]

■箇条書き、リスト

- リスト
- リスト
    - リスト

1. 番号付きリスト
2. 番号付きリスト
    1. 番号付きリスト	※タブで階層を下げることができます


■折り畳み
<details><summary>ここに折り畳みの題名</summary>
<div>

ここに詳細を書いてもろて

</div>
</details>

■引用
> text
>> text

■リンク
[ワイのTwitter](https://twitter.com/minikutku99)

■dl,dt,ddが使える　
※加工できない、赤文字とかにはできない　
※ただ、HTMLの\<strong>とか使える

■テーブル
3x3	と入力
テーブルを挿入を押す

↓をいじると右寄せにできたりする
|:-----------|------------:|:------------:|
※:の位置が違う

■水平線
***********************************

■注釈
注釈したい奴→ゴリラ[^1]
注釈の本体　→[^1]: なんだこいつ！

■取り消し線
~~見やすさもクソもないｗ~~

■フォントカラー
<font color="Blue">

□フォントサイズは見当たらなかった

*/
```

<details><summary>~~見やすさもクソもないｗ~~</summary>
<div>自分的使い方はメモ帳とかにコピペして、
ちらっと見る感じかな。
<br>ただ、他の人から見たらちょっと何言ってるかわからん文書になってる気がするので、
オススメできないね。（なんで書いた）
<br>後々追記されてくかも</div>
</details>
Laravel TinkerでSQLを確認するには

Tinker で実際に SQL を確認したくなったので、少し調べた。
`flushQueryLog()` が地味に便利かもしれない。

# 環境
- Laravel 7.20.0
- PHP 7.4.7
- MySQL 5.7.29

# 前提

**Tinker でいろいろ試しながらログを確認したい**  という場合を想定している。

# 手順

```
$ php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.7 — cli) by Justin Hileman
>>> DB::logging();
=> false

>>> DB::enableQueryLog();
=> null

>>> DB::logging();
=> true

>>> App\Memo::find(1);
=> App\Memo {#3940
     id: 1,
     title: "タイトル1",
     body: "本文1",
     is_published: 1,
     created_at: "2020-07-18 13:26:37",
     updated_at: "2020-07-18 13:26:37",
   }

>>> dump(DB::getQueryLog()) && DB::flushQueryLog();
array:1 [
  0 => array:3 [
    "query" => "select * from `memos` where `memos`.`id` = ? limit 1"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 103.03
  ]
]
=> false
```

# 説明

- `DB::logging()`
  - 現在のログ出力設定を確認する
      - `true` : ログ出力が ON である
      - `false` : ログ出力が OFF である

- `DB::enableQueryLog()`
  - ログ出力を ON にする
  - OFF に戻す場合は `DB::disableQueryLog()` を使う

- `dump(変数)`
  - 変数の中身を表示する（ [マニュアル](https://readouble.com/laravel/7.x/ja/helpers.html#method-dump) ）

- `DB::getQueryLog()`
  - ログを取得する

- `DB::flushQueryLog()`
  - ログの中身を空っぽにする

# 蛇足

`dd(DB::getQueryLog())` としている記事をよく見かけるけど、 `dd()` は Tinker を終了させるので、Tinker でいろいろ試したい人にはあんまり向かないように思う。
なので、 `dd()` のかわりに `dump()` を使っている。

また、デフォルトでは `getQueryLog()` をしてもログは消えないけど、連続で確認する場合、一度画面に表示したログは不要だろう。
なので、以下のように、 `dump()` したら速やかに `flushQueryLog()` を実行してログを空っぽにしている。

```
dump(DB::getQueryLog()) && DB::flushQueryLog();
```
D言語では +++ は許されるが &&& は場合による

[C/C++ では+++は許される](https://qiita.com/Nabetani/items/ea9e141f650492b9e147) を読んで書きました。

DとC++の演算子優先度は大体同じなので、`+++` とか `---` は同じように実行可能です。

```d:
import std;

void main()
{
    int a = 2, b = 3;
    auto c = a +++ b;
    writeln(a); // 3
    writeln(b); // 3
    writeln(c); // 5
}
```
実行：https://run.dlang.io/is/weJvOy

---

違いは `&&&` です。
これもC++同様、`a && (&b)` と解釈されて数値とポインタの `&&` になります。
結果は真偽値なので、数値が `0` またはポインタが `null` でなければ `true` ですね。

```d:OK
import std;

void main()
{
    int a = 2, b = 3;
    auto c = a &&& b;
    writeln(c); // true
}
```
実行：https://run.dlang.io/is/7rdtFO


ところが、D言語では `@safe` が付いている関数では危険なポインタ演算としてエラーになります。

```d:エラー
import std;

void main() @safe
{
    int a = 2, b = 3;
    auto c = a &&& b;
    writeln(c); // onlineapp.d(6): Error: cannot take address of local b in @safe function main
}
```
実行：https://run.dlang.io/is/FqaBl0

ポインタと数値の演算は危ないので禁止している言語も多く、こういう動作を期待することもありますね。

以上、その操作よく考えると危ないかもしれない、という話でした。

ちなみに仕様としては `Safe Functions` として、以下に禁止される操作がまとめられています。

- Safe Functions
    - https://dlang.org/spec/function.html#safe-functions
vscode上wxPython(及びtraitsui)にてDISPLAYエラー

# 環境
Ubuntu18.04
wxPython 4.0.4
Python 3.7

# 経緯
traitsuiのHello worldが動かなかったので、そもそもtoolkitとして使用しているwxPythonが動くのか以下のHello Worldコードで確認しました。

``` python
# First things, first. Import the wxPython package.
import os
import wx

# Next, create an application object.
app = wx.App()
print(app.IsDisplayAvailable())

# Then a frame.
frm = wx.Frame(None, title="Hello World")

# Show it.
frm.Show()

# Start the event loop.
app.MainLoop()
```

すると以下のようなエラー"Unable to access the X Display, is $DISPLAY set properly?"に。
![Screenshot from 2020-07-18 14-15-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485117/595d0b5e-af85-03c3-a1bb-acd7f9a078dc.png)


ターミナルにて"DISPLAY=:0"とか打ったり、launch.jsonにてenv変数にてDISPLAYを設定してもダメでした。

#解法
結局、以下の様にコード上で環境変数指定して解決できました。

``` python
# First things, first. Import the wxPython package.
import os
import wx

os.environ["DISPLAY"] = ":0"

# Next, create an application object.
app = wx.App()
print(app.IsDisplayAvailable())

# Then a frame.
frm = wx.Frame(None, title="Hello World")

# Show it.
frm.Show()

# Start the event loop.
app.MainLoop()
```

以下は表示されたウィンドウです。
![Screenshot from 2020-07-18 14-21-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485117/2ae8c00f-ca2d-2fa5-ac42-2e65068bc664.png)


#考察
そもそも、vscodeのターミナルにおいてはxeyesが`xeyes -display :0`としなければ表示できませんでした。加えて、通常のターミナルにおいては、特に対策を行わなくてもHello World表示はできていたので、vscodeのターミナル実装に問題があるようです。
has_secure_password でパスワードの暗号化を行った Rails model のテストデータを fixture で作る

## 概要
has_secure_password でパスワードの暗号化を行う様にした model を使うメソッドを Minitest でテストする為に fixture でテストデータを投入しようしたら、テーブルには password というカラムはありませんというエラーでテストコードが通りませんでした。
fixture で password_digest カラムに暗号化した値を入れてテストデータを作る方法を調べました。
調べるのに時間がかかったので、解決方法を残します。

## 環境
Rails 6.0.3

## モデル
```
class Hoge < ApplicationRecord
  ...
  has_secure_password
end
```

## エラーになった fixture
```
hoge_hoge:
  ...
  password: password
```

## 出ていたエラー
```
ActiveRecord::Fixture::FixtureError: table "hoges" has no columns named "password".
```

## 原因
fixture では has_secure_password で追加される password アクセサは使えず、 ERB を使って ruby のコードを実行しなければいけなかった様です。

## 修正した fixture
```
hoge_hoge:
  ...
  password_digest: <%= BCrypt::Password.create('password') %>
```

テーブルのカラム名である password_digest に BCrypt::Password.create を使って生成した値を入れています。

## 参考にさせて頂きました。

(fixtureでpassword_digestに直接暗号化した値を指定する方法 https://stackoverflow.com/questions/30894771/rails-fixtures-with-bcrypt)

(フィクスチャのしくみ https://railsguides.jp/testing.html#%E3%83%95%E3%82%A3%E3%82%AF%E3%82%B9%E3%83%81%E3%83%A3%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF を参照）
Laravelドキュメント日本語訳サイト

#Laravel公式ドキュメントの日本語訳サイト
Laravel公式ドキュメントを日本語訳してくれているサイト。
私のように日本語しかわからないエンジニアにとっては、とてもありがたい存在。

[ReadDouble]
[https://readouble.com](https://readouble.com)

Laravelを学び始めたエンジニアは、かなりの高確率でお世話になっているのでは？

私だけかもしれませんが、初めて閲覧した時、インストール手順以外の項目に、すぐ辿り着けず、ちょっと悩んだので、備忘録兼ねて。

1. [Laravel公式ドキュメントの日本語訳サイト](https://readouble.com)にアクセスします。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646252/0e36393a-71c7-5d7d-f4cf-5b9c15146afb.png)

1. Laravelのバージョンを選択します。
![1.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646252/fa4a06e1-51ee-fc1b-dc22-89fb5b97f636.png)
※ここでは、「7.x」を選択します。

1. 左上角に配置された、本のアイコンをクリックします。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646252/62aa4167-9572-29ef-e99b-8cbfb8e1c66c.png)

1. メニューが開くので、必要な項目を選択します。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646252/78cb3ffe-e6aa-3b47-b347-b2f4e8505d4d.png)
TypeORMエンティティの現実的な設計

TypeORM便利ですね。
TypeORMはまだ未成熟ですが、それでもTypeORMが便利である最大の理由は、TypeScriptによる強力な静的解析の恩恵を受けられることです。
これにより、Java等の他の静的型言語で実装した場合はユニットテストか実行時エラーでしか検出できなかったエラーを実行時に検出できるようになります。

今回扱うのはいかにもJavaっぽいアノテーションもりもりのエンティティです。ここをうまく扱えなければTypeORMのメリットが半減してしまいます。

# 案1: よく見かける例
```ts
@Entity()
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @CreateDateColumn()
  createdAt: Date;
}
```

サンプルでもっともよく見かける例です。シンプルで分かりやすいのですが、様々な問題点があります。

## saveが失敗する

上記の例では`name`は必須フィールドですが、

```ts
const user = new User();
UserRepository.save(user);
```

のようなコードがコンパイルエラーなしで通ってしまい、

## strictPropertyInitializationが使えない

TypeScriptの`strictPropertyInitialization`は、`undefined`でないクラスのフィールドがコンストラクタで初期化されることを保障するための設定です。正直言って**神機能**です。

```ts
class Person {
  name: string;
  age: number; // 後から追記した
  constructor(name: string) {
    this.name = name;
  }
}
```

上記の例では、コンストラクタでageフィールドが初期化されていないため、

```ts
new Person('Taro').age.toString();
```

などが実行時エラーとなってしまいます。これは危ない。しかしながら、`strictPropertyInitialization`さえ有効にしていれば、このようなバグを未然に防ぐことができます。

# 案2: コンストラクタで初期化しちまえ！

こちらの方が安全性が高いでしょうか。

```ts
@Entity()
export class User {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column()
  name: string;

  @CreateDateColumn()
  createdAt!: Date;

  constructor(name: string) {
    this.name = name;
  }
}
```

この手法の問題点は、**コンストラクタの仕様変更が怖くてできない**ことです。例えば、

```ts
constructor(firstName: string, lastName: string);
```

が、

```ts
constructor(lastName: string, firstName: string);
```

にいつの間にか入れ替わっていたとしたら・・・？恐ろしいバグが発生してしまいます。また、フィールド数が増えたときにコンストラクタが長いとソースコードが読みにくくなってしまうのも辛いところですね。

# 現実的な解: AutoGeneratedなカラムをOmitしたオブジェクトをObject.assignする

賛否両論あると思いますが今のところこれで落ち着きました。

```ts
@Entity()
export class User {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column()
  name!: string;

  @CreateDateColumn()
  createdAt!: Date;

  constructor(properties: UserInitializationProperties) {
    Object.assign(this, properties);
  }
}

export type UserInitializationProperties = Omit<User, 'id' | 'createdAt'>;
```

この手法のメリットとしては、

* 新しいフィールドを追加したとき、何もしなければエラーとなる
  * 追加したフィールドはOmitされないので、コンストラクタの引数に渡すオブジェクトの必須フィールドとなります。
* `Rename Symbol`でフィールド名を簡単に変更できる
  * 例えば`name`フィールドを`namae`に変更しようと思ったとしても、VSCodeならF2キーを押すだけで簡単に変更できます。幸せ。

「こうしたほうがいいよ！」等ありましたら是非教えていただければと思いますm(_ _)m
文字列を一文字ごとに分割する

# 追記

コメントで @masakihori さんに教えて頂きましたが

```swift
let arr = Array(str)
```

これで済みます。

---


文字列を一文字ごとに分割

```swift
var str = "あいう \naiu"

var arr: [String] = []
for i in 0...(str.count - 1) {
    let idx = str.index(str.startIndex, offsetBy: i)
    arr.append(String(str[idx]))
}
print(arr)
```

```swift:output
["あ", "い", "う", " ", "\n", "a", "i", "u"]
```
Pandasのlocの仕様が変わったのでメモ



```python
data = [[1,2,3],[4,5,6],[7,8,9]]
col = ['A','C','E']
df = pd.DataFrame(data, columns=col)
#   A  C  E
#0  1  2  3
#1  4  5  6
#2  7  8  9
```

Pandas 0.23以前ではこれに対してlocで項目にA,B,Cと指定すると
データにない項目名はすべて欠損値として作成されていた。

```python
sel_col = ['A','B','C']
print(df.loc[:,sel_col])
#version 0.23以前の場合
#   A   B  C
#0  1 NaN  2
#1  4 NaN  5
#2  7 NaN  8
```


しかしPandas 1.0以降では以下のようなエラーが出るようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259220/ac80a512-bb3e-1f9e-f4bd-2d4e9dc15082.png)

どうやらデータフレームにない項目を指定してはいけないことになったらしい。
以前と同じようにデータフレームにない項目は欠損として作りたい場合は代わりにreindexを使えば可能だ。

```python
sel_col = ['A','B','C']
print(df.reindex(columns=sel_col))
#   A   B  C
#0  1 NaN  2
#1  4 NaN  5
#2  7 NaN  8
```

もしくはデータフレームに含まれる項目のみを表示させたい場合は以下のように
データフレームの項目と指定項目のintersectionをとることができるらしい。

```python
print(df.loc[:,df.columns.intersection(sel_col)])
#   A  C
#0  1  2
#1  4  5
#2  7  8
```
heroku: deploy next.js

deploy next.js app to heroku

```.sh:terminal
# set up nextjs app
git clone https://.../your-nextjs-app.git

# add a new remote branch named as heroku which connects to the heroku server
cd your-nextjs-app
heroku create

# create procfile (set command for heroku server to run app)
vim Procfile
```

```.sh:Procfile
# YOU MUST SET PORT as $PORT, NOT a NUMBER LIKE 3000 or 8080. because heroku randomly assigns port nubmer to the deployed app 
npx next start -p $PORT
```

```.sh:terminal
# deploy your app to heroku server
git push heroku 

# open page
heroku open
```
【Python】データサイエンス100本ノック（構造化データ加工編） 003 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/bR1-GEwxg6g)もしています。

##問題
P-003: レシート明細のデータフレーム（df_receipt）から売上日（sales_ymd）、顧客ID（customer_id）、商品コード（product_cd）、売上金額（amount）の順に列を指定し、10件表示させよ。ただし、sales_ymdはsales_dateに項目名を変更しながら抽出すること。

##解答
```:コード
df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \
.rename(columns={'sales_ymd': 'sales_date'}).head(10)
```

##出力
|  | sales_date | customer_id | product_cd | amount |
|--:|--:|:--|:--|--:|
| 0 | 20181103 | CS006214000001 | P070305012 | 158 |
| 1 | 20181118 | CS008415000097 | P070701017 | 81 |
| 2 | 20170712 | CS028414000014 | P060101005 | 170 |
| 3 | 20190205 | ZZ000000000000 | P050301001 | 25 |
| 4 | 20180821 | CS025415000050 | P060102007 | 90 |
| 5 | 20190605 | CS003515000195 | P050102002 | 138 |
| 6 | 20181205 | CS024514000042 | P080101005 | 30 |
| 7 | 20190922 | CS040415000178 | P070501004 | 128 |
| 8 | 20170504 | ZZ000000000000 | P071302010 | 770 |
| 9 | 20191010 | CS027514000015 | P071101003 | 680 |

##解説
・PandasのDataFrame/Seriesにて、列を指定しつつ、列名を変更して、先頭データを確認する方法です。
・列情報を絞り、かつ、列名をわかりやすく変更して確認したい時に使用します。
・**'<データ名>[[<列名A>,<列名B>,<列名C>]].rename(columns={('<列名A>':'<列名D>')}).head(n)'**で、先頭n行目までの指定した列(列名A,列名B,列名C)のうち、列名A を 列名Dに変更した上で順番(列名D,列名B,列名C)に表示します。
・**' \ 'は、見やすいように、コードを改行するために入れています。**
LPWAを MQTT-SNで使ってみた（2）

# LoRaWANとLoRaLink MQTT-SNの違い
## LoRaWAN
LoRaWANはLoRaWAN end-node(EN)とGateway(GW),Network Sever(NS), MQTT Broker(MB)で構成されている。GWにはインテリジェントな機能はなく、受信したLoRaWANパケットを全て自分が所属するNSへUDPで送信する。　NSは送られてきたパケットのうち自身に登録されているENのものだけを拾い出しENに応答を返す。自分のネットワークに所属するENからのデータは暗号を復号してMBへ送信する。ユーザはENから送られたデータをMQTTでMBから取り出して使用する事になる。　MBにはデータを保存する機能は含まれないため、MBから取り出したデータはDB等に保存する必要がある。
またend-nodeは各社が提供するLoRaWANデバイスを使うか、LoRaWAN用の通信デバイスを購入してArduinoやSTMなどのMCUを外付してデバイスを製作する必要がある。![LoRaWAN2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41752/1e1e3f57-264a-afd7-36a6-bc447d9e0fd2.png)
LoRaWANゲートウェイは他者のデバイスのデータを区別せずに送信することから有償サービスの場合は通信事業者の所有物として設置しなければならない。　TheThingsNetworkは日本で唯一無償でLoRaWANサービスを提供している。これを使用する場合は個人でゲートウェイを設置できる。しかしDwelltime1をサポートできるマルチチャンネルのゲートウェイの技適が取得されていない。
## LoRaLink MQTT-SN
LoRaLinkを使用したMQTT-SNの最大の違いは自分が管理していないデバイスのデータはGWが受信しないということだ。そのためGWを個人で自由に設置できる。　そもそも、LoRaWANのような全国にまたがるサービスの提供は考えておらず、農地や地域の一部などで一日二回程度の送信がボタン電池一個で一年間できるようなことを想定している。
ネットワークの構成はLoRaWANよりシンプルで全て自前で用意することが容易である。
![LoRaMQTT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41752/6015ea5c-c344-ca31-db6c-9f71201ae40f.png)
次回はSX1276+MCUデバイスについて解説する。
【PowerShell】コマンド出力結果を変数に入力する方法

# はじめに
コマンド出力結果を変数に入力する方法をアウトプットします。

# コマンド

```powershell:command
 <変数> = <実行したいコマンド>
```

## 実行例

```powershell:実行コマンド例
$test = Get-Host
Write-Output $test 
```

```powershell:実行結果
PS C:\Users\Administrator> C:\Users\Administrator\Desktop\scripts\dns_check\test.ps1


Name             : Windows PowerShell ISE Host
Version          : 5.1.17763.1007
InstanceId       : 02356453-d661-49b1-9bff-29f1aa00ea35
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : ja-JP
CurrentUICulture : ja-JP
PrivateData      : Microsoft.PowerShell.Host.ISE.ISEOptions
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

PS C:\Users\Administrator>  
```

# よく使用するテクニック

## コマンド実行結果の中の1つのオブジェクトのみ入力したい場合

```powershell:実行コマンド
$test = Get-Host | Select-Object Name
Write-Output $test 
```

```powershell:実行結果
PS C:\Users\Administrator> C:\Users\Administrator\Desktop\scripts\dns_check\test.ps1

Name                       
----                       
Windows PowerShell ISE Host

PS C:\Users\Administrator>  
```

## 特定の行のみ抜き出す方法

### 例1

```powershell:実行コマンド
$test = Get-Host | Out-String -Stream | Select-String "ISE"
Write-Output $test 
```

```powershell:実行結果
 PS C:\Users\Administrator> C:\Users\Administrator\Desktop\scripts\dns_check\test.ps1

Name             : Windows PowerShell ISE Host
PrivateData      : Microsoft.PowerShell.Host.ISE.ISEOptions

PS C:\Users\Administrator>  
```

### 例2

```powershell:実行コマンド
$test = Get-Host | Select-Object Name | Out-String -Stream | Select-String "ISE"
Write-Output $test 
```

```powershell:実行結果
PS C:\Users\Administrator> C:\Users\Administrator\Desktop\scripts\dns_check\test.ps1

Windows PowerShell ISE Host

PS C:\Users\Administrator>  
```
rails test をしたときの ActiveRecord::NoDatabaseError を解決する (Railsチュートリアル 3章)

自分がrailsチュートリアルを進めていく上で、発生したエラーを記録していきます。
ハードはMacBook Air, 開発環境はVScodeを用いています。

#Rails チュートリアル 3章 3.3.1 最初のテスト

```:実行するコマンド
$ rails test
```

```:発生するエラー
$ rails test
~省略~
~省略~ FATAL:  database "tutorial_test" does not exist (ActiveRecord::NoDatabaseError)
```

これは、**データベースがありません！**というエラーです。rails testをするときも、**テスト用のデータベースを作成する必要があります。**

#解決方法 データベースを生成する

そこで、コマンドでデータベースを生成します。

```:データベースを生成するために実行するコマンド
$ rails db:create
```
>ちなみに

>```
$ rake db:create
```
でもできます。これについては、こちらの記事が参考になります。[Railsのrakeってなんぞ？](https://qiita.com/SuguruOoki/items/e736b15bbb80eacf66d7)

このコマンドでは、config/database.yml の内容に沿ってデータベースが生成されます。

```:実行結果
$ rails db:create

Created database 'アプリ名_development'
Created database 'アプリ名_test'
```

このように表示されると、データベースが正常に生成されたことになります。

####ここまできたら、$ rails test が正しく通るはずです！

役に立ったら是非**LGTMボタンをポチッと押していただけると嬉しいです。**
一緒に Rails学習 頑張りましょう！:raised_hand_tone1:
【Ruby】キーワード付き引数と引数のデフォルト値について

##はじめに
バージョン
ruby 2.6.3
rails 5.2.3

キーワード付き引数についてよく理解していなかったのでハマりました。
イコールを使ってただのデフォルト値付きのメソッドを定義していたにも関わらず、メソッド呼び出しの際にキーワード付き引数の呼び出し方をしていた為、意図しない引数が渡っておりエラーが発生していた。
###今回のミス
```ruby
#デフォルト値付き引数でメソッドを定義
def hello(lang = "ja", place = "Japan")
 puts "#{lang} : #{place}"
end

#キーワード付き引数の呼び出し方
hello(lang: "en", place: "America")
#=>
{:lang=>"en", :place=>"America"} : Japan
```
引数がハッシュとして解釈されて意図しない引数が渡ってしまった。

<br>

###キーワード付き引数について
参考　https://qiita.com/jnchito/items/74e0930c54df90f9704c

```ruby
def hello(lang: "ja", place: "Japan")
 puts "#{lang} : #{place}"
end

#引数なしの呼び出し
hello
#=>
ja : Japan

#キーワードありで引数の値を変更して呼び出し
hello(lang: "en", place: "America")
#=>
en : America

#キーワードのない引数で呼び出し
hello("en", "America")
#=>
wrong number of arguments (given 2, expected 0) 
```
キーワード付き引数を持つメソッドを引数なしで呼び出すとデフォルト値でメソッドが呼び出される。
キーワードのない引数で呼び出そうとするとエラーが発生する。

###デフォルト値を持つ引数について
参考　https://rooter.jp/programming/ruby_method_default/

```ruby
def hello(lang = "ja", place = "Japan")
 puts "#{lang} : #{place}"
end

#引数なしの呼び出し
hello
#=>
"ja : Japan"

#キーワードのない引数で呼び出し
hello("en", "America")
#=>
en : America
```
ESLintのカスタムルールで条件文の判定に関数を使うのを禁止しよう

# 禁止するコード

```javascript
function func(num) {
    return num === 0;
}

if (func) //付け忘れ
    console.log("zero");

class A {
    func(num) {
        return num === 0;
    }
    method() {
        if (this.func) //付け忘れ
            console.log("zero");
    }
}
```

条件文の判定部分に関数を使い、`()`を付け忘れている。

条件文の判定部分に`()`を付けない関数を使うことを禁止するESLintのカスタムルールを作成する。

# 正しいコード

```javascript
function func(num) {
    return num === 0;
}

if (func()) //()を追加
    console.log("zero");

class A {
    func(num) {
        return num === 0;
    }
    method() {
        if (this.func()) //()を追加
            console.log("zero");
    }
}
```

# ESLintのカスタムルール

[no-cond-func](https://github.com/querykuma/snippets/blob/master/eslint-rules/no-cond-func.js)を作った。

`--fix`(自動修正)にも対応した。

# 動作確認

```shell
> eslint test.js

   7:1  error    evaluate function as condition  rulesdir/no-cond-func
  20:9  error    evaluate method as condition    rulesdir/no-cond-func
```

`eslint-plugin-rulesdir`を使っているので、コマンドラインオプションに`--rulesdir rules`がない。

# PoC

以前の記事でin+配列を禁止するカスタムルールがESLintに追加されたら嬉しいと望んだ。

しかし、ESLintのガイドを読んだら

>  As of 2020, we only accept rules related to new ECMAScript features.　We prefer that new rules be implemented in plugins.

新しいECMAScriptの特徴に関するルールだけを受け入れる。

> Keep in mind that we have over 200 rules, and that is daunting both for end users and the ESLint team (who has to maintain them). As such, any new rules must be deemed of high importance to be considered for inclusion in ESLint

200以上のルールがあってエンドユーザーと（それらを維持しなければならない）ESLintチームをひるませる。

ESLintに入る新しいルールは超重要なものでなければならない。

> Implementation is Your Responsibility
> The ESLint team doesn't implement new rules that are suggested by users because we have a limited number of people and need to focus on the overall roadmap.
> Once a rule is accepted, you are responsible for implementing and documenting the rule. 

ESLintチームは限られた人員しかいないので、ユーザーが提案した新しいルールを実装しない。

ユーザーにルールの実装と文書化の責任がある。

とあった。

<br>

ESLintチームの状況はこのようになっている。

新しいルールは、新しいECMAScriptの特徴に関係する超重要なものでないならプラグインで作り、npm パッケージを作って公開することになる。

# 関連記事

[ESLintのカスタムルールでin+配列を禁止しよう](https://qiita.com/querykuma/items/d4b0a2c7a705dbec53dc)

[ESLintでプログラミングを快適にしよう](https://qiita.com/querykuma/items/5fc177f426bb53802efa)

[New Rules - ESLint - Pluggable JavaScript linter](https://eslint.org/docs/developer-guide/contributing/new-rules)

# おわりに

もし[no-in-array](https://github.com/querykuma/snippets/blob/master/eslint-rules/no-in-array.js)や[no-cond-func](https://github.com/querykuma/snippets/blob/master/eslint-rules/no-cond-func.js)のカスタムルールを使いたい人がいたら、`eslint-plugin-rulesdir`を使って使ってみてください。
DockerのMySQLコンテナを日本語対応させる

[『SQL ゼロからはじめるデータベース操作』](https://www.shoeisha.co.jp/book/detail/9784798144450)の演習をDocker & MySQLでやろうとして、日本語が入力できない現象につまづいた時のメモです。

##最終的な構成
全部同じ場所に置いてください

```yml:docker-compose.yml
version: "3"

services:
  mysql:
    build:
      context: .
    environment:
      MYSQL_ROOT_PASSWORD: "password"
      MYSQL_USER: "root"
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:
    driver: local
```

```Dockerfile:Dockerfile
FROM mysql:5.7

RUN apt-get update
RUN apt-get -y install locales-all

ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8

COPY mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf
```

```:mysqld_charset.cnf
[mysqld]
character_set_server=utf8
character_set_filesystem=utf8
collation-server=utf8_general_ci
init-connect='SET NAMES utf8'
init_connect='SET collation_connection = utf8_general_ci'
skip-character-set-client-handshake
```

## 内容
### ①Debianのlocaleを設定する
環境変数でlocaleを日本に指定しないとそもそもコマンドラインで日本語を打つことが出来ないようです。

以下の記事を参考に設定します。
[[Debian]Debian stretchのDockerコンテナを日本語化する](https://tech.chakapoko.com/linux/debian/stretch-ja.html)

### ②MySQLの文字コードをutf8に設定する
今度はMySQL側の設定です、MySQLはデフォルトでlatin1という日本語を扱えない文字コードが設定されているのでこれをutf8に変更します。

コンテナ内部のMySQL設定を変更するには一工夫必要で、設定情報を書いた`.cnf`ファイルを`/etc/mysql/conf.d/`以下に配置することで設定を反映させます。
この辺はググれば情報が出てくると思うので適宜調べてください。

以下を参考にしました。
[dockerのMySQLのutf8文字コードのイメージを作る](https://daichan.club/docker/78379)

## 最後に
Docker便利ですけど環境変数や設定周りでつまづくことが多くて大変…
pythonでbit全探索する際のスニペット

# pythonでbit全探索したい

自分用のメモ。気が向いたらちゃんと書き直す。

ある10進数の数字xをn桁の2進数にしたいことがある。(主にbit全探索の時に)
その時にformatとかを使ってもよいが、書き方が覚えられなかったので、
よく使う方法をメモ。

忘れた時用のコードの解説。
`bin(x >> i)`でxを2進数にしたものを一桁ずつずらしていく。
そのずらした数字の一番下の桁の数字だけが欲しいので2で割った余りを計算する。
2で割った余りを計算するためにはbitシフトしたものをintに戻す必要があるので
`int(bin,2)`として2進数のものを10進数に戻している。
`x_array_bin`に代入する順番を入れ替えれば、ちゃんと`[0,0,0,1,1]`と出来るが、
bit全探索ではあまり関係がないのでこのままにしてある。


```python

x = 3
n = 5
x_array_bin = [0 for _ in range(n)]
for i in range(n):
        x_array_bin[i] = int(bin(x >> i),2)%2

print(x_array_bin)

#[1, 1, 0, 0, 0]
    

```
TomcatでJavaServletアプリをローカルでデプロイする

#TomcatでServletアプリをデプロイする方法

やること自体は単純なのですが、意外といろいろな記事を読んでも重要な部分が書いていなくて、頭を抱えたので、備忘録がてら書いています。

##1.準備

###a.Eclipseなどから自分のServletアプリをwarファイル形式でエクスポートする

Eclipseからは動的プロジェクトのファイルを右クリックでエクスポート>War形式でエクスポート、を選択し任意のディレクトリにwarファイル形式でエクスポートしておきます。

![スクリーンショット 2020-07-18 12.29.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485150/3fac72d6-cd7e-f0ca-52c6-bd58fef60414.png)

###b.Tomcatのインストール

これらはEclipseから元々Tomcatを起動してローカルサーバで試しているよ、という場合には不要ですが、ない場合にはインストールが必要です。

こちらのサイトからzipファイルなどで自分のPCにインストールします。
http://tomcat.apache.org/download-80.cgi

Windowsの場合は、bit数に合わせてインストールファイルが違うようですので、自分の環境にあったものをインストールしてください。(Macの場合はzipファイルをダウンロードすればOKです。)

![スクリーンショット 2020-07-18 12.59.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485150/f4756c8d-d527-1446-1b42-4e440a746345.png)

###c.インストールしたファイルをunzipする

ダウンロードしたファイルを開き、webappsファイルに行きます。

ファイルの中身は以下の通り。ここからwebappsに行きます。

![スクリーンショット 2020-07-18 13.02.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485150/8dd88464-4e7e-b43d-847a-49c75541275c.png)

このwebappsディレクトリにaでエクスポートしておいたwarファイルを置きます。

###d.Tomcatのパーミッションを変更する

このあとインストールしたTomcatフォルダ内のシェルファイルもしくはバッチファイルを起動するのですが、デフォルトではパーミッションが644になっており、起動できない場合があるため、その場合は以下のコマンドにて変更。

```
$ cd /Applications/apache-tomcat-8.5.57
$ chmod 755 *.sh
```

##2.Tomcatを起動する

以下コマンドでTomcatのシェルファイルを起動します。

```
$ ./startup.sh
```

そうすると、先ほどwebappsディレクトリにおいたwarファイルがコンパイルされて、同名のファイルがwebapps配下に作成されます。

https://localhost:8080/app名

成功すれば、このURLからアクセスできるようになります。

終了する場合は、以下のコマンドを入れます。


```
$ ./shutdown.sh
```
sshを介してリモートの処理をpipeで繋ぐ

2020/7/18 @angel_p_57さんのご指摘により、不要なお気持ちcat（`ssh USER@HOST "cat | ..."`としていたもの）を取り除きました。ありがとうございます。

--------------------

例えば下のpipeの処理

```sh
$ seq 1 50 | shuf | grep 1
```

`shuf`だけsshで繋いでいるリモートマシン上でやりたいときに下のように書ける。

```sh
$ seq 1 50 | ssh USER@HOST shuf | grep 1
17
13
18
15
19
16
11
1
12
14
10
```

ローカルのpythonスクリプトをリモートで動かしたい時はこれ。

```sh
$ cat script.py | ssh USER@HOST python3
```

本当にリモートで実行されているか確認:

```sh
$ echo "import os; os.system('hostname')" | ssh USER@HOST python3
```
Thinkpad X1C 5th  携帯電話が消えた

Thinkpad X1C 5thを持っていたが，これまでたまにしか使わなかった．
このX1Cには携帯SIMをさせ，安いSIMデータ通信を利用できるようにしてあった．
Windows10を2004に更新したので持ち歩き用としたらが，電車の中で通信ができない．
ネットワークに「携帯電話」が含まれていない，消えた，どうしてだろう．

そこで次の作業をした．
（１）Windowsのアップデート
（２）Lenovoのアップデート（BIOSとかドライバとか）
（３）再起動
再起動後とくに変化がなく，相変わらず「携帯電話」がネットワークに表示されなかった．

やっぱりだめか．
（２）の更新後，Sierraのドライバも更新したというログがでるのだが，
（２）を再実行すると同じようにSierraのドライバが更新リストに現れる．
これ，結局更新できていないのかもしれない．
あるいは，デバイスが認識されていないのか？

すこしGoogleで検索したが，状況がよくわからなかった．
ただ，「デバイスが壊れたので交換した」というブログを一つ見つけた．
このデバイス，壊れることがあるのか・・・．

アマゾンでSierra　EM7430 for Lenovoのデバイスがあったので購入した．
15k円くらいしたが，このままでは格安とはいえSIM契約が無駄だ．

そこで次の操作をした．
（１）新しいEM7430に交換
（２）Windowsのアップデート
（３）Lenovoのアップデート（BIOSとかドライバとか）
（４）再起動
再起動後とくに変化がなく，相変わらず「携帯電話」がネットワークに表示されなかった．

しかし，そこで「あーあ，だめか」と思ってうだうだ（数分）していたら画面の右下に「モバイルネットワークデバイスの更新」という小窓が開き，なにやら更新が始まった．

更新終了後にネットワークを確認すると「携帯電話」の項目が出現した．
なんと．

正直，EM7430が壊れていたのか，更新が効いたのかの判断はつかないが，結果的にSIM回線によるネットワークが使えるようになったのでこれで「良し」とする．
投稿してもまたLGTMが0・・・、せや拡張機能で見た目だけでもバズった様に見せよう！！


![computer_man3_cry.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/acf9bd9e-3272-b162-5579-4482719852e5.png)

Qiitaで記事を書けども書けどもLGTMがつかへん・・・

何となくLGTM押してくれればええのに・・・
せめて見かけだけでもええからLGTMが欲しい・・・

エンジニアやったら自分でプログラム作って色々できるのに・・・

![computer_man1_smile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/63701156-a7d6-350d-4336-b60c860319e5.png)

せや、ワイ今年からエンジニアなったんや！
拡張機能作って何とかしてみるで！！

## 自作拡張機能①
![internet_kanki_man1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/a82cf43f-dbad-72ca-ede1-32c82f91a855.png)



<img width="111" alt="スクリーンショット 2020-07-17 1.11.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/666cb8a1-16d2-f49a-37d9-8cc31c35f359.png">
が
</a><img width="111" alt="スクリーンショット 2020-07-17 1.10.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/cc933b5c-665f-6e70-c6d8-e910609b73c0.png">

ほな！たった2行で完成や！
初めて拡張機能作ったのにワイ天才や！

```iWantLgtm.js
var like = document.getElementsByClassName('it-Actions_likeCount');
like[0].textContent = '777';

```

```manifest.json
{
  "name": "qiita",
  "version": "1.0.0",
  "manifest_version": 2,
  "description": "qiitaのLGTMをパッとみ偽装するアドオン",
  "content_scripts": [{
    "matches": ["https://qiita.com/*"],
    "js": [
      "iWantLgtm.js"
    ]
  }]
}
```

せやけど、これやと無条件にLGTM変えてまうなぁ
ワイ謙虚やから条件でも追加したろ

## 自作拡張機能②
![syokuji_computer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/82a3c0c8-111e-25b7-19fb-cf1808177e4c.png)

0件の記事だけLGTMが増える様にしたで
ワイ謙虚やなぁ〜

```iWantLgtm.js
var like = document.getElementsByClassName('it-Actions_likeCount');

//LGTMが0だった場合はLGTMを777に変える
if (like[0].textContent == 0){
    like[0].textContent = '777';
}
```

ただ、これや人様の記事のLGTMも変えてまう・・・
manifest.jsonのmatchesでURL絞るのありやけどそれは少しださいし、自分のIDを入力できる様にするのは実装が・・・


## 自作拡張機能③
![tonarino_shibafu_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/15770cfd-7b2b-79b8-971a-72b9a4599d35.png)

view数が表示されるのは自分の書いた記事だけやがな！
それを条件にすればええんや！！

```iWantLgtm.js
//自分の投稿のみ処理を行う(view数のdivが存在するか確認している)
if(document.getElementsByClassName('it-Header_pv').length){

    var like = document.getElementsByClassName('it-Actions_likeCount');

    //LGTMが0だった場合はLGTMを777に変える
    if (like[0].textContent == 0){
        like[0].textContent = '777';
    }
}
```

これで完成や！
ワイの記事はみなLGTMが777になったで！！


## 参考サイト
<a href="https://osaka.uda2.com/">関西弁変換</a>

<a href="https://chrome.google.com/webstore/detail/qiitaaddlgtm/icekodeccdcbknneciedhodoggccghba?hl=ja&authuser=0">アドオンが審査とったので掲載しておきます。</a>
【JavaScript】乱数　（範囲指定）

#はじめに
勉強したことを自分のメモ代わりに残します。


#乱数

JavaScriptで乱数を作るには、「Math」オブジェクトの「random()」メソッドを使用します。

```javascript:js
var random = Math.random();
//生成した乱数（ Math.random() ）を変数randomに代入 
 
console.log( random );

```


出力結果


```
0.8023803655112587
```

Math.random()」は0〜1未満（1は入らない）までの小数による乱数を生成することができます。


#乱数の範囲指定

「0 〜 10」の範囲で乱数を作るプログラムを例に作ってみます。


```js:js
var random = Math.random() * 11;
 
console.log( random );

```

出力結果

```
7.51600326571613
```

範囲を決めた乱数を作るときには、「Math.random()」に最大値を掛けることで作る事ができます。

しかし「Math.random()」は0〜1未満（0〜0.9999････）の少数を返します。
「0 〜 10」の範囲を作りたい場合、最大値の10をそのまま掛けてしまうと「0 〜 9」の範囲になってしまうというわけです。

なので、最大値に1を足して「11」を掛けることで、「0 〜 10」の範囲を設定する事ができます。

また「Math.random()」は小数点の乱数を生成するので、これを扱いやすい整数に変える必要があります。

##Math.floor()

```js:js
var random = Math.floor( Math.random() * 11 );
 
console.log( random );

```

Mathオブジェクトの「floor()」メソッドを使えばOKです！
出力結果

```
7
```

となります。


##「最小値 〜 最大値」

「最小値 〜 最大値」を任意に決めて乱数の範囲を作る事ができます。

```
Math.random() * ( 最大値 - 最小値 ) + 最小値;
```
最大値と最小値を入れてあげる事で任意の範囲を指定する事ができます。

「最大値」についてですが、上記でもあったように例えば「0 〜 10」であれば、10に1を足した「11」が「最大値」であるという点に注意しましょう。


サンプルとして、「7 〜 12」の範囲で乱数を作ってみましょう。

```js:js
var random = Math.floor( Math.random() * 6 ) + 7;
//最小値「7」と最大値から最小値を引いた「6」を使う

```

「7 〜 12」なので最大値に1を足した13から最小値を引いて「6」を「random」メソッドに掛けます。最後に、最小値「7」を足してあげれば、「7 〜 12」までの範囲における乱数を生成することが出来ます。
【Mac】rails sでlocalhostにアクセスできないのはセキュリティソフト「ESET」が原因だった

#環境
PC：Macbook Air
ブラウザ：Google chrome

#症状
railsアプリを作成後、localhostを開こうとするが「このページは動作していません」と表示され接続できない。

##詳細
・ターミナルで`rails s` を入力時はエラーメッセージは出ないが、ブラウザでlocalhost:3000にアクセスしようとすると「このページは動作していません - localhostからデータが送信されませんでした。」と表示され、接続できない。

・`rails s -b 0.0.0.0`では接続できる。

#試したこと
・`lsof -i :3000`で、port3000が使用されていないかチェックし`kill -QUIT <PID>`で消去。
→結果は変わらず。

・ブラウザをchromeからfirefoxに変えてみた
→`rails s`で接続できる。

・ブラウザの問題だと考え、[この記事](https://stackoverflow.com/questions/25277457/google-chrome-redirecting-localhost-to-https)を参考に、chromeの設定を以下のように変更。
1. アドレスバーに「chrome://net-internals/#hsts」をコピペして開く
2.Delete domain security policiesにlocalhostと入力
→再度`rails s`を試すも失敗。


#結論（エラーの原因）
上記の通り色々と試すもことごとく失敗し、もう一度ブラウザのエラーメッセージをよく読み、「ERR_EMPTY_RESPONSE localhost」で検索したところ、[この記事](https://qiita.com/enzirion/items/3af4afc906604da93c20)にたどり着く。

結果、**原因はPCに入れているセキュリティソフト「ESET Cyber Security Pro」**だった！！

<img width="396" alt="スクリーンショット 2020-07-18 12.38.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621420/5a2c08ee-2ec1-0521-a1c8-c293ce6e3a98.png">


#ESETの設定
[公式サイト](https://eset-support.canon-its.jp/faq/show/1583?site_domain=default)にしたがって、一度パーソナルファイアウォール機能を無効にし、該当する通信が確立されるか試してみてください。

これで繋がるなら、原因は間違いなくESETのファイアウォール。

あとは、サイトの指示にしたがって、フィルタリングモードを［対話モード］にし、通信を許可するためのルールを作成すれば解決するはず。

#まとめ
今回、localhostにつながらない原因がESETにあるという結論にたどり着くまで、かなり時間がかかってしまいましたが、調べてみると、導入しているセキュリティソフトが悪さをしてしまうケースはよくあるようです。

何をやってもだめな時は、一度セキュリティソフトを確認してみてください。
pythonで辞書型のkeyに配列は使えるか？

# pythonで辞書型のkeyに配列を使いたい

競技プログラミングをやっていると、配列と値をハッシュテーブルで紐付けたいことがあります。(ex. 辞書型に[1,2]と入れると"s"と返ってくるようなもの)


いつもlistをkeyにしようとして、怒られてpythonでは辞書型のkeyに配列って使えなかったっけ？となるのでメモ。

結論としてはlistではなくtupleを使えばできます。
動作としてはこんな感じ。

```python

d = {}
d[(1,2)] = "s"
print(d)

# {(1, 2): "s"}

```
Spring Boot本レビュー: Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発

https://www.shoeisha.co.jp/book/detail/9784798142470

総評: 1冊目としてはナシ。2冊目以降ならアリかな。

---

初学者に薦められるSpring Boot入門本を探しています。
本書で4冊目。他の書籍については[こちら](https://qiita.com/tags/springboot%e6%9b%b8%e7%b1%8d%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc)を参照。
持ってる本はこれで全てなのでおそらくラストです。

今までの3冊と違うのは、

- Spring Bootの本でなくSpring Frameworkの本であること[^1]
- Kindle Unlimited対象ではなく、他と比較してお値段お高めであること
    - (ただし、しばしば行っている翔泳社本セールの対象になっているので定価の半額で購入できる機会は多いはず)

です。

[^1]: と思ってたんですが、あらためて読んでみると本書籍最後のサンプルアプリをSpring Bootで作っていたりして、(Spring Bootでなく)Spring Frmaeworkを使ってwebアプリケーションを作りたい人にとってはちょっとピントがずれてる気もしてきました…

著者は(全員がそうなのかは存じませんが)Springプロジェクトのコードにコントリビュートされてたりするので記述の正確さは折り紙付きだと思います。[^2]
ただ、入門者にとって理解しやすいかと言うとそれはまた別問題で…

[^2]: これも読み直しているときに気づいたのですが、14章のサンプルアプリ作成で `UserDetails` に `User` エンティティ持たせるとかかなりどうかと思う実装してたりしてました(その他、PostgreSQLのストアドプロシージャに依存してるので他のRDBMSで確認しづらかったり)。(世間の評判にひきずられて)やや本書を過大評価してしまっていたように思います…

冒頭リンクから目次が見られますが、これを見るだけでちょっととっ散らかった印象を受けます。
更に実際読んでみると、章の担当者が知ってることベースで記載内容を決めた感じがして、説明されている内容の重要度がわからないです。
(比較的重要なものもそうでないものも、同じような感じで説明されてしまっている)
フレームワークユーザ視点というより、フレームワーク提供者視点というか。

なので、2冊目以降、「あ、こういう機能があるんだ！？」という新しい発見をするために/公式リファレンスを読むための道標として読むのはありかなと思いますが、入門書として1冊目に買ってもあまり内容が頭に入ってこないのではないかと思います。

[こちら](https://qiita.com/suke_masa/items/392976749fce94a8ef1f)に、結構細かいobsoletedとなっている内容について説明されてたりしますが、そういうのは読者である自分が(そのとき持っていなくても、自分で調べて)気づくレベルの知識を持っていることが期待される書籍かなと考えます。
(逆に言うと、このページに書いてある古くなっているという事情はあまり問題にならないと考えます。)

あと、これは入門者視点でなく私視点での要望になるのですが。
かなりフレームワークの挙動について突っ込んで解説されているのはありがたいのですが、リファレンスのどこを見れば書いてあるのか(とか、あるいは、実はリファレンスに載ってなくてコード見ないとわからないんですよ、みたいな情報)も記載してくれているとありがたかったかな、という点があります。
短いコードで複雑な結果を得る～一次元セル・オートマトン、画像で保存版～ 

## これは何？

前回の記事「[短いコードで複雑な結果を得る～一次元セル・オートマトン～](https://qiita.com/can110/items/2cd23331d3a894a68517)」の修正版です。
以下を修正しました。

- オートマトンをジェネレータで実装
- 結果を画像として保存

１セル１ピクセルで描画すると[ちょっと何言ってるか分からない](https://dic.nicovideo.jp/a/%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E4%BD%95%E8%A8%80%E3%81%A3%E3%81%A6%E3%82%8B%E3%81%8B%E5%88%86%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84)ですね。

## コード
```Python
import numpy as np
from PIL import Image
import random

# セル状態を返すジェネレータ
def CA( rule_id, n_cell, init_cell_id = -1):

    rule = list(map(int, f'{rule_id:08b}'))

    # 初期状態
    if init_cell_id < 0:
        cell_c = [random.randint(0,1) for _ in range(n_cell)]
    else:
        # 初期値としてint値を与えると、そのビットパターンを初期状態とする
        cell_c = list(map(int, f'{init_cell_id:b}'.zfill(n_cell)[-n_cell:]))
        cell_c = np.array(cell_c)

    yield cell_c

    while True:
        cell_n = [ rule[cell_c[i-1]*4 + cell_c[i]*2 + cell_c[(i+i) % n_cell]] for i in range(n_cell)] # 次の状態
        cell_c = cell_n # 状態の入替
        yield cell_c


random.seed(110)

# データ作成
W, H = 640, 480 # 幅, 高
img = np.zeros((H, W))
ca = CA( 30, W) # ルールID, セル数
for h, c in zip(range(H), ca):
    img[h,:] = c

# 画像として保存
img = Image.fromarray(img*255).convert('RGB')
img.save('ret.png')
```

##結果
![ret.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175214/d056e820-5ee4-2b83-24bb-e636d177f9b2.png)
簡易CMS 作成で無料ブログを公開する。 Vue CLI版 表示機能 / build公開


# 概要
あまり具体的な、実装内容では無いのですが

IndexedDB + Vue等の、抵コスト構成機能の関係となり
簡易的なCMSの作成となります。
Vue CLI , build ファイルで。
クラウド側にコピーすると
記事編集機能が出力した。
jsonファイルを読むと、CMS表示する仕組みとなります。

・ＣＭＳ表示の、レイアウト変更、カスタマイズ関係。こちらです。
https://note.com/knaka0209/n/n3a6e3853b324

・記事の編集機能の説明は、こちらです。
https://note.com/knaka0209/n/nfbe2ab41a344

# 全体の編集手順 ( インストールを除く )

・編集機能で、記事を編集し。エクスポート機能で
　jsonファイルを出力
・CMS表示ドメインに jsonファイルを、アップロードする。
  パス : /cms.json

　上記で。編集内容が公開されます

# 環境

Chrome 83
Vue CLI
vue-router
axios

# デモのページ

　内の、デモ紹介ページで。URL記載しております
  今回は、netlifyにデプロイした場合です
  CMSの記載がある。部分です

https://note.com/knaka0209/n/n16487eb5e647


# 画面
・詳細

![ss-cms-show-0717a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159710/429f9006-38ef-cd37-8522-7267f5efc59b.png)

・トップ
![ss-cms-0717b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159710/075fe57c-0ada-8e52-457d-0d49855de681.png)


・MDの文字サンプル
![ss-cms-show-0717b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159710/b549d6cf-1de2-feb9-c657-22309549eb84.png)


### 参考のファイル / VUe CLI の　build ファイルになります

https://github.com/kuc-arc-f/vue_spa3cms_dist



***
Docker コマンド

Dockerについてメモ。

Dockerについては、後回しでもいいかと思っていましたが、

オラクルデータべース学習（インストール）の為にDockerを利用することになりました。

### Dockerのバージョンを確認

ターミナルで`docker --version`とすると、バージョン情報を返します。

```terminal:Terminal.app
docker --version

Docker version 19.03.8, build afacb8b
```

`docker version`とすると、バージョンに関する全ての情報を返します。

```terminal:Terminal.app
docker version

Client: Docker Engine - Community
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        afacb8b
 Built:             Wed Mar 11 01:21:11 2020
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.17
  Git commit:       afacb8b
  Built:            Wed Mar 11 01:29:16 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
```
API、Git、Go言語などの情報もまとめて返します。
 `OS/Arch: darwin/amd64`の`darwin`（ダーウィン）は、アップルが開発するUnix系のPOSIX準拠オペレーティングシステム (OS) で、つまりmacOSってことみたいです。

### Dockerの環境を確認
```terminal:Terminal.app
docker system info
```
`info`だけでもいろんな情報がでますね。

```terminal:Terminal.app
docker info
```
Dockerの稼働状況を表示。

```terminal:Terminal.app
docker container ls
```
Dockerのネットワーク情報を表示。

```terminal:Terminal.app
docker network ls
```
Compilation of OpenFOAM v2006 with runTimePostProcessing [trouble and temporary fix]

runTimePostProcessing functionality is not available in precompiled packages of v1912 and v2006.

I made [a note how to compile OFv1912 with runTimePostProcessing.](https://qiita.com/snaka-dev/items/26b4132f94bdb4e2c021) 

The same way as v1912 gave me no error during compilation. However, runTimePostProcessing feature can not effective. The problem is the place where the compiled library is stored, I think.


## Refs
- [OpenFOAM® Quick Build Guide v2006](https://develop.openfoam.com/Development/openfoam/-/blob/OpenFOAM-v2006/doc/Build.md)
- [OpenFOAM® ThirdParty Build v2006](https://develop.openfoam.com/Development/ThirdParty-common/-/blob/v2006/BUILD.md)

## ThirdParty Compilation

### ParaView

```
cd $WM_THIRD_PARTY_DIR
makeParaView
```

You can build ParaView 5.6.3, including with the ability to use Python and MPI. Options are same as explained [here at OpenFOAM WiKi](
https://openfoamwiki.net/index.php/Installation/Linux/OpenFOAM-v1806/Ubuntu). 

It may be easy if you use a script like [this example provided in a ThirdParty directory.](https://develop.openfoam.com/Development/ThirdParty-common/-/blob/master/makeParaView.example)

### VTK

Check the VTK version with the following command.

```
cat ParaView-v5.6.3/VTK/CMake/vtkVersion.cmake
```

If the version is 8.2.0, create a link with the name of VTK-8.2.0.

```
ln -s ParaView-v5.6.3/VTK/ VTK-8.2.0
```

Now, compile the VTK.

```
makeVTK
```

You can build VTK with mpi and other options. It may be easy if you use a script like [this example provided in a ThirdParty directory.](https://develop.openfoam.com/Development/ThirdParty-common/-/blob/master/makeVTK.example)


## OpenFOAM v2006

Then, prepare for the OF compilation.

```
wmRefresh
cd $WM_PROJECT_DIR
export ParaView_DIR=$WM_THIRD_PARTY_DIR/platforms/linux64Gcc/ParaView-5.6.3
export VTK_DIR=$WM_THIRD_PARTY_DIR/platforms/linux64Gcc/VTK-8.2.0
```

Finally, compile OpenFOAM-v2006.

```
foam
./Allwmake -j -s -l
```

## Test

You can check the functionality with tutorials/incompressible/simpleFoam/windAroundBuildings.

You will get the error message like this `librunTimePostProcessing.so: cannot open shared object file: No such file or directory`

### trouble shooting

OpenFOAM compilation create files like `librunTimePostProcessing.so` in the directory `$WM_PROJECT_DIR/platforms/linux64GccDPInt32Opt/lib/lib`.

Should the `librunTimePostProcessing.so` file be in the parent directory `$WM_PROJECT_DIR/platforms/linux64GccDPInt32Opt/lib` ?

If I copy the following three files into `$WM_PROJECT_DIR/platforms/linux64GccDPInt32Opt/lib`, runTimePostProcessing function works perfectly.
`librunTimePostProcessing.so`
`librunTimePostProcessing.so.8`
`librunTimePostProcessing.so.8.2.0`
【Python】データサイエンス100本ノック（構造化データ加工編） 002 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/sRGR3lhBlcY)もしています。

##問題
P-002: レシート明細のデータフレーム（df_receipt）から売上日（sales_ymd）、顧客ID（customer_id）、商品コード（product_cd）、売上金額（amount）の順に列を指定し、10件表示させよ。

##解答
```:コード
df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']].head(10)
```

##出力
|  | sales_ymd | customer_id | product_cd | amount |
|--:|--:|:--|:--|--:|
| 0 | 20181103 | CS006214000001 | P070305012 | 158 |
| 1 | 20181118 | CS008415000097 | P070701017 | 81 |
| 2 | 20170712 | CS028414000014 | P060101005 | 170 |
| 3 | 20190205 | ZZ000000000000 | P050301001 | 25 |
| 4 | 20180821 | CS025415000050 | P060102007 | 90 |
| 5 | 20190605 | CS003515000195 | P050102002 | 138 |
| 6 | 20181205 | CS024514000042 | P080101005 | 30 |
| 7 | 20190922 | CS040415000178 | P070501004 | 128 |
| 8 | 20170504 | ZZ000000000000 | P071302010 | 770 |
| 9 | 20191010 | CS027514000015 | P071101003 | 680 |

##解説
・PandasのDataFrame/Seriesにて、列を指定して先頭データを確認する方法です。
・列の情報を絞って、ざっくり確認したい時に使用します。
・**'<データ名>[[<列名A>,<列名B>,<列名C>]].head(n)'**で、先頭n行目までの指定した列(列名A,列名B,列名C)を順番に表示します。
IISサーバにアクセスした時に初めに表示するファイルを設定する

#記事一覧
[Visual StudioのASP.NET Core MVC で Web アプリを作成してみた（記事一覧）](https://qiita.com/yuta-sasaki/items/31307b88f7234b92f728)


#「IISマネージャ」の「既存のドキュメント」で優先度を設定する
「コントロール パネル\システムとセキュリティ\管理ツール」→「インターネット インフォメーション サービス (IIS) マネージャー」を起動する。
接続ウィンドウで、対象のサイトを選択した状態で、「既存のドキュメント」をダブルクリックする。
<img width="709" alt="キャプチャ1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/3a0f6bb2-4745-d202-9817-0932cf117a3c.png">
「既存のドキュメント」で、アクセスした時に初めに表示するファイルの優先度を変更する。
リストの上のほうが優先度が高い。
<img width="709" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/5285fd14-fdbe-8e1b-9741-42ea6dbd28f1.png">
【メモ】自分が知識集約系サービス作るならどんな実装にしたいか

随意追記

## linkability

cf.
:rage: Qiita運営に受け入れてもらえなかった要望 - Qiita
https://qiita.com/nkay/questions/7b4dd77b4334aab641ac

ざっと読んだ感想：ひとことで言うなら、**linkability**? が重要視されているっぽい

ルート的な投稿へのコメント・回答が、その投稿の編集によってちぐはぐになる問題は、現状でも引用 & WebArchive で対処できる（つまり面倒だけど、ユーザ側の工夫と努力でも実現できる）ので、運営側としての優先順位は低くなるのは分かる。

linkability というところを考えると、個人的には、記事も質問もコメントも回答も、データベース的には、すべて同列に扱われ、入れ子関係で親投稿・子投稿が識別 & 差分同士が紐づく、という形態が理想形。
差分同士を対応させておけば、親投稿の内容が書き換わっても、元の内容を参照できるし。

つまり、「はてな匿名ダイアリー」「Scrapbox.io」の発展版。
単純な要素が勝手に組み合わさっていくような実装が好み。

コメント・回答するときに付けるタグは、親投稿のものを継承しつつ、必要に応じて自分の投稿に任意のタグを追加できるようにしておけば良いかな。

記事／質問／コメント／回答の分類は、いっそのこと無くても良さそう。読めば分かるし。
ただ最低限、「答え」が出ているかどうかぐらいは`Passed-Issue` とか適当にタグで示しておくと良いかも。（`解決済み`とかだと意味合いが変わってくるので、`Passed-Issue`。）

プロフィールページに行くと、`Article`タグ、`Comment`タグ、`そのほか設定済みの`タグ…の投稿が、タブ切り替えで見れるようになっていれば、Qiita っぽい雰囲気になりそう。cf. sect:Empowerment

## Empowerment

既存サービスの代替品を作るより、既存サービスを empowerment するものを作りたい。（先駆者への敬意）
ブラウザ拡張とか、サービス連携とかで、それができるなら、その方向性で。