OmniAICreator/Qiita-1.07M huggingface dataset:
circleci/slack@4.x.xで、複数のjobを持つ場合のpass/failedを通知仕分ける方法

# 初期設定

orbのgithubを見ると迷うことなく終えられるため、そちらを参考にしてください
https://github.com/CircleCI-Public/slack-orb/wiki/Setup

今回、環境変数を設定する際に `slack` コンテキストの設定を想定します

# 通知を分ける難しさ

`slack/notify` では、 `event` パラメーターによって、通知を行う条件を出し分けることができます。

```yaml
- slack/notify:
    channel: 'xxx'
    event: fail
    template: basic_fail_1
```


例えばこれだと、failしたときにだけslackに通知されます。

しかし、  `event` は同一job内の状態のみ見ます。
つまり **複数のjobに跨る場合、例えばnotifyだけ行うjobを作った場合、常にpassになります**


```yaml
jobs:
  notify:
    executor: xxx
      steps:
        - slack/notify:
            channel: 'xxx'
            event: fail
            template: basic_fail_1
workflows:
  test:
    jobs:
      - build
      - test
      - notify:
          requires:
            - build
            - test
          context:
            - slack
```

こういう書き方をしても、 **`event: fail`となることはないので、何も起きません**

# 通知仕分ける方法

以下の考え方で出し分けます

- 多数jobを持つworkflowの場合、1つ1つの成功を知るのはノイズになるのでやりたくない
- workflowのjobの内、1つでも失敗したら通知を受けたい

というわけで、より具体的に言うと

- 失敗したら通知を受けたいjobの最後に、 `event: fail` のnotifyを差し込む。たくさん書くので、 `command` 化する
- 成功したら通知を受けたいjobは、通知を送るだけのjobを作って、 `requires` で制御する。

という感じになります。

```yaml
# 最初にコマンドを作る
commands:
  notify_failed:
    steps:
      - slack/notify:
          channel: 'xxxx'
          event: fail
          template: basic_fail_1
  notify_passed:
    steps:
      - slack/notify:
          channel: 'xxxx'
          event: pass
          template: basic_success_1

# buildとtestというjobがある想定
jobs:
  build:
    executor: xxx
    steps:
      - checkout
      - restore_modules
      - run:
          name: install dependencies
          command: yarn install
      - save_modules
      - notify_failed # このjobが失敗した場合のみ通知する
  test:
    executor: xxx
    steps:
      - checkout
      - restore_modules
      - run:
          name: install dependencies
          command: yarn install
      - run:
          name: run test
          command: yarn test:ci
      - notify_failed # このjobが失敗した場合のみ通知する
  notify:
    executor: plain
    steps:
      - notify_passed # 成功の通知だけするjobを作る

# requiresを使うことで、成功通知のjobを失敗時に抑制する
workflows:
  version: 2
  test:
    jobs:
      - build:
          context:
            - slack
      - test:
          requires:
            - build
          context:
            - slack
      - notify:
          requires:
            - build
            - test
          context:
            - slack
```

# 所管

Circle CIの設定など、普段あまりやらないので、ちょっと大変やった。
GestureDetectorを用いたドラッグ&ドロップの実装【Flutter】

Flutterでウィジェットのドラッグ＆ドロップを実装するには通常、Draggableウィジェットでラップすると実現できる。
だが、例えば「グリッド線に沿ってドラッグ」などのギミックを作りたいときは不向きなのではないか？と思った。
（もしかするとDraggableでもできるかもしれないけど！わからん！）

そうして２日間__GestureDetector__を利用したドラッグ＆ドロップの方法を模索していたが、苦戦。
最終的にStack Overflowに質問をしてみたところ、秒速で解決したので、日本語でまとめておく。

ちなみにStack Overflowの記事はこちら。

https://stackoverflow.com/questions/66719501/why-is-the-origin-of-the-widget-constantly-at-top-left-when-i-use-transform-tran

#コード

```dart
import 'package:flutter/material.dart';

class DragButton extends StatefulWidget {
  @override
  DragButtonState createState() => DragButtonState();
}

class DragButtonState extends State<DragButton> {
  Offset offset = new Offset(0.0, 0.0);

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: offset,
      child: GestureDetector(
        onPanUpdate: (DragUpdateDetails details) {
          setState(() {
            offset += details.delta;
          });
        },
        child: ElevatedButton(
          onPressed: null,
          child: Text('Button'),
        ),
      ),
    );
  }
}
```

こんな感じ。重要なのは下の部分。

```dart
        onPanUpdate: (DragUpdateDetails details) {
          setState(() {
            offset += details.delta;
          });
        },
```

details.deltaでドラッグの変化量を取得して、そのままoffsetに加算する感じ。
これで、自由にドラッグ&ドロップが実装できる！
RubyでFizzBuzz問題のコードを書く（初心者用）

## はじめに
この記事はRubyを使った初歩的なプログラミングのアウトプットの練習をするためのものです。
見辛い点、わかりづらい点などあったらご指摘していただけると幸いです。

## FizzBuzz問題について
FizzBuzz問題は、プログラミングの初歩的な問題です。内容は
"1~100の数字を表示させる"
ただしこの時、
"3の倍数の数字の代わりにFizz"
"5の倍数の数字の代わりにBuzz"
"３と５の倍数の数字の代わりにFizzBuzz"
と表示させる。
と言う問題です。

## 方針
まず1~100の数字を表示させることから考え、表示させる元の数字によって処理を変えていきましょう。
1~100の数字を表示するにはwhile文を使います。元の数字によって処理を変える部分はif文を使います。

## 1~100の数字の表示

```ruby
count = 1
while count <= 100
  puts count
  count += 1
end
```

countと言う変数を用意し、代入する値を1ずつ増やしながら1から100まで表示させます。次に、このcountが3や5の倍数のときの処理について考えましょう。

## 条件分岐の部分について

まず3の倍数のときにFizzと表示させる部分を考えます。すなわち、countの値が3の倍数になっている場合、Fizzと表示させれば良いわけです。
変数が3の倍数になると言うことは、変数が3で割り切れれば良いわけなので

```ruby
if count % 3 == 0
  puts "Fizz"
end
```
と記述することで、countが３の倍数のときはFizzと表示させることができます。
5の倍数についても同様に、

```ruby
if count % 5 == 0
  puts "Buzz"
end
```

と記述することで、題意を満たすことができます。

次に3と5の倍数について考えます。3と５の倍数とはすなわち15の倍数のことです。
そこで、これまでと同様に

```ruby
if count % 15 == 0
  puts "FizzBuzz"
end
```

と記述すると題意を満たせそうです。それ以外の場合についてはcountの値をそのまま表示させます。いちいちif文をendで区切ってまたif文を書くのは冗長なので、これまでの記述をelsif文,else文を使ってまとめると、

```ruby
if count % 3 == 0
  puts "Fizz"
elsif count % 5 == 0
  puts "Buzz"
elsif count % 15 == 0
  puts "FizzBuzz"
else
  puts count
end
```

となります。繰り返しのwhlie文も合わせて記述すると、

```ruby
count = 1

while count <= 100
  if count % 3 == 0
    puts "Fizz"
  elsif count % 5 == 0
    puts "Buzz"
  elsif count % 15 == 0
    puts "FizzBuzz"
  else
    puts count
  end
  count += 1
end
```

となります。一見これで完成に見えます。しかし、このプログラムを実行しても題意は満たされません。実際にプログラムを実行しても、FizzBuzzの表示が見当たらないはずです。

## プログラムの修正
このプログラムの問題点は、15の倍数がFizzと言う表示になり、FizzBuzzと言う表示にならない点にあります。これの原因は、15の倍数であると言うことは同時に3の倍数でもあることと、3の倍数の処理が15の倍数の処理より上に書かれてあることが原因です。

この問題を回避する方法はいくつかあります。自分の思いついた二通りの方法を以下に示します。

### 条件を変える
一つ目は、FizzとBuzzの表示をする条件がFizzBuzzの表示条件とかぶらないようにするために、それぞれの条件に追記すると言う方法です。

```ruby
if count % 3 == 0 && count % 15 != 0
  puts "Fizz"
elsif count % 5 == 0 && count % 15 != 0
  puts "Buzz"
elsif count % 15 == 0
  puts "FizzBuzz"
else 
  puts count
end
```

### 条件を読み込む順番を変える
二つ目は、FizzBuzzの表示がされるかどうかを一番に判定することで、他の条件とかぶらないようにする方法です。
15の倍数についての処理を3,5の倍数より先にしてしまえば、FizzBuzzと表示するべきところにはFizzBuzzと。そうでない部分についてはまたそれぞれの条件で表示がなされる。と言う具合です。

