OmniAICreator/Qiita-1.07M huggingface dataset:
pythonによるcsvファイル読み込みとグラフ化

今回は自分用のメモとしてpandasを用いてcsvファイルを読み込み，読み込んだデータをグラフ表示することをまとめる．

#pandasによるcsvファイルの読み込み
今回は相対パスでプログラムとcsvファイルが同じディレクトリ内にある場合で示す．csvファイルについては気象庁のデータから月の日照時間データを使うことにした．

>[気象庁　過去の気象データダウンロード](https://www.data.jma.go.jp/gmd/risk/obsdl/)

pandasは日本語をうまく読み込めないので，csvファイルの日本語データを英語に直す必要がある．とりあえず今回はデータのうち日付と日照時間の合計のみを用いることにする．またデータを折れ線グラフでグラフ表示してみる．

```python:read_csv.py
import pandas as pd
data1 = pd.read_csv('data.csv')
#データの確認
print(data1)
#折れ線グラフで表示
data1.plot()
```

データの確認をすると一応の表の値は以下のように得られる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945232/e1bc0a34-58b0-6706-0a0c-f626f1d287cf.png)
さらに得られた折れ線グラフは以下のようになる．
![ダウンロード01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945232/947be0ae-e683-7dce-bd41-e8ffce76c8e9.png)

これ以外にもプロット方法については以下のようなことがコマンドがある．

```python:pandas_graph_command
data.plot() #折れ線グラフ
data.plot.bar(stacked=True) # 積み上げ棒グラフ
data.plot.scatter('date','time(hour)') # 列を指定して散布図
data['time(hour)'].plot.hist() # 列を指定してヒストグラム
```

とりあえずは以上です．
後は時間があれば内容を充実していこうと思います．

