OmniAICreator/Qiita-1.07M huggingface dataset:
リレーショナルデータベース　デッドロックの具体例

DBの勉強を進めると、避けなければならない処理として、デッドロックに出会います。
なんとなく理屈はわかるけど、あまりリアルに感じられない、という人もいるかも知れません。
そんな人の一助となるべく、どんな具体的な処理で発生するのか、まとめてみました。

#デッドロックとは

###デッドロックの定義
二つのトランザクションが，互いに相手の所有するロックが解除されるのを待機して処理が進まなくなる状態のこと。

>基礎から理解するデータベースのしくみ（12）
>https://tech.nikkeibp.co.jp/it/article/COLUMN/20060118/227490/


ここでいうトランザクションとは、DBMSがデータベースにデータを反映させる単位で、一連の処理(レコードの更新等)のまとまりです。データベースの整合性を保つために利用されます。
たとえば、レコードの更新の途中で処理が失敗した場合では、トランザクション単位で処理を取り消すことにより、不完全なデータがデータベースに残ること防ぎます。

>https://qiita.com/zd6ir7/items/6568b6c3efc5d6a13865


###デッドロックが発生するロジック

以下の2つのトランザクションがあるとします。

 - テーブルAとテーブルBを順に操作する、トランザクション(1)
 - テーブルBとテーブルAを順に操作する、トランザクション(2)

この2つのトランザクションが同時期に実行されることを想定します。

 - トランザクション(1)が、テーブルAをロックしテーブルBを更新しようとする。
 - トランザクション(2)が、テーブルBをロックしテーブルAを更新しようとする。

タイミングが同時期であった場合、
トランザクション(1)は、トランザクション(2)によってロックされたテーブルBのロックが解除されるのを待ち、
トランザクション(2)は、トランザクション(1)によってロックされたテーブルAのロックが解除されるのを待ちます。

しかし、ロックはトランザクションが完了するまで解除されないので、ロックが解除されることはなく、それぞれのトランザクションは待ちつづけることになります。

これがデッドロックのロジックです。

>https://cloudear.jp/blog/?p=1335

※デッドロックはいくつかの種類に分類されますが、上記のロジックは「サイクルデッドロック」と呼ばれる、デッドロックの中でも最も典型的なパターンになります。

#具体例1
###ソース
メルカリJPのサーバーサイドエンジニアの@Hiraku氏が以下のブログで紹介されている。
>https://tech.mercari.com/entry/2017/12/18/deadlock

###考察
上記「デッドロックが発生するロジック」に当てはめてみると

 - トランザクション(1)　⇒　出品者(A)・購入者(B)の情報を順に更新する処理(1)
 - トランザクション(2)　⇒　出品者(B)・購入者(A)の情報を順に更新する処理(2)

上記トランザクションは、顧客が異なるだけの同じトランザクション。

操作対象は

 - テーブルA　⇒　顧客Aの出品・購入の情報
 - テーブルB　⇒　顧客Bの出品・購入の情報

具体的なレコードについては言及されていませんが、**(勝手に)想像してみて**、この情報を、取引が発生したときに更新される「出品件数」と「購入件数」をもつ顧客に紐づいたレコードと考えてみます。

トランザクション(1)は、顧客Aのレコードをロックして、出品件数を更新。そのまま顧客Bのレコードにある購入件数を更新するために顧客Bのレコードにアクセスしようしますが、顧客Bのレコードはトランザクション(2)が出品件数を更新するためにロックしているので、ロック解除を待たなければなりません。

一方で、トランザクション(2)は、顧客Bの出品件数を更新したあと、顧客Aの購入件数にアクセスするが、すでにトランザクション(1)が顧客Aのレコードをロックしているので、解除を待っている状態になっています。

デッドロックが発生しますね。


#具体例2
###
>https://tech.nikkeibp.co.jp/it/article/COLUMN/20060118/227490/

###考察
上記「デッドロックが発生するロジック」に当てはめてみると

 - トランザクション(1)　⇒　振込元の口座(A)・振込先の口座(B)の情報を順に更新する振込み処理(1)
 - トランザクション(2)　⇒　振込元の口座(B)・振込先の口座(A)の情報を順に更新する振込み処理(2)

上記トランザクションは、口座が異なるだけの同じトランザクションです。


操作対象は

 - テーブルA　⇒　口座(A)のレコード
 - テーブルB　⇒　口座(B)のレコード