```ruby
if count % 15 == 0
  puts "FizzBuzz"
elsif count % 5 == 0
  puts "Buzz"
elsif count % 3 == 0
  puts "Fizz"
else
  puts count
end
```

コードの分かりやすさなどもを考えると一概にどちらが優れているか、自分では判断できなかったので二つとも紹介をさせていただきました。他にも方法はあると思います。

追記：比べてみると、よりシンプルなコードになっている、後者の方がより良いコードと認識していただけるようです。（コメントより）

## 感想・まとめ
自分も初心者ですし、できるだけ初心者でも分かりやすい表現を使ったつもりです。”条件を読み込む順番を変える”と言う表現だけで伝わるかどうかがいちばんの不安です。それだけでなぜ問題が解決されるのかの言語化がうまくできている気がしません。自分では理解できた気になっているのですが、説明として適切かどうかは自信がありません。精進していこうと思います。
AWSのEC2上で立てたUbuntu内のファイルを自分のPCと共有する


##AWS側の設定

####必要なポートの開放
EC2>セキュリティグループ>インバウンドルールの設定で、
>・UDP 137番ポート：NetBIOS ネーム・サービス（名前登録など）用
・UDP 138番ポート：NetBIOS データグラム・サービス（ブラウジングなど）用
・TCP 139番ポート：NetBIOS over TCP（ファイル / 印刷サービスなど ）用
・TCP 445番ポート：ダイレクト・ホスティング SMB（ファイル / 印刷サービスなど）用
をソースマイIPとして設定。


##Ubuntu側での設定
####下準備

```
rootユーザになる
sudo su -

```

####Sambaのインストール
```
sudo apt install samba
```
####Sambaパスワードの作成(ubuntuユーザに紐付けられる)
```
sudo useradd (名前）
sudo passwd (設定した名前)
 -------------------------------------------------------------------------
Ubuntuユーザーのパスワードを設定する
-------------------------------------------------------------------------
sudo smbpasswd -a （設定した名前)
-------------------------------------------------------------------------
Sambaでのパスワードを設定する
-------------------------------------------------------------------------
rootユーザになる
sudo su -
自分をルートユーザーにする
visudo

```

####Sambaの設定ファイルの編集
まず、Sambaをインストールしたときに自動生成された設定ファイル(/etc/samba/smb.conf)のバックアップをとっておく

```
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.original
```
いよいよ編集、

```
sudo vi /etc/samba/smb.conf
```

今Ubuntu内の/home/ubuntu/nukkitフォルダを共有したいので92%付近の[printer]の設定項目の上か下に以下を追加する(commentは何でも良い)

```
[global]
   interfaces = ローカルip(192.168.1.25など）
-------------------------------------------------------------------------
・・・

-------------------------------------------------------------------------
[nukkit]
   comment = nukkitdevelopment
   path = /home/ubuntu/nukkit
   browsable = yes
   readonly = no
```

Sambaを起動させる。

```
sudo service smbd nmbd start
```

自動起動設定をする

```
sudo systemctl enable smbd nmbd
```

##入り方
エクスプローラで

```
\\グローバルip\nukkit
```


##参考
https://recipe.kc-cloud.jp/archives/10873

https://qiita.com/u-bayashi/items/77e0ae1bdb4efa193b23

https://teleporter.hateblo.jp/entry/2019/03/26/121020

https://suin.io/473

http://motojapan.hateblo.jp/entry/2017/09/26/083753
pythonで「ポモドーロタイマー」を作ってみた

いわゆる[ポモドーロテクニック](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD%E3%83%BB%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF)用のタイマーはたくさんあるけれど、以下の不満点を満たしてくれるものがなかなかなかったので、自作してみた。

* タイマーを途中で一時停止することができない。（トイレ行っている間にタイマーが終わってた）
* タイマーを途中で停止することができない。（一区切りついたところで、休憩に入りたいのに、、）
* タイマーを動作させている途中で、PCがスリープに入ってしまう。（パソコン作業だけじゃないでしょ？）
* 音を消していたら、ウインドウの下に隠れていてタイマーが終了したことに気づかない。（ずっとタイマーをみてられないでしょ？）

https://github.com/GaneshaShiisa/Pomodoro_Timer.git

Windowsでしか使えないパッケージを使ってしまったので、それ以外では動作しないと思います。

* pywin32 （windowを前面に持ってくるのに使用）

```python
hwnd = win32gui.FindWindow(None, title) # windowのハンドルを取得
#  最前面表示の設定
win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0,
                      0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
# 最前面表示の解除
win32gui.SetWindowPos(self.hwnd, win32con.HWND_NOTOPMOST, 0,
                      0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
```

（参考）
https://office54.net/python/app/windows-foreground-active
https://blog.goo.ne.jp/masaki_goo_2006/e/6ddf4977ba01dd11d6be256c17cc2ccf

* winsound　（バックグラウンドで音を鳴らすのに使用）

```python
# バックグラウンドで音を鳴らす
winsound.PlaySound("Clock-Alarm05.wav", winsound.SND_FILENAME | winsound.SND_ASYNC | winsound.SND_LOOP)
# 音を停止する
winsound.PlaySound(None, winsound.SND_ASYNC)

```

（参考）
https://www.javaer101.com/en/article/22464192.html
【UE4】Control Rigを物理で吊るす実験／ぷちコン15進捗 - 2021/03/20

[1]:https://historia.co.jp/ue4petitcon15

[株式会社ヒストリアさん主催の第15回UE4ぷちコン][1]の作業進捗。
表題の通り、Control Rigと物理の合わせ技を試している(難航中)

# イマココ

まずは物理の実験。
やりたいことはボルダリング。崖とか岩壁とかを登るアレである。
…ということで、棒人間を吊るしてみるテスト。

片手でぶら下がる。
![20210320_1752_Hang01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/ec2c4cdf-e40b-a7ae-d4e0-8019b178ee88.gif)

両手でぶら下がる。
![20210320_1757_Hang02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/9e633ec5-a418-851f-f2c1-1e483d562128.gif)

両手両足で踏ん張る。
![20210320_1759_Hang03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/12d214a3-30c9-5c1c-f054-1eab5ca16e03.gif)

どのパターンもやっていることはシンプルで、

- `DeltaLength` = (現在の`hand`と`upperarm`の距離) － (スケルトンで測った腕を伸ばしたときの長さ)
- `upperarm`から`hand`に向かう方向に、`DeltaLength`×`ばね係数`の大きさの力を`AddForce`
- それに準じたトルクを肩に`AddTorque`

…という感じ。

> ばねだけだといつまでも振動してしまうので、ルートに置いたコリジョンコンポーネントの、`Linear Damping`と`Angular Damping`に 2.0 くらいの値を入れてある。

# これをマネキン女子に適用してみると…

- 両手両足をIK (=Basic IK) で固定。
- ボディ、というかマネキン女子Skeletal Meshを持ったアクタそのものが、両手両足の位置関係から`Add Force`や`Add Torque`してもらう。

という形で実装。
（つまり、アクタ自体が動いて、両手両足をIKで元の位置に貼り付けている）

![20210320_1839_HangGray02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/a38a3f5f-0e55-0b52-cd32-ae7d1cacc7f2.gif)
(途中カクつく場面があるのは、長い動画の一部を雑に切り捨てたからです)

- なんとなくボルダリングしているように見えなくもない…
    - なんだか捕まった宇宙人(←昭和ネタ?)みたいで気に食わないが。
- 左側に腰を寄せた位置で平衡状態になる。
    - 棒人間でやった実験と結果が異なる…

現在、ここで困り中。
「右と左のボーンの位置や角度が（計算誤差などにより）微妙に異なるから」と予想しているが、そもそも微妙な誤差で片側に偏ってしまうような仕組みだと、実用に耐えないと思っている。

別の方向性でも考えてみます…
（残り時間が非常に怪しいが）
GithubのSSH接続を設定する

GitHubにssh接続する必要性が生じたため、備忘録として残します。

# 公開鍵・秘密鍵を作る

以下のコマンドを順に打ちます

```
$ cd ~/.ssh
$ ssh-keygen -t rsa
```
生成したSSH 鍵の公開鍵の内容は次のコマンドを実行すると確認できます。

```
$ cat id_rsa.pub
```

以上で公開鍵と秘密鍵が作れました。

# GitHubにSSHを登録

自身のGithubアカウントからSettingにいき、生成したSSH Keyを追加する。

- Title : 公開鍵の名前を入力してください
- Key   : 公開鍵の中身をコピー&ペーストしてください

# 接続の確認
以下のコマンドを打って

```
$ ssh -T git@github.com
```
Hi (account名)! You've successfully authenticated, but GitHub does not provide shell access.
と返ってきたら成功です！

