OmniAICreator/Qiita-1.07M huggingface dataset:
Debian 10 (buster) にtranslate-shellをインストール

Debian 10 (buster) ではデフォルトでtranslate-shellをaptでインストール不可で、検索しても直ぐに情報が出てこなかったので、ここに投稿しておこうと思う。
なお、translate-shellとはGoogle翻訳を呼び出すコマンドである。

translate-shellをaptでインストールするには、事前にcontribリポジトリを追加する。

```
# echo "deb http://ftp.de.debian.org/debian buster main contrib" > /etc/apt/sources.list.d/contrib.list
# apt update
# apt install translate-shell
```

参考： https://packages.debian.org/buster/all/translate-shell/download

これでシェル上で翻訳ができるので、とても便利である。

```
$ trans -b en:ja "hello world!"
こんにちは世界！
```


#### 2020/10/21追記

デフォルトでインストール可能な他のLinuxディストリビューションで以下のエラーが出力された場合、バージョンアップすると良い。

```
[ERROR] Null response.
[ERROR] Oops! Something went wrong and I can't translate it for you :(
```

実際にはバージョンチェックを行い、最新版をダウンロードして、既存のファイルを更新する。

```
$ sudo trans -U
Current version:        0.9.2.1
New version available:  0.9.6.12
Download from:  http://www.soimort.org/translate-shell/trans
$ sudo wget http://www.soimort.org/translate-shell/trans
$ sudo chmod +x trans
$ sudo mv trans `which trans`
```
本日の学習まとめ　ユーザー管理機能実装にて

#はじめに
　今回は完全に自分用で覚えておきたいことを雑多に書き連ねている。

##正規表現
　

```ruby

PASSWORD_REGEX = /\A(?=.*?[A-z])(?=.*?[\d])[A-z\d]+\z/i.freeze # 半角英数混合1字以上
ZENKAKU_REGEX = /\A[ぁ-んァ-ン一-龥]+\z/.freeze # 全角ひらカタ漢字
KANA_REGEX = /\A[ァ-ヶー－]+\z/.freeze # 全角カナ
```


`freeze`は変数が変わらないようにするため。

##バリデーションのオプションをまとめる

```ruby

with_options presence: true do
 validates #オプションをつける 
end
```


##エラーメッセージを表示させる

foem_withの中でrenderメソッドでファイルを呼び出す。そのとき、devise配下のファイルであるように記述をする。

```ruby

<%= form_with model: @user, url: user_registration_path', local: true do |f| %>
  <%= render 'devise/shared/error_messages', model: f.object %>
```

```ruby:_error_messages.html.erb
<% if model.errors.any? %>
  <div id="error_explanation">
    <h2>
      <%= I18n.t("errors.messages.not_saved",
                 count: model.errors.count,
                 resource: model.class.model_name.human.downcase)
       %>
    </h2>
    <ul>
      <%= model.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>

modelを呼び出すように記述する。
Power Apps キャンバスアプリをテナント外のユーザーと共有してみて、気が付いたこと

Power Apps キャンバスアプリをテナント外のユーザーを共有してみて、気が付いたことをメモします。尚、本件に関してはより正確な情報は公式アカウントに委ねます。
・[テナント外のユーザーとアプリを共有する (B2B)](https://docs.microsoft.com/ja-jp/power-platform-release-plan/2019wave2/microsoft-powerapps/share-apps-users-outside-tenant-b2b-or-b2c)
・[ゲストと共有する](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/share-app#share-with-guests)

# スマホアプリで、共有されたキャンバスアプリが見つからない場合がある
Power Appsの共有でテナント外のユーザーに共有しても、Power Apps内の「すべてのアプリ」「マイアプリ」で見えない場合がある。おそらくですが、これはゲストユーザーには、「ユーザーロール」しか割り当てられないことが影響していると思います。ただし、同じテナント内であれば、「共同所有者」になっていなくても、アプリケーションは一覧に現れるので、直接的な説明にはなっていないと思っています。
では、テナント外のユーザーと共有できていないかというとそういう訳ではなく、Webリンクを共有することで確かにアプリを使用することが可能になります。更に、私の環境の場合は、一度Webリンクでアプリを開いた後に、スマホアプリのPower Appsを開くと、以前までは見えなかったテナント外から共有されたアプリが確認することが出来ます。この辺り、まだ納得は出来ていないですが、現状では、テナント外のユーザーとキャンバスアプリを共有した時のちょっとした困りごとぐらいに考えています。

# スマホにプッシュ通知を送ることが出来ない
Power Apps キャンバスアプリを決まったタイミングで使用して欲しいと考えていて、Power Automateを使って定刻に「Send push notification」を通知する処理を検討していました。
ただし、ここにも困ったことが発生して、Power Automateの「Send push notification」の宛先でテナント外のユーザーを設定しても、実際にテナント外のユーザーにプッシュ通知を送ることが出来ませんでした。
こちらも、
・[Power Apps でプッシュ通知を送信する](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/add-notifications#before-you-start)
により正確な情報が記載されていると思いますが、「開始する前」の項目で、「共同作成者のアクセス許可」に言及されています。上記の内容でも記載したとおり、テナント外で共有されたアプリは「ユーザーロール」しか割り当てられていません。なので、「共同作成者のアクセス許可」を与えることは事実上不可能である為、その為にテナント外のユーザーにアプリを共有しても「Send push notification」を使って、スマホアプリに通知を送ることは出来ません。しかし、スマホアプリで共有されたアプリが見えない現象との関連も確認が出来ていて、Webリンクでアプリを開いた後で、「すべてのアプリ」の中で共有されたアプリが見えている状態になっていると、プッシュ通知が受け取れることもありました。ただ、いずれにせよ、挙動が不安定な為、安心して利用できる状態ではないような気がします。
＊回避策としては「ユーザーロール」であっても、Webリンクからアプリを開いて使うことは出来るので、Teamsにメンションを付けて、Webリンクを一緒にメッセージを送るという手法で、それなりに回避することは可能です。ただし、Power Appsのスマホアプリのみで完結したいと思うとちょっと難しくなります。

# まとめ
とりあえず、上記の２点が試してみた情報になります(2020/10/17現在)。
そもそも、Power Apps自体が同一テナント内で使用することを想定した思想であるような気はしていますが、ちょっとテナント外のユーザーを共有して仕事をしたいを考えても、少しばかり制限事項が出てくるので、そのメモ程度に読んでもらえたらと思います。
＊尚、上記の挙動の解釈に関しては個人的な考えも含まれていますが、Power Appsの挙動としては確認できていますので、もしテナント外のユーザーとの共有を検討している場合は、参考にして貰えたらと思います。

この記事を書いている時点(2020/10/17)で、ちょっと前にはなかったプッシュ通知のV2の情報が確認できました。なので、こちらが使用できるようになると少し変わるのかもしれません。
[Power Apps Notification V2 (Preview)](https://docs.microsoft.com/en-us/connectors/powerappsnotificationv2/)
MacBookAirにemacsを導入してみる

## 前略
初めてまともにQiitaにて記事を書きます。
Markdown記法に慣れていないので一般的なQiitaの書き方に促していなかったり
CUI操作不慣れや知識不足により問題だらけかと思いますが、ご容赦いただけると嬉しいです。

## 環境
macOS Catalina バージョン10.15.7

## インストール対象emacs
emacs 3.9.0

## きっかけ
本来の目的はmacにデフォルトでは入っていないpython3.xxを入れようとしたのがきっかけです。
~/.bash_profile　を編集しようとしたのですが、
CUIのエディタがvimしか入っていなかったので、
元々過去にemacsを少しだけ触ったことがあったこともあり、
せっかくならemacs入れてみようかと思った次第です。
(vimに慣れる、という方が良かったかもしれませんが、、、)

## いざ、インストール
参考にさせていただいたのは[この記事](https://qiita.com/Takuma_Ikeda/items/0908be8a626f26bf72e1)です。

コマンド一発でインストールできるものかと思っていたのですが、そうでもないのですね。。。
macのパッケージ管理ソフトの**Homebrew**が必要ということみたいで、
まずはそちらをインストールします。
コマンドは以下です。

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

[このURL](https://brew.sh/index_ja)のコマンドをそのままコピーさせていただきました、
他のemacsインストール記事でも参照されていたので王道のWebサイトなんだろうと思いました。

そして何やら大量にインストールされているようで少々ビビりながら待っていると、
２、３分で問題なく完了しました。

その後、brewコマンドにて、emacsインストールを実行します。

```
brew install emacs
```

なんだかんだここまでで3GB容量が食われているように見えました。
エディタ一つのインストールにここまでかかるのかとショック。。。
（最小限のインストールになっていないのか、中身を理解仕切っていないまま安易にコマンド実行するのが問題なのでしょうか・・・今後の課題です。）

というわけで、emacsのインストールも無事完了しました。
慣れていないと王道のエディタを入れるだけでも一苦労ですね・・・
Qiita様と過去に記事を書いてくださった皆様に圧倒的感謝です。。
ありがとうございました。
これにて初稿を終了します。

これからも地道に頑張るぞ〜！
【初心者向け】MySQLでローカルにDBを作成する方法

MySQLを勉強するためにローカルでDBを作成する方法を調べたので、備忘録的まとめ。
※MySQLが使える状態であることが前提。

## 1.MySQLを起動
```
＄ mysql.server start
Starting MySQL
 SUCCESS! 
