OmniAICreator/Qiita-1.07M huggingface dataset:
useRef

# useRefの用途
* DOMへのrefを通したアクセス手段
* スコープの長いmutable変数生成

## 基本仕様
* refを変えても再レンダリングは走らない（通常の変数と同じ動作）
* コンポーネントとライフサイクルをともにする（再レンダリング時に再生成されない）

## DOMへのrefを通したアクセス手段

React のサンプルでイメージはつかめる

```react
function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}
```

個人的には内部のDOMの振る舞いを外から操作していると思うので、振る舞いを変える穴が増えている印象であまり使いたくない。

## スコープの長い変数
通常、コンポーネント内の変数はrenderごとに再生成される。
useRefを通して作成した変数は、コンポーネント初期化時からコンポーネントが消えるまで保持される。

[const, use state, use refのスコープ違い(codesandbox)](https://codesandbox.io/embed/useref-zj6l1?fontsize=14&hidenavigation=1&theme=dark)

見ての通り、Use Ref Randomには、表示時にRefの初期化で数値を生成してセットしている。
再レンダリングを何度されようが変わらない。Refの値は意図して変えない限り、維持されている。
Refの値を変えたところで再レンダリングのトリガーとはならないため、見た目は変わらず、次回の他の値の再レンダリング時にcurrentの値で表示される。
そろそろReactのパフォーマンスチューニングが必要になったのでuseMemoとuseCallbackを調べてみた

業務でRailsアプリをRails + React/Reduxへのリプレイスを行いましたが、不要なレンダリングなどが目立ちパフォーマンスがよろしくないので、そろそろ`useCallback`と`useMemo`の出番かなと思い調べてみました。

僕自身の理解度は
`useMemo` = 値をメモ化する
`useCallback` = コールバック関数を記憶する。イベントハンドラなどに使用する
くらいの知識量です。

## useMemo
[公式ドキュメント](https://ja.reactjs.org/docs/hooks-reference.html#usememo)では次のように説明しています。
> メモ化された値を返します。

そのまんまじゃねーか...
Reactのfunctionコンポーネントは主に以下のタイミングで再レンダリングが行われます。

* 親コンポーネントがレンダリングされたとき
* 親コンポーネントから渡されているpropsに変更があったとき
* コンポーネント内にあるuseStateで定義している変数に変更があったとき
 
使っているときはなんとなくこのくらい再レンダリングされる要素があるんだなと感じますが、文字に起こすと結構な頻度で再レンダリング走ることがわかりますね。
このときに処理をレンダリングされるたびに行っていたらパフォーマンス悪いよねということでメモ化しようというのが`useMemo`です。

使い方は以下のようになります。

```
import React, { useMemo } from 'react'

const Foo = useMemo(() => {
 // 処理
 return hogehoge
}, [依存変数])
```

メモ化したい処理を書いてreturnするだけですね。
注意が必要なのは`useMemo`の第二引数です。
useEffectなども同じなのでわかりやすいですが、第二引数は依存関係を表しています。
動作は2パターンあります。

* 空配列を渡した場合は初回の一度だけ実行される
* 変数を渡した場合は、初回と渡した変数に変更があった場合に処理が実行される

例えば、以下のコードは変数yに依存しているので変数yに変更があった場合は処理にも実行されます。(メモ化する処理ではないですが目をつむってください)

```
const square = useMemo(() => {
 return y ** y
}, [y]
```

第二引数にはなにかしら変数が渡されていることが多いイメージですね。

## useCallback

[公式ドキュメント](https://ja.reactjs.org/docs/hooks-reference.html#usecallback)では次にように説明されています。
> メモ化されたコールバックを返します。

...知ってた

コールバック関数も再レンダリングされるたびに関数インスタンスを生成されてしまうのでメモ化することでパフォーマンスを改善できます。
`useCallback`の使い方は`useMemo`とほぼほぼ同じです。(これもメモ化する必要はないです...)

```
import React, { useState, useCallback } from 'react'

const [count, setCount] = useState(0)
const onClick = useCallback(() => {
 setCount(count + 1)
}

return <Button onClick={onClick}>
```

主にイベントハンドラを使うときに使うと簡単に言ってしまいたいのですが、`useCallback`の使い所は少々難しいです。
詳しく解説している記事をqiitaにて発見しましたので、ご興味ある方はぜひご覧ください。
[React HooksのuseCallbackを正しく理解する](https://qiita.com/uehaj/items/99f7cd014e2c0fa1fc4e)

## あとがき
`useMemo`も`useCallback`も使い方自体はすごく簡単ですが、適切に使用しないとパフォーマンス上がらないというのが最大の難所だと感じています。
僕の知識が深まってきたら改めて記事にしたいです。
あと、ここらへんの簡単なガイドラインなどあったらほしいですね。

余談ですが、qiitaに記事を投稿するの初めてなのですごい緊張しました。
一回投稿したことで心理的障壁が下がることを期待。
カスケード障害とサーキットブレーカーの図 (PlantUML)

カスケード障害とサーキットブレーカーの様子をPlantUMLで作成しました。
この図を含んだブログ記事も記載しているので、興味あるかたは以下からどうぞ。

[すごいよ、サーキットブレーカー！ 〜 マイクロサービスアーキテクチャの設計パターン 〜 - ふじやまエッグの日々](https://fujiyamaegg.hatenablog.com/entry/2020/06/13/135404)

# カスケード障害
最初は局所的な障害が、だんだんとネットワーク全体に障害が連鎖していきます。それがカスケード障害です。そんな展開を以降の図で表現しています。

![cascade1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/ba55396b-fc85-fc50-ff69-9c50e511d8ac.png)

![cascade2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/f72af0ee-7f91-f1d2-46c8-6d59dadf8b12.png)

![cascade3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/9f42e597-4999-c83c-b3f4-02d0e7da0284.png)


![cascade4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/56ca2986-9e2b-c816-c32b-ee31f4624a77.png)

![cascade5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/21046e15-f9f2-3c1a-51b8-9b8804b830bf.png)

# サーキットブレーカーによる解決
サーキットブレーカーを導入することで、障害が発生したとしても、連鎖させずに止めることができます。

正常時は、回路(Circuit)は、閉じていますが(Closed)、リクエスト先のサービスに障害が発生するとサーキットブレーカー(Circuit Breaker)を発動させ、回路を開きます(Open)。

![circuitbreaker1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/5d27e088-e995-49f3-72bc-d8f855625514.png)

![circuitbreaker2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/04d529a8-e6c4-f521-3874-1ffe5a7c6680.png)



# 最後に
サーキットブレーカーは、ネットワーク全体に甚大な被害をもたらしかねないカスケード障害を食い止める、設計パターンです。 マイクロサービスアーキテクチャには、なくてはならない機構です。そんなサーキットブレーカーのありがたさを以下の記事にまとめているので、興味あるかたはぜひどうぞ。

[すごいよ、サービスメッシュ！ 〜 マイクロサービスアーキテクチャの設計パターン 〜 - ふじやまエッグの日々](https://fujiyamaegg.hatenablog.com/entry/2020/06/13/135404 )
Androidのベクター画像を使う

### 良いところ

- 端末解像度ごとに画像用意しなくて良いこと
- 画質を低下しないこと


### Android Studio定義した画像追加 手順

- リソースファイルに右クリック > new > Vector Asset
- <img width="678" alt="スクリーンショット 2020-06-13 14.23.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296847/64d03325-8447-a406-f5e9-f8f4418ae15f.png">

- Clip Art クリックして画像選択
- <img width="709" alt="スクリーンショット 2020-06-13 12.44.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296847/e12e3c9e-b578-8d88-7a80-8c171d81e5a6.png">

- Color　クリックして色を指定する
- Opacity 透過色指定
- next > finished

### 生成されたファイル例

- xml

```xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:tint="?attr/colorControlNormal"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M20.5,6c-2.61,0.7 -5.67,1 -8.5,1s-5.89,-0.3 -8.5,-1L3,8c1.86,0.5 4,0.83 6,1v13h2v-6h2v6h2V9c2,-0.17 4.14,-0.5 6,-1l-0.5,-2zM12,6c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2z" />
</vector>
```
- pathDataを展開したらこんなになりました。

``` 
    <path
        android:fillColor="@android:color/white"
        android:pathData="
        M22,16
        v-2
        l-8.5,-5
        V4
        C13.5,2.67 12.83,2 12,2
        s-1.5,0.67 -1.5,1.5
        V9
        L2,14
        v2
        l8.5,-2.5
        V19
        L8,20.5
        L8,22
        l4,-1
        l4,1
        l0,-1.5
        L13.5,19
        v-5.5
        L22,16
        z" />
```
### pathDataの説明

|  記号  |  意味  |
| ---- | ---- |
|  M  |  移動  |
|  L  |  直線  |
|  H  |  水平線  |
|  V  |  垂直線  |
|  C S Q T A   |  曲線  |
|  Z  |  パスを閉じる  |


### まとめ

- 既存にある画像を取り込むには便利
- 簡単なpathDataを自作するできる
- 曲線など複雑な図形作るには慣れるまで時間かかりそう

### 参考サイト
https://developer.android.com/reference/android/graphics/drawable/VectorDrawable.html
https://developer.android.com/guide/topics/graphics/vector-drawable-resources
DiscordのチャンネルへPythonで通知を行う方法


## はじめに

こんにちは、クラウドエンジニアの tmasuyama です。

オンライン飲み会なんかが流行っている昨今、ツールは色々ありますが
私の周りだと結構[Discord](https://discord.com/)が人気のような気がします。

Zoom と違って 3 人以上でも時間制限が無いことはもちろん、
遅延が少ないこと、多少のノイズは自動で消してくれるとことなんかもよいですよね。

そんな Discord ですが、Slack や LINE のように Bot で通知を飛ばすことができます。
curl のような気持ちで使うことができるので、使い方を紹介しましょう。

## 事前準備

API キーに相当する、WebHookURL を取得します。
チャンネルを作成したら、歯車マークから設定画面に飛びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/a0abf45f-ddb2-f50e-55df-e632886f4a1b.png)

開くと**ウェブフック**という項目があるのでクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/69606d56-dc4c-4052-799f-9dc9c31691de.png)

**ウェブフックを作成**を選択しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/66b546d9-a75a-47d8-5271-5b0c54ddc097.png)

名前の欄は、Discord で通知される時に Bot 名になります。
また、**ウェブフック URL**は後で Python ファイル内で使うのでコピーしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/29c6e934-35cd-f293-d511-9a01d80888b8.png)

これで事前の準備は完了です。

## Python ファイルの作成

特に Python 側で事前の準備は必要なく、requests モジュールを使います。
ここでは定番の**Hello, World!**を通知させましょう。

```discord_bot.py
# coding: utf-8
import requests

discord_webhook_url = '先ほどコピーしたウェブフックURL'

data = {"content": "Hello, World!"}
requests.post(discord_webhook_url, data=data)
```

実行してみると、次のような形で Discord のチャンネルに通知がきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/4e05c9ba-e145-445f-0876-f46c68764408.png)

これだけのコードで通知を飛ばすことができましたね。
お疲れさまでした。
IPv6アドレスしかないドメイン名は使えるのか😭

アドレスとしてIPv6アドレスしか持っていないドメイン名は現状(2020年6月)で使えるのか、という話です。[http://www.東京2021.tk](http://www.xn--2021-4x5f052k.tk) http://[2400:4050:2ba1:ac00:99:f0ae:8600:beef]/ （←QiitaがIPv6アドレスをわかってないからリンクにならない）というウェブサイトは [Freenom](https://www.freenom.com/ja/index.html) で以下のようなドメイン設定をしています。

![スクリーンショット 2020-06-13 14-02-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/18e99b04-dc0f-b279-0e4c-829bbec808cb.png)

んで、グーグル検索で `site:xn--2021-4x5f052k.tk "東京2021"` としても何も結果が出ないし、[http://www.🕔🕘.gq](http://www.xn--hx8hha.gq/) でも駄目なので、「東京2021」が嫌われているわけでも無いっぽいです…
~~`webmaster@東京2021.tk` にGmailからメール送っても届きません。~~ これは間違いで、postfixの設定ちゃんとやったらちゃんとGmailから`webmaster@東京2021.tk`宛てメールが届きました。メール受信設定の手順は例えば [🙆@I❤️♨️.tk というメルアドでメール受信する](https://qiita.com/kakinaguru_zo/items/e1c598cc17af623b4f62) を参照。Postfixとdovecotの設定やるとGmailからSMTP/POP3経由で絵文字ドメインからメールの送受信できます。このとき「👌」みたいなユーザー名は少なくとも `/etc/passwd` には作れないので、ユーザー名はアルファベットで作っておく必要はあります。

なお、IPv4のグローバル固定アドレスを普通の家庭用インターネットプロバイダから貰うのは若干追加料金がかかりますが、IPv6アドレスの下64ビットは自分で勝手に決めて機器に割り当ててよいので、適当に固定して、例えばNTTのレンタルルーターで以下のように外部との通信を全部許可すると公開サーバーを簡単に作れます。

![スクリーンショット 2020-06-13 14-19-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/17964891-611b-7832-396b-305b5c5c50ed.png)
ベイズでイロレーティング計算

逐次的な更新式より簡単かつ拡張性がある気がするので。

1~bernouli(sigmoid(b*delta_rate))

と、trueだけを取るlogistic回帰で、bはrate差100を64%にするために
Solve[1/(1 + Exp[-x*100]) == 0.64, x]
と計算

サンプルが少ない場合に、事前分布は無いと凄いことになるのでnormal(1500,1000)としました。


```r

library(rstan)

scode="
data{
  int N;
  int M;
  int x[N];
  int y[N];
  int one[N];
}

parameters {
  real rate[M];
}

model{
  real b=0.00575364;
  rate~normal(1500,1000);
  for(i in 1:N){
    target += bernoulli_lpmf( one[i] | inv_logit(b*(rate[x[i]]-rate[y[i]])) );
  }
  
}


#b=Solve[1/(1 + Exp[-x*100]) == 0.64, x]

#1-4の4人でxが勝ち
x=c(1,3,4,1,4,3,1)
y=c(2,2,3,3,2,2,4)

lst=list(N=length(x),x=x,y=y,M=max(x),one=rep(1,length(x)))
fit=stan(model_code = scode,data=lst,
         #init = function(){},
         chain=1,iter=500,warmup = 80)

la=extract(fit)

rate=apply(la$rate,2,mean)
print(rate)

```

[1] 2463.690  403.316 1254.647 1795.259

と割と妥当になります。
これは超基本で、perform[i]~normal(rate[i])とパフォーマンスを入れて多段階にするtrueskillsみたいなのや、rate[i,t]と時系列にする、そして次回にやるダブルスのレーティング等があります。
zshでのasdfの補完設定

# zshでのasdfの補完設定

Catalinaにしてからshellがzshになり次のようなエラーが出るようになったので修正しました。

```zsh
/usr/local/opt/asdf/etc/bash_completion.d/asdf.bash:68: command not found: complete
```

## 補完の設定
基本的には、 `fpath` を設定して `autoload -Uz compinit` と `compinit` を実行します。
asdfのinstall時に Homebrewを使った場合 と Gitを使った場合 で `fpath` の設定値が異なります。

## Homebrewを使ってinstallした場合
```zsh
fpath=(
  $(brew --prefix asdf)/etc/bash_completion.d
  $fpath
)
autoload -Uz compinit && compinit
```

## Gitを使ってinstallした場合
`ASDF_DIR` はGitを使ってinstallしたときのasdfのディレクトリを設定してください。

```zsh
fpath=(${ASDF_DIR}/completions $fpath)
autoload -Uz compinit && compinit
```

## 修正前

```zsh
# asdf
. $(brew --prefix asdf)/asdf.sh
. $(brew --prefix asdf)/etc/bash_completion.d/asdf.bash

# enable the default zsh completions!
autoload -Uz compinit && compinit
```

## 参考サイト
https://asdf-vm.com/#/core-manage-asdf-vm?id=add-to-your-shell
https://github.com/asdf-vm/asdf/issues/68
https://docs.brew.sh/Shell-Completion#configuring-completions-in-zsh
MeCabで形態素解析してみた

Ubuntu(bionic)上で、Ruby(mecabジェム)を使って形態素解析を実行してみるところまでの手順です。

まずはインストール。

```bash
apt install mecab mecab-ipadic-utf8 libmecab-dev
gem install mecab
```

以下のプログラムで解析結果を出力してみてみることが出来ます。

```ruby
require 'mecab'

tagger = MeCab::Tagger.new
puts tagger.parse(open('sample.txt').read)
```

出力結果の文字列(String)をパースして、単語の出現回数順に表示するサンプルです。

```ruby
require 'mecab'

tagger = MeCab::Tagger.new
t = tagger.parse(open('sample.txt').read)
words = {}
t.split("\n").each do |l|
  w = l.split("\t")[0]
  c = words[w] || 0
  c += 1
  words[w] = c
end

words.sort {|a,b| a[1] <=> b[1]}.each do |v|
  puts v[0]+"\t"+v[1].to_s
end
```

この例では品詞などを考慮していないので、「、。（句読点）」なども含まれてしまいます。目的に応じてフィルタリングなどが必要かと思います。

nattoというgemもあるようで、これらの力を借りるのも手かもしれません。また、もっと専門的な分析手法を手軽に試したい、ビジュアライズ（グラフ化）なども、という場合は [KH Coder](http://khcoder.net/) というフリーソフトが役に立つかもしれません（内部でやはりMeCabを使っているようです）。

- 参考: [mecabを使ってみた](https://qiita.com/hkengo/items/0c47675c86535bc85d1e)

追記(20.06.13) コメント欄で頂いたアドバイスに従って、コードを改良してみました。Ubuntu(bionic-beaver)の標準で入っているRubyのバージョンが `2.5.1p57` でしたので、tally以外を採用した形です。

```ruby
require 'mecab'

tagger = MeCab::Tagger.new
t = tagger.parse(IO.read('sample.txt'))
words = Hash.new(0)
t.split("\n").each do |l|
  w = l.split("\t")[0]
  words[w] += 1
end

words.sort_by {|a| a[1]}.each do |w,f|
  puts "%4d %s" % [f,w]
end
```
SBcloud

###Alicloud（仮想化マシン）を試すことにする
- SBcloud紹介
![sbcloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/20756fff-0c63-ba6d-0f47-ec63356f05c2.png)

- アカウントを作成する「[リンク](https://account.alibabacloud.com/register/intl_register.htm?spm=a2c45.11132017.1372584.14.19017aebV86K4d)」  
![account.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/66f19b5a-6cda-1fdb-da28-d3ce364163ad.png)
- クレジットカード有効化にする
![card.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/9f1b86df-d2ee-7899-d1c1-404b1d93f521.png)
- インスタンス作成（試すため安いものを選びました）
![linux.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/469b58ad-183b-45a8-6b24-71a6dfa74f05.png)
- ユーザー作成  
![accesskey01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/62cca1b2-2d22-5794-8114-94afc2e7616f.png)
![ram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/1fba3dee-e2a5-57fe-5d3c-e6eec8b0bff4.png)
![useradd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/064623b8-fb78-1d07-969f-cd19c37a3e91.png)
- VNC登録
![vnc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/d18529ba-4615-1dc1-e0e4-2fef1fd620d6.png)
![aliyun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/c1d0b3ff-c616-d3b4-efa9-0509f12db051.png)
- IntelliJ IDEAプラグイン設定
![plugins.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/7efe47df-107d-2d07-f28c-6e87ce8d6d61.png)
![set01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/381466e2-2807-95f7-b66c-c736c70ebd0a.png)
![set02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/345ceb6d-5e6d-2f7f-6e25-9d6984ebd187.png)
![set03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/1bc03477-3b9c-95fa-6a01-c3e96fcb703f.png)
![set04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/b45c00a1-001b-eeef-91fc-8fb6e73f53b1.png)
![set05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/67f3d81e-5d26-f482-d877-b6068799dcee.png)
VuetifyのtreeviewをIE11で表示した際のスタイル崩れについて

# 背景

以前、Vuetifyを調べていた際に、treeviewをIE11で表示した際に微妙にスタイルが崩れることに気づいた。

一応、下記のとおりVuetifyはPolyfill適用でIE11にも対応しているようなので、基本的にはIE11でも動作することになっている。
https://vuetifyjs.com/ja/getting-started/browser-support/

ただ、この現象は公式にあるIE11対応の手順を実施しても解決できなかったので、利用側でこのスタイル崩れに対応できないかと思い調べてみた。

# 現象

現象としては、ツリーの子要素を開くアイコンを押したときの灰色の丸部分が微妙にずれている感じ。

![tree.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/1a865a14-3dfe-8f33-9149-0326c5fd7604.gif)


公式サイトのツリービューをIE11で表示すると再現するので簡単に確認できる(2020/6時点)。
https://vuetifyjs.com/ja/components/treeview/


# 修正してみる

まずは、Treeviewを利用した簡単なコードを書いてみる。

```App.vue
<template>
  <VApp>
    <VTreeview :items="items"></VTreeview>
  </VApp>
</template>

<script lang="ts">
import Vue from "vue";
import { VApp, VTreeview } from "vuetify/lib";

export default Vue.extend({
  name: "App",

  components: {
    VApp,
    VTreeview,
  },

  data: () => ({
    items: [
    ... (省略) ...
    ],
  }),
});
</script>
```

実行してIE11で表示してみる。

![tree.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/3db5ae14-c088-674e-aacd-8e86a228c28c.gif)

当然、スタイル崩れはそのまま。

DOMを調べてそれっぽい要素を特定し、スタイルを適用してみる。

```App.vue
...
<style>
.v-treeview-node__root .v-icon.v-icon::after {
  top: 0;
  left: 0;
}
</style>
```

再度、IE11で確認してみる。

![tree.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/f6c9f229-b10b-311b-a0c2-e940c103720e.gif)

とりあえず、正しく動作してそう。
念のため、Chromeでも動作確認。

![tree.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643184/56aec08a-29ad-e52e-5272-c98203e9f8bf.gif)

大丈夫そう。

# さいごに

VuetifyのtreeviewをIE11で表示した際のスタイル崩れに対応してみた。
適切なやり方かは分からないが、一応、chromeなど、他のブラウザと同様の動きにできることは分かった。
ターミナルから音声ファイル再生・変換(mac, linux)



## soxコマンド(変換)

### rawをwavに変換

	sox -t raw -r 16k -e signed -b 16 -c 1 -x raw test.wav

 signed 16bit PCM ビックエンディアン 1ch 16kHz

	sox -t raw -r 16k -e signed -b 16 -c 1 raw test.wav

 signed 16bit PCM リトルエンディアン 1ch 16kHz

## playコマンド(再生)

#### wavの再生
	play -t wav test.wav 

#### rawの再生
	play -t raw -r 16k -e signed -b 16 -c 1 raw 

 - signed 16bit PCM リトルエンディアン 1ch 16kHz 


#### エンディアンを入れ替え
	play -t raw -r 16k -e signed -b 16 -c 1 -x raw 

 - signed 16bit PCM ビックエンディアン 1ch 16kHz
OS起動時のRunlevel

systemdでは、起動時のターゲットを変更する場合には、以下のコマンドを実行します。 #systemctl set-default ターゲット名.target systemdでは、従来のSysVinit/Upstartのランレベルに相当するターゲットがデフォルトで存在します。

#主なターゲットと用途 
・poweroff.target …　システムを停止します
・rescue.target …　レスキューモード（シングルユーザモード相当）にシステムを切り替えます。
・multi-user.target …　非グラフィカルなインタフェースで複数ユーザがシステムを利用できる状態に切り替えます ・graphical.target …　グラフィカルなインタフェースで複数ユーザがシステムを利用できる状態に切り替えます
・reboot.target …　システムを再起動します
作業用ブランチに最新のmasterを取り込む

某プログラミングスクールでチーム開発を行った際、コンフリクト連発したので忘れることはないと思うが、念のため！
自分が作業用ブランチで作業中に、別の開発者がmasterにmargeする。それを自分の作業用ブランチに取り込みたいということが多々ありました！




#####originを更新

```ruby:ターミナル
git fetch origin
```


#####作業用ブランチにmasterを取り込む

```ruby:ターミナル
git merge --no-ff origin/master
```


これだけ！
MySQLとPostgreSQLのテーブルコピー方法の違い

今まではPostgreSQLをよく使ってきていました。
今後、MySQLやMariaDBのほうを主に使っていきそうなので、違いを早めに把握しておきたいと思います。

よく使うテーブルコピーです。
コピーしておくと作業前後でテーブルデータの差分比較ができるのでよく使っています。
（さらに作業前後でdumpも取ってます。）

## MySQL

2行に分けて実行するようです。
`LIKE` の使い方が若干慣れないです。

```sql
-- テーブルコピー
CREATE TABLE new_table LIKE original_table;
INSERT INTO new_table SELECT * FROM original_table;
```

## PostgreSQL

1行でできます。

```sql
-- テーブルコピー
CREATE TABLE new_table AS SELECT * FROM original_table;
```

## 雑感

データベースの修正は、いつも細心の注意が必要なので胃が痛いです。。。
上記は保険です。保険。
jQuery.extendをlodashに置き換える

```js
const options = $.extend(true, {}  defaultOptions, userOptions);
```

これをlodashに置き換えたい。
deepCopyの方法だけなら検索するとすぐに出てくるが、deepCopyしつつデフォルト値を上書きしたい場合の例がぱっと見つけられなかったので自分用のメモとして残す。

# 置き換え

```js
const options = _.defaultsDeep(_.cloneDeep(userOptions), _.cloneDeep(defaultOptions))
```


# 例
**jQuery**

```js
const userOptions = {
  a: 1,
  b: {
    c: "aaa",
    d: [{
      e: 1000
    }]
  }
}

const defaultOptions = {
  a: 100,
  b: {
    d: [{
      e: -1000
    }, {
      f: -1000
    }]
  },
  g: function () {
    return 1;
  }
}

console.log($.extend(true, {}, defaultOptions, userOptions))

> {"a":1,"b":{"d":[{"e":1000},{"f":-1000}],"c":"aaa"}, "g": ƒ g()}
```

**lodash**

```js
const options = _.defaultsDeep(_.cloneDeep(userOptions), _.cloneDeep(defaultOptions))

console.log(options)

> {"a":1,"b":{"c":"aaa","d":[{"e":1000},{"f":-1000}]}, "g": ƒ g()}
```

# deepCopyしない場合
```js
const options = _.defaultsDeep(userOptions, defaultOptions)
userOptions.b = 0
console.log("user", userOptions)
> {"a":1,"b":0, "g": ƒ g()}
console.log("extended", options)
> {"a":1,"b":0, "g": ƒ g()}
```

# defaultsDeepでなくdefaultsを使った場合
```js
const options = _.defaults(_.cloneDeep(userOptions), _.cloneDeep(defaultOptions))
console.log(options)
> {"a":1,"b":{"c":"aaa","d":[{"e":1000}]}, "g": ƒ g()}
```
PYNQ-Z1 > HDMI > HDMI入力とHDMI出力を試す (内蔵のJupyter Notebookサンプル)

```txt:動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)
Vivado v2019.1 (64-bit)
```

### 概要

- base.bitを使う
- HDMIを入力し、処理をした上でHDMI出力する

### 接続

- PC HDMI出力 <=> PYNQのHDMI in
- PYNQのHDMI out <=> モニターのHDMI

### サンプルプログラム

ブラウザ接続した先の`base/video`にHDMI関連のサンプルがあることを知った。
今回は`hdmi_introduction.ipynb`をコピーして試した。

以下のようなサンプルがあった。

- そのまま転送する
- Frames per secondを計算する
    - 結果: `Frames per second:  60.0581293062524`
- OpenCVで処理 > エッジ抽出?
- Gray-scale処理
- 24bit mode
- 画像取込み
- YBCRカラーモード
Goでconfigファイルを読み込む

### 必要なパッケージをインストール

```bash:パッケージのインストール
go get gopkg.in/ini.v1
```

### config.iniファイルの例

```text:config.ini
[db_setting]
host = mysql
user_name = root
password = password
db_name = development
```

### 実装

```golang:main.go
package main

import (
	"fmt"

	"gopkg.in/ini.v1"
)

// ConfigList 設定ファイルから取得したデータを保持する構造体
type ConfigList struct {
	Host     string
	UserName string
	Password string
	DBName   string
}

// Config 設定リスト保持変数
var Config ConfigList

// コンストラクタ
func init() {
	// ファイル読み込み
	cfg, err := ini.Load("config.ini")
	if err != nil {

	}

	// 変数に設定
	Config = ConfigList{
		Host:     cfg.Section("db_setting").Key("host").String(),
		UserName: cfg.Section("db_setting").Key("user_name").String(),
		Password: cfg.Section("db_setting").Key("password").String(),
		DBName:   cfg.Section("db_setting").Key("db_name").String(),
	}
}

func main() {
	// 以下の形でアクセスできる
	fmt.Println(Config.Host)
	fmt.Println(Config.UserName)
}

```
Ubuntu 18.04 をクリーンインストールした話

# はじめに
Linux初学者の自分用のメモです
ここにある手順を踏み，不具合が生じても一切の責任を負いかねますので御了承ください

# 行ったこと
- Ubuntu 14.04 から Ubuntu 18.04にディストリビューションを変更
- 端末のタブ補完が遅い問題の解決
- GUIの乱れ，フリーズの解消

# 方法
#### Ubuntu 14.04 から Ubuntu 18.04にディストリビューションを変更
1. 以下のリンクから Ubuntu 18.04.3 LTS のISOイメージをダウンロードする
　　https://www.ubuntulinux.jp/download/ja-remix

2. DVD-RにダウンロードしたISOイメージを書き込む
[Ubuntu/ISOイメージをDVD,CDに書き込む方法・brasero - Linuxと過ごす](https://linux.just4fun.biz/?Ubuntu/ISO%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92DVD%2CCD%E3%81%AB%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95%E3%83%BBbrasero)
を参考に行った

3. バックアップをとったことを確認し，DVD-Rを入れた状態で再起動する

4. BIOSを起動させる
[パソコンメーカー別「PC起動時」に「BIOSを起動させるキー」の一覧メモ](https://freesoft.tvbok.com/tips/peripherals/bios_boot_fn-key_list.html)

5. BIOS画面で起動デバイスの優先順位をCD/DVDを1番にしてExitする

6. 以下のサイトを参考にインストールを行った
[Ubuntu 18.04 LTS Desktop をインストールする方法](https://kb.seeck.jp/archives/8056) 

#### 端末のタブ補完が遅い問題の解決
1. デフォルトの端末であるGNOME端末を起動しメニューバーの**編集**>**Preferences**を開く

2. **Sound** の **端末ベルを鳴らす** のチェックマークを外す

#### GUIの乱れ，フリーズの解消
1. ドライバのインストール
`$sudo ubuntu-drivers autoinstall`

2. 再起動

# おわりに
クリーンインストールは自分のPC環境ではこの方法で上手くいった．
端末のタブ補完が遅い問題に関してはベル1つで大きく変わった．
GUIの乱れも解消できてよかった．
TF-IDFとWord Cloudで文書中のキーワードを可視化する

word cloudのメモ
※TF-IDFは以前に投稿済み
https://qiita.com/y-s-y-s/items/c36498d40267555e116e
※Google Colaboratory上で確認（2020/06/13）

#単語辞書 (vocab) とTF-IDFを準備

```
#全ての単語 (下は例)
$ vocab
array(['a', 'able', 'at', ..., 'zebra', 'zone', 'zoo'], dtype='<U79')

#文書ごとのTF-IDFベクトル
$ TF_IDF
array([[ 0.        ,  0.        ,  0.        , ...,  0.        ,
         0.        ,  0.        ],
       [61.9792226 ,  0.        ,  3.38385083, ...,  0.        ,
         0.        ,  0.        ],
       [ 0.        ,  0.        ,  6.76770166, ...,  0.        ,
         0.        ,  0.        ],
       ...,
       [ 0.        ,  0.        ,  0.        , ...,  0.        ,
         0.        ,  0.        ],
       [ 2.75463212,  0.        ,  0.        , ...,  0.        ,
         0.        ,  0.        ],
       [ 1.37731606,  2.84060202,  0.        , ...,  0.        ,
         0.        ,  0.        ]])
```


#dic[document]=vecを作成

```
words = vocab.tolist()
vecs = TF_IDF.tolist()
temp_dic = {}
vecs_dic = []
for vec in vecs:
    for i in range(len(vec)):
        temp_dic[words[i]] = vec[i] 
    vecs_dic.append(temp_dic)
    temp_dic = {} 
```


```
$ len(vecs_dic)
(文書の数)

$ len(vecs_dic[0])
(ベクトルの次元数)
```


#可視化

```
#文書リストから89個目の文書を可視化
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import sys

wordcloud = WordCloud(background_color='white', width=1024, height=674)
wordcloud.generate_from_frequencies(vecs_dic[88])
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.figure()
plt.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431266/52e895b9-d132-8841-a9a5-d24d94e41582.png)


#Word CloudでZeroDivisionError，Segmentation faultが出たら
参考文献[2]を参考に小さな値を足してあげることで解決しました．


```
words = vocab.tolist()
vecs = TF_IDF.tolist()
temp_dic = {}
vecs_dic = []
for vec in vecs:
    for i in range(len(vec)):
        temp_dic[words[i]] = vec[i] + 1e-5 #要素が0になるのを防ぐ
    vecs_dic.append(temp_dic)
    temp_dic = {} 
```


#文書ごとに画像を作成し，保存する
保存する場合にはwordcloud.to_fileを加えて以下のように変更する．

```
i=0
for v in vecs_dic:
  i+=1
  wordcloud = WordCloud(background_color='white', width=1024, height=674)
  wordcloud.generate_from_frequencies(v)
  wordcloud.to_file([PATH] + str(i) + ".png")
```


#参考文献
[1] https://qiita.com/pma1013/items/d183b4b2504173ba037e
[2] https://github.com/amueller/word_cloud/issues/456
Go言語でログをファイルに出力する

```golang:ログ出力

func Setting(fileName string) {
    // ログファイルを開く
    logfile, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)

    // ログファイルを開けなかった場合
    if err != nil {
        log.Fatalf("file=logFile err=%s", err.Error())
    }

    // ログ出力時に日時とファイルの場所を自動的に追加で出力する
    log.SetFlags(log.Ldate | log.Ltime | log.Llongfile)

    // ログ出力と同時にファイルに書き込む
    multiLogFile := io.MultiWriter(os.Stdout, logfile)
    log.SetOutput(multiLogFile)
}

func Fatal(err error) {
    // 接頭語を設定
    log.SetPrefix("[FATAL] ")
    log.Printf("%+v\n", err)
}
```

```golang:SetFlagsに設定可能な定数
const (
  Ldate         = 1 << iota      // 日付
  Ltime                          // 時刻
  Lmicroseconds                  // 時刻（マイクロ秒）
  Llongfile                      // ディレクトリを含むファイルパス
  Lshortfile                     // ファイル名のみのファイルパス
  LUTC                           // タイムゾーンに依存しないUTC時刻
  LstdFlags     = Ldate | Ltime  // 日付 (Ldata) と時刻 (Ltime)
)
```
よく使う文字列関数(PHP, JavaScript)

普段仕事でPHPやJavaScript(以下 Js)、CSSを使用しています。
仕事していて、時々文字列操作等でよく使う機会がある関数を備忘録として残そうと思います


文字列数値化
## 数値化
文字列を数値
ifの判定や計算処理など、正確にするため、文字列を数値に変換など行うことをします

### PHP

>intval (整数型に変換する文字列 （, 基数(省略可)）);

文字列を数値化する関数です。第二引数で何進数の文字列にするか選択することも可能（デフォルトは10進数）

```
// 文字列(string)型を数値を変数に格納
$val = '300';

// 10進数で変換
var_dump(intval($val));
// 2進数で変換
var_dump(intval($val, 2)); 
// 8進数で変換
var_dump(intval($val, 8)); 
// 16進数で変換
var_dump(intval($val, 16));
```

### JS
文字列から整数値

>parseInt(整数型に変換する文字列 （, 基数(省略可))

文字列を数値化(整数値)する関数です。第二引数で何進数の文字列にするか選択することも可能。（デフォルトは10進数）
こちらを使用する場合小数点は省略されます

```
parseInt('123', 10);  // 123（10進数の整数）
parseInt('ff', 16);   // 255(16進数の整数）
parseInt('2.8', 10);  // 2（小数点以下を切り捨てる）
parseInt('123a', 10); // 123（数字以外は無視）
```


文字列から小数値
>parseFloat(変換する文字列)

文字列を数値化(小数点を含む数値)する関数です。

```
parseFloat('2.8');    // 2.8（実数）
parseFloat('123a');   // 123（数字以外は無視）
```



## 特定の文字列を含むかのチェック
文字列が探す方法とmatchなどの正規表現を使う方法があるが、ただ特定の文字列が含まれているかを調べる際、処理速度が違ってくる場合がある。
簡単な処理であれば、速く結果がでるほうがいいです

正規表現使う方法を使わない方法を記載します

### PHP

#### 正規表現　未使用
>strpos (  対象文字列 , mixed $needle [, int $offset = 0 ] )

文字列内の部分文字列が最初に現れる場所を見つける関数。
見つからない場合falseを返すので、それを利用し文字列が含まれているかを探します

```
if(strpos($subject,'bc') !== false){
  //'abcd'のなかに'bc'が含まれている場合
}

if(strpos($subject,'bc') === false){
  //'abcd'のなかに'bc'が含まれていない場合
}
```

#### 正規表現　使用

>preg_match ( 正規表現パターン , 対象文字列 [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )

※第３引数の$matchesを設定した場合、マッチングした値が配列に代入されます

※第4引数の$matchesに代入される値の入り方が指定できます


```
if(preg_match('/bc/',$subject)){
  //$subjectのなかにbcが含まれている場合
}

if(!preg_match('/bc/',$subject)){
  //$subjectのなかにbcが含まれていない場合
}
```

[PHP リファレンス]　matchesの詳細はこちら
https://www.php.net/manual/ja/function.preg-match.php
余裕ある時にでも再度まとめます


### JS
#### 正規表現　未使用

>文字列.indexOf( 検索したい文字[, 検索開始位置])
文字列の中に指定した文字の存在する位置を返す。なけれあば-1になりこれを利用します。
文字列だけでなく配列でも使用可能

```
if ( str.indexOf('hoge') != -1) {
//strにhogeを含む場合の処理

}
```

#### 正規表現　使用

>文字列.match( 検索条件(正規表現パターン) )

```
if ( str.match(/hoge/)) {
//strにhogeを含む場合の処理

}
```


私がよく使うものです。
他にも仕事しながらよく使うものあったこちら更新してきます
【Golang】標準パッケージ context

#【Golang】標準パッケージ context
Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。

```
package main

//context
/*
簡単なゴルーチンとチャネルを作ってある。

長くかかりすぎる処理の場合キャンセルして欲しい場合に使われる
WEBアプリケーションで、ユーザーからのリクエストを処理するのが長かったりの場合にキャンセルするなど。
*/

import (
	"context"
	"fmt"
	"time"
)

func longProcess(ctx context.Context, ch chan string) {
	fmt.Println("開始")
	time.Sleep(2 * time.Second)
	fmt.Println("終了")
	ch <- "実行結果"
}

func main() {
	ch := make(chan string)
	//長くかかりすぎる場合キャンセルして欲しい
	//contextを作成
	ctx := context.Background()
	//ctxを1秒間のタイムアウトをつけたもので再定義
	//longProcessより短いと、エラーで終了できる。
	ctx, cancel := context.WithTimeout(ctx, 1*time.Second)

	//もしタイムアウトしたら、定義したcancelを実行
	//ctx.Done()へ入る
	defer cancel()

	//ctxを渡す
	//1秒間で処理が終わらなかったらゴルーチンを終了する
	go longProcess(ctx, ch)

	//goroutinの直後にキャンセルすると、強制終了され実行されない
	//途中でキャンセルさせたい場合など
	//cancel()

	//名前付きループ
CTXLOOP:
	for {
		select {
		//キャンセルされたら
		//完了しなかったら、エラー出力
		case <-ctx.Done():
			fmt.Println("##########Error###########")
			fmt.Println(ctx.Err())
			//ループを抜ける
			break CTXLOOP
		case s := <-ch:
			fmt.Println(s)
			fmt.Println("success")
			break CTXLOOP
		}

	}

	//ループを抜けたら
	fmt.Println("ループ抜けた")
}

```
Common Data Service : キーで一意制約が適用されない

[Common Data Service のプライマリフィールドとキーについて](https://qiita.com/kenakamu/items/8081716dfe8ab09949b4#%E3%82%AD%E3%83%BC) で紹介したキーについて、先日一意制約がうまく動作しないという話がありました。

# 再現手順

任意のエンティティで一意制約をかけたい列に対してキーを設定します。
以下は取引先企業に対して、取引先企業名と電子メールに対して制約を書けています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/bcbe2746-bc9c-5537-1ae6-3f4b85f4c0cb.png)

次にエンティティの保存をクリックして変更を反映します。

その後データが重複するレコードを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/6b40d972-e4f8-daab-44dd-e0d6a5cf9229.png)

# 理由と対処

キーを作成すると、バックグランドジョブでインデックスが作成されますが、いくつかの理由で上記問題が発生します。

- 既に重複レコードがある
- インデックスが作成される前にレコードを作成してしまった

# 対処

まずは現在のキー作成のステータスを確認します。

1\. 画面右上のギアアイコンより「詳細設定」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/f61b08dd-1de7-19dd-ea7a-f4f805edcade.png)

2\. 「設定」の右側にある下矢印をクリックして、ソリューションを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/f56e9503-6414-1e14-8de7-5eb149fb5fad.png)

3\.「アンマネージドソリューション」のビューより「Common Data Services Default Solution」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/6a584d45-b931-7055-b85d-4b283f4aa2ca.png)

4\. エンティティを展開して、キーを確認。ここではステータスが失敗になっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/cd347aa6-edc1-37d0-7293-ef31d6134817.png)

5\. エラーをクリックして詳細を確認。重複データが既にある旨が表示されいている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/900372f0-2b84-0ea2-8104-668b241b2dc7.png)

この場合は、すでに重複しているレコードの値を変更して、気W-再作成してください。

ステータスが失敗でも完了でもない場合は、時間がかかっているだけですので、しばらく待ってからステータスを再度確認してください。

# まとめ

CDS の画面にもステータスが出るといいのですが、現在は上記手順で確認が必要です。思ったように動作しない場合は確認してみてください。
Yamlファイルを活用してDBにデータを挿入する

###  <font color='lightblue'>１）背景</font>
Yamlファイルについて、環境設定などの用途で使用されることが多いですが、アプリケーションでデフォルトデータを予めデータベースに登録したい場合なども、csvファイルと比較してyamlファイルは便利です。

私のようにポートフォリオを作成していると、サンプルデータについて、見てもらう人が意識せず、セッティングしておく必要があります。ソースには書かない、csvは可読性が低いなど、yamlが登場する場面だと思います。

###  <font color='lightblue'>２）環境</font>

| 項目              |               内容 | 
|:-----------------|:------------------:|
| OS.Catalina      |           v10.15.4 |      
| Ruby             |            v2.5.1 |  
| Ruby On Rails    |           v5.2.4.3 |       


###  <font color='lightblue'>３）内容</font>
**対応１）yamlファイルの作成**
細かな設定ができますが。ここでは省略します。後述するデータイメージを参照して下さい。

```yaml:default_user.yml
- id: 1,
  password: 111111
  name: '未登録ユーザ'
  email: 'example@test.com'
````
**対応２）yamlを読み込んで出力するサービスを作成する**
少し長いですが、以下の通りサービスを作成しました。
require('yaml')で機能拡張が必要になります。

```ruby:user_insert_service.rb
 1 class MakeDefaultDataService
 2   require('yaml')
（省略）

 3   def insert_user_data
 4     begin
 5       default_user = User.new
 6       insert_data = YAML.load_file('app/lib/yaml/default_user.yml')
 7       insert_data.each do | data |
 8         default_user.id = data["id"]
 9         default_user.password = data["password"]
10         default_user.name = data["name"]
11       end
12       default_user.save
13     rescue
14       p "（ユーザ）データ登録に失敗しました。"
15     end
16   end
```

このメソッドを実行した時、4行目の「insert_data」変数には以下のようにデータがセットされています。

```
[{"id"=>1, "password"=>111111, "name"=>"未登録ユーザ", "email"=>"example@test.com"}]
```

あとは、適宜データを加工して、データベースにセットするだけですね。
便利ですね。
以上です。
【AzureAD】テナントのライセンスについて

AzureADを見てた時に、あれ？テナントにもP2ライセンスがついてるけど、
これって何に使えるんだろう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/4827e41a-7f47-c44c-6e49-9b0d56917f15.png)


ライセンスは基本的に、ユーザーに対して割り当てるはずなんだけど、
テナントにライセンスが付与されているということは、すべてのユーザー
にP2ライセンスがついているって事？

わからないので検証してみました。
P1/P2ライセンスが割り当てられているtestuserと
割り当てられてないtestuser2を作成します


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/9215fec6-f0b8-329c-8a22-47098633c237.png)
testuser2にはintuneだけつけておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/0cd27901-277e-9078-4444-2f573f9d5579.png)

条件付きアクセスをするにはP1/p2ライセンスが必要なので
testuser2では条件付きアクセスは、本来適用されないはず



testuser2でsalesforceにアクセスすると、しっかり条件付きアクセスが適用されました？？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/7343cf9c-9153-6fe8-7c40-b9ac046eb9a1.png)


ちょっとよくわからなかったので、MSに確認してみました。
テナントにP1/P2ライセンスが付与されていると、ユーザーにも同ライセンスが付与されるみたいです。

じゃあユーザー単位でライセンスいらないじゃんって
思うんですが、基本的な考え方はユーザー毎にライセンス付与が必要らしく、
上記の場合はライセンス違反になるとのこと。


ライセンスを付与し忘れていて、ライセンス違反を知らないうちで、やってた
なんて事も考えられるんですが、現状ライセンス違反していることを検知する仕組みはないらしいです。残念。

MSのサイトにライセンスについては載っていますが、
例えばサードアプリとのSSOをする場合、条件付きアクセスもメールも利用せずにただ単純にSSOだけをする場合は、ライセンス必要なの？不要なの？
って言われても、すぐにはわからないので出来れば検知できる仕組み欲しいですね　笑


定期的なライセンスの棚卸が必要と判断しました。
以上です。
【学習メモ】Rails 1つのViewでformの文言を変更する

【課題】
new,create,updateで使うformファイルで、f.submitタグの文言を、アクションごとに違った表示にしたい＆正しくDBに格納させたい

【解決の条件】
1.create時は’登録’、update時は’変更’などとボタンの表示が変わっていること
2.'登録'、'変更'を押したら、それぞれ正しいアクションが実行されること

【解決策】
①Controllerに、f.submit用のオブジェクト（インスタンス変数）を用意し、Viewで記載する（参考の「」の2番目の回答を参照）

```ruby

# GET /books/new
  def new
    @book = Book.new
    @submit = '登録'
  end

  # GET /books/1/edit
  def edit
    @submit = '修正'
  end
```

```erb
  .actions = f.submit @submit
```

②条件分岐を利用し、Viewに直接記載する

今回は、Contollerのアクション名で条件分岐する方法を採用

```ruby:_form.html.slim
  - if controller.action_name == "new"
    = f.submit "この内容で登録する",class: "btn btn-primary"
  - elsif controller.action_name == "edit"
    = f.submit "この内容で更新する",class: "btn btn-primary"
  - else
    = link_to "編集する" ,edit_record_path(@record), class: 'btn btn-primary mr-3'
```




#参考
[rails- slimでのf.submitの文言指定](https://ja.stackoverflow.com/questions/22755/rails-slim%e3%81%a7%e3%81%aef-submit%e3%81%ae%e6%96%87%e8%a8%80%e6%8c%87%e5%ae%9a)

[ViewやヘルパーやControllerにおいて、コントローラ名やアクション名で条件分岐する方法](https://qiita.com/lasershaow/items/e7a75d3e1653c9ca39d8)
PHP 学習用　簡単なサイコロプログラムの作り方

本日から、プログラミング学習の学びの場としてqittaにて学んだことを発信していこうと思います。

本日の学び
オブジェクト志向を利用した簡単なサイコロプログラム

PHPの学習を深めるため、簡単なサイコロプログラムを作成した。

まず、以下のようにCalcクラスを作成した。

```php

<?php
class Calc{
     public $number1;
     public $number2;
     public function __construct(){
         $this->number1=rand(1,6);
         $this->number2=rand(1,6);
     }
  public function numberFirst(){
      return $this->number1;
  }   
  public function numberSecond(){
    return $this->number2;
}   
  public function sum(){
      echo $this->number1 + $this->number2;
  }
  public function sameNumber(){
      if($this->number1==$this->number2){
          echo "ゾロ目来たで";
      }else{
          echo "";
      }
  }
}
$sum=new Calc();
?>

```

上記のようにサイコロに必要なクラスを作成。
最初にクラスにて、$number1,$number2の変数を作成。
そして、

```php5
    public function __construct(){
         $this->number1=rand(1,6);
         $this->number2=rand(1,6);
     }
```

のように、
$number1,$number2をコンストラクト化を行い
rand変数を使用して1~6の数がランダムに表示出来るように設定。

そして、

```php

  public function numberFirst(){
      echo $this->number1;
  }   
  public function numberSecond(){
    echo $this->number2;
}   
  public function sum(){
      echo $this->number1 + $this->number2;
  }
  public function sameNumber(){
      if($this->number1==$this->number2){
          echo "ゾロ目来たで";
      }else{
          echo "";
      }
  }
}
```
と各関数を作成し

```php
<?php
$sum=new Calc();
?>
```
上記のようにインスタンス化を行うことでクラス外での関数の使用が可能になった。

最後に、コード上にて、

```php

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>サイコロ</title>
</head>
<body>
    <h1>サイコロ</h1>
    <p>サイコロの目は「<?php echo $sum->numberFirst();?>」「<?php echo $sum->numberSecond();?>」でした</p>
     <p>サイコロの合計値は「<?php $sum->sum();?>」でした</p>
     <p><?php $sum->sameNumber();?></p>
    <p><a href="<?php echo $_SERVER['SCRIPT_NAME'];?>">もう一度</a></p>
</body>

```
と記載してPHPを各要素に入れることで
完成する。

これで、
サイコロの目、各サイコロの合計値、
ゾロ目になった際に、知らせてくれるプログラムが完成した。

オブジェクト志向を使って初めて簡単なプログラムを作成したが、使い慣れてくればどの場所でも関数を利用できるので早くマスターして使い慣れていこうと思う。

ご指摘、フィードバックございましたら教えて頂けるとありがたいです。
【Swift・Objective-C】Base64のエンコード・デコード

#Base64とは？
base64とは、64進数を意味する言葉で、すべてのデータをアルファベット(a~z, A~z)と数字(0~9)、一部の記号(+,/)の64文字で表すエンコード方式です
ただ、データ長を揃えるためにパディングとして末尾に記号の=を使用するので、厳密にはbase64は、65文字の英数字から表現されます

#エンコード
**Swift**

```swift
let testString = "Hello, playground"

let testData = testString.data(using: .utf8)

let encodedString = testData?.base64EncodedString()

print(encodedString!)    // SGVsbG8sIHBsYXlncm91bmQ=
```

**Objective-C**

```objective_c
NSString *testString = @"Hello, playground";

NSData *testData = [testString dataUsingEncoding:NSUTF8StringEncoding];

NSString *encodedString = [testData base64EncodedStringWithOptions:0];

NSLog(@"Encoded: %@", base64Encoded);
```

#デコード
**Swift**

```swift
let restoreData = Data(base64Encoded: encodedString!)

let restoreString = String(data: restoreData!, encoding: .utf8)

print(restoreString!)    // "Hello, playground"
```

**Objective-C**

```objective_c
NSData *restoreData = [[NSData alloc]initWithBase64EncodedString:encodedString options:0];

NSString *restoreString = [[NSString alloc] initWithData:restoreData encoding:NSUTF8StringEncoding];

NSLog(@"Decoded: %@", restoreString);
```

#参考
https://riptutorial.com/ja/objective-c/example/7159/nsdata-base64%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E6%96%87%E5%AD%97%E5%88%97%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A8%E3%83%87%E3%82%B3%E3%83%BC%E3%83%89

https://qiita.com/PlanetMeron/items/2905e2d0aa7fe46a36d4
React.StrictMode配下では関数コンポーネントは二回呼ばれる（開発時のみ）

# codesandboxでrenderが二回呼び出されてしまう。

codesandboxで関数を書くと、console.logがどうしても二回出る。

調べてみると、どうも`<React.StrictMode>`の影響らしい。

[React公式のドキュメント](https://ja.reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects)

どうも関数としての結果が冪等であるかどうかをチェックするために、
Functional Componentは、２回実行しているようだ。

ただ、これは本番モードでは行われないとのこと。
iOSシミュレーターを初期化する

シミュレーター内にサンプルアプリが増えたので、一度すっきりさせたいなーと思った時に調べた。

シミュレーターアプリの
- Device
    - Erase All Content and Settingを選択

<img width="508" alt="スクリーンショット 2020-06-13 11.48.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126370/59491b73-302f-e0ce-005f-9cbcbabc96cf.png">
エンジニア系創業者向けの事業計画SaaS

【ご案内】
私の知人が立ち上げた、エンジニア創業者向けの事業計画SaaSを試してみたい方を募集します！

NotionやAirtableのようなテンプレ型SaaSが昨今急成長していますが、事業計画もテンプレでサクッと作れたら起業家がもっとプロダクトや事業開発に専念できて良いなと思い。LP是非ご覧下さい!
https://bit.ly/2UEsp1E
フォルダ内のファイル数を定期的にログ出力する

```
watch -n [監視間隔(秒)] 'cnt=`ls -1 [監視対象ディレクトリ] | wc -l`; echo `date "+%Y-%m-%d %H:%M:%S"` ファイル数:${cnt} | tee -a [出力先ファイルログ名]'
```

例：１秒間隔で「/home/hoge」ディレクトリのファイル数を「/home/fuga.log」というファイルに出力する。

```
watch -n 1 'cnt=`ls -1 /home/hoge | wc -l`; echo `date "+%Y-%m-%d %H:%M:%S"` ファイル数:${cnt} | tee -a /home/fuga.log'
```
rails のparams[:id]の正体

railsでアクションを定義するときに受け取るデータを

```ruby
params[:id]
```
と表現することが多かったのだけどいまいち意味がわかっていなかったのでメモ。
同じようなことで悩んでいる方の参考になればと思う。

<h1>前提条件</h1>

例えばこんな感じで投稿を表示する画面で投稿の詳細を確認する機能を実装したかったとする。<img width="798" alt="Myblog.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/60c1bb16-5d35-51f3-9bdf-ec24eb3273ee.png">
詳細表示するアクションはshowアクションなのでコントローラーにshowアクションを定義しつつそれに対応するビューを用意してあげると良さそう。

<h1>showアクションの設定</h1>

多くのrailsの学習サイトなどではshowアクションは以下のように表現されていることが多いんじゃないかと思う。

```ruby
  def show
    @post = Post.find(params[:id])
  end
```


 これは以下のように分解できて、それぞれ以下のような意味である。
Post…Postモデル。データベース上に保存されたPostのデータ
find…Postモデルから条件に一致するものを指定して取得する方法
params[:id]:…findで取得してくるデータの条件
params…特定のツイートのURLを開いたときなどにくっついてくるデータ
:id…ツイートに紐付いたid

つまりこれでPostモデルの中からユーザーがアクセスしようとしているpostのidに対応しているデータを拾ってきます、という意味になる。

@post…上記を外部のデータ(というかビュー)でも使えるようにインスタンス変数に代入

で、それをインスタンス変数に代入することでビューファイルに表示できるようにしているわけです。

実際にルーティングを調べてみると

```
post GET    /posts/:id(.:format)             　posts#show
```

postsコントローラーのshowアクションに対応するルーティングのパスはpost/:idとある。この:idというのがここのpostに対応しているので、showアクションで呼ぶビューには同じidのpostが表示されるようにしたい。なのでshowアクションで上記に書いたように@postを定義してビューに読み込んでいるのだ。
[Rails5]　Rspec  -ネスト時の単体テスト-

#・はじめに

Routingネスト時の単体テストについて備忘録として残します。

#1. 前提条件

**まず以下の様にpostテーブルが存在しているとします、**

```ruby
create_table "posts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.string "content", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "group_id"
    t.integer "user_id"
  end
```

**そして以下の様にgroup配下にネストされている状態です。**

```ruby
  resources :groups do
    resources :posts, only: %i[new create edit update]
  end
```

#2.結論

そこまで難しいことでは無いので結論を書きます。

上記の様な条件ならば

**期待する動作に親モデルidのパラメーターを渡してあげるだけでした**
（私はわざわざ親モデルを直接作成しようとして大ハマりしました）

```ruby
  before do
    get :new, params: { group_id: group.id }
  end
```


すごくシンプルにハッシュ形式で覚える事が出来ました。
codemagicのビルドが通らない

# 問題

```
ERROR! Did not find matching provisioning profiles for code signing!

> xcodebuild -workspace /Users/builder/clone/ios/Runner.xcworkspace -scheme Production -archivePath /Users/builder/build.xcarchive -config Release-Production archive COMPILER_INDEX_STORE_ENABLE=NO DEVELOPMENT_TEAM='' CODE_SIGN_IDENTITY='iPhone Developer'

❌  error: No profiles for 'xxxx' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'xxxx'. Automatic signing is disabled and unable to generate a profile. To enable automatic signing, pass -allowProvisioningUpdates to xcodebuild. (in target 'Runner' from project 'Runner')

```

というエラーが出て困った。
これをみて後ろの方の `No Profile ~` が問題かと思い調査、全然解決策がわからず幾星霜。


- ローカルで試す
- アカウントの設定を見直す
- codemagic.yamlを見直す
- sshでコンテナに入って直接実行してみる

...

などなど試したものの、わからず。
他のビルドが通るprojファイルの中を1行ずつ見直した。

## 解決策

> projファイルの中でproduct_bundle_identifierの設定を消す

が正しい、ビルド通る方はprojファイルをGUIじゃなくて直接見たときにproduct_bundle_identifierの文字は含まれない。codemagicのCIはこれを見てしまうっぽいので参照に失敗していた。ムズすぎ
裏スレッドで走らせる emacs ビルトインの GREP

# emacs 自力 grep を裏スレッドで走らせる
Emacs 26 でついた thread 関数を使って [bi-grep](https://qiita.com/s-fubuki/items/c14e4a8d78d8214cd721) を BG(バックグラウンド)実行するようにしてみました。

bi-grep を書いて qiita で出したとき既に thread 関数の存在は認知していて、それを使えばイイカンジにできるんじゃなどとは思っていたのですが、スレッドプロラグラムなど書いたこともなく使い方が皆目判らず保留していました。

が、とりあえず試行錯誤しながら組んでみて何となく動くものができたのでとりあえず出しておきます。

# インストール
[此処](https://gist.github.com/s-fubuki/986f9104b1cbe3cf5ab6f629ec2160ff)から source をコピーして、 `load-path` の通ったところに置いて `init.el` 等で `require` します。

# 調整
起動後すぐに制御が帰ってきてもカクカクしがちだと思います。
これは変数 `bg-slice-time` の値をうまく調整することにより気休め程度には軽減できるかもしれません。
現在のデフォルトは `0.0005` ですが、これがベストな値と言う訳でもないので各自の環境で適当に追い込んでみてください。

```emacs-lisp:init.el
(setq bg-slice-time 0.0007)
```

上記のような要領で `init.el` 等で再設定します。
この変数はサーチループを一瞬休ませる時間の設定で、この瞬間を突いてキーイン等すると表スレッドに一瞬戻りあたかも同時に動いているかのようになります。
なのでこの数値を大きくすれば表のカクカクは軽減されますが、それとは引き換えに裏の grep は遅くなります。

> `bg-slice-time` が `NIL` だと従来のシングルスレッド動作になります.

# 同時に複数起動
サーチ結果の出る前に連続して次のサーチを起動をしても正常に動くようにはしたつもりなので、その辺は人間側が気にせず使えると思います。

が、 結局裏の動作に引っ張らてキーインが重くなっていて、次の入力ができない等という非喜劇が起きたりします。

ありがちなワードでディレクトリを再帰的に掘ったりして、サーチ量やマッチ量が多ければ多いほどフリーズしたようになる時間が発生してしまいます。

マッチが多いとサーチが完了して結果をバッファにフラッシュしているときが一番重くなるので、終了したんだなということが表から察っすることができるのですが...

# その他の基本的な使い方
## 指定ファイルのワイルドカード
ワイルドカードの展開に eshell-glob-regexp を利用しているので shell 風のワイルドカード指定ができます。

|説明|表記|
|:---|:---|
| 拡張子 .el のファイルにマッチ | &lowast;.el|
| 拡張子 .doc、.txt と .org のファイルにマッチ|&lowast;&#46;(doc&brvbar;txt&brvbar;org) |
| foo ディレクトリ以下を再帰的に掘り拡張子 .el のファイルにマッチ | /foo/&lowast;&lowast;/&lowast;.el |
(注: &lowast;&lowast;&lowast; のシムリンクには非対応です)

## 大文字と小文字の区別
プレフィクス起動すると大文字小文字を別のものとしてサーチします。
デフォルトでは区別しません。

# 次回構想
これがうまくいけば叩き出しにして [mew-search-with-builtin.el](https://qiita.com/s-fubuki/items/ea748215336e7ffd48bf) にも応用したいと企んでいます。
それでは楽しんでください!

# 変更点
## Sat Jul  4 08:47:06 2020 rev.1.2
- シングルスレッドモードフラグの変更(bg-single-thread -> bg-slice-time).
- フックの追加 bg-grep-front-hook, bg-grep-after-hook.
- マッチハイライトを font-lock にする.
- 他メッセージ修正等.

# 関連プログラム
- [bi-grep](https://qiita.com/s-fubuki/items/c14e4a8d78d8214cd721)
Chrome の検証を使った JS が絡んだエラー内容の確認方法

すっごく基本的な内容だと思いますが、個人的に結構感動したので。

#背景
バックエンドはFuelPHPで、angularJSを用いてのチャットの送信がうまくできなかったので、エラーの内容を確認したかった。

#操作
1.Google Chrome でページを開き右クリックから「検証」を選択
2.上のツールバーの中から「Network」を選択
　（Elements,Console,Sources,... と並んでいます）
3.Filter のところから「All」を選択
　（All,XHR,JS,CSS,... と並んでいます）
4.検証したい操作を実行
5.エラーが発生している部分が赤文字で出てくるのでクリック
　（今回は.jsonファイルでした）

これでエラー内容が確認できるはずです。今回の場合はしっかりFuelPHPのエラーページが見られました。
Pythonで日本語の類義語を取得する

pythonで自然言語処理をする際に日本語で類義語を取得する手軽な方法があまり見つからなかったのでまとめておきます

## 事前準備

今回はNLTKのwordnetと日本語を扱うためのOpen Multilingual Wordnetの機能を利用します。

```bash
pip install nltk
python -c "import nltk;nltk.download('wordnet')"
python -c "import nltk;nltk.download('omw)"
```

## Synsetの取得

SynsetはWordnetで定義されている概念の単位です。試しに「米」という単語についてSynsetを取得して定義を見てみます。

```python
from nltk.corpus import wordnet

synsets = wordnet.synsets("米",lang='jpn')
for syn in synsets:
    print(syn,":",syn.definition())

# Synset('rice.n.01') : grains used as food either unpolished or more often polished
# Synset('united_states.n.01') : North American republic containing 50 states - 48 conterminous states in North America plus Alaska in northwest North America and the Hawaiian Islands in the Pacific Ocean; achieved independence in 1776
# Synset('meter.n.01') : the basic unit of length adopted under the Systeme International d'Unites (approximately 1.094 yards)
```

「米」に対する概念として”食べ物”、”アメリカ”、”メートル”の三つが登録されていることが確認できます。

## 類義語の取得

Synsetにはその概念に属する単語が登録されているため類義語として取得することができます。”食べ物”としての「米」の類義語を取得してみます

```python
rice_synset=synsets[0]
synonyms=rice_synset.lemma_names("jpn")
print(synonyms)
# ['イネ', 'ライス', 'おまんま', '上米', '上げ米', '供米', '八木', '御飯', '枕米', '産米', '田の実', '白米', '神米', '禾穀', '稲', '稲孫', '穀', '米', '米穀', '米飯', '粮米', '糧米', '舎利', '褻稲', '銀飯', 'ご飯', '飯', '飯米']
```
「イネ」や「ご飯」などよさげな類義語が取得できました。

## まとめ

NLTKのOpen Multilingual Wordnetを使ってpythonから簡単に類義語を検索することができました。
注意点として単語によっては複数の概念が登録されているため、意図したものと違う類義語を取得しないように適切なSynsetを選ぶ必要がありそうです。

以上

## 参考

- https://www.nltk.org/howto/wordnet.html
- http://compling.hss.ntu.edu.sg/omw/
（自分メモ）Docker コマンド

Docker コマンドの備忘録。

# コンテナ
## コンテナの確認
- docker container ls
- docker ps

## コンテナの確認（停止中も含む）
- docker container ls -a
- docker ps -a

## コンテナの停止
- docker container stop [CONTAINER ID]
- docker stop [CONTAINER ID]

## コンテナの削除
- docker container rm [CONTAINER ID]
- docker rm [CONTAINER ID]

# イメージ
## イメージの確認
- docker image ls

## イメージの削除
- docker image rm [IMAGE ID]
- docker rmi [IMAGE ID]

# ネットワーク
## ネットワークの確認
- docker network ls

## ネットワークの削除
- docker network rm [NETWORK ID]

# ボリューム
## ボリュームの確認
- docker volume ls

## ボリュームの削除
- docker volume rm [VOLUME NAME]

# 一括削除
- docker system prune

# 一括削除（ボリューム含む）
- docker system prune --volumes
mongoDBのインストール手順が変わっていた件

## mongoDBのインストール
公式ドキュメント
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/

mongodbがbrewから消えたようなので、代替手順。
【前提】
MacOS
Homebrewインストール済み

#### Tapのインストール

```
brew tap mongodb/brew
```

#### mongodb-communityのインストール

```
brew install mongodb-community
...
==> Summary
🍺  /usr/local/Cellar/mongodb-community/4.2.7: 21 files, 306.2MB, built in 4 seconds
```

ログや接続先の設定ファイル

```
/usr/local/etc/mongod.conf
```


## コマンド

#### バージョン確認

```
mongod --version
```

#### バックグラウンドでの起動と停止

起動

```
brew services start mongodb-community
```

停止

```
brew services stop mongodb-community
```

プロセスの確認

```
ps aux | grep -v grep | grep mongod
```


#### 手動で起動
停止したい場合は Ctl+C

```
mongod --config /usr/local/etc/mongod.conf
```

#### コンソール起動

```
mongo
```

データベース確認

```
...
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
```