OmniAICreator/Qiita-1.07M huggingface dataset:
pythonでクロージャを書いてみた

## 概要

決まりきった正規表現は何回もコンパイルする必要がないので、メモ化したいが、グローバル変数は使いたくないので、初めてクロージャを使って実装してみた
まだまだpython初心者なので、あんまりpythonらしいコードが書けてるかは自信がない

## 実装

```python
import re
from typing import Callable, Pattern


def create_email_regexp_generate_func() -> Callable[[], Pattern]:
    reg = None

    def _email_regexp() -> Pattern:
        # regへの参照を可能にする
        nonlocal reg
        if reg is None:
            reg = re.compile(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)")
        return reg

    return _email_regexp
```
これで、初回呼び出し時のみコンパイル処理が走り、以後はreg変数に保持された正規表現オブジェクトを参照するようにできた

```python
generate_email_regexp = create_email_regexp_generate_func()
generate_email_regexp()
generate_email_regexp()
generate_email_regexp()
```

## 参考文献
https://tech.firenium.com/rfc5322_regular_each_language/#Python
JavaScriptで時間を表示する(初学者向け)

##はじめに

javascriptで時間を表示するプログラムの作り方です。

##時間を取得するメソッド
まず、今回使用するメソッドを確認しましょう。

|項目|メソッド名|
|---|-------|
|時|getHours( )|
|分|getMinutes( )|
|秒|getSeconds( )|

↑の3種類のメソッドを変数の中に入れ込んで時間を取得していきます。

次にHTMLはこのようになっています↓

```qiita:HTML

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script src="time.js"></script>
</body>

</html>

```

JavaScriptはこのようになっています↓

```qiita:javascript

// 現在の時間を表示

//----------------------------------------------------------------------------
//Dateインスタンスを作成すると、現在の時刻を示すDateオブジェクトのインスタンスが作成されます↓
//----------------------------------------------------------------------------
const now = new Date();


const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();

document.write(hours + ':' + minutes + ':' + seconds);


```
それでは解説していきます。

まず、変数名**now**の中に**new Date( )**を代入します。

次に変数名**hours**を作って**now.getHours();**を代入します。
変数名**minutes**には**now.getMinutes();**を代入し、
変数名**seconds**には**now.getSeconds();**を代入します。

最後にdocument.write(hours + ':' + minutes + ':' + seconds);の部分は、
「ドキュメントの中に(時:分:秒)を書き出してくださいね」という指示をしているということです。

そして、このように時間が表示されていて、ブラウザを読み込むたびに変化します↓

--------------------------------

![スクリーンショット 2021-12-30 16.37.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1784356/aaab8008-04d7-d317-5b00-f70849e16a68.png)

-------------------------------

##おわり

ご覧いただきありがとうございました。

また他の記事でお会いしましょう〜👋
ちょっとだけWebGLを触ってみた結果。

# あらすじ

知人から<font color="Tomato">「WebGL詳しい？」</font>と声をかけられました。初耳でした。せっかくなので少し触ってみることに。

# 軽く調べて分かったこと

* WebGLの GL は「Graphics Library」の略
    * OpenGLとかの GL と同じ
* WebGLはJavaScriptのAPI
    * つまりWebブラウザ上でのコンピュータグラフィックス（CG）表示に用いられる
* JavaScriptということは下記２つがあれば試しに書いて動かして遊べる
    * テキストエディタ（自分はVSCodeを使用）
    * ブラウザ（自分はGoogleChromeを使用）

# 入門サイトを探してさっそく触ってみた

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

上記サイトを発見し、チュートリアルのページを見てみると<font color="Tomato">真っ黒な背景にカラフルな正方形を描画するサンプル</font>が載っていたのでさっそくトライ。所要時間2～3時間程度で作ることができました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600213/ca53805c-acca-32ac-2f8f-a5d9b4c7638b.png" border="3" width=50%>
さらに背景色や正方形の色・サイズを自由に変えることもできました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600213/b3fb38df-ba78-a625-491d-2d007f34a602.png" border="3" width=50%>
ところがこのチュートリアルページ、元英語を日本語訳した独特の言い回しが解釈しにくかったり、文章の一部が未翻訳（英語のまま）だったり、説明文中のコードにところどころミス（バグ）があったり、説明不足だったり、、、いろいろ厄介でした。
正解のソースコードがまるごとGitHubに置いてあったのでそれをお手本にしてなんとかした感じです。
まだ正直なところサンプルコードが何をしているのか完全には理解できていません。
ちなみにチュートリアルをさらに進めていけば<font color="Tomato">正方形をぐるぐる動かす（アニメーション）</font>こともできるみたいですが、、、いったん今日はここまでにします。

# さらに調べて分かったこと

* 基礎用語いろいろ
    * canvas　⇒グラフィック表示に使うHTMLタグ
    * レンダリング　⇒数値データをもとに画面描画すること
    * シェーダー　⇒色とか陰影とか形とかの処理を行うプログラムのこと
        * バーテックスシェーダー　⇒立体の各頂点に対して実行される
        * フラグメントシェーダー　⇒表示する各ピクセルに対して実行される
* GLSL　⇒WebGLを使う際に書く特別な記法
    * 参考記事　https://qiita.com/yosuheeeee/items/775e3d9fd54246b60913
    * 参考記事　https://qiita.com/alicial/items/71a800305e11fc9ed46d
* GLSL editor　⇒GLSLを気軽に体験できるツール
    * 参考記事　https://qiita.com/doxas/items/b8221e92a2bfdc6fc211
* three.js　⇒WebGLを簡単に使うためのライブラリ
    * 参考記事　https://qiita.com/shu1512b/items/200cb991c328be78576d

自分はcanvasタグすら知らなかったので勉強になりました。
WebGLはテクニック次第でいろいろできそうですね。今日はちょっと触っただけですが、機会があればもっと深入りしてみたい気も。

<font color="Tomato">「WebGL詳しい？」</font>と訊いてきた知人氏、WebGLを知るきっかけをありがとうございました！

以上でーす。
WebArena Indigo 環境設定5）プロセス最大値の変更

WebArena Indigo 環境設定4）時間設定の変更
https://qiita.com/naga_kt/items/194dfcd70f72d977187d
の続き。

## プロセス最大値の変更(CentOS7のみ)

　ulimitコマンドで実行可能なユーザープロセスの最大数を確認したところ、デフォルト設定では3790だった。それを「-S」オプションで4096に増やそうとしたが、エラーメッセージが出てできなかった。
　これはOSの問題というよりもvpsのスペックの問題だったかもしれない。

~~~linux
$ulimit -u
3790
$ulimit -Su 4096
-bash: ulimit: max user processes: cannot modify limit: Invalid argument
~~~

 スーパーユーザになって/etc/security/limits.confを編集した。

~~~linux
$su
Password:
#cd /etc/security/
#ls -lrt
total 52
-rw-r--r--. 1 root root 1718 Dec  7  2011 pwquality.conf
-rw-r--r--. 1 root root   82 Apr 11  2018 chroot.conf
-rw-r--r--. 1 root root 4564 Apr 11  2018 access.conf
-rw-r--r--. 1 root root 2972 Apr 11  2018 pam_env.conf
drwxr-xr-x. 2 root root    6 Apr 11  2018 console.perms.d
-rw-r--r--. 1 root root  939 Apr 11  2018 console.perms
-rw-r--r--. 1 root root  604 Apr 11  2018 console.handlers
drwxr-xr-x. 2 root root    6 Apr 11  2018 console.apps
-rw-r--r--. 1 root root 3635 Apr 11  2018 group.conf
-rwxr-xr-x. 1 root root 1019 Apr 11  2018 namespace.init
drwxr-xr-x. 2 root root    6 Apr 11  2018 namespace.d
-rw-r--r--. 1 root root 1440 Apr 11  2018 namespace.conf
-rw-r--r--. 1 root root  419 Apr 11  2018 sepermit.conf
-rw-r--r--. 1 root root 2179 Apr 11  2018 time.conf
-rw-------. 1 root root    0 Apr 11  2018 opasswd
drwxr-xr-x. 2 root root   27 Oct  6  2018 limits.d
-rw-r--r--. 1 root root 2558 Dec 17 15:26 limits.conf
#cp -p limits.conf limits.conf-org
#vi limits.conf
~~~

編集前

