OmniAICreator/Qiita-1.07M huggingface dataset:
xlsxデータを読み込んで出力してみる

# Brightの対象
Webアプリ開発 Elixir > クラス1 > Elixir Web／ライブラリ > CSV／Excel > Xlsxir

--- 

使うライブラリ

https://hexdocs.pm/xlsxir/overview.html

ソース例

Xlsxファイルを読み込んで0シート目の内容をタブ区切りで表示します

```Elixir
Mix.install([{:xlsxir, "~> 1.6"}])

{:ok, tid} = Xlsxir.multi_extract("./test.xlsx", 0)
Xlsxir.get_list(tid)
|> Enum.each(&Enum.join(&1, "\t") |> IO.puts)
Xlsxir.close(tid)
```

実行例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/7f0a17bf-09c9-9676-9bf7-80c3ab116eea.png)

データ例
![Screenshot from 2022-12-24 22-45-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/fd2866bb-92dc-a60c-028c-0c327bd76444.png)

応用すれば、xlsxファイルからデータを読み込んでデータ加工ができそうですね
Markdown記法

Markdown記法のことを全く知らなかったので、簡単なものを5個ピックアップしてみました。

### 1.見出し

```ruby:見出し
# H1タグ
## H2タグ
##### H5タグ
```
# H1タグ
## H2タグ
###### H6タグ

* * *
### 2.コードの挿入

コードのはじめと終わりに```をつける。
（終わりの`を表示させる方法がまだわかりません）


```java:
```java:java
public class Main{
    public static void main(String[] args){
        int age;
        age = 30;
        System.out.println(age);
    }
}
```

```java:java
public class Main{
    public static void main(String[] args){
        int age;
        age = 30;
        System.out.println(age);
    }
}
```
***
### 3.テーブル
整数x整数と入力すると、「テーブルを挿入」というタブが出てくるのでクリックすると、自動でテーブルが作成される。
例：3x3と入力した場合↓
| 1 | 2 | 3 |
|:-:|:-:|:-:|
|   |   |   |
|   |   |   |
|   |   |   |
***
### 4.リスト

+ 順序なしリスト：文頭に「*」「+」「-」のいずれかと半角スペースを入れると順序なしリスト

1. 番号付きリスト：文頭に「数字.」と半角スペースを入れると番号付きリスト
***
### 5.補足
```ruby:見出し
:::note info
インフォメーション
infoは省略可能です。
:::

:::note warn
警告
○○に注意してください。
:::

:::note alert
より強い警告
○○しないでください。
:::
```
:::note info
インフォメーション
infoは省略可能です。
:::

:::note warn
警告
○○に注意してください。
:::

:::note alert
より強い警告
○○しないでください。
:::
* * *
dlopen(): error loading libfuse.so.2 AppImages require FUSE to run.  You might still be able to extract the contents of this AppImage  if you run it with the --appimage-extract option.

```bash
$ ./jetbrains-toolbox 
dlopen(): error loading libfuse.so.2

AppImages require FUSE to run. 
You might still be able to extract the contents of this AppImage 
if you run it with the --appimage-extract option. 
See https://github.com/AppImage/AppImageKit/wiki/FUSE 
for more information
```

ツールボックスをインストール中にエラーが出ました

# `libfuse2`をインストールしましょう

```bash
sudo apt install libfuse2
```
gocsvですべてのセルをダブルクォーテーションで囲む

# 概要
gocsvで生成するCSVのすべてのセルをダブルクォーテーションで囲みたかった。
[ネットで見つけた記事](https://qiita.com/developer-kikikaikai/items/af278f52cb06cc0f430d)とは別パターンの実装をしてみた。

# 実装

## 方針
ネットで見つけた記事では、生成したCSVをデコードして、各セルをダブルクォーテーションで囲った後、もう一度エンコードしている。

自分は、以下の方法で実装してみた。
gocsvでは、デフォルトでは内部でencoding/csvのWriter構造体を使用している。そこで、
1. gocsvのCSVWriterインターフェイスを実装する構造体を作成する
2. ↑で作成した構造体に、encoding/csvのWriterの実装を参考に、すべてのセルをダブルクォーテーションで囲むWriteメソッドを生やす
3. ↑をgocsvのMarshalCSVメソッドに渡す

### [gocsvのCSVWriterインターフェイス](https://github.com/gocarina/gocsv/blob/ad3251f9fa25/safe_csv.go#L9)

```go
type CSVWriter interface {
	Write(row []string) error
	Flush()
	Error() error
}
```

### ↑を実装するカスタム構造体

```go
type customCSVWriter struct {
	w *bufio.Writer
}

func NewCustomCSVWriter(w io.Writer) gocsv.CSVWriter {
	return &customCSVWriter{
		w: bufio.NewWriter(w),
	}
}

// Write writes すべてのセルをダブルクォーテーションで囲んだCSV
// encoding/csvのWriteメソッド(https://cs.opensource.google/go/go/+/refs/tags/go1.19.2:src/encoding/csv/writer.go;l=48)を一部改修したもの
// 違いは以下
// 1. すべてのセルをダブルクォーテーションで囲む
// 2. 区切り文字は`,`固定
// 3. 改行文字に`\r\n`を使用するオプションは無効
func (w *customCSVWriter) Write(record []string) error {
	for n, field := range record {
		if n > 0 {
			if _, err := w.w.WriteRune(','); err != nil {
				return err
			}
		}

		if err := w.w.WriteByte('"'); err != nil {
			return err
		}
		for len(field) > 0 {
			// Search for special characters.
			i := strings.IndexAny(field, "\"\r\n")
			if i < 0 {
				i = len(field)
			}

			// Copy verbatim everything before the special character.
			if _, err := w.w.WriteString(field[:i]); err != nil {
				return err
			}
			field = field[i:]

			// Encode the special character.
			if len(field) > 0 {
				var err error
				switch field[0] {
				case '"':
					_, err = w.w.WriteString(`""`)
        case '\r':
          err = w.w.WriteByte('\r')
				case '\n':
          err = w.w.WriteByte('\n')
				}
				field = field[1:]
				if err != nil {
					return err
				}
			}
		}
		if err := w.w.WriteByte('"'); err != nil {
			return err
		}
	}

	err := w.w.WriteByte('\n')
	return err
}

func (w *customCSVWriter) Flush() {
	w.w.Flush()
}

func (w *customCSVWriter) Error() error {
	_, err := w.w.Write(nil)
	return err
}

```

### ↑を呼び出すコード
```go
buffer := bytes.Buffer{}
csvWriter := NewCustomCSVWriter(&buffer)
err := gocsv.MarshalCSV(&(CSVにしたい構造体など), csvWriter)
```


# 参考
- [gocsv](https://github.com/gocarina/gocsv)
- [ネットで見つけた記事](https://qiita.com/developer-kikikaikai/items/af278f52cb06cc0f430d)
GlueからAuroraのMySQLにJDBC接続する

# 概要
AWS GlueからAuroraのMySQLにJDBC接続してデータを取得する方法を紹介します。

# 環境
- python==3.7
- pyspark==2.4.3

# 手順
1. VPCの設定
2. AWS Glue接続を追加する
3. コード

### VPCの設定
[こちら](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/setup-vpc-for-glue-access.html)を参考に、接続したいAuroraクラスタが所属するセキュリティグループの設定をします。

### AWS Glue接続を追加する
[こちら](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/console-connections.html)を参考に、接続したいAuroraクラスタに対して`AWS Glue`接続を追加します。

### コード
PySparkでJDBC接続する例を記載します。

```python
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session

jdbc_url = f"jdbc:mysql://{ホスト}:{ポート}/{データベース名}"

df = spark.read.jdbc(jdbc_url, {テーブル名}, properties={
                "user": {ユーザ名},
                "password": {パスワード}
            })
```

JDBCに接続するためのURLの形式は以下

```python
"jdbc:mysql://{ホスト}:{ポート}/{データベース名}"
```

# 参考
- [JDBC データストアに接続するための VPC の設定 AWS Glue](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/setup-vpc-for-glue-access.html)
- [AWS Glue 接続の追加](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/console-connections.html)
- [Sparkのドキュメント](https://spark.apache.org/docs/2.4.3/sql-data-sources-jdbc.html)
AnimatePresenceに慣れる[framer-motion]

# 背景

 - [framer-motion](https://www.framer.com/motion/)を使うことで、React Componentのマウント・アンマウント時にアニメーションを定義することができる。
 - このうち、アンマウントについては、 対象のコンポーネントを `AnimatePresence` コンポーネントでラップする必要があるが、少しクセがあるので、ここで説明する。

# 基本的な利用方法

 - ロードが完了したら(`loaded=true`)、`Spinner`をフェードアウトして、`Content`コンポーネントをフェードインさせる例。
 - 必ず、AnimatePresence の直下のコンポーネントに`key`を付ける必要がある。
 - `Spinner`のフェードアウトを待ってから`Content`をフェードインさせたいので `exitBeforeEnter` を付ける。

```jsx
<AnimatePresence exitBeforeEnter>
  {loaded && (
    <motion.div key="content" init={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0}}>
      <Content  />
    </motion.div>
  )}
  {!loaded && (
    <motion.div key="spinner" init={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0}}>
      <Spinner />
    </motion.div>
  )}
