OmniAICreator/Qiita-1.07M huggingface dataset:
line bot上で数字を絵文字として表示したい

#はじめに
line bot上で表示する数字を、絵文字の数字で表示させてみようと思い実装。
bot内で数字を表示したいと思ったときに使えると思い備忘録メモ。
動作イメージはこんな感じです、改行の文字数カウントの挙動を見るため、一桁の時は敢えて改行するようにしています。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666990/74c3ab3b-f61a-e33b-f663-2802eab5b293.png">


#備忘録
##基本的なお作法
Visual Studio Codeで実装し、ngrokでトンネリングして実行。
この部分はline botとのやりとりをする上での基本的なコードです。

```js

'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: 'チャンネルシークレット',
    channelAccessToken: 'アクセストークン'
};

const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);

    //ここのif分はdeveloper consoleの"接続確認"用なので削除して問題ない。
    if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
        res.send('Hello LINE BOT!(POST)');
        console.log('疎通確認用');
        return; 
    }

    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

async function handleEvent(event) {
  //ここに色々書く
}
```

##数字を絵文字に変換する
ここが今回大事な部分。
数字を引数にして絵文字を返すようなmake_emoji_num関数を実装。
indexはtextの左から何文字目の$を置き換えるかの番号で、改行を意味する"\n"は1文字判定らしい。

```js
async function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  var reply_dic = make_reply(event.message.text)
  return client.replyMessage(event.replyToken, reply_dic);
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);
![Screenshot_20201105-163114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666990/8cfc7cb2-3307-35dc-7445-579476e7f81c.png)

function make_reply(num){
  var reply_dic= {
        "type": "text",
  }

  var product_id = "5ac21b4f031a6752fb806d59"
  var emojiID_list = ["062","053","054","055","056","057","058","059","060","061"];
  var junokurai = Math.floor(num / 10);
  var ichinokurai = num % 10;
  var emoji_list = [];

  if (num >= 10){
    reply_dic["text"] = "$$"
    
    emoji_list.push(
      {
        "index": 0,
        "productId": product_id,
        "emojiId": emojiID_list[junokurai]  
      }
    )
    emoji_list.push(
      {
        "index": 1,
        "productId": product_id,
        "emojiId": emojiID_list[ichinokurai]  
      }
    )
    reply_dic["emojis"] = emoji_list;
    console.log(reply_dic);
  }else if (num < 10){
    reply_dic["text"] = "\n$"

    emoji_list.push(
      {
        "index": 1,
        "productId": product_id,
        "emojiId": emojiID_list[ichinokurai]  
      }
    )
    reply_dic["emojis"] = emoji_list;
  }

  reply_dic.text += "テスト"
  return reply_dic;

}

```

##その他便利な資料たち
・よさげなline botを作るための自分用メモ
　https://qiita.com/canonno/items/bb71c3d7e308cb8337a1

・line bot絵文字IDリスト
　https://d.line-scdn.net/r/devcenter/sendable_line_emoji_list.pdf

・Textを送る場合のAPIリファレンス
　https://developers.line.biz/en/reference/messaging-api/#text-message
【JS】アロー関数の波カッコ有無の違い

アロー関数を書いていて、矢印の後に波カッコ`{ }`をつける場合と付けない場合で出力が変わってくる。

<br>

```js:波カッコなしの例
arr = [1,2,3,4,5]
arr1 = arr.map((x)=> x*2)

//出力　[2, 4, 6, 8, 10]
```

```js:波カッコありの例
arr = [1,2,3,4,5]
arr1 = arr.map((x)=> {x*2})

//出力 [undefined, undefined, undefined, undefined, undefined]
```


<br>

##波カッコを使うメリットと注意点

波カッコを使うメリットは、**複数の式を記述できる**こと。

波カッコを使う場合は必ず`return`が必要になる。

```js:波カッコありの例
arr = [1,2,3,4,5]
arr1 = arr.map((x)=> {return x*2})

//出力　[2, 4, 6, 8, 10]
```


<br>
##波カッコを使った例

下記のように、複数の式を記述できるようになる。

```js:波カッコあり
arr = [1,2,3,4,5]

arr2 = arr.map((x)=> {
    x = x*2,
    x = x+1
    return x
    })

console.log(arr2)

//出力
 [3, 5, 7, 9, 11]
```


<br>
##波カッコが不要な場合
一つの式でかける場合は波カッコ不要。returnも省略できる。

```js:波カッコなし
arr = [1,2,3,4,5]

arr3 = arr.map((x)=> x*2+1)

console.log(arr3)
// [3, 5, 7, 9, 11]
```


<br>
**▼省略しない場合**

```js:波カッコ省略しない場合
arr = [1,2,3,4,5]

arr3 = arr.map((x)=> {return x*2+1})

console.log(arr3)
// [3, 5, 7, 9, 11]
```

<br>
なお、returnなしで波カッコを付けてしまうと、欲しい出力は得られない。

```js:returnなし
arr = [1,2,3,4,5]

arr4 = arr.map((x)=> {x*2+1})

console.log(arr4)
// [undefined, undefined, undefined, undefined, undefined]
```

いっそエラーになってくれるとわかりやすいのだが、エラーにはならないので注意が必要。



<br>
<br>
##追記

ついつい難解な気がして避けがちなmozillaの説明を読み解いてみる。


**▼ページの内容**

```:基本的な構文
(param1, param2, …, paramN) => { statements } 
(param1, param2, …, paramN) => expression
// 上記の式は、次の式と同等です: => { return expression; }

// 引数が 1 つしかない場合、丸括弧 () の使用は任意です:
(singleParam) => { statements }
singleParam => { statements }

// 引数がない場合、丸括弧を書かねばいけません:
() => { statements }
```

＞[アロー関数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions)


<br>
**▼内容確認**

```:1つめ
(param1, param2, …, paramN) => { statements } 
(param1, param2, …, paramN) => expression
(param1, param2, …, paramN) => { return expression; }
```

・`(param1, param2, …, paramN)`
引数をparamで表している。数は任意。

・`statements`
文。実行する処理のことをいう。
変数宣言や代入、四則演算などが文にあたる。

```js:文
var x, y, z;
x = 5;      
y = 6;      
z = x + y;  
```

