OmniAICreator/Qiita-1.07M huggingface dataset:
VHF帯　真空管アンプの内部構造

約25年前、HTML手打ちで自作機器のWEBサイトを作っていました。
Geocitiesで長らく公開＆放置していたのですが、Geocities廃止と共に消えてしまいました。
何かの役に立つと思うので、当時の内容を（多少修正して）QiitaにUPします。
今見るとずいぶんわかりづらいが追って修正します。
***
当時、業務用のVHF帯真空管アンプの中身を見る機会があって写真を撮りました。
当時のデジカメのピクセル数は640x480しかなくしかもトリミングしてあるので今となってはとても小さい画像しかないです。
11枚目の画像で見切れている週刊少年マガジンが古すぎて泣ける・・・
***
![amp1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/26310562-5488-cdce-cbce-0f663bd769ce.jpeg)
![amp5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/5f997a51-e570-eb20-fd1b-ddc5da7b475b.jpeg)
![amp6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/182621d8-042d-8dff-9e30-e17a9384cc08.jpeg)
![amp7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/09a7350a-7ad8-4efa-eb5f-20bacb6489c3.jpeg)
![amp8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/71d82d70-de1c-62d3-9b2d-e90b2b140ac5.jpeg)
![amp12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/0a843eba-6128-94d4-69fe-d891d8fc0cd8.jpeg)
![amp13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/76e58905-39ed-3bdf-5e99-e18e3d938ac5.jpeg)
![amp14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/94d94bab-fa14-7231-a036-3d49a71d8a6b.jpeg)
![amp16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/49801b07-b324-a499-6766-2c3c514e855d.jpeg)
![amp17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/ab60779b-c91a-ee76-68e6-150f6128a053.jpeg)
![amp18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/9669d89a-84cc-06e6-d8e7-b5f062ac1ca2.jpeg)
![amp18-s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255615/a1063403-75a9-3542-c1b3-882435876628.jpeg)
Kali Linuxでpip2を使う

#書くこと
Kali LinuxでPython2のコードを実行しようとしたときにモジュールがないと言われたので、pipでインストールしようとしたのですが、Python2でpipが使えなかったのでインストールした時の話です。
#環境
* ホストOS: macOS Big Sur 11.5.1
* ゲストOS: Kali Linux 2021.2
* Python2: 2.7.18
* 仮想化ソフト: VirtualBox

#pipのインストール
私は最初、pipをインストールするためにhttps://pip.pypa.io/en/stable/installing/ というサイトのget-pip.pyをダウンロードしました。そして、以下のようにget-pip.pyを実行しました。

```
$ python get-pip.py
ERROR: This script does not work on Python 2.7 The minimum supported Python version is 3.6. Please use https://bootstrap.pypa.io/pip/2.7/get-pip.py instead.
```
すると、上のようなエラーが出ました。このスクリプトはPython 2.7で動かないようです。

調べると、Python2.7用のget-pip.pyは違う場所に置かれていたようなので、そちらを使うことにしました。

以下のようにコマンドを実行し、インストールをしました。

```
$ curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py                                                                                                                     1 ⨯
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1863k  100 1863k    0     0  5716k      0 --:--:-- --:--:-- --:--:-- 5716k

$ python get-pip.py                                                     
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Defaulting to user installation because normal site-packages is not writeable
Collecting pip<21.0
  Downloading pip-20.3.4-py2.py3-none-any.whl (1.5 MB)
     |████████████████████████████████| 1.5 MB 6.5 MB/s 
Collecting wheel
  Downloading wheel-0.36.2-py2.py3-none-any.whl (35 kB)
Installing collected packages: pip, wheel
  WARNING: The scripts pip, pip2 and pip2.7 are installed in '/home/kali/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script wheel is installed in '/home/kali/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-20.3.4 wheel-0.36.2

```
ここで、The scripts pip, pip2 and pip2.7 are installed in '/home/kali/.local/bin' which is not on PATH.とあり、pipは/home/kali/.local/binの下にあるようです。

```
$ ls /home/kali/.local/bin                                                                                                                                                            1 ⨯
pip  pip2  pip2.7  wheel
```
無事にインストールされていました。

#まとめ
最終的に、自分の環境ではpipを使ってモジュールを導入することができました。
次に使うことはないかもしれないです。
pip2を繰り返し使う予定のある方はpipのパスを通しておくと良いかもしれないです。
ディレクトリトラバーサルとは何か調べてみた

<body>
    <h1>はじめに</h1>
        <p>
            本記事では、ディレクトリトラバーサルとはどのような攻撃か、
            この攻撃を受けるとどのような被害が発生するのか、
            どのような対策を講じれば防ぐことができるのかを説明します。
        </p>
    <h1>ディレクトリトラバーサルとはどのような攻撃か</h1>
        <p>　　
              「トラバーサル」とは横断、という意味です。
            ディレクトリトラバーサルは一般には公開されていないディレクトリを参照して
            ファイルを閲覧する攻撃手法です。
            　親ディレクトリを指定した相対パスや絶対パスをサーバへと送ることで実現します。
            このことからパストラバーサルとも呼ばれています。
        </p>
    <h1>どのような被害が発生するのか</h1>
        <p>
            パスワードファイルを盗み見られ、不正ログインされたり、情報を改ざんされたりします。
        </p>
    <h1>対策</h1>
        <p>
            公開しているファイルにIDを対応させて、IDを指定させる
            外部からファイルパスを受け付けないようにする、
            ファイル参照に相対パスを指定させない、
            不正なアクセスを検知した時点で遮断する
            などがあげられます。
        </p>
    <h1>おわりに</h1>
        <p>
            HTTPヘッダの理解やOS、言語それぞれの特徴を把握することで適切な対応が出来ます。
            これらの仕組を学習していき、より深い理解を目指していきます。
            読んでいただきありがとうございました。
        </p>
</body>
</html>
DETReg: Unsupervised Pretraining with Region Priors for Object Detection

# 物体検出向け教師なし事前学習手法：DETReg: Unsupervised Pretraining with Region Priors for Object Detection


## 一行で

Transformerによる物体検出向け教師なし事前学習を提案しfine-tuning形式のベンチマークでSoTA

## 要約

近年、教師なしの事前学習が有効であることが示されており、画像分類では教師あり学習と同等あるいは同等以上の性能が出ている。他方、これらの既存手法は、物体検出におけるオブジェクトのローカライズという側面を扱っておらず、物体検出に適した設計となっていない。本論文では、物体検出のための教師なしの事前学習手法として、領域に関するPriorを組み合わせたTransformerであるDETRegを提案。

## 手法

提案手法では、物体検出の基礎となる2つのタスク、すなわちローカライゼーションとカテゴライズに相補的な信号を組み合わせて自己教師化する。ローカライズの信号には、Off-the-shelfな手法であるSelective Searchで得られる、pseudo-labelとしてのbboxを使用。オブジェクトの特徴に関する信号には、Contrastive LearningのSoTAであるSwAVを用いる。この2つをBipartite Matchingで組み合わせ、ラベルなしデータで学習。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860620/b67775fe-4a46-4b64-8c56-d568b06306ff.png)

## 定量的な評価結果

MS COCOのfine-tuning形式の評価において、通常の物体検出手法としてDeformable DETR、従来の教師なし手法としてMoCoV2、Ablation studyとしてDeformable DETR+SwAVと比較。
fine-tuningデータがフルセットの1%から10%の範囲にかけて提案手法が既存手法よりも明らかに良い結果を示しており、具体的にはデータの割合が1%から5%程度の領域ではMoCoV2等との手法と比較して10pt前後の開きがある。データの割合が増えてくる10%以上では、MoCoV2等の手法との差が縮まってくるが、5pt程度はあり、また、ベースラインと比較すると10pt前後の開きがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860620/84351943-8a80-ac3c-61fc-abe59e5125b7.png)

## 実装

https://github.com/amirbar/DETReg
Vue.jsをHTMLにインラインで書く&コンポーネントを別ファイルで書く

# 経緯
- webページの中の1ページだけVue.jsで書きたい
- cdnのvueを使ってhtmlにインラインでvueを書くことにする
- 1ページなんだけどコード量はまあまあ多くなりそうなので、パーツをコンポーネント化して別ファイルに書きたい

→やり方がわからなかったので実験した

# 環境
Mac OS BigSur v11.4
Vue.js 2系
php 7.3.24(テンプレートエンジンとして使用)

# 作るもの
vueの公式にあるカウンターボタンを子コンポーネントとして別ファイルで作る
https://jp.vuejs.org/v2/guide/components.html
![スクリーンショット 2021-08-08 0.58.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284906/9236e114-9b4c-71f8-66da-7f383d6615af.png)

# やり方①jsファイルに書く
- 子jsファイルでvueコンポーネントを定義し、templateのDOMは文字列(下記`counterButton.js`の`template`)に実装する。
- 親htmlから子jsファイルをscriptタグで読み込む

```js:counterButton.js
const template = `
<div>
  <button v-on:click="count++">You clicked me {{ count }} times.</button>
