OmniAICreator/Qiita-1.07M huggingface dataset:
CSSのリファクタリングにあたって、意外と大事な考え方

## この記事の概要

ある箇所のCSSを変更したら、意図しない箇所にまで影響が及んでしまった経験はありませんか？
CSSを書いたことがある人ならほぼ全員が遭遇する事象だと思います。

そんなCSSリファクタリングをするにあたって、あまり話題に出ないけど個人的に大事だと思っている観点を記事にしてみました。

この記事を読みさえすればリファクタリングが上手くいく、というものではありません。
しかし、考慮に入れておくとリファクタリングが頓挫・中止になる可能性が減る気がします。

## スタンス

### 今より良い見た目を作ろうと思わない

おそらく1番大事な点です。
CSSのリファクタリングが話題に上がる時点で、大なり小なり見た目も古めかしくなっているのでしょう。

ここはグッとこらえて「見た目は変えず、コードの作りを良くするだけ」に絞ってください。

「普通に考えて、リファクタリングの中にアップデートを入れるわけないじゃない」と思われる方もいるかもしれません。
しかし、何故か多くの人は「ここの色、もうちょっとこうしたいなあ」なんて触りだしてしまうのです。

どこかの見た目をアップデートしようものなら、いつの間にかUIリニューアルプロジェクトのような空気になってしまいます。
もう一度書きますが、グッとこらえて「見た目は変えず、コードの作りを良くするだけ」に絞ってください。

### 既存のコードを無理に活かそうと思わない

つらく苦しいですが、活かそうと思わないでください。
既存CSSはあくまで参考資料であり、リファクタリングが終わったらすべて捨てる、くらいの気概で丁度良いと思います。

私の経験でいうと、短めの期間で効果の高かったときほど「1から書き直し」に近いやり方をしています。
乱暴な言い方ですが「リファクタリングしたいと思うCSS」ですから、どうにか活かしたとて大したメリットはありません。

### 古めのコードを悪としない

「未だに`float`のレイアウトかー、Gridに置き換えよう」と思うのは否定しませんし、叶うならそちらの方が良いでしょう。
しかし、CSSのリファクタリングで得られる効果のうち、大きいのは「コードを触った箇所だけ見た目が変更される」状態を作ることだと思っています。

そのため、無理をして沼にハマるよりは「思った通りに動く状態を作る」だけに専念し、フェーズ2としてモダンな書き方へ移行する方が良いでしょう。

## テクニック

### 上の階層から触る

CSSとはCascading Style Sheetsの略です。
その名の通りスタイルをカスケーディングしているので、下の階層の要素ほど色々なオーバーライドの結果に成り立っています。
そのため、下の階層の要素を先に直しても、後から上の階層を触ると崩れてしまうかもしれません。

掃除をする場合、埃が上から下に落ちてくるので、高い場所からはじめて段々低い場所へ移っていきます。
似たようなイメージではないでしょうか。

例えば、以下のような構成だとします。

- html
  - head
  - body
    - div（全体のレイアウトを決めるwrapper）
      - header
      - main
      - aside
      - footer

この場合、いきなり`header`や`main`に手をつけず、`html`や`body`にかかっているスタイルに手を入れます。
reset.cssの類を導入している場合、全称セレクタによる`box-sizing`指定や`body`への`font-family`指定があるでしょうか。

歴史が積み重なった結果なのでしょうが、`body`にメインカラーであろう`color`を当てている……とかも見たことがあります。
こういうレイヤーから丁寧に処理します。

なお、お察しの通り上の階層のスタイルをいじるのでときにはページ全体が目も当てられないほど崩れます。
しかしそこで挫けてはいけません。
大きく崩れない要素≒下の階層の要素なので、先ほど記載したように後から上の階層の要素を触ったら結局崩れます。

### ページごとのCSSを書いて、後からモジュールに分割する

モジュールごとに美しく分割できていて、綺麗な作りになっているのが理想です。
同じスタイルを2度も3度も書かない方が効率が良いのは当たり前でしょう。
しかし、リファクタリングの最中にそれを求めると苦戦しがちな気がします。

変な話、現在表示されているページにちゃんとしたスタイルが当たっていれば良いのです。
違うページにも`全く同じスタイルで名前だけが違うクラス`があったとして、顧客からしたら関係ありません。

1つのページに1つのCSSファイルが対応している状態を作った後、共通して登場しているものを切り出す、という進め方の方が早すぎる抽象化も防げる気がします。

### ロジック込みでリファクタリングする

リファクタリングの例としては微妙なのですが、イメージしやすいと思う内容で説明します。

```jsx
<p className="paragraph">何かの説明</p>
<ul className="unordered-list">
  {items.map((item) => (
    <li>{item}</li>
  ))}
</ul>
<p className="paragraph">何かの説明</p>
```

```css
.unordered-list {
  padding: 1em;
}

.paragraph {
  margin-top: 1em;
}
```

`item`が無い場合も`ul`は描画されるので`padding`が適用されてしまい、`p`要素同士がやたら離れてしまいます。

これをCSSだけで改善しようとした結果、何かしらの打ち消し用スタイルが書かれているとしましょう。
どこか別の場所では打ち消して欲しくないため更に上書きして……と苦しい世界が見えるのではないでしょうか。
CSSだけのリファクタリングでこれを解消するのは結構つらい気がします。

というわけで、この場合は以下のように変えます。

```jsx
<p className="paragraph">何かの説明</p>
{items.length > 0 && (
  <ul className="unordered-list">
    {items.map((item) => (
      <li>{item}</li>
    ))}
  </ul>
)}
<p className="paragraph">何かの説明</p>
```

`ul`は`item`があれば描画される、なければ描画されない、とスッキリしました。
これでCSSのリファクタリングに集中できます。

ロジックはアンタッチャブルだと感じてる人もいそうなのですが、手を入れた方が効果的な場面もあります。
周りと相談しながらにはなると思いますが、CSSだけで解決しようとしない方が良いでしょう。

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox
Vue.jsのはじめにつまづいたエラー

触り始めたときにつまづいたことをメモしていきます


# vue/no-unused-components
コンポーネントをインポートしているのに使用してないとエラーになっちゃう。
エラーにまでしなくてもよくない？と思うけど…
例えば以下のコードだとエラーが出る。
```
<template>
  <div>Hello World!</div>
</template>

<script>
  import MyHeader from './components/MyHeader.vue'

  export default {
    components: {
      MyHeader, 
    }
  }
</script>
```

`MyHeader.vue`のコンポーネントをインポートしておいて使用していないので、
`vue/no-unused-components`のエラーになっちゃいます。

# vue/multi-word-component-names

