OmniAICreator/Qiita-1.07M huggingface dataset:
SwiftUI で UITextField を使ってマークされたテキストを無視する

iOSアプリ開発中に SwiftUI の TextField で日本語入力したときに、テキストがうまく入力できない場合があって困りました。
とりあえず、UITextField で回避する方法を書いておきます。

## 準備

- Xcode 11.5 

## UITextField と代用する

`SwiftUI.TextField` の入力がおかしいときは、マークされたテキストのときに起こっているようだったので、そのときの入力だけ無視するように UITextField を代わりに使って実装します。
※ マークされたテキストは、日本語のような `multistage text input` のときに起きるそうです。

- https://developer.apple.com/documentation/uikit/uitextinput/1614489-markedtextrange

UITextField を UIViewRepresentableでラップしつつ、SwiftUI.TextField と同じようなインターフェイスが取れるようにしてます。


```swift
import Combine
import SwiftUI
import UIKit

struct MyTextField: UIViewRepresentable {
  private var placeholder: String
  @Binding private var text: String
  private var textField = UITextField()

  init(_ placeholder: String, text: Binding<String>) {
    self.placeholder = placeholder
    self._text = text
  }

  func makeCoordinator() -> Coordinator {
    Coordinator(textField: self.textField, text: self._text)
  }

  func makeUIView(context: Context) -> UITextField {
    textField.placeholder = self.placeholder
    return textField
  }

  func updateUIView(_ uiView: UITextField, context: Context) {
    uiView.text = self.$text.wrappedValue
  }

  class Coordinator: NSObject {
    private var dispose = Set<AnyCancellable>()
    @Binding var text: String

    init(textField: UITextField, text: Binding<String>) {
      self._text = text
      super.init()
      textField.delegate = self
      NotificationCenter.default
        .publisher(for: UITextField.textDidChangeNotification, object: textField)
        .compactMap { $0.object as? UITextField }
        .filter { $0.markedTextRange == nil } // マークされたテキストを無視する
        .compactMap { $0.text }
        .receive(on: RunLoop.main)
        .assign(to: \.text, on: self)
        .store(in: &dispose)
    }
  }
}

extension MyTextField.Coordinator: UITextFieldDelegate {
  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
  }
}
```

## 使い方

```swift
struct MyTextField_Previews: PreviewProvider {
    struct ContentView: View {
      @State var text: String = ""

      var body: some View {
        VStack {
          Text(self.text)
            .foregroundColor(.red).padding()
          MyTextField("placeholder", text: self.$text)
            .frame(height: 28).padding()
          Button(action: { self.text = "" }) {
            Text("Clear")
          }
        }
      }
    }

    static var previews: some View {
      ContentView()
    }
}
```

上記の `MyTextField` は `SwiftUI.TextField` と同じように使えるので、そのうち、バージョンアップで修正されたらすぐ差し替えられます。
ただし、`@State` の `text` には変換中のテキスト（マークされているときのテキスト）は入ってきませんが、変換が決定したときにバインドされます。
とりあえずひとつの解決策としてありかなと思います。
NanoPi NEO2にAipo8(グループウエア）をインストールする方法

#### 1. はじめに####
Aipo公式サイトではインストーラ版の配布が終了していますが、ネットで探すとインストーラ版が見つかります。同時アクセスが少ない環境であればAipo8をNanopi NEO2で動作させることができますので、インストール方法を紹介します。 

#### 2. 前提ソフトのインストール####

```
#apt update   
#apt upgrade
#apt-get install nmap lsof unzip libreadline-dev zlib1g-dev
#apt-get install openjdk-8-jre
```

#### 3. Aipo8インストーラのダウンロード ####
aipo-8.1.1-linux-x64.tar.gzのファイル名で検索をかけてダウンロードしてください。
NanopiのCPUはIntelやAMDじゃないって。心配無用です。

#### 4. Aipoの展開 ####
aipo-8.1.1-linux-x64.tar.gzの場所はどこでもいいのですが、rootユーザのホームディレクトリーにあるという想定で進めます。

```
#cd 
#tar -zxvf aipo-8.1.1-linux-x64.tar.gz
```

#### 5. スクリプトの修正 ####
```
#cd 
#cd aipo-8.1.1-linux-x64/bin
```
validate.shをエディタで開き、68行目あたりのlsofの行のsbinの部分をbinに書き換えて保存。
変更前）/usr/sbin/lsof 
変更後）/usr/bin/lsof 

```
#cd ~/aipo-8.1.1-linux-x64
```
installer.sh をエディタで開き、/shの部分をすべて/bashに書き換えて保存。（5ヶ所くらい）

#### 6. Aipoのインストール ####
```
#cd ~/aipo-8.1.1-linux-x64
#chmod 755 installer.sh
#bash ./installer.sh
```
インストールが終了するまで30分くらい待ちます。

#### 7. シェルの修正 ####
```
#cd /usr/local/aipo/tomcat/bin/
```
catalina.shをエディタで開き、次のように書き換えて保存
（215行目あたり）
　　JAVA_ENDORSED_DIRS='cygpath --path --windows "$JAVA_ENDORSED_DIRS"'の行を削除
（シェルの中の次の文字列をすべて削除(10ヶ所くらい）
    `-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS"` 

```
#cd /usr/local/aipo/conf
```
Intel用のJREは動作しませんので、Armbin用のJREにするために、jre.confを次のように修正します。
(修正前）JAVA_HOME=/usr/local/aipo/jre
(修正後）JAVA_HOME=JAVA_HOME=/usr/lib/jvm/java-8-openjdk-arm64/jre

#### 8. Aipoの起動 ####

```
#cd /usr/local/aipo/bin
#./startup.sh
```
#### 9. Aipoへのログイン ####
ブラウザを起動して
http://(NanopiのIDアドレス）
ユーザID:admin
パスワード:admin

以上
for文の多重ループ

#多重ループが理解しにくい

こんにちは、徳永です

今回はfor文を使った多重ループの概念が難しかったので
復習も兼ねて書き留めておく

まず最初に出会ったのは

ドットインストールにて
[『phpを使ってビンゴゲームを作ろう』](https://dotinstall.com/lessons/bingo_php_v2)
要は以下のような表示をHTMLで表示させてみようといったものだ

<img width="802" alt="スクリーンショット 2020-06-06 23.29.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598309/1813a4f9-7767-787a-e868-1339a5809c53.png">

ちなみに表示のさせかたは、かなり端折ってはいるが

```php:

for ($i = 0; $i < 5; $i++) {
    for ($j = 0; $j <= 5; $j++) {
        //ランダムな数値を生成する処理
    }
    echo PHP_EOL;
}

```


$i = 行

$j = 列

を表示させている

一番わかりやすかったやり方は
$iを一気に5回ループさせるのではなく
まずは一回だけループさせてみる

そうすると上段１行だけ表示されるのがわかる

なるほど・・・・
＄iの１回のループで＄jを5回繰り返し、それを＄i for文で5回繰り返しているのだな
ということが分かった

##まとめ

非常にややこしくて、頭の中で整理がつきにくい処理は
まず一番小さな数値を試しに代入してみて
そこから一つずつ増やして順を追っていけば、理解もしやすいのではないだろうか

急がば回れということわざがあるが
これはまさに今回の事例にぴったりのことわざであった



最後までみていただきありがとうございます！

Twitterもやっていますのでよかったらフォローお願いします！
[＠tokuppee15](https://twitter.com/tokuppee15)
Azure Private Linkを使ってExpressRoute(Private Peering)経由でSQL Databaseに接続する

サービスエンドポイントという機能は、vNetに配置されたAzure VMからSQL Databaseへの通信時に、インターネットに出ずにMicrosoftネットワーク内で閉じたアクセス（ルーティング）が可能です。あくまでもルーティングなので、SQL DatabaseにはプライベートIPは付与されません。

Private Linkでは、SQL DatabaseにvNet内のプライベートIPを割り当てることができるため、オンプレからExpress Route(Private Peering)経由で直接アクセスが可能です。

最近Azureの様々なサービスがPrivate Linkに正式対応し始めました。
今回はオンプレからExpress Route(Private Peering)経由でSQL Databaseに繋いでみましょう。

# 前提
* Express Route(Private Peering)接続されたvNetが存在すること
* SQL Databaseが作成されていること

# Private Link(プライベートエンドポイント)を作成する
* SQL Serverの左バーより[プライベートエンドポイント接続]を選択します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/a4e06305-5c18-464c-426d-e63f3c6fb5da.png)

* [+プライベートエンドポイント]を選択します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/3807d430-def1-48da-6368-c8e0a9085544.png)

* [名前]、[地域]を入力します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/4b56bbea-fdf2-a07b-f14b-f5e6c974816e.png)

* リソースの種類に[Microsoft.sql/servers]を選択し、対象リソースを選びます。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/a2cead3e-2b3b-b9fe-91a9-91a5a2294482.png)

* ExpressRoute(PrivatePeering)接続されたvNetを選択します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/fdbec0b9-eefd-35d7-ee79-781a4f424177.png)

* ここまで入力してプライベートエンドポイントを作成します。  
* 数分でプライベートエンドポイントが作られます。ちゃんとプライベートIPが振られてますね。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/074d17a3-c9e2-1b7a-5789-a9e18597ec1f.png)

