OmniAICreator/Qiita-1.07M huggingface dataset:
jQueryで改行が効かない <br>

## jQueryで改行ができなかった件について

## 修正後（改行できるようになった）
``` js:改行できる
var message = "この文は改行できます。" + "<br>" + "この文は改行できます。";
$('書き換えたいクラスやidなど').html(message);
```
``` :結果
この文は改行できます。
この文は改行できます。
```


## 修正前（改行できない）
``` js:改行できない
var message = "この文は改行できません。" + "\n" + "この文は改行できません。";
$('書き換えたいクラスやidなど').text(message);
```
``` :結果
この文は改行できません。この文は改行できません。
```

## 改行するために変更したこと
- 改行タグを `\n` から `<br>` にした
- `text()` ではなく `html()` にした

　
　
この記事は以下の情報を参考にして執筆しました。
- https://aoma23.hatenablog.jp/entry/js_nl2br
【Golang】ポインタまとめ

# 34 ポインタ
&(アンパサンド)はアドレスを持ってくる時に使用する。
*はポインタ型の変数だと明示する際に使用。
アドレスを格納したポインタ型の実体を参照する場合、ポインタ型の変数に*を付ける。

```go
package main

import "fmt"

func main() {
	var x int = 10
	var y *int = &x
	log.Printf("x: %v", x)   // x: 10
	log.Printf("x: %v", &x)  // x: 0x1400000ee10
	log.Printf("y: %v", y)   // x: 0x1400000ee10
	log.Printf("y: %v", *y)  // x: 10
}
```

```実行結果.go
10
0xc0000160c8
0xc0000160c8
10
```

```go
package main

import "fmt"

func increment(num *int) {
	// 824633794672
	fmt.Printf("num: %d\n", num)
	*num = *num + 1
}

func main() {
	value := 10
	fmt.Println("Before:", value)

	// ポインタを渡す
	increment(&value)

	// 824633794672
	fmt.Printf("&value: %d\n", &value)

	fmt.Println("After:", value)
}

```

```実行結果.go
Before: 10
num: 824633794672
&value: 824633794672
After: 11
```


# 36 struct
```go
package main

import "fmt"

type Vertex struct {
	X, Y int
	S    string
}

func main() {
	v := Vertex{X: 1, Y: 2, S: "ver"}
	fmt.Println(v)

	v4 := Vertex{}
	fmt.Printf("%T %v\n", v, v4)

	var v5 Vertex
	fmt.Printf("%T %v\n", v5, v5)

	// ポインタ
	v6 := new(Vertex)
	fmt.Printf("%T %v\n", v6, v6)

	// 推奨
	v7 := &Vertex{}
	fmt.Printf("%T %v\n", v7, v7)

	// スライス
	// 推奨
	s1 := make([]int, 0)
	fmt.Println(s1)

	s2 := []int{}
	fmt.Println(s2)
}

```
v4,v５の方法で制限するやり方と、v6,v7のやり方では違うものが宣言されているので注意。
ポインタとしての宣言方法はv7のほうが推奨されている(アンパサンドがついていてポインタを定義しているとわかりやすい)

同様にスライスも定義の仕方が複数あるが、s1のほうが推奨されている
※この講座自体少し前の情報のため変わっているかも

```go
package main

import "fmt"

type Vertex struct {
	X, Y int
	S    string
}

func changeVertex(v Vertex) {
	v.X = 1000
}

func changeVertex2(v *Vertex) {
	v.X = 1000
}

func main() {
	v := Vertex{X: 1, Y: 2, S: "ver"}
	changeVertex(v)
	fmt.Println(v)

	v2 := &Vertex{X: 1, Y: 2, S: "ver"}
	changeVertex2(v2)
	fmt.Println(v2)
}
```

```　実行結果.go
{1 2 ver}
{1000 2 ver}
```
### 構造体の値を書き換えたいとき
vはchangeVertex()の関数内でのみ変数が書き換わるが、mainには影響がない。
書き換えたい場合はv2のように、構造体を宣言する際にアンパサンド&をつける。
changeVertex2()を実行するときに渡しているのは、構造体が格納されているメモリのアドレスになる。
関数の引数にアスタリスクをつければ、渡ってきたメモリのアドレスから中身を参照することができるため、値を書き換える事ができる。
rails7でバリデーションエラーで画面が遷移しない場合の解決法

バリデーションエラーが起きた後、画面遷移せずにエラーメッセージも表示されなかったのでこれを解決するしました。

# 環境
Ruby 3.0.2
Rails 7.0.2.3

## 結論：~~Turboの動作をオフにする~~ `redirect_to`を使う

~~form_withに `data: { turbo: false }` を追加する~~

`render :new` としていた部分を `redirect_to action: :new`に変更したら解決しました。
バリデーションエラーは`flash`を使って取得しています。
```ruby: EventsController.rb
  def create
    @event = events.new(event_params)
    if @event.save
      flash[:success] = "#{@event.name}を登録しました"
      redirect_to @event
    else
      flash[:errors] = @event.errors.full_messages
      redirect_to action: :new
      # render :new だと動かない
    end
  end
```


## 発生していたエラー

バリデーションエラーが発生した際に、画面のリロードが発生せず、コンソールに以下のエラーが表示された。

```ruby
Error: Form responses must redirect to another location　at k.requestSucceededWithResponse
```

## 問題発生時のコード


```ruby: new.html.haml (≒ new.html.erb)
= form_with model: @event do |f|
  = f.label :name, 'イベント名'
  = f.text_field :name
```


```ruby: Event.rb
class Event < ApplicationRecord
  has_many :items
  belongs_to :user

  validates :name, presence: true
```


```ruby: EventsController.rb
class EventsController < ApplicationController
  before_action :authenticate_user!

  def new
    @event = Event.new
  end

  def create
    @event = current_user.events.new(event_params)
    if @event.save
      redirect_to action: :index
    else
      render :new
    end
  end

private

  def event_params
    params.require(:event).permit(:name, :event_datetime, :memo)
  end
...
```

## Turboって？

rails7からデフォルトで入っているGem

https://github.com/hotwired/turbo-rails

ざっくりですが、Javascriptを書かずに簡単にSPAを実現してくれる

## 参考
https://stackoverflow.com/questions/70400958/error-form-responses-must-redirect-to-another-location

https://turbo.hotwired.dev/handbook/introduction
jQueryのtext()とhtml()の違い

## text()について

text()は指定した要素のテキストノードを返す。
指定した要素に含まれる子孫要素のテキストノードすべてを結合して返す。
※ テキストノードは、「HTML 文書」や「XML 文書」の、タグ以外の文字データ
　

今回使用するhtmlの例
``` html:html
<div class="hoge">
  <div class="hoge1">hoge1です</div>
  <ul>
    <li>hogeの中の1個目</li>
    <li>hogeの中の2個目</li>
  </ul>
</div
``` 

このhtmlに対して
`$('.hoge').text();`
を実行すると、次のような結果になる。

``` :結果
hoge1です hoge1の中の1個目 hoge1の中の2個目
```


## html()
html()は指定した要素のHTMLを返す（指定した要素は含まない）

今回使用するhtmlの例
``` html:html
<div class="hoge">
  <div class="hoge1">hoge1です</div>
  <ul>
    <li>hogeの中の1個目</li>
    <li>hogeの中の2個目</li>
  </ul>
</div
``` 

このhtmlに対して
`$('.hoge').html();`
を実行すると、次のような結果になる。

``` :結果
<div class="hoge1">hoge1です</div>
  <ul>
    <li>hogeの中の1個目</li>
    <li>hogeの中の2個目</li>
  </ul>
```

## その他
html()やtext()で書き換えた文が存在するかどうかの確認。
自分がやった方法なので、他に方法にも方法はある。

```
console.log($('.hoge').text());
console.log($('.hoge').html());
```
　
　
　
この記事は以下の情報を参考にして執筆しました。
- https://www.koikikukan.com/archives/2012/09/05-015555.php
C言語はQiitaで学びたい

C言語を学習中の大学３年生です。
記事を初めて投稿させて頂く前は、主に質問・相談でお世話になっていました。

<details><summary>➀区切りスペースを入れるか否かで分岐する整数の文字列（クリックで表示）</summary>

```c
#include<stdio.h>

void sequence(int min,int max,int d){   //最小値=min，最大値=max，公差=d
	int current=min;   //現在値=current
	for(;current<=max;current=current+d){
		if(current==max){
			printf("%d",current);
		}else{
			printf("%d ",current);
		}
	}
	printf("\n\n");
}

int main(void){
	sequence(1,99,2);
	sequence(-100,0,2);
	sequence(10,150,10);
	return 0;
}
```
</details>

<details><summary>➁乱数生成のアルファベット版（クリックで表示）</summary>

```c
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void pwmaker(int x){
	int num;
	srand( time(0) );
	for(int m=0;m<x;m++){
		num=rand();
		if(num%20>9){
			char alp[]={"abcdefghijklmn"};
			printf("%c",alp[num%( sizeof(alp)-1 )]);
		}else{
			printf("%d",num%10);
		}
	}
}

int main(void){
	int a;   //生成する整数列の桁数
	scanf("%d",&a);
	pwmaker(a);
}
```
</details>