・ファイル名　→　パスカルケース
・HTML内　 →　ケバブケース
・JS内 →　キャメルケース
参考
[【Vue】単一ファイルコンポーネントの命名規則まとめ【ファイル名から記法まで】](https://qiita.com/ngron/items/ab2a17ae483c95a2f15e)

# Can't resolve 'sass-loader'

.vueファイルの中でscssを使うなら、sass-loaderもnpm installする必要があります。
以下でインストールして解消しました。

```
npm install sass-loader -D

npm install node-sass -D

```
【PHP】ビルトインサーバーの使い方

自分用のメモです。

# ビルトインサーバーとは

- PHPでのプログラム開発サポート用に組み込まれているサーバー環境のこと。

- ローカル環境はXAMPPやMAMPなどの環境を用意してPHPを動かしている方も多いと思いますが、PHPの場合、ビルドインサーバーを使うとコマンド１つで手軽にローカルサーバーの立ち上げができるので便利です。
- ただし、ビルトインサーバーはあくまで簡易的な環境のため、データベースなどと連携したい場合は、自前で用意する必要があります。

# ビルトインサーバー立ち上げ〜ブラウザでの表示方法

#### 作業フォルダへ移動

```
$ cd sample_dr
```

#### 立ち上げる

```
$ php -S localhost:8000
```

#### （例）sample.phpファイルを表示させたい場合

```
http://localhost:8000/sample.php にアクセス
```
【GAS】GASからJavascriptへのデータの受け渡し

## はじめに
GASでWebアプリケーションを作る際、例えばスプレッドシートのデータをGASで読み込み、読み込んだデータをJavaScriptで動的に操作したいといったことが発生すると思います。
しかも書いていると途中でどっちの変数か忘れて、GASの変数をそのままJavaScriptに書いてundefinedになったりすることも。
今回はこのあたりを解決する方法を備忘録として書いておきます。


## 変数の場合
１つの変数の場合、スクリプトレットを利用すれば簡単に代入可能です。

```Javascript
<?
var hoge = 1;
var fuga = 'test';
?>
<html>
<head>
<base href="_top">
</head>
<script>
var hoge = <?!=hoge ?>; //GASの変数を代入
var fuga = '<?!=fuga ?>'; //文字列はクォートで囲む
</script>
```

## 配列・連想配列の場合
配列の場合は、一旦JSONにしてから受け渡すと簡単です。
GASのJSON.stringify()でJSON文字列にしたものを、Javascript側でparseします。
```Javascript
<?
var hoge = [1,2,3,4,5];
?>
<html>
<head>
<base href="_top">
</head>
<script>
var hoge = JSON.parse('<?!=JSON.stringify(hoge) ?>');
</script>
```

## おわりに
もしかしたら他のやり方もあるのかもしれないですが、実装するのも簡単なのでおすすめです。
EmacsでCoqを動かすまで（Mac）

# Homebrewのインストール

[Homebrew](https://brew.sh/index_ja)

```bash
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

# Emacsのインストール

[Emacsのインストール](https://emacs-jp.github.io/tips/install-emacs)

```bash
% brew install emacs --cask
```

# opamのインストール

[opamを用いたOCamlプロジェクトのセットアップ方法](https://zenn.dev/hoddy3190/articles/4b7347ecd7ba59)

```bash
% brew install opam　#Homebrewを用いてopamのインストール
% opam init　#opamの初期化
% eval $(opam env)　#環境変数の更新
```

# Coqのインストール

```bash
% opam pin add coq 8.13.0 #Coqをバージチョン指定でインストール
% opam list　#coq 8.13.0 pinned to version 8.13.0の表記があるはず
```

# Emacsの設定

```bash
(require 'package)
;; (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3") ; see remark below
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
```

```bash
M-x package-list-packages
```

上のコマンドを入力して表示されたリストからproof-generalを選択し、インストール

company-coqも同様の手順で入れると便利

coqtop not found的なエラーが出たらinit.elを書き換える

```
(require 'package)
;;(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3") ; see remark below
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(coq-prog-name "/Users/mayu/.opam/default/bin/coqtop") <-----
 '(package-selected-packages '(company-coq proof-general ##)) 
 '(proof-three-window-enable t))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )
(add-hook 'coq-mode-hook #'company-coq-mode)
```

矢印の箇所はcoqtopへのpathを指定、基本[ROOT]/.opam/[Ocaml_VERSION]/bin/coqtopになるはず
Solid.js: Dynamic の使い方 (TypeScript)

次のページを参考にしました。
[制御フロー/Dynamic](https://www.solidjs.com/tutorial/flow_dynamic)

プロジェクトの作成

```bash
npx degit solidjs/templates/ts dynamic01
cd dynamic01
npm i
npm run dev
```

src/App.tsx を改造

```tsx:src/App.tsx
import type { Component } from 'solid-js';
import { render } from 'solid-js/web';
import { createSignal, Switch, Match, For } from "solid-js";

const RedThing = () => <strong style="color: red">Red Thing</strong>;
const GreenThing = () => <strong style="color: green">Green Thing</strong>;
const BlueThing = () => <strong style="color: blue">Blue Thing</strong>;
const YellowThing = () => <strong style="color: yellow">Yellow Thing</strong>;
const CyanThing = () => <strong style="color: cyan">Cyan Thing</strong>;

const options = {
  red: RedThing,
  green: GreenThing,
  blue: BlueThing,
  yellow: YellowThing,
  cyan: CyanThing
}
const App: Component = () => {
const [selected, setSelected] = createSignal("red");
  return (
    <>
      <div>Select Colors</div>
	<blockquote>
      <div>Jun/24/2022</div>
	</blockquote>
<select value={selected()} onInput={e => setSelected(e.currentTarget.value)}>
        <For each={Object.keys(options)}>{
          color => <option value={color}>{color}</option>
        }</For>
      </select>
      &nbsp;&nbsp;&nbsp;
<Dynamic component={options[selected()]} />
    </>
  )

}

export default App
```

ブラウザーで http://localhost:3000/ にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/d9eedd77-1b9c-a43f-3d74-021f548a1f8b.png)
[git]ファイルを指定して変更を戻す



## 実現したいこと

複数の変更をpushしている時、一部のファイルのだけ前のコミットの状況に戻したい。

## 使用コマンド

`git checkout` で実現できた。引数は戻りたいコミットのidと戻したいファイル名。

```
git checkout {commitID} {fileName}
```

## 実際に打ったコマンド

```
git checkout HEAD@{5} app/Http/Controllers/User/UserController.php
```

```
XXXMacBook-Pro:backend XXX$ git add .
XXXMacBook-Pro:backend XXX$ git commit -m"BookingControllerの変更取り消し"
[XXX 14f37267] UserController.phpの変更戻す
 1 file changed, 16 insertions(+), 12 deletions(-)
XXXMacBook-Pro:backend XXX$ git push origin branch
Enumerating objects: 13, done.
Counting objects: 100% (13/13), done.
Delta compression using up to 4 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 756 bytes | 756.00 KiB/s, done.
Total 7 (delta 6), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (6/6), completed with 6 local objects.
To https://XXX.git

```

無事pushまでできました。
DatabricksでDelta形式のテーブルを触ってみた

# はじめに
前記事(URL)ではDatabricksでDeltaテーブルの構築を行いました。
今回は構築したDeltaテーブルを実際に使用していきたいと思います。

以下の流れでDeltaテーブルを触っていきます。
・データの中身の確認
・クエリの実装
・可視化

# データの中身の確認
前回作成したテーブルの中身を実際に見ていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/c8e08e2e-3157-ff79-ca7d-977a7f1e0886.png)

# クエリの実装
クエリを使用して、データの整理を行っていきます。
今回は、時系列に沿って全国の人口の推移を総人口、男女別で抜き出すようなクエリを作成していきます。
実際のコードと実行結果が以下の画像です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/a77b7b80-116f-5f55-b14a-7f5faa38a0a9.png)

欲しい情報だけを抽出することができました。
 
# 可視化
Databricksでは出力されたテーブルの可視化も行えます。
先ほどの画像のテーブルの下にあるグラフのマークをクリックし、Plot Optionsをクリックすることによってグラフをカスタマイズできます。
今回はX軸に年、Y軸に総人口、女性の人口、男性の人口を指定して折れ線グラフを作成してみました。
カスタマイズを終えれば右下のApplyをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/306829bd-43d4-5529-c6bd-65f107516924.png)

最終的に以下のような画像が出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/5b58938e-3e4e-d8f9-7c17-3f1adbfc108e.png)
Plot Optionsを以下のように変更すると異なるグラフにもなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/510b97cb-58dd-a786-562b-942c57e0a371.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/2105882b-8168-9387-1dfa-65d47ad61258.png)


これで時系列に沿った全国の人口の推移を総人口、男女別で可視化することができました。
このようにDatabricksでは作成したDeltaテーブルを使用することができます。
nodenv installが使えない時の対処法

# 前提
今回この現象は，`macOS`でHomebrewを使用してインストールではなく`Oracle Linux 8`で[Github](https://github.com/nodenv/nodenv)からインストールした際に遭遇した場面です．また，Nodenvのインストール手順は先ほど記載したNodenvのGithubに丁寧に書かれているのでそちらを参考にしてください．
※今回の解決方法は他のOSを用いた際にも対応可能かもしれませんが...

# 場面
Terminal上で
```Terminal
$ nodenv install
```
を実行した際に
```Termianl
nodenv: no such command `install'
```
が帰ってきた際です．

# 対処
Githubからインストールした場合`node-buil`が自動的にインストールされないため`nodenv install`が使用できません．そのためTerminal上で...
```Terminal
cd .nodenv
```
```Terminal
mkdir plugins
```
```Terminal
cd plugins
```
```Terminal
git clone https://github.com/nodenv/node-build.git
```
を順番に行うことで`nodenv install`が使用できるようになりました．

# おわり
最後までご覧いただきありがとうございました．
RuntimeError: CUDA error: no kernel image is available for execution on the device

BERTを使用している時にエラーが発生してかなり困ったので、自分用メモも兼ねてまとめようと思います。

最初に記載しておくと、ビギナーがやるようなミスをしています。
ちなみに自分はくっそビギナーです。

どんなエラーかと言うと．．．
**GPUを使う処理でカーネルがないんだけど？？**
（RuntimeError: CUDA error: no kernel image is available for execution on the device）
っていうエラーらしいです。
そんなん知らんがなって感じです。

現状
-

まず、自分の現状の環境についてですが、以下のような感じです。
#### PCの環境等
```
# CUDAのバージョン ---> 11.2
print(os.name)
>> posix  #unix系
!python --version
>> Pyrhon 3.8.5
torch.__version__
>> 1.8.1+cu102
```
#### 各々の環境に合った推奨コマンド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/723408/91bfa912-5a64-7941-f721-f9c981deef2f.png)
もともとのtorchは1.8とかだったような気がするのですが、https://pytorch.org/ を参考に、上の画像のコードを実行してたりしたらぐっちゃぐちゃになってしまいました。
といった感じです。
自分がバカなだけで、大半の人はこのサイト使ったら上手くいくんですかね？

#### GPU使用可否について
また、PyTorchでGPUが使えるかどうかについては、以下の画像のように使えてます。
```
torch.cuda.is_available()
>> True  # Falseなら使えていない
```
なのに、冒頭に記載しているようなエラーがでます。
```
torch.tensor([0.1, 0.2])
>> tensor([0.1000, 0.2000])
torch.tensor([0.1, 0.2]).cuda()
>>> (省略) RuntimeError: CUDA error: no kernel image is available for execution on the device
```
...とまぁこんな感じです（笑）

解決策
-
まさかの凡ミスでした。
[PCの環境等](#pcの環境等)を見て頂くと、torchは1.8.1+cu102になっています。
この時点でおかしいことに早期で気づくべきでした。
[各々の環境に合った推奨コマンド](#各々の環境に合った推奨コマンド)を見て頂くと、インストール文の最後には「cu113」と書いてありますよね。
でも、確かにコピペしてちゃんとインストールしたんですよ（笑）。
と思ってたんですけど、自分があまり仕様を分かっていませんでした。
どうやらアップグレードするには、pip install の後に「-U」が必要らしいです。

```
!pip install -U torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu113

torch.__version__
>> 1.11.0+cu113
```
ということで、ようやくインストールできました。欲しかったバージョンのものが。
ここで、先ほどエラーだったコードを実行してみます。

```
torch.tensor([0.1, 0.2]).cuda()
>> tensor([0.1000, 0.2000], device='cuda:0')
```
なんか実行できました（笑）。
良かった。

結論
-
自分無能
TransferTransactionのスキーマを読み解こうその５

# TransferTransactionBodyについて

```
# Send mosaics and messages between two accounts.
struct TransferTransaction
	TRANSACTION_VERSION = make_const(uint8, 1)
	TRANSACTION_TYPE = make_const(TransactionType, TRANSFER)

	inline Transaction
	inline TransferTransactionBody // 今回はここ
```

## スキーマ

スキーマは以下のようになっています。

```
# Shared content between TransferTransaction and EmbeddedTransferTransaction.
inline struct TransferTransactionBody
	# recipient address　受取人のアドレス
	recipient_address = UnresolvedAddress

	# size of attached message　メッセージのサイズをアタッチする2バイト
	message_size = uint16

	# number of attached mosaics　モザイクの数をアタッチする1バイト
	mosaics_count = uint8

	# reserved padding to align mosaics on 8-byte boundary　
    # モザイクのために空白の1バイトを設定
	transfer_transaction_body_reserved_1 = make_reserved(uint8, 0)

	# reserved padding to align mosaics on 8-byte boundary
　　　　　　　　# モザイクを8バイト境界に整列させるための予約パディング
	transfer_transaction_body_reserved_2 = make_reserved(uint32, 0)

	# attached mosaics
    # 送信するモザイク
	@sort_key(mosaic_id)
	mosaics = array(UnresolvedMosaic, mosaics_count)

	# attached message
　　　　　　　　# 送信するメッセージ
	message = array(uint8, message_size)
```

recipient_address　= UnresolvedAddress
つまり
recipient_address　= binary_fixed(24): 24バイト

https://github.com/symbol/symbol/blob/dev/catbuffer/schemas/symbol/types.cats#L74

message_size = uint16

2バイト

mosaics_count = uint8

1バイト

transfer_transaction_body_reserved_1 = make_reserved(uint8, 0)

1バイト

transfer_transaction_body_reserved_2 = make_reserved(uint32, 0)

4バイト

UnresolvedMosaic

```
# A quantity of a certain mosaic, specified either through a MosaicId or an alias.
struct UnresolvedMosaic
	# Unresolved mosaic identifier.
	mosaic_id = UnresolvedMosaicId

	# Mosaic amount.
	amount = Amount
```

using UnresolvedMosaicId = uint64 
8バイト

https://github.com/symbol/symbol/blob/dev/catbuffer/schemas/symbol/types.cats#L5

using Amount = uint64
8バイト

message = array(uint8, message_size)

メッセージサイズの文字をキャラクターとしてuint8の表現で1文字2バイトで表現する？

![スクリーンショット 2022-06-24 15.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/e3116465-1449-b5c9-3bed-1e0828971392.png)


# まとめ

まとめるとこんな感じかと。

![スクリーンショット 2022-06-24 15.51.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/b5cc31a5-44eb-df5d-3537-635e4c54106c.png)
コメント欄にリストのキーワードがあればフラグ化する(SPSS Modeler データ加工逆引き2-6)

# コメント欄にリストのキーワードがあればフラグ化

![スクリーンショット 2022-06-24 13.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/14898c79-4a0e-c59e-b04c-2154e1a25812.png)

## 1.想定される利用目的

・コールセンターログやアンケートのFA(自由回答)から、特定ワード有無を特徴量として予測に活用する。
・保守記録や設備ログから注目するべき特定ワード有無を特徴量として予測に活用する。

＊この記事では簡易的な方法を紹介します。
動詞や形容詞のような活用の対応や、表記揺れを考慮しする本格的なテキストマイニングをSPSS Modelerで行う場合には以下がお薦めです。

https://smart-analytics.jp/spss/ibm-spss-modeler/datas_for_modeler/

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/blob/main/textflag.str?raw=true

## 3.サンプルストリームの説明

![スクリーンショット 2022-06-28 10.12.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/e61dbb0e-7a16-9813-5105-3ed9ccba4fd8.png)

a.入力するデータの1つ目はコンタクトセンターの入電記録です。
![スクリーンショット 2022-06-24 13.46.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/c9748d55-484f-b5a7-2c70-5e7fcdd96d30.png)

b.２つ目の入力データは注目するべきキーワードのリストです。Excelなどで表記揺れの辞書とともに管理すると便利です。
![スクリーンショット 2022-06-24 13.47.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3889318f-565c-6622-60b8-9895ba0ff786.png)

c.[レコード結合]ノードで条件結合を行います。部分外部結合にして①を主テーブルにします（赤枠）。さらに[結合方法]には[条件]を選択して[重複したフィールド名〜]をチェックします。記述する条件式は以下の通りでです。何文字目にキーワードの文字列が登場するか整数で返す関数で、キーワードを見つけないと0を返すルールを利用しています。
![スクリーンショット 2022-06-28 10.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5dd2286f-4579-f595-587d-5abb361a5a8b.png)

[プレビュー]します。ID番号2のレコードにはキーワードが含まれないので欠損値Nullになっています。
![スクリーンショット 2022-06-28 10.16.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/b7df2775-4fd5-305d-423c-3946e36855d9.png)

d.[フラグ設定]ノードを編集します。
![スクリーンショット 2022-06-28 10.24.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f0385aa8-45a9-ab0c-50b1-c0d4d3589746.png)

[テーブル]を実行します。
![スクリーンショット 2022-06-28 10.25.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5f5dd1fc-fdef-62e5-a86d-aa32606f1b86.png)

#### 注意事項
キーワードが250を超えるときはストリームのプロパティの制限を変更してください。
今回は②で[値の読み込み]をしていますが、ご自分で作成されるときには入力時が[データ型]ノードで[値の読み込み]をしないと[フラグ設定]のメンバーにキーワードがリストされないので注意してください。

https://qiita.com/416nishimaki/items/bcaec1cd8e455c3f68a9#%E3%83%95%E3%83%A9%E3%82%B0%E5%8C%96%E3%81%99%E3%82%8B%E3%81%B9%E3%81%8D%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84

## 4.参考情報

#### 拡張ノードでPythonのライブラリを呼び出してテキスト処理する

https://www.ibm.com/blogs/solutions/jp-ja/spssmodeler-push-node-22/

#### キーワードの有無で類似文章を検索する

https://www.ibm.com/blogs/solutions/jp-ja/modeler-tips-16/

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
Solid.js: SVG の使い方 (TypeScript)

次のページを参考にしました。
[導入/JSX](https://www.solidjs.com/tutorial/introduction_jsx)

プロジェクトの作成

```bash
npx degit solidjs/templates/ts svg01
cd svg01
npm i
npm run dev
```

src/App.tsx を改造

```tsx:src/App.tsx
import type { Component } from 'solid-js';
import { render } from 'solid-js/web';

const App: Component = () => {
  return (
    <>
      <div>Five Circles</div>
	<blockquote>
      <div>Jun/24/2022</div>
	</blockquote>
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <circle cx="30" cy="20" r="10" stroke="cyan" fill="none"/>
  <circle cx="50" cy="20" r="10" stroke="black" fill="none"/>
  <circle cx="70" cy="20" r="10" stroke="red" fill="none"/>
  <circle cx="40" cy="37.32" r="10" stroke="yellow" fill="none"/>
  <circle cx="60" cy="37.32" r="10" stroke="green" fill="none"/>
</svg>
    </>
  )

}

export default App
```

ブラウザーで http://localhost:3000/ にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a46b2b3f-6825-a6f6-5d1a-9493ea643e42.png)
【SwiftUI】The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressionsを解決

# はじめに
私はSwiftUIに慣れるまでこのエラーを出しまくりました。
しかし、よくエラーの意味がわかりませんでした笑

最近になって解決方法がわかったので記録しておきます。


# エラー文
![Xni95.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/7ab868ae-29ce-9e70-8483-f5984366d331.png)
```
The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
```
「コンパイラは、この式を合理的な時間で型チェックすることができません。この式を個別の部分式に分割してみてください。」ということらしいです

# 原因
「Viewの中にエラーがあるがコードが多すぎでどこがエラーかわからない」

おそらくこんな感じではないかと思っています。


# 解決方法
**Viewの中の要素を一つずつコメントアウトして原因箇所を探す**

コードが少なくなるときちんとエラーが表示されるようになります。

# おわり
おそらく、このエラーが出る方はクソでかViewを作っちゃっているので、
Viewは小さく分割して作るのがいいと思います。
vimeoでendedイベントを取れないとき

vimeoを利用し、同一のiframe内で動画を連続再生したいという要望。
ところが、playerのendedイベントがなぜか1つめの再生のものしか取れない。
そのような状態でもgetEndedメソッドは使えたので、力業。
```javascript
setInterval(function () {
	player.getEnded().then(function (ended) {
		if (ended) {
			// ここで必要な処理
		}
	});
}, 100);
```
もっといいやり方はないかな？
POSTMANで作成したリクエストをスクリプトに変換

例は Twitter API で curl に変換、windows10で使用

適当な request を開いて Code snippet を開く
リストからcurlを選択

設定 → Line continuation character → 
　windows poerhesll（`）バッククォート
　コマンドプロンプト（^）
設定 → Quote Type → double

ちなみに Windows PoerShell だと動かない
参考：https://devadjust.exblog.jp/22690878/
 → "原因はエイリアス"の部分

PowerShell内では、Invoke-WebRequest という別コマンドが呼び出されていて、cURLと互換性がなく、一部パラメーターがエラーになるらしい。

記事に書いてあるけど、拡張子を指定するか、別名を解除する。
```
@rem OK
curl.exe --location --request -GET https://api.github.com/zen
@rem NG
curl --location --request -GET https://api.github.com/zen
```

![スクリーンショット 2022-06-24 143734.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713217/5daa4702-2027-a91c-18de-662cb22a0162.png)

便利..!!!
【EC-CUBE 4.0】 無効化したプラグインでもservices.yamlをロードしてしまう問題

# 解説

例えばこんなプラグイン。

``` yaml:services.yaml
services:
    Plugin\MyPlugin\Service\PurchaseFlow\Processor\DeliveryFeePreprocessor:
        decorates: Eccube\Service\PurchaseFlow\Processor\DeliveryFeePreprocessor
```

``` php
// 前略
class DeliveryFeePreprocessor implements ItemHolderPreprocessor
{
    // 中略
    public function process(ItemHolderInterface $itemHolder, PurchaseContext $context)
    {
        /** @var Order $Order */
        $Order = $itemHolder;
        $myValue = $Order->getMyPluginValue();
        // 後略
```

送料計算サービスを置き換えて、独自の計算を行なうような想定。有効化して使っている分には問題ない。

無効化するとEntityの拡張は解除されるが、プラグインのservices.yamlは引き続き読み込まれる。

それでこんなエラーが発生するようになる。

> Attempted to call an undefined method named "getMyPluginValue" of class "Eccube\Entity\Order".


https://github.com/EC-CUBE/ec-cube/issues/3936

# 解決

仕組みを考慮すると、無効化したプラグインのservices.yamlを読み込んでしまうのは仕方がないこと。

プラグインの有効化/無効化時にservices.yamlをコピー/削除することで対応しよう。

``` PluginManager.php
class PluginManager extends AbstractPluginManager
{
    public function enable(array $meta, ContainerInterface $container)
    {
        $this->copyServiceConfig();
    }

    public function update(array $meta, ContainerInterface $container)
    {
        $this->copyServiceConfig();
    }

    public function disable(array $meta, ContainerInterface $container)
    {
        $this->deleteServiceConfig();
    }

    private function copyServiceConfig(): void
    {
        $fs = new Filesystem();
        $fs->copy(__DIR__ . '/Resource/services.dist.yaml', __DIR__ . '/Resource/config/services.yaml', true);
    }

    private function deleteServiceConfig(): void
    {
        $fs = new Filesystem();
        $fs->remove(__DIR__ . '/Resource/config/services.yaml');
    }
```
クローン作成やらなんやら

## クローンを作成したけれど・・・
さて、昨日の続きでGitHubからのクローン作成を行いました。
コードは`$ git clone https://github.com/[ユーザー名]/[プロジェクト名].git`
これでうまくいった〜〜〜！！！
と思ってファイルを確認・・・
中身がなーーーーーい！
GitHubのデフォルトブランチ変更手順

対処法｜デフォルトブランチの変更
デフォルトブランチの設定は「Settings」タブの「Branches」で行います。 
[![Image from Gyazo](https://i.gyazo.com/66d5737fdd7a1fc7911508b54653beb6.png)](https://gyazo.com/66d5737fdd7a1fc7911508b54653beb6)
ここの中に写っている「Settings」をクリックし、次に「Branches」をクリック。
[![Image from Gyazo](https://i.gyazo.com/c5223ed9733831463a24c568db5091b6.png)](https://gyazo.com/c5223ed9733831463a24c568db5091b6)
赤色の警告が出ますけど、そのボタンを押す。
[![Image from Gyazo](https://i.gyazo.com/ff063d2709f5a3937f3daa2e68b961e8.png)](https://gyazo.com/ff063d2709f5a3937f3daa2e68b961e8)
英語だらけで分かりにくいですが、これを実行すれば完了します。
pushの時に使ったコードが最後masterを使用したので、デフォルトになっていなかったことが原因。

GitHubに行きデフォルトリポジトリを変更し、もう一度挑戦！！！！
完了しました。

## さて、昨日の続きをしよう・・・
続きをするべく、エディターでプロジェクトフォルダを開き、コマンドラインで`$ php artisan serve`をすると
`Fatal error: Uncaught Error: Failed opening required '/Users/saito8118/Desktop/simplenote/vendor/autoload.php'`autoload.phpがないと怒られました。
早速ググりまして、`$ composer update`を実行！

その後また500番のSERVER_ERRORが表示
.envファイルがなかったため自分の環境に合わせて設定。

>[参考記事](https://qiita.com/waonn/items/43298d66f7cc59c64a2d)

`$ php artisan key:generate`も実行！
ここまでやってやっと立ち上がりました。
結構苦労するんだなぁと実感しましたね！
こんな感じでも日々成長しています。
【Unity】開発中いつでもカメラのスクリーンショットを撮る

Cameraコンポーネントを拡張して非実行時でもゲームビューのスクリーンショットを撮れるようにします。
もちろん実行時でも撮れます。

# Cameraコンポーネントから保存
後述するコードを追加すると"Export and Save"ボタンが表示されます。
"Export and Save"ボタンを押すことで指定した場所にpng画像が保存されます。
![スクリーンショット 2022-06-24 143405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515818/7322ef91-7b1c-7600-efb1-30ef15b77e8a.png)


### エクスポート結果例
ゲームビューが指定したパスにpng画像で保存されます。
![ss_20220624141754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515818/f69c6b09-4633-c38c-172d-c042a5083135.png)






# コード
以下のコードをを**Editorフォルダ**に保存してください。
```csharp
using System;
using UnityEngine;
using UnityEditor;
using System.IO;

[CustomEditor(typeof(Camera))]
public class CameraScreenshot : Editor
{
    string exportFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) + "\\Unity_Screenshots";
    public override void OnInspectorGUI()
    {
        EditorGUILayout.BeginVertical(GUI.skin.box);
        {
            GUILayout.Label("Screenshot");
            exportFolderPath = EditorGUILayout.TextField("Folder Path",exportFolderPath);
            if (GUILayout.Button("Export and Save"))
            {
                if (!Directory.Exists(exportFolderPath))  Directory.CreateDirectory(exportFolderPath);
                string exportPath = $"{exportFolderPath}/ss_{DateTime.Now:yyyyMMddHHmmss}.png";
                ScreenCapture.CaptureScreenshot(exportPath);
                File.Exists(exportPath);
                Debug.Log("Exported the screenshot.");
            }
        }
        EditorGUILayout.EndVertical();
         base.OnInspectorGUI();
    }
}
```

必ず**Editorフォルダ**にコードを置いてください。

初期保存フォルダパスを変更する場合はexportFolderPath、ファイル名を変更する場合は、exportPathの"ss_"以降を変更してください。

# シーンビューの位置のスクショが欲しい場合
ゲームビューの位置ではなく、シーンビューの位置でスクリーンショットが欲しい場合は、
カメラオブジェクトを選択した状態で`Ctrl + Shft + F`を押すとシーンビューの位置にカメラが合いますので、その状態で"Export and Save"を押してください。
PowerShellでリストのIPアドレスに対して繰り返し到達性を確認する

### Whileを使かって繰り返しIPアドレスリストへのIP到達性を確認する

IP到達性を確認したいIPアドレスのリストを作成し、そのリストに対して繰り返しTest-Connectionを使ったICMPのチェックを実施します。

### ユースケースのポイント
+ **foreach**を使ってリストからIPアドレスを読み込み変数に代入する
+ 上記のforeachを使ったリストの1巡を、**while**を使って管理する
※Pingを実施する全回数、もしくは「成功」「失敗」の回数で実行回数を管理する

以下、環境です。
**Windows 10 Enterprise**
**PowerShell 5.1**　

※デフォルトの環境で使えることを意識しているので**PowerShell 7**を使っていません。

``` ipAddrList.txt
172.22.1.201
172.22.1.170
172.22.1.81
172.22.1.26
172.22.1.25
172.22.0.1
172.22.0.2
```
+ IP到達性を確認したいIPアドレスリスト

``` icmpTesp.ps1
$ipAddrs = (Get-Content ./ipAddrList.txt)

$i = 0
while ($i -lt 2){
    foreach ($line in $ipAddrs) {
        $result = Test-Connection $line -Count 1 -Quiet
        if ($result -eq "True") {
            Write-Host $line "Reachable!"
            #$i++
        } else {
            Write-Host $line "Warning : Unreachable!"
            $i++
        }
    }
}
```
+ 2回「失敗」するとスクリプトが終了します。

``` Result
PS C:\Users\MashCannu> .\icmpTest.ps1
172.22.1.201 Reachable!
172.22.1.170 Reachable!
172.22.1.81 Reachable!
172.22.1.26 Reachable!
172.22.1.25 Reachable!
172.22.0.1 Reachable!
172.22.0.2 Warning : Unreachable!
172.22.1.201 Reachable!
172.22.1.170 Reachable!
172.22.1.81 Reachable!
172.22.1.26 Reachable!
172.22.1.25 Reachable!
172.22.0.1 Reachable!
172.22.0.2 Warning : Unreachable!
```

### コード解説

``` line1.ps1
$ipAddrs = (Get-Content ./ipAddrList.txt)
```
+ $ipAddrListを読み込み変数ipAddrsに代入する

``` line2.ps1
    foreach ($line in $ipAddrs) {
        $result = Test-Connection $line -Count 1 -Quiet
        if ($result -eq "True") {
            Write-Host $line "Reachable!"
            #$i++
        } else {
            Write-Host $line "Warning : Unreachable!"
            $i++
```
+ **$ipAddrs**から1行づつIPアドレスを読み込み変数 **$line**に代入
+ **Test-Connection**で対象のIPアドレス **$line** に対して1回pingを実施し結果をBoolen値 True/Falseで返す
+ Falseの場合（else{}ブロック）は$i++ を付け、1つずつ増やして終了する回数をカウントする

``` line3.ps1
$i = 0
while ($i -lt 2){

}
```
+ $i = 0　初期値をゼロで設定
+ ($i -lt 2) で -lt (less than) 2回以下と条件設定
+ **Foreach**ブロック内で、$i++で１つづ増やして回数をカウントしている
2分で分かるAWS CDK入門～AWS CDKとは?～

# Infrastructure as Codeとは?
* 繰り返し設定する項目を手動で実施すると下記のような問題点があります。
![CDK入門2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/5b3bd776-f587-6907-a87b-8172201f8ef4.png)

* インフラをコードで定義することで下記のようなメリットが生まれます。
![CDK入門3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/51cb8244-b350-9124-ce13-234ac3e48e22.png)

# CloudFormation(CFn)とは?
* Yamlでテンプレートを書くとStackが作成され、VPCやEC2などのAWSリソースが作成されます。
![CDK入門4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/d9ad29bd-6510-6347-536d-a5010d9cfddb.png)

* 下記のようなVPCにサブネットを4つ作る構成を考えてみます。
![CDK入門5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/c98d97b1-46c6-5a12-427a-33e3d50e3a64.png)

* CFnで書くと結構なコード量となります。
![CDK入門6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/64f164e2-b3ae-e9f3-64b2-5d4161a25a42.png)

* CFnは細かい設定を定義する必要があるため、コードが長くなります。
![CDK入門7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/0abca283-a859-098d-65c8-9ab88f4b8602.png)

# AWS CDKとは?
* CDKはプログラム言語でリソースが定義出来てコード量も少なくなります。
![CDK入門8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/6a5f0dc5-907b-98ef-bb06-43792a05a9a3.png)

* CDKで書いたコードからCFnのテンプレートが作成された後、AWSリソースが作成されます。
![CDK入門9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/bf17eb33-068a-0014-adc0-2c3f4d5beb7e.png)

* 上記VPCとサブネットの作成コードです。CFnと比べて随分コード量が減ります。
![CDK入門10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/d6248d46-0615-2b1a-1068-c7a492eb3d72.png)

# まとめ
* CDKは慣れればCFnより断然運用効率が上がると思います。
![CDK入門11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/95b76f0c-8d3e-c973-5230-7187ff11a602.png)
Solid.js: コンパイルなしでの使い方

こちらを参考にしました。
[# コンパイルなし？](https://www.solidjs.com/guides/getting-started#%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%AA%E3%81%97%EF%BC%9F)

フォルダー構造

```text
$ tree
.
├── index.html
└── index.js
```

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Solid.js Test</title>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8">
</head>
<body>
<div id="root"></div>
<script type="module" src="index.js"></script>
<hr />
Jun/24/2022<br />
</body>
</html>
```

```js:index.js
// ---------------------------------------------------------------
//	index.js
//
//						Jun/24/2022
// ---------------------------------------------------------------
import { createSignal, onCleanup, } from "https://cdn.skypack.dev/solid-js";
import { render } from "https://cdn.skypack.dev/solid-js/web";
import html from "https://cdn.skypack.dev/solid-js/html";

// ---------------------------------------------------------------
const App = () => {
        const [count, setCount] = createSignal(0),
          timer = setInterval(() => setCount(count() + 1), 1000);
        onCleanup(() => clearInterval(timer));
        return html`<div>${count}</div>`;
      };

render (App,document.getElementById('root'));
// ---------------------------------------------------------------
```

サーバーの起動

```bash
http-server
```

クライアントで　http://localhost:8080/　にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6b92434d-aa6f-6e05-e976-4574514108d5.png)
これでXSLT3.0に入門できる！簡単にHello Worldする方法を編み出した

XSLTは1999年に仕様が公開され、現在は3.0までバージョンが進んでいます。
にも関わらず長年XSLTでHello Worldをするいい方がありませんでした。
もちろん「xslt hello world」で検索すればいくらでもやり方は出てきます。

しかし、みんなこう思うはずです。

「これじゃない」

普通の人が考えるHello Worldというのは、コマンド一発でコンソールに「Hello World」と出てくるものです。
そうなっていない原因は、XSLTは基本的にXSLにXMLを入力し、何らかのテキストファイルに出力する仕様になっているためです。

じゃあ無理なのか…と思いきや、できます。みんなが

「これだ！」

となる方法を編み出しましたのでご紹介します。

# 環境
なお今回のやりかたはWindows上で行う方法なので、それ以外は考慮していません。

またJava実行環境が必要です。

# コマンド
具体的なコードはGoogleドライブに置いています。
https://drive.google.com/drive/folders/1-JhO33H5BJGvZ895fA4hmfEgYL8cFJvN?usp=sharing

これをZIPでダウンロードし、解凍します。あるいはパソコンからドライブにアクセスします。

そして、コマンドプロンプトでファイル群の入ったディレクトリに移動し、次をコマンドします。
```.\xslt.bat helloworld.xsl```
すると次が出力されます。
```hello world.```

または
```.\call.bat hellowolrd.xsl```
とコマンドしても同じ結果が出てきます。

どうなっているのか？少しずつ見ていきましょう。

# コード
まずバッチファイルはこうなっています。

```bat:xslt.bat
@echo off
if not [%2%]==[] (
set param="%2=%3"
)
java -jar saxon-he-10.8.jar -s:%1 -xsl:%1 -o:out/out.txt %param%
```

Javaでsaxon-he-10.8.jarを実行していることが分かります。
引数は-sが入力ソース、-xslがXSLTのXSLファイルです。-oでout/out.txtに出力しています。

```bat:call.bat
@echo on
if not [%2%]==[] (
set param="%2=%3"
)
java -jar saxon-he-10.8.jar -it -xsl:%1 %param%
```
こちらは-itフラグを付けていますね。

次にXSLを見てみましょう。

```xml
<?xml version="1.0"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0">
  <xsl:output method="text"/>
  <xsl:template match="/" name="xsl:initial-template">
  	<xsl:message>hello world.</xsl:message>
  </xsl:template>
</xsl:stylesheet>
```

ポイントとなるのが
```<xsl:message>hello world.</xsl:message>```
という箇所です。ここでコマンドプロンプトに出力しています。

xslt.batのやり方で重要なのは-sと-xslに同じXSLを指定していることです。
XSLはXMLであることを利用し、XSLに自分自身を処理対象とさせることにあります。
私も色々やってきて感じたのですが、入力元となるXMLを用意するのがかなり面倒でした。
しかし、自分自身なら手間はかかりません。

call.batではただ単に名前付きテンプレートを呼び出しています。入力もout.txtの出力も抑えられています。
とても簡明ですね。

他にもいろいろ置いていますが、XMLを処理することを念頭にしたXSLを置いていて、基本となる考え方は「自分自身を処理させる」です。
ここからXSLT3.0ライフを満喫しましょう！
RubyのCSV出力でUTF8→S-JISに変換する時の文字化け対応

UTF8で保存した🐡や、旧漢字といったものをSJISに変換して、そのまま出そうとエラーがでる。
そのため以下のように書けば、SJISに変換する時、文字化け対象は「？」で書きだすことでエラーが出ない。

```
text = utf8_dummy_data
CSV.open("hoge.csv", "w", encoding: "SJIS") do |csv|
  csv << [text.encode(Encoding::Windows_31J, Encoding::UTF_8, invalid: :replace, undef: :replace)]
end
```

簡単なことなんだけど、検証とか調査に時間がかかったので記録しておきます。

よかったらいいね！👍
いただけると嬉しいです✌('ω'✌ )三✌('ω')✌三( ✌'ω')✌
応用情報技術者試験 試験対策

## 概要

幅広い知識を要求される試験。

基礎情報技術者試験とは異なり対策本も限られてくる。本気で高得点を狙うなら、データベーススペシャリストやらネットワークスペシャリストやらの高度区分試験の過去問対策が必要そう。

有限の時間で合格に必要な知識を得るには、「ある程度」コンパクトにまとまった本で勉強を進めるべき。

基本情報技術者試験にそれなりの成績で合格している人なら、問題集ベースよりも参考書で知識を膨らませていく方が効率よい気がする。

午後試験は選択科目のチョイスが一番大事。個人的には問 2, 3, 4, 7 がお勧め。

## 参考書

#### (全文PDF・単語帳アプリ付)徹底攻略 応用情報技術者教科書 令和4年度

分かりやすくまとまっていて、概観を掴むのにはちょうど良い。

https://www.amazon.co.jp/dp/4295012912/


#### キタミ式イラストIT塾 応用情報技術者 令和04年

分量に圧倒されるけど、イラストが多くて分かりやすい。

https://www.amazon.co.jp/dp/B09MYHHJ9P/

## 問題集

#### 2022　応用情報技術者　午後問題の重点対策

情報セキュリティ（必須科目）と自分で選んだ選択科目だけ、やればよい。

https://www.amazon.co.jp/dp/B09LYWP98M/
Node.jsのバージョン切り替え（nodebrew）


Node.jsのバージョン切り替えに関するメモ

<h2>Node.js管理ツール</h2>
・nodebrew


その他の管理ツール一覧はheppokofrontendさんの記事が参考になります。
[Node.jsのバージョン管理ツールを改めて選定する【2021年】](https://qiita.com/heppokofrontend/items/5c4cc738c5239f4afe02)

<h4>現在利用中のNodeのバージョンを確認する</h4>

```
$ node -v
v16.14.0
```

<h4>ダウンロード可能なNodeのバージョンを確認する</h4>

```
$nodebrew ls-remote
v0.0.1    v0.0.2    v0.0.3    v0.0.4    v0.0.5    v0.0.6    

v0.1.0    v0.1.1    v0.1.2    v0.1.3    v0.1.4    v0.1.5    v0.1.6    v0.1.7
v0.1.8    v0.1.9    v0.1.10   v0.1.11   v0.1.12   v0.1.13   v0.1.14   v0.1.15
v0.1.16   v0.1.17   v0.1.18   v0.1.19   v0.1.20   v0.1.21   v0.1.22   v0.1.23
v0.1.24   v0.1.25   v0.1.26   v0.1.27   v0.1.28   v0.1.29   v0.1.30   v0.1.31
v0.1.32   v0.1.33   v0.1.90   v0.1.91   v0.1.92   v0.1.93   v0.1.94   v0.1.95
v0.1.96   v0.1.97   v0.1.98   v0.1.99   v0.1.100  v0.1.101  v0.1.102  v0.1.103
v0.1.104  
（以下略）
```

<h4>Nodeのバージョンをダウンロードする</h4>

```
$ nodebrew install v8.9.4 👈バージョンを指定

最新の安定版をインストールする場合は以下
$ nodebrew install-binary stable
```


<h4>ダウンロード済みのNodeのバージョンを確認する</h4>

```
$ nodebrew list
v8.9.4
v10.15.0
v12.16.3
v12.18.3
v16.2.0
v16.14.0

current: v16.14.0　　👈現在利用中のバージョン
```

<h4>利用するNodeのバージョンを切り替える</h4>

```
$ nodebrew use v8.9.4 👈 使うバージョンを指定
$ node -v
v8.9.4
```
Spigotにおいて看板を用いてプレイヤーからの入力を取得する

## 最初に
看板でプレイヤーからの入力を取得する方法を雑に書きます。

## ステップ1
今回はプレイヤーの座標に看板を設置して入力を取得していきます
```
Location loc = player.getLocation();
Block block = loc.getBlock();
block.setType(Material.OAK_SIGN);

BlockState signState = block.getState();
Sign sign = (Sign) signState;
sign.update();
player.openSign(sign)
```
おわりです。......


嘘です。少し解説します。
## 解説
1行目：
プレイヤーの座標（Location型）を取得

2行目：
`Location loc = player.getLocation();`で取得した座標のブロックを取得

3行目：
`Block block = loc.getBlock();`で取得したブロックをオークの看板に置き換える

4行目：
`Block block = loc.getBlock();`で取得したブロックの内部情報を取得

5行目：
`BlockState signState = block.getState();`で取得した内部情報をSign型にキャスト（変換）

6行目：
情報のアップデート（多分いらない）

7行目：
プレイヤーに看板の編集画面を表示する。
といった流れになります。

ちなみにこれだけでは看板の編集画面を表示するだけで終わってしまうので
```
public void onSignCange(SignChangeEvent event){
    String signString = event.getLine(0);
```
などを利用してプレイヤーが看板を編集したイベントが発火されたら看板の情報を取得するように書くと表題のように看板を用いてプレイヤーからの入力を取得することができます。

なお、このように書くと普通に看板を設置して編集した際にも同じ処理が適用されてしまうのでタグ付け/読み取りなどを利用して場合分けできるようにするとよいと思います。
___
今回はテストとしてプレイヤーの座標を使用しましたが、実装する際はプレイヤーから離れた座標を指定するとよいでしょう。（壊される心配とかがないところ）
また編集を完了する前にプレイヤーが書き込んでいる看板を破壊すると、編集画面は消えませんがSignChangeEventが発火されず入力された情報を取得することができません。
なので、看板の画面を表示する流れの中で設置されている看板を上書きすることがないようにブロックの種類を判定するコードを書いておくなどしましょう。

### 参考
Spigotフォーラム("create-a-sign-from-a-block")
(https://www.spigotmc.org/threads/create-a-sign-from-a-block.279590/)

てれるん氏運営Discordサーバー、プラグイン塾のみなさん

## 

それでは、よいプラグインライフを～
-坂木唖ルカ-
three.jsのテクスチャが意図した色合いにならない時

## 概要
`three.js`を使って3DモデルをWebブラウザに描画する時に[GLTFLoader](https://threejs.org/docs/#examples/en/loaders/GLTFLoader)を使う場面がありました。具体的には、Webブラウザで出力すると実際にの色合いより濃い色合いに映る問題がありました。その際に、遭遇した色合いが意図しないものになる問題で効果的だった対処法について記します。
この問題は、three.jsの[WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer)のデフォルトの色空間が線形色空間を使っているため、モニタで描画した際に色合いが意図していないものになることが原因のようです。詳細は[参考文献](https://tech.cygames.co.jp/archives/2296/)が大変わかりやすかったです。

## 対処方法1
`three.js`の`レンダラー(WebGLRenderer)のテクスチャ`に対して`sRGBEncoding`を設定する
```javascript
// 色合いをディスプレイに合わせてsRGB補正
renderer.outputEncoding = THREE.sRGBEncoding
```
※他のテクスチャに対しても**sRGB補正**がかかることを注意。具体的には、カメラ画像などを背景に埋めていた場合に白飛びしたような現象が起きます。
## 対処方法2
以下のようにモデルのテクスチャのみ`sRGB空間`を適用する方法です。これで、方法１の注意書きで記述したようにレンダラーを`sRGB空間`に設定すると`線形色空間`でいい感じの配色だったのに色合いが変わることを防げます。
```javascript
const gltfLoader = new THREE.GLTFLoader()
gltfLoader.load('./model/xxx.glb', (gltf) => {
  gltf.scene.traverse((child) => {
    if (child.isMesh) {
      child.texture.encoding = THREE.sRGBEncoding
    }
  })
})
```
Windows WSL2でDocker環境を構築

# Windows WSL2でDocker環境を構築

## はじめに

- Windowsに簡単にUbuntu環境を構築してDockerを構築したい！という思いから作業をしたので、以下にその手順をまとめます。
- Docker for Windowsではダメなの？という件に関して、Docker For Windowsで問題のない環境であればそちらが手軽です。
  - ですが、Docker For Windowsは私の環境では重く、ちょっと使いづらかったので、構築しました。
  - Dockerを何に使うの？という点については、私の場合、別記事にする予定ですがPlantUML ServerとMermaidの環境構築に利用しています。
  - [VS CodeでPlantUML with WSL2](https://qiita.com/whim0321/items/84baa0e6fd9f4a05f0f2)　まさに記事にしようと思っていたことがまんま書いてあったので、こちらをどうぞ
  - [Mermaidで描いた図形を画像ファイルに出力し、キレイに拡大表示してみた](https://dev.classmethod.jp/articles/mermaid-live-editor/)　Mermaidはこちら。
  - 単純にオフラインになっても、VS CodeでMarkdown仕様書を作成するために、PlantUMLやMarmeidを画像やPDFなどに変換できる環境を整えたかったため

## 以下手順です

### 1. Windows PowerShellで以下２行を実行

```shell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

### 2. ここで再起動

### 3. 以下からWSLインストーラーをダウンロードしてインストール

```shell
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
```

### 4. WSL 2を規定のバージョンとして設定する

以下、Windows PowerShellで以下を実行

```shell
wsl --set-default-version 2
```

### 5. Ubuntuをインストール

```shell
wsl --install -d Ubuntu
```

### 6. Ubuntuのインストール画面で、nameを聞かれる

- Windowsのログインユーザ名にしました

### 7. パスワードを聞かれる

- 新たにつけるパスワードにしてください

### 8. wslのデフォルトを変更

```shell
wsl --list --verbose
```

で確認し、Ubuntuの左に「*」がなかったら、

```shell
wsl --set-default Ubuntu
```

を実行する

### 9. ターミナルを開き

```shell
sudo apt update | sudo apt upgrade -y
sudo apt list --upgradable
sudo apt update | sudo apt upgrade -y
sudo apt autoremove
```

を実行する
同じことを繰り返しているのは、リスト更新後、何か更新が増えていたらインストールするため。

### 10. docker のためのパッケージをインストール

```shell
sudo apt install curl -y | sudo apt install apt-transport-https -y
```

### 11. dockerをインストール

#### a)GPG鍵の交換

```shell
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
```

#### b)docker安定板のインストール

```shell
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```

#### c)docker-engineをインストール

```shell
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io -y
```

#### d)docker composeをインストール

```shell
sudo apt install docker-compose -y
```

### 12. dockerデーモン起動

```shell
sudo service docker start
```

### 13. ユーザの追加

```shell
sudo gpasswd -a {ユーザ名} docker
```

例)sudo gpasswd -a tanoue docker

以上でDockerの構築は完了です。
Tailwind CSSのベストプラクティス

# 概要

* 今回は[Tailwind CSS](https://tailwindcss.com/)におけるスタイリングのベストプラクティスについてまとめました。
* ベストプラクティスにあたっては、[tailwindlabs](https://github.com/tailwindlabs)のCommunity Manageをされている[Sophiaさん](https://gist.github.com/sandren)のTipsを基にしております。
* また、本記事はTailwind CSS自体の説明は割愛しているため、Tailwind CSS自体を学びたい場合は、[こちら](https://www.youtube.com/watch?v=elgqxmdVms8&list=PL5f_mz_zU5eXWYDXHUDOLBE0scnuJofO0)をオススメいたします。

# Tailwind CSSのベストプラクティス
## ユーティリティクラス

* 複数のユーティリティクラスを使用する場合は、その文字列の順番に意味を持たせます。
* [Concentric CSS](https://rhodesmill.org/brandon/2011/concentric-css/)のアプローチを使うのが良さそうです。
* Concentric CSSでは、プロパティをアルファベット順とかにするのではなくて、それぞれのプロパティの役割ごとに並び替えます。

下記はConcentric CSSで並び替えたcssの例です。
```
{
    display: ;
    position: ;
    float: ;
    clear: ;

    visibility: ;
    opacity: ;
    z-index: ;

    margin: ;
    outline: ;
    border: ;
    background: ;
    padding: ;

    width: ;
    height: ;
    overflow: ;

    color: ;
    text: ;
    font: ;
}
```

* このルールに従うと下記のような順番でユーティリティクラスをつけていく形になります。
  * ① : ポジショニング系
  * ② : ボックスモデル
  * ③ : ボーダ系
  * ④ : コンテンツのサイズとスクロールバー周りのやつ
  * ⑤ : テキスト周りのやつ
  * ⑥ : その他の視覚的な調整を行うもの

---

* 使用するユーティリティクラスの数を少なくします。
* 例えば、ml-2 mr-2 と書いているのであれば、mx-2にすれば１つのユーティリティクラスで解決します。

**良くない例**
```
ml-2 mr-2
```
上記は下記のように書き直せます。

**良い例**
```
mx-2
```

他にもシンプルにできるのであればシンプルにできるよう努力する。

**良くない例**
```
pt-4 lg:pt-8 pr-4 pb-4 pl-4
```

**良い例**
```
p-4 lg:pt-8
```

---

* 画面のサイズごとにユーティリティクラスが変わるbreakpoint's prefix(レスポンシブになるユーティリティクラス)を使用している場合、まとめられるのであればまとめる。

**良くない例**
```
lg:flex lg:flex-col lg:justify-center
```

* それぞれのユーティリティクラスごとにlg:をつけてますよね。
* これは下記のようにまとめられます。

**良い例**
```
block lg:flex flex-col justify-center
```

---

* レスポンシブになるユーティリティクラスでは、画面サイズに応じてそのユーティリティクラスが適用される。
* なので、無駄なユーティリティクラスは省略できます。

**良くない例**
```
block sm:block md:flex lg:flex xl:flex
```

* 上記の場合、md:　に記載されているものが適用されるので、それ以上の画面サイズに応じたユーティリティクラスは省略できます。

**良い例**
```
block sm:block md:flex
```

## コンポーネントクラス

* ```@apply```を使用する場合は、Tailwind CSSがプロジェクトに馴染んできたくらいで使用します。
* なぜかというと```@apply```の使用用途が、あるコンポーネント内のユーティリティクラスの文字列が他のコンポーネントでも使用されている場合に共有として使えるように@applyを使用することで意味を持つ為です。(これで重複するようなユーティリティクラスを排除できる)


# 参考

https://www.youtube.com/watch?v=elgqxmdVms8&list=PL5f_mz_zU5eXWYDXHUDOLBE0scnuJofO0

https://theodorusclarence.com/blog/tailwindcss-best-practice

https://gist.github.com/sandren/0f22e116f01611beab2b1195ab731b63
Chromeのfaviconを即時反映させたい。

Chromeのキャッシュを削除すればよいだけの話だが、目的がfaviconの更新だけで、他のキャッシュまで消したくないので、その方法の話。

Chromeのfaviconキャッシュの場所は、こちら。
※ 以下のコマンドはすべてChromeが閉じた状態で行う。

**Windows**の場合、`%LOCALAPPDATA%\Google\Chrome\User Data\Default\Favicons`がキャッシュファイルの場所となる。

faviconを更新したい場合、これを削除すれば、キャッシュされているすべてのfaviconが更新される。
```
# faviconキャッシュを削除
del "%LOCALAPPDATA%\Google\Chrome\User Data\Default\Favicons"
```
一時的にこのキャッシュをバックアップして、後で戻してもよい。
```
# faviconキャッシュを一時退避
ren "%LOCALAPPDATA%\Google\Chrome\User Data\Default\Favicons" Favicons_

# 退避したfaviconキャッシュを復元
del "%LOCALAPPDATA%\Google\Chrome\User Data\Default\Favicons"
ren "%LOCALAPPDATA%\Google\Chrome\User Data\Default\Favicons_" Favicons

```

以上
WSLのインストールを試してみた

## はじめに
SSHポートフォワーディングを勉強のため、まず最初にWSLのインストールを試してみました。
WSL（Windows Subsystem for Linux）は、Windows上でLinuxの環境を使用出来ます。

以下のサイトを参考にしました。
https://docs.microsoft.com/ja-jp/windows/wsl/
https://atmarkit.itmedia.co.jp/ait/articles/2103/23/news007.html



以下のサイトで学びました。
infracollege
https://infracollege.vamdemicsystem.black/linux/




## 動作条件
Windows11で試しました


## WSLのインストールの手順

### コマンドプロンプトを管理者権限で開き、WSLをインストールしました
```
Microsoft Windows [Version 10.0.22000.739]
(c) Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>wsl --install
インストール中: 仮想マシン プラットフォーム
仮想マシン プラットフォーム はインストールされました。
インストール中: Linux 用 Windows サブシステム
Linux 用 Windows サブシステム はインストールされました。
ダウンロード中: WSL カーネル
インストール中: WSL カーネル
WSL カーネル はインストールされました。
ダウンロード中: GUI アプリ サポート
インストール中: GUI アプリ サポート
GUI アプリ サポート はインストールされました。
ダウンロード中: Ubuntu
要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。

C:\WINDOWS\system32>
```
### PCを再起動した

### Windowsの検索で「WSL」で検索した
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/e3342e45-5305-5485-f20c-9795834580cd.png)

### WSLを開きユーザーを作成した

ユーザー作成(例 test)とユーザーのパスワードを設定した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/bdc1ccbe-57aa-fa2f-15ff-62a3fa50897a.png)
cronを用いたrsyncの実行

# はじめに
例えばバックアップをしたいとき，ファイルを定期的に送信するため，cronとrsyncを用いることがあります．今回は，バックアップを目標とした手順を述べます．

# 環境
今回はESXiでVMを作成しています．
VMの構成は以下の通りです．

##### VM 構成情報 (ファイルサーバ)
・OS Ubuntu-20.04.2
・vCPU 2 コア
・RAM 8GB
・HDD 220GB
##### VM 構成情報 (バックアップサーバ)
・OS Ubuntu-20.04.2
・vCPU 2 コア
・RAM 8GB
・HDD 120GB

ファイルサーバから，バックアップサーバのbackupというディレクトリにファイルを送信します．

# cron
cronは，プログラムを自動実行するためのデーモンです．
人によってこの設定場所は違いますが，今回は/etc/cron.dで作成した場合を想定します．


# バックアップ用のシェルスクリプト作成
今回は，バックアップをすることを想定したシェルスクリプトを作成します．
```backup.sh
expect -c "
  set timeout 3
  spawn rsync -av [file-name] [user-name]@[host-name]:~/backup
  expect \"password:\"
  send -- \"hogehoge\r\"
  expect eof
  exit
"
```

rsyncはsshを用いるため，パスワードを聞かれます．自動でパスワードを入力するため，expectを用います．

```
sudo apt install expect
```
最後にinteractを用いるサイトがありますが，これは標準入出力をシェルに戻すためのコマンドなので，cronでは実行できず処理が止まります．これによりファイルを送信できないことがあるため気を付けましょう．

次に，backup.shに実行権限を付与します．
```
$ sudo chmod +x backup.sh
```

# cronの実行場所

cronの設定場所には

・/var/spool/cron/crontabs/[USER]
・/etc/crontab
・/etc/cron.hourly
・/etc/cron.daily
・/etc/cron.monthly
・/etc/cron.weekly
・/etc/cron.d

があります[1]．

また，ネットで検索すると

・crontab -eでvar/spool/cron/crontabs/[USER]に書き込む方法
・/etc/cron.d内にファイルを作成する方法
・/etc/cron.(hourly|daily|weekly|monthly)/内に設定する方法
・/etc/crontabで設定する方法

があります[2]．

個人的には，crontab -rで間違えて設定を削除しないよう，/etc/cron.d内に設定するのがよさそうです．cron.dは本来インストールされたパッケージ専用のディレクトリらしいですが，プロジェクトや担当者毎にファイルを分けられます．

# cronの設定
cron.d内にcron実行用のファイルを作成します．
エディタはお好きなものを使ってください．今回はvimを使用します．
```
$ cd /etc/cron.d
$ sudo vim cron_test
```

cron_test内に実行したいファイルを追記します．
```cron_test
*/1 *   * * *   user    /home/user/backup.sh
```
今回はテストを兼ねて，一分間隔で送信する設定にしました．

送信先(今回はバックアップサーバのbackupディレクトリ)にファイルがあれば成功です．
```
$ watch ls backup
```
と入力すると，backupディレクトリにファイルが送信されるかを毎回lsで確認しなくてよいです．

# ファイルが送信されない場合
```
$ cat /var/log/syslog | grep cron -i
```
で，cronに関するログを見ることができます．
```
(No MTA installed, discarding output)
```
と表示されている場合，
```
$ sudo apt install postfix
$ sudo apt install mailutils
```
でインストールしてください．
ログを確認できるようになります．
postfixのインストール時は，今回local onlyを選択しました．

また，
```
$ mail
```
でもログを確認できるようになります．

# 参考文献
[1]penpenメモ，”色々なcronの場所と違い【Ubuntu 18.04.4 LTS】”，https://penpen-dev.com/blog/cron/
[2]とーますメモ，”【cron】改めてcronの設定方法について勉強し直してみた”，https://thoames.hatenadiary.jp/entry/2018/12/30/101021
JavaScriptで0パディングを行う方法

# 0パディングとは
ゼロパディングとは、数値を文字として表現・表示する際に、指定された桁数に足りない分だけ左右に「0」を追加する処理のこと。決まった長さ（固定長）の文字列に変換したいときに行われる。※1

この処理をJavaScriptで行いたい場合、非常に簡単に実装することが可能です。

## String.prototype.padStart()メソッド
0パディングを行うためにはpadStart()メソッドを用います。
padStart() メソッドは、結果の文字列が指定した長さになるように、現在の文字列を他の文字列で (必要に応じて繰り返して) 延長します。延長は、現在の文字列の先頭から適用されます。

使用方法としては第一引数に設定したい文字数、第二引数に埋める文字です。
例えば3桁で表示したい場合は下記のようなコードになります。
```
let num ="6"
console.log(num.padStart(3, '0'));
```
出力結果
```  "006" ```

これが仮に初めから3桁の数字が用意されている場合は0を挿入しません。
```
let num2="333";
console.log(num2.padStart(3,"0"))
```

出力結果
``` "333" ```
また、例えば0の代わりに"x"を指定した場合は　
```
let num = "6";
console.log(num.padStart(3,"x"))
```
出力結果
``` "xx6" ```
となります。



## 引用
https://e-words.jp/w/ゼロパディング.html
## MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/padStart