</AnimatePresence>
```

# その他できること

 - 上記は単純なフェードイン・フェードアウトだが、直下のコンポーネントに `key` をつけることを守っていれば、アニメーションは、子孫のコンポーネントで定義することもできる。
 - 直下のコンポーネントは、自作のコンポーネントでもOK。

```jsx
<AnimatePresence exitBeforeEnter>
  {loaded && (
    <Content key="content" />
  )}
  {!loaded && (
    <Spinner key="spinner" />
  )}
</AnimatePresence>

// Spinner.tsx
<div>
  <motion.div init={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0, x: -1}}>
    loadが終わったら、左に消える
  </motion.div>
  <motion.div init={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0, x: 1}}>
    loadが終わったら、右に消える
  </motion.div>
</div>
```

# できないこと

 - AnimatePresenceをネストさせると、子のAnimatePresence以下にあるexitアニメーションは効かなくなってしまう。
 - 下記の例の場合、 `<div key="content">` のアンマウント時に、 `<motion.div key="content1">` の アニメーション (`exit={{opacity: 0, x: -1}}`)は効かなくなる。
 - https://github.com/framer/motion/issues/746

```tsx
<AnimatePresence exitBeforeEnter>
  {loaded && (
    <div key="content">{/* ここのアンマウント時に */}
      <AnimatePresence exitBeforeEnter>
        {tab1 && (
          <motion.div key="content1" init={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0, x: -1}}>
            <Content1  />{/* ここのアニメーションは効かない */}
          </motion.div>
        )}
        {tab2 && (
          <motion.div key="content2" init={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0, x: -1}}>
            <Content2  />
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  )}
  {!loaded && (
    <div key="spinner">
      <Spinner />
    </div>
  )}
</AnimatePresence>
```
【Alpine.jsまとめ】とりあえずこれらを知っておけば開発できる

# そもそもAlpine.jsを知らない方へ
https://qiita.com/yowatsuyoengineer/items/aaa166752dc2342aef69

# Alpine.jsの導入方法
### scriptタグを使う方法
headタグに以下のscriptタグをブチ込むだけ
```html
<html>
  <head>
    ...
    <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
  </head>
  ...
</html>
```

### npmを使う方法
①まずインストール
```
npm install alpinejs
```

②バンドルするjsファイルに以下を記載する
Reactならapp.jsになると思います。
```js
import Alpine from 'alpinejs'
 
window.Alpine = Alpine
Alpine.start()
```

# 知っておくべき用語　2選
### ディレクティブ
x-○○のこと。
これらを使ってDOMを操作したり、クラス名を変更したり、cssを変えたりできる。

::: note
<b>よく使う/とりあえずこれ覚えておけばOKなディレクティブ</b>

x-data → プロパティ、メソッドを定義するのに必須。必ず記述する。
x-init → 初期化処理に使う
x-show → 要素を表示したり消したりするのに使う
x-bind → 要素のHTML属性（class, style, placeholderなど）を変えるのに使う
x-on → イベントを付ける時に使う（クリックイベントは＠clickで代用可能）
x-model → input要素に付ける。入力値をプロパティに反映させるときに使う。
x-transition → 簡単なアニメーションを付ける時に使う。
x-effect → プロパティの変更に同期にして処理を行いたいときに使う。
x-cloak → x-showを使っても要素が表示されてしまう時に使う。

<b><font color="red">※ ここにあるディレクティブの使用用途は他にもいろいろあります。</font></b>
:::

### マジックプロパティ
$○○のこと。
知らなくても全然使える。


# 書き方の基本
文字の表示・非表示を切り替えるボタンの例
### ①x-dataを定義
```html
<div x-data="{}">
    <button>表示</button>
    <div>やっほー</div>
</div>
```
### ②x-dataのプロパティ、メソッドを作成する
```diff_html
<div x-data="{
+    open: false,
+    toggle() { this.open = ! this.open }
}">
    <button>表示</button>
    <div>やっほー</div>
</div>
```

### ③ディレクティブを使ってプロパティ、メソッドを要素に割り当てる
button要素にクリックイベントを付与、div要素にx-showを付与する。
```diff_html
<div x-data="{
    open: false,
    toggle() { this.open = ! this.open }
}">
+    <button @click="toggle">表示</button>
+    <div x-show="open">やっほー</div>
</div>
```


簡単な処理を記述する分には以上の3ステップだけです。

# プラグインについて
Alpine.jsに機能を追加するプラグインが色々あります。
使いどころが多そうなプラグインを紹介しているので是非見てください。

### Mask
https://qiita.com/yowatsuyoengineer/items/99027c57bc73fdd8cce6

### Persist
https://qiita.com/yowatsuyoengineer/items/97952e755c6937216110

### Collapse
https://qiita.com/yowatsuyoengineer/items/1adb99963ed24ee918c1

# コピペで何とかしたい時
既に有志が作っているコンポーネントをコピペで利用できるサイトです。
Alpine.jsはシンプルなので、他人が作ったコンポーネントも比較的カスタマイズがしやすくて良きです。

https://qiita.com/yowatsuyoengineer/items/1f781574b4fc79a81803

# アプリの規模が大きくなった時
storeを使うことで、複数のx-dataで使えるデータを作れます。
言い換えれば<b>グローバルな状態管理</b>ということです。

https://qiita.com/yowatsuyoengineer/items/ce17131f3d38b27de711


# まとめ
12月1日からアドベントカレンダーの企画でずっとAlpine.jsの記事を書きました。
今回のアドカレがAlpine.js初学者にとって有益な情報になってくれれば良きでござんす。
ハッカソンで役に立つサービス（LINE Developers）

# はじめに
この記事は[**ハッカソン Advent Calendar 2022**](https://qiita.com/advent-calendar/2022/hackathon)の14日目の記事です。
本日は、ハッカソンで役に立つサービス**LINE Developers**について書きます。

## LINE Developersとは
一言でいうと、『**LINEが提供する機能を使って開発するためのツール**』です！

### LINE Developersサイト
LINEを使用する開発者向けの情報発信サイトがあります

公式サイトより引用
> LINEでは、外部の企業や開発者に向けて、LINEのサービスとの連携が可能になるAPI（以降、LINE APIと呼びます）を提供しています。LINE Developersサイト（https://developers.line.biz/）では、そうしたLINE APIの仕様や、開発手順を解説したドキュメントを開発者向けに提供しています。
> 
> たとえば、「自社で運営するECサイトに『LINEログイン』のボタンをつけて、エンドユーザーが手軽にLINEアカウントでログインできるようにしたい」と考えた開発者が、「実装方法がわからない」といった技術的な問題につまづかず、スムーズに開発できるよう、LINE DevelopersサイトではドキュメントやAPIリファレンスを公開しています。

https://developers.line.biz/ja/

## LINE Developersで提供されているサービス

**LINE**はたくさんのサービスを提供しています！
ハッカソンで使えそうサービスをピックアップします！

### LINEログイン
LINEログインをアプリに組み込むサービスです

https://developers.line.biz/ja/services/line-login/

### Messaging API
LINE botが簡単に作れるサービスです

https://developers.line.biz/ja/services/messaging-api/

**Messaging API**を使用して作ったプロダクト

https://protopedia.net/prototype/3010

### LINEミニアプリ
LINE上で動作するアプリを作成できます
触ったことがないので、時間があるときに何か作ってみたいです

https://developers.line.biz/ja/services/line-mini-app/


### LINE CLOVA
OCRやChatbot、本人確認などができる

https://developers.line.biz/ja/services/line-clova/


# おわりに
**LINE**は利用率がとても高いサービスなので、LINEログインなど使用してアプリを連携する価値は非常に高いと思います！
Apex 言語の字句解析パーサを Apex 言語で書いてみた

# `Apex` 言語の字句解析パーサを Apex 言語で書いてみた

`Apex` 言語の字句解析パーサを `Apex` 言語で書いてみて、GitHub に公開してみました。`RsvrApexParser` と名づけました。
※これは趣味の活動です。

## GitHub

- RsvrApexParser
    - https://github.com/igapyon/RsvrApexParser
    - Apex Parser written in Apex language.

## Usage

`RsvrApexParser` に内包される `RsvrApexLexicalParser` というクラスを使うと字句解析できます。

```JavaScript
List<ApexClass> apcList = [SELECT Name, Body, NamespacePrefix
                FROM ApexClass
                WHERE Status = 'Active'
                ORDER BY LastModifiedDate DESC
                LIMIT 1];

