OmniAICreator/Qiita-1.07M huggingface dataset:
【TypeScript】Utility TypesのPartialを深く理解する

# この記事は何？
この記事は、Utility Typesの一つである**Partial**について深く理解する記事です。
Utility Typesってそもそも何？という型（方）は以下の記事を御覧ください🙇🏻
👉 [TypeScriptのUtility Typesを理解して活用する](https://qiita.com/NOMURA_keibyou38/items/84caee0657f57650577d)

そもそも、TypeScriptって何？って型は以下を御覧ください
👉 [JavaScriptを知っている方がTypeScriptをなんとなく理解するための記事① ~はじめに~](https://qiita.com/NOMURA_keibyou38/items/06a3218de3ff480ce9de)

# Partial＜Type＞とは
TypeScript公式には以下のように書かれています。
> Constructs a type with all properties of Type set to optional. This utility will return a type that represents all subsets of a given type.
> Typeのすべてのプロパティがオプションに設定されたタイプを構築します。このユーティリティは、指定されたタイプのすべてのサブセットを表すタイプを返します。
> https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype

つまり、どういうことかというと、
`ある型`について、全てオプショナル（その型を使っても使わなくても良い）にしてしまうもの、ということです。

具体的に、コードで見ていきましょう。
まずは、`Partial`を**使わない場合です**

```typescript
interface digitalMonsters {
  name: string;
  nextGrade: string;
  level: number;
}

// プロパティ'level'がタイプ '{name：string; nextGrade：文字列;}にありません。タイプ'digitalMonsters'では必須です。
const agumon: digitalMonsters = {
  name: "agumon",
  nextGrade: "gureimon",
}
```

`level: number;`がないので当然アウト🙅です。
次は、`Partial`を**使った場合**です。

```typescript
interface digitalMonsters {
  name: string;
  nextGrade: string;
  level: number;
}

type looseDigitalMonsters = Partial<digitalMonsters>;

// levelがなくてもOK
const looseAgumon: looseDigitalMonsters = {
  name: "agumon",
  nextGrade: "gureimon",
}

// nameもlevelがなくてもOK
const looseAgumon2: looseDigitalMonsters = {
  nextGrade: "gureimon",
}

// nameもnextGradeがなくてもOK
const looseAgumon3: looseDigitalMonsters = {
  level: 3,
}
```

このように`Partial<Type>`を通すと、各プロパティを指定してもしなくても良い状態になります。
型定義としては少しゆるい状態になりますので、取り扱いには注意が必要そうです。

また、以下のように使うと理解が深まるかもしれません。

```typescript
interface digitalMonsters {
  name: string;
  nextGrade: string;
  level: number;
}

interface Ability {
  offensivePower: number,
  defensePower: number
}

type looseDigitalMonsters = digitalMonsters & Partial<Ability>;

// OK
const looseAgumon: looseDigitalMonsters = {
  name: "agumon",
  nextGrade: "greimon",
  level: 3,
  offensivePower: 100,
}

type strictDigitalMonsters = digitalMonsters & Ability;

// タイプ'{name： string; nextGrade： string; level： number; }'は、タイプ'Ability'から次のプロパティが欠落しています： offensivePower, defensePower
const strictAgumon: strictDigitalMonsters = {
  name: "agumon",
  nextGrade: "greimon",
  level: 3,
}
```


React&TypeScriptなどで使いたい場合は、以下のように書けば良さそうです。

```jsx
type Props = digitalMonsters & Partial<Ability>;

const digitalMonsterList: React.FC<Props> = (props) => {
 ...
}
```

# おわりに
今回は、Partialについて書いてみました。
是非、ご活用ください！

# 参考
- https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype
- https://www.mmj.ne.jp/mmjblog/typescript-object-update-method/
ASP.NET Core ver2.1でajax通信でサーバに通信できない原因はコード以外にもあった! 

【実行環境】
PC：Windows10
開発環境：Visual Studio2019
使用言語：HTML、Javascript、C#

ASP.NET Core ver2.1をHTMLフォーム画面を作り、ajaxでPost通信しようとしたがステータスコード400エラー(Bad request)や404エラー(Not Found)が続出した。

Post通信するときのソースコードのバグが無いか隈なく探したがこれといったバグは見当たらなかった。

そしてやっと見つけた！
原因はVisual Studio2019の設定にあった！

ソリューションプロジェクトを新規作成する時.Net Coreのバージョンを2.1に設定して作成するが、プロジェクトのプロパティの中の対象のフレームワークのバージョンが新規作成時のバージョンとずれていることが原因であった！
それによってPost通信が全く行われない状況にあった。

プロジェクトを作成したときの.Net Coreのバージョン設定が必ずしもプロジェクトのプロパティ内のバージョンに反映されているとは限らない。

なので、プロジェクトのプロパティの.Net Coreのバージョンも新規作成時と合致しているかを確認する必要がある！

変更手順はこの手順で進める。
<★変更手順★>
①ツールバー【プロジェクト】⇒【(ソリューションプロジェクト名)のプロパティ(P)】を選択する。
②【アプリケーション】タブを開き、【対象のフレームワーク(G)】欄のコンボボックスからを新規作成時に設定したバージョンを選択する(今回は「.Net Core 2.1」)。
③上書き保存する(Ctrl + Sキー)で変更完了！

文字だけではわかりにくいので変更前と変更後の写真も添付する。
【変更前】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/829bdfae-ba68-5486-53ea-69d4e2ff47da.png)



【変更後】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/b7b45b07-8d4b-6d09-8ff7-f89fb1de5446.png)





いい勉強になった！
PerlのArchive::Zipを使ったzip圧縮時に、ダメ文字(0x5C)が入る文字のファイル名をzip化しちゃうと、解凍時に文字化けしてしまう

Linux環境でcpanのArchive::Zipを使ってzipファイルを作成する際に、zipファイルの中に入れるファイル名をcp932にしたのだが、ファイルを解凍すると中のファイル名が見事に文字化けしていることがあった。
どうやらダメ文字(0x5c)が入るような”ソ”とか”能”とかがうまく表現できない。

## ダメ文字とは
Shift_JIS(SJIS, cp932) の文字コードで、2byte目が0x5c の \ になっているものの俗称(だめ文字、駄目文字)

https://sites.google.com/site/fudist/Home/grep/damemoji


## コード例
zip内のファイル名として、cp932にした文字列を設定する。

```perl
$file_name = Encode::encode("cp932" => "ソムリエ芸能界");

my $zip = Archive::Zip->new;
$zip->addString($content, $file_name);
```

## 文字化けの原因

Archive::Zipの下記の箇所で、\を/に置き換えていることが原因。

```perl:Member.pm
sub fileName {
    my $self    = shift;
    my $newName = shift;

    if (defined $newName) {
        $newName =~ y{\\/}{/}s;    # deal with dos/windoze problems
        $self->{'fileName'} = $newName;
    }
    return $self->{'fileName'};
}
```

何だ？「deal with dos/windoze problems」って。
「dos/windozeの問題に対処する」ってことか。

https://www.wdic.org/w/TECH/Windoze

## 自身の対応

おそらく、zip内ファイル名として、フォルダパスを指定した場合に不都合があった？（しかもwindows環境のみ）
と考えて、Windows環境でのみ、置換処理を実行するように変更してみたところ、自身のツールでは文字化けは解消された。

```perl:Member.pm
sub fileName {
    my $self    = shift;
    my $newName = shift;

    if (defined $newName) {
        if ($^O eq 'MSWin32') {
            $newName =~ y{\\/}{/}s;    # deal with dos/windoze problems
        }
        $self->{'fileName'} = $newName;
    }
    return $self->{'fileName'};
}
```

## 補足

最近のzipフォーマットでは、ファイル名がutf8かどうかのフラグを持っていて、フラグがONになっていたらWindows10の標準解凍機能でもutf8のファイル名が文字化けせずに解凍できるらしい。(EFSフラグ)

おそらくArchive::Zipは未対応。

### 参考
https://tmtms.hatenablog.com/entry/2017/04/05/zip

https://qiita.com/Teloo/items/9cfd3b39a2a5cebf61b8


## 考察

うーん、これはArchive::Zipの不具合でしょうか？
でも、いくらググっても、ダメ文字が化ける現象は自分以外には見つからなかった。
使い方が間違ってるんでしょうか？
【Ruby】Ruby・Railsのバージョンを知りたい時


