OmniAICreator/Qiita-1.07M huggingface dataset:
【terminal】iTerm2を見やすくしちゃうやつ〜zshをいじくる〜

### Udemyの教材をやり初めてずっと気になっていたこと
動画に出てくるターミナルがみんな色わけされててかっこいい。
現在いるブランチ名が表示されていたり時刻が表示されていたり、とにかく見やすい。
なにこれどうやってやるの？と調べてみた話です。


### zshファイルの表示
```terminal
% vi .zshrc
```

`I`でINSERTモードにして追加。


```terminal
# git
autoload -Uz vcs_info
setopt prompt_subst
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr "%F{magenta}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{yellow}+"
zstyle ':vcs_info:*' formats "%F{cyan}%c%u[%b]%f"
zstyle ':vcs_info:*' actionformats '[%b|%a]'
precmd () { vcs_info }

#プロンプト
PROMPT='%*
%F{green}[%~]%F{cyan}$vcs_info_msg_0_%f %# '
```
入力が終わったら`ESC`→`:WQ`で保存。


### 設定した内容を保存する

```terminal
% source ~/.zshrc
```

できたのがこんな感じ。


![4bbc4461ab44f3bca15a4a01356da318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887559/d6d6ede0-b55b-bc8a-ca00-c4ef4b9a6eb3.png)

めっちゃいい。時間がある時にもっとカスタマイズしたいなと思いました。


### 参考にさせていただきました
@y-hirako0928様
[最短最速でターミナルカスタマイズをする。](https://qiita.com/y-hirako0928/items/30b6f8d0162dbb8ca486)

[【macOS Catalina】MacのターミナルにGitブランチ名を表示させる](https://bottoms-programming.com/archives/termina-git-branch-name-zsh.html)

ありがとうございました。
【JavaScript 】aタグのhrefを書き換えたい

aタグに書かれているhrefの値をJavaScriptで変更したい。

```HTML:HTML
<a href="/Home/About" id="link">About</a>
```

```JS:JS
function Replace() {
    let link = document.getElementById('link');
    let url = '/Home/Replace';

    //href属性の値を書き換える
    link.setAttribute('href', url);
}
```
GitHub Actionsで複数Job間でデータを共有する方法 - Job outputs

GitHub ActionsはJobごとに別々のGitHub Actions Runnerで実行され、つまり別々のOSで実行されるのでJob間でデータを共有するには工夫が必要となる。

解決策の１つにArtifactsのUpload/Downloadがあって、少々面倒ではあるが、他に手っ取り早い方法もなさそうだしこれでよいだろうという理解だった。 残念ながら今のところGitHub ActionsにはJob間で共有可能なグローバルスコープの変数はなく・・・

ArtifactsのUpload/DownloadによるJob間のデータ共有する方法
共有したいデータをファイルに書き出し[actions/upload-artifact](https://github.com/actions/upload-artifact)でArtifactとしてアップロードし、別のJobで[actions/download-artifact](https://github.com/actions/download-artifact)を使ってそのArtifactを読み込みデータを取得する
詳しくはこちらを参照ください - [Passing data between jobs in a workflow](https://docs.github.com/en/actions/guides/storing-workflow-data-as-artifacts#passing-data-between-jobs-in-a-workflow)

ところが、こちらの[Stackoverflow投稿](https://stackoverflow.com/questions/59175332/using-output-from-a-previous-job-in-a-new-one-in-a-github-action)でもっと手軽な良い方法が紹介されていた。それが`jobs.<jobs_id>.outputs`。2020年４月に[アナウンス](https://github.blog/changelog/2020-04-15-github-actions-new-workflow-features/)された機能のようだ。

[公式ページ](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idoutputs)には次のように説明されている。

> A map of outputs for a job. Job outputs are available to all downstream jobs that depend on this job. For more information on defining job dependencies, see jobs.<job_id>.needs.
>Job outputs are strings, and job outputs containing expressions are evaluated on the runner at the end of each job. Outputs containing secrets are redacted on the runner and not sent to GitHub Actions.

つまり、あるJobにおける処理結果を`jobs.<jobs_id>.outputs`でマッピングすることができて、その後のJobでそいつを参照できるのだ。 ArtifactsのUpload/Downloadのようにわざわざファイルのアップ・ダウンロードする必要もなく、手軽で直感的。

サンプルをそのまま抜粋するが、後続のjob2ではjob1のマッピングされた出力結果を`${{needs.job1.outputs.output1}}`で参照している。

```yaml
jobs:
  job1:
    runs-on: ubuntu-latest
    # Map a step output to a job output
    outputs:
      output1: ${{ steps.step1.outputs.test }}
      output2: ${{ steps.step2.outputs.test }}
    steps:
    - id: step1
      run: echo "::set-output name=test::hello"
    - id: step2
      run: echo "::set-output name=test::world"
  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
    - run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}
```
ref: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idoutputs

簡単なテキストデータであればこれでよいのではないだろうか
MASTEERDRIVEのオンラインと吸出し(DriveMonitor)

SIEMENSの古いDRIVEででMASTERDRIVEという機器があります。

そのオンライン、吸出しの流れを記述します。

①パラメータが手元にない状態からの吸出し(USS インターフェースを使用)
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/e817fc76-1f92-30c2-7e0c-12809bec5053.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/0ebef73d-8db9-9b99-cd96-a55432c9f439.png)
Find online drivesというウィンドウが出てくるので、startをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/1f39343a-9e89-2c99-8a73-0028f89fb050.png)
 見つかりました。
基本的にUSSなので一つしか出てこないです。
見つかったらすぐにオンライン表示に切り替わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/66f3216b-e345-e2a8-db02-5450824b4466.png)
Save drive parameter to fileをクリック
  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/60de3148-b80f-d50a-bbc2-0e525824c74a.png)
そのままの選択でOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/3c5ec025-6590-626f-d1ae-09d518151834.png)
 　保存するファイル名を入力。
Saveを押すと吸出しスタート。


②DriveMonitorのオンライン接続設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/44c8b040-1b7f-41d8-dbee-78531c849907.png)
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/b28ae5f3-7668-28f7-561f-fc714ed07699.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548319/5465578e-f031-a318-ee98-fcc785eecf12.png)
出来ればBaud rateを19200に上げて実行する方がよい。（パソコンのポートもDrive（P701で設定）も全て）
9600だと一台当たり5分以上かかるが、19200だと5分以内には終わる。
38400など速すぎる設定にはしないほうがよい。パラメータを吸い出すときに、通信が速すぎて吸い出さないパラメータが出てくる可能性がある。19200までならそういった現象は起きない。

































②DriveMonitorのオンライン接続設定
 
  
出来ればBaud rateを19200に上げて実行する方がよい。（パソコンのポートもDrive（P701で設定）も全て）
9600だと一台当たり5分以上かかるが、19200だと5分以内には終わる。
38400など速すぎる設定にはしないほうがよい。パラメータを吸い出すときに、通信が速すぎて吸い出さないパラメータが出てくる可能性がある。19200までならそういった現象は起きない。
Rails 備忘録

validates
onとif
on: バリデーションの実行タイミング

```
class Person < ApplicationRecord
  # 値が重複していてもemailを更新できる
  validates :email, uniqueness: true, on: :create

  # 新規レコード作成時に、数字でない年齢表現を使える
  validates :age, numericality: true, on: :update

  # デフォルト (作成時と更新時の両方でバリデーションを行なう)
  validates :name, presence: true
end
```

if: バリデーションを行う条件

```
class Order < ApplicationRecord
  validates :card_number, presence: true, if: :paid_with_card?

  def paid_with_card?
    payment_type == "card"
  end
end
```
 両方シンボルで指定することに注意

nil?
nilだけtrue

empty?
空文字、空配列true

blank
両方

ランダム数値
```
format("%0#{n}d", SecureRandom.random_number(10**n))
```

memberとcollectionの違い
簡単に言うと、routingにidが付くか付かないか
【Swift】PickerViewの中身が表示されないとき

# どういうことか

![dd88120c8416b3000c00e44b57d40e20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/40b96b43-8eba-29cc-950b-2bc14851383c.png)

