OmniAICreator/Qiita-1.07M huggingface dataset:
FigmaのInteractive componentsでMaterial-UIのText Fieldを再現してみる

## これは何

- タイトルの通り、FigmaのInteractive componentsでMaterial-UIのText Fieldの変化を再現してみた記事です
    - 一部再現しきれていませんが、パッと見はかなり近いものができたと思います
- また「[3000文字Tips - 知ると便利なTipsをみんなへ届けよう](https://qiita.com/official-events/d523df99d6479293ffa7)」イベントへの投稿記事でもあります

## そもそもMaterial-UIのText Fieldってどんなもの

https://material-ui.com/components/text-fields/

公式ドキュメントはこちらです。

いくつか種類がありますが、今回は1番ベーシックな見た目のものを再現してみます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/e79b28ab-2acf-5f2f-4ccb-5f3117d9a76a.gif)

## 実際に作ってみた

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/a8d6645a-e06e-2ea3-0023-a3d955481b80.gif)

だいたい良い感じではないでしょうか？

## 作り方

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/112384bb-e62c-d8c9-4538-7f35abf52224.png)

まずは展開した状態から作りました。

ポイントは2つです

1. 上に移動するラベルを高さ12pxのFrameで囲っておく
    1. プレースホルダーっぽい見た目のときが16px、上に移動したときが12px
    1. 実際のMateril-UIでも、上に移動したラベルの高さ込みでコンポーネントが構成されている
1. 後から太くなるボーダーを高さ1pxのFrameで囲っておく
    1. hoverや入力時に太くなるのでFrameで囲っておかないとレイアウトがずれる

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/7bca26f9-ca11-7fcb-d334-ac695e0830ca.png)

次はプレースホルダー状態を作りました。

Frameはそのままの位置で`Clip content`のチェックを外し、ラベルの位置と大きさだけ変更
これでレイアウトに影響を与えず動かせます

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/7a4cdc11-bc9f-9fa0-e7f2-e958cb8b832d.png)

hoverや入力中の見た目も、1pxのFrameで囲った上で`Clip content`のチェックを外し、ボーダーの高さを2pxに増やしています。
こちらも全体のレイアウトに影響を与えずに太くできています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/d96922da-a3d6-de52-ddce-470f4cce1d19.png)

あとはComponent化→Variants設定をした上でPrototypeモードでトリガーを与えていきます。

| 状態 | トリガー1 |　変化する先1 | トリガー2 | 変化する先2 |
| --- | --- | --- | --- | --- |
| デフォルト | Mouse enter | ホバー状態 |  |  |
| ホバー状態 | Click | 入力中 | Mouse leave | デフォルト |
| 入力中 | Click | 入力完了 | Key/gamepad (Backspace) | デフォルト |
| 入力完了 | Key/gamepad (Backspace) | デフォルト |

`Mouse enter`と`Mouse leave`はひとまとめにして`While hovering`でも良いのですが、`While hovering`だと何故か微妙にチラつくシーンがあるのでこのようにしてみました。

ちなみにAnimationは全てSmart animationで200msで動かしています。

## 後書き

ここまで書いて気がつきましたが、なぜMaterial Designを参照せずいきなりMaterial-UIを真似ていたのでしょう。
自分でもわかりませんが、だいたい再現できたので良しとします。
【備忘録】Next.jsちっくなお話　+ORMライブラリ / propsわかりやすい資料

## .next
npm run dev するたびに作成される
不具合があれば難なく消そう


##prisma
ORMライブラリ

```
主にセキュリティ面を考慮しなくていいし、
SQLを書く面倒やミスが減る。
```

SQL文書かなくても
いいようにDB自動生成してくれる優れもの

>その一歩手前でDB操作触るなら「MySQL２」
べた書きでSQL文を書くが、
ORMライブラリのありがたみがよりわかる代物。
https://www.npmjs.com/package/mysql2




導入初歩だけ

```
npm install prisma -D

npx prisma init

migrate➡localDBを自動生成
初回：$ npx prisma migrate dev --name init --preview-feature
※以降※
npx prisma migrate dev  --name init　するたびに
　schema.prismaのテーブル定義が反映される
```


## props
Next触っててpropsってよく出てくるので
振り返りようにメモ

React.js チュートリアル超入門_propsとか
https://note.com/natsukingdom/m/me5fa275da270
【初心者向け】list-style-typeのリストマークが下方向にズレる原因と対策

#どうも7noteです。リストマークが下にズレる原因と対策

`<li>`タグに使うlist-style-type（リストマーク）が下にズレることがあります。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/95cba35a-f933-f635-26ba-642681b7e3da.png)

明らかに点（・）の位置がおかしいですね。
本来であれば、1行目の左側に点（・）が配置されてほしいのですが、下にズレてしまっています。
解決方法の前にこうなってしまう原因のソースを見てみます。

## 原因のソース

```index.html
<ul>
  <li><span>長いテキスト。長いテキスト。長いテキスト。長いテキスト。長いテキスト。長いテキスト。長いテキスト。</span></li>
  <li><span>長いテキスト。長いテキスト。長いテキスト。長いテキスト。長いテキスト。長いテキスト。長いテキスト。</span></li>
</ul>
```

```style.css
li {
  list-style-type: disc; /* リストマーク（※初期値） */
}
li span {
  display: inline-block; /* こいつが原因 */
}
```

liの中の要素がインラインブロック要素の場合、リストマーク（・）の位置がズレてしまうようです。
簡単なのはspanをインラインブロック要素にしなければ済みますが、それができない場合は違う方法で点（・）を付けましょう。

## 解決方法

### 方法① liの子要素をインラインブロックにしない

### 方法② `list-style-type: disc;`を使わずにリストマークを付ける

```style.css
li {
  list-style: none;
}
li span {
  display: inline-block;
  text-indent: 1em;
}
li span::before {
  content: "・ ";
}
```

![OK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/816b4f67-2703-c316-6893-52da2a7cfd3e.png)

疑似要素を使ってリストマークの代わりになる点（・）を作成します。
beforeに指定することで、テキストの冒頭に文字を追加することができるので、`text-indent`と組み合わせて使うことで、
1行目の左側に点（・）を配置することができます。

## まとめ

HTMLとCSS初心者の頃は分からない事が本当に多くあるので、ひたすらググりまくるしかありません。
もし聞ける人がいれば周りの人に聞くのもいいです。

それでも分からない場合は、ブラウザの検証ツール（F12キー）を使って怪しそうな要素やCSSを少しずつ消していくのが良いでしょう。

そうやって原因を特定する力もWEB制作者に必須のスキルになります！


#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
VSCodeでターミナルの起動に失敗する:終了コード 2147516566

# 問題
VSCodeでターミナルを起動できなくなりました。  
  
次のようなメッセージがポップアップされます。  

```
ターミナル プロセス "C:\Users\***\.dotnet\tools\pwsh.exe" が終了コード 2147516566 で終了しました。
```  
  
# 解決策
`setting.json`に次を追記してください。  

```json:setting.json
  "terminal.integrated.shell.windows": "C:\\WINDOWS\\system32\\cmd.exe",
```
ヘルプには「32bit版のターミナルを64bit版Windowsで使うとき」の項に記載がありました。  
私のwindowsは64bitですが、今までは普通に起動できていたんだけどなぁ…  

# 可能性として  
Unityをインストールしたあとに発生しました。vidual studioと干渉するのかもしれません。
subscription for firebase extension stripe

riotjs上で、これ以上シンプルにできないほど切り詰めた
定期購読機能を実装してみた。

今回は、商品はひとつでおこなっているため

有名なapp.jsのサンプルのように
\<template>に商品リストを埋め込み表示、選択することもなく
subscribeボタンだけです。
まず、index.htmlの下のほうに追加
\<script src='https://js.stripe.com/v3/'>
\</script>

+ subscribeボタンの動作(onclick='{onsubscribe}')

すでに、定期購読なされていた場合、stripe上の請求書ページへ
でない場合、stripe上のカード支払いページへ


+ onsubscribe()の実装

**サブスクされているかは？**
**/customers/{uid}/subscriptions/{id}.status のみ みよ！！**



trialingまたはactiveなsubscriptionがあるか確認します。
firestore('/customers/{uid}/subscriptions/').where(status==('trialing' or 'active')).Snapshot(ss=>if(ss.empty){処理１へ}else{処理２へ})

処理１
firestore('/products/XYZ/prices/ABC')
※今回、一つしか無いので、クエらない(ABC直指定)


このpriceID(= ABCのこと)を含んだcheckout値※を
/customers/{uid}/checkout_sessions/に追加後
そのdocIdを以下の関数の引数に渡し、終了！！

Stripe('公開鍵').redirectToCheckout({docId})

※checkout値 {[taxRates],price:priceID,callbackUrlなど、その他の情報} 

処理２
cloud functionで、引数に'戻りURL'のみ※を渡し、
'ext-firestore-stripe-subscriptions-createPortalLink'をコール
戻り値として、請求ページのURLが来るので、そこへ飛ぶ

