OmniAICreator/Qiita-1.07M huggingface dataset:
ESLintをディレクトリ以下にインストールして使用する

# 概要
- nodeJSをインストールしてからESLineを使用できるようになるまでの設定方法
- ESLineはグローバルにインストールするのではなく作業ディレクトリ以下にインストールする

# 環境
- macOS Big Sur
- node 14.18.0
- npm 6.14.15

# 設定方法
## ディレクトリの準備

```
$ mkdir node_test
$ cd node_test
```

## package.json を作成する
- npm init して適宜設定していく

```
$ npm init
```

## ESLint のインストール
- eslint の本体は作業環境にインストールする ( -D | --save-dev )
- `node_modules/.bin/eslint` にリンクが生成される
- 実体は `node_modules/eslint/bin/eslint.js` にインストールされる

```
$ npm install eslint --save-dev
```

## ESLint の設定をする
- 対話形式で設定を行う

```
$ node_modules/.bin/eslint --init
```

- `enforce code style` を含めて `Use a popular style guide` にすると

```
? How would you like to use ESLint? …
  To check syntax only
  To check syntax and find problems
❯ To check syntax, find problems, and enforce code style
```
```
? How would you like to define a style for your project? …
❯ Use a popular style guide
```

- どのスタイルガイドを使用するか選択する
- この時に選択したスタイルガイドの設定がインストールされていない場合にはインストールする

```
? Which style guide do you want to follow? …
  Airbnb: https://github.com/airbnb/javascript
  Standard: https://github.com/standard/standard
❯ Google: https://github.com/google/eslint-config-google
  XO: https://github.com/xojs/eslint-config-xo
```
```
Checking peerDependencies of eslint-config-google@latest
The config that you've selected requires the following dependencies:

eslint-config-google@latest eslint@>=5.16.0
? Would you like to install them now with npm? › No / Yes
```

# 実行
## ファイルを作成
``` main.js
console.log("Hello World!!")
```

## ESLint の実行 ( テストのみ )
```
$ node_modules/.bin/eslint main.js

***/node_test/main.js
  1:13  error  Strings must use singlequote  quotes
  1:29  error  Missing semicolon             semi

✖ 2 problems (2 errors, 0 warnings)
  2 errors and 0 warnings potentially fixable with the `--fix` option.
```

## ESLint の実行 ( 上書きも )
```
$ node_modules/.bin/eslint --fix main.js
```
``` main.js
console.log('Hello World!!');
```
Atcoder Beginner Contest 221 D - Online games

#問題

[ABC221 D - Online games](https://atcoder.jp/contests/abc221/tasks/abc221_d)

#解答
~~~python3
N = int(input())

AB = [""]*2*N
dayList = [""]*2*N
for i in range(N):
    A,B = map(int,input().split())
    AB[2*i] = [A,1]
    AB[2*i+1]= [A+B,-1]
    dayList[2*i] = A
    dayList[2*i+1] = A+B

daySet =  sorted(set(dayList))
AB.sort()

loginNum = 0
index = 0
loginDays = [0]*(N+1)

for i in range(len(daySet)):
    logiNumBefore = loginNum
    while AB[index][0] == daySet[i]:
        loginNum += AB[index][1]
        index +=1
        if index >= len(AB):
            break
    if i ==0:
        continue
    else:
        loginDays[logiNumBefore] += (daySet[i] - daySet[i-1])

loginDays.pop(0)

print(" ".join(map(str,loginDays)))
~~~

※記事を書くにあたって提出してACになったソースコードを綺麗に書き直し、Python3で提出したら何故かTLEになってしまいました。(PyPyではACになりました)

#解法

- ログインした日とログアウトした日を早い順に並べて日付ごとのログイン人数を増減させる。
- ログイン人数に応じた日数を記録する配列を持っておき、ログインした人かログアウトした人がいた場合、それまでのログイン人数と日数を配列に加算していく。

#おわりに
このような問題は以前解いたことがあり、しっかり理解したつもりだったのですが、実際の問題に活用ませんでした。
ただでさえまだ全然知識がない状態なので知識のある問題は確実に取れるようにしないと行けないですね。。。
あと、この記事を書くにあたってこの解法がどういう名前なのかをを調べたのですがいまいちわからなかったので知ってる方がいたら教えていただきたいです。

以上、最後まで読んでいただきありがとうございました。
クラウド管理ゲートウェイ(CMG)は個人アカウントで作成できない

# 概要
個人でオンプレのConfiguraton Managerサーバー(2107評価版)とAzureアカウントを作成したので、CMG作成も試みました。
結果、エラーにより作成できませんでした。そのときの記録です。(2021/10/4時点)

# 作成手順
Microsoftの公式手順書をもとに実施
Configuration Manager 用に CMG を設定する
https://docs.microsoft.com/ja-jp/mem/configmgr/core/clients/manage/cmg/setup-cloud-management-gateway

Configuration Managerコンソールを開き、管理 > クラウドサービス > クラウド管理ゲートウェイまで移動
画面左上のリボン「クラウド管理ゲートウェイを作成」をクリック、または「クラウド管理ゲートウェイ」を右クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445228/a9393cc9-ace4-e42b-7df4-a6c1a06a2947.png)

「サインイン」ボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445228/717e7fa0-faf7-38e8-cce4-a36a6158cc5c.png)

Azureサービスを使用している個人アカウント名を入力。サインイン画面で「次へ」を押してもダメでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445228/38632ffc-f5cd-7ed1-73c8-93387175a937.png)
エラーメッセージ：
「ここに個人アカウントでサインインすることはできません。代わりに職場または学校アカウントをご利用ください。」

(´・ω・`)
Intersection Observer

##Intersection Observerを使ってみた。


```javascript:javascript
const targetEle = document.querySelector(".targetEle");
const cb = function (entries, observer) {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            entry.target.classList.add("inview")
        } else {
            entry.target.classList.remove("inview")
        }
    })
}
const io = new IntersectionObserver(cb, options);
io.observe(targetEle)

```

ーーーーーーーーーーーーーーーーーーーーーーーーーーー

参考


https://qiita.com/tatsuyankmura/items/544827d0a724c2f0c495

https://qiita.com/ryo_hisano/items/42f5980720bc832e6e09

https://qiita.com/seira/items/f6fb18a23103df59a892

https://ics.media/entry/190902/
docker-compose 環境で letter_opener_web が動かなかった話

## letter_opener_web が動かなかった

現在やっているプロジェクトを開始した当初からメール送信のローカル確認のために [letter_opener_web](https://github.com/fgrehm/letter_opener_web) を入れていた。
これは以前からも利用しており特に問題が起きたこともなかったので普通に動くだろうと思って導入した。

が、動かなかった。

正確に言うと `http://localhost:3000/letter_opener` にアクセスしてメール確認画面は何の問題なく表示されるが、メールが届かない。それ以外、どこにも何もエラーが出ていない。。

意味不明な状態だった。

## とりあえず使っている、開発環境

利用している開発環境は以下のような形で、特に特殊なことはしていない

- Docker for Mac
- Rails 6.x
- Ruby 2.x
- docker-compose
- Sidekiq (メールの送信もこちらを使って非同期で送信)

## 結局、、

- Mailer を常に `deliver_later` で利用している
- letter_opener_web のメール情報のデフォルト保存先が `tmp/letter_opener` になっている
- tmp 下が docker-compose で volumes で同期対象外になっていた

の組み合わせで起こっているという事が原因でした。

## Mailer を常に `deliver_later` で利用している

順を追って説明していくとまずこちら。

Sidekiq worker を利用しているためメール送信は全て deliver_later として全て worker に任せています。

それをデバッグのために rails console で `deliver_now!` としたのが始まりでした。

```rb
# 実装では deliver_later を使っている
UserMailer.hoge.deliver_later

# のを ↓ で rails console 上でデバッグ
UserMailer.hoge.deliver_now!
```

すると無事メールが届いた。

