OmniAICreator/Qiita-1.07M huggingface dataset:
[K8s] サービスタイプ NodePort 動作確認

## 概要

本投稿はK8sのサービス機能の一つである `NodePort` の動作確認を行った際の個人メモです。

## 前提条件

* MacOSにminikube、kubectlがインストールされていること。
* K8sクラスタが既に起動していること

```
$ minikube start
```

## サービスとは

`サービス`とは一時的な存在であり永続的なIPアドレスを持たないポッドに対し、クライアントがアクセスするためのオブジェクトです。
以下記事でデプロイメントまでの動作確認を行っているため、今回は外部からpodに対してアクセスできるか確認を行います。

https://qiita.com/hrtkjm/items/9b017d5e7d367dc8339b

サービスには以下のようなタイプがありますが、今回は`NodePort`を使用します。

|サービスタイプ|アクセス可能範囲と手段 |
|---|---
|ClusterIP| ポッドネットワーク上のポッドから、内部DNSに登録された名前でアクセスできる。|
|NodePort |CluterIPに加え、K8sの外部クライアントのノードのIPとポートを指定することでアクセスできる
| LoadBalancer| NodePortのアクセス範囲に加え、K8sクラスタ外のクライアントも代表アドレスとプロトコルのデフォルトポートを使用してアクセスできる
| ExternalName | K8sクラスタ内のポッドネットワーク上のクライアントから、外部のIPアドレスを名前でアクセスできる。

## NodePortのマニフェスト

nginxのpodを起動させるためのデプロイメント用と、サービス用でファイルを分けています。

```deploy.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: web-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:latest
```

```service-np.yml
apiVersion: v1
kind: Service
metadata:
  name: web-service-np
spec:
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
  type: NodePort # NodePortを指定
```

## デプロイと動作確認

サービスの確認を行うと、32496ポートにマッピングしていることがわかります。
公開用のポート番号は、デフォルトで30000~32767です。

```
$ kubectl apply -f deploy.yml
deployment.extensions/web-deploy configured
$ kubectl apply -f service-np.yml
service/web-service-np created
$ kubectl get service
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes       ClusterIP   10.0.0.1     <none>        443/TCP        16d
web-service-np   NodePort    10.0.0.56    <none>        80:32496/TCP   30s
```

クラスタのIPを確認後、使用している端末からnginxのhtmlにアクセスできるか確認します。

```
$ minikube ip
192.168.99.100
$ curl 192.168.99.100:32496
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

サービスを使用することで、ポッドに外部からアクセスできることが確認できました。
NodePortはお手軽に動作確認ができて便利ですが、本番運用向きではないためご注意を。
Twitterカードの設定方法

自分が運営しているサイトの記事をTwitterでこんな風にリンクしてみたくないですか？
![IMG_2232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116361/66603f3f-7740-ce10-f574-626d8dde9611.png)
↑こんな感じに。これはTwitterカードと言い、一言でいうと「画像付きリンク情報」になります。
今から、どうすればTwitterカードを設定できるのか、説明していきます。
#Twitterカードとは
Twitterカードとは、設定していない場合は次のようになります。
![IMG_2233.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116361/836e9c52-73ff-b4c8-c4fd-493140fb647f.png)
それに対して Twitter カードが設定されている場合は次のようになります。
![IMG_2232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116361/3d94af5e-016b-9bc1-e3de-81077cc68312.png)
やはり、Twitterカードが設定されている方がクリックしたくなりますよね。
#Twitterカードの4種類ある
**Summary Card**
サマリーカードは小さめの画像と記事のタイトルおよび概要を表示できる、Twitterカードです。
![IMG_2234.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116361/fef18a32-d3aa-da20-a583-a502d415c724.png)
**Summary Card with Large Image**
大きな画像付きサマリーカードは大きめの画像と記事のタイトルおよび概要を表示できる、Twitterカードです。
![IMG_2232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116361/5d8828c1-56f6-f0c1-e112-0da491e2bfd5.png)
**App Card**
アプリ用のカードです。アプリのダウンロードページへのリンクを表示する、Twitterカードが表示されます。アプリ用なので今回は省略します。
**Player Card**
動画を配信しているサイト向けのTwitterカードです。ツイートに表示されたカード上で動画のダイジェストなどを再生することができます。動画用なので今回は省略します。
#metaタグに記載する
```
<meta name="twitter:card" content="1.カードの種類">
<meta name="twitter:site" content="2.Twitterのユーザー名">
<meta name="twitter:title" content="3.記事のタイトル">
<meta name="twitter:description" content="4.記事の概要">
<meta name="twitter:image" content="5.カードに表示する画像のURL">
```
1.「カードの種類」には 
Summary Card の場合 ⇒ **summary**
Summary Card with Large Image の場合 ⇒ **summary_large_image**
を指定します。

2.「Twitter のユーザー名」には 
Twitterアカウントのユーザー名を@に続けて入力するだけです

3.「記事のタイトル」には
Twitterカードを設定するページの記事のタイトルを指定します。

4.「記事の概要」には
Twitterカードを設定するページの記事の概要を指定します。文字数に制限はありませんが、定められた文字数以上の値は省略されます。

5.カードに表示する画像のURLには 
Twitterカードに表示される画像が設置されているURLを指定します。

#最後に
ツイートにurlを記載するだけで、このようになります。
![IMG_2232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116361/8f8ea8a0-b338-86a8-8fa3-8fabfdc7cafe.png)

今回の記事を見てくれてありがとうございます。
最後に自分のNewsサイトでも、Twitterカードを使って、記事の宣伝をしているので、もし良かったら見てください。
[NewsTweet｜Twitterで注目されているニュースが分かる](http://newstweet.jp)

**お世話になったリンク**
[【2020年版】Twitterカードとは？使い方と設定方法まとめ](https://saruwakakun.com/html-css/reference/twitter-card)
[Twitterカードの使い方と設定方法](https://www.howtonote.jp/twitter/helpful/index5.html)
Laravel の Collection で多次元配列の最初or最後の値を得る

 Laravelで多次元配列の最初or最後の要素を取得する方法をシェアします。

次のようにpluckメソッドで指定したキーの全コレクション値を取得し、first()をチェーンでつなぎ、最初の値を取得できます。

```
$collection = collect([
    ['id' => '001', 'name' => '鈴木'],
    ['id' => '002', 'name' => '山田'],
    ['id' => '003', 'name' => '田中'],
    ['id' => '004', 'name' => '佐藤'],
]);

echo $collection->pluck('name')->first();　// 鈴木

echo $collection->pluck('name')->last();　// 佐藤

```

## 参考

https://readouble.com/laravel/5.8/ja/collections.html#method-pluck
誤った情報をpushしてしまった時の対処法

#この記事で分かること
* 誤った情報をpushしてしまった
* 誤った情報をcommitしてしまった

#誤った情報をpushしてしまった
pushした情報をローカルリポジトリに戻すことはできません。したがって、pushする前に作業をしているブランチは正しいのかどうか、必ず確認するようにしましょう。
それでも間違ってpushしてしまうことがあります。ローカルリポジトリにその情報は戻せないものの、リモートリポジトリにある誤ったcommit情報は取り消すことができます


#commitを取り消す方法
![cbe00f28b88d5f18b9c71024034afe3d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/653892e4-735a-56d7-c811-47569363c1df.png)

commitを取り消すためには、revertと呼ばれる技術を用います
間違ってpushしたcommitを取り消すことができます。commitを削除するのではなく、「指定するcommitを取り消すためのcommit」を追加で行います。
revertはcommitされた変更と逆になる変更を追加することで、commitを取り消します

#誤った情報をcommitしてしまった
![83c821f4a185cf767e80dcde53e109da.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/945bb23d-d342-fbf5-5a34-334b1a4fc6e5.png)
#現場からは以上です！
[Rails] find と find_by の違い

この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
findとfind_byについて曖昧なところがあったので、自分なりにまとめてみました。

#find
- 引数には__id(主キー)__を指定します。
- 指定したidのレコードを取得するというイメージです。
- idが見つからない時は__例外(RecordNotFound)が返って来ます。__赤いエラーページが発生してしまうのですね。
- 引数を複数指定することも可能です。


```ruby
モデル名.find(idデータ)
```

- 具体的には以下のように使います。

```ruby
Item.find(1) # => idが1のレコードを返す
Item.find(1,3,5) # => 指定したidを配列で返す
```

#find_by
- データは__１番最初に合致した1件のみ__取得できます。
- id以外のカラム名なども検索条件にできます。
- 条件に合致するものがないと__nil__を返します。取得データがなくてもfind_byの記述以降も処理を続けたい時に便利ですね。
- 条件は複数指定可能です。

```ruby
モデル名.find_by(条件)
```

- 具体的には以下のように使います。

```ruby
Article.find_by(title: 'hoge') 
# => titleが'hoge'で最初に合致したデータを返す