なにもない

## 疑ってみること

```swift
    @IBOutlet weak var pickerView: UIPickerView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        pickerView.delegate = self
        pickerView.dataSource = self
    }
```

`delegate` とかを書いてないのでは？？

たとえば他の方が同じような実装をしたControllerでは**Storyboardでdelegateなどが設定されている**場合、それを参考にしながら書くとハマる。というかハマった。

おわり(´・ω・｀)
Lightningナレッジのチャネルに記事を挿入するアクションを設定する

フィールドラベルを非表示にできるみたいです。

記事が挿入されたフィールドラベルと関連ファイルを含めるかどうかを選択します。
デフォルトでは、フィールドラベルはすべてのチャネルに挿入された記事に含まれ、関連ファイルは電子メールに添付されます。ファイルが添付されている場合でも、エージェントはメールを送信する前にファイルを切り離すことができます。
1.フィールドラベルを非表示にするには、[フィールドラベルを省略]を選択します。
2.添付ファイルをスキップするには、[関連ファイルを電子メールに添付しない]を選択します。

https://help.salesforce.com/articleView?id=sf.knowledge_insert_article_content_email.htm&type=5

元の質問
https://trailblazers.salesforce.com/answers?id=9064S000000DjdU
brakemanのMassAssignmentでエラー(rails)


#課題
指定した箇所について、brakemanのMassAssignmentチェックをスキップしたい。

#詳細
brakemanのログを見ると、以下のようにWarningが出ている。

```
== Warnings ==

Confidence: Medium
Category: Mass Assignment
Check: PermitAttributes
Message: Potentially dangerous key allowed for mass assignment
Code: params.require(:user).permit(:role)
File: app/controllers/users_controller.rb
Line: 14
```

どうやら、以下のソースコードの「role」という単語に反応しているようだ。

```ruby:users_controller.rb
  private

  def user_params
    params.require(:user).permit(:role)
  end
```

brakemanのソースコードを覗いてみると、
https://github.com/presidentbeef/brakeman/blob/aef6253a8b7bcb97116f2af1ed2a561a6ae35bd5/lib/brakeman/checks/check_permit_attributes.rb

roleがSUSPIOUS_KEYSとして登録されていた。
admin、account_idやroleなどのカラム名をpermitするのは危険だと定義しているらしい。

```ruby:lib/brakeman/checks/check_permit_attributes.rb
require 'brakeman/checks/base_check'

class Brakeman::CheckPermitAttributes < Brakeman::BaseCheck
  Brakeman::Checks.add self

  @description = "Warn on potentially dangerous attributes allowed via permit"

  SUSPICIOUS_KEYS = {
    admin: :high,
    account_id: :high,
    role: :medium,
    banned: :medium,
  }
```

私としてはroleをpermitしたいので、このwarningチェックをスキップさせたい。

# 解決策
config/brakeman.ignore にスキップさせたい項目を定義できるようだ。
このファイルは以下のコマンドでスキップさせたい項目も定義しながら、作成できる。

```
bundle exec brakeman -I 
```

以上で解決した。
【VBA】日付から月末を求める方法

今回は、月末を求める方法です。

サンプルデータは以下の図をご覧ください。

![サンプル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242278/2ad2ab8f-e28a-ebfe-e157-73699f7bb911.jpeg)

↓実演動画
https://youtu.be/PKS9JwrsPG0

ソースコードは下記の通りです。

```

Sub 月末を求める()

　　Cells(2, 2) = DateSerial(Year(Cells(2, 1)), Month(Cells(2, 1)) + 1, 0)
    
End Sub

```

詳細を説明します。

>DateSerial(Year(Cells(2, 1)), Month(Cells(2, 1)) + 1, 0)

今回は、DateSerial関数を使用します。
DateSerial関数は、指定した日付を返す関数になります。

第1引数、第2引数、第3引数には、それぞれ年、月、日を指定します。

DateSerial関数の詳細はこちら
https://www.tipsfound.com/vba/05dateserial

値に0を入れると、一つ前の値が返されます。
※例えば、元データが2021/4/15だった場合、日を0とすると2021/3/31が返される。

今回は、今月末を取得するため日を0にし、前月末が取得されるため月に+1することで期待する値が取得出来ました。

以上が、月末を求める方法でした。
picoCTF 2021 Who are you? Writeupを早く見たい

何度，心が折れても，あきらめずに粘り強く頑張った ~~が，どうしても解けなかった記念として，途中までの記録を残す。~~ 結果，救いの手が差しのべられ，ついにスウェーデンを倒しました。

http://mercury.picoctf.net:38322/

## step 1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/c2c11238-559b-78ce-1ae1-1bf3bb1b38ae.png)
Only people who use the official PicoBrowser are allowed on this site!

```
User-Agent: PicoBrowser
```

## step 2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/8c3e1956-b599-6540-3049-64f224ec49df.png)
I don't trust users visiting from another site.

```
User-Agent: PicoBrowser
Referer: http://mercury.picoctf.net:38322/
```
## step 3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/a56d8588-3a4b-21a5-4b41-f0e9d0375492.png)
Sorry, this site only worked in 2018.

ヒント

https://tools.ietf.org/html/rfc2616

```
User-Agent: PicoBrowser
Referer: http://mercury.picoctf.net:38322/
Date: Tue, 15 Nov 2018 08:12:31 GMT
```

## step 4
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/a0337843-6eb4-4173-d975-8c1167585177.png)
I don't trust users who can be tracked.

rfcは探しにくいので

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/DNT

```
User-Agent: PicoBrowser
Referer: http://mercury.picoctf.net:38322/
Date: Tue, 15 Nov 2018 08:12:31 GMT
DNT: 0
```

## step 5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/b9795b01-4d8b-d33a-d46d-0f484b30c2c6.png)
This website is only for people from Sweden.

Sweden 何を試しても突破できない。

@ioliteningさんに答え教えてもらいました。ありがとうございます。
X-Forwarded-For:

https://tools.ietf.org/html/rfc7239

X-Forwarded-For (XFF) とは、HTTPヘッダフィールドの一つ。HTTPプロキシサーバまたは負荷分散装置（ロードバランサ）を経由してウェブサーバに接続するクライアントの送信元IPアドレスを特定する際のデファクトスタンダードである。（ウィキペディアより引用）

https://ja.wikipedia.org/wiki/X-Forwarded-For

これって， ロードバランサ が Webサーバ に対して，「本物の接続元はこのIPだよ」ってやるためにあるやつだよね。
This website is only for people from Sweden.
とは違うと思う。
私の判定では，運営側の作問ミス。

スウェーデンのIP

https://www.nirsoft.net/countryip/se.html

```
User-Agent: PicoBrowser
Referer: http://mercury.picoctf.net:38322/
Date: Tue, 15 Nov 2018 08:12:31 CEST
DNT: 0
X-Forwarded-For: 2.71.255.255
```

## step 6
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/38041127-ac9f-99fe-e52c-5d13931aabca.png)
You're in Sweden but you don't speak Swedish?

