OmniAICreator/Qiita-1.07M huggingface dataset:
wsl2でsshfsを使ってサーバーをmountしたら、explorerから見れた。

#前提
windows10にwsl2がインストールされていて、ubuntu20.04LTS(普通のLinuxなら大丈夫だと思う)が入っている。
普段sshを使ってサーバーにアクセスしている。
windows10のexplorerからサーバー上のファイルとかを見たい！！

#方法
####sshfsをubuntu(wsl2)にインストール

```
sudo apt update
sudo apt upgrade
sudo apt install sshfs
```
sshfsはmountするためのやつです。
####ubuntu上にmount pointを作成。

```
sudo mkdir /mnt/my-remote-server
```
####mount pointを私のものにする。
```
sudo chown $USER: /mnt/my-remote-server/
```
###mountする
-o allow_other オプションをつけずにmountするとmount自体は可能だが、explorerからmount pointを開こうとしたときにエラーが出てくる。まず、-o allow_other オプションがroot以外の人でも使えるように/etc/fuse.confを編集する。

```
sudo vi /etc/fuse.conf
```
user_allow_other をコメントイン

```conf:/etc/fuse.conf
# /etc/fuse.conf - Configuration file for Filesystem in Userspace (FUSE)

# Set the maximum number of FUSE mounts allowed to non-root users.
# The default is 1000.
#mount_max = 1000

Allow non-root users to specify the allow_other or allow_root mount options.
user_allow_other # ここをコメントイン
```
mountする。

```
sshfs hogename@hogeremtoeserver:/ /mnt/my-remote-server -o allow_other -o follow_symlinks
```
これでどのuserからでも見れるようにmountできました。
ちなみに-o follow_symlinksはシンボリックリンクをちゃんと追えるようにするためのものです。

###explorerでmount pointを見る

```
cd /mnt/my-remote-server
explorer.exe .
```
無事見れましたね😊

#参考
- ngyukiの日記[https://ngyuki.hatenablog.com/entry/2020/08/30/143734]
- https://tomohiro.me/posts/symlinks-for-sshfs
ジェネレーターでmultiprocessingに送るデータを順次用意する

時間のかかるバッチ処理はマルチプロセスで短縮すべきです。でも、マルチプロセスってなんかわかりづらいです。

```Python:imageprocessing.py
import glob
import os.path
import cv2

dir = r'c:\data\image\'
fl = glob.glob(os.path.join(dir,'**/*'),recursive = True)
for i in fl:
    im = cv2.imread(i)
    im = imageprocess(im)
    cv2.imwrite(i, im)
```
こういう処理があったとして、マルチプロセスにするにはどうすればよいでしょうか。

```Python:imageprocessingmp1.py
import glob
import os.path
import cv2
from multiprocessing import Pool

def func(file):
    im = cv2.imread(file)
    im = imageprocess(im)
    cv2.imwrite(file, im)

dir = r'c:\data\image\'
fl = glob.glob(os.path.join(dir,'**/*'),recursive = True)

with Pool(4) as p:
    for _ in p.imap_unordered(func,fl):
        pass
```
こうなりますね。
ですが、これには少し問題があるかもしれません。
と、言うのも、これは計算結果をそのままディスクに書き出しているのですが、この部分はマルチプロセス部分なので、同時に複数の読み込みと書き出しが起きています。これはあまりよろしくはありません。出来ればそういう所はワーカープロセスでなく制御する部分に置きたいです。

```Python:imageprocessingmp2.py
import glob
import os.path
import cv2
from multiprocessing import Pool

def func(args):
    return args[0],imageprocess(args[1])

dir = r'c:\data\image\'
fl = glob.glob(os.path.join(dir,'**/*'),recursive = True)

with Pool(4) as p:
    for result in p.imap_unordered(func,[i,cv2.imread(i) for i in fl]):
         cv2.imwrite(result[0], result[1])
```
でもこれではダメです。最初に全部のデータをディスクから読み込むので、メモリがアホみたいに必要になります。
どうすればいいでしょう

Queueで制御する？、そう考えましたがはっきり言って面倒です。

```Python:imageprocessingmp3.py
import glob
import os.path
import cv2
from multiprocessing import Pool

def func(args):
    return args[0],imageprocess(args[1])

def files(fl):
    for i in fl:
         im = cv2.imread(i)
         yield [i,im]

dir = r'c:\data\image\'
fl = glob.glob(os.path.join(dir,'**/*'),recursive = True)

with Pool(4) as p:
    for result in p.imap_unordered(func,files(fl)):
         cv2.imwrite(result[0], result[1])
```

そこで、ジェネレータを使用すると、必要な時に読み込むようになります。
(送るデータが少ない場合は有る程度まとめて実行されるようです)
JavascriptとRubyの違いについて

#２つの言語の役割
初学者はRubyは学ぶことが多い言語です。
サーバーサイドの言語でwebアプリの裏側で処理が行われる言語で
```ロジックが反映される言語```です。
一方でJavascriptはブラウザなどの操作で使われる
```見た目が反映される言語```です。
最近は、***サーバサイドJavaScriptのNode.jsやDeno.jsもあり、
WebサーバをJavaScriptで動かす***ことも増えてます。

#JavascriptとRubyの言語選びの基準
最初にRubyです。
1 初学者でも取り組みやすい (コードがシンプルで教材なども豊富)
2 日本語のドキュメントも充実
3  Ruby on railsというフレームワークで開発スピードが速い

次にJavascriptです。
1 webサイトではほとんどJavascriptで使われる
2 1つ言語を極めればキャッチアップしやすいが、初学者でも取り組みやすい(個人的にはRubyの方が簡単)
3 教材やドキュメントが豊富


次からは具体的にコードの違いを見ていきます。

#JavascriptとRubyのコードの違いについて

1 「プログラミング」と出力させて比較していきます。

●Ruby

```rb
puts "プログラミング"
```

⚫︎Javascript

```js
console.log("プログラミング");
```

putsとconsoleで出力させます。
Rubyは"" のみですがJavascriptは("");ですね。
この２つの違いがあります。


2 snake_caseとcamel_case

Rubyはsnake_caseと言って_が出てきます。

```rb

programming_language = "Ruby"
puts  programming_language #Rubyと出力
```

Javascriptはcamel_caseを使います。

```js
const programmingLanguage = 'Javascript';
console.log(programmingLanguage); #Javascriptと出力
```

3 変数の使い方
RubyとJavascriptには下のような違いがあります。

⚫︎Ruby

```rb
programming_language = "Ruby"
puts "言語は#{programming_language }です"   #言語はRubyですと出力
```
""(ダブルクオテーション)の中で#{}が処理される

⚫︎Javascript

```js
const programmingLanguage = 'Javascript';
console.log(`言語は${programmingLanguage}です。`); #言語はJavascriptです。
```
``（バッククオート)内で${}で囲みます。


#最後に
１つ言語に慣れたら言語チェンジは難しくないみたいです。
微妙な違いはありますはコツは同じです。
１つ言語を選んで慣れてから他の言語をやると習得は速いなと２つの言語を学習してみて感じ　ました。


⚫︎参考資料
https://blog.proglus.jp/2940
https://qiita.com/tamutomo223/items/37338f51d9bdcb7587ad
【備忘】Apexで文字バイト数をチェックして特定バイト数で切り捨てる

# パターン①
midで1文字ずつ分割してチェックする

```Apex

public static String biteCheck1 (String targetStr, Integer maxLength) {
    List<String> resultList = new List<String>();
    String result = '';

    String str = '';
    Integer j = 0;
    for (Integer i = 0; i < targetStr.length(); i++) {
        str = targetStr.mid(i,1);
        j += Blob.valueOf(str).size();
        if (j <= maxLength) {
            resultList.add(str);
        } else {
            break;
        }
    }

    for (String s : resultList) result += s;
    system.debug(Blob.valueOf(result).size());
    system.debug(result);
    return result;
}
```

# パターン②
split('')で分割してチェックする

```Apex
public static String biteCheck2 (String targetStr, Integer maxLength) {
    List<String> splitList = targetStr.split('');
    String result = '';
    List<String> resultList = new List<String>();
    Integer j = 0;
    for (String s : splitList) {
        j += Blob.valueOf(s).size();
        if (j <= maxLength) {
            resultList.add(s);
        } else {
            break;
        }
    }

    for (String s : resultList) result += s;
    system.debug(Blob.valueOf(result).size());
    system.debug(result);
    return result;
}
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364548/4a882101-9522-e252-48b5-dcd77e5015b9.png)
bootstrapでcontainerの幅を変える方法

##結論
containerのstyleにmax-widthを設定する

```html

<div class="container" style="max-width: 800px;">