## Rubyのバージョンを調べる:  `ruby -v`

```ruby
$ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin18]
```

## Railsのバージョンを調べる:  `rails -v`

```ruby
$ rails -v
Rails 5.1.7
```

## Rubyをrbenvで管理している場合のバージョンを調べる: `rbenv versions`
(*が付いているものが設定されているRubyのバージョン)

```ruby
$ rbenv versions
  system
  2.2.1
* 2.3.0 (set by /Users/admin/.ruby-version)
  2.3.5
  2.5.0
  2.5.1
```

## RubyGemsのバージョンを確認するコマンド: `gem -v`

```ruby
$ gem -v
3.1.4
```
Trying to get property 'id' of non-object ()　解決方法

Laravel入門(p.208)で、クエリビルダを使って指定したIDのレコードを取得し、ブラウザ表示させようとした時に次のエラーが発生しました。

```
Trying to get property 'id' of non-object (View: /work/resources/views/hello/show.blade.php)
```

![スクリーンショット 2021-03-07 22.42.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/8ad8f33f-9ccb-a613-81e0-ea7f155196f4.png)

このエラーは、`存在しないプロパティを取得しようとする`と発生します。
結論から言ってしまうと、このエラーの原因は、/hello/showにアクセスする際に、
ただ`?id=1`のようにパラメータを用意していなかったからでした（笑)
ただの参考書の見逃しでした。

しかし、エラーについて調べていると、どうやらリレーションの先が無かった場合にnullを返してくれる関数があるらしく、
その関数を使うことで今回のエラーを解決できるようなので試しに使ってみました。

##optional( )
その関数がこちらです！
この関数はヘルパー関数といい、渡されたオブジェクトに対し、is_objectが真の場合はオブジェクトとプロパティを渡し、nullの場合は例外を回避してくれます。

ということで早速下記のようにテーブル表示の記述を修正して/hello/showにアクセスしてみます。

「show.blade.php」

```
@section('content')
    <table>
        <tr><th>id: </th><td>{{$item->id}}</td></tr>
        <tr><th>name: </th><td>{{$item->name}}</td></tr>
        <tr><th>mail: </th><td>{{$item->mail}}</td></tr>
        <tr><th>age: </th><td>{{$item->age}}</td></tr>
    </table>
    </item>
@endsection

↓ //optional関数追加

@section('content')
    <table>
        <tr><th>id: </th><td>{{optional($item)->id}}</td></tr>
        <tr><th>name: </th><td>{{optional($item)->name}}</td></tr>
        <tr><th>mail: </th><td>{{optional($item)->mail}}</td></tr>
        <tr><th>age: </th><td>{{optional($item)->age}}</td></tr>
    </table>
    </item>
@endsection
```

これで、再度パラメータを用意せずに/hello/showにアクセスしてみます。

![スクリーンショット 2021-03-07 23.01.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/44371b77-befc-9415-41ae-0e3b9e2104d2.png)

すると、ご覧の通りレコードが無くてもnullの状態でテーブル表示されました。

では、次はちゃんとパラメータを用意して`/hello/show?id=2`でアクセスしてみます。
![スクリーンショット 2021-03-07 23.04.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601015/69a1b444-0cdb-1677-7762-a76082d97731.png)

すると、idが2のレコードがちゃんと表示されました！

参考サイトはこちら
https://qol-kk.com/wp2/blog/2018/12/19/post-992/
https://neco.sakuratan.com/laravel-20190909/
[ruby, rails] nil　empty　blank　present


nil?とempty?はrubyのメソッドで、blank?とpresent?はrailsで拡張されたメソッド（つまりrubyでは使えない）ってことを覚えておく。

-

##nil?
nilは存在しないという意味。
対して　""は「何も無い」が存在している。空白の存在。

book.nil?
もしbook自体が存在しないなら、上記はtrueを返す。

##empty?
empty?は「入れ物」は存在するのが前提。
book.empty?
description.empty?
は、bookやdescriptionそのものは存在していることが前提で、その配列の中身が空か、文字列の中身が空の場合にtrueを返す。
配列や文字列そのもの（入れ物）が無い場合にはNoMethodErrorが発生する。空ですか？と聞いてるわけだから、少なくとも「入れ物」が存在しないとダメってことか。

##blank?
blank?は、nil?とempty?の合わせ技
では、中身が空か、または入れものそのものが存在しないときの判定はどうなるか。blank?が使える。empty?とnil?を足したようなものだ。presentnilと空のオブジェクトを判定できる。

unless description.blank?
end
と書けば、descriptionの文字列が空か、そもそもdescription自体が存在しない場合に処理をスキップできる。

##present?
present?は、!blank?と同じ意味
ちなみに上の処理は present?を使って

if description.present?
end
と書ける。

-

nil? すべてのオブジェクトに定義されている。nilのときのみtrueを返す。
empty? 文字列の長さが0のとき、または配列が空のときにTrueを返す。もちろん数値には定義されていない。
blank? railsの拡張。nil, "", " ", [], {} のいずれかでTrueを返す。
PHPの型と種類についてざっくりまとめ

#PHPの３つのデータ種類
- スカラー型：１つの変数に１つの値を扱うことができる。
- 複合型：１つの変数に複数の変数を扱うことができる。
- 特殊型：スカラー型にも複合型にも属さない。

この３種類の中に８つのデータ型がある。


#PHPの８つのデータ型
データ型：データの性質のこと。
PHPはデータの型付けが弱い言語で、データ型を自動で判別してくれる。
変数の宣言時に型指定をしなくて良い。


| データ型（日本語） | データ型（日本語） | 種類 | 概要 |
|:-:|:-:|:-:|:-:|
| 文字列型  | string  |  スカラー | クォートで囲まれた文字列  |
| 整数型  | integer  | スカラー  | -1,0,50などの整数。<br>１０進数以外も表現可能。  |
| 浮動小数点数型  | float(double)  | スカラー  | 1.332、-0.15などの小数点数。 |
| 論理型  | boolean  | スカラー  | true または false  |
| 配列型  | array  | 複合  | 複数のデータの集合  |
| オブジェクト型 | object  | 複合  |  データと処理系の集合 |
| リソース型  | resource  |  特殊 |  外部リソース参照 |
| ヌル型  | null  | 特殊  |  null(値を持たないこと) |


参考：https://wepicks.net/phpref-datatype/

以下、リテラルという言葉を使っていく。
リテラルとは、「値そのもの」のこと。


##文字列型

文字、または文字列連結された値。

文字列リテラルは、
シングルクォート（''）
ダブルクォート（""）
ヒアドキュメント
によるものの３つが挙げられる。

「 ダブルクォート（""） 」で囲まれた中に変数があると変数箇所が格納されているデータに置き換わる。
これを変数展開という。
「シングルクォート（''）」だと変数は展開されない。

参考記事：https://wepicks.net/moziretsugata/


##整数型

整数、負の数、ゼロを表現できる。


##浮動小数点数型

小数を表現できる。
指数表現を使った浮動小数点を使うことができる。

##論理型

trueかfalseのいずれかの状態しか持たない（trueとfalseはTRUEとFALSEでも可）

PHPでfalseとみなす状況は、以下の通り。


- 空文字、または文字列の０
- 整数リテラルの０
- 浮動小数点リテラルの０．０
- 要素数が０
- null（未定義）

```php
$x = '';
$x = '0';
$x = 0;
$x = 0.0;
$array = [];
$x = $array;  // 要素数は０
$x = null;
```

##配列型

１つの変数に複数の値をもたせることができる。


参考：http://blog.a-way-out.net/blog/2015/12/22/php-array/

話はとても変わるが、以下は参考記事から引用。大事だなと思ったところ。
> PHPの配列はarray型の1つしかない
> PHPの配列は順番を保持している
> 配列のキーの型は整数と文字列しかなく、両者は区別される
> 配列のキーには暗黙の型変換が起こる！


##オブジェクト型

オブジェクト型とは、データと手続きをまとめたもの。
クラスをnewして作ったインスタンスはオブジェクト型になります。

##リソース型

リソース型は特殊な型で、
外部リソースへの参照を保持している。

例えば、
fopen()でファイルを参照したり
mysql_connect()でDBへ接続した状態を変数に入れると
それはリソース型になる。