でも何故？

## 謎が解けないので、 letter_opener_web を改めて見ることにした

すると README.md でも書かれているが

```
If you're using :letter_opener_web as your delivery method, you can change the location of the letters by adding the following to an initializer (or in development.rb):

LetterOpenerWeb.configure do |config|
  config.letters_location = Rails.root.join('your', 'new', 'path')
end
```

のような設定を発見。

なるほど、メールはファイルとして `config.letters_location` に指定された場所に保存されるのか。

で、デフォルトの `config.letters_location` は？

https://github.com/fgrehm/letter_opener_web/blob/master/lib/letter_opener_web.rb#L13

で見つけた。なるほど `tmp/letter_opener` か。

## ここでやっと気付き

docker-compose で `tmp` を同期しないようにしていたっけ

```yml
# この app_base を rails と sidekiq で共通に利用している
x-base: &app_base
  # ...略...
  volumes:
    - .:/app
    - /app/tmp
    - /app/log
    - /app/.git
```

↑ のようにローカルのファイルを全て `/app` に同期しつつ、 `tmp` `log` `.git` は同期しないように別ボリュームにしてしまっている。

## 全てを理解した

`deliver_later` でメール送信した場合に Sidekiq 側で問題なくメール送信 (tmp/letter_opener にメール書き出し) が行われていたが、いざ rails server 側で `http://localhost:3000/letter_opener` にアクセスしようとすると、 `tmp/letter_opener` の同期がコンテナ間で同期されていないためメールが見えなかった。

`deliver_now!` で送信した際にはメールは rails server 側で送信されるため、`http://localhost:3000/letter_opener` にアクセスした際もローカルに作成されている `tmp/letter_opener` を参照する為届いているように見えた。

という単純なことでした。

解決策としては

- `tmp` を volume 同期対象にする
- `letters_location` を `tmp` 外にする

のどちらかを行えば解決出来そうとのことで、現在のプロジェクトでは

```rb
LetterOpenerWeb.configure do |config|
  config.letters_location = Rails.root.join('.letter_openner')
end
```

のコードを入れることにより無事 letter_opener_web が動くようになりました。

めでたしめでたし

## 教訓

README 読め！

以上
AtCoder Beginner Contest 214

##[A - New Generation ABC](https://atcoder.jp/contests/abc214/tasks/abc214_a)

O(1)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
 
int main() {
    int N;
    cin >> N;
 
    if(0<N && N<126) cout << "4" << endl;
    else if(125<N && N<212) cout << "6" << endl;
    else cout << "8" << endl;
 
    return 0;
}
```

##[B - How many?](https://atcoder.jp/contests/abc214/tasks/abc214_b)

O(N^3)
100*100*100=1000000
全探索です。

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
 
int main() {
    int S, T;
    cin >> S >> T;
 
    int res=0;
    for(int a=0; a<=100; a++){
        for(int b=0; b<=100; b++){
            for(int c=0; c<=100; c++){
            	if(a+b+c <= S && a*b*c <= T) res++; 
    	    }
    	}
    }
    cout << res << endl;
 
    return 0;
}
```

##[C - Distribution](https://atcoder.jp/contests/abc214/tasks/abc214_c)

O(N)
まず最初に全ての人に高橋君が渡す宝石、時刻を持たせる。
その後、すぬけ君が別のすぬけ君に渡す処理を行います。
この時の時刻が現在の時刻より小さいなら更新を処理を行います。

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
 
int main() {
    int N;
    cin >> N;
 
    vector<int> S(N);
    vector<int> T(N);
    rep(i, N) cin >> S[i];
    rep(i, N) cin >> T[i];
  
    queue<P> que;
    vector<int> res(N);
    rep(i, N){
    	res[i] = T[i];
      	que.push(P(i, T[i]));
    }
  
    while(!que.empty()){
        P p = que.front();
    	que.pop();
      
      	int num = p.first+1;
      	if(p.first+1>=N) num=0;
      	
    	if(S[p.first]+p.second < res[num]){
        	res[num] = S[p.first]+p.second;
          	que.push(P(num, S[p.first]+p.second));
        }
    }
  
    rep(i, N) cout << res[i] << endl;;
  
    return 0;
}
```
PythonとGraphvizでグラフを描く_1

# はじめに

この記事はVisual Studio Code+Python+Graphvizで簡単な図を描くことを目的としています。
図を描くといえばExcelやPowerPointを利用することが一般的ですが、そのように描画した図は再利用が難しい場合があり、かつ過去履歴との差分を比較することも難しいです。
なので、出来るだけテキストベースで図を管理していきたい、というのが本記事のねらいです。

## 環境

* Windows10
* Python 3.7
* Visual Studio Code

## 導入

[公式サイト](https://graphviz.org/) の DownloadからStable Windows install packagesを探し、新しいもので自分のPCにあうものをインストールします。
私は64-bit Installerを選択しました。
インストールが完了したら
```$ pip install graphviz```
とコマンドラインで打ち込みモジュールをインストールしておきます。

# 作図

まずはざっくりと作ってみます。
ピッコマという漫画アプリで配信されている『今世は当主になります』という漫画の人物相関図をネタにやってみます。

```python:example1.py

import graphviz

dot = graphviz.Digraph(format = 'png', 
comment = "今世は当主になります　～2話　人物相関図")

```

Digraphは有向グラフ（線に矢印が付くやつ）の意です。これを無向グラフ（ノードを単に線でつないだグラフ）にしたい場合は`graphviz.Graph`とします。
formatは出力結果の保存形式を決めます。
さてでは、この有向グラフdotにノードとエッジ（線）を追加していきます。

```python
dot.node('F', 'フィレンティア・ロンバルディ\n主人公')
dot.node('G', 'ギャラハン・ロンバルディ')
dot.node('E', 'フィレンティアの母')

dot.edge('F', 'G', label = '父')
dot.edge('F', 'E', label = '母')
```

nodeメソッドの中の引数はnameとlabelになります。（labelはなくてもよい)
nameは別にアルファベット1文字である必要はありません。複数文字でも大丈夫です。
edgeメソッドで線を引く時nameを使ってノードごとの識別を行います。
\nは改行として認識されます。
こうして一応形が出来ましたので、次にグラフを出力してみます。

```python
dot.render('./example1.gv', view=True)
```

ここまで打ち込んだらプログラムを実行します。画面に下図のようなものが表示されるでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186560/68c24a5a-4f05-24c9-05b2-4782e4cd309e.png)

はい、見事に文字化けしています。
graphvizで日本語を使用する場合フォントを指定する必要があります。
それにはattrメソッドを使います。
コードを追加します。

```python
dot.attr('node', fontname = 'Meiryo UI')
dot.attr('edge', fontname = 'Meiryo UI')
```

フォントはお好みで。日本語フォントなら何でもいいでしょう。
この指定の仕方から分かるように、ノードとエッジのフォント指定は別々です。  
今回は使用していませんがグラフのラベルを指定する時もまた別個にフォント指定が必要です。

この二行を追加した結果がこちら。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186560/e4f192af-ce42-f742-6b49-71873583cfef.png)

ちゃんと日本語で表示されましたね。
ホントは敵キャラとか色々追加したかったのですがそれはまた次回。
AtCoder Beginner Contest 213

##[A - Bitwise Exclusive Or](https://atcoder.jp/contests/abc213/tasks/abc213_a)

O(1)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int a, b;
    cin >> a >> b;
    cout << (a ^ b) << endl;

    return 0;
}
```

##[B - Booby Prize](https://atcoder.jp/contests/abc213/tasks/abc213_b)

