OmniAICreator/Qiita-1.07M huggingface dataset:
php8系のwordpressでエラー「Your PHP installation appears to be missing the MySQL extension which is required by WordPress.」

# Wordpressで起動のエラー
ubuntu + nginx + php8 + mariadb環境でwordpressをローカルのDocker環境で作成中に下記の画面のエラーが出ました。

![スクリーンショット 2023-02-23 14.15.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145608/6bcdd9f5-3061-7896-aac1-149109995b9f.png)
```
Your PHP installation appears to be missing the MySQL extension which is required by WordPress.
```
メッセージからするに拡張機能の追加を忘れていたことに気づく。
下記のように最初はバージョンを指定せずに入れたが状況変わらず。
```
apt install php-curl php-gd php-intl php-mbstring php-soap php-xml php-xmlrpc php-zip
```

どうやら、php8系の場合は、今のところ（2023年2月23日）バージョンも明示しないといけないみたいです。
```
apt-get install -y php8.1-cli php8.1-common php8.1-mysql php8.1-zip php8.1-gd php8.1-mbstring php8.1-curl php8.1-xml php8.1-bcmath
```
これでいつものwordpressのインスコ画面の登場でした。

![スクリーンショット 2023-02-23 14.20.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145608/80b9859d-4ef0-9a9d-aae5-64353522be03.png)
.com Master Advance ★★(ダブルスター)を最速？で取得する方法

# そもそも.com Masterってなあにぃ？
 簡単に言うと基本情報のNW分野がめっちゃ多めに出るようなイメージ。。。。。
