OmniAICreator/Qiita-1.07M huggingface dataset:
エラーメッセージの抽出と日本語化

#目次
<b>①エラーメッセージの仕組み</b>
<b>②エラーメッセージのビューへの反映</b>
<b>③日本語の設定の方法</b>



##①エラーメッセージの仕組み
インスタンス.errors.full_messagesとすると空の配列を返してくる。
バリデーションに引っかかった時に、エラーのメッセージが配列の中に、入る仕組みになっている。

仮にpostモデルにvalidates :trueと記述した際には、必ずpostモデルに何かしら入っていなければならない。その際に何も入力せずに保存した時の動きを確認する

```php:コンソール
①rails cと入力
②post = Post.new(content:"") 不正なデータを入力
③post.errors.full_messagesと入力すると以下の表示が返ってくる
→[]
④post.save  保存するとfalseが返ってくる
⑤この時、post.errors.full_messagesと入力すると
["Content can't be blank"]というメッセージが返ってくる
```
##②エラーメッセージのビューへの反映
エラーメッセージをビューに反映する際には、上記の配列から抜き出して表示をすれば良い。

```php:ビューファイル
<% @post.errors.full_messages.each do |message| %>
 <%= message %>
<% end %>

```

##③日本語の設定の方法
②でエラーメッセージはビューで表示できたと思うが、表示が英語になっているはず。
英語表記から日本語に変更するには、以下の手順を踏む。
1. gem 'rails-i18n'をGemfileに追加。
2. bundle installしましょう。
3. 一部日本語化を指定する設定用のja.ymlファイルを作成。
4. configに設定を追加。
5. 再起動

3について、
config/locales/models/に、ja.ymlというファイルを作成して、以下のようにカラム名と日本語の対応表を記述しなければいけない。

```php:config/locales/models/
ja:
  activerecord:
    models:
      post: 投稿
    attributes:
      post:
        content: 投稿内容
      モデル名:
        カラム名:日本語表示
        
```

4について

```php:config/application.rb
config.i18n.default_locale = :ja
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.yml').to_s]
```

上記の2文を追加すれば良い。これは、正規表現を使い、config/locales以下のディレクトリ内にある全てのymlファイルを読み込むように指示するものとなります。

###### ※localeとは、多言語化用の言語ファイル。多言語化以外にも、何度も使う文言を一限管理するために使われる。住所、会社名、時間をフォーマットする時の形式、今日の日付を出力する時の形式などを管理するために使われる。
######※config.i18n.load_pathの設定でconfig/locales以下のどの階層のディレクトリも読み込ませるようにしておくことが大事。この記述があることでディレクトリを分けることでカテゴリごとにi18nのデータを管理することができる様になる。
CarbonのdiffInMonthsはちゃんと動かない

1999-02-01 から 1999-03-01は１ヶ月あるが
diffInMonthsの戻り値は0だった。

```php
>>> var_dump((new \Carbon\Carbon('1999-02-01'))->diffInMonths(new \Carbon\Carbon('1999-03-01')));
/Users/tsugie/Projects/jin/vendor/psy/psysh/src/ExecutionLoopClosure.php(55) : eval()'d code:1:
int(0)

```

1999-02-01 から 1999-05-01は３ヶ月あるが
diffInMonthsの戻り値は2だった。

```php
>>> var_dump((new \Carbon\Carbon('1999-02-01'))->diffInMonths(new \Carbon\Carbon('1999-05-01')));
/Users/tsugie/Projects/jin/vendor/psy/psysh/src/ExecutionLoopClosure.php(55) : eval()'d code:1:
int(2)
```
【UniRx】ReactiveProperty<> をインスペクタに表示させる


備忘録です
通常ReactivePropertyはインスペクタ表示できないけど、ちょちょいといじれば表示させられるっぽい

#やることは2つ
①自前でReactivePropertyを継承したクラスを作って、そいつに[System.Serializable]をつける
②InspectorDisplayDrawerを継承したクラスを作って、①で作ったクラスを指定する


#実装

①の実装

```c#:①自前のReactivePropertyの作成.
/// <summary>
/// インスペクタに表示できるReactiveProperty<int>
/// </summary>
[System.Serializable]
public class IntReactiveProperty : ReactiveProperty<int>
{
    public IntReactiveProperty()
    {
    }
}
```

①だけでもとりあえず表示は可能。ただ以下のようにインスペクタにはこんな感じでが出てくる.
![スクリーンショット 2021-04-08 17.27.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534199/cefd4a6f-65ce-6c6e-658d-9f9689b2af18.png)

いちいちToggle開くのはめんどいので、②を実装する

②の実装

```c#:②InspectorDisplayDrawerの指定.
/// <summary>
/// IntReactivePropertyを直接インスペクタからいじれるようにする（Toggleなしにできる）
/// </summary>
[CustomPropertyDrawer(typeof(IntReactiveProperty))]
public class AddInspectorDisplayDrawer : InspectorDisplayDrawer
{ }
```

するとこうなる

![スクリーンショット 2021-04-08 17.28.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534199/93e24242-7072-0c52-580e-920454037a2d.png)

直接いじれて素敵〜〜〜！


#参考リンク
https://bluebirdofoz.hatenablog.com/entry/2021/02/13/230837
【AWS】IAM Access Analyzerで最小権限もAWSに作ってもらう