O(N)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int n;
    cin >> n;

    vector<P> A(n);
    rep(i, n){
        cin >> A[i].first;
        A[i].second = i+1;
    }
    sort(A.begin(), A.end());
    cout << A[n-2].second << endl;

    return 0;
}
```

##[C - Reorder Cards](https://atcoder.jp/contests/abc213/tasks/abc213_c)

O(N)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int field[100000];
int main() {
    int H, W, N;
    cin >> H >> W >> N;

    vector<int> A(N);
    vector<int> B(N);
    rep(i, N) cin >> A[i] >> B[i];
    vector<int> ys;
    rep(i, N) ys.push_back(A[i]);
    sort(ys.begin(), ys.end());
    ys.erase( unique(ys.begin(), ys.end()), ys.end());
    rep(i, N) A[i] = lower_bound(ys.begin(), ys.end(), A[i]) - ys.begin() + 1;

    vector<int> xs;
    rep(i, N) xs.push_back(B[i]);
    sort(xs.begin(), xs.end());
    xs.erase( unique(xs.begin(), xs.end()), xs.end());
    rep(i, N) B[i] = lower_bound(xs.begin(), xs.end(), B[i]) - xs.begin()+ 1;

    rep(i, N) cout << A[i] << " " << B[i] << endl;

    return 0;
}
```
ransackを用いて複数ワードの空白区切り、フリーワードでの検索機能を実装する

## はじめに
開発ですぐに忘れそうなことを、簡単に再度調べられるようにするための備忘録です。

## やりたいこと
検索機能を簡単に実装できるransackを用いて、
複数のワードを空白区切りで入力された時の検索と
カラムを跨いだフリーワードでの検索を実装したい。

## 事前知識

例えば、Blogモデルにransackを用いて検索機能を実装する流れとして、

- カラム名_eq, カラム名_contなどのパラメーターを渡す（ `params[:q][:title_cont]`など ）
- `Blog.ransack(params[:q])`で検索
- 検索で得られたオブジェクトに対して`result`を用いて、ActiveRecord_Relationに変換する

のような流れで実装していく。

その他、細かな点は[ソースコード](https://github.com/activerecord-hackery/ransack)や[ピカワカ](https://pikawaka.com/rails/ransack)さんのサイトが参考になりそう。

## 実装の流れ

1. 入力された文字列を空白で区切る
2. 区切った単語と検索したいパラメーターをハッシュに格納
3. 得られたハッシュをransackに渡す

を新しい検索メソッドとして、実装していく。
また、検索のロジックになってくるため、model側にscopeメソッドとして実装する。

```ruby:model.rb

  scope :multi_search, -> (freeword) {
    words = freeword.scan(/[[:^space:]]+/)

# ※1
    g = words.map do |word|
      {
        x1_eq: word,
        x2_cont: word,
        x3_cont: word,
        m: "or"
      }
    end
# ※2
    ransack({ m: 'and', g: g, s: 'xxx desc' })
  }

```

※1：x1~x3は検索したいカラムを指定する
※2：cominatorでandかor検索かを指定できる。また、sのバリューにソートしたい条件を渡すことで、出力のソート条件も指定ができる。

上記で複数ワードの検索が実装できる。

※2021年10月６日、コメントいただいた書き方で、※1、 2をそれぞれ修正いたしました。

最後に、ransackの`params[:q]`には、デフォルトでは、カラム名_contなどしか渡せないので、`ransackable_scopes`に好きなワードを設定する。

```ruby:model.rb
  def self.ransackable_scopes(auth_object = nil)
    %i[freeword]
  end
```

これで複数ワードで検索する準備ができたので、
ビュー側で、

```erb:view.html.erb
<%= search_form_for @q, url: search_machines_path do |f| %>
  <%= f.search_field :freeword %>
  <%= f.submit %>
<% end %>
```
コントローラー側で、

```ruby:controller.rb

@search = Blog.multi_search(params[:q])
@list = @search.result(distinct: true)

```
とすれば、複数ワード、フリーワードでの検索機能が実装できる。
【理系大学生向け】Ubuntu20.04.3 LTSインストール後にやったこと

<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=True} -->

<!-- code_chunk_output -->

