OmniAICreator/Qiita-1.07M huggingface dataset:
Autify で Salesforce を動かしてみよう～ vol.4 もっと詳細なブラウザ情報ってとれるの？

# はじめに
- Autify で Salesforce を動かしてみよう、と思い記事にしてみます。
- TIPSなども記載できれば、と考えています。

#### ご了承ください
- まだまだ勉強中の部分もあります。間違っている箇所もあるかもしれません。
- Salesforce、Autify は、この時点のバージョン(2021年1月～3月頃) での内容になります。今後、仕様変更が変わることによって、内容の通りにならない可能性もあります。ご了承ください。
 - また、URLなども変更になっている可能性もあります。

# 前回まで
- Autify で Salesforce を動かしてみよう～ vol.0 準備編
 - https://qiita.com/xx_mana/items/107eb97dcc0da26daeb8
- Autify で Salesforce を動かしてみよう～ vol.1 ログインへの道
 - https://qiita.com/xx_mana/items/7f532a977184037ea80c
- Autify で Salesforce を動かしてみよう～ vol.2 JSステップ・現在の日時
 - https://qiita.com/xx_mana/items/1642075b7fdb4950d419
- Autify で Salesforce を動かしてみよう～ vol.3 文字色のエラーチェック
 - https://qiita.com/xx_mana/items/59e1cf5275ef0656d7c9

# ブラウザの情報
- ある日のこと
- 😳「なんか、画面崩れ起こしているよ？？」
- 🐹「えっ？そんなことないよ？？？」
- 🐸🐺「？？？？」

原因を調べたら、ブラウザのバージョン違い、それもマイナーバージョンによるものでした。

- 👱「Autify はバージョン情報わかるんでしたっけ？」
- 私「はい、わかります、こんな感じです」

- 「テストプラン」で実行環境を「Chrome」を指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/72cf594e-4534-a894-2fc1-0d17daeaf3ea.png)

- 「テストプラン」で実行環境を「FireFox」を指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/08f7a4fa-10bc-9511-a87d-bb8798871075.png)

- 「テストプラン」で実行環境を「Edge」を指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/998f299f-4714-23c4-c059-7b3005a38c48.png)


- 私「実行結果もバージョンは表示されてます」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/7f820f72-6a24-b2ff-a77e-44d0e2b4f1c5.png)


- 👱「マイナーバージョンはわからないのかな…」

- 私「🙉」



# やってみよう！

- JSステップを用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/ec738385-ce92-3a40-3925-7903d6222ff9.png)

```javascript:JSステップ
var userAgent = window.navigator.userAgent;
return userAgent;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/0e5fc1cb-ce67-bc90-9ce9-072288130af1.png)

JSステップの結果を利用します。

どうなるでしょうか。

- Chrome
 - 88.0.4324.150 とマイナーバージョンまで判断できそうです。

```
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36
```

- FireFox
 - 85.0 のようですね。

```
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0
```

- Edge
 - 88.0.705.50 なのかな？

```
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.50
```

- IE
 - IE の細かいバージョンは取れないようですね。

```
Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko
```

# まとめ
- 上記の方法で取得、DBなどに保存することで、どの詳細なブラウザバージョンで実行したのか、わかると思います。
- シナリオに含めて毎回実施するのも良いでしょうし、一日一回に実施するような専用のシナリオを作っても良いでしょう。

# 更新履歴
- なし
動画ファイルをgifへ変換する

#はじめに
gifアニメーションの作り方は調べればたくさん出てきますが、よく使う割に毎回調べるのが手間だったので、メモとして残させていただきます。
gifアニメーションはQiitaの記事でビジュアル化したい際はもちろん、teratail等でプログラミングの質問をする際や、GithubでわかりやすいREADMEを書くとき等、用途は多岐に渡るので、忘れたら毎回この記事に戻ってこようと思います。

#gifアニメーション作成方法
###Homebrewインストール
[Homebrew](https://brew.sh/index_ja)が入っていない場合、↓のコマンド（**2021/4/3時点**）でHomebrewをインストール

```bash
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

```bash
$ brew -v
Homebrew 3.0.4
```

