OmniAICreator/Qiita-1.07M huggingface dataset:
AlmaLinuxにnetdataをインストールする際のメモ

AlmaLinuxにnetdataをインストールする手順
---

### 必要なパッケージのインストール
```:bash
dnf install autogen-libopts libuv
dnf install zlib-devel libuuid-devel libmnl-devel gcc make git autoconf automake pkgconfig json-c-devel
```
- `libuv-devel` をインストールするために、powertools リポジトリを有効化する
```:bash
vim /etc/yum.repos.d/almalinux-powertools.repo
# enabled=0
enabled=1

dnf update
dnf install libuv-devel
```


### netdataのインストール
- netdata のアップデートについても下記以降の対応となる。
- `--depth 1` オプションで、git clone で master ブランチにある最新のコミットだけを落としている。コミット履歴が大量にあるGitリポジトリでも，素早く落とすことができる。
- depth オプションを使用した git clone を シャロークローン (shallow clone) とも呼称する。
```:bash
mkdir -p /opt/src/
cd /opt/src/
git clone https://github.com/firehol/netdata.git --depth=1
cd netdata
./netdata-installer.sh --install /opt
```

### 起動＆自動起動の設定
今回、インストールした際は systemd にも登録されており、起動＆自動起動設定もされていました。 
`--dont-start-it` オプションを指定してインストールした場合はインストール後に netdata が起動されません。 
こういった場合に手動で起動＆自動起動設定を行う場合は以下のように設定します。

```:bash
systemctl daemon-reload
systemctl enable netdata
systemctl start netdata
```
起動したらWebサーバが19999ポートでListenしますので、下記の形のURLにアクセスします。
`http://<your-server-IP or Your-Server-Name>:19999`

### Apacheとの連携
firewallでポートを開放してもいいですが管理が煩雑になるのとベーシック認証を行いたいのでProxyで対応します。

```:bash
vim /opt/.htpasswd_netdata

<BASIC認証ユーザー>:<BASIC認証パスワード>
```

```:bash
vim /etc/httpd/conf.d/vhost.conf

<VirtualHost *:80>
ServerName XXX.XXX.XXX.XX
    <Location />
        AuthType Basic
        AuthName "Authentication for netdata"
        AuthUserFile /opt/.htpasswd_netdata
        Require valid-user
    </Location>
    ProxyPass / http://localhost:19999/
    ProxyPassReverse / http://localhost:19999/
</VirtualHost>
```

再起動後アクセスしBASIC認証付きでアクセスできることを確認します。
BASIC認証を設定することでnetdataのページがSEOに乗らないように対策もできます。

```:bash
httpd -t
httpd -k graceful
```
`http://<your-server-IP>` で確認。


### メール通知設定
デフォルトで以下のようなメール通知の設定がされている。メールサーバが入っている場合は、root宛にメールが送られる。宛先を変更する場合は `DEFAULT_RECIPIENT_EMAIL` を変更する。設定を変更後はサービス再起動を行う。  
`/opt/netdata/usr/lib/netdata/conf.d/health_alarm_notify.conf`
```
EMAIL_SENDER=""
SEND_EMAIL="YES"
DEFAULT_RECIPIENT_EMAIL="root"
```

メール通知の確認については下記コマンドを実行することでテスト通知が行える。
```
/opt/netdata/usr/libexec/netdata/plugins.d/alarm-notify.sh test
```

### Slack通知
メール通知をOFFにし、SlackメッセージをONにする設定を行う場合は、Slackのincoming WebhookでURLを取得後、SLACK_WEBHOOK_URLにそのURLを設定し、DEFAULT_RECIPIENT_SLACKにチャンネル名（#は省く）を設定しサービス再起動を行えば、そのチャンネル宛に通知が届くようになる。  
`/opt/netdata/usr/lib/netdata/conf.d/health_alarm_notify.conf`
```
# [Email]
SEND_EMAIL='NO'

# [Slack]
SEND_SLACK='YES'
SLACK_WEBHOOK_URL='https://hooks.slack.com/services/xxxx......'
DEFAULT_RECIPIENT_SLACK='netdata'
```
giboを使用して.gitignoreを作成したのに反映されなかった話

## 結論
```:PowerShell
gibo dump <使用している言語やプラットフォーム> | Out-File .gitignore -Encoding UTF8
```
.gitignoreの文字コードをUTF-8にすることで解決。

#やったこと
PyCharmでPythonを弄っているのでpythonとJetBrainsを指定している。
### giboで.gitignoreを作成

``` :Terminal
gibo dump python JetBrains >> .gitignore
git git status --ignored
--略
Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        .idea/workspace.xml
```

無視するファイルが足りてない。[^1] 
[^1]: 無視されているのはIDEが初期設定で指定しているもの。\_\_pycache\_\_やvenvディレクトリも無視されるはずだった。


###キャッシュの削除[^2]

``` :Terminal
git rm -r --cached .
fatal: pathspec '.' did not match any files
```

対象のファイルが存在しないと怒られる。`git add`してないので当然対象となるようなファイルは無い。
キャッシュが存在すると.gitignoreでは無視しなくなるが今回は当てはまらなかった。
ワイルドカードの指定がうまくできていなかったのかとしばらく`rm -r --cached`を試す。

### .config\git\ignoreを設定

``` :Terminal
gibo dump python JetBrains >> ignore
git git status --ignored
--略
Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        .idea/workspace.xml
        __pycache__/
        venv/
```

リポジトリ全体で共有されるgitignoreを設定したらとりあえず出来た。なんか気に食わないので削除して検索を続ける。

### 文字コードによって認識されないらしい
>どうやらPowerShellでリダイレクトして作成したテキストファイルは文字コードがUnicode（UTF-16LE）になるらしく、gitが認識してくれなかった模様。[^3]

``` :Terminal
git git status --ignored
--略
Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        .idea/workspace.xml
        __pycache__/
        venv/
```

文字コードをUTF-8にしたところ認識された。

### いっぺんに済ませたい
`gibo dump python JetBrains >> .gitignore`って入力してからテキストエディタ開いてUTF-8に変更してって作業になる。つらい。 ~~IDEなら文字コードを変換できることに今更気が付いた。もっとつらい。~~

``` :Terminal
gibo dump python JetBrains | Out-File .gitignore -Encoding UTF8
git git status --ignored
--略
Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        .idea/workspace.xml
        __pycache__/
        venv/
```
`Out-File`コマンドを使用して文字コードをUTF-8に指定する。

## giboの使い方
https://qiita.com/spiegel-im-spiegel/items/45a4619aafcacc161521

コードを落としてpath通せばいいというざっくりとした認識。

[^2]: https://qiita.com/fuwamaki/items/3ed021163e50beab7154
[^3]: https://qiita.com/ogsoon/items/a2325f44f558c4c4aceb ここを見ればこの記事なんていらない。先にこっちを見つけていればこの記事を書くこともなかった。
HDFについて② 〜File Objects〜

備忘録です。かなり初心者なので、どしどしご指摘お願いします。
https://docs.h5py.org/en/latest/index.html
を参考にしています。

```py
#準備:h5pyパッケージ&HDF5ファイルの読み込み
import h5py
f = h5py.File('myfile.h5','r+')
#r・・・read only ファイルは存在しなくてはならない
#r+・・・Read/write　ファイルは存在しなくてはならない
#w・・・create file 新規作成。既存なら初期化
#w-・・・create file 新規作成。既存なら失敗
#a・・・Read/write 新規作成。既存なら別に作成（名前がダブるので注意）。
```
ファイルは使い終わったら閉じるといいみたいです。
##File drivers
ファイルを開くときに、どのドライバを使用するか選べるみたいです。僕はこのコマンド使いません。なんだかよくわからなかったから。そもそもfile driversって何者ですか。
(あとで追記します。きっと)

##Python file-like objects
io.BytesIOやtempfile.TemporaryFileといった、Pythonファイルのようなオブジェクトについて。一時的にHDF5を作成するときに便利。

これらのオブジェクトはバイナリ形式で開かれ、read(),write(), seek(),tell(),truncate(),flush()といったメソッドを持つ必要がある。

これもよくわかりませんでした。
(あとで追記します。きっと)
#####※注意！
pythonなどでHDF5ファイルをいじっているときは、Pythonより先にHDF5を閉じるように！だそうです。

##Closing files
####strong closing
File.close()と記述するor with h5py.File(...)を離れること。ファイルは閉じられ、オブジェクトは使えなくなる。
####weak closing
オブジェクトコードがPythonのコードがカバーする範囲を超えたとき、そのPythonコードに属するオブジェクトがなくなったときに閉じられる。（Pythonの方のファイルが消えたときとかでしょうか？）

正直、後者はいつ使うかわかりません。