```
このようにするとcontainerの幅の最大値を設定してをレスポンシブにデザインにすることができます。

##余談
また、このようにすると幅が一定の値になるため、画面が小さくても同じ幅のままになります。

```html

<div class="container" style="width: 800px;">

```
【Ruby on Rails】rails sして立ち上がらない時の解消方法


#はじめに

久しぶりにrailsのサーバーを立ち上げようとしたら以下のエラーが出たので、解決方法をメモしておきます。

````
=> Booting Puma
=> Rails 5.1.6 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.4.1-p111), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:8080
Exiting
/usr/local/rvm/gems/ruby-2.4.1/gems/puma-3.9.1/lib/puma/binder.rb:269:in `initialize': Address already in use - bind(2) for "127.0.0.1" port 8080 (Errno::EADDRINUSE)
from /usr/local/rvm/gems/ruby-2.4.1/gems/puma-3.9.1/lib/puma/binder.rb:269:in `new'
from /usr/local/rvm/gems/ruby-2.4.1/gems/puma-3.9.1/lib/puma/binder.rb:269:in `add_tcp_listener'
.
.
省略
.
.
from bin/rails:3:in `<main>'
`````


#環境

* Rails 5.2.5
* Ruby 2.6.3

#原因と解決方法

下記コマンドでプロセスを確認しました。

````
lsof -i -P | grep 8080
````

私の場合、8080ポートっだったのですが、3000とか人によって異なるようです。

````
ruby  10463 ec2-user   11u  IPv4  24076      0t0  TCP localhost:8080 (LISTEN)
````

数字は適当なのですが、コマンドで表示された10463のプロセスが邪魔してる様子。

なので、下記コマンドでプロセスを停止！

````
kill -9 10463
`````

再度rails sしたら直りました。
久しぶりだったので、結構焦りましたが調べればなんてことなかった。



#参考にさせて頂いた記事

https://qiita.com/ebkn/items/7c3cdde49641ec5e5b61
Command Line

**ファイルの作成**
touch ファイル名

**ファイルの中身を表示**
cat ファイル名

**ディレクトリを作成**
mkdir ディレクトリ名

**ディレクトリを移動**
cd ディレクトリ名

**カレントディレクトリを確認**
pwd

**ディレクトリの中身を表示**
ls

**1つ親のディレクトリ**
cd ..

**ファイルを移動させる**
mv ファイル名 ディレクトリ名

**ファイル名を変更**
mv ファイル名 新しいファイル名

**ファイルのコピー**
cp コピーするファイル名 新しいファイル名

**ファイルの削除**
rm ファイル名
sshでの接続に失敗する場合の対処

sshでラズパに接続しようとすると、以下のようなエラーが出ることがある。
sshでは最初に接続した時にホストの公開鍵を保存しています。
で、次の接続の時にホスト鍵を比較して前回と同じホストに接続したかを
確認するような仕組みになっているらしい。

保存していた鍵と違っていた場合に以下のエラーが出て接続できなくなるらしい。

```shell-session:
% ssh pi@192.168.10.25
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:EKvX5V61nQcKfwyd/r+iSsBCzaWvrCxCxGg1vPBbc+s.
Please contact your system administrator.
Add correct host key in /Users/nomura/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /Users/nomura/.ssh/known_hosts:8
Host key for 192.168.10.25 has changed and you have requested strict checking.
Host key verification failed.
```

``ssh-keyget``コマンドを使って鍵を削除します。


```shell-session:
% ssh-keygen -R 192.168.10.25
# Host 192.168.10.25 found: line 8
/Users/nomura/.ssh/known_hosts updated.
Original contents retained as /Users/nomura/.ssh/known_hosts.old
```

再度sshで接続すると初回と同じ手順で接続することができるようになります。

```shell-session:
% ssh pi@192.168.10.25       
The authenticity of host '192.168.10.25 (192.168.10.25)' can't be established.
ED25519 key fingerprint is SHA256:EKvX5V61nQcKfwyd/r+iSsBCzaWvrCxCxGg1vPBbc+s.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.10.25' (ED25519) to the list of known hosts.
pi@192.168.10.25's password: 
Linux raspberrypi 5.10.63-v7l+ #1459 SMP Wed Oct 6 16:41:57 BST 2021 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Nov 19 19:39:51 2021
```


### 参考

https://www.niandc.co.jp/sol/tech/date20150729_507.php

https://qiita.com/hnw/items/0eeee62ce403b8d6a23c

https://qiita.com/nnmr/items/d22a4915de4d8def17b5
pathlibメモ


#基本操作

```Python
from pathlib import Path
imgs=Path("imgs")
imgs/"test.png"
# PosixPath('imgs/test,png)
```

##ディレクトリ生成

```python
dirc=Path("dirc")
dirc.mkdir(exist_ok=True) 
```

##ファイルの中身一覧

```python
dirc=Path("dirc")
files=list(dirc.iterdir())
```

##文字にする
基本的に(すべての親ディレクトリ)/ファイル名という扱い

```python
img=Path("dirc/test.png")

# 文字列に
str(img)
# 'dirc/test.png'

# ファイル名
img.name
# 'test.png'

# ファイル名のみ
img.stem
# 'test'

# 拡張子
img.suffix
# '.png'

#親ディレクトリの取得
img.parent
# PosixPath('dirc')

img=Path("dirc/test1/test2/test.png")
# PosixPath('dirc/test1/test2')

```
##ファイルの存在確認

```python
dirc=Path("dirc")

# 存在するかどうか
dirc..exists()

# ディレクトリかどうか（存在しなくてもFalse）
dirc.is_dir()

# ファイルかどうか（存在しなくてもFalse）
dirc.is_file()
```

##使用例
./testA/内の画像を全て読み込んで./testB/内のすべてのディレクトリ内に保存

```python:test.py
from pathlib import Path
import cv2
testA=Path("testA")
testB=Path("testB")
testA_files=list(testA.iterdir())
imgs=[]
names=[]
for testA_file in testA_files:
     if ".png" == testA_file.suffix:
             names.append(testA_file.name)
             imgs.append(cv2.imread(str(testA_file)))

for testB_dir in testB_dirs:
     if testB_dir.is_dir():
             for img,name in zip(imgs,names):
                     cv2.imwrite(str(testB_dir/name),img)

```
VBAのAndが論理演算だけでなくビット演算もしてた話

## はじめに
VBAでフォルダの判定方法を探していた時にこんな条件式を見かけた。

```vb
If (GetAttr(filepath) And vbDirectory) > 0 Then
```
どうやら`vbDirectory`はファイルの属性を表す定数で、整数値の`16`を意味するらしい。
`GetAttr(filepath)`は引数のファイルパスを調べ、`vbDirectory`などのファイル属性を表す整数値を返すようだ。

ということは、仮に引数`file`がフォルダで`GetAttr(file)`が16を返したとするとこうなる。

```
If (16 And 16) > 0 Then
```

一瞬戸惑ってしまうが、どうやら`16 And 16`の部分は**ビット演算の論理積**を計算しているようだ。
ちなみに`Or`演算子は論理和。
VBAでは論理演算子とビット演算子が同じらしい。本当に紛らわしい・・・

## GetAttr
本題からはそれるが、`GetAttr`は引数に指定したパスの属性を調べて、該当した属性の定数(数値)を**合計**して返してくれる関数らしい。

[公式ドキュメント](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/getattr-function)より定数を抜粋したものが下記

|定数|値|説明|
|---|---|---|
|vbNormal|0|標準|
|vbReadOnly|1|読み取り専用。|
|vbHidden|2|非表示。|
|vbSystem|4|システム ファイル。 Macintosh では使用できません。|
|vbDirectory|16|ディレクトリまたはフォルダー|
|vbArchive|32|前回のバックアップ以降にファイルが変更されています。 Macintosh では使用できません。|
|vbAlias|64|指定されたファイル名はエイリアスです。 Macintosh でのみ使用できます。|

## なぜ論理積のビット演算を使う？
調べたいビット位置に`1`を仕込めば、対象のデータを拾ってこれるという論理積の性質を使用している。

(例) 読み取り専用のシステムファイルが非表示か調べたいときは、

```
vbReadOnly + vbSystem And vbReadOnly > 0 
→ 1 + 4 And 2 > 0
→ 5 And 2 > 0
```
という条件式になる。
2進数4桁にすると5 → `0101`、2 → `0010`となり、`論理積`を計算すると`0000`になるので、条件式は`False`、非表示属性を持っていないことがわかる。

| 8の位| 4の位| 2の位| 1の位|
|---|---|---|---|
|0|1|0|1|
|0|0|1|0|
|↓|↓|↓|↓|
|0|0|0|0|

## 終わりに
論理演算子とビット演算子が同じ言語を初めて見た気がする。紛らわしいなあ。
【DOM操作(後編)】JavaScriptのaddEventListenerについて、「・・したら」をまとめてみた

[前回](https://qiita.com/yasu-hoshi/items/ceaba8b8dbe0ebc7ec04)はDOM操作の大まかな流れを解説しました。
具体的には**「<font color="red">A</font>をしたら<font color="SteelBlue">Bの処理</font>をする」**の**「<font color="red">A</font>（きっかけとなるアクション）」**について解説していきました。
(例)「<font color="red">クリックしたら</font>」「<font color="red">ホバーしたら</font>」など

今回はその<font color="red">A</font>の後の
**「<font color="SteelBlue">Bの処理</font>」**にてよく使用されるメソッドについて解説していきます。


#①ボタンをクリックするとリストが生成
まずは次のように記述

```html
 <button>追加</button>
 <ul>
 </ul>
