OmniAICreator/Qiita-1.07M huggingface dataset:
Next.js & material UIで[Prop className` did not match`]が発生する

# 問題
Next.jsアプリでmaterial-UIを使用した際に、`[Prop className' did not match' Server 'xx' Client 'xx']`が発生する

### 詳細
- `makeStyles`で作成したスタイルの読み込み時に発生
- 初回レンダリング時には発生しない
- 変更を加えたり、ページ更新を行うと発生する
- `Server 'xx' Client 'xx'`の内容は、`Server "makeStyles-mainContainer-1" Client makeStyles-mainContainer-2`のように、クラス名に違いが生じている

# 解決方法
参照：
[Material UI公式：サーバーサイドレンダリングについて](https://material-ui.com/ja/guides/server-rendering/)
[上記ページからのリンク:Next.jsのサンプルリポジトリ](https://github.com/mui-org/material-ui/tree/master/examples/nextjs)

サンプルリポジトリの通り、`_app.js`と`_document.js`を変更することで解決

```react:pages/_app.js
import React from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
import { ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import theme from '../src/theme';

export default function MyApp(props) {
  const { Component, pageProps } = props;

  React.useEffect(() => {
    // Remove the server-side injected CSS.
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }, []);

  return (
    <React.Fragment>
      <Head>
        <title>My page</title>
        <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
      </Head>
      <ThemeProvider theme={theme}>
        {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
        <CssBaseline />
        <Component {...pageProps} />
      </ThemeProvider>
    </React.Fragment>
  );
}

MyApp.propTypes = {
  Component: PropTypes.elementType.isRequired,
  pageProps: PropTypes.object.isRequired,
};

```

```react:_document.js
import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/core/styles';
import theme from '../src/theme';

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          {/* PWA primary color */}
          <meta name="theme-color" content={theme.palette.primary.main} />
          <link
            rel="stylesheet"
            href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with server-side generation (SSG).
MyDocument.getInitialProps = async (ctx) => {

  // Render app and page and get the context of the page with collected side effects.
  const sheets = new ServerStyleSheets();
  const originalRenderPage = ctx.renderPage;

  ctx.renderPage = () =>
    originalRenderPage({
      enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
    });

  const initialProps = await Document.getInitialProps(ctx);

  return {
    ...initialProps,
    // Styles fragment is rendered after the app and page rendering finish.
    styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
  };
};
```
One-Touch SearchをPython3.7.3で再現する(Windows10)

# One-Touch Searchって何？
ハイライトした文字列をボタンワンクリックでgoogle検索してくれる機能です。
LogicoolのM950というマウスに搭載されている便利機能です。
今回Pythonで再現した理由は、この便利な機能が次の世代のマウスからなくなってしまったからです。

余談ですが、この機能が便利すぎて離れられないためにM950を9年近く使い続けています。途中チャタリングに悩まされましたが、分解して修理して使い続けるくらい便利な機能です。

#プログラムの大枠
1. Pythonでスクリプトを書く。
2. 1をbatファイルで起動できるようにする。
3. 2のショートカットを作成し、ショートカットキーで起動させる。

##1. Pythonのスクリプト
```python
import webbrowser
import pyautogui
import pyperclip
import time

pyautogui.hotkey('alt', 'tab')
time.sleep(0.03)
pyautogui.hotkey('ctrl', 'c')
time.sleep(0.03)
clipboard = pyperclip.paste()
url = 'https://www.google.co.jp/search?hl=ja&q=' + clipboard

webbrowser.open(url)
```
流れとしては、
1. pyautoguiでキーボード入力を行い、ハイライトした文字列をコピー。
2. pyperclipでクリップボードの内容を'clipboard'読み取る。
3. 'url= 'の行でgoogleでの検索用の'url'を作成。
4. webbrowserで標準ブラウザで'url'にアクセス
です。
time.sleep()の部分では、これを入れないと私の環境ではうまくコピーができなかったため入れました。
※ここで作成した.pyファイルにスペースを含めないように注意してください。

##2. batファイルの作成
任意の場所にbatファイルを作成します。
まずは 右クリック＞新規作成＞テキストドキュメント を行ってください。
テキストの内容は

python.exeへのパス（半角スペース）1で作成した.pyへのパス

です。
その後、このテキストファイルの拡張子を.txtから.batに変更してください。
その際に表示される警告は無視して構いません。

##3. batのショートカットを作成し、ホットキーで実行できるようにする。
1. 2で作成した.batファイルを右クリックして、「ショートカットの作成」を選択して下さい。
2. できたショートカットを右クリックして「プロパティ」を選択して下さい。
3. 「ショートカット」のタブを選択し「ショートカットキー」を選択した後、任意のキーの組み合わせ*を押して下さい。
4. 「実行時の大きさ」を「最小化」にすると見栄えが良くなります。
![プロパティ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552205/fb534dd8-946f-1cf2-b0c3-46cdc4125c89.jpeg)

これで出来上がりです。
例ではonetouch.batというファイルを作成し、「Ctl + Shift + Alt + K」でショートカットキーを設定しました。
任意の文字列をハイライトして、3で設定したショートカットキーを押してみて下さい。うまく行けば、google検索できるはずです。
このショートカットキーをマウスのボタンに割り当てればマウスのボタンを押すだけで検索ができます。

#問題点
- ハイライトした文字列の始まりが「#」だとうまく検索できない。
- 純正のOne-Touch Searchより若干遅い。
Hierarchical clustering in Scipy

# Reference

* https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy.cluster.hierarchy.linkage
* https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.cut_tree.html
* https://www.haya-programming.com/entry/2019/02/11/035943
* https://www.haya-programming.com/entry/2019/02/16/214750

# Preparation

```
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.rcParams['font.size']=15

def plt_legend_out(frameon=True):
    plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, frameon=frameon)
```

```
from scipy.spatial.distance import pdist
from scipy.spatial.distance import squareform
from scipy.cluster.hierarchy import centroid, fcluster
from scipy.cluster.hierarchy import cut_tree
```

# Data

以下のa,b,cを分類することを考えます。

```
df = pd.DataFrame({'x':[1,2,2],'y':[1,1,3],'name':['a','b','c']})

sns.scatterplot(data=df,x='x',y='y',hue='name')
plt_legend_out()
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/2bff0ecf-8e61-7b2d-5e9a-6f978949cbe8.png)

# Main

距離行列を計算します。

```
>>> y = pdist(df[['x','y']])
>>> y
array([1.        , 2.23606798, 2.        ])
```

上記の行列は、以下の距離行列の省略形です。

```
df_plot = pd.DataFrame(squareform(pdist(df[['x','y']])))

df_plot.columns = df['name'].values
df_plot.index   = df['name'].values
df_plot
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/cddcf873-5a63-5789-166d-64ee238dfe63.png)

averageをとってクラスタリングします。

```
>>> Z = linkage(y, method='average')
>>> Z
array([[0.        , 1.        , 1.        , 2.        ],
       [2.        , 3.        , 2.11803399, 3.        ]])
```

0.9と1.1がクラスタ数の境目です。

```
dendrogram(Z,labels=df['name'].values)
plt.axhline(1.1,color='gray',ls='dashed')
plt.axhline(0.9,color='gray',ls='dashed')
plt.ylabel('distance')
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/62d67a2f-90ec-1364-d4f5-49a035908d51.png)

距離に1.1を指定するとクラスタ数は2になり、0.9を指定するとクラスタ数は3になります。

```
>>> fcluster(Z, 1.1, criterion='distance')
array([1, 1, 2], dtype=int32)
```

```
>>> fcluster(Z, 0.9, criterion='distance')
array([1, 2, 3], dtype=int32)
```

cut_treeでクラスタ数を指定することも可能です。

```
>>> cut_tree(Z, n_clusters=2)
array([[0],
       [0],
       [1]])
```

（省略）

```
sns.scatterplot(data=df,x='x',y='y',hue='name')
plt.scatter(df['x'].mean(),df['y'].mean(),label='center',color='k')
plt_legend_out()
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/62024dda-2150-e1de-6147-76aa1cc5e069.png)
インフラ基本知識①

###LAN(Local Area Network)
LANとは、狭い範囲でのネットワークのこと。

###WAN(Wide Area Network)
WANとは、LANとLANをつなげて広範囲に繋げたネットワークのこと。