1. [はじめに](#はじめに)
2. [準備](#準備)
3. [やったこと](#やったこと)
    1. [Google日本語入力(Mozc)のインストール](#google日本語入力mozcのインストール)
    2. [FFmpegのインストール](#ffmpegのインストール)
    3. [VScodeのインストール](#vscodeのインストール)
    4. [Zoomのインストール](#zoomのインストール)
    5. [C++コンパイラなどのインストール](#cコンパイラなどのインストール)
    6. [GoogleDriveのマウント](#googledriveのマウント)
    7. [GitHub](#github)

<!-- /code_chunk_output -->

# はじめに
この記事では備忘録ついでに、Ubuntuをクリーンインストールしたあとに追加でやったことのまとめを残します。インストールしたバージョンは

> Ubuntu Desktop 20.04.3 LTS(英語版)

使用用途は**ブラウジング、プログラミング(C++)、グラフ作成、Markdownの作成、Zoom**などです。
大学での持ち運び用に古いWindowsパソコンを引っ張り出してきて使おうという魂胆です。
特にキーボードがもともとUSキーボードだったので日本語リミックスではなく英語バージョンをそのまま使います。

一気にできないので少しずつ追記をしていきます。参考文献を引いているのでそちらを参照していただければ幸いです。

# 準備
以下のインストールにはすべてTerminalを用います。イメージはWindowsのコマンドプロンプトです。開くにはお好みのタイミングで

> Ctrl + Alt + T

です。これができないと先に進めません。

# やったこと
## Google日本語入力(Mozc)のインストール
英語版でもいいですが日本語入力ができないと困るのでMozcを入れます。

```:Terminal
$ sudo apt install ibus-mozc
```

これで再起動すればインストールOKです。言語を切り替えるには

> Windwosキー + Spaceキー

です。うまく切り替わらに場合はUbuntuなら右上にIME的なのがあるのでそこをクリックして「Hiragama」に変えてあげてください。

## FFmpegのインストール

Firefoxで大学の講義動画を見ようとしたところ、

> you may required to install the video codecs

とコーデックをインストールしてくれ、とのエラーメッセージが出ました。Youtube等の動画共有サイトではデフォルトで動画再生可能なようですが、大学生御用達のMoodleにアップロードされている動画は再生不可能なようです。

そこで、フリーの動画再生、記録、変換ソフトである**FFmpeg**を入れます。インストールは

```:Terminal
$ sudo apt install ffmpeg
```

これで大学生の皆さんは問題なく講義動画がみられます。


## VScodeのインストール

普段からVScodeを使っていて、何でもかんでもVScodeで書く癖がついているのでUbuntuにも入れておきます。

**注意点ですが**snap経由でVScodeを入れると、mozc(Google日本語入力)が有効になっていても日本語を入力することができません。

そこでLinuxのインストールファイルの形式である **.deb** のパッケージからインストールします。

Microsoft公式
https://code.visualstudio.com/download

においてあるdebパッケージをダウンロードして実行すると、自動でVScodeがインストールされます。

## Zoomのインストール
snap経由でインストールしました。こちらは日本語入力が問題なくできます。

## C++コンパイラなどのインストール

C++をメインで書くのでコンパイラとしてg++を入れます。

```:Terminal
$ sudo apt install build-essential
```

デバッガとしてgdbを入れます。gdbはgccでコンパイルしたプログラムのデバッグを行うデバッガですが、互換性のあるものならデバッグしてくれます。

```:Terminal
$ sudo apt install gdb
```

インストールちゃんとできたか確認するときは

```:Terminal
$ sudo apt install g++
```

とやると教えてくれます。VScodeをエディタとして使うために細かいJSONなどの作成は


@CamouflageSixさんの記事

https://qiita.com/CamouflageSix/items/9133b2981e8b6e1f1548

を参考にさせていただきました。ありがとうございました。

## GoogleDriveのマウント

日常的に講義のPDF等はすべてGoogleDriveに入れているのでUbuntuでも見れるようにします。GoogleDriveを見るには

- Webブラウザからログインしてみる
- パソコン上のフォルダをマウントしてアクセスする

の２つがあります。これはLinuxに限らずWindowsでもどちらも可能です。フォルダをマウントすると、ファイルの移動などがやりやすいため、そちらで運用します。

参考にしたサイト様
「Ubuntu20.04でGoogleドライブを同期させたので手順を書く」,(2021年10月4日閲覧)
http://pineplanter.moo.jp/non-it-salaryman/2020/08/15/google-drive-ubuntu/

## GitHub
Power BI Desktopの棒グラフで特定の曜日の色をルールで変える（Tipsメモ）

##月曜日の色を変える準備【新しい列】

日単位で推移する棒グラフ（バーグラフ）の特定の曜日（今回は月曜日）だけ色を変えてみました。
方法は色々あると思いますが、比較的に容易で応用が利きそうな手段を考えてみました。
データは厚生労働省が提供している新型コロナウイルスに関連するオープンデータを使いました。

https://covid19.mhlw.go.jp/

元のグラフは以下のようになります。
日毎の国内感染者数推移です（直近60日間）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/48c1d999-628e-fde0-2e50-bd7544f57421.png)

**新しい列**を作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/a8ef8049-20b4-a135-a4b5-dce135f1c35d.png)

##DAX関数【WEEKDAY】

**WEEKDAY関数**を使い、曜日を番号にします。
日付範囲は 1 (日曜日) から 7 (土曜日) です。

https://docs.microsoft.com/ja-jp/dax/weekday-function-dax

```R
DayNo = WEEKDAY(pcr_positive_daily[Date])
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/6cd96848-2bfa-1695-e417-82fe16c3be12.png)

##ルールで色付与【条件付き書式】

**書式　→　データの色**からルール設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/ae834568-2abb-969c-e8fc-11dd89cf1aa1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/d44767d4-1132-274b-d0a0-5e77cb1546bc.png)

左上のドロップダウンから**ルール**を選びます。
先ほど追加した列フィールドの「DayNo」の**平均（1日単位の集計なので合計など他でもOK）**が**2（火曜日）**の場合の**結果**として「色」を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/d4b12882-e452-8246-084d-83da263d8812.png)

**OK**をクリックすると、月曜日のバーの色が変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/ea5bd5a3-7cd0-20cf-564a-964a5bb86c78.png)


**了**
ABC57 B - Checkpoints diff 茶を解いた

https://atcoder.jp/contests/abc057/tasks/abc057_b

![abc57_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/faee6b0d-10a3-081d-1a97-48e82e51731e.png)
![abc57_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/ac41c941-9358-a2cb-ffc2-249853db0e6b.png)
![abc57_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/02c334ea-f9cb-1e12-5a99-c56ec6fb2da5.png)
![abc57_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/c4090db4-565f-640d-da0d-6b3cb8488b3c.png)
![abc57_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/f6edcc33-9743-9478-c103-eacffb5455be.png)

全探索ではなかろうか。
N,M が 50 以下なので行けそうな気配。

```Checkpoints.py
N,M = map(int,input().split())

person = []
for _ in range(N):
    a,b = map(int,input().split())
    person.append([a,b])

checkPOINT = []
for _ in range(M):
    c,d = map(int,input().split())
    checkPOINT.append([c,d])

nums = []
memo = 0
#print(person,checkPOINT)
for n in range(N):
    score,ans = 0,float("inf")
    for m in range(M):
        #print(n,m)
        score = abs(person[n][0]-checkPOINT[m][0]) + abs(person[n][1]-checkPOINT[m][1])
        if score < ans:#<= 最初に最小値となったものを記録し続ける <= ココ
            ans = score
            memo = m+1
    nums.append(memo)

for s in nums:
    print(s)
```

問題文には最小地点が複数の場合、
チェックポイントの数字が一番小さい場合を所望している。
前述のコメントにある **ここ** にあるような書き方で OK
GitHubの2段階認証ではpersonal access tokenというものが必要らしい

記念すべき初投稿です。
僕は今、Swiftの勉強をしており、やっと1つのアプリを作ることができました。まぁただの四則計算しかできない電卓アプリですけど...。それでさっさとGitHubとやらにファイルをアップロードして、次のアプリ制作に取り掛かろうと思ったのですが、結果的にファイルをアップロードするまでに4時間、沼にハマってました。マジで腹立つ。
今、プログラミングを勉強している初心者エンジニアの方達には、こんなしょうもないことで時間を食って欲しくないので、共有したいと思います。もし間違っていることを書いていたら、びしばしとご指摘ください。


#沼にハマるまでの道筋
僕は、GitHubにファイルをアップロードするやり方がわからなかったので、[初心者用：GitHubにファイルをアップロードする方法（超基本）](https://qiita.com/under_chilchil/items/ec9d0050c1e3fb6576de)を見て、手順通りにやってみたのですが、最後の

```
git push -u origin master
```

を実行したら、

```
Username for 'https://github.com': hoge-user
Password for 'https://hoge-user@github.com':
```

というのが出てきたので、「こんなのあるなんて聞いてないぞ」とか思いながら、GitHubのユーザー名とパスワードを入力して実行。

```
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/hoge-user/repository-name.git/'
```

というのが出てきて、まだ僕は初心者なのでこの2行は成功の合図だと思い、意外と簡単だなとか甘いこと考えてたら、まぁ〜何回リロードしてもアップロードされない。


#原因
原因を調べたら、これは2段階認証というものだとわかりました。さらに、

```
Username for 'https://github.com': hoge-user
Password for 'https://hoge-user@github.com':
```

ここでの2行目のパスワードはGitHubに登録した時のパスワードではなく、personal access tokenという別のパスワードが必要なんだそうです。そんなんわかるか！
1行目のユーザー名は普通にGitHubのユーザー名を入れます。


#personal access token入手方法
特に難しいことはなく、[personal access tokenの作成方法](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)の通りにやっていけば、問題ありません。
8の項目なのですが、なんかチェックをつけたり、外したりしてて、あまり意味がわからなかったので、僕は1番上の repo というものだけにしかチェックをしなかったのですが、問題なくアップロードできたので大丈夫だと思います。
この8の項目でなにをしているのかわかる方いらっしゃいましたら、ご教授いただけるとありがたいです！
あとは、personal access tokenをコピーして、2行目のパスワードのところに貼り付けて実行するだけです。そうすると、なんだかさっきのより成功の合図感がありますよね？


#余談
こんな自慢げに記事を書いてますが、この情報に行き着くまでに先ほども書いたように、4時間もかかりました。まず僕は、自分が打っているパスワードが間違っているのではないかと、何回も試し、それで1時間。次はまた同じように、git initからやり直していたら、最初に実行した時とターミナルの処理結果がなんか違うと気づいたので調べてみたら、リポジトリの履歴の初期化を行うと良いらしく、[Gitでリポジトリの履歴を初期化する方法を紹介！](https://qumeru.com/magazine/526)という記事に出会い、さらに1時間。しかし、これでもうまくいかなく、また調べてみたら、ターミナルでVimというものをいじれば、2段階認証をしなくて済むという記事[（githubを二段階認証に変更後に起こるエラーの対処方法）](https://qiita.com/sayama0402/items/670b6b650ebdd8680a0b)を見て、ここで初めて2段階認証を知り、また１時間。やっとここで解決の兆しが見えたところで、Vimってなんか普通に文字が打てないみたいで、わからなくなって強制終了したらスワップ?みたいなよくわからないのですが、ターミナルによるエラーいじめに遭い、それを克服し、[Githubの2段階認証入れたらpushできなくなった人へ](https://qiita.com/cyborg__ninja/items/6efd349370bf5f8bffb2)に出会い、解決しました。
AWS CLIを使って、Amazon S3へ自動バックアップ

##はじめに
数TBのサーバデータをクラウドへバックアップする必要性が出てきて、なるべくバッチとかタスクとか使って自動でやりたいと思ったのが事の始まりです。AWSのCLIを使うとめちゃくちゃ簡単に実現できたので、今回ご紹介します。
##AWS CLIのインストール
まず、下記からAWS CLIをダウンロードして、インストールします。
[AWS CLI](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-windows.html)
すべてそのままNEXTで進んでいけばOKです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980545/aa3a5a88-96cc-b979-0e89-1cb54db25eec.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980545/8b78150f-3084-d451-5512-11a7c0c697db.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980545/606fe1e9-bf6c-5f57-f6a6-9758b2b4e7af.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980545/b8d9dce2-8390-f0c1-17e2-b588e8f771b1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980545/ff66b870-358c-9655-fc4d-7c9cec8ded17.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980545/220e8819-b88a-8df2-318b-1ba1975630a5.png)

##初期設定
コマンドプロンプトを起動し、下記のコマンドを打ちます。
（IAMユーザのアクセスキーとシークレットアクセスキーは事前に作成しておいてください。作成方法はここでは割愛します。）

```
>aws configure
AWS Access Key ID [None]: *****
AWS Secret Access Key [None]: *****
Default region name [None]: ap-northeast-1(東京リージョンの場合)
Default output format [None]: json
```

これでAWS CLIにIAMユーザーが紐づきました。

##バッチファイル作成
次に、バッチファイルを作成します。**バッチファイルの中身はたった1行だけでOKです。**

```
aws s3 sync "バックアップ元のフォルダパス" s3://バックアップ先のバケット名 --delete
```

**※syncと--deleteオプションをつけると、バックアップ元で削除されたデータは、バケットからも削除されます。完全に同期されるようなイメージです。**

あとはタスクスケジューラで上記バッチが定期的に実行されるようにタスクを作成するだけです。

##おわりに
気になる料金ですが、S3→外方向は課金されるが、外→S3方向は課金されないと、どこかの記事で見かけたのですが、実際どうなのかは確認してみないことにはわかりません。請求が確定したら当記事を更新しようと思います。
C++勉強記録(江添亮のC++入門) - 001

## C++勉強記録(江添亮のC++入門) - 001



## __has_include()について

[江添亮のC++入門](https://ezoeryou.github.io/cpp-intro/#%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E7%9C%81%E7%95%A5)にて下記コードの意味を調べたのでメモを残す。

https://ezoeryou.github.io/cpp-intro/#%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E7%9C%81%E7%95%A5

```c++
#if __has_include(<string_view>)
#   include <string_view>
#endif
```



__has_includeとは下記のような機能である。

> `__has_include`はインクルードするファイルが存在するかどうかを返す述語である。
>
> `__has_include`に指定されたインクルードファイルが存在する場合は 1 として評価され、インクルードファイルが存在しない場合は 0 として評価される。
>
> 参照：[cpprefjp - C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp17/has_include.html)

https://cpprefjp.github.io/lang/cpp17/has_include.html

つまり問題となるコードは、`<string_view>`というヘッダが存在するかどうかを確認し、存在すればインクルードするというコードなのである。

ちなみに、__has_include()が使用できるのはc++17以降である。



## #warningについて

ついでに、参照：[cpprefjp - C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp17/has_include.html)の`__has_include`の説明ページに載っていた下記の例コードについても調べた。

https://cpprefjp.github.io/lang/cpp17/has_include.html

```c++
#if __has_include(<has_include.hpp>)
#  warning <has_include.hpp> is found
#else
#  warning <has_include.hpp> is not found
#endif
```

上記コードを参考に下記のようなプログラムを作成した。

*has_include.h*

```c++
#include <iostream>

#if __has_include(<string_view>)
        #include <string_view>
        #warning <string_view> is found
#else
        #warning <string_view> is not found
#endif
```

*has_include.cpp*

```c++
#include "has_include.h"

int main() {
}
```

実行結果：

```
$ g++ -std=c++20 -o has_include ./has_include.cpp
In file included from ./has_include.cpp:1:
./has_include.h:5:3: warning: #warning <string_view> is found [-Wcpp]
    5 |  #warning <string_view> is found
      |   ^~~~~~~
```

上記実行結果のように、コンパイル時にwarning messageが出力された。



\#warning ディレクティブ(#warning directive)について下記サイトを参考にしました。

- 参考：[SE学院](http://itref.fc2web.com/c/preprocessor.html#ERROR)

http://itref.fc2web.com/c/preprocessor.html#ERROR

- 参考：[C/C++の#warning](https://sygh.hatenadiary.jp/entry/2018/01/22/010030)

https://sygh.hatenadiary.jp/entry/2018/01/22/010030

- 参考：[プリプロセッサ #warning は非標準](https://aki-yam.hatenablog.com/entry/20081006/1223275074)

https://aki-yam.hatenablog.com/entry/20081006/1223275074

要するにコンパイラにwarningを発生させる命令であり、プリプロセッサ(preprocessor)の一部だ。

\#errorディレクティブ(#error directive)も存在し、そちらはコンパイラにerrorを発生させ、エラー終了させる(コンパイルが完了しない)。



つまり問題となる例コードは、ファイルが存在するかどうかをコンパイル時にwarning message形式で出力させるコードだったのだ。



ただし、このコードには問題がある。

```
$ g++ -std=c++20 --pedantic-errors -o has_include ./has_include.cpp
In file included from ./has_include.cpp:1:
./has_include.h:5:3: error: #warning is a GCC extension
    5 |  #warning <string_view> is found
      |   ^~~~~~~
./has_include.h:5:3: warning: #warning <string_view> is found [-Wcpp]
```

上記のように、`--pedantic-errors`(C++の規格を厳格に守るオプション(規格に違反しているコードがコンパイルエラー扱いになる))を使用した場合コンパイルエラーとなる。

`#warning is a GCC extension`とあるように、`#warning`はgcc/g++ の拡張であり、標準ではないという事である。

ちなみに#error directiveは[言語仕様として標準化されている](http://en.cppreference.com/w/cpp/preprocessor)。

http://en.cppreference.com/w/cpp/preprocessor
wsl_ubuntuでwindowsホストのファイルにアクセスするパス

wslのubuntu20.04上でDockerを使う時にwindowsホストのファイルをマウントしたかったのでメモ
(文字コードとか大丈夫かな)

docker run -it -p 10000:8888 -v /mnt/c/Users/User名/work/signate:/home/jovyan/work/ --gpus all jupyter/scipy-notebook
Laravelで画像を素材として使う時に、画像が出てこないときの対処法

Laravelで画像をHTMLファイルに読み込ませて使いたいと考えたのですが、やり方を知らなかったので、今ここで共有していきたいと思います。

###　現象
画像が入ったフォルダをviewファイルが有るフォルダに置いて、画像パスを指定したのに動かない。
というのがありました。
何度も何度も画像パスを確認していったのですが、うまく動きませんでした。

###　解決策

Laravel8系では、resourcesディレクトリに画像を入れておくと、表示されません。
わたしはresourcesディレクトリに素材の画像を入れて使おうとしていたのでどんなに画像パスが合っていても表示されないというわけですね。
resourcesのプログラムは、いったんコンパイルされてそれがpublickに反映されているので、ブラウザ上に反映させようとしたらpublickディレクトリに置かないといけないみたいです。
なので、publickディレクトリに画像フォルダを入れておくディレクトリを起きましょう。
そうしたら、resourcesディレクトリのHTMLファイルにパスを書けばきちんと反映されます。

皆さんよかったら試してみてください。
HAVING句でデータの歯抜けを探す方法を見ながら、集合思考言語と手続き型言語の違いを考える（2/2）

## はじめに

HAVING句でデータの歯抜けを探す方法を見ながら、集合思考言語と手続き型言語の違いを考えてみます。（2/2）

Schema (MySQL v8.0)

```sql
CREATE TABLE members (
  id INT NOT NULL PRIMARY KEY auto_increment,
  name TEXT
);

INSERT INTO members VALUES
    (1, 'brown'),
    (2, 'rally'),
    (3, 'boggie'),
    (5, 'tashiro'),
    (6, 'yamada'),
    (8, 'takeda');
```

Result

| id  | name    |
| --- | ------- |
| 1   | brown   |
| 2   | rally   |
| 3   | boggie  |
| 5   | tashiro |
| 6   | yamada  |
| 8   | takeda  |

## 歯抜けの最小値

前回は、このデータの歯抜けを探しました。今日は、歯抜けの最小値を求めていきましょう。

最小ときたら `MIN` ということで。

query

```sql
SELECT MIN(id + 1) AS gap
FROM members
WHERE (id + 1) NOT IN (SELECT id FROM members)
```

結果は4が返ってきます。

`NOT IN`を使ったサブクエリで、あるidの`+1`のidがあるかを調べています。

見つからないid は[3, 6, 8]が真になります。

歯抜けがない場合は、9が得られます。（ほんとか？と思う方は是非試してください。）

テーブルはファイルではないので行に順序はありません。それゆえ、こういう行同士の比較を行う際にソートをしません。

## 連番にNULLが入ってた場合

少しスキーマを変えます。

Schema (MySQL v8.0)

```sql
    CREATE TABLE members (
      id INT,
      name TEXT
    );
    
    INSERT INTO members VALUES
        (1, 'brown'),
        (2, 'rally'),
        (NULL, 'telly'),
        (3, 'boggie'),
        (5, 'tashiro'),
        (6, 'yamada'),
        (8, 'takeda');
```

| id  | name    |
| --- | ------- |
| 1   | brown   |
| 2   | rally   |
|     | telly   |
| 3   | boggie  |
| 5   | tashiro |
| 6   | yamada  |
| 8   | takeda  |

query

```sql
SELECT MIN(id + 1) AS gap
FROM members
WHERE (id + 1) NOT IN (SELECT id FROM members)

```

results

| gap |
| --- |
|     |

これまでの記事を見ていただい方なら、この挙動がしっくりくるかと思います。

本日は、以上です。

## 参照

https://www.amazon.co.jp/dp/4798157821/

108 - 109p

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103
Homebrewのrmtrashが無い…？

2021/10/03投稿

**※最新版は[haroot.net](https://haroot.net/articles/11)に移動しました。**

# 結論
`rmtrash`が無い原因は見つかりませんでしたが`trash`を代わりに入れたら機能しました。

# 環境
macOS Big Sur 11.3

# 動機
ターミナルの`rm`コマンドで誤って**必要なファイル**を消してしまったため、消さずにゴミ箱に移動するだけに変えようと思った。
調べるとHomebrew経由で`rmtrash`というゴミ箱に移動するだけのコマンドがあるらしいので入れてみる。

```
brew install rmtrash
```
実行結果 :

```
Updating Homebrew...
(略)

Warning: No available formula or cask with the name "rmtrash". Did you mean trash?
==> Searching for similarly named formulae...
This similarly named formula was found:
trash
To install it, run:
  brew install trash
==> Searching for a previously deleted formula (in the last month)...
Error: No previously deleted formula found.
==> Searching taps on GitHub...
Error: No formulae found in taps.
```
`rmtrash`なんてパッケージはない。`trash`の間違いでは？と言われた。
念の為[Homebrewサイト](https://formulae.brew.sh/formula/)のパッケージ一覧から探してみたが確かにそんなパッケージは無かった…
`trash`に変わったんですかね？(わかる人いたら教えてください)

# trashを入れてみる
言われた通りtrashを入れてみます。(サイトのパッケージ一覧見たら`macos-trash`というのもありました。違いはわかりませんが。)

```
brew install trash
```
実行結果 :

```
==> Downloading https://ghcr.io/v2/homebrew/core/trash/manifests/0.9.2-1
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/trash/blobs/sha256:403ba52ce97d38535e1d127ca227afd4ea2d0e0c8b
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:403ba52ce97d38535e1d127ca
######################################################################## 100.0%
==> Pouring trash--0.9.2.big_sur.bottle.1.tar.gz
🍺  /usr/local/Cellar/trash/0.9.2: 5 files, 60.8KB
user@usernoMacBook-Pro Desktop %
```

## 動作確認

```
touch A.txt
trash A.txt
```
実行結果 :
![スクリーンショット 2021-10-03 22.42.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/b85ef981-1db2-e956-4f92-e0df5ea2aeac.png)
ちゃんとゴミ箱に移動してくれました。ちなみにフォルダも同様に`trash`のみで消えました(中にファイルがあっても)。
# エイリアスを貼る
このままだと間違えて`rm`コマンド使ってしまいそうなので`rm`と打つと`trash`が実行されるようにエイリアスを貼ります。
.bash_profileや.zshrcを開き(PCのシェルによって異なります)、

```:.bash_profileや.zshrcなど
alias rm="trash"
```
保存してターミナルを再起動したら完了です。
## 動作確認(エイリアス)

```
touch A2.txt
rm A2.txt
```
実行結果 :
![スクリーンショット 2021-10-03 23.02.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/85d176c9-32ad-14c3-52d2-4f1f77b4fec5.png)
`rm`と打って`trash`の動作になっていることが確認できました。

# 参考文献
* [rmtrashのすすめ〜誤削除を防止する〜](https://qiita.com/nakamurau1@github/items/7fd6ee87787d0687c2e2)
ここら辺見ながら`rmtrash`やろうとして上手くいきませんでした。
* [Hombrew公式のパッケージ一覧](https://formulae.brew.sh/formula/)
ExcelVBA 特定フォルダ複数ブック特定シートを1ブックにコピーし集約する

###はじめに
同一内容が記載されたExcelファイルが多数存在する。
当該ファイルはシート１に内容が記載されているが
集計するために、1シートに集約したい。
コピペの手作業だと絶望的な数だったのでVBAで対応しました。

↓こんな感じのファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/2c19b716-2f07-de10-c914-11119d47bc17.png)

###作業内容
新規ブックを作成して
以下のマクロを記述して実行した。

```
Sub 特定フォルダ複数ブック特定シートを1ブックにコピーし集約する()
On Error GoTo Exception

    Dim MyBookName      'カレントブック名
    Dim buf As String   'ファイル一覧取得
    Dim cnt As Long     'カウント
    Dim Path As String                'ワークブックパス
    Dim Paste_des_Colum As Long     '貼り付け先の列
    Dim Last_Row As Long              '貼り付け先の行
    Dim Paste_source_Cell As String   '貼り付け元の開始セル

    MyBookName = ActiveWorkbook.Name
    Paste_des_Colum = 2
    Paste_source_Cell = "A2"
    
    'ワークブックパスを取得
    Path = ThisWorkbook.Path & "\"
        
    'ワークブック読み取り
    buf = Dir(Path & "*.xlsx")
    
    Do While buf <> ""
        
        '貼り付け先の最終行を取得する
        Last_Row = Range("B65535").End(xlUp).Row
        
        'ブック開く
        Workbooks.Open Path & buf
        'ブック選択
        Windows(buf).Activate
        'シート選択
        Sheets("Sheet1").Select
        '表の最終まで範囲選択
        Range(Range(Paste_source_Cell), ActiveCell.SpecialCells(xlLastCell)).Select
        'コピー
        Selection.Copy
        
        'ブック戻す
        Windows(MyBookName).Activate
        Sheets("Sheet1").Select
        'コピー先選択
        Cells(Last_Row + 1, Paste_des_Colum).Select
        '貼り付け
        ActiveSheet.Paste
        
         'ブック閉じる
        Windows(buf).Close
                
        cnt = cnt + 1
        buf = Dir()
    Loop

    MsgBox "終了しました"

Exception:
    MsgBox Err.Number & vbCrLf & Err.Description
    
End Sub

```

---
####履歴
2021/10/3 新規作成
Qiita Markdown のバグ?


Qiita Markdown のバグでしたら直してほしい内容

<font color="red">追記</font>
<font color="red">連絡をいただいて、以下の内容を Qiita サポート窓口へ相談しました</font>


## 状況

下記の場合、「B-1-(2)」の見出しレベルは「B-1-(1)」と同じである.
しかし、(後述画像のように) 目次を見ると、「B-1-(2)」のインデントが 1つ浅い.

```
## A

yyyy

## B

### B-1

#### B-1-(1)

xxxx

###### 参考情報

xxxx

#### B-1-(2)

xxxx

```

## 表示結果(と期待値)

下図左のように表示されるが、期待値は右である.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/9f5b836a-e722-ef7b-aacf-4ced52651fef.png)
SecurityHubのAPIでセキュリティ情報を取得してみる

SecurityHubのAPIを使って、AWSの画面に出ている情報を収集しようとしてみた。

# やりたいこと
AWS Security Hubのセキュリティ基準から確認できる、以下の情報を取得したい。
(1) 各ベンチマークの各項目のステータス(成功とか失敗とか)
以下の「ステータス」とか「タイトル」とか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/89dc8d54-fe97-baec-f892-4437c59ba21c.png)
(2) 各ベンチマークの各項目の、リソースごとのステータス
各項目の詳細画面では、以下のように項目に関係のあるリソースとリソースごとのステータスが表示されるので、それを取得したい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/2843e04a-a58a-8aa1-ee99-fd42d043ad62.png)

# まずは何も考えずに情報取得
言語はC#で、AWS SDKのSecurityHubを使用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/9803e064-fcc3-0c6a-a17b-6319d0fea37f.png)
GetFindingsメソッドで情報を取得する。nextTokenがある場合は、すべて情報を取得するまでループすることも忘れずに。
※ APIの呼び出しにはSecurityHubのClientを適切に生成する必要がある。

```C#
string nextToken = null;

do
  {
    var request = new GetFindingsRequest();
    request.MaxResults = 100;
    request.NextToken = nextToken;

    var response = securityHubClient.GetFindingsAsync(request).Result;

    var data = response.Findings;
    SecurityFindings.AddRange(data);

    nextToken = response.NextToken;
    request.NextToken = nextToken;

    response = securityHubClient.GetFindingsAsync(request).Result;

  } while (nextToken != null);
```

取得した結果が以下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/37b07305-a26c-a59f-9f51-c3dc74f32697.png)
ちょっと多くないですか････？
ベストプラクティスが113項目、CISが43項目だから、全部で156項目だと思っていたけど｡｡｡｡

# いったい何が多いのか
データの中身を追ってみたところ、以下二つが原因っぽい。
※ ちゃんとSecurityHubのドキュメントを事前に読めばすぐわかったことかもしれない｡｡｡

(1) レコードの状態が「ARCHIVE」のものが混じっている。
どうやら過去のステータスを内部的に保持している様子。確かによくよく見ると、各項目に「更新日時」みたいなものがある。
しかしARCHIVEのものを除外した結果、画面に表示されているものがなくなる、みたいなことは避けたい｡｡｡

(2) １つの項目に複数のリソースの結果がある場合、GetFindingsの結果(インスタンス)が別になる
レスポンスの中身を読むと、1項目1リソースで1オブジェクトの様子。なので、これらを解析すれば求めるものが得られるはず。
ただ、レスポンス内のResourcesは、名前の通り複数形なので、将来同じ結果はここにまとめるなんて構想があるのかも･･･？

# 条件を決めてフィルタする
とりあえず調査結果から、レコードの状態がACTIVEに等しいものだけ取得してみる。
すると、245あった結果が215になった。少しだけ減ったけど、もうここから考えるのもめんどいからいったん表示してみる。

# コンソールに出力する
出力用に適当なモデルを作成し、取得した情報をコンソールに出力させてみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/884e7be9-3da9-091f-8ccf-107117133b35.png)

どうやら、取れた様子。よかったよかった。

項目の説明とか対処方法も取得できているので、出そうと思えば出せる。

ほかのサービス(Inspector)と連携していれば、そこの情報も取得できそう･･･

以上。
ev3dev(python) : 加速度センサー(HiTechnic社製)の使い方

ev3devでHiTechnic社製の加速度センサーを使う方法が見当たらなかったのでメモ
#参考サイト
[1]

https://ev3dev-lang.readthedocs.io/projects/python-ev3dev/en/stable/sensors.html#ev3dev2.sensor.Sensor

[2]

http://docs.ev3dev.org/projects/lego-linux-drivers/en/ev3dev-stretch/sensor_data.html#ht-nxt-accel

#センサーの確認
Base"Sensor"クラスを使用してセンサ情報を確認する(参考サイト[1])。
※加速度センサーはポート1に接続

```python
#!/usr/bin/env/ python3
from ev3dev2.sensor import INPUT_1
from ev3dev2.sensor import Sensor

s1 = Sensor(INPUT_1)
print(s1.address, s1.driver_name)
```
実行結果
加速度センサが接続されている「ht-nxt-accel」と表示される

```
ev3-ports:in1:i2c1 ht-nxt-accel
```

他にも色々確認してみる

```python
#!/usr/bin/env/ python3

# from ev3dev2.sensor import INPUT_1, INPUT_2, INPUT_3, INPUT_4
from ev3dev2.sensor import INPUT_1
from ev3dev2.sensor import Sensor

s1 = Sensor(INPUT_1)
print(s1.address, s1.driver_name)

#mode一覧を確認
print("modes:", s1.modes)
#modeを"ALL"に設定
s1.mode = "ALL"
#modeを確認
print("mode:", s1.mode)
#取得するvalueの数を確認
print("num_values", s1.num_values)
print("//---------//")
#各valueの値を確認する
for i in range(s1.num_values):
    print("Value[{}] : ".format(i) ,s1.value(i))
```

実行結果

```
robot@ev3dev:~/testspace$ python3 ScanSensorPort.py 
ev3-ports:in1:i2c1 ht-nxt-accel
modes: ['ACCEL', 'ALL']
mode: ALL
num_values 6
//---------//
Value[0] :  1
Value[1] :  253
Value[2] :  49
Value[3] :  1
Value[4] :  1
Value[5] :  1
```
参考サイト[2]よりmode='ALL'にしてvalue(0)~(2)を取得すれば
3軸(x, y, z)の値が取得できることがわかる。


#3軸(x, y, z)の加速度を取得するプログラム
上記の確認より以下のプログラムで3軸の加速度が取得できる。

```python:AccelerationSensor.py
#!/usr/bin/env/ python3
 
from ev3dev2.sensor import INPUT_1
from ev3dev2.sensor import Sensor

class AccelerationSensor:
    # クラスを呼び出す際に引数として加速度センサーが接続されているポートを指定する。
    # modeで"ALL"(3軸の加速度が必要な場合)を指定しな場合、初期値が"ACCEL"となりエラーになる
    def __init__(self, input_n):
        self.s = Sensor(input_n)
        self.s.mode = "ALL"
    
    def ThreeAxisAcceleration(self):
        #3軸の加速度を取得する
        x = self.Conversion(self.s.value(0))
        y = self.Conversion(self.s.value(1))
        z = self.Conversion(self.s.value(2))
        acce_value = (x, y, z)
        return(acce_value)
    
    def Conversion(self, value): 
        # 生のセンサデータ(0~255)を加速度g(-2g ~ 2g)の値に変換する
        # 0~127   = -2g ~ 0g
        # 128~255 =  0g ~ 2g 
        coefficient = 2/128
        if value < 128:
            value = (value * coefficient) * -1
            value = round(value, 2)
            return(value)
        elif value >= 128:
            value = (255 - value) * coefficient
            value = round(value, 2)
            return(value)

if __name__ == '__main__':
    acc_sensor =  AccelerationSensor(INPUT_1)
    while True:
        print(acc_sensor.ThreeAxisAcceleration())
```
実行結果

```
robot@ev3dev:~/testspace$ python3 AccelerationSensor.py 
(0.09, -0.02, -0.78)
(0.09, -0.02, -0.78)
(0.09, -0.02, -0.78)
(0.09, -0.02, -0.78)
...
```
※注意
加速度センサーでは重力により地面に対して垂直に重力加速度(0.98)が測定される
(センサにより実際の値は誤差がある)
上記結果だとz軸のマイナス方向に重力加速度(-0.78)が働いている.

以上
ABC72 C - Together を解いた

https://atcoder.jp/contests/abc072/tasks/arc082_a

![abc72_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/f3df4bf3-a1e5-1f5c-3b1b-51e1e8ab1f29.png)
![abc72_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/5d8f80b1-c27d-bd41-9339-93040af83049.png)

全部リストしてみよっかな。
それを数えて最大値を出してみる。

```Together.py
N = int(input())
A = list(map(int,input().split()))

lis = []

for i in range(N):#O(N)
    a,b,c = A[i]-1,A[i],A[i]+1
    lis.append(a)
    lis.append(b)
    lis.append(c)

from collections import Counter
lis = Counter(lis)#O(N)

print(lis.most_common()[0][1])
##total 計算量 ザックリ O(2N)
```

意気揚々とカウントしたが、最大値のスマートな出し方に
困ったので、ググった。以下が分かり易い。

https://note.nkmk.me/python-collections-counter/

尚、collections の Counter は以下を眺めると O(N) で行けるっぽ買った。

https://inarizuuuushi.hatenablog.com/entry/2017/01/03/171845
勉強会に行ってみた　~yoboca 呼び出し通知サービス~

#はじめに
先日、オンライン勉強会にてLine Developers Community REV UP 2021に参加させて頂きました。
参加した経緯としてはエンジニアとして技術力も大事ではあるが問題発見力も必要だと感じております。その問題に対してどういったアプローチが有効であるのかそういったアイディアの引き出しを増やしていきたいといった思いから受講しました。

#LINE Developers Community 
 このコミュニティは、LINE社外の有志メンバーを中心に運営されています。

LINEの技術が好きな方とのネットワーク作りはもちろんのこと、LINEのAPI に関連する多様なイベントの企画運営通じて、参加者同士が情報交換を行い、日々の開発/運用に役立てていくことも運営の目的の１つとしています。

#取り扱う技術
基本的には LINE の開発プラットフォームにおける技術全般を扱う

* Messaging API
* LINE Login
* LINE Front-end Framework
* LINE Pay
* LINE Things
* LINE Notify
* Clova Extension Kit

#グループメンバー対象者
* LINEのAPIを活用している方
* 今後活用したいと考えている方
* チャットボットの開発運用に関心をお持ちの方

#Communityへの参加方法
* connpassからの参加
* 過去のイベントはYoutubeにuploadされています

https://www.youtube.com/watch?v=18CIJL-gYqQ

#yoboca 呼び出し通知サービス

yoboca 呼び出し通知サービスを一言で説明すると、”ブルブル”から”yoboca”へ
よく、フードコードであるブルブルをアプリ化したサービスとなっています。

__”呼び出し”に特化したミニアプリサービス__

>LINEミニアプリは、LIFF（LINE Front-End Framework）上で実行されるウェブアプリです。 LINEミニアプリを使えば、ユーザーはアプリをインストールしなくてもサービスを利用できます。
「LINEミニアプリ」が公式名です。
LINEミニアプリはウェブアプリですので、HTML5のほとんどの仕様が使用でき(LINE Developers)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1572216/6f7abb25-08bb-a617-f92a-7229e5183ae1.png" width=50%>

#特徴① ブルブルを超える
__「呼び出して終わり」ではない！__
なんとイノベーション的なフレーズなんでしょう！心に響きますね:blush:
ブルブルから通知に置き換わることで、店舗として様々なメリットに繋げられます。

||yoboca|ブルブル|
|:---:|:---:|:--:|
|通知距離|携帯電話網の範囲|100m程度|
|メンテナス|不要|バッテリー交換、充電|
|感染症対策|不要|アルコール除菌|
|紛失、盗撮リスク|なし|あり|
|価格モデル|月額利用|買取/レンタル|

#特徴② 順番待ち"以外"の待ち時間へ対応

順番待ち以外の待ち時間へ対応

* 順番に関係なく出来上がったものから呼び出せる

>主な利用シーン:フードコート

* 1週間後や3ヶ月など、翌日以降に通知したい

>主な利用シーン:各修理

ユーザーの一意見として、順番待ち以外でも対応する点は非常に魅力ですね！！！
依頼物が終了後、通知で見るだけなので今までの電話の工程がなくなるのか有難い

#特徴③ ワンタップで簡単呼び出し通知
店舗者は呼び出しの操作の工程が多いのでは？？と思った方がいらっしゃると思いますが、操作自体はワンタップで
ユーザーに通知を送ることができます。

#特徴④ 登録も”QR読込→ワンタップ”で完了

#最後に
LINEの主な利用目的は「連絡手段」で認知でした。LINEもこういったサービスを手掛けているのに関心を向けれたことには大きな収穫と感じました。
STM8と液晶、ACM1602K-NLW-BBWでHello Worldを表示



x 原因は、わからないが液晶がちらつく場合は、ウェートを調整してね!!


STM8SでArduinoを使い16文字2行液晶に
Hello Worldを表示するプログラム

74hc164シフトレジスターを使用した。
液晶とのピン数を節約した。信号線10本から
信号線3本に減らした。

1 CLK クロック端子(緑)
2 RSDATA RS端子(黄)とデータの共有端子
3 E 読み込み書き込み同期信号(青)


PD0 E
PD2 CLK
PD4 DATA/RS
PD6


![o_con31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0d5628b8-ff2b-a911-6422-ea93f7bc9e99.jpeg)




h_con39.jpg


![h_con39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/580cd41e-e483-bd3c-4f57-5be5df774b13.jpeg)



```c++


//*          *****  *****  
//*         *       *    * 
//*         *       *    *
//*         *       *    *
//*         *       *    *
//********   *****  *****

#define DW   digitalWrite

#define en       PD0 // pin5
#define swdclk   PD2 // pin7
#define swdio    PD4 // pin9


//              12345678   12345678   12345678   12345678
char b8[8] = {0b10000000,0b01000000,0b00100000,0b00010000,
              0b00001000,0b00000100,0b00000010,0b00000001 };

//液晶に1文字を送る
//vは、キャラクター　rsは、アドレス　0コマンド　1キャラクター
void seg1(char v,char rs)
{
  for(char jj=0;jj<8;jj++){
    if( (v & b8[jj]) == 0 ){DW(swdio,0);/*ビットが0*/}else{DW(swdio,1);/*ビットが1*/}
    DW(swdclk,1);
    DW(swdclk,0);
  }//for

  DW(swdio,rs);   
  DW(en,1); delay(1);
  DW(en,0);       
}//seg1

//文字列の表示 nana_seg
int ns_printf(char *str1) {

    //文字の中身がゼロか
    while(*str1){

        //一文字出力
        seg1( *str1 ++ , 1  );

    } //while

    //戻り値
    return(0);
}//ns_printf

//液晶の初期化コード
int lcd_int[]={
  0x30,0x30,0x30,0x38,0x08,0x01,0x06,0x08+0x04
};//lcd_init

//初期化
void setup() {

  //GPIO初期化
  pinMode(swdclk,OUTPUT);
  pinMode(swdio,OUTPUT);
  pinMode(en,OUTPUT);
  DW(en,0);

  //液晶の初期化
  for(int ii=0;ii<8;ii++){ 
    seg1( lcd_int[ii] , 0);delay(2);
  }//for

}//setup

//メインループ
void loop() {

  seg1( 0x80+0x00 , 0  ); //1ライン目にカーソルを移動
  ns_printf( "HELLO WORLD!" ); //液晶に表示

  //無限ループ
  while(1){}

} //loop


```