OmniAICreator/Qiita-1.07M huggingface dataset:
mod_auth_mellon + ADFS の組み合わせで認証が失敗する

# はじめに

idP に Microsoft ADFS、SAMP SP に mod_auth_mellon を組み合わせた際に発生した認証エラーの対処内容です。
内容としては単純なものでしたが、若干ハマってしまったのでご参考になればと思います。

# 発生した事象

SPにアクセスを行い、ADFSに遷移しログインが成功したのち、SPにレスポンスをPOSTしたタイミングで、mod_auth_mellon にて以下のエラーが出力されて認証が失敗する。

```
Error processing authn response. Lasso error: [-432] Status code is not success, SAML Response: 
StatusCode1="urn:oasis:names:tc:SAML:2.0:status:Requester",
StatusCode2="urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy", StatusMessage="(null)"
```

# 原因と対処方法

原因は ADFSが返答する情報が mod_auth_mellon が求めているポリシーに則っていないためエラーとなっている。
対処方法としては、ADFSに要求規則名 Name ID で以下の規則を追加する。

```
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
 => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient");
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518444/270ba2c9-acc9-dba5-4c5c-fcc5dd82b89c.png)
# おまけ

上記の対処方法に行き着くまでに調査した内容です。

## ハッシュアルゴリズムの相違？

idP と SP でハッシュアルゴリズムが異なっている場合にもこのエラーが発生するとのことだったが、両者ともSHA254となっていた。
→ 念の為、SHA1で揃えてみたがエラーは解消せず。

## ライブラリのバージョン

mod_auth_mellon は SSO のライブラリに lasso を使用しており、SHA256を使用するには lasso 2.5以上が必要。
→ バージョンを確認したところ、2.5.1だった。

```
# yum list installed | grep lasso
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
lasso.x86_64                          2.5.1-3.el7                     @base
```


# 参考(ソフトウェア構成)

||SAMLのミドルウェア|備考|
|:----|:----|:-----|
|idP|Microsoft ADFS|WindowsServer2019<br>|
|SAMP SP|mod_auth_mellon|CentOS Linux (release 7.7.1908)<br>Apache(2.4.6-90.el7.centos) <br>mod_auth_mellon(0.14.0-2.el7_6.4)|
Install imagick on macOS Catalina + php 7.4 メモ

brew install php@7.3
brew install imagemagick 
pecl install imagick


cd /tmp
curl -s -O https://pear.php.net/install-pear-nozlib.phar
sudo php install-pear-nozlib.phar -d /usr/local/lib/php -b /usr/local/bin


brew install autoconf


sudo pear channel-update pear.php.net
sudo pecl channel-update pecl.php.net
sudo pear upgrade-all --ignore-errors


xcode-select --install


Open /etc/php.ini and add .:/usr/local/lib/php/pear to include_path(if /etc/php.ini does not exist, create it with the following content).
include_path = ".:/usr/local/lib/php/pear"

pecl install imagick

pecl config-get ext_dir | pbcopy


/usr/local/etc/php/7.4/php.ini


open php.ini search for extension= and at the end of extension list add
extension=imagick.so



mkdir /usr/local/lib/php/pecl


sudo pecl install imagick
ラズパイのpythonでオーディオファイルを再生

#pygame
音声ファイルの再生にはpygameを使ってみます。
ラズパイのpythonにはpygameがインストールされているようなので、とくにインストールするパッケージはないです。

#音声ファイル
今回は[ここ](https://taira-komori.jpn.org/sound/animals01/cat1a.mp3)から猫のファイルをダウンロードします。

#ファイルの置き場所
pythonファイルがあるディレクトリにaudioというフォルダを作って、その中にダウンロードしたcat1a.mp3を置きます。
任意のフォルダ
  |--audio.py
  |--audio
       |---cat1a.mp3

#ファイル名
ファイル名はaudio.pyとします。

```python:audio.py
import pygame
import time


pygame.mixer.init(frequency=44100)
pygame.mixer.music.load("audio/cat1a.mp3")
pygame.mixer.music.play(1)
time.sleep(2)
pygame.mixer.music.stop()