```
```javascript
const todoList = document.querySelector('ul');

document.querySelector('button').addEventListener('click' ,() => {
  // ここから下で解説していきます。
  const list = document.createElement('li')
  list.textContent = "勉強する";
  todoList.appendChild(list);
})
```
![スクリーンショット 2021-11-20 16.11.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029408/cebfc103-e7dd-abee-d8ab-52bf2fb20638.png)
ブラウザには追加ボタンがあるのみです。

**🏃‍♀️一つずつ見て行きましょう🏃‍♀️**
##・createElement( )
HTML要素を生成できます

```javascript
// <li></li>を作成。listとして使用できます。
const list = document.createElement('li');

// もちろん li 以外でも使用可能
```

##・textContent( )
要素内のテキストを取得、編集できます。

```javascript
// 先ほど作成したlistのテキストを編集
list.textContent = "勉強する";

// 確認してみよう
console.log(list)   //  <li>勉強する</li>
```

##・appendChaild( )
指定した親要素の子要素の"最後"に追加される

```javascript
// ulの要素取得
const todoList = document.querySelector('ul');

// 先ほどの"<li>勉強する</li>"をtodoListに追加
todoList.appendChild(list);
```
**これらの処理によって追加ボタンをクリックすると**
![スクリーンショット 2021-11-20 16.11.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029408/c37eb519-92bb-4e69-a195-ffabe7d3e3e6.png)
**このようにリストが追加されます**

#②ボタンをクリックするとリストが削除

先ほどとは別で次のようにボタンとリストを用意!

```html
<button>削除</button>
  <ul>
    <li>買い物に行く</li>
 </ul>
```

```javascript
const todoList = document.querySelector('ul');

document.querySelector('button').addEventListener('click' ,() => {
  // ここから下を解説
  const message = confirm("削除してもいいですか？")
  if(message){
    list.remove();
  } else {
    return;
  }
})
```
ブラウザはこんな感じ
![スクリーンショット 2021-11-20 16.11.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029408/970850ed-08f4-18d9-c742-2dab4f3ae793.png)
**🏃‍♀️一つずつ見て行きましょう🏃‍♀️**
##・confirm( )
画面上にダイアログ表示("キャンセル"と"OK"で確認)

```javascript
const message = confirm("削除してもいいですか？")
  if(message){
  // ここにOKの時の処理
  } else {
  // ここにキャンセルの時の処理
  }
```

##・remove( )
対象のノードを削除できます。

```javascript
// listを削除
list.remove()
```
**これで"削除ボタン"をクリックすると"削除してもいいですか？"と確認
→OKならリスト削除 / キャンセルならそのまま**といった処理になります。


##③その他のよく使うメソッド

###・add( )

```javascript
// (要素).classListに対して使用
list.classList.add('is-valid');

//listに対して'is-valid'クラスを付与
```
クラス削除の際は先ほど紹介した**remove( )**が使えます。

###・toggle( )
クラスを付与したり削除したりできます。

```javascript
// listに'red'クラスがついてたら削除。ついてないなら付与
list.classList.toggle('red');
```


##終わりに
今回は初歩的なもののみご紹介させていただきました。
参考にしていただけたら幸いです。
「GithubのHTMLをダウンロードせずにプレビューするアプリ」作ってみた!!


##今回は「GithubのHTMLをダウンロードせずにプレビューするアプリ」作ってみた!! です
私の業務効率化だけのために作ったと言っても過言ではないので、興味ない方はページをそっと閉じていただければと存じます ＜m(__)m＞


##画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104530/548fb493-da87-3015-3a4e-c9ac88b16a0a.jpeg" width="800">

**【使い方は簡単】**
画面内にテキストボックスに「Github上に置いてある”HTMLファイル”のアドレスを入力し、
HTML/CSS/JavaScriptがレンダリング実行されている状態をブラウザで表示できます。
※JSフレームワーク等は動作ません


**【以下サイトリンク】**
https://github-html-view.azurewebsites.net/

## ことのはじまり
大学のプログラミング授業でGithubに課題を提出してもらうことに決めました。

**【実際にやってみた】**
１つのリポジトリに十数回分の課題提出が入ります。

**【困ったことが】**
毎回、授業の最初に講評するのですが、毎回ダウンロード、全ての課題がダウンロードされる。
大学のPCなので毎回ZIPをダウンロードして展開し、HTMLをブラウザで開き、講評する。
※４０名弱、４０回！！ こりゃ大変だ・・・・。。時間もかかる。

**【効率よく講評するには... と考え出す】**
GithubでHTMLを表示する設定を全員に覚えて貰えばいい！？ → 全員覚えるのはどうだろうか・・・。ただでさえ、プログラミングに苦手意識がある学生も少なからずいるわけだもんな〜と悩んでいると、、、
”TAからGithubのURLを入力したら見れるのあったら便利ですよね〜”とご意見いただき、
”なるほど...作るか...”、学生の負担が増えるのは好ましくないと思ってたので、この方法が良いかな〜と思ったのが作るきっかけでした。

## このアプリを使う人の想定（超ニッチ！！）

- 大学等のWeb（JavaScript含む）課題をGithubに提出してもらっている先生
- 他・・・？いない？


##なんと、使うの自分だけだ・・・

それでいいんです。プログラミングはツールです。
何かを作るためにある。
今回の問題解決は「私の業務の効率化！！」それで良いではないか！
エンジニアは作れるから業務効率化できるんですよね～ホント良かった。

##失敗は？
あります！！それはちょっとだけデザイン頑張ったところです。トップページの。
※CSS苦手なのに。そこが時間かかりました！！


**使い方と作った経緯もYoutubeに載せてあります。**
ご興味湧いた人は、是非見ていただければ嬉しいです。


## 【Github-HTML-Viewerの解説動画】
[「GithubのHTML/CSSをブラウザで簡単表示確認！」ありそうで無かったアプリを作った！]

<iframe width="560" height="315" src="https://www.youtube.com/embed/hF3z_tW6FBY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>







以上
Vue.jsで404や500エラーページの制御がしたい

# 404エラーページ

[Vue Router](https://router.vuejs.org/ja/)を利用して制御する。
ワイルドカードのパスを作ることで、どのパスにもマッチしなかった時のビューに飛ばすことができる。
サブディレクトリで使う404ビューを変えることもできる。

```javascript:src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'

import Index from '@/views/Index'
import NotFoundError from '@/views/errors/404'
import FooNotFoundError from '@/views/errors/foo/404'
import BarNotFoundError from '@/views/errors/bar/404'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Index',
    component: Index,
  },
  {
    path: '*',
    name: 'NotFoundError',
    component: NotFoundError,
  },
  {
    path: '/foo/*',
    name: 'FooNotFoundError',
    component: FooNotFoundError,
  },
  {
    path: '/bar/*',
    name: 'BarNotFoundError',
    component: BarNotFoundError,
  },
]

const router = new VueRouter({
  mode: 'history',
  routes: routes,
})
```

# 500エラーページ

[errorHandlerフック](https://jp.vuejs.org/v2/api/index.html#errorHandler)を利用して制御する。
キャッチされない例外が発生したとき、最終的に`errorHandler`が呼び出されてくれるため、そこで500エラーのビューに飛ばしています。

```javascript:src/main.js
～省略～
// Error Handling
Vue.config.errorHandler = (err, vm, info) => {
  console.error(`errorHandler: ${info}`, err)
  router.replace({ name: 'InternalServerError' })
}

new Vue({
  router,
  render: (h) => h(App),
}).$mount('#app')
```

適当なエラーページ

```javascript:src/views/errors/500.vue
<template>
  <div>
    <h1>500 Internal Server Error</h1>
  </div>