```

## 2.rootユーザーでログイン
```
2020-10-17T13:43:42.6NZ mysqld_safe A mysqld process already exists
mysql -u root　// これを入力する
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.31 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

## 3.DBを作成
```
mysql> create database testDB; // これを入力する
Query OK, 1 row affected (0.01 sec)
```

## 4.DBを確認
```
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| testDB             | // 作成したDBが入っている
+--------------------+
7 rows in set (0.00 sec)
```

## 5.DBを選択する
```
mysql> use testDB; // これを入力する
Database changed
```

## 6.テーブルを確認
```
mysql> show tables; // これを入力する
Empty set (0.00 sec)
```
→DBを作成しただけで、中身は空の状態

ここまでで、DBの作成は完了。

※DB作成後にデータを突っ込みたい方はこちらを参照
[【MySQL】テーブルを作成して、CSVファイルからデータをインポートする方法](https://qiita.com/OhshimaRyo/items/c4921b79742f1d99970d)
【HTML&CSS】レスポンシブで改行の位置を切り替える方法

#プログラミング勉強日記
2020年10月17日
レスポンシブでサイトを作るときに、パソコンでみるときとスマホでみるときで改行の位置を変えたいときにメディアクエリを使うことで解決する方法を知ったのでまとめる。


#パソコンのみ・スマホのみで改行させる方法
　まず、ブレイクポイントを680pxとしたとき、680px以下の時は`.pc`は非表示に、`.sp`は表示する。逆に、680px以上のときは`.pc`は表示に、`.sp`は非表示にする。

```css:css
@media screen and (min-width: 680px) {
  .pc { display:block; }
  .sp { display:none; }
}
@media screen and (max-width:680px) {
  .pc{ display:none; }
  .sp{ display:block; }
}
```

　これを開業する`br`のclassとして追加する。

```html:html
<p>パソコンのみで改行したい場合<br class="pc">このようになる。</p>
<p>スマホのみで改行したい場合<br class="sp">このようになる。</p>
```

パソコンから見た場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/fdb1ab06-416c-13a7-fcf4-43da28e21d6b.png)

スマホから見た場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/50a82bd3-4e58-6737-63ad-6d34685d497c.png)