# 接続確認
## 自分のPCから

* 自PCから名前解決できているのか確認してみます。

```
$ ping kwhr-private-sql.database.windows.net
cr2.japaneast1-a.control.database.windows.net [13.78.61.196]に ping を送信しています
```

* パブリックIPを引いてきてますね。独自DNSに設定すればよいのですが、今回は環境がないため、hostsで上書きしてみます。

```
$ ping kwhr-private-sql.database.windows.net
kwhr-private-sql.database.windows.net [10.10.2.116]に ping を送信しています
```

* プライベートIPに変わりました。この状態でSSMSで接続したところ問題なく接続できました。

* ちなみに、SQL Server側ではパブリックネットワークアクセスは拒否しているため、Private Link経由でアクセスしていることが分かります。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/0b7a19f5-7246-3283-348e-ba05864d7f0b.png)

## 同一vNetから

* 同一vNetの異なるサブネットからはどうでしょうか。

```
$ ping kwhr-private-sql.database.windows.net
PING kwhr-private-sql.privatelink.database.windows.net (10.10.2.116)
```

* 今度はhosts設定していませんが、名前解決できています。これは、Azure内のプライベートDNSが効いているからですね。

以上
Google Colaboratoryで「!pip install pyspark」が実行可能

# Goole ColaboratoryでPysparkを始める方法
以下のコードによりpysaprkのモジュールを使えるようになる。

```python

!pip install pyspark
import pyspark
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate() 
spark
```
## 参考
今までは<a href="https://qiita.com/hiehara/items/43d740074827eb736462">こちら</a>の記事に書いてあるコードをコピペしてsparkを使っていました。
しかし、2020年6月5日の午後に実行すると、<a href="https://stackoverflow.com/questions/62198911/not-able-to-run-pyspark-in-google-colab">こちらの質問</a>と同じエラーが発生し、
結果、pip installできることを知りました(以前はできなかったと認識しています)。
<a href="http://apache.osuosl.org/spark/">sparkのバージョン</a>が更新されていたので、その更新作業がエラーに関係していると思っています。
2020年6月7日現在は、<a href="https://qiita.com/hiehara/items/43d740074827eb736462">先ほどの記事</a>のコードでも実行できます。
【SQL】テーブルのデータを複数のカラム指定してグループ化する方法

# はじめに
タイトルにもある通り、テーブルデータを複数のカラムを指定してグループ化したかったのだが、詰まってしまったのでメモとして記事に残します。

# やりたいこと
以下の売り上げを管理するデータを持つテーブルがあるとする。

item|date
:---:|:---:
apple|2020-06-06
apple|2020-06-06
orange|2020-06-06
orange|2020-06-06
grape|2020-06-06
orange|2020-06-05
orange|2020-06-05
grape|2020-06-05
apple|2020-06-05
grape|2020-06-05

このデータを1日ごとの種類別の売り上げた個数を取得したい。
最終目標の取得データは以下

item|sum|date
:---:|:---:|:---:
apple|2|2020-06-06
orange|2|2020-06-06
grape|1|2020-06-06
orange|2|2020-06-05
grape|2|2020-06-05
apple|1|2020-06-05

# やり方
やり方は超簡単である。
自分が長い時間悩んでいた事が馬鹿らしく思えるほどに。

```sql
select item, count(item) as sum, date
from sales
group by item, date
```

以上である。

# 余談
自分がなぜ時間がかかってしまったのか。
普通に__group by__で日付をグループ化までは良かったのだが、そこから__item__をグループ化するのに以下の様にしてしまった。

```sql
select item, count(item) as sum, date
from sales
group by item and date
```

そうすると、全てのデータがグループ化されて取得できてしまった。

次にサブクエリなどを用いて、データをこねくり回して取得してやろうとしていたが、実現できず。
結局上司の仏様に助けを求めたら、超簡単な返答が返ってきて笑ってしまいました。
浅はかな知識より、しっかりと勉強をして知識をつけないとなと実感した日でした。
本日は以上、ありがとうございました。
C++ STL vectorのempty()は長さ0で真

`vector`は要素の長さが0であれば真を返します。`v.empty()`と`v.begin() == v.end()`が同じ結果になるので当たり前ですが、初期化子リストを代入するとどうなるのだろうと気になったので。

# いつもの書き方

```cpp
#include <vector>
#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
	vector<int> v1;
	vector<int> v2 = {};
	vector<int> v3 = {0};

	wcout << boolalpha << v1.empty() << endl; // true
	wcout << boolalpha << v2.empty() << endl; // true
	wcout << boolalpha << v3.empty() << endl; // false

	return 0;
}
```

# 清書版

代入演算子を伴わないリスト初期化`type var {};`と`wcout`の既定フラグ設定`wcout.setf`を使用しています。

```cpp
#include <vector>
#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    vector<int> v1;
    vector<int> v2{};
    vector<int> v3{0};

    auto fmtflags = wcout.setf(wcout.boolalpha);
    wcout << v1.empty() << endl; // true
    wcout << v2.empty() << endl; // true
    wcout << v3.empty() << endl; // false
    wcout.setf(fmtflags);

    return 0;
}
```
【VSCode】Visual Studio Codeでターミナル(terminal)をクリアー(clean)する方法

# 方法
1. `cmd + shift + p`でコマンドパレットを開いて
2. `Terminal:clear`でクリアできます

## ショートカット
`Ctrl + Shift + k`が割り当てられていますが、他のコマンド(行の削除)で使われているため動作しません。
なので他のショートカットを割り当てましょう。
1. `cmd + shift + p`でコマンドパレットを開いて
2. `Preference: open keyboard shortcuts`でショートカット設定を開きます。
3. `terminal clear`とかで検索しましょう
4. `Cmd + k`などが空いていたら割り当てましょう

terminalに`celan`

# 参考と言う名の引用
https://stackoverflow.com/questions/48713604/how-can-i-clear-the-terminal-in-visual-studio-code/54032337#54032337?newreg=a127e736a829450fac4b5ce44049abbe
[Swift] アプリ内でSafariを開く方法

たまに使うときに忘れてるので備忘録です。


## 完成形
| `.pageSheet`<br>（iOS13以降でデフォルトの画面遷移） | `.fullScreen` |`.overFullScreen`|
|:-:|:-:|:-:|
| ![pageSheet.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328477/7d9ac71c-ac83-318f-ffa1-6ac850d7b974.gif)|![fullScreen.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328477/ff3d7f70-4dc8-bfd1-1dee-ccc2bc85c18b.gif)|![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328477/e39e4e32-5f94-d975-46da-03ee2a28eb9d.gif)
|

## コード
`import SafariServices`を忘れずに。

```Swift:ViewController.swift
import SafariServices
```

### デフォルト（`.pageSheet`）

```Swift:ViewController.swift
let webPage = "https://google.com"
let safariVC = SFSafariViewController(url: NSURL(string: webPage)! as URL)
// pageSheetの場合は、modalPresentationStyleの部分を書かなくてもpageSheetで表示されます。
safariVC.modalPresentationStyle = .pageSheet
present(safariVC, animated: true, completion: nil)
```

### `.fullScreen`

```Swift:ViewController.swift
safariVC.modalPresentationStyle = .fullScreen
```
### `.overFullScreen`

```Swift:ViewController.swift
safariVC.modalPresentationStyle = .overFullScreen
```

### 使用例
```Swift
@IBAction func TappedWebBtn(_ sender:UIButton) {
    let webPage = "https://google.com"
    let safariVC = SFSafariViewController(url: NSURL(string: webPage)! as URL)
    safariVC.modalPresentationStyle = .pageSheet
    present(safariVC, animated: true, completion: nil)
}
```