</template>
```

エラーページへのルーティングを追加

```javascript:src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'

import Index from '@/views/Index'
import InternalServerError from '@/views/errors/500'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Index',
    component: Index,
  },
  {
    path: '/error',
    name: 'InternalServerError',
    component: InternalServerError,
  },
]

const router = new VueRouter({
  mode: 'history',
  routes: routes,
})

export default router
```

コンポーネントの中でこんな感じで例外を飛ばしてみると確認できます。

```javascript
 mounted: function(){
   throw new Error('Error')
 }
```
Docker 用語解説！ 「Imageをpullしてcontainerを起動させるって…。どうゆうこと…？」

##はじめ
Docker用語の理解の薄さから調べていても記事の内容が理解できないことが多々あったので、一度整理してみることにしました。

もし何か記述ミスがあった場合はご教授していただけると幸いです。
##Dockerとは 
Dockerとは開発環境をコンテナ化(パッケージ化)することで開発環境の共有や環境構築を楽にしてくれるサービスです。
同じ開発環境でもMacやWindowsのようにPCのOSが異なると表示されるデータが異なる時があるのですが、Dockerを使うと表示されるデータがOSの違いを問わず統一されます。
また、パッケージ化することでPCの容量の節約にもなります。

##Docker デーモン
Dockerデーモンとはコマンドを受け取り処理するサーバのことです。クライアントのpcから送られてきたコマンド（docker psとか）をDockerデーモンが裏で処理をしてくれています。

##Dockerfile
Dockerfileとは↓のImageを自作する時に使うファイルのことです。

##Image
Imageはコンテナを作るための材料のことです。これはDocker HubというDockerが公式サイトからpull(ダウンロード)して作ることもできるし、自分で手作りすることもできます。
ImageとしてはnginxやApacheといったwebサーバ、mysqlやoracle database、Ruby on railsやDjangoといったフレームワークなどの開発に必要なものがImageとしてはあります。

##コンテナ
コンテナ(Container)とは隔離された開発環境のことです。
そしてこのコンテナはImageから作られ、PCの要領などがある限り、何個でも立ち上げることができます。

Dockerfile、Image、コンテナの関係を料理に例えると
DockerfileがレシピでImageが料理の材料、コンテナが料理そのものみたいな感じかと思います。

##Docker Hub
Docker HubとはDocker版のGit Hubのような物で、Imageやコンテナをクラウド上で共有できます。既に公開されているコンテナをpull(ダウンロード)して簡単に開発環境を作ることもできます。

##Docker Compose
Docker Composeとは複数のコンテナを使用するようなアプリケーションの環境を作るときに複数個のコンテナを連携してくれるツールです。

##Kubernetes
KubernetesとはDocker Composeよりも、より複雑なアプリケーション(よりたくさんのコンテナを使う様な)の環境を作るときに使うツールです。

##終わり
現在、AWSにポートフォリオをデプロイしているエンジニア志望の者ですが、自分がこれまで学んだSQLやAWSなどのサービス開発関係の勉強の中で一番Dockerの理解が難しかったです…。一度udemyでハンズオン形式の講座を受けて、2つのアプリケーションをDockerを使って開発しましたが、動画教材ではなく書籍でもじっくり勉強する必要があるなと感じました。
Ruby のメソッド名は小文字で始めなければならない，わけじゃない

ときどき，Ruby における命名規則として

> メソッド名は小文字で始めなければならない

と書かれた記事を目にしますが，そんなことはありません。

# 大文字で始めることもできる

以下のように大文字始まりのメソッドを定義することもできます。

```rb
def Ruby
  puts "Hello, Ruby!"
end

Ruby() # => Hello, Ruby!
```

メソッド名をアルファベット小文字で始めるのは，文法上のルールではなく慣習なのです。

しかし，大文字始まりのメソッド名を使うとき，注意しなければならない点があります。
上のコードで，`Ruby` というメソッドを呼び出すときに `Ruby()` のようにして `()` を付けました。
あれれ？　`( )` は省略できるんじゃなかったっけ？
はい，そうなんですが，今の場合，`()` が無いと「定数の参照」なのか「メソッド呼び出し」なのか区別がつきません。こういう場合，Ruby の処理系は定数の参照と解釈するようになっています（そういう仕様）。
それゆえ，単に `Ruby` と書いたのでは

```
uninitialized constant Ruby (NameError)
```

というエラーが発生します。
なお，実引数を与えるときは `( )` が省略できます：

```rb
def Ruby(message)
  puts "#{message}, Ruby!"
end

Ruby "Hello" # => Hello, Ruby!
```

これはメソッド呼び出しとしか解釈しようがないからです。

# 組込みクラスのメソッドはどうか

文法上のルールではないにしても，「メソッド名はアルファベット小文字で始める」という慣習があるのなら，組込みクラスや標準添付ライブラリーのメソッドも当然その慣習に則っているのか，というと，実はそうでもありません。

[Kernel](https://docs.ruby-lang.org/ja/3.0.0/class/Kernel.html) モジュールのメソッド一覧を眺めると，[Array](https://docs.ruby-lang.org/ja/3.0.0/method/Kernel/m/Array.html), [Complex](https://docs.ruby-lang.org/ja/3.0.0/method/Kernel/m/Complex.html), [Float](https://docs.ruby-lang.org/ja/3.0.0/method/Kernel/m/Float.html), [Hash](https://docs.ruby-lang.org/ja/3.0.0/method/Kernel/m/Hash.html), [Integer](https://docs.ruby-lang.org/ja/3.0.0/method/Kernel/m/Integer.html), [Rational](https://docs.ruby-lang.org/ja/3.0.0/method/Kernel/m/Rational.html), [String](https://docs.ruby-lang.org/ja/3.0.0/method/Kernel/m/String.html) といった大文字始まりのメソッドが目に入ります。
すぐに気がつくように，メソッド名と同名の組込みクラスがありますよね。
これら一群のメソッドは，同名のクラスのインスタンスを生成するためのものです。

たとえば，複素数オブジェクトを生成するのに，`Complex.new` を使って

```rb
Complex.new(1, 2) # => (1+2i)
```

としてもいいのですが，

```rb
Complex(1, 2)    # => (1+2i)
```

と書くこともできます。

また，組込みではありませんが，標準添付ライブラリーの [Pathname](https://docs.ruby-lang.org/ja/3.0.0/class/Pathname.html) クラスでは，`Pathname.new("foo/bar")` の代わりに `Pathname("foo/bar")` と書くことができます。

これらを初めて見たときは，クラスに引数を付けるとオブジェクトができるという文法でもあるのか，と思いましたが，単にクラスと同名のメソッドが定義されているのでした。

文字数で 4 文字減るだけですが，このほうが簡潔なので私は気に入っています。
自分でクラスを作るときも，目的によってはこのような生成メソッドを合わせて定義しています。

逆に，メソッド名を大文字で始めるのは，このようなケースに限定したほうがいいだろうなと思います。

# アルファベット以外も実は OK

ローカル変数名に漢字や仮名が使えるのと同じく，メソッド名にも使えます。

```rb
def ビール飲みたい(回数)
  puts ["ビール飲みたい"] * 回数
end