##Filenames on Linux
(自分がLinux使うのでこれしか読んでません。。）
unicode文字を使うのはノープロブレム。しかし、エンコードされたbytesを使うとたまにおかしくなる。
(あとで追記します。きっと)
M1 MacでOAK-Dを動かす


#0 はじめに
[OAK-D](https://store.opencv.ai/products/oak-d)の[デモコード](https://docs.luxonis.com/en/latest/#demo-script)を実行するまでの手順です
![スクリーンショット 2021-08-27 16.37.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84072/b088b9fc-f09f-96c7-78ce-234304bdb66b.png)

### やってみて
* ターミナルはRosetta2を使用する
* 元々ARM環境でHomebrewを使用していたのですが、Rosetta2環境と別々でインストールすることができ、両立できています

##参考にさせていただいたページ
###Rosetta2とHomebrewのインストール
https://zenn.dev/_lambda314/articles/63b851221a7016

###OAK-Dで遊んでみる
https://zenn.dev/karaage0703/scraps/79299ef4063626

#1 動作環境
* M1 Mac
* macOS Big Sur 11.5.2

#2 環境構築

## 1 Rosetta2とHomebrewを導入
こちらのリンク先通りにやりました。Rosetta2とNative環境の切り替えまでできるようにしてくれているのでとても助かりました。
https://zenn.dev/_lambda314/articles/63b851221a7016

##2 実行環境の準備
###2-1 Miniforgeのインストール

```
brew install miniforge
```

###2-2 仮想環境を準備
仮想環境を使用した方がなにかといいので作ります

```
conda create -n depthai python=3.8
```

###2-3 初期設定
```
conda init zsh
```

を実行後、ターミナルを一度終了し、再度立ち上げる
※デフォルトはbashに設定されており、現在のmacOSのターミナルはzshなので、設定を変更します

###2-4 仮想環境をアクティベート

```
conda activate depthai
```

### 2-5 必要なパッケージのインストール
[こちら](https://docs.luxonis.com/projects/api/en/latest/tutorials/hello_world/)に書いてあるパッケージインストールコマンドを実行します

```
python3 -m pip install numpy opencv-python depthai --user
```

上記ページに書いてあるGithubページへ行くとhello_world.pyを入手できますので、それを実行してみると画像認識ができます
![スクリーンショット 2021-08-27 15.48.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84072/540f4de6-fb50-c760-4bc0-f0363632be15.png)


#3 デモ実行
[こちらのページ](https://docs.luxonis.com/en/latest/#demo-script)に書いてあるとおりに進めます。

![スクリーンショット 2021-08-27 16.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84072/67c8ac59-ed93-e501-735f-2e7b3a6bfc5e.png)
EJSで何が入ってるかわからない文字列をJavaScriptの変数に渡す

# はじめに
基本的なEJS構文についてはmiwashutaro0611様の記事を参考にしてください。

https://qiita.com/miwashutaro0611/items/36910f2d784ff70a527d

#### 追記
できれば<%- %>を使いたくないので

```javascript
<% var json_ejs = encodeURIComponent(JSON.stringify({markdown:markdown})) %>
<script language="javascript" type="text/javascript">
 const json = "<%= json_ejs%>";
 var markdown = JSON.parse(decodeURIComponent(json)).markdown;
</script>
```
の方がいいかもしれません。

# 変換
次のように変換します。

```javascript
<%# markdown は何が入っているかわからない文字列です。%>

<% var json_ejs = JSON.stringify({markdown:encodeURIComponent(markdown)}) %>
<script language="javascript" type="text/javascript">
 const json = <%-json_ejs%>;
 var markdown = decodeURIComponent(json.markdown);
</script>

```

---
# 以下 説明(試したこと)
### 普通の渡し方
普通にやると

```javascript
var text = <%= markdown %>
```

ですが改行や"などに対応していません。

### JSON.stringify と <%- %>
json形式に変換した後、<%- %>でオブジェクトとして出力します。

```javascript
<%# markdown は何が入っているかわからない文字列です。%>

<% var json_ejs = JSON.stringify({markdown:markdown}) %>
<script language="javascript" type="text/javascript">
 const json = <%-json_ejs%>;
 var markdown = json.markdown;
</script>

```

ですが<%- %>で出力するため

```javascript
var markdown = 'console.log("💩");</script>';
```
のようにscriptタグを含まれると💩だけ残して強制終了します。

# encodeURIComponentとdecodeURIComponent
一時的にencodeURIComponentを通してタグをエスケープします。
参考: https://shanabrian.com/web/javascript/escape-encode-uri-component.php

```javascript
一番上のコード
```

# おわりに
間違いやもっと良い方法がありましたらコメントをお願いします。
rails5にBootstrap5を導入する。

Bootstrap5を導入する記事がrails6のものばかりだったので一応。
当方はrailsチュートリアルを無料で読むためにrails5.2を利用しています。

なお、超初心者向けの記事のため記載しておきますと、
Bootstrap5はIE11以下、初期のEdgeには対応しておりません。
また、紹介するBootstrap関連の便利gemがまだまだBootstrap4対応なので、Bootstrap4にしておいたほうがいいと思います。
こちらでそんなに問題なく動いているバージョンで追加していっています。

# Bootstrapと依存popper.js
```ruby:Gemfile
gem 'bootstrap', '~> 5.1.0'
gem 'popper_js', '~> 2.9.3'
```

```scss:assets/stylesheets/application.scss
 @import "bootstrap";
```

```js:assets/javascript/application.js
//= require popper
//= require bootstrap-sprockets
```

これだけ。`application.js`のpopper.jsは上に書かないといけないらしいですが試していません。

JQuery依存はなくなりましたがハンバーガーメニューなど、Javascriptが不要になったわけではなかったです。
記事を書いている私も初心者過ぎてそのへんよくわかっていませんでした。

bundle installもお忘れなく。

```
bundle install
```

JQueryが必要になれば、追加で導入すれば問題なく利用できます。

# ついでにBootstrap_formを導入
Bootstrapでラクをするくらいですから、Formもラクをしていきましょう。
ただ、Bootstrap5対応はまだ開発中であり、たまにissueにひっかかることもあります。
それでも、めちゃくちゃ便利でcrispyです。

```ruby:Gemfile
gem "bootstrap_form", git: "https://github.com/bootstrap-ruby/bootstrap_form.git", branch: "bootstrap-5"
```

```scss:assets/stylesheets/application.scss
@import "rails_bootstrap_forms";
```

## 注意点
何度も記載しておりますが、IE11非対応です。
polyfillを入れることで対応するらしいですが、もし確認する機会があればやってみたいと思います。

[polyfill](https://github.com/twbs/bootstrap/pull/30377/commits/e95558e18a3d9eb6a15bc0aa93f78aa6a43ff134)
または
[polyfill.io](https://coliff.github.io/bootstrap-ie11/)


#### 参考

[twbs/bootstrap-rubygem](https://github.com/twbs/bootstrap-rubygem/blob/master/README.md)
[bootstrap-ruby/bootstrap_form](https://github.com/bootstrap-ruby/bootstrap_form/tree/bootstrap-5)
.NET 5.0 でSystem.Windows.Formを使うコンソールアプリ　--メモ--

以前、.NET framework 4.xでコンソールアプリを作ったのだが、その中で　System.Windows.Forms.Clipboardクラス　を使っている。
これを.NET5.0 (旧称 .NET Core)で作り直したいと思ったら、予想外に大変だった。参照の追加で.NET Frameworkにはあったはずのアセンブリの項目がどこにもない。
また、.NET5.0ではマルチプラットフォームを意識したものになった分、Windowsで従来通りシンプルに使いたいだけの者には敷居が高くなっている気がするが、こちらが正式な.NET Frameworkの後継であるようなので乗り換えてみたい。

以下、メモ。

新規で.NET 5.0のコンソールアプリのプロジェクト作成。
ソリューションエクスプローラ > プロジェクトファイルの編集

すると、デフォルトで以下の通り。

```xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

```

OutPutTypeだけを残して、これを以下のように修正。

```xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <!-- ここから -->
    <TargetFramework>net5.0-windows</TargetFramework>
    <DisableWinExeOutputInference>true</DisableWinExeOutputInference>
    <UseWindowsForms>true</UseWindowsForms>
    <!-- ここまで -->
  </PropertyGroup>

</Project>

```

    <DisableWinExeOutputInference>true</DisableWinExeOutputInference>
    <UseWindowsForms>true</UseWindowsForms>

は２つ揃ってはじめてコンソールのウィンドウが出てくるようだ。

これで準備完了。

```csharp
using System;
using System.Windows.Forms;

namespace ConsoleApp7
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Console.WriteLine("コピーしてあるテキストを表示。");
            if (Clipboard.ContainsText())
            {
                Console.WriteLine(Clipboard.GetText());
            }
        }
    }
}

```

[参考]
[WPF/Windowsフォームに関する.NET 5の大きな変更 ](https://www.infoq.com/jp/news/2021/02/net-5-breaking-changes-windows/)
[.NET 5 プロジェクトの TargetFramework](https://rksoftware.hatenablog.com/entry/2020/10/12/220814)
vue.js で element ui rate が何度も動いてしまう

elment ui の el-rate を使って

・ユーザーのID
・スコア

を取得して axios したい。
しかし、1度クリックしたら何度も動いてしまう。

結論
`@change.once` を使おう！

```vue

<template>

    <div>
            <div v-for="(v,key) in list">
                イケメン度 {{list[key].ikemen}}
                <el-rate v-model="list[key].ikemen" @change.once="ikemenRate(key)"></el-rate>
            </div>
    </div>

</template>

<script>



    export default {

        data () {
            return {
                list:[]
            };
        },

        methods: {

            ikemenRate(key){

                let dataform = new FormData();
                dataform.append('id',this.list[key].id);
                dataform.append('ikemen',this.list[key].ikemen);

                axios.post('/user/ikemenRate', dataform).then(e => {
                    console.log(e.data.res);
                    console.log(" イケメンレート 成功");
                }).catch((error) => {
                    console.log(" イケメンレート エラー");
                });
            },
        },


    }
</script>



```
【機械学習初心者】部屋の広さから家賃を予測


##はじめに

機械学習の知識を使って財務シュミレーションを簡潔に行いたいと思いPythonで実装してみました。


##対象者
* 機械学習初心者
* 財務シュミレーションなど行いたい方


##開発した時の環境
```
version 
Python 3.8.5
Homebrew 3.0.2 
jupyter notebook
```

##単回帰分析の実装

部屋の広さx家賃がy万円

##まず取り込みたいCSVデータをインポートします

```
import pandas as pd
df = pd.read_csv('sample.csv')
```

#グラフ描画ツールMatplotlib
```
import matplotlib.pyplot as plt
```
#xとyの散布図プロット
```
plt.scatter(x, y)
plt.show()

```
![Screenshot 2021-08-16 at 14.24.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412087/30e9bff6-c175-802d-6f75-0884ed13b655.png)

```
#予測値
xx = x*x
xy = x*y
a = xy.sum()/xx.sum()

plt.scatter(x,y, label='y')
#学習フェーズ
plt.plot(x, a*x, label='y_hat', color ='red')
plt.legend()
plt.show
```
![Screenshot 2021-08-18 at 12.43.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412087/fc9e9420-2693-2b63-426d-96967994cbfc.png)

```
#予測値
x_new = 1000 #○○平米の部屋
mean = df.mean()
mean['x']

xc = x_new - mean['x']
xc 

yc = a*xc

y_hat = a*xc + mean['y']


def predict(x):
    
 a = 30069.022519284063
 xm = 37.622219999999999
 ym = 121065.0
 xc = x - xm 
 y_hat = a*xc + ym

 return y_hat  
```
[初心者向け]WindowsにPythonをインストールする前に読んでほしい

# はじめに

WindowsでPython環境を構築する際、いろんな方法が出てくるので、初心者にとって何がベストか分かりません。
Pythonの場合は開発コミュニティが活発であるため、Python本体やライブラリも含めて頻繁にバージョンアップされます。
ただバージョンアップすることで、環境起因のバグが発生して、沼にハマってしまうことがあります。
そこで、このような問題を避けるため、バージョン別のPython仮想環境を構築するのが定石です。
今回、Python仮想環境を構築するシンプルな方法について、まとめます。

# Python環境構築の流れ

[1.インストーラを入手](#1-インストーラを入手)
[2.インストール先ディレクトリを作成してPythonをインストール](#2-インストール先ディレクトリを作成してPythonをインストール)
[3.仮想環境用のディレクトリを作成して仮想環境を構築](#3-仮想環境用のディレクトリを作成して仮想環境を構築)
[4.仮想環境にライブラリをインストール](#4-仮想環境にライブラリをインストール)

#1. インストーラを入手

https://www.python.org/downloads/

こちらのサイトからインストーラをダウンロードします。

#2. インストール先ディレクトリを作成してPythonをインストール

任意の場所にインストール先ディレクトリを作成します。
（今回はユーザディレクトリにpyverというフォルダを作りました。）

インストーラを起動してCustomize installationをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/6e1a58ce-4e64-0fa7-98a3-0250b5e2e063.png)

インストール先ディレクトリを指定して、更にPythonバージョンがわかるようにディレクトリを指定します。（今回はpy383とした）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/58557fd7-c576-0070-9759-a6995913799c.png)


#3. 仮想環境用のディレクトリを作成して仮想環境を構築

仮想環境用のディレクトリを作成します。
（今回はユーザディレクトリにpyprojというフォルダを作りました。）

コマンドプロンプトを起動して、作成したディレクトリに移動します。
その後、先程インストールしたpythonのコマンドで仮想環境を作成します。
（今回はmy_envという仮想環境名として作成しました）

```powershell
c:\Users\[ユーザ名]\pyver\py383\python -m venv my_env
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/abdead9a-56eb-a77a-189e-54312f4d20c4.png)


[仮想環境名]\Scripts\activateと実行することで、仮想環境に切り替えができます。
pythonと実行することで、Python Shellが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/e6b68f93-27ba-5b88-9243-1ab2136125cb.png)


#4. 仮想環境にライブラリをインストール

pip installコマンドでPythonライブラリをインストールします。
インストール後、importすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/eb28c8ff-b7d2-362c-097c-9d03983d8444.png)


# まとめ

WindowsにPython仮想環境を構築して、ライブラリをインストールする手順をまとめました。
新しいバージョンのPythonが出た場合も、同様の手順で環境を構築することが可能です。
余計なシステムファイルが増えたり、環境変数が変更されるなど、PC環境を汚さず構築できるため、おすすめです。

以上です。
"/"を忘れたかっただけなのに

こんにちは。つんあーです。

みなさん、JS（あるいはTS）でファイルパスを操作する時、どうしていますか？
（紛らわしいのですが、今回はブラウザが対象の話です。Node.jsはそんなに悩まないですからね）




パスの末尾の`/`の扱いって、なかなか困りますよね。
こんなのとか、

```javascript
const url = location.href;
fetch(url + '/data.json').then(... // /は必要なんだっけ🤔

// => 404 : http://localhost/page//data.json
// 違う、そうじゃないの
```

あるいはこんなのとか、

```javascript
const url = location.hostname;
fetch(url + 'data.json').then(... // /は必要なんだっけ🤔

// => 404 : http://localhostdata.json
// お゛お゛お゛お゛ん
```

みたいなやつです。
私はよくこんなことをやってます。きっとあなたも1度はやったことあるはず。
1度と言わずに週1回くらいやってるはず。きっと。



ところでPythonの[pathlib](https://docs.python.org/ja/3/library/pathlib.html)は、便利ですよね。


```python
import pathlib

path = pathlib.Path('Users/hoge')
filepath = path / 'data.csv'
print(str(filepath))

# => "Users/hoge/data.csv"
```


**JSでもこんな感じに`/`の有無とか無視したい！**
**ってかNode.jsには`path`モジュールとかあるんだからイケるっしょ！**

と思って調べたのですが、
*「js パス 解決」*
とか
*「js パス　モジュール」*
とかでググろうもんなら、

*「Webpackでimportのパスを解決する方法」*やら
*「TypeScriptでWebpackのimportがエラーになる」*とか
*「Webpack5からはNode.jのspolyfillが標準装備されなくなったから`path`モジュールを使うには云々...」*

みたいなものばっかりでなかなか必要な情報（=ブラウザでさくっと使えるパス関係モジュール）にたどり着けませんでした。

（ってかimport関連詰まりやすいよねぇ）


# 結論（Webpack5以上）

```
$ npm i -S path-browserify
```

```js
import path from 'path-browserify';

const url = path.join('hoge/', '/fuga');
console.log(url);

// => 'hoge/fuga'
```

なお、TypeScriptの場合は型定義ファイルに以下を追加する必要があります。

```index.d.ts
declare module 'path-browserify' {
    import path from 'path'
    export default path
}
```






おしまい。
powershellとは何か？～初学者の忘備録～

##今回powershellを学習した背景
powershellを業務で使用するようになるのですが、サーバー構築や運用の際に構文を打つ程度で知識が乏しかったため、まずは概要から学習しようと考えました。

##そもそもpowershellとは
MicroSoft社が開発したオブジェクト指向の言語

##powershellおすすめのポイント
・Windowsにインストールされているため、使う前の準備が不要
　⇒開発環境の構築が不要
・pwoershell ISE という機能により、初心者でも命令文のミスに気づきやすくなる
　⇒命令文を実行するとどのような動作が行われるかを調べることが出来る
　「デバック」という統合開発環境ツールのおかげ

##powershellでできること
・PC上での操作を肩代わりしてタスク自動化できる
・複雑な自動化をスマートに実装できる
　⇒ややこしい条件分岐やさまざまなプロパティへの同時アクセス、並列処理など
・officeを操作できる
　⇒COMオブジェクトというソフトウェア利用のための外部接続用オブジェクトを
　　利用できるから　



##powershellの基本文法
・文字列の出力
　⇒Write-hostコマンドレットを用いることで画面にに文字列を出力
・変数と変数対応展開
　⇒$変数名＝代入する値という記法で、変数の宣言/代入を行える
・四則演算
・if文
　⇒「もし～なら、～する」という処理を行う基本的な構文
・パイプ
　⇒左辺の処理の実行結果を右辺の処理の入力情報”として渡せる


参照サイト
https://goworkship.com/magazine/powershell/#PowerShell-2
https://www.fenet.jp/infla/column/technology/
オブジェクト指向とは何なのか？（今理解できる範囲でまとめてみる）　初心者なりに

<h2>オブジェクト指向</h2>
これまで何回か目にし、その度に調べてるけどよく理解できていません。
こういうのって、実務経験積んでくうちに理解できてくるものなんじゃないのかな・・・と
現状あんまり理解できていない私としては思います。

Rubyはオブジェクト指向言語、JavaもJavascriptもそうらしいです。
で、オブジェクト指向って一体何なのか。。

<h2>効率よく開発するための考え方</h2>
何かのコード記述のルールがあって、それがオブジェクト指向っていうわけではなく、、
「効率よく開発をするための考え方や概念」だそうです。

<h2>特徴①カプセル化</h2>

「オブジェクト」というものが、データやメソッドなんかを一つのカプセルにまとめてしまうようなイメージです。
カプセル化されてしまうと、外からは中がどうなってるか見えません。
情報がカプセルにより「隠されている」これがカプセル化です。
カプセル化することで他からの影響を受けにくく、カプセルごと分けて考えることができます。

<h2>特徴②継承</h2>
同じようなプログラムはまとめていこうという考え方。
よく例に出てくるのが車ですね。
車という上位クラス（スーパークラス）から派生したものが、
乗用車やバス、トラックです。←下位クラス（サブクラス）になります。
乗用車もバスも結局は車なので、上位クラスの特徴を受け継いでることになります。
これが継承です。

<h2>特徴③ポリモーフィズム</h2>
同じメッセージを複数のオブジェクトに送った結果それぞれが、
固有の処理を行うこと。これをポリモーフィズム（多態性といいます。）
車でいうと、バスはバスの機能をするよねーっていうことです。



<h2>まとめ</h2>
カプセル化・・他から影響受けない、破壊されない
継承・・同じようなプログラムはまとめていこう
ポリモーフィズム・・汎用性を持つ
[iOS] URLSchemeで起動した時のAppDelegate/SceneDelegateの呼び出し順序

※本記事の前提環境：Xcode 12.5.1

AppDelegate/SceneDelegateを両方実装している場合に、URLSchemeのトリガーによって、URLパラメータ取得系のdelegateメソッドがどのように走るのかを調査しました。

結構メンドクサイなと思いました…

なお、アプリ未起動状態でURLSchemeによってアプリが起動された場合のデバッグについては、以下の記事を参考にさせていただきました。

https://qiita.com/AlecYawata/items/79f45e85ecc573860dcb

# iOS 13以降

注：URLパラメータ取得系のdelegateメソッド以外については省略しています。

## アプリ未起動状態

1. AppDelegate - application(_ :didFinishLaunchingWithOptions)
2. SceneDelegate - scene(_ :willConnectTo :options)

※注：scene(_ :openURLContexts)は呼ばれない

## アプリ起動状態

1. SceneDelegate - scene(_ :openURLContexts)

# iOS 12以前

## アプリ未起動状態

1. AppDelegate - application(_ :didFinishLaunchingWithOptions)
2. AppDelegate - application(_ :open :options)

## アプリ起動状態

1. AppDelegate - application(_ :open options)
ArduinoUno で温度湿度センサーを使う

![IMG_20210827_155836.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/f7895baf-3fe5-e82b-ff1d-9ff15e4a59d3.jpeg)

こちらで構築した環境で、温度湿度計を使ってみました。
[ArduinoUno で LCD モジュールを使う](https://qiita.com/ekzemplaro/items/a8569f99f5e541798c89)

温度湿度計は
Temperature & Humidity Sensor pro v1.3 です。

ライブラリーはこちらです。
[ Seeed-Studio / Grove_Temperature_And_Humidity_Senso](https://github.com/Seeed-Studio/Grove_Temperature_And_Humidity_Sensor)

ライブラリーのインストール

```bash
cd ~/Arduino/libraries
git clone https://github.com/Seeed-Studio/Grove_Temperature_And_Humidity_Sensor.git
```

```text:temperature_humidity/temperature_humidity.ino
// ---------------------------------------------------------------
/*
	temperature_humidity.ino

					Apr/27/2021
*/
// ---------------------------------------------------------------
#include "DHT.h"
#include "rgb_lcd.h"

#define DHTTYPE DHT22
#define DHTPIN 8 
DHT dht(DHTPIN, DHTTYPE);

rgb_lcd lcd;

int count = 0;
// ---------------------------------------------------------------
void setup()
{
	dht.begin();
	lcd.begin(16,2);
	lcd.setRGB(0, 64, 64);

	Serial.begin(9600);

	Serial.println("*** temperature_humidity.ino *** start ***");
	Serial.println("*** Aug/27/2021 PM 16:18 ***");
}

// ---------------------------------------------------------------
void lcd_display_proc(float temp_hum[])
{
	lcd.setCursor(0,0);
	lcd.print(String(temp_hum[0]) + " C");
	lcd.setCursor(0,1);
	lcd.print(String(temp_hum[1]) + " %");

	Serial.print("temperature = ");
	Serial.print(temp_hum[0]);
	Serial.print("C  ");
	Serial.print("Current humidity = ");
	Serial.print(temp_hum[1]);
	Serial.println("%");
}

// ---------------------------------------------------------------
void loop()
{
	float temp_hum[2] = {0};

	Serial.print("count = " + String(count) + "  ");

	if (!dht.readTempAndHumidity(temp_hum))
		{
		lcd_display_proc(temp_hum);
		}
	else
		{
		Serial.println("ERROR! *** TemperatureAndHumidityRead");
		}

	delay(3000);

	count++;
}

// ---------------------------------------------------------------
```
Docker runのオプションについてまとめてみた

別の記事に投稿している内容に関連して、Docker Runのオプションについて少し調べてみました。
[参考ページ](https://haronoid.hatenablog.com/entry/2017/10/12/191406)

# コンテナの作成・実行
SonerQubeのコンテナ作成で↓こんなコマンドを実行してます。
```docker run -itd --name sonar -p 9000:9000 sonarqube```

## runについて
まずは```run```について、```run```は```create```＋```start```コマンドを合わせたコマンドになっていて。

|コマンド |　　　　　 概要 |
|:--|:--|
| ```run```  | ```create```＋```start```  |
| ```create```  | コンテナ作成のみ行われる  |
| ```start```  | 作成済みのコンテナを開始する  |

## オプション
上記で使用している```-itd```は下にある```-i```,```-t```,```-d```を合わせたオプション

|　　コマンド |　　　　　 概要 |
|:-----|:--|
| -i, --interative=false  |  コンテナの標準入力を開く |
| -t, --tty=false  | tty(端末デバイス)を使う  |
| -d, --detach=false  | バックグラウンドで実行する  |
| --name  | コンテナ名  |
| -p | {ホストのポート}:{コンテナのポート}  |

# 関連記事

- [よく使いそうなDockerコマンドをまとめてみた](https://qiita.com/beeeegle/items/dbba416810ee75bbdd92)
unity ios書き出しのスプラッシュを任意の色にする

#環境
Unity 2019.4.15
Xcode 12.4

この環境でデフォルトで書き出すと、黒に近い灰色のスプラッシュになります
Unityで黒のpngを設定しても、思った効果になりませんでした
仕様が変わったようでXcodeのStoryBoardから読んでるらしいです。

#解決策
一応、ビルドが通りましたが
いいのか、悪いのか、、、

１、Unityのスプラッシュ設定は、デフォルトのまま（show Splash Screen OFF）書き出し
２、Xcodeで、StoryBoardを開きRootViewの下を削除する　
３、RootViewのBackgroundとTintを任意の色にする

![スクリーンショット 2021-08-27 15.33.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514937/e119cf5e-c660-332e-3a76-8921de926efd.png)
学習メモ(2021/8/27)

##コマンドライン
###  ファイルとディレクトリ削除
確認なしで削除可能

``` 
rm -rf ディレクトリ名
```   
##Git
###フォーク
他人のリポジトリを自分のアカウントにコピーする時に用いる

###ブランチを作成して移動する  
```
git checkout -b ブランチ名
```  
###ブランチをリモートにpush  
HEADとすることでブランチ名を打たなくて良くなる  

```
git push orgin HEAD
```
###originとは  
git push origin masterのoriginって何なの？って思っていましたが、ローカルでのリモートリポジトリの呼び方とのこと。デフォルトでoriginという名前になっているけど、repoAみたいに自由に舐めをつけることも可能。
ラズパイでelecomのwifiドングルを使用する

## 環境
動作確認日：2021-03-20

- raspberry pi 2 B
- raspbian
- wifiドングル(ELECOM WDC-150SU2MWH)

## 手順
### Step1　準備
`lsusb`でwifiドングルが認識されているかチェックする。
認識されていれば、`uname -a`で全てのシステム情報を表示させ、バージョンをチェック。

### Step2 ドライバのダウンロード
Step1で確認したバージョンと合致するものを[http://downloads.fars-robotics.net/wifi-drivers/8188eu-drivers/](http://downloads.fars-robotics.net/wifi-drivers/8188eu-drivers/)のドライバ一覧からwgetで取ってくる。
例えば、step1の結果が 

```
Linux raspberrypi 4.4.8-v7+ #881 SMP Sat Apr 30 12:16:50 BST 2016 armv7l GNU/Linux 
```
だった場合、ダウンロードするのは8188eu-**4.4.8-v7-881**.tar.gz.になる。

### Step3 インストール
Step2でダウンロードしてきたドライバをtarで解凍。
`tar xzf 8188eu-4.4.8-v7-881.tar.gz`

以下でインストールする。
`./install.sh`

### Step4 確認
`sudo reboot`して、wifiにつながれば成功です。

## 参考
http://teppodone.hatenadiary.jp/entry/ELECOM_WDC-150SU2MonRaspberryPi

https://www.raspberrypi.org/forums/viewtopic.php?p=462982%EF%BC%8C2017/08/31%E9%96%B2%E8%A6%A7
SonarQubeをDockerで立ち上げた時の話

SonarQubeで何かできるか、どこまでの精度なのかを調査する前段階として導入までの手順をまとめます。

参考にした記事
https://qiita.com/takao-takass/items/5d54768ad0d315d3dad4

Dockerのコンテナを使えば楽々導入できました。
詰まったのはポート設定くらいでした。

# 実施環境

- Windows10 Pro<br>
Windows10 へDockerインストールについては [コチラ](https://docs.docker.jp/docker-for-windows/install.html) を参照。


# SonarQubeコンテナ作成

1. コマンドプロンプトを開いて、[dockerSonarQubeページ](https://hub.docker.com/_/sonarqube) に載ってるコマンドを実行します。
```docker pull sonarqube```

1. Docker Run
SonarQubeのポートは9000なので、ポートフォワーディングで9000に接続します。
（特に設定しないと、任意のポートが割り振られたので、要検証・・・）
```docker run -itd --name sonar -p 9000:9000 sonarqube```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/9ea46bc4-1ff6-b980-0315-ea251fa1dcb3.png" width=70%>


# SonarQubeのページにアクセスする

ブラウザを起動して下記にアクセスします。
```http://localhost:9000```
もしくは、
```http://{hostネーム or IPアドレス}:9000```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/68b702fd-8329-81e1-01c3-680a9d95f8f8.png" width=70%>

わー！開けました！


# 関連記事
- [SonarQube＋WindowsでPHPソースをスキャンする](https://qiita.com/beeeegle/items/ee38f03cdcf99a028692)
- [よく使いそうなDockerコマンドをまとめてみた](https://qiita.com/beeeegle/items/dbba416810ee75bbdd92)
DataFrameでcolumn名の異なる列を縦に結合する。

# 状況
### DataFrameのColumn名の異なる列を、ひとつの列にしたい。

まず仮のDataFrameを用意します。

```python
import pandas as pd

list_A = [["apple", 100], ["banana", 200], ["orange", 300]]
list_B = [["potato", 30], ["carrot", 20], ["lettuce", 10]]


df_A = pd.DataFrame(data=list_A, columns=["fruits", "price"])
df_B = pd.DataFrame(data=list_B, columns=["vegetables", "weight"])

```
|  | fruits | price |
|:-:|:-:|:-:|
| 0 |  apple	 |  100 |
| 1  | banana  |  200 |
| 2 | orange  | 300  |

|  | vegetables | weight |
|:-:|:-:|:-:|
| 0  | potato  | 30  |
| 1  |  carrot | 20  |
|  2 |  lettuce | 10  |

例えば、fruitsの列とvegetablesの列を一緒のfoodの列にしたいとします。

このままpandasの関数concatで2つのDataFrameを縦結合をしようとすると、以下のようにfruitsとvegetablesの列は別の列になってしまします。

```py
# 縦結合
df_food = pd.concat([df_A, df_B], ignore_index=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/900476/f4d14249-d519-1939-fa0e-da11ca7b5c85.png)

絶妙に困りますよねこれ…。

# 解決策
### 名前を一致させてから、結合する。

```py
# colum名変更
df_food_A = df_A.rename(columns={'fruits': 'food'}) 
df_food_B = df_B.rename(columns={'vegetables': 'food'})
# 縦結合
df_food = pd.concat([df_food_A, df_food_B], ignore_index=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/900476/bf8937b1-9b5f-0c0f-87e0-04cbd6a417c2.png)

# 解説

### colum名変更
`データ.rename(columns={'変更前の名前': '変更後の名前'})`でDataFrameのcolum名を変更できます。

```py
# colum名変更
df_food_A = df_A.rename(columns={'fruits': 'food'}) 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/900476/b98c5138-4125-f13f-52d3-158858062069.png)
これは便利ですね。

### 縦結合
`concat`で縦に結合します。
名前が同じものは、統合されるようです。

このとき、`ignore_index=True`を引数に指定しておくことで、index番号をきれいに順番にすることができます。

```py
df_food = pd.concat([df_food_A, df_food_B], ignore_index=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/900476/703aad2a-0364-8c36-9c5a-2135daed9084.png)


# 参考
下記を参考にさせていただきました。
[ラベル名が異なる場合のmergeについて](https://ja.stackoverflow.com/questions/56037/%e3%83%a9%e3%83%99%e3%83%ab%e5%90%8d%e3%81%8c%e7%95%b0%e3%81%aa%e3%82%8b%e5%a0%b4%e5%90%88%e3%81%aemerge%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6)
[Pandas](https://qiita.com/ksktkd/items/3bf9bddd4424a1ef9dd8)
[指定した軸の方向にDataFrameを結合するPandasのconcat関数の使い方](https://deepage.net/features/pandas-concat.html)


### 読んでいただき、ありがとうございました。
NFCpyでタグに書き込む


#hardware

https://www.rfid-nfc-realtouchshop.com/shopdetail/000000000146/

https://pur.store.sony.jp/pasori/products/RC-S380/RC-S380_product/

#setup
brew install libusb
pip3 install nfcpy

#script 
公式のものを改変

```python:nfcwriter.py

import nfc
import sys

def on_connect(tag):
    global data 

    if tag.ndef is not None:
        for record in tag.ndef.records:
            print(record)
        if tag.ndef.is_writeable:
            from ndef import TextRecord
            tag.ndef.records = [TextRecord(data)]
            print("write complete")

def main():

    with nfc.ContactlessFrontend("usb") as clf:
        rdwr = {
            'on-connect': on_connect
        }
        clf.connect(rdwr=rdwr)
     
        
if __name__ == '__main__':
    global data 
    if len(sys.argv) > 1:
        data=sys.argv[1]
        print("Put NFC-Tag")
        main()
    else: 
        print("Need Record-Text")
```

#実行
python3 nfcwriter.py helloworld
GitリポジトリをGitHubに移行する手順（Gitコマンド編）

## 1.移行元のリポジトリURLをコピーする
移行元リポジトリにある`.git`で終わるURLをコピーします。
コピーしたURLは`SOURCE_REPOSITORY_URL`と呼びます。

## 2.移行先のリポジトリURLをコピーする
移行先のGitHubリポジトリを作成します。
`.git`で終わるURLをコピーしておきます。コピーしたURLは`DESTINATION_REPOSITORY_URL`と呼びます。

## 3.複製元リポジトリのベアクローンを作成する
Gitコマンドで複製元のリポジトリをクローンします。
このローカルリポジトリは移行後に削除するので、保存場所を気にする必要はありません。

```
git clone --bare <SOURCE_REPOSITORY_URL>
```

`--bare`オプションを付けると、ソースコードがなく、更新履歴やブランチ状態などを保持しているリポジトリを作成できるようです（`--mirror`でもほぼ同じ？）。
新規ターミナルで実行すると、ルートディレクトリ（`~`）に`<user-name>/<SOURCE_REPOSITORY_URL>`が作成されます。

`XXX@XXX.git.backlog.jp:/project-name/old-repository.git`なら`old-repository.git`のように作成されます。
`Resolving deltas: 100% (10000/10000), done.`のようになれば完了です。
このようなファイル構成になっています。

```
old-repository.git/
├── HEAD
├── config
├── description
├── hooks/
├── info/
├── objects/
├── packed-refs
└── refs/
```

## 4.ミラーリポジトリに移動する

```
cd <REPOSITORY>
```

`<REPOSITORY>`は`git clone --bare`で作成される`.git`フォルダです。
`git clone --mirror XXX@XXX.git.backlog.jp:/project-name/old-repository.git` とした場合は、`cd old-repository.git`となります。


## 5.複製元リポジトリを複製先のリポジトリにミラープッシュする
複製先のURL（`<DESTINATION_REPOSITORY_URL>`）にローカルリポジトリをプッシュします。

```
git push --mirror <DESTINATION_REPOSITORY_URL>
```

`remote: Resolving deltas: 100% (0000/10000), done.`のようになれば完了です。

コミット履歴やブランチ・タグ情報も複製できているのが確認できると思います。

注意点としては、複製元リポジトリがmasterブランチを使っていると、複製先でデフォルトブランチがmasterにならない現状が起きました（アルファベット順で最初のブランチ名が初期設定されている？）。
移行後にGitHubで、Settings→Branchesと進んで「Default branch」をmasterに変更して解消できました。


## 6.一時ローカルリポジトリを削除する
リポジトリは複製できたので、一時的にクローンしたリポジトリを削除します。

```
cd ..
```

```
rm -rf <REPOSITORY>
```

お疲れ様でした。これで移行は完了です！

## 参考情報
- [リポジトリを複製する - GitHub Docs](https://docs.github.com/ja/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/duplicating-a-repository)
- [Gitリポジトリを別のGitサーバーに移行する - Qiita](https://qiita.com/orange5405/items/783b74667bcc69a34a52)
ArduinoUno で LCD モジュールを使う

![IMG_20210827_144132.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/543e91b3-40e3-08d7-7b27-f01b65641c65.jpeg)

こちらで構築した環境で LCD モジュールを使ってみます。
[Arduino CLI の使いかた](https://qiita.com/ekzemplaro/items/ed2db3d05bd8f4fc2cb5)

LCD モジュールは
Grove-LCD Backlight v4.0 です。

使うライブラリーはこちらです。
[ Seeed-Studio / Grove_LCD_RGB_Backlight](https://github.com/Seeed-Studio/Grove_LCD_RGB_Backlight)

ライブラリーのインストール

```bash
cd ~/Arduino/libraries
git clone https://github.com/Seeed-Studio/Grove_LCD_RGB_Backlight.git
```

```text:hello/hello.ino
// ---------------------------------------------------------------
/*
	hello.ino

					Aug/27/2021
*/
// ---------------------------------------------------------------
#include "rgb_lcd.h"

rgb_lcd lcd;
int count = 0;

// ---------------------------------------------------------------
void setup()
{
	lcd.begin(16,2);
	lcd.setRGB(0, 64, 64);
	Serial.begin(9600);
	display_proc("*** hello.ino *** start *** ");
}

// ---------------------------------------------------------------
void display_proc(char msg[])
{
	lcd.setCursor(0,0);
	lcd.print (msg);
	Serial.print(msg);
	Serial.println("  " + String(count));
	delay(2000);
	count++;
}

// ---------------------------------------------------------------
void loop()
{
	display_proc("Good Morning!  ");
	lcd.setRGB(0, 0, 64);
	display_proc("Good Afternoon!  ");
	lcd.setRGB(0, 64, 0);
	display_proc("Good Evening!  ");
	lcd.setRGB(64, 0, 0);
	display_proc("Good Night!  ");
	lcd.setRGB(64, 0, 64);
}

// ---------------------------------------------------------------
```

実行結果

```text
$ ./receive.py 
*** hello.ino *** start ***   0
Good Morning!    1
Good Afternoon!    2
Good Evening!    3
Good Night!    4
Good Morning!    5
Good Afternoon!    6
Good Evening!    7
Good Night!    8
Good Morning!    9
```
Dockerをwindows homeで利用する

#はじめに
メモをとっているものの、実際には公式マニュアルを読めば大丈夫である。リンクは下。
https://docs.docker.jp/docker-for-windows/install-windows-home.html

#WSLの有効化
・Windows Subsystem for Linux　つまりwindowsでLinuxを利用すること
・仮想化も有効にする
→「windowsの機能の有効化または無効化」で以下の２つにチェック
① Linux用windowssサブシステム
② 仮想マシン　プラットフォーム

#WSL2に更新する
こちらのサイトのパッケージをDL&実行＝手順４（WSL2更新パッケージ）
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package

以下のコマンドを実行
```
// PowerShell
wsl --set-default-version 2
```

#Ubuntu20.04をインストール
・MicroSoft Storeより入手する。
・CentOSは対応していない模様。githubのリポジトリ存在はあるが、公式マニュアルはない。
・Ubuntuを起動し、最初のユーザーを生成する。
・aptコマンドを更新
```
$ sudo apt update && sudo apt upgrade
```

#DockerHub for Windowsをインストール
DLサイト
https://hub.docker.com/?overlay=onboarding


参考URL

公式
・Homeにインストールする　https://docs.docker.jp/docker-for-windows/install-windows-home.html
・WSL2について　https://docs.docker.jp/docker-for-windows/wsl.html
・WSL2更新パッケージ
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package
・Ubuntuの初期設定　https://docs.microsoft.com/ja-jp/windows/wsl/user-support
非公式
・https://qiita.com/idani/items/fb7681d79eeb48c05144
・https://qiita.com/teckback/items/c048faef648da6c83058

☆CentOSをインストールする場合の方法はこちら（非公式）
https://www.geekfeed.co.jp/geekblog/install_centos8_on_wsl2_for_free
VMwareでのBridge設定と固定IP設定手順

# 目的
VMWareでネットワークのBridge設定＋固定IPアドレスの設定手順が覚えられないのでドキュメント化しておく。類似記事はたくさんあると思うが、個人の備忘録として。

# 環境
- VMWare：Workstation Pro(16.1.2)
- ホストOS：Windows10
- ゲストOS：Ubuntu 16.0.4

# 手順
## Bridgeアダプタの追加
1. ゲストOSを停止
1. メニューの「編集 >> 仮想ネットワークエディタ」を選択
1. 仮想ネットワークエディタで「設定の変更」をクリック
![仮想ネットワークエディタ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41649/21d3f3e2-ce74-18f6-d40e-15247d8e4e51.png)
1. 「ネットワークの追加」をクリック
1. 「追加するネットワークを選択」でVMnet0を選択。
1. ブリッジを選択。
1. ブリッジ先で対象のアダプタを選択
1. 「OK」を押してダイアログを閉じる
![仮想ネットワークエディタ02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41649/fdc01e9a-34b1-1861-6bca-cabf917d7b1c.png)

## 固定IPの設定
1. ゲストOSを起動
1. 「システム設定 >> ネットワーク」でネットワーク設定を開く
1. 対象アダプタで固定IPを設定する
1. ゲストOSを再起動（再起動しないと反映されない）
三葉結び目の描き方

####環境

Wolfram Mathematica:Version 12.0.0.0

####プログラム

```Mathematica:三葉結び目.nb
r[t_] := Sin[3 t/4]^2 + 1;
ParametricPlot3D[{r[t]*Cos[t], r[t]*Sin[t], Sin[3 t/2]}, {t, 0, 4 Pi}]
```

####実行例

![sanyou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1935301/9da32fa4-4427-7316-0700-37a291ad1911.png)

####解説

所謂右手型である。媒介変数関数の三番目を負にすれば左手型になる。

####参考サイト

https://ja.wikipedia.org/wiki/%E4%B8%89%E8%91%89%E7%B5%90%E3%81%B3%E7%9B%AE
アプリから実行中のSQLを解析する（Oracle）

アプリケーションから実行中のSQLを解析する方法です。

データベースの処理に時間がかかっているっぽいけど、どのSQLが問題かわからなかったり、
処理が全然終わらないときに、どのSQLが遅いか確認したりできます。


```
select
  SQL_ID
  , SQL_TEXT
  , LAST_ACTIVE_TIME 最終実行時間
  , EXECUTIONS 実行回数
  , ROUND(ELAPSED_TIME / (1000 * 1000),3) 経過時間
  , CASE EXECUTIONS 
    WHEN 0 THEN ROUND(ELAPSED_TIME / (1000 * 1000),3) 
    ELSE  
      ROUND(ELAPSED_TIME / EXECUTIONS / (1000 * 1000),3)
    END 平均経過時間
  , module
  , PARSING_SCHEMA_NAME
  , SQL_FULLTEXT
from
  (select *  from V$SQL order by LAST_ACTIVE_TIME desc) 
where
  rownum < 10;
```
SQL_ID　　　　　　　　：SQL_IDについてはOracleのドキュメントを参照
SQL_TEXT　　　　　　　：SQLの冒頭部分
最終実行時間　　　　　：最後にSQLが実行されたタイムスタンプ
実行回数　　　　　　　：このSQLが実行された回数
経過時間　　　　　　　：このSQLの実行にかかった秒数(複数回実行された場合、合計が表示される)
平均経過時間　　　　　：経過時間を実行回数で割った値
module　　　　　　　　：実行ファイル名
PARSING_SCHEMA_NAME　：実行ユーザー名
SQL_FULLTEXT　　　　　：SQL全文

SQLがプールに残っている限り、情報は保持されるので、
実行回数をリセットする場合はSQLプールをクリアしてください。

```
ALTER SYSTEM FLUSH SHARED_POOL;  
```
Jupyter Notebookでコードの自動補完でエラーがでる

# 問題

Jupyter-notebookにて
以下画面でtabを押して補完しようとすると、エラーが出る。

![Screenshot from 2021-08-27 13-39-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215525/a6026d87-510a-e844-fe90-2c78012545cf.png)


```
[IPKernelApp] ERROR | Exception in message handler:
Traceback (most recent call last):
以下略
  File "/home/xxxxx/xxxxx/xxxxx/lib/python3.6/site-packages/IPython/core/completer.py", line 1374, in _jedi_matches
    text[:offset], namespaces, column=cursor_column, line=cursor_line + 1)
  File "/home/xxxxx/xxxxx/xxxxx/lib/python3.6/site-packages/jedi/api/__init__.py", line 726, in __init__
    project=Project(Path.cwd()), **kwds)
TypeError: __init__() got an unexpected keyword argument 'column'

```

# 原因

標準でpipでインストールされる、補完に使っている標準オプションのJediのversionがあってないのが原因らしい

# 環境

python 3.6
Jedi 0.18
Ipython 7.26

# 解決

以下で一発解決。

```
pip install jedi==0.17.2
```

# イケてない解決

毎回以下のコマンドをいつ込み、Jediの使用をやめる。
毎回jupyter起動するたび、こんなコマンドを打ってられない。

```
%config Completer.use_jedi = False
```

以下のコマンドでは何も変わらない。
```
%config IPCompleter.greedy=True
```
【Node.js】HummusJSで既存のPDFへ簡単書き込み

入力フォームのような体裁のPDFってありますよね。
例えば、こんなのです。
![form1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418041/ad1140ca-61e3-f9f1-4374-829ee6253b25.png)
出典:[医療費控除の明細書など -- 国税庁ホームページ-明細書・計算明細書等](https://www.nta.go.jp/taxes/shiraberu/shinkoku/yoshiki/02/pdf/ref1.pdf)

直接このフォームに文字列を追記できたらペンを持たなくて済むので便利ですね！
そこで利用するのが**HummusJS**です！

https://github.com/galkahana/HummusJS

## 動作環境

node: v14.17.4
npm: v6.14.14

nodeやnpmの環境がない場合は[インストール](https://nodejs.org/ja/download/)してください。

HummusJSは`v1.0.110`を利用しました。

## 試してみよう

#### プロジェクト作成

```
> npm init
```

表示される内容がよくわからなければ、全てエンターキーで飛ばして頂いて構いません。

#### npmで`HummusJS`をインストール

```
> npm install hummus
```

#### 同ディレクトリに以下ファイルを作成

```javascript:overwrite.js
const hummus = require("hummus");

const pdfWriter = hummus.createWriterToModify(
  "original.pdf",                    // 編集元PDFのパス
  { modifiedFilePath: "output.pdf" } // 保存先パス
);

// フォントファイルをインポート
const font = pdfWriter.getFontForFile("font.ttf");

 // 編集するページを取得(1ページ目を編集するため、2つ目の引数を0とする)
const pageModifier = new hummus.PDFPageModifier(pdfWriter,0);
pageModifier.startContext().getContext().writeText(
  "野比のび太", // 入力文字列
  59,572,      // 座標を入力 ページの左下端が(0,0)
  {
    font: font,         // フォントの指定
    size: 12,           // 文字サイズの指定
    colorspace: "gray", // 色空間を"gray", "cmyk", "rgb"から選択
    color: 0x00         // カラーコード
  }
);
pageModifier.startContext().getContext().writeText(
  "ドラえもん",
  59,552,
  {
    font: font,
    size: 12,
    colorspace: "rgb",
    color: 0x153ed3 // 青色
  }
);
pageModifier.endContext().writePage();

pdfWriter.end();
```

#### 同ディレクトリに`input.pdf`と`font.ttf`を配置

今回、`input.pdf`として[前述のPDF](https://www.nta.go.jp/taxes/shiraberu/shinkoku/yoshiki/02/pdf/ref1.pdf)、`font.ttf`として[源真ゴシック](http://jikasei.me/font/genshin)をお借りしました。

#### 実行

```
> node overwrite.js
```

正常動作した場合、何も表示されません。`output.pdf`が出力されます。

#### `output.pdf`の内容確認

二人の名前を氏名欄に書き込むことができました！

![form2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418041/5d35cfb1-4ab5-c0f6-e3b6-cd822e7e2cc1.png)


## まとめ

座標を指定しなければならないのは面倒ですが、特に難しいこともなくPDFへの書き込みをできる**HummusJS**を是非活用してみてください！
今回利用したコードは[こちら](https://github.com/machimachida/pdf-overwriter)にもあります。

## 参考URL

[HummusJS - wiki](https://github.com/galkahana/HummusJS/wiki)
swfファイルから特定の文字列を取り出す方法

## はじめに
もうフラッシュなんて使われていないとは思いますが、
swfのソースが無い、けど中どうなってるか見たいって方は試してみる価値はあるかなと思います。

## 環境
今回はWindowsで行いましたが他でも出来そうです。

## 手順

１．まず変換したいswfをご用意します。

２．swfmillというツールをDLし、swfmill.zipを展開します。
https://www.swfmill.org/
Windows binaryで問題無いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156172/61e9e359-8ae9-90f3-b2be-766367fc1075.png)

３．以下のコマンドをbatファイルに保存し、swfファイルをxmlファイルに変換する
`> swfmill.exe swf2xml 変換したいファイル.swf 出力したいファイル名.xml`

４．出力したxmlファイルを検索したりして目的の文字列とか入ってないか眺める

## 参考にしたサイト様
### 1ft-seabass.jp.MEMO
　Windows環境にてswfmillを使って複数ファイルに同時に変換するコマンドプロンプト（バッチ）を作ったメモ
　https://www.1ft-seabass.jp/memo/2013/05/13/windows-swfmill-multifile-commandprompt-batch-memo/

## おわりに
今回はリコンパイルしやすいのが手元にあったのでやってみましたが、
重要な文字列（パスワードとか）は中に入れると割と簡単に取り出せるので、（そんな機会はもう無いと思いますが）控えたほうがよさそうです。
mecab-ipadic-neologdがうまくインストールできないときの対処方法

mecab-ipadic-neologdのインストールがうまくできず、数日かけてやっと解決できたので手順を示します。

## 必要なパッケージのインストール
mecab-ipadic-neologdを動かすにはいくつか必要なパッケージがあるので、それらをインストールします。
以下はMacOSでのコマンドです。(他のOSの方は、mecab-ipadic-neologdのreadmeファイルを見てください。)
なお、Jyupter Notebook上ではうまくインストールできなかったので、ターミナル上で実行してください。順番が大事です。(ソフトが入ってないとうまく解凍できずやり直すハメになります。)

```
＄ xcode-select --install
```
```
$ brew install libiconv
```
```
$ brew install mecab mecab-ipadic git curl xz
```

## mecab-ipadic-neologdのインストール準備
必要なファイルをダウンロードします。

```
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
```

## mecab-ipadic-neologdのインストール
ディレクトリを変更してからインストールを行います。

```
$ cd mecab-ipadic-neologd
```

いよいよインストールです。

```
$ ./bin/install-mecab-ipadic-neologd -n
```
インストールが順調にいくと、「yes」「no」を質問されますので、ターミナル上に「yes」と入力してエンターします。

## 動作確認
最後にインストールがうまくいっているか確認します。
ターミナルに次のコマンドを入力します。

```
$ echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
```

そうすると文字入力できるので試しに「鬼滅の刃っていいよね。」とでも入力してエンターキーを押してみましょう。
なにかしら出てくるはずです。controlキー+Cキーを押して抜けたら動作確認は完了です。
インストールがうまくいっていないときは、「そんなファイルありませんよ」的なメッセージが出てきます。

これでもつまづいてしまったらreadmeファイルを見てください。

以上です。
ubuntu vsftpd 530 Login incorrect  

ubuntu 安装 vsftpd 一般使用：

`sudo apt install vsftpd`

## vsftp 配置

```shell
listen=YES
listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
write_enable=YES
dirmessage_enable=YES
use_localtime=YES
connect_from_port_20=YES
chroot_local_user=YES
pam_service_name=vsftpd
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES
user_sub_token=$USER
local_root=/home/$USER/ftp
pasv_min_port=50000
pasv_max_port=50010
#全部用户被限制在主目录
chroot_local_user=YES
#启用例外用户名单
chroot_list_enable=YES
#指定例外用户列表文件，列表中用户不被锁定在主目录
chroot_list_file=/etc/vsftpd/chroot_list
#开启被动模式
pasv_enable=YES
#公网IP
pasv_address=1.1.1.1
```

在账号、密码、主目录都是正确的情况下，可能会遇到账号登录提示 530 Login incorrect 的问题。

网络上有好多解决方案，例如修改`/etc/vsftpd.conf`文件，将`pam_service_name=vsftpd` 修改为 `pam_service_name=ftp` ，虽然能够解决这个问题，但是这种方法其实是错误的。这样由于/etc/pam.d/ftp 文件不存在，等于是绕过了 PAM。

## vsftpd pam 文件分析

```shell
# /etc/pam.d/vsftpd
# Standard behaviour for ftpd(8).
auth	required	pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed

# Note: vsftpd handles anonymous logins on its own. Do not enable pam_ftp.so.

# Standard pam includes
@include common-account
@include common-session
@include common-auth
auth	required	pam_shells.so
```

可能导致 530 错误的有：
`auth required pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed` 和 `auth required pam_shells.so`

`auth required pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed`
该配置项的含义是 `/etc/ftpusers` 中的用户禁止登陆，如果文件不存在在默认所有用户均允许登录. 所以确保用户没在这个文件内。

`auth required pam_shells.so` 配置项的含义为仅允许用户的 shell 为 /etc/shells
文件内的 shell 命令时，才能够成功。

```
cat /etc/shells

# /etc/shells: valid login shells
/bin/sh
/bin/bash
/bin/rbash
/bin/dash
```

而创建 ftp 用户时，为了禁止 ssh 登录，一般多为/bin/false 、/usr/sbin/nologin 等，显然不是一个有效的 bash，也就无法登录了。

## 解决方案

1. 查看/etc/ftpusers，确保账号没有在这个文件内。
2. 修改/etc/pam.d/vsftpd
   将 `auth required pam_shells.so` 修改为-> `auth required pam_nologin.so` 即可
3. 重启 vsftpd

---

https://help.aliyun.com/document_detail/60152.html

https://www.jianshu.com/p/91c7d4a115e0

https://bynss.com/codes/463471.html
Google Sheets「フィルタ」と「フィルタ表示」の違いを理解してないと袋叩きに合うので今のうちに覚えておく

# 環境

- Google Sheets (2021/8/27)


# 違いを理解

|  項目  |  意味  | 用途  |
| ---- | ---- | ---- |
|  フィルタ  |  すべての閲覧者に影響する  | 全員が閲覧不要項目を非表示にする、など |
|  フィルタ表示  |  自分のみにフィルタを適用 | 自分用に一時的にビューを切り替える、など |


# フィルタ作成時のやさしい通知

![ss1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/1a03008f-d482-56a5-8776-c6b60ae36628.png)

# フィルタ表示の画面

- 作った「フィルタ表示」は、他の閲覧者に共有されるようだ

![ss2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/fdc60172-a526-37da-5034-c5d64962f0ed.png)
Laravel-echo-serverでチャットアプリを作ろうとしたらSameSiteの設定で怒られた

# 概要
チャット機能をつけるためにLaravel-echo-server + Redisにてソケット通信を行おうとしたところSameSiteの設定でIssueが出ていた。
無事動いたので備忘録。

チャット機能は以下を参考
[Laravel Broadcasting (Laravel Echo)を試してみる](https://qiita.com/zaburo/items/34289d4573f39113b25a#%E5%AE%9F%E8%A3%85%EF%BC%92event%E3%81%AE%E8%BF%BD%E5%8A%A0privatechannel%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%A6%E9%80%9A%E4%BF%A1%E3%81%99%E3%82%8B)

# 環境
Laravel Framework 6.20.32
MAMP 6.4
PHP 7.4.6

# やったこと
* localhostのSSL設定
* laravelのsame_siteの設定
* laravel-echo-serverのSSL設定
* 接続先をhttpsへ変更

# localhostのSSL設定
以下のサイトを参考。
他のやり方だと何故かうまく行かなかった。
[ローカル開発環境にSSLを設定できるmkcertがめちゃくちゃ便利だった](https://parashuto.com/rriver/tools/mkcert-for-local-ssl-dev-env)

# laravelのsame_siteの設定
{ルート}/session.phpで設定

```session.php
'same_site' => 'lax',
```

noneに設定すると怒られたのでlaxにしました。

```
Mark cross-site cookies as Secure to allow setting them in cross-site contexts
```

# laravel-echo-serverのSSL設定
laravel-echo-server.jsonをSSLに対応。
認証はMAMPの時に作成したもの。

```laravel-echo-server.json
	"port": "6001",
	"protocol": "https",
	"socketio": {},
	"secureOptions": 67108864,
	"sslCertPath": "/Applications/MAMP/conf/apache/keys/localhost.pem",
	"sslKeyPath": "/Applications/MAMP/conf/apache/keys/localhost-key.pem",
```

忘れずにサーバーを再起動。

```
laravel-echo-server start
```


# 接続先をhttpsへ変更
laravel-echoの設定を変更

```bootstrap.js
window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: 'https://' + window.location.hostname + ':6001'
});
```

忘れずにjsを更新。

```
npm run dev
```

# おわり
これでとりあえずIssuesはなくなりました。
Qiita APIを使って直近100件のタイトルだけ取得する

技術トレンドを word Cloud で見せたいな、と思った時の技術トレンドの拾い上げ(メモ)

## 参考記事

- [Qiitaの新着記事を見たい。なのでQiita APIを叩こう。](https://qiita.com/yyano/items/f8172f80cb93307af317)
    - from yyanoさん
- [Qiita Developer - API v2](https://qiita.com/api/v2/docs#get-apiv2items)
- [PythonでWeb APIを叩いてJSONをパースする](https://qiita.com/bow_arrow/items/4dcab3389c892baba1a5)
    - from bow_arrowさん

## 結論

```
# python --version
Python 2.7.5
```

```python
# _*_ coding: utf-8 _*_

import requests
import urllib
import json
import sys
import codecs
from bs4 import BeautifulSoup

# webAPIからJSON形式の文字列の結果を取得し返却する
def getData():

    # proxy設定
    proxies = {
        "http":"プロキシサーバ:ポート",
        "https":"プロキシサーバ:ポート"
    }

    # API
    url = 'http://qiita.com/api/v2/items?'

    # APIパラメータセット
    param = {
        'page': '1',        # ページ番号(1-100)
        'per_page' : '100'  # 1ページ要素数(1-100)
    }

    # パラメータ文字列作成
    paramStr = urllib.urlencode(param)

    # APIを叩いて変数に結果を格納
    response = requests.get(url + paramStr, proxies=proxies)

    # JSONに変換
    jsonData = response.json()

    # 配列の中にJSONが入っているので配列要素毎にループ
    for jsonObj in jsonData:
        # 欲しいのはタイトルだけ
        print(jsonObj["title"])

    return response

# main
if __name__ == '__main__':

    # webAPIからJSON形式の文字列の結果を取得する
    apiRes = getData()
```

結果

```
Wordpressで固定ページのURLを変えるには
ASP.NET MVC CSV出力メモ
[Ruby on rails]ゲストログイン機能　ゲストログインは削除、編集されないようにする
GCP Data engineer 合格体験記
Dataiku：社名の由来とその読み方
[JS]簡単なフォームバリデーション
無心でコピペしてGitOpsを試してみた with Argo CD
EC2に自動でEIPを割り当ててくれるシェルスクリプト
[Mac]Windowのどこをドラッグしても移動できるアプリの実装について
OpenSSL で複数のホスト名に対応した自己署名証明書を作成するには
IBM Cloud internet services (CIS)からROKSのpodにアクセスしてみた
Nest-js Headerデコレータのカスタム
JSON
[axios] ファイルダウンロードができない or 空ファイルになってしまう現象の解消
PowerAutomateDesktopのexcelまとめ記事はpowerhacksさんの所が良い予感……
flutter_flavorizr + flutter_flavorでFlutterの環境切り替えした後に、iOSでbuildした時の 「Unable to load contents of file list」の解決方法
Node.js（axios）からDirectCloud-BOX APIでファイル一覧の取得とnode話
【GCP】利用料割引しているパートナーを調査
OKtaの検証用アカウントを取得してみる
Vue.js開発中のエラー対処
【Ruby on rails】JavaScript 非同期通信のコメント機能でエラーメッセージを出す　バリデーション
AWSのEC2インスタンスでAmazon Correttoを用いてJDK16を導入する
Terraform+SAMでLambda+APIGatewayの環境構築
CodeceptJSのhelper、playWright vs WebDriver
QNAPにgitea入れるメモ
:
:
```