OmniAICreator/Qiita-1.07M huggingface dataset:
IntelliJで何かアノテーションが付与されていたら Function 〜 is never used の警告を出さないようにする

IntelliJで開発していて、コード量が増え、リファクタリングを繰り返していくと、Function 〜 is never usedの警告は大変助かります。
まぁ、不要だからと消して後悔することもあるけど、使われないコードがパス検索にヒットすると邪魔なので、消すようにしてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/22f94e8c-c088-6095-203f-2871d94f68fb.png)
一方で、今のプログラミングスタイルでは、アノテーションが付与されたメソッドが、どこからともなく呼び出されることが多いので、このコード検査機能が煩わしい時があります。上の図でMore actionsを選択すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/0e92629f-84b9-89e5-47e6-1ce3138e11cf.png)
「Suppress unused warning if annotated by 〜」を選択すると、アノテーションの種類ごとに抑制することができます。
しかし、アノテーションの種類毎なので、@GetMappingや@PostMapping、@Scheduledなどなどなどの度にSuppressをしていくのは面倒です。

そこで、この際は割り切って、アノテーションの種類に依らず、アノテーションが付与されていたらFunction 〜 is never usedを抑制することにしました。
ここで使っているIntelliJのバージョンは２０２０．１．１ で、手順は以下の通りです。

1. Preferencesの検索ボックスにunusedと入力。
2. InspectionsのUnused declarationを選択。
3. 右下のEntry Pointsタブを選択。
4. Annotationsボタンをクリック。
5. 上段のMark as entry point if annotated byのAdd Annotations Patternをクリック。
6. .*を入力してOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/b3c4e158-6f2f-1c2d-7d5f-5b7f9e9470f7.png)
自分の環境で設定直後はFunction 〜 is never usedのままなんですが、改行を打ち込むなどすると設定が反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/53f5c77f-3b4f-d460-d869-3bf4f81992b9.png)

しばらく、この設定で使って見たいと思います。

* ちなみに、実作業では教えて頂いたJapanese Language Pack EAPで日本語化しています。ただIntelliJがCommunity Editionのせいか、「Inspections」が「コード検査を実行しています。」になったり他にもいろいろとあって、説明が微妙になるので、記事用にプラグインは無効化しました。
サムネイルのクリックによる画像の切り替え

 今回は小さい画像をクリックすると大きく表示される方法を学びます。

<a href="https://gyazo.com/77a0d9e0ae90fec62f6b21d952cb737d"><img src="https://i.gyazo.com/77a0d9e0ae90fec62f6b21d952cb737d.jpg" alt="Image from Gyazo" width="626"/></a>

## HTML
メイン画像とサムネイル画像をそれぞれ配置します。
メイン画像にはid、サムネイル画像にはクラスとカスタムデータ属性data-imageを記入しておく。

※カスタムデータ属性とはdata-の後は自由に名前を決めることができる属性

```html


<div class= "menu">
   <div>
　　　<!-- メイン画像 -->
     <img src="img1.jpg" id="bigimg">
   </div>
   <ul>
     <!-- サムネイル画像 -->
     <li><img src="img1.jpg" class="thumb" data-image="img1.jpg"></li>
     <li><img src="img2.jpg" class="thumb" data-image="img2.jpg"></li>
     <li><img src="img3.jpg" class="thumb" data-image="img3.jpg"></li>
     <li><img src="img4.jpg" class="thumb" data-image="img4.jpg"></li>
   </ul>
</div>
```

##JavaScript
querySelectorAll(".thumb")はclass="thumb"が付与されているものをすべて取得して変数thumbsに代入している。querySelectorはCSSのセレクタにマッチする要素を取得できるが、Allを付けないと１番上の要素しか取得されない。

```java

  // 変数thumbsにquerySelectorAllで取得したサムネイル画像を代入
  const thumbs = document.querySelectorAll(".thumb");
  // forEachメソッドで要素を分ける
  thumbs.forEach(function(item, index){
    // 画像がクリックされた時にイベントが発生する
    item.onclick = function(){
      // クリックされた画像のカスタムデータ属性を読み取り、id="bigimg"のsrcに代入
      document.getElementById("bigimg").src = this.dataset.image;
    }
  });
```

以上で切り替えができる様になりました。

## 最後に
見たらわかるけど自分では思いつかないだろうな...
自由自在に扱える様になりたい。
マーケットバスケット分析（Market Basket Analysis）