```

#イヤホンジャックにつないだスピーカーやヘッドホンから音を出したいとき
１）メニューのスピーカーマークを右クリックしてAnalogを選択
だめだったら
２）[ここ](https://qiita.com/Higemal/items/950712475e18a4ae1997)を参考にraspi-configの設定をしてみる
だめだったら、再起動してみる、それでもだめだったら
３）ターミナルで下記のコマンドを実行して、再起動してみる

```
cd /opt/vc/src/hello_pi
./rebuild.sh
```
c++ using使い方の名称まとめ

c++ではusingの使い方がいろいろある。使い方の名称をしらないと検索もかけられないのでそのまとめ。解説リンク付き。

|  名称 |用途|サンプルコード|
|----|----|----|
|[エイリアス宣言<br>型エイリアス<br>エイリアステンプレート](https://docs.microsoft.com/ja-jp/cpp/cpp/aliases-and-typedefs-cpp?view=vs-2019)| 型の別名の定義  |using Int = int;|
|[usingデイレクティブ](https://docs.microsoft.com/ja-jp/cpp/cpp/namespaces-cpp?view=vs-2019)|namespace記述の省略 | using namespace std; |
|[using宣言](https://docs.microsoft.com/ja-jp/cpp/cpp/using-declaration?view=vs-2019)|namespace記述の省略|using std::cout;|
|[using宣言](https://docs.microsoft.com/ja-jp/cpp/cpp/using-declaration?view=vs-2019)|クラスのコンスラタや関数の継承||
SwiftUI Listのグループ化スタイル iOS14対応

## 概要

iOS13、iOS14でグループ化リストを表示する際のTipsです。

## SwiftUIでグループ化されたListを表示

iOS13の**GroupedListStyle()**と、iOS14で追加された**InsetGroupedListStyle()**を切り分けて設定していきます。

### iOS13

SwiftUIでグループ化されたテーブルを表示する場合、iOS13では

```swift
List {
    Text("List Item 1")
    Text("List Item 2")
    Text("List Item 3")
}.listStyle(GroupedListStyle())
```

としていました。

### iOS14

iOS14では、**InsetGroupedListStyle()**を使用して

```swift
List {
    Text("List Item 1")
    Text("List Item 2")
    Text("List Item 3")
}
.listStyle(InsetGroupedListStyle())
```

とします。

### iOS13/iOS14 両方対応

使い易いようにViewを拡張して

```swift
extension View {
    func iOS14Coordinator_ListStyle() -> some View {
        Group{
            if #available(iOS 14, *) {
                self
                    .listStyle(InsetGroupedListStyle())
            }else{
                self
                    .listStyle(GroupedListStyle())
            }
      }
    }
}
```

以下のように使います。

```swift
List {
    Text("List Item 1")
    Text("List Item 2")
    Text("List Item 3")
}
.iOS14Coordinator_ListStyle()
```

---

[https://developer.apple.com/documentation/swiftui/insetgroupedliststyle](https://developer.apple.com/documentation/swiftui/insetgroupedliststyle)
[https://developer.apple.com/documentation/swiftui/groupedliststyle](https://developer.apple.com/documentation/swiftui/groupedliststyle)
射撃

#要約
カッコいい射撃にしたいけど、やり方すぐに忘れるから、備忘録作る!!


####カッコいい射撃とは？
銃口から、火花飛び散る
なんかすごいサウンドが出る
連射すると、射線が分かる
当たったところに爆風とか、火花がある


###1.銃口から火花のエフェクト
武器の銃口部分を基準にエフェクトを発生させる。


###2.銃声のサウンド
弾が出るタイミングでエフェクトを再生する


###3.連射と射線
クリックしている間、Onになって、Onの間は射撃を繰り返す。
弾自体が若干発光することで、銃弾が飛んでいく方向が分かるようにする


###4.当たり判定
弾が当たった箇所でエフェクトを発生させる
当たった箇所を参照して、『1.銃口から火花のエフェクト』と同じ様にエフェクトを発生させる
戦術機シミュレーター作ってみる

注釈：この記事は編集中のため、内容がほぼありません。

##目次
<details><summary>目次<summary>
要約（この記事の目的）
一章　自機に関る機能
二章　NPCの機能
三章　LEVELの機能
四章　操作系統の拡張
五章　操作系統以外の拡張
六章　追加したい機能（やりたい）
</details>


#要約
前置き
本記事は各機能についての備忘録として使用します。
機能別に分けるので、真似したいと思ったら、勝手に使ってくださいｗ
記事の内容は順次追加予定です。

(´・ω:;.:...そんなにカッコいいこと記事に出来るかわからないけど……

<br/>
<br/>
<br/>

マブラヴって良いよね、二次創作のマブラヴTSFをプレイしたい
数年後
猫「え、開発サークル解散したの？」

公式「20thイベントやるよ」
某きた○おう氏「プレゼン面倒なので、作ってみました」
よく訓練された衛士達「うぉぉぉ!!」
公式「新作出すね」
よく訓練された衛士達「うぉぉぉ!!」


猫「あれ、FPS視点の作品無いね。作ろう」
※その旧TSF開発サークルの元メンバーが密かに開発しているとも聞くが、待ちきれないので自作するに至る

#一章　自機に関る機能
<dl>
  <dt>1. 移動</dt>
基本的な<a href="https://qiita.com/NEKOGAMIJINJYA/items/13dfed6824a45002205e">移動</a>は二種類
・徐々に加速するジェット移動
　この移動方法はWASDを押し続けると、一定速度まで移動速度が上がる。
・瞬間的に加速するロケット移動
　この移動方法はWASDをダブルクリックした際に発動する。
　ジェット移動をしながら、ロケット移動をすると、緊急回避の様な用法を想定している。
</dd>
<dt>2. 攻撃</dt>
FPS視点による<a href="https://qiita.com/NEKOGAMIJINJYA/items/71febd0cbf942ffc8490">射撃</a>を行う。
カッコいいエフェクト付ける。
銃撃っぽい音がする。
ボタンを押し続ける限り、連射する。
リロードを行う等
<br>
<dd>打撃</dd>※射撃を優先するので、打撃による攻撃は後回しになります。


<dt>3. UI</dt><dd/>
基本的なUIは本家マブラヴをUIを~~パクリ~~できるだけ再現します。 
再現と言っても、技術不足の現状では見た目だけの再現なのか、UIの動きまで再現出来るのかは不明です。
見た目は雰囲気を上げるには重要なことなのですが、衛士の育成によるBETAの殲滅が最優先事項です。
その為、こちらも~~後回しする~~遅れる可能性が高いです。


#二章　NPCの機能
1. BETAについて
1. AI
1. BETA以外のNPCについて

#三章　LEVELの機能
１．MAP

#四章　操作系統の拡張
1. 武装交換
1. 武装のAI化<br>
これは武装が自動的に敵NPCを射撃する機能、自動ロックオンの様な機能です。
1. 友軍機への指示(AI系)

#五章　操作系統以外の拡張
1. マルチ化
1. 戦闘と戦術

#六章　追加したい機能（やりたい）
1. VR化 
<br>
※酔いが酷すぎる場合、ごく限られたメンバーでのテストプレイで完結する可能性があります。
vue 3.0(One Piece)がリリースされたらしいからリリースノートを読んでみる

## はじめに

vueの勉強をしているとVue.js 3.0がそろそろリリースされるとかされないとかされたとかいう話を耳にします。
勉強始めたてでvueそのものに関してもよくわかってないですが、とりあえずリリースノートを読んでVue3.0ってなんぞやみたいなことを自分なりに学習がてらまとめてみる記事です。

## リリースノートを読んでみる

2020/9/18についにvue.js3.0がリリースされたっぽい。いろいろと情報をまとめてくれていた記事もたくさんあったけど、とりあえず公式の[リリースノート](https://github.com/vuejs/vue-next/releases/tag/v3.0.0)を見てみる。


`This new major version of the framework provides improved performance, smaller bundle sizes, better TypeScript integration, new APIs for tackling large scale use cases, and a solid foundation for long-term future iterations of the framework.`

パフォーマンスの向上、バンドルサイズの縮小、TypeScript統合の改善、大規模なユースケースに取り組むための新たなAPIs、と長期的な将来の反復のための強固な基盤、が提供されるらしい。

一個ずつ詳しく見ていく。

### 大規模なユースケースへの対応

Vue3.0では、Vue2.xのobject-based APIはほとんどそのまま。ただし、Vue3.0では[compositionAPI](https://v3.vuejs.org/guide/composition-api-introduction.html#why-composition-api)が追加されている。CompositionAPIによって、コードの再利用やより信頼性のある型推論、柔軟なコード編成、が可能となる。

Vue2.xでもCompositionAPIを用いることができるplugin([`@vue/composition-api`](https://github.com/vuejs/composition-api))が用意されており、Vue2と3の両方で機能するCompositionAPIユーティリティライブラリ([`vueuse`](https://github.com/antfu/vueuse),[`vue-composable`](https://github.com/antfu/vueuse))も既に存在している。



### バンドルサイズの縮小とパフォーマンスの向上

Vue3.0では、"compiler-informed Virtual DOM"が採用された。
これにより、Vue3はVue2よりも[大幅にパフォーマンスが向上](https://docs.google.com/spreadsheets/u/1/d/1VJFx-kQ4KjJmnpDXIEaig-cVAAJtpIGLZNbv3Lr4CR0/edit?usp=sharing)している。

- バンドルサイズ : 最大41％軽量
- 初期レンダリング : 最大55％高速
- ページの更新 : 最大133％高速
- メモリ使用量 : 最大54％減少

![スクリーンショット 2020-09-30 15.12.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/4ebb5f79-4fb9-088c-bfbe-81aed934d5e3.png)
[](https://docs.google.com/spreadsheets/d/1VJFx-kQ4KjJmnpDXIEaig-cVAAJtpIGLZNbv3Lr4CR0/edit#gid=0)

### TypeScript統合の改善

Vue3.0のコードベースはTypeScriptで記述されており、自動的に生成・テスト・バンドルされた型定義が含まれている。公式のVSCode拡張機能であるVeturは、Vue 3の改善された内部型定義を活用して、テンプレート表現とpropsの型チェックをサポート。

### 実験的な新機能
`Singe-File Components`(`.Vue`)用の二つの新機能が提案された。

- [`<script setup>`](https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-script-setup.md)
    - SFC内にsetupを書かずにCompositionAPIが使えるようになる。
    - SFCではsetupがめちゃくちゃ利用されるので、書かないで済む方が楽だよね的なモチベーションらしい。
- [`<style vars>`](https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-style-variables.md)
    - SFC内のCSS部分で、変数を用いることができるようになる。
    - これまではtemplateで要素にstyleタグをjsから渡していたものを、cssで簡潔に記述可能に。
- `<Suspense>`
    - 非同期処理の完了を、最初のレンダリング時に待機するためのコンポーネント。
    - `v-if: isLoading`みたいなのがいらなくなる。

## まとめ
この記事ではリリースノートを読んでみました。
vue2と3で**下位互換性**があるので、compositionAPIとか使わない人でも**とりあえずvue3にあげれば高速化の恩恵を受けられる**、ということなのかな？？

次の記事では、compositionAPIなど、新たな機能をより深掘っていきます。
SharePoint Framework開発環境の設定方法

１．SharePoint Framework（SPFx）の概要
SPFxは、SharePoint Online モダンサイトに対してJavaScript / CSSでのカスタマイズを導入するための唯一の仕組みです。開発はJavaScriptで行います。

SPFxで開発できるものは以下です。
　・Webパーツ
　・ビューにカスタムのコマンドを追加
　・ビューに表示する列の描画をカスタマイズ
　・サイト全体のヘッダ開発
　・サイト全体のフッタ開発
　・サイト全体にJavaScript / CSSを埋め込む

２．開発環境設定手順
 参考ページ：https://docs.microsoft.com/ja-jp/sharepoint/dev/spfx/set-up-your-development-environment
　①Node.js. を以下のページからインストールする。（.msiファイル）
　　https://nodejs.org/dist/latest-v10.x/
　　※最新バージョンは14.X.Xとなりますが、現在SharePoint Frameworkに対応していないため、10.X.Xの最新バージョンをインストールしてください。
　②Node.js.command promptを管理者として実行する。
　③必要な開発ツールをインストールするために、以下のコマンドを入力する。
　　・npm install yo --global
　　・npm install gulp --global　（Gulp のインストール）
　　・npm install yo --global　（Yeoman のインストール）
　　・npm install @microsoft/generator-sharepoint --global　（Yeoman の SharePoint ジェネレーターをインストール）
　④SharePoint のクライアント側の最初の Web パーツを作成する。
　　参考ページ：https://docs.microsoft.com/ja-jp/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part
　（例）以下のWebパーツを作成すると、「HelloWorld」と表示される。
　　Ⅰ．任意の場所に以下のコマンドを使用してディレクトリを作成する。
　　　md helloworld-webpart
　　Ⅱ、Ⅰで作成したディレクトリに移動する。
　　　cd helloworld-webpart
　　Ⅲ．YeomanのSharePointジェネレーターを実行して、新しいHelloWorldのWeb パーツを作成する。
　　　yo @microsoft/sharepoint
　　Ⅳ．ダイアログ ボックスが表示されるので、今回は以下で対応する。
　　　・What is your solution name?
　　　　→helloworld-webpart
　　　・Which baseline packages do you want to target for your component(s)? 　　　　
       →SharePoint Online only (latest)
　　　・Where do you want to place the files? 
　　　　→Use the current folder
　　　・Do you want to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment or adding apps in sites? 
　　　　→No
　　　・Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant? 
　　　　→No
　　　・Which type of client-side component to create? 
　　　　→WebPart
　　　・What is your Web part name? 
　　　　→HelloWorld
　　　・What is your Web part description? 
　　　　→HelloWorld description
　　　・Which framework would you like to use? 
　　　　→No JavaScript framework
　⑤開発者用自己署名証明書を以下のコマンドで取得する。
　　・gulp trust-dev-cert
　　※SharePoint Framework Yeomanジェネレーターでプロジェクトが作成された後、プロジェクトのルート フォルダー内で行う。
　⑥以下のコマンドを入力して、開発環境を開く
　　・gulp serve
　　![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699286/c47c8c75-3da1-49ed-15df-15416cc89585.png)
【私的まとめ】package.jsonについて

#違い
###package.json
- インストールしたいパッケージ情報の一覧

###package-lock.json
- 実際にインストールされているパッケージ情報の一覧
- package.jsonに変更があったときに自動で変更される

#バージョン表記
##チルダ`~`

`~1.2.3` → 1.2.3 <= version <= 1.3.0
`~1.2` → 1.2.x
`~1` → 1.x

##キャレット`^`
一番左のバージョンは固定
それ以外は許容

`^1.2.3` := `1.2.3 <= version < 2.0.0`
`^0.2.3` := `0.2.3 <= version < 0.3.0`
`^0.0.3` := `0.0.3 <= version < 0.0.4`
引用：[package.json のチルダ(~) とキャレット(^)](https://qiita.com/sotarok/items/4ebd4cfedab186355867)





#参考
- [package.json のチルダ(~) とキャレット(^)](https://qiita.com/sotarok/items/4ebd4cfedab186355867)
- [【Node.js】package.jsonとpackage-lock.jsonについて簡単にまとめる](https://qiita.com/risto24/items/18837cc4eef176e8b6c7)
ヘッダーメニューの作り方【基本的なテンプレの型】

無料学習サイトでヒントを元にhtmlとcssを学習したけど、いざゼロからheaderを作成していくとなると(・・?)←こんな状態（笑）

そうならないために初めから型を用意してみました

```html:html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>サイトのタイトル</title>
    <link rel="stylesheet" href="stylesheet.css">
  </head>
  <body>
    <header>
    </header>
  </body>
