OmniAICreator/Qiita-1.07M huggingface dataset:
Herokuで運用しているサービスが突如500エラーを吐くようになった。

Herokuで運用しているサービスが突如500エラーを吐くようになったので確認。
サービスといってもPoC用に建てたAPIサーバーで、エラー検知等は行ってなかった。


## とりあえずログを確認

`$ heroku logs -t ` でとりあえずログを確認

```
F, [2020-07-29T03:23:19.600711 #4] FATAL -- : [cb47240d-1f9b-4d80-997a-d97ee1a3302e] ActiveRecord::StatementInvalid (PG::InsufficientPrivilege: ERROR:  permission denied for table device_data
```

` PG::InsufficientPrivilege: ERROR:  permission denied for table `
が出ている。


## DBへのアクセス権がないっていってるのでこの記事を参考に確認。
https://www.two-ways.com/mt/usakorog/2009/08/db-1.html

確認していくも関係なさそう。
権限は直近で変更していない。


## Herokuのpg独自の問題だと気づく
https://qiita.com/pugiemonn/items/e08f06f22086a7e51b42
こちらの記事通りでしたありがとうございました。


`$ heroku pg:info `

```pgの状態を確認
=== DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           2/20
PG Version:            12.3
Created:               2020-07-07 15:55 UTC
Data Size:             12.5 MB
Tables:                6
Rows:                  16132/10000 (Write access revoked)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-lively-57044
```

heroku のHobby Devプランは10,000件まで😂

## データをとりあえず 10,000件以下まで減らす

`$ heroku pg:info `　

```
=== DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           2/20
PG Version:            12.3
Created:               2020-07-07 15:55 UTC
Data Size:             12.4 MB
Tables:                6
Rows:                  3339/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-lively-57044
```

## 再度問題のあったPOST APIを確認
```
curl -X POST -H 'Authorization: Token' -H 'Content-Type:application/json' -d '{}' https://herokuapp.com/
```

```
{"status":200,"message":"successfully created"}%  
```

OK🎉
プルリクエストの内容をローカル環境で稼働確認する(github)

## はじめに

共同開発で他のメンバーがプルリクエストした内容をレビューする際、ソースの確認だけでなく、実際の挙動を自分のローカル環境上で確認したくなり、手順を調べたのでまとめました。

**2020/6/9 改定**
「bashのaliasに登録して省力化」する方法を追加

## 前提

リモートリポジトリにはgithubを使用している

## やり方

1.  github上で、Pull requests（プルリクエスト）タブをクリックして、確認したプルリクエストを選択