#参考文献
[PCのみ改行・SPのみ改行をCSSで実装する方法【レスポンシブデザイン】](https://kakedashiweb.site/archives/1158)
【メモ】WSL2上でIntelliJを動かして開発する最小限の準備

# 概要
最近作業用のPCを入れ替えたついでにWSL2を使い始めました。
主な用途としてはDockerなんですが、[**ベストプラクティス**](https://docs.docker.com/docker-for-windows/wsl/#best-practices)としては作業ファイルもLinux上に配置した方がいいらしいです。
VSCodeではWSL2での作業を想定した[**プラグイン**](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)が提供されていてIntelliJでも同じことができないかなーと思いいろいろ調べました。

現時点ではVSCodeに提供されているプラグインと同じ機能のものはなさそうなんですが、
ちょっとした設定で同等のことが出来そうなので試行錯誤した結果をメモしておきます。

# 前提
WSL2の導入はすでに終わっているものとします。（導入方法などは解説しません）
使用するOSはUbuntuです。
2020年10月時点での情報です。

# Windows側の設定
こちらの記事を参考にさせていただきました。
↓↓↓
[WSL2におけるVcXsrvの設定](https://qiita.com/ryoi084/items/0dff11134592d0bb895c)

# Ubuntu側の設定
## やることを簡単に箇条書き
1. XWindowSystemの出力先をホストOSにする
1. ブラウザをインストールする（JetBrainsのアカウント認証に使用する）
1. JetBrainsToolboxをインストールする

何回か試したところブラウザはChromeを選んだ方が簡単でした。
Firefoxだと何個か手動でパッケージを追加する必要がありました。

## コマンドを列挙

```bash:XWindowSystemの出力先をホストマシンに指定する
sed -i '$a export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '\''{print $2}'\''):0' .bashrc
```

```bash:chromeをインストールするためのリポジトリ追加
sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
```

```bash:インストールする前に実行
sudo apt update
```

```bash:ブラウザをインストール
sudo apt install google-chrome-stable
```

```bash:JetBrainsToolboxをインストール
curl -O https://raw.githubusercontent.com/nagygergo/jetbrains-toolbox-install/master/jetbrains-toolbox.sh
chmod u+x jetbrains-toolbox.sh
./jetbrains-toolbox.sh
```
[参考URL](https://pleiades.io/help/idea/installation-guide.html)

## あとはUbuntuを再起動しToolboxを起動する

```powershell:ホストマシンで実行
wsl -t Ubuntu
```

```bash:Toolboxを起動
jetbrains-toolbox
```

これでWindowsにインストールしたIntelliJとほぼ変わらない感じで使えそうです。

## Firefoxを使う場合（補足情報）
Firefoxの場合は以下のパッケージが不足するみたいです。
最初Firefoxを使おうと思って躓いたので調査した結果です。

```bash:Toolboxが要求するライブラリ
sudo apt install libnss3
sudo apt install libgbm1
```

そしてこちらを入れないとブラウザで認証した後のリダイレクトがうまく動きません。

```bash:これを入れないとToolbox認証後に反応しない
sudo apt install xdg-utils
```

認証が成功した後に `jetbrains` というプロトコルを使用しようとしてunknown protocolになっていました。
（あまりよくわかっていない）

# まとめ
あまりWSL周りに手を出してこなかったのですがとても便利そうだと感じました。
WindowsでDockerを使用した開発のストレスもだいぶ軽減されそうです。
このまま発展が続いてOSの機能的な違いなんて意識しない未来が来ると素晴らしいなと思いました！

# その他の関連情報
[日本語化](https://blog.mamansoft.net/2020/07/26/efficient-wsl2-with-ubuntu2/)
【Vue.js】リアクティブに画像プレビューする


#new FileReaderについて

アップロード画像を非同期に読み取ることができるオブジェクト

```javascript:
const reader = new FileReader();
```

#FileReaderでできること

読み込まれた画像情報をアップロード画像データに上書きする

```javascript:
reader.onload = (e) => {
  this.staff_image = e.target.result;
};
```

アップロード画像を読み込む

```javascript:
reader.readAsDataURL(this.staff_image);
```

- 読み取り操作が正常に完了されたら、result属性に格納されたデータを、アップロード画像データに上書きする
- アップロード画像を読み込ませた結果をresult属性に返している




#実践：アップロード画像をプレビューで表示させて、DBに保存する

###ポイント
* プレビュー画像と、DB保存画像の格納dataを分けて考える

###流れ
1. v-input-fileに、v-model属性をつけることで、アップロードファイルとdataオプションと連動させる
2. 画像がアップロードされたらimgaeUp関数が着火し、画像ファイル拡張子を使えるものに限定させる。この時、DBに保存する画像情報を格納しておく。
3. もし使えない画像拡張の場合は、errors変数にエラー文を格納すると共に画像情報を削除し、imageUp関数を強制終了させる
4. 特に問題ない場合、プレビュー画像用に画像情報をパースし、アップロード画像を表示させる判定に切り替える。


##tmplateタグ(pug形式)

```javascript:
v-img(v-if="image", :src="staff_image")
v-img(v-else, src="/images/default.png")
```

```javascript:
v-file-input(
  hide-input,                   // フォームを隠す
  prepend-icon="mdi-camera",    // ボタンアイコン 
  @change="imageUp()",          // アップロードされたら、着火する関数
  v-model="staff_image"         // アップロード画像と連動させる
)
```

##scriptタグ

```javascript:
data() {
  return {
    staff_image: "",     // アップロードファイルの格納場所
    image_name: "",      // DBに保存するアップロードファイル
    image: false,        // 表示するのは、デフォルト画像かアップロード画像かの判定
  };
},

imageUp() {

  // 画像ファイル拡張子の検証
  const type = this.staff_image.type;
  this.image_name = this.staff_image;    // DB保存用に、画像情報を格納しておく
  let errors = "";
  if (
    type !== "image/jpeg" &&
    type !== "image/gif" &&
    type !== "image/png" &&
    type !== "application/pdf"
  ) {
    errors +=
    ".jpg、.gif、.png、.pdfのいずれかのファイルのみ許可されています\n";
  }
  if (errors) {
    alert(errors);
    this.staff_image = "";
    this.image_name = "";
    this.image = false;
    return;                             // エラー処理の場合、imageUp関数を強制終了する
  }

  // アップロード画像をプレビューで表示させる
  const reader = new FileReader();
  reader.onload = (e) => {
    this.staff_image = e.target.result;
  };
  reader.readAsDataURL(this.staff_image);
  this.image = true;                         // アップロード画像の表示に切り替える
},

```
AWS上でMoodleの環境を構築する方法


## Moodleとは？
Moodle（ムードル）は無料のオープンソースソフトウェアで、学習管理システム（LMS=Learning Management System)としての機能を備えています。Moodleを利用することで、インターネット上で講義コースを作成・運用することができます。また、資料配布・動画配信・フォーラム・小テスト・課題提出・フィードバックなど様々な機能があり、学習者の学習履歴を閲覧することも可能です。![スクリーンショット 2020-10-17 21.05.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/a9578a88-8430-c2fc-1cd5-14104f6fa1cd.png)

## AWSを使ってMoodleの環境を構築する方法
### EC2でMOODLE入りのイメージを使うのが手っ取り早い
AWSのEC2（クラウド上の仮想マシン）を起動する時に、既にソフトウェアがインストールされているイメージを使うことができます。今回はAWS MarketplaceにあるMoodleのイメージをそのまま使いたいと思います。Marketplaceに存在する無料/有料の製品は、直接EC２内で起動することが可能です。

### 環境構築手順

### 1. まずは「インスタンスを起動」して「Moodle」を選択しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/2eeab3a3-cf05-ad94-ca3c-01545601e212.png)

・「インスタンスを起動」をクリック。
・地域の設置がこの時「東京」になっていることも併せてチェックしておく。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/98939dd8-43bf-a8f9-ae51-43014a88bae6.png" width="400">

・「Moodle Certified by Bitnami」を選択。
今回はBitnami(ビットナミー)が提供しているMoodleのイメージを使います。Bitnamiとは、簡単に言うとWebアプリケーションに必要な環境を構築してくれるソフトのことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/e9cc6faf-8489-86c0-6385-af360abc7686.png)



### 2. EC2インスタンスのスペックを選択しよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/397597ee-868f-0b9c-240b-1ec16db88158.png)

・インスタンスの大きさを選択。一人で利用するのであれば`t2.micro`で十分。
・「確認と作成」、「起動」をクリック。


### 3. SSHで利用するキーを作成しよう
・SSHで利用するキーの作成。
SSHとはサーバにファイルを転送したり、サーバの操作を直接行うために接続するキーになります。

### 4. Moodleサーバーを構築しよう
サーバが立ち上がると、`running`という項目が出てきます。これは起動できているということです。インスタンスを選択すると、パブリックDNSというのがあるので、その文字列をコピーしてブラウザのURL欄に張り付けて移動してください。Moodleの初期画面にたどり着きます。

### 5. 初期ユーザを取得しよう

Moodleの初期ユーザの確認はちょっと特殊です。
インスタンスを右クリックしてシステムログを見てください。その中の下のほうにMoodleの初期ユーザのパスワードが記述されております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/9cec66f4-e2d6-0ff7-4e28-90b0f58a5f67.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/2efd6572-d5fb-3502-39b0-1a5198305111.png)

### 6. MOODLEへログイン
Usernameと初期パスワードを入力してログインが完了！
Amazon Linux 2をVirtualBoxで実行する

何番煎じかわかりませんが、Amazon Linux 2をVirtualBoxで実行しました。

公式ドキュメントはこちらです。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/amazon-linux-2-virtual-machine.html

公式ドキュメントでは、カスタマイズしたseed.isoを作る手順が載っていますが、サンプルのseed.isoも用意されておりますので、こちらを使って起動してみます。

# 準備

ディスクイメージ(vdi)
https://cdn.amazonlinux.com/os-images/latest/virtualbox/

サンプルseed.iso
https://cdn.amazonlinux.com/os-images/latest/

2020/10/17時点では、`latest`は`2.0.20200917.0`にリダイレクトされます。

## サンプルseed.isoの内容

サンプルseed.isoでは、以下の設定がされています。

ホスト名　amazonlinux.onprem
ユーザー
　user1（パスワードamazon）
　user2（パスワードamazon）?
　user3（パスワード設定無し、sshのキー指定あり）
　ec2-user（パスワードamazon）

とりあえずseed.isoで起動して、後で設定を変えればいいような気もします。

# 仮想マシンの作成

入手したvdiファイルをハードディスクとして設定し、seed.isoを光学ドライブとして設定するだけです。

![スクリーンショット 2020-10-17 21.56.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/2839dd6e-b2e2-7ba6-da02-5cfc98266f74.png)

![スクリーンショット 2020-10-17 21.57.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/f4279d3b-cce2-b87e-b068-138bef6444b3.png)

# 起動

ec2-user（パスワードamazon）でログインできます。

![スクリーンショット 2020-10-17 22.24.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/ab65e969-3e65-4943-0377-44e96b9d4e27.png)

# おまけ　GUIとVNCをインストールする

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-2-install-gui/
に従い、mateデスクトップとTigerVNCをインストールし、GUIでアクセスしてみます。

```console
sudo amazon-linux-extras install mate-desktop1.x
sudo bash -c 'echo PREFERRED=/usr/bin/mate-session > /etc/sysconfig/desktop'

sudo yum install tigervnc-server

vncpasswd

sudo cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@.service
sudo sed -i 's/<USER>/ec2-user/' /etc/systemd/system/vncserver@.service
sudo systemctl daemon-reload
sudo systemctl enable vncserver@:1
sudo systemctl start vncserver@:1
```

かなり味気ない見た目ですが、VNCでアクセスできました。

![スクリーンショット 2020-10-17 22.48.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/34cc1344-c3fd-c3d0-4902-053559428e1b.png)
Semantic action内でmultimapに格納したデータをmulti-indexに格納

Boostには、multi-indexというスペックがあるらしい。

↓　テンプレートテクニックのポリシーのところを読んでいたら発見した。
https://www.sbcr.jp/product/4797376685/

multi-indexの部分を見てみる。。

    35typedef multi_index_container<
    36  session,
    37    indexed_by<
    38      ordered_unique<tag<linenumber>,   member<session, int, &session::linenumber> >,
    39      ordered_unique<tag<source_ipaddr>, member<session, std::string, &session::source_ipaddr> >,
    40      ordered_unique<tag<dest_ipaddr>, member<session, std::string, &session::dest_ipaddr> >,
    41      sequenced<tag<seq> >
    42      >
    43  > dictionary;

今週、Boost Semantic Actionからマルチマップ(multimap)に値を格納する
https://qiita.com/Ruo_Ando/items/c10cbb551f1ce616d139
を書いたが、semantic actionからmulti-indexへのインサートがうまくいかなさげなので、(*´Д｀)
マルチマップに格納したあとにマルチインデックスに格納することにした。

<pre>
   149    for (auto& x:m) {
   150      // std::cout << x.first << " => " << x.second << std::endl;                                                                                                                     
   151
   152          for (auto& y:m) {
   153            if(x.first == y.first && x.second != y.second)
   154              {
   155                // std::cout << x.first << "," << x.second << "," << y.second << std::endl;                                                                                           
   156                dict.insert(session(x.first, x.second,  y.second));
   157              }
   158          }
   159    }
   161    for (auto & it: dict.get<0>()) {
   162      std::cout << it.linenumber << "," << it.source_ipaddr << "," << it.dest_ipaddr << std::endl;
   163    }
</pre>

コードはこちら
https://github.com/RuoAndo/qiita/blob/master/ipaddress6.cpp

実行してみる。。。(IPアドレスはランダムに生成)
<pre>
$ cat random_data.txt 
"2019/07/02 02:02:00.839","2019/07/02 02:02:00","2019/07/02 02:02:00","841","255.178.167.132","25846","iy","69.215.218.225","51321","bu","8MP","VX13Gpdkt","drN","deETa","gyAY4gdZ","8","TJoPPQuOKvrxzAjCd11rpqqSqs","912","198","336","769","278","554","rand-pa1"
"2019/07/02 02:02:52.006","2019/07/02 02:02:52","2019/07/02 02:02:52","478","104.40.197.93","41214","ol","76.213.36.241","23907","Vu","OYF","H6zQlnN5X","yV3","P2VPw","9D3viFsS","5","cogAhSIycmvdYl7RaZNjGCsWqj","953","917","636","718","142","607","rand-pa1"
"2019/07/02 12:12:16.086","2019/07/02 12:12:16","2019/07/02 
$ ./a.out random_data.txt 
line:0 255.178.167.132:0
文字数：14
　内容：69.215.218.225,0
line:0 69.215.218.225:0
文字数：13
　内容：104.40.197.93,1
line:1 104.40.197.93:0
文字数：13
　内容：76.213.36.241,1
line:1 76.213.36.241:0
文字数：14
　内容：120.175.225.23,2
line:2 120.175.225.23:0
文字数：13
　内容：55.156.36.246,2
line:2 55.156.36.246:0
Displaying elements...
0,255.178.167.132,69.215.218.225
1,104.40.197.93,76.213.36.241
2,120.175.225.23,55.156.36.246
</pre>

（｀ー´）b
Laravel（7.20.0）でゲストログイン機能を実装

# はじめに
ポートフォリオ作成していくうえで、開発して終わりではもったいないと思います。
どうせなら作ったものを、ほかの人に触ってもらってフィードバックを受け、それをもとに改善していくことでより良いものを作ることが出来、かつ勉強にもなります。

とはいっても、自分も最初はなかなか作ったものを他人に見せる勇気がありませんでした。
最近では、友人や面接時に様々なフィードバックをいただき、日々改善しています。

そんな中、ログイン機能を実装しているアプリケーションの場合、アカウントを作成しログインする必要があります。
友達であればまだいいかもしれませんが、関係の浅い人（面接官など）の場合アカウントを作成しログインしてアプリケーションを触ることは手間がかかり***触ってもらえる機会を失ってしまうかもしれません。***
それはもったいない！！！

そこで今回は、ゲストログイン機能を実装したので軽くご紹介します！

# 前提
- すでにアプリケーションがあり、ログイン機能を実装している

# 流れ
とはいっても、そんなに難しいことをするわけでもありません。

やることとしては、
- ゲストログイン処理の実装
- 登録画面とログイン画面に、ゲストログインボタンを実装
- web.phpにてルーティングの実装

# ゲストログイン処理の実装

まず、Laravelの公式ドキュメントを見てみると

> Laravelの認証サービスにはAuthファザードでアクセスできます。クラスの最初でAuthファサードを確実にインポートしておきましょう。次にattemptメソッドを見てみましょう。
[認証7.x 自前のユーザー認証](https://readouble.com/laravel/7.x/ja/authentication.html)

とのことで、認証するにあたってAuthファザードのattemptメソッドを使えばよさそう。
今回はapp\Controllers\Auth\LoginController.phpにゲストログイン処理を実装する。

```LoginController.php

public function guestLogin()
{
    $email = 'hoge@hoge.jp';
    $password = 'hogehoge';

    if (Auth::attempt(['email' => $email, 'password' => $password])) {
        return redirect()->route('home');
    }

    return redirect('/');
}
```

attemptメソッドは、最初の引数として、キー／値ペアの配列を受け取ります。
今回は、メールアドレスとパスワードの配列を引数に指定します。こちらで指定している値（emailとpassword）を持つユーザーアカウントをデータベース内にあるか探す。
→当然ながら、あらかじめゲスト用アカウントデータを作成しておくこと！

認証が成功すれば、trueを返し失敗したらfalseを返す。

注意点としては、
> データベース中のハッシュ済みパスワードと比較する前に、フレームワークは自動的に値をハッシュ化するため、passwordへ指定する値はハッシュ化しないでください。

とのこと。より詳しく確認したい場合は、公式ドキュメントをご確認ください。

これでゲストログイン処理の実装が完了。

# ゲストログインボタンを実装
ゲストログイン処理を実装しても、肝心のゲストログインボタンを忘れたらできません。
そこで登録画面とログイン画面に、ゲストログインボタンを実装していきます！

```login.blade.php
<button type="submit" class="btn btn-secondary guest-btn">
　　<a href="/login/guest">Guest Login</a>
</button>
```

こんな感じで、register.blade.phpも同様に上記のコードを実装します。

これで終わりかと思いきや、まだ肝心のルーティングを用意していないためそちらを記載します。

# ルーティングの実装
web.phpにてルーティングを実装する。

```web.php
Route::get('/login/guest', 'Auth\LoginController@guestLogin');
```

これで完成。

# まとめ
今回は、Laravelにてゲストログイン機能を実装しました。
後回しにしていましたが、やってみるととても簡単でした。ちょっとした機能ではありますが、今回のようにユーザー目線で開発が行えるといいですね！
[PowerAutomate]自分のフォーム以外でもトリガーを設定する方法

PowerAutomateでFormsへの回答をトリガーとして実行する場合、以下のトリガーイベントを作成します。

![img_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145504/59a094b1-d827-7be2-cf53-11c8acb7dbad.png)

この時、候補に「自分のフォーム」で作ったものだけが出てきます。
しかし、グループで作ったフォームをトリガーとしたい場合どうしたら良いでしょうか？

## やり方

トリガーを設定したいフォームを開いてURLを確認してください。
このURLパラメータの`FormId=`から先の文字列をコピーします。

![img_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145504/57dbd28e-a0e5-b8a6-b424-e5fc8f1ccc76.png)

もしくは回答用URLの`id=`以降も同じ値になっています。

![img_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145504/11c72cf3-be6e-638f-3904-5d0bbee5bde2.png)

PowerAutomateに戻って、フォームID入力欄の候補から「カスタム値の入力」を選択後、上記でコピーした文字列を貼り付けます。

![img_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145504/6952338e-5f1e-b038-f9f3-bcccbd7065b8.png)

以上でグループで作成したフォームもトリガーを設定できる様になります。
ggplot2やGGallyをplotlyに楽に変換する



知らなかったのでメモがてら紹介

- 作図したものをインタラクティブにしたい
- plotlyが便利なのは知っているがplotly用のコード整形が面倒

#それ、ggplot2が使えれば実現できます



```r
#library(tidyverse)
library(dplyr)
library(ggplot2)
library(plotly)

g<- iris %>% 
  ggplot()+
  aes(x=Sepal.Length,y=Sepal.Width,color=Species)+
  geom_point()

#print(g)
ggplotly(g)
```




![gggs.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/7d31edf6-f163-202a-1369-d0b117bc3d90.gif)






「**ggplotly()**」これだけでplotlyになっちゃう。素敵。


GGallyだって


```r

library(GGally)

g<- iris %>% 
  GGally::ggpairs(data = ., aes(color = Species))

#print(g)

ggplotly(g)
```


![ggg.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d127b5ae-886e-5b92-3f5a-779403a2185a.gif)




#以上

便利
【画像処理】ポスタリゼーション

#1. 概要
画像処理の基本的な技術、「ポスタリゼーション」を紹介します。ポスタリゼーションとは、階段上のトーンカーブによる変換で、出力画素値を数段階に制限する手法です。

下図のように入力画像の画素値をn段階（下図は4段階）にして、出力画像の画素値を制限します。そうすることで境界線が鮮明になり、アートのような色合いを表現することが出来ます。

ポスタリゼーションは書籍[「ディジタル画像処理」](https://www.amazon.co.jp/%E3%83%87%E3%82%A3%E3%82%B8%E3%82%BF%E3%83%AB%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86-%E6%94%B9%E8%A8%82%E7%AC%AC%E4%BA%8C%E7%89%88-%E3%83%87%E3%82%A3%E3%82%B8%E3%82%BF%E3%83%AB%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86%E7%B7%A8%E9%9B%86%E5%A7%94%E5%93%A1%E4%BC%9A/dp/490347464X/ref=asc_df_490347464X/?tag=jpgo-22&linkCode=df0&hvadid=342595526565&hvpos=&hvnetw=g&hvrand=5492134153117811443&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009247&hvtargid=pla-889374643658&psc=1&th=1&psc=1"DIP")に記載されている処理方法を踏襲しています。処理後の画像に画素値0、255を残すようなトーンカーブを使用するのでコントラストのはっきりとした画像となっています。


![posterization.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565845/f3a85f88-7589-ad65-1460-1d1842ab03f8.jpeg)


#2. 環境

ポスタリゼーション処理を試した環境は以下となっています。

Python 3.6.8
numpy 1.18.1
matplotlib 3.1.2
opencv-python 4.1.2.30

ライブラリでOpenCVを使用するので事前にインストールをお願いします。

```
pip install opencv-python
```

#3. コード

ポスタリゼーションについていろいろなサイトを見てところ、多くのサイトでは画素値255のホワイトは出力画像に反映しないLUTを使用していました。

今回の処理は画素値255「ホワイト」も出力画像に反映しているので、LUT作りを工夫しました。
binsのインプットとアウトプットを分けたりしていますが、詳細はコードのコメント欄を参考にしてくださいね。


```posterization.py
#coding: utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt

def main():
    img = cv2.imread('image.jpg')                   #画像の読み込み
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)    #グレースケール化
    n = 4                                           # 画素値の分割数

    pos = posterization(gray, n)
    cv2.imwrite('pos.jpg', pos)          #ポスタリゼーションした画像の出力

def posterization(img, n):
    x = np.arange(256)                   #0,1,2...255までの整数が並んだ配列

    ibins = np.linspace(0, 255, n+1)     #LUTより入力は255/(n+1)で分割
    obins = np.linspace(0,255, n)        #LUTより出力は255/nで分割

    num=np.digitize(x, ibins)-1          #インプットの画素値をポスタリゼーションするために番号付けを行う
    num[255] = n-1                       #digitize処理で外れてしまう画素値255の番号を修正する

    y = np.array(obins[num], dtype=int)   #ポスタリゼーションするLUTを作成する
    pos_LUT(n, y)                         #LUTの図を作成
    pos = cv2.LUT(img, y)                 #ポスタリゼーションを行う

    return pos

#ポスタリゼーションのLUT図作成
def pos_LUT(n, y):
    x = np.arange(0,256,1)
    plt.plot(x,y)
    plt.savefig("pos_LUT.png")

if __name__=='__main__':
    main()
```

#4. 参考文献
★書籍
・[ディジタル画像処理[改訂第二版] （公益財団法人 画像情報教育振興協会（CG-ARTS））][0]
[0]:https://www.amazon.co.jp/%E3%83%87%E3%82%A3%E3%82%B8%E3%82%BF%E3%83%AB%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86-%E6%94%B9%E8%A8%82%E7%AC%AC%E4%BA%8C%E7%89%88-%E3%83%87%E3%82%A3%E3%82%B8%E3%82%BF%E3%83%AB%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86%E7%B7%A8%E9%9B%86%E5%A7%94%E5%93%A1%E4%BC%9A/dp/490347464X/ref=asc_df_490347464X/?tag=jpgo-22&linkCode=df0&hvadid=342595526565&hvpos=&hvnetw=g&hvrand=5492134153117811443&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009247&hvtargid=pla-889374643658&psc=1&th=1&psc=1

★サイト
・[OpenCV – cv2.LUT の使い方、ガンマ補正、ネガポジ反転、ポスタリゼーション][1]
[1]:https://pystyle.info/opencv-tone-transform/#outline__6
・[digitizeの使い方(numpy)][2]
[2]:http://arduinopid.web.fc2.com/Q3-36.html
Rubyの正規表現について（メタ文字、キャプチャ、関連メソッド）

#はじめに
　正規表現を覚え始めたため、その使い方について備忘も兼ねて記述します。

#サンプルコード
以下のようなプロフィールがあるとします。

```rb
text = <<TEXT
生年月日:1234年5月6日生まれ
郵便番号:789-1111
TEXT
```

#生年月日から数字のみを抽出したい場合

```rb
(\d+)年(\d+)月(\d+)日
#=> 1234,5,6 が抽出される。
#=>下は年月日の漢字もマッチしてしまう。
\d+年\d+月\d+日
#=>1234年5月6日
```
###正規表現のメタ文字の意味
**\d**　・・・　半角数字（桁は問わない）
**+**　 ・・・　直前の文字やパターンが1回以上連続している
**()**  ・・・　内部でマッチした文字列をキャプチャまたはグループ化
**年,月,日**　・・・メタ文字ではなく、ただの文字列

#郵便番号の間にハイフン"-"を除きたい場合

```rb
p text[/\d{3}-\d{4}/].gsub('-','')
#=>7891111
```
###正規表現のメタ文字やメソッドの意味
**/（正規表現）/**　・・・正規表現オブジェクトは／で囲んで作成する（「Rubyにおける正規表現リテラル」という）
**[]**・・・文字列から正規表現にマッチした部分を抜き出すStringクラスのメソッド。エイリアスメソッドは、**slice**メソッド。
**{3},{4}**・・・直前の文字（この場合は\d）が、{}で囲んだ数だけ連続する
**-**　・・・メタ文字ではなく、ただのハイフン。（ハイフンは、記述の仕方によっては「文字の範囲」を表す場合もあるため注意）
**gsub('第1引数','第2引数'）**・・・第1引数にマッチした文字列を第2引数の文字列で置き換える。上記の場合、文字列"-"を""（削除を意味する）に変換している。
なお、**slice**メソッドや**gsub**メソッドには、それぞれ「破壊的メソッド（※）」が用意されている。
（※）呼び出したオブジェクトの状態を変更してしまうメソッド。末尾に"!"を付ける。

#正規表現のテストができるツール
正規表現は、メタ文字を駆使するため試行錯誤できるツールがを使うと、視覚的に確認できます。
![reg_exp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698990/58cd969b-ba48-9af6-983b-958ca5c51abc.png)


https://rubular.com/

#終わりに
文字列の検索や置換で威力を発揮する正規表現。
近いうちに使いこなしたいと思い、まずは初歩的な学習内容を記述しました。
ここまで読んでくださり、ありがとうございました。
温度センサーとLEDで室温をぱっと見で分かるものを作ってみた

# 目的
温度センサーとLEDを使ってみたかったので、2つを同時に使って色で室温がぱっとわかるものを作ってみました。


# 実現方法
### 使用したもの
・obniz Board 1Y
・高精度IC温度センサー LM60BIZ
・マイコン内蔵RGB 8mmLED PL9823-F8

### ロジック
個人的には25℃をより下だと涼しい、25℃より上だと暖かいだと感じているので
　温度センサーで取得した温度が25℃より大きい場合、<strong><font color="DarkOrange">オレンジ</font></strong>
　それ以外の場合、<strong><font color="DeepSkyBlue">水色</font></strong>
にしました。
obnizへは
　温度センサー　0、1、2　へ接続
　LED　9、10、11　へ接続
しています。

# 実際に動かしてみた
実際に動かした動画をTwitterにあげてます！
※温度センサーに指を近づけて、温度をわざとあげました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">温度センサーとLEDを組み合わせてみました！<a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> <a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/r4dY4U0bHI">pic.twitter.com/r4dY4U0bHI</a></p>&mdash; heihei (@heihei15408697) <a href="https://twitter.com/heihei15408697/status/1317447404145111040?ref_src=twsrc%5Etfw">October 17, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# コード
```Javascript
const Obniz = require('obniz');
const obniz = new Obniz('ObnizのID');  // Obniz_IDに自分のIDを入れてください

obniz.onconnect = async function () {
    // 温度センサの利用
    const tempsens = obniz.wired('LM60', { gnd: 0, output: 1, vcc: 2 });
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 9, vcc: 10, din: 11 });

    // setIntervalで間隔を作る
    setInterval(async function () {
        // 同期で取得
        const temp = await tempsens.getWait();

        if (temp>25) {
            // オレンジ
            rgbled.rgb(255, 165, 0);
        } else {
            // 水色
            rgbled.rgb(0, 191, 250);
        }

        // ターミナル表示
        console.log('obniz temp:', temp);
        // 温度をコンソールに表示
        console.log(temp);
        // obnizディスプレイ表示
        obniz.display.clear();
        obniz.display.print(temp + 'C');
    }, 10000); // 10000ミリ秒 = 10秒
}
```


# 考察
最初は温度センサーとLEDを組み合わせるのはハードル結構高いのかなと思ったのですが、obnizを使うと簡単にできることを体験することができました！（2時間くらいで出来ました！）
・今は25℃固定ですが、徐々にLEDの色を変えていく
・LINEなどのツールを使って、温度確認したときに色がでるようにする
などいろいろ発展させていければと思っています！
UIViewをコードからPreview可能にする。

# 先に結論

テストとかの時にデバッガからViewを見れたら便利になるよってお話。

![スクリーンショット 2020-10-17 22.17.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117659/73f5480c-4e03-df5e-6d1b-d0f5b0b29b74.png)

# `debugQuickLookObject`

Xcodeの機能として、独自クラスを見やすく表示する`debugQuickLookObject `という機能がある。

この機能はBreak Pointで止めている最中にObjectのプレビューを可能にするものであり、テキストや画像、URLなんかをPreviewできる。

```swift
@objc func debugQuickLookObject() -> Any? {
    URL(string: "https://www.google.co.jp/")
}
```

このようにURLを返せば

![スクリーンショット 2021-02-26 15.39.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117659/ee4636be-2c1b-e0c9-9e56-519fdb590896.png)

ページが表示される

じゃあこれでリアルタイムの`UIView`を表示できたら楽しそうという考え。

# 実装

`debugQuickLookObject`を実装する。

Swift4.0あたりから`@objc`をつけないと動かなくなってる。

### iOS

```swift
extension UIView {
    @objc func debugQuickLookObject() -> Any? {
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
        drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }
}

```

### mac

```swift
extension NSView {
    @objc func debugQuickLookObject() -> Any? {
        guard let rep = self.bitmapImageRepForCachingDisplay(in: bounds) else { return nil }
        self.cacheDisplay(in: self.bounds, to: rep)
        
        guard let cgImage = rep.cgImage else { return nil }
        return NSImage(cgImage: cgImage, size: bounds.size)
    }
}
```

これでLLDBデバッガでbreakpointを貼って止めて、目のマークを押すと

![スクリーンショット 2020-10-17 22.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117659/9de4f57f-0da5-dda5-c52e-e2e6e750b4b3.png)


Viewの内容をPreviewできる。


![スクリーンショット 2020-10-17 22.17.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117659/e265b965-5967-1db8-8cec-d31b8ee88240.png)
SSH接続しているリモートがVSCodeで開けなくなった。

突然のこと。
VSCodeでSSH接続しているリモートが開かなくなった。
具体的には、SSH接続はしているが下記のようなエラーが延々と現れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/1c6b6231-fcfc-9c58-eefc-574ba23d3643.png)

- 原因が分かる方いましたらご教授ください

「More Info」で飛んだ先のページもよくわからなかったので、いろいろ試してみることにした。→　[More Infoで飛ばされたページ](https://code.visualstudio.com/docs/remote/linux#_remote-host-container-wsl-linux-prerequisites)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/0875b082-18ec-bf7a-66cb-42402b5fc92e.png)



### 試したこと

1. PC再起動

1. opensslをアップグレード

1. VSCodeの拡張機能を再インストール

1. 拡張機能でSSH再接続 → なおった


## 1. PC再起動

困ったときは再起動！

→ なおらない

## 2. opensslをアップグレード

「[VSCode Remote SSH接続できない](https://qiita.com/y-mattun/items/3af358ba784c6af56c0c)」を参考にopensslをアップグレード！

- opensslとは暗号化通信に使われるソフトウェアのことで、サーバーに通信するためにクライアント側に用意されている鍵のようなもの。

→　なおらない

## 3. VSCodeの拡張機能を再インストール

SSH接続するファイルを開く際に使っていた拡張機能「Remote-SSH」をアンインストール＆再インストール！

- 手順

 1.  VSCodeを開く
 1.  左のメニュータブから拡張機能を選択する
 1.  インストール済みの中から「Remote-SSH」を選択してアンインストールする
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/848e67fd-f49b-bb45-2516-09c2eaaa19b4.png)
 1.  再インストールして有効にする

→ なおらない

## 4. 拡張機能でSSH再接続

先ほど有効にした拡張機能でSSH接続を再実行！

- 手順
 1.  左下の緑のマークをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/9b3b52d3-3853-3f99-a8b6-76d924478f99.png)
 1.  「Remote-SSH: Connect to Host...」を選択する
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/ff169cf7-536c-f185-f473-990be933e431.png)
 1.  接続したいホスト名を選択する

→ なおった！

### その後

原因は追求していない。
その後は下記の普段使っているSSH接続方法で問題なく接続できるようになった。

```shell:ターミナル
$ ssh [ 接続したいホスト名 ]
```
Pylintを実行して結果を読む

以下のソースコードに対してPylintをかけてみる。

```python
A = 10

print(A)
```


実行コマンドは以下です。-rnをつけると余計なログを出力しないようにできるらしい。

```console
pylint -rn test.py
```

実行結果は以下です。

```consol
************* Module test
test.py:1:0: C0111: Missing module docstring (missing-docstring)

-------------------------------------------------------------------
Your code has been rated at 5.00/10 (previous run: 10.00/10, -5.00)
```

5.00/10 点でした。docstringがないと怒られました。
ソースコード品質の根拠にするためには信頼できそうですが、100点を目指すのは難しそうです。。。
【After Effects】Motion Tools 2インストールに失敗する時の対処法

After Effectsには`Motion Tools 2`という便利無料プラグインがあります。`Window -> Motion Tools 2.jsxbin`から以下のパネルが開きます。

<img src=https://user-images.githubusercontent.com/144386/96330630-b6e9a580-1091-11eb-99d4-dd12bdb7f617.png width=250 />

僕は、選択オブジェクトのピボットを変更する機能(赤枠部分)ぐらいしか使っていませんが、これだけでもかなり制作効率を上げてくれます。

プラグインファイルの入手方法自体は、記事下部の参考リンクをご参照ください。

以下本題です。

## Motion Tools 2のインストールに失敗した時の対処法

インストールは手順通り`Motion Tools 2.jsxbin`を`Scripts/ScriptUI Panels`に入れます。

その後、Motion Tools 2を起動しようとすると以下のエラーが発生します。

<img src=https://user-images.githubusercontent.com/144386/96229357-be497a00-0fd1-11eb-85cb-771251cdbd9a.png width=350 />

> Network access disabled. To allow, please go to Preferences > General and check off 'Allow Scripts to Write Files and Access Network' to resolve.

このようなエラーが出た場合は、エラー内容に沿って対処していきます。

## アプリケーションのスクリプト設定の変更

`環境設定 -> スクリプトとエクスプレッション`を選びます。

<img src=https://user-images.githubusercontent.com/144386/96329498-7df90300-1088-11eb-8d15-510d583b889e.png width=450 />

`スクリプトによるファイルへの書き込みとネットワークへのアクセス許可`にチェックを入れれます。

<br />

再度Motion Tools 2を起動すれば動くようになるはずです。



## 参考サイト

- [【After Effects】Motion Tools 2 ダウンロード・インストール方法 | Adobe信者NEXTistの動画編集が楽しくなる小ネタブログ（NEXTist Skill Box）](https://nextist.net/motion-tools-2/)
AWS lightsail+お名前ドットコム、で30分でWordPress立ち上げ：チュートリURLと注意点メモ


ほぼこの手順。
https://lightsail.aws.amazon.com/ls/docs/ja_jp/articles/amazon-lightsail-tutorial-launching-and-configuring-wordpress#create-a-wordpress-instance

注意点
・SSH接続するまでに、5分くらい待つ必要あり
・ドメインを買うのは、amazon routeからだと高いから、お名前ドットコムとかが良いと思う。
（amazon route→11ドル、お名前ドットコム→セールで140円）
・静的IPに紐付けした後は、WordPress管理画面のドメインもそっちになるから注意
・最初、英語表記になる（設定で変えられそうだけど、別に不便がないからこのまま）
Windowsでの.pyファイルの実行方法いろいろ

# 普通の.pyファイルの実行方法
Windows環境でのラッパーファイル作成方法を書く。
普通ならコマンドプロンプト等から実行する場合こうするはずだ。（python.exeのあるディレクトリのPATHが通ってる前提）

```
C:\Users\testuser> python C:\Users\testUser\pyruntest.py
→pyruntest.pyの実行結果が出る
```
しかし.pyファイルにpython.exeを関連付けされてなければ、こうはできない。

```
C:\Users\testuser> pyruntest.py
→エラー
```

## 1. batファイル or cmdファイルでラッパー作る

```
@echo off
%PYTHONPATH%\python.exe %~dp0\%~n0.py %*
```

例えばpyruntest.batというファイル名で上記を保存しておいたら
pyruntest.batと同じディレクトリにあるpyruntest.pyを次のように実行できる。

```
C:> pyruntest.bat
→pyruntest.pyの実行結果が出る
```

Pathを通しておけばどこからでも行ける
.batと打つのも面倒ならば拡張子を.cmdに変えればよい。

```
C:> pyruntest
→pyruntest.pyの実行結果が出る
```

## 2. C#でexeを作る。
1.の方法で大抵は問題ないのだが、処理させたい複数のファイルを引数として処理させるために
.cmdへドラッグアンドドロップさせたりしたときに割とこんなエラーが出る。

```powershell
コマンドに指定したコマンドライン引数が多すぎます。正しい値を指定して、再度実行して下さい。
```

原因はcmd.exeの制限? 2047文字 or 8191文字(WinXP以降)が最大のようです。
powershellならこの上限はないのだが、.ps1をダブルクリックで実行させるには更にいばらの道。。
なんとお粗末なターミナルなのだろうか、、コマンドプロンプトだのPowershellなんてこの世から無くなってくれれば良いのにと思う。
exe化してしまえば解決できるはず。

そんな時に多分使える手段としてはもう、exe実行形式にするしかないだろう。
どうやってexe化するか色々手段があるのだが、

* pyInstallerやpy2exeで作る  -> ファイルサイズがMB単位にバカデカいexeになってしまう。
* C言語で書く  ->  開発環境構築が大変 eclipseやVisual Studioなんて入れたくない
* C# & csc   -> Windows10からは標準でcsc.exeが入ってる
* JavaScript & jsc   -> Windows10からは標準でjsc.exeが入ってる

結局Javascriptで作ろうと思ったが挫折、C#で作ることになった。

### pyruntest.cs
C#初心者でよくわからないことが沢山あるがとりあえず動いたので晒す。

```c#
using System;
using System.Diagnostics;
using System.ComponentModel;

class Program
    {
    static void Main(string[] args)
    {
	    // Python Program Path
	    var pythonScriptPath = System.Reflection.Assembly.GetExecutingAssembly().Location.Replace(".exe", "") + ".py";
	    
	    try
	    {
	        var startInfo = new ProcessStartInfo()
	        {
	            FileName = @"python.exe",
	            UseShellExecute = false,
	            Arguments = "\"" + pythonScriptPath + "\" \"" + string.Join("\" \"", args),
	    	};
	    	
		    using (var process = Process.Start(startInfo))
	        {
	            process.WaitForExit();
	        }

		}
    	catch (Win32Exception)
    	{
    		Console.WriteLine("python.exeが見つかりませんでした。環境変数PATHに追加してください");
    	}

    }
}
```

csc.exeでコンパイルするとpyruntest.exeができる

```
C:\Users\testuser> C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe pyruntest.cs
C:\Users\testuser> pyruntest.exe
→pyruntest.pyの実行結果が出る
C:\Users\testuser> pyruntest
→もちろんこれでもpyruntest.pyの実行結果が出る
```

ちゃんと環境変数パスを通してあげとけばカレントディレクトリ関係なく実行できる

```
C:\Users\testuser> set PATH=%PATH%;%CD%
C:\Users\testuser> setx PATH %PATH%
C:\Users\testuser> cd \
C:> pyruntest
→pyruntest.pyの実行結果が出る
```

方法1も方法2も共通の仕組みで、
上記実行方法共通的な仕様：[実行させたい].pyと同じディレクトリに[実行させたい].bat or [実行させたい].cmd or [実行させたい].exeを置く。(ラッパーのソースを毎回修正する必要はないようにした)

余談）なぜこんなことをしてるかというと自宅PCなら関連付け設定すれば終わりだが、
　　　仕事用のシンクライアント環境だと権限がなく設定変更できなかったので、
　　　こういった回りくどいラッパーが必要になってしまうのである。不便な世の中になってしまった。
Rails ブラウザ上で、ルートを確認する

# はじめに
今回は、ブラウザ上でルートの確認の仕方について学習します。

普段は、ターミナルにrails routesをたたき、確認していました。

```
$ rails routes
      Prefix Verb   URI Pattern               Controller#Action
sessions_new GET    /sessions/new(.:format)   sessions#new
        root GET    /                         static_pages#home
        help GET    /help(.:format)           static_pages#help
       about GET    /about(.:format)          static_pages#about
     contact GET    /contact(.:format)        static_pages#contact
      signup GET    /signup(.:format)         users#new
             POST   /signup(.:format)         users#create
       login GET    /login(.:format)          sessions#new
             POST   /login(.:format)          sessions#create
      logout DELETE /logout(.:format)         sessions#destroy
       users GET    /users(.:format)          users#index
             POST   /users(.:format)          users#create
    new_user GET    /users/new(.:format)      users#new
   edit_user GET    /users/:id/edit(.:format) users#edit
        user GET    /users/:id(.:format)      users#show
             PATCH  /users/:id(.:format)      users#update
             PUT    /users/:id(.:format)      users#update
             DELETE /users/:id(.:format)      users#destroy
```

# ブラウザ上で確認する方法

(http://localhost:3000/rails/info/routes)

こちらにアクセスするだけです！

左の列から
-Helper
-HTTP Verb
-Path
-Controller#Action

となっていて、構成はターミナルと変わりません。

こちらの方が見やすいですね！
.zsh_historyをシンボリックリンクにしようとすると無限ループにハマるのを阻止する

# 事象
`.zsh_history` をDropbox などで保存しておき、シンボリックリンクでリンクさせようとしたことはないだろうか。

```bash
ln -s ~/Dropbox/zsh/zsh_history .zsh_history
```

のような感じで。簡単にシンボリックリンクが作れると思うだろう。


しかし次のようなエラーになる。

```bash
ln: .zsh_history: File exists
```

「おお、ファイルを削除し忘れたかな」と思い、削除したとしよう

```bash
rm -f .zsh_history
```

そして再度リンクを作ろうとする

```bash
ln -s ~/Dropbox/zsh/zsh_history .zsh_history
```

しかし、

```bash
ln: .zsh_history: File exists
```

なぜだ…。

これは、コマンドを実行した時点でhistoryファイルが作成されるためである。

つまり、

コマンドを書いてEnter => ヒストリーファイル作成 => コマンド実行

の順番なので常に `.zsh_history` ファイルが存在してしまうのである。

**何この無限ループ...**


# 解決方法

```
export HISTFILE=/path/to/dropbox_file
```

~~別の適当なファイルをHISTFILEにしてからやることで、この問題は解決する。~~
~~簡単けど、色々考えさせられて面倒ですね。~~

Dropbox上のファイルにHISTFILEが向くように .zshrc などで修正するのが良さそう。
Raspbian(buster)にdockerとdocker-composeをインストールする

新しく購入したラズパイにdockerとdocker-composeの環境を構築したので、備忘録として残します。

# 実行環境
Raspberry Pi 4
メモリ : 4GB
OS : Raspbian GNU/Linux 10 (buster)

# dockerのインストール

## 既存の環境のdockerを削除

真っ新な環境なので、ないと思いますが念のため

```shell
sudo apt remove -y docker docker-engine docker.io containerd runc
```

## パッケージの更新

```shell
👉 sudo apt update
```

## dockerのインストール

以下のコマンドでrootユーザーになって、インストール用スクリプトを取得して実行

```shell
👉 su -
👉 curl https://get.docker.com | sh
```

実行後、以下のコマンドで入っていることを確認

```shell
👉 docker -v
Docker version 19.03.13, build 4484c46
```

## rootユーザー以外でも利用できるようにする

現状では、一般ユーザーはdockerを使えません。

```shell
👉 grep docker /etc/group
docker:x:995:
```

なので、以下のコマンドで利用できるユーザーを設定します。
今回はreishisuというユーザー名を追加してみました。

```shell
👉 usermod -aG docker reishisu
```

そして、もう一度確認するとreishisuというユーザーが追加されていることがわかります。

```shell
👉 grep docker /etc/group
docker:x:995:reishisu
```

# docker-composeのインストール

公式サイトでは、以下のように書かれており64bitでのインストール方法しかありませんでした...🥺
>
[公式ページ](https://docs.docker.com/compose/install/)より引用
- You can run Compose on macOS, Windows, and 64-bit Linux.
>

ですが、直接GitHubからリポジトリをcloneして実行すればインストールできます。

## リポジトリをcloneしてくる

```shell
👉 su -
👉 git clone https://github.com/docker/compose.git
```

## 最新のバージョンにチェックアウト

2020/10/17現在だと "1.27.4" です。

```shell
👉 cd compose
👉 git checkout -b 1.27.4
```

## ビルドする

めちゃくちゃ時間がかかりますが、気長に待ちましょう(自分の環境だと15分くらいかかりました)

```shell
👉 ./script/build/linux
```

## バイナリをコピーしてコマンドを実行できるようにする

ビルドが完了するとdistという名前のディレクトリが作成されているので、移動してバージョンを確認してみます。

```shell
👉 cd dist
👉 ./docker-compose-Linux-armv7l version
docker-compose version 1.28.0dev, build a24843e1
docker-py version: 4.3.1
CPython version: 3.7.7
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019
```

なので、docker-composeというコマンドとしてどこからでも実行できるように、binフォルダにコピーします。

```shell
👉 cp docker-compose-Linux-armv7l /usr/local/bin/docker-compose
```

コピーが完了すると、どこからでもdocker-composeコマンドが使えるようになってます。

```shell
👉 cd
👉 docker-compose version
docker-compose version 1.28.0dev, build a24843e1
docker-py version: 4.3.1
CPython version: 3.7.7
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019
```

# 一般ユーザーでも実行できるようにする

パーミッションを755に変更して、rootユーザー以外も読み取りと実行をできるようにします。

```shell
👉 chmod 755 /usr/local/bin/docker-compose
```

こんな感じになってたらOKです！！

```shell
👉 ll /usr/local/bin
合計 7.8M
-rwxr-xr-x 1 root root 7.8M 10月 17 21:34 docker-compose
```


これでdockerとdocker-composeのインストールは完了です。

お疲れ様でした！！
Linux: 強制ロック(mandatory lock)

Linuxでファイルの強制ロック(mandatory lock)をする方法です。

## 強制ロックとは

* アドバイザリロックとは異なり、Linux固有の機能。POSIXやUNIXにはない。
* ロックを掛けたプロセス以外からの、read()やwrite()をできなくする。
* race conditionが発生する可能性があったりして、ロックの信頼性は高くない。ロックと同時にreadやwriteが獲得されると、ロック中なのに読み書きできてしまうらしい。

## 強制ロックが有効になる環境を作る

強制ロックを有効にするには、2つの条件を満たす必要があります。

1. ロックされるファイルは`-o mand`でマウントされたファイルシステムでないとならない。
2. ロックされるファイルは、set-group-IDビットがOnで、group-executeビットがOffでないとならない。


```bash
mkdir dir
mount -t tmpfs -o mand,size=1m tmpfs ./dir
chmod g+s,g-x dir/lockfile
echo hello > dir/lockfile
```

## 強制ロックを発動する

強制ロックを発動するために、システムコールを呼び出すPythonスクリプトを作ります。

```lock.py
#!/usr/bin/env python
import fcntl, os, time, sys
f = open(sys.argv[1], "r+")
fcntl.lockf(f, fcntl.LOCK_EX)
print(f.readlines())
time.sleep(10)
```

このlock.pyは、10秒間dir/lockfileを排他的強制ロックします。lock.pyを実行している10秒間の間に、他のプロセスからdir/lockfileを読み込もうとすると、pythonのプロセスが終了するまで待たされます。

```bash
# ロックする
./lock.py

# 別ターミナルで
cat dir/lockfile # 10秒程度待たされる
```

この10秒間に、`lslocks`や`/proc/locks`を確認すると、ロックが掛かっている事がわかります。

```
root@vagrant:~/dir# lslocks
COMMAND           PID  TYPE SIZE MODE  M START END PATH
lvmetad           463 POSIX   4B WRITE 0     0   0 /run/lvmetad.pid
cron              866 FLOCK   4B WRITE 0     0   0 /run/crond.pid
atd               848 POSIX   4B WRITE 0     0   0 /run/atd.pid
lxcfs             849 POSIX   4B WRITE 0     0   0 /run/lxcfs.pid
iscsid           1135 POSIX   5B WRITE 0     0   0 /run/iscsid.pid
python           1818 POSIX   0B WRITE 1     0   0 /dev/pts/0
☝🏻ここ

root@vagrant:~/dir# cat /proc/locks
1: POSIX  MANDATORY WRITE 1818 00:2c:3 0 EOF 👈🏻ここ
2: POSIX  ADVISORY  WRITE 1135 00:13:1503 0 EOF
3: POSIX  ADVISORY  WRITE 849 00:13:1498 0 EOF
4: POSIX  ADVISORY  WRITE 848 00:13:1487 0 EOF
5: FLOCK  ADVISORY  WRITE 866 00:13:1485 0 EOF
6: POSIX  ADVISORY  WRITE 463 00:13:1258 0 EOF
```

## 参考

- [File locking in Linux](https://gavv.github.io/articles/file-locks/#mandatory-locking)
【Vue.js】 transitionを使用してfade-in, fade-out

##【ゴール】
【Vue.js】 transitionを使用してfade-in, fade-out

![画面収録 2020-10-17 21.08.19.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620689/54de2f20-e7e9-6ec3-4b13-656478b67c54.gif)


##【環境】
`mac catarina 10.156`
`Vue.js v2.6.12`

##【実装】

`
■ifで条件分岐
■transition　name="fade"で、fadeモードに
`

```js:Helloworld.vue

<template>
  <div>
    <h2>hi</h2>
    <button @click="show = !show">変更</button>
    <transition name="fade" >
      <p v-if="show">trasition</p>
    <transition>
  </div>
<template>

<script>

export default ({
  data(){
    return {
      show: true       
    }
  }
})
</script>

<style scoped>

.fade-enter-active,
.fade-leave-active {
  transion: opacity 0.5s;
}


.fade-enter,
.fade-leave-to{
  opacity: 0;
}

</style>

```

以上



##【まとめ】

■transitionでアニメーションを作成
■nameでアニメーションの種類を指定してあげる
■style内でtransitionの設定をする

##【オススメ記事】

■ 【Vue.js】クリック処理　@click
https://qiita.com/tanaka-yu3/items/e578cadf35a7bc024770

■ 【Vue.js】 IF文・For文　条件分岐、繰り返し処理
https://qiita.com/tanaka-yu3/items/0ccf9a11525331b764de

■ 【Vue.js】 vue-routerを利用してルーティング作成し画面遷移を！！
https://qiita.com/tanaka-yu3/items/1b1f5f2b2d9638f50d33
【Flutter/ Dart】スプラッシュ画像

## 概要
アプリ起動時に表示されるスプラッシュ画像の実装方法です。

## 手順

1. flutter_native_splash をインストール

  https://pub.dev/packages/flutter_native_splash/install

2. 設定を追加

```.yaml:pubspec.yaml
flutter_native_splash:
  image: "images/logo.png"
  color: "cccccc"
```


3. `pub get`
4. `flutter pub pub run flutter_native_splash:create`
ArchiverがZIPに含めるファイルをフィルタする

NodeモジュールArchiverは、ディレクトリをZIP圧縮するとき、ZIPに含めるファイルをフィルタすることができます。
（できないと思い込んでて、普通にできた。。）

# ZIP圧縮するディレクトリ
以下のディレクトリをZIP圧縮するとします。

```:ZIP圧縮するディレクトリ
somedir
│  file1.txt
│
├─dir1
│      file2.jpg
│      file3.txt
│
└─dir2
        file4.jpg
        file5.txt
```

# プログラム
プログラムは以下になります。
ディレクトリをZIP圧縮するために<code>directory</code>関数を使いますが、第3引数にフィルタする関数を渡せます。
フィルタする関数の引数には、ZIP圧縮に含めるフォルダ・ファイルのデータが渡されます。
このデータをみて、含める場合データを返し、含めない場合<code>false</code>を返します。
サンプルでは拡張子<code>.txt</code>のファイルを含めないようにしています。

```javascript:サンプル
const fs = require('fs')
const path = require('path')
const archiver = require('archiver')

const output = fs.createWriteStream(__dirname + '/somedir.zip')
const archive = archiver('zip', {
  zlib: { level: 9 }
})

output.on('close', function() {
  console.log('finish')
})

archive.pipe(output)

archive.directory('somedir', 'somedir', filter)

archive.finalize()

function filter(entry) {
  if (path.extname(entry.name) === '.txt') {
    // zipに含めない場合falseを返す
    return false
  } else {
    // zipに含める
    return entry
  }
}
```

# ZIP圧縮されたディレクトリの中身
ZIP圧縮されたディレクトリを解凍し、中身を見てみると、以下になります。
拡張子<code>.txt</code>のファイルはZIPに含まれていません。

```:解凍したディレクトリ
somedir
├─dir1
│      file2.jpg
│
└─dir2
        file4.jpg
```

# 非同期でフィルタできない
<code>directory</code>関数に渡すフィルタ関数ですが、<code>Promise</code>を返せません。
<code>async</code>/<code>await</code>が使えず、非同期でフィルタができません。
（これはちょい残念かも）