```php
$resource = fopen('test.txt', 'r');
var_dump($resource);
// resource(470) of type (stream)
```

引用元：https://qiita.com/minato-naka/items/abd7f76dca2b15a7d6ba#%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E5%9E%8B


＃＃NULL型
値を持たないことを意味していて、リテラルとしてnullを持つ。


以下の場合、変数はNULLであるとみなされる。

- 変数に値が代入されてない場合。
- 変数にnullが明示的にはいっている場合。
- unset命令で変数の内容が破棄された場合


##参考
PHPの型比較を行うときに参考にすること。

https://www.php.net/manual/ja/types.comparisons.php
dotnet publishをするとエラーMSB4126が発生する

riderで作成したapiをdotnetコマンドでpublishした際にエラーでハマったのでメモ

# 結論

```bash
dotnet publish -p:Configuration=Release -p:Platform="Any CPU"
```

# 環境

macOs Catalina 10.15.7
Rider 2020.03.2
docnet core 5.0.103

# 問題

```Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ./*.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Realease -o /app

FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT [ "dotnet", "hoge.dll"]

```

こちらを実行すると掲題のエラーが発生。
* 上記はdockerfileだが、結局ローカルで試しても発生したため、dockerのせいではなかった。

## エラー内容

```bash
error MSB4126: The specified solution configuration "Realese|Any CPU" is invalid. Please specify a valid solution configuration using the Configuration and Platform properties (e.g. MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform="Any CPU") or leave those properties blank to use the default solution configuration. 
```

## hoge.sln

```bash

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hoge", "hoge.csproj", "{F5EA8D2E-2117-4753-93CB-EF809C3A7D1B}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{F5EA8D2E-2117-4753-93CB-EF809C3A7D1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{F5EA8D2E-2117-4753-93CB-EF809C3A7D1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{F5EA8D2E-2117-4753-93CB-EF809C3A7D1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{F5EA8D2E-2117-4753-93CB-EF809C3A7D1B}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
EndGlobal
```

ソリューションファイルをみても特に問題点が見当たらない。

# 調査と唐突な解決

調査してみたが、visual Stadioでソリューションファイルのプロパティを云々、というのが多かった。
が、当然Riderでは使えそうにない。

https://stackoverflow.com/questions/50398549/adding-pplatform-any-cpu-parameter-forces-the-build-in-debug-configuration

こちらを見ると、Any CPUというパラメータを追加しろとのこと。
しかし、VSではないので追加の仕方がわからない。。。

ふと、 `/p:Configuration=Debug /p:Platform="Any CPU"` こちらの一文が気になって、追加して実行してみた。

```bash
dotnet publish -p:Configuration=Release -p:Platform="Any CPU"
```

動いた。
https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish
しかし、こちらにもこのオプションについての記載がなく、仔細はなぞのまま。
とりあえず動いたのでよし。
[Tkinter] Treeview 練習

#はじめに
Pythonで表をGUIで表示してくれるTreeViewを使ってみました。GUIにはTkinterを利用します。

#やりたいこと
下記のような表を作成し、GUIに表示したいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/cc789351-4a33-3ccd-b15b-9f75138f39ce.png)

#Tkinter

```Python
import tkinter as tk
from tkinter import ttk

main_win = tk.Tk()
main_win.title('Pizza List')
main_win.geometry('400x300')

#Treeviewを宣言
my_tree = ttk.Treeview(main_win)
main_win.mainloop()

```

#Columnを定義

```Python
#Define Our Columns
my_tree['columns'] = ('Name', 'ID', 'Favorite Pizza')

```

#Columnのフォーマットを定義

```Python
my_tree['columns'] = ('Name','ID','Favorite Pizza')
my_tree.column('#0',width=0, stretch='no')
my_tree.column('Name', anchor='w', width=120)
my_tree.column('ID',anchor='center', width=80)
my_tree.column('Favorite Pizza', anchor='w', width=120)
```

#ColumnのHeadingを作成

```Python
#Create Heading
my_tree.heading('#0',text='Label',anchor='w')
my_tree.heading('Name', text='Name',anchor='w')
my_tree.heading('ID', text='ID', anchor='center')
my_tree.heading('Favorite Pizza',text='Favorite Pizza', anchor='w')
```


#データを追加

```Python
#Add data
my_tree.insert(parent='', index='end', iid=0 ,values=('John',1,'Peperoni'))
my_tree.insert(parent='', index='end', iid=1 ,values=('Mary','2','Cheese'))
my_tree.insert(parent='', index='end', iid=2, values=('Tina','3','Ham'))
my_tree.insert(parent='', index='end', iid=3, values=('Bob','4','Supreme'))
my_tree.insert(parent='', index='end', iid=4, values=('Erin','5','Cheese'))
my_tree.insert(parent='', index='end', iid=5, values=('Wes','600','Onion'))
```



#全体コード

```Python
import tkinter as tk
from tkinter import ttk

main_win = tk.Tk()
main_win.title('Pizza List')
main_win.geometry('400x300')

#Treeviewを宣言
my_tree = ttk.Treeview(main_win)

#Define Our Columns
my_tree['columns'] = ('Name', 'ID', 'Favorite Pizza')

#Formate Our Columns

my_tree['columns'] = ('Name','ID','Favorite Pizza')
my_tree.column('#0',width=0, stretch='no')
my_tree.column('Name', anchor='w', width=120)
my_tree.column('ID',anchor='center', width=80)
my_tree.column('Favorite Pizza', anchor='w', width=120)

#Create Heading
my_tree.heading('#0',text='Label',anchor='w')
my_tree.heading('Name', text='Name',anchor='w')
my_tree.heading('ID', text='ID', anchor='center')
my_tree.heading('Favorite Pizza',text='Favorite Pizza', anchor='w')

#Add data
my_tree.insert(parent='', index='end', iid=0 ,values=('John',1,'Peperoni'))
my_tree.insert(parent='', index='end', iid=1 ,values=('Mary','2','Cheese'))
my_tree.insert(parent='', index='end', iid=2, values=('Tina','3','Ham'))
my_tree.insert(parent='', index='end', iid=3, values=('Bob','4','Supreme'))
my_tree.insert(parent='', index='end', iid=4, values=('Erin','5','Cheese'))
my_tree.insert(parent='', index='end', iid=5, values=('Wes','600','Onion'))


# my_tree.move('6','0','0')
my_tree.pack(pady=20)


main_win.mainloop()

# https://www.youtube.com/watch?v=YTqDYmfccQU
```

#参考資料

1. https://www.youtube.com/watch?v=YTqDYmfccQU
2. https://riptutorial.com/tkinter/example/31880/treeview--basic-example
[Laravel] Declaration of Illuminate\Container\Container must be compatible with にハマったのでメモ

laravel でcomposer update したら、

```
PHP Fatal error:  Declaration of Illuminate\Container\Container::get($id) must be compatible with Psr\Container\ContainerInterface::get(string $id)
```

とエラーが発生したのでその解決方法をメモ


## 解決策
composer.json の設定をミスったのかとか
composer のchache-clear とか
composer.lockとvendorを削除して、再度、composer install とか
bootstrap/chacheのファイルを削除とか
いろいろ試したが全く解決せず


数時間、格闘した末、
あらためてエラー内容をみると、


```
Psr\Container\ContainerInterface::get(string $id)
```
と互換性がないといっている、


つまり、

```
Illuminate\Container\Container::get($id)
```

Illuminate\Container\Containerクラスのgetメソッドに、タイプヒンティングがないのでエラーになっていました



取り急ぎの対応として
Illuminate\Container\Container:592あたり

```php

public function get(string $id)
```

string を追加するとエラー解消


この対応方法でいいのかはわからないが、
緊急で対応する必要がある方は、参考にしてください。。
【TypeScript】Utility TypesのParametersを深く理解する

