OmniAICreator/Qiita-1.07M huggingface dataset:
Phoenix LiveViewのページタイトル

今日は[LiveView](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html)の[HTML title](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title)をページ移動の際に更新する方法についてまとめます。

- [4/17(土) 00:00〜 4/19(月) 23:59開催のautoracex #23](https://autoracex.connpass.com/event/210477/)での成果です。
- [English edition](https://dev.to/mnishiguchi/page-title-for-phoenix-liveview-347b)

[Phoenix LiveView 公式ドキュメント](https://hexdocs.pm/phoenix_live_view/live-layouts.html#updating-the-html-document-title)によると、`socket.assigns[:page_title]`にページタイトル文字列を代入するだけの簡単な作業でした。

```elixir
defmodule MnishiguchiWeb.EnvironmentLive do
  use MnishiguchiWeb, :live_view

  def mount(_params, _session, socket) do
    socket = assign(socket, page_title: "Environment")
    {:ok, socket}
  end

  ...
```

これで問題は解決しましたが、もうちょっと踏み込んで「モジュール名をもとにページタイトルを生成できないのか」興味が湧いてきました。

[Phoenix.Naming](https://hexdocs.pm/phoenix/Phoenix.Naming.html)という便利なモジュールがありました。

```elixir
iex> MnishiguchiWeb.EnvironmentLive |> Phoenix.Naming.resource_name("Live") |> Phoenix.Naming.humanize()
"Environment"
```

[Phoenix.Naming](https://hexdocs.pm/phoenix/Phoenix.Naming.html)を用いて簡単な関数を書きました。

```elixir
defmodule MnishiguchiWeb.LiveUtils do
  @doc """
  Generates a page title string based on the specified LiveView module atom.

  ## Examples

      iex(1)> LiveUtils.page_title(MnishiguchiWeb.EnvironmentLive)
      "Environment"

      iex(2)> LiveUtils.page_title(MnishiguchiWeb.Environment.MeasurementsLive)
      "Measurements"

  """
  def page_title(view_atom) when is_atom(view_atom) do
    view_atom
    |> Phoenix.Naming.resource_name("Live")
    |> Phoenix.Naming.humanize()
  end
end
```

そしてLiveViewの`mount`で`assign`します。

```elixir
defmodule MnishiguchiWeb.EnvironmentLive do
  use MnishiguchiWeb, :live_view

  @default_assigns [
    page_title: MnishiguchiWeb.LiveUtils.page_title(__MODULE__),
  ]

  def mount(_params, _session, socket) do
    socket = assign(socket, @default_assigns)
    {:ok, socket}
  end

  ...
```

手作業で各ページのタイトルを決定してもたいして時間がかからないので、いちいちこんなことする必要はないのかもしれませんが、ここに至るまでの学びのプロセスを楽しみました。

あえてメリットいうと、新しいLiveViewを作成する際にコピー・ペーストでできることでしょうか。

個人的にはこのシンプルなソリューションに満足していますが、マクロ等を駆使したもっときれいなアプローチがあるのかもしれません。

そういえば、サイト全体のタイトルを自分の好みに設定するために、以前に[こういうの](https://dev.to/mnishiguchi/phoenix-1-5-page-title-gdg)を書きました。

https://dev.to/mnishiguchi/phoenix-1-5-page-title-gdg

[国際化 (i18n)](https://ja.wikipedia.org/wiki/%E5%9B%BD%E9%9A%9B%E5%8C%96%E3%81%A8%E5%9C%B0%E5%9F%9F%E5%8C%96)にも挑戦したいですね。

以上

https://autoracex.connpass.com/

https://join.slack.com/t/elixirjp/shared_invite/zt-ae8m5bad-WW69GH1w4iuafm1tKNgd~w

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html

https://hexdocs.pm/phoenix_live_view/live-layouts.html#updating-the-html-document-title

https://hexdocs.pm/phoenix/Phoenix.Naming.html
継承の関係が民法典のパンデクテン方式に似てるなという感想

##はじめに
私は昨年から法学部生として法律を勉強しています。
民法講義の一回目で学ぶパンデクテン方式が、プログラミングの継承の考え方に似てるなと思ったのでまとめてみます。
##民法典でパンデクテン方式をとる意義
日本には民法という法律があります。
これは買い物や結婚など、私たちの生活に密接に関わるもののルールを定めています。
生活の中には様々な法律関係があるため、民法の条文数は1000を超えています。（第1条、第2条というやつです。）

民法典ではこの大量の条文をただ並べるのではなく、必要なものを素早く見つけるために、パンデクテン方式という考え方で条文が整理されています。

##パンデクテン方式とは
Wikipediaでは次のように説明されています。
>パンデクテン方式（パンデクテンほうしき）とは、民法典において、一般的・抽象的規定を個別的規定に先立ち「総則」としてまとめることにより、法典を体系的に編纂することに主眼をおいた著述形式である。

つまり細かい規定を定める前に、そのすべてに共通する事項をくくりだして先に提示しておくということです。

例えば買い物や結婚などについて詳しく定める前に、これらの法律行為は信義に従って誠実に行いましょうね、ということを総則に置いています。
##パンデクテン方式を継承で
このパンデクテン方式が下記のようなスーパークラスとサブクラスの関係で表せるのではないかと思いました。（４編と５編は省略）

```Java:pande.java
public class 第１編総則{
}
public class 第２編物権 extends 第１編総則{
}
public class 第３編債権 extends 第１編総則{
}
```
また第２編物権や第３編債権もそれぞれ固有の総則をもっており、その編で共通の事項をくくりだしています。

##まとめ
共通する部分をまとめてくくりだすることで、全体がコンパクトになり機能の所在が分かりやすくなりますね。
たまたま継承がパンデクテン方式に似てるなと思いましたが、くくりだしの考え方を用いるものは他分野でも多く見られるのではないでしょうか。
【AWS】マネージドサービス/アンマネージドサービスとは？【初心者】

# 概要

AWSについて学習していたときに出てきた、マネージドサービス/アンマネージサービスについて理解するのに少し混乱したためまとめてみた。

# 参考書籍

[ゼロからわかる Amazon Web Services超入門 はじめてのクラウド かんたんIT基礎講座](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%82%8F%E3%81%8B%E3%82%8B-Amazon-Services%E8%B6%85%E5%85%A5%E9%96%80-%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89-%E3%81%8B%E3%82%93%E3%81%9F%E3%82%93IT%E5%9F%BA%E7%A4%8E%E8%AC%9B%E5%BA%A7-ebook/dp/B07TFTGHMX/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%82%8F%E3%81%8B%E3%82%8BAmazon+Web+Services%E8%B6%85%E5%85%A5%E9%96%80&qid=1618669761&s=books&sr=1-1)

# マネージドサービス/アンマネージサービス

## マネージドサービスとは

特定の目的の設定が完了した状態のサービスを貸し出すサービスを**マネージドサービス**という。
代表的なものとしてS3などが挙げられる

## アンマネージドサービスとは

素のままのサーバーを貸し出すサービスを**アンマネージドサービス**という。
代表的なものとしてEC2などが挙げられる

## 責任分界点

マネージドサービスとアンマネージドサービスでは、どこまでを自分で担当するか、どこまでクラウドサービスが担当してくれるかという違いもある
この担当の分岐点のことを**責任分界点**という
責任分界点がクラウドサービス側に寄っているものほど保守運用をクラウドサービスに任せられる = 運用の手間を軽減できるということになる。

## SaaS、PaaS、IaaS

クラウドを語るとき、「どこまでの機能が提供されるのか」を分ける用語として**SaaS**、**PaaS**、**IaaS**という3つの言葉がよく使われる。

### SaaS

ソフトウェアの機能がサービスとして提供されるもの。
多くのマネージドサービスがこれに相当し、利用者は保守・運用の一切を任せることができる。

### PaaS

アプリケーションを実行するためのプラットフォームを提供するもの。

### IaaS

ネットワークや仮想的なサーバーなど、インフラ部分を提供するもの。
アンマネージドサービスがこれに相当し、利用者は全体の保守・管理をする必要がある。
enumとenum_helpの使い方【rails】

### はじめに
`enum`と`enum_help`について

### enumって何？？
モデルで数値のデータ型で定義しているカラムを、
文字列型として使えるようにすることができます。

例えば、0は男性、1は女性みたいな感じです。

### 定義方法
enumはモデルに定義する必要があります。
定義の仕方は主に2つあります。

・名前だけを定義する方法
・名前とそれに対応する数値を定義する方法

では、1つずつ見ていきましょう！

####  1.名前だけを定義する方法
まず、前提としてUserモデルのroleカラムがあるという前提で説明していきます。


```rb:models/user.rb
class User < ApplicationRecord
  enum role: [ :general, :admin ]
end
```

上記のように定義します。

「role」の部分がカラム名です。
その横に配列として、使いたい名前を定義していき、左から順番に0から数字が紐づけられていきます。

上の例でいうと、
「general: 0, admin: 1」という風になります。

ちなみ後から下記のように定義を追加した場合、

```rb:models/user.rb
class User < ApplicationRecord
  enum role: [ :general, :writer, :admin ]
end
```

「general: 0, writer: 1, admin: 2」と言う風になります。

つまり、後から定義したとしても、数字は前から順に割り振られていきます。
なので、仮にすでにデータベースに「admin」が保存されていた場合、
それが「writer」ということになってしまいます。

####  2.名前とそれに対応する数値を定義する方法

```rb:models/user.rb
class User < ApplicationRecord
  enum role: { general: 0, admin: 1 }
end
```

こちらの方法は、明示的に名前と対応する数字を定義します。

ちなみに、こちらの方法は後から定義を追加する場合は
下記のように数字を明示的に指定する必要があります。

```rb:models/user.rb
class User < ApplicationRecord
  enum role: { general: 0, writer: 2, admin: 1 }
end
```
なので、先程のようにデータが途中から変わってしまうというようなことは起こり得ません。
明示的に指定したほうがわかりやすいので私はこちらの方法を推奨します。

また、一番最初に定義している値、つまり「general: 0」の値をデフォルトとしてモデルに定義すると、より良いです。

```rb:マイグレーションファイル
class AddRoleToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :role, :integer, null: false, default: 0
  end
end
```

### コンソールで使ってみる
```rb:コンソール
irb(main):001:0> User.roles    ※定義済のカラムを参照
=> {"general"=>0, "admin"=>1}  ※ハッシュ形式で保存されている

irb(main):002:0> User.roles[:general] ※ハッシュなので一項目だけ参照することも可能
=> 0
irb(main):003:0> User.roles[:admin]
=> 1

irb(main):004:0> user = User.first

irb(main):005:0> user.general?  ※このような便利なメソッドも使えるようになります。
=> false
irb(main):006:0> user.admin?
=> true

irb(main):006:0> user.general!  # roleをgeneralに変更する

irb(main):006:0> User.general  # roleカラムがgeneralのデータを取得する
                               # User.where(role: :general)と同じ挙動
```

### enum_helpって何？？

enum_helpとはenumで定義した値をi18n化させることができるgemです！

現段階では下記のようになります。

```rb:コンソール
irb(main):007:0> user.role
=> "admin"

※これを日本語にしたい！
```

### 導入方法

導入方法は簡単！
enum_helpというgemを追加して、localeに翻訳を設定するだけです！

```rb:Gemfile
gem 'enum_help'
```
```
$ bundle install
```
```rb:config/locales/activerecord/ja.yml
ja:
  enums:
    user:
      role:
        general: 一般
        admin: 管理者
```
```rb:コンソール
irb(main):007:0> user.role
=> "admin"

irb(main):008:0> user.role_i18n  ※カラム名のあとに「_i18n」をつけて呼び出す
=> "管理者"
```

enum_helpを導入すると、便利なヘルパーも追加されます。

```rb:コンソール
irb(main):011:0> User.roles
=> {"general"=>0, "admin"=>1}

irb(main):012:0> User.roles_i18n
=> {"general"=>"一般", "admin"=>"管理者"}

irb(main):013:0> User.roles_i18n.invert
=> {"一般"=>"general", "管理者"=>"admin"}  ※キーとバリューが入れ替わる！
```
このinvertメソッドはセレクトボックスを使う時やransackを利用した時などに有効です！

※間違いなどあればコメントください！
Codeforces Round #715  Div. 2C The Sports Festival: 区間DP典型

https://codeforces.com/contest/1509/problem/C

区間DPの超典型。以下、0-indexed。

# この問題の難しさ
入力をソートして、どこからかスタートし、最適に左右にとり続ければよいことがわかるが、これでは、ある地点をスタートして、左右どちらに行くかを計算するため、$O(2000*2^{2000})$のオーダーとなる。

# アプローチ
まず、入力をソートしてn個の要素を$a_0, a_1, ..., a_{n-1}$とする。
ある区間$[l, r)$の最善なコストを$dp[l, r)$と表す。この時、求めたい結果は$dp[0, n)$である。ただし、題意より、$dp[x, x+1) = 0$である(つまり、ある１つの数を選んでいるとき)。
この時、$dp[l, r) = min ((a_r - a_l) + dp[l+1, r), dp[l, r+1) + (a_r - a_l))$である。つまり、 ある区間のコストとは、それより1つ短いコストに1つ追加したものである。これを図に示すと以下のようになる。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/95e8dddc-8515-6d27-ad85-7c13e1be9a8f.png width=50%>

これをテーブルにすると以下のようになる。(線の合流のminをとり、合流地点の$(a_r - a_l)$を足す。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/540a82e1-1c7c-cf3e-c26a-1e47357175b0.png width=50%>

# 実装上の注意
Pythonは配列へのアクセスが遅い。このため、単純にに書くと(以下実装例のoldFunction)TLEするかぎりぎりになる。これは、Pythonの配列へのアクセスの遅さが関係しているようである。(ある程度大きい配列に対するアクセスのキャッシュの幅が狭いように感じる)
このため、実装例では2本のdpを持ち、下から計算している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/d4e56d28-12cf-aab5-1923-66d6c6d55d79.png)

このように

# 実装(Python3)

```Python3
import sys
input = sys.stdin.readline
def do():
    n = int(input())
    dat = sorted(list(map(int, input().split())))
    dp = [0] * (n+1)
    for step in range(0, n):
        newdp = [0] * (n + 1)
        for i in range(n-step+1, n+1):
            l, r = n-step-1 , i
            newdp[i] = min(dp[i], newdp[i-1]) + (dat[r-1] - dat[l])
        dp = newdp
    print(dp[n])
do()

def oldFunction():
    n = int(input())
    dat = sorted(list(map(int, input().split())))
    dp = [0] * ( (n+1) * (n+1) )
    for width in range(2, n+1):
        for l in range(0, n - width+1):
            r = l + width
            dp[l*n + r] = (dat[r-1] - dat[l]) + min(dp[l*n + r-1], dp[l*n+n + r])
    print(dp[n])
```
https://codeforces.com/contest/1509/submission/113335223

# 実装(C++)
```C++
using namespace std;
int main() {
    //FASTIOpre();
    ll n; cin >> n;
    ll x; vector<ll> dat(n); REP(i, n){cin >> x; dat.at(i) = x;}
    vector<vector<ll>> table(n+1, vector<ll>(n+1, 1e18));
    sort(ALL(dat));
    REP(i, n) table.at(i).at(i+1) = 0L;
    ll r;
    FOR(width, 2, n+1){
        REP(l, n- width+1){
            r = l + width;
            table.at(l).at(r) = min(table.at(l).at(r), table.at(l).at(r-1) + (dat.at(r-1) - dat.at(l)));
            table.at(l).at(r) = min(table.at(l).at(r), (dat.at(r-1) - dat.at(l)) + table.at(l+1).at(r));
        }
    }
    cout << table.at(0).at(n) << "\n";
}
```
https://codeforces.com/contest/1509/submission/113328835
TypeScriptの自分的まとめ



## 型について
- [AmplifyのAPIリクエストをTypeScriptでちゃんと型をつける](https://zenn.dev/ynakamura/articles/210460b470f7b973e5cc)
- [TypeScript の型定義ファイルと仲良くなろう](https://developer.hatenastaff.com/entry/2016/06/27/140931)
- [「型指定の方法」と「基本型の種類」](https://www.wakuwakubank.com/posts/499-typescript-type/)

## Utility Types 
- [Using built-in utility types in TypeScript](https://blog.logrocket.com/using-built-in-utility-types-in-typescript/)
- [Utility Typesをまとめて理解する](https://qiita.com/k-penguin-sato/items/e2791d7a57e96f6144e5)
- [TypeScriptの便利機能の紹介(その1)](https://kossy-web-engineer.hatenablog.com/entry/2020/09/02/120845)
- [TypeScriptのunion型はorです　〜union型、構造的部分型、余剰プロパティチェックの話〜](https://qiita.com/uhyo/items/b1f806531895cb2e7d9a)
- [ユニオン型がけっこうイイね](https://m-hiyama.hatenablog.com/entry/20180117/1516157225)
- [判別可能なUnion型](https://zenn.dev/tsuboi/articles/d4124649a08def490236)

## オーバーロード
- [オーバーロードの様々な書き方](https://qiita.com/eyuta/items/73b9b3af5f9820f74ae7)
- [オーバーロードを使用する上での注意点](https://qiita.com/eyuta/items/cfe5880e396a2246f8c0)
- [引数がないメソッドをオーバーライドしてオーバーロードする方法](https://qiita.com/isoken26/items/9babb331af8163e9a7ec)
- [オーバーロードメソッドを定義する方法](https://qiita.com/suin/items/7d6837a0342b36891099)
- [型の異なるメソッドをオーバーライドする](https://qiita.com/ConquestArrow/items/960d0e3a25fca4897787)

## jsStudio
- [インターフェース](http://js.studio-kingdom.com/typescript/handbook/interfaces)
- [べき・べからず集](http://js.studio-kingdom.com/typescript/declaration_files/dos_and_donts)
- [高等な型](http://js.studio-kingdom.com/typescript/handbook/advanced_types)
- [ジェネリクス](http://js.studio-kingdom.com/typescript/handbook/generics)
- [関数](http://js.studio-kingdom.com/typescript/handbook/functions)

## TypeScript Deep Dive
- [呼び出しオブジェクト](https://typescript-jp.gitbook.io/deep-dive/type-system/callable)
- [Union型（Union Types）](https://book.yyts.org/features/union-types)
- [ジェネリクス](https://typescript-jp.gitbook.io/deep-dive/type-system/generics)
- [Type Assertion（型アサーション）](https://typescript-jp.gitbook.io/deep-dive/type-system/type-assertion)
- [型ガード](https://typescript-jp.gitbook.io/deep-dive/type-system/typeguard)

## 仕事ですぐに使えるTypeScript
- [ジェネリクス](https://future-architect.github.io/typescript-guide/generics.html)
- [複合型](https://future-architect.github.io/typescript-guide/complex.html)
Laravelのログフォーマットのカスタムで改行が効かない時

# はじめに
Laravelでログのフォーマットを変更しようとした時に改行が思ったように効かない、そんな時の対処法

# Laravelでログフォーマットを変更する方法

フォーマットを変更したいログのチャンネルに`'tap' => [App\Logging\CustomizeFormatter::class],`を追加

```php
'channels' => [
        'stack' => [
            'driver' => 'stack',
            'tap' => [App\Logging\CustomizeFormatter::class],
            'channels' => ['error', 'app'],
            'ignore_exceptions' => false,
        ],
]
```

`app/Logging/CustomizeFormatter.php`を作成してログのフォーマットを記述していきます
laravel８のリファレンスに記載のコードは以下

```php
<?php

namespace App\Logging;

use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
    /**
     * 指定するロガーインスタンスをカスタマイズ
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new LineFormatter(
                '[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
            ));
        }
    }
}
```

このコードのままだと改行が効かずにログが一行で出力され続けます。見にくくて不便。

加えて改行のために末尾に `\n`を追加して`'[%datetime%] %channel%.%level_name%: %message% %context% %extra%'\n`としても改行は効きません。

#ログを改行させて表示したい
`LineFormatter`クラスを参照すると

```php
public function __construct(?string $format = null, ?string $dateFormat = null, bool $allowInlineLineBreaks = false, bool $ignoreEmptyContextAndExtra = false)
    {
        $this->format = $format === null ? static::SIMPLE_FORMAT : $format;
        $this->allowInlineLineBreaks = $allowInlineLineBreaks;
        $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
        parent::__construct($dateFormat);
    }
```

第三引数が`bool $allowInlineLineBreaks = false`で改行の可否を定めるものでありデフォルト値がfalseになっていることがわかります。
思うように改行が効かなかったのはこいつのせい。

ついでに第二引数を見ると`?string $dateFormat = null`となっていて日時のフォーマットを引数で渡すことができます。便利。

これらを踏まえてコードを書き換えると

```php
<?php


namespace App\Logging;

use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
    /**
     * 指定するロガーインスタンスをカスタマイズ
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new LineFormatter(
                "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", 'Y/m/d H:i:s', true
            ));
        }
    }
}
```


出力されるログは以下のようになります。
改行が効いていること。日時フォーマットが指定したものになっていることが確認できました。

```
[2021/04/17 13:51:19] local.ERROR: this is error log [] []
[2021/04/17 13:51:23] local.INFO: this is info log [] []
```
fopen, fgetcsv

# fopen()関数
概要
ファイルまたはURLを開く
返り値
成功時はファイルポインタリソース、失敗時はfalse

# fgetcsv()関数
概要
ファイルポインタから行を取得し、CSVフィールドを処理する
返り値
読み込んだフィールドを含む配列。取得できない場合はfalse
JuliaプログラムのVS Code上での開発

Juliaの標準開発環境はJunoだったようなのだけど、個人的にはずっとJupyter Notebookを使っていた。しかし去年のJuliaConの発表ビデオを見ていたらどうもVS Codeが押しになっているようなので移行。

https://www.youtube.com/watch?v=rQ7D1lXt3GM&list=PLP8iPy9hna6Tl2UHTrm4jnIYrLkIcAROR&index=3

## 設定
普通にVS Codeをインストールする。拡張インストールのパネルで、Juliaとタイプするとかなりたくさんの拡張が出てくるが、`julialang.language-julia`がオフィシャルなやつなので、これをインストールする。

後述するinlineでの結果表示はデフォルトではオフなのでオンにする。これには、左下の歯車アイコンからSettingsページをオープンし、テキストフィールドから「julia inline」などと打ち込んで検索する。

下のような設定がでるので、デフォルトが`REPL`となっているプルダウンメニューから `both`を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412142/2001c19e-9e4e-8823-f33a-19083c716e46.png)


## 使い方

エディタで編集しているコードの一部を、REPLで実行して、結果を編集コードの一部に挿入してくれる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412142/f8944311-9a10-5217-4dfc-5b23770201b3.png)

こうなっているところで、`end`のところでで [shift]-[enter] すると
結果が直接その場に挿入される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412142/1261ae67-619e-f95e-a1aa-002deb304d86.png)

`##`で区切られたブロックを「セル」として考え、セルの内部で[shift]-[enter]すると、セル全体が評価される。Jupyterノートブックと同じような感覚で開発をすすめる事ができる。

結果として書き込まれたテキストは、もちろん実際にはファイル中に書かれるわけではなく、セーブしたファイルには存在しない。

## デバッグ
コードの左側をクリックするとブレークポイントが挿入できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412142/aa83df22-8a08-78c9-f176-85ac47b92ddf.png)

右上の右三角アイコンから`Debug File In New Process`を指定して実行すると、ブレークポイントで止まる。これで変数名などを左のペインで見ることができるようになる。

## 所感
これは相当便利っぽい。Jupyterだと書いたコードからソースを抽出するのに一手間かかったが、これはその手間がない。また複数ファイルにまたがる実装がかんたんにできそう。あれ?でもモジュール宣言とかは当然複数のセルにまたがりそうだけど、どういう扱いになるんだろう。。。
WordPress  テーマの画像と、CSSファイルのパスを修正する方法

# はじめに
・WordPress初心者の方
・WordPressのテーマで、画像やCSSが反映さない方


## テーマに、画像やCSSが反映されない理由
・テーマファイルは、WordPressディレクトリの**`「wp-content/themes/~」`**に置くため、画像やCSSのファイルパスが切れて反映さません。なお、相対パスでも反映されないので注意が必要です。

**※画像とCSSファイルのパスと、WordPressで認識されるパスの詳細**

|画像、CSSのパス|WordPressで認識されるパス|
|:---:|:---:|
|wp-content/themes/自作テーマ/images/画像.jpg|wordpress/images/画像.jpg|
|wp-content/themes/自作テーマ/css/style.css|wordpress/style.css|



## テーマの画像と、CSSファイルのパスを修正
WordPressに認識されるパスを記述するには、WordPressの独自の関数である**`get_template_directory_uri()`**を使用します。

**`get_template_directory_uri()`**は、使用しているテーマのディレクトリのURLを返します。パラメータはなしになります。有効化しているテンプレートのみに有効で、文末には**`/（スラッシュ）`**が付かないので注意が必要です。

## WordPresの「style.css」について
WordPressのテーマを使用する際は、必ず**`style.css`**を作成してください。また、style.ccsを記述する際にはテーマの名前を必ず記述します。

※以下を参考にしてください。

```css:style.css
/*
Theme Name : ここにテーマの名前
*/

/*
ここに、CSSを記述
*/
```

では、実際に簡単なテーマのサンプルコードを書いていきます。

######サンプルコード
```tex:ディレクトリ構成
※画像のファイルパス
wp-content/themes/qiita_wp01/images/wordpress.jpg

※CSSのファイルパス
wp-content/themes/qiita_wp01/style.css
```

```php:index.php
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>WordPressパスの修正</title>
	<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style.css">
</head>
<body>
	<h1>WordPress</h1>
	<img src="<?php echo get_template_directory_uri(); ?>/images/wordpress.jpg">
</body>
</html>
```

```css:style.css
/*
Theme Name : WordPress
*/

h1 {
	color: blue;
	text-align: center;
}

img {
	width: 100%;
}
```




##まとめ

・WodPressで画像やCSSファイルのパスを修正する場合は、**`get_template_directory_uri()`**を使用。

・テーマを作成する際には、必ず**`style.css`**を作成する。

・**`style.css`**には、テーマの名前を必ず記述する。
E資格 2021#1の得点率

2021年3月12日に、E資格2021#1の科目ごとの結果がJDLAから公開されました。
その結果はこちらです。

|科目|平均得点率(%)|
|----|----|
|応用数学|69.65|
|機械学習|72.14|
|深層学習|67.80|
|開発環境|78.39|

そうであれば、全科目の正答数を合計した平均点は

```math
\frac{69.65\% + 72.14\% + 67.80\% + 78.39\%}{4}=72.00\%
```

なのでしょうか。
おそらく違います。

合格発表の日、合格者はTwitterに各自の科目ごとの平均得点率を書き込んでいます。
その書き込みを見ると、科目ごとに平均得点率にある傾向が見られます。

|科目|平均得点率の一部(%)|刻み幅(%)|
|----|----|----|
|応用数学|75, 83, 92, 100|8,9|
|機械学習|75, 83, 92, 100|8,9|
|深層学習|88, 90, 91, 92|約1|
|開発環境|75, 83, 92, 100|8,9|

応用数学、機械学習、開発環境は8,9%固定の刻みになっています。
この8,9%という値から、それぞれの問題数は12問であることが
推定されます。

|正答数|得点率(%)|
|----|----|
|9|75 (=9/12)|
|10|83 (=10/12)|
|11|92 (=11/12)|
|12|100 (=12/12)|

つまり、応用数学、機械学習、開発環境の問題数の合計は
12+12+12=36問であることが推定されます。

その一方で、E資格の総問題数は 102 問程度であると言われています。
そうであると仮定すると、深層学習の問題数は102-36=66問になります。
つまり、科目ごとの問題数は以下のようになります。

|科目|問題数|
|----|----|
|応用数学|12|
|機械学習|12|
|深層学習|66|
|開発環境|12|

4科目の配分が同じであると仮定した場合と、
4科目の配分が上の表（深層学習の問題数が66問）であると仮定した場合とで
それぞれの総得点率を計算してみましょう。

ここで、JDLAから通知された自分の得点が以下の得点率だったと仮定します。

|科目|得点率(%)|
|----|----|
|応用数学|100|
|機械学習|100|
|深層学習|58|
|開発環境|100|

4科目の配分が同じであると仮定すると、総得点率はこちらです。

```math
\frac{100\%+100\%+58\%+100\%}{4}=89.50\%
```

一方で、4科目の配分が異なる（深層学習の問題数が66問）場合を計算してみます。
まず、科目ごとの正答数を計算します。

|科目|得点率(%)|問題数|正答数|
|----|----|----|----|
|応用数学|100|12|12 (=12*100%)|
|機械学習|100|12|12 (=12*100%)|
|深層学習|58|66|約38 (=66*58%)|
|開発環境|100|12|12 (=12*100%)|

正答数を元に、総得点率を計算します。

```math
\frac{12+12+38+12}{12+12+66+12}*100=72.54\%
```

同じ配分の場合とは全く異なる総得点率になりました。
ご自身の総得点率が気になる人は、一度計算してみてはいかがでしょうか。

なお、上記の計算において、問題ごとに重みがあることは仮定していません。
【初心者でもわかる】CSSで「✕」の作り方

# どうも7noteです。CSSオンリーで「✕」を作ります

CSSを使って✕を作ります。
コピペで使えますよ。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/2e778823-a5cc-54c0-cecd-b8f3fa481fa3.png)

線の端を丸くすることも可能

![sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/f10d23e4-f9d4-cdee-a4f6-b47978e85e81.png)


## cssで✕の作り方

```css
.batten {
  width: 20px;        /* 線の長さ */
  position: relative; /* 基準位置に指定 */
}

.batten::before,
.batten::after {
  content: "";      /* 疑似要素に必須 */
  width: 100%;      /* 幅いっぱいを指定 */
  height: 2px;      /* 適度な太さを指定 */
  display: inline-block; /* 高さを持たせるためにinline-blockを指定 */
  background: #aaa; /* 線の色を指定 */
  border-radius: 2px;    /* 線の端を丸くしたいなら指定する */
  position: absolute;    /* 相対位置に指定 */
  top: 0;           /* 表示位置を上から0pxに指定 */
  left: 0;          /* 表示位置を左から0pxに指定 */
}

.batten::before {
  transform: rotate(45deg); /* 時計回りに45度回転させる */
}
.batten::after {
  transform: rotate(-45deg); /* 反時計回りに45度回転させる */
}

```

## ハンバーガーメニュー（3本線メニュー）から✕に変わるやつ

こちらは過去の記事で紹介しているので以下からご覧ください。

https://qiita.com/7note/items/cc76ae85409fbf1122be

## まとめ

テキストで✕にしてもいいのですが、線1本ずつに装飾したり、アニメーションをさせるならcssで✕を作ったほうが勝手がいいですね。
あとはborder-radiusで線の端を丸くできるので、デザイン的にも◎。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
Reactでメール送信機能を実装する

# はじめに
Reactで、サーバレスでメール送信機能を追加する方法を紹介します。


# 環境/前提
![<LABEL>-<MESSAGE>](https://img.shields.io/badge/node-14.15.0-<COLOR>) ![<LABEL>-<MESSAGE>](https://img.shields.io/badge/npm-6.14.8-<COLOR>) 
上記ライブラリがインストールされていること。

# 手順

今回は「EmailJS」というサービスを使って実装していきます。


## EmailJSにサービス登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/0edcb96a-8239-925b-0eb5-1dfd5a0f0dcf.png)

アカウントを作成すると↓みたいなダッシュボードが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/122a2163-bef0-b564-ca51-5fb92f7f18d1.png)

「Add New Service」からサービスを作成できます。
作成した「Service ID」を使って、ReactからEmailJSのサービスを利用できます。

## EmailJSにテンプレート登録
次にメールの雛形になるテンプレートを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/a4152b88-620b-d449-77f3-3482bbc69dbc.png)

「Create New Template」からサービスを作成できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/c0a2a845-bd33-ab5e-02e5-8104a4815b88.png)

ここで中括弧で宣言してある部分に、Reactからのパラメータを埋め込むことができます。
作成した「Template ID」を使って、ReactからEmailJSのサービスを利用できます。

ここまででEmailJS側の設定は完了です。

## ライブラリインストール
EmailJS用のnpmパッケージをインストールします。

```
npm i emailjs-com
```

https://www.npmjs.com/package/emailjs-com


## ReactからEmailJSを呼び出し

```index.ts
  import { init,emailjs } from 'emailjs-com';

  function onclickSendMail(){
      // emailjsのUser_IDを使って初期化
      init(process.env.GATSBY_USER_ID);

      // 環境変数からService_IDとTemplate_IDを取得する。
      const emailjsServiceId = process.env.GATSBY_EMAILJS_SERVICE_ID;
      const emailjsTemplateId = process.env.GATSBY_EMAILJS_TEMPLATE_ID;
  
      // emailjsのテンプレートに渡すパラメータを宣言
      const templateParams = {
          from_name: emailName,
          message: emailText
      };

      // ServiceId,Template_ID,テンプレートに渡すパラメータを引数にemailjsを呼び出し
      emailjs.send(emailjsServiceId,emailjsTemplateId, templateParams).
      then(()=>{
        // do something
      });
  }
```

以上の手順でReactからサーバレスでメール送信をすることができます。
matplotlibで描画したテキストのバウンディングボックスを取得する

# TL;DR
matplotlibで`ax.text()`を用いて描画したテキストのバウンディングボックス(bounding box, bbox)を取得するには次のようにします。
調査した環境はmacOS Big Sur 11.2.3, Python 3.9.2, matplotlib 3.3.4です。

```Python
import matplotlib.pyplot as plt

fig, ax = plt.subplots(1,1)

# 図の範囲を指定する（これがないと正しくbboxを取得できない）
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

# 先に描画を行う（これがないとエラーになる）
fig.canvas.draw()

# テキストの描画
text = ax.text(0.2, 0.2, "abcdefg0123あいう日本語", color='black', fontname="GenEi Gothic P", fontsize=20)

# グラフの座標でのbboxの取得
bbox = text.get_window_extent().transformed(ax.transData.inverted())

# bboxの描画
ax.plot([bbox.x0, bbox.x0, bbox.x1, bbox.x1, bbox.x0], [bbox.y0, bbox.y1, bbox.y1, bbox.y0, bbox.y0])

plt.show() 
```

![bbox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/829116/82d2e240-1138-ce20-3ee2-b1116eac2bb6.png)

# 注意点

## 先に`fig.canvas.draw()`を呼ぶ

`fig.canvas.draw()`を呼ばないと次のようなエラーが出ます。

```
RuntimeError                              Traceback (most recent call last)
<ipython-input-42-009947e9c4d3> in <module>
     12 
     13 # グラフ内の座標でのbboxの取得
---> 14 bbox = text.get_window_extent().transformed(ax.transData.inverted())
     15 
     16 # bboxの描画

~/miniconda3/envs/cartopy-env/lib/python3.9/site-packages/matplotlib/text.py in get_window_extent(self, renderer, dpi)
    897             self._renderer = self.figure._cachedRenderer
    898         if self._renderer is None:
--> 899             raise RuntimeError('Cannot get window extent w/o renderer')
    900 
    901         with cbook._setattr_cm(self.figure, dpi=dpi):

RuntimeError: Cannot get window extent w/o renderer
```

## 図の範囲を設定する

```python
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
```
を書かず、図の範囲を設定しない場合、bboxが正しく取得できません。
![bbox2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/829116/e7b51ecd-1206-be20-d7c9-9d3c7751e349.png)

## `.inverse_transformed()`は非推奨
古い情報だと

```Python
bbox = text.get_window_extent().transformed(ax.transData.inverted())
```

の部分を

```Python
bbox = text.get_window_extent().inverse_transformed(ax.transData)
```

と書いていることがありますが、これは非推奨(deprecated)です。

```
<ipython-input-45-c5bc8ab82cc2>:14: MatplotlibDeprecationWarning: 
The inverse_transformed function was deprecated in Matplotlib 3.3 and will be removed two minor releases later. Use transformed(transform.inverted()) instead.
  bbox = text.get_window_extent().inverse_transformed(ax.transData)
```

# 参考にしたページ
https://stackoverflow.com/questions/24581194/matplotlib-text-bounding-box-dimensions
Excelでの行・列・セルの挿入/削除のショートカットキー

## 挿入

行or列orセルを選択して、
`Ctrl` + `+`　(ただし`+` = `Shift` + `;`) 
(Webブラウザの`拡大`のショートカットキーと同じ)

## 削除

行or列orセルを選択して、
`Ctrl` + `-`
(Webブラウザの`縮小`のショートカットキーと同じ)

## ちなみに
行・列全体を選択するショートカットもあるが...これは覚えられなそう。
### 行全体の選択
選択したい行上のセルで、
`Shift` + `Space`
※日本語入力モードだと普通にセルにスペースが入力されてしまうので、英語入力に切り替えてから。

### 列全体の選択
選択したい列上のセルで、
`Ctrl` + `Space`
[oci] CLIでのコマンドのタブ補完が効くようになりました

ちょっとした仕様拡張ですが、OCI CLI (Oracle Cloud Infrastructure Command Line Interface)での第2引数以降がPowerShell版で自動補完されるようになりました。

コマンドを途中まで打ってタブを打つと、残りが補完されて表示されるアレです。
これまでは、CLI はコマンドは引き数を熟知していないと、なかなか使えませんでしたが、これで少しハードルが下がったと思います。

## CLIの動き
cliの文法は
`oci <service> <type> <action> <options>`
の4つの引数で成立していますが、自動補完では、それぞれ全てうろ覚えで入力できます。
例えば oci iam user list  と打ちたい場合は、
oci ia<タブ> us<タブ> li<タブ> と打つだけで、あとは補完されます。

## 自動補完のしくみ
OciTabExpansion.ps1 というコードが新規に追加されています。
それが 'Microsoft.PowerShell_profile.ps1' というpowershell起動時に自動実行される起動スクリプトの最終行に追記されていて、呼び出される仕組みになっています。
oci cliがインストールされたPowershell上で、$profile という環境変数が示すファイルを編集してみると、最終行に
. "C:\Users\<ユーザーID>\lib\oracle-cli\Lib\site-packages\oci_cli\bin\OciTabExpansion.ps1"
のような形式でタブ拡張機能が追加されていることが分かります。
このOciTabExpansion.ps1の中を覗いてみると、どのようにしてタブ補完しているのかが分かります。
ここで、一度なにかociコマンドを起動してみた後に
```
PS > Write-host $ociTopLevelCommands
```
と打つと、OCIが提供するサービス一覧が出力されます。今は55種類のサービスが提供されていることが分かります。
```
analytics
announce
api-gateway
application-migration
audit
<以下略>
```

さらに
```
PS > Write-Host $ociSubcommands 
```
と打ってみると、今度はサブコマンド一覧が取得できます。

Name                           Value
----                           -----
db autonomous-database-backup  create get list
email sender                   change-compartment create delete get list update
data-catalog entity            create delete get list update
data-catalog attribute-tag     create delete get list
ocvs work-request-error        list
network virtual-circuit-pub... bulk-add bulk-delete list
ce                             cluster cluster-options node-pool node-pool-options work-request work-request-error...
db node                        get list reset soft-reset start stop
ocvs work-request              get list
db db-home                     create delete get list
<以下略>



NameとValueの形式で、格納されています。NameのカラムでTopLevelCommandとSubCommandが関連付けられていて、Valueカラムには動詞が格納されているようです。
これで、タブ補完の挙動のしくみが理解できます。

oci db autonomous-database-backup create と打つには、
oci db autoタブ crタブ　で足りることが分かります。

自分がよく使いそうなociの第一引数だけ覚えておけば、なんとかなりそうですね。

# 補足情報
## コマンドライン・インタフェース(CLI)

https://docs.oracle.com/ja-jp/iaas/Content/API/Concepts/cliconcepts.htm

## oci-cliのgithub

https://github.com/oracle/oci-cli

## CLIのpowershell install バッチ
```
powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.ps1'))"
```

## 今回確認したcliのversion
`oci -v` での確認結果: 2.21.1
hotwire-railsのデモを参考にしたらsubmit後のリセット処理に失敗したので変更点をメモ

# はじめに

この記事はhotwireの使い方の説明ではありません。
hotwireの概要にについては以下などを参照していただければと思います。

https://hotwire.dev/

https://techracho.bpsinc.jp/hachi8833/2020_12_24/102368

# 本題

[hotwire-railsのデモチャットアプリ](https://github.com/hotwired/hotwire-rails-demo-chat) を参考に同じようなアプリを作ってみた際、submit時のリセット処理がうまく動かなかったので動くようにした変更点をメモ。
以下の内容以外は変更することなく動きました。(2021/04現在)

### 環境

- rails (6.1.3.1)
- webpacker (5.2.1)
- hotwire-rails (0.1.3)

### デモとの違い

`hotwire-rails` をインストールした際にjavascriptの展開されるディレクトリが変更されていました。
予想ですがwebpackerの構成に準拠したのかと思われます。

```
# デモ
app/assets/javascript/
# ローカル
app/javascript/
```

### 変更点

変更点は2つあります。

1. reset_form_controller.jsの呼び方を修正
1. reset_form_controller.js、`reset`メソッド内の`this.element`を呼べるようにする

#### 1. reset_form_controller.jsの呼び方を修正

そもそもフォームのリセット処理が呼ばれないので呼び方を修正

```diff:app/views/messages/new.html.erb
  <%= form_with(model: [ @message.room, @message ],
-        data: { controller: "reset_form", action: "turbo:submit-end->reset_form#reset" }) do |form| %>
+        data: { controller: "reset-form", action: "turbo:submit-end->reset-form#reset" }) do |form| %>
```

=> stimulus的にはreset_form_controller.jsを参照する場合、ファイル名をケバブケースにした `reset-form` が正しいらしい。

参考: https://stackoverflow.com/questions/65461717/issue-with-resetting-form-after-submission-using-hotwire-stimulus-js-rails-6

#### 2. reset_form_controller.js、`reset`メソッド内の`this.element`を呼べるようにする

サブミット後にformのリセットをしようとしているがボタンが戻らないのでform要素をjsで参照できるように修正

```diff:app/javascript/controllers/reset_form_controller.js
+ import Rails from "@rails/ujs"
  import { Controller } from "stimulus"

  export default class extends Controller {
    reset() {
+     Rails.enableElement(this.element)
      this.element.reset()
    }
  }
```

=> こちらは暫定対応として捉えてもらったほうがいい？
=> どうやらrails/ujsの既存の問題らしい。

参考: https://discuss.hotwire.dev/t/reseting-disabled-buttons-for-a-submitted-form-using-stimulus/1962

# 最後に

#### hotwireの感想

hotwireまだまだ勉強中ですが フロントエンド == js で何でもやろうをなくしてくれそうで、しがないサーバーサイドエンジニアの私としてはとても嬉しかったりしています。
今後のhotwireの成長には期待しています。
真・強制ダークモード

右目が疼く...

# BookMarklet作る
素人は手を出しづらいからかこんなに便利なのにあまり使っている人がいない。
セキュリティ懸念なのか。単に知らないのか

## 強制ダークモード
[いまさらながらダークモード対応に入門した](https://qiita.com/blkclct/items/91caffa72f76c12d6531)より

```javascript
javascript:(function(){ document.body.style.filter="invert(100%) hue-rotate(180deg)"; })()
```
ただ、上記ページでも言われている通り、画像が反転する。実用的ではないですね。

## 真・強制ダークモード
```javascript
javascript:(function(){const COLOR="#c5cddb",BG_COLOR="#171923";let elm=document.querySelectorAll("body,div,span,h1,h2,h3,h4,h5,h6,p,pre,a");Object.keys(elm).forEach(function(i){elm[i].style.cssText=`transition:all 150ms;color:${COLOR};background-Color:${BG_COLOR}`;});})()
```
ぼちぼち使えます。右目にも優しい。

### Before
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110729/339cf8cc-4610-2212-8293-a89c1bbcf122.png)

### After
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110729/952aa9cc-791c-9b47-006d-32cf1f6b0035.png)
【Java】Optionalが処理できないならデフォルト値を返そう

# 概要
Optionalはnullである可能性を明示的に返してくれる便利なコンテナ・オブジェクトです。
if(obj == null)... といったことをしなくてよくなったのは素晴らしいことだと思っています。

# 考察内容
nullをOptional型で返してSyetem.out.printすると<span class="rmarker">「Optional.empty」</span>が表示されます。
null安全なのは良いけど、WebアプリケーションのView等に表示するわけにはいかないなぁと感じたのがきっかけです。

対応方法として、Optionalを返すのではなく、nullをデフォルト値等に変換してから返してしまえばいいのではないかというのが考えです。

# 実装例


<div class="ymarker">商品情報を持つItemオブジェクト（WebアプリケーションだとEntity想定）</div>
<ul>
<li>name、amountは必須項目なので値は必ず保持しており、<span class="dotline">descriptionはnullである可能性がある状況を想定。</span></li>
<li>descriptionはフィールドとしてはnullを保持するが、アクセサで返す値はデフォルト値として空文字にする。</li>
<li>これにより、Entityとしてはnullを持つのでDB値と整合性が取れ、利用側のクラス（ここではMain）はデフォルト値（空文字）を扱うことができる。</li>
</ul>

``` Item.java
import java.util.Optional;
public class Item {
	private String name;		// DBで必須項目
	private Integer amount;		// DBで必須項目
	private String description;	// DBで任意項目（NULLの可能性がある）

	public Item(String name, Integer amount, String description) {
		this.name = name;
		this.amount = amount;
		this.description = defaltStrValue(description);
	}

	public String name() {
		return name;
	}

	public Integer amount() {
		return amount;
	}

	public String description() {
		return Optional.ofNullable(description).orElse("");
	}

	public String text() {
		return "["+ String.format(
					"name: %s, amount: %d, description: %s", name, amount, description)
				+ "]";
	}
}
``` 

``` Main.java
public class Main {
	public static void main(String...strings) {
		// nullをOptionalで返すと、「Optional.empty」が表示される。
		System.out.println(Optional.ofNullable(null));

		Item tv = new Item("BRAVIA", 79000, null);
		System.out.println(tv.text());
		System.out.println("description is " + tv.description());
	}
} 
``` 

<code>Optional.empty
[name: BRAVIA, amount: 79000, description: null]
description is </code>

Webアプリケーションなんかで、modelにそのままentityを渡して表示させると、「Optional.empty」が出てしまうので、<span class="rmarker">アクセサ（Getter）でデフォルト値にしてしまう</span>のが、適切かなぁと思った次第です。

# まとめ
<ul>
<li>Optionalはnull安全にできる便利なコンテナ・オブジェクトである。</li>
<li>利用側で処理せず、「Optional.empty」となってしまうようであれば、デフォルト値を返してしまうのがよさそう。</li>
<li>フィールドで保持する値（null）とアクセサで返す値（空文字）を分けることで、DB値と利用側で表示する値を区別して扱うことも可能になる。</li>
</ul>

# 参考
<a href="https://qiita.com/liguofeng29/items/0608be8670798e3028a5" rel="noopener" target="_blank">Qiita - Optionalの正しい使い方</a>
<a href="https://qiita.com/sunadiary/items/e905f8752f6c2da2d8f2" rel="noopener" target="_blank">Qiita - 【Java】Optionalの正しい使い方を学ぶ</a>
<a href="https://qiita.com/shindooo/items/815d651a72f568112910" rel="noopener" target="_blank">Qiita - Java 8 "Optional" ～ これからのnullとの付き合い方 ～</a>
<a href="https://qiita.com/Aruneko/items/b883dd705d4ada03de52" rel="noopener" target="_blank">Qiita - [Java8] Optionalで脱Exception!</a>
LeetCode日本語修行4日目- [220- Contains Duplicate III]

##Contains Duplicate III
参考https://leetcode.com/problems/contains-duplicate-iii/
###問題の内容
整数配列numsと2つの整数kとt、
配列中に
abs(nums[i] - nums[j]) <= t
abs(i - j) <= k
条件を満たすとなるiとjがあればtrueを返す。
###例
例1:
Input: nums = [1,2,3,1], k = 3, t = 0
Output: true

例2:
Input: nums = [1,0,1,1], k = 1, t = 2
Output: true

例3:
Input: nums = [1,5,9,1,5,9], k = 2, t = 3
Output: false
###ヒント:
0 <= nums.length <= 2 * 104
-231 <= nums[i] <= 231 - 1
0 <= k <= 104
0 <= t <= 231 - 1

---
一番分かりやすいのは、ループ処理ですね,注意するべきのは、Longです
今回のテストcaseの中に

```Kotlin
[2147483647,-1,2147483647]
1
2147483647
```
他の似ているcaseもうあります、
Intの範囲は 有効な値は  -2147483648から2147483647ので。処理する必要。
　

```Kotlin
class Solution {
    fun containsNearbyAlmostDuplicate(nums: IntArray, k: Int, t: Int): Boolean {
        if(k<0 || t < 0){
            return false
        }

        for(i in 0 until nums.size){
           for(j in Math.max(i-k,0) until Math.min(nums.size,i+k) ){
               if(Math.abs(nums[i].toLong() - nums[j].toLong()) <= t.toLong() ){
                   if(j == i){
                       continue
                   }
                   return true
               }
           } 
        }
        return false
    }
}
```
ですが.....この結果

```Kotlin
2972 ms  	40 MB
```
長過ぎ....
それを改善する為、バケットソートを使います。

バケットソート（英: bucket sort）は、ソートのアルゴリズムの一つ。バケツソート、ビンソート（英: bin sort）などともいう。バケツ数 k 個使った場合、オーダーはO(n + k)となり、ソートする要素数nとk を無関係にできる場合線形時間ソートとなるが、要素間の全順序関係を用いるソートとは異なり、キーの取りうる値がk種類である、という入力により強い制限を要求するソートである。
#####参考：https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%B1%E3%83%83%E3%83%88%E3%82%BD%E3%83%BC%E3%83%88
今回は、バケツの長さはt＋１、nums[i]とnums[j]は一つのバケツに格納されていますなら、trueを返す
隣のバケツの場合、二つの差は　<= t　なら、同じtrueを返す
``var bucketLength = t+1``
t+1の原因は
もし``t=3``即ち``Max-Min=3``この時、バケツ中は``1,2,3,4``バケツの長さは``４``です
``nums[i]<0``の場合0が含めないので、０からじゃない、１から、調整が必要です

```Kotlin
class Solution {
    fun containsNearbyAlmostDuplicate(nums: IntArray, k: Int, t: Int): Boolean {

        if(k < 0 || t < 0){
            return false
        }
        
        var map = HashMap<Long,Long>()
        var bucketLength = t+1

        for(i in 0 until nums.size){
            var id: Long = getBucketID(nums[i].toLong(),bucketLength.toLong())

            if(map.containsKey(id)){
                return true
            }
            if(map.containsKey(id-1) && Math.abs(nums[i] - map.get(id-1)!!) < bucketLength){
                return true
            }

            if(map.containsKey(id+1) && Math.abs(nums[i] - map.get(id+1)!!) < bucketLength){
                return true
            }

            map.put(id,nums[i].toLong())
            if(i >= k){
                map.remove(getBucketID(nums[i-k].toLong(),bucketLength.toLong()))
            }    
        }
        return false
    }

    fun getBucketID(value: Long,length: Long): Long{
        if(value >= 0){
            return value/length
        }else{
            return (value+1)/length - 1
        }
    }
}
```
Julia その7 いろいろ

なんか知らんが、下書きのまま残っていたようなので公開。

## range とイテレータ
pythonでいうrangeに相当するイテレータは`:`でつくる

``` Julia
1:4
# 1,2,3,4
```
初期値と終端値を指定する。両端はインクルーシブなので、これで1から10までの値が生成される。
ステップを指定するには真ん中に書く。

``` Julia
1:2:7
# 1,3,5,7
```

典型的なインデックスを使うfor文はこれを用いて書く。

``` Julia
for i in 1:10
    println(i)
end
```

### range 関数
`:`で生成されるRangeオブジェクトは関数で作ることもできる。
この関数は次のように定義されている。

``` Julia
range(start[, stop]; length, stop, step=1)
```
長さが指定できるので、例えば、1から10までを20等分して0.5刻みの系列をつくる、などということが書きやすい。

``` Julia
range(1, 10, length=20)
```

## ループするインデックスの作り方

配列などの1つ目の要素と2つ目の要素を交互に取り出したい、というようなケースはよくある。配列インデックスが0から始まる言語では、0と1を交互に作ればいいので、カウンタのmod 2をとればいい。

``` Python
  index = counter % 2
```
しかし、インデックスが1で始まるJuliaのような言語では、1と2を交互につくる必要がある。この場合には、

``` Julia
  index = 3 - index
```
とするらしい。うーん。。1,2,3をループさせるにはどうするんだろう。やっぱりmodをとって1足すのか。

[2021/4/18 追記] twitterで、まさにmodをとって1足す`mod1`という関数があることを教えていただいだ。ありがとうございます。


## Dict型
辞書は`Dict`型で表され、`Dict`関数で作る。直接のリテラルは用意されていない。これはちょっと意外だ。もっともタプルの列で比較的キレイに定義できるので不要なのだろう。

``` Julia
d = Dict([
 ("key1", 1),
 ("key2", 2),
])
```
下記のようにPairを使ったシンタックスでも記述できる。

``` Julia
d = Dict(
 "key1" => 1,
 "key2" => 2,
)
```
辞書は次のように、キーバリューのタプルのリストとしてループできる。

``` Julia
for (k,v) in d
    println((k, v))
end

("key2", 2)
("key1", 1)
```
# グローバル変数のリスト
現在のモジュールを知るには`@__MODULE__`マクロを用いる。`names`関数で指定したモジュールのグローバル変数を列挙できる。

``` Julia
julia> names(@__MODULE__)
9-element Array{Symbol,1}:
 :Base            
 :Core            
 :InteractiveUtils
 :Main            
 :ans
...             
```
## バージョンの取得
```
using InteractiveUtils
versioninfo()
```
でもいいし、

```
VERSION
```
でもよい。上の方が細かい情報が提供されている。
Flutterの自分的まとめ

## Flutterの使い方の基本
- [Flutterコマンド一覧まとめ](https://qiita.com/kurun_pan/items/f9251b1827ce9dca9e14)

## Dart/Flutterで非同期処理
- [DartのFutureを使って非同期処理を書く](https://sbfl.net/blog/2015/01/05/writing-asynchronous-operation-with-future-in-dart/)
- [FutureのNullとvoidとそれぞれの挙動の違いについてまとめる](https://qiita.com/arthur_foreign/items/1c92a0f43d7e927fa2df)
- [async libraryでFutureとStreamを使った非同期処理についてまとめてみた](https://qiita.com/arthur_foreign/items/4d85423e9307512237da)
- [flutter:Futer<T>abstract class ドキュメント](https://api.flutter.dev/flutter/dart-async/Future-class.html)

## Flutter/Amplify
- [Amplify Flutterを学ぶ](https://qiita.com/makotomi/items/7bb09ff225d0fcbce1b6)
- [Amplify Fluutterがリリースされました!](https://dev.classmethod.jp/articles/what-new-amplify-flutter/)
- [Amplify Docs:Flutter Getting Started](https://docs.amplify.aws/start/q/integration/flutter)
- [AWS AmplifyによるiOSアプリ開発入門](https://qiita.com/papi_tokei/items/ee4abf44703f8692f006)
- [Amplifyの自分的まとめ](https://qiita.com/Tamamushi/items/5d6b52dbb1b8e5090987)
Laravelでログレベルにしたがってログの出力先を変更する

#はじめに
Laravelでログレベルにしたがってログの出力先を変更したい時の設定について
例えばerror以上はerror.log分けておきたい。みたいな時に使えます

# 環境
- PHP 7.4.16
- Laravel 8.34.0

# やり方

config/loggerに以下を記述

```php
'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['error', 'app'],
            'ignore_exceptions' => false,
        ],

        'app' => [
            'driver' => 'single',
            'path' => storage_path('logs/app.log'),
            'ignore_exceptions' => false,
            'level' => 'debug',
            ],

        'error' => [
            'driver' => 'single',
            'path' => storage_path('logs/error.log'),
            'ignore_exceptions' => false,
            'level' => 'error',
        ],
]
```

デフォルトのチャンネルがstackになっているので.envファイル中の`LOG_CHANNEL`に関して以下の設定になっていることを確認

```
LOG_CHANNEL=stack
or
LOG_CHANNEL=
```

#結果
```
storage 
└── logs
    ├── app.log
    ├── error.log
    └── laravel.log
```

app.log

```
[2021-04-17 12:45:46] local.INFO: this is info log  
[2021-04-17 12:45:51] local.ERROR: this is error log
```

error.log

```
[2021-04-17 12:45:51] local.ERROR: this is error log  
```

app.log, error.logそれぞれに想定するログレベル以上のログが出力されることが確認できた
Vue.js+Firebase Authentication（メール／パスワード）で認証

#何故Firebase Authenticationで認証しようとしたのか
当初はBasic認証させたかった（Functionsの利用）が、
Firebaseの無料枠では出来なかったため、
Firebase Authenticationでメールアドレス＋パスワード認証をすることにした

#実装方法
###Firebaseの設定
####①プロジェクト作成
####②Authenticationの設定
・[Authentication]>[Sign-in method]>[メール/パスワード]を有効に変更
・[Authentication]>[Users]>[ユーザー追加]で使用するメール/パスワードを登録しておく
####③プロジェクトの設定
・[設定]>[全般]でウェブ API キーをコピー
・[設定]>[サービスアカウント]でAdmin SDK 構成スニペットをコピー
・新しい秘密鍵の生成を押下して、秘密鍵情報のjsonファイルを取得（serviceAccountKey.jsonにリネームしておく）

###コーディング（Vue.js）
main.js

```
import firebase from 'firebase'
var admin = require("firebase-admin");

//③で取得した秘密鍵情報のjsonファイルを指定
var serviceAccount = require("path/to/serviceAccountKey.json");

const config = {
  apiKey: 【③で取得したAPIキー】,
  credential: admin.credential.cert(serviceAccount)
};

firebase.initializeApp(config);
```

SignIn.vue(新規作成)

```
  <div class="signin">
        <div>
          <div class="message">
            {{ message }}
          </div>
          <div class="input-area">
            <b-container>
                <b-row>
                  <b-col>メールアドレス：</b-col>
                </b-row>
                <b-row>
                  <b-col><b-form-input type="email" v-model="mailaddress"/></b-col>
                </b-row>
                <br>
                <b-row>
                  <b-col>パスワード：</b-col>
                </b-row>
                <b-row>
                  <b-col><b-form-input type="password" v-model="password"/></b-col>
                </b-row>
            </b-container>
            <br>
            <b-button variant="primary" @click="signIn">サインイン</b-button>
          </div>
        </div>
  </div>

<script>
import firebase from 'firebase'

export default {
  name: 'SignIn',
  data() {
    return {
      mailaddress: '',
      password: '',
      message: '',
    };
  },
  methods: {
      signIn: function () {
        //firebaseSDKのサインイン関数を利用
        firebase.auth().signInWithEmailAndPassword(this.mailaddress, this.password)
        .then(()=>{
            // 成功時の処理
            console.log("OK");
            this.$router.push({ name: 【TOPページ】 });
          }
        )
        .catch(()=>{
            // エラー時の処理
            console.log("NG");
            this.message = "サインイン情報が間違っています。";
            this.password = "";
          }
        )
      }
    }
}
</script>
```

#追記
・basic認証代わりなので、今回は手動でメール／パスワードを用意したが、
認証ユーザー作成（firebase.auth().createWithEmailAndPassword）も可能
・認証状態の取得（firebase.auth().onAuthStateChanged）とrouter.beforeEachを組み合わせれば、認証されていな場合は、サインイン画面に戻る等も実装可能
Amplifyの自分的まとめ


## Amplify Authentication（Cognito）
− [Amplify Docs: Authentication](https://docs.amplify.aws/lib/auth/signin/q/platform/flutter)
- [Amplify AuthenticationでSMS認証](https://www.ragate.co.jp/blog/articles/713)
- [Amplify Auth（Cognito）AWS consoleで設定](https://makky12.hatenablog.com/entry/2019/09/21/190641)

## Amplify複数IDP認証の連携について
- [Cognitoで複数のIDP認証を単一ユーザー認証として扱うベストプラクティスを考えてみました](https://www.ragate.co.jp/blog/articles/3826)

## Amplify Multi Envrionment（ブランチ作成／活用）
- [Amplify Multi Environment でチーム開発を整備する](https://dev.classmethod.jp/articles/amplify-multienv-team-dev/)
- [AWS Amplifyで、amplify env を使って、開発環境の共有と分離をしてみた](https://thinkami.hatenablog.com/entry/2019/07/27/210948)

## Flutterのユーザー認証にCognitoを使う
- [Flutterアプリのユーザー認証システムにAmazon Cognitoを使う(OAuth 2, Google, LINEなど)](https://qiita.com/Chrg/items/f8a6338796aa5a84bbf6)
- [端末認証／デバイスの追跡と記憶](https://sites.google.com/site/technicalkoda/cognito/duan-mo-ren-zheng)
配列操作メソッド

# forEach
配列データに対してforEachを実行すると、配列データの値1つずつに対してコールバック関数に記述した処理を実行できる。
### 配列の中身を取得
```php
const items = ['りんご','バナナ','もも','ブドウ'];
items.forEach(value => {
  console.log(value);
});//りんごバナナももブドウ)
```
# map
- 関数内に実行したい処理を書いておくことで、配列の各要素に対して好きな操作ができる
- 「forEach」との違いは、「map」は実行後の結果を配列データとして<strong>返す</strong>こと
- 元となる配列から新しい配列を作成できる

```php
const array = [1,2,3,4,5,6,7];
const newArray = array.map(value => value * 3)
console.log(newArray);//[3,6,9,12,15,18,21]
```
# find

提供されたテスト関数を満たす配列内の <strong>最初の要素の値</strong>を返す
trueを返す要素が見つかるまで、要素に対して一度ずつ関数を実行する。

```php
const before = [25,40,230,280];
const after = before.find(param => {
  return ((param % 20) === 0);
});
console.log(after);//40
```
# filter
全ての要素に対して関数を一度ずつ実行し、戻り値(return)で true を返した要素からなる新しい配列を生成する。
mapとは異なり、trueを返した要素のみの配列を返し、生成された配列の値には実行時の要素の値が格納される。

```php
const before = [25,40,230,280];
const after = before.filter(param => {
  return ((param % 20) === 0);
});
console.log(after);//[40,280]
```
# some
trueを返す要素が見つかるまで、要素に対して一度ずつ関数を実行する。
trueを返す要素が見つかると、trueを返す。

```php
const list = [10, 20, 30, 40];
const retVal = list.some(param => {
 console.log(param);
 return (param >= 20);
});
>10
>20
console.log(retVal)//true
```
# evey
false を返す要素が見つかるまで、要素に対して一度ずつ関数を実行する。
falseを返す要素が見つかると、falseを返す。

```php
const list = [10, 20, 30, 40];
const retVal = list.every(param => {
 console.log(param);
 return (param >= 20);
});
>10
console.log(retVal);//false

```
【Workato】コミュニティライブラリ

##コミュニティライブラリとは？
コミュニティライブラリとは、Workatoのプラットフォーム内に組み込まれているリソースライブラリで、自分が作ったレシピやコネクターを公開することができる。

##コミュニティレシピ
まずはレシピを検索できる画面。
このようにアプリの一覧が表示されているので、この中からアプリを選択するとそのアプリを使ってるレシピの一覧が表示される。
![スクリーンショット 2021-04-17 21.06.57（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/947273/aa056862-2807-a01b-a7c5-8eeed0ec378e.png)

例えばSalesforceを選んでみると...
![スクリーンショット 2021-04-17 21.09.21（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/947273/96d4a294-730e-e61a-de04-5f5623f8bfdb.png)
Salesforceコネクターを使用しているレシピがたくさん出てくる。
現時点では`13399`個のレシピが公開されている...！
左下のアイコンでトリガーとアクションそれぞれで使用されているアプリが分かる。また右下には公開しているユーザ名も表示される。

もちろん、アプリを複数指定すればその両方のアプリを利用しているレシピを検索することも可能だ。
![スクリーンショット 2021-04-17 21.15.33（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/947273/f1c9efcf-1a75-e0f5-d3c6-fc3ad0e39c56.png)

##コミュニティコネクター
コミュニティには自分の作ったコネクターも公開することができる。
Workatoのコネクターには、Workato社が作成・メンテしているコネクターと、ユーザ自身が作成したカスタムコネクターの2種類が存在する。
どちらのコネクターもレシピ内で使用するときの使い心地や機能差は全くない。

Workato社が用意しているコネクターの中に連携したいアプリのコネクターがない場合、
**1. コミュニティに上がってるカスタムコネクターを使う**
**2. ユニバーサルコネクターを使う（HTTPコネクター）**
**3. カスタムコネクターを作成する**
といった選択肢がある。
基本的にはグローバルで展開されているSaaSはほとんどコネクターがもう用意されているが...
![スクリーンショット 2021-04-17 21.16.23（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/947273/6b8499a2-aac0-a7af-39d5-0962a931f61e.png)
日本のサービスも上がってるものがちらほら...
![スクリーンショット 2021-04-17 21.26.20（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/947273/c348a081-2d94-2120-8536-1fb27e0d3efc.png)
![スクリーンショット 2021-04-17 21.25.56（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/947273/054b181c-a752-c7e6-a0b6-791ecd42a0b0.png)
そして謎のポケモンコネクター...笑
![スクリーンショット 2021-04-17 21.28.00（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/947273/9c96038b-079b-9734-ba23-8501db86cd9d.png)

このコミュニティがあるおかげで毎回一からレシピやコネクターを作らなくても済む。
特にカスタムコネクターの作成に関しては、エンジニアからすれば大して難しくないがビジネスユーザーには少々ハードルが高い。
他の誰かが作ったコネクターを使わせてもらえるのは非常にありがたいですね〜
なので私もコネクターを作る機会があればコミュニティに公開するようにします！
テスト32

```vb

Sub Row_height()

'事前に指定の列に行の高さが調整される値を入力

Dim i As Long

With ThisWorkbook.Sheets("再帰テスト")

    For i = 1 To 2000
    '行の高さを再入力
    
        .Cells(i, 1).RowHeight = .Cells(i, 1).RowHeight
    
    Next i
    
    .Columns(10).ClearContents

End With

'別シートにコピーして指定の列の値を削除
With ThisWorkbook

    .Sheets("再帰テスト").Rows("1:2000").Copy
    .Sheets("Sheet10").Cells.PasteSpecial (xlPasteAll)
    .Sheets("Sheet10").Columns(10).ClearContents

End With

End Sub