for (ApexClass apc : apcList) {
    String apexClassBody = RsvrApexLexicalParserUtil.readApexClassBody(apc.Name);
    RsvrApexLexicalParser parser = new RsvrApexLexicalParser();
    List<RsvrApexLexicalParser.LexicalToken> result = parser.parse(apexClassBody);
    // あとは字句解析結果をお好みに使います。
}
```


## 未実装

おおよその字句解析には対応させてみましたが、主に以下の箇所が未実装ではあります。

- SOQL Currency literal
- SOSL FIND seriese

## 感想

数年に一回は字句解析、構文解析を書き下ろしたくなるのですが、今ちょうど Salesforce Apex を扱っているので、それならば Apex で Apex を解析してみよう、というのがスタート地点です。
ただ、CPU の 10秒ルールがあって、書き下ろしには一部苦労が、、、。パフォーマンス改善をおこない、 10秒ルールには抵触しづらくはなっています。

ほんとうは構文解析も書き下ろしてみたいのですが、暇時間が確保できず、また Apex の構文は規模が大きめで ちょっと手が出ませんでした。
商品サムネイル画像にマウスを乗せるとメイン写真が切り替わる

⇒<a href="https://nonbiri3.com/?p=7342">実際の動作ページはこちら</a>

プログラムはこちら。
もっと良い書き方があったら教えてくださいm(_ _)m
```html
<style type="text/css">
    #mainImage img{
        height:300px;
    }
    div#imageList ul {
        margin: 10px;
        padding: 0;
    }
    div#imageList li {
        float: left;
        list-style-type: none;
        margin-left: 5px;
    }
    div#imageList li img {
        width: 50px;
        height: 50px;
    }
    </style>


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
     $('#imageList img').hover(function(){
        $('#mainImage img').attr('src', $(this).attr('src')); 
        $('#mainImage img').wrap($('<a>').attr('href',$(this).attr('src')));
    }); 
});
</script>

<div id="base">

    <div id="mainImage">
        <img src="sample1.jpg"/>
    </div>
 
    <div id="imageList">
        <ul>
            <li><img src="sample1.jpg"></li>
            <li><img src="sample2.jpg"></li>
            <li><img src="sample3.jpg"></li>
            <li><img src="sample4.jpg"></li>
            <li><img src="sample5.jpg"></li>
        </ul>
    </div>
</div>
```
git revert（間違ったコミットを打ち消したいとき ）


## 経緯　
railsにてログイン機能を実装していた時、うっかりdevelopブランチのまま作業をしていた...!

```
% git branch                        
* develop
  main
```
それに気づかないまま、**git add .**　し、 **git commit** してしまった。（コミット名は、**login_user** としていました）


## やったこと
コミットを取り消したいということで、**git revert ＜commitID＞** コマンドを使いました。
```
git revert <commitID>
```
commitIDは、後述の**git log** コマンドを入力して確認できます。

>既存のコミットを取り消すためのコマンドです。
>「取り消したいコミットを打ち消すようなコミットを新しく作成する」という処理によって、既存のコミットを取り消します。
>新しくコミットを追加しているだけなので、既存コミットの履歴が消えるわけではありません(コミットログをみると残っています)。
どんな変更があったのかということが(revertしたということも含めて)残るので、リモートにpushされて公開されているコミットに対しても安全に使うことができます。

>コミットIDを指定することで、そのコミットを打ち消すようなコミットが新しく追加されます。
コードは、そのコミットがなかったときの状態になります。
revertコマンドを実行するとエディタが開き、コミットメッセージを編集することができます
https://qiita.com/chihiro/items/2fa827d0eac98109e7ee

### 注意点
**git reset** という直前のcommitを取り消すコマンドとは似ていますが、挙動が異なります。
・git reset：　　そのまま過去に戻す
・git revert：　「打ち消しするコミット」を新たに追加して、状況を戻す

下記の記事でわかりやすく書かれています。


https://www-creators.com/archives/1116





```
% git revert 696f612a618958b77e9677e89146711586e24d90
[develop 2efe394] Revert "login_user"
 Committer: **** <***.local>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 10 files changed, 66 insertions(+), 119 deletions(-)
```

### git log

**git log** をみると、最新のコミット名の前にRevertが付与されているのがわかります。
```
% git log
commit 2efe39460fded828917cf8db02c20a6ff17a24d1 (HEAD -> develop)
Author: **** <****.local>
Date:   Sat Dec 24 06:53:27 2022 +0900

    Revert "login_user"   ＃こちら
    
    This reverts commit 696f612a618958b77e9677e89146711586e24d90.

commit 696f612a618958b77e9677e89146711586e24d90
Author: **** <****.local>
Date:   Sat Dec 24 06:50:36 2022 +0900

    login_user

commit 9b17c66b3e08b90867d96b91b86b1d63961fbe60 (origin/develop)
Merge: 9634da5 d0df5be
Author: **** <****@users.noreply.github.com>
Date:   Tue Dec 20 08:40:18 2022 +0900
```

### 新しいブランチへ切り替え
commit前の状態に戻ったところで、**git checkout -b (作成したいブランチ名)** で、developからブランチを切りました。
「-b」オプションを指定することで、ブランチの作成とチェックアウトを同時に行うことができます。

今回は、**feature/login_user** というブランチ名にしました。（ややこしいですが、コミット名と同じです）

```
% git checkout -b feature/login_user
Switched to a new branch 'feature/login_user'
% git branch                        
  develop
* feature/login_user #こちら
  main
```
補足ですが、以下のコマンドでもブランチの作成はできます。
```
git branch <branchname>
```

## 参考記事
https://qiita.com/chihiro/items/2fa827d0eac98109e7ee


https://backlog.com/ja/git-tutorial/stepup/07/


https://www-creators.com/archives/1116
ハッカソンで役に立つサービス（twilio）

# はじめに
この記事は[**ハッカソン Advent Calendar 2022**](https://qiita.com/advent-calendar/2022/hackathon)の13日目の記事です。
本日は、ハッカソンで役に立つサービス**twilio**について書きます。

## twilioとは

公式ドキュメントより引用
> Twilioとは音声、メッセージング・SMS、Video、emailなどの顧客との接点となるチャネルを包括的にAPIで提供する、顧客エンゲージメントプラットフォームです。

https://www.twilio.com/ja/

## twilioが提供する主なサービス

twilioは**たくさん**のサービスを提供しています！
すべて紹介するのは大変なので、ハッカソンで活躍しそうなサービスをピックアップします！

### 1. Programmable Voice
電話の発信や通話の録音・保存などが簡単にできます

https://cloudapi.kddi-web.com/function/voice

**Programmable Voice**を使用して作ったプロダクト

https://protopedia.net/prototype/3010

### 2. Programmable SMS
SMSの送信が簡単にできます

https://cloudapi.kddi-web.com/function/sms

### 3. Programmable Video
Web会議を簡単にアプリに組み込むことができます

https://cloudapi.kddi-web.com/function/video

**Programmable Voice**を使用して作ったプロダクト

https://protopedia.net/prototype/3637

# おわりに
**twilio**は様々なサービスを提供している上に簡単にアプリに組み込めるので
触っておいて損はないと思います！
自作OSをブラウザ上で動かしてみた。

## はじめに

この記事は[自作OS Advent Calendar 2022](https://adventar.org/calendars/8392)の24日目の記事として書かれています。

低レイヤーや自作OSに興味をもっているcotoro89と申します。

今回、v86を使い私が自作しているOS(Mv6)をブラウザ上で動かしたので簡単にご紹介します。

ブラウザだけで自作OSを動かせれば、自作OSに興味を持った方が手軽に試せるのでは？というのが、今回取り組んだ背景です。

もしも要望があれば、どこかで動作するイメージを公開したいと思います。

## 動作イメージ

まずは具体的な動きを動画でご覧ください。

ブラウザで該当URLにアクセスした後、BIOS起動、OS起動を経て、シェル上でpsコマンドを実行した結果（2つのプロセスを確認）までを録画したものです。キーボードやコンソールも再現されており、この範疇では非常にエミュレーション精度が高いように見えます。

![boot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075880/3050fc81-d303-8d67-02c4-ac927337d07d.gif)


## 利用の流れ

[v86](https://github.com/copy/v86)はWebAssemblyによるx86エミュレータです。このためWebAssemblyが実行できるWebブラウザ上でv86を動かすことで、Linuxといった32bit環境のOSを稼働させることができます。

利用までの大きな流れは以下の通りです。

1. v86をビルドする。
1. 起動させたいディスクイメージ(今回はfd image)をフォルダに配置する。
1. htmlファイル（v86 apiを用いて自作OSの情報を渡す）を配置する。
1. httpサーバーを起動させる。
1. URL(http://localhost:8000)にブラウザでアクセスする。

たったこれだけで、自作OSをブラウザ上で動かせるのは大変手軽と言えると思えます。

## html(osdev.html)

なお、利用したhtml(osdev.html)を参考までに掲載します。
非常に簡単なAPI記述でx86エミュレーションを利用できるため、他にも応用範囲が広いように思えます。

```osdev.html
<!doctype html>
<title>Basic Emulator</title>

