OmniAICreator/Qiita-1.07M huggingface dataset:
TsukuCTF 2021 -  digits 100 

#問題

https://tsukuctf.sechack365.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/af4fe60e-2475-7574-90ab-0bac67ec3ceb.png)


#解いてみた

まずは問題文のhttps://tsukuctf.sechack365.com/problems/digits にアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/2d5408be-08df-9218-d53f-fe2ddeaa4567.png)

が返ってきます。
パラメータをつけてhttps://tsukuctf.sechack365.com/problems/digits?q=1234567890 にアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/764def86-1a16-cd05-462d-f075dbd9e405.png)

これはもちろん失敗ですが、何か成功するとフラグが出てくるということでしょうか。
0000000000~9999999999をやればどれか成功する？

とりあえず添付ファイルをダウンロードしてみてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d7a53776-9256-10a0-da3b-671a9f6052b6.png)

見た感じパラメータについてチェックしてるだけのようで

- 10桁
- 「-」や「+」が入ってない。
- 整数（int型）

の条件を満たしてかつ 文字列の先頭4文字に 0より小さい数 or 9より大きい数があれば成功。ということでしょうか。
整数じゃないといけないのに0より小さいか9より大きい数字なんて10進数にはないはずです。
記号でもいれて文字コードで9より大きい数字をたたき出す感じでしょうか。

「.」を使えば小数だけどintの時はまるめてくれそう。

https://tsukuctf.sechack365.com/problems/digits?q=1.34567890 にアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c4d41f7f-9e8d-58a4-eb70-bdf0d8473c93.png)

ダメ。
小数点以下が0ならいけるか？
https://tsukuctf.sechack365.com/problems/digits?q=1.00000000 にアクセス。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/1eb829fa-6b9e-5f39-e099-6f467d27c049.png)

ダメ。
先頭を0xにしたら16進数として読み込んでくれる？
https://tsukuctf.sechack365.com/problems/digits?q=0x34567890 にアクセス。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/0d1bd5da-b25b-dc87-97ed-046a1807c588.png)

ダメ。

pythonの整数で使える記号をネットで調べてみると以下の記事が見つかった。

pythonのアンダーバーこれなんやねん
https://qiita.com/kiii142/items/6879cb065ad4c5f0b901

数字を見やすくするためだけに「_」を使うことができるらしい。
たとえば1_000なら1000として扱われる。
見た目だけ人間には見やすくなるけどプログラム的には無視されるらしい。

https://tsukuctf.sechack365.com/problems/digits?q=0_34567890 にアクセス。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e39973a4-f622-1376-2adf-5c03faa90beb.png)

できた。
VirtualBox Extension Pack をコマンドライン (CLI) からインストール＆アップデートする

VirtualBox を使用するときによく使うアドオン VirtualBox Extension Pack ですが、このアドオンの追加インストール面倒じゃないですか？
また、バージョンアップ時によく忘れていたりしませんか？

EULA は毎回同意していますので、これもコマンドラインからまとめてインストールさせてほしいものです。

実は VBoxManage コマンドに Extension Pack をインストールするコマンドがあります。
今回はこれを利用してコマンドからインストール＆アップデートを行います。

## 前提条件

ざっくり2つです｡

### 1. VirtualBox がインストール済みである

これは Scoop なり、Chocolatey なり、winget なりでコマンドラインからインストールしましょう。

おすすめは Scoop でのインストールです。

```powershell:PowerShell
scoop add bucket nonportable
scoop install virtualbox-np
```

VirtualBox 本体のコマンドラインからのインストール方法はすでに確立されていますので、解説は他に任せます。
また、BIOS で VT-x が有効になっているかなどの初歩的トラップの解説も他に任せます。
今回の本質とはかけ離れますので。

### 2. `VBoxManage` にパスが通っている

`VBoxManage -v` と入力して、バージョン情報が返ってくれば OK です。
エラーの場合は、VirtualBox インストールフォルダに移動して作業してみてください。
デフォルトでは下記パスに移動すれば、パスが通っていなくても OK です。

```powershell:PowerShell
cd "C:\Program Files\Oracle\VirtualBox"
VBoxManage -v
```

> Scoop で VirtualBox をインストールしていれば、パスは自動で設定してくれます。
> Scoop 最高！

## コマンド

下記7行です。一気にコピペして実行できます。
途中、ユーザーアカウント制御が表示されますのでご注意ください。

```powershell:PowerShell
$ver = VBoxManage -v
$ver = $ver.Remove( $ver.IndexOf("r") )
Invoke-WebRequest -Uri "https://download.virtualbox.org/virtualbox/${ver}/Oracle_VM_VirtualBox_Extension_Pack-${ver}.vbox-extpack" -OutFile Oracle_VM_VirtualBox_Extension_Pack.vbox-extpack -UseBasicParsing
echo y | VBoxManage extpack install --replace Oracle_VM_VirtualBox_Extension_Pack.vbox-extpack
rm Oracle_VM_VirtualBox_Extension_Pack.vbox-extpack
VBoxManage extpack cleanup
Remove-Variable ver
```

ざっくり解説すると、ver という変数に現在の VirtualBox のバージョンを取得させ､それに対応した Extension Pack をダウンロードしてインストール(アップデート)させているだけです。

## 感想

実は scoop でインストールできる `virtualbox-with-extension-pack-np` だと、Extension Pack も合わせてインストールしてくれるのですが、この Extension Pack が古いバージョンのものがインストールされることが多いです。
いちいち Issue だすのもめんどくさいし、出したところで手動でアップデートしなきゃいけないし、ということで応用が効く手段を構築しておきたかったのでした。

ま、Docker 使う機会の方が多くなってきているんですけどね。。。

## 参考

公式ドキュメントより
Oracle VM VirtualBox User Manual
Chapter 8. VBoxManage
8.41. VBoxManage extpack
https://www.virtualbox.org/manual/ch08.html#vboxmanage-extpack
【AWS/EC2】mainから更新データをpullし、seed読み込み直す

#はじめに

awsのec2環境で、毎回データベースをリセットしseedを読み込み直す手順を忘れてしまうので記録。

#手順

###mainの変更を反映する場合

1.main環境をpullする

```ruby
git pull origin main
```

こちらはいつも通り。

2.該当の変更をした場合は、以下の該当処理を実行

- マイグレーションファイルを変更した場合

```ruby
bundle exec rails db:migrate RAILS_ENV=production
```

- Gemfileを変更した場合

```ruby
bundle install --path vendor/bundle --without test development
```

- CSS/JavaScript/画像(デザイン・レイアウト関係)の変更

```ruby
bundle exec rails assets:precompile RAILS_ENV=production
```

3.アプリケーションサーバ停止・起動

###データベースを削除する場合（シード読み込み直しを含む）

1.データベースを削除

```ruby
RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rails db:drop
```

2.データベース作成

```ruby
rails db:create RAILS_ENV=production
```

3.テーブル、カラム作成

```ruby
rails db:migrate RAILS_ENV=production
```

4.シード読み込み

```ruby
rails db:seed RAILS_ENV=production
```

5.アプリケーションサーバ停止・起動

どちらも、アプリケーションサーバーを起動し直すことを忘れないように！

#終わりに

基本的な手順を留めておきます。
HerokuへDjangoをデプロイするときにApplication Errorになる場合

# 概要
ローカル環境でDjangoアプリを作成して、正常に動くことを確認。
Herokuへデプロイするために設定をして、デプロイが完了し、作成されたURLを開くと`Application Error`と表示される。
`heroku logs --tail`でログを確認すると下記の表示。

```
heroku[router]: at=error code=H14 desc="No web processes running"
```

このような場合に確認することとその改善点は下記のとおり。

## 確認ポイント
`heroku ps`でWebサーバーが動いているか確認。
下記の表示だとWebサーバーがない状態なので、Application Errorになる。

```zsh
$ heroku ps
Free dyno hours quota remaining this month: 1000h 0m (100%)
Free dyno usage for this app: 0h 0m (0%)
For more information on dyno sleeping and how to upgrade, see:
https://devcenter.heroku.com/articles/dyno-sleeping

No dynos on ⬢ あなたが命名したアプリ名
```

正常に動いていれば下記の表示になる。

```zsh
$ heroku ps
Free dyno hours quota remaining this month: 1000h 0m (100%)
Free dyno usage for this app: 0h 0m (0%)
For more information on dyno sleeping and how to upgrade, see:
https://devcenter.heroku.com/articles/dyno-sleeping

=== web (Free): gunicorn あなたが命名したDjangoプロジェクト名.wsgi --log-file - (1)
web.1: up 2021/09/23 22:32:59 +0900 (~ 16s ago)
```

