OmniAICreator/Qiita-1.07M huggingface dataset:
多言語FizzBuzzチャレンジ8日目:D言語

## これまでのまとめ

https://qiita.com/tenteko/private/fc52f7aec63ba5f67854

https://qiita.com/tenteko/private/ca9813f0982370d0c901

https://qiita.com/tenteko/private/bc808ba59f6993019045

https://qiita.com/tenteko/private/74aa4c422196cb5cdeac

https://qiita.com/tenteko/private/ea22bd19360333f9ca85

https://qiita.com/tenteko/private/ec2f7c2f99229a55a7aa

https://qiita.com/tenteko/private/237556777f5c5546af6e


## 本日のお品書き
ついに全く触ったことのない言語に到達しました…。おらわくわくすっぞ…！

## FizzBuzz
今回は環境を導入していません。充実のDLang Tourにコードの実行スペースがあるため、そちらで動作を確認してみました。

https://tour.dlang.org/tour/ja/welcome/welcome-to-d

```d
import std.stdio;

void main()
{
    for (int i = 1; i < 101; i++)
    {
        if (i % 15 == 0)
        {
            writeln("FizzBuzz");
        }
        else if (i % 3 == 0)
        {
            writeln("Fizz");
        }
        else if (i % 5 == 0)
        {
            writeln("Buzz");
        }
        else
        {
            writeln(i);
        }
    }
}
```

上記は一番愚直な例です。情報を検索してみると、もっとD言語らしい書き方というのがいろいろヒットしました。参考になりそうな記事を以下に引用させて頂きます。

https://qiita.com/cedretaber/items/90b7b34ee710eb5cc965#コンパイル時メタプログラミング
オンプレミスの監視ツールを刷新した話

