OmniAICreator/Qiita-1.07M huggingface dataset:
io.BytesIO()にデータフレームで作成したExcelを保存して、openpyxlで列の幅を変更してメールに添付する方法

業務でio.BytesIO()にデータフレームから作成したExcelファイルを保存した後に
openpyxlで列の幅を修正する際につまづいたのでここにメモを残します。

クソコードですが、業務終了後自宅で６時間かけてやっとうまく動いたので許してください;;;;
多分よろしくない書き方しているので動きますけどコピペはやめた方が良いです。ごめんなさい。

```python
from csv import writer
from tkinter import W
import pandas as pd
import io
import openpyxl
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
import smtplib
from os.path import basename
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
import smtplib
from os.path import basename

output = io.BytesIO()
writer = pd.ExcelWriter

df = pd.DataFrame([['2022/03/28','hoge','hige','fuge','fege','foge','0.0'],['2022/03/29','hoge1','hige1','fuge1','fege1','foge1','1.0']]\
    , columns=['DATE', "HOGE", 'HIGE', 'FUGE', 'FEGE', 'FOGE', 'SU-ZI'])

file_name = 'sample.xlsx'
sheet_name = 'sheet1'

# index=Falseにすると不要なインデックスがつかない
df.to_excel(output,index=False,sheet_name=sheet_name)

writer.save
output.seek(0)

wb = openpyxl.load_workbook(output)
ws = wb[sheet_name]

# 列の幅を修正する
for col in ws.columns:
　　max_length = 0
   column = col[0].column
　
　　for cell in col:
       if len(str(cell.value)) > max_length:
           max_length = len(str(cell.value))

       adjusted_width = (max_length + 2) * 1.5
       ws.column_dimensions[col[0].column_letter].width = adjusted_width

wb.save(output)
writer.save
output.seek(0)
 
# SMTP認証情報
account = "接続先のアカウント"
password = "接続先のパスワード"
 
# 送受信先
to_email = "送信先のアドレス"
from_email = "送信元のアドレス"
 
# MIMEの作成
subject = "件名"
message = "本文"
# バイナリデータを添付する場合はMultipart、テキストのみの場合はMIMETextだけで大丈夫です
msg = MIMEMultipart()
msg["Subject"] = subject
msg["To"] = to_email
msg["From"] = from_email
msg.attach(MIMEText(message))

part = MIMEApplication(output.read(),Name=basename(file_name))
 
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(file_name)
msg.attach(part)
 
# メール送信処理
# Gmailでテストする場合
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(account, password)
server.send_message(msg)
server.quit()
writer.close
```
【Gatsby.js】超初心者がインストールからlocalhost:8000に表示させるまで

# 筆者のスペック
* HTML/CSS/jQueryを使った静的サイトしか作ったことない
* ぶっちゃけJavaScriptのこと何もわかっていない
* Reactで静的サイトを作ってみたいけど、無勉強でいきなり始めるのはさすがに無理なので、Reactのフレームワークを使ってみることにした

「Gatsby.jsとは？何がすごいの？」というのはこちらの解説が素晴らしいです。

https://qiita.com/hppRC/items/00739eaf9ae7fc95c1ca


# インストール手順

## Gitが入っているか確認

```
$ git --version
```

入っていれば`git version 2.20.1 (Apple Git-117)` のように表示される。

WindowsでGitが入っていない方は下記を参考にインストール
https://www.sejuku.net/blog/73444

## Node.js が入っているか確認

```
$ node -v 
```

ここで　`v16.14.2` など、Node.jsのバージョンが表示されれば既にインストールされているので、そのまま次に進んでOK！

バージョンが表示されない場合は、Node.jsがインストールされていないので、下記サイトからダウンロード↓

https://nodejs.org/ja/

:::note warn
v16.14.2(推奨版)をダウンロードしてください
:::


## nのインストール

```
$ npm install -g n
```

Node.jsをダウングレード / アップグレードしたり、使用可能なバージョンを表示したりする時にあると便利なのでインストールしておく。

## 【重要】 Node.jsのバージョンを推奨版と同じものにする

次項でGatsby.jsをインストール、サイト作成をしていくのですが、
サイト作成時、Node.jsのバージョンが古すぎる or 新しすぎると次のようなエラーが出ます。


#### バージョンが古すぎる場合
```
 ERROR 

Gatsby requires Node.js 14.15.0 or higher (you have v14.0.0).
Upgrade Node to the latest stable release: https://gatsby.dev/upgrading-node-js
```

#### バージョンが新しすぎる場合
```
 ERROR 

Command failed with exit code 1: npm install
```

前項でv16.14.2(推奨版)をダウンロードしていれば、このような問題は起きないかと思いますが、
後々エラーになってしまうと時間がかかってしまうので、とりあえず以下叩いておくことをお勧めします。


```
$ sudo n stable
Password:
~
~
~
cp: /usr/local/include/node/cppgc/common.h: Permission denied
installed : v16.14.2 (with npm 6.14.8)
```

これでNode.jsのバージョンが推奨のバージョンに変わります。

パスワードを入力後、だら〜っといろいろ流れますが、最後にNode.jsのバージョンが表示されればOKです。

このとき、nをインストールしていないと「nなんてコマンドはないが？」と言われます…。


## Gatsby.jsをインストール

```
$ npm install --global gatsby-cli
```

## Gatsby.jsでサイトを作成

```
$ gatsby my-gatsby-project demo https://github.com/LekoArts/gatsby-starter-portfolio-cara.git
```

このコマンドを叩くと、今いる階層に`my-gatsby-project`というGatsby.js専用フォルダが作成されます。
名前はなんでも大丈夫です(後から変えられます)

```
Your new Gatsby site has been successfully bootstrapped. Start developing it by running:

  cd my-gatsby-project
  gatsby develop

```


上のような表示が出れば成功です！！:tada:

指示通り`my-gatsby-project`で`gatsby develop`を実行してみます。

```
$ cd my-gatsby-project
$ gatsby develop
```

数十秒後、次のような表示が出たらビルド成功です。

```
success Building development bundle - 11.257s
success Writing page-data.json files to public directory - 0.066s - 3/8 120.75/s
```

http://localhost:8000 にアクセスしてみてください。

こんなページが表示されているかと思います。

![スクリーンショット 2022-03-28 23.31.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355320/434914d0-7b7f-072e-6d87-b92c5b08da15.png)


お疲れ様でした！

:::note warn
localhostが表示されない場合
http:// ではなく https:// になっていると表示されないので要注意です。
:::


# 参考にさせていただいたサイト様 :bow:

