OmniAICreator/Qiita-1.07M huggingface dataset:
組織の制限付きのChromebookにAndroidアプリをインストールする

:::note warn
注意
ChromeOS 110(109?)辺りでバグ修正が行われ、デベロッパーモードに移行しないとワイヤレスデバッグを有効化できないようになってしまいました。ワイヤレスデバッグを使用してAndroidアプリをインストールしたい場合、Chromebookをデベロッパーモードに移行してください(自己責任)。
:::

# 準備
##### 必要なもの
- Chromebook
- Windows搭載PC
- WiFi
- インストールしたいアプリのAPKファイル

##### ADB環境をインストール
ここではADB環境のインストール手順については割愛します。
Googleで「adb インストール」と調べたらいくらでも出てきます。

##### ワイヤレスデバッグの有効化・ペアリング
- Chromebook
1. [設定] -> 左側の[アプリ] -> [Google Play ストア] を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483049/6e69f1a0-b7f5-28fc-3338-fa8388e2e3de.png)
1. [Android 設定を管理] を開く
1. 下の方にある [デバイス情報] を開く
1. [ビルド番号] を20回くらい連打
1. 戻って [システム] -> [開発者向けオプション] を開く
1. [ワイヤレスデバッグ] -> ONにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483049/7cc52367-c5a2-3db0-8073-19a0b26acbd9.png)

1. [このネットワークでワイヤレス デバッグを許可しますか？]というメッセージが出てきたら [許可]を押す
1. [ペア設定コードによるデバイスのペア設定]を押す
1. [IPアドレスとポート]の下に書いてあるIPアドレスをメモしておく (IPアドレス①とする)
1. 出てきた6桁の数字(ペアコード)とIPアドレスをメモしておく (IPアドレス➁とする) ([キャンセル]は押さない)

- Windows PC
コマンドプロンプト or PowerShellで以下のコマンドを実行
``` sh
> adb.exe pair (メモしたIPアドレス➁) (6桁のペアコード)

# 例) adb.exe pair 192.168.1.3:12345 654321
```

Successfully paired to (メモしたIPアドレス➁) ... と表示されたらOK

# Chromebookに接続

コマンドプロンプト or PowerShellで以下のコマンドを実行
``` sh
> adb.exe connect (メモしたIPアドレス➁)

# 例) adb.exe connect 192.168.1.3:23456
```

connected to (メモしたIPアドレス➁) と表示されたらOK

# アプリをインストール
コマンドプロンプト or PowerShellで以下のコマンドを実行
``` sh
> adb.exe -s (メモしたIPアドレス①) install (APKファイルのフルパス)

# 例) adb.exe -s 192.168.1.3:23456 install 'C:¥Users¥hogehoge¥Downloads¥Twitter.apk'
```
最後にSuccessと表示されたら、アプリのインストール成功!!

## 注意
今回実験したChromebookでは、Chrome ポリシー 'ArcAppInstallEventLoggingEnabled' が有効だったため、教育委員会や学校側のGoogle 管理コンソールの監査ログなどからアプリのインストールがバレている可能性があります。

※ポリシーは chrome://policy で確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483049/1d88ae9f-85ce-43db-c3f1-cbab1377c2d1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483049/b701b22e-7b87-1d9b-26f5-92adb6ffdeb4.png)
https://chromeenterprise.google/policies/?policy=ArcAppInstallEventLoggingEnabled

**アプリのインストールを行う際は、危険性を理解し、自己責任でインストールしてください。**
Looking Glass + M1Mac + Blenderの動作メモ

# はじめに

M1Macに変更したあと、Looking Glass 8.9とLeapMotion再セットアップしたので、メモとして残しておきます。(久しぶりにやったらリンクなどもろもろなくなっていたので。。) 

# HoloPlay Service

HoloPlay Service -> Looking Glass Bridgeに移行が進んでいるそうですが、いれてみても、Looking Glass 8.9では、認識せず、HoloPlayServiceをいれなおしました。Looking Glass Bridgeが入っている状態で、上から、Looking Glass Bridgeをインストールしましたが問題なし。
(下記からDL)

https://docs.lookingglassfactory.com/getting-started/looking-glass-bridge/troubleshooting

# Looking Glass Studio

# Blender Plug In

https://github.com/regcs/AliceLG/releases

![スクリーンショット 2023-01-21 8.51.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/a7b99b3f-105e-0257-86bf-5a3ac0e2287f.png)
![スクリーンショット 2023-01-21 8.52.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/1ff841c7-d366-c1d8-7b74-84aec265b7ee.png)
![スクリーンショット 2023-01-21 8.53.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/67c612bc-ed9d-6212-578c-4103f0a3b6dd.png)
![スクリーンショット 2023-01-21 8.53.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/20b974a9-01a2-4e02-9919-d4b811bc67c7.png)
![スクリーンショット 2023-01-21 8.53.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/bf6dcaa8-1c17-e877-7126-a7575e3d38da.png)
![スクリーンショット 2023-01-21 8.57.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/8d75227d-0868-9bdc-b5cf-423397fa1ba1.png)

![スクリーンショット 2023-01-21 9.05.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/72dfe4db-2a54-8918-cb28-3d10aa0939d0.png)


# 読み込み

![スクリーンショット 2023-01-23 16.25.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/21d60410-ae9e-25f3-c44e-d61eb88cb47a.png)
スピルの連結

# 複数のスピルの連結

[知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11240867326)の焼き直し。
作った式が後で見て、わけわかめになるので、メモ。

## 使用例

指定した範囲（```開始```,```終了```)と、周辺の値を取ってきて、連結する。
イメージとしては、図の表から、オレンジ色の部分を中心として取ってきて、
青い部分を周辺として取ってくる。
```開始```,```終了```の値は、色々変えて観測したい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455423/a10bc54a-cdb1-edd3-b1a4-ffe364e0d0a0.png)

## 式の説明
```vb
=LET(
 '変数定義
 B,$B$5,     '表の起点. offset関数で使用
 S,F4,       '開始行
 L,F5,       '終了行
 C,F6-1,     '参照列. offset関数で使用
 D,L-S+1,    '選択範囲の行数
 P,INT(D/2), '周辺（選択範囲手前）の行数
 N,D-P,      '周辺（選択範囲後）の行数
 '式本体
 '要素（スピルを含む）を連結して、分割する。
 'TEXTSPLITが使えるようになれば、FILTERXMLはいらない。
 'FILTERXMLはタグ(<b>)で囲まれた要素を個別に取ってきているだけ。(FILTERXMLはdesktop windows限定機能らしい)
 'TEXTJOINは各要素がタグで囲まれるように、連結している。
 FILTERXML("<a><b>" & TEXTJOIN("</b><b>",TRUE, ' <a>タグはダミー。<b>タグで囲む
   '連結したい要素を列挙
   "中心",
   OFFSET(B, S-1, C, D, 1), ' 選択範囲を取ってくる
   "　",
   "周辺",
   OFFSET(B, S-1-P, C, P, 1), ' 周辺（選択範囲手前）を取ってくる
   OFFSET(B, L, C, N, 1) ' 周辺（選択範囲後）を取ってくる
  ) & "</b></a>", "//b") ' "//b"は<b>タグの要素を取ってくるXPath
)
```

Excelの式の中に直接コメント書ければいいのに。。。

## 実例

### No列を取ってくる
```vb
=LET(
 B,$B$5, 
 S,F4,
 L,F5,
 C,0,
 D,L-S+1,
 P,INT(D/2),
 N,D-P,
 FILTERXML("<a><b>" & TEXTJOIN("</b><b>",TRUE,
   "中心",
   OFFSET(B, S-1, C, D, 1),
   "　",
   "周辺",
   OFFSET(B, S-1-P, C, P, 1),
   OFFSET(B, L, C, N, 1)
  ) & "</b></a>", "//b")
)
```

### 値列を取ってくる
```vb
=LET(
 B,$B$5,
 S,F4,
 L,F5,
 C,F6-1,
 D,L-S+1,
 P,INT(D/2),
 N,D-P,
 FILTERXML("<a><b>" & TEXTJOIN("</b><b>",TRUE,
   "中心",
   OFFSET(B, S-1, C, D, 1),
   "　",
   "周辺",
   OFFSET(B, S-1-P, C, P, 1),
   OFFSET(B, L, C, N, 1)
  ) & "</b></a>", "//b")
)
```
デプロイレスでログをコントロールする取り組み

# はじめに

本田技研工業のRoadSyncチームのバックエンドを担当している中村です。

外部への発表を積極的にやっていこう、という趣旨でTechブログの投稿第一弾になります。

# TL;DR