<script src="../build/libv86.js"></script>
<script>
        "use strict";

        window.onload = function()
        {
            var emulator = window.emulator = new V86Starter({
                    wasm_path: "../build/v86.wasm",
                    memory_size: 256 * 1024 * 1024,
                    vga_memory_size: 2 * 1024 * 1024,
                    screen_container: document.getElementById("screen_container"),
                    bios: {
                        url: "../bios/seabios.bin",
                    },
                    vga_bios: {
                        url: "../bios/vgabios.bin",
                    },
                    fda: {
                        url: "../images/fatfdimg.img",
                    },
                    autostart: true,
                    acpi: true,
             });
        }
</script>

<!-- A minimal structure for the ScreenAdapter defined in browser/screen.js -->
<div id="screen_container">
    <div style="white-space: pre; font: 14px monospace; line-height: 14px"></div>
    <canvas style="display: none"></canvas>
</div>

```

## Mv6
私が以下のコンセプトで開発中のOSです。
安全性を高める上で、開発言語はC++（Better　Cとして利用）です。

+ UNIX(v6) like OS
+ セキュアかつ安全性が高い（開発言語で安全性を担保）

### 実装状況

現在はユーザ空間でアプリを動かすための実装を進めています。

- [x] マルチタスク
- [x] マルチコア（LAPIC）
- [x] MMU（Kerne/User空間の分離）
- [x] シェル
- [ ] ユーザ空間
- [ ] ファイルシステム

### その他

参考にさせていただいたOSは以下のとおりです。
xv6は少ないコード量でマルチコア対応からファイルシステム等まで実装しており、OSを自作する上でとても参考になりました。

+ hariboteOS(「30日でできる！ OS自作入門」)
+ xv6
+ MikanOS(ゼロからの OS 自作入門)
M5StickCPlusで8ServoHAT1.1を作動させるのに沼ったのでメモ

<b>[ こちら ](https://manumaruscript.com/m5stickcplus-8servohat-v1-1/)</b>に移動しました。

~~サンプルコードから動作確認を行うとするも、製品ページから公式ドキュメントに飛ぶもNot foundになったり、そもそも日本語訳だけおかしい感じの製品名になっていたりしてライブラリがごちゃごちゃしていたので備忘録として記録しておきます。~~
Apache Commons Lang3 の StringUtils と CharUtils を Salesforce Apex 言語に移植してみた

# `StringUtils` と `CharUtils` を Salesforce Apex に移植

Apache Commons Lang3 の `StringUtils` と `CharUtils` を Salesforce `Apex` 言語に移植して github に公開してみました。`ApacheCommonsLang4Apex` という名前で登録しました。
※主要なメソッドは移植されています。一部未実装のメソッドもあります。

## Usage

ApacheCommonsLang4Apex を利用することにより、以下のような Appache Commons Lang3 っぽい機能を使用することが可能になります。

```javascript
System.assertEquals('...fghi...', StringUtils.abbreviate('abcdefghijklmno', 5, 10));
System.assertEquals('', StringUtils.defaultString(null));
System.assertEquals('bat', StringUtils.defaultString('bat'));
```

## GitHub 上のリポジトリ

- [ApacheCommonsLang4Apex on GitHub](https://github.com/igapyon/ApacheCommonsLang4Apex)

ソースコードは この GitHub リポジトリから clone して入手可能です。
いつか `AppExchange` にもトライしてみたいですが、それは暇になった時にでも。。。

本当は `Apache Commons Lang3` に含まれるおおよその機能を移植したいですが、それは手間的にとても無理なので、自分としてあったら便利かつ移植が簡単そうなな `StringUtils` と `CharUtils` を手始めにざっと移植してみました。
※後日談 2022/12/25 に Apex Test のカバー率が 90% を超えました。

## ライセンス

ライセンスは `Apache License 2.0` です。そもそも Commons Lang ソースコードをコピペしてちょっこし Apex 用に変更しただけのものですので、ほぼほぼ Apache Commons Lang と思っていただけたら幸いです。

## 背景

Salesforce の Apex 言語は Java 言語にとてもよく似ています。そのため、Apache Commons Lang3 のような機能が欲しいな、と思う場面が多々あります。とくに StringUtils はぜひ使いたいと思い、ざっと移植して書き下ろしました。

### 後日談(2022/12/26)

後でわかったことをここにメモ。
世の中、同じようなことを考える方はいらっしゃるようで、もう10年以上前に Apex Commons (apex-lang?) という Apache Commons Lang を Apex に移植されていたアクティビティがあったようです。

- https://github.com/apex-commons/
- https://github.com/apex-commons/base/tree/master/src/classes

結構本格的に移植したようで、大量のクラスが Apex 化されています。率直にすごいです。圧倒されます。
なお、このプロジェクト自体はメンテナンスが緩やかなようでして、StringUtils.cls の API バージョンは 13.0 という、素朴にかなり古いものになります。また、多分当時の事情なのですが、JavaDoc部分がトルツメされていますので、そこが惜しいところですの。

## 移植参加者募集

私が隙間時間で実装するには Apache Commons Lang3 はとても広大です。
移植が進んだら、Apex開発のお困りの少しは解決できると期待されますのですの。
我こそはと腕に覚えのある OSS に理解のある方の参加をお待ちしてますです。
憧れのSalesforceエンジニアになってみて

未経験から今の会社に入社して来年の4月で1年が経とうとしているシリュウです。

皆さん、Salesforceというサービスをご存知でしょうか？
簡単に説明すると顧客管理システム（CRM）や営業支援システム（SFA）を中心とした企業向けのクラウドサービスで、最近では日本のトップ企業が次々と導入を進めているサービスです💨
CMでは二階堂ふみさんや大谷翔平選手が出演しています…（スゴイ🙌）

2022年10月からSalesforceエンジニアとしてのキャリアがスタートしたので、今回は***私がSalesforceエンジニアを目指した理由***を書いていきたいと思います。

👇簡単な経歴👇
2022年4月にエンジニアとして現企業に入社/
初案件はPHP/2022年10月からSalesforce案件に入る…🎉

プログラミングスクール卒業の際に書いた記事がありますので、
もしよければ読んでみて下さい🙌
https://qiita.com/ryuryu0213ww/items/29caea197b4fad625c8c


## Salesforceエンジニアを目指した理由

まずSalesforceエンジニアを目指した理由ですが...
#### カスタマーサクセス、「顧客の成功こそが、自社が提供する最大の価値である」という概念・考えをSalesforceはずっと前から大切にして、私はその考えにとても共感し、そんな素敵な会社が生み出したサービスのエンジニアとなり、企業や個人の成功に貢献したいと思った

です。

転職活動を始めた去年の10月頃はまだSalesforceという名前すら知りませんでした。
たまたま今勤めている企業がSalesforceのシステム導入に関わっていて、面接前に試しでSalesforceを学べる学習プラットフォーム[Trailhead](https://trailhead.salesforce.com/ja/today)で学習してみて、とても楽しく興味が沸いたのでSalesforceの開発に関わるエンジニアの方にお話し聞いたり、本を読んでみたりとSalesforceについて色々と調べてみました。
途中まではこんなサービスあるんだー、程度の考えだったんですが、ある本に出会ってSalesforceをエンジニアキャリアの軸として活躍したいと心に決めました。

↓こちら
https://www.amazon.co.jp/s?k=trailblazer+%E6%9C%AC&crid=3Q8DPV7NWNSI5&sprefix=trailblazer%2Caps%2C354&ref=nb_sb_ss_ts-doa-p_5_11

めっちゃいい本です。少しでも興味がある方はぜひ読んでみて下さい。
前職から自分自身が一番大切にしていた「人の成功に貢献したい・できるような人間になりたい」という考えがあった自分にはピッタリの本でした
ああ、また読み直したくなってきました…。年末にゆっくりと読書します…。

## Salesforceエンジニアを目指すにあたって
Salesforceエンジニアとして活躍したいと心に決めた私ですが、今の会社から内定を頂いてから入社まで4ヶ月以上あって、
しかも入社後は新人研修が3ヶ月あり、Salesforceの案件に入るまでに相当時間がかかりました。

その期間内はとても後悔しました。
もし転職活動前に戻れるならSalesforceエンジニアになるためどう動くか考えてまとめてみましたので参考にしてみて下さい🙌

#### ①Salesforceの開発・管理等をやっている企業へ入る
これは当たり前ですかね、私も実際に案件に入ってみて思い知りましたが、実践に勝る経験はないです👍

#### ②リスキル・人材育成プログラムに参加する
↓詳細
[未経験からのリスキルでSalesforceエキスパートに！](https://trailhead.salesforce.com/ja/today)
[Pathfinder](https://trailhead.salesforce.com/ja/today)

私も参加したかったのですが、Pathfinderはすでに入社後で応募できず、アクセンチュアのリスキルは選考に落ちてしまいました…・
挑戦できるチャンスがあれば、チャレンジしてみる事をお勧めします！

#### ③資格を取る
IT業界って資格はそんなに評価されないと聞いていましたが、salesforce界隈は意外と評価されるイメージです。
初めてのSalesforce案件に配属される際に、一緒に開発にするパートナーさんとお話しする機会があり、その際にSalesforceの基礎？となる資格
「Salesforce認定アドミニストレーター」を持っている事をお話ししたら、「え？未経験からマジ？」みたいな反応されました。

実務経験か資格、どっちが大切かと聞かれると実務経験の方が大事だと思いますが、資格は必ず持っておいた方がいいと思います。
私も年明けから2つの資格にチャレンジ予定です💪



## Salesforceエンジニアになって実際どうだい？

#### めっちゃ楽しいです、こんなに自分の仕事に誇りを持って、好きな仕事ができて、本当に最高です。

これはSalesforceエンジニアだからというわけではなく、エンジニアとして***好きなサービス・技術に携われている*** っていうのが
とても大事だなと最近実感しています。
まだ一年目のエンジニアですが、これからエンジニアになる方は***好きな技術・サービスを見つける、作る***のが大事だと思うので、
色々な技術に触れてみて、その中にSalesforceという選択肢をプラスしてみるといいかもです

私もこれからのSalesforceエンジニアとして、活躍できるように頑張っていきますので、お互いに頑張りましょう！
ハッカソンで役に立つサービス（Azure Functions）

# はじめに
この記事は[**ハッカソン Advent Calendar 2022**](https://qiita.com/advent-calendar/2022/hackathon)の12日目の記事です。
本日は、ハッカソンで役に立つサービス**Azure Functions**について書きます。

## Azure Functionsとは
一言でいうと、『**バックエンドを短時間で構築できるAzureのサービス**』です！

公式ドキュメントの説明
> 複雑なオーケストレーションの問題を解決するのに役立つイベント駆動型のサーバーレスコンピューティングプラットフォームを使用して、より効率的に開発を行います。Azure Functions のエンド ツー エンドの開発エクスペリエンスでは、使い慣れた言語を使用できます。追加のセットアップなしでローカルでビルドとデバッグを行い、クラウドで大規模にデプロイして運用し、トリガーとバインディングを使用してサービスを統合します。

https://azure.microsoft.com/ja-jp/products/functions/#overview

## Azure Functionsを使うメリット

### 1. サーバ管理が不要
プログラムを書くだけで実行環境を構築できます

### 2. クラウド（Azure）の知識がほぼ必要ない
サーバの構築が必要ないので、知識がない人でも環境構築できます

### 3. 費用が低い
用途に応じて、複数のプランから選択できます

https://azure.microsoft.com/ja-jp/pricing/details/functions/
テスト82

```vb
'リストボックスのメモ....〆(･ω･。)
'1 ､ユーザーフォームの挿入
'2 ､リストボックスの作成
'3 ､MultiSelect 1
'4 ､ListStyle 1
'5 ､ColumnsCount 5
'6 ､ColumnsHeads True