</html>
```
htmlの型はこんな感じ

では次にcssを見てみましょう

```css:css
/* CSSのリセット（消さないでください） */
html, body,
ul, ol, li,
h1, h2, h3, h4, h5, h6, p,
form, input, div {
  margin: 0;
  padding: 0;
}

body {
  font-family: "Avenir Next", "Hiragino Kaku Gothic ProN W3", sans-serif;
}

li {
  list-style: none;
}
```
以上になります

ここからどんどんカスタマイズしていき理想のサイトを制作していきましょう。
macOS CatalinaでSQL接続をAWS Session Manager経由の踏み台サーバ経由で行う方法


# この記事
macOSをMojaveからCatalinaに変えたのですが
SequelProのmysql接続が同じ設定なのに失敗しました
ちょっとハマったので備忘として残します

## AWS Session Manager
Session Managerとは、ざっくりいうとAWSのIAM認証でインスタンスにログインできるようにする仕組みです
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/what-is-systems-manager.html
NetworkACLやSecurityGroupなどの設定をせずともインスタンスに直接ログインできて便利です
在宅勤務などでIPアドレスを固定できないような場合でもセキュリティが担保できます
Session Managerで踏み台サーバにログインして、そこからDBにアクセスします

## SequelPro
MySQLクライアントとして利用します
SequelACEという後継ソフトが出ていますが、そちらではこの方法で接続ができませんでした
(セキュリティを高めるため？にサンドボックスという仕組みを使っていて、それが仇になっていそうです)

その他TablePlusなども試しましたが駄目で、この方法で接続できるのは確認できる範囲ではSequelProだけでした

## 前提
awscli@2とSessionManagerを公式のやり方で入れました
デフォルトシェルはfishです(bashでも同じ結果になりました)

# 方法
`.ssh/config`に接続設定を書き、そのホスト名をSequelProで指定します
このとき、`export PATH=$PATH:/usr/local/bin`が必要です。(Mojaveではなくても動きました)
Session Managerにパスが通ってないらしく、その場所をパスに加えます

```
Host YOUR_AWESOME_HOST
    HostName        i-0xxxxxxxxxxxxxxx
    Port            22
    IdentityFile    ~/.ssh/YOUR_AWESOME_KEY.pem
    User            ec2-user
    ProxyCommand    sh -c "export PATH=$PATH:/usr/local/bin && /usr/local/bin/aws --region us-west-2 ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p' --profile YOUR_AWESOME_PROFILE"