※ cloud function内では、引数contextよりuidを参照できるため
　そのような情報は一切、渡さなくてもOKなのです。

今回は、以上です。
riotないの？この程度なら、想像におまかせします。ｗ
【メモ】アンチパターンとは？？　英語検索大事だよねってお話


##　アンチパターン
プログラミング的によくない、汚いパターン

イケてない実装とはいわゆる
これのことを指すと思ってもらってOK

>可読性が低い（手続き型プログラム）だったり
昔の手法過ぎて今は使われない実装方法だったりと様々

```
なんかこれ使うの渋ってますな～
ってときは『これしないの、アンチパターンだからですか？』
と聞くといい反応もらえるかもよ？
```



##　英語検索
エンジニアとして生きていく上では
『英語検索』は必須だなと。
備忘録的なのを残しておきたいのでおいておきますｍｍ

```
pass parametaer　パラメーターを渡す
```
【開発】PRの適切なわけかた

PRは開発者、レビュワー双方に負担になっては
いけないのでよく『細かくPR出しましょう』なんてよく言われます！


ですが、細かくって
どれくらい？３ファイルくらい？
と定量的な判断ができなかったです。


ですが、
天下のGoogle様がこんなものを出してくれました。


##Google エンジニアリング・プラクティス ドキュメント

■PRの最適な分け方
https://shuuji3.xyz/eng-practices/eng-practices


##読んだ感想
読んだらまとめて
落とし込んでいきたいな～と
Apache + gunicorn + Django の組み合わせが良かった件

#はじめに
Apache + mod_wsgi + Django がうまく連携できず途方にくれていたところ、Apache + gnuicorn + Django に変更したところ一瞬で連携できたという話。

#詳細
参考にしたURLを並べておく