###プロバイダ(ISP:Internet Service Provider)
通信事業者のこと。世界中のネットワークをTCP/IP技術で相互接続している。

###イントラネット
社内のネットワークのこと。

###エクストラネット
イントラネットとイントラネットを繋げたネットワークのこと。

###サーバ・クライアントモデル
自身が保有するアプリケーションサービスを提供するコンピュータをサーバという。サーバが保有するアプリケーションサービスを利用する側をクライアントという。

###バイナリーデータ
2進数で表現された0と1だけのデータのこと。符号化（エンコード）とは、文字コードを見てバイナリーデータに変換すること。復号化（デコード）とは、バイナリーデータから文字コードを見て人が理解できる文字に変換すること。受信する側で文字コードが送信側と違うと文字化けが起きる。

###帯域幅
通信速度のこと。1秒間に何bit送ることができるかを表す単位を「bps(bits per second)」という。5bpsと13bpsなら、１秒間に13個の１か０のデータを送れるから13bpsの方が通信速度が早いと言える。またバイトとは重さを表し、1バイトは8ビットで表現される。100バイトなら800ビット分のデータを相手に送ったということ。

###通信障害
輻輳（ふくそう）とは、大量のデータ通信が原因でネットワークが混雑し、データ通信が困難になること。
ジッタとは、信号が想定より早すぎたり遅すぎたりして相手に送信され、映像や音声の乱れに繋がる。

###ノードとリンク
ノードとは、ネットワーク機器のこと（コンピュータ、プリンタやルータ）。リンクとはノードとノードの通り道のこと（ケーブルや電話機線）。

###通信の種類
ユニキャストとは、一つのノードにのみ通信すること（1:1）。ブロードキャストとは、同じネットワークにいるノード全てと通信すること(1:全て)。マルチキャストとは、複数のノードをグループにしてそこのグループに対して通信すること(1:特定のグループ)。
UbuntuでEFIだとmemtest86+が起動しない

# 概要

`memtest86+` がパッケージにインストールされてるんですけど、grubのメニューに出てこないから、おかしいなと思ったら、こいつEFIに対応してないやんけ！
しかたないからmemtest86をefiのパーティションにいれて、起動させた話です。

# コマンドたち

## とりあえずmemtest86を落としてきて、マウントする
```bash
$ wget https://www.memtest86.com/downloads/memtest86-usb.zip
$ unzip memtest86-usb.zip
$ sudo mkdir -p /mnt
$ sudo mount -o loop,offset=$((514048*512)) memtest86-usb.img /mnt/
$ cd /mnt
$ find
.
./EFI
./EFI/BOOT
./EFI/BOOT/mt86.png
./EFI/BOOT/BOOTX64.efi
./EFI/BOOT/BOOTIA32.efi
./EFI/BOOT/Benchmark
./EFI/BOOT/unifont.bin
./EFI/BOOT/blacklist.cfg
./help
./help/MemTest86_User_Guide_UEFI.pdf
./license.rtf
```

## EFIのパーティションにmemtestを入れる

```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev             15G     0   15G   0% /dev
tmpfs           3.0G  1.8M  3.0G   1% /run
/dev/nvme0n1p2  916G  8.9G  860G   2% /
tmpfs            15G     0   15G   0% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs            15G     0   15G   0% /sys/fs/cgroup
/dev/nvme0n1p1  511M  7.8M  504M   2% /boot/efi
…省略…

$ sudo mkdir /boot/efi/EFI/memtest
$ sudo cp -r EFI/BOOT/* /boot/efi/EFI/memtest
```

## efiのboot設定にmemtestを追加する

```
$ efibootmgr -v
BootCurrent: 0001
Timeout: 0 seconds
BootOrder: 0001,0006,0007,0005,0004,0000
Boot0000* Windows Boot Manager	VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}....................
Boot0001* ubuntu	HD(1,GPT,aa80d35d-d60d-449d-8c36-2427e797b23b,0x800,0x100000)/File(\EFI\UBUNTU\SHIMX64.EFI)
Boot0004* Generic Usb Device	VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)
Boot0005* CD/DVD Device	VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)
Boot0006* UEFI: PXE IPV4 Realtek PCIe GBE Family Controller	PciRoot(0x0)/Pci(0x1,0x6)/Pci(0x0,0x0)/MAC(6c4b90ddb3a2,0)/IPv4(0.0.0.00.0.0.0,0,0)..BO
Boot0007* UEFI: PXE IPV6 Realtek PCIe GBE Family Controller	PciRoot(0x0)/Pci(0x1,0x6)/Pci(0x0,0x0)/MAC(6c4b90ddb3a2,0)/IPv6([::]:<->[::]:,0,0)..BO
$ sudo efibootmgr -c --disk /dev/nvme0n1p1 --part 1 --loader /EFI/memtest/BOOTX64.efi --label "memtest"
$ sudo efibootmgr -o 1,2,6,7,5,4,0
```

## 再起動したらmemtestが起動するようにする

```
$ sudo efibootmgr -n 2
```

で、再起動すれば、memtestが起動します。
さぁ、一晩動かそう。


# 参考にした

というか、diskの位置以外はほぼ同じことしてます。
- http://pyopyopyo.hatenablog.com/entry/20160528/p1
Arduinoでシリアルに文字列を送信してシリアルに表示する



![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) シリアルに文字列を送ってシリアルに表示するだけ

##やること
ArduinoでSerial.readStringUntil()を使うサンプルです。
このコマンドのおかげでコードが短くできます。

##スケッチ

```c++:Arduino系

String A;

void setup() {
  Serial.begin(9600);//シリアル通信を開く
}

void loop() {
  if (Serial.available() > 0 ) { //「> 0」はなくても動く
    //シリアルデータを改行記号が現れるまでAに文字列として読み込む
    //0x0aは改行記号
    A = Serial.readStringUntil(0x0a);
    Serial.println(A);//それをシリアルに表示する
  }
}
```

### 使い方
実行してシリアルモニタから何か送信すると、それが画面にそのまま返されます。
Ubuntuでお手軽に機械学習（Python）の環境構築

# はじめに
何番煎じかはわかりませんが、Ubuntuに新規で機械学習（Python）環境を構築した際のメモを残します。
システム（Ubuntu）にプリインストールされているPythonを用いて、**最小限のインストールでお手軽に環境構築したい方向け**です。
環境：Ubuntu 20.04 LTS

# Python, pip, venvのインストール
Ubuntu 20.04 LTSの通常ディストリビューションであれば、Python3はプリインストールされているはずです。
念のため、ターミナルに以下を入力し、確認しておきます。

```shell:ターミナル
python3 -V               
Python 3.8.2

# インストールされていない場合
sudo apt install python3
```
次に、各種ライブラリのインストールに必要となるpipをインストールします。

```shell:ターミナル
sudo apt install python3-pip

# インストールの確認
pip3 --version
```

システムで使用しているPythonにライブラリを直でインストールすることは、最悪システムを壊してしまうこともあり、おすすめできません。
そこで、仮想環境を構築し、ライブラリのインストールがシステムの依存環境などに影響を与えないようにします。
UbuntuプリインストールのPythonでvenvを使用するには下記インストールが必要になります。

```shell:ターミナル
sudo apt install python3-venv
```

# 仮想環境の作成と有効化

ライブラリをインストールする前に仮想環境を作成しておきます。

```shell:ターミナル
# ホームディレクトリ内.venvフォルダにMLという仮想環境を作成
python3 -m venv .venv/ML
```

下記を実行し、作成した仮想環境を有効化します。

```shell:ターミナル
cd .venv/ML
source bin/activate

# 無効化する際は下記を実行
deactivate
```
# ライブラリのインストール

仮想環境内にライブラリをインストールしていきます。
下記はscikit-learn, matplotlib, pandasを一括でインストールする例です。

```shell:ターミナル
pip3 install -U scikit-learn ,matplotlib, pandas
```

※Matplotlibでプロットの表示`plt.show()`をした際に下記のようなエラーが出る場合があります。

> UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.

Python上でUIの描画に必要なTkinterがインストールされていないためです。
合わせてインストールしておくといいです。

```shell:ターミナル
sudo apt install python3-tk
```

以上で環境構築は終了です。

# 追記

VSCodeでコーディングする場合は、先ほど作成した仮想環境をデフォルトのインタプリタに設定しておくと便利です。
Settings.jsonに下記を追加しておくと、自動的に仮想環境を有効化してプログラムを実行してくれます。