ビール飲みたい 3
# => ビール飲みたい
#    ビール飲みたい
#    ビール飲みたい
```

蛇足でした。

# 最後に

この記事は 2020 年のアドベントカレンダー
[【初心者必読】Ruby の誤解あるある Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ruby_misunderstandings)
の最後の記事です。

2021 年のじゃなくて 2020 年ね！　投稿したのは 2021 年 11 月だけど。
Qiita のアドベントカレンダーは，アドベント期間が終っても投稿できるみたい。
アドベント期間中にすべての日付を埋めることができなかったので，年が変わっても少しずつ記事を足していって，今日ようやく最後の日付（12/1）を埋めることができました。一年かかった。
自分としては，Ruby の初心者のよくある誤解の総まとめ的な，それなりに役に立つ記事群のつもりでしたが，今日の時点で LGTM の総数がたった 15 という壊滅的に淋しい企画に終わりました :sob:
Git コマンド

**Gitの準備**
git init

**共有するファイルを選択**
git add ファイル名

**選択したファイルを記録**
git commit -m "メッセージ"

**リモートリポジトリの準備**
git remote add リモートリポジトリ名 URL

**リモートリポジトリにファイルをアップロード**
git push origin master

**リモートリポジトリのファイルをダウンロード**
git pull origin master

**変更したファイルを把握**
git status

**変更内容を把握**
git diff

**addしたファイルを確認**
git status

**わかりやすいコミットメッセージ**
git commit -m "サブタイトルの色修正"

**自分や他人のコミットを確認**
git log
**変更内容**
git log -p
Qキーを押すことで終了できる
MSI Afterburner で再起動すると設定がリセットされてしまうときの対処法

# はじめに
マイニングや機械学習で使用しているGPU（グラフィックボード）の設定をするAfterbunerとうソフトのチューニングに半日費やしたのでメモを残します。

# Afternunerとは
Afterbunerはこちら
https://jp.msi.com/Landing/afterburner/graphics-cards

VOLTAGE,CLOCK,FANなどをGUIでイジれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/341bfdeb-3e9e-6e08-afb3-ffe9ee37fbc3.png)

# 問題
設定内容が再起動すると保持されないのでググってみたら、BIOSをフラッシュすればいい？とか、電圧制御のロックが解除されてない？とか、半日近く格闘したが未解決に終わりかけた。

# 解決
プロパティ(歯車アイコン) > プロファイル >  2Dプロファイル > 保存したプロファイルを選ぶ

でいけました。
【Docker】php.iniはどこにある？

PHPの環境設定ファイルであるphp.iniの居場所を見失ったので．

####　コンテナ内にあります

Dockerfileの下のようなところに記載されている

```:Dockerfile
（例）
COPY php.ini /usr/local/etc/php/
```

###コンテナ内に入って確認

```
コンテナのnameを確認
$ docker ps
(docker-composeを使っていたら) $ docker-compose ps
```
コンテナの中に入る

```
$ docker exec -it　コンテナname bash
(docker-composeを使っていたら) $ docker-compose exec -it　コンテナname bash
```

移動して確認

```
$ cd /usr/local/etc/php/
$ cat php.ini
```
Webデザイン講座

#HTML
Hyper Text Transfer Protocol 
・W3Cが作った。
・始まりは原子研究所で論文を一緒に読みたいから。
・FPT＝HTMLだけでなく、全て。（→HTTPはHTMLだけ？）
・プロトコル＝Httpとか
・ドメイン＝www.の後ろ
・トップドメイン＝.comとか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1651134/f468444e-12e3-0950-f6de-f78b0ac32119.png)


##ICANN
ドメイン名やIPアドレス、プロトコルポート番号などをグローバルに調整する。

##パラメータ
###FTP
File Transfer Protocol

###HTTP
Hyper Text Transfer Protocol


## Browser
・ウェブデザインをする際は、複数のブラウザでテストをする必要がある。
　→各ブラウザの良し悪しを知るべき。
  →http://html5test.com/index.htmlに接続すると、ブラウザのスコアがわかる。
###Mosaic
世界初のグラフィカルなブラウザ。
その後、ブラウザ戦争が起こる。
ブラウザ戦争とは、NetscapeとMicrosoftの間の激しい戦争期間のことを指し、ブラウザが市場を支配するようになる。
IEはNetscapeのNavigatorに遅れを取っていたが、最終的に勝利し、1990年代はIEの時代になる。

###InternetExplore
・一番有名で、一番人気なブラウザだった。
・Windows10が販売された2015年からは、後続であるMicrosoftEdgeが使われ始めた。

###MicrosoftEdge
・IEの次に人気になったブラウザ。
・IEを使っている人もいるので、Edgeと両方で使える必要があった（当初）

###Google Chrome 
・Googleが作った。
・GoogleChromeはセキュリティに特に注力している。

###Firefox 
・Firefoxはオープンソースとして有名。
・オープンソースとは、誰でもFirefoxを改造できるということ。
・常に改良を重ねられるため、良い。
【Python】便利記法集等（個人的メモ）

個人的メモです. 随時追加します.

#文字列を数値に置換
+ yesなら0, noなら1みたいなやつ

```python
import pandas as pd

data = pd.DataFrame({"ans": ["yes","no", "no", "yes", "no"]})
print("before\n", data)
data["ans"] = data["ans"].map({"yes":0, "no":1})
print("\nafter\n", data)
```
### 実行結果

```
before
    ans
0  yes
1   no
2   no
3  yes
4   no

after
    ans
0    0
1    1
2    1
3    0
4    1
```
<br>


# 部分文字列の判定
+ str型のオブジェクトS, T に対して `S in T` で `T` の部分文字列に `S` を含むか判定

### AtCoder ABC230 B問題解説より

```python
S = input()
T = "oxx" * 10 ** 5
print("Yes" if S in T else "No")

```

# 文字列に数を埋め込む
+ `.format()` を使う

```python
//名前は田中である. 88歳だ.

print("名前は{}である. {}歳だ.".format("Tanaka", 88))
print("名前は{1}である. {0}歳だ.".format(88, "Tanaka"))
print("名前は{name}である. {age}歳だ.".format(name="Tanaka", age=88))