- デプロイレスでログの流量制御ができるようになってるよ。
- UserIDやAPI、リクエストの処理時間などでログ出力の可否を決めているよ。
- ログの出力を決定する定義はGCS上にJSONで保存して、定期的に読み込んでいるよ

# RoadSyncとは

![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/38628d15-c76c-74d0-2cc5-b8a9a23bc4b8.png)


バイクを運転中にハンドルスイッチとボイスコントロールでメッセージや音楽、ナビゲーションなどを安全に操作することのできるアプリです。

Hondaではこのアプリの内製化に取り組んでいます。

# バックエンドの課題

## バックエンドの全体像

バックエンドチームはGCP上で(そこそこイケてる)インフラを構築しています。

Firebaseで認証したリクエストをCloudRunで受け取り、DBとBigQueryへ流し込んでいるのが大まかな流れになります。

また、開発体制としてDev,Stag,Prodの3段構成をしており、

- Dev = バックエンドの開発用
- Stag = クライアント及びQAの検証用
- Prod = 本番

として運用していました。

以下、ざっくりとしたシステム構成。よくあるGateway、サービス、DBの3段構成です。(実際はもう少し複雑ですが)

![Untitled (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/e00afa58-a057-7701-5551-96b2b96fabef.png)

## ログの利用状況

ログが活用できそうな場面としては以下の業務が想定されます。

| 業務 | 要望 |
| --- | --- |
| エラー監視 | ERROR, WARNレベルはマストで見たい。<br>でも、INFOレベルは場合によっては見たい。(直近でリリースしたAPIなど) |
| バックエンドの機能開発と運用改善 | 全部見たい |
| クライアントのAPIを利用する機能の確認 | Prodで検証する場合、テストアカウントだけ全部のログを見たい
Stagで検証する場合、基本的に全部見たい |
| BigQueryをベースにした分析基盤の提供 | バッチ処理のステータスや結果はINFOログに出しておきたい |
| カスタマーサポートから上がってくる不具合の調査 | カスタマーサポートへコンプレインを寄せていただいたユーザのログを追跡し、状況の再現などを監視したい |

従来はログのON/OFFの切り替えのために環境変数をフラグにしたFeature Flag的な運用をしていましたが、以下のような欠点があります。

- 一つのログの切り替えにデプロイが発生する
- Weeklyのリリースを行っている中で、Prodへの反映はどうしても遅れる
- Dev,Stag,Prodが今どの出力制御になっているか把握がしんどい

また、CloudRunのログ形式にフォーマットされておらず

- メタデータが構造化されておらず、ログの種類によって表記がまちまちだった
- ErrorReportingっていう超便利なエラー管理サービスでコントロールできていなかった

という弱点も同時に抱えておりました。

# Logger

## Overview

そこで、Ruled Loggerを紹介します。以下を満たした実装で、NestJS上で動作しています。

- 定期的にGCS上に保存している`rules.json`を見に行く
- エラーのレベルはERROR/WARN/INFOの3つ
- ERRORとWARNは常に出力、INFOは`Rule`に応じて出力を決定
- ログの呼び出しにはメタ情報(UserIdやApiNameなど)を付与する必要があり、構造化された形式でLoggingされる
- INFOが呼び出された際、`rules.json`をパースし理解した簡易的なルールエンジンが動いており、メタ情報と`rules.json`を照らし合わせて出力するかを決定します。

## どんなことができるのか

### Ruledな機能

- 特定のAPI/ユーザ/アプリバージョン/プラットフォームだけ、ログを出力 - - - 条件とする
- 条件にマッチしたログで、レスポンスまでの処理に一定時間以上掛かった場合のみ出力
- 条件にマッチしたログを一定の確率で出力

### 構造化機能

- Cloud Loggingの画面で、特定の条件を満たすログだけをフィルタリングできるようなった
- TraceIdが付与されて、リクエスト単位でログを辿れるようになった
- デプロイフローとは別の経路でログを出力できるようになった
- ERRORはErrorReportingに記録されるようになり、エラーのトリアージが可能になった

## できたもの

ルールは以下のような定義ファイルを参照する。

カスタマーサポートから打ち上げがあると、ログを有効にしてアプリのサービス向上に役立てたり

リリース直後のAPIはとりあえずログを吐き出すようにしたり、何かと使いみちがあると思います

```json
{
	  "$schema": "./schema.json",
      "description": "enable logging at Trips",
      "userId": ["xxxxxxxxxxx"],
      "platform": ["android"],
      "samplingRate": 1,
      "apiName": [
        "GetTripDetail",
        "ListTrips",
        "DeleteAllTrips",
      ],
      "options": {
        "timeOption": true
      }
    }
```

日々のログ管理画面はメタ情報が付与され、出力がコントロールされ

![Untitled (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/b0efd2ae-4d15-5f22-36ad-3f6a9db12134.png)

GCPの神サービスの一つErrorReportingにも集約されます

![mosaic_20221228173239 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/c8a3a46b-8400-8c74-3a95-136b6f11a6c4.png)

---

## 結論

- ログは丁寧に構造化しよう。
- デプロイで変更する機能とデプロイ外で変更する機能を分離しよう。
ChatGPTにMySQLのダミー用データベースを作成してもらった

# きっかけ
「MySQLのダミー用データベースがほしいな」
「[Dummy data for MYSQL database](https://filldb.info/)とか使えばいいのかな。使ったことないからちょっと面倒。」
「ChatGPT使ってみるか」

# やったこと
## ChatGPTにお願いする
Promptに以下のように入力しました。
>Give me the code of MySQL in order to generate dummy database.

爆速で解答とコードが返ってきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950855/6c3f5a75-a5a5-20c6-e66b-86d3582cf4ae.png)

>Here is some example code that you can use to generate a dummy database in MySQL:
```sql
-- Create a new database
CREATE DATABASE dummy_db;

-- Select the dummy database
USE dummy_db;

-- Create a new table called 'employees'
CREATE TABLE employees (
  id INT AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(255),
  last_name VARCHAR(255),
  email VARCHAR(255),
  age INT
);

-- Insert some dummy data into the 'employees' table
INSERT INTO employees (first_name, last_name, email, age)
VALUES ('John', 'Doe', 'john.doe@example.com', 35),
       ('Jane', 'Doe', 'jane.doe@example.com', 32),
       ('Bob', 'Smith', 'bob.smith@example.com', 42),
       ('Samantha', 'Johnson', 'samantha.johnson@example.com', 29);
```
> >This code will create a new database called "dummy_db", and create a table called "employees" with columns for id, first_name, last_name, email, and age. It also inserts some dummy data into the table.
 > You can also use the SELECT statement to check the data.
```sql
SELECT * FROM employees;
```
>Please note that this is a basic example and you can adjust it to your needs.

## MySQLでSQLクエリを実行してみた
ubuntuでMySQLを実行してみました。
```bash
$ vim dummy.sql
```
でChatGPTが作ってくれたSQLをコピペしました。

```bash
$ mysql < dummy.sql
```

MySQLを起動し，クエリを実行してみたところ，ちゃんとデータベースができてました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950855/5219f328-66e0-cacf-d735-601598dac508.png)

## 終わりに
ChatGPTの使い方としてはあまりにも小さすぎる気がしますが，ひとまず私もChatGPTの恩恵を感じることができました。
ROS2 Gazebo上のロボット位置の真値をトピックで出力する方法

# はじめに

ROS2のGazeboでロボットのGazebo上の真の位置をROS2トピックで出力する方法のメモ
ROS1と同じく`libgazebo_ros_p3d`プラグインを使う。


# 実装

ロボットのsdfまたはurdfファイル内に以下を記述する。
ROS1の時と記述が異なるので注意。

```xml:model.sdf
      <plugin name="p3d_base_controller" filename="libgazebo_ros_p3d.so">
        <ros>
        <namespace>p3d</namespace>
        <remapping>odom:=odom</remapping>
        </ros>
        <frame_name>map</frame_name>
        <body_name>base_footprint</body_name>
        <update_rate>10.0</update_rate>
        <always_on>true</always_on>
      </plugin>
```

この例ではnav_msgs/msg/Odometry型のトピック`/p3d/odom` に位置が出力される。

# 動作確認

rviz2を起動、ADDからOdometryを追加して、Topic `/p3d/odom`を選択。
Gazebo上のロボットの位置を動かして矢印の位置が同じ位置にあればOK。


![Screenshot from 2023-01-24 18-56-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/64020f65-e4bd-b0f8-ac42-265e0edfaae8.png)

または

```bash
ros2 topic echo /p3d/odom 
```

でposeの値を見る


# 参考


https://qiita.com/srs/items/a1e4efc472023a052819


https://answers.ros.org/question/400256/solved-how-to-use-libgazebo_ros_p3d/
paiza.ioでelixir その182

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

# 練習問題
zipを解凍せよ。

# 方針
unzip使う。

# サンプルコード

```
:inets.start
:ssl.start



defmodule W do
	def get(name, url) do
        {:ok, {_status, _headers, body}} = :httpc.request(url)
        body = IO.iodata_to_binary(body)
        File.write(name, body)
	end
end

W.get("sample.zip", 'https://resolvenet.org/modules/contrib/webform/tests/files/sample.zip')


{result, 0} = System.cmd("unzip", ["sample.zip"])
IO.puts result
{result, 0} = System.cmd("ls", [])
IO.puts result





```

# 実行結果

```
Archive:  sample.zip
  inflating: apple-touch-icon-114-precomposed.png  
   creating: __MACOSX/
  inflating: __MACOSX/._apple-touch-icon-114-precomposed.png  
  inflating: apple-touch-icon-57-precomposed.png  
  inflating: __MACOSX/._apple-touch-icon-57-precomposed.png  
  inflating: apple-touch-icon-72-precomposed.png  
  inflating: __MACOSX/._apple-touch-icon-72-precomposed.png  

apple-touch-icon-114-precomposed.png
apple-touch-icon-57-precomposed.png
apple-touch-icon-72-precomposed.png
exec_command
exec_stderr.txt
exec_stdin.txt
exec_stdout.txt
__MACOSX
Main.exs
main.tar.gz
runner_mysql
runner_php
run_user
sample.zip
```

# 成果物

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


以上。
aws cliによるS3操作

大抵はググればでてくる内容だが、シェル芸を足してもっと見やすくする。
S3でファイルを見る場面があったが、ファイル数が毎秒増えていく用途のバケットだったので、GUIで見ることが困難だった。そのためコマンドで対応するほかなかった。そういうときのナレッジ。

# S3バケットをlsする
```Shell
aws s3 ls s3://BUCKETNAME/DIRNAME/ --human-readable
```
BUCKETNAMEにはバケット名を、DIRNAMEにはディレクトリ名を置き換えて入力。--human-readableをつけることで、サイズ等を見やすくしてくれる。つけないとバイト表記。S3バケットの指定は、一番後ろにスラッシュをつけないといけないので、注意。
また、東京リージョンであってもタイムスタンプがUTCのため、時間が9時間マイナスされていても焦らないこと。

# S3バケットをlsして、最新ファイルだけ抽出する
```
aws s3 ls s3://BUCKETNAME/DIRNAME/ --human-readable | sort -nr | head -n 10
```
CloudShellはパイプと一般的なLinuxコマンドが使えるので、それを利用。sortで並び替えを行い、headで上から10行の結果を出力。head -n 10の数値は任意変更して、見やすくファイル名を出力する。

# S3バケットから指定したファイルをダウンロードする
```
aws s3 cp s3://BUCKETNAME/DIRNAME/ ./ --exclude "*" --include "FILENAME" --recursive
```
CloudShell上のカレントディレクトリに、指定したファイルをダウンロードする。このあと、単なるlsコマンドで、ダウンロードを確認。FILENAMEに実際のファイル名を記載する。

# S3バケットのgzファイルをcatする
```
aws s3 cp s3://BUCKETNAME/DIRNAME/FILENAME.gz - | zcat
```
たまにマネージドサービスなどのログをS3に保存すると、gzファイルのことがある。たとえばCloudFrontとかCloudFrontとか（大事なことなので2回書きました）。そのようなファイルをちょっと見たいときに利用する。

# S3バケットのgzファイルをgrepでキーワード検索する
```
aws s3 cp s3://BUCKETNAME/DIRNAME/FILENAME.gz - | zgrep "KEYWORD"
```
そのようなgzファイルをダウンロードせずに中身をgrep検索したいときは上記。"KEYWORD"を検索したいキーワードに置き換える。zgrepはヘルプ等を参照。基本grepとだいたい同じオプションが利用可能。

# S3バケットの最新gzファイル1つを機械的にgrepでキーワード検索する
いままでの応用技。何も考えたくないぐらい機械的にやりたいときはこれ。
```
[cloudshell-user@ip ~]$ BUCKETDIRNAME="s3://BUCKETNAME/DIRNAME/"
[cloudshell-user@ip ~]$ FILENAME=`aws s3 ls ${BUCKETDIRNAME} --human-readable | sort -nr | head -n 1 | awk '{ print $5 }'`
[cloudshell-user@ip ~]$ aws s3 cp ${BUCKETDIRNAME}${FILENAME} - | zgrep "KEYWORD"
```
変数にすることで、コマンドは同じものを単純繰り返しすることできる。変更するのは1行目のS3バケットとディレクトリ名、3行目のzgrep検索キーワードのみ。

## 参考リンク
[aws]s3 lsで取得したファイルを更新日時順でソートする
https://blog.hello-world.jp.net/posts/aws-4254
Azure Function(.NET インプロセス)で App Configuration から KeyVault を参照する

App Configuration で Key Vault 参照している設定値をAzure Functions (.NET インプロセス) から読み出す方法のメモ

## ポイント
- `Startup` クラスで `AddAzureAppConfiguration` する。
- Azure Functions は Managed ID を有効化し、Key Vaultへのアクセスできるようにしておく(RBAC or アクセスポリシー)

```c#:Startup.cs
using System;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Azure.Identity;

[assembly: FunctionsStartup(typeof(Company.Function.Startup))]

namespace Company.Function
{
    class Startup : FunctionsStartup
    {
        public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
        {
            string cs = Environment.GetEnvironmentVariable("AppConfigurationConnectionString");
            builder.ConfigurationBuilder.AddAzureAppConfiguration(options =>
            {
                options.Connect(cs)
                    .ConfigureKeyVault(kv =>
                    {
                        kv.SetCredential(new DefaultAzureCredential());
                    });
            });
        }

        public override void Configure(IFunctionsHostBuilder builder)
        {
        }
    }
}
```

# 参考

https://learn.microsoft.com/ja-jp/azure/azure-app-configuration/quickstart-azure-functions-csharp?tabs=in-process

https://learn.microsoft.com/ja-jp/azure/azure-app-configuration/use-key-vault-references-dotnet-core?tabs=core5x#add-a-key-vault-reference-to-app-configuration

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources

https://learn.microsoft.com/ja-jp/azure/app-service/app-service-key-vault-references?tabs=azure-cli
技術ブログはじめました（パナソニック アドバンストテクノロジー）

パナソニック アドバンストテクノロジー株式会社の@Takahashi_Saburoです。

この度、社内のメンバーと技術ブログを書き始めることにしました。
最初の投稿になりますので、今回なぜ技術ブログを始めることになったのか綴りたいと思います。

# どんな会社なのか

詳しくは[Organization の About](https://qiita.com/organizations/panasonic_ad)や[会社のHP](https://adtsd.jpn.panasonic.com/)を見てもらうと記載されていますが、すごくざっくり言うと、主に **組み込みシステム・ソフトの研究開発** をしている会社です。

特定の産業分野に特化するというよりは、常に技術的に先行している分野や技術にこだわって開発をしています。以前は家電などが中心でしたが、近年は自動車、IoT、産業、建設・農業、ロボティクスなどの分野に守備範囲を大きく広げていっています。

# なぜ社外に公開したくなったのか

私たちの会社は、間接部門を除くとほぼ全員が組み込みシステム・ソフトエンジニアという~~偏った~~素敵な会社です。

技術者の塊なので、他社に負けない技術力を強みとして維持するために切磋琢磨しています。
これまで社内では有志による勉強会やノウハウを蓄積するイベントなどが何度も生まれてきました。ただ、なかなか継続するのが難しく・・・

そんな中、社内から「オープンな情報から学んだことに関しては、どうせなら社内だけでなく社外にも公開しながら、モチベーションを上げて続けていきたい！」という意見が出ました。咄嗟に「それいいね！」と思ったのがきっかけです。

他にも以下のような肯定的な意見もあり、**「考え過ぎるより、まずやってみよう！」** ということで始めました。

- 単純にアウトプットしたものを見てもらえるとのが楽しい
- 組織として技術力はあるはずなのに、社外になかなか届いていないことが寂しい
- 世の中の技術と比べて、自分たちの技術がどのくらいイケているかわかる
- 良い記事を書けば、企業も個人も価値が高まるはず　などなど

# どんな技術ネタを投稿したいのか

下記のような技術ネタを投稿できたらと思っています。
まだ完全に絵に描いた餅ですが・・・

<dl>
  <dt>ロボティクス関連技術</dt>
  <dd>ROS、自律移動系、アルゴリズム・理論系　など</dd>
  <dt>シミュレーション技術</dt>
  <dd>デジタルヒューマン、モデルベース（MBD/MBSE）　など</dd>
  <dt>安心安全系</dt>
  <dd>機能安全、IoT セキュリティ　など</dd>
  <dt>その他</dt>
  <dd>開発技術やマネジメント手法など、面白そうなことがあれば何でも</dt>
</dl>

# さいごに

まだまだ手探り状態からのスタートなので、やさしく見守っていただければと思います。
肩肘張り過ぎず、まずは継続していきたいと考えています。

技術内容に少しでも興味があれば、ぜひお声がけください！
FactoryBotでtraitを利用する際は第二引数にtrait名を定義する必要がある

## 結論

### 正しい引数の順番
```ruby
create(:author, :trait名, name: 'テスト一郎')
```

### 誤った引数の順番
```ruby
create(:author, name: 'テスト一郎', :trait名)
```
こうすると以下のようなエラーが表示される
```
syntax error, unexpected ')', expecting =>
```
複数引数のラムダ記述方

# 初めに
今回は、複数の引数を持ったラムダ式の書き方を書いていこうと思います
### 本文
基本的には複数の引数を必要としたラムダ式を書くときはその引数をまとめて`data class`にしちゃうことが多いですが、そこまでの手間をかけるのも面倒だし何よりそのためだけに`data class`を作るのは適してない時に使っていただけるかと思います。
今回は今後多く使われるであろう`compose`で紹介していこうと思います
```kotlin
@Composable
fun Screen(
    onClick: (hoge: String, huga: Long) -> Unit = { _, _ -> },
) {}
```
呼び出す側は以下のようにすれば使えます
```kotlin
setContent {
        Screen(onClickIngredientTag = { hoge: String, huga: Long -> }
    }
```
### 最後に
今回は複数の引数を持ったラムダ式の書き方を紹介しました
地味に使う場面が多いのにあまり記事等に残ってたりしなかったので、自分の備忘録用に記事にしてみました。
皆さんのお役に立てれば幸いです
endpointリポジトリが引っ越しした？

## どうも コロンボです。

ansibleでエラーが出ましてね？

```
TASK [deployment : Install endpoint repo] **********************************************************************
**********************************************************************************************************
fatal: [aru-system]: FAILED! => {
 "changed": false,
 "msg": "Failure downloading https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.7-1.x86_64.rpm,
 Request failed: <urlopen error [Errno -2] Name or service not known>"
}
```

何に使ってるのかも不明なんだけれども。
（後で確認してみたら、 `Perl` や `Git` のパッケージが入ってました）

検索したけどそんなに情報がある感じがしなかった。

リポジトリのURLを変更しました。

```
https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.7-1.x86_64.rpm
　　　　　↓
https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm
```

https://packages.endpointdev.com/　に

```
Enterprise Linux 7 (RHEL & CentOS 7)

To add the End Point Yum repository to your Yum configuration:

# yum install https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm
```

って書いてあったからネ。

```
(Note that this service previously operated at packages.endpoint.com and
 moved to packages.endpointdev.com on 2021-11-30.)
```

とも書いてあったので、2021年11月30日に移転したようです。
[Embulk] .liquid,  embulk, in:type=mysql, out:type=file, delimiter=TSVについてのメモ

# この記事について

EmbulkでTSV出力する時にエラーに遭遇したので解決メモを残します。

# 実行環境

- Docker（openjdk:8-jre-alpine）
- embulk-input-mysql * configの `in:` 指定
- Cloud Build (GCP)
- cloud_sql_proxy

# Error

```console
org.embulk.exec.PartialExecutionException: org.embulk.config.ConfigException: java.lang.IllegalArgumentException: Can not deserialize instance of char out of VALUE_STRING token
```

# Code

## NG

```liquid:sample.yml.liquid
out:
  type: file
  file_ext: csv
  formatter:
    type: csv
    charset: UTF-8
    delimiter: '\t'
    quote: '"'
    escape: '\'
    null_string: 'NULL'
    skip_header_lines: 0
```

`delimiter: '\t'`の部分です。
`delimiter: {{'\t'}}`とか`delimiter: '\\t'`でもダメ。何故だ。


## OK


```liquid:sample.yml.liquid
out:
  type: file
  file_ext: csv
  formatter:
    type: csv
    charset: UTF-8
    delimiter: '	'
    quote: '"'
    escape: '\'
    null_string: 'NULL'
    skip_header_lines: 0
```

タブstringを直接入力すればいけました。珍しい。

# Btw

formatterに`type: tsv`というのはありません。以上です。

# 補足

### 2023/1/25
コメント頂いた方より、"で区切る（"\t"）ことで解消されるケースがあります。
実行環境について追記したのと、この辺りはもう少し追ってみたいと思います。
【備忘】apt updateでエラーが起きたときの対処（Ubuntu)

apt updateを実行したらエラーが発生。
結果的には無駄な作業もしましたが、今後使えることがありそうなので備忘として投稿しています。

##### （前提）
これからWinHQが出てきますが、かなり前にインストールし、削除していましたという経緯があります。
作業で設定ファイルを変更していますが、事前にバックアップを取得しています。
面倒なので記載していません。
```shell
#ubunutuバージョン
VERSION="20.04.5 LTS (Focal Fossa)"
```

### 最初に起きた事象
ErrorとWarningが表示された。
```shell
ubuntu-user@ubuntu-PC:~$ sudo apt update
#（省略）
エラー:4 https://dl.winehq.org/wine-builds/ubuntu jammy InRelease              
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 00A0A00AA000000A
#（省略）

W: GPG エラー: https://dl.winehq.org/wine-builds/ubuntu jammy InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 00A0A00AA000000A
E: リポジトリ https://dl.winehq.org/wine-builds/ubuntu jammy InRelease は署名されていません。
N: このようなリポジトリから更新を安全に行うことができないので、デフォルトでは更新が無効になっています。
N: リポジトリの作成とユーザ設定の詳細は、apt-secure(8) man ページを参照してください。
```

# 【結論】エラーに関わっている使用していないレポジトリを削除した
source.list.d配下のファイルを削除した。
```shell
ubuntu-user@ubuntu-PC: sudo ls -l /etc/apt/sources.list.d/
合計 28
#（省略）
-rw-r--r-- 1 root root 165  8月 15 00:32 winehq-jammy.sources

ubuntu-user@ubuntu-PC: sudo rm -i /etc/apt/sources.list.d/winehq-jammy.sources 
rm: 通常ファイル '/etc/apt/sources.list.d/winehq-jammy.sources' を削除しますか? y

ubuntu-user@ubuntu-PC: sudo apt update
#（省略）
完了

ubuntu-user@ubuntu-PC:~$ sudo apt upgrade
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
アップグレードパッケージを検出しています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
#（省略）
これを削除するには 'sudo apt autoremove' を利用してください。
#（省略）
アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 0 個。

ubuntu-user@ubuntu-PC:~$ sudo apt autoremove
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージは「削除」されます:
#（省略）
```

# 解決に至るまでに試したこと
上記の解決までたどり着くまでに試したこと。
公開鍵に問題があるとメッセージ表示されているため、新しい公開鍵を取得した。
しかし、期限切れの表示は一切なかった。
さらに言うと、エラー表示のPUBKEY自体がlistで表示されていない。
```shell
ubuntu-user@ubuntu-PC:~$ apt-key list
#（省略）
```
エラー解決のため一応新しく公開鍵を取得する。変更なし、との表示。
その後、apt updateをするも変化なし。
```shell
ubuntu-user@ubuntu-PC:~$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 00A0A00AA000000A
Executing: /tmp/apt-key-gpghome.gHtxrI4IMt/gpg.1.sh --keyserver keyserver.ubuntu.com --recv-keys 00A0A00AA000000A
gpg: 鍵00A0A00AA000000A:"WineHQ packages <wine-devel@winehq.org>"変更なし
gpg: 処理数の合計: 1
gpg:              変更なし: 1

ubuntu-user@ubuntu-PC:~$ sudo apt update
#（省略）
```
WineeHQは不要なのでリポジトリとして見ないようにする。
sources.listを編集して、apt update実行、表示に多少の変化はあるがエラーは同じ。
```shell
ubuntu-user@ubuntu-PC:~$ sudo ls -l /etc/apt/sources.list
ubuntu-user@ubuntu-PC:~$ sudo cat /etc/apt/sources.list | grep -v "#"
ubuntu-user@ubuntu-PC:~$ sudo vi /etc/apt/sources.list

# deb https://dl.winehq.org/wine-builds/ubuntu/ focal main をコメントアウトした
# すべての参照先をhttp://ftp.riken.go.jp/Linux/ubuntu/　へ変更した。

ubuntu-user@ubuntu-PC:~$ sudo apt update
#（省略）
```

この後に[【結論】](#【結論】エラーに関わっている使用していないレポジトリを削除した)の方法を実行し、解決に至りました。
firebaseでreactアプリをデプロイしたが反映されなかった話

# この記事で行うこと
firebaseにreactをデプロイした際に詰まった箇所を記載します。
デプロイ手順や環境構築に関する詳しい記事は、みなさんが書いて下さっているのでそちらを参考に!

# ことの発端

開発してfirebseにデプロイしてみたが、開発したソースコードがうまく反映されない。。。！！！
`Firebase Hosting Setup Complete`が出てしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264678/1ce2a2ef-304d-1965-6ba1-ae562def7d02.png)

記事を見ながら、`firebase init`の時にpublicじゃなくてbuildにしたりしたのになんでだろう..?

```bash
? What do you want to use as your public directory? (public) build
```

# 原因

`create-react-app`を一番最初にやった際に、階層を間違えていたため、今回アプリ開発を行った`react-todo-pwa`
配下のbuildフォルダではなく、`reactApp`配下のbuildファイルを指定していた。

```bash
reactApp
├── build ←←←← これは'firebase initi'時に生成される上記画像のhtml
│   ├── 404.html
│   └── index.html 
├── node_modules
└── react-todo-pwa
    ├── build ←←←← これは'npm run build'時に生成される圧縮したフォルダ
    │   ├── 404.html
    │   ├── index.html
    │   └── static
    │       ├── css
    │       ├── js
    │       └── media
    ├── node_modules
    ├── public
    └── src
        ├── components
        ├── provider
        └── service
```

また、原因に気付き`react-todo-pwa/build`を指定したのにも関わらず、その後の選択肢で`npm run build`で生成したindex.htmlファイルを間違えてオーバーライドで消してしまったためドツボにハマってしまった。

```bash
? File react-todo-pwa/build/index.html already exists. Overwrite? Yes
```

# 解決
フォルダ構成を直したりすれば良いが、一旦は参照先を`build`ではなく`react-todo-pwa/build`で回避した。

```firebase.json
{
  "hosting": {
    "public": "react-todo-pwa/build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
```

firebase initでオーバーライドするファイルは気をつけよう。

```bash
? File react-todo-pwa/build/index.html already exists. Overwrite? No
```

init後のdeployも忘れずに。

```bash
docker compose exec react-app firebase deploy
```
char GPTでコード生成テスト

「javascriptで入力項目が変更されたら背景を黄色にするには？」をDeeplで日本語から英語に翻訳。
それをchat GPT に渡すと、こんな回答をしてくれました。
3種類の例を示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374317/880e6276-e847-014e-b9b8-f44214043370.png)
2. Visual Best Practice I　解答アドバンス

