OmniAICreator/Qiita-1.07M huggingface dataset:
【メモ】JavaScriptのreplaceメソッドと正規表現について

忘れてしまいそうなので、メモっときます。

##replaceメソッドの使い方
`replace('検索文字','置換した後の文字')`という感じ。

そして、`$1`とか`$2`とかは、検索文字の`()`の中身のこと。

```
var str = '今日は2019年6月16日、明日は2019年6月17日です。';
var result1 = str.replace( /(\d+)年(\d+)月(\d+)日/g , "$1/$2/$3" );

// 結果
今日は2019/6/16、明日は2019/6/17です。
```

みたいな感じになる。

##正規表現

今回謎だったのが、下記の正規表現。

```
replace(/[\|｜](.+?)《(.+?)》/g, '<ruby>$1<rt>$2</rt></ruby>')
```
無知すぎて、この程度もわかりませんでした・・・

でも今らなわかる！！！

・`/パターン/フラグ`という正規表現の記述方法。
・`[\|｜]` は`|`か`｜`に一致するものという意味。
・`\（バックスラッシュ）`はエスケープするためのもの。
・`[]`は角括弧に含まれるいずれか１文字にマッチする。
・`.+?`は一文字以上の文字と一致する。
・`/g`で一致するのがあっても、最後まで検索&置換を続ける

という感じ。

これで、**`|`か`｜`で始まって、文字《文字》**という正規表現ができる。
Rails AWS 本番環境でテータベースリセットしてseedデータ投入方法

#Railsで本番環境でテータベースリセットしてseedデータ投入方法

```
[ec2-user@******* current]$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop
[ec2-user@******* current]$ bundle exec rails db:create RAILS_ENV=production
[ec2-user@******* current]$ bundle exec rails db:migrate RAILS_ENV=production
[ec2-user@******* current]$ bundle exec rails db:seed RAILS_ENV=production
```
上から順番に実行で終わりです。

#最後に
bundle execをつけないとエラーになりました。
Power AutomateでCDSのオプションセットの値を取得する方法


# 注意事項
この手順はCDSの、レコード作成、更新、削除をトリガーとした時のみ有効なようです
CDSレコード取得アクションでは取得できませんでした・・・

# 背景
Dynamicsやモデル駆動型アプリ（どっちも一緒だな）を利用しているとわかると思いますが、
オプションセットを定義した後、Power Automateでラベル名を取得しようとしても内部のID（番号）が取得されてしまいます。

↓こういうのです
![2021-01-09_19h30_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48100/ba96df1d-7f9c-4eb8-1fc3-5e9d92b3dbe5.png)


これをPower Automateを利用して取得しようとすると数字のみが返ってきます
Valueなんだからオプションセットの値を返して来てほしいのですが数字です。

# 概要
PowerAutomateでは項目から選択してくると当然ですがこういう形で設定すると思います
![2021-01-09_19h53_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48100/bc784040-619f-fc1e-6a8b-03fc4e6d4d0a.png)


これの結果を見てみると・・・
![2021-01-09_19h36_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48100/ce2409c1-1015-1049-7048-a8f075a14b80.png)


違う！そうじゃない！！となりますよね。
そこで以下のようにすると取りたい値を取ることができました

# 取得手順
式タブを選択し、適当な文字をとりあえず入力（この場合は、a )
![2021-01-09_19h42_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48100/71e8d46c-f516-6d7a-f61a-efbf6717ce54.png)

動的なコンテンツタブを選択し、取りたい値の項目をクリックします
以下のようになるので、頭のaを削除します
![2021-01-09_19h53_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48100/0b656b24-b11d-4fac-2d27-07af86339afa.png)

フィールド名を以下のように変更します
_フィールド名_label
![2021-01-09_19h56_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48100/38c9a86f-ffed-c7ba-766a-4df71fd97815.png)

OKをクリックし式を確定させます。
フローを保存してテストすると以下のようになります
![2021-01-09_19h58_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48100/7bc126d1-0b25-58a8-1eae-5049e701b3d9.png)

# 所感
オプションセットの値すべてを取得等はできませんが、フロー内での判定分にオプションセットの値を使いたいときには十分かなと思います。
数字だけだと見返したときに何で判定してるかまったくわからないので・・・
なんでこれ標準で提供してくれないんですかね・・・。
【基本情報】ハードディスクとその他の補助記憶装置

 ###ハードディスクの構造と記録方法

内部にはプラッタと呼ばれる金属ディスクが入っていて、磁気ヘッドで記録していく。
####構造
![7D638116-605A-43C3-9BB1-16144F1CFBA8_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696517/4583ea7f-5e73-5c7d-e466-979a54a02c4c.jpeg)


ファイルはクラスタ単位で記録されるので、使っていくと穴あき部分ができる。

アクセス時間＝シーク時間＋サーチ時間＋転送時間

穴あきのことをフラグメンテーションという。（断片化）
⇨デフラグして修正

RAIDはハードディスクを複数組み合わせることで速度や信頼性を向上する。
０〜６までの７種類で、０、１、５は覚えた方が良い。

ストライピング⇨分散して記録（速い）
ミラーリング⇨同じのを記録（信頼性あり）

リムーバブルメディア
バックアップ用途やソフトウェアの配布媒体として広く利用されている。

ex)
光ディスク、光磁気ディスク、磁気テープ、フロッピーディスク、メモリカード（フラッシュメモリ、SSD）、USB
[サクラエディタ][マクロ][js]プログラム対象行数取得マクロ

#早速ですが
VB.NET開発で、コーディング行数をコメントに記述する必要があり、毎回行数を数えるのが面倒のため、容易に取得できるマクロを作成

##ざっくりな手順
 ①VisualStudioからプログラムをコピー
 ②サクラエディタに貼り付け
 ③マクロ実行

```visualbasic:PGLineCnt.vbs
' *****************************************************************************************
' タイトル：プログラム対象行数取得(サクラエディタマクロ用)
' 説明    ：プログラムのコメント行、空白行を除き、
'           プログラム対象行数をクリップボードにコピーする。
' 作成者  ：●●●●
' 設定手順：①[メニュー]-[設定]-[共通設定]から[マクロ]タブを選択
'           ②空き番号行を選択、名前に任意の名前を入力し、Fileに当マクロを選択後、
'             設定ボタンを押下
'           ③[キー割当]タブを選択
'           ④種別のリストから[外部マクロ]を選択、機能欄から②で登録したマクロを選択し、
'             任意のキーを割付
'           ⑤サクラエディタの再起動
'
' 変更履歴：2021.01.08 新規登録
' *****************************************************************************************

Call Editor.ReplaceAll("^[ |\t]*" & "\'" & ".*[\r\n]", "", 4)	'置換1:コメント行を置換
Call Editor.ReplaceAll("^[\r\n]+", "", 4)						'置換2:空白行を置換

Call Editor.ReDraw(0)			'再描画
Call Editor.GoFileTop(0)		'先頭行移動

lcnt = Editor.GetLineCount(0)		'対象行数取得
Call Editor.SetClipboard(0, lcnt)	'対象行数取得をクリップボードにコピー
msgbox(lcnt)						'対象行数取得をメッセージ表示
```


```javascript:PGLineCnt.js
/*
 * タイトル：プログラム対象行数取得マクロ(サクラエディタマクロ用)
 * 説明    ：プログラムのコメント行、空白行を除き、
 *           プログラム対象行数をクリップボードにコピーする。
 * 作成者  ：●●●●
 * 設定手順：①[メニュー]-[設定]-[共通設定]から[マクロ]タブを選択
 *           ②空き番号行を選択、名前に任意の名前を入力し、Fileに当マクロを選択後、
 *             設定ボタンを押下
 *           ③[キー割当]タブを選択
 *           ④種別のリストから[外部マクロ]を選択、機能欄から②で登録したマクロを選択し、
 *             任意のキーを割付
 *           ⑤サクラエディタの再起動
 *
 * 変更履歴：2021.01.08 新規登録
 */

// 置換
//Editor.ReplaceAll('^[\r\n]+|^[\s|\t]*' + '\'' + '.*[\r\n]', '', 4);	// 置換
Editor.ReplaceAll('^[ |\t]*' + '\'' + '.*[\r\n]', '', 4);	// 置換1:コメント行を置換
Editor.ReplaceAll('^[\r\n]+', '', 4);						// 置換2:空白行を置換

Editor.ReDraw(0);		// 再描画
Editor.GoFileTop(0);	// 先頭行移動

var lcnt = Editor.GetLineCount(0);	//対象行数取得
Editor.SetClipboard(0, lcnt);		//対象行数取得をクリップボードにコピー
Editor.InfoMsg(lcnt)				//対象行数取得をメッセージ表示

```
#最後に
サクラエディタの正規表現は、秀丸の結果と微妙に違うのは私の勘違いと思うが、細かい事は気にしない。
（深層学習で大切な内積。）内積、外積、ドット積、numpyのdot関数の関係について。スカラー積とかも。。