で、BASICとADVACEの2種類あります。
>「就職・転職・スキルアップに！あなたのICTスキルを証明する資格」[インターネット検定　ドットコムマスター](https://www.ntt.com/business/services/application/content-video-delivery/com-master.html "ドットコムマスター ")

 割とマイナーな資格()だともうので、転職に有利かは甚だ疑問ですが、NWに関する知識を深めるという意味ではいいかもしれません(?)

# なんで受験したか
会社から奨励金出るからです。はい。

# 対策

 効率よく資格だけ取りたいなら下記参考書の模擬問題5回分を一通り回答して、わからないところはネットや参考書で調べて覚えれば良いと思います。
(ホントは全部読んだ方が知識を身に着ける上では良いと思うので推奨はしません...?)

https://www.amazon.co.jp/com-Master%E6%95%99%E7%A7%91%E6%9B%B8-Master-ADVANCE-%E7%AC%AC3%E7%89%88/dp/4798161381 

 あと、公式の模擬問題集(インターネット検定 .com Master ADVANCE 「模擬テスト」問題
販売価格 364円（税込400円)がコンビニで購入できるので模擬問題全て終わってやることなくなったら受けた方がいいと思います。

https://www.ntt.com/business/services/application/content-video-delivery/com-master/buy.html

 ちなみに、実際の試験ではこの公式の模擬問題集から体感20%くらい出ていたので購入して損はないのかなとは思います。(これも解説ないけどw)

# 結果と振り返り
 結果はめっちゃギリギリでしたが参考書の模擬問題5回分と公式の模擬問題1回分を解き直すことでダブルスターを取得することができました。

<img width="500" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112815/5a8c3cfa-8953-68a8-c1f5-8e7e5d8f0770.png>

 最後に対策の効率について

|  | 参考書| 章末問題(参考書) |参考書の模擬問題 |公式の模擬問題|
|:-----------|------------:|:------------:|:------------:|:------------:|
| 知識をしっかりつけたい       | ◎      | ○         |×|×|
| 資格だけパスしたい    | ×| △       |◎|◎|


別にNWに関する知識なんかどうでもよくて資格だけ取っとかないと困る！！！って人は、模擬問題集だけやっとけばすぐに取れますよ、、、っていうお話でした。
ニフクラ mobile backendを拡張するNCMBプロキシを開発中です（Google認証）

ニフクラ mobile backendでは認証やデータストア（クラウドデータベース）、ファイルストア（ファイルストレージ）、プッシュ通知など様々な機能があります。そして、サーバーレスで拡張できるスクリプト機能もあります。

しかし、実際のアプリ要件は多彩で、場合によっては他にも様々な機能が望まれます。すべての需要を満たすのは困難な場合もあります。そこで、NCMBのフロントとして動作するプロキシソフトウェアを開発中です。

このプロキシを使うことによって、小さなニーズはプロキシ側で実装できるようになります。今回はプロキシによる****Google****認証機能を紹介します。

## 追加する機能（予定）

現状は透過的なプロキシ + リアルタイム通知くらいしかありませんが、以下のような機能を実装する予定です。

- 認証をJSON Web Tokenに
- GitHub認証
- ソーシャル認証（標準ではサーバー認証が必要ですが、プロキシだけで認証できるように）
- Webhooks
- 署名なしでデータストア操作
- 全リクエストログ記録

他にもデータストアの集計機能、GraphQL機能なども追加できると便利そうです。なお、Webhooksなどの機能はプロキシ経由でしか実現できませんので注意してください（管理画面で操作しても実行されません）。

## NCMBの****Google****認証の課題

NCMBで標準提供されているGoogle認証は以下の課題があります。

- 別途サーバーが必要

Google認証は認証後、リダイレクトを受け取る外部サーバーが必要です。プロキシサーバーを利用することで、コーディングレスでGoogle認証を導入できます。

## インストール

[NCMBMania/ncmb-proxy](https://github.com/NCMBMania/ncmb-proxy)のリポジトリをクローンします。

```
git clone git@github.com:NCMBMania/ncmb-proxy.git

```

ライブラリをインストールします。

```
npm i

```

## 設定の編集

`setting.example.yml` をコピーして `setting.yml` を作成します。そして、ファイル内にあるアプリケーションキー、クライアントキーをそれぞれお持ちのものに書き換えてください。

```
applicationKey: YOUR_APPLICATION_KEY
clientKey: YOUR_CLIENT_KEY

```

## サーバーを起動

サーバーを起動する際には、以下のコマンドを実行します（まだ開発中なので、開発用サーバーが立ち上がります）。

```
npm run dev

```

例えばローカルの場合、 `http://localhost:3000` にてサーバーが立ち上がります。

## デモ

デモサーバーを [https://ncmb.moongift.dev](https://ncmb.moongift.dev/) で立ち上げてあります。これを実際に使っているデモを[こちらに立ち上げています](https://jsfiddle.net/moongift/g2719zhL/81/)。

## 使い方

### 設定の追加

`settings.yaml` に以下の項目を追加してください。スコープは自由に設定できますが、デフォルトはprofileとemailのようです。

```jsx
google:
  clientId: "クライアントID"
  clientSecret: "クライアントシークレット"
  callbackUrl: "(プロキシサーバーのURL)/auth/google/callback"
  scope:
    - profile
    - email
```

### クライアント側の変更

以下はJavaScript SDKでの実装です。新しいウィンドウを `(プロキシサーバーのURL)/auth/google` で開きます。

```jsx
document.querySelector('#btn').addEventListener('click', async (e) => {
  window.open(`https://${fqdn}/auth/google`);
});
```

そして、windowのイベントリスターでmessageを受け取ります。この内容をNCMB.Userオブジェクトに適用し、 `loginWith` で認証し、ローカルに認証データを保存します。

```jsx
window.addEventListener('message', async function (e) {
  const user = new ncmb.User;
  for (const key in e.data) {
    user.set(key, e.data[key]);
  }
  await ncmb.User.loginWith(user);
});
```

## Googleの設定

Google Cloud Consoleでプロジェクトを作成し、さらにOAuth2クライアントを作成します。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/5dc8ee04-88a5-b663-6860-533d75b54d53.png)

OAuthコールバックURLとして `(プロキシサーバーのURL)/auth/google/callback` を設定してください。

## メリット

プロキシサーバーを使うことで、以下のメリットがあります。

1. クライアントIDなどをアプリ側に記述する必要がありません
2. サーバーの用意が不要です

## まとめ

プロキシサーバーを使うことで、キーを隠蔽できたり、リアルタイム通信などの追加機能が利用できます。NCMBをより便利に使いこなすために、ぜひご利用ください。

[NCMBMania/ncmb-proxy](https://github.com/NCMBMania/ncmb-proxy)
CKA 試験、ETCD バックアップ

# ETCD

## ETCD概要
 - k8sのマスターでcluster情報を保存(event, cpu, RAM)
 - k8sの運用情報を保存

## ETCDのバックアップのやり方

### チートシート
https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#backing-up-an-etcd-cluster

# Etcd snapshot（バックアップ）
### 1. backup
```
sudo ETCDCTL_API=3 etcdctl 
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key  \
  snapshot save /tmp/etcd-backup
```

`cacert` `cert` `key` でオプションをつける必要があるが、下記のコマンドで確認できる
snapshot の場所は`/tmp/etcd-backup`

```
ps -ef | grep kube | grep trusted-ca-file
ps -ef | grep kube | grep cert-file
ps -ef | grep kube | grep key-file
```
![스크린샷 2023-02-19 23.08.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961840/23015e24-39e5-e3cb-cea5-29929b967efd.png)
![스크린샷 2023-02-19 23.09.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961840/77c512a0-74c2-fd7f-1630-cbef9f743fc7.png)
![스크린샷 2023-02-19 23.09.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961840/fb93c42b-e928-0c8c-c3d9-b7d25761152d.png)


# Etcd リストア（復元）
### 1. 新しいパス(/var/lib/etcd-new)で バックアップしたファイルを展開する
```
sudo ETCDCTL_API=3 etcdctl snapshot restore --data-dir <data-dir-location> snapshotdb
```
```
sudo ETCDCTL_API=3 etcdctl snapshot restore --data-dir /var/lib/etcd-new /tmp/etcd-backup
```


### 2. etcd podのデータ保存先を`/var/lib/etcd-new`に変更
```
sudo -i
vi /etc/kubernetes/manifests/etcd.yaml
```


### 3. ファイルの中身で下記のように修正する
```
  - hostPath:
      path: /var/lib/etcd
      type: DirectoryOrCreate
    name: etcd-data
↓

  - hostPath:
      path: /var/lib/etcd-new
      type: DirectoryOrCreate
    name: etcd-data
```


![스크린샷 2023-02-23 14.00.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961840/2b67a2ee-4d4f-1295-01eb-f5d6a3b52c26.png)
![스크린샷 2023-02-23 14.00.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961840/f5103057-5e2b-4a18-edd6-a5f8cfefa1bd.png)


### 4. 保存して、終了すると（wq）etcd podがリブートされる

下記の命令語でetcd podが`自動的に再起動される`ことを確認

```
sudo docker ps -a | grep etcd
```
[emacs][Python]Pythonをglobalに対応する

# 最近、Python, Golangのコードを見ることが増えた

globalが使えると嬉しいと思いました。

[GNU Global(gtags)の対応言語を増やしてみる](https://mickey-happygolucky.hatenablog.com/entry/2019/04/01/115817)を参考にした。

ハマりどころはgtagsのインストール先にパスを通す必要があったことと、gtags.elもファイルからインストールしなおした。
[Docker][RoL]備忘録 DockerでRubyOnRailsを立ち上げる時に必要なおまじない

# Docker compose upする前に
1. Railsプロジェクトを作成する
    ```Shell:Shell
    docker compose run --rm web rails new . --force --nodeps --database=mysql
    ```
    Djangoと違い、めちゃくちゃ時間がかかる。

2. 再ビルドする
    ```Shell:Shell
    docker compose build
    ```

3. detabase.ymlの修正(データベースの修正)
    ```yaml:config\detabase.yml
    default: &default
    adapter: mysql2
    encoding: utf8mb4
    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
    username: root
    password: <%= ENV.fetch("DATABASE_PASSWORD") %>
    host: db
    port: 3306
    ```
4. RubyOnRailsを立ち上げる
    ```Shell:Shell
    docker compose up -d
    ```

5. データベースを作成
    ```Shell:Shell
    docker compose exec web rake db:create
    ```

localhost:3000にRubyOnRailsが立ち上がる。

[Docker&仮想サーバー完全入門](https://book.impress.co.jp/books/1121101138)を参考にさせていただきました。　良書です。
rails routesエラー

# はじめに
devise使っている為、ルーティング編集をしました。
編集した際に、devise_for :usersとdevise_for :adminがダブって
記述してしまっていた為、エラーが出ていました。

--------------
route.rbに下記を追加

```php:route.rb
devise_for :users,skip: [:passwords], controllers: {
  registrations: "user/registrations",
  sessions: 'user/sessions'
}


devise_for :admin, skip: [:registrations, :passwords] ,controllers: {
  sessions: "admin/sessions"
}
```




```
$ rails routes
```

上記のコマンドを打つと・・・・

```
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here: 
```

こんなエラーが出てきた！:frowning2:


「same name」同じ名前があるからエラーみたいな感じ…
route.rbを確認してみると・・・


```php:route.rb
devise_for :admins
devise_for :users
  

devise_for :users,skip: [:passwords], controllers: {
  registrations: "user/registrations",
  sessions: 'user/sessions'
}


devise_for :admin, skip: [:registrations, :passwords] ,controllers: {
  sessions: "admin/sessions"
}
```

上に
devise_for :adminsとdevise_for :users
があり、下にもある！
devise_for :users,skip:・・・・・
devise_for :admin, skip: ・・・・


ダブっているせいでエラーが出ていたようです。。。

```php:route.rb
 #devise_for :admins
 #devise_for :users
         ↑
「＃」コメントアウトすると
エラーが消えてrails routesコマンドで
ルート確認することができました
 
devise_for :users,skip: [:passwords], controllers: {
  registrations: "user/registrations",
  sessions: 'user/sessions'
}

devise_for :admin, skip: [:registrations, :passwords] ,controllers: {
  sessions: "admin/sessions"
}
```

devise_for :admins
devise_for :users
を「＃」コメントアウトして～
rails routesコマンドをまた打ってみると～？

エラーが出ずルート確認することができました:relaxed::clap_tone1:
【ESLint】【JSX】propsにスプレッド構文を使うのは好ましくない理由

現在参画しているプロジェクトでは、ESLintの`react/jsx-props-no-spreading`を有効にし、propsにスプレッド構文を使うことは原則禁止となりました。

### 理由
↓のgithubの内容がわかりやすいですが、予期せぬ値が渡されてしまう可能性があるためです。また、渡したいプロパティを明示的に羅列するため、可読性の向上も見込めます。
https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md


### 良い例

渡す必要のある値のみ、明示的に記述する。
```typescript
const {src, alt} = props;
const {one_prop, two_prop} = otherProps;
<MyCustomComponent one_prop={one_prop} two_prop={two_prop} />
<img src={src} alt={alt} />
```

### 悪い例

渡す必要のない値まで、スプレッドでまるっと全部渡してしまう
```typescript
<App {...props} />
<MyCustomComponent {...props} some_other_prop={some_other_prop} />
<img {...props} />
```
【Swift】AppTrackingTransparencyの設定を確認するコード

SwiftでAppTrackingTransparencyの設定を確認するコード

## コード

```swift
import AppTrackingTransparency

switch ATTrackingManager.trackingAuthorizationStatus {
    case .notDetermined:
        print("notDetermined")
    case .restricted:
        print("restricted")
    case .denied:
        print("denied")
    case .authorized:
        print("authorized")
    @unknown default:
        fatalError()
}
```

## 参考
https://developer.apple.com/forums/thread/690607

https://zenn.dev/yorifuji/articles/ios-app-tracking-transparency

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
railsで後でunique制約をつける


コマンドでマイグレーションファイルを作成
```
rails g migration [テーブル名]
rails g migration Osusume
```

add_index〜〜のところを追記して、`rails db:migrate`する
```
class Osusume < ActiveRecord::Migration[7.0]
  def change
    add_index :osusumes, [:title, :short_title], unique: true
  end
end
```
【GitHub利用者必見】リカバリーコードのダウンロードと携帯情報の登録


## 結論

- リカバリーコードをダウンロードしよう
- 携帯情報を登録しよう

以下から飛べばどちらもできる。
https://github.com/settings/two_factor_authentication/configure



---

GitHubにログインしようと思ったら、二要素認証を求められた。

![ 2023-02-23 13.15.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/91a73eda-736b-82f0-a6d7-5019eeda8f40.png)



二要素認証ができない場合(つまり携帯情報を登録していない場合)、代わりにリカバリーコードを入力する必要がある。

(筆者はリカバリーコードの存在を忘れていたので)、5分くらいググってた結果、過去の自分がちゃんとしていればPCにダウンロードしているはずであることが判明した。

とりあえず以下コマンドで確認。

```bash
mdfind github-recovery-codes.txt
```

上記で発見できたので、ことなきを得たが、携帯情報未登録&リカバリーコードがない場合は、GitHubに連絡しないといけない。

https://docs.github.com/ja/authentication/securing-your-account-with-two-factor-authentication-2fa/recovering-your-account-if-you-lose-your-2fa-credentials#using-a-two-factor-authentication-recovery-code


これだと即時でログインできずに非常に辛いので、今のうちに携帯情報登録してリカバリーコードをダウンロードしましょう。
Docker Desktop for Windowsにおける名前付きvolumesの保管場所

# 要約

- ここに保管されてる -> `\\wsl$\docker-desktop-data\version-pack-data\community\docker\` 
- dockerのversionによって細かくパスが異なるみたい

# きっかけ

docker desktop for windowsで名前付きvolumeを作成した際、そのデータはローカル環境上のどこに保管されているのかが気になった。

# 環境
- OS: windows10
    - wsl2
    - Ubuntu-18.04
- Docker version: 20.10.22

# 調べたこと

とりあえず作成済みの名前付きvolumeについてinspectをみてみた。

```bash
$ docker volume inspect mysqlvolume
[
    {
        "CreatedAt": "2023-02-20T12:53:36Z",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "sample_product_1_workspace",
            "com.docker.compose.version": "1.29.2",
            "com.docker.compose.volume": "mysqlvolume"
        },
        "Mountpoint": "/var/lib/docker/volumes/mysqlvolume/_data",
        "Name": "mysqlvolume",
        "Options": null,
        "Scope": "local"
    }
]
```

Moutpointがそれっぽいが、探してみたけど見当たらない。

```bash
$ ls /var/lib/docker/volumes/mysqlvolume/_data
ls: cannot access '/var/lib/docker/volumes/mysqlvolume/_data': No such file or directory
```

ubuntu上にないなら、docker desktop for windowsのアプリとして名前付きvolume（ストレージ）を一括管理してる場所がhostのどこかにある気がする。  

上記の直感を元に色々ググってみたところ、[stackoverflowでドンピシャの質問](https://stackoverflow.com/questions/43181654/locating-data-volumes-in-docker-desktop-windows)があった。
回答者によると `\\wsl$\docker-desktop-data\data\docker\volumes` <- ここにあるらしい。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614279/e532a9ee-fa65-515d-f84a-e21bf8dad698.png)
なかった。

記載されたversionとは異なるが `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\`<- こっち側にあった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614279/af804b7c-16e0-752e-5a8e-65f686a43390.png)

かなりざっくりした直感だったが、同じことを疑問に思う人が他にもいたのがちょっと嬉しかった。  
windows上でdockerがどういった仕組みで動くのか全然わかっていないが、気になった部分から少しずつ理解度を上げていきたい。

# 余談

macだとまた違う管理っぽい。
https://uzimihsr.github.io/post/2020-12-15-docker-desktop-for-mac-hyperkit-vm/#fn:1

# 参考記事

- https://stackoverflow.com/questions/43181654/locating-data-volumes-in-docker-desktop-windows
量子コンピュータの理解を目指し　その１

# 量子コンピュータへの個人的所感

量子コンピュータも通常のコンピュータと同じような考え方で構成されています。量子ゲートは量子ビットから構成され、その量子ゲートを組み合わせて量子回路を作り、量子回路が量子アルゴリズムを実現します。

1) 量子ビット
2) 量子ゲート
3) 量子回路
4) 量子アルゴリズム（≒今の量子コンピュータ）

量子アルゴリズムと今の量子コンピュータをニアリーイコールにした見解ですが。PCはハードウェアを変更をせずに（電子回路はそのまま）様々な事ができますが、今の量子コンピュータは回路を作り変えないと別の事はできません。IBMで公開していたものも、自分で量子回路を書いて計算させていましたね。

将来的には汎用的な計算ができる量子回路も考案されるのかもしれませんが、量子回路の作り変えが簡単にいくらでも出来るという汎用性の方がまだあるように思え、自分的には量子コンピュータは、今のPCのとは違う方向性で発展する気がします。

# 量子コンピュータはなぜ理解しにくいか

まず、当たり前なのですが、簡単に理解できることではないので、時間をかける必要がある思います。しかし、その覚悟の上で時間をかけてもなお分かり難い事が多いようです。端的に言ってしまうと「量子」の概念が理解できないからだと思います。

そんな事は分かってるという声が聞こえる気がしますが、少し補足をすると。量子コンピュータ入門と題される多くの記事や書籍では、最初に数学的に量子ビットを定義し、その前提で話をどんどん発展させていきます。発展させる際の論理や計算は決して複雑なものではありません。

しかし、抽象的な概念というのは実感をもてないと、どんなに簡単な論理でも以外と納得できず、納得できない事実から論理的に納得できない事実を導くという事を繰り返す苦行を続ける事になります。

習うより慣れろとはいいますが、自分の場合、全く納得できず、実感のないまま、機械的に抽象概念を反復練習することによって脳自身も機械的にその概念を当たり前の事ととらえはじめると、おのづと実感（心的な脳による理解とでも言っておきましょうか）が伴ってくるような気がしてます（コスパは最悪ですね、おまけに理解というものの本質が分からなくなりませ）。

しかし、ちょっと知りたい、すこしでも「なるほど！」と思いたい程度だと、実感を得るまでモチベーションを保ち続けるのは難しく、
【GAS】「appsscript.json」のエラー: サービス ID は空にできませんの対処法

## 事象
・ライブラリを読み込もうとした際に「サービス ID は空にできません」のエラーが表示される
・サービスIDを入力したのち再度ライブラリの「追加」ボタンを押しても同様のエラーが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2931101/8df0a451-2a04-0008-6338-0873a3846178.png)

## 原因と対処法
サービスIDを未入力の状態で追加したライブラリ情報が「appscript.json」上に残っていたことが原因でした。
エラー発生時のjsonファイルはこんな感じ。librariesの1つ目がサービスID未入力のもの、2つ目がきちんと入力して保存し直したものです
```appscript.json
{
  "timeZone": "Asia/Tokyo",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "dependencies": {
    "libraries": [
      {
        "userSymbol": "",
        "version": "0",
        "libraryId": "*********************************************************",
        "developmentMode": true
      },
      {
        "userSymbol": "test",
        "version": "0",
        "libraryId": "*********************************************************",
        "developmentMode": true
      }
    ]
  }
}
```
エラーの原因になっている1つ目のライブラリ情報を削除することで正常にライブラリの追加・参照が行えるようになります。
```appscript.json
{
  "timeZone": "Asia/Tokyo",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "dependencies": {
    "libraries": [
      {
        "userSymbol": "test",
        "version": "0",
        "libraryId": "*********************************************************",
        "developmentMode": true
      }
    ]
  }
}
```

## 備考：サービスIDが未入力になる原因
プロジェクト内でライブラリを追加する時、通常はライブラリとして公開しているプロジェクトの名前が自動でID欄に記入されるようになっています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2931101/355b6ab8-d3a6-48af-d8ea-5eac8fdb4837.png)
こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2931101/16d35a8a-6b18-758e-2322-8f0dda14bd6c.png)

また、サービスIDを未入力の状態に戻すとUI上で警告が表示され、［追加］ボタンは非活性になる仕様になっています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2931101/87c35787-00d4-cdd7-34cd-7219c578a90e.png)
ところがライブラリとして公開されている参照先のプロジェクトの名前を日本語（おそらく正確にはサービスIDとして有効ではない文字列）にしてしまうと、IDが未入力のまま追加ボタンが押せてしまい、サービスIDのないライブラリ情報の記録につながってしまうようです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2931101/95199318-6a26-e33a-2d37-17a800ad8277.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2931101/0c6c5057-9624-f460-c069-ac011f7d9ee7.png)
加えてサービスIDが未入力の状態で追加したライブラリはエディタ横の「ライブラリ」欄には表示されないため、ライブラリを追加できたのかできてないのかぱっと見分かりづらい感じになるようです、困ったね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2931101/26ac6080-dc4c-e822-cb6f-0ea67569ca08.png)
Windowsにリモートアクセスする方法についてのメモ

## この記事の概要

Winodowsにリモートアクセスする方法について調べた結果のメモである。    

## GUIによるリモートアクセス

### リモートデスクトップ

#### 概要

事前に許可設定をしていないとアクセスできない。  
メモリ不足等何かトラブルが発生すると、アクセスができなくなる。   
Homeエディションではリモートデスクトップを有効にすることはできない。  

#### 参考

[Windows10 リモートデスクトップの設定方法](https://www.v-warp.com/blog/remotedesktop_windows_setting/)

### vnc

#### 概要

UltraVNC等のvncソフトをインストールすると利用可能になる。  

#### 参考

[UltraVNC](https://forest.watch.impress.co.jp/library/software/ultravnc/)

### Chrome リモート デスクトップ

#### 概要

Chromeを経由してアクセスを可能にする。  

#### 参考

[Chrome リモート デスクトップを使って他のパソコンにアクセスする](https://support.google.com/chrome/answer/1649523?hl=ja&co=GENIE.Platform%3DDesktop)

### コンピュータの管理

#### 方法

試してみたが、Windows10だとアクセスできなかった。

#### 参考

[システムをリモートからシャットダウンする](https://atmarkit.itmedia.co.jp/ait/articles/0401/10/news025.html)

## CUIによるアクセス

### openssh

#### 概要

最近のWindowsはオプションでopensshサーバが追加可能になった。  
opensshサーバを有効化するとsshクライアントでWindowsマシンにアクセスが可能になる。  
VSCodeのRemote SSH でもアクセスすることができる。

#### 参考

[OpenSSH をインストールする](https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse)

[windows10にsshサーバを立てる (+起動時にサービス起動する)](https://tyaron626.hatenablog.jp/entry/2020/09/09/155411)

### netコマンドを使う

#### 概要

これでもリモートアクセスできるようだが、試してみたが駄目だった。

```
net use \\172.23.0.1 /user:[接続先PCの管理者ユーザ] 
shutdown /m 172.23.0.1 /r /f 
```
#### 参考

[Windowsをリモートで再起動する](https://www.thinqa.net/2020/04/10/483)

### psexec

試したことはないが、古いWindowsでもリモートPCのコマンドを実行できる。  

#### 参考


https://learn.microsoft.com/ja-jp/sysinternals/downloads/psexec

### powershell

powershellの標準機能でもリモートでのアクセスが可能のようだ。

#### 参考

[リモート コマンドの実行](https://learn.microsoft.com/ja-jp/powershell/scripting/learn/remoting/running-remote-commands?view=powershell-7.3) 

[【PowerShell】リモート接続を行う方法（Enter-PSSession）](https://cloud-si.com/enter-pssession/)

## 結論

Windowsにリモートアクセスする場合は、   
リモートデスクトップとopenssh serverを使うのがよいと思われる。
VMware: PlayerのゲストをESXiに移動した際の手順の備忘録

# VMWare PlayerのゲストをESXiに移動した際の手順の備忘録

# バージョン
|製品|バージョン|
|----|---------:|
|VMware Player| 17|
|VMware ESXi|7|

PlayerはWin10で動作しているものとする。

# 手順
1. 対象ゲスト(vmx)ファイルの格納ディレクトリを記録しておく
1. コマンドプロンプトで`VMware Playerのインストールディレクトリ\OVFTool`に移動
   デフォルトでは`c:\Program Files (x86)\VMWare\VMWare Player`
1. `ovftool.exe 移動元vmxファイル名 移動先ディレクトリ名`
:::note warn
移動元vmxファイル名はファイル名まで記述するが、移動先はディレクトリ。
移動先ディレクトリの下にゲストの名称のディレクトリを作成してくれるので、移動先ディレクトリにゲスト名を含んだものを指定すると、予定していたものより1階層増えるので、注意
:::
4\. ゲストのovfファイルが作成されたら、ESXiにデプロイする。


# 参考
https://zapping.beccou.com/2019/08/26/vmplayer-memorandum/

他にも、2,3サイトを参考にさせていただいたが、URLを失念しました。
参考になりました。ありがとうございました。
if文


## if文
```py.qiita.py
# 　4 if文
#  4-1 
x = 223
if x < 0:
    print('0よりも小さいですよ！')