```
User-Agent: PicoBrowser
Referer: http://mercury.picoctf.net:38322/
Date: Tue, 15 Nov 2018 08:12:31 CEST
DNT: 0
X-Forwarded-For: 2.71.255.255
Accept-Language: sv-SE
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/e2d6a735-06f7-8ad0-c50f-4abbed4ce5ce.png)

やったぜ！
MacでcentOSにssh接続できない時の解決法


# 前提
以下の記事を参考にcentOSをインストールしました。

https://qiita.com/nooboolean/items/de4e6bbae5df040177af

同じ方が書いている以下の記事でssh接続を試みました。

https://qiita.com/nooboolean/items/96ae44d0090794dce8d1


# 【ここからが本題】
手順通りにやっても失敗してしまい困った。。。
ssh接続が成功するまでやったことを順番に記載していきます。

## ①「 systemctl restart network　で接続失敗 」
タイトルのコマンドを実行すると以下のメッセージが表示される。

Failed to restart network.service: Unit network.service not found.

network.serviceがないらしい。

以下の記事を参考に解決しました。
https://uktia.hatenablog.jp/entry/20191102/1572698888

## ②「 port 22: Connection refused で接続失敗」
ssh root@IPアドレス を入力するとタイトルのメッセージが。。。
以下の記事を参考にポートフォアディングを設定しました。

https://qiita.com/sango/items/1b57a9641499971ca806#_reference-9ae6982ac9592f15f424

## ③「 そもそもcentOSのネットワーク設定を間違えていた 」
私の場合は、NATがブリッジアダプターになっていたので、NATに設定しました。
一度設定したものが記事通りになっているか。の確認は一通りやるといいかもしれません。

## ④「 [ssh root@ IPアドレス]を変えてみる 」
nmtuiコマンドでcentOSネットワークの設定をしました。その際にホストオンリーアダプタにIPv4の設定します。IPv4はホストネットワークマネージャーで設定した値以外を設定した場合は、ホストネットワークマネージャーに揃えると良いかもしれません。
接続の際は、以下のコマンドを実行
ssh root@ ホストネットワークマネージャーで設定したIPv4アドレス

# 以上です。
もし以上4つ手順を踏んでも失敗するようであれば、以下の記事が参考になるかもしれません。

https://qiita.com/sango/items/816136188387221f05b3
picoCTF 2021 Scavenger Hunt Writeup

何度，心が折れても，あきらめずに粘り強く頑張った結果解けた問題なので，うれしさのあまり Writeup を残す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/fe3b7fe0-8e19-1f9e-8985-20d7204b3dba.png)

http://mercury.picoctf.net:39491/

見た目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/d6dd4dda-0d74-eb01-21be-7456eb6fdf9b.png)

まずソースを見る

```html
<!doctype html>
<html>
  <head>
    <title>Scavenger Hunt</title>
    <link href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="mycss.css">
    <script type="application/javascript" src="myjs.js"></script>
  </head>

  <body>
    <div class="container">
      <header>
		<h1>Just some boring HTML</h1>
      </header>

      <button class="tablink" onclick="openTab('tabintro', this, '#222')" id="defaultOpen">How</button>
      <button class="tablink" onclick="openTab('tababout', this, '#222')">What</button>

      <div id="tabintro" class="tabcontent">
		<h3>How</h3>
		<p>How do you like my website?</p>
      </div>

      <div id="tababout" class="tabcontent">
		<h3>What</h3>
		<p>I used these to make this site: <br/>
		  HTML <br/>
		  CSS <br/>
		  JS (JavaScript)
		</p>
	<!-- Here's the first part of the flag: picoCTF{t -->
      </div>

    </div>

  </body>
</html>
```

Here's the first part of the flag: picoCTF{t
と書いてるので，CSSやjsを見ていくパターンと予測

CSS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/dc5a3d7d-0b4f-9244-a18f-217bcf87a566.png)
２つ目Get

js
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/622cedc1-9db1-57a1-bb7e-c9323bdc2fb9.png)
ヒントだけ
How can I keep Google from indexing my website?

robots.txtかな？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/65530861-223a-c457-8725-89d6f09019eb.png)
３つ目Get
ってか，またヒントが
I think this is an apache server... can you Access the next flag?

Apache特有か？
apache ctf でググったら　↓　これが出てきた

https://pwning.re/2017/11/20/h1-212-writeup/

.htaccessか

https://httpd.apache.org/docs/2.4/ja/howto/htaccess.html

https://www.xserver.ne.jp/manual/man_server_htaccess.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/b52c5afe-0716-2b16-cfb6-27ca0ea768c8.png)
ビンゴ！４つ目Get
まだヒントが
I love making websites on my Mac, I can Store a lot of information there.

MACの自動保存

確かMACにさしたUSBに変な隠しファイルがたくさんできてたよな。
消すんじゃなかった。
ネットで頑張ってみる。
あった。

https://discussionsjapan.apple.com/thread/250564486

https://discussionsjapan.apple.com/thread/251636359

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/c68b0529-138d-425b-31a0-fe5db627e620.png)
picoCTF 2021 Disk, disk, sleuth! II writeup

ネットでやり方を見つければ簡単に出来る問題ではあるが，自分としては，Linuxの削除ファイルの復元をEnCase等に頼らず，初めて無料ツールでやったので記録を残しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/d4cc70ee-663c-97be-27c9-87bda5d9be36.png)

down-at-the-bottom.txtを探せとのこと

マウントしてファイルを探してみる

```
＄ file dds2-alpine.flag.img 
dds2-alpine.flag.img: DOS/MBR boot sector; partition 1 : ID=0x83, active, start-CHS (0x0,32,33), end-CHS (0x10,81,1), startsector 2048, 260096 sectors

＄ fdisk -l -u dds2-alpine.flag.img
ディスク dds2-alpine.flag.img: 128 MiB, 134217728 バイト, 262144 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x5d8b75fc

デバイス              起動 開始位置 最後から セクタ サイズ Id タイプ
dds2-alpine.flag.img1 *        2048   262143 260096   127M 83 Linux

$ sudo mount -o loop,offset=$((2048*512)) dds2-alpine.flag.img /mnt/test

$ grep -r "down-at-the-bottom.txt" *

```

やっぱりダメ。

ヒント見る

http://wiki.sleuthkit.org/index.php?title=TSK_Tool_Overview

参考にしたサイト

https://kaworu.jpn.org/kaworu/2012-12-04-1.php

fls　参考にしたサイト

http://www.kazamiya.net/SleuthKit/fls

```
$ fls -r -b 512 -o 2048 dds2-alpine.flag.img | grep "down-at-the-bottom.txt"

 r/r 18291:	down-at-the-bottom.txt
```

iノード番号がわかった。

icat　参考にしたサイト

http://www.kazamiya.net/SleuthKit/icat

```
$ icat -b 512 -o 2048 dds2-alpine.flag.img 18291

   _     _     _     _     _     _     _     _     _     _     _     _     _  
  / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \ 
 ( p ) ( i ) ( c ) ( o ) ( C ) ( T ) ( F ) ( { ) ( f ) ( 0 ) ( r ) ( 3 ) ( n )
  \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/ 
   _     _     _     _     _     _     _     _     _     _     _     _     _  
  / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \ 
 ( s ) ( 1 ) ( c ) ( 4 ) ( t ) ( 0 ) ( r ) ( _ ) ( n ) ( 0 ) ( v ) ( 1 ) ( c )
  \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/ 
   _     _     _     _     _     _     _     _     _     _     _  
  / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \ 
 ( 3 ) ( _ ) ( 0 ) ( b ) ( a ) ( 8 ) ( d ) ( 0 ) ( 2 ) ( d ) ( } )
  \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/ 
```
S3の特定のフォルダのみを許可するIAMポリシー

S3の特定のプレフィックスに限定して、S3オブジェクトの基本操作（読み込み、書き込み、削除、オブジェクト一覧確認）のみを許可するIAMポリシーは、

# 結論

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET/PREFIX/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": "PREFIX/*"
                }
            }
        }
    ]
}
```

# 説明

S3オブジェクトの基本操作（読み込み、書き込み、削除、オブジェクト一覧確認）に必要な権限のActionは `s3:GetObject`、`s3:PutObject`、`s3:DeleteObject`、`s3:ListBucket` です。

ちなみにオブジェクト一覧を見るための権限は ListObject のような名前ではなく `s3:ListBucket` です。これに対してバケットの一覧は `s3:ListAllMyBuckets` です。名前が紛らわしいです。