# 参考記事
https://qiita.com/shizuma/items/2b2f873a0034839e47ce

https://qiita.com/0ta2/items/25c27d447378b13a1ac3

https://www.sejuku.net/blog/74220

https://backlog.com/ja/git-tutorial/reference/ssh/

https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-SSH-%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%AE%E4%BD%9C%E6%88%90
VSCodeにCloudFormation Linterをインストールする手順

## CloudFormation Linterとは？
CFnテンプレートをチェック、プロパティ保管も用意されており、
入れない理由がないと言っても過言ではないVSCodeのプラグインです！


## 環境

```terminal
❯ code -v
1.54.3

❯ pip3 --version
pip 20.3.3 from /usr/local/lib/python3.9/site-packages/pip (python 3.9)
```
### 1. pipでcfn-lintインストール

```terminal
> pip3 install cfn-lint
```

### 2. cfn-lintのパスを確認
あとで使うのでメモ

```terminal
❯ which cfn-lint
/usr/local/bin/cfn-lint
```

### 3. VSCode拡張機能のCloudFormation Linterをインストール

![スクリーンショット 2021-03-20 18.10.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/679bac04-dc43-c4f2-dd2b-09907deffa4a.png)

### 4. CloudFormation LinterのPathを変更
VSCodeの設定を開きます。`⌘ + ,`
先ほどメモしたパスを`Cfn Lint: Path`に設定
![スクリーンショット 2021-03-20 18.22.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/0000acd6-e990-a298-997b-192ad549a0b0.png)

### 完了！！！
![スクリーンショット 2021-03-20 18.29.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/23844c51-e802-0b65-ca5b-221968a2bc06.png)