#     条件分岐
elif x > 0:
    print('0よりも大きいですよ！')
#     else : 上の条件のいずれにも当てはまらない場合
else:
    print('0です！')

```
## FIZZBUZZ問題
```py.qiita.py
#  4 -2 FizzBuzz問題
#  ３で割り切れる時はFIZZ, 5で割り切れる時はBUZZ, 3と5で割り切れる時はFIZZBUZZを返す
x = 220
# 　プログラムは上から順に実行されるので、条件の厳しいものから順に書いていくとよいかもしれない
if x % 15 == 0:
    print('3と５で割り切れるので、FIZZBUZZ')
elif x % 3 == 0:
    print('3で割り切れるので、FIZZ')
elif x % 5 == 0:
    print('5で割り切れるので、BUZZ')
else:
    print(x, 'は割り切れません')
```
ニフクラ mobile backendを拡張するNCMBプロキシを開発中です（Facebook認証）

ニフクラ mobile backendでは認証やデータストア（クラウドデータベース）、ファイルストア（ファイルストレージ）、プッシュ通知など様々な機能があります。そして、サーバーレスで拡張できるスクリプト機能もあります。

しかし、実際のアプリ要件は多彩で、場合によっては他にも様々な機能が望まれます。すべての需要を満たすのは困難な場合もあります。そこで、NCMBのフロントとして動作するプロキシソフトウェアを開発中です。

このプロキシを使うことによって、小さなニーズはプロキシ側で実装できるようになります。今回はプロキシによるFacebook認証機能を紹介します。

## 追加する機能（予定）

現状は透過的なプロキシ + リアルタイム通知くらいしかありませんが、以下のような機能を実装する予定です。

- 認証をJSON Web Tokenに
- GitHub認証
- ソーシャル認証（標準ではサーバー認証が必要ですが、プロキシだけで認証できるように）
- Webhooks
- 署名なしでデータストア操作
- 全リクエストログ記録

他にもデータストアの集計機能、GraphQL機能なども追加できると便利そうです。なお、Webhooksなどの機能はプロキシ経由でしか実現できませんので注意してください（管理画面で操作しても実行されません）。

## NCMBのFacebook認証の課題

NCMBで標準提供されているFacebook認証は以下の課題があります。

- 有効期限をNCMBの日付フォーマットに合わせて作成する必要がある

Facebook認証は外部サーバー不要ですが、Monacaアプリの場合にはInAppBrowserで外部JavaScriptをインジェクションするなど、多少面倒な仕組みが必要です。

また、有効期限をNCMBの日付フォーマットに合わせる必要があり、多少面倒です。

そうした点をプロキシサーバーでは解決できます。

## インストール

[NCMBMania/ncmb-proxy](https://github.com/NCMBMania/ncmb-proxy)のリポジトリをクローンします。

```
git clone git@github.com:NCMBMania/ncmb-proxy.git