これを踏まえて、次のように書きたくなるのですが、

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET/PREFIX/*"
            ]
        }
    ]
}
```

これはうまくいきません。読み込み、書き込み、削除はできますが、オブジェクト一覧を見ることができません。

Resourceで指定するリソースの種類はActionごとに決まっていて、`s3:GetObject`、`s3:PutObject`、`s3:DeleteObject` はオブジェクトですが、`s3:ListBucket` はバケットなのです。従って、`s3:ListBucket` だけResourceは `arn:aws:s3:::BUCKET` のようにバケット単位での指定が必要です。ここにプレフィックスを書くことはできません。

`s3:ListBucket` だけ分けて書くことになります。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET/PREFIX/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET"
            ]
        }
    ]
}
```

しかし、これだと `s3:ListBucket` は特定プレフィックス配下ではなく、バケット全体で許可されてしまいます。Conditionに以下のように `s3:prefix` の条件を書くことで、特定プレフィックス配下に限定することが必要になります。これで冒頭のIAMポリシーになります。

```json
            "Condition": {
                "StringLike": {
                    "s3:prefix": "PREFIX/*"
                }
            }
```

ポイント

- `s3:ListBucket` だけ分けて書く
    - Resourceはバケット全体を指定
    - Conditionに `s3:prefix` を指定
- `s3:???Object` はResourceにプレフィックスを含める

（毎回身近なところから似たIAMポリシーを探したり、ググったりしてるので、できる限りシンプルなパターンとして、記事にまとめておいたものです）

# 参考

Actionの一覧とそれぞれの指定できるリソースの種類は、次の公式ドキュメントに載っています。

[Actions, resources, and condition keys for Amazon S3 - Service Authorization Reference](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazons3.html)
manimの作法 その51

#概要

manimの作法、調べてみた。
練習問題やってみた。

#参考にしたページ。

https://qiita.com/masudaryo/items/29537e98220ed9c8bc0a

#サンプルコード

```
from manimlib.imports import *

R = 3
e = 0.7
n = 0
u = 0

def f1(t):
	return np.array((e * np.cos(3 * u) + R * np.cos(u + 2 * n * np.pi / 3) + R * np.sqrt(3) * np.cos(u + t), 
					 e * np.sin(3 * u) + R * np.sin(u + 2 * n * np.pi / 3) + R * np.sqrt(3) * np.sin(u + t), 0))
def f2(t):
	return np.array((e * np.cos(3 * t) + R * np.cos(t), 
					 e * np.sin(3 * t) + R * np.sin(t), 0))
def f3(t):
	return np.array((2 * e * np.cos(3 * t), 
					 2 * e * np.sin(3 * t), 0))
def f4(t):
	return np.array((e * np.cos(3 * u) + e * np.cos(3 * t), 
					 e * np.sin(3 * u) + e * np.sin(3 * t), 0))

class test(Scene):
	def construct(self):
		global n, u
		grid = NumberPlane()
		self.add(grid)
		func2 = ParametricFunction(f2, t_min = TAU * 0, t_max = TAU, fill_opacity = 0)
		self.add(func2)
		func3 = ParametricFunction(f3, t_min = TAU * 0, t_max = TAU, fill_opacity = 0)
		self.add(func3)
		self.wait()
		for u in TAU * np.arange(0, 0.4, 1 / 40):
			func4 = ParametricFunction(f4, t_min = TAU * 0, t_max = TAU, stroke_color = PINK, fill_opacity = 0)
			self.add(func4)
			n = 0
			rot0 = ParametricFunction(f1, t_min = np.pi / 6 * (4 * n + 5), t_max = np.pi / 6 * (4 * n + 7), stroke_color = PINK, fill_opacity = 0)
			self.add(rot0)
			n = 1
			rot1 = ParametricFunction(f1, t_min = np.pi / 6 * (4 * n + 5), t_max = np.pi / 6 * (4 * n + 7), stroke_color = PINK, fill_opacity = 0)
			self.add(rot1)
			n = 2
			rot2 = ParametricFunction(f1, t_min = np.pi / 6 * (4 * n + 5), t_max = np.pi / 6 * (4 * n + 7), stroke_color = PINK, fill_opacity = 0)
			self.add(rot2)
			self.wait()
			self.remove(rot0)
			self.remove(rot1)
			self.remove(rot2)
			self.remove(func4)





```

#生成した動画。

https://www.youtube.com/watch?v=8xA_u8knltI

以上。
蟹さんのSDK

RTL8196CなどのLexraのSDKをいろいろ探してみたところ以下のようなものがありました。

|sdk|gcc|
|:--|:--|
|rsdk-1.3.6-4181|3.4.6|
|rsdk-1.3.6-5281|3.4.6|
|rsdk-1.5.5-5281|4.4.5|
|rsdk-1.5.6-5281|4.4.6|
|rsdk-1.5.10-4181|4.4.7|
|rsdk-1.5.10-5281|4.4.7|
|rsdk-4.4.7-4181|4.4.7|

蟹さんがあっちゃくせ（庄内弁）と思うのは、なぜか1.4が欠番になってることや1.5.6までは最終桁がgccのレビジョンをあらわしていたのが、その後外れていたり、またいきなり飛んで4.4.7になってたりすることがあります。いきなり飛んでいるのはmips 24Kを作るようになって24KのSDK(msdk)とバージョンをあわせるためだったのではないかと思います。

Realtekはごたぶんにもれず、armのSOCもやっていて、なぜ後になってmips 24Kをやる必要があったのかはなはだ疑問です。

あとLexraのアーキテクチャ(5281,4181)毎にSDKを用意しているように見えるのですが、中には該当のアーキテクチャ専用のgccと全アーキテクチャ対応のgccが入っています。

集めたものはここに置いてあります。

https://github.com/yamori813/rtl819x-toolchain

GPLのソースに入っていたファイルをgithubなどに上げてるのを集めたのだが検索が思ったほど効かず結構手間がかかった。他にもrsdk-1.5.8-4281-EB-2.6.30-0.9.30.3-m32ub-120907.tar.gzというファイルもありそうなのだが、検索では出てこない。どうも最近の検索結果は意図的にファイルなどを削除しているような気がする。

蟹さんはいろいろやる事で、技術者が翻弄され、製品のクオリティーが下がり、結局は会社のためにならないと思うのですが。
MacにGradleを導入する手順メモ

環境
macOS Big Sur 11.2.3

<h3>①Homebrewを導入</h3>

```terminal:terminal
# Macのパッケージ管理ツールhomebrewをインストール
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

# バージョン確認
brew --version

# Homebrew 3.0.10

# brewコマンドでgradleをインストール
brew install gradle
```
MacにMavenを導入する手順メモ

環境
macOS Big Sur 11.2.3

<h3>① Mavenファイルの取得</h3>

Mavenの公式サイト(https://maven.apache.org/download.cgi)にアクセスする。

「Binary tar.gz archive」をダウンロードする。

ダウンロードディレクトリに「 apache-maven-○.○.○-bin.tar.gz 」ファイルが
ダウンロードされているのでこれを[ /usr/local ]へ移動し、解凍。
（ユーザにroot権限を付与していない場合は必要に応じてコマンドの頭に sudo を追加して実行）

```terminal:terminal
# ファイルを移動
mv Downloads/apache-maven-3.6.3-bin.tar.gz /usr/local

# ファイル移動先ディレクトリに移動
cd /usr/local

# ファイルを解凍
tar zxvf apache-maven-3.6.3-bin.tar.gz

# 不要な元ファイルを削除
rm apache-maven-3.6.3-bin.tar.gz
```

「 /usr/local　」ディレクトリに「 apache-maven-3.6.3 」というファイルが配置されている
ことを確認する

<h3>②環境変数設定</h3>

「 M3_HOME 」という名前で先程解凍したMavenファイルのPathを作成する

```terminal:terminal
# exportコマンドでファイルのPathを環境変数に指定
export M3_HOME=/usr/local/apache-maven-3.6.3

# 同様に/binまでのPathを環境変数に指定
M3=$M3_HOME/bin

# 環境変数PATHに追加
export PATH=$PATH:$M3

# 最後に環境変数PATHの変更内容を反映させる
source ~/.bash_profile
```

<h3>③最終確認</h3>

```terminal:terminal
# 導入されたMavenのバージョンを確認
mvn -version

# Apache Maven 3.6.3
```

Mavenのバージョンが表示されたので無事導入完了
正規表現まとめ

LPICで正規表現を勉強したので忘れないように書きます。
grepコマンドを例にまとめます。
#grepコマンドについて
書式： grep [option] 検索パターン [ファイル名]
オプション
-i : 大文字小文字を区別しない。
-v : パターンがマッチしない行を表示。
etc...
詳しくはmanコマンドなどで見てください。

#主な正規表現
```.``` 任意の一文字。
```*```直前の文字の0回以上の繰り返し。
```[]```カッコ内のいずれか一文字。
　　　- : 範囲を指定。
　　　^ : カッコの中以外。
```^```行頭。
```$```行末。
```\```エスケープ文字。
```^$``` 空白行を表す。
###使用例
例えば以下だと、sample.txt内のaで始まり、任意の数の数字が入り、zで終わる行を検索ができる。

```
grep '^a[0-9]*z$' sample.txt
```
正規表現がシェルのメタキャラクタとして解釈されないようにシングルクォーテーションをつけたほうがいいらしい。
#拡張正規表現

```+``` 直前の文字の1回以上の繰り返し。
```?``` 直前の文字の0もしくは1回の繰り返し。
```|``` 左右いずれかにマッチ。
```{n}``` 直前の文字のn回の繰り返し。
```{n,m}```直前の文字のn回からm回の繰り返し。

###使用法
以下のコマンドのどちらかを使用。
・grep -E
・egrep
###使用例
x86もしくはx64が含まれる行を検索しています。

```
grep -E 'x[86|64]'
```
下は郵便番号の正規表現です。

```
egrep '[0-9]{3}-[0-9]{4}'
```

#その他
以下を組み合わせることで幅広い表現ができる。
```/d```0-9までの数字1文字
```/b```英数字とそれ以外の文字の境界
```/s```空白文字、タブ、改行コード1文字
```/w```単語に使用される任意の文字
```()```グループ化
```/n (n=数字)```前方参照構成体。前方のグループ化文字列と一致する
```*?```できるだけ少ない繰り返しを処理する最初の一致
```+?```1回以上。できるだけ少ない繰り返し

など多数あります。



最長一致の原則を知らないとバグを埋め込んでしまう可能性があるので正規表現はあまり積極的には使いたくない。

**間違いがありましたらご指摘ください。**
変数と定数



#const
- ブロックスコープ（{}外では参照できない)
- 再代入禁止
- 値が変わらないのでコードが読みやすい
- オブジェクトなどの値は変更可能

```php
const test = 'hoge';
test = 'fuga'; //エラー
```
#let
- ブロックスコープ
- 再代入可能
- 同名変数を許可しない
- より細かく変数の有効範囲を管理できる
- ループ処理（for文）等、あらかじめ変数の中身が変化することが分かっている場合に使う

```php
let hoge = 'hoge';
hoge = 'hogehoge';

console.log(hoge);//hogehoge

```

#ver
- 同名変数が許可される（バグの可能性あり）
- 関数スコープ
- ES6以前の命令


#まとめ

- 変数宣言は基本的に <code>const</code>で
- 変数への再代入が必要な場合に限り<code>let</code>を使う
- 原則 <code>var</code>は使わない

| 変数 | 再代入 | 再宣言 | 関数内宣言 | ブロック内宣言 |
|:-----------|------------:|------------:|------------:|------------:|
| const      | ×        | ×       | ブロック       | ブロック      | 
| let        | ○        | ×       | ブロック       | ブロック |
| var        | ○        | ○       | ブロック       | グローバル    |
| 宣言省略<br>（非strict mode） | ○         | ×      | グローバル  | グローバル
screenコマンドで擬似端末（pseudo terminal）を開く

シリアル通信アプリをハードウェアなしでもデバッグできることを期待して、screenコマンドで擬似端末を開くことを試したのでメモ。

# スレーブ側を開く

開きたい擬似端末を`tty{$ID}`/`pty{$ID}`の組、ボーレートを`$BAUDRATE`として、

```console
% screen /dev/tty${ID} ${BAUDRATE}
```

# マスタ側を開く

スレーブ側を先に開いた状態にて、

```console
% screen /dev/pty${ID} ${BAUDRATE}
```

# 動作チェック

開いたマスタ側に標準入力を与えると、開いたスレーブ側の標準出力に与えた内容が表示される。
逆に、開いたスレーブ側に標準入力を与えると、開いたマスタ側の標準出力に与えた内容が表示される。

終了する際は`Ctrl+a→k`。

# 未確認事項

- `/dev/ptmx`と`/dev/pts/${ID}`の組でも同様に開けるか（Macでpts側のスペシャルファイルが見つけられなかった）

# 参考文献

- [screen コマンドでシリアル通信 for Mac & Linux @hideyuki ](https://qiita.com/hideyuki/items/9258f33180d98ad0cb1e)
- [pts - スペシャルファイル (デバイス)の説明 - Linux コマンド集 一覧表](https://kazmax.zpp.jp/cmd/p/pts.4.html)
【PartiQL】INSERT文備忘録

# はじめに

DynamoDBのサンプルデータを作成する際にJSONを書くのが嫌すぎるので**PartiQL**のINSERT文を使いたいと思い備忘録としてまとめてみました。

# この記事で扱わないこと

DynamoDBにはバイナリ型、Null型がありますが、本記事では**PartiQL**を用いたバイナリ型データ、Null型データの挿入は扱いません。（個人的に使うことがなさそうなので。使いたくなったら追記します。）

# 基本構文

```
INSERT INTO table VALUE item
```

# String

```
INSERT INTO test VALUE {'PK' : '1', 'Str': 'Hello World'}
```

# Number

```
INSERT INTO test VALUE {'PK' : '2', 'Num': 100}
```

# Boolean

```
INSERT INTO test VALUE {'PK' : '3', 'Bool': TRUE}
```

# List

各要素の型は異なる型でも良いです。

```
INSERT INTO test VALUE {'PK' : '4', 'List': ['hoge', 100]}
```

# Map

```
INSERT INTO test VALUE {'PK' : '5', 'Map': {'key': 'value'}}
```

# Set

同一の型の集合です。
順序は保証されません。
各要素はセット内で一意でなければいけません。

## String

```
INSERT INTO test VALUE {'PK' : '6', 'StrSet': <<'val1', 'val2'>>}
```

## Number

```
INSERT INTO test VALUE {'PK' : '7', 'NumSet': <<1, 2>>}
```
Hinemos 6.2 を CentOS7 にインストール

~~~bash
# ■実行環境
# CentOS 7
# Hinemos 


# ■事前準備
# 1. OSインストール後アップデート
yum update

# 2. Hinemos のパッケージダウンロード
# https://github.com/hinemos/hinemos/releases/tag/v6.2.2
# hinemos-6.2-manager-6.2.2-1.el7.x86_64.rpm
# hinemos-6.2-web-6.2.2-1.el7.x86_64.rpm

# 3. 2 を /tmp に配置
cd /tmp
ll

# 4. SELinuxの無効化
getenforce                                          # 現在の設定確認
cp -p /etc/selinux/config /etc/selinux/config_org   # バックアップ
vi /etc/selinux/config                              # 編集
# ここから
SELINUX=disabled                                    # 無効にする場合
# ここまで
shutdown -r now                                     # 設定を反映させるには再起動が必要
getenforce                                          # 現在の設定確認

# 5. 関連パッケージのインストール
yum -y install java-1.8.0-openjdk
yum -y install unzip
yum -y install vlgothic-p-fonts
yum -y install vim-common

# 6. firewall
firewall-cmd --list-services --zone=public --permanent
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload


# ■Hinemos マネージャのインストール
# 1. インストール
cd /tmp
rpm -ivh hinemos-6.2-manager-6.2.2-1.el7.x86_64.rpm
# => /opt/hinemos にインストールされます。

cat /opt/hinemos/etc/hinemos.cfg | grep "export LANG"
# => ja_JP.UTF-8 であること

# 2. サービスの起動
service hinemos_manager start
# => Redirecting to /bin/systemctl start hinemos_manager.service のみ表示されればOK

service hinemos_manager status
# => Active であること

service hinemos_manager status
# => Active であること

systemctl list-unit-files | grep hinemos
# => 自動起動の設定は自動で行われる


# ■Hinemos Webクライアントのインストール
# 1. 事前確認
locale | grep LANG
# => LANG=ja_JP.UTF-8 であること

# 2. インストール
cd /tmp
rpm -ivh hinemos-6.2-web-6.2.2-1.el7.x86_64.rpm

cat /opt/hinemos_web/conf/hinemos_web.cfg | grep "export LANG"
# => ja_JP.UTF-8 であること

# 3. サービスの起動
service hinemos_web start
# => Redirecting to /bin/systemctl start hinemos_web.service のみ表示されればOK

# 4. 接続確認
http://xxx.xxx.xx.xx/
ユーザー名：hinemos
初期パスワード：hinemos
~~~
【VR】アバターの表情に関する考察

#サマリ
VR空間で話をしていると、アバターの表情が読み取れるような感じがすることありませんか？アバターの表情があまり変化しないとしても。

ありますよね！！(^^)

この感覚、不思議だなーと思っていたのですが、
ふと「能面」もお面なのに表情を感じることがあるな、と思った訳です。
ちょっと調べてみると「能面」にはいくつもの感情を読み取れる仕掛けがあることがわかりました。
「能面」の各顔パーツが異なる情動を表現しているそうで、「情動キメラ」というそうです。
眉毛と目と口がそれぞれ違う表情を感じるように作られていて「能面」の角度によって違う表情に見えると。

詳しくはコチラ↓
[■名大と東大、「能面」が多様な表情に見えるのは「情動キメラ」が理由と解明](https://news.mynavi.jp/article/20121122-a153/)

この能面の「情動キメラ」、VR空間のアバターでも同様に感じるのか実験してみました。

#準備
実験で使うアバターを用意します。
VR空間としては写真からアバターを作成できるSpatialを使用します。
それでは「能面」の写真を使ってアバターを作ってみましょう。

![能面アバター1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/42baf3ac-204a-b91f-3016-ea54e6017c51.png)


怖いですね。。。
僕のFBの写真はこの実験で作った能面アバターです。

#実験
能面アバターの顔の角度を変えていろいろな表情を感じるか実験してみましょう。

- 正面(基本形)

![能面アバター_正面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/25c656f0-b441-1814-c3b3-16349ed5b475.png)
あまり表情は感じないですね。証明写真みたい(^^)

- 上向き

![能面アバター_上向き.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/a73aa160-6299-4100-1516-1bf0d222490a.png)

どうでしょうか？正面とちがって笑っているようにみえませんか？
目が三日月みたいになっているところがポイントでしょうか。

- 下向き

![能面アバター_下向き.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/6346ec26-b7ee-d6c0-c19c-84da2f1cd9f4.png)

不機嫌そうに睨んでいるように感じますね。悪いこと考えてそう(^^;
正面や上向きとちがって眉毛がまっすぐになっています。

- 斜め上

![能面アバター_斜め上.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/c1a12fdf-4c14-4b52-f63a-7f582c3fb981.png)

希望に胸を膨らませている感じ？
明るさやポジティブな感情を感じますね。

- 斜め下

![能面アバター_斜め下2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/8eb23ba5-32f9-4b57-08e9-a32fa5f52862.png)

何か悩み事でもあるんでしょうか。
身の回りにこんな表情の人がいたら要注意です。メンタル系の病院につれていってあげましょう(^^)
悲しみや憂いを感じる一方で、子供やかわいい小動物を見るような優しい表情も感じました。

#考察
実験を行った顔の角度と感じる表情をまとめます。

|顔の角度|感じる表情|
|---|---|
|正面|無表情|
|上向き|笑顔|
|下向き|不機嫌・睨む|
|斜め上|希望・ポジティブ|
|斜め下|悲しみ・慈しみ|

表情が動かない能面アバターでも顔の角度によって違う表情を読み取れることが確認できました。
論文にあったように、眉毛や目の形の変化が表情に関係しているように感じます。
論文では口の形(口角の向きなど)が大きく影響するとのことでしたが、口からはあまり表情を感じませんでした。
Spatialはリップシンクで口を動かすのでもともとの能面の口とは少し形が違うのかもしれません。
情動キメラの論文とは読み取れる表情が違うようですが、そのあたりが影響しているのかもしれません。
実験してみて顔の向き自体もも表情に影響するのかなと感じました。

みんながみんな能面のように計算されたアバターではありませんが、アバターに表情を感じる一つの要因になっているんでしょうね。



# 最後に。。。
![能面アバター_ホラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/85f5e28a-291c-0b47-079c-8d13d698c0b6.png)
死んでる！！

#　
チームハイエナ <img width="120" alt="hyaeninae_tomei.png"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/99b448d3-7ff0-58f3-302b-8528cf339b8d.png">
【Flutter】下タブでの画面切り替えを実装

## 概要
下タブの実装にはBottomNavigationBarを使います

## コード
```dart 
import 'package:flutter/material.dart';

class Navigation extends StatefulWidget {
  @override
  _NavigationState createState() => _NavigationState();
}

class _NavigationState extends State<Navigation> {
  // 選択中のIndex
  int _selectedIndex = 0;
  // タブ分けするウィジェット
  List<Widget> _widgetList = <Widget> [
    Text('1'),
    Text('2'),
    Text('3'),
  ];
  // ナビゲーションアイテムをタップしたら選択中Indexを変更
  void _navigationItemTap(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('test'),
      ),
      body: Center(
        child: _widgetList.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.timer), label: 'Timer'),
          BottomNavigationBarItem(icon: Icon(Icons.watch_later_outlined), label: 'Stop Watch'),
          BottomNavigationBarItem(icon: Icon(Icons.access_alarm), label: 'Alarm'),
        ],
        currentIndex: _selectedIndex,
        onTap: _navigationItemTap,
        selectedFontSize: 13.0,
        selectedItemColor: Colors.white,
        unselectedFontSize: 10.0,
        unselectedItemColor: Colors.grey,
        backgroundColor: Colors.black,
      ),
    );
  }
}
```
_widgetListに別画面のWidgetを入力すれば画面遷移もOK！
[CSS] width:100% と width:auto の違い

# はじめに

質問されたときにパッと答えられなかったので記事にまとめました！

## width: 100%とは？

widthにpaddingとborderは含まれない

widthの幅指定にpaddingとborderが含まれないため、HTMLの子要素にwidth:100%を指定したうえで、paddingとborderを指定してしまうと、親要素から子要素がはみ出て画面に表示される


### サンプルコード

```html

<div class='parent'>
 <div class='children'>children</div>
</div>

.parent {
  width: 400px;
  height: 200px;
  background-color: red;
}

.children {
  width: 100%;
  height: 150px;
  border: 10px solid blue;
  background-color: yellow;
}

```

### デザイン

![width.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508390/f79ac726-4ba2-0ee6-5b27-8b9dfb52e423.png)

## width: autoとは？

widthの中にpaddingとborderが含まれる

widthの幅指定にpaddingとborderが含まれるため、HTMLの子要素にwidth:autoを指定したうえで、paddingもしくはborderを指定しても、親要素から子要素がはみ出ないで画面に表示される

### サンプルコード

```html

<div class='parent'>
 <div class='children'>children</div>
</div>

.parent {
  width: 400px;
  height: 200px;
  background-color: red;
}

.children {
  width: auto;
  height: 150px;
  border: 10px solid blue;
  background-color: yellow;
}

```

### デザイン

![width2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508390/92d20caf-b064-8a29-e1f8-ce70e71026a3.png)
親要素から子要素がはみ出ないで表示されていますね

# 結論

width: 100%を指定するとwidthにpaddingとborderは含まれない
width: autoを指定するとwidthにpaddingとborderは含まれる
[chrome拡張機能]求む！storageのいい感じのラップ方法

# chrome拡張機能でstorageをラップしたい

## 要約
　chrome拡張機能を開発する時って、コールバックばっかりでしんどいですよね。特にstorageみたいな使う頻度が高くなりそうなapiは、できればpromise化して使いやすくしたいです。（拡張機能でにそこまでやる必要ある？みたいな話もありますが）
　この記事ではstorageをクラスとしてまとめてみたのですが、もうちょっといい感じにならないものかと思い記事にしてみた次第です。ご意見いただけたらうれしいです。
　勿論、どう使うかによっても色々考え方変わると思いますが、一旦ある程度汎用的に使えるものを想定して下記クラスを作成しています。

## 前提情報
・storageのデータ保存方法は所謂key-value方式。
・一個のオブジェクトへ保存していくイメージ。
※他にも色々制約などがありますが下記リンクにて

[公式リファレンス](https://developer.chrome.com/docs/extensions/reference/storage/)
[わかりやすい説明](https://qiita.com/dhun/items/cf18e43cb0376fcff302)

## raz的な実装イメージ

### storageのinterface・抽象クラス

``` storage.ts
export type StorageType = 'local' | 'sync';

export interface StorageInterFace<T> {
  readonly key: string;
  initializeData(): T;
}

export interface StorageData {
  isInitialized: boolean;
}

export abstract class Storage<T extends StorageData> implements StorageInterFace<T> {
  private storage: chrome.storage.LocalStorageArea | chrome.storage.SyncStorageArea;
  readonly key: string;
  protected constructor(key: string, saveType?: StorageType) {
    this.key = key;
    this.storage = saveType === 'sync' ? chrome.storage.sync : chrome.storage.local;
  }

  save = async (data: T) => {
    // keyのつけ外しをこのクラス内でやってあげることで、データの扱いが無茶苦茶やり易いはず。
    const saveObject = {
      [this.key]: data,
    };
    return await new Promise((resolve, reject) => {
      this.storage.set(saveObject, () => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
        }
      });
    });
  };

  load = async (): Promise<T> => {
    return await new Promise((resolve, reject) => {
      this.storage.get(this.key, async (result) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
        }
        // 普通のSaasとかと違ってDB（storage）の環境設定とかがあらかじめできるわけではないので、
        // 初回データアクセス時はundifinedの判定と初期データの作成をしてあげる必要があります。
        const data = result[this.key] as T;
        if (!data?.isInitialized) {
          const initData = this.initializeData();
          await this.save(initData); 
          resolve(initData);
        }
        resolve(result[this.key] as T);
      });
    });
  };

  abstract initializeData(): T;
}
```

### 実装クラス（一例）

```config.ts
import { StorageData, StorageType, Storage } from './Storage';

interface ConfigData extends StorageData {
  storageType: StorageType;
}

const config_key = 'custum_tabGroup_config';

export class ConfigStorage extends Storage<ConfigData> {
  // initをstatic化しているのは他のkeyの値を参照したいケースがあると思っているため。
  // （例えばメインの大きめなデータはlocalに保存するかどうか設定として持っておくかどうかを選べる様にするとかがある想定です。）
  static init = () => new ConfigStorage(config_key, 'sync');

  initializeData = (): ConfigData => ({ isInitialized: true, storageType: 'sync' });
}
```

## 宣伝
本当に大した機能じゃないですが、拡張機能リリースしたのでよかったらみてみてください。
githubもpublicにしてみました。
https://github.com/R-Az/custum_tabGroup
https://chrome.google.com/webstore/detail/tabgroupcustoms/aiidfmkcfamdjancnfkppnbhakahcndm?hl=ja
SQLでNULLを使うときの注意点まとめ


### 1. NULLは値ではない。

NULLは`未知`または`適用不能`を意味する。値ではなく、そこに値が存在しないことを示す記号である。

### 2. 述語をまともに適用できず、適用すると`unknown`が生じ、SQLが直感に反する動作をする。

NULLに比較述語を適用した結果、常に`unknown`となる。
単純な例として、

```sql
SELECT * FROM tbl WHERE col = NULL;
```

これは、NULLの行を選択することはできない。
何故ならば、`col = NULL`とするとこの評価値は`unknown`となる。クエリの結果として選択されるのは評価値が`true`の行のみである。

以下が正しい。

```sql
SELECT * FROM tbl WHERE col IS NULL;
```

### 3. 第3の真理値`unknown`

SQLの世界には第3の真理値である`unknown`が存在する。
true,false,unknownの間に次のような優先順位があると考えるとわかりやすい。

* ANDの場合: false > unknown > true
* ORの場合: true > unknown > false

## 問題を引き起こすSQLの例

### 排中律が成立しない

```sql
SELECT * FROM students WHERE age = 20 OR age <> 20;
```

このSQLはageがNULLのレコードを選択しない。

### CASE式

```sql
CASE col_1
  WHEN 1    THEN 'o'
  WHEN NULL THEN 'x'
END
```

この式は絶対に`x`を返さない。2つ目のWHEN句が`col_1 = NULL`の省略形であるため。

## 対策

テーブルにNOT NULL成約をつけて極力NULLを排除し、以下の指針を検討する。

* コード値の場合、未コード化用コードを割り振る
* 名前の場合、「名無し」を割り振る
* 数値の場合、0で代替する
* 日付の場合、最大値、最小値で代替する
VPS上のdocker-composeがハングする(異常に遅い)問題

## 環境

* Ubuntu 20.04
* docker 20.10.5
* docker-compose 1.28.6

## 問題
バーチャルプライベートサーバー(VPS)にdockerとdocker-composeを

* [UbuntuへDockerをインストール](https://qiita.com/sanotaku/items/8a2cc7058cdcb9571a24)
* [How To Install and Use Docker on Ubuntu 20.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04)
* [How To Install and Use Docker Compose on Ubuntu 20.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-20-04)

辺りを参考にしてインストールしたところ、インストール自体はうまく行ったが、docker-compose が異常に遅い。ほとんどハングしている感じになった。

    $ time docker-compose --version
    docker-compose version 1.28.6, build 5db8d86f
    
    real	0m55.659s
    user	0m0.827s
    sys 	0m0.144s

このくらいで済む時もあるし、もっと遅かったり、もうちょっと早い時もある。

## 原因
乱数を作るデバイス /dev/random が、VPSだとエントロピーが足りないらしく、docker-compose が乱数を使おうとしたときにたっぷり待たされてしまうことが原因らしい。以下に該当しそうな議論があった。

* [docker-compose often takes a long time to do anything #6552](https://github.com/docker/compose/issues/6552)
* [docker-compose hangs #6678](https://github.com/docker/compose/issues/6678)

実際それが原因かどうかは、entropy の大きさを調べて見ればいい。

    $ cat /proc/sys/kernel/random/entropy_avail 
    45

この数字が小さい(< 1000)と python の乱数生成が遅くなって、python で書かれている docker-compose が遅くなるということらしい。

## 解決策
haveged と言うパッケージをインストールする。

    $ sudo apt-get install -y haveged

解決したか確認。

    $ time docker-compose --version
    docker-compose version 1.28.6, build 5db8d86f

    real	0m0.906s
    user	0m0.784s
    sys 	0m0.121s

1秒以下ということで、こんなもんかな。

この haveged は、https://wiki.archlinux.jp/index.php/Haveged に説明がある通りで、「haveged は仮想環境で質の高いエントロピーを作れるのかどうか疑問があります。Haveged は rdtsc 命令を使用していますが、仮想マシンでこの命令が仮想化されるとエントロピーが低品質になってしまいます。」と言うことです。/dev/random で得られる乱数の質に影響があるかもしれないことを理解した上で使ってください。
Laravel 8でObserverを使ってレコード操作ユーザー記録機能を実装する

# Observer作成
> 【前提】レコード操作ユーザーの記録対象とするModelのテーブルに、下記のカラムが定義されていること。
> * created_by
> * updated_by
> * deleted_by
> * restored_by

* artisan make:observerで作成

```console
php artisan make:observer AuditObserver

Observer created successfully.
```

> app/Observers/AuditObserver.phpが作成される。

* app/Observers/AuditObserver.php

```php
<?php

namespace App\Observers;

// ①追加：ここから
use Illuminate\Database\Eloquent\Model;
// ①追加：ここまで

class AuditObserver
{
    // ②変更：BEFORE
    //
    // ②変更：AFTER
    /**
     * 当該モデルのcreated_byに操作を実行したユーザーのIDをセットする
     *
     * @param  Model  $model
     */
    public function creating(Model $model)
    {
        $model->created_by = auth()->user() ? auth()->user()->id : 0;
    }

    /**
     * 当該モデルのupdated_byに操作を実行したユーザーのIDをセットする
     *
     * @param  Model  $model
     */
    public function updating(Model $model)
    {
        $model->updated_by = auth()->user() ? auth()->user()->id : 0;
    }

    /**
     * 当該モデルのupdated_byに操作を実行したユーザーのIDをセットする
     *
     * @param  Model  $model
     */
    public function saving(Model $model)
    {
        $model->updated_by = auth()->user() ? auth()->user()->id : 0;
    }

    /**
     * 当該モデルのdeleted_byに操作を実行したユーザーのIDをセットする
     *
     * @param  Model  $model
     */
    public function deleting(Model $model)
    {
        $model->deleted_by = auth()->user() ? auth()->user()->id : 0;
    }

    /**
     * 当該モデルのrestored_byに操作を実行したユーザーのIDをセットする
     *
     * @param  Model  $model
     */
    public function restoring(Model $model)
    {
        $model->restored_by = auth()->user() ? auth()->user()->id : 0;
    }
    // ②変更：ここまで
}

