OmniAICreator/Qiita-1.07M huggingface dataset:
データを配列ではなく、オブジェクトの形で保存できるstdClassを使いましょう !!  

# データを配列ではなく、オブジェクトの形で保存できるstdClassを使いましょう !!

バックエンドでAPIを作成しJson形式でフロントに渡す実装をする時、
ローカル環境とテスト環境で挙動が違ってハマった点を記載します。

## データを配列でJson形式に渡した時
```
        foreach ($payslipList as $key=>$value) {
            //合計金額の計算
            $total =$value->amount_tax  -$rental_amount_tax;

            //合計金額がマイナス時は一覧に出力しない
            if($total > 0){
                //API
                $payslipData[$key]['year'] = $year;
                $payslipData[$key]['month'] = $month;
                $payslipData[$key]['text'] = $year . '年'. $month .'月度　御支払通知書'
            }
        }
 ```
 
配列dataのキーが連続でない下記のAPIの場合、フロントではオブジェクトとして受け取れるが、

```
{
   “status”: 200,
   “response_time”: 1.8469810485839844,
   “message”: “処理を完了しました。“,
   “data”: {
       “0": {
           “year”: “2019",
           “month”: “11",
           “text”: “2019年11月度　御支払通知書”
       },
       “2”: {
           “year”: “2019”,
           “month”: “09”,
           “text”: “2019年09月度　御支払通知書”
       }
   }
}
```

しかし、配列dataのキーが連続である下記のAPIの場合、フロントでは配列として受け取れるらしい

```
{
    "status": 200,
    "response_time": 2.6169888973236084,
    "message": "処理を完了しました。",
    "data": [
        {
            "year": "2019",
            "month": "11",
            "text": "2019年11月度　御支払通知書"
        },
        {
            "year": "2019",
            "month": "09",
            "text": "2019年09月度　御支払通知書"
        }
    ]
}
```

## stdClass利用してデータを配列に渡した時
```
        foreach ($payslipList as $key=>$value) {
            //合計金額の計算
            $total =$value->amount_tax  -$rental_amount_tax;

            //合計金額がマイナス時は一覧に出力しない
            if($total > 0){
                //API
                $payslipJson = new \stdClass();
                $payslipJson->year = $year;
                $payslipJson->month = $month;
                $payslipJson->text = $year . '年'. $month .'月度　御支払通知書';
                $payslipData[] = $payslipJson;
            }
        }
        
```
配列dataのキーがいつも連続なので、フロントではいつも配列として受け取れるようになる。

```
{
    "status": 200,
    "response_time": 2.8132009506225586,
    "message": "処理を完了しました。",
    "data": [
        {
            "year": "2019",
            "month": "11",
            "text": "2019年11月度　御支払通知書"
        },
        {
            "year": "2019",
            "month": "09",
            "text": "2019年09月度　御支払通知書"
        }
    ]
}
```

# 参考サイト
http://phpspot.net/php/pgPHP%E6%A8%99%E6%BA%96%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AEstdClass%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6.html
python：インスタンスメソッド


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


##確認：　インスタンスメソッドとは
pythonのクラスの中で定義した関数のことです。

#第一引数 self
クラスの中では関数を定義できます。
この、クラスの中で定義した関数のことを**メソッド**と呼びます。
メソッドの定義では、以下のように第一引数にselfを追加する必要があることに注意です！
```def hello(self):```
このselfには、インスタンス自身が代入されています。

このメソッドを呼び出す記載方法は、
```インスタンス名.メソッド名()```
です。
インスタンスが変数に代入されている場合は、```変数.メソッド名()```になります☺︎

#printとreturnの運用方法の違い
####printの場合
def内でprintとしていれば、```menu_item1.info()```のようにそのまま使用できます。

```
class MenuItem:
    def info(self):
        print(self.name + ': ' + str(self.price))

menu_item1 = MenuItem()
menu_item1.name = 'サンドイッチ'
menu_item1.price = 500

# menu_item1.info()の値を出力してください
menu_item1.info()
menu_item2 = MenuItem()
menu_item2.name = 'チョコケーキ'
menu_item2.price = 400

# menu_item2.info()の値を出力してください
menu_item2.info()
```

####returnの場合
def内でreturnとしていると、```print(menu_item1.info())```のように、出力しなければなりません。


```
class MenuItem:
    def info(self):
        # print()の中身を戻り値として返してください
        return self.name + ': ' + str(self.price)


menu_item1 = MenuItem()
menu_item1.name = 'サンドイッチ'
menu_item1.price = 500

# menu_item1.info()の値を出力してください
print(menu_item1.info())
menu_item2 = MenuItem()
menu_item2.name = 'チョコケーキ'
menu_item2.price = 400

# menu_item2.info()の値を出力してください
print(menu_item2.info())
```