```json:Settings.json
"python.defaultInterpreterPath": "/home/$USERNAME/.venv/ML/bin/python3",
```
Resolve error: No valid exports main found for /node_modules/colorette の解決法

Vue.js書いていてコミットしようとしたら、 `vue-cli-service lint` で怒られた。

```
✖ vue-cli-service lint found some errors. Please fix them and try committing again.
Error resolving webpackConfig Error: No valid exports main found for '/path/to/project/node_modules/colorette'
```

なんのこっちゃ・・・と思って調べたら、Node.jsのバージョンが古いのが問題らしい。
`v13.5.0` でした。

別PCで作ったプロジェクトをクローンしたときに、差異が発生したのだろうか。

nvmが入っていたので、[この記事](https://phoenixnap.com/kb/update-node-js-version)を参考にバージョン上げ。

```
nvm ls-remote
```

で最新バージョンを確認。

```
nvm install v14.7.0
```

で最新バージョンをインストール。

プロジェクト内の `node_modules` を削除し、改めてパッケージをインストール。

```
npm install
```

無事、コミットできるようになりました:v:
Goを使ってコマンドプロンプト(cmd)のコマンドを実行

## GoはPythonみたいに使えてしかも環境に合わせたバイナリを作成してくれるやばい言語

最近Goにはまっていまして単純なことをしようとしてもちょっと詰まったりしたので
備忘録としてここに残しておきます。

## Goを使ってコマンドプロンプト(cmd)のコマンドを実行
以下で実行できます。あらかじめcmdを**「cmd /C」**しておくところがポイントです。

``` go
package main

import (
    "fmt"
    "os/exec"
	"time"
	"log"
)

func main() {
	out, err := exec.Command("cmd", "/C", "echo hello > test.txt").Output()
	if err != nil {
		log.Fatal(err)
	}else{
		fmt.Println(out)
	}
}
```

## 改訂履歴
- 2020/8/10 新規作成
Goのfyneで日本語を文字化けさせない手っ取り早い方法

## fyneでサンプルアプリを動かそうとしたら文字化けに遭遇

GOについて暇さえあれば勉強している私です。将来的にはGUIのアプリで設定ファイルを作成するものを製作し会社のサービスとして提供する予定です。

そのためによいGUIのライブラリはないかと探していたところ[fyne](https://github.com/fyne-io/fyne)を見つけました

早速以下のようなサンプルを以下の環境で作ったところフォントが文字化けしました。

- OS：Windows10
- Go：go version go1.14.7 windows/amd64

``` go
package main

import (
	"fyne.io/fyne/widget"
	"fyne.io/fyne/app"
)

func main() {
	app := app.New()

	w := app.NewWindow("こんにちは")
	w.SetContent(widget.NewVBox(
		widget.NewLabel("こんにちは Fyne!"),
		widget.NewButton("Quit", func() {
			app.Quit()
		}),
	))

	w.ShowAndRun()
}
```

解決方法としては環境変数**FYNE_FONT**を設定すればいいそうです。

以下のように設定しました。

``` cmd
set FYNE_FONT=C:\Windows\Fonts\meiryo.ttc
```

これで普通に文字化けせずに表示されます。

Goはやっぱりすごいです。Flutterも覚えればデスクトップ、モバイル共に環境に左右されないアプリ製作がはかどりそうです。

## 改訂履歴

- 2020/8/10 新規作成
Numpy行列をLatex用に出力

#目標
普通にnumpyのndarrayをprintすると

```
[[ 9.999e+00 -1.000e-03 -1.000e-03]
 [-1.000e-03  9.999e+00 -1.000e-03]
 [-1.000e-03 -1.000e-03  9.999e+00]]
```

のようになる。
このndarrayをlatexでコンパイルできる形に出力させたい。
つまり、このndarrayを与えれば、

```latex

\begin{pmatrix}
    \ 9.999 & -0.001 & -0.001 \\
    -0.001 & \ 9.999 & -0.001 \\
    -0.001 & -0.001 & \ 9.999 \\
\end{pmatrix}
```
みたいな出力をする関数を作る。こればあれば

![mat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257157/22c4e058-6113-d778-e2b1-8b7686d29c3b.png)

ができる

```latex
\documentclass[12pt]{article}
\usepackage{amsmath}
\begin{document}
\begin{align*}
\begin{pmatrix}
    \ 9.999 & -0.001 & -0.001 \\
    -0.001 & \ 9.999 & -0.001 \\
    -0.001 & -0.001 & \ 9.999 \\
\end{pmatrix}
\end{align*}
\end{document}
```
#作り方

まず、行列の行数と列の数は、numpy.array.shapeでtupleとして取得できる。
tupleに(行数、列数)として入っているのでこれをそれぞれ変数に入れる。
[5. データ構造 — Python 3.8.5 ドキュメント ](https://docs.python.org/ja/3/tutorial/datastructures.html#tuples-and-sequences)



```python 
import numpy as np
matrix = np.ones((3,3))
 _, max_column = matrix.shape
```

今回は行数は使わないので、使わないという意味を込めて_と言う変数として書いた。

#作った関数

```python
def str_2dmatrix_latex(matrix, indent=4, digit=3, env="pmatrix"):
    r"""
    Convert 2d matrix to str for latex.
    *In your latex preset, you must add
    amsmath

    Parameters
    ----------
    matrix : numpy.ndarray
        2d matrix
    indent : int
        indent width
        if indent is -1, indent become tab
    digit : int
        digit=2 0.11
        digit=3 0.111
    env : str
        env is inserted ... in \begin{...}
        and \end{...}

    Return
    ------
    str
    """
    _, max_column = matrix.shape
    if indent == -1:
        str_indent = "\t"
    else:
        str_indent = " " * indent
    list_str = []
    list_str.append(r"\begin{" + f"{env}" + "}\n")
    for row in matrix:
        for j, elem in enumerate(row):
            str_elem = f"{elem:.{digit}f}"
            # format
            if elem > 0:
                str_elem = r"\ " + str_elem
            # write matrix element
            if j == 0:
                list_str.append(str_indent + str_elem + " & ")
            elif j == max_column - 1:
                list_str.append(str_elem + r" \\" + "\n")
            else:
                list_str.append(str_elem + " & ")
    list_str.append(r"\end{" + f"{env}" + "}\n")
    return "".join(list_str)


def main():
    one_mat = np.ones((3, 3))
    """
     1 1 1
     1 1 1
     1 1 1
    """
    id_mat = np.eye(3)
    """
     1 0 0
     0 1 0
     0 0 1
    """
    mat = 10 * id_mat - 0.001 * one_mat
    print(str_2dmatrix_latex(mat))


if __name__ == "__main__":
    main()

```

実行結果

```
\begin{pmatrix}
    \ 9.999 & -0.001 & -0.001 \\
    -0.001 & \ 9.999 & -0.001 \\
    -0.001 & -0.001 & \ 9.999 \\
\end{pmatrix}
```
Windows 10 HomeにDocher Toolboxを入れようとして沼にはまった...

#はじめに
[こちらの記事](https://qiita.com/idani/items/fb7681d79eeb48c05144)を参考にDocker Toolboxをインストールしていました。
著者様、わかりやすい記事をありがとうございますm(_ _)m
記事を見た感じ大変な作業はないように思えましたが、記事にはないエラーが発生しました...

#Checking Status on defaultでエラー
[Dockerの公式サイトから](https://docs.docker.com/toolbox/toolbox_install_windows/)インストーラーを入手。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372182/eff038c5-347f-29a1-b084-6ecd7f576fb0.png">

その後、Docker Quickstart Terminalを起動すると、**Checking Status on default**でエラーが出ました。
このエラーを解消するのは簡単で、Windowsの**Virtual Machine Platform**を無効化すればいいです。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372182/1c337107-0156-5bd8-6503-d8161ea2c4ec.png">
**コントロールパネル->プログラム->Windowsの機能の有効化または無効化**からの**Virtual Machine Platform**を無効化すると、Docker Toolbox実行環境が整った！
とはならず、今度はSetting envでエラーがでました...

#Setting envでエラー
結論としては**SETXをbashで実行できなかったせいでした**。
エラーの原因がわからずDocker Quickstart Terminalを実行したときに動いているコードを見ることにしました（Docker Toolboxのインストール先に指定したファイルの中のstart.sh 79行目から）

```shell
STEP="Setting env"
eval "$("${DOCKER_MACHINE}" env --shell=bash --no-proxy "${VM}" | sed -e "s/export/SETX/g" | sed -e "s/=/ /g")" &> /dev/null #for persistent Environment Variables, available in next sessions
eval "$("${DOCKER_MACHINE}" env --shell=bash --no-proxy "${VM}")" #for transient Environment Variables, available in current session
```

自分はShell Scriptの知識が全くなかったので、書かれてある単語をちまちま調べることになりました。
いろいろ試した結果、**STEXをbashで実行できていないことが判明！**
代わりに**set**を使って環境変数を指定すればいいのではと思い書き換えてみる。

```shell
eval "$("${DOCKER_MACHINE}" env --shell=bash --no-proxy "${VM}" | sed -e "s/export/SETX/g" | sed -e "s/=/ /g")" &> /dev/null
↓
eval "$("${DOCKER_MACHINE}" env --shell=bash --no-proxy "${VM}" | sed -e "s/export/set/g")" &> /dev/null 
```
そして、Docker Quickstart Terminalを起動すると...
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372182/eed790b7-f28e-e2d5-7aa9-581c05be7f26.png">
クジラちゃん出てきてくれました^^
hello worldも正しく動いてくれましたので、Docker Toolboxの実行環境を無事構築することができました。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372182/ecdbe65d-8626-e9a3-ceb8-db03bea641c9.png">

#おわりに
Dockerってほとんどgolangで作られてるそうですね。
golangを理解してないと解消できないエラーとかじゃなくてよかったです。
別の機会にぜひ学びたいですね。
Eclipseプラグイン・プロジェクトでJavaのクラスのメソッド・パラメータの名前をリフレクションで取得できない時の暫定対応メモ

Java8以降、クラスのコンストラクタを含むメソッドのパラメータ名をリフレクションを通して取得できるようになりました。`javac`に`-parameters`オプションを追加してコンパイルすることで、これに必要な情報がクラスファイルに格納されます。

Eclipseにおいては、例えばJavaプロジェクトの場合、プロジェクト共通あるいはプロジェクト毎の設定において、以下のチェックを入れてエクスポートすることで、対応したjarを作成することができます。恐らく、チェックすることで、`-parameters`オプションが内部で設定されてコンパイルされるのだろうと思います。
<img width="500" alt="eclipse-setting.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457466/a947733b-6763-8479-0125-3abf53ac0003.png"/>
簡略ですが、以下のような感じでコンストラクタやメソッドオブジェクトへの参照からリフレクションを使って、パラメータ名を確認することができます。

```java
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
    System.out.println("constructor: " + constructor.getName());
    for (Parameter param : constructor.getParameters()) {
        System.out.println("  param: " + param.getName() + ", type: " + param.getType().getSimpleName());
    }
}
```
```java
for (Method method : clazz.getDeclaredMethods()) {
    System.out.println("method: " + method.getName());
    for (Parameter param : method.getParameters()) {
        System.out.println("  param: " + param.getName() + ", type: " + param.getType().getSimpleName());
    }
}
```
## 問題の症状
ところが、プラグイン・プロジェクトの場合、何故か、この設定が機能していないようで、エクスポートして作成した`jar`(というかバンドル)では、メソッドのパラメータ名は、`arg0, arg1, arg2…`となります。このような名前は、`-parameters`オプションを指定しない場合に、自動的に付けられるものです。なお、使用しているEclipse IDEは、`Version: 2020-06 (4.16.0) Build id: 20200615-1200`です。(多分、最新)


このことから、プラグイン・プロジェクトの場合、チェックを入れても、実際には`-paramters`オプションが使用されずにコンパイルされているように見えます。なお、チェックを入れると、以下のファイルに次の一行が追加されます。

<プロジェクト>/.settings/org.eclipse.jdt.core.prefs
```
org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
```
この設定が入ったプロジェクトでエクスポートすることで、メソッドのパラメータ名をリフレクションで取得可能な`jar`が作成されることが期待されます。

プラグイン・プロジェクトの場合、バンドルの依存関係を明示した`MANIFEST.MF`を作成して、手軽にOSGiバンドルを作成できて重宝なのですが、今回の件は、かなり不便に感じました。

## 暫定対応
そこで、一旦、プラグイン・プロジェクトで作成した、バンドルの依存関係を解決した`MANIFEST.MF`の雛形を、別途、そのプラグイン・プロジェクトと同一ソースのJavaプロジェクトを起こして、そこから参照させてOSGiバンドルを作成することにしました。(安易ですが)

以上、備忘録でした。(何か誤解しているかも？)
【Flutter】数値かどうかを調べる

Flutterで、数字または数値形式の文字列であるかを調べる。

# 書き方

```dart:sample.dart
  double.tryParse(input) != null;
```
tryParseについて
https://api.flutter.dev/flutter/dart-core/int/tryParse.html

## 検証
| 入力値            |　結果              |   
|:-----------------|------------------:|
| 123              |            true   |
| +123             |              true |
| -123             |              true |
| 123.456               |           true |
| 1,234             |             false |
| hoge          |           false |
| null          |           false |
| 123x             |             false |
browser-syncでAPIをproxyする

# 始めに
ローカルでの開発でAPIのCORSを回避するためにproxyを通すことがあると思いますが、webpack-dev-serverを使うと簡単に設定することができます。また、検索にも引っ掛かりやすいのでつまづいたら調べることができます。

```webpack.config.js
devServer: {
  proxy: {
    '/api': {
      target: 'https://hogehoge.com',
      changeOrigin: true,
    },
  },
}
```

しかしbrowser-syncを使ったパターンになると中々記事がない上、browser-syncで使用するパラメータの`proxy`はwebpack-dev-serverとは違った意味で使われるため中々使い方が分かりませんでした。なのでその辺についてここでまとめたいと思います。

## browser-syncで設定するproxyの勘違い
browser-syncで設定するproxyはwebpack-dev-serverと違って**ローカルサーバーのhostnameを指定する**ものになっています。`localhost`ではなく`hogehoge.com`でアクセスできるようにするとかですね。あんまりどういう目的で使用するのか分かりませんが・・・。
なのでAPIを別なサーバーへproxyしたいときとかには使用できないです😓

# browser-syncでAPIをproxyする方法
proxyオプションで設定できないのでどうするかと言うと、proxy用のmiddlewareを差し込みます。
具体的にはhttp-proxy-middlewareを使用して以下のようにしました。
ちなみにwebpack-dev-serverもこのパッケージを使用しているので設定方法は同じになると思います。
https://webpack.js.org/configuration/dev-server/#devserverproxy

```script.js
const browserSync = require('browser-sync');
const { createProxyMiddleware } = require('http-proxy-middleware');

const bs = browserSync.create();

bs.init({
  server: {
    baseDir: './src',
    middleware: [
      createProxyMiddleware('/api', {
        target: 'https://qiita.com/',
        // Basic認証がある場合はユーザ名とパスワードをコロンでつなげると自動で認証してくれる
        // auth: 'username:password',
        changeOrigin: true,
      }),
    ],
  },
  watch: true,
  ghostMode: false,
});
```

あとは普通にbrowser-syncで立ち上げたサーバーにAPIリクエストしたらproxyしてくれます。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Proxy Test</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
</head>
<body>
  <p>proxy test</p>
  <script>
    axios.get('/api/v2/items')
      .then((response) => {
        console.log(response.data);
      });
  </script>
</body>
</html>
```

# 終わりに
以上がbrowser-syncでAPIをproxyする方法でした。普段の開発ではwebpack-dev-serverでproxyするでいいと思いますが、webpackすらいらない場合の開発やビルド済みのファイルでローカルで動作確認する際にbrowser-syncでproxyする方法は役立つかなと思いました。
以下にサンプルのリポジトリも載せますので、興味がある方は見てください。

+ [サンプルリポジトリ](https://github.com/wintyo/test-proxy-browser-sync)

## 参考URL
+ [BrowserSyncの使い方でハマったこと](https://wp.tekapo.com/2014/08/13/how-to-use-browsersync/)
+ [Gulp browser-sync-プロキシ経由でAPIリクエストをリダイレクト](https://www.it-swarm.dev/ja/api/gulp-browsersync%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E7%B5%8C%E7%94%B1%E3%81%A7api%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%92%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88/1048012800/)
SAMLによって、GoogleアカウントでAWSマネジメントコンソールにSSOログインする

# 前置き
AWSには、IAM Userというユーザー管理機能があり、AWSアカウント内でユーザー管理することも可能です。
しかし、G Suiteを使っている環境において、メンバーが増えるたびに、Googleアカウントを発行したり、AWS IAMユーザーを発行したりするには、工数が発生するとともに、漏洩のリスクも増やしてしまいます。
そこで、SSOにより、GoogleアカウントにてAWSアカウントにログインできるようにしてみます。

AWSおよびGoogle（G Suite）には、これをSAML経由で簡単に実現できるようにしてくれています。

ここでの詳細な説明は割愛しますが、SAML環境は、IdP（認証をつかさどる）とSP（サービス提供）によって構成されます。
ここでは、G SuiteがIdP、AWSがSPとなります。
構成図としては、AWSドキュメントのSSO関連のいたるところでみる、以下がわかりやすいです。
<img width="772" alt="G Suite アカウントを用いた AWS へのシングルサインオン | AWS Startup ブログ 2020-08-10 14-48-00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/a155a8aa-e63a-19c4-8896-28eb37edbc90.png">

なお、図では「AWS SSO Endpoint」と表記がありますが、今回の手順では、「AWS SSO」は利用しません。
より詳細なコントロールが必要な際などに、「AWS SSO」を利用することになります（最後のまとめにも記載）。

# 前置き２
だいたい、このサイトの手順どおりで実現できます。しかし、いくつか現在（2020/8/10）の環境では差異があるため、手順どおりに進めていく上での留意点を補足する形で、以降の手順を記載します。
https://support.google.com/a/answer/6194963?hl=en

# Stepごとの補足ポイント
## Before you begin

以下の手順において、表記されているようなリンクは見つけられませんでした。
しかしながら、ユーザーリスト右上の「More」に、「Manage Custom Attribute」という、両者を混ぜ合わせたようなリンクから、手順を実行できました。

> 3 At the top of Users list, click Manage user attributes User attributes.
> 4 At the top right, click Add Custom Attribute.

ちょいちょいこの手の差異はあったような気もしますが、Googleに限らず、Web UI上の表記が微妙にアップデートされ、公式の手順書と差異があることはままあります。

## Step 4: Enable the Amazon Web Services app

正直、英語で読んでも日本語で読んでも、ここで書いている文が言語として難解でした :(

また、これだけではStep 5の検証をとおすのに、不十分に思えます。
検証するユーザー（Chromeを使っているならログイン中のユーザーアカウント）にて、ロールを設定しておかねばなりません(Step 6相当の準備)。

Step 2でAWS側に準備しておいたロール群(※)の出番です。
(※) 以下の２つの形式のもの。 
- arn:aws:iam::ACCOUNT_NUMBER:role/SSO
- arn:aws:iam::ACCOUNT_NUMBER:saml-provider/GoogleApps

G Suiteのユーザー一覧から、検証したいユーザーのリンクを開きます。
「User Information」を開くと、「Amazon」という項目が見つけられると思います。また、この時点では、Roleは未設定の状態になっているかと思います。
このロールを編集し、Step 2で作成したロールの２つのARNを、カンマ区切りで設定します。

これで、Step 5での検証や、Google Appsから、AWSマネジメントコンソールにログインすることが可能になったかと思われます :)

# まとめ
個人的には、ユーザーへのロールの設定が罠になるかと思いますが、それ以外については手順は丁寧で、SAMLやSSOについて、あまり理解していなくても表題の実現が可能かと思いますが、SSOの仕組みを自分で手を動かして動かすことで、理解が深まることもあるかと思います。

今回実施した手段は、AWSアカウントとGoogleアカウントそれぞれで設定しました。
複数のAWSアカウントを扱ったりしていったり、ユーザー数が増えて行ったりと、ビジネスが成長していく上でこの手順では厳しくなってきます。
AWS SSOなどを利用した仕組みを構築する必要があります。

また、そのあたりの記事も書けたらと思います。
Flaskでエラー　OSError: [Errno 98] Address already in use

##現象
Flaskアプリケーションを作成中、サーバーを起動したまま何度もモジュールを修正していると、標題のエラーが発生した。

###エラーメッセージ
```bash
OSError: [Errno 98] Address already in use
```
メッセージのままだけど、「利用しようとしているアドレスはすでにほかで使ってるから今は使えないよ」ということらしい。
こういう場合はポートが埋まってるんだろうと当たりをつけてエラーメッセージを検索する。

検索した結果以下の記事がでヒットした。
https://qiita.com/ringCurrent/items/2413c795372baa7b479d

エラー番号が「48」と「98」で違うけど、おそらく環境差異なので気にせず解決方法を実行していく。

1.「lsof」コマンドのインストール
lsofコマンドで使用中のポートを確認するらしいが、使用しているdocker環境には入ってないみたい。

```
(base) root@e8cf64ce12e9:/home/continuumio# lsof -i :5000
bash: lsof: command not found
```

さくっとインストールする。(OSがubuntuなのでaptを使用)

```
(base) root@e8cf64ce12e9:/home/continuumio# apt install lsof
Reading package lists... Done
```

2.重複しているポートの確認
重複して利用しているポートを確認する。対象のポートはFlaskの起動時に指定しているのでコードを確認する。

```main.py
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000, debug=True)
```

lsofコマンドでポート5000を使っているプロセスを確認
(-i オプションで対象を限定しないと大量に抽出されるため注意)

```bash
(base) root@e8cf64ce12e9:/home/continuumio# lsof -i :5000
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
python  881 root    4u  IPv4 237229      0t0  TCP *:5000 (LISTEN)
python  901 root    4u  IPv4 237229      0t0  TCP *:5000 (LISTEN)
python  901 root    5u  IPv4 237229      0t0  TCP *:5000 (LISTEN)
```

3.抽出された一覧から不要なプロセスを終了させる。

- kill　終了コマンド。物騒な名前。
- -9　強制終了
- :xxxx　ポート番号

詳細は「man コマンド」で確認

```bash
(base) root@e8cf64ce12e9:/home/continuumio# kill -9 901
```

以上
Web Design Trends 2020

Websites and web-related resources are becoming an integral part of our daily lives. So as demand for web design skills increases — a lot of us may still not know what exactly is web design. In simple words, It is an art of planning and designing websites from scratch. There are a number of small aspects that fall under the wider web development umbrella, such as website architecture, user interface and user experience, webpage layout, navigation, colors, fonts, and overall graphics. With the combination of all these, web designers are busy creating masterpieces that absolutely stand out in the crowd.

Let’s dig right into <a href="https://www.sphinx-solution.com/blog/web-design-trends-2020/">web design trends 2020</a>. These trends are the perfect blend of visual designing and emerging technologies. 

1) Use of Whitespace and Simplistic/Minimalist Design
It’s often said that simplicity attracts more than complexity, The minimalist trend in web design has become popular today, The best thing about this design trend is that while it continuously evolves and looks modern and classy. 

2) Dark Theme Design
The dark theme is a buzz word in the market as many businesses integrate dark mode themes on their website. This mode of web design not only looks ultra-modern but also easily attracts colours and design elements to the eyes. Dark themes are suitable for OLED screens as they help in saving power and increasing screen duration. 

3) Retro Styled or Vintage Web Design
The retro era is back, this year, we are going to experience the early 50s, and 60s inspired vintage or retro style websites as the latest trends in web design. Many designers use effects that remind us of the vintage period, such as faded colors, black-and-white photos, classic images, vintage typography, etc. 

4) Combination of Illustration and Photos
We are witnessing another stunning trend in web design, where photos or images combine with a simple hand-drawn 2D sketch. It’s a well-known fact that custom illustration is an excellent way to highlight your brand.

5) Data Visualization in Web Design
Data visualizations look creative, appealing, useful, and never misleading. Designers are creators of visuals. Many people understand visual information better than text information. Data visualization is an effective way of quantitative representation data visually.



After considering every factor, we can say this year we would witness some significant development by the <a href="https://www.sphinx-solution.com/web-development/">web design companies</a>. The fusion of two or more technologies will be trending. 



This blog was originally published on <a href="https://www.sphinx-solution.com/blog/">Sphinx Solutions</a>.
Github ActionsでGoのCI環境を作成する

# はじめに
みなさんCIしてますか？
ちなみに僕はCIは大好きですが、それの環境構築をするのは大嫌いです。
毎回細かい設定をしたり、ごちゃごちゃといろんなことをやらなければいけないのは本当に憂鬱です。
ということで今回は新しくサービスを作成するときに必要であろうGoのアプリケーションのCIをGithub Actionsで簡単にやりたいと思います!

# Github Actionsについて簡単に、、、
Github ActionsはGitHubが2019年11月に正式に公開したGitHub上のリポジトリやイシューに対するさまざまな操作をトリガーとしてあらかじめ定義しておいた処理を実行できる機能です。
これまでの

- Circle CI
- Jenkins

の兄弟みたいな物だと思ってもらえるといいと思います！

またGithub Actionsは `.github/workflows/`配下にymlファイルを作成することで処理を実行してくれます

```
├── .github
│   └── workflows
│       └── ci.yml
```


# 今回のゴール

今回はあくまで最低限のci環境を構築するだけなのでやることは

- buildできる 
- lintを通す
- testを通す

この3つだけです!
もちろんこのあとDockerHubにあげたり、リリースまで行ったりと、やれることはたくさんあると思いますがいったん今回は省略です。

# Actionを実行するファイルの実装
```yaml:ci.yml
name: go-ci

on: [push]

jobs:
  # 共通処理
  setup:
    runs-on: ubuntu-latest
    steps:
      - name: set up
        uses: actions/setup-go@v2
        with:
          go-version: ^1.13
        id: go
      - name: check out
        uses: actions/checkout@v2
      
      # 処理を高速化するために環境をキャッシュ
      - name: Cache
        uses: actions/cache@v2.1.0
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-

  # buildテスト
  build:
    needs: setup
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: build
        run: go build ./...

  # testを通す
  test:
    needs: setup
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: test
        run: go test ./... -v

  # lintを通す
  lint:
    needs: setup
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v2
        with:
          version: v1.29
```

パッと見かなりいろんなパラメータがあって０から全てを作っていくのはとても難しそうなイメージがありますが、、、
実はそんなことありません。Github Actionsは既にかなりの数のテンプレートが存在するので基本的にそれらのテンプレを組み合わせるだけです。
（上記のコードもほぼそれらのテンプレートをそのまま使っています。）

具体的には、、、
`# 共通処理` -> [setup-go](https://github.com/actions/setup-go)
`# 処理を高速化するために環境をキャッシュ` -> [actions/cache](https://github.com/actions/cache/blob/main/examples.md#go---modules)
`# lintを通す` -> [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action#how-to-use)

を参考にしています。
（build, test処理はGoの標準コマンドを活用しているので省略します）

上記actionsでやってることとしては、、、
`# 共通処理`となってるところでgoの環境のセットアップ
↓
共通処理終了後`build`, `test`, `lint`の処理を並行で実行 

というような感じです

<img width="841" alt="スクリーンショット 2020-08-10 18.02.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/5d1192df-1552-a8e0-63b4-b6432c9c6248.png">
最終的にプルリクエストを出したときにこのようにワークフローが回っていることが確認できれば成功です！


# おわりに
Github Actionsがリリースされてからまだ日が浅いこともありベストプラクティスが確立されてないところや、OSSのスター数がどれも少ないところなど多少不安な点もありつつもCIをもGithub内で完結できるのはとても魅力的ですし、他のCIツールを使ったことがある方であれば学習コストもほとんどかからないと思うので、１度は触った方がいいのかなと思っています。
PHPの配列は値が変更されるまで複製されないことの確認

PHPの配列は擬似基本型
---

PHPにおいて配列はオブジェクトのような参照型ではなく
数値や文字列と同じように基本型のように振る舞う

しかし内部的には参照型であり
値が変更されることで値が複製されることによって
あたかも基本型であるような振る舞いをしているだけである


確認
---

まずは大きめの配列を作って
同じ配列を10回別の配列に追加してみる

```php
<?php
echo "first:".(memory_get_usage()>>8)."KB<br/>";
$arr = [];
for($i=0;$i<10000;$i++) {
    $arr[] = $i;
}
$arr2=[];
for($i=0;$i<10;$i++) {
    $arr2[$i] = $arr;
}
echo "now:".(memory_get_usage()>>8)."KB<br/>";
echo "peak:".(memory_get_peak_usage()>>8)."KB";
/*
結果
first:1553KB
now:3620KB
peak:3620KB
*/
```

別の配列に追加する数を10回から100回に増やしてみる

```php
<?php
echo "first:".(memory_get_usage()>>8)."KB<br/>";
$arr = [];
for($i=0;$i<10000;$i++) {
    $arr[] = $i;
}
$arr2=[];
for($i=0;$i<10;$i++) {
    $arr2[$i] = $arr;
}
echo "now:".(memory_get_usage()>>8)."KB<br/>";
echo "peak:".(memory_get_peak_usage()>>8)."KB";
/*
結果
first:1553KB
now:3649KB
peak:3649KB
*/
```

10回：3620KB
100回：3649KB

ほとんど変動がない

次に別の配列に値を変更しながら100回追加してみる

```php
echo "first:".(memory_get_usage()>>8)."KB<br/>";
$arr = [];
for($i=0;$i<10000;$i++) {
    $arr[] = $i;
}
$arr2=[];
for($i=0;$i<100;$i++) {
    $arr2[$i] = $arr;
    $arr2[$i][0]++;
}
echo "now:".(memory_get_usage()>>8)."KB<br/>";
echo "peak:".(memory_get_peak_usage()>>8)."KB";
/*
結果
first:1554KB
now:210072KB
peak:210072KB
*/
```
変更せずに100回：3649KB
変更しながら100回：210072KB

劇的にメモリ使用量が増えた


つまり何？
---

PHPのメモリの節約のためには無用に配列の値を変更することを避けるべきである
値を加工するなら取り出してからやったほうが良い

```php
function hoge($huge_array){
  $huge_array['value'] = some_modify($huge_array['value']);
}

↓

function hoge($huge_array){
  $value = some_modify($huge_array['value']);
}
```

PHPで配列が複製されるのを防ぐために参照変数を用いることは無意味である
値を変更しさえしなければ配列は複製されない

```php
function hoge(&$array){
 ...
}

↓

function hoge($array){
 ...
}
```
ObnizOS Wifi ステルス プロキシ設定を試してみる

# 概要
M5Stick BasicでセキュアーにWiFi接続して、インターネットにアクセスできそうなので、24時間計測しているマイクロビット等の取得データをアップしたい。
そのための、第一弾として、M5StickにObnizOSをインストールして、セキュアーにWiFi接続させてみました。
このページは、その忘備録です。

- micro:bitやArduinoなどで取得したデータをシリアル通信でマイコンに出力して、マイコン側でインターネットに接続することをずっと考えていました。
- ラズパイで簡単に実現できるのですが、ラズパイはれっきとしたコンピュータなので、起動やシャットダウンなど気になることが多くて、マイコンでなんとかしたいと思っていました。



# 再開しました。

- 前回の問題は、どうも一発イントールコマンドでは、デバイス認証が上手くいっていないことが原因のようです。
- そのため、以下のサイトを参考にして、直接サイトからデバイスキーを受け取って、完了できました。
- https://www.hivoki.com/install-obnizos/
- ↑このページの情報で直接デバイスキーを書き込んでインストール完成
- インストール後は、ターミナル画面の支持に従いWifi設定をした。
- ステルスも設定できるし、Proxyも設定でき、コネクト成功までたどり着きました。

# ObnizOSのインストールから

- [ObnizOS概要](https://obniz.io/ja/doc/reference/obnizos-for-esp32/overview)
- 今回はM5Stack Basicを使ってみる
- [公式ページ：M5Stack Basic](https://obniz.io/ja/doc/reference/m5stack/)
- [Qiitaページ:公式サポートされた M5Stack + M5StickC 用obnizOSをインストールしてみよう！](https://qiita.com/wamisnet/items/b154f0e696c1d57caf1c)
- node.js v14.7 をmacOS Catalinaにinstall.
- 参考にしたサイト[MacにNode.jsをインストール](https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09)

# ObnizOSでWifiの設定

 - [非公開 (シークレット) SSID に obnizで接続しよう](https://qiita.com/wamisnet/items/3b91b6bedc77ac7d0e1c)
 - 上記、詳細ページがリンク切れ

# ホームページ

[簡単マイコン教室 micro:bit 大好き！おっちゃん先生のホームページ](https://qiita.com/tmdoi/items/61be444e1879912aa2a5)
【Swift】オプショナル束縛構文の使い方

###1.はじめに
---
前回オプショナル型の基本についての記事を書きましたが、今回はオプショナル型を実装するうえで、コードを読みやすく、スマートに書くことができる、オプショナル束縛構文について解説しようと思います。
前回の記事はこちらです。
(https://qiita.com/0901_yasyun/items/d64986bdfe917d90382c)

###2.オプショナル束縛構文とは
---
まず以下のif文の条件を見てください。

```swift:
let year : Int? = Int("2000")   
if let y = year {       //ここのif文の書き方に注目
    print("ハレー彗星は\(y + 61)年に来る")
}else{
    print("エラー")
}
```

この条件の書き方は、if文とwhile文の条件部にのみ記述することができる、特別な構文です。これを**オプショナル構文**、または**if-let文**と呼びます。
このコードだと、もし変数yearがnilではない値を持っていたら、if文の条件判定は真となります。

###3.コードを書く上でのメリット
---
通常通りであれば、まずオプショナル型の式の値がnilなのかどうかをチェックし、その後にまったくの別で、その値を使用したコードを書いていくことになります。

しかしこの書き方を使うことで、オプショナル型の式の値がnilではなかった場合、その値をチェックしたif文のthen節で、そのまま使うことができます。

###4.オプショナル束縛構文の使い方
---
基本的な構文の使い方は、2で示したコードの通りです。
気を付けることとしては、2のコードにおいてyearの値がnilであれば、if文の条件は偽でelse節が実行されますが、その場合定数yはelse節では使うことができません。

オプショナル束縛構文の条件が成立した場合、条件部で定義された変数などはthen節でしか参照することはできません。これを利用してこの変数などに、元のオプショナル型の変数などと同じ名前を使うことができます。以下のコードを見てください。

```swift:
let halley : Int? = Int("2000") //定数halleyはInt?型
if var halley = halley {        //変数halleyはInt型であり、then節内でのみ有効
    print("ハレー彗星は\(halley)年に来た")
    halley += 61
    print("次は\(halley)年だと予想される")
}
```

なお、先ほども述べましたが、オプショナル束縛はif文やwhile文の条件部に記述したときのみ、特別な意味を持つので注意してください。

###5.オプショナル束縛と条件式
---
複数のオプショナル型の値を使って処理を行いたい場合、if-let文をネストすることもできますが、カンマで区切って複数の条件を並べることができます。以下のコードを見てください。

```swift:
if let sapporo = Int("1972"), let nagano = Int("1998") {
    print("\(nagano - sapporo) years.")
}
```

オプショナル型の値だけでなく、その他の条件もカンマで区切って記述することができます。

```swift:
var nagano = 1998
if nagano < 2000, let tokyo = Int("2020"), tokyo > nagano {
    print("\(tokyo - nagano)")     //22と出力される
}
```

条件を複数書いた場合、このコードだとnaganoが2000未満の場合のみ、カンマの右側のオプショナル束縛の評価に進みます。オプショナル式がnilではなかった場合、定数tokyoにInt型の値が代入され、さらに右の条件式が評価されます。

このように、一番左側から条件の評価が始まり、条件式が偽になるか、オプショナル式がnilだった時点で評価は終了し、ifの条件は偽となります。
また、左側で値が代入された定数や変数を、右側の式で使うこともできます。

###おわりに
---
今回はコードをきれいに書く上で必須ともいえる、オプショナル束縛構文の使い方について解説しました。コードの可読性を高めることは、自分の書いたコードを世の中に発信する際にとても重要なことなので、ぜひこの書き方を利用してみてください。
Twitterマーケティング？自動化しちゃば？

この頃、サービスをリリースした阿部です。
過剰なタイトルをつけたものの、マーケティングがわからなく四苦八苦です。
とりあえず、RubyでTwitter運用を始めたので、そのナレッジを記載します。
（始めたばかりで成果のほどは不明。）

Twitter運用めんどくさい。。
僕、Rubyエンジニアでツイッタラーじゃないんだけど（怒）
簡単に運用する方法ないの？
って人向けの記事です。

サンプルはRubyで記載しています。

## アジェンダ
- どうやって自動化した？
- Twitter Rest APIとは？
- RubyのTwitter REST APIの導入方法
- 実際にどんな運用をしているか
- まとめ

## どうやって自動化した？
僕は、[Twitter Rest API](http://westplain.sakura.ne.jp/sub/translate/twitter/Documentation/REST-APIs/Public-API/REST-APIs.cgi)を使って自動化しました。

## Twitter Rest APIとは？
名前の通り、Twitterが提供しているAPIです。
このAPIを呼び出すことによって、
ツイートやリツイートなどのTwitter上の処理を、プログラムから実行することができます。

RubyにはこのTwitter Rest APIを簡単に呼び出せるgemがあるので、
恩恵に預かりましょう。
https://github.com/sferik/twitter

各APIの概要、パラメーターなどを知りたい場合は下のリファレンスを参照してください。
わかりやすくまとめられています。
https://rdoc.info/gems/twitter/Twitter/REST

## Twitter REST APIの導入方法
#### アカウント作成
まずはTwitter開発者アカウントを作成します。
僕はこちらの記事を参考にしました。
https://qiita.com/kngsym2018/items/2524d21455aac111cdee

英語で連絡しなければいけないので少々手間ですが、
気合で乗り越えてください。



#### 実装

Clientを作成するクラスを実装しましょう。
ClientがTwitterAPIを呼び出す各メソッドを持っています。
Clientを作成してメソッドを呼び出せば、
ツイートやリツイートなどの処理をプログラムから呼び出すことが可能です。

```twitter-wrapper.rb
require 'twitter'
class TwitterWrapper
  attr_accessor :client

  def initialize
    @client = Twitter::REST::Client.new do |config|
      config.consumer_key = ENV["TWITTER_API_KEY"]
      config.consumer_secret = ENV["TWITTER_API_SECRET"]
      config.access_token = ENV["TWITTER_ACCESS_TOKEN"]
      config.access_token_secret = ENV["TWITTER_ACCESS_TOKEN_SECRET"]
    end
  end

  def tweet(content:, option: {})
    @client.update(content, option)
  end

  def tweet_with_media(content:, images: , option: {})
    @client.update_with_media(content, images, option)
  end

  def retweets(tweet_id: nil)
    @client.retweet(tweet_id)
  end

end

```

今回、設定はconfig/twitter.ymlに配置しましたが、好きなところに配置してください。
Twitter::REST::ClientをNewする際に、それぞれの値を正しく入力できれば問題ないです。
twitter-wrapper.rbには今回説明するメソッドしか記載していませんが、
他にもたくさんメソッドがあるので[ドキュメント](https://rdoc.info/gems/twitter/Twitter/REST/)で確認してみると面白いと思います。

## 実際にどんな運用をしているのか
僕は以下の運用を行っています。

- コンテンツが投稿されたタイミングでツイートする
- 一定時間ごとに自分のツイートをリツイートする

#### コンテンツが投稿されたタイミングツイートする
コンテンツが投稿された時、tweetを呼び出しています。
ツイートAPIを呼び出すupdate_with_mediaのラップメソッド（tweet_with_media）を実行しているだけです。
今回は画像も一緒にツイートしたかったので、update_with_mediaを使っています。
画像が不要な場合は、updateメソッドを使えば大丈夫です。

```tweet.rb
  class Tweet < Twitters::Application
    def tweet(content)
      tweet_wrapper = TwitterWrapper.new
      content = content #ツイート内容
      images  = 【画像】 # Array<File>
      tweet_wrapper.tweet_wrapper.tweet_with_media(content: content, images: images)
    end
  end
```

#### 一定時間ごとに自分のリツイートする
cronで下記処理を呼び出しています。
ただ、すでにリツイートしているツイートを再度リツイートしようとするとエラーを吐きます。
処理を追加してあげたほうが優しいと思います。

```retweet.rb
tweet_wrapper = TwitterWrapper.new

tweet_wrapper.search('アカウント名').each do |tweet|
  user_name = tweet.user.screen_name

  return false if !user_name.include?('アカウント名')

  tweet_wrapper.retweets(tweet_id: tweet_id)
end

```

## まとめ
上記は僕がパパッと考えたやり方なので、もっと洗練できると思います。
こんなやり方、書き方あるよって方はコメントいただければ幸いです！

良き、Twitterライフを！
試験 AZ-900: Microsoft Azure Fundamentalsの受験記録

[この記事](https://qiita.com/allforbigfire/items/68dfe2e2a5b682bf70d1)に書いたように、
業務時間中に Microsoft Azure Virtual Training Day:Fundamentals を受講させていただきました。
(次回開催日程の詳細は、[Azure のイベント 地域のイベント情報の確認](https://azure.microsoft.com/ja-jp/community/events/)を参照ください。)

従来とは違って、「バウチャーレスになった」と案内がありました。

#####申し込み時のハマりポイント
オンライン研修から5営業日して、AZ-900試験を申し込むため「Pearson VUEでスケジュール」を押下。
表示されたサイト内で、研修を申し込んだ会社メールアドレスを入力します。システムから認証メールが来ます。
その後、Microsoft認定試験の登録メールアドレスと会社メールアドレスを紐づける操作をします。無事に完了すると、Pearson VUEの最初の画面でバウチャーを適用させる項目が表示されます。ここで申し込む操作をしないと、せっかくのバウチャー割引が適用されません。
申し込み手順の要領が分からず、何度も途中まで申し込み操作をしました。(画面キャプチャできれば良かったのですが。)

#####勉強の方法
Microsoft Learnの「ラーニング パス > Azure の基礎」は終わったので、続いて[「ラーニング パス > 試験 AZ-900: Microsoft Azure Fundamentals」](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900)をやっていって研修で聞いた内容を脳に定着させるぞ、といざ始める段階である事に気が付きました。

<img width="235" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/7c0d9621-2d2f-ba6b-14ca-6ce925da3cd2.png"><img width="239" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/b1f28271-3fa3-b227-e4ca-24c43e0e2767.png">

**なぜトレーニングの中身が英語なんですか？:scream:**

<img width="772" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/3772f9f2-a46c-2563-819b-812a1dc20dc1.png">

**このモジュールは、まもなく次の言語で使用できるようになります: 日本語。**

そういう事は早く知りたかったです。

唯一のテキスト [合格対策 Microsoft認定 AZ-900:Microsoft Azure Fundamentalsテキスト&問題集](https://www.amazon.co.jp/%E5%90%88%E6%A0%BC%E5%AF%BE%E7%AD%96-Microsoft%E8%AA%8D%E5%AE%9A-AZ-900-Microsoft-Fundamentals%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88/dp/4865942319)を一読後に、章末問題、模擬問題を一通り解きました。

※　出版社のサイトに、新傾向の問題解説PDFがアップロードされていました。確認しておいて良かったです。

この時点で、試験当日の早朝なので、睡魔でフラフラでした。

#####試験結果

![IMG_4463.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/0d50f943-e4b9-2927-5e55-428bb2be069f.jpeg)

合格点 700点の試験で、740点を取ったのでギリギリで合格しました。

#####感想
お盆休みで浮かれすぎて、準備不足でした。
「合格」ではあるので、これで安心して会社に報告できます。

次のステップとしては、AWS認定クラウドプラクティショナーを受験すると思います。
Rubyで3桁区切り表示を実現する

#３桁区切の表示にしたい場合
1. to_s(:delimited)メソッドを使用する
2. 上記メソッドを使用するために、ファイル先頭にrequireを追加する  
active_supportはRuby on Railsのコンポーネントで色んなメソッドを使えるようにするもの

````ruby:num.rb
require "active_support/core_ext/numeric/conversions"

10000.to_s(:delimited)
# => "10,000"
````


詳細はRailsガイドのActive Supportページに記載有（6.3 書式設定）
https://railsguides.jp/active_support_core_extensions.html#%E6%9B%B8%E5%BC%8F%E8%A8%AD%E5%AE%9A


#あとがき
私は３桁表示方法を探していた時
「.to_s(:delimited)メソッドで数値を３桁区切にできるらしい！」と喜んで使用したところ
requireが必要だとは知らず、以下エラーに遭遇。

````
in `to_s': no implicit conversion of Symbol into Integer (TypeError)
````
to_sは正常に使用できるのに、(:delimited)を追加するとエラーが発生して困りました。
そのため、 to_s(:delimited)メソッドをrubyで使用する場合はactive_support を有効にするrequireが必須です。

この機会にactive_supportの他の便利なメソッドも学習し、活用していきたいと思います。
【AWS】S3で静的ホスティングしてRoute53でルーティングする

# はじめに
最近、Route53でドメインを作成してみたので、試しに、S3の静的ホスティングを試してみようと思いました。　

# 方法

## S3のバケットを静的ホスティング設定する

### S3バケットの作成
まず、S3のバケットを作成します。
> ※バケット名は、ドメイン名と同じ名前でないと正しくルーティングされません。

作成時にパブリックアクセスをブロックするか聞かれますが、チェックを外して、ブロックしないように設定してください。

### 静的ホスティングの設定
作成が完了したら、当該バケットのプロパティページを開いて、`Static website hosting`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401878/18fc652f-6d62-55e4-0c94-ef5b3eca8e57.png)

`このバケットを使用してウェブサイトをホスティングする`を選択します。
そして、今回は「インデックスドキュメント」のみ設定します。
`index.html`と入力して、`保存`ボタンをクリックします。

### バケットポリシーの作成
静的配信を行うために、設定を行う必要があります。
バケットのアクセス権限のタブを開いて下記の設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401878/176ae68f-48ce-eb3e-cdeb-64f9ecb71415.png)


```json:設定するバケットポリシー
 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::ここにバケット名を記載/*"
            ]
        }
    ]
}
```
リソースの`"arn:aws:s3:::ここにバケット名を記載/*"`の部分は自分のバケット名に変更してください。


### index.htmlの作成

アクセスされた際に表示される、「index.html」ファイルを作成します。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<head>
    <title>ウェブサイトのホームページ</title>
</head>
<body>
  <h1>ようこそ！</h1>
  <p>S3で静的ホスティング!</p>
</body>
</html>
```

オブジェクトをアップしたら、正しく静的配信されているか確認してみましょう。
下記のように表示されていた場合は、正しく設定出来ています！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401878/f8af55e8-060d-f65a-a1f7-8a180a542bca.png)

## Route53でルーティングを設定

AWSマネジメントコンソールでRoute53のページを開き、左のメニューからホストゾーンを選択します。
ルーティングを行いたいドメイン名を選択します。

> ※ドメインを取得していない、場合は、取得してください。

### レコードの作成

`レコードの作成`をクリックします。

今回は、`シンプルルーティング`を選択します。
その後、`シンプルなレコードを定義`をクリックします。


今回は、サブドメインを設定するわけでは無いので、`レコード名`は空白にします。

`値/トラフィックのルーティング先`は「S3ウェブサイトエンドポイントへのエイリアス」を選択します。
その次に、リージョンはS3のバケットを作成したリージョンを選択します。
選択できるバケットが存在する場合は、プルダウンに表示されるので、選択します。

`レコードタイプ`は「A - IPv4アドレスと一部のAWSリソースにトラフィックをルーティングします。」を選択します。
今回、`ターゲットのヘルスを評価`は不要なので、チェックを外します。

レコードの情報を入力する事ができれば、右下の`レコードを作成`をクリックします。

# 最後に
設定が完了したら、先ほど登録したレコード名にアクセスしてみましょう！

S3のindex.htmlの内容が表示されると思います！

これで、S3で簡単にウェブページをホスティングする事ができました！
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylibエラーの対処法

npmを久々に実行しようとしたら、以下のエラーで使えなくなっていましたので、使えるようにする備忘録です。

```
$ npm -g install パッケージ名
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib
  Referenced from: /usr/local/bin/node
  Reason: image not found
zsh: abort      npm -g install パッケージ名
```

## nodeを再インストール

```shell
$ brew reinstall node
```

僕はHomebrewでnodeをインストールしていましたので、`reinstall`でnodeを再インストールすると解決しました。


## 環境

- macOS Catalina 10.15.5
- Homebrew 2.4.9
- Node.js 14.7.0


## 参考

- [npmのエラー解決「dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.60.dylib」](https://qiita.com/SuguruOoki/items/3f4fb307861fcedda7a5)