OmniAICreator/Qiita-1.07M huggingface dataset:
【Windows】バッチファイル(BATファイル)の書き方

バッチファイルでバッチ処理やラッパーを書く際に、使用頻度の高い書き方を備忘録としてまとめました。

#バッチファイルの操作方法
BATの最初と最後に記述する内容は，ある程度決まっています。
冒頭と末尾は，便利なので暗記してしまいましょう。

```test.bat
@echo off

rem
rem このバッチの説明
rem

rem 設定事項
set HOGE="変数の値"

rem このバッチが存在するフォルダをカレントに
pushd %0\..
cls


〜処理〜


pause
exit
```

##1.「@echo off」で実行中のコマンドを非表示にする
 バッチファイルの冒頭には「@echo off」と記述します。これは、それ以下に記述されるコマンドをすべて画面に表示させないコードです。この記述がない場合、処理を実行するたびにコマンドが画面に表示されることになります。

　厳密には「echo off」が「以下のコマンドを非表示にする」記述です。「echo off」の前につける「@」は「行内のコマンドを非表示にする」記述です。「echo off」だけではそれ以下のコマンドしか消せず「echo off」自体が残るため、「@」を付けます。

##2.「rem」でコメントを記述する
「rem」と記述した後ろに入力した文章はコメントとして扱われ、処理の実行には一切影響しません。基本的には冒頭と各処理の行で活用します。

 冒頭では、そのバッチファイルの処理目的をコメントとして残します。何のために作ったバッチファイルなのか、後で分からなくならないようにするためです。

 そして各処理の行では、その処理の内容を記入しておくと、バッチファイル作成者以外の人が見ても理解しやすくなります。

##3.「set」で環境変数を設定する
「set」と記述し、それ以下に環境変数（OSが管理している変数）を記述します。

##4.「pushd」でディレクトリの移動。
　pushdコマンドでディレクトリを移動できます。cdコマンドだと異なるドライブに移動できないため、ドライブの違いやネットワークの違いを気にせず移動できるpushdコマンドを使用しています。
　%0.. は，このバッチファイルが存在するフォルダを指しています。したがって，バッチの存在ずるフォルダをカレントディレクトリにすることができます。

#まとめ
バッチファイルとは、一連の処理を記述したものであり、それをまとめて実行するためのテキストファイルです。バッチファイルで処理を自動化でき、人為的ミスや手間の削減に役立ちます。

Windows環境下ではメモ帳を使って作成可能です。コードを記入して拡張子を「.bat」に変更し、コマンドプロンプトから実行できます。

この記事を参考にして、バッチファイルを有効に活用できるようにしていきましょう。
NCMBのSwift SDKを使ってmacOS用CLIアプリケーションを作る

XcodeではCLI（コマンドラインインタフェース）なアプリを開発できますが、その中でもNCMBのSwift SDKを使ってみます。これができれば、ちょっとした管理用ツールを作るのが手軽になるでしょう。

## プロジェクトを作る

Xcodeでの新規プロジェクト作成時にCommand Line Toolを選択します。

![ScreenShot_ 2021-08-02 9.56.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/a63a3aa9-7fb8-1dcf-8460-ae90da3c3207.png)


## SDKのインストール

NCMBのSwift SDKをインストールするのはSwift Packagesを使うのが簡単でしょう。FileメニューからSwift Packages > Add Package Dependencyと選択します。

![ScreenShot_ 2021-08-02 9.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/7f1bd23f-24dd-7bcd-ab39-1bffd9c8eddf.png)


出てきたダイアログでSwift SDKのGitリポジトリURLを入力します。GitHubのリポジトリでHTTPSとして取得できるもの、または下記URLになります。

![ScreenShot_ 2021-08-02 9.35.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/55faa7fa-9f31-5439-88af-ff4ed0b2169d.png)


```
https://github.com/NIFCLOUD-mbaas/ncmb_swift.git
```

バージョンは最新のものでかまいません。


![ScreenShot_ 2021-08-02 9.36.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/4b256ddb-880d-c930-751b-1c2674299668.png)

後はFinishボタンを押せば完了です。

![ScreenShot_ 2021-08-02 9.36.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/5c3e59c0-6469-7d6f-006d-be734a11342f.png)


## Swift SDKの修正

実はそのままでは使えないので `NCMB/service/NCMBFileService.swift` を開きます。そして `MobileCoreServices` をインポートしないようにします。

```swift
import Foundation
// import MobileCoreServices
```

## 使い方

実際のコードです。まず Swift SDKをインポートします。

```swift
import Foundation
import NCMB // 追加
```

そして初期化します。初期化時のキー（アプリケーションキーとクライアントキー）はNCMBの管理画面より取得してください。

```swift
NCMB.initialize(applicationKey: "YOUR_APPLICATION_KEY", clientKey: "YOUR_CLIENT_KEY")
```

注意点としては、NCMBはネットワーク処理が基本なので、非同期処理になるということです。そこで `DispatchGroup` を使っていきます。

```swift
let dispatchGroup = DispatchGroup()
```

非同期処理の開始時に実行します。

```swift
dispatchGroup.enter()
```

NCMBの処理を書いていきます。

```swift
// クラスのNCMBObjectを作成
let object : NCMBObject = NCMBObject(className: "TestClass")
// オブジェクトに値を設定
object["message"] = "Hello, NCMB!"
// データストアへの登録
object.saveInBackground(callback: { result in
    switch result {
    case .success:
        // 保存に成功した場合の処理
        print("保存に成功しました")
        // 非同期処理を抜ける
        dispatchGroup.leave()
    case let .failure(error):
        // 保存に失敗した場合の処理
        print("保存に失敗しました: \(error)")
    }
})
```

すべての非同期処理が終わったタイミングで `dispatchGroup.notify` が呼ばれます。

```swift
dispatchGroup.notify(queue: DispatchQueue.main) {
    print("Hello, World!")
    exit(EXIT_SUCCESS)
}
```

後は処理の開始です。

```swift
dispatchMain()
```

これでCLIとして、NCMBを使えるアプリケーションができあがります。

## まとめ

コマンドライン引数を扱う場合には Commander などを使えば良いでしょう。より複雑な処理を行う際には、Swift SDKの同期処理メソッドを使ってください。

ぜひCLIでもNCMBを役立ててください！

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)
AtCoderログ：0051 - ABC 156 B

# 問題

https://atcoder.jp/contests/abc156/tasks/abc156_b

## 問題文
> 整数 $N$ を $K$ 進数で表したとき、何桁になるかを求めてください。

## 制約
> ・入力は全て整数である。
> ・$1 \le N \le 10^9$
> ・$2 \le K \le 10$

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067) ([第05問類題](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-5-%E5%95%8F--abc-083-b---some-sums-200-%E7%82%B9))

# 回答
## 回答1 (AC)
例えば $1234$ という整数は $1 \times 1000 + 2 \times 100 + 3 \times 10 + 4$ (1つの1000と2つの100と3つの10と4の和) という構造になっています。ここで$1000,100,10$ はすべて $10$ のべき乗 ($1000=10^3$, $100=10^2$, $10=10^1$) に由来しているため、このような整数の表し方を10進法と呼びます。今回は $K$ 進法表記の問題なので、$10$ のべき乗の代わりに $K$ のべき乗を使用します。

再び n=1234 の例で k=10 のときに各桁の求め方を考えてみましょう。最下位の 4 は n%10 で求められます。10 の位の 3 は n/10 の最下位なので、(n/10)%10 で求められますが、別の見方をすると、(最下位の 4 を求めた後に) n を n/10 で置き換えた上で n%10 で求めることもできます。同様に、さらに n を n/10 で置き換えた上で n%10 を求めると 100 の位 2 が得られます。最後に、さらに n を n/10 で置き換えた上で n%10 を求めると 1000 の位 1 が得られます。最後に n を n/10 で置き換えると値は 0 になるので、全ての桁が計算できたことがわかります (下表参照)

n の値|n%10|n/10
------|----|----
1234  |4   |123
123   |3   |12
12    |2   |1
1     |1   |0

処理手順としては、$K$ 進法で表記した値を保持するための文字列 s (最初はヌル)を用意します。$K$ 進法における最下位の値は n%k となるので、この値を文字列として s に保存し、n を n%k で置き換えます。この処理を n が 0 になるまで繰り返します。n が 0 になると、文字列 s に $K$ 進法表記が完成しているので、その桁数 s.size() を出力して終了となります。コードは以下のようになりました。

```C++:abc156b-1.cpp
#include <bits/stdc++.h>
using namespace std;

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

  string s = "";
  while ( n>0 ) {
    s += to_string(n%k);
    n =  n/k;
  }
  
  cout << s.size() << endl;
}
```

# 回答2 (AC)
問題では $N$ を $K$ 進法で表した時の桁数を聞かれているので、$K$ 進数での表現は必要ありません。そこで桁数を直接計算してみましょう。

