OmniAICreator/Qiita-1.07M huggingface dataset:
3Dプリンタと組み合わせて遊ぶ！thingiverseで見つけたSeeed製品の3Dモデル

SeeedUG Advent Calenderの20日目の記事です。
クリスマス前に体調を崩して、見事に落とした記事ネタだけど、年内のうちに供養させるぞ！と言う事で筆をとりました。

というわけで改めましてコンニチワ！[熊本県3Dプリンタ勉強会](https://sites.google.com/site/3dkumamoto/)でよく遊んでる @tatsu1225 です。

今回のネタは3DプリンタとSeeed製品の組み合わせ。
ちょっとした固定にケースが欲しい！ってな時に3Dプリンタって便利なんですけど、ケースのモデル作るのも億劫ですよね。
って時はThingiverseを漁ると有名どころのボードは色々データが上がってたり。
この辺のデータを活用させて頂くと幸せになれるのでサクッと紹介してみるよー。


## 3Dプリンタを買ったら、まずは漁ってみようThingiverse
![e73d3e787b9ffe02f3f6b49b6d56b265.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/3ea87f69-ce18-e408-4edf-846a7224f58f.png)

- [Thingiverse](https://www.thingiverse.com/)

3Dプリンタユーザならご存じの方も多いと思いますが、Thingiverseってな有志が作った3Dモデルを共有するサイトがあります。
こちらには結構いろいろなモデルが挙がってまして、新しくマイコンボード買ったらThingiverseでモデル漁って、即プリンティング。

プリンティングしている間にボード弄ってLチカできる頃にはケースも完成して幸せ！ってなのが私の王道パターンです。マジ最高。


## WioNode向けの3Dモデルのデータもあるぞ！
![4fcff702ae66a2e5f2ee6914bc5409ff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/c09e2229-10bb-53b8-4682-bd1e2966d0e7.png)

- [SeeedStudio Wio Node Case](https://www.thingiverse.com/thing:2024657)

Raspberry Pi や Arduino以外にも色々モデルが挙がってまして、WioNodeのケースなんかもあがってます。（他だとLattePandaのケースとかGoogle Homeの壁掛けホルダーなどなど。何でもあるぞ！
WioNodeは取付穴とかないんで、固定に苦労するんですよね。ケースめっちゃありがたい...!!

![IMG_20191230_104721.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/f1e07b99-7824-d040-763b-38c8a12fb096.jpeg)

というわけで、私の手元の3Dプリンタでプリントしたものがコチラ。良い出来だ...。
ちなみに、AmazonでGETできる3万円台のReplap + 激安フィラメント(2000円/kg)でも十分プリントできました。やったぜ。


## Grove向けもあるある！Wrapperも良いけどね
![648186a168408921f57a40c143987076.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/9f8ef90d-fee0-5c3e-1296-aae918216eb5.png)


- [Thingiverse | "Grove"の検索結果](https://www.thingiverse.com/search?q=Grove&dwh=825e0959513bfef)

ちなみにGrove向けのホルダーなどの3Dモデルも探すといくつか出てきます。

![044a8eeaaced5a1faf1b0ed1e542d4b1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/cc45e5d2-6d20-ded8-229f-c159ffc487b4.png)

- [GROVE sensor module holder](https://www.thingiverse.com/thing:2493336)

いくつか試してみたんですが、個人的にオススメなのはコチラのモデル。



![IMG_20191230_104817.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/d9e94373-18b2-68f9-3fcf-e0e0658bfc17.jpeg)
![IMG_20191230_104853.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/f66b2ea7-e918-850f-0bde-13da28bde5e2.jpeg)


こんな感じでGroveモジュールをスタッキングできます。Groveモジュールを複数使いだすと固定に困るんですよね。これはイイネ！


![607022_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/caa25a5f-ff25-a01a-c5d1-a0c7a71a10b7.jpeg)

ちなみに、Seeedさんの公式には[Wrapper](https://www.marutsu.co.jp/pc/i/607022/)もあったり。こちは4個セットで350円ぐらい。マルツで売ってます。WrapperはLEGOにくっつけられるのが良いところ。
手間もかからないし、個人的にはこっちも好きです。

まあ、この辺は好みで！


# というわけで、合体！かんせい！
![IMG_20191230_104927.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/c4021f1d-a21d-a3ec-8859-94128b242666.jpeg)
![IMG_20191230_104931.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304878/db220f47-604d-2c1a-ef77-41e29876647c.jpeg)

ひゅー！！


というわけで、Thingiverseいいぞ。ってお話でした。
良い年末工作をお楽しみください！また来年！
paizaでilasm

# 概要

paizaでilasmやってみた。

# サンプルコード


```
import subprocess
import os

def cil():
    c_file = 'hello1.il'
    test_c = """
.assembly hello0 { 
}
.method static void Main() cil managed {
	.entrypoint
	.maxstack 	8
	ldstr 		"hello0"
	call 		void [mscorlib]System.Console::WriteLine(string)
	ret
}
.method public instance void Say(string A_1) cil managed {
	.maxstack	1
	ldarg.1
	call		void [mscorlib]System.Console::WriteLine(string)
	ret
}

"""
    with open(c_file, 'w') as f:
        f.write(test_c)
    os.system("ilasm %s" % c_file)
    os.system("mono hello1.exe")
    
if __name__ == '__main__':
  cil()


```

# 成果物

https://paiza.io/projects/lRa9NPOpI5A_LVgAAtA8GA

以上。
コマンドからPython起動時のWarningメッセを消す

####事象
Pythonをコマンドプロンプトから「python」と入力して起動したときに、下記の警告メッセージが表示された。なんだか気持ち悪かったので、解決したときの方法をメモ書きしておく。

```Python 3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32
Warning:
This Python interpreter is in a conda environment, but the environment has
not been activated.  Libraries may fail to load.  To activate this environment
please see https://conda.io/activation
Type "help", "copyright", "credits" or "license" for more information.```

####原因
「conda environment」と書いてあったので、そもそもAnacondaにてPythonをインストールしたことが原因っぽい。（かなり前に触ったっきりだったので、そういえば忘れていた、、。照）

Windows 版は、直接 Python3.7 を起動するのではだめで、conda の環境を起動してから Python3.7 を起動する必要がある模様。

####問題
そのまま使うことも可能だが、上記のように Python3.7 を直接起動したら問題になるのは、Pycharm と Excel で xlwings を使う場合。
（Pycharm の方は、Version 2019.1 で対応がなされたので、特に何もしなくても問題は解決）

####解決策
こちらの方の記事が参考になった。
>https://qiita.com/yniji/items/668f805a72a6ced6a2bd

ただ、上記手順でコマンドプロンプトから操作するのはややこしそうなので、そもそも今回であれば
Anacondaプロンプトをデスクトップ左下のWindowsメニューから起動
↓
「python」と入力すると、今度はWarningが表示されなくなる。
→解決！

そもそも環境を触ったのが久々だったので、忘れていたり理解しきれてなかったというのが問題でした。これを機にメモ書きを残しておこうと反省です。。
クロージャ(Closure)

関数内のスコープに保持された変数を参照、処理する関数

# 例1
関数内の値を `+1` して返す。

```javascript
const incrementAfterUse = (initNum)  => {
  let n = initNum;

  const increment = () => n++;

  return increment;
}

count = incrementAfterUse(1);
console.log(count()); // 1
console.log(count()); // 2
console.log(count()); // 3
console.log(count()); // 4
```

# 例2

```javascript
const incrementFn = (initNum)  => {
  let n = initNum;

  return {
    increment: () => ++n,
    showNum: () => n
  }
}

let count = incrementFn(1);
console.log(count.showNum()); // 1
console.log(count.showNum()); // 1
console.log(count.increment()); // 2
console.log(count.increment()); // 3
console.log(count.showNum()); // 3
console.log(count.showNum()); // 3
```

# 個人的なイメージ
クラスのインスタンス変数、インスタンスメソッドみたいなことを関数でやるためのもののように見える。

その他、こんな感じの使い方もありますみたいなものがあれば教えてもらえると嬉しいです。
ilasmでstack machine その6

# 概要

ilasmでstack machineやってみた。
俺言語、コンパイラを考えてみた。
3段階です。

# １回目コンパイル後


```
pushi   1
    set     i
loop:
    get     i
    pushi   100
    if<     bye
    get     i
    pushi   15
    %
    if      fizzbuzz
    get     i
    pushi   5
    %
    if      buzz
    get     i
    pushi   3
    %
    if      fizz
    get     i
    call    printi
    jp      tugi

fizzbuzz:
    push    "fizzbuzz"
    jp      print
buzz:
    push    "buzz"
    jp      print
fizz:
    push    "fizz"

print:
    call    prints

tugi:
    get     i
    pushi   1
    +
    set     i
    jp      loop

bye:
    ret
```

# ソース


```
10 i=1
30 j=i/15
40 #=%=0*120
50 j=i/5
60 #=%=0*140
70 j=i/3
80 #=%=0*160
90 ?=i
100 #=i<100*180
110 #=300
120 ?="fizzbuzz "
130 #=180
140 ?="buzz "
150 #=180
160 ?="fizz "
180 i=i+1
190 #=30

```

# 2回目コンパイル後

```
.assembly fizzbuzz {}
.method static void main() {
.entrypoint
.locals init(int32 i)
    ldc.i4   1
    stloc     i
loop:
    ldloc     i
    ldc.i4   100
    bgt     bye
    ldloc     i
    ldc.i4   15
    rem
    brfalse      fizzbuzz
    ldloc     i
    ldc.i4   5
    rem
    brfalse      buzz
    ldloc     i
    ldc.i4   3
    rem
    brfalse      fizz
    ldloc     i
    call    void [mscorlib] System.Console::WriteLine(int32)
    br      tugi

fizzbuzz:
    ldstr    "fizzbuzz"
    br      print
buzz:
    ldstr    "buzz"
    br      print
fizz:
    ldstr    "fizz"

print:
    call    void [mscorlib] System.Console::WriteLine(string)

tugi:
    ldloc     i
    ldc.i4   1
    add
    stloc     i
    br      loop

bye:
    ret

}


```

以上。
xGenで書くEKL①　Axisから3つのVectorをとる方法

xGenを使っていてGrasshopperにはない機能を見つけたので忘備録として残しています。

今回作ったのは簡単なパラメトリックのファサード。
それぞれのパネルのAxisを作ってそこからジオメトリを編集しようと試みました。

![Simple_Facade.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425318/2fd4417e-c190-fc88-a56c-dfacaab0ae87.png)
![features.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425318/4ea573c5-b4ee-2556-1ba4-ed46cd8bc071.png)
![Axis.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425318/b2aaa7ab-4833-1eb3-95e5-7635dfb5fbc8.png)

CATIA（xGen)では、サーフェスのノーマルはとるダイレクトな方法がありましたが、サーフェスから得たAxisからそれぞれのVectorへ分解するFeatureがなかったので、EKLで書いてみました。

```ex

let originVector(Vector)

originVector = inAxis.Origin :Vector

origin = originVector

let axMatrix(Matrix)
outMatrix = inAxis.Axes : Matrix

dirX = outMatrix.GetLine(1)
dirY = outMatrix.GetLine(2)
dirZ = outMatrix.GetLine(3)
```
インデックスマージで非効率なインデックスが選択されることがある

MySQL (Amazon RDS) でスロークエリ対策した際のノート。

MySQLではクエリオプティマイザがクエリ実行計画を立てる際に、絞り込み効果の低い列 (例えばレコード全体の20-30%以上が該当する場合など) に付けられたインデックスを使用することは通常ありません。

例えば 1, 2 二つの値しか持たないようなカラムに付けられたインデックスが存在していても、通常テーブルスキャンが選択されます。(そちらのほうが早いので）

しかしながら、インデックスマージでは、選択性の低いカラムのインデックスが使用されてしまい、結果的にパフォーマンスの大幅な低下を招くケースがありました。

https://dev.mysql.com/doc/refman/5.6/ja/index-merge-optimization.html

## SQLとクエリ実行プラン

**SQL**

```sql
SELECT MAX( create_timestamp )
FROM foobars
WHERE ( 
    foobars.valid_flag = '0' 
    AND foobars.spec_id IN ( '3', '5', '6', '7', '8', '9' ) 
    AND foobars.group_id = '622' 
    AND foobars.status_flag = '1' 
    );
```

**実行プラン**

|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|
|---|---|---|---|---|---|---|---|---|---|---|---|
|1|SIMPLE|foobars|NULL|index_merge|group_id,spec_id,status_flag,valid_flag|group_id,status_flag,valid_flag|4,1,1|NULL|4804|100.00|Using intersect(group_id,status_flag,valid_flag); Using where|

`valid_flag`は値が `1`, `2` の2種類しか存在しない列で、全体の95%以上が `1` です。抽出条件として `2` を選択するケースは、システム管理でごくまれに発生するだけであり、なおかつ他のカラムに付けられたインデックスで十分検索対象を絞り込めることもあり、このカラムに対する単独のインデックスは全く不要です。

`foobars`テーブルのレコード数は合計数百万件あります。
今回のケースでは、`valid_flag`セカンダリインデックスをスキャンして集めた数百万件 (の95%程度) のPKを他のセカンダリインデックス (group_id, status_flag) をスキャンして集めたPKのリストと突き合わせる、という処理が内部的に行われていたと思われます。
これではクエリも遅くなるはずです。

## 対策

* `valid_flag`カラムに付けられた単独のインデックスは削除します。存在しても使われることがないばかりか、インデックスマージに混ぜ込まれてパフォーマンスの低下を招きます。

```sql
ALTER TABLE foobars DROP INDEX `valid_flag`;
```

この時点ですでに十分パフォーマンスが改善しました。

* ついでに複合インデックスを作成します。しかもカバリングインデックスにしました。
    * このSELECTクエリはかなりの数が発行されており、レコードの作成よりも読み取り時に発生する負荷のほうがはるかに大きいです。
    * インデックスの最初の方に、他のクエリでも使用されるカラムを並べ、後ろの方にこのクエリのためのカラムを並べています。

```sql
ALTER TABLE foobars ADD INDEX `idx_group_spec_flag` (`group_id`, `spec_id`, `valid_flag`, `status_flag`, `create_timestamp`);
```

## 結論

低カーディナリティのカラムに付けられた、どう考えても役に立たないインデックス達。

あっても害はないように思えますが、INSERT/UPDATE 時のパフォーマンスに影響を与えるほか、インデックスマージに混ぜ込まれてパフォーマンスの大幅な低下を招くことがあります。

まぁいっか、で済まさず見つけたら削除しましょう！
【ネタ】廻せ！奇跡の好循環サイクルGodPDCAサイクル！！

#1．GodPDCAサイクルとは
日本が生み出した奇跡の好循環サイクル。この手法の最も素晴らしい点は、「絶対に失敗しない」ことです。
そのため、日本の各企業がこぞって取り入れています。ですので、ぜひ御社もGodPDCAサイクルを取りいれ、その素晴らしさを実感しましょう！
## P（計画）
神様（社長、取締役）のお告げを聞きましょう。どんなに長くとも、どんなに間違ったことでも、心の底から聞くことが大切です。
![internet_god.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/9bc45fc8-0249-527d-34d3-6ee39bb4f39a.png)

## D（実行）
神のお告げに従い、ひたすら働きましょう。
![busy_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/71b86628-a2cc-b370-1b8c-8998e9cbc0b4.png)

## C（処刑）
神のお告げを正しく実行したか確認しましょう。もし、神の教えに逆らうものがいれば、容赦なく罰しましょう！
![business_black_kigyou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/421dbf70-13d2-f193-8ec8-018e48c67212.png)

## A（懺悔）
神に実施した結果を報告しましょう。どんな失敗をしたとしても、神は必ずあなたを許してくれます。そして、神を信じる者は永遠の命（終身雇用）を与えられます。
![religion_keiji_woman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/931fab6c-ed16-30ad-82fd-f86e4d4952ab.png)


## 結果
上記を行うと必ず成功し、好循環なPDCAサイクルが廻り続けます。

なぜか？

神様（社長、取締役）が失敗するはずないからです！
失敗しないからこそ神なのです！

## まとめ
全然会社がよくならないな…と思っていたら、大抵上記のサイクルを回していることがよくあります。そして、GodPDCAサイクルの問題点は「一見サイクルが回っているように見える」ことです。そのため、どんどん良くなっていると勘違いをして、最終的に何らかのリスクが発生した際にようやく間違いに気づくのです。
コマンド実行時刻と履歴を .bash_history に保存

# はじめに
初期設定だと実行したコマンドは分かるが時刻が分からないので、記録できるようにする。

# 設定
.bashrcを下記のように編集すると、コマンドの実行時刻を記録できる。
ただし実行時刻を記録した場合、.bash_historyに記録できるのは__HISTFILESIZEの半分の件数__となるので注意。
HISTFILESIZEはファイルの最大行数を表している。
__時刻とコマンドでそれぞれ1行ずつ使用する__ので、下記の例であれば記録される個数の上限は30000÷2=15000件となる。

```text:.bashrc
HISTSIZE=15000
HISTFILESIZE=30000
HISTTIMEFORMAT='%Y/%m/%d %H:%M:%S '
```
設定を反映させる。

```
$ source ~/.bashrc
```
historyコマンドで履歴を表示してみる。

```
$ history | tail -n 5
14997  2019/12/30 09:24:16 xclock &
14998  2019/12/30 09:24:34 xclock -digital &
14999  2019/12/30 09:43:42 source .bashrc
15000  2019/12/30 10:16:59 bc
15001  2019/12/30 10:50:58 history | tail -n 5
```
実行時刻が分かるようになる。
設定前に実行したコマンドの時刻は記録されておらず、正しく表示されない。

# 参考
[historyコマンドに日時を付与する](https://qiita.com/bezeklik/items/56a597acc2eb568860d7)
Raspberry Pi で .Net の Web アプリケーションを Nginx で動かす

次のバージョンで確認しました。

```text
$ dotnet --version
6.0.302
$ nginx -v
nginx version: nginx/1.18.0
```

ポート 80 へのアクセスを、ポート 5000 へリバースプロキシします。

こちらで動かしたプロジェクトを　Nginx で動かします。
[Raspberry Pi で .Net Core の Web アプリケーションを publish](https://qiita.com/ekzemplaro/items/f07abe82894a3dcb6c07)

1) Nginx のインストール

```bash
sudo apt install nginx-full
```

2) ブラウザーで http://host にアクセスしてディフォールトの画面が表示されるのを確認。

/var/www/html/index.nginx-debian.html を改造して、表示が変わるのを確認。

3) /etc/nginx/sites-available/default を編集

```text:/etc/nginx/sites-available/default
#
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        index index.html index.htm;

        server_name _;

        location / {
                proxy_pass http://127.0.0.1:5000;
                proxy_set_header X-Forwarded-Host $host;
        }
}
```

編集に問題がないことを確認。

```bash
sudo nginx -t
```

4) Nginx を再起動

```bash
sudo systemctl restart nginx
```

5) ブラウザーで http://host にアクセス
![nginx_kestrel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c288cea4-3fba-4446-d56f-e873b2121757.png)
JavaはExcelをPDFに変えます

本論文では、JavaプログラムでExcelブックをPDF文書に変更する方法を紹介します, 含む

*Workbook全体をPDFに変更します。
*指定されたシートをPDFに変更します。

使用ツール：Free Spire.XLS for Java （無料版）
https://www.e-iceblue.com/Introduce/free-xls-for-java.html

Jarファイルの取得と導入：
Method 1：ホームページを通じてjarファイルのカバンをダウンロードします。ダウンロード後、ファイルを解凍して、libフォルダの下のSpire.xls.jarファイルをJavaプログラムに導入します。
https://www.e-iceblue.com/Download/xls-for-java-free.html

Method 2：maven倉庫設置による導入:
https://www.e-iceblue.com/Tutorials/Licensing/How-to-install-Spire.PDF-for-Java-from-Maven-Repository.html

Excelテストドキュメントは次の通りです。二つのシートが含まれています：
![Sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/aa3d4170-83b9-02d6-3f0f-acb84613a9e0.png)

JAVA Samples

Demo 1. Workbook全体をPDFに変更します

```java

import com.spire.xls.*;

public class ExcelToPDF {
    public static void main(String[] args) {
        // Excelドキュメントを読み込む
        Workbook wb = new Workbook();
        wb.loadFromFile("test.xlsx");

        //呼び出し方法をPDF形式に保存します
        wb.saveToFile("ToPDF.pdf",FileFormat.PDF);
    }
}
```
効果図：

![Excel to PDF 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/d4e82db5-2efd-14d3-5819-53a4e51ac8b1.png)

Demo 2. 指定されたシートをPDFに変更します

```java

import com.spire.xls.*;

public class ExcelToPDF {
    public static void main(String[] args) {
        // Excelドキュメントを読み込む
        Workbook wb = new Workbook();
        wb.loadFromFile("test.xlsx");

        // 2番目のシートを取得
        Worksheet sheet = wb.getWorksheets().get(1);

        //呼び出し方法をPDF形式に保存します
        sheet.saveToPdf("ToPDF2.pdf");
    }
}
```

効果図:
![Excel to PDF 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/0d454333-0ddc-4e2c-6f16-9aef9e2fe670.png)

The END
PHP,Pythonでの一時的なAWS認証情報の取得


# はじめに

AWSのEC2にアクセスキーを発行するのはアンチパターン。
キーが盗まれて使われることがあるので、キーは発行しないのが一番良い。
EC2にIAMロールっていう一時的なアクセスキーを発行するのが良いパターン。

# Pythonで使う



```:run.py
import boto3

session = boto3.session.Session(profile_name='prodaccess')
credentials = session.get_credentials()

# この値をbotoとかで自由に使って。
print(credentials.access_key)
print(credentials.secret_key)
print(credentials.token)
```

[boto3を使った一時的なAWS認証情報の取得](https://qiita.com/speg03/items/9ba5a34d721c9f4f90c5)

# PHPで使う

## Laravelで使う

aws-sdk-php-laravelってライブラリがある。

[aws-sdk-php-laravel](https://github.com/aws/aws-sdk-php-laravel)
[IAM Roleを使ってAWS ElasticSearch ServiceのデータをLaravelで取得する](https://qiita.com/wakanayoshizawa/items/3dc775eea01a75369b3c)
[公式　AWS SDK for PHP への一時認証情報の提供](https://docs.aws.amazon.com/ja_jp/sdk-for-php/v3/developer-guide/aws-sdk-php-v3-developer-guide.pdf)

```
composer require aws/aws-sdk-php
```

```:composer.json
{
    "require": {
        "aws/aws-sdk-php-laravel": "~3.0"
    }
}
```

公式の通りだけど


# PHP SDKを直で使う

createTokenがよし何やる。

[ここ](https://gist.github.com/sators/38dbe25f655f1c783cb2c49e9873d58a)にもサンプルはある。

```php:
$token = $RdsAuthGenerator->createToken($clusterEndpoint . ":" . $clusterPort, $clusterRegion, $dbUsername);
$mysqli = mysqli_init();
mysqli_options($mysqli, MYSQLI_READ_DEFAULT_FILE, "./my.cnf");
$mysqli->real_connect($clusterEndpoint, $dbUsername, $token, $dbDatabase, $clusterPort, NULL, MYSQLI_CLIENT_SSL);
if ($mysqli->connect_errno) {
    echo "Error: Failed to make a MySQL connection, here is why: <br />";
    echo "Errno: " . $mysqli->connect_errno . "<br />";
    echo "Error: " . $mysqli->connect_error . "<br />";
    exit;
}
/***** Example code to perform a query and return all tables in the DB *****/
$tableList = array();
$res = mysqli_query($mysqli,"SHOW TABLES");
while($cRow = mysqli_fetch_array($res))
{
    $tableList[] = $cRow[0];
}
```
ディレクトリを飛び回る z コマンド

## z コマンドとは

よく使用するディレクトリへのアクセスを簡単に行う便利コマンドです。
通常は `cd` コマンドで相対パスや絶対パスを引数にしますが、 `z` コマンドを使うとディレクトリ名の一部が一致すれば最近アクセスしたディレクトリへ遷移します。

何度もディレクトリを行き来する場合にとても便利なコマンドです。

## GitHub

https://github.com/rupa/z

## 動作シェル

bash, zsh で動作します。

## インストール

```shell-session
$ git clone git@github.com:rupa/z.git ~/z
```

お好みの場所へ配置してください。今回の例では `~/z` にインストールします。

`~/.bash_profile` や `~/.zshrc` に追記します。

```bash:~/.bash_profile
. ~/z/z.sh
```

## 使い方

`~/foo/bar/hoge/fuga` というディレクトリがあれば下記コマンドでどこからでも移動できます。

```shell-session
$ z fuga
```

**<font color="Crimson">※一度はfugaディレクトリにアクセスしている必要があります。</font>**

### 同名ディレクトリがある場合

アクセス頻度が多いディレクトリが優先されます。
詳細な計算方法は公式READMEを参照ください。

## alias

`z` は押しづらいので `j(jump)` にエイリアスを張ると良いです。

```bash:~/.bash_profile
alias j=z
```

```shell-session
$ j fuga
```

## 参考記事

- [z.shでよく行くディレクトリに手軽に移動する](https://qiita.com/yoshikaw/items/38d3008ac7d0b19b4805)
ilasmでclass

# 概要

ilasmでclass書いてみた。

# 環境

windows 7 64bit
.Net Framework 2.0

# サンプルコード


```
.assembly hello1 {
}
.class private auto ansi hello1 extends [mscorlib]System.Object {					
    //クラス
	.method public specialname rtspecialname instance void .ctor() cil managed {	
        //コンストラクター
		.maxstack	2
		ldarg.0
		call		instance void [mscorlib]System.Object::.ctor()
		ret
	}
	.method public instance void Say(string A_1) cil managed {
		.maxstack	1
		ldarg.1
		call		void [mscorlib]System.Console::WriteLine(string)
		ret
	}
	.method static void Main() cil managed {		
        //メイン
		.entrypoint
		.maxstack 	8
		.locals 	init (string V_0, class hello1 V_1)
		ldstr		"hello1"
		stloc.0										
        //変数V_0に、"hello1"入れる。
		newobj		instance void hello1::.ctor()
		stloc.1										
        //変数V_1に、クラスhello1入れる。
		ldloc.1
		ldloc.0
		call		instance void hello1::Say(string)
        //stackにクラスとhello1積んで、Sayをコール。
		ret
	}
}


```

以上。
Linuxで認識されているディスクの処理速度を簡単に測る方法

# TL;DR
OS やミドルウェアといった様々なレイヤーを扱っていても、ディスクの Read/Write 速度というものは必ずボトルネックになりえる要素として存在する。ディスクがボトルネックになっているか疑わしいと考えた時、簡易的にディスクのスループットを計測する方法を紹介。

- `dd`コマンド、`pv` コマンドを利用することでディスクスループットが簡易的に計測することが可能

# 利用シーン
一例となりますが、ファイル圧縮処理を行う時に圧縮処理がなぜか遅い、といった場合等に紹介する方法での調査が有用だと考えます。

# ディスクの Read スループットを計測する
`dd` コマンドを利用して計測対象のディスクを `if` に設定、 `of` に `/dev/null` を指定することで Read スループットを計測することが可能です。ちなみに注意としては `dd` コマンドとなるため、あくまでシーケンシャルのアクセスになることを意識することが大事だと思います。

- `/dev/sda1` の Read スループットを計測する例
 
```shell
dd if=/dev/sda1 of=/dev/null bs=16k status=progress
```

出力は下記のような内容となります。

```shell
584122368 bytes (584 MB) copied, 4.61756 s, 127 MB/s
```

# 各コマンドにおける処理速度を計測する
上記で紹介した方法は、ほぼ純粋なディスク速度となります。ですが利用シーンの例にもある通り、例えば圧縮処理が遅いといった時に、それが純粋なディスク速度が遅いのか圧縮処理がボトルネックになっていて遅いのか切り分けたい場合があると思います。そのような場合に有効なのが各コマンドの処理速度を計測することができる `pv` コマンドとなります。

## pv コマンドとは
`pv` コマンドはパイプ処理を実施する時に、パイプを渡るデータ量を計測するコマンドとなります。例えば、下記のような例がある場合 `tar` コマンドから `lz4` コマンドへ渡るデータ量、すなわち `tar` コマンドの処理がどの程度の速度で実施されているか確認することができます。これによって、下記コマンドの実行速度がなぜか遅いといった場合に `tar` コマンドがボトルネックになっているのか、`lz4` コマンドがボトルネックになっているか当たりをつけることができます。

```shell
tar -b 256 -cvf - /data/ | lz4 -c
```

## 使い方
下記のように計測したいパイプの間に `pv` コマンドを挟むことで計測することが可能です。

- `tar` コマンドの速度を計測する例

```shell
tar -b 256 -cvf - /data/ | pv | lz4 -c > /dev/null
```

- `lz4` コマンドの速度を計測する例

```shell
tar -b 256 -cvf - /data/mysql/ | lz4 -c | pv > /dev/null
```

出力は下記のような内容となります。

```shell
8.66GiB 0:00:04 [2.19GiB/s] [  <=>           ]
```

# おわりに
ディスクの性能を測る方法は数多くあると思いますが、今回は手軽に確認ができる方法として上記方法を紹介しました。ディスクへのアクセスも`Read` `Write` に加えて `Random IO` `Sequential IO`、速度の指標も `IOPS` `Throughput` というように様々な種類があるため、常に「今回はどのようなアクセスパターンが発生する処理なのか」等を意識するとボトルネックの発見に円滑に近づけたりすると思います。
dyld_shared_cache_extract_dylibs failed っていう謎のエラーが出たときの解決策

https://forums.developer.apple.com/thread/108917

こちらに書いてありました。
僕の環境：
Xcode 10.3
iOS 13.2.2

```
1.以下のフォルダを開く
 〜/ Library / Developer / Xcode / iOS DeviceSupport
 / 13.2.2 / Symbols / System / Library / Caches / com.apple.dyld

2.「.processed_dyld_shared_cache_arm64e」っていう名前の空のファイルを作ってそこに入れる

3. xcodeを再起動してお楽しみください!
```
高階関数(HOF: Higher Order Function)

関数を引数に取ったり、関数を戻り値として返す関数のこと。

# 例
```javascript
// 引数に入れるための関数を準備
const double = n => n * 2;

// 関数 fn の引数を num 倍する関数を返す
const hof = (num, fn) => {
  return n => fn(n * num);
}

// 関数 double の引数を2倍する関数(つまり4倍)を返す
const quadruple = hof(2, double);

console.log(quadruple(3)) // 12
```
Advent Calendar 2019 の振り返り

# 概要
毎年 Qiita で行われている Advent Calendar に初めて参加してみたので、その振り返り。

# 参加したカレンダー
参加したといっても、ひとりAdvent Calendar のみです。

* [looking back this year for my tech Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nkk777dev)
  * やりきったら、**ccilu のレインブーツを買う！** ということをモチベーションに始めた（以下参考画像）
  * https://www.ccilu.jp/
![ccilu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220144/0420eb43-be4a-d2cd-e69f-fcb7bcc16779.jpeg)


# 参加してみての感想
## よかったこと
* 25日間最後まで投稿することができた
* 投稿日前に記事を書き終わるようにするため、計画を立てて記事を作成することができた
  * 飲み会とかの予定があるから早めに書き終わらないとなどを考えて行動できた（記事の予約投稿にはすごくお世話になりました）
* 自分なりの記事の書き方のテンプレートを作ることができた
* 記事を書くために自分のやってきた技術の振り返りを行うことができた
  * アウトプットの形にするために、自分がやってきたことを深掘りして理解が深まったと思う
  * 自分の過去に直面した問題とその解決方法の記録になるので、今後どこかできっと役に立つと思う（思いたい）
* 意外と自分の記事を見ている人がいるっていうことがうれしかった
  * 自分の記事を読んで、「いいね」してくれたってことは、少しはその人のためになることができたのかな
  * [おひとり様カレンダーランキング](https://qiita.com/tomowarkar/items/c3939c0985c36929b35a) に取り上げてもらえていたのもすごくモチベーションが上がった

## 悪かったこと
* 25日間投稿する！っていうのを一番の目的にしていたせいで、ためになるような記事をあげられていたかが怪しい

## 今後に向けて（改善したい、続けたいこと）
* Qiitaへの記事の投稿を定期的に行うようにしたい
  * 週1、もしくは月1ぐらいでは上げられるようにしたい
  * Qiitaにこだわらなくてもいいかもしれないが、何かしらアウトプットを出すようにしたい
  * そのためにも新しいことにチャレンジしていきたい
* 来年の Advent Calendar にも参加したい！
  * 来年は他の人が開催している Advent Calendar への参加をしてみたい
  * 他の人のAdvent Calendar だと、ひとりAdvent Calendar よりもちゃんとした内容の記事を出さないとっていう緊張感が出ていい経験になりそう
  * ひとりAdvent Calendar もできればやりたい

# まとめ
悪かったことがほとんど思い浮かばなかったのでちゃんと振り返りになっているかは微妙だけど、
やってみてよかったなとは終わった今でも思います。
RustでJPEG画像の各ピクセルのRGBを取得する

絵でも描こうかと思っていたら, Rustでimageクレートをたたいていました。

# 0. 実行環境
- Windows10 Home
- rustc 1.39.0

# 1. 使用したクレート
- image = "0.22.3"

# 2. ソースコード
```rust:main.rs
use image::open;

fn main() {
    let img = open("src/sample_image.jpg").unwrap().to_rgb();

    let img_width = img.width();    // 画像の幅を取得
    let img_height = img.height();  // 画像の高さを取得

    for y in 0..img_height {
        for x in 0..img_width {
            let pixel = img.get_pixel(x, y);   // (x, y)のピクセルを取得
            let r = pixel[0];
            let g = pixel[1];
            let b = pixel[2];
            println!("({}, {}, {})", r, g, b);
        }
    }
}
```

```Cargo.toml
[package]
name = "image_practice"
version = "0.1.0"
authors = ["*** <miserarenaiyo@example.com>"]
edition = "20XX"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
image = "0.22.3"
```

# 3. 実行結果
```
(100, 100, 100)
(100, 100, 101)
(100, 100, 100)
.
.
.
```
上のように延々とRGBが出力されます。

# 4. 参考URL
- https://docs.rs/image/0.23.0-preview.0/image/index.html (image)
- https://docs.rs/image/0.23.0-preview.0/image/fn.open.html (image::open)
- https://docs.rs/image/0.23.0-preview.0/image/struct.ImageBuffer.html (width, height, get_pixel)
- https://docs.rs/image/0.23.0-preview.0/image/struct.Rgb.html (image::Rgb)
SyntaxError Unexpected token 'export'

# はじめに
Nuxt.jsを使っていて、SPAからSSRに切り替えたときに表題のようなエラーが出てハマった。
いろいろ調べてみた結果、解決したので備忘録として解決方法を投稿する（以下は方法の一つであり、他にも方法はありそうです。あくまで参考程度でお願いします）。

<img width="1366" alt="スクリーンショット 2019-12-30 9.24.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/54190f97-f3bc-ddad-752f-25756cc333a1.png">


# 解決策
私の場合は、fontawesomeを追加した時にnuxt.config.jsで`plugins: ['plugins/vuetify'],`となっていることが原因でした。SSRをサポートしていないvuetifyプラグインが追加されていたことが原因のよう。

nuxt.config.jsを以下のように変更する。

```js:nuxt.config.js（変更前）
plugins: ['plugins/vuetify'],
```

```js:nuxt.config.js（変更後）
plugins: [{ src: 'plugins/vuetify', ssr: false }],
```


# おわりに
[こちら](https://greensock.com/forums/topic/17888-importing-plugins-in-nuxtjs/page/2/)を参照。
Macでgit-prompt.sh のPROMPT_DIRTRIM が効かない解決法




# 起こったこと

Mac terminal(bash) で git-prompt.sh でCommand Lineをいい感じに
整形しようとしたら
現在pathの表示部分が長いときに折りたたむ
```
PROMPT_DIRTRIM=2
```

のように PROMPT_DIRTRIMが効かなかった。



# 解決法

bash のバージョンが古いらしい。(>= v4.0が対応のよう)
ので、バージョンアップ。
(そして利用shellの変更。)


```
$ brew install bash

# Add the new shell to the list of legit shells
$ sudo bash -c "echo /usr/local/bin/bash >> /private/etc/shells"

# Change the shell for the user
$ chsh -s /usr/local/bin/bash
```

そしてterminal に入り直す。


# 参考


https://unix.stackexchange.com/questions/291897/prompt-dirtrim-not-working

https://gist.github.com/samnang/1759336
function定義の関数とアロー関数との this の違い

# function定義の関数の this
定義された文脈中の object

# アロー関数の this
関数それ自体

# 例
- function定義の関数の this

以下の例では `obj1` が `this` となっている。

```javascript
const obj1 = {
  num: 123,
  fn: function() {
    console.log(this);
  }
}

obj1.fn()
// { num: 444, fn: [Function: fn] }
```

- アロー関数の this

```javascript
const obj2 = {
  num: 888,
  fn:()=>{
    console.log(this);
  }
};

obj2.fn()
// Object [global] {
//   global: [Circular],
//     clearInterval: [Function: clearInterval],
//     clearTimeout: [Function: clearTimeout],
//     setInterval: [Function: setInterval],
//     setTimeout: [Function: setTimeout] { [Symbol(util.promisify.custom)]: [Function] },
//     queueMicrotask: [Function: queueMicrotask],
//     clearImmediate: [Function: clearImmediate],
//     setImmediate: [Function: setImmediate] {
//     [Symbol(util.promisify.custom)]: [Function]
//   }
// }
```

# 開発における使い分け
基本的にアロー関数を使って、コードベース内で統一していく方がいい。

そうすることで、function定義の関数を使っていると、関数内で `this` から何か使いたいんだなという意図を伝えられる。
令和RSS-Ai platform for bio engineering and business

https://www.reiwarss.com/

Ai platform for bio engineering and business

（1）AI
（2）自動運転
（3）ブロックチェン
（4）サイバーセキュリティ

主な特徴：

基本1hour毎に更新,24時間以内の内容のみ記憶
好きなテーマを自由に選択
広告無し
GPIOの探し方

mruby on YABMを動かしているBCM5354なGemtek WRTB-204GなデバイスのGPIOを探してみました。

基板の写真はInternal-Photos-830239.pdfというファイルで見ることができます。

```ruby:led.rb
begin

yabm = YABM.new

bit = 0

maxpin = 8

orgdir = yabm.gpiogetdir()
orgctl = yabm.gpiogetctl()
yabm.print "ORG DIR: " + orgdir.to_s + " CTL: " + orgctl.to_s + "\r\n"
yabm.gpiosetdir(0xff)

while 1 do

  yabm.print bit.to_s + " "
  yabm.gpiosetdat(1 << bit)
  bit = bit + 1
  if bit == maxpin
    bit = 0
  end
  6.times {
    start = yabm.count() 
    while yabm.count() < start + 1000 do
    end
    yabm.print "*"
  }
  yabm.print "\r\n"
end

rescue => e
  yabm.print e.to_s
end
```

このスクリプトを実行してLEDがGPIOのどのピンにアサインされているかを確認します。

回路はこのようになっています。

![LED.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/f553eeb4-2672-f7ec-1cd6-d4998c33b95c.png)


ビットが立つと消灯します。

|パターン|表示|色|接続|
|:--|:--|:--|:--|
|LED1|POWER|緑|GND直結|
|LED10|SECURITY|橙|GPIO6|
|LED2|WIRELESS|緑|GPIO2|
|LED6|||GPIO1(未実装)|
|LED11|DIAG|赤|GPIO7|
|LED7|||?(未実装)|
|LED4|INTERNET|緑|Ethernet|

yabmでのLEDの制御はこんな感じで書けます。

```ruby
LED10 = (1 << 6)
  reg = yabm.gpiogetdat
# 点灯
  yabm.gpiosetdat(reg & ~LED10)
# 消灯
  yabm.gpiosetdat(reg | LED10)
```

スイッチもテスターであたって、確認します。

|パターン|GPIO|
|:--|:--|
|SW1|0|
|SW2|4|

これで3と5がないので、最初液晶とスイッチの基板に実装されているHT82K68Eへの接続が3,5なのかと思って調べていたのですが、テスターが反応しません。

BCM5354はPRODUCT Briefを見ても使えそうなインターフェースがGPIOとUSBしかないので、これのどちらかだと考えたのですがHT82K68EはUSBは使えないので、GPIOではないかと考えていました。

しばらく基板とにらめっこしてふと気が付きました。左上にSW3という未実装なパターンがあり、そこが3,5でした。

BCM5354はuartが2つあるのでHT82K68Eへの接続はuartでした。

ちょうどBitbangなI2Cを試したいとおもっていたので3,5を使うことにしました。

ビットの回し方を以下のようなコードを最近見かけました。

```ruby
  bit = (bit + 1) % maxpin
```

好みですが、私はあまり好きではないです。

# おまけ

[液晶をArudinoで制御](https://qiita.com/yamori813/items/91c787d96fc2234cf733)してみました。
競技プログラミングのためにやったことメモ

競技プログラミングのために色々試行錯誤する経過を記録する。

ちょくちょく更新して行きます。

# 環境

- OS X
- gcc 9.2

# やったこと

## bits/stdc++.hの導入

標準ライブラリを一気に入れてくれる優れものということで導入

参考にしたサイト
[https://annin401.hatenablog.com/entry/2019/03/29/005224](https://annin401.hatenablog.com/entry/2019/03/29/005224)
https://qiita.com/EngTks/items/ffa2a7b4d264e7a052c6

うまくビルドできなかったので以下の対処を実施
https://qiita.com/dynamonda/items/3a2f5bd063cb5e457605

## 使いそうな関数をutil.hppとして切り出し

- 素数判定
- string置換
Ruby on Rails - show all routes / paths or urls / in rails console / e.g `app.methods.grep /_path\Z/`

```
bundle exec rails console
```

```rb
[1] pry(main)> app.methods.grep /_path\Z/
```

```rb
[2] pry(main)> app.methods.grep /_url\Z/
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2894








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#Rails - rails console で全てのパス・URLを確認する ( e.g `app.methods.grep /_path\Z/` )

# example

```
bundle exec rails console
```

```rb
[1] pry(main)> app.methods.grep /_path\Z/
```

```rb
[2] pry(main)> app.methods.grep /_url\Z/
```

# app って何よ？

main空間に生えているインスタンスっぽい？


```rb
[15] pry(main)> self
=> main
[16] pry(main)> self.app
=> #<ActionDispatch::Integration::Session:0x000055e5817d8540
```

`Rails.application.app` とはまた違うようだ。

# Ref

rails console の tips - Qiita
https://qiita.com/snaka/items/eeb5dee96e44fca54a2e

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2893








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
スマホで簡単にマイニングができるPi Network

#Pi Networkとは
Pi Networkとはスタンフォード大学の博士課程のグループによって開発されている仮想通貨だ。
今年の3月に公開され、現在では125万人を超えている。


#Pi Networkの特徴
##マイニングが簡単にできる
ビットコインなどの今までの仮想通貨では高性能なコンピュータを用いて知識のある人がマイニングをしていたが、Pi Networkでは誰でもスマホで1日に一回ボタンをタップするだけでマイニングをすることができる。
Git でよく使うコマンドまとめ

## リモートリポジトリとのやりとり

### リモートリポジトリを新規ディレクトリにコピー
```
git clone <リポジトリのURL>
```

### 上流ブランチ（デフォルトで `origin` レポジトリ）を現在のブランチにマージ
```
git pull
```

### 上流ブランチを指定して現在のブランチを反映
```
git push -u origin <ブランチ名>
```

### 現在のブランチを上流ブランチに反映
```
git push
```

## ブランチの操作

### ブランチのリストを表示
```
git branch
```

### ブランチを作成して切り替え
```
git checkout -b <ブランチ名>
```

### ブランチを切り替え
```
git checkout <ブランチ名>
```

### 指定したブランチを現在のブランチにマージ
```
git merge <ブランチ名>
```

### ブランチを削除
```
git branch -d <ブランチ名>
```

## ローカルリポジトリでの操作

### 変更されたファイルを確認
```
git status
```

### 変更箇所を確認
```
git diff
```

### ファイルの追加・更新をインデックスに追加してコミット
```
git add <ファイル/ディレクトリのパス>
git commit -m "<コメント>"
```

### すべてのファイルの更新をインデックスに追加してコミット
```
git commit -am "<コメント>"
```
【Golang + Lambda + API Gateway】で、S3バケットを作るAPIを作ってみた

![lambda(qiita).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415008/36cf3111-680d-ed98-11be-d7263cd3c788.png)
##前提条件
2019年12月29日に試してみたものです。
Go 1.12.9


#1. GolangのコードをLambdaで実行

###必要なライブラリをインストール
```
$ go get -u github.com/aws/aws-lambda-go/lambda
$ go get -u github.com/aws/aws-sdk-go/...
```

###指定したバケット名で、S3バケットを作るコード
作った関数は、引数として受け取ったバケット名で、S3バケットを作り、その結果をログに出力するもの。

```golang:hello.go
package main

import (
	"log"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
)

type MyEvent struct {
	BucketName string `json:"bucket_name"`
}

func hello(event MyEvent) {
	// 流れ：認証情報→セッション→S3
	creds := credentials.NewStaticCredentials("AWS_ACCESS_KEY", "AWS_SECRET_ACCESS_KEY", "") //第３引数はtoken
	session, _ := session.NewSession(&aws.Config{
		Credentials: creds,
		Region:      aws.String("ap-northeast-1")},
	)
	svc := s3.New(session)
	resp, _ := svc.CreateBucket(&s3.CreateBucketInput{
		Bucket: aws.String(event.BucketName),
	})
	log.Println(resp) //Lambdaテストの実行結果のログ出力や、CloudWatchのロググループで確認できる
}

func main() {
	lambda.Start(hello)
}
```

###ビルド(クロスコンパイル)して、zipファイルにする
Lambdaで動かすためには、普通にgo buildするのではなく、Linux上でも動作するようにクロスコンパイルの設定を追加する必要がある

```terminal
$ GOOS=linux GOARCH=amd64 go build -o hello
$ zip handler.zip ./hello
```

###zipファイルをLambdaにアップロード
1. Lambdaコンソールから関数を作成し、上記で作成したZIPファイルをアップロード
2. **Lambdaの関数コードのハンドラは、作成した関数名と一致させる（本記事ではhello）**
3. 忘れずに保存ボタン

###テスト（動作確認）
+ Lambdaコンソールの「テストイベントの設定」画面で、下記のjsonデータを入力
+ S3バケット名になるため、**一意になる名前**を指定

```json
{
  "bucket_name": "test191229" 
}
```
+ S3コンソールで、指定したバケット名で作られているか確認
+ ログ出力を確認　→　成功した場合、「Location」（S3のURL）が返ってくる

#2. API GatewayでAPI作成
1. API Gatewayコンソールから「APIの作成」→REST APIの「構築」ボタン
2. API名を入力し、API作成
3. アクション→「リソースの作成」（**リソース名は、アクセスするパスになるので注意**）
4. アクション→「メソッドの作成」（GETを指定し、作ったLambda関数を指定）
5. 「メソッドリクエスト」→「URLクエリ文字列パラメータ」を追加（bucket_name）
6. 「マッピングテンプレートの追加」(Content-Type:application/json)
7. 「テンプレートの生成」→emptyにし、以下を入力


```
#set($inputRoot = $input.path('$'))
{
    "bucket_name" : "$input.params('bucket_name')"
}
```
　**※上記が、作成したhello関数の引数として入ってくる**

>$input.params(x)	
パラメータ名文字列 x が指定された場合に、パス、クエリ文字列、またはヘッダー値から (この順番で検索される) メソッドリクエストパラメータの値を返します。

マッピングテンプレートで使える変数・関数
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#input-variable-reference


8.最後に、「アクション」→「APIのデプロイ」（ここで入力する**ステージも、アクセスするパスになるので注意**）

###アクセスするURL
+ 「APIのデプロイ」後、Lambdaコンソールに表示されるURLを利用
+ 例えば、ステージ名が「stage」、リソース名が「myresource」、「URLクエリ文字列パラメータ」が「bucket_name」の場合、
***URL/stage/myresource?bucket_name=test191230***

+ ここにアクセスすると、「test191230」というS3バケットが作成される

##参考にさせて頂いた記事
[AWS Lambda で Go が使えるようになったので試してみた](https://dev.classmethod.jp/cloud/aws/aws-lambda-supports-go/)
[golang + Lambda + API GatewayでREST APIを作ってみた](https://qiita.com/icchi_h/items/76f6a0a235e4823d322a)
[AWS SDK for Go S3バケット基本操作](https://qiita.com/nightswinger/items/df6050ea8f8f541360f4)
個人開発向けAWSアカウント作成RTA(2019ver)

# これ何
- お正月にGolangやらで遊ぼうとしたら、個人用AWSアカウントを解約してたの忘れてて、新たに作り直す必要が発生した。
- Tips自体は色々落ちてるが、以下の気持ちになり自分用の手順をまとめたくなった。
  - 個人の責任の範囲内で、要点は抑えつつミニマムな設定で始めたい。
  - 網羅感がないTips群≒都度ググる必要あり
  - **逆に網羅性のある記事はテキスト量が多く読むのがつらい。**
- 基本的には利用経験、アカウント開設経験ありの人向けの覚書とする。
- 全然RTAじゃないけど許して

## 0.アカウント開設～rootアカウントでのログイン
略。
公式UIがよく変わる都合上、作る度に地味にハマるのはご愛敬。

## 1．rootアカウントでやること
### 1-1. rootアカウントのMFA設定
- [x] IAM画面から、MFA設定を行う
  - 最悪これはやらないと怖くて眠れない

### 1-2. Admin権限のIAMユーザ作成
- [x] 自分用IAMユーザ(Admin)の作成
  - **Administrator Access**を直接 or グループを作成してアタッチ。
     - ベストプラクティスは後者だが、私用なら前者で十分。 
- [x] IAMユーザのMFA設定
  - IAMユーザを選択して、認証情報→MFA デバイスの割り当て

### 1-3. 請求周り
- [x] IAM アクセスのアクティブ化
  - コンソール右上のアカウント名→「マイアカウント」→「IAM ユーザー/ロールによる請求情報へのアクセス」
  - これやらないと費用が気になる度にrootアカウントで入り直すことになるので、個人向けでもやった方が良いです。
- [x] 円払いへの切り替え
   - 同じく「マイアカウント」から「お支払い方法」→「お支払通貨の設定」でJPYに変更
   - デフォのドル払いだと外貨取扱手数料(ググると1.63%くらい？)取られるので**かなり大切。**

### 1-4. サポートレベル変更
- [ ] AWS側の障害について問い合わせたい時は開発者サポート\$29/月, 回答早く欲しい場合はビジネス\$100/月
  - 趣味の開発環境が欲しいだけなので私はパス。 

## 2．IAMユーザでやること
### 0. コンソールログイン(with MFA)
- ログインできたら、あとはrootアカウントは解約まで封印できるはず

### 1．コスト管理
- budgetsで請求アラートを設定。
  - 週・日の単位で通知が欲しい場合は別途Lambdaなどで作りこみ。
  - 以下は100円以下で運用したい人の例

|ステップ   |設定|値|覚書  |
|---|---|---|---|
|1 予算タイプの選択  |コスト予算 |-  |-|
|2 予算の設定  |間隔|月別  |最小の間隔。  |
|2 予算の設定  |予算額|$1  |自身が許容できる額の最小。  |
|3 アラートの設定  |アラートのしきい値|予算の80%  |Defaultのまま |
|3 アラートの設定  |連絡電子メール|※メアド  |アクティブに使うアドレスで(知らないうちに破産するので) |

### 2．監査用の御三家
#### CloudTrail
- 手順は一番楽そうなものを。
  - [x] CloudTrailを全リージョン有効化
     - 参考：[Cloud Formationで簡単に全リージョンのCloudTrailを有効化する](https://qiita.com/szk3/items/6b62c8bb8c2ebc549cca)
  - [ ] CloudTrail のデータイベントを有効化。S3のPUT,GET、Lambdaの色々を拾う
     - S3，Lambda周りでデバッグしたい人は。
     - 別途費用かかるのでとりあえずパス
  - [ ] CloudTrail Insightsを有効化
     - お金かかるので、私はGuardDutyに任せます。

#### GuardDuty
※ 個人アカウント利用での予算感が分かっていないので、一月様子を見た後、別途更新予定。 

- 全リージョンで有効化。
  - [x] StackSets用IAM Roleを2個作成。
     - 参考:「[StackSets用IAM Roleのクイック作成リンク作ってみた](https://dev.classmethod.jp/cloud/aws/create-stacksets-iam-role/)」

  - [x] 全リージョンへStacksetする。
     - 参考:「[一発でGuardDutyを全リージョン有効化して通知設定するテンプレート作った](https://dev.classmethod.jp/cloud/aws/set-guardduty-all-region/)」
     - リージョンの指定～の下りはコンソールのUIが変更されてて、「すべてのリージョンを追加」ボタンを押せばOK。
     - 作成まで10分くらいかかる

#### Config
- [x] 個人用アカウントなので、とりあえず有効化をゴールとする。
  - [StackSets](https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacksets)で以下のセッティング

|ステップ   |設定|値|覚書  |
|---|---|---|---|
|1 テンプレートの選択  |前提条件 - テンプレートの準備 |サンプルテンプレートを使用  |-|
|1 テンプレートの選択  |サンプルテンプレートの選択 |AWS Configの有効化  |-|
|2 スタックの詳細を指定  | NotificationEmail |<自分のメアド>  |-|

## 3．fin.
これであとは自由だ。
Cloud9建てて好きなことして遊びましょう。

### RTA的な振り返り
- CloudTrail, GuardDutyもStackSetsのテンプレートにあるので、それで十分かも(やってて気づいた)
- SNSトピックのConfirmはStackSetのスキマ時間で実施しよう。
- 結局記事書きながら作ってたので時間測れてない(笑) 30~長くても60分あればいけるかな。
Rubyの配列の要素をn個の配列へ順繰りに振り分け

配列や範囲オブジェクトなどに対し以下のように動作する **`Enumerable#balance`** を実装したい。ロードバランサーの[**ラウンドロビン方式**](https://ja.wikipedia.org/wiki/ラウンドロビン)みたいな感じ。

```ruby
pp (:A..:Z).balance(7) # 均等にならない場合
#=> [[:A, :H, :O, :V],
#    [:B, :I, :P, :W],
#    [:C, :J, :Q, :X],
#    [:D, :K, :R, :Y],
#    [:E, :L, :S, :Z],
#    [:F, :M, :T],
#    [:G, :N, :U]]

pp (:Α..:Ω).balance(4) # 均等になる場合
#=> [[:Α, :Ε, :Ι, :Ν, :Ρ, :Φ],
#    [:Β, :Ζ, :Κ, :Ξ, :Σ, :Χ],
#    [:Γ, :Η, :Λ, :Ο, :Τ, :Ψ],
#    [:Δ, :Θ, :Μ, :Π, :Υ, :Ω]]

pp [].balance(3) # 空配列の場合
#=> [[], [], []]
```

---

作ったらこうなった。

```ruby
module Enumerable
  def balance(n)
    m = nil
    each_slice(n).to_a.tap do |*, la|
      return Array.new(n) { [] } unless la
      m = la.size
      la[n-1] = la[n-1] # nil padding
    end.transpose.tap do |ta|
      ta.drop(m).each(&:pop) # remove padding
    end
  end
end
```

* 基本戦略は `each_slice(n).to_a.transpose` 。
* しかし、転置 [`Array#transpose`](https://docs.ruby-lang.org/ja/latest/method/Array/i/transpose.html) は各要素の大きさが揃っていることが必要。
* なので転置の前後でパディングの追加と削除を実施する。
	* 転置前は最終行の配列長を他と同じになるよう増やす。（参考：[不足分をnilで埋めた配列を取得](/HMMNRST/items/2d8f190bc6b03614311c)）
	* 転置後は増やした分だけ各行の末端を削る。（※ `#compact` だと元々あったnilまで消してしまう）
* 細かい配列操作は破壊的に行い、なるべく新しいインスタンス生成を抑える。
	* [`Object#tap`](https://docs.ruby-lang.org/ja/latest/method/Object/i/tap.html) が活躍。
* 空配列の転置は都合が悪いので、早めに検知してreturnする。（参考：[空の配列に対するRubyのメソッドの挙動](/HMMNRST/items/43f2c77eab3c62b4eb5a)）

---

無限のリストでも処理できるようにn個のEnumeratorを返すことも考えたが、使い勝手や効率がよくわからないので保留。

```ruby
module Enumerable
  def lazy_balance(n)
    enum = lazy
    Array.new(n) { |i| enum.drop(i).each_slice(n).map(&:first) }
  end
end
```

これは [`Enumerator::Lazy`](https://docs.ruby-lang.org/ja/latest/class/Enumerator=3a=3aLazy.html) の配列を返しているため、最後に各要素を `#force` （ `#to_a` ）すれば最初の例と同じ結果が得られる。

```ruby
pp (:A..:Z).lazy_balance(7).map(&:force)

pp (:Α..:Ω).lazy_balance(4).map(&:force)

pp [].lazy_balance(3).map(&:force)
```
PHP 変数を文字列中で展開する

# 目的

- 変数に格納された内容を文字列中で展開して表示する方法をまとめる

# 書き方の例

- 下記に変数Aに格納された内容を文字列中で展開して表示する処理を記載する。

```php
echo "任意の文字列{$変数A}任意の文字列";
```

# より具体的な書き方の例

- 下記に変数`name`に格納された内容を文字列中で展開して表示する処理を記載する。

```php
//変数に内容の格納
$name = "みりを";

echo "おはようございます{$name}さん";
```
モジュールの初回importにHookして、モジュールパスをprintする

# 初めてのimportにHookして、モジュールパスをprintする

## TL;DR
* Python2.7.14[^1]で、モジュールの**初回Import**後にフックして実行する仕組みが欲しかった。
    * Python3系ではもっとスマートな方法があるはず。
* モジュールの初回Import時に読み込み元のファイルパスを表示するスクリプトを作成した。
* 本内容はAutodesk Mayaとは一切関係がないが、  
MayaやHoudini、Blenderなど、Pythonインタプリタを利用しているツール上であればつきまとう(気がする)問題への、  
一つの答えになりそうなのでタグを付けている。

## モチベーション
* 長く運営が続いたプロジェクトは、内製ツールも増えていく。  
ツールの利用状況を調べることで、不要になったツールをある程度削除することは可能だが、  
ライブラリや設計が悪いと、スクリプトファイルの依存関係の把握すら満足に出来ず、  
消したら何か環境が壊れることを恐れて[^2]、削除できなくなってしまう。
* 不要なスクリプトファイルが増えることで、無駄なファイルの保守や引き継ぎコストが上がってしまうが、人手は足らなくなる一方。
* 初回Import時にHookする仕組みを作り、ファイル単位の利用状況を集計することで、  
不要なスクリプトファイルを発見し、安易に削除できるようにして、無駄なコストを減らしたい。
* ついでにモジュールの読み込み元も把握しておきたい。

[^1]: 正確にはMayaのPythonインタプリタ上で。
[^2]: 検閲済み。


## コード
```firstimport_hook.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import __builtin__
import types
import copy
import sys

import inspect

# reload() 対策のため __import__ がBuiltinFunctionか確認した上で格納する。
if isinstance(__import__, types.BuiltinFunctionType):
    _original__import__ = copy.deepcopy(__import__)

# 他のモジュールでimport hookされている場合などに、
# _original__import__ が定義出来ないので適当にエラーを吐く
elif '_original__import__' not in globals():
    raise ImportError('Definition of _original__import__ failed.')


def __get_modulefile_from_load_module():
    try:
        # 読み込み元のモジュールファイルを取得する
        currentframe = inspect.currentframe()
        module_file = currentframe.f_back.f_back.f_code.co_filename
    finally:
        # 参照カウントを正しくするためにdel。
        del currentframe

    return module_file


def print_modulefile_post_first_import(*args, **kwargs):
    """初回インポート後にモジュールファイルを表示する"""

    # importする前のモジュール読み込み状況を取得
    loaded_module_names = sys.modules.keys()

    # __import__を実行
    module = _original__import__(*args, **kwargs)

    # 既に一度ロードしたことがあったモジュールは処理しない
    if module.__name__ in loaded_module_names:
        return module

    # __file__ がないモジュールのパスは表示しない
    filepath = getattr(module, '__file__', None)
    if filepath:
        path_from_load_module = __get_modulefile_from_load_module()

        print('%s -> %s' % (path_from_load_module, filepath))

    return module


def enable_import_hook():
    """インポートフックを有効にする"""
    __builtin__.__import__ = print_modulefile_post_first_import


def disable_import_hook():
    """インポートフックを無効にする"""
    __builtin__.__import__ = _original__import__


if __name__ == '__main__':
    # importフックを有効にする
    enable_import_hook()

    import json
    reload(json)
```

```startup.py
import firstimport_hook
firstimport_hook.enable_import_hook()
```

## 最後に

これで、Pythonファイルの初回Import時に、読み込んだモジュールのパスがprint()できるようになった。
あとは適当にサーバーに送信すれば集計なども可能だろう。

mel？知らない子ですね……
初心者によるプログラミング学習ログ 198日目

#100日チャレンジの198日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

198日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>198日目<br><br>udemyでjqueryとCSS＋メディアクエリ<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1211392130645553152?ref_src=twsrc%5Etfw">December 29, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
JXAでFinderのカレントパスをiTerm2で開く


前々からJXAに興味があったので、練習がてら書いてみました。
AppleScriptを一から覚えるのは面倒ですが、JXAなら一度勝手が分かれば、スラスラ書けそうな気がします。同様のことをAppleScriptでやる記事は良く見かけますが、JXAでは見かけなかったので、誰かの参考になれば幸いです。

Script Editorで記述したスクリプトは、メニューバーから
`File > Export...`を選択し、File Formatに`Application`を選択して保存。cdtoやgo2shellなどと同様に、Finderのツールバーに配置して利用できます。

## サンプルコード
```js:open-cwd-with-iterm2.js

(function () {
    // iTerm2以外の任意のアプリケーションの実行可能パスも指定可能
    let exePath = "/Applications/iTerm.app/Contents/MacOS/iTerm2";

    let finder  = Application("Finder");
    let frontWindow = finder.windows().filter(function (w) {return w.index() == 1;})[0];
    let cwd = $.NSURL.alloc.initWithString(frontWindow.target().url()).fileSystemRepresentation;
    let app = Application.currentApplication();
    app.includeStandardAdditions = true;
    cmd = `open -a "${exePath}" "${cwd}"`;
    result = app.doShellScript(cmd, {
        administratorPrivileges: false,
        withPrompt: '',
        alteringLineEndings: false
    });
    console.log(result);
})();
```
## 任意のアプリケーションの実行可能パス取得方法

1. Finderで`/Applications`を開く
1. 任意アプリケーション(\*.app)を右クリして`Show Package Content`を選択
1. Contents/MacOS/ の中から実行可能ファイルを見つけ右クリ
1. Optionキーを押下しながら、コンテキストメニューの中から`Copy "XXXX" as Pathname`を選択する

### アプリケーションの実行可能パス例

<table>
    <thea>
        <tr>
            <th>Name</th>
            <th>Path</th>
        </tr>
    </thea>
    <tbody>
        <tr><td>Visual Studio Code</td><td>/System/Volumes/Data/Applications/Visual Studio Code.app/Contents/MacOS/Electron</td></tr>
        <tr><td>Visual Studio Code - Insiders</td><td>/System/Volumes/Data/Applications/Visual Studio Code - Insiders.app/Contents/MacOS/Electron</td></tr>
        <tr><td>Sourcetree</td><td>/System/Volumes/Data/Applications/Sourcetree.app/Contents/MacOS/Sourcetree</td></tr>
        <tr><td>Fork</td><td>/System/Volumes/Data/Applications/Fork.app/Contents/MacOS/Fork</td></tr>
        <tr><td rowspan="2">Sublime Merge</td><td>/System/Volumes/Data/Applications/Sublime Merge.app/Contents/MacOS/sublime_merge</td></tr>
        <td>/System/Volumes/Data/Applications/Sublime Merge.app/Contents/SharedSupport/bin/smerge</td></tr>
        <tr><td rowspan="2">Sublime Text</td><td>/System/Volumes/Data/Applications/Sublime Text.app/Contents/MacOS/Sublime Text</td></tr>
        <tr><td>/System/Volumes/Data/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl</td></tr>
    </tbody>
</table>

## アイコン変更方法

1. Finderで`/Applications`を開く
1. 任意アプリケーション(\*.app)をコピー(Cmd+c)
1. `open-cwd-with-app.app`を右クリして`Get Info`を選択（Cmd+i）
1. 左上のアイコンを選択してペースト(Cmd+v)
富士通PRIMERGY OSインストール 初心者はまりポイント

なんとなく，サーバ機っぽいものを家で動かしたかったので安いのを買ってみたが，はまった．
意外と探しても出てこなかったので，メモとして残しておきます．

# TL;DR
既存のSSDやHDDを入れ替えて，新しくOSをインストールする時は，embedded MegaRAID ドライバに付属する説明pdfをよく読みましょう．
（RAID構成を初期化してから，インストールしましょう）

# はじめに
### 対象とする読み手／私のレベル
- 自作PCを組んだことがある
- Linux系，Unix他，OSをインストールしたことある
- しかし，RAIDを組んだことがない人

### したいこと
- HDD, SSDの換装
- CentOSのインストール

# やったこと
### 問題
一般的なPCや自作マシンに対して，Ubuntuやら，なんやらをインストールする際には，ブートusbを作成すれば，挿し込むだけでなんとかなります．
（BIOS等の設定はともかく）

しかしながら，今回の富士通PRIMERGY（私は中古の型落ちTX150S8を購入）は，それだけでは，なぜかドライブが認識されませんでした．
BIOS上の表示も違うものが表示されていました．

ひとまず，CentOSの入ったusbでインストールを進めてみることにしましたが，インストール先の選択のところでドライブが認識されません．

### 調査
調べる感じでは．基本的に，[富士通のドライバ](ドライバ
https://www.fujitsu.com/jp/products/computing/servers/primergy/software/linux/support/driver.html)から，PRIMERGYのモデルにあったものを探してきて，それでboot usbを作り，そのusbをインストールの途中で使い，手動でドライバのインストールを行えば，できそうですが，自分の場合はそれでもダメでした．
（ここらの辺の流れは，[ここ](http://ottoserver.com/pcserver1/wp/archives/2794)が詳しいです）

### 解決
結局のところ，HDD，SSDを入れ替えた後にRAIDの再構成を行なっていなかったことに起因していました．

そのため，[ここ](https://www.fanatic.co.jp/report/report-271/)を参考にRAIDの構成をしました．
（おそらくモデルでUIは変わるが，やっていることは同じはず）

その結果CentOS v7.7だと（ドライバなしでも）認識されるようになりました．
(MBでRAIDを組めるような物も，この過程が必要なんでしょうかね？)

CentOS v8は，（v7用の）ドライバを使用しても認識せず．
（v8用のドライバが出れば使えるようになる？）

# まとめ
HDD，SSDを入れ替えて，新しくOSをインストールする時は，RAID構成を初期化してから，インストールしましょう．

# 他
地味に（NASなどの楽なものを除くと）RAID初だったので，苦戦した．

他のOSやPRIMERGYのモデルについては，まずここをみる
https://jp.fujitsu.com/platform/server/primergy/software/linux/products/distribution/free-os.html

Embedded MegaRAIDの取説
https://jp.fujitsu.com/platform/server/primergy/manual/peripdf/b7fy-2551-01.pdf
[Scala] シングルトンオブジェクトとコンパニオンオブジェクト

# シングルトンオブジェクトとコンパニオンオブジェクト
> class で宣言したクラスの場合、そこから複数のインスタンスを生成することができますが、object で宣言されたクラスからは、ひとつのインスタンスしか生成することができません。これを **シングルトンオブジェクト** といいます。

特徴としては、

 1. classを定義するようにobjectを定義できる
 1. シングルトンオブジェクトとクラスが同じ名前で定義された時、そのクラスのコンパニオンオブジェクトと呼ぶ
 1. クラスとコンパニオンオブジェクトは、互いに非公開メンバーにアクセスできる

1.について、classの代わりにobjectと定義すればOK。

```scala
scala> object sample {
     |   val s: String = "This is object."
     |   println(s)
     | }
defined object sample
```

↑で、objectを定義して、呼べば"This is object."が出力される。

```scala
scala> sample
This is object.
```

2.について、例えば以下のclassを定義して、同じ名前のobjectを定義すればOK。

```scala
class smaple
object sample // class sample に対するコンパニオンオブジェクト
```

3.について、以下のようなclassとobjectを定義する。

```scala
scala> :paste
// Entering paste mode (ctrl-D to finish)

class info(val publicInfo: String, private val secretInfo: String)
object info {
  def showWeight = {
    val info = new info("height, 186", "Weight, 126")
    println(info.secretInfo)
  }
}

// Exiting paste mode, now interpreting.

defined class info
defined object info
```

class info には、非公開なフィールド(private val) `secretInfo` が含まれているが、定義したコンパニオンオブジェクトからアクセスしている。

確認

```scala
scala> info.showWeight
Weight, 126
```

# 参考
https://docs.scala-lang.org/ja/tour/singleton-objects.html
https://www.amazon.co.jp/dp/B01LYPRFI7/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1