OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Pi のイメージファイルのダウンロード、SDカードへの書き込み

Raspberry PiのイメージファイルをmacOSで書き込みするまでのメモです。
以下を参考にしました。

Copying an operating system image to an SD card using Mac OS
https://www.raspberrypi.org/documentation/installation/installing-images/mac.md

MacでSDカードにRaspberryPiイメージを書き込む
https://pocketlog.net/20180906/raspberrypi_image_dd_for_mac/

MAC OS上でのオペレーティングシステムイメージのインストール
http://igarashi-systems.com/sample/translation/raspberry-pi/installation/install-mac.html

#環境
macOS High Sierra 10.13.6
Raspberry Pi Zero WH

#イメージファイルのダウンロード
公式サイトはダウンロードスピードが遅いので、日本国内のミラーサイトからダウンロードします。
今回はLite版をダウンロードしました。
例：http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian_lite/images/

イメージファイルは以下に格納しておきます。

```
$ ls -lh /Users/user/Downloads/2020-02-13-raspbian-buster-lite.img 
-rw-r--r--@ 1 nikofu501  staff   1.7G  2 13 16:10 /Users/nikofu501/Downloads/2020-02-13-raspbian-buster-lite.img
```

#イメージファイルのインストール
SDカードにイメージを書き込みます。ここから、rootでの作業になります。

##SDカードのディスクのフォーマット
まず、以下のコマンドを実行し、SDカードのディスクを確認します。今回は/dev/disk2がSDカードのディスクです。

```
# diskutil list

/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *8.0 GB     disk2
   1:             Windows_FAT_32 NO NAME                 8.0 GB     disk2s1
```
パーティションを削除します。

```
# diskutil partitionDisk /dev/disk2 1 MBR "Free Space" "%noformat%" 100%

Started partitioning on disk2
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Finished partitioning on disk2
/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                                                   *7.9 GB     disk2
```

ディスクをアンマウントします。

```
# diskutil unmountDisk /dev/disk2*

Unmount of all volumes on disk2 was successful
```

ディスクをフォーマッットします。アンマウントした状態で以下のコマンドを実行します。

```
# diskutil eraseVolume FAT32 BLANK /dev/disk2
```

フォーマットコマンドを実行時に、以下のようなエラーが出た場合、パーティションを削除できていません。
パーティションを削除してください。
```Started erase on disk2
Unmounting disk
Error: -69888: Couldn't unmount disk
```
フォーマットが終わると以下のように出力されます。
```Started erase on disk2
Unmounting disk
Erasing
512 bytes per physical sector
/dev/rdisk2: 15436312 sectors in 1929539 FAT32 clusters (4096 bytes/cluster)
bps=512 spc=8 res=32 nft=2 mid=0xf0 spt=32 hds=255 hid=0 drv=0x00 bsec=15466496 bspf=15075 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk2 BLANK
```

以下のコマンドでフォーマットできていることを確認します。（NAMEにBRANKが表示されていること）

```
# diskutil list

/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                            BLANK                  *7.9 GB     disk2
```

##イメージファイルの書き込み
イメージファイルをSDカードに書き込みます。
書き込み前にアンマウントします。

```
# diskutil unmountDisk /dev/disk2*
# cd /Users/user/Downloads
# dd bs=1m if=2020-02-13-raspbian-buster-lite.img of=/dev/rdisk2
```

書き込み中は「controlキー＋T」で状況を確認できます。
出力例：
```load: 2.49  cmd: dd 4337 uninterruptible 0.00u 0.13s
6+0 records in
5+0 records out
5242880 bytes transferred in 4.021259 secs (1303791 bytes/sec)
```

書き込みが終わるとコマンドラインが表示されます。
検証用のLINEアカウントを作ろう

# はじめに
検証用のiphoneが用意できたのでLINEも検証用のモノを作ってみたくなったのでやってみた

# やってみた
## この端末の電話番号を入力
　早速電話番号を聞かれた。。。
　たしか、、、以前に初期化前iphoneでLINE両方使いしようとしたら
　片一方のLINEアプリが凍結してしまい、必ずどっちかの端末でした
　LINEが使えないことをふと思い出した…。

　が、やってみた。
　すると、自前携帯のLINEから
　「【重要】
　　ほかの端末のLINEから、あなたの電話番号による認証が要求されました。…」
　と警告メッセージが飛んできた。
　知らずにこれされたら怖い・・・。

　SMSに番号が贈られたのでこれを確認コードとして入力すると
　「おかえりなさい、〇〇〇〇」
　と現れて、本人のアカウントかどうか聞かれた。
　今回やりたかったのは検証用の別アカウントだったので既存アカウント扱いされたら困る…ので
　電話番号は別のものを使わないとダメなようだ。

　でもfacebookログインでもよさそうなのでこっちで試してみる。
　
　facebookのログインアカウントが尋ねられたので入力。
　次は「アカウントを新規登録」画面。入力はうまくいった様子。
　名前を決められるようだ。

　facebookで使っている名前そのままだと区別がつかないのでちょっとだけ変えて登録。

　年齢確認の画面出た。
　　・auをご契約の方
　　・LINEモバイルをご契約の方
　の2択が出た。多分、今使っている端末が元auで購入したiphoneだからだろう。
　「あとで」が選べるのでそれを選ぶことにした。

　サービス向上のための情報利用に関するお願い　の画面。
　⇒　同意する　タップ

登録完了～。

記念に自前のアカウントと友達になって投稿テストをやってみたら無事にメッセージがやり取りできていることを確認することができた

## まとめ
・LINEアカウントを作るには基本的に電話番号が必要
・facebookアカウントがあれば電話番号を使わずにLINEアカウントを作ることができる
・年齢確認は自身の入力を信用するのではなく、
　・キャリア契約の確認
　・LINEモバイルの契約の確認
　などを使っていて少し確認を強化している

最近のSNSはアカウントの管理を結構強固にしているから作る側も考えているんだなぁ…と勉強になった。
VS CodeアップデートしたらRemote-SSHが動かなくなった

本日VSCodeをアップデート(1.43.0)したらRemote-SSHが動かなくなってしまったので一応メモ。

- VS Code(1.43.0)
- Ubunu 18.04

ログを確認すると、以下のようなものが出力されていた（適当にマスキング）。

```
[18:23:31.201] > 663e0e29aad8: running
> 
[18:23:31.215] > Acquiring lock on /home/xx/.vscode-server/bin/xxxx
> xxxx/vscode-remote-lock.xxxx.xxxx       
> 
[18:23:31.223] > \ln /home/xxx/.vscode-server/bin/xxxxxx/vscod
> e-remote-lock.xxx.xxxxx.target /home/xxx/.v
> scode-server/bin/xxxxxx/vscode-remote-lock.kur
> e.xxxxx
> Installation already in progress...
> 663e0e29aad8##24##
> ln: failed to create hard link '/home/xxx/.vscode-server/bin/xxx
> xxxx/vscode-remote-lock.xxxx.xxxx
> 5f9903a': File exists
>
```

`failed to create hard link` でファイルを作成できない（すでに存在する）ということで、同名のファイルはたしかにあったので、削除したら動いた。深追いはしていない。
CSS3:align-itemsのendとflex-endとbaselineの使い分け

こんばんは。
web制作会社就職を目指している、twitter上の「#駆け出しエンジニアとつながりたい」でおなじみの駆け出しエンジニアのひとりです。アウトプットが大事ということで、コード書く以外のアウトプット方法としてqiitaを始めてみます。間違ったこと書いていたらガッツリ怒ってください。

今回は、フレックスボックス内での子要素の下揃えで少し迷ったので、私と同じような初心者のために書いてみようと思います。
フレックスボックス内で使用するalign-itemsのflex-endとendとbaselineって似たようなイメージないですか？
調べたら全然違いました。


htmlとsassは以下の通りです。


        <!--html-->
        <div class="inner1">
            <div class="item1">1</div>
            <div class="item2">2</div>
            <div class="item3">3</div>
        </div>
   
        <div class="inner2">
            <div class="item1">1</div>
            <div class="item2">2</div>
            <div class="item3">3</div>
        </div>

        //以下sass
        .inner1{
            height: 500px;
            border: solid 1px;
            padding: 10px;
            display: flex;
            text-align: center;
            align-items:baseline;

            .item1{
                background-color:$orange ;
                      
            }

            .item2{
                
                background-color: $green;
            }

            .item3{
                background-color: $yellow;

            }
        }


<h2>flex-end</h2> 
子要素がdisplay:flex;を指定している親要素の最下部に張り付いた。
これは予想通りの動きでした。
<img width="1113" alt="flex-end.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603163/256cc340-d82d-7978-1648-c9cd3053a8b1.png">