# 参考文献
>[interface 2021年6月号](https://interface.cqpub.co.jp/magazine/202106/)
>[京大　python 演習](https://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/245698)
【Nuxt.js】新規作成時Babelで大量のWARNが出てくるときの解消法

新しく[Nuxt.js](https://ja.nuxtjs.org/)の`version 2.14.6`でプロジェクトを立ち上げようとし、`yarn create nuxt-app <project-naem>`し、
インストール完了後、`yarn dev`で立ち上げたらコチラの`WARN`が大量に発生しました。

```
WARN  Though the "loose" option was set to "false" in your @babel/preset-env config, it will not be used for @babel/plugin-proposal-private-methods since the "loose" mode option was set to "true" for @babel/plugin-proposal-class-properties.The "loose" option must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled): you can silence this warning by explicitly adding        ["@babel/plugin-proposal-private-methods", { "loose": true }]
to the "plugins" section of your Babel config.
```
![スクリーンショット 0003-05-05 21.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163786/32b78873-8868-f14e-bab4-08b1185bf51e.png)


## WARNの内容を読んで見る
とりあえず翻訳してみる。

>
babel/preset-env 設定で "loose" オプションが "false" に設定されていますが、@babel/plugin-proposal-class-properties の "loose" モードオプションが "true" に設定されているため、@babel/plugin-proposal-private-methods では使用されません。 babel/plugin-proposal-class-properties、@babel/plugin-proposal-private-methods、および @babel/plugin-proposal-private-property-in-object (それらが有効な場合) では、"loose" オプションは同じでなければなりません。
をBabel設定の "plugins "セクションに追加してください。

`Babel`に何か関係がありそうです。
"loose" オプションが "false" に設定されているから"true"にしてくださいのような感じで書かれています。

## nuxt.config.jsに記入する
`Babel`の設定を変えるには公式サイトに書いてあります。
https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-build/#presets
これを参考に対応してみます。

```nuxt.config.js
  build: {
    babel: {
      presets({ isServer }, [preset, options]) {
        options.loose = true
      },
    },
  },
```
`build`内に`babel`の設定をします。`option`に先程の`warn`の内容の`loose`を`true`に設定します。
再度`yarn dev`すると、`warn`が消えました。

## eslintでエラー
`warn`は消えたのですが、`eslint`を入れているとソース上にエラーが出てきます。
![スクリーンショット 0003-05-05 21.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163786/f55630b9-787d-0873-841a-e1d8e16abe13.png)

エラー内容を読んで見るとこのような内容が出てきます。
`isServer`や`preset`を何も宣言してないので不要ですね。

```
var isServer: any
'isServer' が宣言されていますが、その値が読み取られることはありません。ts(6133)
'isServer' is defined but never used. Allowed unused args must match /^_/u.eslint@typescript-eslint/no-unused-vars)
```

## @babel/plugin-proposal-private-methodsの設定で対応する
`@babel/plugin-proposal-private-methods`の`loose`オプションを`true`にするだけなのでこちらに書き換えてみました。

```nuxt.config.js
  build: {
    babel: {
      plugins: [['@babel/plugin-proposal-private-methods', { loose: true }]],
    },
  },
```

これで`WARN`もソース内のエラー両方消えました。

`Nuxt`の`2.14.6`のバージョンを新規でインストールしたときに`babel`の`loose option`が`warn`になるようですね。
`2.14.6`以降で新規に作成するときは参考にしてみてください。
Heroku無料枠の限界に挑む！30分以上アクセスがなくてもスリープにならないようにやらしく設定する

# Herokuの無料枠だと、30分アクセスがないとスリープしてしまう問題をなんとかしたい...!!

https://www.shookuro.com/entry/2018/05/02/133225

>(Herokuの無料枠では)Web アプリに 30 分間アクセスがないとスリープします。
次にアクセスがあったときに Dyno を起動する必要があるので数秒程度、レスポンスに時間が掛かります。

# なぜやるのか

現在LINEボットを開発中で、無料で済ませたいためHerokuにデプロイしたのですが、Herokuの無料枠では30分何もアクセスがないとサーバーがスリープモードに入ってしまいます。一度スリープモードに入ってしまうと、再度起動までに予想外に時間がかかってしまい、ボットで返ってくるはずの返事が返ってこなかったり、LIFFブラウザを立ち上げてからページを開くまでに30秒ほどかかってしまったりと、このスリープが予想外に弊害になっていました。

ですが、ようは30分内になんらかのリクエストがアプリ側に送られればHerokuはスリープモードに入らないわけです。
ということで、Herokuのアドオン、「Scheduler」を使用して、10分に一回、Heroku側になんらかのリクエストを送る処理を実装することにしました。


# やり方

参考: https://haayaaa.hatenablog.com/entry/2019/03/01/222221

### ①Schedulerアドオンの追加
まず、ターミナルから` heroku addons:add scheduler:standard`をしてアドオンを追加します

```
 heroku addons:add scheduler:standard
```

※アドオンとは、プラグイン、拡張機能のようなものです。

###②Herokuのブラウザアプリにアクセスし、shedulerをクリック

![puffshare _ Hero (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619224/cf07853c-bf8c-8346-956c-741fdd1f9e6f.png)


### ③ Add jobをクリックし、10分毎にHerokuのデプロイ先URLにcurlコマンドでリクエストコマンドを送る処理を追加
![heroku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619224/b6e6949f-83ce-60e9-c7c5-2bf626d16ae0.png)

### (④ `% heroku logs -t`でログを確認)

ターミナルで`% heroku logs -t`を叩き、10分毎に以下のようなログが残っていたら成功です

```
2021-05-05T13:22:03.309820+00:00 app[api]: Starting process with command `curl https://hoge.herokuapp.com/` by user scheduler@addons.heroku.com
2021-05-05T13:22:19.636248+00:00 heroku[scheduler.5024]: Starting process with command `curl https://hoge.herokuapp.com/`
```

簡単〜
SkPy ― Python で Skype に投稿

## 概要

[SkPy](https://skpy.t.allofti.me/index.html) を使用して、Python から簡単に Skype へ投稿できます。
投稿のみにしか利用していないので、メッセージの送信のみまとめます。
Microsoft のオフィシャルなライブラリではないので、信頼性を求める場合は [Microsoft Bot Framework](https://dev.botframework.com) の使用を検討すると良いかもしれません。

## [インストール](https://skpy.t.allofti.me/guides/install.html#from-pypi)

~~~
pip install skpy
~~~

※ Anaconda を使用の場合は、仮想環境を使用して環境構築後、最後に pip install が良いようです。
詳しくは、以下、参照してください。

* [Using Pip in a Conda Environment](https://www.anaconda.com/blog/using-pip-in-a-conda-environment) 
* [Installing non-conda packages](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-pkgs.html#installing-non-conda-packages)

## ログイン

~~~
from skpy import Skype

sk = Skype(user, pwd)  # user: Skype username, pwd: Skype account password
~~~

## chat.id 取得

メッセージの送信時に、使用する id を取得します。

~~~
for chat in sk.chats.recent():
    print(chat)
~~~

SkPy ドキュメント「[Iterating chats](https://skpy.t.allofti.me/guides/chats.html#iterating-chats)」に実行結果があるので参照してください。

## メッセージ送信

~~~
channel = sk.chats.chat('19:*****.skype')	# 取得した id を指定
channel.sendMsg("Test")
~~~

ID で指定したグループチャットに 「Test」が表示されます。

## 補足

* 24時間 でセッションが切れるようです  
  24時間で、token が無効になるようなので、毎日同じ時刻に再接続しています。  
  試していませんが、Skype() の3番目の引数で path を指定するとセッション情報が保持されるようです。
  token が無効になると再接続という動作になるようです。  
  詳しくは、「[Rate limits and sessions](https://pypi.org/project/SkPy/#rate-limits-and-sessions) 」を参照してください。
2. 旧 Skype ID でのログイン失敗  
  昔から Skype で使用しているアカウントでログインができなくなったことがあります。  
  Microsoft の仕様変更が原因だったようで「[skpy GitHub Issue](https://github.com/Terrance/SkPy/issues/65)」を参考に試行錯誤しました。  
  旧Skype ID でサインインして、アカウントエイリアス(***@outlook.jp)を追加することで、ログインできるようになりました。  
  （他にもいくつか変更していますが、最終的に解決したときに変更したものがこれです。）  
  ログインできないときは、SkPy Guides 「[Logging in](https://skpy.t.allofti.me/guides/login.html)」も参照してみてください。
Atcoder ABC186 E - Throne : CRT 中国剰余定理

初めてのCRT入門。

https://atcoder.jp/contests/abc186/tasks/abc186_e

次のように言い換えられます。
$s, k, n$が与えられたとき、$s + kx \equiv 0 (\bmod n)$となる$x$を答えよ。存在しない場合、$-1$を答えよ。


CRTは、ある数$a$を考えたときに、$b_1, b_2, m_1, m_2$を与えることで(2つでなくて複数個与えることもできます)
$$a \equiv b_1 (\bmod m_1) \\\\
a \equiv b_2 (\bmod m_2) 
$$
となるすべての$a$および、$\bmod m$を求めることができます。

今回は次の２式を考えます。
- $kx \equiv 0 (\bmod k) $: $k$の整数倍を$k$で割った余りは0であることが明らかです。
- $kx \equiv (n-s) (\bmod n) $: 冒頭の式$s + kx \equiv 0 (\bmod n) $から$s$を右辺に移し、$kx \equiv - s (\bmod n) $とします。modの定義より、$kx \equiv n - s (\bmod n) $として良いです。

2つの式をCRTして$a,m$を得ればよいです。求めた$a$と$m$は$a$を答えとすればよいです。もしこれが、最初の最小の値ではなくて、$c$回目に座る回数なら、$a + (c-1)m$を答えればよいです。

# 実装
```Python
def egcd(a, b):
    if a == 0:
        return b, 0, 1
    else:
        g, y, x = egcd(b % a, a)
        return g, x - (b // a) * y, y
# https://qiita.com/drken/items/ae02240cd1f8edfc86fd
# a = b1 (mod m1)
# a = b2 (mod m2)
# となるような、 a = r (mod m) を返す
# m=-1のとき解なし。
def crt(bList, mList):
    r, m = 0, 1
    for i in range(len(bList)):
        d, x, y = egcd(m, mList[i])
        if (bList[i] - r) % d != 0:
            return [0, -1]
        tmp = (bList[i] - r) // d * x % (mList[i] // d)
        r += m * tmp
        m *= mList[i] // d
    return [r, m]

for _ in range(int(input())):
    n,s,k = map(int, input().split())
    r, m = crt([0, n-s], [k, n])
    if m == -1:
        print(-1)
    else:
        print(r // k)
```
https://atcoder.jp/contests/abc186/submissions/22332590
因数分解するゲーム「Wallprime」をAIで解いてみた

# はじめに
Wallprime(ワルプライム)という素因数分解をして壁をどんどん破壊していくスマホのゲームを、AIの物体検出を使用して解いてみました。
こんなゲームです。

<iframe width="560" height="315" src="https://www.youtube.com/embed/ZihsjJSQxm0?start=45" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

このゲームの画面をPythonのOpenCVを使用して映像を読み取り、Microsoft Azure Cognitive ServicesのCustom Visionを使用して物体検出して、その結果から素因数分解を行い、表示を行います。
# 作ったもの
作ったものはこのようなものになってます。
(打つのが遅くてあまりスコアは出せてません。。)
<iframe width="560" height="315" src="https://www.youtube.com/embed/-Ns-Qw2q0LQ?start=45" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# どうやって作ったか
Custom Visionを使用することで、「画像分類」や「物体検出」を行うことができます。また、クラウド上で、「アノテーション」、「学習」、「推論」の一連の流れを行うことができます。

作成したアプリケーションは、以下を行います。

- wallprimeで表示された数値の認識(Custom Vision)
- 認識した数値を素因数分解
- 認識した数値と素因数分解した数値を画面に表示

Custom Visionを使用して、アプリケーションを構築する流れは、一般的な物体検出を行うディープラーニングと同様で以下の流れになります。

- データ収集(wallprimeのアプリケーション画像を集める)
- アノテーション(数値の0～9のタグ付けを行う)
- 学習
- 推論

詳しい作り方と使用したソースコードはブログに記載しています。
https://remix-yh.net/1156/
# さいごに
AzureのCustom Visionを使うことで、AIを詳しくなくても簡単に作成することができました。(アノテーション含めて、半日くらい)
AIで物体検出をする全体像(アノテーションから推論まで)を知るという意味でも、面白くて良い題材かと思いますので、やってみてはいかがでしょうか。
０からのRubyインストールからRailsでアプリケーションフォルダ作成までの手順まとめ


これからRubyをインストールして、Railsを使ってアプリケーション開発をしていきたい初学者の方の役に立てるかもしれません。エラーで詰まっている方の参考になれたらいいなと思います。私はRuby：3.0.1とRails：6.1.3.1 をインストールしました、インストールまでの手順を残しておこうと思います(mac環境です)


まずはRubyのインストール、macos(Big Sur)にも元から入っていますが、バージョンが 2.6.0 くらいだったため、最新の 3.0.1をインストールしました。

https://qiita.com/hujuu/items/3d600f2b2384c145ad12

rbenvでRubyを入れる解説はこちらの記事がわかりやすかったです。
（ただHomebrewは入っている前提だったので、もし入れられてなければ
https://qiita.com/zaburo/items/29fe23c1ceb6056109fd
こちらの記事を参考にして下さい）


Rubyのインストールまで終えたら次はRailsを入れていきます。

ターミナルで

```
$ gem install rails
```

を実行します。しかし、私の場合

```
ERROR: While executing gem ... (Gem::FilePermissionError)
```

というエラーが出てしまいインストールできません
これはmacにデフォルトで入っているバージョンのRubyを使おうとして、パーミッションエラーが出てしまっていからだと思います

https://qiita.com/nishina555/items/63ebd4a508a09c481150

こちらの記事にPermissionErrorが出た時の対処法が載ってあります


先程　`$ rbenv global 3.0.1`　とした事で勝手に、インストールしたRubyのバージョンを使えるようになったと思っていましたが、どうやら違ったようです

シェルがzshの方は `~/.zshrc` に、bashの方は `~/.bash_profile`にPATHを通さなければいけません

https://qiita.com/k3ntar0/items/eb8cdbd8eba9da388def

PATHの通し方はこちらがわかりやすかったです。私の場合は .zshrc ファイルが無かったので作成しました

ちなみに `~/.zshrc (~/.bash_profile)`ファイルというのは、シェルを起動する時に、環境変数や関数などの定義を自動で行ってくれる設定ファイルです。ここにPATHを通しておくと、通したファイルのパスのRubyのバージョンが、毎回自動で認識されて使えるようになります。

`$ open ~/.zshrc` でファイルに記述する内容は

```
[[ -d ~/.rbenv ]] && \
export PATH=${HOME}/.rbenv/bin:${PATH} && \
eval "$(rbenv init -)"
```

こちらになります。記述し終わったらシェルを再起動して、もう一度 `$ gem install rails ` をしてみるとインストールできました。


できたのですが、、、

`$ rails new practice_app`

としてpractice_appフォルダを作成しようとしても

```
Rails is not currently installed on this system. To get the latest version, simply 
type:

$ sudo gem install rails

You can then rerun your "rails" command.
```

というエラーが出てしまいます。言われたとおり
`$ sudo gem install rails`を実行してみます
インストールできました。というメッセージが出てきました、しかし　`rails -v`　を実行するとまた上記のエラーと同じメッセージを返されます

調べてみると、これは先程変更した .zshrc の反映がうまくいってなかった事が原因みたいです

そこで、ターミナルを再起動します。

解決できました。こんなに簡単に。笑

https://qiita.com/aki319809/items/9de7f14285cd0c69e2d2

こちらが解決方法の載ってあった記事になります


これで　`$ rails new practice_app`とすると作成できました！


少し長かったですが、私と同じ環境の方のエラー解決の力に力になれればなと思います。
Git コミットをまとめる

# 目的

- HEADからのコミットの個数を指定して複数のコミットを一つにまとめる方法を記載する

# 方法

1. 下記コマンドを実行する。

    ```terminal
    $ git rebase -i HEAD~HEADからのまとめるコミット数
    ```

1. エディタが開いたらまとめ元になりたいコミットを「pick」、「pick」コミットにまとめられたいコミットを「squash」と記載する。

# 具体例

1. `$ git log`コマンドを実行したときに下記の出力がなされている時のHEADのコミットとその一つ前のコミットをまとめる方法を下記に記載する。コミットIDが「70044e」のコミットをまとめ元とし、コミットIDが「b0bc13」のコミットをまとめたい。

    ```terminal
    [21:33:48]MacBook-Pro~/test/git_test$ git log
    commit b0bc1348910b0c4b9994c83466ab7288746d4414 (HEAD -> master)
    Author: 大川峻 <okawashun@MacBook-Pro.local>
    Date:   Wed May 5 21:14:15 2021 +0900
    
        テスト記載 1を追記
    
    commit 70044e6aa0856b3eca659e381c40a434668f8582
    Author: 大川峻 <okawashun@MacBook-Pro.local>
    Date:   Wed May 5 21:13:03 2021 +0900
    
        テスト用ファイルを追加
    
    commit bfac6cdc0e30e4c4badb9830d4644518d0d0406a
    Author: 大川峻 <okawashun@MacBook-Pro.local>
    Date:   Wed May 5 21:12:49 2021 +0900
    
        first commit
    ```

1. 当該リポジトリで下記コマンドを実行する。

    ```terminal
    $ git rebase -i HEAD~2
    ```

1. 開いたエディタで下記のように記載する。

    ![Untitled-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b6e4ab73-13f0-880c-4f57-d4e5b42298ec.png)

1. 一つ前のエディタで保存すると下記のエディタが開く。特に編集などせずに保存する。

    ![Untitled-2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/357f50c6-f64e-0313-8aa1-a91cf05e4df9.png)

1. `$ git log`を実行したところ下記のように表示され無事にコミットがまとめられた。（まとめたコミットのコミットの時間はまとめ元のコミット時間が適応されるようだ）

    ```terminal
    [21:33:48]MacBook-Pro~/test/git_test$ git log
    commit 0b334d2c1ca24e1a2af3484b15a32f0c37d8f547 (HEAD -> master)
    Author: 大川峻 <okawashun@MacBook-Pro.local>
    Date:   Wed May 5 21:13:03 2021 +0900
    
        テスト用ファイルを追加
        
        テスト記載 1を追記
    
    commit bfac6cdc0e30e4c4badb9830d4644518d0d0406a
    Author: 大川峻 <okawashun@MacBook-Pro.local>
    Date:   Wed May 5 21:12:49 2021 +0900
    
        first commit
    ```
データレイク(AWS)な記事

# はじめに

- https://aws.amazon.com/jp/builders-flash/202002/datalake-on-aws/?awsf.filter-name=*all

# データレイク?データウェアハウス?

「データを蓄積して分析するための環境」という意味ではデータウエアハウスもデータレイクも同じ

- データウェアハウス：「目的指向」のため、どういう分析をするのかという目的を決めてから、そのための環境として構築される
- データレイク：目的を持たずにデータを一元的に管理するもの

https://aws.amazon.com/jp/big-data/datalakes-and-analytics/what-is-a-data-lake/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/25da8d1b-7e49-4ece-b459-6ec12a7ae900.png)

# データレイクを構築するには?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/f8496d9d-bccf-f7bf-76cc-27c6295221df.png)

- まだデータレイク構築はしたことがないという IT エンジニアの方には、「`AWS Lake Formation`」というサービスをご紹介。
    - データレイクへのアクセス制御を一元で定義して管理し、データの機密性を強化するビジネスメタデータをデータに付けることで安全なデータレイクを素早く構築できる


# AWS CloudFormation を使ったデータレイクの構築

`AWS CloudFormation`を利用することで、AWS クラウド上に、安全で柔軟があり、かつコスト効率の高いデータレイクを短時間でデプロイできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/272705da-ee0c-78bf-de0f-b0612f2c7f03.png)

このテンプレートを実行すると、上記のように Amazon S3、AWS Glue、Amazon Elasticsearch Service、Amazon DynamoDB、AWS Lambda や Amazon API Gateway などで構成されたデータレイクが、デフォルト設定の場合であれば、約 30 分程度 (目安) で自動デプロイ可能

# より運用管理負荷が低いデータレイクを実現するには？

データレイクもサーバーレスで構築できる。
AWS では `Amazon Kinesis Data Streams` や `Amazon Kinesis Data Firehose`、`Amazon S3` などのサービスを使用したサーバレスデータレイクの設計、構築、および運用もできる。
~駆け出しのLinux復習~  「シンボリックリンク」とは何ぞや

駆け出しエンジニアが曖昧なLinuxを再度復習した内容の一部をアウトプットする記事です。
プログラミング学習を始めて初期の頃にLinux標準教科書をやりましたが、その頃は重要性にイマイチ気付いておらず、、、曖昧な部分が多いまま時間が経ってしまいました。
エンジニアを目指す上で、特にデプロイなどでのインフラ整備の際にLinuxは避けて通れないんだと強く感じました。。。
加えてLinuxを扱いこなせるのって「なんか、凄い格好良い」っていう単純な思考の持ち主であるが故、基礎をもう一度叩き込んで成長していこうと思った訳です、、、


「新しいLinuxの教科書」で学習した内容を基にアウトプットしていきます。

# シンボリックリンクとは何ぞや

### リンクとは
~~「ファイルの別名」にあたる。~~
~~ファイルに別名を付けること＝リンクを張る~~

### ハードリンクとシンボリックリンク
リンクには２種類あり、ハードリンクとシンボリックリンクがある。
~~両者は似て異なるが、主にシンボリックリンクが使用されるらしいので、ハードリンクについては割愛。~~

※捕捉を頂きました！
別名を付ける、という観点ではハードリンクとシンボリックリンクで比較すると、シンボリックリンクの方が使われているようですが、

厳密には**リンクとはファイル名とinode番号のつながり**のことであり、
その**リンクをディレクトリ上に登録する事をハードリンクと呼ぶ**ようです！（つまりファイルには必ず何かしら名前を付けるので、それ自体もハードリンク。ハードリンクは複数持たせる事が可能なので、別名をつける様な使い方ができる）

詳しくはコメント欄をご覧ください！ハードリンクについて参考にした記事も載せてます！

## シンボリックリンクとは
***「張られたリンク先へのパスが書かれた小さな特殊ファイル」***
あくまでパスが書かれているものであるため、本物のファイルとは全く別のもの。（この点でハードリンクと異なります）

これだけだとパッとしないですね。

## 使い方

```
ln -s [リンク元ファイル] [リンク名]
```

ハードリンクの際は -sオプションをつけないため、sってシンボリックのsかな？と解釈して覚えます。

例えば、カレントディレクトリに

```bash
$ ls
example.html

$ cat example.html
Hello World!
Helloooooooooooooo
```

こんな感じのexample.htmlというファイルがあったとして、このファイルにexampleというリンク名でシンボリックリンクを張ります。

```bash
ln -s example.html example
```

lsコマンドで確認してみましょう。

```bash
$ ls
example example.html   #exampleというファイルが作成されている

$ ls -l
lrwxr-xr-x  1 username  staff  12  5  5 19:13 example -> example.html
-rw-r--r--  1 username  staff   0  5  5 19:13 example.html
```

新たにexampleという名前のファイルが作成され、ls -lの出力結果からは、
example -> example.html　という感じで「どのファイルを指しているのか」を読み取ることができます。
つまり、**exampleと言ったらexample.htmlと言ってるのだと解釈することを意味しています**

試しにexampleを使ってみます。

```
$ cat example
Hello World!
Helloooooooooooooo
```

このように、example.htmlと言わずとも、リンク名を指示するだけで特定のファイルに辿り着くことができています。
これがシンボリックリンクです。

### シンボリックリンクの削除
リンクを削除する際は、通常ファイルを削除するのと同じ様にrmコマンドでOK
シンボリックリンクを削除したとしても、これはあくまでパスが書かれた特殊ファイルなので、元のファイルexample.htmlには何の影響もありません。

```bash
$ rm example # シンボリックリンクexampleを削除
```

逆に、シンボリックリンクがある状態で元のexample.htmlが削除されると、シンボリックリンクはリンク先のファイルが見つからないために破損状態になります。

## どこで使う
利用用途は様々あるようです。私自身まだ覚えたてなので知らないことも多いかと思いますが、特になるほどと思ったのは、**「長いパス名を省略できる」**という点です。

例えばRailsのタスク管理アプリケーションが深い階層の中にあったとします。（適当です）

```bash
home/work/project/rails/todo_app
```

ここまで深くは無かったですが、私自身、ポートフォリオを配置しているディレクトリに毎回移動してrails sとかを起動していました。
この場合、毎回これだけのパス指定してアプリケーションのディレクトリまで行くのって凄く大変ですよね、、、
そんな時にこのシンボリックリンクが役立ちます。
リンクを張ってみましょう。

```bash
# ルートディレクトリで
$ ln -s home/work/project/rails/todo_app todo_app
#　todo_appというシンボリックリンク名を張る

$ ls -l todo_app #確認してみます
lrwxr-xr-x  1 username  staff  32  5  5 20:58 todo_app -> home/work/project/rails/todo_app
```

この結果、todo_appと宣言するだけで、それがhome/work/project/rails/todo_appのことであると解釈してくれます。

```bash
$ cd todo_app
# これだけでルートディレクトリから一発で移動できる！
```

他にも、バージョン管理のためにも使われるそうです。複数のバージョンが存在するプログラムがあるとして、最新版を常に利用したいとかの場合に、最新版にだけ"latest"というシンボリックリンクを張っておくことで簡単に最新版のプログラムを利用できるようにするというものです。


# 終わりに
シンボリックリンク、便利だな〜と思いました。
凄く簡単な内容ですが、覚えておいて損はないと感じたのでアウトプットすることにしました。

エイリアスっていう言葉がよくプログラミング学習で出てきますが、それと似たようなものです。
「総理」「首相」って言われたら2021年5月現在では殆どの人がパッと「菅総理」を思い浮かべると思いますが、それと近いものですかね・・・？

ありがとうございました。
JavaScriptの繰り返し処理for文

JavaScriptの繰り返し処理for文について


```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>繰り返し処理</title>
  </head>
  <body>
    <script src="js/loop.js"></script>
  </body>
</html>
```

```JavaScript
for (var i = 1; i <=3; i++){
  console.log(i);
}
```
結果

![47a2beb25acafa1ca22efe7919d8eb1b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1301666/08fc1638-420b-ee73-bc50-b219211a67ec.png)

まず変数iに1が代入され、console.logが実行されます。変数iは１なので１と実行されます。
次に増減式のi++が実行されます。この時にiに1が足されるので2になります。
次にループ継続条件式が実行されます。この時にiは２なので<=3が成り立ちそのまま継続されます。
これを繰り返して、４回目になると4<=3となり条件式が成り立たなくなるのでここで終了となります。
結果出力は１、２、３となります。
Educational Codeforces Round 102 B. String LCM: Z-アルゴリズムを使った繰り返し文字列の判別

<b>Zアルゴリズムは不要ですが、初めて実戦で使ったのでメモ</b>

https://codeforces.com/contest/1473/problem/B

その文字列がある文字列を何回繰り返してできているのか？の判定が必要です。制約的に愚直に計算できますが、Zアルゴリズムを使って解きました。

# 題意
- ある文字列s,tが与えられる
- ここで、ある文字列strを考えたときに、別の文字列aをb回繰り返してstrが得られるとき、strはaで割り切れるとする。
    - 例えば、abababはab x 3回なので、abで割り切れ、 ababab x 1回なので、abababで割り切れる
    - 例えば、abcはabc x 1回でしか割り切れないので、abcでのみ割り切れる
- s,tで割り切れる最小の文字列を答えよ。存在しない場合は-1を出力せよ。

# こう考えた

考察は解説に任せます、この問題は`文字列のLCM(一般的なものではなく、この問題の範囲の中での言葉です)`を求める問題です。
上記例のようにこの問題は、整数の約数のように考えられます。<b>文字札s,tに共通に含まれる共有の約文字列(約数のようなもの)を求め、それぞれの個数のLCMを求めた回数繰り返す</b>。


# ポイント：ある文字列の約文字列（約数)の求め方
さて、この動作に必要なのは、以下のような情報を列挙することです。

- abababはab x 3回なので、abで割り切れ、 ababab x 1回なので、abababで割り切れる
- abcはabc x 1回でしか割り切れないので、abcでのみ割り切れる
以下のように考えます。
- あるn文字の文字列の1文字目からi文字目($1\leq i \leq n$)文字目を使って、元の文字列が作れるかを判定する
- この際、nがiで割り切れなければ、その文字列をつなげて作成できるものではないので候補にはならない
    - `ababab`は`abab`をマッチングの方法によっては2回含みますが、この問題の題意では、1回含むなら、`abab` ２回含むなら`abababab`になるので、`abab`から`ababab`を作ることはd系ません
- i文字の文字だけで構成される可能性があるなら、元の文字列の1～i文字目,  i+1 ～ 2i文字目 , ... , ki+1 ～ n 文字目にその文字が含まれるかを確認する

ここで、Zアルゴリズムを使います。

- iをnまでインクリメントさせながら、1-i文字目までと元の文字列を連結した文字列にZアルゴリズムを適応する
- 得られた配列を元の文字列の1文字目からstep iで回し、i以上であることを確認する
- すべてのforでi以上なら、その文字は1からi文字目までの繰り返しでできている。失敗すれば、1からi文字目までの繰り返しでその文字列を作ることはできない

# 実装

```Python
class zAlgorithm():
    def __init__(self, s):
        self.sdat = list(map(lambda x: ord(x), s))
        self.sl = len(s)
        self.res = [0] * self.sl
        self.res[0] = self.sl
        i, j = 1, 0
        while i < self.sl:
            while (i+j) < self.sl:
                if self.sdat[j] != self.sdat[i+j]:
                    break
                j += 1
            self.res[i] = j
            if(j == 0):
                i += 1
                continue
            k = 1
            while (i+k) < self.sl and (k+self.res[k] < j):
                self.res[i+k] = self.res[k]
                k += 1
            i += k
            j -= k
def stringDivisors(s):
    z = zAlgorithm(s)
    res = dict()
    for i in range(len(s) // 2):
        curTryLen = i+1
        if len(s) % curTryLen != 0:
            continue
        target = s[:i+1]
        t = s[:i+1] + ":" + s
        z = zAlgorithm(t)
        can = True
        for j in range(0, len(s) , curTryLen):
            if z.res[len(target) + 1 + j] >= len(target):
                continue
            can = False
            break
        if can:
            res[target] = len(s) // curTryLen
    res[s] = 1
    return res
import math
def lcm(x, y):
    return (x * y) // math.gcd(x, y)
q = int(input())
for _ in range(q):
    s, t = input(), input()
    sdiv = stringDivisors(s)
    tdiv = stringDivisors(t)
    reslen = 0
    resval = ""
    for k in list(sdiv.keys()):
        if k not in tdiv:
            continue
        tmps = str(k) * lcm(sdiv[k], tdiv[k])
        if len(tmps) > reslen:
            reslen = len(tmps)
            resval = tmps
    if resval == "":
        print(-1)
    else:
        print(resval)
```

https://codeforces.com/contest/1473/submission/104376007
x86_64のサブバージョンが登場した話

# x86_64の簡単な歴史
現在家庭用PCやサーバでよく利用されているCPUアーキテクチャはx86_64(AMD64, Intel64)です。x86_64は2000年にAMDが仕様を発表し、2003年から実装CPUが登場しています。
今から20年以上も前の規格なので、SSE, SSE2が標準とされていますが、それ以降の機能は規格に含まれていません。ですが、せっかく機能があるのですからなるべく新しい機能を利用して高速化を図りたいものです。
# 歴史の長さ故の問題
今でも`-march=skylake`（GCC, Clangの例）のように、コンパイル時にCPU世代を指定することでCPU最適化ビルドが可能です。しかしCPUの世代ごとに引数が変わるため引数の種類が極めて多く、選ぶのも困難です。面倒なので数えていませんが、GCCのドキュメントを読むとやたらと多いことがわかります。
https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
そのうえ、-marchオプションでコンパイルしてしまうと、別のCPUでプログラムが動かなくなることがあります。そのため広く配布されるバイナリはCPU最適化を行わずにコンパイルするのが一般的です。自分でビルドする場合でも、GitHubActionsやECS Fargateなど物理サーバが隠蔽されている環境では問題になります。
こうした環境では時々違うCPUのマシンにデプロイされ、日和見で実行エラーになる場合があります。こうした事情から、これまでCPU最適化はあまり利用されてきていませんでした。
# x86_64の世代分け
前置きが長くなりましたが、これに対応するため2020年にAMD, Intel, Red Hat, SUSEが共同でx86_64のバリアントを定義しました。これはCPU世代をある程度まとめて、その中で共通して利用できる機能を定義しているものです。具体的には現在以下のとおりです。
## x86_64-v2(Level A)
対応する機能：CMPXCHG16B, LAHF/SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3
だいたい2008年から2011年くらいのCPUがこれにあたります。コードネームではNehalemに近いです。そして2020年にリリースされたAtom Pシリーズもこのレベルです。
## Level B
対応する機能：x86_64-v2のすべて + AVX
Sandy Bridge世代に該当します。この世代は差が小さいので、あまり使われないだろうとのこと。この世代はx86_64-v*表記ではスキップされていてLevel表記だけです。
## x86_64-v3(Level C)
x86_64-v2のすべて + AVX + AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE
だいたいHaswell世代のCPUが該当します。

## x86_64-v4(Level D)
x86_64-v3のすべて + AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL
Xeon Scalable Processorが該当します。コードネームではSkylake以降です。

# コンパイラの対応状況
GCC 11, LLVM Clang 12以上でx86-64-v2, x86-64-v3, x86-64-v4が指定できるようになりました。今はまだこれらを利用したバイナリはほとんど出回っていませんが、そのうち各バリアント向けのバイナリも提供されるようになるでしょう。
GCC 11: https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
Clang 12: https://releases.llvm.org/12.0.0/tools/clang/docs/UsersManual.html

RedHat 9ではx86_64-v2をビルドターゲットにする予定とのこと。
https://developers.redhat.com/blog/2021/01/05/building-red-hat-enterprise-linux-9-for-the-x86-64-v2-microarchitecture-level/
CLionでのesp32開発に必要な環境整備

いろいろハマった（♦）のでメモを残したいと思います。

## 開発ボードを用意する

1. USB に差し込んで、`/dev`の下に `usbmodem` や `USBtoUART` などの名前が出ているか確認します。
1. 表示がなければ、ドライバーがインストールされてない可能性があります。SILABSのチップが乗っているかどうか確認します。
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657779/5a4d896f-b8d5-0579-7796-d805439619cf.png)
1. SILABSのチップがある場合、[Silicon Labs のダウンロードページ](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers)
   から適宜にダウンロードし、インストールします。
1. 再度USBに差し込んで、`/dev/cu.SLAB_USBtoUART` があると確認します。

## PlatformIO Core をインストールする

必ず [homebrew 経由](https://formulae.brew.sh/formula/platformio)でインストールします。

```
brew install platformio
```

[PlatformIO 本家のインストール指示](https://docs.platformio.org/en/latest//core/installation.html)に従うと、インストールされるPlatformIO Coreがうまく認識されません♦。

インストールが終わったあと確認します。

```
$ which platformio
/usr/local/bin/platformio
```
 
## Platformio プラグインを整備する

1. CLionの設定画面(`⌘`+`,`)を開き、左側から `Plugins` を選びます。
   <details>
<summary>スクリーンショット</summary>
![スクリーンショット 2021-05-05 20.27.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657779/598b5c46-c0ce-15ff-40c1-e3358d9598df.png)
</details>
1. platformio で検索してインストールします（iniというプラグインが必要です。聞かれたら、合わせてインストールします）。
1. CLionを再起動します
1. 再起動した後、再び設定画面を開きます。
1. 左側から `Languages & Frameworks` > `PlatformIO` を選びます。
   <details><summary>スクリーンショット</summary>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657779/aabf4893-f3c4-ab0c-f64b-881a0e7a7405.png)
</details>
1. platformio のインストール場所 `/usr/local/bin/platformio` を入力します。

## プロジェクトを作成しビルドする

1. メニューから `File` > `New Project` を選びます。
1. 左側から `PlatformIO` を選びます。
1. `Espressif` > `Espressif ESP32 Dev Module` > `espidf` を選びます（お持ちのボードに応じて適宜に選んでください）
   <details><summary>スクリーンショット</summary>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657779/a62bef85-6f42-e255-137a-ac36213698ac.png)</details>
1. [Create] を押します。
   プロジェクト作成に５分ぐらい時間がかかります。作成終了後 `src/main.c` が作成されます
1. `platformio.ini` を修正します。
    - `platform = espressif32@1.11.2` （♦重要。新しい espidf は使えません）
    - `upload_port = /dev/cu.SLAB_USBtoUART`（Windowsの場合は`COMnn`です）

platformio.ini 例

```ini
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp32dev]
platform = espressif32@1.11.2
board = esp32dev
framework = espidf
src_dir = src
upload_port = /dev/cu.SLAB_USBtoUART
```

ツールバーの「🔨ビルド」ボタンを押してビルドを開始します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657779/2212e088-043b-e016-f114-0cb1fb2d141e.png)

以上
JavaScriptで自動計算

## 自動計算機能の実装

自分用のメモです〜
正解かどうかは分かりません！！
が、ひとまず動いたので残しておきます。

```javascript

function calc (){
  const itemPrice = document.getElementById("item-price");
  itemPrice.addEventListener("keyup",()=>{
//取得した要素が入力されたら（keyup）イベント発火
    tax = parseInt(itemPrice.value * 0.1);
    const addTax = document.getElementById("add-tax-price");
    addTax.innerHTML = `${tax}円`
//taxはアイテムの値段.valudの10%を小数点以下切り捨て
//表示させる要素を取得して、innnerHTMLで上書き

    prof = (itemPrice.value) - (tax)
    const priceContent = document.getElementById("profit");
    priceContent.innerHTML = prof
  })
}

window.addEventListener('load',calc);


```

めちゃくちゃ頭抱えて悩んでたけど、めちゃくちゃ基礎でした。。
精進します。

以上
inputで入力した数字がうまく反映してくれない？ (今日のPython Day5)

## 0. はじめに
　参考書を読んで理解できてもいざ自分でコードを書こうとすると上手く行かないことがよくあります。一緒にアウトプットしませんか？
　毎日1問、Pythonの問題を出題します。出題範囲は特に定めていませんがはじめの1ヶ月くらいは『入門Python3　第2版』の第1～11章までのことが分かれば解ける問題にしたいと思います。「こういう問題を作って欲しい」などのリクエストがございましたら初心者ながら頑張って作問します。また「別解を思いついた」、「間違えを見つけた」などがありましたら遠慮なくコメント欄にて教えて下さい。記事を執筆している当人もこの記事を読んでくださった方も新たなことを学ぶことができるので。

## 1. 問題
　以下のように、数字の1を入力すると「私も！」が、数字の0を入力すると「そいういときもあるよ」と表示されるプログラムを太郎君は作成した。しかし1と0を入力しても「正しい数を入力してください」と表示されてしまう。太郎くんに代わってプログラムを直そう！

```python
print("pythonが楽しいと思う人は1を、楽しくないと思う人は0を入力してください。")
ans = input()
if ans == 1:
    print("私も！")
elif ans == 0:
    print("そいういときもあるよ")
else:
    print("正しい数を入力してください")
```

##2. ヒント
ansの型がどうなっているか確認してみましょう。

##3. 解答

```python
print("pythonが楽しいと思う人は1を、楽しくないと思う人は0を入力してください。")
ans = int(input())    # int()を追加する。
if ans == 0:
    print("私も！")
elif ans == 1:
    print("そいういときもあるよ")
else:
    print("正しい数を入力してください")
```

##4. 解説
　input()関数を用いて入力された値は文字列になります。今回の問題では入力された値が整数の0か1かを判断したいのでansを文字列から整数に変換するためにint()関数を追加する必要があります。

##5. おまけトーク
　プログラミング習いたての人に説明するのって難しいですよね。例えば今回の記事も最初は「input関数の戻り値は文字列になります。」のように書こうとしたのですが、「戻り値って何？」となりそうだなと思いやめました。「戻り値なんて分かって当然だろ。初心者だからといってバカにするな！」と言われそうですが、念には念を入れました。
【rails6】結合テストコードエラー　expected ◯◯◯◯, but was not given a block　の解決

みなさんこんばんは！
今日も結合テストコードのエラー解決について記載していきます

## 本日対面したエラー
```
ターミナル
Failure/Error: expect(find_link('削除する',  href: article_path(@article1)).click).to change{Article.count}.by(-1)
       expected ◯◯☆☆◯◯, but was not given a block
```

・・・「◯◯☆☆◯◯がブロックで渡されてないよ！」という日本語訳となります

では、原因のテストコード記述を確認してみましょう！

```article_spec.rb
# 投稿を削除するとレコードの数が1減ることを確認する
expect(find_link('削除する',  href: article_path(@article1)).click).to change{Article.count}.by(-1)
```

きっと皆様であればどこが間違っているのか、すぐにわかりますよね…

**間違っているのは、 expect( ) です、ここは expect{ } で結んであげないとダメなのです**

`changeマッチャでモデルのカウントをする場合のみ、expect()ではなくexpect{}を使いましょう`
と教わっていました…この箇所を忘れてしまったということですね…反省です…

では、直していきましょう

```article_spec.rb
# 投稿を削除するとレコードの数が1減ることを確認する
expect{find_link('削除する',  href: article_path(@article1)).click}.to change{Article.count}.by(-1)
```

ターミナルで実行します

```
Finished in 12.24 seconds (files took 1.3 seconds to load)
3 examples, 0 failures
```
うん、当然ですが無事にテスト終了しました！

続きを書いていくことにします:ok_hand:
( )括弧いるいらない？

①はvue.jsの仕様としてメソッドの名前を指定するとなっている
②インラインメソッドハンドラ・・メソッド名を直接指定する代わりに、インライン JavaScript 式でメソッドを指定することもできます:
③二重中間の中ではcomputedプロパティは( )を付けない
④二重中間の中ではメッソドの呼び出しは( )をつける

```vuejs
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <div id="app">
    <button @click="countUp">+1</button> #①
    <button @click="countUp()">+1</button>#②
    <p>{{ counterComputed }}</p>#③
    <p>{{ counterMethod() }}</p>#④

</div>
<script>
  new Vue({
    el: '#app',
    data: {
     counter: 0
    },
    computed: {
      counterComputed: function() {
        return this.counter *2;
        }
      },
      methods: {
        countUp: function() {
          this.counter += 1;
        },
        counterMethod: function() {
          return this.counter *2;
        }
      }
  })
</script>
</body>
```
VS CodeのPHP Intelephense で拡張モジュールのサポートを追加する

## 対象

- Visual Studio Code (VS Code)の extension で PHP の Language Server である [PHP Intelephense](https://github.com/bmewburn/vscode-intelephense) を使っている人が対象です 

## やりたいこと

- intelephense で補完が効く PHP extension (拡張モジュール) を増やしたい

## 詳細

- intelephense を導入していると、PHP のよく使われる拡張モジュールのクラスについてはコード補完や定義表示のサポートをしてくれる(補完用のStubを有効にする)設定になっています
- しかし、デフォルトでStubが有効にされている extension は限られています(21/05/05時点で71)
- 実は設定を変更するだけでStubを有効にできる extension が多くあります(21/05/05時点でデフォルト71+107)

## 方法

- 今回は Redis の extension のコード補完・定義表示を設定することにします。設定前はクラス名に Hover しても定義が表示されず、 `Undefined type 'Redis'.` となっています。
  ![Screen Shot 2021-05-05 at 19.01.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627077/30547767-9d2c-fbd5-e86a-f15da3a41e74.png)

- VS Codeの設定画面を開きます (`Code > Preferences > Settings` または `Command(Ctrl) + ,`)

- User設定またはWorkspace設定のいずれかを選び、
  `Extensions > intelephense > intelephense Stubs` で
  `Add Item` をクリック、 有効にしたいモジュール名を入力します
  - [設定可能なモジュールのリスト](https://github.com/bmewburn/vscode-intelephense/blob/master/package.json#L151-L329)
  ![Screen Shot 2021-05-05 at 20.01.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627077/8baf20cc-f605-631d-35f1-cc1c625aadb2.png)
  - または、たとえばWorkspace設定の場合、 `.vscode/settings.json` を直接編集しても設定可能です。まとめてたくさんの extension の Stub を有効にしたいときは、こちらの方法が良さそうですね。
  ![Screen Shot 2021-05-05 at 20.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627077/8fc1cfb4-27d2-159a-237e-4a49fd30d8aa.png)

- 無事、定義が表示されるようになりました
  ![Screen Shot 2021-05-05 at 19.05.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627077/0a5efd5d-530c-de0c-927e-bc648408991e.png)

## 補足

- 技術的には、JetBrainsの [phpstorm-stubs](https://github.com/JetBrains/phpstorm-stubs)を利用しているようです
Typescript環境でReactを使ったWebアプリを作ろう

##事前準備
開発に入る前に以下が入っていない場合は先にインストールをしてください

###Node.jsがインストールされている確認
```terminal:Node.jsのバージョン確認
node -v
```

###yarnがインストールされているか確認
```terminal:yarnのバージョン確認
yarn -v
```


##プロジェクトの作成

プロジェクト名:react_practice

```terminal:プロジェクトの作成
npx create-react-app react_practice --template typescript
```
###確認
作成したアプリケーションのディレクトリに移動し、下記実行

```terminal:確認
yarn start
```

ブラウザが立ち上がり、Reactのロゴマークがクルクル回っていれば成功


##初期化
不要なファイルを削除し、整理します。
またそれに伴いそれらを使っていたところでエラーが発生するのでそれを修正します。

###削除する一覧
以下のファイルごと削除します。

####publicフォルダ
- favicon.ico
- logo192.png
- logo512.png
- manifest.json
- robots.txt

####srcフォルダ
- App.test.tsx
- logo.svg
- react-app-env.d.ts
- reportWebVitals.ts
- setupTests.ts

###削除する箇所
ファイルを以下のように書き換えます

####App.tsx

```tsx:App.tsx
import React from 'react';
import './App.css';

export const App = () => {
  return (
    <div>リセット済</div>
  );
}
```

####index.tsx

```tsx:index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {App} from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
```

ここでもう一度正常に動作するかどう確認してください。
正常に表示ができればOKです。
pandasの行のマスクはbool型を明示する

言いたいことはタイトルのままだけど、ちょっとだけ整理したのでまとめておく。

# 発生したトラブル

毎日値が変動する数百のデータがあり、その監視を行う必要ができた。
ただし、一度値が0になったらその後は監視しなくても良かったため、pandasで次のような表を作ってgit管理することにより、監視状況の確認をできるようにした。

|設定|チェック完了フラグ|
|---|---|
|2|True|
|1|False|
|0|None|

例えば最新のログが上記のような形式になっていた場合、次に監視するのはチェック完了フラグがFalse(まだ条件を満たしていない)とNone(今まで監視していなかった)のした2つの行になる。

これを抜き出そうとして、```if None:```が```if False:```と同じになるからと横着したらエラーを吐いた。


# コード

出たエラーと対処法もまとめて表記。

```python
import pandas as pd

f = pd.DataFrame([[2, True], [1, False], [0, None]], columns=["value", "checked"])

print(f)
print("-----")

# print(f[~f["checked"]])
# TypeError: bad operand type for unary ~: 'NoneType'

# print(f[f["checked"]])
# ValueError: Cannot mask with non-boolean array containing NA / NaN values

# print(f[f["value"]])
# KeyError: "None of [Int64Index([2, 1, 0], dtype='int64')] are in the [columns]"

print(f[~f["checked"].astype(bool)])

```

一番最初のコメントアウトが横着した結果。「~はNoneを含む入力には使えない」とのことだった。

二番目のコメントアウトはそれを踏まえた確認。「NA(None)を含むようなbool型ではない配列はマスクには使えない」とのこと。

なお、だからといって3つめのコメントアウトのようにbool型じゃない配列を入れたら今度は列のマスク用だと受け取るようだ。
(これを踏まえると、2番目の「マスク」って「列のマスク」である可能性がある)

正しくは、一番最後の行のようにastype関数で変換してやることだった。
それであれば下記のような結果が出力された

```
   value checked
0      2    True
1      1   False
2      0    None
-----
   value checked
1      1   False
2      0    None
```
could not lock config file C:/home/.gitconfig: No such file or directoryが出てPlease tell me who you areが解決できない

could not lock config file C:/home/.gitconfig: No such file or directoryが出てPlease tell me who you areが解決できない事態に陥りました。

結果、HOMEの環境変数が.gitconfigがあるディレクトリになっていなかったので変更すると解決しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/e2fd195a-bb4f-9116-aa11-c6ba970c1728.png)


今までこんなことせずとも良かったのでよくわからないエラーでした。
watcherを使ってx秒後にカウンターをゼロにする

watchは非同期処理によく使う
*ちなみにreturnは非同期処理では使えない。
*thisも非同期処理では使えない.vmを設定してvmを使って指定します。
*vm(ViewModelの略)をVueインスタンスの変数名としてよく使います。

setTimeoutは、 指定された処理を指定された時間後に1回実行します。
第一引数にはコード文字列か関数オブジェクトを指定します。第二引数には処理待ち時間もしくは実行間隔をmsecで指定します。

```vuejs
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <div id="app">
    <p>{{ counter }}</p>
    <button @click="counter += 1">+1</button>
    <p>{{ lessThanThree }}</p>

</div>
<script>
  new Vue({
    el: '#app',
    data: {
     counter: 0
    },
    computed: {
      lessThanThree: function() {
        console.log('Computed');
        return this.counter > 3 ? '3以上' : '3以下'
        }
      },
      watch: {
        counter: function() {
          var vm = this;
          setTimeout(function() {
          vm.counter = 0
          }, 3000)
        }
      }
  })
</script>
</body>
```

3秒経ったらカウンターはゼロに戻りました。
【Unity】敵の視野を疑似的に表示するギズモをつくった



![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516386/4ccef131-89f2-9c4e-f2dc-0b5b35aa2f68.png)
よくある扇状の視野範囲をギズモで擬似的に表示できます。
検知の方法は偉大なるこちらの方の記事を参考にさせていただくと良いと思います。
: [Unityで敵が主人公を検知する範囲を視覚内に限定する](https://gametukurikata.com/program/onlyforwardsearch)


```cs:Enemy_DetectionAI.cs
using UnityEngine;
public class Enemy_DetectionAI : MonoBehaviour
{   
    [SerializeField] private float searchRadius;
    [SerializeField] private float searchAngle = 130f;

   private void OnDrawGizmos()
    {
        Vector3 trans = transform.position;
        Gizmos.DrawWireSphere(trans, searchRadius);

        Gizmos.color = Color.red;
        float x, y, r, a;
        r = searchRadius;
        a = transform.eulerAngles.y + 90;
        x = r * Mathf.Cos(a * Mathf.PI / 180f);
        y = r * Mathf.Sin(a * Mathf.PI / 180f);
        Vector3 forwardPos = new Vector3(-x, 0, y);
        Gizmos.DrawSphere(trans + forwardPos, .1f);

        Gizmos.color = Color.green;
        float xr, yr;
        xr = r * Mathf.Cos((a + searchAngle/2) * Mathf.PI / 180f);
        yr = r * Mathf.Sin((a + searchAngle/2) * Mathf.PI / 180f);
        Vector3 rightPos = new Vector3(-xr, 0, yr);
        Gizmos.DrawSphere(trans + rightPos, .1f);

        Gizmos.color = Color.blue;
        float xl, yl;
        xl = r * Mathf.Cos((a - searchAngle/2) * Mathf.PI / 180f);
        yl = r * Mathf.Sin((a - searchAngle/2) * Mathf.PI / 180f);
        Vector3 leftPos = new Vector3(-xl, 0, yl);
        Gizmos.DrawSphere(trans + leftPos, .1f);

        Gizmos.color = Color.red;
        Gizmos.DrawLine(trans, trans + forwardPos);
        Gizmos.DrawLine(trans, trans + rightPos);
        Gizmos.DrawLine(trans, trans + leftPos);
    }
}
```
CypressでのE2Eテスト自動化で学んだ事

## はじめに
E2Eテスト自動化でCypressを使った際に学んだ事を備忘録として残しておく。

## Cypressとは
[ここを参照。](https://www.cypress.io/)
[Cypressを使ってみるにはここ。](https://docs.cypress.io/guides/getting-started/installing-cypress)

## Index
- [cy.contains()の使い方](#cycontainsの使い方)
- [データ駆動テストの実現方法](#データ駆動テストの実現方法)
- [自動テストの時にだけ起きてしまうエラーを無視する](#自動テストの時にだけ起きてしまうエラーを無視する)
- [〇〇されるまで待機するの実現方法](#〇〇されるまで待機するの実現方法)
- [cy.get('#hoge').then($el => {})の$elの正体](#cygethogethenel--のelの正体)

## cy.contains()の使い方
DOM指定を行う際に、どうしても文字列で検索して指定したい場面も出てくる。
その際に`cy.contains()`コマンドは便利だが、これは`cy.get('…').contains('hoge')`のように`cy.get()`コマンドの後に用いるようにする。
理由としては以下の2つ。

- containsで文字列を検索してDOMを指定する際に、検索対象のDOM範囲を制限し、意図しない動きにならないようにするため
- getではDOMレンダリングまで暗黙的な待機処理が行われるが、containsでは暗黙的な待機処理がないため、DOMレンダリング前に動いてしまい要素が見つからないというエラーが起きやすくなる

| 推奨 | 非推奨 |
|:-:|:-:|
| cy.get('#id').contains('hoge')  | cy.contains('hoge') |

## データ駆動テストの実現方法
テストでは同じシナリオを異なるデータで実行したいという場面は多く、そんな時にはデータ駆動テストを実装する。
Cypressでもデータ駆動テストは実現でき、以下のように実装すればよい。

```ディレクトリ構成
cypress 
├── fixtures 
│   └── hoge.json 
├── integration 
│   └── data-driven-test.js
```

```js:data-driven-test.js
const datas = require('../fixtures/hoge')

datas.forEach(data => {
  before('', () => {
  })

  beforeEach('', () => {
  })

  it('', () => {
  })
})
```

### 参考文献
- https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/fundamentals__dynamic-tests/cypress/integration/fixture-spec.js

## 自動テストの時にだけ起きてしまうエラーを無視する
手動テストの際には起きないが、Cypressでの自動テストではエラーが起きるという時には、以下のようにする事でそのエラーを無視する事ができる。

```js:ignore-err.js
it('', () => {
  cy.on('uncaught:exception', (error) => {
    console.log(`${error.message}`);
    return false;
  })
})
```

## 〇〇されるまで待機するの実現方法
自動テストにおいては、ページ遷移などの際に〇〇が表示されるまで待機させたいという事が出てくる。
Seleniumでは`ImplicitWait`を使うと思うが、Cypressでは`cy.should()`コマンドを用いて実現する。

```js.implicit-wait.js
cy.get('#hoge')
  .should('have.text', hogehoge)
```

明示的にどれだけの時間を待機させるかを設定する事もでき、その場合以下のように書く。

```js.implicit-wait-define-time.js
cy.get('#hoge', { timeout: 5000 })
  .should('have.text', hogehoge)
```

## cy.get('#hoge').then($el => {})の$elの正体
以下のようにある要素にクラスが含まれている場合には、というif文を書く事もできる。
※$el：jQuery.fn.initオブジェクト

```js:sample.js
cy.get('#hoge').then($el => {

  // ある状態の時には〇〇を…という事ができる
  if ($el.className === 'selected') {
    // 何かのテスト
  }
})
```

## その他　ナレッジの宝庫
以下にはCypressを使ってテストをする際に、「これどうやるんだろう」となった時にとても参考になるナレッジがまとまっている。

- https://docs.cypress.io/examples/examples/recipes

## 関連記事
- [Cypressで躓いた所　クロスドメイン・iframe](https://qiita.com/yuta-katayama-23/items/80a7ce5c772af2548d9e)
画像のコーナー検出


# はじめに
OpenCVでコーナーの検出を行います。方法は主に```Harris Corner Detection Method```と```goodFeaturesToTrack Detection Method```の２つがあります。

使用する画像は次の画像です。```Rectangles.png```として保存して使用します。

![Rectangles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/78e911f4-8935-28fa-4ff6-beb1e9f52828.png)

# Harris Corner Detection Method

はじめに```Harris Corner Detection Method```を試します。

```harris.py
import cv2
import numpy as np


image= cv2.imread('Rectangles.png')
gray= cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

gray= np.float32(gray)

harris_corners= cv2.cornerHarris(gray, 3, 3, 0.05)

kernel= np.ones((7,7), np.uint8)

harris_corners= cv2.dilate(harris_corners, kernel, iterations= 2)


image[harris_corners > 0.025 * harris_corners.max()]= [255,127,127]

cv2.imwrite('Corner_detected_rectangles.png', image)
cv2.imshow('Harris Corners', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

- 処理後

![Corner_detected_rectangles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/7e24d68d-6b62-2f1c-beb5-7903da919c5c.png)

# goodFeaturesToTrack Detection Method

次に```goodFeaturesToTrack Detection Method```を試します。

```goodReatures.py
import cv2

img= cv2.imread('Rectangles.png')
gray= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

corners= cv2.goodFeaturesToTrack(gray, 100, 0.01, 50)

for corner in corners:
    x,y= corner[0]
    x= int(x)
    y= int(y)
    cv2.rectangle(img, (x-10,y-10),(x+10,y+10),(255,0,0),-1)


cv2.imwrite('Corner_detected_rectangles.png', img)
cv2.imshow("goodFeaturesToTrack Corner Detection", img)
cv2.waitKey()
cv2.destroyAllWindows()
```

- 処理後

![Corner_detected_rectangles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/34774a4d-7f14-31c9-13a3-6e414c14a0cd.png)


### 参考

https://ayatalog.hatenablog.jp/entry/2021/03/20/131603

https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%8A%E3%83%BC%E6%A4%9C%E5%87%BA%E6%B3%95

http://www.learningaboutelectronics.com/Articles/How-to-detect-corners-in-an-image-Python-OpenCV.php
Ubuntu 20.04 に最新のprotobufを入れてprotocでGoのコードを生成するまで

## 前書き
死ぬほど苦戦しました。
protobufの入れ方が幾つかあるのですが、上手くいかないものが沢山あり、ようやくインストールする方法が見つかりました。

### 前提

- go version go1.13.8 linux/amd64
- NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"


## protobuf
```bash
sudo apt install protobuf-compiler
```
だとバージョンが古すぎてAPIv2が使えません。

公式のリポジトリからコードを引っ張ってきてインストールすることになります。

>```bash
sudo apt install autoconf automake libtool curl make g++ unzip -y
git clone https://github.com/google/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
configure
make
make check
sudo make install
sudo ldconfig
```
引用 [Ubuntu 20.04に最新のProtobufをインストールする](https://qiita.com/reoring/items/0b9b6ce0623a4d8266f0)

`make`や`make check`等は劇遅です。
環境によっては1時間ほどかかるかも。

ターミナルを一度再起動して

```bash
protoc --version
```

で最新バージョンになっていればOKです。

### Goのライブラリ

```bash
go install google.golang.org/grpc
go install github.com/golang/protobuf/protoc-gen-go
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
```

### PAHTが通っていないのであれば

```bash
protoc-gen-go-grpc: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
```

このようなエラーが出る場合はPATHが通っていないので
`~/.bashrc`を開くor作成して

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

を追記

### 以上
後は任意のprotoに対してprotocコマンドを実行。
以上で生成できました。
Databricksのシークレットのスコープ

> [Databricksにおけるシークレットの管理](https://qiita.com/taka_yayoi/items/338ef0c5394fe4eb87c0)のコンテンツです。

[Secret scopes \| Databricks on AWS](https://docs.databricks.com/security/secrets/secret-scopes.html) [2021/4/12時点]の翻訳です。

シークレットの管理はスコープの作成からスタートします。シークレットのスコープは、名前で識別されるシークレットのコレクションです。一つのワークスペースにおいては、最大100のシークレットスコープを定義できます。

# 概要

Databricks管理のシークレットスコープは、Databricksで管理される暗号化されたデータベースに格納されます。シークレットスコープの名前は、

- ワークスペースで一意である必要があります。
- アルファベット、数字、ダッシュ(-)、アンダースコア、ピリオドから構成され、128文字以内である必要があります。

スコープ名には機密情報を含めるべきではなく、ワークスペースのユーザーに理解できるものである必要があります。

Databricks管理のシークレットスコープは、[Databricks CLI](https://docs.databricks.com/dev-tools/cli/index.html)(バージョン0.7.1以降)あるいは、[Secrets API](https://docs.databricks.com/dev-tools/api/latest/secrets.html)で作成することができます。

## スコープのアクセス権

スコープは[ACL](https://docs.databricks.com/security/access-control/secret-acl.html)によって管理されるアクセス権を伴って作成されます。デフォルトでは、スコープを作成したユーザー(作成者)に対して、作成者がシークレットの読み取り、スコープへのシークレットの書き込み、スコープのACLの変更ができるように、`MANAGE`権限が付与されます。[Premium plan](https://databricks.com/product/aws-pricing)を契約しているのであれば、スコープに対してより詳細なアクセス権を設定できます。詳細は、[Secret access control](https://docs.databricks.com/security/access-control/secret-acl.html)を参照ください。

スコープを作成した際に、明示的に全てのユーザーに`MANAGE`権限を設定することも可能です。実際のところ、[Premium plan](https://databricks.com/product/aws-pricing)を契約していないのであれば、全てのユーザーに`MANAGE`権限を与えるべきです。

# Databricks管理のシークレットスコープの作成

シークレット名は大文字小文字を区別しません。

Databricks CLIでスコープを作成するには以下を実行します。

```bash
databricks secrets create-scope --scope <scope-name>
```

デフォルトでは、スコープ作成者に`MANAGE`権限が付与されます。[Premium plan](https://databricks.com/product/aws-pricing)を契約していないのであれば、スコープ作成時に"users"(全てのユーザー)に`MANAGE`権限を与えるべきです。

```bash
databricks secrets create-scope --scope <scope-name> --initial-manage-principal users
```

Secret APIの[Put secret](https://docs.databricks.com/dev-tools/api/latest/secrets.html#put-secret)操作でも、Databricks管理のシークレットスコープを作成することができます。

[Premium plan](https://databricks.com/product/aws-pricing)を契約しているのであれば、あとでアクセス権を変更することが可能です。詳細は、[Secret access control](https://docs.databricks.com/security/access-control/secret-acl.html)を参照ください。

シークレットのスコープを作成すれば、[シークレットを追加](https://qiita.com/taka_yayoi/items/7e4eae0786b94cb7a5de)できるようになります。

# シークレットスコープの一覧

CLIを用いて既存のスコープの一覧を表示するには、以下を実行します。

```bash
databricks secrets list-scopes
```

Secret APIの[List secrets](https://docs.databricks.com/dev-tools/api/latest/secrets.html#list-secrets)操作でも一覧を取得できます。

# シークレットスコープの削除

シークレットのスコープを削除すると、スコープに適用されているすべてのシークレットとACLも削除されます。

```bash
databricks secrets delete-scope --scope <scope-name>
```

Secret APIの[Delete secret scope](https://docs.databricks.com/dev-tools/api/latest/secrets.html#delete-secret-scope)操作でも削除することが可能です。


### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
computedプロパティとメソッドの違い

computedは関連したイベントが発火しない限り発生しない。
メソッドは画面が何度も描画する度に計算している。

（１）カウンター「counter」と別のカウンター「otherCouner」を設置する。
（２）どちらもcomputedもメソッドもreturn　this.counterとしてcounterのみに連動。

カウンターやアザーカウンターを両方別々にいくつか押してみると


```vuejs
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <div id="app">
    <p>{{ counter }}</p>
    <button @click="counter += 1">+1</button>
    <p>{{ otherCounter }}</p>
    <button @click="otherCounter += 1">別の+1</button>
    <p>{{ lessThanThreeComputed }}</p>
    <p>{{ lessThanThreeMethod() }}</p>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
     counter: 0,
     otherCounter: 0
    },
    computed: {
      lessThanThreeComputed: function() {
        console.log('Computed');
        return this.counter > 3 ? '3以上' : '3以下'
        }
      },
    methods: {
      lessThanThreeMethod: function() {
        console.log('Method');
        return this.counter > 3 ? '3以上' : '3以下'
      }
    }
  })
</script>
</body>
```


結果
＋１を押した場合
![20210505-193951.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/902ec17d-9fa2-edd1-995b-8fafdaf05890.png)


別の＋１を何度か押した場合
![20210505-194014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/dd1de348-7c0b-edd3-d3c9-9f4d8df3524c.png)

メソッドのみ挙動を確認

**computedは関連したMODのイベントでした発火しない。**
**メソッドはこれとは違い二重中括弧の中にメソッドを書くと描画されるたびに実行される。**