#概要

深層学習で内積は、かなり重要。
内積、外積、ドット積、numpyのdot関数の関係について、若干、ややこしいので記事にする。


#内積、外積、ドット積、numpyのdot関数


ここで示したい結論は、

* まず、図示すると、大まかには、以下のようになると思う。(緑の矩形は、すべて、同じものを指す）。　
ここで、「同じ」とは、深層学習のアルゴリズム説明とかで、dot product, inner product, scalar productという用語が出て場合に、違うものと考えなくて良いという程度の意味。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/bc7b9754-bf45-e228-37d3-061b3a7605ab.png)



* numpyのdot関数は、ドット積という意味では少し、ずれた内容のものが含まれている。

* あえて、狭い範囲で考えて、dot関数、ドット積、内積は、同じものを指すことができる。
（numpyのdot関数は、別の意味、機能もあるので、ご注意。）

* 外積は、なんというか、別途、広がりのあるものなので、、、、深層学習には直接は影響なし、
だと思う。

* 深層学習において、内積がどう重要かは、この記事の対象外。

とりあえず、Wikiの記載で、内積、外積、ドット積の関係を示す。

##内積(wikiより）

以下から引用。
https://ja.wikipedia.org/wiki/%E5%86%85%E7%A9%8D

>線型代数学における内積（ないせき、英: inner product）は、（実または複素）ベクトル空間上で定義される非退化かつ正定値のエルミート半双線型形式（実係数の場合には対称双線型形式）のことである。二つのベクトルに対してある数（スカラー）を定める二項演算であるためスカラー積（スカラーせき、英: scalar product）ともいう。


　
>「内積」(inner) という語は「外積」(outer) の反対という意味での名称だが、外積は（きっちり反対というよりは）もう少し広い状況で考えることができる。



##外積(wikiより）

以下から引用。
https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E7%A9%8D

>ベクトル積（英語: vector product）とは、ベクトル解析において、3次元の向き付けられた内積空間において定義される、2つのベクトルから新たなベクトルを与える二項演算である。2つのベクトル a, b (以下、ベクトルは太字で表記)のベクトル積は a×b や [a,b] で表される。演算の記号からクロス積（cross product）と呼ばれることもある。2つのベクトルからスカラーを与える二項演算である内積に対して外積（がいせき）とも呼ばれるが、英語でouter productは直積を意味するので注意を要する。

##ドット積(wikiより）

以下から引用。
https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%83%E3%83%88%E7%A9%8D

>数学あるいは物理学においてドット積（ドットせき、英: dot product）あるいは点乗積（てんじょうせき）とは、ベクトル演算の一種で、2つの同じ長さの数列から一つの数値を返す演算。代数的および幾何的に定義されている。幾何的定義では、（デカルト座標の入った）ユークリッド空間 Rn において標準的に定義される内積のことである。

上記より、「標準内積」を意味する。


##dot関数
numpyのhelpより

```
dot(...)
    dot(a, b, out=None)

    Dot product of two arrays. Specifically,

    - If both `a` and `b` are 1-D arrays, it is inner product of vectors
      (without complex conjugation).

    - If both `a` and `b` are 2-D arrays, it is matrix multiplication,
      but using :func:`matmul` or ``a @ b`` is preferred.

    - If either `a` or `b` is 0-D (scalar), it is equivalent to :func:`multiply`
      and using ``numpy.multiply(a, b)`` or ``a * b`` is preferred.

    - If `a` is an N-D array and `b` is a 1-D array, it is a sum product over
      the last axis of `a` and `b`.

    - If `a` is an N-D array and `b` is an M-D array (where ``M>=2``), it is a
      sum product over the last axis of `a` and the second-to-last axis of `b`::

        dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
```

Google翻訳

>-`a`と `b`の両方が2次元配列の場合、それは行列の乗算です。
>       ただし、：func： `matmul`または``a @ b``を使用することをお勧めします。
>
> -`a`または `b`のいずれかが0-D（スカラー）の場合、：func：` multiply`と同等です。
>      `` numpy.multiply（a、b） ``または `` a * b``を使用することをお勧めします。
>