<h2>end</h2>
動きませんでした。まさかでした。
endのくせに最上部に張り付いたままでした。
ちなみに親要素のdisplay:flex;を削除しても、同様でした。
<img width="1108" alt="end.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603163/2b089088-a027-c7ab-ad9a-3db28911149e.png">


<h2>baseline</h2>
横並びになっている子要素の中の文字のベースライン(要素の最下部ではなく文字の最下部)がそろいました。これを使うとフレックスボックスの最下部(ベースライン)に引っ付くイメージを持っていましたが、文字の最下部を揃えるときに使うようです。

<img width="1109" alt="baseline.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603163/a9c33b55-9395-6664-9b10-a23ba3be99a1.png">


<h3>結論</h3>
フレックスボックス内での下揃えはflex-endを使おう。
Raspberry PiのGPIO端子のスイッチ入力

#　はじめに
Raspberry PiのGPIO端子を使用して、スイッチ入力を行う際の、プルダウン抵抗について。
Raspberry PiのGPIO端子は、3.3V、最大16mAで作動します。
また、Raspberry Piは複数のGPIOを使用できますが、**同時に流せる電流は50mAまで**です。

# 物理プルダウン抵抗
Raspberry PiのGPIO端子は最大16mAまでしか流せないので、抵抗を使って電流を落とす必要があります。オームの法則から、抵抗値を求めます。

```math
R = \frac{V}{I}\\
R = \frac{3.3}{0.016}\\
R = 206.25
```

最低206.25Ω以上の抵抗をプルダウン抵抗として使用します。余裕を持たせて、GPIO端子にかかる電流が3mA程度になるように1kΩ程度の抵抗を使います。
GPIO端子26本すべて使用する場合、78mAと許容量を超えるので、抵抗値を上げる必要があります。

## 回路例

GPIO入力端子として26番のGPIO7端子を使用しています。回路のハイインピーダンス(解放)状態を防ぐため、グランド端子に接続します。

![物理抵抗.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/faa9b9af-119e-3540-4259-52ff2c33362b.png)

## プログラム例
スイッチが押されると、コンソールにSW Onと出力。

```python
import RPi.GPIO as GPIO

GPIO_Nbr = 7

GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_Nbr, GPIO.IN)

while True:
	if GPIO.input(GPIO_Nbr):
		print("SW On")

GPIO.cleanup()
```

# 内部プルダウン抵抗
GPIOを操作するPythonライブラリの`RPI.GPIO`を使用してプルダウン抵抗を有効化させます。

```
RPI.GPIO.setup(端子番号, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
```

## 回路例

![Untitled Sketch_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/da747d1f-5cc6-a2e3-5408-f10379dc0f61.png)

## プログラム例

```python
import RPi.GPIO as GPIO

GPIO_Nbr = 7

GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_Nbr, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

while True:
	if GPIO.input(GPIO_Nbr):
		print("SW On")

GPIO.cleanup()
```
【Golang】Go 1.14での独自パッケージimportでエラーになるとき

数年Goを離れてたら、バージョン1.14になってたのでキャッチアップしなければ（Go 1.10の人）。
`go mod`による管理が楽しい。

## TL;DR

- 各ディレクトリにgo.modを設置
  - `go mod init`をする
- local importするため各go.modファイルに`replace`を追加
  - 参照階層がネストするときに注意
     - 例）main.go → ./api.go → ./domain/models/Sample.go
     - mainのgo.modにはreplace文が2行必要になります
         - main.goから見たapiの相対パス
         - main.goから見たmodelsの相対パス 

## 出てきて困ったエラー

```
C:\Users\username\go\src\github.com\username\repo>go build ./...
go: finding module for package github.com/username/repo/domain/models
api\api.go:13:2: no matching versions for query "latest"
```

とか

```
go: github.com/username/repo/api@v0.0.0-00010101000000-000000000000 requires
        github.com/username/repo/domain/models@v0.0.0-00010101000000-000000000000: invalid version: unknown revision 000000000000
```

## 前提

