OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaScript】Arrayの反復メソッドまとめ(forEach, filter, mapとか)

JavaScriptで使用できるArrayの反復メソッドについてまとめてみた

# 反復メソッドについて
- これらのメソッドは配列を処理する際にコールバックされる関数を引数に取る。
- メソッドが呼ばれたタイミングで配列の`length`値を一時的に保存して処理を行うため、処理中に追記された要素は処理に影響を与えない
- しかし、配列に対するその他の変更(要素の値の書き換えや削除)は、その要素が変更された後に処理中で参照する場合に操作に影響を与える。つまり、処理中に変更した要素を再度同じ処理中に参照しようとした場合、変更後の要素を参照することになる。


# 引数の説明
- `element`: 配列内の要素を一つ一つ取り出したもの
- `index`: 何回目のループかを検知するための番号
- `array`: 元の配列

# forEach
```js
const list = [0, 1, 2, 3]
list.forEach((element, index, array) => {
  console.log(element)
})

// 0, 1, 2, 3
```
- 配列の一つ一つを`item`として取り出して何かしらの処理を行うことができる


# filter
```js
const list = [0, 1, 2, 3]
const newList = list.filter((element, index, array) => {
  return (element > 1)
})

console.log(newList)

// [2, 3]
```
- 元の配列から条件に当てはまるものだけを取得して、新しい配列を作成することができる
- 条件に当てはまる要素だけで配列を作成したい場合や、要素の中の不要な要素を削除したい場合に活用できる

# map
```js
const list = [0, 1, 2, 3]
const newList = list.map((element, index, array) => {
  return element + 1
})

console.log(newList)

// [1, 2, 3, 4]
```
- 元の配列から、何かしらの処理を加えて新しい配列を作成することができる
- `filter`との違いは、elementに整形処理や値を変更する処理を加えるかどうか
- 新しく作成された配列を必ず使用することを目的としているため、処理だけを行いたい場合は、`forEach`などを使用しなければならない

# reduce, reduceRight
```js
const list = [0, 1, 2, 3]
const totalVaule = list.reduce((previousValue, currentValue, index, array) => {
  return previousValue + currentValue
})

console.log(totalValue)

// 6
```
- 配列の先頭から順番に処理を行う
- reduceRightの場合は最後から順番に処理を行う


# every
```js
const list = [0, 1, 2, 3]
const isPassed = list.every((element, index, array) => {
  return element > 1
})

console.log(isPassed)

//false
```
- 配列内の全ての要素がその条件に当てはまるかどうかを調べることができる


# some
```js
const list = [0, 1, 2, 3]
const isExist = list.some((element, index, array) => {
  return element = 3
})

console.log(isExist)

// true
```
- 条件を満たすものがあるかを判定する
- 処理中に`true`が返ってきたタイミングで処理が止まる

# find
```js
const list = [0, 1, 2, 3]
const target = list.find((element, index, array) => {
  element >= 2
})

console.log(target)

// 2
```
- 条件に当てはまる配列内の最初の要素を返す
  - 要素が見つからない場合は`undefined`を返す
- 条件に当てはまる最初の添字が必要な場合は、`findIndex()`を使用する
  - 要素が見つからない場合は`-1`を返す
- 配列内に要素が存在するかを調べる場合は`includes()`を使用する

## 参考
[Array MDN web docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array)
Vue.jsの繰り返しレンダリング(v-for)のまとめ

# v-for

繰り返し描画ができます。
indexを引数に取ることもできます。

``` html:
<div id="app">
  <ul>
    <li v-for="fruit in fruits">{{fruit}}</li>
  </ul>
  
  <ul>
      <li v-for="(fruit, index) in fruits">{{index}}{{fruit}}</li>
    </ul>
    
  <ul>
    <template v-for="fruit in fruits">
      <li>{{fruit}}</li>
      <hr>
    </template>
  </ul>
</div>

<script>
  new Vue({
    el: "#app",
    data: {
      fruits: ['りんご', 'バナナ', 'ぶどう']
    }
  })
</script>

```
## オブジェクトで指定する場合
``` html:
<div id="app">
  <ul>
    <li v-for="value in object">{{value}}</li>
  </ul>
  <ul>
    <li v-for="(value, key, index) in object">{{index}}{{key}}{{value}}</li>
  </ul>
</div>

<script>
  new Vue({
    el: "#app",
    data: {
      object: {
        firstName: '太郎',
        lastName: '田中',
        age: 20
      }
    }
  })
</script>

```

# v-forには必ずkeyをつけるようにしましょう

vueはDOMの移動を最低限に抑えるため、keyを使用しないと意図しない動きになることがあります。
key属性を外して、inputに何らか入力して、削除ボタンを押してみるとわかると思います。

```html:
<div id="app">
  <ul>
    <div v-for="fruit in fruits" :key="fruit">
      <p>{{fruit}}</p>
      <input />
    </div>
  </ul>
  <button @click="remove">先頭を削除</button>
</div>

<script>
  new Vue({
    el: "#app",
    data: {
      fruits: ['りんご', 'バナナ', 'ぶどう']
    },
    methods: {
      remove: function () {
        this.fruits.shift()
      }
    }
  })
</script>

```
ストロングパラメーター、プライベートメソッドとは

###ストロングパラメーター
ストロングパラメーターとは指定したキーを持つパラメーターのみを受け取るようにする
特定のキーしか受け取れないような仕組みを構築することができる
###プライベートメソッド
クラス外から呼び出すことのできないメソッド
ストロングパラメーターを記述したメソッドは、private以下に記載して、プライベートメソッドとして扱う
【例】プライベートメソッド

```
class PostsController < ApplicationController
   def index
     （処理） 
   end 
  
   def new
     （処理） 
   end 
  
   def create 
     （処理） 
   end 

      private 
   def private_method  # プライベートメソッド 
     params.require(`モデル名`).permit(`カラム名`)
   end 

end
```
```
def create
    Post.create(post_params)
  end

private
  def post_params
    params.require(:post).permit(:title, :text, :image)
  end
```
みたいな感じで記述する。privateのpost_paramsはcreateのpost_paramsに代入される
####1.Classの外部から呼ばれたら困るメソッドを隔離
メソッドの中には、Classの外部から呼び出されてしまうとエラーを起こすメソッドも存在し、そのような事態を事前に防ぐことができる
####2.可読性
classの外部から呼び出されるメソッドを探すときに、private以下の部分は目を通さなくて良くなり、繰り返し使用するメソッドもprivate以下に集約できますので、コードをシンプルにできる
Vue.jsの条件付きレンダリング(v-ifなど)まとめ

## v-if

条件を満たしている場合、描画されます。

``` html
<div id="app">
  <h1 v-if="visible">Text</h1>
  
  <!--templateタグ指定でもOK-->
  <template v-if="visible">
    <h1>Text1</h1>
    <h1>Text2</h1>
    <h1>Text3</h1>
  </template>
  
  <button @click="visible = !visible">
    {{ visible ? "表示してます" : "非表示です"}}
  </button>
</div>

<script>
  new Vue({
    el: "#app",
    data: {
      visible: true
    }
  })
</script>
```

## v-show

条件を満たしていない場合、**display:noneをスタイルに追加します。**
そのためtemplateタグでは使用できません。ですが初期描画は遅いですが、v-ifと比べて処理が発生するときのコストが低いです。

とても頻繁に、切り替える場合はv-showを使用しましょう。

``` html
<div id="app">
  <h1 v-show="visible">Text</h1>
  <button @click="visible = !visible">
    {{ visible ? "表示してます" : "非表示です"}}
  </button>
</div>

<script>
  new Vue({
    el: "#app",
    data: {
      visible: true
    }
  })
</script>
```

## v-else

条件を満たしていない場合、描画されます。
v-ifの直後でないと使用できません。

``` html
<div id="app">
  <p v-if="visible">OK!</p>
  <p v-else="visible">Not OK...</p>
  <button @click="visible = !visible">
    反転
  </button>
</div>

<script>
  new Vue({
    el: "#app",
    data: {
      visible: true
    }
  })
</script>
```

## v-else-if

ちょっと複雑な条件式を指定できます。
v-ifの直下でないと使用できません。

``` html
<div id="app">
  <p v-if="count == 0">カウント0</p>
  <p v-else-if="count >= 1 && count <= 5">カウント1以上かつ5以下</p>
  <p v-else>カウント6以上</p>
  <button @click="count += 1">
    +1
  </button>
</div>

<script>
  new Vue({
    el: "#app",
    data: {
      count: 0
    }
  })
</script>
```
Windowsでnpm startしたときに「内部コマンドまたは外部コマンド～」と出てくる現象と戦う

# 1. 問題発生

