OmniAICreator/Qiita-1.07M huggingface dataset:
嫌いなものはメール送信です。Gmailさん、受信してよ

## 概要
ポエム。Web系に関わってから絶対関わりたくないと思ったものがメール関連の仕事。しかし、間接的に関わることに。しかもGmailに届かない。メールのことなんてほとんど知らんのに。


## メール関連に関わりたくなくなった出来事
とある一人エンジニアの社長がいた。関係性はうちの社長との仕事関係。Webサービス作成を頼んでいて、私は門外だったけど、データの収集役として作業した。最終的には私のデータを使ってWebサービスを展開していく予定だったが、うちの社長との折り合いが付かなくなって消えてしまった。

話を戻して、とあるときに事件が起こった。うちの小汚い部屋の隅に何やらそのエンジニア社長のサーバーを置いていたらしくてメールサーバーが不具合を起こしてメールの送受信が止まっていたらしい。うちの会社とは無関係。その社長の顧客数は2,300くらいだったと思う。クレームが凄かったらしい。その様子を見てメール関連の仕事は絶対関わりたくないと思った。

# たくさんのメール送信システムの実装
マッチングメール、ステップメール、リンクをクリックしたらメールを運営に送信する機能等を実装した話。

## マッチングメール機能を作ることに
エンジニア社長がいなくなったから代わりに私がWebサービスを作ることになった。実験で似たようなコンセプトを２、３サイト作ってみて事なきを得た。

次の指令がマッチングメールを作る事だった。当時は条件にあった登録してあるデータをメールで送信してくれとのこと。簡易的な会員機能をつけて、条件にマッチしたらそのデータを会員に送るとういう奴だ。

所謂、マッチングメール。当然会員にのみメールを送ることになるのだが「メールアドレスとパスワードを両方入力するの面倒じゃね？パスワード忘れちゃうでしょう。」という理由でパスワードを廃止しろという指令がきた。流石にそれはヤベーのでデメリットを説明して納得してもらった。

マッチングメール機能の実装、これ自体は簡単に出来た。条件に当てはまったものをメール送信するだけなのだから。問題は送った後だ。同じデータを何回も送るのか、一回だけなのか。色々あったけど何度も送る仕様になった。いまだったら良くて[SPAM]と件名につくか迷惑メール行きだろう。悪ければメールすら届かない。

## ときは流れて、またマッチングメール機能を作ることに+ステップメール機能も作ることに。
今度は全然違うところでまたマッチングメールを作っている。前回と違って一回送信したものは再度送らない仕様。さらに、メールにはデータの詳細ページに飛ぶためのリンクがあるのだが、それをクリックしたとき、運営者に「クリックされたよ！」とメールを送信するための機能も実装した。
ステップメールは会員登録した後に3日後にAの内容、7日後にはBの内容と送るものである。

# Gmailにメールが届かなくなった
ある日突然Gmailにメール受信されなくなった。迷惑メールにすら入っていない。
そのトラブルの話を聞いていくつかの予想はついた。SMTP認証でメールの送信をしてないからだろうと。

そのことを社長に説明したけどイマイチ理解してくれず遠回りしたのだがそれは関係ない話なので省く。同サーバーでこっそり実験をしてSMTP認証なら無事届くことを確認した。CakePHP2(レガシーなフレームワーク)を使っていたのだがちゃんとSMTP認証ができるような設定があって軽微な修正で済んだ。良かった良かった。

## ホスティングサーバーがサーバー移転すると言い出した
このサービスは共用サーバーで動いていた。それくらいの規模のサービスだったと思ってくれて良い。ホスティング会社の中の人は何もしなくても大丈夫。ただIPアドレスは変わりますよとのこと。内心は信用していなかった。
強制移転なので拒否はできない。私的にサーバーを借りていて、同じようなことを言われて移転したのだがcrontabの中身がなくなってたことがあったからだ。
予想通りトラブルは起きた。お問合せフォームからのメール送信がうまくいかないのだ。
ここらの記憶は曖昧なのだが今回は送信自体がうまく出来てなかった。ゾーンの設定をいじって何とか送信できるようにした気がする。

## サービスも安定してたところに別のサービスで使っているサーバーがまた移転
また移転するぞ！と行ってきたのだが今回は前回とは勝手が違う。結構大きいサービスなので問題を起こすわけにはいかない。任せてたいたら99%トラブルだろうなと思ったので専用サーバー(管理は向こう)を借りてそっちにサービスを移行することにした。

理由がもう一つがあってメールの送信制限がギリギリだったのだ。Mailgunとかメール送信メインのサービス使いませんか？と提案したのだが専用サーバーなら無制限にメール送信が使えるとのことだったので聞き入れてもらえなかった。(blastengineは知らなかった)書いてはいないがこのホスティング会社で3,4回サーバー移転の機会があったがトラブルがなかったことは一度も無い。

#### 余談
無制限は100%無制限ではない。帯域無制限、容量無制限、このように謳っているところは要注意。容量無制限はアマゾンですら撤退したサービスがあるのだ。帯域無制限も使いすぎると文句を言われる。しっかりと「負荷をかけすぎたらダメだよ」のようなことが利用規約に書いてあるのだ。とあるホスティング事業を手伝っていたこともあって、そのときの繋がりで(別な会社)無制限とは謳っているけど一定の帯域制限が決まっている表を見せてもらったこともある。

## 専用サーバーでトラブルは起きたか否か？
結果から言うと起きた。メール送信できていたのに急に出来なくなったのだ。問い合わせをしたが何も変えてないと言う。ここで初めて書くが利用しているホスティング会社のSMTPのポート番号がサーバーによって違っているのだ。465だったり587だったり。当然、問い合わせのときにポートのことも聞いた。

PHPのエラーを見るとopenssl系のエラーが出ていたのを覚えている。そのせいもあって最終的にはロールバックをするしかないかと思ったが一晩寝て、メールアプリで送信してみたら普通に送信できた。
おかしくね？と思ってポートを変えたら送信できるようになった。脱力。

# Gmailのガイドライン変更
やっと、落ち着いたと思ったらなにやらGmailのガイドライン変更。
そのことについて、アドベントカレンダーに1日目に色々と書いてあった。