- Windows 10
  - [VSCodeでGo言語の開発環境を構築する - Qiita](https://qiita.com/melty_go/items/c977ba594efcffc8b567)を参考に環境構築
- module-aware mode
  - デフォルトでonになるみたいですが、念のため`go env -w GO111MODULE=on`でonに

`go env`の結果です。

``` env.log
set GO111MODULE=on
set GOPATH=C:\Users\username\go
```

## ディレクトリ構成

%GOPATH%配下である必要はないですが、一応標準的な配置。本記事に関係ないファイルを除外して記載してあります。

``` tree.log
%GOPATH%\src\github.com\username\repo
│  main.go
│
├─api
│      api.go
│
└─domain
   └─models
          Sample.go
```

## 解決手順

### ./main.go→./api/api.go

main.goのなかで、自作apiパッケージを利用する場合、下記の手順が必要。

- main.goと同階層にあるgo.modにreplace追加
  - `replace github.com/username/repo/api => ./api`
- apiの階層にgo.mod作成
  - `cd ./api`
  - `go mod init`
- main.goにimport
  - `import api "github.com/username/repo/api"`

### ./api/api.go→./domain/models/Sample.go

api.goのなかで、自作modelsパッケージを利用する場合、下記の手順が必要。

- api.goと同階層にあるgo.modにreplace追加
  - `replace github.com/username/repo/domain/models => ../domain/models`
  - **そのgo.modから見ての相対パスなので注意！**
- domain/modelsの階層にgo.mod作成
  - `cd ./domain/models`
  - `go mod init`
- api.goにimport
  - `import models "github.com/username/repo/domain/models"`
- **main.goと同階層にあるgo.modにもreplace追加**
  - `replace github.com/username/repo/domain/models => ./domain/models`

### mainのgo.mod

``` go.mod
module github.com/username/repo

go 1.14

replace (
	github.com/username/repo/api => ./api
	github.com/username/repo/domain/models => ./domain/models
)

require (
	...
)
```

### apiのgo.mod

``` go.mod
module github.com/username/repo/api

go 1.14

replace github.com/username/repo/domain/models => ../domain/models

require (
	...
)
```

### 解決後のgo.mod分布イメージ

``` tree.log
%GOPATH%\src\github.com\username\repo
│  go.mod
│  go.sum
│  main.go
│
├─api
│      api.go
│      go.mod
│      go.sum
│
└─domain
   └─models
          go.mod
          Sample.go
```

## 今回は問題なかったけど

- 将来domain直下に.goファイルが出てくるようになったら、今回と同様の手順で解決できるはず
- domain/repositoriesとか作ってrepositoriesパッケージ使う場合も同じお話

## 同ジャンルのQiitaの先人たち

- [【Golang】独自パッケージのインポート - Qiita](https://qiita.com/lp-peg/items/9f7da97d9f7292f16fbc)
- [Golang - Go Modulesで開発環境の用意する - Qiita](https://qiita.com/so-heee/items/56f5317b42cec3d94383)
【CSS】読み込み時にスライドされhover時に灰色のフィルタがかかり拡大するアニメーション

### udemy動画内容のメモ・備忘録

```html:index.html
<div class="cover-slide hover-darken inview">
  <img class="img-zoom" src="images/image-1.jpg" alt="">
</div>
```

```scss:style.scss
@import 'mixin';

img {
  max-width: 100%;
  vertical-align: bottom;
}

.cover-slide {
  position: relative;
  overflow: hidden;

  &::after {
    content: '';
    position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #eaebe6;

    @include animation(
      $name: kf-cover-slide
    );
  }
  &.inview {
    &::after {
      @include animation(
        $name: kf-cover-slide,
        $duration: 1.6s,
        $timing-function: ease-in-out,
        // $fill-mode: normal
      );
    }
  }
}

@keyframes kf-cover-slide {
  0% {
    left: 0;
    right: 100%;
  }
  50% {
    left: 0;
    right: 0;
  }
  100% {
    left: 100%;
    right: 0;
  }
}

.img-zoom {
  opacity: 0;

  .inview & {
    opacity: 1;
    transition: transform 0.3s ease;
    @include animation(
      $name: kf-img-show,
      $duration: 1.6s,
      $timing-function: ease-in-out,
      $fill-mode: normal
    );

    &:hover {
      transform: scale(1.1);
    }
  }
}

@keyframes kf-img-show {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 0;
  }
  50.1% {
    opacity: 1;
    transform: scale(1.5);
  }
  100% {
    opacity: 1;
  }
}

.hover-darken {
  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
    transition: backgorund-color 0.3s ease;
    pointer-events: none;

    @include animation(
      $name: kf-img-show,
      $duration: 1.6s,
      $timing-function: ease-in-out,
      $fill-mode: normal
    );
  }
  &:hover::before {
    background-color: rgba(0, 0, 0, 0.4);
  }
}
```

```scss:_mixin.scss
@mixin animation(
  $name,
  $duration: 1s,
  $timing-function: ease,
  $delay: 0s,
  $iteration-count: 1,
  $direction: normal,
  $fill-mode: forwards
) {
  animation: {
    name: $name;
    duration: $duration;
    timing-function: $timing-function;
    delay: $delay;
    iteration-count: $iteration-count;
    direction: $direction;
    fill-mode: $fill-mode;
  }
}
```
検証用のapple IDを作ろう

# はじめに
iphoneXs購入に伴いお役御免となったiphone7を自宅検証用として
セカンドライフを送らせてあげたいと思い、
せっかく検証用にするんであればapple IDも検証用に作ってみようということで
記録を残すことにする

# 前提条件
・auで購入したiphone
・iphoneは初期状態に戻した
・そこから電源をいれた状態
・とりあえずホーム画面は出た


# apple IDを登録しよう
https://support.apple.com/ja-jp/HT204316#ios
iphneからでも作れるそうなので早速やってみた。

## touch IDを登録する
apple IDを作ろうと思い
初期化状態のiphoneのセットアップを始めたら最初に始まったのが
touch IDの登録作業。
これは指でホームボタンをタッチ⇒離すを繰り返したら完了。

## apple ID作成
設定＞iPhoneにサインイン＞Apple IDをお持ちでないかわすれば場合　タップ
で　Apple IDを作成　タップ

生年月日を入力
名前を入力
　⇒渡邉 弘志テスト用　って氏名にした
メールアドレスを入力
　⇒普段使いのApple IDと同じgmailアドレスにしてみた
　　⇒ってやろうとしたらNGになった。どうやらApple IDで同じメアドはNGなようだ
　⇒gmailのエイリアス機能を使って別メアドを作成（watyanabe164+dev@gmail.com)して
　　登録を試みたところ、次へ進めた
パスワードを入力
　⇒入れた
SMSもしくは通話できる電話番号の入力
　⇒ここでどうしても電話番号が必要になるっぽい。
　　とりあえず自前のiphoneで使ってる電話番号あてにSMS送ってみたところ
　　確認メールの送信はできた。がメアドがNGと言われた。
（リトライ）メールアドレスを入力
　⇒yahooのメアド持っていたのでそれにしてみた。
（リトライ）SMSもしくは通話できる電話番号の入力
　⇒自前の電話番号を使ってみたところ、無事通った。
iphoneパスワードの入力
　⇒ホーム画面出すときのパスワードを聞かれたので入力した。

…以上まで実行したらアカウントが作成できた！

最後に、登録したメアドあてにメールを送って確認コードを入力してって画面が出たので
実行したらyahooメールのところに確認コードの記載されたメールが来た。
これを入力したところ、いつもの設定画面に戻ることができた。めでたしめでたし。

## App Storeの登録
　apple IDを入力すれば利用できる。。。
　かと思ったら、初回のアプリインストール時に
　App Store用にカード情報、住所、電話番号の入力を求められた。
　　カード情報は「なし」でもイケた。
　　住所と電話番号は必須だったけど、自前のものと同一でもイケた。

# まとめ
やってみたら意外といけた。でもいくつか気を付けるポイントはあった
　・キャリアなしでも、wifi接続はできる
　・キャリアなしでも、apple IDの登録はできる
　・apple IDには、appleに登録したことのないメアドが必要
　・登録メアドは、エイリアスで複製したものではダメなので別個で用意する必要がある
　・wifi環境とメアドさえ用意できればSIMがなくてもiphoneは使える。

## 次やりたいことメモ
・検証用のLINEアカウント作る
・検証用のfacebookアカウント作る
・検証用のtwitterアカウント作る

## ちょっと脱線：gmailのエイリアスアドレス作成
https://dekiru.net/article/16418/
意外と簡単。
　1. Gmailの［設定］ボタン→［設定］をクリック
　2. ［設定］画面で、［アカウントとインポート］→名前＞［他のメールアドレスを追加］の順にクリック
　3. ［自分のメールアドレスを追加］画面で、エイリアスのメールアドレスを登録
でOK。

で作ったメアドが
　〇〇〇〇+dev@gmail.com　※〇〇〇〇は自前gmailの名前

ちなみに
　〇〇〇〇_dev@gmail.com
で登録しようとしたら↓↓のようなメッセージが現れた。
確認メールでの確認が必要なようでちょっと手間が必要なようだ。
~~~~~~~~~~~~
　〇〇〇〇_dev@gmail.com としてメールを送信するには、このメール アドレスの所有者であることを確認する必要があります。確認を行うには、[確認メールの送信] をクリックします。
〇〇〇〇_dev@gmail.com に、アドレスを確認する手順を記載したメールが送信されます。
~~~~~~~~~~~~
多対多

##多対多
『Instagram』を例とします。『Instagram』はひとつの写真に複数のタグ付けができます。こうしたタグ付け機能を実現するには3つのテーブルが必要です。タグを保存するテーブル、写真を保存するテーブル、そして「どの写真にどのタグが登録されているか」を保存するテーブルです。
このうち写真やタグを保存するテーブルの名前はそのままtagsテーブル、photosテーブルとします。「どの写真にどのタグが登録されているか」のテーブルは、慣習的にphotos_tagsテーブル、と名付けます。関係する2つのテーブルをアンダーバーでくっつけています。
例ですがそれぞれのテーブルに保存されているレコードの関係性は以下のようにしたとします。

| tagsテーブル      |photosテーブル| photos_tagsテーブル  |
|:-----------------|------------------:|:------------------:|
|               id |              id    |               id  |
|              name|          name      |           tag_id  |
|             .....|         location   |        photos_id  |
|             .....|         ......     |         .....     |
ひとつの写真には「東京／カフェ／おしゃれ」のように複数のタグが属しています。
また同じ「東京」のタグに対してもたくさんの写真が投稿されるので、ひとつのタグに複数の写真が属しているとも言えます。
このような関係が多対多です。多対多の関係を表現するには、photos_tagsテーブルのような中間テーブルが必要です。
##中間テーブル
中間テーブルには、「どの写真がどのタグと関連づいているか」という情報が記載されていることになります。
ひとつのレコードには「photos_id × tags_id」の組み合わせが記録され、全ての写真とタグの組み合わせの数分、レコードが蓄積されていきます。10個の写真にそれぞれ3つずつタグが付いている場合、全ての関係性を表すのに中間テーブルのレコードは30個生成されるということになります。
##has_many throughオプション
モデルに多対多を定義するときに利用します。
throughは、「〜を経由する」という意味です。
【例】

```
# app/models/photo.rb
class Photo < ActiveRecord::Base
  has_many :photos_tags
  has_many :tags, through: :photos_tags
end

# app/models/tag.rb
class Tag < ActiveRecord::Base
  has_many :photos_tags
  has_many :photos, through: :photos_tags
end

# app/models/photos_tag.rb
class PhotosTag < ActiveRecord::Base
  belongs_to :photo
  belongs_to :tag
end
```
上記のようなアソシエーションを定義することで、自動的に以下のようなメソッドが使えるようになります。
【例】

```
# 通常レコードの作成
tag1 = Tag.create(name: "東京")
tag2 = Tag.create(name: "おしゃれ")
photo1 = Photo.create(image: "cool_cafe.jpg", location: "渋谷")

# 多対多関係を定義したレコードの作成
tag1.photos.create(image: "cute_shop.jpg", location: "原宿")

# リレーションの追加
tag1.photos << photo1
photo1.tags << tag2

# リレーションを利用したレコードの取得
photo1.tags
# => #<Tag id:1, name:"東京">,#<Tag id:2, name:"おしゃれ">
```
「通常レコードの作成」のところでは単体のインスタンスを生成しています。【例】は、nameプロパティを持ったtagインスタンスとimage及びlocationプロパティを持ったphotoインスタンスです。これらの間には多対多の関係が定義されています。

「多対多関係を定義したレコードの作成」のところでは多対多の関係性を利用し、tag1に関係したphotoインスタンスを新たに生成しています。photosと、複数形になります。

「リレーションの追加」のところでは後からインスタンス同士を関連付けることも可能です。<<メソッド「配列オブジェクト << 追加する要素」を使用すると実現することができます。
tag1と関係しているphotosの配列に、新たにPhotoクラスのインスタンスを追加することでリレーションを生成しています。
photo1と関係しているtagsの配列に対し、新たにtag2とのアソシエーションを追加しています。

「リレーションを利用したレコードの取得」のところではリレーションしている要素を全て出力することもできます。【例】だとphoto1は「リレーションの追加」でそれぞれtag1・tag2に関連付けられているので、返り値としてtag1ならびにtag2のインスタンスが出力されています。
##has_manyメソッドの他のオプション指定

|オプション名	|                                     用途|
|:-----------------|---------------------------------------------:|
|class_name	|関連するモデルのクラス名を指定でき、関連名(photos_tags等、has_manyの直後に書くもの)と参照先のクラス名(PhotosTagのようなモデル名)を異なるものにできる|
|foreign_key	|参照先を参照する外部キーの名前を指定できる（デフォルトは、参照先のモデル名_id）|
|dependent	|親モデルのデータを消したら関連するモデルのデータも連動して消したいときに使用します。destroyとdelete_allでひとつひとつ消していくか、一気に消すかを指定できる|
|source	|関連テーブルから先のモデルにアクセスするための(関連モデルから見た)関連名を指定できる|
GitHub Actions 作成のアンチパターン

## はじめに

GitHub Actionsの作り方の紹介記事や実際に作成されたアクションが増えてきましたが、あまりいいとは思えない方法をちらほら見かけるので...

## ビルドしたファイルや依存モジュールをデフォルトブランチで管理

変更したソース以外の変更が可読性の低い状態で多く混ざることがあり、PRでコードレビューをしても悪意のあるコードを見逃す可能性が高いため、リリース用のブランチ以外にビルドされたファイルや依存モジュールをコミットしてはいけません。

さもなければジョブごとに６０分間書き込み権限のある`GITHUB_TOKEN`を外部に送信するようなコードが紛れ込むかもしれません。

そもそもコントリビュートのしやすさや node のバージョンの違いによるバイナリの違い等を考慮すれば node_modules などはソース管理されるべきではないのは当たり前のことなので、これらが考慮されていない時点で大いに問題があります。

## アクションの指定が master

READMEなどに書かれている使用例で `master` が指定されている場合、おそらく Compatibility を考慮していないのでしょう

```yaml
on: push
name: test
jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: owner/repo@master
        with:
          abc: xyz
```

この書き方の場合、破壊的変更が入っても最新のものが実行されるため、いつの間にかワークフローが動かなくなるということが発生します。

前述のセキュリティの問題もこの指定の場合すぐに影響されます。

[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) などで適切にバージョンを決定し、タグを貼ってREADMEを書き直すべきです。

> steps:
>     - uses: actions/javascript-action@master  # do not do this

[actions/toolkitのversioningに関するドキュメント](https://github.com/actions/toolkit/blob/6459481e988198bf53e186abf23350b085b1250f/docs/action-versioning.md#compatibility)

もちろん `dist/index.js` などのファイルも master から削除しなければなりません。

### テストしにくい？

チェックアウトするのをリリース用のブランチやタグにすればいいだけです。

```yaml
on: push
name: test
jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          ref: releases/v1
      - uses: ./
        with:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

## Semantic Versioning を使用していない

> GitHubに安定した体験を提供するアクションを作成するときは、セマンティクスバージョニングを使用することをお勧めします

https://help.github.com/ja/actions/building-actions/about-actions#versioning-your-action

とあるように、将来的に継続した提供を考慮しているアクションでは `Semantic Versioning` の使用が推奨されています。

逆に `Semantic Versioning` が使用されていないアクションは問題があっても更新されない可能性や急に破壊的変更が入る可能性があると受け取られるため、メジャー、マイナー、パッチバージョンを考慮してタグを付与すべきです。

ただ、実際はリリースのたびにタグを貼り直す作業は非常に面倒であるため、パッチバージョン（e.g. `v1.2.3`）でタグが貼られていれば使用しても問題ないアクションだと考えています。

## Docker タイプの GitHub Actions

Dockerfileを利用したアクションの場合、アクション実行前にビルドの動作が入るため遅いです。

どうしても必要なソフトウェアがインストールされていない、ソフトウェアのバージョンを固定したいなど理由があってのことであれば問題ないかもしれませんが、例えば「Linterを走らせるだけ」のような処理で使用するのは無駄に時間を浪費するだけです。

また `if: failure()` などでスキップされる場合もビルドは行われます。
したがって、失敗した場合にSlackに通知するみたいなことを行う場合に使用すると、失敗していないときの実行時間も増えてしまいます。

特にプライベートリポジトリの場合、無料枠を無駄に消費することになるのでJavaScriptで書き直したほうがいいです。
vue cliのプロジェクトにaxiosを読み込む方法

備忘録です。

### したいこと
・vue cliのプロジェクトでHTTP Requestを行いたい

### 方法
vue.jsにはHTTP Requestをする機能が備わっていないので、HTTP RequestができるようJavascriptのライブラリを読み込む必要があります。簡単にHTTP Requestを行えることから[axios](https://github.com/axios/axios)が多くの人に好まれているようです。

まずはaxiosをプロジェクトにインストールします。

#### ステップ1 
プロジェクト内のターミナルからaxiosをインストール👇
(npmはすでにインストール済みと仮定します) 
補足：Visual Studio Codeを使用している場合、プロジェクトファイルを開いた状態で`表示 👉 ターミナル`に行くと、ターミナルが開けます。私の場合は、`vuejs`というファイルがプロジェクトファイルなので、そのなかにaxiosをインストールします。

```
USER-no-MacBook-Air-2:vuejs user$　npm install axios
```

数秒待つとインストールされます。

#### ステップ2
使用するためにはインストールするだけでなく、インポートする必要があります。プロジェクト内で使えるようにするにはmain.js内にインポートします。

##### main.jsファイル内

```
import Axios from 'axios'
Vue.use(Axios)
```

#### ステップ3
さらにcomponentsのなか、あるいはrootとなるapp.vueなどで使う場合は、そこにもインポートする必要があります。

##### app.vue内など、HTTP Requestを行いたいvueファイルの中

```
<script>
import axios from 'axios';//ここで読み込む

export default {
  data() {
    return {
        //
    } 
  },
 methods: {
        //
    }
    }
         
 }
</script>
```

これで使える状態になります。

### 補足: `.get`して情報を画面に表示させる
ここでは[JSON Placeholder](https://jsonplaceholder.typicode.com/)というダミーテキストを返してくれるAPIサーバーを例に説明します。ここではJSON Placeholderの[/posts](https://jsonplaceholder.typicode.com/posts)を使います。

たとえば`#showBlogs`というdivのなかにある、`<h2></h2>` には **JSON Placeholder/postsのtitle** を、`<article></article>`には **JSON Placeholder/postsのbody** を表示したい場合。

.getメソッドで情報を取得しなければいけません。そのためには`created(){}`を`export default`内に使います。

```
<template>
  <div id="showBlogs">
      <h1>Blog Articles</h1>
      <div v-for="(blog, idx) in blogs" v-bind:key="idx" class="single-blog">
          <h2>{{ blog.title }}</h2>//ここで情報を表示する
          <article>{{ blog.body }}</article>//ここで情報を表示する
      </div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
        blogs:[]
    }
  },
  methods: {
  //
  },
  created(){
      axios.get('https://jsonplaceholder.typicode.com/posts').then(response => {
          this.blogs = response.data
      })//ここで情報をくれ〜〜〜というリクエストをする
}
}
</script>
```

このようにして私は無事画面に情報を表示することができました。とはいえ初心者なので何かあればご指摘いただけると幸いです🙇‍♀️
自己紹介

#はじめに
はじめまして、えすえす(@SS_lngmn)と申します。
学生時代の専攻はバリバリの生物系でした（今話題のPCRとかやってた実験屋さんです）。
プログラミングそのものを始めたのは社会人になってからで、現在は一端のSASプログラマーとして働いています。
SASに限らずいろんな技術を身に着けたいと思い、備忘録としてQiitaをはじめてみました。

#試したことのある言語
- SAS
- VBA
- Python
- Google Apps Script

SAS以外はちょろっとかじった程度なので、もっぱら忘却の危機と戦っています。

#これからやりたいこと
最近chromebookを買ったので、クラウド環境でできることを色々試してみたいと思っています。もしSAS使えたら最高だなぁ。
wikipediaにpythonからアクセスする方法

http://www.minekawada.com/wikipedia-python.html

目次
インストール方法について
pythonでwikipedia検索結果の候補一覧を出す方法
pythonでwikipediaのページを出力する方法
wikipediaのページをさらに詳しく見ていく



続きのページ
http://minekawada.com/wikipedia-python-wordcloud.html


#追記

紆余曲折あって以下のようなサイトが出来上がりました。

日本語版
http://www.minekawada.com/kawaminee/wordcloud/%E3%82%A2%E3%83%B3%E3%83%91%E3%83%B3%E3%83%9E%E3%83%B3


英語版
http://www.minekawada.com/kawaminee/wordcloud-eng/Donald_Trump
Apache Zeppelin のインストール

やってみたのでメモ
# 前提
CentOS 7
Java インストール済み

# 手順
1. tar ファイルをダウンロードする

    ```sh
    # curl -LkvOf https://ftp.jaist.ac.jp/pub/apache/zeppelin/zeppelin-0.8.2/zeppelin-0.8.2-bin-all.tgz
    ```

2. ダウンロードした tar ファイルを展開する

    ```sh
    # tar zxf zeppelin-0.8.2-bin-all.tgz
    ```

3. 展開してできたディレクトリを`/opt`配下に移動する

    ```sh
    # mv zeppelin-0.8.2-bin-all /opt/zeppelin
    ```

4. zeppelin 実行用ユーザを作成する

    ```sh
    # useradd zeppelin
    ```


5. 必要に応じて環境変数を設定する(ここではIPアドレス)

    ```sh
    # cp /opt/zeppelin/conf/zeppelin-env.sh.template /opt/zeppelin/conf/zeppelin-env.sh
    # vi /opt/zeppelin/conf/zeppelin-env.sh
    ```
    
    ```
    export ZEPPELIN_ADDR=<ブラウザでアクセスするIPアドレス>                          # Bind address (default 127.0.0.1)
    ```

6. ディレクトリの所有者を zeppelin 実行用ユーザに変更する

    ```sh
    # chown -R zeppelin:zeppelin /opt/zeppelin
    ```

6. zeppelin サービスファイルを作成する

    ```sh
    # vi /etc/systemd/system/zeppelin.service
    ```
    
    ```
    [Unit]
    Description=Apache Zeppelin Service

    [Service]
    Type=forking
    User=zeppelin
    ExecStart=/opt/zeppelin/bin/zeppelin-daemon.sh start
    ExecStop=/opt/zeppelin/bin/zeppelin-daemon.sh stop
    
    [Install]
    WantedBy=multi-user.target
    ```

7. サービスファイルを再読み込みする

    ```sh
    # systemctl daemon-reload
    ```

8. 起動する

    ```sh
    # systemctl start zeppelin
    ```

9. ブラウザからアクセスする

    ![Zeppelin.アクセス直後png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34297/3e146307-099d-be3f-f6e8-4c568af76096.png)


# 参考
- [Install](https://zeppelin.apache.org/docs/0.8.2/quickstart/install.html)
- [Zeppelin Properties - Apache Zeppelin Configuration](https://zeppelin.apache.org/docs/0.8.2/setup/operation/configuration.html)
[SwiftUI]Modal表示の仕組みについて考えるTIPs

短いです。モーダル表示周りの仕組みについて考えたことを残しておきます。雑文です。

# 前書き
SwiftUIでmodal表示をする時に、以下のような事をします。

1. `.sheet(isPresented: $showModal) { ... }`
2. 次の画面で`@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>`を宣言して、`presentationMode.toggle()`をする事で画面を閉じることができる。

この挙動がどのようなものか、ブラックボックスで利用していたのですが、[先日書いた記事](https://qiita.com/yosshi4486/items/3d92f81feaabc1049b4c)と合わせて考えると、なんとなく挙動が想像できました。

# 考えた仕組み
肝心なのは`Environment Modifier`という考え方で、`.sheet(isPresented: $showModal) { ... }` を実行するとSheetでの表示処理と合わせて、`.environment(\.presentationMode, isPresented)`の処理が内部的に実行されており、そのため`@Environment`で`presentationMode`が取得でき、画面を閉じるなどの操作が可能になっている。という感じです。

# 終わり
このように、SwiftUIでは`Modifier`に対して環境変数を設定する仕組みを同時に入れておき、別の`View`で`Environment`を使って取り出す。のような操作はメインのパターンとして登場しそうですね。

それでは終わりです。お読みいただきありがとうございました〜
FlutterでStackの下のビューにタッチイベントを伝える

StackでSingleChildScrollViewの上に、オーバーレイで全画面のWidgetを重ねて、下のビューはスクロールしたいということがありました。
実現するためにはオーバーレイのWidgetを`IgnorePointer`でラップすれば、下のSingleChildScrollViewにスクロールイベントが伝わるようになります。

```
    return SizedBox(
      height: double.infinity,
      width: double.infinity,
      child: Stack(
        children: <Widget>[
          SingleChildScrollView(),
          IgnorePointer(ignoring: true, child: Container())
        ],
      ),
    );
```

参考
https://stackoverflow.com/questions/51622318/pointer-events-nonecss-in-flutter

ちなみにReact Nativeでは https://qiita.com/sekitaka_1214/items/6dbc08401cf349a78cef
ローカル環境へのWordPressインストール方法

# はじめに

ここでは、MAMPを使ってローカル環境にWordPressをインストールする方法について解説します。
Windows環境を想定しています。


# WordPress用データベースの作成

まず、WordPress用に、MySQLデータベースを作成します。
データベース名はWordPressインストール時に入力しますので、WordPress用のデータベースであることが分かりやすい名前にしておくと良いです。


# WordPressのインストール

[WordPress公式ページ](https://ja.wordpress.org/)にアクセスし、「Wordpressを入手」をクリックします。

![WP-top.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517951/0be1c527-b755-7599-9122-095ac98ea6ba.png)

すると、ダウンロードページに移ります。
ここで、WordPress X.X.Xをダウンロードをクリックすると、zipファイルがダウンロードされます。

![WP-download.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517951/bb6891e8-7c94-071a-0e1d-afb44ef96573.png)

zipファイルを展開し、MAMPディレクトリのhtdocsディレクトリ下にコピーします（デフォルトの設定の場合）。
そして、「localhost:80/wordpress」にアクセスします（Macの場合はlocalhost:8888）。
すると、以下のような画面が出てくるので、「さあ始めましょう！」をクリックします。

![WP-setup.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517951/023aae45-8833-264d-1d26-3dfbd0978e85.png)

すると、データベースにアクセスするための情報の入力を求められるので、上で作成したデータベース名などを入力します。

![WP-detail.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517951/615f8f99-90b1-d559-63cf-279b89cf65e4.png)

「インストール実行」をクリックすると、WordPressがインストールされます。

![WP-installed.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517951/ae36fae4-4cc9-734f-c97e-8d1b906612f6.png)

その後、管理画面にログインするためのユーザー名やパスワードを作成すると、ローカル環境でWordPressを利用できるようになります。


# まとめ

ここでは、ローカル環境にWordPressをインストールする方法について解説しました。
WordPressはレンタルサーバーにインストールすることが多いと思いますが、ローカル環境にもインストールしておくと、公開前のサイトの記事の下書きをストックしておいたりなどの使い方ができます。
個人アプリ制作

animationプロパティ
animation-name -> アニメーションの名前
animation-duration -> アニメーションの開始から終わるまでの時間（1回分）
| xs | x秒 
| xms | xミリ秒（1000ミリ秒 = 1秒）

animation-timing-function -> アニメーションの進捗時の効果
| ease | 開始と完了を滑らかにする（cubic-bezier(0.25, 0.1, 0.25, 1.0) を指定したのと同じ）（初期値） 
| linear | 一定（cubic-bezier(0.0, 0.0, 1.0, 1.0) を指定したのと同じ） 
| ease-in | ゆっくり始まる（cubic-bezier(0.42, 0, 1.0, 1.0) を指定したのと同じ） 
| ease-out | ゆっくり終わる（cubic-bezier(0, 0, 0.58, 1.0) を指定したのと同じ） 
| ease-in-out | ゆっくり始まってゆっくり終わる（cubic-bezier(0.42, 0, 0.58, 1.0) を指定したのと同じ） 
| cubic-bezier(数値, 数値, 数値, 数値) | 3次ベジェ曲線のP1とP2を (x1, y1, x2, y2) で指定 

animation-delay -> アニメーションが開始するまでの時間
| xs | x秒 
| xms | xミリ秒（1000ミリ秒 = 1秒） 

animation-iteration-count -> アニメーションの繰り返し回数
| infinite | 無限に再生を繰り返す 
| 数値 | 数値で再生回数を指定する（初期値は1） 

animation-direction -> アニメーションを逆再生（順番）
| normal | 普通方向の再生でアニメーションサイクルを繰り返す（初期値） 
| alternate | 奇数回では普通方向の再生、偶数回では逆方向の再生となって、アニメーションサイクルを繰り返す 

animation-fill-mode -> アニメーションの開始前と終了後の状態
| none | 適応なし（初期値） 

| forwards | アニメーションの終了時に、もとの状態に戻らない（100%の状態） 
| backwards | アニメーションの終了時に、もとの状態に戻る（0%の状態） 
| both | forwardsとbackwardsが両方適応される 

animation-play-state -> アニメーションの再生と停止
| running | アニメーションが再生されます（初期値） 
| paused | アニメーションが停止します 

@keyframes animation-name {
  from {           　　　　　　　　　　　         //開始時スタイル
    width: 0%;
  }
  to {　　　　　　　　　　　　　//終了時スタイル
    width: 100%;
  }
}
Selenium IDEを複数同時実行する

Selenium IDE（Chrome版）はブラウザの簡単な自動化で重宝しますが、
できれば同時に動かしたい場面ありますよね。
（自分の場合はブラウザで表示されるデータの監視をしながら別のプログラムを動かしたかった）

結論としては、**Google Chromeでユーザーを追加**します。

**■ 必要なもの**
・ Google Chrome
・ Selenium IDE (Chrome拡張機能)

**■ やり方**
公式[^1]引用
1. ユーザーまたはプロフィールを追加する
2. パソコンで Chrome を開きます。
3. 右上のプロフィール プロフィール をクリックします。
4. [追加] をクリックします。
5. 名前と画像を選択します。
6. [追加] をクリックします。新しいウィンドウが開き、同期をオンにするように求められます。
~~7. （省略可）新しいプロフィール用の Google アカウントを使用して Chrome で同期をオンにします。ブックマーク、履歴、パスワードとその他の設定が自動的に同期されます。~~
⇒同一PC内では同期できないので`7`は実施しなくて大丈夫です。

それだけだとなんだか寂しいので、
以下、画像で簡単に手順を記載しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/5dd5ecd4-71ec-8fb4-5cee-4bda4b6ebd38.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/0485660d-b119-a2b9-8fc1-5ff166790d46.png)

同時に実行している様子です（同じソースですが）。

![1e2d66f4500377bc5e2b3578aef5d27a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/13a2beff-f1d9-d884-fc0f-8e7d9ac48d28.gif)

**■ 所感**
ユーザー追加自体は教えてもらって初めて知ったのですが、
ついでにできてしまいました。棚ぼたです。

[^1]: [Chrome を他のユーザーと共有する - パソコン - Google Chrome ヘルプ](https://support.google.com/chrome/answer/2364824?co=GENIE.Platform%3DDesktop&hl=ja)
AzureADでのグループベースのライセンス管理

#グループベースのライセンス管理とは
AzureADで作成したグループに対して、配下のメンバーにライセンス付与を行う機能です。
MSの概要は[こちら](https://docs.microsoft.com/ja-jp/azure/active-directory/fundamentals/active-directory-licensing-whatis-azure-portal)

#どんな時に便利なの？
ライセンス付与は手動もしくはスクリプトで運用をされているところが多いかと思いますが
この機能を使うと、AzureADのグループ管理さえ行っていけば、勝手にライセンスも付与してくれます。
→運用負荷の軽減につながるというメリットがあります。

#実際にやってみた
##前提条件
以下のいずれかのライセンスが必要
・Azure AD Premium P1 以上
・Office 365 Enterprise E3、Office 365 A3、Office 365 GCC G3、Office 365 E3 for GCCH、Office 365 E3 for DOD 

##AzureADの設定
まずAzurePortalにログインします。

メニューからAzureActiveDirectory→ライセンス→すべての製品　を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167126/8a20354b-d409-b83b-1bf9-562f03c7c3e7.png)

※今回はあらかじめAzureADのP2の試用版をとっていて、EMSのE5の試用版を取得しています。

今回はE5のライセンスを付与します。
なので、「Enterprise Mobility + Security E5」にチェックを入れて、「割り当て」を選択します。

ライセンス付与対象のグループを選択します。
※今回はあらかじめ「営業部」というグループにユーザーtest01とtest02を入れています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167126/fbf1fcf8-2cf1-1406-9338-4e415231442f.png)
続いて「割り当てオプション」を選択して、必要に応じてオンオフを切り替えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167126/0ca0267d-bd2d-3d4c-5473-30bf4963e712.png)

最後に「割り当て」をクリックします。

再度「Enterprise Mobility + Security E5」を選択し、「ライセンスされているグループ」を選択すると、営業部のグループが入っていて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167126/596eeae4-ccd9-078b-f29e-508e0b03972b.png)


「ライセンスされているユーザー」にtest01とtest02がいることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167126/ef96aafa-c2c1-055e-1d8a-741d4d42d17c.png)

##Apendix
グループには「手動管理」と「動的管理」があり、「メンバーシップの種類」を[動的ユーザー]とした場合には、グループのメンバー追加、削除をユーザー属性をベースに動的に更新することができます。
これを使って、例えばdiscription属性に[sales]と入っている場合は営業部のグループにいれる、といったことができます。
そうすることで、ユーザーを作成するだけで、自動的に適切なライセンスを割り当てることが可能となります。

今までは手動運用だったり、ライセンス付与スクリプトの開発などを行っていましたが
これを活用するとかなり工数削減に繋がりますね。

ただしライセンス数の残数には注意ですね。
よくあるトラブルについては、この辺りが参考になりそうです。
[Azure Active Directory のグループのライセンスに関する問題を特定して解決する](https://docs.microsoft.com/ja-jp/azure/active-directory/users-groups-roles/licensing-groups-resolve-problems)
[開発]Javaフレームワーク比較

個人メモ

# 【Javaフレームワーク】
| No | フレームワーク                                                  | 開発           | 公開年 | バージョン(確認日時) | 概要                                                                |
|----|-----------------------------------------------------------------|----------------|--------|----------------------|---------------------------------------------------------------------|
| 1  | [Play Framework](https://www.playframework.com/)                | Guillaume Bort |        |                      |                                                                     |
| 2  | [Spring Boot](https://spring.io/projects/spring-boot)           |                |        |                      |                                                                     |
| 3  | [Spring Framework](https://spring.io/projects/spring-framework) | Rod Johnson    | 2003年 |                      | 環境に依存する機能を外部から提供可能とする方法が特徴的              |
| 4  | [Apache Struts](https://struts.apache.org/)                     |                |        |                      |                                                                     |
| 5  | [JSF(Java Server Faces)](https://javaserverfaces.java.net/)     |                | 2004年 |                      |                                                                     |
| 6  | [Apache Wicket](https://wicket.apache.org/)                     |                | 2005年 |                      |                                                                     |
| 7  | [Dropwizard](http://www.dropwizard.io/)                         |                |        |                      | yammerのWebサービス提供のために作られた、比較的新しいフレームワーク |

## [Play Framework](https://www.playframework.com/)  Zenexity社のソフトウェア開発者であるGuillaume Bortにより作成
Ruby on RailsとDjangoから大きな影響を受けた、これらと似た同種のフレームワーク
## [Spring Boot](https://spring.io/projects/spring-boot)
2.2.2
## [Spring Framework](https://spring.io/projects/spring-framework)
## [Apache Struts](https://struts.apache.org/)
## [JSF (Java Server Faces)](https://javaserverfaces.java.net/)
## [Apache Wicket](https://wicket.apache.org/)
## [Dropwizard](http://www.dropwizard.io/)
[開発]javascriptフレームワーク比較

#■ 【JavaScriptフレームワーク】
| No | JavaScriptフレームワーク                    | 開発                     | 公開年 | バージョン(確認日時) | 概要                                                  |
|----|---------------------------------------------|--------------------------|--------|----------------------|-------------------------------------------------------|
| 1  | [Angular](https://angular.jp/)              | Google及びコミュニティ   | 2016年 | 8.2.9(2019.12)       | モダンなWebアプリのための機能を多く標準で備えています |
| 2  | [AngularJS](https://angularjs.org/)         | Google及びコミュニティ   | 2012年 | 1.7.x(2019.12)       |                                                       |
| 3  | [Vue.js](https://vuejs.org/)                | Evan You（元Google）     |        |                      |                                                       |
| 4  | [jQuery](https://jquery.com/)               | ジョン・レシグ           |        |                      |                                                       |
| 5  | [React.js](https://reactjs.org/)            | Facebook及びコミュニティ |        |                      | 最小限の状態から開始                                  |
| 6  | [Riot.js](https://riot.js.org/ja/)          |                          |        |                      | シンプルかつ軽量なコンポーネント指向のUIライブラリ    |
| 7  | [Hyperapp](https://github.com/jorgebucaran) |                          |        |                      |                                                       |
| 8  | [Backbone.js](https://backbonejs.org/)      |                          |        |                      |                                                       |
## [Angular](https://angular.jp/)
TypeScriptとRxJS
## [AngularJS](https://angularjs.org/)
動作端末が多いアプリケーションを作成出来る
## [Vue.js](https://vuejs.org/)    開発者Evan You（元Google）

ライブラリ
## [jQuery](https://jquery.com/)   開発者ジョン・レシグ 
## [React.js](https://reactjs.org/)
JSX、Flow、Redux
## [Riot.js](https://riot.js.org/ja/)
非常にシンプルかつ学習コストの低いコンポーネント指向のフレームワーク
## [Hyperapp](https://github.com/jorgebucaran)  開発者Jorge Bucaran（Qiitaの中の人）
## [Backbone.js](https://backbonejs.org/)

## その他
w2ui

#■ 【CSSフレームワーク】

| No | CSSフレームワーク                           | 開発 | 公開年 | バージョン(確認日時) | 概要                                                                               |
|----|--------------------------------------------|------|--------|----------------------|------------------------------------------------------------------------------------|
| 1  | [Bootstrap](https://getbootstrap.com/)     |      |        |                      | 王道                                                                               |
| 2  | [Materialize](https://materializecss.com/) |      |        |                      | Google推奨のデザインガイドラインである「マテリアルデザイン」に準じたフレームワーク |
| 3  | [Milligram](https://milligram.io/)         |      |        |                      | シンプルな作りで動作が軽いのが特徴                                                 |


## [Bootstrap](https://getbootstrap.com/)
## [Materialize](https://materializecss.com/)
Googleが推奨するデザインのガイドラインである「マテリアルデザイン」に準じたフレームワーク
## [Milligram](https://milligram.io/)
シンプルな作りで動作が軽いのが特徴
mosquittoでpub/sub

mosquittoを用いたpub/sub通信について、以下のそれぞれでの実施方法を自分用にまとめる。

* コマンド(mosquitto-clients)
* python
* javascript

# コマンド(mosquitto-clients)

## localhostでmosquittoが起動している場合

pub

```bash
mosquitto_pub -d -t test/mytopic -m "mymsg" -r
```

※-rをつけるとRetail機能が有効となり、あとからsubしたプロセスに、最後にpubしたメッセージが届く


sub

```bash
mosquitto_sub -d -t test/mytopic
```

## 他ホストで起動している場合

pub

```bash
mosquitto_pub -h 192.168.3.142 -p 1883 -t test/mytopic -m 'mymsg' -q 0 -d -r
```

sub

```
mosquitto_sub -h 192.168.3.142 -p 1883 -t test/mytopic -d
```

# python

pub

１発

```python
import paho.mqtt.publish as mqtt_pub

mqtt_pub.single("test/mytopic", "mymsg",retain=True,hostname="localhost",port=1883)
```

インスタンス生成して実施するパターン

```python
import paho.mqtt.client as mqtt

mqttc = mqtt.Client()
mqttc.connect("localhost", 1883, 60)

mqttc.publish("test/mytopic","mymsg",qos=0,retain=True)
```

sub

```
import paho.mqtt.client as mqtt

def on_message(mqttc, obj, msg):
    print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))

mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.connect("localhost", 1883, 60)

mqttc.subscribe("test/mytopic")

mqttc.loop_forever()
```

トピックごとにコールバック先を指定する。

```python
import paho.mqtt.client as mqtt

def on_mytopic_a(mosq,obj,msg):
    print("specific:"+msg.topic + " " + str(msg.qos) + " " + str(msg.payload))

def on_message(mqttc, obj, msg):
    print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))

mqttc = mqtt.Client()
mqttc.message_callback_add("test/mytopic/a",on_mytopic_a)
mqttc.on_message = on_message
mqttc.connect("localhost", 1883, 60)

mqttc.subscribe("test/#")

mqttc.loop_forever()
```



# javascript

※mosquittoのweb-socketを使用して通信

pub

```javascript
import mqtt from 'mqtt';

this.mqtt_client = mqtt.connect("ws://192.168.3.142:9090");

this.mqtt_client.publish("test/mytopic","mymsg",{qos:0,retain:true});
```


sub

```javascript
import mqtt from 'mqtt';

on_message = (topic,message) => {
      console.log(message);
}

this.mqtt_client = mqtt.connect("ws://192.168.3.142:9090");

this.mqtt_client.subscribe("test/mytopic",{qos:0});
this.mqtt_client.on("message",this.on_message);
```

# memo

~~on_messageでtopicの内容に応じて処理を分岐するのはあまりエレガントでない気がする。~~
~~subscribeするトピック毎にコールバック先を指定できないのか？コールバック先毎にmqttの接続インスタンスを作ってコールバックする？~~

pythonはmessage_callback_addでトピック毎のコールバック先を指定できる。(subscribeでワイルドカード？で指定）

~~MQTT.jsはsubscribeでcallback関数を指定できるっぽいが、未検証。検証し次第アップデートする。~~

MQTT.jsはトピック毎の指定はできない(issueが投稿されている。https://github.com/mqttjs/MQTT.js/issues/941)。


# 参考

https://qiita.com/hsgucci/items/6461d8555ea1245ef6c2

https://www.sunbit.co.jp/blog/2019/11/21802/

https://github.com/eclipse/paho.mqtt.python/blob/master/examples/client_sub-multiple-callback.py

https://github.com/mqttjs/MQTT.js/blob/master/README.md
Swift UIButtonの背景色をHighlightで変わるようにする

#単色のUIImage生成
SwiftのUIButtonの`titleColor` は `state`によって動的に変えることができますが、背景色は変えられません。
そのため、動的に変更することが可能な、単色のUIImageを背景に設定することで背景を動的に変更するようにします。

```swift
var image: UIImage? {
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContext(rect.size)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }
        context.setFillColor(UIColor(red: 1, green: 1, blue: 1, alpha: 0.8).cgColor)
        context.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
```

#使い方
任意の場所でこのように書くと任意の色で設定することができます！

```swift
    let button = UIButton()
    button.setBackgroundImage(image, for: .normal)
    button.setBackgroundImage(image, for: .highlighted)
```
COTOHA APIでつくる「ルー語」変換LINE Bot

# やりたいこと・経緯
- 入力した日本語文の一部をカタカナ表記の英語に変換（＝**ルー語**を生成）し返すLINE Botをつくってみる
- ルー語とは：日本語文の一部を単語単位でカタカナ表記の英語に置き換えたルー大柴さんの（流行ったのは十年以上前の）ネタ
- たとえば「言わぬがフラワー」「塵も積もればマウンテン」など
- 実はすでに[ルー語変換](https://lou5.jp/)というウェブサイトがあり、そのサイトの[開発経緯](https://e8y.net/blog/2006/12/31/p139.html)には「文章を形態素解析 → 単語を英訳 → 英語をカタカナ読みに翻訳 」していると書いてある
- 日本語文の形態素解析にはMeCabを利用しているそう。COTOHA APIを使って作ったらどうなるだろうか、という単純な思いつき

# COTOHA APIについて
- https://api.ce-cotoha.com/
- 文の形態素解析や固有表現抽出などの自然言語処理や音声処理をRESTなAPIでやってくれるAPI
- ひととおりに触ってみて、非常に精度がよく、アイディア次第で色々な面白いものがつくれそう
- 今回は「キーワード抽出」のAPIを利用しています

# つくったもの
[![Image from Gyazo](https://i.gyazo.com/1c488d6f2e2536320c6eba2582360b6e.gif)](https://gyazo.com/1c488d6f2e2536320c6eba2582360b6e)

# 仕様
- ユーザーからの日本語文入力を受け取る
    - COTOHA APIのキーワード抽出にかけ、キーワードを抽出
    - 最上位のキーワード（APIからは複数の返り値もありえる）をGoogle 翻訳で英語に変換
    - 英語に変換したキーワードを、カタカナに変換
- ユーザーからの入力のうちキーワードを変換されたカタカナに置き換え、返信

# 技術
- COTOHA APIの[「キーワード抽出」API](https://api.ce-cotoha.com/contents/reference/apireference.html#keyword)。例↓

```js

const BASE_URL = 'https://api.ce-cotoha.com/api/dev/'

async function extractKeywords(documentArray) {
  const urlEndPoint = 'nlp/v1/keyword'
  return axios({
    url: BASE_URL + urlEndPoint,
    method: 'POST',
    headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        'Authorization': `Bearer ${await getAccessToken()}`
    },
    data: {
        'document': documentArray
    }
  }).then(res => {
    const keywords = res.data.result
    if (keywords.length === 0) return false
    return keywords
  }).catch(err => {
    console.log(err.response.status)
    console.log(err.response.data)
    return false
　})
}
```
- ソースコード（環境変数除く）

![img](https://gh-card.dev/repos/embokoir/cotoha-lou-linebot.svg?fullname=)
- サーバーはNode、全面的にasync-await / axios
- デプロイはGithubから[Glitch](https://glitch.com)へクローン
- Google翻訳部分はCloud Translation APIを使うのが精度も速度もいいとは思うものの面倒だったのでGASでそれっぽいAPIを自作 
- 英語→カタカナ変換の部分は[English to Katakana Converter](https://www.sljfaq.org/cgi/e2k.cgi)のAPI（非公式）を使わせていただきました *1

# 考察など
- ルー語は、文のうちどこをどう英語化するかが妙で、ルー大柴さんはその点が絶妙。片っ端から英訳しているわけでもないし、またいわゆる日本語英語みたいなものも織り交ぜている
- 当初はCOTOHA APIの構文解析APIを使用していたが、文からすべての名詞とかを抽出したところで**どれを英訳すると面白くなるのか**という部分で実装が難しくなってくることに気づき、キーワード抽出APIに乗り換えたところ、いい感じにワードを選んでくれた。ちなみにCOTOHA API的に「キーワード」とは「名詞」「主語」「目的語」「反復される語」などの属性を持ちやすい気がした
- ルー語化する文はことわざや早口言葉やお堅い文が向いている

# 結果比較
本家のものは[名言・格言『ルー大柴さんの気になる言葉』一覧リスト](https://iso-labo.com/labo/words_of_lou-Oshiba.html)を参照しました

|元々の日本語|本家ルー語|このBot|ルー語変換サイト|
|:---:|:---:|:---:|:---:|
|言わぬが花|言わぬがフラワー|**言わぬがフラワー**|言わぬがフラワー|
|一寸先は闇|一寸先はダーク|**一寸先はダークネス**|一寸アフターはダーク|
|寝耳に水|寝耳にウォーター|**寝耳にウォーター**|寝耳に水|
|阿吽の呼吸|阿吽のブレス|**阿吽のブリージング**|阿吽のブレス|
|三日坊主|スリーデイズ坊主|**スリーデーズシェーブド**|三デイクルーカット|
|身を粉にする|身をパウダーにする|**身をパウダーにする**|ボディーをミールにする|
|二兎を追う者は一兎をも得ず|二兎をチェイスする者は一兎をもゲットせず|**二兎を追う者はワンラビットをも得ず**|二兎をランアフターするパースンは一ラビットをも得ず|
|雨降って地固まる|レイン降ってグランド固まる|**雨降ってソリディファイ**|レイン降ってアース固まる|

# 結論
- ルー語ってコンピュータ的に生成しようとすると実は結構奥深い
- COTOHA APIが抽出するキーワードは、ルー語の面白さに割と近づけているのでは…？
- 嵐の前のセレニティー、伝家のトレジャーソードあたりが個人的にツボ
- ~~気になる方はこちらかQRコードから友だち登録して遊んでみてください~~公開停止しました 2020/8
apollo clientのcacheに有効期限をつける

# はじめに

Apollo Client ver3.0では新たにcacheについていくつか機能が追加されています。その一つがcacheの削除です。
cacheに有効期限を設ける方法について、考えたので備忘録として残します（もっといい方法があれば教えてください）

# evictとgc

今回は Apollo Client ver3.0で新しく追加されたgcとevictを使います。詳しい説明は[公式doc](https://www.apollographql.com/docs/react/v3.0-beta/caching/cache-interaction/#garbage-collection-and-cache-eviction)を参照してください

### evict
evictはcacheに保存されているdataを消すことができます。
使う際は__typenameとidをセットにして使います

```javascript
cache.evict('__typename:id')
```

### gc
gcはevictで特定のdataを消した後cacheに残っているゴミを消すことができます。
ここでいう今回消したdataをrefとして持つ親データです。子を消した事によって、親が参照するdataがなくなりますが、gcを使う事によってこういったゴミを消すことができ、cacheのdataがクリーンに保たれます。

```javascript
cache.gc()
```


# 実装例

以前挙げた[Qiitaの記事](https://qiita.com/kobyta/items/d21d5a0b6d06bfea8b48)のQueryで保存されたcacheに有効期限10分をを設定したコードです。（apollo clientの中に有効期限設定できる機能があるのかも?）

```javascript
import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client";

const link = new HttpLink({
  uri: "http://localhost:4000/graphql"
});

const cache = new InMemoryCache()

const cacheInterval = setInterval(() => {
  cache.evict('Comment:1');
  cache.gc();
}, 10 * 60 * 1000);

const client = new ApolloClient({
  link,
  cache,
  defaultOptions: {
    watchQuery: {
      fetchPolicy: "cache-first"
    }
  }
});
```
並列"Hello World"から始めるCUDA入門

# はじめに

CUDAって、OpenMPなんかに比べると「とりあえず並列に動くコード」を書くのが難しい気がします。
私も何年か前に初めてCUDAを勉強したとき、**ブロックとかスレッドとかストリームとかメモリのコピーとか、コード書く前に覚えること多すぎる...**と苦しみました。コードが動くとこまでいかないと、モチベーション維持が大変ですよね。

そこで、**とりあえず並列で動くHello World**の書き方を紹介したいと思います！参考になれば幸いです。

# 並列処理させるための関数を作る

今回は"Hello World"を出力する関数を作り、それをCUDAで並列処理させるために書き換えていきます！
まず、C言語でベースとなるコードを書いていきましょう。

```c++
#include <stdio.h>

void hello(){
    printf("Hello World !!\n");
}

int main() {
    hello();
    return 0;
}
```

出来ました。`hello`関数を呼び出すと`"Hello World !!\n"`が表示されます。
この`hello`関数を並列処理させるには、**関数の先頭に`__global__`を付けるだけでOKです！**

```c++
#include <stdio.h>

__global__ void hello(){
    printf("Hello World !!\n");
}

int main() {
    hello();
    return 0;
}
```

これで`hello`関数はGPUで並列処理される関数に生まれ変わりました。このように先頭に`__global__`をつけた関数を**カーネル関数**と呼びます。**関数の書き換えはこれだけです。**

じゃあ早速コンパイル&実行してみましょう！

```
: error: a __global__ function call must be configured
```

なんかエラーが出ましたね。まあ当たり前ですね、**並列数書いてないんですから。**

# 並列数を記述する

並列数は関数を呼び出すときに付け加えてやればOKです！

```c++
#include <stdio.h>

__global__ void hello(){
    printf("Hello CUDA World !!\n");
}

int main() {
    hello<<< 2, 4 >>>();
    return 0;
}
```

ここで見慣れない記法が現れました。`<<< 2, 4 >>>`って何...?

これは、関数を呼び出す際に使用するブロック数とスレッド数を表しています。書き方は、`<<< [ブロック数], [スレッド数] >>>`です。CUDAではスレッドの上位階層にブロックが用意されていて、「何ブロック目の何番スレッド」と住所のように管理されています。このあたりの話は少しややこしくなるので詳しい説明はまた別途行うこととします。

この記事では、**[ブロック数]×[スレッド数]だけ関数が並列処理される！**とだけ覚えてください。

ブロック数とスレッド数を追記したコードでコンパイル＆実行してみます。

```

```

...何も表示されません。なぜでしょうか？

# カーネル関数の同期処理

実は、カーネル関数は関数内の処理の終了を待たずにCPU側（関数の外）の処理が進んでしまうんです！今回の場合だとカーネル関数呼び出し後すぐにプログラムが終了するため、**Hello Worldが出力される前にプロセスが終了してしまいました**。

この問題は、カーネル関数を呼び出した後に`cudaDeviceSynchronize();`を記述してやれば解決します。この関数の呼び出しは、**カーネル関数でGPUに渡した処理が全部終わるまでCPUは待っててくださいね。**という意味になります。これを反映したコードが以下です。

```c++
#include <stdio.h>

__global__ void hello(){
    printf("Hello CUDA World !!\n");
}

int main() {
    hello<<< 2, 4 >>>();
    cudaDeviceSynchronize();
    return 0;
}
```

# 実行

今度こそ完成です。コンパイル＆実行してみましょう。

```
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
```

ちゃんと2×4=8並列されてますね。紆余曲折ありましたが意外とすんなり並列処理できたのではないでしょうか。

# まとめ

今回はできるだけ難しいことは置いといて、とりあえず並列に動くコードを書くことに焦点を当てて解説してみました。さすがにこの知識だけだと実際にCUDAを活用するには不十分化かと思いますが、少しでも勉強のお手伝いができたなら幸いです。