OmniAICreator/Qiita-1.07M huggingface dataset:
GitLab14→13ダウングレード方法

# はじめに
社内で利用しているCentOS7にyumでインストールしたGitLabのアップグレード作業を実施した。(13.12.12⇒14.1.8⇒14.5.2)
14.1.8⇒14.5.2にアップグレードした正しい手順を踏んでいないため、500エラーでGitLabが正常に起動しなくなった。
どうやら[こちら](https://docs.gitlab.com/ee/user/admin_area/monitoring/background_migrations.html#database-migrations-failing-because-of-batched-background-migration-not-finished)の事象に陥ったよう。
復旧させるために一度ダウングレードしないといけないので、13.12.12に戻す手順についてこちらに記載する。

# 実行環境

| 項目             | 値        | 
| ---------------- | --------- | 
| OS               | CentOS7   | 
| インストール方式 | Omnibus   | 
| GitLab種別       | GitLab CE | 
| バージョン       | 13.8.0    | 

# 前提
- 作業前に以下それぞれのバックアップファイルを取得していること
  - baseデータ
  - 設定ファイル
- バックアップファイルは別サーバ等に保管されていること

# GitLabをアンインストールする 
まず、インストール済のGitlabをアンインストールする

```
コマンド確認
# gitlab-ctl -h

アンインストール
# gitlab-ctl uninstall

データも削除
# gitlab-ctl cleanse

既に全部バックアップ済みなので生成されたファイルを削除
# rm -rf gitlab-cleanse-*
# rm -rf /opt/gitlab/

yumからも削除
# yum remove gitlab-ce -y
```

# GitLabを再インストール

```
yumでインストール
# yum install gitlab-ce-13.12.12-ce.0.el7.x86_64

gitlabのインストールを確認
# gitlab-rake gitlab:env:info
```

# 構成ファイルをリストア
設定関連のバックアップファイルをカレントディレクトリに配置し、以下コマンド実行

```
既存のディレクトリ名を修正(バックアップをとっておく)
# mv /etc/gitlab /etc/gitlab.yyyymmdd

構成ファイルを解凍し、gitlabディレクトリが存在することを確認
# tar zxvf ~/xxxxxxxx_yyyy_mm_dd_13.12.12_conf.tar

構成ファイルを/etc/gitlabに配置
# mv ~./gitlab /etc/gitlab/

設定を反映
# gitlab-ctl reconfigure 
# gitlab-ctl restart
```

# GitLabのベースバックアップをリストア
```
バックアップファイルを以下に配置
# cp ~./xxxxxxxx_yyyy_mm_dd_13.12.12.tar /var/opt/gitlab/backups

設置したバックアップファイルのオーナーを変更
# chown git.git /var/opt/gitlab/backups/xxxxxxxx_yyyy_mm_dd_13.12.12.tar

オーナーの確認
# ls -la /var/opt/gitlab/backups/

不要なプロセスを停止
# gitlab-ctl stop puma
# gitlab-ctl stop sidekiq

プロセス停止の確認
# gitlab-ctl status

リストア
# gitlab-backup restore BACKUP=xxxxxxxx_yyyy_mm_dd_13.12.12

設定を反映
# gitlab-ctl reconfigure 
# gitlab-ctl restart

```

# 参考
- [GitLabを別サーバーに移行](https://blog.dksg.jp/2016/04/gitlab.html)
- [Back up and restore GitLab(公式)](https://docs.gitlab.com/ee/raketasks/backup_restore.html#restore-gitlab)
SQLでnullにハマった話

こんにちは。
エンジニアもどきにもなれない謎の初号機X（エックス）です。

こちらの記事は金属加工プラットフォームを開発・運用するCatallaxyのCatallaxy Advent Calendar 2021の第17日目の記事となります。

私より前の方々たちは随分と楽しい記事（おもしろいかはともかく）を書かれていたようでハードルが高くなってしまいましたが、この辺りで下げ気味にしてあげましょう。
何について書くか？そんな悩んでいませんが、人生初のSQLを書いた際にnullにハマった話でもしましょう。

# SQLでnullにハマった話

「～を含まない」文字列検索をしようと、下記のようなSQLを書きました。
ここでは仮に、「あいう」とします。

```sql
select hogehoge
from fuga
where foo not like '%あいう%'
```

しかし、期待していた通りの結果は得られませんでした。
上記の例では条件がnot likeのみとなっていますが、当時、他にもwhere句に条件を指定していたので、どこが原因なのかがわかりませんでした。
where句に書いてある条件をひとつずつコメントアウトしていき、調査したところ、どうやらnot likeが悪さをしている様子。
ヒットしてほしいのにヒットしてくれないレコードを抜き出して見てみると、何もデータが入力されていないものがヒットしていないようです。
何もデータが入っていない...つまりnullです。

わたしはこの時気づきました。
**『あれだけ「nullは要注意」と本で読んだじゃないか....！！！！！！！！！！！！！！』**

> NULLが存在する場合の条件判定は大変複雑になり、おまけに明らかに私たちの間隔に反する動作をします。そのため、データベース界の有識者たちの間では「なるべくNULLを使うべきではない」ということが共通認識になっています。
引用元：[SQL第2版　ゼロからはじめるデータベース操作](https://www.amazon.co.jp/dp/B01HD5VWWO)

他にも、

- NULLを含んだ計算は問答無用でNULLになる
- NULLに比較演算子は使えない（is nullを使おう！）

というようなことがこの本には書いてあります。

nullはとても特別な子なのです。
nullは論理演算子においてもtrueにもfalseにもならないので、絞り込みから漏れてしまうとのこと。
本を読んでいた当時は「ふーんそうなんだ～」レベルでしたが、今回身を持って実感しました。

最終的にどのように解決したかというと、下記で突破できました。

```sql
select hogehoge
from fuga
where foo not like '%あいう%' or foo is null
```
比較演算子はnullには使用できませんので、foo = nullは不正解です。

ちなみに、本に記載のあったように、『「なるべくNULLを使うべきではない」ということが共通認識』ということはなさそうです。
現在、筆者はER図を勉強中ですが、絶対nullを発生させないように...！とテーブルを分けまくってER図を設計したら「分けすぎるとテーブル結合をしまくらないといけないからそこまで分けなくていい」と、オンラインスクールのメンターにフィードバックされていた生徒を見ました。
実際弊社でもNULL値が入っているテーブルはあるようです。

やはり机上の勉強だけではなく、現場で行うことは大切ですね。

# 筆者は何者？

いかがでしたでしょうか。
プログラマーの方から見れば、拙い文章だったかもしれません。
実は筆者の職種はエンジニアではございません。
普段はセールスという営業ポジションにて働いています。

なぜエンジニアたちのアドベントカレンダーに参加しているのか。
[フィヨルドブートキャンプ](https://bootcamp.fjord.jp/welcome)（以下、フィヨルド）というオンラインスクールに会社の福利厚生で通わせていただいているため、半ば強制...ではなく、自ら喜んで参加させていただきました。

本記事に記載したSQLについても、フィヨルドに通ったことがきっかけで書き始めました。しかしSQLはプログラミングのほんの一部に過ぎません。それだけのために入学する決断をするのはもったいないでしょう。わたしは、プログラミングをやって行くにつれて、エンジニア陣との共通言語が増えたことがとても嬉しいです。

自分も一味違う営業になりたい！と思った方は一度採用情報をご覧ください。
もちろん、ただの福利厚生制度なのでプログラミングを学ぶのは全く持って必須ではないのでご安心を。あなたなりの「一味」を見つけてください。
株式会社Catallaxy　採用募集ページ：https://open.talentio.com/r/1/c/catallaxy/homes/2947

一連のアドベントカレンダーを書いているような、様々な社員があなたをお待ちしております。

今後のアドベントカレンダーもお楽しみください。
pythonのsubprocessでコマンド実行

## subprocessでコマンド実行結果を取得

以下で取れます。

```bash
import subprocess
res = subprocess.run("whoami", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 

print(res.returncode) #=> 終了コード
print(res.stdout)  #=> 標準出力
print(res.stderr) #=> 標準エラー出力
```


以上です。

※以下、どうでもいいこと。

「こんにちは！ IT業界3日目の初心者プログラマーです! 」みたいな入りやめませんか。
「こんにちは！ IT業界3日目の初心者プログラマーです! 今日はosのカーネル解析をしてみました！」みたいな。
型 'string | undefined' を型 'string' に割り当てることはできません。

学習中の備忘録として

```auth.ts
export const signOut = () => {
  return client.delete("/auth/sign_out", { headers: {
    "access-token": Cookies.get("_access_token"),
    "client": Cookies.get("_client"),
    "uid": Cookies.get("_uid"),
  }})
}
```

だと

```
Type 'string | undefined' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.  TS2322

    17 | export const signOut = () => {
    18 |   return client.delete("/auth/sign_out", { headers: {
  > 19 |     "access-token": Cookies.get("_access_token"),
       |     ^
    20 |     "client": Cookies.get("_client") || "",
    21 |     "uid": Cookies.get("_uid") || "",
    22 |   }})
```

とのコンパイルエラーとなったので、String || undefinedと明示してあげる必要があると思い下記のように修正した。

```auth.ts
export const signOut = () => {
  return client.delete("/auth/sign_out", { headers: {
    "access-token": Cookies.get("_access_token") || "",
    "client": Cookies.get("_client") || "",
    "uid": Cookies.get("_uid") || "",
  }})
}
```

無事コンパイルされ期待した通りに動いた。
（何気にあれこれ試してここで3時間は潰れた）
Collaのご紹介


こんにちは！
株式会社Catallaxyの[Catallaxy Advent Calendar 2021](https://qiita.com/advent-calendar/2021/catallaxy)、20日目の記事を担当させて頂きます。
17日目は謎の初号機X（エックス）さんによる[SQLでnullにはまった話](https://qiita.com/catallaxy/items/a4a1acf3f26e96cb95ed)でした。

自己紹介が遅れました、わたくしバックオフィスの甲平と申します。
本日は弊社で取り入れているCollaをご紹介したいと思います。

### Collaとは
CollaとはBotがチームメンバーのことを教えてくれるSlackアプリです。
[Colla（コラ）](https://colla.jp/)

関わりのないメンバーのことを知ることができたり、コミュニケーションを取るきっかけにもなったりと、大変ありがたい存在です！
Collaさんが普段わざわざ聞かないような質問もしてくれるので、意外な一面を知れたりするのがとても面白い。

### 使い方

使い方はとても簡単で
1. Collaさんから送られてくる質問に答える
2. 設定したslackチャンネルにてシャッフルで回答が公開される
というものです！シンプル！


こんな感じで質問がきます。
![質問.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/8f07ecac-c3d5-dd32-9414-c9871f6ced59.png)


全然回答してないのがばれる…。

「質問に答える」から回答するだけでＯＫ！
![名称未設定のデザイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/c449b93a-2b07-1f53-8c20-829874801623.png)

Collaさんは律儀なので即レスしてくれます。できる女。

弊社ではColla専用チャンネルを作っており、そこに回答が通知されます。
![シャッフル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/a87c7cc6-a307-66f6-c9af-bfbbbcbb91a2.png)

一つ目の回答者が12/7記事担当の方だということが一目瞭然です。
[仕事ができるいいやつ](https://qiita.com/catallaxy/items/9eb62c04884bcc826cdd)

質問については設定が可能で、弊社では下図のように設定しています。
![576d85051fdaad12d609281d2153d22c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/a80dccb5-69ca-0a06-1a12-026e4f372398.png)

メンバー全員が出社したであろう11時に質問をし、眠くなってくるであろう15時頃に回答を投下する作戦です。
その他はてきとうです。

### 回答集

そんなこんなで導入してはや5ヶ月程経ちました。
個人的にお気に入りの回答を発表したいと思います。

===
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/364a35d3-c402-41b0-d9ba-fbcf7da04082.png)
立派な大人になれて良かったです。
 
===
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/770a65d0-77ab-84b9-01bb-c118d54f9895.png)
ちょっと怖いですね…

===
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/7318f131-9348-01d6-6abc-eb3b76ea4de6.png)
そこは果たして観光地なのか

===
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/65291601-cc6f-6d42-9126-843921ec2bed.png)
ネタかと思いきや本当に軽音部でボーカルをされていたそうです！
聞きたい！

===
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/de60242a-271d-1802-a7d4-9dc3134bf7f5.png)
味覚が心配。

===
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/5dec22de-e4b3-ee35-7b36-dbb0126ceaa2.png)
これはむちゃくちゃ笑いました。
無料コーヒーに並ぶのは関西人だけらしいですね！？
（筆者も回答者も関西人です）

===
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/e443a8a2-10ab-6324-9b53-19446c403189.png)
Collaさんに辛辣

===
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/30444c2a-75ee-bafe-4c13-4e09dd9cae92.png)
お笑い芸人なの？

===

いかがだったでしょうか？
気になる回答はありましたか？

### 最後に

現在弊社ではざまざまな職種を募集中です。
メンバーや会社に少しでも興味を持った方は是非下記ページをチェックしてみてください！
[株式会社Catallaxy/採用募集ページ](https://open.talentio.com/r/1/c/catallaxy/homes/2947)

明日はXXさんです。お楽しみに！
AWS WAF マネージドルールについて



### 1. AWS WAFとは

AWS WAFとは、ウェブアプリケーションの通信内容を検査し、不正なアクセスを遮断するサービスです。ウェブアプリケーションの脆弱性を悪用した攻撃などからウェブアプリケーションを保護することが目的であり、AWS WAFはALB、CloudFront、API Gatewayに紐付けされます（EC2には直接適用できません）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/a9ea571b-01a4-6452-a009-12e43ca0f952.png)

### 2. Web ACLとは

AWS WAFは、Web ACL と呼ばれるルールの集合体を定義することで、攻撃に対する戦略を定義します。ルールは、ステートメント（リクエストを検査するための条件の定義）、アクション（条件に一致したリクエストの処理方法）により構成されます。Web ACLで設定できるルール数には上限があり、ルールに紐づくWeb Capacity Unit(WCU)の合計値が決まっています。

### 3. マネージドルールとは

WAF WAFでは、AWSが準備したマネージドルールもしくはサードパーティが作成したルールをセットします。[ここ](https://www.wafcharm.com/blog/how-to-choose-aws-managed-rules/)のサイトがとても分かり易いので、この内容を以下に抜粋します。[こちらも](https://dev.classmethod.jp/articles/aws-waf-v2/)分かり易い。

***Core Rule Set***
一般に Web アプリケーションに適用されるルールが含まれています。これにより、OWASP の出版物や一般的な Common Vulnerabilities and Exposures（ CVE ）に記載されているものを含む、広範な脆弱性の悪用に対する保護が提供されます。
***Admin Protection***
公開された管理ページへの外部アクセスをブロックできるルールが含まれています。
これは、サードパーティのソフトウェアを実行している場合や、悪意のある攻撃者が
アプリケーションへの管理アクセス権を取得するリスクを軽減したい場合に役立ちます。
***Known Bad Inputs***
無効であることがわかっており、脆弱性の悪用または発見に関連付けられている要求パターンを
ブロックできるルールが含まれています。これにより、悪意のある攻撃者が脆弱なアプリケーションを発見するリスクを減らすことができます。
SQL Database SQL インジェクション攻撃など、SQL データベースの悪用に関連する要求パターンをブロックできるルールが含まれています。これにより、不正なクエリのリモート注入を防ぐことができます。
***LINUX operating system***
Local File Inclusion（ LFI ）攻撃など、Linux 固有の脆弱性の悪用に関連する要求パターンをブロックするルールが含まれています。これにより、ファイルの内容を公開したり、攻撃者が
アクセスすべきではないコードを実行したりする攻撃を防ぐことができます。
POSIX Operating System Local File Inclusion（ LFI ）攻撃を含む POSIX / POSIX ライクな OS に固有の脆弱性の悪用に関連するリクエストパターンをブロックするルールが含まれています。これにより、ファイルの内容を公開したり、アクセスを許可しないコードを実行したりする攻撃を防ぐことができます。
***Windows Operating System***
Windows 固有の脆弱性（ PowerShell コマンドなど）の悪用に関連する要求パターンをブロックするルールが含まれています。これにより攻撃者が許可されていないコマンドを実行したり、悪意のあるコードを実行したりする攻撃を防ぐことができます。
***PHP Application***
安全でない PHP 関数の挿入など、PHP の使用に固有の脆弱性の悪用に関連する要求パターンをブロックするルールが含まれています。これにより、攻撃者がリモートでコードまたはコマンドを実行できるエクスプロイトを防ぐことができます。
***WordPress Application***
WordPress アプリケーショングループには、WordPress サイト固有の脆弱性の悪用に関連する
リクエストパターンをブロックするルールが含まれています。
***Amazon IP Reputation***
このグループには、Amazon 脅威インテリジェンスに基づくルールが含まれます。これは、ボットやその他の脅威に関連するソースをブロックする場合に役立ちます。

お客さんに提案するときは、こういった形（↓）で整理すると良いのだろうな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/7774c43a-4e08-ed66-1aa1-6128ddfdb8a8.png)

以上
Salesforceで「作成日」を秒数まで表示する数式項目作成方法

今回はSalesforceで「作成日」を秒数まで表示する数式項目作成方法をご紹介します。
通常であれば作成日項目は
2021/12/08 17:35
のように分単位しか表示されません。

何秒まで　を表示させるには、数式項目（項目型：テキスト）を作成する必要があります。

数式は下記となります

TEXT(YEAR(DATEVALUE( CreatedDate ))) + "/" + LPAD(TEXT(MONTH(DATEVALUE(CreatedDate))), 2, "0") + "/" + LPAD(TEXT(DAY(DATEVALUE(CreatedDate))), 2, "0") + " " + LPAD(TEXT(HOUR(TIMEVALUE(CreatedDate ))+ 9), 2, "0") + ":" + LPAD(TEXT(MINUTE(TIMEVALUE(CreatedDate))), 2, "0") + ":" + LPAD(TEXT(SECOND(TIMEVALUE(CreatedDate))), 2, "0")


なお、上記数式は日本時間の時間差を考慮したもの（つまり+９時間　をしたもの）
です。

時間差を考慮しなければ下記となります

TEXT(YEAR(DATEVALUE( CreatedDate ))) + "/" +
LPAD(TEXT(MONTH(DATEVALUE(CreatedDate))), 2, "0") + "/" +
LPAD(TEXT(DAY(DATEVALUE(CreatedDate))), 2, "0") +  
" " +
LPAD(TEXT(HOUR(TIMEVALUE(CreatedDate))), 2, "0") + ":" +
LPAD(TEXT(MINUTE(TIMEVALUE(CreatedDate))), 2, "0") + ":" +
LPAD(TEXT(SECOND(TIMEVALUE(CreatedDate))), 2, "0")
秒数を数える

秒数を数えるためには、タイマーを使うと便利です。

タイマーをリセットするブロックを実行するとすると、０からタイマーブロックが動きます。

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75307/0dbe157f-a829-d565-a5e9-00017208c57c.png">

あとはタイマーブロックの値を調べれば、リセットしてからの経過時間が分かります。値はミリ秒が小数点以下で表されています。切り捨てれば秒数が整数で取得できます。

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75307/c43eeaa9-0c58-4809-44fa-cacd339cb590.png">

サンプルでは、ストップウォッチを作ってみました。

サンプルプログラム
https://scratch.mit.edu/projects/617696412

![スクリーンショット](https://cdn2.scratch.mit.edu/get_image/project/617696412_480x320.png)
【S3のACL設定について】

クロスアカウントでの S3アップロードではまらないためにしっかり理解しよう。
### **S3のACLとは？**
バケットとオブジェクトへのアクセスを管理できる。
### **そもそもネットワークACLとはなんだったか？**

S3のACL設定とは別物。

VPCレイヤにかけることで複数サブネットに対するインバウンドトラフィックとアウトバウンドトラフィックを制御できる。

セキュリティグループとの違いとしては、サブネット全体（インスタンス全体）に対するFW設定がしたいのか、各インスタンスレベルでのFW設定がしたいのかといった使い方の違いがある。

### **S3はデフォルトACLを自動設定する**

リソースの所有者にフルコントロール権限を与えるACLが設定される。

### **S3のACL設定は３要素に大別できる**

`Owner要素` Ownerの正規ユーザー ID を通じて所有者を識別する
`Grantee要素` どの被付与者（アカウントorグループ）に対してPermissionを適用するかを決める
`Permission要素` Granteeで決めた被付与者に対して権限を付与する

```yaml
{
   "Owner": {
		"DisplayName": "",
		"ID": ""
	},
	"Grants": [
		{
			"Grantee": {
			"DisplayName": "",
			"ID": "",
			"Type": ""
		},
		"Permission": "FULL_CONTROL"
	}]
}
```

### **新規オブジェクトの所有者はデフォルトではアップロードアカウント**

バケット所有者はデフォルトでは別アカウントからアップロードされたオブジェクトにアクセスできない。
バケット所有者が別アカウントからアップロードされたオブジェクトにアクセスできるようにするためには、**`PutObject`**に**`-acl bucket-owner-full-control`** オプションを付与する。

### **オブジェクトの所有者が誰になるか問題**
![25A9B994-6D55-4ADE-A031-EA5C2B28279F.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530710/5fc5d3d5-6701-76ae-5d6d-b3d0eda6be7a.jpeg)
`希望するバケット所有者` 
bucket-owner-full-control 既定ACLを設定したリクエストをすればバケット所有者にもアクセス権限が付与される。

`オブジェクトライター` 
デフォルトの設定。アップロードアカウントがオブジェクト所有者となり、バケット所有者が別アカウントの場合にバケット所有者にアクセス権がなくなる
Azure Cognitive Servicesで提供されているSpeech serviceを使ってみた。

#はじめに
Azure Cognitive Servicesで提供されているSpeech serviceを使って音声テキスト変換機能を実装する機会があったので、簡単にご紹介したいと思います！

##そもそもSpeech Service とは
Speech Serviceとは音声テキスト変換、テキスト読み上げ、音声翻訳を Azureが提供するSpeech CLI、Speech SDK、REST API などを使って簡単にWebアプリ、ツール、デバイスに実装することが出来る便利なサービスです。

##音声テキスト変換が提供する機能
以下のような機能が提供されています。
・リアルタイムの音声テキスト変換
オーディオ ストリームまたはローカル ファイルからテキストへの文字起こしまたは翻訳をリアルタイムで行います。

・一括音声テキスト変換
Azure Blob Storage に格納された大量の音声データに対して、音声からテキストへの文字起こしを非同期で行うことができます。

・会話の文字起こし
リアルタイムの音声認識、話者識別、およびダイアライゼーションが有効になります。 話者を区別することができるため、対面会議の文字起こしに最適です。

また、他にも発音や評価する機能やカスタム音声モデルの作成機能などがあります。

#音声テキスト変換機能を実装してみる。
音声ファイル（wav形式）をローカル上でテキストに変換してみる。

■実行環境
macOS
python3.8

■実行準備
①Azure sppechサービスの作成。
Azure portalへログインしてCognitive Servicesの音声サービスを立ち上げます。
![speech-service.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335632/a18b85db-4311-e6b6-f4fb-cf9cf52e3ca0.png)
音声サービスのデプロイが完了したら、サブスクリプションキーと地域（リージョン）を控えます。（コードを実行する際に利用するため）

![key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335632/8e181903-2d7e-c1a4-c798-043f73809de8.png)

②音声ファイルの準備
・wav形式の音声ファイルを用意します。

③音声変換コードの準備
・下記コードを実行環境に用意します。

```voice-to-text.py
import azure.cognitiveservices.speech as speechsdk
import os

#音声サービスの接続情報
speech_subscription = "<サブスクリプションキーを格納>"
speech_region= "<サービスのリージョンを格納>"
language = "ja-JP"

#音声ファイルのパス
voice_file = "<音声ファイルのパスを格納>"

def voice_to_text():
    speech_config = speechsdk.SpeechConfig(subscription=speech_subscription, region=speech_region,speech_recognition_language=language)
    audio_input = speechsdk.AudioConfig(filename=voice_file)
    speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_input)
    result = speech_recognizer.recognize_once_async().get()
    return result.text


print("音声ファイルの変換を実行中")
text = voice_to_text()
print("音声ファイルの出力：",text)
print("処理終了")
```

■実行結果の確認

```実行結果.
% python3.8 voice-to-text.py
音声ファイルの変換を実行中
音声ファイルの出力： 天気は晴れです。
% 
```
問題なく、音声ファイルからテキストに起こされていることを確認できました！
今回は非同期の音声テキスト変換でしたので、次回はリアルタイムでの音声テキスト変換をやってみようと思います。
error /node_modules/node-sass: Command failedの解決策

タイトルの通り、/node_modules/node-sass: Command failedのエラーが発生し、うまくWebpackが動作せず`Webpacker::Manifest::MissingEntryError`が発生しました。

その解決方法を残しておきます。

## 環境

```
ruby 2.7.2
rails 6.0.3.4
node --version v16.0.0
```

## エラー内容

`bundle exec rails webpacker:install`コマンドを実行するとこのようなエラーが出ました。

```
error /Users/xxx/xxx/xxx/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
Exit code: 1
Command: node scripts/build.js
Arguments: 
Directory: /Users/xxx/xxx/xxx/node_modules/@rails/webpacker/node_modules/node-sass
```

## 状況

`package.json`には本来あるはずの以下の記述がありませんでした。

```json
"@rails/webpacker": "5.4.3",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12",
"node-sass": "^7.0.0",
```

## 変更内容

### 1 webpacker

まずは、Gemfileを変更しwebpacekrのバージョンを変更しました

```rb
前
gem 'webpacker', '~> 4.0'

後
gem 'webpacker', '~> 5.0'
```

### 2 yarn.lock or package.lock.jsonを削除

次に、`yarn.lock` または `package.lock.json`を削除します

### 3 package.json

次に、package.jsonに`"@rails/webpacker": "5.4.3"`を追記します。


### 4 yarn install

`$ yarn install`を実行します

### 5 yarn add node-sass

`$ yarn add node-sass`

以上の手順でうまくwebpackerが動作するようになりました。
電気設計からエンジニアになってみて

# 電気設計からエンジニアになってみて



工作機械メーカーの電気設計者からITエンジニアに転職して約半年が経ちました。
エンジニアになるまでの経過と、実際になってからの所感を記事にしました。





## この記事は下記のような方におすすめの記事です。

**・ITエンジニアを志そうか迷っている人**

**・エンジニアへの転職活動に不安を持っている方**

僕自身が体験した内容と、勉強した事、行動などを記事にしていますので

参考になれば幸いです。



## 経歴

| 年月            |               所属               |
| :-------------- | :------------------------------: |
| 2016/4~2020/03  | 工作機械メーカー電気設計（新卒） |
| 2020/03~2020/08 |      Progate, 書籍等で独学       |
| 2020/08~2021/01 |         ポテパンキャンプ         |
| 2021/01~2021/05 |   ポートフォリオ作成＆転職活動   |
| 2021/07~        |     受託開発の企業に中途入社     |

大学は理工学部を卒業、プログラミングはC言語の基礎を履修。

当時ハッカーに憧れていた経緯もありプログラミングに興味を持つ...がアホの子なので再テストでギリギリ単位習得

研究室ではMATLABといった数値解析を扱うソフトを使ってグラフ描写の為にプログラミング書いていた。

こういった背景があり何となくプログラマーになろうかなぁと考えるようになった。



## エンジニアになろうと思ったきっかけ

社会人になって５年ほど電気設計に熱中したが、工作機械の電気設計は電気回路の設計と機械のシーケンスを考える仕事であり、私が楽しいと思えるのは機械のシーケンス（動作）をPLCといったソフトを使って正しい動作をするか、バグがあればどのようにして修正すればいいか、等を考える時間が楽しかった。

次第に学生時代に抱いていたプログラミングへの興味が、火をかけはじめたヤカンの水のようにふつふつと再燃するようになった。

#### ２０代特有の奇病「おれ、このままでいいんだろうか」

そしてこの時期の僕は代わり映えのない生活のなかで自分の将来について案じることが多くなった。

聞けば多くの二十代はこの奇病を一度は患うことが多いらしい。僕も例外に漏れず日々自問自答をしていた。

2019年末に大学の友人で奇病のことを話すと彼らも患っているらしく、このままではいかんと一致団結して

**「２０２０年はチャレンジの年にしよう。やりたかった事にチャレンジしよう」**

と皆で意気込み、筋トレと勉強を毎日スカイプを通して行うことを約束した。

この時にエンジニアになろうと固く胸に刻んだ。



## エンジニアとして働いてみた感想

結論を先に言いますと

**ITエンジニア最高！！！超楽しい！！！前職には戻れない！！**

転職したことに１ミリも後悔なく、非常に満足のいく転職が出来たと思う。

理由としては下記が大きい

**・出社は任意**

**・服装自由**

**・オフィスが綺麗**

**・残業時間が全体的に非常に少ない**

**・優しい人がおおい**

何より一番不安に感じていたのは、自分の能力で仕事がまともに出来るのかどうかだったが

Pマネの方や同僚の方の手厚いサポートもあり、スムーズにアサインできた。

企業からの評価も概ね良好（当然お世辞も含まれていると思うが）だったので最高の環境の職場で働けていると思う。



## 今後はどんなエンジニアを目指したいか
今はわからなことがあればPM、先輩方にご教授していただいているので、
私が誰かに教えるような立場として立ってみたい気持ちが強い。
弊社には地元大学、専門学校向けにハッカソンやインターンを定期的に行っているため、そのようなイベントに定期的に参加しようと思う。


## 最後に

私は転職活動中に常に他の未経験エンジニアとの差別化を意識していました。

転職活動は時間がかかればかかるほど不安になってしまいますが、自分の強みを見直すことは非常によい経験だと思うのでたっぷり時間をかけて転職活動をしても問題ないと思います。

読者の方の転職活動応援しています！



転職活動はWantedlyのみで行っていました。ポテパン卒業の方はよかったら参考にしてください

https://www.wantedly.com/id/nama0606
mui の CircularProgress を反時計回り(左回り/counterclockwise) に回す

mui(v5) の CircularProgress を反時計回り(左回り / counterclockwise) に回す方法です。

`variant="determinate"` の場合、 `value` に負数を与えることで反時計回りに回すことができます。

```tsx
// 時計回り
<CircularProgress variant="determinate" value={0} />
<CircularProgress variant="determinate" value={25} />
<CircularProgress variant="determinate" value={50} />
<CircularProgress variant="determinate" value={75} />
<CircularProgress variant="determinate" value={100} />

// 反時計回り
<CircularProgress variant="determinate" value={0} />
<CircularProgress variant="determinate" value={-25} />
<CircularProgress variant="determinate" value={-50} />
<CircularProgress variant="determinate" value={-75} />
<CircularProgress variant="determinate" value={-100} />
```

**イメージ**
![mui-circular-progress-counterclockwise-CodeSandbox (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95831/8c789d5b-6b77-fe7c-ea0e-fc840239b8f6.png)

**注意**
[mui の ドキュメント](https://mui.com/api/circular-progress/#props)では 0 - 100 の正の数を受け取ると説明されており、将来的に塞がれてしまう恐れがある hacky な方法なので、実際に利用される場合にはご留意ください。
PrimeHub デモビデオ ー モデルからデプロイまで


## デモビデオ

### MLflow Setup

<iframe width="560" height="315" src="https://www.youtube.com/embed/f_ECpNGB4WA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

### Models Tracking

<iframe width="560" height="315" src="https://www.youtube.com/embed/ZLUA3Q2taDw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


### Model Deployment

<iframe width="560" height="315" src="https://www.youtube.com/embed/FbOV5Uwm7eo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## PrimeHubについて

+ [PrimeHub GitHub Repository](https://github.com/InfuseAI/primehub)

+ [PrimeHub Documentation](https://docs.primehub.io/)

+ [PrimeHub AWS One-Click Installation](https://qiita.com/GabxInfuseAI/items/dde88007c7ef63a56988)

+ [PrimeHub Enterprise - the End-to-End ML Platform](https://qiita.com/GabxInfuseAI/items/29132e25eddc622194b4)
RustでAKBONE2020を動かす


Wio TerminalでRustをやるのをちょっと途中で投げ出してました。
初心に戻ってArduinoからやり直そうと思います。

基本ここ↓をなぞっていけばよさそうですが手順通りに進めてもbuildできません :innocent:

https://book.avr-rust.com/

ちょっと調べてみたところ以下のissueにヒットするようで、`nightly-2021-01-07`のtoolchainを使わないとbuildできないようです。

https://github.com/rust-lang/rust/issues/82104

※LLVM側の問題の様子です
https://github.com/rust-lang/compiler-builtins/issues/400

### 環境構築

WindowsのWSLにRustを入れた後、`nightly-2021-01-07`のtoolchainをinstallしました。

```
rustup toolchain install nightly-2021-01-07
rustup component add rust-src --toolchain nightly-2021-01-07
```

### Lチカ

installしたらこの方のコードをCloneします。

https://elchika.com/article/c74e9dd4-cdbe-4550-a4e9-60730bb374b0
https://github.com/grace2riku/avr-hal/tree/add_leafony

```
git clone -b add_leafony https://github.com/grace2riku/avr-hal.git
cd avr-hal/boards/arduino-uno/
cargo +nightly-2021-01-07 build --example uno-blink
```

buildできたらホスト側のTerminalからelfファイルをArduinoに書き込みます。
WindowsではAKBONEを挿したらデバイスマネージャーでポートを確認してCOM3=ttyS3に置き換えるといいようです。

```
avrdude -patmega328p -carduino -P/dev/ttyS3 -b57600 -D -Uflash:w:../../target/avr-atmega328p/debug/examples/uno-blink.elf:e

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "../../target/avr-atmega328p/debug/examples/uno-blink.elf"
avrdude: writing flash (374 bytes):

Writing | ################################################## | 100% 0.11s

avrdude: 374 bytes of flash written
avrdude: verifying flash memory against ../../target/avr-atmega328p/debug/examples/uno-blink.elf:
avrdude: load data flash data from input file ../../target/avr-atmega328p/debug/examples/uno-blink.elf:
avrdude: input file ../../target/avr-atmega328p/debug/examples/uno-blink.elf contains 374 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.08s

avrdude: verifying ...
avrdude: 374 bytes of flash verified

avrdude: safemode: Fuses OK (E:00, H:00, L:00)

avrdude done.  Thank you.
```

書き込みに成功してLEDが点滅すればOKです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146663/987839b0-bb2f-d857-e4cf-2f8893514f92.png" width=400 />
【Chobiitカスタマイズ集・その②】サイドバーを非表示にする！

#はじめに
今回も今回とて、Chobiitのカスタマイズについて紹介したいと思います！
Chobiitとは、株式会社ノベルワークスが提供している
Cybozu社のkintoneとの外部連携サービスです。
詳しくはこちらをご参照ください！→https://www.novelworks.jp/chobiit

#Chobiitのサイドバーってどこ？？
画像赤枠の部分になります。
![スクリーンショット (32).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1487043/a3ab776a-715d-6ea4-1e45-0aa73812fe63.png)


最近「クリックする箇所を最小限にしたい＝サイドバーを非表示にしたい」という
お声を頂くことが増えてきました。
今回はこの赤枠の部分を非表示にするカスタマイズをご紹介致します！

#手順①：サイドバーを非表示にする

```css:hide_sidebar.css
/*サイドバーを非表示*/
#sidebar {
    display: none;
}

/*list-app-custom.jsでのモバイル版対応の影響回避*/
#content{
    height: 100vh;
}

/*ヘッダーを左詰め*/
.header {
    padding-left: 0px;
}

/*レコード詳細画面のボタンを左詰め*/
.follow {
    left: 0;
}
```

上記で作成したCSSをChobiitに設定します。
設定方法や設定場所については、下記のURLを参照してください。
→https://www.novelworks.jp/chobiit/customize/

設定してみると…サイドバーが消えました！
![スクリーンショット (34).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1487043/5c27055d-7cdf-cc7c-ee98-8e62518750ea.png)

ただし、ここで問題発生です。
サイドバーと一緒に、ホームへの遷移ボタン（赤色の枠）も消えてしまいました。
そのため、ロゴ＋表示名（黄色の枠）からホームへ遷移させる実装をしましょう！
![スクリーンショット (33).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1487043/9ec9b97f-5ba2-5d77-7846-70734ac702ea.png)


#手順②：アプリ一覧画面に遷移する処理

```javascript:list-app-custom.js
$(function () {

    //sibar
    //モバイル版：サイドバー非表示
    $('#rowOffCanvas').removeClass('row-offcanvas');
    $('#rowOffCanvas').removeClass('row-offcanvas-left');
    $('.d-sm-block').remove();

    //モバイル版：ロゴを表示
    $('.logo').siblings().show();
    
    //モバイル版：表示名を表示
    $('.logo').siblings().css('font-size', '0.9rem');
    
    //ロゴのカーソル形状を設定
    $('.logo').css('cursor', 'pointer');
    
    //表示名のカーソル形状を設定
    $('.logo').siblings().css('cursor', 'pointer');
    
    //ロゴをクリックしたらアプリ一覧画面に遷移
    $('.logo').click(function () {
        location.href = location.origin + '/list_app.html';
    });
    
    //表示名をクリックしたらアプリ一覧画面に遷移
    $('.logo').siblings().click(function () {
        location.href = location.origin + '/list_app.html';
    });

});
```


これで解決です！
[JavaScript] innerHTMLの使い方

# innerHTMLの使い方
**innerHTML**とは、HTML要素の中身を取得・変更する際に使用されるプロパティ。
HTML要素の中身を変更できるので、動的にwebページを作成することができる。

## 要素を取得する場合
対象のHTML要素を取得し、表示する場合は以下のように書ける。

```html:index.html
<div id="elementId">
    <p> こんにちは！ </p>
</div>
```

```javascript:sample.js
const element = getElementById(elementId);
console.log(element.innerHTML);     //  <p> こんにちは！ </p>
```

## 要素を変更する場合
対象のHTML要素の中身を変更する場合は以下のように書ける。

```javascript
const element = getElementById(elementId);
element.innerHTML = <変更内容>;    
```
**innerHTML**は、要素を書き換えるため、変更前の内容は残っていない。単純に要素を追加したい場合は、```appendChild()```がある。
また、以下のようにすると対象要素の中身を削除（空）にすることができる。

``````javascript
element.innerHTML = "";    
```
なぜ WHI では times 文化がうまくまわっているのか？

# そもそも times って？

times（分報、timeline、などと言われたりもします）とは、Slackなどの社内コミュニケーションツール上で自分専用のチャンネルを作成し、自分の好きなタイミングで好きな内容を投稿していくものです。
要は社内Twitterのような感じです。
自分で進めているタスクの進捗管理やTODO管理、ちょっとした相談や雑談など、いろいろな用途で使うことができます。

# times のメリット・デメリット

times を始めてみるととても便利で、メリットがたくさんあります。
しかし、もちろんデメリットもあります。

## メリット

- 社内コミュニケーションが活発になる
    - 実際に会って話したことがないメンバーでも、times を見るとなんとなく人となりがわかったりする
    - 部署が異なる人でも、times なら交流しやすい
- 気軽に投稿できる
    - 困った時に「助けて！」と言いやすい
    - 誰かが助けてくれることも多い
    - 同じ問題を感じる人同士で集まって、改善に向かってアクションをとるきっかけになったりする
- 自分の思考や学びを整理できる
    - 考えていることや学びを文字起こしすることになるので、自ずと整理されていく
    - 自分以外の人にも共有できる

## デメリット

- times の数が増えすぎるとどれを見たらいいかわからない、見るのに時間がかかる
    - たくさんの times に入っていると、通知が止まらなくなったりする
- 井戸端会議になりがち、情報が一部の人にしか伝わらない
    - いわゆるタバコ部屋のような
- 雑談しすぎてしまう、業務に支障が出る
- 文章を書くのが苦手だと使いづらい
- 治安が（以下略）

人数に対してスケールしない、timesアクティブユーザーが100を超えると厳しい、などの意見[^1]もあるようです。

[^1]: https://note.com/vaaaaanquish/n/ncc512cf0e263

# WHI の times 文化

WHIの従業員数は執筆時点で1738名[^2]、社内Slackのtimesの数は750を超える[^3]ようです。

[^2]: https://www.works-hi.co.jp/corporate

[^3]: 個人のtimesだけではなく、部署として運営しているtimesも含みます。

times アクティブユーザーが 100 を超えると厳しいという意見もあるなか、少なくとも筆者のまわりでは times がとてもうまく活用され、社内のコミュニケーションや業務にとても役立っているように見えます。

なぜ WHI では times 文化がうまくいっているのか、理由を考えてみました。

## 情報のハブになってる times が複数ある

times の数が増えすぎると、どれを見たらいいかわからないという問題が発生します。
これに対して、WHI の社内 Slack には「この人の times を見ておけばだいたいの情報がつかめそう」「とりあえず参加しとけば安心」という times が複数存在します。

それぞれ別組織の人の times なので集まる情報が微妙に異なりつつ、ハブとなっている times 管理者同士は相互フォローなので、時には同じ情報が流れてきたりします。

times がたくさんありすぎてどれを見たらいいかわからない、たくさん入ると疲れてしまう、という人でも、ハブとなっている times にだけ入っておけば自然と情報が流れてくるため、情報格差が起こりにくい状態となっています。

社内の風通しをよくしてくれる人が複数人いるようなイメージです。

## ポジティブな人が多い、誹謗中傷は基本的にない

基本です。そもそも times は他人を攻撃するためのものではありません。
しかし、思ったことを気軽に投稿できるという性質上、意図せずに他人への攻撃を投稿してしまう、というパターンも times ではよくあると思います。

WHI の場合、会社の雰囲気・文化として、ポジティブな人（問題解決型の思考をする人）が多いため、この問題があまり表面化していないように感じます。
何か困ったことや問題点・課題について投稿するときには、感情的な投稿をするのではなく、
解決案や自分の考え、アイディアを添える人が多いように感じます。[^4]

[^4]: 感情的な投稿が全くないわけではありません。

## もともと雑談推奨な文化

WHI はもともと雑談推奨な会社です。[^5]
もともと雑談推奨な文化があったので、対面でのコミュニケーションが減少し、代わりに Slack でのコミュニケーションが主流になっていった時に、自然と times という文化が生まれたように感じます。
もともと雑談推奨なので、雑談も業務の延長線上で、本業に支障が出ることもありません。

[^5]: WHI の前身である Works Applications 社から引き継いだ文化だと思います。

## times を業務利用していない

1つ前に「雑談も業務の延長線上」とは書きましたが、あくまでも雑談は雑談、times は times です。
times を利用する人がどんなに増えても、業務に関する重要な連絡や公式な連絡は、チームチャンネルやプロジェクトのチャンネルなどの公式な場所で行っています。
この使い分けがキチンとできていることで、「重要な決定が times で行われてアナウンスもされなかった」などという事態はほぼ発生しません。

## コミュニケーションの場が複数ある

times はその性質上、どうしても文字によるコミュニケーションとなってしまいます。そのため、自分の考えを文章に表現することが苦手だったり、文章を書くのに時間がかかる人にとっては times の活用が難しい場合もあります。

WHI の場合、Google Meet や oVice による対面・口頭での雑談の機会や会社からの情報発信のプラットフォームなど、
times 以外にも社内コミュニケーションの場が複数設けられています。
times が苦手な場合は times 以外を使えばいいので、自分に合ったコミュニケーションを選択することができます。

# まとめ

WHI で times 文化が根付いている理由、うまくまわっている理由について考えてみました。
WHI にもともとあった雰囲気・風土が times 文化とフィットしていたということと、社内のコミュニケーション施策に力を入れていることが、うまくまわっている大きな理由なのではないかと感じます。
今後もうまく times を活用し、業務に行かせていけるといいなと思います。

### 参考文献

- https://giginc.co.jp/blog/giglab/slack-hunho
- https://note.com/vaaaaanquish/n/ncc512cf0e263
- https://note.com/masashignio/n/n7f5daec0b5dc
- https://stefafafan.hatenablog.com/entry/2017/03/21/130422
apache+laravelで素のindex.phpが表示されるんだが

表題の事案。
こんな事態に直面することがあるのか、いや、あった。（反語）

どういうことか、順を追っていきたい。

### 環境

- ubuntu 20.04
- apache 2.4
- php 7.4.3
- Laravel 7.15

ちょっとわけあって、環境が少し古いものを構築しなければならず、ひと昔前のこんな要件に。
ただバージョンが違っても、同じことが発生した場合には同じ解決策でいけると思う。

### 状況と実施手順

１. さくらのレンサバでまず箱を作ってもらった
２. git、php、composerなど必要そうなものを一通りインストール(別の担当者が主に担当(責任転嫁☆))

```
# php関係
sudo apt install php7.4 php7.4-fpm php7.4-mbstring php7.4-dom php7.4-mysql php7.4-redis
sudo apt install zip unzip vim npm nodejs
```

３. cloneでソースコードを配置
４. 以下コマンドを実行しapache2.4を構築

```
# インストール
sudo apt update
sudo apt install apache2
# 起動を確認
systemctl status apache2

# 必要なモジュール
sudo a2enmod rewrite

# confファイル(中身は割愛)
sudo vim sites-available/hoge.conf
sudo a2ensite hoge

sudo systemctl reload apache2
```

５. さてアクセスしてみようぞ・・・
![capture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465525/393b23bf-a7b2-e306-c3dc-bb339dd249ce.png)

？？？？？？？？

apacheの設定手順に抜けがあったか…？
本来ならばindex.phpから適切にルーティングされていくはずだが。

右往左往すること(してない)数日、解決策をネットの海から釣り上げた。

### さっさと解決策を

とりあえず何かが足りていないことだけははっきりしていたが、
それにたどり着くまでかなりの時間を要してしまった。
結果的に以下コマンドで解決。

```
sudo apt-get install libapache2-mod-php7.4
```

やはり何かが足りなかったか。。。

インストールするものが漏れてしまうと
こんなかんじで普段発生しえない事象に遭遇してしまうので、
構築時に何をインストールするかはしっかり確認したいところですな。

### 参考リンク
https://www.webdevqa.jp.net/ja/php/laravel%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%ABindexphp%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E8%A1%A8%E7%A4%BA/831167465/
データ分析案件1年目でパイプラインを作った話

# はじめに

本記事はデータラーニングギルドAdvent Calendar 2021 16日目の記事となります。

データサイエンス未経験ながら、とある経験をデータラーニングギルド代表の村上さん(@tomoyuki-murakami)に評価頂いて、
今年の8月からデータ分析案件に関わらせて頂くことになりました。

そのあたりのことをふわっと振り返って行ければいいな、と思います。

# とある経験って何？

1年間だけですが、都内の認可保育園にて保育士をやっていた経験です。
0～4歳満遍なく見てましたが、0歳ちゃん長めです。

ちなみに4年制大学を卒業していれば、保育士試験をパスするだけで保育士資格が取れるようになっています。
未だに保育士は不足しているようなので、エンジニアに疲れたら挑戦してみてください（私もSIerしながら資格取りました）。


# 今何やってるの

赤ちゃんの行動を記録する育児アプリのデータ分析をしています。

最初の大きな案件としては、アプリ内のあるレポート機能を表示するためのデータパイプラインを作成しました。

リリース前につき多くは語れないので、パイプラインのアーキテクチャを軽く解説してみようとおもいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409742/0fe8e8de-d4aa-60bc-d842-56440a3af5a8.png)



#### Digdag 

バッチ処理を行うときの定番ツールです。
ワークフローを書くことでBigQueryとPythonの実行を制御します。

digdagサーバはdockerコンテナ上に立て、docker-compose.ymlに環境変数を書いておくことで、
開発/本番環境の差異を吸収することができます。[^1]

githubにdigファイルとsqlをまとめて置いておき、適宜以下のことを行うワークフローを作成しておくとソース管理に便利です。

```shell
$ git pull
$ digdag push hogehoge_workflow
```

Python処理はGCPのAI Platform Notebooksのインスタンスを別途立てています。
gcloud CLIで以下のようなコマンドを打つことで、他サーバに配置されたノートブックの実行することができます。

```shell
# digdagサーバにて
$ gcloud compute ssh fugafuga-instance --command="/usr/local/bin/exec_notebook.sh /home/jupyter/src/calculation.ipynb"
```

`gcloud compute ssh`にてコマンドを実行すると、Jupyter Labをブラウザで開いた場合のパスとは変わってしまうので、
ノートブック側に以下のようなラッパーを置いておきます。

```shell:/usr/local/bin/exec_notebook.sh
#!/bin/bash
export PATH="/usr/local/cuda/bin:/opt/conda/bin:/opt/conda/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin"
jupyter nbconvert --execute $1 --to notebook --inplace
```

[^1]: [digdagサーバをコンテナで動かしてジョブもコンテナで動かす際の設定例](https://qiita.com/kanga/items/7f2849ad5a2a625a662c)

#### Firebase

データベースにデータを突っ込んで置くと、RESTfulなAPIサーバとして扱うことができるBaaSです。
サーバレスでメンテいらず！爆速！しゅごい！

アプリケーションサーバーとデータの受け渡し方法は色々あるかと思いますが、

- 扱うデータの総量が小さい
- 複雑な検索クエリは必要無い
- アプリケーションサーバ側のRDBがAzureだったため、気軽にレプリケーション用のサーバを立てれない

などの理由でFirebaseによるAPI方式を採用しました。

難点としては、
Firebaseのデータベースは（Realtime DatabaseにせよCloud firestoreにせよ）、
json型の構造化データを使用するため、BigQueryと食べ合わせが悪いです。

今回はBigQueryで作成した分析結果をFirebase用のjsonに変換する処理をPythonで書き下しました。

```json:BigQueryから簡単に生成できるjson
{
  [{
    "user_id": "A-san",
    "feature": "XXXX",
  },
  {
    "user_id": "B-san",
    "feature": "YYYY",
  }]
}
```

```json:Firebaseで扱いやすいjson
{
  "A-san" : {
    "feature": "XXXX",
  },
  "B-san" : {
    "feature": "YYYY",
  },
}
```

# おわりに

今回は技術寄りのお話に終始しましたが、
保育のドメイン知識がこんな感じに生きたよーっていう話を次回があればしたいな、と思います。
Error:error configuring Terraform AWS Provider: error validating provider credentials: error calling sts:GetCallerIdentity: InvalidClientTokenId: The security token included in the request is invalid.

## What's This

TFリソースを削除しようとしたら、エラー。
エラー内容通りだったので、すぐ解決できた。

## Error Details

```
terraform destroy
```

で、構築したTFリソースを削除しようとしたら、以下エラー。

```
error configuring Terraform AWS Provider: error validating provider credentials:
 error calling sts:GetCallerIdentity: InvalidClientTokenId: 
The security token included in the request is invalid
        status code: 403, request id:"XXXXXXXXXX"
```

## Cause of failure
applyの際に使用していた、IAM ユーザーを削除していたからでした。

## How to resolve
再度、IAMユーザー作成して、シークレットキーとアクセスキーをenvファイルに入れてdestroyしたら、通りました。

## ほか
TFはコマンド１つで簡単にリソースをdestroyできるので、楽ですね。
英語の勉強 無料で高品質な英語教材 React

chromeブラウザでの翻訳ツール
DeepL翻訳（ベータ版）
https://chrome.google.com/webstore/detail/deepl-translate-beta-vers/cofdbpoegempjloogbagkncekinflcnj

英文を品詞分解するツール
Reader - AnnoReader
https://annoreader.com/reader

英語の動画
React Conf 2021 - YouTube
https://www.youtube.com/channel/UC1hOCRBN2mnXgN5reSoO3pQ

このYouTubeチャンネルには英語と日本語字幕がついています。
技術の動画英語は簡易です。
最新の技術です。
このチャンネルのようにすべてが揃っている所は稀です。

React Conf 2021 Recap – React Blog
https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html

React Conf 2021の概要

Tweaks for YouTube
https://chrome.google.com/webstore/detail/tweaks-for-youtube/ogkoifddpkoabehfemkolflcjhklmkge?hl=ja

Chromeの拡張機能
動画のスピードをマウスカーソルを動画上のある範囲に置く。
そこがスピード変更範囲だったらマウスホイールで簡単に変更できる。
そこが音声変更範囲だったらマウスホイールで簡単に変更できる。
そこが再生位置変更範囲だったらマウスホイールで簡単に変更できる。

Download subtitles from Youtube, Viki, Viu, Vlive and more! - DownSub
https://downsub.com/

このサイトで字幕をダウンロードできます。

日本語字幕
英語字幕
日本語＋英語字幕
(srtファイルも可能)
その他

srtファイルとは
字幕ファイルと呼ばれる、テキスト形式のファイルです。 

YouTubeで字幕をONにして、文字起こしを開きます。
文字起こしは保存ボタンの右にある3点リーダー（・・・）から開くことが出来ます。

文字起こし部分をクリックすればリピートもかんたんです。

数分でこれらを使用した英語学習する環境が整います。

YouTubeで英語と日本語の字幕がついた動画の検索ができるようになってほしい。
現在のYouTube検索では字幕がついているかどうかまでで、字幕の種類まで特定は出来ない。

YouTubu上の字幕の切り替えがかなり面倒。
ボタン一つで英語＜＝＞日本語字幕の切り替えが出来ないものか。
情報処理安全確保支援士に合格する方法

令和3年秋の試験で情報処理安全確保支援士に合格しました。感想書きます。

[午前Ⅰ] 免除
[午前Ⅱ] 92
[午後Ⅰ] 89
[午後Ⅱ] 69
[選択問題] 午後Ⅰ問1,2 午後Ⅱ問2
[受験回数] 1回
[学習時間] 午前Ⅱは2ヶ月前から、午後は1週間前から
[保有資格] AP
[参考書]　午前は過去問道場、午後は過去問集の本買った

そこそこ真面目に取り組んだ。午前Ⅱは過去問道場をときまくって、既出の問題であれば100％当たるレベルまで対策を行った。午前の内容は午後で固有名詞を問われることがあるので、固有名詞も含めて覚えるつもりでやった。その結果として午後Ⅱ問2でCRYPTRECを答えることが出来た。

午後の問題はより実践的な内容を問われるので、普段からネットワークやサーバーの設定を行っている人なら簡単に突破出来ると思う。ただ、何を記述すれば点が取れるのかを知る必要があるので、3日前あたりから数年分の過去問を解いて傾向と対策を掴むと良い。

この資格を取ってみてセキュリティってつまらないなぁと思った。特に午後の問題を見ていて、社内のPCにセキュリティソフトを導入するだとか、ネットワークにファイアーウォールを設定してログを分析するだとか、そういう問題は解決する方法もツールも確立してるし、それをただ状況に応じてカスタムして導入するだけのルーチンワークなのでつまらないなぁと私は思った。自分は先端技術で何か新しいことが出来ないか考えるのが好きなのであって、実際に人が使うパソコンをどのように安全に運用するのかなんてことには興味ないんだと思う。もっと先端のセキュリティ技術であれば楽しいのかもしれないが、少なくとも情報処理安全確保支援士の勉強の範囲内ではそういうのを知ることは出来なかった。結果としてセキュリティってつまらないという印象だけが残ってしまった。

まあ、登録セキュスペにはならなくていっかなぁ
WPF CheckBoxのサイズ変更（スタイルで）

WPFのデフォルトのチェックボックスのスタイルを変更して、サイズを変更する方法。

![20211216fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/7446741e-b344-debd-68f6-274d641d4763.png)

デフォルトのスタイルのうち、

- **markGrid** Width="24", Height="24"
- **optionMark** Margin="4", Stretch="Uniform"
- **indeterminateMark** Margin="4"

を変更すればOKです。

スタイルのコード全体は、次に掲載しておきました。

https://stackoverflow.com/questions/13481275/how-to-make-checkbox-bigger/70371693#70371693

### 備考

- チェックとその四角の枠のサイズを変更したいだけなのに、適当なスタイルを見つけることができなかったんですよね。
- スタイルの自由度が高いかわりに、スタイルのコードの量が多い。必要とする部分をみつけるのに、苦労する。
Warning: unable to build chain to self-signed root for signer "iPhone Developer: XXXXXX (XXXXX)" の対処方法

# はじめに

Xcode でビルドする際に以下のようなエラーが出るシチュエーションがありました。

```
Warning: unable to build chain to self-signed root for signer "iPhone Developer: XXXXXX (XXXXX)"
```

新しいビルドマシンを用意したときに出やすかったので原因を書き留めておこうかと思います。

## 原因

Xcode で署名する際に必要な証明書が足りていない。

具体的には Apple Worldwide Developer Relations Certification Authority (WWDR Certificate) は中間証明書というものがキーチェインアクセスにインポートされていない。

Xcode の「Preference > Accounts」から Apple Developer にリンクした場合に必要な証明書がインストールされるんじゃないかと思いますが、リンクしない端末ではその証明書がインストールされずにという状況で発生しているのではないかと思います。（詳しくは調べていないですが、少なくとも上記の中間証明書がインストールされていなかった）

## 対処方法

[WWDR Certificate ダウンロードリンク](https://www.apple.com/certificateauthority/)から[WWDRCA](https://developer.apple.com/certificationauthority/AppleWWDRCA.cer)と[WWDRCAG3](https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer)をインストールする。

これだけです。

# まとめ

チーム制作の場合、証明書などは共有して Xcode からは Apple に接続することがなかったりするので、意外と見落としがちな部分かと思います。

色々なサイトで同じエラーが出ている方をチラホラ見かけ、証明書の作り直しや Xcode の再インストールや再起動など様々な解決方法が挙がっていましたが、私の環境ではこれで直りました。
【BigQuery】簡単に使える便利なSQLコマンドtips

# はじめに
始めまして、株式会社ジール所属の@sherryuuerです。
現在、GCPの各サービスを使って分析環境の構築に携わっております。
その中で得たノウハウやtipsを、Qiitaを通して発信していきたいと思います。

今回はGCPでよく使われるBigQueryのtipsを共有していきたいと思います。

# テーブルのDDLを出力
テーブルのDDLを出力するためには、INFORMATION_SCHEMAのTABLESを参照することで一括で出力することができます。

SQLは以下になります。

```sql:test.sql
select table_name,ddl from dataset_name.INFORMATION_SCHEMA.TABLES
```
特定のテーブルのDDLを出力するにはテーブルを指定するのも可能です。

```sql:test.sql
select ddl from dataset_name.INFORMATION_SCHEMA.TABLES 
where table_name = 'test_table'
```
※dataset_nameは対象のテーブルが格納されたデータセットです。

# VIEWの情報を確認する
INFORMATION_SCHEMAでビュー定義の情報も確認できます。

たとえばビューtest_tableの定義を確認したい場合のSQLは以下になります。

```sql:test.sql
select * from `dataset_name.INFORMATION_SCHEMA.VIEWS`
where table_name =  'test_table'
```
※dataset_nameは対象のビューが格納されたデータセットで、table_nameはビュー名です。

# 注意点
INFORMATION_SCHEMAはプロジェクトレベルの編集者権限、もしくはBigQuery管理者権限が必要です。BigQueryジョブユーザーでは参照できないです。
Microsoft SCCM連携について

※本投稿は過去に弊社のHatena blog [MKIが解説するServiceNow開発blog](https://mki-blog.hatenablog.com/) に掲載した内容を再編集したものです。
***
ServiceNowにはITSMやITOM、ITBMなど様々な製品がありますが、各製品は構成管理データベース（CMDB）を中心として多種多様な連携が可能となっています。
今回はそんなCMDBの情報をMicrosoft Endpoint Configuration Manager（旧System Center Configuration Manager（SCCM）、以下MECM）から自動でインポートして、CMDBの作成と更新を行う方法についてご紹介したいと思います。

#Service Graph Connector for Microsoft SCCM
ServiceNowではCMDBのCIを作成する手段としてITOM Discoveryという機能が用意されていますが、すでにサードパーティの製品で構成情報を収集する環境が整っているユーザ向けに、サードパーティ製品との連携機能がプラグインとして提供されています。
その中で、MECMとの連携を行うためのプラグインが「Service Graph Connector for Microsoft SCCM」となっています。
このプラグインを導入することで、MECMで管理している構成情報をServiceNowのCMDBにインポートすることができます。また、インポートをスケジュール化することが可能なので、CMDBの自動更新も可能になります。

#導入方法
導入方法は非常に簡単で、プラグインをインストールした後、セットアップのガイダンスに従って以下の2つの画面を設定するだけで設定が完了します。

【設定画面①　SCCMのDBへの接続情報】
![0301.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/02cb7122-3ee2-2080-ed0a-c7172796ea1f.png)

【設定画面②　ジョブのスケジュール設定】
![0302.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/05b44067-c914-a08d-15c6-fb11393a3fc3.png)

#連携イメージ
上記の設定を行った後はスケジュールが実行されるのを待ち、結果を確認するだけです。
まずは、連携されるMECM側のデータを確認してみましょう。

【MECMで管理されているクライアントPCの情報】
![0303.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/28d0a97e-93b2-805e-7a7c-6abe24db4004.png)

次に、これがServiceNowに連携されたかを確認してみましょう。

【ServiceNowのCMDBに連携されたクライアントPCの情報】
![0304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/356482b0-62dd-4c31-bd60-168d6ff533f4.png)

ServiceNowにMECMで管理されているnowcl01というクライアントPCの情報が連携されたことがわかるかと思います。
コンピュータの名称やスペック、シリアルナンバー、ネットワークアダプタ、ストレージ、インストールされているソフトウェア等の情報が連携されていることがわかります。
Microsoft SearchからServiceNowナレッジを検索する

※本投稿は過去に弊社のHatena blog [MKIが解説するServiceNow開発blog](https://mki-blog.hatenablog.com/) に掲載した内容を再編集したものです。
***
今回はMicrosoft製品からServiceNowのナレッジベースを検索する機能を紹介したいと思います。

#Microsoft Search Graph Connector
この機能はBingからServiceNowのナレッジを検索できるようにするための機能です。
今回はMicrosoft365に用意されたインテグレーション用の機能を紹介させていただきます。

この機能は、Microsoft SearchというMicrosoftの検索機能がServiceNowのデータベースに接続し、ナレッジベースをクロールしてインデックスを作成するため、データはあくまでServiceNow側にのみ保存されることになります（データ連携は行われません）。

詳しい手順はMicrosoftのサイトで紹介されていますのでここでは完成イメージを御覧いただきたいと思います。

https://docs.microsoft.com/en-us/microsoftsearch/servicenow-connector

#完成イメージ
下図のようにBingをブラウザで開き、検索ワードを入力して検索します。
（Microsoft365にログイン済の状態です。）
![0201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/c3ccf184-8b9e-e7df-9d3e-7809f3751791.png)
すると、以下のような検索画面に切り替わりますので、「職場」タブの中の「ServiceNow Knowledge」タブを選択すると、ServiceNowのナレッジの検索結果が表示されます。
検索結果のリンクをクリックします。
![0202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/5cad1d31-6297-e44d-31a1-c227e9f342eb.png)
すると、以下のようにServiceNowのナレッジの画面が別タブで表示されました。
![0203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/8497c31b-6391-ae0a-7e75-400876e6df93.png)
レポート作成のちょっとした新機能「Function Field」について

※本投稿は過去に弊社のHatena blog [MKIが解説するServiceNow開発blog](https://mki-blog.hatenablog.com/) に掲載した内容を再編集したものです。
***
みなさんはServiceNowでレポートを作るときにレポートに出力したいフィールドがテーブルに存在せずに困ったことはないでしょうか？ 

たとえば、レポート対象のテーブルに開始日と終了日の日付フィールドがあるとします。レポートには、開始から終了に要した日数を出力したいが、テーブルにはこのフィールドが存在しないため、テーブルにカスタムフィールドを追加した、というような経験はないでしょうか？ 

こんなちょっとした問題に対応するための新機能が少し前のQuebecリリースで追加されていたのでご紹介します。 

#Function Field 
レポートの作成画面にいつのまにか下図の赤枠のような項目が追加されていることにお気づきでしょうか？ 
![0401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/459ffbd6-c7a9-cbf8-f958-e9cfbc51a49b.png)


ボタンを押してみると、下図のようなモーダルウィンドウが開きます。 
![0402.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/7dd349e1-bbbd-629a-76ab-5eb5922326a3.png)

Labelには追加したいフィールドの名前、Return Typeにはそのフィールドに表示する値の型を入力します。 
そして、その値を生成する関数をDefinition欄で定義します。 
定義に際しては以下の2種類の入力補助機能を利用できます。 

- Add Operation 
- Add Field 

前者は下図のように、利用できる関数とそのヘルプが表示されます。（Excelの関数によく似ています） 
![0403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/7933e0ba-95ea-e940-ed78-4dd55ace9a84.png)

後者は関数の引数として使用するフィールドの物理名の入力を補助してくれます。 
![0405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/1390ad18-a0a3-7d55-8e05-12879b664f70.png)
Add Fieldの項目にセレクタが表示されるので選択。
![0406.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/3f167b3a-5d1e-e9ac-f1bc-07abdb634d9e.png)
![0407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/13b61b05-6c54-2f02-d1c7-912d2be016e8.png)

下図は入力補助を使って作成した関数です。 
Actual StartとActual Endの期間を出力する関数です。 
関数を定義しているフィールドの下に「Syntax is correct for this function」と表示されているので、関数が正しく機能することがわかります。 
![0408.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/bcb4350c-b044-9271-56e4-82b082da9cd3.png)

Saveボタンを押して関数を保存したら、作成したフィールドをレポートに表示してみます。 
![0409.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/90d676c7-b8ab-d251-dee3-fd5407caf347.png)

図の赤枠の箇所に関数フィールドを表示しました。二つの日時の差を期間として表示することができました。
IntegrationHubを使ったSharePoint連携について

※本投稿は過去に弊社のHatena blog [MKIが解説するServiceNow開発blog](https://mki-blog.hatenablog.com/) に掲載した内容を再編集したものです。
***
弊社では社内の情報共有ポータルとしてSharePointを利用していますが、システムに関する問い合わせにはServiceNowのインシデント機能を利用しています。
インシデント発生を抑制するための手段としてServiceNowによくある質問をナレッジとして登録しているのですが、この情報をSharePointにも連携したい、という要望があり、連携方法を検証してみたので、ご紹介したいと思います。

#IntegrationHub Microsoft SharePoint Spoke
連携の検証にあたっては、IntegrationHubのspokeを利用しました。

https://docs.servicenow.com/bundle/paris-servicenow-platform/page/administer/integrationhub-store-spokes/concept/sharepoint-online-spoke.html

このスポークには、SharePointのREST APIを操作するための様々なアクションが用意されているのですが、その中の「Create List Item」アクションを利用して、ServiceNowのナレッジ記事が作成されたときに、SharePointのリストに記事を行として追加する処理を作成していきたいと思います。

#連携の設定方法

###SharePointに連携用のアプリケーションを作成
まずはSharePointにServiceNowと連携するためのアプリケーションを作成し、権限の設定を行います。詳しい手順はServiceNowのドキュメントに記載があるのでここでは割愛します。

https://docs.servicenow.com/bundle/paris-servicenow-platform/page/administer/integrationhub-store-spokes/task/conf-sharept-tenant.html

 
###ServiceNowにプラグインをインストール
Microsoft SharePoint Spoke（sn_sp_spoke）というプラグインをインストールします。

###IntegrationHubの接続設定を行います
設定するのは以下のデータです。
######①アプリケーションレジストリ （メニュー 「システムOAuth ＞ アプリケーションレジストリ」）
![0101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/a5ab3723-1bca-c39e-da0b-b292fe0e0c2c.png)
####②テナント （メニュー 「Microsoft SharePoint Online ＞ テナント」）
![0102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/e72b2c01-97ca-7eee-d1d0-f610bd20ffad.png)
#####③資格情報（メニュー 「IntegrationHub ＞ 資格情報」）
![0103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/b59efdf7-74ab-ff72-81eb-eb4673b383d2.png)
#####④トークンを取得する
接続情報が登録できたら、資格情報の画面で「OAuth トークンの取得」関連リンクをクリックしてトークンを取得します。
#####⑤Flow Designerでアクションをカスタマイズ
spokeで提供される「Create List Item」アクションでは、リストアイテムに連携できる項目が限られているので、アクションをコピーしてカスタムアクションを作成します。
![0104.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/c9ab7d7a-ab54-5859-76df-12d2d531e113.png)
ここではナレッジのNumberとDescriptionをアクションのインプットとして追加設定しました。
また、Preprocessing画面でinputの値をREST APIのリクエストに反映させる処理を追記します。（下図の赤枠部分。スクリプトの16、17行目のペイロード部分ではSharePointのリストのカラムのEntityPropertyNameを指定する必要があります）
![0105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/6566d749-1b51-4458-6211-7767a9033b3f.png)
#####⑥ビジネスルール
最後に、ナレッジが作成されたらIntegrationHubのActionを実行するようにビジネスルールを作成しておきます。


#結果
上記のとおり実装した結果、以下のようにServiceNowで登録したナレッジが、SharePointのリストに自動連携されるようになりました。
![0106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/d157f1ca-e10f-56da-5e47-3591fcc46bf8.png)
![0107.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/453e9ad6-2b71-9890-8f82-e59b3f1b7f44.png)
![0108.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297934/4c1d53ee-4d9d-dd5e-b0a7-c0b7af366c15.png)

今回の検証ではリストアイテムの新規作成だけを検証したため、実際の運用を考えると更新や削除のパターンも実装する必要がありますが、連携の雰囲気はつかんでいただけたのではないかと思います。
エレコム ヘッドセット HS-HP23TBKのマイクが認識しない対応方法

![HS-HP23TBK_21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/dc835545-3a6c-e117-be22-f88a9acb77d5.jpeg)

 1. マイクのスイッチを **オフにする**
 ![img-07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/1bb20533-e18c-ddbe-b9de-a7f32e03c492.jpeg)

 2. 4極ジャックに挿す
 3. マイクのスイッチをオンにする

---

前例はいくつかあるようで。
 - http://seaglow.seesaa.net/article/431720797.html
 - https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14163871189
 - https://okwave.jp/qa/q9866384.html
 - http://shimizuk200.blogspot.com/2020/08/blog-post.html

ヘッドホン側は音が出るのでマイクの故障かと思ったほど。あくまで成功例の一つとして。
文字認識をiPhoneで簡単にしたいなら、VisionTextRecognitionで秒

#概要
画像から文字認識をする方法です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/f7f7ff63-06fe-05ff-6d82-bc68a5ac6938.png", width=300>


#伝えたいこと
機械学習を使って文字を認識するのは、Visionのフレームワークで簡単にできます。

#解決したい課題
画像のテキストが難しい手続きなしで、パッと読み取れれば、たとえばOCRアプリなど、いろんなサービスに応用できます。

#解決手法
Visionを使います。
アップルのフレームワークで、機械学習ベースの文字認識が簡単に使えます。

###留意点
ただし、現在のところ日本語はサポートされていません。
>２０２１年　１２月　現在のサポート言語
英語
フランス語
イタリア語
ドイツ語
スペイン語
ポルトガル語
中国語　簡体
中国語　繁体

```swift
let request = VNRecognizeTextRequest()
let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: .right, options: requestOptions)
do {
    try handler.perform([request])
} catch let error {
    print(error)
}
guard let observations = request.results as? [VNTextObservation] else { return }
for observation in observations {
    let box = observation.boundingBox
    let topCandidate = observation.topCandidates(1)
    if let recognizedText = topCandidate.first {
        print(recognizedText.string)
    }
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/b647bf06-049f-39dd-f132-aa55679a5762.jpeg", width=300>
>business
&
We have
people
A VISION
Principle
Education
UNDIVIDED
? ?
We start
1
Z
We hate
WE DONT WORK
WITH
from WHY
digital
Government
Open
knowledge
Not-only-money!
1
POWER
We Love
Open
digital
processi
Teamf
Community
Power
Digital
Honesty with
of
STOMO
idea
transforma-
ourselves
Design
†ion
Skills
2
Creative ir
Digital
2
AS
Passion
Diversity
PRODUCT
development
RESTRICT
-f
opinions
Customer
deseloptrert
Invisible
digital
Punk
WE DON'T
make
and research
useless
2
PRODUCT
Symbies
Concept

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
簡単な開発内容をお書き添えの上、お気軽にご連絡ください。
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)