OmniAICreator/Qiita-1.07M huggingface dataset:
MastodonのPostgreSQLのDatabaseをWAL-Gでオブジェクトストレージにバックアップ

MastodonのPostgreSQLのDatabaseをWAL-Gでオブジェクトストレージにバックアップしたい
# 最初に
基本的にのえるさんの記事を参考にさせてもらいました。
https://blog.noellabo.jp/entry/2019/03/05/yMjQeU9JXHxcyHTL
ちょっと気になった点と相違点などを補足させてもらいます。
参考元よりかなり雑なので一度ご覧になってからの方がいいかもしれない…

# 作業環境
ここの作業環境はFedora 34ですが、同時にセットアップしたCentOS Stream 8でも動きました、DBはPostgreSQL13です
ただ後者CentOS Stream 8はwal-gのパッケージがwal-g-pg-ubuntu-18.04-amd64.tar.gzじゃないといけなかった
前者Fedora 34はwal-g-pg-ubuntu-20.04-amd64.tar.gzのパッケージで動いた
バージョンとしてはwal-g v1.0を使わせてもらいました
FedoraなんでUbuntuのビルド済みパッケージ使えないかと思ったけど
そんなことはなかったのでwgetでubuntuのビルド済みパッケージをダウンロードして解凍して/usr/local/bin/wal-gとして置いた

# 環境変数定義
次に/usr/local/bin/wal-g.shを作成します。
このスクリプトで環境変数を操作します。
今回の作業環境はGoogle Cloud Storageなので設定値はちゃんと見てもらって
https://cloud.google.com/docs/authentication/production#manually
を参考にjsonファイルをコンピュータにダウンロードしてサーバーの任意のディレクトリに置いて欲しい

```bash:wal-g.sh
#!/bin/bash
export WALG_COMPRESSION_METHOD="brotli"
export WALG_GS_PREFIX="バケットのgsutil URI"
export GOOGLE_APPLICATION_CREDENTIALS="さっきのjsonファイルのディレクトリ指定"
export PGPORT="5432"
export PGHOST="/var/run/postgresql"
exec /usr/local/bin/wal-g "$@"
```

# フルバックアップはサービス化したい　１日ごとのバックアップ
フルバックアップはサービス化したいんで
/etc/systemd/system/wal-g-full-backup.serviceを作成し、systemctl daemon-reload
ちなみにExecStartPostに書いてあるのはBetter Uptimeっていうので死活監視したくてheartbeat用のURLにcurl投げてます
このサービスを実行することでデータベースのバックアップをオブジェクトストレージに転送できます
うちはretain 90で90個分（＝９０日分）保存してるわけだけど１回あたりで結構容量食うから７個分とかでもいいかも

```systemd:wal-g-full-backup.service
[Unit]
Description = WAL-G Full Backup

[Service]
Type = oneshot
User = postgres
WorkingDirectory = /usr/local/bin
ExecStart = /usr/bin/bash -c '/usr/local/bin/wal-g.sh backup-push /var/lib/pgsql/13/data'
ExecStartPost = /usr/bin/bash -c '/usr/local/bin/wal-g.sh delete retain 90 --confirm'
ExecStartPost = curl "監視サイトのheartbeat設定ページに書いてあるURL"
```

# cronで毎日実行させたい
上記のバックアップをcronで毎日実行したいんですが最近はcrondが無効化されてることあるらしいので
crondサービスをsystemctlで有効化して開始する
cronが入ってないのならばインストール、すでに有効化済みならOK
そもそもcron使わないでsystemctlのtimerファイル作成でもよし（これが最近のトレンドらしい）
/etc/cron.daily/wal-g-dailyっていうファイルを作成

```php:wal-g-daily
#!/bin/bash
systemctl start wal-g-full-backup
```
あとはこれにchmod +x /etc/cron.daily/wal-g-dailyで実行権限付与する（しないとcronが動かない）

# postgresql.confの設定 毎分のバックアップの設定
postgresql.confの該当箇所のみ書き換える /var/lib/pgsql/13/data/postgresql.conf
これで毎分WALをアーカイブしてオブジェクトストレージに転送できるらしい
設定終わったらsystemctl restart postgresql-13.service
restore_commandはリカバリの時に使う設定だけどストリーミングレプリケーションしてる際にはここからWALを読み出すので、設定しとくといい

```php:postgresql.conf
archive_mode = on
archive_command = '/usr/local/bin/wal-g.sh wal-push %p'
archive_timeout = 60
wal_level = replica
restore_command = '/usr/local/bin/wal-g.sh wal-fetch "%f" "%p"'
```

あとはsudo tail -f /var/lib/pgsql/13/data/log/postgresql-{任意の曜日}.logで変なエラー出てないか見てやる
プログラミングの基礎　PHPで応用を考えてみる。

#はじめに
浅井健一さん著書の『プログラミングの基礎』　という本があります。
この本の趣旨として正しいコードを書くための道標となる「デザインレシピ」というものがあります。
・どのようにメソッドを作れば良いのか？
・正しいプログラムを作るにはどうすれば良いのか？

著者が提唱する`デザインレシピ`に沿って書けばこのような疑問を払拭できるのです。

この本ではOCamlという関数型言語を用いて説明がされています。
しかしながら、他の言語でも応用が効くんじゃないか？と考え
PHPでも応用できるのではないかと思いまとめてみました。

#メソッド定義に関するデザインレシピ

デザインレシピはプログラム作成時に従うべき指針を提示してくれます。
重要なポイントをまとめると
`①目的：`
　　  `作成するメソッドが何をするものなのか。何を受け取り何を返すのかを考える`
`②例：`
　　  `目的をより具体的に落とし込む作業。作成するメソッドに望まれる入力と出力の例を作成する。`
`③本体：`
　　  `メソッド本体の作成をする。目的では「何を」するか考えたがここでは「どうやって」実現するか考える`
`④テスト：`
　　　`望みどおりの挙動をしているのか。作ったテストプログラムで確認を行う`
　　　`挙動が望み通りでないのならば①からもう一回練り直す`

以上4stepです。
では実際のコードで見ていきましょう。

#給料を計算するメソッドkyuyo

表題の通り給料を計算するメソッドで考えていきます。
デザインレシピに沿って考えるとまず初めに考えるべきは目的です。
今回の目的は
`働いた時間(x)に応じたアルバイト代を計算すること`
とします。
ここで引数を入れるときは入出力の型も考えておきましょう。


``` kyuryo_head.php
// 目的：働いた時間(x)に応じたアルバイト代を計算する 
// kyuyo : int -> int 

<?php 
function kyuyo ($x){
  return  $x * 0;
}
?>
```
この３行をヘッダと呼び`目的、型、変数名`を入れます。

**そもそも自分はこのメソッドで何をやりたいのか？**
**引数の型は何でどのような型で出力されるのか？**
**考えられる最小の形のメソッドを考えると捉えていいと思います。**
少し面倒ですが特に型を考えるのは省略してはいけないと著者も言っています！
確かに考えたことなかったけどメソッドの理解が進む気がする。。。

基本形であるヘッダができたので次は例ですね！
最小の形では０を掛けるようにしたのでとりあえず８００と考えます！

```kyuryo.php
<?php
function kyuyo ($x){
  return  $x * 800;
}

kyuyo(5);
 4000;
?>
```

このように成功した時の例を考えていきます。
例を作っておけば完成した後にテストで確かめていくことができる！
3つほど作っておくと良いそうです。

続いてテストを書いていきます。

```kyuryo_test.php
<?php
require kyuryo.php;

if (kyuyo(5) === 4000 ) {
  echo "true";
} else {
  echo "false!;
}
?>
```

このテストは当然trueとなるはずです。
さて、ここで最初に作ったヘッダをテストしてみます。

```kyuryo_head_test.php
<?php
require kyuryo_head.php;

if (kyuyo(5) === 4000 ) {
  echo "true";
} else {
  echo "false!;
}
?>
```

この時点では全てを0で返すのでfalseになります。
先に最小限のヘッダを作りここでテストをする。
ここで出てくるfalseをtrueにするようにメソッドの中身を作れば良いわけなので
目標ができるということみたいです！

さてここまできたら最後はどうやって実現するかを考えます。
今回の場合は超簡単ですね。働いた時間xに時給をかけてあげれば良いですね。
最終的にはこうなりました。

```kyuryo.php
<?php
//　時給（円）
 $jikyu = 800;

// 目的：働いた時間(x)に応じたアルバイト代を計算する 
// kyuyo : int -> int 

function kyuyo ($x){
  return  $x * $jikyu;
}

//後はテストを実施してtrue確認すれば完了！
```

#まとめ
今回は例題ですごく簡単なので一気にやった方が早いじゃんと！思っちゃいますが
複雑になる程効果が高いはずです。
デザインレシピに沿っているかいないかでメソッドの完成度、信頼度が物凄く変わりそうだと感じました。

今回はメソッドのデザインレシピでしたが他にもif文のデザインレシピなど
色々なデザインレシピがありますので一度本を読んでみると勉強になると思います！

今回はPHPで考えましたがどの言語にも応用が効くと思います！
Markdown: [プログラミングの基礎](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E5%9F%BA%E7%A4%8E-Computer-Science-Library-%E6%B5%85%E4%BA%95/dp/4781911609 "プログラミングの基礎")

内容に間違いありましたら陳謝します
応用数学

#第1章:線形代数

##行列

* スカラーを表にしたもの
* ベクトルの変換や連立方程式を解く際に用いる

##行の基本変形

* i行目をc倍する
* s行目にt行目のc倍を加える
* p行目とq行目を入れ替える

##連立1次方程式の解き方

1. 係数部分と変数部分、解部分に分けた3つの行列で表す
1. 係数部分の行列を行の基本変形を用いて単位行列に持っていく
1. 係数部分に行の基本変形を適用した際には解部分にも同様の変形を適用する

##逆行列

正方行列$A$との席が単位行列$E$となる行列
$A^{-1}$と表す
$$AA^{-1} = A^{-1}A = E$$

