OmniAICreator/Qiita-1.07M huggingface dataset:
応用数学 第一章 線形代数【ラビットチャレンジ】

# 概要
本記事は「JDLA E資格」の取得に必要なJDLA認定プログラムのひとつであるラビットチャレンジの受講レポートとして投稿したものです。

E資格について
https://www.jdla.org/certificate/engineer/

# 目次
[ベクトルとスカラー](#ベクトルとスカラー)
[行列とは](#行列とは)
[行列の積](#行列の積)
[単位行列と逆行列](#単位行列と逆行列)
[行列式](#行列式)
[固有値と固有ベクトル](#固有値と固有ベクトル)
[固有値分解](#固有値分解)
[特異値分解](#特異値分解)

# ベクトルとスカラー
### ベクトル
「向き」と「大きさ」を持つ量のこと。
有向線分（矢印）で表されることが多いが、
有向線分が「位置」と「向き」と「大きさ」で決まるのに対して
ベクトルは「向き」と「大きさ」だけで決まる（位置は問題にしない）。

### スカラー
いわゆる普通の数。「大きさ」のみで「向き」を持たない。
ベクトルに対して「向き」を持たない数字というような意味で使われることが多い言葉。
ベクトルの係数になれる、演算可能であるなどの特徴を持つ。

# 行列とは
以下のように、いくつかの数を長方形状に並べて括弧で囲んだもの。
横の並びを行、縦の並びを列といい、行列内の各数字を成分という。
ベクトルの変換に使えたり、連立方程式を解くのに使えたりする。

```math
\begin{pmatrix}
3 & 2 & 0 \\
0 & 2 & 0 \\
0 & 0 & 1 \\
\end{pmatrix}
```

# 行列の積
以下のように、左側の行と右側の列をかけて足すようにして計算する。
普通の数と違ってかける順番が変わると結果も変わる（同じ場合もある）。
行列に割り算はない。

```math
\begin{pmatrix}
a & b \\
c & d \\
\end{pmatrix}
\times
\begin{pmatrix}
p & q \\
r & s \\
\end{pmatrix}
=
\begin{pmatrix}
ap+br & aq+bs \\
cp+dr & cq+ds
\end{pmatrix}
```

# 単位行列と逆行列
### 単位行列
以下のようにn次の正方行列（n×nの正方形状の行列）において、
右下がりの対角線上の成分がすべて1で、他がすべて0の行列のこと。
普通の数でいうと1のような性質を持つ（何をかけても結果が変わらない等）。
大文字アルファベットの I や E で表す。

```math
I =
\begin{pmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1 \\
\end{pmatrix}
```

### 逆行列
普通の数において、ある数にかけて1になる数をその数の逆数というが、
ある正方行列Aにかけると単位行列になる行列をAの逆行列という。
-1乗の部分は「インバース」と読む（行列Aの逆行列$A^{-1}$ならAインバース）。

```math
AA^{-1}=A^{-1}A=I
```

# 行列式
ある正方行列が逆行列を持つかどうかを判別するための行列式（determinant）というものがあり、
以下のように行列の括弧の部分を｜にして表す。
行列式は行列そのものではなく数（スカラー）である。
2次の正方行列では以下のように計算できる。この値が0である行列は逆行列をもたない。

```math
\begin{vmatrix}
a & b \\
c & d
\end{vmatrix}
= ad-bc
```


# 固有値と固有ベクトル
ある正方行列Aに対して、以下のような式が成り立つような特殊なベクトル$\vec{x}(\neq\vec{0})$と、右辺の係数λ（ラムダ）がある。
このときλを固有値、$\vec{x}$を固有ベクトルという。

```math
A\vec{x}=λ\vec{x}
```

# 固有値分解
ある正方行列Aに対して、固有値λを右下がりの対角線上に並べた正方行列Λ（ラムダ）と、固有ベクトルを並べた行列Vを利用して、行列Aを以下のように変形することを固有値分解という。

```math
A=VΛV^{-1}
```

# 特異値分解
正方行列以外の行列で固有値分解のようなことができる。

```math
M\vec{v}=σ\vec{u} \\
M^{T}\vec{u}=σ\vec{v} \\\\
```

上記のような特殊な単位ベクトルがあるならば特異値分解できる。

```math
M=USV^{-1}
```
【AWS SOA】ELB Pre-Warmingの備忘録

#はじめに
AWS SOAの勉強の中でELB Pre-Warming機能を学習したので、本稿で簡単に備忘録として残していきたい。

#Pre-Warmingとは
通常ELBのスケールには時間がかかるが、急激なアクセス増加が見込まれる場合に、事前にELB Pre-Warming(暖気運転申請)を行うことでELBのスケールに対応できる。

#申請の仕方
コンソール画面上部にサポートボタンがあるので、そこでサポートセンターを選択する。
![スクリーンショット 2020-11-03 16.00.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/25944394-259f-8a7e-3b47-6d0b1df8d35c.png)

![スクリーンショット 2020-11-03 16.04.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/874c25e3-5ec2-3e0a-d2fc-333fd9bb77c8.png)
ここでテクニカルサポートを選択して必要な項目を入れるのだが、ベーシックサポートプランでは技術サポートを行なっていないため、Pre-Warningの申請ができなかったが、サポートプランをアップグレードするとできるようだ。
![スクリーンショット 2020-11-03 16.05.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/f42973a4-29d5-1cf8-a25c-f5353927cfcd.png)

https://support.serverworks.co.jp/hc/ja/articles/115002356313-ELB%E5%88%A9%E7%94%A8%E7%92%B0%E5%A2%83%E3%81%A7%E6%80%A5%E6%BF%80%E3%81%AA%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%A2%97%E5%8A%A0%E3%81%8C%E8%A6%8B%E8%BE%BC%E3%81%BE%E3%82%8C%E3%82%8B%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8C-%E4%BA%8B%E5%89%8D%E3%81%AB%E4%BD%95%E3%81%8B%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B-

https://dev.classmethod.jp/articles/elastic-load-balancing-pre-warming/
Gitの取り消し(add, commit)

## 直前のgit commitの取り消し

ワーキングツリーの変更は残す場合

```
git reset --soft HEAD^
```

ワーキングツリーの変更も取り消す場合

```
git reset --hard HEAD^
```


`zsh: no matches found: HEAD^` とエラーが出た場合は下記のコマンドで取り消せます。

```
git reset --soft HEAD\^
```

initial commitの取り消し

```
$ git update-ref -d HEAD
```

[zsh: no matches found: HEAD^と出たときの解決策](zsh: no matches found: HEAD^と出たときの解決策)

## 直前のgit add の取り消し

```
git reset HEAD
```
HTML/CSS:パラグラフに対して段を作る

#【概要】

<b>1.[結論](#1結論)</b>

<b>2.[実際にどのように行うか](#2実際にどのように行うか)</b>

<b>3.[開発環境](#3開発環境)</b>



#1.結論
<b>`text-indent:`+`margin-left`</b>を使用する！

#2.どのようにコーディング

```html
<span class="subtitle">【開発環境】</span></br>
 <span class="back-indent2">・HTML/CSS/Javascript/Ruby/RubyonRails</span>
```

```css
.back-indent2{
  text-indent: -1em;
  margin-left: 1em;
}
```

・`text-indent`で１行目のインデント幅を調整します。
`<ul>`,`<li>`タグと併用してクラスの名前をつければ改行しても`<li>`毎にきれいに段落を作れます。
・今回は親要素に対して位置を調整したいので`em`を使用しました。htmlに対して配置したければ`rem`で構いません。


下記の図のように段を作れます。
![スクリーンショット 2020-11-03 15.50.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686400/48ba8212-b638-faeb-b890-c17c46623654.png)
※色や影等のCSS記述は省いています。


#3.開発環境
HTML5
CSS3
数学関数 ― J 言語入門

J では、階乗や三角関数など、いくつかの関数が verb として実装されています。そのうちの一部を、ここで紹介します [^1]。

# 床関数・天井関数

床関数 (floor) は `<.`、天井関数 (ceiling) は `>.` (どちらも monad) です。

```j
   <.1.2
1
   <._1.2
_2
   >.1.2
2
   >._1.2
_1
```

# max・min

`<.` と `>.` を dyad として使うと、引数のうち小さい方 / 大きい方を返します。

```j
   1 <. 2   NB. min
1
   1 >. 2   NB. max
2
```

`/` と組み合わせると、リストの中で最小 / 最大の値を求められます。

```j
   <./ 2 5 0 _2 1
_2
```

# 最大公約数・最小公倍数

`+.` (dyad) は最大公約数 (GCD) を、`*.` (dyad) は最小公倍数 (LCM) を求めます。

```j
   12 +. 16
4
   12 *. 16
48
```

引数が boolean (0 / 1) の場合は、`+.` は論理和 (or)、`*.` は論理積 (and) を表します。

```j
   0 +. 1
1
   0 *. 1
0
```

# 階乗

`!` (monad) は階乗を計算します。自然数以外も引数にとることができます (ガンマ関数を用いて計算されるため)。

```j
   !5       NB. 5!
120
```

`!` (dyad) は、組合せの総数を求める計算です。

```j
   3 ! 5    NB. C(5, 3)
10
```

# 指数関数・対数関数

x の y 乗 (指数) を計算するには、`^` (dyad) を使います。

```j
   2 ^ 3
8
```

一方で、対数は、`^.` (dyad) で求められます。

```j
   2 ^. 8   NB. log(2, 8)
3
```

`^` も `^.` も、monad として使った場合、底を e (ネイピア数) として計算されます。

# 三角関数

`o.` は、三角関数などの計算に使われます [^2]。

```j
   NB. 1r3p1 は 1/3 * π^1 = π/3 (60°)
   1 o. 1r3p1     NB. sin(π/3)
0.866025
   2 o. 1r3p1     NB. cos(π/3)
0.5
   3 o. 1r3p1     NB. tan(π/3)
1.73205
```

左の引数で、関数を指定します。(例えば、1 は sin、2 は cos を表します。) なんと 25 種類 [^3] の関数を使うことができるのですが、多すぎるので割愛します。

# 複素数

`j.` は、実数から複素数を作る verb です。

```j
   j. 2
0j2
   1 j. _1
1j_1
   _1 j. 2 * 3
_1j6
```

複素数から実部・虚部を取り出す機能もあります。

```j
   +.2j3       NB. 実部・虚部のリスト
2 3
   9 o. 2j3    NB. 実部
2
   11 o. 2j3   NB. 虚部
3
```

複素数の計算は基本的に実数と同じ verb を使いますが、1 つだけ注意が必要です。`+` (monad) は、引数が complex のとき**共役複素数**を返します。

```j
   +2j3
2j_3
```

# 素数

`p:` (monad) を使うと、n 番目の素数を求めることができます。

```j
   p:3      NB. 3 番目の素数
7
   p:i.10   NB. 最初の 10 個の素数
2 3 5 7 11 13 17 19 23 29
```

`q:` (monad) は、素因数分解を行います。

```j
   q:120
2 2 2 3 5
```

---

\[ 前 : [様々な数値](https://qiita.com/unsigned-wrong-wrong-int/items/96ed987360617667c29b) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [ユニコード文字列](https://qiita.com/unsigned-wrong-wrong-int/items/399759d08f536811aeaa) \]

[^1]: もちろん、覚えなくていいです。使う機会があるのは ほんの一部だと思います。
[^2]: 三角関数や円に関係のある 雑多な機能が詰め込まれています。
[^3]: _12 から 12 までの整数で指定します。
spring initializrでdatabaseで一覧表示されたもの調べてみた

**JDBC API SQL**
>Database Connectivity API that defines how a client may connect and query a database.

**Flyway Migration SQL**
>Version control for your database so you can migrate from any version (incl. an empty database) to the latest version of the schema.

**Apache Derby Database SQL**
>An open source relational database implemented entirely in Java.

→テーブルのバージョン管理に使う

**H2 Database SQL**
>Provides a fast in-memory database that supports JDBC API and R2DBC access, with a small (2mb) footprint. Supports embedded and server modes as well as a browser based console application.

→インメモリのdb。非常に高速

**HyperSQL Database SQL**
>Lightweight 100% Java SQL Database Engine.

**PostgreSQL Driver SQL**
>A JDBC and R2DBC driver that allows Java programs to connect to a PostgreSQL database using standard,
10S database independent Java code.

**Spring Data R2DBC**
>Provides Reactive Relational Database Connectivity to persist data in SQL stores using Spring Data in
reactive applications.

**Liquibase Migration SQL**
>Liquibase database migration and source control library.

**JOOQ Access Layer SQL**
>Generate Java code from your database and build type safe SQL queries through a fluent API.

**MS SQL Server Driver**
>A JDBC and R2DBC driver that provides access to Microsoft SQL Server and Azure SQL Database from any Java application.

**Spring Data for Apache Cassandra NOSQL**
>A free and open-source, distributed, NOSQL database management system that offers high-scalability and high-performance.

**Spring Data Reactive for Apache Cassandra NOSQL**
>Access Cassandra NOSQL Database in a reactive fashion.

**Spring Data Couchbase NOSQL NOSQL**
>document-oriented database that offers in memory-first architecture, geo-distributed deployments, and workload isolation.

**Spring Data Reactive Couchbase NOSQL**
>Access Couchbase NOSQL database in a reactive fashion with Spring Data Couchbase.

**Spring Data Neo4j NOSQL**
>An open source NOSQL database that stores data structured as graphs consisting of nodes, connected by relationships.

**Graphite OBSERVABILITY**
>Hierarchical metrics systems backed by a fixed-size database.

**Prometheus OBSERVABILITY**
>An in-memory dimensional time series database with a simple built-in UI, a custom query language, and math operations.

**Testcontainers TESTING**
>Provide lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.

**Embedded MongoDB Database TESTING**
>Provides a platform neutral way for running MongoDB in unit tests.

**AWS RDS AMAZON WEB SERVICES**
>Relational databases on AWS with RDS and Spring Cloud AWS JDBC.

##他

**MySQL Driver SQL**
> MySQL JDBC and R2DBC driver.

MySQLと接続するために必要なJDBCドライバー

参考にしたページ
---

[spring initializr](https://start.spring.io/)
Seeeduino XIAO でポートが見えなくなってしまった時は


[リセットダブルクリックで復活](https://wiki.seeedstudio.com/jp/Seeeduino-XIAO/#_6)
![reset](https://files.seeedstudio.com/wiki/Seeeduino-XIAO/img/XIAO-reset.gif)

・・・もうここにボタン付けちゃおうかなって思うくらいよく起こりません？
Firebase: PRを上げるだけで、レビュー環境を作成する方法 - ローカル

# Firebase: PRを上げるだけで、レビュー環境を作成する方法 - ローカル

記事はこちらに移行しました。
https://zenn.dev/articles/d4a9f6e3cd4d08f1cf8c/edit
ServiceNow - Scripted REST APIの作成

#概要
ServiceNowテーブルAPIを利用すると簡単にテーブルのデータを取得したり更新することが可能。しかし、次のような制限があります：

- 参照フィールドの場合はsys_idを指定する必要がある
- 1回の呼び出しでテーブル1つからデータしか取得できない
- API毎にセキュリティ（ACL）を設定できない

例えばテーブルAPIでは指定したインシデント番号のチケットに添付したファイルをダウンロードするには数回の呼び出しが必要になります。一回の呼び出しでファイルをダウンロードすり場合はScripted REST APIを作成します。
今回はよりScripted REST APIの基本を学ぶために指定したメールアドレスのユーザ情報を返すスクリプトを作成します。

##Scripted REST API
アプリケーションナビゲータから「Scripted REST API」を開き、次のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/fdd4a47d-9a15-f78b-4090-46191619324d.png)

「Resources」タブの「New」ボタンを押下して実行するスクリプトを記述します。今回はURIのメールアドレスを指定するようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/452accc8-a5d2-e036-3462-b3045993be14.png)

URLのパラメータとして指定できるようにする場合は前頁の「Query Parameters」をパラメータを作成します。

###Scripted REST APIリソーススクリプト
リソースのスクリプトにすべてのコードを記述することもできますが、保守性を考えてテーブル検索スクリプトをスクリプトインクルードに記述して、Scripted REST APIリソースではそのスクリプトを呼び出すようにします。

```
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
	return new getUserDetails().getdetails(request.pathParams.userid);
})(request, response);
```

###スクリプトインクルード
多くの場合はクライアントから呼び出されますが、今回はサーバ側での呼び出しになるので「Client callable」のチェックは外します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/d3c780fd-799c-7829-e86f-aab4329b0dc6.png)

```
var getUserDetails = Class.create();
getUserDetails.prototype = {
    initialize: function() {},

    getdetails: function(email) {
        var userInfo = [];
        try {
            var grUser = new GlideRecord('sys_user');
            if (grUser.get('email', email)) {
                userInfo.push({
                    'name': grUser.name,
                    'email': grUser.email,
                    'company': grUser.company.name
                });
            }
            return userInfo;
        } catch (e) {
            gs.error("ERROR=", e);
        }
    },

    type: 'getUserDetails'
};
```
##実行
REST API Explorerから実行すると次のようにJSONメッセージが戻ります。

```
{
  "result": [
    {
      "name": "Lucius Bagnoli",
      "email": "lucius.bagnoli@example.com",
      "company": "ACME Japan"
    }
  ]
}
```
よさげなline botを作るための自分用メモ

#linebotを作りたい
けどセンスがない！
もともとあるツールをフル活用しつつうまく作っていこうメモ。

#備忘録
・Line messaging APIドキュメント：コーディングするときはこれを見ろ
　https://developers.line.biz/en/docs/messaging-api/message-types/#imagemap-messages

・Rich menuを作るときの便利なQiita：
　https://qiita.com/bowtin/items/32ac5d2b4c67bd0c1dc2

・Rich menuを作るときの入り口：
　https://manager.line.biz/account

・Line botからTwitterへ投稿するお作法Qiita：
　https://qiita.com/bm0521/items/39ae81e2ba01c9d3e0bd

・Twitterへ投稿する下書きを作るとき："https://twitter.com/intent/tweet"
　⇒?text=とか?hashtagsをつけると投稿内に埋め込める
　※日本語を入れたいときはエンコードの必要があるので
　①chromeの検索窓で日本語で入れる　ex)https://twitter.com/intent/tweet?text=あいうえおかきくけこ
　②Enterで動作確認
　③検索窓からメモ帳などへコピペ、エンコードされたものがペーストされる
　④嬉しい！

#さいごに
　メモの癖大事
CentOS8.2に秘密鍵・公開鍵を作成してVSCodeでSSH接続する

##はじめに
今までAWSのサーバーにSSH接続していましたが、ローカル開発環境でCentOSを動かしたところ、鍵の作成だったり色々必要なのでメモしました。

##環境
サーバー側　CentOS8.2
クライアント側　Windows10
（SSHクライアントソフト　VSCode）

##前提
・VSCodeにRemote-SSHがインストールされていること
　参考：[VSCode の Remote - SSH 機能を使って EC2 上で開発する](https://blog.serverworks.co.jp/tech/2020/02/20/vscode-remote-ssh/)
・サーバーにtarがインストールされていること
　※SSH接続の際に、アーカイブを展開する必要があるようです。インストールはyum install -y tarでできます。
・SSHサーバーのルートログインが許可されていること
　※推奨されませんが、今回はテストのためrootでログインしています。

##大きな流れ
①サーバー側で秘密鍵・公開鍵を作成
②秘密鍵をクライアント側にアップロード
③VSCodeでサーバーにSSH接続

##①サーバー側で秘密鍵・公開鍵を作成
秘密鍵・公開鍵の作成は仕組み的にはサーバー側、クライアント側「どちらで実行しても良い」そうですが、クライアント側で作成した公開鍵をサーバー側に転送するほうが一般的のようです。今回は、Linuxでの鍵作成をしたかったのでサーバー側（CentOS）で作成します。


```bash:秘密鍵・公開鍵を作成
# ssh-keygen -t RSA -b 4096
Generating public/private RSA key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): 
Enter same passphrase again:
```

`ssh-keygen`は秘密鍵と公開鍵を作成するコマンドです。
書式　`ssh-keygen -t 暗号方式 -b ビット数`
オプション　`-t`　暗号方式を指定
　　　　　　`-b`　ビット数を指定

-fオプションで作成場所を指定していない場合、/root/.ssh/id_rsaに保存してよいか聞かれるのでENTERを押します。
秘密鍵に設定するパスフレーズの入力を求められます、なしでいいのでそのままEnterを押します。


```bash:作成完了
# ssh-keygen -t RSA -b 4096
Your identification has been saved in /root/.ssh/id_rsa.  
Your public key has been saved in /root/.ssh/id_rsa.pub.  
The key fingerprint is:  
SHA256:7YG9R04q702Nje8GSOEH7kdrgrsgrsgLYbTqNTbWvU root@localhost.localdomain  
The key's randomart image is:  
+---[RSA 4096]----+  
|                 |  
|  .+ .. . o      |  
| .+.=..+ o o     |  
|.. o++. o++ .    |  
|.  ooo. SE+oo    |  
| o .+o   .oB.=   |  
|  +o.   . + *.o  |  
|   .o    o + ..  |  
|  .. .   .o .oo  |  
+----[SHA256]-----+
```

```bash:~/.ssh/に鍵が作成されていることを確認
# ls -al ~/.ssh/
-rw-------. 1 root root 3389 11月  3 01:08 id_rsa 
-rw-r--r--. 1 root root  752 11月  3 01:08 id_rsa.pub
```

※.pubと末尾に記載されている方が公開鍵です。（publicの略）

公開鍵のファイル名をauthorized_keysに修正します。

```bash:公開鍵のファイル名をauthorized_keysに修正
# mv id_rsa.pub authorized_keys
```
これで公開鍵と秘密鍵の生成は完了です。
次に秘密鍵をクライアント側に移動させます。

##②秘密鍵をクライアント側にアップロード
scpコマンドを使ってもよいのですが、今回はTeratermの機能を利用してクライアント側に移動させました。
File→SSH_SCP
Fromに`/root/.ssh/id_rsa`
Toに任意のWindowsフォルダ
　参考：[Teratermでコマンドを使わず簡単にファイル転送する方法](https://glodia.jp/blog/9669/)

##④VSCodeでサーバーにSSH接続
VSCodeの左ペインにモニターのようなアイコンがあるのでクリック
リモートエクスプローラーが開くのでSSH TARGETSの右側の+を押下
コマンド入力画面が開くので、以下を入力
`ssh -l root -i "Windowsフォルダ内の秘密鍵のパス" SSHサーバーのホスト名もしくはIPアドレス`
Enterを押すと接続完了です。

`SSH`はsshプロトコルを用いて別ホストに接続するコマンドです。
書式　`ssh オプション ホスト名`
オプション　`-l`　ユーザーを指定
　　　　　　`-i`　秘密鍵を指定
言語別基本チートシート(Ruby, PHP)

#Ruby

| 1 | 2 |
|:-:|:-:|
| 文字の呼び出し  | putもしくはp,print  |
| 一行コメントアウト  | #シャープでコメントアウト  |
| 複数行コメントアウト  | #=bigin #=end  |
|   |   |
|   |   |
|   |   |
|   |   |
|   |   |
|   |   |

#PHP
ローカルで開発する場合は、MAMPかXAMPPのDL必須。
最後に;を忘れずに！

| 1 | 2 |
|:-:|:-:|
| 文字の呼び出し  | echo "呼び出したい文字列"  |
| 一行コメントアウト  | //スラッシュ2本  |
| 複数行コメントアウト | /* スラッシュ+コメ */  |
| 埋め込み  |  <?php ?> |
|  変数名 |  $variables_name1 |
| 埋め込み時の改行 |  echo "文字列< br >" (※brとカッコの間に空白は不要)|
| echoで呼び出した文字列の中に変数・定数を埋め込む時| echo "{$name} 文字列";|
gem 'sprockets' 4.0での並列処理でデッドロックしてしまう問題について

## gem 'sprockets'について
seeetsファイルをコンパイルするライブラリ。
ただし、rails 5.1 からはjavascriptコンパイラには`webpacker`が推奨され、rails 6.0からはjavascriptコンパイラのデフォルトが`webpacker`に変更されている。
現時点ではCSSやimageのコンパイルのデフォルトに使用されている。

CSS, image -> sprockets
javascript -> webpacker

## 現象

アセットプリコンパイルで実行結果が返ってこなくなります。

## 解決方法
### 1. 並行処理を無効にする設定を行う。
以下どちらかの設定をアプリケーションの設定で行うことで、並行処理を無効にし問題発生を回避します。

```
Rails.application.config.assets.export_concurrent = false
Sprockets.export_concurrent = false
```

### 2.sprocketsのバージョン3系を使用する
gem 'sprockets'のメンテナンスは遅く、修正まで時間がかかることが予想されるので3系を使うのも1つです。

## 詳細

Sprockets 4.0ではコンパイルのパフォーマンス向上のためにマルチスレッドで並行実行される様にな離ました。
See: https://github.com/rails/sprockets/pull/469

並行処理は`Concurrent::Promise`を使用し、その後`promises.each(&:wait!)`で`wait!`しています。

```ruby
promises = args.flatten.map do |path|
  Concurrent::Promise.execute(executor: executor) do
    environment.find_all_linked_assets(path) do |asset|
      yield asset
    end
  end
end
promises.each(&:wait!)
```
See: https://github.com/rails/sprockets/pull/469/files#diff-0d972076f2fbe7a73281fcc0282e57a1618bba231bc8023a4d5bc5705fb06da7R123-R130

このとき、`wait!`メソッドでは処理が終わるまでtimeoutの時間待機するのですが、引数を指定していないため`nil`が入り、永遠に待ち続けます。

```
def wait!(timeout = nil)
  wait(timeout).tap { raise self if rejected? }
end
```

See: https://github.com/ruby-concurrency/concurrent-ruby/blob/ffed3c3c0518030b0ed245637703089fa1f0eeee/lib/concurrent/concern/obligation.rb#L79-L89

並行処理の中でデッドロックが発生した場合、アセットプリコンパイル処理が永遠に終わらない問題が発生します。
並行処理している中で、複数のスレッドが同一のファイルをコンパイルしようとしてデッドロックしているようです。
ruby-concurrencyのバグ？の可能性があるとのことです。
https://github.com/ruby-concurrency/concurrent-ruby/issues/870

また類似のissueも多く回っています。
See: https://github.com/rails/sprockets/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+thread+OR+concurrent

## 参考
https://github.com/rails/sprockets/issues/640
https://github.com/rails/sprockets/issues/581
https://github.com/ruby-concurrency/concurrent-ruby/issues/870
https://github.com/ruby-concurrency/concurrent-ruby/blob/ffed3c3c0518030b0ed245637703089fa1f0eeee/lib/concurrent/synchronization/lockable_object.rb#L6-L20

## その他
sprocketsについての議論は以下のWTFのページも勉強になります。
https://discuss.rubyonrails.org/t/sprockets-abandonment/74371/24
[SQL]基本構文

# はじめに
SQLの勉強をしているので、使った構文を随時更新していきます。

## LIKE
部分一致や前方一致、後方一致検索が出来る。

```
SELECT *
FROM MEMBERS
WHERE NAME LIKE '%A%' OR NAME LIKE '%B'
```

NAMEに「A」を含むレコードの抽出。

- '%A%'：Aを含む
- 'A%'：Aから始まる
- '%A'：Aで終わる


## DISTINCT
重複削除

```
SELECT DISTINCT NAME
FROM MEMBERS
```
NAMEカラムの重複を削除して抽出。

## MOD
AをBで割った余りを返す。
MOD( A, B )
 
```
SELECT AGE
FROM MEMBERS
WHERE MOD(AGE,2)=0
```
AGEが偶数のみ抽出。

## COUNT
レコード数取得。
差分を求めることも可能。

```
SELECT COUNT(NAME) - COUNT(DISTINCT NAME)
FROM MEMBERS
```

## INNER JOIN
テーブル結合
`ON`以降の条件にマッチするもののみ抽出。
※`LEFT OUTER JOIN`と`RIGHT OUTER JOIN`もある。

```
SELECT *
FROM テーブル1
INNER JOIN テーブル2
ON テーブル1.ID = テーブル2.MEMBER_ID
INNER JOIN テーブル3
ON テーブル1.ID = テーブル3.MEMBER_ID
WHERE ~
```

## CHAR_LENGTH(CHARACTER_LENGTH)
文字数を返す。

```
SELECT CHAR_LENGTH(カラム名)
FROM MEMBERS
ORDER BY CHAR_LENGTH(CITY) DESC
LIMIT 1;
```

## IFNULL(A,B)
第一引数がnullだった場合、第二引数に置き換える。

## SELECT SUBSTRING(NAME, 1, 1)
どこから(第二引数、先頭は1)、どれくらい(第二引数)を抽出。
NAMEカラムの１番目から一文字抜き出す。


## GROUP BY
データをグループ化する。
例：メンバー毎のMONEYの合計を抽出。

```
SELECT SUM(MONEY)
FROM MEMBERS
GROUP BY MEMBER.ID
```
## RIGHT LEFT
RIGHT:右から
LEFT：左から

第一引数：対象のカラム、文字
第二引数：何文字分取り出すか

```
SELECT NAME
FROM MEMBERS
WHERE LEFT(NAME, 1) IN ('a', 'b')
AND RIGHT(NAME, 1) NOT IN ('x', 'y')
```

## SUBSTRING
第一引数：対象
第二引数：何文字目から
第三引数：何文字分
抽出する。

```
WHERE SUBSTRING(NAME, 1, 3)
```

## ORDER BY
昇順、降順で並び替える

```
WHERE ~ 
ORDER BY RIGHT(NAME, 1), AGE ASC
```

## サブクエリ

```
SELECT NAME
FROM MEMBERS
WHERE BIRTHPLACE IN (
  SELECT BIRTHPLACE
  FROM DETAILS
  WHERE BIRTHPLACE = 'Tokyo'
)
```

## case

```
SELECT 
case
 when (A + B) < C then 'hoge'
 when A = B then 'hogehoge'
 else 'hogehogehoge'
end
FROM tables
``` 

## between
範囲指定

```
select *
from hogehoges
where created_at between '2021-03-01 00:00:00' and '2021-03-02 23:59:59'; 
```
Nanopi NEO3へVisual Studio Codeをへインストールする

# はじめに
Visual Studio Codeのバージョンが1.5になり、ARM64のCPUでも簡単にVisual Studio Codeがインストールできるようになりました。Nanopi NEO3でも同じ手順でインストールできるので紹介します。

# インストール方法
### インストーラをダウンロード
ブラウザで表示されるリンク先からARM64用のdebファイルをダウンロードします。
```wget https://aka.ms/linux-arm64-deb```
### インストール
``` dpkg -i linux-arm64-deb ```

以上
Javaの開発環境の構築（Macの場合）

#始めに
今回から学習の進捗報告・メモがわりにQiitaで記事を書いていくことにします。
同じ初学者の方は参考にしてください。

##環境の種類
①Eclipse
Eclipsは主にJavaアプリケーションの開発に用いられる統合開発環境（IDE）です。
またフリーオープンソースのソフトウェアで無料で使用することができます。

1990年代後半にIBM社によって開発されましたが、よりオープンなソフトウェアにする為に、現在は非営利組織Eclipse Foundationが運営に当たっています。

３ヶ月ごとにリリースされています。2018年までは「惑星」「人名」「元素」などリリースごとにコードネームがありましたが現在廃止され配信時の年月がコードネームになっています。
今回はEclipseをの環境を構築します。

②InteliJ
IntelliJ IDEAは、チェコに本社を置くJetBrains社が開発した、Javaなど数多くのプログラミング言語に対応した統合開発環境です。

基本は無料で使用することができますが、１部の機能は有料になっています。

メリットは企業が運営しているということでバージョンのアップデートの速度が早く、Scalaなど最新の言語にも対応しています。

##構築手順
###Pleiades All in Oneのインストール
Eclips本体は英語版しかない為、別途日本語化ツールが必要になります。
その日本語化ツールがPleiadesというものになりますが、Pleiades All in Oneをインストールすると
EclipsとPleiadesを同時にインストールしてくれます。



手順1　検索サイトで「Pleiades All in One」と検索
大体１番上にサイトが出てきます。
![スクリーンショット 2020-11-03 12.52.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/fadcf232-59d6-3071-12c5-2f6f632eb394.png)


手順２　Pleiades All in Oneのダウンロード
青色ボタンの一番左上が最新版になっているので、最新版をクリック

![スクリーンショット 2020-11-03 12.53.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/ba040ae8-8288-412b-395d-6155431a1d8c.png)

手順３JavaのFull Editionをクリック（左から３番目、上から３番目のボタン）
![スクリーンショット 2020-11-03 13.02.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/1ead67fc-132d-cf61-9206-a8bfda9d8fb5.png)

手順４ダウンロードリンクをクリックしてダウンロードを開始（20~30分）
![スクリーンショット 2020-11-03 13.06.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/28bed4af-6515-205d-ee15-062b62e2a1c0.png)

手順５EclipseをApplicationsにドラッグアンドドロップ
![スクリーンショット 2020-11-03 13.21.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/4d81c243-3e94-dbdf-59e8-3f7c25451f96.png)

※エラーが発生した場合
キャンセルで一度閉じる
![スクリーンショット 2020-11-03 13.30.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/a4e90d3e-badd-914a-abce-5c692400037d.png)

システム環境開発のセキュリティとプライバシーの一般の下部のこのまま開くをクリック

![スクリーンショット 2020-11-03 13.34.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/ce52ed65-6365-c69a-4441-d777721aab2b.png)

開くをクリック
![スクリーンショット 2020-11-03 15.11.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/afc71377-2f2e-b271-f563-dc1973c9ffc2.png)

手順６　無事にインストールが完了しました！
![スクリーンショット 2020-11-03 15.13.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772822/dd5c279a-b22e-c57c-fa0b-63962076a7a9.png)

#終わり
特に難しい作業はありませんでした。
ServiceNow - 複数チェックボックスの中で１つの選択を必須にする

#概要
二つ以上の項目の選択を必須にするスクリプトです。ServiceNowフォーラムでの質問の回答です。
一つ以上の選択を必須にする場合はUIポリシーで1つのチェックボックスを必須にするとチェックを必須にできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/4e21fc53-f76d-9e32-1dc9-b70dfedb243b.png)

二つ以上の選択を必須にする場合はUIポリシーで2つのチェックボックスを必須にしても1つの選択で登録することができます。
二つ以上の選択を必須にするにはクライアントスクリプトを作成する必要があります。

#手順
##変数の定義
次のようにラベルと3つのチェックボックスを定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/5cdba6e6-0984-13f0-b8d4-98892a0b76fe.png)

##UIポリシー
最低一つの選択を必須にするためにUIポリシーを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/56e95dbf-1b46-824e-4b3c-5af7dcc3e86d.png)
フォームを開いて見ると次のようにラベルの右に赤い「*」が表示されて選択が必須であることを示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/88ff117e-2b9d-5bd8-201e-c90ec0d8d4ba.png)
但し残念なことに1つを選択すると黒くなります。これはしょうがないとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/0d780aed-9164-7410-4495-febe0f394a56.png)

##クライアントスクリプト
次のスクリプトを作成します。変数「mandatoryCount」は選択必須項目の数です。今回は2つの選択を必須にするので「2」にします。

```
function onSubmit() {
    //Set the mandatory checkbox variable names and total mandatory count here
    var mandatoryVars = 'club_wembely_membership,education,player_status_competitions';
    var mandatoryCount = 1;
   
    var passed = forceMandatoryCheckboxes(mandatoryVars, mandatoryCount);
    if (!passed) {
        //Abort the submit
        var message = 'You must select at least ' + mandatoryCount + ' options.';
        g_form.addErrorMessage(message);
        return false;
    }
}

function forceMandatoryCheckboxes(mandatory, count) {
    //Split the mandatory variable names into an array
    mandatory = mandatory.split(',');
    var answer = false;
    var varFound = false;
    var numTrue = 0;
    //Check each variable in the array
    for (var x = 0; x < mandatory.length; x++) {
        //Check to see if variable exists
        if (g_form.hasField(mandatory[x])) {
            varFound = true;
            //Check to see if variable is set to 'true'
            if (g_form.getValue(mandatory[x]) == 'true') {
                numTrue ++;
                //Exit the loop if we have reached required number of 'true'
                if (numTrue >= count) {
                    answer = true;
                    break;
                }
            }
        }
    }
    //If we didn't find any of the variables allow the submit
    if (varFound == false) {
        answer = true;
    }
    //Return true or false
    return answer;
}
```
##実行
フォームを開いて試して見ます。項目1つを選択しただけで「Order Now」ボタンを押下すると次のようにエラーメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/0999dd2a-768c-b1a6-f339-ac640fe9af13.png)

以上
OpenCV「画像の表示、画像のサイズ変更」

##本格始動！
ここまでで環境構築は説明してきましたが、前回最後に書いたコードで動かなければ、何かがうまくいっていないので設定を見直しましょう。アイアンマンが好きなのでコードの名前はMark1,Mark2・・のように書いていきます。

##Mark1　前回のコードの紹介
```
#include <opencv2/opencv.hpp>

#if _DEBUG
#pragma comment(lib,"opencv_world430d.lib")
#else
#pragma comment(lib,"opencv_world430.lib")
#endif

using namespace cv;	
using namaspase std;

int main(void) {


	Mat img = imread("C:\\opencv\\sources\\samples\\data\\lena.jpg");

	imshow("View", img);

	waitKey();

	return 0;

}
```
######解説①
c言語とc++言語の大きな違いの一つに名前空間という考えがあります。OpenCVも名前空間があり通常はOpenCVの関数の前にはcv::をつけます。僕は毎回書くのがめんどくさいので先にusing namespace cv;をつけて書かなくていいようにしています。
######解説②
Mat imgでimgという箱を作ります。その箱の中にC:\\opencv\\sources\\samples\\data\\lena.jpgのようなパスをimreadで読み込んで入れましょう。パスは￥一つだけだとエラーになるので￥￥と二つつけましょう。以下のように、先にimgを作ってもいいです。パスは必ず""の中に入れましょう。

```
	Mat img;
	img = imread("C:\\opencv\\sources\\samples\\data\\lena.jpg");
```

######解説③
```
imshow("View", img);
```
これは画像を表示させる関数です。さっき作ったimgをViewという名前で表示させます。""の中の名前は何でもいいです。

######解説③

```
waitKey();
```
これなしでも画像は表示されますが、一瞬で消えてしまいます。名前からわかると思いますが、何か起こるまで待つようにするためにあります。waitKey(10);のように()の中の数字を変えると表示時間を変えられます。

######解説④
このように表示されると成功です。

![lena.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843242/1e32645b-0ceb-989c-202d-96089fcd2e36.jpeg)

##Mark2　画像のサイズ変更
```
#include <opencv2/opencv.hpp>

#if _DEBUG
#pragma comment(lib,"opencv_world430d.lib")
#else
#pragma comment(lib,"opencv_world430.lib")
#endif

using namespace cv;	

int main(void) {

	Mat img = imread("C:\\opencv\\sources\\samples\\data\\lena.jpg");

	resize(img, img, Size(), 0.5, 0.5);																	

	imshow("View", img);

	waitKey();

	return 0;
}

```
######解説①
```
resize(img, img, Size(), 0.5, 0.5);
```
さっきのコードに　これを追加させるだけです。最初のimgは入力画像で二つ目のimgは出力画像です。Size()を入力した後、一つ目の0.5はx方向に0.5倍、二つ目はy方向に0.5倍します。つまり大きさを半分にできます。0.5の数字を変えると縦長や横長にもできるので試してください。

######解説②
このようにこのように出てくればOKです。

![0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843242/8ca49102-754b-2b07-c334-a55ef2de62de.jpeg)



##最後に
あくまで自分のメモ帳として残しているので自分に分かりやすいように書いています。あほっぽい表現もあるかもしれませんがご了承ください。初心者向けですが、これが誰かの役に少しでもなればいいなと思います。(僕も最初かなりつまずいたので)
githubのmainブランチに初pushするときに出たエラー解決方法

BLMの影響により、masterが奴隷制度を連想させるということで、githubではデフォルトのブランチ名がmasterからmainに変更となったそうです。これにより、個人プロジェクトをgithubへ上げる時に支障が出たので、解決方法を書きます。


##[事前準備] gitのデフォルトブランチ名をmainにする
ローカル開発環境でgitのデフォルトブランチ名をmasterからmainに変更します。


##ローカルリポジトリをgithubに上げる
今回は、通常の手順で個人のプロジェクトをgithubに上げます。
（事前にgithubでリポジトリを作ってあります。）

```
$ git init
```

```
$ git remote add origin リポジトリのURL
```

```
$ git commit -m'first'
```

```
git push origin main
```



ここで、エラーが発生します

```
! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:リポジトリ名'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```


リモートリポジトリで変更した内容がローカルに反映されていないことが原因のようです。まず、リモートブランチを追跡ブランチに反映させるためにfetchを実行する。

```
$ git fetch
```

追跡ブランチをローカルブランチに反映させるためにmergeを実行する。

```
$ git merge origin/main
```

また、エラーが発生

```
fatal: refusing to merge unrelated histories
```

調べてみると、mainブランチのヒストリーが紐づいていないようです。。そのため、上記をmergeするには-allow-unrelated-historiesという、関連のないリポジトリの内容をマージするためのオプションが必要らしいので、オプションを付けてmergeを実行。

```
git merge --allow-unrelated-histories origin/main
```

またまたエラーが発生

```
CONFLICT (add/add): Merge conflict in README.md
Auto-merging README.md
Automatic merge failed; fix conflicts and then commit the result.
```

README.mdファイルでコンフリクトを起こしています。
git statusで状況を確認すると原因が出てきました。

```
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both added:      README.md

no changes added to commit (use "git add" and/or "git commit -a")
```

README.mdのファイルがコンフリクトを起こしているのでaddしろと出てきました。
（自分の場合、リモートリポジトリではREADMEファイルのみ作成していたので、ローカルとコンフリクトしてしまったようです。）

言われた通りaddを実行

```
$ git add README.md
```

commitを実行

```
$ git commit -m'second commit'
```

pushを実行

```
$ git push origin main
```

問題なくpushできました！


###参考記事
[Gitのデフォルト・ブランチ名を変更する方法](https://parashuto.com/rriver/tools/change-git-default-branch-name)
[GitHubへのpushが「fetch first」と表示されてrejectedとなったときの対処](https://wonderful-tereshkova-38f91d.netlify.app/GitHub%E3%81%B8%E3%81%AEpush%E3%81%8C%E3%80%8Cfetch%20first%E3%80%8D%E3%81%A8%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%A6rejected%E3%81%A8%E3%81%AA%E3%81%A3%E3%81%9F%E3%81%A8%E3%81%8D%E3%81%AE%E5%AF%BE%E5%87%A6/)
マルチアップロード　Flask-Form-Model＋JS埋め込み

#内容
Flaskでファイル送信FORMを動的に作っていて、自分なりに解を見出したのでまとめる。
関連質問は以下となる
https://teratail.com/questions/300488
https://teratail.com/questions/302044

#結論
Flaskからのレンダリングは、フォームの個数だけを指示する。
JS側でフォームの成形をする　→　VUEの出る幕は無し

最終的にはVue.Jsは使わないことにしました。

#解決した方法
HTMLフォームとFLASKのFORM-MODEL処理について、下記の辞書を使い紐付けを行った。

JS 
dict =  { "title1:"db1","title2":"db2", "title3":"db3","title4":"db4" }

python
model_table = {"db1",database1,"db2":database2,"db3":database3,"db4":database4}

全体的なループカウンタは、Flask側からJINJA2でループを回して、レンダリング時にloop.index0を使いIDタグに命名している。
DOM完成後にJSでdictのループを回して、MAPのINDEXからIDを生成し、html本文を書き換えている。

```html

          {% for i in forms %}
          <h1 id = "t{{loop.index0}}"></h1>
          <p>
              <form id = "f{{loop.index0}}" class="form form-horizontal" method="POST" action="{{url_for('data_import')}}"  enctype="multipart/form-data">
                  <input type="file" name="file">
                  <input type="submit" >
              </form>
          </p>
          {% endfor %}

<script>
var dict =  { "title1:"db1","title2":"db2", "title3":"db3","title4":"db4" }

    Object.keys(dict).map(function(key,index){
        document.getElementById('t'+index).textContent = key;
        document.getElementById('f'+index).action += "/"+dict[key];
    });
</script>
```

Flask側はURLエンドでデータベースのモデルを特定できるようにした。
モデルを自体を直接的に辞書に突っ込んでおり、model_nameを介して
共通コードで処理している。

いったんモデルクラスに実装したdata_importというメソッドで
処理はモデル毎にカスタマイズしており、
returnされるobjectは、データのインスタンス群であり、これを一括で更新する。

```python
model_table = {"db1",database1,"db2":database2,"db3":database3,"db4":database4}

#データインポート処理
@app.route('/import')
@app.route('/import/<model_name>',methods=["GET", "POST"])
def data_import(model_name):
    if request.method == 'POST': 
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            flash(name + "ファイルを選択してください。", "failed")
            return redirect(request.url)
        if file and allowed_file(file.filename): 
            filename = secure_filename(file.filename)
            filename =os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(filename)
            model = model_table[model_name]
            objects = model.data_import(filename)

            db.session.bulk_save_objects(objects)
            db.session.commit()

        return render_template(
            'table_viewer.html',
            forms = range(4)
        )

    return render_template( 
        'import.html',
        forms = [1,2,3,4]
    )
```

#あとがき
　何故ここまで複雑化したのかというと、いろんな理由がある。

・バックエンドの処理において、フォーム毎にバインディングしているデータベースが違うこと
・FLASK側ではORMライブラリを使い、複数ファイルに分かれたSQLITEに対して、共通化した処理でコミットさせたかった
・Flaskのテンプレート内のVIEWに関わる情報については、受け側のHTML内で処理したかった。
・POST送信はHTMLのデフォルトでやりたく、AJAX通信の複雑さをコードに入れたくなかった。

　最近は便利なフレームワークが多いが、無理をせずにバニラjsで十分できることもある。
工夫されたコードはいたってシンプルであり、かつ美しいものである。
スクリプトとCGIについて小学生でもわかるように説明してみた

## プログラム
CGIを説明する上で必要なので簡単に紹介。
ざっくり説明するとユーザーがコンピューターに出す指示された任務。例えば

- メール送信機能作って!
- 赤いボタンを表示させたい!

など


## CGI
Google Chromeなどのwebブラウザが出した要求に応じてWebサーバがプログラムを起動させる仕組みのこと。
ホームページを見せてくれ!という要求に対し、その場でホームページのファイルを作って返すための仕組みと思ってください。要求を受信したwebサーバーはCGIによってプログラム(指示された任務)を実行します。プログラムはwebブラウザから送信されてきたデータやサーバー自身が持っているデータなどからファイルを作成し、サーバーを通してwebブラウザに送信されます。
![スクリーンショット 2020-11-03 14.36.48（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/57a811d5-6951-dae2-470d-6b566718be03.png)



## スクリプト
人間が読める言語に変換したプログラムをコンピュータが分かる形に変換する作業（コンパイル）を人間が意識しないで済むプログラム。プログラム(指示された任務)が動くまでの流れは

１．人がわかる言語でコンピューターにやって欲しいことを書く(プログラミング)
２．1で書いたコードをPCさんに分かる言語に翻訳する。(コンパイル)
３．PCさんが2で実行した説明書を読んで働く(実行)

この内２のコンパイルが人間から見てやってないように見えるのがスクリプト
![スクリーンショット 2020-11-03 14.38.44（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/5e310439-5cde-f45f-cd4b-0569a35dfe9c.png)


## クライアントサイドスクリプト
ブラウザ側で処理をする時に動作するのでクライアントサイドの言語。cssやjavascriptなどが挙げられる。
例えばログイン画面でパスワードが8文字以上必要なのに6文字で登録ボタンを押した時、CGI(処理)を実行する前にエラーを出す行為がクライアントサイドスクリプトになる。ログインページを読み込んだ時に用意されたjavascriptを実行しているだけなのでページは更新されずにエラーメッセージが表示される
![スクリーンショット 2020-11-03 14.40.19（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/741a8606-aafc-3a16-2d45-12f0e88d4cda.png)



## サーバーサイドスクリプト
WEB サーバー側でCGI(処理)を行いクライアントに返すプログラム言語。Ruby,phpなどが挙げられる。
例えばログイン画面で誤ったパスワードを入力し送信した場合、Webサーバー(CGI)がプログラム(指示された任務)を起動してパスワード確認をするその結果、エラーであることをユーザーに知らせるといった行為。CGI(処理)を実行しているのでページは一度更新される
![スクリーンショット 2020-11-03 14.42.03（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/fc92be2b-b639-4ea4-16e9-c81432ea1383.png)
[ServiceNow] sys_idからどのテーブルにあるレコードか調べる

# きっかけ
エラー調査でトランザクションログを確認していて、対象のSysIDがどのテーブルのものかわからなかった

`/sys.scripts.do?sys_id=xxxx..(対象のsys_id)&action=run_module`

## プラットフォーム
Paris

## 参考にしたURL
https://community.servicenow.com/community?id=community_question&sys_id=bda11b6ddbdcdbc01dcaf3231f961949

# 解決策
下記のスクリプトを実行

```javascript:search_by_sysid
var target_id = "[検索対象のsys_id]";
 
var gr = new GlideRecord('sys_metadata');
gr.addQuery('sys_id', target_id);
gr.addActiveQuery();
gr.query();
while(gr.next()) {
    // このダブルチェックをしないと大量にゴミがログに吐かれるらしい
    if(gr.sys_id == target_id) {
        gs.log(" ID: " + gr.sys_id + " Name: " + gr.name + " Class: " + gr.sys_class_name);
        gs.log(gr.getRowCount());
    }
}
```

## 実行結果

> *** Script:  ID: xxxx..(対象のsys_id) Name: undefined Class: sys_app_module
> *** Script: 1
rails学習　7日目

#Railsチュートリアル　第５章
##Bootstrapとカスタムcss

Bootstrap：簡単にwebの見た目をよくしてくれる便利ツール

>Bootstrapの追加方法

①Gemfileにbootstrap-sassを書く

```
gem 'bootstrap-sass','3.3.7'
```
②bundle installでgemファイルを取り込む

```
bundle
```
これでBootstrapが使える状態になった

>カスタムcss

app/assets/stylesheetのしたにcustom.scssファイルを作成

```scss:app/assets/stylesheet/custom.scss
@import "bootstrap-sprocket";
@import "bootstrap";
```
@importでbootstrapを反映させた。これでbootstrapを使えるcss(custom.scss)ができた。


##5.2 Sassとアセットパイプライン

>アセットパイプライン

jsやcss、画像などそれぞれのファイルを一つにまとめてブラウザ上で見れるようにするもの。

>Sass(scss)

cssのレベルアップバージョンがSassになる。
Cssのファイルは.cssだが、Sassのファイルは.scssという形式になる

####Sassの応用的な書き方

書き方１：まとめる

cssの書き方

```css
.center{
   text-align: center;
 }

.center h1{
   margin-bottom: 10px;
 }
```
sassの書き方

```scss
.center{
   text-align: center;
 h1{
   margin-bottom: 10px;
  }
 }
```
center{　　h1{　　  }}という書き方ができる

また他にも

cssの書き方

```css
#logo{
   float:left;
  }

#logo:hover{
   color:#fff
  }
```
scssの書き方

```scss
#logo{
   float:left;
 &:hover{
    color:#fff
    }
   }
```
とまとめて書くことができる。

書き方２：変数

```css
$light-gray:#777  

h1{
color:$light-gray
}
```
と任意の操作を変数として代入して扱うことができる。

####URL

root_path => '/'
root_url => 'http://www.example.com'
のようにroot_pathは.comから後ろの文字を判断する。root_urlはurlの全てで判断する。

ただしredirect_toの場合はroot_urlの方を使う。
ServiceNow - ビジネスルールからクライアントにエラーを返す

#概要
ビジネスルールが発生したエラーメッセージをクライアントスクリプトに送る場合はgs.addErrorMessage()を使う。

#例
添付ファイルをアップロードする場合に既に同じ名前の添付ファイルがある場合はエラーを返す。ただし、クライアントページを再読込しないとメッセージは表示されない。

```
var gr = new GlideRecord('sys_attachment');
gr.addQuery('table_name', current.table_name);
gr.addQuery('table_sys_id', current.table_sys_id);
gr.addQuery('file_name', current.file_name);
gr.addQuery('content_type', current.content_type);
gr.addQuery('size_bytes', current.size_bytes);
gr.addQuery('size_compressed', current.size_compressed);
gr.setLimit(1);
gr.query();
if (gr.next()) {
    gs.addErrorMessage('File ' + current.file_name + 'already exists.");
    current.setAbortAction(true);
```
PyCharmでpip installできないライブラリをimportする

# 実行環境
- Ubuntu 18.04
- Python 2.7
- PyCharm Community 2020.2

# 経緯
Ubuntuでweiliu89さんの[ssd-caffe]("https://github.com/weiliu89/caffe/tree/ssd")を導入したのですが、Pythonインタープリタまわりが初心者だったためPyCharm環境でうまくimportできませんでした。解決したので記録を残しておきます。

今回はCaffeをimportしていますが、github等からcloneしたものは全般的に同様の手順でimportできるようになるはずです。

# 手順
## 1. PyCharmでインタープリタの設定をする
PyCharmを開き、ファイル -> 設定 -> プロジェクト:プロジェクト名 -> Pythonインタープリター
でインタープリタの設定ページに移動します。

defaultではPython2.7 /usr/bin/python2.7(灰文字)とかになっているのではないでしょうか。
ここを切り替えることでPythonのバージョンを変えたりすることができます。

下にインストールされているパッケージがリスト化されていると思います。


## 2. インタープリタにPathを加えるだけ
では使いたいインタープリタにPathを加えましょう。
右の歯車ボタンからすべて表示を選択すると、使用できるインタープリタの一覧が表示されます。
ここで使用したいものを選択した状態で、右の５つのアイコンのうち一番下の「選択したインタープリタのパスを表示する」を開きます。

するとパスがズラッと表示されますね。
今回はCaffeを入れたいので、追加ボタンを押して、"/home/usrname/caffe/python"を追加します（環境によって変えてください）。

適用して`import caffe`で確認してみましょう。
オープンソースのpipパッケージにloggerを入れて動作解析する

# 概要
- ソースが公開されているpipパッケージの動作を調べるため、logger入りのパッケージを作って、ローカルからインストールします。


# 今回の対象
- django-allauth 0.44.0



# 準備

- 現在インストールされているバージョンを確認
    - `pip list | grep django-allauth`

- ソースコードをGitHubからclone
    - `mkdir django-allauth-with-log && cd django-allauth-with-log`
    - `git clone https://github.com/pennersr/django-allauth.git`
    - `cd django-allauth`

# ローカルからpipでインストールする手順の確認

## バージョン番号の変更

- `vi allauth/__init__.py`

```python
#VERSION = (0, 44, 0, "dev", 0)
VERSION = (0, 44, 0, "dev", 99)
```

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

- `pip uninstall django-allauth`

## ローカルからインストール

- setup.py のあるディレクトリの1つ上のディレクトリに移動
    - `cd ..`
- pipでディレクトリ指定でインストール
    - `pip install ./django-allauth/`

## インストールされたバージョンの確認
 - `pip list | grep django-allauth`

    - 上記で書き換えたバージョン番号 `django-allauth     0.44.0.dev99` と出れば成功です


# 解析用に手を加える

## loggerの設定を追加

loggerの設定ファイルを追加し、`allauth/app_settings.py`から読み込む


- `vi allauth/logging_settings.py`

```python
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,

    'formatters': {
        'django.server': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[%(server_time)s] %(message)s a',
        },
        'develop': {
          'format': '%(asctime)s [%(levelname)s] %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'develop',
        },
        'django.server': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.server',
        },
    },
    'loggers': {
        '': {
          'handlers': ['console'],
          'level': 'DEBUG',
          'propagate': False,
        },
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
        },
        'django.server': {
            'handlers': ['django.server'],
            'level': 'INFO',
            'propagate': False,
        },
    }
}
```

- `vi allauth/app_settings.py`

```python
from .logging_settings import *    # 追加
```


## 任意の場所にログ出力を追加

- 例えば、`allauth/account/views.py`に以下を追加

- loggerの設定

```python
import sys
import logging
logger = logging.getLogger(__name__)
```


- 任意の場所に以下を追加(例：`class SignupView` の `def dispatch` )

```python
    logger.info(f'class={self.__class__.__name__}, function={sys._getframe().f_code.co_name}, Line={sys._getframe().f_lineno} called.')
```

- クラス名は継承先の名前?が表示されるので注意が必要

# ローカルからpipで再インストール
- `pip uninstall -y django-allauth`
- `pip install ./django-allauth/`
    - `Successfully installed django-allauth-0.44.99.dev0`と出れば成功です


# 動作確認
- サーバを起動して`http://127.0.0.1:8000/member/signup/`のようなURLにアクセスして、以下のようにコンソールに表示されればOKです。

```sh
2020-11-03 01:23:45,678 [INFO] class=SignupView, function=dispatch, Line=238 called.
```
機械学習でt+pazolite楽曲を判別する（NNCチャレンジ発展）

#### 1. はじめに
　[前回][1]は[NNCチャレンジ][2]の作品として「t+pazolite楽曲が機械に判別できる」ことを示した。
結果には満足できたものの、内容はNNCに入力できるようにデータの前処理をすることに終始して肝心の機械学習に対する考察がおざなりであった。前回のチャレンジでの気づきを生かしてより実践的なコンテンツを作っていきたい。

#### 2. 機械は本当にとぱぞ曲を判定できたのか？
　前回は[Audiostock][3]提供の楽曲データにとぱぞ曲を混ぜて楽曲がとぱぞによるものかそうでないかを判定する識別器を作った。評価は99%以上の正解率を誇り、機械学習によって一作曲家の楽曲を判定できるという結果となった。
![NNC_challenge_tpz_or_not_result1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620425/074d9f05-955c-2c83-756c-0b7051aff6ed.png)
![NNC_challenge_tpz_or_not_result2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620425/ab5aba1a-fd9c-b192-8aed-cb5f4185a56a.png)
　使用したデータはAudiostock提供のおよそ10000曲に、提供データと同じサイズに切りそろえた手持ちのとぱぞ曲を付け加えたものである。ここで疑問になるのは提供データが楽曲の独自性を判定するのに十分な多様性を持っていたかということである。
筆者は提供データの全てを実際に再生してみたわけではない。提供データにはt+pazolite氏の得意とするBPM150を超えるような"早い"楽曲はなかったかもしれないし、とぱぞ楽曲に使用された特別なシンセサイザーの音に反応した結果判定が容易だった可能性もある。今回はこの点を検証していきたい。

#### 3.検証
　まずは提供データの偏っていた可能性について検証する。提供データが判別するべきとぱぞ曲とあまりに解離していた場合、判定は容易になるだろう。したがって検証データとして"よく似た"楽曲の中にとぱぞ楽曲を混ぜたものを用意して、とぱぞ楽曲を判別できるかを調べた。用意したデータは少ないが、結果は写真のようになる。
![tpz_or_not_result_false.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620425/df1e66af-44fa-a6da-841c-8fefe8a5b640.png)
　予想通り正解率が下がった。原因は学習用データにとぱぞ曲に"似ている"楽曲が少なかったことにある。Audiostock提供データととぱぞ曲には判別に十分な差異があるが、同じ尺度でTANO-C楽曲ととぱぞ曲を区別できないのである。


#### 4.改善
　t+pazolite氏が所属する作曲家集団"HARDCORE TANO-C"の他の作曲者の楽曲を学習用データに混ぜることにする。TANO-C楽曲データを学習用データに混ぜたもので学習すると結果は次のようになる。
![tpz_or_not_result1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620425/012bfe68-a346-8849-3de7-198c20e9437c.png)
　前回の結果よりもさらに一桁精度の高い判定結果が得られた。とぱぞ楽曲は同ジャンルの曲の中でも判別可能な楽曲であることもわかる。

#### 5.終わりに
　今回の結果から、特定の作曲者を機械学習で判別できることがわかる。学習用データにその作曲者と同ジャンルの作曲者の楽曲を多く混ぜることで精度がより高くなることもわかった。次回はデータの前処理ではなく機械学習の手法そのもので精度をあげる方法を考えたい。


[1]:https://qiita.com/nonnon-git/items/90d0b666b779e730a088
[2]:https://nnc-challenge.com/
[3]:https://audiostock.jp/![NNC_challenge_tpz_or_not_result2.png]
【Ruby】メソッドの前のレシーバがない（ように見える）場合の考え方

## 背景：

レシーバとは、A.medhod(B)のAのことです。
メソッドの前のレシーバがないように見える場合があります。例えば、以下のような場合です。

```ruby
class ClassA
  def say
    puts instance_of? String #false
    puts instance_of? ClassA #true
  end
end
ClassA.new.say
#false
#true
```

instance_of? は
[【Ruby】is_a? と instance_of? の違い](https://qiita.com/akihiro_kubota/items/3ca17fe7f7bd810e4cf9)
の説明にも書いたように、

```ruby
A.instance_of? B 
```
とあるときに、AはBのインスタンスであるというものなのですが、上記の例の場合`A.`がないですよね。

## 考え方

結論としては、上記のinstance_of?の前にはClassAのインスタンスがついています。
同じクラスや継承元クラスやインクルードしたモジュールのメソッドを参照する場合はメソッドの前にインスタンスをつける必要がないです（自動的についていると考える）。
追記：「レシーバーをあらわに書かないメソッド呼び出しでは，self がレシーバーとなる，というルールがあります。」というコメントをいただきましたが、こちらの考え方の方がわかりやすいと思います。

例えば、以下のような場合がありますが、

```ruby
class ClassB
  def say_b
    say_b2
  end
  def say_b2
    puts "bbb"
  end
end
ClassB.new.say_b
# bbb
```
これはほとんど違和感ありませんよね？
同じクラスのメソッドは他のメソッドからレシーバを書かず（というか書けない）に実行することができます。
これと同様に先のinstance_of?メソッドも実際はスーパークラスのObjectクラスのメソッドです（厳密にいうとObjectクラスがインクルードしてるKernelモジュールのメソッドのようです）。

```ruby
ClassA.new.method(:instance_of?).owner
=> Kernel
```

## 違和感を感じた原因

おそらく、最初のinstance_of?がいきなり出てきたところで、違和感を感じたのはinstance_of?メソッドとClassAの関連が見えなかったからと思われます。


## 確認方法
レシーバを確認する方法もあります。

```ruby
method(:メソッド).receiver
```
で出力できます。

```ruby
class ClassB
  def say_b
    say_b2
    puts method(:say_b2).receiver
  end
  def say_b2
    puts "bbb"
  end
end
ClassB.new.say_b
# bbb
# #<ClassB:0x00007ff34d8a0550>
```
say_b2 のレシーバがClassBのインスタンスであることが確認できます。
実は、method(:say_b2)の前にもClassBのインスタンスが既についてしまっているのですが。
anyenvのgoenvにGoLangをインストール

突如業務でGo言語、GoLangを使うことになる可能性が出てきたので、勉強を始めようと思いました。
せっかくなので環境作りを控えておきます。どなたかの役に立つと幸いです。

## 環境

HARD： MBP2015
OS： macOS Catalina 10.15.7 

## anyenvのインストール

多言語でもよくよく出てくる言語のバージョン管理ツールですが、GoLang版もあり、 `goenv` となります。色々試そうとするとバージョン管理ツールが山程溜まってくるので、ここは `anyenv` を使って一元管理しましょう。後から導入しようとすると、pathを通したりするので大変なことになります…。
`anyenv` のインストール手順については、調べると山程出てくるので、そちらを参照してください。

参考: [anyenv + macOS環境構築](https://qiita.com/rinpa/items/81766cd6a7b23dea9f3c)

```
$ anyenv install -l
  Renv
  crenv
  denv
  erlenv
  exenv
  goenv
  hsenv
  jenv
  jlenv
  luaenv
  nodenv
  phpenv
  plenv
  pyenv
  rbenv
  sbtenv
  scalaenv
  swiftenv
  tfenv
```

`goenv` があることを確認出来ました。インストールしましょう。

```
$ anyenv install goenv
/var/folders/jg/bmq8whm12bzbh6rszy2yqbpc0000gn/T/goenv.20201103131148.40785 ~/work/suzuki84g
Cloning https://github.com/syndbg/goenv.git master to goenv...
Cloning into 'goenv'...
remote: Enumerating objects: 106, done.
remote: Counting objects: 100% (106/106), done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 14294 (delta 49), reused 45 (delta 12), pack-reused 14188
Receiving objects: 100% (14294/14294), 2.57 MiB | 1.89 MiB/s, done.
Resolving deltas: 100% (9715/9715), done.
~/work/suzuki84g

Install goenv succeeded!
Please reload your profile (exec $SHELL -l) or open a new session.
```

`exec $SHELL -l` でshellを再起動し、完了です。
`goenv -v` でインストールされていることが確認できました。

```
$ goenv -v
goenv 2.0.0beta11
```

## GoLangのインストール

参考: [goenvでgoをインストール 〜初心者向け〜](https://qiita.com/yut-kt/items/9f5ac1e788df61f64290)

`goenv install -l` でインストール出来るバージョンが山程出てきます。必要なものをインストールしましょう。ここでは最新版を入れてみます。

```
$ goenv install 1.15.3
Downloading go1.15.3.darwin-amd64.tar.gz...
-> https://golang.org/dl/go1.15.3.darwin-amd64.tar.gz
Installing Go Darwin 64bit 1.15.3...
Installed Go Darwin 64bit 1.15.3 to /Users/suzukiyuuki/.anyenv/envs/goenv/versions/1.15.3

$ goenv versions
  1.15.3
```

インストールログから `.anyenv` 配下に1.15.3がインストールされたことを確認しました。
次にglobalでの使用を宣言し、諸々の確認を取ります。env系のコマンド体型は揃えられていて直感的に使えるの本当に助かる。

```
$ goenv global 1.15.3
$ goenv rehash
$ goenv versions
* 1.15.3 (set by /Users/suzukiyuuki/.anyenv/envs/goenv/version)

$ go version
go version go1.15.3 darwin/amd64

$ which go
/Users/suzukiyuuki/.anyenv/envs/goenv/shims/go
```

取り敢えずこれで動く、はず。
メルカリさんのエンジニアコミュニティで公開されている[「プログラミング言語Go完全入門」の「完全」公開のお知らせ](https://engineering.mercari.com/blog/entry/goforbeginners/)が取っつきやすそうだったので、取り敢えずやってみます。
何か良いドキュメントなどあれば教えて下さい。
【第2回】初心者二人で0から麻雀アプリ開発

 [第1回の記事はこちら](https://qiita.com/RTkd59/items/3968bff9a1d9982cd1db)
交互にそれぞれのアカウントで記事を書いていきます。

#第2回会議(2020年10月31日)
麻雀に関係するiosアプリを作ろう！！そんな感じで始まったプロジェクト第2回目の会議


##アプリの概要
！！！統合型麻雀成績管理ツール！！！
とかっこつけて書きましたが、要するにアプリひとつでフリー・セット麻雀の両方の成績を管理出来るアプリが目標です。

##開発ツールの追加
[Slack](https://slack.com/intl/ja-jp/)と[Trello](https://trello.com/ja)を導入しました。
Slackは多機能チャットツールで、話題ごとのチャットや、ファイル共有などが簡単にできるのが利点(らしい)です。
私の所属する研究室に導入するかもということで、じゃあこっちのプロジェクトにも使っちゃえ！と思い切って導入しました。
trelloはタスク管理ツールで、プロジェクトメンバーで共有できるToDoリストや、タスクの分担ができるツールです。



Slackとtrelloは連携でき、trelloでできたToDoをslackに通知してくれたり、slack側から簡単なToDoを作れたりするらしいです。
詳しい使い方は使いながら覚えて行きたいと思います。タスク





##画面のデザイン
画面のデザインについて、カレンダーと収支入力画面をどうするのか、収支入力とシフト入力の画面を一緒にするのか、分けるのか、どんな感じにするのかは、来週までに作って持ち寄るということになりました。基本デザインとしては、ホーム画面の下部にタブを配置し、各機能に飛ぶイメージを考えています。

##今後の予定
第3回会議　１週間後
##最後に
はやくコーディングの工程に入りたい…(コーディング出来るとは言ってない)
swiftの勉強をして、コーディングに入る頃には、書けるようになっていたいです。
Python で文字化けした行を含むファイルを読み込む

試験が細かく行われていないＷｅｂアプリケーションのログファイルって、一部の行が文字化けしていることがありますよね（アプリケーションが出力しているエラーメッセージなど）。

このようなログファイルから統計情報などを取ろうとして、ログファイルをPythonで読み込もうとすると、案の定、文字化けしている行で「デコードできない」という例外が発生してしまいます。

あと、突然知らないシステムのログを渡されて解析を依頼された時など、一見普通の行に見えるのに何故かPyhonで読み込むと「デコードできない」というエラーが発生する場合もあります。この場合はログファイルの文字コードなどを丹念に調査するという方法もありますが、解析と関係ない行ならば発生するエラーに対処している時間が無いこともあります。

そこで、ファイルを open する際に、引数にパラメータ「``errors='replace'``」を指定すると、文字化けしている箇所（デコードに失敗した箇所）は「？」に置換して読み込んでくれます。

```
f = open('foo.log', mode='r', errors='replace')
```

ログから統計情報を集計したいけど、デコードエラーの処理を書く時間が無い時などお試し下さい。

それでは、良い Python ライフを！！