OmniAICreator/Qiita-1.07M huggingface dataset:
自作シェルスクリプトのパスを記載せずに実行したい。

<p>最近、業務中の作業コストをさげるためにLinuxでシェルスクリプトを作成することが増えてきました。<br>
スクリプト作成時当初はスクリプトをたたくだけ喜んでいましたが、慣れてくると、毎回スクリプトを実行するためのパスを記載するのが面倒になりつつあります。<br>今回はパスを記載せず、スクリプトを実行するためにしたこといくつか記載します。</p>
<p>環境はCentOS7.9です。</p>

<p>まず、以下ファイルを用意しました。<br>

```sh
/root/cmd/hoge.sh　
echo "hoge"
```

<h1 class="has-normal-font-size">方法1　.bash_profile　内のexportにパスを追記する。</h1>

<p><br>例<br>

```sh
vim  .bash_profile
export PATH=$HOME/cmd:$PATH
```
hoge.shを実行する。

```sh
hoge.sh
hoge
```
<h1 class="has-normal-font-size">方法2　/usr/local/bin 以下にシンボリックリンクを追加する。</h1>

<p>例</p>

```sh
ln -s ~/cmd/hoge.sh /usr/local/bin/hoge2
```

hogeを実行する。<br>

```sh
hoge2
hoge
```


<p>いずれも上記の方法はファイルが環境変数$PATH内にパスがあれば、<br>CUI内でコマンドを探して実行してくれるというルールの上で成り立っているらしいです。<br>ちなみに　<br>/bin/はシングルモード用（OSが壊れてときとか）<br>/usr/bin/はシングルモードではないかつ、RPM等のパッケージに入っているコマンド等が収納<br>/usr/local/binは自作スクリプトなどを置くディレクトリ<br>なので今は自作スクリプトを主に方法2の方法で採用しています。</p>
TypeScriptにて文字列として表現される日付情報をDate型に変換しつつ型チェックしたい

`fp-ts`や`io-ts`の概要を知っている方向けです.

## 結論
**日付情報が必ず文字列で表現される**のであれば, `io-ts-types`で提供されている`DateFromISOString`を使いましょう.
(日付情報がDate型で表現される場合がダメな理由は下の方を見てください)

