OmniAICreator/Qiita-1.07M huggingface dataset:
【unity】特定の平面に速度上限を設定する

# はじめに
オブジェクトを水平方向（前後左右）に移動させる際、`AddForce()`にて力を加えていたため、移動キーを入力し続けると際限なく加速し続け、限界突破してしまう。

そのため、`rigidbody.velocity.magnitude`にてオブジェクトの速度を取得し、一定の速度を超えないようにプログラムを書こうと思ったが、上下方向の速度、つまりジャンプも考慮されてしまい、ジャンプした際に高さが低くなってしまう。

そこで、特定の平面（xz平面）に関してのみ上限速度を設定してみた。


# 内容
非常に単純な実装で対応できた。要するに任意の平面に関しての速度を計算し、上限の速度を超えた際は`rb.velocity`の各値を調整する。

```c#:速度の調整（抜粋）
public class PlayerMoveController : MonoBehaviour
{
    void FixedUpdate()
    {
        // 移動速度設定
        rb.AddForce(playerSpeedSide, playerJumpPower, playerSpeedFront);
        
        // 移動速度上限チェック
        float horizontalSpeed = (float)Math.Sqrt(Math.Pow(rb.velocity.x, 2) + Math.Pow(rb.velocity.z, 2));
        if (horizontalSpeed > Main.PLAYER_SPEED_MAX)
        {
            rb.velocity = new Vector3(
                rb.velocity.x / (horizontalSpeed / Main.PLAYER_SPEED_MAX),
                rb.velocity.y,
                rb.velocity.z / (horizontalSpeed / Main.PLAYER_SPEED_MAX)
            );
        }
    }
}
```

# 詳細
まず、通常通り`AddForce()`にて力を加える。その後、現在の特定の平面の速度を計算し、上限と比較する。
もし上限を超えていた場合、`velocity`の各値を調整する。

## 1. 特定平面に関する速度
```c#:速度の計算
float horizontalSpeed = (float)Math.Sqrt(
    Math.Pow(rb.velocity.x, 2) + Math.Pow(rb.velocity.z, 2)
);
```
今回はxz平面の速度を制限したいので、x方向とz方向の速度を合成して算出する。やっていることはただのベクトルの合成となる。（それぞれの速度をvx,vzとする場合、√(vx^2+vz^2)となる。）

## 2. 速度の制限
```c#:速度の制限
if (horizontalSpeed > Main.PLAYER_SPEED_MAX)
{
    rb.velocity = new Vector3(
        rb.velocity.x / (horizontalSpeed / Main.PLAYER_SPEED_MAX),
        rb.velocity.y,
        rb.velocity.z / (horizontalSpeed / Main.PLAYER_SPEED_MAX)
    );
}
```
上限を超えた分だけ、各方向の速度を制限する。

例えば、vxが9, vzが12, 上限が5だった場合、平面に関する速度は15となる。
この場合、上限が5なので、vx,vzそれぞれを15/5 = 3で割り、vx=3, vz=4となるため、方向を変えずに速度を制限することができる。

# まとめ
これで、ジャンプに関する挙動はそのままに速度制限ができる。限界突破せずに安心して世界を移動できる。

# 参考文献
- [【Unity入門】Rigidbodyで自在に移動!velocityの活用方法!](https://www.sejuku.net/blog/55084)
エンジニアを志す初心者QAの備忘録

# 初めてのQiita
はじめまして。
むーと申します。
自分がインプットした情報をアウトプットし、身に付けるためにQiitaを始めようと思いました。
何かを発信・投稿するのは初めてなので不安はありますが、勉強した内容をブログのような形式でやっていきたいと思います。

## 自己紹介
2022年1月からマークアップ言語の勉強を始めました。
前職はITと関係ない訪問看護師として従事して参りましたが、2022年5月に転職してQAとなりました。
現在、30歳。エンジニアになれるよう勉強中です。

## 現在、勉強している内容
・マークアップ言語（HTML・CSS）
※転職後は他の勉強を優先していたので、一時的にお休みしていました。
・JSTQB関連
・MySQL
・ER図

## 今後、取り組みたいこと
・Qiita投稿（不定期）
・JavaScript学習
・ポートフォリオ作成

## 最後に
最後まで読んでいただきありがとうございます。
仕事も勉強も全力で取り組み、スキルアップに努めていきます。
よろしくお願いします。
アノテーションベースの MyBatis で one-to-one / one-to-many のテーブルを1クエリでとってくる方法

積年の疑問が晴れた。が、だいぶゴツい。

## サマリ

- one-to-many のときは、@One アノテーションに columnPrefix / resultMap を使う
- many-to-many のときは、@Many アノテーションでおなじようにすればできるはず（未検証）

## 背景

### 過去、アノテーションベースでは N+1 問題が回避不可だった

https://qiita.com/d-yosh/items/a2bec9718bccfe15a6ae#one-many

> しかし、@Oneや@Manyでは上記と同じことを実現できず、必ず他の select を実行するしかありません。
select を利用する方法は N+1 問題が起きてしまうのが嫌で、個人的にはあまり使っていなかったので、ここはちょっとデメリットかなと思いました。

## mybatis-3.5.5 で解消した模様
mybatis-3.5.5 で `@One` `@Many` に columnPrefix を指定できるようになった。
これにより、N + 1 問題を発生させずに、１クエリで one-to-one / one-to-many テーブルをとってこれるようになった。

https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.5.5

## コード例

こんな感じのテーブルのとき

```sql
CREATE TABLE IF NOT EXISTS users (
  id UUID PRIMARY KEY,
  username text NOT NULL UNIQUE,
);

CREATE TABLE IF NOT EXISTS articles (
  id UUID PRIMARY KEY,
  user_id UUID NOT NULL references users(id), -- one-to-one relationship
  body text NOT NULL,
);
```

こうする
```java
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface ArticleRepository {

    @Select("""
            SELECT
                a.id
              , a.user_id
              , a.body
              , u.id as user_id
              , u.username as user_username
            FROM articles a
            JOIN users u on a.user_id = u.id
            """)
    @Results(value = {
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "body", property = "body"),
            @Result(property = "user", one = @One(resultMap = "userResultMap", columnPrefix = "user_"))
    })
    List<ArticleRecord> select();

    @Select("SELECT '1'") // このクエリは実行されない。@ResultMap を定義するためのダミークエリ
    @Results(id = "userResultMap", value = {
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "username", property = "username"),
    })
    UserRecord __userResultMap();
}
```
オズボーンのチェックリストとSCAMPERでアイデア量産！

## はじめに
「なんかアイデアない？」と言われても、すぐには出ないっす...そう思ってませんか？
実は、オズボーンのチェックリストやSCAMPERなどのフレームワークを活用すればパパッとアイデアが量産できちゃうかも？

この記事では、アイデアを量産するフレームワークであるオズボーンのチェックリストとSCAMPERを解説します。
マーケティングやコンサルで使われるものですが、プログラミングに応用できるようにアレンジしてみました。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者
- 「自分にはアイデアなんて出せない」と思っている人

## 結論
アイデアを出すのに詰まったら、オズボーンのチェックリストかSCAMPERを使ってアイデアを広げると良いよ！

## オズボーンのチェックリストとは？
オズボーンのチェックリストは、下記の9つの質問に対する答えを考えることでアイデアを膨らませるフレームワークです。
9つの項目があることから、マンダラートとの相性が抜群に良いです。

### 転用
他の使い道はないか？を考えます。

:::note
現在のコード・ロジックを他の画面に使えないか？
現在のコード・ロジックをデバッグ目的ではなくUIに使えないか？
現在のコード・ロジックを利用者が違う別プロジェクトに使えないか？
:::

### 応用
似たものがないか？を考えます。

:::note
他プロジェクトのコード・ロジックを使えないか？
他画面のプロジェクトのコード・ロジックを使えないか？
過去のコード・ロジックを使えないか？
:::

### 修正
見た目を変えられないか？を考えます。

:::note
サイズを変更できないか？
色を変更できないか？
アニメーションを変更できないか？
:::

### 拡大
プラス方向に変化させるとどうなるか？を考えます。

:::note
もう少し詳しくコメントを書けないか？
同時アクセス数が多くなるとどうなる？
データ数が多くなるとどうなる？
引数を増やしたらどうなる？
:::

### 縮小
マイナス方向に変化させるとどうなるか？を考えます。

:::note
不要なコード・ロジックはないか？
if文を三項演算子に置換できないか？
foreachではなく、コレクションのヘルパー関数を使えないか？
条件分岐を使い、対象を制限したらどうなるか？
:::

### 代用
他のもので代用できるか？を考えます。

:::note
ライブラリが使えないか？
他の言語・フレームワークのロジックが使えないか？
他のメソッドが使えないか？
:::

### 置換
入れ替えができないか？を考えます。

:::note
一部のコードやロジックを入れ替えたらどうなるか？
if節とelse節を入れ替えたらどうなるか？
異なるメソッドと使ったらどうなるか？
コードやロジックの記述位置(ファイル・クラス)を変更したらどうなるか？
:::

### 逆転
上下左右や、時系列を入れ替えたらどうなるか？を考えます。

:::note
クエリを並べ替えた方が処理が早くならないか？
データの並び順を昇順から降順にしたらどうなるか？
if文を三項演算子に置換できないか？
:::

### 結合
組み合わせたらどうなるか、を考えます。

:::note
2つのクラスを統合するとどうか？
2種類の画面を1つに統合するとどうか？
画面の一部を共通化できないか？
:::

## SCAMPERとは？
オズボーンのチェックリストを改良し、7項目にしたアイデア発想フレームワークです。
以下の7つの質問を投げかけてアイデアを膨らませます。

### Substitute(入れ替える)
他のアイデアと入れ替えるとどうなるか、を考えます。

:::note
一部のコードやロジックを入れ替えたらどうなるか？
if節とelse節を入れ替えたらどうなるか？
異なるメソッドと使ったらどうなるか？
コードやロジックの記述位置(ファイル・クラス)を変更したらどうなるか？
:::

### Combine(組み合わせる)
2つ以上のアイデアを組み合わせて相乗効果が出ないか、を考えます。

:::note
2つのクラスを統合するとどうか？
2種類の画面を1つに統合するとどうか？
画面の一部を共通化できないか？
:::

### Adapt（当てはめる）
既にあるアイデアを応用するとどうなるか、を考えます。

:::note
他プロジェクトのコード・ロジックを使えないか？
他画面のプロジェクトのコード・ロジックを使えないか？
過去のコード・ロジックを使えないか？
:::

### Modify(変更する)
内容を変更したり、修正するとどうなるか、を考えます。

:::note
サイズを変更できないか？
色を変更できないか？
アニメーションを変更できないか？
:::

### Put to Other Uses(他の用途にする)
現在あるアイデアを再利用できないか、を考えます。

:::note
現在のコード・ロジックを他の画面に使えないか？
現在のコード・ロジックをデバッグ目的ではなくUIに使えないか？
現在のコード・ロジックを利用者が違う別プロジェクトに使えないか？
:::

### Eliminate or Minify(排除・縮小する)
一部を削除したり、小さくしてみたらどうなるか、を考えます。

:::note
不要なコード・ロジックはないか？
if文を三項演算子に置換できないか？
foreachではなく、コレクションのヘルパー関数を使えないか？
条件分岐を使い、対象を制限したらどうなるか？
:::

### Rearrange or Reverse(並べ替え・逆転する)
順番を並べ替えたり、逆にしてみたらどうなるか、を考えます。

:::note
クエリを並べ替えた方が処理が早くならないか？
データの並び順を昇順から降順にしたらどうなるか？
if文を三項演算子に置換できないか？
:::

## おわりに
アイデア発想を広げるオズボーンのチェックリストとSCAMPERについてまとめました。
Unityゲーム制作奮闘記 - Live2dモデルの瞬き異常動作の調査

## はじめに

本事象には結構長いコト悩まされていて、未だに完全な解決には至っていません。
もっと良い対策が見つかったら追記したいと思います。

## 事象
これはLive2dモデルが半目になる = 瞬きの基準値が勝手に変わり、動作が不安定になるという事象です。
発生するタイミングも明確でなく、故意に再現させることも出来ませんでした。

最初は原因が全く分からず、animationで目を開いてみたり、
パラメータを直接更新してみたのですが、全く解消しませんでした。

## 調査結果（推測）
事象を切り分けた結果、複数の要因が絡み合って発生していることが見えてきました。

原因①Cubisum Eye Blinkを使い、瞬きをさせている。
原因②Animationで目の開閉度を操作している。
原因③Animationの再生速度を操作している。
※原因③はまだ確定では無いですが、影響している可能性は高そうです。

要するに「目の開閉」というパラメータを、
"Animation"と"Cubisum Eye Blink"という二か所から操作していて、
且つ、Animationの速度変更で動作が不安定になった結果、
タイミングが悪いと**Cubisum Eye Blinkの瞬きの基準値がずれてしまう**
という事だろう、と推測しています。

ちなみに、"Cubisum Eye Blink"の設定は、"Animation"の動きを反映させるために
「Multiple」で設定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401336/5c0bd052-b17d-494a-4f1d-4776f790c23d.png)


