OmniAICreator/Qiita-1.07M huggingface dataset:
【Capybara,webdrivers】統合テスト(System Spec)とは

##統合テスト(System Spec)とは
統合テストは、アプリケーション全体が一つのシステムとして期待通りに動くか否かを検証するテストのこと。

統合テストにおいては、``Capybara``という``ruby``のライブラリを使用。``Capybara``を使うことで、実際のアプリケーションの使われ方をコードで表すことができる。（**fill_in**や**click_button**など）

``webdrivers``は``ChromeDriver``を簡単に導入してくれるgemである。アプリケーション全体が一つのシステムとして期待通りに動くか否かを検証する場合、実際にブラウザでテストがそうのように動いているのか目視できた方が分かりやすいので、``Capybara``と``webdrivers``はセットで入れることが多い。

``Capybara``と``webdrivers``の導入を記載していく。

##gemの導入

```Gemfile.
group :test, :development do
  # （省略）
  gem 'capybara'
  gem 'webdrivers'
end
```

``bundle install``後、``spec/rails_helper.rb``に下記の一文を追記。

```spec/rails_helper.rb
require 'capybara/rspec'　　#追記

Capybara.configure do |config|
---省略---
end
```

##webdriversの設定

``spec/support``ディレクトリ下に``capybara.rb``を作成し、下記を追記。

```spec/support/capybara.rb
RSpec.configure do |config|
    config.before(:each, type: :system) do
        driven_by :selenium, using: :headless_chrome　#←ブラウザの表示無
       #driven_by :selenium_chrome　←ブラウザの表示有
    end
end
```

``chrome``についての設定を記入している。ここで``headless_chrome``と記入されている一文を表記すればブラウザの表示を無しにできる。
逆に、コメントアウトされている方を記載すると、ブラウザの表示有になる。

**注意**
テストファイルを作成した際、おそらくデフォルトで下記のようになっている。

```example_spec.rb
require 'rails_helper'

RSpec.describe 'Tasks', type: :system do
before do
driven_by(:rack_test)
end

pending "add some scenarios #{__FILE__}"
#↑この1文はRSpecの書き方を解説している。削除してOK
end
```
``driven_by``で実行時のブラウザを指定しているので、この記載を削除。（``spec/support/capybara.rb``でブラウザの指定を一元管理しているため）

##【Capybara】要素を操作するメソッド

| メソッド| 動作 |
|:-:|:-:|
| visit  |  ページへアクセスする(GETリクエスト) |
|  check | チェックボックスをチェックする  |
|uncheck   |  チェックボックスのチェックを外す |
| fill_in  | テキストフォームに入力する  |
|  select |セレクトボックスを選択する   |
| choose  | ラジオボタンを選択する  |
| attach_file  | ファイルセレクタにファイルを設定する  |
| click  |  クリックを実行する |
|  click_on |  ボタンorリンクをクリックする(click_button/click_link) |
|  accept_alert | アラートのボタンをクリックする  |
|switch_to_window(windows.last)|最後に開いたタブに移動|
|page.driver.browser.switch_to.alert.accept|アラートウインドウの「OK」ボタンを押す|
|page.driver.browser.switch_to.alert.dismiss|アラートウインドウの「キャンセル」ボタンを押す|
|have_selector|特定のタグやCSS要素に特定の文字列が表示されているかを検証|

##実用例

```tasks_spec.rb
equire 'rails_helper'

RSpec.describe 'Tasks', type: :system do
  let(:user) { create(:user) }
  let(:task) { create(:task) }

  describe 'タスク削除' do
      let!(:task) { create(:task, user: user) }

      it 'タスクの削除が成功する' do
        visit tasks_path
        click_on "Destroy"
        expect(page.accept_confirm).to eq 'Are you sure?'        
        expect(page).to have_content "Task was successfully destroyed"
        expect(current_path).to eq tasks_path
        expect(page).not_to have_content task.title
      end
    end
  end
end
```