[公式doc](https://gcanti.github.io/io-ts-types/modules/DateFromISOString.ts.html)

```typescript
import * as t from "io-ts"
import * as tt from "io-ts-types"

const UserCodec = t.type({
  id: t.number,
  name: t.string,
  createdAt: tt.DateFromISOString,
  updatedAt: tt.DateFromISOString,
})

type User = t.TypeOf<typeof UserCodec>
/**
 *  type User = {
 *     id: number
 *     name: string
 *     createdAt: Date
 *     updatedAt: Date
 *  }
 */

// ex
const inputValue = {
  id: 3,
  name: "るりと",
  createdAt: "2021-03-25T14:48:38.401Z",
  updatedAt: "2022-03-25T17:42:38.401Z",
}

console.log(UserCodec.decode(inputValue))
/**
 * {
 *    _tag: "Right"
 *    right: { id: 3, name: "るりと", createdAt: Wed Mar 16 2022 02:42:38 GMT+0900 (日本標準時)・・・ }
 * }
 */
```

## 本題
普通の`Date`型であれば、`io-ts-types`にて提供されている`date`を用いれば型チェックが出来ます. しかしながら, JSONなどに日付情報が文字列として埋め込まれている状態に対しては`date`を用いても弾かれてしまいます.

[io-ts-typesのdate](https://gcanti.github.io/io-ts-types/modules/date.ts.html)
[コードの参考元](https://gcanti.github.io/io-ts-types/modules/DateFromISOString.ts.html#datefromisostring)
```typescript
import * as tt from 'io-ts-types'
import * as E from 'fp-ts/Either'

// Date型で日付が表現される場合は通る
const date = new Date(1973, 10, 30)
assert.deepStrictEqual(tt.date.decode(date), E.right(date))

// 文字列で日付が表現される場合は弾かれる
const input = date.toISOString()
assert.deepStrictEqual(tt.date.decode(input), E.left(date))
```

ここで`io-ts-types`にて提供されている`DateFromISOString`を用いることによって, 文字列としての日付情報を`Date`型として型チェックすることが出来ます.

```typescript
import * as tt from 'io-ts-types'
import * as E from 'fp-ts/Either'

const date = new Date(1973, 10, 30)
const input = date.toISOString()
assert.deepStrictEqual(tt.DateFromISOString.decode(input), E.right(date))
```

## 注意点
`Date`型で表現される日付情報を`DateFromISOString`で型チェックしようとすると弾かれます.
```typescript
import * as tt from 'io-ts-types'
import * as E from 'fp-ts/Either'

const date = new Date(1973, 10, 30)
assert.deepStrictEqual(tt.DateFromISOString.decode(input), E.left(date))
```
PGPでのWeb of Trustとは

## これはなに

PGP/GPGで信頼モデルとして

- 公開鍵基盤（PKI）
- Web of Trust（WoT）

が出てきたので、Web of Trustについて学んだことをまとめる。

## Web of Trustとは

> 引用: https://en.wikipedia.org/wiki/Web_of_trust
> 
> In cryptography, a web of trust is a concept used in PGP, GnuPG, and other OpenPGP-compatible systems to establish the authenticity of the binding between a public key and its owner. Its decentralized trust model is an alternative to the centralized trust model of a public key infrastructure (PKI), which relies exclusively on a certificate authority (or a hierarchy of such). As with computer networks, there are many independent webs of trust, and any user (through their public key certificate) can be a part of, and a link between, multiple webs.
>
> （日本語訳）
> 暗号技術において、Web of Trustは、PGP、GnuPG、およびその他のOpenPGP互換システムにおいて、公開鍵とその所有者の間の結合の信頼性を確立するために使用される概念である。この分散型信頼モデルは、認証局（またはその階層）のみに依存する公開鍵基盤（PKI）の集中型信頼モデルの代替となるものです。コンピュータネットワークと同様に、多くの独立した信頼の網が存在し、どのユーザーも（公開鍵証明書を通じて）複数の網の一部となり、またその間をつなぐことができるのです。

HTTPSのような認証局による公開鍵の証明とは異なり、それぞれの個人が認証をしあい、信頼を構築していくモデルのこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352836/f51cb9ef-be63-3721-ef78-b02ab02b5499.png)
（引用: https://en.wikipedia.org/wiki/Web_of_trust）

画像左の`Ingo`が自分だとすると、

1. 友達である`Eva`と`Axel`は信頼できる
2. `Manuel`は`Eva`が信頼できる（例えば友達）としているため、知らない人だが`Ingo`からも信頼できる
3. `Susi`は`Manuel`が信頼できるとしているため、`Eva`も知らない人だが信頼できる

といった連鎖によって信頼のネットワークを構築していく。

信頼できるかどうかの判断は公開鍵への署名によって行われ、その証明書をもとに判断される。

この連鎖によって信頼する深さ,信頼できるとしている人数などに関してはそれぞれの個人が設定できる。
上記の例だと、友達である`Eva`と`Axel`の友達までは信頼するといったことができる。

このように認証局に左右されず、自身で信頼の基準を決めることができる。

以下の記事が具体的でわかりやすい。

https://www.gniibe.org/memo/software/gpg/what-is-not-wot.html

### 信頼できると安全は別の話

ただし、信頼できると安全は別の話である。
PKIやWeb of Trustが保証するのは、その公開鍵と鍵の持ち主が一致していることであって、その持ち主がどんな人かまでは保証できない。

HTTPSが良い例で、HTTPSでページにアクセスできるからと言って、そのページが安全かどうかはわからない。HTTPSが保証するのは、そのドメインにアクセスしていることであって、そのサイトの運営者が悪い人なのかどうかは保証しない。（EV証明書では身元まで保証している）

どこまでが保証されていて、どこからが保証されていないのかは把握しておく必要がある。

## 最後に

Web of Trustについて現状学んだことをまとめた。
わからんことだらけだが、知れば知るほど面白くなってきたので引き続き勉強するぞ！


もし、間違っている箇所があれば編集リクエストで教えていただけると助かります :bow:

## Refs

- [Web of trust - Wikipedia](https://en.wikipedia.org/wiki/Web_of_trust)
- [公開鍵基盤 - Wikipedia](https://ja.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%8D%B5%E5%9F%BA%E7%9B%A4)
- [What is not WoT? (In Japanese: WoT とはなんでないか)](https://www.gniibe.org/memo/software/gpg/what-is-not-wot.html)
- [OpenPGP の電子署名は「ユーザーの身元を保証し」ない | text.Baldanders.info](https://text.baldanders.info/openpgp/web-of-trust/)
IonicでGoogle Fontを使う方法

# Google Fontをダウンロード

https://fonts.google.com/noto/specimen/Noto+Sans+JP

今回は「Noto Sans Japanese」を例にしていきます。
普通にGoogle Fontのデータをダウンロード

![スクリーンショット 2022-03-25 9.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/4b1f2f5d-9c87-6538-6662-604d12acb599.png)

おそらく6種類のファイルがダウンロードできたかと思いますが、今回は`NotoSansJP-Regular.otf`しか使いません:ok_woman:

# プロジェクト内に設置
👇のようにIonicのプロジェクト内の設置します。
`projectFolder/src/assets/fonts/Noto_Sans_JP/NotoSansJP-Regular.otf`

# Importして使う
`global.scss`に👇のようなcssを追加

```scss:global.scss
@font-face {
  font-family: 'NotoSansJP';
  src: url('assets/fonts/Noto_Sans_JP/NotoSansJP-Regular.otf');
}

ion-content {
  font-family: 'NotoSansJP';
}
```



# 参考

https://levelup.gitconnected.com/how-to-add-a-new-font-into-your-ionic-app-b7e0871ff5f4
Helmを使うと気になるあれこれ

## tl; dr

私がHelmを使って学んだけどあまり見つからない情報をまとめます。

## はじめに

Helmをこれから使う、などの方は[ほかの記事](https://qiita.com/search?q=helm)をご参照ください。

この記事はv3を前提にしています。

## Releaseについて

:::note warn
ReleaseとはChartをhelmコマンドでインストールしたインスタンスを指しています。helmコマンドなどのアプリケーションを公開することではありません。
:::

### インストールした時に出力された内容をまた見たい

できます。

```text
helm -n <namespace> get notes <release>
```

このほかにも、インストールした時のvaluesの設定値やインストールしたmanifestも見ることができます。

[helm get](https://helm.sh/docs/helm/helm_get/)

### Releaseの情報はどこにある?

ReleaseをインストールしたnamespaceのSecretに格納されています。

dataの中に格納されているのですが、gzip圧縮されているので、直接見るのは結構面倒です。

## Chartに関して

### Chartファイルはリポジトリからどう取得する?

以下のコマンドでtgzファイルとして取得できます。

```text
helm pull <repo>/<chart> --version <version>
```

取得したchartファイルは `helm install` / `helm upgrade` コマンドにおいて `<repo>/<chart>` と書く代わりにchartファイルをパスで指定することができます。オフライン環境にインストールする際などに利用できます。

### values.yamlってどう書いたらいいの?/どんなパラメータが使えるの?

どんなパラメータを受け付けるかはChartの作成者次第なので一概には言えません。

ただ調べ方としては
- ArtifactHubなどの配布サイトの説明をよく読む
    - 開発元のページなどがリンクされている場合はそちらも
- Chartに埋め込みのvalues.yamlを読む
    - 裏技的ですが、Chartに含まれているvalues.yamlを読むとコメントで役割や効果などが書かれている場合もあります。特に、第三者に対して公開されているもの、複数人で開発されているものはコメントが書かれていることが多いです。

## Chart repositoryに関して

### Chart repositoryってどういうものなの?

端的にいうと、以下の条件を満たすWebサーバです

- repositoryにあるChartのメタデータを格納したinde.yamlを公開する
    - repositoryのURLに `/index.yaml` をつけてリクエストすると取得できます。
- Chartファイルであるtgzファイルを公開する
    - index.yamlに格納先URLを記述する

### Chart repositoryをセルフホストするには?

いくつか方法があります。

- GitHub Pagesを使う方法
    - OSSプロジェクトではよく使われる方法です。
    - 詳しいやり方は上の条件を満たせるようにファイルを配置するだけのはずなので書きません。(ググると出てくると思います)
- [ChartMuseum](https://chartmuseum.com/)を使う方法
    - ChartMuseumの[Helm Chart](https://artifacthub.io/packages/helm/chartmuseum/chartmuseum)があります。
    - ホストするRepositoryの操作が[HTTP API](https://chartmuseum.com/docs/#chart-manipulation)で行えます。
    - ChartのストレージとしてPVのほかにS3/GCS/Azure Blob Storageなどのオブジェクトストレージを利用できます。
初心者ブロックチェーンに挑戦する　19

# 最初にひろうのは藁一本でいい

## つぎは蜜柑

　NFT作成サイトの制作も終盤です。私Aが作ったサイトに私Bが訪れて「自分のNFTをつくろう」というボタンを押すと、私Bのウォレットからガス代が落ちて、代わりに私BのウォレットにNFTが届く。一人二役なので、ときどき何をしているのかわからなくなる。挙動を確認するためにやたらボタンを押していると、「あなたの口座には残高が足りません」と言われたりして、あわてておもちゃの銀行におもちゃのお金をもらいにゆく。

　今回できてくるおもちゃのNFTは、ベースの四角に三つのランダムな文字列が出る、というもので、すでにできあがった人たちが、どんな文字列を配列に入れているか見るのもなかなかおもしろい。ラーメンの具と、スープと、価格、なんていうのもあったけど、日本語の文字列にするにはちょっと手間がかかるらしい。無意味なアルファベットの人もいれば、ゲームのキャラと武器とか、ちゃんと主語、動詞、目的語の人もいる。私はベタに、スウィーツのレシピにした。ラズベリー×ミント×アイスみたいな。

　最後にまた出ました、はい、ここからは自分で考えて、オリジナリティーを出しましょう。しかもだ、その例として、ミント待ちの画像を出す･･･って、ほら、これ、前回、私が沼ったヤツじゃん。

　で、今回幸せなことは、この「お待ちくださいメッセージ」を入れて仕上げて、それをGitHubで公開してくれている･･･いや、みんな公開なんだろうけど、見ていいよ、とDiscordに挙げてくれている人がいたので、また、長文読解法で挑戦しました。

- なるほど、そう書くのか。

　と、感心しつつ走らせたら、エラーだ。なんか足らないと言っている。

- ああ、dependenciesになにか足すのか。

　うーん、まだ文句言われる。そうか、flutterでdependeciesになにか書いたら、必ずpub getするけど、ここではどうするんだろう。Discordで聞く。即答。

- npm install ***

　なるほどね、一つ覚えた。
　ちょっと文字のサイズを変えたいな、それは前回やったぞ、どっかにCSSファイルがあるはず。あったあった。

　さて、あとはこれをGitHubに上げて、さらにネットで公開。あれ、その前にまだもう一つ、なんかあるらしいが･･･今日は疲れたので、ここまで。
【佐武の線形代数学】次元定理

p.112 の定理 6, 7, 9 の関係です．

![Satake p112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/f198777a-c649-840a-bb9f-316ee673909b.png)

いわゆる「次元定理」とか「線型代数学の基本定理」といわれています．Strang 先生の本を元に解説した記事もあります．

https://qiita.com/kenjihiranabe/items/eadbcae5402d89660e65?=2

佐武の『線型代数学』についてその他の記事は以下より．

https://qiita.com/kenjihiranabe/items/3a942a5b835617bbc2ad
EC2Windowsでディスク情報からEBSデバイス名を特定する


WindowsインスタンスにEBSをアタッチした後、しばらくして「あれ？このDISKってどのEBSだろう」となる事がある。
同じサイズのEBSを複数追加しているからサイズから特定する事も出来ない。

と、困って、どうすれば良いのか調べたらAWSのドキュメントに書いてあった。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/ec2-windows-volumes.html


いくつか書いてあるが、Windowsのスタートメニューから「コンピュータの管理」-> 「ディスクの管理」と進み、確認したいdiskのプロパティを確認。
![2022-03-25_13h35_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199673/698aabb3-9885-81cb-700e-116064b1459c.png)


表示された画面赤枠部分を確認し、[こちら](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/ec2-windows-volumes.html#ebs-volume-map)の表と突き合わせて特定すれば良いようだ。
この例のDISKは`xvdd`だと特定できる。

![2022-03-25_13h35_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199673/a176f4b5-95ec-69ff-66d0-fd2e1dfdb917.png)
Go言語の「zserge/lorca」で「Microsoft Edgeは自動テスト ソフトウェアによって制御されています」を消したい

## 2023.4.25 追記
Lorca、理由は不明ですかここ数日、強制終了する。
↓Webで検索すると同様な事象がある事が判明。信頼性が一番大事。
https://teratail.com/questions/unqysn0v2vbnl5


# はじめに
go言語の「zserge/lorca」の実行時、Windows上部に以下の記述が出る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/e6b05519-56ff-a4ce-e4b8-6cb4347ccde3.png)
非常にうっとうしい。
PythonのSeleniumでも同一事象が起きていて、ネットで消す方法を検索できるが、Go言語で見つからなので、ソースファイルを探ってみた。
# 結論
「github.com\zserge\lorca」のファイル「ui.go」内の以下の記述の「--」を消せばよい。
- "--no-first-run",　→　"no-first-run",
- "--enable-automation",　→　"enable-automation",


## 「ui.go」の修正箇所
```Go
var defaultChromeArgs = []string{
	"--disable-background-networking",
	"--disable-background-timer-throttling",
	"--disable-backgrounding-occluded-windows",
	"--disable-breakpad",
	"--disable-client-side-phishing-detection",
	"--disable-default-apps",
	"--disable-dev-shm-usage",
	"--disable-infobars",
	"--disable-extensions",
	"--disable-features=site-per-process",
	"--disable-hang-monitor",
	"--disable-ipc-flooding-protection",
	"--disable-popup-blocking",
	"--disable-prompt-on-repost",
	"--disable-renderer-backgrounding",
	"--disable-sync",
	"--disable-translate",
	"--disable-windows10-custom-titlebar",
	"--metrics-recording-only",

	//"--no-first-run",//←こちらは元の記述
	"no-first-run",//←このように「--」を消す

	"--no-default-browser-check",
	"--safebrowsing-disable-auto-update",

	//"--enable-automation",//←こちらは元の記述
	"enable-automation",//←このように「--」を消す
	
	"--password-store=basic",
	"--use-mock-keychain",
}

```

## 注意
- ソースファイルに手を入れるので、気を付けてください。


# 参考
[Github/zserge/lorca](https://github.com/zserge/lorca)
[Github/zserge/lorca/ui.go](https://github.com/zserge/lorca/blob/master/ui.go)
[【Python】Selenium：「Chromeは自動テストソフトウェアによって制御されています」を消す方法](https://office54.net/python/scraping/selenium-chrome-status)

# 参考:Loaca
[Lorcaを使ってGoでHTML5アプリを作ろう！](https://qiita.com/gashirar/items/7ce73c9094b3f777cc9a)
[golangでguiをつくれるライブラリをさがして、hello worldしてみる](https://scrapbox.io/tsuchinaga/golang%E3%81%A7gui%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8C%E3%82%8B%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E3%81%95%E3%81%8C%E3%81%97%E3%81%A6%E3%80%81hello_world%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)
Vue,TypeScriptのリンターおよびフォーマッターを導入する

# リンターの導入

１．ESLint のインストール

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

２．npx eslint --initコマンドで、対話的に ESLint 構成を作成する

```
npx eslint --init
```
コマンドを実行し、ESLint の構成ファイルを作成する。
今回は以下の構成で作業を進めていく。

```
How would you like to use ESLint?はTo check syntax, find problems, and enforce code styleを選択。
What type of modules does your project use?はJavaScript modules (import/export) を選択。
Which framework does your project use?はNone of theseを選択。
Does your project use TypeScript?はYesを選択。
Where does your code run?はBrowserとNodeを選択。
How would you like to define a style for your project?はUse a popular style guideを選択。
Which style guide do you want to follow?はStandardを選択。
What format do you want your config file to be in?はJavaScriptを選択。
Would you like to install them now with npm?はYesを選択し、必要なモジュールをインストール。
```
**.eslintrc.jsが作成されたことを確認する**

# フォーマッターの導入

１．Prettier をインストール

```
npm install --save-dev prettier eslint-config-prettier
```

**バージョン整合性エラーを履く場合は、バージョンを下げるなどして入れ直してください。**
**eslint-config-prettierは、ESLintのフォーマッターを無効化し、リンタのみを有効にするもの**

２．.eslintrc.jsに Prettier の項目を追加する

```javascript:.eslintrc.js
module.exports = {
  /* 中略 */
  extends: [
    /* 中略 */
    "prettier", // 追加。他の設定の上書きを行うために、必ず最後に配置する。
  ],
};
```


# 実行スクリプトを準備する

package.jsonのscriptに実行コマンドを追加する。
以下はsrc配下の.tsと.vueのファイルに対して実行する。

```json:package.json
/* 中略 */
"scripts": {
 /* 中略 */
    "lint": "vue-cli-service lint &&prettier --write \"src/**/*{.ts,.vue}\" "
  },
```

# 実行する

```shell
npm run lint
```

以上
fsでテキストファイルの書き込みをする

## 環境
Ubuntu20.4
node.js v16.14.0

## はじめに
fsモジュールを使って、テキストファイル（CSVファイル）に書き込みする処理のサンプルコードです。fsモジュールはNode.jsに標準で組み込まれています。よって、**npm install fs**や、**yarn add fs**は行う必要はありません。

## 解説

fsを使えるようにするため、最初にfsをrequireで読み込みます。
```
var fs   = require('fs');
```

下記処理で、空のテキストファイルを作成しています。第１引数に書き込み先のファイル名、第２引数に書き込む値を設定しています。書き込む値を空白にすることで、0kbの空ファイルが作成されます。この関数の便利なところは、書き込むファイルが存在していない場合は、新規でファイルを作成し、存在している場合は、ファイルを一旦削除してから、新規ファイルを作成してくれるところです。writeFileSync１行で、ファイルのオープン、書き込み、クローズの３役を一旦に行ってくれます。

書き込みを行う関数には、**writeFileSync**と、**writeFile**の２種類存在します。Syncがつくかつかないかの違いです。Syncがつくと同期型で処理を行い、Syncがつかないと非同期型で処理を行います。どっちで処理をしたいかは好きづきでいいかと思います。ただし、データ件数が大量にある場合は、レスポンスを考えると非同期型にした方がいいです。
```
fs.writeFileSync( file , "" );
```

上記の書き方で、ファイルのオープン、書き込み、クローズを１行で実現できるが、３つの処理を分けて記述する方法もあります。下記の処理は、ファイルのオープンだけを行います。第２引数の**w**は新規書き込みモードでオープンするという意味です。既存のファイルの末行に追加更新する場合は、第２引数に**a**（append）を指定します。今回は空ファイルに書き込みをするため、**a**モードでオープンしても結果的には同じです。

fs.writeFileSync( file , 'ヘッダ情報' );と記述して、先頭行に「ヘッダ情報」を書き込み、２行目から明細行を書き込む場合は、必ず、**a**モードでオープンしないといけません。
```
var fd = fs.openSync( file, "w");
```

下記の処理は、ary配列を文字列に変換して書き込みを行っています。また、配列のカンマ区切りを改行コードに変換しています。第３引数の0は、書き込むときの開始位置です。大抵、0で問題ないはずです。
```
fs.writeSync(fd, ary.join("\n"), 0);
```

下記の処理で、オープンしたファイルのクローズを行います。オープンとクローズは１対１で対応させる必要があります。しかし、ファイルをクローズせず、オープンにしせたままでプログラムを終了させ、再度、同じファイルをオープンした場合、「既に、オープンされています」といったエラーがでるようなことはありません。恐らく、オープンする時に、オープン済であれば、自動でクローズさせるように仕組んでいるのだと推測されます。この辺は堅牢な作りになっているのでしょう。つまり、下記１行をコメントにしてコードを実行しても正常に動作します。
```
fs.closeSync(fd);
```

オープン、書き込み、クローズと３処理を個別に記述する書き方にも、同期型の書き方、非同期型の書き方と２種類あります。同期型は、それぞれ、openSync、writeSync、closeSync、非同期型は、open、write、closeとなります。

## コード
``` node.js
function test_write() {
 
    try {
        var fs   = require('fs');
        var ary  = [];
        var file = __dirname + "/test" + ".txt";

        ary.push("駅名,果物,価格");
        ary.push("米原,バナナ,1000");
        ary.push("彦根,りんご,3000");

        fs.writeFileSync( file , "" );

        var fd = fs.openSync( file, "w");
        fs.writeSync(fd, ary.join("\n"), 0);
        fs.closeSync(fd);

    } catch ( err ){
        console.log(err.name + ': ' + err.message);
        process.exit(-1);
    }
};
```
## 出力結果
テキストファイルの出力結果です。
```text.txt
駅名,果物,価格
米原,バナナ,1000
彦根,りんご,3000
```
Combine(Swift)に関しての特に参考になった知見

### スレッドについて
https://qiita.com/shiz/items/9dc8e9a96f399b6c7246

` .receive(on: DispatchQueue.main)`を用いるとメインスレッドで受けれるので良さそうである。
`.receive(on: RunLoop.main)`は、スクロール中に止まるらしい（Timerがスクロール中に止まるのと同じく）

### UIControlをCombineで購読したい

デフォルトで用意されているものはない。

CombineCocoaを利用すればできる模様。
[UIKitでもCombineしたい！を叶えるCombineCocoaを試してみる](https://dev.classmethod.jp/articles/combinecocoa/)
[もしUIKitでUIを作りCombineで非同期処理を行うなら絶対にCombineCocoaの導入を検討するべきではないだろうか](https://emoshu.co.jp/blog/archives/18)
[CombineCommunity/CombineCocoa](https://github.com/CombineCommunity/CombineCocoa)

自分でPublisher, Subscriptionを作っても良い。

[zafarivaev/UIControl+Combine.swift](https://gist.github.com/zafarivaev/d5864857cd18bc21982a066396368c6a)
[Observe UIButton Events Using Combine in Swift 5](https://betterprogramming.pub/observe-uibutton-events-using-combine-in-swift-5-63c1a4e0a0c1)
[Subscription](https://developer.apple.com/documentation/combine/subscription)
[Publisher](https://developer.apple.com/documentation/combine/publisher)

### RxSwiftとCombineの対応

非常に便利なチートシートがあった。
[RxSwift to Combine Cheatsheet](https://github.com/CombineCommunity/rxswift-to-combine-cheatsheet)

### Timerについて
上記チートシートにも少し書いてあるが、Combineでは以下のように実装する。

- 以下、引用

```swift:Timer.swift
    func startCounting() {
        isTimerRunning = true
        cancellable = Timer.publish(every: 1.0, on: .main, in: .common)
            .autoconnect()
            .sink { _ in
                self.count += 1
            }
    }
```

- 以上、引用　[【Combine】Timerの処理をCombineを使って置き換える](https://www.hfoasi8fje3.work/entry/2021/08/22/【Combine】Timerの処理をCombineを使って置き換える#ContentViewModelswift-1)より

上記を軽く解説すると、[`Timer.publish`は`ConnectablePublisher`（connectメソッドを呼ばれて初めてイベントを発生させる）というもの]()だが、特にそのような機能を利用しないので、`.autoconnect()`を呼んで普通のpublisherのような振る舞いに戻しているようである。


### [setFailureType()]()について

- 以下、引用


```swift:Int+extension.swift
extension Int {
    enum NumberConvertError: Error {
        case convert
    }

    func toAnyPublisher(string: String) -> AnyPublisher<Int, Error> {
        guard let number = Int(string) else {
            return Fail(error: NumberConvertError.convert)
            .eraseToAnyPublisher()
        }
        return Just(number)
            .setFailureType(to: Error.self)
            .eraseToAnyPublisher()
    }
}
```

> PublisherのFailureがNeverの場合のみに使用でき
指定したError Protocolに適合した型を出力するPublisherに変換します。
上記の例ですとJust<Int, Never>からJust<Int, Error>に変換しています

逆にErrorを含むパブリッシャーをErrorを返さないパブリッシャーに変えたい時は、[mapError(_:)](https://developer.apple.com/documentation/combine/publisher/maperror(_:))が使える。

### 自分独自のオペレータを作りたい

extensionを利用して作ることができる。以下は一例。

```swift:Publisher+CustomOperators.swift
import Foundation
import Combine

extension Publisher {
    
    func throttleForTap()  -> AnyPublisher<Output, Failure> {
        return self.throttle(
                for: RunLoop.SchedulerTimeType.Stride(Const.tapThrottleDuration),
                scheduler: RunLoop.main,
                latest: false
            )
        .eraseToAnyPublisher()
    }
}
```

参考: [Custom Operators in Swift Combine](https://bignerdranch.com/blog/custom-operators-in-swift-combine/)
Swagger(yaml)ファイルからHTMLのAPI仕様書の作成方法


# 目次
- 概要
- redoc-cliのインストール
- API仕様書の作成

# 概要
こちらのAPI仕様書作成手順として、redoc-cli コマンドラインを使ってSwagger(yaml)ファイルからHTMLのAPI仕様書作成する手順になります。

#### 手順
1. redoc-cliをインストールする
1. yamlファイルを準備する
1. redoc-cliコマンドを利用し、API仕様書を作成する

# redoc-cliのインストール
`npm install -g redoc-cli`を実行し、redoc-cliをインストールする。

※最低nodeバージョンv12が必要

# API仕様書の作成
yamlファイルを準備して、`redoc-cli bundle inputFile.yaml -o API仕様書.html` を実行し、HTMLのAPI仕様書作成する。
※yamlフィアルの代わりに、jsonファイルからも生成できる。

①yamlファイルを準備する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/e1a37ec8-88ef-46c9-3edb-4e6f5e0a951f.png)

②コマンドを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/ba8660e5-9ae8-fa19-60a9-517c26c6dbce.png)

③API仕様書.htmlファイルが出来上がる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/e7c93ee4-3344-938d-b8b8-da30a8cde209.png)
WSL2(Ubuntu20.04)+venv+pyBulletで深層強化学習のサンプルプログラムを動かす


# WSLとGUIの準備
PowerShellにてWSLのUbuntu20.04をインストールします。


```  bash
# PowerShellにて
$ wsl --list --online
$ wsl --install –d Ubuntu-20.04
```

WSLはCUIのみなのでこのままではGUIが表示されません。
そのためXサーバーを動かすことでGUIを表示します。
VcXsrvの設定については下記をご参考にお願いします。

https://qiita.com/ryoi084/items/0dff11134592d0bb895c

# Python仮想環境
Python関連のパッケージのインストールはシステム全体に影響を与えるかもしれないので私はPythonの仮想環境(venv)を使っています。
```  bash
# WSLにて
$ python3 -V # pythonのバージョン確認
Python 3.8.10
$ sudo apt install python3.8-venv # 3.8用venvのインストール
$ python3 -m venv vTEST # vTESTという名前の仮想環境を作成
$ source ./vTEST/bin/activate # 仮想環境vTESTを実行
(vTEST) PCname:~$
```

上記のように(vTEST)とカッコ付きで仮想環境名が表示されれば成功です。
ちなみに仮想環境の停止・削除はそれぞれ次のコマンドで行います。
``` bash
# WSLにて
(vTEST) PCname:~$ deactivate # 実行中の仮想環境の停止
$ rm -rf vTEST # 仮想環境vTESTの削除(停止中のみ可能)
```

# pyBulletのインストールとサンプル実行

DISPLAYの環境設定を忘れずに
``` bash
# WSLにて
(vTEST) PCname:~$ export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
``` 

pBulletとnumpyをインストールします。
``` bash
# WSLにて
(vTEST) PCname:~$ pip3 install pybullet
(vTEST) PCname:~$ pip3 install numpy
``` 


``` bash
# WSLにて 
(vTEST) PCname:~$ git clone --depth 1 https://github.com/bulletphysics/bullet3
(vTEST) PCname:~$ cd bullet3/examples/pybullet/examples/
(vTEST) PCname:~bullet3/examples/pybullet/examples$ python3 humanoid_manual_control.py
``` 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159523/5a75a441-41b4-3dc3-73d8-cc13e4fe3a1d.png" width=70%>

# 深層強化学習のサンプル実行
Tensorflowに必要なパッケージをインストールしておきます。
``` bash
# WSLにて 
(vTEST) PCname:~$ pip3 install wheel
(vTEST) PCname:~$ pip3 install tornado
``` 

深層強化学習に必要なTensorflowと強化学習用ライブラリTF-Agentsをインストールします。
``` bash
# WSLにて 
(vTEST) PCname:~$ pip3 install tensorflow
(vTEST) PCname:~$ pip3 install tf_agents
``` 

サンプルを動かしてみましょう。人が動き回れば成功です。
``` bash
# WSLにて 
(vTEST) PCname:~$ python -m pybullet_envs.examples.enjoy_TF_HumanoidFlagrunHarderBulletEnv_v1_2017jul
``` 


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159523/b3d3eb40-9ca0-3de1-6107-566e882d5b2d.png" width=70%>



# 参考ページ
・WSL2のGUI設定でつまずいたところ
https://qiita.com/baibai25/items/5841b0592727893d960f
・深層強化学習のための物理シミュレーション環境構築（PyBullet)
https://zenn.dev/karaage0703/articles/e01c2abc88373c
プログラミングスクールに通っての実況や感想。

短いですがお許しを。
プログラミングスクールに通って思ったことなどをお話します。

# やっていること
PHPとLaravelを使ってコピーアプリの作成。（初めて2か月足らずなので）
使っているツールはAWSのCloud９。課題の提出はgitを使用。
# 始めて思ったこと
カリキュラム通りにやれば、出来なくないが、オリジナルを作る時には苦労しそう。
PHPは勉強してたからある程度は分かっていたが、Laravelは初めてだったので、大変。

# 通っているプログラミングスクールについて
スクールはTechboostというスクール。契約期間は半年。当初は副業やフリーランス目的で始めたが、転職でもいい。
3か月でコピーアプリの作成や課題を終わらせ、残り半年でオリジナルアプリ作成～副業サポートまでと考えている。

# これから
先は長いが、楽しんでやっていければと思っています。
AWSの分散負荷テストソリューションで突然異常になる

# 事象
AWSの分散負荷テストソリューションで、さっきまで正常に終了していたシナリオが突然異常終了（Failed）するようになりました。
シナリオはJMeterシナリオファイルを使用。
TaskやConcurrency等のパラメータを変更しても結果は変わらず。
# 解決方法
JMeterのシナリオファイルを再アップロードしたら正常終了するようになりました。
原因は不明です。。。
Provisioning profile "" doesn't include signing certificate '内容'が発生

# Provisioning profile "" doesn't include signing certificate '内容'が発生
`Flutter build ipa`の時に発生

# 解決策
.Cettificateの'内容'
・Provisioning file（AutoではなくManualの場合）の'内容'
・XcodeのTARGETSのRunner→Build Settings→Signingの'内容'

を全て一致させる。（僕の場合の'内容'は'Apple Distribution'でした！！）
WordPressブログを開設する方法

WordPressブログの始め方｜誰でも簡単にWordPressブログを作る方法
»https://sora-iro-blog.com/wordpress-start

無料ブログとWordPressのメリット・デメリットについて、簡単に紹介しますね。
無料ブログサービスは主に「はてなブログ、アメブロ」など指しております。
初期設定が簡単ですが、運営会社が倒産してしまうとブログ自体が無くなってしまう可能性があります。

エックスサーバーで2つ目のWordPressブログを作成する方法【お名前.comでドメイン取得】
»https://sora-iro-blog.com/multiple-wordpress-install
'Flutter/Flutter.h' file not found flutter/.pub-cache/hosted/pub.dartlang.org/url_lau ncher_ios-6.0.15/ios/Classes/FLTURLLauncherPlugin.h:4:8が発生

# 'Flutter/Flutter.h' file not found flutter/.pub-cache/hosted/pub.dartlang.org/url_lau ncher_ios-6.0.15/ios/Classes/FLTURLLauncherPlugin.h:4:8が発生
`Flutter build ipa`
でこのエラーが発生しました。
原因はPodfileにありました

## ダメな方のPodfileのpost_install
```
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
    end
  end
end
```

## いい方のPodfileのpost_install
```
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
  end
end
```
Xcodeでチェリーピックしてみた

#Git苦手意識との向き合い

別ブランチの全てのコミットを反映させたいときはマージにすればいいけど、いくつかかいつまんで反映させたい時に、チェリーピックを活用してみた。

#複数コミット適応可否について
Xcodeの機能としては、なさそう。
あればなおよかったが、ひとつずつチェリーピックしてまとめてプッシュでも困らないとも思った。

#感想

よかったと思う。



#今後の目標
コミットの取り消しについて理解を深めたい。
コルーチンの中でコルーチンを待つ

コルーチンの中でコルーチンを待つ場合、今まで
 
```
yield return StartCoroutine(otherCoroutine(var));
```
とやっていたのですが、
```
yield return otherCoroutine(var);
```
でも大丈夫みたいです。知りませんでした！
Flutter build ipaで Module '' not foundが出る

# Flutter build ipaで Module '' not foundが出る
```Podfile.js
# Uncomment this line to define a global platform for your project
platform :ios, '11.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
    end
  end
end
```
# 結論
PodfileとXcodeのtarget iOSバージョンが一致していなかったのが原因
# 解決策
Xcode → Project(targetじゃない方のRunner) → info → Deployment target → 11.0に補正
pg_dumpでバージョン不一致となったら、dockerでpg_dumpするッピ

pg_dumpでバージョンミスマッチが出たら
aborting because of server version mismatch


dockerする、便利になった
```
docker run -it -v "$PWD":/usr/src -w /usr/src --rm postgres:13 bash
$ pg_dump .....
```
環境構築について(django+MySQL on docker-compose)


## はじめに
今回は、私がよく使用するdjango+MySQLの環境構築について紹介します

## 想定環境
Dockerとdocker-composeがインストールされているとします。
## 環境構築までの流れ
環境構築までの流れは以下のようになっています。この3ステップを踏めば環境構築することができます。

・ファイル準備
・プロジェクトの作成
・サービスの起動

### ファイル準備
用意するファイルは以下の三つになります。一つのディレクトリに入れておきます。
``` Dockerfile:Dockerfile
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install --upgrade pip && pip install -r requirements.txt
COPY . /code/
```

``` docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: django-db
      MYSQL_USER: django
      MYSQL_PASSWORD: django
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
  web:
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
```

``` requirement.txt
Django==3.1   # Django3.1
mysqlclient   # pythonでMySQLに接続するためのドライバ
sqlalchemy
```
### プロジェクトの作成
作成したファイルがおいてあるディレクトリに移動し、ターミナル上で以下のコマンドを実行する
``` Docker:
docker-compose run web django-admin.py startproject djangopj .
```

- プロジェクトが開始されたことを確認したら、djangopj/settings.pyを開き、DATABASESの項目を編集します。
→　djangoプロジェクトの作成をした際、settings.pyにはsqliteの設定がデフォルトでされている為です。

```setting.py 
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django-db',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': 'db',
        'PORT': '3306'
    }
}
```

### サービスの起動
docker-compose.ymlが置いてあるディレクトリで、以下のコマンドを実行
```Docker
docker-compose up
```

- [http://localhost:8000/](http://localhost:8000/) にアクセスしてDjangoのトップページが表示されたらOK
サブディレクトリを再帰的にスキャンして、日付順にソートするプログラム

---
## はじめに

![free164b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/c98ebe2a-6da3-0521-856b-54cdf16c3613.png)

ファイルサーバで複数人がファイルを投稿しているような中小企業ってあると思うんだけど、有益なフォルダ分けがされていたりするのは当然として、そうなると、

**更新日が一番新しいのはどれだろう?**

とか

**最近更新された資料はどれだろう?**

とかの検索は面倒かも知れない。

というので、sDirというツールを作ってみた。

---
## インストールと使い方

「[サブディレクトリを再帰的にスキャンして、日付順(作成日時/更新日時/アクセス日時)に表示するCLIまたはWPFなプログラム](http://rocketeer.dip.jp/sanaki/free/free164.htm)」からダウンロードして、zip解凍するだけ。

コマンドライン版の「sDirDateSort.exe」と、GUI/WPFの「sDirDateSortWPF.exe」が、実行ファイル。

GUI版だとこんな感じで、**xx月xx日のxx時あたりより最近更新されたファイルはどれかなぁ～**、とか **あっ、◆◆提案書が更新されてる**、とか見つけることができる。

![free164c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/41a1cece-9cd3-77f2-de62-9a3832616f90.png)

コマンドライン版は、こんな感じ

```
C:\>sDirDateSort.exe
sDirDateSort.exe ver 1.0.0.0
                            created by active@window.goukaku.com

sDirDateSort.exe DirPath [options]

      Compiled ver.v4.0.30319
           Run ver.v4.0.30319(Win32)
-----------------------------------------
     -A : AccessTime   ( ASC)
     -a : AccessTime   (DESC)
     -C : CreationTime ( ASC)
     -c : CreationTime (DESC)
     -M : ModifiedTime ( ASC)
     -m : ModifiedTime (DESC) (Default)
     -d : DebugMode
```

GUI版にも、コマンドライン版の引数はそのまま使えるようになっています。

---
## 以上
【カスタムテーブル】カスタムテーブルを定義してみる

時に客先でデータベースビューが必要になるケースがありますが、お客様のデータベースへのビューの追加がどうも...といった場合があります。そのような場合が、[Sharperlight](https://sharperlight.jp/)**カスタムテーブル**の出番です。”仮想的”あるいは”ソフト的”なテーブル(ビュー)とでもいうのでしょうか、お客様のデータベース環境に手を加えることなく業務に必要なビューを準備することができます。
## 前準備
**カスタムテーブル**を作成する前にビューの元となるSELECT SQL文を準備しましょう。**カスタムテーブル**はSELECT文でのみ作成するわけではないのですが、ここではSELECT文での作成を紹介します。
```
SELECT s.Id, s.売上日, s.Invoice#, p.製品名, r.区名, s.数量
FROM [dbo].[Sales] s
LEFT OUTER JOIN [dbo].[Products] p ON p.Id = s.製品Id
LEFT OUTER JOIN [dbo].[Regions] r ON r.Id = s.区Id
```
準備ができたら早速**カスタムテーブル**を作成してみます。
## カスタムテーブルの作成
[Sharperlight](https://sharperlight.jp/)アプリケーションメニューから**カスタムテーブル**を起動します。
![Qiita Common - Menu Custom Table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/15fc1641-7bbf-d1ca-e7bb-23befc13b3e7.png)
右クリックメニューから**新規**を選択します。
![2022-03-25 Figure 01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b4a6c16a-76ed-5f72-a36d-3e61e0a156f5.png)
[OK]をクリックし先に進みます。
![2022-03-25 Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0d9d0e84-45cf-28db-d10e-3432ab80adbe.png)
**製品**を選びます。
**製品**は**クライアントのセットアップ**でデータベースと結びつけられているので、ここではどのデータベースに対してカスタムテーブルを作成するかを念頭に**製品**を選びます。
この記事では準備したSELECT SQL文が**Qiita Demo Product**に結び付けられているデータベースのテーブルを使用しているので、この**製品**を選びます。  
![2022-03-25 Figure 03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e8a60020-e8fb-8ed1-8d7f-71f18aa78736.png)
[Yes]はいをクリックして先に進みます。
![2022-03-25 Figure 04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e1e1c2aa-2d43-5775-55af-e6877d63d762.png)
準備したSQL文を貼り付け、[OK]をクリックします。
![2022-03-25 Figure 05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/7fe07c81-1366-158c-44a4-82a2512fd3d2.png)
[一般]タブでは、**コード**と**タイトル**を入力します。**コード**は、内部的にこのカスタムテーブルを識別する一意のコードになるので、簡潔で判別しやすいものにします。
![2022-03-25 Figure 06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/883d4e9a-d848-ce62-0705-57ff61cb2e2c.png)
[テーブルの詳細]タブでは、テーブルの属性(Attributes)を確認します。コード(Code)には、[一般]タブで入力したコードが設定されています。摘要(Description)は、クエリビルダ等でテーブル一覧に表示される場合の名称です。判別しやすいものにします。テーブル名(Table Name)には、先に貼り付けたSQL文が確認できます。
[OK]を押して保存します
![2022-03-25 Figure 07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e5d75cf6-3b34-6448-fc43-9d4cf49a6b96.png)
![2022-03-25 Figure 08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b00484ef-9989-a528-1c78-16b520f9e086.png)
## カスタムテーブルの使用
**クエリビルダ**を起動します。[製品]に**Qiita Demo Product**を選択します。テーブル参照では作成したカスタムテーブルが表示されていることを確認します。
![2022-03-25 Figure 09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/bd920265-7b8c-ee43-5f49-1139e77316f9.png)
ではそのカスタムテーブルを選択し、全てのフィールドを[出力]領域に設定し、[プレビュー]ボタンでデータを確認します。正常にデータが表示されたなら、カスタムテーブルの作成はこれで完了です。
![2022-03-25 Figure 10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e31a8dad-bf98-bd68-d5f7-7c159c7aea5c.png)
:postbox:[Sharperlight](https://sharperlight.jp/)
自作のLINEbotにFlexMessageを実装したら使いやすくなった話


# はじめに
以前、毎日エンジニアニュースというLINEbotを作成しました。

その時の記事はこちら

https://qiita.com/menasuba/items/ba66a8b0fa2f40345ee5

追加してもらえるとと嬉しいです。
![スクリーンショット 2022-03-16 17.51.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2305872/538b4f75-d847-88d3-01e5-f417846b1726.png)

# FlexMessageを実装するまで
FlexMessageを実装する前のメッセージはこちらになります
![スクリーンショット 2022-03-16 17.20.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2305872/386472be-8ff6-4476-a8c3-523c4455033c.png)

このメッセージのよくない点は、「見にくい」のと「記事のタイトルとurlが離れているため見たいなと思った記事はどれだっけなあと確認する必要がある」の二つだと思います。
本当は作る過程でFlexMessageを実装したかったのですが、実装できない理由がありました。
　
# なぜFlexMessageを実装できなかったのか
### 原因
なぜ実装できなかったのかというと配列での渡し方がわからなかったからです。
こちらがそのコードになります。


```CreateMessage.ts
import { SetItem } from "./types/SetItemType";

export const FetchMessage = async (data: SetItem): Promise<any> => {
  try {
    let titleMessage = "";
    let urlMessage = "";
    let numberList = 1;
    data.setTitle.forEach((res) => {
      const addTitleMessage = res;
      if (titleMessage === "") {
        titleMessage = `[${numberList}]${addTitleMessage}`;
        numberList++;
      } else {
        titleMessage += `\n\n[${numberList}]${addTitleMessage}`;
        numberList++;
      }
    });
    numberList = 1;
    data.setUrl.forEach((res) => {
      const addUrlMessage = res;
      if (urlMessage === "") {
        urlMessage = `[${numberList}]${addUrlMessage}`;
        numberList++;
      } else {
        urlMessage += `\n\n[${numberList}]${addUrlMessage}`;
        numberList++;
      }
    });
    const message = titleMessage + "\n\n" + urlMessage;
    return message;
  } catch (err: unknown) {
    console.log(err);
  }
};
```
このコードは取得した記事をtitleMessage,urlMessageに格納している処理になります。
配列の渡し方がわからなかったので変数に文字列を格納しまくって一つのなが〜い文字列にし、それを出力していました。

### 解決

ですが、こちらの記事で実装法を知りました。
本当に感謝です！![


https://qiita.com/Ryo9597/items/4cd1908e5bd41467cd52

#  実装　
この様な感じでデザインしてみました!
上 QiitaAPI 下 NewsAPI
![スクリーンショット 2022-03-25 9.55.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2305872/7f5b2d72-f4ab-34e0-034b-ce20f60bfeec.png)

見比べるとだいぶ改善されていると思います。
QiitaはできるだけQiitaの記事っぽくなるようにデザインしてみました。

# つまずいたところ

NewsAPIの記事を表示する際に画像が表示されていない箇所がいくつかありました。
### 原因
公式ドキュメントによるとpngとjpgの二つが対応しているとのこと。
表示されていないところを確認してみるとsvgであることがわかりました。

### 解決
svg形式の場合はunsplashの画像を出力するようにしました。

```NewsArticleMessage.ts
 let urlImage = val.urlToImage;
    const fileExtension = urlImage.split(".").pop();

    if (fileExtension === "svg") {
      urlImage = "https://source.unsplash.com/featured/?programming";
    }
}
```

# まとめ
今回はFlexMessageを実装してみました。
時間はかかったんですがデザインするのがとても面白く没頭していましたw
まだまだ改善点があるのでこれからもアップデートしていき、使いやすいbotにしていきます!!

最後までご覧いただきありがとうございました!!!

[GitHub] 

https://github.com/suba327777/LINE-Engineer-News

# 参考

https://qiita.com/menasuba/items/ba66a8b0fa2f40345ee5

https://qiita.com/Ryo9597/items/4cd1908e5bd41467cd52

https://developers.line.biz/ja/docs/messaging-api/flex-message-layout/#baseline-box

https://1-notes.com/javascript-get-the-extension-from-the-file-name/
【Unity】ショートカット備忘録

# はじめに
人間の苛立ちあるところにショートカットあり。ちゃんと[マニュアル](https://docs.unity3d.com/ja/2019.4/Manual/)を読みましょう。
以下の内容は2019.1から実装された[ショートカットマネージャー](https://docs.unity3d.com/ja/2019.4/Manual/ShortcutsManager.html)を通してUnity内から確認可能です。

## 環境
Windows 10 Pro 20H2 (19042.1526)
Unity 2019.4.31f1
## ショートカット（抜粋）
全てのショートカットを確認したい場合は、Unityプロジェクト内の[ショートカットマネージャー](https://docs.unity3d.com/ja/2019.4/Manual/ShortcutsManager.html)をご覧ください。
Mac環境の場合は”Ctrl”を”⌘”、”Alt”を”Option”に読み替えてください。

### HierarchyWindow/GameObject
|  キー| 動作| 条件 |
|:-:|:-:|:-:|
|  H |  オブジェクトを表示/非表示 |   |
| Ctrl + Shift + A | コンポーネントを追加 |   |
| Alt + Shift + A | オブジェクトをアクティブ/非アクティブ |   |
| Alt + 左クリック  |  下階層のツリーをすべて開く/閉じる | ツリーを示す三角マークをクリックする |


### AnimationWindow
|  キー| 動作|
|:-:|:-:|
| F | 選択キーを表示最適化 |
| A |  全フレームを表示 |
| C |  カーブ/ドープシート切り替え |
| . | 次のフレームへ移動 |
| , |  前のフレームへ移動 |
| Alt + . | 次のキーフレームへ移動 |
| Alt + , | 前のキーフレームへ移動 |

### SceneWindow
|  キー| 動作|
|:-:|:-:|
| Alt + 右クリックドラッグ | 拡大縮小 |

### ProjectWindow
|  キー| 動作| 条件 |
|:-:|:-:|:-:|
| Alt + 左クリック  |  下階層のツリーをすべて開く/閉じる | ツリーを示す三角マークをクリックする |
| Ctr + Alt + C | アセットのパスをコピー |  |

### Window呼び出し
あまりに非直感的な割当
|  キー| 呼び出されるWindow |
|:-:|:-:|
| Ctrl + 1 | Scene |
| Ctrl + 2 | Game |
| Ctrl + 3 | Inspector |
| Ctrl + 4 | Hierarchy |
| Ctrl + 5 | Project |
| Ctrl + 6 | Animation |
| Ctrl + Shift + C | Console |


## ちなみに
以上のショートカットは全てカスタム可能です。~~Unityプロジェクト内の[ショートカットマネージャー](https://docs.unity3d.com/ja/2019.4/Manual/ShortcutsManager.html)をご覧ください。~~

# 終わりに
前々からUnityの操作に苛立ちを覚えていながらも、古い公式の[ホットキー解説](https://docs.unity3d.com/ja/2018.4/Manual/UnityHotkeys.html)くらいしか目を通さなかった怠惰を反省しています。
現在主に使用しているUnityのバージョンマニュアルを見るとショートカットマネージャーが紹介されていたので確認したところ、大変便利な代物だったので個人的に便利だけど忘れがちな部分を抜粋した記事にしました。
VLCでフォルダ内動画をコマンドラインで全画面ランダム再生

# やりたいこと
まあ、例えばPVとか、CMとか。
フォルダに突っ込んであるものを。
コマンド一発でランダム再生してくれるのが欲しいなって。
で、まあVLCのコマンドラインオプションで実現出来たので、メモ。

# 完成形
こんなかんじになりました。
```
"C:\Program Files\VideoLAN\VLC\vlc.exe" --fullscreen --no-osd  --no-qt-fs-controller --qt-fs-sensitivity=0 --mmdevice-volume=1.00 --playlist-autostart --random --loop --playlist-tree c:\videodata\
```
Windows系で書いてますけれども、まあLinux系でもオプションは流用可能かと。

# 解説
各オプションは、こんな感じです。

|オプション記述  |意味  |
|---|---|
|--fullscreen  |全画面で起動  |
|--no-osd  |OSDを非表示  |
|--no-qt-fs-controller  |全画面用コントローラー非表示  |
|--qt-fs-sensitivity=0  |マウスカーソル表示時間を「０」  |
|--mmdevice-volume=1.00  |音量を「１（１００％）」  |
|--playlist-autostart  |プレイリストを自動再生  |
|--random  |プレイリストをランダム再生  |
|--loop  |プレイリストをループ  |
|--playlist-tree [dir]  |ディレクトリ内ファイルをプレイリスト化  |

# ま、これで
余ったPCだのラズパイだのを、電源入れたら再生する系の動画プレイヤーとして使えるかもね！。

以上です。
Rails のscaffold



駆け出しエンジニアのTakaです。
本日からQittaを書くことにしました。
よろしくお願いします。
本日のテーマは、scafoldです

アプリを作るためには、viewやcontroller,routesなど様々な機能が必要になってきます。
1,scaffoldはこれらの作業をまとめて行って、簡単にアプリケーションの雛形を作ってくれます。

```
rails generate scaffold post title:string body:text
```
Postモデルは名前を表し、「title」属性と、「body」属性を持つアプリが作成される。


2,必ず、データベースとやりとりできるマイグレーションファイルの作成もしておきましょう。
```
rails db:migrate
rails server
```

3,その後にlocalhost:3000に入ることでアクセスすることができる。

![MVC.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358181/75347f32-edac-2f47-1411-660e3791b99d.jpeg)

また以下の図を参考にする。
（絵になってしまい申し訳ございません。）
１、ユーザからのリクエストはルーテイングに送られて、指定されたコントローラに割り当てられる。
２、ルーテイング機能がリクエストの処理を行うべき、コントローラとアクションを決定する。
３、アクションで、必要に応じてモデルにアクセスさせる。
４、モデルはデータベースの書き込みと読み出しのどちらも行う。
５、モデルから再びコントローラにデータが送られる。
６、コントローラーからビューに必要なデータを送る。
７、ビューがユーザのブラウザに返される。
#include <source_location> failed

`__FILE__`などを今風に扱えるライブラリがあると知り利用しようと試みましたが2022/03/25現在ではまだmacでは利用できませんでした。

https://cpprefjp.github.io/reference/source_location/source_location/current.html

## やったこと

```c++
#include <source_location>
#include <iostream>

using namespace std;
int main()
{
    const source_location loc = source_location::current();
    cout << loc.line() << endl;
    cout << loc.column() << endl;
    cout << loc.file_name() << endl;
    cout << loc.function_name() << endl;

    cout << __FILE__ << endl;
    return 0;
}
```

```zsh
[9:21:03: build]$ g++ -o loc loc.cpp -std=gnu++2a
loc.cpp:1:10: fatal error: 'source_location' file not found
#include <source_location>
         ^~~~~~~~~~~~~~~~~
1 error generated.
[9:21:56: build]$ g++ --version
Apple clang version 13.1.6 (clang-1316.0.21.2)
Target: arm64-apple-darwin21.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
[9:21:03: build]$ 

```

## 環境

![スクリーンショット 2022-03-25 9.56.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38013/4afb0e85-90b4-aeb4-6376-f4af82ca2542.png)
【Shopify】セクションの仕組み(onlinestore 2.0)

shopifyで自分でセクションを追加したり、編集したいと思ったことはありませんか？
それについて公式ドキュメントを読みながら色々試行錯誤したことを記録しておきます。

:::note warn
自分用のメモなので、書き方はめちゃくちゃです、すいません。とりあえず共有しておけば助かる人が一人でもいるんじゃないかと思って投稿しています。ご了承ください。
:::

***

例えば、collectionページを作る
Templateフォルダ内のcollection.jsonで
- どんな要素（section）があるのか
- どんな順番で並んでいるのか
を決定

Sectionについて
https://shopify.dev/themes/architecture/sections

sectionの定義の仕方
```json
{
  "sections": {
      "template": {
        "type": "template-collection",
        "settings": {
        }
      }
  },
  "order":[]
}
```
ここではtemplate-collectionをもとにして、このsectionが形成される
template-collectionの説明は後述

sectionの必須項目として、sectionsとorderの2種類がある。
Sections内の記述例は以下のようになる
```json
{
  "name": "Default product template",
  "sections": {
    "main": {
      "type": "product",
      "settings": {
        "show_vendor": true
      }
    },
    "recommendations": {
      "type": "product-recommendations"
    }
  },
  "order": [
    "main",
    "recommendations"
  ]
}
```
とりあえず
sectionのID：上で「main」「recommendations」とか書いてるやつ
type：どのliquidファイルをもとにそのsectionを描画するのか
だけ覚えとけばOK

:::note info
sectionの構成要素についての公式ドキュメント
https://shopify.dev/themes/architecture/templates/json-templates#section-data
:::



そして、template-collection.liquid内でschemaが設定できる
これはshopifyのカスタマイズ画面から、ユーザーが自由に入力できるもの

schemaの記述方法
```liquid
{% schema %}
{
    "name": "Template Collection",
    "settings":[
        {
            "type":"number",
            "id": "number_of_products_per_page"
                }
    ]
}
{% endschema %}
```
Nameはタイトル
Typeは、どんな感じで入力するのかを決める
- Checkbox
- Number
- Radio
- Range
- Select
- Text
- Textarea
の7種類がある

:::note info
schemaについての公式ドキュメント
https://shopify.dev/themes/architecture/templates/json-templates#section-data
:::

https://shopify.dev/themes/architecture/settings/input-settings#basic-input-settings


Idは、schemaを記述したliquid内でその値を呼び出すときの名前
例えば、liquid内で、template Collectionで決めた値にアクセスしたければ、
section.settings.number_of_products_per_pageと記述する

labelは入力する際の説明。そんな重要じゃない。
React の hooks をどこで呼び出すか？

# Reactを使っていて hooks に関する以下のエラーに遭遇

```
React Hook "useResult" is called in function "onClickEnd" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use"
```
自分のアプリを実行して最近よく見かけるんだが、hooks の使い方がまずいってことなのかと。
初心者過ぎてよくわからないので、やってはいけないことを調べて修正したい。

## どういうことなんだろう？
https://qiita.com/tatsumin0206/items/4e1076e2deedf20a9485
によると
`
（前略）
なぜなら、printメソッドを実行することで、使用されるフックの数が変わってしまうからです。
フックを使用する場合は、コンポーネントを読み込んだ時点でどのフックが使われるかを明示しなければいけないので、printメソッドを実行して途中でフックの数が変わるといった挙動をしてしまうとエラーになってしまいます。
（後略）
`
フックの数が途中で変わるから、というのがなんとなくの理由であることがわかった。
ここでいうフックって何？
```
  const [value, setValue] = useState(0)
```
この部分のことのようだ。つまりuseStateなんかのhook関係の定義を呼ぶときに、componentのroot （たぶん関数定義に入る前のセクション）でやらないといけないのかなという理解。

## やってみたこと
自分の定義した関数はカスタムフック useCycleResult というものの中で定義した useResult という関数だった。
### 関数の名前が良くないの？
- useResult -> pushResult 
と名称を変更してみた。
今度はReactの関数は大文字から始まらないといけないよ、というエラーが出た
- pushResult -> PushResult
として再実行してエラーがでなくなった。

# 結局エラーが出るようになった
実行事前のチェックのエラーがでなくなっただけで根本的な問題解決ができていなかった模様。
```
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
```
### また use に戻す
https://qiita.com/tatsumin0206/items/4e1076e2deedf20a9485
の「その２」の部分に該当するのが hooks を呼び出している関数名には 'use' で始まる名前をつける必要があるとある
今の自分のコードの構成は
- カスタムフック(useCycleResult)の中でuseResultという関数を定義して
- 外部の関数のonClickButtonみたいな関数の中から useResult を呼ぶ　というもの

この書き方は結構やっている。エラーメッセージをよく読むと "onClickEnd" という関数の名前を変えたら良い？と思ったのでやってみた。

### onClickEnd -> useClickEnd 
と関数名を変更したらうまく走った。
しばらくはそういうことと思ってやってみよう。
Tailwind CSS IntelliSense が動かない

Visual Studio Code の拡張機能の Tailwind CSS IntelliSense が特定の HTML ファイルで動作しなかったときの解決メモです。

### 環境

- Visual Studio Code | バージョン: 1.65.2
- Tailwind CSS IntelliSense | バージョン: v0.7.7

### ディレクトリ構成

```
.
├── dist
│   └── output.css
├── src
│   ├── a.html
│   ├── b.html
│   └── input.css
└── tailwind.config.js
```

### 症状

上記ディレクトリ構成で、 a.html では Tailwind CSS IntelliSense の suggestions が表示されるのですが、b.html では表示されない。（a.html と b.html は同じ内容）

### 解決のため、試したこと

- b.html のファイル名を変える 🙅
- a.html を b.html にリネーム 🙅
- Tailwind CSS IntelliSense の再インストール 🙅
- Visual Studio Code の再起動 🙅
- Mac の再起動 🙅

### 解決方法

ルートディレクトリをリネームしたら解決しました 🙆
特定文字で分割して列作成

| email |
|:-|
| aaa＠xxx.com |
| bbb＠yyy.co.jp |
| ccc＠zzz.ne.jp |

上のようなデータフレームから、下のようなデータフレームを作りたい

| email | user | domain |
|:-|:-|:-|
|aaa＠xxx.com | aaa | xxx.com |
|bbb＠yyy.co.jp | bbb | yyy.co.jp |
|ccc＠zzz.ne.jp | ccc | zzz.ne.jp |

# 1. 特定文字列で分割
```python
temp = df["email"].str.split("＠")
print(temp)
# 0      [aaa, xxx.com]
# 1    [bbb, yyy.co.jp]
# 2    [ccc, zzz.ne.jp]
# Name: email, dtype: object
```

# 2. 分割結果をデータフレームに拡張
```python
temp = df["email"].str.split("＠", expand=True)
print(temp)
#      0          1
# 0  aaa    xxx.com
# 1  bbb  yyy.co.jp
# 2  ccc  zzz.ne.jp
```

# 3. 列名設定
```python
temp = df["email"].str.split("＠", expand=True).set_axis(["user", "domain"], axis=1)
print(temp)
#   user     domain
# 0  aaa    xxx.com
# 1  bbb  yyy.co.jp
# 2  ccc  zzz.ne.jp
```

# 4. 元のデータフレームに結合
```python
result = pd.concat([df, df["email"].str.split("＠", expand=True).set_axis(["user", "domain"], axis=1)], axis=1)
print(result)
#             email user     domain
# 0    aaa＠xxx.com  aaa    xxx.com
# 1  bbb＠yyy.co.jp  bbb  yyy.co.jp
# 2  ccc＠zzz.ne.jp  ccc  zzz.ne.jp
```
firestoreを使って採番ルールを実装しよう

### はじめに

firebaseでアプリを開発しており、ドキュメントに対して採番ルールを設け、新たなドキュメントが作成されるたびに、1ずつ追加され、新たな番号が付与されるというのをcloud funtionsで実装する必要がありました。

### 最初の実装

主にここはチームメンバーが実装してくれたのですが、いろいろな技術記事を探すと、
- firestoreに採番用のドキュメントを1つ用意
- そのドキュメントを全件取得し、Math.max()で最大値を取得
- 最大値に＋1をして、新たなドキュメントを作る

という方法が紹介されており、この方法で実装しました。

我々のチームで実装したコードは以下のような形でした。

```react
let existsTodoNumber;
const todoNumberList = await firestore.collection("TodoNumbers").get();

const todoNumberData = todoNumberList.docs.map((doc) => {
  const replaceTodoNumber = doc.data().todoNumber.replace("ABC", "");
  return { todoNumber: replaceTodoNumber };
});

if (todoNumberData.length === 0) {
  existsTodoNumber = 0;
} else {
  //todoNumberDataから一番大きい数値を取得
  const maxTodoNumber = Math.max(...todoNumberData.map((d) => d.todoNumber));
  existsTodoNumber = maxShipmentNumber;
}

const newTodoNumber = existsTodoNumber + 1;
const convertTodoNumber = "ABC" + String(newTodoNumber);

```

### 問題点
先輩エンジニアにレビューを頂いたところ、以下のような指摘をもらいました。

- この実装だと、todoNumberが増えれば増えるほど、最大値を取得するときの、ドキュメント取得サイズが線形的に増えていく(N+1)
- readのコストも、functionsのメモリもサービスの成長に連れて大量消費していく実装になる。
- 単純な連番の数字を保存するためのfieldを用意すれば、クエリ1回で最大値の取得が可能。



### 実際にリファクタリングしたコード

指摘事項を踏まえ、以下のように修正しました。

```react
let existsTodoNumber;
const existsTodoNumberData = await firestore
  .collection("TodoNumbers")
  .orderBy("value", "desc")
  .limit(1)
  .get();

if (existsTodoNumberData.empty) {
  existsTodoNumber = 0;
} else {
  existsTodoNumber = existNumberData.docs[0].data().number;
}
const newNumber = existsTodoNumber + 1;
const convertTodoNumber = "ABC" + String(newNumber);
```


### 所感

やっていることは同じでも、パフォーマンスを考慮すると書き方が変わって非常に勉強になりました。
またこのコペルニクス的転換はプログラミングの極みであると感じ、最高におもしろいと思いました。

メインでの実装は私ではなく、チームメンバーであり、私は頂いたアドバイスをもとに、リファクタリングしただけなので、記事での発信をためらいましたが、
firestoreの採番をクエリを使った実装例の記事がなさそうだったので、記事を書くことに決めました。

同じような採番実装でお悩みの方に少しでもお役に立てれば幸いです。