# この記事は何？
この記事は、Utility Typesの一つである**Parameters**について深く理解する記事です。
Utility Typesってそもそも何？という型（方）は以下の記事を御覧ください🙇🏻
👉 [TypeScriptのUtility Typesを理解して活用する](https://qiita.com/NOMURA_keibyou38/items/84caee0657f57650577d)

そもそも、TypeScriptって何？って型は以下を御覧ください
👉 [JavaScriptを知っている方がTypeScriptをなんとなく理解するための記事① ~はじめに~](https://qiita.com/NOMURA_keibyou38/items/06a3218de3ff480ce9de)

# Parameters＜Type, Keys＞とは
TypeScript公式には以下のように書かれています。
> Constructs a tuple type from the types used in the parameters of a function type Type.
> 関数型Typeのパラメーターで使用される型からタプル型を構築します。
> https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype

ちょっとわかりづらいですね😅

因数分解すると以下のような意味になります。
- 関数型Typeのパラメーターで使用される型から → 関数の引数の型から
- タプル型を構築します。 → タプル型を構築する

つまり、Parameterは、関数を使ってタプル型を生成するものです。

実際にコードの場合、以下のように表すことが出来ます。

```typescript
type hogehoge = Parameters<関数型>
```


```typescript
// type nonTuple = []
type nonTuple = Parameters<() => string>; // 引数がないので空タプル

// type stringTuple = [value: string]
type stringTuple = Parameters<(value: string) => string>; // 引数がstringのタプル

const callAnimal = (animalName: string, owner: string): void => {
  console.log(`${animalName}！${owner}の近くにおいで！`);
}

// type animalTuple = [animalName: string, owner: string]
type animalTuple = Parameters<typeof callAnimal>; // 引数が2つなので、２つ要素のあるタプル
```

このParameters<>はどのようなシーンで利用するのでしょうか？

これは個人的に考えた用途なのですが、サードパーティーの関数を利用する時に使えるのではないかと考えています。

例えば、以下のような関数を含むパッケージをインストールするとします。

```typescript:plusOneMessage.ts
export const plusOne = (num: number, greeting: string): string => {
  return `${greeting}、${num}をプラス１すると${num + 1}が得られます。`;
};
```

そして、この関数を利用してみます。

```typescript
// plusOne関数をimport
import { plusOne } from "./plusOneMessage";

// 予めplusOne関数の引数の型を`Paramaters`で作る
type plusOneType = Parameters<typeof plusOne>; // type plusOneType = [num: number, greeting: string]

// plusOne関数にわたす予定の定数の型を指定する。
const inputForm: plusOneType = [100, "こんにちは"]; // const inputForm: [num: number, greeting: string]

// plusOneを使う
console.log(plusOne(...inputForm)); // こんにちは、100をプラス１すると101が得られます。
```

このように、誤った型の引数を関数に渡さないよう、予め`Paramaters`で関数の型を作っておいて、引数に関数の型を指定します。
この関数から作った型を使えば、誤った型を持つ引数を渡すことが防げます。
また、わざわざplusOneの関数の型を`interfece`で作る必要もありません。

また、React&TypeScriptであれば、以下のように使っても良いかもしれません。

```jsx
import { plusOne } from "./plusOneMessage";

type Props = Parameters<typeof plusOne>;

const hogehogeComponent: React.FC<Props> = (props) => {
 ...
}
```

以上のように、利用できるかと思います。
他にも、良い利用方法があれば是非コメント欄で教えて下さい！

# おわりに
今回は、Utility TypesのParametersについて紹介しました。
是非、ご活用ください！

# 参考
- https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype
- https://qiita.com/canoypa/items/a05c4157ea668dbd2f2d
- https://hachibeechan.hateblo.jp/entry/how2-copy-arguments-type-in-TypeScript
[ AWS ] EC2の本番環境で画像が表示されない問題

RailsのポートフォリオをデプロイしたくてEC2の環境構築から始まり、
ようやく終わりが見えかけたその時に悲劇が起こった。
　
　
![スクリーンショット 2021-03-07 22.11.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/b362eddf-f4c6-d76d-44ad-db30b3b603b0.png)
なん..だと！？


　　
仕方なくログで確かめるが、読み方がいまいち分からない。
ただあからさまに違う所を発見。

```
$ tail -f  production.log

13: <div class='main-image'>
14: <%= image_tag "main_dog", class:"main-dog" %>
15: </div>

app/views/pets/index.html.erb:14
```


ローカル環境の画像のせいでエラーが起きているらしい。
何が原因かなんて想像もつきませんでした。
　

##解決方法
imagesファイルの画像はどうやら本番環境で作動するにあたり、
データがコンパイル(圧縮)されるのが原因らしい。
あとは送られるパスも変わるらしい。パスについてはほんとに謎。

**コンパイルされるのが原因**なので、

```config/environments/production.rb
config.assets.compile = false
```

２９行目の記述を**false**から
**true**に変更してあげる。↓↓

```config/environments/production.rb
config.assets.compile = true
```
　

次に**public配下に/images**を入れる。
　　

そして画像を読み込むpathを書いてあげる。
(パスの指定を本番環境用に指定する)

```
<%= image_tag ‘/images/dog.jpg', class:"main-dog"  %>
```

**！上記のエラーログの記述だと読み込まない！**
　　


記述が終わり次第、Gitにコミット、プッシュし
ターミナル(EC2内)



###まとめ
自分の場合はこれでEC2の本番環境でもエラーがなくなり、無事画像が読み込めていました。一件落着です。
【Oculus Integration】UI Interactionの方法

1. UI Canvasに`OVR Raycaster`コンポーネントをアタッチします。
2. UI Canvasの`Graphic Raycaster`コンポーネントを削除します。
3. UI Canvasを追加した際に同時に追加された、`EventSystem`オブジェクトを削除します。
4.  プロジェクトから`UIHelper`Prefabをシーンに追加します。
5. `UI　Helper`の`EventSystem`にある`OVR Input Module`コンポーネントの`Ray Trasform`に使用するコントローラーをドラッグ&ドロップします。`Right Hand Anchor`または`Left Hand Anchor`.
UnityでBoltを使用してWebRequestをする

# 使用バージョン
- Unity 2019.4.21f1
- Bolt 1.4.12

# 本記事の目的
Boltを使ってUnityWebRequestを使って通信を実装する

# はじめに
Unityの公式になった、Boltというビジュアルスクリプトプログラミングツールがあります
公式でのチュートリアル動画などありますが、個人的にWebRequestを使っての通信で詰まった部分があったので
その備忘録として記事を書きます

# github
今回の通信のサンプルをGithubに公開しています
https://github.com/ttyyamada/BoltNetworkSample

# セットアップ

まず、Boltのインストール時、インストール済みの場合は
`Tools→Bolt→Unit Options Wizard...`
のAssembly Optionsの画面から
`UnityWebRequestModule`を追加します

![Assembly OptionsにUnityWebRequestを追加](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49946/a726c6d1-d4a2-d958-bdd6-bd9920f32fc6.png)

その次のType Optionsの画面では
- UnityWebRequest
- DownloadHandler
- UnityWebRequestAsyncOperation
の3つを追加します

![Type Optionsに追加](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49946/8372453a-7f03-b336-2217-393b2dd5c6a9.png)

こうする事で、BoltのNodeでUnityWebRequestを使う準備ができました

# Graphの追加

ここは通常のBoltと同じ感じでGraphを追加していきます
結果としてはこんな感じになります

![BoltのGraphサンプル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49946/b07d08fc-b9e2-465b-6096-128b200cd907.png)

（これらのノードのサンプルは[Github](https://github.com/ttyyamada/BoltNetworkSample)に公開してあります）

# Graphの説明
まず最初に、トリガーとなる最初の部分をGraph Inspectorから設定します
（わかりにくいですが、`Window→Graph Inspector`から表示できます）

今回はUpdateをトリガーにしていますが、そこで`Coroutine`にチェックを入れます
![Coroutineにチェック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49946/6c231252-a8c7-d1ce-b2c7-53e49a945853.png)

こうする事でGraphのノードでCoroutineを実行することができます

通信部分のGraphの設定はこのように設定しています

![通信説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49946/d11810fe-e71f-4ef3-4178-6ec709906311.png)

このサンプルではDebug.Logで通信内容を出しているだけですが、通常は通信結果をjsonUtilityなどでクラスにコンバートして表示。などできます

# 最後に
今回はCoroutineのInspectorでの設定、UnityWebRequestのAssembly Optionsの追加などで詰まってしまったので、
そこの備忘録として記載しました
BoltはBolt2の開発が進められていますが、互換性も維持するらしいので、今から触っておくのも良いかもしれません
pygameでゲームを作ってみる1

#はじめに
Pythonの基本的な文法を学んだところで、何かを作ってみたいと思い、3月5日からpygameでもぐらたたきのようなゲーム（もぐらではなくプレーリードッグ）を作り始めた。
（プレーリードッグが巣穴に住むかわいい姿を見たときに思いついた。）
せっかくなので、作成過程を記録していきたいと思う。
です・ます調が柔らかくて好きだけど、サクッと書きやすいし、なんか恥ずかしいから、だ・である調にしてみたり。（たりって2回使わないといけないよね～と思いながらレポートじゃないときは間違った方法で使ってしまう）

#進捗
###できること
・テキストを表示する
・残り時間をカウントし、表示する
・得点を計算し、表示する
・画像を表示する
・画像を一方向に動かす
・画像上をクリックしたときに「+1」を表示する
・画像上をクリックしたときに1点加える
###コード全文

```python:Game.py
import pygame
from pygame.locals import *
import sys
from pygame.time import Clock

def main():
    pygame.init()
    (w,h) = (500, 500)
    (x,y) = (w/2, h/2)
    pygame.display.set_mode((w,h), 0, 32)
    cl = pygame.time.Clock()
    screen = pygame.display.get_surface()
    pygame.display.set_caption("Game")
    font = pygame.font.SysFont(None, 78)
    font2 = pygame.font.SysFont(None, 45)
    font3 = pygame.font.SysFont(None, 30)
    text1 = font.render("Click!", True, (204, 102, 112))
    text2 = font2.render("+1", True, (0, 0, 0))
    ob1 = pygame.image.load("Game\dg.jpg")
    rect_ob1 = ob1.get_rect() 
    rect_ob1.center = (x, y)
    a = 50
    b = 200
    c = 0
    score = 0
    n_frames = 0
    TIME_END = 15
    
    while (1):
        screen.fill((102, 204, 194)) 
        screen.blit(text1, [170, 30])
        screen.blit(ob1, (a, b))
        ob1Rect = pygame.Rect((a, b), ob1.get_rect().size)
        
        rest = TIME_END - (n_frames / 30)
        text4 = font3.render('time: {}'.format(round(rest,1)), True, (0, 0, 0))            
        screen.blit(text4,[350,60])

        for event in pygame.event.get():
            if event.type == QUIT:
               pygame.quit()
               sys.exit()
            if n_frames < 30 * TIME_END and event.type == MOUSEBUTTONDOWN and event.button == 1:
                if ob1Rect.collidepoint(event.pos):
                    c = 9
                    score += 1
        text3 = font3.render('score : {}'.format(score), True, (0, 0, 0))
        screen.blit(text3, [350, 40] )

        if c > 0:
            pos = pygame.mouse.get_pos()
            screen.blit(text2, pos)
            c -= 1

        pygame.display.update()
       
        if n_frames < 30 * TIME_END:
             n_frames += 1
        
        b -= 2

        cl.tick(30)

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

#おわりに
便利そうなSpriteクラスについて学び、使ってみる。
Rails 正規表現

##正規表記の種類
>私が覚えた正規表記の種類についてここに残しておきます。
うまく組み合わせてパスワード・名前入力にバリデーションをしてください。
Railsでバリデーションをするにはモデル作成時に生成されたモデル名.rbに記入してください。
誰かのやくに立てたら幸いです。

|種類|意味|
|:-:|:-:|
|[a-z]|角括弧で囲まれた文字のいずれか 1個に一致|
|\d|数字に一致|
|{n, m}|直前の文字が少なくともn回、多くてもm回出現するものに一致|
|.|改行以外のどの1文字にも一致|
|+| 直前の文字の1回以上の繰り返しに一致|
|\A|直後の文字が先頭にある文字列に一致|
|\z|直前の文字が末尾にある文字列に一致|
|[ぁ-んァ-ヶ一-龥々]|角括弧に囲まれたかな、カナ、漢字のいずれかにマッチ（ヴ、ヵ、ヶ、々を含む）|
|?=|直後に設定した文字が続く文字列に一致|
|*?|直前に設定した文字が0回以上続く文字列をチェックし、?の直後の文字が出た段階でその1文字を返す|

##Password

```モデル.rb
PASSWORD_REGEX = (/\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i)
validates_format_of :password, with: PASSWORD_REGEX
```

##名前
```モデル.rb
 with_options presence: true, format: { with: /\A[ぁ-んァ-ン一-龥]+\z/ } do
    validates :family_name
    validates :last_name
  end
```
Terraform用のサービスプリンシパルを作成する

## Terraform用のサービスプリンシパルを作成
ここで出力された値は次の手順で環境変数に登録します

```console
% az ad sp create-for-rbac -n <name>
```

## 環境変数に登録
上記コマンドで出力された情報を環境変数に登録

```console
export ARM_SUBSCRIPTION_ID=<サブスクリプションID>
export ARM_CLIENT_ID=<サービスプリンシパルのappId>
export ARM_CLIENT_SECRET=<サービスプリンシパルのpassword>
export ARM_TENANT_ID=<サービスプリンシパルのtenant>
```

## 確認用のtfファイル作成
```terraform:main.tf
terraform {
  required_version = "0.14.7"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 2.47.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "test" {
  name     = "test-rg"
  location = "Japan East"
}
```

## 確認
サービスプリンシパルを使ってapplyできることを確認します

```console
% terraform init
% terraform plan
% terraform apply
```

## 後片付け
無事に確認が終わったら片付けしておきます

```console
% terraform destroy
```

以上
【Git】ワークツリー内の時に、削除したディレクトリを戻す方法

いまいちgit管理の旨みを感じれないまま、
ポートフォリオの開発をしていました。

久々にRailsチュートリアルを１章から読んでみたら、
コミット前の状態に戻す方法が乗っていたので、
必要になると思い、投稿しました。

```
$ git status

On branch feature/1
Your branch is up to date with 'origin/feature/1'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	deleted:    app/controllers/application_controller.rb
	deleted:    app/controllers/concerns/.keep

no changes added to commit (use "git add" and/or "git commit -a")
```
コントローラーが削除されましたよというエラーが表示されています。

```
$ git checkout -f

On branch feature/1
Your branch is up to date with 'origin/feature/1'.
```
あたなのブランチは最新の状態ですになりました。
<br>
念のため、statusとlsで中身が戻ったかもみてみます

```
$ git status

Your branch is up to date with 'origin/feature/1'.
```

```
$ ls app/controllers

application_controller.rb	concerns
```

無事に戻りました！
NSTextCheckingResult.CheckingType.linkでURL抽出を正常に行うならURLのあとに半角スペースもしくは改行を入れるべき

# NSTextCheckingResult.CheckingType.link

URL抽出に使う、Stringの配列で受け取れる

```swift:実装例
let check = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
let match = check.matches(in: self, options: [], range: NSMakeRange(0, self.count))
let urls: [String] = match.compactMap { (self as NSString).substring(with: $0.range) }
```

NSAttributedStringと組み合わせてUITextViewにリンクを挿入するときなどに使う

```swift:実装例
let textView = UITextView()
let attributeString = NSMutableAttributedString(string:textView.text)
urls.forEach { url in
    attributeString.addAttribute(.link,
                                 value: url,
                                 range: NSString(string: content.text).range(of: url))
}
textView.attributedText = attributeString
```

![standard.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278589/6be10dc9-d675-9d9c-76b3-0749d7eaec20.gif)


# URLの後ろすぐに日本語がついている場合
すべてURLとして処理される

![none.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278589/b6ac96b1-0f74-7be1-de04-fba8da108c14.png)


半角スペースもしくは改行をすれば正常に動作する。

![space.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278589/b1b24a23-5edc-8235-b723-28d43718bc46.png)


英語圏だとURLと見分けがつかないから必然的に改行もしくはスペースが入るわけで
こういうケースがあるのは日本語含む非英語圏ならではなのかと思う🙄

# 自由入力でリンクをつきのUITextViewを作るなら正規表現が良い

```swift:実装例
let pattern = "(http://|https://){1}[0-9a-zA-Z\\.\\-/:!#$%&@=?_]+"
let regex = try! NSRegularExpression(pattern:pattern, options:[])
guard let range = self.range(of:self) else { return [] }
let urls: [String] = regex.matches(in:self, range:NSRange(range, in: self)).map { String(self[Range($0.range, in:self)!]) }
```

![regex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278589/1eed3f89-3463-4766-a01c-a6a672c4d37f.png)

# github
https://github.com/aoi-kimura/linkSample
【Ruby on Rails】 Permission denied @ dir_s_mkdir の解消法

自身の備忘録のために。

Railsチュートリアルでbundleのインストールを実行中に下記エラーが発生。
「Permission denied @ dir_s_mkdir」

調査を進めると、権限が「username」ではなく「root」になっているのが原因でした。

ターミナル上で「sudo chown -R username /Users/username/.rbenv」を入力して実行。
usernameの部分は自PCのユーザー名に変更する。

引用、参考にさせて頂いた文献は下記です。
https://dara-blog.com/about-rails-error01

大変参考になりました。ありがとうございます。
【HTML】brタグを多用してはいけない

#プログラミング勉強日記
2021年3月7日


#brタグを多用してはいけない理由

- <b>デバイスによってレイアウトがずれてしまうため</b>

　必要なところで`<br>`を使うのはいいが、レイアウトを整えるために使うのは良くない。デバイスによって画面幅が異なり返って見にくくなる可能性がある。


#対処法
　膨大なページですでに`<br>`を多用している場合は、CSSで改行を無効にすることができる。


```css:CSS
br {
 display : none ;
}
```

　段落を作ることで、改行の記述を減らすこともできる。

```html:HTML
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>sample</title>
</head>

<body>
  <p>段落1</p>
  <p>段落2</p>
</body>
</html>
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/e773ddfb-6d02-d671-d8ae-b63745658c48.png)
[【HTML入門】pタグと改行の関係をレイアウトの違いに注目して完全に理解](https://www.sejuku.net/blog/77744)

#参考文献
[[HTML] BRタグは使うな! 私が「改行」を一切使わなくなった1つの理由](https://yossense.com/br-do-not-use/)
masterブランチにコミット済みの内容をレビューしたときにやったこと


## 状況
プログラミングを始めたばかりの友人にコードレビューをお願いされた。
ソースコードはGithubにあって、masterブランチにすべてコミットされている。
行単位のコメントを付けたいが、どうしたら良いか。


## 対応方針
masterブランチとは切り離されたブランチを二つ作成し、GitHubでプルリクエストを作成する。
そこでレビューを行う。


## やったこと

```
# 対象のリポジトリをクローンする
git clone ...

# 親を持たないブランチを作成する
git checkout --orphan  tmp_branch_for_review

# 空の状態のブランチを作りたいのでいったん全部消す（ここら辺、もっとスマートなやり方がありそう）
git rm --cached . -r

# ファイルが無いとコミットでエラーになるのでREADMEだけ戻す。（commit時のオプションで回避できそう）
git add README.md

# commitしてpush。このブランチがプルリクエストのだし先となる。
git commit -m 'Initial Commit'
git push origin tmp_branch_for_review


# プルリクエストの出し元となるブランチを作成する
git checkout -b tmp_branch_for_review2

# 先ほどgit rmで削除したファイルを戻す
git add .

# commitしてpush
git commit -m 'commit'
git push origin tmp_branch_for_review2
```


"tmp_branch_for_review2"から"tmp_branch_for_review"にプルリクエストを作成する。


## 補足
masterブランチの最初のコミットが単純な内容であれば、もっと単純な方法が取れたと思う。例えば、masterブランチの最初のコミットからブランチを切り、そこに対してmasterブランチからプルリクエストを出せば良さそう。

今回は、masterブランチの最初のコミットでほぼ全てのファイルが追加されていたため、色々うまくいかずに今回の方法を取った。
Google Colaboratory でファイルを読み込み

#Google Colaboratory で CSVファイル読み込み

google colaboratory に読み込んだNotebookでcsvファイルを読み込むには
google driveをマウントした後に、絶対パスを指定すれば読み込むことができる。

https://note.com/092i034i/n/n76f2c2de1974

ということで、pandasで読み込ませたところ、
エラーになってしまった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62549/0653666e-737b-a89e-ef35-e0b109c7cb97.png)

```ipynb
!ls /content/drive/My\ Drive/csv_data
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62549/de08da84-e606-53b8-c243-6d0ecad64496.png)

見慣れない拡張子がついている。
どうもCSVファイルはアップすると別のファイル形式に変換されるようで、
Driveの設定で変換されないようにする必要があった。

# 対処方法

Driveに行き、歯車マークをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62549/29bce965-c6f4-1512-db95-2faed773d357.png)

設定をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62549/1038be4f-baa0-02d4-d074-da78a5f20cd0.png)

「アップロードしたファイルを変換する」のチェックをOFFに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62549/b109a6ce-03ff-6f4e-9d70-ba4c11baa33b.png)

再度CSVファイルをアップロードしてから読み込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62549/4f443268-dba7-75ca-80a5-85d1d5e8be49.png)

これで、読み込むことができました。

```python
import pandas as pd

df_links = pd.read_csv("/content/drive/My Drive/csv_data/test.csv")
df_links.head()
```

test.csvの中身が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62549/9a7efbe7-8752-1582-47ff-0feaab650ab3.png)
Windows 10 + WSL2 + Ubuntu 20.04 + Visual Studio CodeでPythonの学習環境を整える

# はじめに

Pythonの勉強をするために、手を動かしながら文法やライブラリを覚えることが大事です。
そのためには、コードを書いて動かすための環境を整えなければなりません。
本記事は実務向けではなく、Pythonを学習するための最低限の環境を整えることを目的として執筆します。

すでに良質なQiita記事が公開されているため適宜参照させていただきながらまとめました。

# 要件

要件は以下です。

- Visual Studio Codeを利用すること
- REPLまたは1ファイルが実行できること

# 前提条件

- Windows 10がインストール済のPCが手元にあること

# 確認環境

|コンポーネント|バージョン|
|---|---|
|OS|Windows 10 Pro 20H2 |
|ハイパーバイザ|Windows Subsystem for Linux 2 (以下 WSL2)|
|エディタ| Visual Studio Code 1.53.2 |
|プログラミング言語 | Python 3.8.5 |

# 環境構築手順

## WSL2のセットアップ

下記の記事を参考にWSL2のセットアップを行います。
[WSL2(Windows Subsystem for Linux)導入手順](https://qiita.com/kenchan1193/items/74edfc67910b51469b45)

## パッケージのインストール

WSL2で動作するUbuntuで下記のコマンドを実行し、パッケージをインストールする

```
sudo apt install python3
```

## Visual Studio Codeのセットアップ

下記のサイトからVisual Studio Codeをダウンロード・インストールします。
[Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)

## Visual Studio Codeのエクステンションのインストール

下記のVisual Studio Codeのエクステンションをインストールします。

- [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
- [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python)

## Visual Studio CodeからWSL2に接続する

Visual Studio Codeを開き、リモートエクスプローラを選択。
Ubuntu-20.04を右クリックし「Connect to WSL」を選択すると、WSL2のUbuntuに接続された別ウィンドウが開く。

# PythonプログラムをREPLから実行する

## pythonを起動する

ターミナルで"python3"と入力する

## Pythonプログラムを実行する

下記のプログラムを入力すると、Hello World.と表示されることを確認する。

```
print('Hello World.')
```

# Pythonプログラムをファイルから実行する

## サンプルプログラムの作成

以下をhello.pyとして作成する。

```
print('Hello World.')
```

## インタプリタを選択

Ctrl + Shift + Pで"Python Select Interpriter"と入力し、「Python 3.8.5 64-bit」を選択する。

## ターミナルでPythonファイルを実行

"Run Python File in Terminal"を実行し、ターミナルにHello World.という文字列が表示されたことを確認する。

# 参考情報

- [WSL2(Windows Subsystem for Linux)導入手順](https://qiita.com/kenchan1193/items/74edfc67910b51469b45)
- [Getting Started with Python in VS Code](https://code.visualstudio.com/docs/python/python-tutorial)

# 最後に

本記事によってPythonをREPLまたはファイルから実行しできる学習環境を構築することができました。
Newtonsoft の Json.NET を Unity で使うときに便利な設定

NewtonSoft の Json.NET 使っていますか？Unity 標準の JSON Utility と比較して汎用性が高く、ちょっとしたことをよしなに取り込んでくれることが多いのでよく使っています。おまけに書いた問題もありますが、それはまた別記事で。

# TL;DR
以下設定しておけば、JsonSerializationException が出ることもなく、LowerCamelCase にも対応できます。
### サンプルコード
``` C#
        var settings = new JsonSerializerSettings
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
        var json = JsonConvert.SerializeObject(target, settings);
```


# JsonSerializationException が出てしまう
## エラーサンプル
```
JsonSerializationException: Self referencing loop detected for property 'normalized' with type 'UnityEngine.Vector3'. Path 'normalized.normalized'.
```

## 原因
Unity の normalized のプロパティは、自身のプロパティに normalized を持っているので、このプロパティを無限に参照できることに起因しています。

## 解決方法
シリアライズするときにオプションを設定することで無視することができます。これだけでエラーは回避できます。
> var settings = new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore};


# key は小文字だが、プロパティは大文字始まりにしたい
サーバサイドとやりとりするときに、相手方が LowerCamel を想定している場合があります。
ただフィールドやプロパティを UpperCamel にしたい場合に差異がでてしまうので、そこをうまくやる設定項目です。

## 解決方法
シリアライズするときにオプションを設定することで、よしなにうまくやってくれます。
> var settings = new JsonSerializerSettings {ContractResolver = new CamelCasePropertyNamesContractResolver()};

## 参考
相手方が LowerCamel だったとしても、デシリアライズは設定なしでも Json.NET がよしなにやってくれます。


# おまけ
問題だと思っていること。

* dll で取り込んでいると、WPFビルドやiOSビルドで死ぬときがある。
  * WPFビルドの場合は、Unity からソリューションを出したタイミングで、dll を追加してあげればエラーにならないようにする方法があります。また別記事で書きます。
  * iOSビルドの場合は、dll では無理なので、PackageManager で本家 folk されたプログラムを取り込む方法があります。また別記事で書きます。
* パフォーマンスが良くない。こちらの[記事](https://takap-tech.com/entry/2020/08/16/201555)が参考になるかと。
Roman to Int  〜leetcode〜


#〜問題文〜
```
Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000


For example, 2 is written as II in Roman numeral, just two one's added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

I can be placed before V (5) and X (10) to make 4 and 9. 
X can be placed before L (50) and C (100) to make 40 and 90. 
C can be placed before D (500) and M (1000) to make 400 and 900.
Given a roman numeral, convert it to an integer.

 

Example

Input: roman = "III"
Output: 3
Example 2:

Input: roman = "IV"
Output: 4
Example 3:

Input: roman = "IX"
Output: 9
Example 4:

Input: roman = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
Example 5:

Input: roman = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
 

Constraints:

1 <= s.length <= 15
s contains only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M').
It is guaranteed that s is a valid roman numeral in the range [1, 3999].

```

引用元：　https://leetcode.com/problems/roman-to-integer/

簡単に要約すると、「任意のローマ数字を入れたら数字になるようにコーディングしなさい。」だそうです。

↓回答例


```ruby
def roman_to_int(s)
  hash = {
    'I'=> 1,
    'V'=> 5,
    'X'=> 10,
    'L'=> 50,
    'C'=> 100,
    'D'=> 500,
    'M'=> 1000
  }

  total = 0
  i = 0
  while i < s.length
    if i + 1 < s.length && hash[s[i]] < hash[s[i+1]]
      total += hash[s[i+1]] - hash[s[i]]
      i += 1
    else
      total += hash[s[i]]
    end

    i += 1
  end

  return total
end
```

回答引用元（一部改変）：
https://leetcode.com/problems/roman-to-integer/discuss/704290/ruby-solution-44ms-using-each_char


#以下、上記回答の分解分析

## 1. ハッシュでの定義

```ruby
hash = {
    'I' =>    1,
    'V' =>    5,
    'X' =>    10,
    'L' =>     50,
    'C' =>     100,
    'D' =>     500,
    'M' =>     1000 
    }
```

やはりハッシュはアローでつなぐと見やすいですね（個人的に）。

## 2. 変数の定義

```ruby
 i = 0
```
each処理をする前に、入力されたローマ数字の前後関係を定義しておく。


## 3. ① while文 + ② if文

##① while文

```ruby
while i < s.length
   
　　〜省略〜
 
end
```

記入されたローマ数字の文字数（s.length）が回数（ i ）よりも少ない間は、処理が継続する。
（例）Input: s = "IV"　　=>　  s.length = 2

##② if文

```ruby
    if i + 1 < s.length && hash[s[i]] < hash[s[i+1]]

      total += hash[s[i+1]] - hash[s[i]]
      i += 1

    else

      total += hash[s[i]]

    end
```

【条件】
「記入されたローマ数字の文字数（s.length）が回数（ i ）よりも少ない」
　かつ
「前のローマ数字　が　後のローマ数字よりも小さい」

ならば、以下の処理を行う。

【処理】
後のローマ数字の値　-　前のローマ数字の値

```ruby
return total
```
値を返却。
discord.jsのフレームワークを作ってみた話

# 自己紹介
どうもみーかんです。
今回はdiscord.jsのフレームワーク、
discord.js-noobsをつくってみました。
そのインストールから実際の使い方を説明していこうと思います。

# インストール
npmの場合

```shell
$ npm install discord.js-noobs@1.0.0-fix
```

※ 現在は1.0.0-fixが安定版です。

# 実際に使ってみる
まずはClientの説明から
discord.jsのClientをベースに、
`command`, `commandDir`, `commands`
などが追加されている。

さっそく有名なping pongを書いてみよう。

```js:ping.js
const { Client } = require("discord.js-noobs");
const client = new Client({
  prefix: ["!"],
  readyMessage: (client) => `${client.user.tag} is ready!`,
  token: "ボットのトークン"
});

client.command("ping", (msg) => {
  msg.reply("pong!");
});
```

この状態で`!ping`と送信すると`@mention, pong!`と返ってくるはずです。

これができたら次のステップです。

# 引数(args)を取得する
`Client#command`の第二引数から取得することができます。
`!hello 〇〇`と送るとオウム返しするコードを書いてみましょう！

```js:hello.js
client.command("hello", (msg, args) => {
  msg.channel.send(`Hello ${args.join(" ")}!`);
});
```

この状態で`!hello noobs`と送信すると`Hello noobs!`と返ってくるはずです。

# 後書き
実際に使ってみてどうでしたか？
使いやすいと思ってもらえれば幸いです。
また開発環境が整えば開発する予定(かも)
Union typeからしっかりとExclude

試験結果から成績を6段階に分けるUnion Typeがあったとします。

```typescript
type ExamGrade = 'Perfect' | 'Excellent' | 'Awesome' | 'Great' | 'Good' | 'BAD!!!';
```

ここで合格だけの成績のUnion Typeを作りたいとします。そんなときは`ExamGrade`から不合格である`BAD!!!`を取り除いてしまう方法が一番簡単でしょう。

Union Typeからある型を取り除くためには`Exclude<T, U>`という便利なモノがUtility Typeで定義されています。これを使えば簡単に実装ができそうです。

## `Exclude<T, U>`の罠🧟

合格の成績`PassGrade`をこのように作ったとすると悲しいことが起きるでしょう。

```typescript
type PassGrade = Exclude<ExamGrade, 'BAD!!'>;
```

`ExamGrade, PassGrade` の両方をお使いのIDE等で貼り付けてみるとお分かりかもしれませんが`PassGrade`は`ExamGrade`とまったく同じ結果のUnion Typeです。つまり`BAD!!!`を取り除けていません。

## 何がいけなかったんですか👶

ズバリ言ってしまえばtypoが原因です。不合格を表すLiteral Typeは`BAD!!!`であったのに対し`PassGrade`で取り除こうとしたLiteral Typeは`BAD!!`です。`!`が足りないがために希望のUnion Typeが得られないという問題が発生していました。

このままではこの学校は落第するはずの学生が卒業してしまうかもしれません。

## `Exclude<T,U>`ってどうなっているんですか

`Exclude<T, U>`はTypeScriptでは以下のように定義されています。

```typescript
type Exclude<T, U> = T extends U ? never : T;
```

`T, U`の関係が重要です。右辺を見れば`T`は`U`の部分型であるかどうかで分岐をしていることはわかりますが入力部分である左辺ではこのふたつの型変数にはなんの関係もありません。
そのため`U`に`T`に存在しない型を入力したとしてもTypeScriptは問題なく(エラーを出さずに)ただの`T`を返してしまいます。

## どうすればいいんですか🤖

`T, U`の関係を自身で定義してあげればいいのです。以下のようにすると`T`の部分型である`U`しか代入できなくなります。

```typescript
type Eliminate<T, U extends T> = Exclude<T, U>;
```

`Eliminate<T, U>`は`Exclude<T, U>`に少しだけ変更を加えました。ジェネリクス`U`を`T`の部分型であることを明記するだけで先程の問題はなくなります。

```typescript
type ExamResult = 'Perfect' | 'Excellent' | 'Awesome' | 'Great' | 'Good' | 'BAD!!!';
type PassResult = Eliminate<ExamResult, 'BAD!!'>;
// Type '"BAD!!"' does not satisfy the constraint 'ExamResult'.
```

ジェネリクスにこのような制約を加えることによってシステム、サービスに細かい変更が加わったときに全体を見返すことなくTypeScriptが問題を報告してくれるようになるでしょう。
とくにtypoが多くて不安な方は積極的に導入をしましょう！🙋‍♂️🙋‍♂️
Swiftでスライダーを実装する。

### 音楽アプリであるような音量バーを実装してみた。

```
import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            Image(systemName: "speaker.fill")
            Slider(value: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant(10)/*@END_MENU_TOKEN@*/)
            Image(systemName: "speaker.3.fill")
        }
        .accentColor(/*@START_MENU_TOKEN@*/.gray/*@END_MENU_TOKEN@*/)
        .foregroundColor(/*@START_MENU_TOKEN@*/.gray/*@END_MENU_TOKEN@*/)
    .padding(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

＜シュミレーター＞
![シュミレーター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/8492f2ec-0cfb-054b-b9bb-03f0cc1e9bc9.png)


おおお、音量ボタン出てきた！
＊スライダーは動かすコードは書いてません
Django バックエンドでのクリックカウント2

# さらにスマートなクリック回数カウント
　<a href="https://qiita.com/hexanitrobenzen/items/a90bc2f3a06df01f9458">前回の記事</a>でDjangoのバックエンドでの表示回数のカウントの仕方について記事を執筆させていただきましたが、今回、さらに短いコーディングでバックエンドでのクリック回数カウントのやり方を見つけ出しましたので記事にすることにしました。

# 1.models.py
　まずはmodels.pyです。こちらから大きく書き方が違ってきます。
<pre>
# 記事
class Post(models.Model):
    user = models.ForeignKey(User, verbose_name='投稿者', on_delete=models.CASCADE)
    title = models.CharField(verbose_name='タイトル', max_length=40)
    content = models.TextField(verbose_name='本文')
    img = models.ImageField(blank=True, null=True)
    views = models.IntegerField(default=0) # 変更点
    created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True) 
</pre>

　今回もモデルの定義は適当です。前回の記事との相違点は新たにviewsというテーブルを用意したことと、カウント用に用意していたViewクラスを削除したことです。クリック回数のカウントをした後の結果はPostモデルのviewsテーブルに格納されることになります。

# 2.views.py
　次にviews.pyです。こちらも前回の記事と比較しますとかなりスマートな書き方になります。

<pre>
from django.views import generic
from .models import Post

# 記事の一覧表示
class PostListView(LoginRequiredMixin, generic.ListView):
    model = Post
    template_name = 'index.html'
    context_object_name = 'post_list'

    def getqueryset(self):
        posts = Post.objects.all().order_by('-created_at')
        return posts

# 記事の詳細へ移動
class PostDetailView(LoginRequiredMixin, generic.DetailView):
    model = Post
    template_name = 'post_detail.html'

# 記事の表示回数をカウント(主にここを変更)
def add_count(request, pk):
    count = Post.objects.get(pk=pk) # カウントを加算する記事を取得
    count.views += 1 # 記事が持つviews要素を1増やす
    count.save() # 保存

    return redirect('post_detail', pk=count.pk)
</pre>

　ご覧の通り、以前の記事よりもカウント処理をする関数の行数が少なくなりました。データベースのカウントを増やした後で記事詳細画面へと移動するロジックについては前回の記事と変わっていません。

# 3.urls.py
　こちらも一応掲載しておきますが以前と変わらずです。
<pre>
from django.urls import path

from . import views

urlpatterns = [
    path('', views.PostListView.as_view(), name='index'),
    path('post_detail/', views.PostDetailView().as_view(), name='post_detail'),
    path('add_count/', views.add_count, name='add_count'),
]
</pre>

　あとはテンプレートとなるHTMLファイルですが、前回の記事と変更はありません。ですので、HTMLファイルについてですが、変更点はほぼありません。強いて言うなら{{ items.number_of_views }}と記述していた箇所を{{ items.views }}と書き換える程度です。ですので、<a href="https://qiita.com/hexanitrobenzen/items/a90bc2f3a06df01f9458">こちら</a>のテンプレートをご参照いただき、該当箇所を上記のように書き換えていただければと思います。

　今回の記事は以上になります。以前よりかはコードが短くなっていますので多少はコーディング時間の短縮になるかと思います。参考になりましたら是非ともご活用いただければ幸いです。
Graphql-Rubyでクエリの戻り値をユーザの権限によって制限する

アプリケーションにおいてユーザの権限管理は頭を悩ませる問題ですよね。
当然、`Graphql-Ruby`でも権限管理は出てきます。（結構方法がいっぱいあるので、いつかまとめたい）
今回は、ユーザの権限ごとに戻り値の`ObjectType`に取得できるデータ範囲を制限する方法を説明します。

# 作るもの
記事作成サービスを考えます。
ユーザには**一般ユーザ**と**管理者ユーザ**の2つの役割が存在するとしましょう。
一般ユーザが取得できる記事は公開済みの記事のみで、管理者は全記事を取得できます。ログインユーザによる取得制限を`scope_items`メソッドを`objectType`に定義することで実現してみようと思います。

# scope_itemsを使わない場合
まず記事のオブジェクトを`Article`として、`ObjectType`は以下のようにかけます。

```article_type.rb
module ObjectTypes
  class ArticleType < ObjectTypes::BaseObject

    field :title, String, null: false  #記事タイトル
    field :content, String, null: false  #内容
    field :published, Boolean, null: false #公開済みか?
  end
end
```
さて、上記のように`ObjectType`を定義すると、記事一覧等を取得したい場合、常に一般ユーザか管理者ユーザかを`query field`内で条件分岐させる必要が生じます。

```article.rb
def resolve
  if current_user.admin?
    ::Article.all
  else
    ::Article.published # 公開済みのも
  end
end
```
　articleのクエリだけなら良いですが、`article`を扱う全てのqueryで書くのは面倒ですよね。

# scope_itemsでObjectTypeを制限する
上記の問題のために`scope_items`メソッドが`ObjectType`に用意されています。
では早速、`ObjectType`に`scope_items`を追加してみます。

```article_type.rb
module ObjectTypes
  class ArticleType < ObjectTypes::BaseObject

    field :title, String, null: false  #記事タイトル
    field :content, String, null: false  #内容
    field :published, Boolean, null: false #公開済みか?

    def self.scope_items(items, context)
      context[:current_user].admin? ? items : items.published
    end
  end
end
```
これだけです。簡単ですね。`items`は`article`オブジェクトの`ActiveRecordRelation`が入っています。
`scope_items`メソッドは`Article Object`が呼ばれるたびに実行され、実行ユーザごとに取得できるデータを制限することができます。以降は、実行ユーザを気にすることなく、articleを取得できます！


`scope_items`メソッドは非常に便利ですが、個人的には権限管理というドメインに関わるロジックが`ObjectType`に記述されているのが少し気になるところです。
Azure CLIのcompletionを有効にする

## completionファイルをダウンロードする
```console
% mkdir -p ~/.zsh/completions  # 場所は任意
% cd !$
% curl -sLO 'https://raw.githubusercontent.com/Azure/azure-cli/dev/az.completion'
```

## .zshrcにcompletionファイルを読み込む設定を追加する
```zsh:.zshrc
autoload -Uz +X bashcompinit && bashcompinit
if [ -f "$HOME/.zsh/completions/az.completion" ]; then
  source $HOME/.zsh/completions/az.completion
fi
```

## SHELLを再読み込み
```console
% exec -l $SHELL
```

## 確認
```console
% az account <TAB>
--help            -h                clear             get-access-token  list              list-locations    lock              management-group  set               show
```

以上