```

# trait作成

```bash
mkdir -p app/Traits
```

* app/Traits/AuditObservable.php

```php
<?php

namespace App\Traits;

use App\Models\User;
use App\Observers\AuditObserver;

trait AuditObservable
{
    public static function bootAuditObservable()
    {
        self::observe(AuditObserver::class);
    }

    /**
     * レコード作成ユーザーを取得して返す
     *
     * @return mixed
     */
    public function createdBy()
    {
        return $this->hasOne(User::class, 'id', 'created_by');
    }

    /**
     * レコード更新ユーザーを取得して返す
     *
     * @return mixed
     */
    public function updatedBy()
    {
        return $this->hasOne(User::class, 'id', 'updated_by');
    }

    /**
     * レコード削除ユーザーを取得して返す
     *
     * @return mixed
     */
    public function deletedBy()
    {
        return $this->hasOne(User::class, 'id', 'deleted_by');
    }

    /**
     * レコード復元ユーザーを取得して返す
     *
     * @return mixed
     */
    public function restoredBy()
    {
        return $this->hasOne(User::class, 'id', 'restored_by');
    }
}

```

# ModelクラスでAuditObservableトレイトを読み込み
* app/Models/Post.php

```php
<?php

namespace App\Models;

// ①追加：ここから
use App\Traits\AuditObservable;
// ①追加：ここまで
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    // ②追加：ここから
    use AuditObservable;
    // ②追加：ここまで
    use HasFactory;
    use SoftDeletes;

    // ...
}