### 参考
[Linterを使ってCloudFormationの間違いに爆速で気づく](https://dev.classmethod.jp/articles/use-linter-to-notice-mistakes-of-cloudformation/)
[VSCodeにCloudFormationのLinterを追加する](https://infraya.work/posts/adding_cfn-lint_to_vscode/)
topcoder SRM 802 Div1 Medium BestEvenSplit

topcoder SRM 802 Div1 Medium BestEvenSplitをビットマスクの列挙で解いてみた。

### 問題

- Nは偶数で2から30まで
- N人を同人数の二つのグループにわける
- 友達のペアが与えられる
- 友達が同じグループになる個数を最大化するき、何通りのわけかたがありえるか求める

### 方針

30ビットは巨大だが、そのうちの15人固定なので、もしかしてビットで全部列挙できるのでは? と思ってやってみた。
前処理として、自分の友達をビットマスクで生成しておく。それにより、自分が所属するグループに友達が何人いるかビットでわかる。

### 実装

Nビットのうち、ちょうどKビット立っている集合を列挙する方法は[蟻本](https://www.amazon.co.jp/dp/4839941068)p.144と、けんちょん氏の[ビット演算 (bit 演算) の使い方を総特集！](https://qiita.com/drken/items/7c6ff2aa4d8fce1c9361#8-next_combination)に載っている。

```cpp
inline int next_combination(int sub) {
    int x = sub & -sub, y = sub + x;
    return (((sub & ~y) / x) >> 1) | y;
}
```

これでやってみたところ、30ビット(10億通り)のうち15個ビットが立つのは1.5億個くらいであった。しかしループだけで4秒以上かかってしまう。(この問題は特別に制限時間が3秒に拡大されている)
その後、立っているビットと立っていないビットの数は同じなので、反転したものを使えば、半分だけ列挙すればよいことに気づいた。上の `next_combination` は昇順に列挙できるので、ビットマスクの値が、反転したビットマスクの値未満の間だけ列挙すればよい。すなわちビットマスクの値が2^(N-1)までを列挙する。そうすると半分の77,558,760回の処理となり、3秒でも収まるようになった。

```cpp
class BestEvenSplit {
public:
    int count(int N, vector <int> X, vector <int> Y) {
        vector<int> friends(N);
        for (int i = 0; i < (int)X.size(); ++i) {
            friends[X[i]] |= 1 << Y[i];
            friends[Y[i]] |= 1 << X[i];
        }
        int ans = 0, max_count = 0;
        for (int comb = (1 << N / 2) - 1; comb < (1 << (N - 1)); comb = next_combination(comb)) {
            int cnt = 0;
            for (int i = 0; i < N; ++i) {
                // この人が所属するグループのビットマスク(combまたは~comb)を使う
                cnt += __builtin_popcount(friends[i] & ((comb & (1 << i)) ? comb : ~comb));
            }
            ans += cnt == max_count;
            if (cnt > max_count) {
                // マッチした数が最大値を超えていたら答えをリセットする
                max_count = cnt;
                ans = 1;
            }
        }
        return ans;
    }
}
```
Cloud Firestore orderBy 制限：範囲で取得する値と異なる項目でソートできない

## はじめに

先週からwebアプリ作ってまして。
[nuxt.js で4月から小学生の息子用に足し算練習webアプリを半日で作成できるか企画](https://qiita.com/kaku3/items/209c22a8638b55d99fc0)

ランキング機能あるとモチベーション上がるだろうと思って firebase でさらっとランキング作ったのですが。

ワイフ「上位陣に動きがなくてつまらない」
ワイ「じゃー、デイリーランキング作るわ」

と言うやり取りがありまして。

そんなこともあろうかとスコア登録日時のタイムスタンプを登録してたのでチョロく出来るかと思って２つ返事をしたら、firestore の制限でハマりましたというお話です。

## データ構造

```
scores [
  {
    mode: 'ゲームモード', // 複数のゲームモードのスコアを同じテーブルに格納している
    name: 'ニックネーム',
    score: 得点
    createdAt: 登録日時のタイムスタンプ
  },
  ...
]
```

## 日指定しないクエリ

``` query.js
const q = db.collection('scores')
            .where('mode', '==', this.displayGameMode) // 10秒モード, 30秒モード, 耐久モード
            .orderBy('score', this.orderBy) // 'desc' or 'asc'
            .limit(100)
```

複数の項目に対して条件を付ける場合 index を作成する必要があります。
ゲームモードによってスコア昇順 / スコア降順で値を取得したいので2つ index を作成します。

![2021-03-20_18h20_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/81b431d1-ccd7-3088-44df-705d8036e9d6.png)

- mode Ascending, score Ascending
- mode Ascending, score Descending

mode は [=] の比較でしか使わないので昇順でも降順でも問題ないです。

index を指定していない状態で query を投げるとブラウザのコンソールに警告が出て、リンクを踏むと上のスクリーンショットのページに遷移し index を作成できるのでここは悩まずイケます。

## 日指定するクエリ

問題はこちら。
ネットを細切れに検索すると日指定できそうに見え、実際指定できるのですが **他の項目でソートできない** という制限があります。

``` query.js
// 動く
const q = db.collection('scores')
            .where('mode', '==', this.displayGameMode)
            .where('createdAt', '>=', startTime)
            .where('createdAt', '<', endTime)
            .limit(100)

// 動く
const q = db.collection('scores')
            .where('mode', '==', this.displayGameMode)
            .orderBy('createdAt', 'desc')
            .startAt(startTime) // startAt(>=), startAfter(>)
            .endBefore(endTime) // endAt(<), endBefore(<)

// 動かない
const q = db.collection('scores')
            .where('mode', '==', this.displayGameMode)
            .where('createdAt', '>=', startTime)
            .where('createdAt', '<', endTime)
            .orderBy('score', this.orderBy)  // ★範囲で取得する値と異なる項目でソートできない
            .limit(100)

```

## 回避

日付に貼り付けて登録も取得も行う様にして、= で比較出来るようにしました。

``` query.js
// 動く
const q = db.collection('scores')
            .where('mode', '==', this.displayGameMode)
            .where('createdAt', '=', startTime)
            .orderBy('score', this.orderBy)
            .limit(100)
```

## おわりに

開発進んでからこういうのに気づくと致命傷だったりするのでお気をつけください。
intra-mart グリッドテーブルのrowIdをクライアントサイドスクリプトAPIで取得する

intra-mart IM-BIS / IM-FormaDesiner のスクリプトメモ
クライアントサイドスクリプトAPIのグリッドテーブル全行取得でrowIdを取得する。

外部連携や削除などで、実際に表示されているrowIdと内部のrowIdが異なる場合がある。
この内部のrowIdを一連の流れで取得出来たら便利だなと思いチャレンジ。

#対象
・intra-mart Accel Platform
・IM-BIS
・IM-FormaDesiner

#やりかた
IM-BIS for Accel Platform IM-BIS 仕様書に記載されているグリッドテーブルの全行取得で・・・

```Javascript:sample.js
var rowId = "";
var inputIdList = [];
inputIdList[0] = "%フィールド識別ID%";
var result = formaItems.product_80_gridtable.getItemData.%テーブル識別ID%(rowId, inputIdList);
for(var i=0; i<result.length; i++){
    imuiAlert(result[i].%フィールド識別ID%);
}
```

%フィールド識別ID%　に　imfrRowIdCelSub　を指定する。

```Javascript:sample.js
var rowId = "";
var inputIdList = [];
inputIdList[0] = "imfrRowIdCelSub";
inputIdList[1] = "gt1_text1";
inputIdList[2] = "gt1_text2";
var result = formaItems.product_80_gridtable.getItemData.%テーブル識別ID%(rowId, inputIdList);
for(var i=0; i<result.length; i++){
    // gt1_text1 != gt1_text2 セル色変更
    if( result[i].gt1_text1 != result[i].gt1_text2 ){
        $(#gt1).setCell(result[i].imfrRowIdCelSub, 'gt1_text1', ’’, {background:'#ffe5f2'});
        $(#gt1).setCell(result[i].imfrRowIdCelSub, 'gt1_text2', ’’, {background:'#ffe5f2'});
    }
}
```
データ同期

#目次
[Salesforce Direct データ](#Salesforce Direct データ)
[使いどき](#使いどき)
[](#)
[](#)
[](#)
[](#)

# Salesforce Direct データ

こいつの存在は知らなかった。Salesforce データをデータセットに読み込む必要はありません。代わりに、ダッシュボードウィジェットで Salesforce オブジェクトを直接クエリできます
![スクリーンショット 2021-03-20 18.46.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/8400fdb1-7866-c6ca-346c-c9365888bc40.png)

SOQLクエリが記載されている感じですね。

#使いどき

データが頻繁に変化して、スケジュール済みデータフローでは変化の頻度に追いつけないような場合にのみ、Salesforce Direct を使用してください。多くのレコードが入った Salesforce オブジェクトに対してクエリを実行すると、長い時間がかかることがあります。検索条件を使用して、クエリ対象となるデータを制限してください。たとえば、すべてのオープンケースではなく、特定の期間にオープンになったケースに対してのみクエリを実行します。


#参考文献
[Salesforce Direct を使ってみる](https://trailhead.salesforce.com/ja/content/learn/modules/einstein-analytics-and-discovery-certification-maintenance-winter-20/get-handson-with-salesforce-direct)

[データインテグレーションの使用開始](https://help.salesforce.com/articleView?id=sf.bi_integrate_get_started.htm&type=5)
[jquery]フォーム追加のappendチェーンを詳説

# appendで動的フォーム追加をしよう
イメージ図　→https://gyazo.com/3583ecfc924f4845861df37d124db646
学習対象者　jqueryでのdom取得がわかる方
##### 学べること
1. [appendの使い方](#appendの使い方)
2. [タグ内属性での変数の使い方](#タグ内属性での変数の使い方)
3. [セレクトボックスselect-optionのコピーの仕方](#セレクトボックスselect-optionのコピーの仕方)
4. [cloneでのコピーの問題点(所感)](#cloneでのコピーの問題点)


##### 序章
dom取得と新規の違い

```js:jquery_new.js
//　取得
$('タグ') $('.クラス名') $('#id名') $('[type=checkbox]')

// 新規
$('<タグ>')
```

## appendの使い方
##### 基本的な使い方
```js:jquery_append.js
親.append(子)
// 親の中に子要素が入る
$('form').append('<p>')
// 親form要素の中に新たにp要素が入る
```
原則:親要素の最後に子要素が挿入される
##### 課題

```html:hoge.html
<form>
  <p>
    <input type="checkbox" id="check1" value="1">
    <select>
      <option value="1">選択肢1</option>
      <option value="2">選択肢2</option>
    <select>
  </p>
</form>
<ボタン>
```
ボタンを押すとp要素以下のinput,select(option)をform(親)に追加する
このようなフォームを想定します。

- idを一意にしたいので、変数で変える
- checkboxのvalueもフォームに送るパラメーターなので変える
- セレクトボックスは何も変わらないのでそのままコピーする


## タグ内属性での変数の使い方

```js:jquery_append.js
var num = 2
var inputNew = $('<input>',{
 id: 'check' + num
 value: num
});

// 抽象化
var 数字の変数名 = 数字
var タグ変数名 = $('タグ',{
 属性: '変わらない属性名部分' + 数字の変数名
});
```


## セレクトボックスselect-optionのコピーの仕方
セレクトボックスの中身は選択肢も属性も変える必要がないので、**clone**でコピーしちゃいましょう

```js:jquery_append.js
var optionClone = $('select').children('option').clone(false)
// 既存のselectから子要素のオプションをコピー

var selectNew = $('<select>').append(optionClone)
// 新規セレクト要素にコピーしたoptionクローンを入れる
```

最後に、pタグに`inputNew`と`selectNew`を入れ、それをformに入れれば完成です。

```js:jquery_append.js
var pNew = $('<p>').append(inputNew, selectNew)
// 新規p要素にinputNewとselectNewを入れる

$('form').append(pNew)
// 既存form要素にpNewを入れる
```

## cloneでのコピーの問題点
`clone`という便利なものがあるのに、このappendチェーン使う理由って何？って思うかもしれません。
`clone`は取得したタグをクローンします。この際、取得する条件を厳密にしないと、**倍々**に増えていきます。
今回の例で言うと、pを条件緩めにクローンすると、1回クリックする毎に、2,4,8,16と増えていきます。
また、フォームの値もそのまま`clone`してしまうので、この初期化も念頭に記述しなければならないです。
一応、下記にclone倍々・継承問題の解決法の1つを残しておきます。

### バイバイ、倍々

```html:twice.html
<input type="text" class="origin hidden">
<form>
  <input type="text" class="origin">
</form>
```

```css:twice.css
.hidden{
   display: none;
}
```
```js:jquery_twice.js
const inputClone =  $('.hidden').clone(false).removeClass('hidden')
// display: none;がかかっているclass="hidden"を消す

$('form').append(inputClone)
```
`.css`でも変わりますが、**classを消してcssを変える**という発想も使えるので頭の片隅にでも。
## 余談-変数格納とカスタム属性
数字の変数の使い方はわかったけど、保持の方法がわからない問題は、以下の解決法でどうでしょうか
1. カスタム属性に格納する
2. １を取得し、変数宣言
3. ２の変数++;で１足す
4. .attrで変数を再格納

jquery初心者なので覚えた方がいいテクニックがあれば是非コメントお願いします！
AI素人のポンコツエンジニアがG検定対策に合格した件について（G検定対策）【後編】

#はじめに
　昨年（2020年）、日本ディープラーニング協会（以下JDLA）が運営するG検定に合格致しました。（下記の写真が合格した年度）

![general20203_regular.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681742/a55ccfa7-817f-f1e1-2f4b-90059b1280f9.jpeg)

当初は、AIに関しては「何となく」のイメージしか持っておらず、実際に「AIとは何なのか？」という漠然としたイメージしか持っていませんでした。そのため、AIに関しての現実的な認識を正確に把握していきたいと思い今回受験し、その結果無事に合格致しました。この記事では、私が実際にどのようにしてG検定を合格したのか、【前編】、【中編】、【後編】の3編に分けて解説していきたいと思います。構成は下記のようにしております。

<ul>
<li>【前編】：AI（機械学習・ディープラーニング）がそもそも何なのか理解したい初級者向け</li>
<li>【中編】：G検定の全容を把握したい中級者向け</li>
<li>【後編】：G検定を本格的に合格したい上級者向け</li>
</ul>

#そもそもG検定とは何なのか
　G検定とは、JDLAが主催する<b>ビジネスレベル（事業レベル）に相当する幅広いAIに関しての知識を証明する認定試験</b>となります。「AIって話題になっているけど具体的にはどのようなもの？」、「機械学習とかディープラーニングって何なのか？」、「私たちの生活・社会にとってAIは何の関係性・背景があるのか？」といったAIに関する歴史・技術・背景・法律・社会などを幅広いAI周りの知識の理解を目標としており、現在多数の主要IT企業も注目している認定試験でもあります。ちなみに、G検定の「G」はジェネラリスト（generalist）の頭文字から取ってきております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681742/f12e92d1-cbb9-9cae-1590-c2448e04e6c4.png)


#本題
　今回は、【後編】という訳でG検定合格の本格的な対策方法を話していきたいと思います。G検定合格する上で、必要な書籍は（前回の【中編】でお話しした）「白本」に加え、インプレスが出版しているこちらの「徹底攻略 ディープラーニングG検定 ジェネラリスト問題集」――通称「黒本」を活用するのが一般的です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681742/c8e885f2-3710-f970-6378-22e47ee94045.png)

　内容の方を見てみるとざっと、こんな感じです。

<ol>
<li>人工知能（AI）をめるぐ歴史と動向</li>
<li>機械学習の基礎</li>
<li>機械学習の具体的手法</li>
<li>基礎数学</li>
<li>ディープラーニングの概要</li>
<li>ディープラーニングの手法</li>
<li>ディープラーニングの研究分野と応用</li>
<li>総合問題</li>
</ol>

　内容を見てみると、「白本」の内容と多く被る部分があります。しかし一方で、各セクションごとに取り扱っている問題は各々が深い問題で構成されており、「白本」では網羅しきれなかった部分、言い換えるとG検定の標準レベルに相当する設問が多数収録されています。また、こちらは「白本」のようなテキスト（教科書）とは異なり、問題集であるため各セクションごとの傾向と対策を掴む上でも最適です。但し、一方で「黒本」はあくまでも「問題集」であるため初心者にはややとっつきづらい内容となっております。そのため、もし「黒本」で詰まってしまう場面がありましたら、一度「白本」に立ち返って復習するのが最適であると思います。

　また、「黒本」に加えてもう少し深い領域までG検定の対策を行いたい場合はこちらの「AI白書」もおすすめです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681742/91e4d326-9c20-1ad9-01cd-b6fc725adbe0.png)

　こちらの書籍はIPA（情報処理推進機構）が発行しているAIに関する最新の動向をまとめたもので、国内のAI事情は勿論、国際水準のAI事情や人間社会とAIに関する法律・倫理といった社会情勢などを深く語っているため、より深くAIを理解したい人には最適な書籍です。但し、こちらはG検定の範囲のコア的な部分が多いためG検定メインの教材としてではなく、サブ的な立ち位置で対応していくように注意していきましょう。


#終わりに
　今回の内容で、1通りG検定に対する本格的な攻略方法について話していきました。この記事が皆さんのG検定の対策になれば幸いだと思います。また、最後ですが今回のG検定の経験を元に「G検定対策辞典」というサイトを開設いたしました。

https://www.gsite.tech

こちらはG検定に頻出の用語を掲載している辞書サイトです。良かったらぜひご活用してみて下さい。それではまた。
AI、自律、哲学、のキーワードで検索してえられる文献に関して

#はじめに
AIの「自律」に関して考える場合、
ひとつには、哲学的？な立場があると思う。（ワタシとしては、あまり理解が届かない領域ではあるが。）
念のため、その内容を、少し見てみた。

#AI、自律、哲学、のキーワードで検索してえられる文献
いろいろ出てくるが、読みやすそうなpdfを２つほど選び、その内容を確認した。

##その１（URL、タイトル）
http://pssj.info/jsrnps/contents/contents_data/PSSJ-JSRNPS1(2018)_Karen_Yamazaki.pdf

人工知能の自律性について　（山﨑 かれん）

##その１　（内容抜粋、引用）

>BDI エ ー ジ ェ ン ト は 人 間 の よ う な 形 で 自 ら 欲求を 持 つ こ と が な い と い う 点において、 今 回 定 め た 人 格 的 自 律 性 を 持 つ こ と に は な っ て い ない。 こ の 問 題に対処する た め の 研 究 と し て 二 つ の 方 向 を 考 え て い る 。 一 つ は 人 工 物 に 自 ら欲 求 を 生 み 出 す 機 構 を 与 え る と い う 方 向 、 も う 一 つ は 自 ら 欲 求 を 持 た な い 人工 物 に 自 律 性 を 認 め る と い う 今 回 と は 異 な る 形 の 自 律 性 概 念 の 構 築 を 行 う という方向 で あ る 。

- - -

##その２（URL、タイトル）
https://www.issj.net/journal/jissj/Vol14_No2_Open/S1V14N2.pdf
実行可能な AI 技術のための条件
The Conditions for Feasible AI Technology
（西垣 通）

##その２　（内容抜粋、引用）

>演繹から統計への重点変更が，過去の挫折の克服と応用範囲の拡大をもたらしたことは間違いない．だがこれは同時に，現在の AI の弱点を浮きあがらせる．演繹推論であれば原則として誤りは生じないが，統計推論なら少なくとも確率的な誤りから逃れられない．

- - -
>マスコミにはよく「自律型（autonomous）AI」という言葉が登場する．AI 駆動のロボットは，自律的だから人気があると言う人もいる．だが，いったい自律的な機械など存在するだろうか．機械は人間の指令通り作動する他律的な存在であり，AI も人間の作ったプログラムにしたがって作動する以上，決して例外ではないはずだ．

- - -
>現在の AI が，ビッグデータ有効活用への道をひらく可能性をもつことは確かである．だが，AI の出力から誤りを無くすことはできないし，また AI は情報の意味内容を真にとらえてはいない．それらの点を考えると，AI システムの保守維持技術の確立，さらに情報をより生命的／社会的なものととらえる情報教育の拡大が重要なことがわかる．このことに気づかないと，早晩，AI ブームは尻すぼみになっていくだろう．


#まとめ
特にありません。
**主体**とか(これらの文献では直接の指摘はなかったかもしれないが）**身体性**とか、、、とりあえず、そのあたりのことが指摘されている。
必ず指摘される部分ではある。
後者の文献では、「統計推論」等の表現でAIの限界を示されているようにも読めるが、個人的には、AIに対して「統計推論」という表現に違和感があるのと、かりにそうだとしても、それによって、特別な限界がある気はしていない。（おそらく、わかりやすい表現をされているだけだと思うが。）

これらの内容が、わかりやすく、端的に表現された文献等あれば、知りたい。
ちょっとCSS触り始めた方へ

# はじめに

2021年に触ったCSSをざっと書いていきます。

自分自身が「なんとなくCSSわかる」ぐらいの感覚なので、調べながら書いてました。
なので比較的新しい技術が多いかと思いますので、これから書き始めた人や、最近触ってなかったって人には参考になるかと思います。

ざっと羅列していきます。

## gridLayout

レイアウト決める時の味方。神様。
例えばカードコンポーネントを3カラムで作りたいな〜みたいな時に良い。
CSSだけなくUIフレームワークにも大抵採用されているので概要は知っといて損なし。

ただし、ブラウザ間で非対応もあったりするので注意。

## calc

いろいろ計算してくれるプロパティ。フォントとかにつかうと画面サイズに合わせて変わるので便利。

https://coliss.com/articles/build-websites/operation/css/how-calc-works-by-ire.html

## minmax

gridでよく使うcalcみたいなやつ。便利です。よく使いました。
auto-fitとかもよく使う

https://coliss.com/articles/build-websites/operation/css/how-to-use-css-minmax.html

## 擬似要素 / クラス

慣れないうちは使いづらく感じるんですが、慣れるとこれがないとしんどい。

こんなやつですね。
`:before / :after`
`:not() / :first-child`

`:first-of-type`
とかはよく使いました。兄弟要素の最初にだけスタイルを当てる場合など。

https://qiita.com/manabuyasuda/items/86f9bf68f80ad7ce5104

## UIフレームワーク

いわゆるmaterialUIとか、vuetifyとか。

```js
    <v-container
      v-for="align in alignments"
      :key="align"
      class="grey lighten-5 mb-6"
    >
      <v-row
        :align="align"
        no-gutters
        style="height: 150px;"
      >
        <v-col
          v-for="n in 3"
          :key="n"
        >
          <v-card
            class="pa-2"
            outlined
            tile
          >
            One of three columns
          </v-card>
        </v-col>
      </v-row>
    </v-container>
```

これはvuetifyの公式から引用したものですが、どれか1種類理解するとあとは似たような感じです。

## CSS in JS

CSSの引き出しとして書けるようになっておくと仕事の幅広がると思います。
styledComponents / emotion　あたりは知っておいて損なし

## tailWind

CSSフレームワークの中では高いシェア。これも簡単に触っておいて理解しておくとよし

いいなーと思えば続けて採用すれば良いと思います。

## margin padding

適当につけない。いまさらですが。

https://eclair.company/media/difference-between-margin-and-padding/

## max-width / min-height　とか

たんにwidthよりも優れたシーンがあるので。いまさらですが。

## flex-inline

これないとしんどい場面多かった。
`display: flex` で囲ったあとなの要素をinline的に扱いたい場合に良いと思います。

## position: sticky

便利な固定ヘッダー。これあったらJS要らなかった。
bugがあるみたいな書き込み見ましたが、仕様の問題であってbugではないので、読んで理解すれば問題なし。

```css
.some-component{
    position: sticky;
    top: 0;
} 
```

これだけで実現できるのはすごい。

https://coliss.com/articles/build-websites/operation/css/css-position-sticky-how-it-really-works.html

## 色の定数化

あたりまえだけど。大事ですよね。サイズとかも個人的にはしたい。

## さいごに

CSSは基礎さえ理解しておけば取り回しが効くのでちょっと触って知っておく。みたいなスタンスは有効やなって思います。

お役に立てれば幸いですm_ _m
数値計算でNumbaをつかうときの罠

よく考えたら当たり前だけど, 関数の返り値に引数に含めていない変数が入っていると, 生Pythonでは呼び出したときの名前空間が参照されるがNumbaを使うと**コンパイル時に名前空間にあった値**が使われる.このため, **｢関数の頭にデコレータをつけるだけで計算が速い!!｣**とか言って書いて, たとえば関数の引数に関数が入っていると予想外の挙動をすることに.

```python

C=10
def f(X,Y):
    I=0.4
    return (-C*Y+X-pow(X,3)/3+I)*C

def g(X,Y):
    return (X-0.8*C*Y+0.7)/C
```

こんなふうに系を関数として定義して, 引数には含めない外のパラメータ(ここではC)をふくめて扱うのって結構あるあるだと思うけど, これは思わぬミスの原因. 
当たり前だけど普通に計算は通ってエラーは出ないので厄介.

数値積分で系のパラメータを外から変えると積分用のアルゴリズムを一般化できて便利なんだけど, JITを使うときはパラメータも系の引数にして専用に積分アルゴリズムを書かないとだめ.

#だめな例

```python
@jit
def jit_testa():
    return a
@jit
def jit_testtesta(x):
    return x()

def testb():
    return b

def testtestb(x):
    return x()
```
bは途中で変えて呼び出しても反映されるけど, aを途中で変えても定義し直さないかぎり最初の値が返ってくる(実験したらわかる). 定義し直すとめちゃくちゃ重くなるのでJITを使う意味がない.解決としては引数にほしい値を入れる.こうすると呼び出し時の名前空間を参照してくれる.
Firebaseでサブコレクションまで再帰的に削除する上での作業備忘録

作業備忘録なので、自分がわかるようにしか書きません。申し訳ありませんが、参考にならないと思います。

FirebaseのFirestoreにおいて、ドキュメントを削除しても、ドキュメント配下のサブコレクションは削除されない問題がある。
公式では、FirebaseのFunctionsサービスを用いて、サーバサイドに削除関数を配置してクライアント側から呼び出すように設定することを推奨している。

Functionsのサンプルコードは以下になる。
https://github.com/firebase/snippets-node/blob/master/firestore/solution-deletes/functions/index.js

Functionsを使えるようになるまでにもろもろの設定があるが（設定手順は紹介しない）、デフォルトのままだと上記のコードをデプロイしてもエラーが起きる。

参考までにデプロイ時のコードを以下に載せる。

```sh
sudo firebase deploy --only functions
```

エラー内容は以下のようなものになる。

```
function terminated. Recommended action: inspect logs for termination reason. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging Function cannot be initialized
```

原因はパッケージ不足だった。
プロジェクトフォルダ/functions/上で以下のコマンドを実行することで、firebase-toolsが使用できるようになるのでデプロイが成功するようになる。
（プロジェクトフォルダ/node_modulesとプロジェクトフォルダ/functions/node_modulesが共有でないことに気づくまでに時間がかかったため、備忘録として追加しておく）

```sh
sudo npm install --save firebase-tools
```

デプロイが成功したため、今度はフロント側から呼び出すコードが必要になる。
以下の公式が推奨する手順の「クライアントからの呼び出し」という項目を進めていく。
https://firebase.google.com/docs/firestore/solutions/delete-collections?hl=ja

完了し次第、備忘録に追加する予定...
【Springfox】@JsonValueがSwaggerの定義に反映されなかった問題への対処【Jackson】

# TL;DR
- `@JsonValue`を`public`な`getter`に付与すれば反映される
  - フィールドに付与しても反映されない
  - `private`な`getter`では反映されない

# 問題
以下のような`enum class`を定義し、レスポンスのフィールドに入れました。

```kotlin
import com.fasterxml.jackson.annotation.JsonValue

enum class SampleEnum(label: String) {
    Foo("label of Foo"), Bar("label of Bar");

    @JsonValue
    private val jsonValue = mapOf("name" to name, "label" to label)
}
```

実際のレスポンスは以下のようになります。

```json
{
  "sampleEnum":{"name":"Foo","label":"label of Foo"}
}
```

一方、`Springfox`に表示される`Swagger`定義は以下のようになっていました。

```json
{
  "sampleEnum": "Foo"
}
```

# 対処法
動かして確認した限り、`Springfox`は`public`な関数のみ反映するようでした。
なるべくdiffが小さくなるよう変更した例は以下の通りです。

```kotlin
import com.fasterxml.jackson.annotation.JsonValue

enum class SampleEnum(label: String) {
    Foo("label of Foo"), Bar("label of Bar");

    // public化 + getterにアノテーションを振る形に変更
    @get:JsonValue
    val jsonValue = mapOf("name" to name, "label" to label)
}
```

`Swagger`定義も以下のように変化しました。

```json
{
  "sampleEnum": "{name=class, label=label of class}"
}
```
Rustの長い長い型名

# まえがき
この記事の目的は、非常に長い名前の型を生成して、~~コンパイラで遊ぶこと~~型推論やトレイト境界のありがたさを理解することです。
記念すべき初投稿。
# 導入
RustやC++は、型名が長くなりやすい性質を持っています。
C++でSTLを駆使してコードを書いていたときは、型名の長さ(と<<>>の多さ)が嫌になってしまったこともあります。
Rustでは、型推論(とそれを助けるトレイト境界)のおかげで、長い型名を見る機会は少ないと思います。しかし、型名は水面下で存在していて、顕在化すると下記のような惨劇を引き起こします。

https://qiita.com/wada314/items/201ab5d66ac7daeb9c3d

:::note info
impl Traitが導入されて上記の問題は解決されたものの、std::any::Anyを使うには未だ真の名前が必要なはず。
:::

# 本題
本題のコードはこちら。get_longnameはVecとスライスを受け取ってイテレータを返す関数です。それほど不自然ではないと思いますが……

```rust
fn get_longname(input :Vec<isize>, n :&[usize])->impl Iterator<Item=isize>{
	let a = input.into_iter();
	let mut n = n.into_iter();

	let a = match n.next() {
		Some(&x) => Enum::A(a.take(x)),
			  _  => Enum::B(a),
	};
	let a = match n.next() {
		Some(&x) => Enum::A(a.take(x)),
			  _  => Enum::B(a),
	};
	let a = match n.next() {
		Some(&x) => Enum::A(a.take(x)),
			  _  => Enum::B(a),
	};
	let a = match n.next() {
		Some(&x) => Enum::A(a.take(x)),
			  _  => Enum::B(a),
	};
	a

}
```
戻り値の正確な型名はこちら

Enum&lt;std::iter::Take&lt;Enum&lt;std::iter::Take&lt;Enum&lt;std::iter::Take&lt;Enum&lt;std::iter::Take&lt;std::vec::IntoIter&lt;isize&gt;&gt;, std::vec::IntoIter&lt;isize&gt;&gt;&gt;, Enum&lt;std::iter::Take&lt;std::vec::IntoIter&lt;isize&gt;&gt;, std::vec::IntoIter&lt;isize&gt;&gt;&gt;&gt;, Enum&lt;std::iter::Take&lt;Enum&lt;std::iter::Take&lt;std::vec::IntoIter&lt;isize&gt;&gt;, std::vec::IntoIter&lt;isize&gt;&gt;&gt;, Enum&lt;std::iter::Take&lt;std::vec::IntoIter&lt;isize&gt;&gt;, std::vec::IntoIter&lt;isize&gt;&gt;&gt;&gt;&gt;, Enum&lt;std::iter::Take&lt;Enum&lt;std::iter::Take&lt;Enum&lt;std::iter::Take&lt;std::vec::IntoIter&lt;isize&gt;&gt;, std::vec::IntoIter&lt;isize&gt;&gt;&gt;, Enum&lt;std::iter::Take&lt;std::vec::IntoIter&lt;isize&gt;&gt;, std::vec::IntoIter&lt;isize&gt;&gt;&gt;&gt;, Enum&lt;std::iter::Take&lt;Enum&lt;std::iter::Take&lt;std::vec::IntoIter&lt;isize&gt;&gt;, std::vec::IntoIter&lt;isize&gt;&gt;&gt;, Enum&lt;std::iter::Take&lt;std::vec::IntoIter&lt;isize&gt;&gt;, std::vec::IntoIter&lt;isize&gt;&gt;&gt;&gt;&gt;

ここまで長くなるなんて想像できましたか?
しかも、let a = match…から…};までの4行を追加するたびに型名の長さは指数関数的に増えます。どんな長さの型名も簡単に用意できますね。
Rustでは、このように型名が非常に長くなることがあります。時には扱っている型の真の名前を見てみるのも良いでしょう。変数の後ろに:u8と書けば確認できます(impl Trait以外)。

:::note info
Enumの定義は[こちらのリンク](https://qiita.com/taiki-e/items/39688f6c86b919988222)のコードを使用いたしました。
:::

```rust
enum Enum<A, B> {
    A(A),
    B(B),
}

impl<A, B> Iterator for Enum<A, B>
where
    A: Iterator,
    B: Iterator<Item = A::Item>,
{
    type Item = A::Item;
    fn next(&mut self) -> Option<Self::Item> {
        match self {
            Enum::A(x) => x.next(),
            Enum::B(x) => x.next(),
        }
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        match self {
            Enum::A(x) => x.size_hint(),
            Enum::B(x) => x.size_hint(),
        }
	}
}
```

# まとめ

+ Rustの型名は長いよ。
+ でも普段は意識しないよ。
+ たまに確認しよう。

## おまけ
matchを含む文を6個に増やした場合
![Screenshot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159333/aa808399-1f18-d966-8ab6-1566b2b01c3f.png)
SQLを学んでみた③(検索結果を並べ変えたり除外したり)

実務でSQLやDBについて理解していないといけないと思い勉強を始めました。
その内容をまとめます。

## SELECTへの装飾

SELECT文につけることで並べかえなどができます。
主なものが以下です。

- DISTINCT
- ORDER BY
- EXCEPT
- INTERSECT


## DISTINCT

重複しているものを除外してくれます。

例えば家計簿をつけていて以下のようなDBがあったとします。

| 日付         | 内容          | 入金       | 出金        |
|:-----------:|:------------:|----------:|------------:|
| 0201         | コンビニ       | 0         | 500        |
| 0205         | スーパー      | 0         | 2000        |
| 0210         | カフェ        | 0         | 1000        |
| 0215         | 給料         | 250000    | 0           |


上記の例でいうと、入金が0のものが3回あるのでこれを除外してみようと思います。

```
SELECT DISTINCT 入金
FROM 家計簿
```

そうすると以下のようになります。

| 入金       |
|----------:|
|  0        |
| 250000    |


SELECTの後にすぐに続けて記載します。


## ORDER BY

これが一番使う気がします。
カラムを指定してASC(昇順)もしくはDESC(降順)に並べ替えてくれます。

例えば先ほどの家計簿で、日付順に並べ替えてみます。

| 日付         | 内容          | 入金       | 出金        |
|:-----------:|:------------:|----------:|------------:|
| 0201         | コンビニ       | 0         | 500        |
| 0205         | スーパー      | 0         | 2000        |
| 0210         | カフェ        | 0         | 1000        |
| 0215         | 給料         | 250000    | 0           |

```
SELECT * FROM 家計簿
ORDER BY 日付 DESC
```

そうすると以下のように降順になります。

| 日付         | 内容        | 入金       | 出金        |
|:-----------:|:----------:|----------:|------------:|
| 0215         | 給料       | 250000    | 0           |
| 0210         | カフェ      | 0         | 1000        |
| 0205         | スーパー    | 0         | 2000        |
| 0201         | コンビニ     | 0         | 500         |


ORDER BYはカンマで区切って複数指定することもできます。
その場合は左から順番に並び替えをして、その上で同じものがあればそれをさらに並び替えるという処理になります。


## EXCEPT

あるSELECT文の検索結果と別のSELECT文を比べて重複するものを差し引いてくれます。

```
SELECT 内容 FROM 家計簿1月
EXCEPT
SELECT 内容 FROM 家計簿2月
```

上記のように使うと重複を差し引き、1月と2月でかぶっていないものだけ出力してくれます。


## INTERSECT

あるSELECT文の検索結果と別のSELECT文を比べて重複したものだけを出力してくれます。

```
SELECT 内容 FROM 家計簿1月
INTERSECT
SELECT 内容 FROM 家計簿2月
```

上記のように使うとそれぞれで重複しているものだけ出力してくれます。

以上です。
wordpressでHTTPS化するためにリバースプロキシをNginxで構築する

- Nginx側の設定 "https://myblog.ms" でHTTPS化すると仮定しています。  



```
server {
	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.html index.htm index.nginx-debian.html;
        server_name myblog.ms; # managed by Certbot
        proxy_set_header    Host    $host;
        proxy_set_header    X-Real-IP    $remote_addr;
        proxy_set_header    X-Forwarded-Proto https;
        proxy_set_header    X-Forwarded-Port 443;
        proxy_set_header    X-Forwarded-Host       $host;
        proxy_set_header    X-Forwarded-Server    $host;
        proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

	location / {
                proxy_pass http://172.18.100.2;
                #ご自身のwordpressのサーバーのIPアドレスを記入してください
	}

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/myblog.ms/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/myblog.ms/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = myblog.ms) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


	listen 80 ;
	listen [::]:80 ;
    server_name myblog.ms;
    return 404; # managed by Certbot


}
```

- wordpress側の設定 wp-config.php

```
<?php
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
define('FORCE_SSL_ADMIN',true);
$_SERVER['HTTPS'] = 'on';
define('WP_HOME','https://myblog.ms');
define('WP_SITEURL','https://myblog.ms');
```
Swift5で動画をアプリ内で再生させる方法

#パターン①

① 使いたい動画をプロジェクトに追加する。
＊チェック’を忘れずに
![スクリーンショット 2021-03-20 16.53.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1215670/25a09557-bf00-4600-1108-db1e1247334e.png)


② ```import AVKit```をコントローラに追加

③

```swift 
override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
}
```
の中に

```
let player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "動画ファイル名", ofType: "動画ファイル拡張子名")!))
let layer = AVPlayerLayer(player: player)
layer.frame = view.bounds
view.layer.addSublayer(layer)
player.play()
```
を追加。

ビルドしてみると

![スクリーンショット 2021-03-20 16.55.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1215670/d3f75397-f67e-676c-5d06-a9aa3862c536.png)

真ん中で再生される。

 画面全体にしたい時 ```  layer.videoGravity = .resizeAspectFill ``` 追加
 音を消したい時　``` player.volume = 0 ``` 追加

#パターン②

①②はパターン①同様

③

```swift
 override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated) ｝
```
の中に

```swift
let player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "動画ファイル名", ofType: "動画ファイル拡張子名")!))
let vc = AVPlayerViewController()
vc.player = player
present(vc, animated: true)
```
を追加。

ビルドしてみると

![スクリーンショット 2021-03-20 17.12.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1215670/9322f485-98df-cb45-3fc4-74bdcec65218.png)

こんな感じで再生される。


参考にしたもの
https://www.youtube.com/watch?v=yqCJcdFl55I&t=258s
Slack APIとjqでSlackにいるメンバーをサクッと取得

# きっかけ

とあるSlackで特定のクラスタが何人いるのか数えたいと思いました。
そこでもはや何番煎じかもわからないですが、jqでSlackのユーザ一覧を取得し整形するということを試してみました。

# Slack APIにてtoken取得

## とりあえずアクセス
とりあえず下記のURLへアクセスし、Apps一覧の画面へいきましょう。

https://api.slack.com/apps

## アプリ作成

上記のURLをクリックすると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/0ae045d0-c129-8a86-be25-8c077cdf6903.png)
もしくは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/a43bf0cf-7bb0-597f-84b3-4a28ef9d0674.png)

みたいな画面が見えるはずなので、`Create New App`をクリックします。
そうすると下記の画面が出てくるはずなので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/8f7365f7-98df-26c1-83ee-116ed6588f47.png)
`App Name`にアプリの名前を入力し、`Development Slack Workspace`で対象のWorkspaceを選択します。

## Permissonを与えて、Workspaceへの認証を実施

Appが出来上がると以下のBasic Infomation 画面へ遷移します（今回はサンプルとしてtestというAppを作成しています）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/64f8ae93-d840-8022-d23d-79a33a52f051.png)
左メニューにある`Features`の`OAuth & Permissions`へ移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/5430e132-a0ae-ae1a-e9a1-60419eb1fd86.png)
下へスクロールすると、Scopeという項目があります。
`User Token Scopes`の下にある`Add an OAuth Scope`を押して`users:read`の権限を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/8a5902e3-39ec-754c-839c-ca2fa16a1ccd.png)
終わったら、左メニューにある`Install App` をクリックし移動し、`Install to Workspace`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/4a645bc5-3296-d168-74f3-12b2b4d53819.png)
下記みたいな認証画面が出てくるので許可します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/9f17ceb8-2c20-91f9-82cc-69f0180ba59e.png)
これでUser Tokenが取得完了し一旦は終わりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/ae87aa50-d3a1-0558-bd3d-1275fb238821.png)
このUser Tokenはコピーしておきましょう。

# 取得して加工

## とりあえずjsonを取得
（やっとここからスクショが不要な部分になってほっとしてます）
以下はLinux, Mac, WSL/WSL2での利用を前提として記載となっております。
PowerShellやCommand Promptでの利用を前提としていない旨ご了承ください。

user.listのリファレンスを読む限り、HTTPのGetを投げてあげたらResponseで帰ってくるそうなので、とりあえずcurlで叩きます。

https://api.slack.com/methods/users.list

curlでの取得は以下の通りです。
※`<YourToken>`は取得したUserToken

```shell
curl -X POST -H 'Authorization: Bearer <YourToken>' -H 'Content-type: application/json' https://slack.com/api/users.list > users_temp.json
```

## jqのinstall

みんながみんなjqを入れてるわけではないはずなので、jsonの加工に必要なjqをインストール手順を示します。

```shell
sudo apt update
sudo apt install -y jq
```

## レスポンスのjsonが読みづらいので整形

1行で返ってきてとても読みづらいので先ほど導入したjqで整形します。

```shell
cat users_temp.json | jq -r > users.json
```

## csvへ出力
最後に、jsonからユーザ名を列にしたcsvを出力します。
jqの`--raw-output`オプションを使ってもダブルクオートが消えないので、最後にsedコマンドで消し去っています。とりあえずワンライナーにて実行しています。

```shell
cat users.json |jq --raw-output '.members[] | [.name, .real_name] | @csv' | sed s/\"//g > users.csv
```

あとはcsvで確認すればOKです。
ちなみに、SlackにはWhat I Doに所属を記載でき、users.infoのAPIで個々の内容を取得することも可能です。
たださすがに制限に引っかかるであろうこと、何より人によって記載が異なったりすることがよくあるので結局最後はcsvを見て数え上げました・・・。

https://api.slack.com/methods/users.info

# 参考にした記事

https://qiita.com/sukebeeeeei/items/7b059f0d8f90183ecb67
Javaで複数バージョン切り替え

# Linux
```bash 
$ update-java-alternatives --list
java-1.11.0-openjdk-amd64      1111       /usr/lib/jvm/java-1.11.0-openjdk-amd64
java-1.8.0-openjdk-amd64       1081       /usr/lib/jvm/java-1.8.0-openjdk-amd64

$ sudo update-java-alternatives --set /usr/lib/jvm/java-1.8.0-openjdk-amd64
update-alternatives: error: no alternatives for mozilla-javaplugin.so
update-java-alternatives: plugin alternative does not exist: /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/IcedTeaPlugin.so
```

# macOS
```bash
$ /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
    11.0.9, x86_64:     "OpenJDK 11.0.9"        /Library/Java/JavaVirtualMachines/jdk-11.0.9+11/Contents/Home
    1.8.0_282, x86_64:  "Zulu 8.52.0.23"        /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home
    1.8.0_221, x86_64:  "Java SE 8"     /Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk-11.0.9+11/Contents/Home
```

```bash
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0_282)
# or
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
```

# jenv
jenvを使っている場合はmacOSの↑の手順が動かない。rbenvっぽく使う。

# IntelliJ IDEA
* File > Project Structure > Project Settings > Project > Project SDK

を変更する。
変数について(PHP)

# 変数とは
変数とは、例えるなら、**「箱」**のようなものです。
変数(箱)があることによって文字や数値などのデータを入れることができます。
変数にデータを入れることを**「代入」**と言います。
変数からデータを取り出すことを**「参照」**と言います。
変数には名前をつけることができます。それを変数名と言います。
変数を作ることを**「変数を宣言する」**と言います。

# コードの書き方

実際にコードを書いてみます。

```php
<?php
  $num;
  $num = 50;
  echo $num;
```

１行ずつ解説します。
まず、**$num;**という変数を宣言します。
次に**$num;**に**50**という数値を代入します。
そして変数の中身を参照するために、**echo**を使います。
この状態でターミナルで実行すると**50**が返ってきます。

また変数の宣言と同時に代入することも可能です。

```php
 <?php
  $num = 50;
  echo $num; 
```

先程の文より、記述量が少なくて済みます。

#変数名についての注意点

変数名は数字から始めることができません。
変数名はアンダースコア以外の記号を使用できません。
※PHPでは予約語(forやreturn等)も変数名として使用できますが、区別が分かりにくいので使用しない方が良いです。
確率と統計 入門 

# 確率変数と確率分布

## 基礎用語

* 標本点(Sample point)
６面体のサイコロを投げた時、取りうる目は、{1, 2, 3, 4, 5, 6}の６つです。
このようなとりうる結果のことを標本点と呼びます。

* 標本空間(sample space)
標本点の全体の集合を標本空間と呼びます。

* 事象(event)
起こりえる事柄の事象(event)と呼びます。事象は標本空間の部分集合によって定義されます。例えば、サイコロの目が奇数であるという事象は

```math
A = \{ 1,3,5 \}
```

* 空事象(empty event)
標本点を１つも含まない事象を空集合(empty event)と呼びます$${\emptyset}$$

* 根集合(elementary event)
ただ１つの標本点からなる事象

* 全集合(whole event)
標本空間全体を全事象と呼びます

* 和集合(union of events)
事象AとBの少なくとも１つが起こるという事象をAとBの和事象(union of events)
$$ A \cup B$$

* 積事象(intersection of events)
$$ A \cap B$$

* 排反事象(disjoint events)
事象A、事象Bが同時には起きないときAとBは排反事象と呼びます。

$$ A \cap B = \emptyset $$

＊補事象(complemetary event)
事象Aがおこらないという事象をAの補事象と呼び、記号は$$ A^c$$で表します。

* ド・モルガンの法則
$$
(A \cup B)^c = A^c \cap B^c
$$
$$
(A \cap B)^c = A^c \cup B^c
$$

## 確率

確率とは事象の起こりやすさを表す尺度、事象Aの起こる確率を$Pr(A)$とあらわす

コルモゴロフの3つの公理
1. 任意の事象$A_i$に対して、 $0  \leq Pr(A_i) \leq 1$
2. 全事象$\Omega$にたいして$Pr(\Omega)=1$
3. お互いに排反な事象$A_i$に対して、$Pr( \cup_i A_i)=\sum_iPr(A_i)$

### 加法定理

事象が２つの場合
$$Pr(A \cup B) = Pr(A) + Pr(B) - Pr(A \cap B)$$

事象が３つの場合
$$Pr(A \cup B \cup C) = Pr(A) + Pr(B) + Pr(C) - Pr(A \cap B) - Pr(A \cap C) - Pr(B \cap C) + Pr(A \cap B \cap C)$$

### 確率変数と確率分布
ある変数がとる各値に対して確率が与えられているとき、その変数を確率変数(random variable)とよびます。　

* 確率分布
確率変数が実際にとる値を実現値とよび、確率分布(Probability distribution)とは、確率変数の実現値と確率との関係を関数としてあらわしたものです。

* 加算集合(countable set)
集合の各元にを数え上げることができる集合を加算集合と呼びます。

* 離散型確率変数
加算集合の中の値をとる確率変数を、離散型確率変数(discrete random variable)と呼びます。
$$ Pr(x) = f(x) $$
【Ruby on Rails】N+1問題とはなにか

## N+1問題とはなにか？
N+１問題とはなにか。なんとなく、データベースで１対多とかあるからそういうことかなというのは感じ取れる。
ユーザーが１人に対して、複数の記事が紐づいている。このようなことに関するなにかかな？・・・・そうらしい。

## SQLの発行
N+1問題とは、1つのテーブルと多(N)のテーブルへのSQLの発行がたくさんされてしまいパフォーマンスの低下につながるようというものらしい。

### パフォーマンスの低下とは？
簡単にいうと、SQLがたくさん発行されるため、画面の表示までにとても時間がかかってしまうようになるよみたいなこと。
ほかにも、色々な影響が考えられるが、DBに高い負荷をかけてしまうため、システムにとって良くないことがたくさんつながる。
DB(データベース）はシステムを開発する上では、欠かせない存在。

## サービスの成長と共にパフォーマンスが低下する
はじめはよくても、ユーザーがたくさん増えてサービスが成長していきデータの量が増えるとパフォーマンスに明らかな影響が出る。
そのため、実装をする段階でこのようなDBへの負荷も考えながらコードを書いていくことがプロフェッショナルだと思う。