###ffmpegをインストール
gifへの変換はffmpegを使用します。
[ffmpegのページ](https://www.ffmpeg.org/)からもインストールできますが、今回はHomebrewでやっていきます。

```bash
$ brew install ffmpeg
```
インストールできているかも一応確認します。

```bash
$ ffmpeg
```
これでエラーが起きずにコマンドが動作していればインストール完了です。

###動画ファイルをgifに変換
変換したい動画ファイルがあるディレクトリに移動します。
今回はデスクトップに動画ファイルを置いているので、デスクトップに移動して作業します。

```bash
$ cd Desktop
```
```bash
$ ls
movie.mov
```
このmovie.movをgifへ変換したいと思います。

```bash
ffmpeg -i movie.mov -r 10 sample.gif
```
`i-`の後ろの`movie.mov`は変換前の動画ファイル、`sample.gif`は変換後のgifファイルです。

`-r`の後ろの数字は1秒間に表示したい画像の数、画像数が多いほどgifはスムーズだが容量大きいということです。
今回は10にしていますが、`-r 5`にすれば容量は半分になります。

###gifファイルのプレビュー
gifファイルをそのまま開くと画像のプレビューになってしまうので、動きが確認できません。
なので、該当gifファイルを選択したら、**`スペースキー`**を押すと、gifをプレビューできます。

###gifファイルのをQiita記事に投稿
Qiitaの場合、gifファイル投稿はQiitaの下書き画面にドラッグアンドドロップでできます。
以下もgifファイルです。あるのとないのでは見やすさが違うので、積極的に活用していきたいと思います。

![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493982/97c66207-5a61-d630-2c4a-2d01c8abbab7.gif)
documentとHTMLElementにgetElementByXPath定義する

ブラウザのコンソールでのちょっとした作業用。探せば色々見つかるのだけど、 `document`に対してだけではなく、どの`HTMLElement`に対しても実行できるところまでまとまってるのはあまりないようだったので。

```javascript
(() => {

  const __getElementByXPath = function(path, root) {
    const result = document.evaluate(path, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
    return result.snapshotLength > 0 ? result.snapshotItem(0) : null
  }
  const __getElementsByXPath = function(path, root) {
    const array = []
    const result = document.evaluate(path, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (let i = 0; i < result.snapshotLength; i++) {
      array.push(result.snapshotItem(i));
    }
    return array;
  }

  document.getElementByXPath = function(path) {
    return __getElementByXPath(path, this)
  }
  document.getElementsByXPath = function(path) {
    return __getElementsByXPath(path, this)
  }
  HTMLElement.prototype.getElementByXPath = function(path) {
    return __getElementByXPath(path, this)
  }
  HTMLElement.prototype.getElementsByXPath = function(path) {
    return __getElementsByXPath(path, this)
  }
  
})()
```
node-sassで改行出来なかった話

# 状況
node-sassをインストールして、自動コンパイルさせる設定が上手くいかなかった。

#環境
node: v12.13.0
node-sass: 5.0.0

#実際のコード（抜粋）

main.sass

```
* {
  margin: 0;
}
```
コンパイル時、ターミナルに表示されたエラー

```
{ 
 "message": "Invalid CSS after \"* {\": expected \"}\", was \"{\"",
 "formatted": "Error: Invalid CSS after \"* {\": expected \"}\", was \"{\"\n        on line 1 of public/sass/main.sass\n>> * { {\n\n   ---^\n"
}
```
ええ…sassファイル内で改行出来ないの…

#解決策
問題点：ファイルの拡張子が違った

元々 `hoge.sass` にしていたものを `hoge.scss`に変更したら出来ました。
scssファイルにしなければいけないんですね。知りませんでした。

##番外編：それでも別のエラーが出た
```
Error: EROFS: read-only file system, mkdir '/style.css'
```
解決策：予めstyle.cssを作成するとエラーが出る。コンパイル後に生成されるstyle.cssを使えば問題なし。
【Rails】jQueryを使えるようにする(Webpacker)

#はじめに
この記事ではRailsでjqueryを使うための設定を説明します。
この記事の最後では実際にjqueryが使えているかどうかについて確認する仕方についても載せています

#jQueryを導入する
まずは端末で以下のコマンドを打ちます

```:ターミナル
yarn add jquery
```

次に```environment.js```の編集を行います

```javascript:config/webpack/environment.js
const { environment } = require('@rails/webpacker')
// ↓ 追加
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
//ここまで

module.exports = environment
```

次に```application.js```の編集を行います

```javascript:app/javascript/packs/application.js
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"

Rails.start()
Turbolinks.start()
ActiveStorage.start()
//　↓追加
require('jquery')
```

ここまででjqueryのインストールは完了です
最後にちゃんと設定できているか確認します

#jQueryのバージョン確認
まずはアプリを立ち上げます

```:ターミナル
$ rails s
```
※ここで注意なのですがすでにアプリを立ち上げている人は一度接続を切ってもう一度立ち上げてください

次にデベロッパーツールを開きコンソールで```console.log($.fn.jquery)```と打ちます

![Q3k1N0OIMl7c4HR1617410622_1617410634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268848/7bc87e10-ee6b-ec70-128e-25e5d5a7efdf.png)

そしたら右下にjqueryのバージョンが出てくるとおもいますのでこれが出てきたらちゃんと設定できています
お疲れ様でした。
マイコンベンチマーク

# マイコンベンチマークを実施
身近にあったマイコンのベンチマークを実施。

## 対象とするベンチマーク
ベンチマークのソースコードはいくつか見つかる。ここでは代表的なものかつArduino IDE(Platform)で実行可能なものを取り上げた。

### Dhrystone
定義は[こちら](https://ja.wikipedia.org/wiki/Dhrystone)を参照。主に整数演算処理能力を表す。ソースコードは[こちら](https://github.com/ghalfacree/Arduino-Sketches/tree/master/Dhrystone)を利用。マイコンによっては、結果を得るために繰り返し回数を増やすが必要がある。下記結果表の数値は「VAX MIPS rating」の値である。

### Whetstone
定義は[こちら](https://ja.wikipedia.org/wiki/Whetstone)。主に浮動小数点演算処理能力を表す。ソースコードは[こちら](https://github.com/ghalfacree/Arduino-Sketches/blob/master/Whetstone/Whetstone.ino)を利用。下記結果表の数値は「MIPS」値。

### CoreMark
定義は[こちら](https://en.wikipedia.org/wiki/Coremark)。主に組み込みシステムでのCPU能力を表す。ソースコードは[こちら](https://github.com/PaulStoffregen/CoreMark)を利用。下記結果表の数値は、CoreMark値（と言うらしい）。

## 結果
マイコンクロック（周波数）も記載したが、実行時の正確な数値は不明。

|マイコン|Clock(MHz)|Dhrystone|Whetstone|CoreMark|
|---|---|---|---|---|
|Arduino(ATmega328p)|16|9.85|8.01|※1|
|Nucleo(STM32F303RE: ARM Cortex-M4)|72|32.30|48.66|95.21|
|M5Stack(ESP32: Tensilica Xtensa LX6)|160 or 240?|177.01|70.62|351.25|
|ATOM Matrix(ESP32 pico: Xtensa Tensilica LX6)|160 or 240?|177.01|※2|351.23|
|M5StickV(Kendryte K210: RV64IMAFDC) *3|400|417.73|317.46|650.62|
|NodeMCU(ESP8266: Tensilica Xtensa LX106)|80|※4|※4|※4|
|Wio Terminal(ATSAMD51P19: ARM Cortex-M4F)|120 or 200?|99.53|50.00|211.42|
|Seeeduino XIAO(SAMD21G18: ARM Cortex-M0+)|48|26.49|2.04|51.93|
|Spresense(CXD5602: ARM Cortex-M4F)|156?|82.57|66.36|199.32|
|Longan Nano(GD32VF103CBT6)|108|※5|※5|※5|

　　※1 リブートを繰り返し計測できず
　　※2 Buildできず
　　※3 PlatformIO利用、「platformio.ini」に「upload_speed = 115200」追加
　　※4 Arduino IDE、Platform IOの両者でも「Soft WDT reset」が発生し計測できず
　　※5 Arduino IDEで動作せず、PlatformIOでBuildできず（コード修正も試みたが）

### 少しだけ考察

- マイコン周波数が高いほどPerformanceよし
- ここではM5Stickの性能が際立つ
- MtStack5とATOM Matrixはマイコンが同じESP32なので結果はほぼ同じ
GASで別のHTMLファイルをインクルードする

# はじめに

「画面の共通部分を部品化して、複数の画面から使いたい」ということはよくあると思います。
これまで経験したプロジェクトでも `include` という関数を作ってそのようなことを実現してきていましたが、インクルード先ではスクリプトレットが使えない、など制限があるものでした。
もっと使いやすくならないかといろいろ試した結果を書いておきます。

# 対象者

* 基本的な JavaScript が読める方
* GAS で Web アプリを作ったことがある方

# いきなり結論

試行錯誤の結果、これでやりたかった以下のことができました。

* インクルード先の HTML でもスクリプトレットを使える
* インクルードのネスト（インクルード先でインクルード可能）
* インクルード先にパラメーターを渡せる

```js:Code.gs
/**
 * HTMLをインクルードする.
 *
 * @param {string} filename HTMLファイル名
 * @param {Object} params インクルード先に渡すパラメーター
 */
function include(filename, params) {
  const template = HtmlService.createTemplateFromFile(filename);
  if (params) {
    for (const key in params) {
      template[key] = params[key];
    }
  }
  return template.evaluate().getContent();
}
```

# 動作確認

:arrow_up: の `include` 関数を動作確認します。
以下のように複数の HTML を作りました。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= include('css'); ?>
  </head>
  <body class="index">
    <h2>this is index.</h2>
    <?!= include('sub1'); ?>
    <?!= include('sub2', { a:1, b:2 }); ?>
  </body>
</html>
```

```html:css.html
<style>
div {
  margin: 5px;
  padding: 5px;
}
.index { background-color: #ffffff; }  /* 白 */
.calc  { background-color: #99ffff; }  /* 水色 */
.sub1  { background-color: #99ff99; }  /* 緑 */
.sub2  { background-color: #ffff99; }  /* 黄色 */
.sub2_1 { background-color: #9999ff; } /* 紫 */
</style>
```

```html:calc.html
<div class="calc">
  <h4>this is calc.</h4>
  <?= a ?> + <?= b ?> = <?= a + b ?>
</div>
```

```html:sub1.html
<div class="sub1">
  <h3>this is sub1.</h3>
<?
const a = 'A';
const b = 'B';
?>
  <?= a + b ?>
</div>
```

```html:sub2.html
<div class="sub2">
  <h3>this is sub2.</h3>
  <?!= include('calc', { a:a, b:b }); ?>
  <?!= include('sub2_1', { a:a*2, b:b*2 }); ?>
</div>
```

```html:sub2_1.html
<div class="sub2_1">
  <h3>this is sub2_1.</h3>
  <?!= include('calc', { a:a, b:b }); ?>
</div>
```

HTML どうしの関係は以下のようになっています。

* index.html
    * css.html
    * sub1.html
    * sub2.html
        * calc.html
        * sub2_1.html
            * calc.html



つづけて `Code.gs` に `doGet` を追加します。

```js:Code.gs
function doGet(e) {
  return HtmlService.createTemplateFromFile('index').evaluate();
}
```

最後に作成した Web アプリにアクセスすると以下のように表示され、期待通りの動作が確認できました。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525650/77296e2a-6693-37c8-14f7-1379cae85280.png)


# 所感

* GAS で HTML を扱うクラスには、`HtmlOutput` や `HtmlTemplate` があり、色々と機能を持っているようなのでもっと深堀りしてみると面白そうです
* `doGet` 関数は `HtmlOutput` を返す必要があるようなので、最初は `return HtmlService.createHtmlOutputFromFile('index');` と書いていましたが、これではインクルードが期待通り動きませんでした。
    * 一度 `HtmlTemplate` 経由で `HtmlOutput` を生成することに意味がある模様
MENTAに登録して3ヶ月メンターしてみた

#そもそもMENTAとは
プログラミングなどのスキルをもった人が教えたい人と、そのスキルについて教えて欲しい人をマッチングするCtoCサービスです。
まだまだこれからのサービスなので登録していない人は是非登録して使ってみてください。
https://menta.work/

今回はMENTAの方の投稿にも同様の記事をかかせていただきました。
https://menta.work/post/detail/25706/MNFLifA3891FEOfMtVi0

#3ヶ月間やってみた結果
今年の1月にMENTAに登録してメンター活動を3ヶ月間やってみました。
結果としては12人の方と契約させていただき、報酬として約13万円をいただきました！ありがとうございます！

始めた当初はなかなか契約いただけないなーと思っていたのですが、継続的にメッセージを送り続けてなんとかこれだけの契約をさせていただくことができるようになりました。

月別でいうと以下のようになっています。

1月　　1万円
2月　　3万円
3月　　9万円

このまま頑張り続けると月10万円くらいは安定的に稼ぎ続けれるのではないかなと思います。

#依頼いただくために
自分が契約してもらうために意識したポイントだけ簡単にまとめさせていただきます。

それは！即レスです！
基本自分が意識していたポイントはこれだけで、最初は一番重要なポイントかなぁと思っております。
依頼する側ってどのメンターさんがいいかって判断が難しいんですよね。
情報が多すぎて探せない。そのため特徴的なプロフィールを作るか、それが難しい場合はやはりメンター側から動いてメンティさんを探しにいくということがポイントだったかなと思います。

★逆にここを気をつけた方がいいなと思うこと★
・サポート内容を明確にしておく
　時間や日付、期限を明確に、通話はありなのかなしなのかなどを明確にしておかないとずるずる対応してしまいます。

・返金が可能なので相談するだけの場合でもひとまず契約していただく、もしくは相談用のプランを作成する
　相談で結果的に1時間程度時間を使ったけどもお金にならなかったパターンを何回かしたのでそこから得た教訓です。

★今後意識していこうと思っていること★
・○○だったら自分！のような見つけやすいプロフィール作り
　こちらから連絡して契約していただくのには限界があるので、きちんと集客できるようにする。
・依頼の難易度を正確に把握する
　依頼の難易度と対応時間に合う金額をいただくためにも難易度を正確に把握できるようにする。
これができないとお互いが疲弊だけしてしまって誰も幸せになりません。
・環境構築の問題解決はなるべく受けないようにする
　明らかに解決策がすぐわかる問題以外はこちらは手をださないことにしました。唯一1件だけ解決できずに返金対応とさせていただきました。

最近MENTAを始めた方の参考になれば幸いです。
【Python】ある歌手が次出しそうな曲名を提案する


##この記事の目的

最近一人カラオケに行ったのですが、

**「この歌手が次出しそうな曲名なんだろう...」**

僕はふとこう思いました。

誰しもこう思ったことはあるはずです。

ということで、この記事では、

**「ある歌手の出した曲名」**から**「似ている単語」**を用いて**「新しい曲名」**を作る

プログラムを紹介していきます。

##今回使用する言語など

*  Python3
*  MeCab（形態素解析）
*  Word2Vec（言葉の意味合いの処理）

##大まかな手順

※手順は下の参考文献に詳しく書いているのでそちらを参照してください。

1.wikipediaから全記事のデータをひっぱります

2.MeCabやWord2Vecなどをpipなどを使ってインストールします

3.コーパスの用意、モデルの作成が終わったらpythonでプログラムを書きます

（コピペでもプラグイン類があればしっかり動きます。）

```python:main.py
import MeCab
import random
from gensim.models import KeyedVectors

mt = MeCab.Tagger('')
wv = KeyedVectors.load_word2vec_format('./wiki.vec.pt', binary=True)

word_result="" 

# texts 変数は曲名を格納する配列なので自由にいじってください
texts=["裸の心","マリーゴールド","桜が降る夜は","君はロックを聞かない","愛を伝えたいだとか","今夜このまま","さよならの今日に","空の青さを知る人よ","生きていたんだよな","猫"]
text=texts[random.randint(0, len(texts)-1)]

node = mt.parseToNode(text)
while node:
    fields = node.feature.split(",")
    # 名詞、動詞、形容詞に限定
    if fields[0] == '名詞' or fields[0] == '動詞' or fields[0] == '形容詞':
        topnumber=10 # topnumberを多くするとバリエーションが増えますが精度が落ちます
        results = wv.most_similar(positive=[fields[6]],topn=topnumber) 
        result = results[random.randint(0, topnumber-1)][0]
        word_result += result
    else:
        word_result += fields[6]
    node = node.next

print(word_result)

```

※今回はあいみょんさんの曲名を例に使用しました。

##実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515312/701d051f-97a2-171e-2e88-5ab7441b5cf4.png)

このように、動詞の活用に対応していないので、不自然な日本語になってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515312/50e654d6-12af-f7e4-3dd6-57ad4ebb2742.png)

たまに手を抜くこともあります。チェシャとはなんでしょうか...？

##今後追加したい機能

* 日本語の活用の改善
* もっとわかりやすくする
* 「チェシャ」とは何なのか解明する

##参考文献

Mecab（形態素解析）で遊んでみた！
https://qiita.com/str32/items/c1ced3b017ff5cacc4dc

【Python】Word2Vecの使い方
https://qiita.com/kenta1984/items/93b64768494f971edf86

Word2Vecを理解する
https://qiita.com/g-k/items/69afa87c73654af49d36
RenderTexture間のRay変換

メインカメラ(Persepective)からのオブジェクトへのRayによる当たり判定 をRenderTextureを描画しているSubCamera(Orthographic)のRay へと変換するものです

![ScreenPoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/1a32799e-8225-58cb-1e66-f7bc66dd996b.png)


```C#
    public ray TransformRay(Ray ray,GameObject TargetScreen)
    {
        Plane QuadPlane = new Plane(-TargetScreen.transform.forward, TargetScreen.transform.position);
 
        float enter = 0;
        TargetPlane.Raycast(ray, out enter);
        Vector3 HitPoint = ray.GetPoint(enter);
        
        Vector3 shift=transform.position-TargetScreen.transform.position;
        float scale=transform.lossyScale.magnitude/TargetScreen.lossyScale.magnitude;
        Hitpoint=(HitPoint-shift)*scale;
 
        return new Ray(HitPoint,transform.forward);
    }
```

・なんの意味があるのか？
主にLive2Dを描画するために使います。Live2DはOrthographicのカメラにしか写りません。
そこでPersepectiveのカメラに写したい場合は一度Live2DモデルをRenderTextureに描画して、それをマテリアルにして３Ｄ空間のオブジェクトに反映させます。

ですがこの方法だと基準点が違うため当たり判定用のRayの変換が必要になります。そのためのスクリプトです。

RenderTextureに描画してPersepectiveカメラに写すことでズーム、スクロール、半透明化が可能になります
ffmpegでフォルダ内の動画を一括変換する


# やりたいこと

古いデジカメで撮ったAVI形式の動画が大量に出てきた。AVI形式はサイズが大きいので、MP4形式に変換し容量を節約したい。１ファイルずつ変換するのは面倒なので、一気に変換したいと考えた。

やりたいことは、以下の2点。
**１）MP4形式をAVI形式に変換したい**
**２）特定のフォルダにあるファイルを、すべて〇〇したい（一括処理）**


結論から書くと、Macのターミナル（zsh）を使い、下記コマンドで出来た。

```zsh
for f in **/*.avi; do ffmpeg -i "$f" -pix_fmt yuv420p "${f%.AVI}.mp4"; done
```

:::note warn
`ffmpeg`が入っていない場合は、`Homebrew`等でインストールしておく。
```zsh
brew install ffmpeg
```
:::

# 解説

### １）AVI形式をMP4形式に変換

- ffmpegを使って変換する。
- AVI形式からMP4形式に変換する場合、そのままではMacのQuickTimeで再生できない。`-pix_fmt yuv420p`などのオプションをつけて変換する必要がある。

```zsh
ffmpeg -i input.avi -pix_fmt yuv420p output.mp4
```

### ２）フォルダにあるファイルを一括処理

#### フォルダにあるファイルの名前を取得する
- `**/*`の記法を使えば、サブフォルダも含めてフォルダにあるファイルの名前を取得できる。

```zsh
$ ls
movie1.avi  movie2.avi  movie3.avi
$ for f in **/*.avi; do echo $f; done
movie1.avi
movie2.avi
movie3.avi
```

#### ファイル名の拡張子だけを変更する
- ffmpegでは、出力ファイル名を指定する必要がある。元のファイル名から、拡張子だけをavi→mp4に置き換えた名前にしたい。
- `${変数%マッチパターン}`で、後方からの検索で一番初めにマッチした部分を削除する。これを使って、拡張子を除いたファイル名を取得する。
- 得られたファイル名に、変換したい形式（MP4形式なら`.mp4`）を付与してffmpegに渡せば変換してくれる。

``` zsh
$ var="movie.avi"; echo ${var%.avi}.mp4
movie.mp4
```

---

　初版　2021年4月3日公開
　第2版　2022年5月6日公開
　第3版　2024年8月14日公開
Raspberry Pi 4をUSBブートする

　2021年4月現在のUSBブートの説明です。ラズパイ400が出た以降のラズパイ4は、USBブートが優先になっています。
　ここでは、国内販売が始まってすぐに購入したラズパイ4（2GB）です。
　古いラズパイは、「SDメモリ・カード」からブートと「USBのストレージ」からのブートをどちらかに変更できます。デフォルトはSDメモリ・カードです。USBのストレージからブートするように変更する方法は、下記のページに解説されています。二通りあります。

　　[USB mass storage boot](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md)

###二つ目の「Using raspi-config to update the bootloader from within Raspberry Pi OS」を実行する
　[Raspberry Pi Imager](https://www.raspberrypi.org/software/)を使って、SDメモリ（32GB）にRaspberry Pi OS with desktop （March 4th 2021）を書き込みます。　

<img width="400" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/0113890a-cdb3-f929-ce04-951a9b2600d5.png">


　このSDメモリを挿し込んで、ラズパイを起動します。セットアップの画面が中央に出ていますが、無視してターミナルで、sudo raspi-configを実行します。次の画面が出ます。Advanced Optionsを選びます。

　
<img width="450" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/3d13f33d-d250-d9cb-d591-1cbdc8eb7e12.png">

　Boot Orderを選びます。

<img width="450" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/354aba8b-f09a-d965-a0ed-ea854ae19019.png">

　USB Bootを選び、okを押したのち、終了します。ラズパイを終了します。

<img width="450" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/bc1fd40b-d916-dbb1-7c93-af2acc609406.png">

PS.もしこの設定に失敗しても、SDメモリを入れずに、USBストレージをつないでおけば、そちらからブートします。つまり、上記の設定変更は必要ない?ということになってしまう。
PS.ファームウェアを最新にするには、次のコマンドで可能

```
sudo apt update
sudo apt full-upgrade
sudo reboot
```

###USBストレージ
　昔Windows10で使っていたM.2 NVMe SSD 256GB を、アマゾンで購入したM.2 SSDケースにいれました。

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/209ba0aa-f1e8-cf75-bb47-86792d88c111.png">



　M.2には「NVMe SSD」と「SSD」の2種類があります。入れ物は、それぞれ異なります。

　実験はしていませんが、普通のUSBメモリも使えると思います。読み出し速度はSSDと同じくらい、書き込み速度は少し遅いかもしれません。

　Raspberry Pi Imagerを使って、このUSBストレージにRaspberry Pi OS with desktop （March 4th 2021）を書き込みます。USB3のコネクタに挿して、ラズパイの電源を入れます。

　~~dfコマンド見ると、rootは32GBでした。特に困らないので、このまま使います。必要だったらパーティションを切りなおしてください。~~
【Swift】CollectionViewのカスタムセルをタップすることでUISwitchを切り替える

# どういうことか

こういうことがやりたい。

![d760189770a3a5b3dedc0b5689ae8206.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/057eb944-a88b-d29b-a8d7-c47e6f24fff4.gif)

## どうするのか

- xibを使ってUIを作るが、この際にUIButtonでセル全体を覆ってしまうのがコツ
- どちらのセルをタップしたのかの判定も入れる
- Delegateを使う

## カスタムセル側

```swift:ToggleCollectionViewCell.swift
protocol ToggleCollectionViewCellDelegate {
    func toggleSwitchAction(toggleSwitchCheck: Bool, type: String)
}

class ToggleCollectionViewCell: UICollectionViewCell, Reusable {

    @IBOutlet weak var toggleSwitch: UISwitch!
    
    var toggleSwitchCheck = false
    
    // どっちのセルをタップしたのか判定するための変数
    var contentType = ""

    var delegate: ToggleCollectionViewCellDelegate?
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }

    @IBAction func titleButtonAction(_ sender: Any) {
        
        // スイッチの切替処理
        if toggleSwitchCheck {
            toggleSwitch.setOn(false, animated:true)
            toggleSwitchCheck = false
        } else {
            toggleSwitch.setOn(true, animated:true)
            toggleSwitchCheck = true
        }

        // スイッチの判定とセルの判定を渡してあげる
        delegate?.toggleSwitchAction(toggleSwitchCheck: toggleSwitchCheck,  type: contentType)
    }
}
```

## Controller側

Delegateメソッドはextensionに書きます（自由ですが）。
セルをタップすることでController内のメンバ変数が切り替わるので、それによってなんらかの処理をしてあげるといい感じです。

```swift:ViewController.swift

    // メンバ変数
    var areYaru = false
    var koreYaru = false

// 中略

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = CollectionViewUtility.createCell(collectionView, identifier: ToggleCollectionViewCell.reusableIdentifier, indexPath) as! ToggleCollectionViewCell
        
        switch (indexPath.section) {
        
        case 0:
            cell.titleButtonLabel.setTitle("あれをやる", for: .normal)
            cell.delegate = self
            cell.contentType = "are"

            return cell
            
        case 1:
            cell.titleButtonLabel.setTitle("これをやる", for: .normal)            
            cell.delegate = self
            cell.contentType = "kore"

            return cell
            
        default:
            return UICollectionViewCell()
        }
    }

// 中略

extension ViewController: ToggleCollectionViewCellDelegate {

    // Delegateメソッド
    func toggleSwitchAction(toggleSwitchCheck: Bool, type: String) {
                
        if type == "userId" {
            areYaru = toggleSwitchCheck
        } else if type == "biometrics" {
            koreYaru = toggleSwitchCheck
        } else {
            print("error")
        }
    }
}
```

おわり(´・ω・｀)
Matplotlib animation

# matplotlib で sin波のアニメーションを作った

+ `ax.plot()`を`img`で拾える
+ `ax.set_prop_cycle(None)` で色を固定できる
+ `'imagemagick'` はお手持ちの環境で
+ `repeat=False` がうまく動かないのは疑問

```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as mpani
x = 2*np.pi* np.arange(50)/50
fig = plt.figure()
ax = fig.add_subplot(111)

imgs = []
for dx in x:
    ax.set_prop_cycle(None)
    img = ax.plot(x, np.sin(x+dx))
    imgs.append(img)
    
ani = mpani.ArtistAnimation(fig, imgs, interval=100, blit=True, repeat=False)
ani.save('mytest.gif', 'imagemagick')
```
![mytest.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175620/9f28f01b-e0ba-8a87-a5be-e59a9ceaf2a5.gif)
HackTheBox Machineへのアプローチ

# HackTheBox Machineへのアプローチ
常設なのでWriteupが書けない上に既にそこらに転がってるので、代わりにいくつかのMachineを解いて学んだ侵入のアプローチの方法を書くことにした。

## 情報収集
HackTheBoxのMachineはひとつのサーバだけで完結するのでネットワークの調査とかは必要ないので、与えられたIPの情報を集めることになる。

### ポートスキャン
最初はIPしか与えられてないので、nmapなどでポートスキャンをする。
最初は全てのポートをスキャンせずによく使われるポートだけをスキャンしてどんなサービスが動いてるか調べる。
そこで発見したサービスについて調べている間に全てのポートをスキャンするのがよさそう。

### 開いているポートの調査
ほとんどの場合sshとWebサービスが動いているポートがある。
次はそこで動いているのがどのようなものなのかを調査する。

Webサービスだと、既存のソフトウェア(Apache, GitLab, Mattermost, WordPressなど)がそのまま動いていることもあれば、オリジナルのWebサービスの後ろでnmap、imagemagickなどのコマンドを動かしていることもある。それらのサービスの機能を使ってみてどのような働きや出力をするのか観察する。通常通りではない挙動(エラーメッセージなど)はより詳細な情報を得るためのヒントになることがある。
同じIPでもバーチャルホストでgit.example.comとexample.comではアクセスするサービスが違うみたいなことがあるので、サブドメインが異なるリンクなどを見つけたら/etc/hostsなどに設定して、そのURLで接続してみるといい。ワードリストを使ってgobusterなどで発見できることもある。
また、Webサービスならdirbとかを使って公開されるべきではない情報が公開されていないかをチェックしてみる。テスト環境やWordPressのディレクトリで認証情報が見つかることもある。サービスの中で公開されている内容から、他のコンテンツの情報が推測できる場合がある(サブドメインだったりファイル名だったりバックアップだったり)。

ソフトウェアのバージョン情報が得られたならそれをもとにCVEを探す。特に任意コード実行と任意ファイル読み込み、書き込みが侵入に使えることが多い。バージョンが特定できなくてもRCEなどがあれば試してみると刺さるかもしれないので試してみよう、新しめの脆弱性があることがほとんどだった。

## Exploitation
情報収集で得た情報を元に、侵入できそうなポイントを探し侵入する。

情報収集の段階で何らかの認証情報(DBとかWebサービスとかの)を得られたなら、それをログインに使えないかを試す。デフォルトパスワードが使えることもある。パスワードの使い回しはHackTheBoxではかなりよくある。

RCEなどが発見できているのならそれを試す。Reverse ShellがうまくいかないならBind Shell、それでもうまくいかないならsshの鍵を書き込んで追加するなど、色々やってみる。

## Post Exploitation
HackTheBoxのMachineなら、最初はroot権限のないアカウントで侵入してフラグを手にいれ、そこからrootへの権限昇格を狙う流れになる。

権限昇格のための情報収集からやることになる。自分の場合だと、[linpeas.sh](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS)のようなスキャナーを使って、仮想マシン環境の検知や権限設定の不備などを調査し、脆弱性を探す。よくあるパターンでは、どこかの設定ファイルに書いてある認証情報がrootの使い回しであったり、`sudo -l`で見つかるパスワードなしでroot権限で実行できるプログラムに脆弱性があったりする。HackTheBoxだと通常VMWare上で動いているっぽいが、ときどきDocker上で動かされていてDockerのコンテナからescapeするようなMachineもある。DBが動いているMachineでは、DBの認証情報やDBに格納されているハッシュを使って権限が上のユーザにアクセスできることがある。
【Linux】面白いコマンドまとめ

環境はubuntu 18.04.4 LTS

#xeyes

カーソルを追いかける目が出てくる。

#pv

sudo apt_get install pv
でダウンロードする必要あり。

```
echo "" | pv -qL 10
```


標準出力がリアルタイムで表示される。
Lは１秒あたりのバイトの制限。
随時、追加予定。
ラズパイpicoをVSCode[Pico-Go]で接続できないときの対処法

# 結論
### bluetoothを切ったら接続できるようになりました.
<br>
…すみません以上です。COMが原因でした。これで出来なかったら原因わかんないです…
# 使用環境
* windows ノートPC ( HP_SPECTRE )
* VSCode (バージョン:1.55.0)
* 拡張機能 : Pico-Go
* 使用機材 : ラズパイpico, 100均の通信用ケーブル(充電用だと多分無理)<br>

セットアップは以下を参考にさせていただきました。感謝。
https://rikoubou.hatenablog.com/entry/2021/02/05/150631 <br>

* 公式ホームページからファイルをダウンロードしてきて、<br>
* 拡張機能のPico-Goをインストールして、<br>
* USBでPCにつないで、<br>
* ダウンロードしてきたファイルをドラック&ドロップして、<br>
* ラズパイpicoの再起動を待つ<br>

だけやりました。

# エラーの状態と解決方法の詳細
セットアップ終了後はこんな感じです。（ラズパイpicoつないだ状態）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/3decbe7f-ac6c-2110-8804-fdd3547b371c.png)
ここで、↑ の`✖Pico Disconnected`をクリックすると接続されるのですが<br>今回は以下のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/c9f50019-2a08-d500-059a-781fc56c75c6.png)

```:表示文
Connecting to COM4...

> Connection timed out. Click the "Pico Disconnected" button to try again.
```
単純につながらないからもう一回試してみてと言われているのですが、何回やってもできません。
ここで、`COM4`に着目して、コントロールパネルで調べてみると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/cc685783-ee16-9cc0-e76f-ff8795fb5ab3.png)

このように、`COM4`はBluetoothリンクがなんたらというものになっていました。
要は、bluetoothにつなげようとしてしまっているらしいです。
#### なので、bluetoothを切ると`COM4`が消えて、`COM3`(ラズパイpico)につながるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/e695d69c-c662-e8d3-bfef-7b64d6b964a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/e4a80dbd-7e64-42fc-1f0a-252ac38fdf1f.png)
無事つながりました。
`>>>`のところにコマンドをうつか、下の青線にあるボタンをクリックして操作します。
<br>
COMを選ぶ方法が見つかればいいんですがね…
原因がbluetoothでなかったとしても、一度COMポートは確認するといいかもしれません。

読んでいただきありがとうございました。あなたの成功を願います。



# 参考文献
【Raspberry Pi Pico/Windows】Raspberry Pi Picoの環境構築する(MicroPython)：rikoubou様
https://rikoubou.hatenablog.com/entry/2021/02/05/150631
Comparative evaluation of CNN architectures for Image Caption Generation

# はじめに

- どんなモデルがあるのか調査がてら、読んでいきます

# 要約

- 17の画像キャプション生成CNNモデルを比較した
- ネットワークの複雑さやオブジェクト認識性能とは、必ずしも相関しなかった


# 提案手法

- ないのかと思ってたけど、あった
- ちょびっと

# 実験

## 概要

- CNN+LSTM, CNN+LSTM+Attention なモデルを調査
-  Squeezenet [31], Shufflenet
[32], Mobilenet [33], MnasNet [34], ResNet [13], GoogLeNet
[29], DenseNet [15], Inceptionv4 [24], AlexNet [22], DPN
(Dual Path Network) [36], ResNext [37], SeNet [39], PolyNet
[40], WideResNet [38], VGG [14], NASNetLarge [35] and
InceptionResNetv2 を対象
- Flickr8k データセットで評価
-  BLEU, METEOR, CIDER, ROUGE-L and SPICEで評価

|  指標  |  概要  |
| ---- | ---- |
|  BLEU  |  n-gram含有率を算出(40以上で高品質といえる)  |
|  METEOR  |  BLEUの補完的な存在。unigram系。人手評価との相関が高め  |
|  CIDER  | キャプション生成でよく利用される。n-gram含有率  |
|  ROUGE-L  | n-gram含有率  |
|  SPICE  |  キャプション生成でよく利用される。グラフ系  |


## 結果

![スクリーンショット 2021-04-03 1.05.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/1438c9dd-4073-84f8-d6ac-d30bc5e8aa13.png)

![スクリーンショット 2021-04-03 1.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/60891b14-c3de-fa1b-5490-1f2c25b9d284.png)

- パラメータが小さくても勝つ時は勝つ(DenseNet121 and VGG-11)
- どのメソッドも、理にかなったキャプションを生成できている。バリエーションがあるようだ
    - 全体的に言えるのは、性別の認識ミスがある
    - これは、データの偏りによるものだと考えられる
    - 例えば、サッカーをしている人は男性が多い -> 女性がサッカーをしていても、キャプションでは男性と言ってしまう的なこと

![スクリーンショット 2021-04-03 1.31.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/4699e83a-2a1f-0ca3-55c7-1f40f11d6e23.png)

![スクリーンショット 2021-04-03 1.34.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/5ae50530-03d8-2896-6120-36fef505f91d.png)

## まとめ

- ResNet[13] and DenseNet[15]がキャプション生成には適していると思う
Node.jsでの標準入力の書き方をまとめてみた

## 初めに
最近になって、あらためて Node.jsでatCoderやLeetCodeでアルゴリズム問題を解いてみようと思ったのですが、Node.jsの標準入力の書き方は調べてみると色々あってどれがいいんだろうと少し迷ったので、いい機会なのでまとめてみました。

## Node.js(標準入力)のパターン

### 1. ```/dev/stdin``` を```readFileSync```を利用して読み込む

```javascript:input1.js
var input = require("fs").readFileSync("/dev/stdin", "utf8");
console.log(input);
```

標準入力を表す特殊ファイル(``` /dev/stdin ```)を```readFileSync```で読み込みます。

**メリット** : 記述がかなりシンプル
**デメリット**: ```/dev/stdin```はUNIX系のOSでしか利用できないので、Windowsでは利用できない 

### 2. ```process.stdin```を```readline```モジュールを利用して読む

```javascript:input2.js
process.stdin.setEncoding("utf8");

var lines = []; 
var reader = require("readline").createInterface({
  input: process.stdin,
});

reader.on("line", (line) => {
  //改行ごとに"line"イベントが発火される
  lines.push(line); //ここで、lines配列に、標準入力から渡されたデータを入れる
});
reader.on("close", () => {
  //標準入力のストリームが終了すると呼ばれる
  console.log(lines); 
});
```

改行単位で```Readable stream```を処理できる```readline```モジュールを利用してデータを読み込みます。

**メリット** : 改行単位で読み込めるので、1行ごとで処理を行う場合や一度に処理するにはインプットが大きすぎる場合には便利。
**デメリット**: 改行ごとの処理と読み込み完了後の処理に分かれるため、記述量が多い。

### 3. ```process.stdin```を ```for await...of```を利用して読む

```javascript:input3.js

(async () => {
  const buffers = [];
  for await (const chunk of process.stdin) buffers.push(chunk);
  const buffer = Buffer.concat(buffers);
  const text = buffer.toString();
  console.log(text);
})()

```

標準入力を非同期のイテラブルなオブジェクトとしてループで処理します。

**メリット** : 分割して読み込みされるので、一度に処理しきれないインプットを扱う場合には便利。
**デメリット**: 文字列への変換が必要なので、やや記述量が多い。またデータが分割される場所をコントロールしにくい。

### おわりに
Windowsを利用していない場合やインプットが多くない場合は1の方法を利用して、それ以外のケースでは必要に応じて2または3の方法で記述するのが良さそうだなと思いました。

それでは素敵なNode.jsライフを。

### 参考リンク
* [Qiita:Node.jsの標準入力と](https://qiita.com/hiroqn@github/items/c927bc97780c34eda562)
* [nodejs.org: Readline](https://nodejs.org/api/readline.html)
* [Qiita:Node.js 12+なら標準入力が超簡単に読める](https://qiita.com/naokikimura/items/ffcac9ee68c7ca6f2f13)
* [MDN:for await...of](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for-await...of)
* [nodejs.org: Consuming readable streams with async iterators](https://nodejs.org/api/stream.html#stream_streams_compatibility_with_async_generators_and_async_iterators)
yukicoder contest 289 (Kanten4205’s Birthday Contest) 参戦記

# yukicoder contest 289 (Kanten4205’s Birthday Contest) 参戦記

yukicoder なのに ABC みたいな難易度.

## [A 1461 しあはせや歩みゆく？](https://yukicoder.me/problems/no/1461)

N≦10<sup>15</sup> なので素直にシミュレートすると TLE するのは明らか. 10歩前くらいまで一気に飛ばして、そこからシミュレートすることによって AC できる.

```python
N = int(input())

a = max(N - 10, 0)

result = a * 5
p = a
while p != N:
    if result % 5 in [0, 1, 2]:
        p += 1
    else:
        p -= 1
    result += 1
print(result)
```

## [B 1462 最弱WEAKER](https://yukicoder.me/problems/no/1462)

素直にメモ化再帰で解くコードを書いたら TLE や MLE になって散々な目にあったので、規則性を見出そうと前から100個解かせてみたら偶奇だけだとわかった.

```python
N = int(input())

if N % 2 == 0:
    print('YES')
else:
    print('NO')
```

## [C 1463 Hungry Kanten](https://yukicoder.me/problems/no/1463)

N≦18なので bit 全探索で一発.

```python
from itertools import product
from functools import reduce

N, K, *A = map(int, open(0).read().split())

s = set()
for p in product([True, False], repeat=N):
    if list(p).count(True) < K:
        continue
    s.add(sum(A[i] for i in range(N) if p[i]))
    s.add(reduce(lambda x, y: x * y, (A[i] for i in range(N) if p[i])))
print(len(s))
```

## [D 1464 Number Conversion](https://yukicoder.me/problems/no/1464)

decimal を使えば小数点以下を正確に扱えるので、小数点以下がなくなるまで分母と分子を10倍し、最後に最大公約数で割ればよい.

```python
from decimal import Decimal
from math import gcd

X = Decimal(input())

r = 1
while X - int(X) != 0:
    X *= 10
    r *= 10

X =int(X)
n = gcd(X, r)
print('%d/%d' % (X // n, r // n))
```

## [E 1465 Archaea](https://yukicoder.me/problems/no/1465)

これはどこかで見たような問題. ゴールから逆向きにメモ化再帰をすれば解けます.

```python
from functools import lru_cache
from sys import setrecursionlimit

setrecursionlimit(10 ** 6)

N, K = map(int, input().split())


@lru_cache(maxsize=None)
def f(n, k):
    if k > K:
        return False
    if n == 1:
        return True
    if n % 2 == 0:
        result = f(n // 2, k + 1)
        if result:
            return True
    if n > 3:
        return f(n - 3, k + 1)
    return False


if f(N, 0):
    print('YES')
else:
    print('NO')
```
【Linux】ちょっと便利なコマンドまとめ

本記事は、ほぼ自分のためのメモです。

## cat -n 行数と共に出力

##sed 　ある特定の行数のみ出力

catはファイルの中身をすべて出力するがsebは特定の行数を指定可能

```zsh
sed -n 5p filename #5行目指定
sed -n 5,8p filename #5~8の3行を出力
```

随時追加していきます。
Ansible Tips: shellモジュールのデバックモード実行ログを対象ノードのファイルにもリアルタイムで書き出す

備忘

# 目的
Ansible shellモジュール利用の際、どこを実行しているかなどをリアルタイムで確認したい場合、ファイルに実行ログを書き出しておくことで対応できる可能性がある。
Ansibleのログとログファイルの両方に書き出したい場合の例を示す。



## 参考

https://unix.stackexchange.com/questions/145651/using-exec-and-tee-to-redirect-logs-to-stdout-and-a-log-file-in-the-same-time




## tasks例

```yaml
  - shell: |-
      set -x
      exec > >(tee -a "/tmp/ansible_shell.log") 2>&1
      echo "hello world."
    args:
      executable: /bin/bash  # AIX環境などではbashを導入の上で明示的にbash指定が必要
    register: r
  - debug:
      var: r.stdout_lines
```

exec > >(tee -a "/tmp/ansible_shell.log") 2>&1 
は
exec &> >(tee -a "/tmp/ansible_shell.log")
ともまとめられる。



## Ansibleログ出力


```
TASK [shell] *******************************************************************************************************************
changed: [localhost]

TASK [debug] *******************************************************************************************************************
ok: [localhost] => {
    "r.stdout_lines": [
        "+ echo 'hello world.'",
        "hello world."
    ]
}
```

## ファイル出力

ターゲットマシン上で

```
$ cat /tmp/ansible_shell.log
+ echo 'hello world.'
hello world.
```

## リアルタイムログ確認例

ターゲットマシン上で

```
$ touch /tmp/ansible_shell.log
$ tail -0 -f /tmp/ansible_shell.log
+ echo 'hello world.'
hello world.
```
perfect pixcelというツールに感動した話

最近perfectpixelなるツールをつかってみて感動したのでそのメモ書きです。

https://chrome.google.com/webstore/detail/perfectpixel-by-welldonec/dkaagdgjmgdmbnecmcefdhjekcoceebi?hl=ja

そもそも久しぶりにHTMLとCSSを使ったデザインの当て込みをおこなおうとしたのですが、
xdで作られたファイルでデザインを納品してもらったのが初めてでした。
xdのファイルの画像の高さ、幅やサイズを確認してそれをもとにCSSで画像の高さや文字のサイズを設定しようとしたのですが、そもそもxdファイルとCSSのサイズ感が合わない。

このままだと正確な数値がわからないとなやんでいたところに上記のツールですよ。
何ができるかというと、とってもシンプルなのですが画像をブラウザの画面の上に透過させて載せることができるんですよね。

詳細な使い方はこちら
https://www.asobou.co.jp/blog/web/perfectpixel

これがめちゃくちゃよくて納品されたデザインとずれているかどうかが確認できるんですよね。
子供の頃に使った「うつしがみ」の要領ですね。
（みんな使いましたよね？？）

HTML,CSSのコーディングには必須だなと思いました。
Flutterのスクロールにびろーんもぐにょーんも必要ない

Flutterでスクロール系のWidget使うと、iOSの場合スクロールの端でバウンス効果があってびろーんとなる(BouncingScrollPhysics)。Androidの場合びろーんとはならないが(ClampingScrollPhysics)、グローエフェクトが掛かってぐにょーんとアニメ表示が出る(GlowingOverscrollIndicator)。アプリ全体でびろーんもぐにょーんも全否定したい場合はどうするかのメモ。

```dart:never_glow_scroll.dart
import 'package:flutter/material.dart';

class NeverGlowScrollBehavior extends ScrollBehavior {
  const NeverGlowScrollBehavior();

  @override
  Widget buildViewportChrome(
          BuildContext context, Widget child, AxisDirection axisDirection) =>
      child;

  @override
  ScrollPhysics getScrollPhysics(BuildContext context) =>
      const ClampingScrollPhysics();
}

class NeverGlowScrollConfiguration extends StatelessWidget {
  final Widget child;

  const NeverGlowScrollConfiguration({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ScrollConfiguration(
      behavior: const NeverGlowScrollBehavior(),
      child: child,
    );
  }
}
```

NeverGlowScrollBehaviorが要で、getScrollPhysics()で無条件にびろーんとならないClampingScrollPhysicsを返している。そしてbuildViewportChrome()で何もさせないようにしてグローエフェクトを潰している。
NeverGlowScrollConfigurationはNeverGlowScrollBehaviorを使うようにしているだけなのであってもなくても良い。


そしてMaterialAppのbuilderで、


```dart:main.dart
    return MaterialApp(
      // ...
      builder: (context, child) => NeverGlowScrollConfiguration(child: child),
```
とするとアプリ全体でびろーんもぐにょーんも消える。
「この画面だけNeverScrollableScrollPhysics使いたい」なんてときは個別にphysics設定とかすればオッケー。
Windows 10 の VirtualBox + Vagrant 環境に於ける CentOS Stream 8 仮想マシン起動手順

## 前提

今回の手順を検証した環境は以下の通り。

- Windows 10 Pro 20H2
- VirtualBox 6.1.18
- Vagrant 2.2.15


## 手順

### 仮想マシン起動

1. VirtualBox と Vagrant をインストールする。

    1. [Downloads – Oracle VM VirtualBox](https://www.virtualbox.org/wiki/Downloads)
    1. [Downloads | Vagrant by HashiCorp](https://www.vagrantup.com/downloads)

1. Windows のスタートボタンを右クリックし, コマンドプロンプトをクリックする。
1. vagrant ディレクトリーを作成する。

    ```powershell
    > mkdir vagrant
    ```

1. 作業ディレクトリーを移動して, CentOS 用のディレクトリーを作成する。

    ```powershell
    > cd vagrant
    > mkdir centos
    ```

1. 作業ディレクトリーを移動して, Vagrant の設定ファイルを生成する。

    ```powershell
    > cd centos
    > vagrant init
    ```

1. メモ帳で設定ファイルを開き, Box を `base` から `centos/stream8` 変更する。

    ```powershell
    > notepad Vagrantfile
    ```

    ```diff_ruby:Vagrantfile
    --- Vagrantfile.org     2021-04-02 20:40:20.328164000 +0900
    +++ Vagrantfile 2021-04-02 20:41:36.510341300 +0900
    @@ -12,7 +12,7 @@

       # Every Vagrant development environment requires a box. You can search for
       # boxes at https://vagrantcloud.com/search.
    -  config.vm.box = "base"
    +  config.vm.box = "centos/stream8"

       # Disable automatic box update checking. If you disable this, then
       # boxes will only be checked for updates when the user runs
    ```

1. 仮想マシンを起動する。ただし, Box のダウンロードが遅い場合は [Box のダウンロードが死ぬほど遅い場合](#box-%E3%81%AE%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%8C%E6%AD%BB%E3%81%AC%E3%81%BB%E3%81%A9%E9%81%85%E3%81%84%E5%A0%B4%E5%90%88) を参照すること。

    ```powershell
    > vagrant up
    ```


### ログイン, ログアウト, シャットダウン

プロンプト記号が `>` の場合はコマンドプロンプトで, `$` の場合は CentOS にログインした状態で実行すること。

1. 仮想マシンにログイン (SSH 接続) する。

    ```powershell
    > vagrant ssh
    ```

1. 仮想マシンからログアウトする。

    ```shell
    $ exit
    ```

1. 仮想マシンをシャットダウンする。

    ```shell
    $ sudo systemctl poweroff
    ```

1. 仮想マシンがシャットダウンされていることを確認する。

    ```powershell
    > vagrant status
    ```


## 参考文献

### Box のダウンロードが死ぬほど遅い場合

多少マシになる程度の対策。

1. Web ブラウザーを開き, [CentOS Cloud images](https://cloud.centos.org/centos/8-stream/x86_64/images/) にアクセスする。
1. VirtualBox 用 Vagrant Box のリンクをコピーする。
    - 今回は `CentOS-Stream-Vagrant-8-20210210.0.x86_64.vagrant-virtualbox.box` とする。
1. Windows のスタートボタンを右クリックし, コマンドプロンプトをクリックする。
1. ダウンロード用のディレクトリーに移動し, Box をダウンロードする。

    ```powershell
    > cd Downloads
    > curl -LO https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-Vagrant-8-20210210.0.x86_64.vagrant-virtualbox.box
    ```

1. Box を追加する。

    ```powershell
    > vagrant box add centos/stream8 CentOS-Stream-Vagrant-8-20210210.0.x86_64.vagrant-virtualbox.box
    ```


### 他の仮想マシンを試す場合

Vagrant Cloud で検索する。

- [Discover Vagrant Boxes - Vagrant Cloud](https://app.vagrantup.com/boxes/search)
- [centos - Vagrant Cloud](https://app.vagrantup.com/centos)
- [ubuntu - Vagrant Cloud](https://app.vagrantup.com/ubuntu)


どっとはらい。
【cloud9】Ｒailsチュートリアルやってたら、cloud9で容量足りなくなって更新できなくなったので容量増やした【Rails】

<h2>症状</h2>
Ｒailsチュートリアルをやっていたら、下記エラーが表示されてファイルが更新できなくなってしまいました。

```
Failed to write to '更新対象のファイルの中身'. ENOSPC: no space left on device, write .
```

翻訳すると、「書き込みに失敗しました。デバイスにスペースが残っていません」
容量が足りなくて、ファイルの更新ができなくっていると推測。

前半で作った「hello_app」「toy_app 」は既に削除していたので、EBS ボリューム(Amazon Elastic Block Storage)を増やしていこうと考えました。
念のため、df -h コマンドで、現在の容量をチェックし、100%になっていることを確認しました。

```
df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      9.7G  9.7G     0 100% /
```


<h2>解決策</h2>
Railsチュートリアルの2. EBS ボリュームを増やす方法を確認しながらEBSボリュームを増やして、ファイルを更新できるようにしました。

Railsチュートリアルの手順を下記に引用し、実際にやっていきます。
>
1.<a href="https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Volumes:search=aws-cloud9;sort=desc:createTime">Amazon EC2 コンソール</a>を開きます。
2.「ボリューム」を選択し、変更するボリュームを選択します。（複数あって分からない場合は、「インスタンス」の「実行中のインスタンス」の中からaws-cloud9から始まる Name のインスタンス ID をコピーし、ボリューム内で検索するとよいでしょう。）
3.上部にある「アクション」ボタンから「ボリュームの変更」を選択し、サイズを <a href="https://aws.amazon.com/jp/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&all-free-tier.q=ec2&all-free-tier.q_operator=AND">AWS が定める最大無料枠</a>に設定し、変更します。（執筆時点では 30 でしたが、念のため確認しておくことをオススメします）
4.「インスタンス」にいき、該当のインスタンスを選択後、画面上部にある「アクション」ボタンから「インスタンスの状態」→「再起動（停止中なら開始）」をします。
5「Cloud9」に戻り、ターミナルからボリュームの拡張をします。現在のインスタンスに割り当てられているブロックデバイスの情報を確認するには、lsblkコマンドで表示します。ルートボリュームである/dev/xvdaは拡張されていますが、/dev/xvda1はまだ元のままです。


1から3でコンソールを対象のボリュームを選択し、アクションを押したの下記です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/499114a8-20b8-759a-b415-9d087e820f9f.png)


![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/9281778e-51fe-5ac5-e5fd-9a24b831cb13.jpeg)

4.「インスタンス」に行き、街頭のインスタンスを再起動しました。
![キャプチャ13.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/5314e074-4a3c-a916-9856-38361c0a7ed7.jpeg)

```
lsblk

xvda    202:0    0   30G  0 disk 
└─xvda1 202:1    0   10G  0 part /
```

5のコマンドを打とうとすると、「容量が足りないよ」と怒られてしまいました。
容量が足りないから増やそうとしているのに、その命令が出せないというパラドックス状態に。。。

```
 sudo resize2fs /dev/xvda
sudo: unable to resolve host ip-ホスト名: Resource temporarily unavailable
resize2fs 1.44.1 (24-Mar-2018)
resize2fs: Device or resource busy while trying to open /dev/xvda
Couldn't find valid filesystem superblock.

```

詰んだと思って放置して、後日確認したらボリュームが追加されていました。

```terminal:ターミナル
df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       30G  9.2G   20G  32% /
```

おそらくですが、ボリュームが変更ほやほやだったため、状態が黄色状態でうまくボリュームの変更が未完了できていなかったようです。
とりあえず、cloud9でボリューム追加できました！


<h2>参考</h2>
困ったときのヒント集－Railsチュートリアル
https://railstutorial.jp/help#volume-up-aws-ebs

No space left on deviceで、Volume増やしたけど、growpartコマンドすら実行できない状況を解決(docker containerを削除した)
https://qiita.com/gymnstcs/items/f535bdf8f85513580577
AWS認定のデジタルバッジをダウンロードする方法

AWS認定のデジタルバッジ（ロゴ）をダウンロードする方法についての備忘録です。
以前はAWS認定アカウントからダウンロードできたみたいですが、現在はCredly（AcclaimはCredlyと合併した模様）から直接ダウンロードする必要があるようです。

#前提条件
・バッジの申請とアカウントのセットアップが完了していること

#手順
1. Credly にサインイン (https://www.credly.com/users/sign_in)
2. 画面上の [Dashboard] を選択
3. 対象のバッジをクリック
4. 画面左上の [Share] をクリック
5. [↓]（下矢印）のアイコンをクリック
6. [Download Image] をクリック

#参考
https://support.credly.com/hc/en-us/articles/360041542052-Video-Can-I-Print-my-Badge-
※上記のリンクは画像（.png）ではなくPDF（.pdf）としてダウンロードする際の手順です
4月3日にOracleでPLEASE句もどきを実現する

# 1. はじめに

エイプリル・フールのネタとして DB 界隈で話題になっている PLEASE 句を Oracle でも実現してみようという話です。

[時代に即したMySQﾚの新機能：PLEASE句 - sakaikの日々雑感～(T)編](https://sakaik.hateblo.jp/entry/20210401/mysql_please_clause_in_aprilfool)

オープンソースでない Oracle では SQL パーサーを弄ることは難しいので、飽くまで「PLEASE句もどき」ですが…

# 2. 準備

まず、DB ユーザーとテーブルを作ります。

```
-- ユーザーの作成
conn sys/????????@PDB as sysdba
create user app_user identified by ???????? quota unlimited on users;
grant create session, create table to app_user;

-- テーブルの作成
conn app_user/????????@PDB
create table members (
	member_id   number(3) primary key,
	member_name varchar2(20)
);
insert into members values (1, '田中');
insert into members values (2, '山田');
insert into members values (3, '高橋');
commit;
```

#3. PLEASE 句もどきの実現

本記事ではファイングレイン監査のイベントハンドラーを用いて実現します。

まずは、監査ユーザーの作成です。

```
conn sys/????????@PDB as sysdba
create user audit_user identified by ???????? quota unlimited on users;
grant create session, create procedure to audit_user;
grant execute on dbms_fga to audit_user;
grant execute on dbms_lock to audit_user;
```

``/* please */`` というコメントを付与せずにクエリを実行した際に3秒待たせるイベントハンドラー（PL/SQL のプロシージャー）を作成します。

```
conn audit_user/????????@PDB
create or replace procedure sleep_if_rude (
	schema_name varchar2,
	table_name  varchar2,
	policy_name varchar2
)
as
begin
	-- 失礼な奴からのクエリは３秒待たせる。
	if sys_context('USERENV','CURRENT_SQL') not like '%/* please */%'
	then
		dbms_lock.sleep(3);
	end if;
end;
/
```

最後に、作成済みのテーブルにイベントハンドラーを呼び出す FGA ポリシーを追加します（今回は SELECT だけ対象にします）。

```
conn audit_user/????????@PDB
execute dbms_fga.add_policy( -
	object_schema   => 'APP_USER', -
	object_name     => 'MEMBERS', -
	policy_name     => 'please_policy', -
	handler_schema  => 'AUDIT_USER', -
	handler_module  => 'SLEEP_IF_RUDE', -
	statement_types => 'SELECT' -
);
```

# 4. 動作確認

```
SQL> conn app_user/????????@PDB
接続されました。
SQL> set timing on
SQL> select * from members;

 MEMBER_ID MEMBER_NAME
---------- --------------------
         1 田中
         2 山田
         3 高橋

経過: 00:00:03.09
SQL> select /* please */ * from members;

 MEMBER_ID MEMBER_NAME
---------- --------------------
         1 田中
         2 山田
         3 高橋

経過: 00:00:00.01
SQL>
```

``/* please */```を付与していないクエリはちゃんと3秒遅くなりました。
VS Code Remote DevelopmentとDocker-ComposeとFastAPI

# 1. VS Codeの設定
１．extentions から「Remote Development」をインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331630/0d8691c3-6729-69af-cc68-869b897d3619.png)

# 2. DockerとFastAPIの作成
#### ディレクトリ構成図
```
.
├── docker-compose.yml
├── Dockerfile
├── main.py
└── requirements.txt 
```

```Dockerfile:Dockerfile
FROM python:3.8-alpine

WORKDIR /workspace

COPY requirements.txt .

RUN apk add --no-cache build-base \
 && pip install --no-cache-dir --trusted-host pypi.python.org -r requirements.txt \
 && apk del build-base

COPY main.py .

EXPOSE 8080

```

```yml:docker-compose.yml
version: "3.0"

services:
  api:
    container_name: "fastapi_app"
    build: .
    image: fastapi
    restart: always
    tty: true
    ports:
      - 8080:8080
```

```txt:requirements.txt
fastapi
uvicorn[standard]
```

```python:main.py
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    user_id: int
    name: str
    
@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.post("/user/")
def create_user(user: User):
    return {"res": "ok", "ID": user.user_id, "名前": user.name}
```

# 3. devcontainer を作成
1. 左下の「Open a Remote Window」をクリックして、「Remote-container: Add Development Container Configuration Files...」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331630/65db2992-b8b0-ff5a-9c50-ba568649a133.png)

2. docker-compose.yml からVS Codeの設定ファイルを作成する為「From 'docker-compose.yml'」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331630/fbcdaf1a-60e8-85a8-fb2a-fa425188eec1.png)


3. 拡張機能をコンテナにインストールする為、.devcontainer/devcontainer.json の extensions に 「ms-python.python」 の拡張機能を指定する


```json:devcontainer.json
{
"extensions": [
		"ms-python.python"
    ]
}
```

# コンテナを起動
1. 左下の「Open a Remote Window」をクリックして、「Remote-Containers: Open Folder in Container」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331630/6fd6be23-7f58-44f6-4ca4-a1be19bb63d6.png)

# FastAPIサーバーを起動
```
uvicorn main:app --reload --host 0.0.0.0 --port 8000
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331630/cb35dcfa-12c6-8ecd-c57d-d8db0ebf416a.png)

# 動作確認
http://localhost:8000/docs

#### 参照
https://qiita.com/satto_sann/items/8a458a8952f50b73f420

https://qiita.com/satto_sann/items/fcd3832a1fea2c607b85

https://aimek-developer.blogspot.com/2020/09/vscode-python-flask-docker-02.html
[学習内容のまとめ]Javaのデータ型について

## Javaのデータ型の種類
- 基本データ型(プリミティブ型)
- 参照型(リファレンス型)
以上の２つに分けられる。

### 基本データ型(プリミティブ型)について
基本データ型には数値、文字(文字と文字列は違うので注意)、真偽値を代入できる。
char, int, long, float, double, booleanが該当する。

### 参照型(リファレンス型)について
参照型は、インスタンスへの参照。
種類としては、
- 配列型
- クラス型
- インターフェイス型
が挙げられる。文字列を扱うStringはクラス型(Stringクラス)である。Stringクラス以外にも、Dateクラスなどがある。

###[補足]
char型の変数には整数が代入できる。文字には番号が振られて管理されているため(文字コード)。

```java
public static void main(String[] args){
  char c1 = 97;
  System.out.println(c1); // 実行結果: a
  char c2 = '\u0061'; //unicodeに従ったときのa
  System.out.println(c2); // 実行結果: a

  // bの文字コードを確認する
  char c3 = 'b';
  int c4 = (int)c3; //数字型に変換する
  System.out.println(c4); // 実行結果: 98
}
```