例えば $10$ 進法で $2$ 桁の整数は $10$ 以上 $99$ 以下ですが、これは $10^1$ 以上 $10^2-1$ 以下と表すことが出来ます。同様に、$10$ 進法で $m$ 桁の整数 $x$ は $10^{m-1} \le x \le 10^m-1$ となります。ここで両辺の対数をとると $\log_{10}{10^{m-1}} \le \log_{10}{x} \le \log_{10}{(10^m-1)} < \log_{10}{10^m}$ となり $m-1 \le \log_{10}{x} < m$ が得られます。この式が言っているのは「$m$ 桁の整数 $x$ の対数値は $m-1$ 以上 $m$ 未満である」ということです。従って、整数 $x$ の(底が $10$ の)対数値の小数点以下を切り捨てれば $m-1$ が得られる、つまり「整数 $x$ の桁数は $\lfloor \log_{10}{x} \rfloor +1$ 桁である」ことがわかります (ここで $\lfloor a \rfloor$ は $a$ の小数点以下を切り捨てる関数)。

問題は整数 $N$ を $K$ 進数で表した時の桁数を聞いているので、$10$ 進数と同じように考えて、桁数は $\lfloor \log_{k}{x} \rfloor +1$ となります。通常、$\log_k$ という関数は用意されていませんが、対数関数の性質より、$\log_{k}{x}=\log_{10}{n}/\log_{10}{k}$ となるので、簡単に計算可能です。コードは以下のようになりました。

```C++:abc156b-2.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n, k;
  cin >> n >> k;

  int ndigit = int(log(n)/log(k))+1;

  cout << ndigit << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc156/tasks/abc156_b/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2020/02/24/091729)
k で割り切れる回数から桁数を求めていました。

## [AtCoder の解説](https://atcoder.jp/contests/abc156/tasks/abc156_b/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/abc156/editorial.pdf)
こちらも k で割り切れる回数から桁数を求めていました。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0050 - ABC 212 A](https://qiita.com/RoadLynton/items/2d02c750d4977ba2a159)
- 次の記事 → [AtCoderログ：0052 - ABC 212 B](https://qiita.com/RoadLynton/items/6bfd748018f6872da0d6)
Vue.jsでブラウザバックを検知する方法

## 概要
ブラウザバックを検知して、Vue.jsのプロパティに論理値をセットすることによってVueコンポーネント内でブラウザバックしたかどうかを判定できるようにする。

## プログラム
### Vue.jsのプロパティに「$browserBackFlg」をセット

```js:app.js
// ブラウザバックを検知してコンポーネントで「this.$browserBackFlg」で使用できるようにする。
Vue.prototype.$browserBackFlg = false
history.replaceState(null, '', null)
window.addEventListener('popstate', function() {
  Vue.prototype.$browserBackFlg = true

  window.setTimeout(() => {
    Vue.prototype.$browserBackFlg = false
  }, 500)
})
```

#### `history.replaceState(stateObj, title, [url])`
現在の履歴を編集し、メソッドに渡された `stateObj`、`title`、`URL`パラメータによって置き換えます。
強制的に履歴を残すことで、履歴が変更されたことを検知させます。
https://developer.mozilla.org/ja/docs/Web/API/History/replaceState

#### `window.addEventListener('popstate', function() {})`
`popstate`をイベントリスナーに登録することにより、履歴項目が変わるたびにウィンドウに発行されます。

#### `window.setTimeout(() => , 500)`
`window.setTimeout`を使用して500ミリ秒後に「$browserBackFlg」をfalseにします。
これがないと、永遠に「$browserBackFlg」がtrueのままになってしまいます。

### セットした「$browserBackFlg」を使ってVueコンポーネント内でブラウザバック検知

```vue:Home.vue
<script>
export default {
  created() {
    if (this.$browserBackFlg) {
      // ブラウザバック時の処理
    }
    else {
      // ブラウザバック時でなく普通のページ遷移のときの処理
    }
  }
}
</script>
```
しておくと便利かもしれないRailsの設定

備忘録。Railsのバージョンは6.1。環境はWSL

## 開発環境周り
### ログをターミナルに出力する
````config/environments/development.rb
config.logger = Logger.new(STDOUT)
````

### 編集を開発サーバーに即反映
````config/environments/development.rb
config.file_watcher = ActiveSupport::FileUpdateChecker
````

### js更新しても勝手にコンパイルしない
WSLだと重い

````config/webpacker.yml
development:
  <<: *default
  compile: false
````

### assets(css)のデバッグモードオフ
何故かcssが開発途中で反映されなくなるため

````config/environments/development.rb
config.assets.debug = false
````

## View周り
### formのlocal(remote)をデフォルトでtrue
基本的にvalidationエラーとか非同期で返すため

````config/application.rb
class Application < Rails::Application
  config.action_view.form_with_generates_remote_forms = true
end
````

## テスト周り
### 逆マッチャーの定義
````spec/rails_helper.rb
RSpec::Matchers.define_negated_matcher :not_change, :change
RSpec::Matchers.define_negated_matcher :not_match, :match
````

### selenium chrome
````spec/rails_helper.rb
Capybara.server = :puma
Capybara.javascript_driver = :selenium_chrome

Capybara.register_driver :selenium_chrome_headless do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new
  options.add_argument '--no-sandbox'
  options.add_argument '--headless'
  options.add_argument '--window-size=1400,1400'
  options.add_argument '--disable-dev-shm-usage'
  Capybara::Selenium::Driver.new app, browser: :chrome, options: options
end

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :selenium_chrome_headless
  end
end
````

### factoryの生成場所指定
rails g factory_bot:modelするときの

````config/application.rb
class Application < Rails::Application
  config.generators do |g|
    g.factory_bot dir: 'spec/factories'
  end
end
【Python3】opencvで画像の品質を出来るだけ落とさず縮小する【初心者向け】


cv2.resizeをデフォルト設定で行うと、画像の品質が劣化する。

cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) → dst

画像の縮小には interpolation=INTER_AREA、拡大には INTER_CUBIC(処理遅め)、またはINTER_LINER(速くて見た目もよい)を使用すると良いようだ。

https://www.tutorialkart.com/opencv/python/opencv-python-resize-image/

>[optional] flag that takes one of the following methods. INTER_NEAREST – a nearest-neighbor interpolation INTER_LINEAR – a bilinear interpolation (used by default).INTER_AREA – resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method. INTER_CUBIC – a bicubic interpolation over 4×4 pixel neighborhood INTER_LANCZOS4 – a Lanczos interpolation over 8×8 pixel neighborhood.

イラストだと劣化がわかりにくいため、文章のファイルを使用する。
試しに「吾輩は猫である」の冒頭をスクショ。画像として保存。

https://www.aozora.gr.jp/cards/000148/files/789_14547.html

### オリジナル画像(shape=(1590, 2621, 3))
![neko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/ad9f5b4b-a862-7921-7467-3762546e8ef7.png)

### コード
```py
from PIL import Image
import cv2

