OmniAICreator/Qiita-1.07M huggingface dataset:
install mongodb on ubuntu with docker

```
snap install docker
sudo systemctl enable docker
sudo systemctl start docker
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add

sudo apt install make docker-compose -y

docker run -p 0.0.0.0:27017:27017 --restart=always --name mongo -d mongo:4.2.0
```
ページ非表示で止まったvideoタグをもう一度再生する

HTMLのvideoタグで動画を再生しているときに違うタブを開いたりしてページを非表示にするともう一度ページを表示したときに動画が止まったままで再生されません。

これをもう一度再生させるにはページが表示されたことを知らせてくれるpageshowイベントを使います。
```javascript
window.addEventListener("pageshow", function(){
 document.getElementById("video").play(); //idは使用してるものに変えてください
});
```
これで非表示だったページを再表示したときに自動的に動画が再生されます。
最後のカンマについて（JavaScript）

## 最後のカンマとは？
最後のカンマとは、JavaScriptにおけるアレイやオブジェクトの括弧の内部で使用するカンマについて、一番最後のエレメントに対してカンマをつけるのかとうか？という話です。
ちなみに、英語では、trailing commaと呼び、trailとは、足跡や引きずった跡のことなので、カンマを引きずった跡に見立てているわけです。

## JavaScript Arrays

最初にアレイですが、JavaScriptでは最後のカンマがあってもなくても、問題ありません。

```JavaScript

var arr = [ "絵梨花","瑞穂","紗理菜", ];

console.log(arr); // [ "絵梨花","瑞穂","紗理菜" ]
console.log(arr.length) // 3

```
ただし、もう一つカンマを付け加えると変なことになりますので、注意しましょう。

```JavaScript

var arr = [ "絵梨花","瑞穂","紗理菜",, ];

console.log(arr); // [ "絵梨花","瑞穂","紗理菜", (empty) ]
console.log(arr.length) // 4

```

:::note
JavaScriptでは、アレイについては、ECMAScript 1（1997）より最後のカンマはあってもなくてもよい仕様となっています。
:::

## JavaScript Objects
オブジェクトについても、最後のカンマがあってもなくてもOKです。

```JavaScript
var member = {
    firstName: "Sarina", 
    lastName: "Ushio",
    team:"Hinatazaka 46",
    eyeColor:"brown",
}
console.log(member); 
// { firstName: "Sarina", lastName: "Ushio", team:"Hinatazaka 46", eyeColor:"brown" }
console.log(Object.keys(member).length) // 4
```
:::note
オブジェクトについてはECMAScript 2009（ES5）より最後のカンマがあってもなくても問題ない仕様となりました。（それまでは、最後のカンマがあるとエラーになっていました。）
:::

## JavaScript Functions
ファンクションのパラメータにおいて最後のカンマを付けても、問題なく動作します。
また、一度宣言したファンクションを起動する場合、そのパラメータにおける最後のカンマも許容されます。

```JavaScript
function add (a,b) {
    return a + b;
}

function parameterwithtrailingcomma (a,b,) {
    return a + b;
}

console.log(add(2,3)) // 5
console.log(add(2,3,)) // 5
console.log(parameterwithtrailingcomma(2,3)) // 5
console.log(parameterwithtrailingcomma(2,3,)) // 5
```
:::note
ファンクションのパラメータについては、ECMAScript 2017（ES8）より最後のカンマがあってもなくても問題ない仕様となりました。（それまでは、最後のカンマがあるとエラーになっていました。）
:::

ただし、rest parameterについては、最後のカンマを付けるとエラーになります。こちらは、最後のカンマを付けない、正しい使い方。
```JavaScript:
function show (...numbers) {
    return numbers;
}
console.log(show(1,2,3,4,5)); //[1,2,3,4,5]
```
こちらは、rest parameterに最後のカンマが付いていて、SyntaxErrorになるケース。JavaScriptがこのファンクションを読み込む段階でエラーになるので、コンソールログは出力されません。
```JavaScript:
function show (...numbers,) {
    return numbers;
}
console.log(show(1,2,3,4,5));
```

## JSON
JSONは、JavaScript Object Notationの略ですが、広く利用されているデータ交換のためのフォーマットです。ただし、その名前とは裏腹に、JavaScriptとは独立した仕様になっていて、最後のカンマをつけるとエラーになります。

```JavaScript
//正しいフォーマットのサンプル
{ "name":"Erika", "height":162, "address":"Tokyo" }

//最後にカンマを付けるとエラーになります
{ "name":"Erika", "height":162, "address":"Tokyo", }

//正しいJSONフォーマットの場合
const jsonText = '{ "name":"Erika", "height":162, "address":"Tokyo" }';
const obj = JSON.parse(jsonText);
console.log("obj:", obj); //{ name:"Erika", height:162, address:"Tokyo" }

//最後にカンマを付けた間違ったフォーマットの場合
const jsonText2 = '{ "name":"Erika", "height":162, "address":"Tokyo", }';
const obj2 = JSON.parse(jsonText2); //最後のカンマがあるため、SyntaxErrorにより中止
console.log("obj2:", obj2);
```

## おすすめのコーディングポリシー
いくつかのJavaScriptの教科書では、「アレイもオブジェクトも最後のカンマをつける」ことが推奨されています。
私自身はクセになっていて、最後のカンマを省略してしまうことが多いですが、特にオブジェクトでは、複雑なオブジェクト・プロパティを編集する際は圧倒的に楽になりますので、「常に最後のカンマをつける」ということでよいかと思います。
【mocha】非同期関数の例外テスト

**mocha**で、``async``/``await``を使った非同期関数で例外が発生することをテストする方法をメモしておく。

# 非同期関数で例外が発生しない場合のテスト
まず単純な非同期関数で例外が発生しない場合のテストは、``async``/``await``を使って以下のように書ける。

```JavaScript:テストコード例
describe("非同期関数のテスト", () => {
    it("例外が発生しない場合", async () => {
        const result = await <テスト対象の非同期関数>;
        // assertでチェック
    });
 });
```

# 非同期関数で例外が発生する場合のテスト
非同期関数で例外が発生する場合のテストを``try``/``catch``を使って以下のように書いた。

```JavaScript:テストコード例
describe("非同期関数のテスト", () => {
    it("例外が発生する場合", async () => {
        try {
            await <テスト対象の非同期関数>;
            // 例外が発生しない場合テスト失敗とする。
            assert.fail("Exception not thrown");
        } catch (e) {
            // assertでチェック
        }
    });
 });
```
【errors.add】とは？

## errors.addとは
特定の条件でバリデーション（自作のバリデーションなど）をかけ、そのエラーメッセージを追加するときに使う。

## 使い方

```rb
# シンプルな構文(どんなエラーなのか)
> user.errors.add(:base, '名前の文字数オーバー')
> user.errors.full_messages
 => ["名前の文字数オーバー"]

# 一般的な構文(どのカラムの、どんなエラーなのか)
> user.errors.add(:name, '文字数オーバー')
> user.errors.full_messages
=> ["Name 文字数オーバー"] 
```