</div>
`;

Vue.component('counter-button', {
  template,
  data: function () {
    return {
      count: 0,
    };
  },
});
```
```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>vue-cdn</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="./js/counterButton.js"></script>
  </head>

  <body>
    <div id="app">
      <counter-button></counter-button>
    </div>

    <script>
      new Vue({
        el: '#app',
      });
    </script>
  </body>
</html>
```

### :smile:メリット
- jsファイルなのでvueのコードは書きやすい(自動フォーマットとか設定してればちゃんと動く)

### :sob:デメリット
- DOMは文字列で書く必要があるため、可読性が低い
- バッククオートで囲めば改行もできるが、ハイライトとかされないのでやっぱり可読性は低い

# やり方②テンプレートエンジンのhtmlに書く
- 今回はテンプレートエンジンとしてphpを使用(macでデフォルトのphpがサクッと使えたので)
- 子phpファイルにて、コンポーネントをscriptタグ内で定義し、templateのDOMは`x-template`を使用して実装する。
- 親phpから子phpファイルをincludeする

```php5:counter-button.php
<script type="text/x-template" id="counterButton">
  <div>
    <button v-on:click="count++">You clicked me {{ count }} times.</button>
  </div>
</script>
<script>
  Vue.component('counter-button', {
    template: '#counterButton',
    data: function () {
      return {
        count: 0,
      };
    },
  });
</script>
```

```php5:index.php
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>vue-inline</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  </head>

  <body>
    <div id="app">
      <span>{{ message }}</span>
      <counter-button></counter-button>
    </div>

    <?php include('./components/counterButton.php'); ?>
    <script>
      new Vue({
        el: '#app',
      });
    </script>

  </body>
</html>
```

### :smile:メリット
- DOMもvueもscriptタグ内に書くので、わりと綺麗に書ける(自動フォーマットとかハイライトとか設定してればちゃんと動く)

### :sob:デメリット
- 最終的にブラウザにレンダリングされるDOMが、body内にscriptタグが乱立してたりしてちょっと見苦しい(動作に問題はない。たぶん。)

## 個人的には
②のテンプレートエンジンで外部化する方がいいと思う。
①のように文字列でDOMを書くのはかなりきつい。
もうちょっと複雑なhtml属性やらvueの制御を書くことになった時にしんどくなると思う。

②は単一ファイルコンポーネントで書くときとほぼ同じ感じで書けるので、個人的には抵抗なく実装が進められそう。
今回はたまたまphpでやってるが、Thymeleafとかその他テンプレートエンジンでもincludeさえできれば問題なく動くはず。

## 参考にさせていただきました
https://johobase.com/vue-js-x-template/
AWS CAF とは

## 勉強前イメージ

よくわからない・・・
Cから始まるのってあまりない

## 調査

### AWS CAFとは

AWS Cloud Adoption Framework の略で、AWSへのクラウド導入フレームワークになります。
まだAWSを利用していない企業などがクラウドサービスを導入するために、効果的な計画を建てるサポートをします。
それぞれ6つの分野ごとにガイダンスが用意されています。
そもそもどうやってクラウドを導入したら良いかわからない・・・という人に役立ちます。

### 6つの分野

6つの分野はCAFではパースペクティブと呼ばれます。
クラウド導入時、それぞれどういう視点で見る必要があるのかというのが記載されています。
以下の6つになります。

- ビジネス
	- IT戦略やビジネスリスクについて求められる
- 人員
	- スタッフのリソース管理や組織変更管理について求められる
- ガバナンス
	- プログラム・プロジェクト管理やライセンスについて求められる
- プラットフォーム
	- アーキテクチャや開発について求められる
- セキュリティ
	- インシデントへの対応やインフラのセキュリティについて求められる
- オペレーション
	- モニタリングやレポートと分析について求められる

## 勉強後イメージ

そもそも会社がどうやってクラウドを導入したら良いのか、という教科書みたいなやつ？
人事観点やビジネス観点での視点もある。

## 参考