#特殊なインスタンスメソッド＿init＿
＿init＿メソッドは、クラス名()でインスタンスを生成した直後に自動的で呼び出されるものです。
これをすれば、インスタンスの生成と同時に、インスタンスに値が代入できます。[pythonでのメニュー作成方法](https://qiita.com/r_Ran/items/17398f0424c97f69f96a)のStep2,3が同時にできるということです。

つまり通常以下のように書かなければいけなかったところを、

```
menu_item1 = MenuItem()
menu_item1.name = 'サンドイッチ'
menu_item1.price = 500
```

defの部分を＿init＿メソッドを使って以下のように書くことで、

```
    def __init__(self):
        self.name = 'サンドイッチ'
        self.price = 500
```


```menu_item1.name = 'サンドイッチ'```や```menu_item1.price = 500```
が省けるということです！

こちらの方が関連のある情報がまとまっていて、わかりやすいですね😊

また、＿init＿メソッドに引数を渡すことで、値のバリュエーションを増やせます。
詳しくいうと、
```
    def __init__(self):
        self.name = 'サンドイッチ'
        self.price = 500
```
このように具体的な数値を代入するのではなく、
```
    def __init__(self, name, price):
        self.name = name
        self.price = price
```
とするということです。

##参照
・progate python　ⅳ
iOSとそれ以外のOSのブラウザでスクロールイベントを取得する方法

# はじめに

手持ちのiOSでのスクロールイベントの取得で詰まったりしたので備忘録。

# スクロール量の取得
以下の4つのどれかを参照する事でスクロール量を取得可能である。

- document.documentElement.scrollTop
- document.body.scrollTop
- window.pageYOffset
- window.scrollY

`document.documentElement.scrollTop`と`document.body.scrollTop`はどちらか片方しか定義されていないブラウザが多いので、参照するなら以下のようにすべきだろう。

```js
document.documentElement.scrollTop || document.body.scrollTop
```

<details><summary>参考：各ブラウザにおけるスクロール量の値</summary><div>

Macの各ブラウザのコンソールから以下のイベントを生やしてログを見た。

```js
window.addEventListener("scroll", function () {
  console.log(document.documentElement.scrollTop + "," + document.body.scrollTop + "," + window.pageYOffset + "," + window.scrollY);
}, false);
```

***結果***

|ブラウザ|document.documentElement.scrollTop|document.body.scrollTop|window.pageYOffset|window.scrollY|
|---|---|---|---|---|
|Chrome|120|0|120|120|
|Firefox|120|0|119.80000305175781|119.80000305175781|
|Safari|120|0|120|120|
|Opera|120|0|120|120|

</div></details>

# PCとAndroidにおけるスクロールイベントの取得
PCやAndroidでは以下のようにaddEventListenerの[scroll](https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event)イベントでスクロールの座標を取得できる。

```js
window.addEventListener("scroll", function () {
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
}, false);
```

# iOSにおけるスクロールイベントの取得
iOSではscrollイベントが発火されない。
なので[setTimeout](https://developer.mozilla.org/ja/docs/Web/API/WindowTimers/setTimeout)を使って随時`window.pageYOffset`を取得し、スクロールイベントを検知する。

```js
setTimeout(function () {
  var scrollTop = window.pageYOffset;
}, 10);
```

上のコードでは指を離した後の慣性スクロールも検知可能。
setTimeoutのディレイミリ秒数は状況に応じて自由に変更してください。

## 参考：touchmoveとtouchendは使えないのか?
[touchmove](https://developer.mozilla.org/en-US/docs/Web/API/Document/touchmove_event)と[touchend](https://developer.mozilla.org/en-US/docs/Web/API/Document/touchend_event)を用いる事で以下のように指によるスクロールイベントを検知可能である。

```js
function scrollChange () {
  var scrollTop = window.pageYOffset;
}
window.addEventListener("touchmove", scrollChange, false);
window.addEventListener("touchend", scrollChange, false);
```

しかし、上のコードは実際には使い物にならないだろう。
理由は**指を離した後の慣性スクロールを一切検知できない**からである。

# どのOSでもスクロールイベントの取得する方法

[onscroll](https://developer.mozilla.org/ja/docs/Web/API/GlobalEventHandlers/onscroll)イベントハンドラーを使えばOSに関わらずスクロールイベントを取得可能。
ただし、addEventListenerと違って複数ハンドリングできず、他のjsに関数を書き換えられる可能性すらあることに注意。

```js
window.onscroll = function () {
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
}
```
Devise (Warden) + Redis で管理してる Rails のセッションから特定ユーザのものを破棄する

# 何がしたいか

session_store に Redis かつ Devise で認証を管理してる Rails アプリの特定ユーザのセッションをすべて破棄したい。

# どうやるか

セッションストアから対象ユーザのセッション情報を割り出して削除すれば良い。

Railsはセッションストアに `sessions:session_id`(session_idはRailsが発行したsession_id) ってキーでセッション情報を保持する。Wardenはそのセッション情報の中に `warden.user.user.key`(そのまま)ってキーでユーザIDなどの認証情報を保持する。


```ruby
mapping = 'user'
user_id = 42

# Redisからすべてのセッション情報を抽出
Redis.current.keys('sessions:*').select { |key|
  # セッション情報の実態を取り出す
  user_hash = Marshal.load(Redis.current.get(key))
  # ユーザを特定
  user_hash["warden.user.#{mapping}.key"][0].include?(user_id)
rescue
  false
}.each { |key|
  # 特定したユーザのセッションを破棄
  Redis.current.del(key)
}
```

野蛮かつ不穏な感じ…実施は自己責任で。

# リンク集

- [Device](https://github.com/plataformatec/devise/)
- [Warden](https://github.com/wardencommunity/warden)
- [RedisStore](https://github.com/redis-store/redis-store/)
    - Rails の session store を Redis に対応させるやつ
- [Redis](https://github.com/redis/redis-rb)
    - Ruby の Redis クライアント. RedisStoreはRedisとこれで通信してる
- [Marshal](https://docs.ruby-lang.org/ja/latest/class/Marshal.html)
    - RedisStoreは(昔の)デフォルトだとRedisに保存するデータを Marshal でシリアライズする
    - `Marshal.load` は未検証の値に使っちゃダメ。
- [[Rails] deviseのセッション(session)はどのように決められているのか - Qiita](https://qiita.com/sada4649/items/aefa728148cba68f2d6a)
    - Devise -> Warden のコードリーディングの記事。とてもわかりやすい
Digdagでエラー発生時にSlack通知をする

# 概要
Digdagでエラー発生時にSlack通知をする。
Slackのincoming-webhookアプリでWebhook URLの発行を事前にしておき、下記`SLACK_INCOMING_WEBHOOK_URL`の値として記載する。
※以下サンプルは`#general`に`@channel`通知なので注意。

```digdag:slack_test.dig
_export:
  SLACK_INCOMING_WEBHOOK_URL: https://hooks.slack.com/services/xxxxxx/xxxxxx/xxxxxxxxxxxxxxxxxxxxx

_error:
  http>: ${SLACK_INCOMING_WEBHOOK_URL}
  method: POST
  content:
    username: "Digdag workflow"
    icon_emoji: ":x:"
    channel: "#general"
    attachments:
    - title: "Workflow failed!"
      text: <!channel> Error occurred! ${task_name}
      color: danger
  content_format: json

# 存在しないシェルを実行してエラー終了する
+step1:
  sh>: sh exec_not_exist.sh
```

# 実行

```bash
> digdag run test.dig -a
```

# 結果（Slack通知）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24897/c5d17edd-698d-6f30-f97d-1922c0649f3a.png)

# メモ
エラー発生時に以下の様に `${error.message}`, `${error.stacktrace}` でエラーの内容を参照・通知可能。

```
      text: <!channel> Error occurred! ${error.message}, ${error.stacktrace}
```

ただし下記の通り、Digdag自体のエラーなので見る必要なさそう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24897/d142d112-8c6c-141f-fc24-0212993d65b1.png)


# 参考
https://qiita.com/hoto17296/items/51d77f6e4d3be891e084
AWSチュートリアル解読：第一回

#AWSチュートリアル
AWSを実際に触ってみようと思っても、何をどうすれば良いか分からない...そんな時は...
こんにちは、学生アルバイトのsosonoです。
今回は簡単にLambda、APIGateway、S3、DynamoDB、Cognitoが体感できるAWSチュートリアルを詳説していきます。全４回の予定です！！
以下のリンクから手順に沿って、数時間で完了できます。
<a href="https://aws.amazon.com/jp/getting-started/projects/build-serverless-web-app-lambda-apigateway-s3-dynamodb-cognito/">AWS公式チュートリアル</a>

チュートリアル概要です。
![スクリーンショット 2019-10-25 19.43.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379839/41a73435-f611-566b-c504-a3c383c84558.png)

チュートリアルは理解しながら進めるべきです。ということで、初心者ながら気になった部分を整理してみました。今回は第一回めの記事になります！（上記❶の部分に該当します！！）

以下のステップは実際のチュートリアルのステップに対応しています。

##(ステップ１)リージョンを選択する

バケットや後出のLambda関数は全て同じリージョンで作成する必要があります。<br>コスト最小化などを考えて、地理的に近い部分にするべきでしょう。

##（ステップ2）S3バケットを作成する

作成自体は簡単です。名前が一意になるようにすることに注意すればたります。

##(ステップ4)パブリック読み込みを許可するバケットポリシーを追加する

コピペさせることから分かるように（？）S3ではここが一番不明瞭。少し整理してみる。
<a href="https://qiita.com/ryo0301/items/791c0a666feeea0a704c">[Qiita]S3のアクセスコントロールまとめ</a>
この記事でほとんど把握できるはず。。。


###パブリックアクセス（設定機能）

チュートリアルでは4つのチェックボックスがあって、よく分からないままポチポチさせられた。
ACL、バケットポリシーの公開設定をブロックしたりする機能で、イメージとしては下述バケットポリシーの監視役みたいな感じ。他にも既存の公開設定の削除なども可能。

- 4つのチェックボックスを整理してみると、、、

 - ACLの公開に関する設定<br>
       - 新規バケット、オブジェクトへのACLをブロック
       - 全てのACLを無視
 - バケットポリシーの公開に関する設定<br>
       - バケットポリシーによる、バケット・オブジェクトへのバケットポリシーをブロック
       - バケットポリシーによる、バケット・オブジェクトへのパブリックアクセス、クロスアカウントアクセスを無視

という作りになっている。これをポチるだけでアカウント全体を管理できるという優れもの。  
このチュートリアルでは、ACLの公開に関する設定、の部分にチェックを入れているので、ACLはブロック、無視しようとしているということが分かります。

###バケットポリシー
バケットに対してアクセス管理を行います。今回のチュートリアルでコピペするのがこれ(JSON形式)。
バケットポリシーがなければ、アクセスは全て拒否される。それはこちらとしてもまずい、、、

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow", 
            "Principal": "*", 
            "Action": "s3:GetObject", 
            "Resource": "arn:aws:s3:::[YOUR_BUCKET_NAME]/*" 
        } 
    ] 
}
```

詳しく見ていきます。

- "Effect":Allow
バケットへの操作を許可しておいて、、、

- "principal"
特定のIAMユーザからのアクセスを許可するために使用

- "Action"
バケットのARNを指定する（ARNは第二回以降登場します。今はふーんくらいで。。。）

- "Resource"
このポリシーの対象となるリソース（先ほど作成したバケットのこと）

これによって新しいポリシーが追加される<br>（という動作になっていたことはチュートリアルでは触れられていない、、、）

###注意

コピペした後、[YOUR_BUCKET_NAME]を変更するが、　[]まで含めて変更すること（詰まりそうなポイント！！！）
この後に”保存”を押すと、”このバケットにはパブリックアクセス権限があります”と表示されるが気にしないこと（チュートリアルなのだから、、、）

##(ステップ５)ウェブサイトのホスティングを有効にする

S3のバケット内に、静的ウェブサイトをホストできる。サイトにアクセスできるようにウェブサービスの実行、他のサービスの使用、等は必要ないのです。

##(ステップ６)実装を検証する

あとはウェブエンドポイントURLをクリックするだけです！！！

#まとめ

第一回はS3に関するチュートリアルでした。よく分からないままコピペさせられると、チュートリアルを完了しても腑に落ちない感じがして嫌です。。。
この調子であと3回、作っていけたらなと思います。
Android Studioについて

Android Studioで、スマホのアプリケーションを作成しようと”足掻”いている超初心者です。											
Android Studioを学習する中で、自身のPC仕様の関係で、エミュレータ起動が不可。											
で、GenymotionとVirtualBoxwoを構築しました。											
で、教えて頂きたいのですが、作成した、アプリケーション（未完成）をGenymotionに、インポートして、動作を確認する。											
と、言う理解でいいのでしょうか？
お色直ししたAzureポータルを自在にカスタマイズ！

# はじめに
前回、["メニューバーやアイコンが変更！？　Azureポータルがお色直し！"](https://tech-blog.cloud-config.jp/2019-10-16-menu-bar-and-icons-have-changed-in-azure-portal/)で、Azureポータルのデザイン変更部分を紹介しました。  
今回は、Azureポータルのデザインを自在にカスタマイズできる方法について紹介します。  
ちなみにカスタマイズできるのは以下の４つです。

- 既定のビュー（Microsoft Azureアイコンを押したときに遷移するページ）
- メニューバー
- テーマ
- ハイコントラストのテーマ

この中から今回は見た目が大きく変わる「既定のビュー」と「メニューバー」について紹介します。

# 既定のビュー
既定のビューとはMicrosoft Azureアイコンを押したときに遷移するページのことです。  
現在、ホームとダッシュボードが選択でき、それぞれ設定すると、以下のようになります。
![2019-10-29-customize-your-customized-azure-portal-001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/b96fa6c7-3d6a-2c75-b690-3f28121bc4cc.png)
# メニューバー
前回の記事でも取り上げたメニューバーとリソースウィンドウ展開の変化をどちらにするか設定することができます。  
Flyoutを選択するとハンバーガーメニュー＋左上に階層構造が表示され、Dockedを選択するとメニューバー＋左側にどんどん列が追加されていきます。
![2019-10-29-customize-your-customized-azure-portal-002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/30e92b84-0b60-81ee-ff9c-ae25e7c5d08c.png)
# おわりに
今回は、Azureポータルのデザインで既定のビューとメニューバーを自在にカスタマイズできる方法について紹介しました。  
使いやすいようにカスタマイズして、Azure Portalをより使いこなしていきたいですね。
CentOS7にnginxのバージョンを指定してインストール

nginx の最新は1.17.5　(2019/10/29 現在)

1.17.4を取得したい場合

```console
$ rpm -ivh http://nginx.org/packages/mainline/centos/7/x86_64/RPMS/nginx-1.17.4-1.el7.ngx.x86_64.rpm
```

もしくは

```console
$ vi /etc/yum.repos.d/nginx.repo
```

以下追加

```console
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
```


///////////////////////////////////////////////////
$releasever
/etc/yum.conf の distroverpkg の値
distroverpkg=centos-release

$basearch
x86_64
///////////////////////////////////////////////////

```console
$ yum search --showduplicate nginx --enablerepo=nginx-mainline
$ yum install nginx-1.17.4-1.el7.ngx.x86_64 --enablerepo=nginx

$ nginx -v
nginx version: nginx/1.17.4
```
JavaScript で繰り返し処理内の非同期処理を同期的に行いたい

#はじめに
最近Chrome拡張機能を作ろうと、JavaScriptを触り始めました。
漏れなく非同期処理というものにハマったので、繰り返し処理でPromiseしたいという初心者向けの覚書です。

Promiseやasync/awaitに関しては素晴らしい記事がたくさんあるので、Google itしてください。
#細かいお話
今回私がやりたかったのは、クローリングを自動化するChrome拡張機能を作成することです。
これにあたって、以下の作業を同期的に繰り返し行う必要があります。

1. ページをクロール
2. 結果が取れているか確認
3. 次のページへ
4. ページのロードが完了したら1へ

ことChrome拡張機能においては特に、クローリングやページロードは全て非同期的に行われるのが
めちゃくちゃ厄介でした。
Javascript初心者だったので、はじめはなぜ結果が戻ってこないのかすらわからない。
promiseやasync/awaitを覚えたところで、繰り返し処理の中にどうやって使うの・・・？
て感じで四苦八苦しましたが、まあ割と簡単に簡潔に書けたみたいです。

#書いたコード
煩雑になるので中の処理や例外処理は全部省いて、概要だけ。
*(10/30 コメントいただいて訂正しました)*


```javascript:promise.js
var promise = Promise.resolve();
promise.then(function loop(count) {
    setTimeout(function() {
        crawling(hoge).then(function (res_s) {
            return jump()
        }).then(function (res_j) {
            return wait()
        }).then(function (res_w) {
            return loop()
        });
    }, 2000);
    count++;
}(count));
```

##内容
要は再帰関数です。
最初にresolve済みのPromiseを一つ生成してあげて、thenで再帰関数「loop」を定義してあげます。
再帰関数の中には、実行したい処理を順にthenで繋いであげて、最後にloopに戻れば、順番に実行した後頭に戻る（再帰的に実行する）処理となります。

色々と試行錯誤しましたが結局一番シンプルにうまく実装できたのがこの形式でした。
- 配列にPromiseを入れて、前のPromiseが終わるまで待ってみようとか
- async/awaitでなんかうまいことできないかなとか
方法はもっと色々あるのかもしれませんが、初心者にはPromise/thenが最もシンプルで理解しやすいのかなと。

#当たり前ですが
コード内のcrawlingやjump,wait等の関数は全てPromiseを返す関数です。

```javascript:crawling.js
function crawling(hoge) {
    return new Promise(function(resolve) {
        /* クロール処理をかく */
        resolve(response);
    });
}
```

#おわりに
JavaScriptがとっても厄介な言語だということがわかりましたが、めげずに頑張っていこうと思います。
何かアドバイス等ございましたらコメントまでお願いします。

作成した拡張機能についても今後記事を書いていきたいです。
AWSへデプロイしてみよう（〜EC2インスタンス作成 その１）

# AWSへデプロイする為に必要なこと
vimの基礎知識
AWSのアカウント


## １．vimの基礎知識
- vimでは、カーソルをカーソルキーではなく(h,j,k,l)を使用して動かします。(カーソルキーでも動く場合があります。)
- 編集する時は、iを押して編集モード（insert mode）にします。
- カーソルを動かすときや、vimコマンドを実行する時は、escキーを押して通常モードにします。
- ファイルを保存するときは、通常モードにして、`:wq`を入力し、エンターを押します。
- ファイルを開いて何もせずに閉じたい場合、通常モードにして、`:q!`を入力し、エンターを押します。

### 1.1 catコマンド
catコマンドを使用することでファイルの中身を、ターミナルに出力させることができます。

### 1.2 ユーザーには管理ユーザーと一般ユーザーがある
管理ユーザーは全てのファイル・フォルダに権限を持ち、一般ユーザーはそれぞれ持つ権限が異なります。
権限を確認するには ls -l コマンド（ls -la)。

```
Akihiro-no-MacBook-Pro:hoge Akihiro$ ls -la
・
-rw-r--r--    1 Akihiro  staff     0  8  1 17:36 .moge
drwxr-xr-x    2 Akihiro  staff    68  8  2 14:25 fuga
-rw-r--r--    1 Akihiro  staff     0  8  1 17:31 fugafuga
-rw-r--r--    1 Akihiro  staff     0  8  1 17:31 hogehoge
-rw-r--r--    1 Akihiro  staff     9  8  1 18:16 poge
```
権限は、-rw-r--r--の部分で確認することができます。

```
1列目　フォルダかファイルかシンボリックリンクであるか
2〜4列目　所有者に対しての権限
5〜7列目　所有グループに対しての権限
8〜10列目　その他のユーザーに対しての権限
```
1列目 フォルダかファイルかシンボリックリンクであるか?
ファイルの場合は-、フォルダの場合は、dになり、シンボリックリンクの場合lになります。

２列目以降は権限を表します。
権限は３種類。

```
r read(読み取り権限)
w write(書き込み権限)
x execute(実行権限)
```

2〜4列目は、所有者に対しての権限を表しています。
rw- となっていたら、この所有者はread/write権限を持っています。

5〜7列目は、所有グループに対しての権限を表しています。
8〜10列目は、その他のユーザに対しての権限を表しています。

### 1.3 権限の変更
権限を変更するためには、chmodコマンドを使用します。
chmodコマンドを使用する場合、権限は数字で表されます。

```
4　r read(読み取り権限)
2　w write(書き込み権限)
1　x execute(実行権限)
-------
6　rw-　
4　r--
5　r-x
7  rwxという権限、つまり全ての権限を持っていた場合7になります。
```

## 2. AWSでサーバを構築する
EC2のインスタンスを作成する。

### 2.1 AWSアカウントの作成
詳細省きます。

### 2.2 EC2インスタンスの作成
画面右上でリージョン「アジアパシフィック（東京）」を選択します。
さらに「インスタンスの作成」ボタンをクリックします。

ステップ 1: Amazon マシンイメージ (AMI)
複数の選択肢がありますが、ここでは[Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type]を選択します。

次は「ステップ 2: インスタンスタイプの選択」画面になりますが、無料プランではt2.microしか選択できませんので、そのまま選択して次へ進みます。

次は「ステップ 3: インスタンスの詳細の設定」画面になります。ここでは設定することはないので、次に進みましょう。

次は「ステップ 4: ストレージの追加」画面になります。 
ここでは、サイズは8、ボリュームタイプは汎用になっていることを確認してから、「次の手順：タグの追加」をクリックしましょう。

次は「ステップ 5: タグの追加」画面になります。 
今回は「キー」に「name」、「値」に「（アプリ名）-production」と入力してから「次の手順：セキュリティグループの設定」に進みます。

次は「ステップ 6: セキュリティグループの設定」画面になります。
セキュリティグループとはファイアウォールのようなものでアクセス制限をします。この設定を記述することで、どの部分からどのようにEC2サーバー（インスタンス）へのアクセスを許すかの設定を行うことができます。
今回はブラウザなどからアクセスするためのhttpと、コンソールからEC2にログインするためのsshへの通信を許可しましょう。
sshは最初から設定されているので、httpのルールを追加します。
ルールの追加ボタンを押下すると行が一つ増えます。 増えた行のタイプの欄でセレクトボックスからhttpを選択します。
ここでは、セキュリティグループ名と説明欄を、（アプリ名）-sg-ec2とします。

![スクリーンショット 2019-10-29 16.48.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455406/5c75eb26-6194-78b5-33cb-4ade7177df6c.png)

最後にインスタンスの確認を行うと、「既存のキーペアを選択するか、新しいキーペアを作成します」というポップアップ画面が表示されます。

新しいキーペアの作成」を選択します。 キーペア名は何でもよいです。
続いて、[キーペアのダウンロード]ボタンをクリックします。これにより、キーペアの秘密鍵（achieve-key.pem）がPCにダウンロードされ、EC2とSSH接続をするための事前準備ができたことになります。

キーペアの秘密鍵（achieve-key.pem）のダウンロードが完了しましたら[インスタンスの作成]をクリックします。
これでEC2インスタンスが作成できました。

続きます。。
Nuxtで完了画面などへの直接アクセス（SSR時）を拒否する方法

## Nuxtで直接アクセスさせないページを作成する
Nuxt.jsのuniversalモードでの開発で、応募や購入など何らかのアクション後の完了画面で直接アクセスをさせない方法を紹介します。

### ミドルウェアを使って直接アクセス禁止機能の実装

ミドルウェアを使って簡単に実装・持ち回りができます。
早速、以下コードになります。

```js:/middleware/reject-direct.js
export default function ({ ssrContext, redirect }) {
  if (ssrContext) {
    redirect('/')
  }
}
```
Nuxtでは、SSR時に`ssrContext`に値が設定されるので、
それがあるかないかだけのシンプルな判定で直接アクセスを拒否して、別のページに飛ばす機能を実現できます。
使い方は、このミドルウェアを直接アクセス禁止にしたいページで持ち回るだけです。

### 作成した直接アクセス拒否のミドルウェアをページコンポーネントで読み込む
普通にscript内で`middleware: 'reject-direct'`と書いて、利用ミドルウェアを設定します。
完了ページは検索エンジンに載せたくないと思いますので、metaタグの`noindex,nofollow`も合わせて設定しています。

```completed.vue
<template>
  <section>
    <h1>完了</h1>
    <p>完了しました</p>
  </section>
</template>

<script>
export default {
  middleware: 'reject-direct',
  layout: 'default', //各自、任意のレイアウトを指定してください
  head () {
    return {
      title: '完了',
      meta: [
        { hid: 'description', name: 'description', content: '完了ページです' },
        { hid: 'robots', name: 'robots', content: 'noindex,follow'}
      ]
    }
  }
}
</script>
```

### まとめ
- ミドルウェアで汎用的なアクセス制限機能をつくれる
- SSR時に設定されるコンテキストを使って、直接アクセスを判定する
- ページコンポーネントで作成したミドルウェアを設定する

Nuxtでのアクセス制御、特に直接アクセスを拒否したいときの参考になれば幸いです。

### 参考にしたページ
Nuxtで、SPAモードで開発している方はこちらが参考になるかと思います。
https://qiita.com/howdy39/items/2587d7950acc39d468d7
pythonでのメニュー作成方法

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

#メニュー作成の流れ
pythonでメニューという”もの”(インスタンス）を作るには、
設計図（クラス）を用意する必要があります。

Step1.設計図(クラス)を用意する。
Step2.クラスからインスタンスを作成する。
Step3.インスタンスに情報を追加する。

##Step1.設計図(クラス)を用意する。
クラスは
```class　クラス名:```
とすることで定義できます。
✔︎クラス名の最初は大文字
✔︎さいごに:が必要
なことに注意しましょう！

クラスの中身はインデントをして書き始めましょう！
例えば、
```class MenuItem:
(インデント)pass
```
だと、何も処理がないことを示しています。

##Step2.クラスからインスタンスを作成する。
クラス名()
としてクラスを呼び出し、クラスを用いて新しいインスタンスを作ることができます。
また、変数にクラス名を代入して、作ったインスタンスを変数に代入することもできます。

##Step3.インスタンスに情報を追加する。
ここでは、インスタンス変数を用いて、情報を追加して行きます。
インスタンス変数とは、
```
menu_item1 = MenuItem()
menu_item1.name = 'サンドイッチ'
print(menu_item1.name)
```
のような時のnameのことです。
print(menu_item1.name)のように、インスタンス変数の値を用いることもできます。

##ちなみに…メニューの左側に番号をつける方法
番号を保存するには、for文の外で番号を保存するための変数を用意する必要があります。

```
lessons = ['Ruby', 'Python', 'Java']
index = 0
for lesson in lessons:
(インデント)print(str(index)+'.'+lesson)
(インデント)index +=1
```

##プラスワン知識
get_total_price()で合計金額を取得することができます。
```
class MenuItem:
(インデント）get_total_price(self,count):
(インデント×２)total_price = self.price*count
```

###参照
・progate　python　ⅳ
systemd/timerを使ってサーバを毎晩リブートさせる

サーバを定期的に再起動したいという需要は常に存在します。

完璧に書かれたシステムにおいてメモリが一方的に減っていくなんてことはおこらないはずですが、どっかの誰かが開放し忘れたコードにより徐々に減っていく空きメモリ。原因を追求するより、定期的に再起動しちゃえば一発解決だよね🧙

なんか時々落ちるこのサービス、いっそ定期的にサーバを再起動しておけば、たとえ落ちたとしても復活するから、大体の時間は動いてるサービスにできるんじゃないの？😈

いいことか悪いことか、かっこいいかどうかはともかくとして、定期的にサーバを再起動しておけば解決できるある種の問題が存在することは事実です。問題の先送りだって一つの技術力ですし(後ろめたいときって前置きが長くなるよね)

ともかくそういうわけで何らかの理由でサーバを定期的に再起動させたいときの設定です。

CentOS7から標準になったSystemdのTimer機能を使います

# serviceの作成と登録

```shell-session
$ sudo nano /etc/systemd/system/reboot.service
```

```config:reboot.service
[Unit]
Description=Scheduled Reboot

[Service]
Type=simple
ExecStart=/usr/bin/systemctl --force reboot
```

こうやって出来たserviceファイルを

```console
sudo systemctl enable reboot
```

で登録します。

この段階で、

```console
sudo systemctl start reboot
```
ってたたいてあげると、サーバが予告なく再起動するかと思います。

Q: rebootコマンドじゃないの？
A: rebootとかhaltはCentOS7から非推奨になりました
[10.4. システムのシャットダウン、サスペンド、休止状態 Red Hat Enterprise Linux 7 | Red Hat Customer Portal](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-power)

# Timerの作成と登録

# serviceの作成と登録

```shell-session
$ sudo nano /etc/systemd/system/reboot.timer
```

```config:reboot.timer
[Unit]
Description=schedule reboot

[Timer]
Unit=reboot.service
OnCalendar=*-*-* 5:30:00

[Install]
WantedBy=timers.target
```

この例では毎朝5:30に再起動する記述になっています

```console
sudo systemctl enable reboot.timer
sudo systemctl start reboot.timer
```

で登録します。

```console
$ sudo systemctl list-timers --all
NEXT                         LEFT          LAST                         PASSED   UNIT                         ACTIVATES
Tue 2019-10-29 17:04:33 JST  4min 59s left n/a                          n/a      systemd-tmpfiles-clean.timer systemd-t
Wed 2019-10-30 05:30:00 JST  12h left      n/a                          n/a      reboot.timer                 reboot.se
n/a                          n/a           n/a                          n/a      systemd-readahead-done.timer systemd-r
```

という具合に、次の5:30にrebootが予定されていれば出来上がりです。よい再起動ライフを！
iPadで縦画面固定する

自分メモ。環境はXcode 11.0、Swift 5.1。
XcodeのDevice Orientationで設定していた固定画面がiPhoneにしか適用されていなかったため、iPadにも適用されるよう設定を修正しました。

## iPadで縦画面固定する

1. Xcodeのナビゲーターでプロジェクト名をクリック
2. Generalタブ>Deployment InfoでiPadのみにチェックを入れる
3. Device OrientationのチェックをPortraitのみにする
4. Requires full screenにチェックを入れる

なお画面回転についてはinfo.plistで設定しているようです。


## 参考
[[Swift] iPad 縦画面固定が反映されず、横に回転する時](https://nobuhiroharada.com/2018/11/18/post-1143/)
laravel-adminその他管理画面ジェネレータを調査してまとめた

### こんな方向け

- 管理画面ジェネレータを探している
- laravel-adminを聞いたことがある
- laravel-adminを実際に使っている

### laravel-admin って何？
> laravel-admin is administrative interface builder for laravel which can help you build CRUD backends just with few lines of code.
>> laravel-adminは、わずか数行のコードでCRUD処理を実現できるLaravel用の管理画面インターフェースビルダです。

現在は、公式にはLaravel5.5までしかサポートしていないようです。(5.8でも動作しますが6.0以降は動作しない模様)

### 主な機能
一般的な一覧画面、個別画面、新規作成、編集画面をマイグレーション、モデルファイルを参照してコマンド一発で作ってくれます。

また、操作ログをDBに保存する機能もデフォルトでついています。

生成される画面のテーマは[こちら(adminLTE)](https://adminlte.io/themes/AdminLTE/index2.html)

### リポジトリ URL
https://github.com/z-song/laravel-admin

### 作者Github URL
https://github.com/z-song

今も活発にlaravel-adminにcommitされているようです。

### 公式ドキュメント(英語版)
https://laravel-admin.org/docs/#/

### 記事執筆時データ

**スター数**: 7.4k

**イシュー** open: 約120, closed: 約3000
**プルリクエスト** open: 約20, closed: 約1000 

自分がプルリクエストを出した時は、2~3日でマージしてくれました。早い。

### その他管理画面ジェネレータとの比較(スター数のみ)
Voyager(スター数: 約8.8k)
https://github.com/the-control-group/voyager

LaraAdmin(スター数: 約1.3k)
https://github.com/dwijitsolutions/laraadmin

QuickAdmin(スター数: 約500)
https://github.com/LaravelDaily/quickadmin

InfyOm(Backend、画面別々)
https://github.com/InfyOmLabs/laravel-generator (スター数: 約2.6k)
https://github.com/InfyOmLabs/adminlte-generator (スター数: 約230)

AppzCoder(スター数: 約1.1k)
https://github.com/appzcoder/crud-generator

Laravel-Backpack
https://github.com/Laravel-Backpack/Base (スター数: 約800)
https://github.com/Laravel-Backpack/CRUD (スター数: 約1.4k)

Sleeping-Owl(スター数: 約500) 
https://github.com/sleeping-owl/admin

Rapyd-Laravel(スター数: 約800)

参考: https://laravel-news.com/13-laravel-admin-panel-generators

### デモサイト URL
https://demo.laravel-admin.org/auth/login
`username/password : admin/admin`
Python　標準ライブラリとimportの使い方

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

##標準ライブラリとは
pythonに初めから用意されているモジュールで、importを用いて読み込み使用できます！

#randomモジュール
```import random```
と書くことで読み込めます。(後述:importの利用法)

####random.randint(x, y)
xからyまでの英数をランダムに取得できます。
コンピューターとじゃんけんする際、手の出し方に用いられます。

#importの利用法
別ファイルのコードを、
```import モジュール名```
として読み込むことができます。

例）
import menu_item
menu_item1 = menu_item.MenuItem(...)

また、クラスを直接読み込むこともできます！

例）
from menu_item import MenuItem
menu_item1 = MenuItem(...)

##さいごに
これからどんどん追記していこうと思います！
Pyenv と Pipenv で Python 環境を構築する

いままでなにも考えずanacondaを使っていたのですが、なんとなくanacondaをやめたくなったので、いろいろ調べました。
いろいろ調べた結果、pyenvとpipenvの組み合わせが最強な気がしたので、これらをインストールします。

この記事ではpyenvとpipenvのインストールの仕方と、それぞれの基本的な使い方をまとめてみようと思います。

# pyenvのインストール

pyenvはpythonのバージョンを管理するツールです。

**「この参考書ではpython 3.7.1を使ってるけど、こっちのちょっと古い参考書ではpython 3.3.7を使ってる。。。
どっちのpythonも残しておくにはどうしたらいいんだろう？？」**

を解決するツールです。

githubを読んでインストールします。macならhomebrewがラクです。
https://github.com/pyenv/pyenv

# pyenvの使い方

`pyenv -h`
でコマンド一覧が見られます。

よく使いそうなのは、
`pyenv install --list`
`pyenv install x.x.x`
`pyenv versions`
あたりでしょうか。使いやすそうですね。いいですね。

# pipenvのインストール

pipenvはパッケージマネージャです。pythonのパッケージ依存関係を管理します。rubyでいうbundler、nodeでいうnpmですね。
パッケージマネージャはpipenv以外にもvenvやvirtualenvがありますが、pipenvは[python公式でも紹介されています](https://packaging.python.org/tutorials/managing-dependencies/)し、他のものより高性能かつ使いやすいので、特にこだわりがないのであればpipenvでいいと思います。

githubを読んでインストールします。これもmacならbrewでいけますね。素晴らしい。
https://github.com/pypa/pipenv

# pipenvの使い方

`pipenv -h`をして確認します。

# そもそもなぜpython環境構築は渾然としているのか？

pythonの開発環境はこの記事で紹介したanacondaやpyenv, pipenv以外にもあります。
そこで、なんでそんなにあるの？ なんでいくつもインストールしなきゃいけないの？ てかひとつでよくね？ と思うわけですが、それは、管理する対象が3つあるからです。

- python自体のバージョン管理
- pythonパッケージの管理（各パッケージ間の依存関係の管理）
- pythonパッケージインストールツール

上記3つをそれぞれ管理しなきゃいけないので（絶対にしなきゃいけないわけではないけど）、組合せ爆発的に開発環境手法が増えてしまうわけですね。大変ですね。

参考記事
[pyenv、pyenv-virtualenv、venv、Anaconda、Pipenv。私はPipenvを使う。](https://qiita.com/KRiver1/items/c1788e616b77a9bad4dd)

# おわりに

この記事を書きながらインストール作業をしていたのですが、pipenv、すごく強いですね。
特に`pipenv --python x.x.x`ってやるだけでpyenvをキックしてくれるの最高すぎます。

**pyenv**と**pipenv**、おすすめです！！！

# 参考にさせていただいた記事

[pyenv、pyenv-virtualenv、venv、Anaconda、Pipenv。私はPipenvを使う。](https://qiita.com/KRiver1/items/c1788e616b77a9bad4dd)
[pythonの環境構築戦争にイラストで終止符を打つ](https://qiita.com/ganariya/items/1bf870275bad7b5ab506?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items)
[pyenvが必要かどうかフローチャート](https://qiita.com/shibukawa/items/0daab479a2fd2cb8a0e7)
[venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)
Oracleデータベースの接続でハマった話@Oracle 18c

###問題
DBを操作する外部のアプリケーションでローカルマシンのDBに接続しようとするも、一向に繋がらず。
結果的にはめっちゃ初歩的なミスだったのだけれど、めちゃくちゃ時間食ってしまった。

###リスナー設定
「ORA-12541：リスナーがありません」や「ORA-12514：指定された接続識別子を解決できませんでした」など、リスナー関係のエラーメッセージが出てくるので、そこらへんだろうと思って色々やった。
なぜか初期設定ではこれとは異なる形（SERVICE_NAMESが存在せず、SIDに何か知らない値が入ってたり）となっていたが、結局公式ドキュメントにある形式で書いたら解決した。
[6 tnsnames.oraファイル内のローカル・ネーミング・パラメータ] (https://docs.oracle.com/cd/E96517_01/netrf/local-naming-parameters-in-tnsnames-ora-file.html#GUID-A3F9D023-9CC4-445D-8921-6E40BD900EAD)
[7 listener.oraファイル内のOracle Net Listenerパラメータ] (https://docs.oracle.com/cd/E96517_01/netrf/Oracle-Net-Listener-parameters-in-listener-ora-file.html#GUID-F9FA0DF5-2FAF-45CA-B6A1-F0166C7BFE54)

###解決
結果としては、tnsnames.oraのSERVICE_NAMESが初期化パラメータのSERVICE_NAMESと食い違っていた。
Bronzeのテキストにも書いてある初歩的なことだったのだが、設定方法を把握していなかった。
資格を取得した意味とは一体

###感想
なんで初期値でちゃんと設定してくれないの？
VagrantのHomestead + MacOSで、mDNS を使って名前解決をする

Homesteadを使ってLaravelプロジェクトを開発するべく、[Laravel Homestead 6.0 Laravel](https://readouble.com/laravel/6.0/ja/homestead.html) に従って手順を進めていくと

>Homesteadでは自動的にホストを解決できるように、mDNSによりホスト名を公開しています。Homestead.yamlファイルで、hostname: homesteadとセットすれば、このホストはhomestead.localで使用できます。MacOS、iOS、LinuxディストリビューションではmDNSがデフォルトでサポートされています。Windowsでは、Bonjour Print Services for Windowsをインストールする必要があります。

とあるが、providerにVagrantを使っていると、`homestead.local` の名前解決ができない場合がある。


```terminal:macos側
$ ping homestead.local
ping: cannot resolve homestead.local: Unknown host
```

```terminal:Homestead側
$ sudo apt install avahi-utils
(略)
$ avahi-browse -a -t
+   eth2 IPv6  (Macのhost名)                                        _companion-link._tcp local
```

Vagrantのネットワークアダプターをbridgeに変更することで、名前解決ができるようになる。

```ruby:Vagrantfile

(略)
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
(略)
    config.vm.network "public_network", bridge: 'en0: Wi-Fi (AirPort)'
(略)
end
(略)
```

Vagrantfileを修正後、仮想マシンを再起動する。

```terminal:macos側
$ ping homestead.local
PING homestead.local (192.168.11.66): 56 data bytes
64 bytes from 192.168.11.66: icmp_seq=0 ttl=64 time=0.448 ms
64 bytes from 192.168.11.66: icmp_seq=1 ttl=64 time=
```

```terminal:Homestead側
$ avahi-browse -a -t
(略)
+   eth2 IPv4 (Macのhost名)                                       _companion-link._tcp local
(その他、ローカルネットワーク内の機器)
(略)
```



(参考)

https://ideal-reality.com/computer/server/vagrant-mdns/
gradle-ssh-pluginでSSH


gradleに仕事をさせすぎてbuild.gradleが魔境化している昨今、デプロイとかそういうのもお前やっとけよとgradleに押し付けてみましょ。

ということで差し当たり今回はjacocoのカバレッジレポートをサーバーに放り込んででgradleくん。おら、さっさと働くんだよ。

```groovy:build.gralde
buildscript {
	repositories {
	  jcenter()
	}
	dependencies {
	  classpath 'org.hidetake:gradle-ssh-plugin:2.10.1'
	}
}

apply plugin: 'org.hidetake.ssh'

remotes {
	coverageCenter {
		host = coverageCenterHost
		user = coverageCenterUser
		// この辺のパスなんかいい取り方がありそうなんだが
		identity = file(System.getProperty("user.home") + '/.ssh/id_rsa')
		// パスワード認証の場合はidentityと代えてこっちを
		// password = 'hogehoge'
	}
}

task publish(dependsOn: 'jacoco') {
	// リモートのパス
	def uploadDir = "/usr/share/nginx/html/$project.name"
	def localDir = "$buildDir/reports/jacoco/jacoco"
	ssh.run {
		session(remotes.coverageCenter) {
			// コマンドの実行
			execute "mkdir -p $uploadDir" 
			// フォルダコピー
			put from:localDir, into:uploadDir
		}
	}
}
```
一応ホスト名なんかはgradle.propertyから取るようにしたが、build.gradleに直書きしてもよろしいざんす。

```gradle.properties
coverageCenterHost = 192.168.99.100
coverageCenterUser = user
```


**ビルドする前にバージョン差し込んでビルドして単体通してカバレッジレポート作ってリリースノート作って配布物作って部品系はNexusにアップロードしてリリース案内をslackに投稿して評価環境にモジュールをデプロイしてservice restartもちゃんとやれよ。前までのログはzipにしてNASに置いとくんだ。あーそれともう一つ、カバレッジレポートをWEBで公開しとけよ。**

さて、他にgradleちゃんにやってもらうお仕事なかったかしら・・・。

あ、Dockerイメージ作らせるべ。
module 'keras.backend' has no attribute 'control_flow_ops'というエラーに対処するために

# はじめに
kerasのバージョンアップに伴い、以上のエラーが出てしまいました。これの解決方法を備忘録として残しておきます。

#環境
MacOS Mojave
Python 3.7.2
Keras 2.3.1
tensorflow 1.13.1

#手順

##kerasの場所を調べる

terminalでpythonの対話シェルを開き、以下のコマンドでkerasのパスを特定します。
(***には自分の環境のパスを入れます。)

```
>>>import keras
>>>keras.__file__
/***/python3.7/site-packages/keras/__init__.py
```

##/***/python3.7/site-packages/keras/backend/\_\_init\_\_.pyを開く

場所が特定できたら、/***/python3.7/site-packages/keras/backendに入っている\_\_init\_\_.pyを開きます。

##from tensorflow.python.ops import control_flow_opsを追加する

from .load_backend importの並びの中に
from tensorflow.python.ops import control_flow_ops
を追加します。

```__init__.py
                  .
                  .
                  .
from .load_backend import eager
from .load_backend import size
from .load_backend import control_dependencies

from tensorflow.python.ops import control_flow_ops
```

#終わり
私はこの方法で動かすことができました。もしかしたら、物によっては動かないかもしれないので悪しからず、、、
独自ドメイン＝Netlify、サブドメイン＝レンタルサーバー

お名前.comで取得したドメインをNetlifyに設定してたけど
サブドメインは別のレンタルサーバーに設定したい場合。

### 状況と問題
最初はNetlifyへネームサーバーを変更して運用してましたが
サブドメインだけをレンタルサーバーに設定したくなりAレコードで設定したりしてましたが
その構成だとSSL化が出来ない。。（ロリポップ、ConoHaなど）

### 正しかった対応
結局ネームサーバーをレンタルサーバーにして、そっちからNetlifyに設定するのが正解でした。

@とwwwのみNetlifyのIPアドレスを設定してます（青枠部分）
![キャプチャ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155724/4cddafbb-5d30-02c6-515d-25723c9c0428.jpeg)
コンテナに入る時にDockerfileに書いたbashの設定が反映された状態にする方法

# コンテナ内でbashに書いたコマンドが使えない
環境変数をDockerfileで.bash_profileに書き込むように設定したコンテナにdocker runで入ってみたら、環境変数として書いたはずのコマンドが使えない。command not foundになってしまう。.bash_profileを見てみると、ちゃんと書かれている。なので、入ったコンテナ内でsourceコマンドを使うと、登録したコマンドは使えるようになる。が、しかし、入った時点で使えるようになっていてほしい・・・

## 解決策
loginオプションなるものがあるらしいです。

```
$ docker run -it IMAGE_ID /bin/bash --login
```

これを使えば、コンテナに入った時に既に環境変数が読み込まれた状態になっています。
Ansibleのextra varsを指定しYAML形式の値を変更してみる

## 準備
### 各種バージョン
```
$  python --version
Python 2.7.5
$ ansible --version
ansible 2.5.0
```

### group_varsはこんな感じを準備
```
server:
  git:
    url: git@hoge.com
    version: master
  nginx:
    home: /home/nginx
    config: nginx.conf
timezone: jp
```
## やってみよう！！
### timezoneを変更を上書きしてみる NGパターン
```
--extra-vars "timezone: us"
```
じつはYAML形式では指定できない。

### timezoneを変更を上書きしてみる OKパターン
```
--extra-vars "timezone=us"
```
上記が正解

### versionを上書きしてみる 安定のNGパターン
```
--extra-vars "server.git.version: develop"
```

何度も書くけど、YAMLでは指定できない。
ここで地味にハマったけど、JSON形式で指定が可能らしい。
参考：[playbooks_variables](https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#passing-variables-on-the-command-line)

### versionを上書きしてみる OKっぽいパターン
```
--extra-vars "{'server': {'git': {'version': 'develop'}}}"
```

こう書くことで、エラー出ず指定が可能です。
ただし、JSON形式だと指定したもので全体が上書きされます。
上書きされてどうなるかというと以下な感じになります。

```
server:
  git:
    version: develop
timezone: jp
```

**他の情報が消えちゃった。。困った。。。**

結局どうしたかというと、以下のようにYAMLを変更しました

```
server:
  git:
    url: git@hoge.com
  nginx:
    home: /home/nginx
    config: nginx.conf
timezone: jp
git_version: master
```

で

```
--extra-vars "git_version=develop"
```

そう。書き換える可能性があるものは第一階層で単項目で書いておく。
今の所、この解決策しか見つかってません。

もし、いいやり方あれば教えて下さい。。
「Auth0でこんなことが出来るのか？」という質問を４つ

1.メールアドレス以外の会員IDを使用することは可能でしょうか？
--------
ユーザーガイドを見ると会員登録はユニークなメールアドレスとポリシーに適合するPWの登録が必須となっています。これを個々のユーザーの識別コードをアプリケーション側がユニーク発番してメールアドレスは会員プロファイルの属性の一つとして持たせることは可能でしょうか？それとも全ての会員に対してユニークなメールアドレスによるAuth0の会員情報登録が必須なのでしょうか？

2.ログイン画面をAuth0の外部に出して任意のデザインにすることは可能でしょうか？
--------
※）恐らくAuth0のログインAPIを外部ログイン画面アプリケーションから使用することで可能になるのではないかと予想しますがいかがでしょうか？

3.複数アプリ間におけるログイン時の会員情報共有で次のようなことは可能でしょうか？
--------
それぞれのアプリケーション固有の会員マスターにデータが登録されていないと正しく動作しないアプリ[A]とアプリ[B]があります。
ここでアプリ[A]の会員マスターにしか登録されていない会員がアプリ[B]にSSOするための次のような仕組みを考えます。

・アプリ[A]の会員①が自身のDataBase内にある会員情報を参照してログインします。

・Auth0はCustom Database Connectionで認証させてその会員情報を裏でMongoDBに登録します。

・続いてその会員は同じブラウザセッションでアプリ[B]への遷移を試みます。

・アプリ[B]はAuth0の認証情報を引っ張ってきて自身の会員マスターにその情報が登録されているかチェックします。

・未登録であれば必要な情報をMongoDBに登録された会員①の情報を引っ張ってきてその場で会員マスターに登録します。これで会員①はアプリ[B]内で専用の会員IDを発行され、アプリ[B]の中ではこのIDで動作させます。

･･･とこのような事は可能でしょうか？（会員①はアプリ[A]とアプリ[B]とAuth0の会員マスターにはそれぞれ異なるIDを持ちますがアプリ[A][B]の会員マスターにはAuth0の会員IDを属性として持たせるようにすれば可能になると思います。。。がそもそもこんなことが出来るのか？が知りたいです。)

4.SNSまたは企業従業員向けの認証サービスのIDと、Auth0に予め登録されている会員を紐付けることは可能でしょうか？
--------
企業向けの認証サービスやSNSのアカウントと予めAuth0に登録している会員のアカウントを後付で何らかの操作により紐付けることは可能でしょうか？例えば上の例でいったんアプリ[A]の会員としてログインしている会員①がアプリ[A]内のメニューより「FaceBook認証を可能にする」を選ぶとFBアカウントで会員[A]としてアプリ[A]に入れるようになる。。。というような。

========
qiitaでは最初の投稿になります。色々気をつけて書いたのですが、至らない点多々あると思いますので予めお詫び申し上げます。
少々雲をつかむような質問でありますが、Auth0のサイトや@furuthさんの素晴らしい記事を色々読んでみても上のような要件に関する情報は見つかりませんでした。情報のある方、何かヒントをお持ちの方、何卒ご提供くださいますよう宜しくお願いいたします。
ディレクトリの合計容量を確認するには(local, Gogle Cloud Storage, S3)


特定のディレクトリ配下にあるファイルの総容量を見る方法です。

# ローカルのファイルシステム

`du`コマンドで調べられます。以下の例では`path`ディレクトリの総容量を確認できます。

```
$ du -sh ./path/
```

オプション

- `-s`
    - 合計の容量のみを表示するオプション。
    - これを付けないとサブディレクトリも再帰的に容量を表示される。
- `-c`
    - 合計の容量を表示するオプション。
    - これを付けなくてもディレクトリ単位での合計は表示してくれるので、これが生きるのは複数のディレクトリまたはファイルをパラメータで指定した場合。
- `-h`
    - 容量表示に G, M, K などの人間にとってわかりやすい単位を付与するオプション。
    - これを付けないと数字のみのバイト単位での表示になり、桁数が多いと見づらい。
- `--help`
    - ヘルプ表示

## `-s`と`-c`の違い

`-s`と`-c`の違いが分かりづらいのですが、以下の2ファイルがあったとすると、

```
./path/a.txt
./path/b/b.txt
```

`-s`では合計のみの表示。

```
$ du -s ./path/
16   ./path/
```

`-s`なしではサブディレクトリも表示。

```
$ du ./path/
8    ./path/b
16   ./path/
```

`-c`はtotal表示が追加されますが、役立たずです。

```
$ du -cs ./path/
16   ./path/
16   total
```
```
$ du -c ./path/
8    ./path/b
16   ./path/
16   total
```

`-c`は複数のディレクトリを指定した場合に役に立ちます。

```
$ du -cs ./path1/ ./path2/
16   ./path1/
16   ./path2/
32   total
```

# Google Cloud Storage

GCPのストレージであるGoogle Cloud Storageでは、`gsutil du`コマンドで確認できます。

```
$ gsutil du -sh gs://xxxx/path/
```

オプションはローカルの`du`コマンドと同じです。オプションを覚えやすくて`gsutil`はいいですね。

# AWS S3

AWSのストレージであるS3では、`aws s3 ls`コマンドで確認できます。

```
$ aws s3 ls --human --recursive --sum s3://yyyy/path/
```

`aws`コマンドはコマンドの使い方もオプションも`gsutil`と違ってオリジナルです。`gsutil`のほうがいいですね。

そして、なんとGoogleの`gsutil du`コマンドでもS3の容量を確認できます。

```
$ gsutil du -sh s3://yyyy/path/
```

やっぱり`gsutil`のほうがいいですね。

# 参考

[AWS CLIを使用してS3のサイズとオブジェクト数を取得してみた - カピバラ好きなエンジニアブログ](https://capybara-engineer.hatenablog.com/entry/2019/10/29/154229)

`du`だけでなく`cp`や`ls`も`gsutil`はS3に対応している！
[Google Cloud StorageとAWS S3との間でファイルをコピーするには - Qiita](https://qiita.com/suzuki-navi/items/cf92371e71cb4d106300)
[gsutil、aws s3での基本的なファイル操作（Google Cloud Storage、S3） - Qiita](https://qiita.com/suzuki-navi/items/775b9f9029af19780be3)
JMPで描く「ランチャート(折れ線グラフ)」

統計解析ソフト「JMP（ジャンプ）」は、簡単な操作で、分かりやすいグラフを素早く作成することができます。その結果、多くの時間をデータのより深い考察に充てることができます。

前回は「散布図」の作り方を確認しましたが、今回はJMPで「ランチャート(折れ線グラフ)」を作ってみましょう。

[※ランチャートとは、時系列に沿って、データの変化を分析する折れ線グラフです。]

今回も数ステップで簡単にグラフが作れます。さっそく試してみましょう！

■セットアップ
JMPを起動します（まだインストールしていない方は[**こちら[トライアル版]**](https://www.jmp.com/ja_jp/download-jmp-free-trial.html?utm_campaign=td7013Z000002sEGsQAM&utm_source=JMPblog&utm_medium=)からダウンロードしてください）。

■ランチャート 
1.対象データを開きます（今回はサンプルデータを使用します）
「ヘルプ」>「サンプルデータライブラリ」と進み、「Time Series」>「GNP.jmp」を選択します。
<img width="800" alt="asset1.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/6aa0d127-df9b-e871-acee-1ef851ee2b87.jpeg">
<img width="800" alt="asset7_1.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/fb783355-925c-be0e-2005-0f2c0f3c98f9.jpeg">
<img width="800" alt="asset7_2.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/ecbde7c1-ad04-d3de-e345-bb3c574f78dd.jpeg">
2.メニューから「グラフ」>「グラフビルダー」を選択します。
<img width="800" alt="asset7_3.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/a176649e-057b-5b62-b7ec-69f06cd0e3ba.jpeg">
3.列の選択ボックスから、1つの変数(または一度に複数の変数)をドラッグしてYゾーンにドロップします（この例では「国内民間粗投資」と「商品およびサービスの純輸出」を選択）。
4.列の選択ボックスから、時間の順序を表す列をXゾーンにドラッグ&ドロップします（この例では「日付」を選択）。 
<img width="800" alt="asset7_4.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/13a32001-6653-48c6-4e21-9098530e1228.jpeg">
5.グラフパレット(ウィンドウ上部)にある折れ線のアイコンをクリックします。 
<img width="800" alt="asset7_5.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/282886fc-340c-8b47-e484-0de826c21d7d.jpeg">
6.これでランチャートが表示されました。あとは「終了」をクリックし、必要に応じて微調整します(以下のヒントを参照してください)。

ヒント: 
1.凡例上でマウスを右クリックすると、線の太さや他の線のプロパティを変更できます。
<img width="800" alt="asset7_6.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/9722eaf6-52ae-2ce9-45df-aa764ebdff33.jpeg">
2.グラフのタイトルや軸ラベルをクリックすると、その内容を編集できます。軸のスケールを変更するには、軸をダブルクリックします。
<img width="800" alt="asset7_7_2.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/3ea853c9-3dd1-a467-6e66-6150cb411869.jpeg">
3.グラフビルダーのタイトル横の赤い三角ボタンをクリックすると、設定パネルの再表示、また凡例やタイトルなどの表示／非表示を設定できます。
<img width="800" alt="asset7_8.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/6831c3de-ae22-4ed3-881c-f59b7ed920d4.jpeg">


注意: ランチャートは管理図のプラットフォーム(「分析」>「品質と工程」>「管理図」>「ランチャート」)でも作成できます。 

■	動画（英語版）
実際の操作を見て、復習してみましょう。
※ビデオの前半で紹介している「重ね合わせプロット」は、JMP 14からはグラフビルダーに統合されていますので、JMP 14以上をお持ちの方は、ビデオの後半をご覧ください。

[**Run Charts (Line Graphs)**](http://players.brightcove.net/1872491364001/default_default/index.html?videoId=5541681480001)

■	さあ始めよう！
JMPの全機能を30日間試せるトライアル版で、データからさらなる情報を導き出せることを実感してください。
さあ始めましょう。ダウンロードは[**コチラ！**](https://www.jmp.com/ja_jp/download-jmp-free-trial.html?utm_campaign=td7013Z000002sEGsQAM&utm_source=JMPblog&utm_medium=)）

■	JMPについて
JMP（ジャンプ）は世界中のエンジニア、データアナリストに選ばれているインタラクティブで可視的なデータ分析ツールです。

＜ SNSで様々な情報をお届けしています ＞
[**Facebook**](https://www.facebook.com/JMPjpn)
[**Twitter**](https://twitter.com/JMP_Japan)
STM32のTIMの位相をずらす

TIMでPWMを出している途中で、TIMの位相を正確に動かしたい、というニッチ(たぶん)な使い方。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264452/9d077c41-8914-3002-ccd9-96b1b5a2e283.png)

1段目がPWMの波形。
2段目がデバッグ用のピン出力。

デバッグ出力がバタバタしたあたりでPWMの位相が50%ほど変化しているのがわかる。

1つ目のエッジで「次の周期で位相を変えなさい」という指示を出す(ループ)。
指示の直後の割り込み(2つ目のエッジ)で周期を調整している(ISR)。
そのままだと以降も周期が短いままなので、その次の割り込み(3つ目のエッジ)で周期を戻している(ISR)。

## テストコード

```c++:初期化
htim3.Instance->PSC = 0;
htim3.Instance->ARR = tim3_ARR;
htim3.Instance->CCR1 = 500;

HAL_TIM_GenerateEvent(&htim3, TIM_EVENTSOURCE_UPDATE);

HAL_TIM_RegisterCallback(&htim3, HAL_TIM_PERIOD_ELAPSED_CB_ID, TIM3_period);

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

osDelay(5);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
__HAL_TIM_CLEAR_IT(&htim3, TIM_IT_UPDATE);
__HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);

osDelay(5);

HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
```

```c++:ISR
void TIM3_period(TIM_HandleTypeDef *htim)
{
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_7);

    if (htim3.Instance->ARR == tim3_ARR)
    {
        htim3.Instance->ARR = tim3_ARR / 2;
    }
    else
    {
        htim3.Instance->ARR = tim3_ARR;
        __HAL_TIM_DISABLE_IT(&htim3, TIM_IT_UPDATE);
    }
}
```

今回は周期・移相量を定数で固定としたが、適当な変数で持たせれば自由に動かせるはず。

また、コールバックを使うので、どこかで`#define USE_HAL_TIM_REGISTER_CALLBACKS 1`を定義しておく必要がある。

## その他

タイミングクリティカルな処理をゴリゴリやるので、実際に使う際は十分注意すること。今回のテストコードは実環境ではたぶんうまく動かない(低確率でバグる)。
[ Android ] 画面遷移後の画面でサーバから乱数を取得 （未完）

今回は画面遷移後の画面でHTTP通信を行うプログラムの実装を試みた。

##java.net.SocketException: Socket failed: EPERM(Operation not permitted)
現在、画面遷移は以下のような流れになっている。
![スクリーンショット (38).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/23a85f44-30f1-58b3-9c6a-f698b6429a56.png)


ボタン2を押下により画面3が呼び出し、onCreateで非同期処理を実行。
非同期処理クラスのonPostExcecuteでサーバから取得した乱数をTextViewに表示。
しかし、通信する際、
java.net.SocketException: Socket failed: EPERM(Operation not permitted)
というエラーが表示される。

##調査結果
未だ解決方法はわかっていない。

調査では以下のような解決方法が示されていたが、
試してみたが、うまくいかなかった。
本実装の問題とは関係ないようである。
他の方はこれで解決できるかもしれないので、
参考にしていただきたい。

［解決方法］
・AndroidManifest.xmlに以下のコードを追加する。

~~~
<manifest>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
~~~

・参考URL
https://stackoverflow.com/questions/56266801/java-net-socketexception-socket-failed-eperm-operation-not-permitted

##まとめ
私の記事「サーバクライアント通信」に記載したコードでは
HTTP通信とサーバからの値取得はうまくいっていた。
今回と過去の記事での違いは
MainActivityから非同期処理を呼び出しているか、
画面遷移後の画面から呼び出しているかである。
ここに何かヒントがあるのか…
次回はこの問題を解決できるよう頑張りたい。
以上。
PyTorchのGPU使用時のメモリ関連エラー

PyTorchでGPUを使っていてメモリについてのRuntime Errorが出たときの対処についてメモしておきます。
同じエラーに出くわし、このページが参考になる人がいれば幸いです。

# Forループの中でPyTorchで定義されている変数を+=などすると、変数のメモリが解放されない
下のコード例はミニバッチ内でだしたlossを全体のloss_avgに加えて、後で平均を取ろうとしている。
コメントアウトした方のloss_avg += lossを使うと、これ以上メモリ割り当てができないというRuntime Errorがでるため、下のfloat(loss)のようにfloat変数に変換する。

```
loss_avg = 0.0
for batch_idx, (data, target) in enumerate(test_loader):
        data, target = torch.autograd.Variable(data.cuda()), torch.autograd.Variable(target.cuda())

        # forward
        output = net(data)
        loss = F.cross_entropy(output, target)

        # accuracy
        pred = output.data.max(1)[1]
        correct += pred.eq(target.data).sum()

        # test loss average
        #loss_avg += loss
        loss_avg += float(loss)
```
参考ページ
https://pytorch.org/docs/stable/notes/faq.html

# Docker container起動時
PyTorchのGPUを使うDocker containerを起動するときには、 --ipc=host か --shm-size=16G のオプションをつけてメモリ割当をしておく必要がある。
AWS ECRにてコンテナイメージ脆弱性診断サポート

streampack の Tana です。

ついに AWS ECR にてコンテナの脆弱性診断の機能が追加されました。

https://aws.amazon.com/about-aws/whats-new/2019/10/announcing-image-scanning-for-amazon-ecr/

GCP(Google Cloud Platform)ではちょっと前に GA になりましたが、AWS でも正式に発表されました。今後のコンテナのセキュリティも常にイメージプッシュ後にチェックしていれば、よりセキュアな提供が可能になりそうです。

# ECR - AWS

早速、スキャンの方法です。

コンテナイメージがプッシュされていれば、事前に設定など不要です。

対象のイメージを選択します。
"Scan" をクリックされると実行されます。
<img width="1344" alt="scan-step.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232803/f5c38954-247c-7533-9fdc-9d96bc4c92fa.png">

その結果です。
<img width="1462" alt="Amazon_ECR.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232803/45c23fad-fba6-537d-2b42-799339804476.png">

とても簡単ですね。
診断結果のタイプから対応時期の検討もしやすそうです。

# GCR - GCPの結果

ちなみに最近 Beta から GA になった GCP のコンテナイメージの脆弱性診断結果です。

<img width="944" alt="GCP-Container-Registry.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232803/9c10dfd0-67f5-cb0a-6196-6add94e75409.png">

同じイメージ使いましたが、同じ結果でした。
引き続き本番運用にも適用して行きたいと思います。

では、より良いコンテナライフを。