[Cacti](https://www.cacti.net) というsnmp+RRDtool ベースなモニタリングツールを利用して監視していたものを

[prometheus](https://prometheus.io)+[grafana](https://grafana.com/grafana/)+長期保存ストレージ に移行した話。

## Cacti とは、
SNMPを利用したモニタリングツールで、ネットワーク監視などに主に使われている。
0.8x のころ、 weathermap というプラグインがあり、ネットワーク図を描いて、どこからどこへの通信が多いのか可視化できる便利さがあったが、1.0になったころ、対応せず、使えなくなった。という経緯がある。
データストアとしてRRDToolを利用している。

## RRDTool とは
時系列データのためのデータベースツール。直近のデータは細かく、古いデータはaggregateして大雑把に保存したりできる高性能なツール
古いデータをaggregateすることで、長期間のデータをコンパクトに保存できる。

## prometheus とは
モニタリングとアラートのためのツール。
時系列データを扱うことができる。

## grana とは
ダッシュボードツール。prometheusのデータを可視化できる。

# なぜ移行したのか
そもそも、Cacti以外にも社内では複数の監視ツールが動いており、個別に運用するのが手間だったので統一したかった。
統一先としてproemtheusが筋がよさそうだった。(ので、本記事ではCactiを対象にしているけれど、もういくつかの監視ツールを移行した。)

監視対象の追加はつど依頼を受けて設定する。という方法をとっており、時間がとられていたし、リードタイムもそこそこかかっていた。
proemtheusになって、設定ファイルをgit管理し、pull requestを出してもらってレビュー、mergeで自動反映させることができるようになり、監視対象追加にかかる、時間とリードタイムが減った。




# 移行手順
1. 各機器のsnmpで取得している情報を洗い出す
    * これはCacti の設定を見ていことで可能
1. 必要な監視項目を洗い出す
    * 今となっては不要な項目が存在する場合があるので忘れずに
    * 足りない項目があれば足す
1. [SNMP Exporter](https://github.com/prometheus/snmp_exporter) を導入する
    * 通信制限がかけられていることがあるため、snmp監視している端末から行う
1. prometheus でデータが取得できていることを確認する
1. grafana でデータを可視化しつつ、必要なダッシュボードを整備す
1. prometheusのデータをremote writeという機能を利用して長期保存ストレージにコピーする
1. Cactiとprometheusで取得できているデータに差がないことを確認できたらCactiからのデータ取得をやめる
    * 忘れずに新しいデータはproemtheusにあることを利用者に伝える
    * Cactiからデータ移行は大変なのでCacti は read only で残しておく
1. snmp監視から他のexporterに移行できないか検討する
    * linuxであれば [node_exporter](https://github.com/prometheus/node_exporter) が利用できる
    * カスタムsnmpメトリクスについても、良いexporter がないか探す
1. 他のexporterに移して問題なければ snmnp_exporterから対象を削除していく
1. grafanaもしくは Alertmanagerでアラートを設定していく

# 移行してどんないいことがあったか
* データ取得が速くなった
  snmpはデータ取得にそこそこ時間がかかっていたが、snmpの利用をかなり縮小できて、結果、速くなった
* 冗長化できた
  proemtheusを2台動かして、両方から同じデータを取得しており、片方が止まっても大丈夫になった
  Cactiは設定がデータベースにあるため、設定の同期が大変で冗長化できていなかった
* ダッシュボードがモダナイズされた。
    見た目が今風なのはとてもいい。
    初見でもわりとダッシュボードが作れる(proemtheusへのクエリを少し覚える必要はあるけれど)
* 権限管理が楽になった
  SAMLやgoogleログインが可能なので、ユーザ管理が楽
* 監視が民主化された
  上記2点の結果でもあるのだけれど、誰でもダッシュボードやアラートが設定できるようになったので

# 苦労したところ
監視対象の洗い出しと必要な項目の洗い出しがとても大変だった。

そもそもすでに動いていない監視対象もCactiには存在していて、そもそも量が膨大だった。

監視項目の洗い出しでは、取得しているけど使っていないだろう。という項目について、取得をやめる。という決断がしにくかった。
今まで取得していたのだからとりあえず欲しい(でも見てない)。に対抗するのはそれなりに大変。

# 難しいところ

prometheus 自体としては標準で2週間分くらいのデータしか保持しないようになっており、期間を増やすことも推奨されていないので
長期保存には別のデータストアを用意する必要がある。

データストアとしては[Thanos](https://thanos.io), [cortex](https://cortexmetrics.io), [victoriametrics](https://victoriametrics.com), [Mimir](https://grafana.com/oss/mimir/) などがある。

データストアにはaggregate機能があるもの、ないものがあるので自分たちの用途にあったものを探す必要がある。
実際、aggregate機能のないデータストアを選択し、保存期間もCactiのころの2年より短くした。

proemtheus 1台で膨大な量のデータを扱うのが難しいらしい。その場合、proemetheusを複数台動かして、データ取得対象を分散させる必要があるとのこと。
これは、オンプレミスの限られた範囲での利用だったので問題になるほどではなかった。
大規模事例としては[LINEの事例](https://www.youtube.com/watch?v=3MvHTwRQcT8)がある。
【Python】HDF5で日本語出力ができなくて困った件


## 背景
HDF5で日本語を保存したとき
` b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'`
のような出力になってしまい困っていたのですが、解決できまちた

が、より良い方法があればご教授いただけると幸いです٩( 'ω' )و

そしてPythonを普段使わないのでマズイことしてたらご指摘くださいませ

## バージョン情報
python:3.6.1
h5py:2.7.0
※ Dockerで動かしています

## コード
出力時に`decode('utf-8')`でデコードを行うことで解決できました。
``` python
import h5py

with h5py.File('sample_dataset.hdf5', mode='w') as f:
    # vlen=str でないとUnicode文字が使えないので注意
    str_dtype = h5py.special_dtype(vlen=str)

    dataset = f.create_dataset(
    'str_dataset', shape=(1,1), dtype=str_dtype)
    dataset[0,0] = 'あいう'
    # 以下の形式でhdf5ファイルに保存
    # b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'

with h5py.File("sample_dataset.hdf5", "r") as f:
    data = f["str_dataset"][0,0]
    # 出力時にデコードを行う
    print(data.decode('utf-8'))
    print(data)
    # 出力：あいう

```

## 参考

https://grapebanana.com/python-encoding-utf-8-7161/

https://docs.h5py.org/en/2.8.0/strings.html
UDPヘッダをかんたんに説明してみる

# 勉強前の理解度
* UDPヘッダというものが存在する


# UDPヘッダの概要

### 送信元ポート番号(16bit)
　**送信元のポート番号**。
　返答を必要としない場合、この値を0にして送信することがある。

### 宛先ポート番号(16bit)
　**宛先のポート番号**。


### パケット長(16bit)
　**UDPヘッダとデータの長さの合計値**をオクテット単位で示す。


### チェックサム(16bit)
　**UDPヘッダとデータが破損していないかを示す**。初期値は0。対象範囲の1の補数の和の合計値を16bit単位で求め、その1の補数を保持している。対象となる範囲は、UDPヘッダとUDPペイロード、UDP疑似ヘッダである、**UDP疑似ヘッダはチェックサムの計算のためにUDPヘッダの前に疑似的に用意されるヘッダ**で、実際の通信には含まれない。

##### 1の補数の和の1の補数をとる理由
　チェックサムの計算で「1の補数」ではなく「**1の補数の和の1の補数**」を利用する理由の一つに、受信者側のチェックサムの確認が簡略化されることがあるらしい。受信者側が対象範囲の合計値の1の補数を計算して、それが0になるかを確かめるだけでよいからだ。

　例えば、チェックサムが初期値の0の状態でチェックサムを計算して、その1の補数の和が「**1001**」であったとする。当然チェックサムは「**0110**」となる。(チェックサムとその計算単位を4bitに簡略化した)
　そして、受信側が計算する1の補数は**1001**(チェックサム以外)+**0110**(チェックサム)=**1111**となり、チェックサムは「**0000**」となる。「1の補数の和の1の補数」を利用する場合は、チェックサムが**0**であることを確認するだけで良いのだ。
　※受信者側が求めるチェックサムは、「16bitごとの合計値の1の補数」である(送信側と計算方法が異なる)。

　一方、「1の補数」を利用する場合は、送信者側が計算してチェックサムを一旦保管して、受信者が計算したチェックサムと比較しなければならない。これだと受信者側の手間が増えてしまう。(みたいな感じだと思う)



# 参考
[第13回　データグラム通信を実現するUDPプロトコル：基礎から学ぶWindowsネットワーク（3/4 ページ） - ＠IT](https://atmarkit.itmedia.co.jp/ait/articles/0310/09/news001_3.html)
[IP チェックサムの秘密](https://www.mew.org/~kazu/doc/bsdmag/cksum.html)
[マスタリングＴＣＣＰ/IP](https://www.ohmsha.co.jp/tbc/text_series_0201.htm)
【備忘録】【Rails】initializeメソッドの使い方

自分用のメモです。

# initializeメソッドとは(一言で)

- コンストラクタのこと。

# コンストラクタとは
- オブジェクトを生成した際に1度だけ実行される機能を指す名称。
- なお、オブジェクトが生成された際にのみ実行されることから、そのオブジェクト内で共通に使えるインスタンス変数の初期化などに使われる。
- ただしクラスを定義した際、コンストラクタを必ず作る必要はない。
- コンストラクタが定義されていなくてもオブジェクトを生成できる。
- また、Rubyではオブジェクトを生成するnewメソッドの引数を利用して、コンストラクタによる変数の初期化も可能。

# initializeメソッドの特徴

- initializeメソッドを定義しておくと、インスタンス生成時に必ず実行したい処理をメソッドを呼び出すことなく実行することができる。
- 例えば次の例では、initializeメソッドの中でインスタンス変数の初期化を行っている。

```ruby:
class Car
  def initialize()
    @name = "未定義"
  end
end

car = Car.new()
```

 - こうすることで、Car.newでインスタンスを生成したあとでメソッドを呼び出す記述をしなくても自動的にメソッドを呼び出してくれるので便利。
 - initializeメソッドを使わない場合は、このように書かないといけない。
 
```ruby:
class Car
  def init()
    @name = "未定義"
  end
end

car = Car.new()
car.init()
```

# 引数を渡すこともできる

```ruby
class Hello
  # 名前を保持するクラス変数
  @name = nil
  
  # クラスの初期化メソッド
  def initialize(name)
    @name = name
  end
  
  # クラスのインスタンスメソッド
  def talk
    puts "hello, #{@name}"
  end
  
end
 
# classのnewメソッドに引数を渡す
hello = Hello.new("asami")
 
# newメソッドからinitializeメソッドに渡って初期化された名前が使用される
hello.talk
```

この場合、initializeメソッドを呼びだす時(インスタンス生成時)に引数を指定して呼び出すことになるから、メソッドに値を渡すことができる。
そしてメソッドの中で、"asami" が @name に代入される。
最後にインスタンス変数であるhelloに対してtalkメソッドを実行しているので、以下が出力される。

```ruby:出力結果
hello, asami
```

# 参考にさせていただいた記事
[initializeメソッドの使い方
](https://www.javadrive.jp/ruby/class/index5.html)
[【Ruby入門】classのnewとinitializeについてまとめ](https://www.sejuku.net/blog/21170)
cdkでLambda Layerを作成するときは、zip化しないでOK

# はじめに
レイヤーを使うLambdaを、cdk(python)で作成したいことってありますよね。
そのとき、ちょっとはまったので共有します。

# 内容
cdkでの文法などは
https://medium.com/geekculture/deploying-aws-lambda-layers-with-python-8b15e24bdad2
ここなど参考にどうぞ。

問題は、cdkで作成したディレクトリ直下に配置するlayerを格納するディレクトリ（ここではlambda-layersとします）についてです。
一般的にLambdaのレイヤーには、zipで固めたファイルをインポートしますが、**zip化はcdkがやってくれる**のでやる必要はありません！というよりむしろ、**やってはいけません**！！
（これをやってしまい、エラーが発生していました･･･）

lambda-layersにいる状態で
```bash
$ mkdir python
$ pip install -t python requests
```
これでOKです。安心して、cdk deployしましょう（裏でcdk君がzip化してくれます）。
ちなみに、lambdaのレイヤーを作るときのお作法として、pythonというディレクトリは固定だそうです。
AWS上にTerraform実行環境を最速で構築する

# はじめに
 - Terraformの場合、CloudFormationと違い、PCやEC2など`実行環境の準備`とTerraformが使うための`認証情報（アクセスキー/シークレット or IAMロール）の設定`が必要になる。
 - ちょっとテストでコード作成・デプロイしたい場合や、最初のリソース作成だけをTerraformでやりたい場合は、そのためにこれらに環境を準備することに手間を感じていた。
 - そこでAWS CloudShellを使った`1分でできるTerraform実行環境の構築手順`を整理してみました。

# 最速Terraformデプロイ
## 0.必要なもの
 - AWSアカウント
 - Terraformデプロイに必要な権限を割り当てられたIAMユーザ（AdministratorAccess）
 
## 1.実行環境の起動
 - Terraformデプロイに必要な権限を設定したIAMユーザでマネジメントコンソールにログイン。
 - 上部のバーをクリックし、Cloud Shellを起動します。
![fig1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598740/e543c25e-7e04-14ec-57bb-7099f0fa5165.png)

> CloudShellとは

https://docs.aws.amazon.com/ja_jp/cloudshell/latest/userguide/welcome.html

## 2.Terraformのインストール
#### Terraformのインストール方法
 - terraformコマンドの実行ファイルをHashicorpのサイトから直接ダウンロードします。

```bash:以下をコピペしてください。
## 実行ファイルのダウンロード
curl -o tf.zip https://releases.hashicorp.com/terraform/1.3.4/terraform_1.3.4_linux_amd64.zip

## ファイルの解凍
unzip tf.zip

## コマンド実行ファイル置き場をhomeディレクトリに作成、ファイルを移動
mkdir .bin
mv terraform .bin/

## パスを通す
echo "export PATH=$PATH:$HOME/.bin" >> .bashrc
source .bashrc
``` 
> CloudShellへのTerraformのインストールについては、yumやtfenvで行うことも可能ですが、homeディレクトリ以外への変更は、一度ログインセッションが切れるとリセットされます。

>  最新バージョンのダウンロードURL確認先
> https://www.terraform.io/downloads
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598740/d5f18c12-ffe1-8036-99d5-d217158cb463.png)


#### インストール後の確認
- 以下のように`terraform -v`と入力して、バージョンが表示されればOKです。
```bash:"terraform -v"を入力 
$ terraform -v
Terraform v1.3.4
on linux_amd64
``` 


## 3.デプロイ（Init/Plan/Apply）
- ログインしているIAMユーザの権限がCloudShellにも引き継がれているため、そのままデプロイできます。

#### tfファイルの作成
```main.tf
 # AWS Provider を設定
 provider "aws" {
   region = "ap-northeast-1"
 }

 # VPCを作成
 resource "aws_vpc" "example" {
   cidr_block = "10.0.0.0/16"
 }
```
<br>

#### terraform init
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598740/440f1ed9-4577-62f5-2b82-041c3960c660.png)

#### terraform plan
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598740/ff185b58-63ec-308a-a44a-612178f672f2.png)

#### terraform apply
![fig8_vpc-apply-result1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598740/4609abed-7ee9-6420-0a4f-31f328889119.png)
Bigqueryの料金抑制方法①/アラート作成

## 概要
bigquery警察なるパトロールシステムの実装方法
大規模クエリが実行され続けると料金が増大してアラート連絡の実行


## 対応方法

①指標トリガーを作成（どれくらいの閾値になればアラートを発するのか）
②媒体チャンネル設定の作成

#### ポリシー作成　
##### 手順

ポリシーを作成(通知ポリシーの作成)より作成 > 指標としてBigqueryを選択 > アラートのトリガー基準を作成 > Notification Channelsでアラートを通知するチャンネルを選択
(未作成の場合は[チャンネル作成]より媒体を選択して作成)

作成ページ：
GCPポリシーページ

◼︎指標としてBigqueryを選択
ー指標にbigqueryを指定
◼︎アラートのトリガー基準を作成
ー基準の設定

## テスト

#### テスト概要
アラートを作成してSMSへ通知するか確認した結果
「above 数値となることを確認」




## 参照ドキュメント

[Google Cloud Platform でアラート通知設定](https://qiita.com/KKawa/items/996c2bd34f5f7092ab8f)

[GCP公式ドキュメント:指標ベースのアラート ポリシーの管理](https://cloud.google.com/monitoring/alerts/using-alerting-ui?hl=ja#preview-interface)
Databricksにてdbutils.widget により RUN IDを取得する方法

## 概要

Databricksにてdbutils.widget により RUN IDを取得する方法を共有します。

以前の記事にて、`dbutils.notebook.entry_point` にて RUN ID を取得する方法を紹介したのですが、特定の環境ではエラーとなり取得できないようです。

https://qiita.com/manabian/items/c41b9439d24ead7910b4

> py4j.security.Py4JSecurityException: Method public java.lang.String com.databricks.backend.common.rpc.CommandContext.toJson() is not whitelisted on class class com.databricks.backend.common.rpc.CommandContext

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/2d1f2257-a1b2-4b2c-c05d-44dd945d6d6f.png)

パラメーター変数を dbutils.widget により取得する方法を代替案として考えました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4da17650-3d05-752b-e0ac-0b0ee549178c.png)

引用元：[タスク パラメーター変数 - Azure Databricks | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/databricks/workflows/jobs/jobs#--task-parameter-variables)

## 実施方法

### 1. ジョブを実施するノートブック（`run`）にて下記のコードを記載

```python
para = {
    "job_id":'{{job_id}}',
    "run_id":'{{run_id}}',
    "start_date":'{{start_date}}',
    "start_time":'{{start_time}}',
    "task_retry_count":'{{task_retry_count}}',
    "parent_run_id":'{{parent_run_id}}',
    "trigger_info_col_value": '{"triggered_by": "job","job": "{{job_id}}", "job": "{{run_id}}"}"}'
}
 
dbutils.notebook.run('./print', 0, para)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/441005ad-1a40-8073-bcc0-59c4196eb1cc.png)

### 2. ジョブとして実行されるノートブック（`print`）にて下記のコードを記載

```python
dbutils.widgets.text('job_id', '')
dbutils.widgets.text('run_id', '')
dbutils.widgets.text('start_date', '')
dbutils.widgets.text('start_time', '')
dbutils.widgets.text('task_retry_count', '')
dbutils.widgets.text('parent_run_id', '')
dbutils.widgets.text('trigger_info_col_value', '{"triggered_by": "manual"}')

print(dbutils.widgets.get('job_id'))
print(dbutils.widgets.get('run_id'))
print(dbutils.widgets.get('start_date'))
print(dbutils.widgets.get('start_time'))
print(dbutils.widgets.get('task_retry_count'))
print(dbutils.widgets.get('parent_run_id'))
print(dbutils.widgets.get('trigger_info_col_value'))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/9aa1c239-350d-6154-55d8-f17cee7265b0.png)

### 3. 1 のノートブックを実行して、実行されたジョブのリンク（例：下記画像の`Notebook job #320448512477653`）をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/bfecf6e1-6e7b-8f8c-b5f3-fbb52398c005.png)


### 4. パラメータ引数が書き換えられて（`override`）、 dbutils.widgets.get により値を取得できていることを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e2f87389-08e6-3916-1e56-96ce672b6121.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e3eb5bfe-046d-682b-4135-c03c5b305d63.png)
技術的負債と向き合ってみる

# 技術的負債とは

```
なんらかの問題が起こったとき、技術チームはしばしば妥協策を取ります。
しかし、実はこれは、最善の対応にかかるコストの支払いを先延ばしにしているにすぎません。
```

```
また、借金と同じように、技術的負債にも “利子” が発生します。 
プロジェクトの成長に伴って、問題への対処はどんどん難しくなり、コストもかさんでいきます。
```

「技術的」とついていますが、普通の負債と変わらないんですね。
早く返済しないと利子が増えていき、どんどんと返す期間が伸びていく、と。

いっそ無かったことに、または見なかったことにしたいですね…。

# 技術的負債はなぜ生まれるのか

そんな技術的負債はなぜ生まれてしまうのでしょうか？
また、なぜ大きく膨れ上がってしまうのでしょうか？

### 1. 知識の喪失/外的環境の変化

同じプロジェクトにずっと同じ人が同じポジションで携わることは非常に稀です。
普通のプロジェクトですと、初期の立ち上げと、その後の運用とでメンバーが入れ替わることが多いです。

そのため、プロジェクトの知識を受け継ぐためにドキュメントを作成することがよくあります。

しかし、そのドキュメントも最初に作ってからメンテナンスがされなかったり、
ドメイン（業務）に着目して作られておらず、業務の変化に対応できない場合は資産ではなく負債になります。

また、伝言ゲームと同じで、最初の意味・意図は途中でどんどんと変わっていってしまいます。

最初の意味・意図が正常に受け継がれたとしても、周囲の環境が立ち上げ当初と変わっている場合もあります。
周囲の環境が変わってしまっては、たとえドキュメントが正しく受け継がれたとしても、当初の目的を果たせません。

このようにして知識が失われ、周囲の状況は変化し、システムがレガシーなものへとなっていきます。

### 2. 必要な変更の規模が大きくなる/変更に必要な時間は短くなる

最初から複雑化つ巨大な物を作るプロジェクトは稀です。
どんなサービスも、小さくスマートに始めることが多いです。

そこから、新機能の追加であったり、既存機能の改善という形でアップデートを繰り返していきます。
初めのうちはそこまで問題ではありません。少しの変更で新たな要望に応えていけます。

この時に、将来のことを考えて修正を行ったとします。
しかし、残念なことに、その時に考えた状況と、実際に迎えた状況は大きく異なることが多いです。

結果として、意図しない形で負債が発生します。

また、ビジネスはどんどん加速していくので、システムの変更もそのスピードについていくことが求められます。
ここでシステム改修に時間をかけないため「妥協策」を選ぶことがよくあることです。
結果、その「妥協策」がじわりじわりとシステム変更にとっての障害物、つまりは技術的負債となることがあります。

それなら「妥協策」を選ばなければいいではないか！と、思いますが、「ビジネス」はそれを許してくれません。

時間は有限です。また、大抵のチャンスは一瞬です。
妥協しなかった結果、良いものが出来上がったとしても、時を逸してしまっては元も子もありません。

私は技術的負債をよく「ジェンガ」に例えてイメージします。
限られた時間でピースを抜いて、積み上げる必要があるならば、取りやすいところ取ってしまいますよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190745/7946402c-42d6-5146-811e-4a431ac73445.png)

結果として、後半になればなるほど、改修の難易度が上がっていくのです。
今、我々の目の前にある技術的負債とは、絶妙なバランスの上に成り立っているのです。

# 技術的負債と向き合う/理想を考える

さて、そんな技術的負債ですが、そのままにしておく訳にはいきません。
そのままにしていては、もう手が付けられません。

下手に触ったら崩れるのが目に見えています。
目の前にある複雑に積み上がったジェンガ（技術的負債）、、、どうしましょう？

### その1. 見なかったことにして、危険を承知で突き進む
危険を承知で突き進んだ結果、それまで積み上げてきたものは崩れてしまうことでしょう。

### その2. 最初からやり直す
リニューアルプロジェクトです。

[20万人月の作業を1人でやる話 〜1万7千年生きたSE〜](https://nihonpanda.hatenablog.com/entry/2016/07/06/151239) なんてネタもありました。
※最終的には３５万人月になったようですが…

最初からやり直すとしても、要件を整理したりで時間を要するので簡単にはいきません。
溜まりに溜まった負債は、そう簡単になくなりません。

仮に最初からやり直すとした場合、潔く色々なものを捨て去るのが良い気がします。

### その3. コツコツと積み上げ直していく
これは現時点で自分が考える理想案です。
具体的にはチームを2つに分けて取り組めたらいい、と考えています。

- とにかく速度優先！ガンガン進めるチーム（とはいえ、多少は考えて作る）
- 堅牢な土台を築いていくチーム（最初のチームが作ったものをリファクタしていく）

作った端からガッチリ固めていけば堅牢なものができあるのでは！と思っています。
スピードも落とさないのでビジネスにもついていけるはず！

ただ、この案にも欠点があります。

まずコストですね。単純計算で2倍のコストが発生します。
チーム2つ分の稼働費用が発生します。

また、後から追いかけるチームが先をいくチームに追いつけなくなる可能性もあります。

追いつけなかった場合、先をいくチームはスピード優先で作ったものに更なる改修を行うため
意図せずに負債が発生してしまいます。

# まとめ/所感
技術的負債に立ち向かう道のりは、長く険しいですね。
夏休みの宿題のように後回しにはできないので、日々コツコツと向き合うのが理想ではあります。

作ったその時は良くても、後々振り返った時には絶対にレガシーなものになってしまうのはよくあることです。
覚悟を決めて、日々、自分が作ったものをキレイにしていきたい、と頭では思うのですがね…

現実とは厳しいものです。

残念ながら今回の考察では、どのように立ち向かうのが良いのか答えを出せませんでした。
これからも日々、考察を重ねて参りたいと思います。

---

# 引用元
- [技術的負債とは？DevOps で負債を計測し管理する方法](https://circleci.com/ja/blog/manage-and-measure-technical-debt/)
- [20万人月の作業を1人でやる話 〜1万7千年生きたSE〜](https://nihonpanda.hatenablog.com/entry/2016/07/06/151239)
【備忘録】【Rails】クラスメソッドとインスタンスメソッドの違い

クラスメソッドとインスタンスメソッドの違いについて、曖昧な理解だったため、今回改めて勉強しました。


# クラスメソッドの特徴

- クラス内で def self.メソッド名 〜 end で定義する
- クラスから直接データを呼び出すことができる
- あるモデルクラス全体に対し、情報を変更したり、参照したりするメソッドを作成するときに使うと便利
- 例えば「User」クラスを作成した場合を例にするなら、ユーザー一覧の表示や、ユーザー全体で共有して使うステータスを更新するメソッドを作成するときに使うと良い。

```ruby:def self.method_name での書き方
class Hoge
  def self.hoge
    puts "hoge"
  end
end
Hoge.hoge # => hoge

# selfはHogeでもOK
```

```ruby:class << self 内でクラスメソッドを定義する書き方
class Hoge
  class << self
    def hoge
      puts "hoge"
    end
  end
end
Hoge.hoge # => hoge

# selfはHogeでもOK
```

# インスタンスメソッドの特徴

- クラスからインスタンスを生成しないと呼び出すことができない
- あるモデルクラスがあった時、そのモデルから個別のインスタンスに関わる情報を変更したり、参照したりするメソッドを作成するときに使うと便利
- 例えば「User」クラスを作成した場合を例にするなら、特定のユーザーインスタンスのプロフィールを表示したり更新したりするメソッドを作成するときに使うと良い

```ruby:インスタンスメソッドの書き方
class Hoge
  def hoge
    puts "hoge"
  end
end
Hoge.new.hoge # => hoge
```

# 両者の違い
- クラスメソッドはクラス自身に関する情報の変更や参照の役割をもっているのに対して、インスタンスメソッドは個別のインスタンスに関する情報の変更や参照の役割りを持っている。

# クラスメソッドとインスタンスメソッド、どちらを使うべきか迷ったら
- 迷ったときは「とりあえずインスタンスメソッド」を使うべし。

# こちらの記事には実例が書かれていて、とてもわかりやすかったです。
- [クラスメソッド、インスタンスメソッド。いつ使うのか。
](https://qiita.com/right1121/items/c3997653a621c74fb97d)

# その他、参考にさせていただいた記事
- [Rubyのクラスメソッドとインスタンスメソッドの例
](https://qiita.com/tbpgr/items/56eb65c0ea5882abbb07)

- [【Ruby入門】クラスメソッドとインスタンスメソッドの使い方まとめ](https://26gram.com/ruby-class-and-instance-methods)
一般ユーザにシステム管理コマンドの使用許可方法（sudo・/etc/sudoers・visudoコマンド）

Linuxを勉強し始めて約1ヶ月経過。
ずっとrootユーザでコマンド叩いてたので、そろそろ一般ユーザで作業してパーミッションに慣れようと決意。
「管理ユーザコマンド実行したい時にはとりあえず’sudo’をコマンドの前に打てばいいんだろ？　」
と横柄な態度で望んでいたらコマンド弾かれて痛い思いしたのでその記録

## 理解すること
・ただsudoをコマンド文頭に打てば使えるわけでない
・システム管理コマンドの使用を一般ユーザにも許可する
⇒　`/etc/sudoers`を編集する
・`/etc/sudoers`は特殊ファイルなので、`visudo`コマンドで編集
※`vi`コマンドは使わない
・コマンドレベルの許可・ユーザレベルの許可ができる


## `$sudo date 121020002018`で弾かれた

システククロックの変更のため、
```
[yuzo@localhost ~]$ ls -l `which date`
-rwxr-xr-x. 1 root root 108640 10月 21  2021 /usr/bin/date
[yuzo@localhost ~]$ sudo date 121020002018
[sudo] yuzo のパスワード:
yuzo は sudoers ファイル内にありません。この事象は記録・報告されます。
```

エラーに
`「yuzo は sudoers ファイル内にありません。この事象は記録・報告されます」`

sudoersファイルに「現在ログインしてるユーザー（yuzo）にsudoの実行権限を付与」しないといけないようです。

話はそれますが、エラーの後半部分「この事象は記録・報告されます」のログを確認します。

```:tail -f /var/log/secure
Nov  3 15:05:09 localhost sudo[6381]:    yuzo : user NOT in sudoers ; TTY=pts/1 ; PWD=/home/yuzo ; USER=root ; COMMAND=/bin/date 121020002018
```
しっかり認証が弾かれたユーザー名とコマンドがログに残っています。

## 一般ユーザに管理コマンドの実行権付与する

```
[root@localhost] ~ 15:30:56 # ls -l /etc/sudoers
-r--r-----. 1 root root 4328  4月 20  2022 /etc/sudoers
```
パーミッションが440の特殊ファイルなので`visudo`コマンドで編集します

```:visudo
#ファイル最終行に「システム管理コマンド"date" を"yuzo"でも使用可能にする設定」
yuzo ALL=(ALL) /usr/bin/date
```
設定が終わったので、yuzoでログインしてターミナルで再度`sudo date 121020002018`コマンド実行
```
[yuzo@localhost ~]$ sudo date 121020002018
2018年 12月 10日 月曜日 20:00:00 JST
```
一般ユーザーyuzoにdateコマンドを使用可能にしたので今回は打てました。

ただこれだと一つ一つの管理コマンドを`visudo`で追加で手間なので全てのシステム管理コマンドを付与する場合には次のように設定

```:visudo
#ファイル最終行に「システム管理コマンド"date" を"yuzo"でも使用可能にする設定」
#yuzo ALL=(ALL) /usr/bin/date //コメントアウト
user2 ALL=(ALL) ALL
```

動作確認

一般ユーザに参照権限与えられていないログファイルやpwハッシュ化された/etc/shadowファイルが一般ユーザでsudo付ければ見れることの確認

```
[yuzo@localhost ~]$ sudo tail -n 1 /var/log/{messages,secure}
[sudo] yuzo のパスワード:
==> /var/log/messages <==
Nov  3 16:06:40 localhost systemd[1]: Started Fingerprint Authentication Daemon.
==> /var/log/secure <==
Nov  3 16:00:53 localhost sudo[7606]: pam_unix(sudo:session): session closed for user root
```

※ここで求められるパスワードはrootユーザーのpwではなく、ログインしているユーザー自身のpw
ポモドーロテクニックってなに？

# ポモドーロテクニックとは？
初めて聞く方は、ポモドーロ？なにそれ美味しいの？って思うかもしれませんが、
簡単に言うと**集中力と生産性を高め、効率よく仕事を進めることができる時間管理術**のことで、
**1つのタスクを細かく分割し、分割した1つ1つのタスクを短時間で終わらせてから休憩する**という短い作業時間と休憩を繰り返していく方法のことを言います。
この方法を行うことで、1つの時間区切りのなかでタスクを終わらせるために、集中力と生産性のアップが期待できます。

# なんでポモドーロって名前なの？

- 90年代はじめに、起業家で作家でもあるフランチェスコ・シリロ氏が発案
- ポモドーロ（イタリア語でトマトの意）という名前は、シリロ氏が学生時代に愛用していたトマト型のキッチンタイマーに由来している。

割と最近の方で、本も出されているみたいですね。
[![スクリーンショット 2022-10-26 17.50.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604036/9993548a-5b53-62a0-9466-8593959fd683.png)](https://www.amazon.co.jp/%E6%9C%AC-%E3%83%95%E3%83%A9%E3%83%B3%E3%83%81%E3%82%A7%E3%82%B9%E3%82%B3%E3%83%BB%E3%82%B7%E3%83%AA%E3%83%AD/s?rh=n%3A465392%2Cp_27%3A%E3%83%95%E3%83%A9%E3%83%B3%E3%83%81%E3%82%A7%E3%82%B9%E3%82%B3%E3%83%BB%E3%82%B7%E3%83%AA%E3%83%AD)

# 具体的にどうやって行うの？
結論から言うと、「**25分間作業に集中し、５分休憩を取ること**」です。

もっと詳しく説明していくと、
~~~
① その日に達成したい1つのタスクを細かく分割する
② 分割した1つのタスクを25分間集中して行う（タイマーをセット）
③ 5分休憩を取る
④ ②と③を繰り返し、4ポモドーロ（2時間）ごとに30分間の休憩を取る
~~~

の、流れになります。

# それって効果あるの？→【ある】

まず、集中力には脳内伝達物質であるβエンドルフィンが影響しているといわれています。
 βエンドルフィンは「脳内麻薬」とも呼ばれ、**集中力・作業スピードをアップ**させる効果があります。

人が集中し始めるとβエンドルフィンが徐々に分泌され、**15分～20分でピーク**に達します。
そこからは下降していくので、これが25分に1度の休憩が効果的と判断された根拠とのことです。

当然、個人差はあるので、25分を基準として自分に最適な時間を見つけるのが理想的です。
私は会社で１週間に一度、１時間だけ「**ポモドーロ会**」がありますが、そこで自分が学びたい分野を学び、インプットする時間とアウトプットする時間に分けてポモドーロテクニックを使用していますが、これが意外と集中できて１時間があっという間に過ぎ、やるべきことに集中できているので、おすすめです。

# ポモドーロでもっと生産的になりたいあなたへ

実はポモドーロテクニックの効果を上げるポイントもあります。

#### ①正確に時間を測ること
これぐらいかな？って自分の中の時計ではなく、タイマーを使ってしっかり測りましょう。
ちなみに会社のタイマーはこれを使っています。

https://amzn.asia/d/1chqUBH

#### ②その２５分間で完璧にこなすのではなく、中途半端に終わらせる
これは中途半端に終わらせることで、次のポモドーロの時に続きから始めやすくなるためです。

#### ③１ポモドーロ（=25分）で何をするかまで細分化する
このポモドーロの時はこれ！と明確にし、次に何に取り組めばいいのか分かるようにタスクを細分化しておきましょう。

#### ④やらないことをリスト化し、決めておく
例えば、
```
・メールを見ない、電話にでない→休憩時間にまとめて行う
・音楽を聴かない→ノイズキャンセリングを使用する
・携帯を触らない→目の見えないところに置く
・分からないところをすぐに質問しない→あとでまとめて聞くようにする
```
このように「〇〇しない」代わりに、「あとで〇〇する」という自分なりの行動パターンを決めておくと良いです。

#### ⑤休憩中は作業をせずに頭の中を開放（深呼吸、ストレッチ,コーヒーなど）
休憩中も仕事が気になったりしますが、頭の中を空っぽにし一度リセットしましょう。ひたすらボーッとするのでもいいですし、体を動かしてみるのも良いです。

#### ⑥最初のポモドーロに最も集中することが大切
最初の時にポモドーロのスイッチを入れましょう。最初がダレてしまうとその後のポモドーロも上手く効果を実感できません。
どうしても集中できない時は、無理にポモドーロを意識しなくてもよいでしょう。

#### ⑦簡単に集中することが難しいことに使うべきである
逆を言うと、「**自分の自由時間に使うべきではない**」ということです。
仕事のここぞと言うタイミングでこのテクニックは使うべきでしょう。

## 最後に
いかがでしたでしょうか？
一度集中すると長い時間集中できる方もいるので、無理に２５分に合わせなくても良いです。
自分に合ったポモドーロテクニックで、仕事もプライベートも充実させていきましょう！！
refresh_tokenでリフレッシュしたい

# １．はじめに
　Google AssistantからアクセスできるＡＰＩを作成して、ローカルで音楽再生をさせたりしているのですが、だいたい翌日にはステータスを拾えなくなっています。再リンクを行えば回復はするのですが、ちょっと使いづらいのは確かです。そういう風にステータスを拾えなくなるサービスは他にもあるのでそういうものなのかと思わなくもありませんでしたが、HTTPサーバーのログを見ると、トークン制御のアクセスで４００が出ています。

　OAuth2ってそういうものでしたっけ。
# ２．リフレッシュトークンでリフレッシュさせたい
　もちろん違って、アクセストークンの期限が切れたらより期限の長いリフレッシュトークンを使ってアクセストークンを取り直すことができるはずです。念のため、topen.phpへPOSTされたデータを確認するとトークンリフレッシュが要求されています。
```
grant_type=refresh_token&refresh_token=dff5……bd37&client_id=googleclient&client_secret=secret
```
　ただ、ログを取ると400(Bad Request)を返しているので改めて[OAuth2 Server PHP](https://bshaffer.github.io/oauth2-server-php-docs/ )のGrant Typesにある[Refresh Token](https://bshaffer.github.io/oauth2-server-php-docs/grant-types/refresh-token/ )を読んでみると、OAuth2サーバーを簡単に構築する[cookbook](https://bshaffer.github.io/oauth2-server-php-docs/cookbook/ )ではリフレッシュトークンを使った許可延期の処理は組み込まれていないのでした。

　リフレッシュトークンを使った許可処理を組み込むにはcookbookで作成した`server.php`にrefresh_token許可のメソッドを追加します。
```
$server->addGrantType(new OAuth2\GrantType\RefreshToken($storage, array(
    'always_issue_new_refresh_token' => true,
    'unset_refresh_token_after_use'  => true, 
    'refresh_token_lifetime'         => 1209600,
)));
```
`GrantType\RefreshToken()`は３つのオプションを持っています。
+ `always_issue_new_refresh_token`
　リフレッシュトークンが使われるとリフレッシュトークンを新規発行する（デフォルト:false)
+ `unset_refresh_token_after_use`
　使われたリフレッシュトークンを取り消す（デフォルト:true)
+ `refresh_token_lifetime`
　リフレッシュトークンの寿命（デフォルト:1209600(２週間))

　試行錯誤はしましたが、`always_issue_new_refresh_token`を`true`にするのが良いようです。デフォルトのままだと、リフレッシュ処理が１回行われてaccess_tokenが発行されますが、使われたリフレッシュトークンは削除されて二度目のリフレッシュができなくなりました。（なんか微妙な動きという気はします）
# ３．動作確認
　動作確認するためにはリフレッシュトークンが使われなければなりません。一旦リンクを取り直すと１時間有効のアクセストークンが出されるので、１時間待ってアクセストークンの有効期限が切れるのを待ちます。１時間経ってgoogle Assistantを再読み込みさせてアクセスログにtoken.phpへのアクセスがが200であればＯＫ。念のためさらに１時間待って再度リフレッシュトークンが発行されるかどうかを確認します。
　トークンの発行状況ですが、oauth2用に作成したテーブルを確認するのが容易なようです。
+ アクセストークンの一覧
`select * from oatuh_access_tokens order by expires;`
+ リフレッシュトークンの一覧
`select * from oatuh_refresh_tokens order by expires;`

　oauth_access_tokensに１時間有効のトークンが登録され、oauth_refrsh_tokenに２週間有効なトークンが登録されていればＯＫです。特にoauth_refresh_tokensについては、リンクを取り直した時に発行された（最新のものより有効期限が１時間短い）トークンが無いことを確認します。oauth_refresh_tokensについては、動作確認の前後で内容を確認すると良いと思います。
# ４．おわりに
　リフレッシュトークンが使えるようになり、goolge Assistantで気が付いたらステータスを拾えなくなっているようなこともなくなりました。それはそれとしてoauth_access_tokensにしろ、oauth_refresh_tokensにしろ、今のところトークンが溜まっていく一方です。古いトークンが残っていても期限は切れているので害はないと思いますが、いらない情報でリソースが消費されていくのもどうかという気がします。

　ところでモックアップとして作成していた疑似スマートデバイスですが、現在は音楽再生のデバイスのような振る舞いもできるようになっています。

　OAuth2関連ＤＢの整理や疑似スマートデバイスの拡張については、また稿を改めたいと思います。
axis環境のoption (tikz備忘録)


Latexの文書内で直接作図を行うことが可能なTikzパッケージについて。
調べながら使用してきたaxis環境のoptionをまとめる。


※2023年5月23日加筆
pgfplotのマニュアル
https://tikz.dev/pgfplots/reference-axis


```latex
\begin{tikzpicture}
\begin{axis}[
            %option
            ]

%　axis環境の中で
%　グラフの描画や
%　作図が可能

\end{axis}
\end{tikzpicture}
```

#### 軸の位置

```latex
\begin{axis}[
            axis y line = center,
            axis x line = center
            ]
```

#### 描画のスケール調整
個人的にはこれが部分的に使えるのが便利。（scope環境を使えば事足りる気もするが...）
`\begin{tikzpicture}`のoption引数として使うとラベルも影響を受けてしまうことがあるが、こちらはラベルの影響が無い。

```latex
\begin{axis}[
            xscale=1.0,
            yscale=1.0,
            axis equal image
            ]
```

`scale`には軸ごとに好きな縮尺を入力。
`axis equal image`引数があると、`axis`環境での縮尺の自動調整をoffにできる。

参考URL:

https://tex.stackexchange.com/questions/61039/how-to-keep-a-11-scale-with-x-and-y-axis


#### 描画範囲の設定

```latex
\begin{axis}[
            xmin=-1.1,
            xmax=1.1,
            ymin=-0.1,
            ymax=1.1
            ]
```


#### 軸の目盛りの設定

```latex
\begin{axis}[
            xtick={-1, -0.5, 0, ,0.5 ,1},
            xticklabels={-1, $-\dfrac{1}{2}$, 0, $\dfrac{1}{2}$, 1},
            ytick={0, 1},
            yticklabels={0, 1}
            ]
```

`xtick` `ytick`には軸の位置を値で入力。
`xticklabel` `yticklabel`には軸の目盛りに表示する文字列や式を入力可能。

#### 軸の目盛りとグラフが重なってしまう場合

調べると大体ラベルの位置を微調整する方法も出てくるが、目盛りの背景を白く塗ることもできる。

```latex
\begin{axis}[
            yticklabel style={fill=white},
            set layers = axis on top,
            ytick={0, 1},
            yticklabels={0, 1}
            ]
```

`yticklabel style`の引数に`{fill=white}`を使用すれば背景を白く塗ることができる。
`set layers`を`axis on top`に指定することで軸目盛りを最前面に表示する。

参考URL:

https://tex.stackexchange.com/questions/641543/white-background-behind-axis-ticks




こういうのってどこを調べると出てくるんでしょう...といつも思うんですがpgfplot周りに全然明るく無いためまずはそこから...

適宜加筆修正していきます。
多言語FizzBuzzチャレンジ7日目:C#

## これまでのまとめ
https://qiita.com/tenteko/private/fc52f7aec63ba5f67854

https://qiita.com/tenteko/private/ca9813f0982370d0c901

https://qiita.com/tenteko/private/bc808ba59f6993019045

https://qiita.com/tenteko/private/74aa4c422196cb5cdeac

https://qiita.com/tenteko/private/ea22bd19360333f9ca85

https://qiita.com/tenteko/private/ec2f7c2f99229a55a7aa

## 本日のお品書き
適当に名前で並べたのでC, C++の次ですが、はい、全く違う言語に突入します。C#です。
書きっぷりがオブジェクト（コンポーネント）指向感あふれてきますが、FizzBuzz程度だと片鱗が見えるぐらいですね。

## FizzBuzz
```c#
using System;

class Hello {
  static void Main() {
    for (int i = 1; i < 101; i++) {
      if (i % 15 == 0) {
        Console.WriteLine("FizzBuzz");
      } else if (i % 3 == 0) {
        Console.WriteLine("Fizz");
      } else if (i % 5 == 0) {
        Console.WriteLine("Buzz");
      } else {
        Console.WriteLine(i);
      }
    }
  }
}
```

コンパイルにあたってはVisual Studioを導入するのが王道のようですが、上記程度のプログラムであればWindowsのどこかに入っている`csc.exe`を使えばよいですね。(C:\Windows\Microsoft.NET以下あたり)

```shell
csc main.cs
```

## 別解: dotnetを使った作成
簡単なコンソールアプリケーションであれば、dotnetを使ってプロジェクトを作成することで、ロジック部分だけに注目してプログラムを書けるようです。

```shell
# wingetなどで.NET Framework 6.0あたりを導入しておく
dotnet new console -o fizzbuzz -f net6.0
cd fizzbuzz
# edit Program.cs
dotnet run
```

```c#:Program.cs
for (int i = 1; i < 101; i++) {
  if (i % 15 == 0) {
    Console.WriteLine("Fizz Buzz");
  } else if (i % 3 == 0) {
    Console.WriteLine("Fizz");
  } else if (i % 5 == 0) {
    Console.WriteLine("Buzz");
  } else {
    Console.WriteLine(i);
  }
}
```
NVIDIA driverの調べ方～インストール

# 失敗編

成功編は後述

## GPUの確認

```
$ lspci | grep -i nvidia
01:00.0 VGA compatible controller: NVIDIA Corporation GP102 [TITAN X] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GP102 HDMI Audio Controller (rev a1)
02:00.0 VGA compatible controller: NVIDIA Corporation GP102 [TITAN X] (rev a1)
02:00.1 Audio device: NVIDIA Corporation GP102 HDMI Audio Controller (rev a1)
```

## 現在のNVIDIA-driverの確認
```
$ dpkg -l grep nvidia
dpkg-query: no packages found matching nvidia
```
何もない場合はこうなる

## 現在のNVIDIA-driverの消去
```
$ sudo apt-get --purge remove nvidia-*
[sudo] password for OO:
```

## 適したドライバの確認

```
$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.1/0000:02:00.0 ==
modalias : pci:v000010DEd00001B00sv000010DEsd0000119Abc03sc00i00
vendor   : NVIDIA Corporation
model    : GP102 [TITAN X]
driver   : nvidia-driver-515-server - distro non-free
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-470 - distro non-free
driver   : nvidia-driver-510 - distro non-free
driver   : nvidia-driver-470-server - distro non-free
driver   : nvidia-driver-510-server - distro non-free
driver   : nvidia-driver-520 - distro non-free
driver   : nvidia-driver-390 - distro non-free
driver   : nvidia-driver-515 - distro non-free recommended
driver   : nvidia-driver-418-server - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin
```

↑の情報を基にして適したドライバを検索します。（推奨ドライバが複数あったため）
[NVIDIA driverの検索](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)


私の場合は以下のようになりました。
![スクリーンショット 2022-11-01 160156.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2896388/4aab0079-213f-bb3a-3fb3-6d43a7ccc445.png)


# インストール

## nvidia-driver-515のインストール

```
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-driver-515
```

## 再起動

```
$ sudo reboot
```

## 確認
```
$ nvidia-smi
```

# 成功編
上記の方法でなぜできないのはわかりませんでした。
くやしい。。。

## アップデート
```
$ sudo apt update
$ sudo apt upgrade
```

## アンインストール
```
$ sudo apt purge nvidia-*
$ sudo apt purge cuda-*
```

## インストール
```
sudo ubuntu-drivers install
```

## 再起動
```
$ sudo reboot
```

## 確認
```
$ nvidia-smi
```
mavenについて

mavenの本を読んで先駆者の方々の頭脳に感嘆の声が漏れすぎたのでまとめを兼ねて投稿です

___________
<h5>Antとは</h5>
Mavenの前身。<br><br>
設定はbuild.xmlに加算的アプローチ（必要になったものを必要になった時点で追加する）で記載する。<br><br>
依存関係の再帰的な解決は行わないので、
「A（自身）→B→C」の場合、B,Cに依存するという設定を記載する必要がある。

___________
<h5>Mavenとは</h5>
設定はpom.xmlに差分的アプローチで記載。<br><br>
依存ソフトウェアをインターネット経由で取得し、かつ依存関係の再帰的な解決を行う。「A（自身）→B→C」の場合、Bに依存するという設定を記載すればよい。<br><br>
ソフトウェア開発のビルドプロセスが「コンパイル、テスト、アーカイブ作成」と大体手順が決まっていることから、Mavenでは標準的なビルド手順を定め、それに従ったビルドプロセスを豊富なプラグインによって自動的に実行できるようにしている。そのためAntと異なり、この標準的な手順との差分だけを記述すればよい。

___________
<h5>参考</h5>
https://amzn.asia/d/drV8mvs

古い本ですがMavenの基本的な考え方が学べました
eclipseとmavenとspring ざっくり説明

<h5>java bronze合格して開発者を目指し始めた初心者向けの説明</h5>
今までプリミティブ型の最大桁数くらいしか習ってなかったのにいきなりいろんな用語でてきてわかんないよ！っていう人向け

_______
<h5>ビルド</h5>
javaアプリケーションを作成するには、「ビルド」という手順を踏まなければいけません。

「ビルド」という手順を容易に済ませてくれるのが「ビルドツール」です。
_______
<h5>maven</h5>
mavenはビルドツールです。
mavenの場合、ビルドの設定を記載するファイルはpom.xmlになります。

_______
<h5>spring</h5>
springはjavaのソースファイルを書くのに役立つフレームワークです。
(cssのフレームワーク「Bootstrap」のように、おまじない入れるだけで簡単に実装できたりします。)
利用するにはビルドツールの設定ファイルに記載が必要です。

_______
<h5>eclipse</h5>
eclipseにstsをいれると、プロジェクトの新規作成からspringプロジェクトが選べるようになり、ウィザードで選択していくだけで自動でmavenの設定ファイルに書き込んでくれるようになります。

_______
<h5>まとめ</h5>
mavenはビルドツール。<br>
springはソースファイル書く際に役立つフレームワーク。<br>
eclipseは、ビルドツールの設定やソースファイル書くのをサポートしてくれたり実行環境用意してくれてたりする開発環境
TFunction | TFunctionRef | TUniqueFunction is 何？

## はじめに
本記事は UE にある TFunction系のクラスについての情報や使用するにあたって意識すべき点を簡単にまとめた物になります。

対象読者はプログラマーを想定しており、関数オブジェクトなどいくつかの用語説明は省くことをご了承頂いた上で読み進めてもらえると幸いです。

なにか間違ってたらコメントください


## TFunction 
https://docs.unrealengine.com/5.0/en-US/API/Runtime/Core/GenericPlatform/TFunction/

std::function のUEC++バージョン
関数オブジェクトなど呼び出し可能な物を保持できます。

コールバック等の用途でこれが関数の引数として使用されることもありますが、この時にコピーコストが気になる場合は後述するTFunctionRef に出来ないかも検討してみてください。

記述例：
```cpp
// 変数
TFunction<bool(int32)> ReturnFalse = [](int32 a)
{
	return false;
};

// 引数
void Func(TFunction<bool(void)> Predicate)
{
	if (Predicate())
	{
		std::cout << "True";
	}

	std::cout << "False";
}
```

## TFunctionRef
https://docs.unrealengine.com/4.27/en-US/API/Runtime/Core/GenericPlatform/TFunctionRef/

関数オブジェクトなど呼び出し可能な物の参照を保持します。


TFunctionとは違い参照を保持するため、TFunctionと比べてコピーコストを気にしなくてもいいことが利点ですが、下記のような場合だとラムダのスコープが抜けて破棄されるため、不正アクセスとなります。
```cpp
TFunctionRef<bool(void)> f = []{ return false; };
f(); // この時には↑は破棄されているため、不正アクセスとなる

/*
	@note TFunctionRefクラスコメント一部抜粋
	A class which represents a reference to something callable.
    The important part here is reference - if you bind it to a lambda and the lambda
    goes out of scope, you will be left with an invalid reference.

    google翻訳：
    呼び出し可能なものへの参照を表すクラス。
    ここで重要な部分は参照です。これをラムダにバインドし、ラムダがスコープ外になると、
    無効な参照が残ります。
 */
```

ラムダ式を変数へと格納したい場合は下記のように、autoやTFunctionを使用してください。

```cpp
auto Func = []{ return false; };
TFunction<bool(void)> Func2 = []{ return false; };
```


## TUniqueFunction
https://docs.unrealengine.com/4.27/en-US/API/Runtime/Core/Templates/TUniqueFunction/

基本的にはTFunctionと同等ですが、所有権が唯一になるように振舞います。
そのため、基本的にはコピーが出来ず、MoveTempで所有権を移譲します。
```cpp
TUniqueFunction<bool(void)> UniqueFunc = []{ return false; };
TFunction<bool(void)> a = UniqueFunc; // NG
TUniqueFunction<bool(void)> b = UniqueFunc; // NG
TUniqueFunction<bool(void)> c = MoveTemp(UniqueFunc); // OK
```
Salesforce アイテム（Astro のぬいぐるみなど）を購入する方法

![GetImage.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689091/b636b5d8-deba-2717-f3fc-ca5b2fb46f3c.jpeg)

## Salesforce の Astro の「ぬいぐるみ」を入手する方法
日本から Salesforce のアイテムを手に入れるにはどうしたら良いでしょうか。
答えは簡単です。<font color="red">通販サイト</font>が存在します。
※注意点は、世界の地域ごとに通販サイトが異なるので APAC (アジア太平洋) 地域のサイトで購入するように気をつけてください。

以下、私が日本から Astro のぬいぐるみをゲットした方法です。ちなみに１体 35 ドルです。

Salesforce Store(APAC)の<a href="https://apac.salesforcestore.com/">通販サイト</a>にアクセスします。

https://apac.salesforcestore.com/

![スクリーンショット 2022-11-03 15.14.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689091/743a0575-efbb-d3c4-07bf-f0be3e4c468a.png)

右上に表示されている人のマークのアイコンをクリックして、アカウントを作成します。Email は Gmail 等なんでもいいようです。

![スクリーンショット 2022-11-03 15.15.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689091/d1bd8606-5cb2-9f17-a884-86cb1dac7fec.png)

アカウント登録ができたらお買い物ができます。
カテゴリごとに分かれてるので、とても見やすいです。

● Sustainable - 環境にやさしい Salesforce グッズ
● Apparel - Tシャツやトレーナーなどのアパレルグッズ
● Electronics - USBメモリなどの電化製品
● Office - ノートやボールペンなどの事務用品
● Bags - トートバックやショルダーバッグなど多彩なアイテム
● Leisure - 屋外で使うレジャー用品などのアイテム
● All - すべてのアイテムを確認できます。Astro のぬいぐるみもあります。

アイテムを選択して「ADD TO BAG」ボタンで追加します。
クレカでお支払いして完了。

さて、日本にちゃんと届くかというところですが、なんと１週間ぐらいで国際郵便で届きました！
どこから発送されているか確認したところ、オーストラリアから送られてきたようです。

![IMG_0047 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689091/ad87469c-01a4-3db9-7371-a613a5ae71f1.jpeg)

２体購入したので 70 ドルですが、それ以外に　Tシャツやジャンパーとかも買いました。
送料が、80 ドルぐらいしたので少し高いですが、欲しかった Astro のぬいぐるみをやっとゲットできました。
疑似ヒアドキュメントを使ったローカルのmdファイルをブラウザで表示する

[HeredocForMarkdown](https://github.com/etsuhisa/HeredocForMarkdown)というスクリプトを作成してみました。
Javascriptの関数のコメントによる疑似ヒアドキュメントを使って、ローカルのmdファイルをブラウザでHTMLに変換して表示する、というものです。
以下がポイントとなります。
* テキストを独立した複数のファイルで保持する。
* ブラウザでローカルのファイルを扱う。
* ファイル間を移動できる。

## mdファイルの形式
読み込めるmdファイルは純粋なMarkdownではなくJavascriptなので、以下のように本文以外に前後に疑似ヒアドキュメントにするための仕掛けが必要です。
```javascript
MD.set(()=>{/* // magic line

# This is sample1
Click the link [sample2](sample2)
to view another md content.

*/}); // magic line
```

本文部分だけ抜き出し、Markdownのパーサを通すことで以下のようにHTMLになって表示できます。
```HTML
<h1>This is sample1</h1>
<p>Click the link <a href="sample2">sample2</a>
to view another md content.</p>
```

## 処理の流れ
以下のようになります。
1. scriptタグでmdファイルを動的に読み込み。
2. mdファイル内で関数のコメントで文字列を定義。
3. 文字列をMarkdownのパーサmarkd.parseでHTMLに変換。
4. mdファイル間のリンクはonclickでmdファイルの動的読み込みにする。

## 参考：Javascriptの疑似ヒアドキュメント
以下の方法があります。
* `function(){/*～*/}`と関数内にコメントを書いてtoStringで関数定義自体を文字列化して取得する。
  本文以外に関数定義の部分を書かないとならない。
* `<script type='text/plain' id='xxx'>～</script>`の間に書いて`document.getElementById('xxx').textContent`で内容を取得する。
  HTML内に書く必要がある。外部ファイル指定の場合はtextContentが取得できない。
* バッククォートで挟んだテンプレートリテラルを使う。
  バッククォートを多用するMarkdownと相性が悪い。

外部ファイルでMarkdown形式のファイルを扱いたいので関数のコメントでの疑似ヒアドキュメント一択となりました。

## 最後に
疑似ヒアドキュメントの使い方や使い道の実験であり、このスクリプト自体はあまり意味はないです。
純粋なmdファイルを扱えれば意味があったかもしれません。
[salesforce]多対多リレーションの貼り方について、ジャンクションオブジェクト


Salesforceのリレーションは2つの種類があります。
そもそも、リレーションというのは他のオブジェクトへの参照のことですね。

どんな種類があるかというと、参照関係と主従関係です。
これにどんな違いがあるか？というと代表的なところで以下になります。

- 主従関係
    - とあるレコードに対し、主となるレコードを設定します
    - レコードの所有者は、主となるオブジェクトの所有者と同じになります。これにより共有ルールに影響します
    - 主となるオブジェクトでは、積み上げ集計を使って複数の従レコードの集計（件数、合計、最大、最小など）が簡単に集計できます
    - 主となるレコードを更新しても従レコードには影響しませんが、従レコードを更新すると主となるレコードの積み上げ集計項目は更新されます
    - 主となるレコードを削除すると従レコードは削除されます
- 参照関係
    - とあるレコードから、1つのレコードを参照します
    - レコードの所有者は参照先に関係なく設定できます
    - 参照先レコードで集計しようとするとフローやApexを作成する必要があります
    - 参照先レコードを削除すると、参照をクリアする　もしくは参照先レコードの削除を禁止するのどちらかを選択して設定できます

ジョンクションオブジェクトとは？というのは公式リファレンスもあるし他の方が解説しているので省略します。
https://help.salesforce.com/s/articleView?id=sf.relationships_manytomany.htm&type=5

で、ジャンクションオブジェクトでは従オブジェクトを1つ作ってそこに主オブジェクトを2つ設定することでできますよ、というふうに説明がされているんですよね。

ただし、厄介なのが主従関係の個数制限です。実はSalesforceでは1つのオブジェクトは主、従合わせて2つまでしか主従関係が設定できないのです。なのでジャンクションを設定したいけどできない、、という状況があると思います。

が、ジャンクションオブジェクトは上で書いた違いを許容できれば参照関係でもできます！ご安心ください。
プログラミングの独学で重要な本選びについて

![a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953959/e06a56a5-70fa-d6e6-7b0d-96d06d339f2b.jpeg)


はじめに
最近、子供大人問わずプログラミングを学んでみようという方が増えています。小学校でプログラミング授業の必修化が始まったり、飲食、サービス業、営業からプログラミングを勉強し、エンジニアに転職する人が以前より増えたりしています。ですが、いざ独学を始めたら難しくて挫折してしまったり、本を買おうとしたけれど種類がたくさんありすぎてどれを選べば良いのか分からないということがあるのではないでしょうか。そんな方のためにこの記事では、挫折しないための独学方法や本選びのコツについて解説していきます。

プログラミングの独学について
よく、プログラミングは独学だと、習得するまでに時間がかかるし、挫折率も高いという話を耳にします。そのような話を聞くとプログラミングの独学は、難しいのかなと思われがちですがが、そんなことはありません。これからプログラミングを独学で勉強しようという場合、どのプログラミング言語を選ぶかや独学方法、本選びが大切になります。

初心者向けプログラミング言語
プログラミング言語には、初心者も習得しやすい難易度の低いものもあれば、初心者向けではない難易度の高いものもあります。初心者が難易度の高いプログラミング言語を選んでしまうと挫折の原因になってしまいます。初心者向けのプログラミング言語には、PHPやJavaScriptがあります。どちらも構文や文法などがわかりやすく、開発環境を導入するのが割と簡単なので初心者にオススメの言語です。

学習順序
プログラミングを独学で勉強する場合、どのような勉強方法をとるかも大事です。少し前までは、本で学習するのが一般的でしたが、最近では動画やオンライン学習サイトなどもあります。本では、開発環境の導入から始まり、実際にアプリケーションを作成したりするものが多く、オンライン学習サイトでは、コードをサイト内で実行できるようになっており、構文や文法をすぐに勉強できます。 したがって、プログラミング初心者がプログラミングを独学で勉強する場合、この2つをうまく取り入れると良いでしょう。プログラミングを勉強する手順としては、「オンラインサイトで基礎構文や文法を勉強」→「本で開発環境構築から勉強」→「実際にアプリなどのシステムを構築」という風に勉強を進めていくと挫折も少なくなるでしょう。

初心者向け本選びのコツ
プログラミングの本には、初心者から中級者向け、上級者向けの本があります。

タイトルに超入門と記載されている
初心向けの本には、「超入門」や「プログラミング初心者に優しい」などの文言がタイトルや表紙に記載されています。よく表紙に入門と書かれているものがありますが、そう書かれていても初心者向けではない場合があります。その言語の入門書であり、プログラミング初心者の入門書ではないことがあり、他言語経験者向けに書かれているものもあるので上級者向けのものもあります。ですが、超入門と記載されているものなどは、プログラミング初心者の入門書です。本選びを間違えると内容が難しすぎて理解できず、挫折の原因になってしまいます。以下に、プログラミング初心者向けの本の特徴をまとめました。

表紙やタイトルに「超入門」と記載されている
前述しましたが、プログラミング初心者向けの本には、「超入門」や「初心者でもわかる」などと表紙やタイトルに記載されているのものを選ぶと良いでしょう。

イラストや図などが多い
説明の文章に対して、わかりやすいようにイメージ図などが書かれていたり、キャラクターが登場するような本は初心者向けです。少し、中身を見てみて説明が理解しやすいか、処理のイメージなどの図がわかりやすいかをチェックしましょう。講師にも合う合わないがあるように本にも、その人に合う、合わないはあります。プログラミングなどの技術関係の本は1冊3000円前後と決して安くはないので、損をしないためにも買う前にしっかり中身を確認するべきです。<a href="https://office-fleq.com/">ペットくすり</a>

カラー印刷
プログラミングの本は、初心者向けのものはカラー印刷されているものが多いですが、中級者向けや上級者向けの本は、白黒印刷のものが多いです。特に上級者向けのものは、図を使っての解説などがほとんどなく、白黒印刷でほぼ文字だけです。逆に初心者向けの本は、図やイラストが多いのでカラー印刷のものが多いです。1章ごとに要点をまとめ、箇条書きで書かれていたり、練習問題が記載されていたりします。

まとめ
いかがでしたでしょうか。初心者が独学でプログラミングを勉強するときの挫折しないための学習順序や本の選び方などをお話しました。プログラミングは独学で学習する場合、学習する言語や学習方法、本選びで挫折率や習得率が変わってきます。言語選びは、初心者でも習得しやすいもので、自分が作りたものを実現できる言語を選び、学習方法は今は初心者に優しいツールが以前と違い、たくさんあるので上手く活用すると良いでしょう。そして、最初から難しいことをやろうとせず、簡単なものからひとつひとつ積み上げていくと良いでしょう。それがプログラミング学習を挫折しないコツです。
minicondaのインストールから使い方まで

macでminicondaの環境作ったので備忘がてら残しておきます。
anacondaは商用利用有料と聞いたのでminicondaにしました。
## インストール
以下のURLからダウンロードしてインストール
https://docs.conda.io/en/latest/miniconda.html
## 使い方
- 仮想環境確認
```
conda env list
```
- 仮想環境作成
```
conda create -n pythonenv python=3.10
```
- 仮想環境有効化
```
conda activate pythonenv
```
- 仮想環境無効化
```
conda deactivate 
```
- 仮想環境削除
```
conda remove -n pythonenv --all
```
- 仮想環境に入っているパッケージを確認
```
conda list
```
- パッケージインストール
```
conda install django
```
- パッケージアンインストール
```
conda remove django
```
TF &Torch version for GPU CUDA

* 互換性 (22.10)
  - MLやRL 開発の　Frameworkとして、Tensorflow 2.X, Torchをよく使用するが、GPU版を実装するときにはversion 互換性を注意すべきである。うまく動作しない場合も存在する

* PyTorch
    - https://pytorch.org/get-started/previous-versions/
    - 一覧表
    
| version | cuda | remarks |
|:-------:|:----:|:-------:|
| 1.13    | 11.7, 11.6       |   |
| 1.12    | 11.6, 11.3, 10.2 |   |
| 1.11    | 11.3, 10.2       |   |

* Tensorflow 2.X
    - システム要件(https://www.tensorflow.org/install/pip?hl=ja)
        - Python 3.6～3.9
        - Python 3.9 サポートには、TensorFlow 2.5 以降が必要(https://github.com/tensorflow/tensorflow/blob/r2.5/tensorflow/tools/pip_package/setup.py\)
        - Python 3.8 サポートには、TensorFlow 2.2 以降が必要
        - pip 19.0 以降
    - ソフトウェア要件(https://www.tensorflow.org/install/gpu?hl=ja)
        - NVIDIA® GPU ドライバ: CUDA® 11.2 には 450.80.02 以降が必要
        - CUDA® ツールキット:TensorFlow は CUDA® 11.2 に対応
        （TensorFlow は 2.5.0 以降）
        - cuDNN SDK 8.1.0 cuDNN バージョン
        - （省略可）TensorRT 6.0 は一部のモデル上での推論のレイテンシとスループットを改善
 
| version | numpy |remarks |
|:-------:|:----:|:----:|
| 2.8 ~  | >= 1.20| |   
| 2.7   | >= 1.14.5| keras 2.6 needs 1.19.2, h5py needs 1.14.5 for py37|  
| 2.4,2.5,2.6 | ~=1.19.2 | |
| 2.2, 2.3 | >= 1.16.0, < 1.19.0 | |

:::note info
最新版TF2.11: tf2.10, cuda 11.8 cudnn 8.6(22.10) numpy >= 1.20
TensorFlow 2.5 の GPU 版での，cuDNN のバージョンは 8.2
TensorFlow 2.4 の GPU 版での，cuDNN のバージョンは 8.0.5
TensorFlow 2.3, 2.2, 2.1 の GPU 版での，cuDNN のバージョンは 7.6
そして，TensorFlow 1.13 以上 TensorFlow 2.0 までの GPU 版での，cuDNN のバージョンは7.4 が良い
:::
※about detail: http://tecsingularity.com/cuda/version-2/
if文を使わなくても良くなる？ルックアップテーブルとは？

## 前置き
これから説明していくコードの書き方を知ってはいましたが、名前がついていることを知りませんでした。
あらためて知ったことを記録として残しておきたい為、参考になれば嬉しいです。

## ルックアップテーブルの使い方

・ルックアップテーブルとは
>計算機科学におけるルックアップテーブル（英: Lookup table）とは、複雑な計算処理を単純な配列の参照処理で置き換えて効率化を図るために作られた、配列や連想配列などのデータ構造のことをいう。
Wikipediaより引用

言葉だけだと分かりにくいと思うので、例を見ながらどんなときにどのように書くことを言うのか見ていきましょう。
下記はお金「円」の値によって取得する「果物」が変わる処理を書いています。

```php
    if ($yen === '100円') {
       $fruit = 'オレンジ';
    } else if ($yen === '110円') {
       $fruit = 'りんご';
    } else if ($yen === '120円') {
       $fruit = 'ぶどう';
    } else if ($yen === '130円') {
       $fruit = 'スイカ';
    }
```
ifが数個続いて使われています。
この程度のelse ifの量であればまだ読みやすいですが、これが7、8つと続くと気になりますね。
```php
    switch ($yen) {
      case '100円':
         $fruit = 'オレンジ';
         break;
      case '110円':
         $fruit = 'りんご';
         break;
      case '120円':
         $fruit = 'ぶどう';
         break;
      case '130円':
         $fruit = 'スイカ';
         break;
}
```
else ifをなくし、switch文を使用しました。
先ほどよりは見やすくなりましたが、文字量が多いところが気になりますね。

```php
    $fruit = [
      '100円' => 'オレンジ',
      '110円' => 'りんご',
      '120円' => 'ぶどう',
      '130円' => 'スイカ',
    ][$yen];
```
上記のif文とswitch文より遥かに行数、文字数を短縮できました。
＄fruitの期待値としては、上記の＄fruitと同じ値になるはずです。
配列に前もって欲しい値を用意しておき、＄yenの中身によって取り出す値を変えることができます。
これをルックアップテーブルと言います。

## まとめ
時と場合によって「使用できる・できない」はありますが、頭の片隅に入れておくだけで行数や文字数を大幅に減らすことができます。名前を知らなかった、そもそもこの書き方を知らなかったという方の参考になればと思います。

## 参考文献
ルックアップテーブル - Wikipedia
https://ja.wikipedia.org/wiki/%E3%83%AB%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB
Laravelでよりクリーンなコードを書く
https://www.gigas-jp.com/appnews/archives/11954
UUCP とは

## 勉強前イメージ

なんか昔のネットワーク的なイメージ

## 調査

### UUCP とは

Unix to Unix CoPy の略でUNIXのマシンでファイルを転送する時、ファイルをコピーする時のプログラム・コマンドになります。
一定期間ごとに電話回線上でバケツリレー式にファイルを交換することで通信を行います。
1995年頃まではこの方法でメールやニュースが配送されていました。

UUCPのコマンドとしては以下のような感じで使われていました。

```
uucp [送信をするファイル名] [転送先のディレクトリ名]
```

今でいうとscpコマンドとよく似ている感じです。

## 勉強後イメージ

なんか見たことあったけどコマンドなのかー
しかも調べてたらrcpと似てるって書いてあってrcpとは...ってなったけど
scpの暗号化されてないバージョンだった
色々知らないことがある

## 参考

- [実践で学ぶ、一歩進んだサーバ構築・運用術](https://www.gcd.org/sengoku/docs/NikkeiLinux00-07/dialup.ja.html)
- [【rcp】Linuxでリモート・ローカル間でファイルを転送するコマンド](https://uxmilk.jp/52220)
【備忘録】【Rails】new + save と create の違い

どちらもレコードをつくるときのメソッドですが、何が違うのだろうと疑問に思ったので調べました。

# new + save を使うべき場合

### ①コントローラー内で、条件分岐させたいとき

例えばArticleモデルでバリデーションの設定をしていて、
保存時にバリデーションを適用させたいときにはif文等で条件分岐の記述をしますが、
その場合は以下のようにnew + save メソッドを使います。
理由：createメソッドでは、たとえ保存に失敗してもオブジェクトを返すためif文がtrueとなり成功時の処理を行ってしまうからです。

```ruby:
def create
    @article = Article.new(article_params)
    if @article.save
      redirect_to("該当パス")
    else
      flash.now[:alert] = '文字を入力してください。'
      render :index
    end
end
```

### ②view側で使いたいとき

例えば Book モデルを操作する BooksController があったとする。
new アクションを

```ruby:
def new
  @book = Book.new
end
```

などと書いておいて、この @book を入力フォームで使いたい、そんな場合にもnew + save を使う。

# create を使うべき場合

インスタンス生成と保存を同時に行いたいとき。



# 参考にさせていただいた記事
[【Rails】createメソッドとnew + saveメソッドの違い](https://qiita.com/yamato1491038/items/d4045812a65d9eb98348)

[【Rails】newとcreateの違い
](https://qiita.com/hirouch/items/054bb8543aade6afbebb)
[newとcreateの違い
](https://qiita.com/Kaisyou/items/7d609787d4ae8c2425a0)
[new,save,createアクションそれぞれの使い分け
](https://teratail.com/questions/20276)
多言語FizzBuzzチャレンジ6日目:C++

## これまでのまとめ
https://qiita.com/tenteko/private/fc52f7aec63ba5f67854

https://qiita.com/tenteko/private/ca9813f0982370d0c901

https://qiita.com/tenteko/private/bc808ba59f6993019045

https://qiita.com/tenteko/private/74aa4c422196cb5cdeac

https://qiita.com/tenteko/private/ea22bd19360333f9ca85

## 本日のお品書き
泣く子も黙る(再)C++。FizzBuzzするだけならCと大きくは違わないですね…。

## FizzBuzz

```cpp
#include <iostream>
// iostreamの中で定義している`std`名前空間を呼び出している
// std::cout, std::endl などを短縮して呼び出すため
using namespace std;

int main() {
  for (int i = 0; i < 101; i++) {
    if (i % 15 == 0) {
      cout << "FizzBuzz" << endl;
    } else if (i % 3 == 0) {
      cout << "Fizz" << endl;
    } else if (i % 5 == 0) {
      cout << "Buzz" << endl;
    } else {
      cout << i << endl;
    }
  }
  return 0;
}
```

## 【おまけ】コンパイルまで
```shell
g++ main.cpp
./a.out
```
ActiveStrageとは

### Activestrageとは

Webアプリを作成していると、必ずと言っていいほど必要な画像の取り扱い。
Activestrageとは単純に言ってしまえば画像を取り扱うためのgemです。
ほぼ毎回使うと言っても過言ではないので、忘れないようにまとめてみました。

#### Activestrageを導入しよう

画像を投稿できるようにするには、ActiveStorageが必要です。
なぜなら画像はカラムとして保存することができないため、別の手段を使って保存する必要があり、その役割を担ってくれるのがこのActiveStorageなのです。
では、まずはインストールから始めましょう。

```
$ rails active_storage:install
```
インストールが終わるとdb/migrate内にActiveStorageのマイグレーションファイルが追加されます。
マイグレーションファイルということは...
そう、毎回おなじみのこちらのコマンドが必要です。
```
$ rails db:migrate
```
:::note info
ActiveStorageは３つのテーブルを作成します。
①active_storage_blobs
②active_storage_variant_records
③active_storage_attachments


①のblobsは、識別keyやファイル名、ファイルの種類、サイズなどを管理します。
②のvariantはサイズの変更などの加工情報を記録してくれます
③attachmentsはblobモデルとアプリ内のモデルを関連付ける中間テーブルの役割です。
アプリ内の他のモデルと紐付けられるように、関連するモデルのFKカラム名（外部キー）をFK値として持っているのはこの子です。
:::

#### モデルへの記述

ActiveStorageを使うには、どのモデルに画像を使うのか記述する必要があります。
listだとかbookだとかpostだとか各々のモデルに合わせて記入してください。
```ruby:app/models/post.rb
class Post < ApplicationRecord
  has_one_attached :image
end
```
※もし複数のファイルを扱いたい場合はoneをmanyに変更してください。
```ruby:app/models/post.rb
class Post < ApplicationRecord
  has_many_attached :image
end
```
モデルに記載することで、このモデルにimageカラムが追加されたのと同じように扱うことができます。
ActiveStorageを使うとわざわざpostモデルにカラムを追加しなくてもいいので楽ですね！
あとはストロングパラメータ内にimageを追加すれば下準備は完了です。
```ruby:app/controller/posts_controller.rb
:
  private
  def post_params
    params.require(:post).permit(:○○, :○○, :image) #image追加
  end
```

以上がActivestrageの基本の説明になります。
#### 投稿フォーム作成
あとは画像投稿するためのviewを整えていきましょう。
```ruby:app/views/posts/new.html.erb
<p>画像</p>
<%= f.file_field :image, accept: "image/*" %>
<%= f.submit %>
```
`"file_field"`はファイル投稿のためのフィールドです。
ファイルであれば画像以外（動画や音声と）も投稿できてしまうので、accept: "image/*"を使用し画像ファイルのみ投稿できるよう設定しています。
投稿後の画像を表示させるコードを記述すれば完了です。
```ruby:app/views/posts/index.html.erb
<p>画像</p>
<% @posts.each do |post| %>
 :
 :
 <%= image_tag post.image, size: "100x100" %>
<% end %>
```
この`image_tag`にpostに紐づいているimageを渡すことで画像が表示できます。
以上になります。
下記記事にもっと詳しく書いてありますのでよければ参照ください。

>https://pikawaka.com/rails/active_storage

複数のファイルを取り扱ってみたい！などの要望がある方は下記記事参照ください☺︎
>https://qiita.com/hmmrjn/items/7cc5e5348755c517458a