```
Node.jsライブラリのPuppeteerでスクショしてみた

業務でNode.jsライブラリのPuppeteerが中心的な役割の部分を触っているのでその学習の為に導入して動かしてみようと思いました。

##Puppeteerとは？
公式サイト：https://pptr.dev/
パペティアと読みます。Node.jsライブラリで、Google製。
GoogleのWebブラウザ「Chrome」は、UIを持たずコマンドラインやリモートデバッグ機能を通じてWebブラウザを操作できる「Headless Chrome」機能を備えています。Headless Chromeを利用すると人間がWebブラウザをマウスやキーボードで操作することなく、プログラムでHeadless Chromeを起動し、特定のWebページを読み込み、画面キャプチャの取得や、指定された場所をクリックし、値を入力し結果を取得する、といった操作を自動的に行わせることができるようになります。

UIの自動テストとか、スクレイピングなどでも使えて汎用性が高いのですが、この記事ではあくまでもスクショ機能だけを触れていきます。

##導入
早速動かしてみましょう、適当に作業ディレクトリを作って、以下のどちらかのコマンドでPuppeteerをインストールします。

```
npm i puppeteer
or
yarn add puppeteer
```

まずは公式ドキュメントに載ってる超基本のコードでスクショしてみましょう。
example.jsというファイルに以下のコードを書きます。

```javascript
const puppeteer = require('puppeteer');