## 改善方法
原因はHeroku用の`Procfile`を`procfile`で誤って作成してデプロイしてしまったこと。
誤りに気付いて単純に存在する`procfile`のファイル名を`Procfile`に変更して再度デプロイしたが、状況は変わらず。
ファイル名を`procfile`へもとに戻してgitから削除。

```zsh
$ git rm procfile -f
```

新たに`Procfile`を作成してデプロイしたところ正常に稼働し、サイトが表示された。
TypeScriptのArray.includesが配列の要素と異なる型の値を受け取れるようにする

## Array.includesが配列の要素と異なる型の値を受け取るとコンパイルエラーが起こる
今回困ったのは以下のような状況で起きたコンパイルエラーです。 

```typescript
// Union型を使った列挙
const SEARCH_PARAM = {
  p1: "パラメータ1",
  p2: "パラメータ2",
  p3: "パラメータ3",
} as const;
type TSearchParam =  typeof SEARCH_PARAM[keyof typeof SEARCH_PARAM];

// TSearchParam[]型のincludesメソッドに文字列を渡す
const arr: TSearchParam[] = [SEARCH_PARAM.p1, SEARCH_PARAM.p2];
let value: string = "hello";
arr.includes(value);

// すると、以下のコンパイルエラーが起こる
// Argument of type 'string' is not assignable to parameter of type 'TSearchParam'.(2345)
```

「TSearchParamを引数として受け取るのでstring型は受け付けないよ」というエラーですね。
ちなみに、```SEARCH_PARAM ```と```TSearchParam ``` はEnum型の代わりにUnion型で列挙型を表現する方法[^1]です。
JSではincludesメソッドに何を渡してもbooleanが返って来るので楽でしたが、TSの場合引数に型チェックが入ってしまいます。
Array\<TSearchParam>.includesなら文字列を受け取れるだろうと想定していたのでちょっと悲しかったです。


## エラーの原因
Array.includesの定義を確認すると、以下[^2]のようになっていました。

```typescript
interface Array<T> {
    includes(searchElement: T, fromIndex?: number): boolean;
}
```
つまり、includesメソッドの引数は**配列の要素と同じ型、もしくはそのサブタイプのみしか受け付けない**ようです。

## 今回の対処法
配列を**any[]型にキャスト**して、includesメソッドがどんな引数でも受け取れるようにしました。
これでどんな値を受け取ってもコンパイルエラーが起きず、配列に同じ値が含まれるときのみtrueが返り、それ以外の場合にfalseが返ります。
できるだけキャストしたくなかったですが他に思いつかなかったのでこれで対応。

```typescript
// TSearchParam[]型のincludesメソッドに文字列を渡す
const arr: TSearchParam[] = [SEARCH_PARAM.p1, SEARCH_PARAM.p2];
let value: string = "hello";
(arr as any).includes(value);
```


## おまけ
私と同じようにArray.includesはどんな型でも受け取れるようにしてほしいと思う人がいたようで、GitHubでこんな定義だと嬉しいよねという投稿[^3]がありました。
ある配列のincludesの引数に渡した値の型が、要素の型orそのサブタイプであればbooleanを返し、それ以外の型の場合はfalseを返すという定義です。

```typescript
interface Array<T> {
    includes<U>(searchElement: U, fromIndex?: number): U extends T ? boolean : false;
}
```