Fruit.find_by(name: 'apple', color: 'red') 
# => nameが'apple'でcolorが'red'のデータを返す
```
####2つ条件を指定して1つだけ合致しなかった場合

```ruby
Fruit.find_by(name: 'apple', color: 'blue') #=> nilを返す
```
球上で互いに距離をおいてみた

<p class="codepen" data-height="520" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="YzWpLyb" style="height: 520px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="MovingPointsToKeepDistanceOnTheSphereUsingThreeJs">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/YzWpLyb">
  MovingPointsToKeepDistanceOnTheSphereUsingThreeJs</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

やっていること：球上で、互いの点間の距離の最小値が増加する側に点を徐々に移動させています。

やりたかったこと：正多面体とかの頂点に落ち着かないかなー・・・と思ったけど局所最適解ちっくなとこに落ち着いてしまうので無理でした。

コロナ禍っぽいタイトルになったのは偶然です。。

# 参考サイト

 - [Three.jsで大量のパーティクルを表示する方法 - ICS MEDIA](https://ics.media/tutorial-three/points/)
 - [球面上にランダムで置いたプロットをなるべく分散させたい - Qiita](https://qiita.com/clomie/items/e5dd35dcfcba082b2a7f#%E7%90%83%E9%9D%A2%E4%B8%8A%E3%81%AB%E4%B8%80%E6%A7%98%E5%88%86%E5%B8%83%E3%81%95%E3%81%9B%E3%82%8B%E8%A8%88%E7%AE%97%E6%96%B9%E6%B3%95%E3%81%8C%E3%81%82%E3%81%A3%E3%81%9F%E8%BF%BD%E8%A8%98)
VSCode カーソル移動

<h1>VSCode</h1>

__VSCode__で`keybindings.json`に対しキーボードからの操作を定義することで、_HomePosition_を崩さすにカーソル移動ができるようになります。

```keybindings.json
[
  {
    "key": "ctrl+u",
    "command": "cursorUp",
    "when": "textInputFocus"
  },
  {
    "key": "ctrl+n",
    "command": "cursorDown",
    "when": "textInputFocus"
  },
  {
    "key": "ctrl+j",
    "command": "cursorRight",
    "when": "textInputFocus"
  },
  {
    "key": "ctrl+h",
    "command": "cursorLeft",
    "when": "textInputFocus"
  },
  {
    "key": "tab",
    "command": "selectNextSuggestion",
    "when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
  },
  {
    "key": "ctrl+down",
    "command": "-selectNextSuggestion",
    "when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
  },
  {
    "key": "shift+tab",
    "command": "selectPrevSuggestion",
    "when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
  },
  {
    "key": "ctrl+up",
    "command": "-selectPrevSuggestion",
    "when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
  }
]
```

<details><summary>VsCodeの設定変更で効率化</summary><div>
最短距離で_keyborad_からの入力をする。
</div></details>
A2019 - 処理前後ファイルの、ファイル名を使った突合処理

#変換前後といった、部分的に同じ文字列が含まれるファイルの突合

今日やったのは、とあるお客さんの為に、IQ BotでOCRエンジンを変えつつ、
IQ Botの分類処理（例えば同じ請求書でも会社毎にフォーマットが異なるので自動的に分類する仕組み）がどれだけ動くかを確認する作業でした。
もっと細かく書いておくと、IQ Botでは、それぞれのファイルの中に、取りたい項目のラベルのうち、どのラベルが、どの様な配置で検知されたによって、自動的にグループ分けされます。
この時、必要数のラベルが見つからないと、Unclassifiedという、このラーニングインスタンスで処理すべき帳票ではないのでは？という結果が返ってきます。
OCRのエンジンによって、文字認識精度が異なりますので、良いエンジン程、Unclassifiedになる数が減るという事です。

##作りたかったデータ
作りたかったのは、こんな表。どの帳票がABBYYだとUnclassifiedになり、Googleともう一つのOCRエンジンでは特定できたかです。
ファイル数も全部で100以上あったので手作業での集計はやめてロボット作ることにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/eca5b059-6b73-b474-4495-a6508c2b1649.png)

##手元にあるデータ
使えるデータとしては下記。

1. Aの列に入っている元のファイル一覧。
    2. これは、コマンドプロンプトから、DIR /Bコマンドで元ファイルのフォルダを検索すれば簡単に取得可能なのでExcelに貼り付けました。
2. B列にチェックを入れたいファイルの一覧。
    3. IQ Botの結果フォルダのうちUnclassifiedに入っているファイルです。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/6fbfa828-3898-4014-75ca-e0bc9b9f4b2c.png)

##どうやって比較するのか
比較対象のデータは、前の方に処理IDがついてしまっているので、後方一致とかそんな感じで取る感じですね。
尚、IQ Botで正常処理されたcsvファイルだと、後ろに”.csv”も含まれますので、中間を一致させる必要があります。

##とりあえず、ロボット組みながら良い方法を考えましょうと。

| ↓こんな順番で考えながら組んでいきました。 | 出来上がったロボット |
|:--|:-:|
| 1. まず、エクセルを元にするでエクセルの開くと閉じる。難しいことしないから「基本のエクセル」で良いか。 <br><br> 2. ついでに、該当した場合に「*」をエクセルに入れたいので、エクセルのセル設定。 <br><br>3. あ、OCR毎に見るフォルダを変えるから、文字列の設定を入れて置くか。 <br><br>4. 順次処理なので、ループを入れて  <br><br> 5. どの行なのかをチェックしておくために、カウンター用変数作って、念の為その初期化を入れつつ、ループ内にインクリメント（カウントアップ） <br> <br> 6. ファイル名のマッチングは・・・あ、IFにファイルの存在確認ってのがあったから、それで行けるか？ <br> <br> ということで、試してみて、完了～  |  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/12c67dd4-1696-a663-652c-b76197049ac3.png) |




少しずつ条件を変えながら実行するために、対象フォルダを変数に入れる処理とか突っ込みましたが、それでも、たったの9ステップ♪
あ。。これ5行目の処理、6行目に纏められるねｗｗ
あと、結局カウンターの初期化も変数のデフォルトに入れて置けばよいので無くても行ける。
余計なの省けば6ステップですね。

この処理のミソは4行目と6行目ですかね。
４行目のループ処理で、Unclassifiedのファイルが入ったフォルダーにある各ファイルが順次処理されるようにし、
６行目のIF条件でファイルの存在として、ワイルドカードで囲んだ形でファイル名を指定してます。

この処理を応用すれば、先日Twitterで見かけた、異なる3つのフォルダに、それぞれ頭に異なる文字列が付けられたcsvファイルの結合処理も、割と簡単に実装できるかと思います。

↓デュアル表示（＝フロー表示＋リスト表示）で全体像↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/0a1bff8d-53fa-c05f-cb2c-2267c093e7c9.png) 

##コメント
こんな個人作業の、しかも一度しか使わないようなロボット、効果は得られないので開発担当者とか外注して作って貰うということはあり得ないかと思います。簡単に作れるA2019ならではですかね。
【LINEBot】Flexメッセージが送れない時に確認すること

僕も一瞬戸惑ったし、友達が困っていたLINEBotの初心者落とし穴を共有します。

#この記事の対象者

「LINEBotを触るようになり、textとか画像とか送れるようになったけど、自分で作ったFlexMessageが送信できない」と思っている方

#筆者の環境

```
LINEBotDesigner:バージョン1.3.4 (1.3.4)
```

#この記事で解決できるエラー文
![スクリーンショット 2020-10-22 23.23.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/7179219b-da9a-cb14-0b73-6216248852b0.png)

要するにMessageのtypeが `text, image, video, audio, location, sticker, template, imagemap, flex`しか送れないとのこと。

#確認してほしいこと
![スクリーンショット 2020-10-22 23.26.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/1093ab5b-0fd3-d484-2577-c4cb6e25eba8.png)

[LINEBotDesigner](https://developers.line.biz/ja/services/bot-designer/)や[FlexMessageシュミレーター](https://developers.line.biz/flex-simulator/)で作ったFlexMessageのJSONはtypeが`bubble`になっています。ですので送信できません。

#解決策

LINEBotDesignerやFlexMessageシュミレーターで作ったFlexMessageの頭と後ろに文字を必要なものを付け足す

```

 {
  "type": "flex",
  "altText": "flexMessageです",
  "contents": {ここの部分に作ったMessageを書く}
}
```
これで無事送信できるようになると思います。一度お試しください。

## 使用例

```
{
  "type": "flex",
  "altText": "flexMessageです",
  "contents": {
  "type": "bubble",
  "direction": "rtl",
  "header": {
    "type": "box",
    "layout": "vertical",
    "contents": [
      {
        "type": "text",
        "text": "簡単なFlexメッセージ",
        "align": "center",
        "contents": []
      }
    ]
  },
  "body": {
    "type": "box",
    "layout": "vertical",
    "contents": [
      {
        "type": "text",
        "text": "ここは本文を書くところです",
        "align": "center",
        "contents": []
      }
    ]
  },
  "footer": {
    "type": "box",
    "layout": "horizontal",
    "contents": [
      {
        "type": "button",
        "action": {
          "type": "uri",
          "label": "これはボタンです",
          "uri": "https://linecorp.com"
        }
      }
    ]
  },
  "styles": {
    "header": {
      "backgroundColor": "#7CE4ADFF",
      "separator": false
    },
    "body": {
      "backgroundColor": "#FFACACFF",
      "separatorColor": "#FFFFFFFF"
    }
  }
}
}