実行する命令のリスト。
＞[W3C statements](https://www.w3schools.com/js/js_statements.asp)



・`expression`
式。一意の値を返すもの
結果が数値、文字列、true/falseになるものが式。

```:式
1 / 2
i -= 2
i * 2
'A ' + 'string'
2
0.02
'something'
true
false
[1,2,3]
{}
a && b
a || b
!a
```

＞[flaviocopes JS expressions](https://flaviocopes.com/javascript-expressions/)


・` { return expression; }`
expressionにreturnをつけると文（statement）として扱うことができる。



<br>
###まとめ
英語のそもそもの意味を理解する必要があった。。

・statements: 文。（AをBにするといった命令）
・expression: 式。（一意の値を返す）
・param: 引数
・singleParams: 引数一つ
[Flutter] floatingActionButton を複数表示する方法（※Material Design非推奨）

floatingAnctionButton(以下FAB）を1画面に複数設置したい場合のサンプルです。
ただし、Material Design では、FABは画面内の主要、または最も一般的な操作を表現するためのものとされているため**「原則1画面に1つ」**が推奨されています。
特別な理由がない場合は大事なアクションをFAB、他方は通常のボタンにした方がMaterial Design に沿ったものになります。
参考※1のMaterial Design公式ではFAB2つで「Caution」、3つで「Don't」とされていますね。。

以下にサンプルを記載します。
参考※2のflutter.devの通り、Scaffoldの中でappBar, bodyと一緒に記述します。

```dart
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(centerTitle: true, title: Text('Title')),
    body: // （省略）
    floatingActionButton: Column(
      verticalDirection: VerticalDirection.up, // childrenの先頭が下に配置されます。
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        // 1つ目のFAB
        FloatingActionButton(
          // 参考※3よりユニークな名称をつけましょう。ないとエラーになります。
          // There are multiple heroes that share the same tag within a subtree.
          heroTag: "search",
          child: Icon(Icons.search),
          backgroundColor: Colors.blue[200],
          onPressed: () async {
            // （省略）タップされた際の処理
          },
        ),
        // 2つ目のFAB
        Container( // 余白を設けるためContainerでラップします。
          margin: EdgeInsets.only(bottom: 16.0),
          child: FloatingActionButton(
            // 参考※3よりユニークな名称をつけましょう。ないとエラーになります。
            heroTag: "scan",
            child: Icon(MdiIcons.barcodeScan),
            backgroundColor: Colors.pink[200],
            onPressed: () async {
              // （省略）タップされた際の処理
            },
          ),
        ),
      ],
    ),
  );
}
 ```

<h2>参考</h2>
<a href="https://material.io/components/buttons-floating-action-button#usage">※1 Material Design Buttons: floating action button</a>
<a href="https://api.flutter.dev/flutter/material/FloatingActionButton-class.html">※2 flutter.dev FloatingActionButton class</a>
<a href="https://medium.com/@miajimyu/flutter-2%E3%81%A4%E4%BB%A5%E4%B8%8A%E3%81%AEfloatingactionbutton%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%A0%B4%E5%90%88%E3%81%AE%E7%94%BB%E9%9D%A2%E9%81%B7%E7%A7%BB%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6-4631530cc4e4">※3 [Flutter]2つ以上のFloatingActionButtonを使った場合の画面遷移の注意点</a>
gasのwebアプリがgsuite配下では開けない問題

##問題点
gasで作成したwebアプリを公開してもgsuite配下では見ることができない問題

##詳細
まず通常gasでwebアプリを公開した場合下記のようなurlになります。
（フリーアカウント、ドメインがgmail.comの場合）
https://script.google.com/a/macros/s/"スクリプトid"/exec
こちらのurlはブラウザにログインしているアカウントがフリーアカウントである場合は見ることができますが、それ以外の場合は開きません。

##擬似的な解決策
根本的な解決はできませんが、ブラウザにログインしている特定のgsuiteアカウントに公開する必要がある場合は、その特定のgsuiteアカウントのドメインがわかっている前提ですが、
https://script.google.com/a/macros/"ブラウザにログインしているドメイン名"/s/"スクリプトid"/exec
とすることでその特定のgsuiteアカウントでは見ることができるようになります。

##根本的な解決に向けて試したが死んでしまった施策
1.何度見たか数えきれない下記の画面ですが、このページに移行する前に少なくとも読み込みするだろうと思い、

![スクリーンショット 2020-11-05 16.19.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601731/a9a86390-9169-46ee-35d5-78cf8ac7d85c.png)

最初の読み込みの際にユーザーがブラウザにログインしているメールアドレスを取得して@以降のドメインを抽出し、強制的に下記の
https://script.google.com/a/macros/"ブラウザにログインしているドメイン名"/s/"スクリプトid"/exec
urlを生成してページ遷移させようとしたのですが、そもそもvar resultまで届かないという無念な結果に終わってしまいました。


下記のスクリプトはユーザーがブラウザにログインしているメールアドレスを取得できるスクリプトです。(＊個人情報の取り扱いには気をつけましょう)

```javascript:getEmail.gs
function doGet() {
  var result = Session.getActiveUser().getEmail();
...
```

##最後に
これの解決策を思いつかれた、もしくはそもそもこれで解決できるよということを教えていただける心優しい方がいればコメントもしくは記事に書いていただけますと幸いです、自分も根本的な解決に向けてまた取り組んでみます。

##本当に最後に
現在私は個人事業主として下記のサイトの事業を取り進めております。(サイトはまだ作成して間もないのでまだガタガタです、、)
ホテルの自動チェックインのラインでの実装や、rpaの制作をメインに進めています。
作業の自動化等にご興味があれば是非ご連絡ください。何卒よろしくお願いいたします。
https://senren.work/
info@senren.work
windowsの環境でwebアプリ制作でハマったこと

```py
    return database_name == ':memory:' or 'mode=memory' in database_name
TypeError: argument of type 'WindowsPath' is not iterable
```

このエラーがなかなか消えなかったので、windows環境でdjanogoを使っている人に向けてメモを残す。
setting.pyのデータベースの部分を変更する必要がある。

`'NAME': BASE_DIR / 'db.sqlite3',`
この部分を変更する。

`'NAME': str(BASE_DIR / 'db.sqlite3'),`

```py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': str(BASE_DIR / 'db.sqlite3'),
    }
}
```

翻訳では引数は何回も使えない。
【ざっくり解説】Railsで本番環境と開発環境の動作を分ける方法

## いきなり結論

### Controllerの場合
#### 本番環境

```rb:users_controller.rb
if Rails.env.production?
  #本番環境のみ適用
end
```
#### 開発環境
```rb:users_controller.rb
if Rails.env.development?
  #開発環境のみ適用
end
```

### Viewの場合
#### 本番環境
```erb:index.html.erb
<% if Rails.env.production? %>
  <%# 本番環境のみ %>
<% end %>
```
#### 開発環境
```erb:index.html.erb
<% if Rails.env.development? %>
  <%# 開発環境のみ %>
<% end %>
```

## 秒速でまとめ
「開発環境と本番環境でズレが出てしまう…」
「仕方なく本番環境に合わせてるけど、開発環境の時に不便だな…」

そんな時に使える条件分岐をご紹介しました。
本番環境って難しい！Rails学習頑張っていきましょう！
ブラックボックスに感じていたdeviseのコントローラーを触ってみた

#はじめに
　deviseとは、ユーザー管理機能の実装を簡単にしてくれるGem。簡単にしてくれているが故に、「なぜ、動作するのか」がわからない部分が多々存在していた。オリジナルのアプリケーションを作成していて、今までとは仕様を変更したいと思い、色々と試行錯誤し、以前よりもdeviseの使い方がわかってきた気がする。

##deviseのコントローラー
　deviseについて初めて学習した時は、コントローラーについて、全く扱わなかった。他の機能ではMVCモデルを意識して、実装しているにも関わらず、deviseについては、ルーティングも勝手に生成されるし、コントローラーは存在すらしなかった。RailsがMVCモデルを謳っている以上、「コントローラーがあるのだろうが、見えなくなっているんだろうなぁ」程度の考えで今まで学習してきた。
　ターミナルでコマンドを確かめると、

```bash
rails g --help

=>
Devise:
  devise
  devise:controllers
  devise:install
  devise:views
```

deviseでコントローラーを生成できることに気づいた。

##今まではdeviseのコントローラーを使わなかった場合

`application_controller.rb`にストロングパラメーターを設定していた。このファイルは全てのコントローラーに継承されているので、deviseのコントローラーにも適用れている。
devise以外のコントローラーに干渉しないように、

```ruby:application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?

 private
 def configure_permitted_parameters
   devise_parameter_sanitizer.permit(:sign_up, keys: [:カラム名])
 end
```

と記述し、devise_controller?でdeviseのコントローラーを使う時のみに、ストロングパラメーターの処理が行われるようにしたいた。

##経緯
　現在作成しているアプリケーションでは、ユーザーのサインインを「メールアドレス」と「パスワード」での認証ではなく、<font color=red>「ニックネーム」</font>と「パスワード」に変更できないか考えていた。


##流れ
1. deviseのコントローラーを生成
2. サインインを任意の認証に変更
3. deviseのコントローラーでストロングパラメーターを作成
4. ルーティングにアクションを追記
4. ビューファイルを任意の認証に変更

###1. deviseのコントローラーを生成

ターミナルで

```bash
rails g devise:controllers user
```

他のコントローラーの生成と違うのは、controller<font color=red>s</font>と複数形になる点。なぜなら、このコマンドで、deviseのサインイン・サインアップなど様々なコントローラーが同時に生成されるため。
###2. サインインを任意の認証に変更
```ruby:config/initializwes/devise.rb/49行目
config.authentication_keys = [:nickname]
```
コメントアウトを外し、任意の認証に使いたいカラムを記述。
※`:password`は記述しなくても、サインインの認証に使うことができる。

###3. deviseのコントローラーでストロングパラメーターを作成

```ruby:app/controllers/user/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
  before_action :configure_sign_in_params, only: [:create] #コメントアウトを外す
(中略)
protected #コメントアウトを外す
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_in_params #コメントアウトを外す
    devise_parameter_sanitizer.permit(:sign_in, keys: [:nickname, :password]) #コメントアウトを外し、角括弧の中に、認証に使いたいカラムを記述　※ここはpasswordについても記述する
end #コメントアウトを外す
```

###4. ルーティングにアクションを追記

```ruby:config/routes.rb
devise_for :users, controllers: {sessions: 'users/sessions'}
```
`users`以降を追記。
###5. ビューファイルを任意の認証に変更
```ruby:views/devise/sessions/new.html.erb
<%= form_with model: @user, url: user_session_path, class: 'sessions-main', local: true do |f| %>
  <%= f.text_field :nickname, class:"nickname", id:"nickname", placeholder:"ニックネーム" %>
  <%= f.password_field :password, class:"input-default", id:"password", placeholder:"6文字以上の半角英数字" %>
  <%= f.submit "ログインする", class:"reg-btn" %>
<% end %>
```
最低限だと、こんな感じかと…

##最後に
　同様に新規登録のコントローラーについても修正することが可能。sessionsの部分がregistrationsに置き換えて考えればいけるかと…
Python 3.9.0、3.8.6を pyenv を使って macOS BigSur にインストールする

下記の Python バージョンを pyenv を用いてインストールするとき、
ビルドに失敗する場合にお試しください。

###確認済みバージョン
* 3.9.0
* 3.8.6

# 問題
* macOS BigSur 11.0 beta、11.1 Beta
* Xcode 12.2 beta 3
* Command Line Tools for Xcode 12 beta 3

上記のケースで
`pyenv install 3.9.0`
`pyenv install 3.8.6`
を実行すると、下記のようにビルドに失敗する

```shell:shell
..
BUILD FAILED (OS X 11.0 using python-build 20180424)
..
make: *** [install] Error 1
```

# 解決策

## Step1: XCode コマンドラインツールの設定
1. `Xcode-beta.app` / `Xcode.app`を開く
2. XCode -> Preference -> Locations
3. Command Line Tools を 目的のバージョンに変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331415/7b03ed41-3ec4-995f-3537-ea23afdfeeaf.png)

## Step2: pyenv に指定の Python をインストール
シェルで下記を実行

```shell:shell
LDFLAGS="-L$(xcrun --show-sdk-path)/usr/lib" pyenv install 3.9.0
```

# 確認

インストールを確認

```shell:shell
pyenv versions
* system (set by /usr/local/var/pyenv/version)
  3.9.0
```

グローバルに設定
シェルをリロード
Python バージョンの確認

```shell:shell
pyenv global 3.9.0
zsh -l
python --version
Python 3.9.0
```
無事 `3.9.0` になりました。

---
Source:
https://github.com/pyenv/pyenv/issues/1643
https://medium.com/@koji_kanao/install-python-3-8-0-via-pyenv-on-bigsur-b4246987a548
JavaはPowerPointでSmartArt図形のテキストコンテンツを抽出

前回の記事では、[PowerPointにSmartArt図形を追加する方法](https://qiita.com/wendy_wang/items/48b556784d3f3284a316)を紹介しましたが、本日は、JavaプログラムでSmartArt図形のテキストコンテンツを抽出する方法を紹介します。 （ライブラリ： Free Spire.Presentation for Java）

**JARパッケージのインポート**
**方法1：** [Free Spire.Presentation for Java](https://www.e-iceblue.com/Download/presentation-for-java-free.html)をダウンロードして解凍したら、libフォルダーのSpire.Presentation.jarパッケージを依存関係としてJavaアプリケーションにインポートします。

**方法2：** Mavenリポジトリから直接にJARパッケージをインストールしたら、pom.xmlファイルを次のように構成します。

```xml
<repositories>
        <repository>
            <id>com.e-iceblue</id>
            <name>e-iceblue</name>
            <url>http://repo.e-iceblue.com/nexus/content/groups/public/</url>
        </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.presentation.free</artifactId>
        <version>3.9.0</version>
    </dependency>
</dependencies>
```

**Javaサンプルコード**

```java
import com.spire.presentation.Presentation;
import com.spire.presentation.diagrams.ISmartArt;
import java.io.*;

public class extractTextFromSmartArt {
    public static void main(String[] args) throws Exception {
        Presentation presentation = new Presentation();
        presentation.loadFromFile("SmartArt.pptx");

        //新規txtドキュメントを作成
        String result = "extractTextFromSmartArt.txt";
        File file=new File(result);
        if(file.exists()){
            file.delete();
        }
        file.createNewFile();
        FileWriter fw =new FileWriter(file,true);
        BufferedWriter bw =new BufferedWriter(fw);

        bw.write("下記はSmartArtから抽出されたテキストです。" + "\r\n");

        //すべてのスライドをループし、SmartArt図形を取得してください
        for (int i = 0; i < presentation.getSlides().getCount(); i++)
        {
            for (int j = 0; j < presentation.getSlides().get(i).getShapes().getCount(); j++)
            {
                if (presentation.getSlides().get(i).getShapes().get(j) instanceof ISmartArt)
                {
                    ISmartArt smartArt = (ISmartArt)presentation.getSlides().get(i).getShapes().get(j);

                    //SmartArtにあったテキストを抽出します
                    for (int k = 0; k < smartArt.getNodes().getCount(); k++)
                    {
                        bw.write(smartArt.getNodes().get(k).getTextFrame().getText() + "\r\n");
                    }
                }
            }
        }
        bw.flush();
        bw.close();
        fw.close();

    }
}
```

![75778150-D752-43a0-A3CB-3837AFC5BB03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/61bbba09-f97c-d0dd-2a5e-496cc5aaf319.png)
テキストボックスの内容を取得・出力、ページ上までスクロール

最近使ったjQueryの技:sparkles:をまとめます。その２
参考にしたサイトがたくさんになったけど、自分の理解力がなく、その分たくさん見て理解した感じ。
#お品書き
+ テキストボックスの内容を取得・・・`.val();`
+ jQueryで取得した内容をブラウザ上に出力・・・`html()`
+ ページの一番上までスクロールされるやつ・・・` $(window).scrollTop(0);`

#テキストボックスの内容を取得する
新規会員登録ページなどで、入力後に内容を確認するページを挟む。この時点ではまだsubmitはされない。
送信していない内容を取得する方法？？？:thinking:
と悩んだので備忘録。
他にもいい方法があるかもですが・・・
##`val()`メソッド
HTMLのvalue属性を取得したり、変更できるメソッド
らしい。
あれ？value？バリューって何だっけってなったそこの私。
少し時間が空くとhtmlのform周りの属性はあやふやになってしまう。
(ついでにいえばQiitaのマークダウンの書き方もすぐ忘れちゃう。別ページに開くのではなく右上にいてほしかった・・・)
>value属性で設定した値は初期入力値となる。

HTML的にはこう書いてあることが、多かった。
テキストボックスに表示される初期値を取得したいわけではないよ〜と思って混乱したけど。:disappointed_relieved:
value値はテキストボックスに入力した文字列へ初期値から変更される。

###使い方
`対象となるHTML要素.val()`が基本。

```js
var getValue = $('#button').val();
```
#val()で取得した内容をブラウザ上に出力
###html()メソッド

>「html()」を使うと、任意のHTML要素を取得したり意図的に要素を追加・書き換えをすることが出来ます


```js
$('body').html(getValue);
```
これによってbody要素内に先程getValueで取得したvalue値を表示することができる。

# ページの一番上までスクロールする
端っこのボタンをクリックするとページの一番上までスクロールするよく見るやつ。
`id="button"`のボタンを用意したとして。

```js
    $('#button').click(function () {
        $(window).scrollTop(0);
```
なんて簡単。
windowに対して、指定したスクロール位置まで移動する。
一番上は0。

参考にしたサイト
[【jQuery入門】val()によるvalue値の取得・変更・設定まとめ！](https://www.sejuku.net/blog/45297)
[JavaScript テキストボックスの値を取得/設定する](https://itsakura.com/js-textbox)・・・val()だけじゃなくてgetElementByIdを使う方法もあるらしい！
[jQueryのhtml()で追加・取得・書き換えの方法まとめ！](https://www.sejuku.net/blog/38267)
[jQuery でテキストボックスの値を設定／取得／追記／削除を行う方法](https://webllica.com/jquery-text-edit-get-add-del/#h2-2)
[【jQuery入門】scrollTop()で画面のスクロール位置を取得・設定する方法！](https://www.sejuku.net/blog/61689)
submitメソッドの使い方（Javaシルバー）

# substringメソッドとは

文字列から任意の部分列を取得するメソッド。
例えば、「今日はいい天気ですね」という文字列から「天気」という文字列だけを
抜き出すことができる。

Stringクラスのメソッド
java.lang.String.substring()

substring：部分列、部分文字列、サブストリング



## 使い方

```java

public static void main(String[] args) {
	//抜き出し前の文字列
	String str = "abcde";
	//抜き出した文字列を表示
	System.out.println(str.substring(2,4));
  }

```
実行結果

```java
	cd
```

抽出する文字列を指定する範囲は、以下のように文字と文字の間に線を引き、
番号を振ると分かりやすい。

　　｜a｜b｜c｜d｜e｜
　   　0　1　2　3　4　5

 | 今 | 日|は| い |い |天 |気 |で | す | ね|
0　1　2　3　4　5　6　7　8　9　10　




開始位置だけを指定して、終了位置を指定しないと、残りのすげての文字を抜き出す。

```java

public static void main(String[] args) {
	//抜き出し前の文字列
	String str = "今日はいい天気ですね";
	//抜き出した文字列を表示
	System.out.println(str.substring(5));
  }

```
実行結果

```java
	天気ですね
```
MoekadenRoomのECHONET Lite対応機器をスマホアプリ「家電手帳」で操作してみた

#はじめに
ECHONET Lite対応家電のシミュレータ[MoekadenRoom](https://github.com/SonyCSL/MoekadenRoom)というものがあるようで、Macにインストールして試してみます。
Macで試すには、Proccessing IDEで動かす必要があるようです。
>I could not export for Mac. Please execute in Processing IDE.

家電管理アプリ「[家電手帳](https://inetcore.com/kadentecho/)」ではECHONET Lite対応家電の一部が操作できるので、MoekadenRoomの家電でも操作できるのかを試してみます。

#ECHONET Liteとは
>ECHONET Liteは、センサ類、白物家電、設備系機器など省リソースの機器をIoT化し、エネルギーマネジメントやリモートメンテナンスなどのサービスなどを実現するための通信仕様です。
通信仕様や各機器の制御コマンドを共通仕様とすることで、マルチベンダー環境でのシステム構築を実現します。

[ECHONET Lite規格の特長と概要](https://echonet.jp/about/features/)

#Processing IDEをダウンロードする
Proccesing IDEは以下からダウンロードしました。
https://processing.org/download/?processing

#必要なライブラリをダウンロードして配置する
Proccesing IDEをインストールできたら、以下から必要なライブラリ(OpenECHO for ProcessingとControlP5)をダウンロードします。
https://github.com/SonyCSL/OpenECHO
ダウンロードできたら、以下のようにライブラリを配置します。

```
$ cp OpenECHO-master/Processing/libraries/  ~/Documents/Processing/libraries/
```

#MoekadenRoomを起動する
以下からMoekadenRoomをダウンロードします。
https://github.com/SonyCSL/MoekadenRoom
`ModekadenRoom-master`がダウンロードできたら、フォルダの名前を`MoekadenRoom`に変更します。
`MoekadenRoom/MoekadenRoom.pde`をクリックするとMoekadenRoomが起動します。
以下のようにGUIで操作できます。
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/0fafe780-0cb8-eba5-174b-6e948e372b54.gif)

#家電管理アプリ「家電手帳」でMoekadenRoomのECHONET Lite対応機器を操作する
###家電手帳とは
[家電手帳](https://inetcore.com/kadentecho/)は家電を管理するためのアプリです。メーカー名、型番、保証書の画像など家電管理に必要な情報をまとめて登録でき、50万種類以上の機器やその取扱説明書、リコール情報も確認できます。家電のリモコン機能も搭載しています。

###家電手帳で操作できる家電
家電手帳では、同じネットワークに接続しているテレビやエアコンでリモコン機能を使うことができます。
登録方法や対応家電は以下のページです。
https://inetcore.com/kadentecho/remocon.html

###家電手帳でMoekadenRoomの家電を操作する
1.スマホをPCと同じSSIDのWi-Fiに接続する
2.[家電手帳](https://inetcore.com/kadentecho/)をインストールする
3.以下の画面で➕ボタンをタップしてリモコンを登録する
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/4143c45a-a841-2ed2-0be8-c57e48e3544c.jpeg">
4.リモコン操作ができる家電を検索する
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/b9001788-e677-82fd-14e0-3f773a757d1b.jpeg">
5.MoekadenRoomで操作できる家電はエアコンと照明
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/ab120bfb-90f8-3549-ac77-67aaa2ede881.jpeg">
6.家電を操作する
照明のリモコン画面でON/OFFを試してみました。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/a4043913-678f-27fe-f096-7ada9d4d0e8f.jpeg">
Macの画面に表示されているMoekadenRoomの照明がON/OFFしました!
![output1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/9983f39d-aa8d-02b7-28f9-566a6cffcb10.gif)
以下のエアコンのリモコン画面で操作してみました。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/ccd6e354-800f-f26b-a8e2-56f264500356.jpeg">
MoekadenRoomのエアコンが操作できました!
![output2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/d9656ab2-124b-0afd-76b5-dcd858c937c1.gif)

#おわりに
MacでECHONET Lite対応家電のシミュレータ[MoekadenRoom](https://github.com/SonyCSL/MoekadenRoom)を動かして、スマホアプリ「家電手帳」で操作してみました。
EchonetLite対応の家電が家にあれば、家電手帳でリモコン操作ができます。
家電手帳では、以下の家電の操作に対応しています。
[リモコン対応家電]
(https://inetcore.com/kadentecho/support_remoteControl/index.html)
無料でインストールできるので、皆さんも試してみてください。
Materializeのselect等フォームが正常に動作しないとき

#結論
turbolinksを無効にすると動くかもしれません。

#エラー解消までの経緯
##Materializeとは
簡単にマテリアルデザインを導入できるCSSフレームワークです。
Bootstrapで仕上げたUIを垢抜けさせることができるのが良い。
しかし各コンポーネントを使用する際は独特な設定や制約があり、なかなか癖があります。

##Matelializeはややこしい
- 様々なコンポーネントを使用する前はjQuery(もしくはJS)で初期設定が必要です。

- また例えばselectフォームは```f.label```より先に```f.select```を書かなくてはいけない。
以下のように。

```
(通常のRailsで作成するselectフォーム)
<%= f.label :column %>
<%= f.select :column, ~ %>

(Materializeでselectを作成するとき)
<%= f.select :column, ~ %>
<%= f.label :column %>
```

それならRailsのフォームでサクッと完成させたいと思うとあることに気付きます。
...Materializeを導入したあとはRailsのフォームが表示されないのです。

そこで何とかselectを動作させるため色々いじっていたらタイトルにある通り正常に動作しないエラーが出てしまいました。

#原因の発見
##前提
- JSはSprocketsで管理

##エラー解消の手順
「 フォームが正常に動作しない 」とはページをリロードしないとselectが表示されず、
consoleにエラーが何も出ない状態でした。

そこでjQueryがきちんと読み込めていないと仮設を立てて
```layouts/application.html.erb```と ```assets/javascripts/application.js```
を確認。

気になるところを発見しました。

```
<%= javascript_include_tag 'application', data-turbolinks-track': 'reload' %>
```

turbolinksをキーワードに調べることに。

##turbolinksの問題点
```$(document).ready(function()``` が発火しない

turbolinksの主な動作は、

- fetchReplacement
  < a >タグのリンクをajax化する

- fetchHistory
  戻るなどでページ遷移する際、復元できるページであれば復元する

以上どちらの動作においても ```ready```が発火しないそう。

##turbolinksを使いながらjQueryを使いたいとき
- ```$(document).on 'ready page:load'``` で
  jQueryの```ready``` とturbolinksの ```page:load```どちらも定義する

- ```jquery-turbolinks gem```で上記の対策をとってもらう

- turbolinksを無効にする

##turbolinks無効の手順
```
(Gemfile)
gem 'turbolinks' #削除
```

```
(assets/javascripts/application.js)
//= require jquery
//= require materialize
//= require turbolinks #削除
//= require rails-ujs
//= require_tree .
```

```
(layouts/application.html.erb)
<head>
  <%= stylesheet_link_tag 'application', media: 'all' %>
- <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
+ <%= javascript_include_tag 'application' %>
- <%= javascript_include_tag 'materialize', 'data-turbolinks-track': 'reload' %>
+ <%= javascript_include_tag 'materialize' %>
</head>
```

#Materializeのselectが特定の環境下でのみ動作しないとき
1. 公式Githubをcloneする  
[https://github.com/Dogfalo/materialize](github)
2. ```js/select.js```を自分の環境下(JSを読み込んでいる場所)に配置する
3. assets/javascripts/application.jsで```select.js```を読み込む

以上の手順ではiOS13などでの動作がうまく行かないときに有効のようです。


#参考

[turbolinksをオフにしないためにやったこと](https://qiita.com/saboyutaka/items/bcc0966313c6f7399a6e#trigger%E3%81%AE%E7%99%BA%E7%81%AB%E3%82%BF%E3%82%A4%E3%83%9F%E3%83%B3%E3%82%B0)

[materializeを使ったformのselectタグで、iOS13だと正しく選択できない](https://qiita.com/mutax/items/18aa1fc1ad2742d2c4af)

[【Rails】turbolinksを無効化する](https://qiita.com/d0ne1s/items/5a4122d2972be3812986)
Unity Get Rotation From The Editor Panel

```c#
public float GetInspectorRotationValueMethod(Transform transform, string rotationAngle)
{
        System.Type transformType = transform.GetType();
        PropertyInfo m_propertyInfo_rotationOrder = transformType.GetProperty("rotationOrder", BindingFlags.Instance | BindingFlags.NonPublic);
        object m_OldRotationOrder = m_propertyInfo_rotationOrder.GetValue(transform, null);
        MethodInfo m_methodInfo_GetLocalEulerAngles = transformType.GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
        object value = m_methodInfo_GetLocalEulerAngles.Invoke(transform, new object[] { m_OldRotationOrder });
        string temp = value.ToString();
        temp = temp.Remove(0, 1);
        temp = temp.Remove(temp.Length - 1, 1);
        string[] tempVector3;
        tempVector3 = temp.Split(',');
        Vector3 vector3 = new Vector3(float.Parse(tempVector3[0]), float.Parse(tempVector3[1]), float.Parse(tempVector3[2]));

        switch(rotationAngle)
        {
            case "x":
                return vector3.x;
                break;
            case "y":
                return vector3.y;
                break;
            case "z":
                return vector3.z;
                break;
            default :
                return vector3.x;
                break;
        }
}
```
VPSを経由して安全に自宅サーバを公開する

Raspberry piなどを使用して安価に自宅サーバを公開したい場合があります。
このとき、VPSを経由する事で自宅IPアドレスを公表せずに自宅サーバを公開する事ができるので、その方法を紹介します。

## 目的
* 自宅サーバを自宅のIPアドレスを公表せずに公開する

## 使用する方法
* SSHポートフォワード（リモートフォワード）
  - 自宅からサーバへのリモートフォワードではあれば、VPSを固定IPにするだけで固定IPアドレス化が可能

## 構成
![home_server_via_vps.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566062/d59f72fc-1d2c-fb2c-0da9-6f289623e6aa.png)

## 設定
### VPS側
SSHサーバをインストールし、 `GatewayPorts` を有効にします。

```conf:/etc/ssh/sshd_config
GatewayPorts: yes
```

### 自宅サーバ側
SSHポートフォワードを使用し、VPSサーバにアクセスします。
変数は適宜環境に置き換えてください。

```bash
export open_port=8000
export home_port=8080
export host=example.com
export ssh_key=~/.ssh/example.pem
ssh -fNT -o ServerAliveInterval=30 -R ${open_port}:*:${home_port} ${host} -i ${ssh_key}
```

## 動作確認
VPSサーバのIPアドレスに対し、公開したポート番号でアクセスし、自宅サーバへアクセスできれば完了です。

## あとがき
SSHのセッションが切れると接続できなくなるため、セッションが切れたとき再接続できるクライアントや、仕組みを導入するとより堅牢になります。
また、VPSサーバはネットワーク通信料が固定料金のものを選ぶと試算しやすいのでおすすめです。
誰でもわかるデバイスドライバ講座　はじめに



# はじめに

[サイエンスパーク][1]では[デバイスドライバの開発][2]を20年以上続けており、15年ほど前からWebページ上にて「[誰でもわかるデバイスドライバ講座][3]」としてデバイスドライバに関する技術情報を発信しております。

https://sciencepark.co.jp/device_driver/dvdr/
[1]:https://sciencepark.co.jp/
[2]:https://sciencepark.co.jp/device_driver/
[3]:https://sciencepark.co.jp/device_driver/dvdr/

この度、Qiita Organizationにサイエンスパーク株式会社として登録いたしましたので、サイエンスパークのWebページだけではなくQiitaでもデバドラ講座を発信し、一人でも多くの方がデバイスドライバの開発に興味を持っていただければと思います。
担当させていただきますのは、サイエンスパークに今年(2020年)入社いたしました、Canbeです。情報発信をさせていただくにあたり、私自身もレベルアップしていけたらと思います。よろしくお願いいたします。

サイエンスパークのWebページにて公開しているデバドラ講座ですが、初版が作成されたころはドライバーの開発モデルはWDMしかなく、開発支援機能が乏しいテキストエディタ―とコマンドラインにてビルドをしていたとのことです。
当時は、VisualStudio CodeやAtomなど高度なカスタマイズやC++のコード補完機能などのプラグインなどは存在していませんので、ソースコードは補完されずに手入力、ビルドも手動で実施という今では考えられないような人力による開発環境だったというには、時代を感じます。
現在はVisualStudioによる統合開発環境が整備され、開発支援機能が充実してきており、VSによる開発でも、テキストエディタ(VS Code)による開発でも15年前とは比較にならないくらい改善されています。

このような時代の流れもあり、Web版のデバドラ講座を現在に合わせて再編したものを発信していく予定です。
誰でもわかるデバイスドライバ講座として”初心者でもデバイスドライバ開発ができる！！”を目標にした記事を投稿していきます。

次回からは、新たな執筆を含めたデバイスドライバ講座の基礎編から順次投稿させていただきますので、お付き合いいただければと存じます。

それでは皆様よろしくお願いいたします。
SwiftUIのListでRealmのデータを削除するとクラッシュする時の直し方

#Index is out of boundsでクラッシュ！
SwiftUIのListの.onDeleteでperformに下記のメソッドを渡し、

```
func deleteRow(offsets: IndexSet) {
      guard  let index = offsets.first else {
           return
      }
      let deleteItem = hoges[index]
      try! realm.write {
        realm.delete(deleteItem)
      }
      self.hoges = realm.objects(Hoge.self)
}
```

試しに、このように記述していたら、 "Index ~ is out of bounds (must be less than ~)." とよく見るエラーでクラッシュしてしまいました。

#~~クラッシュしない書き方~~
https://stackoverflow.com/questions/61165998/how-to-delete-data-from-swiftui-list-and-realm

~~こちらを参考にindexをforEachで回すようにしたらクラッシュしなくなります！~~


```
func deleteRow(offsets: IndexSet) {
      offsets.forEach({ index in
      　try! realm.write {
       　　realm.delete(self.hoges[index])
        }
      })
      self.hoges = realm.objects(Hoge.self)
}
```

追記：
上記で直ったと思っていたのですが、最後尾のデータ削除時のみクラッシュしなくなるだけで、他のcellを消したりすると同様にクラッシュしてしましました。
ググって出た情報を参考にforEachをカスタマイズしたり、データが存在するかどうか確かめるexistメソッドを生やしたりしましたが、どれもうまくいかず、、

#Modelを作る
暫定的にこちらの記事を参考に、`@objc dynamic var` で定義しているRealmのデータと同じ値を定義したModelをstructで作り、ViewModelのイニシャライザでRealmから代入し、Listからは直接Realmを参照せず、Modelから値をとるようにしてクラッシュを回避しました。

```
import RealmSwift

class Hoge: Object, Identifiable {
    @objc dynamic var id: String = ""
    @objc dynamic var title: String = ""
    
    override static func primaryKey() -> String? {
        return "id"
    }
}
```

```
struct HogeModel {
    let id: String
    let title: String
}
```
https://llcc.hatenablog.com/entry/2020/04/26/205254

開発規模が大きいとこのやり方も結構厄介かもしれません。


RealmSwiftの方にも似たようなissueが立っているようですが、SwiftUIでも更に使いやすくなると良いですね！
https://github.com/realm/realm-cocoa/issues/6635

#Frozen Objectsを使う （20/11/16 追記）
もっと改善できないかと探すうちに、RealmのResultsをimmutableに扱えるFrozenObjectsがあるという事を知りました。
https://realm.io/blog/realm-database-a-new-architecture-and-frozen-objects/

まだ、詳しい使い方を把握できていませんが、わざわざModelを作り直すよりは簡単な方法を見つけました。
``self.hoges = realm.objects(Hoge.self)?.freeze()``
本当はこのように書きたいのですが、こう宣言して、deleteなどのrealm.writeを使う操作をするとクラッシュします。
なので、暫定的に、このようにimmutableなプロパティーをPublishedにしてイニシャライザや、realm.writeで書き込みをした際に、代入することでクラッシュを回避できるようになりました！

```HogeViewModel.swift
  var hoges: Results<Hoge>?
  @Published var freezedHoges: Results<Hoge>?

  let realm = try! Realm()
    
  init() {
    hoges = realm.objects(Hoge.self)
    freezedHoges = hoges?.freeze()
  }

  func addHoge() {
    let hoge = Hoge()
    hoge.id = NSUUID().uuidString
    hoge.title = "fuga"
    try! realm.write {
      realm.add(hoge)
    }
    freezedHoges = hoges?.freeze()
  }
 
```
Rails logger 1分で大まかに把握

# loggerを使うことでRailsのコード上から、ログを出力できる
###ログの保存場所
デフォルトではRails.root/log/になる
### STDOUT(標準出力)への書き出し
`config.logger = Logger.new(STDOUT)`
### 出力フォーマットを変更できるようになる
`config.log_formatter = ::Logger::Formatter.new`
### 出力したいログレベルを設定
`config.log_level = :error`
fatal	プログラムのクラッシュなど、制御できないエラー
error	プログラムで制御できるエラー
warn	警告
info	システム操作や、管理に役立つ情報
debug	開発者向けの情報
設定したレベルより上が全て表示される(:errorならfatalとerror)
### タグ付きのログ出力
`logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))`
【CSS】画面いっぱいに背景色を付ける

基本的な話ですが、忘れがちなのでメモしておきます。

#事前準備
HTML

```html
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>画面いっぱいに背景色</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="contents">
        <h1>コンテンツ</h1>
        <p>
            コンテンツ
        </p>
        <p>
            コンテンツ
        </p>
        <p>
            コンテンツ
        </p>
        <p>
            コンテンツ
        </p>
        <p>
            コンテンツ
        </p>
        <p>
            コンテンツ
        </p>
        <p>
            コンテンツ
        </p>
    </div>
</body>
</html>
```

CSS

```css
.contents{
    background-color: rgb(206, 206, 206);
}
```

表示確認
![first.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/6c142360-ca70-2218-c5e2-e2a980cc72e3.png)

準備完了です。では見ていきましょう。

#画面全体に背景色をつける
シンプルに画面全体に背景色を付けたい場合はbodyに背景色を指定するだけです。

bodyタグ内に、文字や画像などの要素を記述することでブラウザ上に表示できますが、body自体に背景色を指定することで画面全体に色を付けることができます。

```css
body{
    background-color: gray;
}

.contents1{
    background-color: rgb(206, 206, 206);
}
```

表示確認
![background-color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/efdbff04-08f5-bd1e-ae00-b434b48eb751.png)


#特定の要素の背景色を画面いっぱいに表示させる
contentsクラスを画面いっぱいに表示させてみましょう。

##①%を使って表示

contentsクラスのheightを100%にして、親要素の高さを基準とします。
そして、画面いっぱいにする為に親要素のhtml、bodyのheightも100%にします。

```css
html,body{
    height: 100%;
}

body{
    background-color: gray;
}

.contents{
    height: 100%;
    background-color: rgb(206, 206, 206);
}
```

表示確認
![margin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/faca81cc-41f1-9a30-a482-414e01272bef.png)
デフォルトでmargin（余白）が設定されているので、``*``でリセットします。

```css
*{
    margin: 0;
    padding: 0;
}
```

できました！
![パーセント指定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/86f7d3c7-40ff-0b12-e894-1601d9ecc581.png)

##②vw,vhを使って表示
vwとvhはビューポート(画面表示領域)で要素の幅、高さを指定することができます。
つまり、100vw,100vhとは、画面サイズを基準として、縦横100%で要素を表示するという意味になります。

```css
*{
    margin: 0;
    padding: 0;
}

body{
    background-color: gray;
}

.contents{
    width: 100vw;
    height: 100vh;
    background-color: rgb(255, 254, 199);
}
```

表示確認　こちらも問題なくできました！
![ビューポート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/7f311912-2578-1815-96bf-bcdec4e0c6b5.png)


#参考
https://nansystem.com/css-full-page-background-color/
中田敦彦のyoutube大学_脳①②

#はじめに
自分のQiita投稿テスト用。
中田敦彦のyoutube大学の脳①、②についてメモ書きを残す。
[youtube動画 【脳①】記憶や感情は脳の中でどうやって作られるのか？](https://www.youtube.com/watch?v=wpcCDTGTys4&t=919s)
[youtube動画 【脳②】感情の生まれ方・運動神経の仕組み・恐ろしい脳の病気](https://www.youtube.com/watch?v=6h3o1GtptV0)

#脳の仕組み
![中田_脳.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/847177/f66a52c6-8d54-4629-e646-bb10e954dfbd.png)
- 人間をつかさどるのは、「心」＜「脳」
- 病気の解決方法：「呪術（呪い）」→「医学（科学）」　ヒポクラテス提唱

#基本構造
- 左脳：左脳：論理的思考（言葉、言語）が得意
右脳：芸術的(?)ビジュアル的(?)思考（直感的思考、空間的思考）が得意

- 1.大脳皮質：ガワ。記憶や感情のコントロール。
2.辺縁系：海馬や偏桃体など
3.基底核：運動のON/OFFのコントロール
　→人は「静止」ができるようなる
4.小脳：運動の微調整
![nou4tu.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/847177/9888c3ed-53d3-c457-877f-b0c6c3a1a540.jpeg)

- ニューロン（神経細胞）
 - ニューロン同士が刺激（電気信号）を送りあっている
- 軸索（神経線維）
- シナプス：接合部分
  - シナプス同士は実は結合はしていない
  - 神経伝達物質をシナプス間で送りあって、はじめて電気が流れる
- 神経伝達物質：（ボールの役割）
 - 刺激（興奮？）の電気信号？
 - ３大伝達物質：
     - ノルアドレナリン：快楽
     - ドーパミン：意欲
     - セロトニン：安定
- 受容体：（キャッチャーの役割）
###参考URL
・脳＋机　と　パソコン　の対応関係
[パソコン選びの３つのキーワード](https://genki365.net/gnkt01/pub/sheet.php?id=68220)
![](https://genki365.net/gnkt01/pub/content_image.php?fname=68220_13_1.jpg)
・脳　と　パソコン　の対応関係
[脳みそのスペック差について](https://noumisoblog.com/noumiso-spec/)
![](https://noumisoblog.com/wp-content/uploads/2019/06/%E8%84%B3%E3%81%A8%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%81%AE%E5%AF%BE%E6%AF%94.png)

#記憶
###海馬
- 辺縁系２大トップの1つ目
- 記憶をつかさどる
- 辺縁系にある
- 大脳皮質に情報を書き込む

###反復
- 記憶力（海馬）は反復で鍛えられる
- 登山道の草の生えた道と同じ。繰り返し通ると、道が太くなる。→長期記憶
  - 長期記憶：シナプス間の伝達物質の行き渡しを何度もやると強くなる<br><br>
- 人間はワーキングメモリ（メモリ）で短期記憶を処理して、反復することで長期記憶（HDD)に書き込む
　
- 記憶は３種類ある？（記憶の残りやすさ：エピソード＜意味＜手続き）
  - エピソード記憶：「過去に〇〇した」という記憶。
  - 意味記憶：知識。「パンは食べるもの」みたいなやつ？
  - 手続き記憶：「自転車の乗り方」などの運動と結びつく記憶。

###睡眠
 - 寝ることで記憶が定着する<br>
　　→日を跨いで復習すると記憶は定着しやすい？

#感情
###偏桃体（チェック屋さん）
- 辺縁系２トップの２つ目
- ある出来事が起きたときに、過去の記憶と照合して判断する<br>
　（例１：大声でおじさんが叫ぶ→過去に似た経験があって、過去の記憶から「怖い」と判断する）

###神経伝達物質（ボール）
 - 偏桃体で過去の経験から出来事を判断して、投げるボール（神経伝達物質）を変える
 - ３大伝達物質：
   - ドーパミン：快楽（食欲や性欲などの「快」の方）
     - 多すぎ→幻覚が出る
     - 少なすぎ→何事も楽しくなくなる
   - ノルアドレナリン：意欲、（集中）
     - 多すぎ→暴力的になる
     - 少なすぎ→意欲がわかない
   - セロトニン：安定
     - ドーパミン（快楽）やノルアドレナリン（意欲）をコントロールする？
     - セロトニンが不足すると、不安定になり不安感が出る？
     - 食事、睡眠、適度な運動、日光を浴びることなどでセロトニンが出る

#運動
###基底核
 - 運動のON/OFFをつかさどる
 - 基底核を損傷すると、体の動きを静止できなくなる

###小脳
 - 運動の微調整をする<br>
　　→小脳を損傷すると、微調整ができなくなり触りたい場所（ボタンなど）をピンポイントで触れなくなったりする

#脳の病気
###脳卒中（よくわからなかった）
#####脳梗塞
- 脳の血管の肥大化して血液の通り道が狭くなる<br>
  or 血管が固まって通り道が狭くなる<br>
　　  →血液が詰まる
- コレステロールが原因になる

#####脳出血
- 脳の血管がもろくなって、血管が破裂する

→生活習慣を改善するのが大切

###うつ
 - メカニズムはまだ完全には分かっていない<br>
 - （提唱されているメカニズム）
   - 1.ストレスで海馬が傷つけられて起こる（炎症モデル？）<br>
     2.セロトニンが不足して起こる<br>
　　　→抗うつ薬(SSRI)でセロトニンを増やして治療する
 - 治療法はまだちゃんと分かってない

###アルツハイマー
 - 脳の中の老廃物が蓄積して起こる
 - 対処療法しか現在ない


#おわりに
 - あっちゃんは記憶のメカニズムを勉強して、記憶しやすい勉強法を作っていたらしい
 - パワポで作った方がまだ楽かも？
 - 慣れれば改行や画像埋め込みなどが便利なのでQiitaの方がいずれ楽になるかも？（わからん）
AccessのVBEでコンパイルする方法と注意点

#バージョン
Access for Microsoft 365 MSO（16.0.13328.20262）32ビット
Windows10 Pro バージョン1909 OSビルド18363.1171


#コンパイルする方法
Alt + F11 でVBE画面出して、これ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/28e70762-f69b-010d-1334-892487bcd1da.png)


#何でコンパイルすんの？
* 関数や変数なんかの名前変更時の修正漏れ
* フォーム上に存在しないパーツを参照しちゃってる

とか炙り出せる。

例えばこんな感じ。
関数名変えたけど、戻り値のところ変え忘れた、みたいな。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1325b802-1d84-fede-95d7-3543e76f0979.png)
VBEにリファクタリング機能付いてればいいのにね…(´・ω・`)


#注意点
**Option Explicit** が無いとミスを炙り出せないことがあるぞい。
例えばこんなのはコンパイル通っちゃいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e2acd3ab-0477-f7e6-0fb9-c3990f05ac7c.png)
tester2を関数の戻り値ではなく、関数内の変数と解釈してるんだろうなあ…。


#蛇足
インタープリンタだからコンパイルしても実行速度の向上は見込めないのかなあ…。
いちいち手でやるのダルイからファイル開くor閉じる時に自動でコンパイル走ってくれる設定とかあるといいなあ。今度探してみよう。
swift FilterとMapを使う

巨大データを扱う時に、例えば写真のデータ：
id,filepath,date,filenameなどなどの基本情報
isSelected,rating,openEyeなどなどのアプリに必要なフラグ

こんなものがありますが、必要におうじて様々な配列を抽出する必要がしばしば

FilterとMapを使います。

```php:ImageViewModel
struct ImageViewModel {
    let id: String = ""
    let name: String = ""
    var isSelected: Bool = false
}
```

isSelectがtrueになっているすべての写真を取得して、
それらの写真のidを新しい配列として出したい時：

```
let imageViewModels = [ImageViewModel]()
let targetImageIds = imageViewModels.filter({ $0.isSelected }).map({ $0.id })
```
センサーデータをラズパイに保存！！(準備編)

# センサーデータをラズパイに保存！！(準備編)

Iot のセンシングを行う際、データを保存しないといけない。
Json、txt、などいろいろな方法で保存する場合がある。
今回は、一番オーソドックスなデータベースに追加することにしましょう。

## 使用機器

- raspberry Pi
- PC
- 何かしらのセンサー(今回は、土中水分)
- ESP32
- Wi-Fi ルーター

## 通信方式

MQTT を使用します。
これは、ブローカーに対して送信データに topic を設定することで、受信したい PC などが指定 topic に関するデータを受け取れるというものです。
また、Iot なので、省電力などの面からもこの通信方式がよく使われているように感じます。

## 準備

- raspberry Pi に mySql をインストールします。
- ssh 設定
- IPAddress 固定
- MQTT インストール
- ESP32 の準備

### MySql

```
sudo apt-get install mysql-server
```

これで、インストール中に設定させるので次は、ログインできるかを確認します。

```
mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.12-0ubuntu1 (Ubuntu)

Copyright (c) 2000, 2016, 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>
```

### ssh 設定

 設定に関しては、非常に簡単です。
 GUI の場合は raspberry の設定を開いてインターフェースの部分の ssh を有効にするだけです。
 設定＝＞インターフェース＝＞ ssh 有効

 そうすると TeraTerm とかで IP 指定して

 ```
 pi  
 自分で設定したパスワードを打ち込むとログインできます。
 ```

### IPAddress の固定化

 IPAddress は、ずっと動いている場合は変わらないと思います。
 何あるかわからないので、IP アドレスを固定しときましょう。

 まず、自分の環境の IP アドレスを知りましょう。

 ```
 ipconfig /all

 <!-- ==========抜粋=========== -->
 　サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .: fe80::30ff:fe0c:2043%4
                                          192.168.11.1
   DHCP サーバー . . . . . . . . . . . .: 192.168.11.1
   DHCPv6 IAID . . . . . . . . . . . . .: 36740131
 ```

 サブネットマスクは、255.255．255.0 なので、24 ですね。
 デフォルトゲートウェイが、192.168．11.1
 DHCP サーバー も同様ですね
 IP アドレスを 192.168.11.90 に固定済ます。

 ```
 sudo nano /etc/dhcpcd.conf

 <!-- 追記します。（Wi-Fi接続） -->
 interface wlan0
 static ip_address=192.168.11.90/24
 static routers=192.168.11.1
 static domain_name_servers=192.168.11.1
 ```

 再起動して IP が固定化していれば完了です。

### MQTT インストール

 モスキートをインストール

 ```
 <!-- ブローカーです。 -->
 sudo apt install mosquitto

 <!-- サーバ起動 -->
 sudo systemctl start mosquitto
 ```

 ラズパイで MQTT のトピック送信する場合

 ```
 sudo apt install mosquitto-clients
 ```

 test

 ```
 <!-- サーバ側 -->
 mosquitto_sub -d -t test

 <!-- クライアント側 -->
 mosquitto_pub -d -t test -m "こんにちは"
 ```

 test という topic で送信したデータが表示できれば完了です。

### ESP32

 ボードのインストール
 ライブラリのインストールを行ってください
 使用するライブラリは、以下の通りです。

 ```c
 #include <WiFi.h>
 #include <PubSubClient.h>
 #include <ArduinoJson.h>
 ```

 ライブラリのインストールに関してですが自分の周りでも環境によってエラーが違う？場合があり、ここで詳細の説明はしません。
【Vue・JS】nullの場合を考える必要あり！TypeErrorの回避法

Vueで宣言済みのプロパティを選択してるのにTypeErrorが表示される場合の対処法について。


##状況

初期状態で**空の配列に対し、配列内のプロパティを呼び出す設定を記述した**ところ、下記エラーが発生。

```
[Vue warn]: Error in render: "TypeError: Cannot read property 'aaa' of undefined"
```

指定した配列は初期状態は空だが、クリックイベントで中身が追加されていく。


<br>
##発生原因
空の配列の存在しないプロパティが指定されていたためエラーが発生した。

**▼勘違い**
中身が空でもその要素は指定できる（aaa[0]はエラーにならない）。このため、中身が空の状態で将来入る予定のプロパティも指定可能と勘違いした。

空の配列`arr=[]`に対して、arr[0]としてもエラーにならない。

```vue:エラーにならない
<template>
  <div>
    <p>null test</p>
    <p>・arr:{{arr}}</p>
    <p>・arr[0]:{{arr[0]}}</p>
  </div>
</template>
```

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/cbbc14d8-1e4a-df1b-8f91-2ba10b1aa891.png)|
|:--|


`arr[0].aaa`など、プロパティを指定した時点でエラーになる。

```vue:エラーになる
<template>
  <div>
    <p>null test</p>
    <p>・arr[0].aaa:{{arr[0].aaa}}</p>
  </div>
</template>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/e6bdb5f7-8cf4-4ea6-7938-8597a5486e29.png)



<br>
##対処法
v-ifを使ってnullの時は表示しないように回避する。

**▼配列の場合**
配列の場合は長さが0以上を指定すればいい。

```vue:
    <p v-if="arr.length > 0">
      ・{{arr[0].aaa}}
    </p>
```

ただし、この場合配列が空でもpタグは表示される。

<br>
**▼値の場合**
値の場合中身が空でもエラーにならないが、v-ifとBoolean()を使うことで、中身がない場合は表示させないようにできる。

```vue:
    <p v-if="Boolean(text)">
      ・{{text}}
    </p>
```

<br>
**▼配列が空の場合はタグを非表示にする**
上記を組み合わせると、配列に値がある場合のみタグの表示ができるようになる。

```vue:
    <p v-if="Boorean(arr) && arr.length > 0">
      ・{{arr[0].aaa}}
    </p>
```



<br>
VueというよりはJSの問題。JSはnullになる条件も考えながら組んでいく必要がある。
sequelizeのupsertの挙動を説明させて頂きます

# Sequelize使ってますか？
この記事ではsequelizeのほんの1メソッドについて説明するので、sequelizeなんて名前も聞いたことないね。って方はおそらく、何の役にも立たない情報だと思います。そういう方はYoutubeでジャルジャルを見てください。めちゃくちゃ面白いですよ。
 
私のSequelize歴は浅く半年程度です。過去のプロジェクトからの引き継ぎで使ってるものであまり詳しくは理解していません。スマホアプリを作っていまして、私はバックエンドを担当しています。

# ある日、こんな嫌な問題が起こりました。
アプリを社内リリースして、社長がガンガン使ってる時に「なんか、突然他人のデータが見れるようになって、自分のデータは見れなくなったんだけど。」　思い当たる節がなかったので勘も働かず、QAにバグを再現してもらうことになりました。 色々やってくれて、なぜか原因は分からないが1日半かけて同じバグを発生させてもらいました。

認証にはJWTのアクセストークン(とアクセストークンを更新するためのリフレッシュトークン)を使っているのですが、アクセストークンが他のユーザーのものになっていました。アクセストークンが期限が切れた後、リフレッシュトークンでアクセストークンを更新できたことから、リフレッシュトークンも他人のものだと判明しました。`最悪`ですよね。  ユーザーの個人情報が思いっきりリークしてるんですよ。公にローンチする前だったのが、不幸中の幸いです。

# 大きな原因は2つ
- jwtでトークンを発行すると常にユニークだと勘違いしていた。 トークンを発行する`jwt.sign()`は中身(ペイロードやオプション)が全く同じで、UNIX timestampが同じ場合はある特定のトークンを作るということです。
(参考)https://github.com/auth0/node-jsonwebtoken/issues/426
  
  
  
 - sequlizeのupsertはまずはCREATEを試みて、プライマリーキーが被ってる時、または特定のキーを引数で指定し被った時にUPDATEすると勝手に思い込んでいました。


仮に以下のようなテーブルがあったとします。  

| id(primaryKey, autoIncrement) | name | token(unique) |
|:-----------|:------------|:------------|
| 1       | Brasil        | ABC         |
| 2     | Peru      | DEF       |
| 3       | Colombia        | GHI         |
| 4         | Mexico          | JKL           |
| 5       | Peru       | MNO       |
| 6    | Brasil     | OQR      |




`token`はunique制約を持っているとします。

```
await db.tableName.upsert({ name: "Argentina",value:"OQR" });

```
このようなコードが走ったときの、`私の思い込んでた挙動`はtokenが被ってるので、新しくレコードを作れないとエラーを返すことです。
しかし、実際の挙動はガッツリ6行目のレコードをアップデートしにいきます。
(参考)https://sequelize.org/master/class/lib/model.js~Model.html#static-method-upsert



今回の事件は6行目のレコード変更前と変更後で説明がつきます。BrasilさんはOQRというトークンを持っていて、ほんの数100ms以内にトークンを発行したArgentinaさんにもOQRというトークンが発行されてしまい、しかもDBにUPDATEという形で書き込めてしまいます。次にBrasilさんがOQRというトークンを持ってきて、アクセストークンをアップデートしようとすると、DBにはOQRというトークンはArgentinaさんが結びついているので、Argentinaさん用のアクセストークンを発行してしまい、それをBrasilさんに返してしまいます。


# 解決策
リフレッシュトークンのペイロードにユーザーの固有情報を入れるか、n桁のランダム文字列を入れると、異なるユーザー間でトークンが被ることはなくなります。
Salesforce URL Hack in Lightning　3

# 主従関係、参照関係の項目へのデフォルト値のセット

/lightning/o/JucyuMeisai__c/new?defaultFieldValues=Account__c={!JucyuMeisai__c.Account__c}

新しくレコードを作る時に、得意先(取引先）を引用したいと思っています。

Account__cにJucyuMeisai__c.Account__cをセットしようとするのですが上記式ではできません。
テキストの別の項目に値を入れてみると　何故か得意先(取引先）のNameが入っています。

試しに

/lightning/o/JucyuMeisai__c/new?defaultFieldValues=Account__c=001N000001vh5RiIAI

と、得意先(取引先）のIdをセットすると、ちゃんとデフォルト値がセットされます。
このIdは15桁、18桁のどちらでも機能しました。(2022/05/27確認)

どうも、JucyuMeisai__c.Account__cはIdを引用できてない感じ。


仕方ないので、新たに得意先(取引先）のIdである数式項目を作って、その数式項目をセットします。

/lightning/o/JucyuMeisai__c/new?defaultFieldValues=Account__c={!JucyuMeisai__c.AccountId__c}

これだと、きちんとセットできました。

何だろうなぁ。

+ [カスタムボタンを使用した参照項目の引き込みについて](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000MaFPN)


# アイデアに挙がっています。
[**Allow URL hacking feature is missing in Lightning**](https://trailblazer.salesforce.com/ideaView?id=0873A0000003W5qQAE)

これを読んでいると
Salesforce had released URl hacking feature in Spring 20 for lightning. We are using it in our project, however, it has stopped working after Winter 21 release. Winter 21 release notes has no mention about the feature. This is impacting our all users.

@Salesforce Product Team, Do you have any plans to resolve the issue?

Winter21のリリース後に機能しなくなりましと... これってバグかな？

# 式に改行があると動かない？

[Lightning Navigate to Create Record with Default Values not working](https://salesforce.stackexchange.com/questions/319066/lightning-navigate-to-create-record-with-default-values-not-working)

# backgroundContext

Auraでナビゲーションを使用している場合、backgroundContextは、「新規」アクションをオーバーライドするときに背景が空白になるという古い問題を解決します。

```
var pageReference = {
                "type": "standard__objectPage",
                "attributes": {
                    objectApiName: "Event",
                    actionName: "new",
                    additionalParams: ""
                },
                "state": {
                    navigationLocation: "LIST_VIEW",
                    backgroundContext: "/lightning/o/Event/home",
                    count: "1",
                    nooverride: '1',
                    defaultFieldValues: encodedValues,
                    recordTypeId: eventRecordTypeId
                }
            };
```

[Spring 20 - Navigate to a Record’s Create Page with Default Field Values - Return URL not working](https://developer.salesforce.com/forums/ForumsMain?id=9062I000000XqtCQAS)
【Python3.8〜】lambda式でスマートに再帰関数を定義する方法

#はじめに
lambda式でも再帰を使いたいことありますよね（主にネタコードで）。
Python3.8以降ならスッキリかけます。
フィボナッチ数列のx番目を求める関数で比較してみましょう。

#方法
## 〜Python3.7

```python
print((lambda x: (lambda f, x: f(f, x))(lambda f, x: f(f, x-1)+f(f, x-2) if x > 2 else 1, x))(10))
# >> 55
```

## Python3.8〜

```python
print((self:=lambda x:self(x-1) + self(x-2) if x > 2 else 1)(10))
# >> 55
```

**す　ご　く　す　っ　き　り**