##行列式
```math
det \left(
\begin{matrix} 
a_{11} & a_{12} \\ 
a_{21} & a_{22} 
\end{matrix} 
\right)
= a_{11}a_{22} - a_{12}a_{21} \\
\\
det \left(
\begin{matrix} 
a_{11} & a_{12} & a_{13} \\ 
a_{21} & a_{22} & a_{23} \\
a_{31} & a_{32} & a_{33}
\end{matrix} 
\right)
= a_{11}a_{22}a_{33} + a_{12}a_{23}a_{31} + a_{13}a_{21}a_{32} \\
\hspace{95pt} - a_{11}a_{23}a_{32} - a_{12}a_{21}a_{33} - a_{13}a_{22}a_{31}
```

行列式 $|A| \neq 0$ のとき逆行列が存在する

##固有値と固有ベクトル

$$A \vec{x} = \lambda \vec{x}$$
このような式が成り立つ時 $\lambda$を固有値、$\vec{x}$を固有ベクトルという

##固有値分解

固有値 $\lambda_1, \lambda_2, \cdots, \lambda_n$と固有ベクトル $\vec{v}_1, \vec{v}_2, \cdots, \vec{v}_n$ を持ち、固有値を対角線上に並べた(それ以外の成分は0の)正方行列を $A$ とする

```math
{\Lambda=\left(
\begin{array}{cccc}
\lambda_{1} &   &  & \\
 & \lambda_{2} & & \\
 &  &\ddots &  \\
 &  &  & \lambda_{n}
\end{array}
\right)
}
```

$A$ に対応する固有ベクトルを並べた行列を $V$ とする

```math
{V=\left(
\begin{array}{cccc}
\vec{v}_{1} & \vec{v}_{2}  & \cdots & \vec{v}_{n}
\end{array}
\right)
}
```

この時、

```math
AV = VA \\
A = VAV^{-1}
```

##特異値分解
固有値分解は正方行列でしかできないが、正方行列でない行列に対して似たような分解を行うことができる

##確率
* 頻度確率(客観確率)
* ベイズ確率(主観確率)

```math
P(A)=\frac{n(A)}{n(U)}=\frac{事象Aが起こる数}{すべての事象数}\\
0\leq P(A) \leq 1
```

##条件付き確率
ある事象 $B$ が与えられたもとで $A$ となる確率
$$P(A | B)=\frac{P(A\cap B)}{P(B)}$$

##独立な事象の同時確率
お互いの発生には因果関係のない事象 $A$ と事象 $B$ が同時に発生する確率
$$P(A\cap B) = P(A)P(B|A) = P(A)P(B)$$

##ベイズ則(ベイズの定理)
```math
P(A)P(B|A)=P(B)P(A|B) \\
P(B|A)=\frac{P(B)P(A|B)}{P(A)} \\
\frac{P(B\cap A)}{P(A)} = \frac{P(A\cap B)}{P(A)}
```

##期待値
その分布における確率を考慮した平均値

離散的な分布の期待値
$$E(x) = \sum_{k=1}^{n}x_kP(x_k)$$

連続的な分布の期待値
$$E(x) = \int xP(x)dx$$

##分散
データの散らばり具合
$$Var(x) = E((x-E(x))^2) = E(x^2)-(E(x))^2$$

##共分散
2つのデータ系列の傾向の違い

* 正の値を取れば似た傾向
* 負の値を取れば逆の傾向
* 0に近いほど関係性に乏しく、$|1|$に近いほど関係性が強い

$$Cov(x, y) = E((x-(E(x))(y-(E(y))) = E(xy)-E(x)E(y)$$

##ベルヌーイ分布
* コイントス
$$P(x|\mu) = \mu^x(1-\mu)^{1-x}$$

##マルチヌーイ(カテゴリカル)分布
* サイコロを転がす

##二項分布
* ベルヌーイ分布の多試行版
$$P(x|\lambda, n)=\frac{n!}{x!(n-x)!} \lambda^x(1-\lambda)^{n-x}$$

##ガウス分布
釣鐘型の連続分布
$$f(x)=\frac{1}{\sqrt{2\pi\sigma}}exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)$$

##自己情報量
$P(x)$の確率で起きる事象$x$の自己情報量
$$I(x)=-\log_2P(x)$$

##シャノンエントロピー
自己情報量の期待値
情報を送る際に必要なビット数の平均の下限
$$H(x) = E(I(x)) = -E(\log_2P(x))) = -\sum(P(x)\log_2P(x)))$$

## カルバック・ライブラー　ダイバージェンス
同じ事象・確率変数における異なる確率分布P, Qの違いを表す
離散確率分布$P$の$Q$に対するカルバック・ライブラー情報量

```math
D_{KL}(P||Q) = \sum_{x}p(x)log_{2}\frac{p(x)}{q(x)} = \sum_{x}p(x)(log_{2}p(x) - log_{2}q(x))
```

連続確率分布では積分する

##交差エントロピー

* カルバック・ライブラー　ダイバージェンスの一部分を取り出したもの
* $Q$についての自己情報量を$P$の分布で平均している

$$H(P, Q)=H(P)+D_{KL}(P||Q)=-\sum_{i}P(x_i)log_2(Q(x_i))$$

$Q$の分布に最適化されたコードで$P$の分布の確率変数の情報を送ってしまった際に必要なビット数の平均の下限
機械学習の損失関数に用いられる
【JavaScript】配列用のメソッドをまとめてみた

*書き途中なので随時追加予定です。*

##reduce
配列の各要素の値を累積し1つの値にするメソッド。

````JavaScript
[対象の配列].reduce(function([累積値], [処理される値]){})
````
**[対象の配列]**に対して配列の各要素の値を**[累積値]**に累積していく。
**配列の中身を1つずつ足していって合計値を出す**って感じ。


###使用例
 例）**配列の各値の合計値が知りたい**

````JavaScript
var array = [1,2,3,4,5];

var totalNum = array.reduce(function(a,b){
    return a + b;
});

console.log(totalNum); // 15

````
上記の例ではarray配列の値の合計値が返されている。
配列の値を1つずつ足し算し、aの[累積値]に累積してくれている。

ざっくりとこんな感じ↓

|処理の回数|aの値|bの値|次処理のaに持ち越される値|
|---|---|---|---|
|1回目 | 0 | 1 | 1 |
|2回目 | 1 ( 1回目の累積値 )| 2 | 3 |
|3回目 | 3 ( 2回目の累積値 )| 3 | 6 |
|4回目 | 6 ( 3回目の累積値 )| 4 | 10 |
|5回目 | 10 ( 4回目の累積値 )| 5 | -　(処理終了)

現在の処理に対して、aの[累積値]の更新をしてくれるのは次の処理になる。
そのため返り値は`a + b`をしてあげる必要がある。

##splice
指定した配列から要素を削除、追加して組み替えた値を返してくれるメソッド。

````JavaScript
/*
 第1引数　　：削除,追加したい要素のindex
 第2引数　　：削除したい要素の数
 第3引数以降：追加したい要素
*/

//配列の要素を削除する場合
[対象の配列].splice([削除する配列のindex],[削除する要素の数]);

//配列の要素を追加する場合
//第２引数、削除する要素はないため０にする
[対象の配列].splice([追加する配列のindex],0,[追加する要素1],[追加する要素2]...);
````

###使用例
 例）**配列の３番目の要素を削除して、新しい要素を入れ直したい**

````JavaScript
//'がきぐげご'を'さしすせそ'に変更
var array = ['あいうえお','かきくけこ','がぎぐげご','たちつてと'];
array.splice(2,1,'さしすせそ');

console.log(array);//['あいうえお','かきくけこ','さしすせそ','たちつてと']
````

##every
配列の各要素に対して指定した条件の**すべて**が一致した場合にtrueを返してくれるメソッド。
配列内の要素が1つでも一致しない場合はfalseを返す。

````JavaScript
var array = [1,10,100]

array.some(value => value < 1000);
//return true
//配列の各要素、全てが1000より小さい数字のため

array.some(value => value < 10)
//return false
//配列内に10より大きい数字が存在するため

````
##some
配列の各要素に対して指定した条件が**1つでも**一致した場合にtrueを返してくれるメソッド。

````JavaScript
var array = [1,10,100]

array.some(value => value > 99);
//return true
//1つの要素は99以上であるため

````

##Object.assing
第1引数に指定したオブジェクトに第2引数以降をコピーしてくれるメソッド。
第1引数に無名オブジェクトを指定することで、第2引数以降のコピー内容を新しいオブジェクトとして作成することができる。

````JavaScript
let obj1 = { a:1, b:2 };
let obj2 = Object.assign({},obj1);
//　{ a:1, b:2 }
````
詳細はこのページをみてもらうといいかも。
いろんなコピーの方法があるみたいです。
https://qiita.com/SE-studying-now/items/ecdbc0317ba1806aed61

## map
配列の各要素1つずつに対して「コールバック関数」を実行し、その結果を新しい配列として返すことができるメソッド。
元の配列は操作（変更）することはできない。新しい配列を作るのがお仕事。

````JavaScript
let array = [1,2,3,4];

let result = array.map(function(value) {
    // 【コールバック関数】各要素に適用したい処理を記載
    // 今回は配列内の各要素を2倍にする
    return value * 2;
});
// result = [2,4,6,8]
// arrayの各要素が2倍され、resultという新しい配列に格納された
````

### 3つの引数を取得することも可能

````JavaScript
[配列データ].map(function(value, index, array) {
    // value: 配列の値
    // index: 配列のインデックス番号
    // array: 現在処理してる配列
});
````
2つ目の引数`index`を利用すれば、偶数の配列番号の値だけ2倍にする等ができる。

````JavaScript
let array = [1,2,3,4];

array.map(function(value, index, array) {
    if(index % 2 === 0 ) {
        return value * 2;
    } else {
        return value;
    }
});
````
3つ目の引数`array`を利用すれば、元の配列データを操作（変更）することができる。
例えば、元の配列を2倍にしたい場合↓。

````JavaScript
let base_array = [1,2,3,4];