**入力によっては、dotとmatmul(行列の積）が同じ意味であることを示す。**

```
>>> import numpy as np
>>> c = np.array([[1,2],[3,4]])
>>> d = np.array([[10,100],[1000,10000]])
>>>
>>> e = np.dot(c,d)
>>> e
array([[ 2010, 20100],
       [ 4030, 40300]])
>>>
>>> f = np.matmul(c,d)
>>> f
array([[ 2010, 20100],
       [ 4030, 40300]])
>>>

```



#まとめ
深層学習では内積が重要であることを別途記事にしたいと思います。
コメントなどあれば、お願いします。:candy:
AWS Cloud9における「Oops VFS connection does not exist」というエラーと解決策について

#はじめに
**Railsチュートリアル第４版の第１章**の開発中に発生した「Oops VFS connection does not exist」というエラー発生状況とその解決策についてです。

#開発環境
* MacOS Catalina 10.15.7
* Safari 13.1.3
* AWS Cloud9
* Rails 5.1.6
* ruby 2.6.3

#エラー内容
Cloud9上にてRailsサーバを起動し、プレビューよりデフォルトページを
表示しようとしたところ、以下の画像が表示される。
エラーメッセージ：「Oops VFS connection does not exist」
![スクリーンショット 2020-12-27 19.05.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/948417/7d1b18c5-915e-2d3c-b957-2a2278987bc1.png)

#原因
Could9IDE起動自体にはCookieは不要だが、**アプリやファイルのプレビュー機能を利用するにはCookieを有効化する必要がある**らしい。
（実は「Third-party cookies disabled」というエラーメッセージが一番最初にプレビュー実行した際に出ていた。エラーメッセージはよく見ないといけないですね。）

[参考]
AWSユーザガイド アプリケーションプレビューまたはファイルプレビュー通知: 「サードパーティーの Cookie を無効にしました」
https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/troubleshooting.html#troubleshooting-preview (2021年1月2日)

#解決策
Safariの[環境設定]>[プライバシー]タブにて**「サイト越えトラッキングを防ぐ」**のチェックをオフにする。デフォルトでは「オン(有効)」になっている。
ちなみに、Safariの「サイト越えトラッキングを防ぐ」のデフォルト設定はバージョン11.0から。
![スクリーンショット 2021-01-02 10.26.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/948417/38d947d4-b256-b606-d998-e859abfde8f0.png)

#まとめ
「Oops VFS connection does not exist」というエラーメッセージから今回の原因にたどりつきにくかったと感じたので記事にしました。クラウドベースでの開発の際には、ブラウザ設定にも注意を払ってやる必要がありますね。
[Rails]多対多のリレーションで、カラムのペアにunique制約を付ける（最初から＆後から）

駆け出しエンジニアの簡単なメモです。
間違いや誤解を招くような書き方があればご指摘いただけると幸いです。

#1.中間テーブル作成
ユーザー(User)が投稿(Post)をお気に入り登録できる機能を作成しよう→
postsテーブルとusersテーブルの間にbookmarksという中間テーブルを作成→

```
rails g model Bookmark user:references post:references
```

これによりusersテーブルとpostsテーブルの両方を参照するように指定できます。
user_idとpost_idのペアを作成する事で、「お気に入り登録している」という状態を作ります。
しかしながらこの場合、user_idとpost_idのペアが重複することは有り得ません。（既にお気に入り登録している投稿に更にお気に入り登録はできない）
データベースで矛盾が生じないように、二つのペアがuniqueであることを明示する必要が有ります。

#2.1. unique制約を付ける（最初から）

作成されたマイグレーションファイルに追記します。

```Ruby
class CreateBookmarks < ActiveRecord::Migration[6.0]
  def change
    create_table :bookmarks do |t|
      t.references :user, null: false, foreign_key: true
      t.references :post, null: false, foreign_key: true

      t.timestamps

      #以下を追記
      t.index [:user_id, :post_id], unique: true
    end
  end
end


```

あとはrails db:migrateすればオーケーです。


#2.2 unique制約を付ける（後から）

今回メモするきっかけになったことです。
「あっやべ！付け忘れた！」となって後から追加する方法を調べました。

### migrationファイルを作成

```
rails g migration AddIndexUserIdAndPostIdToBookmarks
```

### 中身を記述

```Ruby
class AddIndexUserIdAndPostIdToBookmarks < ActiveRecord::Migration[6.0]
  def change
    add_index :bookmarks, [:user_id, :post_id], unique: true
  end
end
```

とてもシンプルで簡単でした。
あとはrails db:migrateでオーケー！



参考にさせていただいた記事
[Ruby on RailsでDBにユニーク制約を付与する方法](https://iriya-0624.hatenadiary.org/entry/20130429/1367246420)
[Railsドキュメント](https://railsdoc.com/page/add_index)
【エラー対処】peeweeでpeewee.IntegrityError 1451が発生する


# はじめに

pythonのORMマッパーであるpeeweeでUserテーブルの行を削除するAPIを書いたところ以下のようなエラーが発生しました．

```bash
peewee.IntegrityError: (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`atnow_database`.`task`, CONSTRAINT `task_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`))')
```

# 原因

今回使用したpeeweeのORMモデルは以下のようになっていました．

```python
import peewee
from code.models.base import Base


class User(Base):
    username = peewee.CharField(unique=True, index=True)
    is_active = peewee.BooleanField(default=True)
    hashed_user_token = peewee.CharField()
```

```python
from code.models.base import Base
from code.models.user import User


class Task(Base):
    name = peewee.CharField(max_length=30, index=True)
    description = peewee.CharField(max_length=300, default='')

    # 外部キー
    user = peewee.ForeignKeyField(User, backref='tasks')
```

このようなモデル設計において，Userの行を削除しようとしていました．

ここで，Task側のテーブルは外部キーとしてUserを持っています．
また，それをUser側も知っており外部参照されていることを知っています．

よって，何も指定しないまま書くと自動的に外部キー制約がSQLのテーブルのスキーマに追加されます．

そのため，Userの行だけを削除しようとすると，関連ついているTaskたちが取り残されてしまうので，それを防ぐために削除を許さず1451エラーが出ていました．

Task側に立って考えてみると，参照先のUserが勝手に消えていたら困ってしまいますね..


# 対応策

[公式ドキュメントに`小さく`書いてありました](http://docs.peewee-orm.com/en/latest/peewee/api.html#ForeignKeyField).

削除されたときのアクションを文字列で指定できます．
`CASCADE`を用いると，Userを消すときに関連づいているTaskも自動で消せるため，エラーは起こりません．

```python
class Task(Base):
    name = peewee.CharField(max_length=30, index=True)
    description = peewee.CharField(max_length=300, default='')

    # 外部キー
    user = peewee.ForeignKeyField(User, backref='tasks', on_delete='CASCADE')
```
ionic ui componentで、inputのデータバインドがうまくいかない時（v-modelが効いてない時）

覚書です。

```vue
<ion-item>
        <ion-label position="stacked">名前</ion-label>
        <ion-input v-model="petName"></ion-input>
</ion-item>
```
これを
こうすると動く

```vue
<ion-item>
        <ion-label position="stacked">名前</ion-label>
        <ion-input :value="petName" @input="petName = $event.target.value"></ion-input>
</ion-item>
```

参照元🙏：
https://www.koatech.info/blog/vue-databinding-ionic/
https://github.com/vuejs/vue/issues/7830
Azure Cosmos DB のデータ暗号化について

## 概要

- Cosmos DB ではすべてのデータ（データベース）、メディア添付ファイル、バックアップが暗号化される。

  - Cosmos DB では一般的なデータ（プライマリデータベース）を SSD に保存し、メディア系ファイルやバックアップは Blob （HDD）に格納するとのこと。

  - データの転送中（ネットワーク経由）と保存時（非揮発性メモリ）にデータは暗号化されているため、エンドツーエンドでの暗号化が実現されているとも。

- Cosmos DB に保存されるすべてのデータは自動で暗号化されるため、追加での操作は不要。

  - この暗号化を ON/OFF にする機能はなく、既定ですべて ON 担っている。

  - 追加コストはかからない。

  - 暗号化キーが交換される頻度は、「Microsoft の暗号化キーローテーションに関するガイドライン」に従っている。内容は非公開とのこと。

- 暗号化には AES 256 の技術が使用されている。

  - 暗号化に使用される共通鍵は、必要に応じて独自のキーを使用することも可能。[カスタマーマネージドキー](https://docs.microsoft.com/ja-jp/azure/cosmos-db/how-to-setup-cmk)の記事を参照。

- すべての Azure Cosmos DB リージョンで暗号化の機能は有効になっている。

- 暗号化によるパフォーマンスの SLA への影響や変化はないとのこと。詳細は 「[Cosmos DB の SLA](https://azure.microsoft.com/support/legal/sla/cosmos-db)」を参照。

## 参考資料

- [Azure Cosmos DB でのデータの暗号化](https://docs.microsoft.com/ja-jp/azure/cosmos-db/database-encryption-at-rest)
ReactNativeでテキストボタンまたはテキストリンクのタップ領域を拡大する

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658122/d4545763-57bd-1d20-c6c1-102763f1cef1.png" width=50%>

一部リンクがあるようなテキストの場合タップ領域がかなりシビアで正確にタップしないと押すことが出来ない。

```tsx
const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.row}>
        <Text>パスワードを忘れた方は</Text>
        <TouchableOpacity
          onPress={() => {
            console.log('tap');
          }}>
          <Text style={styles.link}>こちら</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    margin: 8,
  },
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },
  link: {
    textDecorationLine: 'underline',
    color: 'blue',
  },
});
```


`<TouchableOpacity>`のstyleにpaddingを設定してタップ領域を広げることができるが、paddingで広がった分、他の領域に影響を与えてしまいデザインが崩れてしまったりしてしまう。

```tsx
  <TouchableOpacity
    style={{borderColor: 'gray', borderWidth: 1, padding: 8}}
    onPress={() => {
      console.log('tap');
    }}>   
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658122/fade15b9-68ce-775c-bcc4-c636a3764161.png" width=50%>


こういうときはpaddingで設定した値を負のmarginとして付与してあげればよい。

```tsx
  <TouchableOpacity
    style={{borderColor: 'gray', borderWidth: 1, padding: 8, margin: -8}}
    onPress={() => {
      console.log('tap');
    }}>        
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658122/c6a0b544-caa4-5d35-1271-e57bd8015603.png" width=50%>

こうすることで他の領域に影響を与えずにテキストリンクのタップ領域を拡大することができる。

参考:
[ボタンやアイコンやナビゲーションなど、クリック・タップ可能な領域のサイズを広くする実装方法のまとめ](https://coliss.com/articles/build-websites/operation/css/enhancing-the-clickable-area-size.html)
[テキストだけのボタンは、なぜスマホでのユーザビリティを損なうのか](https://coliss.com/articles/build-websites/operation/work/why-text-buttons-hurt-mobile-usability.html)
[Text margin, padding not working if in another Text component #6728](https://github.com/facebook/react-native/issues/6728)
C#で塗りつぶし描画アプリを作る

以前、[ピクチャボックス内をマーカーでベタ塗りするアプリ](https://qiita.com/ikenohotori/items/b4ea177de8619ba255ff)を作った。
それを改良して、ボタンを押した時だけピクチャボックスが塗りつぶされるアプリを作成する。


追加仕様
・ピクチャボックス内をマーカーが移動する
・保存ボタンを押すと、マーカーが表示される位置が塗りつぶされる。
・塗りつぶされた部分は消えない。

C#＆アプリ初心者の練習です。

#アプリの作成
環境：Windows+VisualStudio(Winforms)

```C#:drawpolygon.cs
    public partial class Form1 : Form
    {
        int SaveTrigger = 0;
        List<PointF[]> list = new List<PointF[]>();

        public Form1()
        {
            InitializeComponent();           
        }

        private void PastePicture(object sender, PaintEventArgs e)
        {
            int mouseY = Decimal.ToInt32(numericUpDown1.Value);

            SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(88, 0, 0, 255));
            Brush brush = new SolidBrush(Color.Gray);

            PointF point1 = new PointF(0, mouseY + 100);
            PointF point2 = new PointF(pictureBox1.Width, mouseY + 100);
            PointF point3 = new PointF(pictureBox1.Width, mouseY - 100);
            PointF point4 = new PointF(0, mouseY - 100);

            PointF[] curvePoints =
            {
                 point1,
                 point2,
                 point3,
                 point4
            };

            // 保存が押された時の座標を保存
            if(SaveTrigger == 1)
            { 
                list.Add(curvePoints);
                SaveTrigger = 0;
            }

            for (int i = 0; i < list.Count; i++)
            {
                e.Graphics.FillPolygon(brush, list[i]);
            }

            // 常にマーカーを描画
            e.Graphics.FillPolygon(semiTransBrush, curvePoints);
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();
        }

        private void save_Click(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();
            SaveTrigger = 1;
        }
    }
```
Paintイベント内に「マーカーの描画」と「塗りつぶし部分の描画」をそれぞれ作成した。
「マーカーの描画」は、数値入力ボックスの値を座標とする。
「塗りつぶし部分の描画」は、保存ボタンが押された時だけ実行される。
（Paintイベントにパラメータ情報を渡す方法がわからず、保存ボタンが押された時のみ実行するかどうかの判定にSaveTriggerというグローバル変数を使ってしまった。良い方法があれば教えて下さい。）

実行画面
![2021-01-09_18h46_52.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/130b6136-b3a4-a88d-4326-f8e9474ccfbc.gif)
Bash reference

* `man bash` 
  * 困ったときはまずmanual
* [Top (Bash Reference Manual)](https://www.gnu.org/software/bash/manual/html_node/index.html)
  * 困ったときは公式reference
* [bashスクリプティング研修の資料を公開します - エムスリーテックブログ](https://www.m3tech.blog/entry/2018/08/21/bash-scripting)
  * manualやreferenceでは上手く使う方法はあまり書いていない。こういう情報源も重要。 
* [シェルスクリプト（Bash）の記号の意味 - Qiita](https://qiita.com/kou029w/items/3e1285e3cef14682f4fe)
【M1】MacにHomebrewがインストールできない「zsh: command not found: brew」

:::note warn
2021年2月よりhomebrewが正式にM1Macに対応しました。(v3.0.0)
正規の手順でのインストールは[公式ホームページ](https://brew.sh/)に従ってください。
:::

2020年11月11日以降に購入したボクのMacBookに、Homebrewがインストールできないといった問題が起きました。（エラー `zsh: command not found: brew` )調べたところ、最新のMacBookのCPUにはApple社が開発した「M1」と言うモノを使っているみたいで、この「M1」が原因でMacにHomebrwがインストールできないみたいです。同じように2020年11月11日以降に最新のMacBookを購入して、Homebrewがインストールできない方は以下の方法を試してみて下さい。

## MacBookのCPU （プロセッサ）を調べる

### ターミナルから調べる方法
ターミナルから以下のコマンドを実行して下さい。実行するとCPUの情報が取得できます。

```:terminal
$ sysctl -a machdep.cpu.brand_string

## 実行結果
machdep.cpu.brand_string: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
```

### GUIから調べる方法


1. PC左上の、「apple」のボタンをクリック
2. 「このMacについて」をクリック
3. macOSの下欄に書いてあるプロセッサの情報を見る

![スクリーンショット 2021-01-09 18.26.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/85a40dc7-afe1-20f1-7954-cb0a4c22e45c.png)


## ターミナルの設定を 「Rossetaを使用して開く」 に変更する
CPUがM1だった場合、ターミナルの設定を、**Rossetaを使用して開く**に変更しないと、Homebrewはインストールができません。

1. ファインダーの検索窓で 「ターミナル」 と検索
2. 出てきたターミナルを右クリックして、 「情報を見る」 をクリック
3.  「Rosseta使用して開く」 （またはRosseta2） 左横のチェックボックスにチェックを入れる
4.  ターミナルを再起動
![スクリーンショット 2021-01-09 18.36.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/18ac4a01-b7b2-f996-2782-dbdf4eab334a.png)


## 再度Homebrwをインストール

ターミナルを起動し、以下のコマンドを入力して **Homebrew** をインストールしてみて下さい。今度はうまくいくはずです。[Homebrewホームページ](https://brew.sh/index_ja)

```:terminal
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

## 確認

```:terminal
brew -v

# 実行結果
Homebrew 2.6.2
```

これまでの設定でまだHomebrwが入らない方は、ターミナルの**Rossetaを使用して開く**がうまく[反映されていない可能性](https://docs.brew.sh/Installation)があるので、Macbookを再起動して、再度挑戦して下さい。
ありがとうございました。

参考
https://qiita.com/shira-shun/items/0f6213f4923cb5544367
https://freeheroblog.com/first-conf/
大きいサイズのファイルをメールに添付する

- Contents
    - [方法1: ファイルを直接メールに添付して送る](#方法1-ファイルを直接メールに添付して送る) 
    - [方法2: ファイルをドライブにアップロードして送る](#方法2-ファイルをドライブにアップロードして送る)
        - [1. オンラインストレージサービスにファイルをアップロードする](#1-オンラインストレージサービスにファイルをアップロードする)
        - [2. 共有リンクを取得する](#2-共有リンクを取得する)
        - [3. リンクをコピーしてメールで送る](#3-リンクをコピーしてメールで送る)


# 方法1: ファイルを直接メールに添付して送る

ファイルのサイズが2MB以下であればメールに直接ファイルを添付して送っても基本的には大丈夫。
※ 受信先によっては受け取れない可能性もある。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/e2b5daab-5852-9395-890b-4d3af0d9c28e.png" width="32%" height="32%" > <img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/06860e7e-28c9-f5b8-9051-d919071d97cc.png width="30%" height="30%" >


# 方法2: ファイルをドライブにアップロードして送る

受信先がより確実にファイルを受け取れるようにするにはこちらの方法が確実。

## 1. オンラインストレージサービスにファイルをアップロードする

今回はオンラインストレージサービスとしてGoogle Driveを利用する。
他にもDropboxやOneDriveなど好きなものを用いると良い。

Google Driveをブラウザ上で開いたら適当なフォルダを用意する。

|![mail3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/7d1b1345-227d-f290-5347-c06276bcb2a1.png)|
|:-:|

そのフォルダに移動してファイルをドロップするか、「ファイルをアップロードする」でメールで送信したいファイルをアップロードする。

|![mail4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/f47885b3-6ba2-c7c5-9599-d58500e74cfe.png)|
|:-:|

|![mail5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/8e40fc74-f094-933d-0c9e-c3c5807d4f4a.png)|
|:-:|

|![mail6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/9c87a584-a0d6-e93f-1cb7-7c5d18787892.png)|
|:-:|

## 2. 共有リンクを取得する

オンラインストレージに保存したファイルは通常外部から閲覧できない。
ファイルを誰かと共有する方法はいくつかやり方があるが、ここでは「**共有リンク**」を使用する。

**共有リンク** ... 外部からでもファイルへアクセスできる特別なリンク。

外部と共有したいファイルの共有リンクを取得する。
#### ファイルの上で右クリックし「リンクを取得」をクリックする。

|![mail7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/0449fef7-ef9d-d3f0-3fa3-2104e6f30aa3.png)|
|:-:|

#### 共有対象を「リンクを知っている全員」に変更する。

通常最初は共有対象が「制限付き」になっているはず。
これをクリックして「**リンクを知っている全員**」に変更する。
この変更をすることによって、ファイルを共有したい相手に共有リンクを送れば、その相手もファイルへアクセスできるようになる。

|![mail8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/64d0e754-3ed6-0a96-411e-4797fbbd4e33.png)|
|:-:|

|![mail9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/8179164f-1d57-75a6-4e83-cfa934eb13d5.png)|
|:-:|

まだ「**完了**」を押さずに次のステップに進む。


##3. リンクをコピーしてメールで送る

共有リンクは**http: //drive.google.com/xxx**である。
これをコピーしてメールで送るために「**リンクをコピー**」をクリックする。
これでコピペの準備は整ったので「**完了**」を押して設定を反映させる。

試しにコピーしたリンクを別のブラウザでペーストしてリンク先を開いてみるとファイルが表示されるはずである。
(もしもコピーがうまくできていなかったら再度「リンクを取得」を押してコピーすれば良い。)

|![mail10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/0e74dc9d-0b89-23e0-2ee5-a19afa3c03c6.png)|
|:-:|

コピーしたリンクをメールに載せて送る。

|![mail11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007710/1e07e6a5-e415-3692-fab2-ea7ebd90d015.png)|
|:-:|

これでメールが送られてきた相手は共有リンクからファイルをダウンロードすることができる。

なお、迷惑メールと間違われないようメールを送るときはリンク先のファイルの詳細(内容やファイル名など)をメール本文中に記載することを推奨する。
また、同様に共有リンクでファイルを共有する旨のメールが送られてくる側に立った場合も、送信元やファイルの内容に覚えがあり信頼がおけることを確認してからリンク先を開くよう心がけるとよい。
Mac CatalystでtoolbarItemをBigSur Styleにする

Catalystで`NSToolBarItem`にSFSymbolsで画像を設定するだけでは、BigSurのボタンの周辺にクリック領域が広がるようなスタイルになりません。それを実現するには以下のように`isBordered`にtrueを設定します。

```swift
let item = NSToolbarItem(itemIdentifier: identifier)
item.isBordered = true
```

これは嬉しい副次的効果もあリます。SFSymbolsをただ適応するだけでは、macらしくない少し大きめのアイコンとして表示されてしまいます。しかし、上記のBigSur StyleのNSToolbarItemを適応すると、良い感じに画像が縮小してくれます。
rails db:seed 後、viewでのエラー

##seedのデータをいれた後にviewで@user.imageが無いと怒られた
```ruby:seed.rb
#テストユーザーの作成
user1 = User.create(
        name: "test"
        email: "test@gmail.com"
        password: "testtest"
        passwoed_confirmation: "testtest"
        )
```
よし　

```
#docker使っているので
$ docker-compose run --rm web rails db:seed

#docker使っていなければ
$ rails db:seed
```

これで完璧！　と思ったら、、、

@user.imageなんてないだよね~って怒られました。

いやいや、controllerでimageつけてますがな！

```ruby:controllers/user_controller
def create
  @user = User.new(user_params)
  if !@user.image.attached?
    image_path  = Rails.root.join('app/assets/images/user_default.png')
ここ→@user.image.attach(io: File.open(image_path), filename: 'user_default.png')
  end
  @user.save
end
```

と思っていたけどそんなの関係ないんだよね。

てことで

```ruby:seed.rb
image_path  = Rails.root.join('app/assets/images/user_default.png')
user1.image.attach(io: File.open(image_path), filename: 'user_default.png')
```
追加してあげて(画像の投稿機能にactive storage 使ってます)

```
#emailに一意性つけてるのでdb削除からのmigrate
$ docker-compose run --rm web rails db:migrate:reset

$ docker-compose run --rm web rails db:seed
```

はいエラーはかないから僕の勝ち。

こんな事にならないように

imageバリデーションかけておいたほうが安全かもしれません。
「Failed to query OpenXR runtime information. Do you have an active runtime set up?」を解決する

##エラー内容
>Failed to query OpenXR runtime information. Do you have an active runtime set up?

##解決法
oculus.jsonのlibrary_pathを書き換える

```
{
    "file_format_version": "1.0.0",
    "runtime":
    {
        "api_version": "1.0",
        "name": "Oculus OpenXR",
        "library_path": "Oculusが保存されているドライブ:\\Oculus\\Support\\oculus-runtime\\LibOVRRT64_1.dll"
    }
}
```
**blender_oculus.cmd**は**oculus.json**の内容を実行しているので、
書き換えると、エラーがなくなり、BlenderでVR機能が使える
webpackのcontextとは


・ベースとなるpathを指定する。(entryやloaderの解決に使用される)
・絶対pathで記述する
・指定しないとカレンとディレクトリが使用される。(ので指定することをおすすめする)

```webpack.config.js
const path = require('path');

module.exports = {
    context: path.resolve(__dirname, 'app')
}
```


https://webpack.js.org/configuration/entry-context/#context
AWSからメールがauのezweb.ne.jpに送れない

### 現象
- AWSのCognitoを使って、ログインメールをau携帯のezweb.ne.jpあてに送信したところ、
いつまでたっても確認メールが来ないという事象が起きました。
- また、以前も、Billingの請求アラートや、SESでau携帯メールアドレスを指定しても届かない、受信できないということが発生していました。

### 原因
- auの[迷惑メールフィルター トップ](https://mfilter.ezweb.ne.jp/jsp/md/index.jsp)のおススメ設定が、なりすまし規制 レベル「高」になっており、レベル「高」だと受信できないようです。
![setting1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/4caaec86-bbeb-2a5a-d615-fa039cff78a0.png)

### 対策
- なりすまし規制は、レベル「低」にする。
![setting2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/b5a4b5d1-a34f-fe65-a8dc-e939092090a9.png)
以上
FirefoxやRustコンパイラ内で使われているハッシュ関数「FxHash」について調べてみた

# FxHashとは

`FxHash`は**暗号的に安全でない**高速なハッシュ関数です。
64bit環境では64bitいっぺんに処理できることが強みでFirefoxやrustcの内部で使うハッシュマップなどに使われています。
rustcでは[FNV](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function)(これはバイト単位で処理する)から`FxHash`に変更することで衝突が少し増えたもののスピードが速いので全体としては性能の改善に繋がりました。 [PR](https://github.com/rust-lang/rust/pull/37229)

参考:
https://searchfox.org/mozilla-central/source/mfbt/HashFunctions.h
https://github.com/cbreeden/fxhash
https://github.com/rust-lang/rustc-hash

# アルゴリズム

`FxHash`のアルゴリズムは超簡単です。

わかりやすさのためにrustのコードを[rustc_hash](https://github.com/rust-lang/rustc-hash/blob/master/src/lib.rs)より抜粋

```rust
pub struct FxHasher {
    hash: usize,
}

#[cfg(target_pointer_width = "32")]
const K: usize = 0x9e3779b9;
#[cfg(target_pointer_width = "64")]
const K: usize = 0x517cc1b727220a95;

impl Default for FxHasher {
    #[inline]
    fn default() -> FxHasher {
        FxHasher { hash: 0 }
    }
}

impl FxHasher {
    #[inline]
    fn add_to_hash(&mut self, i: usize) {
        self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K);
    }
}
```

メインの処理は、

```rust
self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K);
```

だけです。

ここで`K`の値は、
32bitの場合は黄金比、

```python
# python
hex(int((math.sqrt(5) - 1) / 2 * (2 ** 32)))
```

64bitの場合は円周率

```python
# python
hex(int(1 / math.pi * 2**64))
```

から導出されています。

## 解説

### 入力の最初の32/64ビット

まず、`self.hash`が`0`のデフォルトの状態、つまりハッシュ対象が32/64bit以内の場合を考えると、

```rust
self.hash = i.wrapping_mul(K);
```

とただ掛け算しているだけになり、これは`K`が黄金比の場合、`Fibonacci Hashing`と呼ばれ出力がよく分散するらしいです。（よくわかってない）
ただ、64bitの場合は`K`を黄金比にすると偶数となってしまい、そうすると出力が必ず偶数になってしまい良くないので円周率(これは奇数になる)を使っているらしいです。[参考](https://github.com/rust-lang/rust/pull/37229#issuecomment-254138725) (結局`K`が無理数(に近い整数)なら割と何でも良さそう?)
また、[オリジナルのソースコード](https://searchfox.org/mozilla-central/source/mfbt/HashFunctions.h)では`K`は

- 奇数
- 各ビットの1/0の割合が大体半々

なら何でも良いと書いてあります。

### 入力の32/64ビット以降

ハッシュ対象が32/64bitより大きい場合は32/64bitづつに区切ってハッシュ値を蓄積していくことになります

再掲

```rust
self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K);
```

ここではまず`self.hash`を左に`5`回転させています。特別`5`でなくても構いませんが偶数だと回転し続けたときのパターン数が減ってしまうので奇数のほうが良いです(もっと言えば素数だと良い?)。
ちなみにこの左回転は[The Art of Computer Programming](https://www.amazon.co.jp/gp/product/B087YT9S1D/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1)の6.4に載っているG. D. Knottが提唱した、複数語のハッシュ値を単純に加算や`xor`で合成すると(X, Y)と(Y, X)のハッシュ値が衝突してしまうので事前に回転させるという手法をもってきたものだと思います。たしかに、ここで回転しないと(X, Y)と(Y, X)のハッシュ値が同じになってしまいます。

それから入力と`xor`を取った**あとで**掛け算をします。`xor`が掛け算の後だと`self.hash`が`0`のときに入力をそのまま出力してしまうので良くありません。

これで終わりです。

# 歴史

- 2012年 Firefoxの内部で実装される。このときは他に`spookyhash`、`murmurhash3`、`cityhash`などが検討されていた
    - https://bugzilla.mozilla.org/show_bug.cgi?id=729952
- 2016年 rustc内で使われるようになる。このときに64bitへの拡張が行われる。`FxHash`という名前もここで初めて付いた？
    - https://github.com/rust-lang/rust/pull/37229
Readmeの書き方　

#特徴
* githubでおなじみ
* ***マークダウン記法***でかく


#内容
* Name
* Overview
* Demo
* Usage
* Requirement
* Install
* Note
* Author
* License
* References

## Name

## Overview

## Demo
gifを使うべし
## Usage
実行方法
コマンドオプション

## Requirement
環境
依存関係

## Install
インストールコマンド

## Note
## Author
## License
## References
明日のビットコイン価格を予知する

#概要
乗るしかないビッグウェーブなのかを判断する。

#Prophet
とても簡単でそれっぽいことができるProphetに、Binanceのデータを入れてみる。


```Python
df = pd.read_csv('http://www.cryptodatadownload.com/cdd/Binance_BTCUSDT_d.csv', skiprows=[0])
df['y'] = df[['high', 'low']].mean(axis = 1)
```
（中略）

👇結果



<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Time-series forecasting of Bitcoin prices using Prophet<a href="https://twitter.com/search?q=%24BTC&amp;src=ctag&amp;ref_src=twsrc%5Etfw">$BTC</a> <a href="https://twitter.com/hashtag/Bitcoin?src=hash&amp;ref_src=twsrc%5Etfw">#Bitcoin</a> <a href="https://t.co/7y1qoDb0xn">pic.twitter.com/7y1qoDb0xn</a></p>&mdash; 今川哲矢 (@TetsuyaImagawa) <a href="https://twitter.com/TetsuyaImagawa/status/1347672604824387584?ref_src=twsrc%5Etfw">January 8, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



**乗るしかないこのビッグウェーブに。**


#LSTM

適当（）なパラメータを入れます。

```Python
scaler = MinMaxScaler()
n_input = 30
n_features = 1
generator = TimeseriesGenerator(train, train, length=n_input, batch_size=7)
model = Sequential()
model.add(LSTM(200, activation='relu', input_shape=(n_input, n_features)))
model.add(Dropout(0.15))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
model.fit_generator(generator,epochs=90)
```





👇結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142638/520cc6ed-2edc-9b3d-e4ff-7ec665de1c9f.png)


**乗るべきではないこのビッグウェーブに。**
【discord.py】リアクションをついたら役職を付けたり消したりする方法【python】

ちょっとばかしハマったのでメモしておきます。

## 特定のメッセージに特定のリアクションをつけたら役職（role）をつける


```python
@client.event
async def on_raw_reaction_add(payload):
    if payload.message_id == リアクションを付けてほしいメッセージID:
        checked_emoji = payload.emoji.id

        guild_id = payload.guild_id
        guild = discord.utils.find(lambda g: g.id == guild_id, client.guilds)
        if checked_emoji == リアクションのID:
            role = guild.get_role(役職のID)
            await payload.member.add_roles(role)
```

## リアクションを消したらその役職（role）が消える

```python
@client.event
async def on_raw_reaction_remove(payload):
    if payload.message_id == リアクションを付けてほしいメッセージID:
        checked_emoji = payload.emoji.id

        guild_id = payload.guild_id
        guild = discord.utils.find(lambda g: g.id == guild_id, client.guilds)
        if checked_emoji == リアクションのID:
            role = guild.get_role(役職のID)
            member = guild.get_member(payload.user_id)
            await member.remove_roles(role)

```

## ハマったところ


役職をつける方は、

```python
            await payload.member.add_roles(role)
```

でいけるのですが、消すほうは、


```python
            member = guild.get_member(payload.user_id)
            await member.remove_roles(role)
```

という感じでいったん`member`を取得する必要があります。

リアクションが付けられた場合は`payload`の中に`member`が入ってくるのですが、リアクションが消されたときは`member`が存在しないためです。

https://discordpy.readthedocs.io/en/latest/api.html?highlight=reaction%20remove#discord.RawReactionActionEvent.member




```python
            await payload.member.remove_roles(role)
```
と書いたりして、

```
AttributeError: 'NoneType' object has no attribute 'remove_roles'
```

と怒られまくったりしてる人がこの記事を見て解決に至ってくれれば幸いです。
modal遷移をフルスクリーンで、下から出ないように行う

全画面で遷移したいとき、下から出したくないとき、ありますよね。
以下は`UIButton`に`addTarget`し、遷移する関数です。

```swift
@objc func buttonTapped() {
        let nextVC = nextViewController()
        nextVC.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
        nextVC.modalPresentationStyle = UIModalPresentationStyle.fullScreen
        self.navigationController?.pushViewController(nextVC, animated: true)
    }
```

`UIModalTransitionStyle`は列挙型で、は遷移アニメーションを指定することができます。

```swift
public enum UIModalTransitionStyle : Int {

    case coverVertical = 0

    case flipHorizontal = 1

    case crossDissolve = 2

    @available(iOS 3.2, *)
    case partialCurl = 3
}
```
デフォルトでは`coverVertical`が設定されているので、自然に遷移する(?)`crossDissolve`に変えます。

同様に`modalPresentationStyle`も列挙型の中から`fullScreen`に変更します。

ちなみに`modalPresentationStyle`は以下のように書かれています。

```swift
public enum UIModalPresentationStyle : Int {

    
    case fullScreen = 0

    @available(iOS 3.2, *)
    case pageSheet = 1

    @available(iOS 3.2, *)
    case formSheet = 2

    @available(iOS 3.2, *)
    case currentContext = 3

    @available(iOS 7.0, *)
    case custom = 4

    @available(iOS 8.0, *)
    case overFullScreen = 5

    @available(iOS 8.0, *)
    case overCurrentContext = 6

    @available(iOS 8.0, *)
    case popover = 7

    
    @available(iOS 7.0, *)
    case none = -1

    @available(iOS 13.0, *)
    case automatic = -2
}
```
【AWS】ストレージ

#EBS
◆特徴
・EC2インスタンスにアタッチして使用するブロックレベルのストレージサービス
・OSやアプリケーション、データの置き場所など様々な用途で利用される
・Snapshot機能によるS3へのバックアップやディスクの暗号化機能を提供
・９９.９９９％の可用性
・AZ毎に独立している

◆ユースケース 
・汎用SSD
　→小規模
・プロビジョンドIOPS
　→リレーショナルデータベース
　→NoSQLデータベース
　→持続可能なIOPSパフォーマンスが必要なアプリケーション
・スループット最適化HDD
　→ビックデータ、分析
　→Hadoop
　→Splunk
　→データウェアハウス
・コールドHDD
　→ログデータ
　→アーカイブ
　→低頻度アクセスの大量データ

◆他サービスの連携
・監視
　Cloudwatch

◆スナップショット
EBS-backedインスタンスに障害が発生した場合
　→EBSbackedインスタンスを停止して再起動

・関連する全てのボリュームのスナップショットを自動的に作成し、新しいAMIを作成
以下の手順に従って、ボリュームを新しいインスタンスにアタッチする
１）ルートボリュームのスナップショットを作成
２）作成したスナップショットを使用して新しいAMIを登録
３）新しいAMIから新しいインスタンスを起動
４）残りのAmazon EBSボリュームを古いインスタンスからデタッチ
５）Amazon EBSボリュームを新しいインスタンスに再アップ

・EBSボリュームのデータをS3にバックアップ可能
・スナップショットは増分バックアップ


#EFS
◆特徴
・データディレクトリ階層にファイルとして格納される
・ネットワーク越しに共有されるストレージ
・複数AZの最大数千のEC2インスタンスからファイルシステムへ同時アクセス可



◆ユースケース 
・パッケージアプリの共有ディレクトリ
・ビックデータ
・コンテンツの共有レポジトリ
・コンテナインスタンス　フリート全体が使用するデータ
→ビックデータ分析、メディア処理ワークフロー、コンテンツ管理、Web配信、ホームディレクトリ


#S3
◆スナップショット
EC2API経由のみで利用可能

◆ライフサイクルポリシー
・ストレージコスト削減
　→オブジェクトをS3Glacierにアーカイブする
　→一定期間後に削除する

◆署名付きURL
・デフォルトでは、オブジェクトの所有者のみがアクセスできる
・オブジェクトの所有者はアクセス制限で他のユーザにアクセスできるように変更できる
・署名付きURLを作成し、一時的な認証情報を付与することにより、ユーザに権限つきのURLを発行可能
・照明付きURLの作成時は、ユーザにアクセスを許可する機関を指定
・署名付きURLを受け取ったユーザは誰でもアクセスできるようになる

#Glacier

#Strage Gateway
→標準的なストレージプロトコルを利用してAWSのストレージサービスへのアクセスを可能にするハイブリッドストレージソリューション

◆特徴
・標準的なストレージプロトコルを活用したシームレスなインテグレーション
・キャッシュを活用した低レイテンシーなアクセス
・AWSストレージサービスのコスト、拡張性
・効率的なデータ転送
・データ暗号化
・AWSのモニタリング、管理、セキュリティとのインテグレーション

◆活用領域
・クラウドワークロードの活用
　→ビッグデータ処理、クラウドバースティング、移行のためにデータをAWSストレージに移動
・バックアップ、アーカイブ、災害対策
　→コスト効率の高いAWSのストレージにバックアップ、ローカルまたはクラウド上へリストア
・階層化クラウドストレージ
　→オンプレミス環境で容易にAWSストレージを活用

◆メモ
・ACL、BucketPolicy、IAMにてアクセスコントロールが可能
Dart: JSON のデータを削除 (Delete)

```dart:json_delete.dart
/*
	json_delete.dart

					Jan/09/2021
*/
// -------------------------------------------------------------
import 'dart:io';
import 'dart:convert';

// -------------------------------------------------------------
str_to_file_proc (str_out,file_out)
{
	var file = new File (file_out);
	var sink = file.openWrite ();
	sink.write (str_out);
	sink.close ();
}

// -------------------------------------------------------------
main (List<String> arguments) {
	stderr.writeln ("*** 開始 ***");

	String file_name = '${arguments[0]}';
	String key = '${arguments[1]}';

	print (key);

	File file = new File (file_name);
	Future future = file.readAsString ();

	future.then((content)
		{
		var dict_aa = jsonDecode(content);

		if (dict_aa.containsKey (key))
			{
			dict_aa.remove (key);

			var str_out = jsonEncode(dict_aa);

			str_to_file_proc (str_out,file_name);
			}

		stderr.writeln ("*** 終了 ***");
		}); 
}

// -------------------------------------------------------------
```

実行コマンド

```bash
dart json_delete.dart cities.json t0927
```

次のバージョンで確認しました。

```text
$ dart --version
Dart SDK version: 2.19.0-58.0.dev (dev) (Tue Aug 2 15:37:38 2022 -0700) on "linux_x64"
```
Dart: JSON のデータを更新 (Update)

```dart:json_update.dart
/*
	json_update.dart

					Jan/09/2021
*/
// -------------------------------------------------------------
import 'dart:io';
import 'dart:convert';

// -------------------------------------------------------------
dict_update_proc (dict_aa,key,population)
{
	var today = new DateTime.now();

	dict_aa[key]["population"] = population.toString ();
	dict_aa[key]["date_mod"] = today.toString ();

	return	dict_aa; 
}

// -------------------------------------------------------------
str_to_file_proc (str_out,file_out)
{
	var file = new File (file_out);
	var sink = file.openWrite ();
	sink.write (str_out);
	sink.close ();
}

// -------------------------------------------------------------
main (List<String> arguments) {
	stderr.writeln ("*** 開始 ***");

	String file_name = '${arguments[0]}';
	String key = '${arguments[1]}';
	int population = int.parse ('${arguments[2]}');

	print (key + '\t' + population.toString ());

	File file = new File (file_name);
	Future future = file.readAsString ();

	future.then((content)
		{
		var dict_aa = jsonDecode(content);

		if (dict_aa.containsKey (key))
			{
			dict_aa = dict_update_proc (dict_aa,key,population);

			var str_out = jsonEncode(dict_aa);

			str_to_file_proc (str_out,file_name);
			}

		stderr.writeln ("*** 終了 ***");
		}); 
}

// -------------------------------------------------------------
```

実行コマンド

```bash
dart json_update.dart cities.json t0923 3582600
```

次のバージョンで確認しました。

```text
$ dart --version
Dart SDK version: 2.19.0-58.0.dev (dev) (Tue Aug 2 15:37:38 2022 -0700) on "linux_x64"
```
Dart: JSON のデータを読む (Read)

```dart:json_read.dart
/*
	json_read.dart

					Aug/03/2022
*/
// -------------------------------------------------------------
import 'dart:io'; 
import 'dart:convert';

// -------------------------------------------------------------
disp_unit_proc (key,value) {
	String str_out = key + "\t" + value["name"] + "\t" + value["population"].toString() + "\t" + value["date_mod"];
	print (str_out);
}
// -------------------------------------------------------------
dict_display_proc (dict_aa)
{
	dict_aa.forEach((key,value) => disp_unit_proc (key,value));
}

// -------------------------------------------------------------
main (List<String> arguments) {
	stderr.writeln ("*** 開始 ***");

	String file_name = '${arguments[0]}';

	File file = new File (file_name);
	Future future = file.readAsString ();

	future.then((content)
		{
		Map dict_aa = jsonDecode(content);

		dict_display_proc (dict_aa);

		stderr.writeln ("*** 終了 ***");
		}); 
}

// -------------------------------------------------------------
```

実行コマンド

```bash
dart json_read.dart cities.json
```

次のバージョンで確認しました。

```text
$ dart --version
Dart SDK version: 2.19.0-58.0.dev (dev) (Tue Aug 2 15:37:38 2022 -0700) on "linux_x64"
```
ThymeleafでTimestamp型をフォーマットする

```java
  @GetMapping(value = "")
  public String init(Model m) {
    LocalDateTime ldt = LocalDateTime.now();
    Timestamp ts = Timestamp.valueOf(ldt);
    m.addAttribute("ts", ts); // ts = 2021-01-09 17:38:27.918333
    return "index";
  }
```

```html
<p th:text="${#dates.format(new java.util.Date(ts), 'yyyy-MM-dd hh:mm')}"></p>
<!-- 出力: 2021-01-09 17:38 -->
```
Dart: JSON のデータを作成 (Create)

```dart:json_create.dart
/*
	json_create.dart

						Jan/09/2021
*/
// -------------------------------------------------------------
import 'dart:io';
import 'dart:convert';

// -------------------------------------------------------------
str_to_file_proc (str_out,file_out)
{
	var file = new File (file_out);
	var sink = file.openWrite ();
	sink.write (str_out);
	sink.close ();
}

// -------------------------------------------------------------
dict_append_proc (dict_aa,key,name,population,date_mod)
{
	var unit_aa = new Map ();

	unit_aa["name"] = name;
	unit_aa["population"] = population.toString();
	unit_aa["date_mod"] = date_mod;
	dict_aa[key] = unit_aa;

	return	dict_aa;
}

// -------------------------------------------------------------
data_prepare_proc ()
{
	var dict_aa = new Map ();

	dict_aa = dict_append_proc (dict_aa,'t0921','宇都宮',42761,'1957-2-20');
	dict_aa = dict_append_proc (dict_aa,'t0922','小山',17895,'1957-8-15');
	dict_aa = dict_append_proc (dict_aa,'t0923','佐野',71564,'1957-12-14');
	dict_aa = dict_append_proc (dict_aa,'t0924','足利',93672,'1957-5-9');
	dict_aa = dict_append_proc (dict_aa,'t0925','日光',72351,'1957-6-4');
	dict_aa = dict_append_proc (dict_aa,'t0926','下野',35187,'1957-3-21');
	dict_aa = dict_append_proc (dict_aa,'t0927','さくら',31246,'1957-10-23');
	dict_aa = dict_append_proc (dict_aa,'t0928','矢板',65792,'1957-8-26');
	dict_aa = dict_append_proc (dict_aa,'t0929','真岡',74139,'1957-2-15');
	dict_aa = dict_append_proc (dict_aa,'t0930','栃木',29831,'1957-8-7');
	dict_aa = dict_append_proc (dict_aa,'t0931','大田原',54927,'1957-5-12');
	dict_aa = dict_append_proc (dict_aa,'t0932','鹿沼',36842,'1957-4-24');
	dict_aa = dict_append_proc (dict_aa,'t0933','那須塩原',93875,'1957-2-9');
	dict_aa = dict_append_proc (dict_aa,'t0934','那須烏山',38254,'1957-3-21');

	return	dict_aa;
}

// -------------------------------------------------------------
main (List<String> arguments)
{
	stderr.writeln ("*** 開始 ***");

	String file_out = '${arguments[0]}';

	var dict_aa = data_prepare_proc ();

	var str_out = jsonEncode(dict_aa);

	str_to_file_proc (str_out,file_out);

	stderr.writeln ("*** 終了 ***");

}

// -------------------------------------------------------------
```

実行コマンド

```bash
dart json_create.dart cities.json
```

次のバージョンで確認しました。

```text
$ dart --version
Dart SDK version: 2.19.0-58.0.dev (dev) (Tue Aug 2 15:37:38 2022 -0700) on "linux_x64"
```
【Laravel】composerコマンドでメモリ不足で実行できない場合の対処法【composer】

メモリ不足でcomposerコマンドが実行できない場合、無制限のオプション？を一緒につけることでインストールできるようになります。

## 下記のコマンドを実行して失敗した場合・・・
```
composer require laravel/helpers
```

## 「-1」で無制限にする
```
COMPOSER_MEMORY_LIMIT=-1 composer require laravel/helpers
```

これでcomposerコマンドの実行が成功すると思います。
MacBook Proが突然ブラックアウトした（mysqlが接続できなくなった）

##前書き
タイトルにもあるように突然画面が消えた。なんだかこんな現象が前にもあった気がする。。
キーボードを押しても何しても反応がない。ただ調べてみるとあっけなく復活したので記事にする。（自分のマックだと何回も起こりそうだし、、）

##結論
再起動をするためにタッチIDを押してみる。ここで反応がなければSMCリセットを実行する。

SMCリセットはマックの電源が落ちている状態で電源を繋ぎ「シフト」「コントロール」「オプション」「電源ボタン」の4つを10秒同時に長押しし、同時に離す。これにより完全に電源が落ちるので電源ボタン（タッチID）を押して再度起動させる。


##以上です！
めちゃくちゃ簡単で特に何もつまることはないのですが定期的に落ちるのが謎で腹が立ちます笑
私は神戸市に住んでいるのですが大寒波の影響で-9度にまで冷え込んでいるのも原因だったのかもしれません。


##PS　
開発環境を開いたままブラックアウトするとmysqlに必要なファイルが消えてしまうことがあるようです。以前にも消えたことがあったので冷静に対処しました笑
その時の記事です↓
https://qiita.com/soshiro/items/9f62632005f34af24248

![スクリーンショット 2021-01-09 17.13.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927542/27f0b8ef-8983-0cd1-c3b4-6e99d1dc9ba1.png)
Ubuntuに接続したマイコンとLiDARのポート名と実行権限を変更する

マイコンとURGをUSB接続してシリアル通信をする際に、実行権限（パーミッション）とポート名（/dev/ttyACM0等）が必要になってくると思います。

このようにシリアルデバイスが複数ある場合、デバイスは接続された順番にポート名が割り当てられるため、デバイスが複数接続された場合に毎回シリアルの設定を変えなければいけません。
また、シリアル通信は実行権限を付与してやる必要があります。

デバイス接続時に毎回設定する設定が面倒なのでそれに対応していきます。

# 設定方法

マイコン : STM Nucleo F446RE
LiDAR : Hokuyo UTM-30lx

まずマイコンのデバイス情報を調べます。下記のコマンドを実行します。

```sh

dmesg
```

すると、ログの下の方に接続したデバイスのプロダクト名が出てくるので、そのデバイス名の上にある[idVendor][idProduct][SerialNumber]の3つを記録します。

【URG】
![Screenshot from 2021-01-09 18-42-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149593/e5aa9d06-d3d0-b4d5-bea1-41b15cf255ac.png)
【マイコン】
![Screenshot from 2021-01-09 18-43-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149593/533d7115-8235-9962-6f95-6de648a34e01.png)






次に設定ファイルを作成します。
下記コマンドを実行してルート権限でテキストを開きます。

```sh

sudo vim /etc/udev/rules.d/99-serial.rules
```

さきほど調べた3つの番号と、設定したいポート名、実行権限が以下の場合は


以下のように設定して保存します。

```sh
KERNEL=="ttyACM*", ATTRS{idVendor}=="15d1", ATTRS{idProduct}=="0000", SYMLINK+="ttyACM_URG", MODE="0666"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", ATTRS{serial}=="**3**", SYMLINK+="ttyACM_STM", MODE="0666"
```
※ URG側はserial番号を使用しません。

これで設定完了です。
リロードする方法もあるのですが、確実のため再起動してください。

# 確認
デバイスを接続して以下のコマンドを打ちます。

```sh

reo@reo-desktop:~$ ls -la /dev/ttyACM_STM 
lrwxrwxrwx 1 root root 7  1月  9 18:36 /dev/ttyACM_STM -> ttyACM1

reo@reo-desktop:~$ ls -la /dev/ttyACM_URG 
lrwxrwxrwx 1 root root 7  1月  9 18:36 /dev/ttyACM_URG -> ttyACM0

```

このように出力されれば設定成功です。
【ラズパイ】pythonのrequests+BeautifulSoupで取得できないwebページのスクレイピング

# TL;DR
pythonでwebスクレイピングを行いたく、いつも通りrequests+BeautifulSoupで試してみました。
しかし、何故かページの一部しか取得できず、色々調べたところ「requests-html」というものが出てきたので、これを紹介します。

# 環境
- Raspberry Pi 4 Model B(Raspbian GNU/Linux 10)
- Python 3.6.1

# module
pipで`requests_html`をinstallします。

## ラズパイ特有のエラー
macで試した際は何も問題なかったのですが、ラズパイでpip install requests_htmlを行った際、以下のようなエラーが発生
```ERROR: Command errored out with exit status 1:
(省略)
Error: Please make sure the libxml2 and libxslt development packages are installed.
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output ```

どうやらlxmlというものをrequests_htmlで入れているらしく、ラズパイではこれがエラーになっていると。
以下で解決
```sudo apt-get install libxml2-dev libxslt-dev python3-dev
pip install lxml
```

# コード
```
from requests_html import HTMLSession
url = "https://stopcovid19.metro.tokyo.lg.jp/cards/positive-rate"
# セッション開始
session = HTMLSession()
r = session.get(url)
r.html.render()

# 要素取得
rows = r.html.find("span")
for row in rows:
    print(row.text) # 全てのspan要素のテキストが表示される
```
r.html.find("要素名")で、ページ内の指定した全ての要素を取得します。
この例では東京都新型コロナサイトを取得しているのですが、requests+BeautifulSoupだと画面の一部しか取得できませんでした。
![corona.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256661/19a1b21e-b37e-1cc0-2ce8-c233ee262a0a.png)
Use-PowerShell

PowerShellの備忘録！

# Commandタイプ
- Cmdlet
- Alias
- Function
- Filter
- Workflow
- Script
- Application
- Configuration
- ExternalScript

# 操作関連
- コマンドの実行を止めるには_Ctrl+C_を押せばよい。
- パラメーターの入力を複数求められたときに打ち切るには_Shift+Enter_を押す。複数行モード>>を抜ける時も同様に_Shift+Enter_を押せばよい。

# オプション関連
## -ResultSize
表示される結果の最大件数を指定できる。既定値は1000。unlimitedを設定すると全件表示される。
## -AllowClobber
`Import-PSSession`のオプションの１つ。既存セッションに存在するコマンドはImportされないのが既定だが、このオプションを使うとすべてのコマンドがImportされる。
## -Confirm:$False
確認ダイアログの表示を省略する。

# Object関連のCmdlet
## Group-Object
ある属性値でGroup化する。

```powershell:例
Get-Mailbox | Group-Object RecipientTypeDetails
```
## Sort-Object
ある属性値でSort化する。

```powershell:例
Get-Mailbox | Group-Object RecipientTypeDetails | Sort-Object Count
```

# Microsoft365(旧Office365)関連メモ
- MsOnlineをImportしていなくても、実際`Get-MsolUser`は候補に挙がる。ただし`Get-MsolUser`は`Connect-MsolService`実行後でないと実行できない。つまり`Connect-MsolService`はMsOnlineをImportしていなくても実行可能。

# その他メモ
- PS3.0からはモジュールは暗黙的に読み込むことが可能。
- モジュールの暗黙読み込み先は`$Env:PSModulePath`に定義されている3か所。システムレベルパスとユーザーレベルパスがある。
- モジュールの再読み込みは可能だが、一度削除(`Remove-Module`)しないと上書きされない(同一Runspaceでモジュールが維持されるから)。
- インテリセンス候補に挙がったコマンドを実行時にバックグラウンドで`Import-Module`が走る。
- 削除せずに強制上書きするには`-Force`を。