##参考記事
[【Rails】Capybaraを使った統合テスト（導入〜簡単なテスト実行まで）](https://qiita.com/koki_73/items/c033e7a059192ec73c25)
[【Rspec】統合テスト(System Spec)について](https://post-output.com/%E3%80%90rspec%E3%80%91%E7%B5%B1%E5%90%88%E3%83%86%E3%82%B9%E3%83%88system-spec%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/?amp=1#toc2)
[Rspecの設定（SystemSpecの導入、実行時にブラウザ表示、非表示の切り替え設定） #5](https://github.com/diveintocode-corp/rails_exam01_bugfix/issues/5)
[Capybaraと仲良くなる（タブ・ウィンドウの操作について）](https://qiita.com/TAByasu/items/b88f069a2f9f07253f47)
数と数字と数値

# TL;DR
大小を比較する事やその順番に意味があるならそれはきっと「数値」なのでInteger等のカラムを使おう。
そうじゃないならそれはきっと「数字で表されたコード」なのでString等のカラムにしておこう。

[ここ](https://qiita.com/)は日本語についての知識を記録・共有するための場所ではなく、[エンジニアに関する知識を記録・共有するため](https://qiita.com/about)の場所なので、ざっくりと。

# 数（かず）ってなんだろ
量や順序を表すものです。

# 数字（すうじ）ってなんだろ
主に数を表記、表現するために使用する記号、文字です。

# 数値（すうち）ってなんだろ
数が（主に数字によって）表された値です。

# つまり？
数字で書いてあっても数ではないものがあります。
例えば電話番号や車のナンバーなどは数字で書かれていますが、数ではないし数値でもないです。
こういった物をDBに格納する際にInteger等のカラムを使うと色々と不都合があります。
わかりやすいところでは「先頭の0」がなくなったり、「先頭の0」のせいで8進数になったりです。

一見数値だけど実は数字、というパターンが数多く存在します。
また、数字のことを数値と言ってしまってる場合も多いです。
大小を比較（つまり量）できそう、順番を表してそう、でも数値じゃないってこともあります。
電話番号やナンバーは一見数値ですが、量や順番そのものに意味はありません。

定義書に「数値型」って書いてあるそのデータ、本当に「数値」ですか？

数値なのか数字なのか分からなくなってきたそこのアナタ。
ランチェスターではサーバーサイドエンジニアを募集していますので、数値と数字についての議論がてら、まずはざっくばらんにお話ししてみませんか？
下記からご応募お待ちしております。
▼ https://herp.careers/v1/lanchester/Bucw0mXRKogc
▼ https://www.wantedly.com/companies/lanchester
▼採用動画について：https://moovy.jp/job/651
【Android】AnimatedVectorDrawableを作成する

# 概要

作成方法が少しややこしかったので、自分用にメモ。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/68778e4d-1f89-9c5b-93a3-4e997dea386c.gif" width="50%">
[AnimatedVectorDrawable](https://developer.android.com/guide/topics/graphics/drawable-animation?hl=ja#AnimVector)により画像をアニメーション化する方法について説明。
ここでは、[Shape Shifter](https://shapeshifter.design)を使用して作成する方法を記述。


# 作成方法
## 1. SVG画像を2個用意
アニメーション開始時の画像と終了時の画像をsvg形式で用意。

## 2. Shape Shifterにimport
[Shape Shifter](https://shapeshifter.design)サイト内の左側のImport→SVGをクリックし、用意した2つの画像を選択し、importする。

## 3. アニメーション追加
3-1. 左下のフォルダツリーから終了時の画像を選択し、右上にあるpathDataをコピー。
![explain1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/0cc69e5a-a8e5-7e5d-e382-e928a739269b.png)

3-2. 左下のフォルダツリーの開始時の画像の右にある時計アイコン→pathDataを選択。
![explain2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/9b448cad-cf54-c379-423e-6c3b22842d68.png)

3-3. pathDataのtoValueを消して、3-1でコピーした値をペースト。Auto Fixするために、下に出てくる赤色のアイコンをクリック。自動でいい感じにアニメーションをしてくれる。
![explain3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/badaf8f3-7c4e-3d6b-d422-2283fa54087d.png)

3-4. 左下のフォルダツリーから終了時の画像を選択し、デリートキーを押す。これはもういらないので削除する。

## 4. 保存
左下のExport→Animated Vector Drawableを選択。
Javascriptでランダムな文字列を生成

https://qiita.com/fukasawah/items/db7f0405564bdc37820e
function getRandomStr(){
  const LENGTH = 8 //生成したい文字列の長さ
  const SOURCE = "abcdefghijklmnopqrstuvwxyz0123456789" //元になる文字
  let result = ''

  for(let i=0; i<LENGTH; i++){
    result += SOURCE[Math.floor(Math.random() * SOURCE.length)];
  }
  
  return result //p9zh1ziw
}
クロスサイト・リクエスト・フォージェリーの対策-react

クロスサイト・リクエスト・フォージェリー対応方法
step1:
各ページでAPIを呼び出す直前にワンタイムトークン（乱数Aとする）を生成し、生成した「乱数A」をCookieに格納します。
「乱数A」をハッシュ化（SHA256）します。その結果を「ハッシュB」とします。

utils.tsに共通方法を追加する
//クロスサイト・リクエスト・フォージェリーの対策:ランダム文字列ハッシュ化（SHA256）
export const digestMessage = async (message: string | undefined) => {
const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8); // hash the message
const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
return hashHex;
}
//SHA256化Tokenを生成する
export const setCsrfToken = async () => {
var radm = String(Math.random());
console.log("SHA256化前:", radm);
const csrf_token = await digestMessage(radm);
console.log("SHA256化後:", csrf_token);
console.log('set csrf_token=' + csrf_token);
document.cookie="csrf_token=" + csrf_token + "; path=/";
};
//Tokenを取得する
export const getCsrfToken = () => {
const csrf_token = document.cookie.replace(/(?:(?:^|.*;\s*)csrf_token\s*\=\s*([^;]*).*$)|^.*$/, "");
console.log('get csrf_token=' + csrf_token);
return csrf_token;
};
step 2:
「ハッシュB」はAPIのパラメーターとして、サーバーへ送信します。その際、Cookieに埋め込まれた「乱数A」の値も送信されます。

// ページの初期化後にホームの情報を取得する
useEffect(() => {
setCsrfToken();
dispatch({
type: 'home/fetchHomeInfo',
payload: {
language: getLocale(),
csrfToken: getCsrfToken(),
}
}).then((res: RequestResponse) => requestErrorPopup(res));
}, []);

step3:
API側でCookieに格納された「乱数A」とリクエストとして送られてきた「ハッシュB」を取り出して、取り出した「乱数A」をハッシュ化（SHA256）して「ハッシュB」と比較します。
Cookie cookie = request.getCookie("csrf_token").get();
if(!csrfToken.equals(cookie.value())) {
//if(!csrfToken.equals(cookie.value())) {
logger__.error("csrfToken is diffent with request cooike");
return internalServerError(LogMessage.CMN_SYSTEM_ERROR);
}
multiprocessingで並列処理 【備忘録】

Poolオブジェクトによる基本的なプロセス管理と、Pipeオブジェクトを使った返り値処理を記載する。
[multiprocessing Documentation](https://docs.python.org/ja/3/library/multiprocessing.html)(accessed: 2022/01/31)

## 実行環境
Mac OS Monterey 12.1
Python 3.9.2
iMac (Retina 5K, 27-inch, 2017)
プロセッサ 3.4 GHz クアッドコアIntel Core i5

## Pool Object
引数 processesに整数を与えるとその数のプロセスを生成して並列処理を行う。何も与えないと自動的にos.cpu_count()が返す値を使ってプロセスを生成する。

### imap_unorderd(func, iterable[, chunksize])
プロセスにタスクを渡す方法は複数あるが、タスクの処理順を気にしない場合はimap_unordered()が最も速い。
funcに処理したい関数を渡し、iterableにその引数を渡す。chunksizeはタスクの分割サイズを決めるものだがunorderdの場合処理が終わったプロセスから順番にタスクが振られるので気にする必要はない。

```python
pool = Pool()
pool.imap_unordered(api_task, params) # これだけで並列処理してくれる。

# tqdm(プログレスバー)を組み合わせたバージョン
with tqdm(total=len(params)) as t:
        for _ in pool.imap_unordered(api_task, params):
            t.update(1)
```

## Pipe Object
他プロセスからの返り値を受け取るために使う。
片方の端で読み書きを同時に行うとPipe内データが破損する恐れがある。
引数にduplexを取り、 duplex=Trueで双方向性,Falseで一方向性のPipeを生成できる。
データの破損を避けるためにFalseで運用するのが無難。

```python
from multiprocessing import Process, Pipe

def double(x, sender):  # 並列処理に渡す関数
    sleep(3)
    y = x*x
    sender.send(y)
    return None
    

nums = range(5)
process_list = []
connections = [] # Pipe

for name in names:
    receiver, sender = Pipe(False) # 受信側、送信側の順で生成される
    p = Process(target=double, args=(nums, sender))
    connections.append(receiver)
    process_list.append(p)
    p.start()  # プロセスの処理を開始する。

for process in process_list:  # タスクの終了待ち処理 この間プロセスはロックされる。
    process.join(1) # 1秒間のタイムアウトをとる タスクひとつひとつが十分に高速に処理できる場合いらないかもしれない。(要動作確認)

results = [conn.recv() for conn in connections]
print(results)

for process in process_list:
    process.terminate() # プロセスを終了させる
```


## 終わりに
プロセスの学問的理解をしたいと考えながら既に数年経ちました。
参考文献に載せたCPUのコアとスレッド、プロセスの関係性の記事がわかりやすかったです。
ハードウェアの勉強とソフトウェアの勉強は交互にすべきですね。

## 参考文献
[multiprocessing の基本](https://ja.pymotw.com/2/multiprocessing/basics.html)(accessed 2022/01/31)
[【図解】CPUのコアとスレッドとプロセスの違い](https://milestone-of-se.nesuke.com/sv-basic/architecture/cpu/)(accessed 2022/01/31)
機械学習を使って束ねたままのケーブルの長さを判別してみた

こんにちは。のぐちです。
アミューズメント系ユーザー企業で社内SEやっています。
今回は現場でよくある困ったことを解決するためのツールを作ってみました。

# 結束されたケーブル類の長さをほどかずに判別することはできるか？

私は1カ月に1-2回ほどモール内の広場等で開催するイベントにスタッフとして参加するのですが、
会場内にLANや電源といったケーブル類を敷設するときに、<b>「ケーブルの長さ分からない問題」</b>が起きます。
各種ケーブルは以下のような状態で現地に運び込まれるのですが、使いまわしている資材になるため、
<b> 長さの仕分け等がされておらず、長さや色もバラバラで雑多に詰め込まれています。</b>
使おうと思って、ほどいてみたら長さが足りずに、別のをほどくエンドレス…のような感じになります。

![DSC_0746_3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471853/3d1f37dd-ee22-9ac7-9612-3cdb5b85c6f9.jpeg)


# 機械学習を用いてケーブルの長さを判断するツールを作ってみた
今回は最近学んだ機械学習を用いて、このケーブルの長さが分からない問題を解決するツールを開発してみました。

## 使ったもの
<b>・Teachable Machine（無料で使える機械学習ツール）
・CodePen（HTML/CSS/JS のコーディングから公開までを一挙に行えるツール） </b>

## できあがったもの

### ・Teachable Machine の学習モデル
Teachable Machine では、下図のようなイメージで、画像データをいくつかの回答のパターンに分けて登録し<b> 機械学習モデルを作ることができます。 </b>
作成した機械学習モデルは、クラウド上に保存され Web サイトやアプリなどからアクセスすることができます。
今回は、様々な長さの LAN ケーブルを束ねたまま撮影したものを、5パターンの長さ別に取り込ませました。
また、画像に映ってはいませんが、E パターンとして何もない画面を登録しています。
![tm_desktop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471853/2e049058-663d-bcec-81e2-0ce7da004efd.png)

### ・CodePenで作ったコード
HTML+CSS+JSのWebページをWeb上のエディタで作成することができるツールです。
今回はHTMLとCSSは簡素ですがJS部分をそこそこ作りこんでいます。
エラーチェック機構あるのでめっちゃ便利です。
JS部分に多数存在する、console.log(XXX);は、CodePen の内部コンソールにログ出す機能なので、主にデバッグ用に記述しているものです。
<p class="codepen" data-height="480" data-default-tab="html,result" data-slug-hash="RwjPZXG" data-user="noguchi_af" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/noguchi_af/pen/RwjPZXG">
  ケーブルの長さ調べるツール</a> by のぐち (<a href="https://codepen.io/noguchi_af">@noguchi_af</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### ・アプリの動作
推論している間に画面が止まっているように見えてしまうため、推論回数を出力して動作が見えるようにしています。<br>
<iframe width="360" height="640" src="https://www.youtube.com/embed/Su_AZulpHnE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## 開発上のポイント

###・利用者が分かりやすい単位に合わせる
イベント会場では大抵長机に沿ってケーブル敷設するので、<b>具体的な長さよりも、
長机(180cm規格)何台分の場所に使えるか</b>といった観点で結果を出力しました。自社開発の利点ですね。
また、スマホで利用することを前提に開発しています。

###・推論を複数回処理させて回答制度を上げる
このプログラムは撮影している画像からケーブルの長さを推論するものなのですが、
<b>撮影時の物体の位置などで結構結果がぶれるため、loopを用いて 1回の処理あたりに10回の推論を行わせました。</b>

###・複数回の推論結果を元に最も確度の高い推論結果を返す
Teachable Machine から返される推論結果として今回5つのパターンを設定したのですが、
今回は<b>10回推論させた上で、最も回答回数が多かったものを結果として出力</b>させるようにしました。
最終的に1つの推論を導き出すといった動作を Java Script 上でどのように記述するか、が今回もっともハマったポイントです。
この辺はもっとスマートな関数とかあるかもしれませんが、割とコンパクトにまとまったので満足です。　

# 完成！したが…。

### ・的中率40%くらい…。
このツール <b>推論の制度がすごく低いです。</b>的中率40%くらいでした。
ケーブルが対象だと、画像としてはほぼ同じようなものになってしまう上、見た目の大きさで判別されてしまうらしく、
<b>カメラからケーブルまでの距離で大きく結果がぶれてしまいました。</b>

### ・今後はUIもかっこよくしたい。
今回は推論結果の正確性を高めることに注力したので、UI はすごくシンプルなものになっています。
もっとボタンとか、タイトルとかかっこよくしたいですね。

### ・やっぱり言語は難しい。
今回、JavaScript 初挑戦となりましたが、やっぱり言語は難しいですね。
ロジックが思いついても、それを実現するためのコーディングの手法は、1つ1つ調べて試してだったので思ったより時間が掛かってしまいました。
<b>ノーコーディングツールのありがたさを再認識した開発となりました。</b>
urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failedの対処法

##問題
PythonでWebスクレイピングをする時に

```python
import urllib.request
response=urllib.request.urlopen('https://yahoo.co.jp') 
```
しようとしたら，

```
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)
```
と出力されてしまった．

##解決方法

```
/Applications/Python\ 3.7/Install\ Certificates.command 
```
とコマンドを叩くと証明書の検証がうまくいった．
【Vue.js】Vue.jsについて

# Vue.jsとは
**Vue.js**とは、UIを構築するための**プログレッシブフレームワーク**のこと。
**プログレッシブフレームワーク**とは、Evan You氏によって提唱された、どのような規模・段階の Web アプリにも対応できるフレームワークの概念のこと。
**Vue.js**を使うことで、開発効率の向上や冗長な記述を減らすことができる。また、他のフレームワークより独自のルールなどが少なく、自由度が高い。

#特徴・メリット
**Vue.js**の特徴やメリットをいくつか挙げておく。

## ディレクティブ
**ディレクティブ**とは、**Vue.js**における独自の属性（```v-○○```）のことで、これを使うことでDOM操作ができる。
これによりDOM操作の記述を減らすことができ、開発スピードが向上する。

## 双方向データバインディング
**双方向データバインディング**とは、JavaScriptのデータとView、双方向のデータを監視して常に同期する機能のこと。
つまり、データの変更があればViewを更新し、Viewの変更があればデータの更新を行う機能。

## コンポーネント
**コンポーネント**は、アプリケーションの様々な機能を役割によって分割したもの。
**コンポーネント**を使ってパーツ化することで、再利用性やデザインの一貫性が高まり、効率よく開発やメンテナンスを行うこともできる。

## 拡張性
**Vue.js**は、シンプルな設計で非常に拡張性の高いフレームワーク。
他のライブラリと組み合わせることができ、段階的に規模を拡大することも可能なため、様々な規模の開発に利用できる。

##SPA（Single Page Application）
**Vue.js**は、**SPA**の開発が行いやすい。
**SPA**は、ページ遷移なしで、単一のページ内でコンテンツが切り替わるアプリケーションのこと。

## 学習コスト
**Vue.js**は、シンプルに設計されているため、他のフレームワークよりも学習コストが低い。
また、フレームワークとして人気が高いため、技術情報が多い。
クロスサイト・リクエスト・フォージェリーの対策-javascript

ワンタイムトークン方式
step1
各ページでAPIを呼び出す直前にワンタイムトークン（乱数Aとする）を生成し、生成した「乱数A」をCookieに格納します。
step2
「乱数A」をハッシュ化（SHA256）します。その結果を「ハッシュB」とします。
setp3
「ハッシュB」はAPIのパラメーターとして、サーバーへ送信します。その際、Cookieに埋め込まれた「乱数A」の値も送信されます。
step4
API側でCookieに格納された「乱数A」とリクエストとして送られてきた「ハッシュB」を取り出して、取り出した「乱数A」をハッシュ化（SHA256）して「ハッシュB」と比較します。値が同じでしたらリクエストを受け付けます。その以外はエラーとして返します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658339/c531f018-ac8c-1267-32bf-1a0159aa79ef.png)
HTML5のhead内の記述

ベースはこれ

```html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>ページタイトル</title>
        <meta name="description" content="ページの説明" />
        <meta name="format-detection" content="telephone=no" />

        <!-- favicon/webclipicon -->
        <link rel="icon" href="favicon.ico" />
        <link rel="icon" href="favicon.svg" type="image/svg+xml">
        <link rel="apple-touch-icon" href="webclip.png" />
        
        <!-- css -->
        <link rel="stylesheet" href="css/style.css" />
        
        <!-- js -->
        <script src="js/main.js" defer></script>
        
    </head>

    <body>...</body>
</html>
```
<br>
このサイトを参考にしました

https://moshashugyo.com/media/html-head
windows batchでのエラーハンドリング

# 概要

Windowsのbatchでは`trap`のようなコマンドや、`set -e`のようなエラーで即終了するような機構がないためエラーハンドリングする場合は`%ERRORLEVEL%`を全コマンド実行後にチェックする必要がある。
しかし、それだとエラーチェックの行が多くなりすぎるため読みづらいコードになってしまう。
その点を改善できる方法を考えてみる。

# 単純にエラーコードを返す

結論から言うと、以下のようにすることでエラーコードを呼び出し側に返すことができる。

```batch
some_command || exit /b !ERRORLEVEL!
```

これはサブルーチンの`call`に対しても使えるため、

```batch
call :sub || exit /b !ERRORLEVEL!
exit /b

:sub
    some_commandA || exit /b !ERRORLEVEL!
    some_commandB || exit /b !ERRORLEVEL!
    some_commandC || exit /b !ERRORLEVEL!
exit /b
```

のように使うことができる。

# エラー表示をする

batchにする以上何度も実行されると思うが、呼び出しをする度にコマンドプロンプトなどで%ERRORLEVEL%を確認するのは不毛なのでエラー表示もbatchにしたい。

```batch
some_command || call :onerror || exit /b !ERRORLEVEL!
exit /b

:onerror
echo エラー発生[%ERRORLEVEL%]
exit /b
```

上記の処理を見るとわかる通り`call`や`echo`では`%ERRORLEVEL%`の書き換えが起こらないのでエラーハンドラを`call`すれば問題なく処理できる。
ちゃんと引数として渡したい場合は`call :onerror "%ERRORLEVEL%"`としてあげれば大丈夫だった。

`:onerror`内での処理の内容によっては`%ERRORLEVEL%`が書き換わる可能性があるため、`:onerror`の先頭で変数に格納するのが安全かもしれない。

# batchファイルとして私が思う完成系

最後に私の思うbatchファイルの完成系テンプレートを置いておくことにする。

```batch
@echo off
@setlocal

call :entrypoint || call :onerror
exit /b

:onerror
echo Error[%ERRORLEVEL%]
exit /b

:entrypoint
    some_commandA || exit /b !ERRORLEVEL!
    some_commandB || exit /b !ERRORLEVEL!
    some_commandC || exit /b !ERRORLEVEL!
exit /b
```
【VRChat】ごろ寝システム入れるときに悩んだから初心者のために残しておく

# 背景
・自分でごろ寝システム入れるときに説明読んでもいまいちわからなかった（読解力（ｒｙ）
・人に教えてもらえる人がいない人向け（）
・初心者のために残しておこかなと思ったので。
ちなみにごろ寝システムってのはこんなやつ。

寝転がったり，写真のような座り方ができちゃうってやつ（わかりやすい写真なかった（））
![VRChat_1920x1080_2022-01-23_23-25-18.164.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/0af2a1d1-9e04-18c7-53d6-6b76a9d75c08.png)

# 環境
・Unity 2019.4.31f1
・UnityHub 3.0.1
・Windows10 Pro 64Bit(21H2)
# 前提
・VRChat Avatars 3.0
・アバターのアップロードの方法がわかっている前提。
・やる気。←これ大事
# 1.導入
とりあえず，ごろ寝システムをダウンロードしてくる。
[ごろ寝システム](https://booth.pm/ja/items/2886739)

# 2.アバターのプロジェクトを開く
プロジェクトを作成して云々は今回は省略します。


起動するとこうなるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/4d423769-1b84-964b-57b6-9a03e2e20398.png)
今回はMAKIEDAさんの水撫月ちゃんを使って解説していきます。（水撫月ちゃんはいいぞ。買おう！）
[水撫月Boothのページ](https://booth.pm/ja/items/3159064)

# 3.ごろ寝システムをUnityに読み込む。
先ほど1でダウンロードしたごろ寝システムのzipを解凍して，このファイルをダブルクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/a14b087f-e46f-4b7e-953f-229d41b97f50.png)
この画面が出たら躊躇なくインポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/7e0fe3d9-c784-132f-abe4-295f2b5b13be.png)
その次に画像の通りに進めて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/02f7ad3d-e61c-23e5-02dc-618cade72255.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/abf54bf0-4f81-3bb6-78fd-b72c933bf22f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/057ec691-8420-79be-1a34-a80892604b60.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/516ec153-1e70-87cb-2588-4b881c67e9b5.png)
こうなれば，よし！（）
# 4.Menuの設定
そして次にExpressionsの設定をしていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/e4c40991-6565-a089-e8b2-92ad3a83f6ea.png)
まずは，Menuから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/3da5bd8c-8802-92c6-89d2-bd31f2cf05ce.png)
からのAdd Control
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/a7249e22-0cf9-3e96-f221-a8a4771fb3bd.png)
このように設定をしていきます。
# 5.Parametersの設定
次にParametersの設定をしていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/fe287013-84ed-98b4-9cd0-a3e7404fc672.png)
のような画面を出し，
Addから次の３つを追加していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/b8ec26fd-f571-c210-b5dc-ecc044f863c1.png)
追加出来たら，全体を見直して，間違いがないか確認したらアップロード！！！
#最後に
たぶんこれでごろ寝システムの導入はできたと思います。
1年位前からVRChatを始めて，VR機器買ったりして楽しんでますが，ごろ寝システム入れたいなぁと思ってて入れてみようとしてつまずいたのがきっかけでこれをノリと勢いで書いてます。
こういうの入れたいなぁって人の役に立つといいなと思います。
（こんな日本語で伝わる気がしませんが。）
# 参考資料
・[ごろ寝システム](https://booth.pm/ja/items/2886739)
・[月夜さん](https://twitter.com/Tsukiyo2000)
導入の際はありがとうございました。
GPUが起動できるかのチェック

# GPU 利用できるかのチェック

## 1. 以下を実行し、Trueが出ているかチェック

```Python3
import torch

print(torch.cuda.is_available())
```

## 2. 以下`False`が出たとき用

# システムのアップデート

```
sudo apt update
sudo apt upgrade
sudo apt dist-upgrade
```

# `CUDA`, `CUDNN`の削除

```
sudo apt --purge remove nvidia-*
sudo apt --purge remove cuda-*
```

# Install CUDA

今回は11.3のインストール例

```
wget https://developer.download.nvidia.com/compute/cuda/11.0.3/local_installers/cuda_11.0.3_450.51.06_linux.run
```

# 再起動
```
reboot
```

# Install できたかチェック

```Python3
import torch
print(torch.cuda.is_available())
```

# 参考

[How to install the NVIDIA driver](https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-20-04-focal-fossa-linux)
PythonでFXチャートを表示してみる


PythonでFXチャートを表示するのをGoogle Colabでやってみます。
https://colab.research.google.com

Google ColabでTA-libを使う方法
https://laid-back-scientist.com/talib

このページではyahoo_finance_api2で株価を取得していますが、アキシオリーのヒストリカルデータをダウンロードしてきます。
https://www.axiory.com/jp/how-to-install/historical-data

```python
import talib
import pandas as pd
import mplfinance as mpf
from google.colab import drive

# Googleの株価を取得
# my_share = share.Share('GOOG')
# ohlcv = my_share.get_historical(
#     share.PERIOD_TYPE_YEAR, 1,
#    share.FREQUENCY_TYPE_DAY, 1)
#df = pd.DataFrame(ohlcv)
# unix時間をtimestampに変換
#df['timestamp'] = #pd.to_datetime(df['timestamp'].astype(int), unit='ms')

drive.mount('/content/drive')

df = pd.read_csv(filepath_or_buffer='drive/My Drive/USDJPY_2021_all.csv',
                 names = ['date','time','open','high','low','close','volume'])
df['timestamp'] = pd.to_datetime(df['date'] +" "+ df['time'], format='%Y.%m.%d %H:%M')
df.drop({'date','time'},axis = 1,inplace = True)

df.set_index("timestamp", inplace=True)
df
```

ヒストリカルデータをWebAPI化して使う方法もやってみました。
https://qiita.com/namikitakeo/items/208ebdcb61e6259dcc44
国当てルーレットクイズをGitHubからwebサーバーを使わずに公開する。

昨年の夏ぐらいにJavaScriptとLeafletの練習用に作っていた国名当てのクイズアプリのソースコードをGitHubで公開してみました。
ソースコードも画像ファイルなんかも全部公開しなくてはいけなくなるので公開OKのフリーの素材を使って作っています。

フリーのデータは（特に海外の世界地図データ）は国境や海岸線等もGISでいろいろいじらなくてはいけなかったのでそのまま使えるってわけじゃないですね。
音はMacのGarageBandで作ったので一応okのはずです。
音を使うとずっとダウンロードしちゃうかもしれませんのでwifi必須でお願いします。。。。

GItHubで公開するのはすごい簡単で
- GitHubのリポジトリの「setting」→「Options」→「Danger Zone」の「Change repository visibility」をpublicに変更するだけでした。
- あとはリポジトリの直下にあるindex.htmlを読みにいけばよいです。
- https://（アカウント名）.github.io/（リポジトリ名）/index.html
- 私のアプリは　
https://0712kazu.github.io/roulette_World/index.html
となります。
- [アプリ](https://0712kazu.github.io/roulette_World/index.html)
非常に簡単でびっくりしました。
VMWare Fusionでguest（windows）からhost（mac）の開発環境（localhost:3000）にアクセス

### 環境

Host: Mac Big Sur 11.5.2
VM: VMWare Fusion 12.1.2
Guest: Windows 10 x64

### やりたいこと

お客さんの環境（Windows）だけで、デザインが崩れたので修正したい
Guest（Windows）からHost（Mac）の開発環境（localhost:3000）にアクセスして直接操作

### 手順

1 VMでWindowsを立ち上げる
2 Macのターミナルでコマンド実行

```
$ ifconfig
```

3 上記から該当するものを探す

```
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=400<CHANNEL_IO>
	ether 3c:22:fb:13:df:4f
	inet6 fe80::1c84:d089:5dae:5860%en0 prefixlen 64 secured scopeid 0x6
	inet 192.168.128.56 netmask 0xffffff00 broadcast 192.168.128.255
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active
```

4 自分のは`192.168.128.56`
5 Windowsでchromeを立ち上げて、`192.168.128.56:3000`にアクセス

動作は遅いけどとりあえずこれで確認できた
踏み台サーバーを経由した多段SSHのconfigの書き方

## 初めに
自分の備忘録として、パスワード認証で踏み台サーバーを経由したSSH接続に少し困ったので書いておきます。

## 自分がはまった部分

以下のようなconfigを書いてSSHコマンドを叩いた所、ssh: Could not resolve hostname ssh: でエラーになりました。

```.ssh/config
# 踏み台サーバー
Host step-server
HostName hoge
User hoge
Port hoge
IdentitiesOnly no
TCPKeepAlive yes

# SSHしたいサーバー
Host target-server
HostName hoge
User hoge
IdentitiesOnly no
TCPKeepAlive yes
ProxyCommand ssh -W %h:%p step-server
```


## 解決策

**OepnSSH 8.0よりも前のversionを使用している場合にconfigに絶対パスを使用しなければいけないらしい。**
(この問題はOpenSSHのバグで、OpenSSH 8.0以降では修正されているようです)
具体的に以下のようにconfigを書いたら動きました。

```.ssh/config
# 踏み台サーバー
Host step-server
HostName hoge
User hoge
Port hoge
IdentitiesOnly no
TCPKeepAlive yes

# 目的のサーバー
Host target-server
HostName hoge
User hoge
IdentitiesOnly no
TCPKeepAlive yes
ProxyCommand C:\Windows\System32\OpenSSh\ssh.exe -W %h:%p step-server # 絶対パスに変更
```

## 参考文献
以下の記事に助けてもらいました。
https://www.suzu6.net/posts/205-ssh-config-proxycommand-windows10/

何か修正した方が良いこと等、なんでもコメント頂けると幸いです。
Rspecで特定のテストだけ実行する

##特定のテストを実行
特定のテストを実行には２つあり、１つは実行したいテストのファイル名と行数を指定する方法。

```ターミナル.
$ rspec spec/models/user_spec.rb:8
```
２つ目はテストコード``it``の前に``f``をつけるだけでそのテストのみ実行される方法。

```task_spec.rb
require 'rails_helper'

RSpec.describe Task, type: :model do  
  describe 'validaton' do
    fit 'タスクを問題なく作成' do. #fitとなっているこのテストだけ実行される。
      task = build(:task)
      expect(task).to be_valid
      expect(task.errors).to be_empty
    end

    it 'タイトル空欄は無効' do
      task = build(:task,title: "")
      expect(task).to be_invalid
      expect(task.errors[:title]).to eq ["can't be blank"]
    end
  end
end
```
ターミナルで入力するよりも、``fit``と入力したほうが簡単なので、これが使えるように設定していく。

##spec_helperを編集

```spec_helper.rb
RSpec.configure do |config|
  config.filter_run_when_matching :focus
　　 #↑コメントアウトされているはずなので解除
end
```
これで、``fdescribe``, ``fcontext``, ``fit`` のように使うことができる。

##参考記事
[RSpecで特定のテストを実行する方法](https://zenn.dev/harasho/articles/execute-only-specific-tests)
Python のログを JSON で出力する

Python で書いたサーバのエラーログを CloudWatch Logs に吐き出していたところ、Traceback の改行文字で分割されていてエラー内容が非常に追いづらいという体験をした。

どうやら CloudWatch Logs は JSON でログを吐けばよしなにパースしてくれるらしく、本番環境のログは JSON で吐き出したほうが良さそうということで、Python のログを Traceback つきで JSON 出力するようにしてみた。

## 初期設定
``` python
from os import getenv
import logging
import json


class JSONFormatter(logging.Formatter):
    """ログを JSON で出力するフォーマッタ"""

    def format(self, record: logging.LogRecord) -> str:
        try:
            data = vars(record)
            exc_info = data.pop("exc_info")
            if exc_info:
                data["traceback"] = self.formatException(exc_info).splitlines()
            return json.dumps(data)
        except:
            return super().format(record)


log_handler = logging.StreamHandler()
if getenv("LOG_FORMAT", "default").lower() == "json":
    log_handler.setFormatter(JSONFormatter())
logging.basicConfig(handlers=[log_handler], level=getenv("LOG_LEVEL", logging.WARNING))
```

- 環境変数で設定を切り替えれるようにしているが、そのへんは好みで
- Traceback を行ごとに区切っている (splitlines) が、これは CloudWatch Logs で見やすくするためで、区切らなくてもいいとは思う
- `json.dumps` が何らかの理由で失敗したときなどにログをロストしないように `super().format(record)` している

## 使い方
``` python
from logging import getLogger

logger = getLogger(__name__)

try:
    1/0  # 例外を発生させる
except:
    logger.exception("Unexpected error occurred")
```

- ルートロガーの設定を変更しているので、 `getLogger` で新しくロガーを作成した場合でも特に何も設定する必要はない
- 例外をキャッチした際に `logger.exception` を使っておけば LogRecord に `exc_info` が含まれるので、特に何もしなくても Traceback がログ出力されるので便利
    - `logger.exception("...")` は `logger.error("...", exc_info=True)` と同じ (たぶん) なので、ログレベルは ERROR になる
- extra に渡した追加データもそのままログに出力される
    - 例： `logger.exception("...", extra={"user_id": "..."})`

## 出力されるエラー
※ 本来は改行されていない1行の JSON 文字列が出力されるが、ここでは見やすくするために整形している

``` json
{
  "name": "__main__",
  "msg": "Unexpected error occurred",
  "args": [],
  "levelname": "ERROR",
  "levelno": 40,
  "pathname": "main.py",
  "filename": "main.py",
  "module": "main",
  "exc_text": null,
  "stack_info": null,
  "lineno": 8,
  "funcName": "<module>",
  "created": 1643609361.1079879,
  "msecs": 107.98788070678711,
  "relativeCreated": 3.8950443267822266,
  "thread": 4410674688,
  "threadName": "MainThread",
  "processName": "MainProcess",
  "process": 17896,
  "traceback": [
    "Traceback (most recent call last):",
    "  File \"main.py\", line 6, in <module>",
    "    1/0",
    "ZeroDivisionError: division by zero"
  ]
}
```

## 参考
- https://docs.python.org/ja/3/library/logging.html
- https://docs.python.org/ja/3/library/traceback.html
- https://github.com/python/cpython/blob/main/Lib/logging/__init__.py
- https://dev.classmethod.jp/articles/lambda-python-log-output-json/
Salesforce DX を使用したアプリケーション開発


# アプリケーション作成の準備

```
sfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch
```
を実行するとエラーが出ます。

 This command requires a dev hub org username set either with a flag or by default in the config.

何かよく分からん。探すとここに回避策がある。ありがたい。

[【Salesforce】デモのE-Bikes Lightning Web Components をローカルに導入できた件Part1【Salesforce DX／Sandbox／DevHub】](https://alis.to/Pura8/articles/KyqWwgqmXqbR)


これを先に実行してから、先ほどのコマンドを入力すると機能した。

```
sfdx force:auth:web:login -d -a DevHub
sfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch
```


# 同じ質問を集めてみました。

+ [ERROR running force:auth:web:login: getaddrinfo ENOTFOUND login.salesforce.com](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000A8kY0SAJ)

Authorize the CLI to work with your DevHub by typing:
次のように入力して、CLIがDevHubと連携することを承認します。
 
```
sfdx force:auth:web:login -h
```
 
This will automatically open your browser and prompt you to log in to the dev hub. Use the credentials that you used to create the Salesforce DX authorized dev hub. Click Allow when the Oauth Flow prompts you to.
これにより、ブラウザが自動的に開き、開発ハブにログインするように求められます。 SalesforceDX認定開発ハブの作成に使用したクレデンシャルを使用します。 Oauthフローからプロンプトが表示されたら、[許可]をクリックします。

Once you’ve gone through this authorization process you can set up an alias using the following command
この承認プロセスを完了すると、次のコマンドを使用してエイリアスを設定できます

``` 
sfdx force:auth:web:login -d -a DevHub
```

You should see something like:
 
```
Successfully authorized <your-username> with org id 00B1I000000L9r3UCY
```

You may now close the browser

Now you should be able to open the dev hub using this

``` 
sfdx force:org:open -u DevHub
```


+ ["This command requires a dev hub org username set either with a flag or by default in the config." error](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FTebmSAD)

It finally works - I think what worked is checking what is set as a default username 
sfdx config:get defaultusername
then setting new alias for that username
sfdx alias:set my-hub-org=<username>
then finally
cci flow run dev_org --org dev

# sfdx force:auth:web:login -d -a DevHub


このコマンドを先に実行するといいみたい。
[ERROR running force:org:create:  Missing message org_create:RequiresDevhubUsernameError  for locale en_US.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Hn32U)
DatabricksでExcel ファイルをDelta Lakeに保存する


# はじめに

Excelで業務を行なっていることって、まだまだ沢山ありますよね。そのような大量のデータをいち早くデータ解析に回すにはということで試してみました。

今回は複数のExcelファイルを一度に読み取って Delta Lakeに保存するまでを試してみます。


# データソース

サンプルデータとして、Blob Storage上に５つのExcelをアップロードしました。
データは、generatorで作成した１００行のデータでカラムは全て一緒ですが、バラバラのカラム名であっても読み取れるようにしております。

こんなデータ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/bf078c22-a7ae-d401-d98a-863d4d6b1930.png)

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

Excelファイルを読み込むために、ライブラリーをインストールしておきます。

```
%pip install openpyxl
```

# Excelファイルの読み込み（１ファイルの場合）

１ファイルだけであればこちらの方法で読み取れます。今回 `storage_path`には blobストレージを指定してますが、今回はその部分は省略してます。

```
import pandas
import io

df = spark.read.format("binaryFile").load(storage_path + "/data01.xlsx")

bstream = io.BytesIO(df.select("content").collect()[0].content)
pdf = pandas.read_excel(bstream)
pdf 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/ce86597e-8084-b18d-4a1c-15d47ef0e101.png)


# 複数のExcelファイル読み込み　＆　Delta Lake保存

それでは、本題である複数のExcelファイルを一気に読み取ってみたいと思います。
またDelta Lakeに保存しておき、その後処理をしやすくしておきます。

```
import io
import pandas as pd 
from pyspark.sql.functions import *

# 保存する　DeltaLake Directory path 
delta_path = '\<保存先のパス>'

# Data load by binary
df1 = spark.read.format("binaryFile").load(storage_path)
  
# binary contents をロードして中身を読み込み、DeltaLakeに書き込む
def excel_to_df(ps):
  for i in range(ps.count()):
    bstream = io.BytesIO(ps.collect()[i].content)
    pdf = pd.read_excel(bstream)
    df = spark.createDataFrame(pdf)
    df.write.mode('append').option("mergeSchema", "true").save(delta_path)

excel_to_df(df1.select('content'))
```

これで、Excelファイルを読み込み、DeltaLakeに保存出来ました。
確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/9a357814-966d-44bc-3c48-c746284c4295.png)

５００行のデータになってますね。


Delta Lakeに保存出来たのであとはデータ分析や、機械学習などで簡単に利用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/a2c79bb4-1103-df84-708a-25b93ae97593.png)
ビッグフィックス登場

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

コードプロジェクトが脆弱性を特定し、修正するのを手伝うと、Tシャツがもらえるほか、他の賞品に応募することができます。多くの人が参加し、貢献しています。

https://snyk.io/events/the-big-fix/
Go導入リンク

# Go導入リンク

新しく案件でGoを使うことになったので使えそうなドキュメントをリンクしていく
随時更新予定

追記予定：
デプロイ周り
Unity連携
gRPC-web

# Goダウンロード・インストール

**公式サイト**

https://go.dev/

**ダウンロード**

https://go.dev/dl/

**確認**

```bash
$ go version
go version go1.17.6 darwin/amd64
```

# エディタ

VSCodeやAtomなどにプラグイン入れる方法もあるが、すぐ始められて多機能なJET BRAINSのGoLandが一番いいと思う（有料だけどその価値はあった

https://www.jetbrains.com/ja-jp/go/

# チュートリアル

## A Tour of Go

初学者は一通りこれを見ればいい、ポインタ、Goroutineだけ理解を深めるため他のサイトも見た。

https://go-tour-jp.appspot.com/welcome/1

### メモ

以下、Go特有だったのでメモ

**Defer**
遅延処理 try-cath-finalyのfinaly的に使う
[https://go-tour-jp.appspot.com/flowcontrol/12](https://go-tour-jp.appspot.com/flowcontrol/12)

**Array**
スライスはデータ格納していない、単に元の配列の部分列を指すだけ
[https://go-tour-jp.appspot.com/moretypes/8](https://go-tour-jp.appspot.com/moretypes/8)

**Pointer receivers**
ポインタレシーバ、変数レシーバーの違い
変数レシーバーはコピーを渡す。
ポイントレシーバーはレシーバー自体を更新する。
レシーバー自身を更新することが多いため、変数レシーバよりもポインタレシーバの方が使うことが多い
[https://go-tour-jp.appspot.com/methods/1](https://go-tour-jp.appspot.com/methods/1)
[https://go-tour-jp.appspot.com/methods/4](https://go-tour-jp.appspot.com/methods/4)

使い所、構造体など
[https://nishinatoshiharu.com/go-structure-pointermethod/](https://nishinatoshiharu.com/go-structure-pointermethod/)

**The empty interface**
型が不明な場合に`var i interface{}` を使うと全ての型を入れることができる。（Any的な）`a := x` と違いはintとかstringとか型が違を入れ替えて使うことができる。
[https://go-tour-jp.appspot.com/methods/14](https://go-tour-jp.appspot.com/methods/14)

**Stringers**
fmt.Println(a, z) でString() を見にいく、これに関しては標準関数を理解していないとわからないので、他に定義済みが無いか確認しないとダメ
[https://go-tour-jp.appspot.com/methods/17](https://go-tour-jp.appspot.com/methods/17)

**Goroutine**
個人サイトの方がわかりやすかった。
GoroutineはGoLangで書くメリットの大きな一つなので下記でポイントを押さえておく
[https://qiita.com/taigamikami/items/fc798cdd6a4eaf9a7d5e](https://qiita.com/taigamikami/items/fc798cdd6a4eaf9a7d5e)
[https://go-tour-jp.appspot.com/concurrency/1](https://go-tour-jp.appspot.com/concurrency/1)

# 標準ライブラリ

チュートリアルやって標準ライブラリ詳しくないとダメだと認識

https://pkg.go.dev/std

# テスト

標準ライブラリにテストがあり使い勝手がGOOD!!
実行はGoLandで走らすことができた

https://pkg.go.dev/testing

https://future-architect.github.io/articles/20200601/

# gRPC

公式サイトのQuick startがわかりやすかった

https://grpc.io/docs/languages/go/quickstart/

**MacOS gRPCインストール**

```bash
$ brew install protobuf
$ protoc --version 
libprotoc 3.19.4
```

**クライアントツール**

毎回Go側でクライアントコードを書くのも大変なのでクライアントツールをインストール
使い方はサイトを参考

```bash
$ brew install --cask bloomrpc
```

https://github.com/bloomrpc/bloomrpc

https://it-blue-collar-dairy.com/grpc_client_tool_bloomrpc/

**Go Plugins**

```bash
$ go get -u google.golang.org/grpc
$ go install -v google.golang.org/protobuf/cmd/protoc-gen-go@latest
$ go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
```

```bash
$ export PATH="$PATH:$(go env GOPATH)/bin"
```

# MongoDB

公式ドライバあり、ドキュメントもわかりやすい。

ダウンロード

```bash
$ go get go.mongodb.org/mongo-driver/mongo
$ go install -v go.mongodb.org/mongo-driver/mongo
$ go install -v go.mongodb.org/mongo-driver/mongo/options
$ go install -v go.mongodb.org/mongo-driver/mongo/readpref
```

https://pkg.go.dev/go.mongodb.org/mongo-driver@v1.8.0/mongo

https://docs.mongodb.com/drivers/go/current/quick-start/

https://docs.mongodb.com/drivers/go/current/
2022年に流行る技術予想〜働き方編〜

2022年に流行る技術予想というテーマのイベントが開催していたので
私は今回ソフトウェアエンジニアの「働き方」について記載したいと思います。

## フルリモートの案件で休日や空いた時間に副業する人が増える
コロナ禍で急速に働き方の変革が進み、なかば強制的にフルリモートに移行した企業も多いですが、
その中で大いにメリットを感じるところもあり移行が進んでいる部分もあると思います。
もちろん出社の良さも中にはありますがエンジニアとしてはIT業界全体がリモート化していく流れにはなってほしいものです。

そして、フルリモートになりライフワークバランスを見直した方も多いのではないでしょうか。
休日や空き時間など少し余裕ができたりしている人もいると思います。
今後は副業も今まで以上にもっと増えてくると思います。

「副業から複業の時代へ」
なんて言葉を耳にする機会も増えましたが、

そして今後は、
複業からさらにその先へ、副業が「副業」としての境目がなくなり「本業」×「本業」となっていくと思われます。
投資で分散化させるのと同じように本業も１つの会社・業務・案件などに依存せず
複数の柱を持つことが主流になるのではないでしょうか。

本来複業は本業への支障をきたさないようにという理由で制限していた会社もあったと思うのですが
エンジニアとしては複数の業務・技術・チームでの働き方を経験するのは、エンジニアとしても人間としても
プラスの要素が大きいです。
個人で勉強するだけでなく仕事として業務で他のシステムやアーキテクチャ、プログラミングに触れるのはとてもプラスです。
そういう意味でも今後複数の仕事をこなすエンジニアは増えると思います。

最近では案件紹介のエージェント自体の数も増えていますし、リモートの案件も増えています、さらにフルリモートに特化したエージェントも増えてきていますね。

## テレワークで地方の活性

直近でいうとLINEやヤフーも働き方の変革として住む場所の地域指定を撤廃しましたね。
これまでは週１や２は出社、または月に数度は出社などハイブリッドな就業形態が多かったかと思いますが
この東京一極化から地方でのエンジニアの活躍も増えていくでしょう。
というより既に増えてきています。

私も九州にUターン移住しましたが今の所不便はあまりありません。
勉強会や研修などもオンラインのミーティングが当たり前になり、ウェビナーも開催されます。
コロナが収まってくればもう少しオフラインのセミナーなども増えるかもしれませんがそれでもオンラインとのハイブリッドな開催は予想されます。
企業としても採用の幅が増えますしより優秀なエンジニアを獲得するとなると東京や関東に絞った採用は徐々に少なくなっていくのではないでしょうか。

地方は不動産も安いですし固定費を下げてPCやガジェットへの投資、生産性向上する環境づくりへの投資はメリットがありますね。

## 課題はリモートでのエンジニアの育成、教育の難しさ

テレワーク・フルリモートでの一番の課題としてはどこの企業も「コミュニケーションのとり方」が１つとして上がるのではないでしょうか。
やったことある人ならば誰もが経験していると思います。
実際エンジニアの重要なインプットとしては物理的に近しい人との普段の雑談やMTGが多いこともあったと思います。

MTG終わりで
「ぶっちゃけさっきの話どう思います？」や
「ここがちょっと分からなかったんでちょっと聞いていいですか？」
というような会話はオンラインではなくなりました。
ある種機械的に進んでいくオンラインミーティングではそこが課題ですよね。

ただ、上記はトライアンドエラーで色々試行錯誤していければ自ずと見えてくることもあるとして、
もう１つは新人や若手のエンジニアの育成の難しさです。

フルリモートが最高！便利！戻りたくない！という方たちはある程度経験を積んで一人でも作業ができる層が多いようにも感じます。

まだ右も左も分からない新人や若手は今後、育つエンジニアと停滞するエンジニアの二極化の時代へなってくるのではないでしょうか。

私自身は技術者として技術に昔から興味があるとかプログラミングが好きというタイプではなかったので
若手の時に尊敬できる先輩エンジニアや上司にお世話になって今があるなと感じます。
人を育てるのは人であるように、エンジニアを育てるのはエンジニアです。

コミュニケーションが別段苦手でもないという方でもビデオ会議のみのやりとりのみではキツイという方もいる中で、コミュニケーションが苦手が方がオンラインのみで成長していくのは課題が大きいと感じます。

2030年には最大で約79万人のIT人材不足に陥るという経済産業省が発表した試算があります。2020年時点でも約30万人の不足がといわれています。
2030年というとちょうど今のフルリモート時代に仕事を始めた世代がちょうど１０年選手くらいになる頃ですよね。
その世代が活躍でき、さらには人材も確保できる業界の裾野の拡大は大切ですね。

心理的安全性への配慮や取り組み、より重要な教育への取り組みは私自身課題でもあります。

様々なセミナーなどで、「テレワークでの我々の働き方への取り組み」などを目にしますが
それは今年2022年もまだまだトライアンドエラーを重ねつつ多く目にしそうです。

https://qiita.com/official-events/5cb794f7cb9ac194ed70
【Rspec】ログイン機能をモジュールで共通化しテストコードをDRYにする

##手順
1.**rails_helper**を編集
2.**support**ディレクトリにてファイルを作成
3.**login**機能の記入
4.メソッド使用例

##1.rails_helperを編集

```rails_helper.rb
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
# 23行目のコメントアウトを外す

---省略---

RSpec.configure do |config|
  # 中略
  config.include LoginSupport
end
```

``('spec', 'support', '**', '*.rb')``
**spec/support/◯◯/△△.rb**のファイルを読み込むという設定。

``RSpec.configure do |config|``下に作成したファイルを読み込むという記述をする。
今回は``LoginSupport``と命名してモジュールを作成する。

##2.supportディレクトリにてファイルを作成
手順１で``support``ディレクトリ下を読み込むという設定をしたので、``support``ディレクトリを作成。

次に、ファイルを作成するが、その際の注意としてファイル名とモジュール名は一致させる必要がある。

```ターミナル.
$ mkdir support
#ディレクトリ作成

$ touch spec/support/login_support.rb
#ファイル作成
```

##3.**login**機能の記入

```spec/support/login_support.rb
module LoginSupport
  def login(user)
    fill_in 'メールアドレス', with: user.email
    fill_in 'パスワード', with: user.password
    click_button 'ログイン'
  end
end
```

##4.メソッド使用例

```user_sessions_spec.rb
require 'rails_helper'

RSpec.describe 'UserSessions', type: :system do
  let(:user) { create(:user) }

  describe 'ログイン' do
    context 'フォームの入力値が正常' do
      it 'ログイン処理が成功する' do
        login(user)
        expect(page).to have_content 'Login successful'
        expect(current_path).to eq root_path
      end
    end
  end
end
```

##参考記事
[【Rails】Rspecでマクロを定義して処理を共通化する方法](https://qiita.com/mattan5271/items/6df9f14e5daa5e0dc1c8)
[Rspecでサインインメソッドを共通化して切り出す(devise使わないとき)[system spec][request spec]](https://qiita.com/tanutanu/items/14b0a1729069b53aa5b8)
CI/CD 継続的〇〇

　最近CI/CDという言葉をよく聞くようになったものの、「何かを自動化するやつだっけ？」と知識が無さすぎたので調べました。

# 目次
- 概要
- メリット

## 概要
　CI/CDは、ソフトウェアの変更を常にテストして自動で本番環境にリリース可能な状態にしておくというソフトウェア開発の手法を指す。

**CI** (Continuous Integration) : 継続的インテグレーション
　CIは主にシステムやアプリケーションの変更を常に自動でテストすることを指す。コーディング後のアプリケーションのビルドや変更テスト、リポジトリへのPushを自動化することで、より正確かつ迅速に開発を進めることが可能になる。

**CD** (Continuous Delivery) : 継続的デリバリー
　CDは主に自動で本番環境にリリースを行うことを指す。インストールパッケージの作成や利用者への配信環境への登録などのリリース工程までを自動化することで、システムやアプリケーションの変更を高速で行うことができる。

cf) 継続的デプロイメント
　リリース後に本番環境への導入（デプロイ）まで自動化することを指す。ビルドやテストが済んだプログラムのリリース、デプロイまでが完全に自動化され、実運用環境のプログラムが継続的に自動更新される。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2091770/b173132d-5514-23ec-d583-c30b62349431.png)

> https://cloudbees.techmatrix.jp/devops/cd/

## メリット
　・ビルド,テスト,デプロイのコスト削減
　・人的ミス減少による品質向上
　・自動化による開発工数の削減

# まとめ
　CI/CDはコーディング後のテストやデプロイの自動化を行うことができる手法だと知り、一貫したシステム開発において便利なんだなと思いました。JenkinsやCircleCIといったCIツールがあるみたいなので実際に開発で使用して利便性を実感してみようと思います。

# 参考
https://cloudbees.techmatrix.jp/devops/cd/

https://e-words.jp/w/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%83%87%E3%83%AA%E3%83%90%E3%83%AA%E3%83%BC.html

https://www.stylez.co.jp/columns/what_is_devops_and_what_is_cicd/

https://www.kagoya.jp/howto/it-glossary/develop/cicd/
react-hook-formを用いて、二つの入力欄にまたがるvalidationを実装する方法

# 概要
　こんにちは！今日はreact-hook-formを用いて、やや複雑なvalidationを実装する方法を説明します。
react-hook-formでは、色々なvalidationが簡単に書けるようになっています。
今回は、二つの入力欄にまたがるvalidationを解説します。具体的には名字と名前に入力された文字列の長さが合計で 20未満になるようなvalidationを実装します。
よく使いそうな簡単なvalidationは、以前他の記事で解説したので参照してみてください！（RequireやmaxLengthなど)

# 具体的な方法
## 1. watchを宣言する。

(例)

```typescript
const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<ValuesType>({
    mode: 'onSubmit',
    reValidateMode: 'onChange',
  })
```

まずはreact-hook-formのimportを忘れずに行ってください。
その後、useFormを使って各変数の宣言をする際に、watchを宣言するようにします。これにより、validationに入力されている値がいつでも参照できるようになります。
ここでValuesTypeには、入力されるデータの型が格納されています。

## 2. validationを記述

（例）

```typescript
<input
              placeholder="姓"
              type="text"
              defaultValue="あ"
              {...register('user.last_name', {
                required: '必須項目です',
                validate: {
                  lessThanTwenty: (value) =>
                    value.length + watch('user.first_name', '').length < 20 ||
                    '漢字氏名を合わせて20文字未満で入力してください',
                },
              })}
            />
```

例のようにregisterの第二引数にvalidationを記述していきます。
今回重要なのはvalidateの中身です。validateの中身を例のように記述することで、漢字氏名合わせて20文字未満でないとエラーが出るようになります。このようにvalidateの内容を記述してあげると自由にvalidationを記述することができます。
また具体的なvalidationの内容を書いた後に```||```を記述し、その後にエラーメッセージを書くことで、どのようなエラーメッセージを表示するかも記述できます！

# まとめ
今日は、やや複雑なvalidationの書き方を解説しました。
validateを用いることで、色々なvalidationがかけるようになるので、是非参考にしてみてください！
Pythonで特定ディレクトリ内の特定文字列を含むファイルを列挙する

表題の通り，pythonで特定ディレクトリ内の任意の深さにあるファイルを列挙するプログラムを書きました．

実行例は以下の通りです．

```shell
# pathはホームディレクトリを起点として考えています．
$ python3 find.py --word "word to search!!!" --path target_directory
```

コードは以下の通りです．

```python:find.py
import os
from argparse import ArgumentParser
from typing import Tuple


def _is_word_in_file(word: str, file: str) -> bool:
    with open(file, 'r') as f:
        for line in f:
            if word in line:
                return True
        else:
            return False


def _get_args() -> Tuple[str, str, str]:
    parser = ArgumentParser()
    parser.add_argument(
        '--path',
        required=True,
        type=str,
        help='The path of interest'
    )
    parser.add_argument(
        '--word',
        required=True,
        type=str,
        help='The word to check whether each file has'
    )
    parser.add_argument(
        '--ext',
        default='.py',
        type=str,
        help='The extension of files to check such as `.tex`, `.py`, `.csv`.\n'
             'You can omit the period and just parse such as `tex`, `py`, `csv` as well'
    )
    try:
        args = parser.parse_args()
    except:
        import sys
        parser.print_help()
        sys.exit()

    path, word, ext = args.path, args.word, args.ext
    if not ext.startswith('.'):
        ext = '.' + ext

    return path, word, ext


if __name__ == '__main__':
    path, word, ext = _get_args()
    path = path if 'home' in path else os.path.join(os.environ['HOME'], path)

    for root, dirs, files in os.walk(path): 
        if len(files) == 0:
            continue

        target_files = [os.path.join(root, fn) for fn in files if fn.endswith(ext)]
        passed_files = [fn for fn in target_files if _is_word_in_file(word, fn)]

        if len(passed_files) > 0:
            print('\n'.join(passed_files))
```
March文系3年次編入生のエンジニア就活



こんにちは！初投稿です。

プログラミングを勉強するにあたって、Qiitaで記録をつけていくことにしました。

自分の経歴は、大学二年生で英語の勉強のみしてきました。（TOEIC　745点）

プログラミングの勉強の初めは、web制作の勉強をしていましたが、エンジニアの方々に相談した結果、サーバーサイドエンジニアを目指そうと方向転換しました。

現在は、ProgateのPHPを学習しているところです。かなり難しい内容ですが、慣れるまで食らいつきます。

これから、同じ境遇の方々や、エンジニアの方たちをみて学習していきたいです。よろしくお願いいたします。
[py2rb] 抽象基底クラス

# はじめに
移植やってます。
( from python 3.7 to ruby 2.7 )
# 抽象基底クラス (Python)
```python
from collections.abc import Sized

print(isinstance([1, 2], Sized))
print(issubclass(list, Sized))
print(isinstance([], Sized))
print(isinstance(set({1, 2}), Sized))
print(isinstance(3, Sized))
print(isinstance('Hello, world!', Sized))
print(isinstance({'id': 1, 'name': 'John'}, Sized))

# output
True
True 
True 
True 
False
True 
True 
```
https://qiita.com/shinsa82/items/4f0b9aa48efc58837548

こちらの記事が分かりやすい。
# defined? (Ruby)
```ruby
require 'set'

def sizeable(obj)
  if obj.is_a?(Integer)
    false
  else
    begin
      obj.size
      true
    rescue => exception
      obj.method_defined? :size, true
    end
  end
end

puts sizeable(3)
puts sizeable([])
puts sizeable([1, 2])
puts sizeable(Set.new([1, 2]))
puts sizeable({'id': 1, 'name': 'John'})
puts sizeable('Hello, world!')
puts sizeable(Array)
puts sizeable(Class)

# output
false
true 
true 
true 
true 
true 
true 
false
```
https://docs.ruby-lang.org/ja/latest/method/Module/i/method_defined=3f.html

`Integer.size`ってバイト数を返すんですね。

花より団子で。
# メモ
+ Python の 抽象基底クラス を学習した
+ 百里を行く者は九十里を半ばとす
TLSの通信

TLS通信
参考サイト
https://www.asobou.co.jp/blog/web/ssl
https://www.digicert.co.jp/welcome/pdf/wp_ssl_negotiation.pdf
https://dev.classmethod.jp/articles/https-encryption/

1.クライアント側（ブラウザ）から接続したいサイトに対して
Client Hello
サーバに対して以下の情報を送る
使用するプロトコルのバージョン
乱数（後で使用する）
セッションID（？）
クライアントが利用できる暗号化方式


2.サーバ側から
a:SSL（サーバ）証明書を送る
b:サーバ証明書に付いている公開鍵を送る
Serverhello
暗号とハッシュ関数のアルゴリズムをクライアントに送る。
アルゴリズムはクライアント側から送られたものからサーバ側が選ぶ
乱数（後で使用する）

3.クライアント側
ブラウザにあるルート証明書で公開鍵が正当なものであっるか確認する

4.クライアント側
公開鍵を使って共通鍵を作成する。
その公開鍵で暗号化した共通鍵をサーバに送る
クライアント乱数
サーバ乱数
プリマスタシークレット乱数


5.サーバ側
秘密鍵でその共通鍵を取り出す
クライアント乱数
サーバ乱数
プリマスタ乱数
これらを解読できるのは秘密鍵しかない。


6.共通鍵で通信を行う。