base_array.map(function(value, index, array) {
    // arrayには現在処理している配列が格納されているので、
    // array = base_array　になる。
    array[index] = value * 2;
});
// base_array = [2,4,6,8];
````
`index`と`array`を利用して、元の配列データ（base_array）にアクセスしている。
[React]オブジェクトをmapで展開する方法

## はじめに
本記事はオブジェクトでmapを展開する方法について解説する記事です。
筆者はReactについて現在勉強中ですが分かりにくいなどあればメッセージをくださると幸いです。


## やり方
オブジェクトのkeysとvaluesの二通りで解説します ※以下例

```
const x = [1 : "abc"]  // [keys : values]
```


###1.keysを出力する場合
keysを展開する場合は`Object.keys(オブジェクト名).map`で行うことができます

```
export function App() {
  const names = {"太郎": [], "次郎" : [] ,"三郎":[]}

  return (
    <>
      <select>
         <option value='' selected >選択してください</option>
         {Object.keys(names).map(name => {
            return (
               <option value={name} id={name}>{name}</option>
            );
         })}
      </select>
    </>
  );
}
```

###2.valuesを出力する場合
valuesを展開する場合は`Object.values(オブジェクト名).map`で行うことができます

```
export function App() {
  const names = {1 : "太郎",2 : "次郎", 3 : "三郎"}

  return (
    <>
      <select>
         <option value='' selected >選択してください</option>
         {Object.values(names).map(name => {
            return (
               <option value={name} id={name}>{name}</option>
            );
         })}
      </select>
    </>
  );
}
```
pdftotext コマンド＋ファイル名表示（シェルスクリプト ）

こんにちは
```pdftotext```コマンドを```find```と組み合わせて使うことにし、シェルスクリプトに仕立てました。ファイル名が行頭に表示されるようにしました。

```console
$ find . -name "*.pdf" -print0 | xargs -0 ./pdftotext.sh
./1.pdf: ...
./1.pdf: ...
./2.pdf: ...
 :
 :
```

```pdftotext.sh
#!/bin/sh
options=""
while [ $# -gt 0 ]; do
  case "$1" in
    -*)       options="$options $1"; shift ;;
    *)        break ;;
  esac
done

for file in "$@"; do
  [ "${file##*.}" != "pdf" ] && continue
  pdftotext $options "$file" - | while read -r line; do printf '%s\n' "$file: $line"; done
done
exit
```
【Linux】/etc/group とは？初心者が簡単にまとめてみた！

# /etc/group とは？
`/etc/group`はグループの設定が保存されているファイルです！

グループっていうのは、ユーザーがまとまっているやつですよね。
（学校でいうクラスとか部活とか？会社でいう部署みたいなものですかね？）

`/etc/group`ファイルの中身をもう少し詳しく見ていきましょう！

# 何が書いてあるの？
`cat`コマンドを使用してファイルの中身を見てみます。

```
[root@localhost ~]# cat /etc/group 
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
　：
```
こんな感じにたくさん表示されます！
（本当は何十行も表示されるのですが割愛しますね。気になる方はコマンドを実行してみてください☆）

1行に1グループの情報が書いてあります。
1行目に`root`が表示されているのでその行を見ていきましょう。

# どうやって読むの？

`root:x:0:`が書いてあると分かったところでどういう意味か分からないですよね。暗号みたい。
これには書式の決まりがあります！

`:`は区切りのマークです！
なので、`root:x:0:`には以下のように4つの情報が書かれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637094/6816c996-6dda-3da1-f97c-d75a324fb36a.png)
左から順番に見てみましょう。

まず1つ目は「グループ名」です。
つまり`root`という名前のグループということですね！

2つ目は「グループパスワード」です。
グループメンバー用のパスワードが入ります。ただ！！`x`はパスワードではない。ということに気をつけてくださいね。

ここに実際のパスワードが表示されてしまったら、
そのグループに所属していないユーザもパスワードを知ることができちゃいますよね。

今は「シャドウパスワード」というものが使われているから`x`が入るらしいです。
（へ～そうなんだ～くらいで流しておきましょう）

次！3つ目は「GID（グループID）」です。
グループを識別するための数字が入ります。`root`グループのGIDは`0`ということですね！

最後！4つ目は「グループメンバー」です。
`root`グループをサブグループにしているユーザーのユーザー名が入ります。
複数のユーザが所属している場合は「,」で区切って並べます。

`root`グループをサブグループにしているユーザーはいないみたいですね。

というか、そもそも「サブグループにしている」ってなんですかね。

まあ、ここまでで`/etc/group`についてどういうものなのか、何が書いてあるファイルなのかはなんとなくわかりましたね。

# サブグループ？

ここから少し難しくなります・・・。
余裕があれば読んでみてください☆

まず、ユーザーは複数のグループに所属することができます。

ユーザーにとって基本となる（メインの？）グループを「プライマリーグループ（基本グループ）」といいます。

そして、それ以外に所属しているグループを「サブグループ（参加グループ、セカンダリーグループ）」といいます。
（兼部みたいなことですかね？）

なにが違うの？？っていうと、
例えば、ファイルやディレクトリ（フォルダ）を作成すると、
作成したユーザーが所属しているグループがファイルやディレクトリの所有グループになります。

そのときに所有グループとしてデフォルトで適用されるのがプライマリーグループ（基本グループ）です。

（「所有グループ？？」という方はさらっと流してください！パーミッションについて学ぶと少し分かると思います☆）

# 最初からグループがたくさんあるんだけど・・・？
ユーザーもグループも作成していないのに、最初からグループがたくさんありますよね。

それ、`root`と`lp`以外のグループ（そのグループに所属しているユーザーも）は全て現在のシステムでは実際に必要のない、ほとんど使用されていないグループ（ユーザー）らしいです。

昔に使用されていたのがそのまま残っているみたいですね。
削除する必要がなければ残しておいてもいいだろう。みたいな感じかもしれません。

# 余談
/etc/配下をみていたら`/etc/group-`というファイルがありました。
`/etc/group`ファイルのバックアップらしいです！
他のファイルにも同じようにありそうですね。
# おわりに
最後まで読んでいただきありがとうございます。
拙い文章がだらだらと続いてしまい、読みにくかったと思います。すみません:bow_tone1:
また、間違った説明があればご教授いただけると幸いです。

「なにが分からないのかも分からない、、、」そんな私のような方の参考になれば嬉しいです。