```

ライブラリをインストールします。

```
npm i

```

## 設定の編集

`setting.example.yml` をコピーして `setting.yml` を作成します。そして、ファイル内にあるアプリケーションキー、クライアントキーをそれぞれお持ちのものに書き換えてください。

```
applicationKey: YOUR_APPLICATION_KEY
clientKey: YOUR_CLIENT_KEY

```

## サーバーを起動

サーバーを起動する際には、以下のコマンドを実行します（まだ開発中なので、開発用サーバーが立ち上がります）。

```
npm run dev

```

例えばローカルの場合、 `http://localhost:3000` にてサーバーが立ち上がります。

## デモ

デモサーバーを [https://ncmb.moongift.dev](https://ncmb.moongift.dev/) で立ち上げてあります。これを実際に使っているデモを[こちらに立ち上げています](https://jsfiddle.net/moongift/g2719zhL/81/)。

## 使い方

### 設定の追加

`settings.yaml` に以下の項目を追加してください。これらはFacebook管理画面で取得できます（コールバックURLは自分で設定します。開発モードであればlocalhostが利用できます）。

```jsx
facebook:
  callbackUrl: コールバック用のURL
  appId: "FacebookアプリID"
  appSecret: "Facebookアプリのシークレット"
```

### クライアント側の変更

以下はJavaScript SDKでの実装です。新しいウィンドウを `(プロキシサーバーのURL)/auth/facebook` で開きます。

```jsx
document.querySelector('#btn').addEventListener('click', async (e) => {
  window.open(`https://${fqdn}/auth/facebook`);
});
```

そして、windowのイベントリスターでmessageを受け取ります。この内容をNCMB.Userオブジェクトに適用し、 `loginWith` で認証し、ローカルに認証データを保存します。

```jsx
window.addEventListener('message', async function (e) {
  const user = new ncmb.User;
  for (const key in e.data) {
    user.set(key, e.data[key]);
  }
  await ncmb.User.loginWith(user);
});
```

## Facebookの設定

Facebookでアプリを作成したら、そのOAuthコールバックURLとして `(プロキシサーバーのURL)/auth/facebook/callback` を設定してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/ad2bb080-b0f1-c105-4ed8-4b7d45cbcaaf.png)

他、必要な情報はApp IDとApp secretになります。


## メリット

プロキシサーバーを使うことで、以下のメリットがあります。

1. アプリIDすらアプリ側に記述が不要です。

ただし、この認証はWebサーバーを介するものなので、ユーザー体験としてはFacebookアプリを呼び出す方式の方が良さそうです。

## まとめ

プロキシサーバーを使うことで、キーを隠蔽できたり、リアルタイム通信などの追加機能が利用できます。NCMBをより便利に使いこなすために、ぜひご利用ください。

[NCMBMania/ncmb-proxy](https://github.com/NCMBMania/ncmb-proxy)
Neovimでsignをminimapのように表示するplugin

# 概要
最近作ったNeovimのplugin、signbarの紹介記事。

https://github.com/dr666m1/signbar.nvim

こんな感じで右端のfloating window（以下signbar）にbuffer内のsign（行番号の左に表示されるあれ）を一覧表示してくれる。このgifは粗いけれどGitHubにはオリジナルのmp4があるよ。

![374df91a2655-20230220.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540947/3ceec271-30d6-558e-6ead-4558ad6ac21a.gif)


# 背景
なぜこのpluginを作ったかというと、以下のような悩みがあったから。同じようなことで悩んでいる人には役立つはず！

* [marks.nvim](https://github.com/chentoast/marks.nvim)でどのmarkをどの辺りで使ったかわからなくなる
* 各種language serverがエラーをsignとして表示してくれるけど、編集中の箇所から離れていると気づかない[^err]


[^err]: 自分はエラー数をstatuslineに表示しているのになぜか気づけない...

# 設定
[packer.nvim](https://github.com/wbthomason/packer.nvim)を使う。以下を書き足せばOK（コメントは細かく設定する場合の例）。

```lua
use {
  'dr666m1/signbar.nvim',
  config = function()
    require("signbar").setup {
      -- refresh_interval = 1000,
      -- ignored_sign_names = { "Marks_a" },
      -- ignored_sign_groups = { "MarkSigns" },
    }
  end
}
```

以下、設定項目について補足。

#### refresh_interval (integer)
指定した間隔（ミリ秒）でsignbarを更新する。デフォルト（nil）だとカーソル移動ごとに更新されるが、それだと頻繁過ぎるときに指定する想定。あまりに間隔が短いとE322のエラーが発生するので、指定するなら1000以上とかがよさげ。

#### ignored_sign_names, ignored_sign_grups (table)
signbarに表示したくないsignをnameやgroup単位で指定する。ちなみに、現在表示されているsignのnameやgroupを確認するには`:sign place group=*`を実行するとよい。

# 最後に
よければ試しに使ってくださいませ！
belongsToManyで取得したデータからpivotテーブルの情報を除く

# やりたいこと
多対多の関係性のテーブルからリレーション先のデータを取得するとpivotテーブルの情報も含まれてしまうから、それを除外した上で取得したい。

以下のようなUserとGroupのmodelがあります。
```User.php
class User extends Authenticatable
{
    public function groups()
    {
        return $this->belongsToMany(Group::class);
    }
}
```

```Group.php
class Group extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class);
    }
}
```

GroupからUserの情報を取得しようとすると、、

```GroupController.php
$group = Group::find(1);
$group->users()->get(['users.id', 'name'])
```

pivotテーブルの情報も含まれていて、これを削除したい。
```
group: [
{
    id: 3,
    name: "テスト太郎",
    pivot: {
        user_id: 3,
        group_id: 1
    }
},
```

# 対応方法
方法は二つあります。

### 1.リレーション先のモデルにhiddenプロパティを追加する

```User.php
class User extends Authenticatable
{
    protected $hidden = [
        'pivot',//追加する
    ];

    public function groups()
    {
        return $this->belongsToMany(Group::class);
    }
}
```

### ２.取得時にmakeHidden（）を使用する

```GroupController.php
$group = Group::find(1);
$group->users()->get(['users.id', 'name'])->makeHidden('pivot');
```

参考：https://readouble.com/laravel/8.x/ja/eloquent-collections.html#method-makeHidden

以上
型とキャスト


## 型の確認
```py:qiita.py
#  3. 型とキャスト
# 　3-1 type関数: 型を調べることができる
a = 4
# print(type(a))

#  3-2 
six = 6
pi = 3.14
text = 'text'
is_false = False

#  型の確認ができる
print(type(six)) # int
print(type(pi)) # int
print(type(text)) # float : 実数のこと
print(type(is_false)) # bool
```

## キャスト
```py:qiita.py
#  3-3 　キャスト : 型の変換ができる
#  型の確認
three = 3
print(type(three))

print('int → str　に変換中')

#  str(対象)で型の変換が可能
three_str = str(three)
print(type(three_str))

print('str → int に変換中')

# 　int型に変換する
three_int = int(three_str)
print(type(three_int))

#  比較演算子を用いて確認する
print('threeとthree_strの型は',three == three_str) # False
print('threeとthree_intの型は',three == three_int) # True

```
simulink UART出力

　matlabのsimulinkの環境で、シリアル（UART）で信号を出力する実験です。matlabはR2022bです。

### UARTボードを用意
　アマゾンで、[KKHMF 3個 CP2102モジュール マイクロ USB転UART TTL 6ピン シリアル コンバーター](https://www.amazon.co.jp/KKHMF-CP2102%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-USB%E8%BB%A2UART-%E3%82%B3%E3%83%B3%E3%83%90%E3%83%BC%E3%82%BF%E3%83%BC-%E3%80%8C%E5%9B%BD%E5%86%85%E9%85%8D%E9%80%81%E3%80%8D/dp/B088FL8Q3Y/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2B5778XZZP1PD&keywords=hiletgo+2%E5%80%8B%E3%82%BB%E3%83%83%E3%83%88+cp2102+%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%ADusb%E8%BB%A2uart&qid=1677112451&sprefix=hiletgo+2%E5%80%8B%E3%82%BB%E3%83%83%E3%83%88+cp2102+%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD+usb%E8%BB%A2uart%2Caps%2C176&sr=8-1)を入手します。筆者が購入したときは2個セットでした。
　PCとUSBケーブルで接続します。
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/9f66af08-5808-fa8b-8223-be8584296a91.png">

　RXIとTXDをオシロスコープのプローブに接続します。

### simulinkの設定
　Instrument Control ToolboxのSerial ConfigurationとSerial Sendをドラッグします。入力用に定数もドラッグして接続します。

![sim201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/470be6e2-d434-b194-51ee-59b948a6c0b2.png)

　それぞれの設定です。

　COM3ポートにボードがつながっています。9600ボー、8ビット、パリティなし、ストップ・ビットは1に設定しました。
　
![sim202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a3d27c05-68b9-d2cd-b070-164e32f3d1cb.png)


　ヘッダーは0xf0、ターミネータは0x55にして、オシロスコープで見たときにわかるようにしました。
![sim203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/73a1d259-55bf-7d74-ca45-c071a21784f9.png)

　2バイトのデータを送ります。
![sim204.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/8080e84f-86b6-4d87-82ff-c4d1dc9eb81c.png)

### オシロスコープで見る

　リトル・エンディアンで0x02が送られていることが確認できました。

![sim102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/cdd1271e-13e9-6b42-8553-9697397517c8.png)
FastAPIをdockerで動かす

## はじめに
備忘録です。
Dockerは知っている前提なので、詳しい説明は省きます

*構成*
```
app
 - main.py
 - Dockerfile
.env
requirements.txt
docker-compose.yml
```

*Dockerfile*
```Dockerfile
FROM python:3.9-buster

WORKDIR /app

COPY ./requirements.txt .

RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt

COPY ./app .

CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]
```

*docker-compose.yml*
```yml
version: "3.8"
services:
  app:
    build:
      context: ./
      dockerfile: ./app/Dockerfile
    env_file: ./.env
    tty: true
    volumes:
      - ./app:/app
    ports:
      - "8000:8000"
    environment:
      - TZ=Asia/Tokyo