```

+ `{インデックス番号:初期指定}` で書式を変えられる
+ インデックス番号は省略できる

# 集合 `set()` に関するあれこれ

+ `sorted()` は使えるけど `sort()` は使えない
オブジェクトを任意のスピードで回転させる

タイトル通りのスクリプト。
C#初心者なりに上達したいので、
こんな感じのスクリプトをぽちぽち書いていきます


    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class RotaryTable : MonoBehaviour
    {
    public int x = 0;
    public int y = 0;
    public int z = 0;

    // Start is called before the first frame update
    void Start()
    {

    }

    void Update()
    {
        this.transform.Rotate(new Vector3(x,y,z) * Time.deltaTime, Space.World);
    }
    }
Udemyでwebについて学習したことまとめ①

# Udemyにて学習したことについて備忘録としてまとめてみました。

## まずは基本
### ドメイン名
IPネットワークにおいてそれぞれのコンピュータを識別する名称
例)
www.google.com

### IP
internet protocol。
インターネット通信に関する約束ごと

### IPアドレス
IPネットワークに接続された機器を判別するための番号
例)
192.168.1.1

### DNS(domain name system)
ドメイン名からIPアドレスを紐づける仕組み。
インターネット上のコンピュータ同士が通信する際はIPアドレス　
例)
192.168.1.1
人間が使うときは覚えやすいようドメイン名　
例)
www.google.com

### HTML(Hyper text markup language)
・文章構造を記述する仕組み
・webページの内容を記述するためのマークアップ言語
・マークアップコンテンツの始めと終わりに「タブ」をつけ
意味づけする
例)
\<h1>文字\</h1>
※h1は見出し

### CSS(cascading style sheets)
・文字の色やサイズ、レイアウトの指定
・HTMLで書かれた構造化された文章のスタイルを指定するための言語

### JavaScript
・Webブラウザで動作する言語

## フロントエンドとバックエンド
- フロントエンド
 - ユーザーが見て操作する部分
 - クライアント側(ブラウザ)で動作するもの
 - HTML、CSS、JavaScriptで記述
- バックエンド
 - サーバー側で処理が行われるもの
 - DBアクセス、ファイルアクセス、合計金額の計算などを行う
 - プログラミング言語(Rubyなど)で記述 

## 静的なページと動的なページ
- 静的なページ
 - Webサーバ上に置かれたHTMLファイルなどをブラウザで表示するだけ<br>
 　※リロードしても変化しないもの
- 動的なページ
 - アクセスするたびに表示内容が変わる可能性がある
 - サーバー側で動作するプログラミング言語とデータを保存しておける<br>
   データベースを組み合わせてアクセスするたび表示を変えたり
   ユーザーによって<br>表示を書き換える<br>
　 ※twitterなどリロードすると表示が変化するもの  


##### 参考
###### この記事は以下を参考にして執筆しました。
[Udemyのサイトはこちら](https://www.googleadservices.com/pagead/aclk?sa=L&ai=DChcSEwj86qmaoqb0AhUUBGAKHRAoCO0YABAAGgJ0bQ&ohost=www.google.com&cid=CAASEuRosiI9g8wWMNM3IWv9qNg99A&sig=AOD64_0WiuxeRJ3LvyKKWDBRZheaW9AEWQ&q&adurl&ved=2ahUKEwj0gqSaoqb0AhUOiZQKHTbUDj8Q0Qx6BAgCEAE)
React Router Switchが使えないときの解決法

##はじめに
現在大学生でreactを勉強しています.
Routerを使う際にエラーが起きたので解決法について共有したいと思います.
##結論
###バージョンを下げる

``npm install react-router-dom@5``

###もしくは新しい記法に慣れる

・SwitchをRoutesに変更して記述
・Routeのcomponentをelementに変更して記述
・Routeのexactは使わない

##原因
React Routerを使いたくてSwitchをimportしようとした際にに,'react-router-dom'には'Switch'がありませんと言われました.

##解決法
なんで?と思ったんですが調べてみると,どうやらアップデートで記述方法が変更されていたらしいです.

ついでに,Routeを使用する際のexact,componentの変更についても知りました.

以下に参考にした記事を載せておきます.
詳しい説明を見たい方はこちらを参照してください.

##最後に
はじめて投稿しましたが,これからも共有していきたいと思います😊


##参考
https://reactrouter.com/docs/en/v6/upgrading/v5

https://stackoverflow.com/questions/63124161/attempted-import-error-switch-is-not-exported-from-react-router-dom
to_s は数値を文字列化するメソッド，なのか？

Ruby の初心者がお書きになった記事で，

> `to_s` は数値を文字列にするメソッドです

と書かれているものを非常によく目にします。
確かに

```rb
3.to_s   # => "3"
0.1.to_s # => "0.1"
```

ですから，このメソッドは数値を文字列に変換しています。
にも関わらず引用した表現に引っかかりを感じるのは，数値以外のオブジェクトにも `to_s` メソッドが使えるからです。

```rb:例
{朝: 3, 暮: 4}.to_s
# => "{:朝=>3, :暮=>4}"
```

Ruby に入門したての方は，

* 同名のメソッドが複数のクラスやモジュールに定義されていることがある
* そのうちのどのメソッドが呼び出されるかはレシーバーによって決まる

ということを早いうちに知っておかれるとよいと思います。

（メソッド呼び出しの）レシーバーというのは，上記のコードで言えばメソッド呼び出しの `.` の前に書かれているオブジェクトのことです。
一般には，メソッド呼び出しの `.` の前には式を書くことができ，その式を評価した結果として得られたオブジェクトがレシーバーとなります。たとえば，

```rb
(1 + 2).to_s
```

というコードであれば，「`1 + 2` という式を評価して得られた `3` という Integer オブジェクト」が `to_s` メソッドのレシーバーになります。

Ruby の組込みクラスの場合，`to_s` はすべて「自身を表現する文字列オブジェクトを返す」という働きを持ちます。
どのように文字列表現を作るかはクラスごとに違っています。同じ数値クラスでも，Integer の `to_s` と Float の `to_s` は別のメソッドであり，前者が引数を取りうるのに対し，後者は引数を受け付けない，といった違いもあります。
【Mac】スクリーンショットの保存場所を変更する方法

# デスクトップがスクリーンショットだらけになっていない？
スクリーンショット便利ですよね。私もメモの代わりだったり、仕事で変更したスタイルを共有する際によく使用します。
ただ、デフォルトの設定のままだとどんどんデスクトップにスクリーンショットが増えてしまう…デスクトップを綺麗に保ちたい民にとってこれは死活問題ですよね！
今回はスクリーンショットの保存先を指定する方法をここに残しておきます。

# スクリーンショットの保存先を変更する方法
1. スクリーンショットを保存したいファイルを作成する

1. `shift + command + 5`でスクリーンショットのメニューを開く
1. オプションメニューの一番上にある保存先から、スクリーンショットを保存したいファイルを選択する![スクリーンショット 2021-11-20 午後2.26.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684193/76a4159d-9bbc-6d88-0dc2-f3142c3ab6b7.png)

1. おわり！🎉

## 【おまけ】スクリーンショットの名前を変更する方法
ターミナルに`defaults write com.apple.screencapture name **`(**には付けたい名前をいれる)と入力
そうすると保存されるスクリーンショットの名前が「スクリーンショット 日付」から「＊＊　日付」に変更できます。
Unity Student のラインセンスが突然切れた

マニュアルアクティベートで期限切れと言われたが、割と最近にライセンスを取り直したはずなので、ちょっと粘ってみた。

まず、以下の画面でシートの削除、再割り当てをしても直らなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253921/e1627d27-951f-86b5-3c9e-782fd9f402b0.png)

実は、青色で塗りつぶしたところにあるリンク（シリアルキーが書かれている）の先にさらにページがある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253921/87d94273-edc4-2e20-5b7d-12eba30b5733.png)

問題発生時、ここに２台分の情報があったが、すべてのアクティベーションを削除し、0 件になっている状態で Unity Hub から再度、同じシリアルキーを入れると、きちんと認証された。

そういえば、Unity Student Plan は１台分でしかアクティベートできなかった気がするので、それが原因かもしれない。（逆に、なぜ２台分登録できていたのかは謎）

というわけで、意外とあっさり直った。
Elasticsearch の scroll でダンプしてみる

# Overview

Elasticsearch の index をダンプするのに Scoll API とかいうのがあるのを知ったので、
https://qiita.com/mug-cup/items/5fbe8a4fd27a2f6492b1

ここはシェル芸でひとつ。

# コード

```bash:.curlrc
-H "Content-Type: application/json"
```

```json:body.jq
{
  "scroll": "1m",
  "scroll_id": $v[0]._scroll_id
}
```

```bash:dump-scroll.sh
#!/bin/bash

ES_ENDPOINT="http://localhost:9200"
ES_INDEX="hoge"

curl -K .curlrc "${ES_ENDPOINT}/${ES_INDEX}/_search?scroll=1m&size=9000" >000.json
jq -n -f body.jq --slurpfile v 000.json >body.json

yes | awk '{ printf "%03d\n", NR }' \
| while read i; do
    curl -K .curlrc "${ES_ENDPOINT}/_search/scroll" -d@body.json >${i}.json
    jq --exit-status '.hits.hits == []' ${i}.json && break
done
```

# 投入はこんな感じ

cf. https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html

```json:es-to-bulk.jq
.hits.hits[]
| {
  index: {
    _index: ._index,
    _id: ._id
  }
}, ._source
```

```bash:import.sh
#!/bin/bash

ES_ENDPOINT="http://localhost:9200"

ls ???.json | while read f; do
    echo ${f}
    jq -c -f es-to-bulk.jq ${f} \
        | curl -K .curlrc "${ES_ENDPOINT}/_bulk" --data-binary @-
done
```
PowerAppsでデータソースからキャンバスアプリを作成して、SubmitForm();Navigate()がうまくいかない人へ

簡単なアプリを作っていてハマったのでメモ。
データソースからアプリ作れるの簡単だから良いんですけどね、、、

#結論
EditFormのOnSuccessが悪かった(それを知らない自分が悪かった)

#経緯
データソースからアプリ作ると最初3つ画面が作られる。
そこから画面を増やし、データ編集をする画面(初期状態のEditScreen1てやつ)の入力が終わった時に、特定のページに遷移するよう設定したかった。
だからチェックマークのアイコンのOnSelectに
![スクリーンショット 2021-11-19 20.54.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485045/d8c5363c-b5c9-037d-e575-0b741dfa8e8d.png)


```
SubmitForm(xxx);Navigate(yyy)
```

としたら

__う　ま　く　い　か　な　い__

#解決法
探し回って、どうやらOnSuccessが悪さをしているとのこと。
でもチェックマークのアイコンにOnSuccessは
__見　つ　か　ら　な　い__
![スクリーンショット 2021-11-19 21.03.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485045/7d3ce95e-3406-2b23-160a-42a0fb58adc9.png)

「やっぱイチから作るかー」なんて考えてた矢先に「そういやフォームを編集してるんだったよな」と思い見直すと
__そ こ に お っ た ん か わ れ__
![スクリーンショット 2021-11-19 21.06.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485045/2f7c5894-86b3-33c0-e887-b8d669c83b46.png)
EditFormのOnSuccessにBack()の代わりに

```
Navigate(yyy)
```

と書き換えて、チェックマークのアイコンのOnSuccessを

```
SubmitForm(xxx)
```

に戻し無事遷移。

#他に
「ここで詰まったわ」なんてのがあったらコメントに残してもらえると嬉しいです。
[Beautiful Soup]を使ったスクレイピングの実装方法

##概要
今回は「WEBブラウザ上のページURLからスクレイピング→情報を抽出してcsvに追記する」という実装方法について記載します！

◼︎必要ツール&モジュール
[Beautiful Soup]
[python]
[pandas]
[requests]
◼︎環境
[jupyter notebook]


### 実装コード解説
notebookのインストール方法から立ち上げ方までは省略します！
また、通常関数化させますが解説のため関数化せずに記載します！

[【初心者向け】Jupyter Notebookの使い方！インストール方法から解説](https://udemy.benesse.co.jp/development/python-work/jupyter-notebook.html)

#### 実装フロー
ざっくりとした内容はこちらです。
URLから情報を抽出→内容を加工→追記


・URLから情報を抽出

```py:py
from bs4 import BeautifulSoup
import requests
import pandas as pd
from datetime import datetime