## 参考記事
[【Rails】errors.addって何？](https://qiita.com/yujiG/items/3e34e2e0e7b4120b0584)
【PowerShell】複数のテキストファイルを結合する（Get-Contentコマンド）

## 環境
+ Microsoft Windows 10.0.22000.318（21H2）
+ PowerShell 7.2.0

## 準備
```posh:PowerShell
# フォルダ「test」を作成
New-Item test -ItemType Directory

# txtファイルを作成
New-Item a.txt -Value a.txtの中身
New-Item b.txt -Value b.txtの中身

# a.txtとb.txtの確認（[-Encoding XXX] で文字コードを指定）
Get-Content a.txt, b.txt -Encoding utf8
<# 
a.txtの中身
b.txtの中身
#>
```

<details><summary>New-Itemコマンドのオプション</summary>

```
New-Item
   [-Path] <String[]>
   [-ItemType <String>]
   [-Value <Object>]
   [-Force]
   [-Credential <PSCredential>]
   [-WhatIf]
   [-Confirm]
   [<CommonParameters>]
```

詳しくは[こちら](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-item?view=powershell-7.2)

</details>

<details><summary>Get-Contentコマンドのオプション</summary>

```
Get-Content
   [-ReadCount <Int64>]
   [-TotalCount <Int64>]
   [-Tail <Int32>]
   [-Path] <String[]>
   [-Filter <String>]
   [-Include <String[]>]
   [-Exclude <String[]>]
   [-Force]
   [-Credential <PSCredential>]
   [-Delimiter <String>]
   [-Wait]
   [-Raw]
   [-Encoding <Encoding>]
   [-AsByteStream]
   [-Stream <String>]
   [<CommonParameters>]
```

詳しくは[こちら](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-item?view=powershell-7.2)

</details>

## 指定したテキストファイルを結合する場合
```posh:PowerShell
Get-Content a.txt, b.txt | Set-Content combined.txt
```

## フォルダ内のすべてのテキストファイルを結合する場合
```posh:PowerShell
Get-Content *.txt | Set-Content combined.txt
```

## 確認
```posh:PowerShell
Get-Content combined.txt -Encoding utf8
<# 
a.txtの中身
b.txtの中身
#>
```

## 参考
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/?view=powershell-7.2
【Stimulus】targetがある時だけ関数を実行する方法

# はじめに

Rails7 で JavaScript を利用するときは Stimulus を使うのがデフォルトになっています。

特定のページで関数を実行する方法を書き残しておきます。

## 環境

- Rails 7.0.22
- Ruby 3.1.1
- Rspec 3.10.0
- stimulus-rails 1.0.4

## やりたい事

特定のページの時だけクラスを削除する関数を実行する

# 本文

Stimulus のライフサイクルコールバックと呼ばれる特別なメソッドを使用すると目的を達成できます。

`TargetConnected()`を利用する

```javascript:class_controller.js
import { Controller } from "@hotwired/stimulus";

// Connects to data-controller="class"
export default class extends Controller {
  static target = ["class"];

  classTargetConnected() { //ターゲット名が入る
    const target = this.classTarget // これでdata-target='class'がついている要素が取得できる
    target.classList.remove("remove-target");
  }
}

```

```html: target.html.erb
<div data-controller='class'> <!--data-controllerがない起動しない -->
  <p>target</p>
  <p class= 'remvoe-target' data-class-target='class'>remove-target</p>
  <!--data-class-targetがDOMに接続されるとclassTargetConnectedが実行される -->
</div>
```

# 参考

[公式リファレンスーライフサイクルコールバック](https://stimulus.hotwired.dev/reference/lifecycle-callbacks)

[Github stimulus](https://github.com/hotwired/stimulus)
【React Native】LinearGradientの中にScrollViewを置くとエラーログを吐かずにクラッシュする

最近React Nativeでアプリを作っていたのですが、奇妙なバグに出くわしたのでメモ書き程度に残しておきます。

# 開発環境

開発環境はExpoです。

``` json: package.json
{
  (省略)
  "dependencies": {
    "expo": "~44.0.0",
    "expo-linear-gradient": "^11.0.3",
    "expo-status-bar": "~1.2.0",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-web": "0.17.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@types/react": "~17.0.21",
    "@types/react-native": "~0.64.12",
    "typescript": "~4.3.5"
  }
}
```

# スクロールすると落ちる

とある条件下でスクロールビューを動かすと稀にアプリが落ちるという不具合です。
初めてこのバグに気付いた時は普通にスクロールしただけでアプリが落ちたのですが、色々試行錯誤した結果、動画のようにpadding（またはmargin）を設定している画面端でマウスをドラッグしたままクルクルすると再現しやすいことがわかりました。（なんでかはわかりません）
![名称未設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540389/61617195-eef3-93f7-1a52-b2ac59da0c64.gif)

実機検証中にこのバグが発生したので、シミュレータでも再現するか確認してみましたが、再現はしたもののエラーログも何も吐かずにアプリがクラッシュして途方に暮れていました。

再現させるために色々試して気付いたことは
* スクロールできる状態でないと再現しない
* ScrollView内のコンテンツがScrollViewに全て収まる状態でオーバースクロールしても再現しない
* iOSのみ再現する

ということです。

# 問題のコード

バグが再現するコードです。

``` jsx:App.tsx
import { SafeAreaView, ScrollView, StyleSheet, Text } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';

export default function App() {
  return (
    <SafeAreaView style={styles.container}>
      <LinearGradient
        style={styles.linearGradient}
        colors={['red', 'yellow']}>
        <ScrollView>
          <Text>
            {省略}
          </Text>
        </ScrollView>
      </LinearGradient>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  linearGradient: {
    width: '100%',
    height: '100%',
    paddingLeft: 30
  }
});

```

ExpoのログではなくOS側のログを見てもそれらしきエラーログを発見できなかったので、仕方なくどういう条件でバグが再現するのかをしらみ潰しに試していきました。
結論としては、LinearGradientの中にScrollViewを置いている状態でスクロールするとアプリがクラッシュすることがあるようです。

# 解決策
解決策はシンプルで、LinearGradientに`position: 'absolute'`を指定して、LinearGradientの中にコンポーネントをネストさせないようにしました。

``` jsx:App.tsx
import { SafeAreaView, ScrollView, StyleSheet, Text } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';

export default function App() {
  return (
    <SafeAreaView style={styles.container}>
      <LinearGradient
        style={styles.linearGradient}
        colors={['red', 'yellow']}/>
      <ScrollView>
        <Text>
          {省略}
        </Text>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center'
  },
  linearGradient: {
    width: '100%',
    height: '100%',
    position: 'absolute',
    bottom: 0
  }
});
```

# 終わりに
かれこれ半年近くReact Nativeをやってきましたが、腑に落ちないようなバグが多い印象があります。
スクロールビューにグラデーションをかけたいというニッチな（？）使い方をする人は少ないかと思いますが、参考になったら嬉しいです。
結局なぜアプリがクラッシュするのかわからないことだけが心残りですが...。（わかる方がいたら教えてください）
net/httpを用いたHTTPリクエスト

## 背景
指定したURLのステータスコードをどう抽出するかの忘備録。

## 使い方
```rb
uri = URI.parse("https://www.google.com/?hl=ja")
response = Net::HTTP.get_response(uri)

response.code #ステータスコードが返ってくる
response.body #レスポンスbodyが返ってくる
```
上記``response.code``の結果として **文字列の``"200"``** と返ってくる。

## 参考記事
[RubyのHTTPリクエストをできるだけシンプルに実装する](https://qiita.com/takano-h/items/dd10818eb7e09161bc29#%E4%B8%80%E7%95%AA%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E6%96%B9%E6%B3%95)
make(旧integromat)を使ってLambdaを実行する〜EC2の起動・停止篇

## 1.はじめに
makeからLambdaを呼び出し、EC2の起動・停止を行う手順です。

前回の記事はこちら。この記事で作ったリソースをそのまま流用します。

https://qiita.com/okome-chan/items/f0359139b2e72daf686c

## 2.今回やること
こんな感じのパイプラインを作ってLambdaを実行します。
Slackのチャンネルに投げたメッセージをトリガーにして、OutgoingWebhooksからmakeのWebhooksを呼び出す。
メッセージは`{ key:value }`でLambdaに渡して、EC2の起動・停止の判定に利用します。

![スクリーンショット 2022-03-28 14.36.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/19d01da8-bc67-1165-56d9-2299b8efc6b8.png)

## 3.アプリの設定
### 3-1.Slack
今回は`Start`と`Stop`をトリガーにするので、Outgoing Webhooksに以下の設定を行います。

![スクリーンショット 2022-03-27 22.27.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/44e3cfdf-d5a5-27a2-37d3-17531a57c3d7.png)

そのままの意味ですが、Startから始まるメッセージがチャンネルにポストされればEC2を起動。
Stopから始まるメッセージがポストされればEC2が停止するようにします。

### 3-2.make
前回の記事で作ったScenarioをそのまま使います。

https://qiita.com/okome-chan/items/f0359139b2e72daf686c

Lambda側で`{ key:value }`を使用するので、Bodyの設定も行います。

![スクリーンショット 2022-03-28 14.37.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/163df22f-2876-7479-0abb-87408aff265d.png)

### 3-3.AWS(Lambda)
公式のEC2の起動・停止プログラムのサンプルにif文を追加しました。

```python:lambda_function.py
import boto3
import json

region = 'ap-northeast-1'
instances = ['i-xxxxxxxxxxxxxxxxx']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    if event['key'] == 'Start':
        ec2.start_instances(InstanceIds=instances)
        print('started your instances: ' + str(instances))
    else:
        ec2.stop_instances(InstanceIds=instances)
        print('stoped your instances: ' + str(instances))
```

引用元はこちら。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/start-stop-lambda-eventbridge/

ちなみに`start_instances`を`reboot_instances`にすると再起動もできます。便利だ。。

## 4.実行してみる
ここまでの手順で`Start`をメッセージすればEC2が起動、`Stop`でEC2が停止すると思います。
ワークフローから実行できるようにするとより良いかと！

## 5.ちなみに
今回はLambdaでStartとStopの判定を行っていますが、make側に任せてもいいです。
その場合はRouterを使います。

![スクリーンショット 2022-03-28 14.57.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/d5bde9f8-98ad-e22e-1b7d-7448b415f8a7.png)

Startで始まるメッセージの場合は上のLambdaをInvokeし、Stopで始まる場合は下のLambdaをInvokeするようRoutingしたScenarioです。
Filterの設定はこんな感じ。

![スクリーンショット 2022-03-28 14.58.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/e8a08ea4-40f6-2a58-8334-6442afe85fbc.png)

Slackにポストするメッセージに合わせて`Contains`や`Equal to`など調整してください。

## 6.おわりに
makeはもっと色々できるし触っていて楽しいSaaSなのですが、導入しているプロジェクトが少なそうなのが難点ですかね…！
ただプログラミングスキルが低いぼくでも慣れればすぐ実装できるGUIは本当に魅力だと思いました。No Codeしゅごい。

以上です。
この記事がどなたかのお役に立てると幸いです:raised_hands:
Blender でハノイの塔の動画を自動生成

https://twitter.com/hibit_at/status/1506221266981728257

　上のような動画を作成しました。

　Blender 上で Python スクリプトを走らせることにより大量の画像を生成しています。

　今までの記事で述べたことに比べて新しい点はそこまでありませんが、定期的に記事にまとめた方が技術が身につくのと、誰かの助けになるかもしれないので一応。

# オブジェクトの作成

　まずは円盤の集合体を生み出します。手作業で生み出してもいいですが、せっかくのスクリプトなのでそこも自動化しましょう。

```python 

import bpy
import numpy as np

np.random.seed(40)

# parameter
height = 4

for i in range(height):
    obj = bpy.ops.mesh.primitive_cylinder_add(vertices=(i+1)*height*5,radius=i+2, depth=1, location=(0,0,height-1-i))
    bpy.context.object.name = f'hanoi{i+1}'
    mat_name = 'material' + str(i)
    bpy.data.materials.new(name = mat_name)
    mat = bpy.data.materials[mat_name]
    mat.use_nodes = False
    mat.diffuse_color = np.random.rand(4)
    mat.diffuse_color[3] = 1
    mat.metallic = 0
    mat.roughness = 1
    bpy.ops.object.material_slot_add()
    bpy.context.object.active_material=mat
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/b0f2b31f-267d-a1dc-6b62-7f4c800f9557.png)

　こんな感じになります。段数は `height` で指定します。色合いが気に食わなければ、`np.random.seed(40)` の中の数値を変えてください。

# 動かす

　次に、円盤を一つずつ動かしながらレンダリングしていきます。

```python 
a = []
b = []
c = []

for i in range(height):
    a.append(i+1)

a = list(reversed(a))
i = 0

def rendering(a,b,c):
    cnt = 0
    for idx in a:
        obj = bpy.data.objects[f'hanoi{idx}']
        obj.location = (-height*3, 0, cnt)
        cnt += 1
    cnt = 0
    for idx in c:
        obj = bpy.data.objects[f'hanoi{idx}']
        obj.location = (0, 0, cnt)
        cnt += 1
    cnt = 0
    for idx in b:
        obj = bpy.data.objects[f'hanoi{idx}']
        obj.location = (height*3, 0, cnt)
        cnt += 1
    global i
    i += 1
    bpy.context.scene.render.filepath = (f'tmp/{i}.png')
    bpy.ops.render.render(write_still=True)

rendering(a,b,c)

def hanoi(n, start, end, tmp):
    if n <= 0:
        return
    hanoi(n-1, start, tmp, end)
    end.append(start.pop())
    rendering(a,b,c)
    hanoi(n-1, tmp, end, start)

hanoi(height, a, b, c)
```

　これで Blender のレンダリング先となっているフォルダに大量の画像が投下されます。後はそれを動画編集ソフトなりで動画化すれば、冒頭のツイートのような動画が作成できます。（床や壁などの設定、ライティングやカメラの画角等は個別に設定しています）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/36764dcc-5406-ee5e-93d3-bdbccd0d7ac2.png)
※ライティング等は個別に設定が必要です。

　注意点として、ハノイの塔は初期状態を含めたら $2^n$ 回のステップが必要なので、`height=100` などに設定したら、一回のレンダリングに $0.1$ 秒しかかからないとしても $1.2676506*10^{29}$ 秒必要であり、太陽系が終了するまで待っていても終わりません。またHDD容量も約 $10^{26}$ GB 必要です。要は、現実的ではないので `height=4` あたりで実験するのがよいでしょう。

# ハノイの塔のステップ

　個人的な、簡単な証明。

　まず、円盤が 1 枚である状態を考える。これを別の棒に移す手間は 1 ステップである。

　次に、円盤が 2 枚である状態を考える。上の 1 枚を除けて考えれば状況は 1. と全く同じである。しかし、上の円盤を除けてから載せ直さなければいけない。つまり、上の 1 枚を除ける→下の 1 枚を移す→上の 1 枚をその上に載せる、という手順が必要である。

　これを一般化する。n 枚を移すためには、
1. n-1 枚を除ける。
1. 1 枚を移動する。
1. n-1 枚をその上に載せる。

　さて、2. に 1 ステップかかることはほぼ自明である。1. と 3. については n-1 枚を動かすための必要な手順に等しい。

　つまり、これは以下のような漸化式で表現できる。

```math 
f(1) = 1 \\
f(n) = 2f(n-1) + 1
```

　これを解いて、必要なステップ数は  $2^n-1$ 、初期状態を含めたら必要なレンダリング回数は $2^n$ となる。

# 参考記事

　再帰プログラム部分は以下の記事を参考にさせていただきました。
[【初心者向け】再帰関数（ハノイの塔を分かりやすく！）](https://qiita.com/ka201504/items/e46d6c9bde13e61b3331)
cscの作法 その68

# 概要
cscの作法、調べてみた。
mdbにcsvを読み込んでみた。

# コンパイル手順

```
>csc csv2mdb.cs /platform:x86

```

# サンプルコード

```
using System;
using System.Data.OleDb;
using System.Data;
using System.IO;
using System.Text;
using System.Collections.Generic;

public static class Program {
	public static void Main(params string[] args) {
		OleDbConnection con = new OleDbConnection();
		con.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=mydb.mdb;";
		con.Open();
		CSVReader reader = new CSVReader(new StreamReader("expense_sample.txt"));
		string[] getLine = null;
		getLine = reader.ReadLine();
		while ((getLine = reader.ReadLine()) != null)
		{
			string sSQL = "INSERT INTO sisyutu(年月日, 項目, 金額, 備考) VALUES(#" + getLine[0].Substring(0, 10) + "#,'" + getLine[1] + "'," + getLine[2] + ",'" + getLine[3] + "')";
			OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(sSQL, con);
			cmd.ExecuteNonQuery();
			Console.WriteLine(sSQL);
		}
	}
}





```


以上。
Laravelのバリデーションエラーで配列の位置を取り出す

申込みフォームなどで、ユーザー数が可変で、各ユーザーの名前と年齢を取得したい場合などに、下記のようなデータが送られてくるとします。

```
["users"] => [
    0 => [
        'name' => '太郎',
        'age' => 20,
    ],
    1 => [
        'name' => '次郎',
        'age' => 18,
    ],
]
```

このとき、n番目の配列内の特定の要素に対してバリデーションエラーのメッセージを表示したいときに、
`n番目は、必ず指定してください。` のような形で、配列の位置を取り出す方法です。

## 対象バージョン
- Laravel9.x

## 結論
attributeで `:index` あるいは `:position` を使う。
https://laravel.com/docs/9.x/validation#error-message-indexes-and-positions

## 実装
`App/Http/Requests/UserRequest.php` に対してrules及びattributesを設定する形での実装を行います。

### ValidationRuleの作成
リクエストする際に、各ユーザーの `name` と `age` が必須であることのルールを設定します。
なお、下記のデータの前提として、日本語のLanguageFileを導入しているものとします。

```php:Requests/UserRequest.php
public function rules()
{
    return [
        'users.*.name' => 'required',
        'users.*.age' => 'required',
    ];
}
```

このとき、エラーを取り出すと、下記のような出力となります。
```
users.1.nameは、必ず指定してください。
users.1.ageは、必ず指定してください。
users.2.nameは、必ず指定してください。
users.2.ageは、必ず指定してください。
```

### 適当にattributesを設定する
```php:Requests/UserRequest.php
public function attributes()
{
    return [
        'users.*.name' => 'ユーザーの名前',
        'users.*.age' => 'ユーザーの年齢',
    ];
}
```

シンプルにこのように登録すると、出力は下記のような形となります。
```
ユーザーの名前は、必ず指定してください。
ユーザーの年齢は、必ず指定してください。
ユーザーの名前は、必ず指定してください。
ユーザーの年齢は、必ず指定してください。
```

このままでは、「どのデータに対してエラーとなっているのか」がわかりません。

### 配列の位置を取り出す
ここで本題となります。
[公式ドキュメントののValidationの項目](https://laravel.com/docs/9.x/validation#error-message-indexes-and-positions)を参照すると、`:index` あるいは `:position` を利用することで、配列の位置(インデックス)を取得できるとの記載があります。

そのため、先程のattributesを下記のように書き換えると、
```php:Requests/UserRequest.php
public function attributes()
{
    return [
        'users.*.name' => ':index番目のユーザーの名前',
        'users.*.age' => ':index番目のユーザーの年齢',
    ];
}
```

エラーの出力は、下記のようになります。
```
1番目のユーザーの名前は、必ず指定してください。
1番目のユーザーの年齢は、必ず指定してください。
2番目のユーザーの名前は、必ず指定してください。
2番目のユーザーの年齢は、必ず指定してください。
```

## 終わりに
この `:index` 及び `:position` については、Laravel9.xのリリースに際して実装されたようです。
[従来は取り出すのが割と面倒](https://stackoverflow.com/questions/36571628/how-to-get-array-index-in-validation-message-laravel-5-2)だったようなので、嬉しいですね。
Fn / OCI Functions 向けに アノテーションを使って HTTP リクエスト処理をすっきり書くフレームワークを作った話


Fn / OCI Functions で API を開発するとします。API は API Gateway を通じて公開する想定です。例えば一連の複数オブジェクトに対する CRUD 処理としましょう。API Gateway 経由の Rest API の実装は、一つのオブジェクトについて同じURLに対する POST/GET/PUT/DELETE のメソッドでアクセスさせることになるでしょう。ではこの時 Function の粒度はどう考えればいいでしょうか？ POST/GET/PUT/DELETE 毎に Function を分けますか？、さすがにそれはしないか... では同じ URL はひとまとめにして（＝対象オブジェクト毎に）、URLのパス単位で Function を分けるのではどうでしょうか？う~ん、それでも Function の数が多くなっちゃうかな...？
つまり、適当な粒度で API 群をまとめて1つの Function で処理する必要が出てくる訳です。ですが、そうすると Function にまとめられた全ての API の入り口は（現状の FDK の仕様では）指定したクラスの単一のメソッドになります。そのメソッドでリクエストを受け取り、HTTP メソッド/パス を確認して、個々の API 処理に分岐させることになります。この処理をコーディングするの、面倒ですよね、if文だらけ、毎回似たようで異なる分岐処理、もっとすっきりとコーディングしたいです。そんなときに役に立つのがこのフレームワーク「Fn Event Router」です。

https://github.com/tkote/fn-event-router

このフレームワークを使うと、

```java
@FnBean
public class HelloFunction {

    @FnHttpEvent(method = "GET", path = ".*/hello", outputType = "text")
    public String hello(String input) {
        // ...
    }
// ...
```

のように、個々の HTTP リクエスト毎にメソッドをマッピングすることができます。Functions の入出力をお助けするJava/Jsonバインディング機能やヘルパークラス等も提供しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544382/d01b15c2-3906-cc4c-5ee5-87de37d7ac62.png)

お試しあれ！
初心者向けにスコープについてどんなものか説明してみる

今回の記事はスコープについて
[アクセス修飾子についての記事](https://qiita.com/YouProgramer/items/b876a7f086ef19e2af86)も関係してきます。
基本的にはどの言語にも共通するお話かと思いますので、今回は言語の指定はしてないです。


# スコープとは
スコープとは、変数の有効範囲のことを表します。
「クラスやメソッドの外で使える変数かどうか」ということです。
冒頭のリンクの記事ではpublicキーワードやprivateキーワードなどについて取り扱われていますが、まさにそこの部分も関係してきます。
また、どこで変数を宣言するかによっても変わってきます。こんな感じ↓
- メソッド**外**で変数を宣言した場合はメソッド外でも使用可(アクセス修飾子でいうとpublic)
- メソッド**内**で変数を宣言した場合はメソッド外では使用不可(アクセス修飾子でいうとprivate)

というのが一般的なスコープです。
例外(？)として、メソッド内でpublicキーワードを使用して変数を宣言した場合は、メソッド外でも値は保持された状態で使用可能となります。(VBAでは可能でした)
アクセス修飾子ってこういうことですね。
この「値が保持された状態」についてですが、基本的に同じ変数名を扱う場合は最後に格納した値を持っています。
その変数のスコープの適用範囲内であれば、最後に格納された値で保持される。といった感じでしょうか。
僕自身、この辺は理解できているのですが説明の仕方が難しいのでこれが届いているかどうか…

ゲームで例えると、こんな感じです。
- タイトル画面はpublic状態
- ロードデータの選択画面もpublic状態
- ロードされたデータはprivateになり、他のデータとの干渉は起きない

みたいな感じですかね…
実際にロードされたデータでプレイする時には、他のセーブデータとは基本的には全く関係ないはずです。
んー、伝わるかな、難しいな笑

ちなみに変数を宣言する前に変数を使用することは論外です。
ソースコードは上から順番に実行されるものなので、変数宣言よりも先に変数を使用するのは変じゃないです？

プログラミングの世界では、public変数を「グローバル変数」、private変数は「ローカル変数」と呼ばれたりしています。

とりあえず、今回はスコープについてということで、初心者の方にわかりやすく伝えようという記事なので、短いですがこの辺で。
【Laravel】model作成時のオプション

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## オプション指定の仕方

model作成の際にオプション指定で、同時に様々なファイルを生成できる。
下記は、migrationファイル・factory・controller（resourceにもとづくメソッドを生やしておいてくれる）を同時に作成してくれる。
```
php artisan make:model Post -m -c -f --resource
```

オプションの種類はこちら。
```
Options:
  -a, --all             Generate a migration, seeder, factory, policy, and resource controller for the model
  -c, --controller      Create a new controller for the model
  -f, --factory         Create a new factory for the model
      --force           Create the class even if the model already exists
  -m, --migration       Create a new migration file for the model
      --morph-pivot     Indicates if the generated model should be a custom polymorphic intermediate table model
      --policy          Create a new policy for the model
  -s, --seed            Create a new seeder for the model
  -p, --pivot           Indicates if the generated model should be a custom intermediate table model
  -r, --resource        Indicates if the generated controller should be a resource controller
      --api             Indicates if the generated controller should be an API controller
  -R, --requests        Create new form request classes and use them in the resource controller
      --test            Generate an accompanying PHPUnit test for the Model
      --pest            Generate an accompanying Pest test for the Model
  -h, --help            Display help for the given command. When no command is given display help for the list command
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi|--no-ansi  Force (or disable --no-ansi) ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env[=ENV]       The environment the command should run under
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
```

## Railsの場合 

```
rails g model post
```
で、migration・model・テストファイルを作成してくれる。
Railsではわざわざオプションにしなくてもmigrationファイルを作成してくれてたの改めて知った。
std:bind

```#include <stdio.h>
#include <functional>

class Test
{
public:
    static void func(int a);
};

class Func
{
public:
    static void test(void (*funcptr)(int a),int b);
    void fs(void (*funcptr)(int a),int b);
};

void Test::func(int a) {
    printf("a = %d\n", a);
}

void Func::test(void (*funcptr)(int a),int b) {
    if(b > 0){funcptr(b);}  // a = 10  
}

void Func::fs(void (*funcptr)(int a),int b) {
    auto fn_half = std::bind(test,funcptr,std::placeholders::_1);
    fn_half(b);
}

int main(void) {
    Test c;
    Func f; 
    //auto f = c.
    f.fs(c.func,5);
    //fs(5);
    return 0;
}
```
【PHP】多次元配列の次元数に上限があるのか気になって試した結果

先日、実務で五次元配列をごにょごにょしているコードに遭遇しました。
普段は三次元配列まででほぼ事足りるので印象に残るコードだったのですが、
ふと、PHPの配列の次元数はどこまでいけるのか気になってしまい調べてみることに。
マニュアルを漁ってもそれっぽい記載を見つけることはできませんでしたが、素敵なブログを発見。

> [PHPの制限一覧](https://blog.ohgaki.net/php-limits)
>
> 配列型の要素数は内部で利用するハッシュのデータ構造定義に依存しています。
> - PHP 7.0未満は2^32個まで （uint32_tが利用されているが、実際には最大数に達する前に問題が発生すると考えられる）
> - PHP 7.0以上の場合、
>   - size_tが32bitの場合は、0x04000000個まで
>   - size_tが64bitの場合は、0x80000000個まで（通常は2^31個まで利用できる、と考えて良い）

実際は要素数の上限に達する以前にメモリが枯渇しますが上限は存在してそうです。
てことは、次元数についても同様にハッシュのデータ構造定義に依存しているって事になるのかな。

## 検証してみる

難しいことはよくわからないので実際に試してみます。

~~~php:100次元配列を作成するコード
$x = [];
for ($i = 1; $i <= 100; ++$i) { $x = [$x]; }
print_r($x);
~~~

控え目に100次元配列を作成してみたところ普通にできました。
少し本気を出して、フリーザ様の第一形態の戦闘力：53万次元配列に挑戦してみたところ・・・作成できました！
その後、500万次元配列も試して作成できましたが、手元環境で10分以上かかってしまい心が折れて検証は終了しました。

## 検証結果：配列の次元数上限値なんてどうでもよくなった

おそらく、配列の次元数上限値はその配列の要素数に左右されるもの。
次元数上限値なんて気にする暇があるなら、お酒飲みにいこうぜ。
GitHubからCodeCommitへ移行

# はじめに
GitHubからCodeCommitへリポジトリを移行してみました。

また、AWSの[こちらのページ](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/how-to-migrate-repository-existing.html)に移行用のドキュメントがありましたので
こちらを参考に進めて行きます。

# 必要な作業
作業内容と行っても複雑なものは特になく

1.移行したいリモートリポジトリをローカルPCにクローン
2.CodeCommitに移行先のリポジトリを作成
3.クローンしたリモートリポジトリをCodeCommitにプッシュ

以上の流れになります。

# リモートリポジトリをローカルPCにクローン
## リモートリポジトリをクローン
今回はリポジトリの移行が目的のため、履歴も持ったベアリポジトリをクローンする必要があります。
※ベアリポジトリとは作業ディレクトリを持たないリポジトリでリモートリポジトリに使用されています。

そのため、--mirrorオプションを付加してクローンします。

```shell
$ git clone --mirror https://github.com/<アカウントID>/<リポジトリ名>.git <クローン先のディレクトリ名>
```

# CodeCommitに移行先のリポジトリを作成（＋その他必要作業）
## マネージドコンソールからリポジトリを新規作成
CodeCommitのマネージドコンソールで「リポジトリを作成」を押下します。
リポジトリの設定画面で任意のリポジトリ名を入力してリポジトリを新規作成します。

## CodeCommitへのプッシュに使用するユーザーを作成
IAMのマネージドコンソールで「ユーザーを追加」を押下し、Git操作で使用するユーザーを作成します。
今回、Gitを通してAWSにアクセスするので「AWS 認証情報タイプを選択」では「アクセスキー - プログラムによるアクセス」にチェックを入れます。

アクセス許可の設定画面で権限を指定します。
「既存のポリシーを直接アタッチ」から権限を検索し、「AWSCodeCommitPowerUser」を選択します。

「次へ」ボタンで進めていくとAWS CLI等の認証で利用するcsvファイルをダウンロード出来ます。

ユーザー作成後、作成したユーザーのページの「認証情報」タブでCodeCommitのHTTPS Git認証情報が生成出来ます。
生成すると、先程と同様に認証情報が記載されたcsvファイルがダウンロードされます。

# クローンしたリモートリポジトリをCodeCommitにプッシュ
## AWS CLIをインストールし、初期設定する
[こちらのページ](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html)を参考にAWS CLIをインストールします。

認証情報類の初期設定は[こちらのページ](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-quickstart.html)を参考に設定します。
※AWSのユーザーを作成した時に取得したcsvファイルの認証情報を利用します。

## CodeCommitにプッシュ
先ほどのクローンで作成したディレクトに移動し、プッシュします。

```shell
$ cd <クローン先のディレクトリ名>
$ git push --all <CodeCommitのリポジトリURL>
```

プッシュする時、Git操作で使用するユーザーの認証情報を求められます。
そのため、AWSユーザーの「CodeCommitのHTTPS Git認証情報」で取得したcsvファイルの内容を使用します。

# 最後に
CodeCommitのマネージドコンソール画面でプッシュした内容や履歴が確認出来ていれば成功です。

# 参考文献
https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/how-to-migrate-repository-existing.html

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

https://www.atlassian.com/ja/git/tutorials/setting-up-a-repository/git-clone#:~:text=git%20clone%20%2D%2Dmirror&text=%E3%81%BE%E3%81%9F%E3%80%81%20%2D%2Dmirror%20%E3%81%AF%E3%80%81%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88,%E6%A9%9F%E8%83%BD%E3%82%92%E6%8F%90%E4%BE%9B%E3%81%97%E3%81%BE%E3%81%99%E3%80%82
時系列データの日付処理【メモ】

## 何があったか
時系列データの取り扱いを学ぶためにまずは、チュートリアルでよく用いられているAirPassengersのデータを読み込むことにしました。

```python
#モジュール
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

#時系列データ関係
from scipy import signal
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.seasonal import STL
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

#データの読み込み
df1 = pd.read_csv('AirPassengers.csv', index_col='Month', parse_dates=True)

df1.head(2)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/0106d265-7f3f-493f-c0cd-f2272dc828c1.png)

ちゃんと日付をインデックスにできているか確認したら。。。**ん？**
本来は1949-01-01スタートなのに、なぜか2049年始まりになっていて。
コードのエラーは出ていないけど、ちょっと気持ち悪いので直せないか調査しました。

## 調査したら
こんな記事を発見。

https://qiita.com/y-vectorfield/items/323960a01d73ec1b4006

簡単にまとめるとExcelのバグらしい。記事はxlsxファイルだが今回のcsvでも同じことが起きていそう。

## 解消方法
csvファイルをExcelで開き、日付部分の数値の書式を標準⇒日付に変えただけ。以上。
根本的な理由は不明ですが、正しい日付で開けるようになりました。
もしかしたらバージョンにもよるかもしれません(自分が使ったExcelは2016年版)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/45861503-a854-35f4-4bba-4b0ddbfc8d46.png)

修正しなくても普通に読み込めるようになると個人的には嬉しいです。

## 参考
https://www.salesanalytics.co.jp/datascience/datascience085/
dmesgでHW情報が分かる

# コマンド
```bash
dmesg -Txk -l err,warn
```

# 出力
<a href="https://gyazo.com/a937462678de2ec339cc50f28176f123"><img src="https://i.gyazo.com/a937462678de2ec339cc50f28176f123.png" alt="Image from Gyazo" width="1888"/></a>


とあるクラウドサーバーだがこんなことが分かるとは。
Django＋uwsgi+NginxでCSRF verificatrion failedが出た

Djangoで作ったwebアプリをNginxとuwsgi使って動かそうとしたら、フォームの送信のところで　`Forbidden(403) CSRF verification failed `のエラーが出た。

Nginxとかの設定は https://office54.net/python/django/ubuntu-django-nginx-uwsgi を参考にした。

ブラウザの F12→コンソール でエラーが出る前後を確認していたら、

```
"secure" Cookie がすでに存在しているため、Cookie "csrftoken" は拒否されています。
```

と出ていたので、ブラウザのCookieを削除したら問題なくフォームが送信できるようになった。
LaravelのDB【個人的なお勉強アウトプット】

## 参考図書
https://www.amazon.co.jp/dp/B07CLLW4MX/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

Laravelはアプリケーションの性格によってデータベース処理にいくつかの機能を用意している。

## DBクラス（クエリビルダ）
DBクラスにあるメソッドを呼び出すことでデータベースにアクセスすることができる。
SQLのクエリを直接実行するのに近い感覚。

## Elopuant(ORM)
DBクラスよりはるかにPHPのオブジェクトらしいアプローチでデータベースを利用できる。

## DBの使い方
Laravelは、標準でMySQL、PostgeSQL、SQLite、SQL Serverに対応している。
データベースの情報はconfigフォルダにあるdatabase.phpにまとめてある。データベースの設定はここから。
環境変数も登録する必要がある。
Laravelは`.env`というファイルに環境変数がまとめられている。
環境変数が.envにない場合、config/database.phpに用意された値が使われるようになる。
Laravelのリダイレクト処理を扱うインスタンス【個人的なお勉強アウトプット】

## 参考図書
https://www.amazon.co.jp/dp/B07CLLW4MX/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

## 参考記事
https://qiita.com/gone0021/items/685cae680fe6163f9a9f

Laravelにはリダイレクト処理を扱う２つのインスタンスがある。

- Illuminate\Http\RedirectResponseクラスのインスタンス
- Illuminate\routing\Redirectorクラスのインスタンス

## Illuminate\Http\RedirectResponseクラスのインスタンス
メソッドチェーンとして使える（`$this`自身を戻り値とする）ものだけ。
### 入力データを付加する
`$response->withInput()`
送られてきたフォームの値を付加してリダイレクト

### バリデータのエラーを付加する
`$response->withErrors(`MessageProvider`)`
エラーメッセージを付加してリダイレクトするもの。
引数には、MessageProviderというインターフェイスを用意する？

### クッキーを付与する
`$response->withCookie('Cookie配列')`
クッキーデータを複数付加してリダイレクトするもの。


## Illuminate\routing\Redirectorクラスのインスタンス
### ルートおよびアクションを指定
`redirect()->route(ルート名,配列)`
`redirect()->action(アクションの指定,配列)`
routeはweb.phpにルート情報として記述したものを指定。
actionは`HelloController@index`のようにコントローラーのアクションを指定

### JSONデータを返す
`redirect()->json(テキスト)`
指定のJSONデータを出力させることができる

### ファイルを返す
`redirect()->download(ファイルパス)`
`redirect()->file(ファイルパス)`
ファイルをダウンロードしたり表示するもの。
times やってたらデブサミ登壇できた話

2022年2月17日に、初めてデブサミでの登壇の機会をいただきました。とてもありがたい経験でした。
https://event.shoeisha.jp/devsumi/20220217/session/3665/

今回の登壇はメインスピーカーの山田さん（@e99h2121）にご指名いただいて実現しました。
ご指名いただくまで正直私は特別なことは何もしておらず、唯一やっていたこととしては times[^1] くらいでした。
つまりタイトルの通り**times やってたらデブサミ登壇できた**ので、そこから得た知見と考えたことをまとめます。

[^1]: times については[こちら](https://qiita.com/satomihoya/items/b125e1eaf44c4a643e6e)の記事をご参照ください。

## 先に結論

今回の経験から得ることができた知見は以下の通りです。

- リモートワークでも、times をうまく活用すれば社内の人脈は増やせる
- 日頃から自分の考えていることを発信することが大事
- それってつまり times 芸人！ times 芸人活動こそがぼちぼち生き延びる道

## 発表内容ざっくりまとめ

会社の大先輩[^2]である山田さんと私が、社内でぼちぼち生き延びるために大事な文書化、資料化、コミュニケーションについて、WHIでの好事例を紹介しながら考えを共有するという内容です。

[^2]: 山田さんは開発歴20年の大ベテラン。最近[私の部署のボスと同期](https://twitter.com/e99h2121/status/1491943123052011520?s=20&t=fZMpT7xCfdPgR8ive6WZBg)であることがわかってﾋｯってなった。

https://speakerdeck.com/whisaiyo/developers-summit-202202

## 山田さんと私（筆者）の関係

当日の発表でも触れたのですが、山田さんとは今回の**デブサミ登壇で初めて一緒にお仕事させていただきました**。
これまでは一緒にお仕事をしたことがなかったので、動いてしゃべる山田さんと会話をしたのは**デブサミ登壇が決まってからの打ち合わせが初めて**でした。

同じ開発部門の社員ではありますが入社年次も違う、部署も違う[^3]、仕事内容も違う。
ほぼ接点のない山田さんと私ですが、2人とも **times をやっていて**、**times 芸人として活動していた**ためお互いの存在は認識していました。
times は相互フォローだったので、**なんとなく知り合い**のようなゆるーいつながりはありました。

[^3]: 正確に言うと一瞬だけ同じ部署にいたような気もします。が、本人同士もよく思い出せないくらいには一瞬なのでノーカンで。

## 相方としてご指名いただくまでの流れ

1. 山田さんがデブサミ公募枠を獲得（ほんとすごい）
2. 山田さんが一緒に登壇する相方を探し始める[^4]
3. 私の times にて、山田さんからご指名いただく
4. 私、二つ返事でOK

![qiita-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908526/15142ca2-efa8-ba44-2aae-27ea6d4972fc.png)

[^4]: https://qiita.com/e99h2121/items/1023521c373364f4d17f#二人登壇形式

## なんで声をかけてもらえたのか？

流れを見るだけだと本当にたまたま声をかけてもらえたように見えますが、実際は声をかけていただけたことにはいくつか理由があると思っています。

### 理由その１：times やってた

大前提です。
前述の通り私と山田さんは一緒にお仕事をしたことがないので、つながりは times だけです。

逆に言えば、times のつながりだけで一緒にデブサミ登壇するくらいの意気投合ができるということです。
**リモートワークでも times のおかげで社内の人脈が広がった**:blush: という素敵な事例だと思います。

### 理由その２：日頃思っていること、課題に感じていることを times で投稿していた

私の times では個人的なタスク整理や MTG の感想などを投稿することが多いのですが、たまにふと考えたことをつぶやきます。

![qiita-4-hide.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908526/3a8e7161-3665-d544-7612-c697bc1510a8.png)


どうしても解決にこぎつけたい！というわけではなく、自分の思考の整理や、今後業務に生かせそうなことをまとめる意味合いで書いています。
他にも同じようなことを課題に感じている方がいると、スレッドで議論が始まったりします。↑の投稿でも、リプライで何人かからご意見をいただけました。

日頃考えていることを times に投稿していると、他の方にも自分の考えが公開されるので **「この人は普段こんなことを考えている人なんだな〜」と認識してもらえます**。

今回いただいたデブサミ登壇のご指名も、山田さんが私の times を見ていて「この人なら今回の発表内容に共感してくれそう」と認識してもらえていたので、ご指名をいただくことができました。
**自分の興味のあることを発信しているとその方向のお仕事をいただくチャンスが増える**:muscle:ということだと思います。

## デブサミ登壇（までの流れ）から得られたこと

以下のような知見を得ることができました。
今回はたまたま「デブサミ登壇」という成果に結びつきましたが、普段の業務でも活かせることではないかと思います。

- リモートワークでも、times をうまく活用すれば社内の人脈は増やせる
- 日頃から自分の考えていることを発信することが大事
    - 興味のあること、課題に感じていること、得意なこと、etc
- それってつまり times 芸人！ times 芸人活動こそがぼちぼち生き延びる道

## まとめ

社内コミュニケーションの活性化のため、リモートワークでぼちぼちやっていくため、うまく times を活用していきましょう！

### 余談

お誘いをいただいた後に聞いた話なのですが、山田さんが私に声をかけるときには「**誘ったら十中八九いけるだろう（=承諾してくれるだろう）**」と思って誘った、とのことでした。

確かに私は以前、time で「声をかけていただいたお仕事は基本断りません！」と公言していたような気がします。
その投稿を山田さんが目にしていたのかは定かではありませんが、どうやら「この人は声かけたらOKしてくれる」と認識いただいていたようです。ありがたい。

「基本断りません！」「いつでも声をかけてね！」というオーラを出していると、声をかけてもらいやすくなるのかもしれないです。巻き込まれ力？
Xcode 13.3 で再ビルドすると「Cycle inside UnityFramework」と表示されてビルドできない問題

# Xcode13.3でビルドできない問題 
私の場合Unityで起こった問題なのだが、Unityに限らないと思われる。

Xcodeを13.3に上げた時から、以下のエラーでビルドできなくなってしまった。

```
Cycle inside UnityFramework; building could produce unreliable results. This usually can be resolved by moving the target's Headers build phase before Compile Sources.
```

Unityで「Build & Run」すると上記エラーで進めなくなってしまう。
ただし、まっさらな状態からビルド(Build->Replace)すれば、なぜかうまくいく。
ただ毎回クリーンビルドするのは時間がかるので、何とかしたい。

# 解決法

エラーメッセージをよく読めば、解決方法が書いてあった。

`This usually can be resolved by moving the target's Headers build phase before Compile Sources.`

つまり

`「UnityFramework」　の　「Build Phase」 で「Compile Sources」の前に「Headers」を置けば大体の場合直る`

ということ。


そういうわけで、以下のように順番を変えてみた。

![スクリーンショット_2022-03-27_15_42_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/27cd167b-25d4-de52-7824-497435fe0e01.png)

これで正常にエラーが出ないで再ビルドが可能になった。

おそらく Xcode13.3 と Unity の現バージョンとの相性の問題だろうから、いずれ直るだろうと思われる。(2022/3/27時点)
メソッドチェーンとは【個人的なお勉強アウトプット】

## メソッドチェーンとは
メソッドの実行結果に対して、変数などを介入せずに直接他のメソッドを実行すること

## メソッドチェーンのメリット
可読性が上がる。
不必要に変数定数を宣言しなくてよくなる

## 処理内容
直前のメソッドの戻り値に対して処理を行っている。

## 参考サイト
https://travel.rakuten.co.jp/mytrip/ranking/spot-karuizawa
#PowerAutomate ビジネスプロセスフロー から クラウドフローを実行する

ビジネスプロセスフローを使うと、業務プロセスの標準化を図ることができます。
業務プロセスの段階を定義して、それに必要な情報の入力を促したり、入力データに併せてステージを分岐するといったこともできるわけです。
詳しく知りたい方は、こちらの Microsoft Learn をぜひお試しください

[Microsoft Learn | Power Automate でビジネス プロセス フローを作成する](https://bit.ly/RtAnM-MSL-PABF)

さて、こちらのビジネスクラウドフローから、クラウドフローを呼び出し、その結果もステージに組み込むことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/fb3e5e2b-36dd-aadc-78e2-4a3e93c534ed.png)

クラウドフロー側に承認アクションを設置したりすることで、業務プロセスをより効率的に標準化することができます。

# 前提条件

ビジネスプロセスフローとクラウドフローは、同一環境にソリューションの一部として登録されている必要があります。
※同一ソリューションである必要はありません。

# クラウドフロー側の作成

## トリガー

トリガーに、Microsoft Dataverse アクションの「ビジネス プロセス フローからフロー ステップが実行された場合」を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/02c96366-6a36-1945-0030-db8b7abc8c9b.png)

入力の追加で、様々な入力パラメータを指定することができます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/340cc206-d876-42b9-da8e-f9091499f105.png)

指定した入力パラメータは、ビジネスプロセスフローから呼び出した際に、以下のように表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/d799b2cc-8399-0fd9-ec50-311788315d35.png)

## 応答結果の戻し方

クラウドフローを実行した結果をビジネスプロセスフローに返す必要があります。

### アクション

Microsoft Dataverse アクションの「行を更新する」を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/f99ab143-5029-9611-88ca-58e3836e3f2b.png)

### テーブル

ビジネスプロセスから呼び出されたクラウドフローは、「プロセスログ」 テーブルにて管理されていますので、こちらのテーブルを更新します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/8126faaf-1595-d35c-9f26-3f12ac93c598.png)

