OmniAICreator/Qiita-1.07M huggingface dataset:
figmaの基本操作のメモ

# ■基本操作

## Frameを作成

①Frameボタンを選択する（ショートカットはF）
②作りたいUIの端末を選択する

## UIの要素を作る

・Rectangleボタンを選択する（ショートカットはR）
・カーソルが＋になるのでドラッグするとオブジェクトが描画できる（Shiftで比率を維持できる）
・Altを押しながらドラッグすると両サイドの長さを同時に変更できる

## UI（テキスト）の要素を作る

・Textボタンを選択する（ショートカットはT）
・描画方法はUIの要素と同様

## スタイルを変更する

・UI要素を選択後右側のプロパティパネルを編集する
・色の変更するにはFillを編集する

# ■レイヤー

##レイヤー構造 

・左側のパネルはオブジェクトのレイヤーの階層構造を示している（レイヤーパネル）
（オブジェクトを選択すると紐づくオブジェクト名が青くなる）
・例えばiphoneレイヤーの中にRectangle1とボタン（テキスト）がネストしているという解釈ができる
（ネストが深くなると右にずれる仕様）

## グループ化

・オブジェクトを選択して右クリック/Group Selectionを選択するとグループ化できる（Cmdl + G）
→レイヤーパネルの階層構造も変化する
・解除する場合は右クリック/Ungroupを選択する（Cmd + shift + G）
・作成したグループ名/オブジェクト名はダブルクリックすると編集できる
・グループ化するメリット
①レイヤーがきれいになる
②オブジェクトの位置調整が簡単になる
→オブジェクトを選択してオプションパネルのAlignアイコンをクリックすると選択オブジェクトの親要素を基準に位置を調整できる

## 非表示とロック

・レイヤーパネルの右側の南京錠アイコン（Cmd + Shift + L）
→レイヤーのロック（Canvasで選択できなくなる）
・目のアイコン（Cmd + Shift H）
→レイヤーの表示/非表示の切り替え

## ページ管理

・レイヤーパネルの右上にPage1という項目がある
・このプルダウンを押下するとページでCanvasを管理できる
・＋ボタンを押下すると新規ページが作成される（ページは複写や削除なども可能）

# ■コンポーネント

## グループをコンポーネント化する

・右クリック/Create Componentを選択する（Cmd + Option + K）
レイヤーパネルのアイコンが水色から紫色に変わり菱形4つのアイコンに変化する（マスターコンポーネント）
・マスターコンポーネントをコピースライドしてできたもの（紫色の菱形アイコン）をインスタンスと呼ぶ
・マスターコンポーネントから要素を引き継げる（マスターを編集するとインスタンスにも反映される）
・インスタンスのプロパティを直接編集すればオーバーライドできる
（ただし下記3点以外はオーバーライドできない）
①**テキスト**： フォント、太さ、サイズ、線の高さ、文字間隔、段落間隔、インデント。
②**色**： Fill、Stroke、背景色、不透明度
③**効果**： ドロップシャドウ、インナーシャドウ、ぼかし。
・オブジェクトの位置やサイズなど上書きできない
→変更する場合、右クリック/Detach Instanceを押下するとインスタンスを解除できる（Cmd + Option + B）
→インスタンスを解除するとマスターコンポーネントの変更が反映されなくなる

## 既存のインスタンスを別のコンポーネントへ置き換える

・インスタンスを選択し後プロパティパネルのInstanceを別のマスターコンポーネントへ変更すると要素を切り替えることができる

## スタイルの登録

・登録したいスタイルを作成し選択する
・プロパティパネルのFillの●4つのアイコンをクリック/＋ボタンをクリック/スタイル名を入力する
→Color Stylesに登録される
→編集する場合は右のアイコンから編集可能（スタイルを当てているオブジェクトに反映される）

# ■プロトタイピング

## プロトタイピングの設定

①Frameを2画面用意する
②プロパティパネルのPrototypeタブに切り替える
③オブジェクトを選択すると右側に白●が表示される
④白丸をマウスでドラッグすると矢印が伸び、別Frameにつなげることができる（ユーザーフロー）

## プロトタイピングを再生する

・画面右上の再生ボタンを押下するとプレゼンテーションモードが立ち上がる
（プロトタイピングの設定した挙動を試すことができる）

## 画面の遷移方法を切り替える

①プロパティパネル/Prototypeタブに変更しておく
②編集したい遷移矢印を選択するとInteraction detailsのポップアップが表示される
③そのAnimationを変更すると遷移方法が変更される

## 実機でプロトタイピングを試す

・Figma Mirrorというアプリがios/Android共にあるようなのでこちらで試すことが可能です

## スクロールの設定

・Frameの縦幅を長くすることで画面スクロールが可能になる
→縦幅を伸ばすとき、中のオブジェクトも伸びてしまうのでCmdを押しながらドラッグすると解決できる

## ヘッダー/フッターの固定設定

・固定するオブジェクトをFrameに配置して選択する
・ヘッダーの場合プロパティパネル/ConstraintsをLeft/Topを選択してFix position when scrollingにチェックをつける（フッターの場合はLeft/Bottom）

## 参考
[https://note.com/fjkn/m/m9829c621e025](https://note.com/fjkn/m/m9829c621e025)
【Vue】day.jsを使って時間を表示する。


#day.jsとは

ずばり日付に関するライブラリです。

#day.jsの導入方法

以下のnpm、yarnを使ってインストールします。

- npm

```
npm install dayjs --save
```

- yarn

```
yarn add dayjs
```
#導入手順
###1.ライブラリの取り込み

```javascript
import dayjs from "dayjs";

dayjs.locale("ja");
Vue.prototype.$dayjs = dayjs;
```

###2.テンプレートを準備

```
<div class="mytime">{{ $dayjs(time).format("hh:mm") }}</div>
```

#細かく日時を設定したい場合

公式リファレンスを参照してください。

https://day.js.org/docs/en/installation/installation
Webメンタル疾患、服薬管理システムのドキュメントです

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/c49e04f1-34c1-d618-5e11-aa4c6ccc1cd9.jpeg)
Webメンタル疾患、服薬管理システムのドキュメントです。
本システムは主治医の先生にも見て頂くため、テキストファイルで管理しています。

1.要件定義
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/946dd738-c8fb-f628-fcd8-2ee96967c297.jpeg)


2.プログラム構成図

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/1f705d28-5d51-2fc0-ad02-4da6d8c7528b.jpeg)


3.画面の使い方
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/db98484f-d6c9-0882-1224-cbe960ccce85.jpeg)

![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/c2b3fd55-c1ca-1a69-5a57-ff0a0a3ff36b.jpeg)


![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/f745b7f4-3f4d-d969-46d7-c7572954d55f.jpeg)
さようなら CentOS8 こんにちは AlmaLinux