2. プルリクエストのID番号を確認
  プルリクの画面(以下の場合、157がプルリクエストのID番号）
![スクリーンショット 2020-07-29 22.38.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233987/600cffcb-e119-74d4-d8f4-51e410326f72.png)


3. ターミナルで以下のgit fetchを実行する。
  ※git fetchって何って方は、[こちら]([https://backlog.com/ja/git-tutorial/stepup/15/](https://backlog.com/ja/git-tutorial/stepup/15/))から
  IDに、先程調べたプルリクエストのIDを、BRANCHNAMEは任意のネーミングでOKです。（プルリクされたブランチ名や、プルリク番号にするとわかりやすいです）

```ruby
git fetch origin pull/ID/head:BRANCHNAME
```

今回の場合は、以下のコマンドを実行

```ruby
git fetch origin pull/157/head:PR-157
```

すると、ローカル上にプルリクエストされたブランチが作成されます。

```ruby
$ git branch
* develop
  PR-157    # ← 作成されたブランチ
  master
```

あとは、作成されたブランチに移動して、サービス起動して挙動の確認を行います。

## bashのaliasに登録して省力化
上記はよく使うコマンドですが、ちょっと長ったらしいしタイポもするので、タイプ数を減らすためにaliasに登録して省力化しましょう（結果タイポを減らせます）

`.bashrc`に以下の内容で登録します。 

```
function gfp() {
 command git fetch origin pull/$1/head:PR-$1
}
```
※gfp : git fetch pull の自分なりのショートカットです。お好みで編集してください

ちょっと解説：通常エイリアスを登録する場合は`alias='git xxx'`としますが、コマンド途中に引数を指定する場合はaliasコマンドではうまくイカないので、funcitonを利用します。

これで、次回から
`gfp プルリク番号`と打つだけで、該当プルリク番号に応じたブランチが作成されます。

なお、.bashrc登録直後に既に起動されているターミナルで使いたいときは`source ~/.bashrc`を忘れずに。。。


## 参考させていただいたサイト

[fetch｜サル先生のGit入門【プロジェクト管理ツールBacklog】](https://backlog.com/ja/git-tutorial/stepup/15/)

[プルリクエストをローカルでチェック アウトする](https://docs.github.com/ja/github/collaborating-with-issues-and-pull-requests/checking-out-pull-requests-locally)

[bashで引数つきのエイリアスを設定する](https://hacknote.jp/archives/8043/)
Relational Network

[前回の記事](https://qiita.com/SoseSose/items/8cbb8016847603f320e6)の続きで、Relational Networkのできる限りの説明になります。

#Relational Networkについて
まずは元論文のリンクを(https://arxiv.org/pdf/1706.01427)
実験結果から見てしまいましょう。
![コメント 2020-07-18 155717.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595608/4a4dea04-cdcf-6533-75e6-67f3c8e610dc.png)
これはCLEVRというオブジェクトの関係から回答を導くデータセットの正解率になります。よくあるニューラルネットワーク（CNN+LSTM、まあ今はあんまり使われてないみたいですが）の正解率は低く、人間（Human)を下回っています。一方、Relational Networkを用いた(CNN+LSTM+RN)は人間を上回る結果が出ています。
この結果から分かりますが、シンプルなニューラルネットワーク(NN)というものは関係というものを認識する能力が低いのです。そこで提案されたのがこのRelational Networkです。後述しますが、関係性を出力に反映するためにシンプルなニューラルネットワークとは違った特殊な構造を持っています。で、この技術をARCで使おうと考えているわけです。

#Relational Network詳細
Relational Networkは式で表すと次のような構造になっています。

```math
RN(O)=f_\phi (\sum_{i,j}g_\theta(o_i,o_j))
```
ここで$O=\\{ o_1,o_2,\dots o_n \\},o_i\in \mathbb{R}^m$で$o_i$はオブジェクトを表します。そして、$f_\phi$と$g_\theta$はパラメータつきの関数（Relational NetworkではMLPで実装）を表します。
図で表すと以下のようになります。![コメント 2020-07-18 152120.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595608/0394324b-741e-6580-a106-92ff8deeb447.png)

CNNとLSTMでオブジェクトを認識し、それをRNに入力することで回答を出すという構造です。
このRNの式、正直、私もいまいちよく分かっていないのですが、$g_\theta$で各オブジェクト毎の関係性を出力し、それらを加算して、$f_\phi$で統合し出力を得るみたいです。ただ、よくあるNN(すべてのオブジェクトを一列に並べてしまって、MLPに入力する)と違うのは二つのオブジェクトを表すベクトルと質問ベクトルだけを並べてMLPに入力しているという点です。これはよくあるNNより制限された構造と考えられ、この制限によりネットワークがオブジェクト間の関係性を学習しやすくなるのだと思っています。

#Sort Of CLEVRデータセット
論文で実際に使用されたデータセットはほかにもあるようですが、Sort OF CLEVRの実験の追試をしてみました。Sort Of CLEVRの例は以下の図になります。
![コメント 2020-07-29 210411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595608/2c40feb1-a560-6cec-66a0-62196a70def7.png)
このデータセットは画像と質問文（図では文章が書いてありますが、実際には質問文はエンコードされています。）で構成されています。画像にはいくつかのオブジェクトがあり、質問文はそのオブジェクトに関する質問で成り立っています。質問には２つ種類があり、オブジェクト間の関係を考慮する必要のない質問（Non-relational question）とオブジェクト間の関係を考慮する必要のある質問（Relational question）があります。そして、図右上にもありますが、ここでもCNN＋RNはCNN+MLPを上回った正解率を特にRelational questionで出しています。

私も追試はしたのですが、正直ほとんどこのリポジトリ(<https://github.com/kimhc6028/relational-networks>)を参考にしただけなので、コードは特に載せません。追試の結果だけ示します。まず、訓練データの正解率です。
![train.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595608/d8d3d175-1f38-e67d-3084-bdcb83913a8f.png)
次にテストデータの正解率です。
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595608/98bb9202-37c1-1ad0-b7a2-3962499b21f0.png)
訓練とテストの差を見る限り、20epochを超えたあたりで、過学習気味ですが、test_acc_relが90%近いのは良いのではないでしょうか。そして一番悪いtest_acc_ternary。これは3つのオブジェクトに関する質問なのですが、完璧に過学習状態であり、test_acc_relと比べても正解率が低いです。一応、60%は出ていますが、三つの関係というのはRNでも難しいようです。３つ以上の関係性は三体問題のような例もあるように、そもそもが難しいものだとは思います。ただ、Sort of Clevrの３つの関係性の問題はそこまで難しいものではない（私が解けば100%に近い数字が出ると思います。）ので、改善の余地があるでしょう。

#まとめと今後
論文の結果からもわかるように、RNはシンプルなNNと比べて、関係性を処理する能力が高いということが分かります。ただし、３つの関係性には苦戦しているようで、３つ以上の関係性が必要な問題はARCにもあるでしょう。そこで、次はReccurent Relatinal Network（RRN）に挑戦してみようと思います。正直、この記事かなり適当なのですが、ただのRNではARCが解けないと思っていたので、このRRNに早く取り組みたかったからです。RRNを使うと数独も解ける用で、フォーマット的にも数独とARCは近いものがあると思います。まあ、どうなるかやってみましょう。
Super-Linterを使ってGitHub ActionsでRubyのlintを実行する

## 前提

[Super-Linter](https://github.com/github/super-linter)のv3を使います。

## 特定の言語のlintだけ実行する

Super-Linterは、デフォルトではリポジトリに含まれるファイルのうち、Super-Linterでlintできる言語[^1]すべてについてlintを実行する。特定の言語についてだけlintを実行するときは、次のように`VALIDATE_<言語名>: true`を`env`として指定する。

例えば、Rubyのlint（すなわちRuboCop）だけ実行したいときの設定ファイルは次のとおり:

```yml:.github/workflows/linter.yml
name: linter

on: [push, pull_request]

jobs:
  build:
    name: Lint code base
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Lint Code Base
        uses: docker://github/super-linter:v3
        env:
          VALIDATE_RUBY: true
          DEFAULT_BRANCH: master
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

## lintのルールファイルを置くパス

例えばRuboCopのルールだと、`.rubocop.yml`という名前のファイルをリポジトリのルートに置くことが多い。しかし、Super-Linterがデフォルトで読むルールファイルのパスは`.github/linters/.ruby-lint.yml`である[^2]。

`LINTER_RULES_PATH`と`RUBY_CONFIG_FILE`を設定すればプロジェクトのルートの`.rubocop.yml`を直接読むように設定できるが、`.github/linters/.ruby-lint.yml`を`.rubocop.yml`へのシンボリックリンクとしておくこともできる。

[^1]: https://github.com/github/super-linter#supported-linters
[^2]: `LINTER_RULES_PATH`のデフォルト値が`.github/linters`、`RUBY_CONFIG_FILE`のデフォルトが`.ruby-lint.yml`であることによる
[PHPStorm]Local Changesで開発中の資源をグループで管理する

## はじめに

PHPStorm のバージョン管理のヘルパー機能である、`Local Changes`の使い方メモです。

詳細は公式ドキュメントを参照してください。
  → [Gitを使用して複数の機能を同時に処理する](https://pleiades.io/help/phpstorm/work-on-several-features-simultaneously.html)

## PHPStormの使い方シリーズ

- [Shelfで並行開発を楽に管理する](https://qiita.com/tmisuoka0423/items/3eeb3eda18ff5617bacb)

## 作業用フォルダを用意する

まず、今回作業を行うフォルダを用意します。
この記事では、ローカルリポジトリ上で作業を行います。

```zsh
% cd ~/Desktop
% mkdir shelf
% cd shelf
```

ローカルリポジトリを作成します。

```zsh
% git init
% ls -la

drwxr-xr-x@  3 mitsuoka-takahiro  staff   96  7 29 21:19 ./
drwx------@ 14 mitsuoka-takahiro  staff  448  7 29 21:16 ../
drwxr-xr-x   9 mitsuoka-takahiro  staff  288  7 29 21:19 .git/
```

.Git フォルダがあれば OK。

## PHPStormでGitツールウィンドウを表示する

`View > Tool Windows > Git`から開くことができます。
ショートカットはデフォルトで`⌘9`に設定されています。

<img src="https://github.com/tmitsuoka0423/qiita/raw/master/phpstorm-change-list/pic1.png">

このような感じのウィンドウが開きます。

<img src="https://github.com/tmitsuoka0423/qiita/raw/master/phpstorm-change-list/pic2.png">

## 変更リストで変更をまとめる(Local Changes)

変更リストを利用すると、開発中のファイルをグループで管理できます。
コミットも変更リスト単位で行うことができ、1 つのコミットに含めるファイルを選択する手間を省くことができます。

### 準備

新しいファイルを 3 つ追加し、ステージングします。
ステージングするのは、バージョン管理対象ファイルでないと Local Changes に表示されなからです。

```zsh
% echo hello > a1.txt
% echo hello > a2.txt
% echo hello > b2.txt
% git add .
```

Git ツールウィンドウはこのようになっていると思います。

<img src="https://github.com/tmitsuoka0423/qiita/raw/master/phpstorm-change-list/pic3.png">

### 変更リストでまとめる

ここで、`a1.txt`と`a2.txt`を機能 A の資源と仮定して、変更リストでまとめてみます。
`a1.txt`を右クリックし、`New Changelist`を選択します。
変更リストの名前を聞かれるので、機能 A を追加するという意味で`add feature A`としておきます。
（変更リストの名前はデフォルトのコミットメッセージとなるので、コミットメッセージを意識してつけておくのがオススメです）

<img src="https://github.com/tmitsuoka0423/qiita/raw/master/phpstorm-change-list/pic4.png">

<img src="https://github.com/tmitsuoka0423/qiita/raw/master/phpstorm-change-list/pic5.png">

新しい変更リストが作成されるので、`a1.txt`と`a2.txt`をドラッグして変更リストに追加します。

<img src="https://github.com/tmitsuoka0423/qiita/raw/master/phpstorm-change-list/pic6.png">

これで、変更リスト`add feature A`に`a1.txt`と`a2.txt`を追加できました。

### 変更リスト単位でコミットする

`⌘K`でコミットウィンドウを開きます。
デフォルトでは、`b2.txt`のみが表示されています。

<img src="https://github.com/tmitsuoka0423/qiita/raw/master/phpstorm-change-list/pic7.png">

ウィンドウ上部の`Changelist`から`add feature A`を選択します。

<img src="https://github.com/tmitsuoka0423/qiita/raw/master/phpstorm-change-list/pic8.png">

変更リスト`add feature A`を選択したので、`a1.txt`と`a2.txt`が表示されました。
また、コミットメッセージに`add feature A`が表示されました。
このままコミットする場合は、右下の`Commit`ボタンをクリックしてください。

### 変更リストのまとめ

変更リストを使うことで、開発中のファイルをグループ化して管理し、そのまま 1 つのコミットとできます。

## PHPStormの使い方シリーズ

- [Shelfで並行開発を楽に管理する](https://qiita.com/tmisuoka0423/items/3eeb3eda18ff5617bacb)
pythonの@propertyについて

`@property`について語るには、基礎から語らなきゃいけないんです。

学校の例を見てみましょう。学生というクラスがあるとしましょう。

通常、クラスの属性を決めるときに、属性をそのまま公開しても良いのですが、勝手に変更することが可能となり、あまりおすすめできません。というのも、点数は通常0 ~ 100の範囲内に位置するので、デタラメに9999にもできてしまいます。明らかにおかしいですね。

``` python3
s = Student() #オブジェクト作成
s.score = 9999
s.score = 1111
# 勝手に書き換えられる
```

ということで、`set_score()`や`get_score()`で成績を取得することにしました。（普通の流れです）

``` python
class Student:
  def get_score():
    return self.self._score

  def set_score(self, value):
    if not isinstance(value, int):
      raise ValueError("score must be an integer! ")
    if value < 0 or value > 100:
      raise ValueError("score must be between 0 ~ 100!")
    self._score = value
```
これでもう勝手に属性を書き換えられなくなったんだね。点数は0 ~ 100の範囲じゃなきゃだめだとと制限をかけることができました。

``` shell
>>> s = Student()
>>> s.set_score(60) # ok!
>>> s.get_score()
60
>>> s.set_score(9999)
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!
```
しかし、これは少し複雑さを増したようなきがするんだ。なんかここでズルをしたくなって、get, setみたいな複雑な方法ではなく、普通に属性を呼びたい、また、勝手に書き換えもできないような方法はないの？？？って知りたくなった。
あるよ。それは`@property`

``` python3
class Student:
  @property
  def score(self):
    return self._score

  @score.setter
  def score(self, value):
    if not isinstance(value, int):
     raise ValueError("score must be an integer!")
    if value < 0 or value > 100:
      raise ValueError("score must be between 0 ~ 100!")
    self._score = value

```

`@property`は少し複雑なので、中身の説明は割愛します。まずは使えるようにしよう。`getter`の方法を属性にしたいときに、`@property`を足せばいい。`@property`がもう一個のデコレーター`@score.setter`を作成した。これを持ってsetter方法を属性のようにします。
`getter -> @property`
`setter -> 属性.setter`



``` shell
>>> s = Student()
>>> s.score = 60 # OK　実際はre(60)
>>> s.score # OK　実際はs.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100! 
# 自分で定義したエラーメッセージ
```



read onlyの属性を定義することも可能→getterメソッドだけ定義し、setterメソッドを定義しなければread onlyですよ。

``` python3
class Student(object):

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2014 - self._birth
# birthは書き換えも読み込みもできるが、ageは読み込みのみできる。
```
# さいごに
`@property`はクラスの定義においてよく使われているので、使えるようにしましょう。私も実はブロックチェーンの練習で`@property`に出会って思い出すために、ここでメモっておきました。

さてさてまたね。
railsのマイグレーションをミスったときにやり直す

` bundle exec rails db:migrate ` をした際に思ってた通りにマイグレーションできずに、失敗することがあります。

この時、git操作でchanged を消すと、migrationした履歴だけが残ってしまい、
マイグレーションステータスにNO FILEが存在していてやっかいなことになります。

汚れてしまったマイグレーション履歴をきれいに戻す手順を示していきます。

## とりあえずstatusコマンドで状況を確認

` $ bundle exec rake db:migrate:status `

```
database: ***/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200707153004  Create users
   up     20200711014336  Create groups
   up     20200715054409  Create graphs
   up     20200715072011  Add group id to graph
   up     20200729104800  Add default temp3 to graph
   up     20200729105435  Add default temp2 to graph
   up     20200729124216  Add values to graphs
   up     20200729124408  ********** NO FILE **********
```

この ` ********** NO FILE ********** ` 状態が存在すると、以降、` bundle exec rails db:migrate ` が成功しなくなります。

## とりあえずNO FILE状態から脱出

上記のstatusコマンドで確認したMigration IDをもとにし、以下のファイルを作成。

` $ vi db/migrate/#{Migration ID}_tmp.rb `

```
class Tmp < ActiveRecord::Migration[5.1]
  def change
  end
end
```

## 再度statusコマンドで再確認し、NO FILEが消えていることを確認

` $ bundle exec rake db:migrate:status `

```
Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200707153004  Create users
   up     20200711014336  Create groups
   up     20200715054409  Create graphs
   up     20200715072011  Add group id to graph
   up     20200729104800  Add default temp3 to graph
   up     20200729105435  Add default temp2 to graph
   up     20200729124216  Add values to graphs
   up     20200729124408  Tmp
```

NO FILEからTmpになってる

## Tmpのマイグレーション履歴をdown statusに変更する


` $ bundle exec rake db:migrate:down VERSION=#{Migration ID} `

## ステータスがdownになっていることを確認する

` $ bundle exec rake db:migrate:status `

```
database: ***/development.sqlite3


 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200707153004  Create users
   up     20200711014336  Create groups
   up     20200715054409  Create graphs
   up     20200715072011  Add group id to graph
   up     20200729104800  Add default temp3 to graph
   up     20200729105435  Add default temp2 to graph
   up     20200729124216  Add values to graphs
  down    20200729124408  Tmp
```

## マイグレーションファイルを削除する

` $ rm -rf db/migrate/#{Migration ID}_tmp.rb `

## 最後にステータスを確認

` $ bundle exec rake db:migrate:status `

```

database: ***/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200707153004  Create users
   up     20200711014336  Create groups
   up     20200711085035  Create device data
   up     20200715054409  Create graphs
   up     20200715072011  Add group id to graph
   up     20200729104800  Add default temp3 to graph
   up     20200729105435  Add default temp2 to graph
   up     20200729124216  Add values to graphs
```

履歴自体が消えて、失敗前に戻った🎉
Pandas : 条件を満たす行を抽出時のエラー ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). の原因と対策

# 結論

``ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). ``

のエラーの原因として、

複数条件なのにそれぞれを`()` で括っていない、`& | ^ `などのbit演算ではなく`and or not`などと書いているなどが検索で出てきますが[^1]　[^stackoverflowの記事]


`isin` を`in` にしてしまっていた時も同様のエラーメッセージがおきるので気をつけましょう。



# 原因となったコード
```python:error.py
tmp__ = transactions[(transactions["year"] == "2014" ) & (transactions ["month"] in ["06","07","08"]))]
```

# 訂正したコード
```python:correct.py
tmp__ = transactions[(transactions["year"] == "2014" ) & (transactions["month"].isin( ["06","07","08"]))]
```
[^1]: nkmkさんのブログ記事にこのエラーが起きるケースとその理由（PandasやNumby ndarrayでは曖昧性解消のため、bitwise(&,|,~)を使うとelement-wiseなoperator(and,or,norなど）　にoverride されるようになっている）が書かれています　https://note.nkmk.me/python-numpy-pandas-value-error-ambiguous/

[^stackoverflowの記事]: 　stackoverflowの記事ではどのように曖昧であるかをもう少し詳しく説明してあります。https://stackoverflow.com/questions/36921951/truth-value-of-a-series-is-ambiguous-use-a-empty-a-bool-a-item-a-any-o
楕円曲線暗号を高速解読する超ρ法

ビットコインに使われているk系楕円曲線暗号(係数a=0)を解読する
ρ法の高速化(超ρ法)に成功。解読平均反復回数が大幅削減した。
平均反復回数: ρ法:sqrt(πr/2), 超ρ法:sqrt(πr/1200)。
平均反復回数はρ法の1/25程度。計算時間は1/35程度。
計算時間が平均反復回数以上に削減した理由は、比較対象のρ法の
多倍長(逆元と法乗算)がgmpで、超ρ法の多倍長はCで自作のため。
自作多倍長はgmpの2倍弱高速で、追加処理を含めても高速である。
楕円曲線暗号(ECC:y^2=x^3+ax+b (mod p),rは位数)はk系(係数a=0)と
r系(乱数系でaはゼロでない)。secp256k1やsecp256r1が代表例。
x,yは座標値でx,y,a,bは整数。p,rは素数。

50ビット及び60ビットのECCを各500個作成し、比較評価した。
50ビットECCの解読：
　平均反復回数: ρ法=4200万回、超ρ法=170万回
　平均計算時間: ρ法=28秒、　  超ρ法=0.85秒
60ビットECCの解読：
　平均反復回数: ρ法=13.3億回、超ρ法=5500万回
　平均計算時間: ρ法=890秒、　 超ρ法=25秒
計算はC言語で4Ghzのパソコンを使用。
詳細はHP( https://ecc-256.com/ )の超ρ法を参照。

超ρ法のρ法に対する主な特長は下記。
1. ρステップ
　Q=n×Bから整数nを求めるT=f(T)のρステップ
 (1) T=f(T)にQを関与させない。TとBだけ関与。
 (2) T=(Tx,Ty)でTyはp/2以下(Ty正と表示)にする。
 (3) (2)の計算でループしたら2倍算
 注) (2)(3)は112ビットECCの世界記録に使用されている。
2. k系(a=0)の利用
 (1) T=(Tx,Ty)でTyが同じでTxが異なるものが3個存在する。
 (2) 対象ECC固有の整数mが存在し、3個のTは1,m,m^2倍の関係。
 (3) 3個内(Tyの正負を入れると6個)の変換は容易。
3. ρテーブル作成の工夫
 (1) n個のρテーブル(ix=Tx (mod n))の作成法に工夫
 (2) R=(Rx,Ry),S=(Sx,Sy),ix=Rx,Sx (mod n)とする。
　　 T=S-Rでix番テーブル作成。
 (3) R,Sを特徴点(ループ結合点)として、衝突点テーブルに登録
 (4) R,Sの作成は2n又は3n個で止める。
4. その他
 (1) T=f(T)にT=T+TB[ix]とT=T-TB[ix]のk系変換後の選択を追加
　　注) 1.の(2)と2.及び本項の適用で平均反復数はsqrt(πr/2)
        からsqrt(πr/24)に減少する。
　　　　ただし、逆元計算は増えないが乗算が増える。
 (2) 3で使用したR,S,TにAIを適用し、特徴点を作成し衝突点
　   テーブルに登録。
 (3) 他数件
inputタグのtype属性について

#inputタグのtype属性について
一つ前の記事で紹介したinputタグのtype属性を今回は書いていきたいと思う。
inputタグはtype属性を変える事で様々な役割を持たせることができるので、非常に便利なタグだ。
##text
名前やメールアドレスなど一行で入力できる情報を入力してもらいたい時に使用する。
##number
半角数字のみを入力してもらいたい時に使用する。
##tel
電話番号を入力してもらいたい時に使用する。
##email
メールアドレスを入力してもらいたい時に使用する。
##url
urlを入力してもらいたい時に使用する。
##password
パスワードを入力してもらいたい時に使用する。入力された文字は全て黒丸で表示される。
##reset
入力した文章を全て消す時に使う。
##submit
送信ボタンの役割をする。

##他にも色々あるが、必要になったら調べてみるといい。
Chatworkで、Slackのリマインドに相当するものをGASで作った

# 概要
Slackでは、`/remind  hoge fuga piyo` でさくっと作れるリマインダ機能。
Chatworkには、それに類するものは現時点ではありません。
なので作ってみました。

# コンセプト
エンジニアなら自前でbot作ればいいです。
非エンジニアでも設定できるようにしたいです。
というわけで、スプレッドシート上に設定を書けば動くようなものにしました。

# 実装環境
そんなわけで、スプレッドシート＋GASです。

# 設定シート
こんな感じにしてみました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282159/20a31b14-3e4e-5240-e629-929b198701e5.png)

- 実行形式は大きく分けて2つです。
    - 日時を指定して1回だけ実行
    - 曜日と時間を指定して繰り返し実行
- 発言者は、内部的に設定してあるAPIトークンに変換されます。
- チャットルームIDでなくチャットルーム名にして内部変換することも考えましたが、チャットルームIDにしました。
    - ルーム名から変換だと、新しい部屋が増えるたびにエンジニアが設定しないといけない(発言者はそこまで頻繁には増えないでしょう多分)
        - もしかしたら管理者のトークンだとgetRoomsで全部屋を取得できるのかもしれないけど、管理者じゃないし(´・ω・`)
    - URLからチャットルームIDを抜き出すことは、誰でもできるとまでは言わないけど、資料示せばなんとかなるでしょ
- いけてないとは思うのですが、重複送信を避けるための送信済みフラグを、シート内に持っています。

# スクリプト仕様
概ねこんな感じで動きます。

- GASのトリガ機能により、毎分起動する
    - 設定シートを読み込んで、発言すべきものがあったら発言する
        - 発言タイミングはとりあえず、「設定日時が過去5分以内」とした
            - 「毎分動作で過去1分以内」だけだと、取りこぼしや重複が起きそうな気がした
                - 5分以内として取りこぼしを防いだ
                - 送信済みフラグで重複送信を防いだ
- GASのトリガ機能により、毎日1回0時に起動する
    - 送信済みフラグをクリアする 

# ソースコード
https://github.com/kumanobori/ChatworkReminderBot

# 感想というか
GASデビュー作です。へんなとこがあったらご指摘頂けるとありがたいです。

# 謝辞
なんかごく当たり前のようにgetRoomsとか書いてましたが、Chatworkのライブラリはこちら使わせて頂きました。ありがとうございます。
https://github.com/cw-shibuya/chatwork-client-gas
React Hooksのメモ

・hooksは関数コンポーネント内でstateに値の追加や更新が行えるようにするもの？
・this.setState()のような処理を行う関数を自動で作成してくれる?

```index.js

import React, {useState} from "react";
import ReactDOM from "react-dom";

//function App()でも可
var App = function() {　

    //現在の値と値を更新する関数を取得
    //useState(n)のnがcntの初期値になる
    var [cnt, setCount] = useState(0);

    var addCount = function() {
        setCount(cnt + 1);
    }

    var minusCount = function() {
        setCount(cnt - 1);
    }

    return (
        <>
          <div>
              <p>Hello React!!</p>
              <input type="button" value="+1" onClick={() => addCount()} />
              <input type="button" value="-1" onClick={() => minusCount()} />
              <p>{cnt}</p>
          </div>
        </>
    )

}


/* 同じものをクラスコンポーネントで書く */
/*
class App extends React.Component {

    constructor(props) {
        super(props);
        this.state = {"cnt": 0};
        this.addCount = this.addCount.bind(this);
        this.minusCount = this.minusCount.bind(this);
    }

    addCount() {
        var cnt = this.state.cnt + 1;
        this.setState({"cnt": cnt});
    }

    minusCount() {
        var cnt = this.state.cnt - 1;
        this.setState({"cnt": cnt});
    }

    render() {
        return(
            <div>
                <p>Hello React!!</p>
                <input type="button" value="+1" onClick={this.addCount} />
                <input type="button" value="-1" onClick={this.minusCount} />
                <p>{this.state.cnt}</p>
            </div>
        );
    }

}
*/

/* クラスコンポーネントと関数コンポーネントで共通 */
ReactDOM.render(<App />, document.getElementById("app"));

```

hooksは複数の状態(this.state)を管理できる。
ここでは{gender: "", place: ""}の状態を管理している。

```index.js

import React, {useState} from "react";
import ReactDOM from "react-dom";

var App = function() {

    //genderの値を書き換えるsetGender()関数が自動で作成される?
    var [gender, setGender] = useState("男性"); 
    var [place, setPlace] = useState("東京都");

    //genderの値を更新する
    var onClick = function() {
        if (gender === "男性") {
            setGender("女性");
        } else {
            setGender("男性");
        }
    }

    //処理が１行だけなのでonChange={() => setPlace(document.getElementById("place").value()}でも良い
    var onChange = function() {
        setPlace(document.getElementById("place").value);
    }

    return (
        <>
          <p>性別 : {gender}</p>
          <p><input type="button" value="性別変更" onClick={() => onClick()} /></p>
          <p>居住地 : {place}</p>
          <select id="place" onChange={() => onChange()}>
              <option value="東京都">東京都</option>
              <option value="神奈川県">神奈川県</option>
              <option value="埼玉県">埼玉県</option>
          </select>
        </>
    )

}


/* クラスコンポーネントと関数コンポーネントで共通 */
ReactDOM.render(<App />, document.getElementById("app"));

```

##コンポーネントの命名について(2020/07/31追記)
コンポーネントの名前は必ず大文字で始めなければならない。
小文字だとReactDOM.render()の第一引数とコンポーネント名が一致していてもエラーが発生する。

```index.js

//良い例
class App extends React.Component { (中略) }
//ダメな例
class app extends React.Component { (中略) }

//良い例
var App = function() { (中略) }
//ダメな例
var app = function() { (中略) }


```
GitHubでまだ消耗してるの？- Are you still worn out on GitHub?

Are you still worn out on GitHub?
===

GitHubでまだ消耗してるの？
GitHubってレスポンス遅くない？
時間を節約したくない？

# You don't have to use GitHub to use Git.

多くの人が知らないので一応説明しておくと、**Git**は、**GitHub** を使わなくても使えます。

もしあなたがエンジニアなら、MacかLinuxを使っていると思います。私はFreeBSDですが。え？Windows？？？（沈黙）

# Creating a Git repository 

**GitHub**は、Gitの **Repository** をホスティングしていますが、Gitの Bare Repositoryそのものは、あなたのパソコンでも作れて共有できます。

```sh
cd ~/
mkdir temp.git # temp.git ディレクトリ内に bare repositoryを作成する
cd temp.git
git init --bare # bare repositoryの作成
cd ~/
git clone ./temp.git cloned_repository_is_here
```

# How to clone via SSH

sshでログインできれば、ssh経由で git repository を clone できます。

```sh
git clone username@example.com:~/temp.git
```

# I don't understand SSH.

THAT'S COOL!!
sshを知らないエンジニアも最近は多いですよね！
そもそもWebデザイナー・コーダーの方にはsshは荷が重いですよ！
そのような場合も想定してあって、GitにはGitサーバーというデーモンが常駐してくれるプログラムがあります！
10年ほど前に、一度作ったことがありますが、もう忘れてしまいました。詳しくはググってみて下さい！

# fatal: transport 'file' not allowed

If you clone a local repository, an error will occur.
ローカルのリポジトリをクローンするとエラーが発生するようになりました。
如果克隆本地存储库，则会发生错误。

This issue is resolved by running the following command:
この問題は、次のコマンドを実行することで解決します。
通过运行以下命令可以解决此问题。

```sh
git config --global protocol.file.allow always
```
【Ruby】Rubyにおける二次元配列の初期化と扱い方

#はじめに
Rubyのアルゴリズムを本気で学び始めた当初、二次元配列に苦しめられましたが、少しずつ扱いに慣れてきたので、備忘録＆誰かの助けになればな...と思い書かせていただきます。
##二次元配列とは？
配列の中に、配列が格納された形の配列のことです。
また２よりも更に大きい次元の配列を多次元配列と言います。

```ruby:arr.rb
#一次元配列（通常の配列）
colors = ["Red", "Green", "Blue"]

#二次元配列
colors = [["Red", "Green", "Blue"], ["Yellow", "Purple", "Orange"]]

```
##二次元配列の初期化の方法
二次元配列を初期化（生成）する上で一つ注意点があります。

以下を参照ください。

```ruby:arr.rb
arr = Array.new(2, Array.new(3, 0))
#=> [[0, 0, 0], [0, 0, 0]]
```
一見、二次元配列になっているのですが、実はこれ、二次元目の配列が全て同一のオブジェクトとして生成されてしまっています。
試しに配列の値を変更してみます。

一つ目の要素（配列）の中の、真ん中の要素に「１」を代入してみます。

```ruby:arr.rb
arr = Array.new(2, Array.new(3, 0))
p arr
#=> [[0, 0, 0], [0, 0, 0]]

arr[0][1] = 1
p arr
#=> [[0, 1, 0], [0, 1, 0]]

#期待していた出力
#=> [[0, 1, 0], [0, 0, 0]]

```
このようにarr[0]に対して行った代入が、別の要素にまで代入されています。

これは最初の初期化の時点で、別々のオブジェクトとして定義できていないことによって起こります。

###個別のオブジェクトとして生成する方法
ブロックを渡すことにより生成します。

```ruby:arr.rb
arr = Array.new(2) { Array.new(3,0) }
p arr
#=> [[0, 0, 0], [0, 0, 0]]

arr[0][1] = 1
p arr
#=> [[0, 1, 0], [0, 0, 0]]
```

※補足
よりわかりやすい説明のコメントいただきましたのでそのまま引用させていただきます。
@kts_h さんありがとうございます。

>メソッドの引数は、メソッド呼び出しの際に一度だけ評価されるので、Array.new(3, 0) を評価して得られた同一のArray オブジェクトが外側の配列の全ての要素になってしまうのに対し、ブロック付きメソッドのブロックは、反復するたびに評価されることがあり、Array.new { |i| ... } はその一例であるため、外側の配列の要素を作るたびに Array.new(3, 0) が評価されて、その都度、異なる Array オブジェクトが作成され、外側の配列の要素になることを明示すると、ほかの初心者の人たちに対し、より親切な説明になるのではないかと思いました。

##二次元配列の操作について
一次元配列とは違い、二次元配列は次元が深くなっていて、一見複雑にも見えるのですが、非常に直感的に操作できます。

###代入
初期化の際にも行いましたが、代入は以下のように行います。

```ruby:arr.rb
arr = Array.new(2) { Array.new(3,0) }

arr[0][0] = 1
p arr
#=> [[1, 0, 0], [0, 0, 0]]

arr[1][2] = 1
p arr
#=> [[0, 0, 0], [0, 0, 1]]
```

###繰り返し処理（each）
次に繰り返し処理での、扱い方です。
今回は「eachメソッド」を使用します。

```ruby:arr.rb
arr = Array.new(3) { Array.new(3,0) }
arr.each do |p_a|
  p p_a
end

#=>
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]

#一番深い次元の要素を一つずつ出力する場合
arr = Array.new(3) { Array.new(3,0) }
arr.each do |p_a|
  p_a.each do |c_a|
    p c_a
  end
end

#=>
0
0
0
0
0
0
0
0
0
```

このように繰り返し処理を二重にかけることで、一番深い要素一つ一つにアクセスできました。

二次元配列は慣れるとロジックを組む上で便利です。
例えば、配列の中の数値でFizzBuzzを行う場合

```ruby:arr.rb
int = 1
arr = Array.new(10) { Array.new(3, 0) }
arr.each_with_index do |p_a, p_index|
  p_a.each_with_index do |c_a, c_index|
    if int % 15 == 0
      arr[p_index][c_index] = "FizzBuzz"
    elsif int % 5 == 0
      arr[p_index][c_index] = "Buzz"
    elsif int % 3 == 0
      arr[p_index][c_index] = "Fizz"
    else
      arr[p_index][c_index] = int
    end
    int += 1
  end
end

p arr
#=>
[[1, 2, "Fizz"], [4, "Buzz", "Fizz"], [7, 8, "Fizz"], 
["Buzz", 11, "Fizz"], [13, 14, "FizzBuzz"], [16, 17, "Fizz"], 
[19, "Buzz", "Fizz"], [22, 23, "Fizz"], ["Buzz", 26, "Fizz"], 
[28, 29, "FizzBuzz"]]

```

このように非常に直感的に操作することができます。

※コードは非常に助長だと思います。ゴメンナサイ

ご指摘等ありましたらズバズバとお願いいたします。
axiosライブラリを用いてクエリパラメータを指定する方法(GET,POST)

### はじめに

時々忘れることがあるので、今回も自分用メモとして残します。
今回は、簡潔に非同期処理を記述する為にasyncとawaitを利用していますが説明等はしておりません。ご了承くださいませ🙇‍♂️

### GETリクエスト
主にAPIを叩いて、データを取得する時に利用します。

```js
const response = await axios.get(url, {
  params: {
    id: 1,
    name: 'hoge'
  }
})
```
上記のように記述すると、id=1とname='hoge'をクエリパラメータとして渡すことができます。
urlの箇所は、<font color="red">APIにアクセスしたいエンドポイント</font>を記述してください:writing_hand:



また、直接URLに記述する方法もあります。

```js

const response = await axios.get('url?id=1&name="hoge"')
```

複数のパラメータを指定する場合は、&記号（アンパサンド）でつないで記述します。


### POSTリクエスト
主にAPIを叩いて、データを保存する時に利用します。

```js

const response = await axios.post(url, {
  id: 1,
  name: 'hoge'
})
```
第二引数に保存したいデータをオブジェクトで指定します。

はい、以上になります。

### おわりに
毎回、自分用のメモとして記述してしまってすみません...もし今回の記事で誤字や脱字等ありましたらご指摘頂けると助かります。閲覧して頂き、ありがとうございました。
【Java】スーパークラス/サブクラスのコンストラクタあれこれ

#目次
- はじめに
- 前提知識
    - 継承クラスについて
    - コンストラクタ
- 今回のキモ
    - 暗黙的なコンストラクタ実行
- おわりに

##はじめに
どうも駆け出しエンジニアです。
先日会社でコーディングをしていた際に人の書いたコードの続きを書かなくちゃいけなくなったんですが、
その時に<b>クラスの継承,コンストラクタ</b>でドツボにはまってしまいかなりの時間を使ってしまいまして....
もう一回頭から学習しなおした所、わからないことがボロボロ出てきてヒドかったので再度まとめることにしました。

なお、本記事は
　・「現在Javaを触っている人」
　・「もう一度内容を復習したい人」
向けとなっております。
各クラス名/変数名は適宜読み替えてください。


##前提知識
#####継承クラスについて
- 継承クラス＝新しいクラスを作るとき、以前作った機能と共通する部分を引き継ぐクラス
- 継承元のクラスのことを「親クラス」、継承先のクラスのことを「子クラス」と呼ぶ。
- 同意義で「スーパークラス」「サブクラス」とも呼ぶ
   ※本記事ではスーパー/サブで表現。
- 継承クラスのインスタンスを作成することで、継承クラスのメソッド/フィールドにアクセスできる。
- ↓↓↓↓記述の仕方は↓↓↓↓

```Super.java
class Super {
  public void exampleSuper(){
    //何らかの処理
  }
}
```
```Sub.java
class Sub extends Super(){ //クラス名 extends 継承元クラス名　で継承。
  public void exampleSub(){
    //何らかの処理
  }
}
```

####コンストラクタ
- コンストラクタ=クラスのインスタンスを作成したときに自動で必ず呼び出されるメソッドのこと
- クラス名と同じ名前のメソッドのこと
- 通例コンストラクタ名は上記理由から先頭は大文字 
- 戻り値はもともと想定していないので、voidは書いちゃダメ(→コンパイルエラー)
- 主にそのクラスのフィールド(メンバ変数)を初期化するのに用いられる。
- というか通例として/暗黙的にそうらしいので、それ以外の余計なことはしない方が吉。<br>
→大規模開発における可読性/保守性の向上につながる<br>
- ↓↓↓↓記述の仕方は↓↓↓↓

```Smple.java
class Sample{
  public Sample(){
    //ここがコンストラクタ
  }
  public void exampleMethod(){
    //これはただのクラスメソッド
  }
}
```

##今回のキモ
####暗黙的なコンストラクタ実行
- クラスのインスタンス化時、継承階層の最上位から下方向へ、順番にインスタンス化されていく
- サブクラスのコンストラクタは最初にスーパークラスのコンストラクタを呼び出す
- スーパークラスのコンストラクタを明示的に呼び出さないとき、自動的に引数のないコンストラクタが呼び出される。
- コンストラクタの呼び出し時は<b>super()</b>メソッドが暗黙的に(自動的に)実行されている

>●super();
>>スーパークラスのコンストラクタを呼び出すメソッド。
>>サブクラスのコンストラクタは"言語実装として"暗黙的(自動的)にスーパークラスのコンストラクタを実行するので、
必ず記述が必要なものではない

- ↓↓↓↓具体例↓↓↓↓

```Super.java
class Super {
	Super() {
		System.out.println("スーパークラスです!");
	}
}

```
```Sub.java
class Sub extends Super {
	Sub() {
		// 暗黙的にスーパークラスのコンストラクタが実行される
		System.out.println("サブクラスです！");
	}
}

```
```Main.java
class Main {
	public static void main(String[] args) {
		Sub obj = new Sub();
}

```
```java
//実行結果
スーパークラスです！
サブクラスです！
```

####"暗黙的スーパーコンストラクターは未定義です"
- スーパークラスのコンストラクタが引数を持つもののみ定義されている場合、暗黙的に実行される「super();」メソッドだけではコンパイルエラー。

▽解決方法
①スーパークラスに引数を持たないコンストラクタを作成する

```Super.java
class Super {
    public name;
    public Super(){
        //コンストラクタをオーバーロードさせる
    }
    public Super(String name){
        this.name = name;
    }
}
```

②サブクラスのコンストラクタ内で、スーパークラスのコンストラクタの引数に合わせたsuper();メソッドで、明示的にスーパークラスのコンストラクタを呼び出す。

```Super.java
class Sub {
    public name;
    public Super(String name){
        // メイン->サブ->スーパーの順で渡ってきたname変数の値をフィールドにセット
        this.name = name;
    }
}
```
```Sub.java
class Sub extends Super {
    Sub(String name) {
    //メインクラスのStrin型変数nameと対応->スーパークラスのコンストラクタへ受け渡し
    super(name);
    }
}
```
```Main.java
class Main {
	public static void main(String[] args) {
		Sub obj = new Sub(String name);
	}
}
```

##終わりに
今回も長くなりましたが読んでいただきありがとうございました。
次回はtry-catchでの例外処理についてかければな～と思ってます。
では。
現地・現物

TPSの教えに**現地・現物**はとても有名です。
ただ、ホワイトカラーやシステム開発などの現場で、どこまでこの通りに把握して実践しているでしょうか？
仕事・作業をしている現場には様々な見えない情報があります。
雰囲気が良い、冷たい雰囲気、温かい雰囲気　これも**現地・現物**に含まれる一つです。
コロナウイルス感染対策の一環で在宅勤務が増えていますが、その在宅勤務でも同じ現場というバーチャルな場があります。
在宅勤務者を対象にした塾を実施していました。この塾では回線の都合で動画の量はすくなく、写真（静止画）と音声だけで実施することも多くありました。
当初は発表者が発言している時に、聴いている他の塾生が声を出して反応することが出来ていませんでした。しかし、順場に司会や発表者を経験することで、声出しや時には発表中にチャットで意見や感想を述べるように変わっていきました。
その結果、声だけで、バーチャルなチームの雰囲気を読み取れるようになってきました。
人間というのは、限られた環境でも、仲間との良い関係を築こうと思って行動していると、その現場特有の目に見えない環境（場）を作ることができます。
この場を大切にし、**五感で感じる**ことで、ホワイトカラーでの真の現地・現物が見えてきます。
**人間の素晴らしい能力です**。
この素晴らしい能力をどれだけ使えているのでしょうか？
Rails 割と使うのにど忘れするコトをまとめてみた。

Railsを約3年程やってみて、**それなりに使うけど毎日使うわけでもない**のでいざ書くとなると**「どう書くんだっけ？」**とついド忘れしてしまう項目をまとめてみた。

# Enum
個人的に「あれ・・・思い出せない」になる回数1位

参考：[【Rails】Enumってどんな子？使えるの？](https://qiita.com/ozackiee/items/17b91e26fad58e147f2e)
### 記述例
```ruby:menu.rb
class Menu < ApplicationRecord
  enum category: { japanese: 0, chinese: 1, western: 2, other: 3 }
end
```

```yml:ja.yml
ja:
  enums:
    menu:
      category:
        japanese: 和食
        chinese: 中華
        western: 洋食
        other: その他
```

### よく使うメソッド
```console
# 設定を確認する
[18] pry(main)> Menu.categories
=> {"japanese"=>0, "chinese"=>1, "western"=>2, "other"=>3}
[19] pry(main)> Menu.categories["japanese"]
=> 0
[20] pry(main)> Menu.categories[:japanese]
=> 0

# 設定(日本語)を確認する
[21] pry(main)> Menu.categories_i18n
=> {"japanese"=>"和食", "chinese"=>"中華", "western"=>"洋食", "other"=>"その他"}

# 個々のインスタンスの値を確認する
[22] pry(main)> menu = Menu.last
[23] pry(main)> menu.category
=> "japanese"
[24] pry(main)> menu.category_i18n
=> "和食"
[25] pry(main)> menu.category_before_type_cast
=> 0
```

# Scope
JavaScriptのアロー関数の様な `->` や、引数ありの場合の `()` を「どこに書くだっけ」となってしまう

参考：[Railsでよく利用する、Scopeの使い方。](https://qiita.com/ngron/items/14a39ce62c9d30bf3ac3)

### 記述例
```ruby:menu.rb
class Menu < ApplicationRecord
  enum category: { japanese: 0, chinese: 1, western: 2, other: 3 }

  # 引数なしの場合
  scope :asian_food, -> { where(category: [Menu.categories[:japanese], Menu.categories[:chinese]]) }
end
```

### 呼び出し方

```ruby
[10] pry(main)> Menu.asian_food
=> [#<Menu:0x0000560df31d6058 id: 1, category: "japanese", name: "出し巻き卵">, #<Menu:0x0000560df31d5f18 id: 2, category: "japanese", name: "味噌汁">]
```

# ActiveRecordのSQLベタ書き
ActiveRecordのメソッドだけでは取得できないデータが欲しい時に部分的にSQLをベタ書きする場合の書き方。プレイスホルダーをどう書くのか忘れてしまう。

```console
[13] pry(main)> Menu.where('created_at >= ?', Date.today)
=> [#<Menu:0x0000561ef0c68c38
  id: 3,
  category: "japanese",
  name: "お好み焼き",
  created_at: Sat, 25 Jul 2020 15:43:24 JST +09:00,
  updated_at: Sat, 25 Jul 2020 15:43:24 JST +09:00>]

```

# routes

`member` と `collection` はどっちがidありでどっちがid無しか、とっさに分からなくなってしまう。

参考：[railsのroutes.rbのmemberとcollectionの違いをわかりやすく解説してみた。〜rails初心者から中級者へ〜](https://qiita.com/hirokihello/items/fa82863ab10a3052d2ff)


```ruby:routes.rb
resources :menus do
  collection do
    get :photo
  end

  member do
    get :reviews
  end
end
```

結論、`id` があるのが `member` 、無いのが `collection`。

```console
 photo_menus GET    /menus/photo(.:format)          menus#photo
 reviews_menu GET   /menus/:id/reviews(.:format)    menus#reviews                                                         
```
QIIME2でOTU名とその系統（門、科、属など）の対応表を得る

[前回の記事](https://qiita.com/taka-ohi/items/55648c189eee6d5c0085)でOTUのカウントデータの取得方法を書いたが、多様性解析など以外の多くの場合、その系統をもとにデータを議論することになると思う。

というわけで、今回はQIIME2を使ってOTUとその系統の対応表を得る方法について書く。

と言っても、一度でもQIIME2を触ったことがある人にとっては正直全然難しくない。
個人的には今後、系統名を用いて色んな解析を投稿する際にこの記事を引用するために書いた。

[公式のチュートリアル](https://docs.qiime2.org/2020.6/tutorials/moving-pictures/)に従って、QIIME2上でtaxonomy.qzvを開く（ブラウザで表示）。


```html:QIIME2
qiime tools view taxonomy.qzv
```

今回は簡単に説明するために、[このリンク](https://view.qiime2.org/?src=https%3A%2F%2Fdocs.qiime2.org%2F2020.6%2Fdata%2Ftutorials%2Fmoving-pictures%2Ftaxonomy.qzv)からサンプルデータのtaxonomy.qzvをブラウザ表示したところに飛べるようにしておく。

![スクリーンショット (87).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682014/b2c1a8cd-20cc-f901-e09a-79a1146be4bb.png)

1列目がOTUのID、2列目が系統名、3列目が信頼度（詳しくは[こちら](https://forum.qiime2.org/t/how-is-the-confidence-calculated-with-taxa-assignments/179)）。

左上の"Download metadata TSV file"を押し、対応表を.tsv（テキストファイル）としてダウンロードする。
読書会「プログラマが知るべき97のこと」#4

# 1．今回の読んだ記事
No.17　[コードに書けないことのみをコメントにする](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AB%E6%9B%B8%E3%81%91%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8%E3%81%AE%E3%81%BF%E3%82%92%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AB%E3%81%99%E3%82%8B/)　
著者: Kevlin Henney

# 2．記事の概要
**コードに書いていないことではなく、書けないことをコメントにする**

+ コードにコメントをつけるのは理論的にはいいこと
+ コメントを書くことにも文章術がある
+ 不適切なコメントは見たものの集中力を削いだり、誤った情報を与える
+ 一部の不要なコメントによって、重要なコメントまで読み飛ばされる可能性がある
+ 読む人にとって価値のあるコメントとは、コードに書いていないあるいは書けないことである



# 3．この記事を選んだ理由・感想
**理由**
どのようなコードを書いたときにコメントが必要になるのか知りたいと思ったから。
コードにかけないことの具体的な事例をグループ内でディスカッションしたかったため。

**感想**
「コメントはたくさん書いた方が良い」という考えが変わった。
（不適切なコメントが作業者の弊害になりうるなど）
コードに書けないこととは、具体的にどのようなものがあるのか、疑問に思った。

# 4．議論

**コードに書けないこととは何ですか？**
	
- なぜ、こういう実装をしているのかを残しておくために使う
- 普通はやらないけれど、特別な意図があってやっている処理にコメントを書いた方がよい
    - 以前見かけて役に立ったもとしては、ライブラリのバグなどに対応するための処理に対するコメントは書いてあって役に立った

**必要なコメントとはどういうものなのか？**

- 以前「このフェーズでは対応しない」というコメントを見たことがあるが、このようなコメントは必要ですか？
    - こういったコメントはずっと消えないという可能性はないですか？
    - TODOなどで書けばよいのでしょうか？
        - こういった後々まで残る課題は、別で管理した方がよいと思う
	
**コメントよりデバッグログに説明を書く**

- コメントを書くより、デバッグログに書いた方が良いというアドバイスをいただいたことがある
    - デバッグログに書くとテストの時や、異常系の処理などの時に役立ちそう

		
**型が決まっていない言語の場合のコメント**

- Pythonなどの型の決まっていない言語には書いた方がいいと思う
- 対して、Javaなど厳密に型が決まっている場合は見ればわかるのでコメントで書く必要はない


**昔のソースコード**

- 以前の現場は組み込み系で、変更履歴をコメントに書いていた
    - 昔はたくさんコメントを書けと言われたけれど、今は無駄なコメントは無い方がいいと感じる
    - （中年社員）そういうコードは懐かしいですね、ヘッダ部分にたくさん更新履歴が書かれていました・・・

# まとめ
読書会4回目。
参加者の若手社員も読書会で話したことを業務で意識しているように思う。
何かしら学ぶことがあったのかなと感じた。
次回に続く。
初心者がSeleniumでWebDriverを使うときにつまづいた時に参考にしたコードなど 

##画面内にない要素をクリックすることはできない
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

スクロールして画面内に出すか、
***
    driver.set_window_size(xxxx,yyyy)
で最初に画面サイズを変更する。
自分は毎回スクロールするのが面倒なので画面サイズを1980、1280にした。
他にもIDなどの要素までスクロールできるっぽい。
***
##ユーザーエージェントがないとロボット扱いしてくるサイトもあるので
    options.add_argument(f'user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36')
ユーザーエージェントを偽装する。
***
##Javascriptのボタンなどをクリックできない場合
    elements = driver.find_element_by_xpath("XPATH")
    loc = elements.location
    x, y = loc['x'], loc['y']
    actions = ActionChains(driver)
    actions.move_by_offset(x, y)
    actions.click()
    actions.perform()
XPATHの座標でクリックする。
***
##テキストが画面内にないと.textなどでは取得できない
    text = driver.find_element_by_id("ID").get_attribute("textContent")
get_attributeで取得する。

##おわり
まだ始めて一ヶ月なのでこれ違うよなどツッコミがあるかもしれませんが、優しく言ってくださると幸いです。
いまだベクトルタイルに対応していない GIS のためのモザイク

いまだベクトルタイルに対応していない GIS を使って地理空間情報を分析することもあるでしょう。

![Tirana,_Albania_2017-04_Tirana_Mosaic_04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/7d93f1f0-d28a-54bc-992c-0a365a9d434d.jpeg)
Photo by Pasztilla aka Attila Terbócs

タイルをつなぎ合わせてモノリシックなデータに戻すことをモザイクと呼びましょう。

モザイクを作る方法を開発しました。レポジトリ名は [mozdev](https://github.com/optgeo/mozdev) にしました。

実際の中身はワンライナーです。このワンライナーを動かすためには、例えば [equinox](https://github.com/unvt/equinox) を使って国連ベクトルタイルツールキットを導入してください。

```zsh
$ rake
```
上記コマンドで、タイルセットをダウンロードして Shapefile に変換します。

## mozdev/Rakefile
```ruby
M = "https://cyberjapandata.gsi.go.jp/xyz/experimental_landformclassification1/mokuroku.csv.gz"

task :default do
  sh "curl --silent #{M} | gzcat | ruby tyler.rb | tippecanoe-json-tool > mozdev.geojsons; ogr2ogr -skipfailures -overwrite mozdev.shp mozdev.geojsons"
end
```

## mozdev/tyler.rb
```ruby
U = "https://maps.gsi.go.jp/xyz/experimental_landformclassification1"
SILENT = false

while gets
  fn = $_.split(',')[0]
  zxy = fn.split('.')[0].split('/').map{|v| v.to_i}
  next unless zxy[0] == 14
  system "curl #{SILENT ? '--silent' : ''} #{U}/#{$_.split(',')[0]}"
end
```

## モザイクのイメージ
<img width="715" alt="モザイクのイメージ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/b2e520d3-b2da-bab5-eaf4-6eda8e60257f.jpeg">
「地形分類（自然地形）」（国土地理院）

## 参考
実際に ogr2ogr でモザイク Shapefile を組み立てた時のエラーの出方は次のような感じでした。
<img width="783" alt="モザイク Shapefile を組み立てた時のエラーの出方" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/7397ac8a-5cfe-b220-e144-6a3e556f65e0.jpeg">

## 相手がベクトルタイルの場合
相手が GeoJSON ベクトルタイルではなく、ベクトルタイルである場合には、`tippecanoe-decode` を使うことになるでしょう。

`tippecanoe-json-tool` も、`tippecanode-decode` も、`tippecanoe` に同梱されています。
GitLabのissueをGanttLabを使ってガントチャート化する

業務でGitLab CEでレポジトリ管理、タスク管理を行っています。タスクの実績をガントチャートで見える化したいとの要望が出てきたので、[GanttLab.com \| A live Gantt chart for GitLab and GitHub](https://www.ganttlab.com/)をつかって実現してみました。

Note: GanttLab自体が[GanttLab.com \| A new GanttLab is out 🎉](https://www.ganttlab.org/news/2020/04/30/a-new-ganttlab-is-out/)に書かれているようにfull rewrite中らしく、まだまだ常用するには足りない機能がたくさんあります。
ちなみにGitLab PreminumのSilver以上であれば、Roadmap機能が使えるので、導入されているのであればそちらを使用するのが良いかと思います。

## GanttLabのインストール

GitLab CE自体は社内のサーバーにdockerで立てているので、Ganttlabも同サーバーに立てることとします。
インストールの手順は、[docs/download-and-install.md · master · GanttLab / GanttLab · GitLab](https://gitlab.com/ganttlab/ganttlab/-/blob/master/docs/download-and-install.md)にあります。

docker imageが用意されており、カスタマイズが必要なら自分でbuildする必要がありそうです。今回はカスタマイズする必要はなさそうなので、ありがたくofficialのdocker imageを使うことにします。
docker-composeでGitLab CE自体を動かしているので、`docker-compose.yml`にGanttLab用の設定を追加します。

```yml:docker-compose.yml
ganttlab:
  image: 'ganttlab/ganttlab:latest'
  restart: always
  ports:
    - '8282:80'
```

`docker-compose up`すれば`:8282`でアクセスできるはずです。

## GitLab CEと連携させる

`:8282`にアクセスすると、下記のようなGitLabとの連携ダイアログが出てきます。

![Screenshot from 2020-07-29 10-00-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177/c201ae59-46d0-31c7-6fd5-907de624f52a.png)

personal access tokenが必要なので、事前に取得しておきます。

取得方法は、[Personal access tokens \| GitLab](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#creating-a-personal-access-token)
Scopeは`api`にしておきます。(下記のスクリーンショットはread_apiになっています）現状GanttLabの方からwriteアクセスするようなことはなさそうなので、`read_api`権限で問題ないのですが、将来的にwrite accessが必要な機能[Ability to edit start and due dates right from GanttLab (#10) · Issues · GanttLab / GanttLab · GitLab](https://gitlab.com/ganttlab/ganttlab/-/issues/10)が実装されそうです。

![Screenshot from 2020-07-29 10-35-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177/a37723ae-985d-6127-4c0d-9567d9defe9a.png)

## 使い方

[How it works /README.md · master · GanttLab / GanttLab · GitLab](https://gitlab.com/ganttlab/ganttlab/-/blob/master/README.md#how-it-works)

に詳しいですが、

StartDateは、下記のルールに基づいて表示され、上から順番に優先されます。
1. issue description内のGanttStartから始まる行
2. (GitLabのみ)milestoneの開始日
3. issueが作られた日

Due Dateは下記の通りでこちらも同じく上から順番に優先されます。

1. issue description内のGanttDueから始まる行
2. (GitLabのみ)issueのDue date
3. (GitLabのみmilestoneのDue date
4. issueのstart date

GitLabの場合、Due dateはあるものの、Start dateは独立して用意されておらず、Issue description内の`GanttStart: `を使うのが良さそうなので、issue templateに書いておくのが良さそうです。


## Issue template 例

```md:.gitlab/issue_templates/template.md

GanttStart: 2020-XX-YY
/due in 1 weeks
```

[GitLab Quick Actions \| GitLab](https://docs.gitlab.com/ce/user/project/quick_actions.html)を用いればdue dateの入力をちょっとだけ楽することができます。
M-SOLUTIONS プロコンオープン 2020

M-SOLUTIONS プロコンオープン 2020にバーチャル参加しました。 
ABCDの4問ACでした。 
Python3を使用しています。

# A問題
ifで条件分岐させます。

```python
import sys
def input():
    return sys.stdin.readline()[:-1]


def main():
    X = int(input())
    if X >= 1800:
        print(1)
    elif X >= 1600:
        print(2)
    elif X >= 1400:
        print(3)
    elif X >= 1200:
        print(4)
    elif X >= 1000:
        print(5)
    elif X >= 800:
        print(6)
    elif X >= 600:
        print(7)
    else:
        print(8)           
    
if __name__ == "__main__":
    main()
```

# B問題
条件を満たすまで操作を行い、操作回数がK以下であれば魔術を成功させられたと考えます。 
これは入力されるA、B、C、Kが小さいために可能です。 
<br>
M君は数字を2倍にする操作を行うため、最も小さい数となるべきAに操作を行わないことが分かります。 
つまり、Aの値が固定された状態で考えます。 
while文で、BがAより大きくなるように操作を行います。 
これにより、Bの値が固定されます。 
同様にwhile文でBより大きいCを求めることができます。

```python
import sys
def input():
    return sys.stdin.readline()[:-1]


def main():
    A, B, C = map(int,input().split())
    K = int(input())
    count = 0
    while A >= B:
        B = B * 2
        count += 1
    while B >= C:
        C = C * 2
        count += 1
    if count <= K:
        print("Yes")
    else:
        print("No")
    
if __name__ == "__main__":
    main()
```

# C問題
この問題は、前学期より評点が高いが低いか判定する必要があるだけで、実際の評点を求める必要はありません。 
<br>
N学期の評点はA[0]*A[1] ~ *A[N-1]で求められます。
N+1学期の評点はA[1] ~ *A[N-1]*A[N]で求められます。 
評点の高低を比較するだけなので、A[0]とA[N]を比較するだけで十分です。 
これをfor文で繰り返し、N-K個の結果を表示します。

```python
import sys
def input():
    return sys.stdin.readline()[:-1]


def main():
    N, K = map(int,input().split())
    A = list(map(int,input().split()))
    for i in range(N - K):
        if A[i] < A[i + K]:
            print("Yes")
        else:
            print("No")  
    
if __name__ == "__main__":
    main()
```

# D問題
株価が低いときに買って、株価が高いときに売りたいというのが基本的な目標です。
<br>
まずi番目とi+1番目を比較し、大きくなっていれば1、小さくなっていれば-1というリストを作ります。 (リスト内包表記の利用) 
1のときは買えるだけ買います。 
1が続くということは株価が上がっていくということなので、一番初めに1になった地点で買えばOKです。 
同様に-1になったときは全ての株を売ります。 
-1が続くということは株価が下がっていくということなので、一番初めに-1になった地点で売ればOKです。

```python
import sys
def input():
    return sys.stdin.readline()[:-1]


def main():
    N = int(input())
    A = list(map(int,input().split()))
    zougen = [-1 if A[i] > A[i + 1] else 1 for i in range(N - 1)]
    money = 1000
    kabu = 0
    for i in range(N-1):
        if zougen[i] == 1:
            kabu += money // A[i]
            money = money % A[i]
        else:
            money += kabu * A[i]
            kabu = 0
    print(A[-1] * kabu + money)



if __name__ == "__main__":
    main()
```
C#によるPOSレジ・サーマルプリンター（レシートプリンター）開発入門 記事一覧

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">POS for .NET関連は企業で扱うことが多いからか、インターネット上の情報がかなり少ないので個人開発が大変。<br>MSDNと機器メーカーのサンプルをいつも以上にじっくり読み込まないといけない。</p>&mdash; おーとま (@automatic_csp) <a href="https://twitter.com/automatic_csp/status/1271072251115220992?ref_src=twsrc%5Etfw">June 11, 2020</a></blockquote>
POS関連の記事って少なくないですか……？

個人的に触る人が少ないのか、POSレジ関連の開発についてまとめられたブログ等の記事はネット上にほとんどありません。Googleで「[OPOS](https://www.google.co.jp/search?q=OPOS)」や「[POS for .NET](https://www.google.co.jp/search?q=POS for .NET)」、「[POS 開発](https://www.google.co.jp/search?q=POS 開発)」などを検索しても、MSDN以外に引っ掛かるのは

- OPOSって知ってますか？
- POS開発に強い会社5選！

といったところ。いざ開発してみようとなると、まわりに知っている人がいない限り、説明書を熟読して必要なドライバーをインストールし、機器メーカーや Microsoft が出しているサンプルを何日もかけて読み込むしかないわけです。
このサンプルを読み込む時間がもったいない。私はものを買ってから思い通りに扱えるようになるまで3か月もかかりました。
ということで、機器の購入からC#で機器を動作させるまでの手順を解説していこうと思います。この記事が開発のハードルを下げることに繋がれば嬉しいです。

# 記事一覧
以下よりどうぞ。

## その1: [開発用にサーマルプリンターなどのPOS機器を購入する時のポイント](https://qiita.com/Automatic9045/items/adca1d0995022bae2fa1)
安価で日本製の機器を購入する方法と、その際の注意点を説明しています。
おまけとして、私のうろ覚えな記憶を基に書いた日本の機器メーカー一覧もあります。

## その2: [サーマルプリンターなどのPOS機器を制御する何通りかの方法](https://qiita.com/Automatic9045/items/c02350b71cd4fab0e378)
POS機器を制御する何通りかの方法を、機器の種類別に説明しています。

## その3: [EPSON製のサーマルプリンターなどのPOS機器をセットアップする](https://qiita.com/Automatic9045/items/820f2a4dccb1b2887065)
どのメーカーでも、セットアップの方法（ドライバーのインストールや使用機器の登録など）はホームページを見れば大体書いてあります。
しかしその中でも、EPSON製の機器についてはカスタマイズ性の高さからセットアップの方法がそこそこ複雑だったので、EPSON製に限って解説しました。

## その4: [C#+POS for .NETでサーマルプリンター等のPOS機器を制御する](https://qiita.com/Automatic9045/items/64073010955ceb8928be)
POS for .NETを利用してPOS機器を動作させる方法を説明しています。

## おまけ1: [POS for .NETのPrintMemoryBitmapで、Graphicsで編集したBitmapを渡せない件](https://qiita.com/Automatic9045/items/6ff588da95e94aa708c4)
クセの強いPrintMemoryBitmapメソッドの使い方を説明しています。

## おまけ2: [【EPSON製 サーマルプリンター】過剰なロール紙の頭出しをやめさせる方法](https://qiita.com/Automatic9045/items/c22e2069a37323ebf07d)
プリンターの電源を入れる度に過剰にロール紙の頭出しをしてくる場合の対処法を説明しています。
rails turorial 11章あたりでハマるだろうこと

# 送信するメールがエンコードされててリンクを踏めない

サインアップ時、nameに日本語を入れる

<img width="994" alt="スクリーンショット 2020-07-29 18.53.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/12342c48-40ab-ac8f-f12b-84d430e3a49f.png">

railsのログをみてみると

<img width="569" alt="スクリーンショット 2020-07-29 18.52.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/1872eb93-39de-2275-b445-a2ee4ce1adc7.png">


```
http://localhost:3000/account_activations/AOSiSUDhma-B1bwZe3Wd_g/edit?email=3Dhogehoge%40gmail.com=0D
```

クエリのemailに謎の"3D"がついている。
その他所々で謎の0Dや3Dが、、、

ログからこのリンクを踏もうとすると

```
User.find_by(email: '3Dhogehoge@gmail.com')
```
を探査してしまいrootに飛ばされる。



### quoted-printable

<img width="573" alt="スクリーンショット 2020-07-29 18.57.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/08e2320b-7306-3146-edd2-5e1311046005.png">

Content-Transfer-Encoding: quoted-printableが原因で
=が=3Dに変換される。

メール本文に日本語があると、7bit文字に変換できないため、
Content-Transfer-Encoding: quoted-printableが登場する。
Content-Transfer-Encoding: quoted-printabl
は8bit文字を7bit文字に変換してエンコードする。

[What does 3D mean in this html email?](https://www.sitepoint.com/community/t/what-does-3d-mean-in-this-html-email/7033)
[quoted-printable](https://wa3.i-3-i.info/word11938.html)

quoted-printablがデコードされる前のurlを踏んでいるので、正しいリンクに飛ばない。

## 解決策
本番環境ではちゃんとデコードされたリンクを踏むので、解決策とまでは言わないが一応
### mail-iso-2022-jpを使う

```Gemfile

group :development, :test do
       ・
       ・
       ・
  gem 'mail-iso-2022-jp'
end
```

bundle installして

```application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: 'noreply@example.com',
  charset: 'ISO-2022-JP'
  layout 'mailer'
end
```


## 最後に

本番環境ではちゃんとデコードしてくれるので、charset指定は変えずにokです。


参考
[日本語メールの仕組み](https://sendgrid.kke.co.jp/blog/?p=10958)



日々精進