OmniAICreator/Qiita-1.07M huggingface dataset:
ノーコードで不動産サイト作成～受注記録～ No code


こちらの[不動産サイト](https://www.ichinosekamakura.com/)立ち上げをさせて頂きました。(サイト掲載許可済)
その後は追加機能・編集をさせて頂いております。
もしくは、社長さんが自ら編集をされています。


使用したウェブサイト制作プラットフォームは、
[Strikingly](https://jp.strikingly.com/)です。

また、会社立ち上げ時に以下の作業も携わらせて頂きました。

・会社ロゴ作成(無料ロゴメーカーサイト[Hatchful](https://hatchful.shopify.com/ja?gclsrc=aw.ds&gclid=Cj0KCQjw6NmHBhD2ARIsAI3hrM0I_CVn4houxG_mNYlEvy57W3wEfP8x_IYdXdBVpNRGZV8HA2jsJ_YaArlfEALw_wcB)利用)
・店舗Google Map登録(Googleマイビジネス等登録)
・Google検索上位設定([Strikingly](https://jp.strikingly.com/)ツール)
・名刺・サイトに掲載する店舗地図(Excelで作成)
・会社名刺作成([ラクスル](https://raksul.com/)利用)
・年賀状作成([ラクスル](https://raksul.com/)利用)
・年賀状等用の名刺管理([myBridge](https://jp.mybridge.com/home)利用)
・チラシ作成([ラクスル](https://raksul.com/)利用)
・不動産サイト登録(Suumoサイト掲載)
・代表取締役写真撮影


Strikinglyを使用し良かった点は、以下の通りです。

・プレビューされながらの編集がやりやすい
・カスタマーセンターの方の返信が早い
・デザイン、テンプレートが豊富、使いやすい
・コーディングを打ち込みできる(有料版特典)
・GoogleMapなどを入れ込む作業がスムーズ
【GCP】GCPの請求先アカウントにグループアカウントを登録した時の挙動

Googleアカウントのメーリングアドレスである、グループアドレスなのですが、
これをGCPの請求先アカウントに登録したときどんな挙動になるのかまとめました。

https://dime.jp/genre/927501/

グループアドレスを登録できるのは知ってましたが、グループアドレスにはパスワードもないのにどうなるんだ？と思ってました。

グループアドレスに登録されているGoogleアカウントであれば、グループアドレスが登録されている請求先アカウントを利用することが可能です。
なので、グループアドレスでログインするのではなく、そこに登録されているアカウントでGCPにログインする感じです。
DaraFrame 行・列の削除

##概要
変数に対して**.drop( )**にインデックスまたはカラムを指定する事で削除できる。


##データフレームを作成
```python
import pandas as pd

data = {"furuits": ["apple", "orange", "banana", "strawberry", "kiwifruit"],
              "time": [1, 4, 5, 6, 3],   "year": [2001, 2002, 2001, 2008, 2006]}

df = pd.DataFrame(data)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/d739743b-f3f5-6e7f-92d9-1dd730ca6834.png)




#0行目を削除
```python
df1 = df.drop(0)
display(df1)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/22a6796d-6ac5-c28b-2807-5791144fb0fa.png)




#列の削除（第２引数にaxis=1を指定する)
```python
df2 = df.drop("year", axis = 1)
display(df2)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/76c44840-df07-0046-f495-f915db2ec3ab.png)




#まとめて削除(リストで渡す)
```python
df3 = df.drop([1, 2, 3, 4])
display(df3)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/572e4870-8b7a-d1d4-9a94-5ac90a4b924d.png)



#奇数のインデックスの行を削除
```python
import numpy as np

df4 = df.drop(np.arange(1, 5, 2))
display(df4)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/e59a7c76-f574-f5cf-0408-4f5838f3e15c.png)
MailCatcher バージョン別のインストールコマンドを公式ページから確認する方法

# 目的

- MailCatcherの公式ページから各バージョンのインストールコマンドを取得する方法をまとめる

# 方法

1. 下記にアクセスする。
    - [https://rubygems.org/gems/mailcatcher](https://rubygems.org/gems/mailcatcher)
1. 「すべてのバージョンを表示」をクリックする。

    ![mailcatcher___RubyGems_org___コミュニティのGemホスティングサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e9ff62bc-0f57-9a1b-6000-345093f88915.png)

1. インストールコマンドを知りたい任意のバージョンをクリックする。今回はバージョン0.7.1を元に解説する。

    ![mailcatcherの全バージョン履歴___RubyGems_org___コミュニティのGemホスティングサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/9049e47f-cfe4-8356-a05a-915e141db1ef.png)

1. 開いた画面の右部にある「インストール：」の下にあるコマンドをコピーすることで任意のバージョンのMailCatcherをインストールするコマンドを取得する事ができる。
1.
VSCodeのターミナルをエディタ領域に作れるようになった！

# はじめに
こんにちは。
東京五輪始まったんですね、実感がないですが、平和に終わることを祈っております :pray:

さて、先日記事にしたVSCodeのコマンドが不要になる事態が発生しました！

https://qiita.com/akitkat/items/408af4d4a4bc128c744b

そうです、ついにターミナルを`エディタ領域`に作れるようになりました！

VSCodeのリリースノートはこちら↓

https://code.visualstudio.com/updates/v1_58#_terminals-in-the-editor-area

# VSCodeのターミナルをエディタ領域に作れるようになった！
エディタ領域にターミナルを起動するコマンドはこちら↓

```
action.createTerminalEditor
```

実行結果はこちら↓

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/f3b1ab53-89bb-5fc5-f238-a0af74e4a5b0.png)

**す、素晴らしい！**

# おわりに
これは便利ですねー、今までタブで何個も開けるので、ログとかtailさせて置くときとか便利ですね、素晴らしい！:smile:

それでは！
MailCatcher バージョンを指定してインストールする

# 目的

- MailCatcherのバージョン固定インストール方法をまとめる

# 方法

- インストール時のコマンドに下記のようにバージョンを指定する。

    ```terminal
    $ gem install mailcatcher -v X.X.X
    ```

- バージョン0.7.1のMailCatcherがほしいなら下記のコマンドを実行する。

    ```terminal
    $ gem install mailcatcher -v 0.7.1
    ```
さくらレンタルサーバのプラン変更

## 概要

さくらのレンタルサーバのプランを変更した時の備忘録です。


## 前提

プラン変更前と変更後の、レンタルサーバを契約している
WordpressとLaravelアプリが乗っている
Composerがインストール済み

## メンテナンスモード

WordpressとLaravelをメンテナンスモードにします。

https://goworkship.com/magazine/wordpress-maintenance/

https://laraweb.net/practice/3115/

## Wordpressのバックアップ

All in One WP Migrationでバックアップを作成します。

https://tcd-theme.com/2019/07/all-in-one-wp-migration.html

## DBのバックアップ

mysqlのダンプを作成します。
Wordpressは上で作成したバックアップから戻せるので、Laravelで利用しているDBのみ取得します。

https://nymemo.com/mysql/301/

## 証明書のダウンロード

独自の証明書を利用している場合は、秘密鍵、中間証明書、SSL証明書をダウンロードする。
さくらの機能でLet’s Encryptを設定している場合は、再設定するばいいのでダウンロードの必要はない。

## ドメインの削除

ドメインを削除します。

## ドメインの設定

変更後のレンタルサーバに、削除したドメインを設定する。
ドメインの反映までしばらく時間がかかります。

## SSLの設定

独自の証明書はダウンロードしたものを利用して、再設定する。
他はLet’s Encryptで設定する。

https://help.sakura.ad.jp/360000338405338/

## Wordpressの復元

さくらのコントロールパネルで、Wordpressを開設する。
All in One WP Migrationプラグインをインストールして、バックアップファイルをインポートします。

### トップページ以外が404

復元は完了したが、トップページ以外が404で表示されませんでした。
以下のURLを参考に`.htaccess`を修正した解決しました。

https://wordpressdehomepage.work/all-in-one-wp-migration-%E3%81%A7404%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%8C%E5%87%BA%E3%81%9F%E3%82%89/

## DBの復元

mysqlのリストアを実行します。

## Laravelのデプロイ

デプロイ方法は省略。
`.env`の設定を間違えないように。

## メンテナンスモードの解除

WordpressとLaravelをメンテナンスモードを解除します。
以上で終わりです。

## 終わりに

さくらのコントロールパネルは、読み込み時間が長いので思った以上に時間がかかりました…。
【python】【pytest-mock】クラス外メソッドをモックにする方法

クラス外メソッドをモックにする必要があった為、その方法のメモ書き。
例として、以下の「time_util.py」があったとします。

```time_util.py
import time
def time_msec() -> int:
    return int(time.time() * 1000)
```

「time_util.py」は、pyファイルに直にメソッドが記載されているもので、
これをpytest-mockを利用して、モック化する場合に、以下の記述でモック化する事が出来ませんでした。

```test01.py（修正前）
import time_util
class Test正常系():
    def test_正常ケース(self, mocker):
        # time_msecをモックにする
        mock_test = mocker.patch("time_util.time_msec")
        mock_test.return_value = 1000
```

上記の形で実行してもコード上は実行時エラーとならず進みますが、実際にはモック化出来ておりません。
方法として、「time_util.py」をimportしている個所（※ここでは仮に、xxx_class.pyで使用しているとする）をモック化します。

```test01.py（修正後）
import time_util
import xxx_class
class Test正常系():
    def test_正常ケース(self, mocker):
        # time_msecをモックにする
        mock_test = mocker.patch("xxx_class.time_util.time_msec")
        mock_test.return_value = 1000
```

上記のような形で、うまくモック化する事が出来ました。

※まぁそもそもpyファイル内で、クラス化していないのもどうかと思うが。。
　解決した方法のメモ書き程度にとらえて頂ければ幸いです。
【 備忘録 】Twilio FAX-APIの乗換を検討

#(追記) 採用結果
2021年7月･･･公開されていた仕様書&送受信料金で選定した結果
当社ではtwilio社のFAX-APIと仕様が似ている [CloudFax](https://api-doc.cloudunion.co.jp/) を採用することにしました。ご参考までに。

#はじめに
Twilio社より2021年12月でFAX API機能の提供打ち切りアナウンスがあったため、他社FAX-APIへの乗換を検討。
さらに、2021.06.03　【再告知】Twilio Programmable Fax 提供終了のお知らせ


#候補を選定
twillio社は代替えサービスとして [InterFAX](https://support.twilio.com/hc/en-us/articles/1260800775109-Programmable-Fax-Migration-Guide-for-Upland-InterFAX) への移行を進めている様子
価格や仕様が現在のtwilio社と大きく変わると面倒なので探すことにした。
※希望は国内ベンダーから選定したいところ


#FAX-API提供会社一覧
 [InterFAX](https://support.twilio.com/hc/en-us/articles/1260800775109-Programmable-Fax-Migration-Guide-for-Upland-InterFAX)
[FaximoSilver](https://silver.faximo.jp/connect/api.html)
[CloudFax](https://cloudfaxapi.cloudunion.co.jp/)


#料金体系
|価　格|InterFAX|FaximoSilver|CloudFax|
|:---:|:---:|:---:|:---:|
|基本料|1,100円|940円|1500円|
|送信料|24.2円|12円|10円||
|受信料|11円|9円|0円|
|備　考|海外サービス(国内代理店)|送信と受信でサービスが異なる|TwilioFAXAPIと類似|

#現状比較
月間枚数
送信：30000枚
受信：8000枚
ch数：10ch

|価　格|InterFAX|FaximoSilver|CloudFax|
|:---:|:---:|:---:|:---:|
|基本料|11000円|9400円|15000円|
|送信料|726000円|360000円|300000円|
|受信料|88000円|72000円|0円|
|合　計|825000円|441400円|315000円|

#備忘録
選定の基準は下記の通りとする。

・現在の仕様と大きく異ならない
・FAX送受信の料金が安い
・サポート体制が充実している

以上の観点からFAX-APIベンダーを選定しようと思います。
MFA認証済みユーザ以外からのアクセスを拒否するS3バケットポリシー

#概要
MFA認証済みユーザ以外からのアクセスを拒否するS3バケットポリシーを記載する

## バケットポリシー
MFA認証をしていないユーザからのアクセスを拒否

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IPAllow",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucketname/*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}
```

MFA認証をして、30分以上経過しているユーザからのアクセスを拒否

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IPAllow",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucketname/*",
            "Condition": {
                "NumericGreaterThanIfExists": {
                    "aws:MultiFactorAuthAge": "1800"
                }
            }
        }
    ]
}
```

## appendix
MFA認証済み、もしくは指定のIP以外からのアクセスを拒否するバケットポリシー
参考：[指定のIPからしかアクセスできないs3バケットポリシー](https://qiita.com/mj69/items/d33483d5ed52aa21b11e)

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IPAllow",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucketname/*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                },
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "111.111.111.111/32",       # 許可するIPアドレス
                        "222.222.222.222/32"
                    ]
                }
            }
        }
    ]
}
```
gitでpushした後に取り消す方法


Revertコミットを作ってPushする
上記で紹介した「git revert」でつくった、取り消しコミットをPushする。
過去の履歴が残ったままで、比較的安全な方法。

直前のコミットを消去する
git reset HEAD^

これで一個前のコミットが消える。
その後再度pushすればいい
WindowsのPostgreSQLで初めてテーブルを作った件について

#はじめに
前回はDBをつくるところまでした。

https://qiita.com/Atsulabo/items/cfb089d1ccd5f82ab34d

今回はテーブルをつくって、出力するところまでやっていこうと思う
どんな形で出力すればいいのだろう。。。
初心者にはまだまだわからないところだらけ

#まずは作ったDBにログイン

```
psql -U （登録したロール）　(新規作成したDB)
```
無事ログイン。
テーブル作成に入ります。
とはいっても仕事で使ってるのを使うわけにもいかないので、、、

ひとまずメンバーリストというテーブル(名前はmember)を作成すると想定して作る。
id
name
age
mailaddress

上のリンクによると、数字型・文字列型があるみたいだけど、

id(char(3))
name(varchar(15))
age(varchar(3))
mailaddress(text)

という感じにする。

というわけでコマンド

```first.sql
CREATE TABLE member
(id char(3) not null,
name varchar(15) not null,
age varchar(3) not null,
mailaddress text not null);
```
コマンドで打つ場合は、Enterをおすと実行されてしまうので
Shift ＋ Enterを押して改行する点に注意。
Enterを押すと
CREATE TABLEと出て、
作れたことになります。

```
¥d
```
でテーブル一覧を開き、作られてるのを確認。
項目も確認したい場合は、下記

```
¥d　member
```

# 閑話休題　−　困ったこと
PRIMARY KEY がどれだか確認しにくい気がする。。。

そもそもSQLってみんなうち間違えないのかな。
なんかエディタっぽいのがあってそこから送信できるといいよね
→と思ったら、Visual Studio Code(今後VSCと略）でエディタがあるらしい。

https://obenkyolab.com/?p=1280#Step3_SQL

ちょうど今使ってたから超タイムリー。

ということで使ってみたが、めっちゃ素敵。
コマンドスクリプトと違って、Enterを押してもすぐ実行にならず、
SQLが間違いないか確かめて、Run Queryを押せばいいだけなのがよい。
しかも何度も使える。
コマンドスクリプトのように途中で間違えたらもう一回やり直しにならないところがすばらしい。

# データを追加する

データを追加する方法としては

１）　コマンドで直接追加
２）　CSV（エクセルとかで作る）でデータファイルを作ってそれを入れる

の２つがある。

## １）コマンドで直接追加
下記の通り。　INTOの次にTable名を書き、
VALUESの次に（）をつけて、その中に、
カラムごとの値を書いていく。

※下記の()はわかりやすく書いてるだけで、
実際に書くときには（）はつけない。

```first.sql
INSERT INTO (Table名)　Values(
　（一番左のカラムの値）,...,(一番右のカラムの値)
)
```
## ２）csvファイルは実際に作るのだけど、ちょっと作ってみた。

ここで注意することは、列名は書かないこと。
たとえばidとか名前、年とか。

いきなりデータから入力してOK。
そして、csv形式で保存する時に、必ず**UTF−8**で保存する。
ｃｓv保存してメモ帳で開いて保存画面でUTF−8を選べば良い。
エクセル上ではutf-8に変更できないらしい。

https://kenpg.bitbucket.io/blog/201601/12.html

また、ファイルパスに日本語を入れない。
そうしないとエラーになる。
またNETWORK SERVICEグループにファイルまたはフォルダの権限を付与する。
詳しくは下記。

https://qiita.com/Pirlo/items/d4c808164e3b4e55b606

そしてVSCで、
COPY (ファイル名) from (ファイルパス）　with (format csv, DELIMITER ';');
とかくと、ちょっと保存に時間がかかるが、できるようになる。

select * from (テーブル名）;で
今のデータが確認できる。　
コマンドスクリプトでなく、VSCだと、すごくわかりやすい。

これで、単独行でも、複数行でも自由自在にデータを入れられるようになった。

MySQLでもできるかどうか、次の記事で試す。
【作成中】Google Maps Platformを使ってみた

https://eng-entrance.com/linux-php-operate
https://qiita.com/sango/items/a08c5b04df7125aaaad3
https://qiita.com/Mune_robo/items/7ac7ea66ae34976aad26
https://qiita.com/Mune_robo/items/2f4f4005670a0fc6b6cd
https://ai-trend.jp/programming/python/google-natural-language-api/


以下でphp mysqlをインストール
https://blog.mktia.com/deploy-apache-web-server-on-google-compute-engine/
http://buchio.ever.jp/gce-php7-mysql-install/

PHPインストールはここがいいかも⇛		https://cloud.google.com/php/tutorials/getting-started-on-compute-engine?hl=ja
		
mapsAPIの詳細は⇛のもみる		https://www.fundely.co.jp/blog/tech/2020/02/19/180051/
		https://www.webdesignleaves.com/pr/plugins/googlemap_01.html
		https://www.apps-gcp.com/gcp-google-maps-api/
		https://www.apps-gcp.com/gcp-google-maps-api/
		https://www.webdesignleaves.com/pr/plugins/googlemap_01.html

===
ここでAPI試す
https://www.webdesignleaves.com/pr/plugins/googlemap_01.html

ポイント1
APIキーの作成部分　使い方によってどのように設定するか考える

～～～～～～～～～
###GoogleMapsAPIの概要

Google Maps Platformとは、Googleが提供するWeb地図サービスです。
Webサイトやアプリに利用するために必要なあらゆるツール（API）をご利用いただけます。
世界各国の地図やストリートビューなどを手軽に利用できる地図サービスです。

Google Maps PlatformはWebサイト、イントラ環境、アプリケーションなどのプラットフォームを問わず様々なAPI（機能）をご利用頂ける法人向け地図配信サービスです。

GCPをお申込みいただくことで、「Google Maps Platform」の請求をまとめることが可能です。
導入に向けたサポートサービスや導入後のアフターフォローも提供いたします。

https://www.zenrin-datacom.net/business/gmapsapi/


###利用開始方法
公式サイト：https://cloud.google.com/maps-platform?hl=ja
使い方：https://developers.google.com/maps/gmp-get-started?hl=ja#create-billing-account


###料金を紹介　
1 か月 $200 分まで無料
ほとんどのお客様にとって、月額 $200 のクレジットでニーズを十分満たすことができます。 予想外の料金の増加を防止するために、毎日の割り当てを設定することもできます。

支払いは従量制
料金は、契約金や解約金、または使用量上限なしで、お客様のニーズに合わせて調整できます。また、モバイルマップを無料で使用できます

https://www.zenrin-datacom.net/business/gmapsapi/price/
https://cloud.google.com/maps-platform/pricing?hl=ja


###ユースケース
https://www.zenrin-datacom.net/business/gmapsapi/
https://www.hitachi-solutions.co.jp/googlemaps/
↓
各APIの意味
https://www.zenrin-datacom.net/business/gmapsapi/function/
MSP(マネジメント・サービス・プロバイダ）の作り方

![スライド01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/af9a12d6-67c2-4d3c-979e-155d1e9245db.jpeg)
![スライド02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/4010090e-3d15-0e65-03de-746037b5645a.jpeg)
![スライド03.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/73d274f4-ff1d-14bb-577c-fb7913f7eaa9.jpeg)
![スライド04.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/f3a446e1-77fa-eef5-11ba-03b2a800a3f2.jpeg)
![スライド05.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/c02c6ab6-3090-0746-e4b6-2fa6a1050438.jpeg)
![スライド06.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/17fdefc7-7dd1-8ac1-85db-438679c921fb.jpeg)
![スライド07.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/1e18091c-8b2e-c3e4-ee73-4be70b377240.jpeg)
![スライド08.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/7e458d66-05cb-c2d9-aa15-d8f9f09c257a.jpeg)
![スライド09.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/99b2acaf-5038-b856-d463-da3fe6d9f0c1.jpeg)
![スライド10.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/aded501d-5740-4086-9f31-9ce4843b092c.jpeg)
![スライド11.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/406a8dab-ca07-4957-d46f-6dc5be7dee8a.jpeg)
![スライド12.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/c30314cb-61c3-ec64-082d-7e70bd07e596.jpeg)
![スライド13.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/7d224bb7-d7c4-5dc6-3c8b-b2e90073c6f9.jpeg)
![スライド14.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/8b38014d-d86b-9e10-c8c3-c63a726d0ae1.jpeg)
![スライド15.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/52732e6c-85f3-2f1b-63fe-a15d608dadc6.jpeg)
![スライド16.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/aed3abed-9275-badb-a23b-7358217c1f0c.jpeg)
![スライド17.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/170afd8a-de7c-3a5c-5f51-89cdbf690237.jpeg)
![スライド18.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/ee7bb65a-b88b-90d8-3a60-9c2f94e211dd.jpeg)
![スライド19.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/9fa6dd6b-b9b0-9551-57f7-b8177b536082.jpeg)
![スライド20.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/ee50da70-7fad-be8e-5584-ea19ac6eaab6.jpeg)
![スライド21.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/e860a582-7e84-54c9-d307-b4cc2e04826e.jpeg)
![スライド22.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1013247/e3744074-e2f6-5941-9fc9-c6d0cb034128.jpeg)
指定のIAMロールを持ったリソースからしかアクセスできないS3バケットポリシー

# 概要
指定のIAMロールを持ったリソースからしかアクセスできないS3バケットポリシーを記載する

## IAMロールIDの準備
バケットポリシーに設定するロールIDはAWS Consoleからは参照出来ないため、AWS CLIで取得する

```
$ rolename=ロール名
$ aws iam list-roles|jq -r '.Roles[]| select (.RoleName == '\"$rolename\"')|.RoleId'|sed "s/$/:*/g"
AROAxxxxxxxxxxxxxxxxx:*
```

## バケットポリシー

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IPAllow",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucketname/*",
            "Condition": {
                "StringNotLike": {
                    "aws:userid": [
                        "AROAxxxxxxxxxxxxxxxxx:*",  #許可するロールのロールID
                        "AROAxxxxxxxxxxxxxxxxx:*"
                    ]
                }
            }
        }
    ]
}
```

## appendix
指定IPもしくは指定ロールからのアクセスを許可する場合のバケットポリシー
参考：[指定のIPからしかアクセスできないs3バケットポリシー](https://qiita.com/mj69/items/d33483d5ed52aa21b11e)

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IPAllow",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucketname/*",
            "Condition": {
                "StringNotLike": {
                    "aws:userid": [
                        "AROAxxxxxxxxxxxxxxxxx:*",  #許可するロールのロールID
                        "AROAxxxxxxxxxxxxxxxxx:*"
                    ]
                },
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "111.111.111.111/32",       # 許可するIPアドレス
                        "222.222.222.222/32"
                    ]
                }
            }
        }
    ]
}

```
gem無し　シンプルな検索機能　ECサイト

<h2>検索機能実装</h2>

以前、ユーザーと本の投稿という検索対象が選べ、
かつ、部分一致、完全一致等、検索方法も選べる　検索機能を実装しましたが、、
今回は、それよりもっと簡単なECサイトでの商品名検索機能です。（部分一致のみ！）

もっと複雑な検索機能の実装は以下の記事↓↓

https://qiita.com/ki_87/items/8015e5942c0d6854eb25

<h2>完成イメージ</h2>

![スクリーンショット 2021-07-21 13.53.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/a267229d-8aaa-8d17-fcb0-2e1596a2354b.png)
![スクリーンショット 2021-07-21 13.53.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/5b6b5e7f-4f40-2a9e-1fb8-1da65e14c9f0.png)

<h3>コントローラー作成</h3>

通常は、

```
rails g controller searches
```
今回私はnamespace使ってるので、、

```
rails g controller public/searches
```

<h3>ルーティング</h3>

```
 scope module: :public do
     root to: 'items#top'
     get '/search', to: 'searches#search'. ＃ここです！！
```

<h3>view 検索フォームの表示のところ</h3>

```
<div class="serch_form">
    <%= form_with url: search_path,method: :get, local: true do |f| %>
    <%= f.text_field :content,placeholder:"商品名を検索"%>
    <%= f.submit'検索'%>
    <% end %>
</div>
```

前回もっと複雑な検索機能を作ってるので、この辺りはサクサク理解できました。
ユーザーの入力した検索ワードをtext_fieldでcontentして受け取っています。
そしてそれを、コントローラーへわたします


<h3>コントローラー記述</h3>


```
class Public::SearchesController < ApplicationController
    
    def search
    @content=params[:content]
    @records=Item.search_for(@content)
    
    end
    
end
```


params[:content]で、検索ワードを受けとり@contentに入れています。
そして、```Item.search_for(@content)```の値を```@records```へ入れています。
この```Item.search_for```はどこにあるかというと・・・・

```perl:item.rb
def self.search_for(content)
        Item.where('name LIKE ?', '%'+content+'%')
    end
```

検索対象であるItemモデルに書いてあります。
where~以降のところは部分一致で検索するよう定義しています。

<h3>View　検索結果を表示</h3>


```
<div class="container">
<div class="row" style="margin-top:40px;">
<div class="col-9 offset-1">
<h3 style="display:inline">検索結果</h3> 
<h6 style="display:inline;">(全<%= @records.count %>件)</h6>
<% if @records.empty? %>
  <div class="text-center" style="margin:30px;">
  <p style="color:red;">該当する商品はありません</p></div>
<% end %>

<div class="d-flex flex-row flex-wrap">
<% @records.each do |data| %>
<div class="item-image col-3" style="margin:30px 0;">
    <%= link_to item_path(data.id) do %>
    <%= attachment_image_tag data, :image, format: 'jpeg', fallback: "no_image.jpg",size:"200x200" %>
    <% end %><br>
    <%=  data.name %><br>
    ￥<%= data.taxin_price.round.to_s(:delimited) %>
</div>
<% end %>
</div>
```

<h2>終わり</h2>

<h2>検索機能のリファクタリング</h2>

コードをよりコンパクトにしました。

https://qiita.com/ki_87/items/8e690ad7cf079d8cf0d8
Android(kotlin)プログラミングで画像をDrawableからファイル名で取得したい!

#したいこと
(RecyclerViewのAdapterで)imageViewにdrawableフォルダに入れている「sample.png」を入れて表示したい
#コード
```kotlin
// ここは説明がめんどくさいから適当ににインスタンス化してるだけなので
// 適宜findViewById()等でインスタンスを取得しておきましょう
val imageView = ImageView()

// ここからがカギ!
// contextに関しても適宜その時のcontextにしましょう
// 引数に関しては「sample」のところだけ変更すれば他は変更する必要はありません
// ファイル名に拡張子は必要ありません
imageView.setImageResource(context.resources.getIdentifier("sample","drawable",context.packageName))
```

#感想
ImageViewにファイル名から画像を指定するに当たり僕のようなｸﾞｸﾞｯﾃｺﾋﾟﾍﾟﾏﾝでも分かるような文献があまりにも少なかったのでこの度記事を書きました。
なお今回の方法は@Cyber_Hacnosukeが昔作っていたアプリで使われていた方法を教えてもらい、それを僕がKotlinに直したものです(すぐ隣に本人いるんですけど一応書いておきます)。
brew installのエラー：curl: (22) The requested URL returned error: 403 Forbidden

##背景・問題
Macで　helmを導入したい！

```
$ brew install helm
```
上記を実行すると、
下記のエラーが出ました！

`curl: (22) The requested URL returned error: 403 Forbidden`

:::note alert
==> Downloading https://homebrew.bintray.com/bottles/helm-3.5.3.big_sur.bottle.tar.gz
Warning: Transient problem: HTTP error Will retry in 1 seconds. 3 retries
Warning: left.
-=O=-                                          #     #    #    #
curl: (22) The requested URL returned error: 403 Forbidden
Error: Failed to download resource "helm"
Download failed: https://homebrew.bintray.com/bottles/helm-3.5.3.big_sur.bottle.tar.gz`
:::

##原因

gitは最新ではないため、
失敗のdownload先のバージョンは3.5.3ですが、
helmで調べみると、
最新のバージョンはなんと3.6.3です！( 2021/7/21 時点 )
https://github.com/helm/helm/releases
![スクリーンショット 2021-07-21 13.56.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181748/b2be1fb4-7ab1-a6b5-e8ae-dc08da6ef830.png)

なので、
download失敗したよ！

##解決策

gitを更新しましょう！`$ brew install git ` 終わったら、再び `$ brew install helm`を実行すれば、無事にinstallできた！

```
$ brew install git    
$ brew install helm
UbuntuでのProxy関連の設定(備忘録)

# やりたいこと
Ubuntuを使っている際に、Proxy設定をしたりVPN環境下でProxy設定を無効にする必要があったりと、いろいろと設定をいじることがありその都度設定方法を調べるのが手間だったので忘れないようにまとめておく。
ちなみに、Windows10でのWSL2でUbuntu環境を構築している。

# 環境
* OS: Windows10 Enterprise / Ubuntu 20.04 STL (WSL2)
* Tools: Docker Desktop

# 設定箇所
人によって違うとは思うが、私の環境では以下が設定箇所。

* /home/{USER}/.bashrc
* /etc/apt/apt.conf
* /home/{USER}/.docker/config.json

# 設定内容
Proxy設定を有効にするには、各ファイルに以下内容を追記する。
`/home/{USER}/.docker/config.json`は`"proxies"`のブロックを追記する。
Proxy設定を無効にするには追記した部分をコメントアウトすれば良い。


`apt`はユーザ環境変数が引き継がれないため、`.bashrc`に追記しただけではProxyに阻まれる。
`sudo`にオプションで、`-E`を付けて実行すると環境変数が引き継がれるようになり、Proxyを通過できる。
設定ファイルに追記するかオプションを付けるかはお好みで。

``` /home/{USER}/.bashrc
export https_proxy="http://{PROXY_HOST}:{PORT}"
export http_proxy=$https_proxy
export HTTPS_PROXY=$https_proxy
export HTTP_PROXY=$https_proxy
```

``` /etc/apt/apt.conf
Acquire::http::Proxy "http://{PROXY_HOST}:{PORT}";
Acquire::https::Proxy "http://{PROXY_HOST}:{PORT}";
```

``` /home/{USER}/.docker/config.json
{
  "credsStore": "desktop.exe",
  "proxies": {
    "default": {
      "httpProxy": "http://{PROXY_HOST}:{PORT}",
      "httpsProxy": "http://{PROXY_HOST}:{PORT}",
      "noProxy": "{HOST_NAME}:{PORT}"
    }
  }
}
```

他のアプリケーションでも設定が必要になれば、追記していこうと思う。

とここまで書いたけど、ベストプラクティス的にはどうするのが正しいんだろう…？
とりあえずProxyを通過できると考えるのを放棄しがちだけど、もっと良いやり方があれば教えて下さい。

以上です。
指定のIPからしかアクセスできないS3バケットポリシー

#概要
指定のIPからしかアクセスできないS3バケットポリシーを記載する

**※正確なIPを設定しないと、当該バケットにアクセスが不可能となりRootユーザでバケットポリシーを削除する以外のアクセス方法が無くなるため注意する。**

## バケットポリシー

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IPAllow",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucketname/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "111.111.111.111/32", # 許可するIPアドレス
                        "222.222.222.222/32"
                    ]
                }
            }
        }
    ]
}
```

## appendix
指定IPもしくは指定ロールからのアクセスを許可する場合のバケットポリシー
参考：[指定のIAMロールを持ったリソースからしかアクセスできないs3バケットポリシー](https://qiita.com/mj69/items/d9dece37e8f04c8878af)

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IPAllow",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucketname/*",
            "Condition": {
                "StringNotLike": {
                    "aws:userid": [
                        "AROAxxxxxxxxxxxxxxxxx:*",  #許可するロールのロールID
                        "AROAxxxxxxxxxxxxxxxxx:*"
                    ]
                },
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "111.111.111.111/32",       # 許可するIPアドレス
                        "222.222.222.222/32"
                    ]
                }
            }
        }
    ]
}

```
WindowsのSourceTreeでCodeCommitに接続

# 概要
WindowsのSourceTreeで、AWSのCodeCommitにSSH接続する方法です。

# 環境
- Windows 10
- SourceTree Ver.3.4.3

# 前提
AWSでCodeCommitを使用する権限を持つアカウントがあることを前提とします。

# 作業手順

1. パブリックキー・プライベートキーのセットアップ
AWSの[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-ssh-windows.html)の手順に沿って設定を行います。

1. SourceTreeでの設定
ツール > オプションから、「SSHクライアント」で「OpenSSH」を選択し、
その上の「SSHキー」で、手順1にて作成したプライベートキーファイルを選択します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367596/d53cfdc7-7c36-d165-ae07-29d5a05ec6ae.png)
以上です。
U-Net紹介

#1.
こちらはU-Netの構造です。形は英語のUと似てるから、U-Netと呼ばれました。U-Netの当時の意図は医学的画像セグメンテーションを行うことです。
![u-net-architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1668082/5fc9fe68-3e88-66e0-8628-060d0a4d628d.png)
　　　　　　　　　　　　　　　　　　　　　　U-Net構造
#2.
U-Netの特徴は主に二つあります。一つ目はEncoder-Decoderの簡単な構造です。このようなAutoencoder構造は信頼性が高くて、セグメンテーションで人気のあるネットワークです。セグメンテーションネットワークに関して、いろんなモデルはUnetに基づいたんです。二つ目の特徴はcopyとcropという手法です。Encoderに生成された特徴マップをcopyし、crop（サイズが違う）してDecoderの特徴マップと連結することです。Skip　Connectionともいわれます。EncoderとDecoderは同じ4層です。なぜ４層なら、この細胞のデータに一番有効であると考えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1668082/346ad313-abcb-d89a-94f4-ba39725beadb.png)
#3.
元論文の入力画像のサイズの設定です。元論文の画像サイズは512*512です。トリミングされた画像なので、こちらの境界は実際の境界ではありません。欠落しているコンテキストは、ミラーリングすることによって補完しました。そして、入力画像のサイズは572*572になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1668082/ee769f7f-1bd2-b5ff-db09-302f4f9e1766.png)
#4.
こちらは描いたU-Netの特徴マップのフローチャートです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1668082/1d49f1fc-0292-e409-4848-f746d3377945.png)
Yahoo Web API で 郵便番号から住所を取得

このAPIの素晴らしいところは、その住所から最寄りの駅まで取得できる。

今回は、
・curl を使って取得し
・ユーザーの町名以外の部分まで表示したいので、詳細住所はカット
・pref 東京都（県）city 銀座 エリア

に分けて取得する。

`$app_id` は変更して下さい。


```hoge.php

//        $sentence = "1040061";//ハイフンあり、なしどちらでも結果一緒
        $sentence = "4530013";//ハイフンあり、なしどちらでも結果一緒

        $api = 'https://map.yahooapis.jp/search/zip/V1/zipCodeSearch';
        $app_id = 'xxxPUdNS3BGbmhjdE5RNCZzPWNvbnN1bWVyxxxcmV0Jng9MDc-';//Yahoo Developer の アプリケーションID

        $params = [
            'query' => $sentence,
            'detail' => 'full'//詳細住所まで取得
        ];

        $ch = curl_init($api);
        curl_setopt_array($ch,
            [
                CURLOPT_POST           => true,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_USERAGENT      => "Yahoo AppID: ".$app_id,
                CURLOPT_POSTFIELDS     => http_build_query($params),
            ]
        );

        $result = curl_exec($ch);
        $res = simplexml_load_string($result);

        curl_close($ch);


        var_dump($res);//取得したものをとりあえず、全て表示
        
        $area = [];
        foreach ($res->Feature->Property->AddressElement as $v) {
            $tmp = (array)$v->Name;//objectを配列に変換
            $tmp = array_shift($tmp);
            $area[] = $tmp;
        }

//        住所表示用に特定されないっように最後の住所（町名）をカット
        array_pop($area);
        $pref = array_shift($area);
        $area = join("",$area);




//        都道府県
        print_r($pref);

//        それ以下の住所
        print_r($area);




```


以上
gitコマンドの備忘録

たまにしか使わなくて忘れるけど、都度検索するのが面倒なので自分用のまとめ

## 実行権限付与
```
find . -name "*.sh" -not -path "*/node_modules/*"  | xargs git update-index --add --chmod=+x
```

## リモートのタグを削除
```
git push --delete origin v0.0.0
```

## ブランチ切り替え、無ければ新規作成
リモートがあればリモートに、無ければ新規作成してリモートにもpushする

```
git checkout $branchName || { git checkout -b $branchName; git push origin $branchName; }
```

## 変更があればコミット
```
git add .
git diff-index --quiet HEAD || git commit -m "commit message"
```

## developにマージ済のブランチと、リモートで削除済のブランチを削除
```
git checkout develop
git pull
git branch --merged | grep -vE '^\*|master$|develop$' | xargs -p -I % git branch -d %
git fetch -p
```
3.2(標準) 二項係数，二項定理

## 方針

二項係数の公式と二項定理について解説する．

### 二項係数

---

```math
{}_nC_r={}_nC_{n-r}
```

→n個から選ばれたr個の組み合わせの総数は，選ばれなかったn-r個の組み合わせの総数に等しい．

```math
{}_{n+1}C_r={}_nC_{r-1}+{}_nC_r
```

→Aさんを含むn+1人からr人選ぶ組み合わせの総数は，「Aさんを選ぶ時，Aさん以外のn人から残りのr-1人を選ぶ組み合わせの総数」と，「Aさんを選ばないとき，Aさん以外のn人から残りのr人を選ぶ組み合わせの総数」の和に等しい．

```math
r{}_nC_r=n{}_{n-1}C_{r-1}
```

→n人からr人選んでその中から代表者を一人選ぶ組み合わせの総数と，n人から代表者を一人選んで残りのr-1人を選ぶ組み合わせの総数は等しい．

---

### 二項定理

---

```math
(a+b)^n=\sum_{k=0}^n{}_nC_ka^kb^{n-k}
```

---

本問では，二項係数の公式に加え2.6で見た和の公式(平行移動)も用いる．

## 答案

```math
\begin{align}
{}_nC_r&= \frac{n!}{r!(n-r)!}\\
{}_nC_{n-r}&= \frac{n!}{(n-r)!r!}
\end{align}
```

より，

```math
{}_nC_r={}_nC_{n-r}
```

が成り立つ．また，

```math
\begin{align}
{}_{n-1}C_{r-1}+{}_{n-1}C_r&= \frac{(n-1)!}{((r-1)!(n-r)!}+\frac{(n-1)!}{r!(n-1-r)!}\\
&= \frac{r(n-1)!+(n-r)(n-1)!}{r!(n-r)!}\\
&= \frac{n!}{r!(n-r)!}\\
&= {}_nC_r
\end{align}
```

が成り立つ．次に，数学的帰納法によって二項定理を証明する．

(i)n=1の時，

```math
(a+b)^1={}_1C_0a^0b^1+{}_1C_1a^1b^0=a+b
```

(ii)n=mの時，

```math
(a+b)^m=\sum_{k=0}^m{}_mC_ka^kb^{m-k}
```

が成り立つと仮定する．両辺に(a+b)を掛けて，

```math
\begin{align}
(a+b)^{m+1}&= (a+b)\{\sum_{k=0}^m{}_mC_ka^kb^{m-k}\}\\
&= \sum_{k=0}^m{}_mC_ka^{k+1}b^{m-k}+\sum_{k=0}^m{}_mC_ka^kb^{m-k+1}\\
&= a^{m+1}+\sum_{k=0}^{m-1}{}_mC_ka^{k+1}b^{m-k}+b^{m+1}+\sum_{k=1}^m{}_mC_ka^kb^{m-k+1}\\
&= a^{m+1}+\sum_{k=1}^m{}_mC_{k-1}a^kb^{m-k+1}+b^{m+1}+\sum_{k=1}^m{}_mC_ka^kb^{m-k+1}\\
&= a^{m+1}+b^{m+1}+\sum_{k=1}^m({}_mC_{k-1}+{}_mC_k)a^kb^{m-k+1}\\
&= a^{m+1}+b^{m+1}+\sum_{k=1}^m{}_{m+1}V_ka^kb^{m-k+1}\\
&= \sum_{k=0}^{m+1}{}_{m+1}C_ka^kb^{m-k+1}
\end{align}
```

より(m+1)の時も成立．以上より，帰納的に二項定理が証明された．

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
[UE4] [UE5] AnimNodeのAlpha Scale Bias Clampを使って滑らかなブレンド処理を簡単実装しよう！

# はじめに
AnimGraphにおける各ノードのON/OFFをノードのAlphaで制御している方はそれなりに多いかと思います。
![lookat2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/4f44d43a-1bc8-747e-db40-eb654d4e8f8e.gif)

この方法は非常に簡単で便利なのですが、Alphaに0, 1で値を渡すとON/OFFの切り替わりがバレバレになってしまいます。そのため、EventGraph側でAlphaの値を0, 0.1, 0.2 ... 1 といった感じで滑らかに変化させたり、Blend用の各ノードを併用したりして切り替わりが分からないようにする必要があります。

**めんどくさいですね！！！**
**処理的にも無駄な感じがプンプンします！**

そんなときに便利なのが今日ご紹介する**Alpha Scale Bias Clamp**です。これを使うことで上述のような対応を入れなくても、以下のように自動的にスムーズに切り替え・ブレンド処理を行ってくれます。

![lookat5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/2941994f-3464-0ec7-ecdd-beed4873aa32.gif)

なお、この機能はUE4.25, UE4.26, UE5早期アクセスで動作することを確認済みです。

# Alpha Scale Bias Clamp の使い方
使い方は非常に簡単で、AnimNodeの詳細パネルの下の方にあるInterp Resultを有効にするだけです。これにより、Alphaに渡す値が変化したときに補間を行ってくれます。言い換えると「EventGraph側でAlphaの値を0, 0.1, 0.2 ... 1 といった感じで滑らかに変化」をAnimNode側でやってくれます。
更に、Interp Speed Increasing(Decreasing)から補間の速度を変更することも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/4b5d1a72-1d80-7f2d-7a2d-fdc3f216bf4c.png)

補間処理だけでなく、入力値に対してScale, Biasを追加したり、Alpha Scale Bias ClampではMap Changeにより入力値を指定の範囲に変換したり、Clamp ResultによりAlphaの上限・下限値を設定することもできます。

これらの処理をEventGraph側でやるのは面倒な上にGameThreadで実行することになるのでパフォーマンスに影響してしまいます。ですので、もし単純な補間・ブレンドで問題ない場合は是非この機能を活用してみてください！


# 参考
以下の動画にて紹介されていたTipsが非常に有用だったので記事にしてみました
Motion Warping and Full-Body IK | Inside Unreal　(1:32:00あたりから)
https://youtu.be/SM_AR-oZ-1k?t=5527


おしまい
Garminのアプリの開発環境Connect IQをVSCodeで構築する

# はじめに
GarminのWatchFaceやAppを開発するための開発環境をVS Codeで構築したので、構築手順をまとめていきます。

この記事を最初に投稿した2021年7月21日時点ではGarmin公式ではEclipceをサポートしており、VSCodeは公式にはサポートしていませんでした。
しかし、2022年4月3日時点でGarminは公式にVSCodeをサポートをするようになっており、[公式ページの環境構築方法](https://developer.garmin.com/connect-iq/reference-guides/visual-studio-code-extension/)を参考に、今回は構築を進めていきます。

使用環境
- OS: Windows 11 Home 21H2
- PC: Dell Inspiron 13

# 目次
[1.Visual Studio Codeのインストール](#visual-studio-codeのインストール)
[2.Monkey CのExtentionのインストール](#monkey-cのextentionのインストール)
[3.Connnect IQ SDKのインストールとセットアップ](#connnect-iq-sdkのインストールとセットアップ)
[4.VSCode上での作業](#vscode上での作業) 
[5.さいごに](#さいごに)


# Visual Studio Codeのインストール

すでにVSCodeを使用している人が大半だと思いますが、[こちら](https://code.visualstudio.com/download)からダウンロードしセットアップします。

# Monkey C Extentionのインストール

Monkey Cのダウンロードは[こちら](https://marketplace.visualstudio.com/items?itemName=garmin.monkey-c)からです。
リンク先のインストールをクリックすると、VSCode上でMonkry Cのインストールが開始します。

非公式のMonkry CのExtentionも存在し、しかも公式版よりも評価が高いので、VSCodeのExtentionの検索バーから普通に検索すると非公式版が公式よりも上位に表示されるので注意が必要です。
 
# Connnect IQ SDKのインストールとセットアップ

Connect IQ SDKは[Garmin公式ページ](https://developer.garmin.com/connect-iq/sdk/)から.exeをダウンロード可能です。

※注意: VSCode上でConnect IQ SDKを動作させるために、version 4.0.6以上である必要があります。これまでにEclipceで開発をされていた方も、再度バージョンの確認が必要です。 

ダウンロードできたら、./sdkmanager.exeを実行後、表示されるポップアップに従ってSDKのセットアップを進めていきます。

# VSCode上での作業
最後に、VSCode上の作業です。
はじめに、公式サイトの手順通りに、Ctrl+Shift+Pでコマンドパレットを呼び出し、Monkey C: Verifi Installationを実行します。
実行すると、developer keyの入力を求められますが現時点でkeyを持っていないと思うので、まずはGenerate a Developer KeyをクリックしKeyを生成し、任意のフォルダにkeyを保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786422/2993db14-15ff-5382-f7df-bf76dd29a2ca.png)

基本的な環境構築に必要な作業は以上になりますが、最後に１つだけ事前に設定しておきたい項目があります。
VSCodeのツールバーのRun > Add Configuration をクリックすると、作業フォルダにlaunch.jsonが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786422/f9a7b292-5156-1691-cfba-9f55d66c3943.png)
次に、コマンドパレット(Ctrl+Shift+P)を開き、Monkey C: Set Products by Product Categoryを実行します。
すると、Button WealablesとTouch Wealabelsの２つが表示されるので、２つともチェックを入れ、OKを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786422/dbd4a76f-84d6-62dc-d832-8169ba3c3c3d.png)

以上で、VSCode上でGarmin Appのコードの動作に必要な環境構築が完了です。これまでEclipceでしか使用できなかったSimulatorもVSCode上で使用することができます。


# さいごに

これまでEclipseのセットアップが面倒な方やそもそもEclipseが苦手でGarmin Appの開発に二の足を踏んでいた方にとって今回Garmin SDKがVSCode対応を始めたことで、ウェアラブル端末の開発コミュニティが盛り上がってくれると嬉しいです。
Bigqueryで使用したbqコマンド

```

ログイン
gcloud auth login

gcloud config set project kaggle-rec-hoge
最後はプロジェクトID

bq help
bq help ls

データセット一覧
bq ls

テーブル一覧
bq ls recruit

プロジェクト一覧
>bq ls -p
        projectId            friendlyName
 ----------------------- ---------------------
  kaggle-rec-hoge   Kaggle-rec
  my-project-khoge     My Project Khoge

USロケーションにデータセットを作成するコマンド
$ bq mk --data_location=US new_dataset

bq mk データセットID.作成したいテーブル名
bq mk kaggle-rec-hoge:new_dataset
bq mk kaggle-rec-hoge:new_dataset.new_table
# idじゃなくてもいけるっぽい
bq mk new_dataset.new_table2

bq –dataset_id=データセットID mk テーブル名
bq –dataset_id=kaggle-rec-hoge:new_dataset mk NEWTABLE

bq rm dataset_sample
# データセットIDでなくて、データセットの名前でも行けたが、IDのほうが安全な気はする
bq rm new_dataset.NEWTABLE
bq rm kaggle-rec-hoge:new_dataset.NEWTABLE

データセットとテーブルをまとめて削除するためのコマンド
$ bq rm -r dataset_sample
-f 

GCS上のCSVファイルをBigQueryのテーブルとしてインポートするコマンド

bq help load | findstr \--
bq help load | findstr auto

bq --location=LOCATION load \
--autodetect \
--source_format=FORMAT \
DATASET.TABLE \
PATH_TO_SOURCE
次のように置き換えます。

LOCATION: ロケーションの名前。--location フラグは省略可能です。たとえば、BigQuery を東京リージョンで使用している場合は、このフラグの値を asia-northeast1 に設定します。ロケーションのデフォルト値は、.bigqueryrc ファイルを使用して設定できます。
FORMAT: NEWLINE_DELIMITED_JSON または CSV。
DATASET: データの読み込み先のテーブルを含むデータセット。
TABLE: データの読み込み先のテーブル名。
PATH_TO_SOURCE: CSV または JSON ファイルの場所です。

bq load --autodetect --source_format=CSV new_dataset.air_store_info gs://kag-recruit/input/air_store_info.csv

bq rm -r new_dataset2
```
夏休みの自由研究　作・古川　清玄

#自動車の「走る・曲がる・止まる」の構造と仕組み
##0.自動車の構造と仕組みを調べようと思った理由
#####僕が自動車の構造と仕組みを調べようと思った理由は、将来、ハードウェアエンジニアになって自動車を作りたいと思っているから、簡単な構造や仕組みは知っておきたいと思ったから。
##1.<font color="ff0000">「走る」仕組み</font>
![自由研究.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786503/a37a880f-2bf1-5ffe-c1d9-bd9b262eba37.jpeg)
#####自動車はガソリンや軽油を燃料とし、下記の４つの工程によってエンジン内で発生したパワーで走ります。

###<font color="ffC0Cb">ピストンが下がり吸気バルブが開く</font>
#####エンジン内の部品の1つ「クランクシャフト」が回転すると吸気バルブが開きます。するとピストンが下がるので、燃料タンクから送られてきたガソリンや軽油、空気などがシリンダーに送り込まれます。

###<font color="ffC0Cb">ピストンを押し上げ混合気を圧縮する</font>
#####更にクランクシャフトが回転すると、ピストンが上がり燃料と空気が混ざった「混合気」が圧縮され、混合ガスとなります。

###<font color="ffC0Cb">点火プラグからの火花で爆発を起こし自動車を動かす</font>
#####圧縮されて発生した混合ガスに点火プラグからの火花で着火し、爆発が起こります。この爆発によって混合ガスが膨張されることでピストンが降下し、クランクシャフトが推進軸の回転に働きかけ、自動車を走らせるのです。

###<font color="ffC0Cb">排気バルブが開き混合ガスを排出する</font>
#####更にクランクシャフトが回転すると排気バルブが開き、燃えた混合ガスが排出され、ピストン が上がります。この排出された混合ガスが「排気ガス」であり、二酸化炭素や炭化水素、窒素酸化物、一酸化炭素が含まれています。

#####この一連のピストンの上下運動がエネルギーとなり、自動車を動かす力となっています。
***
##2.<font color="0000ff">「曲がる」仕組み</font>
![自由研究２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786503/bcecad83-7fa8-ddbb-9896-a5e6400a4edd.jpeg)
#####自動車はドライバーがハンドルを回さない限り曲がりません。そして、ハンドルを切った状態から手を放しても、自動車が直進するように戻ります。これは、タイヤにかかる駆動力が左右均等に伝わるように作られているからです。

###<font color="add8e6">並行運動を利用したハンドルの動きで曲がる</font>
#####ハンドルを回すと「ステアリングシャフト」に回転運動が発生します。この回転運動が「ステアリングギアボックス」で並行（左右の往復）運動に変換されると、タイヤにつながる棒状の部品「タイロッド」が引っ張られます。この並行運動によってタイヤの角度が変わることで自動車が左右に曲がるのです。
***
##3.<font color="ffda03">「止まる」仕組み</font>
![自由研究４.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786503/1aa8ec7b-404a-a5e9-c245-7b73eef58ee4.jpeg)

###<font color="ffa500">制動力・放熱性などに優れているディスクブレーキ</font>
#####ディスクブレーキを踏むと、タイヤと共に回転している「ディスクローター」という部品がブレーキパッドで抑えられます。そのときに発生した摩擦力によって、自動車が減速したり停止したりする仕組みとなっています。
#####ディスクブレーキのメリットは、安定した制動力や優れた放熱性、水分が付着しても回転の遠心力によって弾いたり乾燥させやすいことです。

###<font color="ffa500">安定した制動力を持つドラムブレーキ</font>
#####一方ドラムブレーキは、車輪の内側に設けた「ブレーキシュー」を、内側から外側へ強く押し付けることで、制動力が発揮する仕組みとなっています。
#####構造が簡易なため低コストというメリットがありますが、発生した熱が放出されにくいデメリットが挙げられます。また、ディスクブレーキよりも強いブレーキがかかるため、急ブレーキがかかりやすくなるという特徴も。1970年代頃まではこのドラムブレーキが主流となっていました。
***
##4.感想
#####走る仕組みはなんとなく知っていたけど、曲がる仕組みや、止まる仕組みは知らなかったので、知れてとても良かった。
Unity Editor拡張 Attribute

Attribute
---

編集はできないが表示はされるAttributeの作成


ReadOnlyAttribute.csを作成し、下記ソースを記述



```C#:ReadOnlyAttribute
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//<summary>
//ReadOnlyというAttributeを定義するためのクラス
//クラス名に「Attribute」を入れる必要がある
//</summary>

#if UNITY_EDITOR
using UnityEditor;
#endif

public class ReadOnlyAttribute : PropertyAttribute
{
    
}

#if UNITY_EDITOR
[CustomPropertyDrawer (typeof (ReadOnlyAttribute))]
public class ReadOnlyAttributeDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginDisabledGroup(true);
        EditorGUI.PropertyField(position, property, label, true);
        EditorGUI.EndDisabledGroup();
    }
}
#endif
```


別のスクリプトに下記ソースを記述



```C#:ExampleAttribute
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExampleAttribute : MonoBehaviour
{
    [ReadOnly]
    public int ReadOnlyPublicInt;

    [SerializeField, ReadOnly]
    private int ReadOnlyPrivateInt;
}
```



結果
![658059F7-E7B6-4273-A239-74DC9C2725F2_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/1eaae3a0-e3c7-0b6c-36d1-b7bd7de05720.jpeg)
NSArrayにnilを入れても落ちない理由

```objc
NSString *nilString;
NSArray *array = @[@"hogehoge", nilString, @100];
```

なんてことをすると、

```terminal
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[1]'
```

と落ちちゃうので、`落ちない == nilは来てない`と思い込んでいたら、

```objc
NSArray *array = [NSArray arrayWithObjects:@"hogehoge", nilString, @100, nil];
NSLog(@"%@", array);
//=>(
//=>    hogehoge
//=>)
```

こんな懐かしい書き方をしているものだから、`nilString`が終端になっていて落ちない & `nilString`以降が切り捨てられている、という状況でした。


おしまい
マーケティングコンテンツの作成 ⇒ コンテンツの価値の理解

１．メールマーケティングコンテンツに価値があるのはなぜですか?
２．コンテンツマーケターが直面している課題は次のどれですか?
３．顧客に対する共感を持つことが重要なのはなぜですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/f51d5c74-a590-8268-bd7a-0f21a4e6aec5.png)
【Google Cloud Day'21】「大規模 Agile 組織の Multi Cloud 運営について」を視聴して

大規模 Agile 組織の Multi Cloud 運営について
"Tech ベンチャーである 3-Shake はミッション クリティカルな金融決済領域を NTTデータと協業し複数のクラウドを活用して運用しております。
その中で組織の構築・運営を実施する為に取り組んできた SRE の活動や Google Cloud /AWS を用いて組織 DX において目指している Cloud Native な世界への挑戦をテクノロジー目線でお送りいたします。"
https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d3-gl-25

<table>
	<tr>
		<th>切り口</th>
		<th>内容</th>
	</tr>
	<tr>
		<th>会社概要</th>
		<td></td>
	</tr>
	<tr>
		<th>NTT data 3shale間のやりとり</th>
		<td></td>
	</tr>
	<tr>
		<th>事例</th>
		<td></td>
	</tr>
	<tr>
		<th>アジャイルチームについて</th>
		<td></td>
	</tr>
	<tr>
		<th>single cloudの限界</th>
		<td></td>
	</tr>
	<tr>
		<th>今後について</th>
		<td></td>
	</tr>
</table>
【Google Cloud Day'21】「DeNA ゲーム基盤における Google Cloud Spanner の活用事例」を視聴して

DeNA ゲーム基盤における Google Cloud Spanner の活用事例
https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d2-da-05
DeNA の新ゲーム基盤である Takasho・LCX について、アプリケーションのインフラ構成（GKE・GAE）も開発言語（Go・Java）も違う中で、それぞれデータインフラとして Google Cloud Spanner を選択した経緯、および実際に開発・運用をした中で得られた知見や使用感をご紹介します。

<table>
	<tr>
		<th></th>
		<th></th>
	</tr>
	<tr>
		<th>質問</th>
		<td>返答</td>
	</tr>
	<tr>
		<th>Spannerはシングルリージョン、マルチリージョンどちらを選択されたでしょうか。また、選択理由についても教えてください。</th>
		<td>Spanner はシングルリージョンで使用しています。これはマルチリージョンではシングルリージョンに比べ書き込みレイテンシが遅く、ビジネス上の要件を満たさないと判断したためです。</td>
	</tr>
	<tr>
		<th>spilitの一部ノードへの偏りの理由はなんだったでしょうか。また、どのように対応されたでしょうか。</th>
		<td>データが入っていない状態からノード数をいきなり増やしたことで、負荷ベース/データサイズベースどちらのSplitもつくられなかったことが原因と考えられます。対応としては、徐々に負荷をかけました。</td>
	</tr>
	<tr>
		<th>中国側のデータベースはRDBMSを利用されてるとのことですが、そちらは手動でのシャーディングや負荷分散を行なっているのでしょうか。またGCP側のデータベースもCloud SQLやGCE上でRDBMSを構築することで中国側と統一するという方法も検討されたのでしょうか。</th>
		<td>中国側のデータベースも自動シャード・負荷分散するマネージドサービスを利用しています。GCP側のデータベースは大規模トラフィックの中で高可用性を保つ要件、また保守コストを少なくする目的から、Cloud SQL や GCE 上で自分でクラスタをマネージする選択は技術選定時点で外していました。</td>
	</tr>
</table>

<table>
	<tr>
		<th>切り口</th>
		<th>内容</th>
	</tr>
	<tr>
		<th>ゲーム基盤について</th>
		<td>中国ではGCPが使えないらしい</td>
	</tr>
	<tr>
		<th>比較</th>
		<td></td>
	</tr>
	<tr>
		<th>takashoについて</th>
		<td></td>
	</tr>
	<tr>
		<th>なぜCloudSpannerを導入したか</th>
		<td></td>
	</tr>
</table>

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/e093c6d4-b2cf-f895-0bcc-2765ddacb0fc.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/f679653c-c371-21d8-c3ce-b0392bcb2fb8.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/ef0404e7-ad26-79f0-db3c-28e684a752d0.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/79a6353b-49ba-2d1b-648a-0bcbb0b8ce4c.png)
Pythonで数値などを文字列にくっつけるまとめ

ざっくりまとめ＆リンク集的なものです。

下の「コードの例」はresultが文字列型なら `"今回の結果は: " +  result`でうまくいくやつです。

方法名|コードの例|詳しいことが書いてあるページ
----|----|----
キャスト|"今回の結果は: " +  str(result)|-
f文字列|f"今回の結果は: {result}"|https://note.nkmk.me/python-f-strings/
フォーマット関数|"今回の結果は: {}".format(result)|https://www.atmarkit.co.jp/ait/articles/1904/23/news015_4.html
書式化演算子|"今回の結果は: %s" % (result)|https://www.javadrive.jp/python/string/index23.html


最近、研修中に見かけたんですが、コードの最中に`str = 1`みたいなことを書くと`str(1)`みたいなことができなくなるんで注意ですね。
Unity Editor拡張(SerializeField)

SerializeFieldでのEditor拡張
---

例


```C#:Editor
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Editor : MonoBehaviour
{
    //SerializeField
    public int public_int;

    [SerializeField]
    private int private_int;

    [SerializeField]
    protected int protected_int;

    //インスペクタ上では「m_」は消える
    [SerializeField]
    private int m_int;

    [SerializeField]
    private int[] intArray;

    [SerializeField]
    private List<GameObject> GameObjectList;


    //Range
    [Range(1, 10)]
    public int RangeInt;

    [SerializeField, Range(-1f, 1f)]
    private float rangeFloat;


    //Tooltip
    [SerializeField, Tooltip("整数の値")]
    private int intValue;


    //Header
    [SerializeField, Header("浮動小数点数型です")]
    private float floatValue;


    //Space
    //密集している時などにスペースを空けると見やすい
    [SerializeField]
    private int intValue1;

    [SerializeField, Space(10)]
    private int intValue2;

    [SerializeField]
    private float floatValue1;

    [SerializeField, Space(20)]
    private float floatValue2;

    [SerializeField, Multiline(3)]
    private string stringValue;


    //TextArea
    //テキストフィールド、最小値と最大値を設定できる
    [SerializeField, TextArea(2, 4)]
    private string stringValue1;


    //HideInIndpector
    //SerializeFieldで値は保持しておきたいが、インスペクタから表示を隠したいとき
    [HideInInspector]
    public int intValueH;

    //HideInInspecterを使うとHeaderも見えなくなる
    [SerializeField, HideInInspector, Header("aaa")]
    private float floatValueH;
    
}
```



結果
![FACE43EC-1030-4177-8DDD-0938CE778283_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/91ad6162-a069-5247-8c64-416b648bc403.jpeg)
IPアドレスでアクセスで制限を行う【Rails】

### 目的
自分のポートフォリオサイトを作る時に、
作品投稿画面に遷移できるIPアドレスを制限したかった為実装しました。

・開発している環境下でのみのIPアドレスを許可したい。
・指定したIPアドレス以外はリダイレクトでroot_pathに戻したい。

### request.ip を使ったメソッドをコントローラーに記述
コントローラーの　private　メソッド以下に以下の記述をおこないます。

```ruby:sample_controller.rb
 private

  def client_ip
    request.ip
  end
```
以上の記述だけで、クライアントのIPアドレスを取得できます。

試しに、indexアクションでインスタンス変数に入れてみます。

```ruby:sample_controller.rb
def index
  @ip = client_ip
end
```
viewに読み込んでみます。

```ruby:index.html.erb
 <%= @ip %>
```
すると、

![ed300e8acc07a4d358b34eadb52b81e9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1420298/84fe3c00-cba7-097a-deff-6d218b11dc10.png)

::1と出力されました。
ローカルだと ::1 という値が取得されるようです。
heroku などにデプロイすると、クライアントのIPアドレスを取得できます。

### if文　を使ったメソッドをコントローラーのprivateに定義

```ruby:sample_controller.rb
 private

  def client_ip
    request.ip
  end

  def judge_ip
    if client_ip == "::1"
    elsif client_ip == "123.456.789.10"
    else
      redirect_to root_path
    end
  end
```

このように記述すれば、開発環境と、指定したIPアドレスでのアクセスのみ　true となり、
それ以外は、ルートパスにリダイレクトされる筈です。
この処理をアクションに定義してみます。

```ruby:sample_controller.rb
def new
  judge_ip
end
```

ローカル環境では、
if client_ip == "::1"　を　 "::2"
などに変えて試してみてください。
するとリダイレクトされる筈です。

Wi-Fi環境の場合は、PCでもスマホでも同じIPアドレスとなるので、
スマホのWi-Fiを切ってからアクセスすると、制限がかかっていることが確認できます。

念の為、自分のIPアドレスは環境シェルに格納しました。

セキュリティの知識が少ない為、別の方法の方が良いなどのアドバイスがあれば、
ご教授いただけると助かります。:relaxed:
Ant DesignのUIを日本語化する

この投稿ではAnt DesingのUIを日本語化する方法を説明します。ここで示すコードサンプルはNext.js+TypeScriptでの実装例です。


## Ant DesignのUIを日本語化する方法

日本語化するには、`ConfigProvider`に日本語翻訳データ`"antd/lib/locale/ja_JP"`を渡すだけです:

```tsx:pages/_app.tsx
import { ConfigProvider } from "antd";
import jaJP from "antd/lib/locale/ja_JP";

// ...

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ConfigProvider locale={jaJP}>
      <Component {...pageProps} />
    </ConfigProvider>
  );
}
```


翻訳できているか、試しにフォームを作って確認します:

```tsx:pages/equipments/new.tsx
import { Button, Form, Input } from "antd";

const { Item } = Form;

export default function New() {
  return (
    <Form>
      <Item name="name" label="名前" rules={[{ required: true }]}>
        <Input />
      </Item>
      <Item wrapperCol={{ offset: 8, span: 16 }}>
        <Button type="primary" htmlType="submit">
          保存
        </Button>
      </Item>
    </Form>
  );
}
```

このフォームを送信してみると、バリデーションエラーの文言が日本語化されているのが分かります:

<iframe width="560" height="315" src="https://www.youtube.com/embed/Ygl90wcn0P0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


翻訳されるのはAnt Designのコンポーネントのメッセージだけのようで、アプリ固有の翻訳はAnt Design自体はサポートしていないようです。


この投稿で扱ったコードを含んだアプリ全体のコードはGitHubでご覧いただけます:

https://github.com/suin/nextjs-ant-design-typescript/tree/98cd16216c31ca0cc0d140fe28b2e1dcb0af8840

サンプルで作ったフォームの動作デモはVercelにホスティングしてあるので試せます:

https://nextjs-ant-design-typescript-8mkyb76oi-suin.vercel.app/equipments/new
phpでLEFT関数とRIGHT関数

ExcelにあってphpにはないLEFT関数とRIGHT関数がほしかったので。

```php:my_function.php
function left($str, $num, $encoding = "UTF-8"){
    return mb_substr($str, 0, $num, $encoding);
}

function right($str, $num, $encoding = "UTF-8"){
    return mb_substr($str, $num * (-1), $num, $encoding);
}

echo left("あいうえお", 3);  // → あいう
echo right("あいうえお", 3); // → うえお
```