img = cv2.imread("./neko.png")
height, width = img.shape[:2]
resized_img = cv2.resize(img, (width//3, height//3))
resized_img2 = cv2.resize(img, (width//3, height//3), interpolation = cv2.INTER_AREA)

Image.fromarray(resized_img).save("./tmp.png")
Image.fromarray(resized_img2).save("./tmp2.png")
```

### 1/3に縮小　interpolation=INTER_LINEAR(デフォルト設定)の場合
![tmp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/8ff74e64-4716-c9da-97e7-f7312926d887.png)

### 1/3に縮小　interpolation=INTER_AREA)の場合
![tmp2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/03b1909e-36f3-5b65-7d7c-ded6f0bd6fc1.png)

こうしてみると、縮小の方法ひとつで画像の品質が大きく変わることがよくわかる。
独学プログラマーのまとめ　その6

#初めに
やり遂げる。

###7章　ループ

- 始さえすれば、8割は成功したようなものだ。
   - 残り2割が果てし無い...
- forループ
   - **forループ**は、イテラブルを繰り返し処理するために使われ、**反復処理**と言う。1ループごとにイテラブルから渡される要素を、コード群で使用したり、操作したりする。

forループ構文は以下のように定義される。

```
for [変数名] in [イテラブル]
    [コードブロック]
```
 [変数名]には自由に名前を指定して[イテラブル]の要素を割り当てるために使える。

```python

name = "Ted"
for character in name:    
    print(character)
```
> T
> e
> d

変数名にcharacterを自由に指定し、イテラブルなnameの先頭から新しい要素として一文字ごと出力している。

同様にforループでリスト、タプルの処理をさせると各要素を出力させる。


```python

shows = ["GOT", "Narcos", "Vice"]
for show in shows:
    print(show)
coms = ("A. Development","Friends","Always Sunny")
for show in coms:
    print(show) 
```
> GOT
> Narcos
> Vice
> A. Development
> Friends
> Always Sunny

辞書式では辞書のキーを要素として繰り返す。

```python
people = {"G. Bluth II":"A. Development", "Barney":"HIMYM","Dennis":"Always Sunny"}
for character in people:
    print(character)
```
> G. Bluth II
> Barney
> Dennis

注意として出力の順番は異なる場合がある。それはPython3.6まではキーの順番が保持されるかどうかは実装依存だったから。

繰り返しの何回目かを表す整数値の変数である**インデックス変数**をもちいてミュータブルなイテラブルを更新する例

```python
tv = ["GOT","Narcos","Vice"]
i = 0
for show in tv:
    new = tv[i]
    new = new.upper()
    tv[i] = new
    i += 1
print(tv)
```
>['GOT', 'NARCOS', 'VICE']

Pythonには、各要素のインデックス値を自動的に用意してくれる、enumerate関数がある

```python

tv = ["GOT", "Narcos", "Vice"]
for i, new in enumerate(tv):   # 変数名のところに2つかける
    new = tv[i]                
    new = new.upper()
    tv[i] = new
print(tv)
```
> ['GOT', 'NARCOS', 'VICE']

- range
    - 組み込み関数rangeは、整数を順番に生成する。2つの引数として開始値と、終了値を指定できる。注意として二つ目の引数はその値を含まないこと。例としてrange(1,11)とした場合は、1~10の数字が生成される。

```python

for i in range(1, 11):
    print(i) 
```
> 1
> 2
> ・・・
> 10

- whileループ
    - **whileループ**は式がTrueに評価されている間にコードの実行を繰り返す。
    - 終了しないループを**無限ループ**と呼び、PythonではControlを押しながらcキーを押すととまる。

```python

x = 10
while x > 0:
    print('{}'.format(x))
    x -= 1
print("Happy New Year!")
```
> 10
> 9
> ...
> 1
>'Happy New Year!'

-　break
    -　**break文**はループを終了するための文。Pythonはbreak文に到達するとすぐループを終了する。

- continue
    -**continue文**は、実行中の反復処理を途中で終了して、次の反復処理を開始する。break文とは違いcontinue文ではループは終了しない。

```python
for i in range(1, 6):
    if i == 3:
        continue
    print(i) 
```
> 1
> 2
> 4
> 5

- 入れ子のループ
    - ループの中のループなどの2重、3重ループなどを作成できる。

#終わりに
ループ処理は大事なので丁寧に勉強した。
Railsで複数選択可能なselectタグを実装する

## したいこと
複数選択可能なドロップダウンセレクトタグをさくっときれいに実装したい。

## 使うもの
[bootstrap-select](https://developer.snapappointments.com/bootstrap-select/)
色々探した中で一番シンプルかつ高機能で良さげだった。因みに[MDBootstrap](https://mdbootstrap.com/docs/standard/)ってのでもほとんど同じかんじのが導入できるけど有料(1年で2万円とか。でもめっちゃ高機能だしBootstrapみがない。どっかでみたことある)

## bootstrap-selectの導入
### Bootstrapの導入(※v5, '21/08/03時点でv5対応バージョンはベータ版)
以下を参照
https://qiita.com/kazutosato/items/d47b7705ee545de4cb1a

その後に以下を追記(※正規版だと必要ないかも)

````config/webpack/environment.js
const webpack = require('webpack')
environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    Popper: 'popper.js',
    bootstrap: 'bootstrap' // 追記
  })
)
````
### bootstrap-selectの導入
アプリのディレクトリで以下のコマンドを実行(※最新バージョンは08/03時点でベータ版なのでgitのリポジトリからインストールする)

````
$ yarn add https://github.com/snapappointments/bootstrap-select
````
````app/assets/stylesheets/application.scss
/*
 *= require_tree .
 *= require_self
 *
 *= require bootstrap/scss/bootstrap
 *= 以下を追記
 *= require bootstrap-select/sass/bootstrap-select
 */
````
````app/javascript/packs/application.js
import "bootstrap"
import "bootstrap-select" // 追記
````
## 実装
例) Groupモデルがmembersをhas_manyしていて、新しいgroupのmembersのidの配列を受け取る。

````groups_controller.rb
def new
    @followers = current_user.followers
    @group = current_user.own_groups.build
end

private
    def group_params
        params.require(:group).permit(:name, :desc, members: []) # column: []
    end
````

````app/view/groups/new.html.haml
= f.label :members, class: "form-label"
%select.selectpicker.border.rounded{name: "group[members][]", # object[method][]
                                    multiple: true,           
                                    data: {actions: {box: "true"}}}
    - @followers.each do |follower|
        = tag.option follower.name, value: follower.id
````
f.select, select_tagはmultiple適用できない?しdata属性を設定できないので使わない。
そのまま書くときのポイントは値を配列で返すため、[ ]が所々必要。
何も入力しないとf.selectとかと違ってそのままnilになるので注意。(f.selectは [" "] が返ってくる)
その他bootstrap-selectの機能に関しては以下を参照。

https://developer.snapappointments.com/bootstrap-select/examples/
【Mac】cv2のImportError(Reason: image not found) 

### エラー内容
```
ImportError: dlopen(/Users/user/venv/lib/python3.8/site-packages/cv2/cv2.cpython-38-darwin.so, 2): Library not loaded: /opt/homebrew/opt/ffmpeg/lib/libavcodec.58.dylib
  Referenced from: /Users/user/venv/lib/python3.8/site-packages/cv2/cv2.cpython-38-darwin.so
  Reason: image not found
```

### 環境
+ homebrew 3.2.5
+ python 3.8
+ venv

### 状況

仮想環境上にてpipを使用しopencvをインストール後、importした時にエラーに遭遇

```
$ pip install opencv-python
$ python3
$ import cv2
```

### 解決策(備忘録)
ターミナルを開き、homebrewを使ってopenCVをインストール

```
$ brew install opencv
```

### 参考

https://qiita.com/makki_maki04/items/f62c5e4e68709d9b3b89

「ググれよ自分」と言いたくなるが、homebrewを使い慣れていない状況で
この手のエラーに遭遇すると原因がわからず混乱する。

windows、mac、linuxなど複数のOSを使用していて、同じようにimport出来ると思い込んでいると沼にハマる。
Laravelでblade内での認可

#はじめに
Gateでアクセス制限を定義したのち、blade内で権限によってコンテンツの表示非表示を決めていきます。

###Gateでの定義

`AuthServiceProvider.php`において

```php
    public function boot()
    {
        $this->registerPolicies();

        Gate::define('teacher',function ($user){
            return($user->role == 1);
        });

        Gate::define('student',function ($user){
            return($user->role == 2);
        });
    }
```


このように定義しておきます。

###bladeでの認可

- `@can`ディレクティブ

```php
@can('teacher')
<p>you are teacher!</p>
@elsecan('student')
<p>you are not teacher!!</p>
@endcan
```

- `@canany`ディレクティブ

認可対象が複数の場合は `@canany`ディレクティブを使うと纏まります。


```php
@canany(['teacher','student'])
<p>you are teacher or student!</p>
@endcanany
```

これらのディレクティブは他にもGateで定義した際の引数を持たせたりできます。
以下をご参考に。
[認可 6.x Laravel](https://readouble.com/laravel/6.x/ja/authorization.html)

以上！
2021/08/01開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[tecHub Meetup #08](https://techub.connpass.com/event/219447/)|[tecHub](https://techub.connpass.com/)|28|40|
|:two:|[[オンライン]UOZUゲームジャム-Hot!Summer!!-](https://uozu.connpass.com/event/216479/)|[つくるUOZUプロジェクト](https://uozu.connpass.com/)|28|75|
|:three:|[オンラインもくもく会【コーヒー飲みながら参加しませんか？】35回目](https://mame-coffee-programing.connpass.com/event/220370/)|[まめコーヒー](https://mame-coffee-programing.connpass.com/)|24||
|:four:|[Type Sets Proposal 勉強会](https://gospecreading.connpass.com/event/220389/)|[Go Language Specification 輪読会](https://gospecreading.connpass.com/)|23|28|
|:five:|[SMCN #07 フォトグラメトリ活用3DCGデータ制作勉強会（超初心者向け）](https://chiikiokoshi-vr.connpass.com/event/217913/)|[地域おこしXR研究会](https://chiikiokoshi-vr.connpass.com/)|21|119|
画面右下に出てくるキャプチャーボード画面の対処法

#はじめに
ある日PCを付けるとキャプチャーボードの画面が右下に出てきた
他のソフトで認識されなくなるし、邪魔だしで対処したときの備忘録

画面右下。
スクショには映らないため直撮り
![E6eUpsRUUAMJFMX.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121230/1f830c08-7572-9511-4313-379e431358fa.jpeg)

#原因
NVIDIAのGeForce Experienceが悪さしていたみたい。
キャプボの画面取り込みがカメラと認識されていて表示されていた。

#対処法
1.[Alt+Z]で設定画面を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121230/d59e3a40-ad8c-146f-bb3f-a0c4fe6a20f9.png)

2.[設定]ボタンをクリック
3.[HUBレイアウト]ボタンをクリック
4.[カメラ]ボタンをクリック
5.おそらく位置のどこかに設定されてしまっているので[オフ]に設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121230/7f143e79-490e-28ff-2b6d-37c509c05313.png)

#備考
設定をオフにしてもGeForce Experienceにキャプボの画面入力が引っ張られて、他ソフトでの認識がされないかもなので
オフにした後は一度OS再起動を挟んだほうがいいかも

#終わりに
キャプボがカメラ認識されるのはまぁ...仕方がないかなって感じ
ただ、この手のオーバーレイは、触れない（クリック、ドラック＆ドロップ等できない）ので、
デフォルトでオンになってると対処法が見つけにくいですね。
GeForceExperienceのインスタントリプレイマークの対処法ページがいっぱいあるのも頷ける。
日記 AnyDeskの操作中に日本語入力で困らないためのWindowsアプリを作った

## ダウンロード

https://github.com/Yamine1San/ImeOffAnyDesk/releases/tag/v1.0.0

## 説明

AnyDeskで日本語を入力しようとすると、リモートPCとホストPCの両方のIMEがONになって、うまく入力ができなくて困るので、AnyDeskで操作中にはホストPCだけIMEがOFFになるようタスクトレイに常駐して監視するアプリです。これでストレスフリーなAnyDeskライフが送れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1765459/76b5d3af-5f27-5b11-7b3b-bdfca6d92f4a.png)

## 操作方法

起動するとタスクトレイに常駐します。
その状態でAnyDeskでリモートPCを操作中にIMEをONにするとOFFになります。
終了させるにはタスクトレイのアイコンを右クリックして終了を選択してください。
頻繁にAnyDeskを使う人は、スタートアップにショートカットを入れておくといいかも。

## 処理詳細

### AnyDeskでリモートPCを操作中の判定

フォアグラウンドのアプリがAnyDesk.exeであり、ウインドウタイトルが「 - AnyDesk」で終わっている事。

### 処理の内容

1秒おきにAnyDeskでリモートPCを操作中か判定
操作中の場合、0.2秒おきにIMEの状態をチェックし、ONになっていたらOFFにする。
ランダムで特定のユーザーにかつカラムの値だけを表示(Laravel)

プログラミング初心者です。

##やりたい事
特定のユーザーのWord Modelの値をランダムに取得したい。
##まずはWord Modelの値を取得するにはとやってみた事
調べるとinRandomOrder()使うと出てきたので、まずこのコードを書いてみました。

```php
$word_random = Word::inRandomOrder()->first();
```
first()はひとつだけ取得し、返り値はインスタンスです。

でもこれだと、WordModelを全て取得してしまいます
wordカラムのだけ表示したいので、カラム指定できるselect()を使いました

```php
$word_random = Word::inRandomOrder()->select('word')->first();
```
そして表示したいところに

```php
$word_random["word"]
```
["word"]は連想配列で、ないと、{word:word1}と波括弧とカラム名まで出てきてしまいます
wordがkeyになっているので指定してあげます。

ただModelの値をランダムならここまでの方法でいいと思います。

##特定のユーザーへ
かなりコードが変わりますが、結論これになりました。

```php
$word_random = User::find(1)->words->random();
```
###解説

- User Model同士をWord Modelをリレーションさせました。
- Word Modelにuserのidを保存するようにしています。
- User::find(1)　idで、該当のUserレコードを取得。
- User Modelのリレーションに定義したwordsで、該当のWordレコードを取得。
- random()でWord Modelの値をランダムに返します。
- 表示したいところには、上記の記載方法で大丈夫でした。

###備考
- wordsはcollection(配列)を返すため、inRandomOrder()だとエラーが出ました。
GoogleAppsScriptを利用して日報と週報を書きやすくした

# Google Apps Scriptとは

Googleドライブで利用できる「html,gs(ECMAScript)」が利用できるサービス
早い話が下のやつ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/8953ce52-64a4-7c28-ba91-f01faefabbe5.png)


#やったこと
職場では日報とそれをまとめた週報をメールで送信している。
日報は毎日内容を書く必要があるが、週報は日報の内容をまとめればOKの感じだった。

そこで、日報用のホームを作成した。bootstrapを利用して簡単に作った。

#日報フォーム
下のような感じで、必要報告事項が羅列してある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/70ac7a49-9511-f37b-3412-dcbd926d1c0a.png)
※この記事用に個人用に別途用意した。本当はもっといろいろあります。

全て書き終えると所定のフォーマットメールを自動作成してGmailの下書き保存される、あとは送るだけ
この際に、名前や苗字はクッキーに保存しており次回からは入力があまり必要ないようにしている。

GoogleFromでもできたかもしれんと思ってる。

#週報
週報については、日報で書いた内容の一部をスプレッドシートに保存しておき、毎週月曜日に自動的にフォーマットされたメールを作成して送信してくれるようにした。
勝手に送られててたまにビビる

#結果
日報のフォーマットをメールにコピペしていた時よりも効率は良くなりました。
週報については勝手にやってくれるので本当に楽です。

職場はgoogle workspaceを利用している為、日報を書くのが面倒でgoogle workspaceを利用している人にはお勧めです。
日報をGmailの下書きに保存しているのは、運用上幅を持たせるため行いました。
GmailでAPIから署名付きでメールを送る方法

##メールに自動的に署名は付かない
gmailでAPI経由でメールを送信する際、署名を付ける方法がわからなかったので調査しました。
日本語の記事がほとんど見当たらず、結構詰まったので残しておきます。
railsでの書き方になりますが、gmailのAPIとして提供されている機能ですので、他言語でも対応する書き方が存在するはずです。

##結論
署名などのユーザー設定的なものを扱う**SendAs**なるクラスが存在するため、自身のメアドを指定してそれを取得します[1]。
取得できたsend_asの**signature**（署名）を参照すると、署名を文字列として取得できます。

```ruby
require 'google/apis/gmail_v1'

Gmail = Google::Apis::GmailV1 # Alias the module
service = Gmail::GmailService.new
send_as = service.get_user_setting_send_as('me', 'my-address@gmail.com')
pp send_as.signature
# これで署名が表示されるはず
```

あとはこの署名を本文の下にくっつけて、署名付きメールの完成です。

※当初、メール送信メソッドの引数に「署名付与フラグ」的なものがあると思ったのですが、それとおぼしき引数はありませんでした。
現状、自分が調べた限りではこのような方法でしか署名を付けられそうになかったのですが、他のやり方あれば教えていただきたいです、、、

##プレーンテキストへの変換
自分はプレーンテキストの署名が欲しかったのですが、どうもhtml形式でしか取得できなさそうです[2]。

railsでは、**html2text**というhtmlをいい感じにプレーンテキストに変換してくれるgemがあったため、こちらを利用しました[3]。

##参考サイト
[1] SendAsの取得メソッド
https://googleapis.dev/ruby/google-api-client/v0.34.1/Google/Apis/GmailV1/GmailService.html#get_user_setting_send_as-instance_method
[2] SendAsの詳細
https://googleapis.dev/ruby/google-api-client/v0.34.1/Google/Apis/GmailV1/SendAs.html
[3] html2text
https://github.com/soundasleep/html2text_ruby
[wave.py] Pythonで手っ取り早く音を生成してwav書き出しする

# 使うもの
Python組み込みモジュールの[wave.py](https://docs.python.org/ja/3/library/wave.html)を使います。

# 前提
24bit などを扱うと面倒(*1)なので、ここでは 16bit int, 44.1kHz の音源を作ります。

# 実装
```python:main.py
import wave
import numpy as np
from random import uniform
from struct import pack

# 保存するwaveファイルのファイル名を指定
filename = './output.wav'

# チャンネル数
n_ch = 2  # 1: mono, 2: stereo

# サンプル幅（ビット深度を8で割った値）
s_width = 2 # 2: 16bit, 3: 24bit, 4: 32bit

# サンプリング周波数
s_rate = 44100  # Hz

# 音源の長さ（ここでは3秒とする）
t_length = 3 # sec

# サンプル数
n_samples = t_length * s_rate


# この後で使う波形を定義しておく
def sin(t, f):
    return np.sin(2*np.pi*f*t)

def tri(t, f):
    u = int(2*f*t + 0.5)
    return (-1)**u * (4*f*t - 2*u)

def sqr(t, f):
    return 1 if 0 <= f*t - int(f*t) < 0.5 else -1

def saw(t, f):
    return 2*f*t - 2*int(f*t + 0.5)

def noise():
    return uniform(-1, 1)


# data_array には1サンプルごとにL, Rの順番で変位の値(int)が入る
# 各要素は -32768～32767 の範囲内に収める必要がある
data_array = []

# 最大振幅
A_max = 32767  # = 0.5 * (2**16) - 1

for i_samples in range(n_samples):
  # 秒単位での時間
  t_i = i_samples / s_rate # sec

  # ここで sin の代わりに saw などを用いると音色が変わる
  L_i = A_max * sin(t_i, 440)
  data_array.append(int(L_i))

  R_i = A_max * sin(t_i, 440)
  data_array.append(int(R_i))


# wav 書き出し
with wave.open(filename, 'w') as wf:
    wf.setnchannels(n_ch)
    wf.setsampwidth(s_width)
    wf.setframerate(s_rate)
    data_binary = pack("h" * n_ch * n_samples, *data_array)
    wf.writeframes(data_binary)
```

# 実行
```python main.py```と実行すれば output.wav が出てきます。

# おわり
色々パラメータを変えて遊んでみて下さい。

# 参考文献
(*1) [Pythonでのwavファイル操作](https://qiita.com/Dsuke-K/items/2ad4945a81644db1e9ff)
(*2) [pythonのwaveモジュール](https://qiita.com/bayachin/items/68f7659d31fa6c836317)
macのDockerが遅い。cachedやdelegatedでも遅い。

#問題
VSCodeのdevcontainerを使ったPHPプロジェクトで動作がどうやっても遅かったのですが、最終的にはContainer Volumeを使って高速に動作するようになりました。
マウントの方式にcachedやdelegatedを利用することで気持ち早くはなりますが、やはりファイルの検索や、アプリケーションの実行速度には限界があるのではないでしょうか。
世の中にはやはり同じ問題に当たっている人がいるようで、[公式の記事](https://code.visualstudio.com/docs/remote/containers-advanced#_use-clone-repository-in-container-volume)でContainer Volumeを使ったやり方が記載されていたので試してみました。

#結論
結論から言うとパフォーマンスはLinuxでネイティブに動作させている時と遜色ないものとなりました。
DockerのContainerは捨てて作り直すことも多いですが、その際にも生き残るので使い勝手も必要十分です。

#課題
* マウント先は2021年8月現在`/workspaces`決め打ちなので、`.devcontainer`内の定義は更新が必要。
* Rebuild Containerで0リセットになると認識しているメンバーがいるとつまづくので認識してもらう必要あり。
* ブランチを指定して手元の環境に影響なく別環境を立てられるのが売りになっていますが、ポートの指定などが重複した際にうまく回避するような魔法はないので、そこは要注意。
bashのコンパイルについて

この記事は、bashのソースを読みたいがコンパイルの仕方を知らない人向けに書きます。

bashは以下の手順でコンパイルできます。

```sh
$ wget https://ftp.gnu.org/gnu/bash/bash-5.1.tar.gz
$ tar -xzf bash-5.1.tar.gz
$ cd bash-5.1
$ CFLAGS="-g -O0" ./configure
$ make -j 7
```
この手順が完了すると、カレントディレクトリ内にbashという実行ファイルができています。


*************************************************************************************
[追記]
akinomyogaさんから教えていただきました。
ソースを読むには、開発版のほうが適しているそうです。
（デバッグ用のコードやデバッグ用のmallocが有効になる。）

上記のコードの以下のように変更します。

```sh
$ git clone git://git.savannah.gnu.org/bash.git
$ cd bash
$ CFLAGS="-g -O0" ./configure
$ make -j 7
```
*************************************************************************************

以下に各行の大まかな意味を書きます。

```sh
$ wget https://ftp.gnu.org/gnu/bash/bash5.1.tar.gz
```

このコマンドでbashのソースをダウンロードします。
wgetとはnetwork downloaderです。
詳しくはman wgetとかで調べるといいと思いますが、

適当に

```sh
$ wget https://google.com
```
とかをやってみると、何をやっているのか解ると思います。


```sh
$ tar -xzf bash-5.1.tar.gz
```
これでファイルを展開します。（man tarを参照)


```sh
$ cd bash-5.1
```
カレントディレクトリを変更します。

```sh 
$ CFLAGS="-g -O0" ./configure
```

このコマンドで、Makeというビルドツールに使う
Makefileというファイルを生成します。
Makeは内部でgccを呼び出しています。

```sh
$ ./configure
```
だけでもMakefileは生成されますが、
コンパイル時に使うフラグを指定するために

```
$ CFLAGS="-g -O0" ./configure
```
とします。
フラグ -g を使うことで、コンパイルされるオブジェクトファイルにデバッグ情報を埋め込みます。
フラグ -O0 を使うことで、最適化レベルを最低にします。
gccはコンパイル時に最適化という処理を行っており、
このフラグがない場合、ソースコードとオブジェクトファイルの対応が
変わってしまい、ソースの追跡が難しいです。


```sh
$ make -j 7
```

ビルドします。
フラグ" -j n "を使うことで、マルチプロセスでビルドしてくれるため、ビルドが早く終わります。nは整数です
この場合は７を指定することで７つのプロセスで分割してビルドしています。


以上が終わると、カレントディレクトリ内にbashという実行ファイルができています。

すべてをもとに戻したい場合は


```sh
$ make clean
```

とすれば、実行ファイル、Makefileなどがすべて消えるので、またはじめからやり直せます。
適当なフラグを指定して、実験してみると何が起こっているのかわかります。


ビルド　　　＝　コンパイルやリンクなど様々な処理を経て、実行ファイルを生成すること
コンパイル　＝　ソースコードからリンクする前のオブジェクトファイルを生成すること
リモート環境で Wio Terminal で組み込み Rust を動かしてみるハンズオン

組み込み Rust を試してみたい！
その場合、現時点では書籍「基礎から学ぶ 組み込みRust」において十分な解説があります。


しかしながらこれは Wio Terminal をターゲットとし、手元で書き込み/実行を確認しながら進める前提となっています。

今回はリモート勉強会を想定し、 Wio Terminal を持っていない参加者が複数いても、主催者が持つ Wio Terminal を操作してハンズオンに参加する方法を考えます。

以下は Wio Terminal をターゲットとしていますが、RaspberryPi Pico や ESP32 などをターゲットとしても同じように実現できるでしょう。



# 前提条件

- 参加者は手ぶら
- 主催者側で複数の Wio Terminal がある
- 主催者側で Linux PC がある


# ハンズオン実施方法

- 主催者が手持ちの WIO TERMINAL は WebCam で映し出しておく
- 主催者は Linux PC をハンズオンサーバとして公開する
- 参加者は SSH でハンズオンサーバにアクセスする
- 主催者は WIO TERMINAL のスイッチを2回スライドしてブートローダーモードにする(*)
- 参加者は開発したアプリをWIO TERMINALに転送、実行
- アプリを実行した結果、LED が点滅、WebCam で点滅動作を確認

主催者は、(*)の作業だけはアプリ書き込みが必要となるごとに、手作業で毎回行わないといけません。

# カメラ公開の例

WIO TERMINAL を 2台公開した例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/04e959e2-1cf0-d92a-989f-a939d3591bf1.png)

nanbuwks のカメラにつながっている左側が WIO TERMINAL #1 , 右側がWIO TERMINAL #2 です。
カメラで微妙に見える青いランプがLチカで作業するLEDです。
nanbuwks のカメラの背景ブラウンターミナルが screen セッション1 、背景赤ターミナルが screen セッション2 です。 この screen セッションに参加者が接続して操作します。



# Linux PC の設定

- Rust 開発環境をインストールします(後述)
- リモートでログインする専用のユーザを作り、権限を適切に設定します。特に、マイコンへ書き込みができる権限が必要です。
- 参加者ごとにユーザを別個に作るとインストール実習が個別に行えます。1つのユーザを共用にすると、インストールは1回のみで省略できます。
- Screen セッションを複数作っておきます。
- ポートを適宜開放し、外部から SSH が入れるようにしておきます。
- Wio Terminal を必要数 Linux PC に接続し、ブートローダーモードにしておきます。

# 参加者が行うこと

- ハンズオンサーバに ssh でログインして、screen -x 1 または screen -x 2 でスクリーンセッションにつなぎます。
- Rust で作成したバイナリを、Wio Terminal に書き込みます。
 - 今回作成するバイナリは LED を点滅させるプログラムです。
- 書き込みは、Wio Terminal が外部USBメモリとして見えるのでそこにファイルを転送
- 書き込みが終わると自動でプログラムが実行されます。
- 青いLEDが点滅することが確認できたら成功です。

# バイナリ作成方法

バイナリは以下の2つの方法でつくることができます。
 - ハンズオンサーバで作成
 - 自分のローカルPCで作成したものをハンズオンサーバに転送

ハンズオンサーバで作成するやりかたは、「組み込みRustハンズオンテキスト」https://qiita.com/nanbuwks/items/5c2203f539575a58f29e を参照してください。
自分のローカルPCで作成する場合は、scp でハンズオンサーバにコピーします。
自分のローカルPCで作成する場合は、上記「組み込みRustハンズオンテキスト」を参考にしてください。ただしテキストはLinux用です。他のOSもほぼ同様に作成できますが、適宜相違点を読み替えてください。


# バイナリ書き込み方法


Wio Terminal に書き込むバイナリの形式は uf2 形式です。
Rust でビルドしたバイナリは、以下のようにして uf2 形式に変換してください。
自分のローカルPCでバイナリを作成する場合は、uf2 形式に変換してから scp でハンズオンサーバにコピーします。


```
$ cargo objcopy --example blinky --release --  -O binary blinky.bin
    Finished release [optimized] target(s) in 0.15s
```

```
$ uf2conv blinky.bin --base 0x4000 --output blinky.uf2
```
できたuf2ファイルを書き込みます

Wio Terminal をブートローダーモードにしていると、Wio Terminal が外部USBメモリとして見えるのでそこにファイルを転送します。
例として、「カメラ公開の例」で示した2台の Wio Terminal だと左側が /dev/sdb, 右側が /dev/sdc ですが起動順番で変わります。
どこにマウントされているかは mount コマンドで確認してください。

/media/nanbuwks/Arduino にマウントされていた場合は以下のようにして書き込みます。

```

$ cp blinky.uf2 /media/nanbuwks/Arduino/

```


ブートローダーモードになっていない場合は主催者にリクエストしてブートローダーモードに変更してもらってください。

書き込みが終わると自動でプログラムが実行されます。
青いLEDが点滅することがカメラ経由で確認できたら成功です。
Proxmoxで開発機を置き換え

※自分用メモの要素を含む記事です。
# 構成

|  部位  |  パーツ  |
| ---- | ---- |
|  CPU  |  AMD Ryzen Threadripper 3970x  |
|  Mother Board  |  MSI TRX40 PRO WIFI |
|  Memory  | 3600MHz 16GB×4枚 |
|  SSD  | SAMSUNG 980 PRO 他 |
|  GPU  |  RTX 2080 SUPER |
|  PSU  |  Corsair HX1000 |
|  Case  |  NZXT 510 |
|  CPU Cooler  |  NZXT KRAKEN X63  |
|  GPU Cooler  |  NZXT G12 + NZXT X51 |

# Proxmox
Proxmox 7を導入しました。
KVMベースの仮想化プラットフォームで、実体はDebianです。
CPUコア数をオーバーコミット（物理的なコアはHyperThreading含めて64コアでも、仮想マシンの合計コア数はそれを超えた値を設定できる）して複数の開発機をまとめて1つにしました。
流石に全VMが全力な時に物理コア数を超えるパフォーマンスは出ませんが、現実的にはそうそうピークは被りませんので、銀行の信用創造のように実マシンが増えたような扱いができます。
無料ドメインサービスでドメインを取得してみよう

#はじめに
[第一回](https://qiita.com/noji505/items/24f1a98d778d462f540b)の記事でXAMPPをインストールし、Apacheの環境を構築しましたが、
せっかくなのでドメインを取得しアクセスし易い環境を構築したいと思います。

#ドメインとは
そもそもドメインって？という方のために簡単に説明します。
サイトにアクセスする際にURLでアクセスすると思いますが、例えばグーグルだと[https://www.google.co.jp](https://www.google.co.jp/)といったURLでアクセスすると思います。
この文字列の「<b>google.co.jp</b>」の部分がドメインになります。

#取得してみよう
では早速取得してみましょう。
無料でドメインを取得出来るサービスは色々あるのですが、私は以下を使用しています。
[Dynamic Do!.jp](https://ddo.jp/)

上記のサイトにアクセスし、少し下の方にある「<b>ddo.jp サブドメイン DDNS無料登録</b>」の希望ドメイン欄に自分が取得したいドメイン名を入力します。
![01_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/3599c481-0f25-e57d-3f7a-9eb180012f5c.png)

登録ページにてメールアドレスを入力し、登録完了すると以下のようなメールが届きます。
![02_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/df572b68-3e65-da0d-230a-351d1da5510a.png)

「<b>メールアドレスの確認手続き</b>」の所のURLをクリックし、登録を完了させます。
#ドメインとIPアドレスを紐付ける
次に、先程取得したドメインとIPアドレスを紐付けます。
「[無料ドメイン更新ページ](https://ddo.jp/?free=on)」 にアクセスし、先程登録したドメイン名とパスワードを入力し「<b>IPアドレス更新</b>」ボタンを押します。
※IPアドレスの欄には自動でIPアドレスが入力されていると思います
![03_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/125b2508-733e-b714-b3bb-6c6d9037a121.png)

以下のような画面が表示されれば紐付け成功になります。
![04_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/0807e0f4-1591-2028-475d-56585db2c542.png)

#最後に
ドメインを使ってサーバにアクセス出来るようになれば、サーバを外部に公開しサービスを提供するといったことも行いやすくなると思いますので是非やってみて下さい。
bashのexecute_command_internal()に関する疑問（メモ）

bashのexecute_command_internal()の658行目あたりに子プロセスが実行する部分がある。

こんな感じ


```c
pid_t paren_pid;
int s;

/*中略*/

paren_pid = make_child(/*ｓは使われない*/);


if (paren_pid == 0) {
   
    s  = (/*フラグとかを評価*/)
    s += (/*フラグとかを評価*/)
    
    last_command_exit_value = 
        execute_in_subshell(/*sは使われない*/)
    
    /*ここで初めてｓの値が使われる*/
    if (s)
        subshell_exit(last_command_exit_value);
    else
        sh_exit(last_command_exit_value);
} 


/*これ以降ｓは使われない*/

```

コマンドがサブシェルで実行されるときは、このコードが実行されるっぽい。bashはmake_child()を呼び出して内部でfork()を呼び出す。そして、子プロセスはsにフラグの判定結果を代入して、その結果によってsubshell_exit()かsh_exit()を呼び出す
これら２つの関数は最終的にexit()を呼び出すだけで、メモリを開放する以外にあまり違いはないように見える。

ここまでの処理で疑問がある。

ローカル変数sは親プロセスでは使われておらず、サブシェル内で終了方法を判定する以外に使われていない。

プロセスはフォークするとそのプロセスのコピーがつくられつので、スタックやヒープの情報は保存されている。
なので、sを親プロセスで定義しているのはなんのためなのかがわからない。
つまり、上記のコードを以下のようにしたほうが良いのではないかと思った。


```c
pid_t paren_pid;

/*中略*/

paren_pid = make_child(/*ｓは使われない*/);

if (paren_pid == 0) {
    int s;
    s  = (/*フラグとかを評価*/)
    s += (/*フラグとかを評価*/)
    
    last_command_exit_value = 
        execute_in_subshell(/*sは使われない*/)
    
    /*ここで初めてｓの値が使われる*/
    if (s)
        subshell_exit(last_command_exit_value);
    else
        sh_exit(last_command_exit_value);
}

/*これ以降ｓは使われない*/

```

もしかしたら、完全に抜けている知識があるせいでこのような疑問を持ってしまうのかもしれないが、一応メモのために載せた。
Teensyduinoでスレッドを使う

#Teensyduinoでスレッドを使う
TeensyThreads.hを使います
##インストール
https://github.com/ftrias/TeensyThreads
##注意
マルチスレッドにする場合、
普通のdelay()を使うと指定した時間の待機になりません。
threads.delay()を使いましょう。

```cpp
#include <TeensyThreads.h>

volatile long old[4];

void one() {
  while (1) {
    Serial.print("ONE ");
    Serial.print(threads.id());
    Serial.print(" ");
    Serial.println(millis());
    threads.delay(1000);
  }
}

void two() {
  while (1) {
    Serial.print("TWO ");
    Serial.print(threads.id());
    Serial.print(" ");
    Serial.println(millis());
    threads.delay(1000);
  }
}

void three() {
  while (1) {
    Serial.print("THREE ");
    Serial.print(threads.id());
    Serial.print(" ");
    Serial.println(millis());
    threads.delay(1000);
  }
}

void setup() {
  Serial.begin(9600);
  threads.addThread(one);
  threads.addThread(two);
  threads.addThread(three);
}

void loop() {
  Serial.print("MAIN ");
  Serial.print(threads.id());
  Serial.print(" ");
  Serial.println(millis());
  threads.delay(1000);
//  delay(1000);   //上の行をコメントアウトしてこの行のコメントアウトを外すと1秒間隔がずれていく
}
```
SQLのCASE式を用いて複数列の最大値を求める

## 問題

`Greatests`という仮のテーブルがあるとします。

複数列の中から、最大を選び

| key| x | y | z |
|----|---|---|---|
| A  | 1 | 2 | 3 | 
| B  | 5 | 5 | 2 | 
| C  | 4 | 7 | 1 | 
| D  | 3 | 3 | 8 | 

以下のような出力結果になるような SQLを書いてください。
まずは、xとy 列の2列の比較でやりましょう。

| key| greatest |
|----|----------|
| A  |    2     |
| B  |    5     |
| C  |    7     |
| D  |    3     |

### 解き方の方針

CASE式の条件を`x>y`とかにすればすぐできます。

### SQL

```sql
SELECT
	key,
	CASE WHEN x > y THEN x
	END y AS greatest
FROM Greatests
```

## 問題

では、比較対象をx,y,zの3列にしたらどうでしょうか？

### 解き方の方針

CASE式の中でCASE式を入れて比較すればOKです

### SQL

```sql
SELECT
	key,
	CASE WHEN
　　　　　　　　　　　　　　　　　　　　　　　　　　CASE WHEN x > y THEN x ELSE y END < z
　　　　　　　　　　　　　　　　THEN z
　　　　　　　　　　　　　　　　ELSE
             CASE WHEN x > y THEN x ELSE y END
	END AS greatest
FROM Greatests
```

「`CASE WHEN x > y THEN x ELSE y END`」というCASE式をCASE式の中に書くことで実現できます。

こんなことができるのも、CASE式の実行値が値だからこそです。

同じ容量で、列は増やせますが、可読性は落ちます。

## 参照

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

23p

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

https://qiita.com/ryosuketter/items/713474dbd009870e4103
[gulpエラー] gulp-sass 5 does not have a default Sass compiler

# 状況
1年くらい放置してたプロジェクトを進めようとnpm runしたら、前は問題なく動いていたのに急にこんな風に怒られちゃいました…。

```
Error in plugin "gulp-sass"

gulp-sass 5 does not have a default Sass compiler; please set one yourself.
Both the `sass` and `node-sass` packages are permitted.
For example, in your gulpfile:

  var sass = require('gulp-sass')(require('sass'));
```


# 原因
どうやら2021年7月に[gulp-sass](https://www.npmjs.com/package/gulp-sass)がversion 4から5へとメジャーアップデートされた際に、プラグインの読み込み方も変更されたようです。

# 解決法
エラーでも紹介されている通り、sassの読み込み方を変えます。

まずは ` npm install --save-dev sass` してsassをインストールします。

その後、gulpfile.jsでのプラグインの読み込み方を次のように書き換えます。

```javascript:gulpfile.js
// 旧バージョン
const sass = require('gulp-sass');

// 新バージョン
const sass = require('gulp-sass')(require('sass'));
```

# 参考文献
[gulp-sass](https://www.npmjs.com/package/gulp-sass)
gitコマンド

#目次
[1.はじめに](#1-はじめに)
[2.大まかな流れ](#2-大まかな流れ)
[3.gitコマンドの一連](#3-gitコマンドの一連)
[4.感想](#4-感想)
[5.おわりに](#5-おわりに)

#1. はじめに
railsチュートリアルでGitコマンドをしばらく触っててある程度
push,branch,margeがわかってきたので一連の流れをまとめます。

前回

https://qiita.com/ak-matsu/items/e8a6fa4f654b9d82994b

#2. 大まかな流れ
 - 初期化後、Githubへアクセス
 - リモートリポジトリへアップ
 - ブランチ作成
 - マージ
 - ブランチ削除

#3. gitコマンドの一連

```shell

Gitでパスワードを一定時間保持するように設定する
$ git config --global credential.helper "cache --timeout=86400"

Gitリポジトリの初期化
$ git init
$ git add -A

まだステージングエリアで控えているので
リポジトリへ反映するためコミットする
$ git commit -m "Initialize repository"

変更点があればコミットする(-aはすべての変更、-mはコミットメッセージを追加）
全てのファイルで変更があったものをコミットメッセージとして実行する。
$ git commit -am "Improve the README"

GitHub上にリポジトリを作成、リモートにもpushする。
リモートリポジトリが作成されweb上に展開される（public or private)
$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/sample_app.git
$ git push -u origin master

変更点があればコミットする(-aはすべての変更、-mはコミットメッセージを追加）
全てのファイルで変更があったものをコミットメッセージとして実行する。
$ git commit -am "Add hello"
$ git push

herokuを作成、gitのMasterブランチを元にherokuへデプロイする。
$ heroku create
$ git push heroku master

ブランチを作成 static-pagesはブランチ名
$ git checkout -b static-pages

ブランチへ変更点があったものをGitリポジトリへ追加
$ git add -A
$ git commit -m "変更点を記載"
$ git push -u origin ブランチ名

一度同じブランチでのpushが終われば
都度ブランチ名を記載せず、以下のコマンドで良い。
$ git push

mergeをする場合
$ git checkout master
$ git merge static-pages

ブランチを削除
$ git branch -d modify-README

リモートリポジトリをpushにて反映させて
リモートリポジトリの状態をherokuにもpushさせる
$ git push
$ git push heroku master

```
#4. 感想
railsチュートリアル第1章でgitコマンドを扱い第3章までで使い始めて
ある程度まとめれそうと思い作成。
だいぶGitHubDesktopとの流れが掴んできたのでこの調子で取り組んでいきたい。

#5. おわりに
第３章が終わればまとめに入る。
【 Tello & OpenCV 】key = cv2.waitKey()を削除すると、フレーム画像のウィンドウ表示ができなくなるので、みんな気をつけよう


__*key = cv2.waitKey(1) & 0xff*__のコードは消したり、コメントアウトすると、Telloから画像を受信して、Macbookのウィンドウに出なくなる。

そこで、今回は、__*key = cv2.waitKey(1) & 0xff*__で取得した__*key*変数__ではなく、Python組込の__*input("")*メソッド__を使って、Terminalから標準入力されたキーボード入力を受け取る場合も、この行は、残しておく必要がある。

__（ 参考 ）__

- [python: opencvのimshowで画像が表示されない](https://moimoiblog.com/programing/python-opencv-error2/)

###画像出力に成功するスクリプト

```Python3:OKスクリプト１
# key = cv2.waitKey(1) & 0xffを削除すると、画像が入らなくなる。
# かなり遅延して画像が入る。
import sys
import traceback
import tellopy
import av
import cv2.cv2 as cv2  # for avoidance of pylint error
import numpy
import time

def main():
    drone = tellopy.Tello()
    drone.connect()
    drone.wait_for_connection(60.0)

    container = av.open(drone.get_video_stream())
    #frame_skip=300
    
    for frame in container.decode(video=0):
        image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR)
        cv2.imshow("org",image)
        key = cv2.waitKey(1) & 0xff
       #key = cv2.waitKey(1)

if __name__ == '__main__':
    main()
    
```


###画像出力に成功するスクリプト

```Python3:OKスクリプト１
# key = cv2.waitKey(1) & 0xffを削除すると、画像が入らなくなる。
# かなり遅延して画像が入る。
import sys
import traceback
import tellopy
import av
import cv2.cv2 as cv2  # for avoidance of pylint error
import numpy
import time

def main():
    drone = tellopy.Tello()
    drone.connect()
    drone.wait_for_connection(60.0)

    container = av.open(drone.get_video_stream())
    #frame_skip=300
    
    for frame in container.decode(video=0):
        image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR)
        cv2.imshow("org",image)
       #key = cv2.waitKey(1) & 0xff
        key = cv2.waitKey(1)

if __name__ == '__main__':
    main()
    
```

###画像出力に失敗するスクリプト

```Python3:OKスクリプト１
# key = cv2.waitKey(1) & 0xffを削除すると、画像が入らなくなる。
# かなり遅延して画像が入る。
import sys
import traceback
import tellopy
import av
import cv2.cv2 as cv2  # for avoidance of pylint error
import numpy
import time

def main():
    drone = tellopy.Tello()
    drone.connect()
    drone.wait_for_connection(60.0)

    container = av.open(drone.get_video_stream())
    #frame_skip=300
    
    for frame in container.decode(video=0):
        image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR)
        cv2.imshow("org",image)
       #key = cv2.waitKey(1) & 0xff
       #key = cv2.waitKey(1)

if __name__ == '__main__':
    main()
    
```
#G検定 2021#2 分野ごとの出題数

# JDLA Deep Learning for GENERAL 2021#2

- [一般社団法人 日本ディープラーニング協会](https://www.jdla.org/) 主催
- 2021年7月17日（土）開催
- 以下の 8 分野から出題
    1. 人工知能とは
    1. 人工知能をめぐる動向
    1. 人工知能分野の問題
    1. 機械学習の具体的手法
    1. ディープラーニングの概要
    1. ディープラーニングの手法
    1. ディープラーニングの社会実装に向けて
    1. 数理・統計
- 設問数：191問

先日、上記の試験「G検定」を受験し、無事合格しました。
今回より各分野での得点率が各受験者にメールで通知されるようになりました。
しかし、分野ごとの出題数・正答数が分からなくて、もやもやするので調べました。

# 出題割合

あくまで予想の域を出ませんが、結果から示します。
※初め 3 分野はまとめて 1 分野扱いで正答率が提示されてたのでそれに倣います。

1. 人工知能とは, 人工知能をめぐる動向, 人工知能分野の問題：20 問
1. 機械学習の具体的手法：20 問
1. ディープラーニングの概要：32 問
1. ディープラーニングの手法：65 問
1. ディープラーニングの社会実装に向けて：48 問
1. 数理・統計：6 問

以上を合計すると 191 問となります。

## 調査手法

やり方は泥臭いけど簡単で、

1. みんなのツイートの画像から得点率を収集
1. その得点率があり得る分数を探す

だけです。
例えば、分野 1 は 100, 95, 90, 85, 80, 75, 70, 65 % の人が居たら 20 問だろうな…という具合です。

## 素点逆算

なので、自分の分野別得点率 $a, b, c, d, e, f$ から素点合計を知りたかったら、

$\lceil 0.2a \rceil + \lceil 0.2b \rceil + \lceil 0.32c \rceil + \lceil 0.65e \rceil + \lceil 0.48e \rceil + \lceil 0.06f \rceil $

を計算すれば出てくるはずです。

# おまけ

調査に使ったのは、検索して出た 52 人の合格ツイートで、それに自分の結果を加えました。
53 人の合格者の各分野と合計の平均点・最大値・最小値を書いておきます。2021#3 以降を受験する人の参考になれば幸いです。

|分野|平均 [問]|最大 [問]|最小 [問]|予想出題数 [問]|
|:----|----:|----:|----:|----:|
|人工知能とは, 人工知能をめぐる動向, 人工知能分野の問題|17.98|20|13|20|
|機械学習の具体的手法|16.85|20|12|20|
|ディープラーニングの概要|26.58|32|19|32|
|ディープラーニングの手法|51.32|62|33|65|
|ディープラーニングの社会実装に向けて|36.74|46|27|48|
|数理・統計|4.36|6|1|6|
|合計|153.83|183|119|191|


まぁやっぱり合格基準は素点で 6 割くらいなのかなぁ、という感想です（全問題が同じ重みで合否出されているかは分かりませんが）。

# おまけ2

使った参考書・サイトをメモ。

- ちゃんと全部目を通した
    - [AI For Everyone（すべての人のためのAIリテラシー講座）](https://www.jdla.org/certificate/everyone/)
    - [深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト 第2版](https://amzn.to/3C37Tw1) [^1]
    - [徹底攻略ディープラーニングG検定ジェネラリスト問題集 第2版 (徹底攻略シリーズ)](https://amzn.to/2WGFZFD)
- 時間が足りなくて一部だけ
    - [AI白書2020～広がるAI化格差（ギャップ）と5年先を見据えた企業戦略～](https://www.ipa.go.jp/ikc/our_activities/rs_01.html) [^2]
    - [G検定(AIの検定)模擬テスト – Study-AI](https://study-ai.com/generalist/)
- 日頃の勉強・趣味
    - [Neural Network Console - YouTube](https://www.youtube.com/c/NeuralNetworkConsole)
    - [AIcia Solid Project - YouTube](https://www.youtube.com/channel/UC2lJYodMaAfFeFQrGUwhlaQ)
- 当日受験中お世話になりました
    - [G検定まとめ - Qiita](https://qiita.com/tatsuya11bbs/items/681bc48df2fab68d4c82)
    - [G検定チートシート - Qiita](https://qiita.com/IsHYuhi/items/a5bf16a17c4ca5dd51c2)
    - [【完全版】JDLA G検定チートシート - Qiita](https://qiita.com/RZQiita/items/4a4fec1c91cf95fd64a2)

次はE検定受けようと思います。



[^1]: 第2版出る前に第1版買ってしまって、そのまま臨んだけど、なんとか行けた。
[^2]: ケチって 2019 版の無料 PDF にしてしまった。
[Nodejs] thisが浮気者なのでbindで束縛する

# はじめに
めちゃ久しぶりに記事書きます。Pirikaraです。
最近ほぼJavascriptばっかり書いてますが、業務中に解決したやーつを共有したいと思います。

# this
thisの挙動の違いについては[こちら](https://qiita.com/knknkn1162/items/0fa7dcb6a735125d21db)。

呼んだ所々で値が変わってしまう`this`。
今まで特に意識せずに使ってましたが、この`this`の参照先が変わることで少々困ったことになりました。

# Jestでthisを扱うコードをテストする時に詰んだ
こちらのmixinは、Vue.jsのコンポーネントにmethodsとして読み込まれる関数をまとめたものです。
バックエンド(Ruby on Rails)のコードは自動テストを走らせて品質を担保していますが、フロントのjsファイルに関してはE2Eテストを行なっていました。
E2Eだけでは見落としが発生してしまうので、フロント側にも段階的に自動テストを導入していくことになりました。

そこで、まずはコンポーネントのテストではなくJSファイルのテストを.....と思っていたのですが......

```javascript:mixin.js

export function A(hoge) {
  return this.B(this.$store.hogehoge, hoge)
}

export function B(a, b) {
  return a*b
}
```

```javascript:mixin.test.js

import * as mixin from 'path/to/mixin.js';
it('A関数に10を渡すと、50を返す', () => {
  expect(mixin.A(10)).toEqual(50);
})
```

A関数の中では`this`を取り扱っています。
mixinのコードはコンポーネント内のmethodsとして読み込まれるので、この`this`はコンポーネント自身を指しています。
しかしながら、このテストを実行すると次のエラーが発生します。

```terminal
TypeError:Cannot read property 'hogehoge' of undefined.
```

`this.$store`でVuexのstoreを参照しようとしていますが、テスト環境で実行したこの`this`はmixin自身を指しており、`$store`という値はないためundefinedになります。
当然hogehogeという値も持っていないのでこのエラーになります。

このままでは`this`が影響してテストができません。

# bindで束縛
Javascriptの関数オブジェクトには、bindという便利なメソッドがありました。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

このメソッドを使うと、関数内のthisを指定の値に固定した**新しい関数**を返します。
早速使ってみましょう。

```javascript:mixin.test.js
import * as mixin from 'path/to/mixin.js';
it('A関数に10を渡すと、50を返す', () => {
  const mockTest = mixin.A.bind(5, 10) // 第一引数が関数内のthisの値になる
  expect(mockTest()).toEqual(50);
})
```

これでテストを正しく実行することができました。

ちなみに、下のように直接bindした関数をテストすると、
元の関数がそのまま（thisを固定できないまま）実行されてしまうので注意です。

```javascript:mixin.test.js
import * as mixin from 'path/to/mixin.js';
it('A関数に10を渡すと、50を返す', () => {
  expect(mixin.A.bind(5, 10)).toEqual(50);
})
```

# おわり
おわります。
またネタがあれば書きます。
CrystalでAtCoder(Log #3)

#Easy_3

https://atcoder.jp/contests/code-festival-2016-qualb/tasks/codefestival_2016_qualB_b

成績上位のほうから一人一人調べていく。

## 標準入力
```crystal:input.cr
n, a, b = read_line.split.map(&.to_i)
s = read_line
```

## `String#each_char`, `Iterator#each`

`each_char`は`String`の先頭から１文字ずつ取り出していくイテレータを返すメソッド。
`each`はイテレータの先頭から1つずつ要素を取り出し、逐次処理を行う。

アルゴリズム：
国内と海外で通過した人数をそれぞれ`a_cnt`、`b_cnt`とする。初期値は0。
先頭から１文字ずつ見ていく。
`a`の場合 => 今までの通過人数が`a+b`未満なら通過。`a_cnt`を１増やす。そうでなければ非通過。
`b`の場合 => 今までの通過人数が`a+b`未満かつ海外の通過人数が`b_cnt`未満なら通過。`b_cnt`を１増やす。そうでなければ非通過。

```crystal:each_template
s.each_char.each { |c|
  もしcが'a'で、今までの通過人数がa+b未満の場合
      "Yes"と表示してa_cntを1増やす
  あるいはcが'b'で、今までの通過人数がa+b未満で、海外の通過人数がb未満の場合
      "Yes"と表示してb_cntを1増やす
  その他の場合
    "No"と表示
}
```

`s[i]`でも`s`の`i`文字目にアクセスできるが、ASCII文字限定なら$O(1)$なので問題ない。

## `if`文で実装

実は`case`文もあるが、まだ`if`文もやっていないので`if`文で。
基本構文は下記の通り。

```crystal:if_template
if some_condition
  do_something
elsif some_other_condition
  do_something_else
else
  do_that
end
```

数学で$x > y , x = y, x < y$ に相当するのは`x > y` , `x == y` , `x < y`。
$ p∧q, p∨q$に相当するのは`p && q`と`p || q`。

## AC例

```crystal:code-festival-2016-qualb_b.cr
n, a, b = read_line.split.map(&.to_i)
s = read_line
a_cnt = 0; b_cnt = 0
s.each_char.each{ |c|
  if c == 'a' && a_cnt+b_cnt < a+b
    puts "Yes"
    a_cnt += 1
  elsif c == 'b' && a_cnt+b_cnt < a+b && b_cnt < b
    puts "Yes"
    b_cnt += 1
  else
    puts "No"
  end 
}
```