[^1]: [Lineさん](https://engineering.linecorp.com/ja/blog/typescript-enum-tree-shaking/)や[kabukuさん](https://www.kabuku.co.jp/developers/good-bye-typescript-enum)のブログで紹介されている方法です。
[^2]: [Array.includesの定義(GitHub TypeSc)](https://github.com/microsoft/TypeScript/blob/4c0a51e14b67460b47bdcebea6b70270a83a243e/lib/lib.es2016.array.include.d.ts#L21-L28)
[^3]: [Array.includesはどんな型でも受け取れるようにしてほしいという投稿(stackoverflow)](https://github.com/microsoft/TypeScript/issues/26255#issuecomment-458013731)
大谷翔平選手は９勝だけど、もうすでに二桁以上勝利しています。

次のＣプログラムを実行してください。
大谷翔平選手は9勝だけど、もうすでに二桁以上勝利しています。

```c
#include	<stdio.h>
#define		SYOURISUU	(9)			// 2021年度の勝利数は9勝
#define		HUTAKETA	(010)		// 2桁
int main(void)
{
	printf("大谷翔平選手の勝利数は0%oです。\n", SYOURISUU);
	if (SYOURISUU >= HUTAKETA) {
		printf("勝利数は二桁以上です。\n");
	}
	return 0;
} 
```
XCodeでNo such module 'XXXXX'に詰まった時の対処法

・XCodeで既にpodまわりの再インストールなどを試した。
・しかし、どの手法を試しても同じエラーが出続けてビルドできない。
・各種ライブラリのインストールは確認済み
自分の場合はFirebase関連モジュールのエラーが沢山出て、てっきりFirebaseモジュールの原因？と勘違いしたが、バージョン情報をググっても特段エラーの報告は見つけられない。

# TL;DR

プロジェクトを開くときに間違ってxcodeprojを開いていたのが原因でした。

```:ダメな例
open bar.xcodeproj
```

開くプロジェクトの名前をしっかり確認しましょう。

```:正しい例
open bar.xcworkspace
```

灯台下暗しですね。。。
deviseについて①

自分用としてのメモを残します

---

####1 Gemfileに  gem 'devise'  を記述
→ $ bundle install

次にインストールしたdeviseをセットアップ
→ $ rails g devise:install

これでdeviseを使う準備が整いました。

---

####2 ユーザーのテーブルを作成する
とりあえずUserでモデルを作るとします
→ $ rails g devise User

マイグレーションファイルを確認してみるとデフォルトでまあいろいろと 
書かれていますがpasswordやemail等必要であれば自分で記述していく

######例えば、機能として住所を入れたいと思ったときは、
→ string型のaddressカラムを作成... t.string :address を追加！

追加が終わったら... 
「　$ rails db:migrate　」これは絶対に忘れないようにしよう！！！！

---　
1. config/routes.rb を確認してみると　devise_for :users　が自動生成せれてるよ

2. app/models/user.rb を確認してみると　　　　　　　　　　
　　　　 　devise :database_authenticatable, :registerable,　:recoverable, 　　　:rememberable, :validatable　　　　　　　　　　　　
:database_authenticatable（パスワードの正確性を検証）　　　　　
:registerable（ユーザ登録や編集、削除）　　　　　　　　　　　　
:recoverable（パスワードをリセット）　　　　　　　　　　　
:rememberable（ログイン情報を保存）　　　　　　　　　　　　　
:validatable（emailのフォーマットなどのバリデーション）

---

####3 deviseの設定をする
初期設定ではemailとpasswordが設定されているので追加したい場合はここでいじります。
app/controllers/application_controller.rb　内に

before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:＠＠＠])
  end
＊＠はカラム名を設定してください

　
viewを弄りたい場合には
→ $ rails g devise:views　を実行
ログイン画面、登録画面をそれぞれ変更箇所を変える
（form_forが使用せれているがform_with model: @... と変えておこう）


とりあえず導入から初期設定まで... また管理者機能についてもかなり難航したのでかけたらいいなと思います。
Flutterでの開発でAPIKeyを隠してGithubにあげる方法

チーム開発をするときなどに、自分のコードをGithubなどにあげたい！→でもAPIKeyを隠さないと...というときがあると思います。そうした時に、これが最も手っ取り早くAPIKeyを隠す方法だと思ったので共有します。
※私が作っていたアプリが地図系なので、APIKeyの名前もそんな感じになってますが、お構いなく好きに名前つけてもらって大丈夫です()
#Android
##基本的な設定
https://www.entwicklernotizen.de/blog/how-to-handle-secret-api-keys-in-flutter-for-android-and-i-os/
```android/app/src/main/AndroidManifest.xml```へのAPIKeyの書き込みについてはこれを参考にしてください。ここから先のコードは、```your_api_key```という文字列を自分のAPIKeyに書き換えて使用してください。

```dart:android/local.properties
...
MAPS_API_KEY=your_api_key//これを追加
```
```xml:AndroidManifest.xml
<manifest...
  <application...
    <meta-data...
      android:name="com.google.android.geo.API_KEY"
      android:value="${MAPS_API_KEY}"
    />
    ...
  />
  ...
/>
```

#lib/main.dartへの書き出し
libディレクトリ配下のファイルへの書き出しについては、lib配下にファイルを作ってそれをimportすることによって書き出しを行います。ファイル名は```apikey.dart```とします。

```dart:apikey.dart
String api_key = "your_api_key";
```
```dart:main.dart
...
import 'apikey.dart' //apikey.dartファイルをimport
//これで、main.dart内でapi_keyが呼び出し可能になる
String APIKey = api_key
...
```

main.dart以外でも、lib配下のファイルであればやり方は同じです。その後に、プロジェクトファイル直下の```.gitignore```ファイルに```apikey.dart```を追加してください。

```c:.gitignore
apikey.dart
...
```

#iOS
同様に、```ios/Runner```ディレクトリ配下にAPIKeyを格納するファイルを作ります。ここではファイル名は```apikey.h```とします。同じく```ios/Runner```配下にある```AppDelegate.m```へ書き出します。

```cpp:apikey.h
NSString *maps_api_key = @"your_api_key";
```
```cpp:AppDelegate.m
...
import "apikey.h"//これを追加

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [GMSServices provideAPIKey:maps_api_key];//ここにapikey.hで定義したmaps_api_keyを追加
  [GeneratedPluginRegistrant registerWithRegistry:self];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end
```
そして、同様にプロジェクト直下の```.gitignore```に```apikey.h```を追加します。

```c:.gitignore
apikey.dart
apikey.h
...
```

Swiftを使っている場合どうなるのかはちょっと謎です...が、他サイトに結構乗っていたので今回は割愛します。

#最後に
Qiitaにはいつも助けられているので、少しでも皆さんのお役に立てば幸いです！
ただこの辺のことはちゃんと理解しているわけではないので、変なことを言っていれば知らせていただけると助かります()
Template Method (継承)の採用可否基準


|関連記事のトップページ|
|:--|
|[[シリーズ] Python におけるデザインパターンの記録](https://qiita.com/robozushi10/items/3c1c0d1b1fbf7b38a33b)|

## 概要

基底クラスを継承をした構造 (Template Method) の「採用可否の基準」と「実装例」.
引用元は下記書籍である.

ただし、内容について細かく記すと書籍の無断転載になるので大まかに記している.
また、コードは Ruby から Python に書き換えている.

|引用元情報|一言|
|:--|:--|
|[書籍 -- Rubyによるデザインパターン (Russ Olsen 著)](https://www.amazon.co.jp/Ruby%E3%81%AB%E3%82%88%E3%82%8B%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Russ-Olsen/dp/4894712857)|[原書(英文)](https://www.amazon.com/gp/product/0321490452/ref=as_li_ss_tl?ie=UTF8&tag=eloqruby-20&linkCode=as2&camp=217145&creative=399349&creativeASIN=0321490452)|
|[GitHub -- 著者 Russ Olsen 氏](https://github.com/russolsen/design_patterns_in_ruby_code/tree/master/01)||


## 採用の基準

ここは独断もしくは私の解釈です.

採用基準は次を満すこと.
・**基底クラスの仕様がルーチンレベルまで確定していること**

言い換えると次である.
・**FactoryMethod 以上に基底クラスの大半を継承できる状態にあること**


## 個人的感想

~~Template Method が適用できるほど綺麗に設計する自信が無いので、ほとんど使用したことが無い.~~
~~普段は、もう少し "緩い" Factory Method を使用している.~~

~~私としては、相当枯れた処理に対するリファクタリング用途にしか Template Method が適用できない...~~

~~書籍で頻繁に目にする「文字列を HTML や XML, PlainText で装飾して出力する」ような~~
~~簡単な実装は業務では遭遇しない. (最初はこのような要求でも、後から機能拡張要求が来てしまう)~~

追記

リファクタリングを実施した際に、親・子クラスを作ったことで、
結果的に Template Method が実現できていることは多々あった.

下記より、どうやらリファクタリングの過程で Template Method を実現することは妥当な模様.

:::note info
『<a href="https://www.amazon.co.jp/Ruby%E3%81%AB%E3%82%88%E3%82%8B%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Russ-Olsen/dp/4894712857">Rubyによるデザインパターン (Russ Olsen 著)</a>』 を見たところ、
「<b>TemplateMethod パターンはリファクタリングさせながら完成させれば良い</b> 」
といった旨の記載があった.
:::


## コード例

過去に次のような「検査」処理を実装してみたが、共通部の実装が難しく苦戦した.

```python
from abc import ABCMeta, abstractmethod

class Inspector:
  @abstractmethod
  def __init__(self):
    「初期化」処理は具象クラスごとに異なる.

  def prepare(self, *args, **kwargs):
    全ての具象クラスで使用できる共通の「準備」処理.

  @abstractmethod
  def execute(self, *args, **kwargs):
    具象クラスごとに異なる「検査」処理.

  def reflect(self, *args, **kwargs):
    全ての具象クラスで使用できる共通の「結果記入」処理.
```


以上.
tmux でサーバ上でバッチ処理を実行する、そしてそのログファイルをローカルに落とす

個人的メモ。rails のバッチ処理の場合を想定。

## 手順

リモートサーバーにssh接続する。

```sh
$ kubectl exec -it <Pod名> /bin/bash
```


```sh
$ apt-get update
$ apt-get install tmux

$ tmux new -s <session名>

# ログを書く出す前に、tmux-logging pluginをinstall
$ mkdir /temp && cd /temp
$ git clone https://github.com/tmux-plugins/tmux-logging ~/temp
$ echo 'run-shell ~/temp/logging.tmux' >> /root/.tmux.conf
$ tmux source-file /root/.tmux.conf

<ctr + b, P> # Started logging to /root/xxxxxx.log と表示される。このファイル名をメモ。
 
# railsディレクトリへ移動。
$ cd /app
$ bundle exec rails runner lib/batch/batch.rb

# ctr + w でターミナルを閉じてOK!
```

バッチ処理終了後にコンテナからローカルにファイルコピーする。

```sh
$ kubectl cp <Pod名>:/root/xxxxxx.log ./local_file.log
```


## Ref

- https://www.wantedly.com/companies/wantedly/post_articles/318542
M5Stack ATOM Matrix + UiFLOWでI2C

M5Stack ATOM Matrix + UiFLOW（つまり，MicroPython）でI2Cを扱うにはどうするか，なかなかわからなかった。Blocklyでも動く（`import i2c_bus`という方式）のだが，Writeできるのは1/2/4バイトの整数1個だけのようだ。
結論，MicroPythonの [Quick reference for the ESP32](https://docs.micropython.org/en/v1.10/esp32/quickref.html) というページでわかった。

```
i2c = I2C(scl=Pin(21), sda=Pin(25), freq=100000)
i2c.writeto(slave_addr, buf)
i2c.readfrom(slave_addr, 4)
```

といったコードだ。

ところで，UiFlow（M5FLOW？）でSaveしてもSaveされるのはBlocklyだけで，手で書いたPythonコードはSaveされないことが判明。ええ？エディタに Copy & Paste してコードとして保存。
TsukuCTF 2021 - logonly 100 

#問題

https://tsukuctf.sechack365.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f2f071d0-c987-067f-2140-ec77c802df75.png)

#解いてみた

添付ファイルをダウンロードして中身を見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f32f9323-dbfd-2795-4a65-9afbdf6255c3.png)

こんな感じでログイン失敗したログが大量にあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/10359829-27d8-62d8-d37f-b9430ab9c37a.png)

一番下を見てみます。
最後だけログイン成功してそうですね。
1秒進んでるだけで他は見た感じ一緒っぽい。

はて？それだけでどうすれば？
問題文からSuginaくんはブルートフォースしたと仮定すると214154番目の文字列で成功したということでしょうか。
Kaliに入っているパスワードリストを調べます。

Kali Linux 2021.1でパスワード侵入テストのためのパスワード辞書（リスト）を確認する
https://ethicalhacking.hatenablog.com/entry/checking-the-password-dictionary-for-password-penetration-testing-in-kali-linux-2021-1/

このサイトを見ると

```
/usr/share/wordlists/rockyou.txt.gz
```

というファイルがあって、このファイルがリストだそうです。
kali持ってないのでネットで「rockyou.txt.gz」で検索します。
適当にファイルが出てきたのでそれをダウンロードします。

ファイルを開いて214154番目を入力してみたところ正解でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/1dc2dddb-87ba-7752-8c73-a22601ad41c3.png)
Playgroundで画面描画する方法

# 概要
XcodeのPlaygroundで画面表示する方法です。

## 実行環境
- Apple Swift version 5.4
- Xcode 12.5

# 方法

`UIKit`,`XCPlayground`,`PlaygroundSupport`をインポートして、表示したいViewControllerを`PlaygroundPage.current.liveView`に代入する。

以下のコードを貼り付けると動きます。

## コード

```swift:MyPlayground.playground
import UIKit
import XCPlayground
import PlaygroundSupport

class ViewController: UIViewController{
    
    let label = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.frame = CGRect(x: 0, y: 0, width: 375, height: 667)
        self.label.text = "label"
        self.label.frame = CGRect(x:0, y:300, width:370, height:30)
        self.label.textAlignment = NSTextAlignment.center
        self.view.addSubview(label)
    }
}

PlaygroundPage.current.liveView = ViewController()
```

## 表示
![スクリーンショット 2021-09-23 22.16.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031614/ca9909d9-a06f-2edb-ec5e-b15d7f0f6e17.png)


# おわりに
簡単なテストに是非。
sshを初めて使う：sshキー作成からリモートログインまで

初めてsshを使って他のPCでリモート作業をする際に手こずってしまったので、まとめます！
(詳細は理解していなくて、)とりあえず使えるところまで。

この記事で目指すところ
---
sshとは通信される側とする側で、安全に通信を行うためのプロトコル。

クライアントの公開鍵を、サーバに事前に教えておくことで、リモートログインを認証してもらうのが目標です。
サーバとクライアント両方でやることがあるので、どちらがどちらか混同しないようにお気をつけくださいませ。
接続元-->クライアント
接続先-->サーバ

私はUbuntu18.04とMacOSを使って通信させました。
どちらも同じ設定方法で、双方向の通信を確認しています。

sshキー公開鍵の作成【クライアント側】
--
sshキーを作成します。

```
$  cd ~/.ssh
$  ssh-keygen
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):パスフレーズを入力（入力しないと無しになる)
Enter same passphrase again: パスフレーズを再入力
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
```

これで秘密鍵と公開鍵ができました。確認すると、

```
$  ls
id_rsa  id_rsa.pub
```

id_rsa.pub　が公開鍵、　id_rsa が秘密鍵です。
今回は公開鍵を使います。秘密鍵は誰にも教えないようにしてください！

続いて、id_rsa.pubの中身をサーバ側に丸々教える必要があります。
ファイルをそのままメールで添付、などしてサーバPCに送ってください。
※間違えて秘密鍵を送らないように注意！

sshキーの公開鍵を認証する【サーバ側】
---
authorized_keysファイルにクライアントの公開鍵を配置します。

まずは、authorized_keysファイルを作成し、公開鍵(id_rsa.pubの中身)を保存していきます。
以下のようにファイルを開いて、コピペして保存します。

```
$  gedit ~/.ssh/authorized_keys
```

続いて、authorized_keysに権限を与えてください。
これで認証完了です！

```
$  chmod 600 ~/.ssh/authorized_keys
```

ホスト名とIPアドレスを調べる【サーバ側】
---
接続したいホスト名とIPアドレスを調べましょう。

```
$  hostname
xxxx.local
$  ifconfig
```

ifconfigでずらずら〜っと出てきまして、inetに続く、　「198.168.xxx.x」がIPアドレスです。
また、ログイン時にユーザ名も必要となるので、確認してください。(PCの普段使っているログイン名)


ログインする【クライアント側】
---

以下のどちらでもログインできます！

```
$  ssh ユーザ名＠ホスト名
$  ssh ユーザ名＠IPアドレス
```

パスワードを聞かれたら、サーバ側で設定したパスフレーズを入力してください。
これで、サーバ側のhomeディレクトリにて作業ができるはずです！


毎回ホスト名やIPアドレスを打つのが面倒なら・・【クライアント側】
---
configファイルにログイン情報を書き込んで保存しておくことができます！

```
$  gedit ~/.ssh/config
```
以下のように内容を書き込みます。
>Host hoge #好きな名前
	User ユーザ名
	HostName ホスト名
	ForwardAgent yes

すると、以下コマンドでログイン可能になって簡単！

```
$  ssh hoge
```
サードパーティークッキー（3rd Party Cookie）の廃止

Googleが、Google Chromeで「サードパーティークッキー（3rd Party Cookie）」のサポートを2022年までに段階的に廃止する予定であると発表した。

Appleは、Safariで既にサードパーティークッキーを禁止（ブロック）している。他のWebブラウザもおおむねサードパーティークッキーを禁止する方向にあるようだ。

このため、アドテクノロジー（アドテク）業界は大きなダメージを受けると思われる。




###参考サイト
https://atmarkit.itmedia.co.jp/ait/articles/2105/10/news018.html

https://www.innovation.co.jp/urumo/adtechnology/

https://satori.marketing/marketing-blog/ad-technology/advertisement/

https://gigazine.net/news/20210623-google-antitrust-cookie-technology/
【Laravel】中間テーブルの値をDateTime型で取得したい

## 目的
多対多のモデルがあり、中間テーブルにはDatetime型のフィールドがあるとします。
たとえば下記のように、ユーザーが複数のスクールに通っており、それぞれのスクールを開始した日時をもっているとき、
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995792/0ff91b81-fccc-ae0f-72e2-bd16cae0e749.png)

開始日時をDateTimeで取得し、format()などのメソッドをそのまま使いたいときのモデル定義はどうすればいいかについて、覚書を残します。

```php
foreach($user->schools as $school){
 echo $school->pivot->start_at->format('Y年m月d日'); // Datetimeにキャストされた状態で値を取得したい
}
```

## 結論
カスタム中間テーブルモデルを定義し、そこに日付ミューテタを追加します。

## 手順

### 1. カスタム中間テーブルを作成する
中間テーブル自体のオリジナルモデルを定義して使用することができます。
Pivotを継承することを忘れないようにしましょう。

SchoolUser.php

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot; 

class SchoolUser extends Pivot　// Pivotを継承する
{
    //
}
```

### 2. 日付ミューテタの設定
Eloquentでは、`$dates`プロパティをセットすることにより、属性値をCarbon（DateTimeの拡張クラス）インスタンスとして取得することができます。
ちなみに、タイムスタンプ（created_atとupdated_at）は自動的にキャストされるようになっています。


```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class SchoolUser extends Pivot
{
    protected $dates = ['start_at']; // 日付ミューテタの設定
}
```

### 3. リレーションの設定
おなじみ、各モデルで多対多のリレーションをbelongsToManyで設定します。
このとき、`using`メソッドを呼び出すことで、カスタム中間テーブルモデルを使用することができます。

User.php

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 役目を所有するユーザー
     */
    public function school()
    {
        return $this->belongsToMany('App\School')
                        ->using('App\SchoolUser') // カスタム中間テーブルの使用
                        ->withPivot([
                            'start_at',
                        ]);
    }
}
```

以上。

## 参考
<a href="https://readouble.com/laravel/7.x/ja/eloquent-relationships.html">Laravel 7.x Eloquent：リレーション　</a>
<a href="https://readouble.com/laravel/7.x/ja/eloquent-mutators.html">Laravel 7.x Eloquent：ミューテタ　</a>
Dockerコマンドどこまで短く出来る？

Dockerのコンテナ指定のために毎回長いコンテナ名を打つのはだるい


# 結論

識別子はハッシュ先頭2文字だけで良いみたい

```shell
$ docker run -d ubuntu sleep 600
0a800a0d3a084ad4ca9c76a5efdc69634c025a8a86a0a1374e862f50fea306b1

$ docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
0a800a0d3a08   ubuntu    "sleep 600"   7 seconds ago   Up 4 seconds             xenodochial_boyd

$ docker exec -it 0a bash
root@0a800a0d3a08:/#

$ docker stop 0a
0a
```

execの方がよく使うかも

# 参考

https://techblog.recochoku.jp/6815

gitのコミットハッシュは4文字まで短く出来るらしい
[Unity] ループしていない環境音をクロスフェードしてループにする

...というアセットの販売を開始しました。
[AmbientLooper](https://assetstore.unity.com/packages/tools/audio/ambientlooper-203078)

それに含まれるスクリプトの一部を改変して公開します。
ループ音にしたいAudioSourceがあるオブジェクトに下記スクリプトをアタッチするだけでノンループの環境音がループ音になります。
[動画](https://youtu.be/VyvispRoKKY)

長い環境音などは比較的時間もかかるので、その場合は[AmbientLooper](https://assetstore.unity.com/packages/tools/audio/ambientlooper-203078)でwav化して使用するのがオススメです。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(AudioSource))]
public class CrossFadeLoop : MonoBehaviour
{
    [Tooltip("cross fade dulation[sec]"), Range(0.1f, 5f)] public float m_crossFadeTime = 1f;

    void Start()
    {
        AudioSource audioSrc = gameObject.GetComponent<AudioSource>();
        AudioClip ac = audioSrc.clip;
        float[] data = new float[ac.samples * ac.channels];
        ac.GetData(data, 0);
        int span = Mathf.FloorToInt(m_crossFadeTime * (float)(ac.frequency * ac.channels));
        span -= (span % ac.channels);
        float[] newData = CrossFade(data, span);
        AudioClip newAc = AudioClip.Create("_loop_" + ac.name, newData.Length / ac.channels, ac.channels, ac.frequency, false);
        newAc.SetData(newData, 0);
        audioSrc.clip = newAc;
        if (audioSrc.playOnAwake)
            audioSrc.Play();
    }

    static public float[] CrossFade(float[] data, int span)
    {
        if (data.Length < span * 2)
            return data;

        float[] retData = new float[data.Length - span];
        for (int i = 0; i < span; ++i)
        {
            float rate = (float)(i + 1) / (float)(span + 1);
            retData[i] = data[i] * rate + data[data.Length - span + i] * (1f - rate);
        }
        for (int i = span; i < data.Length - span; ++i)
            retData[i] = data[i];

        return retData;
    }
}
```
具体的な操作としては、自分自身をクロスフェードして頭とおしりをつないでいます。

![AmbLooper.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/0bc459b4-5fdf-5a88-0bc5-67a8d1e7b6b7.png)

まずは

```
        float[] data = new float[ac.samples * ac.channels];
        ac.GetData(data, 0);
```
でclipのデータを取得します。クリップのサイズはサンプル数xチャンネル数で決まります。

次に

```
        int span = Mathf.FloorToInt(m_crossFadeTime * (float)(ac.frequency * ac.channels));
        span -= (span % ac.channels);
```
でクロスフェードさせる時間分のデータ長を設定します。
計算で求めたspanだけでは偶数/奇数になる可能性があり、
チャンネル数が2でspanが奇数だと左右逆のチャンネルのデータをフェードして繋いでしまうことになり、音の定位変化やプチノイズの原因になるため、spanをチャンネル数で割り切れる数に調整します。

あとは

```
        float[] newData = CrossFade(data, span);
```
でデータをクロスフェードさせます。出力されるデータサイズはクロスフェードの分だけ小さくなります。

```
        float[] retData = new float[data.Length - span];
```

新しく作ったAudioClipにデータを読み込ませ、AudioSourceにセットします。

```
        newAc.SetData(newData, 0);
        audioSrc.clip = newAc;
```

AudioSourceに新しいclipを読み込ませると鳴っていた音が止まってしまうので、
音が鳴っていた（PlayOnAwakeがオンになっていた）場合はPlayします

```
        if (audioSrc.playOnAwake)
            audioSrc.Play();
```
Ubuntu 日本語入力 切り替え設定 mozc

# 概要
Ubuntuの日本語入力の設定を一瞬で終わらせるための備忘録

## 手順
1. 以下コマンドを叩く
```
sudo apt install ibus-mozc && sudo reboot 
```
2. 設定 > 地域と言語 で入力ソースに「日本語(Mozc)」を追加
3. 「日本語(Mozc)」の歯車マークをクリック
4. Mozc Settings > Keymap style > Customize
5. 「IMEを有効化」, 「IMEを無効化」のキーマッピングを好きなKeyに設定する

## 手順5の詳細
* デフォルトでマッピングされている「IMEを有効化」, 「IMEを無効化」の項目を削除する・
* 「Ctrl Space」がデフォルトでは「全角スペース入力」としてマッピングされていたので、その項目も削除。

* 新しい項目を追加して、下図のように設定する。
今回はCtrl+Spaceで切り替えするように設定。

![Screenshot from 2021-09-23 21-37-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270423/2de7f88e-18cd-9bc3-4036-a8baaf092759.png)
【React】ロゴの周りを回転するテキストを実装する（CSS in JS）

<!-- =================================================== -->
# 概要
<!-- =================================================== -->
ロゴ画像の周りを回転するテキストを実装します。
CSS in JSとして、[**emotion/css**](https://emotion.sh/docs/@emotion/css)を使用します。

![output(video-cutter-js.com) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/738a5953-d359-0367-78db-d6c7888aec2a.gif)
[> ウールーについて](https://zukan.pokemon.co.jp/detail/831)

:::note info
本記事は、以下の動画をReactに変換したものです。（ほぼ写経です）
:::

https://youtu.be/zwl3kZPZ8H8

<!-- =================================================== -->
# 実装
<!-- =================================================== -->
```.tsx
import React, { VFC } from 'react';
import { css, keyframes } from '@emotion/css';

export const CircleTextLogo: VFC = () => {
	const text = 'No.831 ウールー - 分類：ひつじポケモン - 特性：もふもふ・にげあし'

	return (
		<div className={styles.circle}>
			<div className={styles.logo}></div>
			<div className={styles.text}>
				{text.split('').map((char, i) => (
					<span key={i} className={styles.char(i * 9)}>
						{char}
					</span>
				))}
			</div>
		</div>
	)
}

const animations = {
	rotateText: keyframes`
    0% {
      transform: rotate(360deg);
    }
    100% {
      transform: rotate(0deg);
    }
  `
}

const sizePx = 300

const styles = {
	circle: css`
		position: relative;
		width: ${sizePx}px;
		height: ${sizePx}px;
		border-radius: 50%;
		display: flex;
		justify-content: center;
		align-items: center;
	`,
	logo: css`
		position: absolute;
		width: ${sizePx - 50}px;
		height: ${sizePx - 50}px;
		background-image: url('/assets/u-ru-.png');
		background-size: cover;
		border-radius: 50%;
	`,
	text: css`
		font-family: Consolas;
		font-size: 1.3rem;
		color: #fcfafc;
		position: absolute;
		width: 100%;
		height: 100%;
		animation: ${animations.rotateText} 10s linear infinite;
	`,
	char: (rotateDeg: number) => css`
		position: absolute;
		left: 50%;
		transform: rotate(${rotateDeg}deg);
		transform-origin: 0 ${sizePx / 2}px;
	`
}
```
:::note info
ポイントは、テキストを1文字ずつ分割して、それぞれを少しずつ回転させているところです。
:::
`styles.char(i * 9)`で、1文字を+9度ずつ回転させています。CSS in JSを使う理由は、このようにスタイルに動的な変数を取るためです。
文字の回転度数やサイズは、実際にブラウザで見ながら調整しています。
Webpackのお話

# はじめに
Railsでフロントの構築をする際今まではベストプラクティスがわからずとりあえずSPAを採用していたが、今回はSPAを用いないフロント構成をしようと思った。現在フロントの主流といったらReact,Vueだと思うがこれらをRailsで採用するにあたりWebpackerが必要になってくる。では、なぜWebpackを使わずWebpackerが必要なのか？そういった理由を深掘りしていくためにまずはWebpackについて調べていきたいと思う。

自分の考えをまとめるために疑問形式で深掘りしていきたいと思う。

# Webpackって何？
javascpritモジュールバンドラー

# モジュールの歴史
元々、javascriptにはファイル分割をしてまとめるという機能がなかった。しかし、javascriptの人気に伴いモジュール機能を加えようと動きが出てきた。そこに様々なモジュール仕様を定めたものが出てきた。
※javascriptでいうモジュールとは単に仕様のことを指す。
実際にモジュールを機能として使うためにはそれ用のツールが必要になる。

- CommonJS
- AMD
- ESModule(ECMAScript Module)

### CommonJS
Node.jsで採用されていて最初の誕生したモジュール仕様。Node.js環境では実行可能であるが、ブラウザでは実行できないため、Browserifyを利用してバンドリングする必要があった。

```javascript
// Import 
const sample = require('./sample.js'); 

// Export
module.exports = function example() {
    return "example"
}
```

### AMD
ブラウザでも動作できるようにする仕様。AMDという仕様に準拠したツールがRequireJSである。

### ESModule
ES6で策定された仕様。主要なブラウザで対応しているのでトランスパイルなどが不要。
現在で主流の仕様であり、Node.js v13.2.0でサポートが開始されている。

```javascript
// Import
import sample from "./sample.js"

// Export
export function example1(){
    return "example1"
}
```

ちなみにECMAScriptとはjavascriptの標準規格のこと。javascriptが誕生した初期では、ブラウザごとで独自に拡張を行っていたため、標準化するために作られた。

# モジュールバンドラーは何をするの？
上記の通りモジュール機能ツールが誕生したことによりファイル分割が可能になった。しかし、分割されたファイルをそのままブラウザに送るとファイル転送回数が多くなる。そこでモジュールバンドラーにより分割されたファイルを依存関係を解決しつつ１つのファイルにまとめることでファイル転送回数を増加を解決した。

※ファイル転送回数についてはHTTP/2の登場で解決され得る

モジュールバンドラーには主に３つある。

- Browserify
- rollup.js
- Webpack

### Browserify
CommonJSで書かれたjavascriptファイルをブラウザ用にバンドリングする。
CommonJSはブラウザでは機能しないのでjsファイルをまとめてから配信する。

### rollup.js
ES6に一旦変換することで静的解析できるようにした。
commonjsは標準ではサポートされていない

### Webpack
標準でCommonJSとES Moduleに対応している。
js以外にもcssなどの静的ファイルをバンドルする。

# モジュールバンドラーはファイルをまとめるだけ？
モダンなブラウザではES6に対応しているものがあるので、モジュールバンドラーはもはや必要ないのではないか？と思われるが現在のモジュールバンドラーは様々な機能を取り揃えている

- 複数に分割されたファイルを依存関係を解決してまとめる
- トランスパイル(babel)
- cssのプリプロセッサー(postcss, sass)
- linterでの構文チェック
- ファイルにprefixを付与
- js,cssファイルの圧縮

Webpackではこれらの機能を兼ね備えているため今後も重要なツールになっていくと思う。

# 


# 参考記事
ES6のexportについて　https://qiita.com/senou/items/a2f7a0f717d8aadabbf7
https://note.com/billion_dollars/n/n596fecfdeb2e
https://zenn.dev/arei/scraps/47abc4f7052ff7
lメソッドを用いた際のエラー解決：translation missing[Rails, I18n]

Railsの開発を進める中で、lメソッドを用いた際に、以下のようなエラーが発生したので、その原因と解決について記載したいと思います。
ちなみにI18nやlメソッドの詳しい利用方法に関しては、参考URLをご覧ください。

![スクリーンショット 2021-09-22 22.33.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779676/4b8e9121-a6cb-50f2-a0e0-3ea011a18388.png)

## 結論 ≒ 原因

このエラーの原因はlメソッドの引数である、`@user.created_at`のクラスが、`ActiveSupport::TimeWithZone`であるからです。

I18nを用いる場合、lメソッドを用いた際には、よしなに日本語化してくれます。（application.rbなどを正しく設定できていれば）
しかしlメソッドの引数を翻訳するルールが、今回のエラーに大きく関係しているおり、
lメソッドを用いた場合、

**Dateクラスのインスタンス**は**`ja.date.formats`配下のフォーマット**を、
**Timeクラスのインスタンス**は**`ja.time.formats`配下のフォーマット**を、

それぞれ自動的に探しに行く仕様になっています。（恐らく

なので今回のエラーは、`l @user.created_at, format: :ja_ymd`の、
引数が`ActiveSupport::TimeWithZone`クラスなので、Railsが`ja.time.formats`配下を探しに行ったところ、
**`ja_ymd`フォーマットが定義されていなかったこと**が原因となります。

## 該当コード

```yaml:config/locales/views/ja.yml（エラー発生時
ja:
  date:
    formats:
      ja_ymd: ! '%Y年%m月%d日' # ここを自動的に呼び出してくれると期待していた。
      ja_md: ! '%m月%d日'
      ja_ym: ! '%Y年%m月'
      hyphen: ! '%Y-%m-%d'
      wday: '(%a)'
  time:
    formats:
      ja_ymdhm: ! '%Y年%m月%d日 %H時%M分'
      hm: ! '%H:%M'
      ja_hm: ! '%H時%M分'
      ymdhm: ! '%Y/%m/%d %H:%M'
      mdhm: ! '%m/%d %H:%M'
      dot_ymd: ! '%Y.%m.%d'
```

```ruby:config/application.rb
class Application < Rails::Application
  I18n.enforce_available_locales = true
  config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
  config.i18n.available_locales = :ja
  config.i18n.default_locale = :ja
end
```

```html:app/views/users/show.html.erb
<td>
  <%= l @user.created_at, format: :ja_ymd %>  # ここでエラー発生        なぜならja.time.formats配下にja_ymdが定義されていないから。
  <%= l @user.created_at, format: :ja_hm %>   # ここはエラーが発生しない なぜならja.time.formats配下にja_hmが定義されているから。
</td>
```

## コンソールで確認

```shell:コンソール
[2] pry(main)> @user.created_at.class
=> ActiveSupport::TimeWithZone
[3] pry(main)> I18n.l(Date.today, format: :ja_ymd)
=> "2021年09月22日"
[4] pry(main)> Date.today.class
=> Date
[5] pry(main)> I18n.l(Time.now, format: :ja_ymd) # エラー発生
I18n::MissingTranslationData: translation missing: ja.time.formats.ja_ymd
from /usr/local/bundle/gems/i18n-1.8.10/lib/i18n.rb:374:in `handle_exception`
[6] pry(main)> Time.now.class 
=> Time # なぜならTimeクラスだから
```

## 解決策

```yaml:config/locales/views/ja.yml（修正
ja:
  date:
    formats:
      ja_ymd: ! '%Y年%m月%d日'
      ja_md: ! '%m月%d日'
      ja_ym: ! '%Y年%m月'
      hyphen: ! '%Y-%m-%d'
      wday: '(%a)'
  time:
    formats:
      ja_ymdhm: ! '%Y年%m月%d日 %H時%M分'
      ja_ymd: ! '%Y年%m月%d日' # time配下に追記
      hm: ! '%H:%M'
      ja_hm: ! '%H時%M分'
      ymdhm: ! '%Y/%m/%d %H:%M'
      mdhm: ! '%m/%d %H:%M'
      dot_ymd: ! '%Y.%m.%d'
```

## 参考

https://railsguides.jp/i18n.html

https://qiita.com/Kta-M/items/bd4ba36a58ad602a9d8b

最後までお読みいただき、ありがとうございました！
PowerAutomate: Post系でトースト通知に概要が表示されないという話だったので調査

# 概要
Teams の Action で以下問題が報告されてたので調べてみた

- Post 系の Advanced options で Summary(概要) に設定するとトースト機能で表示されていた筈が、でなくなった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/44c49d08-aaa5-cbf1-2bf1-b87ca667f0d2.png)

# 結論
- Action が整理されて、旧Action で提供していた機能が未対応の部分がある
- [Post message in a chat or channel](https://docs.microsoft.com/en-us/connectors/teams/#post-message-in-a-chat-or-channel) は、Messageがそのまま表示。
- [Post adaptive card in a chat or channel](https://docs.microsoft.com/en-us/connectors/teams/#post-adaptive-card-in-a-chat-or-channel) は、Advanced Option 対応待ち。
- 旧Action は表示されない。既に廃止済みなので早めの置換をしましょう。


# 最初の感覚
- Teams 側の設定のせいでは？

![2021-09-23_14h52_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/fbb35837-e756-7a75-1139-b0f8941239d9.png)

あら？これでも出ないってことは、問題無いね。

# Document 確認

https://docs.microsoft.com/en-us/connectors/teams

Post 系の集約の結果、沢山廃止（Deprecated）されてますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/c5390dcb-5100-9d95-55f3-b19aa8e1e97c.png)

新しい Actions には IsAlert とか Summary とかの Parameters はまだ対応されてないですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/311e71ed-1e33-e9a2-a7e4-da977762cd1c.png)
![2021-09-23_14h55_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/9f646d86-839c-bb03-4c54-93db456d441d.png)

# 動作確認を旧Action含めて実施

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/46cb157d-2388-6f7e-312f-6e9a3b17ca64.png)

[Post message in a chat or channel](https://docs.microsoft.com/en-us/connectors/teams/#post-message-in-a-chat-or-channel) のみ、Messageがそのまま表示された。
![2021-09-23_15h00_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/c4bbd5eb-2315-cecb-9982-dd2e614c4412.png)
[Post adaptive card in a chat or channel](https://docs.microsoft.com/en-us/connectors/teams/#post-adaptive-card-in-a-chat-or-channel) は 何を表示すべきか決められないので Summary Option は対応されると予想。今後に期待、かな。
font-sizeの最小値を限界突破する小技

<h2>どうしてもfont-sizeを10px未満にしたい</h2>
Google chromeではfont-sizeを10px未満に指定しても必ず10pxで表示されます。

この値より小さいと可読性が悪くなるからやめとけよ、というchromeからのメッセージでもあるわけですが、とはいえ、Galaxy fold (Width280px)　用のレスポンシブデザインを作っている時など、どうしても9pxや8pxを使いたい！というときがあると思います。そんな時にfont-size:10px;の制限を突破できる小技があります。

<h2>transform: scale();でブロックごと縮小させる</h2>
　
font-sizeを10pxに指定して、そのテキストブロックをtransformで縮小させると10pxより小さくできます。

transform: scale(0.9);なら9px、transform: scale(0.8);なら8pxになります。

表示はこんな感じ

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

PCからだと読めたもんじゃないですね。

基本的に10px未満はユーザビリティを下げるので使い所はよく検討したほうがいいでしょう。
スパースファイルを圧縮したい(tar方式)

rawディスクイメージなどスパースファイルを更に圧縮したいとき、多くの圧縮ツールはただのNUL文字列として圧縮してしまうので結構な時間がかかる。

```
truncate -s 1T disk.img
zstd disk.img #遅い
```

S(--sparse)オプション対応のtarでラップする。
しかしファイル名が保存されてしまうのでアーカイブの名前を変えると混乱する。

```
tar -Scf - disk.img | zstd -19 > disk.img.tar.zst
mv disk.img.tar.zst foo.img.tar.zst
tar -xf foo.img.tar.zst
# 常にdisk.imgで展開される
```

パイプすることもできるがスパースでなくなってしまう。

```
tar -Oxf foo.img.tar.zst > foo.img
# foo.imgはスパースにならない
```

ddでconv=sparseに置きかえると遅い。

```
tar -Oxf foo.img.tar.zst | dd bs=1M conv=sparse of=foo.img
```

仕方ないのでtarの出力ファイル名を書き換える。

```
tar --transform "s#.*#foo.img#" -xf foo.img.tar.zst
```

もっと良い方法はないだろうか？
Webシステムのセキュリティ対策まとめ　-CAPTCHA-

#CAPTCHAとは

CAPTCHA とは "Completely Automated Public Turing test to tell Computers and Humans Apart" の略であり、コンピューターと人間を区別するためのテストという意味。

CAPTCHAテストは、オンラインユーザーが本当に人間であり、ボットではないかどうかを判断している。ユーザーは、インターネット上で頻繁にCAPTCHAおよびreCAPTCHAテストを実施する。

#色々なCAPTCHA

* 文字の読み取り
* 画像の種類
* 簡単なパズル

 ボットには文字を識別できないように、表示される文字は曲がっています。 テストに合格するために、ユーザーは歪曲された文字を読み、正しい文字列を入力し、フォームを送信する必要があります。 入力された文字が一致しない場合、ユーザーは再試行します。 こうしたテストは、ログインフォーム、アカウント作成、オンライン投票および電子商取引チェックアウトページなどで一般的に利用されています。

__単一のチェックボックスを使用したreCAPTCHAテスト__
![ダウンロード.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1572216/d5736d34-4e90-5f3c-a1a9-3d1fb90143a9.jpeg)

reCAPTCHAテストの中には、「私はロボットではありません。」という文言の横にあるボックスをチェックするでけのものがある。え、簡単じゃん:smile:テストはチェックボックスをクリックするという行為ではありません。チェックボックスをクリックするまでのすべてがテストです。


このreCAPTCHAテストでは、チェックボックスに近づくときのユーザーのカーソルの動きを見ています。人間の場合、最も直接的な動きでさえ、顕微鏡レベルではある程度のランダム性を持っています。

ボットが簡単に模倣できない小さな無意識の動きです。カーソルの動きにこの予測不可能性が含まれている場合、テストはユーザーが正当であると判断している。

#最後に
学習する前はなんだこのグニャグニャ文字って思ってましたが、Webサイトで人間かロボットかを見分けるための技術だったんだなと改めて知りました。本当に多くの技術があり、まだまだ学習する内容多そうだなと感じた次第でありました
Eclipse リファクタリング メモ

##クラス名をリファクタリングする
* 変更したいクラスファイルを開く
* エディターペイン上で変更したクラス箇所を選択する
* 右クリック＞リファクタリング＞名前変更
* 変更後Enterキーを押下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/eeae75c6-b63d-8de1-818a-b23e054205cc.png)
JavaScriptのBOMの解説

## 基本知識

現在主流ブラウザはIE6~11,Chrome,Safari,FireFoxとなる。

## JavaScriptとBOM関係

簡単に言うと、JavaScriptはブラウザで動き、ブラウザを操作するための言語である。そのブラウザの構成はBOMです。
JavaScriptとBOMはコミュニケーションしてるからこそ、今私たちが見てるブラウザになってる。

## BOMとは

JavaScript Browser Object Model (BOM)
それを理解するために以下を先に説明します。

ブラウザの機能構成（オブジェクト構成） 

ブラウザはwindow、location、Navigator、Screen、History、Documentで構成されてる。
windowがlocation、Navigator、Screen、History、Documentの親

* windowオブジェクト

JavaScriptではすべてのグローバル変数は、Windowオブジェクトのプロパティとなります。（HTML DOM ）のdocument オブジェクトもWindowオブジェクトのプロパティとなります。

```javascript
var a = 0;
```
と

```javascript
window.a = 0;
```
同じとなる。

または

```javascript
window.document.getElementById("header");
```
と

```javascript
document.getElementById("header");
````
も同じ

```javascript:window
window.innerHeight
window.innerWidth
window.open() →　新しいウィンド開く
window.close() →　今のウィンドを閉じる
window.moveTo() →　今のウィンドを移動する
window.resizeTo() →　ウィンドを調整する
```

* Navigatorオブジェクト

```javascript:navigator
navigator.appName
navigator.appCodeName
navigator.platform
navigator.cookieEnabled　→　(trueかfalseが戻る)
navigator.product　→　ブラウザエンジンの商品名
navigator.appVersion
navigator.userAgent
navigator.platform
navigator.language
```

**※注意**
Navigatorオブジェクトはブラウザ所有者に修正される可能があるので、プログラミングにはこのオブジェクトを使ってブラウザバージョン情報を取得するのはお勧めしません。

* Screenオブジェクト

```javascript:screen
screen.width
screen.height
screen.availWidth　→　使用可能な広さ
screen.availHeight　→　使用可能な高さ
screen.colorDepth
screen.pixelDepth
```

* `location`オブジェクト

```javascript:location
window.location.href 　→　今現在のURL
window.location.hostname 
window.location.pathname 　→　今現在HTMLのパス
window.location.protocol 　→　プロトコル(httpかhttps)
window.location.assign →　リロードする 
```

* documentオブジェクト

今現在htmlページ情報が含まれる
いわゆるHTML DOMツリー要素です。例えば`<body>`情報、`<table>`情報などなど

悪意のあるjsだとcookie情報も盗まれる。

```javascript:document
document.title
'My little baby'
document.getElementById('name')
null
document.cookie
''
```

* historyオブジェクト

こんなものです。`戻る` ブラウザの閲覧記録となる。

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/755874/246f58b3-be35-4c94-f9d5-7932ede081d8.png)

```javascript:history
history.back
history.forward
```

# その他

* ダイヤログ

```javascript
window.alert(1)
window.confirm("はい");
window.prompt("入力してください","password");　→　何かを入力しないと進めません。キャンセルするとNULLが戻る
```

以上です。

全体こんな感じでコンソールでやってます。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/755874/f597aae1-2529-14e2-eb80-fd1da3d74955.png)

# 参考記事

https://www.javascripttutorial.net/javascript-bom/
python redisで全データ表示するやーつ

```python
from pprint import pprint
import redis
red = redis.Redis(*redis_host, db=db_num)

# 全データの表示
all_keys = {k.decode(): red.type(k).decode() for k in red.keys()}
for k, t in all_keys.items():
    print(f'key: {k}, type: {t}')
    if t == 'string':
        print(red.get(k).decode())
    if t == 'list':
        pprint([m.decode() for m in red.lrange(k, 0, -1)])
    if t == 'set':
        pprint([m.decode() for m in red.smembers(k)])
    if t == 'zset':
        pprint([(m.decode(), red.zrank(k, m), red.zscore(k, m)) for m in red.zrange(k, 0, -1)])
    if t == 'hash':
        pprint([(f.decode(), v.decode()) for f, v in red.hgetall(k).items()])

    print()
[Ruby] AtCoder過去問 B - Coins

##はじめに
AtCoder過去問をrubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/abc087/tasks/abc087_b

##B - Coins

まずは入力を受け取ります。
改行されているのでreadlinesを使って受け取ります。

```ruby
a, b, c, x = readlines.map(&:to_i)
```


繰り返し文を使うので変数countを用意して0を代入しておきます。
今回のポイントは繰り返し文をネストしていくということです。

今回は先に回答を記述します。↓

```ruby
a, b, c, x = readlines.map(&:to_i)

count = 0
(0..a).each do |i|
  (0..b).each do |j|
    (0..c).each do |k|
      if i * 500 + j * 100 + k * 50 == x
        count += 1
      end
    end
  end
end
 
puts count
```

三階層のネストをしています。
ネストにすることにより一番階層の深いkに0からcまでの値が全て入り終わるまでその一つ上の階層jの値は変わりません。

iとjを固定してkを全て試し、jに一つ変化を加えてまたiとjを固定してkを全て回して。。。
ということを繰り返します。

そうすることにより、手持ちの硬貨を使った、考えうる全てのパターンで計算しています。
その中でxと同じ金額になった時はcountに+1しています。

全てのパターンで計算し終わった後に、xと同じ金額になったパターンの数=答えです。
現役エンジニアが本当によく使うVSCodeショートカット10選


# はじめに

自社開発エンジニア歴3ヶ月の駆け出しエンジニアである私が、**実務において本当によく使っているVSCodeショートカット10選**を初学者向けにご紹介。
ぶっちゃけ、これさえ使えるようになっておけばなんとかなるのではと思っています。

キーと記号の対象表を元にご覧ください。
（※対象はMacユーザー）

| キー | 記号 |
| - | - |
|command| ⌘ |
|shift|⇧|
|option|⌥|
|control|⌃|
|caps lock|⇪|


# ショートカット10選
こちらが今回ご紹介する10個です。後ほど、1つずつ記述していきます。

| NO. | キー | 動作 |
| - | - | - |
|1|⌘ + C | カーソル行を1行コピー<br>（範囲選択時は、選択範囲のみコピー）|
|2|⌘ + P | ファイル検索　|
|3|⌘ + F | ファイル内検索　|
|4|⌘ + ⇧ + F | 全文検索　|
|5|⌘ + Z<br>⌘ + ⇧ + Z| 戻る<br>進む　|
|6|⌘ + ← or →| コード行末までカーソルを移動　|
|7|⌘ + ⇧ +　← or →| コード行末まで選択　|
|8|⌥ 　+　↑ or ↓| カーソル行の移動　|
|9|⌘ + ⇧ +　K| カーソル行削除　|
|10|⌘ + /| コメントアウト|

## 1. `⌘ + C`　
VSCodeでは、なにも選択しない状態で、`⌘ + C`を押すと、**カーソルがある行がまるまる1行コピーできます。**
意外と知らない人もいたのではないでしょうか(O_O)

`⌘ + X`で切り取りができますが、これも同じで、何も選択しない状態だと、まるまる1行切り取りできます。
![コピー2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/1e5b5c68-142f-9d1f-369c-004cbdfa2ade.gif)


## 2. `⌘ + P` 
ファイル検索ですね。これも本当によく使います。
相対パスでも、絶対パスでも検索できます。
![ファイル検索.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/392808c2-7084-13e9-701f-6b4cc9a484fe.gif)


## 3. `⌘ + F`
作業ファイル内から、該当するワードを検索します。
該当ワードが複数ある場合は、`Enter`を押すと、次に進めます。
![ファイル内検索.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/b58dd3d5-a2cb-b9b3-6b3f-dc45e2fd7cc2.gif)


## 4. `⌘ + ⇧ + F `
ワークスペース内（ディレクトリ内）を全文検索します。
![全文検索.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/5e978dc8-35ca-5a7e-fa41-5b0accf2d677.gif)


## 5. `⌘ + Z` , `⌘ + ⇧ + Z`
`⌘ + Z`で戻る。 `⌘ + ⇧ + Z`で、戻ったものを進ませることができます。

`⌘ + Z`はよく連発しますね。
これもVSCode以外でもたくさん使います。

![戻る.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/ad44e2eb-7993-77ff-d100-5ea0da3bda3f.gif)

## 6. `⌘ + ← or →`
`⌘ + ← or →`でカーソルを行末に移動させることができます。いちいち移動させるのは面倒臭いですよね、そんなときにどうぞ。

補足ですが、`⌥ + ← or →`で粒度を小さくし単語単位での移動ができます。

![カーソル移動.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/69de9632-f762-0c48-4039-4815368a5d9e.gif)

## 7. `⌘ + ⇧ +　← or →`
　6. `⌘ + ← or →`に`Shift`を付け足すと、行末まで一気に選択することができます。
![行末選択.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/08bfab8d-f9ac-79ca-fbc0-994aa5d7c8c7.gif)

## 8. `⌥ + ↑or ↓`
カーソルがある行をすぐに移動させることができます。
行の入れ替えなどしたいときに、切り取りなどせずに簡単に移動させることができて、これはめちゃくちゃ重宝してますね。
![行移動オプション.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/bc271237-bdbf-13b0-719b-168d0014e4b3.gif)


## 9. `⌘ + ⇧ + K`
`⌘ + ⇧ + K`で、カーソルがある1行をまるまる削除できます。

不用になったコードや、修正を加えたい時によく使っています。
意外と知らない方も多い？のかもしれません🤔
![1行削除.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/c59d8c0c-4f87-1da3-6523-3c24fa0ac628.gif)


## 10.  `⌘ + /`
選択部分を**コメントアウト**してくれます。

なにも選択しない状態ですると、カーソルがある1行だけがコメントアウトされます。
![コメントアウト.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/7492c18e-eb94-8c53-68b4-d102d7007b8d.gif)

# さいごに
ショートカットは覚えれば覚えるほど良い物だと思いますが、私自身の当初はどのショートカットが重要なのかよくわかっていませんでした。
エンジニアとして実際に業務をしていく中で、毎日何１０回と使っているなと感じたショートカットだけ取り上げてみました。

この記事が少しでも、これからエンジニアを目指す人たちや、駆け出しエンジニアの方々への助けになれば幸いです。
Pedersen Commitment

## 作り方
位数が素数 $p$ の有限巡回群上に、ジェネレーター $G$ と $H$ を準備する。
位数が素数なので、群論のラグランジュの定理から $G$ と $H$ の位数は $p$ になり、$G$ 上の元は必ず $H$ 上にも存在して、$G^x=H$ や $H^y=G$ となる $x,y$ が存在するが、これがわからない形で、$G$ と $H$ を準備する。
その上で、Pedersen Commitment $C$ は、

$$C(a, b) = G^a \cdot H^b$$

## 使い方
ジェネレーター $G$ 上の $\cdot$ の演算は、準同型性があって、$G^x + G^y = G^{x+y}$ が成り立つので、
コミットメント同士を足した結果と、コミットメントへの入力を足してものの、コミットメントをを作った結果が一致する。
この性質を利用して、何かをする。

$$C(a,b) + C(c,d) = G^a \cdot H^b \cdot G^c \cdot H^d = G^a \cdot G^c \cdot H^b \cdot H^d = G^{a+c} \cdot H^{b+d} = C(a+c, b+d)$$

## Liquid の Confidential Transaction での使用例
Perdersen Commitment を利用して、トランザクションの具体的な数量を明かさずに、tx-in の合計と、tx-out の合計が一致していることを示す。

例えば、こんなトランザクションがあったとする。

|tx-in|tx-out|
|-----|------|
|   5 |   10 |
|  10 |   32 |
|  17 |      |

この tx-in/out それぞれについて、blinding factor を割り当てる。その際に、blinding factor の tx-in 側の合計と、tx-out 側の合計が同じになるようにする。例えば、

|tx-in|tx-in-blinding-factor|tx-out|tx-out-blinding-factor|
|-----|------------------|------|-------------------|
|   5 |              100 |   10 |                500|
|  10 |              250 |   32 |                 30|
|  17 |              180 |      |                   |

tx-in/out = a, blind factor = b を、$C(a,b)$ で置き換えて、トランザクションを公開する。

|tx-in      |tx-out|
|-----------|------------|
| C(5, 100) | C(10, 500) |
| C(10, 250) | C(32, 30) |
| C(17, 180) | |

こうすると、
$$
C(5, 100) + C(10, 250) + C(17, 180) - C(10, 500) - C(32, 30)
= G^{5+10+17-10-32} \cdot H^{100+250+180-500-30}
= G^0 \cdot H^0 
= e \cdot e 
= e
$$
となるので、具体的な数量を明かしていなくても、tx-in の合計と、tx-out の合計が一致していることがわかる。

## 参考サイト
https://link.springer.com/content/pdf/10.1007%2F3-540-46766-1_9.pdf
http://hooktail.sub.jp/algebra/LagrangeanTheorem/
https://techmedia-think.hatenablog.com/entry/2015/12/31/002253
https://www.blockchainengineer.tokyo/entry/confidential-transactions
https://elementsproject.org/features/confidential-transactions/investigation