### 行ID

トリガーの動的コンテンツにある「Flow ワークフローのログ ID」が該当しますので、その値を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/f66ea83f-6bb1-be26-1f30-d2b3a3ae24b4.png)

### 状態

5つのステータスが選択できます。
処理の内容に合わせて、状態を指定してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/e1658ef6-6f5a-20e7-1e23-7f89a2244ae7.png)

指定した結果がビジネスプロセスに反映されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/b76022e2-fb6b-8b64-bcce-60293187f140.png)

# ビジネスクラウドフロー

コンポーネントから、「フローステップ」を追加します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/d7e07e02-dae8-4e46-b506-b1cba2925d79.png)

フロー選択から、作成したフローを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/7d29fb21-4dc3-10ae-7615-49ffbc343186.png)

※この一覧に表示されるのは、ソリューションとして登録されているフローのみです


# まとめ

というわけで、ビジネスプロセスフローとクラウドフローの連携、ちょっとひと手間ありますが、作ってしまえばとても有用なモデル駆動型アプリとして作ることができ、一連の入力業務を一気通貫で定義してあげることができつつ、インタラクティブにすることもできるようになり、業務効率化がさらに加速するんじゃないでしょうか。

ぜひ、クラウドフローやデスクトップフローと共に、ビジネスクラウドフローも試してみてくださいね！
find_or_initialize_by / find_or_create_by の違い