口座(A) から口座(B）への振込み処理(トランザクション(1))が発生すると、まず口座(A)をロックして口座(A)から振込み金額を減算します。そののち口座Bのレコードに振り込み金額を加算するために口座(B）をロックしようとします。しかし、口座(B)はトランザクション(2)が振込み元として先にロックしているので、ロックの解除を待つことになります。
一方でトランザクション(2)は、口座(B)の更新が終わったあと、口座(A)を更新しようとしますが、すでに口座(A)はトランザクション(1)によってロックされているので、トランザクション(1)による口座(A)のロック解除を待つことになります。
互いにロックした口座の解除を待ち続けるのでデッドロックが発生します。


#デッドロックへの対応
デッドロックを回避するための代表的な対策には以下があります。

 - トランザクションを作成する際のルールとして、アクセスするテーブル・レコードの順番を事前に決定しておく。
 - トランザクションを長くせず、テーブル・レコードがロックされる時間を短くする。
 - DBMSによるデッドロックの検知を適切に設定し、解析のために適切なログを取得しておく。

　など

#まとめ
具体的なトランザクションとテーブル・レコードでデッドロックを確認しました。
デッドロックが、よりリアルに発生する不具合、と感じていただけたならば幸いです。
複数のトランザクションが同時実行される環境では、デッドロックは完全に避けることは、今もなお困難ですので。
Django Girls Tutorialを復習する（４）〜Django URL、Djangoビュー〜

注意事項はこちら。
https://qiita.com/K-Kazutaka/items/1a432bda4f723e6757d6
写経用の記事です。





```mysite/urls.py
from django.urls import path, include
from django.contrib import admin

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
]
```

`blog ディレクトリの下に、新しく urls.py という空のファイルを作る`

```blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
    path('', views.post_list, name='post_list'),
]
```

サーバーを走らせると、コンソール上では下記のようなエラーが発生。
AttributeError: module 'blog.views' has no attribute 'post_list'
これは、'post_list' という属性(attribute)がないことを知らせてくれている。


〜Djangoビューへ〜

```blog/views.py
def post_list(request):
    return render(request, 'blog/post_list.html', {})
```
サーバーは動き出すが、TemplateDoesNotExistというエラーがブラウザ上に発生する。
fbset でのフレームバッファのフォーマット情報の読み解き方

linuxでフレームバッファに映像を表示する。

そのためには、データの並びを確認しなければいけない。

Linuxでは__fbset__ というコマンドを使うと、現在のフレームバッファの情報(解像度, 色のフォーマット)が確認できる。

しかし、初見だと色のフォーマットの読み方がわからなかった。

初学者のために備忘録を兼ねて記事を残しておく。


```bash

//フレームバッファの情報の
$ fbset

    mode "1184x624"
        geometry 1184 624 1184 624 32
        timings 0 0 0 0 0 0 0
        rgba 8/16,8/8,8/0,8/24
    endmode
    
```

fbsetを実行すると、上のように現在のフレームバッファの情報が確認でき

解像度は1184x624で
色のフォーマットは rgba 8/16,8/8,8/0,8/24 とあるがわけがわからない。

これは以下のように読むことができる。

```bash

// 読み方
rgba 8/16, 8/8, 8/0, 8/24
-------------------------
 ==> r:8/16 - 8 bit per pix / 16 bit shift
 ==> g:8/8  - 8 bit per pix /  8 bit shift
 ==> b:8/0  - 8 bit per pix /  0 bit shift
 ==> a:8/24 - 8 bit per pix / 24 bit shift
 = (つまり) ARGB - 8-8-8-8 フォーマットということ.
```

## 参考

[fbset(1) — fbset — Debian stretch — Debian Manpages](https://manpages.debian.org/stretch/fbset/fbset.1.en.html)
vendorフォルダ生成できないというエラー解決メモ

> 以下のようなエラーが出て、composer インストールできない場合についての対応方法

```vim
[RuntimeException] /var/www/html/hogeApp/vendor does not exist and could not be created.
```

## 原因
フォルダの書き込み禁止に引っかかって、composerが vendor フォルダを自動生成しようとしたけどできなかった

## 解決
> 使用したいディレクトリに対して、このようなエラーが出現する場合は権限を変更

```vim
$ chmod -R 777
```
> 再度、composer install、updateを流すだけです
DELETEとTRUNCATEの違い

DELETEとTRUNCATEは、データを削除するということは、
同じなので違いを簡単にご説明します。

状況に応じて使い分けるのが大切です。

# ロールバック出来るか？出来ないかの違い
DELETEは、ロールバック出来ます。
TRUNCATEは、ロールバック出来ません。

# ハイウォーターマーク（HWM）の違い
DELETEは、ハイウォーターマークがリセットされません。
TRUNCATEは、リセットされます。

## ハイウォーターマーク(HWM)とは？
パフォーマンスを意識する時以外は、気にしません。
一言でいうと、
テーブルにどれだけデータが入っているの？という目安のマークになります。

え？だから？って思いますがｗ
私も始めて聞いたときに、え？だから？って思いましたｗ

OracleがSQLを実行する時に、テーブルに対して、FULL SCANした場合のパフォーマンスに大きく影響します。

### FULL SCANするとどうなるの？
名前の通り、テーブルの全レコードをSCAN(=チェック)します。

その時に、HWMのマークまでチェックします。

カンの良い方は、あれ？テーブルのデータ件数を元にチェックすればいいじゃん！
って思いませんか？
私も思いました。

ただ、コレがややこしいので、詳しくは割愛していまいますが、HWMのマーク位置を使用します。

で、話を戻すと、DELETEとだとHWMがリセットされません。
そうすると、100件データを削除しても、FULL SCAN上、100件があるだろうな～って思って、検索をします。
ただ、データは無いので抽出はされないのですが、100件分のデータ領域まで検索してしまいます。
あら、不思議。

なので、FULL SCANした場合の検索速度が遅くなります。

# 使い分けのポイント
後続の作業の有無の違いです。

具体的には、

１．バックアップ取得
２．データを削除
３．その後、諸々作業

で、３で失敗した時に、２もリセットしたい場合、等は、「DELETE」一択です！

１．バックアップ取得
２．データを削除

までなら、「TRUNCATE」一択です！

違いを把握して、使い分けてください。
C#のプロジェクトを作る時はテストプロジェクトは分ける

tl;dr
------

C#のテストプロジェクトは分けましょう。当たり前かもしれませんが。


発端
------------

Azure Functionsを使ったC#プロジェクトを書き始めて、軽い動作確認でユニットテストっぽく書きたいと思い、xunitを入れて実行したら90秒待たされた後に以下のエラー。

```
$ dotnet test

Testhost プロセスが次のエラーにより終了しました: A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Users\2011050\Desktop\testcs\bin\Debug\netcoreapp2.1\bin\'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the C:\Users\2011050\Desktop\testcs\bin\Debug\netcoreapp2.1\bin\testhost.runtimeconfig.json file specifying the appropriate framework.
```

原因が全くわからない。

該当のプロジェクトファイルはこんな感じ。

``` xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.29" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
    <PackageReference Include="xunit" Version="2.4.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
  </ItemGroup>

</Project>

```

ライブラリを追加したり削除したりSDK変えたりしていたところ、以下のことが分かった。

- `Microsoft.NET.Sdk.Functions` がいるとダメで、バージョンは`1.0.23`～`1.0.29`の間は全部ダメ（それ以前はnetcoreapp2.1をサポートしてないっぽい？）
- dotnet sdkも2.1.700と2.2.103を試した
- TFMはnetcoreapp2.1,netcoreapp2.2を試した）

なぜ`Microsoft.NET.Sdk.Functions`と`Microsoft.NET.Test.Sdk`が相乗りした時だけタイムアウトしてしまうのかはよくわからない。

が、そもそもテストなんだからプロダクトのコードとテストコードを同じプロジェクトにするのは良くないのでは、と気づく。`Microsoft.NET.Sdk.Functions`に依存しないプロジェクトを起こしてそこからテストすればよい。

というわけで、src,testの2つのプロジェクトに分けた。大本の原因はわからなかったけども。

とりあえずdotnetコマンドでもVSCode上からのメソッド単位実行もできるようになり満足。



無駄知識
---------------

色々調べている過程で無駄知識を得た。

### TFM=Target Framework Moniker

https://docs.microsoft.com/ja-jp/dotnet/standard/frameworks に書いてあった

### IsTestProjectプロパティ

.Net Core SDK 2.1.500以降からは、`<PackageReference Include="Microsoft.NET.Test.Sdk" Version="xxxx" />`があると、テストプロジェクトとして認識する。どういう仕組みかわからないが、このIsTestProjectプロパティをつけるらしい。逆にないと認識しなくなる。

しかしIsTestProjectプロパティ自体はあまり情報がない。いつどこで入ったんだろう。
https://github.com/search?l=&q=IsTestProject+user%3Adotnet+user%3Amicrosoft&type=Code

### `dotnet test -v diag`

パフォーマンス分析用のログがめちゃくちゃ出る。今回は役に立たなかった。

### `VSTEST_CONNECTION_TIMEOUT`環境変数


冒頭で90秒ぐらいでエラーになる所。90秒は長すぎるというときにこの環境変数が使えるかもしれない。
SDK 2.0.3だと動かなかったので、2.1以上じゃないと機能しないかもしれない。今回は役に経たなかった

```
VSTEST_CONNECTION_TIMEOUT=5 dotnet test
```
リポジトリ・yum・rpmについて

# リポジトリとは
- 様々なパッケージを配布してる場所
    - gitのイメージに近い
- リポジトリ自身は、場所を意味するので、実際にそこにあるパッケージをダウンロードしたり、使用するには、別の操作が必要
- リポジトリは世界中にたくさん存在する
    - 後述するrpmもまたリポジトリ
    - 他には、EPELやCentOSなど

# yumとは
- Yellowdog Updater Modifiedの略
- RedHat系ディストリビューションのパッケージ管理システム
    - Debian系ディストリビュージョンのパッケージ管理システムでは、**apt-get** が使用される
- リポジトリからパッケージをダウンロードし、インストールやアンインストールなどの操作をする事ができる
- パッケージの自動更新や依存性の解決機能を兼ね備えてる
- yumでも後述するrpmを間接的に扱ってる

# rpmとは
- rpm形式のパッケージを管理する
- パッケージ個々を指す
- 依存関係のあるパッケージを自動でインストールしない

# コマンド

## パッケージのアップデート

- yumの場合
    - 依存関係の解決も行う

```terminal
$ yum update
```

- rpmの場合
    - 依存関係の解決は行わない
    - 指定したパッケージ単体をアップデートする

```terminal
$ rpm -Uvh パッケージ名
```
## パッケージのインストール

- yumの場合
    - 依存関係の解決も行う
    - 必要であれば、他のパッケージのインストールも行う

```terminal
$ yum install パッケージ名
```

- rpmの場合
    - 依存関係の解決は行わない
    - 指定したパッケージ単体をインストールする

```terminal
$ rpm -ivh パッケージ名
```

## パッケージの検索

- yumの場合
    - 指定されたキーワードをリポジトリから検索し、結果を返す
    - 関連するパッケージも表示する

```terminal
$ yum search キーワード
```

- rpmの場合
    - rpmパッケージのものを検索する

```terminal
$ rpm -qa キーワード
```

## パッケージの削除

- yumの場合

```terminal
$ yum remove パッケージ名
```

- rpmの場合

```terminal
$rpm -e パッケージ名
```

# 参考
- [yumリポジトリ追加リスト 完全版](https://qiita.com/bezeklik/items/9766003c19f9664602fe)
- [Linuxのパッケージ管理についての用語を理解する](http://kayakuguri.github.io/blog/2015/12/18/linux-package/)
- [初心者の頃に知っておきたかった rpm と yum の違いと使い分け](https://blog.inouetakuya.info/entry/20111006/1317900802)
- [外部レポジトリとは](https://zudoh.com/linux/about-yum-and-repository)
- [【初心者にもわかる】rpmとyumの違いと使い分け一通り](https://eng-entrance.com/linux-package-rpm-yum-def)
Java  オブジェクトのListをソートする

#Comparatorを使い、Collections.sort()でソートする
- Comparatorを使うことで、自分で定義したクラスオブジェクトの特定の値でソートすることができる。

```java:
//List<Person> fooというリストを、xフィールドでソート
Collections.sort(
                  foo,
                  new Comparator<Person>() {
                    @Override
                    public int compare(Person obj1, Person obj2){
                      return obj2.getX - obj1.getX;
                       }
                    }
                  );
```

#Comparator.comparingを使う
- Comparator.comparingを使うとすっきりと書ける

```java:
foo.sort(Comparator.comparing(Person::getX));
```
Django Girls Tutorialを復習する（３）〜ログインページを作ろう〜

注意事項はこちら。
https://qiita.com/K-Kazutaka/items/1a432bda4f723e6757d6
写経用の記事です。


```blog/admin.py
from django.contrib import admin
from .models import Post

admin.site.register(Post)
```


Webサーバーで確認する
`〜$ python manage.py runserver`
ブラウザに行って http://127.0.0.1:8000/admin/ とアドレスバーにタイプします。

ログインするには、superuser （サイトの全てを管理するユーザー）を作る必要があります。 コマンドラインに戻り、python manage.py createsuperuser と入力し、enter キーを押します。

```command-line
Username: admin
Email address: admin@admin.com
Password:
Password (again):
Superuser created successfully.
```

Django adminについてもっと知りたいときは、Djangoドキュメントを見るべし https://docs.djangoproject.com/ja/2.0/ref/contrib/admin/
CSSだけで作るトグルボタン

#概要
この記事では、CSSだけを使ってトグルボタン(あるいはスイッチ)を作ります。デザインは次の通りです。
![toggle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231330/13d2dc94-6974-7ae8-3c2e-3807778106c1.png)

スイッチ部はチェックボックス、丸ボタンは「::after」と「::before」疑似要素で作成します。~~完成後に調べたらQiitaに同様の投稿が結構あったのですが、がんばって作ったので供養します~~。

#ソースコード
##HTML

```html
<label
	><input type="checkbox" checked
	><span>ON</span
	><span>OFF</span
></label>
```

##CSS

```css
/* ---- 共通部 ---- */
input[type=checkbox] {
	display: none;
}
label>input[type=checkbox]~span {
	display: flex;
	justify-content: space-between;
	align-items: center;
	width: 90px;
	height: 28px;
	font-size: 14px;
	border-style: none;
	border-radius: 15px; // =(丸ボタンのサイズ÷2)+(丸ボタンのmargin)
	box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2);
}

/* ---- スイッチがONのとき ---- */
label>input[type=checkbox]:checked+span {
	display: flex;

	/* ---- ボタンのデザイン ---- */
	padding-left: 8px;
	color: white;
	background-color: dodgerblue;
}
label>input[type=checkbox]:checked+span+span {
	display: none;
}

/* ---- スイッチがOFFのとき ---- */
label>input[type=checkbox]+span {
	display: none;
}
label>input[type=checkbox]+span+span {
	display: flex;

	/* ---- ボタンのデザイン ---- */
	padding-right: 8px;
	color: gray;
	background-color: lightgray;
}

/* ---- 丸ボタンのデザイン ---- */
label>input[type=checkbox]:checked+span::after, label>input[type=checkbox]+span+span::before {
	display: block;
	vertical-align: middle;
	width: 24px;
	height: 24px;
	margin: 3px;
	border-radius: 50%;
	background-color: white;
	box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2);
	content: "";
}
```
【備忘録】git pushに失敗した時の解消法

# はじめに
Androidで新規のプロジェクトを作成した際に、`git push`すると以下エラーで失敗してしまいました。

```kotlin
The requested URL returned error: 403
```
毎回、「これどうやって解決するんだったっけ・・・」と思い出すのが面倒臭かったので、備忘録として自分が行なっている解決方法をここに残すことにしました。（根本的な解決になっているかは微妙ですが・・・）

なので、ここで記載するのは「git pushで生じる**全てのエラー**に対する解消法」ではなく、403エラーについて記載します。

# 現象
上で説明した通りだが、`git push`しようとすると、以下のエラーが発生しました。

```kotlin
Push failed: Failed with error: unable to access 'https://github.com/user_name/repository_name.git/': The requested URL returned error: 403
```

# 解決法
上述のエラーが発生した際に、自分が解決するために行なっていることを記載します。
403エラーを解決する方法は、「gitのremoteのurlにユーザー名を含める」です。
方法としては、以下を入力します。

```kotlin
$ git remote set-url origin https://user_name@github.com/user_name/repository_name.git
```
### **⬇︎⬇︎⬇︎具体例⬇︎⬇︎⬇︎**

|内容|値|
|:--:|:--:|
|ユーザー名|taa-suuuk|
|リポジトリ名|TaaSuuukApp|

gitのユーザー名とリポジトリ名が上の場合は、以下のようにurlを変更すれば解決します。

```kotlin
$ git remote set-url origin https://taa-suuk@github.com/taa-suuuk/TaaSuukApp.git
```

# 終わりに
`git push`する際に403エラーが出た際の解決法でした。
以上、備忘録でした。（拙い文章だとは思いますが、備忘録なのでご容赦ください）
Jupyter notebookがMacbookで動かなかった話

## 背景
AnacondaインストールしてJupyter notebook使おうとしたら、以下のエラーが出て使えなかった。

```
No module named 'prompt_toolkit.clipboard'
```

環境は以下。
MacBook Pro
OS: macOS Mojave (v10.14.5)
Anaconda version: conda 4.6.11


## 解決策
以下のコマンドで直った。

```
$ condas install prompt_toolkit
```
Eclipseの改行やタブを非表示にする

#:point_up:はじめに
Eclipseを使用している際に、改行やタブが邪魔だなーと思ったので非表示にする方法を残します:smile:

#:point_up:方法
1. 画面上部にあるEclipseの「環境設定...」をクリック
2. 一般≫エディター≫テキストエディターで「空白文字を表示」のチェックを外す
3. 「適用して閉じる」クリック
4. `DONE`

#:writing_hand:まとめ
表示されていたほうが見やすい方もいるかと思いますが、非表示にしたい方の参考になれば！！
root権限がない所でrubyを使えるようにする

root権限がない所でrbenvを使ってrubyをインストールしようとしたら、以下の事象が発生した。

```
...
The Ruby openssl extension was not compiled.
The Ruby readline extension was not compiled.
The Ruby zlib extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `yum install -y openssl-devel readline-devel zlib-devel` to fetch missing dependencies.
...
```

どうやらopenssl, readline, zlibが不足しているらしい。言われた通りにyum installしたいのだが、まぁroot権限がないので。

```sh
TMPDIR=/path/to/tmp/dir
INSTALLDIR=/path/to/install/dir

# readline
cd $TMPDIR
wget http://ftp.gnu.org/gnu/readline/readline-4.3.tar.gz
tar xzvf readline-4.3.tar.gz
cd readline-4.3
./configure --prefix=$INSTALLDIR/readline
make -j 
make install

# openssl
cd $TMPDIR
wget www.openssl.org/source/openssl-1.1.1c.tar.gz
tar xf openssl-1.1.1c.tar.gz
cd openssl-1.1.1c
./config --prefix=$INSTALLDIR/openssl
make -j build_libs
make install_sw

# zlib
cd $TMPDIR
wget http://zlib.net/zlib-1.2.11.tar.gz
tar xzvf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure --prefix=$INSTALLDIR/zlib
make -j
make install
```

さて、全てを入手したが、それをどうやって教えてあげればよいのだろうか。
答えは以下の通り。

```sh
RUBY_CONFIGURE_OPTS='--with-openssl-dir=$INSTALLDIR/openssl --with-zlib-dir=$INSTALLDIR/zlib --with-readline-dir=$INSTALLDIR/readline' rbenv install 2.6.3
```

`--with-HOGE-dir` を使うことで場所を教えることができる。これでインストールでーきた。
LINE Messaging API  を使ってPDFの内容（英語）の翻訳botを作ってみた【備忘録】

# PDFの内容（英語）を翻訳する
　最近、論文を読む事も大事なインプットになると思い始めた。しかし、英語やドイツ語などの母国語以外で書かれている論文はそのまま理解することが難しく、PDF形式だとコピペして検索が出来ない。この問題を解決すべく、PDF形式の論文を翻訳する機能をpythonで実装する事にした。しかし、ただ翻訳するだけでは面白みがないので対話形式で翻訳範囲の指定まで行ってくれるチャットボットをLINEmessagingAPIを使って作成した。
　pythonパッケージのgoogletransを実装してGoogle翻訳に文字列をhttpで渡して文章の翻訳を行う。googletransはGoogle Translate APIを実装した無料で無制限の pythonライブラリである。また、チャットボットからの返信はpythonの扱いやすさによって、返信数と返信内容を自在に組み替える仕様を実現した。スクリーンショットにて以下にチャットボットとのコミュニケーションを公開する。

# 前提事項
**googletrans(pythonライブラリ)について**

* 単一テキストの最大翻訳文字数は1500字まで
* Google翻訳の制限に依存する

**LINEmessagingAPIについて**

* LINEmessagingAPIについて、文字数は基本1通2000文字でテキストは一度に５通まで送れる
* フリープラン契約
* URLのエンドポイントは１箇所のみ 

**その他**

* PDFによっては10000文字を超えるものが存在する
* 翻訳するPDFファイルはローカル環境にダウンロードしたものを使用する



# 翻訳フロー

1. チャットボットにPDFファイルのパスを渡すと全体のページ数に応じて**ページを指定して翻訳する**か、全ページを**一気に翻訳する**かをチャットボットが判断してくれる。

2. ページ指定の場合は**最小(１ページ)ページ数**から**最大ページ数**までをページ番号による指定ができ、指定範囲外のページが指定されたならもう一度ページ範囲の指定を要求してくる。

3. ページの確認を行う。

4. 確認後、PDFと同一のディレクトリに"**translation_yyyymmdd.txt**"の翻訳版のテキストファイルが作成される。
（※論文等の最新の技術を文書にまとめている場合、翻訳しきれない単語が含まれる場合があるのでその場合にコピペをしてネットで調べる対応が取れるようにテキスト形式に保存する事にした。）


#DEMO


* PDFのファイルパスを入力すると頃から始まる

![IMG_1360.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323243/8d1b36ae-9826-045e-5bcc-c6558a6b16c9.png)

* ファイルの作成が完了するとローカルのPDFと同じディレクトリに翻訳済みのテキストファイルが生成される。


# pythonでの処理で苦労した点
* LINEmessagingAPIを使用して返信を分けて送信する際の値（text）の持ち方と処理に対する返信内容の変更
　処理ごとに異なる数のメッセージを送信したかったので、メッセージをlist型の変数に格納してそのリストの長さによって出力するメッセージの数を分岐させる処理をpythonで実装する事で解決した。

* 会話の内容（一つ前の処理）を記憶する方法の策定
　各処理ごとにハッシュ値を与えて前回の会話の結果をハッシュ値で管理する方法を取る事でセッションごとに処理の流れが切れないようにした。こちらはpython のファイルへの書き込みや読み込みが簡単に行えるopen()関数やwith構文のおかげで楽に実装することが出来た。


# 改善点
* 生成された翻訳後の文書の中で、翻訳しきれていない新しい言葉や専門的な言葉に対応できるようにpythonで別の翻訳機 （ニューラル機械翻訳を検討）を作成する。
* 翻訳しないときはbotと会話が楽しめるようにMeCabによる形態素解析とpythonでkerasをインストールする事で使えるseq2seqによって対話を生成（ある対話文章に対する応答を自動的に生成する）し、簡単なコミュニケーションが取れるようにする。
今日の学習

##やったこと
###・Railsチュートリアルでのわからなかった単語の理解、深掘り
###・MVCについてを詳しく

##学んだこと
###・gemとは
→Ruby用のパッケージ管理ツールで、ruby用のライブラリを使うときに必要なソフトウェア。これにより、ruby用のライブラリのインストール、アンインストール、バージョン管理を簡単に実行できる。
gem自体はruby用に付属されていて、誰でも無料で使える。
###・そもそもライブラリとは？
汎用性の高い複数のプログラムを再利用可能な形でひとまとまりにしたもの。
###Restとは
簡単に言えば、webに運用したソフトウェア設計様式のこと。
URLに対してHTTPメソッドである、『GET（取得）、POST（作成）、PATCH（PUT）（更新）、DELETE（削除）』
これを利用することで統一感のある意味が掴み安いURLを設計することができる。
つまり、 http://localhost:3000/test というURLがあったとする これにRESTを適用すると1つのURLに対してHTTPメソッドのGETでアクセスすればデータを取得。POSTでアクセスすればでデータの作成を行えるということ。
###・ジェネレータとは
Railsの開発において雛形になるソースコードを自動生成するためのコマンド。
＜ジェネレータの用途と種類＞
よく使われるのが　scaffold、controller、 model、 migration。
scaffold を使うと、モデル・ビュー・ルーティング・マイグレーション・コントローラーまで、テスト込みで一括でファイルを作成される。　（rails generate scaffold NAME ）
例えば、rails g scaffold User　を実行すると、ルーティングに resources :users が追加され、アプリケーションにおける基本的な機能である一覧(index)、詳細(show)、新規作成(new/create)、編集(edit/update)、削除(destroy) を実現するために必要なファイルが追加される。
＜コントローラーを追加したい場合＞
Rails g controller / Rails g scaffold_controller　の二種類あり、
 Rails における一般的な RESTful コントローラーを定義したい場合は scaffold_controllerを、そうでない場合は controller を使うのが良い。
＜モデルだけを追加したい場合＞
rails g model
＜マイグレーションのみを追加したい場合＞
rails g migration
###マイグレーションとは
→Railsからデータベースのテーブルを管理するためのファイル
###ERBとは
→rubyのコードを埋め込むことができる。（HTMLなど）
###APIとは
アプリケーションプログラミングインターフェースの略。
・サーバーで用意している関数(機能)をhttpで通信して利用する事。
・利用するには決め事を守ってリクエストを出す。
・決まり事とはURLとか渡すデータの名前とかデータの形式とか。
・レスポンスは大体何かしらのデータ。時々画像も。
・データの形式は最近はJSON。一昔前はXMLが主流だった。
・ajax形式で利用される事が多い
###MVC
<ルーティングとコントローラー>
利用者がRailsアプリケーションにリクエストを送信すると、まずwebサーバーでリクエストを受け取る。
リクエストがRailsアプリケーションに関することである場合、webサーバーからRailsアプリケーションに送られる。
利用者のリクエストはURLとして届き、どのコントローラーに含まれるアクションを実行すればいいのか判断する時に使われるのが「routes.rb」ファイル。このファイルにはどんなURLだった時は、どんなアクションをすればいいのが記憶されている。Railsアプリケションは各コントローラーの中に、複数のアクションが定義されている。
<モデル>
リクエストが登録済みのデータが見たかったり、新しいデータを格納して欲しいといったものの場合、データベースとのやり取りが発生する。
ex 例えば、Railsアプリケーションでは、使用しているデータベース毎にテーブルが用意されていて、利用者からリクエストされたアクションは、モデルを介してデータベースとやりとりされ、データの取得、新しいデータを格納したりする、
<ビュー>
モデルの状態を参照し、視覚表現するもの。
取得したデータをビューへ受け渡す役目を担っている。
＃＃＃課題
SQL文のことについて学ぶ。
Rails active recordbaseについて学ぶ。（継承）
Microsoft Flow：文字列を区切ってループ処理

# 仕様
- 1. カンマ区切りの文字列を変数に格納。（変数の初期化により、変数宣言）
- 2. 「split」関数で、カンマ区切り。（戻り値は、配列）
- 3. 「Apply to each」で、上記のカンマ区切りした各値をOneDriveのファイルに書き出す。

![pr1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/1f61b348-37d7-ab0c-01c2-f75421208a33.png)

- 4.書き出すファイル名は、文字列結合の関数「concat」を使用し、以下の形式とする。「f_」は接頭辞。
　
　- 形式：f_[区切り値]　

![pr2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/61dcba46-13df-f58b-8e1d-92cf37476804.png)

# コードの補足

## 変数の参照

変数の参照は、「variables('変数名')」。

```javascript:split
split(variables('test_var'), ',')
```

## 「Apply to each 」の各値の参照

「item()」関数で、ループの各値を参照。

```javascript:concat
concat('f_', item())
```
演算子まとめ　

# はじめに

いつも忘れてしまうので演算子を備忘録としてまとめてみる
自分メモ

### 算術演算子
これはpowershellでなくても使うから忘れはしない...

| 演算子|説明|サンプル|    
|:-----|----|----:|
| +| 加算| 1+2 |
| -| 減算| 3-1 |
| *|乗算| 1*2 |
| / |除算| 3/1 |
| %| 余剰| 3%1 |

### 代入演算子
これはsqlserverでは使わないから、ちょっと忘れる...

|演算子|説明|サンプル|
|:------|--------|------:|
|= | 代入| $x = 1|
|+=| 加算して代入| $x += 1||
|-=| 減算して代入| $x -= 1 |　　　　
|*=| 乗算して代入| $x *= 2 |
|/=| 除算して代入| $x /= 2 |
|%=| 余剰を代入| $x %= 3 |
|++| インクリメント | $x ++ |
|--| デクリメント | $x -- |

###比較演算子
何が忘れるって、これが一番忘れる...

| 演算子  |　説明  | 
|:--|--:|
| -le  | <=   |
| -lt | <| 
| -gt| > | 
| -ge | >= |
| -eq  | = |
| -ne  | <> |
| -like | ワイルドカードと等しい|
| -notlike | ワイルドカードと等しくない|
| -match | 正規表現と等しい |
| -notmatch | 正規表現と等しくない |
| -contains | 含まれている |
| -notcontains | 含まれていない |
FlaskアプリをHerokuにデプロイする

# 開発環境
ホストマシン：Windows10
ゲストマシン：Vagrant上にCentOS7
## Heroku CLIをインストールしてheroku login…のつもりがうまくいかない
Heroku CLIは以前Railsで開発をしていた時に使っていたので今回も使えるはず・・・そう思って

```
heroku login
```
したのですが、

```
bash: heroku: command not found
```
とのこと。なぜなのか…？

とりあえず、Heroku CLIをアンインストールしてもう一度[Heroku CLI公式ページ](https://devcenter.heroku.com/articles/heroku-cli)から _Download and Install_
の_Windows_の64bitを選んで再インストールをしてみますが、やはり

```
bash: heroku: command not found
```
原因がわからないので、別の方法でherokuをできないか模索しました。

## npmを使ってインストールする
[Heroku CLI公式ページ](https://devcenter.heroku.com/articles/heroku-cli)を下のほうまでスクロールしていくとnpmでインストールする方法がありました。

``It’s strongly recommended to use one of the other installation methods if possible.

This installation method does not autoupdate and requires you to use your system’s version of Node.js, which may be older than the version Heroku develops the CLI against. Heroku uses very current releases of Node.js and does not back-support older versions.``

とあり、できるだけほかのインストール方法を選んだほうがいいそうですがとりあえずデプロイしたいだけなので今回は無視します。

```
npm install -g heroku
```
を実行して、

```
heroku --version
```
とすると

```
heroku/7.26.2 linux-x64 node-v10.14.2
```
どうやらインストールはうまくいったようです。

## heroku loginをするがうまくいかない
Herokuのインストールがうまくいったので、次はheroku loginをしてみようと

```
heroku login
```

と打ち込むと

```
heroku: Press any key to open up the browser to login or q to exit:
```
と表示されます。キーを押すとブラウザが開いてログインするという意味なので、エンターキーを押してしばらく待ってみました。
すると

```
Opening browser to https://cli-auth.heroku.com/auth/browser/24359ea7-3616-4f3e-a83b-18fb013ed660
 ›   Warning: Cannot open browser.
heroku: Waiting for login... !
JSONError: Unexpected end of JSON input while parsing near ' '
    at module.exports (~/.nvm/versions/node/v10.14.2/lib/node_modules/heroku/node_modules/parse-json/index.js:26:19)
    at HTTP._parse (~/.nvm/versions/node/v10.14.2/lib/node_modules/heroku/node_modules/@heroku-cli/command/node_modules/http-call/lib/http.js:343:25)

```
JSONError？　なんですかそれ？　ということで調べてみました。
そうしたらちょうど同じエラーに遭遇した人がいました。

[Herokuにログインできないときの対処法](https://tanarizm.com/heroku-cannot-login)
いわく、Opening brwoser to ~ の ~　をブラウザで開いてログインするのをHerokuが待っているとのこと。

ブラウザで開いてみると
![heroku_before_login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226935/ce3e4ce6-1387-a9cc-a9e5-950fb78b249c.png)
画面真ん中のLog inをクリックすると次のような画面が表示されてログイン成功のようです。
![heroku_after_login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226935/8126ee88-bee1-9942-59f5-edca3996f73b.png)
手元のコンソールにもどってみると

```
Logging in... done
```
と表示されました。ログインに成功したようです。

## heroku createからheroku openまで
ここからさきは[こちらの記事](https://qiita.com/satokibi/items/dea6e7a0a655af8fdb91)等を参考にしました。

今回はデータベースは使わないので

``` requirementx.txt
flask
gunicorn
feedparser #feedparaserはRSS取得用のライブラリ、デプロイには関係ないです

```
Procfileは

``` Procfile
web: gunicorn server:app --log-file=- 
```
として

```
heroku create
git push heroku master
```

とすればデプロイ完了です

```
heroku open
```

としてブラウザ上で確かめましょう。
（小ネタ）Javascriptで何も考えずにデカい数字を変数に代入したら1増えてしまった件



~~~ javascript
const majide_big = 9999999999999999;
console.log(majide_big);

//結果
10000000000000000
~~~

なぜこのようなことが起こるのか調べたら追記します。
（整数型の最大値を超えたからだと思うけど）
Xcodeで作成したiOSアプリを実機iPhoneへインストールする

#:point_up:はじめに
Xcodeで作成したiOSアプリを実機iPhoneへインストールする際に、色々設定の変更等が必要であったためメモ感覚で残します:smile:

#:point_up:前提
- Xcode Versionは「Version 10.2.1 (10E1001)」
- Xcodeにて何らかのiOSアプリは作成済み

#:point_up:XcodeにApple IDを登録

1. 画面上部Xcodeの「Preferences...」を開く
2. 「Accounts」タブへ移動し左下の「＋」をクリック
3. 「Select the type of account you would like to add:」が開いたら「Apple ID」を選択して「Continue」をクリック
4. 「Sign in with your Apple ID.」が開いたらApple IDを入力しエンター、引き続きパスワードを入力して「Next」をクリック
※二段階認証を求められた場合は受信した6桁の確認コードを入力して「続ける」をクリック
5. そうすると何もなかった「Accounts」タブにApple IDが登録され「Taem」も作成される

#:point_up:証明書の登録
1. 「Accounts」タブにApple IDが表示されていることの確認ができたら「Manage Certificates...」をクリック
2. 「Sign certificates for "○○":」が開いたら左下の「＋」クリックして「iOS Development」をクリック
3. 証明書が追加されたことを確認できたら「Done」をクリック

#:point_up:iPhoneを接続
1. iPhoneをLightningケーブルでMacに接続
2. そうするとシュミレーターに「iOS Simulators」ではない実機のiPhoneが選択できるようになるので選択する

#:point_up:iPhoneへiOSアプリをインストールする
1. 作成してあるアプリを選択すると、「General」や「Capabilities」などのタブが表示される
2. 「General」タブを選択し「Signing」にある「Team」を「None」から作成したTeamに変更する
3. シュミレーター実行の三角マーク（command + R）をクリック
※パスワードを求められたらMacのパスワードを入力する

#:point_up:iPhoneでインストールしたiOSアプリを起動
1. iPhone上にインストールしたiOSアプリがあること確認したら、起動させる
※起動した際に、「信用されていないデベロッパ」と表示された場合、iPhoneの設定≫一般≫プロファイルとデバイス管理≫「デベロッパAPP」のApple ID≫「"○○を信頼"」≫「信頼」という操作を実施後に起動
2. `iPhone上で作成したiOSアプリが表示される`

#:writing_hand:まとめ
簡単な操作ですが、設定の変更が必要だったりするので少し面倒です。
ご参考になれば幸いです！
起動中のVBSのプロセスIDを知る方法


##経緯
うっかり無限ループさせてプロセス終了させる時に複数走ってて困ったので

##やり方
以下のコマンドをコマンドプロンプトから実行する
もっと簡単な方法ありそう

```.bat
wmic process where "name like '%wscript%'" get processid,commandline
```
120GBのSSDを512GBのSSDに換装した際に、ケーブル接続とUEFIでハマった点

本日午後に時間を取って、自宅デスクトップPCでOSインストール用に用いていた内蔵SSDを、Intel 320 Series 120GBからWD BLUE 500GBに換装しました。OSインストールディスク用としても、さすがに120GBでは不足するようになってきたのです。残り容量を示すバーが赤色になるというのは只事ではないです。

Web上の情報を元に、Acronis True Image WD Edition等を駆使し、SSD間でのOS移行手順は問題なく終了できました。しかしながら、換装中にハマった点が2点ありましたので報告いたします。

## SATA内蔵ストレージには、SATAケーブルだけでなく、SATA電源ケーブルも接続する必要がある

換装後のSSDを最初にSATAケーブルでマザーボードに接続して起動したとき、「OSが入っているストレージがない」という趣旨の警告が出てしまい、大変焦りました。「UEFIの起動ストレージ検索順が変わってしまったのではないか」などとも考えました。しかしながら、最終的に判明した理由は、「換装後のSSDに、SATA電源ケーブルを接続していなかった」というものでした。USBと違って、SATAケーブルには電源供給機能はないのですよね。PCの内蔵デバイスに最近手を触れていなかったゆえの盲点です。

## 少なくともWindows PCにおいては、Bluetoothキーボードでは、BIOS/UEFIの設定画面に入ることができない

Windows OSにおいては、PCがBluetoothデバイスを認識するのはOSの起動後です。しかしながら、BIOS/UEFIの設定画面に入るためには、OSが起動する前にキーボード操作をしなければなりません。起動プロセスからいって当然の成り行きなのですが、結果として「**Bluetoothキーボードでは、BIOS/UEFIの設定画面に入ることができない**」をも意味するのですよね。デスクトップPCで普段Bluetoothキーボードを使われている諸氏におかれましては、いざBIOS/UEFIの設定画面に入ることになった際に困らぬよう、小さくてもいいので有線接続のキーボードを一つ常備しておくことをおすすめいたします。
cmake から meson へのビルドシステム移行のメモ

cmake の次と名高い meson https://mesonbuild.com/ へビルドシステムを移行するメモです.

## 前提条件

* cmake に精通している

## meson の特徴

python で拡張ができる(cmake スクリプトに悩まずに済む!)

Ubuntu などでは apt で入ります.

Windows では meson, ninja と libpython も含んだパッケージが用意されていますので,  既存 python 環境と切り分けてスタンドアローンで meson を動作させる環境を構築することができます. 

## 設定例

だいたいは https://mesonbuild.com/ を見ればわかりそうですが, single page ではないので機能確認がやりづらいですね.

How do I do X in Meson?
https://mesonbuild.com/howtox.html

### Address sanitizer を使いたい.

meson では標準で対応しています.

```
meson build -Db_sanitize=address
```

などとします. 環境によっては `-Db_lundef=false` も設定するとより確実かもしれません(Ubuntu では b_lundef を false にしないと warning が出ました)

### C/C++ コンパイラを指定したい.

```
CXX=clang++-8 meson build
```

という風にして CXX でコンパイラを指定して bootstrap します.

### `meson.build` を変えたので再構築したい

一応 `ninja` で変更があったら再構築してくれますが,

```
meson --reconfigure build
```

でもいけます.

### C++ のバージョンを指定したい.

```
project('myproj', 'c', 'cpp',
        default_options : ['c_std=c11', 'cpp_std=c++11'])
```

CMake では `set(CMAKE_CXX_STANDARD 11)` とかで指定でした.


### ninja ではなく make を使いたい.

T.B.D.

### コンパイラごとに CXX flag を変えたい

```
if meson.get_compiler('c').get_id() == 'clang'
  extra_args = ['-fclang-flag']
else
  extra_args = []
endif

executable(..., c_args : extra_args)
```

と `meson.get_compiler('c').get_id()` で判断します.

### ファイルごとに cxxflags 設定を変えたい

T.B.W.

cmake でいう `set_source_files_properties`.

### クロスコンパイルしたい

T.B.W.
console.log(this);を使う意味

JavaScriptのデバッグの１つにconsole.log();というものがある。これは、()(引数括弧)の中に変数などを記載することで、その中に代入されている値を確認することができるものである。

console.log(this);のように、()(引数括弧)の中にthisを書くとどのようなことができるのか？
thisを使う意味としては、同じ構造をした複数のHTML要素でも、その中に変数が含まれている時に、その変数内に代入されている具体的数値や代入値をコンソール上において確認するために用いられる。
例えば、チャットアプリなどのグループ編集において、どのメンバーを追加するのかという追加入力のページにおいて、個々のページのHTML構造は全て同じだが、その要素の中のuser.idという変数の中身は何が代入されているか分からない。そのため、console.log(this);を用いて、実際に入力された具体値を確認する。
Xcode11で作成したプロジェクトを古いOSに対応させる(完結編)

以前、投稿した記事の続編です。
[Xcode11で作成したプロジェクトを古いOSに対応させる(とりあえず版)] (https://qiita.com/Hackenbacker/items/86e73f34b377ca415838)
↑の対応をしておいてください。

UniversalアプリでiPhone用とiPad用でViewControllerを使い分けたいなど、
アプリ起動後に表示するViewControllerを自前で設定したい場合があります。

1. 起動時にUIWindowを生成
2. rootViewControllerをセット
3. makeKeyAndVisible()する

iOS12までは```application(_:didFinishLaunchingWithOptions:)```で上記パターンのコードを書けばよかったのですが、iOS13では真っ黒な画面しか出てきません。:cold_sweat:

そこで、以下の対策を行いました。iOS13ではDark Modeも対応します。

1. UIWindowの生成は各OSに応じて行う
　　iOS12:　```AppDelegate``` 
　　iOS13:　```SceneDelegate```

2. 生成したUIWindowの設定を行うクラスメソッドを作成

#AppDelegateでUIWindow生成 (iOS12以前用)
```Swift:AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    if #available(iOS 13.0, *) {
        // do nothing
    } else {
        window = UIWindow()
        AppDelegate.setupWindow(window!)
    }

    return true
}
```

#SceneDelegateでUIWindow生成 (iOS13 onward用)
```Swift:SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }

    window = UIWindow(windowScene: windowScene)
    AppDelegate.setupWindow(window!)
}
```

# UIWindowを設定するクラスメソッドを追加
```Swift:AppDelegate.swift
/// Sets up the window.
///
/// - Parameter window: Window that become key window with the root view controller.
class func setupWindow(_ window: UIWindow) {

    // position and size
    window.frame = UIScreen.main.bounds
        
    // root viewcontroller
    let viewController: UIViewController
    if UIDevice.current.userInterfaceIdiom == .phone {
        viewController = iPhoneViewController()
    } else {
        viewController = iPadViewController()
    }
    window.rootViewController = viewController

    // backgorund
    if #available(iOS 13.0, *) {
        window.backgroundColor = .systemBackground
    } else {
        window.backgroundColor = .white
    }

    window.makeKeyAndVisible()
}
```
---
Xcode 11 beta3を元に作成しています。後日変更される可能性があります。
オフラインどう書く第4回参考問題の解

問題はこちら->https://qiita.com/Nabetani/items/9c514267214d3917edf2
だいぶ前に解いていたのの入出力を修正しました。力技です。
5x5の交点を数字で表し、道を隣の交点間からなる有向線分に分割してリストに入れ、
通行止めの区域を有向線分に変換してリストから削除し、
残りの線分を入口から出口まで、search/3で終点=始点のしりとりのようにつないでゆきます。
assert/1を使って足し算だけすればメモリ使用量は減りそうですが、
あまり使いたくありませんので、findall/3を使いました。
ideoneでは時間内に全問は解けません。

```Prolog
%swi-Prolog  version 7.4.2
%start.

closed([[]],[]):-!.
closed([],[]):-!.
closed([Lh|Lt],L):-closed(Lt,L1),[F,T]=Lh,append([(F,T),(T,F)],L1,L).

closerout(_,_):-! .
closerout(Input,Street,RL):-
     atom_string(Input1,Input),concat_atom(Out,' ',Input1),
     maplist(atom_codes,Out,List),closed(List,Close),subtract(Street,Close,Street1),
     findall(Res,search(Street1,[97],Res),RL).

search(_,[121|Rout],[121|Rout]):-!.
search(Street,Rout,Res):-
     Rout=[Point|_],member((Point,NTo),Street),not(member(NTo,Rout)),
     subtract(Street,[(Point,NTo),(NTo,Point)],Street1),Rout1=[NTo|Rout],
     search(Street1,Rout1,Res).
           
start:-data(L),numlist(97,121,Stre),
     findall((A,B),(select(A,Stre,Stre1),select(B,Stre1,_),
     N is A-B,((abs(N,1),(A>B->C=A;C=B),N1 is (C-97) mod 5,N1=\=0);
     abs(N,5))),Street),go(L,Street).

go([],_):-!.
go([I->N|T],Street):-
     closerout(I,Street,RL),length(RL,R),
     (N==R->write("pass ");write("fail ")),writeln(R),go(T,Street).

data(["" -> 8512,
"af" -> 4256,
"xy" -> 4256,
"pq qr rs st di in ns sx" -> 184,
"af pq qr rs st di in ns sx" -> 92,
"bg ch di ij no st" -> 185,
"bc af ch di no kp mr ns ot pu rs" -> 16,
"ab af" -> 0,
"ty xy" -> 0,
"bg ch ej gh lm lq mr ot rs sx" -> 11,
"ty ch hi mn kp mr rs sx" -> 18,
"xy ch hi mn kp mr rs sx" -> 32,
"ch hi mn kp mr rs sx" -> 50,
"ab cd uv wx" -> 621,
"gh mn st lq qr" -> 685,
"fg gl lm mr rs" -> 171]).
```
【jQuery】 クリックボタンを2回目以降も押せるようにする方法

# はじめに
jQueryを使って文字列を画面上に反映させたいが、
ボタンを1度クリックすると2回目以降がクリックできなくなってしまうという問題。

# 解決法
これを、ボタンが押されて書いた文字列が送信されたのちのアクションの中に記述する。

<img width="558" alt="d16300b06f5534e0b27951ae3b5a4318.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379858/fd24655e-9111-1f7e-7381-3cef7b0f92ba.png">

[disabled]というのがボタンを押された時に動いてしまいこれによって、クリックボタンが2回目以降押せなくなってしまっていたのが原因のようです。
デフォルトでついている機能なのでこれを[false]を使い無効になるように記述すればokになります！



全体図（参考までに…）
ここでは非同期通信でメッセージを送信するという記述の一部です。
<a href="https://gyazo.com/84854cf0cb6da2b28447393c3e3376f7"><img src="https://i.gyazo.com/84854cf0cb6da2b28447393c3e3376f7.png" alt="Image from Gyazo" width="901"/></a>
ソフトウェアテストについて少し知らべてみた！！！

#はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしています。
みなさん、ソフトウェアテストって知っていますか？
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください！


#ソフトウェアテストとは？
ソフトウェアテストは使用に乗っていない予想外な動作をしないか・セキュリティの問題を抱えていないを確認するための作業です。
テスト方法は大きく2つに分けられます。

##ホワイトボックステスト
ホワイトボックスの特徴はテスト対象のソースコードをすべて参照できることです。
そのため、網羅率が最も高い方法と言えます。
欠点は大規模ソフトウェアの場合は手作業でするのが困難になってしまうことです。

##ブラックボックステスト
ブラックボックステストの特徴は入力と出力しかわからない状態でテストをする点です。
そのため、数多くの入力を行い、正常な出力をしているかを常に監視して行います。
欠点はテストを止める時期の判断が難しいことです。

#まとめ
ソフトウェアテストにも興味が出てきたので、今後も勉強していこうと思います！
Vagrant で仮想環境を作る時につまずいたところ

#0.はじめに
Webサーバーを立てたいと思ったのですが、LinuxのPCを持っていなかったので、仮想環境でやろうと思いました。ですが、Vagrant　upで止まってしまい……
その時に取った対応のまとめです。
環境:windows10/Lenovo LEGION

#1.なぜかSSH auth method: private keyで止まる
vagrantとvirtualboxをインストールし、initまではできました。
ですが、肝心のVagrant　upをするとSSH auth method: private keyでストップ。そのままTime outしてしまいます。ここで詰まる問題は結構多いらしくて、しかも原因も様々なんですよね…

#2.仮想化機能が有効になっていない
結論から言ってしまうと、私の場合これでした。PC自体のBIOS設定で仮想化機能がenableになっておらず、このせいで何をやっても仮想環境が作れない状態に。
この設定の替え方はPCによって違います。ちなみにそのなかでもまた、シリーズなどで違いが出てくるので注意が必要です。
PCによっては動かなくなる可能性もあるようなので、自己責任でお願いします。

#3.その他試したこと
このほかにも原因はあるようで以下の記事も参考にさせてもらいました。
[Windows7にVagrantを導入 - 失敗した事](https://qiita.com/rrryutaro/items/260f0f4bd0b1e550b6da)

[仮想化支援機構(VT-x/AMD-V)を有効化できません Vagrant upでOS起動失敗した](https://futurismo.biz/archives/1647)
MNCTF2019 建屋制御Ⅱ

#問題

http://mnctf.info/mnctf2019/tasks.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/72877711-3194-ee1f-e71b-57e4e4489aa5.png)

#解いてみた

さっきの問題の続きです。
さっきの問題もよくわからずたまたま当たっただけなのでこれも数字の羅列をうまくみつけるしかないか。。。
と思ったら「2019/07/02 11:06(UTC)時点の温度」と書いているので少なくともその時間のパケットがあるということでしょう！
かなり絞れるはず！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d5860952-03a4-48ef-2a54-0d9e637159c6.png)

結構ありますね。まぁそれでもかなり絞れたのは確かです。
1F室温モニタのパケットをどうにか見つけ出せればいいんですけど。
さっきの問題でロケーション名から1F工場というのは予想できそうなので、それを調べたところIPアドレスが10.0.0.101と10.0.0.102の2つだということがわかった。
※詳しく書くと一つ前の問題の答えになってしまうのでこの程度の解説にとどめておきます

あとはこのパケットから数字の羅列（温度なので0～40程度で小数点以下が5桁以上ある）を探す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/cdaabe51-3033-f72b-2f6e-06792848835c.png)

いい感じの数字が見つかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5c1fe339-a526-d5be-bd23-10ddebbf1742.png)

内容は全く分からなかったので不完全燃焼ですが。。。
TravisCIでRuby 1.9.3のインストールが失敗するときの対処法

# 現象
TravisCIでRuby 1.9.3のテストを行うとインストールで失敗します。
TravisCIのJob logに以下のメッセージが表示されます。

```
$ rvm use 1.9.3 --install --binary --fuzzy
curl: (22) The requested URL returned error: 404 Not Found
Required ruby-1.9.3 is not installed - installing.
curl: (22) The requested URL returned error: 404 Not Found
Searching for binary rubies, this might take some time.
Requested binary installation but no rubies are available to download, consider skipping --binary flag.
Gemset '' does not exist, 'rvm ruby-1.9.3 do rvm gemset create ' first, or append '--create'.
The command "rvm use 1.9.3 --install --binary --fuzzy" failed and exited with 2 during .
Your build has been stopped.
```

このときのビルド環境は以下の通りです。
job logの`Build system information`を展開すると表示されます。

```
Build system information
Build language: ruby
Build group: stable
Build dist: xenial
Build id: 554948482
Job id: 554948483
Runtime kernel version: 4.15.0-1028-gcp
travis-build version: 7b7f39e22
Build image provisioning date and time
Mon Mar 25 16:43:24 UTC 2019
Operating System Details
Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.6 LTS
Release:	16.04
Codename:	xenial
```

# 原因

19年4月以降、TravisCIのビルド環境のデフォルトがUbuntu 16.04となりました。
[参考：Ubuntu Xenial 16.04 as the default Travis CI build environment](https://blog.travis-ci.com/2019-04-15-xenial-default-build-environment)
ところが、Ubuntu16.04にはRuby 1.9.3がありません。
[参考：Travis CI: Precompiled Ruby Versions](http://rubies.travis-ci.org/)
そのため、上記のようにインストールに失敗しました。

# 対処策

`.travis.yml`でUbuntu 14.04を使用するように明示します。

```.travis.yml
dist: trusty  # work at Ubuntu 14.04 for install Ruby 1.9.3
```

明示するとUbuntu14.04の環境でビルドが実行されます。

```
Build system information
Build language: ruby
Build group: stable
Build dist: trusty
Build id: 554950523
Job id: 554950524
Runtime kernel version: 4.4.0-101-generic
travis-build version: 7b7f39e22
Build image provisioning date and time
Tue Dec  5 19:58:13 UTC 2017
Operating System Details
Distributor ID:	Ubuntu
Description:	Ubuntu 14.04.5 LTS
Release:	14.04
Codename:	trusty
```

ruby 1.9.3のインストールが成功します。

```
$ rvm use 1.9.3 --install --binary --fuzzy
curl: (22) The requested URL returned error: 404 Not Found
Required ruby-1.9.3-p551 is not installed - installing.
curl: (22) The requested URL returned error: 404 Not Found
Searching for binary rubies, this might take some time.
Found remote file https://rvm_io.global.ssl.fastly.net/binaries/ubuntu/14.04/x86_64/ruby-1.9.3-p551.tar.bz2
Checking requirements for ubuntu.
Requirements installation successful.
(snip)
Using /home/travis/.rvm/gems/ruby-1.9.3-p551
```

# その他
Ubuntu 14.04とRuby1.9.3のサポートは終了しているのでテスト対象から外す方法もありますが
事情により今回はRuby 1.9.3でビルドする環境を整えてみました。
数理最適化で全国小中学生プログラミング大会グランプリ作品を解く

# これなに
「[Pythonとグラフ理論で全国小中学生プログラミング大会グランプリ作品を解く - Qiita](https://qiita.com/mascii/items/f0e82f9bd8397763c573)」を数理最適化で解いてみました。

数理最適化については、「[組合せ最適化を使おう](https://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)」を参照ください。

# Pythonのコード

各頂点の次数を入力とします。
各辺が存在するかどうかを変数とすれば、次数が一致する制約条件を作ればOKです。

```py
import pandas as pd
from pulp import LpProblem, lpSum
from ortoolpy import addbinvars, addvals

# 次数のデータ
data = [[int(c) for c in s] for s in """\
12232
23333
33333
24442
13331""".splitlines()]

nr, nc = len(data), len(data[0])
# 変数表（df）の作成（Horionは水平かどうか）
df = pd.DataFrame([(False, i, j) for i in range(nr - 1) for j in range(nc)] +
                  [(True, i, j) for i in range(nr) for j in range(nc - 1)],
                  columns=['Horion', 'Row', 'Col'])
addbinvars(df)  # 変数追加
m = LpProblem()  # 数理モデル（目的関数なし）
for i in range(nr):
    for j in range(nc):
        # (i, j)の次数を一致させる制約条件
        m += lpSum(df[(df.Horion & (df.Row == i) & (df.Col.isin((j - 1, j)))) |
                      (~df.Horion & (df.Row.isin((i - 1, i))) & (df.Col == j))].Var) == data[i][j]
m.solve()  # 解を求める
addvals(df)  # 結果追加
# 得られた辺の集合
st = set(df[df.Val > 0.5].set_index(['Horion', 'Row', 'Col']).index)
# 結果の表示
for i in range(nr):
    for j in range(nc - 1):
        print(' --' if (True, i, j) in st else '   ', end='')
    print()
    if i < nr - 1:
        for j in range(nc):
            print('|' if (False, i, j) in st else ' ', end='  ')
        print()
```

出力結果

```
 --    -- --
   |  |  |  |  
 --    -- --
|  |  |     |  
 --    -- --
|  |  |  |  |  
 -- -- -- --
   |  |  |     
 -- -- -- --
```

元の結果と異なりますが、次数が一致しているのが確認できます。

以上
Linuxディストリビューションについて調査メモ

# Linuxディストリビューションとは？

- アプリケーションなどをパッケージにして、すぐ使用できる状態にしたものディストリビュージョンと呼ぶ。
    - 本来、ディストリビュージョンは、**流通**　や　**分配**　を意味する
- Linuxディストリビュージョンは、つまり、Linuxを利用するに当たって、アプリケーションなどパッケージ化して、すぐ使用できる状態にしたものたちを指す
    - Linux単体では、**Linuxカーネル**　を意味する
    - 核部分のみ存在しても利用する事はできないため、様々なアプリケーションが存在する

## Linuxディストリビューションのトレンド
- Linuxディストリビューションには様々なものがある
- 代表どころ
    - Red Hat Enterprise Linux (RHEL)
        - アメリカのRedHat社が開発
        - 主に、大規模システムのサーバーに利用されてる
    - Fedora
        - RedHat社が支援するFedora Projectによって開発
    - Debian
        - 世界中の有志の結集によって作り上げられた
            - スタートは、イアン・マードックという一人の人物によって開発された（当時、大学生）
    - CentOS
        - RHELのクローン
            - RHELの商用部分を取り除いたディストリビュージョン
    - Ubuntu
        - Canonical UK Ltd.のUbuntuプロジェクトによって開発
            - Debianをベースとなってる

- トレンド
![スクリーンショット 2019-07-06 17.24.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267738/9c7048be-2e92-5707-b4a5-d3c5b9abe6f8.png)

掲載元：https://w3techs.com/technologies/history_details/os-linux

- この表を見ると、現在のトレンドは、**Ubuntu**
    - 1年近くUbuntuがトレンド1位を走ってる状況

## Linuxディストリビュージョンを確認する

- **/etc**　配下のファイルを確認する

```terminal
$ cat /etc/redhat-release
CentOS release 6.10 (Final)
```

- Fedoraの場合や、Debianの場合も同様に　**/etc**　配下のファイルを確認する事で、Linuxディストリビュージョンを確認することができる
- あるいは、　**/etc/issue**　を確認する事で、Linuxディストリビュージョンを確認することができる

## 参考
- [【目的別】初心者におすすめのLinuxディストリビューション7選](https://eng-entrance.com/linux_beginner_distribution)
- [Historical trends in the usage of Linux subcategories for websites](https://w3techs.com/technologies/history_details/os-linux)
- [Linuxディストリビューションとは？](https://www.linuxacademy.ne.jp/lablog/infrastructure/266/)
- [【3分理解】Linuxディストリビューションの確認方法](https://eng-entrance.com/linux-distribution-check)
- [【3分でわかるシリーズ】CentOSとは？](https://eng-entrance.com/what-is-centos)
- [なれる! Debian開発者 〜 45分でわかる? メンテナ入門](https://www.slideshare.net/henrich_d/debian-45)
- [Debian 出典: フリー百科事典『ウィキペディア（Wikipedia）』](https://ja.wikipedia.org/wiki/Debian)
- [Ubuntu 出典: フリー百科事典『ウィキペディア（Wikipedia）』](https://ja.wikipedia.org/wiki/Ubuntu)
- [カノニカル 出典: フリー百科事典『ウィキペディア（Wikipedia）』](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%8E%E3%83%8B%E3%82%AB%E3%83%AB)
MacにAnacondaをインストールしてJupyterを動かす（python環境変数の変更が必要な場合）

自分がインストールした手順をメモに残しておきます。
ご自由にお使いください。
* MacOSの場合に使えるインストール手順です。
* 間違ってる箇所お知らせ下さい。修正します
* 黒い背景はすべてターミナルでコマンドを叩くイメージです。

### 以下手順
1. Anacondaパッケージをダウンロードする
Anaconda のダウンロードページを開き、Anaconda のインストーラをダウンロードします。
`https://www.anaconda.com/distribution/#macos`
*WindowsOS ,LinuxOS をお使いの方は、Anacondaダウンロードページのタブを該当のOSに合わせてダウンロードしてください。

2. インストーラーからAnacondaをインストールする
Anacondaダウンロード後、インストーラーをダブルクリックしてインストールを行って下さい
基本的には続ける、インストールと順にクリックしていきます。`インストールの場所`を変更したい場合はここで変更します。最後に`閉じる`をクリックして完了です。

3. 呼び出すpythonがMacOSのデフォルトに設定されている場合、環境変数を変更する
MacOSはデフォルトでpython2.7がインストールされている場合があります。
私はpython2.7がデフォルトで設定されており`anaconda`が呼べない状態でした。。
そこで、呼び出すpythonを変更する手順も記載しておきます。
*下記がインストールされていることが前提です。(雑ですいません。。)
 - `python3`
 - `homebrew`
 - `pyenv`

python3がインストールされているか確認

```
# python3がインストールされているか確認
$ python3 --version
Python 3.7.3
```
`.bash_profile`を作成して環境変数の設定を行う。

```
# .bash_profileを作成して環境変数の設定を行う。
$ cd ~

# touchで.bash_profileを作成する（ls -aで確認し、すでにある場合は省略）
$ touch .bash_profile
$ ls -a
.bash_profile
```
viコマンドを使用し`.bash_profile`に環境変数を追記する

```
# viコマンドを使用し.bash_profileに環境変数を追記する
$ vi .bash_profile

# .bash_profileに以下を追記する
export PATH="$HOME/.pyenv/shims:$PATH"
```
設定ファイルを反映する

```
# 設定ファイルを反映する
$ source ~/.bash_profile 
```
デフォルトのpythonバージョンを調べる

```
# 設定ファイルを反映する
$ python --version 
Python 3.7.3
```
以上で設定は完了です。
4. 後は作業したいフォルダに移動し、`jupyter notebook`とターミナル上で叩けばjupyterが開くようになります。
* もし自動でjupyterが開かない場合は、`jupyter notebook`とターミナルに入れると、`http://localhost:8888/?***********`と表示されます。
このURLをコピーし、ブラウザで検索してみてください。
ボイスコッド正規系と第三正規系の違い


勉強していて何が違うのかがわからなかったのでまとめる．



## 定義

>  ボイスコッド正規系：
>
>  リレーション R 上の全ての自明でない FD　X → A について，X が R の超キーである場合 



## 結論

情報無損失分解を実現するためにボイスコッド正規系の制約を緩めたものが第三正規系

付与する条件は関係従属の非決定項がキー属性であるという条件 (X　→　A　でAがキー属性)



## 経緯

ボイスコッド正規系のみでは問題が生じた．



例を挙げる．

三つの属性A,B，Cが存在するスキーマを考える．

関係従属性は｛A　→　B｝，｛B,C　→　A｝が成り立っている．



今主キーの設定をB,Cに設定する．

となるとA　→　Bの関係従属がボイスコッド正規系の制約を満たさなくなるので　A,B　と　B,C　の二つテーブルに分解する．

そうするともともと存在していた｛B,C　→　A｝の関係従属性が消滅してしまう．



その問題を解決するために正規系の条件を緩め非決定項にキー属性が入っていれば許可する条件を追加する．



そうするとA，B，CのスキーマでもA　→　BはBがキー属性なのでスキーマを分解せずとも第三正規系の条件を満たしている．このため情報を損失することなく正規系にすることができた．



以上の経緯がありボイスコッド正規系から第三正規系が派生する形で誕生した．







## 参考資料

[データベース設計 関数従属性, BCNF, 3NF 講師： 福田 剛志](http://www.fukudat.com/w/ja/images/e/ed/Basic-4-fd.pdf)
pandasのto_datetimeが遅い！（formatの指定がとても有効！）

## 問題
* Courseraの"How to Win a Data Science Competition: Learn from Top Kagglers"というコースのWeek1の課題をやっていたところ、pandasのto_datetimeを使う場面に遭遇。
* 正直、必ずto_datetimeを使わないといけないというわけではなかったが、使ったことなかったので果敢にチャレンジした笑
* ところが、データのサイズが2,935,849と巨大で、なかなか処理が終わらない！ってなりました。
* こんな感じのデータです。この'date'のカラムに対してto_datetimeを適用したい！

|  | date | date_block_num | shop_id | item_id | item_price | item_cnt_day |
|--:|:--|--:|--:|--:|--:|--:|
| 0 | 02.01.2013 | 0 | 59 | 22154 | 999.00 | 1.0 |
| 1 | 03.01.2013 | 0 | 25 | 2552 | 899.00 | 1.0 |
| 2 | 05.01.2013 | 0 | 25 | 2552 | 899.00 | -1.0 |
| 3 | 06.01.2013 | 0 | 25 | 2554 | 1709.05 | 1.0 |
| 4 | 15.01.2013 | 0 | 25 | 2555 | 1099.00 | 1.0 |
* とりあえずこんな感じにやってみたわけです。

```python
t['date_'] = pd.to_datetime(t['date'])
```

## 原因、と思われるもの及び解決法
* [to_datetime is too slow on large dataset](https://www.kaggle.com/kuldeepnpatel/to-datetime-is-too-slow-on-large-dataset)によると、どうもparseの過程でものすごく時間がかかっている模様。

>In this instance, pandas falls back to dateutil.parser.parse for parsing the strings when no format string is supplied (more flexible, but also slower).

* to_datetimeの引数にformatを指定するか、infer_datetime_format=Trueを指定してやるとparseが早くなる様子。

[pandas.to_datetime](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_datetime.html)によれば、

> infer_datetime_format : boolean, default False
　　　If True and no format is given, attempt to infer the format of the datetime strings, and if it can be inferred, switch to a faster method of parsing them. In some cases this can increase the parsing speed by ~5-10x.

> format : string, default None
　　　strftime to parse time, eg “%d/%m/%Y”, note that “%f” will parse all the way up to nanoseconds.

## 結果
* 2,935,849のデータはさすがに大きいため、初めの50,000件のデータについて試してみたところ以下のような結果に。

|引数なし|infer_datetime_format=True|format='%d.%m.%Y'|
|--:|--:|--:|
|13.87|13.85|0.25|

* format指定するのが爆速という結果に！！
* 今回の'%d.%m.%Y'という型に対してはうまくinferできなかったようで、infer_datetime_formatをTrueにしてもいい結果は得られませんでした。
* なお、2,935,849件全てのデータについてもformatを指定してやると、14.57秒で全てを処理してくれました！優秀！
既約ユニタリ表現について

###更新履歴
-2019年7月6日：初版

ある論文中に出てきた**既約ユニタリ表現**という単語の解説に挑む．
詳しい人がいたらご指摘願いたい．

#群の表現
これは[Wikipedia](https://ja.wikipedia.org/wiki/%E7%BE%A4%E3%81%AE%E8%A1%A8%E7%8F%BE "Wikipedia")からのパクりである．
群$G$の各元$g$に対して線型空間$V$上の線形変換$T(g)$が対応し，

```math
T(gh)=T(g)T(h)
```
が成立するとき，$g$を$T(g)$に対応させる写像$T:G\rightarrow GL(V)$を群$G$の線型空間$V$上の表現といい，線型空間$V$を群$G$の表現空間という．すなわち群$G$の表現とは**「群$G$から線型空間$V$上の正則な一般線形群への準同型写像」**のことである．

###表現行列
群$G$に対応して表列の集合

```math
\Gamma=\{T(g)\mid g\in G\}
```
があり，任意の群の元$g,h$に対して$T(gh)=T(g)T(h)$が成り立つとき，これらの行列を群$G$の表現行列という．

###同値な表現
群$G$の二つの表現$(T_1,V)$と$(T_2,W)$が与えられたとき，ある線形同型$S:V\rightarrow W$が存在して，すべての元$g$に対して相似変換

```math
ST_1(g)S^{-1}=T_2(g)
```
で繋がるならば，表現$T_1$と$T_2$は同型であるという．

#既約表現
これも[Wikipedia](https://ja.wikipedia.org/wiki/%E6%97%A2%E7%B4%84%E8%A1%A8%E7%8F%BE "Wikipedia")からの抜粋．
表現が**可約である**とは，その表現の任意の行列を対角化する相似行列$P$による相似変換

```math
D(a)\mapsto P^{-1}D(a)P
```
によって表現の各行列が同じパターンの対角ブロックに写されることを言う．表現行列が$k$個の行列の直和

```math
D(a)=
\left(\begin{array}{cccc}
D^{(1)}(a) & 0 & \cdots & 0\\
0 & D^{(2)}(a) & \cdots & 0\\
\vdots & \vdots & \ddots & \vdots\\
0 & 0 & \cdots & D^{(k)}(a)
\end{array}\right)=
D^{(1)}(a)\oplus D^{(2)}(a)\oplus\cdots\oplus D^{(k)}(a)
```
に分解できないとき，その表現は**既約である**という．

#ユニタリ表現
これも[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%8B%E3%82%BF%E3%83%AA%E8%A1%A8%E7%8F%BE "Wikipedia")から．
群$G$のユニタリ表現とは，複素ヒルベルト空間$V$上の線形表現$\pi$であり，$\pi(g)$が任意の$g\in G$に対してユニタリ作用素となるものである．

###ユニタリ作用素
ヒルベルト空間$H$上の有界線形作用素$U:H\rightarrow H$がユニタリ作用素であるとは，

```math
\begin{align}
&・U\text{は全射}\\
&・\langle U_x,U_y \rangle _H=\langle x,y\rangle _H
\end{align}
```
を満足するときに言う．

#具体例
ユークリッド平面$\boldsymbol{R}^2$とガウス平面$\boldsymbol{Z}^2$上での回転操作$R=${$\frac{\pi}{2},\pi,\frac{3\pi}{2},{2\pi}$}を考える．
$\boldsymbol{R}^2$では，

```math
\{
\left(\begin{array}{cc}0 & -1\\1 & 0\end{array}\right),\ 
\left(\begin{array}{cc}-1 & 0\\0 & -1\end{array}\right),\ 
\left(\begin{array}{cc}0 & 1\\-1 & 0\end{array}\right),\ 
\left(\begin{array}{cc}1 & 0\\0 & 1\end{array}\right)
\}
```
$\boldsymbol{Z}^2$では，

```math
\{i,\ -1,\ -i,\ 1\}
```

それぞれの表現行列は

```math
\boldsymbol{R}^2:\left(\begin{array}{cc}\cos{r}&-\sin{r}\\\sin{r}&\cos{r}\end{array}\right)\\
\boldsymbol{Z}^2:\cos{r}+i\sin{r}
```
ただし，$r\in R$である．
これらはいずれも行列式もしくは絶対値が$1$の要素を掛ける操作なので，ユニタリ作用素である．

#まとめ
結局Wikipediaをまとめただけだった