url = 'https://~'
read = requests.get(url)
# 読み取ったテキスト情報を解析します。 
ex = BeautifulSoup(read.text, 'html.parser')
print(ex)
```
全体のHTMLが取得できたことを確認できましたか？
それでは上記内容から必要事項のテキストを抽出しますが
方法はテキストの前にあるclass名を記載すれば可能です！
class名の取得には「Chrome」の検索エンジンで対象ページを開いた状態で「デベロッパーツール」を使うのがオススメです。
「Mac：Command + Option + I」
「Windows：Ctrl + Shift + J」

```py:py
# 読み取った全体のHTMLを格納した変数「ex」から部分抽出する
title = ex.select('.title')[0].string
print(title)

# 読み取るテキスト情報に高橋の点数：50という内容があればsplitで分割して50の数字だけを抽出することも可能です！
second = ex.select('.subscribers')[0].string
t_second =  int(second.split('：')[1])
```

・内容を加工
上記内容でそれぞれ取得したい情報を抽出して変数に格納して行きます。
次にそれぞれ取ってきた情報をJSON形式に整形します！

```py:py
# 変数「ap」に格納します。
ap = {
    'タイトル' : title,
    '点数' : t_second,
}
```

・ファイルの読み取りから追記
では今度は最初にimportした「pandas」を使用した後ファイルに追記します。

まず、先ほどの情報を追記するためのcsvが必要なので同じディレクトリに
[appendファイル]を配置します。
そのあと追記して保存という流れになります。


```py:py
# csvを読み取りdfに格納します。
df = pd.read_csv('append.csv')

# 本日の日付を取得
date = datetime.today().strftime('%Y/%-m/%-d')

# 格納した変数より情報を抽出して追記する為の形式に合わせるために「datefarame」に格納します。
ap_tt = ap['title']
ap_se = ap['t_second']
last = pd.DataFrame([[date, ap_tt, ap_se]],columns=['date', 'title', 'score'])

# csvと格納した変数lastを結合させることで情報を追記します。
dg = pd.concat([df, last])

# 保存して完了
df.to_csv('data.csv', index=False)

```
上記保存の最終行に抽出したデータが追記されたら成功です！！



## まとめ
今回、関数を使用せずなるべく簡略化せずに基礎としてコードを記載しましたが
もっと複雑な内容を抽出/加工して追記する方法やコードを1行にまとめたり
抽出を定期実行させたり、クラウド上で読み書きさせたりと発展版が様々あります。
一連の流れをマスターして、自分なりのアレンジを組み合わせて作ったものを当方にも教えていただけると幸いです！

最高なクリエイティブLIFEであれ！


追記/関数

```python
from bs4 import BeautifulSoup
import requests
import pandas as pd
from datetime import datetime


# サイトから必要項目を抽出する関数
def get_info():
    url = ''
    
    read = requests.get(url)
    s = BeautifulSoup(read.text, 'html.parser')
    
    name = s.select('.abc')[0].string
    
    second = ex.select('.subscribers')[0].string
    t_second =  int(second.split('：')[1])
    
    results = {
    'name' : name,
    't_second' : t_second,
    }
    return results

# 必要項目をファイルに追記する
def get_data():
    df = pd.read_csv('file.csv')
    
    #新規のデータ
    results = get_info()
    
    #書き込みデータ
    date = datetime.today().strtime('%Y/%-m/%-d')
    reviews = results['t_second']
    last = pd.DataFrame([[date, reviews]],columns=['date',  'score'])

    df = pd.concat([df, last])
    df.to_csv('data.csv', index=False)
    
if __name__ == '__main__':
    write_data()
```

参照
[［Python入門］Beautiful Soup 4によるスクレイピングの基礎](https://atmarkit.itmedia.co.jp/ait/articles/1910/18/news015.html#bs4)
[図解！Python BeautifulSoupの使い方を徹底解説！(select、find、find_all、インストール、スクレイピングなど)](https://ai-inter1.com/beautifulsoup_1/)
Xcode 13でSwiftプロジェクトをローカライズ（翻訳）

以前、Xcodeにはローカリゼーションをエクスポート / インポートする機能がありましたが、外部のXLIFFエディターが必要でした。WWDC 2021でリリースされたXcode 13には、ローカリゼーション用のエディターが組み込まれています。

この記事では、Xcode 13におけるローカリゼーションのフローについて説明します。

## セットアップ

Xcodeは、既定の開発言語（アプリを開発している時に使用する言語）として英語を使用しています。これは日本語に変更することができます。
[Development language の変更](https://qiita.com/MaShunzhe/items/86200a5c03817497ac29#development-language-の変更)

また、[アプリの翻訳先言語も指定する必要があります。](https://qiita.com/MaShunzhe/items/86200a5c03817497ac29#新しい言語の追加).


## ローカライズ可能な文字列をマークする

SwiftUIビューでは、よく使用される多くのビューコンポーネントにおいて、テキストエントリーはすでにローカライズ可能なものとしてマークされています（例えば、Text、TextField、およびButtonなど）。

![スクリーンショット 2021-11-18 15.25.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/13094ed4-d5dc-f31d-69ac-eb57a630809e.png)

UIKitを使用し、Swiftでコードを書いている場合、`NSLocalizableString`関数で文字列をラップする必要があります。

```swift
let alert = UIAlertController(title: NSLocalizedString("テストタイトル", comment: ""),
                              message: NSLocalizedString("メッセージの内容", comment: ""),
                              preferredStyle: .alert)