### 他の遷移アニメーション
`.formSheet` `.currentContext` `.overCurrentContext` `.popover` `.blurOverFullScreen`
他のアニメーションも実装方法は同じなので、公式ドキュメントをご確認ください。
https://developer.apple.com/documentation/uikit/uimodalpresentationstyle

## サンプル
サンプルコードはGitHubにあげてあります。
https://github.com/rea-sna/SafariSample

## 最後に
最後までご覧いただきありがとうございました。
MSYS2でパッケージをダウングレードする

ここでは [lensfun](http://lensfun.sourceforge.net/) ([mingw-w64-lensfun](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-lensfun)) を、開発版0.3.95から安定版0.3.2へダウングレード[^1]した際の作業を例にする。
[^1]: 当記事投稿後の2021年2月現在、mingw公式のlensfunパッケージは安定版へ巻き戻されている（のでlensfunについては当記事の作業は不要）。経緯は[issue#7108](https://github.com/msys2/MINGW-packages/issues/7108)]を参照。

### ソースコードの入手
mingwのパッケージをごっそり持ってくる。

```
git clone https://github.com/msys2/MINGW-packages.git
```

### ソースコードの巻き戻し
作業用ブランチを作って作業するのが良いと思う。gitの履歴で適切なリビジョンを調べたうえで

```
git checkout -b lensfun-0.3.2-4
git reset --hard aa4975
```
みたいに。

### ビルド依存関係のインストール

```
pacman -S mingw-w64-{x86_64,i668}-cmake
```

### ビルド
管理者として実行したターミナル上で

```
cd /path/to//MINGW-packages/mingw-w64-lensfun/
makepkg-mingw
```
その前に、シンボリックリンクを使えるようにしておく必要があるかも知れない。記事末尾の参考資料を参照。

### インストール

```
pacman -U mingw-w64-*--lensfun-0.3.2-4-any.pkg.tar.xz
```

### ダウングレードしたパッケージが上書き更新されないようにする
```/etc/pacman.conf``` の ```IgnorePkg =``` にパッケージ名を指定しておく。

## 参考
- [Arch Linux - パッケージのダウングレード - パッケージの再コンパイル](https://wiki.archlinux.jp/index.php/%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%83%80%E3%82%A6%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89#.E3.83.91.E3.83.83.E3.82.B1.E3.83.BC.E3.82.B8.E3.81.AE.E5.86.8D.E3.82.B3.E3.83.B3.E3.83.91.E3.82.A4.E3.83.AB)
- [MSYS2でシンボリックリンクを作れるようにしてみた](https://qiita.com/shinyay/items/587fd5cc19033c1bad82)
Confusion Matrixについて

## この記事について
Confusion Matrixについてまとめる

## Confusion Matrixとは
クラス分類において、評価指数の１つ。

|     | Predicted Negative | Predicted Positive |
|:---:|:---:|:---:|
| Actual Negative   | True Negative  | False Positive  |
| Actual Positive   |  False Negative | True Positive  |

Precision = TP / (TP + FP)
Recall = TP / (TP + FN)

```python
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
```
銀河の画像を複数枚タイル状に表示する方法

#環境
Google Colab
(Python:3.6.9, astroquery:0.4)
#全体の流れ

- skyviewから天体カタログ(fitsファイル)を保存
- fitsファイルを元に銀河画像を作成し保存
- ディレクトリから画像データを順番に読み、ndarray配列に格納
- プロット

#コード
##fitsファイルの保存
まずは、Vizierで指定のカタログに載っている天体名とその数の取得。

```python


from astroquery.vizier import Vizier
v=Vizier(catalog="J/ApJS/80/531/gxfluxes",columns=["Name","logLx","Bmag","dist","type"],row_limit=-1)
data=v.query_constraints()
sname=data[0]["Name"]
namelist=[]
for one in sname:
  name=one.strip().split()[0]
  name=one.replace("N","NGC").replace("I","IC")
  namelist.append(name)
olist=["HRI","DSS"]

```
今回の場合、len(namelist)=448なので、448個のの天体があることが分かる。それらの天体のfitsファイルを順に保存していく。


```python
def save(p,name,obs): # save file into fits 
    for onep,oneo in zip(p,obs):
        onep.writeto(name+"_"+oneo+".fits",overwrite=True)
from astroquery.skyview import SkyView
path_fits="/content/drive/My Drive/datastore/fits/"
num=int(input("Times of try (for <=448) : "))
filename=[]


for i in range(num):
  name=namelist[i]
  try:
    paths=SkyView.get_images(position=name,survey=olist)
    save(paths,path_fits+name,olist)
    filename.append(name)
    print("Saved  {}".format(name))
  except:
    print("Not found {}".format(name))
```
ディレクトリからfitsファイルを読み込む。
fitsファイルには300×300のndarray配列の情報があるので、それらを一度1×90000行列にする。他のfitsファイルでも同じ処理をし、その結果を同じndarrayに加えていく。

```python
#ディレクトリ内のfitsファイルの画像データ一次元化し、
#二次元配列のdataの各行に画像データを格納

path_fits=glob.glob("/content/drive/My Drive/datastore/fits/*_DSS.fits")

N=100
#N=len(path_fits)
h=300
w=300


data = np.empty(h*w*N).reshape(N, h*w)
img_data=np.empty(h*w*N)
for i in range(N):
  dsshdu=fits.open(path_fits[i])[0]
  dsswcs=WCS(dsshdu.header)
  dssdata=dsshdu.data
  img_data=np.array(dssdata)
  data[i] = np.array(dssdata).flatten()
data.shape
```

先程フラット化した、画像データを再び、300×300行列にreshapeする。
あとは、普段複数枚の画像を表示するように、`plt.add_subplot()`の第三引数にfor文を用いて1ずつ増やせば、一枚ずつプロットしてくれる。

```python
data_reshaped=data.reshape(N,h,w)

f=plt.figure(figsize=(15,15))
f.subplots_adjust(left=0,right=1,bottom=0,top=1,hspace=0.05,wspace=0.05)

for i in range(N):
  ax=f.add_subplot(10, 10, i+1, xticks=[], yticks=[])
  ax.imshow(data_reshaped[i], interpolation="bilinear")

plt.show()
```

##結果

![2020-06-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373924/47e2e48b-e4a4-a18d-f4f9-7f1e284aa3e9.png)

#参考文献
[【超初心者向け】画像の主成分分析(PCA)をpythonで実装してみる。](https://tips-memo.com/python-2d-pca)
npm installでインストールできるモジュールを作るまでの流れについて

# はじめに

npmでインストール可能なモジュール（パッケージ）のなるべく最小構成の作成方法が中々見つからなかったので、簡単にまとめました。

# 環境
- Node.js 12.16
- npm 6.14

# ファイル構成
npmパッケージには、1つのディレクトリ内にモジュールのソースコードセット、`package.json`、エントリーポイントとなるjsファイル（今回は`index.js`とする）の3種類が必要となる。  

今回の例としては、ディレクトリをmodtest、モジュールのソースコードをサブディレクトリlibの配下に2種類(hello.js, hello2.js)、index.jsとします。

- modtest/
    - lib/
        - hello.js
        - hello2.js
    - index.js
    - package.json

# モジュールの作成

## 1. ディレクトリ作成
空のディレクトリ（今回はmodtest）を作成しておきます。

## 2. package.jsonの作成
空のディレクトリへ移動し、`npm init`コマンドを実行します。

```sh
npm init
```

対話式にモジュール名、バージョン番号等のパッケージ情報を尋ねられるため、必要事項を入力すると、同ディレクトリに下記のような`package.json`が作成されます。

```javascript:package.json
{
  "name": "modtest",
  "version": "1.0.0",
  "description": "The test modules for npm.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "aqmr-kino",
  "license": "ISC"
}
```

## 3. ライブラリモジュールの作成

### 3.1 モジュール作成
モジュール化する対象のコードを作成します。
今回はサンプルとして関数1個（hello）とクラス1個（Hello）を作成します。

各ファイルの最後に`module.exports`を使用して外部からアクセス可能とする関数を設定します。（exportした関数やクラスのみがpublicな関数やクラスとして公開されます）

```javascript:lib/hello.js
function hello() {
    return "hello"
}

module.exports = {
    hello,
}
```

```javascript:lib/hello2.js
class Hello {
    constructor(v) {
        this.value = v;
    }
    hello() {
        return ("hello, " + this.value);
    }
}

module.exports = {
    Hello,
}
```

### 3.2 メインモジュール作成
パッケージのメインファイルとなるjsファイルを作成します。
今回は、`index.js`という名前で作成していますが、`package.json`の`main`に記載するファイル名を変更することで変更可能です。
モジュールを利用するファイルから`require`で読み込んだ場合に実行されるスクリプトで、基本的にはライブラリモジュールを読み込んで、任意の名前で再度exportしておきます。（このファイルでexportされた識別子がモジュールを利用するコードから呼び出すことができる要素となります）

```javascript:index.js
const hello = require('./lib/hello.js')
const hello2 = require('./lib/hello2.js')

module.exports = {
    hello,
    hello2,
}
```

# モジュールのインストール
上記の各種ファイルセットを作成後、`npm install`コマンドで`package.json`があるディレクトリを指定することで、パッケージとしてインストールすることが可能です。

### ローカルのディレクトリから
`npm install`コマンドで作成したモジュールセットの格納されたディレクトリを指定することでモジュールとしてインストールすることができます。

```sh
npm install ./modtest
```

### GitHubから
上記のファイル構成をGithubのリポジトリとしては登録しておけば、`npm install`でコマンドで`git+リポジトリのURL`を指定することによりインストールすることもできる。

```sh
npm install git+https://github.com/user_name/repository_name.git
```

# インストールしたモジュールの使い方
npmでパッケージとしてインストールしたモジュールは一般的なnpmパッケージと同様にrequireで読み込み、パッケージ内でexportされている各関数やクラスを利用することができる。

```javascript:main.js
const modtest = require('modtest')

// helloメソッド（hello.js内）
console.log(modtest.hello.hello())

// hello2.Heloクラス（hello2.js内）
var h = new modtest.hello2.Hello("test")
console.log(h.hello())

```
Jupyter上での共同作業で気をつけたいこと

## Overview
Jupyterを使って他人と一緒に作業をするときに、相手に気をつけて欲しいこと、自分が気をつけてることについて、まとめていく。  
複数人でのJupyter上での作業は何かとやりにくさがある。実験的なコードが多くて読み難かったり、そもそも、実行可能なのかがわかり難かったり。実際には何かしらのマネージメントサービスと連携させたり、チームでルールを設定したりするわけだが、いつでもそれらを設定できるわけでもない。個人レベルの意識でどんなことを気をつけることができるのか、どんなことをやめて欲しいのか、どうしてくれると嬉しいのかをまとめていく。

## 絶対に気を欲しいこと

### 使用されてないコードは残すな
Jupyter上では、簡単にコードを書いて様々なことを手軽に確かめることができる。よくあるのが、最終的に使われてないコードがそのままに残っていることだ。これらがそのまま残ってると、他の人がJupyterファイルを開いた時に最初に行うのは、アクティブなコードとそれ以外の仕分けだ。全体のフローもわかりにくくなるので忘れずに消そう。もしも、使用はされていないものの、重要な部分であるならばコメントアウトなり何なりして、アクティブなコードではないことを明示しよう。

### 上から順に実行できるようにする
個人的にはこれは本当に気にして欲しい。Jupyter上ではCellを追加、挿入をすることができる。そのため、試行錯誤の中で、最終的に通しで実行するためには、下から上、上から下と、めちゃくちゃな順番でCellを実行しなければいけないファイルが出来上がることがある。（個人的には、そもそも実験段階でもこんなワークフローは避けるべきだと思うが。）
この手のJupyterファイルは共同作業者からすれば最悪だ。きちんと実行順序を把握するのも面倒だし、自分で整えた順序が本当にコードを書いた人の意図したものなのかもわからない。せめて、人とシェアする前に、上から実行できるように整えておこう。


### 必要なファイルの上書きコードを残さない
共同作業者は言う。『そのコード、動くから。実行しなくて良いから。』  
正直な感想は『知らんがな』だ。Jupyter上のコードだ。多くの場合はテストがない。本当に動くかどうかなんてわからんし、そもそも、各パーツごとにどう動くのかきちんと確かめる必要がある。そのJupyter上で作業するってことは何らかのタイミングで少なくともコードの実行はするものだ。その実行によって大切なファイルが上書きされて、大変なことに。。ってのはあってはいけない。  
いつ、共同作業者がJupyterのコードを実行しても大丈夫なように、必要なファイルはバージョン管理なり何なりしておこう。


## 気をつけてくれると嬉しいこと

### 参照してるファイルの情報を残してくれ
Jupyterファイル内のCellのコード。

```python
data = pd.read_csv('s3://hoge_1/hoge_2/processed_data.csv')
```

この`processed_data.csv`がどこからなり取ってきたものでチーム内で共有されているなら良い。めんどくさいパターンは、このファイルが別のJupyterファイルで生成され、保存された場合。このファイルを生成しているJupyterファイルを探しにいく必要がある。でもって、よくあるのが、複数のJupyterファイルが、このファイルを保存するためのコードを持っているパターン。どのファイルから作られたのよ？？  
何かしらのマネージメントサービスを使ってないなら、せめて、このファイルがどのJupyterファイルから作られたのか、コメントくらいは残して欲しい。辿っていくのが本当に大変。

### 関数を使ってネームスペースを限定してくれ
Jupyter上では手早く様々な実験をできる。そのためか、グローバルスペースにガツガツとロジックが書かれ、一つの変数名が繰り返しの上書きで再利用されることもしばしば。それが、小さいJupyterファイルならまだ良いが、こういうファイルは100 Cell以上からできてたり。  
Cellを関数単位感覚で使ってるようなコードもよく見るが。それなら関数定義しよう。  

### 実行を確認するためのサンプルされたDEVデータを用意してくれ
上にも書いた通り、共同作業者の書いたJupyter上でのコードが本当に動くかどうかなんて、実行しなければわからない。テストないし。
流石に、全てのプロセス用にテストを書けとまでは言わない。でも、大きなプロセス単位でプログラムの確認をするようにフィクスチュアデータは欲しい。きちんと明記されたフィクスチュアデータあれば、プログラム実行時も何かしら必要なファイルの上書きの可能性についてもそんなに神経質にならなくて済むので気が楽だ。もちろん、自分でサンプリングを行ってデータを作るのは全然構わないし、実際そうしてることが多いのだが、それも、時によっては結構時間がかかる。

### 簡単にで良いからリファクタしてくれ
ある程度コードを書いて、実行を確認したら、10分で良いから立ち止まってコードのクリーニングとリファクタリングをしてくれ。その10分は他の人の1時間を救う。

### ファイル名に合ったコードだけ残す
ファイル名は`data_creation.ipynb`なのに、データセット作成、モデリング、評価まで全部行ってるファイルがあったりする。おそらく、ファイル名を考えたときはデータセット作成のためだけを考えていたのだろうが、作成後にそのままそこで作業してしまったのだろう。分割するかファイル名を変えるかして欲しい。そのようなファイルが10、20と存在すると、開けるまで何があるかわからないブラックボックス状態だ。

### 実行にリソースの問題がある部分にはプロファイル情報を残してくれ
時間がかかりすぎるとかメモリを食いすぎる部分の実行には簡単にで良いからその情報を残して欲しい。Cellのマジックコマンドでも良いし、コメントでも良い。大きな問題を抱える部分が、何の明記もなくそこに存在し、長時間の実行の後に問題に気づくなんて面倒だし、共同作業者としてパフォーマンス改善を行うにしても事前情報が明記されているだけで、だいぶ手間が省ける。


## 最後に
人によっては、『プログラマが普通にコード書いてたら起こらない』とか『綺麗なコード書け、で十分』と思う人もいるかもしれないが、Jupyterでの共同作業者はプログラマのみではない。割と広い範囲の人が、共同作業をしうる。  
そうした時に、互いの意識で互いに幸せになれるのは上記のラインなのかなと思ってる。
Markdowns available Google keep(グーグルキープで使えるマークダウン)動画付き


Markdowns available in Google Keep
でぐぐっても狙った記事が出てこなかったので書く

https://www.google.com/search?q=Markdowns+available+in+Google+Keep&rlz=1C1QABZ_jaJP893JP893&oq=Markdowns+available+in+Google+Keep&aqs=chrome..69i57j33.186j0j9&sourceid=chrome&ie=UTF-8

# 1. 数値のリスト
`1.` から書き始めると改行した時に、`2.`からはじまる
![2020-06-06-22-40-51.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253014/2cc0e073-1f4e-3075-727d-b7eb314aca37.gif)
https://youtu.be/oykL3S2lrvI

# 2. ・からはじまるリスト
`*` + `空白`から書き始めると・からはじまるリストが作れる
![2020-06-06-22-40-25.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253014/f060303c-835a-1ea8-08d6-9b0fd68ed86c.gif)
https://youtu.be/TdLfhmRPwYU

# 3. （番外編）タグを作る
#から書き始めるとタグが作成される
![2020-06-06-22-44-01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253014/9ce8805b-844b-d4e0-b9bb-cb86268b34fc.gif)
https://youtu.be/pYrDOP8GtFw

# 4. （番外編）チェックリスト
オプションからチェックリストにすることができる（markdownではない）
![2020-06-06-23-47-20.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253014/490b8d29-6d2c-03d5-147e-e55c0bfa0dbd.gif)
https://youtu.be/RiYCiYbljQ0

# 拡張機能もあるっぽい
あるにはあるが、Google keepの急なアップデートなどには対応できていないようだったので使わないことにしました。
https://webapps.stackexchange.com/questions/88955/markdown-formatting-in-google-keep
bundle updateをしたらrailsコマンドが使えなくなった件

# はじめに
時間が空いた時に忘れてしまいがちなのでここにメモ兼この記事を見ていただいた方の解決策の一つになれれば嬉しいです。

# 環境
- mac
- Ruby 2.5.1
- Rails 6.0.2.2

## bundle updateをしたらrailsコマンドが使えない…

```ruby
#bundle updateは通る
$ bundle update kaminari
　　　　・
　　　　・
　　　　・
Bundle updated!
```
railsコマンドを打つと…

```ruby
$ rails -v
Beginning in Rails 4, Rails ships with a `rails` binstub at ./bin/rails that
should be used instead of the Bundler-generated `rails` binstub.

If you are seeing this message, your binstub at ./bin/rails was generated by
Bundler instead of Rails.

# `rails`binstubを再生成する必要があるかもみたいなことを言っている
You might need to regenerate your `rails` binstub locally and add it to source
control:

 rails app:update:bin           # Bear in mind this generates other binstubs
                                # too that you may or may not want (like yarn)

# binstubが既にあるならばbundle installにbinstubオプションを付けて実行
If you already have Rails binstubs in source control, you might be
inadvertently overwriting them during deployment by using bundle install
with the --binstubs option.

If your application was created prior to Rails 4, here's how to upgrade:

  bundle config --delete bin    # Turn off Bundler's stub generator
  rails app:update:bin          # Use the new Rails executables
  git add bin                   # Add bin/ to source control

You may need to remove bin/ from your .gitignore as well.

When you install a gem whose executable you want to use in your app,
generate it and add it to source control:

  bundle binstubs some-gem-name
  git add bin/new-executable
```
## rails app:update:binを実行
railsコマンドを打った時と同様の上記のメッセージが表示された後に追加で表示される

```ruby
$ rails app:update:bin
exist  bin
    conflict  bin/rails
# 下のことを聞かれるのでEnterを押す
Overwrite /railsアプリのディレクトリ/bin/rails? (enter "h" for help) [Ynaqdhm]
       force  bin/rails
    conflict  bin/rake
# 下のことを聞かれるのでEnterを押す
Overwrite /railsアプリのディレクトリ/bin/rake? (enter "h" for help) [Ynaqdhm]
       force  bin/rake
   identical  bin/setup
   identical  bin/yarn

# railsコマンドを打つ
$ rails -v
Rails 6.0.2.2
```
無事に表示されました。
## bundle installでも同様
bundle installを行っても、bundle updateでgemの指定をしなくても同じようになりました。
## なぜこうなったのか考える
bundle updateやbundle installによって、実行ファイルとgemとで差異が起きたと思われる。
そして、binstubを新しくすることで解消になったと考えるが、これより先のことはまだわかっていません。
## もう一度bundle updateなどを行うと再度エラーが出てくる
解決はできるものの、gemに変更をするたびに出てこられるのは手間ですね。
現在の私だとまだまだわからないことが多く、本質的な解決に至っていないので、ゆくゆくはbinstubやrailsがやってくれていることも理解していきたいです。
## まとめ
この記事で問題解決が完結とまでは導き出せませんでしたが、いつか戻ってきた時に解決できるように力をつけたいですね。
また、解決方法がありましたらコメントを残していただけると嬉しい限りです。
JavaScript タイマーの使い方

## タイマーの作り方

0.5秒ごとに表示を更新する

```html

<div id="timer"></div>


<script>
let timer = () => {
    let now = new Date();
    document.getElementById('timer').innerHTML = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
}

let timerId = setInterval(timer, 500);
</script>
```

## 時間になったら何かやらせたい場合

上のサンプルで10秒後に時間が変わる

```JavaScript
let timerId = setTimeout(timer, 10*1000); 
```

上のタイマーを解除するには

```JavaScript
clearTimeout(timerId)
```
Marketing Cloud とカスタマーサクセスプラットフォームの概要

1. Marketing Cloud を Sales Cloud および Service Cloud と統合するのはどの製品ですか?
2. trust.marketingcloud.com にアクセスする理由は何ですか?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/76ff6811-88ea-41bb-e6f1-c5bbc2dab5b7.png)
jQueryをシンボリックリンクするのがいいと思いますがどうか？

# 1. ディレクトリをまるっと上書きするパターン

```
/var/www/html
    /index.html
    /js
        /jquery.js
```

```html:index.html
<script type="text/javascript" src="/js/jquery.js"></script>
```

よくあるパターン。というか普通にjQueryを使用しようとするとこうなっていると思います。

## メリット
シンプルで、簡単。
バージョンアップの度に、htmlを更新する必要がない。

## デメリット
現在使用中のjQueryバージョンが分かりにくい。


# 2. バージョン名付きディレクトリにリンクするパターン

```
/var/www/html
    /index.html
    /js
        /jquery-1.11.1.js
        /jquery-2.24.js
        /jquery-3.5.1.js
```

```html:index.html
<script type="text/javascript" src="/js/jquery-3.5.1.js"></script>
```

バージョンアップを経て、こうなったパターン。

## メリット
使用中のjQueryバージョンが一目でわかる。
htmlページごとにjQueryのバージョンを変えることができる。（プラグインが対応していないなど、あえて古いバージョンを使用しなければいけない時とか）

## デメリット
htmlを全て書き換える必要がある。


# 3. シンボリックリンクでリンクするパターン

```
/var/www/html
    /index.html
    /js
        /jquery-1.11.1.js
        /jquery-2.24.js
        /jquery-3.5.1.js
        /jquery.js --> jquery-3.5.1.js
```

```html:index.html
<script type="text/javascript" src="/js/jquery.js"></script>
```

## メリット
htmlの更新が原則不要。
ただし、前述のように個別にバージョンを変えたい場合にバージョン指定もできる。

## デメリット
FTPでいじるコーダーが混在する場合、実ファイルで上書きされてしまう恐れがある（？）
**.ftpignore** 的な仕組みが欲しいけどそんなんある？
現在使用中のjQueryバージョンが分かりにくい。
webpackにeslintを設定する


## 前提

- webpack実行時に、eslintでコードチェックできるようにする
- webpackの基本的な構築方法は省略
- TypeScriptではなく、ネイティブのJavaScriptにて構築
- React環境にて構築

## インストールするライブラリ
- eslint
- eslint-loader
- babel-eslint

## eslintの初期化
- 下記コマンドを実行

```
npx eslint --init
```

- 下記質問が表示されるので、指定したものを選択


```
// syntaxとstyleについてのチェックするを選択
? How would you like to use ESLint?
  To check syntax only
  To check syntax and find problems
❯ To check syntax, find problems, and enforce code style

// import/exportが主流なのでこちらを選択
? What type of modules does your project use? (Use arrow keys)
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these
  
// TypeScriptを使用する場合はy,使用しない場合はN
// 今回はNo
Does your project use TypeScript? (y/N)

// どのjsフレームワークを使用するか？
// 今回はReactを使用する
? Which framework does your project use?
❯◉ React
 ◯  Vue
 ◯  None of these

// ブラウザで動作するアプリケーションを前提としているので以下を選定
? Where does your code run? (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Browser
 ◯  Node
 
 // どれでも良いが、シェアの高いAirbnbを選定
? Which style guide do you want to follow? (Use arrow keys)
❯ Airbnb: https://github.com/airbnb/javascript
  Standard: https://github.com/standard/standard
  Google: https://github.com/google/eslint-config-google

// .eslintrsファイルの形式を選択
// jsonを選んだ場合、json形式になる(.eslintrc.json)
? What format do you want your config file to be in?
  JavaScript
  YAML
❯ JSON

// 関連するライブラリをinstallするか？
// yesを選択
Would you like to install them now with npm? (Y/n)
```

- 上記設定を選択すると、「.eslintrc.json」ファイルが生成される

```json
{
  "env": {
    "browser": true,
    "es2020": true
  },
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 11,
    "sourceType": "module"
  },
  "plugins": ["react"],
  "rules": {}
}
```

## webpackの設定

```javascript
// rulesの中に記載されたloaderは、後ろから順番に実行される
// 1番最初に記述したloaderは最後に実行される
// 順番を入れ替えるのが面倒なため、「enforce」の設定を記載する
rules: [
    {
        // enforce：preを持たないruleよりも早く実行される (1番最初に実行される)
        enforce: 'pre', 
        // eslintの対象は記述子が.jsまたは.jsxのファイルのみ
        test: /\.jsx?$/,
        // /node_modules/をeslintの対象から外す
        exclude: /node_modules/,
        loader: 'eslint-loader',
      },
]
```

### babel-eslintの設定
- eslintrs.jsonにbabel-eslintを設定

```json
{
  "env": {
    "browser": true,
    "es2020": true
  },
  // parserを追記
  "parser": "babel-eslint",
}
```

## eslintを実行
- webpackコマンド実行時にeslintが走る

```
npx webpack
```

- または eslintコマンドで対象のファイルを指定して実施する

```
npx eslint [対象のファイル名]
```

## エラー解消
### jsxの記述子しかeslintしないエラー
- Airbnbのスタイルガイドでjsxの記述子しかeslintできない仕様になっている
- エラー内容

```
src/App.js|8 col 7 error| JSX not allowed in files with extension '.js' (react/jsx-filename-extension)
```

- 無視する場合は、.eslintrc.jsonに以下の設定を記載

```json
{
  "env": {
    "browser": true,
    "es2020": true
  },
  //こちらを追記
  "rules": {
    "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]
  }
}
```

### eslint実行時にエラーになる
- npx webpackコマンド実行時に、eslintでエラーになる場合
- 以下のメッセージがある場合は、コマンド実行によって自動で修正できる

```
✖ 2 problems (2 errors, 0 warnings)
  2 errors and 0 warnings potentially fixable with the `--fix` option.
```

- こちらのコマンドで自動で修正できる

```
npx eslint --fix [対象のファイル]
```
CSS(SCSS)　@forを使ったインクリメント文でゼロパディングした連番の出し方

SCSSで@forをインクリメントして連番の記述をする時に

01〜10をインクリメントしたい場合下記のように

if文をネストすることで連番として出力できます。

#実現したいこと

下記のような連番を@forでインクリメントしたい

```CSS:CSS
.con1{background-image: url(../img/index-main_1.jpeg);}
.con2{background-image: url(../img/index-main_2.jpeg);}
.con3{background-image: url(../img/index-main_3.jpeg);}
.con4{background-image: url(../img/index-main_4.jpeg);}
.con5{background-image: url(../img/index-main_5.jpeg);}
.con6{background-image: url(../img/index-main_6.jpeg);}
.con7{background-image: url(../img/index-main_7.jpeg);}
.con8{background-image: url(../img/index-main_8.jpeg);}
.con9{background-image: url(../img/index-main_9.jpeg);}
.con10{background-image: url(../img/index-main_10.jpeg);}

```

以下で動かそうとすると10個目は正しくコンパイルされません
10ではなく010でコンパイルされてしまうため

```SCSS:SCSS
@for $i from 1 through 10{
  .con#{$i}{
    background-image: url(../img/index-main_0#{$i}.jpeg);}
  }
}

//10個目は../img/index-main_010/jpegとコンパイルされてしまう
```

この場合はif文ネストして１桁と２桁で分岐します。

```SCSS:SCSS

@for $i from 1 through 10{
  @if $i < 10{
    .con#{$i}{
      background-image: url(../img/index-main_0#{$i}.jpeg);}
    }
  } @else {
    .con#{$i}{
      background-image: url(../img/index-main_#{$i}.jpeg);}
    }
  }
}

```

@forや@ifを使うと冗長なCSSをスッキリまとめられる場合もありますので
SCSSで記述する場合は積極的に取り入れていきましょう。
※使わないほうが可視性の高いこともあります。
Git for Windows アップデートコマンド

# はじめに
普段、自宅の Windows PCをあまり使わない。
そのため、使う度に、Windows Updateやウイルス対策ソフトの更新をしている。
ふとGit for Windows のアップデートをした覚えがないので気になって調べてみました。

# コマンド

何はともあれ、まずは、Git for Windows を起動。

```bash
# バージョン確認
git version

git update-git-for-windows

```

とまあ、これだけでした。

早速、仕事用PCでもアップデート！

# References
* https://onoredekaiketsu.com/manually-update-git-bash/
【WordPressのローカル環境作成】WindowsPCをサーバーに見立てたら通信不可。原因はMcAfee

今回はWordPressのローカル開発環境でコケた話です。

WindowsPC上にローカル環境を作成し、Macから閲覧するという構成を検討。

ところが、MacからWordPressサイトが見られない！そんなときにやった対応のまとめになります。

## WordPressローカル環境
- Windows10 PC
- XAMPP


XAMPPを使ったローカル環境構築に関しては下記サイトを参考にしてください。
＞＞　[XAMPPを使ってWordPressローカル環境を構築する全手順](https://bazubu.com/xampp-wordpress-23795.html)

ここで作った環境をローカルネットワークから見られるようにしました。
他のPCやスマホ・タブレットから自由に確認したかったので。

ローカルネットワークでの公開方法は下記サイトを参考に。
＞＞　[スマホや別のPCからローカルサイトへ接続する方法](https://okishumi.com/wordpress/xampp-lan/)

## 起こった事象
前述のサイトを参考にしてローカル環境構築完了。

別のPC(Mac)からWordPressのサイトを確認したかったんですが、エラーで表示されず。

Mac→Windowsでpingも飛ばない状態。

でもWindows→Macではpingは飛ぶ。

ここで疑ったのはWindowsのファイヤーウォールで弾かれている説。

これは実は当たっていたんですが、設定を変更してもうんともすんとも言わない。

うんうんうなってやっとわかりました。

**「このWindows、McAfeeが動いてやがる！！」**

McAfeeをオフにすると、ちゃんとサイトが表示されるじゃないですか！

## 対応内容
とはいっても、このWindowsPCは普段使いもするので、McAfeeをオフにするってのは現実的じゃないので設定変更で対応しました。

１、まずはMcAfeeを開いて、画面上部の「セキュリティ」タブをクリック。
![Mcafee1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562723/38481233-2d92-df54-9d01-69407eaff226.png)

２、画面左側の「ファイヤーウォール」をクリック
![Mcafee2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562723/9cc566a5-8fd8-9398-c59a-91395bc94fb0.png)

3、「ポートとシステムサービス」をクリック
![Mcafee3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562723/8b3fa974-c214-2ce6-7e7c-08f6b57c2c5b.png)

4、ポート開放
HTTPS（ポート443）とHTTP（ポート80）にチェックを入れて登録します。
![Mcafee4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562723/2c33d9d3-a05c-a3b2-b482-3385e643ba74.png)

これでOK。

ローカルなのになぜかHTTPSで通信してしまっていたので、HTTPSとHTTPと両方にチェックを入れました。

これでMac→Windowsでの通信はOK。
めでたくWordPressのサイトがローカルネットワーク内で見られるようになりました。
GAS 配列　範囲　取得　set

#問題発生
GASで範囲を一括で配列に入れた。
しかし、setValuesをした所エラーになった。

#原因
1列しか取得していなかったので、
1次元配列になっていた為setValuesがうまく行かなかった。

#解決策
1次元配列を2次元配列にする。

#範囲を配列で一括取得
###ドメインシートの赤枠のカラムを移動する。
![スクリーンショット 2020-06-06 22.33.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354233/89381a95-31a8-cbbb-74b9-ac85679c6b28.png)

```javascript:
  //■① 範囲を配列で取得する。(※1列なので一次元配列)
  var array1 = shドメイン.getRange(21, 1, 4, 1).getValues();
```

#色々なサイトを見たが下記の方法ではうまくいかない
```javascript:
  //■② getRange(◯,◯,◯,◯).setValues(array1);だとエラーになる。
```

#配列を一括でset
###テーブルシートの赤枠に移動させる。
![スクリーンショット 2020-06-06 22.51.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354233/066916cf-966f-e53f-becb-4214513c929b.png)

```javascript:
  //■③ array1を二次元配列にする。
  var array2 = []; 
  for (var i=0; i<array1.length; i++) { 
    //■④ array2にarray1を入れているだけ。入れる形に気をつける！！
    array2.push([array1[i]]); 
  } 

  shテーブル.getRange(21,1,array2.length,1).setValues(array2);
```

#できた！！
###1列だと2次元配列になっていないので改めて配列に格納する。
![スクリーンショット 2020-06-06 22.58.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354233/55cb8446-8138-7e40-5211-adffa91bfa9c.png)
Dockerで作成したWebサイトをHerokuでデプロイする方法

#環境
Docker 19.03.8
macOS 10.15.5

#前提
Herokuのアカウント登録は完了している
Homebrewのインストールが完了していてbrewコマンドが使える

#デプロイするまでの解説
下記は今回わたしがデプロイしたWebサイトの```docker-compose.yml```のファイルになります。

```docker-compose.yml
version: '3'

services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
      
    environment:
      POSTGRES_PASSWORD: 'postgres'

  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```


###herokuコマンドのインストール
```ruby:terminal
$ brew tap heroku/brew && brew install heroku
```

###heroku-cliにログイン
下記のコマンドを実行したのちにEnterをクリックします。

```ruby:terminal
$ heroku login
heroku: Press any key to open up the browser to login or q to exit:
```
下記の画面が自動的に開きますのでログイン情報を入力します。
<img width="1440" alt="スクリーンショット 2020-06-06 18.10.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587506/f1f707ec-4c0e-e156-4b7a-62e594a528db.png">

###Container Registryにログイン
そして下記のコマンドを実行してContainer Registryにログインします。

```ruby:terminal
$ heroku container:login
Login Succeeded
```

###アプリを新規作成

下記のコマンドを実行してアプリを新規作成をします。```$ heroku create [app name]```でアプリの名前を作成します。自身の指定するアプリ名を入力してください。

```ruby:terminal
$ heroku create recipegram-app
Creating ⬢ recipegram-app... done
https://recipegram-app.herokuapp.com/ | https://git.heroku.com/recipegram-app.git
```

###Container Registryにdocker imageをpushします。
ローカルで作成したdocker imageをHerokuのContainer Registryにpushします。

```ruby:terminal
$ heroku container:push web
```

###Heroku add-onsのpostgresqlを作成
```ruby:terminal
$ heroku addons:create heroku-postgresql:hobby-dev
```

###webプロセスタイプをリリース
```ruby:terminal
$ heroku container:release web
```

###DB migrationの実行
```ruby:terminal
$ heroku run rails db:migrate
```

###assets:precompile
```ruby:terminal
$ heroku run rails assets:precompile
```
###デプロイ完了
以下のコマンドでデプロイしたアプリが開きますので確認をします。

```ruby:terminal
$ heroku open
```

問題なく表示させることができました！URLもきちんと表示されていることが確認できました^_^
<img width="1440" alt="スクリーンショット 2020-06-06 22.41.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587506/6efb0206-0106-dbcd-6c01-d62c3efb88c4.png">

#Herokuにデブロイしたあとに更新する方法
下記のリンクではHerokuにデプロイしたあとに更新する場合の手順を公開していますのでぜひご覧ください！

[【Docker】Herokuでコンテナを使い更新するやり方とMigrateErrorの対処方法について
](https://qiita.com/chisaki0606/items/8485307184a2b54019ba)
AWS Cloud9 (ubuntu) のAWS CLIをversion 2 にアップデートする

AWS Cloud9 にAWS CLI (version2)をインストールした際のメモ
OSはubuntu

## 現行バージョンを確認
Cloud9ではすでにAWS CLIがインストールされている

```
$ aws --version
aws-cli/1.18.45 Python/3.6.9 Linux/4.15.0-1065-aws botocore/1.15.45
```

## Version 2 インストール
v2をダウンロード

```
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
```

現行バージョンをアンインストール

```
$ sudo pip3 uninstall awscli -y
```

インストール

```
$ sudo ./aws/install
You can now run: /usr/local/bin/aws --version
$ aws --version
aws-cli/2.0.15 Python/3.7.3 Linux/4.15.0-1065-aws botocore/2.0.0dev19
```

## その他の設定
AWS Cloud9 はログインユーザが持つ権限の一時的な認証情報が利用できるため、AWS CLIのアカウント設定をしなくてもすぐ利用できるが、許可されるアクションが制限される。
IAM系ユーザやグループの作成などは今のままでは下記のようにエラーとなる。

```
$ aws iam create-group --group-name testgroup
An error occurred (InvalidClientTokenId) when calling the CreateGroup operation: The security token included in the request is invalid
```

回避方法として、一時的な認証（AWS managed temporary credentials）をOFFにし、代わりにロールをアタッチする。

### 設定方法
1. AWS Cloud9 の Prefarences -> AWS Settings -> Credentials でAWS managed temporary credentials をOFFにする
2. IAM のロールで ロールの作成をクリックし、ユースケースでEC2を選択
3. アタッチするアクセス権限ポリシーを選択（例：AdministratorAccess）
4. 作成したロールをCloud9をホストしているEC2にアタッチする

```
$ aws iam create-group --group-name testgroup
{
    "Group": {
        "Path": "/",
        "GroupName": "testgroup",
        "GroupId": "********************",
        "Arn": "arn:aws:iam::************:group/testgroup",
        "CreateDate": "2020-05-22T12:21:14+00:00"
```
TechAcademyが無料公開している「HTML・CSS入門講座」を受講する～HTML第2-1回～

# アジェンダ
* HTMLのタグ
  * p
  * h
* 実践
* Lorem Ipsum

# HTMLのタグ
## p
段落を示すタグ。\<p>\</p>で囲われた文書を一つの段落とする。
paragraphのp。

## h
見出しを示すタグ。6段階に分かれていて、大きいものが\<h1>\</h1>、小さいものが\<h6>\</h6>となる。
headlineのh。

#実践
pタグとhタグがどのように反映されるか確認です。
次のようなindex.htmlを作成しました。

```html:index.html
<!doctype html>

<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>見出しhと段落p</title>
  </head>
  <body>
    <h1>これはh1です。</h1>
    <h2>これはh2です。</h2>
    <h3>これはh3です。</h3>
    <h4>これはh4です。</h4>
    <h5>これはh5です。</h5>
    <h6>これはh6です。</h6>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
      Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    </p>
    <p>
      Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
      Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </body>
</html>
```
これをWebブラウザで表示させるとこんな感じ。
![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/9693e434-f49d-feeb-fd41-1a5d185ff8c7.png)

見出しは、数字が大きくなるにつれてフォントサイズが小さくなっていることが分かる。
段落は、\<p>\</p>で囲った文書がひとまとまりになっていることが分かる。

# Lorem Ipsum
Lorem Ipsumとは、テキスト表示の試験時に多く使用されるダミーテキストのこと。文章や単語に意味はない。
以下に、Lorem Ipsumの原文を示す。

> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
- 引用 : [Wikipedia](https://ja.wikipedia.org/wiki/Lorem_ipsum)

表示試験に意味のある文書を用いると、文書を読むことに集中してしまい、表示の確認がおろそかになるため、意味のない文書が使用されるのだそうだ。

# おわりに
今回は、文書の体裁に関わるタグについて学んだ。
Lorem Ipsumが使われる理由が面白くて好き。

次回 >> [ここ](https://qiita.com/MakoMakoMakotsu/items/4c6c6fd62c133e8999f5)

## 参考
[2-1 見出し・段落（HTMLのテキスト）](https://www.youtube.com/watch?v=5PM7hVtWKsk&list=PLjw-30bsJNVU87F5iCPAW9kB4QDUGQxUG&index=5)
背景画像のみを透過する方法

# プログラミングの勉強日記
2020年6月6日　Progate Lv.83
ウェブページ制作中
背景画像を透過させたいのに、すべての要素が透過されてしまった。

##opacityを背景画像のみに適用する

```html:html
<div class="backgroundImage">
  <h1>背景画像だけにopacityを適用</h1>
</div>
```

```css:css
.backgroundImage{
  background-image:url("./photo/image.png");
  opacity:0.4;
}
```

　このように指定すると、`<h1>`にまでopacityが適用してしまう。そこで、 背景画像の上にrgbaを置いて背景画像だけを透過させるように見せる。

```html:html
<div class="backgroundImage">
  <div class="tentativeImage>
 　　 <h1>背景画像だけにopacityを適用</h1>
  </div>
</div>
```

```css:css
.backgroundImage{
  background-image:url("./photo/image.png");
}
.tentativeImage{
    /* 背景画像の上にrgbaを置いて背景画像のみを透過させる */
    background: rgba(255,255,255,0.5); 
}
```
laravelでテストするときは./vendor/bin/phpunit でもできるけど、php artisan testでもできるよ。

※タイトルが断定ですみません。筆者自身は実務でテストを書いたことがなく、家で書いている状態なので強い方のマサカリにとても弱いです。お気付きの際は、優しくお願いします。

laravelでテストを実行するとき```./vendor/bin/phpunit ```と実行しているページが多い印象なのでこれでもできるよというのを共有したくて書いています。

```bash
php artisan test

# result

   PASS  Tests\Feature\Http\Controllers\Api\UserControllerTest
  ✓ index status
  ✓ index
  ✓ store

  Tests:  3 passed
  Time:   4.42s
```

**結果が少しリッチになるのでおすすめです。**
実行したテストのメソッド名が表示されていい感じです。
(書きながら思ったのですが、phpstormとかで緑色矢印やショートカットで実行してたらそもそも./vendor/bin/phpunitは叩かないんじゃないかと思ってきました)

```XXXXTest.php
    public function testIndexStatus()
    {
      // 省略
    }

    public function testIndex()
    {
      // 省略
    }

    public function testStore()
    {
      // 省略
    }
```

参考ページ
[Testing: Getting Started \- Laravel \- The PHP Framework For Web Artisans](https://laravel.com/docs/7.x/testing#artisan-test-runner)

### 追記
[コメントより](https://qiita.com/yoshinyan/items/9cf36589078bb1da84be#comment-fdc4e425270d42e4dd26)
いただいたコメントを元に試してみました。
```php artisan test```でecho/var_dumpでコンソールに出力するには最後にexitしなければ出ませんでした。
そう考えると```./vendor/bin/phpunit```のほうが実践的かもしれません。
シェルスクリプトで呼び出し元の配列変数を読み取る

# はじめに
変数にセットした配列の値をシェルスクリプトから読み取ろうとした所、上手くいかなかったので自分なりの解決方法をメモします。

# 上手くいかなかった例
まず、以下の様なシェルスクリプトを想定します。

```bash

#! /bin/bash

ARRAY=(1 2 3)
echo "${ARRAY[@]}"
```

このスクリプトを実行すると以下の様になります。

```bash

$ ./test.sh
1 2 3
```

では、スクリプトを以下の様に修正し、`ARRAY`を呼び出し元から読み取るようにします。が、bashでは配列のエクスポートがサポートされていないようで、期待する結果にはなりませんでした。(参考: https://www.mazn.net/blog/2008/11/29/161.html)

```bash

#! /bin/bash

echo "${ARRAY[@]}"
```

```bash
$ export ARRAY=(1 2 3)
$ ./test.sh

```

# 解決方法
一旦配列の中身を環境変数として設定し、スクリプト内部で配列として再定義することで期待する結果を得ることができました。

```bash

#! /bin/bash

ARRAY=($ARRAY)
echo "${ARRAY[@]}"
```

```bash
$ export ARRAY="1 2 3"
$ ./test.sh
1 2 3
```


# 最後に
今回は、変数にセットされた配列の値をスクリプトから読み取る方法を書きました(厳密には配列は読み取っていないですが)。シェルスクリプトは初心者なのでこれが正しい方法なのかはわかりません。もっと良い方法があれば教えていただきたいです。
ESP32でLチカしてみる（part2）

# Goal
- ESP32でLチカする

前回ゴールできなかったのでリベンジ
https://qiita.com/suruseas/items/298ff6f8901d3cb08d3b

# 利用した開発ボード

ＥＳＰ３２－ＤｅｖＫｉｔＣ　ＥＳＰ－ＷＲＯＯＭ－３２開発ボード
http://akizukidenshi.com/catalog/g/gM-11819/

# 前回の反省点を踏まえて

前回最後の最後で躓いた、`アップロード時に ESP32のbootボタンを押し続けないといけない` という仕様？は、他のサイトでは「ボード上での操作は不要」と書いてあることがほとんどだったので、一旦mrubyを外れて、一般的なArduinoIDEのスケッチでLチカをやってからにしました。
結果、得た知見は `アップロード後にはリセットボタン(EN表記)を押さないとアップロードしたスケッチが反映されない` ということ。

==== ここから寄り道 ====
結果としてリセットボタンの押下は不要でした:wink:
==== ここからまで ====

よし、今日は早くクリアできそうな予感がしてきた:relaxed:

# 参考にしたサイト

ハンズ・オン - 3(しまねソフト研究開発センターさま)
https://www.s-itoc.jp/activity/research/mrubyc/mrubyc_tutorial/ESP32/869

# 配線

![Lchica.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/b531dd7e-7709-2799-af60-9ff0e2d22cc1.png)

安物LEDの仕様がよくわからないので抵抗は220Ωで試してみた。

# ソースコードの修正

手順は参考サイトのままですので、詳細は割愛。

```bash
cd $HOME/esp
git clone https://github.com/hasumikin/mrubyc-template-esp32.git led-blinking
cd led-blinking
```

```C:main/main.c
#include "driver/gpio.h"

#include "mrubyc.h"

#include "models/led.h"
#include "loops/master.h"

#define MEMORY_SIZE (1024*40)

static uint8_t memory_pool[MEMORY_SIZE];

static void c_gpio_init_output(mrb_vm *vm, mrb_value *v, int argc) {
  int pin = GET_INT_ARG(1);
  console_printf("init pin %d\n", pin);
  gpio_set_direction(pin, GPIO_MODE_OUTPUT);
}

static void c_gpio_set_level(mrb_vm *vm, mrb_value *v, int argc){
  int pin = GET_INT_ARG(1);
  int level = GET_INT_ARG(2);
  gpio_set_level(pin, level);
}

void app_main(void) {
  mrbc_init(memory_pool, MEMORY_SIZE);

  mrbc_define_method(0, mrbc_class_object, "gpio_init_output", c_gpio_init_output);
  mrbc_define_method(0, mrbc_class_object, "gpio_set_level", c_gpio_set_level);

  mrbc_create_task( led, 0 );
  mrbc_create_task( master, 0 );
  mrbc_run();
}
```

DIO4を使っているので修正しました。

```ruby:mrblib/loops/master.rb
led = Led.new(4)

while true
  led.turn_on
  sleep 1
  led.turn_off
  sleep 1
end
```

```ruby:mrblib/models/led.rb
class Led
  def initialize(pin)
    @pin = pin
    gpio_init_output(@pin)
    turn_off
  end

  def turn_on
    gpio_set_level(@pin, 1)
    puts "turned on"
  end

  def turn_off
    gpio_set_level(@pin, 0)
    puts "turned off"
  end
end
```

あとは、makeして（シリアルポートの設定して）からmake flashでアップロードです。

```
make
make flash
```

初回のmake時間がかかりますね:sweat_smile:

んで、今日はさすがに問題なくクリア！
ちなみにリセットボタンの押下は不要でした。

![l2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/2d10cba6-b099-79be-c787-3468bd7d4dd4.jpeg)

# 感想

ArduinoUNO + ArudinoIDEの安定コンビでLチカやる簡単さに比べるとかなり厳しい気がします…
rubyの開発効率の良さを体験するためには、高すぎるハードルを越えなければならずちょっとメインで使うかどうか躊躇してしまいました。ただ、マルチタスク機能はよさげなのでもう少し触ってみる予定です！

しばらくは

- ArduinoUNOでいろいろ実験
- ESP32で動作確認
- mruby/cに移植してESP32で動作確認

って感じになりそうな予感！
asyncの読み方

ネタ記事です。

皆さん、asyncってなんて読みますか？
私は"あしんく"って呼んでました。

[こちら](https://qiita.com/AtsushiEsashika/items/1a28df47e5454db172cb)の記事の内容をとあるオンラインセミナーで説明した際も、asyncを"あしんく"って呼びながら説明してました。
セミナー後に指摘をいただいたのですが、asyncよ読み方は"えいしんく"だそうです。
[こちら](https://ejje.weblio.jp/content/async)でも"えいしんく"って発音してます。

恥ずかしかったけど勉強になりました(/ω＼)

ちなみに、awaitは”あうえぃと”で良いみたいです！