<details><summary>➂キレイに並び替えてABCDEにするゲームのプログラム（クリックで表示）</summary>

```c
#define MOJISIZE 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
char tbl[MOJISIZE];
char str[MOJISIZE];

void sequence(void);
int loading(void);
void change(int x);

int main(void){
	sequence();
	printf("%s\n",str);
	strcpy(tbl,str);
	int count=0;
	int isEnd;
	do{
		int a;
		do{
			a=loading();
			if(a>0&&a<=5){
				printf("OK input=%d\n",a);
			}else{
				printf("ERROR\n");
			}
		}while(a<1||a>5);
		change(a);
		printf("%s\n", tbl);
		count++;
		isEnd=strcmp(tbl,"ABCDE");
	}while(isEnd!=0);   //比較した２つの文字列が同じ内容であれば strcmpは0を返す
	printf("**%d回目で完成‼**",count);
}

//（sequence関数内）例えば文字列から「C」を選んだ場合、「C」以降のアルファベットを1つずつ前へ更新し、同時にsizeも1だけマイナスする
void sequence(){
	srand( time(0) );
	char alp[]={"ABCDE"};
	int size=MOJISIZE;
	for(int i=0;i<MOJISIZE;i++){
		int rdn=rand()%size;
		str[i]=alp[rdn];
		for(int j=rdn;j<size;j++){
			alp[j]=alp[j+1];
		}
		size--;
	}
}

int loading(){
	int n;
	printf("入力値：");
	scanf("%d",&n);
	return n;
}

//x-1番目とx番目の値を入れ替えるプログラム（change関数内）は、ここでは原則次のような流れで実装する（入力に文字列の最大サイズが来たときは注意）
//➀x-1番目の値を別の変数に一時退避
//➁x-1番目にx番目の値を代入
//➂x番目に➀で退避した値を代入
void change(int x){
	char temp=tbl[x-1];
	if(x==sizeof(tbl)){
		tbl[x-1]=tbl[0];
		tbl[0]=temp;
		return;
	}
	tbl[x-1]=tbl[x];
	tbl[x]=temp;
}
```
</details>

<details><summary>➃配列を引数として受け取るプログラム（クリックで表示）</summary>

```c
#include <stdio.h>
#define lengthof(array) sizeof(array)/sizeof((array)[0])

int sum(int num_array, int array[]){
	int num=0;
	int count=0;
	while(count < num_array){
		num=num+array[count];
		count++;
	}
	return num;
}

int main(void){
	int a[] = {3, 1, 4};
	int b[] = {15, 92, 65};
	int c[] = {358, 979, 323};
	
	printf("%d\n", sum(lengthof(a),a));
	printf("%d\n", sum(lengthof(b),b));
	printf("%d\n", sum(lengthof(c),c));
}
```
</details>

僕には、paizaやQiitaのような、分からない時に質問・相談して共有出来る環境があり、そのおかげで壁に当たっても挫折せずに乗り越えてきました。
**Cは全てのプログラミング言語の根幹をなす言語**と聞いているので、幅広い分野の情報処理に対応出来る可能性がある点、習って損はないかもしれません。しかし、大学生の折り返しを通り越したところで、まだCのスキルしかないのには焦りを感じたため、JavaやPythonにも触っていきたいと考えています。
記事を書いて投稿、とはいえ……まだインプット中の学生です。編集リクエスト大歓迎で、腰を据えてお待ちしています。
引き続き、よろしくお願いします。
【Golang】ステートメントまとめ

# 24 if文

```go
 if result2 := by2(10); result2 == "ok"{
    fmt.Println("great 2")
 }
```
result2の値をこの式以降使用しない場合は、セミコロン;をつなげて条件式を一行で書くことができる。

# 25 for文
```go
func main() {
    sum := 1
    for sum < 10 {
        sum += sum
        fmt.Println(sum)
    }
}
```
phpのようにfor文は書けるが、上記のように省略することもできる
初期値をforの前に定義、インクリメントは省略

# 26 range文
```go
func main() {
    l := []string{"Python", "go", "Java"}

    for i := 0; i < len(l); i++{
        fmt.Println(i, l[i])
    }

    for i, v := range l{
        fmt.Println(i, v)
    }
}

```
スライスの値を出力する際に使用する
上のようにfor文で一つ一つ出してもいいが、下のように変数のiとvを定義してrangeで添字とバリューを出力することもできる

```go
for _, v := range l {
		fmt.Println(v)
	}
```
iを使用しない場合はアンダースコアを使えば省略できる

# 28 defer
```go
deferはmain関数の処理がすべて終わった後に実行される
func main() {
    defer fmt.Println("success")
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    fmt.Println("mail send")
}

deferが複数ある場合は、下に書かれているdeferから順に実行される
```

# 34 ポインタ
```go
package main

import "fmt"

func main() {
	var n int = 100
	fmt.Println(n)
	fmt.Println(&n)

	var p *int = &n
	fmt.Println(p)
	fmt.Println(*p)
}

// 実行結果
100
0xc0000160c8
0xc0000160c8
100
```

アンパサンド&を使用すると、その値を確保しているメモリを参照できる。
メモリのアドレスを格納するときはポインタ型を使用する。*intの型で使用できる。
ポインタ型として定義した変数にアスタリスク*をつけることで、メモリのアドレスに格納されている値を取得することができる。
モバイルコンテンツのパターンの紹介 （UI/UXデザイン）

UI/UXデザインを勉強中なので、今回はモバイルコンテンツのパターンを書いてみたいと思います。私は元々グラフィックデザインをしていたので、見やすく、分かりやすく伝えることは意識していましたが、チラシ、ポスター、パンフレットなどは手に取って見る、ページをめくるという動作は当たり前のことなのでユーザーをどう誘導するかを意識させることはあまりありませんでした。
webの世界に来てみて、機能としては複雑化しているのでパッと伝えるということは難しく、携帯の機能やサイトの見方などを理解してもらった上で、サイトをみてもらう努力が必要なのでユーザーがストレスや負担にならないようにすることは必須なのだと感じています。
モバイルコンテンツのパターンをいくつか紹介します。



　
　
###### 01.階層タイプ
こちらは一般的な仕組みです。
ピラミッド構造になっており、インデックスページとサブページといった親子関係になっています。ユーザーのストレスにならないように階層は深くしない配慮が必要です。検索が必要なサービス、商品分類やニュース記事、FAQなどの大量の情報をまとめることに適していますが、ナビゲーションやステップが増えると逆にストレスになるので考慮する必要があります。
UIデザインとしてはナビゲーションが大事になってくるので、ナビゲーションを必要以上に増やさず、項目を整理してコンパクトにまとめる事が必要になります。
![kaiso.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106270/34bb93d9-28a2-065a-67cd-ac59a9768793.png)

　
###### 02.ハブ＆スポークタイプ
空港のように1つの起点（ハブ）を中央にコンテンツがあり、ポータルサイトを起点に他カテゴリと結びつけます（スポーク）。階層タイプではなく、独立した組織形態やリンク集コンテンツなどに使われます。ヤフーなどの情報系サイトがあります。
色々な機能をまとめる事ができ、独自のメニューが作りやすいです。
マルチタスクの場合は、スポーク間の行き来がしにくいことや戻るナビゲーションが機能しないとハブも機能しないことがあげられます。
![hab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106270/5e75be5d-ba16-35fa-8ef3-976da641726a.png)


　
###### 03.弁当箱タイプ
お弁当箱のように色々な情報を一つにまとめて一覧で見ることができるタイプです。アプリの最初の画面や天気、カレンダー、時計などが一覧で見れるスマホの画面が例として挙げられます。
色々な情報を一覧で一度に見る事ができるし、コンテンツに直接いける便利さがありますが、スマホよりもタブレットなどの大きな画面の方が適している点があります。
![bento.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106270/bbc2fcd9-24a7-79cf-6e80-f5b293844776.png)


###### デザインは「思いやり」
* * *
まだ新人だった時に、先輩にデザインは「思いやり」だと教わってきました。
媒体が変わっても機能が複雑になってもこの考え方は今後変わることはないと思うので、ユーザーが見やすい、分かりやすく、利用したいと思ってもらえるようにUI/UXデザインを勉強していきたいと思います。
選択問題の問題集を作成する

対象
---------------------------------------
オリジナルの問題集(選択問題)を作りたい人

使い方
---------------------------------------
**step1「作成」**
```python

import json

quizes = []
while True:
    question = input('問題を入力してください(nを入力すると終了します): ')
    if question == 'n':
        break
    a = input('選択肢 1: ')
    b = input('選択肢 2: ')
    c = input('選択肢 3: ')
    d = input('選択肢 4: ')
    answer = int(input('答えを1∼4で入力してください: '))
    quiz = {
        'question': question,
        'selections': [a, b, c, d],
        'answer': answer
    }
    quizes.append(quiz)

with open('quiz.json', 'w',encoding='utf-8') as f:
    json.dump(quizes, f, indent=4, ensure_ascii=False)

```