# CentOS8 のEOL問題
2020年12月 に「CentOS8 のリリースは2021年末まで」という（[詳しくはこちら](https://academy.gmocloud.com/qa/20210422/11154)）発表からはや半年、そろそろなんとかしないと重い腰を上げてみました。

# RHEL互換をうたっている移行先
「Red Hat Enterprise Linux 8、[CentOS Stream 8](https://blog.centos.org/2020/12/future-is-centos-stream/)、Oracle Linux 8、RockyLinux、AlmaLinux」があり、ぱっとみ `CentOS Stream 8` がよさそうにみえますが Fedora みたいな[位置づけ](https://www.miraclelinux.com/tech-blog/difference_between_centos_and_centos_stream)のようです。そんな訳でいまのとろこ商用利用可能な `RockyLinux` `AlmaLinux` が有力かなと思っています。

## CentOS Stream の移行方法
とりあえずCentOS Stream に移行してみる。
CentOS Linux 8 から CentOS Stream 8 への[マイグレーション](https://centos.org/distro-faq/#q7-how-do-i-migrate-my-centos-linux-8-installation-to-centos-stream)は意外と簡単でした。

```text
# dnf install centos-release-stream
# dnf distro-sync
# uname -r
4.18.0-301.1.el8.x86_64
# cat /etc/redhat-release
CentOS Stream release 8
```

とりあえずkvmとそのゲストOSも含めて移行してみたが特に問題なく使えている（当たり前か）。

## AlmaLinux 
いまのとろこのAlmaLinux に移行して運用しようと思っています。こちらもマイグレーションは簡単ですね。

```text
# curl -O https://raw.githubusercontent.com/AlmaLinux/almalinux-deploy/master/almalinux-deploy.sh
# sudo bash almalinux-deploy.sh
# uname -r
4.18.0-240.22.1.el8_3.x86_64
# cat /etc/almalinux-release
AlmaLinux release 8.3 (Purple Manul)
```

# マイグレーションをする際の注意
当たり前だけど 必ずバックアップしてから実施すること。あと 1G位の空きが必要となるようです。

# AlmaLinux で運用してみて
とりあえず AlmaLinux に移行して２週間。特に問題なく使えてます。１点不満なのは Cockpit からの ソフトウエア更新チェックが遅いこと。それ以外は問題なく動作していｒます。

# 参考にさせて頂いたサイト
・[AlmaLinuxを使ってみた（後編）](https://qiita.com/yamada-hakase/items/17b41d33e30232b69fe2)
・[Red Hat Enterprise Linux のバイナリ互換 OS の AlmaLinux をいじってみた。](https://pc-freedom.net/today_pc_story/almalinux-8-3-release/)
・[CentOS8の2021年末でのサポート終了を受けて今後の対応策と選択肢を考える](https://www.geekfeed.co.jp/geekblog/migration-path-from-centos8)
MacBookAir向けLinuxカーネルBuild

# LinuxカーネルBuild
MacにてLinuxカーネルBuildにトライ。できるだけ軽量かつ最低限の機能は搭載することを意図する。

## 用いたマシン
MacBook Air 11 inch
2GHz Intel Core i7
（購入時のマザーボードは故障して交換したため、スペックアップ）
8GB RAM

## 準備
### マルチブート
MacOSとのマルーチブートを実現したかったため、[rEFInd](https://www.rodsbooks.com/refind/)をインストール（Mac OS High Sierra(10.13.6)経由）。Windows10もインストールしているため、トリプルブートとなっている。

### Lubuntuダウンロード
[ここ](https://lubuntu.me/downloads/)から、最新LTSである20.04をダウンロードしてインストールする。

## Build
LinuxカーネルBuildについて検索すると多数の情報が見つかるが、[このサイト](https://phoenixnap.com/kb/build-linux-kernel)をベースにすすめた。

### カーネルソースコード
[本家サイト](https://www.kernel.org)からソースコードをダウンロード。用いたバージョンは、5.10.32。

```
$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.32.tar.xz
```

### 必要なパッケージのインストール
```
$ sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison
```

### Configuration
起動中Linuxのバージョンの情報を使って、「.config」をカスタマイズする。

```
$ cd linux-5.10.32
$ cp /boot/config-$(uname -r) .config
```

軽量化するために、[このサイト](https://dtyler.io/articles/2017/12/29/about-kernel-make-config/)を参考にした。下記順にmakeを実行。

```
$ make allnoconfig
$ make defconfig
$ make menuconfig
```

「allnoconfig」で最小化、「defconfig」でアーキテクチャ依存のデフォルト化を行う。「menuconfig」では、カーネル名の文字列追加（"_may1"）のみを実施。

### MacBookAir（Mac?）固有のConfiguration
上記だけでは不十分であろうと判断して、「.config」中のApple関連をすべて有効化した（オリジナルの「.config」を参考に）。

```
CONFIG_APPLE_PROPERTIES=y
CONFIG_MOUSE_APPLETOUCH=m
CONFIG_SENSORS_APPLESMC=m
CONFIG_BACKLIGHT_APPLE=m
CONFIG_HID_APPLE=y
CONFIG_HID_APPLEIR=m
CONFIG_USB_APPLEDISPLAY=m
CONFIG_APPLE_MFI_FASTCHARGE=m
CONFIG_APPLE_GMUX=m
```

これでBuildしてトライしたが、タッチパッドおよびWiFiが使えず。調べたところ、次の有効化が必要であった。

```
CONFIG_MOUSE_BCM5974=m
CONFIG_BRCMSMAC=m
```

前者がタッチパッド、後者がWiFi用のConfiguration。

### make
```
$ make -j 4
```

おおよそ45分くらい要した。ちなみに、単に/bootディレクトリからコピーしてきた「.config」を使ってBuildしたときには、4時間以上かかった。当然であるが、軽量化すれば、Build時間も減る。

```
$ sudo make install_module
$ sudo make install
```

によりインストール。/bootディレクトリにBuildされたカーネルがコピーされる。

## 起動
rEFIndによるOS選択画面は次にようになり、デフォルトでは最後にBuildしたカーネル（末尾に追加した文字列「_may1」）で起動する。
![IMG_20210502_103403.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/7530fb5a-559a-86cf-9adf-39377a63d882.jpeg)

ここでF2を押すと、
![IMG_20210502_103338.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/5f64253a-2e5a-876a-69af-a06f6a6d7bc7.jpeg)
となり、他のカーネルを選択できる。

作成したカーネルの状況をunameコマンドで確認。（小さくてごめんなさい。MacBookAirを見せたかったので。）
![IMG_20210503_132847.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/59b193c5-6d8a-4244-7a16-f0571d3b8996.jpeg)

成功。
FSCalendarの日付の下にLabelを表示させる

FSCalendar関連で調べていたのですがイベントのドットを表示する方法が多く、Labelを表示する方法が少なかったのでここに残しておきます。

```
func calendar(_ calendar: FSCalendar, willDisplay cell: FSCalendarCell, for date: Date, at monthPosition: FSCalendarMonthPosition) {

        let taijulabel = UILabel(frame: CGRect(x: 20, y: 25, width: 20, height: 20))
        taijulabel.font = UIFont.systemFont(ofSize: 8)
        taijulabel.text = "２３"
        taijulabel.textColor = UIColor.lightGray
        taijulabel.layer.cornerRadius = cell.bounds.width/2

        cell.addSubview(taijulabel)

    }
```
willDisplay cellメソッドを使用します。

cell.addSubviewでCellの上にラベルを貼るイメージでしょうか。

今回は日付の下に小さく数字を入れてみました。
![スクリーンショット 2021-05-15 9.25.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1112697/908c8b0c-10a3-2816-6b0c-4ca2ab45c53f.png)

こんな感じになります。

色々できそうなので、幅が広がりそうです！
MySQLの日付関数

MySQLの日付関数についてよく使うものを備忘録としてまとめました。

#####現在の日時

```
SELECT CURDATE() AS cur_d,
       NOW() cur_dt;

+-------------+----------------------------+
| cur_d       | cur_dt                     |
+-------------+----------------------------+
| 2020-09-20  | 2020-09-21 12:34:56        |
+-------------+----------------------------+
```

#####現在の日時を YYYY-MM-DD HH:MM:SS形式で表示

```
SELECT DATE_FORMAT(CURDATE(), "%Y-%m-%d %H:%i:%s") AS fmt_d,
       DATE_FORMAT(NOW(), "%Y-%m-%d %H:%i:%s") AS fmt_dt;

+---------------------+---------------------+
| fmt_d               | fmt_dt              |
+---------------------+---------------------+
| 2020-09-20 00:00:00 | 2020-09-20 12:34:56 |
+---------------------+---------------------+
```

#####現在の日時を日（時分秒は全て0）で丸める

```
SELECT DATE_FORMAT(DATE(NOW()), "%Y-%m-%d %H:%i:%s") AS dt_trc;

+---------------------+
| dt_trc              |
+---------------------+
| 2020-09-20T00:00:00 |
+---------------------+
```

#####現在の日時に日を加算

```
SELECT DATE_ADD(CURDATE(), INTERVAL 1 DAY) AS d_add,
       DATE_ADD(NOW(), INTERVAL 1 DAY) AS dt_add;

+-------------+----------------------------+
| d_add       | dt_add                     |
+-------------+----------------------------+
| 2020-09-21  | 2020-09-21 12:34:56        |
+-------------+----------------------------+
```


#####日付から一部(年/月/日)を抽出

```
SELECT
  EXTRACT(YEAR FROM '2021-05-15') AS YYYY
  , EXTRACT(YEAR_MONTH FROM '2021-05-15 01:02:03') AS YYYYMM
  , EXTRACT(DAY_MINUTE FROM '2021-05-15 01:02:03') AS DDHHMI
  , EXTRACT(MICROSECOND FROM '2021-05-15 10:30:00.000123') AS SS
;

+----------+----------+----------+----------+
| YYYY     | YYYYMM   | DDHHMI   |  SS      |
+-------------+-------+----------+----------+
| 2021     | 202105   | 150102   | 123      |
+----------+----------+----------+----------+
```

#####文字列から日付型へ変換

```
SELECT STR_TO_DATE('2020-09-20', '%Y-%m-%d') AS str_d_1,
       STR_TO_DATE('2020年9月20日', '%Y年%m月%d日') AS str_d_2;


+-------------+---------------------+
| prs_d       | prs_dt              |
+-------------+---------------------+
| 2020-09-20  | 2020-09-20          |
+-------------+---------------------+
```

#####月初と月末

```
SELECT
  DATE_FORMAT( CURDATE(), '%Y-%m-01') AS 今月1日（月初）
  , LAST_DAY( now()) AS 今月末
  , DATE_FORMAT( DATE_ADD(CURDATE(), INTERVAL -1 MONTH), '%Y-%m-01') AS 先月1日（月初）
  , LAST_DAY( DATE_FORMAT( DATE_ADD(CURDATE(), INTERVAL -1 MONTH), '%Y-%m-01')) AS 先月末
;

+--------------+--------------+--------------+--------------+
| 今月1日（月初）  | 今月末        | 先月1日（月初）  | 先月末        |
+--------------+--------------+--------------+--------------+
| 2020-09-01   | 2020-09-31   | 2020-08-01   | 2020-08-31   |
+--------------+--------------+--------------+--------------+
```

##参考：
[MySQL リファレンスマニュアル 12.7 日付および時間関数](https://dev.mysql.com/doc/refman/5.6/ja/date-and-time-functions.html)
Mysqlデータベースをwindowsでdumpしてubuntuでインポートする

タイトルの操作をしようとしてツボにはまってしまったので。

Windowsのpowershellから[とほほコマンド](https://www.tohoho-web.com/ex/mysql-mysqldump.html)でdumpした：

```sh:dump.sh
mysqldump -h localhost -u root -pパスワード --databases twitter > dump.sql
```

で、これをubuntuにインポートしようとしたらエラーが起きた：

```sh:import.sh
ubuntu@ip-xxx-xx-xx-xx:~/workspace$ sudo mysql -u root -p twitter < dump.sql
Enter password:
ERROR: ASCII '\0' appeared in the statement, but this is not allowed unless option --binary-mode is enabled and mysql is run in non-interactive mode. Set --binary-mode to 1 if ASCII '\0' is expected. Query: '・'.
ubuntu@ip-xxx-xx-xx-xx:
```

どうやら、powershellの文字コードの問題だったらしく、powershellのデフォルト処理文字コードはCP932(≒SJIS)であるから文字化けしちゃったんじゃねーの、ということであった（[参考](https://teratail.com/questions/43154)）。

じゃーpowershell以外からdumpすればよいのでは、ということでmysql workbenchからdumpしてインポートを再度試みたところ、無事成功してくれた：

```sh:import_agagin.sh
ubuntu@ip-xxx-xx-xx-xx:~/workspace$ sudo mysql --binary-mode -u root -p twitter < Dump20210515.sql
Enter password:
ubuntu@ip-xxx-xx-xx-xx:
```

よかったですね。
Pythonでメール送信の時添付ファイルを複数添付して送る


#Pythonでメール送信の時添付ファイルを複数添付して送る
力技で解決

```python
import os
import smtplib
import ssl
import sys
import glob
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# 第1引数が送り先、第2が添付したいファイルが入っているフォルダ
def sendmail(sendto, attach):
    account = "XXX@co.jp"
    password = "XXX"

    # 送受信先
    to_email = sendto
    from_email = "from"

    # MIMEの作成 -メール本文の内容
    subject = "XXX"
    message = "XXX\n"
    msg = MIMEMultipart()
    msg["Subject"] = subject
    msg["To"] = to_email
    msg["From"] = from_email
    msg.attach(MIMEText(message))

    # ファイルを添付　引数で指定したフォルダのファイルを添付する
    for file in attach:
        fname = os.path.basename(file)
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(open(file, 'rb').read())
        encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment', filename=fname)
        msg.attach(part)

    # メール送信処理

    server = smtplib.SMTP_SSL("XXX", 465, context=ssl.create_default_context())
    server.login(account, password)
    server.send_message(msg)
    server.quit()

#　PDFだけ送りたかったのでこの書式になった
#　尚、個人的な環境からiniからメールアドレスを抽出して送付する形となっている
sendfileXXX = glob.glob(r"D:\Users\XXX\Desktop\mail\XXX\*.pdf")
f = open(r"D:\Users\XXX\Desktop\mail\XXX\mail.ini", 'r')
sendtoXXX1 = f.read()
f.close()
sendmail(sendtoXXX1, sendfileXXX)

sys.exit()
```
AWSを理解する[S3編]

#概要
はじめに、この記事はAWS初学者が備忘録として作成しています。
ですが、私のような初学者のために少しでもなればと思い、公開しています。
不適切や、わかりにくい点を見つけた場合はご指摘頂ければ幸いです。

1. [ネットワークを構築する](https://qiita.com/enuii3/items/103c4b9b0db472f36ddb)
2. [webサーバーソフトをインストールする](https://qiita.com/enuii3/items/a68f42563a6331b89db3)
3. [webサーバーにWordPressをインストールする](https://qiita.com/enuii3/items/cfd0053a27ab2ccb052d)
4. [通信の仕組みを理解する](https://qiita.com/enuii3/items/7f1196c28ae740c91482)
5. [S3を使って公開する](https://qiita.com/enuii3/items/db930446f334db3ce1da/)👈今ここ

#S3を使って公開する際の要点
1. S3バケットを作成する
2. Static Website hosting機能を有効にする
3. 匿名アクセスできるようにする(バケットポリシーの設定)
4. 公開したいファイルをアップロードする

##Static Website hosting機能についての補足
S3バケットにアクセスするときのURLのことをエンドポイントという
デフォルトではアクセス権限が付与されたユーザーしかwebサーバーとしてのS3にアクセスできないので、アクセスするにはパケットポリシーの設定を変更して、匿名アクセスできるようにする必要がある。

###インデックスドキュメントとエラードキュメントを設定する
**インデックスドキュメント**: `https://S3バケット名/`や、`http://S3バケット名/フォルダ名/フォルダ名/`などのように、/で終わるURLを指定した時に返すファイルのこと

**エラードキュメント**: 指定したファイルが存在しないなど、何かしらのエラーが発生したときに返すページを構成するファイルです。(エラードキュメントの機能を使わない時でもこの機能は必須で、error.htmlを指定する)

**リダイレクトルール**: 特定のURLが指定された時に、別のURLにリダイレクトするための設定

###リダイレクトルールの補足
コンテンツの一部が別のサーバーにある時に使う設定です。代表的な使い方は、S3とは別にプログラムを実行可能なWebサーバー(例えば、Apacheやnginxなどをインストールしたサーバー(EC2など))を構築しておき、/cgi-bin/などのURLパスが入力された時に、そちらにリダイレクトするという運用
リダイレクトルールを設定することで、ファイルの配信はS3、プログラムの実行は別のサーバーというような構成ができる。
また、リダイレクトではHTTPのステータスコードによってリダイレクトすることもできるので、ファイルが見つからないエラーが発生したときは、特定のページにリダイレクトという設定にもできる。

##カスタムポリシーの設定
S3の既存のポリシーでは匿名アクセスを許可することはできないため、カスタムポリシーを設定する必要がある。
そのためにはまず、S3のアクセス許可から下記の項目のチェックを外す。
> 任意のパブリックバケットポリシーまたはアクセスポイントポリシーを介したバケットとオブジェクトへのパブリックアクセスとクロスアカウントアクセスをブロックする

カスタムポリシーはJSON形式のデータとして構成しなければならないが、全ユーザーに読み取り権限を与えるポリシーに限っては、設定用JSON形式データがAWSのドキュメント(下記のJSON)として公開されているので、バケット名を変更する必要がある

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::example-bucket/*"]
    }
  ]
}
```
- **Version**: この設定構成のバージョン番号です。指定された通りの値を、そのまま使います(設定項目が改定されて、新しい項目が追加されたり、設定の書き方が変わったりするときは、このバージョン番号が変わる)
- **Sid**: このポリシーの名称です。任意の名称
- **EffetctとPrincipal**: Effectは許諾の種類、principalは誰に対するのか指定します。ここで指定されているAllowは許可、*は全ユーザーを示します。つまり、全ユーザーに対して許可という意味になります。
- **ActionとResource**: Actionはどんな操作か、Resourceは何に対してかを指定します。Actionで指定されているs3:Getobjectは読み取りの操作を示している。Resourceで指定している*arn:aws:s3:::example-bucket/\*'は、その対象です。

>are:aws:s3:リージョン:アカウント:バケット名/パス名

「:」と書かれて何も書かれていない場所は指定しないという意味です。
また「\*」は全てを意味します。つまり、この例では、リージョン、アカウントにかかわらず、example-bucketという名前のS3バケットの全てのパス(*)に対する操作をいう意味になります。

#tips
###独自ドメイン名でのアクセスや暗号化通信も見据えたWebサーバーの構成図
- 独自ドメインを使用したい場合はS3のバケット名をwww.example.co.jpなどにした上でDNSサーバーの設定をする(S3のバケット名は後から変更できない)
- S3バケットのWeb機能は暗号化に対応していなく、暗号化したい場合はS3の前段に適切に設定したCloudFrontを設置することで対応可能(https://でアクセスが可能になる)

- **CloudFront**: コンテンツのキャッシュ機能を提供するサービス(暗号化の機能がある)
How to create JSON from spreadsheet data

## Workflow
1.Create Google apps project.

2.Create files at project.
→env.gs&code.gs

3.Copy the code below
Put spreadsheet id & sheet name at the appropriate place.

```js:env.gs
const SPREAD_SHEET = SpreadsheetApp.openById('spreadsheet id');
const SHEET_API =  "sheet name";
```

```js:code.gs
function getData(sheetName) {
  var sheet = SPREAD_SHEET.getSheetByName(SHEET_API);
  const rows = sheet.getDataRange().getValues();
  const keys = rows.splice(0, 1)[0];
  return rows.map(row => {
    const obj = {};
    row.map((item, index) => {
      obj[String(keys[index])] = String(item);
    });
    return obj;
  });
}

function doGet() {
  var data = getData('SHEET_API');
  return ContentService.createTextOutput(JSON.stringify(data, null, 2))
  .setMimeType(ContentService.MimeType.JSON);
}

```

4.Push Deploy
Then select New Deploy
Change "Users who can access" to "Everyone"

5.Get url
chakra-ui & react-hook-form サンプル


### Form Component

HookForm.tsx

```:HookForm.tsx
import * as React from 'react'
import { useForm } from 'react-hook-form'
import { Input, Button } from '@chakra-ui/react'
import { FormErrorMessage, FormLabel, FormControl } from '@chakra-ui/react'

type FormData = {
  firstName: string
  lastName: string
}

export function HookForm() {
  //
  const {
    register,
    handleSubmit,
    formState,
    formState: { errors },
  } = useForm<FormData>({
    mode: 'all',
  })

  // const onSubmit = handleSubmit((data) => console.log(data))

  function onSubmit(values) {
    return new Promise(() => {
      setTimeout(() => {
        alert(JSON.stringify(values, null, 2))
      }, 1000)
    })
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <FormControl id="firstName" isInvalid={!!errors.firstName} isRequired>
        <FormLabel>First Name</FormLabel>
        <Input placeholder="first name" {...register('firstName', { required: true })} />
        <FormErrorMessage>{errors.firstName && 'First name is required'}</FormErrorMessage>
      </FormControl>

      <FormControl id="lastName" isInvalid={!!errors.lastName} isRequired>
        <FormLabel>Last Name</FormLabel>
        <Input placeholder="last name" {...register('lastName', { required: true })} />
        <FormErrorMessage>{errors.lastName && 'Last name is required'}</FormErrorMessage>
      </FormControl>

      <Button mt={4} colorScheme="teal" isLoading={formState.isSubmitting} type="submit">
        Submit
      </Button>
    </form>
  )
}

```



### stories

HookForm.stories.tsx

```
import React from 'react'

import { Story, Meta } from '@storybook/react/types-6-0'
import { HookForm } from '../../../components/example/validation/HookForm'

export default {
  title: 'Example/HookForm',
  component: HookForm,
} as Meta

export const HookFormSample: Story = (args) => <HookForm {...args} />

```
cscの作法 その47 sha256

#概要

cscの作法、調べてみた。
sha256やってみた。

#サンプルコード

```
using System;
using System.Text;
using System.Security.Cryptography;
using CodeShare.Cryptography;

public class Program
{
	public static void Main()
	{
		string inputValue = "abc";
		string actualResult256 = SHA.GenerateSHA256String(inputValue);
		Console.WriteLine("Input: " + inputValue);
		Console.WriteLine("Actual: " + actualResult256);
		inputValue = "";
		actualResult256 = SHA.GenerateSHA256String(inputValue);
		Console.WriteLine("Input: " + inputValue);
		Console.WriteLine("Actual: " + actualResult256);
		actualResult256 = SHA.FromHexString("d3");
		Console.WriteLine("Input: d3");
		Console.WriteLine("Actual: " + actualResult256);
		actualResult256 = SHA.FromHexString("11af");
		Console.WriteLine("Input: 11af");
		Console.WriteLine("Actual: " + actualResult256);
	}
}

namespace CodeShare.Cryptography
{
	public static class SHA
	{
		public static string GenerateSHA256String(string inputString)
		{
			SHA256 sha256 = SHA256Managed.Create();
			byte[] bytes = Encoding.UTF8.GetBytes(inputString);
			byte[] hash = sha256.ComputeHash(bytes);
			return GetStringFromHash(hash);
		}
		public static string FromHexString(string hexString)
		{
			byte[] bytes = new byte[hexString.Length / 2];
			for (int i = 0; i < bytes.Length; i++)
			{
				bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
			}
			SHA256 sha256 = SHA256Managed.Create();
			byte[] hash = sha256.ComputeHash(bytes);
			return GetStringFromHash(hash);
		}
		public static string GenerateSHA512String(string inputString)
		{
			SHA512 sha512 = SHA512Managed.Create();
			byte[] bytes = Encoding.UTF8.GetBytes(inputString);
			byte[] hash = sha512.ComputeHash(bytes);
			return GetStringFromHash(hash);
		}
		private static string GetStringFromHash(byte[] hash)
		{
			StringBuilder result = new StringBuilder();
			for (int i = 0; i < hash.Length; i++)
			{
				result.Append(hash[i].ToString("X2"));
			}
			return result.ToString();
		}
		public static string Hex2Str(string hexString)
		{
			byte[] bytes = new byte[hexString.Length / 2];
			for (int i = 0; i < bytes.Length; i++)
			{
				bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
			}
			return Encoding.UTF8.GetString(bytes);
		}
	}
}





```

#結果

```


Input: abc
Actual: BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD
Input:
Actual: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
Input: d3
Actual: 28969CDFA74A12C82F3BAD960B0B000ACA2AC329DEEA5C2328EBC6F2BA9802C1
Input: 11af
Actual: 5CA7133FA735326081558AC312C620EECA9970D1E70A4B95533D956F072D1F98


```

以上。
Jetson Xavier NXでXsensのIMUを使いたい

Jetson Xavier NXで自律移動システムを構成するときに，IMUとしてXsens社のMTi-30を使おうと思ったのですが，単にxsens_driverをaptでインストールするだけでは動かなかったのでメモをまとめます．

## 症状
xsens_driverをaptでインストールしてroslaunchしても，下記のエラーメッセージが出てきます．

```
fatal could not find proper mt device
```

もちろん値は取れません．lsusbを叩くとデバイス自体は見えているので，その先のドライバ周りが怪しそうです．

## なぜ動かない？


そもそもなぜ動かないかを調べたところ，普段のUbuntuのカーネルには含まれているドライバがJetson向けイメージでは入っていないことが原因のようです．Xavier NXに限った話ではなく，AGX Xavierでも[同じくXsensのデバイスが検出できない症例](https://forums.developer.nvidia.com/t/xavier-cannot-recognize-xsens-solved/66673)が起きており，TX1や2でもカーネルの都合でそのままでは[動かないデバイス](https://qiita.com/karaage0703/items/9bef6aeec9ad24f647c6)の記事も割とありました．ライセンス的な都合なのでしょうか．不便．

## 解決策


ドライバがないなら入れれば良いじゃない，ということで自分でビルドしてカーネルにインストールすることにしました．[上記の症例](https://forums.developer.nvidia.com/t/xavier-cannot-recognize-xsens-solved/66673/15)やそこから参照されているページに沿って進めてみたのですが，xsens_mt.koが生成されずに困っていたところ，Xsens社のコミュニティページに[良い感じの手順](https://base.xsens.com/hc/en-us/community/posts/211806629-MTi-300-not-working-on-NVIDIA-TX1-platform-Kernel-3-10-96-)が載っていました．これに基づいて実際に叩いたコマンドを以下にまとめます．

```
cd ~
git clone https://github.com/xsens/xsens_mt.git
cd xsens_mt/
make
sudo modprobe ./xsens_mt.ko
sudo depmod -a
sudo cp xsens_mt.ko /lib/modules/4.9.140-tegra/kernel/drivers/usb/serial/
sudo reboot now
rosstack profile
rospack profile
sudo depmod -a
sudo reboot now
```

何やかんや試行錯誤行き当たりばったりで試したログをそのまま貼っているので，冗長だったり足りない内容があるかもしれませんがとりあえずこれで動いたのでメモとして残しておきます．

## 参考

- ROS.org [xsens_driver] : http://wiki.ros.org/xsens_driver
- xavier cannot recognize xsens (Solved) : https://forums.developer.nvidia.com/t/xavier-cannot-recognize-xsens-solved/66673
- A guide to solve USB serial driver problems on TX2 : https://forums.developer.nvidia.com/t/a-guide-to-solve-usb-serial-driver-problems-on-tx2/60787#5254939
- Jetson NanoでMIDIを使うためにカーネルビルド : https://qiita.com/karaage0703/items/9bef6aeec9ad24f647c6
PostgreSQL初学者 忘備録 ［MacOS］

PostgreSQL初学者の忘備録。
PostgreSQLをインストールした後、ターミナルから弄っていくことを想定。
なおテーブルの作成などはFlask-SQLAlchemyから行います。

# PostgreSQLサーバーの起動・停止
起動と停止には大きく分けてOSのデーモン管理コマンド（Macではbrew）から行うパターンとPostreSQLコマンドから行う方法がある。ここではデーモン管理コマンドの方のみ掲載します。

```console
# 起動
brew services start postgresql

# 停止
brew services stop postgresql

# 再起動
brew services restart postgresql
```


# psqlを利用したPostgreSQLの対話型処理
psqlコマンドはPostgreSQLのターミナル型フロントエンドです。
これを用いることでターミナルからPostgreSQLに問い合わせを行い、結果を確認することができます。

#　DB一覧の表示

```console
psql -l
```

# 特定のロールからアクセス
ロールとはユーザーとグループが1つになったものです。
つまりそれぞれ権限を持った、ログインの最小単位となるユーザーもロール、
そのユーザーをまとめて任意の集団であるグループもロール、ということになります。

PostgreSQLは初回インストール後、自動であらゆる権限が付与されたスーパーユーザーが作成されています。
なお随所でその名称はpostgresと言われていますが、brewでインストールした際はpostgresではなく、MacBookのアカウント名になります。

またスーパーユーザー同様に自動でpostgres, template0, template1というDBも作成されます。
今回はスーパーユーザー名がpostgresだと仮定して、
template1にアクセスするには

```console
psql -U postgres -d template1
```

となります。
psqlのオプションで-Uはアクセス時のロール名指定に、-dはデータベース名指定に使用します。
なおロール名とデータベース名が一緒である場合は

```console
psql　-U postgres
```

とDB名を省略してOKです。
また

```console
psql template1
```

とした場合はDB名が指定されたこととなります。
またその時指定されていないロール名はOSのユーザー名が使われます。
（なのでbrewでインストールした際は省略するとスーパーユーザーでのアクセスとなります）

アクセス時には他にもホスト名やポート番号を指定することもでき、それを含めると

```console
psql -h ホスト名 -p ポート番号 -U ロール名 -d データベース名
```

となる。
なお-hを省略した場合はlocalhost、-pを省略した場合はインストール時に設定したポート（通常は5432）となっている。
また再掲すると -d省略時はアクセスするDB名はユーザー名と同じになり、-Uを省略した場合はOSのユーザー名がロール名となる。

# ロールの作成
いつまでもスーパーユーザーでアクセスするわけにもいかないのでロールを作ります。
これ以降は上記の方法で特定のDBにアクセスした状態で作業します。

ロールを作成するには

```sql
CREATE ROLE ロール名;
```

もしくは

```sql
CREATE USER ロール名;
```

上記2つの違いはCREATE USERの場合はデフォルトで作成したロールにログイン権限（＝データベースに接続する権限）が付与されています。
CREATE ROLEの方はデフォルトでは付与されていません。付与する場合は、

```sql
CREATE ROLE ロール名 LOGIN;
```

とします。
基本的にロール作成時の権限付与はCREATE ROLE ロール名 権限名;と付与していきます。
主な権限は

・ログイン：LOGIN
・データベース作成：CREATEDB
・ロール作成：CREATEROLE
・スーパーユーザーにする：SUPERUSER

あたりでしょうか。

また上記の権限を取りたい、もしくは今ないロールに与えたい場合は

```sql
# 与える場合
ALTER ROLE ロール名 権限名

# 取り去る場合
ALTER ROLE ロール名 NO権限名
```

とする。例えば既に作成済みでログイン権限のあるロール・user1からログイン権限を取るには

```sql
ALTER ROLE ロール名 NOLOGIN
```

とします。

なおアクセス時にパスワードを要求する場合は

```sql
CREATE ROLE ロール名 WITH PASSWORD 'パスワード';
```

とします。
Git管理下にソース管理したくないゴミファイルを置きたい時

# Git管理下にゴミを置く
Git管理下に雑多なメモとかを置きたい時ありますよね。
普通にファイル作成するとそれが追加ファイル扱いでdiffになってしまい、いちいち差分で出てきて邪魔です。また、誤って`git add .`なんかした日にはゴミがメンバー全体の目に晒されることになります。

具体的には以下のようなフォルダ構成の時、

```
├── .gitignore
├── fuga
│   └── fuga.dart
├── hoge
│   └── hoge.dart
└── piyo
    └── piyo.dart
```

こういう感じにメモを置いておきたい、みたいなケースを想定しています。

```
├── .gitignore
├── fuga
│   └── fuga.dart
├── hoge
│   └── hoge.dart
├── memo
│   ├── awesome_memo.md ←
│   ├── memo1.md ←
│   └── memo2.md ←
└── piyo
    └── piyo.dart
```

`memo`フォルダをルートにある`.gitignore`に追加すれば`memo`フォルダ配下のファイルは差分に出て来なくなりますが、.gitignore自体に差分が出てしまうため同様に誤ってコミットしてしまう可能性があります。そのため、この方法は採用できません。


# どうやってゴミを無視するか
## Step 1
ゴミを置いてあるフォルダの直下に`.gitignore`を追加します

```
├── .gitignore
├── fuga
│   └── fuga.dart
├── hoge
│   └── hoge.dart
├── memo
│   ├── .gitignore ←　追加
│   ├── awesome_memo.md
│   ├── memo1.md
│   └── memo2.md
└── piyo
    └── piyo.dart
```

## Step 2
`.gitignore`を以下のように編集します

```..gitignore
*
```
`.gitignore`は深い階層にあるものの設定が優先されるため、このようにするとフォルダ内の全ファイルがソースコントロールの対象外になります。
また、全ファイルを指定することで`.gitignore`ごとignoreできます。

お試しください。
【Quantization】pytroch でFP32をFP16にすると遅くなる

# 背景

実行速度を上げたくFP32をFP16にしてみた

# 実験

stereo matchingのPSMNetで実験してみた
FP32(args.half=False)とFP16(args.half=True)

```
    model.eval()

    if args.cuda:
        imgL = imgL.cuda()
        imgR = imgR.cuda()
    
    if args.half:
        model.half()
        imgL = imgL.half()
        imgR = imgR.half()

    with torch.no_grad():
        torch.cuda.synchronize()
        start_time = time.time()
        pred_dispL = model(imgL, imgR)
        torch.cuda.synchronize()
        processing_time = time.time() - start_time
        print("time = %.4f" % (processing_time))

```


# 結果

FP32
time = 0.5656[s]
time = 0.5608[s]
time = 0.5621[s]
time = 0.5624[s]
time = 0.5623[s]
time = 0.5626[s]

FP16
time = 0.7387[s]
time = 0.7365[s]
time = 0.7357[s]
time = 0.7370[s]
time = 0.7365[s]

# 結論

なぜだかFP16の方が遅い
何回やっても違うモデルでやってもFP16の方が遅い
今後理由を調査したい
ER図からテーブル定義書を自動生成する方法

## はじめに
UMLで記述したER図のデータからGoogleSpreadSheetのテーブル定義書を自動生成する方法の解説です。
ER図作成からシステム開発を開始する人にはうってつけの方法です。

## サンプル動画
![2021-05-15_11h31_09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490767/141dc30a-c8d9-b079-8a50-73dee8886096.gif)

## 手順
1. UMLで記述したER図をGoogleDriveの任意のディレクトリに保存します
2. 新規でGoogleSpreadSheetを作成します。SpreadSheetのタイトルをUserとします  
※ER図に記載したテーブルのうち、タイトルと同一のカテゴリのテーブルのみを読み込みます
3. ツール → スクリプトエディタを選択し、AppsScriptエディタを開きます  
[https://github.com/stepupdream/import-erdiagram/blob/main/jp.js](https://github.com/stepupdream/import-erdiagram/blob/main/jp.js)  
こちらのソースコードをエディタに貼り付けます。
4. 1行目のdriveFolderIdの部分をER図が保存してあるGoogleDriveのフォルダIDに変更し、変更を保存します  
フォルダーIDとは：[https://www.yukibnb.com/entry/2019/11/26/163738#公式](https://www.yukibnb.com/entry/2019/11/26/163738#%E5%85%AC%E5%BC%8F)
5. スクリプトエディタは閉じ、GoogleSpreadSheetをリロードします
6. リロードするとER図を取り込むというメニューが追加されるので「全データを取り込む」を実行します

## UMLでER図を記述する方法
[https://qiita.com/nagareboshi/items/8369b554d07b27760e59](https://qiita.com/nagareboshi/items/8369b554d07b27760e59)

## ER図のサンプル
```jsx
@startuml

'区分罫線を非表示
hide empty members

'マークと背景色の定義
!define master_data_db #E2EFDA-C6E0B4
!define user_db #FCE4D6-F8CBAD
!define MASTER_DATA AAFFAA
!define User FFAA00

'設定職を定義
skinparam class {
    BorderColor Black
    ArrowColor Black
}

package "ユーザー管理" as user {
    entity "accounts [アカウント]" as accounts <<U, User>> user_db {
        + id : bigInteger [ID]
        # user_id  :  bigInteger  [ユーザID]
    }

    entity "users [ユーザー]" as users <<U, User>> user_db {
        + id : bigInteger [ID]
        name : string [名前]
    }

    entity "prefectures [都道府県]" as prefectures <<M, MASTER_DATA>> master_data_db {
        + id : integer [ID]
        name : string [県名]
    }
}

'関係図を定義
users        ||-up-||     accounts

'テーブルメモ
note right of prefectures : メモです
@enduml
```

## 記述ルール
```jsx
entity "テーブル名 [テーブル日本語名]" as テーブル名 <<カテゴリマーク, カテゴリ>> コネクション名 {
  カラム名 : データ型 [カラム日本語名]
}
```

## 補足
- 「現在のシートのみを取り込む」は、「全データを取り込む」実行時に生成されるデフォルトデータ（1行目のデータ）が存在する時のみ実行可能です
- 「現在のシートのみを取り込む」は、シート名と同一のUMLファイル名のER図を読み取ることができます
- デフォルトデータに追加する形で自由にシートに列を追加可能です。ER図では表現しきれなかった内容などを別途追記するときに便利です。追加した列はER図を再読み込みしても消えることはありません
- ER図とテーブル定義の二重編集を避けるため、テーブル定義書の自動読み込みセルはスプレッドシートの機能のセルの保護をかけておくと便利です
プロバイダーから ProviderManifestToken 文字列が返されませんでした。

# はじめに
下記サイトと同じエラーが発生して困った。。。

◆entity-framework - EntityFrameworkの「System.Data.Entity.Core.ProviderIncompatibleException」
　https://ja.ojit.com/so/entity-framework/2298558


# 参考サイト
◆Using Entity Framework 6 with Npgsql 2.1.0
　http://fxjr.blogspot.com/2014/02/using-entity-framework-6-with-npgsql-210.html
　　※以下は試してみたい
　　　from　defaultConnectionFactory type="Npgsql.NpgsqlConnectionFactory, Npgsql"
　　　to　　defaultConnectionFactory type="Npgsql.NpgsqlConnectionFactory, Npgsql.EntityFramework"

◆Examples What is the ProviderManifestToken value for Oracle.ManagedDataAccess 19.3?
　https://entityframework.net/knowledge-base/60179828/what-is-the-providermanifesttoken-value-for-oracle-manageddataaccess-19-3-
◆Does .Net Framework 4.0 have features for connecting to DB2
　https://stackoverflow.com/questions/979473/does-net-framework-4-0-have-features-for-connecting-to-db2/2009262

◆EF6 & Npgsql #804
　https://github.com/npgsql/npgsql/issues/804
　　

◆DbProviderFactory の取得
　https://docs.microsoft.com/ja-jp/dotnet/framework/data/adonet/obtaining-a-dbproviderfactory
　　※試したいのがいっぱいある...



◆構成ファイルの設定
　https://docs.microsoft.com/ja-jp/ef/ef6/fundamentals/configuring/config-file?redirectedfrom=MSDN
　　※「ファイルへのデータベース操作のログ記録 (EF 6.1 以降)」を試してどうなるか

◆Entity Framework 6 プロバイダー
　https://docs.microsoft.com/ja-jp/ef/ef6/fundamentals/providers/
◆Entity Framework 6 プロバイダーモデル
　https://docs.microsoft.com/ja-jp/ef/ef6/fundamentals/providers/provider-model
　　※このサイトの内容はちゃんと読まないとダメかも...


※これらは関係なさそうだが一応めも
◆Entity Framework upgrade to 6 configuration and nuget magic
　http://robsneuron.blogspot.com/2013/11/entity-framework-upgrade-to-6.html
◆【C#】【Entityframework】DBの値を取得しようとすると例外が発生する
　https://teratail.com/questions/151831
◆Examples
　https://community.denodo.com/docs/html/browse/6.0/vdp/developer/introduction/examples/examples
　　※contains a C# program that sends a query to Virtual DataPort, using the Entity Framework.
◆不変名「MySql.Data.MySqlClient」のADO.NETプロバイダーは、マシンまたはアプリケーションの構成ファイルに登録されていません
　https://www.it-swarm.jp.net/ja/c%23/%E4%B8%8D%E5%A4%89%E5%90%8D%E3%80%8Cmysqldatamysqlclient%E3%80%8D%E3%81%AEadonet%E3%83%97%E3%83%AD%E3%83%90%E3%82%A4%E3%83%80%E3%83%BC%E3%81%AF%E3%80%81%E3%83%9E%E3%82%B7%E3%83%B3%E3%81%BE%E3%81%9F%E3%81%AF%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E6%A7%8B%E6%88%90%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E7%99%BB%E9%8C%B2%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%9B%E3%82%93/827222984/




# TODO
- [ ]  キーワード検索による原因調査
一定期間が過ぎたら使用できなくするコードの作成

#背景
pyinstallerとかでexe化してお試し版を配布する際に、使用期限を付けたいときのコードです。自分で作ったexeが勝手に独り歩きしてあちこちで配布されないために…。

#コード説明
１：今日の日付を入手
２：使用制限"limitdate"を記載して、日付方式に変更。
３：日付を比較して、使用期限を過ぎていないようであれば、何か他の操作に移る。
　（ここではOKがプリントされます）

```python:limit.py
from datetime import datetime

today = datetime.now()

def LIMIT():
  limitdate= str("2021/05/19")
  limitdate = datetime.strptime(limitdate,"%Y/%m/%d") 
  if limitdate >= today:
    print("OK")
  else: 
    sys.exit()

LIMIT()
初心者のためのX線解析（①イメージの生成）

#概要
本シリーズでは、初学者を対象に、ChandraX線天文衛星の観測データの解析手順について説明する。
本トピックはデータのダウンロードからイメージの生成までを目標とする。


#解析に必要なツール

・ciao：ChandraX線天文衛星の観測データを解析するツール。
・ds9：天文系の画像などを描像するソフトウェア。

著者の環境
ciao version：4.13

これらの環境構築については本トピックでは触れない。以下の記事などが参考になる。
https://qiita.com/yamadasuzaku/items/638b60fb7f9f7d8c0e73



#手順
##1. データの取得


###1-1. Observation Searchからデータを検索
以下のサイトからまずデータのID（Obs ID）を取得する。
https://cda.harvard.edu/chaser/mainEntry.do
Target Nameに目標天体の名称を入力==>Search
以下は超新星残骸"Cassiopeia A"の検索結果
![スクリーンショット 2021-05-15 0.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431137/d6a50ccd-a88a-cf91-e162-5e6389f13c24.png)
ここで欲しいデータのObs IDを控えておく。

###1-2. CIAOを起動

```terminal
(base) ajisai:casA tsuchioka$ ciao
```

###1-3. データをダウンロード

```terminal
(ciao-4.13) ajisai:casA tsuchioka$ download_chandra_obsid 4634
```

*download_chandra_obsid [Obs ID]

##2. イメージの作成

###2-1. Obs IDデータセットの処理
```terminal
(ciao-4.13) ajisai:casA tsuchioka$ chandra_repro 4634 4634/repro
```
*chandra_repro [入力ディレクトリ] [出力ディレクトリ]


###2-2. イメージの作成


```terminal
(ciao-4.13) ajisai:casA tsuchioka$ fluximage 4634/repro/acisf04634_repro_evt2.fits 4634/4634
```
*fluximage [入力(イベントファイル)] [出力(flux image)]

・実際にはパラメータとしてカメラの領域やエネルギーバンドなども選べるが、指定しないと勝手にデフォルトの値が採用される。

・先ほどchandra_reproコマンドで生成したイベントファイルにはX線光子のイベントデータが含まれており、これを入力に使う。

・同時に生成される３種類のイメージファイルについて説明する。
1. flux image：各画素値がX線のflux（単位時間あたり単位㎠あたりの光子量）に対応するイメージ。ファイル名が"flux.img"で終わる。
2. thresh image：各画素値がX線光子のカウントに対応するイメージ。ファイル名が"thresh.img"で終わる。
3. exposure map：単なるカウントのマップを物理的に意味のあるフラックスに変換するため(※1)に必要な情報を含んだイメージ。ファイル名が"thresh.expmap"で終わる。

(※1)衛星に搭載されている検出器については、入射場所や入射エネルギーによって検出効率が異なる。そのため有効面積に量子効率をかけたexposure mapを使って各ピクセルのカウント数を補正しなければならない。

→つまり実際にはflux imageはthresh imageをexposure mapで割り算することによって得られている。

###2-3. （応用） 複数のIDから１枚のイメージを作成する

```terminal
(ciao-4.13) ajisai:casA tsuchioka$ merge_obs 4634/,4635/,4636/,4637/,4638/,4639 merged
```
*merge_obs [ID]/, ... /,[ID] [出力(flux image)]

・同じ天体で複数のIDがある場合、それらを組み合わせることで露光時間を増やし統計をよくすることができる。

・merge_obsは、個々のイベントファイルを同じ接線上に再投影するreproject_obsと、観測ごとのイベントファイルからexposure mapやflux imageを作成し、それらを１枚の画像に統合するflux_obsを組み合わせたものである。


##3. イメージの確認

最後にds9というソフトを用いて、作成したイメージの確認を行う。


```terminal
(ciao-4.13) ajisai:4634 tsuchioka$ ds9 4634_broad_flux.img
```
![スクリーンショット 2021-05-15 1.51.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431137/e2a7bca6-e0ff-3917-cb9c-ced1d7a884ab.png)


ここでは表示されているイメージを見やすくするためにds9の設定を操作する。

-「色==>b」でカラーバーの種類を変える。
-「スケール==>対数」でカラーバーを対数軸にする。
-「スケール==>スケールの設定」で表示エネルギー幅を選択。


すると以下のようなイメージが表示された。
![スクリーンショット 2021-05-15 1.52.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431137/37715069-fa4a-5551-df6d-c0ddbe37b14d.png)
#まとめ
本トピックでは、ChandraX線天文衛星の観測データについて、データのダウンロードからイメージの生成までの一通りの流れを説明した。ここでは「必要最低限の解析手順」の説明に留めたが、より解析に工夫を求める場合は以下のサイトからciaoの各コマンドの説明を参考にしていただきたい。
https://cxc.cfa.harvard.edu/ciao/
pythonで作成されたファイルの上書き保存を回避するために


#背景
アウトプットとしてExcel等のファイルを書き出す場合、保存先のフォルダに同一名の大切なファイルがあったのに上書きされちゃって、後々にしまった！と思ったことがあるので、備忘録もかねて同じファイルが存在したら(1)、(2)、(3)…とナンバリングされるようなコードを書きました。
（環境はwindows10のpython3.7.1です。）

#コード説明
###while文の前の準備
１：ファイル名を記載。（ここでは"テスト.xlsx"）
２：ディレクトリからファイル名のリスト(files)を取得。
###while文1周目
１：while文でもし、同じ名前のファイル（"テスト.xlsx"）がファイル名のリスト"files"中にあったら"(1)"をつける。
　（"テスト.xlsx"から".xlsx"を一度消去して、"(1).xlsx"を付けています。）
２：number という変数で"(num-1)"つまり(0)がファイル名にあれば消えるようにする。
　（1周目のwhile文ではこの操作は関係ないです）　
３：num =2になる。
###while文2周目
１：もし"テスト(1).xlsx"もフォルダ内に存在する場合、"(2)"をファイル名につける。
　（"テスト(1).xlsx"から".xlsx"を一度消去して、"(2).xlsx"を付けています。）
２："(num-1)"つまり、今回は"(1)が"ファイル名にあれば消えるようにする。
　（つまり"テスト(1)(2).xlsx"から"(1)"を消す。）

```python:filename.py
import os

filename = "テスト.xlsx"
num = 1
files = os.listdir(base_path)
while filename in files:
    filename = filename(".xlsx","") + "(" + str(num) + ").xlsx"
    number = "(" + str(num-1) + ")"
    filename = filename.replace(number,"")
    num = num + 1
```

もし、デフォルトのファイル名に(1)とかが入ってる場合（”20210515(1)解析.xlsx”みたいな場合）、while文中で(1)が消えちゃうので、そういった場合はrstripで"(数字).xlsx"を消す作業に変更してもよいかもしれません。（いや、むしろこっちの方が良いコードかも？）

```python:filename2.py
import os

filename = "テスト.xlsx"
num = 1
files = os.listdir(base_path)
while filename in files:
    filename = filename.rstrip(".xlsx")
    number = "(" + str(num-1) + ")" 
    filename = filename.rstrip(number)
    filename = filename + "(" + str(num) + ").xlsx"
    num = num + 1
```
20211103：誤字訂正しました。
VSCode 1.56.2 (Windows)でsftpできなくなったよー

5/17 前の修正だとまだ問題あり。以下を参照のこと。
https://github.com/Natizyskunk/ssh2-streams/commit/e1db386ff9b0fc145c67dc13ada3e969d59cc51f#diff-11c2413775403ed66594f387ae0a38ec06ed746902424f86c7cbbbc7e395f4ca

--- 以下は以前分
これを見て修正すべし。

https://github.com/liximomo/vscode-sftp/issues/934
【Androidを使い熟す！】Buttonについて

#####※Android技術者認定にも役に立ちます！

#Button
タッチでイベントを発生させるViewの1つ

#Buttonクラス宣言
```ruby:java
※ Buttonクラスの変数
Button button = findViewById(R.id.button);

※ Buttonクラスのインスタンス化
(コードで書く場合)
Button button = new Button(this);
```

#よく使う機能
・ボタン名セット

```ruby:java
※直接導入
button.setText("文字");

※リソース
button.setText(R.string.text);
```

・クリックイベント

```ruby:java
※ onClickメソッド
extends Activity implements OnClickListener
button.setOnClickListener(this);
public void onClick(View v) {
    if (v == button){
        処理を入れる
    }
}
Tip
 if分ではなくswitch分も代わりによく使う。

※ボタンに直接セット
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        処理を入れる
    }
});

※リスナーセット
button.setOnClickListener(btnListener);
OnClickListener btnListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
        処理を入れる
    }
};

※xml
<Button
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:onClick="clickButton" />

public void ClickButton(View view) {
    処理を入れる
}

```

#Tip
こんな書き方も？

```ruby:java
public class OnClickEvent implements View.OnClickListener {

    private static final OnClickEvent instance = new OnClickEvent();

    private OnClickEvent() {
    }

    public static OnClickEvent getInstance() {
        return instance;
    }

    @Override
    public void onClick(View v) {
        if (v != null) {
            switch (v.getId()) {
                case R.id.button:
                    // クリック処理
                    break;
            }
        }
    }
}
```

```
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout);

    findViewById(R.id.button).setOnClickListener(OnClickEvent.getInstance());
}
```
爆速PayPay API入門

## 関連

- python SDK [https://github.com/paypay/paypayopa-sdk-python](https://github.com/paypay/paypayopa-sdk-python)
- 公式API [https://www.paypay.ne.jp/opa/doc/jp/v1.0/account_link.html](https://www.paypay.ne.jp/opa/doc/jp/v1.0/account_link.html)



## PayPayの登録方法

PayPay for Developersに新規登録をする。
下のURLから新しく開発用のアカウントを作成します。
[PayPay for Developers](https://developer.paypay.ne.jp/account/signup)


## サンプルコードを動かす上で必要な情報

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64677/7b4a7a0a-af1e-520b-8b3f-70607923df68.png)


## パッケージのインストール

開発に必要なパッケージをpip installします

```shell
pip install paypayopa
```

## QRコードのサンプル

実行し、printされたurlにアクセスするとQRコードが生成されます。

```python
import paypayopa
import time

API_KEY = 'xxx'
API_SECRET = 'yyy'
client = paypayopa.Client(auth=(API_KEY, API_SECRET), production_mode=False)
client.set_assume_merchant("zzz")

# requestの送信情報について
# => https://www.paypay.ne.jp/opa/doc/jp/v1.0/preauth_capture#operation/createAuth
request = {
    "merchantPaymentId": round(time.time()), # => 加盟店発番のユニークな決済取引ID
    "codeType": "ORDER_QR",
    "redirectUrl": "http://foobar.com", # => ここを任意のフロントのアプリにしてあげれば良さそう
    "redirectType": "WEB_LINK",
    "orderDescription":"Example - Mune Cake shop",
    "orderItems": [{
        "name": "Moon cake",
        "category": "pasteries",
        "quantity": 1,
        "productId": "67678",
        "unitPrice": {
            "amount": 1,
            "currency": "JPY"
        }
    }],
    "amount": {
        "amount": 1,
        "currency": "JPY"
    },
}

response = client.Code.create_qr_code(request)
print(response['data']['url'])
```

## QRコード支払い

### テストアカウントへのログイン方法

PayPay APIを試すためには、テストユーザーでログインする必要があります。

### PayPayアプリのサンドボックスへのログイン方法

1. 普段使っているPayPayアプリを開く
2. PayPayアプリの中で新規登録／ログイン画面で、PayPayのロゴを７回タップして開発者モードにする
3. テストアカウントでログアウトする
4. 認証コード確認画面に1234を入力する

[テスト環境でPayPayアプリを利用できますか？ – PayPay](https://integration.paypay.ne.jp/hc/ja/articles/4414061901199-%E3%83%86%E3%82%B9%E3%83%88%E7%92%B0%E5%A2%83%E3%81%A7PayPay%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E5%88%A9%E7%94%A8%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%81%8B)

### テストアカウントについて

- [https://developer.paypay.ne.jp/dashboard/home](https://developer.paypay.ne.jp/dashboard/home) にアクセスし、テストユーザータブを選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64677/4a953e2f-059e-2859-aa9f-5a8a585bec9f.png)

## 全体の流れ
1. pythonのコードをからQRコードを生成する
2. PayPayアプリからテストアカウントにログインをし、QRコード決済を行う

爆速でPayPay APIが使えるようになりましたね。
本番運用をするためには、返金等のAPIも実装する必要があるので、こちらのURLをご確認ください。
[PayPay for Developers > checklist](https://developer.paypay.ne.jp/products/docs/checkList)
cloud9でpip installしようとしたらエラーが起こる

## これ何
cloud9でpaypayopaをインストールしたら、エラーが出たので、対応方針をまとめる

エラ〜メッセージは次の通り、エラーを見る限り権限がないので、うまくインストールができていないみたい

```shell
ec2-user:~/environment $ pip install paypayopa 
Collecting paypayopa
  Using cached https://files.pythonhosted.org/packages/cf/8c/1c8b24904179d4332fb9dcc074e49d0ee4dfde4cef670a88e61757d71ec7/paypayopa-1.0.4-py3-none-any.whl
Collecting pyjwt (from paypayopa)
  Downloading https://files.pythonhosted.org/packages/3f/32/d5d3cab27fee7f6b22d7cd7507547ae45d52e26030fa77d1f83d0526c6e5/PyJWT-2.1.0-py3-none-any.whl
Collecting requests (from paypayopa)
  Using cached https://files.pythonhosted.org/packages/29/c1/24814557f1d22c56d50280771a17307e6bf87b70727d975fd6b2ce6b014a/requests-2.25.1-py2.py3-none-any.whl
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.7/site-packages (from requests->paypayopa)
Collecting certifi>=2017.4.17 (from requests->paypayopa)
  Using cached https://files.pythonhosted.org/packages/5e/a0/5f06e1e1d463903cf0c0eebeb751791119ed7a4b3737fdc9a77f1cdfb51f/certifi-2020.12.5-py2.py3-none-any.whl
Collecting chardet<5,>=3.0.2 (from requests->paypayopa)
  Using cached https://files.pythonhosted.org/packages/19/c7/fa589626997dd07bd87d9269342ccb74b1720384a4d739a1872bd84fbe68/chardet-4.0.0-py2.py3-none-any.whl
Collecting idna<3,>=2.5 (from requests->paypayopa)
  Using cached https://files.pythonhosted.org/packages/a2/38/928ddce2273eaa564f6f50de919327bf3a00f091b5baba8dfa9460f3a8a8/idna-2.10-py2.py3-none-any.whl
Installing collected packages: pyjwt, certifi, chardet, idna, requests, paypayopa
Exception:
Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/usr/lib/python3.7/site-packages/pip/commands/install.py", line 365, in run
    strip_file_prefix=options.strip_file_prefix,
  File "/usr/lib/python3.7/site-packages/pip/req/req_set.py", line 784, in install
    **kwargs
  File "/usr/lib/python3.7/site-packages/pip/req/req_install.py", line 854, in install
    strip_file_prefix=strip_file_prefix
  File "/usr/lib/python3.7/site-packages/pip/req/req_install.py", line 1069, in move_wheel_files
    strip_file_prefix=strip_file_prefix,
  File "/usr/lib/python3.7/site-packages/pip/wheel.py", line 345, in move_wheel_files
    clobber(source, lib_dir, True)
  File "/usr/lib/python3.7/site-packages/pip/wheel.py", line 316, in clobber
    ensure_dir(destdir)
  File "/usr/lib/python3.7/site-packages/pip/utils/__init__.py", line 83, in ensure_dir
    os.makedirs(path)
  File "/usr/lib64/python3.7/os.py", line 223, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/usr/local/lib64/python3.7/site-packages/jwt'
```

## 対応方法

解決方法として、rootに入れるのではなく、ユーザーで入れるといいらしい

```
pip install paypayopa --user
```

## 参考
- Python - pythonにpybitflyerをインストール｜teratail https://teratail.com/questions/119153
【Rails】画像アップロード機能の導入

# 目的
Railsで作成したアプリに画像アップロード機能を追加する。

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提
- アプリを作成済み。

# 手順

1. [必要な手順の確認](#必要な手順の確認)
1. [ImageMagickのインストール](#imagemagickのインストール)
1. [Gemのインストール](#gemのインストール)
1. [Active Storageのインストール](#active-storageのインストール)
1. [アソシエーションの設定](#アソシエーションの設定)
1. [ストロングパラメーターの定義](#ストロングパラメーターの定義)
1. [バリデーションの設定](#バリデーションの設定)
1. [画像の表示](#画像の表示)

# 必要な手順の確認

まずは、必要な手順から確認していきましょう！

画像のアップロードには、Railsの`Active Storage`というGemを使用します。
これを使用することで、画像などのファイルのアップロードを簡単にするメソッドが使用できたり、画像を保存するテーブルを簡単に作成できます!

また、画像のサイズや色などを編集する機能も実装します。
画像加工のために必要な`ImageMagick`という画像変換ツールと、それをRailsから使うためのGemをインストールしていきます!

# ImageMagickのインストール

まず`ImageMagick`のインストールから行いましょう!
`ImageMagick`とはサイズ変更や保存形式の変更など、画像に処理を加えることができるツールのことです。

```:ターミナル
% brew install imagemagick
```

`ImageMagick`はGemではなくソフトウェアですので、Homebrewからインストールします!

# Gemのインストール

`ImageMagick`はインストールできましたが、
これをRailsで使用するためには、`MiniMagick`というGemが別に必要となります。
また画像サイズを調整するため、`ImageProcessing`というGemも合わせてインストールしましょう！

```ruby:Gemfile
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
```

```:ターミナル
% bundle install
```

```:ターミナル
% rails s
```

サーバーの再起動も忘れずに！

# Active Storageのインストール

続いて、`Active Storage`をアプリケーション内で使用する準備を行います。
以下のコマンドを実行しましょう!

```:ターミナル
% rails active_storage:install
```

上記のコマンドを実行後、Active Storageに関連したマイグレーションが作成されるため、続けてマイグレートしましょう!

```:ターミナル
% rails db:migrate
```

これで、Active Storageと画像加工ツールの導入は完了です!

続いて画像を保存するための方法も記載します。

# アソシエーションの設定

まずはアソシエーションの設定です。
以下の記述により、`モデル.ファイル名`で、添付されたファイルにアクセスできるようになります！

```ruby:app/models/post.rb
class Post < ApplicationRecord
  has_one_attached :image
end
```

`has_one_attachedメソッド`とは、各レコードとファイルを1対1の関係で紐づけるメソッドです。

# ストロングパラメーターの定義

次に`image`という名前でアクセスできるようになった画像ファイルの保存を許可します！

```ruby:app/controllers/posts_controller.rb
  # 中略

  private

  def test_params
    params.require(:post).permit(:text, :image)
  end
```

この記述で、`image`という画像ファイルの保存を許可できました。

# バリデーションの設定

今回は投稿時には画像が必須という機能を実装したいため、バリデーションの追加も行います！

```ruby:post.rb
with_options presence: true do
    validates :text
    validates :image
  end
```

これで投稿時には画像が必須となりました。

# 画像の表示

最後に保存した画像を表示します。

```:app/views/posts/index.html.erb
<%= image_tag post.image.variant(resize: '500x500') %>
```

Active Storageを導入している為、`variantメソッド`が使用可能です。
このメソッドを使用することで、ファイルの表示サイズを指定できます！

# 最後に

これで、画像アップロードの機能は追加できました!
あとは、ビューファイルの編集などしてください!
では。