OmniAICreator/Qiita-1.07M huggingface dataset:
JavaからRubyへ!!

#【JavaからRubyへ!!】

Javaを学びつつ、Rubyを習得することが現時点の目標です。
[Ruby 公式リファレンス](https://www.ruby-lang.org/ja//) にJavaとRubyの比較がされていました。
公式リファレンスの「JavaからRubyへ」を参照し、自分用メモとして残します。

##JavaからRubyへ

Javaは成熟は成熟しており、処理速度は高速であるが、とても冗長である。 
JavaからRubyへ移行すると、コードの量を大幅に削減することが可能になる。

##Javaとの類似

メモリはGC（ガベージコレクション）によって管理される。
オブジェクトは強い型付けがされる。
メソッドにpublic、private、protectedの指定可能。

埋め込み型のドキュメントツールが用意されている。
Ruby用のツールRDocで生成されたドキュメントは、javadocで生成したドキュメントにとてもよく似ている。

※ガベージコレクションとは、コンピュータプログラムの実行環境などが備える機能の一つで、実行中のプログラムが占有していたメモリ領域のうち不要になったものを自動的に解放し、空き領域として再利用できるようにするもの。
（IT用語辞典 e-Words より）

##Javaとの相違

・コードをコンパイルする必要がなく、単に実行するだけ。

・異なったサードパーティ製のGUIツールキットがいくつか存在する。

・クラスなどの定義の最後にはendキーワードを使う。コードのまとまりを波括弧で括ることはしない。

・importの代わりにrequireを使う。

・すべてのメンバ変数はプライベート変数です。オブジェクトの外側からはメソッドを介してそれらにアクセス。

・メソッド呼び出しの括弧は基本的にオプションで、しばしば省略される。

・数値も含めて、すべてのものはオブジェクト

・静的型チェックなし

・変数名はただのラベル。変数名は関連付けられた型を持たない。

・型宣言はない。必要に応じて新しい変数名を割りあてれば、それらを利用できる。
　例）int[] a = {1,2,3};ではなくa = [1,2,3]

・キャストはなく、メソッドを呼び出すだけ。例外を確認場合は、コードを実行前にUTで示す。

・コンストラクタは常に”initialize”という名前になる。（クラス名ではない）

・インターフェイスの代わりにMix-inを使う。

・XMLよりもYAMLが好まれる。

・nullはnil

・== と equals( ) の扱いが異なる。
　等価かどうかを評価したい時は、== を使う。【Javaは、equals( ) 】
　二つのオブジェクトが同一かどうかを確認したい時は、equal?( ) を使う。【Javaは、==】

##さいごに。

これらを参考に類似と相違についても頭の片隅に置きつつ、プログラムを理解していきたい。

自分のような人間が、技術力をあげていくには、まず量をこなすことが大事だと思う。
これからもどんどんアウトプットを増やしていきます。
筋電センサ MyoWare を使ってみた

先週末のMakerFaire東京、今年は自宅でTwitterのハッシュタグを追っていました。

そこに、NT加賀で初めて見て感動し、昨年のヒーローズリーグでも拝見した「[筋電車いすテンプラー](https://protopedia/prototype/208e43f0e45c4c78cafadb83d2888cb6)」さんをお見かけしました。

毎回Maker Faireを見るとなんか作ってみたくなります。
2年前に買ったきりそのままになっていた筋電センサーを取り出しました。

基本的にここのサイトを見ながらやりました。
https://learn.adafruit.com/getting-started-with-myoware-muscle-sensor/


##環境
Windows 10

##使用機材
[Arduino UNO](https://www.switch-science.com/catalog/789/)
[筋電センサ Myoware](https://www.switch-science.com/catalog/2682/)

Arduino NANOでもいいと思いますが、手元にUNOしかなかったので。


##配線

参考ページ
https://learn.adafruit.com/getting-started-with-myoware-muscle-sensor/circuit-1

このページにはこう書いてあります。

MyoWare "+"  　ー Arduino "3V"　　（3Vなんかないので、3.3Vでいいですよね？）
MyoWare "-"  　ー　Arduino "GND"
MyoWare "SIG" 　ー　Arduino "A0"


![120849083_3384806331567877_7942591192187125772_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/b5b053ff-449a-05ea-ca3d-c8e45c1b5f92.jpeg)



##コード
Arduinoのサンプルプログラムを開きます。
ファイル -> スケッチ例　-> 01.Basics -> AnalogReadSerial. 

```cs:AnalogReadSerial.ino
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}
```


##Arudinoの設定
ボード：       　Arduino UNO
シリアルポート： 　COM○（Arduino UNO)
シリアルモニタで、9600bpsに設定


##センサーを腕に貼る
![120850030_3384806238234553_5919781416244803419_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/60299a19-32ac-c304-321e-bf3cad28cf30.jpeg)



![120860279_3384806058234571_3422797244210291719_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/c3dde0fc-c6cf-f14c-97ca-8208d9745730.jpeg)

![120858857_3384821818232995_6151984495541872015_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/7e4e7f89-534f-3478-9c62-176a3919daa1.jpeg)


この数値が何を意味しているのかは分からないけど、何かしらの数値をとっているようです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">筋電センサーやってみた。意味は分からないけど何かしら数値は取ってるのかな？ <a href="https://t.co/Q69QiGiIQZ">pic.twitter.com/Q69QiGiIQZ</a></p>&mdash; たつや (@tatsuya1970) <a href="https://twitter.com/tatsuya1970/status/1313839750596431872?ref_src=twsrc%5Etfw">October 7, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<br><br>
さて、これからどうしたらいいものか。

いずれにせよ、
素人が簡単に手を出せる領域ではないことは確かです・・・


<br>
散歩ルートを自動で作成してくれるPGM

<h2>散歩ルートを自動で作成してくれるPGM<h2>
<p>pythonで散歩ルートを自動で作成してくるPGMを作りました。
散歩決定手順としては、予め道と交差点画像を地図上に書き込んだ画像ファイルを
用意しておき、初期交差点位置からランダムに経路を選んで指定した距離以上
になったらルート作成を終了するように動作します。
</p>
<hr>

<h3>PGMファイル<h3>
githubURL:https://github.com/NanjoMiyako/AutoWalkingRoot

<hr>

<h3>サンプル動作画像</h3>
実行時処理例
![screenshot1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/7ebe5e55-b806-02cf-f284-54395248d94a.jpeg)

道と交差点書き込み済みベース地図画像例
![base4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/800a1353-3365-8b50-1fa3-4bb0434dc361.jpeg)






出力ファイル画像例
![resul2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/46bb09f1-891b-14d5-021b-c5eb749e7651.jpeg)

<hr>

<h3>使い方</h3>
以下の手順で散歩ルートを作成します
1.ベース地図画像ファイルを用意します(GoogleMapのスクショなどで作成)
2.ベース地図画像ファイルの上から散歩候補の道を黒く(RGB:0,0,0)、道同士の交差点を赤(RGB:255,0,0)で書き込んだファイルを用意します、交差点に接している道同士は重ならないようにします。
3.AutoWalkingRoot.py中のmain1()メソッドを実行し、2で作成したファイルから
道と交差点のみ抽出した画像ファイルを作成します
4.AutoWalkingRoot.py中のmain2()メソッドを実行し、表示された画像中から散歩の初期位置のX座標とY座標を取得します
5.AutoWalkingRoot.py中のmain3()メソッドを実行し、以下のコマンドライン引数を指定して散歩ルートを作成します
コマンドライン引数1:ベース地図画像パス(拡張子付き)
コマンドライン引数2:道と交差点画像パス(拡張子付き)
コマンドライン引数3:初期X位置
コマンドライン引数4:初期Y位置
コマンドライン引数5:散歩最小距離
コマンドライン引数6:保存する散歩ルート画像ファイル名(拡張子付き)

<hr>
<h3>参考にしたサイト</h3>
<a href="https://note.nkmk.me/python-list-clear-pop-remove-del/">
Pythonでリスト（配列）の要素を削除するclear, pop, remove, del | note.nkmk.me
</a>
<a href="https://www.javadrive.jp/python/for/index1.html">
while文を使った繰り返し | Python入門
</a>
<a href="https://techacademy.jp/magazine/20603">
Pythonでルート（平方根）を計算する方法を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン
</a>
本日の『railsチュートリアル』で詰まったところ(2020/10/07)

#詰まったところ

2.1 アプリケーションの計画
･事象:
`$ git remote add origin git@bitbucket.org:<username>/toy_app.git`
`$ git push -u origin --all`
で、1.4.3で発生したのと同様、pushに失敗する。

･解決方法
`$ git push -f origin --all`
で無理やりpush
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764452/f132800e-1706-bcfe-edbf-74d8fb7b33cd.png)

#本日のまとめ
進捗: 2章 2.1途中まで

感想:
･やはり、日毎に記事を量産するよりも、一つの記事に追記していったほうが自分としても読者としてもメリットが多そうなので、土日にマージすることにする。
･詰まったところがなかった日のことを考えると、追記する形だと進捗と感想だけでも書くことができる。
･addとcommitの違いがわからないので、調べる必要あり
･各コマンドの -a, -Aなどの意味を調べる必要あり
【Unity】二次元配列をインスペクタ上で表示する方法

ゲーム開発をしていると二次元配列を使用したくなることが多々あります。
Unityならインスペクタ上で代入もできるし簡単！！
と思って普通に```public char[][] a;```のようにコーディングしたらインスペクタに表示されず、泣きを見ました...
備忘録として投稿...

#表示方法
方法としては子要素クラスをシリアライズすることで表示できます。

```cs:TwoDimesionalArray.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TwoDimensionalArray : MonoBehaviour
{
    //子要素クラスを使用して配列を作成
    public ChildArray[] array;
}

//シリアライズされた子要素クラス
[System.Serializable]
public class ChildArray
{
    public char[] childArray;
}

```
　
```[System.Serializable]```によってChildArrayクラスをシリアライズしています。![スクリーンショット 2020-10-07 22.51.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694219/e0fcfb1a-70df-4d25-3805-d6cb077c41e6.png)

表示できました！
使い道はほとんどありませんが、子要素の中に子要素という風に改良してあげれば、三次元以上の配列も作成することができます。

#まとめ
* 二次元配列をインスペクタに表示したい場合は子要素をシリアライズする。
* 入れ子のように改良すれば、三次元以上の配列も作成できる。~~誰が使うねん~~
DockerやKubernetesの終了: SIGTERMからSIGKILLまでの猶予期間


## `SIGTERM`と`SIGKILL`のざっくりした理解

`SIGTERM`と`SIGKILL`をざっくり説明すると以下のとおり:

* `SIGTERM`: 終了要求のシグナル。プロセスはこれを受信後も動くことはできる。
* `SIGKILL`: 強制終了。プロセスはこれ以上動作できない。


## グレイスフルシャットダウン (graceful shutdown)

グレイスフルシャットダウンとは、プロセスなどが、新規の作業の受付を締め切り、仕掛り途中の作業をキリのいいところまで処理してから安全に終了することを指します。イメージとしては、「店じまい」です。

強制終了が発生すると、システムの状態が中途半端になったり、データに不整合が起きてしまったりします。グレイスフルシャットダウンはそうならないようにする保護策です。

例えば、HTTPサーバのグレイスフルシャットダウンを例に考えると、HTTPサーバが終了フェーズに入ると、新規のリクエストは受け付けないようにしつつ、既に抱えているリクエストはちゃんとレスポンスを返し終わってから終了します。

DockerやKubernetesなどは、アプリケーションがグレイスフルシャットダウンできるように、`SIGTERM`シグナルを送ったのち、一定の猶予期間経過後、それでも終了してなかったら、`SIGKILL`を送信して強制終了するようになっています。

## DockerやKubernetesなどの`SIGTERM`から`SIGKILL`までの猶予

猶予期間はシステムによって異なります。以下に各システムの猶予期間を列挙します。グレイスフルシャットダウンを実装するにあたってご参考にしてください。

### `docker stop`

* `SIGTERM`を送り、10秒後にプロセスが残っていたら`SIGKILL`を送る。
    * 10秒は`-t`, `--time`オプションで変更可能。
* `docker-compose stop`、`docker-compose down`も同様。

### `docker kill`

* 即座に`SIGKILL`を送る
* `docker rm -f`, `docker-compose kill`も同様。

### KubernetesのPodの終了

* `SIGTERM`を送り、30秒後にプロセスが残っていたら`SIGKILL`を送る。

### Systemd

* `SIGTERM`→ 90秒後`SIGKILL`

### Upstart

* `SIGTERM`→ 5秒後 `SIGKILL`

### Sysvinit

* `SIGTERM`→ 5秒後 `SIGKILL`
GO言語でHello World

#はじめに
これからGO言語を学ぶうえで、備忘録としてやったことをまとめていきたいと思います。
GO言語つかってやってみたいことは結構あるので1から勉強ですね。（暗号解析とかめっちゃかっこよくないですか？）
学業の合間を縫っての勉強になるので更新は遅いと思いますが少しずつやっていきたいですね。
間違いがあった時は教えてもらえると幸いです。

ではやっていきます！

#開発環境
・ノートPC
・Windows 10
・Visual Studio Code
・GO ver.1.15.2

をつかってやってます
※GO言語の環境構築の方法はここでは触れないです
#Hello World!の出力
プログラムの中身はこんな感じ

```go:hello.go
package main

import "fmt"

func main() {
	fmt.Println("Hello World!")
}

//実行方法
>go run hello.go
//Hello World!が出力されればOK
```

モジュールの概念や関数の定義がほかの言語の書き方に似てますよね。合体してるって感じ。


###各部分の説明を軽く紹介
package：おまじない。じゃなくてGOではすべてのプログラムにおいて何かしらのパッケージに属する必要があるらしい、それの宣言。このプログラムでは「main」というパッケージに属していて、プログラムが走ると直後にmainパッケージに属するmain関数が実行される。

import：別のパッケージに含まれているものを使用するときに使う。「fmt」はprint系のパッケージらしい、これによってPrint()やPrintf()などが使えるようになる。import宣言はpackage宣言の後にくる

func：ここではmain関数の定義

以上です。
VSCode で Azure のリソースグループ内の依存関係を可視化する

VS Code の `ARM Template Viewer` 拡張機能と、 Azure からエクスポートした ARM Template を使うことで可視化できるようになります。

[![Image from Gyazo](https://i.gyazo.com/6a70849f0ba5d0aa483f7d755ac00db1.png)](https://gyazo.com/6a70849f0ba5d0aa483f7d755ac00db1)

## VS Code にインストールする拡張機能

VS Code の拡張機能ビューを開いて `ARM Template Viewer` をインストールします。 `arm` で検索すれば上のほうに表示されると思います。

[![Image from Gyazo](https://i.gyazo.com/fdcda28a1cb2d5d8df9bdbdc44d317bd.png)](https://gyazo.com/fdcda28a1cb2d5d8df9bdbdc44d317bd)

- [ARM Template Viewer - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=bencoleman.armview)

## 使い方

サンプルとして Azure Functions と Cosmos DB の二つのリソースをグループに追加したものを可視化してみます。

### Azure から ARM Template のエクスポート

リソースグループを開いて可視化したいリソースグループを選択 > テンプレートのエクスポートを選択します。作成された ARM Template をコピーまたはダウンロードします。

[![Image from Gyazo](https://i.gyazo.com/a5614afd1a6da51d6e0712c08825c537.png)](https://gyazo.com/a5614afd1a6da51d6e0712c08825c537)

### VS Code で ARM Template Viewer の表示

VS Code を開いてコピーまたはダウンロードした ARM Template を貼り付けます。 JSON 形式のファイルフォーマットに変更すると右上に目のアイコンが表示されるのでクリックします。画面右側にリソースが可視化されて表示されます。

[![Image from Gyazo](https://i.gyazo.com/6dca963d6413a125bd2100f148cb74dd.png)](https://gyazo.com/6dca963d6413a125bd2100f148cb74dd)

## その他情報

### Azure CLI から ARM Template をエクスポート

`az group export` コマンドでエクスポートできます。公式ドキュメントは [リソース グループを管理する - Azure CLI - Azure Resource Manager | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/management/manage-resource-groups-cli#export-resource-groups-to-templates) です。

```bash
az group export --name {ResourceGroupName}
```

今回の実行結果:

```powershell
PS C:\Users\piku3n\repo> az group export --name "neko-prod"
# {
#   "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
#   "contentVersion": "1.0.0.0",
#   "parameters": {
#     "databaseAccounts_neko_prod_cos777_name": {
#       "type": "String"
#     },
# ...
```

### GitHub のサンプルを使って可視化

GitHub に ARM Template をまとめた [Azure/azure-quickstart-templates: Azure Quickstart Templates](https://github.com/Azure/azure-quickstart-templates) が存在します。ここから好きな ARM Template を使うことで Azure がなくても可視化することができます。

画像は `vod-aspera-wowza-azuremediaservices` を可視化したものになります。

[![Image from Gyazo](https://i.gyazo.com/0d2fbf4cb4b964c51354c7165bab04f1.png)](https://gyazo.com/0d2fbf4cb4b964c51354c7165bab04f1)

### ARM Template Viewer の機能

- リソースはマウスのドラッグアンドドロップで移動できます。
- リソースをクリックすることで右下に詳細が表示されます。
- フィルターしたり、パラメーターファイルを追加したりできます。

詳しくは [ARM Template Viewer - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=bencoleman.armview) に色々書いてあります。

### ARM Template のエラーチェック

テンプレートの構成がおかしいと Viewer がエラー表示にしてくれます。インポートできるかどうのチェックではないですが、参考程度には使えると思います。

[![Image from Gyazo](https://i.gyazo.com/afe644ca2f8bd8aecaa17d6feb6a4763.png)](https://gyazo.com/afe644ca2f8bd8aecaa17d6feb6a4763)
【AWS SOA】EC2上でのCloudWatchメトリクス

#はじめに
AWS SOAではEC2上でのCloudWatchメトリクスの内容が出題されるので、本稿で取り上げたい。

#EC2上でのCloudWatchメトリクス
EC2上でのCloudWatchメトリクスには以下の内容が含まれる。
##CPU
CPU使用率
クレジット使用状況・バランス
##ネットワーク
ネットワーク出力・入力
ネットワークバケットイン・アウト
##ステータスチェック
インスタンスステータス　EC2 VMをチェック
システムステータス 基盤となるハードウェアをチェック
##ディスク
バイトと操作におけるディスク読み取り・書き込み

※RAMはEC2上のメトリクスで扱われない

![スクリーンショット 2020-10-07 22.47.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/5c808390-63a9-f01e-a153-4a4ca2175403.png)
![スクリーンショット 2020-10-07 22.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/bf6f3cb9-b94d-e723-1c61-945ed19664e3.png)


#詳細モニタリングの設定
EC2>インスタンス>モニタリングで詳細モニタリングを有効化を選択する。
はい、有効化するを選択する。
![スクリーンショット 2020-10-07 22.40.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/9b1e5d83-ee84-f2c0-06a3-1d12fdb3e87a.png)

参考
Ultimate AWS Certified SysOps Administrator Associate 2020
[ServiceNow] スケジュールジョブを Update Set に記録する方法

#概要
スケジュージョブを新規作成、更新しても、Update Set には記録されませんが、開発環境で実装したスケジュールジョブを他の開発物とともに一緒に Update Set に入れて移行させたい場合も多いです。
本記事では、スケジュールジョブを Update Set に記録する方法を説明します。

#手順
1 スケジュールジョブを記録させたい Update set をピッカーで選んでおきます
2 System Definition > Scheduled job に行き、Update Set に記録させたいスケジュールジョブを右クリック -> Copy sys_id を選んで、記録させたいスケジュールジョブの sys_id をコピーしておきます
3 System Definition > Script - Background に行き、以下のスクリプトを実行します

```javascript
var gr = new GlideRecord('sysauto_script'); 
if(gr.get('<対象ジョブのsys_id>')){ 
gs.updateSave(gr); 
}
```
4 System Update Sets > Local Update Sets 行き、スケジュールジョブを記録した Update Set を開き、スケジュールジョブが記録されていることを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756088/83a0698a-4ad7-b527-3d73-9d2a27c8967d.png)
以上です。

#補足
###補足1
gs.updateSaveメソッドは、global スコープでしか動きません。Scoped App に作ったScheduled jobを記録したい場合は、ピッカーのアプリとUpdate set は記録したいScoped Appのものを選んでおき、Script - Background でスクリプトを走らせる画面で、in scope に global を選んで実行します。
こうすることで、global スコープでスクリプトが実行されるため、gs.updateSaveメソッドが動き、スケジュールジョブが記録される Update Set は、ピッカーで選んでおいた Scoped App の Update Set になります。

###補足2
リポジトリを使って、Scoped app を移行させた場合や、Scoped app をまるごと、Update set に Publish した場合は、その Scoped app に含まれるスケジュールジョブも移行対象として含まれます。
新しいソリューションの設計と既存のソリューションの継続的な改善のポイント

#ポイント
改善能力が問われる。
AWSのクラウド案件は一度システムを構成して稼働したら終わりではなく、今後もアップデートしていく必要がある。
特にウェルアーキテクトフレームワークで問われる、５つの柱に沿ったアーキてクチャを顧客要件に合わして洗濯していくことが大切。
#サービスマッピング
* 運用上の優秀性
    * 構成管理
        * クラウドフォーメーション
        * コンフィグ
        * EKS
    * 運用監視
        * クラウドウォッチ
        * クラウドウォッチログ
* 信頼性
    * 耐久性（RPO）
        * S3
        * EBS
        * EFS
        * バックアップ
    * 可用性（RTO）
        * ELB
        * Route５３
        * RDS
        * ECS
* パフォーマンス効率
    * フロントネットワーク
        * クラウドフロント
    * DBストレージ
        * オーロラ
        * RDS
* セキュリティ
    * 認証暗号化
        * KMS
        * HSM
        * ACM
    * 監査
        * トレイル
        * オーガナイゼーション
    * 組織の複雑さ
* コスト最適化
    * コスト管理
継続的に他の方が作成したGit repoからcheckoutし、修正を適用した上で自分のrepoとしてpushする

# 先人の知恵・知見に感謝

Qiitaの ['GitHubでFork/cloneしたリポジトリを本家リポジトリに追従する'](https://qiita.com/xtetsuji/items/555a1ef19ed21ee42873) という記事をもとにした。

# やりたいこと
## 要約

上記掲載の記事を参考とし、Tagへの追従が必要だったので以下手順を作成した。
このエントリーはよりよい方法が確立でき次第更新する。

- 他に作成されているGit repoをもとにする
- 独自のpatchなどを適用したい
- conflictする/元ソースへの影響を出したくないなどの理由によりpull requestなどは行う予定がない
- 将来的にもとのGit repoが更新された際にも追従したい
- 参照元repoのbranchやtagについて指定を行う必要がある

## 現物

実際にやりたかったことは以下の通り。

- https://github.com/df8oe/UHSDR の安定版における最新リリース(tagで指定出来る)を取得
- 日本のバンドプランに合わせた調整(5MHz送出禁止/7MHz調整など)
- 調整したソースコードをbuild
- 新しいリリースが出た際には随時追従

# ToDo
継続的に参照元からのpullと手許masterでの継続的作業の検証。

# 全体を見通す

```
git clone git@github.com:${MYNAME}/${MYREPO}.git
cd ${MYREPO}
git remote add upstream https://github.com/${YOURNAME}/${YOURREPO}.git
git ls-remote --tags upstream
git pull upstream tag ${YOURTAG} --allow-unrelated-histories
(edit)
git add -A
git tag ${YOURTAG}
git commit -m "${MYCOMMITMSG}"
git push origin ${YOURTAG}JA
```

# 事前準備
## 自分のrepoを準備する
下記例にてすでに存在するGitHub repoのclone方法を示す。
Repo自体の作成方法はここでは扱わない。

```
git clone git@github.com:${MYNAME}/${MYREPO}.git  
cd ${MYREPO}
```

## 参照したいrepoを登録する
下記例にて参照したいGit repoを `upstream` にて扱う方法を示す。

```
git remote add upstream https://github.com/${YOURNAME}/${YOURREPO}.git
```

# 継続的適用
## pullしたいtagを確認する
`upstream` のタグ一覧を取得する。

```
git ls-remote --tags upstream
```

## Tagを指定した上でpullする
`upstream` の中から必要とするtagを指定し `master` (すでに指定しているbranch)へのmergeを行う。

```
git pull upstream tag ${YOURTAG} --allow-unrelated-histories
```

## 修正(patch等)を実施する
vi/emacs/sed/patchなど好みの手法で実施する

## 編集内容をcommit/pushする
自分自身が持つrepoへのcommit/pushを行う。
タグは揃える。

```
git add -A
git tag ${YOURTAG}
git commit -m "${MYCOMMITMSG}"
git push origin ${YOURTAG}JA
```
コスト管理のポイント

#ポイント
コスト管理とはAWSを使う上での従量課金のメリットを享受するためにどのような管理と最適化を行うかについての内容である。
コスト管理では、コストエクスプローラやバジェットを使用してコストの分析を行う。実際のコストを考慮した設計では、マネージドサービスやコンテナ サービスを積極的に検討し、EC2使う場合にはオンデマンドかスポットかリザーブを使い分けることが問われる。
FileMergeの"Files are not ascii"をコマンド1発で黙らせる

# 結論

ターミナルで以下を実行する

```bash
defaults write "com.apple.FileMerge" maxNonAscii -int 2147483647
```
※ macOS Mojave 10.14.6、FileMerge Version 2.11 (14533)で確認 

# 余談

`FileMerge.app`は、Xcode付属のdiffツール。 
差分をグラフィカルに確認できて便利ですよね。 

ただし、日本語の含まれるUTF-8のテキストファイル等をdiffにかけると警告が表示されます。
`Proceed anyway`をクリックすれば良いのですが、毎回1クリックが煩わしい。

![ 2020-10-07 22.00.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301/7ba75720-d68d-85f5-5a7e-959116ee5c41.png)

ググると、FileMergeのfilter設定でファイルをiconvでSJISに変換せよ、というのがヒットしますが…UTF-8から変換できない文字もあるので気が進みませんでした。

警告がでなければいいだけなのにな…と思いながらもう少し探すと、以下にたどり着きました。
https://giellalt.uit.no/tools/FileMerge.html

私からは以上です。
MySQLの基礎メモ

MySQLを使用中に気づいた点等を簡単にメモしていく。


###PRIMARY KEY(主キー)の役割
・テーブル検索のスピードを格段に早くする
・テーブルデータの整合性を保証する

PRIMARY KEYを設定すると「どこに何が登録されているか？」を探すためのインデックスと呼ばれる情報が自動的に作成。また、PRIMARY KEYを設定した列は同じデータは登録できないためエラーとなり、NULL値も登録できない。

[参考]https://www.sejuku.net/blog/52356


###INTTEGERとINTの違い
「INTEGER」は「INT」の別名で、どちらを記述しても同一の動きとなる。

INTEGER（INT）
　バイト数：4バイト
　標準桁数：int(11)
　符号付きの時の範囲：-2,147,483,648 ～ 2,147,483,647
　符号なしの時の範囲： 0 ～ 4,294,967,295

[参考]https://blog.s-giken.net/367.html

###CHARとVARCHARの違い
・CHAR
固定長文字列。
文字列末尾に必要な分の空白を付け加えて指定の長さの文字列として格納する。
文字数が決まってて、早い処理を求めるなら、CHARを使用。

・VARCHAR
可変長文字列。
指定された分だけメモリに格納される。
末尾に空白をつけず、効率よくメモリに格納したかったら、VARCHARを使用。

[参考]https://qiita.com/nuts_468/items/4db32c8066c1d0772c6b



###コメントの記述方法
コメントの記述方法としては、下記の３つがある。

```
#comment
```
文字から行末まで。

```
--comment
``` 
シーケンスから行末まで。MySQL では、「-- 」 (二重ダッシュ) のコメントスタイルは、2番目のダッシュに少なくとも1つの空白または制御文字 (空白、タブ、改行など) を続ける必要がある。

```
/* comment */
```
この構文では、開始と終了のシーケンスは同じ行にある必要はないので、複数の行にわたってコメントを記すことができる。

[参考]https://dev.mysql.com/doc/refman/5.6/ja/comments.html
移行の計画のポイントについて

#ポイント
基本的にはオンプレからのクラウドへのマイグレーションに関するものである。移行時の検討内容としてはネットワーク・アプリケーション・データの三つに分類される。
#ネットワーク
ネットワークはオンプレ寛容とAWs環境の間のネットワーク接続やIPアドレス、ドメインをどのように維持しつつ移行していくのかが焦点となる。
#アプリケーション
アプリケーション移行では、AWsが保有する目ネージどサービスをどこまで活用し、既存のモノリシックなアプリケーションをどこまでクラウドネイティブな状態へ近付けるかが焦点となる。
#データ
データに関しては大容量のファイルやデータベースをどのようにAWSへ行こうするかを検討する。

#まとめ
マネージド移行サービスは充実しており、その活用方法は複雑になっている。ユーザ要件に対して、最低限のソリューションを選択することが大切。

#お世話になるサービス
* ネットワーク移行案件
    * Route５３
    * ダイレクトコネクト
* アプリケーション移行案件
    * サーバーマイグレーションサービス
    * データベースマイグレーションサービス
* データ移行案件
    * AWSトランスファー系サービス
    * スノー系サービス
    * ストレージゲートウェイ
組織の複雑さに対する設計のポイント

#ポイント
　試験の４割を占める「組織、移行、コスト」に関してはAWsのクラウド案件で共通する事柄である。これらはクラウド固有の管理やガバナンスをどのように保つかという内容
企業のセキュリティポリシーに複雑な権限分離の要件があった場合には、アカウントレベルで環境を分けなければならない。また、それぞれの制御設計に対するガバナンス（管理）も求められる。IAMであればトレイルを設定する。VPCであればフローログを導入するなど。
【Docker】docker-entrypoint-initdb.dにディレクトリをマウントしない形で初期データを投入する【MySQL】

# TL;DR
- `Docker`ではディレクトリをマウントするとコンテナ内の情報が上書きされてしまうが、`bind`でファイルをマウントするなら上書きされない
- `MySQL`公式イメージでは、`docker-entrypoint-initdb.d`に置いた`.sh`ファイルはコンテナ起動時に実行される
- よって、`DDL`を入れたディレクトリを任意のパスにマウントし、投入用スクリプトを`docker-entrypoint-initdb.d`に`bind`でマウントすることで、`docker-entrypoint-initdb.d`に`DDL`をマウントしない形で初期データを投入できる

# 本文

## やりたかったこと
コンテナ内の`docker-entrypoint-initdb.d`を上書きせず、かつディレクトリをマウントするのと同じような使い勝手で、コンテナ起動時に初期化用`DDL`を実行したかったです。

## やり方
冒頭で書いた通り、ファイルをマウントする形であれば、コンテナ内の`docker-entrypoint-initdb.d`は上書きされません。
また、`MySQL`公式イメージでは、`docker-entrypoint-initdb.d`に置いた`.sh`ファイルはコンテナ起動時に実行されます。

よって、任意のディレクトリとして`DDL`を入れたディレクトリをマウントし、その投入は`docker-entrypoint-initdb.d`にマウントしたシェルスクリプトで行えばできます。
以下は投入スクリプトの例です。

```sh:投入スクリプト
#!/bin/sh
#---
# MySqlコンテナの/docker-entrypoint-initdb.dにファイルとしてマウントすることで
# そのコンテナの/tmp/init.dにマウントされた差分DDLをMySQLに投入する
#
# /tmp/init.dにファイルが存在しない場合はエラーとなる
#---
ls -1 /tmp/init.d/*.sql | while read file
do
  mysql -uroot -proot < $file
done
```

一連の実行はファイル名のアルファベット順であるため、マウント時のファイル名を調整すれば、順序の制御も可能です。
例えばマウントするファイル名のプレフィックスを`zzz-`とすることで、最後に実行されるようにできます。

```yml:docker-compose.yml
# 略（※イメージです、動かして試してはいません）
  volumes:
    - type: bind # 投入シェルのマウント、実行順を最後にするためzzz-というプレフィックスを指定している
      source: ./init.sh
      target: /docker-entrypoint-initdb.d/zzz-init.sh
    - ./init.d:/tmp/init.d/ # DDLを投入スクリプトに合わせ/tmp/init.dにマウント
```

## これが必要になった背景
`docker-entrypoint-initdb.d`に初期データが入っている形式のイメージを利用する必要が有り、ここにディレクトリをマウントすることができなかったためです。
素直に`docker-entrypoint-initdb.d`にファイルを配置する方法でやるなら`DDL`ファイルを個別にマウントする必要が有るため、ディレクトリでまとめてマウントする方法を検討してこのやり方に行きつきました。

# 参考にさせて頂いた内容
- [mysql \- Docker Hub](https://hub.docker.com/_/mysql)
  - `Initializing a fresh instance`の章に`.sh`や`.sql`の実行に関する記述が有ります
Python 入れ子構造の辞書を展開してPandasのMultiIndexのようなことをする


# やりたいこと

- 入れ子構造の辞書をアンダーバーで繋いで展開したい。
    - Input: `d1 = {'A':{'i':0,'j':1},'B':{'i':2,'j':3}}` のような辞書の要素に辞書が入るようなデータ
    - Output: `d2 = {'A_i':0, 'A_j':1, 'B_i':2, 'B_j':3}`のように一次元に開かれたデータ


## 関数（Not Smart）

- 入れ子構造の辞書はつまるところ，木構造になる
- イメージとしては木構造を割いて根と末端を直接つなぐ感じの処理になる
- 深さ優先探索っぽく実装するとなると再帰関数が良さそう

ということで書いたのが以下のようなコードになります。

```python

# key 変更
def changekey(dict,k1,k2):
    dict[k2] = dict[k1]
    del dict[k1]

# すべてのKeyにアンダーバー付きで修飾語をつける
def addkeyheader(dict,key):
    ks = list(dict.keys())
    for k in ks:
        changekey(dict,k,key+'_'+k)

# 本命の関数 深さ優先探索をした後に要素名を結合して返す
def dict_flatten(dict_,depth=2):
    newdict = {}
    for key in list(dict_.keys()):
        # 要素もdictなら再帰的に呼び出す 
        if isinstance(dict_[key], dict):
            if depth > 0:
                dic = dict_flatten(dict_[key],depth-1)
                addkeyheader(dic,key)
                newdict.update(dic)
            else:
                newdict[key] = dict_[key]
        # 要素がdictじゃないならそのまま
        else:
            newdict[key] = dict_[key]
    return newdict

```

## よりスマートな実装

コメントにてよりスマートな実装を教えていただきました。

```python
def _unwrap(dct, prefix):
    for key, value in dct.items():
        new_key = f'{prefix}_{key}'
        if isinstance(value, dict):
            yield from _unwrap(value, new_key)
        else:
            yield new_key[1:], value       

def unwrap(dct):
    return dict(_unwrap(dct, ''))

d2 = unwrap(d1)

```


## 想定していた使い道

- 入れ子構造のdictは以下のように2次元状に配置される（[参考](http://nishidy.hatenablog.com/entry/2016/03/10/015337)）。
- これとは異なり単にデータを単に並べたい場合がある。

Inputを変換すると以下のようになり，

```python
>> pd.DataFrame.from_dict(d1)
   A  B
i  0  2
j  1  3
```

Outputを変換すると以下の様になります。

```python
>> pd.DataFrame(d2,index=[""])
  A_i  A_j  B_i  B_j
    0    1    2    3
```

これでめでたしと思いきや，pandasの理解が浅かったです。

## PandasでMultiIndexを用いてナチュラルに分解が可能である

わざわざ分解するまでもなく実用上はMultiIndexの機能で編集可能です。
https://qiita.com/Morinikiz/items/40faa91e7a83807c0552

- dfをstack()またはunstack()することでまとめられる。
    - stackで列側を高レベルに，unstackで行側を高レベルに置ける
    - ただ，[こちらの解説](https://qiita.com/Morinikiz/items/40faa91e7a83807c0552)と挙動が逆なのはなぜ？

```python
>>> df = pd.DataFrame(d1)
>>> df
   A  B
i  0  2
j  1  3
```

```python
>>> df.unstack()
A  i    0
   j    1
B  i    2
   j    3
dtype: int64
>>> df.stack()
i  A    0
   B    2
j  A    1
   B    3
dtype: int64
```

Data Frameに戻すには最後にto_frame()を使えばいいです。

```python
>>> df.unstack().to_frame("name")
     name
A i     0
  j     1
B i     2
  j     3
```
v-modelでバインドしたcheckboxのvalueに"on"という文字列が入ってしまう

## 概要
checkboxの値を取得し、チェックされているか否かをBooleanでpostしたい。
しかし、なぜかvalueにBooleanではなく「on」という文字列が入ってしまう。

上記のような現象が起こった原因と解決策を自分なりに検証したので記載します。

#### 上記の現象が起こったコード
~~~exsample.vue
<template>
    <label
      v-for="(checkBox, key) in list"
      :key="key"
      :for="sample' + key"
    >
        <input
          :id="'sample' + key"
          v-model="checkBox.checkboxStatus"
          type="checkbox"
          name="sample[]"
          class="input"
        />
    <label>
</template>

<script>
  export default {
    data() {
      return {
        list: {
          { id: 1, checkboxStatus: false },
          { id: 2, checkboxStatus: false },
        },
      }
    },
  }
</script>

~~~

#### 　問題解決後のコード
~~~exsample.vue
<template>
    <label
      v-for="(checkBox, key) in list"
      :key="key"
      :for="sample' + key"
    >
        <input
          :id="'sample' + key"
          v-model="checkBox.checkboxStatus"
          type="checkbox"
          name="sample[]"
          class="input"
          @change=" e => changeHandle(e, 'sample[]', key, list.id,)"
        />
    <label>
</template>

<script>
  export default {
    data() {
      return {
        list: {
          { id: 1, checkboxStatus: false },
          { id: 2, checkboxStatus: false },
        },
      }
    },
    methods: {
      changeHandle(e, eln, index, id) {
        const isChecked = e.target.checked;
        document.form[eln][index].value = isChecked ? id : null;
      },
    },
  }
</script>

~~~


## 解説
checkboxをクリックした際に変わる値はtarget.valueではなく、target.checkedだった。
target.checkedの値はBooleanだが、submit時に送られる値はvalueなので
requestから見ると"on"という値になっていた~~（nullではなく"on"になるのはvueの仕様??）~~
@tomoyuki_okawa さんにコメントで教えていただきました、ありがとうございます！
HTMLの仕様みたいです、恥ずかしながら知りませんでした💦
https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/checkbox

そのため、無理やりではあるがDOMを取得しtarget.checkedの結果に応じvalueにpostしたい結果を代入するという方法を取りました。
もっと良い方法をご存知の方がいらっしゃいましたらご教示いただけると幸いです！
iOS 14で必要な？NSUserTrackingUsageDescriptionの設定方法


#NSUserTrackingUsageDescriptionとは何よ？
iOS14になったデバイスではじめてアプリをビルドすると、クラッシュしてもうた。。。
Xcodeのログは以下:point_down:

```console
This app has crashed because it attempted to access privacy-sensitive data without a usage description.  The app's Info.plist must contain an NSUserTrackingUsageDescription key with a string value explaining to the user how the app uses this data.
```

どうやら`NSUserTrackingUsageDescription`が必要？らしい。

とりあえず[公式のドキュメント](https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription)を読んでみる。


**要は`info.plist`に記載するList Keyのことらしい**

そして何が目的なのかと言うと、、、

>IDFA (Identifier for Advertisers) は、Appleがユーザーの端末にランダムに割り当てるデバイスIDです。 広告主はこのIDを使ってユーザーの広告エンゲージメント 、アプリ内のユーザー行動を計測することで、カスタマイズした広告を配信することができます。
https://www.adjust.com/ja/glossary/idfa/

と言うことらしいので、**「適切な広告配信のために、あなたのデバイスに割り当てられたIDを広告主が使用していいっすか？」**的な意味かな？？

#`info.plist`に値を追加
[こちら](https://medium.com/macoclock/how-to-apply-idfa-on-ios-14-beta-5-or-above-d44a425081d5)を参考に、とりあえずValueの部分に文字を入れてみる。


![スクリーンショット 2020-10-06 22.12.58.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/1604d8e8-3207-09b7-0855-ea37926db556.jpeg)


これでkeyとvalueをセットした

![スクリーンショット 2020-10-06 22.10.27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/4c13311b-99e5-ce59-37b3-321a68acbbf1.jpeg)

お！これが例のIDFAオプトインダイアログですか！
シュミレーターが英語設定なのでオプトインダイアログも英語になっているが、とりあえず問題なさそう。

参考：[iOS14で、IDFAオプトインダイアログを出してみる](https://qiita.com/matsuyoro/items/6c3db53b7bda4903328e)

#オプトインダイアログを日本語にする
[こちら](https://note.com/kiwi26/n/nb188b7039ac7)を参考に、それっぽい日本語文にして、実機でビルドしてみるとちゃんとオプトインダイアログは日本語になってました。



#最後に
アプリに広告を出している人はいずれ対応しないといけないっぽいので、お早めに〜


#追記
##SKAdNetworkItemsを追加する
>ここではGoogleがSKAdNetworkを利用できるようにします。
ユーザにIDFAの取得を拒否された場合でもAppleが提供するSKAdNetworkを利用して広告を配信するために利用するものです。
https://d1v1b.com/posts/update_admob_for_ios_app

![skadnetwork.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/1d23ece3-c3e8-349f-c7ef-ae4c374e39b1.png)

`Info.plist`にSKAdNetworkItemsを追加しておいた方が良さそうなので、入れておく
コメント機能のエラーハンドリングについて

#はじめに
Rails 6.0.3.4

コメント機能のエラーハンドリングの実装中躓いたのでここに記録します。

レシピ投稿サイトを作っており、レシピの詳細に入ると、その中にコメント機能とコメント一覧がある状態です。
コメントを投稿したユーザーの名前も一緒に載せます。
Commentモデル・コントローラー・コメントを表示させるビューは出来上がっているものとします。
ルーティングでは、CommentはRecipeにネストしてあります。

#バリデーションを作成

```
class Comment < ApplicationRecord
  belongs_to :recipe
  belongs_to :user
  validates :contents, presence: true, length: { maximum: 100 }
end
```

このような感じです。
contentsはコメント内容が入るカラム名です。
contentsのバリデーションは、空欄では投稿できないことと、100文字以内であるというものにしました。

#commentsコントローラーの編集
```
class CommentsController < ApplicationController

  def create
    @recipe = Recipe.find(params[:recipe_id])　#どのレシピと紐づいているか定義
    @comment = Comment.new(comment_params)　#空のインスタンスを作る（ストロングパラメータも忘れずに）
    if @comment.save　#もしコメントがセーブできたら
      redirect_to recipe_path(@comment.recipe.id)　#レシピ一覧に戻ります。戻り先のパスに、どのレシピのidなのかを教えてあげましょう。アソシエーションしているので、@comment.recipe.idでOK
    else　#もし保存できなかったら（バリデーションで弾かれた時）
      @comments = @recipe.comments.includes(:user)　#コメントは今までのコメントを表示させておき（ここを書いてなかった）
       render 'recipes/show'　#レシピ一覧へ戻ります
    end
  end

  private

  def comment_params
    略
  end
end
```
※recipesコントローラーの記述は省略しますが、
recipeビューでうつしたいものなのでもちろん空のインスタンスを置いてあげ、
eachメソッドでコメントが回せるように＠comments = で、そのレシピに対して投稿された保存済みのコメント定義してあげます

私はとりあえず、保存されない時はrenderで戻せばいいや！とrenderしか書いていませんでした。
ですがそうするとエラーメッセージは出るのですが、今までのコメントが一覧から消えてしまうエラーが起こります。

renderはそもそも直接ビューを表示させるものです。コントローラーを経由していません。
つまり、＠commentsの定義がされないままrender 'recipes/show'にいってしまうので、
レシピ一覧（recipes/showのビュー）で書かれている＠commentsとはなんですか？となっていたみたいです。
なのでrenderでビューに戻す前に、＠commentsを定義してあげましょう。

#ビュー
念のため置いておきます。

```
<div class="comment-box">
    <% if @comments %>
      <% @comments.each do |comment| %>←ここの@commentsのこと
        <p>
        <strong><%= comment.user.nickname %>：</strong>
        <%= comment.contents %>
        </p>
      <% end %>
    <% end %>
  </div>
```
AWS Lambda LayersへZenpyをデプロイしてみる

[Zendesk API](https://develop.zendesk.com/hc/en-us/categories/360000003388)をPythonから簡単に呼び出せるようにするラッパー[Zenpy](http://docs.facetoe.com.au/zenpy.html#)をAWS Lambda Layerに入れてみます。

# なぜLambda Layerを使うのか？
AWS Lambdaへプログラムをデプロイする際に関連するライブラリ群も一緒に入れる必要があります。そのため、複雑なプログラムになるとデプロイパッケージが肥大化しがちでした。
ライブラリやカスタムランタイム、その他の依存関係をまとめたZIPパッケージです。

- AWS公式ドキュメント： [AWS Lambda レイヤー](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html)

# この記事で行うこと
AWS Lambda Layerへ`Zenpy`ライブラリをデプロイする。

# 事前準備
* Dockerが必要です
* AWS SAMが必要です
    * `pip install aws-sam-cli`
* Amazon S3バケットを事前に作成する  
    * `s3-bucket ${APP_NAME}-${ENV}`

# Gihubから以下のリポジトリをクローン
https://github.com/hagaji/zenpyLambdaLayer

# ビルド＆デプロイ

```sh
pip install --upgrade pip
(cd ./; ./build.sh)
(cd ./; ENV=stg ./cli deploy)
```

#### 作成されるLayerの名前は `Zenpy-python37-layer` です  


### 動確するLambdaサンプルコード

```python
import json
from zenpy import Zenpy

creds = {
"token": "zendesknotoken",
"email": "hoge@moge.jp",
"subdomain": "zendesktest"
}

def lambda_handler(event, context):
    try:
        zenpy_client = Zenpy(**creds)
        ticket = zenpy_client.tickets(id=947)
        print(ticket)
    except Exception as e:
        print(e)

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```
Dockerのイメージ&コンテナの配置フォルダを変更

# 目的
dockerのイメージやらコンテナの保存先のvhdxをCではなくDドライブの任意のフォルダに持っていきたい。
基本は参考に挙げたリンク先の手順で行った。

# やってみたけどうまくいかない
```Powershell:chgdockerdir_failed.ps
wsl --import docker-desktop D:\Docker\docker-desktop docker-desktop.tar
```
上記を流した後、import先にはvhdxではなく、
Linuxみたいなディレクトリ構成のフォルダ群が出来上がる。
その状態でもDocker Desktopは起動するし、docker -vでバージョン情報は返ってくるが
docker runコマンドは起動せず下記のエラー。

```Powershell:chgdockerdir_failed2.ps
docker run -d -p 80:80 docker/getting-started
docker: Error response from daemon: open \\.\pipe\docker_engine_linux: The system cannot find the file specified.
```

# 原因？
```Powershell:chgdockerdir_failed2.ps
wsl --import docker-desktop D:\Docker\docker-desktop docker-desktop.tar --version 2
```
これだとうまくvhdxでimportできた。
指定しないとversion1になる場合がある？
wslのデフォルトを設定できるコマンドがあるようなので、
それをあらかじめ設定しておけば問題ないのでは？

wsl --set-default-version 2
であらかじめ設定してからだとimport時にversionを指定しなくてもOKみたいなのでこれで。

ちなみににっちもさっちもいかなくなった場合は
DockerDesktopのTroubleshootの
「Clean / Purge data」を押せば元に戻る。

# 最終的に流したコマンド
以下Powershellから実施

```Powershell:chgdockerdir.ps
#dockerを停止しておく
#デフォルトのwslのバージョンを2にしておく
wsl --set-default-version 2
#一度ディストリビューションをシャットダウン
wsl --shutdown
wsl -l -v
#  NAME                   STATE           VERSION
#* docker-desktop         Stopped         2
#  docker-desktop-data    Stopped         2

#現在のvhxdをtar形式でexport
wsl --export docker-desktop docker-desktop.tar
wsl --export docker-desktop-data docker-desktop-data.tar

wsl --unregister docker-desktop
#登録を解除しています...
wsl --unregister docker-desktop-data
#登録を解除しています...

#さっきexportしたtarを読み込み
wsl --import docker-desktop D:\Docker\docker-desktop docker-desktop.tar
wsl --import docker-desktop-data D:\Docker\docker-desktop-data docker-desktop-data.tar

```

#参考
[WSL2 Dockerのイメージ・コンテナの格納先を変更したい (WSL2のvhdxファイルを移動させたい)](https://qiita.com/neko_the_shadow/items/ae87b2480345152bc3cb)
[Docker Desktop の ディスク領域 を Cドライブから別のドライブへ移動する方法](https://nosubject.io/windowsdocker-desktop-move-disk-image/)
[「WSL」ディストリビューションのインポート・エクスポートはこんなに簡単！](https://forest.watch.impress.co.jp/docs/serial/yajiuma/1220926.html)
ParticleSystemにはパーティクルの最大サイズの設定がある

[PR: CADDiではバックエンドエンジニア、フロントエンジニア、アルゴリズムエンジニア、SRE等などを募集しています](https://corp.caddi.jp/recruit/eng)。

`ParticleSystem` を使っていると、大きなパーティクルを生成した時にスケールが不自然になる場合がある。これは `ParticleSystemRenderer` モジュールのパラメータ `ParticleSystemRenderer.maxParticleSize` （と `ParticleSystemRenderer.minParticleSize`）によるものである。

![ParticleSystemRenderer.maxParticleSize](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78355/10635777-27c6-4bc6-adad-25ccaafe398c.png)

この値を大きくすることでパーティクルの最大サイズを変更することができる。値を `Infinity` にすることで、上限値を事実上無効化することができる。

- [UnityEngine.ParticleSystem - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/ParticleSystem.html)
- [UnityEngine.ParticleSystemRenderer - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/ParticleSystemRenderer.html)
- [ParticleSystemRenderer-maxParticleSize - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/ParticleSystemRenderer-maxParticleSize.html)
- [ParticleSystemRenderer-minParticleSize - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/ParticleSystemRenderer-minParticleSize.html)
docker内にてマイグレーション時にエラーが出て詰まった話 PHP laravel

#docker内にてマイグレーション時にエラーが出て詰まった話 (laravel)
以下エラー内容です

```terminal:terminal
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known (SQL: select * from information_schema.tables where table_schema = db_name and table_name = migrations and table_type = 'BASE TABLE')

  at /var/www/html/laravel-vue-app/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
    665|         // If an exception occurs when attempting to run a query, we'll format the error
    666|         // message to include the bindings with SQL, which will make this exception a
    667|         // lot more helpful to the developer instead of just the database's errors.
    668|         catch (Exception $e) {
  > 669|             throw new QueryException(
    670|                 $query, $this->prepareBindings($bindings), $e
    671|             );
    672|         }
    673|

  Exception trace:

  1   PDOException::("PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name or service not known")
      /var/www/html/laravel-vue-app/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  2   PDO::__construct("mysql:host=mysql;port=3306;dbname=db_name", "db_user", "db_password", [])
      /var/www/html/laravel-vue-app/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  Please use the argument -v to see more details.
```
結論としてdocker-compose.ymlと.envのmysqlの設定は一緒じゃないとだめらしい

#解決策

laravel(app/)配下の.envがあっているかどうか確認 ->ホスト名に関してはdockerのコンテナ名と合わせる必要がある
docker-compose.ymlの内容に相違がある場合変更する必要性アリ
変更後は　　

```docker:docker
docker-compose stop
docker-compose up -d
```
を行う必要があるとのこと
理由:restartだとdocker-compose.ymlの設定が反映されないため
.envをの設定を反映させる場合は

```terminal:terminal
php artisan config:cache
```
で反映させる必要がある

#原因(追記)
どうやらlaravelがbiludされているappコンテナ-->mysqlがビルドされているdbコンテナ
同士の通信時にエラーが発生しているらしくて,
dockerのコンテナ同士の通信時にはmysqlがビルドされているコンテナにふられたIPアドレスを
使用する必要があるとのこと

```terminal:terminal
cat /etc/hosts | awk ‘END{print $1}’ | sed -r -e ‘s/[0-9]+$/1/g’
```
でコンテナのIPアドレスを確認できます
app配下の.envのホストIPがいっしょかどうか確認したほうがいいでしょう
テストで無闇にAllMatch的な処理をするのはやめよう

# なんの話？
テストを書いていることは大前提として、 **そのテストが失敗した時のことまで考えて書いていますか？** という話です。
具体例に関しては諸説あります。

# どういう状況？
例えばユーザー一覧を取得した時に、 **IDが50以下のユーザーだけ取得できていること** をテストしたいとします。
（実際にこんなテストをするかどうかは今は気にしない）

ユーザーは `id` を持ちます。

```java
public class User {
    private final Integer id;
    // コンストラクタ・ゲッターは省略
}
```

# allMatchを使った実装
いざ、 `getUserList` というメソッドを使いユーザーを取得して、IDが50以下であることをアサートしましょう！

```java
public class UserListTest {
    @Test
    public void test_getUserList() {
        List<User> userList = getUserList();
        assertTrue(userList.stream().allMatch(user -> user.getId() <= 50));
    }
}
```
できました！
めちゃめちゃシンプルに書けてるし、いい感じなのでは 🤔

# 何が悪いの
このようなテストだと、テストが失敗した時に何が間違っていたのか把握することが難しくなります。
例えば `id` = 60のユーザーがリストに含まれている時、下記のようなログが出力されます。

```
expected: <true> but was: <false>
```
これだとどんなデータが`userList`含まれていたのか分からず、なぜテストが失敗したのか良く分かりませんね。


# こうしてみよう

```java
public class UserListTest {
    @Test
    public void test_getUserList() {
        List<User> userList = getUserList();
        List<User> filtered = userList.stream()
            .filter(user -> !(user.getId() <= 50))
            .collect(Collectors.toList());
        assertEquals(filtered, Collections.emptyList());
    }
}
```
このようにIDが50以下のユーザーを取り除き、その結果が空のリストと等しいことをアサートします。
行数も増え条件が否定系になるので少しだけ可読性は下がるかもしれませんが、テストが失敗した時のログは分かりやすくなります。

```
expected: <[]> but was: <[User(id=60)]>
```

# まとめ
- テストが失敗した時にどんなログが出力されるのか考えながらテストを書きましょう
- そのために、 `assertTrue` ではなく `assertEquals` を使うようにしましょう





## メモ
- サンプルリポジトリ: https://github.com/sanopi/dont-use-allmatch/
- サンプルコードではListの具体的な型が異なる可能性がありますが、アサーションには問題ありません。気になる方は`assertEquals`の実装や、`java.util.List#equals`のドキュメントを参照してみてください。
Railsの関連付けのオプションを軽くまとめた(foreign_key、primary_key)

## 背景
テーブル同士の関連付けで、外部キーを変更するときにちょっとハマったので。

### テーブル設計

| products | 
|:--------:|
| id       |
| number   |
| price    |

| features | 
|:--------:|
| id       |
| product_number     |
| etc...   |


## やりたいこと
productsのnumberとfeaturesのproduct_numberで関連付けたい。

## 解説
### コード
```
has_one :feature, foreign_key: "number", primary_key: "product_number"
belongs_to :product, foreign_key: "product_number", primary_key: "number"
```
つまり、product側からfeatureを参照するときは、productのnumberとfeatureのproduct_numberが等しいレコードが紐付く。
逆も同様。

## まとめ
```
foreign_key　外部キーを指定(参照元のテーブルのカラムを指定)。デフォルトはhogehoge_id。
primary_key　別のテーブルを参照するときに用いるカラム(参照先のテーブルのカラムを指定)を指定。デフォルトでid。
```
社内でSOC構築してみた①　#EXIST概要編

Existの構築に関する記事。
<a href="https://qiita.com/hassy_mossan/items/2b58cbd236761bbe6c5f">社内でSOC構築してみた① #EXIST概要編</a>
<a href="https://qiita.com/hassy_mossan/items/78eec8d85ba140ebe00f">社内でSOC構築してみた② #MISP構築編</a>
<a href="https://qiita.com/hassy_mossan/items/f103987f3415a3ce7de8">社内でSOC構築してみた③ #EXIST構築編</a>
<a href="https://qiita.com/hassy_mossan/items/37e7e9b394f4926e4375">社内でSOC構築してみた④ #EXIST設定編</a>

<h2>初めに</h2>
2020年のある日、<b>自社内でSOCを刷新してみよう！</b>という話になりました。
※SOC=Security Operation Centerの略

実際には24h/365dayの本格的な運用ではなく体制や必要なシステムを構築して、検知したらアラート鳴らして担当社員が分析する。
そんな流れをまずは整えていくこととなりました。

これから構築に至るまでの過程をこちらに備忘録としてQiitaに残していきます。

<h2>未知の脅威情報への対処 - EXISTを使用する理由</h2>
構築にあたって一番最初に課題として、かつ重要であると議題に上がったのが<b>未知の脅威情報をどう対処するか</b>でした。

そんな中で見つけたのが<b>EXIST</b>でした。
※EXternal Information aggregation System against cyber Threatの略

情報の収集方法や、情報の属性が多様であることに加えOSSなので今後の拡張性が望めたため、今回は採用を決定しました。

構築から簡単な検証に至るまでを行い、改めて優れた点を実感したので、この記事を通してより大勢の方に認知して頂ければとおもいます。

なおEXISTの構築については苦労する点が多々あったため、概要は簡単にお話をして構築についてこれから重点的に説明いたします。

今回の構築にあたっては以下の情報を参考にしました。
・<a href="https://github.com/nict-csl/exist">EXIST - Github<a>
・<a href="https://soji256.hatenablog.jp/entry/2019/10/23/002216">setodaNote - サイバー脅威情報集約システム EXIST を構築する</a>
・<a href="https://www.misp-project.org/">MISP</a>
・<a href="https://ninoseki.github.io/2018/09/15/head-first-misp.html#%E3%81%AF%E3%81%97%E3%82%99%E3%82%81%E3%81%AB">ninoseki.github.io - Head First MISP - MISP入門<a>

<h2>1．Existの概要</h2>
この記事を見られた方は既にご存じかと思いますが、改めて簡単に概要を説明します。

EXISTは2019年にNICT(情報通信研究機構)がリリースした「サイバー脅威情報集約システム」
簡単に説明すると、異なる属性の脅威情報を集約して横断的な検索を可能とするOSSのWebアプリケーションになります。
![EXIST_overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83071/3559db59-1458-b61f-a3a8-652d92aba8f6.png)

上記はEXISTのNICTが作成した概要図ですが、左側の「Feeds」をみるとSNS、Threat intelligence(OpenSource)、Threat intelligence(Commercial Service)とそれぞれ性質の違う情報源があることがわかります、この点がまず<b>異なる属性の脅威情報</b>を集約しているという点にあたります。

そして集約された情報が真ん中の「EXIST」に集約されます。
集約した情報を1つの検索窓から検索(することもできる)、つまり<b>横断的な検索が可能</b>となります。

以上ザックリですが、概要を説明になります。
<h2>2.EXISTの機能</h2>

Existの主な機能は下記になります。

<b>1.Threat</b>
MISP (Malware Information Sharing Platform)と呼ばれるOSSのWebアプリケーションにて集約される情報を収集します。
MISPについては後の構築編でも扱いますが、簡単に説明すれば脅威情報を登録しコミュニティ間のMISPで情報を共有します。

<b>2.Tracker</b>
SNS、Threat intelligence(OpenSource)、Threat intelligence(Commercial Service)それぞれの情報をクローリングして収集します。

<b>3.Hunter</b>
ThreatとTrackerで収集されたメディア関連の情報とSNSの情報のうち、特定のキーワードをもとに継続的に監視します。
<b>※SNSの監視は少し異なる。</b>

<b>4.Lookup</b>
収集されたIP、URL、Domain、FileHashの情報を検索します。

<b>5.WebAPI</b>
API経由でEXISTを操作します。

<h2>3.EXISTのメリットと活用について</h2>
ここまでは簡単にEXISTについて説明しましたが、結局EXISTは何がすごいのか？どのように使用するのかを簡単に述べます。

<b>1.情報の網羅性とスピード</b>
例えば、JVNで公表される前の情報がSNSやコミュニティで公開されていたり、各メディアでは未公表の情報がSNSから収集できたりとこれまでの様に受動的だった情報の収集が収集という行動によってより早く把握できかつ様々な情報源から網羅的に収集できます。

<b>2.継続的な監視</b>
Hunterの機能を使用すれば、ある時点では検索に掛からなかった情報も時間の経過と共に蓄積されたことで検知が可能となります。

<b>3.関連性による危険性予知</b>
検索対象が様々な情報源に関連していることが把握できるため、データの関連から危険性を予知することができる。

<h3></h3>
以上がEXISTのザックリとした概要になります。
以降は構築方法を記載していきます。
jestのbeforeEach/Allでasyncを使ってうまくいかなかった場合の備忘録

Jestだと、テストごとに初期化したりDBにモックデータを突っ込んだりする場合に```beforeEach```に処理を書きますが、なかなかうまくいかなかったので対処した際の備忘録です。

## 公式Doc

>beforeEach と afterEach は非同期コードをテストする と同様に非同期コードを扱えます - promise を返すか done パラメータのどちらかを選択します。 たとえば、もし initializeCityDatabase() が promiseを返すのであれば、データベースが初期化された際には promise が返されることが望まれます。


```js
beforeEach(() => {
  return initializeCityDatabase();
});
```

または

```js
beforeEach(async (done) => {
  await initializeCityDatabase();
  done()
});
```

まず```return```し忘れていないか、done()を書いているかチェック

## タイムアウト時間を伸ばす

デフォルトのタイムアウト時間は5000msなので、時間がかかる処理をAsync内で行うと期待どおりに動作しない場合がある。
```jest.config.js``` の ```setupFilesAfterEnv```に指定したファイルで指定するのが良さそう。

```js
jest.setTimeout(10000)
```

## それでも解決しない

手元で起きた問題の場合、どうやら最初に実行されるテストだけが```beforeEach```でDBの初期化に失敗してしまうらしく、それ以降のテストは問題ない。
少々強引だが、リトライを設定すればテストは通るはず。

## Jestのリトライ設定

>Runs failed tests n-times until they pass or until the max number of retries is exhausted. This only works with jest-circus!

>テストにおける例:

```js
jest.retryTimes(3);
test('will fail', () => {
  expect(true).toBe(false);
});
```

```This only works with jest-circus!```と書かれているのでそのままでは使えない。

## jest-circus

https://github.com/facebook/jest/tree/master/packages/jest-circus

軽くて高機能なテストランナーらしい。
デフォルトのテストランナーは```jasmine2```なので切り替える。

```bash
npm i -D jest-circus
```

```js:jest.config.js
module.exports = {
  ...
  testRunner: 'jest-circus/runner',
  ...
}
```

リトライが使えるようになり、強引だが一応テストは通るようになった。

根本的に何故うまくいかないのか、こちらで同様の議論があった。
https://github.com/facebook/jest/issues/1256
--go_out: protoc-gen-go: Plugin failed with status code 1.の解決方法


protoファイルを作成し、コードを自動生成しようとした際にエラーが発生。

```
protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld

protoc-gen-go: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
--go_out: protoc-gen-go: Plugin failed with status code 1.
```

PATHを設定してくださいと言われているようなので、`bash_profile`に以下を追加すれば解決！

```
export GOPATH=$HOME/go
PATH=$PATH:$GOPATH/bin
```
オムニチャネル(Omni Channel)

応用情報技術者平成28年春期 午前64

オムニチャネルの特徴はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5fc154d2-5b6a-0809-a221-99c19d8dfa74.png)

１、オムニチャネル(Omni Channel)は、
販路として展開する実店舗、ECサイト、カタログ通販、モバイル端末などのシステムや仕組みをシームレスに連携・融合させ、どの方法でも同レベルの利便性で注文・購入できるようにした販売環境のことです。
"オムニ"は「あらゆる」「すべて」、"チャネル"は「接点」という意味があります。

実店舗とECサイトで在庫管理を一元化したり、インターネットで購入した商品をコンビニなどの実店舗で受け取る仕組みなどが典型的な事例です。


参照：
https://www.ap-siken.com/kakomon/28_haru/q64.html
初学者チームがWebサービス開発を始めて６週間経ったらそれぽくなってきた？

**[YouTube万屋エンジニアチャンネル](https://www.youtube.com/channel/UCHxqQ8bUg5F2GW79D_DvSjQ/videos)**のコミュニティ内で、「フレームワークって何？美味しいの？」レベルのプログラミング初学者が４人集まってWebアプリを制作を始めて６週間が経過しました。６週間経ってようやく、２週間前のような「見られたら超恥ずかしくて死にそう！」というレベルからは脱出できたかなと思います。

「初心者だけど何かモノを作ってみたい！」という方の参考になれば幸いです。過去の記事はこちらです。
「[初学者チームがWebサービス開発を始めて最初の２週間でやったことを振り返り、そして次を考える](https://qiita.com/kakudaisuke/items/8a3f9e9d9ed2630e7e4f)」
「[初学者チームがWebサービス開発を始めて４週間で出来たことと出来なかったこと](https://qiita.com/kakudaisuke/items/3596e78bd158f6e39987)」


#目標達成度
２週間前掲げていた目標と、実際できたことを整理します。

| 2週間前掲げた目標 | 達成度　10点満点|コメント|
|:-----------|------------:|:-----------|
|継承レイアウトで構築し、サイト全体にデザインの統一感がある| 8|２週間前はちんぷんかんぷんでしたがきちんと理解しました→「[Laravel7継承レイアウトの基本を図解してみた](https://qiita.com/kakudaisuke/items/39eb4a80945d08cc1d67)」|
|投稿の文章が長い場合、全文表示／一部表示の切り替えができる| 5|リモートにマージは出来なかったもののメンバーのローカルではコードは書けていた|
|ドロップダウンメニュー| 7|一部を残して実装できました|
|投稿の際、チップスの効いたタグ付けができる|6|Chipsをつけるとinputタグで拾って送信できず...|
|投稿に付いたタグをクリックするとそのタグの投稿一覧を表示できる|8|これはなんとか実装できました。|
|登録ユーザーの投稿一覧が表示できる|8|これもなんとか実装できました。|
|検索機能|0|全く手をつけられませんでした。|
|いいね機能の実装|2|JSで少し検討できただけで、まだDBすら作成できていません。|
|Contactから運営側にメールが届き、問い合わせ内容がわかる|10|Mailtrapを使用して実装できました。|
|ユーザーがプロフ画像を設定できる|5|DBの設計変更を経験しました。ただうまくDBに送ることができず苦戦しています。|
|**総合得点**|**59/100**|**達成度59%**|

その他にできたこと

* Emailアドレスでもアカウントネームでもログインができる

#この２週間を振り返って
###ヒューマンエラーとコミュニケーション
この期間で一番学んだことは、ヒューマンエラーにどう対処するかという問題です。
私たちは、主にslackで連絡を取り合っていて、週２、３でオンラインで全体でMTGしているのですが、この２週間の間にコミュニケーションミスによってGitHub上でヒューマンエラーが１件起きました。こういうのをそのメンバーのせいにしてしまいがちですが、リーダーの責任でもあると思います。いや、そう思って対処しないと、そのリーダーにもチームにも成長は無い気がします。ここでどう次の対策を施すか、それこそリーダーの真価が問われるのかなと思いました。
ここで思ったのは、slackは便利だけど**文字だけで全て全員共通認識が取れていると思うのは傲慢**ということです。今までも通話やビデオ電話でコミュニケーションはしていましたが、その機会をもっと増やそうとチームに呼びかけました。


#今後の開発
###次の目標（開発第４フェーズ）
期限：10/26月曜18:00
下記10点の実装を目指します。

1. 検索機能
* いいね機能の実装
* 投稿の編集削除権限をその投稿主に限る
* 投稿にチップスの効いたタグ付けができる
* 投稿に付いたタグをクリックするとそのタグの投稿一覧をTagControllerで表示できる
* ユーザーがプロフ画像を設定できる
* 開発者紹介がモーダルウィンドウで展開できる
* フッターの画像がランダムに切り替わる
* ユーザーログイン周りのデザインを統一する
* 利用規約ページを設ける

この第４フェーズから、なんと経験者が僕らのプロジェクトに参加してくださるというまさかの展開になったので、その新メンバーの環境構築や慣れるまでの期間を１週間見て、そこから２週間、合計３週間という期間で次のステップアップを目指していきたいです。
Ruby 複数行の入力を受け取る

# 複数行の入力を受け取る
```
input = readlines

# 入力
# 120
# 115
# 122
# 116
# 119
# 117

puts input
# 出力結果
# 120
# 115
# 122
# 116
# 119
# 117 
```

`readlines`メソッドで複数行受け取ることができる


#複数行の入力を改行なしで受け取る
```
input = readlines.map &:chomp

# 入力
# 120
# 115
# 122
# 116
# 119
# 117

print input 
# 出力結果
# ["120", "115", "122", "116", "119", "117"]

puts input
# 出力結果
# 120
# 115
# 122
# 116
# 119
```

・chompメソッド：　文字列の改行を取り除く。
・mapメソッドで要素を整数に変換する
外部委託管理の監査

応用情報技術者平成28年春期 午前60

外部委託管理の監査に関する記述のうち，最も適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/1b1cc74b-f70f-6db7-18ae-1199ba91ddd0.png)

１、
・請負契約においては，委託側の事務所で作業を行っている受託側要員のシステムへのアクセス管理が妥当かどうかを，委託側が監査できるように定める。
　→○。受託側要員の情報へのアクセスに関して、要求事項が遵守されているか否かを監視するためのプロセス及び手順が必要です。

・請負契約の場合は，受託側要員に対する委託側責任者の指揮命令が適切に行われているかどうかを，委託側で監査する。
　→×。請負契約においては、受託側要員に対する指揮命令は受託側企業によって行われていなければなりません。監査すべきは、受託側要員に対する委託側責任者の指揮命令が行われていないことです。

・外部委託で開発した業務システムの品質管理状況は，委託側で監査する必要はなく，受託側で監査すべきである。
　→×。委託業務の進捗状況、品質管理状況などは委託側が監査すべき事項です。

・機密度が高い業務システムの開発を外部に委託している場合は，自社開発に切り替えるよう改善勧告する。
　→×。外部委託と自社開発のどちらが適しているかは、コストや納期、自社の技術などの様々な要素を勘案して決定されるべき事項なので、単に機密性の度合いによって自社開発への切り替えを勧告すべきではありません。


参照：
https://www.ap-siken.com/kakomon/28_haru/q60.html
綺麗にトップページに写真を貼る方法

現在ポートフォリオ作成中
ホームページ上に**大きな写真を載せたい**と考えました。
その際に自分が行ったことを記事にします

#結論
CSSに

```index.css
.photo{
 object-fit: cover
```
を記述しました。

#####この**object-fit**とはなんなのか説明していきます。

#object-fitとは
#####widthやheightに合わせて写真の縦横比を調節してくれるものです!!
はみ出た部分はリサイズされます。

#プロパティ一覧
様々なプロパティが準備してあります
###fill	
初期値。縦横比を無視して画像をコンテナーにフィットさせます。縦横比無視なので画像は歪む場合があります。

###contain
縦横比を維持しつつ、コンテナーからはみ出さないようにぴったりフィットするようにします。余白の部分は縦横どちらの場合も中央に配置します。
###cover
コンテナーに余白が出ないよう縦横比を維持しつつ、全体を覆うようにフィットさせ縦横中央に配置します。コンテナーからはみ出る部分はトリミングします。
###none
画像のリサイズはせずに縦横中央に配置します。
###scale-down
コンテナーより画像が大きい場合は「contain」を、小さい場合は「none」を指定します。
###object-position
画像の位置を指定します。指定の仕方は「object-position:’横の位置’ ‘縦の位置’;」となります。位置の指定は「％」、「px」や「top」・「center」という指定もできます。初期値は「object-position:50% 50%」で縦横中央に配置します。

#最後に
width: 〇〇vw;
height: 〇〇vh;
と合わせれば画面サイズが変わっても画像の大きさは変わらないからオススメです！
画像容量は1MB以下を推奨しますサイズは1920x1080
link_toメソッドを使ったときに、表示させる文字を追加する方法

#link_toメソッドとは
Railsで、「.html.erb」の拡張子でHTMLでいうところのaタグを生成してくれるメソッド。
Railsで開発を進めるときには、よく使うヘルパーメソッドの一つ。

##基本的な書き方

```ruby

<%= link_to '表示させる文字' , リンク先のURLやpath %>
```
表示させる文字のところには、テーブルのカラムから呼び出した値を入れることも可能。
ex) `post.name`、`@user.name`など


##リンクに表示される文字に呼び出した値を入れ、さらに文字列を追加したいとき

```ruby

<%= link_to @user.name + "さん", root_path %>
```
`+ "追加したい文字"`とする。
「さん」を含めた全体がリンク先に行くマウスカーソルの範囲となる。