(async () => {
  //ヘッドレスブラウザの起動
  const browser = await puppeteer.launch();
  //タブを開く
  const page = await browser.newPage();
  //指定したURLに遷移
  await page.goto('https://qiita.com/hisashi_matsui');
  //スクショを撮り、ファイル名example.pngにする。
  await page.screenshot({ path: 'example.png' });
  //終了
  await browser.close();
})();
```

実行します

```javascript
node example.js
```

するとルート直下にスクショのPNGファイルが保存されます！
![スクリーンショット 2021-03-29 23.05.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173182/9347215a-9a29-a97b-501e-699a09bdab25.png)


これだけだと、あくまでも基本中の基本なので、もう少しカスタマイズしていきましょう。


**ブラウザのサイズを設定**
デフォルトだと800 × 600になります。

```javascript
setViewPort({
  width: 1900,
  height: 1200
})
```

**evaluateメソッド**
これを使うと、Nodeではなくブラウザ上(Headless Chrome)でJavaScriptを実行できます。Puppeteerが提供していない高度な処理が必要な場合や、Webページに埋め込まれたJavaScriptを実行する場合などに使用します。

```javascript
const docTitle = await page.evaluate(() => {
  return document.title
});

console.log(docTitle)
//このコンソールは当然コマンド上に出力されます
```

第一引数内の関数に引数を渡す場合は第二引数に入れる必要があります。

```javascript
const a = 15;
const b = 5;
const sum = await page.evaluate((a, b) => {
  return a + b
}, a, b);