```

##カルーセルメッセージの場合
####（追加更新2021/1/10）

```
{
      type: "flex",
      altText: "flexMessageです",
      contents: {
        type: "carousel",
        contents: [
          {type:'bubble' ....},
          {type: 'bubble' ... }
        ]
      }
}

```
カルーセルメッセージの場合は上のようにJSONを書いて、carouselの中の`contents`にカルーセルで表示したいメッセージを配列にしてくといい感じに送信できます。


#おまけ

先ほど追加した`altText`ってなんなのと聞かれることがたまにあります。ここの部分は自由に変えても大丈夫です。↓

![IMG_6602.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/1a8f152f-355b-e75a-7f80-58bed0a5e4b1.jpeg)

このようにLINEの通知だったり、トーク一覧に表示されるメッセージになります。

#あとがき
先日のアップデートが来るまではこんなことしなくてよかったので意外とこける人多いかもと思ったので記事書いてみました。
誰かの力になれたら幸いです。

[だれでもAWSでLINEBotが作れるようになる記事はこちら](https://qiita.com/inoue2002/items/a87df2b520f8b6e37f42)
オリジン間リソース共有を学ぼう

#APIの応用



異なるアプリケーションからのアクセス
「異なるアプリケーション」とは何なのか
例えば、レストラン予約サイトとGoogleマップが異なるアプリケーションであることは理解できると思います。
なぜ違うのか？そもそもブラウザからアクセスする先が違うから。

まだ、ピンとこないですね。
理解するための用語の理解からして行きましょう。


##スキーム
http:// localhost:3000のhttp://部分を指します。
スキームとは、一般的にHTTPプロトコルの部分を指します。

スキームさんが発見したのかな？


##ホスト
http:// localhost:3000のlocalhost:部分や、他にはwww.yahoo.jpのwwwを指します。
これは接続する機器を表していると考える。


##ドメイン
ドメインとは、www.yahoo.jpのyahoo.jpを指します。
これは、インターネット上の住所的な感じですね。


##ポート
ポートとは、http:// localhost:3000の３０００部分を指します。
これは、部屋番号的な感じですね。




***
上記の単語を使用して
「アクセスする先が違う」という意味を理解していきましょう。

##オリジン(Origin)
Webに関連する知識であり、URLのスキーム（プロトコル）、ホスト（ドメイン）、ポートをまとめた総称。

具体的には、http:// localhost:3000やhttps:// techcamp.jpを指します。

URLに似ている？　でも、違うようです。

オリジンは下記の表にある３つの要素から成り立ちます。

| 名称|  例 |
|:-----------|:------------:|
| スキーム      | http://        |
| ホスト     |localhost:      |
| ポート     |3000   |


オリジンが完全に一致したアプリケーションがものが「同一オリジン」となります。

逆にオリジンが１つでも一致しない場合は、「異なるアプリケーション」となります。


異なるアプリケーションに対してアクセスする際の制限に関して**同一オリジンポリシー**と呼ばれるものがあります。


##同一オリジンポリシー
「異なるオリジンのアプリケーションへアクセスする際にセキュリティ面を考慮して制限がかかる仕組み」です。

この制限は、ありがたいことに通常Webアプリケーションフレームワークでははじめから設定されています。解除するには別の設定が必要です。

じゃ、いつ使うのか？


##同一オリジンポリシーを考慮すべきパターン
結論から言うと、同一オリジンポリシーを考慮する必要があるのはAPIを使用するケースです。

例えば、ある会社が運営するWebアプリケーションが、他社が提供している外部APIを使用する時、ほとんどのケースでオリジンが異なります。
この時に同一オリジンポリシーの制限が存在すると、他社のAPIにアクセスすることができないため、API自体を利用することができなくなります。

では、なぜ同一オリジンポリシーが存在するのか？


制限をかけるのは、異なるオリジンからのアクセスを常に許可してしまうと誰でもAPIを使用できる状態になり、意図しないアクセスに対応できないためです。

####異なるオリジンからアクセスがいつでもできるアプリケーションは、「誰でも使用できる」ということです。

すべてに制限を掛けてしまうと外部APIが成り立たなくなってしまうので「制限を解除する仕組み」も存在します。


##CORS
CORSとは、オリジン間リソース共有(Cross-Origin Resource Sharing)の略称であり「異なるオリジン(Origin)のアプリケーションへ、アクセスを許可する仕組み」のことです。

Ruby on Railsで作られたアプリケーションは、同一オリジンポリシーにより、異なるオリジンのアプリケーションからはリクエストを受け付けない設定になっているそうです。


アクセスを許可する必要があるので、その方法は、**rack-cors**というGemを使用します。

こちらのGemをインストールし、設定ファイルに記述を加えれば、異なるオリジンからのアクセスを許可できます。


設定を記述するファイルは**config**ディレクトリ内にある**application.rb**というファイルです。こちらのファイルに、下記のような記述を加えます。

```Ruby:application.rb
〜省略〜

   config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*'
        resource '*', headers: :any, methods: [:get, :post, :options]
      end
    end

〜省略〜
```

originとresourceを指定することで、それぞれ許可する項目を指定できます。
特定のオリジンを許可する場合にはorigins '特定のオリジン'と書く必要があります。

このように行えば、動画配信サイトからViiideoのAPIを使用することが可能になります。


##最後までありがとうございました

また、APIってなんだっけ？の時に見直します。
【Vue.js】vue-cliとVuetifyでサクッと新規プロジェクトを立ち上げる

ポートフォリオ公開用の簡単なSPAが作りたかったので、
vue-cliを使ってサクッと新規プロジェクトを立ち上げた。

## 環境
MacOS Catalina 10.15
vue 2.6.12
Node.js 14.2.0

## vue-cli導入からプロジェクト作成まで
次のコマンドでvue.cliを導入する。そもそもvue-cliが何かは[こちら](https://cli.vuejs.org/)を参照で。

```
npm install -g @vue/cli@3.5.0
```
この記事を書いている今の最新はv4.5.8なのですが、今回はバーション3で進めます。これでインストールは完了。続いてプロジェクトを作成します。

```
vue create my-portfolio
```
基本はデフォルトでいいと思いますが、
この段階でTypeScriptだったり、vue-routerを選択する事も可能です。

```
Vue CLI v3.5.0
? Please pick a preset: 
  Default ([Vue 2] babel, eslint) 
  Manually select features 
```
バージョンによってはYarnかNPMを選択をさせられる場合がありますが、お好みで。

```
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project my-portfolio.
👉  Get started with the following commands:

 $ cd my-portfolio
 $ npm run serve
```
無事に作成出来ました。早速、` npm run serve` でローカルで動作確認してみましょ。

![スクリーンショット 2020-10-22 23.23.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/5581ff26-a10c-84ca-ec88-a4a63000f014.png)

はい、バチクソ簡単です。

## Vuetify入れましょう
今回はサクッとがテーマなので、[Vuetify](https://vuetifyjs.com/en/components/app-bars/)も使います。
vue-cliが入っていれば、以下コマンドでOKです。

```
vue add vuetify
```

これもデフォルトで良いと思います。

```
✔  Successfully installed plugin: vue-cli-plugin-vuetify

? Choose a preset: (Use arrow keys)
❯ Default (recommended) 
  Prototype (rapid development) 
  Configure (advanced)