※解説では解答を明記することがないように気をつけたいと思います、なので全問は載せません、ご了承ください、、
##### データは同じ土台に
美しいビュジュアライゼーションの目的は、ストーリーを見出すことではなく、人にシェアしてアクションしていくことである。その為にもデータは一元管理していくことが必要不可欠になる
##### スプレットシートで本当にデータドリブンは浸透できるのか？
そのファイルを集計や視覚化をしてみるためには一元管理していく必要がありますね
##### Tableau　server/Onlineを使わずにtebx.でレポートを共有してしまうと何が起きてしまうのか？
データの鮮度が落ちてしまい正しいデータを参照できますでしょうか？データの一元管理をし鮮度が落ちないようにしていくことが必要になります
#### Tableau Server/Onlineの機能・効果
###### 機能
データを自動的に更新する
データの流出を防ぐ（セキュリティ)
各コンテンツの利用状況、ユーザーの動向を把握する
データの使用可能者・範囲・用途・権限を設定する（ガバナンス）
Desktopで作成したVizの表示上の全ての機能（見栄えとインタラクション）をDesktopアプリケーションを持たないユーザーにも提供する
ユーザー個別のフィルター条件を記憶してダッシュボードをカスタマイズする（カスタムビュー）
定期的にメールでデータビジュアライゼーションを自分あるいは関係者に送付する（サブスクライブ）
データが一定以上の値を示したときにお知らせを飛ばす（アラート）
データを見た人がコメントしたり所定の相手にメンションする（コラボレーション）
Web上でVizを作成する（Web編集）
Webパーツとして外部Webサービスに埋め込むことができる
モバイル・タブレットなど多様なデバイスに対応する
データの所在や情報を明らかにしてより活用を促す（データカタログ）
ログインした人に応じてそれぞれが見るべきVizを推奨する
###### 効果
それぞれが必要なタイミングでデータを使うことができる
必要な人のみにデータの閲覧を可能にする
適切なタイミングに更新され、管理された安全なデータを使用することができる
誰がデータの管理者なのかを容易に確認できる
データのメタデータを、データベースに接続せずに確認できる
データの集計結果やVizの表示結果など、複数人が同じものを見ている場合、リソースを共有することができる
誰かに聞かなくとも、どこからやってきて、どのように加工されたデータを使っているのかがわかる
誰かに聞かなくとも、どこからやってきて、どのように加工されたデータを使っているのかがわかる
#### レポートファクトリーとは？
①分析結果を求めている「Task」を持っている人が自分でデータを探索することができず、他人に分析やレポーティングを依頼して作ってもらっている状態
②レポート作成依頼を受けるメンバーが過剰な依頼数に忙殺され、すぐに分析結果を依頼主に返すことができない状態
③依頼からレポート完成までに時間がかかり過ぎて、もはやレポートが完成する頃にはその分析結果が不要になっている状態
React：簡易APIクライアント