```

## ちょっとだけ説明
Dockerfileではrequirements.txtに列挙したmoduleをインストールするようにしています。
pythonではpackage.jsonのようなものがないので、このような方法で代用します

*`requirements.txt`*
```txt
fastapi
uvicorn
pydantic
typing
```

*チームメンバーに共有する時は下記のようにしてください*
*立ち上げたコンテナ内で $ pip freeze > requirements.txt* (依存も含めて使用しているmoduleを出力)
*出力されたファイルの内容でrequirementsを上書きして共有する*

## hostの設定
*Dockerfileでhostを0.0.0.0にしています*
*デフォルトではlocalhostで立ち上げてしまいます*
なので下記のようにFastAPIのお馴染みのコマンドで立ち上げるとymlのportsを指定していてもdocker内部からしかアクセスできなくなります
`uvicorn main:app --reload`
winscp 常用設定


```
➊　終了
メニュー＞コマンド＞終了   ショットキーF10

➋　リモートディレクトリ固定
接続済みではなく、最初接続する時、右画面の編集クリック＞
設定クリック＞環境＞ディレクトリ＞最後に使用したディレクトリを記憶する外す＞
リモートディレクトリ＞入力

➌　同期設定
②の一番上です。
【Visual Studio Code】表示言語を統一する