- [AWS クラウド導入フレームワーク「AWS CAF」とは](https://www.cloudsolution.tokai-com.co.jp/white-paper/2021/0413-229.html)
- [3大パブリッククラウドのクラウド導入ベストプラクティスを読んでみた](https://dev.classmethod.jp/articles/cloud-adoption-framework-on-each-clouds/)
AWS Application Discovery Service とは

## 勉強前イメージ

アプリケーションを見つけるサービス・・・？

## 調査

### AWS Application Discovery Service とは

略してADSと書きますが、
オンプレのサーバの使用状況と設定データを収集することが出来ます。
AWSへの移行時に情報収集に時間がかかる場合がありますが、
これを利用することで必要なデータを取得することが出来ます。

### AWS Application Discovery Service のメリット

- 移行計画のための確実なデータ検出

サーバーの仕様情報、パフォーマンスデータなど詳細情報が収集されます。
AWS移行前の詳細なコストの見積もりなどで使用することが出来ます。

- MIGRATION HUB との統合

AWS Migration Hubと統合されています。
移行の進捗を簡単に追跡できます

- 暗号化によるデータ保護

AWSへの転送中も保管中も
収集されたデータは暗号化によって保護されます。

- 移行の専門家と連携

AWSのプロフェッショナルは
Application Discovery Service で取得したデータを分析することができるので、
最適な移行戦略を提案してもらうことができます。

- Athenaでのデータ調査

AWSのサービス、Athenaで収集したデータを分析することが出来ます。
データの生データだけでなく、分析をAWS内で行うことが出来ます。

### 検出方法

- エージェントレス検出

サーバーホスト名やIPアドレス、VMごとの利用状況データなどを収集することができます。
エージェントをサーバにインストールをしないタイプです。
エージェントをサーバにインストールしないので動作に影響しないなどメリットがあります。

- エージェントベース検出

エージェントをサーバにインストールするタイプで、サポートされているOSだけで使用することが出来ます。
Windows Serverや有名なLinuxなどに対応しています。

## 勉強後イメージ

オンプレの情報を取得することができるのは、すごい気になる・・・
一回やってみたい・・。
監視とかでも似たような情報を取得できると思うけど、分析できるのはすごいいいね

## 参考

- [AWS Application Discovery Service](https://aws.amazon.com/jp/application-discovery/)
- [AWS Application Discovery Serviceのご紹介！](https://www.acrovision.jp/service/aws/?p=2611)
- [AWS移行]移行アセスメントを効率化する[AWS Application Discovery Service(ADS)](https://dev.classmethod.jp/articles/application-discovry-service/)
メモ > GCP > Cloud Run



以下をみつつ作業したメモです。


[コンテナ イメージのデプロイ  \|  Cloud Run のドキュメント  \|  Google Cloud](https://cloud.google.com/run/docs/deploying?hl=ja)



# SDK


```
brew install --cask google-cloud-sdk
```




# 準備


Cloud BuildのAPI有効化,

Cloud Strageの有効化




# プロジェクトの作成

```
gcloud init

gcloud projects create cloud-run-hello-ktor
```



## workspaceのセット

```
$ gcloud config get-value project
```
>cloud-run-hello-ktor


```
gcloud config set project cloud-run-hello-ktor
```



## Cloud Build でのbuild

```
gcloud builds submit --tag gcr.io/cloud-run-hello-ktor/helloworld-ktor
```




## Cloud Run へのデプロイ

```
gcloud run deploy --image gcr.io/cloud-run-hello-ktor/helloworld-ktor --platform managed
```






# 初期設定


```
gcloud config set run/platform managed

gcloud config set run/region asia-northeast1
```

asia-northeast1（東京）




# 同時実行とメモリ制限を調整する


[同時実行の仕組み](https://cloud.google.com/run/docs/about-concurrency)を学習して、サービスの同時実行サポートを最適化します。詳細については、[同時実行を調整するための開発のヒント](https://cloud.google.com/run/docs/tips#tuning-concurrency)をご覧ください。

サービスに必要な一時ファイル ストレージの容量も含めて、アプリケーションの実行に十分なメモリ制限が設定されているかどうか確認してください。
[JavaScript]用語一覧

# はじめに
本記事では、JavaScriptを学習した際に、はじめに登場するものを紹介します。
本日、復習したため、アウトプットを兼ねて投稿いたします。

# JavaScriptとは
プログラミング言語の1つで、主にクライアントサイドにおいて使用します。
「ブラウザ上でアプリケーションを便利に使えるように」
「リクエストの送り方の工夫」などをすることができます。

つまり、使い勝手の良いアプリケーションの作成ができるということです。

```
(ex)カーソルを当てると、ブラウザを更新せずメニュー画面が表示される。
```

# 用語一覧
### console.log
コンソールにテキストを表示させるメソッドです。
コンソールに引数が表示されます。
Rubyでいう`putsメソッド`と同様の意味があります。

```js
console.log("Thank you")
//コンソール上では、「Thank you」が表示されます。
```

### var
`再定義、再代入が可能`です。
しかし、誤った記述をすることが多く、現在では、開発現場であまり使われないようです。

```js
var sample = "田中"

sample = "伊藤"
// 再代入可能

var sample = "中村"
// 再定義可能
```

### const
後から書き換えはできない変数を定義するものです。
`再代入、再定義は不可`です。
割と使用する印象です。

```js
const sample = "田中"

sample = "伊藤"
// 再代入NG →エラーが起こる

const sample = "中村"
// 再定義NG →エラーが起こる
```

### let
後から書き換えることができる変数を定義するものです。
`再代入は可能`ですが、`再定義は不可`です。

```js
let sample = "田中"

sample = "伊藤"
// 再代入OK

let sample = "中村"
// 再定義NG →エラーが起こる
```

### for
繰り返し処理を行う際に使用します。

```js
for ([①初期化式]; [②条件式]; [③加算式]) {
  // 繰り返す処理の内容
}
```

①初期化式
変数を定義します。`何回目の処理であるか`を判定するために使用されます。
②条件式
処理を何回繰り返すかを指定します。条件式の戻り値がtrueで有る限り処理は行われ続けます。
③加算式
定義した変数の増減を記述できます。
例えば、（i=i+1）、（i+=1）、（i++）などと記述すれば1周ごとに1が加算されて、処理が実行されます。

```js
for ( let i = 1; i <= 100000; i++ ) {
  // 100000回繰り返し
}
```

### forEach関数
配列に存在する要素に対して、繰り返し処理を行う場合に用いられる関数です。

```js
sports = ["soccer", "baseball", "tennis"]
sports.forEach(function(item) {
  console.log(item)　
})

//soccer,baseball,tennisの順に取り出されます。
```

### function
関数を定義することができます。
functionに続けて関数の名前を記述し、`()のなかに引数`、`{}のなかに処理`を記述します。
Rubyにおける`メソッド`と文法的に意味は同じようなものです。

＊引数がない場合にも()を記述する必要があることに注意しましょう。

```js
function sayYO(){
  console.log("ヨイショ")
}

sayYO()

//コンソール上で、「ヨイショ」と表示されます。
```

### 関数宣言
ここまででの関数の定義する方法は、`関数宣言`といいます。

```js
function 関数名( 引数 ){
  // 関数内の処理
}
```

### 関数式
関数宣言とは、記述に違いがあります。

```js
変数 = function( 引数 ){
  // 関数内の処理
}
```

#### 関数宣言と関数式の違い
読み込まれるタイミングに違いがあります。

関数宣言・・・上から順にコードが読み込まれる。
関数式・・・上から順に読み込まれることはない。

### 関数式の種類
#### 無名関数
関数名なしで関数を定義することができます。
コードを簡単に記述することができます。
関数名の重複を避けることができます。

```js
const rice = function(){
  console.log('米')
}

//ターミナル上には、「米」が表示されます。
```

#### 即時関数
関数を定義するのと同時に処理を実行します。
定義してから呼び出す手間がなくなります。

```js
(function countNum(number) {
  console.log(number)
})(2)

//ターミナル上には、「2」が表示されます。
```

#### アロー関数
functionを省略し、`()=>`を記述することで関数を定義します。
見た目がスッキリし、短い記述で関数を定義できます。

```js
const countNum = (number) => {
  console.log(number)
}
countNum(5)

// ターミナルには、「５」が表示されます。
```

### セミコロン
`;`です。
JavaScriptでは、変数定義の最後に`;`をつけて終了することがあります。

これは、開発現場によって有る場合と無い場合があるようで、
注意が必要です。

# 終わりに
JavaScriptも用語が多いので、ここで終了します。

はじめにも書きましたが、本日JavaScriptの復習をしましたところ、
かなり知識が抜けていましたため、アウトプットいたしました。

しかし、JavaScriptはクライアントが使いやすいように必要不可欠な言語であることから、
私は、今のところ一番好きかもしれません。

Railsとも交えてアプリケーションを作成することが増えるかと思うので、
このタイミングでしっかりと復習し、理解しておきます！

それでは、明日も頑張ります！！
【React】Youtubeのロード中に表示されるスケルトンを実装したい【MaterialUI】

<h2>こんな感じのやつを実装したい</h2>
youtubeでどうがを読み込んでいる際に下記のようなロード状態になると思います。
このロード状態を表すMaterialUIのスケルトンを今回は実装していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/ebd0de42-ac9f-bc1d-938f-e4f83394a259.png)


<h2>実装例</h2>
実装方法は意外とシンプル。
下記のように、MaterialUIの部品をimportして、どんな形で置くかを指定するvariantとWidthとheightをざっくり指定すればOK。
公式ページからコードを引用しました。

```react:skelton
import React from 'react';
import Skeleton from '@material-ui/lab/Skeleton';

export default function Variants() {
  return (
    <div>
      <Skeleton variant="text" />
      <Skeleton variant="circle" width={40} height={40} />
      <Skeleton variant="rect" width={210} height={118} />
    </div>
  );
}
```

上記のコードだと、下記のような表示になります。
variantの指定によって、形が丸や四角、テキストタイプになるので、自分の実装したい形で指定すると良いでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/e82a0675-03dc-a2bd-45ad-c40b4087b650.png)



<h2>参考</h2>

https://v4-3-3.material-ui.com/es/components/skeleton/
サクラエディタ 正規表現 便利技

## 選択(黄色)部分の解除
Ctrl +F3

## 先読み後読み
|項目|例|例の説明|
|----|----|----|
|肯定的先読み|テスト(?=大阪府)|テストの<b>直後</b>に大阪府を含む|
|否定的先読み|テスト(?!大阪府)|テストの<b>直後</b>に大阪府を<b>含まない<b>|
|肯定的後読み|(?<=大阪府)テスト|テストの直前に大阪府を含む|
|否定的後読み|(?<!大阪府)テスト|テストの直前に大阪府を<b>含まない<b>|

### 肯定的先読み（直後に任意の文字列を含む）

#### 例）「大阪」を含む行を抽出

```
^(?=.*大阪).*
```

#### 例）最初の「大阪府」までを抽出

```
^.*?(?=大阪府)
```
#### 例）最後の「大阪府」までを抽出

```
^.*(?=大阪府)
```

#### 例）複数条件に一致する行
```
^(?=.*大阪府)(?=.*労働)(?=.*賃金).*
```


### 否定的先読み（直後に任意の文字列を含まない）

#### 例）先頭が3桁の数字で始まらない行を抽出
```
^(?![0-9]{3}).*$
```

#### 例) 「大阪」を含まない行を抽出

```
^(?!.*大阪).*$
```

参考記事

https://uxmilk.jp/50674

https://abicky.net/2010/05/30/135112/


## 指定文字から文末までを一括削除
```
--大阪府から文末までを削除
大阪府.*
```

![20210807サクラエディタ 正規表現 特定の文字列から削除.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/56d78829-c3b5-5eb6-f63b-11a51f11750b.png)


## タブ/半角スペースを置換

タブを置換
![20210808 サクラエディタ タブを複数の半角スペースに置換.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/a86f508b-43f9-cfd8-777b-8f0e82b76ad5.png)

半角スペースを置換
![20210807 半角スペースを複数の半角スペースに置換するには「正規表現」にチェック - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/a24219cc-80a8-2b2e-4a28-5d3d336abcad.png)




```
--その他の正規表現
\t	タブ	(なし)
\r	改行。CR(Carriage Return：0x0D)	(なし)
\n	改行。LF(Line Feed：0x0A)	(なし)
\d	すべての数字	[0-9]
\D	すべての数字以外の文字	[^0-9]
\s	垂直タブ以外のすべての空白文字	[ \t\f\r\n]
\S	すべての非空白文字	[^ \t\f\r\n]
\w	アルファベット、アンダーバー、数字	[a-zA-Z_0-9]
\W	アルファベット、アンダーバー、数字以外の文字	[^a-zA-Z_0-9]
```

https://qiita.com/hayate242/items/7106977b6460c5120fb4


## 行頭/末尾に付いている空白を削除
「編集」> 「整形」 > 「右末尾の空白を削除 Alt + r 」もしくは「左先頭の空白を削除 Alt + l」 

![20210807 半角スペースをカット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/4a7c65aa-206b-1600-aa13-22d81b856f51.png)




## Grep 機能
Grep:「global regular expression print(ファイル全体から/正規表現に一致する行を/表示する)」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/a0700e48-3970-edc3-9fd5-98ef0f57187c.png)

|項目|説明|例|
|----|----|----|
|条件(N)|検索ワードを入力|hogehoge|
|ファイル(T)|\*.\*||
|フォルダ(O)|検索対象のディレクトリを指定|C:\Users\sample\Desktop\grep|

```text
□検索条件  "hogehoge"
検索対象   *.*
フォルダ   C:\Users\sample\Desktop\grep
    (サブフォルダも検索)
    (英大文字小文字を区別しない)
    (文字コードセットの自動判別)
    (一致した行を出力)

C:\Users\sample\Desktop\grep\testfile_.sql(823,30)  [SJIS]: A:hogehoge
C:\Users\sample\Desktop\grep\testfile_.sql(831,30)  [SJIS]: B:hogehoge
C:\Users\sample\Desktop\grep\testfile_.sql(839,30)  [SJIS]: C:hogehoge
3 個が検索されました。

```
データベース

https://coin1.karou.jp/osk.html
GatsbyでFirebase Analyticsを使うとビルドでエラる問題

# トラブル
最近Gatsbyで個人サイトを作っていて、Firebase Hostingを使ってるのでついでにFirebase Analyticsも使おうと思って、gatsby-plugin-firebaseをインストールして、ドキュメンテーションに従ってセットアップしたらビルドでこの様なエラーが出ました。

![Screen Shot 2021-08-08 at 0.25.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1825969/369702ea-66ec-5062-3d20-c859fe774645.png)

ネットで解決方法を探して、下のようにWebpack設定を変更してみてもなかなかうまくいきませんでした。

```gatsby-node.js
exports.onCreateWebpackConfig = ({ stage, actions, getConfig }) => {
    if (stage === 'build-html') {
    actions.setWebpackConfig({
      externals: getConfig().externals.concat(function(context, request, callback) {
        const regex = /^@?firebase(\/(.+))?/;
        if (regex.test(request)) {
          return callback(null, `umd ${request}`);
        }
        callback();
      }),
    });
  }
};
```

（これが効く場合もあります、詳細は文の最後に）

# 解決方法
今回問題はNode.jsで使えないFirebaseのAnalyticsパッケージを使ってしまったのが理由でした（そしてそれについて完全に忘れてしまったのも理由の一つでした）。
それでAnalyticsに関連する関数を使う前に一回ブラウザー環境チェックして、ブラウザ環境であることを確認してからAnalyticsを使えば問題解決となります。

```index.js
const isBrowser = typeof window !== "undefined"
  if (isBrowser) {
    firebase.analytics().logEvent('visited_home_page')
  }
```

これで解決になりますが、使うことに環境チェックするのはちょっとめんどくさいので、useFirebaseAnalyticsという別のユーティリティ関数として抽出しました。（カスタムフックではないのに名前をuse何ちゃらにしてしまいすみません）

```fbAnalytics.js
import firebase from "gatsby-plugin-firebase"

// Build throw error if it's ran on node
// Adding an isBrowser to ensure that the below code would only ran on browser
const useFirebaseAnalytics = logEvent => {
  const isBrowser = typeof window !== "undefined"
  if (isBrowser) {
    firebase.analytics().logEvent(logEvent)
  }
}
export default useFirebaseAnalytics

```
これでFirebase Analyticsがちゃんと動き出しました。

![Screen Shot 2021-08-08 at 0.48.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1825969/7475ad35-1d2a-bf26-a81e-025b6aace950.png)


# 後書き
解決方法の前に書いてある方法は実際Firestoreなどを使うときビルド失敗した場合にちゃんと効くらしいので、必要がある方はぜひ。
今回は単純にFirebase Analyticsがブラウザでしか使えないことを忘れてしまうことでビルド失敗しましたが、自分と同じく忘れん坊な方のために文章にしました。ご清聴ありがとうございました。
【Ruby】SeleniumでPDFをダウンロードする

RubyつかってPDFを自動でダウンロードしたい。
自動でやるにはSeleniumというライブラリをつかう。

つかってみて、ExcelやCSV、HTMLから直どりでデータを取得することができた。

しかし、PDFだけはChromeがViewrモードになって、いっこうにダウンロードできない…。

立ち上げるブラウザのoptionの「always_open_pdf_externally」をtrueにして、
Viewerモードでなく、常にダウンロードできるようにしているはずなのに…！


それが解決できたので、記事として残す。


こんな設定でやってた。

```ruby:
@driver = Selenium::WebDriver.for :chrome

prefs = {
  prompt_for_download: false,
  default_directory: File.absolute_path("./dl")
}

plugins_prefs = {
  always_open_pdf_externally: true
}

options = Selenium::WebDriver::Chrome::Options.new
options.add_preference(:download, prefs )
options.add_preference(:plugins, plugins_prefs ) 
@driver = Selenium::WebDriver.for :chrome, options: options

```

「always_open_pdf_externally」を文字列にして、
optionの書き方を「:」から「=>」に変える。

なお、「prompt_for_download」などのoptionは文字列にしたら、効かなくなった。


これならダウンロードできた。

```ruby:
　　@driver = Selenium::WebDriver.for :chrome

    prefs = {
      :prompt_for_download => false,
      :default_directory => File.absolute_path("./dl")
    }

    plugins_prefs = {
　　 　# 文字列
      'always_open_pdf_externally' => true
    }

    options = Selenium::WebDriver::Chrome::Options.new
    options.add_preference(:download, prefs)
    options.add_preference(:plugins, plugins_prefs)
    @driver = Selenium::WebDriver.for :chrome, :options => options
```

Seleniumのバグのよう。


参考：
https://stackoverflow.com/questions/66247385/watir-wont-download-pdf-only-opens-in-viewer
M5StickCでまたパスワード入力装置を作った

以前にも、M5StickCでパスワード入力装置を作成しました。一方で、以前パスワード管理アプリ・サーバをPWAで作成していました。
今回は、この2つを組み合わせて、より使いやすいパスワード入力装置を作ります。

以前の記事は以下にあります。

* [PWAを試してみよう](https://qiita.com/poruruba/items/77cbb6448d804e6e996b)
* [M5Stick-Cでパスワード記憶装置 兼 自動入力装置を作る](https://qiita.com/poruruba/items/6e4e29068a28f5ee1711)

ソースコードもろもろは新たに以下のGitHubに上げています。

poruruba/PasswordReminder
※当然ですが、自己責任でお願いします。

https://github.com/poruruba/PasswordReminder

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/48eee577-262d-65ff-0827-88b44c5d2489.png)

#パスワード管理用サーバ

PWAアプリやM5StickCからのリクエストをHTTP POST(Json)として受け取り、レスポンスをJSONとして返します。
誰でもアクセスできては困るので、ファイル名を秘匿の名前にし、API Keyとしてそのファイル名を指定しないとアクセスできないようにして保護しています。

以下のエンドポイントを用意しています。

・/pwd-insert ： パスワード情報を登録します。
・/pwd-update ： パスワード情報を更新します。
・/pwd-delete ： パスワード情報を削除します。
・/pwd-get ： パスワード情報を取得します。
・/pwd-list ： パスワード情報のリスト(パスワードを含まない)を取得します。
・/pwd-allpasswd ： パスワード情報のリスト(パスワードを含む)を取得します。

以下は、PWAの通知用です。必須ではないです。

・/pwd-get-pubkey ： 通知の購読に必要なVapidKeyのうちの公開鍵vapidkey.publicKeyをクライアントに渡します
・/pwd-put-object ： 通知の購読に必要なクライアント側のオブジェクトをサーバ側に登録します。
・/pwd-delete-object ： サーバ側に登録しておいたクライアント側のオブジェクトを削除します。

すべてにおいて、HTTP HeaderのX-API-KEYにファイル名の指定が必要です。

node/data/passwordフォルダに、パスワードを管理するファイルを配置しますが、RAID化されたフォルダに置くのが安心です。

#PWAアプリ

上記のエンドポイントを呼び出して、パスワード管理用サーバにパスワードを登録したり編集したりするWebアプリです。PWAとしているため、AndroidやiPhoneなど機種を問わずネイティブアプリのように使うことができます。
パスワードを選択してアプリ上のボタンを押すと、パスワードがクリップボードにコピーされるので、入力したい場所でCtrl-Vを入力すればよいです。

このアプリが結構便利でいつも自分用に使っています。

#M5StickC

パスワード管理用サーバとPWAアプリだけでも、かなり使えるアプリですが、M5StickCを使ってもっと手軽に使えるようにします。
M5StickCをBLEのHIDデバイス(キーボード)としてふるまうようにすることで、M5StickCにある物理ボタンを押すだけで、素早くパスワード入力できるようになります。

以前もこのM5StickCで作っていましたが、パスワードの登録のために、USB仮想COMポートを使っていて、管理が面倒でした。パスワードの管理はPWAに任せることで、今回はM5StickC側の実装がシンプルになりました。

通常は、BLEが有効となって、HIDとして機能していますが、PWAを使って更新したパスワードファイルをM5StickCに持ってきたい時だけ、WiFi接続して、HTTP POST(Json)呼び出ししています。
複数のパスワードを管理していますが、横のボタンで対象のパスワードを選択することができます。M5StickCのLCDディスプレイに選択中のパスワードのタイトルとユーザIDが表示されます。
そして、表のボタンを押すことで、選択しているパスワードがキーボードから入力されたように振る舞います。
パスワードの同期は、横の電源ボタンを短めに押します。

以上
未経験の学生が２ヶ月の共同開発を終えての感想

#はじめに
**・投稿した経緯**
　6月から２ヶ月間、一人の方と私立探求学園の共同開発に参加しました。結論として
とても良い経験で、僕と同じ未経験の方にはとてもお勧めできる内容でした。
振り返りと学習したことのアウトプットも兼ねて今後参加したいと思う方の参考になればと思い
ます。

#目次
・参加前の状況
・参加した理由
・共同開発の概要(簡単に)
・共同開発で身についたこと
・共同開発で苦労したこと
・全体的な感想
・まとめとこれから

#参加前の状況
・大学2年生２０歳
・２ヶ月間別のプログラミングスクールに通い、文法などの基礎学習と
　個人アプリをテンプレートの教材をもとに作成した程度
・個人で１からアプリを作るといった経験はなし

#参加した理由
・Laravelのアプリを開発できる
・実務では必須のチーム開発を経験することができる
・一緒に開発する仲間がいる
・講師の方に質問、相談できる環境だった


#共同開発の概要(簡単に）
・２ヶ月間で掲示板アプリとECサイトの作成
・今回の開発人数は2人(基本は３〜４人程度)
・週２回のMTG
・Gitでバージョン管理
・GitHubの使用
・質問や連絡などはslackというチャットツールを使用
　[slackとは](https://slack.com/intl/ja-jp/help/articles/115004071768-Slack-%E3%81%A3%E3%81%A6%E4%BD%95%EF%BC%9F)

#共同開発で身についたこと
**①チーム開発スキル**
GitHubのプルリクエストの作成やブランチの切り替え、コンフリクトの解消など
特にGitやGitHubは初めて経験することばかりでした。1人で学習していると経験できないが
実務では確実に必要なことを経験できたことが良かったと感じています。

**②チーム開発の作法や現場目線のコードの書き方**
チーム開発ではpush先を間違えてはいけない、ブランチの切り替えを忘れないことなど
こちらも一人で学習していれば気づけない点を学べました。
またコードレビューではこう書いた方が良いですよ、実務でも〜は使用しますなど現場目線の
ご意見をいただけたので視野が広がりました。

**③エラー対応の引き出しが増えた**
何度も見たエラーの場合、原因がどこにあるのかなんとなく予測できるように、
またデバッグ関数の使い方も講師の方に伺い、エラー解決までの時間が
徐々に短くなりました。
どうしてもわからないエラーは講師の方に質問することで全て解決できました。

**④質問力がついた**
現場に入ってからも必要な質問の仕方について学ぶことができました。
エラーの質問は相手が一度聞けばわかるように質問することが大事と知り、
開発初期は質問作成に１時間ほどかけていました。
最後に講師の方が初期の頃より質問がうまくなったと言ってくださり
とても嬉しかったです(笑)

**⑤説明力がついた**
MTGでは同じ受講生の方と自分の実装箇所を説明し合い、気になる部分は質問したり
しました。(独自にやっていたことです) 言語化することでより深い理解につながる点と、
自分が実装していない箇所の知識がつく点で実施していました。
また最終発表で資料を作成し２ヶ月の成果発表をしたのですが
人前で作成した資料をもとに説明する経験があまりない学生の僕には
ありがたい機会でした。

**⑥Linuxコマンドや仮想環境の知識**
共同開発を通してLinuxコマンドや仮想環境を使用する
経験もでき、調べるようになりました。特にLinuxコマンド
に関しては実務で使用する機会が多いと思うので経験できて
よかったと感じています。

#共同開発で苦労したこと
**①チーム開発においてやってはいけないことの意識**
例えばmasterブランチで作業をしていた、push先を間違えたなどは
何度もミスをし講師の方にフォローしていただきました。
ですが共同開発はミスをしても大丈夫で、講師の方からフォローしていただける
環境だったので苦労しましたが実務に入る前にできて良かったです。

**②答えやすい質問の作成(伝えたいことの言語化）**
答えやすい質問をすることを意識しながらに自分の聞きたい点を取り入れること
にとても苦労しました。ただ何度か質問するうちに上手な聞き方ができるように
なったので苦労した甲斐がありました。この言語化能力は将来も必ず役に立つ
と思うので共同開発で経験できて良かったです。

**③初めてのGitコマンドや慣れないGitHub**
ブランチやmerge、pullなどを初めて使用しました。このことは正直
あまり理解できずに２ヶ月終わるかもというほど困惑しました。
ですが慣れないなか講師の方に質問や自分で調べやってみる、時には
ミスをしながらも徐々に慣れていきました。何度も使ううちに慣れてきたので
改めて実際に手を動かしてみる大切さがわかりました。

**④エラー対応**
Laravelのエラーもそうですがdockerなどの初めて触った部分に関しての
エラーに苦戦しました。特にdockerは何がいけないのかわからない
という状況によく出会い、聞きたいことが言語化しにくいとき一人で悩む
時間が増えた時もありました。ですがミーティングの日や
それ以外の日にzoomでエラー対応をしていただくこともあり、僕たち受講生に
とって有難すぎるサポートもしていただきました。

#全体的な感想
結論から言うととても充実した２ヶ月で、未経験のエンジニアの方にはぜひ
おすすめしたい内容でした。

**貴重なチーム開発経験**
エンジニアは基本チームで開発するとは知っていたのですが具体的なイメージは
全く頭になかったです。しかしGit flowやGitHubを実際に使うことで座学では
わかりずらいチーム開発の概念的な部分が理解できました。

**同じ受講生と共に頑張れた**
同じ受講生は社会人の方で仕事終わりに勉強を行なっている方でした。
そういった人を間近で見ると暇な学生の自分はもっと頑張らないとという気持ちに
なりました。
社会人の方は「若い子が頑張っているならおっさんはもっと頑張らないとな」と
よく自虐をしていましたが(笑)、お互い切磋琢磨できました。
またわからないエラーをzoomで考えたり、有益だと思った情報は共有するなど
し日々高め合うこともできました。

**講師の方の手厚いサポート**
講師の方には大変お世話になりました。エラー対応や進捗確認、キャリア面での相談、
インターンの面接対策もしていただき感謝しています。共同開発が終わってもキャリア
などで悩んだことがあれば相談に乗る、と言ってくださり共同開発の２ヶ月で関係が切れ
ないと言う点も非常に嬉しい点でした。これからのキャリアについて相談できる方が
近くにいてくれることは未経験の自分にとってありがたいです🙏


#まとめとこれから
僕の友人が未経験でエンジニア就職をしたいと言ってきたら必ず探求学園の共同開発
を勧めます。それほど充実した環境で学ばせていただきました。
共同開発をしていると、また講師の方からキャリア面でのアドバイスをいただくとこれから
自分は何が弱いのか、何をするべきか見えてきます。中長期的な視野を持って勉強し
エンジニアとして活躍できるようにこれからも学習していこうと思います。
最後まで読んでいただきありがとうございました！
MySQL

##MySQLの特徴
・オープンソースで基本的に無料
・Linux、macOS、windowsなど、様々な大規模なデータ処理にも耐えうる環境で使える。
・トランザクション、バックアップ、リストア機能がある。
・複数のユーザーで利用でき、ユーザーごとにアクセス権を設定できる
##MySQLコマンド集
###MySQLのインストール
```
$brew install mysql
```
###MySQLの自動設定
```
$ brew services start mysql
```
###MySQLの自動起動を止めたい時
```
$ brew services stop mysql
```
###MySQLのコマンドが打てるかの確認

```
$ which mysql
```
###「Yay! You're on Rails!」が表示されるまで
```
1$rails new アプリ名　--database=mysql
```
```
2 $bundle config --local・・
```
```
3 $rails webpacker:install
```
```
4 $bundle install
```
```
5 $rails db:create
```
```
6 $rails s
```
##関連記事・引用
【MySQL】MacでMySQLを使う
https://qiita.com/aoaoao/items/47113848108f18c2db92
【MySQL】自動起動の意外な落とし穴
https://qiita.com/s_tatsuki/items/52314f1eada0a4bab716
【新卒文系】応用情報技術者試験に向けた勉強記録

こんばんは。
こちらの記事では、2021年秋の応用情報技術者試験に向けた勉強の記録を残していきます。
応援やアドバイス、何でもお待ちしております。

###追記
無事、合格しました！！！

#私について
参考までに私のプロフィールは以下の通りです。

・新卒1年目
・文系学卒
・IT未経験者
・SIer就職
・21年度春の基本情報技術者試験受験予定だったが、試験会場を間違え、受け損ねた。
※今回は必ず会場にたどり着きたいです。。。

#資格取得の背景
取得の目的は、「昇給条件になっているため」です。
ただ、未経験から一人前のエンジニアを目指す私にとっては、ITそのものを知るには非常に望ましい試験であると感じるので、勉強を兼ねての受験でもあります。


#勉強戦略

■6月中旬から末まで
・応用情報技術者試験の対策本を購入。1日0.5章で１周読んだ。
・同時並行で、該当分野の午前問題を1日20問程度解いた。（月合計105問解いた）
・基本情報と重複した問題もあるが、より深い理解が求められた。

■7月
・午前問題を1日40問～80問を目標に勉強。わからない部分は参考書に戻って調べた。（月合計729問解いた)
・正解率は55.1%でした。まあまあですね。
・午後問題の対策を開始。とりあえず選択問題を絞り込みました。
・会社の夏季休暇があり、勉強にあまり時間を割けなかった。(8月からはちゃんと頑張ります。。。）


###※午後問題の選択はこちら
【問１情報セキュリティ（必須）】
得意度：★★★
・セキュリティは基本情報でもやっていましたので、新しい知識も特に必要なく解ける状態。
・最終的には満点を狙うべき分野だと踏んでいます。
・現在の正答率は大体６割前後。
・参考書の読み込みにより、単語問題の抜け漏れを防ぎたいところ。


【問２経営戦略】
得意度：★★★
・国語の問題感が強い。大体本文のどこかからコピー&ペースト。
・年度によって、財務関係の計算や図の穴埋めなども出題される。油断禁物。


【問４システムアーキテクチャ】
得意度：★
・慣れたら解けそうな問題だが、絶妙に複雑。
・理解できれば国語の問題で、知識は特に問われない。
・当日の出題された問題が理解できるかにかかっている。
・計算が入ってきやすい印象。


【問７組込みシステム開発】
得意度：★
・基本的にシステムアーキテクチャと同様。似ている。違いがイマイチ判らない。


【問９プロジェクトマネジメント】
得意度：★★★
・本文に記載されたプロジェクト内容に関して問われる国語問題。

【問10サービスマネジメント】
得意度：★★
・インシデント的な考え方を問われる。
・個人的に苦手な分野（体系的な理解が不足している）
・苦手なだけで本質は国語問題なので、克服したい。


当日も、★が一つの問題もどちらかは必ず回答することになる。
まずは★★のジャンルを固めつつ（回数をこなして慣れる）、★も6割ほど取れるようになることが理想。



■8月
・午前問題は1日40問に減らし、午後問題をメインに勉強。
・午前問題は、「全く同じ問題、前も解いたぞ」と言う現象が頻繁に生じるようになった。
・テクノロジ系が苦手。特に計算に苦手意識あり。
・午後問題は1日1回分を解いている（土日はバッファー）
・午後問題はPCで解くと、文章題の正解率を出してくれるので、なるべくPCで解いている。
・第一週は全範囲を同じ量だけ解いた。
【Rails】carrierwave画像投稿機能 （メモ）

# 目標
* 画像投稿機能

# 開発環境
* Rails: 6.1.3
* ruby: 3.0.0
* mac: os

# 前提
* 投稿機能実装済み
* 投稿テーブルpost


# 実装

### １．Gemfileにcarrierwaveを記述 してインストール

```ruby:Gemfile
gem 'carrierwave'
```

`bundle install`します。

```ruby:ターミナル
$bundle install
```

###２．postテーブルにimageカラム追加

```ruby:ターミナル
$rails g migration AddImageToPosts image:string
```

マイグレーションファイルが生成されます。
`image`カラムが追加されているのを確認してマイグレーションします。

```ruby
class AddImageToPosts < ActiveRecord::Migration[6.1]
  def change
    add_column :posts, :image, :string
  end
end
```
```ruby:ターミナル
$rails db:migrate 
```

### 3.イメージアップローダー作成

```ruby:ターミナル
$rails g uploader image
```
`image_uploader.rb`ファイルが生成される。




###４．モデル紐付け
`post`モデルにイメージアップローダーを紐付ける。

```ruby:app/models/post.rb
class Post < ApplicationRecord
  mount_uploader :image, ImageUploader
end
```

###５.コントローラー記述

`praivate`の`post_params`に`image`を追加。

```ruby:app/contrllers/posts_controller.erb
private

def post_params
  params.require(:post).permit(:content, :title, :image)
end
```
###6.ビュー記述
画像投稿フォーム追加。

```erb:app/views/posts/_form.html.erb
<%= form_with(model: @post)do |f| %>
    <div>
       <%= f.label :title, ' タイトル' %>
       <%= f.text_field :title %>
    </div>
    <div>
       <%= f.label :content, '内容' %>
       <%= f.text_field:content %>
    </div>
       <%= f.label :image, '画像' %>
       <%= f.file_field :image %> 
    <div>
       <%= f.submit '投稿'%>
    </div>
<% end %>
```
画像投稿フォームができました。
![スクリーンショット 2021-08-27 23.10.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927584/9449f98b-fca7-7e3a-8899-a7b9064545b9.png)

これだけでは投稿できないので`image_tag`を使って投稿できるように記述します。

```erb:app/views/posts/show.html.erb
<h5><画像投稿></h5>
<p>タイトル：<%= @post.title %></p>
<p><%= image_tag @post.image.url %></p>
<p>内容：<%= @post.content %></p>
```

記述したので投稿できるはずです。

![スクリーンショット 2021-08-27 23.42.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927584/1010f4da-b218-36bb-7bf0-0f9b03b421e0.png)


こんな感じで無事投稿でできました。
以上です。

#参考
参考にした記事です。
https://qiita.com/k19911848/items/a082cc4e0c0103f935b1
to_iメソッドの使い方

##to_iとは？
数字の文字列を数値オブジェクトに変換するメソッドです。
また、小数を整数に変換することもできます。

以下、サンプルコードになります。

```ruby:使用例
オブジェクト.to_i

num = "1"
p num
=> "1" (文字列）

num.to_i
=> 1 (整数）

puts 100 + "100" 　#数値オブジェクト　+　文字オブジェクトは計算できない
puts 100 + "100".to_i　#to_iを使って文字オブジェクト　⇒　数値オブジェクトに変える
⇒　200
```

###小数を整数に変えることもできる

```ruby
# 小数として定義
num = 1.0
num.class
=> Float

#整数に変換
num = num.to_i
num.class
=> Integer
```




####参考記事
https://pikawaka.com/ruby/to_i
traefikにLet's Encryptを設定する

https://qiita.com/error484/items/d5ff9da8385ea2ee720a

:::note info
上記の設定が出来ていることが前提となります。
:::

## ■traefik.ymlの変更

```/tmp/traefik.yml
# 変更前
certificatesResolvers:
  default:
    acme:
      email: system@test.local
      storage: acme.json
      httpChallenge:
        entryPoint: web
```
```diff_yaml
# 変更後
certificatesResolvers:
  default:
    acme:
      email: system@test.local
      storage: acme.json
+      tlsChallenge: {}
+      # ステージングでの確認はURLが異なります
+      caServer: https://acme-v02.api.letsencrypt.org/directory
      httpChallenge:
        entryPoint: web
```

## ■docker-compose-app.yml

```docker-compose-app.yml
# 変更前
      # 443設定
      - traefik.http.routers.test-app-test-secure.rule=Host(`apptest.local`))
      - traefik.http.routers.test-app-test-secure.entrypoints=secure
      - traefik.http.routers.test-app-test-secure.tls=true
      - traefik.http.routers.test-app-test-secure.service=test-app-test-secure-service
      - traefik.http.services.test-app-test-secure-service.loadbalancer.server.port=80
```
```diff_yaml
# 変更後
      # 443設定
      - traefik.http.routers.test-app-test-secure.rule=Host(`apptest.local`))
      - traefik.http.routers.test-app-test-secure.entrypoints=secure
      - traefik.http.routers.test-app-test-secure.tls=true
+      # certresolverを追加
+      - traefik.http.routers.test-app-test-secure.tls.certresolver=default
      - traefik.http.routers.test-app-test-secure.service=test-app-test-secure-service
      - traefik.http.services.test-app-test-secure-service.loadbalancer.server.port=80
```

## ■SSL証明書対応について

上記の２ファイルを少し変更するだけで対応できます。

:::note warn
設定変更後、traefikコンテナの再起動が必要になります。
caServerを切り替える際、コンテナ内の「acme.json」を削除する必要があります。
:::

## ■関連記事
https://qiita.com/error484/items/d5ff9da8385ea2ee720a

https://qiita.com/error484/items/356087c8e7b6826e0dee
無料でアバターを作れるMakeHumanを試してみた

# はじめに
無料でアバターを作成できるMakeHumanなるものがあるとのことで試してみました。

# 作成
* 顔はアフリカ系、アジア系、白人系の比率で作成、眉毛とまつ毛は複数から選択できる。
* 体系はある程度細かく設定できる。
* 服装の選択肢は少ない。
* 髪型も選択肢は少ない。
* ボーンも数種類から選べる、自分はゲームエンジンを選択した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/b12af3f4-66d3-de60-298f-599b1f56ccdb.png)

# エクスポート
obj,fbx,その他色々が選択できる。

# インポート
* Unityにfbxファイルをそのまま放り込むと、誰これ！？みたいな状態で表示される。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/20ec9043-9bd0-5659-b0b4-631e6d498217.png)

# 後処理
* マテリアルのRendaringMode,Metalling辺りをいじると、それっぽい感じになる。
* 照明を当ててみて雰囲気を確かめる。
* MakeHumanの時と顔が変わっている気がするが細かいことは気にしないこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/eef94da3-4b55-b8c5-6179-9dc8fbd36fbd.png)

# リギング
* RigのAnimationTypeをHumanoidに変更
* objファイルだとエラーが出たので、ケアが不要なfbxの方が良さげ。
<iframe width="560" height="315" src="https://www.youtube.com/embed/C4kzGdYpZt4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 他アバター作成ツールとの比較
* 右側のRealPlayerMeと比べるとリアル路線なデザインになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/10686961-4198-4489-fdba-dc034eb47e0c.png)


# まとめ
* エクスポートすると顔が変わるのが謎…
* 髪型のバリエーションがもう少し多いとうれしいかも
ブログのテーマは模写であるのか


# はじめに
[「模写」とかの著作権についてちょっと調べてみた](https://qiita.com/momonoki1990/items/c16976cddc12dd010549)を見てもやもやするので.

# テーマを見た目からコピーすることは違法か
件の記事の"テーマ"にどの程度の独創性があるか判断できませんが, レイアウトや配色に独創性が認められることは少ないです. "有名企業サイトのデザインを参考にしよう"という記事や企業サイトのリンク集も多くあります. これらも法的に問題になることはほとんどないです.

# 模写なのかリスペクトなのか
引用の要件は, "引用であることが明確で, 自分の著作物が主で, 引用部分が従であること"です. 考えられる状況が無数にあるため, 明確な基準はありません.
例えば, [「人月の神話」の個人的まとめ](https://qiita.com/tonosama/items/4595ba36e1012ff9bac0)は, 文章は誰が見ても引用が主であり, 画像は無断転載です.
模写は, 独創性が認められる絵画を完全にコピーしようとしたもので, 引用とは認められないと思います.

# サポート部門や委託先の返答が素晴らしいのか
件の記事で実際のやりとりがないので, 正しいことは言えません. もし, サポート部門や委託先のスタッフが, 法律や技術に関わる質問に対し独断で回答していたとしたら, 私なら激怒します. よくある質問に対してマニュアル化するにしても, "みんなやってることや, 何心配してんの？"ではなく, "法的に問題ない, 私たちは推奨しています"ということを解りやすく伝える文面にすると思います.
エンジニアとしてお役所仕事が, "無駄なことを伝統的に続けているのか", "その無駄に意味があるのか", 考える必要があると思います.

# まとめ
- 曖昧なことを曖昧なまま放置しない
    - 曖昧な部分が残っているのに仕事を進めない
- 専門外のことを自分で解釈しない
    - 曖昧なままにしないと言っておいて, 本文が曖昧な表現を多用するのは自分で判断しないからです

# 余談
普通の企業なら, 雇用者に対して知的財産について基本的な教育課程があると思います. またSNSの利用についてガイドラインがあると思います. 例えば, 自社のプレスリリースや同僚が業務として書いた記事について, 勝手に転載したり, 翻訳して転載したりすることは禁止のはずです. ガイドラインがない場合は, 著作権法に従い違法だと判断すべきです.
matplotlibで生成したグラフを直接エクセルに出力する方法

# 概要
matplotlibで生成したグラフをエクセルに出力する時、自分のローカルにグラフ画像を保存せずにそのままエクセルに出力したい事があると思います。

今回は「既存のエクセルファイルに新しいタブを追加し、そこにグラフを出力する」という場面を想定し、上記を実現するコードを書いていこうと思います。

# サンプルコード
```python
import io
import openpyxl

import matplotlib.pyplot as plt


fig = plt.figure()

# ~~~~~~ グラフを作っていく処理は省略 ~~~~~~~~

# 既存のエクセルファイルを開き、「chart」という名前のタブを追加する
file = 'path/to/excel.xlsx'
workbook = openpyxl.load_workbook(file)
new_sheet = workbook.create_sheet('chart')

# PCのメモリに画像を保存する
img_data = io.BytesIO()
fig.savefig(img_data, format='png')

# 表示するための画像を生成し、エクセルに出力する
img = openpyxl.drawing.image.Image(img_data)
new_sheet.add_image(img, 'G1')

# 変更を保存
workbook.save(file)
```
# まとめ
これで作成したグラフがエクセルの新しいタブに表示されるはずです。
ローカルに不必要なデータが生成されなくていいですね。
テーブル定義書のWEBサイトをコンテナで作成

テーブル定義書をコンテナで作成します
※コンテナからDBに接続が出来る必要があります

## ■Dockerfile

```Dockerfile
FROM httpd:alpine

# bashを使用する場合はbashをインストールする必要があります
# libxslt は xsltproc を使用するのに必要です
# tzdata は日本時間に変更する場合
RUN apk update \
    && apk add \
        bash \
        mysql-client \
        libxslt \
        tzdata \
    && cp -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && apk del tzdata
```

## ■定義書を作成(shell)

```bash
# スキーマ「test_schema 」の定義書を作成します

FILE_INDEX=/usr/local/apache2/htdocs/index.html
FILE_DUMP=/tmp/mysqldump.xml
FILE_TEMPLATE=/tmp/style.xslt

DB_HOST=localhost
DB_NAME=test_schema 
DB_USER=dbuser
DB_PWD=test

MYSQL_PWD=${DB_PWD} mysqldump -h ${DB_HOST}-u ${DB_USER} --no-data --xml ${DB_NAME} > ${FILE_DUMP} \
    && xsltproc -o ${FILE_INDEX} ${FILE_TEMPLATE} ${FILE_DUMP}

```
CloudWatchLogsに「AWS以外のサーバ環境」からは書き込みが出来て「AWS Fargate」からは書き込みが出来ない時の対応

**<font color=blue>CloudWatch Agent</font>** や **<font color=blue>AWS SDK</font>** を使用して**<font color=blue>CloudWatch Logs</font>**に書き込みをする際の話になります。

**<font color=blue>ローカルのDocker環境</font>**や**<font color=blue>さくらサーバ</font>**などでは動作しても**<font color=blue>AWS Fargate</font>**では動作しなくて困ることがあるかもしれません。

上記でロググループが存在しない際に**<font color=blue>CreateLogGroup</font>**で権限エラーと表示される場合、権限＆ポリシー設定になります。

**<font color=red>IAM</font>**でログ関係の権限を全て与えているから問題が無いと勘違いをされている方もいます。
※AWSをメインで対応している会社でも勘違いをしている方がいました。

###**<font color=red>VPC</font>の<font color=red>エンドポイント</font>のポリシーを疑うと解決するかもしれません。**

## ■CloudWatch Agent

VPCのポリシーに下記権限を与えれば、基本的には問題が無いと思います。

```
# ロググループの作成
CreateLogGroup
# ログストリームの作成
CreateLogStream
# ログの書込
PutLogEvents

# ※ログの自動削除を行う場合、削除の権限が必要になるかと思います
```

## ■AWS SDK（CloudWatch）

VPCのポリシーに下記権限を与えれば、基本的には問題が無いと思います。

※ PHPの場合、**<font color=blue>maxbanton/cwh/src/Handler/CloudWatch.php</font>**を参照

```
# ロググループの作成
CreateLogGroup
# ログストリームの作成
CreateLogStream
# ログの書込
PutLogEvents

# ロググループに「期限」を設定する場合に必要
# ※指定のロググループが存在しない場合のみ処理が実行されます
PutRetentionPolicy
# ロググループの一覧を取得
# ※指定のロググループの存在を確認する際に使用
DescribeLogGroups
# ログストリームの一覧を取得
# ※指定のログストリームの存在を確認する際に使用
DescribeLogStreams
# タグを登録
# ※指定のタグをロググループに登録する際に使用
# ※タグの指定が無ければ不要
TagLogGroup
```

## ■参照
https://qiita.com/error484/items/80381c8f1355c3c617c9

https://qiita.com/error484/items/782d6b5a439410835b7a
【Rails】配列の中のハッシュから値を取得する方法(map)

単一のオブジェクトから持ってくる方法と、
オブジェクトが配列に入っていて、その配列の中から一個一個とりだす方法を紹介します。

1.単一のオブジェクトからデータをもってくる方法
2.オブジェクトが配列に入っているときに、欲しいデータだけをもってくる方法

## 1.単一のオブジェクトからデータをもってくる方法
```rb
# まず、インスタンスを取得
@user = User.find(2)

# @userの中身を確認
@user
=> #<User id: 2, email: "admin1@example.com", last_name: "admin", first_name: "user1", created_at: "2021-08-19 05:52:42", updated_at: "2021-08-19 05:52:42", deleted_at: nil>

```

### この中から欲しいデータだけを取得したいとき

```
user.last_name
=> admin
```

ActiveRecord::Baseを継承したクラスはテーブルの構造を読み取り、自動でgetter,setterを作成する。そのため、カラム名をそのままgetter,setterとして利用ができる
#### userがリレーションを組んでいて、リレーション先のテーブルからデータを持ってきたいときも同じ

```
user.post.title
=> "今日の晩ごはん"
```

#### 値はとれるけど、ActiveRecord的に自然ではないデータのとり方
```
user[:last_name]
=> admin
```
```
user.post[:title]
=> "今日の晩ごはん"
```


## 2.オブジェクトが配列に入っているときに、欲しいデータだけをもってくる方法

```rb
# まずインスタンスを取得
post = Post.find(2)

# postの中身を確認
[28] pry(main)> post
=> #<AssetMaster:0x000055766365a3e0
 id: 2,
 name: "今日の朝ごはん",
 post_image: 1,
 created_at: Thu, 19 Aug 2021 14:52:29 JST +09:00,
 updated_at: Thu, 19 Aug 2021 14:52:29 JST +09:00,
 deleted_at: nil>
 
# このpostに紐付いたデータ(image_masters)が配列に入っている（配列の中にハッシュオブジェクトが3つはいっている）
[28] pry(main)> post.image_masters
=> [#<ImageMaster:0x0000557663c32218
  id: 2,
  name: "電子機器",
  created_at: Thu, 19 Aug 2021 14:52:28 JST +09:00,
  updated_at: Thu, 19 Aug 2021 14:52:28 JST +09:00,
  deleted_at: nil>,
 #<ImageMaster:0x0000557663cb85c0
  id: 7,
  name: "嗜好品",
  created_at: Thu, 19 Aug 2021 14:52:28 JST +09:00,
  updated_at: Thu, 19 Aug 2021 14:52:28 JST +09:00,
  deleted_at: nil>,
 #<ImageMaster:0x0000557663cb8430
  id: 8,
  name: "エンタメ",
  created_at: Thu, 19 Aug 2021 14:52:28 JST +09:00,
  updated_at: Thu, 19 Aug 2021 14:52:28 JST +09:00,
  deleted_at: nil>]
 
```
この中から、ImageMasterのnameが配列で欲しい場合(電子機器,嗜好品,エンタメが配列でほしいとき)

```rb
post.image_masters.map(&:name)
=> ["電子機器", "嗜好品", "エンタメ"]
```

### 補足
このように任意のカラムの配列を取得する方法として「pluck」と「map」の二つのメソッドが存在する。
使い分けの方法は
**DBから値を取得する場合には「pluck」、既にインスタンス化したオブジェクトから値を取得する場合は「map」**
という使い分けが最適です。
詳しくはこちら
[pluckとmap の違いを調査する](https://qiita.com/TT-nasu/items/e6971efd1383d7f500dd)
【unity】dynamicboneでskeltal画像を変形させてる時、ボーンは変形してるのに画像が変形しない時

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1944879/aaa64267-9049-6136-5259-cc065de73f38.png)
プロジェクト設定のスクリプト実行順序にDynamicBoneを追加すること
UIButtonを変形とIndicatorが表示されてるようなアニメーション 

#今回の内容
<img width="150" alt="D90D5657-6E18-4D93-9708-613FC3F90B33_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/b060b9b0-3e4c-5c25-49d8-f35ab88784cf.jpeg"> <img width="152.5" alt="0E396447-584E-4008-BE1A-81875738A8F3_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/3d3a9efd-ae3e-1b05-32db-56aec6927550.jpeg"> 　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　

#コードと簡単解説

* Main.storyboardでUIButtonを作成しておきます.

```Swift:
    @IBOutlet weak var indicatorOnButton: UIButton!
    @IBAction func indicatorOn(_ sender: UIButton) { 押した時の処理 }
```

* indicatorOnButtonの見た目

```Swift:
        indicatorOnButton.frame = CGRect(x: view.frame.minX + 20, y: view.frame.maxY / 8, width: view.frame.maxX - 40, height: indicatorOnButton.frame.size.height)
        indicatorOnButton.layer.cornerRadius = 20.0
        
        indicatorOnButton.layer.shadowOffset = CGSize(width: 5, height: 5)
        indicatorOnButton.layer.shadowOpacity = 0.5
        indicatorOnButton.layer.shadowRadius = 0.5
```

##indicatorOnButtonを押した時の処理（AnimationとIndicator）
 
* indicatorOnButtonが押されてから、`0.5秒`で`.frame`と`.layer.cornerRadius`を変更します。

* 別の場所で良いと思いますが、`indicator `を作成します。`.startAnimating()`でindicatorを回します。

* 3秒間、indicatorを回した後に、`.stopAnimating()`でindicatorを止めます。

* 最後に、`0.5秒`で`.frame`と`.layer.cornerRadius`を元の状態に戻します。

```Swift:
    @IBAction func indicatorOn(_ sender: UIButton) {
        
        sender.setTitle("", for: .normal)
        
        UIButton.animate(withDuration: 0.5, delay: 0, options: .allowAnimatedContent, animations: {
            
            sender.frame = CGRect(x: self.view.center.x - (sender.frame.size.width / 7) / 2, y: sender.frame.origin.y, width: sender.frame.size.width / 7, height: sender.frame.size.height)
            sender.layer.cornerRadius = 25.0
            
        }, completion: nil)
        
        let indicator = UIActivityIndicatorView()
        indicator.frame.origin = CGPoint(x: sender.center.x, y: sender.center.y)
        indicator.color = .white       
        view.addSubview(indicator)
        indicator.startAnimating()
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            
            indicator.stopAnimating()
            
            UIButton.animate(withDuration: 0.5, delay: 0, options: .allowAnimatedContent, animations: {
                
                sender.frame = CGRect(x: self.view.frame.minX + 20, y: sender.frame.origin.y, width: self.view.frame.maxX - 40, height: sender.frame.size.height)
                sender.layer.cornerRadius = 20.0
                
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {sender.setTitle("Indicator", for: .normal)}
                
            }, completion: nil)            
        }
                
    }
```
#終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
AtCoderログ：0094 - ABC 074 B

# 問題

https://atcoder.jp/contests/abc074/tasks/abc074_b

## 問題文
> $xy$ 平面上に $N$ 個のボールがあります。このうち $i$ 番目のボールの位置は $(x_i,i)$ です。したがって、$N$ 本の直線 $y=1, y=2, ..., y=N$ の上にそれぞれ 1 個ずつボールがあることになります。
> すぬけ君は、これらのボールを回収するために、タイプ A, B のロボットを $N$ 台ずつ用意しました。 さらに、タイプ A のロボットのうち $i$ 台目のものを位置 $(0,i)$ に、タイプ B のロボットのうち $i$ 台目のものを位置 $(K,i)$ に設置しました。 したがって、$N$ 本の直線 $y=1, y=2, ..., y=N$ の上にそれぞれ $1$ 台のタイプ A のロボットと、$1$ 台のタイプ B のロボットが設置されたことになります。
> それぞれのタイプのロボットは起動されると以下のように動作します。
> ・タイプ A のロボットは、位置 $(0,a)$ で起動されると、直線 $y=a$ 上にあるボールの位置まで移動し、ボールを回収してもとの位置 $(0,a)$ に戻って停止する。そのようなボールが存在しない場合は何もせずに停止する。
> ・タイプ B のロボットは、位置 $(K,b)$ で起動されると、直線 $y=b$ 上にあるボールの位置まで移動し、ボールを回収してもとの位置 $(K,b)$ に戻って停止する。そのようなボールが存在しない場合は何もせずに停止する。
> これら $2N$ 台のロボットのうちいくつかを起動してボールをすべて回収するとき、ロボットの移動距離の総和として考えられる値のうち最小のものを求めてください。

## 制約
> ・$1 \le N \le 100$
> ・$1 \le K \le 100$
> ・$0<x_i<K$
> ・入力値はすべて整数である。

## 収録されている問題セット
- [[BfB-E]\(AtCoder Problems Boot camp for beginners Easy 100\)](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) #009 

# 回答
## 回答1 (AC)
問題文が長く設定が少し複雑ですが、状況がのみこめればコーディングは単純です。要は、直線の上にボールが置いてあり、両端に置かれたロボットの近い方が回収する、ということです。この直線が $N$ 本あるので、その最短距離の合計を求めることになります。コードは以下のようになりました。ロボットはボールを回収した後、もとの位置に戻る必要があることに注意が必要です。

```C++:abc074b-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n, k;
  cin >> n >> k;
 
  vector<int> x(n);
  for ( int i=0; i<n; i++ ) {
    cin >> x.at(i);
  }

  int dmin = 0;
  for ( int i=0; i<n; i++ ) {
    dmin += min(2*x.at(i),2*(k-x.at(i)));
  }
  
  cout << dmin << endl;
}
```

## 回答1 (AC)
回答1を少しだけ改良します。回答1のコードを見返すと、vector 型変数 x は値を１回参照するだけなので、わざわざ保持する必要があります。そこで cin で読み込みした後に最短距離を調べることで、vector 型変数の使用は不要となります。コードは以下のようになりました。

```C++:abc074b-2.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n, k;
  cin >> n >> k;
 
  int x, dmin = 0;
  for ( int i=0; i<n; i++ ) {
    cin >> x;
      dmin = min(2*x,2*(k-x));
  }
  
  cout << dmin << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc074/tasks/abc074_b/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2017/09/17/210649)
回答1と同じ方針でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc074/tasks/abc074_b/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/arc083/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0093 - ABC 086 B](https://qiita.com/RoadLynton/items/0dee616d2792ac496781)
- 次の記事 → [AtCoderログ：0095 - ABC 160 C](https://qiita.com/RoadLynton/items/4e3644e78ba435562e8f)