console.log(sum) //結果は20
```

**screenshotのオプション**
clip: スクショ範囲を細かく指定できます。x,y座標でどこから縦横何pxを撮影するかを設定できます。

path: ファイルの保存先を指定
（Node.js の標準モジュール path が提供している path.join メソッドを使用して、ディレクトリ名あるいはファイル名を結合、この場合あらかじめscreen_shotsという名のフォルダを用意する必要があります）

```javascript
const path = require('path');
const filepath = path.join(__dirname, 'screen_shots', 'example.png');

await page.screenshot({
  clip: { x: 100, y: 100, width: 300, height: 300 },
  omitBackground: true,
  path: filepath
});
```

##まとめ
このPuppeteerはドキュメントが比較的読みやすかったですし、関連記事も多かったです。
ちなみに、リリース当初はグラデーションとか複雑な描画に弱かったらしいのですが、今は改善されてるみたいです。
関数と所有権の移動 (Rust)

# 所有権の移動

* 所有者が関数の実引数として渡される時、所有権は関数の仮引数に**移動**します。
* そのため、移動後は元の関数内の変数は使用できなくなります。

例:

```rust
struct Foo {
    x: i32,
}

fn do_something(f: Foo) {
    println!("{}", f.x);
    // ② : 引数fはここでドロップします。
}

fn main() {
    let foo = Foo { x: 13 };
    // ① : 変数fooの所有権はdo_somethingに移動します。
    do_something(foo);
    // ③ : 変数fooは使えなくなります。
}
```

[実行結果]

```
❯ cargo run
   Compiling variables v0.1.0 (/Users/yoshitaka.koitabashi/Desktop/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 1.28s
     Running `target/debug/variables`
13
```

## 所有権を関数から返却する

* 下記のように所有権を関数から返却する方法もあります。
* ただ、下記のような処理が複数書かれ、それにより所有権を取ったり戻したりすることを関数で行うとかなり複雑になります。
* これを回避する方法が**参照**と呼ばれる機能です。

例:

```Rust
struct Foo {
    x: i32,
}

fn do_something() -> Foo {
    Foo { x: 13 }
    // ②：所有権が関数に移動します。
    // ③：所有権は関数(do_something)外に移動します。
}

fn main() {
    let foo = do_something();
    // ①：変数fooは所有者になります。
    // ④：関数のスコープの終端により、変数fooはドロップします。
}

```

# 参考文献
* [THE BOOK 4章](https://doc.rust-lang.org/book/)
* [Tour of Rust](https://tourofrust.com/)