## 対策
原因は見えてきましたが、
これを解消するには根本的なゲームの作りを見直す必要がある為、
原因を取り除くという方法は採用できません。

なので、**Cubisum Eye Blinkの瞬きの基準値がずれる**という事象を、
都度復旧する事で、対策したいと考えました。

とはいえ、この方法も一筋縄ではいきません。
瞬きの基準値がずれている原因は、明らかにAnimation側にあるので、
復旧するには**Animationの更新を止める**必要がありそうです。
Animationが目の開閉パラメータを掴んでいる状態だと復旧が出来ません。
（ブレンド用のレイヤーが悪さをしている可能性もある）
しかも単純にAnimatorを一時停止するだけではダメなようです。

現状、復旧が見込める方法は以下の2パターンです。
・Live2dモデルを無効化した状態で、Cubisum Eye Blinkの設定値を初期値に戻す
・Animatorを無効化した状態で、Cubisum Eye Blinkの設定値を初期値に戻す

ただ、どちらの場合もAnimatorが一時的に無効化、
つまりはAnimatorが初期化される事になってしまうので、
ブレンド率などの各種パラメータが初期化されてしまいます。
加えて、Animatorから実行中のBehaviourが停止してしまう為、
処理に不具合が生じる可能性が高いです。

とりあえず現時点ではキャラ変更のタイミング等、
プレイの切れ間に復旧処理を挟むことで暫定対処としましたが、
Animatorを止めずに復旧される方法を模索しなければならないですね。。

```C#
_characterArray[i].SetActive(false);
_characterArray[i].GetComponent<CubismEyeBlinkController>().EyeOpening = 1f;
_characterArray[i].SetActive(true);
```


## おわりに
正直、今回の事象するに遭遇する人は、殆ど皆無ではないかと思っています。
ただ自分と同じ思考で開発している方が居ないとも限らないので、
何かしら役に立てば幸いです。

教訓としては、
「Animationで更新するパラメータ」と
「プログラムから直接更新するパラメータ」は、
Live2d側で分けて作った方が無難ですね。
（割と大変ですが）

もしくは、どちらか一方だけで完結させるとか。
一つのパラメータを2か所から同時に操作するのは、
瞬きに限らず、思った以上に動作が不安定です。

作ってみて初めて分かることって多いですよね。
次回の制作時に活かしたい思います。
ここまで読んで頂き、本当に有難うございました。
fish shellを利用しているならabbrを利用してコミットメッセージのprefixを管理すると便利