```
![Screenshot 2020-09-30 16.38.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297723/b1832836-4382-ff79-9904-bd6c1e9661c2.png)
勉強日誌25日目

間違えたところを答え見ずにもう1回解くとなぜかすらすら解けるところがある。
2択で迷うところがあるということ。
もっと確実にいきたい。

正答率　76%(70)

/etc/hostname
Debian系ディストリビューションでホスト名を設定するファイル

/etc/sysconfig/network
RedHat系ディストリビューションでホスト名を設定するファイル

正答率　79%(76)

netstat
有効なネットワーク接続や開いているソケットの情報を表示

netstat -i
ネットワークインターフェースの統計情報を表示

ifconfig eth0
インターフェースのうちeth0の情報を表示する

nc -p 送信元ポート testsv ポート
ncコマンドで送信元ポート番号からtestsvのポート/tcpに接続するコマンド

模擬試験　正答率　90%

/etc/crontab
システムに定期的に実行させたいジョブを設定するファイル

IPv6
16進数、4桁ずつコロン　：で区切って8ブロック
各ブロック先頭の0は省略可、0000は0に省略可能
連続した0000のブロックは1回だけ：：に省略可能（7ブロックになる）

nc -l 8000
Netcatを使って簡易サーバー作成

/etc/hostname
ホスト名のみ表示

/etc/cron.allowがないときは/etc/cron.denyが適用される

digコマンド
指定したホスト名に対するDNSサーバへの登録情報を表示
DNSサーバからデバッグのための詳細な情報を取得できる
accepts_nested_attributes_forで関連モデルの更新をする方法

### やりたいこと
accepts_nested_attributes_forを使い関連モデルの作成、更新も同時にやっている。

作成のタイミングで関連モデルだけは更新したいケースがあった。

### やりかた
https://github.com/rails/rails/issues/7256#issuecomment-93172189
を自分用にかみ砕いてメモしたものです。

Foo (既存の更新) -> Bar (作成) -> Baz (既存の更新)
・Fooは更新
・Barは作成
・Bazは更新
をしたい。

その場合は以下のようにparamsを渡すだけでよい。

```json
{
  foo: {
    id: "foo_id", => fooを更新するにはidを渡す
    ...
    bar_attributes: {
      ...
      baz_id: "baz_id", => bazを更新するにはbaz_idと
      baz_attributes: {
        id: "baz_id",  => idを渡す。
        ...
      }
    }
}
```
Unity スクリプトの実行順序制御　メモ

■属性による制御
　Start等の実行順序を制御できないので、
　クラスに**DefaultExecutionOrder属性** を付けて制御する。

　()の中の数字が小さいほうが優先して実行される、使いすぎると制御しきれなくなりそう

```
[DefaultExecutionOrder(-1)]
public class XXXX : MonoBehaviour
{
}
```

　●参考URL
　https://www.hanachiru-blog.com/entry/2019/04/30/213102

■Project設定による制御

　Project Settings ---> Script Execution Order で設定する。
　ダイアログの上から下の順序でスクリプトは実行され、Default Time 上下に置くことで制御する。

　●参考URL
　https://docs.unity3d.com/ja/2018.4/Manual/class-MonoManager.html
　https://qiita.com/hibiki8229/items/335978e65273a87e8d69


■Default Timeって何？？

　公式リファレンスに定義がなかったので、どのタイミングを指すのかは不明
　Start？？・Awake？？・そういうのとは違う概念？？

　下記の方がいろいろ調査していた。

　●参考URL
　https://qiita.com/ogawa-to/items/f8c26193cacfa3d2d666
テスト文化を定着させた話


# はじめに
自動テストがほとんど整備されていないRailsプロジェクト、かつテスト文化がなかったチームに、約1年ほどかけてテスト文化を根付かせたことについてお話したいと思います。

# 経緯
当プロジェクトは、当初はCIは整備されているものの、テストはわずかに書いてあるのみでメンテナンスされないまま放置されており、CI上でもテストが失敗していることを無視してリリースされてされていました。

ある時、大きめの不具合を起こしてしまい、再発防止を考える上でせっかくCIでテストが回るようになっているのであればということで、本格的にテストを書いていくことをチームで合意しました。


# 当初の方針
とはいえ、「テスト文化」自体がチームにほぼ根付いていない状態だったので、最初からカバレッジを「~~%にする」等の目標は立てませんでした。
また、テストが書かれていないコードにテストを追加していくことはとても骨が折れる作業です。工数もかかり短期間でカバレッジを上げていくのはあまり現実的ではありませんでした。

なのでカバレッジなど数字にこだわるよりも、とりあえずテストを書いてみようということを意識して、最低限のルールをゆるく立てて実行していく方針にしました。


### ゆるーいルール
テストを書いてからコードを書いていく、いわゆるテスト駆動開発をルールにはしませんでした。

最初期に絶対守るべきルールとして定めたのは
『不具合が見つかった箇所については絶対に書く』ということのみです。

また、新規機能・改修した箇所については、合議制でチーム内で書くべきだよねってところを確認し実装していました。

# テストを書き出してから
このように小さな一歩から初めたテストですが、徐々にプロジェクトにテストが実装されていき、おざなりにされていたCIも回るようになりました。

そんな中、いわゆるデグレをテストで防げたという出来事がありました。「
これがいわば成功体験となり、士気が上がりました。
このあたりで具体的に目標カバレッジを80%と定め、動いていくことに。

## ルールの追加
ある程度テストを書くことに慣れてきたこともあり、ここでルールを１つ追加しました。
『Model,Controller,Service,Helperを触った際は、必ずテストを書く』というルールです。

もちろん既存のコードにはほとんどテストが書かれていない状態だったので、初期は開発工数が増大しましたが、各所に合意をとってやっていくことにしました。

# カバレッジの向上
このルールはチームに定着し、1年ほどするとカバレッジが50%以上向上しました。
テストが充実していくにつれて、デグレ・不具合の事前検知ができるようになり、開発時の「安心感」も増していきました。

この頃になると「テストを書くことは当たり前」という意識がメンバーに定着しており、チーム内でテスト文化が形成できた状態になりました。

# 成功した要因
### 問題意識の共有
「より安定したシステムにしたい」という問題意識がチーム内で共有されていたことが成功した一つの要因だと思います。
チームメンバーも他のテストがない大規模PJの経験があったので、その同じ轍を踏みたくないという意識もあったかと。

### 出だしはゆるく
上述のように、最初期は「とりあえず書いてみよう」とゆるく始めたのがよかったのかなと思います。
ガチガチにルール化して始めようとするとどうしてもエネルギーが必要になってくると思います。
そうではなく、はじめの一歩は小さく始めたことが良かったのかと考えています。

### 新規プロジェクトだった
このプロジェクトは開始から1年程度だったので、テストを追加していくことは割と容易だったのかなと思います。
やはりコード規模が大きくなってくると、テストを実装していくのは厳しい道のりになっていくので、、

### 意識づけ
意識づけはかなり徹底しました。テストを書く作業に慣れてないうちはやはり億劫なものです。
コードレビューの際などに常に呼びかけることで意識づけを行い、徐々に文化を形成していけたかなと思います。


# 最後に
このような感じでチームにテスト文化を根付かせて参りました。
少しでも「うちでもテストを書いていきたい」と思っておられる方の参考になれば幸いです。
Laravel 一覧を表示+デバック 

Laravelでブログの一覧を表示する機能を実装していきます。今回はブログの一覧を表示します。
前提条件として、<a href="https://qiita.com/hirotototototo/items/165f9a28b6445daede9a">Blogモデル</a>,<a href="https://qiita.com/hirotototototo/items/689947637042cf5c3284">【Seeders,Factory】を使ったテストデータ</a>が存在することとします。



#流れ
下記の流れに沿ってDB内の情報を表示できるようにします。
**1. Blog Modelを呼び出す
2. controllerからbladeに渡す
3. bladeでブログデータを表示**


##1. Blog Modelを呼び出す + 2.controllerからbladeに渡す
Blogモデルをcontrollerを使って呼び出します。

```php:controller.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Blog;//BlogModelを使っている

class BlogController extends Controller
{
    /*
     *ブログ一覧を表示する
     *
     * @return view
     */
    public function showList()
    {
      $blogs = Blog::all();//ブログの一覧を取得
      return view('blog.list',['blogs' => $blogs]);//ブログの一覧を配列で渡してあげる
    }
}

```

##デバック
Laravelのメソッドでデバックを行ってくれる物があります。こちらを使って上記でDBからどのような情報が送られてきたのかを確認してみましょう。コマンドは以下になります。

```php
dd(確認したい変数名);
```
上記のコマンドで変数の中身を確認してくれます。またこのコマンドを記載した場所で処理を止めてくれます。

```php:controller.php
public function showList()
    {
      $blogs = Blog::all();
      dd($blogs);//ここで処理を止めて中身を確認してくれる
      return view('blog.list',['blogs' => $blogs]);
    }
```
localhostにアクセスすると、このように表示してくれます。一つ一つの詳細もクリックすると表示してくれます。中身が確認できたら、`dd();`は」削除しておきましょう。
![image.png](https://i.gyazo.com/809eca6ae439ed80d2f2cbc296ec8dbe.png)


##Bladeで表示する
取得した値をforeach文で表示していきます。上のリストのように情報が入るように実装していきます。先ほどのモデルクラスはオブジェクトになりますので、アロー演算子を使って（id,update_at,title,content）を呼び出していきます。

```php:blade.blog.php
<tr>
                <th>記事番号</th>
                <th>日付</th>
                <th>タイトル</th>
                <th></th>
            </tr>
            @foreach($blogs as $blog)
            <tr>
                <td>{{ $blog->id }}</td>
                <td>{{ $blog->update_at}}</td>
                <td>{{ $blog->title }}</td>
                <td>{{ $blog->content }}</td>
            </tr>
            @endforeach
```
以上で以下のように表示されると思います。
![image.png](https://i.gyazo.com/ad01e4219e98119f1a6b3dc52f31284d.png)


#終わりに
参考サイト
https://techacademy.jp/magazine/19296
https://www.youtube.com/watch?v=Flz9J7ojNdk
CodeDeployで、Installが延々と続いて終わらない



CodeDeployで、たまにエラーも出ず、Installが延々と続いて終わらない、という現象が発生することがあります。

エラーが出ないと割とパニくると思うのでかなり軽い内容なのですが、記事にします。

自分にもこの事象は何度か起きたのですが、

1. CodeDeployのIAM Roleに必要な権限がない
2. コンテナの設定ファイルにミスがあるなど、起動できない状態のコンテナをデプロイしようとしている

自分の場合は、いずれもこの2つのどれかが原因でした。

## 事例

参考までに、直近で自分が経験したInstallが延々と続いて終わらない事態について紹介します。

Fargateで、サイドカー構成でfluent-bitのコンテナとFireLensを使って他のコンテナのログをfirehoseに送ろうとした時、以下の制約に気づかず、

>カスタム設定ファイルを使用する場合は、FireLens が使用するパスとは異なるパスを指定する必要があります。Amazon ECS では /fluent-bit/etc/fluent-bit.conf (Fluent Bit) と /fluentd/etc/fluent.conf (Fluentd) のファイルパスは予約されています。

```Dockerfile
FROM amazon/aws-for-fluent-bit:2.1.1

COPY conf/fluent-bit/fluent-bit.conf /fluent-bit/etc/fluent-bit.conf
```

このように予約されたパスに設定ファイルを置いてしまっているDockerfileから作成したイメージをデプロイしようとしていたため、

もしくは

この設定ファイルは、中身はカスタム設定ファイルで普通の設定ファイルとしては不十分だったのが原因だった

ということがInstallが終わらなかった原因として考えられます。

対策として、

- ローカルでコンテナが動くかちゃんと確認する
- ローカルで動いているなら、IAM周りを見直す

くらいでしょうか。

エラーが出ないので初めてこの現象に陥ると結構焦るかと思うのですが、この記事をきっかけに大体の検討をつけられるようになって解決へと繋がれば幸いです。
ls

ディレクトリとファイル一覧が確認できる。

```
# ls ディレクトリ名
```

ls -la で、名前が . で始まるファイル・ディレクトリも表示される。

```
# ls -la ディレクトリ名
```

ファイルサイズをわかりやすく表示させる時は -h オプションをつける。

```
# ls -lah
-rw-r--r-- 1 miisuke wheel   202 Jul  5 15:32 apache-playbook.yml
-rw-r--r-- 1 miisuke wheel  8.7M Jul  1 20:46 apache-tomcat-8.0.24.tar.gz
drwxr-xr-x 2 miisuke wheel  4.0K Jul  4 10:20 backup
```

タイプスタンプ順にソートさせて表示する時は -t オプションをつける。

```
# ls -laht
-rw------- 1 miisuke miisuke 1.1K Jul 26 10:23 .bash_history
drwx------ 7 miisuke miisuke 4.0K Jul 12 05:53 .
-rw-r--r-- 1 miisuke miisuke    0 Jul 11 14:33 copy
```

逆順にソートして表示させる時は -r オプションをつける。

```
# ls -lahtr
-rw-r--r-- 1 miisuke miisuke  124 Mar  4 05:16 .bashrc
-rw-r--r-- 1 miisuke miisuke   18 Mar  4 05:16 .bash_logout
drwxr-xr-x 4 root   root   4.0K Jun 20 15:28 ..
```

### 自分がよく使うオプション
更新が古い順に表示させる時は「ls -lahtr」
更新が新しい順に表示させる時は「ls -laht」
単純に一覧を表示させる時は「ls -lah」

### あるディレクトリ配下全てのファイル数を数える

```
# cd <移動先ディレクトリ>
# ls -laR | grep -c '^-'
```
ls の R オプションで、ディレクトリ内を再帰的に表示させる。
grep の c オプションで、条件にマッチした行数を表示する。
この場合は、頭文字が - のものだけカウントしている。
言語処理100本ノック(2020): 39

```py
"""
37. 「猫」と共起頻度の高い上位10語
「猫」とよく共起する（共起頻度が高い）10語とその出現頻度をグラフ（例えば棒グラフなど）で表示せよ．


sentence_list:
[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],

Memo:
    - 共起頻度: https://www.jtp.co.jp/techport/2018-04-18-001/
"""
from collections import defaultdict
from typing import List

import matplotlib.pyplot as plt

import utils

plt.style.use("ggplot")
plt.rcParams["font.family"] = "Hiragino Mincho ProN"  # 日本語対応


def get_co_occurrence(sentence_list: List[List[dict]]) -> list:
    sents = [
        [word["surface"] for word in sent[1:-1]] for sent in sentence_list
    ]  # [['一'], ['吾輩', 'は', '猫', 'で', 'ある', '。']]
    counter = defaultdict(int)

    for sent in sents:
        if "猫" in sent:
            for word in sent:
                counter[word] += 1

    del counter["猫"]

    sorted_counter = {
        k: v for k, v in sorted(counter.items(), key=lambda item: item[1], reverse=True)
    }
    return list(sorted_counter.items())


def plot_co_occurrence(x: list, y: list) -> None:
    x_pos = [i for i, _ in enumerate(x)]

    plt.bar(x, y)
    plt.xlabel("Term")
    plt.ylabel("Frequency")
    plt.title("Co-occurrence with '猫'")

    plt.xticks(x_pos, x)

    plt.show()


sentence_list = utils.read_json("30_neko_mecab.json")
counter = get_co_occurrence(sentence_list)
# [('の', 391), ('は', 272), ('、', 252), ('に', 250), ('を', 232)]

x = [word[0] for word in counter[:10]]
y = [word[1] for word in counter[:10]]
plot_co_occurrence(x, y)
# ![image-20200527193140109](https://raw.githubusercontent.com/LearnXu/images/master/imgs/image-20200527193140109.png)

```
言語処理100本ノック(2020): 38

```py
"""
37. 「猫」と共起頻度の高い上位10語
「猫」とよく共起する（共起頻度が高い）10語とその出現頻度をグラフ（例えば棒グラフなど）で表示せよ．


sentence_list:
[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],

Memo:
    - 共起頻度: https://www.jtp.co.jp/techport/2018-04-18-001/
"""
from collections import defaultdict
from typing import List

import matplotlib.pyplot as plt

import utils

plt.style.use("ggplot")
plt.rcParams["font.family"] = "Hiragino Mincho ProN"  # 日本語対応


def get_co_occurrence(sentence_list: List[List[dict]]) -> list:
    sents = [
        [word["surface"] for word in sent[1:-1]] for sent in sentence_list
    ]  # [['一'], ['吾輩', 'は', '猫', 'で', 'ある', '。']]
    counter = defaultdict(int)

    for sent in sents:
        if "猫" in sent:
            for word in sent:
                counter[word] += 1

    del counter["猫"]

    sorted_counter = {
        k: v for k, v in sorted(counter.items(), key=lambda item: item[1], reverse=True)
    }
    return list(sorted_counter.items())


def plot_co_occurrence(x: list, y: list) -> None:
    x_pos = [i for i, _ in enumerate(x)]

    plt.bar(x, y)
    plt.xlabel("Term")
    plt.ylabel("Frequency")
    plt.title("Co-occurrence with '猫'")

    plt.xticks(x_pos, x)

    plt.show()


sentence_list = utils.read_json("30_neko_mecab.json")
counter = get_co_occurrence(sentence_list)
# [('の', 391), ('は', 272), ('、', 252), ('に', 250), ('を', 232)]

x = [word[0] for word in counter[:10]]
y = [word[1] for word in counter[:10]]
plot_co_occurrence(x, y)
# ![image-20200527193140109](https://raw.githubusercontent.com/LearnXu/images/master/imgs/image-20200527193140109.png)

```
言語処理100本ノック(2020): 37

```py
"""
37. 「猫」と共起頻度の高い上位10語
「猫」とよく共起する（共起頻度が高い）10語とその出現頻度をグラフ（例えば棒グラフなど）で表示せよ．


sentence_list:
[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],

Memo:
    - 共起頻度: https://www.jtp.co.jp/techport/2018-04-18-001/
"""
from collections import defaultdict
from typing import List

import matplotlib.pyplot as plt

import utils

plt.style.use("ggplot")
plt.rcParams["font.family"] = "Hiragino Mincho ProN"  # 日本語対応


def get_co_occurrence(sentence_list: List[List[dict]]) -> list:
    sents = [
        [word["surface"] for word in sent[1:-1]] for sent in sentence_list
    ]  # [['一'], ['吾輩', 'は', '猫', 'で', 'ある', '。']]
    counter = defaultdict(int)

    for sent in sents:
        if "猫" in sent:
            for word in sent:
                counter[word] += 1

    del counter["猫"]

    sorted_counter = {
        k: v for k, v in sorted(counter.items(), key=lambda item: item[1], reverse=True)
    }
    return list(sorted_counter.items())


def plot_co_occurrence(x: list, y: list) -> None:
    x_pos = [i for i, _ in enumerate(x)]

    plt.bar(x, y)
    plt.xlabel("Term")
    plt.ylabel("Frequency")
    plt.title("Co-occurrence with '猫'")

    plt.xticks(x_pos, x)

    plt.show()


sentence_list = utils.read_json("30_neko_mecab.json")
counter = get_co_occurrence(sentence_list)
# [('の', 391), ('は', 272), ('、', 252), ('に', 250), ('を', 232)]

x = [word[0] for word in counter[:10]]
y = [word[1] for word in counter[:10]]
plot_co_occurrence(x, y)
# ![image-20200527193140109](https://raw.githubusercontent.com/LearnXu/images/master/imgs/image-20200527193140109.png)

```
言語処理100本ノック(2020): 36

```py
"""
36. 頻度上位10語
出現頻度が高い10語とその出現頻度をグラフ（例えば棒グラフなど）で表示せよ．

data:
[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],

Memo:
    - matplotlibで日本語を表示
"""
from collections import Counter
from typing import List

import matplotlib.pyplot as plt

import utils

plt.style.use("ggplot")
plt.rcParams["font.family"] = "Hiragino Mincho ProN"  # 日本語対応


def get_tf(sentence_list: List[List[dict]]) -> list:
    words = [word["surface"] for sent in sentence_list for word in sent[1:-1]]
    c = Counter(words)
    return c.most_common()


def plot_tf(x: list, y: list) -> None:
    x_pos = [i for i, _ in enumerate(x)]

    plt.bar(x, y)
    plt.xlabel("Term")
    plt.ylabel("Frequency")
    plt.title("TF Graph")

    plt.xticks(x_pos, x)

    plt.show()


data = utils.read_json("30_neko_mecab.json")
counter = get_tf(data)
# [('の', 9194), ('。', 7486)]

x = [word[0] for word in counter[:10]]
y = [word[1] for word in counter[:10]]
plot_tf(x, y)
# ![image-20200527192929567](https://raw.githubusercontent.com/LearnXu/images/master/imgs/image-20200527192929567.png)

```
言語処理100本ノック(2020): 35

```py
"""
35. 単語の出現頻度
文章中に出現する単語とその出現頻度を求め，出現頻度の高い順に並べよ．

[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
"""
from collections import Counter
from typing import List

import utils


def get_tf(sentence_list: List[List[dict]]) -> dict:
    words = [word["surface"] for sent in sentence_list for word in sent[1:-1]]
    c = Counter(words)
    return c.most_common()


data = utils.read_json("30_neko_mecab.json")
result = get_tf(data)
# [('の', 9194),
#  ('。', 7486),
#  ('て', 6868),
#  ('、', 6772),
#  ('は', 6420),
#  ('に', 6243),
#  ('を', 6071),
#  ('と', 5508),
#  ('が', 5337),
#  ('た', 3988)]

```
言語処理100本ノック(2020): 34

```py
"""
33. 「AのB」Permalink
2つの名詞が「の」で連結されている名詞句を抽出せよ

[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
"""
import itertools
from typing import List

import utils


def get_none_phase(sentence: List[dict]) -> List[str]:
    result = []
    for i, word in enumerate(sentence):
        if (
            word["surface"] == "の"
            and sentence[i - 1]["pos"] == "名詞"
            and sentence[i + 1]["pos"] == "名詞"
        ):
            result.append(sentence[i - 1]["surface"] + "の" + sentence[i + 1]["surface"])
    return result


data = utils.read_json("30_neko_mecab.json")
none_phases = [get_none_phase(sentence) for sentence in data]
# In [75]: none_phases[:10]
# Out[75]: [[], [], [], [], [], [], [], [], [], ['彼の掌']]
flat = list(itertools.chain(*none_phases))
# ['彼の掌', '掌の上', '書生の顔', 'はずの顔', '顔の真中']

```
言語処理100本ノック(2020): 33

```py
"""
33. 「AのB」Permalink
2つの名詞が「の」で連結されている名詞句を抽出せよ

[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
"""
import itertools
from typing import List

import utils


def get_none_phase(sentence: List[dict]) -> List[str]:
    result = []
    for i, word in enumerate(sentence):
        if (
            word["surface"] == "の"
            and sentence[i - 1]["pos"] == "名詞"
            and sentence[i + 1]["pos"] == "名詞"
        ):
            result.append(sentence[i - 1]["surface"] + "の" + sentence[i + 1]["surface"])
    return result


data = utils.read_json("30_neko_mecab.json")
none_phases = [get_none_phase(sentence) for sentence in data]
# In [75]: none_phases[:10]
# Out[75]: [[], [], [], [], [], [], [], [], [], ['彼の掌']]
flat = list(itertools.chain(*none_phases))
# ['彼の掌', '掌の上', '書生の顔', 'はずの顔', '顔の真中']

```
言語処理100本ノック(2020): 32

```py
"""
32. 動詞の原形
動詞の原形をすべて抽出せよ

[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
"""

import itertools
from typing import List

import utils


def get_verb(sentence: List[dict]) -> List[str, str]:
    result = []
    for word in sentence:
        if word["pos"] == "動詞":
            result.append(word["base"])
    return result


data = utils.read_json("30_neko_mecab.json")
verbs = [get_verb(sentence) for sentence in data if get_verb(sentence)]
# [['生れる', 'つく'], ['する', '泣く', 'する', 'いる'], ['始める', '見る'], ['聞く'], ['捕える', '煮る', '食う']]

flat = list(itertools.chain(*verbs))
# ['生れる', 'つく', 'する', '泣く', 'する']

```
言語処理100本ノック(2020): 31

```py
"""
31. 動詞
動詞の表層形をすべて抽出せよ．

[[{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
 [{'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'},
  {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'},
  {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'},
  {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'},
  {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'},
  {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'},
  {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'},
  {'surface': '', 'base': '*', 'pos': 'BOS/EOS', 'pos1': '*'}],
"""

import itertools
from typing import List

import utils


def get_verb(sentence: List[dict]) -> List:
    result = []
    for word in sentence:
        if word["pos"] == "動詞":
            result.append(word["surface"])
    return result


data = utils.read_json("30_neko_mecab.json")
verbs = [get_verb(sentence) for sentence in data if get_verb(sentence)]
# [['生れ', 'つか'], ['し', '泣い', 'し', 'いる'], ['始め', '見'], ['聞く'], ['捕え', '煮', '食う']]
flat = list(itertools.chain(*verbs))
#  ['生れ', 'つか', 'し', '泣い', 'し']

```
言語処理100本ノック(2020): 30




```py
"""
30. 形態素解析結果の読み込みPermalink
形態素解析結果（neko.txt.mecab）を読み込むプログラムを実装せよ．
ただし，各形態素は表層形（surface），基本形（base），品詞（pos），品詞細分類1（pos1）をキーとするマッピング型に格納し，
1文を形態素（マッピング型）のリストとして表現せよ．第4章の残りの問題では，ここで作ったプログラムを活用せよ．

- `neko.txt.mecab` は`ans30.sh`で作成された。
- これからの質問は`30_neko_mecab.json`を使う


品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音
['名詞', '代名詞', '一般', '*', '*', '*', '吾輩', 'ワガハイ', 'ワガハイ']
"""

from typing import List

import MeCab

import utils


def read_file(path: str) -> List[str]:
    data = []
    with open(path) as f:
        for line in f:
            line = line.strip()
            if line != "":
                data.append(line)
    return data


def parse(sent: str) -> List[str]:
    node = tagger.parseToNode(sent)
    result = []
    while node:
        node_dic = {}
        features = node.feature.split(",")
        node_dic["surface"] = node.surface  # 表層形（surface）
        node_dic["base"] = features[6]  # 基本形（base）
        node_dic["pos"] = features[0]  # 品詞（pos）
        node_dic["pos1"] = features[1]  # 品詞細分類1（pos1）
        result.append(node_dic)
        node = node.next
    return result


file_path = "neko.txt"
data = read_file(file_path)
# ['一', '吾輩は猫である。', '名前はまだ無い。', 'どこで生れたかとんと見当がつかぬ。']

tagger = MeCab.Tagger("-r /usr/local/etc/mecabrc")
result = [parse(sent) for sent in data]

# ans30
utils.save_json(result, "30_neko_mecab.json")
data = utils.read_json("30_neko_mecab.json")

```

`utils.py`:

```py
import itertools
import json
from typing import Any, List


def save_json(data: Any, save_path: str) -> None:
    """Save data to json format.
    Args:
        data (Any): The data to store.
        save_path (str): Path to save.
    """
    with open(save_path, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)


def read_json(path: str) -> List[Any]:
    """Read json data
    Args:
        path (str): Path of file to read.
    Returns:
        List[Any]: FTSE entity data.
    """
    with open(path, "r", encoding="utf-8") as f:
        data = json.load(f)
    return data


def flat(sequence: List[List[Any]]) -> List[Any]:
    return list(itertools.chain(*sequence))

```
Yay! I'm on Rails! Repetition

# はじめに
n回目の`Ruby on Rails`記念です。
# on Rails!
![20200930.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/c50bbf37-c37d-9f06-a50e-c662f7e58494.png)
# 環境
```ubuntu.bash
$ uname -a
Linux ubuntu 5.4.0-48-generic #52-Ubuntu SMP Thu Sep 10 10:58:49 UTC 2020 x86_64 X86_64 X86_64 GNU/Linux
```
今回は、
`windows10`上の`VirtualBox`上の`Ubuntu`
# 嵌ったところ
例によって`sqlite`で引っ掛かりますが、前回経験済みですので大丈夫。
*[前回 - Qiita](https://qiita.com/superrino130/items/ad5179e825c23204db2f)*

## spring
```spring.not
bundler: command not found: spring
```
今回は、`spring`で嵌りました。

```Gemfil.e
  gem 'spring'
  gem 'spring-watcher-listen'
```
`group :development`なので、上記行を削除して対応。

なお、ホストOSからアクセスする場合、VirtualBoxでネットワーク設定を変更する必要があります。
![20200930a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/a7d6e019-154a-76af-8f33-f825d2811e3e.png)

# まとめ
+ VirtualBox に詳しくなった
+ spring で嵌った

参照したサイト
*[Ruby 歴 10 年の私が【絶対に】 gem install rails コマンドを実行しない理由 - Qiita](https://qiita.com/kaishuu0123/items/2a91495e7daa8c7783ed)*
*[Yay! I'm on Rails! - Qiita](https://qiita.com/superrino130/items/ad5179e825c23204db2f)*
言語処理100本ノック(2020): 26

```py
"""
26. 強調マークアップの除去
25の処理時に，テンプレートの値からMediaWikiの強調マークアップ（弱い強調，強調，強い強調のすべて）を除去してテキストに変換せよ（参考: マークアップ早見表）．
"""

import json
import re

import utils


def get_uk_text(path):
    with open(path) as f:
        for line in f:
            line_data = json.loads(line)
            if line_data["title"] == "イギリス":
                data = line_data
                break
    return data["text"]


def get_basic_info(string: str) -> str:
    """Get basic information section
    """
    pattern = re.compile(
        r"""
            ^\{\{基礎情報.*?$   # '{{基礎情報'で始まる行
            (.*?)       # キャプチャ対象、任意の0文字以上、非貪欲
            ^\}\}$      # '}}'で終わる行
        """,
        re.MULTILINE | re.DOTALL | re.VERBOSE,
    )

    return re.findall(pattern, string)[0]


def get_content(string: str) -> list:
    r"""
    https://docs.python.org/3/library/re.html#regular-expression-syntax

    RE:
        - re.X (re.VERBOSE)     Allow us add command to explain the regular expression
        - re.M (re.MULTILINE)   Apply match to each line. If not specified, only match the first line.
        - re.S (re.DOTALL)      Allow to recognize '\n'
        - ^\|       String begin with |
        - ?         Causes the resulting RE to match 0 or 1 repetitions

        - *?        The '*' qualifier is greedy.
                    Adding ? after the qualifier makes it perform the match in non-greedy or minimal fashion; as few characters as possible will be matched.
                    e.g. <.*> is matched against '<a> b <c>'
                    e.g. <.*?> will match only '<a>'

        - (...)     Matches whatever regular expression is inside the parentheses,
        - (?=...)   Matches if ... matches next, but doesn’t consume any of the string. This is called a lookahead assertion.
                    For example, Isaac (?=Asimov) will match 'Isaac ' only if it’s followed by 'Asimov'.
        - (?:...)   A non-capturing version of regular parentheses.

    Input:
        - '|国章リンク =（[[イギリスの国章|国章]]）'
    Return:
        - {'国章リンク': '（[[イギリスの国章|国章]]）'}
    """
    pattern = re.compile(
        r"""
            ^\|
            (.+?)
            \s*
            =
            \s*
            (.+?)
            (?:
                (?=\n\|)
                |
                (?=\n$)
                )
            """,
        re.MULTILINE | re.DOTALL | re.VERBOSE,
    )
    result = re.findall(pattern, string)
    return {k: v for k, v in result}  # dict is ordered when using python 3.7


def remove_markup(text: str) -> str:
    pattern = re.compile(
        r"""
            \'{2,5} # 2〜5個の'
        """,
        re.VERBOSE,
    )

    return re.sub(pattern, "", text)


uk_text = get_uk_text("jawiki-country.json")  # See uk_text.txt

# ans25
basic_info = get_basic_info(uk_text)
fields = get_content(basic_info)  # See 25_en_basic_info.json

# ans26
result = {k: remove_markup(v) for k, v in fields.items()}
utils.save_json(result, "26_no_markup.json")
# ('確立形態4', "現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更")
# ->
# ('確立形態4', '現在の国号「グレートブリテン及び北アイルランド連合王国」に変更')

```
言語処理100本ノック(2020): 25

```py
"""
25. テンプレートの抽出
記事中に含まれる「基礎情報」テンプレートのフィールド名と値を抽出し，辞書オブジェクトとして格納せよ．
"""

import json
import re

import utils


def get_uk_text(path):
    with open(path) as f:
        for line in f:
            line_data = json.loads(line)
            if line_data["title"] == "イギリス":
                data = line_data
                break
    return data["text"]


uk_text = get_uk_text("jawiki-country.json")
# See uk_text.txt


# ans24
def get_basic_info(string: str) -> str:
    """Get basic information section
    """
    pattern = re.compile(
        r"""
            ^\{\{基礎情報.*?$   # '{{基礎情報'で始まる行
            (.*?)       # キャプチャ対象、任意の0文字以上、非貪欲
            ^\}\}$      # '}}'で終わる行
        """,
        re.MULTILINE | re.DOTALL | re.VERBOSE,
    )

    return re.findall(pattern, string)[0]


def get_content(string: str) -> list:
    r"""
    https://docs.python.org/3/library/re.html#regular-expression-syntax

    RE:
        - re.X (re.VERBOSE)     Allow us add command to explain the regular expression
        - re.M (re.MULTILINE)   Apply match to each line. If not specified, only match the first line.
        - re.S (re.DOTALL)      Allow to recognize '\n'
        - ^\|       String begin with |
        - ?         Causes the resulting RE to match 0 or 1 repetitions

        - *?        The '*' qualifier is greedy.
                    Adding ? after the qualifier makes it perform the match in non-greedy or minimal fashion; as few characters as possible will be matched.
                    e.g. <.*> is matched against '<a> b <c>'
                    e.g. <.*?> will match only '<a>'

        - (...)     Matches whatever regular expression is inside the parentheses,
        - (?=...)   Matches if ... matches next, but doesn’t consume any of the string. This is called a lookahead assertion.
                    For example, Isaac (?=Asimov) will match 'Isaac ' only if it’s followed by 'Asimov'.
        - (?:...)   A non-capturing version of regular parentheses.

    Input:
        - '|国章リンク =（[[イギリスの国章|国章]]）'
    Return:
        - {"国章リンク": "（[[イギリスの国章|国章]]）"}
    """
    pattern = re.compile(
        r"""
            ^\|         # '|'で始まる行
            (.+?)       # キャプチャ対象（フィールド名）、任意の1文字以上、非貪欲
            \s*         # 空白文字0文字以上
            =
            \s*         # 空白文字0文字以上
            (.+?)       # キャプチャ対象（値）、任意の1文字以上、非貪欲
            (?:         # キャプチャ対象外のグループ開始
                (?=\n\|)    # 改行+'|'の手前（肯定の先読み）
                |           # または
                (?=\n$)     # 改行+終端の手前（肯定の先読み）
            )               # グループ終了
            """,
        re.MULTILINE | re.DOTALL | re.VERBOSE,
    )
    result = re.findall(pattern, string)
    return {k: v for k, v in result}  # dict is ordered due to python 3.7


basic_info = get_basic_info(uk_text)
# print(basic_info[-100:])
# |国際電話番号 = 44
# |注記 = <references/>

result = get_content(basic_info)
utils.save_json(result, "25_en_basic_info.json")

for r in result.items():
    print(r)
# ('略名', 'イギリス')
# ('日本語国名', 'グレートブリテン及び北アイルランド連合王国')
# ...
# ('国際電話番号', '44')
# ('注記', '<references/>')

```