OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptベースの動画編集サービスを作ってます

# はじめに
JavaScriptベースの動画編集サービス・[Double TONE - https://doubletone.jp](https://doubletone.jp)を作っています。~~2021年10月時点では限定公開ですが、近々ベータ版として一般公開する予定です。~~ (追記)2021年12月1日にオープンベータ版として、一般公開しました！ 

*(追記)[WebAssembly + Web Audio API + Canvas で動画編集（Double TONEの紹介）](https://qiita.com/taukuma/items/1f1a4c6b21b0cc409187)にもう少し詳しい記事を記載しています。*

![doubletone_screenshot_20211019174545.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187642/737c4cd0-6253-07ac-6623-ff0728cee480.png "Double TONE")
イメージはこんな感じです。Qiitaでは、このサービスの開発ブログ的なことを書いていこうと思います。

# 自己紹介
趣味でコーディングをしてます。
本職ではプログラミングすることはあまりなく、Excel職人・PowerPointer職人になってます。
保護猫５匹と楽しく生活してます。

# なんで作ろうと思ったのか
2年ほど前職場の忘年会的なイベントで動画編集が必要になったけど、扱う素材がコンフィデンシャルなため（マネージャー陣からの今だから言える赤裸々な告白）、自宅マシンでの作業ができなく、かつ職場PCには未許可のソフトウェアをインストールしてはいけない制限がありました。 なので、インストール不要、素材のアップロードも不要な動画編集ツールがあれば解決、と思い立ったのがきっかけです。

# 実行環境など
とりあえずMac/PCで、ブラウザは`Google Chrome`のみとしています（スマホ・タブレットは未対応）。メモリ管理あたりの最適化がまだまだのところがありますので結構メモリ食います。

* サーバーサイドは`Node.js`
* フレームワークは、`Express`
* フロント側のUIは`Bootstrap`
* UI制御は、`jQuery`がメイン
* 動画の書き出しは`ffmpeg.wasm`

# 簡単なサービスの紹介
* サービス名：Double TONE（ダブルトーン）
* ブラウザ上で動作する動画編集サービスです
* 基本的な編集作業はブラウザ上で完結します
* 動画や写真などの素材もアップロード不要です
* レンダリングもブラウザ上でやります
* SNSに直接アップロードできます

#### 動作イメージ
ドラッグ＆ドロップで素材をタイムラインに追加
![open video and put to timeline.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187642/0c69b9c9-b7e8-b19d-1ea3-461ce3b87f39.gif)

エフェクトの追加（回転）
![apply effect (rotate).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187642/cd94e717-b4f0-f41b-2390-e40e7175c576.gif)

エフェクトの追加（マスク）
![apply effect (mask).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187642/c5748eb4-8ca5-7614-4f21-8ff14f134b1d.gif)

ソリッドレイヤーの追加とブレンドモード
![add new solid and brend mode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187642/4ca4803b-c8fa-4e6e-e9b1-64472099fddc.gif)

文字
![apply effect (text).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187642/45275d83-6b2f-7857-eac8-cfe12784acb1.gif)

# 今後Qiitaに投稿する内容について
Double TONEの開発メモを自分でも整理するために投稿していくつもりです。このサービスは今のところ一人で開発しているのでバックエンドやインフラ含め試行錯誤した失敗談が多くなるかもしれないです。

# Reference
Node.js: https://nodejs.org/ja/
Express: https://expressjs.com/
Bootstrap: https://getbootstrap.jp/
jQuery: https://jquery.com/
ffmpeg.wasm: https://github.com/ffmpegwasm/ffmpeg.wasm
Jetpack Compose IntrinsicSize

AndroidのJetpack ComposeでIntrinsicSizeを用いてComposeを作成した時の知見です。
この記事は以下のバージョンに対応しています。

| | バージョン |
|:-----------|:------------:|
|Jetpack Compose|1.0.4|
|AndroidStudio|ArcticFox 2020.3.1 Patch 3|

#IntrinsicSize
- 子要素Aは親の高さと同じ
- 子要素Bの高さによって親の高さが決まる

この条件を満たすComposeを作成する場合に、IntrinsicSizeを用いると実装できます。
例えば
![スクリーンショット 2021-10-29 9.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356260/78321471-53e8-d6e9-98cd-0cc1f9569bcf.png)
このようなComposeを作成する場合、左の縦線(子要素A)は親の高さと同じで、テキスト(子要素B)の高さによって親の高さが決まります。

この場合、親のmodifierにModifier.height(IntrinsicSize.Min)を指定すると実現できます。

```Kotlin:IntrinsicSizeSample.kt
@Preview(showBackground = true)
@Composable
fun IntrinsicSizeSample() {
    Row(
        Modifier
            .height(IntrinsicSize.Min)
            .padding(4.dp)
    ) {
        Spacer(
            modifier = Modifier
                .width(12.dp)
                .padding(horizontal = 4.dp)
                .fillMaxHeight()
                .background(color = Color.Gray)
        )
        Text(
            text = "テキスト",
            fontSize = 20.sp
        )
    }
}
```
TextのfontSizeを40.spにしたとしても
![スクリーンショット 2021-10-29 9.55.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356260/097c3c90-b031-b217-c56d-060242210526.png)
となります。
今回はheightを調整するためにIntrinsicSizeを利用しましたが、widthを調整する際にも利用できそうです。
WindowsネイティブコードからDartの処理を呼ぶ

# Dart側の実装

StatefulWidgetを継承したクラスにて、MethodCannelを登録します。
戻り値でオブジェクトを返すことができます。

```main.dart
  @override
  initState() {
    super.initState();
    const MethodChannel('domain/appname').setMethodCallHandler((call) {
      switch (call.method) {
        case 'testMethod':
          return Future.value("true");
        default:
          throw MissingPluginException();
      }
    });
  }
```

#Windowsネイティブ側の実装

flutter_window.cppのOnCreateメソッドの末尾に処理を追加します。

```windows/runner/flutter_window.cpp
#include "flutter/generated_plugin_registrant.h"
#include "flutter/method_channel.h"
#include "flutter/standard_method_codec.h"
#include "flutter/method_result.h"
#include "flutter/method_result_functions.h"

bool FlutterWindow::OnCreate() {
  ...
  const std::string test_channel("domain/appname");
  const flutter::StandardMethodCodec& codec = flutter::StandardMethodCodec::GetInstance();

  flutter::MethodChannel method_channel_(flutter_controller_->engine()->messenger(), test_channel, &codec);

  auto result_handler = std::make_unique<flutter::MethodResultFunctions<>>(
    [](const flutter::EncodableValue* success_value) {
      std::cout << "on_success" << std::endl;
      std::cout << std::get<std::string>(*success_value) << std::endl;
    },
    [](std::string error_code, std::string error_message, const flutter::EncodableValue* error_details) {
      std::cout << "on_error" << std::endl;
    },
    []() {
      std::cout << "on_not_implemented" << std::endl;
    }
    );

  method_channel_.InvokeMethod("testMethod", nullptr, std::move(result_handler));
}

```

# 参考文献

MethodResultFunctionsの書き方が調べてもでなかったため、エンジンのテストコードを参考にしました。

https://engine.chinmaygarde.com/method__channel__unittests_8cc_source.html

https://qiita.com/kurun_pan/items/db6c8fa94bbfb5c0c8d7#52-%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0-kotlin-%E3%81%8B%E3%82%89dart%E3%82%92%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%99
ROS melodic memo for me

# ROS melodic on ubuntu 18.04
## smach_viewer
### 背景
ROSのステートマシンに以前からsmachを使っていて、そのグラフ表示にsmach_viewerを利用していた。
しかし、新しいubuntu 18.04にROS melodicを入れてから実行しようとすると正しく動作しなかった。
どうやら最新の環境ではwxPythonのバージョンが新しくなっていて、それとの整合性がとれなくなっている雰囲気がある。
ここでは、その問題解決の過程をメモとして残しておくことにする。（現時点ではまだ完全解決はしていない）

### Install python-wxgtk2.8
現時点ではpython-wxgtk3.0が使われているようだ。
普通にやっても入らないので以下のようにする。

```.sh
$ sudo gedit /etc/apt/sources.list 
$ deb http://archive.ubuntu.com/ubuntu trusty main universe
$ sudo apt update
$ sudo apt install python-wxgtk2.8 
```
これやるとsmach_viewer起動時に新旧両方が1つのプロセスで使われているというエラーで起動できない。

### Install wxPython
最新のwxPythonを入れてみる。

```.sh
$ pip install wxPython
```
これでは必要な関数が無いとのエラーが表示されて起動できない。

## 派生メモ
### use wxversion with wxPython
```
use wx.version instead wxversion
```
基本情報技術者試験の勉強方法や参考になってサイト、感想など

#### 結果
まだちゃんとした合格通知は出ていませんが、多分合格しているだろうという感じです。
CBT方式なので受験後すぐにスコアレポートとして結果が送られてきます。 
それを見ると、午前が7.5割 午後が8.6割と合格範囲内に入っているのではないかと思います。
#### なぜ受けようと思ったか
・大学が情報系出ていないので、一通りのコンピュータサイエンス周りの学習をしたかった
#### どうだったか
・CBT試験 => 問題用紙の紙に直接メモを書けないので少し苦労した。
・しかし、午前試験、午後試験の間に１週間空いていたので午前が終わった後は午後だけに専念することができた。  
#### どうやって勉強したか
主に下記の基本情報技術者試験ドットコムというサイトを使って勉強しました。
[https://www.fe-siken.com/:title]
こちらは過去問が網羅されており、また、カテゴリごとで勉強できたのも大変助かりました。
個別の勉強でいうと、
・アセンブラをkindleの本で読んだり、
・アセンブラの解説がされている個人ブログを漁ったりなど色々しました。(末尾に参考なったサイトをいくつか載せています)
#### 難しかったところ
アセンブラです。
午後試験のソフトウェア言語選択で、「Python」か「アセンブラ」でずっと悩んでて、結局10日前ぐらいにアセンブラに決めました。
ギリギリになって焦ってアセンブラの勉強を始めましたが、解答に解説がないこともあり、検索で探すのも少し苦労しました。
しかし、アセンブラを勉強することで、計算処理でのメモリやCPUの動きの概要を知れたり、ハードウェアの知識も自然とついてきて、他の午後問題の勉強になったりもしました。
この機会じゃないと触れることもなかったと思うので概要を把握したぐらいですが勉強できてよかったと思っています。  

<br>
参考になったサイト 
[http://eienlearner.seesaa.net/:title]
[http://cdetes.html.xdomain.jp/index2.shtml:title]
[https://nekosiestr77.xsrv.jp/:title]
[チラ裏] ゲーミングPC検討メモ 2021年10月版

# これはなに？

よいGPUが必須のゲームがありまして、イマドキはどんな構成ができるのか、あらためて調べた雑多なメモです。

# なにはともあれGPU

まずは、AMDにするか、~~[謎のAI半導体メーカー](https://www.google.com/search?q=%E8%AC%8E%E3%81%AEai%E5%8D%8A%E5%B0%8E%E4%BD%93%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC)~~ NVIDIAにするか……。

|メーカー| シリーズ | 発表年 | アーキテクチャ | 価格帯 |
|:-:|:--|:-:|:-:|:-:|
|AMD| Radeon RX 6000  | 2020  | RDNA2  | 60,000円〜  |
|AMD| Radeon RX 5000  | 2019  | RDNA  | 20,000円〜  |
|AMD| Radeon RX 500  | 2017  | Poralis 2nd Gen  | 10,000円〜  |
|NVIDIA| GeForce RTX 30  | 2020  | Ampre  | 65,000円〜  |
|NVIDIA| GeForce GTX 16  | 2019  | Turing  | 15,000円〜 |
|NVIDIA| GeForce RTX 20  | 2018  | Turing  | 40,000円〜  |
|NVIDIA| GeForce GTX 10  | 2016  | Pascal  | 16,000円〜  |

お値段と控えめクロック的に、[AMD RX 5600 XT](https://www.amd.com/en/products/graphics/amd-radeon-rx-5600-xt)か、[AMD RX 5600](https://www.amd.com/en/products/graphics/amd-radeon-rx-5600)かな。

あるいは[NVIDIA GeForce GTX 1660 Super](https://www.nvidia.com/ja-jp/geforce/graphics-cards/gtx-1660-super/) か [NVIDIA GeForce GTX 1650 Super](https://www.nvidia.com/ja-jp/geforce/graphics-cards/gtx-1650-super/) かな。


# マザーボード

PCの快適さを決めるのはストレージの速度ということで、NVMe Gen.4 使えるのがよいですね。

| メーカー | チップセット | マザーボード価格帯 | 対応CPU |
|:-:|:-:|:-:|:--|
| AMD | TRX40 | 45,000円〜 | Ryzen Threadripper 3000シリーズ |
| AMD | X570S | 27,000円〜 | |
| AMD | X570 | 16,000円〜 | Ryzen 5000シリーズ、Ryzen 3000シリーズ、Ryzen 2000シリーズ |
| AMD | B550 | 10,000円〜 | Ryzen 5000シリーズ、Ryzen 3000シリーズ |
| Intel | Z590 | 20,000円〜 | 第11世代Coreファミリー、第10世代Coreファミリー |
| Intel | H570 | 13,000円〜 | 〃 |
| Intel | B560 | 11,000円〜 | 〃 |

AMD B550で固めていこうかな。

場所をとらないように、Mini-ITXで探してみます。

| メーカー | 製品 | 価格 |
|:--|:--|:-:|
| ASRock  | [B550 Phantom Gaming-ITX/ax](https://www.asrock.com/mb/AMD/B550%20Phantom%20Gaming-ITXax/index.asp)  | 22,000円〜  |
| ASRock  | [B550M-ITX/ac](https://www.asrock.com/mb/AMD/B550M-ITXac/index.asp)  | 16,000円〜  |
| ASUS  | [B550-I GAMING](https://rog.asus.com/motherboards/rog-strix/rog-strix-b550-i-gaming-model/)  | 25,000円〜  |
| BIOSTAR  |[B550T-SILVER](https://www.biostar.com.tw/app/en/mb/introduction.php?S_ID=1010)   | 13,000円〜  |
| MSI | [MPG B550I GAMING EDGE MAX WIFI](https://www.msi.com/Motherboard/MPG-B550I-GAMING-EDGE-MAX-WIFI)| 27,000円〜 |
| MSI | [MPG B550I GAMING EDGE WIFI](https://www.msi.com/Motherboard/MPG-B550I-GAMING-EDGE-WIFI) | (終売？) |


MSIが好きなんですけれど、ここはASRockか、BIOSTARにします。



# CPU

マザーが決まりましたので、自然とCPUも決まります。
あまり熱を出さないやつが良いですね。

[Ryzen](https://www.amd.com/ja/processors/ryzen#%E3%83%A2%E3%83%87%E3%83%AB%E4%BB%95%E6%A7%98) には、TDP65W〜105Wがあります。65Wのものを挙げてみます。

| 製品 | ベースクロック | L2キャッシュ|L3キャッシュ|価格（円） |
|:--|:-:|:-:|:-:|:-:|
| Ryzen 5 5600X  | 3.7 |3MB|32MB| 37,000〜  |
| Ryzen 5 5700G  | 3.8 |4MB|16MB|47,000〜 |
| Ryzen 5 5600G | 3.9 |3MB|16MB|35,000〜 |
| Ryzen 7 3700X | 3.6 |4MB|32MB|38,000〜 |
| Ryzen 5 3600 | 3.6 |3MB|32MB|27,000〜 |
| Ryzen 3 3300X | 3.8 |2MB|16MB|22,000〜 |
| Ryzen 3 3100 | 3.6 |2MB|16MB|14,000〜 |

価格で決めちゃいましょうかね。


# さて……

メモリとストレージも足して、トータル15〜20万円くらいでしょうか。
半導体不足のせいか、コインマイニングのせいか、GPUがやたら高くてまいります。

これだけ出してWindows PC組むなら、Apple M1のほうがよい気がしてきました。
件のゲームにはMac版もありますし……。
【Python】Selenium 4で、Selenium 3の書き方で書いたらWarningが出た


# はじめに
pythonでseleniumの使い方を学習していたら、Warningが出てきたので、調べてみると、自分がつかっているseleniumが4でした:sweat_smile:

selenium 4だと、書き方が多少異なるようですので、備忘録として残したいと思いました。

- PC: M1 Mac book Air
- OS: Big Sur ver11.6





# DeprecationWarning: executable_path has been deprecated, please pass in a Service object

```python
from selenium import webdriver
from selenium.webdriver.chrome.service import Service 

s = Service('/Users/ds/work/py_lesson/tools/chromedriver')
driver = webdriver.Chrome(service=s, options=options)

driver.get('https://news.yahoo.co.jp')

```

状況としては、`py_lesson`というディレクトリで、seleniumの学習をしています。
なので、`tools`の中に、seleniumの公式ページからダウンロードした`chromedriver`を置いています。

`Service()`の括弧の中に、`chromedriver`のパスを入れてから、`Chrome()`の引数として指定する感じですね。


# UserWarning: find_element_by_* commands are deprecated. Please use find_element() instead

```python
from selenium import webdriver
from selenium.webdriver.chrome.service import Service 
from selenium.webdriver.common.by import By


s = Service('/Users/ds/work/py_lesson/tools/chromedriver')
driver = webdriver.Chrome(service=s)

driver.get('https://news.yahoo.co.jp')

e = driver.find_element(By.TAG_NAME, "h2")
```

学習では、`find_element_by_tag_name`を使っていましたが、どうやら、`find_element`の括弧の中身は、`By.ID`や`By.TAG_NAME`といった`By.xxx`を使うようです。
React-BootstrapのForm.Selectが使えなかった

# はじめに
React/typescriptど素人が書いております。

# 開発環境
VS Code 1.61.2
React 17.0.2
TypeScript 4.4.3
React-Bootstrap 1.6.4

# 問題
https://react-bootstrap.github.io/components/forms/

公式ドキュメントにあった下記コードをコピペで使用しようとしたところ、
Form.selectが使えなかった。

```React
// import Form from 'react-bootstrap/Form'
<Form.Select aria-label="Default select example">
  <option>Open this select menu</option>
  <option value="1">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</Form.Select>
```

![スクリーンショット 2021-10-29 090603.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/281ae04d-cb04-c12f-d416-85923596dc98.png)


# 対応
```React
<Form.Control as="select">...</Form.Control>
```
こちらに書き換えたところ、エラーが消えました。

# 原因
とても初歩的なミスでしたが、React-Bootstrap 1.6.4を使っているのにドキュメントは
v2.0.0を参照しておりました。

ドキュメントv1.6.4を参照したところ、`Form.Control as="select"`になっていました。

```React
<Form>
  <Form.Group controlId="exampleForm.SelectCustom">
    <Form.Label>Custom select</Form.Label>
    <Form.Control as="select" custom>
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option>
      <option>5</option>
    </Form.Control>
  </Form.Group>
</Form>
```
`React-Bootstrap`インストール時にバージョン指定をしてなく、最新版がインストールされていると思い込んでいたのが問題でした。




# 参考
https://stackoverflow.com/questions/68166687/why-isnt-form-select-recognized-in-my-simple-react-bootstrap-app-following-the
templateタグはcontent.firstElementChild.cloneNode(true)がおすすめ

はじめてtemplateタグを使って、すこし嵌りました。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/template

MDNのtemplateタグの使い方のサンプルは、template.content.cloneNodeを行っています。
私は最初これはtr要素だと思っていました。trにidを設定するつもりで
`clone.setAttribute('id','id_of_tr_element')`を行ったのですが、設定できないなとおもっていたところ、これはDocumentFragmentでした。

以下はMDNからの抜粋

```js
    // 既存の HTML tbody と template の行を使って
    // table をインスタンス生成します。
    var tbody = document.querySelector("tbody");
    var template = document.querySelector('#productrow');

    // 新しい行を複製して表に挿入します。
    var clone = template.content.cloneNode(true);
    // cloneがtrだと思っていた
    var td = clone.querySelectorAll("td");
    td[0].textContent = "1235646565";
    td[1].textContent = "Stuff";

    tbody.appendChild(clone);
```

```html
<table id="producttable">
  <thead>
    <tr>
      <td>UPC_Code</td>
      <td>Product_Name</td>
    </tr>
  </thead>
  <tbody>
    <!-- 必要に応じて既存のデータをここに含められます。 -->
  </tbody>
</table>

<template id="productrow">
  <tr>
    <td class="record"></td>
    <td></td>
  </tr>
</template>
```

これはMDNのページでもDocumentFragment の落とし穴の回避 として記載がありました。

templateタグの子として複数要素ある場合でなければ、`template.content.firstElementChild.cloneNode(true)`が楽ちんです。

難しいことをしているわけではないだろうとおもってドキュメントを最後まで読むのを怠たりました。
Github Copilot使ってみた

今回Github Copilotのテクニカルプレビューに参加することができたので使ってみました。
便利だったので短くメモとして書きます。

#Github Copilotとは？
関数名とコードから関数のコードを丸ごと自動保管するAIプログラミング機能。
JS、Ruby、GO、Python、TypeScriptが得意みたいですが、ほか多数の言語で使うことができます。

#使用感
写真のような感じです。
1枚目は入力途中の関数から内容を予測して補完してくれています。
2枚目はコメントから予測して補完してくれてます。
![Github_Copilot_Test.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667272/84093612-8057-b225-d096-cf52f2de0064.jpeg)
![Github_Copilot_Test2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667272/557d2335-3f62-721f-cb84-16e28e899e32.jpeg)

#導入方法
今現在は製品版ではなくテストの段階ですので、テスターとして使うことになります。
[こちら](https://copilot.github.com/)から公式ページにアクセスし、順番待ちリストに登録したのち、Gmailでお知らせが届くので、そちらの指示に従ってVisual Studio Codeに拡張機能をインストールすると導入完了です。VSCode下部にマークが表示されていれば成功です。
![Github_Copilot_Test3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667272/25e6d288-bf26-9d1a-7fe1-0c7fe83613c6.jpeg)


#最後に
今回は GitHub Copilotを使ってみた感じを記録しました。
スランプで数か月Qiitaに投稿できていませんでしたが、これをきっかけにまた書いていければと思います。
ここまで読んでいただきありがとうございました。
Azure DevOps Boardで最近変更されたアイテムを見つけやすくする

# Azure DevOps Boardで最近変更されたアイテムを見つけやすくする

最近変更されたアイテムに、「色」をつけます。

複数のプロジェクトで、色々なスタイルルールを試してみましたが、このルールはどのプロジェクトでも好評でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35234/af3ab248-6c6e-6201-9f5d-4133cce6a98e.png)

設定は簡単で、ボード画面やスプリント画面で以下のスタイルにルールを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35234/1391a45d-4855-e039-689f-23200dcd453b.png)

- Rule Name はご自由に
- Card Colorもご自由に
- 条件（Rule criteria）で、変更日を使った条件を設定。

複数のRuleを設定する場合は、順序やスタイル重複に気を付けてください。
M1 Mac で nコマンドが invalid version になる

# はじめに

完全な備忘録です。

## 事象

M1 Mac で Node のバージョン切り替えコマンド `n` を使って、新しいバージョンをインストールしようとすると以下のようなエラーが出る。

```sh
n 16.13.0

     install : node-v16.13.0

  Error: invalid version 16.13.0
```

`n list` で確認すると、16.13.0は存在している。

## 解決策

[ここ](https://github.com/tj/n/issues/641)にIssueが上がっていた。

M1 Mac では、`--arch x64` が必要なようだ。

```sh
n --arch x64 16.13.0

     install : node-v16.13.0
       mkdir : /usr/local/n/versions/node/16.13.0
       fetch : https://nodejs.org/dist/v16.13.0/node-v16.13.0-darwin-x64.tar.gz
######################################################################### 100.0%
   installed : v16.13.0 

```

以上。
"Treat blank fields as blanks" (not zeros)　 「空白フィールドを空白として扱う」（ゼロではない）

数式フィールドで「空白フィールドを空白として扱う」（ゼロではない）が問題になっていることが案外多い。

単独の場合は問題は顕在化しないですが、この数式を別の数式で使う場合には問題がおきます。

[Calculating a Revenue Value in a formula field](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000BtDiY)
よく使うショートカットまとめ

ここでは知っていると作業効率の向上を期待できるが、あまり一般的ではないと思われるショートカットのみをまとめた。

なお、ここで紹介するショートカットは`windows10 version 20H2`にて動作確認済みである。

## 1. 編集
これらのショートカットは一般的なテキストエディタで利用可能

0. 一つ前の状態に戻す
    `ctrl` + `z`
1. カーソルの移動
    1. カーソル前後にある単語の先頭、末尾に移動
    `ctrl` + `→`, `←`
    2. 行の先頭、末尾に移動
    `HOME`, `END`
    3. テキストの先頭、末尾に移動
    `ctrl` +`HOME`, `END`

2. 文字のハイライト
> ハイライトした文字列では両端にクオーテーションマークを付与することができる
    1. 前方、後方にある１文字をハイライト
    `shift` + `→`, `←`
    2. 前方、後方にある単語の先頭、末尾に移動しながらハイライト
    `ctrl` + `shift`+ `→`, `←`
    または
    `ctrl` + `d`
    3. 行の先頭、行の末尾に移動しながらハイライト
    `shift` + `HOME`, `END`
    4. 一つ上、一つ下の行との入れ替え
    `ctrl` + `shift` + `↑`, `↓`


3. 文字の検索
`ctrl` + `f`

4. 画面の縮小、拡大
`ctrl` + `マウスホイール`
または、
`ctrl` + `+`
`ctrl` + `-`

## 2. ブラウザ
google chrome, firefox, Microsoft edgeでの動作を確認済み

1. タブ操作
    1. 新規タブの作成
    `ctrl` + `t`
    2. カレントタブの削除
    `ctrl` + `w`
    3. カレントタブの切り替え
    `ctrl` + `PgUp`, `Pgdown` 
    4. 表示しているタブのブックマークへの追加
    `ctrl` + `d`
    5. 直前に閉じたタブを開く
    `ctrl` + `shift` + `t`
    6. ひとつ前・後ろのページに移動
    `alt` + `←`, `→`

2. urlの編集
    `ctrl` + `l`
または、
    `alt` + `d`
> `alt` + `d`のショートカットは@toku_さんに教えてもらいました。この場をお借りして感謝申し上げます。

3. 文字の検索
    `ctrl` + `f`

4. ウェブページの検証画面の表示
    `f12`

5. ページのソースの表示
    `ctrl` + `u`

6. 画面の拡大縮小
    `ctrl` + `マウスホイール`
または、
`ctrl` + `+`
`ctrl` + `-`


## 3. スクリーンショット
1. 範囲を指定してスクリーンショットを撮影
`win` + `shift` + `s`
範囲指定で切り取った画面はクリップボードに保存されるので、そのままkeepメモやtwitterに`ctrl` + `v`で張り付けることができる
また、全画面の指定など、他の撮影方法も選ぶことができる

2. 全画面のスクリーンショットを撮影し、クリップボードに保存
`print screen`

3. 全画面のスクリーンショットを撮影し、フォルダに保存
`win` + `print screen`
スクリーンショットを撮影、保存。保存された画像はピクチャフォルダ内のスクリーンショットに保存される。画像の形式はpng

4. アクティブウィンドウを撮影し、クリップボードに保存
`alt` + `print screen`

5. 全画面を撮影し、フォルダに保存
`alt` + `win` + `print screen`

> 4,5のショートカットは@xMAKISHIxさんに教えてもらいました。この場をお借りして感謝申し上げます。
condaを使う際に利用するコマンド一覧

#概要
condaはAnacondaで使える環境作成等が行えるコマンドです。また、Anacondaを利用する場合、ツールとして「Anaconda Powershell Prompt」と「Anaconda Prompt」があります。

■「Anaconda Powershell Prompt」と「Anaconda Prompt」の違い
・Anaconda Powershell Prompt　⇒使えるコマンドが増えている？
・Anaconda Prompt　⇒従来のコマンド環境



<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/3ae40fde-0dce-8993-8de3-56ac202b104c.png">

ただし、Powershellでcondaコマンドを使うにはいろいろと設定が必要なようですので、conda環境を初心者が使いたい場合は、迷わず「Anaconda Prompt」を使ってください。
※以下コマンドを入力すると警告やWarningがでますが、Powershellでもcondaが使えるようになるようです。

```
conda install -n root -c pscondaenvs pscondaenvs
```

利用環境
OS：Windows10
Python：3.7.10

#各コマンド
**仮想環境構築**

```
conda create -n （仮想環境名） python=（Pythonのバージョン） （そのほか入れたいパッケージ名）
conda create -n testsite python=3.7 django
```
**作成した仮想環境の一覧表示**

```
conda info -e
```
**仮想環境の起動**

```
activate （仮想環境名）
activate testsite
```
**仮想環境の停止**

```
deactivate （仮想環境名）
deactivate testsite
```
**仮想環境の削除**

```
conda remove -n （仮想環境名） --all
conda remove -n testsite --all
```
**condaのバージョン確認**

```
conda info
```
**仮想環境に登録されているパッケージを確認する**

```
conda list
```
**導入したいパッケージを調べる**

```
conda search （パッケージ名）
conda search django
```
**特定のチャンネルにあるパッケージを調べる**

```
conda search -c （チャンネル名） （パッケージ名）
conda search -c conda-forge mysqlclient
```
**パッケージをインストールする**

```
conda install （パッケージ名）
conda install mysqlclient
```
**パッケージをアンインストールする**

```
conda uninstall （パッケージ名）
conda uninstall mysqlclient
```
**パッケージをアップデートする**

```
conda update （パッケージ名）
conda update mysqlclient
```
**すべてのパッケージをアップデートする**

```
conda update --all
```
**現在登録されているチャンネルを調べる**

```
conda config --show channels
conda config --show-sources
```
以下でもできるが、こちらはチャンネルの優先順位も表示される

```
conda config --get channels
```
**チャンネルを追加する**

```
conda config --add channels （チャンネル名）
conda config --add channels conda-forge
```
**チャンネルを削除する**

```
conda config --remove channels （チャンネル名）
conda config --remove channels mysqlclient
```
**condaのキャッシュを削除する**

```
conda clean --all
```

#その他
condaでチャンネルの優先順位を変える場合、チャンネル追加時に指定する必要があるようです。もし変えたい場合は、一旦削除してから再度登録します。

**condaで仮想環境を作ることの欠点**
パッケージによっては古いバージョンしかインストールできず、うまく環境を作れないことがあるので注意！
（沼にハマって、結局環境をvenvで作り直しました…）
MacOSでNifiをインストールして初期設定してみた

データフローを自動化できるNifiを使ってみることにした。

MacOSということから、Homebrewを使ってインストール

https://formulae.brew.sh/formula/nifi
% brew install nifi


下記のコマンドでステータスを確認する。
Nifiのバージョンは最新の1.14
% nifi status
Java home: /usr/local/opt/openjdk@11/libexec/openjdk.jdk/Contents/Home
NiFi home: /usr/local/Cellar/nifi/1.14.0/libexec


インストールが確認できたら、
次は、パスワードを変更する。
Nifiの公式ページのコマンドは、MacOS用のものは書いていなかった為、
少しハマったのだが、以下のコマンドを実行して、初期設定を完了できた。

% SetSingleUserCredentials <username> <password>

すると、以下のレスポンスが返ってくる。
/conf/login-identity-providers.xmlに変更が書き加えられたのだろうか。

Login Identity Providers Processed [/usr/local/Cellar/nifi/1.14.0/libexec/./conf/login-identity-providers.xml]

そして、いよいよNifiを起動してGUIを開く。

バックグラウンドで実行
%nifi start

ちゃんと実行できたかは、以下のコマンドで確認できる。

%nifi status

2021-10-29 06:37:12,135 INFO [main] org.apache.nifi.bootstrap.Command Apache NiFi is currently running, listening to Bootstrap on port 58609, PID=76806

NiFi is currently runningとなっているので、正常に起動しているということ。


そして、ブラウザを開く訳なのだが、
最新のNifiのポートは、localhost:8080/nifiではない!!

localhost:8443/nifiが正しい。
また、デフォルトの設定では、httpではなく、httpsでしか動かない。


ポートの設定を確認したいときは、
%nifi statusで、表示されたパスからconf配下のnifi.propertiesから確認できる。
/usr/local/Cellar/nifi/1.14.0/libexec/conf/bootstrap.conf

/usr/local/Cellar/nifi/1.14.0/libexec/conf
・nifi.properties

ここを確認すると、デフォルトは8443ポートが使われている。
nifi.web.https.port=8443

なので、https://localhost:8443/nifi
打ち込むと、Nifiが開き、ログイン画面が表示されるので、
先ほど設定したユーザ名とパスワードを記載する。


すると、Nifiが表示される
Adafruit NRF52840 ItsyBitsyでUSBシリアルが使えなくて困った話

## 初めに

最近BlueToothやらWi-Fiやらで遊びたい場合にはM5Stackとかがほとんど完成してて気楽に使える。が、実際組み込もうとするとまあいろいろと大変である。作りたいものはキッチンタイマーであったとしても頻繁に充電しなきゃいけないとか、電源切り忘れるとあっさり電池がなくなるとか。

そんなわけでもないんだけど、小さくてBlueToothが使えて低消費電力でArduinoでなんとなく開発ができるボードが欲しかった。で勝ったのが、Adafruitの小さいやつ。

## いつものように、これ

``` main.cpp
#include "Arduino.h"

void setup() { Serial.begin(115200); }

void loop()
{
	Serial.println("Hello world");
} 
```

コンパイルしてみると、なんと、通らない。

```
$ pio run
....
Linking .pio/build/adafruit_itsybitsy_nrf52840/firmware.elf
.pio/build/adafruit_itsybitsy_nrf52840/src/main.cpp.o: In function `setup':
main.cpp:(.text.setup+0xc): undefined reference to `Serial'
main.cpp:(.text.setup+0x6): undefined reference to `Adafruit_USBD_CDC::begin(unsigned long)'
.pio/build/adafruit_itsybitsy_nrf52840/src/main.cpp.o: In function `loop':
main.cpp:(.text.loop+0xc): undefined reference to `Serial'
collect2: error: ld returned 1 exit status
```

「なんでだろう、なんでだろう」？！踊りたくなってきた。知ってる人はもう常識だよね、きっと！

Adafruitで売ってるものだからブートローダの問題ではないはずだ。そもそもリンクできてないんだから。

## おまじないを１行

```
#include <Adafruit_TinyUSB.h> // for Serial
```

これをインクルード文の適当なところに追加して改めてコンパイル。

```
$ pio run
Linking .pio/build/adafruit_itsybitsy_nrf52840/firmware.elf
Checking size .pio/build/adafruit_itsybitsy_nrf52840/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   2.9% (used 7128 bytes from 248832 bytes)
Flash: [=         ]   5.1% (used 41580 bytes from 815104 bytes)
========================= [SUCCESS] Took 0.92 seconds =========================
```

はい、できました！シリアルモニタが使えました。これで開発進みます。
Nuxt.jsを本番環境で永続化する方法

#本番環境でNuxt.jsが勝手に止まってしまう。
Nuxtjsを使い始めてはや三ヶ月。初めてサーバーにデプロイしてみた。
なんとなくだが、ターミナルで起動させているだけだから止まらないの？と疑問に思っていた部分はあったのだが、予想は的中した。


:::note warn
警告
自己責任で！
:::
やり方を調べると意外と簡単らしいのでめも。
#サーバーに pm2 をインストール


```
# yarn で pm2 をインストール
$ sudo yarn global add pm2 --prefix /usr/local

# npm で pm2 をインストール
$ npm install pm2 -g
```



npmとかなのでプロジェクト内にコマンドが保存されるのだろうか？(調べるのめんどい)

#ecosystem.config.jsをルートディレクトリに作成する。


```
module.exports = {
  apps: [
    {
      name: 'NuxtAppName',
      exec_mode: 'cluster',
      instances: 'max', // またはインスタンスの数
      script: './node_modules/nuxt/bin/nuxt.js',
      args: 'start'
    }
  ]
}
```

、npm run build でいつも通り、ビルド。(忘れると有効になりません。)

そして、pm2 start でアプリを起動
重要なのはnpm run コマンドは使わないところです。




# 公式ドキュメントは以下。
https://nuxtjs.org/ja/deployments/pm2/
【Unity】ExecuteEvents.Execute／ExecuteHierarchy でスクリプトからクリック等の操作をおこなう

# はじめに

モバイルアプリを筆頭に「マウス（タッチ）のみで操作を完結させる」というのはよくあることかと思います。
そこで悩ましいのが、開発用やサブ入力として**キーボードなどでもクリックやタップ相当の操作**をしたい！という状況です。

今までは専用メソッドを作るなどゴリ押しで対応してしまっていたのですが、どうにもナンセンスな気がして改めて調べ直したのでここに共有しておこうと思います。

# 前置き

## onClick.Invoke
まず考えるのが、イベントの発火メソッド（Button なら [onClick](https://docs.unity3d.com/ja/2019.2/ScriptReference/UI.Button-onClick.html).Invoke()）を呼び出すことです。

```cs
    _button.onClick.Invoke();
```

が、これは**非アクティブだろうと`enable == false`だろうと`interactable == false`だろうと実行**してしまうため、その辺りのケアが必要です。

## OnPointerClick

とすれば次はイベント受け取りコールバックメソッド（Button なら [OnPointerClick()](https://docs.unity3d.com/ja/2018.4/ScriptReference/UI.Button.OnPointerClick.html)）を呼び出す方法です。

```cs
    _button.OnPointerClick(new PointerEventData(EventSystem.current));
```

これは非アクティブ等の状態も見るらしく前述の問題はなく、これで事足りることも多そうです。ただ、イベントを受け取るコンポーネントが複数ある場合があり（音は別のスクリプトで再生している等）、合わせて正しく再現しようと思うと、**イベントハンドラを持つコンポーネントすべて**で実行しなければなりません。

# オブジェクトでイベントを直接実行する ExecuteEvents.Execute

もっと簡単に**オブジェクトをクリックしたという状態を起こす**ようなことはできないのかな、と色々調べていたところ [ExecuteEvents.Execute](https://docs.unity3d.com/ja/2018.4/ScriptReference/EventSystems.ExecuteEvents.Execute.html) という API があることを知りました。
これはゲームオブジェクトに対してクリック等（IEventSystemHandler 系）のイベントを実行するというものです。

例えば、Button コンポーネントをもつゲームオブジェクトへクリックイベントを送るコードは次のようになります。

```cs
    ExecuteEvents.Execute(_button.gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.pointerClickHandler);
```

これで Button のゲームオブジェクトに対してイベントを送ることができる（＝**他にイベントを受け取るコンポーネントがあればそれにもイベントが飛ぶ**）ので、マウスでのクリックにかなり近い動作になると言えます。

# ヒエラルキーも考慮する ExecuteEvents.ExecuteHierarchy

ExecuteEvents.Execute はゲームオブジェクトに直でイベントを送るため、例えばタッチガード[^1]等、他のオブジェクト配置には無関心です。
もしそこまで考えるなら少し手間が必要で、対象の位置へレイキャストを飛ばしてイベントを発生させるゲームオブジェクトを取得する（もう少し具体的にはオブジェクトの位置に Canvas の GraphicRaycaster からレイキャストを飛ばして一番最初に当たったやつでイベントを発生させる）感じになるかと思います。

[^1]: 手前に RaycastTarget を有効にした Image などを置いてイベントをせき止めるやつです。私の周囲ではタッチガードと呼んでいますが正しい名前とかあるんでしょうか…。

ところが少し困ったことに、uGUI 特有のイベントのヒエラルキー伝搬（？）で**「一番最初に当たったオブジェクト」が直接のイベント実行対象でない**場合[^2]があります。
しかしそこはさすが Unity、それをやってくれる [ExecuteEvents.ExecuteHierarchy](https://docs.unity3d.com/ja/2018.4/ScriptReference/EventSystems.ExecuteEvents.ExecuteHierarchy.html) という API がピンポイントでありました。
例えば次のようなコードを書けば、クリックが最初に当たったゲームオブジェクトがイベントを発生させる対象でなくても**親オブジェクトを辿ってイベントを発生させる対象を探して実行してくれて**、かつ、（タッチガードのような）**親子関係にないオブジェクトで遮られていれば反応しない**という、ほぼクリックしたのと同じ状態を再現できます。

```cs
    // ※_raycaster は Canvas に付いている GraphicRaycaster

    PointerEventData eventDataCurrent = new PointerEventData(EventSystem.current);

    // イベントデータをボタンの位置に移動
    eventDataCurrent.position = RectTransformUtility.WorldToScreenPoint(_raycaster.eventCamera, _button.transform.position);

    // イベント受け取り可能なオブジェクトを取得
    var hits = new List<RaycastResult>();
    _raycaster.Raycast(eventDataCurrent, hits);
    if (hits.Count > 0)
    {
        // 最前面のオブジェクトにクリックイベントを実行
        ExecuteEvents.ExecuteHierarchy(hits[0].gameObject, eventDataCurrent, ExecuteEvents.pointerClickHandler);
    }
```

[^2]: デフォルトの Button を作ったときに、手前に Text が付いてきますが、Button の子オブジェクトになっているので問題なく反応してくれるアレです。

# おわりに

私は今回この API を初めて知りましたが、かなり昔のバージョンからあったようですね。
本記事が何かのお役に立てば幸いです。
Keynoteの表にTrueまたはFalseを入力する方法

Keynoteの表にTrueまたはFalseを入力すると自動的にTRUEまたはFALSEに変換される。
最初だけ大文字にしたい場合は、'Trueまたは'Falseと入力するとTrueまたはFalseと表示できる。
NATとは

#NAT : Network ADdress Translator 
ローカルなネットワークにはプライベートIPを設定して、インターネットへ接続するときは、ネットワークをグローバルIPアドレスに変換する技術。

背景としては、IPアドレスの枯渇の問題に対して、常に接続していないホストに枯渇しているグローバルIPを割り当てるのは無駄があるから。
IPv6が、普及すれば、NATを使用しなくても大丈夫になる。

NATを使うことによって1つのグローバルIPアドレスで、複数のホストが通信することが可能になる。

##デメリット
u
<ul>
<li>変換処理のオーバーヘッドのため、告訴区転送処理ができるNATを安価で作るのが困難であり、通信性能が下がる。</li>
<li>外部から内部サーバーに接続することはできない。</li>
<li>通信中にNATが異常動作をして再起動したときは、すべてのTCPコネクションがリセットされる。</li>
<li>NATを2台用意して故障時に切り替えようとしても、TCPコネクションは必ず切れる。</li>
</ul>
javascript演習　〜１０日目/３０日

覚えたこと

e.shiftKey, ctrlKey, altKey

```javascript
checkbox.addEventListener('click', function(e){
  console.log(e.shiftKey)
)
```

thisの使い方、A = !Aとか

```javascript
function handleCheck(e){
    if(e.shiftKey && this.checked){
      checkboxes.forEach(checkbox => {
        if((checkbox === this || checkbox === lastChecked) && lastChecked){
          inBetween = !inBetween;
        }
        if (inBetween){
          checkbox.checked = true;
        }
      })
    }    
    lastChecked = this;
  }
```
TJBot zero updates 2021/10

# TJBot zero updates 2021/10

TJBot zeroを楽しむ為のアップデートです。
ここのところアップデートが出来ていませんでしたが、ピックアップしていきたいと思います。

## 変わったところ・注意点（普通に利用）
1. Watson Visual Recognitionが無償プラン廃止
    1. Google Teachable Machineで代用して対応
    1. 有料プランのVisualRecognitionで対応可能
1. IBM Cloud ライトアカウントが廃止
    1. クレジットカードが必要に
1. 

## 変わったところ・注意点（イメージを自分でビルド）
1. node-red-contrib-openjtalkが公開停止

## 新しいニュース
1. TJBot zeroの足にアクリル板の補強脚セットが公開
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126158/55c5fcb2-980e-368e-9bad-6173de6d3163.png)
https://shop.tjbotfan.tokyo/products/detail/16

1. TJBot zero HATの一般販売が開始

1. 小学生向けTJBot Summer Schoolを開催
    1. TJBotzero + TJBotzero HATで組み立て簡単ハンズオンの実現
【SwiftUI】Textをいじる

```swift
Text("Font").font(.headline)
Text("FontColor").foregroundColor(Color(.blue))
Text("FontWeight").fontWeight(Font.Weight.thin)
Text("Bold").bold()
Text("LineLimit\na").lineLimit(1)
Text("Italic").italic()
Text("[Link](https://www.example.com)")
Text("~~MARKDOWN~~")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263661/c9dfe32d-c643-7321-945d-487c587f0f0f.png)
railsチュートリアル第１０章 管理ユーザー

##ユーザーを削除する
###管理ユーザー
特権を持つ管理ユーザーを識別するために、論理値をとるadmin属性をUserモデルに追加

```
ubuntu:~/environment/sample_app (updating-users) $ rails generate migration add_admin_to_users admin:boolean
Running via Spring preloader in process 3171
      invoke  active_record
      create    db/migrate/20211016122254_add_admin_to_users.rb
````

####boolean型のadmin属性をUserに追加するマイグレーション
db/migrate/[timestamp]_add_admin_to_users.rb

```rb
class AddAdminToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :admin, :boolean, default: false
    # adminカラムがusersテーブルに追加されます。
    # default: false デフォルトでは管理者になれないということ
    # adminの値はデフォルトでnilになります
  end
end
```
admin属性の論理値

```rb
$ rails console --sandbox
>> user = User.first
>> user.admin?
=> false
>> user.toggle!(:admin)
# admin属性の状態をfalseからtrueに反転
=> true
>> user.admin?
=> true
```

####サンプルデータ生成タスクに管理者を1人追加する
db/seeds.rb

```rb
# メインのサンプルユーザーを1人作成する
User.create!(name:  "Example User",
             email: "example@railstutorial.org",
             password:              "foobar",
             password_confirmation: "foobar",
             admin: true)
# create!は基本的にcreateメソッドと同じものですが、
#   ユーザーが無効な場合にfalseを返すのではなく例外を発生させる
# admin:trueにして管理者にする

# 追加のユーザーをまとめて生成する
# メイン以外のユーザー99人を作成
99.times do |n|
  name  = Faker::Name.name
  email = "example-#{n+1}@railstutorial.org"
  # 数ごとにメアドが変更される
  password = "password"
  # パスワードは変わらない
  User.create!(name:  name,
               email: email,
               password:              password,
               password_confirmation: password)
  # 許可された属性リストにadminが含まれていない
  # 任意のユーザーが自分自身にアプリケーションの
  #   管理者権限を与えることを防止
  
end
```
#####データベースをリセットして、サンプルデータを再度生成
```
$ rails db:migrate:reset
$ rails db:seed
```

###演習
1.
Web経由でadmin属性を変更できないことを確認してみましょう。具体的には、リスト 10.56に示したように、PATCHを直接ユーザーのURL（/users/:id）に送信するテストを作成してみてください。テストが正しい振る舞いをしているかどうか確信を得るために、まずはadminをuser_paramsメソッド内の許可されたパラメータ一覧に追加するところから始めてみましょう。最初のテストの結果は red になるはずです。最後の行では、更新済みのユーザー情報をデータベースから読み込めることを確認します（ 6.1.5）。

```rb
require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest
.
.
.
  test "should not allow the admin attribute to be edited via the web" do
    log_in_as(@other_user)
    assert_not @other_user.admin?
    patch user_path(@other_user), params: {
                                    user: { password:              "password",
                                            password_confirmation: "password",
                                            admin: true } }
    assert_not @other_user.reload.admin?
    # レコードの再取得を行い、adminカラムを検証する
  end
.
.
.
end
```
今度のテストの意図が少し分かった。
railsチュートリアル第１０章 パーシャルのリファクタリング

###パーシャルのリファクタリング
railsの便利なツールを使ってコードを整理する

####indexビューに対する最初のリファクタリング
app/views/users/index.html.erb

```rb
<% provide(:title, 'All users') %>
<h1>All users</h1>

<%= will_paginate %>

<ul class="users">
  <% @users.each do |user| %>
    <%= render user %>
  <% end %>
</ul>

<%= will_paginate %>
```
####各ユーザーを表示するパーシャル
app/views/users/_user.html.erb

```html
<li>
  <%= gravatar_for user, size: 50 %>
  <%= link_to user.name, user %>
</li>
```
####indexページの完全なリファクタリング
app/views/users/index.html.erb

```html
<% provide(:title, 'All users') %>
<h1>All users</h1>

<%= will_paginate %>

<ul class="users">
    <%= render @users %>>
     <!--Railsは@users をUserオブジェクトのリストであると推測-->
    <!--ユーザーのコレクションを与えて呼び出すと、
          Railsは自動的にユーザーのコレクションを列挙し、
          それぞれのユーザーを_user.html.erbパーシャルで出力します。-->
</ul>

<%= will_paginate %>
```

#####テスト
```
ubuntu:~/environment/sample_app (updating-users) $ rails t
Running via Spring preloader in process 13391
Started with run options --seed 44048

  39/39: [============================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.78213s
39 tests, 131 assertions, 0 failures, 0 errors, 0 skips
```

###演習
1.
リスト 10.52にあるrenderの行をコメントアウトし、テストの結果が red に変わることを確認してみましょう。

```rb
ubuntu:~/environment/sample_app (updating-users) $ rails t
Running via Spring preloader in process 13535
Started with run options --seed 33825

 FAIL["test_index_including_pagination", #<Minitest::Reporters::Suite:0x0000563856c5da48 @name="UsersIndexTest">, 2.744917383000029]
 test_index_including_pagination#UsersIndexTest (2.74s)
        Expected at least 1 element matching "a[href="/users/14035331"]", found 0..
        Expected 0 to be >= 1.
        test/integration/users_index_test.rb:19:in `block (2 levels) in <class:UsersIndexTest>'
        test/integration/users_index_test.rb:18:in `block in <class:UsersIndexTest>'

  39/39: [============================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.65557s
39 tests, 102 assertions, 1 failures, 0 errors, 0 skips
```
```Expected at least 1 element matching "a[href="/users/14035331"]", found 0..
        Expected 0 to be >= 1.```
1以上の方がいいらしい。
【VirtualBox+Apache+PHP】共有ファイルのパーミッションエラーを解消する方法

VirtualBoxでCentOSにApacheをインストール。
共有ファイルで作成したtest.phpに接続すると、「You don't have permission to access /test.php on this server.」と表示され、ページの表示ができなくて結構ハマりました、、、

無事解決出来たので手順を記録しておきます。

##環境
VirtualBox：6.1.28
ホストOS：MacOS Big sur 11.5.2
ゲストOS：CentOS7
Apache：2.4

##前提条件
「VirtualBox Guest Additions」をインストール済みであること
共有フォルダーのマウント方法は「自動マウント」にしていること

##エラー解消手順
エラーの原因は、ファイル共有をすることにより、ゲストOS（CentOS7）側のマウント先のフォルダの権限が強制的に「rootユーザまたはvboxsfグループ」のみしか読み込み権限が付与されていないからでした。

```
# ls -la /var/www/
drwxrwx---.  1 root vboxsf 128 10月 28 22:18 html
```
これだと一般のユーザがアクセスした場合、当然のことながら読み込み権限がなくページが表示されません。

※今回ホストOS（Mac）側のフォルダを、apacheのドキュメントルートで設定している/var/www/htmlにマウントしています。

###対処法：apacheのユーザを「vboxsf」グループに追加
chmodで権限を変更しようとしても、共有フォルダの場合変更が効きません。（酷い仕様です）

回避策としては、apacheのユーザを「vboxsf」グループに追加してあげれば、ページにアクセスする際に、読み込み権限が付与されて問題を解消できるはず。

apacheのユーザ名は、「/etc/httpd/conf/httpd.conf」の下記コード部分で確認可能です。

```
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
#
User apache
Group apache
```
apacheが「apache」というユーザでhttpリクエストを受け取り、phpファイルにアクセスする訳なので、この「apache」ユーザをグールプへ追加します。

```
# gpasswd -a apache vboxsf
```


apacheがvboxsfグループに追加されたか念のため確認します。

```
# id apache
uid=48(apache) gid=48(apache) groups=48(apache),995(vboxsf)
```

無事追加されていることを確認できたら、CentOSを再起動します。

```
# reboot
```

これで問題なく表示されると思って、アクセスしてみたらまだパーミッションがないと怒られました、、、

###上記設定後もパーミッションエラーとなる場合
それでもApacheからファイルが見れない場合「SELinux」の設定に問題がある可能性があります。

CentOSにはデフォルトでSELinuxがインストールされています。
下記コマンドを実行し「Enforcing」と返って来れば、SELinuxが有効になっています。

```
# getenforce
```
SELinuxは、強制アクセス制御機能を加えるモジュールで、このモジュールが有効になっていることにより、ファイルの権限がないと怒られている可能性があります。

下記コマンドを入力し、一時的に無効にします。

```
# setenforce 0
```

再度CentOSを再起動し、ブラウザからアクセスします。
無事表示されれば、SELinuxが原因です。

恒久的に、SELinuxを無効にするためには、設定ファイルを開き「SELINUX=disabled」と変更します。

設定ファイル：/etc/selinux/config

```
SELINUX=disabled
```

以上で無事、共有ファイルで作成したphpファイルを開くことができました。

調べていたら、Apache2.4のhttpd.configの内容がおかしい、という情報もありました。

今回の手順で解決しない場合は、下記のページも参考になるかと思います。

https://arc-tech.hatenablog.com/entry/2019/09/27/093513

##参考文献
https://www.codelab.jp/blog/?p=2587
正規表現 ファイルごとにプロシージャ作成 VBA

###ファイルごとに下記のようなプロシージャを作成する例

```java
ファイル名

↓

sub　ファイル名()
dim 変数 as String
変数
call 関数(変数,★)
end sub
 
```
正規表現で置換する
(^.*) → sub $1()\tdim 変数 as string\tcall 関数(変数,★)\tend sub

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/09f0d7c8-eece-9732-77ca-a42ad9bdda5d.png)

```java
sub ファイル1()	dim 変数 as string	call 関数(変数,★)	end sub
sub ファイル2()	dim 変数 as string	call 関数(変数,★)	end sub
sub ファイル3()	dim 変数 as string	call 関数(変数,★)	end sub
```
最後にタブ\tを改行\r\nに置換して完了。
ファイル名が多ければ多いほど効果的になる。

```java
sub ファイル1()
dim 変数 as string
call 関数(変数,★)
end sub
sub ファイル2()
dim 変数 as string
call 関数(変数,★)
end sub
sub ファイル3()
dim 変数 as string
call 関数(変数,★)
end sub
```
AWS: Wordpress環境構築やってみた：Gateway Timeoutになる原因。ミスったこと

<h1>データベースにログインができずに　Gateway timeout</h1>
＜経緯＞
　RDB作成時に、セキュリティグループを追加し内容をwebサーバーのセキュリティグループに変更する際、そのままでは 
”You may not specify a referenced group id for an existing IPv4 CIDR rule”
と出てしまうので、
一度、新しいセキュリティグループのインバウンドの設定を削除してから、新たにセキュリティグループを適用させた。

<h2>原因は</h2>
削除しただけで、DBRのポート番号が欠落した状態だったため、エラーになっていた。


<h2>反省と気付き</h2>
初学者で、複雑な設定に戸惑い基本的なことが抜けてしまった。
複雑そうなところを何度も何度も見返して、サイダーは間違っていないかなどそちらばかりに目がいってしまった。

ポートは大事ですね　（汗）


___
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
___
dockerでazure functionsのhttpTriggerをfunctionのauthLevelで開発できるようにする

##背景
* local開発環境はdocker使ってazure functions構成のnodejsのapiを開発している。
* 認証としては**functionのauthLevel**を使いたい。
* authLevelの設定はこんな感じ

```json
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "route": "your/route",
      "methods": ["post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ],
  "scriptFile": "../your/source/folder/index.js"
}
```
* `API_KEY`はazure function appのポータルからとるか、az cliで取れたりする。
* 使う時はこんな感じでcodeというパラメータを使う：

```html
https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>
```
* あるいはrequestのheadersに`x-functions-key`を追加することで認証ができる。

## 課題
* Localのテストで、  
  開発環境のdocker hosted azure functionsに認証を通すには、  
  `API_KEY`を手動で設定する必要がある。(自動生成したkeyは知らないし)


## 解決方法
*まずは下記ファイルを作成：  

host_local_secrets.json

```json
{
    "masterKey": {
        "name": "master",
        "value": "your_local_test_master_key",
        "encrypted": false
    },
    "functionKeys": [{
        "name": "default",
        "value": "your_local_test_function_key",
        "encrypted": false
    }]
}
```

* Dockerfileに下記を追加：

Dockerfile

```dockerfile
FROM mcr.microsoft.com/azure-functions/node:3.0-node12
RUN mkdir /etc/secrets/
ENV FUNCTIONS_SECRETS_PATH=/etc/secrets
ENV AzureWebJobsSecretStorageType=Files
ADD host_local_secrets.json /etc/secrets/host.json
```
* Boom!!! Done. 認証ができるようになった。
* Fly as you wish. To the moon. Freely.
【Corda】Bootcamp をやってみた①

## ゴール
Corda Bootcampを通してCordaの基本的な概念や実装方法を何となく理解する

## 参考
https://www.youtube.com/watch?v=tm06GCD0XJI

## 事前準備
- IntelliJ IDEAをインストール
    - https://www.jetbrains.com/ja-jp/idea/download/#section=mac

### 補足
VSCodeを使う場合Extensionをインストールする
- Java Extension Pack
- VSCode-Corda
  

## やったこと
### ① レポジトリをクローン
こちらのレポジトリをクローンします。
https://github.com/corda/bootcamp-cordapp

```shell
$ git clone https://github.com/corda/bootcamp-cordapp
```
### ② JDK 1.8をダウンロード
IDEAのpreference > Build, Extension, Deployment > Build Tools > Gradle　を開いて
JDKの1.8をダウンロードします。
1.8じゃないとBuildが通りません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263661/1ff1b5e6-78c9-b18f-b6b6-fbfdf568081f.png)

Buildが通った後もDependencyのimportに結構時間がかかるので、焦らずに待ちましょう。

### ③ StateTestsが通るようにする
src > test > java > bootcamp の StateTestsを開くとコメントアウトされています。
これを外してテストが動くように実装していきます。
TDDでハンズオンが進んでいくようです。
例えば、こちらが最初のテストですが、TokenStateを実装していないのでこのテストは失敗します。

```java
@Test 
public void tokenStateHasIssuerOwnerAndAmountParamsOfCorrectTypeInConstructor() {
  new TokenState(alice, bob, 1);
}
```
#### Stateの実装で分かったこと
StateはContractStateをimplementして作成する.
そしてgetParticipants()をoverrideして実装する。
このgetParticipants()で誰がこのStateを確認できるかを指定することができる。
### ④ ContractTestsが通るようにする
StateTestsと同じようにContractTestsも成功するようにしていきます。
#### Contractの実装で分かったこと
ContractはContractをimplementして作成する。
そしてverify()をoverrideして実装する。
このverifyでtransactionを検証することができる。
### ⑤ FlowTestsを通るようにする
FlowTestsに関しても同様に成功するようにしていきます。
#### Flowの実装で分かったこと
FlowでStateを生成して、トランザクションを実行する
### ⑥ Cordappの動作を確認する 
実装したコードを実行して、動作を確認する。
Cordaの特徴である秘匿性を実際に体験できる。
build.gradleを確認すると、4つのnodeが定義されています。
これを起動して、例えば PartyA から PartyB に 100amount 送るというトランザクションを発生させると
AとBではそのトランザクションを確認できるが、Cでは確認できないというふうなことを試すことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263661/1f6abe72-8c1e-bc26-4a68-25909b31749a.png)

## 感想
動画を見ると時間がかかりますが
実際に手を動かすのは15分ぐらいなので
興味ある人はやってみてください

## 記事にしたいこと
ざっくりとした概念や実装方法は分かったので
もう少し深掘りして理解する
ドキュメントがしっかりしているのでちゃんと読めば理解できそう
obnizを楽器化してみたかった。。

皆さんこんにちは、khara_xedgeです。

今回、「obniz board 1Y」というデバイスを入手しました！
「obniz board 1Y」とは、wifiで簡単にインターネットへ接続することができるマイクロコンピュータです。各種センサ接続用の端子を持ち、センサから様々な情報を取得しながら動作するシステムの作成など、IoT工作が手軽に始められます。

そんな「obniz board 1Y」を使って、楽器もどきを作ってみたいと思います。

#環境

今回実装した時の環境は以下の通りです。

◆実行環境
・Node.js 16.10.0

◆パッケージ
・npm 7.24.0

◆コーディング
・Visual Studio Code 1.61.0

◆ハード部品
・obniz board 1Y
・IC温度センサ
・圧電スピーカー
・LED照明（赤）

#演奏スタート！！
いきなりですが、実行結果から！

https://twitter.com/khara_xedge/status/1453365419385835526


#ソースコード

動画で実行したコードは以下の通りです。

```.js
const Obniz = require('obniz');
const obniz = new Obniz('obnizIDを入力');

obniz.onconnect = async function () {
    //温度センサの接続端子
    const tempsens = obniz.wired('LM60', { gnd: 0, output: 1, vcc: 2 });
    //LEDの接続端子
    const led = obniz.wired('LED', { anode: 4, cathode: 5 });
    //スピーカーの接続端子
    const speaker = obniz.wired('Speaker', { signal: 10, gnd: 11 });

    led.on(); //接続時LEDオン

    setInterval(async () => {

        //温度取得
        const temp = await tempsens.getWait();
        // 温度をコンソールに表示
        console.log(temp);
        // displayに反映
        obniz.display.clear();
        obniz.display.print(temp + 'C');

        //ランダム数値生成
        var rmd = Math.floor(Math.random() * 15) + 1;
        let temphz = temp * rmd * rmd;
        
        //スピーカーに音出力
        console.log(temphz);
        console.log(rmd);
        speaker.play(temphz);

    }, 1000); //一定間隔で動作させる

}
```

こちらのコードでは、「obniz board 1Y」に接続した温度センサで室温を取得し、その値にランダムな値を計算させた結果で音階を決定させ、スピーカーから出力しています。


#実は・・

今回室温の値をもとに音階を決定してスピーカーから出力していますが、聞いていただいた通り楽器とは言えません。。
(室温自体あまり変化しないため、ランダム関数で無理やり変化させています)
楽器は自分で演奏してこそ楽器だと思うので、以下のセンサーを使用して構成してみようと思いました。



###・HC-SR04(超音波距離センサー)
![IMG_6345.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2123201/560033cb-d70e-8bad-51eb-d966e1d5a386.jpeg)

こちらは超音波の反射を利用して対象物までの距離を測る測距センサです。
このセンサで取得した距離を音階に設定し、手を近づけたり話したりすることで変化させようと試みました。
__（弦楽器での弦の長さで音階が変わるイメージです）__

いざ実行してみると..
###距離センサの取得した値が0のまま、うんともすんとも言わなくなってしまいました。。
console.logに値を吐き出そうとすると以下のエラーメッセージがでてました。

```
alert: 'warning',
  message: 'io3: heavy output. output voltage is too low when driving high'
```

いろいろ調べましたが、おそらく過電流による不具合の可能性。。
自分の今の手持ちでは対応できそうにないため今回はあきらめました。。

#まとめ
今回「obniz board 1Y」を手に入れたのでセンサやスピーカーを接続してみました。
スピーカーの音階を制御できることから、簡単な楽器を作成してみたかったのですが断念。。
ただ仕組み上温度センサの値を距離センサの値に置き換えることで動きそうなので、興味がある方はチャレンジしてみてください。
GitHub Universeで公開された新機能まとめ

## はじめに
日本時間2021/10/28-29で開催されているGithub UniverseというGithubの年1度のイベントがあり、いくつか新機能が公開されたので簡単にまとめてみました。いやーGithubすごいと思った今日この頃です。

より詳しく知りたい方は以下公式ブログをご参照ください。

https://github.blog/2021-10-27-everything-new-from-universe-2021/

## 1. Command Palette
![command-palette-universe-announcement.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407956/3a9e45e2-b19a-a6f8-1bb8-b849b02c8796.gif)

`github.com`上で`CMD+K`を押すとMacでいうサーチバーのようなものが現れ、レポジトリ、Issue、PRなどの検索が行える。
個人的に今年の発表で一番嬉しいのはこれかも。

## 2. GitHub Codespace
Codespaceにはレポジトリ画面で`.`を押すと移動できます。

https://github.blog/changelog/2021-10-27-new-codespaces-features-launching-at-universe-2021/

### 2-1. CLI操作
CLIを使えばローカルマシンから、codespaceの作成やSSHなんかができちゃいます。

```bash
# Create a new codespace via the CLI
gh codespace create --repo monalisa/octocat --branch main
```

```bash
# SSH into the codespace created above
gh codespace ssh -c monalisa-monalisa-octocat-1337h4x0r
```

SSHできるのはvim, emacsユーザにはめちゃ嬉しいですね！

### 2-2. Port forward
codespaceで起動した開発用サーバ（例えば、`npm start`)をTeamやOrganization内の人とリンクを共有するだけで共有可能。要するに一時的に仮想サーバ上にhostして公開することで他人にすぐレビューしてもらえる。これはかなり便利。

CLIとGUIの両方からPort forward可能。

```bash
# Make port 80 visible to all users in an org
gh codespace ports visibility 80:org -c monalisa-monalisa-octocat-1337h4x0r
```

### 2-3. devcontainer 
プロジェクトルートの`./devcontainer`ディレクトリに`Dockerfile`とjson形式の設定ファイルに依存関係を記述することでCodespaceで利用するイメージをカスタマイズでき、チーム間で共有できる。

## Issue

https://github.com/features/issues/

### ボードとテーブルビューの切り替え
![CleanShot 2021-10-28 at 23.24.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407956/22ccfec6-9d4f-4963-8407-f9e7b61c15b4.png)
スプレッドシートみたいな見た目でIssue管理できます。もちろん特定の条件でフィルタ、ソートできます。

### IssueをTaskに分割

![CleanShot 2021-10-28 at 23.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407956/422ce482-326a-7cac-8af3-bcde72067fbb.png)

Issueをさらに小さいTaskという単位に分割して管理できます。


### 投票機能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407956/cb242861-a602-ce91-4a3a-fcc2337bb170.png)


## まとめ

ここ数年のGithubの躍進がすごく、そのうち本当にGithub上で開発が完結する日が来るのではと感じた2021のGithub Universeでした。ぜひ新機能使ってみてくださいー。
備忘録~リファレンスについて~

##リファレンスとは（PHP)

###例１と例２を比較して理解しよう！
#####（例１）
```
$a = 'qiita';
$b = $a;
$a[0] ='z';
echo $a . PHP_EOL;
echo$B . PHP_EOL;
```
上のコードを実行すると、

```
zhp
php
```
を返す。

#####（例2）
```
$a = 'qiita';
$b = &$a;
$a[0] ='z';
echo $a . PHP_EOL;
echo$B . PHP_EOL;
```
上のコードを実行すると、

```
zhp
zhp
```
を返す。

###解説
変数（箱）の中に値（中身）が入っている。

・例１のような通常の代入は＄aの変数の値を＄bの変数に代入している。
訳すと、＄aという名前の箱の中身を＄bという名前の箱の中にコピーして入れている。
なので、＄aの値と＄bの値は別々で存在しており、三行目で変更しているのは＄aの中の値だけである。


・例２はリファレンスを代入している。
リファレンスとは同じ変数を異なった名前で呼び出すこと。「あだ名」である。
つまり例２は一つの値が入っている変数の名前が二つある状態。
訳すと、＄aというあだ名をもった中身（qiita）が入っている箱に＄bというあだ名をつけている。
なので、＄aの値と＄bの値は同じものであり、三行目は＄aと＄bの共通の値を変更していることになる。
Azureでアーキテクチャ設計する際に参考にすると良いサイト

## はじめに
Azureでアーキテクチャ設計をする際、よく参考にしているサイトを記載します。
**「Azureで開発したいけど、どのAzureリソースを利用・組み合わせればよいか分からない」**といった人に少しでも参考になればと思います。

## よく参考にしているサイト
### [Azure アーキテクチャセンター](https://docs.microsoft.com/ja-jp/azure/architecture/)

公式にも
> 確立されたパターンと手法を使用して Azure でソリューションを設計するためのガイダンスです。

とあるように、設計時のベストプラクティスを参考にしたいときに活用します。特に
- [アーキテクチャの例](https://docs.microsoft.com/ja-jp/azure/architecture/browse/)
- [コンピューティングサービスの選択](https://docs.microsoft.com/ja-jp/azure/architecture/guide/technology-choices/compute-decision-tree#choose-a-candidate-service)
- [負荷分散のディシジョンツリー](https://docs.microsoft.com/ja-jp/azure/architecture/guide/technology-choices/load-balancing-overview#decision-tree-for-load-balancing-in-azure)
あたりを見ると、アーキテクチャの全体像をイメージできてくると思います。


### [Azure Learn](https://docs.microsoft.com/ja-jp/learn/browse/)
Azureの各リソースの用途や実際の設定方法を理解する際に参考にします。
Azureの資格試験のラーニングパスとしても活用できるようです。
https://docs.microsoft.com/ja-jp/learn/certifications/azure-fundamentals/


### [Azureリソースの命名規則の例](https://docs.microsoft.com/ja-jp/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming)

各Azureリソース、環境(本番、ステージング、開発...etc)等の情報を識別しやすいようにするため、Azureリソースの名付けをする際に参考にします。
また[各Azureリソースの推奨される省略形](https://docs.microsoft.com/ja-jp/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations)も併せて参考にします。