```

カスタムSwiftUIビューがある場合、`NSLocalizableString`関数の使用が必要になる場合もあります。

## ビルド設定の更新

コンパイラがローカライズ可能な文字列を抽出します。プロジェクトを選択し、`Build Settings`に移動して、`Use Compiler to Extract Swift Strings`をオンにします。

![スクリーンショット 2021-11-18 15.18.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/0552f494-9461-528c-168b-d7df5e513c90.png)

## ローカリゼーションをエクスポート

`Product`メニューをクリックし、`Export Localizations`をクリックしてください。

![スクリーンショット 2021-11-18 15.49.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/987a3aa0-f056-d4a8-b5fd-b5ea0d7a5ed0.png)

## 翻訳を入力

生成されたフォルダーを開き、`.xcloc`ファイルをダブルクリックしてください。GUIが表示されます。
ターゲットが複数ある場合、選択してターゲットフォルダーを開き、ファイルのいずれかをクリックしてください。

右側の、ターゲット言語が表示されている列のテキストをダブルクリックして編集します。

![スクリーンショット 2021-11-19 13.24.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/7932fb7c-10ce-3ea6-ce88-7aae9a22f231.png)

ファイルを保存します。

## ローカライゼーションのインポート

Xcodeで、`Product`メニューをクリックして、`Import Localizations`をクリックします。 `.xcloc`ファイルを選択して、翻訳をインポートします。

![スクリーンショット 2021-11-18 15.49.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/65e78992-5e1d-7683-3188-63cd6e3210af.png)

## Storyboardローカライズ

[こちらのリンク](https://qiita.com/MaShunzhe/items/86200a5c03817497ac29#ストーリーボードのローカリゼーション)を参照することにより、UIKit Storyboardのローカライズ方法を学ぶことができます。

---

:relaxed: [Twitter @MszPro](https://twitter.com/MszPro)

:newspaper: [iOS開発に関するニュースレター iOS Dev Letter](https://ios-dev-letter.com)

:sunny: [私の公開されているQiita記事のリストをカテゴリー別にご覧いただけます。](http://mszpro.com/ioskiji/)
<img width="150" src="https://cdn.mszmagic.com/static-web-content/AppClipImage_small.png">
ESP32(Arduinoフレームワーク)で利用できるRemoteDebugライブラリについてメモ

[RemoteDebug](https://github.com/JoaoLopesF/RemoteDebug)はESP32/ESP8266(Arduinoフレームワーク)で利用できるワイヤレスデバッグのためのライブラリ。ADBなどのモダンな開発環境の様に７段階にログレベルを設定してデバッグログを出力できる。mDNSにも対応しているため、いちいちIPを調べなくても良い。
接続は基本TELNETクライアントで行う。[webアプリ版](https://github.com/JoaoLopesF/RemoteDebugApp)もあるらしい。ウェブアプリ版のREADMEのリンクはドメインの有効切れで接続すると変な広告サイトに飛ばされるので利用したい場合はローカルにダウンロードして実行すべし。

2019年5月を最後に開発がストップしている。ワイヤレスが必要ない場合は[SerialDebug](https://github.com/JoaoLopesF/SerialDebug)と言うライブラリもある。

---
利用する時にハマりやすい点


コンパイルエラーが出るので対策
src/utility/WebScokets.cppの42行目を

``` WebSockets.cpp@Line42 
#include <hwcrypto/sha.h>
``` 
を以下のように書き換える

``` WebSockets.cpp@Line42 
#include <sha/sha_parallel_engine.h>
``` 

一定時間おきに
`debugHundle()` 
を呼び出す必要がある。呼び出す用の別タスクを作っておくと良い。


``` 
void debug_handle_task(void *pvParameters){
  while(1){
    debugHandle();
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

void setup(){
  //debug用タスクを作成
  xTaskCreate(
    debug_handle_task,               // task function
    "DEBUG",             // task name
    8192,                // stack size
    NULL,                // タスクに渡すポインタ       
    1,                   // task priority
    NULL                 // task handle pointer
  );
}

```
cmakeでMPIのパスが見つからないときの対処法

CMakeで MPIを利用する際には以下のように書くとライブラリのパスやインクルードパスを設定することができる。

```cmake
find_package(MPI)

add_executable(hello.out hello.cpp)
target_link_libraries(hello.out PRIVATE ${MPI_LIBRARIES})
target_include_directories(hello.out PRIVATE ${MPI_INCLUDE_PATH})
```

`find_package(MPI)`によってMPIがインストールされているパスを検索し、インクルードパスとリンクパスが適切に設定される。

しかし、ある時次のようなエラーに遭遇した。

```
CMake Error in /home/murase/.../cmake-build-debug/CMakeFiles/CMakeTmp/CMakeLists.txt:
  Imported target "MPI::MPI_C" includes non-existent path

    "/usr/local/Cellar/open-mpi/4.1.1_2/include/openmpi"

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.
```

パスが見つからないという問題でしばらくハマった。
この原因は実は`brew upgrade open-mpi`をしていたことが問題でMPIのインストール先のパスが変わっていた。cmakeは`find_package`で見つけたパスをキャッシュしており、パスの変更がcmakeの設定に反映されていなかったのが原因だった。

対処法としては、buildディレクトリを削除してもう一度cmakeするとうまく動作するようになる。clionの場合は、Tools->CMake->"Reset Cache and Reload Project"で問題が解決する。
Kubernetes WebUIダッシュボードを導入しKubernetesクラスター環境のリソース収集/監視


[以前の記事](https://qiita.com/rui-watanabe/items/761195cec8ad324a05c6)では、Kubernetes環境のリソース情報の収集や監視を行うためにMetrics Serverを導入しました。

今回の記事では、リソース情報の収集をWeb UIで確認できる、**Kubernetes WebUIダッシュボードの導入**を行っていきたいと思います。

## Kubernetes WebUIダッシュボードのリソースを作成

まずKubernetes WebUIダッシュボードのリソースを作成します。

```
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
```

kubernetes-dashboardのリソースがあることを確認。

```
# kubectl get pods --all-namespaces | grep dashboard
```

## NodePortでの外部公開

ダッシュボードをWebで表示するための、NodePortを指定する変更を行います。

```
# kubectl -n kubernetes-dashboard edit service kubernetes-dashboard
(snip)
ports:
- port: 443
protocol: TCP
targetPort: 8443
nodePort: 32001 <- nodePortを追加
(snip)
# type: ClusterIP
type: NodePort <- NodePortに変更
(snip)
```

この時点で、https://ノードIP:32001で以下のようなWebページが表示されます。

![demo](https://gyazo.com/ff9ec8583d219000dfb48e8c4159e57f/raw)

## ログインユーザー情報の作成


ログインにはユーザー情報のトークンが必要なので、adminユーザーでTokenを作成していきます。

```
# vi kubernetes-dashboard-admin.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard

# kubectl create -f kubernetes-dashboard-admin.yml
```

上記のServiceAccountとClusterRoleBindingのリソースを作成後、以下のコマンドでトークンを表示します。

```
# kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
```

再度https://ノードIP:32001にログインし、上記に表示されたトークンでログインすると、ダッシュボードが表示されリソースの状況の確認などが行えます。

これでKubernetes WebUIダッシュボードの導入は完了です。

![demo](https://gyazo.com/094e039de479c0de5a706205ccb9f748/raw)

## 参考URL

https://kubernetes.io/ja/docs/tasks/access-application-cluster/web-ui-dashboard/
https://qiita.com/yasubehe/items/838832fe488b72fcc887
https://sky-joker.tech/2019/04/21/kubernetes%E3%81%AE%E3%82%BF%E3%82%99%E3%83%83%E3%82%B7%E3%83%A5%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E3%82%92%E5%A4%96%E9%83%A8%E3%81%8B%E3%82%89%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99/
https://ponteru.hatenablog.com/entry/2020/01/15/220830
wsadminで設定し、設定できたことを確認する(JVM編)

まぁアプリケーションサーバヒープサイズと起動引数は絶対現場ではそれぞれ設定するかと思います。
設定値を変数渡しをしたい場合はこちらのコードを参照してください。
※いつか直します。。。
https://qiita.com/XKYUXSOX/items/7f33c1ee19827030f0a7

```JVM_set.py
import csv

with open('jvminfo.txt') as f:
    csvreader = csv.reader(f)
    for row in csvreader:
      nodename=row[0]
      servername=row[1]
      id=AdminConfig.getid('/Node:'+nodename+'/Server:'+servername+'/')
      ProcessID = AdminConfig.list('JavaVirtualMachine',id)
      print nodename + servername
      AdminConfig.modify(ProcessID,'[[initialHeapSize "256"]]')
      AdminConfig.modify(ProcessID,'[[maximumHeapSize "256"]]')
      AdminConfig.modify(ProcessID,'[[genericJvmArguments "-Djava.awt.headless=true,-verbose gc"]]')

AdminConfig.save()

```

設定がきちんとできたことを確認する。


```JVM_get.py

import csv

with open('jvminfo.txt') as f:
    csvreader = csv.reader(f)
    for row in csvreader:
      nodename=row[0]
      servername=row[1]
      id=AdminConfig.getid('/Node:'+nodename+'/Server:'+servername+'/')
      ProcessID = AdminConfig.list('JavaVirtualMachine',id)
      print nodename + servername
      print AdminConfig.showAttribute(ProcessID,'initialHeapSize')
      print AdminConfig.showAttribute(ProcessID,'maximumHeapSize')
      print AdminConfig.showAttribute(ProcessID,'genericJvmArguments')

```
macOS Montereyで"zsh: command not found: php"が出る際の対応方法

MacBook Pro M1 Proが手元に届いたので、開発環境を整えてzshでhomebrewインストールも完了。PHP@7.4をインストールしてPATHを通すところでつまづいた。

```terminal
php -v
```
をしても

```terminal
zsh: command not found: php
```

が表示されてしまう。

```terminal
brew list | grep php
```
では問題なくPHP@7.4が表示されるのでおかしい。

結論、リンクが必要だった。

macOS MontereyのPHPインストール手順としては、

```terminal
brew install php@7.4
```

```terminal
brew link --overwrite --force php@7.4
```

するとそこに表示される

```terminal
echo 'export PATH="/opt/homebrew/opt/php@7.4/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/opt/homebrew/opt/php@7.4/sbin:$PATH"' >> ~/.zshrc
```

を実行。

```terminal
source ~/.zshrc
```

をすると、無事にPHPが認識された。

```terminal
PHP 7.4.26 (cli) (built: Nov 18 2021 15:10:22) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.26, Copyright (c), by Zend Technologies
```
環境構築でつまづくPATHエラーの解決方法！

##概要
インストールすると下記エラーが表示される。
エラー内容を調べると大体が「PATH」を通すという内容が返されます。

```
Requirement already satisfied:~
```
PATHを通す？？？？

なにそれ？？？ってなりますよね！
エラーの対応方法は知っていましたが、恥ずかしながら
なんとなくの意味の理解でしたので解説します。

### PATHを通す
つまり「モジュールをインポートをしたがどこの場所にあるか分からない」と言われています・
トラクターを搬入したが工事現場の監督がどこにいるかわかないという状況ですね！
いちごパフェと言いながらいちごが下にありすぎてどこにあるかわかないという状況ですね！
バチカン市国といいながら、、、、、失礼！！！！！！

つまりはここですよ！！！！って教えてあげる意味で
エラーが出た表示の①の部分のここから読んでほしいという道筋をパソコンに記載してあげる必要があります。

◼︎解決法
シェルスクリプトでpipを実行して下記のエラーが出たらexportにパスを記載してエクスポートします！
これにより「bash_profile」のなかにURLが設定されます！！！！！
順序

```
$ Requirement already satisfied:~①
```
↓

```
 $ export PATH=$PATH:'/Users/~①を記載して実行
```

↓

```
$ source ~/.bash_profile
```
↑確定させる

### まとめ
エンジニアを目指す人は環境構築からいいライフをお過ごしください！