# 参考
【標準のシステムユーザーアカウントの説明および目的】(https://access.redhat.com/ja/solutions/656033)
『LPIC レベル1』
【「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典/etc/group-】(https://wa3.i-3-i.info/word11694.html)
Djangoの設定ファイルでpathlibを使う

## 最初に

Django3.1以降は設定ファイルデフォルトでosモジュールではなくpathlibを使うようになりましたね。
最初はそれでも気にせずosモジュールをインポートして書いてたのですが
素直にpathlibを使えばいいじゃないかと思い試してみました。

## やったこと

### django-environ

今までの書き方

```py:settings.py
env = environ.Env()
env.read_env(os.path.join(BASE_DIR,'.env'))
```

pathlibを使う

```py:settings.py
env = environ.Env()
env.read_env(str(BASE_DIR / '.env'))
```

### static

今までの書き方

```py:settings.py
STATIC_URL = '/static/'

# STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static/')
]
```

pathlibを使う

```py:settings.py
STATIC_URL = '/static/'

# STATIC_ROOT = BASE_DIR / 'static/'

STATICFILES_DIRS = [
    BASE_DIR / 'static/'
]
```

## 最後に

好みはあるかもしれませんが
なんとなくスッキリしたような感じがしませんか？
個人で開発するときは積極的に使っていこうと思います！
ほぼ一夜漬けでAZ104を受験して合格した備忘録【Azure Administrator Associate】

#前提
さすがにゼロから一夜漬けではないので以下に前提を書いておきます。

1. 一年ほど前にAWS認定 ソリューションアーキテクト アソシエイトを取得していた。
2. 一年ほどAWS環境の構築案件を経験していた。
3. 会社からの無料チケットで受験したので不合格だったときのリスクが少なかった。

特に3.がデカいのでご注意ください。一夜漬けでもいけたよ！というより、3.のおかげで一夜漬けでも受験することができ、ギリギリ合格したという話です。(合格ライン700点に対して707点でした)
とはいえ、1. 2.のような経験がある方であれば比較的簡単にAzureのアソシエイトレベルの資格も取れるという一つに指標になると思ったので載せておきます。

#勉強方法

1. 参考書 合格対策 Microsoft認定 AZ-900:Microsoft Azure Fundamentalsテキスト&問題集
2. Microsoft Learn 試験 AZ-104: Microsoft Azure Administrator
3. Udemy(問題集) AZ-104 - Microsoft Azure Administrator Practice Tests 2021

##参考書について
https://www.amazon.co.jp/%E5%90%88%E6%A0%BC%E5%AF%BE%E7%AD%96-Microsoft%E8%AA%8D%E5%AE%9A-AZ-900-Microsoft-Fundamentals%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88/dp/4865942319

まずはこちらをサラっと一読しました。図や画像が多めでAzure未経験でもわかりやすかったです。章末問題や問題集も付いていましたが、あくまでAZ900用ということで読み飛ばしました。Microsoft LearnにもAZ900のラーニングパスがありますが、日本語があまりよくないと感じたのでこちらをオススメします。

##Microsoft Learnについて
https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-104

AZ104の参考書はよさそうなのがなかったので、Learnを利用しました。何よりも無料というところが嬉しいです。進め方としては、サラっと読んだ後に知識チェックを見て、答えとなる部分を探しながら解いていくといった具合です。ハンズオンも豊富ですが、時間がなかったのですべて飛ばしました。
今回は資格取得が目的だったのでハンズオンを飛ばしてしまいましたが、案件で使用する際には絶対にやっておきたい内容ですね。

##Udemy(問題集)について
https://www.udemy.com/course/microsoft-azure-administrator-practice-tests/

最後に実際の問題を解いて知識を確認します。ここが一番大事なのですが、リーズナブルな日本語の問題集というのはあまり多くないようです。
こちらは英語の問題集ですが、Google Chromeの翻訳機能を使えば読めなくはないです。ただし、画像が入っているためそこは翻訳されないです。
そんな感じで読み進めづらいですが、問題内容については実際の試験にもほぼ同じ問題がかなり出たのでオススメです。Udemyはセール時の割引がデカいのでそのときに買いましょう。(1,500円で購入しました。)私は時間の都合で一回分しか解けなかったのですが、全部解けば安泰だと思います。

#試験内容
* 64問 120分
* 一問一答→同じシナリオ問題(10問ないくらい。うろ覚え)→ケーススタディ(4問)

問題数や試験時間、問題形式については改定もありそうなので最新の情報をチェックしましょう。案内メールには150分と記載されていましたが実際にタイマーに表示されていた時間は2時間でした。見直し含めて十分な時間がありますが一応注意しておきたいですね。

問題は3つのセクションにわかれています。問題形式については紹介したUdemyに同じものがあるので慣れることができます。
注意したいのは、同じシナリオ問題については前の設問に戻ることができず、次の設問を見て前の設問に解答することができないことです。一問一答、ケーススタディについては前の設問に戻ることができるので、セクションの最後で見直しを行いましょう。

#所感・まとめ
以上を試験日の前々日の夜くらいからのろのろやり始めてギリギリ合格できました。
やはりAWSと似ている部分が多かったので、理解のスピードは速かったと思いますし、もし知らない・忘れてしまってもAWSに準拠して考えれば7, 8割くらいは当たっていた感じがします。
逆にAWSと違う部分はよく頭に入れておく必要があります。特にID・ガバナンス、監視・バックアップの分野は独特なところが多いように感じたので、重点的に学習すると効率が良いと思います。
【初学者による】PHP入門(Rubyとの比較)

Ruby触ってみたけどPHPも触ってみたい浮気者


# PHPの利点と欠点（Rubyとの比較）
* フレームワークがいっぱいあるよ
  * Laravel/CakePHP/Symfony/CodeIgniter/ZendFramework/Phalcon…　(RubyはRails一択といっていいくらいだが…)
* HTMLと混合して記述できる（ただし分離しておく方が良い）
* WordPressのカスタマイズが出来る（WordPressもPHPで構築されているため）
* アプリは作りやすいが、それ以外の開発は苦手...(Webアプリに特化しているため)


# 出力
変数に付ける **<font color="red">$</font>** と、末尾につける **<font color="red">;</font>** に注意！

```php:PHP
echo 1 + 1   // 出力 2
echo "こんちは";   // 出力 こんちは

$name = "Aさん";  //変数
echo $name;
```

```ruby:Ruby
puts 1 + 1   # 出力 2
puts "こんちは"  # 出力 こんちは

name = "Aさん"
puts name
```

# 文字列の連結
**<font color="red">. </font>**  で連結できる

```php:PHP
$x = "おもち";
$x = $x."もちもち";
$x .= "もちもち";  // 省略形
echo $x;  # 出力 おもちもちもち
```

```ruby:Ruby
x = 1
x = x + 1
x += 1  #省略形
# 出力 2
```

# if文
```php:PHP
$x = 1;
if ($x > 0){
  echo "変数xは0より大きい";
}    
// if ($x > 0)がtrueになるためechoされる
    
```

```ruby:Ruby
x = 1
if x > 0
  puts "変数xは0より大きい"
end
# if x > 0 がtrueになるためputsされる
```

続く
Ubuntu 20.04のdocker build時にタイムゾーン選択を求められた時の対処メモ

[別記事](https://qiita.com/mochi_yu2/items/e2480ae3b2a6db9d7a98#dockerubuntu-2004%E3%81%ABselenium%E3%81%AE%E7%92%B0%E5%A2%83%E3%82%92%E6%A7%8B%E7%AF%89)でUbuntu 20.04をベースイメージとして、docker buildを行った時に、以下のようなメッセージが出て、数値を入力しても先に進まなくなりハマった際の対処メモです。

```console
・・・(省略)・・・
Configuring tzdata
------------------

Please select the geographic area in which you live. Subsequent configuration
questions will narrow this down by presenting a list of cities, representing
the time zones in which they are located.

  1. Africa        6. Asia            11. System V timezones
  2. America       7. Atlantic Ocean  12. US
  3. Antarctica    8. Europe          13. None of the above
  4. Australia     9. Indian Ocean
  5. Arctic Ocean  10. Pacific Ocean
Geographic area:
```

対処としては、以下のように`RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime`という行を追加しました。

```Dockerfile:Dockerfile
FROM ubuntu:20.04

# ★★★ ↓の行を追加 ★★★
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RUN apt-get update \
 && apt-get install -y git tzdata

RUN date
```

- 何が原因で、上記でどうして動いたかという所までは追求していません。
- とりあえず、タイムゾーン関連に見えたので、タイムゾーンを設定しています。
  - 参考：[【設定確認から変更方法まで】Linuxでのタイムゾーンの扱い方](https://eng-entrance.com/linux-time-timezone)
  - 参考：[[Linux]タイムゾーン(Timezone)をUTCから日本標準時(JST)に変更する](https://www.t3a.jp/blog/infrastructure/set-timezone/#outline__2_3)
- Web上で少し調べていくと、いくつか対処方法が書かれた記事が見つかりました。Ubuntuのバージョンによっても挙動・対処が異なるかもしれません。 

## 参考
https://eng-entrance.com/linux-time-timezone

https://zenn.dev/kumamoto/articles/51bf0893620f0c

https://qiita.com/yagince/items/deba267f789604643bab

https://qiita.com/rururu_kenken/items/972314402d588e073d40

https://github.com/moby/moby/issues/12084

https://yoru9zine.hatenablog.com/entry/2017/01/12/224637

https://www.t3a.jp/blog/infrastructure/set-timezone/#outline__2_3
GolangでMysqlに接続してみた！

# はじめに
ある程度C言語の基礎は身についてると自負しているので、いきなりDB接続してみた。
昔C#書いてたので割とすんなり理解できたと思う。
しかし、タイムスタンプの表示方法だけつまづいた。
やっぱタイム型は苦手だ。
# 実践！
## MySQL
### サンプルデータ作成
#### データベース作成
データベース名は任意で頼む！

```mysql
CREATE DATABASE test_db;
```
#### テーブル作成
id(主キー)、名前、作成日時、更新日時

```mysql
create table users (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(10),
created_at datetime  default current_timestamp,
updated_at timestamp default current_timestamp on update current_timestamp
);
```
#### サンプルデータ保存
```mysql
INSERT INTO users (name) VALUES ("名前1"),("名前2"),("名前3");
```
## Go!
### go-sql-driverインストール
```sh
$ go get -u github.com/go-sql-driver/mysql
```
https://github.com/go-sql-driver/mysql

基本的に公式のコードそのままコピペで接続できる！

### Goファイル編集
```dbconnect.go
package main

import (
	"database/sql"
	"fmt"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

type User struct {
	ID         int
	Name       string
	Created_at time.Time
	Updated_at time.Time
}

func main() {
	db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/go_test?parseTime=true&loc=Asia%2FTokyo")
	panic_err(err)
	defer db.Close()

	rows, err := db.Query("SELECT * FROM users")
	panic_err(err)
	defer rows.Close()

	for rows.Next() {
		var user User
		err := rows.Scan(&user.ID, &user.Name, &user.Created_at, &user.Updated_at)
		panic_err(err)
		fmt.Println(user.ID, user.Name, user.Created_at, user.Updated_at)
	}

	err = rows.Err()
	panic_err(err)
}

func panic_err(err error) {
	if err != nil {
		panic(err.Error())
	}
}
```
エラーチェックの部分何回も同じこと書くのアレだったのでエラーチェック用の関数作ってます。
みんなちゃんと動いたかな？
#### 解説
##### サーバー接続部分

```go
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/go_test?parseTime=true&loc=Asia%2FTokyo")
db, err := sql.Open("mysql", "ユーザー名:パスワード@tcp(ホスト:ポート)/データベース名?parseTime=true&loc=Asia%2FTokyo")
// ?parseTime=trueでタイムスタンプをtime型に変換してくれている。
// &loc=Asia%2FTokyoタイムゾーンを東京で表示。
```
##### defer
これ便利です！
呼び出し元の関数が終わるとき or returnされるときにdeferで書いた処理が走るみたいです。
今回は２箇所で使っています。

```go
defer db.Close()
defer rows.Close()
```
ただし、`defer db.Close()`を通った時点で、変数(今回は`db`)の値は確定します。
たとえその後に、`db`の値が変わったとしても`defer db.Close()`を通った時点の値が適用されます。
逆に`defer db.Close()`を通る前に`db`の値が変わるとそれが適用されます。
なので、処理の内容は`defer db.Close()`を通った時に確定し、実際に処理されるのは、呼び出し元の関数が終わるとき or returnされるときです。
今回で言うと最後の`panic_err(err)`の関数が終わった後に、発動します。
複数`defer`を使ったときの処理される順番ですが、先に通る`defer db.Close()`が一番最後に処理され、`defer rows.Close()`がその一つ前で処理されます。

```go
func main() {
  //中略
  panic_err(err)
  rows.Close()
  db.Close()
}
```
deferで上の方に記述していてもこういう順番で処理されている。
##### select結果表示

```
for rows.Next() {
    // 今回は上の方でuserの中身を定義しているが、ここでゴリゴリ書くこともできる。
    var user User
    // var id int
    // var Name string
    // var Created_at time.Time
    // var Updated_at time.Timeみたいに。でもブサイクでしょ？

    err := rows.Scan(&user.ID, &user.Name, &user.Created_at, &user.Updated_at)
    if err != nil {
        panic(err.Error())
    }
    fmt.Println(user.ID, user.Name, user.Created_at, user.Updated_at)
}
```
rows.Scan()内、最初idとnameだけ表示させようとしてidとnameしか記述していなかったらエラーになってしまった。
必ずselectしたすべてのカラムを読み込まないといけないらしい。
# まとめ
今回はgo-sql-driverでMySQLに接続してみました。
次はGormで接続してみようかな。

https://gorm.io/

Goのフレームワークといえばこれっていうやつあんのかな〜。
現場でどんな環境でGo言語開発してんのか気になる〜。
残プロ　第-12回　~第6回から第11回のまとめ~

# 今週のまとめ

第-6回(月)  pandasを利用した.csvの読込，データを1行ずつ処理
第-7回(火)  正規表現モジュールreを使って文字列を分割
第-8回(水)  datetime,calendarモジュールを使用，文字列をdateオブジェクトに変換
第-9回(木)  第6回から第8回のプログラムを組み込み
第-10回(金) 文字列に絵文字を含める，スクレイピングでデータ取得，matplotlibで画像化
第-11回(土) RaspberryPiのcronを利用し.pythonを定期実行

# 今週の学び

## 第-6回 pandas

- read_csv, to_csvは引数encodingが指定できる．指定しない場合，文字化けすることがある．
- to_csvは引数indexで保存の際にインデックスを含めるか指定できる．
- 空白はfloat型のnanとして読み込まれる．いまだ上手く処理する方法を発見できず．

~~~ python:
import pandas as pd

def csvEdit(path_csv):
    csv = pd.read_csv(path_csv)
    for row in csv.itertuples():
        csv.at[row[0], 'hoge'] = huga
    csv.to_csv(path_csv)
~~~


## 第-7回 re

- splitメソッドの返り値はリスト
- 簡単な処理であっても正規表現をつかった方が後々便利

~~~ python:
import re

def separateStr(string):
    separated_comma = re.split(',', string)
    separated_upper = []
    for s in separated_comma:
        separated_upper.append(re.findall('[A-Z][a-z]+', s))
    return separated_upper
~~~


## 第-8回 datetime, calendar

- 次の第何何曜日の計算には，今月の指定曜日を計算したのち今日と比較．過ぎていた場合は翌月を計算する


## 第-9回

組み込みのみのため割愛


## 第-10回　beautifulsoup4, matplotlib

- スクレイピングは意外と簡単
- マトラボで綺麗な表を作るのは意外と大変

## 第-11回　cron

- cronはホームディレクトリで実行されるので，指定には絶対パスを使用する．
- プログラム内でファイルを扱う場合も，同ディレクトリまたは絶対パスを使用しないと上手く実行できない．


# 今週の総括，来週の予定

今週はなかなか時間が割けず，中途半端な記事が多くなってしまいました．推敲がほとんどできていないのは惜しいなぁと思います(余裕があるときに少しずつですが修正中です)．
予定していたタスク管理(csv編集プログラム)も未完の部分があるので，来週はそこを終わらせたいと思います．また，RaspberryPiの外部ネットワーク接続を試します．
form_withで使用できるhtmlタグ

```rb:form_forの書き方
<%= form_with model: @user do |f| %>
  <%= f.text_field :name %>
  <%= f.submit %>
<% end %>
```

|メソッド名|機能|
|--|--|
|f.search_field|検索用ボックス|
|f.label|ラベルタグをを生成<label for="post_cost">Total cost</label>|
|f.text_field|１行のテキストボックス|
|f.text_area|複数行のテキストボックス|
|f.email_field|メールアドレス用ボックス|
|f.range_field|範囲選択バー|
|f.number_field|数値選択|
|f.select|選択ボックス|
|f.date_field|日付ボックス|
|f.datetime_field|日付時刻ボックス|
|f.datetime_local_field|日付時刻ボックス(ローカル)|
|f.month_field|月ボックス|
|f.time_field|時刻ボックス|
|f.week_field|週ボックス|
|f.telephone_field|電話番号用ボックス|
|f.file_field|ファイル選択用ボックス|
|f.password_field|パスワード用ボックス|
|f.hidden_field|隠しフィールド|
|f.check_box|チェックボックス|
|f.radio_button|ラジオボタン|
|f.url_field|URL用ボックス|
|f.color_field|色選択ボックス|
|f.submit|提出用ボタン|

Pikawaka
>https://pikawaka.com/rails/form_with
Redshiftのvarcharについて

## Redshiftのvarchar()でハマった
Redshiftは、PostgreSQLと互換性があるが、文字型で異なる。

* MySQL : 文字数
* PostgreSQL : 文字数
* Redshift : バイト数


[MySQL :: MySQL 5.6 リファレンスマニュアル :: 11.4.1 CHAR および VARCHAR 型](https://dev.mysql.com/doc/refman/5.6/ja/char.html)
[Redshiftの文字列はバイト数換算 - 山ｐの楽しいお勉強生活]
(https://yamap55.hatenablog.com/entry/2017/07/19/094530)
[文字型 - Amazon Redshift](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_Character_types.html)
M1macにhomebrew,pyenvを使ってPythonをインストールしようとしたらエラーがでた

#環境
M1 mac book pro
macOS Big Sur 11.4
hyper 3.0.2
hombrew 3.1.12
pyenv 2.0.1


#状況
フロントエンド中心に勉強していたのですが、WEBエンジニアに興味を持ちサーバーサイドの勉強をはじめました。インターンシップに応募するにあたりnode.jsやGo言語を勉強しようと思ったのですがコーディングテストではCかPythonがいいということを小耳に挟んだためコーディングテストのためだけにPythonの開発環境を整えることにしました。

Homebrewは元から入っておりpyenvもインストールしたのですが肝心のPythonがインストールできず、という状況です。

#エラー文
````
pyenv install 3.9.5
````
とコマンド打ったところ

`WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?`
`ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?`
と言うエラー文が出てきました。

#解決手順
###1
エラー文の下に[ここ](https://github.com/pyenv/pyenv/wiki/Common-build-problems)を参照してと書いてあるので見ます。
`Please consult to the Wiki page to fix the problem.https://github.com/pyenv/pyenv/wiki/Common-build-problems`

###2
「The Python readline」についての記述が見つかりません。なので、一番上の「トラブルシューティングを行う前にPythonのバイナリ依存関係とビルドツールをインストールしてください。」という指示に従いましょう。
↓このリンクに飛びます
https://github.com/pyenv/pyenv/wiki#suggested-build-environment 

###3
Xcode Command Line ToolsとHomebrewをインストールしてから↓を打てって書いてあります。

````
brew install openssl readline sqlite3 xz zlib
````
Homebrewの確認はpyenvのインストールにも使ってるので今回は飛ばします。
Xcode command Line Toolsは入れてるか怪しかったので確認します。

````
xcode-select --install
````
と打つと「すでにインストールされてますよ」とでてきました。(そもそもHomebrewを入れるのにコマンドラインツールが必要だったみたいです)
`xcode-select: error: command line tools are already installed, use "Software Update" to install updates`

###4
HomebrewとXcode Command Line Toolsがインストールされてることが確認できたら[先程のページ](https://github.com/pyenv/pyenv/wiki#suggested-build-environment)に戻り下記コマンドを打つ段階から始めます。

````
brew install openssl readline sqlite3 xz zlib
````
コマンドを打つと
`Warning: openssl@1.1 1.1.1k is already installed and up-to-date.`
インストールはされてるっぽいですが下にエラー文が出てきました。
`Error: Cannot install under Rosetta 2 in ARM default prefix (/opt/homebrew)!
To rerun under ARM use:arch -arm64 brew install ...`

どうやらARMの環境下では`arch -arm64`を先頭につけてコマンドを打たなきゃいけないようです。
なので`arch -arm64 brew install openssl readline sqlite3 xz zlib`と打ちましょう。


###5
`pyenv install 3.9.5`と打っても同じエラー文が出てきてしまったので全てに`arch -arm64`をつけました。

````
arch -arm64 brew install pyenv
````

````
arch -arm64 pyenv install 3.9.5
````
これでインストールできると思います。


#確認
````
pyenv global 3.9.5
````
と打ってから

````
python versions
````
と打つと`* 3.9.5 (~`と出てきました。”が”

````
Python versions
````
と打っても`Python 2.7.16`とmacに元から入ってるバージョンが出てきてしまいます......
とは言え、vscodeでPythonファイルを「ターミナルで実行」すると`opt/homebrew/opt/python@3.9/bin/python3.9`と出てきているのでPython 3.9.*が使えてるみたいです。
Rails6を利用した地図WEBアプリ学習_1


## 内容

RailsとGoogleMapsAPIを利用したサイトを通じて
地図サービスの作成手順を書いていきます。

## 表示内容

最終的な表示イメージ

![120203635-e3d67b80-c262-11eb-8bf5-e98db4e1b260.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17349/419e960d-8c48-7130-ffb8-1ccc7a2546ae.png)


## 手順

サンプルデータとして流山のAEDの場所を表すようにしています。

手順は [wiki](https://github.com/nekakoshi/lessons/wiki/SimpleMap) に記載しています。


現在完成までのソースコードはこちらです。
必要であれば参考にご利用ください。

https://github.com/nekakoshi/lessons/tree/main/simple-map

---

【新卒】→ SIer入社、ドキュメントの日々
【転職】→ IT上場企業、主にインフラ担当
【転職】→ ベンチャーIT企業、主にインフラ担当
【現在】→ 起業

IT業界限定で全ての方に向けて、
今だけ限定で無料キャリア相談実施中。
オンライン面談予約は http://nekakoshi.youcanbook.me
Macの便利すぎるショートカットキー

#便利すぎるMacのショートカットキーを使いこなそう

##よく使うショートカットキー

command + c  コピー

command + x  切り取り

command + v  ペースト

command + z  １つ前の操作に戻る

command + a  全てを選択

command + s  保存する

command + f  検索画面を開く

command + t  新しいタブを開く

上記のショートカットキーはよく使われるのではないでしょうか。
私自身も頻繁に使用しています。

これら以外に


command + q  アプリケーションを閉じる

command + n  新規作成をする、新しいウィンドウを開く

command + ,  環境設定を開く

command + [  戻る

command + ]  進む

などがありますね。

ショートカットキーを使いこなすと作業が効率よく進みますね。
是非、覚えて活用しましょう！！
f.select 男女を選択させる


```rb
  <div class="form-group">
    <%= f.label :sex, '性別' %>
    <%= f.select :sex, {'男性': 1, '女性': 2}, { include_blank: '選択してください'}, { class: 'form-control' , required: true } %>
  </div>
```


>https://techacademy.jp/magazine/37096
laravel シーダの実行時の注意点 個人メモ

# 目的

- laravelのシーダーを実行した際にちょっと戸惑ったのでメモ的に記載する。

# コマンドで指定したシーダーだけ実行される

- シーディング時には下記コマンドを実行する。

    ```terminal
    $ php artisan db:seed シーダークラス名
    ```

- 当たり前だがコマンドで指定したシーダークラス名のもののみ反映される。
- `アプリ名ディレクトリ/database/seeds/`直下のシーダークラスをシーディングしたい場合、その個数分だけシーディングする必要がある。
Rasberry PiとArduinoのI2C接続（IoTに必須なアナログ電圧の測定）


#はじめに
センサの値を取得するために必須とされるアナログ電圧の測定をRasberry Piを使って行います。これができるようになると、RasberryPiがさまざまなアナログ系のセンサ（温度センサや超音波による距離センサなど）の値を認識できるようになるので、飛躍的に活用の幅がひろがります。ただ、そのためのいくつか方法があります。専用のIC（ADコンバータ、MCP3208やMCP3008）を使う手法があり、おそらくそれが一番手っ取り早いと思われますが、今後の拡張性を考えてArduino UNO（これも互換ボードなら、1000円以下で入手できることもあるようです）を使う方法もポピュラーなようです。すでにたくさんの立派な解説（一番下の参考に記載）が出ていて、あえて記事にする必要もないかもしれませんが、実際にやってみたので、ざっとやることを理解したい方向けに、簡単にやったことを紹介します。これをみていただければ、そこまで大変な作業でないことはご理解いただけるのではないかと思います。なお、以下の内容と実践は自己責任でお願いいたします。

#Arduinoの事前準備
まず、Arduino側でアナログ電圧の値の読み取りができるようにセッティングをします。今回は、A0とGND（接地）間の電圧値を取得することにしたいと思います。ラズパイ側からデータが要求された時に、analogRead(A0)で電圧値を取り出して、Wire.writeでI2C通信をさせてRasberry Piの方に読み取ったデータを送るようにします。
以下のプログラムをArduino IDEで作成し、コンパイルおよびボードへの書き込みを行います。

```c
#include <Wire.h> 
 
void setup() { 
    // I2Cバスにアドレス８を使うということで、設定します。 
    Wire.begin(0x8); 
 
    // データが要求された時にsendReading関数が呼ばれるように設定します。 
    Wire.onRequest(sendReading); 
} 
 
// A0ピンの値を読み、４分の１にしてI2Cバスに書き込みます 
void sendReading() { 
    int reading = analogRead(A0); 
    Wire.write(reading/4); 
} 
 
void loop() { 
    delay(100); 
}
```

#ラズパイ・Arduino・電子回路間の接続
次に、ラズパイ、ArduinoUNO,そして電子回路の接続を行います。ボードのピンのアサインメントをよく確認しながら、以下の通り、結線をしてください。

![kairo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280313/4d73f9fd-3469-c0af-1f1e-1a77151918f8.png)

#Rasberry Piの設定（OSの設定）
デフォルトでは、ラズパイはI2C通信ができるようになっていないため、設定をする必要があります。Raspberry Pi OSを立ち上げて、スタートメニューから、設定 -> Raspberry Piの設定　を選択します。そうすると、設定画面が出てきますので、この画面の項目のI2Cのところを「有効」にします。

#Rasberry PiでのPythonコード（ターミナル操作）
いよいよ、Rasberry Pi側からI2C通信を使って電圧を取得する命令を出していきます。ターミナルを立ち上げて、python3を起動し、以下のコードを入力してみてください。

```python
% python3

>> from smbus import SMBus
>> arduino = 0x8
>> i2cbus = SMBus(1)
>> i2cbus.read_byte(arduino)
```

そうすれば、電圧相応の値が出てくると思います。可変抵抗でつまみを回して抵抗値をかえてやると、値の変化もみられると思います。
①A0-GND間の実際の電圧値と②ここで表示される値の関係は、比例の関係にあるので、オシロスコープなどでその係数を出せば、抵抗にかかっている電圧値をラズパイだけで認識できるようになる、というわけです。


#接続イメージ
あまり綺麗なものではありませんが、一応見た目はこんな感じということで参考としてイメージをのせておきます。

![IMG_1075.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280313/a4bfb989-933e-e2b5-c0df-af243c25f27a.jpeg)



#参考情報

https://deviceplus.jp/hobby/raspberry-pi-and-arduino-connect-with-i2c-01/

https://deviceplus.jp/hobby/raspberry-pi-and-arduino-connect-with-i2c-02/

https://sites.google.com/site/memorandumjavaandalgorithm/raspberry-pi-jiang-zuo-arduino-i2c-jie-xu

https://www.indoorcorgielec.com/resources/raspberry-pi/raspberry-pi-i2c/

https://github.com/johnbryanmoore/VL53L0X_rasp_python/issues/13
ABC205_C POW

https://atcoder.jp/contests/abc205/tasks/abc205_c

32bit整数 A, B, Cが与えられ、Cは正。A^CとB^Cの大小を答える。
直接計算はオーバーフローしてできない。流石の`num::bigint`も${10^9}^{10^9}$は無理だろう。30Gbit = 4GByteくらい空間消費量がある。
場合分けすればできるが、Aの符号、Bの符号、AとBの絶対値の大小、Cの偶奇が絡む。なんとかならないか。

数の大小を人間が比較するとき、まず確認するのは符号で、その後が絶対値。
その線で考える。

A^CとB^Cの偶奇はA, Bの符号とCの偶奇で決まる。

+ Cが奇数のときはA^C, B^Cの符号はA, Bと等しい
+ Cが偶数のときはA^C, B^Cも正(またはゼロ)になる

絶対値については、A, Bの絶対値の大小とA^C, B^Cの絶対値の大小は同じ。

A^C, B^Cを計算するのではなく、A^Cの符号、B^Cの符号、A^CとB^Cの絶対値の大小関係を保持する範囲で別のより簡単な計算に置き換える。

---

+ Cが偶数のときはA, Bを絶対値に直す。
+ Cが奇数のときはそのまま
+ そしてA, Bを比較。

---

これで解ける。

https://atcoder.jp/contests/abc205/submissions/23390766

64bitで提出したが、32bitでよかった。

```rust:abc205_c.rs
use proconio:input;

fn main() {
    input! { mut a: i32, mut b: i32, c: i32, };
    if c % 2 == 0 {
        a = a.abs();
        b = b.abs();
    }
    if a < b {
        println!("<");
    } else if a > b {
        println!(">");
    } else {
        println!("=");
    }
}
```

ご清聴ありがとうございました。
Windowsタスクスケジューラの多重起動

## はじめに
普段からWindowsは使っているのだが、タスクスケジューラについては機能は知っているものの、あまり自分で設定したことがなく、多重起動の挙動など色々と設定しながら試してみたので、その時の内容をメモする。

## 実施環境
　Windows 10 pro

## メモ内容
Windowsタスクスケジューラの設定の際、多重起動と同時起動の動きについて、設定をいじりながら実際の挙動をいくつか確認してみた。まずは、多重起動と同時起動の定義から。

**■多重起動**
　１つのタスクにおいて、前回のタスクが終了する前に次のタスクが呼び出される場合のこと。

**■同時起動**
　１つのタスクが実行中に、別のタスクが実行されること。


### 多重起動の設定と挙動について
まず、実行中のタスクが完了していない場合、次のタスクをどの様に起動させるか設定する箇所だが、該当タスクを右クリックしてプロパティを開き、設定タブのところで決める。
![Qiita-No043_img01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/e0cc8f49-4565-056e-ccc4-354cbd94d867.jpeg)

上記赤枠の設定候補は、全部で４つ。

 - 新しいインスタンスを開始しない
 - 新しいインスタンスを並列で実行
 - 新しいインスタンスをキューに追加
 - 既存のインスタンスの停止

上記の設定パターンの際に、どの様な動きとなるのか実際に検証してみたので、その時の結果を以下に貼り付け。

![Qiita-No043_img02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/5afe9209-ac2c-199b-b793-18d1eaa4caba.jpeg)


### 同時起動について

基本的に別のタスクとは独立して動くことが確認できたので、後はそれぞれのタスクで上記の様な起動ルールで動くだけなのだが、一応いくつかのケースでテストしてみたので、その時の結果を貼る。

![Qiita-No043_img03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/edac0a35-03fa-4655-9ca4-bd137dbf285d.jpeg)
「ビブルカード」のような親子のためのツールを作るべく、まずは位置情報アプリのプロトタイプを作成

##「ビブルカード」のような何かを作ってみたい・・・
わが家は共働きで、保育園に通う息子（5歳）がいます。
日中はそれぞれ離れた場所で過ごしており、親子がコミュニケーションを取れる手段がないのが悩みです。

もし現実世界に、ONE PIECEの「**ビブルカード**」のような夢のツールがあったなら・・・と、<br>初心者ながらに妄想＆挑戦中です。（あらゆる可能性を探るため、プロトタイプ中）
※「ビブルカード」やプロダクトの詳細は、以下リンクに記載しています。ぜひご覧ください！

https://note.com/kokano23/n/n0b44d8854e0d


##今回プロトタイプしたもの　～位置情報を取得するWebアプリ～
プロトタイプとして、先日学習した「Web Sensor API」を使って何かできないか？と考えました。
全体イメージとアプリは、以下のとおりです。（今回は、**一部分をプロトタイプ**）

###【プロトタイプ部分】
Webアプリケーションは、NetlifyにデプロイおよびPWA化しています。（リンクは、以下のとおり。）
※自端末（スマホ）と保育園の位置情報を取得するアプリ。（保育園の位置は、公開用のダミーデータ）


https://priceless-lichterman-edbb80.netlify.app

###【全体イメージ】
全体イメージは、以下の図のとおりです。

- 親が持つスマホで位置情報（現在地・保育園の位置）を取得。　**←今回は、こちらをプロトタイプ**
- お互いの距離が近づくと、子どもが持つプロダクトに合図が送られる。（カードやキーホルダー等を想定）


![宿題６－２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1280625/59e42934-3926-070c-49b8-17440a753887.jpeg)




##作成方法・ソースコード

位置情報の取得には、「Geolocation API」を使用しています。構文などは、以下の記事にまとめています。

https://qiita.com/kokano23/items/826b4098243f7d783c38

<details><summary>ソースコードは、セクションのとおりです。（CodePen)</summary><div>
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="kokano23" data-slug-hash="yLMQONP" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="位置情報(Webアプリ）">
  <span>See the Pen <a href="https://codepen.io/kokano23/pen/yLMQONP">
  位置情報(Webアプリ）</a> by kokano23 (<a href="https://codepen.io/kokano23">@kokano23</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</div></details>




##実際の操作で気づいたこと
クラウドファンディングに挑戦したいと思っているため、ユーザーに近い**実姉（保育園児の母）**と、**夫**の2名にWebアプリを使ってもらいました。（以下、フィードバックを記載）
事前に期待していた反応は、以下のとおりです。

- 位置情報アプリとしての精度については、何かしら意見をもらえるのでは？（しっかり取れた、ずれているなど）
- デザインや操作性は、アプリを使い慣れているユーザーとして、他のアプリと比較した率直な意見が聞けそう
- ワーママ（パパ）ならではの忙しい生活スタイルをベースとした意見が聞けそう
 
実際のコメントは、以下のとおりでした。
マイナス部分はいずれも同感で、"今度改善したいが、実現できなかったポイント"を的確に指摘してもらいました。<br>

|分類|内容|
|:---|:---|
|機能面|今回は、全体像の一部ということもあり、このアプリだけで何ができるか分からない|
|機能面|アプリの地図は、１つでよいのでは？（自分の位置・保育園の位置がどちらも表示されるように）|
|機能面|位置情報はしっかり取れている。移動した際も、（面倒ではあるが）ボタンを押せばきちんと反映される|
|操作面|アプリの操作説明は、もっと詳しい方がよい（どのボタン押せばよいか迷う）|
|操作面|マップを表示するまでに、2アクションあるのが手間になる|
|デザイン面|雰囲気はイラストもあり、やわらかくてよい|
|デザイン面|文字のサイズが小さい。スマホの画面全体に表示した方がよい|

##今後の改善点
フィードバックも踏まえて改善点が浮かんだので、しっかりと記録しておきます。

- 実現可能性も含めて、全体像をもっと練る。（子どもが持つツールはどんなもの？どうやって連携する？）
- 位置情報に**変化がない場合**、**変化があった場合**のアクションを明確にする。（移動がない時間は、取得不要）
- アプリを起動しなくても、**自動的に位置情報を取得できる仕組み**が必要。（忙しいので、起動やボタンの押下を忘れる）
- 「Firebase」等の他サービスを使って、位置情報を保存し、そこから情報を取得するなども検討。
- **シンプルかつ操作がしやすい設計**にする。（LINEと連携してリッチメニューを使うなど、簡単な操作が重要）
- **１つの地図上**で、①自端末の位置情報、②保育園の位置情報、③距離などの**一元管理**を目指す。

##参考記事

https://developer.mozilla.org/ja/docs/Web/API/Geolocation_API

https://blog.codecamp.jp/javascript-geolocation
コード品質を構成する要素 【凝集性・疎結合】

[レガシーコードからの脱却 - ソフトウェアの寿命を延ばし価値を高める9つのプラクティス](https://www.amazon.co.jp/%E3%83%AC%E3%82%AC%E3%82%B7%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8B%E3%82%89%E3%81%AE%E8%84%B1%E5%8D%B4-%E2%80%95%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E5%AF%BF%E5%91%BD%E3%82%92%E5%BB%B6%E3%81%B0%E3%81%97%E4%BE%A1%E5%80%A4%E3%82%92%E9%AB%98%E3%82%81%E3%82%8B9%E3%81%A4%E3%81%AE%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-David-Scott-Bernstein/dp/4873118867)
という書籍の第9章がソースコードの品質を扱っていました。こういう概念的なものは自分で書き起こしておくと定着度が上がると思うので備忘録としてまとめます。

## コード品質を構成する要素
- [凝集性(Cohesive)](#凝集性(Cohesive))

- [疎結合(Loosely coupled)](疎結合(Loosely coupled))


#凝集性(Cohesive)

まず、高品質のソースコード = 凝集性の高いソースコードです。
凝集性の高いソースコードはクラスやメソッドが1つのものだけを扱います。(単一責任の原則やUNIXの設計思想「1つのことを上手くやる」とも共通していると言えるでしょう。)

なぜ凝集性が高い方が高品質かというと、プログラムを変更する際にどのクラスを変更すればよいか判断しやすい・1つのクラスの変更が他のクラスに悪い影響を与えにくいからです。

クラス内に定義されているメソッドに共通性がほとんどない(例：ユーザにメールを送るメソッドとユーザ登録用メソッドが同一クラスに定義されている)場合や1つのメソッドで様々な処理を行っている場合(例：バリデーションとSQL発行)に凝集性が低下する傾向があります。

また、凝集度の程度は以下のように分類されます。(上に行くほど良い)

- 機能的凝集: 単一のタスクを定義する(例：2つの自然数の和を計算する)

- 逐次的凝集: ある部分の出力が別の部分になるような関数を集めたモジュール(例：全体でファイルを読み込み、処理をするモジュール)

- 通信的凝集： 同じデータを扱う関数をまとめたモジュール(例：ユーザ情報を扱う関数を集めたモジュール)

- 手続き的凝集: ある処理を行うときに実行される関数を集めたモジュール(例：入力値のバリデーションとデータ書きこみ)

- 時間的凝集： プログラムを動かしたときにモジュール内の関数が連続して動く(例： エラーログを書き込む関数とエラーを管理者に通知する関数を集めたモジュール)

- 論理的凝集： 論理的に同じような関数を集めたモジュール(例： 何かしらのデータ書き込みをする関数群)

- 偶発的凝集： 適当な関数が集まったモジュール

#疎結合(Loosely coupled)

疎結合とは個々のモジュールやコンポーネント同士が直接的に依存していない状態を指します。
別のモジュールを呼び出す際に直接呼び出すのではなく、つなぎ目となるコードを経由して呼び出すことで疎結合な状態が実現されると言われます。(個人的には別のコードを関節的に呼び出すことで疎結合になる理由がいまいち理解できません...)

凝集性と同じようにモジュールの結合度にも程度があります。(上に行くほど良い)

- データ結合: 引数で単純なパラメータを渡す

- スタンプ結合： 引数でオブジェクトを渡す

- 制御結合： 関数の処理を外部のデータによって制御している状態

- 外部結合： 1つのグローバル変数を参照している

- 共通結合： 複数のグローバル変数を参照している

- 内部結合： 他のオブジェクトの内部を参照している


業務では制御結合と外部結合の状態にあるコードをよく目にします。
制御結合を解消するためには詳細な処理を別モジュールや別関数に隔離して、呼び出し元では引数にかかわらず同じ処理をするようにしておくと良いようです。(その別モジュールが制御結合状態になるのでは...?という疑問もありますが...)


## 余談

こういう特定の技術や言語に依存しない知識は汎用性が高いと思うのでドンドン習得したいです。

## 参考資料


- [レガシーコードからの脱却 - ソフトウェアの寿命を延ばし価値を高める9つのプラクティス](https://www.amazon.co.jp/%E3%83%AC%E3%82%AC%E3%82%B7%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8B%E3%82%89%E3%81%AE%E8%84%B1%E5%8D%B4-%E2%80%95%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E5%AF%BF%E5%91%BD%E3%82%92%E5%BB%B6%E3%81%B0%E3%81%97%E4%BE%A1%E5%80%A4%E3%82%92%E9%AB%98%E3%82%81%E3%82%8B9%E3%81%A4%E3%81%AE%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-David-Scott-Bernstein/dp/4873118867)

- [モジュール結合度について](https://qiita.com/eKushida/items/39bdb3f88fb68ecd66f6)

- [凝集度](https://ja.wikipedia.org/wiki/%E5%87%9D%E9%9B%86%E5%BA%A6)

- [モジュール結合度を理解する](https://zenn.dev/taiga533/articles/e08ad4f4af5577079b5b)
バスの到着時刻が正規分布に従っているか実験してみた


#背景
プラントエンジニアのKeisukeです。
去年まで千葉で業務をしていましたが、2021年4月から北海道に転勤して工場で仕事をしています。
現場目線でプラントを見れるので学ぶ事も多く良い経験になっています。
現場は経験がものを言う世界ですが、運転データや不具合記録を分析をして読み取れることも多々あります。今までになかった観点から現場の力になれればと思いながら日々活動しています。

#動機
働いている工場までは自宅から10km、車なしでは到底通勤できない距離です。私は自家用車を持っていませんが、幸いなことに会社から社有バスが出ており、バス停から拾ってもらって通勤をしています。感謝感激です。

バスに揺られながら私はふとこんなことを考えました。
「バスの到着時刻って正規分布にのるのかなぁ？」
夏休みの自由研究でやるような素朴な疑問を解決すべく、私はバスの到着時刻をこの２ヶ月間、せっせと収集していました。社会人も腰を据えて自由研究に取り組める日がいつか来ることを祈りつつ、、、

#データ収集

|日付  |バス到着時刻  |
|---|---|
|4月2日	|07:10:02|
|4月5日	|07:08:27|
|4月6日	|07:08:17|
|4月7日	|07:11:02|
|4月8日	|07:09:12|
|4月9日	|07:10:07|
|4月12日	|07:08:07|
|4月16日	|07:12:17|
|4月19日	|07:08:17|
|4月20日	|07:09:57|
|4月21日	|07:05:23|
|4月22日	|07:08:55|
|4月26日	|07:11:30|
|4月27日	|07:07:22|
|4月28日	|07:08:30|
|5月6日	|07:08:22|
|5月7日	|07:07:32|
|5月10日	|07:11:35|
|5月11日	|07:07:20|
|5月12日	|07:07:35|
|5月13日	|07:10:17|
|5月19日	|07:08:00|
|5月20日	|07:08:37|
|5月24日	|07:07:57|
|5月25日	|07:10:15|
|5月26日	|07:07:17|
|5月27日	|07:08:34|

ということで上表がバス到着時刻のデータになります。会社の朝は結構早いです。6月現在はまだ暖かいですが、あと半年もすれば冬の猛烈な寒波がやってきます。冷え性な私が北海道の凍てつく寒さに耐えられるか心配で夜しか眠れません。
7時6分が到着予定の時刻でやや遅れがある感は否めませんが、いい感じに分布してそうな雰囲気です。

<img width="400" alt="Figure_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565845/8a278d33-1494-8699-98ec-09d8318685ff.png">

到着時刻データをヒストグラムで表したものが上図になります。7時00分00秒を基準（0[s]）としています。
正規分布の形はおぼろげながら見えますが、ちょっと情報量が足りずジグザグな感じが拭えません。それもそのはず今回のデータ数は27個。

#評価方法

正規分布に従っているかを確認する手法として
・Q-Qプロット
・シャピロ・ウィルク検定（S-W検定）
・コルモゴロフ・スミルノフ検定(K-S検定)
があります。

## Q-Qプロット
Q-Qプロットはグラフに引いた直線と今回のデータがどれだけ一致しているかを見る定性的な評価方法です。実際に解析した結果が下図になります。

<img width="400" alt="Q-Qplot.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565845/ebe703d1-d08c-e365-ab41-0f74637558f4.png">



赤い直線にプロットが乗ると正規性が強い事を示します。
どうでしょうか、横軸の両端のデータも直線に乗っていて、正規性を捉えているように感じます。しかし、この手法では正規性を定量的に評価することが出来ません。なので他の方法もトライしてみます。

## シャピロ・ウィルク検定（S-W検定）
S-W検定はデータからP値を計算して定量的に判定する手法になります。
P<0.05であれば「母集団が正規分布である」という帰無仮説を棄却します。
今回は

```math
P = 0.2995
```
という結果で、母集団が正規分布であるという帰無仮説「母集団が正規分布である」は棄却されないという結果になりました。

## コルモゴロフ・スミルノフ検定(K-S検定)
K-S検定はデータ数が多い（1000以上）時に使われる検定です。今回のデータ数は少なく適切ではないですが一応トライしてみます。

```math
P = 0
```
P<0.05となり、K-S検定では帰無仮説が棄却されるという結果になりました。

#まとめ
今回の結果をまとめます。

|評価方法 |正規性 |
|--- |--- |
|Q-Qプロット |△(○) |
|S-W検定    |○ |
|K-S検定  |×|

2ヶ月分の少ないデータ量でしたが、一部の検定で正規性が垣間見える結果となりました。
6月13日現在も絶賛データ収集中なので、バスの到着時刻が正規分布に近づくのかを引き続き検証していきます！
みなさんもバスや電車を待っている時の暇つぶしとしてトライしてみて結果を報告してくれると嬉しいです！！


#参考文献

https://www.st-hakky-blog.com/entry/2017/12/11/200046

https://qiita.com/ground0state/items/80b426e4d39193a609bc

https://analysis-navi.com/?p=3302
VMWare (vmdk)を使ってMikanOSのUEFIブートをする方法

「ゼロからのOS自作入門」の第１章にあるhello.efiをqemuではなくVMWareのディスクで起動する方法です。もっと簡単な方法ある気がしますが。

# 全体のステップ
1. ループバックデバイス準備
1. GPTでパーティションの作成
1. パーティションのフォーマット
1. efiファイルのコピー
1. ループバックデバイスをvmdkに変換
1. VMWareにディスクを追加して起動

vmdkファイルの作成はLinux(VM)上で行い、それをMac上の別のテスト用VMに追加して起動するというシナリオです。
Linux上のコマンドがない場合は頑張って探してインストールして下さい。


## ループバックデバイス準備

100MBのファイルを用意して、ループバックデバイスの作成

```
$ dd if=/dev/zero of=disk.img bs=100M count=1      # 100MBのファイル作成
$ sudo losetup -fP disk.img                        # ループバックデバイスの作成
$ sudo losetup -a                                  # デバイス名表示
/dev/loop0: [2051]:657184 (/develop/MikanOS/disk.img)
```

# GPTでパーティションの作成 
EFIはGPTしか対応しないっぽいのでMBRではなくGPTでパーティションを作成。fdisk利用。

```
$ sudo fdisk /dev/loop0

Welcome to fdisk (util-linux 2.37).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x00cf080e.

Command (m for help): g　　　　　　<------GPTパーティションテーブルの作成
Created a new GPT disklabel (GUID: 7CD727F0-6839-4648-AEF1-81227F22DAAE).

Command (m for help): n          <------ディスク全体を使ってパーティション作成
Partition number (1-128, default 1):
First sector (2048-204766, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-204766, default 204766):

Created a new partition 1 of type 'Linux filesystem' and of size 99 MiB.

Command (m for help): t　　　　　　<------パーティションタイプを"EFI System"に変更
Selected partition 1
Partition type or alias (type L to list all): 1
Changed type of partition 'Linux filesystem' to 'EFI System'

Command (m for help): w          <------変更を書き込んで終了
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
```

パーティションタイプはvfat32がいいのかと思ったけど、タイプのリストに見つけられなかった。GPTでは指定できない？EFI Systemも基本同じっぽいのでとりあえずそれを指定。

## パーティションのフォーマット
今作ったパーティションをvfat32でフォーマット
```
sudo mkfs.vfat -F 32 /dev/loop0p1
```

## efiファイルのコピー
フォーマットしたパーティションを適当なディレクトリにマウントしてhello.efiをコピー。「ゼロからのOS自作入門」第１章 エミュレータでのやり方、の部分とほぼ同じです。
```
$ sudo mount -t vfat /dev/loop0p1 /mnt
$ sudo mkdir -p /mnt/EFI/BOOT
$ sudo cp hello.efi /mnt/EFI/BOOT/BOOTX64.EFI
$ sudo umount /mnt
```
`/mnt`や`hello.efi`は適当に読み替えてください。

## ループバックデバイスをvmdkに変換

```
$ sudo losetup -d /dev/loop0                    # ループバックデバイスを削除して
$ qemu-img convert -O vmdk disk.img disk.vmdk   # vmdkに変換
```

## VMWareにディスクを追加して起動
出来上がった`disk.vmdk`をMacにコピー。そのファイルを使って新規でVM作成

Other 64-bitを選択して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5636/524996c3-1b69-5d93-ce74-7eb0480cd036.png)

Firmware TypeでUEFIを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5636/34d55483-c7db-2e9d-9922-f20d7c0bf1bb.png)

先程コピーしてきたvmdkファイルを指定して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5636/154043ce-c5d7-9e89-f0e2-c166ce55ce98.png)

VMを作成後、起動して"Hello, world!"がでれば成功

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5636/b066c6e5-e0db-04cf-8fb8-0bf08ccf8297.png)
AtCoder Beginner Contest 205 参戦記

# AtCoder Beginner Contest 205 参戦記

## [ABC205A - kcal](https://atcoder.jp/contests/abc205/tasks/abc205_a)

2分で突破. 書くだけ.

```python
A, B = map(int, input().split())

print(A * B / 100)
```

## [ABC205B - Permutation Check](https://atcoder.jp/contests/abc205/tasks/abc205_b)

2分半で突破. 個数カウントしても良かったけど、まあいいかと一つづつチェックした.

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

A.sort()
for i in range(N):
    if i == A[i] - 1:
        continue
    print('No')
    break
else:
    print('Yes')
```

set に押し込んで個数が減らないかチェックするのが一番楽そうだと今気づいた.

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

if len(set(A)) == N:
    print('Yes')
else:
    print('No')
```

## [ABC205C - POW](https://atcoder.jp/contests/abc205/tasks/abc205_c)

14分で突破、WA1. やらかした. どちらも乗数は同じなので偶奇が変わらないように減らしてあげれば OK.

```python
A, B, C = map(int, input().split())

C = (C + 1) % 2 + 1

if pow(A, C) < pow(B, C):
    print('<')
elif pow(A, C) > pow(B, C):
    print('>')
elif pow(A, C) == pow(B, C):
    print('=')
```

## [ABC205D - Kth Excluded](https://atcoder.jp/contests/abc205/tasks/abc205_d)

30分で突破. A<sub>i</sub> が一番右端だと思うと、A<sub>i</sub>+1 は A<sub>i</sub>-i+1 番目の数になる. 実際には右端とは限らないので、Kを超えない A<sub>i</sub> を二分探索で探してそこをベースに計算すれば良い.

```python
from sys import stdin

readline = stdin.readline

N, Q = map(int, readline().split())
A = list(map(int, readline().split()))

result = []
for _ in range(Q):
    K = int(readline())
    ok = 0
    ng = N + 1
    while ng - ok > 1:
        m = ok + (ng - ok) // 2
        if A[m - 1] - m < K:
            ok = m
        else:
            ng = m
    result.append(K + ok)
print(*result, sep='\n')
```

ある数字が何番目かは、Aに含まれるその数より小さい数の個数を調べれば分かり、二分探索を使えば *O*(log<i>N</i>) で求めることができる. K番目以下であるという条件で二分探索すれば *O*(<i>Q</i>log<i>N</i>log<i>N</i>) で答えを求めることができる.

```python
from sys import stdin
from bisect import bisect_left

readline = stdin.readline

N, Q = map(int, readline().split())
A = list(map(int, readline().split()))

result = []
for _ in range(Q):
    K = int(readline())
    ok = K
    ng = K + N + 1
    while ng - ok > 1:
        m = ok + (ng - ok) // 2
        if m - bisect_left(A, m) <= K:
            ok = m
        else:
            ng = m
    result.append(ok)
print(*result, sep='\n')
```