* [デザイナーがReactでイケてるWebサイトを 「簡単に」 作る方法](https://note.com/ryoster/n/n08901cf23825)
* [[Gatsby.js]Error: Command failed with exit code 1: npm install -りーほーブログ](https://omkz.net/error-gatsbyjs-install/)
*  [nコマンドを使用してnode.jsをバージョンアップする](https://yucatio.hatenablog.com/entry/2019/12/06/081900)
【HTML】　メタデータコンテンツ要素についてその１~baseタグ編~

## ＜base＞
base要素は、ドキュメントにおける全ての相対URLの基準となるURLと、リンク先ドキュメントの開き方を指定する要素。


|  |  |
|:-:|:-:|
| 場所  | head要素内で１つだけ使用できる。  |
| コンテンツモデル  | 空  |
| 属性  | グローバル属性。href属性、 target属性。  |
| ブラウザ対応  | Internet Explorer、Google Chrome、Safari、Firefox、Opera  |

:::note info
base要素には、href属性か、target属性の、どちらか１つの属性を指定するか、両方の属性を指定するかする必要がある。

* href属性の値
基準となるURLを指定する

| 属性値 | 説明 |
|:-:|:-:|
| URL  | http:// から始まる絶対URLで指定  |

* target属性の値
リンク先の表示方法を指定する

| 属性値 | 説明 |
|:-:|:-:|
| _blank  | 新規のウィンドウに表示  |
| _self  | 現在のウィンドウ（フレーム）に表示  |
| _parent  | 親ウィンドウ（フレーム）に表示  |
| _top  | フレームを解除してウィンドウ全体に表示  |
| ウィンドウ名、フレーム名  | 任意のウィンドウ（フレーム）に表示  |
:::

:::note warn
* base要素のhref属性で指定したURLがそのHTMLの基準URLとなるため、link要素などURI指定が必要な要素はbase要素の後に記述する必要がある。
* head要素内に一つだけ指定できる。
:::

## サンプルコード
~~~html
<!DOCTYPE html>
<html lang="ja">
 <head>
  <base href="URL" target="_blank">
  <title>ドキュメントのタイトル</title>
 </head>
 <body>
　　ドキュメントの内容
 </body>
</html>
~~~

## 参考サイト

https://web.havincoffee.com/html/tag/base/

http://html5.cyberlab.info/elements/metadata/base.html

https://www.tagindex.com/html5/page/base.html
配信プログラムWebサーバー

入社してからいろんなサーバーに出会って、どれがどんな役割だか一度整理するための自分メモ。
今日はWebサーバー。

ネットワーク上でデータを提供している側をサーバー、データを利用している側をクライアントと呼ぶらしい。
なのでWebサーバーもデータを提供する側。

# 配信プログラム　Webサーバー
WebサーバーはWebブラウザからコンテンツの要求があると、必要なコンテンツをネットワークを通してWebブラウザに送る役割を持っている。コンテンツはWebサーバーによって配信されることでWebページと呼ばれるようになる。
要求されたコンテンツを持っていないときは「持っていない」というメッセージを返したり、別のサーバーに要求するように案内することもある。
よく名前を聞くWebサーバーは、Apache（アパッチ）、Nginx（エンジンエックス）。

# WebブラウザとWebサーバーのやりとりはHTTP
Webページが表示されるには
①Webブラウザから「○✖️というコンテンツをください」と要求。
②Webサーバーから「○✖️だよ」と○✖️コンテンツを送信。
　持っていない場合は、「○✖️は持っていないよ」とメッセージを送信。

というやりとりが行われる。
要求を送ってからコンテンツを受け取るまでの一連のやりとりは、**HTTP**というプロトコル(ルール)としてメッセージの送り方や書式まで細かく決められている。

# プロトコルは世界共通
WebブラウザやWebサーバーには様々な種類があるが、HTTPという共通ルールがあるのでどれを使ってもやりとりすることができる。

# 参考
* [イラスト図解式 この一冊で全部わかるWeb技術の基本](https://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E5%9B%B3%E8%A7%A3%E5%BC%8F-%E3%81%93%E3%81%AE%E4%B8%80%E5%86%8A%E3%81%A7%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8BWeb%E6%8A%80%E8%A1%93%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%B0%8F%E6%9E%97-%E6%81%AD%E5%B9%B3/dp/4797388811/ref=asc_df_4797388811/?tag=jpgo-22&linkCode=df0&hvadid=295704876452&hvpos=&hvnetw=g&hvrand=15357321002661338070&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009210&hvtargid=pla-526274317363&psc=1&th=1&psc=1)

Webサーバーは、Webブラウザから要求されたページを、HTTPに従って送信する。
ブラウザはそれを受け取って表示する。
ブラウザはサーバーから送られてきたデータを利用して表示しているのでクライアント。
最初聞いたときは、ブラウザをクライアントというのに違和感があった。
【 Java_while文とdo-while文 】

現在独学でJavaを学習中です。
この投稿はその備忘録になります。

## while文とdo-while文
Javaにおけるwhile文とは、繰り返し構文を書く際のバリエーションのひとつです。
条件式の内容に従って必要数処理を繰り返します。
また、do-while文とは「まず評価してから条件式を実行する」もので、
while文とは書く順番が異なります。

#### ■ while文
以下のwhile文では、ブロックを実行する前に`条件式(temp > 25)`を評価します。
これを、`前置判定`といいます。
```java
public class App{
 public static void main(String[] args){
  int temp = 30;
  while (temp > 25) {
   temp--;
   System.out.println("温度を一度下げました");
  }
 }
}
```
#### ■do-while文
以下のdo-while文では、ブロックを実行した後に`条件式(temp > 25)`を評価します。
これを、`後置判定`といいます。
```java
public class App{
 public static void main(String[] args){
  int temp = 30;
  do {
   temp--;
   System.out.println("温度を一度下げました");
  }while(temp > 25);
 }
}
```

## while文とdo-while文の違い
・条件式を評価するタイミングが、ブロックを実行する前か後かという違い
↪︎前置判定・後置判定
・ループの最低回数の違い
↪︎do-while文では最低1回はブロックを実行します。




以上になります。
100日でSQLの達人になる@LeetCode! Day50 <CREATE TABLE テーブル名, 変数型のまとめ>

## テーブルを作成する
前回に引き続き[LeetCode](https://leetcode.com/)の問題はお休み。

[db<>fiddle](https://dbfiddle.uk/?rdbms=sqlserver_2019)を使って、何も無いところからテーブルを作成するクエリを書いていきます。
```:SQL
CREATE TABLE テーブル名 (変数名1 変数型 オプション, 変数名2 変数型 オプション)
```
これが基本形。変数は1つ以上指定しないと駄目な様子。オプションは省略可。
このクエリを実行するとテーブル名で指定した名前の空のテーブルが作成できます。

変数型には、下記のものが指定できます。
|データタイプ|クエリ|説明|
|-|-|-|
|整数|BIT|1または0の整数|
|整数|TINYINT|1Byte(8bit)までの整数つまり0-255|
|整数|SMALLINT|2Byteまでの整数|
|整数|INT|4Byteまでの整数。通常はこれで良さそう|
|整数|BIGINT|8Byteまでの整数|
|少数|DECIMAL[(p,s)]|[]は省略可。pが整数と少数を合わせた有効桁数、sが小数部桁数|
|少数|NUMERIC[(p,s)]|DECIMALと全く同じ|
|少数|FLOAT[(n)]|[]は省略可。浮動小数点型|
|少数|REAL|4Byteの浮動小数点型|
|文字列|NCHAR[(n)]|n桁の固定長のUnicode文字列|
|文字列|NVARCHAR(n or MAX)|n桁の可変長のUnicod文字列、MAXの場合は2GBまで|
|文字列|CHAR[(n)]|n桁の固定長の文字列|
|文字列|VARCHAR[(n or MAX)]|n桁の可変長の文字列、MAXの場合は2GBまで|
|日付|DATE|日付のみ|
|日付|TIME|時刻のみ|
|日付|DATETIME2|日付と時刻を表示|

オプションは省略できますが、下記のものが指定できます。
|クエリ|説明|
|-|-|
|NOT NULL|NULLを禁止|
|IDENTITY(開始番号, 増加数)|数値が開始番号から増加数ずつ増えて連番で入力される|
|AUTO_INCREMENT|（これはMS SQL Serverでは使用できない）数値が連番で入力される|
|DEFAULT|`DEFAULT 0`のように使用しDEFAULTの後のものが初期値になる|
|PRIMARY KEY|主キーの設定。同時にNOT NULLの設定も必要になる|
|UNIQUE|重複禁止。NULLはOK|

`PRIMARY KEY`を設定するとインデックスが自動的に作成されて、テーブル検索の速度も早くなります。

今日のポイントは`CREATE TABLEでテーブルを作成する`とした。
モノレポのリポジトリ内のフロントエンドプロジェクトにhuskyの設定を追加する


npmパッケージのhuskyが`v5系`以降の使い方がそれまでと異なっています。

モノレポのリポジトリ内の中でフロントエンド用のプロジェクト(vue-cliやcreate-react-appなど)にのみ`husky`の設定を適用し`lint-staged`を実行する方法をまとめます。

| 名前 | バージョン |
| :--- | :---: |
| npm | 8.1.0 |
| node | 16.13.0 |
| yarn | 1.22.17 |
| TypeScript | 4.4.4 |


## ディレクトリ構成

```text
root/
　├ backendProject/
　└ frontendProject/
```

`frontendProject`=`vue-cliやviteなどで作成したフロントエンドのプロジェクト`(package.jsonが置かれている。)


# husky,lint-stagedのインストール

`frontendProject`ディレクトリ内でhusky,lint-stagedのインストールを行います。

```Shell-session
$ yarn add --dev husky lint-staged
```

package.jsonの`srcripts`に`prepare`が追記されている為モノレポ用の設定として下記の通り修正します。

ダブルクォーテーションをエスケープしている箇所に注意してください。


```json
  "scripts": {
    ...(省略)
    "prepare": "cd .. && husky install frontendProject/.husky",
    "create-precommit": "cd .. && husky add frontendProject/.husky/pre-commit \"cd frontendProject && yarn lint-staged\"",
    "lint-staged": "lint-staged"
  },
```

`frontendProjectディレクトリ内`に`.huskyディレクトリ`を作成する為に`yarn prepare`と`yarn create-precommit`をそれぞれ実行します。

```shell
$ yarn prepare
$ yarn create-precommit
```

`frontendProject/.husky`ディレクトリ内の`pre-commit`ファイルが下記の様な内容で作成されます。
これでコミットをする直前にhusky経由で`lint-staged`を実行する事が出来ます。

`lint-staged`の設定はこれまで通り`package.json`に記載して差し支えありません。

```shell
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

cd frontendProject && yarn lint-staged

```

# nvmを利用している際の注意点

ローカルのnode.jsのバージョン管理に`nvm`を利用している場合、huskyが動く際に現在設定されているnodeのバージョンを取得出来ない場合があります。(husky経由でyarnコマンドが実行出来なくなる)

この場合、自分のホームディレクトリに`~/.huskyrc`を作成してnvmの設定を追記する必要があります。

```Shell
$ touch ~/.huskyrc
$ vim ~/.huskyrc
```

```Shell
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# 現在利用しているnodeバージョンをuseする
nvm use stable
```

これでhusky利用時にローカル環境と同様のnode.jsのバージョンを利用する事が出来ます。
Tailwind CSS のカスタマイズのオススメ

はじめに
---
こんにちは、スタートアップでフロントエンドエンジニアをしているひろです:robot:。

今回はフロントエンドの開発でよく使われている　Tailwind CSS について自分がよくするカスタマイズをまとめてみました。
なにかの参考にして頂けたら幸いです。
（久しぶりの投稿なので優しい目で見てもらえたら幸いです〜！！:bow_tone1::bow_tone1::bow_tone1:）


# 目次
1.カラーパレットの追加
2.コンテンツの高さ、幅の指定したい時
3.クラスのまとめ、設定
4.プラグインの設定と個人的によく使うもの

# 1. カラーパレットの追加
プロジェクトによってスタイルガイドやデザインなどにあるベースカラーとなるものを指定する時は、
下記のように`tailwind.config.js` に追加したいカラーコードなどを追加します。

```js:tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        navy: {
          50: '#EFF6FF',
          100: '#D5DFF0',
          200: '#B4C8EA',
        },
        yellow: '#EAAC2F',
      }
    },
  }
}
```

追加したカラーコードは下記のように背景色、テキストカラーなどを指定するときに使用できます。

```html:html
<div class="bg-navy-100">
  <p class="text-yellow">yellow text</p>
</div>
```
# 2. コンテンツの高さ、幅の指定したい時
ヘッダーやナビゲーションを固定値にして表示させたいときなどに使用します
こちらも`tailwind.config.js` に指定したいサイズで`height`や`width`に追加します。


```js:tailwind.config.js
module.exports = {
  theme: {
    extend: {
      height: {
        'header': '4rem'
        'main': 'calc(100vh - 4rem)'
      },
      width: {
        'side': '8rem'
        'main': 'calc(100vw - 8rem)'
      }
    },
  }
}
```

```html:html
   <div class="h-header"></div>
   <div class="h-main">
     <div class="w-side"></div>
     <div class="w-main"></div>
   </div>
```
# 3. クラスのまとめ、設定
よく使うボタンや外部ライブラリーで追加したものにスタイルを追加したい時などに使用します。（下記は[react-mentions](https://github.com/signavio/react-mentions)をカスタムした際の一部です。）
@applyでtailwindのクラスをまとめて使うことができます。

```css:button.css
@layer base {
  .btn-default {
    @apply inline-flex items-center px-4 py-2 text-base font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50;
  }
  .btn-primary {
    @apply inline-flex items-center px-4 py-2 text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700;
  }
}
```

```css:mention.css
@layer base {
  .mentions {
    @apply my-1 mx-0;
  }

  .mentions__mention {
    @apply text-sm text-navy-800 bg-navy-800 underline rounded border-2 border-navy-800;
  }

}
```

```html:html
   <button class="btn-default">btn-default</button>
   <button class="btn-primary">btn-primary</button>
```

# 4. プラグインの設定と個人的によく使うもの
プラグインの設定では下記のようにpluginsに設定します。


```js:tailwind.config.js
module.exports = {
  plugins: [
    require('@tailwindcss/line-clamp'),
  ],
}
```

```html:html
<p className="line-clamp-3 w-20 texy-base">
  1行目 テキストテキストテキスト
  2行目 テキストテキストテキスト
  3行目 テキストテキストテキスト
  4行目 テキストテキストテキスト
</p>
```

#### 実際の表示のキャプチャー
![スクリーンショット 2022-03-28 23.07.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361164/80843bb1-561e-a6e7-c3fd-0893d3574920.png)
プラグインが適用されて三行目で3点リーダーになっています。


### 個人的によく使うプラグイン

#### フォーム
  https://github.com/tailwindlabs/tailwindcss-forms

#### 三点リーダー

https://github.com/tailwindlabs/tailwindcss-line-clamp

#### リント

https://github.com/francoismassart/eslint-plugin-tailwindcss

# 最後に
以上です。最後まで読んでいただきありがとうございます。
不明点や間違っている点があればコメントでおしらせください。
Power BI Desktop の"リボン"についてクイックに紹介


# 概要

こんにちは。
本シリーズでは、Power BI を始めたばかりの方が "はじめの一歩" を踏み出すために使えそうな情報を集めて発信しています。本記事では、Power BI Desktop のリボンのうち、よく使う機能だけピックアップして紹介します。
(Power BI Desktop のダウンロードと、画面内その他の機能については[こちら](https://qiita.com/Minori_Tanaka/items/c8ddd5053c404ef47422))

### リボン

Power BI Desktop のリボンは Excel ライクな見た目で作られているので直感的に操作しやすいと思います。それぞれのリボンについて、よく使う機能をピックアップしていきます

#### ホーム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/f2dad3c8-8872-cf94-6a2d-4b7a36e7eb40.png)

データに関する設定や、挿入/計算などの機能、クラウド上へのアップロードを行う機能などがあります。

- [データを取得]
    - ローカルやクラウドにある新しいデータへの接続を行います。
- [データの変換]
    - データの ETL 作業をしたいときはこちらから行う。このボタンを押すと、Power Query エディターという別画面が立ち上がります。
- [発行]
    - Power BI Service (クラウド上の共有基盤) にレポートをアップロードします。

#### 挿入

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/bc16f954-68a6-5ecb-d69f-cafda10a6c0c.png)

ページ追加やビジュアル追加などの機能があります。
- [テキストボックス]・[ボタン]
    - グラフの横にテキストを挿入したり、画面遷移のボタンを追加します。


#### モデリング

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/a5013931-245f-dc2d-9b19-fd97fe184fb9.png)
新しい列やメジャーの追加、ロールの管理などデータに関するモデリング機能があります。

- [ロールの管理]
    - 行レベルセキュリティ (RLS) の設定のために頻繁に使います。この機能により、ユーザーIDレベルでデータのフィルタリングができます。RLSについては別記事で今度まとめます。



#### 表示

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/e7cc342b-ba10-a930-7030-a59625f87056.png)

レポートの表示に関する設定を行います。

- [テーマ]
    - PowerPoint のように、レポート全体のテーマを変更行うことができます。また、レポートテーマの作成も可能なので会社カラーなどでのテーマも作れます。
- [モバイルレイアウト]
    - Power BI モバイル用に縦長のレポートレイアウトを作成します。これを設定すると、モバイル上でも縦画面でレポートを見れるようになります。

#### ヘルプ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/9bc85577-169c-1e7a-029c-713d8959243f.png)

Power BI Desktopの活用を助ける機能があります。
- [バージョン情報]
    - 使っているPower BI Desktopのバージョンなどの情報が見れます。サポートに問い合わせる際はこちらからバージョンの確認を求められることがあります。

#### 列ツール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/9137e5a6-cafa-35a3-e2f4-006faa13db91.png)

列ツールは、フィールドペインで特定の列を選択すると出現します。選択した列に関して、
- 型
- ％表示
- カンマ区切り
- 有効数字
- データカテゴリ

などを設定することで、データごとの見せ方をカスタマイズします。

# おわりに
Power BI Desktopのリボンには、想像以上にたくさんの機能が隠れています。
普段使わない機能を探してみると、より表現豊かなレポート開発ができるかもしれませんね。
それでは！
【chrome拡張機能】teratailで不快なユーザをブロックする拡張機能を開発

# はじめに
はじめまして！
ジョージと申します。
最近teratailを使い始めたのですが、意味のない質問を連投しているすごく鬱陶しいユーザがいて不快な気持ちになりました。しかし、teratailには標準のブロック機能がないため、不快なユーザの質問を非表示にする事が出来ませんでした。
そこでchrome拡張機能で以下のような物を開発しました。
- teratailのユーザをブロック出来る
- ブロックしたユーザの質問は非表示にされる

# 実際の使用画面デモ
![VID_20220412_002459_.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606854/60b5bb10-4029-3379-79a0-341ad9aa696d.gif)

# 使用するための手順
## chrome拡張機能のURL
https://chrome.google.com/webstore/detail/teratail%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF/aalicgledpofcbebhlfcakknpgmhhaen
## 本拡張機能の使い方
1. [teratail](https://teratail.com/)に移動し拡張機能をクリックする
2. ブロックしたい~~ユーザの名前~~を入力し、追加ボタンを押す
**2022/4/12追記**
ブロックしたいユーザの名前ではなく、以下画像のようなブロックしたいユーザのプロフィールのurlの最後を入力してください。
![スクリーンショット (394).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606854/8fb284ba-8abb-782c-dae7-7db64d3b76c7.png)

![スクリーンショット (400).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606854/b3a36451-54a9-ef84-1a05-686d743f845b.png)

3.ブラウザをリロードするとブロックしたユーザの質問が非表示になる
↓ブロック前
![スクリーンショット (396).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606854/49e22349-1a18-e647-3bfd-5c8c322c111a.png)

↓ブロック後
![スクリーンショット (401).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606854/23e1d7d1-6c96-8c65-b199-61b9157f8fe2.png)





# 非表示になっているか確認方法
検証ツールのコンソールに質問が非表示にされたログが出るようになっている。
![スクリーンショット (383)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606854/ab916da4-34e6-0011-2b92-d6a90e2318f8.jpeg)

# はじめて使った機能
- ChromeのStorageApi
- MutationObserver
## ChromeのStorageApi
ブロックしたユーザの管理に使いました
[こちらの記事を参考にしました](https://qiita.com/dhun/items/cf18e43cb0376fcff302)
## MutationObserver
ブロックしたユーザの質問のDOMの取得、非表示を行うタイミングをMutationObserverで指定しています。

当初はwindow.onloadごとにDOMの取得、非表示を行おうとしましたが、teratailがspaのため、画面遷移時にロードしないのでMutationObserverを使いました。
[こちらの記事を参考にしました](https://qiita.com/munieru_jp/items/a6f1433652124a2165e4)

# 使用技術
- JavaScript

# 各主要機能の説明

# 今後していきたいこと
- ブロックリストから個別のユーザを削除できるようにしたい
- UIをもうちょっとまともにしたい
- 現在のコードは汚いのでリファクタリングしたい

# おわりに
最後までご覧いただきありがとうございました！！

# 追記
- 2022/3/29
    - ユーザを追加できないバグを修正いたしました。
- 2022/4/3
    - ブロックリストから個別のユーザを削除できるようになりました。
    - ユーザ名を変更したユーザの質問が非表示にされないバグを修正
- 2022/4/28
    - chromeウェブストアに公開されました。
【Java】自作アプリを改良して業務効率化を図り、いつもより3分早く帰る。

こんばんは。

タイトルの通り、夜中に一人でパチパチとアプリを改造しました。

Atcoderに取り組むことで、Javaのライブラリやクラスの呼び出し方に少し慣れてきました。
便利なライブラリがいっぱいでほんとすごいですね。
自分のペースではありますが、研究していきます。

今回は、前からやってみたかったコピー機能を導入しました。

### １．対象アプリ

消費税計算アプリ「消費税さん」です。

金額を入力すると税込み金額、または税抜き金額を計算してくれるシンプルかつ実用的な優良アプリです。
もし使いたい方がいらっしゃったら、自分のパソコンを持参してインストールさせていただきますのでご連絡ください。

<img width="200" alt="Screenshot_20220328-230056.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/8880db41-5efb-973d-5935-d22d0515174d.png">

最初はアプリ開発の練習のつもりで開発したこの消費税さんですが、実務に契約業務でめちゃくちゃ使用しています。
システム屋さん、特にユーザー系ＳＩの方々であれば、パートナー社の契約業務で電卓をたたくことは結構多いのではないでしょうか。
社内の事情で今年度は契約の回数が増えたため、社内の予算をしっかり使い切るよう（余剰分はしっかり返却する）、税込み金額をきちんと計算して間違いのない契約作業が必要になっています。

消費税さんは画面に計算結果を表示してくれますが、この金額を更に他の計算で使用します。
そのため電卓アプリを開いて数字を転記し、他の月の予算と集計したり、他契約分を減算したり、といった作業をしています。
これが結構不便でして、数字を覚えて打ち込まないといけません。ミスが多発する危険があるので、何回か確かめて入力しており割とストレスになっています。

そこで、今回は表示された結果をクリップボードにコピーする機能を作る事にしました。


### ２．実装方法

使ったライブラリは、Clipdataです。
出典：https://developer.android.com/reference/android/content/ClipData
あとはこちらのブログの実装例を参考に（ほぼ踏襲）させていただきました。ありがとうございます。
https://logical-studio.com/develop/development/android_app_beginner/20161215-android_clipboard_copy/

消費税さんのメインのJavaプログラムは、ざっくり以下の流れになっています。
①あいさつ

②金額を入力し、「消費税さん、教えて」ボタンを押下（税抜き金額を出したい場合は、トグルスイッチをONに）

③結果表示

④結果をプリファレンスに設定（次回の画面で表示されるようにしている）

このうち、③のロジックが終了した直後に以下を追加しました。

```java
textView.setText("税込み金額は、" + tax_disp2 + "円だよ。\n（税抜：" + textint + "円　税額：" + (tax_disp2-textint) + "円）" );

//2022/03/28 クリップボードに格納するItemを作成 from
ClipData.Item item = new ClipData.Item(String.valueOf(tax_disp2));
//A.MIMETYPEの作成
String[] mimeType = new String[1];
mimeType[0] = ClipDescription.MIMETYPE_TEXT_URILIST;
//B.クリップボードに格納するClipDataオブジェクトの作成
ClipData kekka = new ClipData(new ClipDescription("text_data", mimeType), item);
//C.クリップボードにデータを格納
ClipboardManager kaku = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
kaku.setPrimaryClip(kekka);
//2022/03/28 クリップボードに格納するItemを作成 to

String tax_disp3 = String.valueOf(tax_disp2);

```

それぞれこんな処理をしています（理解がふんわりしていますが）
先頭：itemに値を設定します。「tax_disp2」というのがコピーしたい計算結果です。
A.MIMEタイプのURIを保持する新しいClipDataを作成します。
B.Clipdataオブジェクトを生成します。ここでは、kekkaという名前でオブジェクトを生成しました。
C.生成したオブジェクトをインスタンス化し、クリップボードにデータを格納します。

なお、ライブラリは以下が必要です（AndroidstudioのAlt+Enterの機能で補足してくれます）。

```java
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
```

### ３．テスト

計算結果（5500）が、電卓にコピペで転記できた(^▽^)/

<img width="300" alt="Screenshot_20220328-230102.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/6e6f6a4b-3c8b-e243-f226-f1e08859b557.png">

<img width="300" alt="Screenshot_20220328-230115.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/d4d279fd-15dc-46a5-23bd-11d6655f00f9.png">

### ４．最後に

一時間程度でできました。

これで明日は3分くらい早く帰れるでしょう。
契約は毎月1，2日が作業ピークなので、1年くらい使えば修正に使用した1時間分の元が取れそうですね。

ちょっとした改善で大きな効果が出るのは気持ちいいですね。
nvm を使って Node.jsを Raspberry Pi にインストール

## はじめに
[新型コロナウイルス接触確認アプリ(COCOA)がインストールされているスマホを数える](https://qiita.com/SamAkada/items/628742941770970c7642)の記事で、紹介した方法では、Node.jsを任意のバージョンに切り替えることができなかったので、方法を調べました。
nvm (Node Version Manager)を使うことで、任意のバージョンをインストールして、バージョンを切り替えて使うことができます。


## nvm (Node Version Manager)のインストール
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
```
```
=> Downloading nvm as script to '/home/pi/.nvm'

=> Appending nvm source string to /home/pi/.bashrc
=> Appending bash_completion source string to /home/pi/.bashrc
=> Close and reopen your terminal to start using nvm or run the following to use it now:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
```
環境変数を反映します。
```bash
source ~/.bashrc
```
## node.jsのインストール可能なバージョン一覧
```bash
nvm ls-remote
        v0.1.14
        v0.1.15
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       v16.14.1   (LTS: Gallium)
->     v16.14.2   (Latest LTS: Gallium)
        v17.0.0
        v17.0.1
        v17.1.0
        v17.2.0
        v17.3.0
        v17.3.1
        v17.4.0
        v17.5.0
        v17.6.0
        v17.7.0
        v17.7.1
        v17.7.2
        v17.8.0
```

## node.jsのバージョン指定のインストール
### Raspberry Pi 2/3/4(ARMv7/8)の場合
```bash
nvm install バージョン
例
nvm install 14.19.1
nvm install 16.14.2
nvm install 17
```

### Raspberry Pi 1/ZERO(ARMv6)の場合
ARMv6のバイナリファイルがないため、unofficialからダウンロードして、最新版のバージョン16 LTSをインストールします。
NVM_NODEJS_ORG_MIRRORを設定しない場合は、ソースコードからビルドするので、非常に時間がかかります。
```bash
NVM_NODEJS_ORG_MIRROR=https://unofficial-builds.nodejs.org/download/release nvm install 16.14.2
```

## node.jsのバージョン切替
```bash
nvm use バージョン
例
nvm use 16.14.1
nvm use 14.19.2
```

## 参考
[nvm instal from unofficial-builds nodejs](https://gist.github.com/dotenorio/474f26e4048764e9f082cdc5fbcb5581)
jest + eslintでVS Codeが describe を見つけてくれない

# 概要
Node.jsアプリを開発する際にjest + eslintをインストールしてテストケースを書くと、VS Codeが以下の警告を出すが、言う通りにしても解決しない。

毎回対処方法を忘れてしまうので備忘録としてメモ。

```
名前 'describe' が見つかりません。テスト ランナーの型定義をインストールする必要がありますか? `npm i --save-dev @types/jest` または `npm i --save-dev @types/mocha` をお試しください。
```

# 対処方法
.eslintrc.js 等に
```javascript
module.exports = {
  ...
  env: {
    'jest/globals': true // 追加
  },
  ...
```
[vue.js]０から学習して、２週間で実践できるまでやりきる

[vue.js]０から学習して、２週間で理解できるようにする

１.Vueを使って、名前、年齢、画像、年齢＋５、ランダム数字を表示させる


~~~js
const app = vue.createApp({
  date() {
    return {
      name: 'Taturo',
      age: 32,
      imageurl:'ja.wikipedia.org/wiki/%E3%83%95%E3%82%A7%E3%83%AB%E3%83%8A%E3%83%B3%E3%83%89%E3%83%BB%E3%82%BF%E3%83%86%E3%82%A3%E3%82%B9%E3%83%BB%E3%82%B8%E3%83%A5%E3%83%8B%E3%82%A2'
  },
  methods: {
    calculateAge() {
      return this.age + 5;
    },
    calculateRandom() {
      return Math.random();
    },
  } 
});
~~~


修正後

~~~js
data() {
    return {
      name: 'Taturo',
      age: 32,
      imageurl:''https://mail-attachment.googleusercontent.com/attachment/u/0/?ui=2&ik=559b00bc9c&attid=0.1&permmsgid=msg-f:1712463901104320482&th=17c3e4d85400afe2&view=att&disp=safe&saddbat=ANGjdJ9G7LexWukUMNxg3tr74HhdxKjsuR4HnhhZ6WssQGkZggQrwsKBm_dwwkd3nayJHuHUMk7cbtaOgq1dDRVVffUipsBbnikbtbzKpsiteHBUp6CEzEIn5_7eYGYKMGTMB8tt3iZ2c8TlWYrHcgtBv5yDddkDNBuvoC6h8-ylCuL1C5dD-0fbVPK3TIWbNGyffTodZsZGjgyarG27Fa9mxUxtHV45ZOQiGqdVO4Ggbbctv7gGjMrCoYBFpXhV0bOsyOHKVYnn3kSYHG59x7hq3AosONzYvgSAcVBJYrFBBWhLoRneg6wVlAETWcXvgMzSh6ZFzdIL1SQRzcvQUXtvXC6kbICsKg6g_C9dAMvXMctN8MI59AHoZbUjBNBRQ6ETfAqrNrnXoDBBYpLsgoSjC41C7p2xZ6bz8prGgA-Y1XAlutU9Cgopp4SVAl0YJQR3l3hrlmkhshGWdxoIhEQAX654_QUJYKU4Vm4906B7GtAvfEmTmfagNYl2XR3a1NJugXvhbjmd1XAyVdsFse2_nBojWsBIjJrX6CxHkf89pFyXA1GW-ApcwNI8oKEBd8R9-''
  },
  methods: {
    calculateAge() {
      return this.age + 5;
    },
    calculateRandom() {
      return Math.random();
    },
  } 
});
~~~


１.スペルミス
dateをdataに修正
2.画像のURL
wikiだったため、画像のURLに修正したところ表示できた
Railsでアプリ作成時に、使用可能なバージョンを確認する方法

# 結論

ターミナルで以下を入力

```
% gem list rails 
```
これで使用可能なバージョンが表示されます

```
*** LOCAL GEMS ***

rails (5.0.1, 4.2.6, 4.2.5, 4.1.6)
```

## ちなみに
バージョンを指定してアプリを立ち上げる場合
```
rails _5.0.1._ new アプリ名
```
これで指定のバージョンでアプリを作成できます。

以上です
SQLの備忘録


# SQL備忘録


|機能|コマンド|
|:---|:---|
|起動|net start mysql57|
|終了|net stop mysql57|
|ログイン|mysql --user=root --password|
|ログアウト|exit|
|sqlファイルの実行|source *filename*.sql|
|ユーザ名とホスト名の取得|SELECT USER();|
|サーバの変数確認|SHOW VARIABLES;|
|情報の確認|\s|
RxSwift, RxCocoaのワードをざっくりと理解する

## 初めに
今回はRxSwiftを学習するにあたって出てくるてあろうワードについて簡単にですがまとめてみました。
ざっくりとても理解してもらうことを目的にしています。



## RxSwift, RxCocoa 共通

### event: 
enumで定義されている, Streamに流れるイベント,値、 中には　onNext, onError, onCompletedがある
```swift
enum Event<Element>  {
    case next(Element)      // next element of a sequence
    case error(Swift.Error) // sequence failed with error
    case completed          // sequence terminated successfully
}
```

`Observable:` 実行者, observerにイベントの発行を通知する,　event を受け取れる
`Observer:` Observableからデータストリームを受け取るクラス,　event を流せる

### Subject: 
Observer, Observableの両方として機能する

|  | イベント | 初期値 |
|:-:|:-:|:-:|
| BehabiorSubject  | onNext, onError, onCompleted  | 必要  |
| PublishSubject  | onNext, onError, onCompleted |  必要ない |
| BehavoirRelay  |  onNextのみ | 必要  |
| PublishRelay  | onNextのみ  |  必要ない |

`〇〇Subject：` onNext以外にもonErroe, onCompletedなど流せる→責務が広いため実務ではあまり使われない
`〇〇Relay:` onNextのみ流す→責務が小さく扱いやすい→積極的に使いたい

`Trants:` Observableの簡単なラッパーで、
RxSwift　→　Single, Completable, Maybeが用意されていて、
RxCocoa　→ Driver, Signal, ControlEvent/Propertyがある
`Single:` 値 か error のイベントが一回だけ発生する.
`Completable:` complate か error のイベントが一回だけ発生する.
`Maybe:` (complate か 値) または error が一回だけ流れる.
イベントが発生する側は Subject をインスタンス化して、外部へは Observable の形で公開するのが基本.

## RxCocoa

`bind:` subscribeでもかえが効くが、バインディングしていることがより明示的になる→onNextしか流れない
`Signal:` エラーが発生しない, main スレッドで実行, subscribe してから発生した event を受け取れる.
`Driver:` エラーが発生しない, main スレッドで実行, 一つ前の event を受け取れる.
`ControlEvent:` エラーが発生しない, main スレッドで実行, メモリ割り当て開放時に complete が発生, subscribe してから発生した event を受け取れる.
`ControlProperty:` エラーが発生しない, main スレッドで実行, メモリ割り当て開放時に complete が発生, 一つ過去の event を受け取れる. 初期値が必要.
`Binder:` エラーイベントを処理しない, 指定した Scheduler (デフォルトは main) で実行. bind(to:) で bind 可能になる.
ショートカットキー【Mac】：デベロッパーツールで要素を選択する

**「Command(⌘)」+「Shift⬆️」+「C」**
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1130361/3affedf8-db05-8286-8bc8-9794f7b27859.png)
▶️選択できた
![スクリーンショット 2022-03-28 22.44.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1130361/36e70aed-88e3-e8c2-933a-ecf33ccd05be.png)
Laravel Sail環境でlaravel/uiを用いて認証機能を実装する

# はじめに
Laravel Sailで作った環境で、認証機能を実装しました。公式ドキュメントを見ると、Laravel BreezeやLaravel Jetstreamが記載されていますが、今回は扱いやすそうな、laravel/uiをインストールすることにしました。

# 参考にした記事
- [Laravel 8.x 認証 :公式ドキュメント](https://readouble.com/laravel/8.x/ja/authentication.html)
- [Laravel 8.x スターターキット :公式ドキュメント](https://readouble.com/laravel/8.x/ja/starter-kits.html)
- [Laravelの認証機能はどれを使うべき？Jetstream, Breeze, Laravel/ui, Fortify を比較](https://biz.addisteria.com/laravel_authentication/)
- [Laravel UIをインストールしよう](https://www.techpit.jp/courses/139/curriculums/142/sections/1056/parts/4194)

# 環境
- Laravel8
- WSL2

# laravel/uiをインストールする
ターミナルで下記のコマンドを実行し、laravel/uiをインストールします。
```
sail composer require laravel/ui
```

# 認証周りの機能を実装する
laravel/uiをインストールするだけでは、コントローラ等はありません。したがって認証周りの機能を実装する必要があります。
下記コマンドを実行します。
```
sail artisan ui bootstrap --auth
```
すると、下記のように表示されます。
```bash
Bootstrap scaffolding installed successfully.
Please run "npm install && npm run dev" to compile your fresh scaffolding.
Authentication scaffolding generated successfully.
```

言われた通り下記を実行します。
```
npm install && npm run dev
```
これで実装完了です。

# ルーティングの一覧を確認する

下記を実行してルーティングの一覧を確認してみます。

```
sail artisan route:list
```
以下の内容が表示されます。（認証部分のみを抜粋）
```terminal
  GET|HEAD   api/user ..............................................................  
  GET|HEAD   home ...................................... home › HomeController@index  
  GET|HEAD   login ...................... login › Auth\LoginController@showLoginForm  
  POST       login ...................................... Auth\LoginController@login  
  POST       logout ........................... logout › Auth\LoginController@logout  
  GET|HEAD   password/confirm password.confirm › Auth\ConfirmPasswordController@sho…  
  POST       password/confirm ............... Auth\ConfirmPasswordController@confirm  
  POST       password/email password.email › Auth\ForgotPasswordController@sendRese…  
  GET|HEAD   password/reset password.request › Auth\ForgotPasswordController@showLi…  
  POST       password/reset ... password.update › Auth\ResetPasswordController@reset  
  GET|HEAD   password/reset/{token} password.reset › Auth\ResetPasswordController@s…  
  GET|HEAD   register ...... register › Auth\RegisterController@showRegistrationForm  
  POST       register ............................. Auth\RegisterController@register  
  GET|HEAD   sanctum/csrf-cookie ....... Laravel\Sanctum › CsrfCookieController@show
```
ルーティングが追加されたことを確認できました！

# ログイン画面の確認
```routes/web.php```に以下のように```/home```のルーティングが追加されています。
```routes/web.php
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
```
```localhost/home```をブラウザで確認してみるとBootstrapが効いていないようなログイン画面が表示されました。
以下を実行してみます。
```
npm run watch
```
ログイン画面の確認ができました！
![localhost_login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868789/cc4695b7-5c53-a4e6-7609-4ed17c214794.png)

# おわりに
今回はlaravel/uiで認証機能を実装してみましたが、Laravel Breeze、Laravel Jetstreamを使っての認証機能の実装も試してみたいです。
自然言語処理モデルBERTの検証(2)-MeCab+WordPiece

##### [前回] [自然言語処理モデルBERTの検証(1)-予測のお試し](https://qiita.com/mingchun_zhao/items/ca926edeb7b5f5845f5f)

## はじめに

前回は、名人から提供されたDockerイメージを実行し、BERTによる予測をさくっと検証しました。
今回は、開発環境を用意し、BERTの実装と予測検証を行ってみます。

開発環境と言っても、Google様から提供されるJupyter notebookクラウド実行環境、
[Google Colaboratory](https://colab.research.google.com/?hl=ja)を使用します。
Googleアカウントを持っていれば、無料プランでもPythonによる機械学習を実装できます。

Colabノートブックに、コードを記述し、インタラクティブに実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/ca4f99aa-3c17-f86e-a030-28e8e698bcee.png)

## 検証シナリオ

「一番幸せを感じるのはどんな時か」を予測してみましょう。

東北大学 乾・鈴木研究室から公開された学習済みモデルを使用します。
https://github.com/cl-tohoku/bert-japanese
トークナイザーは、日本語形態素解析器MecabとWordPieceが使用されています。

## 検証開始

Colabノートブックに、下記コマンドを入力し、実行します。

MeCabのPythonラッパーをインストール
```
! pip install mecab-python3
```

transformersライブラリをインストール
```
! pip install transformers
```

MeCabを容易に利用するためMecabのPythonラッパーfugashiをインストール
```
! pip install fugashi
```

IPA辞書をインストール
```
! pip install ipadic
```

学習済みモデルをインポート
```
import torch
from transformers import BertJapaneseTokenizer
from transformers import BertForMaskedLM
```

tokenizerのインスタンスを作成
```
tokenizer = BertJapaneseTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
```

modelのインスタンスを作成
```
model = BertForMaskedLM.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
```

トークナイザーで、入力文をtoken idの配列に変換
肝は、`mask_token`でマスキングされている予測対象のトークンです。

```
in_ids = tokenizer.encode(f'''一番幸せを感じるのは{tokenizer.mask_token}をする時だ。''', return_tensors='pt')
print(in_ids)
```

すると、token idの配列が表示される
```
tensor([[    2,  4749, 13215,    11, 11486,     5,     9,     4,    11,    34,
            72,    75,     8,     3]])
```

token idの配列を対応する語彙に変換
```
print(tokenizer.convert_ids_to_tokens(in_ids[0].tolist()))
```

出力結果
```
['[CLS]', '一番', '幸せ', 'を', '感じる', 'の', 'は', '[MASK]', 'を', 'する', '時', 'だ', '。', '[SEP]']
```

マスキングされたトークンのインデックスを取得
```
mask_idx = torch.where(in_ids == tokenizer.mask_token_id)[1].tolist()[0]
print(mask_idx)
```

結果は、
```
7
```

モデルを実行し、結果を出力
```
result = model(in_ids)
predicts = result[0][:, mask_idx].topk(5).indices.tolist()[0]
for predict in predicts:
    out_ids = in_ids.tolist()[0]
    out_ids[mask_idx] = predict
    print(tokenizer.decode(out_ids))
```

気になっていた予測結果が出ました
```
[CLS] 一番 幸せ を 感じる の は 仕事 を する 時 だ 。 [SEP]
[CLS] 一番 幸せ を 感じる の は キス を する 時 だ 。 [SEP]
[CLS] 一番 幸せ を 感じる の は 恋 を する 時 だ 。 [SEP]
[CLS] 一番 幸せ を 感じる の は 食事 を する 時 だ 。 [SEP]
[CLS] 一番 幸せ を 感じる の は ゲーム を する 時 だ 。 [SEP]
```

「仕事」が、幸せの上位になっています。
楽しく、楽して仕事できたらいいですね。

## おわりに

Google Colaboratory環境で、トークナイザーとしてMeCab+WordPieceを用いた、
BERTによる予測を行った結果、幸せの答え(?)を得られたようです。
引き続き、機能・性能両面で検証を進めてまいります。
お楽しみに。

##### [次回] [自然言語処理モデルBERTの検証(3)-GLUEベンチマーク](https://qiita.com/mingchun_zhao/items/9269538a0434335fe87d)
100日でSQLの達人になる@LeetCode! Day49 <WebブラウザでMS SQL Server>

## WebブラウザでMS SQL Server
ここまでずーっと[LeetCode](https://leetcode.com/)の問題を解いてきましたが、基本的な事項の見直しをしたいと思いました。
そこで今日から数回、[LeetCode](https://leetcode.com/)の問題はお休みして基本事項の整理をしたいと思います。

まずは、MS SQL Serverの実行環境の確保です。

### MS SQL Server対応
- [db<>fiddle](https://dbfiddle.uk/?rdbms=sqlserver_2019)
色々ありそうですが、使用してみた感じ一番安定していたのがこちら。
MS SQL Serverのバージョンも色々試せますし、MySQL,SQLiteなどメジャーなSQLが全て使えます。
コードの実行も`run`ボタンでシンプルで分かりやすいです。
- [SQL fiddle](http://sqlfiddle.com/)
こちらは有名なサイトだと思います。左右に画面が別れていて、左側でまずはテーブルを作成し、右側で実際のSQLクエリを記載する形式になっています。
しかし、時々作成したテーブルが表示されないなどあり最初のサイトが良いかと思います。
- [rextester.com](https://rextester.com/l/sql_server_online_compiler)
MS SQL Serverだけでなく色々な言語にも対応していそう。

### MS SQL Server以外
MS SQL Server非対応であれば色々選択肢は増えます。
- [DB Fiddle](https://www.db-fiddle.com/)
- [Datasprac](https://www.datasparc.com/online-sql-editor/)
アカウント作成が必要なようですが、作成してしまうと使い勝手は良さそう！？
- [JDOODLE](https://www.jdoodle.com/execute-sql-online/)
- [Oracle Live SQL](https://livesql.oracle.com/)
- [Coding Ground](https://www.tutorialspoint.com/codingground.htm)
こちらはSQLだけでなく色々な言語が試せる

今日のポイントは`Webブラウザ上でSQLの実行環境を整える`とした。
Kotlin KoansでKotlin入門　第１８回：Invoke

# はじめに
公式の問題集[「Kotlin Koans」](https://play.kotlinlang.org/koans/overview)を解きながらKotlinを学習します。

過去記事はこちら
- Introduction
  - [第０回：Kotlin Koansについて](https://qiita.com/kosuke1/items/41d192af63485bfc8cb8)
  - [第１回：Simple Functions](https://qiita.com/kosuke1/items/5862a3ece96082a62e67)
  - [第２回：Named arguments](https://qiita.com/kosuke1/items/2af11262852ee41b5da7)
  - [第３回：Default arguments](https://qiita.com/kosuke1/items/16cb8ac780df58dc8054)
  - [第４回：Triple-quoted strings](https://qiita.com/kosuke1/items/52cfeed2c49b0252d40e)
  - [第５回：String templates](https://qiita.com/kosuke1/items/0221bbbc5bc70847be6f)
  - [第６回：Nullable types](https://qiita.com/kosuke1/items/aa96e422c5313b6961bc)
  - [第７回：Nothing type](https://qiita.com/kosuke1/items/1ca0e48820d58c9dfe16)
  - [第８回：Lambdas](https://qiita.com/kosuke1/items/8de74f9491e003127f53)
- Classes
  - [第９回：Data classes](https://qiita.com/kosuke1/items/1be2de1b4406b8d914bf) 
  - [第１０回：Smart casts](https://qiita.com/kosuke1/items/50bdecaa0740eb0e1a17)
  - [第１１回：Sealed classes](https://qiita.com/kosuke1/items/71a4da02fe1e99da5d63)
  - [第１２回：Rename on import](https://qiita.com/kosuke1/items/f11465cc15a94e7589a3)
  - [第１３回：Extension functions](https://qiita.com/kosuke1/items/d4a1da00bc142c297221)
- Conventions
  - [第１４回：Comparison](https://qiita.com/kosuke1/items/e9486d044cae32167f36) 
  - [第１５回：Ranges](https://qiita.com/kosuke1/items/797f049ce5f33b1810c9)
  - [第１６回：For loop](https://qiita.com/kosuke1/items/f5f6eeea41fb89b2a20c)
  - [第１７回：Operators overloading](https://qiita.com/kosuke1/items/9845f98a632121f1493b)


# 問題
[Invoke](https://play.kotlinlang.org/koans/Conventions/Invoke/Task.kt)

invoke()メソッドを持つオブジェクトは、関数として呼び出すことができます。
どのクラスでも invoke 拡張を追加することができますが、使いすぎないようにしたほうがよいでしょう。
```Kotlin
operator fun Int.invoke() { println(this) }

1() //huh?..
```

Invokable.invoke()という関数を実装して、呼び出された回数をカウントするようにしましょう。


修正前のコード
```Kotlin
class Invokable {
    var numberOfInvocations: Int = 0
        private set

    operator fun invoke(): Invokable {
        TODO()
    }
}

fun invokeTwice(invokable: Invokable) = invokable()()

```


# 問題のポイント
operator overloadingのつづきで[invoke operator](https://kotlinlang.org/docs/operator-overloading.html#invoke-operator)を使います。
括弧だけでinvokeメソッドを呼び出すことができます。


# 解答例

```Kotlin
class Invokable {
    var numberOfInvocations: Int = 0
        private set

    operator fun invoke(): Invokable {
        numberOfInvocations += 1
        return this
    }
}

fun invokeTwice(invokable: Invokable) = invokable()()
```
Laravel artisanでよく使うコマンド

Laravel artisanでよく使うコマンドについて記載。



```
#controller作成
php artisan make:controller Controller

#Model作成
php artisan make:model User

#Modelの生成先を指定したい場合
php artisan make:model Models`\\`User

#migrationファイルの作成
php artisan make:migration 

#migrationを戻す（--stepに指定数分巻き戻される。現在の状況はmigrationテーブルを参照）
php artisan migrate:rollback --step=1

#認証機能を作成したい場合
php artisan make:auth

#artisanコマンド作成
php artisan make:command     

#イベントククラス作成     
php artisan make:event 

#listenerクラス作成   
php artisan make:listener   

#exceptionクラス作成           
php artisan make:exception       

#Create a new model factory 
php artisan make:factory          

#jobクラス作成
php artisan make:job           

#emailクラス作成     
php artisan make:mail             

#middlewareクラス作成
php artisan make:middleware            

#notificationクラスの作成
php artisan make:notification     

#policyクラスの作成
php artisan make:policy           

#service providerクラスの作成
php artisan make:provider         

#requestクラス作成
php artisan make:request          

#resourceの作成
php artisan make:resource         

#validation ruleの作成
php artisan make:rule             

#seederクラス作成
php artisan make:seeder    

#testクラスの作成       
php artisan make:test  

#cache削除
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan clear-compiled

#cache削除（1回で上記を実行）
php artisan optimize:clear

#Composerのオートローダを再生成（artisanではないが）
composer dump-autoload

#キャッシュ作成（config、routeのキャッシュクリア、キャッシュを行う。）
php artisan optimize


```

以上
Web上のHTMLからPython Notebookを自動生成してみた

## 初めに
GitHubのREADME記載のExampleとかをNotebookで実行したことがちまちまあります。
数が多いとコピペも面倒ですし、何よりそんな生産性ゼロなことに時間を奪われたくない！！
ということで`BeautifulSoup`と`jupytext`で自動化してみました。
皆さんの貴重な時間を節約するために是非ご活用くださいー！

## 実装
GithubのREADMEの場合は`element`に`div`、`class_`に`highlight-source-python`を指定すればPythonのコードブロックのみをとってこれます。その他のWebページでもパラメータをよしなに変更していただければ動くかと。

```python
import requests
from bs4 import BeautifulSoup
import jupytext

def convert_html_to_ipynb(
    url: str,
    filename: str,
    element: str = "div",
    class_: str = "highlight-source-python",
) -> None:
    """Fetch HTML and extract only its code block and save it as ipynb."""
    res = requests.get(URL)
    soup = BeautifulSoup(res.text, "html.parser")
    py_percent_text = "\n# %%\n".join(
        [x.get_text() for x in soup.find_all(element, class_=class_)]
    )
    nb_text = jupytext.reads(py_percent_text, fmt="py")
    jupytext.write(nb_text, filename)

convert_html_to_ipynb("https://github.com/...", 'sample.ipynb')
```

## 終わりに
このコードで皆さんの1秒が節約できれば幸いです。
【TypeScript】Mapped typeを活用して拡張性の高いコードを書く

# はじめに
TypeScript+Reactなどの環境で、コンポーネントのタイプによって背景色や文字色などを切り替えたいとき、Mapped typeを使うと拡張性のある実装を行うことができるよ！という話です。
こちらTypeScript初心者向けの記事になりますので、もっと基礎向けの内容も知りたいという方は以下の記事もご覧ください。

https://qiita.com/suzuki0430/items/86a5b4c3c33c48c8bc44

https://qiita.com/suzuki0430/items/f8d5cbbe9401c5945098

# 実装
背景色や文字色を"WARNING"と"DANGER"の2パターン用意したいとき、三項演算子を使えば以下のように書くことができます。

```ts
const backgroundColor = type === "WARING" ? "yellow" : "red";
const color = type === "WARING" ? "white" : "black";
```

しかし、今後"NORMAL"というパターンも用意しなければいけなくなったとき、三項演算子を使うことはできなくなります。
機能拡張のために、`if`や`switch`を使った実装変更を行う必要がでてきてしまいます。

パターンを1つ増やすだけでこのような実装変更を行う必要があるのは、決して拡張性の高いコードとはいえません。
このときに利用するのがMapped typeです。

```ts
type AttentionType = "WARNING" | "DANGER";

type AttentionTheme = {
  backgroundColor: string;
  color: string;
};

const AttentionThemeMap: { [key in AttentionType]: AttentionTheme } = {
  WARNING: {
    backgroundColor: "yellow",
    color: "white",
  },
  DANGER: {
    backgroundColor: "red",
    color: "black",
  },
};
```
`AttentionType`で必要なパターンをユニオンリテラル型で定義し、`AttentionTheme`で各パターンにおけるオブジェクトのプロパティの型を定義します。
すると、`AttentionThemeMap: { [key in AttentionType]: AttentionTheme }`のようなMapped typeを定義することができます。

各パターンにおける`backgroundColor`や`color`を以下のように取得することができるのですが、`type`が`AttentionType`("WARNING"と"DANGER")以外だと、TypeScriptが赤波線でエラーを出して注意してくれます。

```ts
const { backgroundColor, color } = AttentionThemeMap[type]
```
また、"NORMAL"のような新しいパターンを追加したいとき、必要なのは`AttentionType`と`AttentionThemeMap`への簡単なコード追加のみとなります。

```ts
type AttentionType = "WARNING" | "DANGER" | "NORMAL";

const AttentionThemeMap: { [key in AttentionType]: AttentionTheme } = {
  WARNING: {
    backgroundColor: "yellow",
    color: "white",
  },
  DANGER: {
    backgroundColor: "red",
    color: "black",
  },
  NORMAL: {
    backgroundColor: "green",
    color: "white",
  },
};
```
条件変更を`if`や`switch`頼みにすると、コードの可読性も下がってしまいます。
明日からMapped typeを使ってみましょう！

# 参考資料

https://typescriptbook.jp/reference/type-reuse/mapped-types
DSPIC30マイコンでリバーブエフェクターを作りたかった

前回Lチカに成功したPICですが、その後調査を続けてdsPICでエフェクターを作れそう・・・というところまで来ました。
が、実験に使ったdsPIC30F2012はRAMが1KBしかないということに開発途中で気づき、リバーブを作りたくても作れなかった、というお話です。

リバーブにはいくつかのアルゴリズムがありますが、今回はシュレーダー(schroeder)のリバーブを試みました。
これにはIIRコムフィルタが４つとオールパスフィルタ２つが使われています。
IIRコムフィルタはおよそ50msの遅延をもたせるように設計されています。
16bit/Fs28KHzとした場合、これを実現するには、16bitの要素数約1500の配列が必要になります。(1サンプル34μsなので50ms/34μs=1470)
つまり、これひとつだけでメモリ消費が3KBになります。
これを4つ用意すると12KB。
ということで、SRAMの少ないdsPIC30シリーズでは結構厳しそうです。

DSPIC33シリーズならばデータメモリが16KB以上のものもあるので頑張ればできるかもしれません。
が、ヒープやスタック、ニアとファーなんかを考えるとそれでも足りないのかもしれません。
やる気が続けばhttps://akizukidenshi.com/catalog/g/gI-08458/を使って挑戦してみようと思います。

※RAMが豊富に必要ではない歪み系やモジュレーション系なら問題なく作れるはずです。

供養のために上限の遅延数400で作った、遅延15msのショートディレイの画像を貼っておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380862/56e65069-e7b9-e884-f2e0-b321c44f1a06.png)


参考書：dsPIC基盤で始めるディジタル信号処理
React hydrate時の差分検知ではdangerouslySetInnerHTMLで追加した要素は見ない

## これはなに

React でレンダリングされた DOM に`hydrate`をする際に、差分があった場合、再レンダリングが行われる。

> https://ja.reactjs.org/docs/react-dom.html#hydrate
> React はレンダーされる内容が、サーバ・クライアント間で同一であることを期待します。React はテキストコンテンツの差異を修復することは可能ですが、その不一致はバグとして扱い、修正すべきです。開発用モードでは、React は両者のレンダーの不一致について警告します。不一致がある場合に属性の差異が修復されるという保証はありません。これはパフォーマンス上の理由から重要です。なぜなら、ほとんどのアプリケーションにおいて不一致が発生するということは稀であり、全てのマークアップを検証することは許容不可能なほど高コストになるためです。

そう思って、`hydrate`をしていたところ、再レンダリングがされない場合があったため、その場合の条件と推測を記事にする。

今回、検証を行ったサンプルコードは以下。

https://github.com/ohakutsu/archives/tree/main/react-hydrate-test

## どんなときに再レンダリングがされないのか

`dangerouslySetInnerHTML`で要素を追加している場合、`dangerouslySetInnerHTML`プロパティがついている要素配下で差分が生じていても再レンダリングされないことがわかった。

以下は、サーバーでレンダリングしたときは`server`、クライアントでレンダリングしたときは`client`と表示されるコンポーネント。

```jsx:components/App.jsx
import React from "react";

const App = () => {
  let d = "";
  if (typeof window === "undefined") {
    d = "server";
  } else {
    d = "client";
  }

  return (
    <>
      {/* ↓再レンダリングされない */}
      <div
        style={{ backgroundColor: "pink" }}
        dangerouslySetInnerHTML={{ __html: d }}
      ></div>
      {/* ↓再レンダリングされる */}
      <div>{d}</div>
    </>
  );
};

export default App;
```

↓ が実際の結果のスクリーンショットだが、`dangerouslySetInnerHTML`で要素を追加した方（背景がピンク）のみ再レンダリングがされていない。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352836/b1488e99-3437-7e29-c017-859c2beb883d.png)

## なぜ再レンダリングされないのか？（推測）

React のソースコードをすべて追いきれなかったので推測になるが、`dangerouslySetInnerHTML`のソースを読んでみると、単純に`innerHTML`を読んでいるだけの様。

https://github.com/facebook/react/blob/12adaffef7105e2714f82651ea51936c563fe15c/packages/react-dom/src/client/setInnerHTML.js#L63

React が Fiber ツリーをもとにレンダリングしていることを考えると、`dangerouslySetInnerHTML`で追加した要素は Fiber ツリーの管理下にないのではないかと思っている（もしくは、`dangerouslySetInnerHTML`配下は any として扱う）。

その結果、ツリーと実際の DOM を比較しても差分を検出できず、今回のようになってしまう。というのが推測だ。

（もし知っている方がいれば教えていただけるととても助かります！）

## 最後に

React のソースコードを追いきれず、真の理由を知れなかったのは残念だった。
（React のソースコードを読むのは疲れる。）

もし知っている方がいれば教えていただけるととても助かります！
LINEログインをPHPで実装する

LINE for Businessのアカウントでお客さんとやり取りした後に、フォーム入力をお願いすることになりました。フォームにメアドやLINEのニックネームを入力をお願いするのもリダンダントなので、LINEログインでメアドやニックネームを取得してフォームに自動入力させてみます。

手順は以下の通り（<a href="https://developers.line.biz/ja/docs/line-login/integrate-line-login/">こちら</a>を見ながらやるとよいと思います）
1. LINE developersコンソールでLINEログインのチャネルを作成
1. 同コンソールにてコールバックURL設定
1. コード書く

用意するコードはログイン開始ページlogin.phpと、コールバックページcallback.phpの2つです。

```login.php
$callback_url = "https://example.com/callback.php"; //LINE developersコンソールに設定したURL
$state=rand();

$url = sprintf(
    "https://access.line.me/oauth2/v2.1/authorize"
    ."?response_type=code"
    ."&client_id=%s"
    ."&redirect_uri=%s"
    ."&state=%s"
    ."&scope=profile"
    ,"LINE developersコンソールのチャネルID"
    ,$callback_url
    ,$state
);

header("Location: {$url}");
exit;
```



```callback.php
// アクセストークン取得
$url = "https://api.line.me/oauth2/v2.1/token";

$postData = array(
    "grant_type" => "authorization_code",
    "code" => $_GET["code"],
    "redirect_uri" => "https://example.com/callback.php", //LINE developersコンソールに設定したURL
    "client_id" => "LINE developersコンソールのチャネルID",
    "client_secret" => "LINE developersコンソールのチャネルシークレット"
);


$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/oauth2/v2.1/token');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
 
$json = json_decode($response);
$accessToken = $json->access_token; //アクセストークンを取得

$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $accessToken));
curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/profile');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

$json = json_decode($response);


$userInfo= json_decode(json_encode($json), true); //ログインユーザ情報を取得する
$name= $userInfo['displayName']; //LINEのニックネーム
$form_url="https://example.com/form?&entry_username=".$name;//フォームにニックネームを渡す

header("Location: {$form_url}");
```

これでLINEトークでlogin.phpのページを配信 > 連携 > フォームを開く際に名前やメールが自動入力されるという機能が実現できました。