```
` npm run serve`してみましょ。

![スクリーンショット 2020-10-22 23.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/d1fb2137-57a7-53d0-bbc1-2117b12e75c7.png)

OKですね。
ちなみにこの段階でディレクトリ構成はこんな感じ。

![スクリーンショット 2020-10-22 23.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/78dba5ed-edd2-9c00-1a17-969d3bdbd62e.png)
【pipenv】仮想環境の入り方

#環境
windows10
vscode

#はじめ
vscordのterminalを使ってpipenv仮想環境に入る方法。

#1.powershellの変更
はじめは Windows PowerShell になっているため、これを　Command Pronpt　に変更する。

この画面から↓
![powershell1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676731/6a5950fb-fb77-d520-8aa3-ec1c9ac383a1.jpeg)

この<font color='red'>赤枠</font>を押す↓。
![powershell2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676731/862d5cbc-79e9-8d7f-79a0-5d6013e344e8.jpeg)


そして　'Select Default Shell'　を選択。
そして　'Command Pronpt'　を選択。

次にこの<font color='red'>赤枠</font>を押す↓。
![powershell3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676731/a9f9edd2-8d06-9c3d-de46-ed01ddf8498d.jpeg)


そして　'New Terminal'　を選択。
すると以下のようにpowershellが変更される。
![powershell4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676731/7a3fff9d-d429-89a0-7caf-19c213c914d3.jpeg)


#2.仮想環境作製
'C:\Users\user\Descktop\pipenv'に仮想環境をつくるときを例にとる。

```
C:\Users\user\Descktop\pipenv>pipenv shell

```

すると、

```
(pipenv) C:\Users\user\Desktop\pipenv>
```
のように仮想環境を作れる。

#既存の仮想環境に入るとき
'C:\Users\user\Descktop\pipenv'に仮想環境をすでにつくっているときを例にとる。
この時は以下のように　pipenv shell　を使っても仮想環境に入れない。
```
C:\Users\user\Descktop\pipenv>pipenv shell
Shell for ####################### already activated.
No action taken to avoid nested environments.