##はじめに
来る4月7日、IAM Access Analyzerを使って「アクセスポリシーに基づいた最小権限のIAMポリシー」が[作成できるようになりました](https://aws.amazon.com/jp/about-aws/whats-new/2021/04/iam-access-analyzer-easier-implement-least-privilege-permissions-generating-iam-policies-access-activity/)。

前提として、AWS含むクラウドは可能な限り各ユーザーの権限を絞り、それ以外の余計なことができないように設定することがベストプラクティスとされています。
しかし、このために権限を絞るのは正直面倒です。

「ユーザーやらロールやらが増えすぎて、どれが何を使っているのか洗い出すのも大変」
「AmazonS3FullAccess（S3に関することが全部できる権限）から手作業で権限を絞っていったら、EC2からS3に定期的にログを送信するジョブが動かなくなった」（実話）
「AWSだって『[職務機能のAWS管理ポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_job-functions.html)』なんかを用意してくれているんだから大体これで良くない？」 

と、（特に個人的にAWSを利用している場合は）IAM管理は重要ながらも杜撰になりがちです。
ここで今回のアップデートが効いてきます。

##何が嬉しいのか

・とにかく手順が簡単
①[IAM]>[IAMロール]を選択する
![WS000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625553/ff3dba0a-6570-0a89-8a19-0d4af05d78d3.jpeg)
②IAMロールの一覧より、権限を絞りたいロールを選択
![WS000004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625553/b094aa74-6553-2db9-6ab3-13688814e33a.jpeg)
③[CloudTrail イベントに基づいてポリシーを生成]>[ポリシーの作成]を選択
![WS000005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625553/576cd467-7dc1-0497-e828-cec361fca2c8.jpeg)
④CloudTrailイベントの分析期間と、分析する証跡（リージョン）を選択（＋必要があれば証跡に作成するためのIAMロールを作成）
![WS000006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625553/48d9cbd6-8450-0fa6-dea8-76fba92d05b3.jpeg)

やらなければならない作業はたったこれだけです。
利用履歴の細かな確認も、JSONによる権限記載も不要です。AWSが全部自動でやってくれます。

・日本語化済みかつ日本のリージョンに対応済み
個人的なAWSあるあるとして
「便利な機能だけど日本語化されていなくて微妙に面倒」
「便利な機能だけど東京リージョンに追加されていない」
というものがあるのですが、今回はきちんと日本語化＋東京・大阪リージョン対応です。
地味ですが嬉しいポイントです。

・期間指定
CloudTrailの期間指定は、日数で遡るものと日付での期間指定を行うものの二種類存在します。
つまり、「一時的に●●を使っていたけれど、もう使わない。でもCloudTrailの証跡には残ってしまっているな……」という場合にも対応しています。

・無料
こんな便利な機能ですが、無料で使用できます。
CloudFormationといい、便利機能が無料なのはありがたいものです。

##注意すべきポイント
・CloudTrailが有効化されていないと使用できない
個人使用の場合はここでつまずく人も多そうなポイントです。
仕様として、AWSがS3に保存されたCloudTrailログを読み取って「何を使っているのか」を把握するため、CloudTrailが有効化されていない＝ログが保存されていない場合は使えません。
後からオンにしたとしても、ログがたまるまではAccess Analyzerが履歴を拾ってIAMポリシーに落とし込む作業が行えません。
（オンにしたその日にIAMロール作成、としようとすると上記手順の③で「証跡の詳細の取得中にエラーが発生しました」と表示されます）
そもそも大前提として有効化するのがベストプラクティスなのですが、デフォルトでは無効のためログを保存できていない人もいるのではないでしょうか。
この機会に有効化しておきましょう。

・CloudTrailの証跡範囲は最大90日間
大元のCloudTrailの仕様上仕方のない事なのですが、90日より前に使用した証跡は辿れません。
（証跡の範囲指定は90日前までの間で日付を指定するものです）
以前一度使ったきりのサービスを再度使用する場合は注意が必要そうです。

・その他細かい部分
生成されるのはあくまでポリシーのテンプレートであり、そのまま使えない部分もあります。
具体的には、一部のサービスはアクションレベルのポリシー作成に対応していないため、その部分は手作業で設定する必要があります。
また、ポリシー生成には時間が掛かります。CloudTrailの範囲を絞るなど工夫が必要になります。

その他、詳細については[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_generate-policy.html)や[公式ブログ](https://aws.amazon.com/jp/blogs/security/iam-access-analyzer-makes-it-easier-to-implement-least-privilege-permissions-by-generating-iam-policies-based-on-access-activity/)もご参照ください（現状、英語のみなのが残念ですが）。

##終わりに
AWS利用において、ルートアカウントを使い続けていませんか？
IAMユーザーを使用している場合でも、余計なポリシーまで付与してしまっていませんか？
CloudTrailの証跡を保存せずに、履歴を見るだけで満足してしまっていませんか？
「IAM Access Analyzer」の新機能が誕生した今こそ、AWSをセキュアに利用するためにアカウントを見直すチャンスかもしれません。

[弊社ウェブサイト](http://c.itdo.jp/)ではAWSを含むさまざまな技術記事を公開しています。ぜひご覧ください。
How to set debug log for Community Guest User?


September 2, 2017
How to set debug log for Community Guest User?
1. Go to Domains.
https://www.infallibletechie.com/2017/09/how-to-set-debug-log-for-community.html


2. Select the URL of Community



3. Select the Community.



4. Click Public Access Settings button.



5. Click Assigned Users. Get the username.





6. Go to Debug Logs.

7. Click New and select the user.

8. If you are in chrome execute the below command in the console.

document.cookie="debug_logs=debug_logs;domain=.force.com";



9. You will start seeing debug logs for the community guest user.
選考に落ちたら思うこと、それは「うっせぇわ」

#伝えたいこと
選考に落ちても自分のことをダメな人間って思わないこと！

落ち続けてもダメな人間ではありません！

むしろ、現在もチャレンジし続けているキミはすばらしいです！

落ちたら「うっせぇわ」って思おう！

私を落とすなんて、センスがない会社！

こっちから願い下げだ！

諦めない自分を褒めて、挑戦し続けて！

ガンバレ！
Go言語 SQLBoilerでタイプセーフに複数条件のWhere句を書く

# 前置き
小ネタになります:pushpin:
最近Go言語でAPIを作っていてORMに[SQLBoiler](https://github.com/volatiletech/sqlboiler)を採用しました。
少し複雑なWhere句をタイプセーフで書く方法の情報が意外に少ないのではないかと思い執筆しました。

# テーブル構成
このようなテーブルがあったとします。

```sql
CREATE TABLE `foods` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) COLLATE utf8mb4_bin NOT NULL,
  `price` int(10) unsigned NOT NULL,
  `note` varchar(45) COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240974/c383d570-7850-566f-b3a5-47514035846c.png)

# 生クエリ
少しも複雑なWhere句ではないと思いますが、このくらいの条件でもタイプセーフで書いていない記事が多いので執筆してます。
複雑なサブクエリなどを期待されていた方には申し訳ありません:bow:

```sql
SELECT 
    *
FROM
    foods
WHERE
    price >= 100 AND price < 500
        AND (note = '特売' OR note IS NULL)
```

# SQLBoiler
### 比較的よく紹介されている記述
このように紹介されていることが多い印象です。「簡易的にビルダーでクエリを組み立てる」とでも申しましょうか。
モデルにマッピングしてくれる利点はありますが、あまり生クエリと変わりなく筆者としてはもっとORMの恩恵を受けたいと思います。恩恵を受けたくないのならORMを採用しない選択肢もあると考えます。

```go:ソースコード
res, err := models.Foods(
	qm.Where("price >= ? AND price < ? AND (note = ? OR note IS NULL)", 100, 500, "特売")).
	All(context.Background(), db.DB)
```
```sql:SQLBoilerのデバッグモードで出力されたクエリ
SELECT * FROM `foods` WHERE (price >= ? AND price < ? AND (note = ? OR note IS NULL));
[100 500 特売]
```

### WHERE/AND/OR/()毎に組立てる記述
上記の表現、公式ドキュメントから名前を発見できず、読解力や語彙力がなく申し訳ありません:sweat_drops:
このように小分けに書くこともできます。`比較的よく紹介されている記述`と比較したらORMの活用率は上がりましたね。`AND`とか`OR`、`()`のtypoは減るかもしれません。筆者としてはもっとORMの恩恵を受けたいと思います。

```go:ソースコード
res, err := models.Foods(
	qm.Where("price >= ?", 100), qm.And("price < ?", 500),
	qm.Expr(qm.And("note = ?", "特売"), qm.Or("note IS NULL"))).
	All(context.Background(), db.DB)
```
```sql:SQLBoilerのデバッグモードで出力されたクエリ
SELECT * FROM `foods` WHERE price >= ? AND price < ? AND (note = ? OR note IS NULL);
[100 500 特売]
```

### タイプセーフに組立てる記述
ORMの恩恵を多く受けたければ以下のように書けます。SQLBoilerの[公式で強く推奨してる方法](https://github.com/volatiletech/sqlboiler#query-mod-system)です。
「冗長的な記述だけど、タイプセーフでコンパイルエラーになるからいいよね」ということです。SQLBoilerに関わらず、他ORMでもこのような思想はありますね。
インテリセンス(コード補完)が活用できるのも魅力の1つだと感じます。

```go:ソースコード
res, err := models.Foods(
	models.FoodWhere.Price.GTE(100), models.FoodWhere.Price.LT(500),
	qm.Expr(models.FoodWhere.Note.EQ(null.StringFrom("特売")), qm.Or2(models.FoodWhere.Note.IsNull()))).
	All(context.Background(), db.DB)
```
```sql:SQLBoilerのデバッグモードで出力されたクエリ
SELECT * FROM `foods` WHERE `foods`.`price` >= ? AND `foods`.`price` < ? AND (`foods`.`note` = ? OR `foods`.`note` is null);
[100 500 {特売 true}]
```

# 終わりに
ORM自体の是非というのは揉め易いネタだと思いますので割愛します。そもそもORMを採用するにしてもフルスタックかマイクロの議論もあります。全てをORMに頼るのは難しく生クエリで書いたほうが良い場面もありますので「ORMで消耗する」のではなくバランス良く使って生産性や保守性、堅牢性を上げられれば良いかなと思っています。また、公式ドキュメントにタイプセーフな記述方法も書いてあるのですが調査中はわかりませんでした。コードを書き終えてから結果論として「あぁ、このことか」と理解しました。筆者の読解力の問題を棚に上げつつ、ドキュメントをもう少し親切にしてほしいと思っております。
instagramからLocationをscrapeする方法


#Instagramから位置情報をscrape
```insta.py
$pip3 install insta-scrape

from instascrape import Location
place_url = 'https://www.instagram.com/explore/locations/470867993/'
place = Location(place_url)
place.scrape()
latitude = place.latitude
longitude = place.longitude
```

```
command
$python manage.py shell
In [1]: from instascrape import Location

In [2]: place_url = 'https://www.instagram.com/explore/locations/470867993/'

In [3]: place = Location(place_url)

In [4]: place.scrape()
/Users/takamariku/pythonProject/venv/lib/python3.9/site-packages/instascrape/core/_static_scraper.py:134: MissingCookiesWarning: Request header does not contain cookies! It's recommended you pass at least a valid sessionid otherwise Instagram will likely redirect you to their login page.
  warnings.warn(
In [5]: latitude = place.latitude

In [6]: latitude
Out[6]: 35.550838

In [7]: longitude = place.longitude

In [8]: longitude
Out[8]: 139.788537
In [14]: place.to_dict()
Out[14]: 
{'id': '470867993',
 'name': '羽田空港 国内線第2ターミナル',
 'has_public_page': True,
 'latitude': 35.550838,
 'longitude': 139.788537,
 'slug': '2',
 'blurb': '',
 'website': 'https://www.tokyo-airport-bldg.co.jp/',
 'phone': '03-5757-8111',
 'primary_alias_on_fb': '',
 'stress_address': nan,
 'zip_code': nan,
 'city_name': 'Hanedakuukou',
 'region_name': nan,
 'country_code': 'JP',
 'amount_of_posts': 3492}
```
place.to_dict()のcomandを入力すると、その位置情報の全ての情報が表示される。

#終わり
instascrapeでは自分が投稿している情報、位置情報など様々な情報をscrapeできる。Locationの他にも、自分のprofile情報を取得できる、from instascrape import Profileなどのmoduleもある。
AWS cognitoの機能名とcli名

こんがらがったので、AWSのコンソール画面上の機能名とcli名をまとめた。

なんでidpがIDプールじゃなくてユーザプールなんだぜ🤔

(追記)idpはidentity-providerか！

|  コンソール  |  ユーザープール  |  ID プール (フェデレーティッドアイデンティティ)  |
| ---- | ---- |---- |
|  cli  | aws cognito-idp  | aws cognito-identity |
|  js sdk  |  @aws-sdk/client-cognito-identity-provider  | @aws-sdk/client-cognito-identity |
Docker使用時に起きるpidファイルエラーの解決法


Docker使用時にpidファイルが残ってしまってコンテナが起動できずにエラーになるのはよくあることなので、覚えておくのが良いみたいですね。


**以下pidファイルについての説明です。**

>「/var/run」ディレクトリは、システムを起動した後の情報が格納されるディレクトリです。このディレクトリには、主に実行中のプロセスに関する情報が格納された「pidファイル」が存在します。
>「.pid」で終わっているファイルがpidファイルです。このファイルには、該当するプロセスのプロセスIDなどの情報が記述されています。
>プロセスやシステムが異常終了したときにpidファイルが残っているせいでプロセスがうまく起動しないというトラブルもありえます。

引用元：[Linux豆知識 193「/var/run」ディレクトリ](https://linuc.org/study/knowledge/523/#:~:text=%E3%80%8C%2Fvar%2Frun%E3%80%8D%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AF%E3%80%81%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E8%B5%B7%E5%8B%95,%E5%8F%82%E7%85%A7%E3%81%97%E3%81%A6%E3%81%BF%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82)


https://linuc.org/study/knowledge/523/#:~:text=%E3%80%8C%2Fvar%2Frun%E3%80%8D%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AF%E3%80%81%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E8%B5%B7%E5%8B%95,%E5%8F%82%E7%85%A7%E3%81%97%E3%81%A6%E3%81%BF%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82


## 発生状況
docker-compose upをしている時にイレギュラーな終了方法をしてしまうとpidファイルが残ってしまい、エラーが起きることが多々あります。


## エラー内容
pidファイルが残っている状態でdocker-compose upをすると下記のエラー・メッセージが表示されます。
`A server is already running. Check /app/tmp/pids/server.pid.`

## 解決法
server.pidファイルを削除する
`$ rm tmp/pids/server.pid`

これで無事にコンテナを起動出来ます！
`$ docker-compose up (-d)`

## 参照
[Linux豆知識 193「/var/run」ディレクトリ](https://linuc.org/study/knowledge/523/#:~:text=%E3%80%8C%2Fvar%2Frun%E3%80%8D%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AF%E3%80%81%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E8%B5%B7%E5%8B%95,%E5%8F%82%E7%85%A7%E3%81%97%E3%81%A6%E3%81%BF%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82)
アセンブリ言語　strcmpを書いてみた

## 追記

追記 : 2021/04/14

- コメントにて、rbpを使っていることを指摘いただいたので書き直しました。
- cmpsbの使用については、コメントで書き方を教えて頂きました。
    - rdi, rsiが直接インクリメントされるのでDフラグは関係ないようです。
    - 結果に関しても、movsxを使うことで、raxに格納できました。
- 参考文献を追記しました。

## コード

```nasm
section .text
	global _ft_strcmp

_ft_strcmp:
.loop:
	movsx	eax, BYTE[rdi]
	movsx	ecx, BYTE[rsi]
	inc		rdi
	inc		rsi
	sub		eax, ecx
	jne		.end
	test	cl, cl
	jne		.loop
.end:
	ret
```

### movsx

返り値のサイズに合わせるため、movsxで拡張して格納し、比較しています。

### test

2オペランドの論理積を計算し、結果がゼロならゼロフラグ(ZF)を立てます。
同じclとclを比較しているので、clが0なら0を、1なら1を返します。

## テストコード

```c
#include <libc.h>

static void	test_strcmp(const char *d, const char *s)
{
	printf("%s : %s\n", d, s);
	int libasm = ft_strcmp(d, s);
	int libc = strcmp(d, s);
	printf("libc : %d\n", libc);
	printf("libasm : %d\n", libasm);
	if (libc == libasm)
		printf(GREEN"OK\n"RESET);
	else
		printf(RED"NG\n"RESET);
}


static void	testcase_strcmp()
{
	printf("\n--- test strcmp ---\n");
	const char *d = "01234";
	test_strcmp(d, "01234");
	test_strcmp(d, "012341");
	test_strcmp(d, " 01234");
	test_strcmp("0", d);
	test_strcmp("01", d);
	test_strcmp("012", d);
	test_strcmp("0123", d);
	test_strcmp("01234", d);
	test_strcmp("", d);
	test_strcmp(d, "");
	test_strcmp("", "");
}

int main()
{
	testcase_strcmp();
	return (0);
}
```

## RCXレジスタの使用

文字列をインクリメントさせるための配列の添字として、rcxレジスタを使用した。ループ処理に使われるレジスタです。

> RCX
> カウンタレジスタの「C」です。繰り返し回数を指定するような命令（シフト、ループ、REPプレフィックス付のストリング型命令）で繰り返し回数の設定に使います。その他は汎用レジスタとして使用できます。

> Linuxのシステムコールの呼び出しでRCXの内容は保存されません（破壊されます）。

[Assembly Programming on x86-64 Linux (04)](https://www.mztn.org/lxasm64/amd04.html)

## 参考

### レジスタについて

[x64 でのソフトウェア規約 | Microsoft Docs](https://docs.microsoft.com/ja-jp/cpp/build/x64-software-conventions?view=msvc-160)
[NASM x64 Assembly](https://www.cs.uaf.edu/2017/fall/cs301/reference/x86_64.html)
[Assembly Programming on x86-64 Linux (04)](https://www.mztn.org/lxasm64/amd04.html)

### ステータスフラグについて

[条件ジャンプとフラグ](http://wisdom.sakura.ne.jp/programming/asm/assembly13.html)
[FLAGS register - Wikipedia](https://en.wikipedia.org/wiki/FLAGS_register)
[X86アセンブラ/x86アーキテクチャ - Wikibooks](https://ja.wikibooks.org/wiki/X86%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%A9/x86%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)

### movsxについて

[Assembly Programming on x86-64 Linux (07)](https://www.mztn.org/lxasm64/amd07_mov.html)
[GitHub Actions]github-scriptを使ってJavaScriptでスクリプトを記述する

GitHub Actions でワークフローを作った際に、[github-script](https://github.com/actions/github-script) が便利だったので備忘録として残しておきます。

`github-script` は JavaScript でスクリプトを記述することができ、GitHub の REST API を実行したり [actions/toolkit](https://github.com/actions/toolkit) のいくつかのパッケージをスクリプト内で使用することができます。

例えば、

- 文字列操作を行いたいけど、**JavaScript ではすぐ書ける**のにシェルスクリプトでどう書いたらいいかわからない
- GitHub の REST API を実行したいけど、**シェルスクリプトで curl コマンド書くのが面倒**

のような状況では非常に便利に使えます。

# 使い方

## 基本

```
jobs:
  script-test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/github-script@v3
        with:
          script: console.log(context)
```

- `uses` に `actions/github-script@v3` を指定する（バージョンは適宜変更する）
- `script` に JavaScript で処理を書く
  - ここに記述するのは非同期呼び出しされた関数の中身なので `await` なども使うことができる
  - `script` 内では以下の変数が使用できる（詳細は [ドキュメント](https://github.com/actions/github-script/tree/v3.1.1#actionsgithub-script) 参照）
      - `github`
      - `context`
      - `core`
      - `glob`
      - `io`


## スクリプトの結果を次のステップで使いたい場合

```
steps:
  - uses: actions/github-script@v3
    id: my-script
    with:
      script: return "Hello world!"
      result-encoding: string

  - name: Dump result
    run: echo "${{ steps.my-script.outputs.result }}"
```

- `script` で `return` で結果を返した場合に、その結果を次のステップでも使うことができる
- `result-encoding` で結果のエンコード方式を変更できる
  - `json` (デフォルト) : `return` した結果を `JSON.stringify()` したもの
  - `string` : `return` した結果の文字列


## 前のステップからの結果などをスクリプトで使いたい場合

スクリプト内で使いたい値を環境変数として登録することで、スクリプト内でその値を使うことができます。

```
steps:
  - name: Add reviewer
    run: |
      echo "REVIEWER=XXX" >> $GITHUB_ENV

  - uses: actions/github-script@v3
    env:
      ASSIGNEE: ZZZ
    with:
      script: |
        const { REVIEWER, ASSIGNEE } = process.env;
        console.log(`REVIEWER = ${REVIEWER}`);
        console.log(`ASSIGNEE = ${ASSIGNEE}`);
```


## GitHub の REST API を使いたい場合

例えばプルリクエストが作られた際に、`Review me!` ラベルを付け、特定のユーザーをアサインする場合は以下のように書けます。

使える API については [こちら](https://octokit.github.io/rest.js/v18) から参照できます。

```
on:
  pull_request:
    types:
      - 'opened'

jobs:
  review-action:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const issue_number = context.issue.number;
            const addLabels = github.issues.addLabels({...context.repo, issue_number, labels: ['Review me!']});
            const requestReviewers = github.pulls.requestReviewers({...context.repo, pull_number: issue_number, reviewers: ["watabee"]});
            await Promise.allSettled([addLabels, requestReviewers]);
```

上記で `context` 変数を使っていますが [こちら](https://github.com/actions/toolkit/blob/main/packages/github/src/context.ts) を参照すると使える値がわかるかと思います。

# その他

私は試していないですが、上記以外にもドキュメントを見ると以下のようなことができるようです。

- [ファイルに記載したスクリプトを実行](https://github.com/actions/github-script/tree/v3.1.1#run-a-separate-file)
- [npm パッケージを使う](https://github.com/actions/github-script/tree/v3.1.1#use-npm-packages)
- [GraphQL のクエリを実行する](https://github.com/actions/github-script/tree/v3.1.1#run-custom-graphql-queries)
LinuC合格用 1週間でLPICの基礎が学べる本 4日目まとめ

![4日目まとめ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1124047/0211f7c9-3962-6a82-99b2-1f19f28576e1.png)
【CSS】hoverタグ内のspanタグの色をhover時に色を可変



```vuejs:cinema.vue
<template>
  <header class="header">
    <router-link to="/" class="header-ttl">
      <span class="header-ttl-color">C</span>inema</router-link
    >
    <ul class="header-menu">
      <li>
        <router-link to="/first" class="header-link">初めての方へ</router-link>
      </li>
      <li>
        <router-link to="/signup" class="header-link">新規登録</router-link>
      </li>
      <li>
        <router-link to="/signin" class="header-link">ログイン</router-link>
      </li>
      <li>
        <span class="dropdown-menu" @click="open">
          <a class="header-link"
            >マイページ<span class="dropdown-arrow"></span
          ></a>
          <ul class="dropdown" :class="{ isOpen }">
            <li class="dropdown-items">
              <router-link to="/mypage" class="dropdown-link"
                >マイページ</router-link
              >
            </li>
            <li class="dropdown-items">
              <router-link to="/profile" class="dropdown-link"
                >プロフィール編集</router-link
              >
            </li>
            <li class="dropdown-items">
              <button
                class="dropdown-link"
                @click="signOut"
                v-if="authenticatedUser"
              >
                ログアウト
              </button>
            </li>
          </ul>
        </span>
      </li>
    </ul>
  </header>
</template>
```

#⑴hoverタグ内のspanタグの色をhover時に色を可変

```html:html
 <router-link to="/" class="header-ttl">
      <span class="header-ttl-color">C</span>inema</router-link>
```

```css:css

a.header-ttl:hover,
a.header-ttl:hover span {
  color: darkgray;
}
```

上記については、header-ttlに対してheverを指定し、
またheader-ttl内にあるspanタグに対してheverを指定することで実装可能です。

#⑵hoverタグ内のspanタグ内の色をhover時に色を可変

```html:html
<span class="dropdown-menu" @click="open">
          <a class="header-link"
            >マイページ<span class="dropdown-arrow"></span>
          </a>
```


```css:css

 &-link {
    color: #fff;
    font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
    text-decoration: none;
    background-color: transparent;
    border: none;
    outline: none;
    font-size: 1rem;
    font-weight: bold;
    cursor: pointer;
    cursor: hand;
    margin-left: 3rem;
    &:not(:first-child) {
      margin-left: 2rem;
    }
    &:hover {
      color: #bbb;
    }
  }

.dropdown-arrow {
  width: 0px;
  height: 0px;
  position: absolute;
  top: 9px;
  right: -20px;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 7px solid white;
  .header-link:hover & {
    border-top-color: #bbb;
  }
}
```

上記のドロップダウンメニューの「 ▼ 」はボーダーでできていますので、
**⑴同様の方法で文字色を変えても有効にはなりません。**

```css:css
.header-link:hover & {
    border-top-color: #bbb;
  }
```

**border-top-color**のみにhoverを適用させる事で実装可能です。
1分で分かる、iOS14.5のIDFA問題

# はじめに
iOS14.5からはIDFAを取得する為、アプリ側でトラッキングの許可/不許可の確認を行わなければならなくなりました。

この記事では上記で何が起きるのか、そもそもIDFAとはなんぞやという方向けの記事になります。

# IDFAってなに？(00:00)
IDFAはIDentifer For Advertisingの略称になります。

その名の通り広告用の識別番号でアプリ上に表示される広告に使われます。

個人特定は出来ませんが、効果的な広告を表示する為に利用されます。

# 端末自体を識別する番号とは違うの？(00:10)
端末自体を識別する番号とは厳格には異なります。
（端末自体を識別する番号にはUDID、IMEIといったものが使われます）

IDFAはあくまで広告利用を目的とした番号になります。

# IDFAのハンドリング(00:20)
IDFAの利用はユーザ側から操作することができます。

iOS13までは以下の操作で追跡型広告の制限とリセットが行えていました。

|設定→プライバシー|プライバシー→広告|
|:-:|:-:|
|![IMG_0071.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58367/6d8a6ef7-8d5f-24cf-5fe2-0c274b2cb4c8.png)|![IMG_0072.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58367/bbb299ef-0977-92ea-24d5-b39d74ce6ab4.png)|

# iOS14ではどうなったのか(00:30)
iOS14ではIDFAの取得、つまりトラッキングの許可/不許可を端末単位だけではなく、
`アプリ毎でも設定出来る`ようになりました。

これに伴い設定のプライバシー項目に内容の変更が加えられました。

|設定→プライバシー|プライバシー→トラッキング|
|:-:|:-:|
|![IMG_0137.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58367/86b00edd-f1d2-fa4e-5844-2118dba35213.png)|![IMG_0138.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58367/d8d1794b-eead-43bc-c8f7-9f2d00241e53.png)|

トラッキングを許可したアプリはトラッキング画面に許可したアプリとして表示が追加されます。

一度アプリ上でトラッキングを許可しても、トラッキング画面から再度不許可にすることが出来ます。

また元栓となる`Appからのトラッキング要求を許可`を不許可にすると、
全てのアプリでIDFAの取得が行えなくなります。

# で、iOS14.5のIDFA問題って？(00:50)
iOS14で上記アプリ毎のトラッキング許可/不許可の設定が含まれました。

iOS14.4まではアプリ上でユーザに対してトラッキングを許可/不許可を確認しなくてもIDFAを取得出来ていました。

しかしiOS14.5からは必ずユーザに対しトラッキングの許可/不許可を確認しなくてはなりません。

もしアプリが対応していない場合はIDFAが取得できなくなります。

これがiOS14.5のIDFA問題です。

# 参考
### ユーザーのプライバシーとデータの使用
https://developer.apple.com/jp/app-store/user-privacy-and-data-use/

### OS 14.5は「数週間」以内に配信予定。ユーザーの無断追跡禁止とともに
https://japanese.engadget.com/ios145-att-release-030040733.html

### iOS14でtrackingAuthorizationStatusのメモ
https://qiita.com/n_komiya/items/16958bab6a4899dc20a5
モジュール/ライブラリ

# モジュール
**モジュール**とは、Pythonのコードが書かれたファイルのことです。
別ファイルをモジュールとして読み込むことでそこに書かれたコードを利用することができます。

##### import
**import**を使うことで、モジュールを読み込むことができます。
モジュールを読み込んで使いたいファイルに、「`import モジュール名`」と記述することで、読み込むことができます。
※モジュール名はファイル名から「.py」を除いたものです。

```py:script.py
import utils   # 「import モジュール名」

valid = utils.validate(1)   # 「モジュール名.関数名()」
print(valid)
```
```py:utils.py
def validate(hand):
    if hand < 0 or hand > 2:
        return False
    else:
        return True
```
と記述することで、「utils.py」ファイルに記述した関数のコードを「script.py」ファイルで使用することができます。
「`モジュール名.関数名()`」と記述することで、モジュール内の関数を実行することができます。
引数をがある場合は、関数を使用する時と同様に()の中に書きます。


# ライブラリ
上記では、自分でモジュールを作りましたが、Pythonには便利なモジュールがいくつか用意されています。これらのあらかじめ用意されているモジュールは標準ライブラリと呼ばれ、importを用いて読み込むことで便利な関数を利用できるようになります。

### randomモジュール
randomモジュールに用意されている関数randintを用いて、値がランダムになるようにできます。
「`random.randint(x, y)`」と記述することで、xからyまでの整数をランダムに取得することができます。

```py:例
import random

def num():
    return random.randint(1, 5)   # randint関数を用いて、1 ~ 5の数値をランダムに取得

random_num = num()
print(random_num)
```
```text:出力結果
1 ~ 5 の数値がランダムに出力されます
```
Node.jsとは？？

今回は、Node.jsについて学習していきます。

#Node.jsとは？？
簡単に言うとサーバーサイドバージョンのJavaScriptです。
最近JavaScriptでフロントが書かれているため、サーバーサイドもJavaScriptで書いたら効率いいよねってことで使われています。

#　　　　　　Node.jsで何ができるのか？？

#　①Node.jsじたいは動かない
え？動かんの？って思った方もいらっしゃるかなと思います。JavaScriｐｔのプラットフォームです。
あくまで、Node.jsはメインであるJavaScriptが動くよう補佐官のようなものです。　

#　②Webアプリ
Node.jsは軽量のため、リアルタイムのウェブアプリケーションに最適です。
また処理速度も早いため、複数人がログインする場合などに使われたりします。

#　③ゲームアプリ
ゲーム通信に適した通信プロトコルを使用できるようになるライブラリを使用した方がより良いアプリを作ることができます。

#　④スマートフォンアプリ
リアルタイム通信が可能なため、チャット機能などの実装に使われています。

#　⑤ウェブAPI
Expressという機能を使うことで、WEBAPIを作ることができます。
*Expressとは、ウェブアプリケーションやモバイルアプリケーション向けのNode.jsのフレームワークです。
Wordにも、２つの文書を比較して差分を教えてくれる機能があった！

[Wordにも、２つの文書を比較して差分を教えてくれる機能があった！ | エンジョイ！マガジン](https://enjoy.sso.biglobe.ne.jp/archives/word_hikaku/)

へー
1.「文書の比較」画面を開く



2.「元の文書」を指定する






3.「変更された文書」を選択する



4.比較の文書を開く



5. 2つの文書が比較されて表示される



規約書、契約書、仕様書、メールマガジンなど、業務では元原稿と修正原稿を比較しないといけないことが多いかと思います。Word文書でやり取りしている方は、ぜひ活用してみてください
PublicPath設定を変えてもhistoryApiFallbackをきかせて更新可能にする方法

# Vue開発時にドメイン直下のURLにしない場合
Vue.jsを使った開発の話。
`npm run serve`すると開発サーバーが立ち上がります。
開発サーバーだけど、使っているドメイン直下のURLじゃないところにおいてアクセスしたいときありますよね。

例えば、
`https://example.com/`
ではなくて
`https://example.com/myapp/`
にアクセスしたときに表示してほしいみたいな。

自分の場合、グローバル環境にサーバーを一台置いて、リバースプロキシでURLごとに各開発環境に振り分けています。
`https://example.com/appA`ならappAのサーバーを、
`https://example.com/appB`ならappBのサーバーを呼び出してくるみたいな感じです。


ドメイン直下でない場合、PublicPathを設定してやればうまくいきます。
vue.config.jsをつくって以下のように書くだけですね。

``` vue.config.js
module.exports = {
  publicPath: '/myapp'
}
```

ただ、こうするとhistoryApiFallbackがきかなくなります。
そもそもhistoryApiFallbackは、VueRouterをhistoryモードで使っているときに更新したり直URLをたたいたりすると、404になったりエラーが出たりしてしまう際に、ちゃんと動かしてくれる機能です。
同じくvue.config.jsで設定してやります。

``` vue.config.js
module.exports = {
  devServer: {
    historyApiFallback: true
  }
}
```

PublicPathがデフォルトの時はこれで動きますが、PublicPathを変えると動かなくなります。

# historyApiFallbackをPublicPathに合わせて設定する
こんな感じで設定したらうまくいきました。

``` vue.config.js
module.exports = {
  publicPath: '/myapp',

  devServer: {
    historyApiFallback: {
      index: '/myapp/'
    }
  }
}
```
※他のもろもろの設定は端折ってます

参考URLはっときますね

https://webpack.js.org/configuration/dev-server/#devserverhistoryapifallback

https://github.com/bripkens/connect-history-api-fallback
SendGridのDynamicTemplateでハマった話

## Sendgridとは・・
SendGridとは全世界で利用されているメール配信サービスです。

https://sendgrid.com/

SMTP, APIでメール送信を行なってくれるサービスで使われている方も多いと思います。
今回の話題はAPI経由でメール送信を行うときの便利な機能であるDynamicTemplateでハマった部分についてお話しようと思います。

DynamicTemplateはSendGridにTemplateを登録しておき、API経由でTemplateベースのメールを送信する機能です。  
APIにメール本文すべてを渡すのではなく、一部を変数化し、その変数をTemplateに当てはめて動的なメールを送信することができます。

変数展開だけでなく、ループやIF文を使い条件分岐をさせることもでき、メール表現の幅が広がります。

## どこにハマったの？
結果から言うとIF文などちょっとロジカルなことをする部分でハマりました。

何がだめだったかを実際に見てみます。

駄目なパターン

``` html
{{ #if isAdministrator }}
<a href="https://example.com">管理者ページへ</a>
{{ /if }}
```

良いパターン

``` html
{{#if isAdministrator}}
<a href="https://example.com">管理者ページへ</a>
{{/if}}
```

if文を書くときに `{{` と `#if` の間に半角スペースがあることでした。
なんとなく感覚的にカッコの次は半角スペースを入れるということをやっていたために
シンタックスエラーがあり、うまく動かないようでした。

このシンタックスエラーはエディタ上でうまく表示してくれないようで、ハマると延々と躓くことになると思います。
皆さん気をつけましょう！
戻り値return

# 戻り値return

```py:例
def validate(hand):
    if hand < 0 or hand > 2:
        return False
    else:
        return True

valid = validate(1)
print(valid)
```
```text:出力結果
True
```
と記述することで、関数`validate`は引数`1`を受け取ると、処理の結果はTrueとなり、呼び出し元に返します。
この`True`にあたるのが**`戻り値`**です。(Falseも戻り値です。)
記述としては「`return 戻り値`」と書くことで呼び出し元に返すことができます。
そして戻り値があると、関数の呼び出し部分がそのまま値に置きかわります。
例だと、呼び出し元`validate(1)`が戻り値`True`に置きかわります。
それにより、関数の呼び出し部分を変数に代入することができるので、出力結果は`True`が表示されます。
***
### 戻り値を条件式で使うことができます
戻り値がある関数をif文の条件式に書くことで、戻り値の結果に応じて条件分岐をすることができます。

```py:例
def validate(hand):
    if hand < 0 or hand > 2:
        return False
    else:
        return True

if validate(num):
    戻り値がTrueの場合の処理
else:
    戻り値がFalseの場合の処理
```
と記述することで、まずif文の条件式で関数`validate`を呼び出し、関数が実行されます。
そして、戻り値が返されるとその戻り値の結果に応じて条件分岐されます。

この時、条件式でTrueやFalse同士を比較する場合は、「== True」や「== False」を省略することができます。

```py:例
if validate(num) == True:
      ⬇
if validate(num): # == Trueを省略できます
```
---
また、**return**は戻り値を呼び出し元に返すだけでなく、関数内の処理を終了させる性質を持っています。
よって、return以降の関数の処理が実行されることはありません。

```py:例
def num(x, y):
    return x + y
    print('合計値です')

sum = num(1, 3)
print(sum)
```
```text:出力結果
4
[  ]← 合計値です は出力されません
```
上記のように、`return`を記述するとそれ以降の処理(今回では`print('合計値です')`)が実行されません。
markdownで数字付きリストを続ける

# コードブロックを挟むと数字付きリストが連続しないことがある。
1. one 
2. two

```
two is 2
```
3. three

## threeを3として続けるにはコードブロックをインデントする（4spacesだとうまく行った）

````markdown 
1. one 
2. two

    ```
    two is 2
    ```
3. three
````

1. one 
2. two

    ```
    two is 2
    ```
3. three
ダイアログの表示


ログアウト時や削除時に、確認を行うダイアログを表示したいときは、data-confirmオプションを指定することで表示することができる。

```例
<%= link_to "ログアウト", destroy_user_session_path, method: :delete,  data: { confirm: 'ログアウトしますか？' } %>
```
**data: { confirm: 'ログアウトしますか？' }**　の部分。

この記述をするだけで、間違って削除してしまったりすることを減らせるのでユーザーが使いやすくなる。
人生始めて勉強会で登壇してみた話！

## はじめに

みなさんこんにちは！
ハンズラボのサムです！

タイトル通りなのですが、4/7に実施された**「AWS認定 デベロッパーアソシエイトの試験に出るかもなデモ見せあいっこ(ヤマムギvol.12)」**に参加し、
なんとこの度人生で初めて社外の勉強会で登壇側をやりました！！

今回の記事は登壇するまでの裏話とプレゼン資料の公開となります。

物凄く良い機会を頂きました！主催の山下さん本当に有難うございます！！
また、社内の広報の方や見に来てくださった方々本当に有難うございます！！

## 登壇するにあたって色々あったこと

3/21に私のTwitterに山下さんからDMがあり登壇側で参加しませんか！？とお話がありました！
↓
3/22に会社の上司に相談して参加を決意！＆社内のコーポ担当から宣伝するよとお話を頂きました。
そしてコーポレイトサイトのニュースに掲載してもらうことに！！(4/1)

https://www.hands-lab.com/news/n11742/

こういう風に会社の色々な方々の応援してもらえるの本当に嬉しかったです！

そしてここまで来て致命的な問題に遭遇しました。
**発表のネタが思いつかない＆かぶらない様にするにはどうすればよいか！！**

非常に悩んでいたらプレゼン１週間前で大慌てで山下さんの本を読みながら考えていたらふとAWS Elastic Beanstalk面白そうだなと思い、
ネタを決めたので、ここから検証作業をひっそりとやっておりました。
※タイトル発表が遅くなって申し訳ないです...

AWS Elastic Beanstalkは触ったことは無いものの、AWS SAAとかの試験で内容は知っていたのでイケるだろうと踏んでテストをしてみたら、
Webページ用のコードをアップロードする時にzipで圧縮しないといけないのですが、何も考えずに圧縮しないでアップロードしてエラーが起きて悩んだり・・・
![スクリーンショット 2021-04-08 15.15.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181414/be9dca19-9a93-2912-3d64-7a1a0c6fe495.png)

単一インスタンスにするとロードバランサーが作られなかったり・・・
![スクリーンショット 2021-04-08 15.26.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181414/137ad483-f20d-77d3-ab9e-2f21602b267b.png)

当初作ったデモとプレゼンを合わせると制限時間15分を超えるので頑張って削り、
なんとか自分でテストして制限時間の15分でプレゼンとデモを収めることに成功！！

その後、社内のチーム内でデモを実施し15分30秒程度で収めたので、プレゼンの最終段階で少しだけ小休止の話題を削ったりして調整しました。

## 登壇当日

一応事前にお知らせのあった時間にzoomに入ってご挨拶と画面のテストをしたりしてましたが、既にめちゃくちゃ緊張してました！！
他の方が発表しているときは割と集中して見て楽しんでいたのですが、ふと我に帰ったりしたタイミングでAWSのマネジメントコンソールからログアウトしてないかとか、
必要なページはちゃんと表示してあるかとかしきりに確認しておりました・・・。
※心の余裕がなくてあまりツイート出来ず・・・

発表の時も緊張して頭が真っ白でしたが身体が勝手に動いて喋ってました！
後々Twitterやコメント見させていただきましたが、お褒めのお言葉を頂いており嬉しくなって何度もみてニヤニヤしてました（（

発表会の後の懇親会？も色々なお話を聞けて楽しかったです！！

## 感想

総評としてはすごく楽しかったです！！

ただ、ひとつ思ったことは、アウトプットの難しさを痛感しました。
Qiitaの記事ですら難しいと感じるのに、プレゼンとなるとページの構成やレイアウト・デザイン、しゃべる速度、デモの準備など
様々な要因が重なり合って構成できているのでどれもおろそかに出来ないですし、事前の準備の大事さも痛感致しました。

ただ、それと同時にやりきった後の快感と知識の浸透は普通に検証したり記事を書くよりも遥かに多いと感じたので、
これからも機会があればどこかで登壇とかできたらと思いました！

今回のこの記事は完全になぐり書きですが、あえて自分の中の思いを昇華するためにこのスタイルでいきました！
ここまで読んでくださりありがとうございました！

## オマケ

当日のプレゼン資料はこちらから見ることが出来ます！

https://speakerdeck.com/anakagawa/20210407-yamamugivol-dot-12-zhong-chuan-hao-hong
goLang+gin+nginxで開発環境を作ってみる

## 目的
GoLang + Gin の開発環境をWindows(Vagrant-AmazonLinux2)で試してみる

## 環境
- OS:Windows10Pro
- VM:Vagrant(AmazonLinux2)
- BackEnd:Go + Gin

## VM設定
Vagrantで開発環境作ります。

1.ローカル環境に任意のフォルダ(c/venv/xxxx-apl)を作成する。
2.Vagrant定義(bash起動して下記コマンド実行) 

```sh
cd /c/venv/xxxx-apl
vagrant init gbailey/amzn2
```

3.Vagrantファイルの作成（C:\venv\xxxx-apl\Vagrantfile）

```sh
Vagrant.configure("2") do |config|
# AmazonLinux2
  config.vm.box = "gbailey/amzn2"
  config.vm.network "private_network", ip: "192.168.33.10"
# ローカル開発環境(c:\gits\xxxx-apl)とホストのappディレクトリを同期する
  config.vm.synced_folder "/gits/xxxx-apl", "/app/xxxx-apl",type: "virtualbox"
end
```

4.Vagrant 起動

```sh
vagrant up
```

## GoLang
Goをインストールします。

1.yum update

```sh
sudo yum update
```
2.Install Golang

```sh
sudo yum install -y golang
```
*AmazonLinux2extraの方がバージョンが低かったのでそのままyumで入れました*


## Gomod
Goのモジュール管理（Gomod）を設定します。

1.envのGoModuleを有効化します

```sh
cd /app/xxxx-apl
go env -w GO111MODULE=on
```
2.gomodの初期化を行います

```
go mod init xxxx-apl
```

## Gin
GoLangのwebフレームワークGinを入れます。

```sh
go get -u github.com/gin-gonic/gin
```


## Nginx
WebServerはNginxを利用します。

1.extrasからnginxをインストール

```
sudo amazon-linux-extras install nginx1
```
2.nginx起動

```sh
sudo systemctl start nginx
```
3.nginxの自動起動設定を行う

```sh
sudo systemctl enable nginx
```
4.ブラウザで確認（Vagrantに設定したIPでアクセス）

```
http://192.168.33.10/
```

## 試してみる
1. main.goを作成

```go
package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/api/test", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "hellow!",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}
```
2.nginx設定
/etc/nginx/xxxx-apl.confを作成し配置

```conf
server	{
     listen       80;
     location / {
         proxy_pass http://127.0.0.1:8080;
     }
    error_log  /var/log/nginx/xxxx-apl.error.log error;
}
```

3.起動

```sh
go run main.go
```

4.ブラウザアクセス`http://192.168.30.10/api/test`して下記が表示される 

```
"message": "hellow!"
```
Goのdeferって何

Q. deferって何？
A. 関数をreturnする直前に処理を実行してくれます。複数のdeferに処理を渡した場合、最後に渡した処理から順に実行されます。

## サンプルコード
```go
package main

import "fmt"

func main() {
	defer func(){
		fmt.Println("defer1")
	}()
	defer func(){
		fmt.Println("defer2")
	}()
	
	if true {
		fmt.Println("go1")
		return
	}
	fmt.Println("go2")
}
```

## 実行結果
```
go1
defer2
defer1
```
GitHubへのSSH接続手順

# はじめに

GitHubへSSHを利用した接続手順をメモとして残します。

### 環境
Windows10

### 事前準備
GitHubのアカウントが作成済みであること。
PCにGit for Windowsがインストール済みであること。

# 全体の流れ

①　公開鍵・秘密鍵の作成
②　configファイルの作成
③　GitHubに公開鍵を登録
④　接続確認
⑤　鍵をssh-agentへ登録

# ①公開鍵・秘密鍵の作成

Git Bashを起動し、以下の```ssh-keygen```コマンドより公開鍵・秘密鍵を生成します。

```
ssh-keygen -t rsa -b 4096 -C "hogehoge@fuga.com"
# -C メールアドレス
```

鍵の保存場所を聞かれるので、問題なければそのままEnter。
変更した場合は```:```以降に任意のパスを入力します。

```
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/{user name}/.ssh/id_rsa): 
```

パスワードの設定を聞かれるので、任意のパスワードを入力します。
※空でも登録できますが、セキュリティ面を考えると設定した方が良さそうです。

```
Enter passphrase (empty for no passphrase):
```

入力したパスワードを再入力します。

```
Enter same passphrase again:
```

以下のメッセージが表示されればOKです。

```
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
SHA256:VoikRYkzotb7ds0dmdtu/QhNu0DePN9Lla5LTjtBCM8 hogehoge@fuga.com
The key's randomart image is:
+---[RSA 4096]----+
|     o+.         |
|  . ++.. o       |
| ....o. . = .    |
|.. .     . E .  .|
|.   .   S   = ...|
|   .   .   * *...|
|    .   o . BoOo |
|     o . o o+*+*.|
|    . .     o*=.*|
+----[SHA256]-----+
```

指定したパス（デフォルトでは/c/Users/{user name}/.ssh）にid_rsa（秘密鍵）、id_rsa.pub（公開鍵）が作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410918/6676bbb1-1dcb-817a-200a-42208ff0debc.png)

# configファイルの作成

①で作成した鍵と同じディレクトリにconfigファイルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410918/d6d0b6be-e050-27f7-18e6-7abff9914262.png)

configファイルをエディタで開き、下記を貼り付けます。

```
Host github
  HostName github.com
  IdentityFile ~/.ssh/id_rsa
  User git

# IdentityFileは秘密鍵のパス
```

ファイルを保存したらconfigファイルの設定完了です。

# ③GitHubに公開鍵を登録

GitHubにログインして、右上のアイコンから**Settings**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410918/02906890-c3e1-640e-fa29-b7bb036b68d8.png)

**SSH and GPG keys** > **New SSH key**を選択して公開鍵を登録します。
Title・・・任意の文字列
Key・・・生成した公開鍵の内容（公開鍵ファイルをエディタで開き、全選択・コピーし、そのまま貼り付け）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410918/4465da08-271a-0162-550e-e77b7a3c93d6.png)

# ④接続確認

Git Bash上から以下のコマンドを入力します。

```
ssh -T git@github.com
```

初回は接続確認を聞かれます。
問題ないのでyesを入力しEnter。

```
Are you sure you want to continue connecting (yes/no)?
```

パスワードの入力を求められるので、①で設定したパスワードを入力してEnter。

```
Enter passphrase for key '/c/Users/test1/.ssh/id_rsa':
```

以下のメッセージが表示されれば接続OKです！

```
Hi seiyaKM! You've successfully authenticated, but GitHub does not provide shell access.
```

# ⑤鍵をssh-agentへ登録

④までの内容でSSH接続の設定は完了ですが、毎回パスワードの入力を求められるので、省略したい場合はssh-agentを利用します。

.sshがあるディレクトリと同階層に```.bashrc```ファイルを作成します。
作成したファイルをエディタで開き、以下を入力します。

```
#ssh-agent
eval `ssh-agent`
ssh-add
```

Git Bashを再起動するとパスワードの入力を求められます。
ここで認証が成功すれば、以降はパスワードの入力を省略できるようになります。
※ターミナル単位での永続化になるので、別のターミナルを開いたり、一度ターミナルを閉じて再度開くと最初のパスワード入力は発生します。
出来るだけ自分に有利なアンケートを作る

# 概要
「弊社商品は〇〇％の利用者※が”良い”と評価しています」
という数字を目にすることがありますね。

こういう数字って大抵アンケートから作るのですが、どうせならできるだけ良い数字にしたいと思いませんか？
営業努力でお客様満足度を上げて数字を良くするのも大切ですが、ちょっとしたコツで簡単に数字を良くできるので今回はその方法をお教えします。


# 評価の基準を作る
基準の無いアンケートはユーザによって評価がぶれてしまい、思わぬ低評価を受けてしまう可能性があります。

ユーザの中にはこちらの想定外の辛めの評価をする方もいらっしゃいます。
例えば、★での5段階評価の時、「1年で★５を付けるのは1件あるか無いか」というユーザや「普通に良かったから★３。★5は付けたことない」というユーザもいるかもしれません。

こういったユーザによってばらけた基準で評価され、想定外に評価が低くなるのを防ぐため
「５：良い、４：どちらかというと良い、３：普通、２：どちらかというと悪い、１：悪い」
といったように基準を明記することが有効です。


# 4段階評価にする（中央値を消す）
アンケートは「中央値に寄りやすい」という心理効果があります。正規分布に従うと仮定すると5段階評価は
５：6.7%
４：24.2%
３：38.3%
２：24.2%
１：6.7%
となってしまい、「30%のユーザしか良いといえる５，４の回答をしていない」となります。

ここで中央値の存在しない4段階評価「４：良い、３：どちらかというと良い、２：どちらかというと悪い、１：悪い」に変更してあげます。

すると「50%のユーザが良いと言える４か３の回答をした」となります。

何もしてない＋単純な統計に従っているだけなのに数字が改善しました٩( ᐛ )و

ちなみにこれは「Good・bad」の2段階評価でもよいですが、「Goodとは言い切れないけどどちらかというと良いくらいなら回答してもよい」と思っているユーザを取り込める4段階評価が個人的にオススメです。

また、6段階評価以上に行くと「良いって言えるの、5,6だけでは？3～4は普通評価なのでは？」という正論を言う人が出てくるので4段階がやはりオススメです。
（この辺の中央値に寄りやすいって心理を考慮したNPSという評価手法などもあるので気になる人は調べてみてネ）

# 「外れ値」を利用する
一般ユーザ向けにアンケートをとっているとどうしても「お怒りのユーザが故意の最低評価をしてくる」ことがあります。
そういった数字は「外れ値」として統計的に除外しましょう。

外れ値の定義方法はたくさんありますので、グラブス検定や、四分位範囲などいろいろ試してみてください。
一番数字が良くなった統計手法を使うことをお勧めします。

え？改ざんではないかって？？？
「データの改ざん」はしていません。
また、外れ値の除外自体は「ユーザの誤操作の影響を減らす」といった正しい目的に使われることがあり一般的なものです。

「一般的な統計手法」を用い、「外れ値除外する」理由があり、「計算した結果の正しい数字」が露出しているので、誇大広告・優良誤認には当たりません。

でも露骨にやりすぎると流石に違和感出てくるので統計の悪用はほどほどにね٩( ᐛ )و

# 悪い評価を付けにくくする
「アンケートは営業さんから手渡しでお客様に渡しその場で回答してもらう」or「記名式アンケート」したうえで「アンケートはお客様の担当営業の考査に使う」と記載します。

担当営業ならば多少なりともお話しして「ユーザにとって身内よりの人間」になっています。
その身内に「悪い」と評価を付けにくい人間心理を利用します。

そのほか「悪いと評価した場合、悪い理由を必ず書いてね」とか「悪い理由を直接別途お電話で聞く場合があります」など書いて「悪いって書いたら面倒くさいな」と思わせるのも手です。
なお、ハードクレーマーが意気揚々と悪い理由を教えに電話してくださる場合があります。気を付けましょう٩( ᐛ )و

# 良い評価が付きやすいように母集合を調整する
アンケートをとるタイミングを「商品購入後or契約完了後」にします。
そうするとが「商品が良いと納得して購入or契約した人だけ」がアンケート対象になるので、良い評価が付きやすくなります。

※実際に商品を利用したユーザにアンケートを取りました。とか小さく書いてあるヤツです。

こうすると実はアンケートによる「ユーザ満足度X％」という文面の「ユーザの定義」が「良い評価をしやすい母集合」に偏ったものになります。
一方で大多数のユーザはそんな事実には気が付かず、「満足度の高い良い商品なんだな」としか感じ取りません。
わざわざ説明する必要もないですし説明責任もないところなので、誤解したままでいてもらいましょう٩( ᐛ )و

# いろいろ言ったけど。
上記のようにアンケートの数字はある程度操作することが可能です。

「顧客満足度NO1（弊社調べ）」とか、
「御社にコンサルとして入って〇〇の数字を改善しました」とかエビデンスっぽい数字を出されるともっともな気もしてしまいますが簡単に信用しないようにネ٩( ᐛ )و
初学者のプログラミング　ActiveRecord::NotNullViolation in Devise::RegistrationsController#create

##Deviseで生年月日登録でエラーが出た。
ユーザー登録時に生年月日も登録できるようにしたところ、`ActiveRecord::NotNullViolation in Devise::RegistrationsController#create`のエラーが出て散々悩まされた。
##Deviseの仕様
どうやらDeviseの仕様として、デフォルトで受け付けているデータ以外は「安全なデータである」という宣言をApplicationControllerでする必要があるとのこと。

```app/controllers/ApplicationController.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up,
                                      keys: [:birth_day])
  end
end
```

上記のように`configure_permitted_parameters`に登録時(sign_up)に受けつけるデータとして`:birth_day`カラムを追加することによって生年月日の登録ができるようになった。

##まとめ
参考記事を読みながら「確かそんなんあったなー」っと振り返ることができた。結局すぐに忘れちゃうから、困ったことを残しておくことが重要なんだと再確認できた。

##参考
https://teratail.com/questions/235508

## さいごに
プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。より深く学習していきたいと考えておりますので、内容に誤りがございまいたらご指摘等いただけますと幸いです。

参考図書：パーフェクト Ruby on Rails【増補改訂版】すがわらまさのり/前島真一/橋立友宏/後藤優一/五十嵐邦明
rails6にbootstrapを導入する方法

#目次
<b>①Bootstrapのパッケージをインストールする</b>
<b>②Bootstrapを利用できるようにする</b>
<b>③jQueryとPopper.jsを利用できるようにする</b>
<b>④レイアウトを修正する</b>


##①Bootstrapのパッケージをインストールする
ターミナル上で以下のコマンドを実行する
※bootstrapとjQueryとpopper.jsをインストールしている

```
yarn add jquery bootstrap popper.js
```
##②Bootstrapを利用できるようにする
yarnでインストールしたbootstrapのパッケージを利用できるようにするために、
app/javascript/packs/application.js に以下のコードを追加する。

```
import 'bootstrap'
import '../stylesheets/application'
```

app/javascript/stylesheets/application.scssに以下のコードを追加する。


```
@import '~bootstrap/scss/bootstrap';
```

##③jQueryとPopper.jsを利用できるようにする
app/config/webpack/environment.js を修正し、jQueryとPopper.jsを利用できるようにする。


```
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
    Popper: ['popper.js', 'default']
  })
)
module.exports = environment
```
##④レイアウトを修正する
 app/views/layouts/application.erb.html の「stylesheet_link_tag」を「stylesheet_pack_tag」に変更する。

```
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
```
ラズパイのプロセス監視を slee-Pi3 のウォッチドッグタイマで【異常動作検知による監視編】

今回は slee-Pi3のウォッチドッグタイマを利用したプロセス監視機能を活用します。
slee-Pi3 の動作確認が狙いなので、お手元の環境で実行する際は service ファイルのオプションを調整してください。
※作業環境と事前準備は [こちら](https://qiita.com/kiyonaga/private/d86428c8f2ccbd18cd98#%E7%92%B0%E5%A2%83) をご覧ください。

# [関連ブログ]
slee-Pi3 のウォッチドッグタイマを利用したプロセス監視
【[OOM 状態からの即時復帰](https://qiita.com/kiyonaga/items/d86428c8f2ccbd18cd98)】
【[正常動作検知による監視](https://qiita.com/kiyonaga/items/388aa32891d7c0f33266)】
【異常動作検知による監視】←　本ブログ
【[異常動作検知－実装編](https://qiita.com/kiyonaga/items/38b362c4a192c5f13303)】

# [目的と方法]
目的：停止したくないプログラムが停止した場合にクリーンな状態で再開させたい。
方法：プログラム内にハートビートを組込んでおき、ウォッチドッグタイマが異常検知した際に再起動させる。

# [手順1]service ファイル作成
**目的の再現性を高める＋プロセスがkillされやすい**ように Nice=19 , OOMScoreAdjust=1000 に設定しています。
設定の詳細は以下をご覧ください。
[Nice](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Nice=)
[OOMScoreAdjust](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#OOMScoreAdjust=)
```/etc/systemd/system/test-heartbeat.service
[Unit]
Description=sleepi3 test heartbeat
DefaultDependecies=no　
After=sysinit.target

[Service]
Type=simple
Nice=19
OOMScoreAdjust=1000
ExecStart=/opt/mtx/test-heartbeat.sh　←　実行ファイルのフルパス

[Install]
WantedBy=sysinit.target
```

# [手順2]実行プログラム＋ハートビートを作成
前回と同じプログラムを使用しています。
詳細は [こちら](https://qiita.com/kiyonaga/private/388aa32891d7c0f33266#%E6%89%8B%E9%A0%862%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%83%8F%E3%83%BC%E3%83%88%E3%83%93%E3%83%BC%E3%83%88%E4%BD%9C%E6%88%90) をご覧ください。

# [手順3]既存の sleepi3-heartbeat.service を停止し、自作ハートビートを起動する
sleepi3-heartbeat.service は sleePi3-utils に含まれている service です。
```bash
sudo systemctl disable sleepi3-heartbeat.service
sudo systemctl enable test-heartbeat.service
sudo systemctl restart test-heartbeat.service
```
test-heartbeat.service 部分には自作ハートビートのファイル名を入れてください。

# [手順4] OOMKiller 用プログラム作成と実行
今回は [こちら](https://blog.longest-road.com/oom-killer-1/) のブログを参考に作成しました。

※ コード中に (\&amp;t) のような HTML エンティティが含まれています。コードを使用する際は該当部分を取り除いてご利用ください。

# [手順5]復帰確認
OOM 状態になるとハートビートが途絶える様子を確認できます。
途絶えてから60秒後に再起動を始め、正常に起動すれば異常状態からの復帰は成功です。
※slee-Pi3 セットアップ時のウォッチドッグタイマ監視時間は60秒です。

また、下記コマンドを実行すると再起動要因がわかります。
```bash
sleepi3ctl get wakeup-flag
watchdog
```

# [まとめ]
今回は slee-Pi3 のウォッチドッグタイマによるプロセス監視機能を利用しました。
監視させているプロセスが OOMKiller に kill された際にハードウェアリセットをかける仕組みです。
macOSでDNSキャッシュの削除

Terminal.appを起動して以下を実行する．

```bash
sudo killall -HUP mDNSResponder
```

参考記事:

- [macOSでDNSのキャッシュを削除する方法](https://faq.interlink.or.jp/faq2/View/wcDisplayContent.aspx?id=1042)
- [DNSキャッシュをクリアするには（Windows、Mac、Chrome）](https://kinsta.com/jp/knowledgebase/flush-dns/)
swiperのpaginationに0を付けて表示したい

##はじめに
先日の案件で、**swiperのpaginationに0を付けて表示したい**という要望があった。

公式サイトでは以下の通り。
https://swiperjs.com/demos#pagination-fraction
（なお、IEに関してはV5系以上からサポート外となったため、IEでも使用したい場合はv4.5.1以前のものを使用して下さい。）
![スクリーンショット 2021-04-03 12.45.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1211427/2d935947-90e4-5326-08ba-46292a9f1ccc.png)


<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="html,result" data-user="___dan" data-slug-hash="mdRmOXO" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="swiper default">
  <span>See the Pen <a href="https://codepen.io/___dan/pen/mdRmOXO">
  swiper default</a> by dan (<a href="https://codepen.io/___dan">@___dan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

今回は、「1/10」となっている箇所を、「01/10」となるように実装する。


##実装編
formatFractionCurrentというパラメーターが存在し、それを使うと現在のnumberの値を取得できるみたい。
今回は、numberに0を加えたいので、paginationを以下のように実装した。

```JavaScript
pagination: {
    el: '.swiper-pagination',
    type: 'fraction',
    formatFractionCurrent: function (number) {
        return '0' + number;
    }
}
```

これで、「01/10」のような形に出来上がり。
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="html,result" data-user="___dan" data-slug-hash="eYgGaJB" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="swiper fraction">
  <span>See the Pen <a href="https://codepen.io/___dan/pen/eYgGaJB">
  swiper fraction</a> by dan (<a href="https://codepen.io/___dan">@___dan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

##補足
スライドの個数が10個以上のときを考慮して、少し条件分岐を加える必要がある。
（今のままでは、10以上の数値のときに「010/10」となってしまうため。）

取得したnumberの値が10以下のみ、0を加えるようif文で条件式を追加。
これで、思った通りの形になりました。

```JavaScript
formatFractionCurrent: function (number) {
    if (number < 10) {
        return '0' + number;
    } else {
        return number;
    }
}
```

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="html,result" data-user="___dan" data-slug-hash="ExZwzKX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="swiper fraction &amp;gt; 10">
  <span>See the Pen <a href="https://codepen.io/___dan/pen/ExZwzKX">
  swiper fraction &gt; 10</a> by dan (<a href="https://codepen.io/___dan">@___dan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

##参考記事
下記のサイトから、パラメーターを検索しました。
https://www.tutorialdocs.com/tutorial/swiper/api-pagination.html