OmniAICreator/Qiita-1.07M huggingface dataset:
[Flutter] Desktop / Web アプリでマウスドラッグ操作によるスクロールを有効にする方法

# はじめに

バージョンflutter-2.3.0-12.0.pre以降で、Desktop及びWebアプリにおいてマウスのドラッグ操作でスクロースすることが出来なくなりました。デスクトップ環境でアプリをデバッグしているときにあれ？って思うことがあるので（例えば、横方向へのスクロール操作）、元のようにドラッグ操作でスクロールを使えるようにする方法をまとめておきます。

※ 2021/8/22時点で stable 版にはまだリリースされていない機能ですが、そのうち反映されます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">マウスでドラッグしてもスクロールしないようにする変更。<br>ドラッグでスクロールするのはデスクトップやwebらしくなく感じる一因だと思ってたので嬉しい。<a href="https://t.co/HAIydWHWq8">https://t.co/HAIydWHWq8</a></p>&mdash; Kabo💉 (@kabochapo) <a href="https://twitter.com/kabochapo/status/1389784354017083393?ref_src=twsrc%5Etfw">May 5, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
@kabochapo ツイートありがとう（このツイートをなんとなく覚えていた）

## アプリ全体でマウスドラッグ操作を有効にする方法

`MaterialApp`の`scrollBehavior`に[MaterialScrollBehavior](https://api.flutter.dev/flutter/material/MaterialScrollBehavior-class.html)を継承した独自のインスタンスを渡してあげます。`dragDevices`メソッドで返す値に`PointerDeviceKind.mouse`を追加してあげれば良いです。

```Dart
class MyCustomScrollBehavior extends MaterialScrollBehavior {
  @override
  Set<PointerDeviceKind> get dragDevices => { 
    PointerDeviceKind.touch, // 通常のタッチ入力デバイス
    PointerDeviceKind.mouse, // これを追加！
  };
}

MaterialApp(
  scrollBehavior: MyCustomScrollBehavior(), // これを追加！
  // ...
);
```

## 特定のwidgetでのみマウスドラッグ操作を有効にする方法

目的のwidgetを[ScrollConfiguration](https://api.flutter.dev/flutter/widgets/ScrollConfiguration-class.html)で囲ってあげて、`behavior`に上記と同じように`MaterialScrollBehavior`を継承した独自クラスのインスタンスを与えるだけです。

```Shell
class MyCustomScrollBehavior extends MaterialScrollBehavior {
  @override
  Set<PointerDeviceKind> get dragDevices => { 
    PointerDeviceKind.touch,
    PointerDeviceKind.mouse,
  };
}

final ScrollController controller = ScrollController();
ScrollConfiguration(
  behavior: MyCustomScrollBehavior(),
  child: ListView.builder(
    controller: controller,
    itemBuilder: (BuildContext context, int index) {
     return Text('Item $index');
    }
  ),
);
```

## 参考文献
- [Default drag scrolling devices
](https://flutter.dev/docs/release/breaking-changes/default-scroll-behavior-drag)
- [[flutter] reject mouse drags by default in scrollables #81569](https://github.com/flutter/flutter/pull/81569)
【VBA】Outlook の受信メールを HTML ドキュメントに変換して要素を取得する

HTML 形式で受信したメール本文から、getElementsByTagName というような形で取得情報の絞り込みを行う方法について残しておきます。

# 1. 参照設定

まず、参照設定として、次の２つのライブラリを読み込んでおきます。
・Microsoft Outlook 16.0 Object Library
・Microsoft HTML Object Library
![2021-08-22 141355.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551412/8eb44ab9-72a7-c995-d0aa-4330252d6b3e.png)
なお、`16.0` というのは、アプリケーションのバージョンなので、環境によって異なる場合もあると思います。

# 2. サンプルコード

以下のコードは、メール本文を HTML ドキュメントに変換して、getElementsByTagName メソッドで必要な要素を取得するものです。

なお、このコードでは、受信トレイにあるメールを全てループ処理します。
メール数が1000以上あるような場合は、このまま実行せず、<font color="red">ループ数を調整</font>するようにしてください。

```vb:メール本文をHTML形式で取得
Sub GetReceivedEmailByHtml()
    Dim objOutlook As New Outlook.Application 'Outlookオブジェクト生成
    Dim myNamespace As Outlook.Namespace: Set myNamespace = objOutlook.GetNamespace("MAPI") 'Outlook の NameSpace オブジェクトを取得
    Dim myFolder As Folder: Set myFolder = myNamespace.GetDefaultFolder(olFolderInbox) '受信トレイフォルダーを取得
    
    Dim html As New HTMLDocument 'HTMLDocumentオブジェクト生成
    Dim i As Long, j As Long
    
    On Error Resume Next '取得時にエラーが出る場合を回避（配信不能のお知らせメールなど）
    For i = 1 To myFolder.Items.Count '受信トレイのメール数だけループする
        Debug.Print myFolder.Items.Item(i).SenderEmailAddress '送信者アドレス
        Debug.Print myFolder.Items.Item(i).ReceivedTime '受信時間
        Debug.Print myFolder.Items.Item(i).SentOn '送信時間
        Debug.Print myFolder.Items.Item(i).Subject '件名
        Dim htmlBody As String: htmlBody = myFolder.Items.Item(i).htmlBody 'HTML本文
        
        html.Body.innerHTML = htmlBody 'HTMLドキュメントに変換して格納
        Debug.Print html.Body.getElementsByTagName("a")(0).outerHTML 'aタグのうち最初に見つかったものを出力
    Next i
    On Error GoTo 0
End Sub
```

# 3. 簡単な説明

VBA で Outlook の受信メールを取得する方法の基本的なことは、[こちら](https://qiita.com/t-yama-3/items/37545fa9a00c140fb657)を参照してください。
以下、要点だけ書いておきます。

## 3-1. メール本文を HTML 形式で取得

次のところで、受信トレイのメールから、HTML形式（テキスト）で受信メールを取得しています。

```vb:Sample
    htmlBody = myFolder.Items.Item(i).htmlBody
```
`myFolder` は受信トレイとなります。
続く `Items.Item(i)` で、メールを１つずつ取り出しています。
最後の `htmlBody` で HTML 形式のテキストで本文を取得しています。

## 3-2. HTMLDocument オブジェクトに変換

上記で、HTML 形式で取得した本文データはテキストデータのため、そのままでは `getElementsByTagName` メソッドなどを使用して要素の取得をすることはできません。

これを、HTML ドキュメントとして扱うために、`HTMLDocument オブジェクト` を使用します。

### 3-2-1. HTMLDocument オブジェクトのインスタンス作成

次の１行で HTMLDocument オブジェクトのインスタンスを作成しています（HTML ドキュメントを格納する入れ物）。
これには `Microsoft HTML Object Library` の参照設定が必要になります。

```vb:Sample
    Dim html As New HTMLDocument 'HTMLDocumentオブジェクト生成
```
なお、参照設定をしない場合は、次のように書きます。

```vb:Sample（参照設定をしない場合）
    Dim html As Object
    Set html = CreateObject("htmlfile") 'HTMLDocumentオブジェクト生成
```

### 3-2-2. HTML ドキュメントに変換

次の１行で、テキストデータ（htmlBody）を、HTML ドキュメントに変換しています。

```vb:Sample
    html.Body.innerHTML = htmlBody
```

以上で、`html` を HTML ドキュメントととして操作することが可能になります。
あとは、スクレイピングの際と同じ手法で、要素を特定していくことができると思います。

＜参考サイト＞
・[エクセルVBAでIEを使わずにHTMLドキュメントを取得する方法](https://tonari-it.com/excel-vba-http-document-write/)
シンボルについて

# シンボルとは何か？
> シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェクトです。
文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。同じ内容のシンボルはかならず同一のオブジェクトです。
シンボルオブジェクトは以下のようなリテラルで得られます。


引用：公式ドキュメント
https://docs.ruby-lang.org/ja/2.6.0/class/Symbol.html

###シンボルと文字列の違い
シンボルと文字列の違いについて説明します。
シンボルは、Symbolクラスのオブジェクトで、文字列はStringクラスのオブジェクトになります。

```Ruby
:apple.class #=> Symbol
"apple".class #=> String
```

シンボルはRubyの内部で整数として管理されます。そのため、文字列よりも高速に処理を実行出来ます。
また、『同じシンボルであれば同じオブジェクトである』という特徴を持ちます。このため、大量の同じシンボルと文字列を作成した場合、シンボルの方がメモリの使用効率が良くなります。

```Ruby
:apple.object_id #=> 1143388
:apple.object_id #=> 1143388
:apple.object_id #=> 1143388

"apple".object_id #=> 0223819213380
"apple".object_id #=> 0223819213120
"apple".object_id #=> 0223819277810
```
また、文字列のように破壊的な変更は出来ないという特徴を持ちます。

###シンボルの特徴と主な用途
####◎特徴
**・内部的には整数なので、高速に処理することが出来る。**
**・同じシンボルは同じオブジェクトであるため、メモリの効率が良い。**
**・イミュータブルなオブジェクトなので、勝手に値が変えられる心配がない。**
<br>
※イミュータブルオブジェクト・・・作成後にその状態を変えることのできないオブジェクトのことである。対義語はミュータブル (英: mutable) なオブジェクトで、作成後も状態を変えることができる。

####◎用途
**・ハッシュのキー { :key => "value" }**
**・アクセサの引数で渡すインスタンス変数名 attr_reader :name**
**・メソッド引数で渡すメソッド名 __send__ :to_s**
**・C の enum 的な使用 (値そのものは無視してよい場合**

###参考文献
[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/gp/product/4774193976/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4774193976&linkCode=as2&tag=ykms1230e-22&linkId=7d182a6724516a0f1a495c33599a4946)・・・伊藤淳一[著]
Herokuの紹介

# Herokuとは
https://jp.heroku.com/

クラウドサービスの1つで、PaaSに分類される。
現在はSalesforce社が提供している。

# 対応言語
- Ruby
- Java
- Node.js
- PHP
- Python
- Go
- Scala
- Clojure

# Herokuの特徴
## 無料で使用できる
- アカウントを作成すると、5人までフリープランを使用可能。  
フリープランでも基本的な機能をほぼ全て無料で使用できるため、個人でアプリケーションの開発・運用を行うには十分。

## リリース作業が簡単
- gitを内包しているため、資材をプッシュするだけですぐにデプロイすることができる。  
また、GitHubなど外部のプラットフォームと連携することも可能。

## アドオンが豊富
- 多数のアドオンが用意されており、機能の拡張がやりやすい。

## AWSとの連携
- Heroku自体がAWS上に構築されているサービスであるため、AWSのサービスとの連携も可能。  
ただし、一部機能を除き東京リージョンが使えない。

# Heroku CI
Herokuでは、CICDの仕組みを簡単に構築できる。
以下の3ステップで導入可能。

1. Heroku Pipelineを作成する。
GUI上でappにdevelop、staging、productionの3つの環境を追加するだけ。
https://devcenter.heroku.com/articles/pipelines

1. Heroku CIを有効化する。
GUI上の設定画面で「Enable CI」を押下するだけ。

1. 資材の中に、以下のようなapp.jsonを作成する。(gradleでビルドを行う場合)
https://devcenter.heroku.com/ja/articles/app-json-schema

```json:app.json
{
  "environments": {
    "test": {
      "scripts": {
        "test": "gradlew build"
      }
    }
  }
}
```

- develop環境 ⇒ staging環境 ⇒ production環境のリリースがボタン1つで行えるため、リリース作業も非常に簡単。
- アドオンを導入すれば、Heroku CIでDBなどを使用することも可能。
- 資材管理をGitHubなど外部のプラットフォームで行っている場合はHeroku CIでのテスト結果を連携することができる。
[SwiftUI]UIActivityIndicatorViewを作成する

## 投稿の経緯
個人開発中のアプリでインディケーターを作成したので備忘録。

## 環境
Swift version 5.4.2
Xcode version 12.5.1

## 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643372/c35b9b9b-05e5-0240-1b17-e5440be21d0c.png)

表示されているViewの上に`opacity`をつけた背景と画面中央にインディケーターを表示させます。

## インディケーターの作成
```swift
import Foundation
import SwiftUI

struct ActivityIndicator: UIViewRepresentable {
    func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
        UIActivityIndicatorView(style: .large)
    }

    func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) {
        uiView.startAnimating()
    }
}
```

`UIViewRepresentable`を使って`UIActivityIndicatorView`を作成します。
インディケーターをカスタムする場合は`updateUIView`の中で`uiView`をカスタムしてあげれば編集できます。

## インディケーターの呼び出し
```swift
@State private var isShowsIndicator = false


var body: some View {

    /////省略/////

    if isShowsIndicator {
        ZStack {
            Color.black.opacity(0.5)
                .edgesIgnoringSafeArea(.all)
            ActivityIndicator()
        }
        .animation(.linear)
    }
}
```

`@Stateオブジェクト`を使ってインディケータの表示する状態を管理します。
今回の場合、`isShowsIndicator`がtrueでインディケータを起動させるのでこのように書いています。

インディケーターを表示する時に背景色として`ZStack`で囲んでColorと重ねます。
アニメーションをつけると自然にインディケーターが表示されるので書いています。

## お知らせ
現在、iOS開発案件を業務委託で募集中です（副業）。[TwitterDM](https://twitter.com/ken_sasaki2)でご依頼をお待ちしています
Next.jsで自己紹介サイトを作った。



巷では、「**Next.js**」が流行っているらしいですね。

今回は、「**Next.js**」の勉強のために自分の自己紹介サイト↓を作ったので、忘備録を書きます。

https://yoshito.khufrudamonotes.com/

独学なので、技術的な内容は正しくない可能性があります。
もし誤りがあれば、コメントで教えていただけると幸いです。

#Next.jsとは？

**React**の機能を拡張するための**JavaScriptフレームワーク**。
サーバーサイドレンダリング(**SSR**)ができるのがウリ。

みたいな感じだと捉えています。

追記：もう古いみたいです。↓

https://qiita.com/jagaapple/items/faf125e28f8c2860269c

#サーバーサイドレンダリング(SSR)とは？

ページを表示する方法にはいくつかあって

#####- クライアントサイドレンダリング(CSR)
→「サーバーから送られてきたファイル」を元に、ブラウザでページの見た目を作る。
（シンプルなHTML/CSS/JacaScriptのページがこれ。）

#####- シングルページアプリケーション(SPA)
→「サーバーから送られてきた最低限必要なファイル」を元に、JavaScriptでページの見た目を作る。
(Reactがこれ。)

#####- サーバーサイドレンダリング(SSR)
→「Node.js（サーバー側のJavaScript）で見た目を作った状態のページ」がブラウザに送られてくる。
(Next.jsがこれ。)
　
**シングルページアプリケーション**は、JavaScriptで見た目を切り替えるので、表示を切り替る速度が速い。
**サーバーサイドレンダリング**は、あらかじめ出来上がったものを送ってくるので、ページの表示速度が速い。
みたいな感じでしょうか。

https://qiita.com/amakawa_/items/e7d0720e1ab8632769bf

#Next.jsを使うまでの ざっくりとした流れ

試したOSは**Windows10**です。

###①Node.jsをインストールする。

公式サイトから**インストーラ**をダウンロードします。

https://nodejs.org/ja/

インストーラーを使って**Node.js**をインストールします。

###②パッケージマネージャをインストールする。

「**npm**」や「**yarn**」が有名っぽいです。
昔は、**yarn**の方が便利だったみたいですけど、現在は大きな差は無いみたいです。

今回は、勉強も兼ねて**yarn**を使いました。

**npm**は、**Node.js**をインストールしたら使えるので、**npm**を使って

```
$ npm install -g yarn
```
↑コマンドを入力すると**yarn**をインストールできます。

https://qiita.com/rubytomato@github/items/1696530bb9fd59aa28d8

###③パッケージマネージャを使ってNext.jsの環境構築をする。

任意のフォルダにcdコマンドで移動した後

```
npx create-next-app
```

↑コマンドを入力します。
次に、「名前どうする？」みたいな質問をされるので、一通り答えます。
すると、任意のフォルダ内に、**Next.js**を動かすのに必要なファイルを作ってくれます。

ファイルが出来上がったら、任意のフォルダ内で

```
yarn dev
```

↑コマンドを入力すると、ローカルサーバーが立ち上がって
（たぶん）**http://localhost:3000/**からページを確認可能になります。

ローカルサーバーを止めるときは「**Ctrl＋C**」です。

詳しくは公式ドキュメントを参考にしてみてください。
https://nextjs.org/learn/basics/create-nextjs-app/setup

#詰まったところ

###TailwindCSSの導入

ドキュメントにやり方が書いてありました。

https://tailwindcss.com/docs/guides/nextjs


###Googleアナリティクスの導入

こちらの記事が参考になりました。

https://fwywd.com/tech/next-ga-pv


#その他　参考にさせていただいたページや動画

https://www.youtube.com/watch?v=F77RUjHZEAc&t=176s

https://youtu.be/YoIQ_FIBlYY

https://youtu.be/5TymbaeyV-0

https://youtu.be/hL6bDTNQhAc

https://maku.blog/p/9vakw8i/
Jupyterでの出力を自前で定義する

## 概要
`__repr__()`を実装すれば`display()`の出力を定義できます。

## 環境
- Python 3.7.11
- jupyter-notebook 5.2.2

[Google Clolab](https://colab.research.google.com/)を用いました。

## Jupyterの出力
jupyterは、セルの最後の式の評価値を出力として表示します。これは、内部的には`IPython.display.display()`と同じ挙動をしています。

```python
# Jupyterでない純粋なPythonの場合はimportが必要
from IPython.display import display

hoge = "ほげ"
display(hoge) #=> 'ほげ'
```

`display()`は`print()`とは若干異なります。Jupyterでの実行結果は下記のようになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/21c4c3a5-eb19-03ac-687e-8a88140de7e1.png" width=320 />

## 出力を自前で定義する方法
自前で定義したクラスなどでは、そのままではあまり有用な出力が得られません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/9622d65e-2af1-63e4-8c4c-a069c020cff9.png" width=640 />

`display()`の内部では`__repr__()`を呼んでいるため、これを実装すると好きな出力を得ることができます。なお同様に`print()`では`__str__()`が呼ばれています。

```python
class MyClass2:
    def __init__(self, name: str):
        self.name = name
    def __str__(self):
        return "<str:{}>".format(self.name)
    def __repr__(self):
        return "<repr:{}>".format(self.name)
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/bebb2be5-4f47-f1cf-eac9-994ced748d99.png" width=320 />

## 参考
`__str__()`と`__repr__()`の違いや実装時の注意点等は、下記公式ドキュメント等を参考にしてください。

- [Module: display — IPython 7\.26\.0 documentation](https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#IPython.display.display)
- [3\. データモデル — Python 3\.9\.4 ドキュメント](https://docs.python.org/ja/3/reference/datamodel.html#object.__repr__)
rbenvのバージョン管理

<h2>よく使うコマンド</h2>
rbenvを使用前
・homebrewのアップデートとアップグレード

homebrewのアップデートとアップグレード

```
$ brew upgrade && brew update
```

rbenvだけのアップデートをするのであれば

```
$ brew upgrade ruby-build && brew update
```
[brew upgrade]でもupdateは行われますが、updateを入力するのは確認のためです。
ちゃんとアップデートできたら

```
$ brew update
Already up-to-date.
```
と出力されます。

さらにhomebrewが正常に動作しているかのテスト

```
$ brew doctor
```
も行っておきます。
ちゃんと動作しているなら

```
$ brew doctor
Your system is ready to brew.
```
と出力されます。

brewのアップデートとアップグレードを別々にするなら下記
homebrewのアップデート

```
$ brew update
```
homebrewのアップグレード

```
$ brew upgrade
```

<h5>rubyのバージョン確認</h5>
rbenvで使用しているバージョンの確認

```
$ rbenv versions
```

入っているrubyのバージョンが出力される

```
$ rbenv versions
system
  2.5.1
  2.6.5
* 2.6.6 
  2.6.8
  3.0.1
```
＊（アスタリスク）が頭についているのが使用しているバージョンです。

<h5>rbenvでrubyを切り替える方法</h5>
rbenv versionsで調べ入っているrubyのバージョンから選びます。

```
$ rbenv global [バージョン]
// 例)
$ rbenv global 3.0.1
```
rbenv globalのあとの処理

・切り替わった確認

```
$ rbenv versions
```

<h2>たまに使うコマンド</h2>
rbenvでインストールできる安定版のruby

```
$ rbenv install --list
```
rbenvでインストールできるすべてのruby

```
$ rbenv install --list-all / -L
```

下記のように出力されます。

```
$ rbenv install --list
2.6.8
2.7.4
3.0.2
jruby-9.2.19.0
mruby-3.0.0
rbx-5.0
truffleruby-21.2.0.1
truffleruby+graalvm-21.2.0
```

[rbenv install --list] や
[rbenv install --list-all / -L]
などを参考にしてrubyをインストールします。

```
$ rbenv install [バージョン]
```

インストール後は上にかいていることと重複しますが、
インストールされたか確認

```
rbenv versions
```
バージョンの切り替え

```
rbenv global [バージョン]
```
切り替わったか確認

```
rbenv versions
```


現時点で使っているRubyとディレクトリ（フォルダ）の確認
PATHが通っているならmacのデフォルトでもバージョンの確認できます。

```
// macで使用しているrubyのバージョン
$ ruby -v
```
[rbenv versions]と同じバージョンが表示されるはずです。

```
// macで使用しているrubyのディレクトリ（フォルダ）の確認
$ which ruby
```

rbenvのインストールからバージョン管理までもやります。
【Laravel】sortByとorderByについてのメモ

※この記事は初学者が書いています。おかしな部分などありましたら教えて頂けると嬉しいです※

環境:Laravel 6.2

## sortByとorderByの違い

Laravel公式には
**sortByメソッドは指定したキーでコレクションをソートします。**
**orderByメソッドは指定したカラムでクエリ結果をソートします。**
と書かれている

これがそのまま答えとなり、
sortByは　`User::get()->sortBy('id');`　のように、
get等で取得したコレクションをソートする時につかう。
当然getする前はコレクションではないので
`User::sortBy('id')->get();`
のような使い方はできない。

orderByは逆で　`User::orderBy('id')->get();`　のように
get等で取得する前のクエリのソートにつかう。
`User::get()->orderBy('id');`
のようにコレクションに対して使うことはできない。

## AscとDescについて
Ascは昇順（小さい順）、Descは降順（大きい順）。
sortByもorderByもデフォルトが昇順なので
sortByなら`sortBy('id')`が昇順、`sortByDesc('id')`が降順。
orderByなら`orderBy('id')`が昇順、`orderByDesc('id')`が降順。
なお、orderByは`orderBy('id','desc')`という書き方もある。
【Laravel】既存のテーブルにカラムを追加した時のメモ

環境：Laravel6.2

※※初学者が自分用のメモも兼ねて書いています。おかしなこと言ってたら教えて頂けると嬉しいです※※

## 1.マイグレーションファイルを作成する。



既存テーブルに入っているデータが消えてもいいなら
rollback後にテーブル作成時のマイグレーションファイルを編集して改めてmigrateしても良いが
既存テーブルのデータを消したくないのであれば
カラム追加用の新たなマイグレーションファイルを作成する必要がある。

```:マイグレーションファイル作成コマンド
php artisan make:migration add_age_to_posts_table --table=posts
```
↑add_age_to_posts_tableの部分がファイル名になるので内容がわかりやすい名前に。
--table=posts　の部分には追加（編集）したいテーブル名を入れる。

## 2.出来上がったマイグレーションファイルを編集

```php:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class UpdateBooksAddUnique extends Migration
{
  public function up()
  {
    Schema::table('books', function (Blueprint $table) {
          $table->string('tag');
    });
  }
  public function down()
  {
    Schema::table('books', function (Blueprint $table) {
         $table->dropColumn('tag');
    });
  }
}
```

upメソッドとdownメソッドがあり、
upのほうには編集したい内容（追加や削除や制約の変更など）を入力。今回の作業はカラムの追加なので、上記のように入力。
downのほうはrollbackした時用なので、upと逆の処理を書く。
（upでhogeカラム追加の記述をしたならdownにはhogeカラム削除の記述をする。逆にupが削除ならdownは追加。）

downは書かなくても動作はするが、rollback時に困ることになるので基本は書く。

## 3.マイグレーション実施

```:マイグレーション実施コマンド
php artisan migrate
```
Laravelで /(トレイリング スラッシュ)がついているURLを扱うには

# やりたいこと
Laravelの標準ではURLのトレイリングスラッシュが削除されてしまうため、
削除されていないURLを取得・生成したい。

# 環境
Laravel 8.35.1
PHP 7.4.19

# トレリングスラッシュがついたURLを取得する
Illuminate\Http\Requestクラスをオーバーライドする

```php:app/Services/Vendor/Http/Request.php
use Illuminate\Http\Request as BaseRequest;

class Request extends BaseRequest
{
    /**
     * Get the URL (no query string) for the request.
     *
     * @return string
     */
    public function url()
    {
        return preg_replace('/\?.*/', '', $this->getUri());
    }
}
```
Requestクラスを上のオーバーライドしたクラスに置き換える

```php:public/index.php
// use Illuminate\Http\Request;
use App\Services\Vendor\Http\Request;
```
トレイリングスラッシュがついたURLが取得出来る

```php
$request->fullUrl(); // http://localhost/api/works/
```

# トレイリングスラッシュがついたURLを生成する
Illuminate\Routing\UrlGeneratorクラスをオーバーライドする

```php:app/Services/Vendor/Route/UrlGenerator.php
use Illuminate\Routing\UrlGenerator as BaseUrlGenerator;

class UrlGenerator extends BaseUrlGenerator
{
    /**
     * Create a new manager instance.
     *
     * @param BaseUrlGenerator $url
     */
    public function __construct(BaseUrlGenerator $url)
    {
        parent::__construct($url->routes, $url->request);
    }

    /**
     * Format the given URL segments into a single URL.
     *
     * @param string $root
     * @param string $path
     * @param null $route
     * @return string
     */
    public function format($root, $path, $route = null)
    {
        $path = parent::format($root, $path);

        $mathes = null;
        preg_match("/([^\/]+?)?$/", $path, $mathes);
        $last = $mathes[0] ?? '';

        if (strpos($last, ".") === false) {
            return $path . "/";
        }
        return $path;
    }
}
```

上のクラスを登録する

```php:app/Providers/AppServiceProvider.php
    public function boot()
    {
        $url = $this->app['url'];
        $this->app->singleton('url', function () use ($url) {
            return new UrlGenerator($url);
        });
    }
```

トレイリングスラッシュがついたURLが生成出来る

```php
route('api.works.index') // http://localhost/api/works/
```

以上

# 参考
https://readouble.com/laravel/4.2/ja/extending.html
https://qiita.com/watanuki_p/items/ce123404b569214ecff2
URPで歪みシェーダーの実装

# 前書き
URPで背景のバッファの取得とその使用方法をまとめました。

サンプルはGitHubに上げています。
https://github.com/eorfeorf/DistortionShaderInURP


# 環境
Unity2020.3.14f1
Universal RP 10.5.1 (ForwardRenderer)
Shader Graph 10.5.1


# 実装方法
## 描画されたバッファを取得する
`Universal Render Pipeline Asset`の`Opaque Texture`にチェックを入れます。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/E/EorF/20210820/20210820205913.png)

ShaderGraphでは`SceneColor`ノードで`OpaqueTexture`を取得できます。
入力は`UV`、出力は`Color`です。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/E/EorF/20210820/20210820233741.png)

## 歪ませる
歪みはテクスチャをサンプリングする際のUVをずらすことで表現できます。
サンプルでは`Gradient Noise`ノードを使用してUVをずらしています。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/E/EorF/20210821/20210821010619.png)
出力結果
![](https://cdn-ak.f.st-hatena.com/images/fotolife/E/EorF/20210821/20210821005549.png)

# おまけ：ノイズテクスチャをUVに適用する
## ノイズテクスチャをスクロール
タイリングやオフセットは専用の`Tiling And Offset`ノードがあり、`Offset`に`Time`ノードの`Time`を入れると時間経過でスクロールします。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/E/EorF/20210821/20210821015436.gif)

## ノイズをUVに加算する
ノイズテクスチャは白黒で表現されており、値としては0~1になっています。
このまま使っても良いのですが、UVが全体的にずれることになり、実物と見える位置が大きく異なります。
そこで使うのが`Remap`ノードです。
このノードは与えられた数値を指定した数値範囲にマッピングしてくれる優れものです。
今回では`0~1`を`-0.01~0.01`の範囲にリマッピングしています。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/E/EorF/20210821/20210821020019.png)

あとは出力された値を`ScreenPosition`と足し合わせることでUVがずれ、歪みとして表現されます。


# 最後に
URPではGUIでチェックを入れ、ShaderGraphでテクスチャが取得ができるので非常に簡単でした。


# 参考文献

# 転載元
https://eorf.hatenablog.com/entry/2021/08/21/021016
【Laravel】Call to undefined function App\Http\Controllers\curl_init()

###LaravelのController内でcurl_init()を呼び出すとエラーになる

```:エラー内容
Error
Call to undefined function App\Http\Controllers\curl_init()
```

###原因

php.iniのcurlが有効になっていない

###解決策
php.iniのcurlを有効にする

#####php.iniがどこにあるか探す

下記コマンドを実行すると、現在のディレクトリにphpinfo.txtが作られある
```
php -i > phpinfo.txt
```

phpinfo.txtを開き、

` Loaded Configuration File => `を探す

ここにphp.iniがどこにあるかが記載されている。自分の場合は

```
Loaded Configuration File => C:\tools\php80\php.ini
```

chocolatey経由でphpをインストールした場合はC直下にtoolsが作られ、そこに入っていると思われます。

#####extension=curlを有効にする

php.iniを開き、extension=curlで検索して、コメントアウトを外す。

#####サーバーを再起動したら完了！！
オブジェクト指向について

# クラス
C#でオブジェクト指向プログラミングする上での基礎。

```ruby
namespace Material
{
    class Material
    {
        //プロパティ ①
        public int Code { get; private set; }
        public string Name { get; private set; }
        public int Mass { get; private set; }

        //コンストラクタ ②
        public Material(int code, string name, int mass)
        {
            this.Code = code;
            this.Name = name;
            this.Mass = mass;
        }

        //メソッド ③
        public int GetMass()
        {
            return Mass * 2;
        }
    }
}
```

### ①プロパティ
<dl>
　<dt>setアクセサ</dt>
　<dd>クラスの外部からの値の変更の処理。<br>
例では、private(非公開)のため、<br>
コンストラクタ以外でプロパティの値が<br>
設定できないようになっています。
　</dd>
</dl>
<dl>
　<dt>getアクセサ</dt>
　<dd>クラスの外部からの値の取得の処理。</dd>
</dl>

### ②コンストラクタ
クラス名と同じ名前の特殊なメソッド。
インスタンスを初期化するためのメソッドとなります。

### ③メソッド
処理の塊。

## オブジェクトの利用
```ruby
namespace Material
{
    public class Test
    {
        static void Main(string[] args)
        {
            //インスタンスの作成 ①
            Material materialA = new Material(1,"物質A",100);
            //プロパティの利用 ②
            int mass = materialA.Mass;
            //メソッドの利用 ③
            int massDouble = materialA.GetMass();
            Console.WriteLine(mass);
            Console.WriteLine(massDouble);
        }
        
    }
}
```

### ①インスタンスの作成
newをすることでメモリにmaterialAのオブジェクトが作成されます。<br>この時、Materialクラスのコンストラクタが呼び出され、引数の値がコンストラクタに渡されます。

### ②プロパティの利用
Materialクラスに定義されているMassプロパティの値を取得します。

### ③メソッドの利用
Materialクラスに定義されているGetMassメソッドで計算された値が返ってきます。


※サンプルコードでの出力結果は以下となります。<br>
Console.WriteLine(mass);の結果が100
Console.WriteLine(massDouble);の結果が200

## 継承
#### 継承とは

すでに定義されているクラスをもとに、<br>
その性質を受け継ぎ、拡張や変更を加えて<br>
新たなクラスを作成(派生する。ともいう)

```ruby
    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }

        public string GetProfile()
        {
            return "氏名:" + FirstName + LastName + Environment.NewLine + "年齢:" + Age;
        }
    }
```
上記のPersonクラスを継承し、<br>
社員番号と所属部署を加えた<br>
Employeeクラス(社員クラス)を定義します。

```ruby
    //①
    public class Employee : Person
    {
        public int Id { get; set; }
        public string DivisionName { get; set; }
    }
```

①クラス名にコロン(:)を付け、その後に継承元のクラスを指定します。<br>

<dl>
　<dt>継承元</dt>
　<dd>スーパークラスまたは「基底クラス」</dd>
</dl>

<dl>
　<dt>継承して定義したクラス</dt>
　<dd>サブクラスまたは「派生クラス」</dd>
</dl>

```ruby
    class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee
            {
                Id = 100,
                DivisionName = "開発部",
                FirstName = "テスト",
                LastName = "太郎",
                Age = 34,

            };
            Console.WriteLine("部署:{0}　ID：{1}", employee.DivisionName, employee.Id
                + "のプロフィール" + Environment.NewLine + employee.GetProfile());
        }
    }
```

継承を使えばEmployeeクラスを1から作る必要がなくなります。
継承は、一般的に「is a関係」が成り立つときに使用されます。
(社員は人である、三角形は図形である・・・等)



##### 参考文献
###### この記事は以下の書籍を参考にして執筆しました。
実戦で役立つ
C#プログラミングのイディオム/定石＆パターン
MacからRaspberryPiのGUIを表示させる方法

# きっかけ
OpenCVによる顔認識をRaspberryPi上で動作させたいと思い、プログラムを書いていました。
実際にプログラムを動作させる段階になり、顔をどのように認識しているかチェックしたかったのですが、MacからSSHして見ているCUI上だと何も出来ず...
RaspberryPiのGUIで確認したいのだが、一々キーボード・マウス・HDMIをRaspberryPi上に繋げるのも面倒...
何かいい方法が無いかと探してみました

# やりたい事
- MacからRaspberryPiにサッとリモート接続して、GUIを表示させる

# やった事
- RaspberryPiにVNCサーバのインストール
- MacからVNCサーバと化したRaspberryPiへのリモートアクセス

## VNC(Virtual Network Computing)

> VNCとは、ネットワークを通じて別のコンピュータに接続し、そのデスクトップ画面を呼び出して操作することができるリモートデスクトップソフトの一つ。また、オリジナルのVNCを元に開発された派生ソフトウェア群の総称。様々な環境に移植され、相互に接続可能なため、異なるOSで操作するコンピュータの画面を呼び出して操作することができる。
> 参考: [VNC 【Virtual Network Computing】 IT用語辞典](https://e-words.jp/w/VNC.html)

- VNCはリモートデスクトップソフトの名称
- VNCサーバ：リモート接続受け入れが出来ているサーバ
- VNCクライアント：VNCサーバに対してリモート接続する事が可能なクライアント

## TightVNC
RaspberryPiのVNCサーバとして、TightVNCを使用する

> What is TightVNC?
> TightVNC is a free remote desktop application. With TightVNC, you can see the desktop of a remote machine and control it with your local mouse and keyboard, just like you would do it sitting in the front of that computer.
> 参考：[TightVNC Software](https://www.tightvnc.com)

# リモート接続までの道のり
## 流れ
1. RaspberryPiにVNCサーバのインストール
2. tightvncserverの起動
3. MacからRaspberryPiへリモートアクセス

###  RaspberryPiにVNCサーバのインストール
```
$ sudo apt-get update
$ sudo apt-get install tightvncserver
```

### tightvncserverの起動
```
# 起動
$ tightvncserver

# Passwordの初期設定
You will require a password to access your desktops.

Password:
Warning: password truncated to the length of 8.
Verify:

# ViewOnlyのパスワードを設定するか
Would you like to enter a view-only password (y/n)? n

New 'X' desktop is raspberrypi:1

Creating default startup script /home/pi/.vnc/xstartup
Starting applications specified in /home/pi/.vnc/xstartup
Log file is /home/pi/.vnc/raspberrypi:1.log
```

### MacからRaspberryPiへリモートアクセス
MacのFinderで、移動 -> サーバーへ移動 を行う。
![スクリーンショット 2021-08-22 14.00.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142839/7c16947f-923c-ee10-94ff-fda37fa362aa.png)

Host名の変更を行っていない場合は、`vnc://raspberrypi.local:5901`とすれば接続が出来る。
VNCサーバのPortは何も設定していない場合、5901になるらしい。
![スクリーンショット 2021-08-22 14.01.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142839/eb5115d6-f0fa-a584-34a6-bc9b1c6219bb.png)


GUIが表示されれば完了
![スクリーンショット 2021-08-22 14.03.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142839/05bfd27e-64df-9c69-2139-f5629b8ad155.png)
本家 MicroPython の M5ATOM 対応

いつのまにか、本家 MicroPython の github に esp32 ポートのボードに M5 Atom が追加されていたので、最新ソース(2021年8月22日)をビルドして試してみました。

# ビルド

### ESP-IDF 環境の用意(v4.0.2を使う場合)

以下に従って ESP-IDF 環境を用意

https://docs.espressif.com/projects/esp-idf/en/v4.0.2/get-started/index.html#installation-step-by-step

### MicroPython コードのフリーズ(コンパイル)環境ビルド

```bash
$ cd micropython  # MicroPython のソースコードのフォルダ
$ make -C mpy-cross
```

### M5 Atom 用ファームウェアのビルド

```bash
$ cd ports/esp32
$ make submodules
$ make BOARD=M5STACK_ATOM
```

### ファームウェアの書込み

```bash
$ make PORT=<Atomが繋がっているシリアルポート>　erase
$ make PORT=<Atomが繋がっているシリアルポート> BAUD=<ボーレート> deploy
```

※ PORTのデフォルトは `/dev/ttyUSB0` 、BAUDのデフォルトは `460800` 。

# GENERIC　ビルドとの違い

### ビルド済みで配布されているファームウェアとの違い

以前より M5 Atom では[ビルド済みで配布されているESP32用のGENERICファームウェア](https://micropython.org/download/esp32/)が使えます。M5 Atom 対応で変わったところをざっと調べてみたところ `atom` モジュールの追加だけのようです。

`atom` モジュールには GPIO ピンの定数定義、Matrix と Lite のクラスが追加されており、ボタンとLEDの利用が若干便利になっています。

### モジュール `atom`

#### 定数

<dl>
<dt>`WS2812_PIN`
<dd>フルカラーLED(Neopixel)が繋がっているピン番号(27)
<dt>`BUTTON_PIN`
<dd>ボタンの繋がっているピン番号(39)
<dt>`IR_PIN`
<dd>IRトランスミッターの繋がっているピン番号(12)
<dt>`I2C0_SCL_PIN`
<dd>I2C の SCL に使うピン番号(21)
<dt>`I2C0_SDA_PIN`
<dd>I2C の SDA に使うピン番号(25)
<dt>`GROVE_PORT_PIN`
<dd>Grove ポートに使われているピン番号のタプル (26, 32)
</dl>

#### クラス `Matrix`

<dl>
<dt>コンストラクタ
<dd>引数なし。LED数が25個で設定される。
<dt>メソッド `get_button_status()`
<dd>ボタンが押されていなければ 1、押されていれば 0 を返す
<dt>メソッド `set_button_callback(cb)`
<dd>引数 `cb` に指定した関数をボタンが押されたときに呼び出されるコールバック関数として設定する
<dt>メソッド `set_pixel_color(num, r, g, b)`
<dd>`num` (0-24)番目の LED に RGB 値を設定して実際に LED の点灯に反映する         
<dt>メソッド `get_pixel_color(num)`
<dd>`num` (0-24)番目の LED に設定されちる RGB 値を取得する
<dt>メソッド `set_pixels_color(r, g, b)`
<dd>すべての LED に RGB 値を設定して実際に LED の点灯に反映する
</dl>

#### クラス `Lite`

LED数が１にり、LED番号として指定できるのが 0 のみになる以外は `Matrix` クラスと同じ。

### サンプル

ボタンを押すたびに 消灯→赤→緑→青 で全LEDが切り替わるサンプル。

```python
from atom import Matrix

atom_matrix = Matrix()

led_pat_no = 0
led_pat_num = 4
led_pat = ((0, 0, 0), (127, 0, 0), (0, 127, 0), (0, 0, 127))

def atom_led_cb(pin):
    global led_pat_no
    led_pat_no += 1
    if led_pat_no >= led_pat_num:
        led_pat_no = 0
    atom_matrix.set_pixels_color(*led_pat[led_pat_no])

atom_matrix.set_button_callback(atom_led_cb)
```
Firebase Hosting上のNuxtアプリが動的ルーティングのページでリロードすると404になる時の対処法

# はじめに
環境：nuxt:2.15.7, MacOS

Nuxtアプリ（ssr）をFirebase Hostingにデプロイして動的ルーティングを指定したページ（`_id.vue`）でリロードすると404になってしまったのでメモ。
![スクリーンショット 2021-08-22 10.23.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631045/462f2412-6ff5-5f0f-1d19-98f951c5ef23.png)
例えば以下のようなディレクトリ構成だと、`/articles/1`、`/articles/2`のようなルーティングになる。

```sh
pages
├── articles
    ├── _id.vue
```

ローカルだと問題ないのだが、Firebase Hostingにデプロイしたアプリで`/articles/1`にアクセスしてリロードすると404エラーになってしまった。

# 対処法
[Firebaseの公式](https://firebase.google.com/docs/hosting/full-config?hl=ja#rewrites)を参考に、`firebase.json`の`"hosting":{}`内に`rewrites`を設定すると期待通りに動いた。


```diff:firebase.json
  "hosting": {
    "public": "dist",
+  "rewrites": [
+     {
+       "source": "**",
+       "destination": "/index.html"
+     }
+   ],
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
  }
```
最初のfirebaseの環境構築で質問責めされる時、答えようによってはデフォルトで`rewrites`が設定されるらしい。
後はご自身でカスタマイズして欲しい。
Pythonのリスト内包表記による2次元配列の転置

# リストの転置
~~調べても出てこなかったので。~~
たくさん出てきます。きちんと調べましょう（ごめんなさい）。
2次元配列aを転置したものを変数bに代入することを考えます。
b[x][y]にはa[y][x]の要素が入っています。
配列aの縦と横の大きさは同じでなくてもよいものとします。

# for構文を使ったやり方
こちらが一般的なやり方でしょうか。

```python
# 転置する配列
a = [[1,  2,  3,  4],
     [5,  6,  7,  8],
     [9, 10, 11, 12]]

# 配列aの縦と横の大きさ
height = len(a)
width = len(a[0])

# 配列bを、各要素を0で初期化して定義
b = [[0] * height for _ in range(width)]

# aを転置したものをbに代入
for i in range(height):
    for j in range(width):
        b[j][i] = a[i][j]

# 結果確認
print(b)  # [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
```

# リスト内包表記を使ったやり方
こちらの方がすっきり書けます。
が、私はこのやり方だと頭がこんがらがります。精進します。

```python
# 転置する配列
a = [[1,  2,  3,  4],
     [5,  6,  7,  8],
     [9, 10, 11, 12]]

# 配列aの縦と横の大きさ
height = len(a)
width = len(a[0])

# aを転置したものをbに代入
b = [[a[y][x] for y in range(height)] for x in range(width)]

# 結果確認
print(b)  # [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
```
超初心者向け人工知能入門

![qiita1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/037ce68d-0907-de56-d611-ab61c6f87db5.jpeg)


---
![qiita2_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/d15ba6dc-5750-7139-afa1-099fec559c72.jpeg)


---
![qiita3_2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/39cb5d90-91d3-7d70-5a51-01c3f98b7bba.jpeg)

---
![qiita4_2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/093a7fb1-80a7-8523-34c6-c28c31b56f71.jpeg)

---
![qiita5_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/b2da4a96-80c8-46ea-9d34-0eb1546c2576.jpeg)

---
![qiita6_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/b12424a0-e85a-8023-1c52-af226a77099d.jpeg)

---
![qiita7_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/c3bb6c56-3acc-7824-2518-663b7a967bb3.jpeg)
Macでgitを使用してみた

right(engineer)です。

今回は、Macでgitを使用してみたので、
手順をまとめます。

# 環境 

- MacBook Pro (macOS Big Sur：Ver.11.3.1)
- Git (Ver.2.30.1)

# Gitの構成について
基本知識として、gitの構成を以下にまとめた。

- 作業ディレクトリ(ワークツリー)
- ステージングエリア(インデックス)
- ローカルリポジトリ
- リモートリポジトリ

# Gitのインストール〜リポジトリ作成まで
1.gitをインストールする。

```
$ git --version
```

2.gitにユーザ名を登録する。

```
$ git config --global user.name "ユーザ名"
```

3.gitにメールアドレスを登録する。

```
＄ git config --global user.name "メールアドレス"
```

4.githubのアカウントを作成する。
<https://github.com/>

5.githubでリモートリポジトリを作成する。

次にgitからgithubのリモートリポジトリへプッシュする。

6.ローカルにフォルダを作成する。

```
$ mkdir "フォルダ名"
$ cd "フォルダ名"
```

7.イニシャルする。

```
$ git init
```

8.プッシュ先のリモートリポジトリを指定。

```
$ git remote add origin <https://URL>
```

9.フォルダ内にファイル作成。

```
$ touch "ファイル名".c
```

10.gitにファイルをコミットする。ログを入力する。

```
$ git add "ファイル名".c
$ git commit -m "メッセージ"
```

11.ローカルブランチを確認。(masterを確認。)

```
$ git branch
```

12.ファイルをローカルリポジトリからリモートリポジトリへプッシュする。

```
$ git push origin <master>
```

13.githubのリモートリポジトリにファイルが反映されていることを確認する。

# まとめ
Macでgitを導入する機会があったので、備忘録として手順をまとめてみた。
流れをまとめると以下のようになる。
・Gitのインストール(Macの場合、初めからインストールされている)
・Gitのユーザ名/メールアドレス登録
・Githubのアカウント作成
・Githubでリモートリポジトリ作成
・Gitでローカルリポジトリへファイルをコミットする。
・Gitでローカルリポジトリからリモートリポジトリへプッシュする。

今後は以下を実施したいと考えている。
・Windows10環境でのgit環境導入
・GitとVSCodeの連携

# 参考文献
<https://techacademy.jp/magazine/6235>
vue3.0 EventBus 任意のコンポーネントから仕込んでいたVOIDを実行する

データはProvide/inject機能で親戚関係にあるコンポーネントをまたがって利用できる。
今回は子や孫コンポーネントの内部変数を変更する関数を指定しておき、任意のタイミングで親のコンポーネント側から発火させるやり方。

PrimeVUEのprestigeをvue3.0Typescriptで使いやすいように変更している場面で必要な機能だった。
PrimeVueEventbusという機能で実装されていたがjsしかなかったので別機能を使用して移植。

mitt
Raspberry Pi 3 Model B+ 向けにリアルタイムOSを実装してみた話

Raspberry Pi 3 Model B+ 向けにリアルタイムOSを実装したので、その話をします。
Raspberry Pi 4でも動くとは思いますが・・・。

もともと、うまく動作確認ができればお金を取ったり、起業したりする計画もあったのですが、やけっぱちのOSS化です。

ある日、「そうだ、OS作ろう」と思いたってしまい、ちまちまとデータ構造などを設計していました。
で、実際に作り始めるにあたって、ターゲット・デバイスをどうするかという問題にぶち当たりました。
ネット上で色々調べると、比較的高価な機材を買わずとも、Raspberry PiでJTAG接続ができるという記述を見つけました。
そんなわけで、Raspberry Pi向けに、Cortex-Aをターゲット・コアとしてOSのコーディングをはじめました。

し・か・し・・・。

実際にOSが組みあがり、実機での検証をしようとした際、問題が発生しました！
なぜか、ldr疑似命令を実行した段階でRaspberry Piが暴走してしまう。ネット上で検索しても、質問しても、原因がわからず、1年以上の時間が経過しました。
正直、これ以上悩んでいても仕方がないし、解決のめどもまったく立たないので、広く世間に公開して知恵を集めることにしました。

で、このOSについてですが、基本はOSEK/VDX + μITRON4.0な仕様となっています。
詳しい仕様は基本設計書を見て頂くとして、肝心のコードはセルフ・レビューもしておらず、動作確認も上述の事情で最低限しかできていません。
なので、不具合は多数潜んでいると思われます。使用の際は、心してかかってください。

ホーム：
http://fuqs.web.fc2.com/computer/lab/fos.htm

GitHub：
https://github.com/tenkoh2/SSF-OS

Wiki：
https://wiki3.jp/SSF-OS
iOSインターン生が、『リーダブルコード』から学んだこと

# はじめに

インターンで開発をしているときに自分の書いたコードに対して不安を持つようになったので、答え合わせと知識の取得を目標に**『リーダブルコード』**を読んでみました。
今回は自分の力量までの内容だけつまみ読みをする形で読んだので、そこに関して備忘録として残しておきます。

# 学んだこと（随時更新）

- 変数の定義が多い場合は、その変数を使う直前に定義するとわかりやすい！
- ifなどにおいて、関心が含まれる条件は`!`使ってもOK
- 関数で`guard-return`を利用するように、ループ文では`guard-continue`または`break`が使える。
- ifとelseはなるべく近いほうが見やすい
- ネストを深くするということは、プログラマの精神的スタックに条件を溜め込むということ
- ド・モルガンが意外と利用できる
- ライブラリの文書読むと引き出しめっちゃ増える


# 合ってたこと

- グローバル変数は絶対使わない
- 名前は長くても具体的に
- 要約変数という考え方。しかし一度しか使わない場合や、変数が無くても読み取りが容易である場合は必要なし
rubyのsendメソッドってどんなメリットがあるの？

こんにちは、プレイライフの熊﨑です！

rubyのsendメソッドがどんなことをしてくれるメソッドなのかはなんとなく理解していましたが、どんなメリットがあるかまでは恥ずかしながら理解しておりませんでした。
そこで、今回はsendメソッドのメリットについてまとめていきたいと思います！

## sendメソッドとは？
レシーバーの持っているメソッドを文字列やシンボルで指定して呼び出すメソッド
以下のように書きます。

```sample.rb
# Foo.barと書くのと同じ
Foo.send("bar")
```

## どんなメリットがあるのか？
- 条件分岐を書かなくても、メソッドを使い分けることができる。

### 例： 赤信号の場合stop, 青信号の場合goと表示するプログラム

```signal.rb
class TrafficSignal

  # 今は２つしか条件がないが、この条件が膨らんでくると、コード量が増え、可読性も落ちてくる。
  def display_message(signal_color)
    if signal_color == "red"
      display_red_message
    elsif signal_color == "green"
      display_green_messsage
    end
  end

  def display_red_message
    "stop"
  end

  def display_green_messsage
    "go"
  end
end

signal = TrafficSignal.new
puts signal.display_message("red")
puts signal.display_message("green")

```

sendメソッドを使用すると、以下のように書き換えることができる。

```signal.rb
class TrafficSignal

  # 条件分岐を書く必要がなくなる。
  # def display_message(signal_color)
  #  if signal_color == "red"
  #   display_red_message
  # elsif signal_color == "green"
  #   display_green_messsage
  # end

  attr_accessor :signal_color

  def initialize(signal_color)
    @signal_color = signal_color
  end

  def display_red_message
    "stop"
  end

  def display_green_messsage
    "go"
  end
end

signal = TrafficSignal.new("red")
puts signal.send("display_#{signal.signal_color}_message")
```

## 注意点
ユーザーからの入力値をそのままsendメソッドに引き渡すと、悪意あるユーザーがrailsアプリを強制終了させることができてしまうので、要注意

```sample.rb
# 下記のように書くと、悪意のあるユーザーがexitと入力した場合、アプリが終了する。
# exitはKernelモジュールに定義されているメソッド。KernelモジュールはBasicObject以外のすべてのクラスで使用可能。

signal.send("#{params[:signal_color]}")
```

## まとめ
- sendメソッドはレシーバーの持っているメソッドを動的に呼び出すことができる。
- 便利な反面、使い方を誤るとセキュリティーホールを作ってしまうので注意して使用する必要がある。

## 参考文献
[https://qiita.com/igrep/items/b2fed2d467f8a16f5eb0#fn1](https://qiita.com/igrep/items/b2fed2d467f8a16f5eb0#fn1)
[https://docs.ruby-lang.org/ja/latest/method/Object/i/send.html](https://docs.ruby-lang.org/ja/latest/method/Object/i/send.html)
async await メモ

### sample

```javascript
const af = async ()=>{
  setTimeout(()=>{
    console.log("anonymouse func")
  }, 500);
  const ret = await new Promise((resolve)=>{
    console.log("promise function");
    //return 123; // Invalid Code
    resolve(123);
  }).then(r=>{
    console.log(`r:${r}`)
    return r
  });
  console.log("end");
  return ret
}

console.log("before")
const ret = af()
console.log("after")
ret.then(r=>console.log(`r ${r}`));
```

### result
```console
> "before"
> "promise function"
> "after"
> "r:123"
> "end"
> "r 123"
> "anonymouse func"
```

### memo
* async は非同期呼び出しを可能とする定義
* await は、Promise.resolveでラップした値を返す
* new Promise()に渡した関数は、引数のresolveに渡された値をPromiseでラップして返す
* Promise.then()は、resolveされた値を引数に取り、returnした値をPromiseでラップして返す

# 参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function
What is Routing?

経路制御ともいう。
ネットワーク上のデータ配送経路を決定する制御の事である。
ネットワークのトポロジとトラフィック状態に関する情報を収集するためのプロトコルと、ネットワークを介したルートを設計するためのアルゴリズムで構成される。

## ルーティングの役割
パケットを送信するときに最適な配達経路を選択します。
ルーターやL3スイッチがルーティングの役割を担っています。
ルーターは、ルーティングテーブルと呼ばれる情報を持っており、それには、パケットの宛先と次の転送先が記されています。

```
> show ip route
宛先ネットワーク   |    ゲートウェイ    |    インターフェース    |    種別    |    付加情報
192.168.100.0/24      192.168.100.1            LAN1            implicit 
192.168.200.0/24      192.168.100.254          LAN1            static 
```
```
//宛先ネットワーク
  パケットの宛先となるネットワークです。
//ゲートウェイ
  パケットを次に転送する先です。
//インタフェース
  パケットを転送するルーター自身のインタフェースです。
//種別
  ルーティングの種類です。たとえば、静的ルーティングの場合は static、動的ルーティングのRIPの 場合は RIP、ルーター自身が管轄するネットワークの場合は implicit と表示します。
//付加情報
  ルーティングの種類ごとに使用する情報です。
```
[ルーティングの種類は後述します](https://qiita.com/Nakazawa-musc/items/666d1bb5b2025c9a3a05#%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E7%A8%AE%E9%A1%9E)

## ルーティングのルール
ルーティングには2つのルールがある。
### ルール1　ロンゲストマッチの法則  
　受信パケットの宛先IPアドレスに該当するルート情報がルーティングテーブルに複数ある場合、設定された経路のうち最も長くネットマスクと一致した方を優先する。
###  ルール2 ルーティングテーブルにない宛先のパケットは破棄する 
パケット破棄の後、ルータはパケットの送信元へ宛先到達不能（ Destination Unrechable ）メッセージをICMPパケットで通知する。
## ルーティングの種類
実際のネットワークはとても複雑なルーティングを行います。
### 静的ルーティング
人手によってあらかじめルーターに作成しておく方法です。

```
//メリット
・少ない知識でも設定できる
・通信帯域やルーターに負荷が少ない
//デメリット
・ネットワーク構成が変わった場合、すべてのルーターの経路設定を見直す必要がある
・一般的に、経路に障害が発生した場合、代替の経路を利用して通信を継続できない。
```
### 動的ルーティング
ルーター同士が通信して取得した結果をもとにして作成する方法です。

```
//メリット
・ネットワーク構成が変わっても経路設定を変更しなくてよい
・経路に障害が発生した場合、代替の経路を利用して通信を継続できる
//デメリット
・ルーティングプロトコルの知識が必要である
・通信帯域やルーターへ負荷がかかる
・誤った経路の情報が流されると広い範囲にわたって障害が発生する
```
動的ルーティングにはいくつかのプロトコルがあります。

#### RIP（Routing Information Protocol）
宛先までに経由するルーターの数（ホップ数）をもとにして、最小のホップ数の経路を選択する方式である。
OSPFへの移行が進んでいるが、現在でも企業内の小規模なネットワークで利用されている。
#### OSPF（Open Shortest Path First）
RIPに代わるルーティングプロトコルとして開発された。
宛先までの帯域幅など（コスト）をもとにして、最小のコストの経路を選択する方式である。
多くの企業内ネットワークで利用されている。
#### BGP（Border Gateway Protocol）
AS間の経路設定を交換するためのルーティングプロトコルとして開発された。
インターネットのAS間での経路設定で利用されている。

## LANやWANでのルーティング
ネットワークごとに、使われるルーティングは違います。

|ネットワークの種類 |使用されるルーティングの種類  |
|---|---|---|
| LAN |小規模　　　静的ルーティング、動的ルーティング（RI）     |
|     |中規模以上　動的ルーティング（OSPF）
| WAN |AS内　　　　動的ルーティング（RIP、OSPF）|
|     |AS間　　　　動的ルーティング（BGP）      |
AtCoder参加記録No.3ーABC215

#ABC215
今回参加したABC215についての参加記録

2021年8月21日（土）のAtCoder Beginner Contest 215でした。

https://atcoder.jp/contests/abc215



##結果

A,B問題を正解
レート：28→42 (+14) Highest!
順位:6766/ 8537
時間: A問題25:54   B問題32:05
パフォーマンス:137

##詳細

###A問題
[問題](https://atcoder.jp/contests/abc215/tasks/abc215_a)

提出コード（AC)

```python:A問題.py
N = input()
if N =='Hello,World!':
  print('AC')
else:
  print('WA')
```

[提出コード詳細](https://atcoder.jp/contests/abc215/submissions/25218492)


###B問題

[問題](https://atcoder.jp/contests/abc215/tasks/abc215_b)

提出コード（AC)

```python:B問題_1.py
N = int(input())
A =0
for i in range(1000):
  if 2**i<=N:
    A=i
  else:
    A=A
print(A)
```

[詳細](https://atcoder.jp/contests/abc215/submissions/25221299)

###C問題

[問題](https://atcoder.jp/contests/abc215/tasks/abc215_c)

解法が全く思いつかずに未回答

###D問題

[問題](https://atcoder.jp/contests/abc215/tasks/abc215_d)

解法は思いついたが計算量O(N*M*logN)以上であるためでTLE
提出1回目（TLE）

```python:D問題_1.py
N,M =map(int,input().split())
Z = list(map(int,input().split()))
import math
A=[]

for i in range(1,M+1):
  ok = True
  for x in range(N):
    if math.gcd(Z[x],i)==1:
      ok=ok
    else:
      ok=False
  if ok:
    A.append(i)
print(len(A))
for i in range(len(A)):
  print(A[i])
```

[詳細](https://atcoder.jp/contests/abc215/submissions/25226698)

提出2回目（WA）

```python:D問題_2.py
N,M =map(int,input().split())
Z = list(map(int,input().split()))
import math
A=[]

for i in range(1,M+1):
  ok = True
  for x in range(N):
    if math.gcd(Z[x],i)==1:
      ok=ok
    else:
      break
  if ok:
    A.append(i)
print(len(A))
for i in range(len(A)):
  print(A[i])
```

[詳細](https://atcoder.jp/contests/abc215/submissions/25231051)

提出3回目（TLE）

```python:D問題_3.py
N,M =map(int,input().split())
Z = list(map(int,input().split()))
import math
A=[]

for i in range(1,M+1):
  ok = True
  for x in range(N):
    if math.gcd(Z[x],i)==1:
      ok=ok
    else:
      ok=False
      break
  if ok:
    A.append(i)
print(len(A))
for i in range(len(A)):
  print(A[i])
```

[詳細](https://atcoder.jp/contests/abc215/submissions/25231440)

##振り返り、反省
今回もバイト後の参加のためスタートが遅れてしまった。
A,B問題は普通に解けた。

A,B問題については特になし

C問題についてはstr型を使った問題を解いた経験が少ないため解法が分からなかった。
経験を積んでC問題が解けるように勉強していきたい。

D問題は提出前から計算量が多いことがなんとなくわかっていたがそのまま提出。

案の定TLEで正解ならず。2206secでTLEであったためその後悪あがきしたが、実行時間は変わらず終了。

##感想

今回は凡ミスがなく良かった。
コンテスト以外にも問題をといて経験を積みたい。
現在[アルゴリズム実技検定公式テキスト](https://www.amazon.co.jp/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E5%AE%9F%E6%8A%80%E6%A4%9C%E5%AE%9A-%E5%85%AC%E5%BC%8F%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%83%BC-%E4%B8%AD%E7%B4%9A%E7%B7%A8-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/483997277X)を用いて勉強中なのでそれが終わったら問題をたくさん解いていきたい。
ubuntuのswap sizeの変更

# 注意

swapをssd上に作ると、寿命を摩耗します。
壊してもよいssdにするか、それとも、hddを使いましょう

# 現在のswapのサイズの確認

```
$ free -h
              total        used        free      shared  buff/cache   available
Mem:            15G        6.5G        2.7G         29M        6.4G        8.8G
Swap:          2.0G        565M        1.4G

$ sudo swapon --show
NAME      TYPE SIZE   USED PRIO
/swapfile file   2G 565.8M   -2
```

# swapサイズの変更

```
$ sudo swapoff /swapfile
$ sudo fallocate -l 16G /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
$ sudo swapon -s
ファイル名				タイプ		サイズ	使用済み	優先順位
/swapfile                              	file    	16777212	0	-2
$ free -h
              total        used        free      shared  buff/cache   available
Mem:            15G        7.6G        3.5G         67M        4.5G        7.6G
Swap:           15G          0B         15G
```

# 一時的なswapの追加

上は最初から作られていたswapfileなので、/etc/fstabで定常的に有効化されていますが、
一時的に追加する方法

```
$ sudo fallocate -l 16G /swapfile_tmp
$ sudo mkswap /swapfile_tmp
$ sudo swapon /swapfile_tmp
$ sudo swapon -s
```
再起動後に、swapon -sしても使われていないはずです。

恒久的に使いたくなったら

```/etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sdc1 during installation
UUID=mkswapしたときのuuid /               ext4    errors=remount-ro 0       1
/swapfile_tmp                                 none            swap    sw              0       0
```

のようにしてみてください
論文用にtensoraboradのlogをpandasのデータフレームに変換するライブラリ

論文を書くとき提案手法のhyper parameterの依存性を調べるためにhyparparamterとmetricの図を書くことがよくある
実験のlogはtensorbaord logに出力しているので、tensorboard logを集めていい感じにpandasのdata frameにしてくれると便利そう。

## 作ったもの

https://github.com/MasanoriYamada/tensorboardpy

## 使い方

以下のようにtensor boardのlogがある場合

```
runs
├── 0
│   └── events.out.tfevents.xxx.0
├── 1
│   └── events.out.tfevents..xxx.1
├── 2
│   └── events.out.tfevents.xxx.2
├── 3
│   └── events.out.tfevents.xxx.3
└── 4
    └── events.out.tfevents.xxx.4
```

dirを指定すると再帰的にevent fileを探して１つのdata frameにまとめます
読み込むのは add_scalarとhparamsの情報です。

```python
from tensorboardpy import logdir
df = logdir('path/tensorboard_logdir')
```

読み込んだlogが以下のような場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53186/09904ed8-3589-f4ca-ebe6-9de5606ebe82.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53186/ec1c6a64-495b-e3b8-836c-4eb3c4bd2c21.png)

以下のようなdataframeが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53186/e03007a8-ca13-9c3b-b80f-44aa8dcda7fd.png)

## 便利関数
このままでは、hyparparamterの組み合わせに対して、epoch(step)が複数存在するので、metricに対してmaxやminなどのルールに従いdataframeを整形します。
例えば、各hyperparametrのセットに対してtrain/accがmaxのstepだけ抜き出してくるなど

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53186/493227d3-316d-fe6f-be18-d55ff8e92642.png)
BootstrapとjQueryでスライドショーを作成する

<h2>初めに</h2>
Bootstrapのカルーセル機能と
jQueryを使用してぬるっと動くスライドショーを作成しました。
今回udemyの有料講座を見てそれを若干いじって作成してます。
コードを全部のせるようなことはないのでわかりにくいと思います。


<h2>完成イメージ</h2>
以下イメージ図です。分かりにくくてすみません。
画面横幅いっぱいのスライドショーです。自動でスライドしていきます。

![スクリーンショット 2021-08-22 11.45.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/b3acb5a7-2ab5-6a95-e5cc-f5d17c4890da.png)

<h2>Bootstrapでスライドショー作成</h2>

以下のudemyの講座を参照し、作成しましたので詳しい説明はしません。
以下の講座はBootstrapがとてもよく理解できます！

https://www.udemy.com/course/bootstrap4-g/

```html
<div class="carousel slide" data-ride="carousel" id="carousel">
 <div class="carousel-inner">

＃以下は下の棒を出す記述です
    <ol class="carousel-indicators">
        <li class="active" data-target="#carousel" data-slide-to="0"></li>
        <li  data-target="#carousel" data-slide-to="1"></li>
        <li data-target="#carousel" data-slide-to="2"></li>
        <li data-target="#carousel" data-slide-to="3"></li>
        <li data-target="#carousel" data-slide-to="4"></li>
      </ol>

＃以下が１枚目のスライドです。
  <div class="carousel-item carousel-image-1 active">
＃文字を入れる必要なければ以下は不要です。
   <div class="carousel-caption d-none d-md-block">
     <p class="title1 d-none d-lg-block">Welcome</p>
     <p class="introduction"><br>"書きたい文章あれば"</p>
   </div>
  </div>

＃１枚目と同様に２枚目のスライドについて記述します。
１枚目をactiveにしてるので、２枚はactiveは不要です。
activeにするとページ読んだ時に一番最初に表示されます。

省略
```

全体をcarousel slideで囲み、その中にcarousel-innnerクラスを作成します。
そしてその中に、carousel-itemと文字を入れたければ
carousel-captionを作成します。
d-noneの記述は画像が小さくなったら文字は表示しないという記述になります。

<h2>CSSの記述</h2>

こちらも割愛します。

```perl:homes.scss
.carousel-image-1 {
  background-image: image-url("lighthouse.jpg");
  background-size: cover;
  background-position:center;
  position: relative;
  width: 100%;
  height: 600px;
}
```

画像のimage-urlという記述は本番環境でも対応できるようにこのように書いています。
```background-size: cover;```画像の縦横比を崩すことなく、画像ができるだけ大きくなるよう配置。
```background-position:center;```真ん中が大事だから真ん中を基準に配置してもらう

<h2>動かす</h2>
今回はHTMLファイルに直接書きました。

```html
<style>
  $(".carousel").carousel({
    /*２秒間隔*/
    interval: 2000,
    /*マウスが乗ったら止める*/
    /*pause: "hover",*/
  })
</style>
```

カルーセルクラスを取得し、
カルーセルメソッドを使用しています。

<h2>終わり</h2>

以下の講座は本当にわかりやすいのでおすすめです。


https://www.udemy.com/course/bootstrap4-g/