OmniAICreator/Qiita-1.07M huggingface dataset:
プロキシのクライアント証明書の指定

# はじめに

[BurpSuite](https://portswigger.net/burp), [ZAP](https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project), [Fiddler](https://www.telerik.com/fiddler), [sWebTool{自作(C#/.NET4)}](http://rocketeer.dip.jp/sanaki/free/free140.htm) は、SSL の通信を解読しながら転送するプロキシツールで、デバグ/セキュリティ診断で使われている

診断対象にアクセスするのにクライアント署名書が必要な場合の指定方法

# クライアント証明書の指定

## BurpSuiteの場合

![burp.png](https://qiita-image-store.s3.amazonaws.com/0/182822/cdd96746-0dd6-8d0d-6e8c-2f23357de68a.png)

Options→SSL→Client SSL Certificates

転送先Webサイト(ホスト)ごとにクライアント証明書が指定できる。

## ZAPの場合

![zap.png](https://qiita-image-store.s3.amazonaws.com/0/182822/cd784628-ed8d-c418-5768-f534a730a930.png)

オプション→証明書
ファイルと、パスワードを指定する

![zap2.png](https://qiita-image-store.s3.amazonaws.com/0/182822/dbf3bf13-031e-9c2c-2c5e-f314ce643bd2.png)

こちらの一覧に表示されたら**「有効にする」**で有効になる。

ver2.7.0 には**「証明書を有効にするにはZAPを再起動」**と書いてあるけど、再起動しなくても有効だし、再起動すると設定が保存されないので、注意。

## Parosの場合

未稿

## Fiddlerの場合

未稿

## sWebTool の場合

![076.png](https://qiita-image-store.s3.amazonaws.com/0/182822/a1f073b5-9de2-098d-67cc-46e802c2a5f3.png)

「ClientCertificate」ボタンで設定する

# Index

[Indexへ戻る](https://qiita.com/tomoki0sanaki/items/258d6e77e4b16bc7d1c9)

# 以上
RecyclerViewでListAdapterを使う

Google I/O 2018  ``Android Jetpack: what’s new in Android Support Library ``のセッションであがってきたRecyclerViewの新しい機能、ListAdapterとRecyclerViewについて紹介します。

#ListAdapterとは
ListAdapterはSupport Library 27.1.0で提供されたAPIです。ListAdapterはGoogle I/O 2018の``Android Jetpack: what’s new in Android Support Library``のセッションと``Android Jetpack: manage infinite lists with RecyclerView and Paging``のセッションで次のような特徴が紹介されました。

・不変(Immutable)リストの動作
・Diffutilの利用によってコードが簡略される
・アニメーションを提供

ListApdaterは内部的にリストを読むだけの不変オブジェクトとして扱います。従って渡されたリストで直接的な要素の変更を許さず、もし変更するとしてもアップデートは反映されません。リストで要素が修正、追加、削除、移動が発生した場合、必ず変更が反映された新しいリストをListAdpaterへ渡します。バックグラウンドスレッドでリストが変更される場合、内部的にnotifyItem()関数が呼び出され、利用者はアップデートされたRecyclerViewを確認できます。これは既存のRecyclerViewアダプタとの違いであり、ListAdapterの特徴です。

こういう構造でLiveData<List>又はObservable<List>を利用し、リストの変更されたデータを読み、変更されたリストをListAdapterで実装することができます。

ListAdapterの状態を変更するためのAPIは新しいリストを設定する ``submitList(val lsit: List<T>) ``の関数しかありません。内部動作に比べて外部のインターフェースは極端に単純です。

# DiffUtil.ItemCallbackの実装
ListAdapterは２つのリストを比較するためのコンストラクタのパラメータで、 ``Diffuil.Itemcallback ``が必要です。
``Diffuil.Itemcallback ``の実装は以下のようになります。

```kotlin
private val diffCallback = object : DiffUtil.ItemCallback<Int>() {
  override fun areItemsTheSame(oldItem: Int, newItem: Int) =
          oldItem == newItem // check uniqueness

  override fun areContentsTheSame(oldItem: Int, newItem: Int) =
          oldItem == newItem // check contents
}
```

実装すべきメソッドは以下の２つになります。

**areItemsTheSame**
2つのアイテム自体が同じものであるかを判定します。

**areContentsTheSame**
2つのアイテムのデータ内容が同じであるかを判定します。

# ListAdapterの実装
ListAdapterの実装ですが、DiffUtil.ItemCallbackインスタンスを渡せばOKです。

```kotlin
private val adapter: ListAdapter<Int, MyViewHolder> = object : ListAdapter<Int, MyViewHolder>(diffCallback) {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
                MyViewHolder(parent)

        override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
            holder.bindTo(getItem(position))
        }
    }
```


```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
        recyclerView.adapter = adapter.apply {
            registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
                override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
                    recyclerView.scrollToPosition(0)
                }
            })
        }

        numbers.apply {
            value = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
            observe(this@MainActivity, Observer<List<Int>> {
                adapter.submitList(it)
            })
        }
    }
```

#まとめ
ListAdapterを使用すると、より簡単なコードでRecyclerViewを利用することができます。
AWS CloudFormationでのlambda functionのコード管理方法について


## 悩み
AWS CloudFormationで環境を構築できるようになったが、lambdaを利用する場合、現在のソースコード管理がイマイチだった

[AWS Lambda Function Code] (!https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html)

上記のDocをみると以下二つの方法があった


### CloudFormationの中身にコードを入れる

例）

```
ZipFile: |
  import json
  import cfnresponse
  def handler(event, context):
    responseValue = int(event['ResourceProperties']['Input']) * 5
    responseData = {}
    responseData['Data'] = responseValue
    cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")

```

一目でこの方法は論外と判断、
テストしたソースコードをCloudFormationファイルでコピペした後の整合性は誰が責任取るんだ〜
もし使うなら、ソースをzipにしてパスを入れるならありと思うが、多分できない？ようで

### S3で管理
こちはバージョン管理をどうするかが課題
既存んgitと別にS3のバージョン管理を利用することは嫌だったから、
もしこれを使うならシェルでS3にソースコードを登録したあとでにCloudFormationを起動する方法かな？
面倒だけどこちかな？


## 解決した方法
ソースコードを通常とおりに別途ファイルに管理し、CloudFormationのparametersで渡す方法を利用した

### 1. ソースはそのままテキストファイルで保存
 例のファイル名： `./labmdaFuntionTest.js`

 
### 2. CloudFormationのparameters定義

以下のParameters定義を追加 (yamlの場合)

```
Parameters: 
  LambdaFunctionContents: 
    Type: String
```

### 3. Codeをparametersで入力した値で設定

```
Resources:

  ConnectCognitoAuthHooks:
    Type: "AWS::Lambda::Function"
    Properties: 
      FunctionName: 'TestFunction'
      Handler: index.handler
      Runtime: nodejs8.10
      Code: 
        ZipFile: !Ref LambdaFunctionContents
```

### 4. 起動時シェルでソースコードファイルを渡す

```

aws cloudformation deploy --template-file ./LabmdaFuntionTest.yaml --stack-name LabmdaFuntionTest --parameter-overrides LambdaFunctionContents="$(<./labmdaFuntionTest.js)"
```
Microsoft Office 2013をwindows10に再インストールできない

Qiita童貞を卒業します。
（意訳：Qiitaに初投稿です。）
プログラミングというよりは環境を整備する上での問題とその解決策を備忘録として記述。

# 三行で要約
- Windows10でOffice2013をもう一度入れたい。  
- イベントビューアにはイベントID 1603としてエラーが出る
- WindowsUpdateをトラブルシューティングからUpdateデータベースを修復したら無事入った。

# 環境

- OS：Windows10  
みんなだいすきWindows10。
- RAM：16GB
- Office2013が入っていたので入れ直す


# 経緯
- いつもの通りインストーラを起動してインストールができ…ませんでした／(^o^)＼
- プログレスバーが一瞬だけ進んですぐに戻ったあとに「インストール作業中にエラーが発生しました」との文字が出る
- アンインストールは問題なく終了していた

# 解決まで
Program Filesの中に余計なものがないかを探るが、これといった手がかりは見られない。
そこでMSDNやMSのフォーラムに転がっているかもしれないという期待を込めて探ってみた。

…と思ったところまでは良いのだが、すぐに検索するよりも何か証拠がつかめないかと思いつつ捜索を再開。
おなじみイベントビューアで確認したところ、イベントID 1603でエラーが返ってきていた。
「Office2013 1603 Error」などで検索してみたが良い情報は得られず、
下記フォーラムのみ参考になりそうと思って確認してみたが全く解決ができない。
<a href="https://support.microsoft.com/ja-jp/help/834484/you-receive-an-error-1603-a-fatal-error-occurred-during-installation">Windows インストーラー パッケージをインストールしようとすると、「エラー 1603: インストール中に致命的なエラーが発生しました」というエラー メッセージが表示される|Microsoft</a>
権限の問題かと思ったのでCドライブの権限を変更とか色々いじくってみるが変化なし。
Fix itが出ていたが、すでに実行済み。

どこが間違っていたのかを翌日に再び検討。

# おのれWindwsUpdate
AnniversaryUpdateが邪魔しているのかと思ったが、もしそうであればもっと大きな問題になっているはず。

そしてUpdateという文字から思い出した。Windows Updateが原因じゃ？
トラブルシューティングからWindowsUpdateの項を探し出して実行。

データベースにエラーがあったので修復を実行。

修復後、PCを再起動してインストーラをもう一度実行した無事インストール完了まで到達。
何らかの原因でUpdateにはOfficeが入っていると誤解されたのか、原因は未だによく掴めていない。

とりあえず困ったらトラブルシューティングツールを実行しよう。
windows+pipenvでパスが通らない問題の解決まで

# 結論

pipenvとvirtualenvの衝突が問題らしい
一度pipenv,virtualenvをアンインストールしてから、pipenvを再インストールをすればいいらしい

英語読めるマンは[こちらへ](https://stackoverflow.com/questions/46041719/windows-reports-error-when-trying-to-install-package-using-pipenv)

# 症状

Pythonで仮想環境は正式にpipenvを使うことになったらしいので、インストールして使おうと思ったら、

```cmd
> pipenv

> 'pipenv'は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません。

```

# 解決方法

> First, remove your current version of virtualenv: pip uninstall virtualenv

まず今入っているvirtualenvを消します。

```cmd
 > pip uninstall virtualenv
```

>Then, remove your current version of pipenv: pip uninstall pipenv

次に、今入っているpipenvを消します。

```cmd
> pip uninstall pipenv
```

> When you are asked Proceed (y/n)? just enter y. This will give you a clean slate.

「続けますか？」と聞かれたら、yesを選択しましょう。これでクリーンな状態になります。

> Finally, you can once again install pipenv and its dependencies: pip install pipenv

最後にもう一度pipenvとその依存関係をインストールして終了です。

```cmd
> pip install pipenv
```

# あとがき

pipenv入れるだけで時間かかった…
`python -m pipenv`なら通るけどいちいち打つのは面倒だなぁと調べだしたら沼にはまった
良く日本語ページではsite-packagesをパスに入れましょうねーって書いてあるけど、不要だった？？↓

>I know this sounds the mundane, but it is actually the solution for Windows systems. You do not need to modify any of your system environment variables (please do not add site-packages to your environment variables).

なんでもないようなことを言っているように思えるかもしれないけど、これがwindowsでの解決方法なんだ。環境変数は一切触らなくていい。(**site-packagesを環境変数に入れることはしないでね**)

# 引用

https://stackoverflow.com/questions/46041719/windows-reports-error-when-trying-to-install-package-using-pipenv?r=SearchResults
Dart-basicプログラミング

# Dart basicプログラミング
この文章の内容は[dart公式tour](https://www.dartlang.org/guides/language/language-tour#a-basic-dart-program)の冒頭をまとめたものです。

## 最初の一歩

サンプルソース

```dart:basic.dart
// コンソール出力関数
printInteger(int aNumner) {
  print('The number is $aNumner');
}

// 実行メソッド
main() {
  var number = 42;
  printInteger(number);
}
```
・ // シングルコメント　- １行のコメントを表すのもの
・int 型のひとつ。 - 他にもStringやboolなどが存在する
・print - dartの標準関数(coreライブラリで明示てきにimportなどを必要としない）
・main - 実行時に最初に呼び出される特別な関数
・var - variable変数（型を明示的に指定しない変数）
Oracleでインデックスが断片化した時の対処

## はじめに
* 何かテーブルにSQL投げたのに返ってこないみたいな時は、テーブルのインデックスが断片化してるかも
* 大量件数の削除、投入を繰り返していると起きやすいかも
* インデックス断片化時の対処について備忘用に書く

## インデックスの断片化対処の手順
* 調査したいテーブルのインデックス一覧を取得
 
```sql
select index_name from user_ind_columns where table_name = '調査したいテーブル名' order by index_name;
```

* インデックスの統計情報を更新

```sql
analyze index 調査したいテーブル名 validate structure;
```

* インデックスの統計情報を更新

```sql
select name, height, lf_rows, del_lf_rows from index_stats WHERE name = '調査したいインデックス名';
```
```sql:実行結果例
NAME                         HEIGHT    LF_ROWS DEL_LF_ROWS
---------------------------- ---------- ---------- -----------
調査したいインデックス名        1         21           0
```

height・・・インデックスの深さ
lf_rows・・・リーフ行の数
del_lf_rows・・・削除されたリーフ行の数

* 断片率はdel_lf_rows / lf_rowsで計算できるよ

## インデックスの再構築
* 断片化がやばそうならインデックス再構築する

```sql
alter index 再構築したいインデックス名 rebuild;
```
Python SeleniumでAmazonをスクレイピングし商品名と価格データを収集するツール作成②

#目次
・**はじめに**
・**メイン画面作成**
・**メニュー作成**
・**テキストやボタンの配置**
・**動かしてみる**
・**おわりに**

#はじめに
Amazonでキーワード検索したデータをCSVに落とし込むツールを作成したいと思います。
その第２弾です。
<a href="https://qiita.com/yamauchi5748/items/4c287c520a297ad48c6b">前回</a>では環境構築までを簡単に行っております。

**環境**
**・マシン : Windows10**
**・Chrome version : 73.0.3683.75**
**・Chromedriver versin : 73.0.3683.68**
**・Python : python3.7**

#メイン画面作成
さっそくメイン画面部分を作っていきます。

```main.py
from tkinter import *

class Main():
    def __init__(self):
       ####メイン画面の生成####
       self.root = Tk()
       self.root.title("スクレイピングツール")
       self.root.geometry("400x250")
```
これで画面のフレームが作成されます。
タイトルや画面サイズを変更したい場合はtitle,geometryをそれぞれいじってもらえれば対応できるかと思います。

#メニュー作成
次はメニューの作成ですね。
main.pyに追記する感じで

```main.py
###メニュー作成###
self.menu_ROOT = Menu(self.root)
self.root.configure(menu = self.menu_ROOT)

self.menu_ROOT.add_command(label = "終了(X)", under = 3, command = None)
```

これでメイン画面の中に終了機能があるメニューが生成されます。
終了を押してもまだ反応しません、

#テキストやボタンの配置
次は入力テキストBOXやボタンの配置をしていきます
これもさっきと同様に追記して

```main.py
self.label_x = 20
self.label_y = 20
self.entry_width = 30
self.entry_x = 40
self.entry_y = 20

###キーワードを入力するbox###
self.keyword_text = Label(text=u'キーワードを入力してください：', foreground='#000000')
self.keyword_text.place(x = self.label_x, y = self.label_y)
self.keyword_box = Entry(width = self.entry_width)
self.keyword_box.pack(anchor = E, padx = self.entry_x, pady = self.entry_y)

###submitボタン###
self.btn = Button(self.root, text='データ取得')
self.btn.place(x=170, y=170)
```

これでキーワード検索とデータ取得のwidgetの配置ができました。
まだボタンに機能が備わっていないので次回以降で書いていきます。

#動かしてみる
では、今回作った画面を見てみましょう
main.pyの最下部で以下の追記をします

```main.py
if __name__ == "__main__":
    main = Main()
    main.root.mainloop()
```

これで画面が表示されれば成功です。


#おわりに
今回の記事は以上になります。
次回は本タイトルのメインであるスクレイピングを行っていきます

**さいごに参考にしたページです**
<a href="https://qiita.com/nnahito/items/ad1428a30738b3d93762">PythonのTkinterを使ってみる</a>
<a href="https://python.keicode.com/advanced/tkinter.php">Tkinter による GUI プログラミング</a>
ssh初回接続時にknown_hostsに登録される情報って何？

# はじめに
known_hostsに登録される情報がふと気になったので、備忘用にまとめました。

# known_hostsとは
* sshサーバ側の公開鍵の指紋（finger print）が登録されるファイル
* sshクライアント側の.sshディレクトリに格納されている
* 登録されるタイミングはsshサーバに初回接続するタイミング

```sh:接続時メッセージ例
The authenticity of host 'SSHサーバのホスト名' can't be established.
RSA key fingerprint is "実際のfinger print"
Are you sure you want to continue connecting (yes/no)? 
```

# sshサーバの公開鍵
* sshサーバ自身の公開鍵
* sshがインストールされる時に生成される（つまりOSインストール時と考えてよい）
* 公開鍵認証の接続時に、サーバ側に登録する必要のあるクライアント側の公開鍵のことではないので注意
* Linuxとかの場合、以下に格納されている

```sh:公開鍵の格納場所
/etc/ssh/ssh_host_rsa_key.pub
```
16日目：deviseだけで管理者を追加したい

授業で作っている、大学生情報をまとめたwebアプリの今の状態は、
サインアップさえすれば、誰でもデータ閲覧、編集、削除等が出来る状態。

それでは、非常にまずいので、管理者を追加した。
今回はシンプルな機能だけで良いので、devise以外にはgemを追加しなった。

#使用環境
- ホストOS: Windows10 Home
- 仮想環境: Ubuntu Bento/Bionic
- Ruby：2.51
- Rails: 5.2.2
    - gem ：'devise'（ログイン等の機能用）、'kaminari' （ページネーション）
- DB: PostgreSQL
- Heroku

#実作業
##テーブルにadminカラム追加
カラム追加方法は、前日のパスワードカラム追加と同じ。

```:terminal
# rails g migration Addカラム名Toテーブル名　カラム定義
rails g migration AddAdminToStudent admin:boolean
```

###boolean型
真理値の「真 = true」と「偽 = false」という2値をとるデータ型のこと。
Rubyでは偽はfalseとnilで、それ以外がtrueになる。
言語やDBによっては、1と0だったり、違うので注意。

##マイグレーションファイルを編集
boolean型と定義する際は、デフォルト値を設定しないといけない。
adminのデフォルト値に引数falseを渡し、デフォルトではadmin権限がない、と指定する。

```/db/migrate/20190328011407_add_admin_to_student.rb
class AddAdminToStudent < ActiveRecord::Migration[5.2]
  def change
    add_column :students, :admin, :boolean,default: false
  end
end
```

##マイグレーション実行
```
rails db:migrate
```

##admin権限を確認付与

```rb:
stu = Student.find(1)
stu.admin?
=>false
stu.admin = true
stu.save
stu.admin?
=>true
```
admin属性が追加され、またadmin?メソッドを使用できるようになっている。

#adminのみが全データを見れるようにする
admin以外は、自分のデータしか見れないようにしたい。

##controllerのindexアクション編集
adminかどうかで、アクション動作を変える

```rb:
 def index
    if current_student.admin?
      @students = Student.page params[:page]
    else
      @student = current_student
    end
  end
```

##viewを編集
adminかどうかで、viewを変える。

```rb:app/views/student
 <tbody>
    <% if current_student.admin? %>
      <% @students.each do |student| %>
        <tr>
          <td><%= student.name %></td>
          <td><%= student.email %></td>
          <td><%= display_name student.gender %></td>
          <td><%= display_age student.age %></td>
          <td><%= student.opinion %></td>
          <td><%= link_to 'Show', student %></td>
          <td><%= link_to 'Edit', edit_student_path(student) %></td>
          <td><%= link_to 'Destroy', student, method: :delete, data: { confirm: 'Are you sure?' } %></td>
          <td><%= link_to 'New Exam Result', new_exam_result_path(student_id: student.id) %></td>
          <td><%= link_to 'New Club Student', new_club_student_path(student_id: student.id) %></td>
        </tr>
      <% end %>
    <% else %>
      <tr>
        <td><%= @student.name %></td>
        <td><%= @student.email %></td>
        <td><%= display_name @student.gender %></td>
        <td><%= display_age @student.age %></td>
        <td><%= @student.opinion %></td>
        <td><%= link_to 'Show', @student %></td>
        <td><%= link_to 'Edit', edit_student_path(@student) %></td>
        <td><%= link_to 'Destroy', @student, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        <td><%= link_to 'New Exam Result', new_exam_result_path(student_id: @student.id) %></td>
        <td><%= link_to 'New Club student', new_club_student_path(student_id: @student.id) %></td>
      </tr>
    <% end %>
  </tbody>
</table>
<% if current_student.admin? %>
  <%= paginate @students %>
<% end %>
```
adminでなければ、ページネーションが必要でなくなるので、そこも編集。

まだ、一般ユーザでもその他のデータを触れる状態なので、編集しないと。
php-master-changes 2019-03-28

今日は abstract コンストラクタオーバーライド時のシグネチャ互換性チェック修正、FFI の C 言語宣言パーサの修正、phpdbg で readline サポートがデフォルト有効になっていたことの修正、 bison の location tracking を使う修正のリバート、protected メソッドの可視性チェックのテストを追加する修正があった！

# 2019-03-28
## nikic: Treat abstract ctors the same, regardless of origin
- https://github.com/php/php-src/commit/058554810649da431efa3ab851be17b0d2f96fb8
- [7.4~]
- abstract のコンストラクタでは直接の子についてしかシグネチャの互換性がチェックされなかったのを、2 世代以上離れたクラスや interface についてもチェックされるよう修正

## dstogov: Use semantic predicates to simplify lookahead and reduce backtracking
- https://github.com/php/php-src/commit/984d05f9484ee0ddb42360523ab2faeb10140d19
- [7.4~]
- ext/ffi で、C 言語宣言のパーサの最適化

## dstogov: Support for __restrict and few GCC attributes
- https://github.com/php/php-src/commit/363e8dd69d4580e047e365304a1bf9917ed95c71
- [7.4~]
- ext/ffi で、\_\_restrict や GCC 拡張の属性を幾つかサポート
- \_\_restict ……

## krakjoe: fix build: readline support must be disabled by default in phpdbg
- https://github.com/php/php-src/commit/b7442f1bb81303d3211844445f69d4a03565aa39
- [7.2~]
- sapi/phpdbg で、readline のサポートをデフォルト無効に修正
- [前日の修正](https://qiita.com/sj-i/items/56139625cdfe485a619c#krakjoe-fix-77805-phpdbg-build-fails-when-readline-is-shared)でついやってたやつだなー

## nikic: Revert "Switch to bison location tracking"
- https://github.com/php/php-src/commit/7f72d771e8581bfff7856b46ae9fb8555b061118
- [7.4~]
- [先日の修正](https://qiita.com/sj-i/items/2fbf5903a0559eb6f9c9#nikic-switch-to-bison-location-tracking)で bison の location tracking を使うようにしてたのをリバート
- 32 bit 版でパーサのオーバーヘッドが大きくなり、WordPress のテストでパーサ内 48M 命令の実行だったのが 59M 命令になってた[らしい](https://github.com/php/php-src/commit/e528762c1c59bc0bd0bd6d78246c14269630cf0f#commitcomment-32894695)

## nikic: Add additional protected visibility prototype test
- https://github.com/php/php-src/commit/d9fbbbc868e7dda70e3a442f4c300ba46ddf449c
- [7.4~]
- protected メソッドの可視性チェックのテストを追加
- な……[なんだこりゃあ！？](https://3v4l.org/B5dkN)
- 直接の親子関係にない B から D のメソッド呼べる仕様なのか
- [PR:3993](https://github.com/php/php-src/pull/3993#issuecomment-477510759)
- 可視性チェックは A で行われて呼び出されるのは D のメソッド、みたいな感じか
stm32f4-discoveryの作法 その9


#概要

stm32f4-discoveryの作法、調べてみた。
豊四季タイニーBASIC Arduino版、移植してみた。

#写真


![image](https://qiita-image-store.s3.amazonaws.com/0/18104/27fc6447-a11b-cf62-6929-de95bc4862bf.png)

#移植

putchとgetchを書いた。

```
uint8_t rx_buffer[20];
void putch(char c)
{
	char * p = "a";
	p = &c;
	uart_2_send(p, 1);
}
char getch()
{
	if (uart_2_is_interupt()) 
	{
		uart_2_clear_interupt();
		int length = uart_2_get(rx_buffer);
		return rx_buffer[0];
	}
	return;
}
```


#サンプルコード

```
10 FOR I=1 TO 100
20 F=I/3*3=I
30 B=I/5*5=I
40 IF F PRINT "fizz",
50 IF B PRINT "buzz",
60 IF F+B=0 PRINT I,
70 PRINT
80 NEXT I
```

以上。
0からはじめるelm-ui#2-styling

# 今日覚えること

`Element.el`と`Element.Attribute msg`型

```elm
el : List (Attribute msg) -> Element msg -> Element msg
```

[成果物](https://ellie-app.com/56vZz8r5TVwa1)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/3ad6e33d-fcd6-7b40-5153-bd339e22c008.png)

# はじめに

`#1`では文字列をただ表示しただけでした。
今日はアプリケーションらしく見た目を飾ってみましょう

# `Attribute msg`型

elm-uiでは要素の修飾を`Attribute msg`型でおこないます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/14928a3a-c583-6fd1-e0e5-1912ed2c91be.png)

[パッケージサイト](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/)をみてください。`Element.Background`や`Element.Border`, `Element.Font`に見た目に関わるAttribute関数が置いてあります

今日は[`Element.Background.color`](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/Element-Background#color)関数を使って背景色をつけてみます

# テキストに背景色をつける

`Element.el`は雑にいうとdivです。`text`には`Attribute`が指定できないので`el`を噛ましてそこに指定していきます

```elm
el [] <| text "Hello, world."
```

`text`を`el`でつつんで

```elm
el [ Background.color <| rgb255 255 169 85 ] <| text "Hello, world."
```

背景色を指定します

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/61e01251-b1d8-a119-9cbf-b7c5e9a584c2.png)

[ここまでのコード](https://ellie-app.com/56LWKz49XTWa1)

# サイズを変更する

これだけじゃさみしいのでサイズも変更してみましょう

```elm
el [ Background.color <| rgb255 255 169 85 
   , width <| px 200
   , height <| px 200
   ] 
   <| text "Hello, world."
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/3ad6e33d-fcd6-7b40-5153-bd339e22c008.png)

`Element.width`と`Element.height`を使って要素のサイズを指定することできます、
今回はピクセルでサイズを指定してみました。200×200の四角形になりました

# 終わり

今日は要素をスタイリングしてみました

## 宿題

- 要素にボーダーを付けてみましょう
- 文字サイズを32pxにしてみましょう

`#elm_ui_from_0`をつけてTwitterでつぶやいてみてね
HTMLのこれから

HP作成支援が充実。つまりHTML不要？プログラミングは学校の義務教育にも適用される話もあります。ITスキル、OA作業は必修項目。<a href="https://fortune-telling-hit.com/vernis-review-reputation/" >ヴェルニの評判と口コミ</a>、このサイトではコピペを使っています。

行政から公共施設でもIT化は進んでいます。オートメーションにはITスキルが必要。メールやかんたんなデスクワークではPCの最低限のスキルが求められます。

就職の募集要項でも、PCスキルを必要とするところが増えてます。高卒、大卒よりもPC経験を求めます。公式サイト、メール、チャット連絡など。参考<a href="https://fortune-telling-hit.com/lowest-price-phone-divination-comparison/" >安い電話占いどこ</a>

HTMLそのものはこれから廃れるか必修となるか。ブログのようにタイピングするだけで作れるなら、必須スキルではなくなります。サイト制作で文字を打つだけ。

WIXやペライチ等これからもHP作成支援は増えるでしょう。プログラミングなのにプログラミング不要の時代がやってきます。参考<a href="https://fortune-telling-hit.com/nagoya-uranai-ataru-review/" >名古屋の占いの感想</a>

参考サイトのようなものはCMSで自動生成。これからの方向性が見えてくる。
Angular7とBootstrap4でラジオボタンの実装が意外に大変だった件について

Angular7とBootstrap4を使ってサイトを開発しています。
両者については、なんとなく掴んだ感が出てきていたのですが、性別をラジオボタンで実装するのに、意外と手間取りました。
インターネットを調べてもあまり参考になるものが出てこなかったのですが、こういうのはフロント開発の方にすれば普通のことなんでしょうか。

# 目指したもの
通常ラジオボタンと言えば、これです。
<img width="370" alt="sex1.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/eb845968-2444-e540-6873-6aa5bf3144ae.png">

これでも支障はないんです。でも、今時ってこんな感じの方がかっこいいですよね？
<img width="797" alt="sex2.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/6961f536-ad66-570e-9460-303c43997b8c.png">


# 実装してみましょう
かっこいい方を実装するためには、data-toggleというものを使うといいらしいのです。そこで以下のように実装しました。

```pug:signin.component.pug
.row
    .col-lg-4
        p.labeltext 性別
    .col-lg-8
        .btn-group.btn-group-toggle.form-control(data-toggle="sexbuttons")
            label.btn.btn-sm.btn-outline-secondary
                input.sr-only(type="radio" name="sex" id="man" autocomplete="off" '[value]'="0" '[(ngModel)]'="model.sex" '#sex'="ngModel" required '(change)'="model.sex=0" '[checked]'="model.sex===0")
                | 男性
            label.btn.btn-sm.btn-outline-secondary
                input.sr-only(type="radio" name="sex" id="woman" autocomplete="off" '[value]'="1" '[(ngModel)]'="model.sex" '#sex'="ngModel" required '(change)'="model.sex=1" '[checked]'="model.sex===1")
                | 女性
```

これだと、かっこいいラジオボタンとしては表示されるのですが、クリックしても黒くなりません。

# クリックしたら切り替わる実装
原因は、data-toggleの指定でした。buttonsって決まってるんですね。

```pug:signin.component.pug
.row
    .col-lg-4
        p.labeltext 性別
    .col-lg-8
        .btn-group.btn-group-toggle.form-control(data-toggle="buttons")
            label.btn.btn-sm.btn-outline-secondary
                input.sr-only(type="radio" name="sex" id="man" autocomplete="off" '[value]'="0" '[(ngModel)]'="model.sex" '#sex'="ngModel" required '(change)'="model.sex=0" '[checked]'="model.sex===0")
                | 男性
            label.btn.btn-sm.btn-outline-secondary
                input.sr-only(type="radio" name="sex" id="woman" autocomplete="off" '[value]'="1" '[(ngModel)]'="model.sex" '#sex'="ngModel" required '(change)'="model.sex=1" '[checked]'="model.sex===1")
                | 女性
```

クリックした方が黒くなる！よしよし。
双方向データバインディングをしているのですが、クリックした方の値が設定されません。
ラジオボタンとしては完璧なはずだ。本にもそう書いてある。
うーん。

# その正体はラベルにあった
かっこいいラジオボタンって、コントロール的にはラジオボタンをクリックしている訳ではないのです。なんとラベルをクリックしていたのです！
ということは、このように実装すれば行けるはず。

```pug:signin.component.pug
.row
    .col-lg-4
        p.labeltext 性別
    .col-lg-8
        .btn-group.btn-group-toggle.form-control(data-toggle="buttons")
            label.btn.btn-sm.btn-outline-secondary('(click)'="model.sex=0" '[class.active]'="model.sex===0")
                input.sr-only(type="radio" name="sex" id="man" autocomplete="off" '[value]'="0" '[(ngModel)]'="model.sex" '#sex'="ngModel" required)
                | 男性
            label.btn.btn-sm.btn-outline-secondary('(click)'="model.sex=1" '[class.active]'="model.sex===1")
                input.sr-only(type="radio" name="sex" id="woman" autocomplete="off" '[value]'="1" '[(ngModel)]'="model.sex" '#sex'="ngModel" required)
                | 女性
```

つまりラベルの方のclickイベントで値を設定するのと、値に合わせてactiveクラスを追加するかどうかを決めます。

奥が深い･･･。
プログラム初心者におすすめのツールを学習順で紹介していく

#はじめに
プログラミング学習をしていく中で実際に使用している、数あるツールの中で特におすすめ！を抜粋して紹介していきます。

#対象者
* プログラミング学習中の初心者の方
* これからプログラミングの学習を始める方

※あるていど学習されているかたはすでに知っている方が多いと思われます。その場合はスルーしちゃってください。

#1. プログラミング学習(入門編）
* [Progate](https://prog-8.com/)
 * プログラミング初心者向けの学習サービス。一部無料でさまざまな言語を使ってみることも出来ます。自分に合う言語を探してみてはいかがでしょうか。スマートフォンでも可能で電車の移動時間にも学習することが出来た点が良かったです。
* [ドットインストール](https://dotinstall.com)
 * こちらも有名なプログラミング学習サービス。3分の動画形式。動画なので音声解説が有り、理解しやすい印象でした。動画本数もとても充実しています。

##### 入門編が終わったら・・・
#2. プログラミングのスキル判定が出来るサイト
* [paiza](https://paiza.jp/)
 * 新卒就活・転職活動、学習動画とスキル判定も出来るのですが、なんと・・・
無料でスキル判定ができる問題がたくさんあります！
問題ごとにランク(D～S)があり、徐々に上のランクを解けるようになることで達成感と成長を感じることができます。
* [TOPSIC](https://products.sint.co.jp/topsic)
 * 初級から上級まで幅広いエンジニアのプログラミングスキルを判定出来るサービス。社員教育やプログラミング採用試験で取り入れている会社も増えているそう。無料トライアルも出来るのでまずは試してみてはどうでしょうか。

##### プログラマの人たちと競ってみたい・・・
#3. プログラミングのスキルを競えるサイト
* [AtCoder](https://atcoder.jp/?lang=ja)
 * オンラインで参加できるプログラミングコンテストのサイト。レーティングが出るので企業へのアピール要素にもなるかも。コンテストの日程を事前に調べておく必要があります。時間があるときに挑戦してみましょう。

##### そろそろ何か作ってみたい・・・
#4. 成果物をつくろう
* [GitHub](https://github.co.jp/)
    * 複数人でソースコードを共有し共同開発することが出来ます。
Gitでバージョン管理することでソースコードの変更履歴をたどることが出来、前段階まで戻ることやファイルの復元が出来るようになります。
全て英語で最初は？？？となりましたが、意外と慣れればわかってきます。いずれ日本語でも使えることを祈りましょう。
* [Slack](https://slack.com/intl/ja/signin)
 * チームコミュニケーションツール。チャットでのやりとりが中心。それまでの会話から振り返りたい情報を検索することができるためとても便利。共同開発で活用することで作業効率を高めましょう。

##### 開発でつまづいた・・・
#情報共有
* [Qiita](https://qiita.com/)
 * 調べてみましょう。わからないことを検索すると大抵のことは出てくるし、これを無料で使えるのは神。
プログラミングを学習する人はこれまでインプットしてきたものをアウトプットすることが大事です！
記事を投稿し、脳みそに定着していきましょう。

#####それでもわからない場合は・・・
#質問しよう
* [teratail](https://teratail.com/)
 * プログラミングについて質問したいけどメンターに質問ができるところはお金がかかるし・・・
と思っているかた、ここで質問を投げかけてみましょう！無料で利用することができます。プログラミングの先輩方から回答やアドバイスがもらえるかもしれません。

#####1人だと勉強が続かない、業界の人と交流してみたい・・・
#勉強会に参加
* [TECH PLAY](https://techplay.jp/)
 * そんな方はこのサイトで勉強会が探せます。プログラマ向けになっているので、目的に合う勉強会が探しやすいと思います。

#####~~よし、初投稿でここまで文字数稼げれば十分だろう。~~
#最後に
多くのプログラミング初心者のお役に立てれば光栄です。
ちなみにこの記事を書いている途中で、より多くのツールを紹介している記事を見つけちゃいました。もっと多くのツールを使ってみたいかたはぜひ参考にしてみてください。
[新人Webプログラマの学習が捗るリンク集](https://qiita.com/tgsmsk/items/5bc9a2a5fd2d4cb155c2)
certbotでlets encryptを設定する

いつもはawsだとelastic load balancer(ELB)のapplication load balancer(ALB)で設定するんですが、
今回は久しぶりにlightsailを触ることになったので、lets encryptをcertbotで設定しました。

## 環境
[aws lightsail]
OS: ubuntu
server: nginx

## コマンド
### 事前準備
```shell
$ git --version
git version 2.17.1
```
上記で``` git version ``` が表示されれば、下記のinstallは必要ないです。

```shell
$ sudo apt install git
```

### certbotの準備
```shell
$ cd ~

$ git clone https://github.com/certbot/certbot

$ sudo mv certbot /usr/local

$ cd /usr/local/certbot/

$ ./certbot-auto --help
Requesting to rerun ./certbot-auto with root privileges...
Usage: certbot-auto [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates
to both this script and certbot will be downloaded and installed. After
ensuring you have the latest versions installed, certbot will be invoked with
all arguments you have provided.

Help for certbot itself cannot be provided until it is installed.

  --debug                                   attempt experimental installation
  -h, --help                                print this help
  -n, --non-interactive, --noninteractive   run without asking for user input
  --no-bootstrap                            do not install OS dependencies
  --no-self-upgrade                         do not download updates
  --os-packages-only                        install OS dependencies and exit
  --install-only                            install certbot, upgrade if needed, and exit
  -v, --verbose                             provide more output
  -q, --quiet                               provide only update/error output;
                                            implies --non-interactive

All arguments are accepted and forwarded to the Certbot client when run.
```

これでcertbotを使う準備は整いました。

### ドメインに紐づくSSLを取得する
#### 必要なものを用意する
・ドメイン
    ・www.hoge.com
・メールアドレス
    ・webmaster@www.hoge.com

```shell
$ ./certbot-auto certonly --standalone -d www.hoge.com -m webmaster@www.hoge.com --agree-tos -n
```

#### certbotが動かない場合
nginxが動いている場合はcertbotがうまく動かない場合があるのでnginxを止めてから上記のコマンドを実行する。

```shell
$ sudo service nginx stop

$ ./certbot-auto certonly --standalone -d www.hoge.com -m webmaster@www.hoge.com --agree-tos -n
```

### nginxにSSLの設定を書いてSSLを設定する

nginx.conf

```nginx
server {
    listen 80;
    server_name www.hoge.com;
    return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  server_name www.hoge.net;
  root /var/www/html/;

  ssl_certificate /etc/letsencrypt/live/www.hoge.net/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/www.hoge.net/privkey.pem;

  ~
```

nginxを再起動します

```shell
$ sudo service nginx start
```

#### lets encryptは期限があるので更新をする

```shell
$ crontab -e
```

cronのファイル内

```shell
0 1 1 * * root /usr/local/certbot/certbot-auto renew --force-renewal && service nginx restart
```
Google Apps ScriptのgetValues()の返り値

#.getValues()の返り値
[公式リファレンス](https://developers.google.com/apps-script/reference/spreadsheet/range#getValues())によると
>Return
> Object[][] — A two-dimensional array of values.

となっており、**連想配列**の形になっている。

#.indexOf()では取得できない
.indexOf()では連想配列を取得できないため以下のようにして取得する。
（A列にデータがあり、keyNameの列番号を取得する）

```
function main(){
    var keyName = "Qiita";

    var sheet = SpreadsheetApp.getActiveSpreadsheet();
    var list = sheet.getActiveSheet().getRange("A:A").getValues();

    var index = getIndex(keyName,list);

    if(index = -1){
      Logger.log("存在しない");
    }else{
      Logger.log("存在する");
    }
}

function getIndex(keyName, list) {
    for(var i = 0; i < list.length; i++) {
        if(list[i] == keyName) {
            return i;
        }
    }
    return -1; 
}
```

#参考にさせていただいた記事
ありがとうございました。
[.indexOf()で配列のindexが取得できないとき](https://qiita.com/risagon/items/a885704a816540a9e58e)
Word2Vecをざっくり理解する

Word2Vecに対するざっくりとした理解&説明です。
人に聞かれた時に簡単に概要を説明できるようになるくらいのレベル感です。
[ゼロから作るDeep Learning2――自然言語処理編](https://www.oreilly.co.jp/books/9784873118369/) の本を参考にしました。

## Word2vecとは？

**単語の分散表現**の一つ。
**推論ベース**の手法で、**2層のニューラルネットワーク**で構成されている。

ロジックとしては、単語を推測することを目標として、その**副産物として単語の分散表現を得る**ことができる。

## カウントベース vs 推論ベース

Word2Vecなどの推論ベースの手法に対して、**カウントベース**と呼ばれる手法がある。
カウントベースは、その名の通り単語の出現頻度によって単語の分散表現を得る。

##### カウントベースの問題点

- 学習データを一度にまとめて処理する必要がある
- 計算コスト高

##### 推論ベース手法の利点

- 逐次的に学習する
- 並列計算も可

**精度に明確な優劣はなく**、
現在は両方の手法を融合させたような**GloVe**という手法もある。

## word2vecが使用するニューラルネットワークのモデル

Word2Vecが使用するニューラルネットワークのモデルは以下の２つがある。

- CBOW (continuous bag-of-words)
- skip-gram

### ニューラルネットワークによる単語の処理方法

前提として、ニューラルネットワークによる単語の処理を説明する。

##### 1. 単語をone-hot表現というベクトルで表す

```
you say goodbye and I say hello .
```

という文があるとする。
それぞれの単語に以下のように番号を振る。

|you|say|goodbye|and|I|hello|.|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|0|1|2|3|4|5|6| 

one-hot表現では該当する単語の番号のところを1,それ以外を0とする。 
例えば次の単語を以下のようなベクトルで表すことができる。

you -> [1,0,0,0,0,0,0]
goodbye -> [0,0,1,0,0,0,0]


##### 2. ベクトルをニューラルネットワークの入力層のニューロンとして、全結合層による変換を行う

単語をone-hot表現というベクトルで表したため、ニューラルネットワークの入力層として扱うことができる。
ここでは隠れ層を3つとすると、以下の図のように表現できる。

![NN_やり直し.png](https://qiita-image-store.s3.amazonaws.com/0/140953/b4242027-8cf9-e0c6-544d-eef64fd5f735.png)

この重み付け(矢印)の7*3の行列をWと置く。
バイアスのない全結合層は、行列の積と同じ処理である。

※**バイアス**…重みをつける際に加算される定数のこと
※**全結合層**…隣接するニューロン間の全てに矢印による結びつきがあること

よって、入力ベクトルをc, 中間層をhと置くと
**c × W = h**
と表すことができる。

ちなみに、one-hot表現であるから、hは行列の性質で**「Wの該当の列を抜き出す」**ことに相当する。

![NN2.png](https://qiita-image-store.s3.amazonaws.com/0/140953/f63e17ef-c3b5-e508-8d99-c50a9a181c71.png)

## CBOWとは

CBOW(continuous bag-of-words)は、**コンテキスト(周囲の単語)**から**ターゲット(中央の単語)**を推測する。
コンテキストの抜き出す個数は任意に決められるが、ここでは前後1単語とする。

|you|?|goodbye|and|I|hello|.|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|

上記の文に対して、?の単語を推測する。
ターゲットがsay、コンテキストはyouとgoodbyeとなる。

![CBOW.png](https://qiita-image-store.s3.amazonaws.com/0/140953/d8e0e7e5-1cc4-9f83-dadf-c0f1f7ba80eb.png)

入力層：[you, goodbye]の2つ
中間層：ニューロンの値は各入力層の全結合による変換の値を平均したもの
出力層：7個のニューロンは各単語に対応しており、各単語の**「スコア」**を表す

このスコアにSoftmax関数を適用して**「確率」**を求める。 
この**W_inの重み**こそが単語の分散表現。


### CBOWモデルの学習

スコアをSoftmaxで確率に変換し、その確率と教師ラベルから**交差エントロピー誤差**を求め、それを**損失**として学習を行う。

W_inの初期値をランダムにおいて学習を行う。
学習を繰り返すことによってW_inの値は収束し、それが単語の分散表現となる。

※**損失**…学習段階のある時点における**ニューラルネットワークの性能を表す指標**。どれだけ悪いかをスカラとして算出。 
※**交差エントロピー誤差**…多クラス分類を行うニューラルネットワークに対して良く用いられる**損失関数**の一つ。

## skip-gramとは

skip-gramは、**ターゲット(中央の単語)**から**コンテキスト(周囲の単語)**を推測する。

|?|say|?|and|I|hello|.|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|

上記の文に対して、?の単語を推測する。
CBOWと同様に、ターゲットがsay、コンテキストはyouとgoodbyeとなる。

![skipGram.png](https://qiita-image-store.s3.amazonaws.com/0/140953/31e6c19e-4340-5db4-b839-a6cf96f2f16b.png)

入力層：[say]の1つの層。
中間層：ニューロンの値は各入力層の全結合による変換の値を平均したもの
出力層：2つの層が得られる。7個のニューロンは各単語に対応しており、各単語の「スコア」を表す

あとはCBOWとだいたい同じ。

##### CBOWに対するskip-gramの特徴

- skip-gramの方が良い結果が得られる傾向がある
- 計算コスト高

## 最後に
今後はDoc2Vec使ったクラスタリング実装したいです。
間違いや不明点があれば遠慮なくご指摘ください！
Laravel公開時に403エラーになった時の解決法

恐らく初歩中の初歩すぎて調べてもよくわからなかったので載せておきます。

#よくある原因【初心者向け】
ディレクトリの所有者の権限が正しくなかったり、PHPのバージョンがあってなかったりなどがあると思います。
ですがそれで解決しなかった場合よくあるのが、**『publicファイルのディレクトリ位置が正しくない』**です。

##確認方法

試しに、https://〇〇.com/**public/**と、現在のルートからpublicまでを書いてみてください。
もしこれで正常にLaravelの文字が表示された場合は、

1. publicフォルダを移動する
2. 公開フォルダ（ルート）を変更する
3. 
のどちらかで解決できます。

##解決方法

２の場合、もしレンタルサーバーなら簡単に変更できます。
例えばロリポップなら、『独自ドメイン設定』から、『公開 (アップロード) フォルダ』の変更で、先ほどのpublicファイルまでをそのまま書けば、数分後に反映されて解決です！

参考記事→https://www.nkshopping.biz/index.php?ロリポップ%21独自ドメインの設定の際の「フォルダ名」とは何ぞや！

１の場合は、変更後の設定などがちょっと面倒ですが、割とすぐできます。
詳しくは@m-shinさんの下記の記事をご覧ください。

参考記事→https://qiita.com/m-shin/items/d76a4e5268a8df5d5bd2
docker-composeでpostgressのデータベースにアクセスする

```
$docker-compose exec db bash

#psql -d postgres -U username
postgres=# \l
                                       List of databases
          Name          |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
------------------------+----------+----------+------------+------------+-----------------------
 hoge                   | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 fuga                   | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 postgres               | postgres | UTF8     | en_US.utf8 | en_US.utf8 |

#\c hoge
You are now connected to database "hoge" as user "username".

```
Gitバージョン管理にて、気をつけるべきこと①

#Gitバージョン管理について
「Git」とは、プロジェクトの共同開発者それぞれが、お互いに干渉する事なく、システマティックに開発を進めることができる便利なツールです。


プログラミングをするなら、まず始めに学ぶべき「Git」ですが、そんなGitで気をつけるべき事をお伝えします。


それは、git commit、です。



#git commitとは
Gitにおいて、commitとは、変更履歴、つまり歴史のようなものです。
必ず、git add、とセットで使用されます。


```
git add .
```


とするとGitにインデックスされていない、全ての変更や作成ファイルなどがインデックスされます。
インデックスされていないものは、Gitでは存在しない扱いとなり、デプロイする際にエラーの原因になる事がありますから注意が必要です。


```
git add ファイル名
```


としてもOKです。
特定のファイルがインデックスされます。


そして、インデックスされたものを、


```
git commit -m "コミットタイトル"
```


これで、コミットされました。
コミットタイトルは、あとで見返しても分かるものにすべきです。
本当にあとで見たら、どんな変更をしたのか分からなくなります。



#git commitは慎重にやるべき
git commitは決して気軽にやって良いものではありません。
なぜなら、その履歴は


```
git log -p
```


というコマンドで完全に変更箇所が露見してしまうからです。
今後、プロジェクトのコードをgithubのパブリックリポジトリに公開する予定があるなら、なおさらです。


もしも、あなたのプロジェクトに、パスワードなどを記載しているのであれば、すぐに環境変数に置き換えましょう。


ただし、最終的なプロジェクトにパスワードを記載していなくても、変更履歴に残っていれば、それは記述しているのと同じなのです。
その場合は、もうパスワードを変更するしかないと思います。



#git commitをする前に
git commitをする前に、必ずやるべきなのは


```
git diff
```


ですね。


このコマンドは、直前のコミット履歴からの差分を教えてくれます。
その差分の中に、公開すべきではない情報がないか、確認することができます。


git add、をしてしまうと、git diffをしても何も出てきませんのでお気をつけください。


また、公開すべきではないファイルを.gitignoreファイルに記述することも大事です。
そうすることで、そのファイルはGitのバージョン管理の対象から外れることになり、当然コミットもされません。
Excel VBA　必ず使うシリーズ 接続をすべて削除する Delete All Connections

#ドキュメントの検査では削除ができない
意外なことに、これはドキュメントの検査では削除ができない
検索すると、StackOverFlowの以下のページがあり、それを加工して作成した
[Delete connection in Excel using VBA after web scraping]( https://stackoverflow.com/questions/45375293/delete-connection-in-excel-using-vba-after-web-scraping)

#コード

```vb:DeleteWorkbookConnections
Function DeleteWorkbookConnections(wbk As Workbook)
'作成したワークブックの接続を削除して、容量を減少し、素早く開き、セキュリティの警告が出ないようにする関数
'変数はWorkbook
Dim i As Long
Dim wsht As Worksheet, cns As Connections, cn As Connection, Qs As QueryTables, Q As QueryTable
If Not (Application.ScreenUpdating = False) Then Application.ScreenUpdating = False
If Not (Application.DisplayAlerts = False) Then Application.DisplayAlerts = False
For Each wsht In wbk.Worksheets
If wsht.QueryTables.Count > 0 Then
Set Qs = wsht.QueryTables
For Each Q In Qs
Q.Delete
Next
End If
Next
If wbk.Connections.Count > 0 Then
Set cns = wbk.Connections
For i = 1 To cns.Count
cns.Item(i).Delete
Next
End If
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Function
```

## Sub プロシージャ版

```vbSub DeleteWorkbookConnections(wbk As Workbook)
' For Excel VBA
' 指定したワークブックの接続を削除することで、ファイルサイズを縮小し、素早く開き、セキュリティの警告が出ないようにするSub プロシージャ
' 変数はWorkbook
Dim i As Long
Dim wsht As Worksheet, cns As Excel.Connections, cn As Connection, Qs As Excel.QueryTables, Q As Excel.QueryTable
If Not (Excel.Application.ScreenUpdating = False) Then Excel.Application.ScreenUpdating = False
If Not (Excel.Application.DisplayAlerts = False) Then Excel.Application.DisplayAlerts = False
For Each wsht In wbk.Worksheets
  If wsht.QueryTables.Count > 0 Then
   Set Qs = wsht.QueryTables
   For Each Q In Qs
      Q.Delete
    Next
  End If
Next
If wbk.Connections.Count > 0 Then
 Set cns = wbk.Connections
 For i = 1 To cns.Count
    cns.Item(i).Delete
  Next
End If
 With Application
  .ScreenUpdating = True
  .DisplayAlerts = True
End With
End Sub
```

### Thisworkbook版

```vb
Sub DeleteThisWorkbookConnections()
' For Excel VBA
' ThisWorkbookの接続を削除することで、ファイルサイズを縮小し、素早く開き、セキュリティの警告が出ないようにするSub プロシージャ
' 変数はWorkbook
' これはThisWorkBook対象
Dim i As Long
Dim wbk As Workbook: Set wbk = ThisWorkbook
Dim wsht As Worksheet, cns As Excel.Connections, cn As Connection, Qs As Excel.QueryTables, Q As Excel.QueryTable
If Not (Excel.Application.ScreenUpdating = False) Then Excel.Application.ScreenUpdating = False
If Not (Excel.Application.DisplayAlerts = False) Then Excel.Application.DisplayAlerts = False
For Each wsht In wbk.Worksheets
  If wsht.QueryTables.Count > 0 Then
   Set Qs = wsht.QueryTables
   For Each Q In Qs
      Q.Delete
    Next
  End If
Next
If wbk.Connections.Count > 0 Then
 Set cns = wbk.Connections
 For i = 1 To cns.Count
    cns.Item(i).Delete
  Next
End If
 With Application
  .ScreenUpdating = True
  .DisplayAlerts = True
End With
End Sub
```
Firebase Admin SDKからStorageにアップロードする

FirebaseにはStorageサービスがありますよね。
サーバーから使いたい場合は、Admin SDKを使うのが順当かと思います。
ですがアップロードする方法が、ググっても意外と出てこなかったのでメモ。
クライアントからなら、いっぱい出てくるんですけどねー。
Node.jsでやっておりますが、他の言語でも同じように辿っていけばできるはず。

# 前提
[公式ドキュメント](https://firebase.google.com/docs/storage/admin/start?hl=ja)をみると、中身はGoogle Cloud Storageに格納されるっぽいですね。
SDK的にもCloud StorageのAPIを使用するようになるみたいです。
ふむふむ、なるほど。

# 事前準備
まずはinitializeから。Admin SDK使ったことある人はいつものやり方ですね。
storageBucketの設定を忘れずに。

```javascript

const admin = require('firebase-admin');
const serviceAccount = require('path/to/serviceAccountKey.json');
admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    storageBucket: '<BUCKET_NAME>.appspot.com'
});
const bucket = admin.storage().bucket();
```

# あげるぞ
## サーバー内のどこかにあるファイルをな！
対象ファイルがサーバー内のどこかにあって、パスがわかっている場合はこんな感じです。

```javascript

const path = 'path/to/hoge.png';
const options = ;
try {
  // オプションでfirebase consoleから見たときのパスを指定できる
  await bucket.upload(path, { destination: 'path/in/firebase/hoge.png' });
} catch (err) {
  console.log(err);
}
```

参考（公式ドキュメント）：
[https://cloud.google.com/nodejs/docs/reference/storage/2.3.x/Bucket#upload](https://cloud.google.com/nodejs/docs/reference/storage/2.3.x/Bucket#upload)

## 変数で持ってるファイルをな！
サーバー内に保存せずに、直でfirebaseにあげたい場合はこんな感じです。

```javascript

// firebase consoleから覗いたときのパスを指定する
const file = bucket.file('path/in/firebase/hoge.png');
try {
  // hogeはアップロードしたいファイル
  await file.save(hoge);
  // contentTypeは別でセットしないとダメ
  await file.setMetadata({ contentType: 'image/png' });
} catch (err) {
  console.log(err);
}
```

なんかアップロードしたあとにfirestore上のファイルにメタデータをセットしなきゃなんないのがすごく微妙ですね、、
いいやり方ご存知の方、教えて下さーい！

参考（公式ドキュメント）：
[https://cloud.google.com/nodejs/docs/reference/storage/2.3.x/File#save](https://cloud.google.com/nodejs/docs/reference/storage/2.3.x/File#save)

以上でした。

# 参考にさせていただきました
[firebase-adminを使ってCloud FunctionからCloud Storageにファイルアップロードする方法](https://tomokazu-kozuma.com/how-to-upload-files-from-cloud-function-to-cloud-storage-using-firebase-admin/)
Travis CI でのセンシティブな情報の暗号化

`.travis.yml`にトークンなどのセンシティブな情報を暗号化して記述する方法のメモ。

例えば、Slackへの通知のトークンを暗号化したり、GitHubにpushしたい場合などに使用するGitHubのパーソナルアクセストークンを暗号化したりなどに利用する。

## 仕組み

Travis CIの側で各リポジトリ毎に秘密鍵と公開鍵のペアを持っている。travisコマンドで公開鍵を使ってセンシティブな情報を暗号化して`.travis.yml`に記載しておくと、ジョブの実行時にTravis CIのサーバー側で復号される。

## 準備

travisコマンドが必要なのでインストールする。

```
brew install ruby
gem install travis
```

## 手順

### エンドポイントの確認と変更

エンドポイントを確認する。デフォルトのエンドポイントは`https://api.travis-ci.org/`となっている。

```shell
travis endpoint
```

travis-ci.orgではなくtravis-ci.comの場合は、以降のコマンドで`-e https://api.travis-ci.com/`のようにエンドポイントを指定する。あるいはそのショートカットである`--com`または`--pro`を指定することもできる。

Enterpriseの場合は、`-X`フラグも必要なので、`-X -e https://travis.example.com/api`を指定する。

デフォルトのエンドポイントを変更することもできる。

```shell
travis endpoint --set-default -X -e https://travis.example.com/api
```

|フラグ|意味|
|---|---|
|-X, --enterpise|Enterprise向けのセットアップを使う|
|-e, --api-endpoint|エンドポイントのURLを指定|
|--set-default|エンドポイントをデフォルトとして設定|

### ログイン

GitHubのアカウントにログインする。パスワードあるいはGitHubでパーソナルアクセストークンを発行し、そのトークンでもログインできる。パーソナルアクセストークンに与えるべき権限については[こちら](https://docs.travis-ci.com/user/github-oauth-scopes/)を参照。

```shell
travis login --com
```

GitHub Enterpriseへのログインがシングルサインオンの場合は、パスワードがないのでパーソナルアクセストークンでログインする必要がある。

```shell
travis login -X -e https://travis.example.com/api --github-token <personal access token>
```

### 暗号化

暗号化したい文字列を指定して暗号化する。どこのリポジトリかはカレントディレクトリから自動的に検知されるが、`-r sotoiwa/webapp-sample`のように明示的に指定することも可能。

ここではSlackへの通知用のトークンの例を示す。Slack通知用のトークンを[Slack Appの設定](https://app.slack.com/services/BGAAA2X44)から確認し、暗号化する。

```shell
travis encrypt --com "sotoiwa:<通知用のトークン>"
```

表示された文字列を`.travis.yaml`に記載する。

```yaml
notifications:
  slack:
    secure: "<暗号化された文字列>"
```

なお、`--add notifications.slack`のようにオプションをつけることで、暗号化と同時に`.travis.yml`に直接追加することもできる。

## 参考リンク

- https://docs.travis-ci.com/user/encryption-keys/
- https://docs.travis-ci.com/user/github-oauth-scopes/
- https://github.com/travis-ci/travis.rb
- https://stackoverflow.com/questions/39513502/how-to-login-into-a-travis-enterprise-using-travis-cli
Rider 2019.1からIL Viewerがつく

`Rider 2019.1`から`IL Viewer`がつきます。

`Window | IL Viewer`を選択します。そうするとこんな感じで、C#のコードに対応するILを確認できます。

![スクリーンショット 2019-03-29 0.49.49.png](https://qiita-image-store.s3.amazonaws.com/0/4125/5beb456c-f03b-2f60-7a84-c459a19a8902.png)

上の画像のように、C#のコードをハイライトしたり、キャレット置くと該当するILがハイライトされます。また、逆にILコードをハイライトしたり、キャレット置くと該当するC#がハイライトされます。

![スクリーンショット 2019-03-29 0.54.04.png](https://qiita-image-store.s3.amazonaws.com/0/4125/64c91885-df2a-4185-3608-b6275e844018.png)


またIL命令にキャレットを置くと、そのILの説明を読むことができます。（説明はMSDNとECMA-335 standard (Partition III: CIL Instruction Set)のものようです。）ILの勉強には良いですね！


追記：また、Rider 2022.3から[SharpLab](https://sharplab.io/)のように「C# => IL => それに相当するC#」を確認することもできるようになりました。

https://qiita.com/RyotaMurohoshi/items/1f8244f0af50ad30583e

# 関連

* [C#で手軽にILや内部を確認するなら「SharpLab」！](https://qiita.com/RyotaMurohoshi/items/a6a252915f11f7559efe)
* [Run static methods from gutter, IL Viewer, install SDKs and more improvements in Rider 2019.1](https://blog.jetbrains.com/dotnet/2019/03/26/run-static-methods-gutter-il-viewer-install-sdks-improvements-rider-2019-1/)
* [Exploring Intermediate Language (IL) with ReSharper and dotPeek](https://blog.jetbrains.com/dotnet/2017/01/19/exploring-intermediate-language-il-with-resharper-and-dotpeek/)
16日目: Unsupervised Domain Adaptation with Residual Transfer Networks

# Unsupervised Domain Adaptation with Residual Transfer Networks 要約
## 読んだ論文
Unsupervised Domain Adaptation with Residual Transfer Networks
Mingsheng Long, Han Zhu, Jianmin Wang, Michael I. Jordan
https://arxiv.org/abs/1602.04433?context=cs
上記の論文を読んだので簡単にまとめます．NIPS2016で発表された論文で210引用されている良論文．ドメイン適応は人多り読んだかなと思ったのですが，これも面白そうということで読むことにしました．

## ~~3行~~4行でまとめる
- ソースドメインとターゲットドメインの**分類器の差異**をResidual Functionで表現する教師なしのドメイン適応手法を提案している．
- モデルの前半部分はMMDでソースターゲット間で似た表現となるように学習する．
- モデル後半は$f_s=f_t+\Delta f$を仮定し，$\Delta f$をResidual Functionで実装している．
- 要するに前半で共通特徴をとってターゲットに最適化し，そこからの差分でソースを分類できるように最適化する感じ．

## 提案手法
### 提案モデル
![20190328_991.png](https://qiita-image-store.s3.amazonaws.com/0/376859/70f5697b-ff5e-f2d7-8099-098c01e5fa34.png)

### Feature Adaption
- CNNの最後にbottleneck layer（$f_{cb}$）の導入により特徴量の次元数を削減する
- ラベル付きのソースドメインデータセットでFine-tuneし，ソースターゲット間の特徴分布が類似するように新しい特徴表現を学習させる（$f_{cb}, f_{cc}$両方で）．
- 最終的に，Feature adaptionを，式(2)で示されるMMD（Maximum Mean Discrepancy）の最小化によって実施する（MMDは[10日目のDomain Separation Networks](https://qiita.com/himatya/items/353b5ccc66ea8c5c19b4)でも出てきた，DANNと同様に2つの特徴表現の距離を縮めるためによく使われる手法）．今回カーネルはガウシアンカーネル．
- DAN[^1]では複数回MMDを用いて複数層の特徴表現を適応させているが，提案手法では最初にそれらを融合し，融合した層を適応させている．
![20190328_002.png](https://qiita-image-store.s3.amazonaws.com/0/376859/bc8c73fc-ac34-8cab-ad46-25e4dcb3ff0e.png)

[^1]: M. Long, Y. Cao, J. Wang, and M. I. Jordan. Learning transferable features with deep adaptation networks.InICML, 2015

### Classifier Adaption　（括弧文は私なりの解釈）
- Feature Adaptionを行ったところで，（ドメイン間共通の特徴抽出が見込めるだけであり，）ソースドメイン分類器$f_s(x)$と，ターゲットドメイン分類器$f_t(x)$が異なる（$f_s(x) \neq f_t(x)$）以上，何かしらの対応を行わなければならない．
- そこで，本稿では$f_s(x),f_t(x)$は微小な差（$\Delta f(x)$）であると仮定する．
- 従来はこれを$f_t(x)=f_s(x)+\Delta f(x)$と表現していたが，この場合$\Delta f(x)$の訓練にターゲット側のラベルが必要となる．
 - この点をどうするのかが**教師なし**ドメイン適応のチャレンジングなところ．
- これをResNetで用いられているResidual Functionを参考に，ショートカットゲートでFigure1のように表現することで解決する．
 - 式的には$f_s(x)=f_t(x)+\Delta f(x)$（ソース側がターゲット側＋差分で表現される）
- ただ，このままでは$f_t(x)$がターゲット側の特性を学習しないので，Entropy Minimization Principle[^2]（式(4)）により$f_t(x)$を直接ターゲットドメインの領域に対応させている．
 - $min_{f_t}\frac{1}{n_t}\sum_{i=1}^{n_t}H(f_t(x_i^t))$....(4)
 - H(・)はエントロピー関数で，$H(f_t(x_i^t))=-\sum_{j=1}^{c}f_j^t(x_i^t)\log f_j^t(x_i^t)$
 - ここでcはクラス数，$f_j^t(x_i^t)$は$x_i^t$がjに予測される確率

[^2]: Y. Grandvalet and Y. Bengio. Semi-supervised learning by entropy minimization. InNIPS, 2004.

以上を踏まえて，最終的にRTN全体の損失関数は次式で表される．
$min_{f_S=f_T+\Delta f}\frac{1}{n_s}\sum_{i=1}^{n_s}L(f_s(x_i^s), y_i^s)+\frac{\gamma}{n_t}\sum_{i=1}^{n_t}H(f_t(x_i^t))+\lambda D_L(D_s,D_t)$

## 評価実験
![20190328_003.png](https://qiita-image-store.s3.amazonaws.com/0/376859/7ebf824d-9d8d-53de-fc43-f0e0b389073e.png)

Officeデータセット2種類でやって，片方がこんな感じ．

## まとめ
- 教師なしのドメイン適応問題において，Classifier Adaptionな手法をResidual Functionな方法で実装した．
- 重要なのは3つの損失関数で，特徴をMMDで適応させる式(2)，ターゲットドメインをエントロピー最小化で訓練する式(4)，あとは普通にソースドメインのクロスエントロピーである．

## 所管
相変わらず論文選定に時間をとられて1時間半くらい，読んでまとめるのに1時間半くらいでした．腰が痛いです．恐らくこの提案手法は，MMDの部分をDANNにしてもよいし，ターゲットドメインの訓練用ロスを$x_t$を再構築するReconstructionLossにしてもよさそうです（よくなるかは別として）．
SSHのid_rsaファイルがchmodで権限変更できない@WSL

Mac使えないマン、買えないマンなのでWindowsにWindows Subsystem for LinuxのUbuntuを入れて使っています。

GitHubやGitBacketのSSHを設定して快適なGitライフを送ろうと思っていたのですが、
Ubuntuのターミナルを起動した時のホームディレクトリをWindowsの方から使いやすいようにWindows直下の近くに変更してしまっていたので、少しハマってしまいました。

はい、確かに以下のようにしてホームディレクトリ変更してました。

```
$ sudo vi /etc/passwd
```

Windowsから使いやすいようにDドライブの直下近くにしていたんです。

```
hige:x:1000:1000:,,,:/mnd/d/home:/bin/bash
```

そしてSSH秘密鍵を以下のようにして設置していました。

```
$ ls /mnt/d/home/.ssh
id_rsa  id_rsa.pub  known_hosts
```

ssh接続のテストして

```
$ ssh -T git@bitbucket.org
```

するとこのようなの出ました。

```
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for 'id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: id_rsa
Permission denied (publickey).
```

でパーミッションが空きすぎているので、変更します。

```
$ chmod 0600 id_rsa
$ ls -la
total 8
-rwxrwxrwx 1 hige hige 1766 Mar 28 23:25 id_rsa
```
変わっていないよ、、
どうも、**Windowsのファイルシステムではchmodで変えられない**らしいのよ
>NTFS/FAT32等のファイルシステム上ではchmodでアクセス権を変更することはできません。

なので、ちゃんとホームディレクトリに戻してその直下の.sshの中で秘密鍵公開鍵を作ると、chmodで権限が変えられ、SSH接続が成功しました。

```
$ sudo vi /etc/passwd
hige:x:1000:1000:,,,:/home/hige:/bin/bash
```

```
$ ssh-keygen 
$ chmod 0600 id_rsa
$ ls -la
-rw------- 1 hige hige 1766 Mar 29 00:19 id_rsa
$ ssh -T git@bitbucket.org
logged in as higekick.
You can use git or hg to connect to Bitbucket. Shell access is disabled.
```
(^_-)-☆


参考：
https://confluence.atlassian.com/bitbucket/set-up-an-ssh-key-728138079.html
http://tadaoyamaoka.hatenablog.com/entry/2016/08/06/112047
https://ja.stackoverflow.com/questions/44239/chmod-%E3%81%A7-%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3-%E3%81%AE%E5%A4%89%E6%9B%B4%E3%81%8C%E5%87%BA%E6%9D%A5%E3%81%AA%E3%81%84