[Webpackをglobalにインストールすることが非推奨](https://webpack.js.org/guides/shimming/)であることを知り、

``` cmd
> npm remove -g webpack webpack-cli
```

としたところ、既存のプロジェクトにて

``` cmd
> npm run build
'webpack' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

と出てしまった。
package.json の scripts はこんな感じ

``` package.json
"scripts": {
	"build": "webpack --mode development",
}
```


ひとまずこれは再度グローバルにインストールすることで回避していたが、
ある日、Reactの勉強を始めようとしたところ、

``` cmd
> npx create-react-app pwa-sample
> cd pwa-sample
> yarn start
'react-scripts' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

と、こちらもNG。
どういうことなの？

# 2. 試したこと

1. node_modules と packege-lock.json を削除して `npm install` ・・・ NG
2. コマンドプロンプトやPowerShellを管理者で起動して ・・・ NG
3. node_modules/.bin の中に webpack.cmd（react-scripts.cmd） が存在するか確認 ・・・ 存在する
4. npx コマンドでstart ・・・ OK
5. package.json 内の webpack や react-scripts コマンドのパス書き換え ・・・ OK

つまり、 **node_modules/.bin のパスを理解していない** ということか？
この時点での解決策は以下になるが、これではMacやLinuxと共通化ができずに面倒くさいしイマイチ美しくない。

``` package.json
"scripts": {
	"build": "node_modules\\.bin\\webpack.cmd --mode development"   // webpackの場合
	"start": "node_modules\\.bin\\react-scripts.cmd start"   // react-scriptの場合
}
```

通常、私はプロジェクト用のディレクトリは `D:\projects` というパスに設置しているが、
ちょっと気分を変えて `C:\Users\hogehoge\Documents（マイドキュメント）` にて作業してみた。

 ``` cmd
>yarn start
yarn run v1.22.0
$ react-scripts start
Starting the development server...
Compiled successfully!
```

あれ？通った？

# 3.  原因判明

CドライブとDドライブで何が違うんだろう・・・とパーミッションやnpmグローバルディレクトリを覗いていたがよくわからない。
`C:\Users\hogehoge\AppData\Roaming\npm-cache\_logs` も見るがパスは通っているように見える。
(PATHの行に プロジェクトディレクトリ/node_modules/.bin が含まれている)

後は何が問題なのだろうか、ドライブ間で何か特別な操作をしただろうか？

1つだけあった
それは以前に **大文字小文字を区別する設定をしていた** ことだった。

``` 
# 管理者で実行
> fsutil.exe file queryCaseSensitiveInfo D:\projects
ディレクトリ D:\projects の大文字と小文字を区別する属性が有効になっています。
```

試しにこれを解除して再チャレンジ

``` cmd
# 管理者で実行
> fsutil.exe file SetCaseSensitiveInfo D:\project disable
ディレクトリ D:\project の大文字と小文字を区別する属性が無効になっています。

# 通常ユーザーで実行
> yarn start
yarn run v1.22.0
$ react-scripts start
Starting the development server...
Compiled successfully!
```

問題なく通りました。
もちろんwebpackもOK。

どうやら、webpack や react-scripts コマンドは **webpack.cmd や react-scripts.cmd** ではなく、**webpack.CMD や react-scripts.CMD** を探していた、ということらしい。

安易にSetCaseSensitiveInfoを有効にしないように注意しましょう。
~~ただ、これが有効になっていないと困るケースもあるので悩ましい・・・~~
~~状況により中段に書いた `node_modules\\.bin\\webpack.cmd` と併用することになりそう。~~

コメントをいただき解決しました！

# SetCaseSensitiveInfo を有効にしたままコマンドを通す

`.cmd` が実行できるように環境変数に追加することで回避できました。

1. コントロールパネルのシステムを開く
2. システムの詳細設定
3. 環境変数
4. 下段のPATHEXTの編集で末尾に `;.cmd` を追記
5. 保存してコマンドプロンプトを開き直す

``` cmd
# 通常ユーザーで実行
> yarn start
yarn run v1.22.0
$ react-scripts start
Starting the development server...
Compiled successfully!
```
Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; WP_MatchesMapRegex has a deprecated constructor in /

⚠️階層ファイルがめちゃくちゃなのは、スルーしてくださいw

#WordPressの自作テーマの作り方の講座を見ていて急に出て来たエラー

`Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; WP_MatchesMapRegex has a deprecated constructor in /Users/Sites/bootstrap_wp_udemy/B2W Final Course Files/B - Download WordPress/b2w/wp-includes/class-wp.php on line 633
Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; Translation_Entry has a deprecated constructor in /Users/Sites/bootstrap_wp_udemy/B2W Final Course Files/B - Download WordPress/b2w/wp-includes/pomo/entry.php on line 14
Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; POMO_Reader has a deprecated constructor in /Users/Sites/bootstrap_wp_udemy/B2W Final Course Files/B - Download WordPress/b2w/wp-includes/pomo/streams.php on line 12`

##私が使っていたバージョン
PHP 7.3.1
WP version  4.0.1

WPのバージョンが低いとこのようなことが起きるよう。

参照URL
https://www.php.net/manual/ja/migration70.deprecated.php

##解決方法
1. バックアップ（直そうとしているファイルのコピー）をとる。理由はわからなくなって元に戻れないと怖いから。
2. wp-config.phpとwp-contentフォルダを削除
3. 最新のWPのバージョンをとる。私が新しくWPのバージョンをとって来たのは、5.3.2。
4. 新しくとってきたwp-config.phpと新しいwp-contentフォルダを差し替える

参照URL
https://kotori-blog.com/wordpress/upgrade/

これでうまく行きました。
差し替えは怖かったですが、バックアップをとっておいたので安心して実行できました。
めでたし、めでたし。
Vue.jsの基本的なディレクティブまとめ

# v-html

データをhtmlとして、そのまま出力できる。
クロスサイトスクリプティングに気をつける。
ユーザーから入力されたものを表示しないようにすること。

# v-once

一度だけ描画する。
一度描画されたあとは、あとで内容が書き換わることがないです。

# v-bind

属性を指定して、データを出力させることができる。

``` html
<a v-bind:href="url">Google</a>

<!-- このように省略して書くことも可能 -->
<a :href="url">Google</a>

<script>
new Vue({
  el: "#app"
  data: {
    url: 'https://google.com'
  }
})
</script>

```
属性に関しても、Vueから指定することが可能

``` html
<a :[attribute]="google">リンク</a>

<!-- オブジェクト形式で書くことも可能 -->
<a v-bind="{ href: yahoo, id: number }">リンク</a>

<!-- 上を省略したもの -->
<a v-bind="yahooObject">リンク</a>

<script>
new Vue({
  el: "#app"
  data: {
    google: 'https://google.com'
    yahoo: 'https://yahoo.co.jp'
    number: 1
    attribute: 'href'
    yahooObject: {
      href: 'https://yahoo.co.jp',
      id: 1
    }
  }
})
</script>

```

# v-on

## イベントの検知

DOMの提供してるイベントを検知できる。
v-onで使用できるイベントのリストは以下のURLを参考にしましょう。
[イベントリファレンス \| MDN](https://developer.mozilla.org/ja/docs/Web/Events)

``` html: 
<p v-on:click="countUp">{{ number }}回クリック</p>

<!-- 省略するときは@をつける --->
<p @click="countUp">{{ number }}回クリック</p>

<!-- イベントタイプを動的に指定してもいけます。--->
<p @[event]="countUp">{{ number }}回クリック</p>

<script>
new Vue({
  el: "#app"
  data: {
      number: 0,
      event: 'click'
    }
  },
  methods: {
    countUp: function() {
      this.number += 1
    }
  }
})
</script>
``` 

## イベント修飾子

イベントについて、よく使うものに関しては、デフォルトでVueが用意してくれています。

``` html: 
<!-- preventによって、タグ本来の機能を停止 -->
<a v-on:click.prevent href="https://google">このリンクは発動しません。</a>
```


## キー修飾子

キーアクションにおいても、よく使うものに関しては、デフォルトでVueが用意してくれています。

``` html:
<!-- エンターキー押下時に、myFuncが呼ばれる -->
<input type="text" v-on:keyup.enter="myFunc" />
```

# v-model

双方向データバインディングが行なえます。
リアルタイムで、データモデルが変更された際に変更させることができます。

```html:
<div id="app">
  <input type="text" v-model="message" />
  <h1>{{ message }}</h1>
</div>

<script>
new Vue({
  el: "#app",
  data: {
    message: 'Hello World!'
  }
})
</script>

```
Linux 【 nkf, iconv 】 文字＆改行コード変換


## nkf オプション
入力文字コードを自動認識するため、入力ファイルが下記文字コードの場合、入力文字コードの指定は不要。

- JISコード(ISO-2022-JP)
- Shift-JIS
- 日本語EUC
- UTF-8
- UTF-16

```shell
# 【入力ファイル】 の文字コードと改行コードの判別結果を出力する
nkf --guess 【入力ファイル】

# 【入力ファイル】 をUTF-8文字コードで出力する
nkf -w 【入力ファイル】

# 【入力ファイル】 をUNIX改行コード(LF)で出力する
nkf -Lu 【入力ファイル】

# 【入力ファイル】 をUTF-8文字コードおよびUNIX改行コード(LF)へ変換して上書きする
nkf -wLu --overwrite 【入力ファイル】
```

## iconv オプション
```shell
# 【入力ファイル】 の 【入力文字コード】 を 【出力文字コード】 へ変換して 【出力ファイル】 へ出力する
iconv -f 【入力文字コード】 -t 【出力文字コード】 【入力ファイル】 -o 【出力ファイル】
iconv --from-code 【入力文字コード】 --to-code 【出力文字コード】 【入力ファイル】 --output 【出力ファイル】

# 文字コード一覧を表示する（文字コードを指定する際に利用）
iconv -l
iconv --list
```

入力ファイルの文字コードが不明は場合は`file`コマンドで確認。

```shell
# Shift-JIS は Non-ISO extended-ASCII text と表示される
$ file test.txt
test.txt: Non-ISO extended-ASCII text, with CRLF line terminators
```

iconv には改行コード変換オプションがないため、Windows改行コード(CR+LF)からUNIX改行コード(LF)へ変換する場合は、`tr`コマンドにてCR+LF `\r\n` から `\r` を削除し、改行コードをLF `\n` へ変換。

```shell
# 【入力ファイル】 の 【入力文字コード】 を 【出力文字コード】 に、
# 改行コードをUNIX改行コード(LF)へ変換して 【出力ファイル】 へ出力する
iconv -f 【入力文字コード】 -t 【出力文字コード】 【入力ファイル】 | tr -d '\r' > 【出力ファイル】
```
本日の精進：全探索


[こちらの記事(by e869120氏)](https://qiita.com/e869120/items/eb50fdaece12be418faa)を参考に精進してみました．

[AtCoder Beginner Contest 106 B - 105](https://atcoder.jp/contests/abc106/tasks/abc106_b)
全探索その１．N以下の整数のうち，約数をちょうど8コ持つ奇数の数を求めるという問題．
Nの範囲が1-200なので全探索でOK．i=1~Nについて，j=1~iで愚直に割っていけばよい．

ACコード:

```AC.cpp
#include <iostream>
#include <string>
#include <algorithm> 
using namespace std;
 
int main(void){
  int N;
  cin >> N;
  int ans = 0;
  int count;
  for (int i = 1; i <= N; i+=2){
    count = 0;
    for (int j = 1; j <= i; j++){
      if (i%j==0) count++;
    }
    if (count == 8) ans++;
  }
  
  cout << ans << "\n";
  return 0;
}
```



[AtCoder Beginner Contest 122 B - ATCoder](https://atcoder.jp/contests/abc122/tasks/abc122_b)
全探索その２．文字列Sの部分文字列を全列挙し，条件を満たしているか確認すればよい．
"部分文字列"という制約上，全列挙が意外と面倒．部分文字列の左端を固定し，どこまで文字を取り去るかをforループで全列挙する，というやり方でAC．文字列処理はpythonが優秀．
あと，n=1のときループが回らないので，例外処理を挟んだ．あんまりよくない．

ACコード:

```AC.py
S = input()
n = len(S)
ans = 0
flag = True
 
for i in range(n):
  for j in range(i):
    for k in range(i,n+1):
      S_part = S[j:k]
      for s in S_part:
        if not s in "ACGT":
          flag = False
      if flag:
        ans = max(ans,len(S_part))
      flag = True
 
if n == 1:
  if S[0] in "ACGT": ans = 1
print(ans)
```



[AtCoder Beginner Contest 095 C - Half and Half](https://atcoder.jp/contests/abc095/tasks/arc096_a)
全探索の中でも，工夫が必要なタイプ．最大N=10^5だが，愚直に行くと3重ループ必要でTLE，ちょっと式変形しても2重ループでTLE．
結局，AピザとBピザのみで用意した場合の金額からスタートし，ABピザで代替していって最小値を求める方法でAC(有り得るABピザの枚数だけループを回せばよくて，最大でも2*10^5)．
ABピザで代替していったときの枚数計算が微妙に面倒で何回かWAした．こういった部分の細やかさが欲しい．
というか，茶色下位diffくらいあるのかと思ったら灰色diff．

ACコード:

```AC.cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main(void){
  int a,b,c,x,y;
  cin >> a >> b >> c >> x >> y;
  ll value; ll ans_first = a*x + b*y;
  ll ans = 1000000007;
  int x_now; int y_now;
  for (ll i=0; i<=max(x,y)*2; i+=2){
    if (x-i/2 < 0) x_now = x;
    else x_now = i/2;
    if (y-i/2 < 0) y_now = y;
    else y_now = i/2;
    value = ans_first + c*i - a*x_now - b*y_now;
    if (value < ans) ans = value;
  }
  cout << ans << "\n";
  return 0;
}
```
PC使いながらスマートに仕事の電話を受けたい(内容薄め）

# スマホなのにスマートじゃない
電話中はスマホで片手が埋まるものだから、紙のメモをとりながら応対するのが精いっぱいで
「ページのここを今ちょっと修正して見せてくれる？」
などと言われた際はスマホを机に置きまたは肩に挟み両手を開けて作業をする必要が出てくる。

スマホ時代なのにこれはスマートではない、、と日ごろから思っていた。

普段はヘッドホンを付けて音楽・ラジコを聴きながら仕事をしているのだが
電話がかかってくるとヘッドホンを外して対応せねばならないのもいまいち良くない。

# なにかスマートな電話対応ができないものか
手ぶらフォンを使うことも一時考えたが、、あまり使いやすいイメージがなかった。
一度試したことがあったと思ったが、お客様に「聞き取りづらい」と言われたと思う。

# 実現したいこと
1. 話しながらコードを打ってその場で確認してもらうくらいの電話中の自由度
2. 音質悪い、遅延あるでは使い物にならないので、音質がいいこと
3. 音楽を流していてもスムーズにミュートして電話の応対ができること


# 解決編
作業中のスマホでの電話応対は長年の課題だったのだが、最近簡潔な解決策を見つけたので記す。
**ヘッドセットを買いましょう。**

ただのヘッドセットではなく、**マルチポイント対応**の**bluetoothヘッドセット**が望ましい。

私が買ったソニーのヘッドホンサイトではこのような図で示されているやり方。
![コメント 2020-02-27 163629.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25349/a43c19c3-98e5-c8c3-4196-60c62fec4063.png)
これを片側ウォークマンではなくPCでやるだけ。
具体的には接続プロファイルを以下のように登録し分け、接続を同時に行う。
PC：A2DP
スマホ：HFPまたはHSP


これで繋ぐと、PCで音楽聞いててもスマホで電話受けると自動でミュートしてくれる。
ハンズフリー通話もとても快適。確認したが音質にも違和感なしとのこと。

ヘッドセットを買ったら長年の悩みが解決してしまったという単純な話でした。
あと、WH-1000XM3はとても良いものだった。

**ただし、この構成だとヘッドホンのマイク機能がスマホに取られるのでPC側では別途マイクが必要になる点は注意。**
chatworkやskypeなど、PCソフト上で使う用のマイクは別途必要です。（A2DP接続だけじゃbluetoothヘッドセットのマイクがPCに認識されないと思うので）
私は打合せ用に設置してあるWebカメラ内蔵マイクを利用することで解決しています。

→20250126追記
この問題はXM5にしたら解決した。マルチポイント対応が進化して、PCでもスマホでも両方同時に接続しつつマイクを自動で使い分けできる模様。たぶん同時は無理だろうけど、えらいものだ。


# 試行錯誤編
以下は迷走中にボンヤリと考えていた解決方法です。下書きに残っていて、消すのももったいないので書き残しておきます。

## PCから電話をやり取りできれば、スマホに触らなくていいのでは？

### chatworkやskypeなどをよく電話をかけてくるお客様に使ってもらう
無理。現実的じゃない。

### skypeで電話を受ける、かける
日本では着信用の電話番号発行してくれないんだとさ。

### 050plusというのがあるらしい、windows版の電話かけうけができそうだ
ただ遅延があったり通話品質が悪いそうで。

### 汎用SIPソフトと組み合わせて格安050サービスで電話をWindows上に置いたらいいのでは
電話会社と契約して試した後やっぱ無理でしたとなったら面倒でずっと棚上げしていた。
Qiita的にはこれを試した記事を書くべきではある。
【Laravel】環境構築から各機能の実装

# 目次
環境構築
ログイン機能
SNS API連携
ブログ投稿機能
WYSIWYGエディタ
問合せ機能
ソーシャルログイン
Xserverへアップロード

## Laravel 環境構築
https://qiita.com/sano1202/items/6021856b70e4f8d3dc3d

## Laravel ログイン機能
https://php-junkie.net/framework/laravel/login/
https://readouble.com/laravel/5.6/ja/authentication.html

### 「Command "make:auth" is not defined.」が出たら
https://qiita.com/daisu_yamazaki/items/a914a16ca1640334d7a5

## Laravel SNS API連携
https://mseeeen.msen.jp/laravel-socialite/

## Laravel ブログ投稿機能
https://manablog.org/laravel_bulletin_board/
https://blog.hiroyuki90.com/articles/laravel-bbs/

## Laravel WYSIWYGエディタ
### Trix
http://www.thirtyfive.info/entry/2018/07/16/TrixというWYSIWYGエディタを試す。

### TinyMCE
https://agohack.com/how-to-use-tinymce-5/
https://qiita.com/nissuk/items/e31bdfa858d6c5c018c2
https://oxynotes.com/?p=11177

## Laravel 問合せ機能
https://www.webopixel.net/php/1316.html

## Laravel ソーシャルログイン
### ソーシャルログイン とは
https://socialplus.jp/tour/

### ソーシャルログイン実装方法
https://qiita.com/zaburo/items/26e94bce0068f479a8e8

#### LINE編
https://blog.ef-4.co.jp/laravelアプリケーションにlineログインを実装しよう！/

#### SNSのクライアントIDの取得方法
http://ablogcms.io/hands-on/snsLogin.html

## Xserverへアップロード
https://qiita.com/huhe/items/6c3c35005bb8c010614e


---
こちらもどうぞ
【WordPress】環境構築から各機能の実装
https://qiita.com/SyogoSuganoya/items/0143ea6f5e902e147f5c
[android] AVDがpermission deniedで使えない時

# 開発環境
linux

# やり方
qemu-kvmをいれて、kvmグループにオレを追加して、/dev/kvmの所有権をオレにする

```
sudo chmod 777 -R /dev/kvm
sudo apt install qemu-kvm
sudo adduser yourname kvm
sudo chown yourname /dev/kvm
```

## その２
- project structure -> select latest ANDROID API in Project SDK
pug(2.0.0-beta11)でHTMLをエスケープさせずに出力する方法

pugでHTMLを記述した変数をエスケープさせずに展開させようとした際、

```
!{ 変数名 }
```

といった形で展開できると色んな記事で書いてあったのですが、私の環境では以下のようなエラーが出てしまいました。


`/src/views/XXXX.pug nn| ~~~~ !{ 変数名 } ----------------------------^ nn| unexpected text "!{ 変数名"`

結果的に以下の記述でHTMLをエスケープさせずにそのまま出力できました。

```
!= 変数名
```

どなたかの救いになれたら幸いです。
チャットボットを作ろう（１）～まずは調査から～

# チャットボットを作ろう。
今更感も少しあるが。まずは調査から。
基本的にはWebでそれぞれのDevelop登録後、
APIキーを取得して、それを使ってWebメッセージを送る方式になるはず。

以下、ザックリした予定と項目
---

- Web chat bot
どうやらAzureで出来るらしい。他にもあるはずだからそこは見てみる。

- LINE bot
これは前やったことあるから、引っ掛からない気がする。
忘れてる可能性はある。

- Facebook Messanger bot
こっちは未知数。必要なのかなぁ

- Discord bot
これは経験済なので、引っ掛からずに作れそう。

なんでそんな話になったの？
---
いやー、こういうのってFAQとかに使えそうじゃん？
後で返答をカスタムした上で、同じデータソースから、全チャットボットに適用出来たら、
それはとても気楽で助かるんじゃないかなって思ったので。

これを[有料でやってる会社](https://first-contact.jp/)もあるし、サンプルとしては面白そうな気はする。

どこまで出来んの？
---
それは色々と個人の裁量によりそう。。。
手元で可能な範囲はやるし説明もする予定だけど。

以上

# 参考
- ChatBot作成をしてくれる会社。何かググったら出てきた。
  - https://first-contact.jp/
- LINE BOTの作り方を世界一わかりやすく解説（１）【アカウント準備編】
  - https://qiita.com/yoshizaki_kkgk/items/bd4277d3943200beab26
- LINE BOTの作り方
  - https://first-contact.jp/linebot
- Facebookページのメッセンジャーボット
  - https://kekaku.addisteria.com/wp/20180601192333
- microsoft/BotFramework-WebChat
  - https://github.com/microsoft/BotFramework-WebChat
- ボットを Web チャットに接続する
  - https://docs.microsoft.com/ja-jp/azure/bot-service/bot-service-channel-connect-webchat
- Azure BotとLINEでコードレスチャットボットを作ってみた
  - https://cloud.nissho-ele.co.jp/blog/chatbot_azure_line/
rails6 ActionTextの関連付けされない画像データをバックグラウンド削除してみた

# はじめに
Rails6の新機能の１つのActionText(リッチテキストコンテンツと編集をかんたんに導入できる)の関連付けされてない画像データをsidekiqでバックグラウンド削除しようという内容です。
削除jobを実行するPostモデル(ポスト)と実行しないArticleモデル(記事)を使って比較していきます。
## WEBページ
https://hks-portfolio.work/
## GitHub
https://github.com/hironakazuki/aws_on_rails6/
# 環境
- Ruby 2.6.3
- Rails 6.0.2
- gem aws-sdk-s3 1.60.2

# 問題点
こちらがActionTextを実装したPostモデルとArticleモデルのER図になります。
![er-diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181033/886016f2-bfa9-772c-b05a-1f87c5c5dd19.png)

active_storage_blobsにアップロードした画像が保存され、投稿を完了（save)した時にactive_storage_attachmentsにaction_text_rich_textsとの関連情報が保存されます。

しかし、画像をアップロードした時点で active_storage_blobs に新規レコードが作成されてしまい関連付けされなかった場合にも残り続けてしまいます。

以下sidekiqでjobを実行していないArticleモデルでのgifです。
↓一覧画面の上部にactive_storage_attachments, active_storage_blobsを表示しています
![ezgif.com-video-to-gif-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181033/bce641ac-ba96-594d-acee-b5adcbd30ec7.gif)

画像添付をやめたのにActiveStorage::Blobの数： 2に増えてしまっています。
# 本題
関連付けされなかったデータを削除するjobを作成します。

```ruby:app/jobs/delete_unreferenced_blob_job.rb
class DeleteUnreferencedBlobJob < ApplicationJob
  sidekiq_options queue: :default, retry: 3
  require 'aws-sdk-s3' 

  def perform(*args)
    # 全Blobのidを取得
    blob_ids = ActiveStorage::Blob.pluck(:id)
    # 関連付けされているBlobの取得
    _blob_ids = ActiveStorage::Attachment.pluck(:blob_id).uniq
    # 関連付けされていないBlobの割り出し
    unreferenced_blob_ids = blob_ids - _blob_ids
    # 関連付けされていないBlobの画像ファイルを削除
    if Rails.env.production?
      s3 = Aws::S3::Resource.new(
        region: 'ap-northeast-1',
        credentials: Aws::Credentials.new(
          Rails.application.credentials.dig(:aws, :access_key_id),  # S3用アクセスキー
          Rails.application.credentials.dig(:aws, :secret_access_key)  # S3用シークレットアクセスキー
        )
      )
      bucket = s3.bucket('aws-on-rails6')
      unreferenced_blob_ids.each do |id|
        s3_file_key = ActiveStorage::Blob.find(id).key
        bucket.object(s3_file_key).delete
        bucket.objects({prefix: "variants/#{s3_file_key}"}).batch_delete!
      end
    end
    # 関連付けされていないBlobの削除
    ActiveStorage::Blob.where(id: unreferenced_blob_ids).delete_all
  end
end
```
本番環境のみs3の画像ファイルも削除しています。

これをPostモデルのsave, update, delete時に実行します。

```ruby:posts_controller.rb
def create
    if @post.save
            DeleteUnreferencedBlobJob.perform_later
                    .
                    .
def update                                   
    if @post.update
            DeleteUnreferencedBlobJob.perform_later
                    .
                    .
def destroy
    DeleteUndreferencedBlobJob.perform_later if @post.destroy
                    .
                    .

```

Postモデルで先程と同じことをしてみます。
![ezgif.com-video-to-gif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181033/7c3544cd-87d9-e8c1-b47c-7cb19083e1a7.gif)

ActiveStorage::Blobの数： 1となり削除されているのが確認できました！

# 注意点
この実装だとユーザーAが画像添付ポストを作成時、ユーザーBが別のポストをsaveやupdateした場合でもユーザーAのsave前の関連付けされていない画像データが消えてしまうので、複数ユーザーが利用するサービスではメンテナンス時などに実行するのが望ましいでしょう。
ヘルパーメソッドとは、また使用する利点は

###ヘルパーメソッドとは
主にviewでHTMLタグを出現させたりテキストを加工するために予めメソッドが用意される。HTMLやRubyの記述がセットになった、ビューファイルで使用できるメソッド
|:-----|:-----|
| ヘルパーメソッド | 使用用途 |
| form_for | 投稿ページなどにおけるフォームの実装 |
| link_to | リンクの実装 |
| simple_format | 投稿した文章を自動で見やすく整形する |
などがある
フォームの実装例

```
<%= form_for('モデルクラスのインスタンス') do |f| %>
    フォームの中身
<% end %>
```
```
<%= form_for(@post) do |f| %>
  <%= f.text_field :text %>
  <%= f.submit %>
<% end %>
```
```
<%= link_to 'リンクに表示する文字', 'リンク先のURL' %>
```
```
<%= link_to '新規投稿', '/posts/new' %>
```
みたいに使える
###ヘルパーメソッドを使用する利点
1. 複雑なアプリケーションにおいては、ヘルパーメソッドを使用するとコードがシンプルになる
2. 特にフォームにおいては、ヘルパーメソッドを使用しないとセキュリティ上の問題が発生する
stdout/stderr のリダイレクトとパイプの整理

ほぼこちらを自分用に整理したものです。ストック/お気に入りは元記事へどうぞ
[bash: 標準出力、標準エラー出力をファイル、画面それぞれに出力する方法 - Qiita](https://qiita.com/laikuaut/items/e1cc312ffc7ec2c872fc)


```print.sh
# stdout へ Standard Out , stderr へ Standard Error という文字列を出力する
echo "Standard Out" >&1
echo "Standard Error" >&2
```

# リダイレクト先を stdout/stderr のどっちにするか

### stdout へリダイレクト
`print.sh >&1`

### stderr へリダイレクト
`print.sh >&2`


# リダイレクト元を stdout/stderr どっちから取るか

### stdout からリダイレクト
`print.sh > log`
(`print.sh 1> log` も同じ)

### stderr からリダイレクト
`print.sh 2> log`

### stdout/stderr ともにリダイレクト
`print.sh &> log`

### stdout, stderr をそれぞれ別個にリダイレクト
`print.sh 1> stdout.log 2> stderr.log`


# パイプ

### stdout をパイプ
`print.sh | cat > log`

### stderr をパイプ
やる方法はあるけどめんどくさいので略

### stdout, stderr 両方をパイプ
`print.sh 2>&1 | cat > log` (まず `2>&1` で stderr を stdout にリダイレクトしてからパイプにつなぐ)
(`print.sh |& cat > log` も同じ。**`&|` ではない** ことに注意)
dependent: :destroyをつけていても削除できなかった原因

長時間調べたが解決方法が見つからないという状態が続きました。
私のミスだったので、同じような状態の人に私の経験を伝えれればと思い書きます。


##内容
紐付けしたオブジェクトを削除するために、`dependent: :destroy`をつけても、削除できない時に気をつけて欲しいことを書きます。


##問題点

ある特定のUserのみ削除できない

##モデルの関係性
`User`と`Cart`が親子関係で、
`Cart`と`Product`が`Cart_products`と 1対多 です。
`Users ー Carts → Cart_products ← Products`

```rb
class User < ApplicationRecord
  has_one :cart, dependent: :destroy
end

class Cart < ApplicationRecord
  belongs_to :user
  has_many :cart_products, dependent: :destroy
  has_many :products, through: :cart_products
end

class Product < ApplicationRecord
  has_many :cart_products, dependent: :destroy
end

class CartProduct < ApplicationRecord
  belongs_to :cart
  belongs_to :product
end
```

##行っていたこと
関連付けられたオブジェクトもdestroy削除できるように
`has_many`,`has_one`に`dependent: :destroy`をつけていた。

##エラー文
```
Cannot delete or update a parent row: a foreign key constraint fails (`app_name_development`.`cart_products`, CONSTRAINT `fk_rails_a4f3e327f3` FOREIGN KEY (`cart_id`) REFERENCES `carts` (`id`))
```

##原因
`User has_one Cart` で`User` には`Cart`がは1つのみ紐づくようにしていたのですが、
削除できない`User`には2つの`Cart`が紐つかれていた。

そのため
`User has_one Cart`を`User has_many Carts`と変更すると削除できた。

```
+----+---------------------+---------------------+---------+
| id | created_at          | updated_at          | user_id |
+----+---------------------+---------------------+---------+
|  3 | 2020-02-21 07:07:57 | 2020-02-21 07:07:57 |       4 |
| 12 | 2020-02-21 07:29:37 | 2020-02-21 07:29:37 |       7 |
| 13 | 2020-02-21 07:34:26 | 2020-02-21 07:34:26 |       7 |
| 16 | 2020-02-22 07:51:47 | 2020-02-22 07:51:47 |      11 |
+----+---------------------+---------------------+---------+
```

##今後の対処法
モデルを作成する時に、オプションとして`unique: true`を付け、`user`の重複をなしにする。

```XXXXXXX_create_cart.rb
class CreateCarts < ActiveRecord::Migration[5.2]
  def change
    create_table :carts do |t|
      t.references :user, foreign_key: true, unique: true #ここ

      t.timestamps
    end
  end
end

```

##結論
`User has_one Cart` 関係の
`User` に1つのみの`Cart`が紐づくようにしていたのですが、
削除できない`User`には2つの`Cart`が紐つかれていた。

そのため、以下のように`User has_one Cart`を`User has_many Carts`と変更すると削除できた。

```rb
class User < ApplicationRecord
  has_one :cart, dependent: :destroy
end

⬇︎

class User < ApplicationRecord
  has_many :cart, dependent: :destroy
end
```
openpose実行時のエラー対処

openposeを実行したときのエラーについての忘備録

openposeについては下記参照．
https://github.com/CMU-Perceptual-Computing-Lab/openpose

###発生したエラー

```
For the "CUBLAS_STATUS_ALLOC_FAILED" problem, it's because the demo wants to use all visible devices and thus caused crash.
```

GPU関連の設定が怪しいがpytorchなどの別のプログラムでは普通にGPUを使えていたことは確認済み．

openposeの実行時に`CUDA_VISIBLE_DEVICES=2`を加えることで無事に実行できた．
CUDAに使用するデバイスの設定ミスが原因...？

```
CUDA_VISIBLE_DEVICES=2 ./build/examples/openpose/openpose.bin --net_resolution "160x80" --video examples/media/video.avi
```

毎回追加する場合が面倒な場合は`~/.bashrc`内に下記の1行を追加する

```~/.bashrc
export CUDA_VISIBLE_DEVICES=2
```

`~/.bashrc`を変更した後はターミナルを起動し直す，または下記のコマンドを実行

```
source ~/.bashrc
```

###おまけ
openposeをrosで利用
https://github.com/firephinx/openpose_ros
Laravelプロジェクト作成から初めに行うべき設定まとめ

# はじめに
Laravelプロジェクトを作成する方法と、初めに行うべき設定（DB設定や日本語化など）をまとめました。

# 環境
- macOS Catalina 10.15.3
- PHP 7.3.11
- Composer 1.9.3
- Laravel 6.17.1

# プロジェクト作成
ターミナルで以下のコマンドを実行します。

```terminal
$ composer create-project laravel/laravel --prefer-dist sample
Installing laravel/laravel (v6.12.0)
  - Installing laravel/laravel (v6.12.0): Loading from cache

...

Application key set successfully.
```

## `--prefer-dist`について

`--prefer-dist`は、Laravelを圧縮（zip形式）してダウンロードするためのオプションになります。
`--prefer-dist`を指定しないと、Laravelを圧縮せずにダウンロードするためダウンロード時間が長くなります。
なお、`--prefer-source`というオプションもあって、これはオプションを指定しない場合、つまりLaravelを圧縮せずにダウンロードするオプションです。

- `--prefer-source`：Laravelを圧縮せずにダウンロード（ダウンロード時間が長い）
- `--prefer-dist`：Lavavelを圧縮してダウンロード（ダウンロード時間が短い）

[Command-line interface / Commands - Composer](https://getcomposer.org/doc/03-cli.md#create-project)

# DB設定
今回は最も手軽なSQLiteを使用します。

## 設定ファイル変更
`.env`を以下のように設定します。

```
# DB_CONNECTION=mysql
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
DB_CONNECTION=sqlite
```

## DBファイル作成
ターミナルで以下のコマンドを実行します。

```terminal
$ sqlite3 database/database.sqlite
sqlite> .table
sqlite> .q
```

## 解説
`config/database.php`の38〜44行目あたりにSQLiteに関する設定があります。

```php
        'sqlite' => [
            'driver' => 'sqlite',
            'url' => env('DATABASE_URL'),
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
            'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
        ],
```

DBの設定ファイルは以下の行で設定しています。

```php
'database' => env('DB_DATABASE', database_path('database.sqlite')),
```

`env`メソッドは`.env`ファイルから第1引数で指定した設定を取得します。
第1引数で指定した設定が見つからなかった場合は、第2引数で設定したデフォルト値が適用されます。
今回は`.env`に`DB_DATABASE`は設定していないので、第2引数で指定したデフォルト値が適用されています。

# 日本語化
Laravelの日本語化を行います。

## プロジェクト全体
`config/app.php`を以下のように設定します。

```php
'locale' => 'ja',
'fallback_locale' => 'en',
```

`fallback_locale`は、`locale`の設定値がない場合に適用される設定です。

## タイムゾーン
`config/app.php`を以下のように設定します。

```php
'timezone' => 'Asia/Tokyo',
```

## メッセージファイル
`resources/lang/ja`ディレクトリを新たに作成します。

```terminal
$ mkdir resources/lang/ja
```

下記のページからダウンロードしてきたファイル群を作成したディレクトリにコピーする。

[minoryorg/laravel\-resources\-lang\-ja: Laravel 5\.5 日本語メッセージファイル一式です。バリデーションやページネーションを日本語化しています。](https://github.com/minoryorg/laravel-resources-lang-ja)

# バージョン管理
GitとGitHubを使用します。

## リポジトリ作成
下記のページを参考にしてリポジトリを作成します。

[リポジトリを作成する \- GitHub ヘルプ](https://help.github.com/ja/github/getting-started-with-github/create-a-repo)

## 初期設定
ターミナルで以下のコマンドを実行します。

```terminal
$ git init
$ git remote add origin https://github.com/xxxxx/yyyyyyy.git
```

## コミット
ローカルで変更が発生したときは、ターミナルで以下のコマンドを実行します。

```terminal
$ git add .
$ git commit -m "Commit message"
$ git push origin master
```

## `.gitignore`
`.gitignore`は初めから用意されています。
初期設定は以下の通りです。

```
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
```

# まとめ
最低限、これだけは行っておいたほうがいい設定をまとめてみました。
間違いなどありましたらご指摘ください😄
[linux] よく忘れるコマンドメモ

# 環境
zsh

# パイプコマンド

```
alias -g A='| awk'
alias -g C='| pbcopy'
alias -g G='| grep --color=auto'
alias -g H='| head'
alias -g S='| sort'
alias -g T='| tail'
alias -g L='| less -iMR'
alias -g X='| xargs'
```


# ファイル容量を確認

## ncduをインストールする
```
apt install ncdu
```

これが一番早いし楽だし便利
df,duコマンドはだるすぎる



####システム全体
```
df
```

####カレントディレクトリ (１階層）
```
du -sh ${pwd}
```

####カレントディレクトリ (全階層)
```
du -Sh ${pwd}
```
小文字の　s:　１階層
大文字の　S:　全階層
-h: サイズ順

```bash:alias設定
alias size='echo '全階層のサイズ一覧' && du -Sh ${pwd}* | sort -h'
alias size1='echo '1階層のサイズ一覧' && du -sh ${pwd}* | sort -h'
```


#ユーザーをグループへ追加
```
sudo adduser username groupname   
```


#ユーザ情報
```
who
whoami
${whoami}
```
<details>
  -a, --all         -b -d --login -p -r -t -T -u と同じ
  -b, --boot        最後にシステムが起動した時刻
  -d, --dead        終了したプロセスを表示
  -H, --heading     ヘッダ行を表示
      --ips         print ips instead of hostnames. with --lookup,
                    canonicalizes based on stored IP, if available,
                    rather than stored hostname
  -l, --login       システムのログインプロセスを表示する
      --lookup      正式なホスト名を DNS から取得するように試みる
  -m                標準入力に関連づけられたホスト名とユーザのみを表示する
  -p, --process     init によって起動されたアクティブプロセスを表示する
  -q, --count       ログイン中のユーザーのログイン名とユーザ数
  -r, --runlevel    現在のランレベルを表示
  -s, --short       名前, 行および時間のみを表示 (標準)
  -t, --time        最後にシステムの時刻が変更された時刻を表示
  -T, -w, --mesg    ユーザーのメッセージ状態を +, - または ? で追記
  -u, --users       ログイン中のユーザを一覧
</details>



####バージョン確認
```
cat /etc/os-release
```



#権限

*-Rオプションをつけるととディレクトリ配下全てまるごと変更になる*


###chmod: (change mode) 
ファイルやディレクトリのアクセス権を変更する


```
chmod 755 data
chmod -R 755 data
```

| r | 4 | 読み込み権限 |
|:--|--:|:--|
| w | 2 | 書き込み権限 |
| x | 1 | 実行権限 |


###chown: (change owner) 
ファイルやディレクトリの所有者を変更する


```
chown username data
chown -R username data
```


###chgrp: (change group) 
ファイルやディレクトリのグループを変更する


```
chgrp usergroup data
chgrp -R usergroup data
```



#フォント
```
fc-cache -Ev
fc-cache -fv
```
<details>
  -E, --error-on-no-fonts  raise an error if no fonts in a directory
  -f, --force              scan directories with apparently valid caches
  -r, --really-force       erase all existing caches, then rescan
  -s, --system-only        scan system-wide directories only
  -y, --sysroot=SYSROOT    prepend SYSROOT to all paths for scanning
  -v, --verbose            display status information while busy
  -V, --version            display font config version and exit
  -h, --help               display this help and exit
</details>
OpenCVでネットワークカメラの映像を処理する

##ネットワークカメラの画像を処理したい

USBカメラの画像をOpenCVで処理するサンプルはよく見かけますが、ネットワーク・カメラを使用した場合にどのようにコードを記述して良いのかわからなかったので試してみました。

##デバイス指定時にrtspのURLを指定するだけでOK！
結論から言うと、以下のようにキャプチャする際にrtspのURLを指定すればOKです。
使用するカメラによって、rtspのパスは異なりますが、今回使用したIODataのNS210では、ipcam_h264.sdpというパスが指定されていました。（設定画面から自由に変更することが可能です。）

`rtsp://user:password@ip:port/ipcam_h264.sdp`

##コード例
実際のコードのサンプルを以下に示します。
USBカメラと同様のコードで表示が可能です。
なお、USB接続と比べると多少のラグがありますので、ネットワークカメラ側でrtspで送信する動画の解像度やビットレートを調整しましょう。

```camera.py
import cv2

# rtspのURL指定でキャプチャするだけ
capture = cv2.VideoCapture('rtsp://admin:password@192.168.0.1:47614/ipcam_h264.sdp')

while(True):
    ret, frame = capture.read()
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

capture.release()
cv2.destroyAllWindows()
LENOVO ThinkPad X280にUbuntu(bionic)をいれたときの記録



### 環境

ハードウェア情報


```sh:terminal
sudo dmidecode --type system | egrep 'Manufacturer|Version'
>	Manufacturer: LENOVO
>	Version: ThinkPad X280
```

インストールしたOS

```sh:terminal
lsb_release -a
> Distributor ID:	Ubuntu
> Description:	Ubuntu 18.04.4 LTS
> Release:	18.04
> Codename:	bionic
```

# インストールまで

## インストールメディア作成

1. Ubuntu OSのisoイメージを取得する
https://ubuntu.com/#download からダウンロードするとすごく遅いので、ミラーサイトからUbuntuのDesktopイメージをダウンロードする
2. https://www.balena.io/etcher/ からお手元の環境に合わせてインストールメディアを構築するアプリをダウンロード
3. 16GB以上の適当なUSBを利用してインストールメディアを作成

あとはUSBをPCにセットしてぽちぽちしてOSをインストール

# インストール後
トラックポイントとタッチパッドが動かない...

## TrackpointとTouchpadが動かない問題の解決

まず

```sh:terminal
sudo apt update
sudo apt upgrade
```

こちらを参考に修正
[Touchpad and TrackPoint Does Not Work on Lenovo X1C6 and X280](https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1723986)

1. `Ctrl + Alt + t`でTerminalを立ち上げる
2. ブラックリストからコメントアウト

viでファイルを開いて編集

```sh:terminal
sudo vi /etc/modprobe.d/blacklist.conf
```

以下のような行があるので

```
blacklist i2c_i801
```
↓↓　コメントアウトする

```
# blacklist i2c_i801
```

再起動しましょう

```sh:terminal
reboot
```

動きました

## 粛々とセットアップする

違うところもあるが基本的なやりかたはこちらと同様なので省略

https://qiita.com/taketaku/items/b077c3a2cdb2fca696b8

## 感想
- キーボードの打ち心地好き
- 購入当初はUbuntuをいれた後に不具合が多かったが現在では修正されて良好に使える
Githubを使ったチーム開発の流れ（ワーク）

#Githubでのチーム開発
ワークで学んだことを振り返ります。
自分でサブのGitアカウントを作り1人2役で勉強してみました。

実際の現場での流れから補足事項や違いがあれば教えていただけると嬉しいです！
##「リポジトリ共有式プルリクエスト」での場合
※Fork式は後に追記予定

|【*produce*】|【*worker*】|【*things to do*】|【*remarks*】|
|:----------------:|:-----------------:|:------------------|:------------------|
|1|owner|プロジェクトの<br>「リポジトリ(メインリポジトリ)を新規作成」||
|2|owner|リポジトリに<br>「メンバーをコラボレータ登録」する|「github」<br>⇨「setting」⇨「Manage access」⇨「invite a collaborator」|
|3|owner|リポジトリに<br>タスクを「issue」として登録|「issue」をクリックし、タイトル、内容、タスクの振り分け、各タスクの作業者を決定|
|4|owner|プロジェクトの<br>ベース作成|「rails new プロジェクト名」<br>「rails db:create」|
|5|owner|リポジトリに<br>プロジェクトのベースをプッシュ|「git init」<br>「git add -A」<br>「git commit -m "○○"」<br>「git remote add origin SHHのパス」<br>「git push origin master」|
|6|member|オーナーから届いている<br>インビテーションメールを受け入れる|メールを読み「Accept invitation」に入る|
|7|member|プロジェクトのクローンを作成|「git clone SHHのパス」|
|8|member|自身の作業用ブランチの作成|「git checkout -b 自分用ブランチ名」|
|9|member|現在どのブランチにいるか<br>念のため確認|「git branch」|
|10|member|適宜コミットメッセージを<br>実行しながらプロジェクト作業（issue）をこなす||
|11|member|プロジェクトのプッシュ|「git add -A」<br>「git commit -m "〇〇"」<br>「git push origin 作業用ブランチ名」|
|12|member|プルリクエストをあげる。<br>「ターゲットブランチ」<br>と「プルリクエストブランチ」を正しく選択しましょう|「Compare & pull request」|
|13|owner|プルリクエストの通知メール内容を<br>チェックしフィードバック。問題なければ「merge」する|「Merge pull request」<br>「Confirm merge」|
※あとは不要なブランチを削除していく


このような流れで進んでいく！！！（と思います・・・。）
あくまで実戦の場合でも違いはあると思いますが「ほぼ合致している」と希望的観測で
全体的な流れを想像してイメトレして強くなっておきます！

---
プログラミングの勉強を始めてもうすぐ2ヶ月。
忘却曲線を意識しつつ、復習のためのアウトプットとしてQiitaを使用し始めました。
ODACのインストールについて

#この記事の目的
この記事のタイトルにある通り、ODACのインストール方法について方法を記載する。が、本当の目的は以前に書いた記事[「複数バージョンのOracle DBにODAC（ODP.NET）を用いてアクセスするアプリケーションを作る際の参照先DLLに関する注意点」](https://qiita.com/bearbutler/items/35a97befc6ca64c5f2c3)で、GACへのdllやPublisherPolicyの登録方法について、別記事を参照するように書いてあったのに、実際には記事が存在していなかったことに対するフォローが目的である。
なお、今回の例ではODAC183_x64を例にとってコマンドサンプルを作成しているが、ODAC18以降であればコマンドはバージョンの個所を変更するだけで流用できるはずである。

##注意すべき点
以前のODACはOUI(Oracle Universal Installer)でインストールを行うと、自動でGACにdllとPublisherPolicyを登録してくれていたのだが、少なくとも18以降のバージョンでは自動で登録をしない仕様になっている。
GACへの登録をしたい場合には、以下に示す通り、いくつかのコマンドを実行すればよい。

#ステップ ガイド
ODAC183_x64を解凍する
1. 必要があれば、事前にORACLE_HOME用のユーザーを作成しておく(以下の例ではoraclehomeというユーザーを仮定している)
2. 解凍したフォルダ内のsetup.exeを実行しORACLE_HOMEにODACをインストールする(以下の例ではC:\app\oraclehome\product\18.0.0\client_1\)
3. このままだとGACに登録されないので、コマンドを実行しdllとpublisher policyをGACに登録する。
推奨設定のとおり \<ORACLE_HOME> = \<drive>:\app\product\\<oraclehome user>\<version of product>\\\<product type>となっているのであれば以下のとおりである。
ただし、コマンドプロントは管理者で実行し、oraprovcfg はC:\app\oraclehome\product\18.0.0\client_1\ASP.NET\bin\4　に移動したうえで実行している。
 
```common-lisp:
oraprovcfg /action:gac /providerpath:C:\app\oraclehome\product\18.0.0\client_1\odp.net\bin\4\Oracle.DataAccess.dll
oraprovcfg /action:gac /providerpath:C:\app\oraclehome\product\18.0.0\client_1\odp.net\PublisherPolicy\4\Policy.4.112.Oracle.DataAccess.dll
oraprovcfg /action:gac /providerpath:C:\app\oraclehome\product\18.0.0\client_1\odp.net\PublisherPolicy\4\Policy.4.121.Oracle.DataAccess.dll
oraprovcfg /action:gac /providerpath:C:\app\oraclehome\product\18.0.0\client_1\odp.net\PublisherPolicy\4\Policy.4.122.Oracle.DataAccess.dll
```

#確認方法
正しく、dllとPublisherPolicyがGACに登録されたことを確認するには
C:\Windows\Microsoft.NET\assembly\GAC_64 をエクスプローラーで開き、dllとpublisher policyがインストールされていることを確認すればよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/7b8db8ac-b79a-13cc-fc1d-d014adcd562e.png)
[React+Storybook]KnobsでdangerouslySetInnerHTMLがうまく表示されないとき

# 現象

Reactで(Vueもだと思うけど)Storybook + Knobsのスタックで、Knobsの`text()`にHTMLタグを直接渡して、コンポーネントで`dangerouslySetInnerHTML`を使ってレンダリングしようとするとうまく行かない。

<img width="902" alt="Screen Shot 2020-02-27 at 15.45.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174325/8a65b82e-8663-c111-e7e9-c7ccd4eec898.png">


# 原因

Knobsの`text()`にHTMLタグを渡すと、親切にタグをエスケープしてくれるらしい。

```
&lt;p&gt;こんにちは！&lt;br&gt;&lt;br&gt;はじめまして&lt;br&gt;&lt;br&gt;さようなら&lt;/p&gt;
```

# 対応

ただアンエスケープするだけでよし。

```jsx
export const onlyParagraph = () => {
  const beforeContent = text(
    "content",
    "<p>こんにちは！<br><br>はじめまして<br><br>さようなら</p>"
  );

    // Knobsのtext()でHTMLタグがエスケープされてしまうので、アンエスケープしています
    const unescapeHtml = string => {
      const patterns = {
        "&lt;": "<",
        "&gt;": ">",
        "&amp;": "&",
        "&quot;": '"',
        "&#x27;": "'",
        "&#x60;": "`"
      };

      const escapedString = string.replace(
        /&(lt|gt|amp|quot|#x27|#x60);/g,
        match => patterns[match]
      );

      return escapedString;
    }

  return (
    <>
      <HTMLContentWrapper content={unescapeHtml(beforeContent)} />
    </>
  );
};

```
COTOHA API  サンプル集

[COTOHA API Portal](https://api.ce-cotoha.com/contents/index.html) の使用例です。

４つのAPI を５つの言語で使ってみました。

認証情報は、.env に入れました。

APIは
>アクセストークンの取得

>構文解析
>>例題は "特急はくたか"

>固有名詞の抽出
>>例題は "特急はくたかで富山に向かいます。それから、金沢に行って、兼六園に行きます。"

>キーワードの抽出
>>例題は新見南吉の「赤い蝋燭」

言語は
>Python
Node.js
Go
PHP
Ruby

<table>
<tr>
<th></th><th>アクセストークン</th><th>構文解析</th><th>固有名詞</th><th>キーワード</th>
</tr>


<tr>
<th>Python</th>
<td><a href="https://qiita.com/ekzemplaro/items/e2f120bb0848e119be60">access_token.py</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/283f608c8623a725827a">parsing.py</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/c60d97b1f9101b280aa1">proper_noun.py</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/30793b21237a08b2160c">key_word.py</a></td>
</tr>

<tr>
<th>Node.js</th>
<td><a href="https://qiita.com/ekzemplaro/items/b78116fd453ab59f2527">access_token.js</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/3baa38780e881163dda7">parsing.js</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/7eaee17c06e2db80746d">proper_noun.js</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/778ca7ea0152009f0890">key_word.js</a></td>
</tr>

<tr>
<th>Go</th>
<td><a href="https://qiita.com/ekzemplaro/items/fa4f716bcb8f4b8656fb">access_token.go</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/18d4893e0177abcd1ff7">parsing.go</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/fcb7cd77ee8dd0f68be6">proper_noun.go</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/fb58a8a8eb7520fe5390">key_word.go</a></td>
</tr>

<tr>
<th>PHP</th>
<td><a href="https://qiita.com/ekzemplaro/items/8b575c7de9963fc5c56c">access_token.php</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/7afc653777e3785c6a02">parsing.php</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/65b821ae78bafb0004c5">proper_noun.php</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/d1bed5be98915efab31d">key_word.php</a></td>
</tr>

<tr>
<th>Ruby</th>
<td><a href="https://qiita.com/ekzemplaro/items/182aa2f2b799424a0f2c">access_token.rb</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/4ccb52f670f81cb69411">parsing.rb</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/73ed8bb14c695b1de446">proper_noun.rb</a></td>
<td><a href="https://qiita.com/ekzemplaro/items/f081ffd94b434b30fcd5">key_word.rb</a></td>
</tr>



</table>
JavaScript上で他言語プログラムを実行する

# 動機
卒研でとある解析プログラムを開発した．（CとPython）
後任のためにGUIで解析できるElectronデスクトップアプリを開発しようと決意．

ElectronどころかNodeアプリは初だった．Viewはまぁ良いとして解析のロジックをどう繋げようか悩んだ．
不得意なphpやjsに書き換えるのもアレなので，どうにかjs上でC,Pythonプログラムが実行できないかと思案したのが動機．

# 救える人
- Nodeアプリ開発でjs上で他言語のプログラムを実行したい人

本編のネタバレすると，js上にサブプロセスを走らせる．ということをする．
要はコマンドプロンプトやらターミナルだ．なので，ターミナルで出来る作業はなんだって出来る．

これを言うと僕みたいな未熟者以外の方の耳もピクリと動くのではなかろうか．


# 本編
`chile_process`というNodeモジュールを使うと幸せになれる．
このモジュールはjs上でサブプロセスを生成できるという代物．

僕が作ったelectronアプリが例を抜粋するとこんな感じ．

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>subroutine</title>
    <script>
        function subroutine() {
		    let remote = require("electron").remote; // 以下3行はelectronアプリのpathを入手する例
            let app = remote.app;
            let path = app.getAppPath();

            const exec = require("child_process").exec;

            exec(path + "/violin_plot.bat"); // exec()の中にサブプロセスで実行したいコマンドをいれる．
    
	    }
    </script>
</head>
<body>
    <button onclick="subroutine();">サブルーチン</button>
</body>
</html>
```

実際にはターミナルは表示されないので，標準出力とかは確認できないが，解析からのファイル操作とかCやpythonが得意なことで使うと効力を発揮するだろう．
C言語　ポインタのモード切り替えについて

##ポインタはモードを切り替えて扱う
基本的にポインタは２つのモードが存在する。

- __ポインタ変数モード__
- __通常変数モード__

この２つのモードを行き来して使う。

```c
// 通常のint型の変数
int i = 0;

// int型のポインタを宣言
int *p;

// iのポインタをポインタ演算子によって出力し、pに代入
// このときは、ポインタ変数モード
p = &i;

// 通常編集モードに切り替えて、数値を代入
*p = 10;

```

##アドレス演算子&を勘違いしないで！
アドレス演算子&は変数のアドレスを求めるための計算記号なので、ポインタのモードを切り替えているわけではないです。

あくまでコンパイルするときに__アドレスとして置き換わる__だけであって、モード切り替えをしているわけではないです。

ここを勘違いしているといつまでもポインタが使えるようになりません。

##構造体の場合はひと手間かかる
構造体を使用する場合、__通常変数モード__への切り替えは下記のように書きます。

```c
// (*構造体ポインタ変数名).要素名
(*student).year = 10;
```

手間なので、__通常変数モード__への切り替えを下記のように省略して書くこともできます。

```c
// 構造体ポインタ変数名->要素名
student->year = 10;
```


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

typedef struct {
    int year;
    char name[64];

} student;

int main(void)
{
    // student型の変数dataを宣言
    student data;
    // studentのポインタ型pdataを宣言
    student *pdata;

    // pdataにdataのポインタを格納
    pdata = &data;
    
    // pdataを通常変数モードに切り替え、値を格納
    (*pdata).year = 10;
    strcpy((*pdata).name,"MARIO");

    // 同じことを別の書き方でやってみましょう
    pdata->year = 20;
    strcpy(pdata->name, "TANAKA");

    return 0;
}

```




##まとめ
アドレス演算子とポインタのモード切り替えがごっちゃになって混乱しないようにしましょう。
また、構造体の場合は少し書き方が変わりますが、やっていることは同じ、__モード切り替え__です。焦る必要はありません。


###参考
ポインタ変数を使ってみる - 苦しんで覚えるC言語
https://9cguide.appspot.com/15-05.html
pandasでcsvの読み込みをしてIndexをいじってみる

# はじめに
構造化データを扱うのにpandasのDataFrameが良い！と風の噂で聞きました（本当は書店で立ち読みしたデータサイエンスの本で読みました）．
超初心者の覚書としてメモを残しておきたいと思います．

# 環境
Python3.6.10
pandas-1.0.1
Jupyter notebook

#まずはインストール
難しいことは何もなかった...

```console
pip install pandas
```

# csvファイルの読み込み

今回扱いたいデータがcsv形式だったので，csvファイルを読み込んでいきます．
少々調べたところ，pandasにはSeries，DataFrameという二つのデータ構造があり，Seriesが一次元データ，DataFrameが二次元データに対応するらしいということがわかりました（SeriesとDataFrameについては理解が甘々なので勉強し直して別の記事にできたらいいな）

とりあえず今回は，csvデータをDataFrameとして読んでいきたいと思います．

```python:
import pandas as pd
pd.read_csv('データパス',header = None)
```
区切り文字がカンマのcsvファイルを読みたかったので，read_csv()を使いました．
区切り文字がタブ(\t)の場合はread_table()を代わりに使用できるそうです．

また，読みたいcsvファイルには見出し行が存在しないので，headerにNoneを指定しています．

実際に読み込んだデータは，jupyter上では下図のように表示されました↓
<img width="779" alt="スクリーンショット 2020-02-27 13.34.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593268/2ffb26c5-bd91-fc87-5c75-14ac8d871c56.png">

#データの整形

読み込んだデータを次のように整形していきます
・０列目は不要なので削除
・1列目をインデクス（見出し列）にする

![34.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593268/0a425a24-e6e0-9db7-d890-af6628bbdd15.png)

##列の削除

スライスで０列目だけ切り落としていきます．

SeriesやDataFrameではインデクスに文字列を指定することもできますし，（任意の）数値を指定することもできます．特に，インデクスに数値を指定した際の混乱を避けるため，ilocやlocといったインデクス属性を用いてデータにアクセスします．
<img width="1004" alt="スクリーンショット 2020-02-27 14.31.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593268/e24d45c0-eb80-3331-a33d-4fc72df1eeba.png">

今回は（今のところ），DataFrameのインデクスは行・列の両方とも，Pythonスタイルのインデクスと一致しているので，ilocとlocのどちらを用いても同じ結果が得られます．次のようにしてデータの0行目を切り落としました（1行目以降のみ取り出しました）

```python:
#csvを読み込む
df = pd.read_csv('Data/test231.csv',header = None)
#スライスする
df.iloc[:,1:]
```
実際の出力↓
　<img width="730" alt="スクリーンショット 2020-02-27 14.36.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593268/b3960a39-f010-7f7a-2372-a34ed982e29c.png">

前の画像と見比べて列（columns）数が１７０から１６９になっていて，先頭一列のみが減っていると確認できました．

##1列目をインデクスにする

pandasのDataFrameでは，行見出しのことをindex,列見出しのことをcolumnsと呼んでいるらしい．
![6.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593268/6e771d77-3fec-7147-5ff5-3997e2a0e386.png)

次のようにすることで，上の図で"1"という名前のついているcolumnをindexに指定することができました．



```python:

#スライスする
sliced_df = df.iloc[:,1:]
#名前が"1"のcolumnをindexに指定する
sliced_df.set_index(1)
```

下のように実行できました

<img width="600" alt="スクリーンショット 2020-02-27 15.26.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593268/f4aa2f42-6258-0b10-4947-668c5940c887.png">


# おわりに

次はcolumnnの名前を変えたり，このテーブルを階層データとして処理していく記録を覚書として記事にしたいと考えています．
ElmのParserを使うために.htaccessを書いてみました

# レンタルサーバーでElmとSPAしたい
今まで私が作成したSPAではとりあえずフラグメントとクエリーで茶を濁していました。

`https://hoge.com/app-name/?id=1#editPage`
このようにです。

.htaccessをなんとかすれば、レンタルサーバーでもパーサーを使えるのではと思っていましたが後回しでした。

## .htaccess
書いたものがこちらです。

```:.htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /stimer/
  RewriteRule ^img/(.*)$ img/$1 [QSA,L]
  RewriteRule ^sound/(.*)$ sound/$1 [QSA,L]
  RewriteRule ^(.*/)(.*?)$ $2 [QSA,L]
</IfModule>
```

`/stimer/`
これは今回作ったアプリ名です。

`img/`
`sound/`
これは画像ファイルとサウンドファイルを置くフォルダです。

## 動作
`https://hoge.com/app-name/`
`https://hoge.com/app-name`
どちらでもアクセスできます。

`https://hoge.com/app-name/5`
アクセスできません。
最後に`/`を入れる必要があります。

`https://hoge.com/app-name/5/`
アクセスできます。

`https://hoge.com/app-name/sound/start.mp3`
アクセスできます。

## 作ったもの
[stimer](https://pokosuko.work/stimer/)
[リポジトリ](https://github.com/GoldentTuft/stimer)

## まとめ
情報が少ないと感じるのは、自分の検索能力が低いのかElmだからでしょうか?
それとも格安レンタルサーバーなんて今どき使わないのでしょうか?
自分が斜め上を行ってしまっているのでしょうか?
他の人はどうしているのだろうと、腑に落ちないところがありますが、個人的には便利になりそうです。

マサカリお待ちしてお入ります。