```
上の例では　path:#######################　に既に仮想環境が存在していると言われている。

この時は

```
C:\Users\user\Descktop\pipenv>cd #######################
C:#######################>exit
```

のように仮想環境のpathに移動し、そこで__exit__をする。
すると、

```
C:\Users\user\Descktop\pipenv>pipenv shell
(pipenv) C:\Users\user\Desktop\pipenv>
```

のように再び仮想環境に入れる。
WordPress 5 のテーマエディターで .php 編集がエラーになる

WordPress はテーマエディターで CSS や HTML テンプレートを編集できるが、
WordPress 4.9 以降は .php ファイルの編集がエラーになるらしい。

> 致命的なエラーをチェックするためにサイトと通信できないため、PHP の変更は取り消されました。SFTP を使うなど、他の手段で PHP ファイルの変更をアップロードする必要があります。

![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12419/715f34d1-ea68-a061-17c1-af7a682725f0.png)

「file.php の○〜○行目をコメントアウトする」という対策があるらしい。
広い範囲をコメントアウトするのは面倒なので、`if` 文の条件を変えて対応してみた。

![php.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12419/1735df4c-a2a5-5db2-0da2-d29eade520b5.png)

変更前

```php
    if ( $is_active && 'php' === $extension ) {
```

変更後

```php
    if ( $is_active && 'php__IGNORE__' === $extension ) {
```

コメントアウトしなくても、条件が偽になれば実行されないので、何でも良さそう。
無事にファイル編集も成功しました。

![success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12419/60586279-4c97-1f98-217e-6dc0277c98e5.png)

とても正しい対策手順とは思えないけど、管理画面のセキュリティの懸念がない環境なら、これでも良いだろう。
少しずつ正規表現を覚えていく①

#はじめに
　プログラミングの学習をしてきて、今のところ、いちばんの苦手は、「正規表現」だろう。ググれば、いくらでも正解に出会えるが、せめて何を表しているのか読めるようになりたいので、何回かに分けて、紹介していく。

##今日出会った正規表現

正規表現|意味  |
------ |-------
{n}    |n回繰り返す|
{n,m}|n回繰り返す。最大m回まで
[ ]|角括弧の中の文字いずれか一文字にマッチ
[ - ]|-は「から（〜）」みたいな意味
.|任意の一字にマッチ
\d|半角数字

##さいごに
　きっと、読み方は組み合わせによるものだと思う。一つひとつの意味を理解していく必要がありそう。
linux at command

linux at command 意外と使える！ので、ここでメモ。

コマンド指定（ctrl+dで終了）

```bash
22:59:18 root@localhost ~ [0] # at 23:30
at> touch 1.txt
at> <EOT>
job 10 at Thu Oct 22 23:30:00 2020
22:59:37 root@localhost ~ [0] #
```

待ち行列表示

```bash
23:00:59 root@localhost ~ [0] # at -l
10      Thu Oct 22 23:30:00 2020 a root
23:01:00 root@localhost ~ [0] #
```

コマンド内容を表示。ちゃんと現在のフォルダまで移動したね。

```bash
23:01:48 root@localhost ~ [0] # at -c 10
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0
umask 22
XDG_SESSION_ID=16340; export XDG_SESSION_ID
HOSTNAME=localhost; export HOSTNAME
SELINUX_ROLE_REQUESTED=; export SELINUX_ROLE_REQUESTED
SHELL=/bin/bash; export SHELL
HISTSIZE=1000; export HISTSIZE
SELINUX_USE_CURRENT_RANGE=; export SELINUX_USE_CURRENT_RANGE
SSH_TTY=/dev/pts/0; export SSH_TTY
USER=root; export USER
MAIL=/var/spool/mail/root; export MAIL
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin; export PATH
PWD=/root; export PWD
LANG=ja_JP.UTF-8; export LANG
PS1=\\t\ \\u@\\h\ \\w\ [\${PIPESTATUS[@]}]\ \\\$\ ; export PS1
SELINUX_LEVEL_REQUESTED=; export SELINUX_LEVEL_REQUESTED
HISTCONTROL=ignoreboth; export HISTCONTROL
SHLVL=1; export SHLVL
HOME=/root; export HOME
LOGNAME=root; export LOGNAME
LESSOPEN=\|\|/usr/bin/lesspipe.sh\ %s; export LESSOPEN
XDG_RUNTIME_DIR=/run/user/0; export XDG_RUNTIME_DIR
cd /root || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
${SHELL:-/bin/sh} << 'marcinDELIMITER54cbc56c'
touch 1.txt

marcinDELIMITER54cbc56c
23:01:53 root@localhost ~ [0] #
```

コマンド削除

```bash
23:03:58 root@localhost ~ [0] # at -l
10      Thu Oct 22 23:30:00 2020 a root
23:04:06 root@localhost ~ [0] # at -r 10
23:04:11 root@localhost ~ [0] # at -l
23:04:14 root@localhost ~ [0] #
```

以上。
【Java】Listにデータを追加する方法(add,addAll)

#プログラミング勉強日記
2020年10月22日
addAllの使い方がいまいち理解できてなかったのでListにデータを追加する方法まとめる。

#値を追加するaddの使い方
　addメソッドは値を追加することができる。Listの末尾や位置を決めて挿入することができる。

```java:末尾に追加
List<Integer> list = new ArrayList<Integer>();
// integer型のListの末尾に値1を追加
list.add(1);
```
　挿入位置を決める場合は、2つの引数を指定する。第1引数は挿入する場所を、第2引数は挿入する値を指定する。

```java:挿入位置を決める
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(3);
list.add(4);
// Listの1と3の間に2を入れる
list.add(1,,2);
```


#値をまとめて追加できるaddAllの使い方
　addAllは複数の値をまとめて追加することのできるメソッド。

```java
// Listを2つ用意してlistにlist2の値を追加する
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

List<Integer> list2 = new ArrayList<Integer>();
list2.add(5);
list2.add(6);
list2.add(7);
list2.add(8);
list.addAll(list2);
````
　

```java
// Listを定義しなくても上記のコードと同様の結果になる
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.addAll(Arrays.asList(5, 6, 7, 8));
```

　addAllメソッドもaddメソッド同様に、追加する位置を指定できる。処理の方法も同様で、引数を指定する。

```java:挿入位置を決める
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
 
List<Integer> list2 = new ArrayList<Integer>();
list2.add(5);
list2.add(6);
list2.add(7);
list2.add(8);
list.addAll(1, list2);
```

#参考文献
[Java 配列からリストを作成する(addAll/asList)](https://itsakura.com/java-collections)
[【3分でわかるJavaの基礎】Listにデータを追加する方法(add,addAll)](https://www.sejuku.net/blog/14859)
Goの基本型について

##基本型
###論理値型
論理値はbool型で表します。下記のように、真の場合は**true**、偽の場合は**false**の値をとる動作をします。また、型推論での定義もできます。

```
var a bool  //変数aをbool型で定義
a = true    //変数aにtrueを代入
```

```
a := true
```

###数値型
数値型には整数型が用意されており、**符合付き整数型**と**符合なし整数型**の2つの型が用意されています。

符合付き整数型は```int8```、```int16```、```int32```、```int64```の型があり、数値がサイズを表しています。
符合なし整数型は```uint8(byte)```、```uint16```、```uint32```、```uint64```の型があり、同様に数値がサイズを表しています。符合付きと違う点として、```uint8```は```byte```型という別名でも定義することができ、uint8と同じ動作をします。

また、64bit実装のGoでは```int```型は```int64```と同じ動作をしますが、下記のように、同じ符合付き64bit整数を表す方の変数同士であっても、型が異なるというところから、暗黙的な型変換はコンパイルエラーが発生してしまいます。

```
a := int(10)
b := int64(5)
b = a  //コンパイルエラー
fmt.Printf("%v\n", b)
```

このように、暗黙的に型変換をしようとしてしまうとコンパイルエラーが出てしまいます。しかし、下記のようにしっかり型を指定し、明示的に型変換を行えばコンパイルエラーは発生せずに実行することができます。

```
a := int(10)
b := int64(a)
fmt.Printf("%v\n", b)
```

この方法を使えば、型のサイズの最大値を超えた数値の処理が可能になります。

```
a := int8(128)  //コンパイルエラー
fmt.Printf("%v\n", a)
```

```
a := 128
b := int8(a)
fmt.Printf("%v\n", b)
```

**int8の最大値である127**を超えた128での処理ができるようになりました。これは、明示的に行うことで、最大値127に1が加わったときの2進数表現上で**オーバーフロー(桁あふれ)**が起こり、**ラップアラウンド**させられ、値が最小値に戻るようになるからです。なので、この場合出力される値は**int8の最小値である-128**になるということです。

アップアラウンドの対策として、**mathパッケージ**をインポートし、利用することで、桁あふれを意識しながらコードを書いていくことができます。

###浮動小数点型
浮動小数点型には```float32: 単精度浮動小数点```、```float64: 倍精度浮動小数点```の2つの型が用意されています。ちなみに、float32はfloat64より精度が低く、メモリ使用効率の面を考慮しないのであれば、特別ない理由がない限り使用するメリットは少ないと思われます。

```
a := 1.0           //float64
b := float32(1.0)  //float32
```

また、浮動小数点型にも、mathパッケージによって数値範囲を表す定数が用意されていますし、浮動小数点リテラルを使って型の異なった値をとる場合には明示的な型変換を行う必要があります。しかし、小数点部は切り捨てられます。

次に、演算が不能になる特殊な値に関してです。下記の演算による出力結果として、それぞれ+Int(**正の無限大**)、-Int(**負の無限大**)、NaN(**非数**)という意味を持ちます。

```
1.0 / 0.0   //+Int
-1.0 / 0.0  //-Int
0.0 / 0.0   //NaN
```

###複素数型
aが実部、bが虚部、iは虚数単位として、**a + bi**というリテラルで表現されており、```complex64```と```complex128```の2つの型が用意されています。それぞれ、complex64型の実部、虚部には```float32```が使われており、complex128型の実部、虚部には```float64```が使われています。

下記は、複素数リテラルを使用した代入方法です。ちなみに、+ 記号についてはあくまでリテラルの一部であって、演算子ではありません。また、complex関数を使い、実部、虚部それぞれの引数を取ることでそれぞれの値を返し、生成することもできます。

```
a := 1.0 + 2i
```

```
a := complex(1.0, 2)
```

このリテラルの、実部、虚部の値を取り出すための関数も用意されています。

```
a := 1.0 + 2i

real(a)  //1.0
imag(a)  //2
```

###rune型
これは文字を表す型であり、シングルクォーテーションで囲まれた文字を、Unicodeコードポイントで表現し、出力します。また、バックスラッシュから始まるプリフィックスを付加することで、Unicode文字を表現できます。他にも、文字列表現のエスケープシーケンスも用意されています。別名int32と定義されており、同じ動作をします。

```
a := '例'
fmt.Printf("%v", a)  //20363
```

```
a := '\U00101234'
fmt.Printf("%v", a)  //1053236
```

###文字列型
string型と定義されており、ダブルクォーテーションで囲まれた文字列リテラルが用意されています。

```
a := "例題"
fmt.Printf("%v", a)  //例題
```

```
a := "\u65e5本\U00008a9e"
fmt.Printf("%v", a)  //日本語
```

文字列リテラルにはもうひとつ、**RAW文字列リテラル**という形式があります。これは、バッククォーテーションを使い、複数行の文字列に対応したり、その文字に対して処理を行わないという性質があります。

```
a := '
例題
例題
例題
'
fmt.Printf("%v", a)  //例題
　　　　　　　　　　　　   例題
　　　　　　　　　　　　   例題
```

##最後に
今回はGoの基本型についてまとめました！基本型そのものの表面だけではなく、意味や仕組みについてある程度踏み込んで理解できたのではないでしょうか？

この調子でアウトプット続けますー！

##参考文献
著者　松尾愛賀
[翔泳社　スターティングGo言語](https://www.shoeisha.co.jp/search?search=%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0Go%E8%A8%80%E8%AA%9E)
ポートフォリオのダミーデータをFakerで作る【備忘録】

エンジニア初学者の方でポートフォリオのダミーデータを手入力で入れていくのはとても面倒だし、かっこよくダミーデータを入れたいですよね。gem Fakerを使用すれば簡単に実現できます。

# 実装の流れ
作業時間は初めての方で30分程度になります。
1.gem Fakerの導入
2.fakerの日本語化
3.ターミナルからbundle install
4.seedファイルに記述
5.ダミーデータの作成/rails db:seed
6.DBに反映されているか確認

それではやっていきましょう！

# 1.gem fakerの導入
まずは、GemfileにFakerを導入しましょう！

```rails:Gemfile
gem 'faker'
```
# 2.fakerの日本語化
次にfakerの日本語化ファイルを導入します。
下記のリンクから、ja.ymlをダウンロードorコピーしてください、rails内のconfig>locales>ja.ymlに置きます。
https://github.com/faker-ruby/faker/blob/master/lib/locales/ja.yml
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390510/e36f8bf6-c7c8-2aad-88fb-52bc177a32d5.png)
次にapplication.rbのモジュール内に```config.i18n.default_locale = :ja```を記述します

```rails:application.rb
module hoge
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    config.i18n.default_locale = :ja #ここを追加
  end
end
```




※ダウンロードorコピーはrawボタンからできます。(名前を付けてファイルを保存しましょう)
![キャプチャ (2).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390510/87ec9217-c5d6-8e86-f13d-e1da5b8fad24.png)

# 3.bundle install
ターミナルでbundle installしましょう！

# 4.seedファイルに記述
いよいよseedファイルにテストデータを入れていきます。
下記の場合、modelで作成した、name/character/emailのカラムに対して50個のランダムなダミーデータを入力してくれます。  
Faker::のメソッド記述は、READE.meを確認しましょう！

```rails:seeds.rb
50.times do 
  User.create(
    name: Faker::Name.name, 
    character: Faker::Games::Pokemon.name, 
    email: Faker::Internet.email,
  )
end
#一番左のname:はモデルのカラム名
```

次に、rails db:seedでデータの反映をします。

# 5. DBに反映されているか確認

コンソールから```rails c```で反映されているか確認しましょう。

```
User.all
```
※rails cはrails consoleの略

日本語化されたデータが入っていれば完了です。
お疲れさまでした。
Unity:オブジェクトの表示・非表示のエラー

###事象
GameOverメッセージを隠しておいて、ゲームオーバーになった時に表示したかったが、表示できなかった。

##内容
まず、以下のコードをGameOverテキストを貼り付けたパネルにアタッチしたが、start()の非表示処理は動くのに、update()の表示処理が動かなかった

```
public class gameStateManager : MonoBehaviour
{

    public static bool gameState = true;

    void Start()
    {
        this.gameObject.SetActive(false);
    }

    void Update()
    {
        Debug.Log("test");

        if (gameState==false)
        {
            this.gameObject.SetActive(true);
        }
    }
}
```

デバッグ用にログを見たが、ログも出力されていない状態

##原因

GameOverを表示するパネルが以下のスクリプトで非活性になり、update()が以後行われなくなっていることが原因だった。

```
    void Start()
    {
        this.gameObject.SetActive(false);
    }
```

例えば、数秒後に消えるオブジェクトなどはそれ自身が完全にメモリ上から消える必要があるので、this.gameObject.SetActive(false);で削除して良いが、今回のように表示、非表示を繰り返したい場合は、自身を削除するという処理をするとその後のupdate()が効かなくなる

##対処

以下のコードをMainCameraにアタッチして表示非表示の切り替えをすることにした

```
public class gameStateManager : MonoBehaviour
{

    public static bool gameState = true;
    public string gameOverObject = "GameOverPanel";
    GameObject gameObject;

    void Start()
    {
        gameObject = GameObject.Find(gameOverObject);
        gameObject.SetActive(false);
    }

    void Update()
    {

        if (gameState==false)
        {
            gameObject.SetActive(true);
        }
    }
}
```
python + JupyterLab で Web スクレイピング


# はじめに

`JupyterLab` はお手軽に `python` を触ることができる実行環境です。

# 環境構築

```
git clone https://github.com/takiguchi-yu/python-jupyterLab.git
cd python-jupyterLab
```

# JupyterLab 起動

```
docker-compose up -d
```

# アクセス

http://localhost:8888

<img width="500" alt="初期画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/39cf7942-465e-9fce-477e-54c77cc5f002.png">

# JupyterLab 終了

```
docker-compose down
```

# Web スクレイピングサンプル

ちょっとした Web スクレイピングを書いてみる。
外部ファイルに記載されているURLを読み込んで、それを叩きながら結果を外部ファイルに出力するサンプル。
<img width="900" alt="Webスクレイピング実装" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/890542d6-7f71-de7a-25e9-2a5df5b810f9.png">

```python
from bs4 import BeautifulSoup
import requests
headers = {
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1'
}
print('処理開始')
# URLのリスト(外部ファイル)を読み込む
with open('./input_urls.txt', mode='r', encoding='utf-8') as f:
    for url in f:
        result = requests.get(url.rstrip('\n'), headers=headers) # 注意：改行コードを取り除くこと
        print(result.status_code)
        soup = BeautifulSoup(result.content, 'html.parser')
        a = soup.find_all('ここにHTMLタグ名', {'class': 'ここにクラス名'})
        #a = soup.find_all('div', {'class': 'hoge-hoge'})  # 例
        b = a[0].find(text=True) # HTMLタグのテキストを取得
        # スクレイピング結果を外部ファイル(output.txt)に出力
        with open('./output.txt', 'a') as f:
            print(b, file=f)
print('処理完了')
```

# ターミナルも使える

好きなライブラリを自由に入れることができる。

<img width="500" alt="ターミナル1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/3ef9fbd4-b2d2-8523-1fd0-461d06ab2267.jpeg">
<img width="500" alt="ターミナル2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/1a5f64aa-8548-4b49-933a-3d093455bd81.png">

# 環境構築は以下を参考

https://qiita.com/hgaiji/items/edf71435d0565257f980
phpで連想配列から特定のカラムの値をkeyとvalueに指定して返す

連想配列で特定のカラムの値をkeyにして単一のカラムの値をvalueにしたい場合、別の配列を用意しそこにループ処理で値を詰め直すということをやっていました。

```
<?php
    $foods = array(
        array(
            'id' => 1,
            'name' => 'Sushi',
            'country' => 'Japan',
        ),
        array(
            'id' => 2,
            'name' => 'hamburger',
            'country' => 'America',
        ),
        array(
            'id' => 3,
            'name' => 'Pasta',
            'country' => 'Italia',
        )
    );
?> 
```

この配列のidをkeyにnameをvalueにします。

#ループ処理を用いたやり方

```
<?php
    $foods_menu = array();
    foreach($foods as $key => $food){
        $id = $food['id'];
        $name = $food['name'];

        $food_menu[$id] = $name;
    }
?> 
```
こんな感じで毎度ループを回してました。

けれどarray_column関数を使えば毎度ループを回すことなく同じことが実現できます。

#array_columnを用いたやり方

```
<?php
    $foods_menu = array_column($foods,'name','id');
?> 
```

第一引数に対象の配列、第二引数にvalueにしたいカラム、第三引数にkeyにしたいカラムを指定することで実現できます。
（第三引数を指定しなければ0からkeyが割り当てられます。）

便利なのでぜひ。
Prism 8.0 がリリースされてました

ふと見てみたら 12 時間前にリリースされてました！ Prism 8.0 が！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/9edc88dc-6705-2a1f-9b9b-8e4bfd5eee9c.png)

https://github.com/PrismLibrary/Prism/releases/tag/v8.0.0.1909

メジャーバージョンなので若干の BREAKING CHANGES もあるみたいです。例えば `ILoggerFacade` が消えちゃったみたいです。
まぁ、個人的には使ってないし最悪、そこまで大きな影響はないかな？使ってたとしても同じインターフェースのものを自前で定義しても大した労力ではないと思うので。

Prism.Wpf は、ViewModelLocator.AutowireViewModel が自動で true になるとか。

## 機能追加

完全なリストはリリースノートとして、個人的に気になってるのが Xamarin.Forms 向けに Region がサポートされたところですね！！MAUI とかがリリースされたらデスクトップ系もサポートされるはずなので、そういう大きな画面を考慮すると Region があるとやりやすいですよね。

あと、Uno Platform がサポートされたところも大きいですね！Uno Platform に対応したことで UWP の Prism 対応が復活しました。
めでたい。

Uno Platform の Prism は Prism.Wpf をベースに作られているので WPF と同じ感じで作れるのがいいですね。


ということで、近いうちに試してみたいと思います。
【PowerShell】Getコマンドの中から特定の値を抽出する方法

# はじめに
PowerShellでスクリプトを作成していると、「Getコマンドの中から特定の値を抽出したい」と言う時はありませんか？
今回は、こちらの方法をアウトプットします。


# 抽出するデータとは？

以下、コマンド実行結果の`Domain`という値を抽出したいと思います。

※`Get-NetFirewallProfile`はファイアウォール設定を確認するコマンドになります。

```powershell:コマンド実行結果
 PS C:\Users\Administrator> Get-NetFirewallProfile -Name Domain

Name                            : Domain ←　これを抽出
Enabled                         : False
DefaultInboundAction            : NotConfigured
DefaultOutboundAction           : NotConfigured
AllowInboundRules               : NotConfigured
AllowLocalFirewallRules         : NotConfigured
AllowLocalIPsecRules            : NotConfigured
AllowUserApps                   : NotConfigured
AllowUserPorts                  : NotConfigured
AllowUnicastResponseToMulticast : NotConfigured
NotifyOnListen                  : False
EnableStealthModeForIPsec       : NotConfigured
LogFileName                     : %systemroot%\system32\LogFiles\Firewall\pfirewall.log
LogMaxSizeKilobytes             : 4096
LogAllowed                      : False
LogBlocked                      : False
LogIgnored                      : NotConfigured
DisabledInterfaceAliases        : {NotConfigured}
```

# データ抽出

こちらのコマンドを実行します。

```powershell:実行コマンド
  (確認コマンド).項目名
```

## コマンド実行例①

`Get-NetFirewallProfile`の`Name`の値を抽出したい場合

```powershell:コマンド実行例
PS C:\Users\Administrator> (Get-NetFirewallProfile -Name Domain).Name
Domain
```

## コマンド実行例②

`Get-Service`からサービス名のみ抽出

```powershell:コマンド実行例
PS C:\Users\Administrator> (Get-Service -Name ALG).Name
ALG 
```

※抽出しない場合の表示

```powershell
 PS C:\Users\Administrator> Get-Service -Name ALG

Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  ALG                Application Layer Gateway Service      
```

# 最後に

この方法を探す前は、以下記事の方法を使っていました。
[【PowerShell】Linuxのgrepのように行を検索する方法(Windows)](https://qiita.com/satton6987/items/d99514900bfd9c4e607e)

しかし、今回紹介した内容の方が短文で使いやすいことがわかりました。
是非、ご活用ください！
早速XDからVS CodeにScssを生成させようとしたらハマった話

# 最初にオチから
- **<font color="Red">XD側での準備が重要。アセットの名前の頭文字を数字にしては駄目。</font>**

Adobe XD から Visual Studio Code（VS Code） に Design System Packages（DSP）を読み込ませる基本的な機能についてはこちらを参照してください。
https://letsxd.com/vscode

# XD→VS CodeでScssを生成する手順
※Macでしか確認していません。その他の環境の方、ごめんなさい。

1. Adobe XD
	- [ファイル]→[ライブラリの管理]を選択
	- 現在のファイルの[公開]を選択
	- 共有者は自分のみでOK
2. Adobe Creative Cloud
	- ウィンドウを開き[作品]タブを選択
	- CC ライブラリから該当のドキュメントを選択
	- 右上の[表示専用アクセス]の右の[…]を選択し
	- 表示されたリストの[リンクを取得]を選択
	- リンクが生成されたら[リンクをコピー]を選択
3. VS CodeとXDの接続
	- XD機能を使用可能にする
		- 拡張機能からAdobe XDをインストール
		- 右下の[XD]ボタンを選択
	- DSP name and locaiton設定
		- [Create package]を選択
		- [DESIGN SYSTEM PACKAGE NAME]を入力
		- [SAVE LOCATION]を選択
		- [NEXT]を選択
	- Languages設定
		- 今回はScssの書き出しなので[CSS]のチェックを外し、[SCSS]のチェックを入れる
	- Creative Cloud Libraries設定
		- [Authenticate]を選択
			- ウィンドウが開いてAdobe CCの自分のアカウントと紐付けしてください
		- [CC LIBRARY LINK]に 2 で取得したリンクを入力
		- [Import]を選択
4. VS Code側でとりあえずScssの書き出し
	- XDタブの左下の[Start editing]を選択
	- そのまま[Finish editing]を選択
	- 「In order to compile your tokens, Please install Style Dictionary locally.」というアテンションが出るので[Install]を選択
	- style dictionaryの情報が出るので[Export tokens]を選択
	- 「Tokens compiled to SCSS」と出るので、ここでSCSSが書き出し完了

# ここで問題発生
XDで完全にデフォルトの文字色は「#707070」。
この色をアセットに登録して、手を加えないままだと問題が発生します。
おそらくデフォルトのXDのアセットの色表示はカラーチップのような見た目で、その色の名前が表示されていませんが、リスト表示にすると「#707070」という名前が表示されます。

この「#707070」という名前のまま、VS Codeに持ち込んでScssを生成すると

    $707070: #707070;
のような変数を作り出してしまい、Scssのルールに違反してしまいエラーとなりCSSが生成できません。

また、この状況になった際にVS Code側でToken IDを「color_gray」のように編集して変数名を修正した場合、再インポートのタイミングで再び同じ変数が生成されてしまいます。

    $707070: #707070;
    $color_gray: #707070;

逆にXD側で修正した場合、ローカルに残っている「$707070」は別のものとして扱われるため結局

    $707070: #707070;
    $color_gray: #707070;
のようになります。

修正する場合は、XD側で修正し、VS Code側でエラーになっている変数をちまちま削除する方法しかなさそうです。
（上手い修正方法をご存知の方がいらっしゃれば、教えていただけると助かります。🙇🏻‍♂️）
gatsbyでMaterial UIのthemeのcolorを変更する（primary,secondary,background※surface）

`gatsby-browser.js` と `gatsby-ssr.js` とに

```react
import { createMuiTheme } from '@material-ui/core/styles'
import { ThemeProvider } from '@material-ui/styles'
```

して、
`<ThemeProvider theme={theme}>`でつつんであげると良い感じになります。

※メモ：
`gatsby-browser.js` と `gatsby-ssr.js` は、
gatsbyさん的には「中身を同じにしてね」というファイルだそう。
（ssrはサーバサイドレンダリングしてくれるファイルだそう。）

例えば下記のような形です。

```react
import { CssBaseline } from '@material-ui/core'
import React from 'react'
import { RecoilRoot } from 'recoil'

import { createMuiTheme } from '@material-ui/core/styles'
import { ThemeProvider } from '@material-ui/styles'

const theme = createMuiTheme({
  palette: {
    primary: {
      main: '#EF2D29',
    },
    secondary: {
      main: '#00A7C1',
    },
    background: {
      default: '#fff',
    },
  },
})

export const wrapRootElement = ({ element }) => {
  return (
    <RecoilRoot>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        {element}
      </ThemeProvider>
    </RecoilRoot>
  )
}

```

参考：
https://material-ui.com/customization/default-theme/#default-theme

ここからいじりたい値を参照してみよう！

![スクリーンショット 2020-10-22 22.43.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321986/f1d38eb2-058c-49ff-b1a0-5ef176e97898.png)
[個人開発] WEBブラウザ上でジャムセッションするプラットフォーム : loopridge

# あらまし

WebAudio APIを使って、ブラウザ上でジャムセッションできるプラットフォーム [Loopridge](https://loopridge.com/) を作って見ました。とは言っても、リアルタイムのセッションではなく、「ルーパー」の考え方で重ねどりして曲を作り上げる形式です。参加者は数小節の短いトラックを録音&アップロードし他の人のトラックに音を重ねていきます。すでにトラックを重ねるタイプのコラボプラットフォームはありますし、YAMAHA NETDUETTのようなリアルタイム性を追求したサービスもあります。ちょうどその中間的な発想です。

![スクリーンショット 2020-10-22 13.22.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58790/a157b57e-8291-762c-c4a3-763b6e2dc461.png)


# 何ができるの？
* ネット越しにルーパーベースのセッション・トラックメイキングを行えます。
* セッション部屋を作っていろいろな人とセッションできます。
* ループトラックのON/OFFのパターンを様々に組むことで、曲に展開を作ることができます。
* パスワード付きのクローズドな部屋も作れます。
* 録音はコンピュータにつながっている任意のデバイスから可能です。
* モバイル端末からも動きます（と思います。iPhone 11では動きました）

# 使い方
現状はトラックアップロードにはログインが必要です。聞くだけならログイン不要です。

1. 初回アクセス時は Audio Interfaceの有効かの確認ダイアログが表示されます。ブラウザから尋ねられますので有効化してください。（しないと録音できないです）
1. 部屋を選ぶ or 作る。すでにトラックがある場合はダウンロード & 再生されます。それなりに時間かかります。ダウンロードされたものから順次再生されます。
1. 必要であればデバイスの設定（右上メニュー -> Settings）から再生・録音デバイスを選んでください。
1. 右下からテンポと１トラックの長さ(小節数)を指定（一度指定するとこの部屋の中では変更できません)。 「Rec」ボタンで録音します。録音終わると再生されます。
1. （だいじ) 残念ながら現状ではたいてい録音されたトラックのタイミングが遅延(数十msec ~ 1秒程度) します(WEB Audio APIの現状の限界か） 「Timing」ボタンをクリクリしてタイミングを合わせてください。
1. トラック名を適宜入力して、緑色のアップロードボタンを押すとアップロードされます。 

とりあえず、好きに遊んでみてください！

例：
https://loopridge.com/?room=rxroww2MKSaKoT9wn3Jq
https://loopridge.com/?room=wLnRAMm9KQsfRyJnJtzn

# 開発に使った技術要素
* フロントエンド : Bootstrap, WebAudio API, Canvas, WEB Worker, ロスレス圧縮
* バックエンド : Firebase( Firestore, Firebase Storage, Firebase Authentication, Firebase Functions)

## 工夫など
* サイズが大きいオーディオファイルの扱い。録音はwavベースで行うので1秒で176kB. 10秒で1.7MB。ケチらなければそのままバックエンドに送り保存すれば良いが、帯域超過が怖いのでなんとか小さくしたい。ただmp3等は音質やデコード時間の関係等からあまり使いたくない。
 *  →  元の音源をflacライクなロスレス圧縮（しかもクライアントサイドで) をしてバックエンドに送信・保存。
(とは言っても依然帯域を食うので、Firebase無料枠が終了したら使えなくなるかも)
* 上記のような重めな処理をシングルスレッドのJavascriptでUser Experienceをそこわないで実施する必要がある。
 *  → WEB Workerやタスク細分化＆タスクキュー等を用いてUIブロックをなるべく避ける実装を実施。

## ご注意

* 実験的サービスです。トラック・セッション部屋の永続性は保証されません。
* 環境によってはうまく動かないことがあります。Mac + Chrome, Mac + Safari, Mac + Firefox であれば動くことは確認しています。非力なPCだと、音が途切れたり、ずれたり、スロー再生されたりします(Pen-Mのしょぼいwindows note PCだとこの現象でた）。
* それなりに帯域を食いますので、モバイルネットワーク上での使用はご注意ください。とは言っても動画サイトほどではないはず。
Nextでnext devなら動くのにnext buildでエラーが出て解決した

## 前提
- NextでWEBページ`index.js`とDB接続用のAPI`get-data.js`を定義
- `index.js`の`getStaticProps`で`get-data`APIを叩いていた

```js:index.js
import fetch from "node-fetch"

export async function getStaticProps({ params }) {
  // getStaticPropsでget-dataAPIを叩く
  const res = await fetch("http://localhost:3000/api/get-data")
  const data = await res.json()
  return { props: { data } }
}

export default function Index({ data }) {
  ...省略
}
```

```js:api/get-data.js
export default async (req, res) => {
  // DB接続してデータ取得
  const data = await getData()
  res.status(200).json(data)
}
```

## 現象
- `next dev`だと問題は発生せず、期待通り動いたのですが…
- `next build`だと以下のようなエラーが発生しました

```
$ next build
...省略
Compiled successfully.

Automatically optimizing pages ..
Error occurred prerendering page "/index". Read more: https://err.sh/next.js/prerender-error:
FetchError: request to http://localhost:3000/api/get-data failed, reason: connect ECONNREFUSED 127.0.0.1:3000
```

## 解決策
stack overflowにそのまんまな事象と解決策があったので参考にしました
https://stackoverflow.com/questions/61452675/econnrefused-during-next-build-works-fine-with-next-dev

[公式ドキュメント](https://nextjs.org/docs/basic-features/data-fetching#write-server-side-code-directly)に記載してある通り、
>You should not fetch an API route from getStaticProps — instead, you can write the server-side code directly in getStaticProps.

とのことなので**getStaticPropsでAPIルートを呼んではいけない**ようです。
getStaticPropsはサーバサイド処理のため、**APIで実行したい処理をそのままかけ**、ということでした。

## 変更後
```js:index.js
export async function getStaticProps({ params }) {
  // getStaticPropsでDB接続してデータ取得
  const data = await getData()
  return { props: { data } }
}

export default function Index({ data }) {
  ...省略
}
```

`get-data.js`は不要になったため削除しました

## ふりかえり
`next dev`だと問題ないのに`next build`だとエラーが発生する意味がわからなく、ポートを固定したのがよくなかったのか？とか`build`で外部APIの接続確認を行っているオプションを外せないか？などかなりはまってしまいました。。解決してよかったです。

そもそもgetStaticPropsはビルド時にサーバサイド側で走る処理なので、DB接続があるからといってAPIを経由する必要はありませんでした。DB処理をAPI側にまとめたいと思って余計なことをしていました…。ドキュメントちゃんと読め、という話ですね。。反省…
WebView内のテキストフィールドタップ時のキーボード種別

WebView内のテキストフィールドを選択した時に表示されるキーボードのタイプは、何によって決まるのか調べました。今回は```SFSafariView```で試していますが```WKWebView```でも同じはずです。

## 結論
htmlの```type```の指定によって表示されるキーボードの種類が変わります。

```
// 普通のキーボード
<input type="text" size="20" maxlength="30">

// PhonePad 
<input type="tel" size="20" maxlength="30">
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290717/78974021-4f6b-05f9-52f1-f4edf828fa34.gif" width="240">

これ以外にもtypeに```url```や```email```を指定することで、それぞれに応じたキーボードを表示させることができます。
wgetしたzipファイルを保存せずにjarコマンドで直接解凍する

## 使い所

- `jar`コマンドが使えるならば・・・の話のため、使い所は少ない
- githubとかからzipファイルをwgetやcURLで取得し、標準出力へリダイレクトさせ、jarファイルで解凍、とやれる
- zipファイルを保存、解凍、削除という手間が減る

## 例

```bash
# watchmanのビルド済みバイナリをgithubから落としてきて、使えるようにする
wget -qO- https://github.com/facebook/watchman/releases/download/v2020.09.21.00/watchman-v2020.09.21.00-macos.zip | jar xvf /dev/stdin
# 確認
cd ./watchman-v2020.09.21.00-macos
# 移動
tree ./
sudo mv ./lib/*.dylib /usr/local/lib
sudo mv ./bin/watchman /usr/local
```

c.f. homebrew経由のwatchmanインストールは都度`./configure`, `make`, `make install` が必要

## `unzip`ではダメだった

### 最新版 `v6.1` ではサポート外

MANページに、unzipは標準入力からの読み込みに非対応、と記載

>Archives read from standard input are not  yet  supported,
       except  with funzip (and then only the first member of the
       archive can be extracted).

https://opensource.apple.com/source/zip/zip-6/unzip/unzip/unzip.txt.auto.html


### `v8.0` でサポートされる（時期未定）

>Future Plans

と題して、`zipfile from standard input` の解凍のサポートが謳われている

> And then perhaps version 8.0 will be released, with full filter support (that is, able to read and extract a zipfile from standard input like fUnZip does now), but now we're really dreaming.


http://infozip.sourceforge.net/UnZip.html
Laravel:バリデーションをスマートかつ、任意メッセージを作成

【概要】
----------------------------------------
<b>1.結論</b>

<b>2.どのようにコーディングするか</b>

<b>3.開発環境</b>



1.結論
----------------------------------------
<b>FormRequestを作成し、rulesに検証ルールを用いて、messagesメソッドで任意のメッセージ</b>を記載する！

<br>
2.どのようにコーディングするか
----------------------------------------

まずFormRequestを作成します。

```console
php artisan make:request HogeRequest
```
なぜFormRequestを作成するのかというと、その方が機能としてスマートだからです。Controllerにも記載することは可能ですが、コントローラーはViewやModelに指示を送る橋渡し役がメインになります。バリデーションをする役目ではなく、クライアントからリクエストされた際にリクエスト内部でバリデーションの機能を実行した方がスマートだからです。

上記で作成した後にControllerに下記の記載を忘れないでください。

```php:app/HttpControllers/HogeController.php
use App\Http\Requests\HogeRequest;
```
このように記載しないと下記に記載するHogeRequest.phpが機能しません。


```php:app/Http/Requests/HogeRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class HogeRequest extends FormRequest
{
    public function authorize() #---❶
    {

        if ($this->path() == 'hoge') #---❷
        {
            return true;
        }else{
            return false;
        }
     }

    public function rules() #---❸
    {
        return [　
            'name' => 'required',
            'mail' => 'email',
            'age' => 'numeric|between:0,150',
        ]; #---❹
    }

    public function messages() #---❺
    {
        return [
            'name.required' => '名前は必須です',
            'mail.email' => '適切なemailを入力してください',
            'age.numeric' => '年齢は整数で入力してください',
            'age.between' => '適切な値を入力してください'
        ]; #---❻
    }
}

```
❶：authorizeで、FormRequestが許可されているかどうかチェックします。
❷：アクセスしたパスをチェックしています。hoge以外は通さないようにしています。
❸：rulesで、バリデーションの機能を果たしています。
❹：blade.php(view)におけるname要素(name,mail,age)を指定し、検証ルール(required,email,numeric|between)に則ってコーディングしています。
❺：FormRequestのmessagesメソッドをオーバーライドしています。つまり親クラス(FormRequest)のメソッドを子クラス(HogeRequest)で再定義しています。記述していないルールがあった場合は親クラスがそのままレンダリング(英語表記)されます。
❻：❹と同じようにコーディングします。その際に'name要素.検証ルール(❹で設定したルール)' => '任意のメッセージ'を記載すると、アプリ制作者が意図したメッセージを表示できます。



<br>
3.開発環境
----------------------------------------
PHP 7.4.10
Laravel 8.9
<br>
FeliCaの種類

## 種類

### FeliCa Standard

一般的なFeliCaと呼ばれるもの
Suica等の交通系ICや電子マネーはここに属しています。

### FeliCa Lite

FeliCa Standardの下位互換は保ちつつ、チップの小型化やコスト削減のためにセキュリティ機能を簡略化しています。
ICチケットや社員証に使われてることが多いです。

### FeliCa Plug

組み込み型のモジュールFeliCa
マイコンと接続し、カードを作ることができ、FeliCa対応リーダー/ライターとデータ転送が可能になります。
[ここ](https://www.switch-science.com/catalog/321/#:~:text=FeliCa%20Plug%E3%81%AF%E3%80%81FeliCa%E3%81%AE,%E3%81%8C%E5%8F%AF%E8%83%BD%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)から購入することが出来ます。

### FeliCa Link

組み込み型のモジュールFeliCa
`FeliCa Lite` と `FeliCa Plug` が組み合わさったようなもの
省電力で、様々な機能があります。


## 参考

- [FeliCaとは？—構造・スペック・特徴・種類・利用例をまとめて調べてみたぞ！](https://8vivid.net/whats-felica/)
- [feliCaとは？さまざまな種類のICカードに使われているその理由](https://www.japan-card.jp/newcards/post-4812/)
- [RC-S967・RC-S730](https://www.sony.co.jp/Products/felica/business/products/RC-S967.html#:~:text=FeliCa%E2%84%A2%20Link%E3%81%AF%E3%80%81FeliCa,%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%9F%E8%A3%BD%E5%93%81%E3%81%A7%E3%81%99%E3%80%82)