**step2「解く」**

```python

import random
import json

with open("quiz.json",encoding='utf-8') as f:
    quizes = json.load(f)
    random.shuffle(quizes)

print("START")
correct = 0
wrong = 0
for quiz in quizes:
    print(quiz["question"])
    for i, selection in enumerate(quiz["selections"], 1):
        print(f"  {i}: {selection}")
    your_answer = input(f"番号で回答してください(fを入力すると終了) ").strip()
    if your_answer == "f":
        break
    if your_answer == str(quiz["answer"]):
        print('◯')
        correct += 1
    else:
        print('×')
        wrong += 1

print()
print('結果:')
print(f'◯→{correct}')
print(f'×→{wrong}')
print(f'{(correct/(correct + wrong))*100}%')


```

作成した問題集をコピペで共有したりするのも良さそうですね！ご活用ください！

コメント大変勉強になります！
ありがとうございます！
TwitterでGoogle Apps Scriptの日本ユーザー向けコミュニティを作成

最近、Twitterに特定のテーマやトピックを扱うコミュニティ機能が普及し始めています。
そこで、Google Apps Scriptに関する日本ユーザー向けのコミュニティを作成してみました↓
[Google Apps Script日本ユーザーグループ](https://twitter.com/i/communities/1508964612414136323)

# Twitterコミュニティとは

Twitterコミュニティは2021年にリリースされた機能で、日本では2022年になって利用が増えてきているサービスです。
![20220330_auto_010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365005/11ab919c-a257-4e3e-8d04-d84ab799876a.jpeg)

スマホだと下部メニューの中央にある人のアイコンをタップするとコミュニティが表示されます。

特定のトピックに限定した投稿を行うコミュニティとなります。

まだ利用間もないサービスのため、使い方が定まっていない状態です。

ただ、タイムラインにフォローしているユーザーの多様なツイートではなく、特定ジャンルに絞った投稿をルールとすることで情報が集積しやすくなります。

# コミュニティ作成ユーザーは限定

2022年3月31日時点ではすべてのユーザーがコミュニティを利用できるわけではありません。

また、コミュニティに参加できるユーザーでも作成はできないユーザーもいます。

たまたま私は前述したスクリーンショットの通り、右上にコミュニティ作成の+アイコンが表示されていて、作成可能なユーザーでした。

# Google Apps Script日本ユーザーグループを作成

せっかくTwitterコミュニティの作成権限があるので、自分でコミュニティを作成してみようと考えました。

コミュニティの検索で調べたところ、Google Apps Script(GAS)のグループは英語圏のグループのみで、日本人ユーザーが作成したものはありませんでした。

そこで、Google Apps Script日本ユーザーグループのコミュニティを作成してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365005/e099f5a5-d197-955a-fbf9-b3c9e678a807.png)
[Google Apps Script日本ユーザーグループ](https://twitter.com/i/communities/1508964612414136323)

コミュニティの設定は「誰でも参加可能」なので、「参加する」をタップすればすぐに参加できます。

# GASに関する内容なら何でもOK!※直接営業・勧誘はNG

Twitterコミュニティにはルールを設けることができ、モデレーターはルールを決めることができます。

[Google Apps Script日本ユーザーグループ](https://twitter.com/i/communities/1508964612414136323)は心理的安全性を担保したコミュニティにできればと考えています。

そのため、GASを関連したテーマであれば、どんな投稿もOKとしています。

ただし、参加者が嫌がる直接の営業行為や勧誘についてはNGとしています。

また、GASを使おうとして分からなくて、挫折してしまう人も減らせればと思い、質問や相談も大丈夫です。

気軽に投稿しやすい空気で、参加者のGASの知識やノウハウが共有できるコミュニティにしていきたいです。

# GASを使っている方はぜひご参加ください！

まもなく年度が変わる2022年3月30日に[Google Apps Script日本ユーザーグループ](https://twitter.com/i/communities/1508964612414136323)を立ち上げましたが、すでに19人もの方に参加いただいています。

多くのGASを使っているユーザーが集まり、お互いのナレッジやノウハウを共有し、質問や困ったを解決することで、GAS利用が促進できればと考えています。

ぜひ、GASを使っていて、Twitterをされている方はご参加ください！

**[Google Apps Script日本ユーザーグループに参加する](https://twitter.com/i/communities/1508964612414136323)**
開発文書部のお仕事 2022年4月版

## 4月やりたいこと

### 予定

- 開発ガイド
- オンボーディング基盤完成。以下清書
    - [オンボーディング・クエスト式 開発者研修記事スクラップ](https://zenn.dev/e99h2121/articles/onboarding-quest-articles)
    - [オンボーディング時に読んでほしい！開発者記事スクラップ](https://zenn.dev/e99h2121/articles/onboarding-good-articles)
- イベント観戦
    - https://day-one-2022-spring.cto-a.org/
    - https://wtm-tokyo.connpass.com/event/241705/
- 人事と採用協力
    - Twitterアカウントを... 


### 小さいこと
- 日次
    - times確認
    - twitter確認
    - はてブ定時確認
- 月次
    - ローカル開発環境セットアップ、起動確認
    - Wiki確認
    - 社内規定的な読みもの確認





## 3月やったこと

### 新人さんを迎え入れる準備

- [オンボーディング・クエスト式 開発者研修記事スクラップ](https://zenn.dev/e99h2121/articles/onboarding-quest-articles)
- [オンボーディング時に読んでほしい！開発者記事スクラップ](https://zenn.dev/e99h2121/articles/onboarding-good-articles)
- [新人さんにすすめる有益なツール達 2022春 - Qiita](https://qiita.com/e99h2121/items/f70db44e7f69901f0141)

### 曼荼羅のお絵描き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/80a42e0e-c0be-82a3-9bdd-e42e6a5cfc5b.png)

### 色々
- 部署全体MTG
    - チャンネル作成
    - タイムキーパー
    - 司会
    - 実況チャンネルのガヤ
- BIG BOSSの分報を賑やかにした
    - 社内 times 上で最もリアクション数の多いチャンネルに成長。
- 各チーム長と順番にリモート飲み開始
- 業務改善
    - [古の「報告書の書き方」資料に引用されていた10年前の記事が良い - Qiita](https://qiita.com/e99h2121/items/cab02ca9f0cb8556ae28)
    - [合法的時間確保への誘い - 朝のもくもく会を続けている話 - Qiita](https://qiita.com/e99h2121/items/9e5444858d107afdf7a2)
- 読書
    - [「カスタマーサクセスとは何か 日本企業にこそ必要な『これからの顧客との付き合い方』」を読んで、ソフトウェア開発に活きると思ったヒントの要点](https://zenn.dev/e99h2121/articles/customer-success-red)
    - [「良いFAQの書き方」を読んだので、その要点 - Qiita](https://qiita.com/e99h2121/items/1b713a24167b862d726c)
    - [「メンタリング入門」を読んだので、その要点 - Qiita](https://qiita.com/e99h2121/items/734d0ff0148a11b0f0f1)
    - [「ソフトウェアアーキテクチャの基礎」を読んだので、その要点 - Qiita](https://qiita.com/e99h2121/items/1844f5ed8da453a6dfb0)
- 情報収集
    - [「第一回プログラミング教育について話し合う会」に参加したので、その感想 - Qiita](https://qiita.com/flyaway/items/8a40f3bbd0b6bf54f9c2)
    - [「第一回プログラミング教育について話し合う会」をながら視聴したので、その資料など - Qiita](https://qiita.com/e99h2121/items/8adccec78cd757bbda59)
    - [「『ドメイン駆動設計』のススメ - 100日でエヴァンス本を完読したしょぼちむとふりかえる」を視聴したので、その記録 - Qiita](https://qiita.com/e99h2121/items/de450e9a643947b07c3c)


## 感謝

https://qiita.com/satomihoya/items/27b0386ce9ffb25f2fd3

## 以上

- [開発文書部のお仕事 2022年1月版 - Qiita](https://qiita.com/e99h2121/items/b83423a07c975b349f3a)
- [開発文書部のお仕事 2022年2月版 - Qiita](https://qiita.com/e99h2121/items/6ce238b6b53749b7e7d9)
- [開発文書部のお仕事 2022年3月版 - Qiita](https://qiita.com/e99h2121/items/b5f1e5cb9717ad86a65d)

に続き 4月のお仕事掲示です。
どうぞ宜しくお願いいたします～
【PHPUnit + Laravel】認証できていない状態をテストするとUnauthenticatedエラーが発生する場合の対策

# 概要

ログインしていない場合に`401`ステータスが返ってくることをテストすると以下のエラーが発生したので対応法を紹介する

## エラーログ

```bash
Illuminate\Auth\AuthenticationException : Unauthenticated.
```

## テストコード

```diff:UserControllerTest.php
<?php

class PartnerControllerTest extends TestCase
{
    use RefreshDatabase;

    public const INDEX_PATH = 'admin/users';
    
    protected function setUp(): void
    {
        parent::setUp();

        // POST時に419エラーが発生するのでCSRFミドルウェアを無効にする
        $this->withoutMiddleware([VerifyCsrfToken::class]);

        // 詳細エラー取得
        $this->withoutExceptionHandling();

        // テストデータを作成
        $this->authUser = factory(User::class)->create();
    }

    public function test_NG_ログインしていない場合はアクセスできない()
    {
        $response = $this->get(self::INDEX_PATH);
        $response->assertStatus(401);
    }
}
```

# 対応方法

以下を追加する

```php
$this->expectException(AuthenticationException::class);
```


```php:UserControllerTest.php
<?php

class PartnerControllerTest extends TestCase
{
    use RefreshDatabase;

    public const INDEX_PATH = 'admin/users';
    
    protected function setUp(): void
    {
        parent::setUp();

        // POST時に419エラーが発生するのでCSRFミドルウェアを無効にする
        $this->withoutMiddleware([VerifyCsrfToken::class]);

        // 詳細エラー取得
        $this->withoutExceptionHandling();

        // テストデータを作成
        $this->authUser = factory(User::class)->create();
    }

    public function test_NG_ログインしていない場合はアクセスできない()
    {
        $this->expectException(AuthenticationException::class);
        $response = $this->get(self::INDEX_PATH);
        $response->assertStatus(401);
    }
}
```
100日でSQLの達人になる@LeetCode! Day59 <ORDER BY句で使えるOFFSET-FETCH句>

## ORDER BY句で使えるOFFSET-FETCH句について理解する
前回に引き続き[LeetCode](https://leetcode.com/)の問題はお休み。
しばらく[LeetCode](https://leetcode.com/)の方はお休みしましたが、そろそろ問題の方に戻ろうと思います。
今回のテーマは前回よりは簡単です。
ただコマンドに`FETCH`と出てくるので前回の`CURSOR`の話と混同しやすいため要注意。

### 構文
```:SQL
GROUB BY句の中で
　　　　OFFSET　０以上の整数（式も可）　ROWS
　　　　FETCH NEXT　１以上の整数（式も可、FETCHは省略可）　ROWS ONLY
```
これで、先頭から`OFFSET`で指定した行分スキップし、`FETCH`で指定した行分取得します。
指定する場合は`ROWS`や`ONLY`も忘れずに記載が必要。

前回同様に[db<>fiddle](https://dbfiddle.uk/?rdbms=sqlserver_2019)を使います。

### 実行例

下記が実行例です。
<!-- -->
>     CREATE TABLE tbl (id INT)
>     DECLARE @num INT =1
>     
>     WHILE @num <= 50
>      BEGIN
>       INSERT INTO tbl (id) VALUES(@num)
>          SET @num=@num+1
>      END
>     -- ここまでで合計50行の行番号のみ入ったテーブルが出来ています。
>     
>     --使用例１
>     SELECT id FROM tbl
>      ORDER BY id
>      OFFSET 20 ROWS
>      FETCH NEXT 10 ROWS ONLY
>      
>      --使用例2
>     SELECT id FROM tbl
>      ORDER BY id
>      OFFSET 45 ROWS;
>      
>      --使用例3
>     SELECT id FROM tbl
>      ORDER BY id
>      OFFSET 45 ROWS
>      FETCH NEXT 20 ROWS ONLY
>    
> 
> <pre>
> | id |
> | -: |
> | 21 |
> | 22 |
> | 23 |
> | 24 |
> | 25 |
> | 26 |
> | 27 |
> | 28 |
> | 29 |
> | 30 |
> 
> | id |
> | -: |
> | 46 |
> | 47 |
> | 48 |
> | 49 |
> | 50 |
> 
> | id |
> | -: |
> | 46 |
> | 47 |
> | 48 |
> | 49 |
> | 50 |
> </pre>

*db<>fiddle [here](https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=44a0615c6edbbe7ad4ddb5d1dd092db6)*

使用例２では`FETCH句`を省略していますが、後ろ全部を表示しています。
使用例３では`FETCH句`で２０行指定していますが５行しか無いため５行分のみ表示しています。

今日のポイントは`ORDER BY句でOFFSET, FETCHを使って表示する行数をコントロールする`とした。
CognitoのユーザIDを取得（Amplify, Android）

# Amplifyで認証完了後に実行
```kotlin:
    Amplify.Auth.currentUser.userId
```

# 実装例
```kotlin:
    // session確認
    Amplify.Auth.fetchAuthSession(
        {
            // Sessionがある場合
            var userId = Amplify.Auth.currentUser.userId
            binding.userId = userId
        },
        {
            error -> Log.e("AmplifyQuickstart", "Failed to fetch auth session", error)
        }
    )
```
WindowsでminicondaとJupyterを導入する方法

# 前書き
miniconda と Jupyter を入れるときのメモです。

# 環境
Windows 10
Miniconda3

# 導入方法
## Minicondaを入れる
[https://docs.conda.io/en/latest/miniconda.html:embed:cite]

好きなバージョンをインストール。
![スクリーンショット 2022-04-01 025338.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106884/7f34ea3a-067a-a378-5ab0-db8907a44fd4.png)

再起動して環境変数にパスを通す。
ユーザー環境変数ならエクスプローラーを再起動するだけで良い。

## コンソールを開く
<code>Anaconda Prompt (miniconda3)</code>を開く

## パッケージの一覧を見る
<code>conda list</code>で一覧を見られる。

## パッケージを入れる
<code>conda install xxxxx</code>を使って好きなパッケージを入れる。
<code>xxxxx</code>はパッケージ名。
個人的には<code>numpy</code>と<code>matplotlib</code>は必須。

# Jupyterを入れる
## Jupyterをインストール
<code>Anaconda Prompt (miniconda3)</code>で<code>pip install jupyter notebook</code>でインストール。

## ipykernelをインストール
そのままでは python にアタッチされないので<code>conda install notebook ipykernel</code>でインストール。

## Jupyterを開く
<code>Anaconda Prompt (miniconda3)</code>から<code>jupyter notebook</code>と打って起動。

# おまけ
minicondaを入れたけど直接 python 起動させる場合、<code>python</code>と打ち込むと windows store が開くので<code>py</code>で開く。

# 参考文献
https://dev.classmethod.jp/articles/difference-between-anaconda-and-miniconda
https://qiita.com/kawada2017/items/626a80ed5bbfdc2576a5
https://qiita.com/Ringa_hyj/items/0d8193925fbf4e53a113

# 引用元
https://eorf.hatenablog.com/entry/2022/04/01/035413
100日でSQLの達人になる@LeetCode! Day58 <要復習：CURSOR, FETCHの使い方>

## CURSORの使い方について理解する
前回に引き続き[LeetCode](https://leetcode.com/)の問題はお休み。
しばらく[LeetCode](https://leetcode.com/)の方はお休みしましたが、そろそろ問題の方に戻ろうと思います。
今回のテーマは`CURSORの使い方`です。ただ、テーマが重いので今回はサラッと学習してまた復習したいと思います。

前回同様に[db<>fiddle](https://dbfiddle.uk/?rdbms=sqlserver_2019)を使います。

### 今回、まずは理屈よりも基本的な使い方の例を先に示すことにします。

下記が実行例です。
<!-- -->
>     -------------------------------
>     -------------------------------
>     -- オリジナルデータの準備
>     CREATE TABLE tbl1 (id INT)
>     DECLARE @num INT =1
>     
>     WHILE @num <= 10
>      BEGIN
>       INSERT INTO tbl1 (id) VALUES(@num)
>          SET @num=@num+1
>      END
>     -- ここまでで合計10行の行番号のみ入ったテーブルが出来ています。
>     
>     SELECT id, 
>     ABS(CHECKSUM(RAND(id)) % 3) + 1 AS rnd
>     INTO tbl2
>     FROM tbl1
>     -- rndには1,2,3の値のどれかがランダムに入ります
>     -------------------------------
>     -------------------------------
>     
>     BEGIN TRANSACTION
>     BEGIN TRY
>     
>     -- 新しくテーブルを作成するための準備
>     CREATE TABLE tbl3 (id INT, originalid INT, num INT)
>     
>     -- カーソルの値を取得する変数を宣言
>     DECLARE @nid int =1
>     DECLARE @id int
>     DECLARE @rnd int
>     
>     -- カーソルを定義
>     DECLARE cur SCROLL CURSOR  --SCROLLを指定しないとFETCHでNEXTのみしか扱えない
>     FOR SELECT id, rnd FROM tbl2
>     
>     -- カーソルのオープン
>     OPEN cur
>     
>     -- 最初の1行を取得し変数へ値をセットする
>     FETCH NEXT FROM cur INTO @id, @rnd
>     
>     -- データの行数分ループ処理を実行する　@@FETCH_STATUSは最終行まで来て読み込めなくなると-2になる。
>     WHILE @@FETCH_STATUS=0
>     BEGIN
>     
>     -- 実際の処理はここから
>     INSERT INTO tbl3 VALUES(@nid, @id, @rnd)
>     FETCH ABSOLUTE @nid FROM cur INTO @id, @rnd　 -- FETCH RELATIVEを実行するとカーソル位置も変わるためリセット
>     -- 実際の処理はここまで
>     
>     -- あまり良い例では無いが、現在のカーソルの注目している行のrndの値を見て、その分だけ進んだ行のデータを取ってくる
>     FETCH RELATIVE @rnd FROM cur INTO @id, @rnd　
>     SET @nid = @nid + 1
>     END
>     
>     -- カーソルのクローズ
>     CLOSE cur
>     DEALLOCATE cur
>     END TRY
>     
>     -- エラーをキャッチした場合
>     BEGIN CATCH
>     CLOSE cur
>     DEALLOCATE cur
>     
>     ROLLBACK TRANSACTION
>     SELECT  ERROR_NUMBER()    AS errornumber
>            ,ERROR_SEVERITY()  AS errorseverity
>            ,ERROR_STATE()     AS errorstate
>            ,ERROR_PROCEDURE() AS errorprocedure
>            ,ERROR_LINE()      AS errorline
>            ,ERROR_MESSAGE()   AS errormessage;
>     RETURN
>     END CATCH
>     
>     COMMIT TRANSACTION
>     
>     -- もともとのテーブルを表示
>     SELECT * FROM tbl2
>     
>     -- 今回のCURSORを使った結果作成できた表の表示
>     SELECT * FROM tbl3

>     GO
> 
> <pre>
> id | rnd
> -: | --:
>  1 |   2
>  2 |   2
>  3 |   3
>  4 |   3
>  5 |   1
>  6 |   2
>  7 |   1
>  8 |   1
>  9 |   3
> 10 |   3
> 
> id | originalid | num
> -: | ---------: | --:
>  1 |          1 |   2
>  2 |          3 |   3
>  3 |          4 |   3
>  4 |          6 |   2
>  5 |          7 |   1
>  6 |          6 |   2
>  7 |          8 |   1
>  8 |          8 |   1
>  9 |          9 |   3
> </pre>

*db<>fiddle [here](https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=4b9b9833aeb2cd1f212c8d3afb491b54)*

今日のポイントは`CURSORを使うと1行1行データにアクセスして処理が可能`とした。
1次元 bit dp

```c++
int N, M, A[101010];
int cnt[20];
int dp[1 << 20];
int rui[20][101010];

int main() {
	cin >> N >> M; //数、種類の数
	rep(i, 0, N) {
		cin >> A[i]; //種類の順
		A[i]--;
		cnt[A[i]]++; //各種類の個数
		rui[A[i]][i] = 1; //種類、順番(累積和)
	}
	//累積和
	rep(a, 0, M) rep(i, 1, N) rui[a][i] += rui[a][i - 1];//種類、i番目

	rep(msk, 0, 1 << M) dp[msk] = inf; //1: 計算済み
	dp[0] = 0;

	rep(msk, 0, 1 << M) {
		int done = 0; //計算済みの種類の総個数

		rep(i, 0, M) if (msk & (1 << i)) done += cnt[i];

		rep(nxt, 0, M) if (!(msk & (1 << nxt))) {
			int tot = dp[msk]; //計算済みの種類の変更が必要な数
			
			//rep(i, done, done + cnt[nxt]) if (A[i] != nxt) tot++;
			int nxt_cnt = rui[nxt][done + cnt[nxt] - 1]; //種類(nxt)の最後の場所(累積和)

			//続きのスペースの場所にあるnxtの個数
			if (0 < done) nxt_cnt -= rui[nxt][done - 1]; //種類(nxt)の最初の場所を引く(累積和)

			tot += cnt[nxt] - nxt_cnt; //移動が必要なnxtの個数を足す

			chmin(dp[msk + (1 << nxt)], tot);
		}
	}

	cout << dp[(1 << M) - 1] << endl;
}
```
[Laravel]クエリビルダのwhereinで変数を呼びたい時の解決法

## 内容
Laravelのクエリビルダで

```php
->whereIn('user.id', [1,2,3,4]);
```

上記のような時はそのまま簡単にできるのですが、

```php
$hogeIDs = [1,2,3,4,5];

->whereIn('user.id', function ($query){
  //サブクエリで何かしている
  //$hogeIDsをここで使いたい
});
```

この場合だと、ただ変数を呼ぶのでは

```php
Undefined variable '$hogeIDs'
```

となってしまいます。
そうなった場合は

```php
$hogeIDs = [1,2,3,4,5];

->whereIn('user.id', function ($query) use($hogeIDs){
  //サブクエリで何かしている
  //$hogeIDsが使える！
});
```

useで読んであげることにより使えることができます。

https://stackoverflow.com/questions/16815551/how-to-do-this-in-laravel-subquery-where-in
PinePhone ProにTow-Bootを入れようとしてハマった

# はじめに

仕事でお世話になった方からPinePhoneProをいただいたので遊んでいます。
日本語の情報が少なすぎてなかなか大変です。

で、公式サイトを見ていると、Tow-Bootを入れろ的なことが書かれていたのでチャレンジしたらハマりましたｗ

# ハマった状態
こんな感じでエラーが出ました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これは…やばいか？ <a href="https://t.co/KrRhtBkNJ8">pic.twitter.com/KrRhtBkNJ8</a></p>&mdash; ᴛᴀᴋᴀ@浜松/ᴋʀᴏʜɪɢᴇᴡᴀɢᴍᴀ (@project_dev_tk) <a href="https://twitter.com/project_dev_tk/status/1509566800941395972?ref_src=twsrc%5Etfw">March 31, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

一応、これ、[公式のドキュメント](https://tow-boot.org/devices/pine64-pinephonePro.html)に書かれた指示に従ってやってます。
仕方がないのでググったら以下のURLの記事に出合いました。
https://forum.pine64.org/showthread.php?tid=16114&pid=107173#pid107173

# 解決方法
見つけた記事を見ると、REボタンとボリューム-ボタンを同時押しで電源を入れると書かれている。
で、やってみたら・・・できた！
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">REボタンとボリューム-押しながら電源入れてやったらできた。ドキュメントに書いてない手順… <a href="https://t.co/GbH8rAmCCW">pic.twitter.com/GbH8rAmCCW</a></p>&mdash; ᴛᴀᴋᴀ@浜松/ᴋʀᴏʜɪɢᴇᴡᴀɢᴍᴀ (@project_dev_tk) <a href="https://twitter.com/project_dev_tk/status/1509569810786529280?ref_src=twsrc%5Etfw">March 31, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
(あ、ツイートってコメントだけにならないんだ・・・orz)

# おわりに
どう使うかまだ決めてませんが、いろいろOSを試しながら考えようと思っています。
しかし、なんか動作がちょっと安定しないんだよなぁ・・・
社会人一年目振り返り

# はじめに
はじめまして。
私は大学卒業後、大阪に一人暮らししながらとある小さいソフトウェア開発企業で働いています。
社会人になって、１年が経ちました。

この界隈に仲の良い人とかいるわけでは無いですが、情報発信のウォーミングアップがてら何か投稿してみようかなと思った次第です。
今、就活中の方とかにとって何かしらのヒントになれたらと思ってます。
これをきっかけに技術的な話が出来る知り合いとか出来たら嬉しいですね。


# 今の会社で働くことになった経緯
大学卒業後、大学院に進む選択肢もあったのですが（実際に周りの人は８割程度院に進んでる）、私は大学院で２年過ごすよりも実務経験を積んだ方が技術的にも成長できるかなと考えていたため、就職を選びました。
大学では情報系を専攻していたため、それに関連した企業を選ぶのはごく自然な事ではあるのですが、「若いうちの苦労は買ってでもしろ」などと言った古い(と言われる)考え方に肯定的という事もあり、仕事量が多く成長が見込めそうな中小企業で働こうと考え、今の企業を選びました。


# 「成長できる仕事」が多いわけでは無かった
３か月ほどの研修を終え、最初のプロジェクトではかなり色々な経験をさせてもらいました。
ソフトの設計から仕様書の作成、実装までを担当させてもらい、上司にレビューしてもらっては直してを繰り返しながら、仕様書の書き方やコーディング技術、その他にも様々な知識が身について行くのを実感できました。
１年前に自分が書いたコードを読んでみると寒気すらしてきます。
１月末あたりになると、そのプロジェクトもひと段落し、別のプロジェクトに携わることになるのですが、そこで担当したのがソフトのデバッグでした。
どうやら人手が足りないようでその業務をすることになったわけですが、内容としては「バイトを雇った方が良いんじゃないか？」とも思えるような、単純だけど面倒な作業。

この辺りから、仕事について「思ってたのと違う」と言う感情を抱くようになりました。

中小企業が、「新人でも任せてもらえる仕事が多い」と言ったイメージは間違いではありませんでした。
（大企業が実際どのような感じなのかは知りませんが）
ただ、それは「人手が足りない」故、任せてもらえる仕事が多いという話であり、それが自分にとって成長できる仕事であるわけではありませんでした。
社長からはよく「君は出世する」みたいな話はされますが、正直給料がめちゃくちゃ高くなる見込みも無いので、この会社で出世するメリットをあまり感じていないですし、同じ「成長が見込めない仕事」をやるならもっと頑張るメリットがある所で働くべきだなと、そんな事を感じています（「成長できる仕事」が出来るのが一番ですが）。
「石の上にも三年」と言う「今は古い」と言われる考え方がありますが、私はこの言葉はけっこう正しいと思っています。
それでもやはり石は選ぶべきですね。

選び方は未だに分かんないっピ..


# 新卒カードは大事に
私はセキュリティが好きで、休日とかはよくその勉強をしています。
今はCTFを始めようと思って勉強中です。
そんなこともあり、最近は「セキュリティエンジニアに転職したいな」とか考えるようになりました。
少し転職サイトとか見ているのですが、中途採用になるとどうしても「脆弱性診断の経験あり」などと言った条件が加わり、企業に応募してみても「実務経験が求めているスキルと若干異なる」と言った理由で書類選考の時点で弾かれるので、自分が勉強していることや知識などのアピールをする場も設けてもらえません。

強すぎたな、新卒カード..

んでもって大体のケースで新卒カードの強さに気付くのは働いてからなんですよね。

自分が求める労働条件を探すために一回働いてみないといけないシステム何とかならんのか..？


# 今後について
取り敢えず今の仕事を続けながら、引き続き転職先はぼちぼち探して行こうかなと思ってます。
履歴書に書けるスキルが欲しいのでセキュマネでも取りますかね..
資格の取得手当とかも無く、飲みの席で「プライベートでちょっと勉強とかしてる」って話をすると社長が「本買って満足してるだけでしょ」と返してくるような環境にズルズルと長居して腐るようなことだけは避けたいですね。
XubuntuのWorkspaceでWindowsのWin+tabに似たことをする

調べた限り、WindowsのWin+tabと同じ機能ではなさそう。


`Panel`を開いて、`Workspace switcher`を利用中のパネルに追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/38163fd6-74dc-6933-8a9f-3252b33d882c.png)

パネルにワークスペースのどこにいてどこでどのアプリが起動しているか直感的にわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/ad8ea957-c5cb-c1b1-8135-d879502ebacc.png)

アプリケーションを他ワークスペースに移す場合は、GUIだとあれなので、ショートカットでできるようにしておくとよい。
設定は、`Windows Manager`でやる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/0768ec40-4270-9aba-7463-09901ba0a5dd.png)

そうすると、Win+Tab相当の機能がなくても、不便しないということに気が付きました。
さくらのモノプラットフォームのデータをNode-REDで取り出す方法

さくらのモノプラットフォームを使用してIoTの通信試験をしてみたりしているのですが、
プラットフォーム側で受信したデータを簡単に取り出す方法がわからないという話を聞きましたので、自分がやってみた方法を簡単にまとめてみます。

#### 使用するもの
M5stack
開発用PC
[モノプラットフォーム開発キット](https://iot.sakura.ad.jp/request_platform_devkit/)（申し込むと提供してもらえるそうです）

#### 開発環境
Arduino IDE
Node-RED環境

#### 実際の手順
今回はpayloadの取り出しがメインになりますので、Arduino IDEとM5stackの使用ができることを前提に説明していきます。
###### ハードウェアのファーム
M5stackのファームウェアについては[サンプルスケッチ](https://github.com/sakura-internet/sipf-std-client_sample_m5stack)をそのまま使用します。
サンプルスケッチを書き込んでブートさせた後にAボタンを押すとデータ送信をします。
このように、M5stackの画面とモノプラットフォームのコンソールでデータが送信できていることを確認できます。
![モノプラ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/7479b36e-1eff-2749-0327-e0152cb549ba.jpeg)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/0b3d8773-ec5c-551f-4bbf-7f4ba416b4a0.png)

###### 受信用のNode-RED
次にNode-RED側の準備を行います。
安価なVPSを用意してもいいのですが、今回はローカルでやることにします。
Node-REDの環境を用意する必要がある人は[こちら](https://qiita.com/shinfrom/items/e5ecf1ac68f5f0b7118f)を参考に用意してください(Node-REDのインストールだけで大丈夫です)。


実際のフローはこのような感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/5f381732-ee89-b1a8-7dd7-0405b5532d07.png)





処理の流れから説明していきます。
まずはwebソケットの受信用のノードを用意します。
ノードの中の設定は、種類を待ち受け、パスにはモノプラットフォームのコントロールパネルで発行されたものをコピペします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/59c44b27-88f5-6002-f0c6-d8fa447cab31.png)
wss://api.sakura....というものが発行されますので、パスを表す「/」もつけるようにしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/09530f89-8261-0de9-62f0-5acb2cb9939b.png)

次にNode-REDで扱いやすいようにJSONに変換します。これはJSONノードを接続するだけで簡単に行えます。
動作はJSON文字列とオブジェクト間の相互変換を選択しておいてください(おそらくデフォルトです)。

webソケットでデータを受信できるようになっているのですが、webソケットの死活監視のためのkeep alive情
keep alive情報は
```json
{
  "type": "keepalive",
  "timestamp": "2022-03-31T12:38:21.039Z"
}
```
のようなJSONで入ってきます。今回はこの情報は使用しませんので、JSONオブジェクトの中にkeep aliveという情報がある場合は、はじくようにします。
switchノードを用意して、プロパティにmsg.pauload.typeを指定します。
条件は **!= keepalive**にしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/a8fd9e16-7342-4319-b183-0fc613c91b03.png)
これで必要な情報だけが次のノードに流れていくようになりました。

流れてきた情報から実際に必要な情報(payload)を取り出します。
ここではfunctionノードの中にJavascriptを書いてパースする必要がありますが、Node-REDですので最低限の記述で済みます。
functionノードの中の記述はこのようになります。

```javascript
var value = msg.payload.payload[0].value
msg.payload = {
    value
}
return msg;
```
これだけでpayloadのデータが取り出せます。

確認用のdebugノードを用意します。
後はノードをつなげてデプロイします。
これでpayloadのデータが取り出せるようになりました。

#### 感想とappendix
サンプルスケッチとNode-REDを使用することで比較的簡単にLTE通信の試験をすることができます。
なので概念実証までは一気にできるのかなと感じます。
ファイルの送信等もできるようになったみたいですので、近いうちに試してみたいと思います。
実際にセンシングしたデータをどのようにpayloadに詰め込んで(encode)、クラウド側で使用できるようにするのか(decode)なども要望があれば書いてみます。

#### 参考情報
[M5stackを利用してさくらのモノプラットフォームとhacobuneを使ってみました](https://qiita.com/shinfrom/items/964ea29f7a2dd3d8b042)
[LINEボットのローコード開発環境をローカルPC上に構築する方法](https://qiita.com/shinfrom/items/e5ecf1ac68f5f0b7118f)
[公式ドキュメント](https://manual.sakura.ad.jp/cloud/iotpf-beta/getting-started/gs-scom5snrf9160-beta.html)
[公式github](https://github.com/sakura-internet/sipf-std-client_sample_m5stack)
正規表現

・PHPにおける正規表現
PHPではフォームのチェックやインポートデータの確認など、ユーザがWebから入力した何かのチェックに使うことが多い。

・基本的な正規表現
「^」 - 行頭にマッチする。 例：^hello - 行頭にhelloの文字列はこのパターンにマッチする。
「[]」- 角括弧内の任意の1文字にマッチする。例1：[abc] - aかb、cはこのパターンにマッチする。
 - 例2，r[aeu]d。radやred、rudはこのパターンにマッチする。
「[A-Z]」 - 英大文字A-Zの任意1文字にマッチする。例：a[A-Z]c - aAc，aBc，…，aZcなどの文字列はこのパターンにマッチする。
「[a-z]」 - 英小文字a-zの任意1文字にマッチする。例：a[a-z]c - aac，abc，…，azcなどの文字列はこのパターンにマッチする。
「[0-9]」 - 数字0-9の任意1文字にマッチする。例：a[0-9]c - a0c，a1c，…，a9cなどの文字列はこのパターンにマッチする。
「a|b」 - aまたはbにマッチする。例：hello|world - helloまたworldはこのパターンにマッチする。
「()」 - グループ化。()内のパターンは（グループ）と見なされる。このグループに一致する文字列を記憶する。1,2..などの数字によるグループへのアクセスできる。

・「()」の種類

・他の正規表現の一部として利用する
例:(red|white|yellow)手袋  
これはred手袋、white手袋、yellow手袋のいずれかにマッチする。「|」は複数の選択肢のいずれかにマッチさせる場合に利用する

・正規表現の有効範囲を指定する機能
例:php(man)?  
これはphpかphpmanのいずれかにヒットする。
manを一括りにした正規表現としてあらわしており、これをグループ化と呼ぶ。

・PHPの正規表現エンジンではPCREを主に使う。
PCRE正規表現を扱う関数はpregで始まる。*pregではUTF-8のみ使用可能
・UTF-8以外の対処法
mb_ereg系と呼ばれるものだ。文字コードがUTF-8以外のマルチバイト文字列に対して正規表現を行いたい場合は、こちらを利用しよう。

・構文
・デリミタ
記述したパターンはデリミタで囲む必要がある。一般的には / （スラッシュ）を利用することになる。

・メタ文字

正規表現でパターンを表す為の特殊な文字をメタ文字と呼ぶ。

主に下記の通り。
\ - 多目的に使う一般的なエスケープ文字

^ - 検索対象（複数行モードでは行）の始まりを言明

$ - 検索対象の終わりあるいは終端の改行文字の前（複数行モードでは行の終わり）を言明

. - 改行を除くすべての文字にマッチ（デフォルト時）

[ - 文字クラス定義の開始

] - 文字クラス定義の終了

| - 選択肢の開始

( - サブパターンの開始

) - サブパターンの終了

? - ( の意味を拡張／0 または 1 回マッチ／なるべく少ない回数だけマッチ

* - 0 回以上の繰り返し

+ - 1 回以上の繰り返し

{ - 最小／最大を指定する量指定子の開始

} - 最小／最大を指定する量指定子の終了

・preg_matchの書式
  preg_match(/正規表現パターン/,検索対象の文字列,[配列],[動作フラグ],[検索開始位置])

・preg_matchの返り値
パターンにマッチした場合は1を返し、マッチしなかったら0を返します。

・正規表現パターン
「正規表現パターン」でマッチさせたいパターンを指定します。正規表現は/で囲んで記述します。
/正規表現パターン/の最後にアルファベットのiを記載することで、大文字、小文字を区別せずに検索します。

・検索対象の文字列
「検索対象の文字列」では、正規表現でマッチさせる対象文字列です。

・配列
「配列」を指定した場合は、検索結果が配列として代入されます。

・動作フラグ
「動作フラグ」で「PREG_OFFSET_CAPTURE」を指定すると、マッチした文字列の登場した位置（オフセット）をバイト数で取得できます。

・検索開始位置
「検索開始位置」では、先頭ではなく検索を始めたい位置を指定できます。
ただし、指定はバイト数なので注意が必要です。


間違いやアドバイスなどあれば遠慮なく言ってください

参考文献：

https://eng-entrance.com/php-regularex

https://techacademy.jp/magazine/11402
IntersectionObserverクラスで画面をスクロールした時、要素をふわっと出現させる。

#はじめに
ホームページなどでよく見る、下にスクロールさせると下からふわっと画像が出現するようにするにはどうすれば良いのか気になったので調べてみました！

#コード紹介&解説

このような物を作っていきます！

<br>
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="ryuji0526" data-slug-hash="dyNbgbX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="dyNbgbX">
  <span>See the Pen <a href="https://codepen.io/ryuji0526/pen/dyNbgbX">
  dyNbgbX</a> by Ryuji Watanabe (<a href="https://codepen.io/ryuji0526">@ryuji0526</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

コードはこちらになります。

```main.js
  const target = document.querySelector('.target');

// ターゲットが画面領域に触れたきの処理
  function callback(entries){
    if(!entries[0].isIntersecting){
      return;
    }
      //showクラス付与
      entries[0].target.classList.add('show');
  }

  // ターゲットが画面領域に20%交差したら
  const options = {
      threshold: 0.2,
  }

  // IntersectionObserverオブジェクトのインスタンス生成
  const observer = new IntersectionObserver(callback, options);

  // observeメソッド呼び出し
  observer.observe(target);

```

画面領域と、ふわっとさせたい要素が交差するときに、ふわっと出現させるためのクラスを付与することで、スクロール時にふわっと要素が出現するように見せることができます。

それを可能にするのがIntersectionObserverオブジェクトです。文字通り、「交差の監視役」をしてくれます。

```main.js

  // IntersectionObserverオブジェクトのインスタンス生成
  const observer = new IntersectionObserver(callback, options);

```

・第1引数　→ ターゲットの要素と交差が混じったときに実行されるコールバック関数です。
・第2引数　→ オブジェクトで指定することで色々な条件をつけることができるます。
今回の場合は、threshold:0.2　と指定してありますが、これはターゲットの要素との交差の割合が20%を上回るか下回ったときに第1引数で指定した関数が実行されるように指定しています。

<br>
次にobserveメソッドで何を監視するのかを指定します。
今回では、targetクラスを持つ要素を指定しています。

```main.js
 //targetを監視
 observer.observe(target);
```
<br>
最後にcallback関数です。

```main.js
  function callback(entries){
    if(!entries[0].isIntersecting){
      return;
    }
      entries[0].target.classList.add('appear');
  }
```
引数のentriesには、targetに関する情報がオブジェクトで渡されています。
targetをキーとして、要素名が格納されているので、

```main.js
entries[0].target.classList.add('appear')
```
で、監視している要素にappearクラスを付与させています。
（entriesは監視している要素の数に関わらず、情報を配列で渡しています。ただ、今回監視している要素は一つだけなので、決め打ちでentries[0]としています。）

```main.js
    if(!entries[0].isIntersecting){
      return;
    }
```
ここのif文では、target[0]のisIntersectingがfalseだったら、returnをして、処理を中断させています。
isIntersectingとは、要素が交差をしているかをture or falseで表しており、交差したときにtrueを返します。
実は、callback関数は、交差したときだけでなく、監視が始まった時にも実行されます。そのときにappearクラスが付与されてしまうと、スクロールしてもすでに要素が出現してしまっている、という状態になってしまいます。
そういった処理を防ぐために、if文で、「要素が交差したときにだけ、appearクラスを付与してね」と指定しているわけです。
bootstrap4 サイズによって表示（非表示）を切り替える

#### レスポンシブ対応のサイトを作る時に、一定のサイズ以上は表示（非表示）にする方法

```html
#"d-none"で基本非表示、"d-○○-block"で○○以上は表示
<div class="d-none d-md-block"></div>
#逆バージョン
<div class="d-block d-md-none"></div>
```
【トリビアのDelta Lake】#2 Pysparkでゼロパディングを解除する

# Pysparkで、邪魔なゼロを消したい

ゼロパディングというのをご存知でしょうか。桁数が違うデータを、任意の数までゼロで埋めて桁数を揃えてやる、アレです。
サンプルのデータはこんな感じ。
```
sample_data = [{'name': 'Alice',"age": '0002',}, 
               {'name': 'Bob',"age": '0050'}]

df = spark.createDataFrame(sample_data)
df.show()

【結果】
+----+-----+
| age| name|
+----+-----+
|0002|Alice|
|0050|  Bob|
+----+-----+
```
2歳のアリスちゃんと、50歳のボブおじいさんという2列のごく簡単なSparkデータフレーム。
よく見ると、それぞれの年齢がゼロで埋められて4桁に統一されています。

これをPysparkで解除するなら、どうしましょうか。

# 単なる「ゼロ削除」ではダメ
「ゼロを消せばいいじゃん」と、前回の記事と同じコマンドを使うと…

https://qiita.com/yuulian/items/072e747f24ca7550ad98

```
df_remove0 = (
    df
    .select(
　　　　　age,
        regexp_replace(col("age"),"0","").alias("age_remove"),
        "name"
        )
)
df_remove0.show()

【結果】
+----+----------+-----+
| age|age_remove| name|
+----+----------+-----+
|0002|         2|Alice|
|0050|         5|  Bob|
+----+----------+-----+
```
ボブおじいさんが5歳のボブくんになってしまうんです。残したい文字列に含まれるゼロも含めて削除されるのですね。

# regexp_replace('対象カラム', r'^[0]*', '')を使う
結論、こんな感じで書くことが出来ます！
```
from pyspark.sql.functions import regexp_replace,col
df_remove_zeropadding = df.select(
    "age",
    regexp_replace('age', r'^[0]*', '').alias('age_regex_zero'),
    "name")
df_remove_zeropadding.show()

【結果】
+----+--------------+-----+
| age|age_regex_zero| name|
+----+--------------+-----+
|0002|             2|Alice|
|0050|            50|  Bob|
+----+--------------+-----+
```
期待通り、2歳は2歳で出力されるのはもちろん、50歳も50歳のまま表示されました。

これも#1と同じく、dfのオプションの.select,.withcolumn内で
```
regexp_replace('<操作したいカラム名>>', r'^[0]*', '')
```
を行うことで出来ます。

regexp_replace、本当に便利です！

【参考記事】

https://stackoverflow.com/questions/57389885/remove-leading-zeros-pyspark

# このシリーズの目的
クラウドストレージに蓄積された生データ（CSV,JSON等）を加工するのに必要なPysparkの知識を溜めていく、まさに「Pysparkに関するトリビアのDalta Lake」を目指しています。
Pysparkに関する記事はまだ海外のものが多く、このシリーズが私のような国内の駆け出しデータエンジニアの一助になることを願っています。
新 App Store 審査ガイドライン 翻訳&差分ガイド 2022年3月号

## はじめに

これは2022年3月30日付けで変更された App Store 審査ガイドラインの翻訳&差分ガイドです。

[前回](https://qiita.com/midnightSuyama/items/063a5b78ea523ff89f80)からの主な変更点は、リーダーアプリのための外部リンク解放です。

これは日本公正取引委員会との[合意内容](https://www.apple.com/jp/newsroom/2021/09/japan-fair-trade-commission-closes-app-store-investigation/)の「リーダーアプリ内に決済リンクを1つ設置できる」を反映した結果ですが、日本だけではなく世界共通の変更です。

https://developer.apple.com/app-store/review/guidelines/

### 購入導線としての外部リンク

今回、リーダーアプリで解放された外部リンクは、購入導線としての外部リンクを指します。
この外部リンク実装の条件は、審査ガイドラインではなく、次の URL に記載があります。

https://developer.apple.com/support/reader-apps/

大半は、審査ガイドラインに記されているリーダアプリと重なる内容ですが、`Not offer in-app purchases on iOS or iPadOS while using the External Link Account Entitlement` が注目ポイントです。購入導線としての外部リンクを使う場合、アプリ内課金は不可となります。

リンク先は Info.plist の `SKExternalLinkAccount` に登録することになり、リージョンごとに URL は一つです。また、`Not pass additional parameters in the URL` とあり、パラメータ付与は不可なので、使える URL は本当に一つだけ。

リンクする直前の表記も定められています。`Not include, or be used with, language that includes the price of items available on the website (acceptable language includes “go to example.com to create or manage your account”);` とあり、解放される外部リンクは「～を買うための外部リンク」ではなく、「アカウント管理のための外部リンク」という認識が近いです。

## 修正項目

### 3.1.1 In-App Purchase:

> If you want to unlock features or functionality within your app, (by way of example: subscriptions, in-game currencies, game levels, access to premium content, or unlocking a full version), you must use in-app purchase. Apps may not use their own mechanisms to unlock content or functionality, such as license keys, augmented reality markers, QR codes, etc. Apps and their metadata may not include buttons, external links, or other calls to action that direct customers to purchasing mechanisms other than in-app purchase, except as set forth in 3.1.3(a).

`except as set forth in 3.1.3(a)` を追記。3.1.3(a) が優先。

### 3.1.3 Other Purchase Methods:

> The following apps may use purchase methods other than in-app purchase. Apps in this section cannot, within the app, encourage users to use a purchasing method other than in-app purchase. Developers can send communications outside of the app to their user base about purchasing methods other than in-app purchase, except as set forth in 3.1.3(a).

`except as set forth in 3.1.3(a)` を追記。3.1.3(a) が優先。

### 3.1.3(a) “Reader” Apps:

> Apps may allow a user to access previously purchased content or content subscriptions (specifically: magazines, newspapers, books, audio, music, and video). Reader apps may offer account creation for free tiers, and account management functionality for existing customers. Reader app developers may apply for the External Link Account Entitlement to provide an informational link in their app to a web site the developer owns or maintains responsibility for in order to create or manage an account. Learn more about the External Link Account Entitlement.

`Reader app developers may apply for the External Link Account Entitlement to provide an informational link in their app to a web site the developer owns or maintains responsibility for in order to create or manage an account. Learn more about the External Link Account Entitlement.` を追記。外部リンク実装のためには、外部リンク用の申請が別途必要。
【初心者向け】UniTaskを使ってSEが終わったタイミングで次の音楽を流す

SoundEffect鳴らしてからBGMみたいなケースがあるだろうなと思ったのと、
UniTaskを利用するいいケースになるかなと思ったので、そのための投稿です。

# UniTaskを利用
AudioSourceがisPlayingを持っているので、それを利用しながらUniTaskでasync/awaitで待ちます。
上から下に処理が書けるので、流れが読みやすいかと思います。
```C#
using Cysharp.Threading.Tasks;
using UnityEngine;

public class GameController : MonoBehaviour
{
    [SerializeField] private AudioController audioController;

    async void Start()
    {
        // CountDown
        audioController.Play(AudioController.Kind.CountDown);
        // ↑がPlayingでなくなるまで待つ
        await UniTask.WaitUntil(() => !audioController.IsPlaying);
        
        // GameMusic再生
        audioController.Play(AudioController.Kind.GameMusic, true);

        // ゲームを開始する処理が続いていく
    }
}
```

# callbackバージョン
こちらを参照ください。

https://qiita.com/TakashiHamada/items/a5ff15ca7e63c06bfb23

# 参考
## AudioControllerはこんな感じの想定です
```C#
using UnityEngine;

public class AudioController : MonoBehaviour
{
    [SerializeField] private AudioSource audioSource;
    [SerializeField] private AudioClip[] audioClips;

    public bool IsPlaying => audioSource.isPlaying;
        
    public enum Kind
    {
        CountDown = 0,
        GameMusic = 1
    }

    public void Play(Kind kind, bool isLoop = false)
    {
        audioSource.Pause();
        audioSource.clip = audioClips[(int)kind];
        audioSource.loop = isLoop;
        audioSource.Play();
    }
}
```

## 前提
* Unity 2021.2.4f1
* UniTask 2.3.1

## その他
* [UniTask](https://github.com/Cysharp/UniTask) はこちらから
bit dp

[巡回セールスマン問題](https://qiita.com/sibata_yuna/items/33ce6ec6b07cfbe13e14)
dp[bit][最後に訪れた頂点] = 最短経路

[シフト制](https://qiita.com/sibata_yuna/items/d797fd6cd667da9a415c)
dp[bit][日数] = パターン数

[1次元 bit dp](https://qiita.com/sibata_yuna/items/f47b69535cd222b7dd53)
dp[bit] = 最小個数
WPFのViewにローカルの画像を表示する（MVVM）

# はじめに
タイトルだけ見ると、ググっておしまいな気がするけど
半日くらい溶かしたので、備忘録として残しておく

ちなみにググってたくさん出てくる「ビルドアクションをリソースに」すれば治る症状とは別のお話

# 結論

MVVMに則って`View`と`ViewModel`にコードを分けている

```xml:View
<Window>
<!-- Windowタグのプロパティは省略 -->
    <StackPanel>
        <Image Source="{Binding MyImage.Value}" Width="256" Height="256"/>
        <Button Command="{Binding ChangeImage}" Content="Change Image!!" />
    </StackPanel>
</Window>
```

`MyImage`をバインドして、`.Value`には`Bitmap`型を割り当てる
そのビットマップのURIに画像のパスを割り当てる

```cs:ViewModel
internal class MainViewModel : INotifyPropertyChanged
{
   public ReactiveProperty<BitmapImage> MyImage { get; set; }
   public ReactiveCommand ChangeImage { get; }

   public MainViewModel()
   {
       string basePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
       Uri baseUri = new Uri(basePath);
       Uri imageUri = new Uri(baseUri, "./net6.0-windows/1.bmp");
       MyImage = new(new BitmapImage(imageUri));
       
       ChangeImage = new ReactiveCommand().WithSubscribe(() =>
       {
           var newImageUri = new Uri(baseUri, "./net6.0-windows/2.bmp");
           MyImage.Value = new(newImageUri);
       });
   }

   public event PropertyChangedEventHandler? PropertyChanged;
}
```

ハマったポイントとしては、画像を置いたパスが迷子になった点

実行ファイルが置いてあるところの画像を下記のように指定したが、画像が表示されず

```cs:動かないコード
Uri imageUri = new Uri("./1.bmp", UriKind.Relative);
```

結局丁寧に`GetExecutingAssembly().Location`でパスを取得して
`new Uri(baseUri, "./net6.0-windows/1.bmp");`としてURIを結合した

## `Uri`は書き換えできない

メモリを節約するために、単一のインスタンスのURIを書き換えようと思ったが
画像が表示されている最中はソースを書き換えることができず
仕方なく２つのビットマップをつかっている

```cs
_image.UriSource = null;
// nullにはならない
```

## 実際の動き

ボタンクリックすることで表示されている画像が切り替わる

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/84d87511-0250-cf1f-9f4d-d252e5ac4bd9.gif)

# 詳細

結論が長くなった。ここから詳細の説明

## プロジェクトを立ち上げます

.NET 6のWPFアプリケーションをつくり
適当に画像を２枚用意して、`ReactiveProperty`をインストールする

### 脱線

おめでとうございます

https://twitter.com/okazuki/status/1505357653312434176?s=20&t=4mD6KbTBZzOHuO4yBz6bUQ

## 画像を２枚用意する

実行ファイルと同じ階層に画像を２枚用意する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/c166892e-32e8-b605-eba3-96f108d59717.png)

## View側の`Image`にはサイズを与える

```xml:View
<Image Source="{Binding MyImage.Value}" Width="256" Height="256"/>
```

https://qiita.com/kabosu/items/ad8aea7077f0cacfdd5c

今回画像サイズは縦横256pxでつくっている
上記記事と違い、自分の環境では`Strech`に`Fill`や`None`を入れても、画像は表示された

# おわりに

`ViewModel`については特筆すべきことはないので、詳細おわり

繰り返しになるが、表示はされてもメモリ食い荒らしそうなコードで気持ちがわるい

ボタンクリック動作のたびに`new`を通る。。。

# 参考

https://www.delftstack.com/ja/howto/csharp/get-relative-path-in-csharp/