## find_or_initialize_byとは
条件に合致したインスタンスがデータベースに保存されているかどうかをチェックしている。

この時、
・データベースに**保存されている**場合は``findメソッド``
・データベースに**保存されていない**場合は``newメソッド``

として、インスタンスの状況によって適用されるメソッドが異なることがポイント。

インスタンスが保存されている場合、``findメソッド``が適用されるのでインスタンスに保存済みのデータ(idなど)を含めることができる。

``インスタンス = persisted?``や``インスタンス = new_record?``でデータベースの保存状況を真偽値で取得できる。

## find_or_create_byとは
上記の``find_or_initialize_by``と非常によく似ている。条件に合致したインスタンスがデータベースに保存されているかどうかをチェックしている点は、両者とも同じ。

その際に、``find_or_create_byメソッド``は、

・データベースに**保存されている**場合は``findメソッド``
・データベースに**保存されていない**場合は``createメソッド``

となることがポイント。「データベースに保存されていない場合は``createメソッド``」となる。

条件に合致した情報をデータベースに保存していくというケースに適している。

## 参考記事
[【Rails】find_or_initialize_byメソッドを使ってインスタンスを作成する時のポイント](https://qiita.com/yuki_0920/items/b01499848e345e3edb48)
Hugo で記事の URL をカスタマイズ

# はじめに
- 静的サイトジェネレータの [Hugo](https://gohugo.io/) では、記事の URL 階層はデフォルトではディレクトリ階層と一致します
- ですが、場合によっては変更したい場合があります
    - ブログ記事などでは、たとえば ``/diary/2020/04/19`` のような形式にしたい場合もあるでしょう
    - そのためにディレクトリを細かく設定していくのは面倒です
- その際に、必要な設定について記載します

# 検証環境
- hugo v0.93.3

# カスタム URL の指定（Permalinks の設定）
- ``config.toml`` に ``[permalinks]`` 項目を追加することで、記事のパスを自由に設定できます

## サンプル
```toml:config.toml（抜粋）
[permalinks]
  posts = '/:year/:month/:day/:filename/'
```

- 上記の例では、 ``contents/posts`` に配置された各記事の URL は ``2020/04/19/拡張子を除いた記事のファイル名/`` のような形式となります
    - 出力イメージは、[私のブログ記事](https://yagamo-style.com/2022/03/17/hugo-custom-url/)の URL をご覧ください
- ``:year`` のような設定値は他にも用意されているので、必要に応じて公式サイトで確認すると良いでしょう

# まとめ
- URL を物理的なディレクトリ階層と分けられれば、記事の管理がグッと楽になります
- また、途中でディレクトリ階層を変更しても、記事の URL が変わらないのがありがたいですね
- なお、この記事は[私のブログ記事](https://yagamo-style.com/2022/03/17/hugo-custom-url/)からの転載です

# 参考
- [URL Management | Hugo](https://gohugo.io/content-management/urls/)
PDFデータをアウトライン化する方法

# アウトライン化とは？
まず、下記の２つの画像を見てください。
左の画像が「アウトライン化前」のPDFで、右の画像が「アウトライン化後」のPDFです。
<p>
  <img width="30%" margin-right="20px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852882/73048107-0ca8-7a42-5993-208a858de95d.png" />　<img width="30.2%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852882/c148a6fc-6d4d-5f98-6b43-3897b617b924.png">
</p>

左の画像では、文字を選択できる状態になっているのが分かるでしょうか？
右の画像では、一見すると文字があるように見えていますが、実際には **「図形の一部」** となっており、選択することができません。
PDFファイルというのは、見た目では同じに見えていても、実際にはテキストデータと図形データの両方が組み合わさって構成されています。この状態から、**テキストデータ**を**図形データ**に変換する作業を **「アウトライン化」** と言います。

# なぜアウトライン化が必要なのか？
たとえば、PDFの中に、旧字体の漢字が使用されていたとします。その旧字体は、お使いのパソコンでは表示されても、他のパソコンでは表示されなかったりします。他にも、フォントが勝手に変わってしまったり、文字化けが発生するなど、 **文字データは、各パソコンの環境によって表示が変わることがある** のです。

文字データを図形データにしておけば、よほどのことがない限り、どの環境でも同じような見た目になるため、印刷時に不具合が発生しにくくなるのです。

# アウトライン化をする方法（Windows）
※Windowsパソコン限定の方法となります。
※ブラウザは「Chrome」を使用しています。「Edge」や「Firefox」を使用している場合は、適宜読み替えてください。

①PDFファイルを開き、右上のプリンターマークを押します。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852882/e141456f-12ca-4b28-ec7d-86d60be49423.jpeg)
②送信先「Microsoft Print to PDF」を選択し、「印刷」を押します。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852882/8fe93814-5c74-1a35-64f5-3bf1a97774c4.jpeg)
③ファイル名を指定し、保存します。
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852882/c31da932-cf70-0699-772f-e43bcda0460f.jpeg)


以上でアウトライン化は完了です。
実際に、保存したPDFをひらき、文字の部分を選択してみてください。選択できなくなっていることが確認できるはずです。

# おわりに：どのような場面で使うのか？
自分が印刷業者にチラシなどを発注した際に、要求されることが最も多くなります。
もし、「アウトライン化してください」と言われて、うまく出来ない場合は、こちらの記事を参考にしてみてくださいね！
SharePointリストの「いいね」したユーザ情報を取得する

# はじめに
SharePoint 2016 の「いいね」の評価が有効になったリストにおいて、「いいね」をクリックしたユーザ情報を取得する要件が出てきました。
Webブラウザ上で確認する方法は既定の機能で用意されているのですが、その方法ではユーザ情報を一覧形式で取得できないため、SharePointのAPIを使用して一覧取得する方法を紹介します。

# SharePointのAPIを利用して取得する方法
リスト内のアイテムに対し「いいね」したユーザー数やユーザー名を確認する場合、SharePoint Server APIの[SPList](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.sharepoint.splist?view=sharepoint-server)クラスと[SPListItem](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.sharepoint.splistitem?view=sharepoint-server)クラスを使用します。

取得する手順は[SPList](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.sharepoint.splist?view=sharepoint-server)クラスの`GetItemById`メソッドを使用して「いいね」されているリストアイテムの情報を取得し、[SPListItem](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.sharepoint.splistitem?view=sharepoint-server)クラスの以下2つのプロパティから「いいね」に関連した情報を取得することができます。
* `LikesCount`：「いいね」の数
* `LikedBy` 　 ：「いいね」したユーザーコレクション

<br>
「いいね」したユーザーの一覧をCSV形式でファイル出力するスクリプトの一例です。

`GetItemById`メソッドでアイテム情報を取得し、`"LikeBy"`のプロパティからユーザー情報を取得しています。
SharePoint ServerのSharePoint管理シェルでお試しください。

~~~powershell
$web = Get-SPWeb "サイトのUR>"
$list = $web.Lists["リスト表示名"]
$item = $list.GetItemById("アイテムID")
$item["LikedBy"] | Export-CSV "CSVファイルパス"
~~~

* "サイトのURL" には、取得対象のリストが存在するサイトコレクションもしくはサイトのURLを指定してください。
　　例）`Get-SPWeb http://(サーバー名)/sites/(サイト名)`
* "リスト表示名" には、対象のリストの名前を指定してください。 
　　例）`$web.Lists["お知らせ"]`
* "アイテムID" には、「いいね」されているアイテムのIDを指定してください。
　　例）`$list.GetItemById(1)`
* "CSVファイルパス"には、CSVファイルの出力先をフルパスで指定してください。 
　　例）`Export-CSV "C:\\SharePointData\LikedUsers.csv"`

# （参考）Webブラウザ上で確認する方法
本題から外れますが、Webブラウザ上で「いいね」したユーザを確認する方法も紹介します。
リストのビュー上で「いいね」されたアイテムの行にある顔マークにマウスカーソルを合わせるとポップアップが表示され、「いいね」したユーザーの名前を確認することができます。
Webブラウザ上で確認する方法としては、これ以外に既定の機能が用意されておらず、一覧形式で取得することができません。
NuxtにCSSをお作法に則りながら導入

# 前提
ホームページ制作はCSSゲーであると感じたため、CSSをNuxtに導入しようと思った。

そのとき、結構忘れそうな内容だったため、メモる。

また、ここで初めてSCSSなる非常に革命的なものに出会ったため、その導入方法等も記載する。

# SCSS導入方法
なんとNuxt.jsはSCSSをサポートしている
```
npm install sass sass-loader fibers
```
その後、`nuxt.config.js`にて以下を書き込む
```JavaScript:nuxt.config.js
const Sass = require('sass')
const Fiber = require('fibers')

export default {
  // build.loaders のセクションに scss オプションを追加
  build: {
    loaders: {
      scss: {
        implementation: Sass,
        sassOptions: {
          fiber: Fiber
        }
      }
    },
    /*
     ** You can extend webpack config here
     */
    extend (config, ctx) {
    }
  }
}
```
これでOK！ばり簡単

# 普遍的なCSSの場合
## ディレクトリ構造
`assets/styles(またはcss)/common.css`

## nuxt.config.js
`nuxt.config.js`の`css:[]`内に以下を記述する
```JavaScript:nuxt.config.js
export default {
  // ...
  /*
  ** Global CSS
  */
  css: [
    "~assets/styles/common.css"
  ],
  // ...
}
```
これで適用されるはず

## SCSSで書きたいとき
`assets/scss/common.scss`を作成

`nuxt.config.js`に記入したパスもこれに変更することを忘れてはいけない

# 個別のCSSの場合
Vueファイルの\<style>に直接書き込むだけ。

めっちゃ便利

ただし、ページ遷移後にもサイト全体に適用されるため、（Nuxtぽい笑）

`<style>`を`<style scoped>`と表記すればいいようだ。

## SCSSの場合
同様に
```JavaScript:pages/index.vue
<style lang="scss" scoped>
  $color: red;
  p{
    color: $color;
  }
</style>
```
とすると良いようだ。

またここがすごいところで

SCSSのimport構文でassets/scss/に作成したSCSSファイルからimportすることもできる
```JavaScript:pages/index.vue
<style lang="scss" scoped>
  @import "~assets/scss/mixins.scss"
  p{
    color: red;
  }
</style>
```
mixinを共有できるのは非常によき

# まとめ
意外と簡単だが～とか忘れそうなので気をつけます。

参考：https://lessons.lec.cafe/nuxtjs_website/05.scss.html#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E3%81%AAcss%E3%81%AE%E5%88%A9%E7%94%A8
known_hostsファイルについて

AWS上にSSHでログインしてみたところ、エラーが発生したので備忘録として書き残します。

# エラー
```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
fingerprint
Please contact your system administrator.
Add correct host key in /Users/tomo/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Users/tomo/.ssh/known_hosts:22
Host key for IP has changed and you have requested strict checking.
Host key verification failed.
```
こちらは、「SSHキーが変わった」と言うメッセージになります。
エラー内容をよく確認すると、こんなメッセージがありました。
```
Add correct host key in /Users/tomo/.ssh/known_hosts to get rid of this message.
```
こちらは正しいキーをknown_hostsのファイルに追加して下さいとのことです。
逆に言えばknown_hostsのファイル内の該当コードを削除すればよいのかと思い削除しようと思います。

# known_hostsとは
sshのknown_hosts とは、サーバのホスト鍵(host key)の１つのホスト公開鍵を登録するファイルです。

# known_hostsnの該当コードを削除について
下記のようにssh-keygenコマンドの-Rオプションに私の場合は、IPアドレスを入力した所、IPアドレスの該当コードが削除されました。
```
$ ssh-keygen -R IPアドレス
# Host IPアドレス found: line 20
/Users/tomo/.ssh/known_hosts updated.
Original contents retained as /Users/tomo/.ssh/known_hosts.old
```

# これが原因じゃなかった
こちらのエラーはknown_hostsnの該当コードを削除したら解消しましたが、AWS上にSSHでログインできないのは別の原因みたいです。
Safariで別タブでBASIC認証のページを踏むとフリーズする

# 概要
iPadで別タブでBASIC認証のかかったページを踏むと、認証後2,3秒してフリーズしてしまうバグに悩まされていました。
しかも再現するときとしない時が、、なぜ。
あまりにも原因として考えられるのが多すぎるので、他の原因もあるかもしれませんが、
とりあえず備忘録として残します。

# 前提条件
iPad 第７世代 / iPad Air2
iOS 15.4
Safari 15.4

# 解決
今回新規タブを開くのに`window.open`を用いていましたが、
これをシンプルに
`<a id="link1" href="リンク" target="_blank" rel="noopener">リンク</a>`
として、別タブで起動すると問題なく動作しました。

どうしてもjsでやりたければ`document.getElementById("link1").click()`とかでも。

# なぜ？
完全な憶測です。
恐らくJSによるジャンプは動作せず、HTMLによるジャンプなら大丈夫という感じかと思われます。
Safariの微妙に対応してない部分とか考えると何かそんな気しなくもないんですが、、

そもそもSafariはBasic認証の情報が保存されなかったり上書きされたりで、
相性がかなり良くないっぽく、その内の一つのバグかも知れません。

## 追記 2022/03/28
15.4のSafariが結構抱えてるっぽいです。
手持ちのデバイス全部アップデートしちゃったんですが、
確かにアプデ前(恐らく15.2くらい)に検証していたソフトで発生しているので、
15.4のタイミングで何か変わったかもしれません。