### はじめに
この記事は、現状コミットメッセージにprefixを運用していて（しようとしている）、[fish shell](https://fishshell.com/)を利用している（しようとしている）方が対象です。
ここで紹介するprefixに関しては、[こちらの記事](https://qiita.com/konatsu_p/items/dfe199ebe3a7d2010b3e)を参照しています。
fish shellのバージョンは執筆時点で最新の3.5.0を利用しています。

fish shellに関しては、[こちらの記事](https://zenn.dev/sawao/articles/0b40e80d151d6a)に丁寧にまとめていただいているので、まだインストールされていない方は、参照してみてください。

### 利用方法
prefixの運用をしていて、後からコミットログを見返すと、わりとprefixがついていないことがあります。
fish shellでabbrで短縮コマンドを登録しておくことで、わずらわしい入力を簡潔にすませることができ、
短縮コマンドを利用するようになるので、prefixのつけ忘れや入力ミスを減らすことができます。
（入力が楽なので、短縮コマンド使うよねって意味で。）

以下のコマンドを、`config.fish`ファイルに追記します。
先頭に`g`を付与していますが、管理していく上でどのアプリケーションかわからなくなってしまうので、gitであることがわかるようにしています。
そこまで多くない場合は、`g`をつけなくてもいいかも。

```config.fish
abbr -a gcmfe git commit -m \"feat:
abbr -a gcmfi git commit -m \"fix:
abbr -a gcmc git commit -m \"chore:
abbr -a gcmd git commit -m \"docs:
abbr -a gcms git commit -m \"style:
abbr -a gcmr git commit -m \"refactor:
abbr -a gcmp git commit -m \"perf:
abbr -a gcmt git commit -m \"test:
```

Demo
![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624296/892d0de4-987a-11d3-f2e9-20b2e486c1f3.gif)

短縮コマンドを利用することで、煩わしい入力を簡潔にすますことができるようになります。
普段、頻繁に利用しているコマンドはこの機に整理して、短縮コマンドとして登録するのはどうでしょうか。
【Pycharm】pycharmでmermaid記法が文字化けする【未解決】

# 内容
pycharmでmermaid記法が使えるようになりました。
しかし、日本語を図中に書くと文字化けするという問題が発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/6c6a3312-066f-3c7a-cbcf-b0c3193e2d4c.png)
最終的に解決はしませんでしたが、理由はわかりましたので共有しておきます。

# 解析する
以下のような文字化けが起こっています。
``` 
日本語　→　æ¥æ¬èª
```
あんまり見たことないタイプの文字化けですね。
よくあるタイプの文字化けだとわけのわからん漢字がでてきますけど、出てきたのはラテン語ですした。

ラテン語の文字コードといえばlatin-1なので、UTF-8→ bytes → latin-1の変換が起こったのではないかと目星をつけて検証していきます。

検証環境はpython REPLを使用します。
``` python
>>> data = '日本語'
>>> data.encode('UTF-8').hex()
'e697a5e69cace8aa9e'
```
日本語をUTF-8でエンコードすると、'e697a5e69cace8aa9e'という16進数で表現されていました。
これをlatin-1でデコードしてみます。
``` python
>>> bytes.fromhex('e697a5e69cace8aa9e').decode('latin-1')
'æ\x97¥æ\x9c¬èª\x9e'
```
これで最初に出た文字化けと一致しますね。
従って、pycharmのこのバグはUTF-8で書かれた文字列をlatin-1でエンコードしてしまっていることによるものだと判明しました。

# 今後
調べてみると、中国語も変換されていないと公式ページで報告されていますね。　VSCodeのほうでは普通にエンコードできるので、時間が解決する問題でしょう。
マークダウン自体は書けるので、表示だけを別のエディタなどで表示しておけばいいかな？
dockerコンテナをherokuにデプロイする方法

## はじめに
dockerコンテナをローカル端末でビルド、起動できたが、heroku上ではどのようにdockerコンテナをビルド、起動させるかが分からず苦労したので、その概要だけ記載したものです。

皆様が読みやすいように概要だけ、、、
決して面倒だから、というわけではありません、、、
自分が思い出せればいいや、というわけでもありません、、、

そう、決して、、、
## 前提
- herokuアカウントを持っている
- herokuアプリを作成済
- dockerDesktopをインストール（ローカルに）済
- ターミナルで、ビルドしたいdockerfileが格納されているローカルフォルダに移動（cdコマンドで）しておいてください

## STEP1：herokuにログイン
その名の通りherokuの中に入ります

```
heroku login
```
## STEP2：herokuコンテナにログイン
その名の通り、herokuの中のコンテナを操作する領域にログイン

```
heroku container:login
```
## STEP3：herokuコンテナでdockerイメージをビルド
その名の通り、herokuコンテナで、dockerイメージをビルド
結構時間かかります。

```
heroku container:push web -a ＜任意の名前＞
```
## STEP4：herokuコンテナのdockerイメージをherokuアプリへデプロイ
その名の通り、herokuコンテナ領域でビルドしたdockerイメージをherokuアプリ領域へデプロイ

```
heroku container:release web -a ＜アプリ名＞
```
## STEP5：herokuアプリをオープン
その名の通り、アプリオープン
```
heroku open
```

以上となります。
エンドポイントセキュリティとゲートウェイセキュリティの違い

## 勉強前イメージ

エンドポイントはサーバとか末端の機器
ゲートウェイはfirewallとか？

## 調査

### エンドポイントセキュリティ とは

エンドポイントは末端や終点を意味し、
セキュリティ用語では終端機器のサーバやPC、スマートフォンのことを指します。

エンドポイントセキュリティはサーバやPCなどの終端機器を攻撃から守るために行うことを指します。
例えば [ここ](https://qiita.com/miyuki_samitani/items/c3cf2961fcd72a2f86ae) でやったEDRやEPPはエンドポイントセキュリティになります。

## ゲートウェイセキュリティ とは

ゲートウェイはネットワークに入る関門のようなところを指し、セキュリティではfirewallなどを指します。
ゲートウェイセキュリティは↑で書いたようなfirewallやWAF、IPSを指します。
サービスのネットワークやオフィスのネットワークに関してはこちらを導入します。

## 違い

- エンドポイントセキュリティ : PCに適応する、アンチウイルスソフトなどがこちら
- ゲートウェイセキュリティ : ネットワークに適応する、firewallとかがこちら

## 勉強後イメージ

なんか全然違うものだけど文字にするとややこしくなっちゃう不思議
今回は理解してたね、多分

## 参考

- [エンドポイントセキュリティとは？その重要性と対策のポイント](https://www.jbsvc.co.jp/useful/security/what-is-endpoint-security.html)
- [ゲートウェイセキュリティ](https://www.secomtrust.net/service/cybersecurity/gw.html)
記事が４０００超えました。年内に５０００到達予定

2022年７月、Qiitaに投稿した記事が4,000を超えました。

一時期、投稿しても、投稿しても、何の根拠もなく非掲載になった時期もありました。

![drok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/d35a9a2a-9ac7-bc5e-6dea-5207036b2516.png)
<--!
スパムの疑いって、誰が、どう疑ったのか、何の統計もつけずに一方的に通告してくるシステムは、オワコンかと思ったこともありました。
-->
何人かの書き手の方が、記事を取り下げてZENNなどに映って行かれました。

私は、基本的にはResearchmapからGithubへの移行を検討していて、
Qiitaはその寄り道的な利用を考えていたこともあり、さほど腹は立ちませんでした。

<--!
学術系のSNSに掲載できて、同じ内容を商業系のQiiatが掲載を拒否することはありえない事象だと思いました。
-->

これはなんとかしなくてはと思い、採用の応募もしました。

残念ながら、採用していただけず、他社に転職しました。

行きがかり上、記事を5000書いたら、今度こそ、本当にGithubに移行せねばと思っている今日この頃です。
品質管理はド素人のauユーザがauの通信障害を通して学んだサービスマネジメントについて 

<h2>記載した背景</h2>
初投稿です。</br>

子供の頃から20年以上auユーザですが、システムのサービス提供をする業務に携わっている身として、</br> 
障害対応をされている方を思うと辛い部分もありました。</br>
独学で学んだ「サービスマネジメント」についてと、auの通信障害を例に計算練習と考え方をメモします。</br>
なお、自分の理解度をあげるため、個人的解釈を含んで記載しております（「●個人的な解釈」や「→」で表現して記載）。</br> 
用語ごとの直下の１文は基本的に参考文献からの引用となります。

<h1>品質保証とサービスマネジメントについて</h1> 
理解をするために必要そうな用語をメモします。</br> 

<h3>品質（quality）とは</h3>

品質とは、「コンポーネント、システム、プロセスが、特定の要件、ユーザー、顧客のニーズ、期待を満たす度合い」をさします。</br>
</br>

●個人的な解釈</br>
「最近、システム品質安定しているね」は、</br>
「最近、システムの不具合もなく、顧客からのニーズにマッチしているので、品質安定してサービス提供できているね」</br>
と言い換えることができるというもとになります。

<h3>品質保証（quality assurance）とは</h3>
品質マネジメントの一部。</br>
「品質要件を満たしていることの確信度合い」に焦点を当てている状態をさします。</br>
品質が当初設定したレベルに確実に到達するよう、適切なプロセスを遵守するための活動です。</br> 


●個人的な解釈</br>
「きちんと要件定義したとおり動くよね？」 </br> 
「リリース後問題なく、不具合発生せずに動いているよね？」</br>
「止まってもすぐに復旧できるフローになっているよね？」</br> 
というものを、きちんと準備やルール作りできている状態かが大事ということと解釈しました。</br> 


<h3>サービスマネジメントとは</h3>
システムを安定的かつ効率的に運用するための取り組み・仕組みを指します。</br> 

完璧を目指すと、かえって費用や時間がかかるため「目標保証型」と「努力目標型」に区分けし、</br> 
どこまで許容するか等、求めるレベルを事前に決めておきます。</br>
→「●時間以上継続して稼働できることを目標とします」や、</br> 
　　「事前告知を伴う定期メンテナンスは、この条件から除きます」など</br> 

<h3>SLA（Service Level Agreement）とは</h3>
サービスの提供者と利用者（顧客）との間で結ばれる合意文書です。</br>  

　→利用規約や約款に記載があります。</br> 


<h1>稼働率って？</h1>
 
システムが運用開始してから現在までの間、正常に稼働していた時間の割合です。</br> 

稼働率を求めるためには、MTBF（稼働時間）とMTTR（平均修理期間）の値を使い計算します。</br> 


  <h4>●MTBF（稼働時間）</h4> 

```
      MTBF　=　稼働時間の合計　÷　故障の回数 
```
→「MTBF」は長いほうがいいということとなります。


  <h4>●MTTR（平均修理期間）</h4>

```
      MTTR = 故障時間の合計 ÷ 故障の回数
```
→「MTTR」は短いほうがいいということになります。


  <h4>●稼働率</h4>

```
      １台の稼働率 = {MTBF ÷ （MTBF ＋ MTTR）} ×100(％)
```
→100％に近いほうが「安定した稼働率」と言えます。


</br>

<h2>auの通信障害について</h2>
<h3>auの稼働率を計算してみる</h3>
今回通信障害が発生していたのが、 2022年7月2日AM1:35 から 2022年7月4日15:00 までの1回とし、７月の稼働率を計算してみます。</br>


```
# ７月は31日までありますので
31day × 24hours × 60min = 44,640 min

# MTBF
44,640min ÷ 1回 = 44,640 

#MTTR 2022年7月2日AM1:35 から 2022年7月4日15:00は、３,６８5minですので
MTTR = 3,685 ÷ 1回 = 3,685

# 稼働率
7月7日0:00現在における７月の稼働率 = {44,640 ÷ (44,640 + 3,685)} × 100 = 92.37%
```
このまま何事も起きなければ、92.37%となります。 </br> 


<h3>今回のSLAと稼働率</h3>
auの通信サービス契約約款をみると、以下の記載がありました。（抜粋＆個人的解釈）</br> 

```
「通信サービスを全く利用することができない状態が24時間以上その状態が継続したとき」
 
「認知した時刻以後の利用できなかった時間24時間ごとに日数を計算し、
その日数に対応するその通信サービスに係る基本使用料等」
```

サービスマネジメントとしては「目標保証型」で、</br>  
SLAは、「24時間以上継続したら日数換算で基本使用料を補填するよ」という内容と受け取れます。</br> 
今回の場合は、48時間は通信障害が発生していたので、2日分は対象となりうる可能性があるということになります。</br> 
「時間で換算ではない」ということも受け取れます。


<h2>感想</h2>
作業者の方、フロントに立たれている方、暑い中おつかれさまです。</br>

サービス提供は、利用者がいてこそ成り立つものではありますが、</br> 
どんなに大変でも、サービスを提供する際にはサービスマネジメントとSLAの記載をきちんと規約等に載せておくことで、提供している側の身を守ることにもつながるということを学びました。</br> 

今回、障害が起きてしまったことは残念ですが、この「事象」から得ることができたものはいろいろな人にとってそれぞれあると思いましたので、私も次に活かせるようにしたいと思います。</br>
 
<h2>参考文献</h2>
ソフトウェアテスト教科書 JSTQB Foundation第４版 翔泳社</br> 

情報処理教科書 出るとこだけ！　情報セキュリティマネジメント 翔泳社</br>
ａｕ（５Ｇ）通信サービス契約約款 </br>
<a href="https://www.kddi.com/extlib/files/corporate/kddi/kokai/keiyaku_yakkan/pdf/honbun_kddi_5G.pdf">https://www.kddi.com/extlib/files/corporate/kddi/kokai/keiyaku_yakkan/pdf/honbun_kddi_5G.pdf</a>

au 障害情報
<a href="https://news.kddi.com/important/news/important_202207051022.html">https://news.kddi.com/important/news/important_202207051022.html</a>
行動的でない私が自動車メーカーから転職した際の流れと振り返り

# 本記事の位置づけ
コロナ流行当初と比べ転職求人が増えてきたことや、リモート面接での転職活動の気軽さもあり、転職活動される方が増えてきたように思います。

一方で転職活動をしたいと考えているものの「転職活動を何したらよいかわからない」、「多忙な業務と並行して書類を書く体力がない」など終わりをイメージできてない転職活動に対して中々重い腰を上げることのできない方も多いのではないでしょうか？

最近転職に関して相談されることも多くなってきましたので、本記事ではエンジニアの方の転職活動開始の潤滑油になれるよう、私が転職活動した際の転職の流れとそこで感じたことを書かせていただきます。

# 転職活動の流れ

私が転職サイトのエージェント経由で実施した転職活動の流れは下記の図のようになっています。

全体のスケジュール間でいうと、エージェントとの面談から転職先決定まで、3カ月程度かかりました。途中面接日などのスケジュール調整に難航したことあり、もう少し早く転職活動を進められる方も多いと思います。ただ、ストレスで禿げそうなので速攻転職したいと思っても、職場を離れるまでに3~4カ月かかることは知っておくとよいと思います。

![Flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490986/1a435b24-d56d-544d-1afa-d911ed5a5e82.png)

ブロック毎の細かい説明を下記にしていきます。

 ①ハラスメント激化期
前職は完全年功序列制の会社だったのですが、管理職が「ハラスメント気質」で「技術力皆無」な方でした。一方で日々の業務とコミュニケーションで疲れ果てていて、白紙の状態から履歴書や職務経歴書を埋めていく体力もない状況でした。

②転職サイトのエージェントに登録
エージェントには良い悪い噂どちらもありましたが、無料だしひとまず話してみようと考えて手ぶらの状態で複数の転職サイトのエージェントと並行してWeb面談をはじめました。
実際のところ、「面談の形式」や「転職活動の進め方」や「相談に対する回答姿勢」など対応は担当エージェントの方でまちまちでした。一方で、相性のあうエージェントさんだと「こちらの悩みとか転職先の指標とかを言語化」や「具体的な活動スケジュールの明確化」をしてくれたりします。中々転職活動を進められないという方は、金額もかからずリスクも少ないのでとりあえずエージェント登録して面談してみると、自分の考えや転職活動開始のきっかけになってよいかと思います。

③ 必要書類の準備
土日に書いて平日にエージェントさんに添削いただいてというフローで、書いている時間自体は短いんですけど2週間くらい妙に時間がかかりました。必要書類準備と並行して、この時期は受ける企業調査を進めていました。エージェントさんには書類準備まで手伝っていただき、以降は自前で書類応募などを進めていきました。

④ 書類選考＆面接
この段階で大変だったことは「日程調整」です。複数企業へ応募していたのですが、会社に行きながら複数企業の面接日程を調整するのが結構大変でした。
あと面接ですが、技術系の転職の場合にはなると思いますが、何社か受けてみて新卒時代の面接と比較して下記が異なると感じました。

- 1次面接はお互いを知る場(面接というよりお互いの意識あわせの場)
  - 面接で先方が気にしていることは職務経歴(何ができるか)であり、その企業をどれだけ調べているかとか何をしたいかはあまり気にしていない印象
  - 逆にこちらとしては、転職後の部署で何をするのかこっちがわかっていないことを相手もわかっているので、具体的な仕事の話とか聞きやすい雰囲気
- 務める部署・チームの技術者による面談がほとんどなので技術的な会話をしやすい
  - どのようなツールを使っているか、どのような開発をしているかなど、割とこれは社外秘ではないのか...?みたいな内容も含めて技術会話をざっくばらんにできる印象

⑤～⑧ 転職先企業の決定 以降
企業としては、自動車メーカー、測定器メーカー、SIerを受けて最終的に前職と同業へ決めました。
最終選考の合否が出た後、大体フォローアップ面談という合格後の相談会みたいなのがあり、その後1~2週間以内に入社可否をこちらから先方へ伝える流れです。
入社決定後は、社内の退職手続きを進めていきます。パワハラが不安な人は、面談中レコーダーで録音しておきましょう。


# 転職してみて感じたこと

自動車メーカから同業他社へ転職してみて、ソフト開発領域のエンジニアの少なさと新しいソフト開発ツールの導入の遅さは共通していると感じつつ、開発レベルやソフト開発の進めやすさは全く異なると痛感しています。今もし自動車メーカのソフト開発に絶望している方がいても、場合によっては勤め先特有の問題の可能性もあるので受けてみるのはありかもしれないです。

また転職活動では、下記が大切だと個人的には思いました。
 - エージェントは複数企業を試した方が良い
 上述したように、正直担当してくれる人によってまちまちで、営業職から転職してエージェントやっている方もいれば、技術職から転職してエージェントやっている方もいます。自分の思考回路に近いエージェントと巡り会える可能性を少しでも上げるために、何社か試して比較してみると良いと思います。
 - 面接は新卒時よりも楽しい！！
   Web検索では出てこないような細かい技術的な会話ができ、相手もなんでも聞いて精神の企業が多いので怖がる必要はないと感じました。面接では逆質問時間を30分とか長めに設定してくれる企業が多かったので、聞きたいことを事前にまとめてしっかり聞きたいことを聞き切れるようにしておくとよいと思います。

本記事ではほぼ触れませんでしたが、もし自動車メーカでの働き方など興味がある方がいれば、DMなどでご連絡いただければと思います。
毎日、日が変わったときに画面更新

毎日、日が変わったときに画面更新する処理を入れたときのメモです。
```javascript
  const date_now = new Date();
  const date_refresh = new Date();

  date_refresh.setDate(date_now.getDate() + 1);
  date_refresh.setHours(0);
  date_refresh.setMinutes(0);
  date_refresh.setSeconds(0);
  //現在から更新時刻までの時間(ms)
  const time_refresh = date_refresh.getTime() - date_now.getTime();

  useEffect(() => {
    const id_refresh = setTimeout(function () {
      window.location.reload();
    }, time_refresh);

    return () => {clearTimeout(id_refresh);};
  }, [time_refresh]);
```
Swift 画面を強制的に回転させたい！

回転のコードはこれ！
```swift
    override func viewDidLoad() {
        //右か左か判定
        if(UIDevice.current.orientation.rawValue == 4){
            UIDevice.current.setValue(4, forKey: "orientation")
        }
        //左横画面以外の処理
        else {
            //最初の画面呼び出しで画面を右横画面に変更させる。
            UIDevice.current.setValue(3, forKey: "orientation")
        }
    }

    //MARK: 回転設定
    override var shouldAutorotate: Bool {
        return true
    }
    //MARK: 横画面のみ許可
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.landscape
    }
```

### これで任意の画面だけ強制的に回転するコードなのだが、
# StoryBoardの該当画面のViewControllerのPresentation設定を
# 「Full Screen」
# にしないと回転しない!

以上
rails7でomniauthで認証しようとしたらエラーばっかりでうまくいかなかった

# 最終的にはちゃんとできました。
他の言語にうつつを抜かしている間にRubyは３出てるし、railsは７系出てるしでまさに青天の霹靂。
ホスティングする環境によって最近使ってるdotnetをあまり使いたくなかったので、久々にrails触った。

# やりたいこと
ユーザー認証まわりはCognitoにおまかせして、さっと作りたかった。

## 参考にさせていただきました
こちら
https://qiita.com/yhirano55/items/272125c3ce3d7873002e
ありがとうございます。

## ですが動かない

### 最初は「OmniAuth::AuthenticityError Forbidden」が出る
![スクリーンショット 2022-07-07 22.02.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120789/7ca80e2f-48e9-6e64-c133-6871387d0779.png)
これですね。
これは
`gem 'omniauth-rails_csrf_protection'`
を追加したら回避できます。（というかしないといけない？）

### 次は「ActionController::InvalidAuthenticityToken ActionController::InvalidAuthenticityToken」と出る
ここが一番はまった。
CSRFのトークンの検証とかもろもろOFFにしたりとかいろいろやった。（rails5時代の知識だけど）
でもダメ
![スクリーンショット 2022-07-07 22.08.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120789/c5e9d7aa-ecd9-a068-dfa2-adb86d135669.png)

rails6で作り直したりしてもだめ。
新しいプロジェクトを作ってちょっとずつコード実装していくとようやく原因がわかった。

### config/initializers/session_store.rb
`Rails.application.config.session_store :cache_store`
この部分が原因だった。
（なお、そのままセッションをCookie保存だったらCookieのサイズオーバーのエラーが出る）

キャッシュ周りの設定を反映しないといけなかった
`bin/rails dev:cache`
を実行する。

## やっぱり２メジャーバージョンも離れると勝手が違うね
最新のものを使うと情報が少ない、枯れたバージョンだとすぐにEOLになるし大変。
Airflow資料抄訳(3)：DAGを宣言する

恥ずかしながら最近になって知ったワークフローエンジン [Apache Airflow](https://airflow.apache.org/)。日本語の紹介記事もちらほら出てきていますが、[公式ドキュメント](https://airflow.apache.org/docs/)をちょっとずつ抄訳しながら読んでいこうと思います。

3回目の今回は[DAGを宣言する](https://airflow.apache.org/docs/apache-airflow/stable/concepts/dags.html#declaring-a-dag)（Declaring a DAG）。
バージョン2.3.2時点のものです。

---

# DAGを宣言する

DAGを宣言する方法は3つあります。１つ目は、withブロックを使用する方法。オペレーターの初期化にはDAGインスタンスが必要ですが、これは暗黙的に行われます：

```py
with DAG(
    "my_dag_name", start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
    schedule_interval="@daily", catchup=False
) as dag:
    op = EmptyOperator(task_id="task")
```

2つ目は、DAGクラスのコンストラクターを使用する方法。オペレーターの初期化に際してDAGインスタンスを明示的に渡します：

```py
my_dag = DAG("my_dag_name", start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
             schedule_interval="@daily", catchup=False)
op = EmptyOperator(task_id="task", dag=my_dag)
```

3つ目は、`@dag`デコレーターを使用して[関数をDAGジェネレーターに変換する](https://airflow.apache.org/docs/apache-airflow/stable/concepts/dags.html#concepts-dag-decorator)方法：

```py
@dag(start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
     schedule_interval="@daily", catchup=False)
def generate_dag():
    op = EmptyOperator(task_id="task")

dag = generate_dag()
```

DAGは[タスク]( https://airflow.apache.org/docs/apache-airflow/stable/concepts/tasks.html)なしにはありえません。タスクはふつう[オペレーター]( https://airflow.apache.org/docs/apache-airflow/stable/concepts/operators.html)や[センサー]( https://airflow.apache.org/docs/apache-airflow/stable/concepts/sensors.html)、[タスクフロー]( https://airflow.apache.org/docs/apache-airflow/stable/concepts/taskflow.html)の形で追加されます。

## タスクの依存関係

タスクないしオペレーターが単体で利用されることは稀です。例えば、タスクAはタスクBに依存し（タスクBはタスクAの上流に位置する）、タスクCはタスクAに依存する（タスクCはタスクAの下流に位置する）といった具合です。このようなタスク間の依存関係を宣言するのがDAGの構造です。つまり有向非巡回グラフのエッジが依存関係を示します。

タスクの依存関係を宣言するの方法のうち主なものは2つあります。1つ目は演算子 `>>`と`<<`を使用する方法です：

```py
first_task >> [second_task, third_task]
third_task << fourth_task
```

2つ目はもっと明確にメソッド `set_upstream`と`set_downstream`を使用する方法です：

```py
first_task.set_downstream(second_task, third_task)
third_task.set_upstream(fourth_task)
```

もっと複雑な依存関係を宣言するためのショートカットもあります。タスクのリストAがタスクのリストBに依存するようなケースは、上述の方法では宣言できません。代わりに`cross_downstream`を使用します：

```py
from airflow.models.baseoperator import cross_downstream

# 次のように書く代わりに：
# [op1, op2] >> op3
# [op1, op2] >> op4
cross_downstream([op1, op2], [op3, op4])
```

依存関係をチェインさせたいときは`chain`を使用します：

```py:
from airflow.models.baseoperator import chain

# 右のように書く代わりに： op1 >> op2 >> op3 >> op4
chain(op1, op2, op3, op4)

#動的な宣言もできます
chain(*[EmptyOperator(task_id='op' + i) for i in range(1, 6)])
```

チェインにより組になった依存関係も実現できます（`cross_downstream`による依存関係とは異なります）：

```py
from airflow.models.baseoperator import chain

# 次のように書く代わりに：
# op1 >> op2 >> op4 >> op6
# op1 >> op3 >> op5 >> op6
chain(op1, [op2, op3], [op4, op5], op6)
```

---

一対一の依存関係はわかりやすいですが、一対多や多対一や多対多になると、途端に難しくなってきます。
演算子方式の限界が示されていますが、もし仮にこれらが演算子で書き表せたとして、それは果たして可読性に優れているかというと怪しいところ。
畢竟テキストによりグラフを表現することの限界なのでしょうか？
【GitHub】デフォルトブランチの変更方法

# やり方
リポジトリのページに行き、「Settings」を選択します。
![スクリーンショット 2022-07-06 17.17.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d3845c15-1bac-6f46-3b62-c624baa8bf22.png)

左に表示されるメニューの「Branches」を選択します。
![スクリーンショット 2022-07-06 17.19.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/e09361d0-7411-91c3-1420-7a14c51f2f38.png)

「Default branch」の項目が表示されます。
![スクリーンショット 2022-07-06 17.20.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/7c35135f-e89c-1f11-16ce-1ffe81fc7cbb.png)

① 左に表示されている矢印ボタンを押します。
② デフォルトブランチに設定したいブランチを選択します。
③ 「Update」を押します。
![スクリーンショット 2022-07-06 17.21.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/7812f9ec-d113-8a77-695b-89c29cf6bd66.png)

これでデフォルトブランチの変更は完了です
【#22 エンジニア転職学習】DB入門　DBMSのコスト

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

DBの入門をざっくり学習していきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日の学習内容は、DBMSを構築していくためのコストをメインにしました。

* **DBMSのコスト　←Topics!!**
* DBMSのアーキテクチャ

# DBMSのコスト
### イニシャルコストとランニングコスト
DBMSのイニシャルコスト＝**ライセンス料**になる。
大規模での利用ではユーザ数把握が難しいので「プロセッサライセンス」単位になる。
また、**エディションもイニシャルコストを大きく左右**する要素になる。エディションによって、信頼性・性能・セキュリティ機能の搭載有無が違う。

DBMSのランニングコストは主に**サポート料**のこと。
### コストの組み合わせ
現実的に使用されるコストの組み合わせは下記2点となります。
1はOracleなどの基本的な商用利用DBMSの構成。2はサブスク型のレンタルモデルが多い。
どちらにせよ、トータルコストで判断するようにする。
1. **イニシャルあり ランニングあり**
1. **イニシャルなし ランニングあり**


使用している教材はこちら↓


https://www.amazon.co.jp/%E3%81%8A%E3%81%86%E3%81%A1%E3%81%A7%E5%AD%A6%E3%81%B9%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93-%E3%83%9F%E3%83%83%E3%82%AF-ebook/dp/B00TTRZFDC/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=1657112653&sr=8-1


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
Latexの参考文献の順番を直すpythonプログラム

Latexのコードを入力として、参考文献の出てくる順番通りにbibitemを並べかえたものを出力します。

以下のリンクのDaveWさんの回答を基にしました。

https://tex.stackexchange.com/questions/17354/sort-thebibliography-by-citation-order/360587#360587?newreg=8fdd8ded0d3442b887449ab98c1c0ee6

```python:sctex.py
import argparse

#https://tex.stackexchange.com/questions/17354/sort-thebibliography-by-citation-order
#DaveW Mar 27, 2017 at 7:43

parser = argparse.ArgumentParser(description='latex citation sorter')
parser.add_argument('filein')

args = parser.parse_args()

with open(args.filein) as f:
    string = f.read()

start = '\\begin{document}'
end = '\\begin{thebibliography}'
si = string.find(start) + len(start)
ei = string.rfind(end)

body = string[si:ei]

start = '\\begin{thebibliography}'
end = '\\end{thebibliography}'
si = string.find(start) + len(start)
ei = string.rfind(end)

bib = string[si:ei]

authors = []

for c in range(0,len(body)-10):
    if body[c:c+6] == '\\cite{':
        author = ''
        c+=6
        while(body[c]!='}'):
            if(body[c]==' '):
                c+=1
            elif(body[c]==','):
                c+=1
                if author in authors:
                    author = ''
                else:
                    authors.append(author)
                    author=''
            else:
                author += (body[c])
                c+=1
        if author in authors:
            pass
        else:
            authors.append(author)
            
labels = []
refs = []

for c in range(0,len(bib)-7):
    ref=''
    if bib[c:c+9] == '\\bibitem{':
        c+=9
        label=''
        while(bib[c]!='}'):
            label += bib[c]
            c+=1
        labels.append(label)
        c+=1
        while(bib[c:c+9] != '\\bibitem{'):
            if c == len(bib)-1:
                break
            elif (bib[c]) == '\n':
                c+=1
            else:
                ref += (bib[c])
                c+=1
        refs.append(ref)
        
labref = dict(zip(labels,refs))

for author in authors:
    print('\\bibitem{' + author + '}\t' + labref[author])

print('orphans:')

if len(authors) < len(labels):
    orphans = list(set(labels)-set(authors))
    for orphan in orphans:
        print('\033[91m' + '\\bibitem{' + orphan + '}\t' + labref[orphan] + '\033[0m')

```
【PHP初級㉗】range関数、array_sum関数

［問題］　　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksPrimary.html)
整数値を入力させ、1からその値までの総和を計算して表示するプログラムを作成しなさい。
ただし、0以下の値を入力した場合は0と表示する。



# コード
```php
$a = intval(fgets(STDIN));
$m = range(1, $a);
if($a > 0){
    echo array_sum($m);
}else{
    echo '0';
}
```

↓「6」と入力

# 結果
```
21
```


☆range()
・・・ある範囲の整数を有する配列を作成する関数。

例）range(1,10)　　→　　1から10までの整数の配列


☆array_sum()
・・・配列の中の値の合計を計算する関数。

例）
```php
$a = [2,3,4];
echo array_sum($a);
```
　　　　　↓　結果
```
9
```
javascriptで表せる数の限界


正確に扱える最大の整数
Number.MAX_SAFE_INTEGER
9007199254740991

正確に扱える最小の整数
Number.MIN_SAFE_INTEGER
-9007199254740991

Number.MIN_SAFE_INTEGERからNumber.MAX_SAFE_INTEGER以外の範囲では計算結果に誤差が生じる。
Javascriptのbooleanの判定法超基礎

0以外の数値型
"以外の文字列型
配列型
オブジェクト型

これらをifの条件式として扱う場合はtrue扱いになる。

```javascript
//アラートが表示されるパターン
const userName = 'Hitsuji';
if(userName){
 alert(`こんにちは${userName}さん`)
}
```

```javascript
//アラートが表示されるパターン
const address = '';
if(address){
 alert(`あなたは${userName}ですね？`):
}
```
!を付与すると真偽値が逆になる
```javascript
//falseが変える
const flg = 
'JavaScript'.includes('a');
console.log(!flg);
```
!!を２回加えるとデータ型がbooleanになる
```javascript
//結果: true
console.log(!!'Hitsuji'):
```
DockerfileのARGをFROMを越えて引き継ぐ


以下のようなDockerfileを作った。

```Dockerfile
ARG VERSION=latest

FROM busybox:$VERSION

RUN echo $VERSION > /opt/image_version

# ...
```

`/opt/ubuntu_version` には `latest` が書き込まれることを期待したが実際には空。

なんでだーと思ったらちゃんと公式ドキュメントに書いてある。

https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact

> An ARG declared before a FROM is outside of a build stage, so it can’t be used in any instruction after a FROM. To use the default value of an ARG declared before the first FROM use an ARG instruction without a value inside of a build stage:

意訳。

> FROMより前に定義されたARGはビルドステージ外にあります。よって（FROM以降は別のビルドステージになるため）FROM以降はARGを使うことはできません。
FROMより前に定義されたARGのデフォルト値を使えるようにするには、ビルドステージの中でARGを使ってください。このとき、ARGにはデフォルト値を指定しないでください。

FROM以降はARGがリセットされるようなイメージなのかな。
だから$VERSIONで参照しても定義されていないから空文字が出力される。

FROM以降で改めてARG VERSIONを定義すればいいらしい。

```Dockerfile
ARG VERSION=latest

FROM busybox:$VERSION

# これ❗
ARG VERSION

RUN echo $VERSION > /opt/image_version

# ...
```

こうすると `/opt/ubuntu_version` には `latest` が書き込まれる。

よかったよかった。
Javascriptで引数の数が未定だがとりあえず関数を作りたい【残余引数】

function 関数名(...引数) || 
(...引数) => {}

## 不特定数の引数を受け取る関数を作りたい
不特定多数の引数を受け取るには「...引数」のように「...」を用いる。
受け取った引数は引数[0],引数[1]のようにインデックスを使用して使用可能。残余引数という。

渡した引数を全て加算してreturnする関数はこちら。

```javascript
function calcSum(...prices){
 let result = 0;
 for(const value of prices){
   result += value;
}
 return result;
}

const result1 = calcSum(10,20)
```
Mysql8からdumpしてMysql5系にimportする方法

普通に行うと以下のようなエラーが出るので、dump時に一工夫必要です。
```
ERROR 1273 (HY000) at line 264: Unknown collation: 'utf8mb4_0900_ai_ci'
```

# Dump方法
```
mysqldump --compatible=ansi -uroot -p <databasename> > <dump_filename>.sql
```
`---compatible`で互換性を指定してあげることで解決できました。
【JavaScript】条件分岐（if文・三項演算子）

# if文
■もし条件式1ならば処理1を実行する
```JavaScript
if (条件式1) {
  処理1
}
```
■もし条件式1ならば処理1を実行、違う場合は処理2をする
```JavaScript
if (条件式1) {
  処理1
} else {
  処理2
}
```
■もし条件式1ならば処理1を実行、
条件式1には当てはまらないが、条件式2に当てはまれば処理2を実行、
違う場合は処理3をする
```JavaScript
if (条件式1) {
  処理1
} else if (条件式2) {
  処理2
} else {
  処理3
}
```

# 三項演算子
■if文のショートカットとしてよく用いられます。
```javascript
(条件式) ? "true(trueに変換できる値)" : "false(falseに変換できる値)"
```
※条件式を囲んでいる()は必須ではないです。
  
例えば、以下の様なif文があったとします。
```javascript
const price = 1000;

if (price < 500) {
  console.log("安い");
} else if (price > 1500) {
  console.log("高い");
} else {
  console.log("普通");
}
```
三項演算子では以下の様になります。
```javascript
const price = 1000;
const result = (price < 500) ? "安い" : (price > 1500) ? "高い" : "普通";
console.log(result);
```
三項演算子では簡潔に書くことができました。

また三項演算子は、簡潔な分岐処理である、
「if (条件式) { 処理 } else { 処理 }」 で表せる場合に適用するのに留めるのがポイントです。

## まとめ
if文はネストが深くなってしまい、見ずらい・バグが多くなると言われています。

▼参考にさせていただいた記事
https://tenshoku-miti.com/takahiro/program-conditional-branch/
JavaScript のアロー関数の書き方

自分はあまりコードは書きません。
色々記法があって忘れがちなのでメモします。

### アロー関数
#### アロー関数のメリット
##### 1.関数を簡略化できる
##### 2.thisを束縛できる

アロー関数の例

```javascript
const CalcSum = (a,b,c) => {
const result = a + b + c;
return result;
}
```

```javascript
const myFuntion1 = (a) => {
 return a + 2;
})
```
```javascript
const myFunction2 = a => {
 return a + 2;
});
```
```javascript
const myFunction3 = (a) => a + 2;
```
そもそも、時間の取り扱いってどうすれば良いんだっけ？

# はじめに
時間を使いたいんじゃ
時間の管理ってなんじゃ？
そも、RustのChronoというライブラリが言っとるNaive、Local、Utcってなんじゃ。
タイムゾーンがどうのこうの、JSTだのESTだの知った風なことを言ってたんじゃが
ぶっちゃけ知らんかったわい。
時間とは奥深いものよのぅ。

# 動機
まぁ、正直良くわからなかったので挙動とか調べてみた。

# 結論
Localで管理する、というのがベスプラになる！
地球上、どこで起動しても、正しい現地時間を表示できるよ！

# 前提条件
1. ある地域の現地時間の朝9時を基準に時間を計算をしたい！
2. 時差情報はOSから取って来たい！
2. 時差を手動で修正したくない！

これらをまるっとやってくれるのがLocalという型なのである。

```Rust
fn main() {
    time("2022-10-11");
}

fn time(start: &str) {
    let start_time = "9:30";
    let start = format!("{}-{}", start, start_time);
    let start_naive_date_time = NaiveDateTime::parse_from_str(&start, "%Y-%m-%d-%H:%M").unwrap();
    println!("素のお時間: {:?}", start_naive_date_time);
    let local_date_time = Local.from_local_datetime(&start_naive_date_time).unwrap();
    println!("現地時間: {}", local_date_time);
    let jst = local_date_time.with_timezone(&FixedOffset::east(9 * 3600));
    println!("日本標準時(UTC+9): {}", jst);
    let washington_time = local_date_time.with_timezone(&FixedOffset::east(-4 * 3600));
    println!("アメリカワシントン: {}", washington_time);
}
```

実行結果
```
素のお時間: 2022-10-11T09:30:00
現地時間: 2022-10-11 09:30:00 +09:00
日本標準時(UTC+9): 2022-10-11 09:30:00 +09:00
アメリカワシントン: 2022-10-10 20:30:00 -04:00
```

まぁ、日本でやってるので、現地時間と日本時間は同じになりますわなぁ。

じゃあ、どこか遠い日本とはかなり時差の離れたところの現地時刻9時が日本時間とワシントン時間で表すとどうなるかを確認してみよう。

ヌクアロファってなんじゃ？まぁ離れてそうだからここで良いや。トンガに有るらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/b93c4dbf-79c6-1c1f-c0b8-7657b1f29d56.png)

というわけで、実行してみた。
```
素のお時間: 2022-10-11T09:30:00
現地時間: 2022-10-11 09:30:00 +13:00
日本標準時(UTC+9): 2022-10-11 05:30:00 +09:00
アメリカワシントン: 2022-10-10 16:30:00 -04:00
```
正しく、時差情報がLocal先生の力によって更新されている
あと、日本の時間とアメリカ（ワシントン）の時間も、現地時間におけるUTC差分で計算されている。

トンガの時差：UTCから13時間進んでいる
日本の時差：UTCから9時間進んでいる
アメリカ（ワシントン）の時差：UTCから4時間遅れている
UTC：時差の基準となる時間。つまり時差は0

これらを考えるとトンガが9時のときは、UTCが前日の20時を指している。
日本はUTC+9時間なので、5時
アメリカはUTC-4なので、16時

と言う感じになり、もしLocalという型がなければこれを手で計算しなければならぬ。
Localのお陰で手計算しなくて済むというわけですな。お便利ですね。

# おまけ
Date（時刻情報がない日付のみ）の場合はどうなるんだろう？？？？
``` rust
fn time(start: &str) {
    let start_time = "9:30";
    let start = format!("{}-{}", start, start_time);
    let start_naive_date_time = NaiveDate::parse_from_str(&start, "%Y-%m-%d-%H:%M").unwrap();
    println!("素のお時間: {:?}", start_naive_date_time);
    let local_date_time = Local.from_local_date(&start_naive_date_time).unwrap();
    println!("現地時間: {}", local_date_time);
    let jst = local_date_time.with_timezone(&FixedOffset::east(9 * 3600));
    println!("日本標準時(UTC+9): {}", jst);
    let washington_time = local_date_time.with_timezone(&FixedOffset::east(-4 * 3600));
    println!("アメリカワシントン: {}", washington_time);
}
```

実行結果

```
素のお時間: 2022-10-11
現地時間: 2022-10-11+13:00
日本標準時(UTC+9): 2022-10-11+09:00
アメリカワシントン: 2022-10-11-04:00
```
その日に丸め込まれるらしい。
地球上であれば時差は24時間以内に収まるので、どの地域でも**その日**として計算されるわけですな。奥深いものですなぁ。

# まとめ
DateTime<Local>は強い。
時差情報をいい感じにOSから取ってきて計算してくれる。
Dateは**時差**関係なく**その日**として扱われる。
時間の情報がないので時差情報も適用されない。

DateTime&lt;Naive&gt;：時差情報なし
DateTime&lt;Local&gt;：時差情報あり
DateTime&lt;Utc&gt;：時差を計算するための基準時刻


# ものぐさな方へのまとめ
文章が長い、読むのめんどいけどなんて？
Local使っとけばいいっすよ。つよいから。
APG4bで自分が書いたコード1 EX1~EX5


<!-- 
[]()
```c++:.cpp



```
 -->


# AGP4bとは

AtCoder Programming Guide for beginners
AtCoderの初心者向けプログラミングガイドです
この記事ではC++ (GCC 9.2.1)を使っています


知的財産権
本サービスに対して投稿されたプログラムの所有権と著作権は、そのプログラムを作成したユーザに帰属します
https://atcoder.jp/tos
より引用

[EX1 - コードテストと出力の練習](https://atcoder.jp/contests/APG4b/tasks/APG4b_cv)
```c++:EX1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  cout << "こんにちは" << endl;
  cout << "AtCoder!" << endl;
}
```

[EX2 - エラーの修正](https://atcoder.jp/contests/APG4b/tasks/APG4b_cu)
```c++:EX2.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  
  cout << "いつも2525" << endl;
  cout << "AtCoderくん" << endl;
}
``` 

[EX3 - 計算問題](https://atcoder.jp/contests/APG4b/tasks/APG4b_ct)
```c++:EX3.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  cout << 100*(100+1)/2 << endl;
}
```

[EX4 - ◯年は何秒？](https://atcoder.jp/contests/APG4b/tasks/APG4b_cs)
```c++:EX4.cpp

#include <bits/stdc++.h>
using namespace std;
 
int main() {
  // 一年の秒数
  int seconds = 365 * 24 * 60 * 60;
 
  // 以下のコメント/* */を消して追記する
  cout << seconds/* 1年は何秒か */ << endl;
  cout << 2*seconds/* 2年は何秒か */ << endl;
  cout << 5*seconds/* 5年は何秒か */ << endl;
  cout << 10*seconds/* 10年は何秒か */ << endl;
}
```


[EX5 - A足すB問題](https://atcoder.jp/contests/APG4b/tasks/APG4b_cr)
```c++:EX5.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  
   int a, b;
  cin >> a >> b ;
  cout << a + b  << endl;
}


```
An error occurred when sending a notification using 'slack' notifier.OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate) 的なエラーの解決方法

# エラー内容
本番サーバーで以下のことを行ったら表題のエラーが出ました。
* Slackにエラー通知を実装（gem 'exception_notification'）
* Cloudinaryに画像をアップロード

```
An error occurred when sending a notification using 'slack' notifier.OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
```

# 解決方法
本番サーバーにログインし、以下実行。
```
curl -fsSL curl.haxx.se/ca/cacert.pem -o "$(ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE')"
```
解決しない場合はnginxやサーバーの再起動を行ってみてください。


### 参照
https://github.com/rubygems/rubygems/issues/2415#issuecomment-460998632
git merge で衝突(コンフリクト)したときの状態まとめ

## ■概要
git merge でマージを行い「衝突が発生してマージコミットが作られずに処理が停止した状態」がいまいち理解できてなかったので、いったいどのような状態なのかをまとめた。

## ■マージに関連するコミットの名前

|コミット名|説明|git checkout/diffでの指定|TortoiseGitでの呼び名|
|----|----|----|----|
HEAD|マージ作業直前のHEAD|--ours, -2|%mine, LOCAL
MERGE_HEAD|マージしようとしているコミット。|--theirs, -3|%theirs, REMOTE
共通祖先|上２つの共通祖先|--base|%base, BASE

## ■git merge でコンフリクトした状態
### コンフリクトしたときの作業コピー

```
共通祖先コミット　──────→　HEADコミット　────→　【作業コピー】
　　　　　　│　　　　　　　　　(ours側) 　　　　　　　  ↑
　　　　　　│　　　　　　　　　　　　　　　　　　　　　　│
　　　　　　└─────────→　MERGE_HEADコミット　- - - - ┘
　　　　　　　　　　　　　　　(theirs側)　　　　　　※ここの線はマージコミットを作るまでは無い
```

git merge でコンフリクトして止まったときは、HEADコミットの作業コピーに対して以下修正がされた状態になっている。(ちなみにHEADコミットの作業コピーなので、まだMERGE_HEADは親コミットとして登録されてない。)
- 衝突しなかったファイル
  共通祖先コミット..MERGE_HEADの修正が「ステージ状態」にされている
- 衝突したファイル
  どこが衝突したのかわかるように自動編集されて、「衝突・未ステージ状態」にされている。
  (「衝突フラグON」かつ「未ステージ状態」の状態)


### 「衝突・未ステージ状態」のファイルについて
衝突したファイルは以下のような状態遷移をする。
```
　　　　　●初期状態
　　　　　　　↓　　　　　　git add (ステージされると同時に衝突フラグoff)
　[衝突・未ステージ状態]　───────────────┐
　　　　　　　↑　　　　　　　　　　　　　　│
　git checkout --conflict(*)　  　　　 │
　　　　　　　：　　　　　　　　　　　　　 │
　　　　　　　　　　　　　git reset 　　　↓
　[未ステージ状態]　←────────────────　[ステージ状態]
　　　　　　　　　　────────────────→
　　　　　　　　　　　　　git add

(*)git co --conflict=merge ファイル名
   ……のコマンドで、[未ステージ状態][ステージ状態]どちらの状態からでも
  「衝突フラグON」かつ「未ステージ状態」でどこが衝突したのかわかるように
  自動編集された[衝突・未ステージ状態]に戻すことができる。
```

「衝突・未ステージ状態」ファイルに対しては、以下の作業を行うことができる。
これらは衝突フラグがONのファイルにしか行えない。

|コマンド								|説明|
|----|---|
git checkout --ours   ファイル名		|HEADコミットのファイルを作業コピーに上書き。-2オプションも同じ意味。
git checkout --theirs ファイル名		|MERGE_HEADコミットのファイルを作業コピーに上書き。-3オプションも同じ意味。
git diff --ours							|HEADコミット..作業コピーの差分表示。
git diff --theirs						|MERGE_HEADコミット..作業コピーの差分表示。
git add ファイル名						|ファイルを「衝突フラグOFF」にして「ステージ状態」にする。

## ■その他の情報

### TortoiseGit既定マージツール
マージ用のGUIツールの説明。

- 左上ペイン
  共通祖先..MERGE_HEAD の差分(削除行、追加行)が表示されている。
- 右上ペイン
  共通祖先..HEAD の差分(削除行、追加行)が表示されている。
- 下ペイン
  共通祖先..マージ結果ファイルの差分(削除行、追加行)が表示される。
  衝突した箇所は「??????」と表示されている。
  そこをカーソル選択して上部のアイコンをクリックすることで、ours, thirsのどちらかを採用した状態に編集できる。直接テキスト編集することも可能。

### WinMerge
マージ用のGUIツールの説明。

TortoiseGitの設定でマージ外部ツールに「WinMerge.exe」と指定すると、BASE, LOCAL, REMOTEの3ファイルの比較が行われる。
マージ結果ファイルは別のテキストエディタなどで開かないと修正できない。

TortoiseGitの設定でマージ外部ツールに「WinMerge.exe %mine %theirs %merged」と指定すると、3ファイルのうち1つがマージ結果ファイルになる。
マージ結果ファイルを直接WinMergeでテキスト編集できる。

### git status -s の1ファイル1行表示
「衝突・未ステージ状態」のファイルには、左に共通祖先..HEADの変更、右に共通祖先..MERGE_HEADの変更の記号が表示される。通常は「U:衝突」が2つ並んだ表示になるが削除されたファイルなどだと片方が「D:削除」になったりする。
「ステージ状態」「未ステージ状態」のファイルには、左にHEAD..ステージの変更、右にHEAD..作業コピーの変更が表示される。

■参考URL
[Git - ブランチとマージの基本](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%A8%E3%83%9E%E3%83%BC%E3%82%B8%E3%81%AE%E5%9F%BA%E6%9C%AC)

https://qiita.com/te2u/items/c23f82ec84cf65564554
【PHP初級㉖】switch文（条件分岐）

［問題］　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksPrimary.html)
整数値を入力させ、その値が1ならone、2ならtwo、3ならthree、それ以外ならothersと表示するプログラムをswicth-case文を使って作成しなさい。




# コード
```php
switch(intval(fgets(STDIN))){
    case 1:
        echo 'one';
        break;
    case 2:
        echo 'two';
        break;
    case 3:
        echo 'three';
        break;
    default:
        echo 'others';
}
```

↓「4」と入力


# 結果
```
others
```

↓間違えたところ
```php
switch($a = intval(fgets(STDIN))){
```
ここでは変数に代入する必要なし。



☆switch文（条件分岐）
　switch (式){
　　case 値1:
  　　　式が値1と等しい場合の処理1;
  　　　break;
　　case 値2:
  　　　式が値2と等しい場合の処理1;
  　　　break;
　　case 値3:
  　　　式が値3と等しい場合の処理;
  　　　break;
　　default:
  　　　式がいずれの値にも等しくない場合の処理;
　}


☆if文を使ってもできるが、この問題ではswitch文を使ったほうが便利。
Next.jsの環境を整備する（Mac）

作りたいアプリができ、せっかくなので流行のフロントエンドの技術を合わせて試してみます。今回はNext.jsを使うため環境を整備していく。

## やりたいこと
Next.jsのチュートリアルを進める
（Node.jsはインストール済み）

### Next.jsの環境整備
https://nextjs.org/learn/basics/create-nextjs-app
上記に沿って進める

https://nextjs.org/learn/basics/create-nextjs-app/setup

PJを作るコマンド実行

```sh
$ npx create-next-app nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
$ cd nextjs-blog
$ npm run dev
```

### ブラウザで確認する
http://localhost:3000

いけました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/f58ff12b-f19c-8f6e-77af-142d435b9a53.png)

サーバサイドはTypescprit/フロントエンドはNext.jsで進めます。Vue.jsやNuxt.jsは昔使ったことがありますがそれとの比較なども含めて使っていきたい。

## dockerにデプロイする
公開時にはdockerを使うので最初からdockerで動かしておく。

以下を参考に進めます
https://nextjs.org/docs/deployment
Docker Image

```
$ npx create-next-app --example with-docker testapp
$ docker build -t testapp .
$ docker run -p 3000:3000 testapp
```

## Next.jsをTypeScriptにする


画面が参照できました。順次進めていきます。
Herokuでリダイレクトする方法（Python3・Flask）

# TL;DR
- Herokuでは`.htaccess`によるリダイレクトが動作しなかった。
- `flask.redirect`を使ってゴリ押しする。

# `.htaccess`について（不可）
[[Heroku]herokuでhttpでのアクセスをhttpsへリダイレクトさせる設定](http://kayakuguri.github.io/blog/2015/03/03/heroku-force-https/ "[heroku]herokuでhttpでのアクセスをhttpsへリダイレクトさせる設定 - KayaMemo")など、複数のサイトを参考に以下のように作成・アップロードした。
```.htaccess
# リダイレクトを設定する宣言
RewriteEngine on
# X-Forwarded-Protoが設定されているときに作動
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
# HOST,URIを指定して転送
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
```
httpでアクセスしたが、転送されなかった。
原因については不明だが、Pythonを使っているなどの環境が悪い気がする。

# `flask.redirect`について（可）
[PythonのFlaskでhttpからhttpsにリダイレクトする](https://www.mathpython.com/ja/flask-https-redirect/ "PythonのFlaskでhttpからhttpsにリダイレクトする - MathPython")を参考に、以下のように作成した。
```python
from flask import Flask, redirect

app = Flask(__name__) # おまじない

# デコレーターを設定
@app.before_request
def before_request():
    # httpでアクセスしているとき・開発環境のとき以外で作動
    if not request.is_secure and app.env != 'development':
        # URLの"http"を"https"に置き換え
        url = request.url.replace('http://', 'https://', 1)
        # レスポンスステータスコードを"301"に設定
        code = 301
        # 転送
        return redirect(url, code=code)

# (略)
```
httpでアクセスすると、301リダイレクトされる。
基本情報（ハードディスク以外の補助記憶装置）

補助記憶装置にはハードディスクの他にもさまざまな種類があります。
光ディスク（CD、DVD）とか光磁気ディスク（MD）とかメモリカードなど色々。

駆動装置（DVDを読み込む機械）から簡単に取り出せる媒体を**リムーバルメディア**といいます。
下記にその種類を書いていきます。

## 光ディスク
「レーザ光線によって、データの読み書きを行う」のが**光ディスク装置**です。

**CD（Compact Disc)**
音楽用のCDと同じディスクを、コンピュータの記録媒体として利用したものです。
直径12cmの光ディスクで、記憶容量は650MBと700MBの2種類。
安価で大容量なことから、ソフトウェアの配布媒体としても広く使われています。

ディスクの種類には書き込みができない読み込み専用の再生専用型と、一度だけ書き込める追記型、何度でも書き換えができる書き換え可能型の３種類があります。

|  CD-ROM   |  CD-R   |  CD-RW   |
| :---: | :---:| :---: |
|   読み込み専用。再生専用型のCD  |  一度だけ書き込める。追記型のCD  |  何度でも書き換えができる。書き換え可能型のCD|

**DVD(Digital Versatile Disc)**
映像用のDVDと同じディスクを、コンピュータの記録媒体として利用したもの。
基本的な特徴はCDと同じ光ディスクのため、CDよりも波長の短い赤色レーザで記録するため、ビットの高密度化が可能となって、より大容量を実現している。

|  DVD-ROM   |  DVD-R   |  DVD-RW   | DVD-RAM |
| :---: | :---:| :---: | :---: |
|   再生専用型のDVD  |  追記型のDVD  |  書き換え可能型のDVD|  書き換え可能型のDVD|

ROMはRead Only Memoryの略で読むだけ。
RはRecordableの略で１回だけ記録できる。
RWはReWritableの略で書き直しができる。

## 光磁気ディスク(MO: Magneto Optical disk)
レーザ光線と磁気によってデータの読み書きを行うのが**光磁気ディスク装置**。
フロッピーディスクの後継として一時は広く使われていたが、光ディスクの大容量低価格化の波に押されて、ほとんど見なくなった。

## まとめ
量が多いので後日、引き続き書きます。
フロッピーディスクとかメモリカードとかほとんど今は使えないので死語ですね。
CDーRとか音楽を入れて、友達に渡していたりしましたが全くなくなったのでだいぶ古い内容だなーと思いました。
プロキシ下のk8sクラスタ構築で詰まったこと

# 概要
プロキシ環境下でKubernetesクラスタを構築した際に、プロキシ関連で詰まったことがあったのでメモとして残しておきます。ただ、構築してから時間がたっているため発生したエラー等は残せていません。また、Kubernetesクラスタの構築についても詰まったところのみ記事にしています。構築してた当時は全然記事が無かったので解決に時間がかかりましたが、今はそこそこ記事があるのでトラブルシュートしやすいかもしれません。

# 環境
- 外部との通信でプロキシを経由する必要がある
- クラスタ構築にはkubeadm，kubelet、クラスタ内のノード間通信にはcalicoを使う
- マスター1台，ワーカー2台（全てプロキシ下に配置）
- Kubernetes以外のこと（apt，wget等）のプロキシ設定については既に済ませている

## Kubernetesクラスタの構築
通常通りkubeadm，kubelet，kubectl，containerd等をインストールする。
（省略しますが後日追記か別に記事を書くかもしれません）

# 詰まったこと
- containerd のプロキシ設定
- ノード間の通信設定

最後の方に設定をまとめて書いてます。

### containerd のプロキシ設定
dockerhubからコンテナイメージを取得できませんでした。エラーを確認したところプロキシっぽかったのでcontainerdにプロキシの設定を追加したところこのエラーは解決しました。

### ノード間の通信設定
プロキシ環境下のコンピュータでは外部との通信のために環境変数等でプロキシを用いるように設定すると思います。通常は同じネットワーク下であればプロキシを使わずに通信を行いますが、Kubernetesクラスタでは10.96.0.0/12のようなIPアドレスで通信を行うためプロキシを経由して通信を行おうとします。そのため、ワーカーノードをクラスタへ追加することはできますがノード間通信に失敗するためpodが動きません。これは、containerdの設定でクラスタ内の通信にプロキシを使わないように設定すれば解決出来ました。

### 設定内容
設定ファイルは存在しないかったので作成したと記憶しています。
```config:/etc/systemd/system/containerd.service.d/http-proxy.conf
[Service]
Environment="NO_PROXY=10.96.0.0/12"
Environment="HTTP_PROXY={proxy}:{port}"
```

## 必要だったか不明の設定
いろいろ調べていた際に、calicoを使うためにはkubeletのcniオプションを有効にする必要があるらしいので有効にしました。
（kubeadm-flags.envに追記）
```config:/var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=/run/containerd/containerd.sock --pod-infra-container-image=k8s.gcr.io/pause:3.6 --network-plugin=cni"
```

# 参考URLとその他
- kubeadmを使ったKubernetesクラスタの構築
    - https://thinkit.co.jp/article/18188
- ノード間の通信にプロキシを使用しない設定
    - https://github.com/golang/go/issues/16704
- kubeletの設定
    - https://qiita.com/fastwind/items/b4229a3f360e7cd5b8e2#calico%E3%81%AE%E8%A6%81%E4%BB%B6%E3%81%AF
- トークンの有効期限が切れた場合
    - https://zaki-hmkc.hatenablog.com/entry/2020/04/05/103651
- もっとわかりやすそうな記事
    - https://qiita.com/nakkoh/items/9d4b58d57c8a71a6d97c
AWS Amazon Athenaの用語要点まとめ（自分用メモ

・Amazon Athena
Amazon S3上のデータに対して標準SQLを実行できるデータ分析サービス。
サーバーレスなので、EC2インスタンスなどのインフラ（実行環境）のセットアップや管理が不要。
データ分析に利用できるサービスにはAmazon EMRやAmazon Redshiftなどがありますが、いずれもインスタンスやクラスターなどのインフラの管理が必要です。Athenaはこのような考慮をすることなく、プロトタイプの検証や手早く分析をしたいようなケースに向いています。また、S3上に出力される様々なAWSのサービスのログをAthenaで分析するといった使い方もできます。

実行結果は事前に設定したS3バケットへ自動的に保存されます。また、作成したSQLクエリは保存することができ、再実行も簡単に行えます。
Athenaの料金は、SQLクエリの実行時にスキャンしたデータ量を基に決定されます。2022年4月現在では、1TBごとに5USドルが設定されています（東京リージョン）。

■Athenaのデータ形式
Athenaは、CSVやJSONなど一般的なデータ形式に加えて、Hadoopでも利用可能なParquetなどのデータ形式にも対応しています。
※Hadoop（ハドゥープ） … ビッグデータ向けの並列分散処理を行うオープンソースのミドルウェア。AWSではAmazon EMRがHadoopに対応している。

Athenaを利用するには、これらのデータを基にテーブルを作成します。各カラム（列）の名称とデータ形式（文字列型、数値型、日付型など）を入力してテーブルを作成したのちに、クエリを実行できるようになります。

■Amazon QuickSightとの連携
Amazon QuickSightは、サーバーレスに大容量データを分析し経営に役立てるためのBIサービスです。ExcelやCSV、Amazon Redshiftのデータベースなど、様々なデータソースを基にダッシュボードやレポート、グラフを作成してデータを可視化し、データ分析に役立てます。


Athenaで作成したテーブルはQuickSightと連携してグラフ化できます。AWSサービスのログを分析したいような場合、Athenaでテーブルを作成し、作成したテーブルを対象にQuickSightでグラフ化するといった運用が可能