>[Gmail メール送信者のガイドライン変更に備える話](https://qiita.com/hmatsu47/items/04e78fcb331239690911)

SPF・DKIM・DMARC これらの設定が必要なようだ。
SPFは設定してある。DKIMもしてある。
DMARC・・・以前調べたことがあったけど忘れた。何だったかな。メールと関わりたく無いから避けてきたけど、どうにも避けられないようだ。

元気な時に[Gmailのガイドライン](https://support.google.com/mail/answer/81126)を読むとしよう。

記事を書いてくれた人、ありがとう。
Ruby芸160チャレンジ(#23)プロセスを扱う

## この記事は何
[shellgei160を通じて言語習得 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/learning-via-shellgei160)に参加しています。

書籍「シェル芸ワンライナー160本ノック」の例題をRubyで解いてみて、Rubyの学習に役立てようとするものです。

例題はこちらのリポジトリで公開されているものに限ります。
https://github.com/shellgei/shellgei160

## 実行環境など
- Docker image: ruby:3.0.2
- 上記リポジトリをクローンした上で、リポジトリのルートディレクトリ直下に`answer-ruby`ディレクトリを作り、その中に解答となるファイルを作成していきます。

## 今回のテーマ
https://github.com/shellgei/shellgei160/blob/master/answer/23.md

```bash
$ kill -s SIGCONT 5249
```

一時停止してあるプロセス(この例だとpid=5249)を再開する処理ですね。

## 解
さて、まず一時停止中のプロセスを用意しないことには始まりません。
```bash
sleep 1000 &

# [1] 5583
```

このプロセスを一時停止しておきます。
```bash
kill -STOP 5583

ps aux | grep sleep
# root 5583 (略) T (略) sleep 1000
```

よし、ちゃんと止まっていますね。ではこれをRubyプログラムから再開します。

```ruby
pid = 5583
Process.kill(:CONT, pid)
```

## 所感
- `kill`コマンドと使用感が近いので分かりやすいですね。
AZ-305 合格まで (2023.12)

受験記録。「資格よりどれだけ知識を活かせるか」派なのですが客観的にコスパ良く「この人このくらいは勉強してんのな」を見せられる手段だなと思って転職以来それなりに楽しく挑んでいる。

[AZ-900 と MS-900 合格まで (2023.01) - Qiita](https://qiita.com/e99h2121/items/4ee69f047e555990065d)
[AZ-104 合格まで (2023.06) #AZ-104 - Qiita](https://qiita.com/e99h2121/items/de97a5e78b083739b5a1)

2023.12.15 AZ-305 を受けて合格したメモです。

## 感想
- 700 点ギリ、ぽっきりでの合格。うれしい。
- 難易度的に、AZ 104 とそんなに変わらない気もしなくもないが、相変わらず文章題を読む集中力が試される。
- ケース スタディとか、画面を見て答える問題とか、タブを行き来する UI が答えづらい。これは AZ 104 も同じ。
- 蛇足
    - ピアソンの自宅受験、ジャケットを着るなと言われたので褞袍を脱ぐ…。空調必要。
    - 選挙の広報車とかがうっさいなと思ったが、特に進行は影響なかった。
- やはり資格は業務で触るかどうかが一番でかい。
    - 資格取得を目指すなら触って遊んで覚えたい。
        - 調子に乗って本だけ買いっぱなしの AWS SAP 資格をいっそこれから取りたい気がしている。
    - すごく当たり前なのだが、「ここまで理解して説明できる状態にしておく」ことで受かるという感覚がようやく分かった。設問を丸暗記しても意味ないのであとは触ること。


## 主に使ったもの

https://learn.microsoft.com/ja-jp/credentials/certifications/exams/az-305/practice/assessment?assessment-type=practice&assessmentId=15

https://www.udemy.com/ja/topic/microsoft-az-305/

本物のレベル感に一番近そう。

プラス、Oreilly サブスクの AZ 305 のコース「Exam AZ-305: Designing Microsoft Azure Infrastructure Solutions Crash Course」

### Link
https://github.com/timothywarner/az305

https://learn.microsoft.com/ja-jp/credentials/certifications/resources/study-guides/az-305

https://esi.microsoft.com/landing

https://entra.microsoft.com/#home

https://www.microsoft.com/ja-jp/security/business/microsoft-entra-pricing

https://learn.microsoft.com/ja-jp/azure/well-architected/

https://learn.microsoft.com/ja-jp/azure/reliability/cross-region-replication-azure

https://azure.microsoft.com/ja-jp/products/site-recovery



## 違いを理解したもの

https://learn.microsoft.com/ja-jp/azure/virtual-machines/sizes

https://learn.microsoft.com/ja-jp/azure/app-service/overview-hosting-plans

https://qiita.com/e99h2121/items/25ae757eaa884b8e35c1

https://qiita.com/e99h2121/items/7846aa8324c0ff0d933b

https://qiita.com/e99h2121/items/2f0061fa01d12a0a86ff

## 参考にしたもの

https://zenn.dev/takebi/scraps/2459473f1baea4

https://qiita.com/torippy1024/items/ef127cdf82bde9a3bb24



## 次ステップ

AZ-400 あたりを取るのが妥当そう

[試験 AZ-400: Microsoft DevOps ソリューションの設計と実装 - Certifications | Microsoft Learn](https://learn.microsoft.com/ja-jp/certifications/exams/az-400/)
[【合格体験記】Azure DevOps Engineer Expert【AZ-400】 | SIOS Tech. Lab](https://tech-lab.sios.jp/archives/33168)
[Azure認定資格 AZ-400を取得しました - Qiita](https://qiita.com/shingo_kawahara/items/1e0d371276d264fe65fc)

[Azure関連の資格の情報（2023年1月版）](https://zenn.dev/tomot/articles/80cbfb818e7c27)
[Azure関連資格、体系とか受ける順番とか。](https://zenn.dev/tomot/articles/c60883beaf3c5e)
[認定資格および試験を見る | Microsoft Learn](https://learn.microsoft.com/ja-jp/certifications/browse/?expanded=azure&products=azure)
inline CUDA

# 目的

HaskellでGPUを扱う場合には[accelerate](https://www.acceleratehs.org/)などがありますが、既存のGPUを扱えるC/C++のコードを使ってGPUとやり取りする場合に、直接CUDAのコードを扱いたい場合があります。

現状では、CUDAのファイルを使うワークフローが煩雑です。
cabalファイルはCUDAをサポートしてないので、CUDAのコードをあらかじめMakefileなどを使って事前にビルドし、cabalファイルにそのライブラリのファイルを追加するという流れになるかと思います。つまりcabalだけでビルドできません。
[こちらの例](https://github.com/tmcdonell/cuda/tree/master/examples/src/matrixMul)ではMakefileでnvccを使ってCUDAのファイルをビルドしてghcでそのファイルにリンクしていると思います。

今回HaskellのコードにCUDAのコードを埋め込み、cabalファイルに特別な変更を入れないでCUDAのコードを扱えるようにし、cabalだけでビルドできるようにします。

# CUDAを埋め込む方法

今回行ったCUDAを埋め込む方法を紹介します。

すでにHaskellのコード中にC言語のコードを埋め込む[inline-c](https://hackage.haskell.org/package/inline-c)パッケージがあります。
こちらは、template-haskellを使って次のように動作します。cabalの変更は不要です。

1. Haskellのコードをパースして、C言語のコードを抜き出す。
2. Haskellのコードに[FFIの`foreign import ccall`](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/ffi.html)を使いCの関数を呼び出すコードを追加
3. [addForeignSource](https://hackage.haskell.org/package/template-haskell-2.21.0.0/docs/Language-Haskell-TH-Syntax.html#v:addForeignSource)を使って、GHCにC言語のコードを生成してリンクさせる。

[addForeignSource](https://hackage.haskell.org/package/template-haskell-2.21.0.0/docs/Language-Haskell-TH-Syntax.html#v:addForeignSource)はC言語の他にC++、Objective C/C++、アセンブラ、オブジェクトファイルを追加することをサポートしています。

今回はオブジェクトファイルを追加する機能を使ってCUDAを呼び出すようにしました。
次のようにしてCUDAを呼び出します。実際はinline-cのコードを流用しています。

1. Haskellのコードをパースして、CUDAのコードを抜き出す。
1. CUDAのコードをnvccでコンパイルしてオブジェクトファイルにする。
1. Haskellのコードに[FFIの`foreign import ccall`](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/ffi.html)を使いC++の関数を呼び出すコードを追加（CUDAとC++の関数は同じ命名規約）
1. [addForeignSource](https://hackage.haskell.org/package/template-haskell-2.21.0.0/docs/Language-Haskell-TH-Syntax.html#v:addForeignSource)を使って、GHCにCUDAのオブジェクトファイルをリンクさせる。

ソースコードは[こちら](https://github.com/fpco/inline-c/tree/master/inline-c-cuda)です。

# 記述例

CUDAをHaskellに埋め込む例は次のようなものです。完全な例は[こちら](https://github.com/fpco/inline-c/blob/master/inline-c-cuda/test/tests.hs)です。

```Haskell
-- C言語でなくてCUDAを使うように設定
import qualified Language.C.Inline.Cuda as C

C.context $ C.cudaCtx

-- CUDAのカーネルを書く。
[C.emitBlock|
__global__ void
vectorAdd(const float *A, const float *B, float *C, int numElements)
{
...
}
|]

-- CUDAのカーネルを呼び出す。
vectorAdd :: Ptr C.CFloat -> Ptr C.CFloat -> Ptr C.CFloat -> CInt -> IO () 
vectorAdd d_A d_B d_C cNumElements =
  [C.block| void {
    const int threadsPerBlock = 256;
    const int blocksPerGrid =($(int cNumElements) + threadsPerBlock - 1) / threadsPerBlock;
    vectorAdd<<<blocksPerGrid, threadsPerBlock>>>($(float* d_A), $(float* d_B), $(float* d_C), $(int cNumElements));
  } |]
```

# まとめと課題

HaskellとCUDAの連携を既存のワークフローを壊さずにcabalだけで扱えるライブラリ[inline-c-cuda](https://hackage.haskell.org/package/inline-c-cuda)を作成しました。（nvccといったCUDAのコンパイラは別途インストールが必要です。）

今後の課題は、 CUDAのカーネル関数のFusionだと思っています。最近のGPUはメモリのバンド幅がネックになってきているらしく、複数のカーネル関数の一つの関数にしてメモリアクセスを減らし、パフォーマンスを上げる最適化が[pytorch](https://pytorch.org/get-started/pytorch-2.0/)や[CuPy](https://tech.preferred.jp/ja/blog/cupy-kernel-fusion-extension/)では行われています。CUDAを直接使わずにpythonでカーネル関数を使って行われています。
HaskellのStream Fusionで何とかなるといいのですが。
【JavaScript】someメソッドについて

:::note
`some()` は Array インスタンスのメソッドで、指定された関数で実装されているテストに、配列の中の少なくとも 1 つの要素が合格するかどうかを判定します。配列の中で指定された関数が `true` を返す要素を見つけた場合は `true` を返し、そうでない場合は `false` を返します。それ以外の場合は `false` を返します。配列は変更しません。
:::
引用

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some


### 使用例

```javascript
const array = [1, 2, 3, 4, 5];

const hasEvenNumber = array.some(element => element % 2 === 0);

console.log(hasEvenNumber); // 出力: true
```

この例では、arrayに偶数が含まれているかどうかをチェックしています。2が偶数であるため、someメソッドはtrueを返します。

* `some`メソッドは、配列内の要素がテスト条件を満たすとすぐに処理を停止し`true`を返します。
* 空の配列で`some`メソッドを呼び出すと、結果は常に`false`になります。
* `some`メソッドは元の配列を変更しません。
Amazon Aurora Limitless Databaseが解決する課題とそのアーキテクチャについて

## はじめに

AWS re:Invent 2023に行ってきました！初の海外カンファレンス参加でとても刺激的で良い経験となりました。

今回のre:Inventで発表されたアップデートの中でも、個人的に興味深かった「[Amazon Aurora Limitless Database](https://aws.amazon.com/jp/about-aws/whats-new/2023/11/amazon-aurora-limitless-database)」について紹介します。

## 従来のAmazon Aurora

従来のAmazon Auroraの読み込み性能をスケールするにはリードレプリカを追加して性能をスケールすることができました。しかし、書き込み性能をスケールするにはインスタンスサイズに制限を受けていました。

## Amazon Aurora Limitless Databaseとは

今回のアップデートでは上記の課題を解決する「Amazon Aurora Limitless Database」が発表されました。

「Amazon Aurora Limitless Database」とは、自動化された水平スケーリングをサポートし、1秒あたり数百万もの書き込みトランザクションを処理する新機能です。

## Amazon Aurora Limitless Databaseのアーキテクチャ

「Amazon Aurora Limitless Database Limitless」 Database のアーキテクチャは、以下の図の通りです。

複数のデータベースノード(トランザクションルーターとシャード) で構成される2層アーキテクチャです。

![](https://storage.googleapis.com/zenn-user-upload/1f98fc250aba-20231202.png)

Ref: https://aws.amazon.com/jp/blogs/aws/join-the-preview-amazon-aurora-limitless-database/

公式のブログより

>シャードは、それぞれがデータベースのデータのサブセットを保存する Aurora PostgreSQL DBインスタンスであり、並列処理により高い書き込みスループットを実現できます。トランザクションルーターはデータベースの分散性を管理し、単一のデータベースイメージをデータベースクライアントに提供します。

>トランザクションルーターは、データの保存場所に関するメタデータを維持し、受信SQLコマンドを解析してそれらのコマンドをシャードに送信し、シャードからデータを集約して単一の結果をクライアントに返し、分散トランザクションを管理して分散データベース全体の一貫性を維持します。Limitless Databaseアーキテクチャを構成するすべてのノードは、DB シャードグループに含まれます。DBシャードグループには、Limitless Databaseリソースにアクセスするための別のエンドポイントがあります。

## おわりに

嬉しいことに現地で「Amazon Aurora Limitless Database」と似たようなアーキテクチャをApache ShardingSphere-Proxyを使って構築したセッションを聞くことができました。こちらも今後調査していこうと思いました！

https://shardingsphere.apache.org/

https://www.youtube.com/watch?v=VcTPmEJeKM4

## 参考文献

1. https://aws.amazon.com/jp/blogs/aws/join-the-preview-amazon-aurora-limitless-database/
[Ubuntu] TexLiveのインストール

# 環境
Ubuntu 23.04
# TexLiveのインストール
参考: [Linux - TeX Wiki](https://texwiki.texjp.org/?Linux#texlive)
1. ファイルのダウンロード
```bash
$ curl -OL http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
```
- `curl`: URLからダウンロードするやつ
- `-O`: ダウンロード先と同じ名前にする
- `-L`: ダウンロード先がリダイレクトしても、リダイレクト先のファイルをダウンロードする

2.解凍
```bash
$ tar xvf install-tl-unx.tar.gz
```
- `tar`: メインは複数のファイルをアーカイブとして一つにまとめる
- `x`: アーカイブを解凍する
- `v`: verboseの略で、詳細な出力をする
- `f`: 後ろに対象のファイル名を入力. fileの略

3.移動
```bash
$ cd install-tl-2*
```
移動

4.インストール
```bash
$ sudo ./install-tl -no-gui -repository http://mirror.ctan.org/systems/texlive/tlnet/
```
途中で聞かれる
```bash
Actions:
 <I> start installation to hard disk
 <H> help
 <Q> quit
 ```
Iでインストール
でも途中でfailedになった
公式によると、以下で行けたり行けなかったりするらしい
```bash
$ sudo ./install-tl -no-gui -profile installation.profile
```
~~今インストール中なので行けるかもしれん~~
50分はかかったがなんとかインストールできた

5.PATHを通す
```bash
$ sudo /usr/local/texlive/2023/bin/*/tlmgr path add
```
やってることは同じ
```bash
$ echo 'export PATH=$PATH:/usr/local/texlive/2023/bin/*/tlmgr' >> ~/.bashrc
$ source ~/.bashrc
```
6.日本語系のインストール
```bash
$ sudo tlmgr install collection-langjapanese collection-langcjk
```
これで終了！

# 詰まった所
## tlmgrのエラー
```bash
tlmgr: Local TeX Live (2022) is older than remote repository (2023)
```
というエラーが出た。
## 原因
恐らく、`texlive-base`をaptでインストールしたことが原因。
```bash
$ sudo perl ./install-tl --scheme=small --no-interaction 
```
1. 上記コマンドでschemeをsmallでインストールしたことでtlmgrが入っていなかった
2. サジェストされた`texlive-base`が2022のものだったためコンフリクトが起こる

## 解決策
```bash
$ sudo apt --purge remove texlive-base
$ sudo rm -rf /usr/local/texlive
```
完全に削除して、この記事の方法で最新のフルのTexLiveをインストールし直す。
**大は小を兼ねる!!**

# おわりに
めちゃめちゃ苦戦しましたがなんとかやりきった
次回はVSCodeでの設定諸々を書きます！
「あ、私GitHubにコードを公開したいだけなんです。」

# 本記事で取り扱う事
- GitHubを用いてWeb上に自分のコードを**取り敢えず**公開する方法

「取り敢えず」ってのががミソです。
誰かにコード見てもらいたいと思ったものの、いざGitHubについて調べると、なんか色々長ったらしい説明が出てきて読むのに疲れて諦めてしまった人が周りにいたので書きました。

所以、詳しい説明は本記事では取り扱わないので悪しからず。
一回使えるようになってしまえば説明に対するハードルも下がるので、詳しい説明をされている方々の記事も読めるようになるかと。。。。

# 前提・対象
- Gitのダウンロードが済んでいる
- GitHubの登録が済んでいる(まだの人は下から登録)
- とりあえずGitHubに公開したい人

https://github.com/

::: note warn
Web上に公開する。つまり不特定多数の人が閲覧可能な状態だという事を常に念頭に置いてください。
メールアドレスなどの個人情報を直接記載することは控え、APIキーなどは適宜環境変数や設定ファイルに記載することを推奨します。
:::

# 公開鍵・秘密鍵の発行
まず初めにGitHubと自身のPCを紐づける公開鍵、秘密鍵を発行します
macの方はこちら
```terminal:terminal
$mkdir .ssh
$cd .ssh
$ssh-keygen -t rsa -C '自分のメールアドレス'
//色々聞かれるが何も入力せずEnterを数回入力
$cat id_rsa.pub
```
windowsの方はこちら
```powershell:powershell
$mkdir .ssh
$cd .ssh
$ssh-keygen -t rsa -C '自分のメールアドレス'
//色々聞かれるが何も入力せずEnterを数回入力
$type "id_rsa.pub"
```
最後に以下の様な超長い文字列が出力されると思います。
`ssh-rsa AAAAB3NzaC1yc2EAAA..............................................
`
これを**ssh-rsaの部分から最後までコピー**しておいてください！

# 発行した公開鍵の登録
以下のURLにアクセスしてください。
https://github.com/settings/ssh/new

写真の様な画面になると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874115/2a224e11-db67-65b7-fb7b-33a2b0dbd15a.png)
Title欄→`分かりやすい任意の文字列（登録日とか）`
Keytype→`Authentication Key`
Key欄→`先ほどコピーした超長い文字列`
を入力し、`Add SSH key`を押して登録してください。

# GitHubレポジトリの作成
以下のURLにアクセスしてください
どこかしらの`New`という緑色のボタンを押して頂いても大丈夫です。
https://github.com/new
写真のような画面になると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874115/5da32458-ad28-87f3-acc7-d3bb7c57ce14.png)

`Repository name`欄にご自身のプロダクトの名前を設定してください。
※英数字のみ、分かりやすい名前推奨

それ以外は何もいじらず右下にある緑の`Create repository`を押下

すると以下の様な画面になるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874115/d4532557-86d4-76e0-cdd9-9eccf6450ce1.png)
緑で囲っている部分を`SSH`に変更し、赤枠で囲っている部分をコピーしておいてください。
# コマンド入力
ご自身のユーザー名とメアドを登録してください。
```:terminal
git config --global user.name "ユーザー名"
git config --global user.email "メールアドレス"
```
:::note warn
ここからは、ご自身のプロダクトの階層で行ってください。
:::
以下の順に入力してください。
```:terminal
$git add .
$git commit -m "first commit"
$git remote add origin さきほど赤枠内でコピーした内容
$git push origin master
```

::: note warn
macの場合はデフォルトがmainブランチの場合があるのでその場合は`git push origin main`と打ちましょう
:::

GitHubに戻り、`Repositories`の欄に作成したレポジトリ名があれば成功です。（写真でいうexample）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874115/bbfa6e19-4b24-1154-21ab-b2bd5699f13d.png)

コードを共有する場合はご自身のレポジトリ名にアクセスし、その際のURL：`https://github.com/ご自身のユーザー名/レポジトリ名`を共有しましょう。

# プロダクトを編集してGitHubのレポジトリも更新したい時
ご自身のプロダクトが改良されるなどして、最新の状態のコードを公開したいときは以下の順にコマンドを入力してください。
```:terminal
git add .
git commit -m "変更内容をメモ"
git push origin master
```

記事自体は以上です。お疲れ様でした。

# 紹介
今回は個人のプロダクトをただ公開する事のみに焦点を当てましたが、Git・GitHubを使うとコードを元に戻したり、チームで開発出来たりします。

もっと詳しく公開鍵やGitHubについて知りたい人向けに

https://engineer-ninaritai.com/public-key-cryptography/

https://zenn.dev/penguin4731/books/11bee5738e367f/viewer/ecfd5e
SwiftDataのプロパティに"hash"という名前を使うとクラッシュする


これが該当のコード
```Swift
import Foundation
import SwiftData

@Model
final class HogeHoge {
    var hash: String?

    init(_hash: String?) {
        self.hash = hash
    }
}

```
以下がエラー箇所です。

```Swift
{
    @storageRestrictions(accesses: _$backingData, initializes: _hash)
        init(initialValue) {
                    _$backingData.setValue(forKey: \.hash, to: initialValue)
                    _hash = _SwiftDataNoType()
        }

    get {
                    _$observationRegistrar.access(self, keyPath: \.hash) //ここ？
                    return self.getValue(forKey: \.hash)
        }

    set {
                    _$observationRegistrar.withMutation(of: self, keyPath: \.hash) {
                            self.setValue(forKey: \.hash, to: newValue)
                    }
        }
}

```


予約語かなんか使ってるんでしたっけ？とりあえずコンパイル時には警告がなくて、値を取得するときに初めてエラーになる感じでした。
Unityのインスペクタに力技で適当なボタンをねじ込む

こちらは[クラスター Advent Calendar 2023](https://qiita.com/advent-calendar/2023/cluster)（2ページ目）の16日目の記事です！
前日は @kitta65 さんの「[趣味開発のフォーマッタが業務でちょっと役立った話](https://qiita.com/kitta65/items/90cbd652451bdf03b014)」でした！larkを初めて知ったので、今度何かつくってみたいですね。

こんにちは、スワンマンです。クラスター株式会社で主にイベントディレクターとかスワンマンをしています。
![近影](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58380/31dc0a8c-b868-5004-31a1-23cdde6fbfc3.png)

# はじめに

今回[Editor](https://docs.unity3d.com/ja/2021.3/ScriptReference/Editor.html)を使わずにインスペクタを拡張したいんですよ。EditorというのはUnityのクラスで、特定の型をインスペクタ上でいい感じに表示するのに役立つあれですが、今回はそのEditorを使わずに適当な位置に適当なボタンをねじ込みたいんです。
なお、何故そうしたいのかはこの際置いておくこととします。

※今回の内容はUnity 2021.3.4f1上での話です

# PropertyCallbackScope

EditorGUIUtilityにPropertyCallbackScopeというメソッドがあります。
プロパティの表示前にコールバックが行われるスコープを設定するためのもので、[公式リファレンス](https://docs.unity3d.com/ja/current/ScriptReference/EditorGUIUtility.PropertyCallbackScope.html)を見る感じではこう使えということらしいです。
```c#
class MyEditor : EditorWindow
{
    void OnGUI()
    {
        using (var s = new EditorGUIUtility.PropertyCallbackScope((rect, property) => { Debug.Log($"About to draw property path {property.propertyPath}"); }))
        {
            // Block of code with controls
        }
    }
}
```

これ、あたかもOnGUIなどのUI描画の中だけで使えそうな雰囲気を醸し出してますが、全然そんなことはなく違う場所からも呼び出すことが可能です。
そしてUIの描画に関係ないところで生成しっぱなしにすると、全てのプロパティの描画前にコールバックされるようになります。

例えばこんなコードを書くと、
```c#
public class TotemoHidoiFurumai
{
    static EditorGUIUtility.PropertyCallbackScope scope;

    [InitializeOnLoadMethod]
    static void Initialize()
    {
        scope = new EditorGUIUtility.PropertyCallbackScope((rect, prop) => EditorGUILayout.LabelField(prop.propertyPath));
    }
}
```
インスペクタがこうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58380/c428639c-da85-ba8f-1e09-7a29869b50b3.png)

これでいい感じのプロパティの位置が分かったので、あとはこんな感じでボタンをねじ込みます。
```c#
public class SugokuHidoiFurumai
{
    static EditorGUIUtility.PropertyCallbackScope scope;

    [InitializeOnLoadMethod]
    private static void Initialize()
    {
        scope = new EditorGUIUtility.PropertyCallbackScope((rect, prop) =>
        {
            if (prop.serializedObject.targetObject.GetType().Name != "Transform") return;
            if (prop.propertyPath != "m_LocalScale") return;
            if (GUILayout.Button("押す"))
            {
                Debug.Log("やあ");
            }
        });
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58380/0af82b8c-7eb7-fb9b-05a3-d406b28532f7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58380/3559f96f-6f7b-dabd-087d-a18b88945b47.png)

こうして、この世にまたひとつクソコードが生み出されました。

# より良い記事への旅立ち

明日は @MatchaChoco010 さんの「四足歩行アバターを無理やり作る話」です。無理矢理のバトンを明日へ😉
【脱初心者】一般人の知識でテストを強化する

この記事は [ACCESS Advent Calendar 2023](https://qiita.com/advent-calendar/2023/access) 18日目の記事です。

こんにちは、一人用こたつから離れられない @keigo1450 です。
今回は弊社プロダクトである [Linkit Maps](https://linkit.access-company.com/map_resilience/#) を題材に、テスト設計初心者向けの小技を紹介したいと思います。

**対象読者：**
* テストの経験が浅め
* 担当になった製品・サービスやその業界にまだ詳しくない
* テスト技法についてあまり知らない
* きちんとテスト項目を出しているつもりなのにレビューで観点漏れをたくさん指摘される
* 今すぐテストを改善したい

## 3行まとめ

* 仕様書だけを使ったテスト設計には限界がある
* テスト対象を使う人・使われる状況にどんなバリエーションがあるか、一般的な知識から書き出してみよう
* バリエーションを使って「こんな条件でも動くか？」「こんな状況でも使えるか？」という実用性を確認するテストケースを作ろう

## お題：Linkit Maps 位置情報ライブ自動停止・再開機能

（※以下の仕様は題材とするために簡略化したものです）

Linkit Maps には「位置情報ライブ」という機能があり、 **自分の現在位置を他のユーザーと共有する** ことができます。
この位置情報ライブ機能に対し、追加で「自動停止・再開設定」を行うと、毎日・自動的に **「始業時間に位置情報共有を開始し、終業時間に停止する（=業務時間外は位置情報を共有しない）」** ことができます。（エアコンやテレビのOn/Offタイマーや旅行中に部屋の照明をOn/Offする防犯機能などをイメージしてもらえればと思います。）

自動停止・再開設定は3つのUI部品で行います。

* 自動停止・再開スイッチ（初期値 Off）
* 自動再開時刻（初期値 9:00）
* 自動停止時刻（初期値 17:00）

## テスト初心者あるある

「テストをしてください」「テストを作ってください」と言われたときに仕様書からキーワードを拾ってテストしていませんか？

例えばこんな感じです。

* スイッチがオフのとき自動停止・再開しないこと
* スイッチがオンのとき自動停止・再開すること
* 自動再開時刻を変更できること
* 自動停止時刻を変更できること
* …

これらは必要なテストケースですが、これで十分かというとどうでしょうか？
「そうは言っても、まだ製品に詳しくないし…」「テスト技法を身につけるには時間がかかるし…」という人もいるかもしれません。

でも実は、**「誰でも知っている普通のこと」がテストの強化に使えるんです！**

（脱線しますがまずは仕様書から情報を絞り尽くそうという過去記事はこちら → [天・地・表・裏で仕様を読む](https://qiita.com/keigo1450/items/4e0cdfff72eb151c3b7a
)）

## テスト対象の「外側」=現実世界の「色々」に目を向けよう

もしテスト対象について詳しくなくても、それが使われるこの世界のことを私達は色々と知っています。
例えばテスト対象を使う「人」や「環境」について考えてみると、さまざまなバリエーションを思いつくでしょう。

* 業種の違い（建設業、運輸業、不動産業など）
* 職種の違い（営業職、管理職など）
* 勤務時間帯の違い（日勤、夜勤、時短など）
  * 利用シーンの違い（朝、昼、夜、深夜など）
* 勤務場所の違い（都心、地方、海外など）
* …

（Linkit Mapsは主に企業を対象にした製品なので職業に関するバリエーションを例として挙げています。別の製品であれば年齢や性別、趣味などのバリエーションも考えられるかもしれません）

また、「環境」を「ユーザの日常生活」と言い換えてみると、さまざまな出来事（イベント）が起きうることも分かります。

* 仕事中、スマホの電池が切れる
* 移動中に圏外になる
* 電話がかかってきて作業が中断される
* 有休を取る
* …

**こういう人もいる、こういうことも起こる、というような、大抵の人が知っていることをテストに組み込んでみるとどうなるでしょうか？**

* 夜勤の人が自動停止・再開機能を設定しても（例：再開 20:00 / 停止 6:00）動作するか？
* 日本で自動停止・再開を設定した人が海外（例：時差+3時間）に行ったら何時に動作するか？
* 自動停止時刻にスマホの電池が切れていて、帰宅後に充電して電源が入ったら停止状態になるか？
* 自動再開時に圏外エリアにいても正常に再開するか？
* 停止時刻・再開時刻に別のアプリ（例：通話アプリ）を使っていても停止・再開するか？
* …

**テスト対象が現実世界のさまざまな場面にきちんと対応できること、実用に耐えうることを確認するテストケースを作ることができます。**

:::note warn
注意
「これができれば専門知識やテスト技法が不要だ！」ということではありません。また、テストケースの増え過ぎに注意しましょう。
:::

## 「ちゃんとしなきゃ」と思わなくていい

テストケースを作るとき、無意識に「仕様書などチーム内で認められた文書を元にテストケースを作らなきゃいけない」と思っていませんか？
"電池が切れたら"、"スマホを落としたら" なんて日常的なワードは、なんとなく「ちゃんとしてない」と思っていませんか？

大事なのは「仕様書通りに動くこと」ではなくて「実社会で使えること」です。
そしてそれをテストするために必要な知識の一部は、既にあなたの中にあります！
頭の中から「色々」を発掘してテストに活用しましょう！

読んでいただいてありがとうございました。
明日は @komitake さんです！
<title>を変更するhooks

ReactでCSR単体の開発を行う場合`<title>`要素の管理をJavaScript側から行う必要があります。
ページ・コンポーネントごとに`<title>`を設定するようにしても良いですが、hooksとして切り出して再利用したいです。
この記事では`<title>`を設定することと、アンマウント時にタイトルを元の状態に戻せるようなhooksを紹介します。

`<title>`には`document.title`でアクセスできます。そして、`document.title`に文字列を渡すことで値の設定ができます。
そのため、`SampleComponent`コンポーネントをマウントした時に`<title>`を設定するには以下のようにします。
```tsx
const SampleComponent: FC = () => {
  useEffect(() => {
    document.title = 'サンプル';
  }, []);

  return <></>;
};
```
これをhooksに抜き出すと以下のようになります。
```ts
const useTitle = (title: string) => {
  useEffect(() => {
    document.title = title;
  }, [title]);
};
```
これで、コンポーネントがマウントされた時にタイトルの設定が可能になりました。
このままでは、コンポーネントがアンマウントされた時もタイトルを維持してしまいます。任意でアンマウントするタイミングに元のタイトルへ戻せるようにしていきます。
```ts
const useTitle = (title: string, restorePrevTitle = false) => {
  const prevTitle = useRef<string>(document.title);

  useEffect(() => {
    if (prevTitle.current === title) {
      return;
    }
    document.title = title;

    return () => {
      if (restorePrevTitle) {
        document.title = prevTitle.current;
      }
    }
  }, [title]);
};
```
新たに`restorePrevTitle`を引数に取り、`true`の場合はアンマウント時に元のタイトルへ戻るようにしました。
`<title>`を変更する前の値は`ref`に渡すことにより、レンダリング間で保持させています。そして、アンマウント時にその値を`document.title`に渡すことで元のタイトルへ戻すようにしました。

このhooksを使うときは同時に複数のコンポーネントで利用しないことです。複数のコンポーネントで利用した場合はそれぞれのライフサイクルなどのタイミングによって設定されるタイトルが一意に定まらないことが多いので気をつけてください。
Google Colabで気軽にGBFSに触れてみる




:::note info
この記事は [シェアモビリティの標準的なデータフォーマット GBFS Advent Calendar 2023](https://qiita.com/advent-calendar/2023/gbfs) の 17日目の記事です。
:::


# はじめに
この記事をご覧の方はGBFSがどういったものかご存知だと思うので、GBFSの基本的な説明は省きます。

GBFSってなに？という方は、@kumatira さんの記事を参照してください。

https://qiita.com/kumatira/items/f9229c21d9f0db3b5ae3

この記事ではブラウザ上でPythonを実行できるGoogle ColabからGBFSのデータにアクセスする方法を紹介します。

GBFSはjsonの集合体です。そのまま見てもある程度の内容は確認できますが、プログラミング言語を使ってアクセスするとデータの加工やフィルタが簡単にできます。今回はPythonを使ってGBFSのデータにアクセスしてみようと思います。

# Google Colab
以下のURLからアクセスします。

https://colab.research.google.com/?hl=ja

Google Colabを開くとこのような画面になります。
左上のメニューから `ノートブックを新規作成` をクリックします。
![スクリーンショット 2023-12-16 0.19.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102273/9b3d34ae-b3ad-3250-274f-0e1b07d230e5.png)


## GBFSにアクセスするためのライブラリをインストールする
まずはライブラリをインストールするためのコマンドを入力して実行します。 `▶️` を押すと実行されます。

```
pip install gbfs-client
```

![スクリーンショット 2023-12-16 0.20.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102273/ec2e5fdd-63e2-c311-d92d-63feb63f3cc5.png)

しばらく待つとライブラリのインストールが完了します。

![スクリーンショット 2023-12-16 0.24.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102273/9f2c2411-662d-3b69-b145-eb6ad8a4be0f.png)


あとはPythonでGBFSにアクセスするコードを書くだけです!

# 自転車をたくさん置けるステーションの一覧
シェアサイクルのステーションで自転車がたくさん置ける場所の一覧を出してみようと思います。
今回はドコモバイクシェアさんのデータを使用しています、コードを変えることで他のシェアサイクル事業者のデータを見ることもできます。

以下のコードをGoogle Colabに入力して実行します。

```python
from gbfs.services import SystemDiscoveryService
from gbfs.client import GBFSClient

ds = SystemDiscoveryService()

# ドコモ・バイクシェア
client = ds.instantiate_client('docomo-cycle', 'ja')

# ステーションの情報を取得
stations = client.request_feed('station_information').get('data').get('stations')

station_dict = {}

for station in stations:
  name = station.get('name')
  capacity = station.get('capacity')
  station_dict[name] = capacity

# キャパシティの多い順にソートする
station_dict = sorted(station_dict.items(), key=lambda x:x[1], reverse=True)

for station in station_dict:
  print(station)

```

数秒待つとGoogle Colabに結果が表示されます。
(2023/12/16時点のデータです)
1位のステーションでは、なんと115台も自転車が置けるようです!!
2以下も巨大なステーションであることがわかりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102273/d3526741-ab12-19fd-a415-bf75c096a3a1.png)

このようなにGoogle Colabを使うと、Pythonの環境構築など面倒な作業なしでコードを実行することができます。

# 参考
https://qiita.com/kumatira/items/f9229c21d9f0db3b5ae3

https://qiita.com/muto-jo/items/da9bbda99e65c25e3c07

https://qiita.com/muto-jo/items/15fd5ab4276ea1651271
PHP ぼやき日記 2023-12-15

- [次回](https://qiita.com/sj-i/items/bda185bfd574d3cbb89d)
- [前回](https://qiita.com/sj-i/items/ea5df5e11926406b56d1)

不定期に誰に向けるでもなく PHP に関する雑な殴り書きをしている。日付が変わってから変わる前の日付の奴だと言い張って投稿するくらいの雑さ加減。

# private class const あるから local const いらないんじゃない？って言われた
- https://phpc.social/@Crell/111574253159763975
- 俺もなんかそんな気もする
- あとなんかもう一人コメントくれた Russel のひとの[予見](https://phpc.social/@zimzat@mastodon.social/111574636631512790)が秀逸かつ辛辣で笑った
    - いわく、「まず変数の使いまわしを防ぐよう皆デフォで使いはじめるよね」
    - 「次は型宣言もつけようぜってなるよね、はい別 RFC」
    - 「`$` が嫌いな連中も途中から気に入りはじめて、次の RFC は仮引数に定数を使えるようにする奴だろうね」
    - 「そんで次は shadowing とか言い始めるの、はいまた別 RFC」
    - 「一貫しない構文がドミノ倒し的に作られるわけよ」
    - 「ぶっちゃけ単に子クラスで使ったりオーバーライドしたりできない形で状態の別の持ち方を増やすだけだよねそれ」
    - まあローカル変数のかわりなんで子クラスで使ったりオーバーライドしたりできないのは何も悪いことではないし、mutable な変数よりはマシな状態の持ち方だと思うけども、予見そのものはかなり良いところを突いてるように見える、多分本当にそうなる
- 「いらないんじゃない？」という話も分かる一方、やっぱりあったら使うくらいの欲しさ具合はあるんだよな、という感じがするので、[前回の](https://qiita.com/sj-i/items/ea5df5e11926406b56d1#php-%E3%81%AB%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%81%AE-const-%E3%81%BF%E3%81%9F%E3%81%84%E3%81%AA%E3%81%AE%E8%A6%81%E3%82%8B%E3%81%8B%E3%81%AA%E3%81%82)に引き続き欲しい理由が強めにある人いれば教えてほしい
- ついったードットコムで英語でしゃべるのはあまりピンとこないけど（基本日本人としか絡まないし）マストドンだと外人ばっかりなので英語でいいかなってなる

# PHPMD 2.15.0 が出てる
- https://github.com/phpmd/phpmd/releases/tag/2.15.0
- 先行して出てた [PHP Depend](https://github.com/pdepend/pdepend) 2.16 での PHP 8.3 / Symfony 7 の構文対応を含む

# nielsdos のひとが ext/dom の HTML 仕様にのっとってない部分を書き出してた
- https://github.com/nielsdos/php-src/blob/dom-spec-compliance/bugs.md

# staabm のひとが PHPStan で TODO 管理できるようにしてた
- https://github.com/staabm/phpstan-todo-by
- 何を言っているのかわからねーと思うが、TODO コメントに日付を書いておくとその日までに解消されてなかったら PHPStan 先生に怒られるという
- やれば旅行とか結婚式とかのライフイベントの準備まで PHPStan で管理できなくもなそうである

# Xdebug 3.3.1 が出てた
- https://xdebug.org/announcements/2023-12-14
- これはバグ修正リリースだけど、[先月の 3.3.0](https://xdebug.org/announcements/2023-11-30) でフレームグラフ出せるようになってたり中を見れる内部クラスの構造が増えてたりしてわりと元気
Materialの正体

# 前書き

この記事は、2023のUnityアドカレの12/16の記事です。
今年は、完走賞に挑戦してみたいと思います。Qiita君ぬい欲しい！

https://qiita.com/advent-calendar/2023/present-calendar#qiita_award

# はじめに

ゲーム内に存在するオブジェクトの色や質感を調節するためのMaterialです。普段何気なく使っていますが、これは一体全体何者なのでしょうか？特にGraphicsAPIを少しでもかじったことのある方なら尚更謎に感じるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280975/60892c61-4e5f-aa8c-5e4d-d998f95c709e.png)

# 描画するということ

Unityでシーンのオブジェクトを表示するときには隠蔽されていますが、実際にはこのような処理がなされています。

1. 現在の「状態」が存在する
1. 頂点シェーダプログラムをセットする
1. ピクセルシェーダプログラムをセットする
1. 定数バッファをbスロット（番号指定）にセットする
1. テクスチャや構造化バッファをtスロットにセットする
1. テクスチャサンプラーをsストッロにセットする
1. RenderTargetをセットする
1. 描画コマンドの発行

（DX12やVulkanでは○○をセットの部分は、RootSignetureやDescriptorTableなどに固めてセットしたりもします）

マテリアルの「マ」の字も出てきません。

# マテリアルの役割

マテリアルは、上記の機能の一部がセットで提供しています。

- 頂点シェーダプログラムの指定
- ピクセルシェーダプログラムの指定
- 定数バッファとスロット（名前）の指定
- テクスチャとスロット（名前）の指定

### 頂点/ピクセルシェーダプログラムの指定

UnityのShaderは頂点シェーダとピクセルシェーダとそれぞれのバリアントのセットとなっています。

```csharp
class Shader
{
    // シェーダキーワードで引けるようになっている
    Dictionary<HashSet<string>, ShaderProgram> VertexShaderVariants;
    Dictionary<HashSet<string>, ShaderProgram> PixelShaderVariants;
}
```

MaterialにはShaderとShaderKeywordsが設定できますが、これにより、個別のシェーダプログラムが解決できるわけです。

### 定数バッファとスロット（名前）の指定

Materialに保存されている、Float、Vector、Integerは実は定数バッファの個別の中身（フィールド）です。描画時に、これらのMaterialパラメータが定数バッファにPackされてセットされます。

基本指定のないものは`$Global`という名のスロットに差し込まれます。これは、Shader側でグローバル変数のように書かれているものです。（バラバラに書かれていても、1つの定数バッファとして受け付けます）

他にも、`UnityParMateral`という定数バッファを利用できます。これは、Shader側でパラメータ名を`UnityParMateral`という名前の定数バッファとして書いておくと自動でそこにアサインされます。また、この仕組みはSRPBatcherと呼ばれています。`$Global`にはMaterial由来のパラメータだけでなく、`Shader.SetGlobalFloat`などで設定されるグローバル値もPackされるので、ドローコールごとに作成とGPUへの転送が必要です。一方で、`UnityParMateral`は、マテリアルの値が変更されたときにだけ更新すればよいので、GPU側に置きっぱなしでよいのです。だから速いと。

Material由来ではありませんが、`UntityParDraw`、`UnityParFrame`という定数バッファもあります。

### テクスチャとスロット（名前）の指定

Materialのテクスチャパラメータはそのまま、Shader内で対応するTextureのスロットにセットされます。サンプラーはUnityではTextureとセットみたいな扱いになっているので、TextureをセットするときそのTextureにくっついていたサンプラーを一緒にセットします。

また、StructuredBufferという汎用バッファはMaterialが対応していないのでセットすることはできません。

# まとめ

ということで、これがMaterialの正体でした。ザックリいうと、描画コマンドを呼び出すときにセットすべきオオブジェクト群と、Shaderプログラムを解決するための情報がセットで保存されているということですね。
macOSにgfortranを導入する

## 前書き

大学の生協で買ったMacBook AirでFortranを動かしてみたいと思ったので、gfortranを導入した。

なお、筆者のノートパソコンの状態は以下の通り。

-Macbook Air
-Apple M1
-Sonoma 14.1.2（23B92）

なお、前準備としてHomebrewを導入している。

https://qiita.com/Kazuma-Nakano/items/e76c636312c87e1395f2

また導入に際しては、下記のサイトをゴリゴリに参照している。

http://www.compe.media.kyoto-u.ac.jp/syoseki/mac/mac-gfortran.html

## 導入

導入したいgfortranは、GCC（GNU Compiler Collection）というの略で，様々なプログラミング言語のコンパイラ集に含まれている。

これを以下のコマンドをターミナルで実行することでインストールする。

```Objective-C:Objective-C
brew install gcc
```

実行か完了したら、``gfortran -v``をターミナルに打ってバージョンを確認する。
実行結果が出ればOK。

導入ができたらあとは実践あるのみ。
練習として以下のサイトなどがおすすめ。

https://amanotk.github.io/fortran-resume-public/

## 参考

https://qiita.com/Kazuma-Nakano/items/e76c636312c87e1395f2

http://www.compe.media.kyoto-u.ac.jp/syoseki/mac/mac-gfortran.html
Postman での作業が格段に捗るショートカット集

これは[Postman Advent Calendar 2023](https://qiita.com/advent-calendar/2023/postman) シリーズ2 15日目の記事。

日常的に[Postman](https://www.postman.com/) を使っている私が思う作業が格段に捗るPostman ショートカットを紹介します。塵も積もればと何とかといいますが、同じような作業を繰り返す場合、大きく時間をセーブできると思います。

| 処理 | Windowsコマンド | macOSコマンド |
| --- | --- | --- |
| リクエスト送信 | Ctrl + Enter | ⌘ + Enter |
| 新規タブ作成（新規リクエスト作成） | Ctrl + t | ⌘ + t |
| リクエスト保存 | Ctrl + s | ⌘ + s |
| タブを閉じる | Ctrl + w | ⌘ + w |
| サイドバー切り替え | Ctrl + \ | ⌘ + \ |
| 2分割表示の切り替え | Alt + Ctrl + v | ⇧ + ⌘ + v |
| 環境セレクター表示 | Alt + e | ⌥ + e |
| 検索 | Ctrl + k | ⌘ + k |

補足: 
- ⌘ = Command
- ⌥ = Option / Alt
- ⇧ = Shift


これらのショートカット、覚えていればよいですが、忘れることがあります。そんなときは次のコマンドを叩くことでデフォルトショートカット一覧（下記イメージ）が表示されます。もしくは Settings (設定) > Shortcuts (ショートカット)にナビゲートしても同様の表示がされます。

- Windows: `Ctrl` + `/`
- macOS: `⌘` + `/`

![Screenshot 2023-12-15 at 23.26.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/c4ad7db4-e86e-eee5-51c3-98d94fa40e4f.png)

また、デスクトップアプリの場合は、デフォルトのショートカットを変更できます。下記イメージのように変更したいショートカットにホバーさせると編集マークがでます。

![Screenshot 2023-12-15 at 23.31.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/156702ae-7d8e-0f9e-c27e-3102894b88f1.png)

Happy API testing with Postman!
ChromeDriverManagerで複数同時起動する方法

## 前置き
初めに...こんなエラーで悩んでいませんか？
```
Python SeleniumでPermissionError: [WinError 5] アクセスが拒否されました。
```
多くの方はChromeDriverManagerで複数同時起動できないと悩んでいるはずです。
そんな悩みを解決する策を紹介していきます！


## 解決策
最初にコード見せます。理解できない人は解説を見てくださいね。
```python:example.py
...前略...

# driverを起動する関数
def tmp(path):
    # 文字列のパスをserviceに変換
    service = Service(executable_path=path)
    # 起動
    driver = webdriver.Chrome(service=service)
    input(">>")

# パスを取得
path = ChromeDriverManager().install()
for i in range(10):
    # threadで並行処理としてtmpを呼び出す
    threading.Thread(target=lambda: tmp(path)).start()
    time.sleep(1)
```

## 解説
### 結論
・「ChromeDriverManager().install()」は複数同時起動できない
・ webdriverは文字列のパスだけで起動可能
・「ChromeDriverManager().install()」を一度だけ実行し、戻り値のChromeDriverのパスを起動時に使いまわす


### 「ChromeDriverManager().install()」とは？
ChromeDriverManager().install()の通常の使い方はこんな感じですよね
```
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
```
ここで「ChromeDriverManager().install()」の処理内容としては

・新たなChromeバージョンのインストール
・戻り値でインストールしたChromeDriver.exeのパスを返す

といった形です。

この処理内容をみると複数回「ChromeDriverManager().install()」を実行する必要はないと気づきました。そこで1度だけ「ChromeDriverManager().install()」を実行し、ChromeDriverのパスを取得してパスを起動時に使いまわせば複数起動できるのでは。。。と考え検証したところ、成功した次第です。

つまりChromeDriverManager().install()を複数回実行する必要はないし、driver起動にはパスだけあればOKということです！
【VSCode+SpringBoot】SpringBootでAPIを作る⑤

前回↓

https://qiita.com/NaN-jp/items/ca04be9e34732d1204c9

# はじめに
今回はControllerを作成していく

### Controller作成
`Model`と`View`を操作する`Controller`を作成していきます
demo直下にcontrollerフォルダを作成してその中に`PersonController.java`を作成します
```java:src/main/java/com/example/demo/controller/PersonController.java
package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

import com.example.springbootpostgresql.model.Person;

@Controller
public class PersonController {
    @Autowired
    PersonService service;

    @GetMapping("/")
    public String index(Model model){
        model.addAttribute("person", new Person());
        return "index";
    }

    @PostMapping("/insertPerson")
    public String insertPerson(@ModelAttribute Person person, Model model){
        service.insert(person);
        return "result";
    }
}

```
### ⚠️注意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627466/b8ca110d-0329-d437-6a1d-333affb4bbd0.png)
このようなエラーが出ている場合はpom.xmlの`<dependencies></dependencies>`内に以下を追記してください
```xml:pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
```
***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627466/c4dce8c5-1af8-d2a6-2b73-1fef2806aae6.png)
この部分のエラーはとりあえず無視しちゃって大丈夫です
### ✨解説
##### アノテーション
◎`@Controller`
これを付けたクラスをSpringBootは**Controller**として認識します

◎`@Autowired`
詳しく説明してるのはこちら↓

https://springhack.com/autowired-%EF%BC%88springboot%E3%81%AE%E3%82%A2%E3%83%8E%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%EF%BC%89/

◎`@GetMapping`
()内で与えられたURL表現式と一致するHTTP GETリクエストを処理します

◎`@PostMapping`
()内で与えられたURL表現式と一致するHTTP POSTリクエストを処理します

◎`@ModelAttribute`
このアノテーションが付与されることにより、フォームで入力した値を受け取ることができるようになります

# おわりに
今回はControllerを作成しました
次回はRepositoryを作成します
自分のスキルとフリーランスする上であったらいいなぁと思ったスキル

# 自己紹介
- 大分県生まれ大分県育ち東京都在住
- スタートアップのCTO
- フリーランスエンジニアとしても活動中
- 好きな言語/FW -> Django/TypeScript/React

# 自分のスキル
- Django/Laravelを用いたAPI/バックエンド開発
- Typescript/Reactを用いたWebフロントエンド開発
- AWSを使った簡単なインフラ構築
- NginxでのWebサーバー構築


まぁ…こんな感じですかね…
ふつーです。特に何か特別なことはなく。

まぁでも自信過剰でしたね…
以外とお客様から見たかゆいとこには届かず結構弾かれました（笑）

これはできるのに…これが足りない…
みたいなことが多すぎました。

#てなわけで「これ」やっとけばよかったなぁ！！ってやつ紹介します。

- CI/CDの構築
- インフラの構築

総じて「アジャイルに特化したインフラの構築」ですね

これ需要ありです。
macOSにHomebrewを導入する

## 前書き
大学の生協で買ったMacBook AirでFortranを動かしてみたいと思ったので、gfortranを導入したが、その前段階としてHomebrewが必要だったので、ここではその導入方法を述べる。
gfortranの導入については、分けて紹介する。

近日追加URL

なお、筆者のノートパソコンは

- Macbook Air
- Apple M1
- Sonoma 14.1.2（23B92）

## Homebrew導入

作業はMacのターミナル上で行う。
筆者はこれまでMacのターミナルに触れたことがなかったので、まずcommand line toolsをインストールする。
command line toolsとは、コマンド操作を行うためのツールのキットである。

Macのターミナルを開き、以下のコマンドを実行する。

```zsh:zsh
xcode-select --install
```

実行が完了したら、次にHomebrewをインストールする。

https://brew.sh/ja

Homebrewはパッケージ管理システムの一つである。

インストールのために以下のコマンドを実行する。

```zsh:zsh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

パスワードを要求されると思いますが、要求通り進んでいこう。

処理が済んだら、次はHomebrewへのパスを通す。
パスというのは「コマンドを実行するプログラムが保存されているディレクトリの場所を設定する変数」のこと。
詳しくは以下のサイトなどを参照してほしい。

https://reffect.co.jp/windows/full_understanding_mac

「パスを通してください」という指示は、実行結果の中にも以下のような形で書かれていると思う。

```zsh:zsh
==> Next steps:
- Run these two commands in your terminal to add Homebrew to your PATH:
    (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/(自分のユーザー名)/.zprofile
    eval "$(/opt/homebrew/bin/brew shellenv)"
```

現状、Homebrewへのパスが通っていない状況なので、Homebrewのコマンドを打っても実行されない。

例えばHomebrewのバージョンを確認するコマンド

```zsh:zsh
brew -v
```

を打っても、何も起きない。

そこで次は実行結果で指示された``==> Next steps:``に従い、コマンドを順に打ってみる。

```zsh:zsh
 (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') 
eval "$(/opt/homebrew/bin/brew shellenv)"
```

これによってHomebrewへのパスが通る。
この状態で、先ほどのHomebrewのバージョンを確認するコマンドを実行すると、結果が表示されると思う。
結果が表示されれば、それでOK。

## パスの永続化

上記のままだと、ターミナルを閉じた際にHomebrewへのパスが失われてしまう。
そこで、パスを設定して新規ウィンドゥを開いてもすぐにbrewコマンドが使えるようにしよう（パスの永続化: この呼び方は合っていないと思う）。

ここでは以下のサイトを参考にしている。

https://chicog.me/posts/sr4qml2wg

パスへの情報は``.zshrc``というファイル内で管理されているため、そのファイルをいじってあげる。
（筆者の使用しているシェルはzshですが、他のシェルを使っている場合、適宜調べるなどしてほしい）

```zsh:zsh
vi ~/.zshrc
```

ここで``vi``とはテキストエディタであり、簡単に言えばファイルの内容を書き換えたりするコマンドである。
できるのなら``vi``以外でも構わない。
``vi``は使い方が初心者には独特なので、検索して扱い方を学んでほしい。

以上を実行すると、``.zshrc``が開くため、``export PATH=/opt/homebrew/bin:$PATH``と打ち込んで編集を終了する。

その後、以下のコマンドを実行することにより、Homebrewmへのパスが永続化する。

```zsh:zsh
source ~/.zshrc
```

以上によりHomebrewを導入することができた。

近日追加URL

## 参考

https://chicog.me/posts/sr4qml2wg

https://qiita.com/ishidao/items/769b2e9acfc2ce4542b6

https://qiita.com/s79ns/items/7a564151d9ff18f960cf
日本語プログラミング言語をモデリング言語としてシステム開発上中流工程に導入（ユビキタス言語）

# はじめに

日本語プログラミング言語をモデリング言語としてシステム開発上中流工程に導入した場合、そのメリット・デメリットについて考察する記事の5回目です。

本記事の内容はいくつかに分割されて記載されます。本記事中の「本記事」とは分割された内容の総体を指す場合があります。

https://qiita.com/advent-calendar/2023/remind

この記事は日本語構造化仕様記述言語 Re:Mind（リマインド）アドベントカレンダー2023の15日向けの記事です。

## 対象読者
とりあえずこの記事の想定読者はシステムエンジニアさんです。とくに日本語で要求仕様や内部設計資料を書いている方向けのお話です。

# 想定しているシステム開発フロー
オーソドックスなリレーショナルデータベースを使用している業務システムであることを[1回目](https://qiita.com/mylifewithviolin/items/b7cc85911507cf1a2a55)[2回目](https://qiita.com/mylifewithviolin/items/4ce62e0d5473626347e1)の記事で説明しております。

## 想定しているレイヤードアーキテクチャ・業務
一般的なWebアプリケーションシステムであり、簡単な受発注業務をインターネットで支援するシステムであることを[3回目](https://qiita.com/mylifewithviolin/items/d10d59e98c4d2d7dca3d)[4回目](https://qiita.com/mylifewithviolin/items/68dbf00cebb1bc8f6209)の記事で説明しております。

# 想定しているユビキタス言語
今回の記事では、その業務システムで使われるユビキタス言語を簡単に例示しておきます。ユビキタス言語とは、本来的な意味ではあらゆる場所にあるコンピュータやネットワークが、人間の自然な言葉で操作できるようになることを指しますが、ここではドメイン駆動設計（DDD）の文脈で用いられる、業務の専門家とシステム開発チームとの共通用語定義の意味で用います。

どちらの意味でも日本語プログラミング言語を知るものにとっては興味深い定義ですが、DDDの世界ではあくまで自然言語の意味だけで認識されることが一般的のようです。


| 単語 | 定義 |補足・別名など|
|:-------:|:-------|:--------|
| 商品|価格がつき売り買いの対象となるもの|価格：貨幣価値|
| 商取引|商品の所有権の移転|対価として貨幣が交換される|
| 発注者|商取引上の商品の買い手|買う：商品を所有し貨幣を引き渡す|
| 受注者|商取引上の商品の売り手|売る：商品を引き渡し貨幣を受け取る|
| 注文|商取引の買い手の意思表示またはその証拠||
| 発注|商取引の買い手の意思表示||
| 受注|商取引の売り手の合意表示||
| 注文番号|数字などからなる注文の識別情報||
| 注文日|発注者が注文を行った日||
| 受注日|受注者が注文を承けた日||
| 商品コード|商品の数字などからなる識別情報|発注者と受注者で異なるコードをふる場合がある|
| 商品名|商品の識別情報で自由文字列|受注者が命名する場合が多いがオーダーメード品などは発注者による命名の場合もある|
| 単価|商品の販売単位通常１つあたりの価格||
| 注文数量|特定の注文における商品の数量||
| 注文金額|注文数量×単価|数量や単価に小数点以下の値を含む場合は端数処理の取り決めが必要|
| 希望納期|発注者が受注者に要求する商品の引き渡し期限|納期交渉が生じる場合がある|
| 注文書|注文の証拠情報　紙の書面または電子データ ||

# この回のまとめ
ざっくり上流工程の対象業務のユビキタス言語について説明しました。受発注をめぐる電子商取引については、法規制上の問題などさまざまな要件がからんでまいりますが、この記事ではざっくり割愛するとしています。

# 次回
各工程の詳細について引き続き検討していきます。
Gemini APIの使い方

![DALL·E 2023-12-30 12.46.35 - Create a sophisticated and stylish horizontal banner with the word 'Gemini' in the center. The background should be a blend of abstract digital art an~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/3a838364-0fb0-7dba-a9ed-d0c2cc9fc3ba.png)

## はじめに
2023年12月14日、Googleは生成AIモデルであるGeminiのAPI利用を開始しました。このAPIを活用することで、テキスト生成や画像解釈のタスクを自動化し、さまざまなアプリケーションでAIの力を活かすことができます。この記事を通して、Gemini APIの使い方について紹介し、新しい創造的なプロジェクトやアイデアの実現に向けて一歩踏み出すお手伝いができればと思います。
## ステップ1: Geminiの準備
まず、Geminiを使えるように準備します。以下のコードで必要なパッケージのインストール、設定、お義を行います。
```
!pip install -q -U google-generativeai
```
```
import pathlib
import textwrap
import google.generativeai as genai
from google.colab import userdata
from IPython.display import display
from IPython.display import Markdown

def to_markdown(text):
  text = text.replace('•', '  *')
  return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))
  ```
次にAPIキーの設定を行います。
![スクリーンショット 2023-12-15 180013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/c575a82a-21b0-889f-9356-fbfb17797127.png)
Google AI Studio(https://ai.google.dev/?hl=ja)
からAPIキーを取得し以下のように貼り付けます。
your_api_key の部分をご自身のAPIキーに置き換えてください。

```
genai.configure(api_key="your_api_key")
```

## ステップ2: テキストの生成
次に、Geminiを使ってテキストを生成するステップを行います。以下のコードは、Geminiのテキスト生成モデルを用意し、指定したテキストに対する応答を生成する例です。
```
# モデルを準備
model = genai.GenerativeModel('gemini-pro')
```
```
response = model.generate_content("あなたはGemini？あなたにできることを5つ教えて？")
to_markdown(response.text)
```
上記のコードを実行すると、Geminiが指定したテキストに対して生成した応答がMarkdown形式で表示されます。
### 出力 ###
![スクリーンショット 2023-12-16 000441.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/43b70be3-c91c-b8bb-f876-e9e1d6aa91dc.png)

## ステップ3: Visionの使用
Geminiを使って画像解釈を行うステップを実行します。以下のコードは、GeminiのVisionモデルを用意し、指定した画像から情報を抽出する例です。
```
# モデルを準備
model = genai.GenerativeModel('gemini-pro-vision')
```
今回は例として、適当に作成した売り上げ推移グラフをインポートして、グラフの概要を抽出してみます。
```
import PIL.Image
#インポートした画像を読み込み
img = PIL.Image.open('/content/画像のパス')
img
```
![スクリーンショット 2023-12-15 233746.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/fa96accc-2d27-70ac-6a0d-1449773aa9cf.png)

```
response = model.generate_content([
    "このグラフからサマリーを抽出して", 
    img
], stream=True)
response.resolve()
to_markdown(response.text)
```
### 出力 ###
![スクリーンショット 2023-12-16 000456.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/0716c48e-76c7-a9d2-abc3-e2a751b86c61.png)

## 最後に
この記事を通じて、Geminiの準備、テキストの生成、Visionの使用についての基本的な手順を紹介しました。Geminiは強力なツールであり、さまざまな応用が可能です。ぜひこの記事を参考にして、Geminiを活用してテキスト生成と画像解釈を実践してみてください。
WSL上のデータをWindows領域に自動的にバックアップする

WSL Ubuntuのデータを定期的にWindows領域にバックアップする設定方法について記します。

# 背景
* WSLの破損に備え、WSL上のデータをWindows領域に定期的にバックアップしておきたい。
* PC自体の破損にも備えるため、バックアップ先をGoogleドライブの同期対象フォルダ内に指定することでクラウドにもバックアップを取りたい。

# 環境
* Windows 10
* WSL2 (Ubuntu 22.04.3 LTS)

# 同期を実行するシェルスクリプトの作成
以下のようなシェルスクリプトにより、WSL領域のディレクトリをWindows領域に同期することができます。
```bash:sync.sh
#!/bin/bash

# WSLのバックアップ対象のディレクトリ
WSL_BACKUP_DIR="/home"

# Windows側のバックアップ先ディレクトリ
WINDOWS_BACKUP_DIR="/mnt/c/Users/user_name/path_to_backup_dir"

# rsyncコマンドを使って同期する
rsync -av --delete --exclude="/home/user_name/.vscode-server" $WSL_BACKUP_DIR $WINDOWS_BACKUP_DIR
```
:::note
* 同期の対象外とするファイル/ディレクトリは`--exclude`により指定できます。
* Windows側のバックアップ先ディレクトリをGoogleドライブなどのウォッチフォルダ内に指定することで、クラウド上にもバックアップを作成できます。
:::

上記のシェルスクリプトを実行すると、バックアップが実行されます。
```bash:
$ bash sync.sh
```

# 定期的なバックアップの実行設定
作成したシェルスクリプトを定期的に自動で実行するように設定します。ここでは、`cron`による設定方法を説明します。

### crontabの設定
`crontab`を開きます。
```bash:
$ crontab -e
```

定期実行する内容を`crontab`に記載します。以下は、毎時0分に`sync.sh`を実行する場合の例です。
```bash:crontab
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

0 * * * * /home/user_name/sh/sync.sh
```
以下のコマンドにより、crontabの変更内容が反映されていることを確認します。
```bash:
$ crontab -l
```
:::note
* `0 * * * *`の部分は、毎時0分に実行するようコマンドの実行タイミングを指定しています。左から順に`分 時 日 月 曜日`を指定しており、例えば`* * * * *`とした場合には毎分実行されます。
:::

### cronの設定など
シェルスクリプトに実行権限を与えます。
```bash:
$ chmod +x /home/user_name/sh/sync.sh
```

cronが実行されていることを確認します。
```bash:
$ service cron status
```
`* cron is running`と表示されればOKです。cronが起動しておらず`cron is not running`と表示される場合、以下により起動します。
```bash:
$ sudo service cron start
```

`crontab`の変更内容を反映するため、`cron`を再起動します。
```bash:
$ sudo service cron restart
```

これで`sync.sh`の自動定期実行が設定できました。
仕事や人生に焦り始めたら自分の歯車を整えなくてはいけないという話


息抜き、リフレッシュとは少し違う私が日々体感している感覚を今回はアドカレ代筆ということで書いてみたいと思います。

何かが原因であなたが今焦っているとします。
不安とか、悲しみとかでフワフワしている状態です。
鬱といえばそうなんだけれども、やっぱり焦っているくらいが近いような状態。
いきなり今までやっていなかった言語の本を買ってみたり、英語を始めてみたり、とにかく何かを始めなきゃと思ってしまい、だけど焦って何も頭に入ってこない時とかもかな。

今回はそういう時に自分の歯車を整える方法を知っておくといいですよという話をしましょう。

私の場合は
- 自分の性格を改めて振り返る
- 焦っていることを自覚する
- 前の2つをやった後に何か落ち着くためのルーチンワークをする
（無駄に近いことのほうがいい）

こんなことをしてます。

私の性格：悪いことばかりを気にしすぎる。お気持ちドリブン。

ちなみにこれを書いた日はマリオRPGとボトルマンとポケカを短期間で全部買っちゃうなんて・・・娘に使えばいいのに、と落ち込みました。

これを取り返そうと、ｿﾜｿﾜｿﾜｿﾜしてました。
何か手持ちのものを売って補填すればいいんじゃないか、何かもらえるお金はなかったかなとか考えているうちに非常に無駄な焦燥感にのまれました。

この焦っている状態をまず自覚する。
自覚したらまずはその気持ちに対して何も行動を起こさないようにする。
アニメを見たり、ゲームをして、何か代わりのもので埋めようとしない。
感情を上書きしようとすると非常につらいのです。
自分は焦っていて居心地が悪いということをただひたすらに受け入れる。
これが大事。

少し落ち着いてきたら、あの本の差し絵はきれいだなとか、そういえばあそこの風景は素敵だったなとか、お金のかからないもので心を満たしていく。
今日はヤドランの絵でした。昔のヤドランっぽい絵ですごく可愛かった。

最後にルーチンワークをします。

私の場合は字を書くことが多いです。
ひらがなをきれいにひたすら書いたり、名前の練習をしたり。

今日は牛尾剛さんの世界一流エンジニアの思考法に影響を受けたので、基礎を大事にという意味で守破離に1文字、道を足して書いてみました。

はい。
盛大にポエムなのですが、息抜きやリフレッシュによる感情の上書きとは違う、自分の整え方の一例の紹介でした。

埋まっていないアドカレを見つけ次第、次は読書感想文で埋めていきたいと思います。
みんながんばろ～！