## 環境
+ Microsoft Windows 10.0.22621
+ Visual Studio Code 1.75.1

## はじめに
表示言語（Display Language）を英語（既定）に設定していたが，一部の拡張機能で日本語表示になっていため，英語に統一する方法を調べた．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/e4d63c19-fb4c-900d-2b21-763df44d6a7e.png)

## 方法
`C:\Users\USERNAME\.vscode\argv.json` (Windows) を開き，`"locale":"en"` を追記・保存する．（日本語の場合は `"locale":"ja"`）

> Mac(macOS 10.14.6 Mojave)：`~/.vscode/argv.json`
> Linux(Ubuntu 18.04)：`~/.vscode/argv.json`
> 
> 出典：[(随時更新) VSCodeの各種設定ファイルの格納場所備忘録メモ - Qiita](https://qiita.com/y-vectorfield/items/f9df044981ef29083318)


:::note warn
`locale.json` を編集すると書かれているサイトが多数存在するが，これは古いバージョンの情報である．
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/e5be0cfb-7de1-0bfc-fa82-59bc8b23d235.png)

Visual Studio Code を再起動すると，英語表記に変わった．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/60b12817-4c98-8801-bf58-03c32c4eec80.png)

## 参考

https://code.visualstudio.com/docs/getstarted/locales
[GAS]Googleフォームの初期値を入れたURLを生成する方法

# はじめに

Googleフォームで回答に初期値を入れたい場合、
「事前入力したURLを取得」というのでURLを取得できます。

が、フォームを作るたびに手作業でURLを生成するのが苦痛だったので、
GASでURLを生成するコードを作成しました。


# TL;DR

GoogleFormsのパラメータ付きURLを取得する

```javascript
function getLink() {
  const form = FormApp.openById(FORM_ID);
  const items = form.getItems();
  const item = items.find(item => { 
    return item.getTitle() == '質問のタイトル';
  });

  const formResponse = form.createResponse();
  // asTextItem()は質問種別によって変える
  const itemResponse = item.asTextItem().createResponse('回答の初期値');
  formResponse.withItemResponse(itemResponse);
  return formResponse.toPrefilledUrl();
}
```

# 背景

Googleフォームで回答に初期値を入れる場合、以下のようなパラメータ付きURLで実現できます。


```
https://docs.google.com/forms/d/e/[FORM_ID]/viewform?usp=pp_url&entry.1265416375=回答の初期値
```

URLにアクセスするとこのように、回答欄に初期値が埋まります
<img width="300" alt="質問種別" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97730/7886ef3b-777c-61f8-bc27-edcb323732d4.png">



このURLは画面から生成できます。

https://qiita.com/jooji/items/79496f65f1c6c18664f5

パターンとしては
`entry.[質問ID]=回答の初期値`
なので、理屈としては`質問ID`部分の数字が分かれば良いわけです。

ただし、この数字はフォームを作るたびに変わるので、
一般的には、画面からURLを生成するか、htmlからidを探すか、2択のようです。

https://qiita.com/mkohei/items/b62700b46bb71bf0a9c3

1回フォームを作って終わりなら特に問題ないのですが、
諸事情で、多くのGoogleフォームを管理する必要がありました。

（気持ち的に）無理だったので、別の方法を探した所、
GASで同じことが実現できそうだったので作ることにしました。

# GASのコード

```javascript
function getLink() {
  // フォームの設定を取得
  const form = FormApp.openById(FORM_ID);
  const items = form.getItems();
  // 初期値を入れたい質問を選択
  const item = items.find(item => { 
    return item.getTitle() == '質問のタイトル';
  });

  // フォームの回答を生成
  const formResponse = form.createResponse();
  // 記述式の質問項目に対する回答
  const itemResponse = item.asTextItem().createResponse('回答の初期値');
  formResponse.withItemResponse(itemResponse);
  return formResponse.toPrefilledUrl();
}
```

初めてGoogleフォームのスクリプトを書いたので、ややこしかったのですが、
Googleフォームで、アンケートの設定と回答が分かれているのと同様に
オブジェクトも設定(`Form`,`Item`)と回答(`FormResponse`, `ItemResponse`)で別のクラスになっているようです。

詳しく知りたい方はドキュメントを読んでみてください。

https://developers.google.com/apps-script/reference/forms/form?hl=ja


## 注意点
↓質問の種別に応じて、`asTextItem()`の部分は変更してください。
<img width="200" alt="質問種別" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97730/93200b39-d1be-5ed5-13ac-05c1a73fe119.png">

試してないですが、`getType()`で判別できるそうです。

https://developers.google.com/apps-script/reference/forms/item?hl=ja


# 終わり

同じ悩みを抱えている方のお役に立てれば幸いです
【PostgreSQL】docker-composeで起動と初期データ投入

# はじめに

備忘録がてら、`docker compose`を用いたPostgreSQLの環境構築の方法を記述します。
ディレクトリ構成は以下の通りです。

```zsh
docker
├── compose.yaml
├── image
│   └── postgres
│       └── Dockerfile
└── postgres
    └── init
        └── init.sql
```
# ファイルの作成

## compose.yaml