~~~linux
*               hard    nofile          4096
*               soft    nofile          4096
*               soft    nproc           4096
~~~

編集後

~~~linux
*               hard    nofile          4096
*               soft    nofile          4096
*               hard    nproc           4096
*               soft    nproc           4096
~~~

　この後でセッションを終わらせて、再度ログインすると以下のようにプロセス最大値が変更されていた。

~~~linux
$ulimit -u
4096
~~~


---

WebArena Indigo 環境設定6）/tmpフォルダのファイルの削除処理の変更
https://qiita.com/naga_kt/items/c18089ebecb6e26374f4
に続く。



---

### 参考記事

【 ulimit 】コマンド――ユーザーが使用できるリソースを制限する
https://atmarkit.itmedia.co.jp/ait/articles/1908/01/news031.html

プロセスのリソース制限
http://cos7.it-mem.info/2019/01/10/%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%AE%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E5%88%B6%E9%99%90/
JQueryでガラケー向けにグラフを出す方法

結構古いサイトに対する追加改修で、リアルタイムで変動するデータを折線グラフ化して見せたいという要望がありました

とりあえずJQueryのライブラリflotを使って実現
https://www.flotcharts.org/


ただし、一部ユーザがガラケーで、そのユーザ向けにどうしても対応したいとの相談。
今更ガラケー対応ですか？と思いつつ、お金をいただけるのであれば調べましょう


まずガラケーなのでJQueryはまともに動かない

なのでグラフを画像化して表示すればよさそうなことはすぐに思いついたが、個人ごとにグラフデータが異なる仕様。しかも結構リアルタイムなグラフ情報が欲しいのです。

調べた挙句PhantomJSのスクリーンショット機能を使ってグラフをＰＮＧ画像にすることで対応した

PhantomJSというのはJSで動くスクリプトブラウザです。
http://phantomjs.org/


このブラウザ経由させるとアクセスしたページを画像に変換できるので、flotで描画されたグラフをＰＮＧ画像にしてやることで解決

つまりどうゆうことかと言うと、

１・ガラケーがPHPページにアクセス
２・PHPがサーバ内部でPhantomJSをキック
３・PhantomJSがflotのグラフページにアクセス
４・グラフ画像生成
５・ガラケー向けのＨＴＭＬレスポンスに生成グラフ画像のイメージタグを記載


但し画質は悪く、一部ＡＵの端末でPNGが使えなかったので、GIF画像でも描画することにしたが、GIFはさらに画質が悪いというスパイラルに。

お客様と相談した結果、折線グラフを超シンプルにすることで対応

こんな感じ（本物は貼れないのでイメージ図です）
![スクリーンショット 2021-12-30 16.50.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342329/0f2ba3a3-680c-a0e2-ba02-882e2ca8c91a.png)
NCBIからゲノムをrsyncでダウンロードする