'標準モジュール
Sub test2()

UserForm2.Show vbModeless

End Sub

'----------------------------------------
'ユーザーフォーム内のコード

Private Sub CommandButton1_Click()

Dim i As Long
Dim tmp As String
Dim Select_flg As Boolean

Select_flg = False

With ListBox1

    For i = 0 To .ListCount - 1
        '選択されている場合
        If .Selected(i) = True Then
            'リストの値を取得
            tmp = tmp & .List(i, 1) & vbCrLf
            Select_flg = True
            
        End If
      
    Next

End With

'選択チェック
If Select_flg = False Then

    MsgBox "値が選択されていません。", vbCritical, "未選択"
    Exit Sub
    
End If

MsgBox tmp

End Sub

Private Sub UserForm_Initialize()

Dim Last_Row As Long

With ThisWorkbook.Sheets("リスト")
    '最終行取得
    Last_Row = .Cells(Rows.Count, 1).End(xlUp).Row
    
End With


With ListBox1
     '列幅
    .ColumnWidths = "20;80;80;80;80"
    
    'データ挿入
    .RowSource = ThisWorkbook.Sheets("リスト").Range("A2:E" & Last_Row).Address

End With


End Sub
環境変数の「登録・削除・確認」コマンドまとめ

## はじめに

環境変数を登録・削除・確認する方法を以下にまとめる

macOS と Ubuntu で検証したので 
macOS と Ubuntu で動作が担保されています。

環境変数の登録方法は  
「一時的な登録方法」と「永続的な登録方法」の2つの方法が存在します。

今回は「一時的な登録方法」にトピックを絞って記事を書いてます。

***

## 対象読者

- 環境変数の登録方法が「0.1秒」でパッと答えられない人
- 環境変数の削除方法が「0.1秒」でパッと答えられない人
- 環境変数の確認方法が「0.1秒」でパッと答えられない人

***

## 環境変数を登録して実際に登録されていることを確認する方法

- 環境変数を登録するときは `exportコマンド` を使用する
- 特定の環境変数が登録されていることを確認するときは `printenvコマンド` を使用する

```shell
# 環境変数を登録する
export http_proxy=http_proxy

# 登録した環境変数が正しく登録されていることを確認する
printenv http_proxy
# expected output : http_proxy
```

***

## 環境変数を削除して実際に削除されていることを確認する方法

- 環境変数を削除するときは `unsetコマンド` を使用する
- 特定の環境変数が削除されていることを確認するときは `printenvコマンド` を使用する

```shell
# 環境変数を削除する
unset http_proxy

# 環境変数が正しく削除されていることを確認する
printenv http_proxy
# expected output : 何も出力されない
```
ハッカソンで役に立つサービス（Azure DevOps）