- 参考にしたもの
  - [東京大学のデータサイエンティスト育成講座](https://www.amazon.co.jp/%E6%9D%B1%E4%BA%AC%E5%A4%A7%E5%AD%A6%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%82%B9%E3%83%88%E8%82%B2%E6%88%90%E8%AC%9B%E5%BA%A7-%E5%A1%9A%E6%9C%AC-%E9%82%A6%E5%B0%8A-ebook/dp/B07PD237GQ/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E6%9D%B1%E4%BA%AC%E5%A4%A7%E5%AD%A6%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%82%B9%E3%83%88%E8%82%B2%E6%88%90%E8%AC%9B%E5%BA%A7&qid=1588468608&s=digital-text&sr=1-1)

# 「マーケットバスケット分析」の概要

- 機械学習の、教師なし学習に使われる手法。
- 「**Aを買う人にはBも売れる**」というような関連性（アソシエーションルール：Association Rule）を分析する。

# 使う指標

- 支持度（support）
- 確信度（confidence）
- リフト値（lift）

↓の例で、**「Aを買う人は、Bも一緒に買う？」という問題**を考える

| 購入パターン            | 数    |
|:-----------------------|------:|
| 全購入データ            | 1,000 |
| Aが買われた回数         |   800 |
| Bが買われた回数         |   600 |
| A・Bが同時に買われた回数 |   300 |

## 支持度（support）

- **全ての購入データのうち、A・Bが同時に買われた割合。**
- 相対的な値のため、この数字のみでは一概に判断はできない。
- 一般に支持度が小さいルールは有用性も低いことが多い。（=足切り基準として使われたりする）

```math
\frac{300}{1000} = 0.3
```

※「AかつB」というルールのみでなく、「A」という商品の支持度を計算することもある。

## 確信度（confidence）

- **Aが購入されたデータのうち、A・Bが同時に買われた割合。**
- 確信度が高いと商品間の併売が見込めるため、高い商品の中からオファー商品を決定する、といったように使われる。
- ただし、コレも絶対値だけでは一概に判断できないため、↓のリフト値も併せて見る必要あり。

```math
\frac{300}{800} = 0.375
```

※「Bが購入されたデータのうち、A・Bが同時に買われた割合」は、異なる結果となる

```math
\frac{300}{600} = 0.5
```

## リフト値（lift）

- **「全ての購入データのうち、Bが買われた割合」と「Aが購入されたデータのうち、A・Bが同時に買われた割合」の割合。**
  - =確信度（confidence）／（<font color="red">商品Bの</font>）支持度（support）
- 1.0より大きい ＝ 「全体のうちBが買われる割合 < Aが買われたうちBが買われる割合」 ＝ 併売しやすい商品と言えそう
- 1.0より小さい ＝ 「全体のうちBが買われる割合 > Aが買われたうちBが買われる割合」 ＝ 併売しやすい商品と言えなさそう

```math
\frac{ \dfrac{300}{800} }{ \dfrac{600}{1000} } = 0.625
```

この例の場合、「Aを買う人にはBも売れる」とは<font color="red">言えなさそう</font>
Bootstrap4のポップオーバーで画像のスタイルが効かなくてハマった件

# 環境
Bootstrap : 4.4.1

# 問題のソース
```script-popover.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
          integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
            integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
            crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
            integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
            crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
            integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
            crossorigin="anonymous"></script>
    <title>ExampleTitle</title>
</head>

<body>
<div class="container">
    <div class="row m-2">
        <div class="col-12">
            <button type="button" class="btn btn-secondary">popover button</button>
        </div>
    </div>
</div>
</body>

<script>
    $(function () {
        (function () {
            let img = '<img src="../img/sample.jpg" alt="sample" style="width:75px;">';
            let title = '<div>This is popover!</div>';
            $('button').popover({
                'placement': 'top',
                'container': 'body',
                'trigger': 'focus',
                'title': title,
                'html': true,
                'content': img,
            });

        })();

    });
</script>

```

## 実行イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238561/1ea8ff72-8761-edcc-e005-f9c20c565651.png)

スタイルに75pxを指定しているのに効いてない


## 解決策
StirngじゃなくてJQueryでDOMオブジェクトに変換してやればうまくいく

```script-popover.html
～～～省略～～～
'content': $($.parseHTML(img)),
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238561/072fceea-797a-cfac-eaaa-eb8225d4b23e.png)
うまくいった

## リファレンス
https://cccabinet.jpn.org/bootstrap4/components/popovers
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238561/3496f04c-ac84-d518-b89b-eb5a86217c11.png)


String渡せるように見えるんだけど、バグかな？
HTML&CSSについて

<h1>HTMLとは</h1>
HTMLは、Hyper Text Markup Language（ハイパーテキスト・マークアップ・ランゲージ）の略であり、ウェブページを作成するために開発された言語。

- ハイパーテキストは、ハイパーリンクを挿入できるテキストのことである。
- マークアップは、文章の見出しやリストなど文章構造を「定義する」ことである。

このことからHTMLは、ハイパーリンクを挿入できるテキストを含めた文章構造を定義することができる言語である。

<h1>CSSとは</h1>
CSSは、Cascading Style Sheets(カスケーディング・スタイル・シート）の略であり、ウェブページのスタイルを指定するための言語。
カスケーティングは、「小滝」、「階段上に連続する滝」という意味であり、様々なクラスで定義されたスタイルは、下流のスタイルにも引き継がれることである。

このことからCSSは、定義したスタイルが段階的に引き継がれて文章に適用されるスタイルシートである。

<h1>HTMLとCSSの関係性</h1>
ほとんどのwebサイトはHTMLとCSSで作成されており、HTMLでwebサイトに表示する文章構造を決定し、CSSでHTMLの内容を修飾することで普段目にするwebサイトになる。
ビュー(erb,haml)でデバッグを行う

##やること
今回の記事では、表題の通りビューファイルの中でデバッグを行います。
erbとhamlではhtmlの中にRubyを書き込むことが出来るため、実はbinding.pryをかけることが出来ちゃいます。
これにより、ビューで使用する変数にどのような値が格納されているか分かるわけです！
やることはすごく簡単なことですが、意外と盲点となっており初学者では知らない人も多いと思います。

##早速やってみる
以下のようにerbで書かれたビューファイルがあったとします。
注目する点は２行目のbinding.pryです。
erbはビューファイル内にRubyのコードが書けるので、2行目で処理を止めることができます。

```erb
<% @posts.each do |post| %>
  <% binding.pry %>
  <div class="content">
    <div class="content__left">
      <div class="content__left--image"></div>
    </div>
    <div class="content__right">
      <div class="content__right__top">
        <%= post.title %>
      </div>
      <div class="content__right__bottom">
        <div class="content__right__bottom--date">
          <%= post.created_at %>
        </div>
      </div>
    </div>
  </div>
<% end %>
```

ターミナルで@postsの中身が確認できました！
こういった方法も用いてデバッグをやっていきましょう！

```
    1: <% @posts.each do |post| %>
 => 2:   <% binding.pry %>
    3:   <div class="content">
    4:     <div class="content__left">
    5:       <div class="content__left--image"></div>
    6:     </div>
    7:     <div class="content__right">

[1] pry(#<#<Class:0x00007ff22f887b50>>)> @posts
=> [#<Post:0x00007ff22f10a418 id: 1, title: "こんにちは", content: "ブログテスト", created_at: Sat, 10 Aug 2019 00:00:00 UTC +00:00, updated_at: Sat, 10 Aug 2019 00:00:00 UTC +00:00>,
 #<Post:0x00007ff231386a50 id: 2, title: "おはよう", content: "テスト2", created_at: Wed, 01 Jan 2020 00:00:00 UTC +00:00, updated_at: Wed, 01 Jan 2020 00:00:00 UTC +00:00>]
```

##hamlでもデバッグしてみる
やることはほとんど同じなのですが、一応hamlでもbinding.pryをやってみましょう。
2行目にbinding.pryをかけています。

```haml
- @posts.each do |post|
  - binding.pry
  .content
    .content__left
      .content__left--image
    .content__right
      .content__right__top
        = post.title
      .content__right__bottom
        .content__right__bottom--date
          = post.created_at

```
erbでデバッグした時と同じように、@postsの中身を参照することができました！

```
    1: - @posts.each do |post|
 => 2:   - binding.pry
    3:   .content
    4:     .content__left
    5:       .content__left--image
    6:     .content__right
    7:       .content__right__top

[1] pry(#<#<Class:0x00007f8c628e2df8>>)> @posts
=> [#<Post:0x00007f8c6284f648 id: 1, title: "こんにちは", content: "ブログテスト", created_at: Sat, 10 Aug 2019 00:00:00 UTC +00:00, updated_at: Sat, 10 Aug 2019 00:00:00 UTC +00:00>,
 #<Post:0x00007f8c62847d08 id: 2, title: "おはよう", content: "テスト2", created_at: Wed, 01 Jan 2020 00:00:00 UTC +00:00, updated_at: Wed, 01 Jan 2020 00:00:00 UTC +00:00>]
```

今回の記事は以上です！
UbuntuでJAVA_HOMEの設定

UbuntuでJAVA_HOMEの設定方法について記載する。

- javaは、alternativesを経由している前提。
    - /usr/bin/java -> /etc/alternatives/java -> (実際のjavaのロケーション)
    - PATHは、/usr/binに通っているので、特に対応しない。
- 複数のjavaを切り替える場合もsourceコマンドを実行することで対応できるようにしておく。
    - 切り替え方は、こちらを参照。「 [Ubuntuで、複数のJavaをインストールして切替を行う](https://qiita.com/yochapan/items/af86a320035f8db7daf4)」
    
# やり方
### /etc/profle.d配下にjava_home.shを作成

- /etc/profile.d配下のshellは、ログイン時に実行される。

```sh
sudo vi /etc/profile.d/java_home.sh
```

### JAVA_HOMEのエクスポートを記載

- javaコマンドの絶対パスから、JDKのホームディレクトリを判断している。
- `${JAVA_HOME}/bin/java`の場合と`${JAVA_HOME}/jre/bin/java`の場合があるので、その両方に対応させている。（それ以外の場合もあるかも。。。）

```/etc/profile.d/java_home.sh
export JAVA_HOME=`echo $(dirname $(readlink $(readlink $(which java)))) | sed -e 's/\/bin$//g' | sed -e 's/\/jre$//g'`
```

### sourceコマンドで、JAVA_HOMEを反映

```sh
source /etc/profile.d/java_home.sh
```

### 確認

```sh
echo $JAVA_HOME
```
opencvをソースコードからビルドしたときにopencv-pythonに依存するpipパッケージのインストールを通す

# 概要
[この記事](https://qiita.com/devmikyom/items/a568d4246e1103b18f69)でopencvをソースコードからビルドしました。自作のプログラムから`import cv2`はできるのですがopencv-pythonに依存するパッケージをインストールしようとするとopencv-pythonないよって怒られます。site-packagesにシンボリックリンクを貼っただけなので、pip的にはopencvが入ったことにならないのでしょうか？そういえばcmakeでpipの場所を指定しなかったような。

そこで、cv2をラップしたパッケージを作ってみました。`import cv2`はできるので、空っぽのopencv-pythonパッケージを作ってごまかすのもありではと思いましたが、せっかくなのでちゃんと（？）ラップしました。

# 構成
構成は以下のとおりです。

```console
wheel/
├── build               # ビルドしたものが出力される
├── cv2                 # パッケージ名になる
│   ├── __init__.py     # 外にcv2として見せる
│   └── _native
│       ├── cv2.cpython-36m-aarch64-linux-gnu.so # 実体
│       └── __init__.py # 元のcv2をインポートする
├── dist                # whlファイルが出力される。これをpip installする
├── MANIFEST.in         # 実体を指定する。
└── setup.py            # pipの各種設定
```

各ファイルの中身は以下です。`__init__.py`何もわからない。。

```python:setup.py
from setuptools import setup
from setuptools.dist import Distribution

class BinaryDistribution(Distribution):
    def has_ext_modules(foo):
        return True

long_description = "long description of the wheel"

setup(
    name='opencv-python',
    packages=['cv2'],
    version='3.4.3',

    include_package_data=True,
    distclass=BinaryDistribution,

    author='devmikyom',
    description='OpenCV wrapper for Ubuntu 20.04 on raspberry pi 4',
    long_description = long_description,
    classifiers=[
        'Programming Language :: Python :: 3.6'
    ]
)
```

```:MANIFEST:in
include cv2/_native/cv2.cpython-36m-aarch64-linux-gnu.so
```

```python:wheel/cv2/__init__.py
from ._native.cv2 import *
__version__ = '3.4.3'
```

```python:wheel/cv2/_native/__init__.py
from .cv2 import *
```

`__init__.py`本当に何もわからない。。

# ビルドとインストール

```console
$ python setup.py bdist_wheel
$ pip install dist/opencv_python-3.4.3-cp36-cp36m-linux_aarch64.whl
```

`import cv2`できてpip的にもopencv-pythonとしても見えているようです。これで本当に合っているのかよくわかりませんが…
Vue.js基本

#Vue.jsについて

###Vue.js
人気の高いJavaScriptのフレームワークの一つ
https://jp.vuejs.org/index.html


###基本
#####読み込み
Vue.jsの読み込みには、Vue.js本体を配信しているCDNを利用する。Vue.jsには開発用と、本番用の２種類があり、開発バージョンには警告出力とデバックモードがあるので学習ようには最適。

#####Vueインスタンスの作成
Vue.jsを読み込むとVue関数が使用できるようになる。そのVue関数を使いVueインスタンスを作成する。
Vue関数には引数としてオプションオブジェクト（Vue.jsの設定を行うためのオブジェクト）をとり、そのオプションオブジェクトの内容によってVueアプリの挙動が変わる。

```
new Vue({
//オプション
})
```

・elオプション
elオプションではVueインスタンスを紐付けるDOM要素を指定する。DOM要素はCSSセレクタ形式での指定が可能

```
new Vue({
  el: "#app"  //#appを指定
})
```

・dataオプション
Vueインスタンスに持たせたいデータを登録することができる。複数データ持たせることも可能。

```
new Vue({
  el: "#app",
  data: {
    message: "Hello Vue.js"  //messageというプロパティ名で"Hello Vue.js"という値を登録
  }
})
```
これでVueインスタンスを#appに紐付かせ、データも持たせることができた。

・登録したデータを表示
参照したいデータの名前を波括弧を二重にして囲む（Mustache構文）。

```
<div id="app">
  {{ message }}  //Hello Vue.jsと表示
</div>
```


#####属性
HTMLの属性値にVueインスタンスのデータを参照するには、v-bindディレティブを使う。
v-bind:属性名="参照するデータ"の形で使い、Vueインスタンスのデータと属性値を紐付けする。

```:.html
<div id="app">
 <a v-bind:href="href">Vue.js</a>
　　//省略して　:href="href" でも良い
</div>
```

```:.js
new Vue({
  el: "#app",
  data: {
    href: "https://jp.vuejs.org"
  }
})
```

#####条件分岐
条件によって要素の表示を分けたい場合はv-ifディレクティブを使う。値が真か偽どちらに評価されるかで表示の有無が変わる。else if、elseディレクティブも用意されている。

```:.html
<div id="app">
  <p v-if="stock">販売中</p>
  <p v-else-if="stock">のこりわずか</p>
  <p v-else>売り切れ</p>
</div>
```

```:.js
new Vue({
  el: "#app",
  data:　{
    stock: 5
  }
})
```

「のこりりわずか」と表示される。

#####ループ
配列をループしたい場合はv-forを使う。
v-for="配列の要素名 in 配列名"の形で使う。

```:.html
<div id="app">
  <ul>
    <li v-for="item in items">{{ item }}</li>
  </ul>
</div>
```

```:.js
new Vue({
  el: "#app",
  data: {
    items: ['みかん','りんご','ばなな']
  }
})
```

・みかん
・りんご
・ばなな

と表示される。

#####イベント処理
クリック、フォームの送信など、イベントが発生した時に処理を行いたい時はv-onディレクティブを使う。

```:.html
<div id="app">
  <p>カウント : {{ count }}</p>
  <button v-on:click="count = count + 1">カウント追加</button>
  //ボタンをクリックするとcountの値を１増加する
</div>
```

```:.js
new Vue({
  el: "#app",
  data: {
    count: 0
  }
})
```
v-onもよく使うため、省略して「@イベント名="行いたい処理"」と書くこともできる。

以上

まだまだたくさんありますし、自分も勉強中なのでこれから他にも書いていきたいです。
fish shellでのエイリアス設定方法

# TL;DR

`~/.config/fish/functions/*.fish` に書け

# fish をよく知らない方向けに

fish には bash で言う alias はありません。代替手段として、function を記述することで、コマンドの挙動を制御することができます。

# よくある例

`~/.config/fish/config.fish` に function を記載します。

```Fish
function ls
    command ls --color=auto $argv
end
funcsave ls
```

## (今回初めて知った) よくある間違い

~/.config/fish/config.fish に function を記載する場合、funcsaveは不要です。

funcsave は、プロンプト上から動的に関数を定義し、永続化したい場合にのみ使用します。

# 本題に戻って、~/.config/fish/functions/ を使いましょう、というご紹介

## config.fish に function を記載すると

* config.fish が長くなって、可読性メンテナンス性が下がります

## ~/.config/fish/functions/*.fish に書く利点

* 1ファイル1 functionで記述でき、メンテナンス性が高い

# まとめと裏話

本当は利点にいちいちfuncsaveする必要がないよ、と書きたかったのですが、いろいろ試してみたところ、そもそもfuncsave要らないということがわかりました。

ということで、~/.config/fish/functions/ をちゃんと使っていきましょう。
windows10に開発用の仮想環境をubuntu20.04で作る2020

最近私用でwindowsのノートPC購入したので個人開発用に環境設定していた。
初めはwindow上で開発しようと思ったが色々面倒だったので（慣れてないというのもある）思い切ってubuntuの仮想マシンを作り、そこで開発することにした。

# 環境

+ ホストOS：windows 10 Home (64-bit)
+ ゲストOS：Ubuntu 20.04 (Focal Fossa) (64-bit)

# 仮想マシン作成

大体この辺を参考にした。
[Windows10にVirtualBoxとUbuntuをインストール](https://qiita.com/pyon_kiti_jp/items/0be8ac17439abf418e48)

なおubuntuのDesktopイメージファイルのサイズは大きくてダウンロードに結構時間かかるので注意。
また仮想マシン作成時のファイルサイズが小さいと後から変更するのが面倒なので、開発に使うだけだとしても大きめでいいと思う。（今回は200GB）
オフィス系のツールなどは使わないため、セットアップ中は最小限のソフトウェアのみインストールする。

# gitとssh鍵の設定

以下コマンドでgitをインストール
`sudo apt-get install git`

また鍵も作成しておく。

```shell
# ディレクトリ移動
cd ~/.ssh
# 鍵生成
ssh-keygen
# 公開鍵を表示、コピーしてgithubの鍵設定ページに貼り付ける
cat id_rsa.pub
```

# docker

dockerをインストールする。
[公式](https://docs.docker.com/engine/install/ubuntu/)だとubuntuのバージョン19.10までのインストール方法が記載されているが、
20.04だと以下コマンドのみでインストールができる。
`sudo apt install docker.io`

これだけだとpermission不足で操作できないため以下コマンドでdockerグループにログインユーザを追加する。
`sudo gpasswd -a <ユーザ名> docker`

以下コマンドでdocker使えるかを確認。
`docker run hello-world`

ついでにwebサーバ起動できるかを確認。
以下コマンド起動後 `localhost:8080` にアクセスして画面見れることが確認できればOK。
`docker run --name test -p 8080:80 nginx`

# vscode

ubuntu softwareからvscodeをインストールする。
また次の拡張機能をインストールしておく。

+ Python
+ Docker
    + vscode中のGUIでコンテナ管理できる
+ Markdown Preview Enhanced
    + markdownファイルのプレビューがvscode上で確認できる

# 所感

windows上で開発環境作ろうとしたときと比べるとかなりスムーズにできた。
ただubuntuを最新バージョンにしたので若干情報が見つからないところがあったので19とかでも良かったかもしれない。
特にdockerの公式ドキュメントでubuntu 20.04の記述が見つからずビビった。
とはいえ20だと未インストールのコマンドを叩くと対応するパッケージのインストール方法がサジェストされるのが非常に便利。
Flutter アプリに Firebase を追加する

# はじめに
[Flutter によるスマホアプリ開発](https://qiita.com/nekoharuyuki/items/512cc6b10ee2744e799d) で、Flutterの開発環境構築とプロジェクトを作成する方法をまとめました。

スマホアプリとして、質の高いサービスを配信/運用するには「アプリのアクセス/クラッシュ解析」や「PUSH通知」や「ログイン認証」など、多くの機能が必要になります。このような機能は、Firebaseを使用すると簡単に実装することが出来ます。

[Firebase](https://firebase.google.com/?hl=ja) は、優れたアプリを開発し、ユーザーベースを拡大、収益を高めるためのツールです。Firebaseを使えば、インフラ構築に手間取ることなくビジネスを収益化し、効率よくアプリを開発し、運用・管理することができるようになります。

Flutterで作成したプロジェクトにFirebaseを追加する方法を備忘録としてまとめます。

# 事前準備

- [Flutter によるスマホアプリ開発](https://qiita.com/nekoharuyuki/items/512cc6b10ee2744e799d) を確認
  - Flutterの開発環境構築とプロジェクトを作成
- Google アカウントを使って [Firebase](https://console.firebase.google.com/) にログイン
  - Firebase プロジェクトを作成
  - [Firebase プロジェクトについて理解する](https://firebase.google.com/docs/projects/learn-more?hl=ja) を確認

# 実装
[Flutter アプリに Firebase を追加する](https://firebase.google.com/docs/flutter/setup?hl=ja) を参考に実装します。
Firebaseは、OSに依存する機能を使用するので、各プラットフォームごとに実装する必要があります。

## iOS アプリを構成する
[iOS アプリを構成方法](https://firebase.google.com/docs/flutter/setup?hl=ja#configure_an_ios_app) を確認しながら設定します。

1. バンドル ID を [Firebaseコンソール](https://console.firebase.google.com/) に設定します。
2. Firebase iOS 構成ファイル（GoogleService-Info.plist）を取得します。
3. ファイルを Flutter アプリの Runner/Runner ディレクトリに移動します。

## Android アプリを構成する
[Android アプリを構成](https://firebase.google.com/docs/flutter/setup?hl=ja#configure_an_android_app) を確認しながら設定します。

1. パッケージ名 を [Firebaseコンソール](https://console.firebase.google.com/) に設定します。
2. Firebase Android 構成ファイル（google-services.json）を取得します。
3. ファイルを Flutter アプリの android/app ディレクトリに移動します。
4. Gradle ファイルに設定を追記して、 `flutter packages get` を実行します。

```android/build.gradle
buildscript {

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
  }

  // ...
  dependencies {
    // ...

    // Add the following line:
    classpath 'com.google.gms:google-services:4.3.3'  // Google Services plugin
  }
}
allprojects {
  // ...

  repositories {
    // Check that you have following line (if not, add it):
    google()  // Google's Maven repository
    // ...
  }
}
```
```android/app/build.gradle
dependencies {
  // ...
}

// ...

// Add the following line to the bottom of the file:
apply plugin: 'com.google.gms.google-services'  // Google Play services Gradle plugin
```

## FlutterFire プラグインを追加する
[FlutterFire プラグインを追加する](https://firebase.google.com/docs/flutter/setup?hl=ja#add_flutterfire_plugins) を確認しながら設定します。
_以前書いた記事の [FlutterやDartのパッケージを使用する](https://qiita.com/nekoharuyuki/items/512cc6b10ee2744e799d#flutter%E3%82%84dart%E3%81%AE%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B) にプラグインの追加方法は記載してます。_

1. Flutter アプリのルート ディレクトリから、pubspec.yaml ファイルを開きます。
2. [Firebase Core SDK](https://pub.dev/packages/firebase_core) を pubspec.yaml に追記します。

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^0.4.4+3  # add dependency for Firebase Core
```
特定の Firebase プロダクトを使用するためには [FlutterFire プラグイン](https://github.com/flutter/plugins/#plugins) を追加します。

# まとめ
今回は Flutterプロジェクト に Firebase の設定を行いました。
また別で、「アプリのアクセス/クラッシュ解析」や「クロスプラットフォームでPUSH通知」や「ログイン認証」などの実装を、今後まとめていきます。
かばん検定をpythonで行う方法

#はじめに
かばん検定をpythonで行う方法を述べる

#かばん検定とは？
一連の相関関数において，相関があるかを検定する方法．

詳細は，[wikipediaを参照のこと](https://ja.wikipedia.org/wiki/%E3%81%8B%E3%81%B0%E3%82%93%E6%A4%9C%E5%AE%9A)

#かばん検定で用いる関数
例えば，Ljung-Box検定を行う際には，
statsmodels.stats.diagnostic.acorr_ljungbox
を用いる．
詳細は[こちら](https://www.statsmodels.org/stable/generated/statsmodels.stats.diagnostic.acorr_ljungbox.html)

#例1
例えば，ランダムに発生させたノイズ(白色ガウス雑音)で検定を行う．
もちろん，相関関係はないはずなので，帰無仮説は棄却されないはずです．

```python
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.style.use('seaborn')
mpl.rcParams['font.family'] = 'serif'
%matplotlib inline
import numpy as np
from statsmodels.stats.diagnostic import acorr_ljungbox
p = print

#データ点は1000点とする
np.random.seed(42)
data = np.random.standard_normal(1000)

#まずはデータをプロットする
plt.figure(figsize=(10,6))
plt.plot(data,lw = 1.5)
plt.xlabel('time')
plt.ylabel('value')
plt.xlim([0,100])
plt.title('time vs. value plot');
```

当然，白色ガウス雑音の時系列データがプロットされます．
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565132/05f66d55-f2ad-cdd2-fe49-cd7597fa37e7.png)


では，これをかばん検定してみましょう．

```python
result = acorr_ljungbox(data,lags = 5)
p(result)
```

結果は次のようになります．

```
(array([0.05608493, 0.05613943, 0.31898424, 3.27785331, 3.94903872]), array([0.81279444, 0.97232058, 0.9564194 , 0.51244884, 0.55677627]))
```

2つの要素をもったタプル形式で出力されますが，1つ目は検定の統計量，2つ目は，p値です．見た目綺麗なように表形式にしましょう．

```python
result_table = pd.DataFrame(data = result, index=['static value', 'P value'],columns=[str(i) for i in range(1,6)])
result_table
```
以下のような結果が出力されます．列方向は，ラグの大きさです．
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565132/7ee2b8c0-3660-3ac9-f48c-d07d0449a11f.png)

#例2
次に，MA(2)過程の検定を行いましょう．次のような式を想定します．

```math
y_t = 1 + \epsilon_t + 0.5 \epsilon_{t-3}
```

ただし，$\epsilon_t$は白色ガウス雑音とします．
式の形から明らかなように，どうやら時間差が3のとき(例えば$y_5$と$y_8$)に相関が生じそうですよね．もちろん数学的に確認もできるのですが，かばん検定でこれを確認します．

```python
#モデルデータの作成
data = np.zeros(1000)
np.random.seed(42)
err = np.random.standard_normal(1000)
for i in range(1000):
    if i-3 < 0:
        data[i] = 1 + err[i]
    else:
        data[i] = 1 + err[i] + 0.5 * err[i-3]

#まずはデータをプロットする
plt.figure(figsize=(10,6))
plt.plot(data,lw = 1.5)
plt.xlabel('time')
plt.ylabel('value')
plt.title('time vs. value plot (MA(3) model)')
plt.xlim([0,100])
```

![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565132/6a152c36-a36c-d0a2-1b7e-80ef20b99146.png)

```python
result = acorr_ljungbox(data,lags = 5)
result_table = pd.DataFrame(data = result, index=['static value', 'P value'],columns=[str(i) for i in range(1,6)])
result_table
```

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565132/489aa464-da21-ab44-e822-f3fb47bbb828.png)

例えばPを0.05で検定した場合，ラグが2以下の場合は有意な差がないですが，3以上(つまり，$\rho_3$が含まれた場合)になるとと有意な差が出ることがわかります．
Alacrittyでfish shell立ち上げ時にtmuxを起動する方法

設定ファイルである`alacritty.yml`(`~/.config/alacritty/alacritty.yml`とかにあるはず)を以下のようにし

```alacritty.yml
...
shell:
   program: /usr/local/bin/fish
   args:
     - --login
...
```
`config.fish`(`~/.config/fish/config.fish`とかにあるはず）を以下のようにすればいい。

```config.fish
...
if status is-interactive
and not set -q TMUX
    exec tmux
end
...
```

### 参考
https://github.com/fish-shell/fish-shell/issues/4434
PythonのWindows用EXE化をDockerコンテナで実現する方法

Docker上のLinuxで使ってるPythonコードを、人に渡すためにぱぱっとEXE化したい人むけ。

# 利用するコンテナ

windowsでPyInstallerを実行するコンテナを配布されている方がいらっしゃるので、利用させていただきます。

- DockerHub：[cdrx/pyinstaller-linux](https://hub.docker.com/r/cdrx/pyinstaller-windows)

Dockerfileを読んだところ、以下ののWindowsアプリケーションをLinux上で実行するソフトウェアを利用しているようです。

- 外部サイト：[WINE HQ](https://www.winehq.org/)

サイトのTOPに乗っているWineHQの説明（和訳は適当なのであしからず）
>
Wine (元々 "Wine Is Not an Emulator "の頭文字をとったもの) は、Linux、macOS、BSDなどのPOSIX準拠のオペレーティングシステム上でWindowsアプリケーションを実行できる互換性レイヤーです。仮想マシンやエミュレータのように内部のWindowsロジックをシミュレートするのではなく、WineはWindows APIコールをPOSIXコールにその場で変換し、他の方法によるパフォーマンスやメモリのペナルティを排除し、Windowsアプリケーションをデスクトップにクリーンに統合することができます。


# 実行コマンド例

何度も実行することが多いのでシェルスクリプトにして実行しています。
以下のシェルスクリプトをソースコードのあるディレクトリで実行すれば、同じ階層にbuildやdistディレクトリ、.specファイルが生成されます。作成されたWindows用EXEはdistディレクトリの中にあります。

```sh:build.sh
#! /bin/bash
docker run --rm -v "$(pwd):/src/" --entrypoint /bin/sh cdrx/pyinstaller-windows \
-c "/usr/bin/pip install -r requirements.txt && pyinstaller main.py --noconsole --onefile --clean"
```
- ```docker run```：コンテナの実行コマンド
- ```-rm```：コンテナ終了後にコンテナを消去
- ```-v "$(pwd):/src/"```：ホストOSのカレントディレクトリをコンテナOSの/src/にマウント
- ```--entrypoint /bin/sh```実行時にコマンドを渡す相手の指定（今回はshを指定）
- ```cdrx/pyinstaller-windows```：実行するイメージの指定。```cdrx/pyinstaller-linux```を使うとLinux用実行ファイルも作れます。まあ、普通の開発用コンテナでやってもいいと思います。
- ```-c "~ hogehoge ~"```：コンテナ内で実行するコマンドを指定
- ```/usr/bin/pip install -r requirements.txt```：pipで依存関係をインストール。apt等のインストールが必要な場合は追記
- ```pyinstaller main.py --noconsole --onefile --clean```：本題のexe化コマンド。コンソールなし、１ファイル化、前回の結果を消去のオプションを指定。


# 実行結果
今の所３種類ほどのコードをexe化して、win10とwin8で実行しましたが問題なく起動できた。
また、PySimpleGUIのコードも問題なくexe化できたのでPythonでWindows用GUIをサクッと作りたい人にはおすすめしたい。
【Node.js】Node.jsをインストールする方法

#Node.jsインストール

[Node.jsの公式サイト](https://nodejs.org/ja/)にアクセスする。

「推奨版」を押下する。

パッケージが開き、「続ける」を押下する。

「続ける」を押下する。

「同意する」を押下する。

「続ける」を押下する。

「インストール」を押下する。

パスワードを入力し、「ソフトウェアをインストール」を押下する。

「閉じる」を押下する。

#Node.jsインストール確認

ターミナルを開き、下記コマンドを入力し、バージョンが表示されれば確認OK。

```
$ node -v
v12.16.3
$ npm -v
6.14.4
```
rails newでエラーが出た時に解決した話

rails new でアプリを新規作成する時に、以下の画像のようなエラーが出て困っていました。
[![Image from Gyazo](https://i.gyazo.com/2a40ea9dd71f91d038246a0d539272b7.png)](https://gyazo.com/2a40ea9dd71f91d038246a0d539272b7)

以下のコマンドで

```
$ gem list rails versions
```

それぞれのバージョンを確認
[![Image from Gyazo](https://i.gyazo.com/0b7b9417ceebc124bda22088b3aa21c5.png)](https://gyazo.com/0b7b9417ceebc124bda22088b3aa21c5)
原因としては、rails newでエラーが出る部分はrails6の機能になるので、railsのバージョンを指定してコマンドを入力する必要がありました。

```
rails _5.2.4.1_ new アプリ名 -d mysql  
```
無事、rails new　成功しました！
pythonモジュールとしてyoutube_dlを使う．appendix) ニコニコ動画 HTTP 403 error

#インストール
###anaconda
ref) https://anaconda.org/conda-forge/youtube-dl

```
conda install -c conda-forge youtube-dl
```

###pip（未検証）
ref) https://github.com/ytdl-org/youtube-dl/blob/master/README.md

```
sudo -H pip install --upgrade youtube-dl
```

#import

```python
import youtube_dl as ydl
```

#動画DL

動画DLにはydl.main()メソッドとydl._real_main()メソッドがある．
ソースを見ればわかるが，前者は後者のラッパーで，追加で例外処理を行う．後述の理由からここでは後者のメソッドを使う．
引数には色々指定できるが(<a href=https://github.com/ytdl-org/youtube-dl/blob/master/README.md>本家git参照</a>)，オプション指定子とその実態との間にスペースを入れるとそのスペースも実態に含まれるので注意．

```python
myURL = "https://www.nicovideo.jp/watch/so23335421" #保存したい動画のURL
myOUT = "-oout.mp4" #出力動画ファイル名指定

def main():
    try:
        ydl._real_main([myURL, myOUT])
    except ydl.DownloadError:
        main()

main()
```

4分以上のニコニコ動画をDLするとき，ydl.DownloadErrorクラスのエラーが出るのだが（実態はurlibのエラーで，執筆時点のyoutube-dlではこのエラーを回避できないように思われる<a href=https://obel.hatenablog.jp/entry/20191102/1572693444>[参考]</a>），実はメソッドを繰り返せば続きからDLでき，DLが完了すれば当然エラーが出なくなる．よってydl._real_main()がydl.DownloadErrorを吐き続ける間は再帰的にydl._real_main()を実行させ続けることでエラーを見ずに済むようになる．

#備考
youtube_dlモジュールはsys.exitを多用しているので，jupyter notebookできちんと動そうとしたり，他のプログラムと組み合わせて動かしたいならソースを変えなければならないかも?<a href=https://hira98.hatenablog.com/entry/2019/07/02/210000>tryブロックで呼べばなんとかなるかも</a>．
Macで半角クォーテーションの自動変換を無くす

「システム環境設定」>「キーボード」と選択し、「ユーザ辞書」をクリックする。
以下項目を下記画像のようにプルダウン選択を変更する
・二重引用符
・一重引用符
<img width="668" alt="スクリーンショット 2020-05-05 21.28.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518921/cd73c8cd-8faf-14f1-36e1-6e6320584ba8.png">
お名前.comレンタルサーバーにExmentをインストールする

[お名前.comのレンタルサーバーRS](https://www.onamae.com/server/rs/)に[Exment](https://exment.net/)をインストールしてみました。

Xserverとの相違点
https://exment.net/docs/#/ja/install_rental


#composerをインストールします。

```
curl -sS https://getcomposer.org/installer | php -- --install-dir=$HOME/usr/bin/

mv $HOME/usr/bin/composer.phar $HOME/usr/bin/composer

```

#Exmentのインストールを行います。

```
cd
mkdir laravel
cd laravel
wget https://exment.net/downloads/ja/exment.zip
unzip exment.zip
rm exment.zip
```

#シンボリックリンクを作成します。

```
ln -s $HOME/laravel/exment/public $HOME/public_html/(ドメイン名)/db
```

# htaccessの修正
「/laravel/exment/public」に存在する.htaccessに下記記述があると機能しない


```
#下記を削除
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>
```

#SSL化する
インストール時にhttpsの設定をし忘れた場合

```php:/laravel/exment/config/admin.php
 /*
    |--------------------------------------------------------------------------
    | Access via `https`
    |--------------------------------------------------------------------------
    |
    | If your page is going to be accessed via https, set it to `true`.
    |
    */
    'https' => env('ADMIN_HTTPS', false),
↓
   'https' => env('ADMIN_HTTPS', ture),

```

#アップデートする

```
#プロジェクトのルートディレクトリへ移動
[ ~]$ cd laravel/exment


#初回のみ
[ exment]$ wget https://exment.net/downloads/cmd/ExmentUpdateLinuxSakura.sh
Saving to: 'ExmentUpdateLinuxSakura.sh'

100%[==================================================================================>] 357         --.-K/s   in 0s

 'ExmentUpdateLinuxSakura.sh' saved [357/357]


#初回のみ
[ exment]$ chmod 775 ExmentUpdateLinuxSakura.sh


#2回目以降は下記コマンドでアップデート実行
[ exment]$ sh ExmentUpdateLinuxSakura.sh


Execute Update
Could not open input file: artisan
Finish Update!

```

以上
グーグルスプレッドシートの関数で『ダブルクォーテーション（”）』を文字列として認識させる方法

グーグルスプレッドシートの関数内で「”」（ダブルクォーテーション）を文字列として指定する場合は、<b>ダブルクォーテーションを2つ続けて記入する</b>必要があります。

今回、ダブルクォーテーションをなかなか文字として認識させられずに手間取ったので、そのやり方をまとめておこうと思います。


<h2>ダブルクォーテーションを2つ連続で記入する</h2>

通常、スプレッドシートの関数内で文字列を直接指定する場合は、文字列をダブルクォーテーション（”）で括る必要があります。

では、ダブルクォーテーションそのものを文字列として指定する場合は、どうすれば良いのでしょうか？

たとえば、以下の条件の関数を組む場合。

<BLOCKQUOTE>＜条件＞
・A1セルが空白ならば『 ”A” 』と記載する
・A1セルが空白出なければ『 ”B” 』と記載する</BLOCKQUOTE>

ここで、何も考えずに関数を組んでしまうと、『#ERROR!』と表示されてしまいます。

<BLOCKQUOTE>＜これだとエラーになる＞
=if(A1=” ”, ” ”A” ” , ” ”B” ”)</BLOCKQUOTE>

この問題を解決するには、文字列として認識させたいダブルクォーテーションを2つ連続で記入（””）する必要があります。

つまり、上の例では以下のように関数を記入しなければなりません。

<BLOCKQUOTE>=if(A1=” ”, ” ””A”” ” , ” “”B”” ”)</BLOCKQUOTE>

これならば、条件通り、A1が空白ならば『”A1”』、空白でなければ「”A2”」が表示されます。


<h2>まとめ</h2>

関数内で「”」（ダブルクォーテーション）を文字列として指定する場合は、ダブルクォーテーションを2つ続けて記入する必要があります。

「”」が多くなってややこしいですが、、、ぜひ試してみてください。
<h2>インターン生を募集しています！</h2>
私たちは今、<a href="https://heuvel.jp/">フーブル</a>を運営しています。

こちらでは現在、年齢性別問わず、インターン生を募集しています。

Webマーケをしたい！メディアを運用してみたい！という人に必見の内容です。

興味がある方は、<a href="https://www.wantedly.com/users/136771595/post_articles/240240">Wantedly</a>から応募してみてください！
*.tfvars を勝手に読ませる

[ドキュメント](https://www.terraform.io/docs/configuration/variables.html)読んでたら偶然見つけたんだけど、なんで今までしらなかったんだろう。以下の規則に沿うことで `-var-file` オプションを省略して自動で `*.tfvars` を自動で読み込むことができる。

### 方法1

ファイルの名前を `terrarom.tfvars` もしくは `terraform.tfvars.json` にする。


### 方法2
ファイル名を `*.auto.tfvars` もしくは `*.auto.tfvars.json` みたいなファイル名にする。

# おわり
networkに関して

# 概要
これはAWSでのネットワークの設定をする際に個人的に気になった概念・単語をまとめたページ
都度更新予定
参考:[Terraformで構築するAWS](https://y-ohgi.com/introduction-terraform/)

# 気になった単語
## Internet Gateway(IGW)
パブリックsubnetのprivate IPとpublic IPの対応を設定したもの
これがあることで外部との通信が可能になる．

参考:[【図解/AWS】インターネットGWとNAT-GWの違い〜各メリット、パブリックサブネットとは〜](https://milestone-of-se.nesuke.com/sv-advanced/aws/internet-nat-gateway/)

## Route Table
networkの対応表
vpc, 対応させるsubnet, 使用するIGWを設定する
asdfを使用してDenoのバージョンを管理する

本記事では、asdfを使用してDenoのバージョンを管理する方法について記載します。

## asdfとは

[asdf](https://github.com/asdf-vm/asdf)を使用すると、様々なプログラミング言語処理系のバージョンを管理することができます。

もしインストールされていなければ、以下のあたりを参考にインストールしてください。

- [公式サイト](https://asdf-vm.com/#/core-manage-asdf-vm)
- [【言語バージョン管理】asdf使おう(erlang/elixir, node, etc...)](https://qiita.com/ymtszw/items/28cc7a000236510b71c2)

## 環境

以下のバージョンで確認しました。

|項目|バージョン|
|:---:|:---:|
|asdf|v0.7.4|

## asdf-denoをインストールする

asdfはインストールされていることを前提に話を進めていきます。

asdfでDenoのバージョンを管理するためには、[asdf-deno](https://github.com/asdf-community/asdf-deno)プラグインをインストールする必要があります。

まず、asdf-denoをインストールします。

```sh
$ asdf plugin-add deno https://github.com/asdf-community/asdf-deno.git
```

これで、asdf-denoがインストールされます。

以下で確認してみましょう。

```sh
$ asdf list deno
No versions installed
```

`No versions installed`が出れば、インストールに成功しています。

## Denoをインストール

それでは、試しにDenoのv0.42.0をインストールしてみます。

```sh
$ asdf install deno 0.42.0
```

インストールに成功したら、以下を実行します。

0.42.0が表示されれば、インストールに成功しています。

```sh
$ asdf list deno
  0.42.0
```

インストールしただけでは、まだそのバージョンを使用することができません。

以下を実行して、そのバージョンを有効化する必要があります。

```sh
$ asdf global deno 0.42.0
```

これで、v0.42.0が有効化されます。

以下を実行して、確認してみましょう。

```sh
$ deno --version
deno 0.42.0
v8 8.2.308
typescript 3.8.3
```

## バージョンの切り替え

バージョンの切り替えは、インストールと同様の手順で行えます。

試しにv0.41.0へ切り替えてみます。

以下を実行し、v0.41.0をインストールします。

```sh
$ asdf install deno 0.41.0
```

v0.41.0がインストールされたことを確認します。

```sh
$ asdf list deno
  0.41.0
  0.42.0
```

v0.41.0を有効化します。

```sh
$ asdf global deno 0.41.0
```

バージョンが切り替わったことを確認します。

```sh
$ deno --version
deno 0.41.0
v8 8.2.308
typescript 3.8.3
```

これで、バージョンの切り替えに成功しました。

## アンインストール

以下のコマンドを実行すると、特定のバージョンのDenoをアンインストールできます。

```sh
$ asdf uninstall deno <version>
```

試しに、v0.41.0をアンインストールしてみます。

```sh
$ asdf uninstall deno 0.41.0
```

対象のバージョンがアンインストールされていることを確認します。

```sh
$ asdf list deno
  0.42.0
```

## 参考

以下を参考にいたしました。

- [asdf-deno](https://github.com/asdf-community/asdf-deno)
- [【言語バージョン管理】asdf使おう(erlang/elixir, node, etc...)](https://qiita.com/ymtszw/items/28cc7a000236510b71c2)
Twilioを使ってスモールビジネス向けのテレアポシステムを作ってみた

自分で作ったサービスや受託開発案件のテレアポ営業をフリーランスの営業さんにお願いしたいのですが、
・実際にどんな感じで営業しているのか? 優秀そうか?
・後からトラブりそうなこといってないか?システムの仕様についてとか。
・ちゃんと申告どおり仕事をしてくれているのか?
・お客さんとのいった言わない問題を防ぎたい
などの理由で通話内容を管理したいなと思いました。
そこでtwilioを使って簡易的なコールセンターシステムを作りました。


### 主な機能
- 営業対象リストの表示
- リストから対象を選択して、ブラウザからお客様に電話
- 通話内容の録音
- 通話ステータス(未対応、保留、完了)の登録
- 通話メモの入力    
＊ 足りてない機能いろいろあるので、提案やPRお待ちしてます。

![screenshot](https://raw.githubusercontent.com/shrft/sales-call-manager/master/doc/images/callcenter-m.gif)

### 使用している技術
- PHP7/Laravel
- twilio (web上で電話をかけるためのクラウドサービス)

### twilioとは?
twilioは電話の機能を簡単にアプリやウェブサイトに組み込むことができるAPIです。
料金は、5円/分程度です。
[料金表](https://cloudapi.kddi-web.com/price/)    

### 利用方法

1. twilioのアカウントを作成し、電話番号を取得してください。
以下のページの最初のTwilio電話番号を取得までやればOKです。
https://jp.twilio.com/docs/usage/tutorials/how-to-use-your-free-trial-account

2. twilioのプロジェクトを作成します
以下のサイトにアクセスし、FRIENDLY NAMEに任意の名前を設定し[Create]をクリックします。
https://www.twilio.com/console/voice/twiml/apps/create

2. レポジトリをクローンします

```
$ git clone https://github.com/shrft/sales-call-manager
```

4.レポジトリ配下に移動しセットアップを実行します

```
$ cd sales-call-manager
$ cp .env.example.ja .env
$ composer install
$ npm install
$ npm run dev
```

5.```.env```ファイルの中身を更新します。     
書き換えるところは.envファイルを見てください。    

6.アプリケーションキーの生成

```
php artisan key:generate
```
7.databaseの作成
callcenterという名称でデータベースを作成してください。
.envのDB_DATABASEをcallcenterから変更した場合はその名前で作成してください。

8.テーブルの作成とサンプルデータの作成

    php artisan migrate
    php artisan db:seed

9.サーバーの起動

    php artisan serve --host=127.0.0.1

10.以下にアクセスしてお客様一覧が表示されることを確認
http://127.0.0.1:8000/call-list
11.外部からアプリケーションにアクセスできるようにする

    ngrok http -region=jp 8000

12.twilioのプロジェクトページを開く
https://www.twilio.com/console/voice/twiml/apps
13.コールバックURLを設定し[SAVE]をクリック
 Voice->REQUEST_URLの欄に以下を設定
 `https://[ngrokのURL]/twilio/call`
 上記のURLはngrok実行時に表示されます。httpsのほうを入力してください。
    ```Forwarding http://abcdefg.jp.ngrok.io -> http://localhost:8000 
    Forwarding https://abcdefg.jp.ngrok.io -> http://localhost:8000 
    ```
14.以下のURLにアクセスし、任意の電話番号を入力し、電話をかけるボタンをおします
https://[ngrokのURL]/call-list/1
電話番号は国際番号つきで入力してください。
例: 080-0000-0000 にかける場合 => 818000000000
＊ トライアルアカウントだと電話の最初に英語のメッセージが流れる。無視でOK。

15.録音を聞いてみる
以下にアクセスして再生ボタンをクリックしてみてください。
https://www.twilio.com/console/voice/dashboard

＊ ngrok経由だと動作が重くてうまく動かない場合があります。
そういった場合は、何度もreloadすればうまくいきます。
SSL証明書( Let’s Encrypt )の更新をcronで自動化するための、crontab内の記述


https://hi3103.net/notes/web/1082
を参考に、
0  3  *  *  * root /usr/bin/certbot renew
のように、SSLを自動的に更新する記述を、「crontab」に、行いたいです。


Macのコンソールを開いて、
「crontab」を編集して、


>SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root 
HOME=/        
 # For details see man 4 crontabs 
         # Example of job definition: 
 # .---------------- minute (0 - 59)
 # |  .------------- hour (0 - 23) 
 # |  |  .---------- day of month (1 - 31)
 # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ... 
 # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR 
 sun,mon,tue,wed,thu,fri,sat 
 # |  |  |  |  | 
 # *  *  *  *  * user-name command to be executed
**00 04 01 * * root /usr/local/bin/certbot-auto renew --post-hook "sudo service httpd restart"**

のように、最後の行に、
毎月の1日、04時00分に実行
するような記述をして、保存して終了するところまで設定しました。

変更したのは、太字の最終行だけを追加した形です。

crontab内の記述を、最終行に上記の1行だけを追加して、保存した形なのですが、
SSL証明書( Let’s Encrypt )の更新をcronで自動化するための記述として、合っているか？
について、アドバイスを頂くことが出来ますと有り難いです。

お詳しい方がいましたら、是非、ご助言を頂くことが出来ますと幸いです。
(特に、certbot-auto renew --post-hook "sudo service httpd restart"の
部分が、
certbot renew
のみしかかかれていない設定方法がブログなどに書かれている場合も有り、
SSL証明書( Let’s Encrypt )の更新として、合っているか？について
お詳しい方が、いましたら、どうぞよろしくお願いします。)

どうぞよろしくお願いします。
LaravelのGoogleログインの実装で「エラー 400: invalid_request」となる

# 問題点
ローカルホストでgoogleログインをしようとしたら、Googleのclient_idが読み取れてないというエラーが出た。
![スクリーンショット 2020-05-05 20.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223280/d4940237-63b8-535d-fec9-cc8498937e51.png)

## 環境
Laravel 6.8
PHP 7.4
Docker
laravel/socialite 3.2
Google API Consoleの設定完了済み ↓↓
https://console.developers.google.com/project

## 解決方法
services.phpの google設定方法を変える

```:×上手くいかなかった設定方法
    'google' => [
        'client_id' => env('〇〇.apps.googleusercontent.com'),
        'client_secret' => env('〇〇'),
        'redirect' => env('APP_URL') . '/login/google/callback',
    ],
```

```:○上手くいった設定方法
    'google' => [
        'client_id' => '〇〇.apps.googleusercontent.com',
        'client_secret' => '〇〇',
        'redirect' => 'http://localhost/login/google/callback',
    ],
```
どうやら env()に囲まれた状態だと読み取られないことがあるようだったので、そちらを外しました！
Qiita内で投稿した記事をカテゴリ毎に表示する方法

#1.Qiitaを使って思ったこと
+ 技術メモとしてQiitaを始めてみたが記事がカテゴライズされない為後で見返すことが難しい事が解った
+ はてなブログ等他のブログだと投稿日やタグでカテゴライズされる

#2.Qiitaを使ってやりたいこと
+ 記事を後で見返したい

#3.解決方法
+ Qiita内の検索フォームに条件を入れて絞り込むことが出来ることが解った
++ 検索オプション

#4.Qiita内検索オプションの使い方

+ 4-1.タイトルに「Git」を含んでいる

```
title:Git
```

+ 4-2.本文に「Ruby」を含んでいる

```
body:Ruby
```

+ 4-3.コードに「function」を含んでいる

```
code:function
```
+ 4-4.「Rails」タグが付いている

```
tag:Rails
```

+ 4-5.hiwasawa が作成した


```
user:hiwasawa

```
+ 4-6.件より多くストックされている

```
stocks:>3
```

+ 4-7.2020-04-05 以降に作成された

```
created:>2020-04-05
```

+ 4-8.2020-04-01 以降に更新された

```
updated:>2020-04
```

+ 4-9.「tag:Ruby」を含まない

```
-tag:Ruby
```

+ 4-10.「Ruby」または「Rails」を含んでいる

```
Ruby OR Rails
```

#5.実例

+ 5-1.まずは自分のアップした記事を検索

```
user:hiwasawa
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631693/4d4fa8b4-a389-dfce-4293-89aec1892c87.png)


+ 5-2.自分のアップした記事内でpythonタグのついたものだけを検索

```
user:hiwasawa tag:python
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631693/fe6bf40e-e9c6-b1fc-80a8-0529a4735216.png)

+ 5-3.自分のアップした記事内でpythonタグ or Max-MSPタグのついた記事を検索(失敗例)

```
user:hiwasawa tag:python tag:numpy
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631693/2ad656da-d957-ca04-6181-fbc69bbb7b63.png)


+ 5-4.自分のアップした記事内でpythonタグ or Max-MSPタグのついた記事を検索(うまくいった)
　※ORよりもANDの方が優先される仕様らしい

```
user:hiwasawa tag:python OR user:hiwasawa tag:Max-MSP
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631693/7668b775-db7f-edfe-fc48-2bd9ced40447.png)
【Web RTC】Skyway APIを使ってビデオチャット・多人数配信アプリを簡単につくる

今回はSkyWayのAPIを使用して初心者でも簡単にビデオチャットのアプリや多人数に配信するようなアプリを簡単につくっていきます。

すでに存在するアプリとしてはapper.inがあるでしょう。

おなじURLに飛ぶだけで遠方とのビデオチャットができるようになる優れものです。が！最近有料化されてしまいまして、不便になってしまいました。。。

ので、代わりに自前で作ってみます。。

目次

- SkyWay APIとは
- API Keyの発行
- skywayのサンプルコードを落としてくる
- ローカルサーバでテスト / サーバーにデプロイ

##SkyWay APIとは

￼
NTTが開発しているWeb RTCという技術を使用したAPIです。
P2P通信というものを使ってWebページから簡単にビデオを使った通信が可能になります。P2Pとはサーバーを介さずに、パソコン１とパソコン２が簡単に通信できるようなものっていうイメージです。

P2P通信って昔結構ニュースになっていました。Winnyっていうソフトが2000年台初期にでてきて、それがこのP2P通信を使っていました。簡単にファイルの交換ができるがゆえに著作権とかを無視してゲームや漫画が落とせるわけですね。
またウイルスも簡単におくれます。便利っちゃむちゃくちゃ便利なんですが、当時は相当問題になりました。
なのでこの技術はどう使うか、なにを共有できるのかに関して注意しなければならないものですね。

ここでP2Pをもちいて生まれたのがWebRTC（Web Real-Time-Communication）という技術で、ここではリアルタイムのコミュニケーションが対象です。
危険なファイルの共有などはできないようになっているので、安全な使い方ができるようになりましたね。
より詳細に知りたい場合は
https://qiita.com/daitasu/items/ae21b16361eb9f65ed43
などを参照してみてください。

## API Keyの発行




https://webrtc.ecl.ntt.com/

Skyway APIのホームページに行って新規登録を行ってください。ここで開発者として登録を行います。

<img width="400" alt="Screen-Shot-2019-01-21-at-0.12.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221949/3a269c49-118b-0c9e-a28d-235fc2832a36.png">


Community Editionを選びましょう。よっぽど大きいサービスとしない限りはこちらの無料版がいいでしょう。

登録したら早速Applicationsのところから create a new Applicationを押して新しいアプリを作る宣言をしましょう。


￼<img width="400" alt="Screen-Shot-2019-01-21-at-0.14.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221949/4b7369fd-e155-17ec-2cb2-bff2414529cd.png">




￼

これでAPI Keyが発行されました。こちらはソースコードに書いておく必要があります。ので、コピーしておいてください。


<img width="400" alt="15479975767084.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221949/3f95570c-350b-9894-58b0-bb8b710e064b.png">

￼

あとavailable domain（利用可能ドメイン）のところで
localhost
を登録しておくのを忘れないようにしましょう。

## skywayのサンプルコードを落としてくる




https://github.com/skyway/skyway-js-sdk/tree/master/examples/

こちらのgit hubのページにskywayが公開しているサンプルコードがあります。
これらをcloneして自分のPCに落としてきてください。

fullmesh-videochat

ちなみにこれだと多人数向けのビデオチャットになりまして、p2p-broadcastだと配信システムになります。

fullmeshだと多人数で、が想定。SFUというのはP2P通信でありながらも、間にサーバーが入り、自分のパソコンや通信相手のパソコンにかかる負荷を減らしてくれます。
実際fullmeshで３つくらいタブを開いてビデオチャットを開始するとPCがむちゃくちゃ熱くなります（CPUが暴走するので）

￼<img width="400" alt="Screen-Shot-2019-01-17-at-22.38.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221949/780066a8-8907-5407-a677-86c6e44caf97.png">


ちなみに普通のp2pだと個人間でのデータ通信となるので、LINEの通話みたいな感じですね。

### おまけ：受信モード




受信モードにするとこちらの画面をオフにして、完全に映らないようにすることができます。
script.jsで

```javascript:script.js
room = peer.joinRoom('mesh_video_' + roomName, {
        mode: 'mesh'
});
```

とすることで、そのモードにすることができます。

これを工夫すると多人数配信アプリにすることができますね。。。！




### おまけ：SFUモード




SFUモードにすると、仲介のサーバが入ってきてCPUの負荷の軽減などをしてくれるようになります。

```javascript

room = peer.joinRoom('mesh_video_' + roomName, {
        mode: 'sfu'
});
```
で設定可能

## ローカルサーバでテスト / サーバーにデプロイ




MacだったらPythonやRubyのコマンドを使用して、簡単にローカルサーバを立ち上げることができます。

Python3系

```
python -m http.server 8080
```
Ruby

```
ruby -run -e httpd . -p 8080
```
これで、ローカルのアドレスにアクセスすると、うまくできるようになるかと思います！

この状態だとだれとも通信ができないのでサーバーにデプロイしてみましょう。
HerokuやFirebaseでいいかなと

以上になります。
【Python】pipについて調べる

pip freeze  > requirements.txt

pip freezeの意味について調べる
https://note.nkmk.me/python-pip-list-freeze/
pip listとpip freezeが比較される。
pip listの出力フォーマットはpipのバージョンや設定によって異なる場合があるが、pip freezeでは<package-name>==<version>というフォーマットで出力される。
このフォーマットはパッケージをまとめてインストールするための設定ファイルであるrequirements.txtのフォーマット。pip freezeをリダイレクション>でファイル出力して別の環境で使うと、同じパッケージを一括でインストールできる。

＝＝＝

pip freeze  > requirements.txtをうったら、以下のようなメッセージが出た

********************************************************************************
Python 2 is deprecated. Upgrade to pip3 as soon as possible.
See https://cloud.google.com/python/docs/python2-sunset
To suppress this warning, create an empty ~/.cloudshell/no-pip-warning file.
The command will automatically proceed in 5 seconds or on any key.
********************************************************************************
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop suppo
rt for Python 2.7 in January 2021. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-s
upport


requirements.txtに内容が反映されたので、特に問題はなさそうだった。

その後、ターミナルの接続が切れて、tensowflowのインストールができてなさそうだった。
解消されなかったので、何か原因があるのかも。
社会人エンジニアがプログラミングコンテストに参加してみたい#2

#パソコンの環境を整える
macbookを使用しています。

- xcodeをインストール
- jupyter notebookのインストール
- numpyのインストール

C/C++とPythonを使おうかと思います。
処理速度が早い言語、複雑な処理もサポートが豊富で簡単に組める言語です。

#最初にやること
Atcoderのチュートリアルをやりましょう。
作法を知らないと何もできません。

#職業エンジニアの人
ABCに参加してみましょう。
自分の立ち位置を知りましょう。
受験勉強と一緒です。
過去のセンター試験を解いて自分を知らねばなりません。

#初心者の人
[C++入門 AtCoder Programming Guide for beginners (APG4b)](https://atcoder.jp/contests/APG4b)をやりましょう。
プログラムを一から勉強しましょう。

#自分の結果
ABCを回答の６００点でした。
ABC回答のみだと一生灰色と呼ばれるグループだそうです。
あとCが少し怪しい、難しい問題になるとまずいかもしれない。

職業エンジニアの人が仕事に競技プログラムは関係ないっていう気持ちが分かります。
普通のエンジニアの仕事に関係ないです。
仕様書作成とかDB設計とかインフラとか一切関係ないです。

#とりあえずABCまでに必要なこと
ABCまでは条件分岐、ループ処理、入出力処理、バブルソート、再帰処理、STLとか基本ができたら解けます。
Dから壁があります。

#明日は
[AtCoder Beginners Selection](https://atcoder.jp/contests/abs)を解きます。
ABC問題は本当に完璧か確認しD問題対策を行っていきます。
プログラムの話は明日から書きます。
【PHP】Composerコマンド

Composerコマンドがわからないので調べた
プロジェクト単位で PHPのライブラリ（パッケージ）を管理します。
ライブラリ間の依存関係も解決してくれます。
PHPのパッケージ管理ツールです。利用するパッケージ（ライブラリ）間の依存関係も解決してくれます。
https://laboradian.com/php-composer/
elenium::WebDriver::Error::UnknownError: unknown error: Chrome failed to start: crashed.の対処法

## 開発環境
Ruby 2.5.1
Rails 6.0.2
ubuntu(WSL)

## 想定状況
ターミナルに`$ bundle exec rspec spec/system/tasks_spec.rb
`を入力すると以下のエラーが発生。

```

Failures:

  1) タスク管理機能 一覧表示機能 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
     Got 0 failures and 2 other errors:

     1.1) Failure/Error: visit login_path

          Selenium::WebDriver::Error::UnknownError:
            unknown error: Chrome failed to start: crashed.
              (unknown error: DevToolsActivePort file doesn't exist)
              (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)



          # #0 0x7f6845b4bd29 <unknown>
          # ./spec/system/tasks_spec.rb:11:in `block (4 levels) in <top (required)>'

     1.2) Failure/Error: Unable to infer file and line number from backtrace

          Selenium::WebDriver::Error::UnknownError:
            unknown error: Chrome failed to start: crashed.
              (unknown error: DevToolsActivePort file doesn't exist)
              (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)



          # #0 0x7f6845b4bd29 <unknown>

Finished in 2.41 seconds (files took 9.52 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/system/tasks_spec.rb:16 # タスク管理機能 一覧表示機能 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される

```

## やったこと
- [こちら](https://gist.github.com/upinetree/fb71a947cc100e7918b7b280485d620c)の対策Aと対策Bを行ったが、解消しない。

## 解決策
- Gemfileの`gem webdrivers`をコメントアウトする。

## 参考文献
- [WSL Ubuntu 上で chromedriver を使った System Spec を動かす](https://gist.github.com/upinetree/fb71a947cc100e7918b7b280485d620c)
Linux：systemdでの、DNSの置き換え。

systemdの走っているLinuxでは、DNSの置き換えは、
①
`/etc/systemd/resolved.conf`の、`#DNS=`と、コメントアウトされている所を

```
[Resolve]
DNS=8.8.8.8
```

のように、DNSサーバのIPアドレスを指定して、
②

```
systemctl restart systemd-resolved
```

で、適用。

③
```
systemd-resolve --status
```

で、確認します。

#不明な点

なお、デフォルトのDNSは、`systemd-resolve --status`で、先に出て来ませんでした。

systemdで提供されているリゾルバはローカルの127.0.0.53#53で、`nslookup`で名前検索しても、

```
$ nslookup facebook.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	facebook.com
Address: 31.13.82.36
Name:	facebook.com
Address: 2a03:2880:f10f:83:face:b00c:0:25de
```
としか出てきません。多分、①、②、③のステップを踏むと、systemd-resolved内部で書き換えたDNSサーバを呼び出すようになるのでしょう。