#NCBIサーバーにあるゲノムのダウンロード  
##ダウンロードしたい生物種のアドレスを確認
[アドレスはここで検索](https://ftp.ncbi.nlm.nih.gov/genomes/genbank)
例えば大西洋クロマグロ(*Thunnus thynnus*)であれば、上のリンクからvertebrate_otherのディレクトリに進み、Thunnus thynnusをクリックする。そこからダウンロードしたい適当なファイルを見つけて  

```console
rsync --copy-links --recursive --times --verbose rsync://ftp.ncbi.nlm.nih.gov/genomes/genbank/vertebrate_other/Thunnus_thynnus/representative/GCA_003231725.1_GBYP_Tthy_1.0/GCA_003231725.1_GBYP_Tthy_1.0_genomic.gbff.gz ./
```  
と入力。最後の ./ はダウンロードファイルを配置する任意のディレクトリを指定する。
ファイルを解凍する場合は

```console
gunzip hogehoge.gbff.gz
```
【MATLAB】重複を許し​て並べるパターンをすべて列挙する

# やりたいこと
例えば、1,2,3 のうちから重複を許して3つ選び、その並べ方をすべて列挙したい、というケースです。この場合、$3^3=27$通りあります。

# 方法
MATLABのndgrid関数を使います。

# 1~3の整数から3つ選んで並べる

```matlab
[x1,x2,x3] = ndgrid(1:3,1:3,1:3);
[x3(:),x2(:),x1(:)]
```

## 出力結果
```matlab
ans =

     1     1     1
     1     1     2
     1     1     3
     1     2     1
     1     2     2
     1     2     3
     1     3     1
     1     3     2
     1     3     3
     2     1     1
     2     1     2
     2     1     3
     2     2     1
     2     2     2
     2     2     3
     2     3     1
     2     3     2
     2     3     3
     3     1     1
     3     1     2
     3     1     3
     3     2     1
     3     2     2
     3     2     3
     3     3     1
     3     3     2
     3     3     3
```

# A,B,Cで作られる4文字の単語
応用すれば、辞書順も作れます。

```matlab
[x1,x2,x3,x4] = ndgrid('ABC','ABC','ABC','ABC');
[x4(:),x3(:),x2(:),x1(:)]
```

## 出力結果
```matlab
ans =

  81×4 の char 配列

    'AAAA'
    'AAAB'
    'AAAC'
    'AABA'
    'AABB'
    'AABC'
    'AACA'
    'AACB'
    'AACC'
    'ABAA'
    'ABAB'
    'ABAC'
    'ABBA'
    'ABBB'
    'ABBC'
    'ABCA'
    'ABCB'
    'ABCC'
    'ACAA'
    'ACAB'
    'ACAC'
    'ACBA'
    'ACBB'
    'ACBC'
    'ACCA'
    'ACCB'
    'ACCC'
    'BAAA'
    ...
    'CCCC'
```

# 参考サイト
[選択肢から重複を許し​て並べる順列のパター​ンを列挙した行列を作​る方法(MATLAB Answers)](https://jp.mathworks.com/matlabcentral/answers/524396-)
【Rails】セレクトボックスを作る方法と注意点【select・collection_select】

Railsのセレクトボックスって、
引数の順番とか指定できる項目の種類が
ごちゃごちゃしてて、なんとなーくの理解だったので、
色々調べてみました！

なお、間違いやもっと良い方法がある...等ありましたら、
お気軽にコメントください。お願いいたします！

# 作成方法①：select メソッド

select メソッドを使ったセレクトボックスの構文は下記です。

```
select(オブジェクト名, オプションタグの要素(配列 or ハッシュ), オプション, HTMLオプション)
```

まず、コントローラーでselect に渡す要素を準備する必要があります。どのような方法でも良いですが、例として下記のような取得方法があるでしょう。

```app/controllers/user_controller.rb
@users = User.pluck(:name, :id)
# => [["A太郎", 1], ["B太郎", 2], ["C太郎", 3]]

@users = User.all.map { |user| [ user.name, user.id ] }
# => [["A太郎", 1], ["B太郎", 2], ["C太郎", 3]]
```

ビュー側は以下のように書きます。

```app/views/user/index.html.erb
<%= f.select :id, @users, {prompt: "選択してください"}, :class => 'form-control', :id => 'user_id' %>
```

## select に指定できるオプション
オプションについては、[Rails ドキュメント](https://railsdoc.com/page/select)
をご覧ください。

複数選択や選択を無効化するなどの詳細な設定ができますよ！

# 作成方法②：collection_select メソッド【おすすめ】

collection_select メソッドを使ったセレクトボックスの構文は下記です。

```
collection_select(オブジェクト名, メソッド名, 要素の配列, value属性の項目, テキストの項目, オプション, HTMLオプション, イベント属性)
```

select メソッドの際は、DBから取得したデータを select 用に加工する必要がありましたよね。
もしくは、ビュー内でDBから直接データを取得するような指定をする必要があり、
MVCの分離ができていなかったですよね。

しかし「collection_select」メソッドは加工することなく、セレクトボックスを簡単に作成できます！

```app/views/user/index.html.erb
<%= f.collection_select :id, User.all, :id, :name, {prompt: "選択してください"}, :class => 'form-control', :id => 'user_id' %>
```

まあ、「User.all」だってDBから直接取得してるじゃないか！！
と突っ込まれたら、何も言えないのですが...。

それにしても、簡単に記述できるので、個人的にはこちらの方が使いやすいかなーといった感じです。

## collection_select に指定できるオプション
オプションについては、[Rails ドキュメント](https://railsdoc.com/page/collection_select)
をご覧ください。

js用のオプションを指定できるのも便利ですよね。
具体的には「onclick」イベントなどですね。

# オプション指定の順番は注意！

さらには、オプションの指定には注意点もあります。HTMLオプションを指定する際には、先にオプションを必ず指定しなければ、うまく動きません（引数の順番が１つずれちゃうので、当たり前と言えば当たり前なのかもですが）

```app/views/user/index.html.erb
# これはOK
<%= f.collection_select :id, User.all, :id, :name, {prompt: "選択してください"}, :class => 'form-control', :id => 'user_id' %>

# これもOK
<%= f.collection_select :id, User.all, :id, :name, {}, :class => 'form-control', :id => 'user_id' %>

# これはNG
<%= f.collection_select :id, User.all, :id, :name, :class => 'form-control', :id => 'user_id' %>
```

# 参考
[【Rails】セレクトボックスを作る方法と注意点【f.select】](https://takeda-no-nao.net/programming/ruby/how-to-create-select-box/)
Amplifyコンソールでアプリが消せない場合の対処

AmplifyのアプリをAWSのAmplifyコンソール上から消そうとしたら、消せなくなりました。

![スクリーンショット 2021-12-30 16.00.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342329/2cc12b93-edc6-4e2a-357c-a47c8b325989.png)


当初の失敗理由は、多分、Amplifyでアップした設定をAWSコンソールで手動で変えてしまい、権限が壊れた系のアラートだったと思います。

手元に記録がないのでアップできないですが、とりあえずCloudFormationを使って、地道に削除。

CloudFormation上でもう何もないはずなので、消せるかなと思ったら以下のエラー

![スクリーンショット 2021-12-30 16.07.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342329/9187807c-689d-7265-fd33-43d9cbbc6c22.png)


どうも対応するスタックが無いとかいうエラーっぽい。すでに消しましたから当然です

どうしたらいいかGoogle先生に相談
何個か同じような回答がありましたが、一番上の人のリンクを貼ります

https://blog.serverworks.co.jp/amplify-fail-to-remove-app

aws amplify delete-backend-environment --app-id <アプリID> --environment-name dev --profile=私のプロファイル


これで削除成功！
Ryzen自作PCを組み立た　Ryzen5600X、RadeonRX6600

# 自作PCをしようと思った理由
マイニングや自作PCでのPCゲームが流行っているので、２０年ぶりぐらいに自作PCをしてみました。
組んでみての感想は、ハードの組み合わせがよくわからずいろいろと雑誌を読んで組み合わせを考えた。
CPUはスペックが高いのでもう少し下げて値段を抑えることができるのではないかと思ったが、
パフォーマンスは満足している。いろいろと実験してみようと思う。

# 使用パーツ

| No | カテゴリ | 商品名 | 金額 | 購入場所       |
|---:|:------------|:------------|------------:|:-----------------|
| 1 |グラフィックボード|[ASRock RX6600 Challenger D 8G](https://kakaku.com/item/K0001391662/) | 63,250 | ジョウシン |
| 2 |ケース| [CoolerMaster MasterBox Q300L/ MicroATX対応](https://amzn.to/2ZZinhI) | 4,852 | ツクモ |
| 3 |CPU| [Ryzen 5 5600X](https://amzn.to/31m68fT)　CPUとマザボのセット   | 53,300 | ツクモ |
| 4 |マザーボード| [MSI MAG B550M MORTAR WIFI](https://amzn.to/3xTVuc5)  | - | ツクモ |
| 5 |電源| [玄人志向 850W電源 KRPW-GA850W/90+](https://amzn.to/3xUr9Kr) | 10,300 | ツクモ |
| 6 |SSD| [SAMSUNG 980　MZ-V8V1T0B/IT M.2 NVMe / 1TB / PCIe Gen3x4](https://amzn.to/3Ety3Zp)  | 10,980 | ツクモ |
| 7 |メモリ| [CORSAIR CMK32GX4M2E3200C16 / 32GB(16GB×2) / DDR4-3200](https://amzn.to/3lyvvSA)  | 17,563 | ツクモ |
| 8 |クーラー| [虎徹](https://amzn.to/3FRJMS8)  | 3,620 | ヨドバシ |
|   || 合計        | 163,865|  |


# パフォーマンス

## タスクマネージャー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/ce3dbd2d-4992-a392-160b-ea4127680c71.png)

## Blackmagic Disk Speed Test 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/9b21bf7e-4cfc-8793-1083-755b8ff8c76e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/a9b80ff4-d6f0-4d1f-7987-452b6f3f2c93.png)

## CINEBENCH
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/c2bd613d-80b3-f1db-b9cb-410a71ccfcbd.png)

## CrystalDiskMark
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/1674f0dd-5640-216b-f799-5cb9917f833d.png)
Jenkins から Cypress を実行する

# やりたいこと
- Jenkins でビルド・デプロイ後に Cypress で E2E テストを実施したい
    - ビルド・デプロイジョブの後に呼び出せる E2E テスト実行ジョブを作りたい
    - E2E テストは github で管理したい

開発環境をいじるのが嫌だったので、ローカルでいろいろお試し。

# 環境
- WSL2
- Ubuntu 20.04

# 前提
- github 上に Cypress E2E プロジェクトを用意している

# Jenkins の設定
Docker で Jenkins を起動するための `Dockerfile` と `docker-compose.yaml`

``` Dockerfile
FROM jenkins/jenkins:latest

USER root

RUN apt-get update \
  && apt-get install -y \
  nodejs  \ # Cypress 実行のために必要なパッケージ↓
  npm \
  libgtk2.0-0 \
  libgtk-3-0 \
  libgbm-dev \
  libnotify-dev \
  libgconf-2-4 \
  libnss3 \
  libxss1 \
  libasound2 \
  libxtst6 \
  xauth \
  xvfb

USER jenkins

```

``` docker-compose.yaml
version: "3"

services:
  jenkins:
    container_name: jenkins
    build: .
    ports:
      - 8080:8080
    volumes:
      - ./jenkins_home:/var/jenkins_home
    environment:
      - NO_COLOR=1 # Cypress の実行結果が文字化けするため
      - JAVA_OPTS=-Duser.timezone=Asia/Tokyo -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8
```

## 初回起動
1. `docker-compose up` で起動
1. Docker 上で Jenkins の起動が完了したら `http://localhost:8080` にアクセス
1. 初回起動時は Administrator password の入力が必要
    1. 初期パスワードは `/var/jenkins_home/secrets/initialAdminPassword` に記載されている
1. そのまま初期設定完了まで進む

## github 認証
1. Jenkins の管理 ⇒ Manage Credentials ⇒ Jenkins ⇒ グローバルドメイン
1. `Add Credentials`
1. github の認証情報を追加する
    1. ユーザー名：github アカウント
    1. パスワード：github の Access Token
    1. ID：github（自分で分かりやすいもの）

## ジョブ作成
1. 新規ジョブ作成 ⇒ パイプライン
1. Pipeline script 作成

``` groovy
pipeline {
    agent any

    stages {
        stage('cypress test') {
            steps {
                git credentialsId: 'github', url: 'https://github.com/xxx/cypresse2e.git' // credentialsId は上で作成した github 認証の ID
                sh 'npm install cypress --save-dev'
                sh 'npx cypress run'
            }
        }
    }
}
```

## E2E テスト実行
作成したジョブの `ビルド実行`

# はまったところ
## `jenkins_home` のアクセス権限
`docker-compose up` した際に、作業ディレクトリに `jenkins_home` が作成される。何回か試していた際に、このディレクトリにアクセスできないエラーが発生した。
一回削除して、同名のディレクトリを作成したらエラーが解消。（実行ユーザーの問題？）

## Cypress 実行結果の文字化け
Jenkins の `Console Output` に Cypress の実行結果が出力される。ここが盛大に文字化けしていた。
どうやら Cypress の実行結果は ANSI で出力され、Jenkins 側が対応していない模様。（プラグインを入れれば OK？)
`NO_COLOR=1` を設定することで文字化けが解消される。
https://docs.cypress.io/guides/continuous-integration/introduction#Colors

# 参考
https://hub.docker.com/_/jenkins
https://dev.classmethod.jp/articles/jenkins-on-docker/
CI with Jenkins build pipeline for Cypress automation testing：https://www.youtube.com/watch?v=UFErY92HeyM
sortコマンドでcsvファイルを降順ソートする

例えば以下のようなcsvファイルがあったとする。
これの３行目以降を、３列目をキーにして降順ソートしたい。

```bash:test.csv
DATETIME, REPOSITORY_URL, SCORE, LEVEL, RESULT
---
2021/12/28_2:59:17, https://xxx, 58, 1, SUCCESS
2021/12/29_3:06:33, https://xxx, 54, 1, SUCCESS
2021/12/29_3:06:54, https://xxx, 0, 0, FAIL
2021/12/29_3:07:22, https://xxx, 52, 1, SUCCESS
2021/12/29_3:07:37, https://xxx, 0, 0, FAIL
2021/12/29_4:37:54, https://xxx, 53, 1, SUCCESS
```

まず、先頭２行目はソート対象ではないので、`tail -n +3`により３行目以降を対象にする。

```bash
$ FNAME="test.csv"
$ tail -n +3 ${FNAME}
2021/12/28_2:59:17, https://xxx, 58, 1, SUCCESS
2021/12/29_3:06:33, https://xxx, 54, 1, SUCCESS
2021/12/29_3:06:54, https://xxx, 0, 0, FAIL
2021/12/29_3:07:22, https://xxx, 52, 1, SUCCESS
2021/12/29_3:07:37, https://xxx, 0, 0, FAIL
2021/12/29_4:37:54, https://xxx, 53, 1, SUCCESS
```

`sort -nr -t, -k3`により、カンマ区切りでみた時の３列目を、数字扱いで降順ソートする。

```bash
$ FNAME="test.csv"
$ tail -n +3 ${FNAME} | sort -nr -t, -k3
2021/12/28_2:59:17, https://xxx, 58, 1, SUCCESS
2021/12/29_3:06:33, https://xxx, 54, 1, SUCCESS
2021/12/29_4:37:54, https://xxx, 53, 1, SUCCESS
2021/12/29_3:07:22, https://xxx, 52, 1, SUCCESS
2021/12/29_3:07:37, https://xxx, 0, 0, FAIL
2021/12/29_3:06:54, https://xxx, 0, 0, FAIL
```

その後、先頭２行目とくっつけて出力すればOK

```bash
$ FNAME="test.csv"
$ cat <(head -2 ${FNAME}) <(tail -n +3 ${FNAME} | sort -nr -t, -k3)
DATETIME, REPOSITORY_URL, SCORE, LEVEL, RESULT
---
2021/12/28_2:59:17, https://xxx, 58, 1, SUCCESS
2021/12/29_3:06:33, https://xxx, 54, 1, SUCCESS
2021/12/29_4:37:54, https://xxx, 53, 1, SUCCESS
2021/12/29_3:07:22, https://xxx, 52, 1, SUCCESS
2021/12/29_3:07:37, https://xxx, 0, 0, FAIL
2021/12/29_3:06:54, https://xxx, 0, 0, FAIL
```

`column`を使うと見易くなる

```bash
$ FNAME="test.csv"
$ cat <(head -2 ${FNAME}) <(tail -n +3 ${FNAME} | sort -nr -t, -k3 | column -t -s,)
DATETIME, REPOSITORY_URL, SCORE, LEVEL, RESULT
---
2021/12/28_2:59:17   https://xxx   58   1   SUCCESS
2021/12/29_3:06:33   https://xxx   54   1   SUCCESS
2021/12/29_4:37:54   https://xxx   53   1   SUCCESS
2021/12/29_3:07:22   https://xxx   52   1   SUCCESS
2021/12/29_3:07:37   https://xxx   0    0   FAIL
2021/12/29_3:06:54   https://xxx   0    0   FAIL
```

# 参考
[ファイルのn行目以降を表示する](https://qiita.com/sugyan/items/523ed9417678fbdbae53)
[sortコマンドでCSVファイルをソートする場合はソート列の指定方法に注意](https://genzouw.com/entry/2019/04/24/083709/1399/)
[sortコマンドとは？Linuxコマンドでファイルの中身を並び替えする方法をご紹介](https://academy.gmocloud.com/know/20210625/12063)
【Rails】ルーティングのネストについて

## ルーティングのネストとは
ルーティングのネストとは、あるコントローラへのルーティングの記述の中に、別のコントローラへのルーティングを記述すること。

例えばTwitterの場合、ツイートに対してコメントできる機能があるその場合、このアプリケーションのルーティング（routes.rb）の記述は以下のようになる。

```rb
Rails.application.routes.draw do
  resources :tweets do
    resources :comments, only: [:create]
  end
end
```

tweetsコントローラへのルーティングの記述の中に、commentsコントローラへの記述が書かれている。こうすることによって、どのツイートに紐づいたコメントなのかをURLで判別できるようにしている。

## メリット
**①URLの階層構造ができる**
先程のTwitterのルーティング記述により生成されるURLは、「/tweets/id/comments」になる。

もっと具体的に言うと、とあるツイートにコメントすると「/tweets/2/comments」のようなURLが生成される。この「2」という数字はツイートのid番号。

つまり、このコメントは2番のツイートに対するコメントということが、URLから判断することができる。

**②関係性のあるもの同士を紐づけることができる**
ツイートとコメントの関係のように、ルーティングをネストさせることによって関係性のあるもの同士をを紐づけることができる。

``関係があるもの同士は、原則ルーティングをネストさせて関係性のあるURLを生成しよう``
使用する考え方・利用法としては、特に親子関係をもつテーブルがあり、それぞれ親に紐づくデータのみを扱いたいときにネストすることが多い。

>モデルではこのような関係性を「has_many」と「belongs_to」で表現する

## 記入法

```rb
Rails.application.routes.draw do
  resources :親となるコントローラー do
    resources :子となるコントローラー      ←階層を下げ、do,,,endで囲む
  end
end
```

## 参考記事
[【Rails基礎】プログラミング初学者がつまずきやすい「ルーティングのネスト」について簡単に解説](https://techtechmedia.com/routing-nest-rails/)
[ルーティングのネスト](https://qiita.com/kouhei_matuura/items/16b77a25cf53d7ff232a)
STM32L010とI2Cを使ってI2Cスレーブから値を受信する。(STM32L010F4P6)


目的
I2Cスレーブのテスト


![o_con182.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4f510bcd-16ce-0c1c-34c1-726f006807c6.jpeg)




```c++


//I2C_EXPANDER_IN_1

#include "mbed.h"

DigitalOut TX(PB_1);
//DigitalOut TX(PC_14);

//仮想シリアルへの一文字出力 1200bps
int pc_putc(char ch)
{

    TX=1;
    TX=0;//Start
    wait_us(832);

    for(int ii=0; ii<8; ii++) { //Data x 8
        TX=(ch>>ii)&1;
        wait_us(832);
    }; //for

    TX=1;//Stop
    wait_us(832);

    return(0);

} //pc_putc


PortIn     p(PortA, 0x000000FF);   // PA0-PA7

char HEX_C[] =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' } ;

//I2Cの初期化
I2CSlave slave(PA_10, PA_9); //010

//メインルーチン
int main()
{

    TX=1; //ポートの初期化

    char buf[10];//I2Cバッファー
    char cc;

    //I2Cスレーブのアドレスの設定
    slave.address(0x80);

    //無限ループ
    while(1) {

        //I2Cの状態の読み出し(ポーリング)
        int i = slave.receive();

        //ステータスの表示 HEX
        //i = I2CSlave::ReadAddressed; //debug
        cc = i;
        pc_putc('S');
        pc_putc(HEX_C[ cc >> 4    ]);
        pc_putc(HEX_C[ cc &  0x0f ]);
        pc_putc('\r');
        pc_putc('\n');


        if (i == I2CSlave::ReadAddressed) {

            buf[0] = p.read();

            //I2Cマスターに送信する
            slave.write(buf,1);

            //I2Cスレーブの送信データの表示 HEX
            cc = buf[0];
            pc_putc(' ');
            pc_putc('D');
            pc_putc(HEX_C[ cc >> 4    ]);
            pc_putc(HEX_C[ cc &  0x0f ]);
            pc_putc('\r');
            pc_putc('\n');

        }//if

        //1秒の待ち
        wait_ms(500);

    }//while

}//main


//容量削減
void error(const char* format, ...) {}




```
「作ろう! CPU」を中華FPGAで動かすまで

# 1. 背景
 非情報系出身なのに低レイヤの知識を要する業務が多い。どこかで勉強しようということで、こちらの書籍を購入。

http://www.amazon.co.jp/dp/4839968519

内容は初学者にもわかりやすく、大変気に入っている。(経験者には物足りない内容なのかもしれない。)
サポートページによると、推奨されているFPGAボードは軒並み1万円超えで、挫折するリスクを考えると少し怖い。
そこで、アリエクで下記のボードを購入した。

https://ja.aliexpress.com/item/32691369830.html?spm=a2g0o.9042311.0.0.fc354c4dGTpJJt

当時の価格で5000円くらい。
ボード本体にI/Oインターフェースがそれなりに付いているので、これ単体で色々遊べるのかな？と思いこちらにした。

買ったはいいものの、日本語での情報が少なく、こちらもかなり苦戦した。動かすまでの手順をまとめておく。

# 2. 環境
 - PC: Ubuntu 20.04.3 LTS (64bit)
 - Board: 上記Aliexpressのリンク
    - Altera Cyclone iv ep4ce6

# 3. 手順
## 3.1 開発環境の準備
FPGAではボードに合わせて開発環境のソフトを選択する必要があるらしい。
今回のボードでは、IntelのQuartusを用いる。
下記サイトから、無料のLite版をダウンロードし、適切な場所に解凍する。

`intelFPGA_lite/{version}/quartus/bin`の配下の`quartus`が実行ファイルになっている。

## 3.2 USB Blasterの準備
ここが少しはまったところ。[こちらのページ](http://star.a.la9.jp/Quartus/old/Quartus16.0/main5.html)が参考になった。
USB Blasterを使用するには、`/etc/udev/rules.d/51-usbblaster.rules`を作成し、下記の内容を記載する必要があるとのこと。

```
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6001", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6002", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6003", MODE="0666"
```

PC, USB Blaster, FPGAボードの接続は下記の順番

 1. FPGAボードとPCを接続(ボードに給電を開始する)
 1. FPGAボードとUSB Blasterを接続
 1. USB BlasterをPCに接続

quartusを起動する前に`intelFPGA_lite/{version}/quartus/bin/jtagconfig`を実行し、下記のように表示されればOK。

```
1) USB-Blaster [1-7]
  020F10DD   10CL006(Y|Z)/10CL010(Y|Z)/..
```


逆に、下記のようなエラーメッセージが表示される場合はPCを再起動するなどして複数回試してみる。

```
1) USB-Blaster [1-7]
Unable to read device chain - JTAG chain broken
```

## 3.3 Quartus上での操作
ここからは下記の動画が参考になった。

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

1. プロジェクトの作成
    1. `New Project Wizard`を選択
    1. **[Introduction]** `Next>`
    1. **[Directory, Name, Top-Level Entity]** 適切なプロジェクトフォルダ、プロジェクト名を記載し、`Next>`
    1. **[Project Type]** Empty projectを記載し、`Next>`
    1. **[Add Files]** `Next>`
    1. **[Family, Device & Board Settings]**下記を設定し、`Next>` 
      - Family: Cyclone IV E
      - Available devices: EP4CE6E22C8
    1. **[EDA Tool Settings]**  `Next>` 

1. コードを記載
    1. `New` -> `SystemVerilog HDL File`を選択
    1. 書籍のコードを記載し、`*.sv`で保存
1. ピンの割当
    1. `Assignments` -> `Pin Planner`
    1. Node Nameにコード中のin/out名、Locationにピン番号を割り当てる
    1. ピン番号は、Aliexpressのページに記載がある(FPGA_CLKが23番、など)
1. コンパイル
    1. `Processing`->`Start Compilation`
    1. エラーメッセージが出ていないことを確認
1. ボードへの書き込み
    1. `Tools`->`Programmer`
    1.  `Hardware Setup`でUSB Blasterを選択
    1.  `Add File`で出来上がった`*.sof`ファイルを選択
    1.  `Start`を押下

以上の手順で、書籍中のLチカおよび、TD4によるキッチンタイマーの実装が動作することを確認した。


# 4. 所感

とりあえず動かすところまでの流れをざっと記載した。
設定はあまり理解できておらず、どの設定がどのように効くのかはちょっとずつ調べていきたい。
Git_基本操作①

# はじめに
場面別にGitコマンドをまとめていきます.
モチベがあれば続きます.

※筆者はGit初学者のため、間違い等がある場合は優しめにコメント頂けますと助かります…！

# 場面① リモートからローカルにリポジトリを複製する
```bash:コマンド
git clone <remote_url>
```
- 指定先urlのリモートリポジトリからローカルに対してリポジトリを複製
- 通信時のプロトコルは主にhttps もしくは sshを使用
    - 認証方法などが異なる. その場に応じて適切なプロトコルを選択すること

例.
![ex1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/d64e1dd6-1b30-586e-da1f-00ebae6aebe1.png)

# 場面② ローカルでの作業後に作業内容をリモートへアップロードする
```bash:コマンド
git status
```
- 現在の状態を確認するコマンド
- gitに管理されていないファイルは赤字で表示（ステージングされていない状態）
- gitに管理されているファイルは緑字で表示（ステージングされた状態）

```bash:コマンド
git add <file_name>
```
- 特定のファイルをgitに管理(登録)させたい時に使用
- 全てのファイル(git statusで赤字表示されている全てのファイル)をgitに管理させたい時は「git add .」を使用

例.
![ex2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/aba5d344-8d4c-5403-e7c7-973a7faaadb9.png)
![ex3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/906dda6b-7c90-d77b-8151-a1d121288f51.png)

```bash:コマンド
git commit -m <commit_message>
```
- 現在の状態をgitにセーブ(保存)したい時に使用
- 「commit_message」にコミット時のメッセージ内容を記載

例.
![ex4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/a48054a6-7cc6-b0b0-d8d0-0a81d023e90d.png)

※コミット後に同ファイルの編集を行った場合は再度、addとcommit操作が必要
![ex5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/b5f6afed-d502-8916-1d6f-67c05be4c873.png)
![ex6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/dfd5ad86-22ec-b28b-71a0-1a6344c5f883.png)

```bash:コマンド
git log
```
- gitのコミット履歴を確認出来るコマンド
    - 何時何分に誰がコミットしたという記録が残る

例.
![ex7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/8f05af60-4fe7-1311-4d66-1545d0dbf50a.png)

```bash:コマンド
git push <remote> <branch>

// 現在チェックアウトしているブランチを、その上流ブランチに push
git push origin

// ローカルブランチ「master」を、「origin」上の同名のブランチに反映する
git push origin master

// ローカルブランチ「master」を、リモートブランチ「master」に push 
git push origin master:master
```
- リモートにアップロードを行いたい時に使用
- origin：リモートサーバのこと
- 第2引数に「:（コロン）」を用いれば、push 先となるリモートブランチを明示的に指定する事が可能

![ex8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/61740b6a-39b8-5d5d-8328-df1a057736af.png)
push前：
![github_ex1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/d6f1bab0-a624-2117-1f5d-dbf555699c88.png)
push後：
![github_ex2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/d8eae0bf-4fac-2482-4947-c3fcf7c181f7.png)
コミット履歴：
![github_ex3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/ef7f4987-0624-9c5d-9fea-4cb4d29a11a1.png)
1回目のコミット内容：
![github_ex4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/7b6eae85-8e03-90a0-746a-1fec7d3c0361.png)
2回目のコミット内容：
![github_ex5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2413112/1767d99b-0f71-4fab-f261-8651071ab006.png)
# まとめ


メイン

|a  |b  |
|---|---|
|git clone  |リモートリポジトリの内容をローカルに複製|
|git add  |gitに管理(登録) |
|git commit  |gitにセーブ(保存) |
|git push  |リモートにアップロード(反映)|

サポート

|a  |b  |
|---|---|
|git status  |現在の状態を確認|
|git log  |コミット履歴を確認|
Python3エンジニア認定基礎試験

#意図
受験して合格できましたので、これから受験される方への一助になればと思い雑記を残します。
###私のバックグラウンド
・受験前からPythonの経験は多少あり
・ただ使う場面が偏っていたので、一度体系的に勉強してみたかったので受験を決意
・他言語の経験も多少あり
・職業プログラマではない
・飯を食っているのはインフラエンジニアとして
・仕事があるので、勉強に時間を割けるのは土日メイン
#受験当日：メモ用紙等は配布されません
コードを追ったり、リストや文字列を数えたりするのにメモ用紙等があれば便利ですが、試験時にはそのようなものは配布されませんでしたし、持ち込みも不可でした。よって、問題はすべて目で追い、脳内ワーキングメモリで処理せねばなりません。勉強時に問題を解くときもメモ用紙等を使わずに回答できるようにしておきましょう。プログラマさんなら難なくこなすのかもしれませんが、画面一ページほどのコードをパパっと目だけで追って、変数の値が途中どのように変わっていっているのか脳内ワーキングメモリを更新していくのは、初学者には慣れが必要な作業かと思います。
#模擬テストと本番の違い
おそらく多くの方は、[DIVE INTO CODE](https://diver.diveintocode.jp/dive_into_exam/lp)様と、[PRIME STUDY](https://study.prime-strategy.co.jp/)様の無料模擬テストのお世話になると思います。そしてこれらは大変有用です。本番の問題形式としても参考になるのですが、本試験を受験してみての感想です。
###一択問題だけではない
「正しいものを二つ選べ」という問題が出題されました。上記2つの試験ではそのような出題はありませんでしたので、本番では注意してください。試験時間が残っている限り、戻って見直したり回答しなおしたりすることが可能です。
###難易度
私も、DIVE INTO CODE < 本試験 < PRIME STUDY (https://hirahira.blog/python3-basic-exam-method/) と同感です。しかし、当たり前ですがそのままずばりの問題が出るわけではありません。本試験の出題元が[Pythonチュートリアル第4版](https://www.oreilly.co.jp/books/9784873119359/)ですので、その対策である模擬試験も同じドキュメントを参照して作成されることから、ほぼ同じ問題もありました。くれぐれも深層学習で言うところの過学習wにならないように注意してください。問題覚えちゃって、模試の点数が上がってきても実力がついていることにはなりませんので。
#勉強法
多くの方がWebで体験記を公開されているので、大変参考になると思います。多くの方と同意見で、私も「Pythonチュートリアル第4版」は最初に取り組むべき本ではないと思いますし、教科書として良書とも思えません。もちろん出題元なので外せませんし、言語の作者が書いたものとして価値はあります。しかし、いきなりこれを読むと面食らうのではないでしょうか。[Web](https://docs.python.org/ja/3/?trflg=1)で読めるとは言っても、結局私も購入しましたが。
###書籍
・[プログラミング経験者のためのPython最速入門](https://www.amazon.co.jp/gp/product/B01M7WU1K4/ref=ppx_yo_dt_b_d_asin_title_o01?ie=UTF8&psc=1)
これであらましをつかみました。恥ずかしながら、自分で使うツールではエラー処理とかちゃんと書いていませんでしたので、勉強になりました。
・[Pythonチュートリアル第4版](https://www.oreilly.co.jp/books/9784873119359/)
文句を言っておいてなんですが、ここから出題されますので手元にあった方が良いと思います。前述した模擬試験の問題を解いていても、「こんなこと書いてあったっけ？」と思っても、絶対この本に載っていますw だけどこの本では勉強できないんです。うまく伝えられないんですが、この試験の勉強を続けていけばご理解いただけると思いますwww
###演習
・[DIVE INTO CODE](https://diver.diveintocode.jp/dive_into_exam/lp)
受験は無料ですが、月額プランに入らないと、問題の解説を見ることができません。よって1か月だけ入会しました。問題の解説だけでなく技術に関する動画や資料も閲覧できますので、一ヵ月だけ入会して集中的に取り組んでみました。
・[PRIME STUDY](https://study.prime-strategy.co.jp/)
受験も、解説も無料です。メールで回答の正誤は送られてくるものの、問題の選択肢等は模擬試験実施中しか見られないため、回答中に気になることがあればメモしながら取り組むと良いと思います。
Amazonには問題集もあるようですが、私はこのWeb模擬試験のみ使用しました。
###勉強期間
多少の経験があったので、純粋にこの試験のためのみに費やしたのは一ヵ月分の土日数時間だと思います。そもそも集中力がないのもあって、土日といっても数時間ずつくらいしか取り組めませんでした。その数時間の内容は、模擬試験やって、知らないこと理解できないことを調べて、コードをjupyterで動かしてみるといった感じです。
#感想
個人的に、プログラミング・プログラミング言語についてちょっとコンプレックスがありました。私はプログラマではないこと(それで飯を食っているわけではないこと)、学生時代C言語でつまずいたこと、だましだましプログラムを書いてきたこと、体系的に勉強したことがなかったことと、使い方が偏っていたこと、いくら「やったことある」といったも証明するものがないことなどなどです。なので「プログラミングもしますよ」と言うこととか、プログラムやソースについて何か言及することがちょっとはばかられるというか。もちろん基礎試験でそれほど難易度が高いものではありませんが、これでちょっとは自信になりました。「一応資格も持っているよ」とは言えますので(^^;)。勉強していく中で知らないことも多々ありましたし、いままでうやむやにしていたこともちゃんと知識を整理する機会にもなりました。受験を検討されている方の参考になれば幸いです。
VRChatプレイヤーによるParticle System解説 ～Texture Sheet Animation Module編～

:::note warn
この記事はUnity 2019.4.29f1の記事です
:::
[Triggers, Sub Emitters Module編](https://qiita.com/abcde_kind/items/114842bfda2de4d2f649) <<  ここ  >> 次
# はじめに
この記事は**ちょっとParticle System触れるようになったけどまだまだ知らないパラメーターだらけで抵抗感がある人向け**にじゃあ全項目解説しようという記事です。

**パーティクル？シェーダー？憧れるけどよくわかんない…**という人は最近は[VRCUnity勉強会][link-1]などで初歩の初歩から解説してくれる講座などが解説されているのでそこに参加してみたりするといいでしょう。
[link-1]:https://discord.gg/mtvTTyM
その他にこの記事はアドベントカレンダーにしてParticle Systemの記事を増やしてパーティクルへの抵抗感を減らしてやろうという企みもあります。

##Texture Sheet Animation Moduleってどこ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2386883/139b6127-53b6-28d7-6121-fcf6e7855d88.png)
これ
##Texture Sheet Animation
パーティクルのテクスチャをパラパラ漫画のように再生させるためのModule
###Mode
デフォルト Grid
Gridはテクスチャをn×n分割して扱い、SpritesはSpriteを複数枚入れて再生させる、基本操作はほぼ同じなのでここでは**Gridの場合のみ解説する**
###Tiles
デフォルト (1,1)
**テクスチャを何分割してパラパラ漫画のように再生するか決めるパラメーター**
アセットのものとかでやるとわかりやすい
###Animation
デフォルト Whole Sheet
**再生するアニメーションのモード選択**
Whole Sheetは普通に通しで全部再生する、Single Rowは横の行ごとに分割して別々のアニメーションとして扱うまたSingle Rowを選択するとRow Modeを選択することになる
####Row Mode
デフォルト Random
**どの行を再生するか選ぶ方法を決めるパラメーター**
Randomはパーティクル1つ1つ毎にランダム、Customは何番目か指定、Mesh IndexはRender ModeをMeshにした際のメッシュのリストの順番
###Time Mode
デフォルト Lifetime
**アニメーションの再生速度の基準を決めるパラメーター**
Lifetimeは選択するとFrame over Lifetimeのグラフが出てきてパーティクル1つ1つが出てる間にどのようにアニメーションを再生するか決められる
Speedを選択するとSpeed Rangeのパラメーターが出てきて速度に応じて[^1]パラメーターを再生できる
FPSを選択すると1秒間に何フレーム再生するかで決めれる、再生が終わるともう一回再生される
###Start Frame
デフォルト 0
**何番目[^2]のフレームからアニメーションを再生するか決めるパラメーター**
小数は一見意味がなさそうだけど上のグラフとかで扱われてるから微妙に再生タイミングが変わったりとかする
###Cycles
デフォルト 1 (0.0001~100000)
**再生時間の内何回アニメーションを再生するか決めるパラメーター**
再生時間とはLifetimeで言うパーティクルの存在時間
###Affected UV Channels
デフォルト Everything
**テクスチャを分割する際メッシュのUVに影響されるか決めるパラメーター**
基本デフォルトでいいし変える必要があるなら説明しなくてもわかるのでは…？
##おわり
というわけでTexture Sheet Animation Moduleの解説でした
アドベントカレンダー僕一人しか参加してなくて失踪しかけましたがなんとか一人で頑張ってます
次はLight Moduleです
****
[Triggers, Sub Emitters Module編](https://qiita.com/abcde_kind/items/114842bfda2de4d2f649) <<  ここ  >> 次
[^1]: ここと似たパラメーターは以前解説した為省略、Lifetimeのデフォルトの左右端を選んでる感じ https://qiita.com/abcde_kind/items/96710d4e401ca88abbb5
[^2]: Unityは基本的に0番目から数字を数える
JavaScriptのイベント処理について(初学者向け）

##はじめに
JavaScriptのイベント処理の一例をご紹介します。


##内容
今何時？と記されているボタンをクリックすると、
**私の名前はDOMです**の文章が**13時です**に変わるイベントです。

--------------------------------------------------------------------------
![_2021-12-30 14 41 21](https://user-images.githubusercontent.com/86521768/147725022-d68bcdbc-5397-4367-a4c7-67bb658a646f.gif)

--------------------------------------------------------------------------

HTMLはこちらになります↓


``` qiita:html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>event</title>
</head>

<body>
    <p id="message"></p>
    <div><button id="btn1">今何時?</button></div>
    <script src="event.js"></script>
</body>

</html>
```

次にJavaScriptはこちらになります↓
説明も合わせて記載しています。

``` qiita:JavaScript
// ----------------------------------------------------------------------------
// ↓ドキュメントの中にあるid名messageをquerySelectorで取得してHTMLの内容を書き換えた
// ----------------------------------------------------------------------------
document.querySelector('#message').innerHTML = '私の名前はDOMです';

// ---------------------------------------------------------
// ↓btn1がクリックされた時にmessageを13時ですに書きかえる処理
// ---------------------------------------------------------

document.querySelector('#btn1').addEventListener('click', () => {
    document.querySelector('#message').innerHTML = '13時です';
});
```

##おわり

ご覧いただきありがとうございました。

また別の記事でお会いしましょう〜👋
Object.freezeの使い方

#はじめに
先輩から「オブジェクトフリーズしておいて」と言われハテナ過ぎたので調べました。

こちらの記事↓を見たら分かりやすいのですが、constでオブジェクトを定義してもオブジェクトの子要素は追加・削除したりできちゃうのって、罠ですよね。。
それを'Object.freeze'メソッドが解決してくれるようです！
>https://qiita.com/hosomichi/items/093aadcd8891c86e9dda#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E5%A4%89%E6%9B%B4

## Object.freezeとは
>Object.freeze() メソッドはオブジェクトを凍結します。凍結されたオブジェクトは変更できなくなります。オブジェクトを凍結すると、新しいプロパティを追加したり、既存のプロパティを削除したりすることができなくなり、既存のプロパティに対する列挙可否、構成可否、書き込み可否の変更ができなくなり、既存のプロパティの値が変更できなくなります。

なるほどつまり、定数みたいな以降値を変更したくないものは凍結しておくと良いのかな。
とりあえず、使ってみよう。

◆Object.freezeなし

```.js
const FRUITS = {
    FIRST: 'banana',
    SECOND: 'apple',
};
console.log(FRUITS.FIRST); // => banana
// 変更する
FRUITS.FIRST = 'minion';
console.log(FRUITS.FIRST); // => minion
// 追加する
FRUITS.THIRD = 'grape';
console.log(FRUITS.THIRD); // => grape
```

◆Object.freezeあり

```.js
const FRUITS_FREEZE = Object.freeze({
    FIRST: 'banana',
    SECOND: 'apple',
});
// 変更する
FRUITS_FREEZE.FIRST = 'minion';
console.log(FRUITS_FREEZE.FIRST); // => banana
// 追加する
FRUITS_FREEZE.THIRD = 'grape';
console.log(FRUITS_FREEZE.THIRD); // => undefind
```


おー！`Object.freeze`メソッドを使うことで
一度constで定義した定数の変更ができなくなりました！

参考: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
CSV V.S. XML V.S JSON

外部システムとの連携を考える際に、ファイルフォーマットをどうしましょうかという問題は常に存在する。

## CSVのいいところ

だいたいみんな知ってる。エクセルでもつくれるし、エクセルでも見れる。

## CSVの悪いところ

細かいところで仕様のブレが発生する。

- 全部にダブルクォートする？
- フィールド内改行を許す？
- 改行コードはCRLF？LF？
- 文字コードは、SJIS?UTF8?BOMつきUTF8?

一番やばいのが、フィールド内改行。エクセルはセル内改行をLFで表現するが、レコード区切りはCRLF。もはやテキストとしての体幹がグラグラ。UTF8のCSVをダブルクリックしてもエクセルでは文字化けしてしまう。BOMつきUTF8にすれば解決するが、そもそもCSVをダブルクリックしてエクセルで開いちゃうと、前ゼロは抜けちゃうしいいことない。エクセルで開いていただくつもりなら、最初からエクセルファイルをサーバー側で作るのがいいのかも。

## XMLのいいところ

- ツリー構造が定義できる。
- メタデータ定義のパートとデータパートを1ファイルにまとめれる
- でかいファイルの場合もSAXパーサーを使えば省メモリで処理ができる

## XMLの辛いところ

- CSVっぽいテーブルデータを定義するための共通仕様があるようでない。
- ファイル見ただけでは、何が配列で何がハッシュか分からない

## JSONのいいところ

- どの言語でも作りやすい
- ファイル見ただけで構造がわかる
- 見慣れてる

## JSONの悪いところ

- ファイル全部読まないとパースできない
- 1行ずつ完結するNDJSONも規格としては存在するが、NDJSONという単語がメジャーではない
- エクセルでファイルが作れない

## まとめ「仕様を絞ったCSVが暫定一位」

CSVの仕様の幅が広いのは受け入れるしか無い。
「BOMなしUTF8のCSVでフィールド内改行はなしね」で大体はカバーできる。BOMなしUTF8はエクセルで開くのが一手間かかるが、そのひと手間をかけれる人だけがCSVを扱ってよし。フィールド内改行の取り扱いがうまくいかないのはエクセルでもそうなので、CSVを扱う限りはフィールド内改行は諦めた方がいい。（なにか別の文字で置換するルールでいい）。
#キュッパチチャン (発掘品ネタ)

![PXL_20211230_051410200.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/8be44717-bd02-3295-7800-2e76e6d58a20.jpeg)

###すみません、がまんできませんでした。スタックチャンの便乗ネタです。
###NEC PC-9821Lt Windows95 N88-BASICのRS-232C命令をつかって、このNote PCを走らせてみました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%EF%BD%BD%EF%BE%80%EF%BD%AF%EF%BD%B8%EF%BE%81%EF%BD%AC%EF%BE%9D?src=hash&amp;ref_src=twsrc%5Etfw">#ｽﾀｯｸﾁｬﾝ</a> <a href="https://twitter.com/hashtag/%EF%BD%B7%EF%BD%AD%EF%BD%AF%EF%BE%8A%EF%BE%9F%EF%BE%81%EF%BE%81%EF%BD%AC%EF%BE%9D?src=hash&amp;ref_src=twsrc%5Etfw">#ｷｭｯﾊﾟﾁﾁｬﾝ</a><br>NEC PC-9821 Lt N88-BASICのRS-232CのOPEN/CLOSE信号でHブリッジMotorDriverをダイレクトに制御。 <a href="https://t.co/zJWKfP5N33">pic.twitter.com/zJWKfP5N33</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1476394901344784384?ref_src=twsrc%5Etfw">December 30, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#■構成
###・小型ギヤードDCモータ: FM90
###・モータードライバー  : TB6612FNG
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/7dd3a6e4-7359-b925-72ec-df4fb7b6103c.png)
#■RS-232C
###・HブリッジMotor Driverにダイレクト接続しています。
###・危険接続なので詳細説明は割愛します。
###・LED(抵抗入り)は信号確認用です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/3db40d62-d082-3531-b524-028db6d2f936.png)

#■プログラム
###・NEC PC-9821Lt Windows95 N88-BASICです。
###・COMポートをOPEN/CLOSEしているだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/95c4022d-990f-45f2-beb4-79507a4e8f64.png)

#■まとめ
###プログラムのほとんどがグラフィック部分です。何十年かぶりのBASICのグラフィックプログラミングで苦戦しました。
###みなさんよいお年を。
Julia: MongoDB のデータを削除 (Delete)

```julia:mongo_delete.jl
#! /usr/bin/julia
#
#	mongo_delete.jl
#
#					Dec/30/2021
# --------------------------------------------------------------------
using Mongoc
# --------------------------------------------------------------------
println(stderr,"*** 開始 ***")
key_in = ARGS[1]
println(key_in)
#
client = Mongoc.Client("localhost",27017)
database = client["city"]
#
collection = database["saitama"]
selector = Mongoc.BSON("key" => key_in)
Mongoc.delete_one(collection, selector)
println(length(collection))
#
println(stderr,"*** 終了 ***")
# --------------------------------------------------------------------
```

## 確認したバージョン

```text
$ julia --version
julia version 1.10.4
```

```text
# mongod --version
db version v7.0.11
Build Info: {
    "version": "7.0.11",
    "gitVersion": "f451220f0df2b9dfe073f1521837f8ec5c208a8c",
    "openSSLVersion": "OpenSSL 3.0.2 15 Mar 2022",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2204",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
```
Julia: MongoDB のデータを更新 (Update)

```julia:mongo_update.jl
#! /usr/bin/julia
#
#	mongo_update.jl
#
#					Dec/30/2021
# --------------------------------------------------------------------
using Mongoc
# --------------------------------------------------------------------
println(stderr,"*** 開始 ***")
#
key_in = ARGS[1]
population_in = ARGS[2]
println(key_in,'\t',population_in)
#
client = Mongoc.Client("localhost",27017)
database = client["city"]
#
collection = database["saitama"]
selector = Mongoc.BSON("key" => key_in)

today = Libc.strftime("%F", time())
#
update = Mongoc.BSON()
update["\$set"] = Dict("population" => population_in, "date_mod" => today)

println(length(collection))
Mongoc.update_one(collection,selector,update)
println(length(collection))
#
println(stderr,"*** 終了 ***")
# --------------------------------------------------------------------
```

## 確認したバージョン

```text
$ julia --version
julia version 1.10.4
```

```text
# mongod --version
db version v7.0.11
Build Info: {
    "version": "7.0.11",
    "gitVersion": "f451220f0df2b9dfe073f1521837f8ec5c208a8c",
    "openSSLVersion": "OpenSSL 3.0.2 15 Mar 2022",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2204",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
```
Julia: MongoDB のデータを読む (Read)

```julia:mongo_read.jl
#! /usr/bin/julia
#
#	mongo_read.jl
#
#					Dec/30/2021
# --------------------------------------------------------------------
using Mongoc
# --------------------------------------------------------------------
println(stderr,"*** 開始 ***")
#
client = Mongoc.Client("localhost",27017)
database = client["city"]
#
collection = database["saitama"]
println(length(collection))
for doc in Mongoc.find(collection)
#	println(doc)
	print(doc["key"], '\t', doc["name"])
	print('\t',doc["population"])
	println('\t',doc["date_mod"])
end
#
println(stderr,"*** 終了 ***")
# --------------------------------------------------------------------
```

## 確認したバージョン

```text
$ julia --version
julia version 1.10.4
```

```text
# mongod --version
db version v7.0.11
Build Info: {
    "version": "7.0.11",
    "gitVersion": "f451220f0df2b9dfe073f1521837f8ec5c208a8c",
    "openSSLVersion": "OpenSSL 3.0.2 15 Mar 2022",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2204",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
```
Julia: MongoDB のデータを作成 (Create)

text_manipulate.jl はこちら
[Julia: text ファイルの crud](https://qiita.com/ekzemplaro/items/5c7f674ee034a33e2553)

```julia:mongo_create.jl
#! /usr/bin/julia
#
#	mongo_create.jl
#
#					Dec/30/2021
# --------------------------------------------------------------------
using Mongoc
#
include("text_manipulate.jl")
# --------------------------------------------------------------------
function data_prepare_proc()
	dict_aa = Dict()
#
	dict_aa = dict_append_proc(dict_aa,"t1161","さいたま",52761,"2013-4-30")
	dict_aa = dict_append_proc(dict_aa,"t1162","所沢",17295,"2013-8-10")
	dict_aa = dict_append_proc(dict_aa,"t1163","越谷",31674,"2013-1-14")
	dict_aa = dict_append_proc(dict_aa,"t1164","久喜",93612,"2013-2-9")
	dict_aa = dict_append_proc(dict_aa,"t1165","熊谷",62391,"2013-7-4")
	dict_aa = dict_append_proc(dict_aa,"t1166","秩父",95187,"2013-10-21")
	dict_aa = dict_append_proc(dict_aa,"t1167","川越",31246,"2013-7-23")
	dict_aa = dict_append_proc(dict_aa,"t1168","和光",85791,"2013-12-26")
	dict_aa = dict_append_proc(dict_aa,"t1169","新座",24139,"2013-9-15")
#
	return	dict_aa
end
# --------------------------------------------------------------------
println(stderr,"*** 開始 ***")
#
dict_aa = data_prepare_proc()
#
client = Mongoc.Client("localhost",27017)
database = client["city"]
#
collection = database["saitama"]
println(length(collection))
#
for key in sort(collect(keys(dict_aa)))
	doc = Mongoc.BSON()
	doc["key"] = key
	doc["name"] = dict_aa[key]["name"]
	doc["population"] = dict_aa[key]["population"]
	doc["date_mod"] = dict_aa[key]["date_mod"]
	result = push!(collection, doc)
end
#
#
println(stderr,"*** 終了 ***")
# --------------------------------------------------------------------
```

collection の削除方法

```text
$ mongo
> use city
switched to db city
> db.saitama.remove({})
WriteResult({ "nRemoved" : 9 })
```

## 確認したバージョン

```text
$ julia --version
julia version 1.10.4
```

```text
# mongod --version
db version v7.0.11
Build Info: {
    "version": "7.0.11",
    "gitVersion": "f451220f0df2b9dfe073f1521837f8ec5c208a8c",
    "openSSLVersion": "OpenSSL 3.0.2 15 Mar 2022",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2204",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
```
GitLab 初期パスワード

Gitlab 構築したのに初期のパスワードが分からない！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773603/49c1c07d-5f42-6b19-fa5e-16a76e9930e4.png)

# ユーザー名

```root``` です。

# パスワードの調べ方

### コンテナの中に入る

まず、コンテナ名を調べます。
コンテナ名は、docker-compose.yml ファイルに書いてあります。

```
 >> cat docker-compose.yml
services:
    gitlab:
        image: 'gitlab/gitlab-ce:latest'
        restart: always
        environment:
          GITLAB_OMNIBUS_CONFIG: |
            external_url 'http://192.168.202.129:9010'
            gitlab_rails['gitlab_shell_ssh_port'] = 2022
            nginx['listen_port'] = 9010
        ports:
          - '9010:9010'
          - '2022:22'
        volumes:
          - '/srv/gitlab/config:/etc/gitlab'
          - '/srv/gitlab/logs:/var/log/gitlab'
          - '/srv/gitlab/data:/var/opt/gitlab'

```

services の下の、```gitlab``` がサービス名です。


```
 >> docker-compose exec コンテナ名 bash
```
で、コンテナの中に入ることができます。

```
 >> docker-compose exec gitlab bash
```

### パスワードを見る

/etc/gitlab/initial_root_password の中に初期パスワードがあります。

```
 >> cat etc/gitlab/initial_root_password
# WARNING: This value is valid only in the following conditions
#          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
#          2. Password hasn't been changed manually, either via UI or via command line.
#
#          If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.

Password: WJrcFdGUAt9ch4/kosu0itIaqjWmji+3fHkMr8ytNA0=

# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
```

このファイルは 1 日で消えてしまうので注意してください！！

# 簡単な見方

docker-compose.yml があるディレクトリ内で、

```
  >> docker-compose exec (コンテナ名) cat /etc/gitlab/initial_root_password
```

今回は以下

```
  >> docker-compose exec gitlab cat /etc/gitlab/initial_root_password
# docker-compose exec gitlab cat /etc/gitlab/initial_root_password
# WARNING: This value is valid only in the following conditions
#          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
#          2. Password hasn't been changed manually, either via UI or via command line.
#
#          If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.

Password: WJrcFdGUAt9ch4/kosu0itIaqjWmji+3fHkMr8ytNA0=

# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
```