# はじめに
この記事は[**ハッカソン Advent Calendar 2022**](https://qiita.com/advent-calendar/2022/hackathon)の11日目の記事です。
本日は、ハッカソンで役に立つサービス**Azure DevOps**について書きます。

## Azure DevOpsとは
一言でいうと、『**Microsoftが提供するチーム開発のサービス**』です！

https://azure.microsoft.com/ja-jp/products/devops/#overview

## Azure DevOpsに含まれる主なサービス

### 1. Azure Borards
カンバンボードやバックログなどが使える

https://azure.microsoft.com/ja-jp/products/devops/boards/

### 2. Azure Pipelines
CI/CD環境を構築できる

https://azure.microsoft.com/ja-jp/products/devops/pipelines/

### 3. Azure Test Plans
テスト関連のサービス。自動テストも構築できる

https://azure.microsoft.com/ja-jp/products/devops/test-plans/

### 4. Azure Repos
Gitリポジトリを提供してくれる

https://azure.microsoft.com/ja-jp/products/devops/repos/

### 5. Azure Artifacts
パッケージをチームで共有できる

https://azure.microsoft.com/ja-jp/products/devops/artifacts/

### 6. その他
その他にもたくさんサービスがある

https://marketplace.visualstudio.com/azuredevops

# おわりに
**Azure DevOps**は一回だけ触ったことが、いろいろできて便利だった記憶があります！
ArrayList

### 配列とのコード比較

```java:配列を使ったコード
// 配列を準備
String[] names = new String(4)

//4人追加
names[0] = "はたけやま";
names[1] = "さいとう";
names[2] = "とよかわ";
names[3] = "わたなべ";

System.out.println(names[1]);
```
```java:ArrayListを使ったコード
import java.util.ArrayList;

//ArrayListを準備
ArrayList<String> names = new ArrayList<String>();

//4人追加
names.add("はたけやま");
names.add("さいとう");
names.add("とよかわ");
names.add("わたなべ");

System.out.println(names.get(1));
```

### ArrayListの特徴

1.import文を記述する。
`import java.util.ArrayList;`

2.<>記号を使って、格納するインスタンスの型を指定する。
<>記号の中身を変えることで、どんな種類のインスタンスでも格納することができる。
```java:例
ArrayList<String> names = new ArrayList<String>();
ArrayList<Car> names = new ArrayList<Car>();
ArrayList<Date> names = new ArrayList<Date>();
```
`ArrayList<String>`、`ArrayList<Car>`、`ArrayList<Date>` で1つの型を表す。

3.宣言時のサイズ指定は不要。要素は随時追加可能。基本データ型の情報を格納できない。
基本データ型　：　Byte、short、int、long、float、double、char、boolean

```java:ラッパークラスをArrayListに格納
import java.util.ArrayList;

public class Main{
    public static void main(String[] args){
        ArrayList<Integer> points = new ArrayList<Integer>();
        points.add(10); //自動的にIntegerに変換・格納される
        points.add(80); //自動的にIntegerに変換・格納される
        points.add(75); //自動的にIntegerに変換・格納される
        for (int i : points){ //拡張for文も利用可能
            System.out.println(i);
        }
    } 
}
```
:::note info
復習：拡張for文とは？
配列の要素を一つずつ取り出すループを簡単に各ための特殊なfor文
　for(要素の型　任意の変数名：配列変数名){
　　～
　}
:::

```java:拡張for文
public class Main {
    public static void main(String[] args) {
        int[] scores = {10,20,30,40};
        for (int value : scores){
            System.out.println(value);
        }
    }
}
```
JavaScriptではすべてがオブジェクトのようなふるまいをする

「開眼！JavaScript」という本をオススメしてもらって、読んだら本当に面白かった（普段使っているけど改めて勉強になった）です。
タイトルにもある通り、この本を読んで今まで特に気にしていなかったが、ハッとさせられたJavaScriptの本質みたいな部分です。

# プリミティブ型とオブジェクト型
プリミティブ型を生成して複製すると格納している値をコピーします。
そのため、複製した値を変更しても、元の変数の値は変更されません。
```javascript:プリミティブ型の複製
hoge = 'hoge'
//'hoge'
hogeCopy = hoge
//'hoge'
hogeCopy = 'hogehoge'
//'hogehoge'
hoge
//'hoge'
typeof hoge
//'string' でプリミティブ型
```

それに対して、
オプジェクト型は、複製するとオブジェクトのアドレスをコピーするため、
複製先のオブジェクトを変更すると、元のオブジェクトも変更されてしまう。
```javascript:オブジェクト型の複製
obj = new Object()
//{}
obj.hoge = 'hoge'
//'hoge'
obj
//{hoge: 'hoge'}
objCopy = obj
//{hoge: 'hoge'}
objCopy.hoge = 'hogehoge'
//'hogehoge'
objCopy
//{hoge: 'hogehoge'}
obj
//{hoge: 'hogehoge'}　で、objCopy.hogeを変更すると、objも変更される
typeof obj
//'object' でオブジェクト型
typeof objCopy
//'object' でオブジェクト型
```

ここまでは、JavaScriptを実装している上で、なんとなくイメージができる。

# プリミティブ型なのにラッパーオブジェクトのメソッドが使える
`typeof`で、プリミティブ型であることを確認したはずなのに、無意識的に`hoge.length`のようなメソッドを使っていました。

```javascript:プリミティブ型でメソッドが使える
hoge
//'hoge'
hoge.length
// 4
typeof hoge
//'string'
```
Javaでは、プリミティブ型には振る舞い（メソッド）を持たないので、参照型にする必要があります。
https://morizyun.github.io/java/type-primitive-reference.html

JavaScriptでは、この一連の処理をすべてバックグラウンドで自動で行います。

プリミティブ型ですが、目的のメソッドが呼び出されたタイミングでラッパーオブジェクトを生成して
実行後は破棄してプリミティブ型に戻ります。


これが、「~~JavaScriptではすべてがオブジェクトである~~」ではなく、
「JavaScriptではすべてがオブジェクトのようなふるまいをする」という意味でした。

開眼したような気がしました。
気軽にテンプレートを作って文字列を量産しよう

大量にデータを流して特定のテンプレートにしたがって文章を作りたいと思うことありますよね？

ということでさっそく


```Elixir
f = fn x -> """
--------------------------------------
あなたは#{x}番目の訪問者です
--------------------------------------
""" 
|> IO.puts()
end

1..10
|> Enum.each(&f.(&1))
```

実行結果

```
--------------------------------------
あなたは1番目の訪問者です
--------------------------------------

--------------------------------------
あなたは2番目の訪問者です
--------------------------------------

--------------------------------------
あなたは3番目の訪問者です
--------------------------------------

--------------------------------------
あなたは4番目の訪問者です
--------------------------------------

--------------------------------------
あなたは5番目の訪問者です
--------------------------------------

--------------------------------------
あなたは6番目の訪問者です
--------------------------------------

--------------------------------------
あなたは7番目の訪問者です
--------------------------------------

--------------------------------------
あなたは8番目の訪問者です
--------------------------------------

--------------------------------------
あなたは9番目の訪問者です
--------------------------------------

--------------------------------------
あなたは10番目の訪問者です
--------------------------------------
```


定形文章ぽく作るなら

```Elixir
f = fn x, y -> """
#{x} 様

謹啓　
平素は格別のお引き立てを賜り厚く御礼申し上げます。
　 ほげほげ　ふがふが　ほげほげ　ふがふが 
  あなたのラッキー番号は#{y}

""" 
|> IO.puts()
end

~w/田中 木下 佐藤/
|> Enum.each(&f.(&1, Enum.random(1..10)))
```

```
田中 様

謹啓　
平素は格別のお引き立てを賜り厚く御礼申し上げます。
　 ほげほげ　ふがふが　ほげほげ　ふがふが 
  あなたのラッキー番号は2


木下 様

謹啓　
平素は格別のお引き立てを賜り厚く御礼申し上げます。
　 ほげほげ　ふがふが　ほげほげ　ふがふが 
  あなたのラッキー番号は5


佐藤 様

謹啓　
平素は格別のお引き立てを賜り厚く御礼申し上げます。
　 ほげほげ　ふがふが　ほげほげ　ふがふが 
  あなたのラッキー番号は3
```

アイデア次第で、単体テストのコードもデータから作ることもできます。
ngrok でトンネリングすると Rails がブロックする問題

## 問題

ngrok でトンネリングすると、Rails にブロックされる。

その上、`config/environments/development.rb` に👇を入れてみてもなおらない
```
  config.hosts << '.ngrok.io'
```

## 解決

'.ngrok.io' -> '.jp.ngork.io' みたいに .jp を入れると治った

```
  config.hosts << '.jp.ngrok.io'
```

## 感想

ngork のホスト名かわった？
eslint 再帰ファイル検索のやり方

eslintでカレントディレクトリ配下のすべてのjsファイルまたはmjsファイルをチェックするには以下のように指定する。

```
eslint '**/*.{js,mjs}'
```
Windowsコマンドプロンプトなら、パスを二重引用符で囲む
```
eslint "**/*.{js,mjs}"
```

ディレクトリパスを指定するなら
```
eslint "./src/**/*.{js,mjs}"
```

あるいは
```
eslint ./ --ext .js,.mjs
eslint ディレクトリパス --ext .js,.mjs
```

参考
[ESLintのglobパターンがマッチしない問題の対処](https://qiita.com/Tsuyoshi84/items/7c80851371b4bee48de4)
[Eslint glob (**) is not considering all directories recursively](https://stackoverflow.com/questions/54165756/eslint-glob-is-not-considering-all-directories-recursively)
Rails　リンクが正しく動作しているかテストする方法

Railsではリンクが正しく動作しているかどうかをテストする際に統合テストを用います。

まずはテストファイルを作成します。

```Bash
rails generate integration_test site_layout
```

作成されたファイルを開きます。

```Ruby:sample_app/test/integration/site_layout_test.rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest
 
end
```

このファイルにテストコードを書いていきます。

今回は以下の点についてのテストを行います。

<ol>
<li>テンプレートが正しく表示されているかどうか。</li>
<li>リンクが正しく動作しているかどうか。</li>
</ol>

```Ruby:sample_app/test/integration/site_layout_test.rb
class SiteLayoutTest < ActionDispatch::IntegrationTest
  test "layout links" do
    get root_path
    assert_template "static_pages/home"
    assert_select "a[href=?]", root_path, count:2
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
  end
end
```
まず、以下のコードでルートURLにgetリクエストを送ります。

```Ruby
get root_path
```

次に、テンプレートが描画されているかを以下のコードで確認します。

```Ruby
 assert_template "static_pages/home"
```

そして、以下のコードでリンクが正しく動作しているのかを確認します。

```Ruby
assert_select "a[href=?]", root_path, count:2
```
a[href=?]の?をrailsではroot_pathに置き換えています。
つまりこのテストコードがテストしているのは以下のコードになります。

```Html
<a href="/">,,,</a>
```

また、テストするページの中にリンクが複数ある場合、その数もcount:2のように指定することができます。
paiza.ioでelixir その157

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
websocketを実装せよ。

# 方針
以下のライブラリーを借りる。

https://github.com/Azolo/websockex

# サンプルコード

```
defmodule EchoClient do
	use WebSockex
	require Logger
	def start_link(opts \\ []) do
    	URI.default_port("wss", 443)
		WebSockex.start_link("wss://echo.websocket.org/", __MODULE__, :fake_state, opts)
	end
	def echo(client, message) do
		Logger.info("Sending message: #{message}")
		WebSockex.send_frame(client, {:text, message})
	end
	def handle_connect(_conn, state) do
		Logger.info("Connected!")
		{:ok, state}
	end
	def handle_frame({:text, "Can you please reply yourself?" = msg}, :fake_state) do
		Logger.info("Received Message: #{msg}")
		msg = "Sure can!"
		Logger.info("Sending message: #{msg}")
		{:reply, {:text, msg}, :fake_state}
	end
	def handle_frame({:text, "Close the things!" = msg}, :fake_state) do
		Logger.info("Received Message: #{msg}")
		{:close, :fake_state}
	end
	def handle_frame({:text, msg}, :fake_state) do
		Logger.info("Received Message: #{msg}")
		{:ok, :fake_state}
	end
	def handle_disconnect(%{reason: {:local, reason}}, state) do
		Logger.info("Local close with reason: #{inspect reason}")
		{:ok, state}
	end
	def handle_disconnect(disconnect_map, state) do
		super(disconnect_map, state)
	end
end

#{:ok, pid} = 
EchoClient.start_link()
|> IO.inspect
#EchoClient.echo(pid, "Yo Homies!")
#EchoClient.echo(pid, "This and That!")
#EchoClient.echo(pid, "Can you please reply yourself?")
#Process.sleep 1000
#EchoClient.echo(pid, "Close the things!")
#Process.sleep 1500




```

# 実行結果

失敗、タイムアウトで結果出ず。

# 成果物

https://paiza.io/projects/yKwZ8B4QqnQ3Jwzh9DNPqg?language=elixir

以上。
git: 'remote-https' is not a git command

# 1. 概要
Linuxコマンドのちょっとしたエラーメモ

# 2. 現象
AWS KVSなどを扱ってるいつもの実験用Raspberry Pi 4Bでgit cloneしようとしたらエラーが起きた。

```
git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp
```
の実行で妙な警告ログがでた。以下である。

```
git: 'remote-https' is not a git command. See 'git --help'.
```

で、helpを見ても何が起きているのか分からない。gitはそれほど深く扱ってはいないものの、それなりに長い期間使っているが、初めて見た気がする。

# 3. ほかの人の対処方法
検索すると以下のコマンドがよく出てきた。もう入っていると出てきて自分にとっては何も意味がなかった。
```
$ sudo apt install libcurl4-openssl-dev
```

# 4. 自分の対処方法
仕方がないので、gitコマンドを再インストールした。これで直った。
```
$ sudo apt reinstall git
```

ちなみにどうしてこんな事になったのかは不明。
簡単Elixirシリーズ ~ プロセスを知ろう③ ~

# 簡単Elixirシリーズ
## ~ プロセスを知ろう③ ~

この記事は「[Elixir Advent Calendar 2022](https://qiita.com/advent-calendar/2022/elixir)」24日目の記事です
東京にいるけどfukuokaexのYOSUKEです。

簡単 Elixirシリーズでは小ネタをサクッと書いていこう。というコンセプトで作っていきます。

今回は、プロセスについて公式ドキュメントを見ながらサクッと解説の第3段です。

さて、前回の記事の続きものです、ちなみに前回の記事はこちらです。

https://qiita.com/Yoosuke/items/dd44fc47d29b20330680

さて、前回の例ではプロセスを継続的に終了しないようにコードを書き換えました。
今度は、さらにコードを変えて、状態を維持するように変換していきます。

```elixir

defmodule MyProcess do
  def await_receive_msg(msg_received \\ []) do
    IO.puts "プロセス #{inspect(self())}, メッセージ待ち中"
    receive do
      {x, y} = msg -> IO.puts "x + y = #{x + y}"
              [msg | msg_received ]
              |> IO.inspect(label: "メッセージ: ")
              |> await_receive_msg()
      "Quit" = msg -> IO.puts "計算をやめます。"
              [msg | msg_received ]
              |> IO.inspect(label: "メッセージ: ")
              |> await_receive_msg()
      msg -> IO.puts "なんか別のメッセージが送られてきました"
              [msg | msg_received ]
              |> IO.inspect(label: "メッセージ: ")
              |> await_receive_msg()
    end
  end
end
```

これで準び完了です。
早速、実行してみましょう。　メッセージを送った情報が蓄積されて行く様子がわかります。

```elixir
iex()> pid = spawn(MyProcess, :await_receive_msg, []) 
プロセス #PID<0.152.0>, メッセージ待ち中
#PID<0.152.0>
iex()> send(pid, [1,2])                              
なんか別のメッセージが送られてきました
[1, 2]
メッセージ: : [[1, 2]]
プロセス #PID<0.152.0>, メッセージ待ち中
iex()> send(pid, {1,2})
x + y = 3
{1, 2}
メッセージ: : [{1, 2}, [1, 2]]
プロセス #PID<0.152.0>, メッセージ待ち中
iex()> send(pid, {4,2})
x + y = 6
{4, 2}
メッセージ: : [{4, 2}, {1, 2}, [1, 2]]
プロセス #PID<0.152.0>, メッセージ待ち中
iex()> send(pid, "Quit")
計算をやめます。
"Quit"
メッセージ: : ["Quit", {4, 2}, {1, 2}, [1, 2]]
プロセス #PID<0.152.0>, メッセージ待ち中
```

これで、プロセスが状態を保持しながら継続する処理ができました。
これって、LiveView になんだか似てますね。
Next.jsで必須のライブラリでwindow is not definedを引いたとき

vonageのVideo APIを触っているさなか、久々に `ReferenceError: window is not defined`を引いて対応に手古摺ったのでその対処法を記します。

## そもそも`window is not defined`ってどんな時に出るエラーなのか

windowを使ってるけどwindowがない環境で処理が実行されている、つまり**ブラウザ環境でしか動かない処理をサーバーサイド側で動かしたときに生じるエラー**の一つです。



## 対処法

大きく分けて二つ存在します。

### useEffectを使用する

直感的に対応した場合、おそらくこちらになると思います。
useEffectは当然サーバーサイド側で実行されないので、この中でimportをすればいいという発想です。

例のごとく、`useEffect(()=>{}, [])`を作成し、その中で動的読み込みをすることで解決します。

```tsx
const Home: NextPage = () => {
  useEffect(() => {
    (async () => {
      const Foo = (await import("package")).default;
      // named exportの場合
      const Bar = (await import("package").then((module) => module.Bar));
    })
  }
  return <p>hello world</p>
}
```

こちらわかりやすくていいんですが、元々別の処理のためにuseEffectを使っているところに付け足すとかならともかく、そうでない場合は`window is not defined`解決のためにuseRffectして中で即時実行関数を非同期で宣言して～なんて面倒ですし可読性が下がります。

いやまあ正攻法的には本当にこっちだと思うんですけどね。
思うんですが、あまりしたくない手段です。

### next/dynamicを使用する

なんとなく邪道感ありますが、個人的にはこちらを推したいです。

`next/dynamic`は、Next.js環境下における動的読み込み用のライブラリです。
名前からわかる通りNext.jsに付属しているので、追加のインストールなしで使用できます。

使い方としてはこんな感じです。

```tsx
import dynamic from "next/dynamic";

const foo = dynamic(() => import("components/package"), {
  ssr: false,
});

const Home: NextPage = () => { // ...
```


で、一見簡単に見えるこれの何に邪道感があるのかというと、これの返り値が問題なのです。

以下が、dynamicの型情報になります。

```dynamic.d.ts
// ...
export default function dynamic<P = {}>(dynamicOptions: DynamicOptions<P> | Loader<P>, options?: DynamicOptions<P>): React.ComponentType<P>;
// ...
```

見ての通り、返り値が`ComponentType`となっています。
念のためもっと参照をたどると、中身は `ComponentClass<P> | FunctionComponent<P>;` 

そうです。
返り値にコンポーネントしか対応していないので、ライブラリのためだけにコンポーネントを一つ増やす必要があります。

いやまだそれだけなら特に問題はないですが、問題はフラグメントだけのコンポーネントを返すことになりうるということです。

なぜなら、まあ処理をうまいこと切り出してそのコンポーネント内だけの話に済ませられれば良いのですが、`window is not defined`なんてグローバルオブジェクト不足のエラー吐いているライブラリがそう都合よくいくわけがないからです。

というわけで、こんな感じにフラグメントのみを返す違和感のある処理を書くことになります。

```tsx
import { FC } from "react";
import foo from "package"

export const Foo: FC = () => {
  // fooを使った何かしらの処理
  return <></>;
}
export default Foo
```

うーん、ルール上許されているとはいえ違和感。
でも、useEffectと非同期の即時実行関数を増やすよりかは可読性的に良いのも確か。

## おわりに

というわけで、`window is not defined`を引いた時の対処法でした。
個人的には、基本的に`next/dynamic`を使用してあげる方がよいのかなとは思うのですが、まあなんとなく論拠の薄い邪道感があるのでちょっと難しいところですね。
WSL2のSSH接続を外部から行うためのポートプロキシの設定スクリプト

WSL2のSSH接続を外部から行うためのポートプロキシの設定スクリプト。
よく使うのでメモしておきます。

```
#delete portproxy

netsh.exe interface portproxy delete v4tov4 listenport=22

#get wsl ip address

$ip = (wsl -e hostname -I).TrimEnd()

#add portproxy

netsh interface portproxy add v4tov4 listenport=22 connectaddress=$ip connectport=22


#show port proxy

netsh.exe interface portproxy show v4tov4

#show windows ip address

(Get-WmiObject Win32_NetworkAdapterConfiguration).IPAddress
```
「銀河を駆け抜けてランデブー」STM32G071とSSD1331でランダムに点を表示


x だんだんめんどくなったので過去ログを見よ

x テーマは、「銀河を駆け抜けてランデブー」


![o_cop281.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1612c075-cedb-98c7-5ae8-466ba263ee58.jpeg)



```c++



//OLED_SSD1331_RAND_TEST1_071

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>


// You can use any (4 or) 5 pins
#define sclk 13
#define mosi 11
#define cs   10
#define rst  9
#define dc   8


// Color definitions
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF


Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, cs, dc, rst);


//初期化
void setup() {

  //表示の開始
  display.begin();

  //display.fillScreen(BLACK);

}//setup


//メインループ
void loop() {

  int px,py; //座標
  int ii;    //ループカウンター

  // 画面表示をクリア
  display.fillScreen(BLACK);

  for(ii=0;ii<100;ii++){

    //ランダムの設定
    px = random(96);
    py = random(64);

    // display.drawPixel(座標x, 座標y, 点の色);
    display.drawPixel(px, py, WHITE);

  }//for

  delay(1000); //1秒待つ

}//loop






```
【ルール説明・basic】literal-compare

こちらの記事は [Ansible lint Advent Calendar 2022 カレンダー2](https://qiita.com/advent-calendar/2022/ansible-lint) 8日目の記事になります。


今回はルール [literal-compare](https://ansible-lint.readthedocs.io/rules/literal-compare/) について説明します。

### literal-compare

[literal-compare](https://ansible-lint.readthedocs.io/rules/literal-compare/) は`when句`で条件を指定する時に必要以上に複雑な記述がされていないか検証します。

#### 問題のあるコード

```yaml
---
- name: Example playbook
  hosts: all
  tasks:
    - name: Print environment variable to stdout
      ansible.builtin.command: echo $MY_ENV_VAR
      when: ansible_os_family == True # <- 条件の記述が複雑になっている
```

#### 修正されたコード

```yaml
---
- name: Example playbook
  hosts: all
  tasks:
    - name: Print environment variable to stdout
      ansible.builtin.command: echo $MY_ENV_VAR
      when: ansible_os_family # <- 条件は簡潔に記述する
```




### 参考サイト

* [literal-compare — Ansible Lint Documentation](https://ansible-lint.readthedocs.io/rules/literal-compare/)
Ender 5 S1事始め⑤（FlashAir化）

購入していたFlashAirが届いたため、その対応を行った。
結構面倒だったため、備忘録的に手順を記載する。
## Wifiが内蔵されたSDカードについて
まず、前提としてWifiが内蔵されたSDカードで入手可能なものは以下になる。
* FlashAir
東芝製。技適を当然取得しており、安定感がある。残念なことに生産終了。
何やらソリッドギア社のe-Rideやらコムテック社のWSD16G-708LVが仕様互換品らしい。
フリマで買うならタマは一番出てる気がする。
* EZShare
EZshare社（？）が作っているらしい。
現在も製造されているようだ。
昔は株式会社テックが技適を通していたらしいがそのモデルは生産中止となり、現在は不明。
正直技適取っていない気がする・・・。
危ないのでパス。
* Eye-Fi
生産中止になってて良く分からない。
入手も使用も難しそうなのでパス。

2022/12現在ではFlashAirが安牌のようだ。
フリマ経由で入手はしたが、設定が中々難しかったので記載していく。

## 設定方法
[こちら](https://blog.prusa3d.com/easy-wireless-printing-with-flashair-sd-cards_8603/)のサイトを参考に設定していく。
具体的にはFlashAirのカードをPCに挿し、以下の設定を行う
* SD_WLANフォルダ内の隠しファイルのCONFIGをCONFIG.oldにリネームする
これを残しておかないと**FlashAirが文鎮化する**ので注意。
* 隠しファイルのCONFIGを以下の内容に書き換える
[Vendor]
APPSSID=自分のWifiのアクセス名
APPNETWORKKEY=自分のWifiのアクセスパスワード
CID=CONFIG.oldで記載されていたものをコピーする
VERSION=CONFIG.oldで記載されていたものをコピーする
APPMODE=5
APPNAME=3D_printer（実は何でも良い）
LOCK=1
PRODUCT=FlashAir
STA_RETRY_CT=0
UPDIR=/G-Code（ネットワークドライブ割り当てと合っていれば何でも良い）
UPLOAD=1
VENDOR=TOSHIBA
WEBDAV=2
* ルータでアクセスしに来たMACアドレスを手動でIP固定する
ルータごとに処理が異なるため割愛
DHCPじゃあネットワークドライブ割り当てたときに都合が悪いので。
* ネットワークドライブの割り当て
\\\\192.168.1.xx\G-CODE
をネットワークドライブ（例えばZ）に割り当てる。
これによりスライサーから直接Zドライブに保存することでSDカードに転送したことになる。
* コマンドを叩いて実行する
実はファイルは転送されても**Ender5 S1の画面上では認識されない**（何も表示されない）。
そのためターミナルで
M20:.gcodeファイルをリストアップする
M23:次に印刷するファイル名を指定する
M24:SDカードのファイルから印刷する

といった手順を踏んで印刷が可能となる。

## 雑感
手間を少なくするためにFlashAir化したんだが、手間が減ったんだか増えたんだか分からない結果となった。
何かソフトウェアかスクリプトでも作った方が良い気がする・・・。
【テクフラ】社内エンジニアイベントを開催

# はじめに
この記事はand factory.inc Advent Calendar 2022 25日目の記事です。
昨日は @yst_i の [Composeのテストを試す](https://qiita.com/yst_i/items/0cb13bf1f537b2c216e7) でした。

弊社では勉強会やスキルアップに積極的なエンジニアが多いです。
ですが、コロナ禍でエンジニアの交流が少なくなり、社内勉強会なども減っていき、もったいない、かつ社内交流も増やすために弊社では、毎月最終金曜日に『テクニカルフライデー』という社内エンジニアイベントを開催しています。
今回はその様子をお伝えします。

# テクニカルフライデーとは

社内エンジニアのスキルや我々のサービスを「研磨」するような時間です。

## 目的

コンセプトは **「学びは、現場の＆から」**

- 学んだ内容を共有することでエンジニア全体のスキル底上げを目指す
- 普段の業務から離れ自分の興味のあることを学ぶ機会を創出する
- 担当プロダクト以外のエンジニアとのコミュニケーションの場を作る

## 流れ

毎月丸1日（月末金曜日）は研究日にし、3ヶ月に1回の間隔で発表する方針にしました。
学ぶ内容は基本的には自由です。
今まで業務でやったことをアウトプットしたり、自分が興味あること、チャレンジしたいこと、業務効率化したいことなど。

![スクリーンショット_2022-03-15_15.08.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369939/be63630a-47ac-e3fb-9a01-9125e03a0e07.png)


### 研究-1,2月目
1,2月目は研究を行います。

各資料はNotionで管理しております。
Season毎のNotionページを作成し、そこに各エンジニアのカードを作っていただき、研究、発表資料として書き上げてもらいます。
大枠はフォーマットで固めてはいますが、書き方は自由です。

### 発表-3月目
3月目はZoomで発表を行います。

[Zoomのブレイクアウトルーム機能](https://support.zoom.us/hc/ja/articles/206476093-%E3%83%96%E3%83%AC%E3%82%A4%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88-%E3%83%AB%E3%83%BC%E3%83%A0%E3%82%92%E6%9C%89%E5%8A%B9%E5%8C%96%E3%81%99%E3%82%8B)を用いて、1グループ4−6名の少人数グループ毎の部屋を作成し、その中で各エンジニアの発表を行います。

発表は録画しており、後から見返すこともできるようにしています。
最近ではZoomを全社向けに展開して社員なら誰でも発表を見れるようにしています。

- 各エンジニアの持ち時間は30分
    - 発表20分
    - 質疑応答5分
    - buffer5分

![スクリーンショット 2022-12-20 10.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369939/f09d4078-4898-b7c2-e3fb-bb496fa58cd4.png)

# こんな発表がありました
今回で３期目に突入し、発表会の流れもブラッシュアップしつつ、
9月, 10月に研究した後、11月に第３回テクニカルフライデーの発表会を開催しました。

日頃の業務に関係のあることの学びを深める方もいれば、新しいことを学ぶ方もいるなど、多種多様な発表がありました。
また、最近入ったエンジニアには自己紹介してもらっています。

- プロジェクトの数値を使って数値検証
- Swift Concurrency超入門
- アプリの起動時間を計測してみる
- ユースーケースレベルのテストを書く
- 競技プログラミングとGo
- R言語で感情分析やってみる
- GAS scraiping
- Swiftでもっとアニメーションしたい

etc…

# 最後に
このイベントは社内でも好評をいただいておりまして、ぜひ今後も続けていこうとブラッシュアップして開催し続けています。