- [Django + Gunicorn + Apacheでデプロイするときのstaticファイル](http://www.open-force.info/182/show)
- [Apache + Gunicorn + hug で簡単APIサーバ]
(https://kittagon.hateblo.jp/entry/2017/09/14/221257#Apache%E3%81%AE%E8%A8%AD%E5%AE%9A)
- [How to setup Apache with Gunicorn](https://medium.com/django-deployment/how-to-setup-apache-with-gunicorn-6616986f1702)

# Apache + mod_wsgi + Djangoに対するメリット
- ポートで連携するためインストールトラブルの可能性が少ない。
- Apatch + Tomcatと設定 (Apache側のproxy.confの設定) が同じであるため、設定が楽。**mod_wsgi** や **django** のページとにらめっこしなくてもよい。

無理して Apache + mod_wsgi + Django で頑張る必要はないかなーと。
【Rails】rails sしたらActiveRecord::PendingMigrationError【解決済】

### 1.背景
共同開発でメンバーからプルリクのレビュー依頼を頂きました。
ローカルで動作確認を行おうと該当のブランチに切り替え、`rails s`でサーバーを立ち上げたところ、
下記のエラーが表示されました。

```ruby
ActiveRecord::PendingMigrationError (

Migrations are pending. To resolve this issue, run:

        bin/rails db:migrate RAILS_ENV=development

You have 1 pending migration:

20210526151149_create_watches.rb

):
```
pendingとは`保留中`という意味です。

### 2.使用環境
- mac.os バージョン10.15.6
- Ruby 2.7.2
- Rails 6.1.3.1
- psql (PostgreSQL) 12.6

### 3.エラーの原因
今回のプルリク分ではマイグレーションファイルの更新を含む実装を行っているのですが、私自身ローカル環境に取り入れた際にデータベースの更新をしていませんでした。

### 4.エラーの解決方法
#### ①保留中のマイグレーションファイルを確認
エラーから、保留になっている該当のファイルを確認します。

```ruby
ActiveRecord::PendingMigrationError (

Migrations are pending. To resolve this issue, run:

        bin/rails db:migrate RAILS_ENV=development

You have 1 pending migration:

20210526151149_create_watches.rb

):
```

#### ②マイグレーションの実行状況を確認
`rails db:migrate:status`を実行します。

```ruby
team_project % rails db:migrate:status

database: team_project_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210411051744  Create texts
   up     20210411052029  Create movies
   ..
  down    20210526151149  Create watches
```
downは編集可能（マイグレーションが完了していない）の状態なので、ここでも
データベースが更新されていないことが確認できました。
※up：マイグレーションが完了している状態

#### ③データベースを更新
`rails db:migrate`を実行します。

```ruby
team_project % rails db:migrate
== 20210526151149 Create Watches: migrating ====================================
-- create_table(:watches)
   -> 0.0891s
-- add_index(:watches, [:user_id, :movie_id], {:unique=>true})
   -> 0.0026s
== 20210526151149 CreateWatches: migrated (0.0918s) ===========================
```

データベースが更新され、無事サーバーを起動することができました！:smile:

### 5.まとめ
エラー画面に発生箇所と原因が記載されているので、落ち着いて対処したら大丈夫だと思いました！
参考にした記事では他の原因の記載もあるので、合わせて確認して頂くと、理解が深まるかと思います。

### 6.参考
1.web:[ActiveRecord::PendingMigrationErrorの解決方法](https://qiita.com/KONTA2019/items/0444ae3b8c8936a56ee0)
2.web:[RailsのMigrationに関する基本まとめ](https://qiita.com/ponsan_tech/items/c54aee04e56e6bb26eff)

### 7.最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
STM32F767でSPIを使いEEPROM AT93C46を読み出す。


目的
SPIのテスト

前提
事前にアドレス0に1,2が書き込まれている

参考

https://os.mbed.com/users/okini3939/notebook/SPI_jp/


https://www.petitmonte.com/robot/howto_eeprom_spi.html


```c++

#include "mbed.h"
 
SPI spi( D11 , D12 , D13); // mosi, miso, sclk
DigitalOut cs( D10 );
 
//Serial pc(USBTX, USBRX); // tx, rx
Serial pc(SERIAL_TX, SERIAL_RX); //767
 
int main() {
    pc.printf("\r\n767\r\n");
    
    // Setup the spi for 8 bit data, high steady state clock,
    // second edge capture, with a 1MHz clock rate
    spi.format(8,0);
    spi.frequency(1000000);
 
    // Select the device by seting chip select low
    cs = 1;
 
    spi.write(0b00000001);  
    spi.write(0b10000000 | 0);         
    wait_ms(5);    

    uint8_t b1 =  spi.write(0x00);
    uint8_t b2 =  spi.write(0x00);
    uint8_t b3 =  spi.write(0x00); 

    pc.printf("番地(H) = ");
    pc.printf("%d\r\n",
        (b1 << 1) | (b2 >> 7)
    );
    
    
    pc.printf("番地(L) = ");      
    pc.printf("%d\r\n",
    ( (b2 & 0b01111111) << 1)  | (b3 >> 7)
    );
  
    // Deselect the device
    cs = 0;
}



```

![spi_eeprom_767_r_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/dc04aec7-a530-4530-711d-377624a76869.jpeg)


![spi_eeprom_767_r_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/977f875b-06db-0691-9671-2201fab7048f.jpeg)
Pythonのloggingでログ出力先ごとに例外スタックトレースの要否を設定する

## 概要
Pythonのlogging.Logger.exceptionを使用する際、ログ出力先（Handler）ごとに例外スタックトレースを出力するかどうかを設定したい。JavaのLog4jなら%throwableで設定できるが、loggingには同様のフォーマットがなく（標準Formatterを使う限り）必ず出力されることになる。

したがって、個別に設定するためには例外スタックトレースを出力しない独自Formatterを定義する必要がある。

## 実装例
ログファイルには例外スタックトレースを出力し、コンソールには出力しない実装例。

```sample.py
from logging import getLogger, config, Formatter

class NoExceptionFomatter(Formatter):
    """例外スタックトレースを出力しないFormatter"""
    def format(self, record):
        record.message = record.getMessage()
        if self.usesTime():
            record.asctime = self.formatTime(record, self.datefmt)
        return self.formatMessage(record)

# ログ設定
config.dictConfig({
    'version': 1,
    'formatters': {
        'standard': {
            'format': '%(asctime)s %(name)s %(levelname)s %(message)s'
        },
        'custom': {
            '()': NoExceptionFomatter,
            'format': '%(asctime)s %(name)s %(levelname)s %(message)s'
        }
    },
    'handlers': {
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'sample.log',
            'formatter': 'standard'
        },
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'custom'
        }
    },
    'loggers': {
        'sample': {
            'level': 'INFO',
            'handlers': ['file', 'console']
        }
    }
})

# ロガー
logger = getLogger('sample')

# ログ出力
try:
    1 / 0
except:
    logger.exception('exception')
```
標準Formatterを継承して独自Formatterを定義し、formatメソッドをオーバライドする。
オーバライド後の処理は[標準Formatterのformatメソッド](https://github.com/python/cpython/blob/3.9/Lib/logging/__init__.py#L650-L680)から例外スタックトレース付与を省略したもの（上記の実装例ではexc_infoだけでなくstack_infoも省略）
[備忘録] grpCurlの使い方 

## はじめに
最近gRPCでAPIテスト書いたりちょっとしたマイクロサービス開発したりとでgrpcurlと触れ合う機会が多かったので備忘録を兼ねてまとめました。

なるべくイメージがつきやすいように実行コマンドとその出力をセットで書くようにしています。

### 読んで欲しい人
- grpc最近触れたけど手軽にサーバーリクエスト送る方法がまだイメージつかない人
- grpcurlっていうのがあるのを知って使い方を知りたい人
- grpcurlのオプションとか見たい人

__gRPC__についての説明は以前[Go言語+gRPCをはじめから丁寧に解説してみた](https://qiita.com/ishishow/items/c9b633d3d4d22db74a6d)(宣伝)の記事を書いたことがあるので気になる方はそちらをご覧ください

## grpcurlとは
公式: https://github.com/fullstorydev/grpcurl

grpcurlは、gRPCサーバーを操作するためのコマンドラインツールで以下の特徴を持ちます。

* curlライクに作られている
* ストリーミング方式を含むあらゆる種類のRPC方式をサポートしている
* セキュア/TLS サーバーとプレーンテキストサーバー (TLS を使用しない) の両方をサポートし、TLS構成のための多くのオプションを備えている

## インストール
#### バイナリで欲しい人
https://github.com/fullstorydev/grpcurl/releases

#### HomeBrewで入れたい人
```shell
brew install grpcurl
```
#### Goで入れたい人
```shell
go install github.com/fullstorydev/grpcurl/cmd/grpcurl
```

#### インストール確認
下記のコマンドが正常に動けばgrpcurlのインストールは完了です。

```shell 
grpcurl -help
```

### 環境準備

こちらも以前の記事で使った

https://github.com/ishishow/grpc_tutorial

のリポジトリを使います。

```shell
git clone https://github.com/ishishow/grpc_tutorial.git
cd grpc_tutorial
go run server.go
% Go gRPC Beginners Tutorial!　// 起動成功です
```

### サービス一覧を表示
```shell
% grpcurl -plaintext localhost:9000 list                                                         [~]
chat.ChatService
grpc.reflection.v1alpha.ServerReflection
```
##### -plaintextオプション
省略するとTLSで接続されます

##### list
grpcサーバーが持つサービスの一覧が確認できます。
今回はchat.ChatServiceとリフレクションの２つになります。

### サービスの呼び出し
```shell
grpcurl -plaintext -d '{"body": "ishishow"}' localhost:9000 chat.Service
{
  "body": "ishishow! Hello From the Server!"
}
```
こちらリクエストパラメータ有りの場合になります。

リクエストなしの場合は-d{...}は必要ありません。

#### ポイント
- 公式にもありますが、-dオプションはサーバーアドレスとサービス名の前に記述する必要があります。

> To send a non-empty request, use the -d argument. 
> 
> Note that all arguments must come before the server address and method name:


#### サーバーリフレクション
grpcurlは[サーバーリフレクション](https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto) を使っているのでそちらの処理がされていないとprotoファイルを直接渡さなければgrpcurlは実行できません。

サーバーリフレクションを使わないで実行する方法は[こちら](https://github.com/fullstorydev/grpcurl#proto-source-files) を参考にしてください。

また、各言語におけるサーバーリフレクション実装サンプルは[こちら](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md#known-implementations) になります。

※　__C# Go Java C++ Pythonはサポートされていますが、Ruby,とNodeはサーバーリフレクションはサポートされていませんので注意が必要です__

### 他のクライアントツール
最後に他の有名なgrpcクライアントツールを紹介します。

- [grpcc](https://github.com/njpatel/grpcc)
   - grpcc は JavaScript (Node.js) で書かれています。サーバーリフレクションには対応していないのでprotoを読み込む必要があります。
- [evans](https://github.com/ktr0731/evans)
  - evansは非インタラクティブなCLIモードとインタラクティブなREPLモードを兼ね備えた高機能なツールです。こちらはサーバーリフレクションに対応しています。
- [bloomrpc](https://github.com/uw-labs/bloomrpc)
  - こちらはおすすめのGUIで使えるクライアントツールです。PostmanとGraphQL Playgroundにinspireされているらしく、綺麗な見た目でわかりやすくリクエストが送れます。
  - ![editor-preview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628777/dc9eddf8-1026-1168-16b9-815845d769a6.gif)

## 参考リンク

https://www.wantedly.com/companies/wantedly/post_articles/310167

https://engineering.mercari.com/blog/entry/grpc_and_evans/

https://github.com/uw-labs/bloomrpc
[JavaScript]オブジェクト変数にプロパティを追加する

オブジェクト変数にプロパティを追加します。

```
let hoge = {
  name: "太郎" ,
  age: 23
}

※プロパティの追加
hoge.tel = '000-111-222'
hoge["height"] = 166;

console.log(hoge)

// {name: "太郎", age: 23, tel: "000-111-222", height: 166}
```

以上でプロパティを追加できます。

## 参考
https://qiita.com/chihiro/items/eb8c7b2ceee5274a4a8f
サイバーセキュリティ及びソフトウェアアップデートの国際基準

#WP29

世界的な自動車の安全性を継続的に改善しながら、革新的な自動車技術を市場に導入する国連のフレームワーク

https://unece.org/wp29-introduction

![wp29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680014/a925bb21-9807-2bbd-62a4-f9f8057a04ff.png)
https://www.mlit.go.jp/report/press/jidosha07_hh_000343.html

#参考Link
https://www.accenture.com/jp-ja/insights/security/connected-vehicle-7
https://www.pwc.com/jp/ja/knowledge/column/awareness-cyber-security/wp2901.html
https://monoist.atmarkit.co.jp/mn/articles/2006/30/news057.html
https://argus-sec.com/ja/unece-wp29-approved/
Rubyのhash配列のシンボルでの処理方法

Rubyのhash配列のシンボルでの処理方法をブログに記載いたします。


```Ruby
nogizaka = {cap: "秋元真夏", ace: "齋藤飛鳥", front1:"山下美月", front2:"遠藤さくら"}
nogizaka.each do | position,name |
    puts "#{position}のポジションは#{name}です。"
end
```

シンボルのつけ方は

```Ruby
nogizaka = {cap: "秋元真夏", ace: "齋藤飛鳥", front1:"山下美月", front2:"遠藤さくら"}
```

になります。この方法を使うと楽に管理できます。出力結果は

```
capのポジションは秋元真夏です。
aceのポジションは齋藤飛鳥です。
front1のポジションは山下美月です。
front2のポジションは遠藤さくらです。
```

になります。
AWS CLI route53domainsのlist-domainsでドメインが取得できずにハマった話

# 環境

```shell
$ aws --version
=> aws-cli/2.2.7 Python/3.8.8 Darwin/18.7.0 exe/x86_64 prompt/off
```

# 原因
**`region`が`us-east-1`じゃなかったから**

**NG:**

```shell
$ aws route53domains list-domains                                                                                                                                                                               
=> Could not connect to the endpoint URL: "https://route53domains.ap-northeast-1.amazonaws.com/"
```

**OK:**

```shell
$ aws route53domains list-domains --region us-east-1
=> {
    "Domains": [
        {
            "DomainName": "example1.com",
            "AutoRenew": true,
            "TransferLock": false,
            "Expiry": "2021-06-01T09:53:28+09:00"
        },
        {
            "DomainName": "example2.jp",
            "AutoRenew": true,
            "TransferLock": true,
            "Expiry": "2022-06017T00:00:00+09:00"
        },
    ]
}
```

# 詳細
ドメインを取得する際の**`region`は`us-east-1`が固定**らしい。。。
公式のExamplesに小さく書いてたが、この注釈の書き方はあまりにも分かりにくい。。。。

> To list the domains that are registered with the current AWS account  
The following list-domains command lists summary information about the domains that are registered with the current AWS account.  
This command runs only in the us-east-1 Region. If your default region is set to us-east-1, you can omit the region parameter.  

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/route53domains/list-domains.html#examples
Javaからyamlを生成してファイルに書き込む

## はじめに
[Selenideでテスト自動化](https://qiita.com/tatesuke/items/589e30ab9b3dc7037e26)をした際に、シナリオA→Bでデータの受け渡しをする上でyamlに書き込みをしたい場面があった。その時の実装の備忘録を残しておく。

## Javaでyamlを生成してファイルに書き込む
`snakeyaml`と`OutputStreamWriter・BufferedWriter`を使って簡単にできる。
`OutputStreamWriter`を使う理由は、書き込み時の文字コードを指定し文字化けを防ぐため。

```java:sample.java
User user = new User();
user.setId("12345");
user.setName("hoge hoge");

Yaml yaml = new Yaml();   // org.yaml.snakeyaml
File file = new File("C:\\temp\\test.yaml");

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");   // 文字コードを指定するためにOutputStreamWriterを使う
BufferedWriter bw = new BufferedWriter(osw);
bw.write(yaml.dump(user));   // クラスのインスタンス(オブジェクト)
bw.close();
```
```java:User.java
@Data
public class User {
    private String id;
    private String name;
}
```
AWS Control Tower とは

## 勉強前イメージ

コントロールっていうからには全体統括的な・・？
Organizations使ってマルチアカウントがなんとかーって感じがしそう

## 調査

### AWS Control Tower とは

簡単に言うと複数のAWSアカウントを簡単に管理できるようにするサービスです。

経緯としては、AWSを使用していくと複数アカウントが出来たり、統制など取るのが大変になってきました。
また、複数アカウントを集約するためにAWS Organizationsや
AWS Organizationsのアカウントに統制をきかせるService Control Policyなどが存在します。
これらのサービスも多数存在し、管理が大変になりcloudformationのテンプレートの提供が開始されました。
しかし、テンプレートが出来ても確認作業は必要となります。
そこで統制を簡単にするために、まとめて管理できるサービスが `AWS Control Tower` になります。

### AWS Control Tower の機能

- ランディングゾーン

上記で説明記載した、複数アカウントのAWS環境です。
セットアップを自動化して、AWS OrganizationsやAWS Configなど設定します。

- ガードレール

AWSの環境全体にガンバナンスを提供するルールになります。
`予防的` と `発見的` の 2種類があります。
`予防的` ・・・ アクションの発生を防止します。
`発見的` ・・・ アクションが発生された際に検知され、cloudtrailに記録されます。

- Account Factory

新規アカウントを標準化するためのテンプレートです。
組織内で、アカウントのプロビジョニングのワークフローの自動化を支援します。

- ダッシュボード

管理者がランディングゾーンを監視できます。

## 勉強後イメージ

実際触ってるわけじゃないからなーんかイメージがつかない。
あとマルチアカウントに関するサービスありすぎるので、まとめないといけない

## 参考

- [AWS Control Tower とは](https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide/what-is-control-tower.html)
- [AWS Control Towerの特徴](https://www.acrovision.jp/service/aws/?p=1307)
mount時に、Filesystem has duplicate UUID がでて失敗したときのリカバリ方法

備忘録です。

```bash
# fstabに追記
% echo "UUID=`blkid -o list | grep vdb | awk '{print $5}'` /data                   xfs     defaults        0 0" >> /etc/fstab

# マウント失敗…
% mount -a
mount: wrong fs type, bad option, bad superblock on /dev/vdb,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so

# パス指定してもマウントできなかった…
% mount /dev/vda1 /data

# UUIDが重複しててマウントできないみたい
% dmesg | tail -f
XFS (vdb): Filesystem has duplicate UUID e521750b-1437-4012-ad5d-2af7ff11f8b4 - can't mount

# 強制マウントでマウントできるか確認
% sudo mount -t xfs -o nouuid /dev/vdb /data

# 中身確認 ←できた
% ls /data

# マウント解除
% umount -l /dev/vdb

# UUID再生成
% sudo xfs_admin -U generate /dev/vdb

# もっかいマウントしたらできた！
% mount /dev/vdb /data
```
【At Corder】【初心者】ABC088B - Card Game for Two をRuby で解いてみた



#はじめに
[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～ - Qiita](https://qiita.com/drken/items/fd4e5e3630d0f5859067)

こちらの記事を参考に初心者がAt corderに挑戦します。
目的としては、就職活動でのコーディングテスト対策です。
毎日１問を目標としてコツコツやってきます:thinking:

わからないことは調べる精神です。ちょっとでもわからないなぁ、と思ったことは調べて解説と参考文献を載せますので、同じ内容でわからない人がいれば参考にししてください:baby:


https://atcoder.jp/home
#問題文

N枚のカードがあり、i番目のカードにはa_iと番号が振られる。二人のプレイヤー(問題中はAliceとBob)がお互い数字が見えている状態で、交互にカードを選択する。選択するカードが無くなったとき、自分が持っているカードに書かれている数字の合計が得点となる。自分の点数が最大化するように最適な戦略を取った場合、先手(問題文中はAlice)は後手に対し、何点多く得点するか？

##制約

Nは1以上100以下の整数

$a_i$は1以上100以下の整数


##入力

```ruby
N
a1 a2 a3 ... aN
```

##出力

先手が後手よりも多く獲得した点数を出力

###入力例

```ruby
2
3 1
```

###出力例

```ruby
2
```

先手が3を選択、後手が1を選択する。点数は3と1なので、点差は3-1=2となる。

#回答

```ruby
N = gets
numbers = gets.split.map(&:to_i)
alicepoint = 0
bobpoint = 0

while numbers.any?
  
  alicepoint += numbers.max
  numbers.delete_at(numbers.index(numbers.max))
 
  if numbers.empty?
  	break
  end
  
  bobpoint += numbers.max
  numbers.delete_at(numbers.index(numbers.max))

end

puts alicepoint - bobpoint

```

#感想

最近は他の人の回答を回答を見る前に通るプログラムが書けるようになってきたぞ。まだまだメソッド等の使い方は覚えられていないので、調べながら出ないと厳しいな。
変数を頭文字大文字にしていたことで値を更新できず(alicepointとbobpointが頭文字大文字だった)🙄
大文字小文字をちゃんと識別しているのにちょっとびっくり。今後は注意だ！

#参考文献

[Rubyでnil判定をする方法](https://uxmilk.jp/22595)

[break](https://www.javadrive.jp/ruby/for/index9.html)

[Ruby ビギナーのための CGI 入門 【第 5 回】 文字コードと排他処理 1 ページ](https://magazine.rubyist.net/articles/0017/0017-CGIProgrammingForRubyBeginners-1.html)
Python3で2進数の出力を見やすくする

データ収集系の設定をするときに、直接レジストリのどこか特定のbitを変更したくなったりする。16進数と2進数の変換は、Python3を使うのが楽なのでよく利用しているのだが、特に2進数で桁が多くなるとわかりにくくて困っていた。解決方法を見つけたのでメモ。

- `hex()` 16進数で表示
- `int()` 10進数で表示
- `bin()` 2進数で表示
- `0x` 16進数表示
- `0o` 16進数表示
- `0b` 2進数表示

大抵の場合はこれで良いのだが、2進数はすぐに桁がすごいことになるので普通に表示するともうよくわからない。

```python
>>> bin(0x5642)
'0b101011001000010'
```

なので、formatを使う。

```python
>>> '{:#0_b}'.format(0x5642)
'0b101_0110_0100_0010'
```

`#`をつけると出力に`0b`とか`0x`のが付くので何進数で表示しているのかがわかる。
`_`をつけると4桁毎に`_`をつけてくれるので比較的何桁目なのかが分かり易い。2進数が入力の時は、`_`で区切るとわかりやすくなる。数字の中の`_`は無視してくれる。

```python
>>> hex(0b011_1001010_10_11)
'0x1cab'
```

参考
https://note.nkmk.me/python-format-zero-hex/
Googleスプレッドシートでリアルタイムに米国株価格を取得


#はじめに
在宅ワークがゆっくり広がってきた中、投資に目を向ける人も多くなったのではないでしょうか。
投資をやろうかと思っているのですが、情報をスプレッドシートで管理したいと思い備忘録的に残します。
（また追記するかもしれないです）

#やること
スプレッドシート上で、指定した米国株の銘柄の現在株価を取得します。

#実装
スプレッドシートにはGOOGLEFINANCE()という株価等を取得することができるAPIが用意されています。

##構文
中身の構文は↓です。

```
=GOOGLEFINANCE(銘柄, [属性], [開始日], [終了日|日数], [間隔])
```

##銘柄
株価を取得したいので、「銘柄」の説明だけ行います。
「銘柄」とは証券の銘柄コードです。取引所コードと銘柄コードの両方を使います。
取引所コード（NASDAQ）は記載がなくても大丈夫です。

```
=GOOGLEFINANCE("NASDAQ:APPL")
```

##API実装
APIを実装します。
実際に使う場合はセルの参照で使用することができます。
※株価情報の取得には最大20分かかる時があるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103503/b143e993-ae9d-2f64-ff98-796e175294f5.png)
AWS SQS、SNS、SES


#コンポーネントの疎結合
コンポーネント間の相互依存を減らした構成とすることで、１つのコンポーネント変更や障害の影響を削減することができる。

・以下が関連する主要サービス
**Lambda、SQS、ELB、SNS**

・疎結合化のメリット
**ー耐久性が強まる
ー負荷対応やスケーリングなど容易
ーシステム構成の追加・変更が容易**


#SQS(Amazon Simple Queue Service)
完全マネージド型のメッセージキューイングサービスで、マイクロサービス、分散システム、およびサーバーレスアプリケーションの切り離しとスケーリングが可能です。
**SQSはプッシュ通信ではなくポーリング通信です。プッシュ通信はSNSです。**

**ポーリングとは・・・複数のプログラム間通信に対し、一定のタイミングの問合せがあった場合に送受信処理を行う通信方式。**

ーメッセージサイズ・・・メッセージの最大サイズは256KB
ーメッセージ保持期限・・・デフォルトで4日、６０秒から最大１４日間の変更可能

##キューのタイプ
メッセージを管理するための入れ物。
キューの作成・削除の他に、動作属性などの詳細な設定がある。
**【キューに保存できるメッセージの数は無制限です】**

**・Standardキュー**
メッセージの配信順序を保証せず、同一のメッセージが２回配信される可能性がある。

**・FIFOキュー**
メッセージの配信順序を保証する。秒あたりの処理件数はStandardキューに劣る。

##SQSの機能

**・ロングポーリング**
メッセージがある場合に即レスポンスを返すが、メッセージがない場合は設定されたタイムアウトギリギリまでレスポンスを返しません。

**・ショートポーリング**
リクセストを受けるとメッセージの有無に関わらず即レスポンスを返す。こちらの方がAPIの呼び出し回数も多くコストが高くなるので、ロングポーリングを推奨されている。

**・デッドレターキュー**
処理できないメッセージを別のキューに移動する機能。指定された回数処理が失敗したメッセージを通常のキューから除外して、デットレターキューに移動します。

**・可視性タイムアウトを設定(Visibility timeout)**
新しいメッセージを指定時間見えなくする。
SQSを利用して可視性タイムアウトを設定することで、特定のインスタンスにおいて一定期間キューが処理されない場合に限り、可視性タイムアウトを超過するとスポットインスタンス側でキューが見えるようになり処理が実行されるようになります。

##SQSではキューに対して優先度を設定することが可能
優先的に処理されるキューとそうではないキューとに振り分けることが可能です。 各キューが別々にポーリングされる際に、 優先順位の高いキューが最初にポーリングされます。このSQS設定により、**有料ユーザーには優先的に処理するキューを設定し、無料ユーザーにはデフォルトのキューを利用することが可能です。**

優先付けには次のような設定を行います。
１．SQSを用いて優先順位ごとに複数のキューを用意する。
２．処理を急ぐリクエストは優先順位の高いキューに入れる。
３．優先順位に応じてキューを処理するサーバー台数を用意する。
４．キューの「メッセージの遅延送信」機能を利用することで、処理開始時間を遅延させることも可能である。



##EC2インスタンスをホストして、ユーザー数の増加に柔軟に対応するサービス
ELB、Auto Scaling、Route53、SQSが利用される。
ELBはアプリケーションに弾力性を追加するための最も理想的なソリューションの1つです。また、Route53にルーティングポリシーを作成して加重ルーティングなどを使用すると複数のリソースを単一のDNS名に関連付けることができます。


#SNS
プッシュ型の通知サービスで、システムのイベント通知の中核を担う。様々な通知プロトコルに対応している。他のサービスとの非同期通信を可能にする。

**・特徴
ー単一発行メッセージ
ーメッセージ通信順番は保証されない
ー取り消し不可
ーメッセージサイズは最大２５６KB**

・サービスの連携例
CloudWatch・・・Billing Alertの通知
S3・・・ファイルがアップロードされた時の通知　　など

##SNSのエンドポイント
SNSから送信されるメッセージの受信方法のことを指しています。エンドポイントには、HTTP/HTTPS、AWS Lambda、Eメール、SQS、SMS、モバイルプッシュ通知を利用することができます。内部のアプリケーションのアラーム機能としてはSNSの方が最適です。



#SES
フルマネージド型/サーバレス型のコスト効率に優れたEメールサービス
Eメール送信サービスで、SMTPプロトコルを利用する。様々な防御機能を備えており、高い配信性能を誇る。

##送信できなかったメールについての処理は利用者側で行う
この処理を行わないと不正なメールサーバーとみなされ、メール機能を利用することができなくなる。SESはアプリケーションの利用ユーザーに対して一斉メールによるお知らせを実施するといった使い方をします。

#Step Functions
サーバーレスのオーケストレーションサービスであり、 AWSリソースと組み合わせたワークフローを作成するサービスです。人間による操作を必要とするような長時間実行される、半自動化されたワークフローを作成することもできます。
AWS RDSのMariaDB/MySQLでLOAD_FILEと同じ処理をする


AWS RDSのMariaDB/MySQLはRDS上で稼働しています。その為、EC2などのmysqlコマンドからSQLを叩いてローカルのファイルをカラムの値としてロードするLOAD_FILE('ローカルファイル名')が使えません。

バックエンドAPIや管理フロントエンドがまだない状態で、mysqlコマンドから画像やpdfなどのサンプルバイナリファイルをRDSの*BLOBのカラムへ格納したかったのですが、海外含めてググっても不可能と言うレスしかついていなかったので、ややトリッキーですが解決方法を記します。

```sample.sql
-- ◆ローカルにあるサンプル用の画像素材などを一時保存するテンポラリテーブル
--
-- AWS RDSのMariaDBはLOAD_FILE('サーバ側ローカルファイル名')が使えないので
-- テンポラリテーブルを作成し、クライアント側のローカルバイナリファイルを LOAD DATA LOCAL INFILE で読み込んで、
-- そのテーブルのデータをサンプル画像として各種本テーブルへ挿入する。
-- 使う際は、LOAD_FILE('ファイル名') と書くところを (SELECT data FROM tmp_res WHERE file='ファイル名') と記述。
DROP TABLE IF EXISTS tmp_res;
CREATE TEMPORARY TABLE tmp_res (
  -- バイナリデータを一時保存するカラム
  data LONGBLOB not null,
  -- LOAD DATA で無理やり１ファイルをdataに格納するので、それ以外のパラメータはdataの後に定義する事
  id   int4 unsigned not null primary key auto_increment,
  file varchar(256) unique,
  ext  char(4)
) ENGINE=InnoDB AUTO_INCREMENT=1;

-- ◆ローカルのバイナリファイルをLOAD DATA LOCAL INFILEでリモートのRDSへ格納する
-- LOAD DATA は本来 CSV などのテキストファイル用なので、FIELDS TERMINATED BY と LINES TERMINATED BY には読み込むファイルに絶対に含まれないような値を指定しておく事
-- 画像ファイルを１つテンポラリテーブルへ格納
LOAD DATA LOCAL  INFILE './bin/logo.png' INTO TABLE tmp_res CHARACTER SET binary FIELDS TERMINATED BY '\Z\t\0\b\n\r\N' ESCAPED BY '' LINES TERMINATED BY '\Z\t\0\b\n\r\N';
UPDATE tmp_res SET file='./bin/logo.png' ,ext='png'  WHERE id=(SELECT MAX(id) from tmp_res);
-- pdfファイルを１つテンポラリテーブルへ格納
LOAD DATA LOCAL  INFILE './bin/docs/doc.pdf' INTO TABLE tmp_res CHARACTER SET binary FIELDS TERMINATED BY '\Z\t\0\b\n\r\N' ESCAPED BY '' LINES TERMINATED BY '\Z\t\0\b\n\r\N';
UPDATE tmp_res SET file='./bin/docs/doc.pdf' ,ext='pdf' WHERE id=(SELECT MAX(id) from tmp_res);
-- 以下、上記と同じ調子でサンプルバイナリファイルをtmp_resへ保存していく

-- ◆バイナリデータを格納したい本テーブル(例)
drop table if exists bin;
create table bin (
    id      bigint unsigned not null primary key auto_increment,
    bin     LONGBLOB,  -- バイナリデータ(最大4G)
    bin_ext CHAR(4)    -- 拡張子
) ENGINE=InnoDB AUTO_INCREMENT=1;

-- tmp_resテーブルからバイナリデータを得てカラムへINSERT。その他の情報(ここではext)が欲しい場合は同じ感じで。
INSERT INTO bin (bin,bin_ext) VALUES ( (SELECT data FROM tmp_res WHERE file='./bin/logo.png'), (SELECT ext FROM tmp_res WHERE file='./bin/logo.png') );
INSERT INTO bin (bin,bin_ext) VALUES ( (SELECT data FROM tmp_res WHERE file='./bin/docs/doc.pdf'), (SELECT ext FROM tmp_res WHERE file='./bin/docs/doc.pdf') );

```

後は、普通にmysqlコマンドで流し込む（ローカルバイナリファイルはLOAD DATA LOCAL INFILEで参照可能な場所に置いておいてください）

```sh
DATABASE=データベース名
HOST=xyz.yyyyyyyy.ap-northeast-1.rds.amazonaws.com
PORT=3306
PASS=xxxxxxxx
/usr/bin/mysql -h $HOST -P $PORT -u root -p$PASS $DATABASE < sample.sql
```
[ShimaBlock]ブック関連の操作サンプル

###概要
[ShimaBlock for VBA](https://shima-block.shima-soft.com/vba.html)の操作サンプルです。
ExcelVBAのセル関連コードを生成します。

使用サイト：[ShimaBlock for VBA](https://shima-block.shima-soft.com/vba.html)

###ブックオブジェクトの取得(マクロ実行ブック)(ブロック)
マクロを実行しているブックのオブジェクトを取得する場合は、以下のようにブロックを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566115/65097d11-de56-e3ee-bd47-2386dec674fc.png)


###ブックオブジェクトの取得(マクロ実行ブック)(生成コード)
```vb
Sub Main()
    Dim wb As Workbook
    Set wb = ThisWorkBook
End Sub
```

###ブックオブジェクトの取得(アクティブブック)(ブロック)
アクティブブックのオブジェクトを取得する場合は、以下のようにブロックを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566115/026265b7-cc9d-855f-c789-2b17606d76c5.png)

###ブックオブジェクトの取得(アクティブブック)(生成コード)
```vb
Sub Main()
    Dim wb As Workbook
    Set wb = ActiveWorkBook
End Sub
```

###ブックオブジェクトの取得(ブック開く＆セット)(ブロック)
ブックを開いてオブジェクトにセットする場合は、以下のようにブロックを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566115/bd0c3687-20fa-4f45-3fc0-0680c4ea0e50.png)

###ブックオブジェクトの取得(ブック開く＆セット)(生成コード)
```vb
Sub Main()
    Dim wb As Workbook
    Set wb = Workbooks.Open(Filename:="C:\Book1.xlsx", ReadOnly:=True)
End Sub
```

###サンプルコード参照サイト
以下のサイトのコードを参考に、[ShimaBlock for VBA](https://shima-block.shima-soft.com/vba.html)でコーディングしてみました。
[VBA（エクセルマクロ）でよく使うコードまとめ](https://qiita.com/hajimejimejime/items/0109f84051951bfdee0a)
UE4にPythonのモジュールを追加する

これはUE4の自動化の為にPythonでいろいろやりたいけどよく分からんという人の為の超短い記事。

UE4のOutput Logに

`import numpy`

などと打つとそんなモジュールは無いと言われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/fa890ac1-efda-831d-f61f-76367f4390a1.png)

ふむ、ではUE4のPythonのバージョンはいくつだい？ということで
`import sys;print(sys.version)`
と打つと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/327c300b-e1e2-eaf7-58a4-fb0b317d425b.png)
どうやら **3.7.7** らしい。(UE4.26)
ならばpipもデフォルトで入っているだろう。
UE4のPython.exeをEverythingで探したら
`C:\Program Files\Epic Games\UE_4.26\Engine\Binaries\ThirdParty\Python3\Win64\python.exe`
にあった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/ceb705f5-c056-24f8-fdc1-5719e418f97c.png)

では早速numpyを入れてみよう。cmd.exeでpython.exeの場所に移り
`python.exe -m pip install numpy`
を実行すると。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/a33675f1-9ee9-9639-34aa-a2494a662d7d.png)
二個ほどWARNINGが出たがインストール出来た様だ。
f2py.exeはFORTRUNをPythonに変換するものらしいがぶっちゃけ要らん。
あとpipのバージョンが古いから更新しとけよ、というもの。
はいはい、後で上げときます。

で、UE4上でnumpyは動く様になったのかい？
`import numpy`
と打ってみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/97968a15-1683-f605-57b8-424c73ef50f5.png)
おお、エラーが出なくなった。

これでUE4のPythonライフも捗ろうというもの。
よしよし。

-----
**追記**
チームでモジュールを共有したい場合はpipでinstallする際に共通のPYTHONPATHをtargetを指定しておくと良いそうです。
情報有難う御座います。＞小出さん
【Kotlin】Classの継承 オーバーライド 自来也とナルト

#■継承とは
他class内のプロパティやメソッドなどを
違うクラスに引き継ぐ事。

イメージ
師匠の技を弟子が引き継ぐイメージ
自来也がナルトに螺旋丸を引き継ぐのと同じ

■メソッドのoverride
継承したclass内でメソッドを上書きする事時に書く

イメージ
師匠から引き継いだ技にオリジナリティー加える。
螺旋丸を弟子がオリジナリティを加え大玉螺旋丸にする時に必要なもの

#■定義の仕方
まず継承できるクラスには先頭にopenを付ける。
overrideできるメソッドにもopenを付ける。

``` kotlin
open class Ziraiya(var name: String) {
  open fun rasenngann() {
     println("この技名は${this.name}だ！")
  }
}
```

実際に継承してみると下記のような感じになる。

``` kotlin
open class Ziraiya(var wazaName: String) {
  open fun waza() {
     println("この技名は${this.wazaName}だ！")
  }
}

//継承元のクラス名を：を付けて後ろに書く
class Naruto(wazaName: String):Ziraiya(wazaName) {
//継承元の変更したいメソッドの前にoverrideを書く
  override fun waza() {
    println("ナルトは新しい技大玉${this.wazaName}を習得した！")
    //継承元のメソッドを呼ぶ時にsuperを使うsuper(継承元)
    super.waza()
}

val naruto = Naruto("螺旋丸")
naruto.waza()
//結果
//ナルトは新しい技大玉螺旋丸を習得した!
//この技名は螺旋丸だ！

```
openを付けて継承したメソッドをoverrideして上書きしました。
これはあくまで任意なので上書きしなくてもエラーにはならない
必ず上書きをするように促すにはabstractを使用する。次で説明。

#■abstract 抽象クラス　抽象メソッド
必ず上書きさせるために必要な物
openの代わりにabstractを書く

注意:抽象メソッドには内容は書かない,もはや{}も書いてはいけない

``` kotlin
//抽象クラス
abstract class Kakashi(var wazaName: String) {
//抽象メソッド
    abstract fun waza() 
}

class Sasuke(wazaName: String): Kakashi(wazaName) {

//overraideで上書きしないとエラーになる。
  override fun waza() {
      println("俺は新しい力を手に入れた${this.wazaName}！")
  }
}

val sasuke = Sasuke("写輪眼")
sasuke.waza()
//結果: 俺は新しい力を手に入れた写輪眼！
```

この抽象メソッドを元に次回インターフェイスをまとめます！
量子回路とSchedule

# はじめに
Qiskitにおいて、作成した量子回路を実機で実行する場合、裏では校正されたパルスが使われています。そのパルスをパルスモジュールを使って、自分が好きなようにカスタマイズすることが可能です。この記事では量子回路とパルスモジュールを組み合わせた書き方を紹介したいと思います。

まず、Qiskit Pulseを動かすために必要な記述をまとめておきます。

```Python
import numpy as np
from qiskit import QuantumCircuit, transpile, Aer, IBMQ
from qiskit.visualization import *
from qiskit.circuit import Gate

IBMQ.load_account()

provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')
backend = provider.get_backend('ibmq_armonk')
backend_defaults = backend.defaults()
backend_config = backend.configuration()

```

### カスタムゲートに自作パルスをバインドさせる

基本的な流れは以下のとおりです。

1. カスタムゲート作成
1. 1で作成したカスタムゲートを含む量子回路を作成
1. 自分が作成したいパルスの定義を記述したscheduleクラスを作成
1. `add_calibration()`を利用して、3で作成したクラスを2で定義したゲートにバインド

以下サンプルコードを見ていきたいと思います。

```python
from qiskit import pulse

GHz = 1.0e9 # Gigahertz
qubit=0
freq_GHz=4.95
freq=freq_GHz*GHz
drive_sigma_sec = 0.075e-6
drive_duration_sec = drive_sigma_sec * 8
drive_amp = 0.3

# 1. カスタムゲート作成
x_pulse = Gate('x_pulse', num_qubits=1, params=[])

# 2. 1で作成したカスタムゲートを含む量子回路を作成
sample = QuantumCircuit(1, 1)
sample.append(x_pulse, [0])
sample.measure(0, 0)

#3. 自分が作成したいパルスの定義を記述したscheduleクラスを作成
with pulse.build(backend) as x_schedule:
    pulse.set_frequency(freq, pulse.drive_channel(qubit))
    pulse.play(pulse.Gaussian(duration=16 * int(pulse.seconds_to_samples(drive_duration_sec) / 16),
                              amp=drive_amp,
                              sigma=pulse.seconds_to_samples(drive_sigma_sec),
                              name="x_schedule"), pulse.drive_channel(qubit))

#4. 3で作成したクラスを2で定義したゲートにバインド
sample.add_calibration(x_pulse, (0, ), schedule=x_schedule)

```

```python
sample.draw(output='mpl')
```
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78339/87e4367d-9386-b6b2-1151-222da7dfafce.png)

1. カスタムゲート作成  
自分で定義したユニタリゲートを作成することができます。  
https://qiskit.org/documentation/stubs/qiskit.circuit.Gate.html
1. 1で作成したカスタムゲートを含む量子回路を作成  
カスタムゲートを含む量子回路を作成します。ここでは1量子ビットに対してカスタムゲートを作用させる量子回路を作成しています。
1. 自分が作成したいパルスの定義を記述したscheduleクラスを作成  
以前紹介したBuilder構文を利用してパルスを定義しています。ここではパルスモジュールで提供されているメソッド`seconds_to_samples()`を利用しています。このメソッドは引数に秒を与えることで、アクティブなバックエンドで秒単位で経過するサンプルの数を取得することができます。  
https://qiskit.org/documentation/stubs/qiskit.pulse.builder.seconds_to_samples.html  
1. 3で作成したクラスを2で定義したゲートにバインド  
自分が作成したパルスとゲートをバインドします。

### 作成した量子回路のパルスを確認する

自分が作成した量子回路がどのようなパルス構成になっているかも確認することができます。

```python
sample_sx = QuantumCircuit(1, 1)
sample_sx.sx(0)
sample_sx.measure(0, 0)
```

```python
sample_sx.draw(output='mpl')
```
![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78339/db8022d5-7d93-9d40-7c29-d5c7692a1fb3.png)

```python
from qiskit import schedule as build_schedule

# 1. scheduleを定義
schedule = build_schedule(sample_sx,backend)

schedule.draw(backend=backend)
```
![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78339/51c46df6-d52a-5927-b492-b09100be7b81.png)

1. scheduleを定義  
自分が定義した量子回路とバックエンドを定義してscheduleを作成すればパルスの状況が分かります。

# まとめ

この記事では量子回路とscheduleについて紹介しました。自分で定義した量子回路がどのようなパルスとなって実行されているかみてみるのも面白いかと思います。
クリップボード（GTK）のテキストやイメージをコピーペーストする

###クリップボード（GTK）のテキストやイメージをコピーペーストする

GTK C#でのクリップボードを操作するやり方です。
Atomの項目を用途によって指定します。

| 項目 | 用途 |
|:-----------|------------|
| PRIMARY| 選択/ドラッグ範囲・マウス中クリックで貼り付け  |
| CLIPBOARD　 | 多くのGUIアプリケーションがコピペ作業を行うのに使用される|


```
using System;
using Gdk;
using Gtk;

namespace ImageConvertGtk
{
    class Program
    {
        [STAThread]
        public static void Main(string[] args)
        {
            Application.Init();
            
            //PRIMARY (選択/ドラッグ範囲・マウス中クリックで貼り付け)
            //CLIPBOARD(多くのGUIアプリケーションがコピペ作業を行うのに使用される)
            
             Gdk.Atom _atom = Gdk.Atom.Intern("CLIPBOARD", false);
             Gtk.Clipboard _clipBoard = Gtk.Clipboard.Get(_atom);

             //テキストをクリップボードへペースト
             _clipBoard.Text = "aaaaaaa";

             //画像をクリップボードへペースト
             //_clipBoard.Image = new Pixbuf("画像名");
               
             //クリップボードからテキストをコピー
             if (_clipBoard.WaitIsTextAvailable())
             {
                 var text  = _clipBoard.WaitForText();
                 Console.WriteLine(text);
             }
             
             //クリップボードからイメージをコピー
             if (_clipBoard.WaitIsImageAvailable())
             {
                 var image  = _clipBoard.WaitForImage();
                 Console.WriteLine(image);
             }
             
        }
    }
}

```
[PHP]MAMPでWebStartが押せない事件

#はじめに

完全ゴミ記事ですが、一応誰かのためになればと思い記録しておきます。

#やりたいこと
phpMyAdminを使用したくて、以下の画面からWebStartボタンを押しても反応せず、、、
![スクリーンショット 2021-06-01 12.47.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1128031/8eefa01d-9f22-3d4f-a094-b2b4235242c3.png)

一応、再起動等するも治らず、、、、
でもMAMPそのものは正常に起動している

#対処法と原因

はっきりした原因はわからないですが、再インストールしなおしたら治りました！
もしかしすると、**MAMP PROの方のアプリケーションいらない！と思って消してしまったことが原因だったかもしれません**

#おわりに
こんなしょーもない記事ですが、誰かの役に立てば嬉しいです
【AWS CLI】ap-northeast-1でcreate-bucketした際にIllegalLocationConstraintExceptionがスローされた場合の対処法

## はじめに

以下のエラーが発生した際の対処法です。

```sh
$ aws s3api create-bucket --bucket test-bucket

# An error occurred (IllegalLocationConstraintException) when calling the CreateBucket operation: The unspecified location constraint is incompatible for the region specific endpoint this request was sent to.

```

## 結論

`--create-bucket-configuration`に`LocationConstraint=$region`を指定する必要があります。
(今回であれば`--create-bucket-configuration LocationConstraint=ap-northeast-1`)

```sh
$ aws s3api create-bucket --bucket test-bucket --create-bucket-configuration LocationConstraint=ap-northeast-1

# {
#     "Location": "http://test-bucket.s3.amazonaws.com/"
# }
```

## 詳細

[公式リファレンス](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-bucket.html)に全て記載があります。

> LocationConstraint:
>
> > Specifies the Region where the bucket will be created. If you don't specify a Region, the bucket is created in the US East (N. Virginia) Region (us-east-1).

`LocationConstraint`には、バケットを作成するリージョンを指定します。
`LocationConstraint`を指定しない場合、バケットは米国東部 (バージニア北部) リージョン (`us-east-1`) に作成されます。

> > If you send your create bucket request to the s3.amazonaws.com endpoint, the request goes to the us-east-1 Region.
> > ~~
> > Regions outside of us-east-1 require the appropriate LocationConstraint to be specified in order to create the bucket in the desired region:

上述したように`create-bucket`リクエストは、デフォルトでは `us-east-1`に送信されます。

そのため、`us-east-1` 以外にバケットを作成する場合は、そのリージョンを `LocationConstraint` に指定する必要があります。

逆に言えば、`us-east-1`からリクエストを送信する場合は、`--create-bucket-configuration`を指定する必要がありません。
またその場合は、`us-east-1`にバケットが作成されます。

```sh
$ aws s3api create-bucket --bucket test-bucket2 --region us-east-1

# {
#     "Location": "/test-bucket2"
# }


```

## 参考

- [create-bucket — AWS CLI 1.19.84 Command Reference](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-bucket.html)
- [aws s3api create-bucket throws error for us-east-2 · Issue #2603 · aws/aws-cli · GitHub](https://github.com/aws/aws-cli/issues/2603#issuecomment-422271388)
Mac Git ブランチを作成してそのブランチにスイッチする独自コマンドを登録する

# 目的

- 一回実行しただけで`$ git branch`コマンドで作成したブランチにスイッチするコマンドを登録する方法をメモ的にまとめる

# 方法

1. 下記コマンドを実行して独自コマンドを登録するファイルを作成する。

    ```terminal
    $ vi ~/.bash_aliases
    ```

1. 下記の内容を記載する。

    ```~/.bash_aliases
    function gbsw() {
        git branch $1;
        git switch $1;
    }
    alias gbsw=gbsw
    ```

1. 下記コマンドを実行して.bash_profileのバックアップをとっておく。

    ```terminal
    $ cp ~/.bash_profile ~/.bash_profile_org
    ```

1. 下記コマンドを実行して.bash_profileを開く。

    ```terminal
    $ vi ~/.bash_profile
    ```

1. 下記の内容を追記する。

    ```~/.bash_profile
    source ~/.bash_aliases
    ```

1. 下記コマンドを実行して変更を読み込む

    ```terminal
    $ source ~/.bash_profile
    ```

1. 適当なローカルリポジトリでコマンド`$ gbsw ブランチ名`を実行して動作を確認する。
1. 問題なさそうなら下記コマンドを実行して.bash_profile_orgを削除する。

    ```terminal
    $ rm ~/.bash_profile_org
    ```
IBM Security Verify API で ユーザーを削除する

# はじめに
IBM Security Verify APIを利用して、ユーザーを削除する方法についてご紹介いたします。

# APIのリファレンス
APIのリファレンスは、以下のURLから確認できます。
https://<自分のテナント名＞.verify.ibm.com/developer/explorer/#

- ユーザーの取得に利用するAPIは、以下の項目になります。
    - Users Management Version 2.0 

APIに関するKCのヘルプはこちらです。
https://www.ibm.com/support/knowledgecenter/ja/SSCT62/com.ibm.iamservice.doc/concepts/apis.html

# 1.IBM Security VerifyへのAPIクライアントの登録
OAuth アクセストークンを取得するために使用するクライアント ID とクライアントシークレットを準備します。
ブラウザで、IBM Security Verifyの管理画面にアクセスします。
https://<自分のテナント名＞.verify.ibm.com/ui/admin

「構成」-「API クライアント」タブを開き、「APIクライアントの追加」をクリックします。
![OTP-000002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/9799fa7c-cb28-7726-df1d-ccdece0060e8.png)

アクセス件を与えるAPIとしては以下を選択して、「保存」します。
    - ユーザーおよび標準グループの管理

![userdel2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/7fac3cd4-369b-887a-8ceb-8789479d1e9f.png)

登録したAPIクライアントを編集モードにすると、クライアントID/クライアント秘密鍵をコピーできます。
![userdel3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/5c78a4b4-e0be-b240-8c7a-1416155b2019.png)

# 2.アクセストークンの取得

```
curl -X POST "https://<テナント名＞.verify.ibm.com/oidc/endpoint/default/token" --header "Content-Type: application/x-www-form-urlencoded" --data-urlencode "grant_type=client_credentials" --data-urlencode "client_id=<クライアントID>" --data-urlencode "client_secret=＜クライアント秘密鍵＞"
```
取得したアクセストークンは赤枠部分になります。
![qiita (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e28268f3-3827-0a17-9f99-0743503435c8.png)


# 3.ユーザーの削除
ユーザーを削除するためには、以下のコマンドを実行します。

```
curl -i -X DELETE https://<テナント名＞.verify.ibm.com/v2.0/Users/<ユーザーID＞ --header "Authorization: Bearer <アクセストークン>"
```

レスポンスコードは204になります。
![userdel1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e5005ecf-092b-02d8-870b-078d45ff8ae4.png)

# 最後に
IBM Security VerifyのAPIを利用してアカウントを削除する方法についてご紹介しました。
bitcoin: walletnotify的用法

>![](https://upload-images.jianshu.io/upload_images/47789-06f7b150cf5a949b.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

`-walletnotify=<cmd>` Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)

### walletnotify

```
# bitcoin.conf
regtest=1
rpcuser=shooter
rpcpassword=shooter
#walletnotify=curl http://localhost:8000/notify/?tx=%s
walletnotify=/trans.sh %s
```

推荐  `walletnotify=/trans.sh %s`，降低耦合度。

#  trans.sh

``` shell
#!/bin/sh

curl -X GET "http://localhost:8000/notify/?tx=$1"  # http GET method
```

然后开启个http服务, 设定好访问地址, 以django为例:

```python
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    tx = request.GET.get('tx', 'Null') # http GET method
    return HttpResponse("This wallet tx is " + tx)
```

获取到跟本地钱包地址有关的tx后，就可以知道 到帐金额一系列的信息。

还有个类似的 配置: `blocknotify`
`-blocknotify=<cmd>` Execute command when the best block changes (%s in cmd is replaced by block hash) 

---

参考：
https://www.bilibili.com/video/av18079636
https://bitcoin.stackexchange.com/a/24483
https://en.bitcoin.it/wiki/Running_Bitcoin
https://github.com/bitcoin/bitcoin/pull/1974
SQLiteとMySQLで日時の取得方法が違う

##MySQLの場合

```
SELECT DATE_ADD(CURRENT_DATE, INTERVAL 1 MONTH); // 現在から1か月後
SELECT DATE_SUB(CURRENT_DATE, INTERVAL 1 MONTH); // 現在から1カ月前
```

##SQLiteの場合
※現在日時が2021年6月1日の場合

```
SELECT DATE('NOW','localtime','1 MONTH');　// 2021-07-01（現在から1か月後）
SELECT DATE('NOW','localtime','-1 MONTH');　// 2021-05-01（現在から1カ月前）

SELECT strftime('%Y/%m/%d',DATE('NOW','localtime','-1 MONTH')); // 2021/05/01
SELECT strftime('%Y年%m月%d日',DATE('NOW','localtime','-1 MONTH')); // "2021年05月01日"

```
<br>
・半年前以降のデータを削除

```
DELETE FROM テーブル名 WHERE カラム名 < strftime('%Y/%m/%d',DATE('NOW','localtime','-6 MONTH'));
```
Pythonでフーリエ変換をやってみた(+α)

## はじめに
知見蓄積のために音声データを使ってフーリエ変換をやってみた。
ただフーリエ変換だけやっても面白くないので、データをNMRの結果に見立てて化学シフトも描画した。

## 環境
windows10
python:3.7.10
seaborn:0.11.1
matplotlib:3.2.2
pydub:0.25.1

##内容
#### 1.フーリエ変換
```python
#ファイルの読み込み
from google.colab import files
uploaded = files.upload()
```
```python
#モジュール
!pip install pydub
import matplotlib.pyplot as plt
import seaborn as sns;sns.set()
import numpy as np
from pydub import AudioSegment
%matplotlib inline

# 音声ファイルの読み込み
audio = AudioSegment.from_file('/content/Accent19-1.mp3', 'mp3')

# 情報の取得
time = audio.duration_seconds # 再生時間(秒)
rate = audio.frame_rate  # サンプリングレート(Hz)
audio = np.array(audio.get_array_of_samples()) #numpy配列に変換

# グラフ表示のための横軸を設定
o_time = np.arange(0, audio.shape[0]/rate,1/rate)

#プロット
plt.plot(o_time,audio)
plt.xlabel('time')
plt.ylabel('amplitude')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/d693a38a-de0c-3e50-8b6f-f435053b082e.png)

```python
#x方向
number =audio.shape[0] #サンプル数
dt= time/number #時間幅
freq = np.fft.fftfreq(number,d=dt)

#y方向
fourier = np.fft.fft(audio) #フーリエ変換(時間⇒周波数へ)
amp = np.abs(fourier) #強度

plt.plot(freq,amp)
plt.xlabel('frequency(Hz)')
plt.ylabel('amplitude')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/bab4f657-fcd7-a63e-6c89-bcda37fb6d9f.png)

#### 2.NMRの化学シフト
ここからは応用編。実際の未変換NMRデータはさすがに手に入らなかったので、音声データで代用。
正確なものではないが、なんとなくはイメージできるはず。
実際の測定では0~4000Hz程度になるので、いい感じにデータを分割しておく。

```python
#右側だけ使う
fourier2 = fourier[:10000] 
amp2 = amp[:10000]
freq2 = freq[:10000]

plt.plot(freq2,amp2)
plt.xlabel('frequency(Hz)')
plt.ylabel('amplitude')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/34d56d79-0d4d-d3b5-0751-ea665f2aa5de.png)


```python
#NMRの結果に直す
amp2=amp2/10E+7 #割る数値は適当(それらしき値になるように)
base=500*10E+6 #測定周波数=500MHzと定義
ppm=((freq2+base)-base)/base*10E+6
plt.plot(ppm,amp2)
plt.xlabel('ppm')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/5abb98e8-705a-aaad-c8f4-ff589de40a64.png)

## まとめ
フーリエ変換から化学シフトまで実施できた。化学シフト計算は装置がやってくれるので、普段はやることないけど理解にはいいのでは。

## 参考
https://nehori.com/nikki/2020/12/06/post-22673/
https://algorithm.joho.info/programming/python/pydub-play/
http://www.pharm.tohoku.ac.jp/~henkan/lab/tanaka/lecture/OrgSpectrum_text.pdf

音声データは下記のサイトから。
https://otologic.jp/　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/8b4f6121-0c4b-fddb-ab7f-5a71f7ff39a1.png)
腾讯云之无服务器云函数运行golang程序



使用腾讯的 [无服务器云函数](https://cloud.tencent.com/product/scf)启动了一个服务，用 golang 代码生成以太坊的私钥跟地址。

https://service-exvd0ctl-1258120565.ap-beijing.apigateway.myqcloud.com/release/addr

>![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169726/74e6b151-5fc1-a96d-e923-286130d05da6.png)


### 无服务器云函数是什么
腾讯云的无服务器云函数，跟 aws lambda 类似，把一段代码放到云函数服务器上，设定好访问路径，就可以对外访问了。之前若想发布 1 段 20 行代码执行的服务，你可能需要买个 vps，现在用腾讯的云函数即可，灵活方便，省资源。

### 小程序

如果要做些工具类微信小程序，生成 eth、btc 地址，查看天气数据，雾霾指数，运行个云函数，小程序去请求即可。只要不保存大量数据，搭建服务器的费用可以省了。

### 云函数上使用 golang

云函数服务支持的语言真不少，有 python nodejs java golang，为什么选择 golang 了呢？python、nodejs 引入的类库，本人不知道如何才能导入到云函数，java 语法比较啰嗦，而 golang 编译完二进制文件就能直接 run 了，实在是方便的很！

### Golang code

```golang
package main

import (
	"encoding/hex"
	"fmt"

	"github.com/ethereum/go-ethereum/crypto"
	"github.com/tencentyun/scf-go-lib/cloudfunction"
)

func main() {
	cloudfunction.Start(genEthAddr) //使用云函数的固定用法
}

func genEthAddr() (string, error) {
	key, _ := crypto.GenerateKey()

	privateKey := hex.EncodeToString(key.D.Bytes())
	address := crypto.PubkeyToAddress(key.PublicKey).Hex()

	fmt.Printf("privateKey: 0x%s\n", privateKey)
	fmt.Printf("addr: %s\n", address)

	return fmt.Sprintf("私钥: 0x%s 地址: %s", privateKey, address), nil
}

```

### 编译并打包
`GOOS=linux GOARCH=amd64 go build -o main main.go `
`zip main.zip main`

将打包好的 zip 文件上传到腾讯的云函数服务器，设定好访问路由，就可以使用了。

过段时间会放上一个小视频，介绍如何使用腾讯的云函数服务。

---

参考：

https://cloud.tencent.com/document/product/583/18032
https://cloud.tencent.com/document/product/583/12513

https://cloud.tencent.com/document/product/583/9702 Python 部署程序包
https://cloud.tencent.com/document/product/583/12284 计费方式
https://cloud.tencent.com/document/product/583/12282 免费额度