OmniAICreator/Qiita-1.07M huggingface dataset:
GCP PCA合格記(2023/2/3投稿)

# はじめに
この度GCP認定のGoogle Cloud Certified - Professional Cloud Architectを受験してきましたので、勉強した内容と受験した感想を書いておきます。
これから受験される方の参考になれば幸いです。

# 前提
* Google Cloudはほぼ触ったことなし
* AWSの実務経験あり
* AWS認定は全て取っています(詳細は[こちら](https://qiita.com/handy-dd18/items/d21d914bf1c475d777f2))
    * [SAP on AWS認定](https://qiita.com/handy-dd18/items/18e8a856906f97bbb964)も取ってます

# 参考URL
この方の記事が参考になりました。ありがとうございます。
https://o2mamiblog.com/google-cloud-professional-cloud-architect-test/

# 学習内容
今回は以下の順番で勉強を進めました。
[前回](https://qiita.com/handy-dd18/items/46c21bed41405fdfe5ec)とほぼ同じですが、書籍はある程度サービス名とその用途を思い出したら問題を解くことに注力しました。

* ①書籍([GCPの教科書](https://www.amazon.co.jp/dp/B07S1LG1Y1/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1))
* ②[公式模擬問題](https://cloud.google.com/certification/cloud-architect?hl=ja)
* ③練習問題([Udemy](https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/?utm_source=aff-campaign&LSNPUBID=M*j*hKkY1io&utm_medium=udemyads&ranMID=47984&ranSiteID=M.j.hKkY1io-Xk1J5VyOBEf_kAWcGVokbQ))

## 書籍
最初に前回もやったように、[GCPの教科書](https://www.amazon.co.jp/dp/B07S1LG1Y1/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)でGoogle Cloudの全体的なサービスについてざっくりと学習しました。(結構忘れていたので)
受験前はさらっと流す程度しか読まなかったのですが、受験してみて感じたのは思ったよりもサービスの詳細について即答できないところが多かったので、もう少し読み込んでおくべきだったと思いました。

## 公式模擬問題
ACE試験の時と同じように、書籍でサービスについてある程度理解したら、公式の[模擬問題](https://cloud.google.com/certification/practice-exam/cloud-engineer?hl=ja)を解いてどのような問題が出題されるのかを把握しました。
ケーススタディ問題は実際にどのような問題が出題されるのかをイメージするのにかなり役立ちました。

## 練習問題
Google Cloud認定はAWSでよく使っていたkoiwaclubに(ACEを除いて)問題がないため、[Udemyで公開されている練習問題](https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/?utm_source=aff-campaign&LSNPUBID=M*j*hKkY1io&utm_medium=udemyads&ranMID=47984&ranSiteID=M.j.hKkY1io-Xk1J5VyOBEf_kAWcGVokbQ)を購入して勉強しました。
Udemyには50問セット×3つと20問セットが1つ含まれていましたが、実際には50問セット2つを1周して間違えた問題の解説を読み込む方法で勉強しました。
時間があまりとれなかったのもありますが、問題の傾向が大体把握できたのでそこまで周回しなくても問題はなかったです。

# 受験した感想
余裕でした笑、と言いたいところだったのですが、何だかんだ残り時間が20分になるまでは時間を使ってました。
考えるのに時間がかかりそうな問題はフラグつけて適当に回答して、全問回答したあとに時間をかけて再回答しました。
個人的にはその方法が一番考える時間が確保できて焦る必要がないので、別のGoogle Cloud資格を受ける時も同じやり方をしてみようと思います。

# 受験結果
無事に合格することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/033ccb52-183e-21ea-d5cb-f360c36535f3.png)

試験後結果自体はすぐに表示されましたが、正式に合格メールが届いたのは受験の2日後でした。

# おわりに
Azure側の試験をいくつか取れたので、取得できていなかったGoogle Cloudのプロ資格に挑戦してみました。
結果としては合格でしたが、実務で触れていない分どうしても知識的に足りていないところがあるので、ところどころで自信をもって回答できない問題が出てきていたので、極力お金がかからない方法で実機を触る機会を増やしたほうが良いと思いました。

次は同じくGoogle Cloud認定のProfessional Cloud Security Engineer試験を受験予定です。

この記事がどなたかの参考になれば幸いです。
【Django】テンプレートでリダイレクト先のパスとクエリ（パラメーター）を設定する

Djangoのテンプレートファイルのhrefでリンク先のURLを設定する際にパラメーターも同時に設定する方法の備忘録
## href
~~~html
<a href="{% url "apps:sample_page" sample.id %}?sample_query={{ sample.query }}"
~~~

パスは`{% url "" %}`内に上記の`sample.id`のように追加するだけ。
クエリは`{% url "" %}`の外に上記の`?sample_query={{ sample.query }}`のように追加するだけ。

## redirect
~~~python:views.py
redirect_url = reverse('apps:sample_index')
parameters = urlencode({'param1': 'sample_param', 'param2': 123})
url = f'{redirect_url}?{parameters}'
return redirect(url)
~~~
Spring Bootのresourcesファイルを読み込む

# 挨拶
どうも、はじめまして。
お久しぶりの方はお久しぶりです。ミツクマです🐻

今回は、Spring Bootのresourcesにあるファイルを取得する方法を書いていきます。

# はじまり
resourcesファイルに動画ファイルを設置して、Controllerから取得するといった流れで
実装しようとしたところ、resourcesのファイルが取得できませんでした。

```java
Path path = Paths.get("resourcesのパス");
```
で取得しようとしたのですが、NoSuchFileExceptionと表示されうまくいきませんでした。

# 原因の追究
パス指定がダメなのかと思い、色々と試したのですがダメでした。
試した内容としては、

- "classpath:相対パス"
- "filepath:絶対パス"
- "相対パス"のみ

と試したのですがダメでした。

# 私の場合の解決法
これに関しては、あくまで一例なのですが **ClassPathResource** を使用して解決しました。

```java
Resource resource = ClassPathResource("resources以降のパス");
``` 

これで取得することができました。
ClasspathResourceは、getFile(),getPath()メソッドがあるため、
ファイルの取得、パスの取得ができます。

これによって私がやりたかったことができました。
他にも、 **UrlResource , FileResource** があります。
それぞれの用途で適したものを使用すればいいと思います。


# 最後に
今回は、resourcesにあるファイルの取得について紹介させていただきました。
未だ分からないことばっかで、稚拙な記事ではありますが継続して投稿していきたいと思います。
それでは、また別の記事でお会いできれば幸いです。ミツクマでした～🐻
気軽にJavaのコード検証したいだけ

# はじめに
「気軽にJavaの勉強がしたいよ～」と思ったわけです。

# 前提環境
・M1 Mac mini
・docker
・kubernetes

# コンテナ作成
Dockerfileを作成しました。

```shell-session:M1 Mac mini (%はMacOSのシェルプロンプト)
% vi Dockerfile
```

```Dockerfile:Dockerfile
FROM ubuntu:jammy
ARG DEBIAN_FRONTEND=noninteractive

RUN apt update &&\
    apt upgrade -y
RUN apt install -y \
    python3 \
    python3-pip \
    openjdk-11-jdk \
    git \
&&  ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
&&  apt clean \
&&  rm -rf /var/lib/apt/lists/*

ENV TZ=Asia/Tokyo

RUN pip3 install --no-cache-dir \
    jupyterlab \
    jupyterlab_code_formatter \
    jupyterlab-git \
    jupyterlab_widgets \
    jupyterlab-language-pack-ja-JP

RUN git clone https://github.com/SpencerPark/IJava.git &&\
    cd IJava/ &&\
    ./gradlew installKernel

CMD ["jupyter-lab","--allow-root","--ip=0.0.0.0","--port=8888","--no-browser","--NotebookApp.token=''"]
```

buildします。

```shell-session:M1 Mac mini
% docker build -t jupyterlab:latest .
```

そのままdockerで使うなら以下のコマンドで。

```shell-session:M1 Mac mini
% docker run --rm -p 8888:8888 -it jupyterlab:latest
```

コードや設定を保存したいならどこかのディレクトリをボリュームマウントしてください。

# kubernetesで使う
kubernetes用のレジストリに突っ込みます。

```shell-session:M1 Mac mini
% docker build -t 10.0.0.1:30500/jupyterlab:latest .
% docker push 10.0.0.1:30500/jupyterlab:latest
```

namespaceを作って、podとsvcをapplyします。

```shell-session:kubernetes
$ kubectl create namespace jupyterlab
$ vi jupyterlab-pod.yaml
```

```yaml:jupyterlab-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: jupyterlab
  namespace: jupyterlab
  labels:
    app: jupyterlab
spec:
  containers:
  - name: jupyterlab
    image: 10.0.0.1:30500/jupyterlab:latest
    resources:
      requests:
        cpu: 1
        memory: 1.5Gi
      limits:
        cpu: 1
        memory: 1.5Gi
    ports:
    - name: jupyterlab
      containerPort: 8888
```

```shell-session:kubernetes
$ kubectl apply -f jupyterlab-pod.yaml
$ vi jupyterlab-svc.yaml
```

```yaml:jupyterlab-svc.yaml
apiVersion: v1
kind: Service

metadata:
  name: jupyterlab
  namespace: jupyterlab
  labels:
    app: jupyterlab
spec:
  type: NodePort
  ports:
    - name: http
      port: 8888
      targetPort: 8888
      nodePort: 31888
  selector:
    app: jupyterlab
```

```shell-session:kubernetes
$ kubectl apply -f jupyterlab-svc.yaml
```

# おわりに

NotebookでJavaが使えます。
コードはある程度適当(import書かず)でも動きますし、逐一コンパイルしなくていいのは楽です。
![FnkiaevaQAAaGZx.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/436de60e-11da-3e65-4dea-4698c0fbfe4b.jpeg)

簡単なコード検証したいだけなので、これで満足です。
laravelで個別にログファイルを出力する

まずは、ログ出力の設定から。
ログの出力設定はconfig/logging.phpで設定する

```config/logging.php
'hoge' => [
    'driver' => 'daily',
    'path' => storage_path('logs/hoge/hoge_log.log'),
    'level' => 'info',
    'days' => 3, //保存期間
    'permission' => 0664,
],
```
あとは、出力したいControllerとかに
以下のログ出力用のコマンドを渡してあげればよい

```HogeController.php
Log::channel('hoge')->info('なんかのログ', ここは配列);
```

テストしたいだけだったら以下を入れてみる。
```HogeController.php
Log::channel('hoge')->info('test');
```
PyCaretのドキュメント解読: Classification evaluate_model()関数

PyCaret使いこなしのために公式ドキュメントの解読を決意してClassificationのsetup()関数、compare_models()関数のドキュメントを解読。続いてはClassificationのevaluate_models()関数のドキュメント。

```python:evaluate_models()のオプション概要
pycaret.classification.evaluate_model(
  estimator,
  fold: Optional[Union[int, Any]] = None,
  fit_kwargs: Optional[dict] = None,
  plot_kwargs: Optional[dict] = None,
  groups: Optional[Union[str, Any]] = None,
  use_train_data: bool = False
)
```

# 関数の説明
この関数は学習済みモデルの性能を分析するためのユーザーインターフェースを表示します。内部でplot_model()関数を呼び出してます。

:::note warn
注意
* この関数はIPython Notebook(Jupyter Notebook)上でのみ動作します。
:::

# 実行例

```python
from pycaret.datasets import get_data
from pycaret.classification import *

juice = get_data('juice')
exp_name = setup(data = juice,  target = 'Purchase')
best = compare_models()
evaluate_model(best)
```

# 必須パラメータ

## estimator
* 形式: scikit-learn互換オブジェクト
* 説明: 学習済みモデルを渡します。

# オプションパラメータ

## fold
* 形式: int, scikit-learn互換CV生成器
* デフォルト値: None
* 説明: 交差検証を制御します。もしNoneに設定した場合、setup()関数のfold_strategyパラメータで設定したものが使われます。整数値が渡された場合、もし整数値が渡された場合、setup()関数におけるCV生成器の<font color="RED">n_splits</font>パラメータと解釈されます。

## fit_kwargs
* 形式: dict
* デフォルト値: {}(空のdict)
* 説明: モデルのfit()関数に渡す(キーワード)引数のディクショナリです。

## plot_kwargs
* 形式: dict
* デフォルト値: {}(空のdict)
* 説明: ビジュアライザークラス(可視化機能)に渡す(キーワード)引数のディクショナリです。

## groups
* 形式: str, (n_shapses,)の行列形式
* デフォルト値: None
* 説明: 交差検証にGroupKFoldを使用する場合のオプションのグループラベルを設定します。 (n_samples,)の行列形式で渡します。n_samplesは学習データの行数です。 文字列が渡されると、グループラベルの値と等しいデータセット内の列名として解釈されます。

## use_train_data
* 形式: bool
* デフォルト値: False
* 説明: Trueを設定した場合、テストデータの代わりに、学習データを結果のプロットに用います。

# Reference
https://pycaret.readthedocs.io/en/latest/api/classification.html#pycaret.classification.evaluate_model
Node.js で pandas ライクなデータ処理を行う

# Pandasとは?
pandas は python でデータ処理を行う時に、大変優れた機能を提供してくれるライブラリです。
csv の読み込みはもちろん、DBからの読み込みも可能ですし、
メソッド一つで統計量の計算、結合処理までやってくれるスグレモノなんです。
ですがこれ、pythonでしか使えないんです。
しかし！！それを解決してくれる素晴らしいライブラリがありました！！

# その名はDanfo
それがこのDanfo.jsです。
https://danfo.jsdata.org/

Danfo.jsはオープンソースライブラリで、pandas ライブラリに大きく影響を受けている、
と書かれています。
つまり、Node.jsでpandasのノウハウを使えるということです。これは素晴らしい。

# 使い方
Nodeでのインストールは以下
```
npm install danfojs-node
```
特に難しいこともなくインストール可能です。

使用方法は、
https://danfo.jsdata.org/getting-started
に詳しく書いてあります。

それではよき統計ライフを！
HPKP（証明書ピンニング）について調べた時のあれこれ

# きっかけはAWS
先日AWSさんより以下のお達しがありました。
> 背景：
>　2023 年 2 月 1 日から 2023 年 3 月 31 日までの間に、Amazon は Amazon が発行したすべてのパブリック証明書を、旧来の中間 CA, intermediate certificate authority (ICA) から、2022 年 10 月に導入された複数の中間 CA (ICA) /下位認証局のいずれかに移行します。
> ※証明書のピン留めによって既存の ICA 情報を明示的に利用しない限り、お客様による操作は必要ありません
>参考：AWSドキュメント
> https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/troubleshooting-pinning.html


この「※証明書のピン留め」というのが証明書ピンニングというものだそうです。
参考：https://www.digicert.com/jp/blog/certificate-pinning-what-is-certificate-pinning

# 何がマズいの？
認証局を移行する => 違う証明書が必要になる = 今までの証明書が使えない = **通信断‼** = ~~悪即斬‼~~

### AWSさんからの指令：証明書pinning をしていると影響がある可能性ありますので、確認いただけると助かります。
OK、**完全に理解した**。
証明書がピンニングされてるかどうか調べればいいんですね。
楽勝楽勝~~（フラグ）

とりあえずACMにあるパブリック証明書を確認してみよう。

あれ、設定ひと通り見たけどそれっぽいものが無い。。。

いや、証明書はどうやらロードバランサーに紐づいてるからそっちを見てみよう。

リスナーの「Default SSL Cert」に設定されてることは分かったが

分かったが？・・・分からん。

僕「Google先生～、証明書 ピンニング 確認方法～」

G先生「これとかこれとか、こんなんどう？、知らんけど」

### ダメだ、解決できない（汗）

途中 teratail で同じ質問してる同志がいたが、あとから様子見に行くと削除されてた。。。

これは言い出しっぺ？のAWSさんに聞くしかない。

僕「AWSさん、たすけて」

AWSさん「参考：https://developer.mozilla.org/ja/docs/conflicting/Web/Security/Certificate_Transparency 」


>HPKP の有効化
サイトでこの機能を有効化するには、サイトに HTTPS でアクセスされたとに、 HTTP の Public-Key-Pins (en-US) ヘッダーを返す必要があります。
>Public-Key-Pins: pin-sha256="base64=="; max-age=expireTime [; includeSubDomains][; report-uri="reportURI"]

なるほど、このページはピンニングする側の確認方法ではないけれど、
ピンニングした証明書を使ってアクセスするためには、**アクセスされるサーバー側にPublic-Key-Pins (en-US) ヘッダーを返す設定が必要**なのね。
つまりサーバー側にその設定がされてるかどうか確認すればいいと。

よし、
#### 開発チームに依頼しよう（ぶん投げ）

というわけで調査依頼を出して終了したのでした。
めでたしめでたし

## そもそも
https://www.digicert.com/jp/blog/certificate-pinning-what-is-certificate-pinning
こちらでも言及されている通り、
>Googleは、2011年（英語リンク）にChromeブラウザでメインWebサイトの発行認証局をピン留めしたことで、最初にピン留めを利用し始めた例の1つとなりました。
>~
>中略
>~
>安全かつ確実にピン留めを実装することの難しさから、サイトの保護よりもピン留めにより弊害が起こるケースが増えてきました。これらを含む多くの問題が見つかり、やがてGoogleとFirefoxはHPKP導入後わずか数年後にサポートをやめることになりました

2011年から数年後には**非推奨**となっており、プロジェクト担当のAWSさんも「おそらく大丈夫でしょう」とコメントされていました。

# 所感
HPKP自体は既に非推奨となってしまった技術で、これを知ったからと言って自分が開発するサービスに役立つかというと必ずしもそうではない確率が高い。
***だがしかし***、
インターネットの歴史の一端を垣間見れた気分で個人的には楽しかった。
（本音：~~お金貰って勉強できるの最高～~~）
macOSには`sg`コマンドがない。

# はじめに

Linuxには`sg`というコマンドがありまして[^1]。
[^1]: https://man7.org/linux/man-pages/man1/sg.1.html

`sg`を使うことで一時的に別のグループでコマンドを実行できるわけです。

たとえば

```console
sg mygroup -c 'echo $(id -g -n)'
```

とすれば、

```console
mygroup
```

と表示されるわけです。

でもmacOSのターミナルで同じことを実行しようとすると…

```console
zsh: command not found: sg
```

無情にも`sg`コマンドが見つかりません。


# 解決策: `newgrp`を使う

`newgrp`は単独で実行すると`exit`するまで指定したグループでコマンドを実行できるという優れものですが、そのままではシェルスクリプトで使うには不便です。
でも、大丈夫。
`newgrp`の標準入力にコマンドを渡すと、`sg`と同じようにその時だけ別のグループでそれを実行してくれるのです。
具体的には次のようにします：

```console
echo 'echo $(id -g -n)' | newgrp mygroup
```

```console
mygroup
```

やったぜ👍

そして、`newgrp`はLinuxにも存在しているので、macOSでもLinuxでも両方で動くシェルスクリプトを書きたければ、`newgrp`を使えばOK。


という小ネタでした。
Terminalをカスタム

brew install
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
iterm2 install
```
brew install --cask iterm2
```
git install
```
brew install git
```
oh-my-zsh install
```
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
```
powerlevel10k install
```
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
```
vimで~./zshrcを開く
```
vim ~./zshrc
```
↓ZSH_THEME="robbyrussell"を
```
ZSH_THEME="powerlevel10k/powerlevel10k"
```
に置き換え

```
source ~./zshrc
```
⌘qで一回閉じて再度開く
JANOG51 NETCON level1-2問題解説

# はじめに
JANOG51 NETCONにご参加いただいた皆様ありがとうございました。
今回、育成枠として初めて問題作成に携わりました。
本記事ではJANOG51 NETCONにて出題した「level1-2」について解説します。



# 問題文
>新入社員は既存の設定が入ったルータに新たなルータを接続し、ネットワークの勉強することにした。
>既存のルータ設定に合わせて、設定を行ったところ、 PC間で通信ができないようだ。
>各PC間で通信が通るように解決してほしい。
>ゴール
>linux2に対してlinux1からpingが到達すること。
>制限事項
>n9kv2の設定を削除することは禁止とする。
>linuxコンテナのインターフェイスに新たにipアドレスを追加しないこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114078/9fef2f6f-82d6-fe44-14d0-41a77c1ea263.png)






### 問題点

この問題には二つの問題点が存在しました。

1.n9kv1のinterface Ethernet1/2がshutdownしていること
2.n9kv2のACLにおいてPC間でpingを飛ばすために必要なicmpの許可設定が入っていないこと

各問題点につき、50％ずつの配点となっています。



# 解法

### 「1.」の解法

n9kv1のinterface Ethernet1/2でno shutdownを行います。
```n9kv1:サンプルコマンド
n9kv1# conf t
n9kv1(config)# interface Ethernet 1/2
n9kv1(config-if)# no shutdown
```
n9kv1の各interfaceにおける最終config
```n9kv1:最終config
interface Ethernet1/1
no switchport
ip address 192.168.20.1/24
ip router ospf 100 area 192.168.10.1
no shutdown
```
```n9kv1:最終config
interface Ethernet1/2
no switchport
ip address 192.168.10.1/24
ip router ospf 100 area 192.168.10.1
no shutdown
```

### 「2.」の解法
n9kv2に存在しているACLを確認すると PC間でpingを飛ばすために必要なicmpの許可設定が入っていません。
ACLには暗黙のdenyが存在しているため、ACLにpermitを入れる必要があります。
解法例としては、n9kv2のinterfce1/2にあるACLにipかicmpでpermit any anyを追加することが挙げられます。

以下本問題における解答の一例です。


```n9kv2:サンプルコマンド
n9kv2# conf t
n9kv2(config)# ip access-list acl01
n9kv2(config-acl)# permit icmp any any
(n9kv2(config-acl)# permit ip any any)
```
※この際anyの部分を疎通をするうえで必要なものだけに限定しても構いません。


n9kv2のaccess-listにおける最終config
```n9kv2:最終config
ip access-list acl01

…

129 permit icmp any any

(129 permit ip any anyでも可)
```

# 最後に

いかがでしたでしょうか。
今回の問題は私が実際にネットワークの勉強をしている際に、躓いたものを問題にしました。
様々な回答を見ていると、とても勉強になり私にとってもいい機会になりました。

今回はNETCONにご参加いただきありがとうございました。
【Javascript】dotenv　環境変数でUSERNAMEが取れない

## javasciptのコードでUSERNAMEが取得できない
DBに接続するため、環境変数を設定をしていたが、`USERNAME`がおかしい

## logで確認
```javascript
console.log("USERNAME")//PCに設定しているusername
```
usernameはすぐに設定されているようだ。

USERNAME→NAMEにしたところ.envファイルで指定した環境変数を取得できた
PythonによるCSVの読み書き(備忘)


ほぼほぼフルオプション指定のCSV/TSV読み書き

```python
import csv

# CSV/TSV出力サンプル
# - ヘッダーあり
# - 最低限のクォート処理
# - null値の表現あり(null)
header = ['a','b','c','d']
with open('sample.csv', 'w') as f:
    w = csv.DictWriter(f, 
        header,             # ヘッダー指定
        dialect='excel',    # dialectはExcelを指定
        delimiter="\t",     # 区切り文字
        restval="(null)",   # 指定がなければ空白
        quotechar='@',      # データに改行があるときの囲み文字
        quoting=csv.QUOTE_MINIMAL   # 最低限の囲み文字
    )
    w.writeheader()
    w.writerow({
        'a': 123,
        'b': 456,
        'c': 'abc\ndef\n\"abc@def\tghi\"\n'
    })

    # 出力
    # a	b	c	d
    # 123	456	@abc
    # def
    # "abc@@def	ghi"
    # @	
    

# CSV/TSV読み込み
# - ヘッダーあり
# - 最低限のクォート処理
# - 囲み文字指定(@)
with open('sample.csv', 'r') as f:
    r = csv.DictReader(f, 
        dialect='excel', 
        delimiter="\t", 
        quotechar='@',
        quoting=csv.QUOTE_MINIMAL)

    for row in r:
        print(row)
    
    # 出力
    # {'a': '123', 'b': '456', 'c': 'abc\ndef\n"abc@def\tghi"\n', 'd': ''}

```
【初心者】Docker+Django+MySQLで環境構築 その2




Djangoチュートリアルを復習していて、あまり書けなかったのですが
前回の続きから書いていきます。前回記事はこちら↓

https://qiita.com/ri-tama/items/328446e5194f40877cf7




前回はdjangoが動く所までを実装しました。

今回は
・アプリの作成
・アプリの初期設定

をやっていきます。

## アプリの作成


```terminal
C:\Users\ri-tama\django> docker compose exec web bash
ri-tama@5c77eaec699c:/code#
```

docker以下のコードを打つことによりコンテナ内へ入ることができました。(web部分はコンテナ名です)
ちなみにユーザーネーム@以後の数字と英語の羅列はコンテナのIDを表示しています。

```terminal
ri-tama@5c77eaec699c:/code#python3 manage.py startapp sampleapp # (任意の名前)
```

上記コマンドを打つことによりアプリが作成されます。
(ディレクトリ内にsampleapp等の名前がついたディレクトリが作成されれば成功です)


```terminal
ri-tama@5c77eaec699c:/code#exit
```

ちなみにexitと打てばコンテナ内から外に出ることが可能です。

## appの設定

ここからはDjangoの領域になります。
アプリ作成が終わった後は初期設定として2つやることがあります。
・プロジェクト内にあるsettings.pyの中のappに作成したアプリを登録すること
・プロジェクトからアプリへの繋ぎこみをすること

検索すればどこにでも出てくる情報だとは思いますが一応記します。
### 作成したアプリを登録する方法

```python
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'sampleapp.apps.SampleappConfig', # ここを書きます！
]
```

### プロジェクトからアプリへ繋ぎこみする方法 

``` python
from django.cintrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('sampleapp.urls')),#ここを書きます！
]
```


という感じで、簡単な部分でしたがまとめました。
コンテナ外で作業してたのに、コンテナの中で作業することに！
やってみると意外と簡単。

またターミナル上で
キーボードの上下矢印キーを使ってコマンドの履歴を呼び出せるのが非常に便利です。
積極的に使っていきましょう。


読んでいただきありがとうございました。
競技プログラミングを始めてよかったこと

本記事は競技プログラミングを始めてよかったことを記載している。

### 本記事の対象者
　　・競技プログラミングを始めたことがない非情報系の学生
　　・競技プログラミングに興味がある
　　・主にAtcorderを中心に始めたい方
    
### 筆者のステータス
　　・学部～修士で研究でしかプログラムを書いたことがない
　　・実験物理で実験に必要なプログラムを作成する程度
　　・使用言語はC++,python
　　・競技プログラミング歴は数週間程度
   

## なぜ競技プログラミングをはじめたか
　　エンジニア職を中心に就活する上でコーディングテストが必須であり、テスト対策として始めた。

# 競技プログラミングを始めてよかったこと
　　1.少なくとも一つの言語が検索をしなくても、スムーズに書けるようになる
　　2.時間のかかる処理を意識するようになり、研究でも活きる
　　3.いろんな人のコードを読むことで、知らなかった関数などを知ることができる
　　4.アルゴリズムを効率よく学べる
　　5.就活に役立つ
    6.人によっては趣味になる（＝おもしろい）

## 就活ではどう役立つのか？ 
エンジニア職を希望する場合に限るが 
　　1.コーディングテストが開催されいている企業では対策になる  
　　2.企業によってはAtCorderのレートなどが問われることがあるため、有利になるかも？

### 補足：就活に特化するなら
　　1.paizaはスキルチェックを受けておくと大手からスカウトが来ることもある。
　　2.Atcorderはアルゴリズムの習得に有用であり、paizaは実用的な内容である
　　　Atcorderでアルゴリズムの勉強し、テストで実用的な内容にも対応できるように対策すると吉だと思われる。
　 3.余裕があれば個人開発で成果物（ポートフォリオ）を作成できるとより良い


### 最後に
今回は競技プログラミングの利点について述べたが、筆者としては利点とかを省いても競技プログラミング自体が面白いと思っている。
もし、興味のあるかたは趣味として挑戦してみるのもよいと思う
VisualStudioCode備忘録

# 初めに
VisualStudioCodeを使うときの設定をメモします。

# ライブラリ・モジュールのcould not be resolved
ライブラリをpipでインストールした，コードは問題なく使える．
しかしVisual studio Code (以下VSCode)で「could not be resolved」と言われ黄色の波線が出る．そんな時の対処法
![ca2dd7e98d2095e829d3fa428bcc567f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2748346/d662c9bb-94ec-0f59-c52a-e5f88289677d.png)

pandasを例に上げる．
- ターミナルで対話モード．（Windowsの場合：「Python」コマンドを実行）
- 「import pandas」コマンドでpandasをインクルード
- 「`print(pandas.__file__`)」コマンド．ライブラリのディレクトリパスが表示される．
  - 例：`C:\Users\~(中略)~\local- packages\Python39\site-packages\PIL\__init__.py`
  - このパスの先頭から「site- packages」までをコピーする．
- VSCodeの「ファイル」→「ユーザー設定」→「設定」
- 画面上部，「設定の検索」に「extra path」を検索
![f603c1bce00597475c36ef57f01bcde0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2748346/6cae70d2-25e9-c939-9f0f-b13b6e80067c.png)
- python > Analysis: Extra Pathsの「項目の追加」（Add Item）をクリック
- 入力欄にコピーした「~\site-packages」までのパスを入力，「Ok」．
- ソースコードに戻り，黄色の波線が消えていれば成功．
参考：[Visual Studio Codeでライブラリやモジュールが could not be resolved になる時の対処法](https://startlab.jp/learning-python/vscode-settings/) 

# デバッグ時にモジュールのインポートエラー
ライブラリはインストールした．プログラムも問題なく使える．
Visual Studio CodeでF5デバッグ時に「ModuleNotFoundError」のエラーが出る．その対処法１
![303280d450295adb68ffe57d04cb4b62.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2748346/38766b02-e259-dad0-91c0-e94347881478.png)
「F1」キーもしくは「Ctrl＋Shift＋P」で開き，「Python：Select Interpreter」を選択．
パスが選択できるので，使用するライブラリが入ったパスを選ぶ．
![cd89fa9fd3fb6f0ce1990945bd34945f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2748346/e78746fe-8976-d0a4-5dc9-dfaeab68abac.png)
Pythonのライブラリはpipコマンドを利用することで簡単にインストールできますが，新しいバージョンのPythonをインストールする等した結果自分の使うバージョンのPythonとは別のディレクトリを参照することが多々あります．Windows Store等で最新版をインストールした後等，確認が必要です．
参考：[Python VSCode ModuleNotFoundErrorが起きた場合](https://mjeld.com/python-vscode-modulenotfounderror/)
AfterEffectsで制作した動画をMediaEncoderでエンコードできなくなった

AfterEffectsで動画をつくり終わり大きな達成感に浸りつつも、あとは出力だけだからさっとやってしまおうと気を抜きながらMediaEncoderで書き出しを始めたら突如そいつはやってきた。

# 書き出し手順
1. AfterEffects > ファイル > 書き出し > Adobe Media Encoderキューに追加
2. MediaEncoder  > キューを選択した状態でキューを開始（リターン）

ここで謎のエラーステータスが発生した。

## 謎のエラーログ

AMEEncodingErrorLog.txt
```
------------------------------------------------------------
 - エンコード時間 : 00:01:15
mm/dd/YYYY hh:ii:ss PM : エンコードが失敗しました
------------------------------------------------------------
書き出しエラー
ムービーの作成中にエラーが発生しました。
高速レンダラーエラー
フレームを作成できません。
エクスポーターを使用して書き込み : H.264
ファイルに書き込み : /Users/xxx/xxx/xxx/xxx.xxx
書き込みファイルタイプ : H264
タイムコードの前後 : 00:00:01:12 - 00:00:01:28
レンダリングのオフセット : 1.200 秒
コンポーネント : H.264 タイプ エクスポーター
セレクター : 9
エラーコード : -1609629695
```

いままでエラーなんて起こらなかったからなぜかと思いつつも、とりあえずエラーコード調べればなんとかなるやろと思い調査しつつも結果解決できず終い。

別な切り口で探ってみようと、書き出し設定の見直しやそもそもの書き出し元のaepファイルを単純なコンポジション1つだけにするなどやってみたがどれも上手くいかない。

完全に手詰まりである。

## 原因はなんなのか
特定はできていないが、おそらくAfterEffectsやMediaEncoderを2022から2023にしたのが要因としか考えられない。

なぜなら作業するPCは同じだし書き出し設定の変更やプラグイン追加はしていないから。

## 解決方法
結論からいうとMediaEncoderで書き出すことは断念した。

というのも、ググってみたらどうやらAfterEffectsで書き出すことができるらしく、そもそもMediaEncoderを使わなくてもできるようだ。

AfterEffectsはMediaEncoderと違いaviとmov形式でしか書き出せないが、movで書き出すため問題なし。

1. AfterEffects > ファイル > 書き出し > レンダーキューに追加
2. レンダリング設定・出力モジュール・出力先などの設定を行いレンダリング開始

無事書き出すことができた。

mp4など別の形式で書き出す必要がないので問題なかったが、時間があるときに解決していきたいと思う。
リアルタイムで合成音声に変換して美少女の声でVCに参加する

## 概要
合成音声を使ってリアルタイム録音で美少女の声に変換し、VCに参加するシステムを構築してみたので紹介する。

## 想定読者
- Pythonを用いた美少女VCに興味があり、必要なライブラリが知りたい人
- 言語はどうでも良いので大体のシステムの流れを知りたい人

具体的な実装コードは自分の有しているコードを流用したためこの記事では紹介しない。具体的な実装が気になる人は[Twitter](https://twitter.com/sald_ra)のDMを解放しているので、相談して欲しい。


## 技術選定と構成の決定
技術構成は以下になる。
- Python
  - sounddevice pythonで指定したデバイスに音声を出力
  - scipy bytesデータになっているwavデータをbufferに変換
  - speech_recognition マイクから入力された情報をテキストデータに変換
  - PyAudio speech_recognitionの依存ツール
- COEIROINKAPI 与えられたテキストデータを合成音声に変換しbytesデータとして送信

合成音声ソフトはVOICEVOXエンジンを用いた。COEIROINKはその中でもかわいい声があったのでこれにした。技術要件的にCOEIROINKである必要性はなく、VOICEVOXエンジンであれば問題ない。極論同じoutput(wavのbytesデータ)であれば他のエンジンでも良い。

https://coeiroink.com/

COEIROINKはソフトを起動するとローカルAPIが経つ仕組みになっているので、APIにテキストデータ（今回の場合はマイクで話した内容）を渡せば音声データが返ってくる。APIで与えられる音声データはbytes形式のため、書き出さずに再生するためにはscipyが必要になる。他に変換できるライブラリがあるなら、それに変えても問題ない。

https://twitter.com/sald_ra/status/1618211925606944769

## 主な処理の流れ

1. マイクから音声認識を行いテキストデータに変換
1. テキストデータをCOEIROINKのAPIに送信
1. 受信したwavのbytesデータをbufferに変換
1. bufferをsounddeviceで仮想マイクに出力
1. 仮想マイクを美少女で話したい任意のVCのマイクに設定

## 備考
こちら側で実装する必要のあるものは音声認識・bytesデータの再生の二つのため、この二つの要件が達成できるのであればNode.js等他のバックエンド言語でも可能。COEIROINKのAPIをクラウドに載せることができればGPU資源も不要になるので必要なマシンスペックは相当低くできる。

## まとめ
利点としてMMVCなどのリアルタイム変換よりもマシンスペックが必要ないこと、事前準備があまりいらないこと、合成音声のためはっきりした口調であることがある。一方で合成のためのラグが数秒あるためペアプロのような瞬間的なコミュニケーションが必要なものには向かないと思われる。個人的にはこれを流用してナレーションの合成音声化などに使えるのではないかと思ったので、興味がある人は作ってみてほしい。

## 連絡先

https://twitter.com/sald_ra
お前の正面ど～こだ

# 車の正面の出し方

自動車整備にエーミングというのがあるが、その中でターゲットを置くための
センター出しとかターゲット位置出しとかある。

車の中心であれば、[エーミングの位置決め](https://f-gear.co.jp/toolcp/2020/05/08/post-10049/)のようにやればいいけど、
ドラレコのカメラとかヘッドライトとかの正面だと、センター出しした後、
平行線引かないといけないから、もうちょっと簡単にしたい。

## MEAZOR 3D
で、レーザ距離計も欲しいと思っていたので、騙されたと思って[MEAZOR 3D](https://hozodesign.com/en-jp/products/meazor3d)を入手。
普通のレーザ距離計と何が違うかというと、レーザ付きで角度が測れること。
垂直方向はよくあるけど、プロトラクター（分度器）にレーザがついているのが少ない。
（海外ECにはたまに見かけたけど）

ちなみに、ちゃんとしたものだと、[DISTO-X4+DISTO-DST360](https://shop.leica-geosystems.com/jp/ja-JP/leica-disto-x4-p2p-package)になる。
しかも、レーザ付き分度器として使えるかも不明。

なお、MEAZOR 3Dでも距離と水平角度、垂直角度を一度に表示されないので、それぞれ別に測定しないといけない。
あと、垂直方向は微動調整できないので、上下のポイント合わせは難しい。
（元々の用途は部屋の大きさ図るだけだからね・・・）


## やりたいこと
下の図でやりたいことを説明すると、```C```の位置の真正面```D```を求めること。
正面を出すために、```CD```は```AB```と並行であること。
また、```D```は```点O, P, Q```上の壁にあること。

```点Z```に配置したMEAZOR 3Dで、```点A,B,C, O,P,Q```の位置を図り、```点D```の位置を計算し、
水平角・垂直角をMEAZOR 3Dで測り、レーザでポイントしたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455423/22de6db3-259b-4dbc-2bd2-b2837ec7cb81.png)


## 予備実験
とりあえず、部屋の中で既知の```D(真値)```を測定し、
```点A,B,C, O,P,Q```から計算した位置```D(計算)```がどれぐらい差があるかを出してみた。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455423/33bc6780-ee0c-f998-36d2-a5df8d203ab6.png)

距離、垂直角、水平角をそれぞれ別のタイミングで計った割にはそんなにはずれてなさそう。
もう少し練習してみて、本番チャレンジしてみたいと思う。
雪豹のMBA OriginalでSSE

久しぶりにmacamをいじっているのだが、目的の処理が上手くいかないので、気分転換にSSEサポートをやってみた。

https://github.com/yamori813/macam/commit/c6442f35bb998ff1314e31718f247935fec2f8b1

元のコードはネットで見つけたもので128bitで計算してるみたいです。

元々バイト演算でとっても効率の悪いコードになっていました。

普通の演算の場合のCPU負荷

![スクリーンショット（2023-02-03 15.17.32）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/68568e35-c0c9-fcc6-d8b4-934959b5a3c8.png)

SSEを使った場合の負荷

![スクリーンショット（2023-02-03 15.21.04）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/1d43ab8b-0f30-f343-dc47-31cf31b10ae3.png)

目見当で10%くらいでしょうか。SSE使うと綺麗な気がしませんか？

![Untitled.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d1d47ab6-0ccc-2c32-81e9-350ea03fddb9.jpeg)

仙波師匠のはにわのDVDをPS2で再生してデバッグしてました。

フレームデータはインターレスなのだが、セカンドのフレームの始まりのアライメントが128ビット(16バイト)にはまらなかったので、最初のフレームの最後のパケットのパディングを削って調整しました。

世の中はM2とかいってるのに、なにやってるんだか。

まだまだ雪豹
プロジェクト内のすべてのコードから行末のスペースを消し去りたい

よく忘れるので
```ruby
# Railsの例
# gsed: brew install gnu-sed
# ./frontendとか*.rakeとか*.tsとか適宜追加して

cd project_root
export LANG=C
find ./app ./lib ./spec -name '*.slim' -or -name '*.rb' | xargs gsed -i "s/\s*$//g"`
pgadmin4でPostgreSQLにデータをいれてみた。-Mac編-

# 記事の概要
MacにインストールしたPostgreSQLを運用管理ツールであるpgadmin4でデータを挿入してみた。
# 前提
pgadmin4をMacにインストール済み
[PostgreSQLのインストールと基本的な使い方-Mac編-](https://qiita.com/Tiger-Kid/items/8cacb8b89a2d201f4cf8)を実施済み
# 補足
### pgadmin4を日本語表記したい
「File」→ 「Preferences」を選択
![スクリーンショット 2023-02-03 14.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/cf9633a4-c8ce-0874-b30c-d5a78b4308ee.png)
「Miscellaneous」→「User Language」にて、「Japanese」を選択し、「Save」
![スクリーンショット 2023-02-03 14.36.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/ba03837c-b6a3-a755-317b-06bbf8140a20.png)
「Refresh」をすることで日本語表記になる
![スクリーンショット 2023-02-03 14.36.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/dd2b2ea1-50e0-6877-bfe3-e47c4b65c49d.png)

# 本編
### pgadmin4にサーバー追加
左側のサーバーの上で右クリック→「Register」→「Server」
![スクリーンショット 2023-02-02 19.37.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/fbf48130-4704-1453-abbd-6ee82f216a49.png)
サーバーの情報を入力
![スクリーンショット 2023-02-02 19.37.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/0ff03f84-c47a-b265-3ace-d90f154f8500.png)
![スクリーンショット 2023-02-02 19.37.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/26368d2c-f39d-ed3b-2d58-22aa59574064.png)
### テーブルの作成
[PostgreSQLのインストールと基本的な使い方-Mac編-](https://qiita.com/Tiger-Kid/items/8cacb8b89a2d201f4cf8)で作成したdbにテーブルを追加する。
左側のテーブルの上で右クリック→「作成」→「テーブル」
![スクリーンショット 2023-02-03 14.41.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/37de29dc-1ac5-a980-754e-7466e7f22425.png)
Generalタブからテーブルの名前を入力する
![スクリーンショット 2023-02-03 15.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/7a05ee16-fd45-9dd8-01cc-3cd88bf12ef7.png)
列タブからテーブルの列名を入力する
![スクリーンショット 2023-02-03 15.25.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/ea2f06fe-4e65-c4d4-44be-26d7fc3b8d1a.png)
SQLタブより、各タブで入力した内容が反映されたSQL文を確認することができる。
![スクリーンショット 2023-02-03 14.43.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/47e7b388-e3e2-4e9c-6dd8-41ea1e546047.png)
また、作成したテーブルへの権限の付与やセキュリティラベルの付与を行うこともできる。
![スクリーンショット 2023-02-03 14.43.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/785c7c70-0104-c9f5-5787-8f0ffd569378.png)
### データの挿入
作成したテーブルにデータを挿入する。
左側のテーブル名の上で右クリック→「データをインポート/エクスポート」
![スクリーンショット 2023-02-03 14.46.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/add43abc-1897-e441-ee91-81d40d53ff00.png)
挿入するデータを選択し、「区切り文字」や「引用符」、「エスケープ文字」等の設定を行い、「OK」
![スクリーンショット 2023-02-03 14.49.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/e6136aaf-a29f-5d91-1ac5-913eaebd58c8.png)
右下のように「正常に完了しました。」が表示されればOK
![スクリーンショット 2023-02-03 14.49.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/f876554e-57e6-6d03-5706-7373498bcee0.png)
一応うまく実施ができたかの確認をする。
左側のテーブル名の上で右クリック→「データを閲覧/編集」→「すべての行」
![スクリーンショット 2023-02-03 14.50.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/062b58f2-d118-801f-e5f3-97a539d1ca9f.png)
《SS》累積分布関数で順位と連動した賞金金額を計算する

## 概要
私用で成績順位と連動する賞金等を計算するスプレッドシートを作成したので、標準化してシェアします。
会社などで営業成績順位に応じて報奨金が出るなどの場合を想定しています。
もし成績順に応じてy=f(x)のような直線的な賞金金額で良いなら、このような計算をする必要はありません。
成績を上げてもらうために賞金制度を使うと考えると、成績上位者をより優遇するこのような方法もアリなのかなと思います。
画像のグラフのように、累積分布関数を使うと成績上位者がより有利になるような賞金制度を設計できるわけです。
最初はネットで調べれば簡単に作れると思ったのですが、正規分布や累積分布のグラフの作り方はすぐに見つかるわりに、このような用途のシートをそのまま作れるような情報があまり無いようなので、参考になれば幸いです。
私用のものは時間と連動したりしてもうちょっと複雑なのですが、金額にした方がわかりやすいかと思い変えています。
![累積分布01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885228/f670d239-18f3-d313-8157-b75f8bbffad9.png)

## 累積分布関数
累積分布関数については下記のページがとてもわかりやすいです。
私もぜんぜんわからなかったのでとても参考になりました。

https://best-biostatistics.com/summary/ruiseki-bunpu.html

## 詳細
セルに入れる数式の説明です。
![累積分布02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885228/f90d1476-27e7-614f-274b-0029465ad918.png)
セルA2に該当するテスト等の受験者数を入れます。
セルB2に個人の順位を入れます。
セルC3は例なのでどんな数値でもかまいません。
セルD2は下の表をVLOOKUPしてるだけです。
中央値は計算には使用しないのですが、参考として入れてます。

![累積分布03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885228/c300c10f-ba24-a359-b971-c5b8844c69b4.png)
平均の偏りですが、順位の平均を中央値よりも上に押し上げるために使用します。これを入れると中央値の順位付近よりもさらに上の順位でないと賞金が多くなりません。セルB6の平均の関数 `AVERAGE(A8:A)` に掛け合わせます。
偏差の滑らかさはグラフのS字カーブの傾き具合を調整します。０に近いほど傾きが極端になり、１に近づくとゆるやかになります。順位による配分をどのようにするかに影響します。C6セルの標準偏差 `STDEV(A8:A)` に掛け合わせます。

８行目に順に下記のように数式を入れます。
① A8：`SEQUENCE($A$2,1,1,1)`
② B8：`ArrayFormula(IF(A8:A="","",($A$2+1-A8:A)))`
③ C8：`ArrayFormula(IF(A8:A="","",(NORM.DIST(B8:B,$B$6,$C$6,TRUE))))`
④ D8：`ArrayFormula(IF(A8:A="","",ROUNDUP($D$6*C8:C,-2)))`

受験者数が何万人でもこれだけで計算ができるはずです。
①はセルA2に入れた受験者数を１から順に１増で入力していく関数です。（行数, 列数, 開始値, 増分量）
②はA列の数値を逆にする数式です。
③が累積分布関数を組みこんだ式です。（値, 平均, 標準偏差, 累積（True,False））
④は例として賞金金額を入れています。本当はC列の累積度数は１位のときに「１」になるようにしたいのですが、技量不足でうまくできませんでしたので、セルD6で金額を調整し、下２桁で切り上げることで１位が最大賞金額になるようにしています。
何か良い方法があれば教えていただきたいです。
Laravel8+MySQL+ローカル環境でHerokuのecoプラン(有料) へのデプロイ手順

## まずはHerokuのアカウントを作成しクレジットカードの登録をしましょう
https://id.heroku.com/login

Account settings > Billing > **Billing Information**
ここでクレジットカードの情報を入力します。
住所入力時のフォームが英語表記になっていますが**英語で入力するとなぜかエラー**になってしまうことがあります。
その場合は**日本語で入力**すると上手くいくかと思います。

Account settings > Billing > **Eco Dynos Plan**
![Screenshot 2023-02-01 at 0.45.22 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350957/083eedbb-c24a-2490-15bb-b537db1409b7.png)
「**Subscribe to Eco**」をクリックします。

**Heroku CLI**をインストール（**Mac**）
```terminal
$ brew tap heroku/brew && brew install heroku
```

**Heroku**がインストールできていることを確認
```terminal
$ heroku -v
heroku/7.56.1 darwin-x64 node-v12.21.0
```

**ご自身のリポジトリ**に移動
```terminal
$ cd your_repository
```

**Herokuでアプリケーションを作成**
```terminal
$ heroku create
$ heroku create アプリ名 (heroku上でアプリに名前をつけたい場合はこちら)
```

**Heroku**で**MySQL**を使用。今回は**JawsDB MySQL**に変更するため下記のコマンド
```terminal
$ heroku addons:create jawsdb:kitefin --version=8.0
```

## Herokuアプリの環境変数設定
まずは設定を確認
Resources > **Add-ons** で**JawsDB MySQL**を選択
![Screenshot 2023-02-08 at 6.31.38 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350957/fcad92f4-e9db-6672-59d2-1204280c4294.png)


**JawsDB MySQL**のリンクをクリック
![Screenshot 2023-02-03 at 3.40.15 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350957/b58c02b1-0863-c2b5-4a97-c7e9cbcfd956.png)



**DB情報**が表示される
![Screenshot 2023-02-08 at 6.39.00 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350957/55efc9f3-b024-c06f-a6b4-64544f8837c1.png)


Settings > Config Vars > **Reveal Configを開く**
![Screenshot 2023-02-08 at 6.26.13 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350957/4552f58c-0b83-a2a7-7716-73bf3cfb9d18.png)

**KEY**, **VALUE**に各項目を入力
```
APP_KEY = <ご自身のAPP_KEY> （.envファイルの3行目あたりに記載）
DATABASE_URL = mysql://DB_USERNAME:DB_PASSWORD@DB_HOST:3306/DB_DATABASE
DB_HOST = Host
DB_USERNAME = Username
DB_PASSWORD = Password
DB_PORT = 3306
DB_DATABASE = Database
JAWSDB_URL = mysql://DB_USERNAME:DB_PASSWORD@DB_HOST:3306/DB_DATABASE
```

**Buildpacksを追加**
「Add Buildpacks」をクリック
![buidpacks1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350957/89699c16-d880-a564-faff-1a54403f4b86.png)


「node.js」と「php」を選択し「Save changes」をクリック
![buildpacks2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350957/fdc64446-6b9c-6253-91f5-de1921647298.png)




**Procfileを作成**
ProcfileというHerokuの設定ファイルを作成します。
アプリフォルダの直下にProcfileファイルを作成（拡張子なし）。
```terminal
$ touch Procfile
```

Procfileには以下の内容を記述します。
```
web: vendor/bin/heroku-php-apache2 public/
```

※ 記述後各自pushしてください

**HerokuにPush**
```terminal
$ git push heroku main

mainブランチ以外をデプロイしたい場合はこちら
$ git push heroku <デプロイしたいブランチ名>:main
```

**Herokuでmigrate**
```terminal
$ heroku run php artisan migrate
```

**Herokuでseed**
```terminal
$ heroku run php artisan db:seed
```

**Webサイトを開く**
```terminal
$ heroku open
```

**ご自身のアプリが表示されれば完了！**
【IBM Security Verify】拡張ルールを使ってみる

# はじめに
IBM Security Verifyの拡張ルールを使って、メールアドレスの取得、加工してカスタム属性に設定してみます。

拡張ルールを使ったカスタム属性の追加についてはこちらを参照ください。
[【IBM Security Verify】 拡張ルール（Advanced Rule）を使って最終ログイン日（lastLogin）を取得する](https://qiita.com/fitz/items/beb4f0ff4794ab6bb35f)

# 1.拡張ルールでメールアドレスを取得する
```
サンプル1: 関数を使って直接取得する。
user.emails.filter(x, x.type == "work")[0].value
```
```
サンプル2: 変数を使ってみる
statements:
 - context: emailvalue := user.emails.filter(x, x.type == "work")[0].value
 - return: context.emailvalue
```
```
サンプル3: if分も使ってみる(realmが"cloudIdentityRealm"かどうか）
statements:
 - context: realm := user["urn:ietf:params:scim:schemas:extension:ibm:2.0:User"].realm
 - context: emailvalue := user.emails.filter(x, x.type == "work")[0].value
 - if:
    match: context.realm == "cloudIdentityRealm"
    block:
     - return: context.emailvalue
    else:
     - return: string("none")
```


# 2.拡張ルールでメールアドレスのドメイン除いた値（@より左）を取得する

```
サンプル1
user.emails.filter(x, x.type == "work")[0].value.substring(0,user.emails.filter(x, x.type == "work")[0].value.indexOf("@"))

サンプル2
statements:
 - context: emailvalue := user.emails.filter(x, x.type == "work")[0].value
 - context: index := user.emails.filter(x, x.type == "work")[0].value.indexOf("@")
 - return: context.emailvalue.substring(0,context.index)
```

# 参考
- https://www.ibm.com/docs/ja/security-verify?topic=attributes-attribute-functions
- https://www.ibm.com/docs/ja/security-verify?topic=attributes-multi-line-rule-executor
【データ基盤構築/BigQuery】MERGEステートメントでテーブルを差分更新する

# 今回の課題
BigQueryのデータ基盤の差分更新を添付の記事のように実装していたのだが、
MERGEステートメントを使用することでも実装できそうだったので、試してみようと思った。

https://qiita.com/Ayumu-y/items/5c2876bc14c8498d1c82


## MERGEステートメント
INSERT, UPDATE, DELETEオペレーションを１つのステートメントに結合し、オペレーションをアトミックに実行できるDMLステートメントです。

※引用：[MERGEステートメント（BigQuery公式ドキュメント）](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax?hl=ja#merge_statement)


## 前日分のデータを差分更新したい場合のクエリ
コメントアウトで、部分毎にどういった処理をしているか記入致しました。
```SQL
/* 日付関連UDF */
create temp function yesterday() as (
    date(date_sub(current_date(), interval 1 day))
);

/* 差分更新をするクエリ */
merge
    `変更するテーブル名` as a -- 差分追加先のテーブル
using -- ソーステーブルからデータを抽出する
    (
    with master as (
        select
            date(date) as date -- date型に変換
            , page_title
            , user_type
            , page_path
            , regexp_replace(normalize(page_path, NFKC), r'(index|&|\?|https).*|[^a-zA-Z0-9 -/:-@-~_]|[ +:\?#]', '') as page_path_fix --データの揺れを調整
            , pageviews -- pv数
            , users -- uu数
        from
            `ソーステーブル名`
        where
            date = yesterday() -- 1日前を差分更新したいので、一日前にフィルタリング
    )
    select
        date
        , page_title
        , user_type
        , page_path
        , page_path_fix
        , pageviews
        , users
    from
        master
) as b
on -- どのカラムをキーにして、データの有無を判断するか指定
    a.date = b.date
    and a.page_title = b.page_title
    and a.user_type = b.user_type
    and page_path = b.page_path
when matched then -- onの部分でキーに指定したデータが存在する場合に更新する数値のカラムを指定
    update set
        a.pageviews = b.pageviews
        , a.users = b.users
when not matched then -- onの部分でキーに指定したデータが存在しない場合に挿入する数値のカラムを指定
    insert(
        date
        , page_title
        , user_type
        , page_path
        , page_path_fix
        , pageviews
        , users
    )
    values( -- 挿入する数値を指定
        b.date
        , b.page_title
        , b.user_type
        , b.page_path
        , b.page_path_fix
        , b.pageviews
        , b.users
     );
```
postfixのログから”SASL LOGIN authentication failed”が多いIPアドレスをはじくiptablesエントリを自動作成するシェルスクリプトを作ってみた。

# つまりどういうことだってばよ？

postfixのログ`/var/log/mail.warn`に大量に記録されたスパム業者
と思われるIPを片っ端からiptablesで弾く為に、
`SASL LOGIN authentication failed`の回数上位10件のIPアドレスを
対象としたiptablesエントリを自動作成するスクリプトを組んでみた。

## 環境

- debian 11 bullseye
- iptables-persistentがインストール済み
- postfix

## 参考サイト

[SMTP Authを何度も試みててくるIPアドレスをブロックする【postfix】 | ex1-lab](https://ex1.m-yabe.com/archives/4382)

## スクリプト
```bash:mkiplist
#!/bin/bash

sudo grep "SASL LOGIN authentication failed" /var/log/mail.warn | grep -o "\([0-9]\+\.\)\{3\}" | sort | uniq -c | sort -nr | awk '{print "-A INPUT -s " $2 "0/24 -j DROP"}' | head -10
```
## 実行結果
```
-A INPUT -s xxx.xxx.xxx.0/24 -j DROP
-A INPUT -s yyy.yyy.yyy.0/24 -j DROP
-A INPUT -s zzz.zzz.zzz.0/24 -j DROP
...
```

あとはこれを`rules.v4`のfilterに貼り付けて、
`iptables-restore`すればOK。
Goで作った自作のコマンドラインをGitHub Actionsで使用する

最近、[こういったツール](https://github.com/iwashi623/gjobctl)を作りました。
せっかく作ったツールのなので、GitHub Actionsの中で実際に使ってみたいな〜と思ったのですが、自作のパッケージを配布する方法がわからなかったので調べました。その時のメモです。

## ツール紹介
ツールの中身のことを語っても仕方ないので、軽く説明すると、AWS GlueのデプロイなどをするAPIをラップしたものです。
ディレクトリ構成は以下のようになっています。
```
gjobctl
├── cmd/gjobctl
│   └── main.go
├── go.mod
├── go.sum
├── cli.go
├── deploy.go
├── create.go
.
.
.
└── RAEDME.md
```

Terminalで以下のようなコマンドが使えます。
```bash
$ gjobctl
Usage: gjobctl <command>

Flags:
  -h, --help    Show context-sensitive help.

Commands:
  list
    Get GlueJob List

  get <jobname>
    Get GlueJob details in Json format

  create
    Create GlueJob from Json file

  update
    Update GlueJob from Json file

  script-deploy <script-local-path>
    Deploy GlueJob script to S3.

  run <jobname>
    Run GlueJob.

Run "gjobctl <command> --help" for more information on a command.
```

## Github Actionsで使うまでの道
### リポジトリにタグを打つ
```bash
$ git tag -a v0.0.1 -m 'v0.0.1'
$ git push origin v0.0.1
```
リポジトリの`Releases`をポチッと押して、
![スクリーンショット 2023-02-03 15.02.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960876/bdc32453-4428-a39b-555f-641ad4f06de5.png)

タグができているのを確認して（手順通り進むとv0.0.1だけのはず、v0.0.3は無視してください）、
![スクリーンショット 2023-02-03 15.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960876/5113e1ee-e2c3-d393-8036-fae0af12575b.png)

タグの編集画面からRelease Tagとして`v0.0.1`を登録してください。
これでGoアプリケーション側はおしまい。

### Github Actions側
```yml
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-go@v3
        with:
          go-version: 1.19
      - name: Install-tool
        run: |
          export GOPATH=$HOME/go
          export GOBIN=$GOPATH/bin
          export PATH=$PATH:$GOBIN
          go install github.com/iwashi623/gjobctl/cmd/gjobctl@latest
```
こんな感じ。どのディレクトリでも追加する自作のパッケージを使用したいなら、PATHを通して置いたほうがいい。
これで、`gjobctl`コマンドが使えるようになりました。
Clojureの書き方

Clojureに触る機会があり、書き方が他の言語と異なっていたため簡単に纏めておく。
# 変数の定義
## 他の言語では
他の言語では以下のように書くことが多く、見慣れていると思う。
```java:他言語記載例
int sample_variable = value;
```
## Clojureでは
Clojureでは、以下のように変数定義を書くことになる。
```Clojure:Clojure記載例
(def sample-variable value)
```
intなどデータ型の記載が存在せず、defと書くことになる。
### defとは
Clojureで使用するdefとは、関数名や変数名を定義するとき使用する宣言。
他の宣言としては*fn*や*defn*などがあり、それぞれ以下の場合に使用する。
・fnは関数の処理を記載する場合に使用する。関数名の定義はしない
・defnは、def+fnのような宣言。関数名定義と関数の処理を記載する際に使用する

# 関数の定義
関数の定義の記載方法について、引数なしと引数あり場合で纏めていく。
## 他の言語では
他言語の記載例としては、中括弧を使用して処理を記載する場合が多い。
```java:他言語記載例(引数なし)
int sample_function() {
  処理
}
```
```java:他言語記載例(引数あり)
int sample_function(int arg1, int arg2) {
  処理
}
```
## Clojureでは
一方Clojureでは、中括弧を使用せずに
```Clojure:Clojure記載例(引数なし)
(defn sample-function
  []
  (処理)
)
```
```Clojure:Clojure記載例(引数あり)
(defn sample-function
  [arg1, arg2]
  (処理)
)
```
と書く。

# 関数への引数の渡し方
## 他の言語では
他の言語だと以下のような形で引数を渡す形が多いと思う。
```java:他言語記載例
sample_function(arg1, arg2);
```
## Clojureでは
Clojureでは、以下のように引数を渡すことになる。
```Clojure:Clojure記載例
(sample-function arg1 arg2)
```
# 関数の返り値を別の関数に渡す方法
## 他の言語では
関数の返り値を別の関数に渡す場合、他の言語では以下のような書き方で渡すことになる。
```java:他言語記載例1
arg1 = sample_function1();
sample_function2(arg1, arg2);
```
```java:他言語記載例2
sample_function2(sample_function1(), arg2);
```
## Clojureでは
Clojureでは以下のように返り値を渡す。
```Clojure:Clojure記載例1
((def arg1 sample-function1)
 (sample-function2 arg1 arg2))
```
シングルアロー(->)を使用することで以下のように書くこともできる。
```Clojure:Clojure記載例2
(->(sample-function1)
    (sample-function2 arg2))
```
# HelloWorld
標準出力にHello Worldを出すときは、以下のように書く。
```Clojure:Clojure記載例
(println "Hello World!")
```
ApplicationGatewayとLaravelの合わせ技で通信が困った話

# 問題になったこと
AzureのApplicationGatewayを前段に置いて、後ろにLaravelのWebサーバーがある構成で、
何故かLaravelから生成されるURLが非SSLになって色々と困ったので備忘録

## 結論
### 原因
Laravelは特に指定がなければ、サーバー変数$_SERVERの値を使ってURLを生成する。
ApplicationGatewayより後ろを非暗号化httpで通信していたため、Laravel側はhttpのURLを生成していた模様。

### 解決方法
二種類ある
#### 1. Apache側でサーバー変数を書き換える
ApacheのVirtaulhostに下記の設定を追加
```
SetEnv HTTPS on 
```
これで$_SERVER["HTTPS"]が強制的にONになるので、
Laravel側でもhttpsのURLが生成されるようになる

#### 2. Laravel側でURL生成に使う値を強制的に変更する
下記の処理をAppServiceProvider.phpに加えることで強制的にURL生成に使い値を変更することが可能
```
Illuminate\Support\Facades\URL::forceRootUrl('url')
Illuminate\Support\Facades\URL::forceScheme('https')
```
詳細は下記コラムが参考になりました。
より詳しい処理の詳細は下記を確認していただければと。

https://qiita.com/tkek321/items/19465ed85e8cb42af53c
Azure Kubernetes Service あれこれ


# やりたいこと

AKS (Azure Kubernetes Service) をいろいろ触る機会があって、概念レベルだった理解が深まったのでこの記事にまとめます。

:::note info
AKS の作成や操作といった具体的な手順は別記事で投稿する予定です。
:::


# AKS (Azure Kubernetes Service) とは

https://learn.microsoft.com/ja-jp/azure/aks/intro-kubernetes

公式ドキュメントより
> Azure Kubernetes Service (AKS) を使用すると、運用上のオーバーヘッドが Azure にオフロードされるため、Azure でのマネージド Kubernetes クラスターのデプロイが簡素化されます。 ホストされた Kubernetes サービスとして、Azure によって正常性監視やメンテナンスなどの重要なタスクが処理されます。 AKS クラスターを作成すると、コントロール プレーンが自動的に作成されて構成されます。 このコントロール プレーンは、ユーザーから抽象化されたマネージド Azure リソースとして無料で提供されます。 AKS クラスターに接続されているノードに対してのみ課金され、管理します。

Web アプリケーションの各サービスをコンテナで構築するようなマイクロサービスを実現する上で、コンテナのオーケストレーションを行ってくれる Kubernetes を Azure が提供しているもの。Kubernetes のクラスター管理などを Azure が行ってくれるので、サービスの開発に集中でき、導入も簡単になる、というのが個人的な理解。

# AKS の基本概念

https://learn.microsoft.com/ja-jp/azure/aks/concepts-clusters-workloads

## 大まかな流れ

1. AKS クラスターを作成する
    * Azure CLI や Kubernetes CLI が便利
1. マニフェストファイルを作成する
    * マニフェスト: Kubernetes のリソース定義 (YAML)
    * `kind` フィールドの値を変更することで定義対象を変更できる
1. ポッドに関するマニフェストファイルをデプロイする
1. アプリケーション (コンテナイメージ) が AKS 上で実行される

### 事前に行うこと (Optional)

* AKS 用のアプリケーションを準備する
  * コンテナイメージを作成したり、ローカルでテストしたり
* コンテナレジストリを作成する
  * ACR (Azure Container Registry) などを利用する

## 構成要素

AKS クラスターは大きく2つのコンポーネントに分割される

* コントロールプレーン
* ノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743460/9b919b96-43fb-cd39-abcc-1ae4eb37da71.png)

### コントロールプレーン

* クラスターに関する全体的な決定を行う
* クラスターイベントの検出および応答を行う (定義されたポッド数が満たされていないときに新しいポッドを起動するなど)
* kube-apiserver 経由で API を呼び、クラスター内のリソースを管理する
* AKS ではマネージドコントロールプレーンなため、高可用性を意識して構成する必要はないが、コントロールプレーンに直接アクセスはできない
  * 直接アクセスするためには、[Cluster API Provider Azure](https://github.com/kubernetes-sigs/cluster-api-provider-azure) を使用して自己管理型の Kubernetes クラスターを展開する

### ノード

* アプリケーションが実行されるリソース
* クラスター内に少なくとも1つ以上存在する
* AKS では Azure Virtual Machine によって実行されている
  * 1つのノードが1つの VM に相当する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743460/8a8163e1-efa7-64b1-770a-b822efb86a01.png)

#### ノードプール

* 同じ構成のノードはノードプールにグループ化できる
* クラスター内には少なくとも1つのノードプールが存在する
* デフォルトの数とサイズはクラスター作成時に定義する

## ワークロードの構成要素

* ポッド
* デプロイメント

### ポッド

* アプリケーションのインスタンス
* 基本的には実行されるコンテナと1対1でマッピングされる
  * 1つのポッドに複数のコンテナを含む場合もある

### デプロイメント

* ポッドにデプロイするコンテナイメージの定義やレプリカ数などを YAML で定義する (マニフェスト)
* 定義したマニフェストを API 経由でデプロイすることでポッドに適用されるとアプリケーションが実行される

以上です。
Raspberry Pi 400 で Docker 環境を構築してみた。

開発用の環境として、セットアップした Raspberry Pi 400 で Docker 環境を構築してみました。

# 環境
#### 作業PC
- Windows11

#### Raspberry Pi
- Raspberry Pi 400
- microSD（64GB）


# Raspberry Pi 400 のセットアップ
Raspberry Pi 400 のセットアップは、下記の記事を参考にしてください。

https://qiita.com/IoriGunji/items/718f8245136af94066eb?0


# Docker 環境の構築
Docker の環境を構築していきます。

## Docker Engine のインストール
RaspberryPi OS はリポジトリを使用したインストールがサポートされていないため、スクリプトを使用してインストールします。

https://docs.docker.com/engine/install/debian/#install-using-the-convenience-script

まずは古い Docker Engine をアンインストールします。
```bash
sudo apt-get remove docker docker-engine docker.io containerd runc
```

:::note info
上記のコマンド実行時に `パッケージ docker-engine が見つかりません` と表示されても問題ありません。
![Pi400-Docker_20230302172039.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/c36d379e-7fc6-bee8-d570-359a48ebe4c5.png)
:::

次にスクリプトをダウンロードして、 Docker Engine をインストールします。
```bash
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
```

Docker のバージョン確認をしてみます。
バージョンが表示されれば問題ありません。
```bash
docker version
```

Docker コマンドを実行するたびに `sudo` を付けるのは少々煩雑なため、 `docker` グループにユーザーを追加します。
```bash
sudo usermod -aG docker <ユーザー名>
```

付与した権限を反映するために再起動を行います。
```bash
sudo reboot
```


## Docker デーモンの起動
Docker デーモンを起動します。
```bash
sudo service docker start
```


## コンテナの起動
今回は hello-world イメージを起動してみます。
下記のコマンドを実行します。
```bash
docker run hello-world
```

`Hello from Docker!` と表示されれば問題ありません。
![Pi400-Docker_20230227153217.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/a8fe10d6-f999-5b1b-1fc5-98559c0d341e.png)
【GitLab】バージョンアップに失敗したのでバックアップからリストアする

# はじめに
13.xから14.10の最新版にアップグレードしたところ、
何故かアップグレードがコケてよくわからない状態になったので、一旦旧バージョンに戻すことにした。
幸いバージョンアップ時のバックアップを自動で取ってくれるので、そこから復旧する。

## バックアップデータの確認
### 設定ファイル
```
# cp -rp /etc/gitlab /etc/gitlab.bak
```
### GitLabデータ
```
# cd /var/opt/gitlab/backups
# cp -p XXXXXXXXXXX_YYYY_MM_DD_VV.V.VV_gitlab_backup.tar /tmp
```

## アンインストール
```
# gitlab-ctl uninstall
# rpm -e [インストール済gitlabのパッケージを指定]
```

## 再インストール
```
# rpm -ihv [インストールするgitlabのrpm]
```

## リストア
・設定ファイル
```
# mv /etc/gitlab.backup
# gitlab-ctl reconfigure
# gitlab-ctl restart
```
・gitlabデータ
```
# mv /tmp/XXXXXXXXXXX_YYYY_MM_DD_VV.V.VV_gitlab_backup.tar /var/opt/gitlab/backups
# gitlab-ctl stop puma
# gitlab-ctl stop sidekiq
# gitlab-backup restore BACKUP=XXXXXXXXXXX_YYYY_MM_DD_VV.V.VV
... 色々と警告は出るが、問題なければyesで進む
# gitlab-ctl reconfigure
# gitlab-ctl restart
```

ブラウザからアクセスして問題なく戻っていればOK。
【AWS】ALBでIP制限をかける

## AWS構成
ALBとECSを繋げて、ALBのドメイン名からアクセスするようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/33813489-3ffc-4524-305d-7874d9a2a2d4.png)

## 実践
1\. IP制限をかけたいロードバランサーの`Rules`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/8d7b9938-424e-95ad-c428-420af20d70d1.png)

2\. Manage rulesを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/c270e14a-14c9-988f-148a-e38baf6c650e.png)

3\.`+`を選択後、`ルールの挿入`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/ca1c3ad4-84cb-29a6-5f52-e89b917d424f.png)

4\. 送信元IPを選択
制限したいIPアドレスを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/e83b153c-984e-13c6-7d1e-2f0d4b5e6456.png)

5\. 転送先の選択
ECSではターゲットグループを選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/665ae9ff-a0e4-48f0-9446-42208d95f082.png)

6\. その他のIPアドレスの処理
4番でIPの制限はできたので他のすべてのアドレス(0.0.0.0/0)を追加します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/dae74631-7d4d-3e81-e152-fc73fd213e77.png)

7\. テキストの返却
5番ではターゲットグループを選択しましたが、固定レスポンスを返すように設定します。
html/textを選んで<h1>タグで囲んでエラーメッセージを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/3bf3b85c-337b-3f19-8018-8a755886903b.png)

8\. 制限したIP以外でのアクセス
ブラウザ上でDNS名を入力して以下のようになれば成功です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/79840eef-3c6e-1de1-a12c-679e03748e52.png)
Dagger Hiltで使えるアノテーションメモ

# 初めに
今回は個人的に覚えておいた方がいいDagger Hiltのアノテーションを紹介していこうと思います
### 本文
Binds
--- 
@Bindsはインターフェイスのインスタンスを提供するときにどのImplを使用するかを知らせる

Provides
---
@Providesはメソッド内でインスタンスを生成して注入

Qualifierch
---
@Qualifierh同じ型に複数種類のバインディングを提供するためのもの(枝分かれみたいに使える)

Named
---
@Namedは名前をつけるため
### 最後に
今回は備忘録程度に自分がHiltのアノテーションで勉強したことをまとめてみました
誰かのお役に立てれば幸いです