作成：2023年1月24日、　更新：2023年3月9日
体重など健康データを保存するアプリとバックエンドを作ってみたく、バックエンドをGo、フロントエンドをReactで作成予定です。
前回の記事で[Goで簡易APIサーバー](https://qiita.com/RYO_/items/14f3ffd5b44ef95da9ac)を作りましたので、今回はReactで簡易APIクライアントを作成します。

# React簡易クライアント
Reactのプロジェクトを作成します。
```
% npx create-react-app api-react
```
フォルダapi-reactの中で実行します。
```
% yarn start
```
実行できました。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/8e58254e-8ded-4ce6-e2f8-f13b3cc67557.png">

axiosをインストールします。
```
% yarn add axios
```
[React でクライアント](https://github.com/ryoyuki6/go-api202301/blob/qiita20230124/react/src/App.js)を書いて、Goサーバーに GET したところ、エラーが出ました。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/5502790f-94b3-e787-85cc-6221a7518d1f.png">
このエラー blocked by CORS policy については次の記事が参考になりました。
[blocked by CORS policyはもう怖くない！！](https://zenn.dev/tattu/articles/c72d7cbd196970)
[GoでCORSの設定](https://qiita.com/popo62520908/items/24956284e40871497082)
Goサーバーの [main.go](https://github.com/ryoyuki6/go-api202301/blob/qiita20230124/go/main.go) に次のヘッダーをつけたら、
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/02ac0f73-9448-41ed-9678-bf72e4a6c0fd.png">
ちゃんと GET できる様になりました。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/3fd3bfdc-42c3-a4c7-0651-7ec48d9c4db2.png">

Go簡易サーバーからReact簡易クライアントで GET できる様になりました。
次は、GET したデータをReactに表示させていきたいと思います。

ここまでのソースコード
[Go簡易サーバー](https://github.com/ryoyuki6/go-api202301/tree/qiita20230124/go)
[React簡易クライアント](https://github.com/ryoyuki6/go-api202301/tree/qiita20230124/react)

# Get したデータを表示
get したデータを表示させるコードを追加しました。useStateを追加しました。
```
function App() {
  const [getData, setGetData] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await axios.get("http://localhost:8080/health_data");
      setGetData(response.data);
    };
    fetchData();
  }, []);
  console.log("Get data : ", getData);

  return (
    <>
      <ul>
        {getData.map((data) => (
          <li key={data.user_id}>
            user_id : {data.user_id}, weight : {data.weight}, date : {data.date}
          </li>
        ))}
      </ul>
    </>
  )
}
```
<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/efd24b35-509c-32e4-0dfc-47b8eefcdf3e.png">

[Github のソースコード置き場:qiita20230309](https://github.com/ryoyuki6/go-api202301/tree/qiita20230309)




# 参考
・[Github axios](https://github.com/axios/axios)
・[DockerComposeでGoのGinとMySqlの環境を作ってみた-第1弾](https://www.w2solution.co.jp/corporate/tech/dockercompose%E3%81%A7go%E3%81%AEgin%E3%81%A8mysql%E3%81%AE%E7%92%B0%E5%A2%83%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F-%E7%AC%AC1%E5%BC%BE/)
iOS/AndroidでONLYOFFICEドキュメントとNextcloudを連携する

## ONLYOFFICEとNextcloudの連携について

ONLYOFFICEでは、ONLYOFFICE DocsとNextcloudを連携させ、クラウドストレージ内でオフィス文書を編集するための公式コネクタを提供しています。ONLYOFFICEコネクタは、Nextcloudの[アプリストア](https://apps.nextcloud.com/apps/onlyoffice)またはONLYOFFICE [GitHubページ](https://github.com/ONLYOFFICE/onlyoffice-nextcloud)よりダウンロードできます。

:::note warn
ONLYOFFICEとNextcloudの連携コネクタの詳細や仕組みについては、[APIドキュメント](https://api.onlyoffice.com/editors/nextcloud)のページをご覧ください。
:::


### 主な機能

* テキスト文書、スプレッドシート、プレゼンテーションの作成、編集、閲覧
* オンラインフォームの作成と記入
* 他のユーザーとのファイル共有
* トークチャットでのドラッグ＆ドロップによるファイル共有
* 電子透かしによる文書の保護
* リアルタイムでのドキュメントの共同編集：高速と厳格の2つの共同編集モード、変更履歴、コメント、内蔵チャット
* 1つのドキュメントサーバーに接続された複数のNextcloudインスタンス間で共同編集が可能
* **JWTのサポート**により、適切な権限を持つユーザー以外がドキュメントにアクセスできないように、トラフィックを保護する

### 対応フォーマット
* 編集・閲覧用：docx, xlsx, pptx, csv, txt, docxf
* 閲覧のみ：PDF
* フォームへの入力用：OFORM
* OOXML変換による編集用：ODT、ODS、ODP、RTF
* 「ONLYOFFICEで変換する」オプションでOffice Open XML形式に変換する場合：doc, docm, dot, dotx, epub, htm, html, odp, odt, pot, potm, potx, pps, ppsm, ppsx, ppt, pptm, rtf, xls, xlsm, xlt, xltm, xltx

### バージョン7.5.4での新機能
* 変更点
  * 新しいブラウザタブでエディタを開くように修正しました。
  * MacOSでファイルをダウンロードする際の不具合を修正
  
完全な変更履歴は[こちら](https://github.com/ONLYOFFICE/onlyoffice-nextcloud/blob/master/CHANGELOG.md)でご覧いただけます。

:::note warn
ONLYOFFICE DocsをNextcloudに連携する方法を[こちらの記事](https://qiita.com/ONLYOFFICE/items/26130aeb113fa17bd963)でご紹介しています。
:::


## iOS/AndroidでONLYOFFICEドキュメントとNextcloudを連携する

NextcloudとONLYOFFICE Documentsモバイルアプリを連携させ、Nextcloudのドキュメント、スプレッドシート、プレゼンテーションを外出先で共同編集して作業することが可能です。

:::note warn
すでにNextcloudサーバー、ONLYOFFICE Docs、連携アプリがインストールされ、設定されていることが前提になります。
:::


モバイル端末でONLYOFFICEをNextcloudに接続するには、[iOS用ONLYOFFICEドキュメントアプリ](https://www.onlyoffice.com/ja/office-for-ios.aspx)または[Android用ONLYOFFICEドキュメントアプリ](https://www.onlyoffice.com/ja/office-for-android.aspx)の最新版をダウンロード・インストールし、以下の操作を行います。

1. **クラウド**セクションに移動します。
1. **Nextcloud**を選択します。
1. 「**接続URL**」フィールドに、NextcloudサーバーのURLアドレスを挿入します。
1. Nextcloud アカウントのログイン名とパスワードを入力します。
1. 「**次へ**」を押します。

モバイル端末のONLYOFFICE DocsでNextcloudのドキュメントを編集するには、ファイルリストで必要なファイル名をタップします。

[ONLYOFFICEを今すぐダウンロード](https://www.onlyoffice.com/ja/download-docs.aspx?from=qiita)
文字列を1文字ずつに分解したテーブルを生成する関数

組込関数 [STRING_SPLIT](https://learn.microsoft.com/ja-jp/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver16 "STRING_SPLIT (Transact-SQL)") の区切り文字なしバージョンが欲しかったので作ってみた。

※要互換性レベル130以上

```sql:T-SQL
CREATE FUNCTION String_Explode (	
	@input nvarchar(max)
)
RETURNS TABLE
AS
RETURN (
	SELECT
		CAST(SUBSTRING(input, ordinal, 1) AS nchar(1)) value
		,ordinal
	FROM (
		SELECT
			ROW_NUMBER() OVER(ORDER BY value) ordinal
			,@input input
		FROM
			STRING_SPLIT(REPLICATE(',', LEN(@input) - 1), ',')
	) t
)
```

```sql
SELECT * FROM dbo.String_Explode('Qiita郁代')
```

|value|ordinal|
|:-:|:-:|
|Q|1|
|i|2|
|i|3|
|t|4|
|a|5|
|郁|6|
|代|7|
「プログラミング」ノススメ

## 1. はじめに

こんにちは！株式会社ジールの@tomonori_ishikawaです。
データ分析、データ活用で基礎になる技術と言えば、
「プログラミング」と思っております。
ここでは「プログラミング」が出来るようになることのメリット、勉強の仕方をご紹介したいと思います。

### 筆者について
職種：データ分析エンジニア
AIを用いたデータ分析をPythonを用いてデータ加工、
Tableauを用いて可視化を行っています。
要件定義から行っています。

![スクリーンショット 2023-01-24 1018121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118504/5e0f0c3e-470e-bc17-339f-3c92f0c6d3aa.png)



##  2. 「プログラミング」とは?
「プログラム」を作ることを「プログラミング」と言います。
「プログラム」は、コンピュータにやらせる命令を順番に並べたものです。

私達の暮らしの中で使われている
コンピュータは人が命令して初めて動いてくれます。

例えば、銀行のATM。
お金を引き出すボタンを押して、暗証番号を入力し、
引き出したい金額を入力します。

これらの一つ一つの動作は、ATMシステムの中で
プログラムがお金を管理している機械に命令しています。
![スクリーンショット 2023-01-24 1340432.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118504/3f6e3084-1bb1-0f4b-a5aa-65e83e95bd56.png)


##  3. 「プログラミング」が出来るようになると

「プログラミング」が出来るようになるとデータ分析を行う上で楽しいことが増えます。
ここでは3つ挙げたいと思います。

![スクリーンショット 2023-01-24 134543.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118504/1c432cde-bab6-a2cd-4699-adfd6b8e76b7.png)



### 1. 便利だと思うものを作成することが出来る
SNSなど普段私達が使っている便利なwebアプリケーション
はプログラムで作成されています。
普段の生活でこういうのがあればもっと生活が便利になるのに
と思うことや、
こういうのがあれば作業がもっと短くなるのに
と思ったことはないでしょうか？
そういったものをプログラムで作成してたくさんの
人々に使われるようになると、ビジネスチャンスにもなります。

例えば、皆さんがよく使っている
Youtube、Instagram、Pinterest、DropboxはPythonのプログラムで出来ています。

![スクリーンショット 2023-01-24 1359451.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118504/8685c9e2-1e3d-5822-de9e-fe9ec08520c7.png)


### 2. データ加工が自由に出来るようになる。
DXのお仕事やデータをTableau可視化場合を考えます。
ツールを使用することが多いのですが、
会社さんが持っているデータだとツールが読み込むことが出来ないことが多く、
そのまま使用することが難しいです。
このため、エクセルなどのデータをcsvファイルに加工する必要があります。

![スクリーンショット 2023-01-24 1410411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118504/1648c868-ca46-ae3c-678d-84042a17a518.png)

この時、プログラミングを行いデータを加工します。

### 3. 複雑なデータ構造の設計
最近よく耳にするAIを使った予測システムを考えてみます。
最近ではAIの発展によりDX化が進むことによって、
シンギュラリティ=「人工知能が人間の知能と融合する時点」が
起こる。その時点は2045年と言われてたりします。

![スクリーンショット 2023-01-24 1421411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118504/563618ed-192b-20fb-0c05-e5829aafc626.png)

AIによるシステムを設計するには、コンピュータが理解しやすいよう
モデリングを行い、モデルに合わせてデータを加工する必要があります。

最適化、機械学習、ディープラーニングがこれに当たります。

次回では、プログラミングの勉強の仕方を、
Pythonを例にして書きたいと思います。
Tailwind CSSの使い所をどこなのかを考える



## おさらい：Tailwind CSS

Tailwind CSSはUtility firstをコンセプトのCSSフレームワークです。CSS設計におけるUtilityクラスを各プロパティ毎に用意をし、htmlにマルチクラスでコンポーネントを作成していきます。


こんなボタンを作りたいときは以下のように当て込む

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1467845/b9605a2b-4f36-509a-d8e2-77c84162a68d.png)


```html
<button class="bg-blue-400 text-white border-0 px-7 py-3 rounded-lg">ボタン</button>
```

Bootstrapと違い、すでに用意されたコンポーネントから拡張するのではなく、自身が作成したいコンポーネントに対してクラスを当てるため非常にカスタマイズ性と自由度が高いです。
また、ユーティリティクラスで構成されるため、コンポーネントに対して命名の負担を減らせるメリットもあります。
そのためCSS設計やコンポーネントの設計において非常に力強い味方になってくれるフレームワークです。

## どのタイミングでTailwind CSSを採用すればよいか

ではどのタイミングで使っていけば、Tailwind CSSの能力をフルに発揮できていくのかを考えていきます。

### CSS設計が無秩序でありながら、デザイン性を持たせたい場合

例としてあがるのが、プロトタイプ作成などです。人に見せる前提だとしてもプロトタイプは操作性の確認・評価が目的になるため、CSS設計とは無縁です。プロトタイプ作成においてはTailwind CSSを入れておけば最低限のデザイン再現のため余計な思考を巡らせる必要はありませんし、HTML側だけを考えるだけでよいです。その他にもデザインにこだわりがないものなどにも、採用してもよいかもしれません。

また、VueやReactにおけるコンポーネント設計において、CSS in JSに変わるCSSフレームワークとして採用するのもよさそうです。Tailwindの特徴における、HTMLとCSSの関心の分離がJSファイルのみで行われ、コンポーネント名だけを考えればよいので、設計の負担が非常に軽くなりえます。

### 非常に堅牢なCSS設計を考えなければならない場合

上記とは逆で、拡張性と堅牢性をもたせつつも独自のコンポーネントを作成したい場合などもTailwind CSSは向いていると考えられます。
例としてはデザインシステムなどがあたります。Tailwind CSSという共通言語があるので開発メンバー内で意思統一が図りやすく、複雑怪奇な命名規則を考える負担も少なくなります。また、ボタンの色や幅などを拡張するにしても、HTML側だけを見ればよいのでCSSを考えなくてよいものとなります。



## だが、静的HTMLの開発現場に使うのはよくない

非常に柔軟で自由と規律があるTailwind CSSですが、静的HTMLで開発が進む場合、採用は控えたほうがよいと思っております。ネックとなるのはやはり、マルチクラスゆえのHTMLへの記述量多さ。関心の分離が進みますが、記述量を多くし負担を増やしてでもやるべきことなのかは疑問が残ります。
上記のボタンを作るだけでも、HTMLを読み解くだけで負担になりますし、出来上がったHTMLは非常に冗長で難解なものになります。

そうならないために、@applyでまとめて設計をしていけばよいという声も聞こえそうですが、それでは通常のCSS設計とほぼ同じになってしまいます。


```css
@tailwind base;
@tailwind components;
@tailwind utilities;

.btn {
  @apply bg-blue-400 text-white border-0 px-7 py-3 rounded-lg;
}
```

```html
<button class="btn">ボタン</button>
```

CSSファイル自体、スッキリすると思いますが難解性がHTML側からCSS側に移っただけですので、根本的な解決にはなっていません。また、細かなデザイン指定やピクセルパーフェクトが絶対の実装には不向きです。
優位点はユーティリティクラスが存在しているから拡張が楽になるぐらいでしょうか？
しかし、こんな事を考えるならば、普通にCSS設計をしていたほうがマシです。


## 終わりに

Tailwind CSSはユーティリティクラスが故に、関心と分離が進む非常によいフレームワークですが、採用に至っては慎重にならなければならいケースがほとんどです。
CSS設計とは程遠いコンポーネント設計やSPAなどには非常に最適ですが、コーポレートや独自性を持ったCSS設計の場合、Bootstrapのように元あるものから拡張していくケースのほうが、結果としてスムーズに進む可能性があります。
開発現場で何を目的とし何を完成形とするをじっくり見定め、フレームワークの技術採用を考えていきましょう。
[専用SQLプール]データベースレベルでDDLを取得する

Azure Synapase Analytics専用SQLプールでデータベースレベルでDDLをSSMSを使って取得します。
`CREATE DATABASE`だけではなく、テーブルや、ビュー、ユーザーなどオブジェクト全般のDDLを取得します。

# SSMSを起動して対象のサーバへ接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/6b131c65-56f4-17f3-9efc-63f9773c8fe7.png)
必要な接続情報を入力し、SSMSから接続します。

# DDLの抽出の対象となるデータベースを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/7490c7b0-8d41-4041-ab2e-f75c8ab63edf.png)
対象のDBを選択し、右クリックで「スクリプトの生成」を選択します。



# スクリプト生成画面
## 説明
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/b61e199f-164f-869a-9c3d-94f766b9d6a3.png)
「次へ」を押します。

## オブジェクトの選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/0eb9abf8-6658-a5bf-e55a-bdccdb176524.png)
今回はすべて取得したいので「データベース全体とすべてのデータベースオブジェクトのスクリプトを作成」を選択します。
※オブジェクトを指定したい場合は「特定のデータベースオブジェクトを選択」を押し、対象を選択します。

## スクリプト作成オプションの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/5d870be6-2de8-dc8d-3fa8-142abe1e085f.png)
スクリプトの出力方法を指定します。今回はファイルに出力したかったので、「スクリプト ファイルとして保存」を選択しました。

# 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/5f6a28f3-1314-9f67-6dbf-79e351d3b829.png)
概要が表示されます。問題なければ「次へ」を押します。

# スクリプトの保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/cc874b78-ada5-2624-cc02-cfd8c8e25003.png)
スクリプトの作成状況が表示されます。全部完了すれば、「完了」が押せるようになるので、押せば完了です。
[UiPath] Freeプラン(トライアル)で出来ることまとめ

# はじめに
以下の記事を先日投稿しましたが、その中でもAutomation Cloudにて新たに登場した**Freeプラン**で、どんな事ができるのかわかりやすくまとめてみたいと思います。プラン全体の概要に関しては下記に記載しているのでご参照ください。

https://qiita.com/MUCHIUCHI_OJISAN/items/c37f16eaeb08dfbc7a7d

# Freeプランとは？
Freeプランは、無料で使える商用利用可能なプランになります。なので「無料」でUiPathを商用目的に使いたい！という場合はここがエントリポイントになります。以下で詳細を書いている使える製品に限りがあるので、もしそれ以上にたくさんの製品を試してみたい！という場合は、ここから60日間限定のProトライアルに申し込むことが可能です。**このFreeプランは個人の業務を自動化するための最低限の機能が使えるといったようなプランです。**

### ライセンス
Freeプランには、**Automation Expressライセンスが25個**付与されています。逆にAttendedユーザーライセンスやAutomation Developerライセンス等は付与されていません。

:::note info
**Automation Expressライセンスとは？**
UiPathのユーザーライセンスには、開発系のライセンスと実行系のライセンスがありますが、これは開発系のライセンスにカテゴライズされ、かつ無償で各プランに付与されています。
:::

:::note warn
Communityプランについて
Communityプランも同じく無償で使えるプランですが、こちらは**商用目的の利用が不可になります。** もし業務の自動化プロセスを開発するために、Sutdioやその他の製品を利用したい場合は、Pro Trialプランを利用する事を推奨します。
:::

### 使える製品
使える製品は、以下の5つになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133151/31644260-8c2d-ae1d-2d14-45ca10ec5a0f.png)
自動化プロセスを開発するツールは2つ、Studio XとStudio Webです。UiPathといえば、Studioをイメージする読者の方も多いかもしれませんが、このFreeプランでは**Studioを利用した開発はできません。** ただしStudio XやStudio Webでも出来ることは多く、具体的な違いが気になる方は以下の記事を参考ください。

https://qiita.com/miya_gis/items/b55fb830b233d25a89e7

:::note info
**Stuido Webとは？**
昨年プレビューリリースをした開発ツールで、Automatation Cloud上で提供されています。今までのStudioファミリーツールとは異なり、ブラウザ上で自動化プロセスを開発することができます。
:::

:::note warn
Automation Expressのライセンス制約
Freeプランに含まれるAutomation Expressライセンスでは、Studio Web/X経由で開発したプロセスをパブリッシュする先は、My Workspace(Orchestrator上で自身のみがアクセスできるフォルダー環境)に限定されます。
:::

# おわりに
上記にて簡単にFreeプランで使える製品などを説明しました。このプランは、主に初めて自動化プロセスを開発する人向けのトライアルとしてぴったりなプランだと考えています。Webサイトから情報を抽出したり、エクセルやシステムへの入力作業を自動化したり、個人でやっている業務の自動化をかんたんに始めることができます。まだUiPathを使ったことが無い、どんな製品なのか試してみたい。そんな方は以下より無料で始めることができます。

https://cloud.uipath.com/portal_/register?subscriptionPlan=automationkit
Deepstream-appにAtomCam2を連携

# 初めに
前回、DeepStreamSDKの環境を作りましたがこれにAtomCam2のRTSPストリームを流してみたいと思います。
AtomCam2だけRTSP機能が追加されています。（AtomCamSwingにはついていないようです。）

https://qiita.com/kazzzu/items/a0640dfa4be78bddc6f5

# 参考

https://astrotourism.jp/2022/05/30/1135/

# 手順

## AtomCam2の設定確認
AtomCamのアプリで対象のAtomCam2デバイスを選択

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245578/01f5674d-5af4-9cec-8777-229b16e336a0.png)

カメラ表示されます。
右上の歯車マーク（設定）を選択します。

![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245578/b10234ca-220f-0b34-56a0-78ce0a2c34b3.png)

設定→その他を選択

![33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245578/e2314d82-401f-fce4-da49-9afa99266fba.png)

PCで再生を選択
（AtomCam2以外はこのメニューはありません。）

![44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245578/88d9d9f4-1328-21ec-9f5a-71c8b6799336.png)

一番下のアドレス欄をコピーします。

![55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245578/3334ecd5-cd11-63ea-aaf7-62a97d648f47.png)

## deepstream-appを起動します。

```bash
$ xhost +
$ docker run --gpus all -it --rm -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY -w /opt/nvidia/deepstream/deepstream-6.1 nvcr.io/nvidia/deepstream:6.1.1-devel
```
## Configを書き換えてRTSP入力を表示するようにします。
dockerの中に入っているConfigを書き換えます。
サンプルで入っているConfigを書き換えます。（なお、dockerを停止すると変更内容がきえますので注意）

```bash
# vi samples/configs/deepstream-app/source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt
```
```bash
[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP
#type=3 ##<<== koko
type=4
#uri=file://../../streams/sample_1080p_h264.mp4  ##<<== koko
uri=rtsp://XXXX:XXXX@192.168.10.1/live
・・・

[tiled-display]
#enable=1 ##タイル表示をOFFにします。
enable=0
```
変更して保存します。

deepstream-appを起動します。
```bash
# deepstream-app -c samples/configs/deepstream-app/source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt 
```

AtomCam2から流れるRTSPストリームが表示されました。
![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245578/ba5e8156-a85e-4522-352f-5311bc7ccf22.png)
Djangoの本番環境（DEBUG = False）にて、mediaに保存した画像が表示されない問題を解消

<h1>はじめに</h1>

ローカル環境（DEBUG = True）では、mediaに保存されている画像が表示出来るのに、本番環境では表示することが出来ないという問題に直面した。

結論から言うと、サードパーティー製のクラウドストレージ（例：AWSなど）の１つである
[cloudinary.com](https://cloudinary.com/)を利用することで解決したので、自分の行った手順を紹介したいと思う。
※djangoだけで、mediaに保存された画像を表示することは可能かもしれないが、調べきることが出来なかった。

また、
[MEDIA files in production — Django
](https://mrvaibh.medium.com/handle-media-files-in-production-django-cf984aea5490)このサイトの内容を参考にしたので、英文に慣れている方はこちらの内容を参考にされると良いと思う。

注意：今回書いている記事は、ローカル環境では、mediaに保存された画像を表示出来ていることを前提としています。

<h1>Cloudinaryで行う手順</h1>

まず、[cloudinary.com](https://cloudinary.com/)への登録、ログインを行う。そしたら、Welcome to Cloudinary!と書かれているページになると思う。

そのページにある、Configure your SDKと書かれている部分をクリックし、自分の

**cloud_name** 
**api_key**
**api_secret**

を確認する。これらは、この後にDjango内での設定に必要となる。

<h1>Djangoで行う手順</h1>

初めにターミナルにて、
`pip install django-cloudinary-storage`
を行う。

そして、Djangoの**settings.py**に

```python:settings.py
INSTALLED_APPS = [
		...
    'cloudinary_storage',
    'cloudinary',
]
```

を追記する。

続いて、**settings.py**の好きな場所に

```python:settings.py
CLOUDINARY_STORAGE = {
    'CLOUD_NAME': '<your_cloud_name>',
    'API_KEY': '<your_api_key>',
    'API_SECRET': '<your_api_secret>',
}
```

を追加する。このCLOUD_NAME、API_KEY、API_SECRETには先程[Cloudinary.com](https://cloudinary.com/)で確認を行なった自分のものを書く。

最後に、
```python:settings.py
DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.RawMediaCloudinaryStorage'
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
```
をsettings.pyの最後に追加することでおしまい。

管理画面などから、画像を追加するとCloudinaryのデータベースに送られる。
そして、画像はそこから取得されるようになり、本番環境（DEBUG = False）でもローカル環境のように画像を表示することが可能になったと思う。

<h1>おわりに</h1>
本番環境を想定した画像の表示を行う方法が書かれていたサイトが少なかったので、自身の解決法を共有することで、少しでも役に立てると嬉しいと考えています。
リアルタイム通信という技術

# リアルタイム通信とは
リアルタイム＝１００ミリ秒以下でデータを伝送すること

# Webソケットとは
ブラウザとウェブサーバーとの間で双方向通信を行うための通信規格

# 手軽にリアルタイム通信を実装できるPubnubを使ってみた
[こちらの記事](https://qiita.com/n0bisuke/items/36e4b334d17174446df7)を参考にした

## subscribeとは？
```tsx
pubnub.subscribe({
    channels: ["board_game"],
    withPresence: true,
});
```
メッセージを受信する側

## publishとは？
```tsx
pubnub.publish(
    {
        channel: "board_game",
        message: { sender: uuid, content: "" },
    },
    function (status: any, response: any) {
        //Handle error here
    }
);
```
メッセージを送信する側

## 触ってみた感想
ゲームのリアルタイム通信に利用できるわけじゃなさそう。あくまで、チャットに使われる技術。

## Next.jsで作るゲームで使えそうなリアルタイム通信技術を探したい
「nextjs websocket」で検索してみるか。。
npm ERR! の対処法

# npm ERR! の対処法
本記事では、npm install -g yarn実行時に発生したnpm ERR!の対処法についての備忘録を残す。
![スクリーンショット 2023-01-14 12.47.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951997/183a5680-3221-f250-4b3c-70b30fbba958.png)

# 試したこと
1.permission deniedと出力されたので、cdコマンドでnode_modulesディレクトリに移動

2.sudo chown -R info /usr/local/lib/node_modules/実行によって権限を与える


|コマンド  |意味|
|---|---|
|chown  |ファイルの所有者やグループを変更するコマンド|
|-Rオプション  |カレントディレクトリ配下のファイルやディレクトリの所有者を変更|
|info  |自身のユーザ名|
|/usr/local/lib/node_modules/|権限を付与させたいファイルへのパス|


## 無事インストール完了
これでインストールすることに成功した。
![スクリーンショット 2023-01-14 13.07.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951997/aeb1a885-b7b2-8d28-1ff9-4817ca3b3de0.png)

## 参考文献

https://eng-entrance.com/linux-command-chown#-R--recursive
Python sys.stdin.readlines() 読み込み方法


sys.stdin.leadline()の場合
```
import sys
  s = sys.stdin.readline()
  print(s)
```
実行
```sh
$ python3 main.py 
qqqqq　
ここでEnter押せばそのまま出力される
qqqqq
```

sys.stdin.leadlines()の場合
```
import sys
  s = sys.stdin.readlines()
  print(s)
```
実行
```sh
$ python3 main.py 
qqqqq
ここで止まるので入力終了させたい
```

んで、適当にググって最初の方にヒットした記事に従い Ctrl+Z すると

```sh
^Z
[12]+  Stopped                 python3 main.py
```
Ctrl+ C すると

```sh
^CTraceback (most recent call last):
  File "/Users/Desktop/main.py", line 3, in <module>
    s = sys.stdin.readlines()
KeyboardInterrupt
```
入力できやん・・・となってさらに15分ほどググるとありました
https://ytyaru.hatenablog.com/entry/2020/01/10/111111

正解：Ctrl + D
```sh
$ python3 exam_test.py 
qqqqq    
['qqqqq\n']
```
以上