※ ファイル名は `compose.yml` や `docker-compose.yaml` でも動作しますが、公式が推奨しているのは `compose.yaml` のようです。（[参考](https://docs.docker.com/compose/intro/compose-application-model/#the-compose-file)）

まずはじめに`compose.yaml`を作成します。
起動するためのコマンドである`docker compose up -d`を叩いたときに読み込まれるファイルになります。
```compose.yaml
version: '3'
services:
  postgres:
    container_name: sample-db
    build: ./image/postgres
    restart: always
    ports: 
      - "5432:5432"
    volumes:
      - ./postgres/init:/docker-entrypoint-initdb.d
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"
```
imageはDockerfileで定義しているので、それは次に説明します。
Dockerfileを使用しない場合は、`build:`の部分で以下のようにすることでimageを定義することもできます。
```
image: postgres:latest
```

## Dockerfile

`compose.yaml`内の`build:`で指定したパスに`Dockerfile`を作成してimageを定義します。
以下のように1行で定義すればOKです。
```Dockerfile
FROM postgres:15
```
今回はバージョン15を利用しています。

## 初期データ投入用のSQL

`volumes:`でSQLファイルの場所を指定することで、起動時にSQLを流すことができます。
パスの指定は`volumes:`で指定されている内の前半部分である`./postgres/init`です。
ここにSQLファイルを作成します。

```sql
-- DB作成
CREATE DATABASE sample_db;
-- 作成したDBに接続
\c sample_db;
-- テーブル作成
DROP TABLE IF EXISTS sample;
CREATE TABLE sample (
	id integer NOT NULL PRIMARY KEY,
	name char(100) NOT NULL,
	created_date_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- ID用シーケンス作成
CREATE SEQUENCE sample_id_seq START 1;
-- サンブルデータの登録
INSERT INTO sample (id, name) VALUES(nextval('sample_id_seq'), 'sample name');
```

SQLの内容は任意なので、ご自身でお好きなように設定してください。

# 動かしてみる

## 起動

まず`compose.yaml`がある`docker`ディレクトリに移動します。

```zsh
cd docker
```

次にコンテナを起動します。

```zsh
docker compose up -d
```

## 確認

正常に起動しているか確認します。

```zsh
docker ps
```
このコマンドを叩いて、`NAMES`の箇所に`compose.yaml`の`container_name:`に定義した名前が表示されていればOKです。
サンプルコード通りに記述している場合、`sample-db`と表示されます。

次に起動したコンテナに接続します。
`sample-db`の部分はコンテナ名です。

```zsh
docker exec -it sample-db bash
```

コンテナ内で動いているDBに接続します。

```
psql -U postgres -d sample_db
```

`sample_db`はSQLファイル内で作成したDBの名前になります。
SQLファイル内で新たにDBを作成していない場合は`psql -U postgres`のみで大丈夫です。

テーブルにデータが挿入されているか見てみます。

```
SELECT * FROM sample;
```
SQLファイル内で`INSERT`したデータが出力されれば正常に動作しています。

注意点としては初期データを投入するSQL文が間違っていたとき、エラーログなどを出力してくれません。
そのためデータがうまく挿入されないなどの場合、DBに接続した状態で一度直接SQLを流すなどしてSQLの構文が正しいか確認してみるといいと思います。

## コンテナの停止と削除

DBやDockerで起動したコンテナに接続している場合、`exit`を実行することで接続を切ることができます。
`/docker`に移動した状態で以下のコマンドを実行することで、コンテナを停止することができます。

```
docker compose stop
```

削除する場合は次のコマンドになります。

```
docker compose down
```

最後までお読みいただきありがとうございました。
間違ったsetStateの使い方

`setState`対になるstateを使って計算する場合function記法`setCount(prev => prev + 1)`で書くべきです。

理由は、`setCount(count + 1)`のような書き方をするとstateが変更される前に、次の`setCount`が動くと変更前の値で計算してしまうためです。

下記がその例です。
`setCount(count + 1)`は1づつしかcountが増えませんが、`setCount(prev => prev + 1)`では2づつcountが増えます。


```tsx
import { useState } from "react";

import "./App.css";

function App() {
  const [count, setCount] = useState(0);
  const handleAdd = () => {
    // 1づつしか増えない(間違った使い方)
    // setCount(count + 1)
    // setCount(count + 1)
    
    // 2づつ増える
    setCount(prev => prev + 1)
    setCount(prev => prev + 1)
  }


  return (
    <div className="App">
      <button onClick={handleAdd} />
      {count}
    </div>
  );
}

export default App;


```
[codesandbox](https://codesandbox.io/p/sandbox/0usj9z)
そのため、stateを使用してsetStateをする場合は必ずfunction記法で書くようにしましょう。
Virt-ManagerのCreate virtual networkでbridgeが選択肢に出てこない

# 問題の状況

Virt-Managerで作成したゲストOSのネットワークについて、リモートからログインするためにbridgeを指定したい。nmcliでbridgeを作成するも、Create virtual networkのダイアログのMode指定欄にてbridgeが出てこない。

![create_virtual_network.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/f15fdf5f-70e7-3203-accf-b09f6e89e201.jpeg)

:::note info
環境
ホスト Ubuntu 22.04.1 LTS
Virt-Manager ver 4.0
:::

# 対処

`Connection Details`を開く。
XMLの直接編集を許可した上、`<forward mode="bridge">`を記述する。ほか、`<name>...</name>`,`<bridge name="..."/>`を記載する。`<uuid>...</uuid>`はApplyした後、自動で設定される。

![host-bridge_xml.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/50b6b43c-e743-09e2-9292-af3339547154.jpeg)

`Virtual Machine Details`でNICを選択すると、作成したBridgeを`Network source`に選択できる。

![nic-details.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/25172705-029c-3dcb-8bd0-cb86b98cdd6e.jpeg)

# 備考
nmcliを用いたbridgeの作成法は、いろいろ記事があるのでそちらを参照してください。
[Docker][Django]DockerでDjangoを立ち上げる時に必要なおまじない

# Docker compose upする前に
1. Djangoプロジェクトを作成する
    ```Shell:Shell
    docker compose run --rm web django-admin startproject myproject .
    ```

2. Setting.pyの修正(データベースの修正)
    ```python:myprject\setting.py
    DATABASES = {
        'default': {
            #'ENGINE': 'django.db.backends.sqlite3',
            #'NAME': BASE_DIR / 'db.sqlite3',
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'testdb',
            'USER': 'testuser',
            'PASSWORD': 'testpass',
            'HOST': 'db',
            'PORT': '5432',
        }
    }
    ```

localhost:8000にDjangoが立ち上がる


[Docker&仮想サーバー完全入門](https://book.impress.co.jp/books/1121101138)を参考にさせていただきました。　良書です。
Account Discovery Recipe


+ [Account Discovery Recipeが見つからない？](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgDk8)

設定が必要みたい

:::note
Get Account Health Details with Account Discovery

Account Discovery provides dashboards and Einstein Discovery models to help you see which of your accounts has potential for upside growth and which need attention.

Where: This change applies to Lightning Experience in Performance and Unlimited editions with Pipeline Inspection. Pipeline Inspection is also included with Revenue Intelligence, which is available for an extra cost in Enterprise Edition.

Who: To create Account Discovery, you must have a Revenue Intelligence Admin permission set. To access the Account Discovery app, users must have a Revenue Intelligence User permission set.

How: You can view Account Health, Accounts with Potential for Upside, and Einstein Discovery models from the Accounts page in Sales Cloud.

https://help.salesforce.com/s/articleView?id=release-notes.rn_sales_revinsights_acct_discovery.htm&release=242&type=5
:::
Linux Mint 21.1でPDFの一部のフォントが文字化けした場合の解決法

# 問題

WebからダウンロードしたPDFをXreaderで表示すると一部の文字が文字化けしていた（豆腐になっていた）。Firefoxで見ると問題なく表示されている。

# 環境

- Linux Mint 21.1 Cinnamon
- Xreader 3.6.3

# 調査

PDFのフォント情報を見てみる。

```sh
$ sudo apt install nkf
$ pdffonts hogehoge.pdf | nkf -S -w
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
ＭＳゴシック                         CID TrueType      90ms-RKSJ-H      no  no  no       8  0
ＭＳゴシック,Bold                    CID TrueType      90ms-RKSJ-H      no  no  no       5  0
```

MSゴシックが指定されているもののLinux MintにMSゴシックはないので文字化けしている様子。

# 解決

以下のパッケージをインストールしたら文字化けが直った。

- fonts-takao-mincho
- fonts-takao-gothic
- fonts-takao-pgothic

```sh
sudo apt install fonts-takao-mincho fonts-takao-gothic fonts-takao-pgothic
```
plunkerでdeck.gl その14

# 概要
plunkerでdeck.glやってみた。
練習問題やってみた。

# 練習問題
covid-19のjsonを読んで、棒グラフを表示せよ。

# サンプルコード

```

let hexagonLayer = new deck.HexagonLayer();
const tileLayer = new deck.TileLayer({
  data: "https://c.tile.openstreetmap.org/{z}/{x}/{y}.png",
  minZoom: 0,
  maxZoom: 19,
  tileSize: 256,
  renderSubLayers: props => new deck.BitmapLayer(props, {
    data: null,
    image: props.data,
    bounds: (({ west, south, east, north }) => [west, south, east, north])(props.tile.bbox),
  }),
});
const data = [];
const OPTIONS = ['radius', 'elevationScale', 'coverage', 'opacity'];
const colorRange  = [
  [1, 152, 189],
  [73, 227, 206],
  [216, 254, 181],
  [216, 254, 181],
  [254, 237, 177],
  [254, 237, 177],
  [254, 237, 177],
  [254, 237, 177],
  [254, 173, 84],
  [254, 173, 84],
  [254, 173, 84],
  [254, 173, 84],
  [254, 173, 84],
  [254, 173, 84],
  [254, 173, 84],
  [254, 173, 84],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
  [209, 55, 78],
];
const getValue = (d) => {
  return d.v;
};
const deckgl = new deck.Deck({
  initialViewState: {
    longitude: 137,
    latitude: 37,
    zoom: 5,
    minZoom: 2,
    maxZoom: 8,
    pitch: 30,
    bearing: 10,
  },
  controller: true,
  layers: [tileLayer, hexagonLayer, ]
});
const renderLayer = () => {
  const options = {};
  OPTIONS.forEach(key => {
    const value = document.getElementById(key).value;
    document.getElementById(key + '-value').innerHTML = value;
    options[key] = Number(value);
  });
  hexagonLayer = new deck.HexagonLayer({
    id: 'hex',
    data,
    getPosition: ({p}) => p,
    colorRange,
    getColorWeight: getValue,
    getElevationWeight: getValue,
    elevationScale: 200,
    extruded: true,
    pickable: true,
    radius: 1000,
    opacity: 1,
    coverage: 1,
    upperPercentile: 100,
    ...options
  });
  deckgl.setProps({
    layers: [tileLayer, hexagonLayer, ],
  });
}
OPTIONS.forEach(key => {
  document.getElementById(key).oninput = renderLayer;
});
d3.json("https://covid19-japan-web-api.now.sh/api/v1/prefectures", function(error, json) {
  var keys = ["id", "name_ja", "name_en", "lat", "lng", "cases", "deaths"];
  for (var i = 0; i < json.length; i++)
  {
    var s = {
      p: [json[i]["lng"], json[i]["lat"]], 
      v: json[i]["cases"] 
    };
    data.push(s);
  }
  renderLayer();
});





```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/990b1a97-69e0-5bde-737a-42e021d9b9a6.png)


# 成果物

https://embed.plnkr.co/plunk/BNACPTSNDg1M20Oz


以上。
TypeScriptの||と??について

`||`と`??`の使い分けについて解説します。これらは演算子で、どちらも下のように使えます。
```ts
const fooLogical = hoge || 'bar'
const fooNullish = hoge ?? 'bar';
```
`||`は左の値がTruthyの値の時左の値を、Falsyの値の時右の値を返します。`??`は左の値が`null`または`undefined`の時に右の値を、それ以外の場合は左の値を返します。
例えば`hoge`が`false`の時は`||`であれば`'bar'`、`??`であれば`hoge`を返します。`null`の時は両方とも`'bar'`、`123`の時は`hoge`を返します。

それぞれの分岐を表にまとめました。`X || 'dummy'`、`X ?? 'dummy'`のような形式で実行したとします。

| `X` | `\|\|` | `??` |
| --- | --- | --- |
| `'aaa'` | `'aaa'` | `'aaa'` |
| `''` | `'dummy'` | `''` |
| `123` | `123` | `123` |
| `0` | `'dummy'` | `0` |
| `[1]` | `[1]` | `[1]` |
| `[]` | `'dummy'` | `[]` |
| `{}` | `{}` | `{}` |
| `NaN` | `NaN` | `'dummy'` |
| `null` | `'dummy'` | `'dummy'` |
| `undefined` | `'dummy'` | `'dummy'` |

`??`の場合は`null`や`undefined`の場合のみ右の値を使うと覚えておくと良いです。

## `??`をできる限り使うようにする
`||`はFalsyの値の場合はすべて右の値を返すので`string | null`のような型の値に対して行うときに空文字列であっても右の値を返すような想定外の挙動を起こすことがあります。これを防ぐためにtypescriptのeslintでは[`prefer-nullish-coalescing`](https://typescript-eslint.io/rules/prefer-nullish-coalescing/)というルールがあります。これは`??`の使用が可能なときは`??`を使うように矯正するというルールです。
以下のように`foo`が`null`の場合、文字列`'is null'`に置き換えるような関数を考えたときに
```ts
const hoge = (foo: string | null) => foo || 'is null';
```
下のように書くことを進めるようなエラー(もしくは警告)が出るようなルールです。これによって`foo`が空文字列の時に`'is null'`となってしまうことを防ぎます。
```ts
const hoge = (foo: string | null) => foo ?? 'is null';
```
もし空文字列の時も`'is null'`となってしまうことが正しい仕様の場合は一度`string | null`から`string`に型を絞ってから行う必要があります。
Lambda Cloud (GPU Cloud) API の使い方


[Lambda Cloud (GPU Cloud) の使い方](https://qiita.com/ganessa/items/1b477675c43bd29e3917)で紹介させていた[Lambda Cloud (GPU Cloud)](https://lambdalabs.com/service/gpu-cloud)ですが、
[Lambda Cloud API](https://cloud.lambdalabs.com/api/v1/docs)を使って簡単な制御を行うことが出来ます。

## cURL

### インスタンス起動

https://docs.lambdalabs.com/cloud/launch-instance-api/

※ インスタンス起動は10秒に1回と決められているようです。

https://docs.lambdalabs.com/cloud/rate-limiting/

※ インスタンスを終了させずに一時停止させることは出来ないようです。

https://docs.lambdalabs.com/cloud/pause-instance/

### インスタンス終了

https://docs.lambdalabs.com/cloud/terminate-instance-api/

※ インスタンス終了後は復旧できないようです。永続的ファイルシステムで永続的に利用できますが、全てのインスタンスタイプで利用できるわけではありません。

https://docs.lambdalabs.com/cloud/recover-data-terminated-instance/

### 起動中インスタンス一覧取得

https://docs.lambdalabs.com/cloud/list-running-instances/

### インスタンス詳細取得

https://docs.lambdalabs.com/cloud/list-details-specific-instance/

### 提供インスタンスタイプ一覧取得

https://docs.lambdalabs.com/cloud/list-offered-instance-types/

### SSHキー生成＆追加

https://docs.lambdalabs.com/cloud/api-add-ssh-key/

## Python

こんな感じの関数を作っておいて、`API_KEY`と`api`と`data`を渡してやれば呼び出せます。

```python
'''Wrapper for Lambda Cloud API
'''

import requests
import libs.env as env
import json

URL_BASE = 'https://cloud.lambdalabs.com/api/v1/'
HEADER = {
    'Content-Type': 'application/json',
}


def get(api):
    res = requests.get(
        ''.join([URL_BASE, api]),
        headers=HEADER,
        auth=(env.API_KEY, ''),
    )
    return res.json()


def post(api, data):
    res = requests.post(
        ''.join([URL_BASE, api]),
        headers=HEADER,
        data=json.dumps(data),
        auth=(env.API_KEY, ''),
    )
    return res.json()
```

[Lambda Cloud API with Python](https://github.com/ganessaa/lambda-cloud-api-python)として、SSHキー関連以外のサンプル実装を置きました。よろしければ参考にしてください。