OmniAICreator/Qiita-1.07M huggingface dataset:
1.5 サーバーのバックアップを取るには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[こちら](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/)を参照してください。）

概要
それぞれのケースに適したバックアップとリストアの方法をご紹介します。
 

仮想サーバーのOSの場合
仮想サーバーのOSディスクのバックアップとリストアには、主にイメージ・テンプレートを利用します。詳細は以下のリンクでご紹介しています。 仮想サーバーに対してフレックスイメージを利用すれば、下記にご紹介している仮想サーバーで取得したイメージを物理サーバーにリストアすることもできます。

    1.5.1 仮想サーバーのシステム・バックアップを取るには？
    1.5.2 仮想サーバーのシステム・リストア方法は？
 

物理サーバーのOSの場合
物理サーバーのOSディスクのバックアップとリストアには、フレックス・イメージを利用します。詳細は以下のリンクでご紹介しています。
<注意> フレックス・イメージのサービスは、2017年8月7日にサービス提供終了となりました。

    1.5.3 物理サーバーのシステム・バックアップを取得するには？
    1.5.4 物理サーバーのシステム・リストア方法は？
 

仮想サーバーから物理サーバーへ移行の場合
フレックス・イメージを利用して、仮想から物理への移行、逆に物理から仮想への移行、物理から物理へ移行できます。詳細は以下のリンクでご紹介しています。

    1.5.5 仮想サーバーから物理サーバーへ移行するには？
 

データのバックアップの場合
ポイントは、クラウドの異なる場所や異なる種類のストレージへデータを保存することです。このためには、他のデータセンターへバックアップを保存することや、SANストレージからオブジェクト・ストレージやEVaultへ取得するなどの方法が取れます。これらの詳細について、以下のリンクで解説しています。

    1.5.6 データのバックアップを取得するには？
    4.5 仮想テープ(eVault)にバックアップするには？
    4.6 仮想テープ(eVault)からリストアするには？
    4.7 eValutで取得したサーバーと異なるサーバーに戻す方法は？
    5.8 Windowsのネットワーク・ドライブにするには？
    5.9 Linuxでオブジェクト・ストレージをマウントするには？
1.4.4 コンソールからログインするには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[こちら](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/)を参照してください。）


概要
OS障害や設定不備によってネットワークが利用できなくなった場合、復旧のための最後の手段として、SoftLayerでは、サーバーのコンソールからのログイン手段が提供されています。 ここでは、この方法についてご紹介します。
 

VPN接続
サーバーのコンソールにネットワークからログインするために、ウェブ・ブラウザを利用します。 さらに、セキュリティ上の理由から利用者のPCが、SoftLayerとVPN接続されている必要があります。 サポートされるウェブ・ブラウザは、Microsoft Internet Exploer, FireFoxの2種類です、ここでは、Macユーザーも共通で利用できるように、FireFoxを使って、この機能の利用方法を紹介していきます。

ウェブ・ブラウザを利用してVPNへログインするには、 https://www.softlayer.com/をアクセスして、画面右上にあるVPNをクリックします。


次に「Access」のプルダウン・メニューから「TOK01-SSL VPN」を選択して「LOGIN」をクリックして先に進めます。

次に「Username」、「Password」をインプットして「LOGIN」をクリックしてVPN接続を開始します。

次の「セキュリティ警告」のウィンドが表示された場合、「続行」をクリックして先へ進めます。



さらに次の「セキュリティ警告」のウィンドが表示された場合、「許可する」をクリックして先へ進めます。





次の表示の「Welcome!」メッセージが表示されたらVPN接続成功です。



この状態は、利用者PCに対して、SoftLayerの10.x.x.xのプライベート・IPアドレスが割当られ、プライベート・ネットワークのサーバーと通信できる状態です。これで、KVMコンソールを使ってサーバーへログインできる状態へ一歩近づきました。

仮想サーバーのコンソールへのログイン
仮想サーバーや物理サーバーのコンソールにログインするためには、「KVM Console」から開始します。このKVMとはハイパーバイザーのKVMのことではなく、Keyboard, Video, Mouseの略で、サーバーに接続されたキーボード、ディスプレイ、マウスを、サーバーの前に座って直接操作するようなコンソール環境をネットワーク上の利用者へ提供します。この場合のネットワーク接続は、サーバーOSの制御下ではなく、サーバーのハードウェア管理機能によるものです。従って、OSの障害によって、ネットワークからアクセスできなくなった場合の最終復旧手段として利用できるたいへん重要な機能です。

「KVM Console」への進み方は、「デバイス」->「デバイス・リスト」でサーバーのリストを表示します。このリストからサーバーを選択して「デバイスの詳細」を表示します。

「デバイスの詳細」画面の右端の「アクション」をクリックしてメニューを展開します。この中の下から2番目の「KVMコンソール」をクリックしてKVMコンソールを起動します。





Javaアプレットの起動中に次の確認画面が表示されたら「実行」をクリックして先へ進めます。 この段階で、Javaのセキュリティ機能が原因で例外が発生するケースがあります。 この例外発生対策は、次のトラブルシューティングの項で扱います。




サーバーのコンソールへログインが成功すると、サーバーのコンソール画面が表示されます。 もし、この時に真っ黒な画面が表示されたら、マウスのポインタを黒い部分に入れてクリックすると、スクリーンセーバーが解除されて画面が表示されるでしょう。

次の例は、Window Server系のOSのコンソールで、既にログインされた状態です。





次の例は、CentOSのコンソール画面で、画面の下にログイン・プロンプトが表示されています。 KVMコンソールは、英語対応のみですから、日本語が表示された場合は、上画面コピーのように文字化けします。


物理サーバーのコンソールへのログイン
物理サーバー（ベアメタルサーバー）の場合は、「KVM Console」をクリックすると、次のハードウェア管理機能のログイン画面が表示されます。 このパスワードは、「root」のパスワードとは異なりますので、次に、このパスワードを取得する方法を紹介します。



ポータルのメニューから「Devices」->「Device List」->「Device Name」->「Remote Mgmt」をたどり、次の画面を表示します。「Show」にチェックをいれてパスワードを表示します。 このユーザーID、パスワードでログインして管理画面へ進みます。



次の画面でコンソールを起動するために、次のようにクリックして進めます。 「Remote Control」->「Console Redirection」->「Launch Console」





以下のようなコンソール画面が表示されます。 カスタマーポータルからrootのパスワードを取得してログインします。



サーバーのコンソールへのログイン方法の説明は以上です。この機能は普段使うことはほとんどないと思いますが、この機能があることで運用面での安心感は大きく変わります。 大手のクラウド・サービスの中は、コンソールへアクセスできないものもありますので、SoftLayerを利用することのメリットと見ることができると思います。

 

トラブル・シューティング
Java例外発生時の対応

JavaアプレットのKVMコンソールの起動過程で、次のような例外が発生した場合の対応手順のご紹介です。


Windowsのコントロールパネルを開いて、Java(32ビット)のアイコンをクリックして、Javaコントロール・パネル画面を開きます。





「セキュリティ」のタブを選択して、「セキュリティ・レベル」を中に変更します。そして、「例外サイト・リスト」に、画面コピーにある2行を追加するために「サイト・リストの編集」をクリックします。

ここで追加するエントリーは、https://control.softlayer.com/および、http://10.3.14.234:5199/です。この2番目のアドレスは、データセンターやサーバーごとに異なります。このIPアドレスとポート番号は、例外発生ウィンドに表示されていますので、記録しておいてインプットします。

 




Java例外発生時の対応は以上です。
1.4.3 Windowsリモート・デスクトップ接続を使うには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[こちら](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/)を参照してください。）

概要
Windows Server系OSの場合、Windows7やWindows8.1に標準で備わっているリモート・デスクトップ接続を利用してログインできます。 ここではリモート・デスクトップ接続をつかってログインする方法を説明します。
 

パスワードの確認方法
パスワードの確認方法は、1.4.1 SSHパスワード認証を使うには？を参照願います。
 

リモート・デスクトップでの接続
リモート・デスクトップとは、ネットワークを経由して2台のコンピューターを接続します。 この機能を使って接続すると、接続先のコンピューターの前にいるかのようにリモート・コンピューターのデスクトップが表示され、そのプログラムやファイルにアクセスできる機能です。 Windowsのバージョンによって、それぞれ次の方法でプログラムを起動します。
 

Windows8.1 「Windowsロゴキー」->「スタート画面」->「画面左下にある矢印」->「リモート・デスクトップ接続」
Windows7 「スタート」->「アクセサリ」->「リモート・デスクトップ接続」

起動すると次のウィンドが表示されるので、「コンピューター(C)」にログインするサーバーのIPアドレスを入力し、「接続(N)」をクリックしてください。





次の確認ウィンドが表示されるので、「接続(N)」をクリックして続行します。





続いて次に「Windowsセキュリティ」ウィンドが表示されます。「ユーザ名」に「Administrator」、「パスワード」は先に確認したパスワードをインプットし、「OK」をクリックしてください。





次のような警告ウィンドが表示されます。そのまま「はい(Y)」をクリックして続行します。





Windows Serverのデスクトップ画面が表示されたら、ログインは成功です。次の画面は、Windows Server 2012 Standard Editionのログイン後の画面で、デスクトップ上にServer Managerのウィンドが表示されます。

 




以上で、リモート・デスクトップ接続を利用したWindows Server系OSへのログイン方法の説明は終了です。

注意点として、一般的にインターネットに開いたリモート・デスクトップ接続のTCPポートは、ハッキング対象として攻撃を受けます。攻撃を受けるとたいていは、TCPポートが機能しなくなりログインできなくなってしまい、再起動するまで機能しなくなります。 このようなリスクを回避するために、Windowsファイアウォールを併用するなどして、アクセス可能なネットワークをプライベート・アドレスに限定することをおすすめします。
1.4.2 SSH公開鍵認証を使うには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[こちら](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/)を参照してください。）

概要
SSHは、パスワード認証だけではなく公開鍵認証を用いることができます。この章では、マイクロソフト Windows用のTera Termをつかった公開鍵認証のログイン方法を紹介します。
 

Tera Termを使った公開鍵と秘密鍵のペア作成
公開鍵認証は、Tera Termなどのターミナル・ソフト側に秘密鍵、サーバー側に公開鍵を持ちます。 このために公開鍵と秘密鍵のペアを作成して、公開鍵をSoftLayerのカスタマーポータルへ登録します。 一方秘密鍵は、Tera Termに読み込ませて認証に用います

Tera Termを起動すると、次の「Tera Term:新しい接続」のウィンドが表示されます。 このウィンドの「キャンセル」ボタンをクリックして、ウィンドを消します。





続いて、メニュー・バーの「設定」から「SSH鍵生成」をクリックすると「TTSSH: 鍵生成」ウィンドが表示されます。





次の「TTSSH: 鍵生成」ウィンドの「鍵の種類」に「RSA」を選択し、「ビット数」に「2048」をインプットして、「生成」をクリックします。 鍵のペアが作成されると「公開鍵の保存」と「秘密鍵の保存」のボタンが有効になります。





上画面の「公開鍵の保存」をクリックしてファイルとして保存して、SoftLayerのカスタマーポータルへの登録へ備えます。 次に「秘密鍵の保存」をクリックして、パスワードの代わりに利用する秘密鍵をファイルとして保存します。このファイルは、パスワード認証のパスワードに代わるものですから、第三者に取得されたり、外部に流出のないように、セキュアな場所に保存します。

セキュリティを高めるために、この秘密鍵ファイルを暗号化したい場合には、次のように「鍵のパスフレーズ」と「パスフレーズの確認」にパスフレーズと呼ばれる文字列をインプットします。 この文字列は、秘密鍵を使ってログインする際に、暗号化された秘密鍵ファイルの復号に利用しますから、大切に保管しておきます。




SoftLayerカスタマーポータルへ公開鍵の登録
SoftLayerのカスタマーポータル https://control.softlayer.com/ のメニューバーから「デバイス」->「管理」->「SSH 鍵」の順でメニューをたどります。 そして、右端に表示されている「追加」をクリックして入力フォームを表示します。








「参照」をクリックして公開鍵ファイルをアップロードすることもできますし、「鍵のコンテンツ」へ直接鍵ファイルの中身をペーストすることもできます。この公開鍵の文字列に、改行コードなどが入ると鍵として機能しなくなるので、注意してコピーとペーストを実行します。公開鍵を識別できるように、この鍵の名前を「ラベル」の入力フィールドにインプットします。 「メモ」の入力フィールドには補足などをインプットできます。 最後に「追加」ボタンをクリックして登録を完了します。




サーバー注文時に公開鍵を設定
サーバー注文時の最終確認画面（注文フォーム2ページ目）の「SSH Keys」項目のプルダウンメニューから、公開鍵ラベルを選択します。この画面から複数の公開鍵が登録できます。 この操作によって、サーバーのrootユーザーのSSH設定ファイルに、ここで指定した公開鍵が追加されます。





公開鍵認証の準備ができたことにより、パスワード認証を無効化するには、/etc/ssh/sshd_configファイルのPasswordAuthenticationの行のyesをnoに変更します。 この設定は、フレックス・イメージの取得など、カスタマーポータルからのいくつかの操作ができなくなりますので、適用にあたっては考慮が必要です。

Tera Termを使ってログインする
Tera Term 起動時の「Tera Term:新しい接続」に、接続先のIPアドレスをインプットして「OK」をクリックします。





Tera Termとサーバー間で認証が始まると、「SSH認証」ウィンドが表示されるので、ユーザー名に「root」をインプット、「RSA/DSA/ECDSA鍵を使う」のラジオボタンを選択し秘密鍵ボタンをクリックしてファイルを指定して「OK」をクリックします。



秘密鍵ファイルを暗号化している場合は、パスフレーズをインプットします。

ログインしたら、シェルのプロンプトや「hostname」コマンドでホスト名を確認します。




これで、Tera Termを利用した公開鍵認証の説明は終了です。シェルからsshコマンドを利用する場合や他のターミナル・ソフトを利用する場合でも、基本的な項目は同じですから、本章を参考にするとよいでしょう。

SoftLayerのカスタマーポータルに公開鍵を登録することで、Linux系OSの注文時に、「root」のSSHの設定ファイルに公開鍵を埋め込むことができます。 これによって、セキュリティの高いアクセスだけでなく、安全なリモート・シェルの実行環境ができるため、大量のサーバーを効率良く管理できるようになりますので、ぜひ、ご活用いただきたいと思います。
1.4.1 SSHパスワード認証を使うには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[こちら](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/)を参照してください。）

概要
RedHat, DebianなどのLinux系OSでは、SSHを実装したターミナル・ソフトを利用して、ユーザーIDをパスワードで認証して、ログインすることができます。 ここでは、SSHを実装したターミナル・ソフトとして、Tera Termを利用したログイン方法を紹介します。
 

パスワードの確認方法
最初に、SoftLayerのカスタマーポータルでのパスワードの確認方法を見ていきます。 サーバーの注文ごとに、「root」のパスワードは自動生成されます。 このパスワードを知るには、メニューバーの「デバイス」から「デバイス・リスト」を選んでデバイスのリストを表示します。 このリストのサーバー名の左横にある三角のアイコンをクリックして展開し、「パスワードの表示」にチェックを入れると表示されます。








パスワードを確認する別の方法として、デバイス・リストからデバイスを選択しデバイスの詳細画面を開きます。タブの中からパスワードを選択し、非表示になっているパスワード部分をクリックすると表示されます。





次の画面の「Password」の列の「************」をクリックするとパスワードが表示されます。 この画面のリストは、ユーザーとパスワードを追跡するためのものであり、ここからパスワードを変更することはできません。 また、OSで変更したパスワードが自動的に反映されるわけではありませんので、パスワードなどを変更した際は、手動でこの情報を更新しておくと、追跡する際に便利です。

Tera Termを使ったログイン方法
パスワードの確認ができたので、次はTera Termを使ったログイン方法をみていきます。その前にTera Termとは、1994年から1998年にかけて理化学研究所の寺西高(てらにし たかし)氏により開発された国産のターミナルエミュレータです。現在、SOURCEFORGE.JP ( http://sourceforge.jp/projects/ttssh2/ )から、多くに人により改良が加えらたバージョンのTera Term 4.91 (2016/8 現在) をダウンロードすることができます。これは、オープンソースで開発されており、UTF-8 表示に対応しています。また、SSH1 対応モジュール TTSSH を拡張し、SSH2 プロトコルをサポートしています。

Tera Termを起動すると、「Tera Term: 新しい接続」のウィンドが表示されるので、「ホスト」にサーバーのIPアドレスを入力します。「サービス」ラジオボタンは「SSH」となっていることを確認し、「OK」をクリックしてください。また、その他の設定項目はダイアログの画面コピーを参考すると良いでしょう。 このサンプルのIPアドレスは、サーバーのパブリックIPアドレスを入力しています。プライベートIPアドレスを使って接続したい場合には、先にVPN接続が完了している必要があります。





サーバーに接続できると、「SSH認証」ウィンドが表示されます。「ユーザ名」には「root」、「パスフレーズ」は先に確認したパスワードを入力します。パスワード認証ですから、ラジオボタンは「プレインテキストを使う」となっていることを確認し「OK」をクリックします。





ログインに成功したら、コマンド・プロンプトに表示されるホスト名、または、「hostname」コマンドを実行するなどして、実際にログイン先のサーバーであるかどうかの確認を行うと良いでしょう。



以上でTera Termを利用したSSHパスワード認証のログイン方法の説明は終了です。他のターミナル・ソフトを使った場合でも、基本的に行うべき設定は同じですから、本章を参考にして、お好みのソフトウェアでトライしてみるとよいでしょう。
1.4 サーバーへログインするには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[こちら](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/)を参照してください。）

概要
SoftLayerのクラウド上のサーバーへのログイン方法としては、3つの方法があります。 ここでは、これら3つの方法について、ご紹介します。
 

Linux系OSの場合では、SSHが実装されたターミナル・ソフト
Windows系OSの場合では「リモート デスクトップ接続」
サーバー・コンソールからログイン
 

Linux系OSへログインする場合
SSHが実装されたターミナル・ソフトを利用して、ログインすることができます。 このターミナル・ソフトとしては、WindowsのPCでは、TeraTerm(テラターム), PuTTY(パティ)などのOSSを利用できます。 また、MacOSからは、MacOSに標準で提供されているターミナルからシェルを開いて、sshコマンドを実行することでログインできます。 もちろん、Linux系のOSでは、シェルからsshコマンドを実行することで、ログインできます。 認証方法として2つの方式を利用でき、それぞれの詳細は、次の章でご紹介します。

    1.4.1 SSHパスワード認証を使うには？
    1.4.2 SSH公開鍵認証を使うには？
 

Windows系OSへログインする場合
マイクロソフトのOSに標準で備わっている「リモート デスクトップ接続」を利用することができます。 MacOSからWindowsサーバーにログインする場合は、マイクロソフトから提供されているRemote Desktop Connection を利用して接続することができます。 この詳細は、次の章でご紹介します。

    1.4.3.Windowsリモートデスクトップ接続を使うには？

サーバー・コンソールからログイン
クラウド上のサーバーOS障害などにより、ネットワークからのログインができなくなった場合、インターネット・ブラウザから、サーバーのコンソールへログインすることができます。 この場合の注意点として、クライアントをインターネットVPNなどを使って、SoftLayerのプライベート・ネットワークへ接続している必要があります。 このサーバー・コンソールからのログインの詳細は、次の章でご紹介します。

   1.4.4 コンソールからログインするには？
1.3.3 専用ストレージ装置として使うには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[こちら](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/)を参照してください。）

概要
物理サーバーを利用者だけの共有ストレージ装置として利用する方法のご紹介です。 物理サーバーを専用ストレージ装置として使うと、他者の影響による性能変動のない、安価なストレージ装置にできます。
 

ソフトウェア定義ストレージ装置の必要性
一般に、高い可用性が要求されるストレージ装置は、コントローラーや内部通信経路の2重化、ディスク・ドライブのRAID化、電源ユニットの3重化など、徹底して単一障害を無くす設計になっています。 このため、たいへん高価な装置となることから、ネットワークを使って複数のサーバーの共用ストレージ装置として利用することが一般的です。 この共有ストレージの弱点は、アクセスの集中により応答速度が遅くなる性能変動です。 この度合いは、共有ストレージを同時にアクセスするサーバー数にも依存します。 例えば、一日の中でアクセスが集中する時間帯や、バックアップ取得の時間帯、日付の変わるタイミングなどに、アクセス集中により遅くなる傾向があるようです。

共有ストレージ装置の性能変動の課題について、SoftLayerでは、ソフトウェア定義ストレージ装置を提供しています。 この解決策は、物理サーバーをユーザー専用の共有ストレージとして利用できるようにすることで、この課題に対応します。
 

QuantaStor (クアンタ ストア) とは
QuantaStorは、物理サーバーをストレージ装置として利用するためのソフトウェアです。OSNEXUS社によって開発されたソフトウェア製品で、iSCSI, CIFS, NFS, ClusterFS を利用できます。物理サーバーを注文するときのOSの選択メニューから、OSNEXUSを選ぶことで利用できます。

ここでは、SoftLayerのカスタマーポータルで、物理サーバー上に QuantaStor を構成する場合の特徴的な部分をご紹介します。
 

物理サーバーの選択
ストレージ・システムとして利用するため、プライベート・ネットワーク専用の物理サーバーを選択します。 この見分け方は、「Priavate Network Only」のカラムに「Yes」の表示があることです。この物理サーバーは、アウトバウンド無料枠が付いていないため、利用料金が安く設定されています。 もちろんパブリック・ネットワークにも接続できる物理サーバーもQuantaStorを利用することができます。

ディスクのRAID構成を考慮すると、ディスクを数多く搭載できる物理サーバーのモデルを選択するのが良いでしょう。ここでは、最小限として最大4ドライブ搭載できるモデルを選択しました。


QuantaStorの選択
物理サーバーの注文画面から、次のように「OSNEXUS」をクリック、メニューの中から「QuantaStor」を選択します。 メニューにあるように「QuantaStor」の利用料金は、ストレージ容量で決まります。
Oracle Cloud上の仮想マシンへのアクセス許可を追加する

個人の開発環境でOracle Cloudを利用しているのですが、ネットワークセキュリティグループやセキュリティリスト以外にもiptableにも編集を入れる必要があることがわかったので備忘録がてら残します。

永続化のため、iptablesコマンドではなく、rulesファイルを編集します。

```:command
sudo vi /etc/iptables/rules.v4
```

今回は80/tcp, 443/tcpを追加してみました。

```:rules.v4
~

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [463:49013]
:InstanceServices - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p udp --sport 123 -j ACCEPT
-A INPUT -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
~
```

反映させましょう

```:command
sudo /etc/init.d/netfilter-persistent reload
```

もちろん追加だけでなく。変更、拒否もできますので、要件に応じて編集しましょう。
1.3.1 仮想サーバーとの相違点とは？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[こちら](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/)を参照してください。）

概要
仮想サーバーと物理サーバーの考慮するべき、主な相違点について、ご紹介します。
 

ストレージ
仮想サーバーで利用できるSANとLOCALディスクは、どちらもRAID化されています。 これにより、一つのディスク・ドライブの故障によって、データを失うことはありません。 一方、物理サーバーの初期構成では、OSを起動するためのSATAディスクが、一つ割当られているだけです。 このため、データを保護するRAID構成は、必要に応じて注文時に設定しなければなりません。また、物理サーバーでは、SATA、SAS、SSDなどさまざまな種類のディスクから自由に構成することができます。
 

プロセッサーのモデル
仮想サーバーは、CPU 2.0GHz以上の空いている物理サーバー上の仮想環境(ハイパーバイザー)から割当られます。 したがって、仮想サーバーの個々の性能値は、均一ではありません。 一方、物理サーバーは、プロセッサーのスペックを指定して注文できます。
 

CPUのコア数変更
仮想サーバーでは、CPUコア数は、1,2,4,8,12,16（データセンターによっては32,56も選択可能です）の単位で増減できます。 一方、物理サーバーではCPUコア数の変更やプロセッサーのスペック変更はできません。
 

メモリ量の変更
仮想サーバーのメモリは、GB単位 1,2,4,6,12,16,32,48,64の中から増減できます。 一方、物理サーバーでは、メモリ・モジュールの記憶容量単位の増減に制約されます。
 

GPUカード

物理サーバーでは、GPU (Graphics Processing Unit; 画像処理を担当する部品) や GPGPU（General-purpose computing on graphics processing units; GPUによる汎目的計算）のカードを選択することができます。 このオプションは、「GPU Support」が、「Yes」のモデルで利用できます。
 

基本ソフトウェア
仮想サーバーでは、基本ソフトの選択肢は、Linux系OS、Windows系OSに限られます。 一方、物理サーバーは、仮想サーバーで選択できる基本ソフトに加えて、CoreOS、CloudLinux、FreeBSDなど様々なOSが利用でき、VMwareやCitrixXenやHyper-VやParallels Cloud Serverなどのハイパーバイザーも使用でき、さらには仮想ルーターのVyattaや仮想ストレージのQuantaStorまでご利用いただけます。もし、利用したいものが標準で用意されていなかった場合は、DVDのISOファイルを使って利用者が独自にインストールすることもできます。
 

ネットワーク リンク速度
仮想サーバーのネットワークリンク速度の最大は1Gbpsです。物理サーバーでは、10Gbpsのネットワーク・インタフェースが選択できるモデルもあります。
 

ネットワーク MTU (Max Transfer Unit)サイズ
仮想サーバーのMTUサイズは、1500バイトです。 物理サーバーのMTUサイズは、9000バイトまで指定できます。
 

LANポートの二重化設定
物理サーバーでは、物理的なLANポートの二重化設定ができます。 仮想サーバーは、ソフトウェア上の仮想インタフェースなので、そのような設定はありません。
 

注文してから利用できるまでの待ち時間
物理サーバーの「時間単位」であらかじめ用意されているサーバーキットの場合は30分程度です。
物理サーバーの「月単位」でオーダーメイドの場合は2～4時間程度です。オーダーメイドの場合は、注文を受けてからサーバーの組立てとテストを実施するため、「時間単位」に比べて、待ち時間が長くなります。 
 

高可用性対策
2台の仮想サーバーを利用する場合、可用性を高くするために、その仮想サーバーが稼働する物理サーバーは同じものであってはいけません。 この点で、仮想サーバーを一度に複数注文した場合、連続して同じ物理サーバーに割り当らないように配置されますが、状況によって必ず約束できるものではないとされています。 一方、物理サーバーは、仮想サーバーのように共通基盤上に稼働するものではないため、可用性を低下させる要因が少ないと考えられます。
 

アウトバウンド通信の無料枠
月利用の物理サーバーの無料通信料枠は、サーバーの利用料金に関わらず500ギガバイトです。 一方、月利用の仮想サーバーは250ギガバイトです。 物理サーバーのメニューリストの中で、プライベート・ネットワークだけに接続されるものは、この無料枠がついていないので、注意が必要です。

仮想サーバーと物理サーバーの主な相違点は以上です。
DB(ORACLE)についてのtips

#DB(ORACLE)についての権限の参照など


##対象の人
・未経験でSE、PGになって1～2年目のかた
・現場でDMLしか書いたことがない方
・ORACLE以外のDBしか触ったことのないかた
　
##権限について
DBにはユーザーごとに権限が設定されている。
権限が付与されていることしか実行できない。
すべての権限が付与されている「SYS」ユーザーを乱用してしまうと、
様々な人が参照できてしまうため、情報漏洩につながってしまう可能性がある。
そのため、ユーザーをそれぞれ機能やシステムごとに作成し、必要な権限のみ付与するようにする。

##権限の種類

###主要なシステム権限

| システム権限名 | 権限により許可される操作 |
|:-:|:-:|
|　ALTER DATABASE |　データベースの変更  |
|CREATE TABLE |自分のスキーマ内でのテーブルの作成|
|CREATE ANY TABLE | 任意のスキーマ内でのテーブルの作成 |
|ALTER ANY TABLE | 任意のスキーマ内のテーブルまたはビューの変更 |
|DROP ANY TABLE | 任意のスキーマ内ののテーブルまたは表パーティションの削除または切り捨て |
|SELECT ANY TABLE | 任意のスキーマ内のテーブル、ビューまたはマテリアライズド・ビューの問い合わせ
|CREATE ANY INDEX | 任意のスキーマ内のテーブルに対する索引の作成
|ALTER ANY INDEX | 任意のスキーマの索引の変更
|DROP ANY INDEX | 任意のスキーマの索引の削除
|CREATE USER | ユーザーの作成 |
|ALTER USER | ユーザーの変更 |
|DROP USER | ユーザーの削除 |
|CREATE SESSION | データベースへの接続 |

### 主要なオブジェクト権限

|オブジェクト | オブジェクト権限名 | 権限により許可される操作 |
|:-:|:-:|:-:|
| テーブル  |  SELECT  |  該当テーブルへ問い合わせ（SELECT文）  |
|  テーブル | UPDATE   |  該当テーブルのデータ変更（UPDATE文） |
| テーブル | INSERT  | 該当テーブルへの新しい行の追加（INSERT文）  |
|  テーブル |  DELETE | 該当テーブルの行の削除  |
|  テーブル | ALTER  | 該当テーブルの定義の変更  |
| ビュー  | SELECT  | 該当テーブルへ問い合わせ（SELECT文）  |
| ビュー  | UPDATE  | 該当テーブルのデータ変更（UPDATE文）   |
| ビュー  | INSERT  | 該当テーブルへの新しい行の追加（INSERT文）  |
| ビュー  | DELETE   | 該当テーブルの行の削除  |

###権限を付与する/取り消す　GRANT文/REVOKE文
```
GRANT　＜権限＞　TO　＜USER名>;
REVOKE　＜権限＞ FROM ＜USER名>;
```
###他ユーザーのテーブルついて
ユーザーごとに作成したテーブルにアクセスできるのは、基本的にそのユーザーだけである。
ほかのユーザーから参照する場合は、そのユーザーに対しての権限の付与が必要である。
権限がある場合、は対象のスキーマ≒スキーマ（厳密には違う）をDMLのテーブル名の前につけることにより参照することができる。

```
SELECT * FROM <スキーマ名>.<テーブル名>
```

##ビューとマテリアライズドビューについて

###ビュー
ビューとはあらかじめ複雑なSELECT文をビューとして定義しておき、
参照を簡単にするもの。
たとえば、
・サブクエリが何重にも必要になってしまう
・参照するテーブルが多い
などの場合に用いる。

```
CREATE　VIEW　<ビュー名> AS <実表へのSELECT文>
```

###マテリアライズドビューについて
ビューの内容を一回一回検索するのではなく、保存しておくことにより
複雑なものでも高速で検索することができる。
データに変更が出た場合は更新（リフレッシュ）が必要になるが、
その場合もデータに変更がでている個所のみを更新できるため、高速での処理が可能。
下記のは一例なので、詳細は以下のページを参照
[CREATE MATERIALIZED VIEW](https://docs.oracle.com/cd/E57425_01/121/SQLRF/statements_6002.htm "")

```
CREATE MATERIALIZED VIEW <マテビューの名前>
REFRESH <リフレッシュ方法> 
AS <SELECT文>
```
####リフレッシュ方法について
リフレッシュ方法には何種類かある。

| 更新方法 | 別名 | 説明|
|:-:|:-:|:-:|
| complete  | 完全リフレッシュ  |保持していたデータを全削除し、再検索したSQLの結果を保持する   |
|fast   |高速リフレッシュ   | 前回リフレッシュ時点から更新のあった箇所のみを再検索する  |
|force   | デフォルト | 高速リフレッシュが実行できるSQLであれば高速リフレッシュを実行し、不可能であれば完全リフレッシュを実行する  |

fastにするためには、マテリアライズドビューログの作成が必要

```
CREATE MATERIALIZED VIEW LOG ON <マテビューの名前>
WITH SEQUENCE, ROWID
(<集計テーブルのPK>, <集計テーブルのPK>・・・)
INCLUDING NEW VALUES;
```

###ビューおよびマテビューの参照
テーブルと同様にSELECTすれば参照可能

```
SELECT * FROM <ビューの名前>
```
AWSの無料枠使用アラートが来たので確認してみた

#無料分使用のアラートがくるまで
勉強用にアカウントを作成し、EC2を作成。作成して数日程で登録してあるメールアドレス宛に以下のアラートメールが来た。
##EC2インスタンス
・「EC2インスタンスの稼働時間の85％を使用したよ」という内容。インスタンスをしばらく立ち上げっぱなしにして置きアラームがどう出るか確認した。
無料使用時間が750時間なので月末近くになって通知。
![アラート2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594936/61fdfe52-8156-6e75-f322-b68ab76ef247.png)

##S3
リクエストの85％を使用したよという内容。
S3を設定して1~2日で来たので少し焦った。。あれこんなに使った覚えないけどという感じだった。
![アラート4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594936/f0183ae6-7769-cbc8-9b5d-2ab192204245.png)

###S3のリクエスト
[AWS無料利用枠](https://aws.amazon.com/jp/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc)を確認してみた。
S3の欄を確認してみると「５GBの標準ストレージ」の大きい表示。
だが、その下を確認してみると、上記の他に、
・20,000件のGetリクエスト
・2,000件のPutリクエスト
･･･の表示が。通知に引っ掛かったのがこの要件だった。
![アラート5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594936/ea8104e5-98e3-c1f7-e0af-e37d1af4b6ea.png)

これは見つけにくい、、、サービス毎に細かい要件があるようだ。
(Putリクエストだが、コンソールにログイン/ログアウトしただけでもカウントされているようだった…）


#アラートへの対応

・EC2･･･インスタンス名⇒「停止」を選択
⇒停止しておけば課金の対象にはならない。

・S3･･･S3⇒対象のS3バケットを削除

停止及び削除する際は、削除可能なデータかどうか確認の後に対応。

#終わりに
無料枠といっても割と幅が深い。
ただ無料枠といっても、初回の12か月無料枠や無期限無料枠があり、
使用したいサービスの無料分の枠を把握することで、コストを抑えつつ使用しようしていきたい。
![アラート7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594936/460e29bd-83a0-50d5-c8c5-2898e8a86c22.png)
[AWS無料使用枠](https://aws.amazon.com/jp/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsm.page-all-free-tier=1)
Next.js 9.3 ビルトインsass autoprefixer メモ

# ビルトインSassサポート
Next.js 9.3 でビルトインSassがサポートされたようです。
https://nextjs.org/blog/next-9-3#built-in-sass-support-for-global-stylesheets

既存のBuilt-in CSSと同じ感じで、
グローバルのスタイルに加え、CSS Moduleとしても利用できるようになりました。

ビルトインなので設定なしで使用できますが、sassモジュールはインストールしましょう。

```console
yarn add sass
# or
npm install sass
```

テンプレートのgit を作ったのでこちらからどうぞ。
https://github.com/itomise/next-template
sass以外のところは以下の記事を参考にしています。
https://qiita.com/syuji-higa/items/931e44046c17f53b432b

## Global styles
グローバルで利用したいスタイルは、_app.tsxで`~.scss`のようなファイル名でインポートします。

```tsx
// global style - - -
import 'sanitize.css'
import '../styles/common.scss'

class MyApp extends App {
  render(): JSX.Element {
    const { Component, pageProps }: AppProps = this.props

    return (
      <Provider store={store}>
        <Component {...pageProps} />
      </Provider>
    )
  }
}

export default MyApp
```

グローバルのスタイルは_app.tsxでしか適用できないようです。

## Module
CSS Moduleとして使用するには、ファイル名を`~.module.scss`or`~.module.sass`にして、以下のように記述します。

```tsx
import style from '../../styles/layout/Header.module.scss'

const Header: NextComponentType = () => {
  return (
    <>
      <div className={style.l_header}>
        <p>Header</p>
      </div>
    </>
  )
}
```

実際のクラス名は以下のようになりました。
自動で名前を変えてくれるので名前の競合もなくなりますね。
![sass.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441132/5250fadb-2a39-6941-9514-d8a1715b9fbf.png)


## post cssで autoprefixer適用
ルートに`postcss.config.json`を置くだけでautoprefixerが適用されます。
以下のように記述すれば大丈夫なようです。

```json
{
  "plugins": [
    "postcss-flexbugs-fixes",
    [
      "postcss-preset-env",
      {
        "autoprefixer": {
          "grid": true
        },
        "stage": 3,
        "features": {
          "custom-properties": false
        }
      }
    ]
  ]
}
```
nuxtのie対応

2020年はもうIE対応なんていらないんじゃないかと思えるが、NuxtをIEで動作させる為にどうしたら良いか調べても、公式的な記述を見つける事が出来なかったので記す。

#よく見るやり方
よく見るやり方はpolyfill系をheadオプションで付け加える。Qiitaでもhatenaでもstackoverflowでもよく見る。
polyfill.ioからか、あんま見なかったけどbabel-polyfillを入れる。これで動作はする。

```javascript:nuxt.config.js
export default {
  head: {
    script: [
      { src: 'https://polyfill.io/v3/polyfill.min.js' },
      { src: 'https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.8.7/polyfill.min.js' },
    ]
  }
}
```

https://polyfill.io/v3/
https://cdnjs.com/libraries/babel-polyfill

#babel-polyfillじゃないの？
nuxtはbabelで動作しているので、babel-polyfillが使えるような設定あるんじゃないの？と疑問に思った。すると公式ドキュメントにbabel-preset-envというものがあると知る。
それがこちら
https://ja.nuxtjs.org/api/configuration-build/#babel
https://github.com/nuxt/nuxt.js/tree/dev/packages/babel-preset-app

記述しなくてもデフォルトで動作するようだし、なんならIE9でも動くんじゃないかと思えるが、`npm run dev`でも`npm run build && npm run start`でも動かない。さっぱりわからなくなった。よく見るやり方で終わらせようかと悩んでも、じゃあnuxtにあるbabel-preset-envは一体何のためなのだと。

#modern プロパティが正解
丸2日インターネットを彷徨った結果、思いっきりドキュメントに書いてありました。全然気づかなかった。
https://ja.nuxtjs.org/api/configuration-modern

>デフォルト: false
>'server' または true: Node.js サーバがユーザエージェントをベースにブラウザのバージョンをチェックして、対応したモダンかレガシーどちらかのバンドルを配信するでしょう。

私はmodeがuniversalなのでtrueと記述した。
`npm run dev`では動作しない。`npm run build && npm run start`である必要がある。

```javascript:nuxt.config.js
export default {
  modern: true
}
```

一先ずIE11で動作した。

spaの場合はclientでないと動作しないのだろうか。
mode: spa, modern: clientだと`npm run dev`は動くのかな？
git 初心者書置き

## 最初のリポジトリ連携
gitとは俗にいうバージョン管理ツール
よく使われているgithubを使用



branchを作成後ローカルで作業する場合
windowsユーザーはまず[git for windows](https://gitforwindows.org/)が必要な
為downloadする


終わったら コマンドで初期設定をやる

```
git config --global user.name 'yourname'
git config --global user.email 'yourname@example.com'
```


vscodeでソース管理で連携させたら
初回コミットは宛先が必要なため

```shell
git remote add origin https://github.com/yourname/gitpath.git
```
をしておくこと。
github上で**clone or download**ってボタン押したらURLあるので
`gitpath.git`の部分をそこに入れてね

次に初回push等をする際宛先聞かれるので

```shell
git push --set-upstream origin branch-name
```
とします。

これでpushして無事ローカルで作業できるはず。


## コマンド
便宜上
リモートリポジトリ→remote
ローカルリポジトリ→local

# cmd

| コマンド | 内容 | 
|:-----------|:--------|
| clone       | remoteをマウント|
| remote -v|remote確認|
| branch  | localブランチ作成|
| push | local→remote |
| pull | remote→local |
| stash| local変更退避|



# よく使う流れ

## branchにmaster情報反映

最新情報取得

```
git pull origin master
```

branch切り替えて

```
git rebase master
```

## localのcommit取消

該当commitのIDを確認して

```
git log
```

ID指定して削除

```
git reset --hard <commitId>
```

## local branch 削除
[参照](https://qiita.com/hogeta_/items/33d2334c9b1919bd5120)


# 困った時
## failed to push some refs to

rebertして整合性がおかしくなってpushできない時

```
error: failed to push some refs to  'リポジトリパス'
```

こんなエラーが出たら

```
git push origin :<branch name>
```
で解決
ただしlocalが正のときに限る



## rebase-apply
なんかrebase出来ない

```
It seems that there is already a rebase-apply directory, and
I wonder if you are in the middle of another rebase.  If that is the
case, please try
        git rebase (--continue | --abort | --skip)
If that is not the case, please
        rm -fr "hoge/fuga/rebase-apply"
and run me again.  I am stopping in case you still have something
valuable there.
```

要するに「rebase-apply」ってfolderあるから出来ねーよ
って言われているので該当フォルダを消して再度通すと出来ます。
たぶん処理中にハングアウトしたとかそーゆーので残ると起こり得る
PowerShellスクリプトのラッパースクリプト(JScript)

PowerShellスクリプトはそのままでは実行できない。powershell.exeのExecutionPolicy引数にRemoteSignedを渡し、PowerShellスクリプトを実行できるようにしたラッパースクリプト。

#実行方法

1. ラッパースクリプト(拡張子 js)と実行したいPowerShellスクリプト(拡張子 ps1)を同じフォルダに置く
2. 2つのスクリプトの拡張子を除くファイル名を同じにする
3. ラッパースクリプトを実行する
    - ラッパースクリプトをダブルクリックする
    - ラッパースクリプトにファイルをドラッグ＆ドロップする
    - コマンドプロンプトで cscript を使用して実行する

#ソース
###ラッパースクリプト

```javascript:runps1.js

// powershell.exe の WindowStyle 引数の値
var PS_WINDOW_STYLE = "Normal";

// WshShell.Run の 第2引数(windowStyle)の値
var WSH_WINDOW_STYLE = 1;

// WshShell.Run の 第3引数(waitOnReturn)の値
var WSH_WAIT_ON_RETURN = true;

function main() {
	try {
		var cmd = [
				"powershell.exe", "-NoLogo", "-NoProfile",
				"-WindowStyle", PS_WINDOW_STYLE,
				"-ExecutionPolicy", "RemoteSigned",
				"-File", quote(WScript.ScriptFullName.replace(/\.js$/, ".ps1"))
			];
		for (var i = 0; i < WScript.Arguments.length; i++) {
			cmd.push(quote(WScript.Arguments(i)));
		}
		return WScript.CreateObject("WScript.Shell").Run(cmd.join(" "), WSH_WINDOW_STYLE, WSH_WAIT_ON_RETURN);
	} catch (e) {
		WScript.Echo(e)
		return -1;
	}
}

function quote(arg) {
	return arg.indexOf(" ") >= 0 ? '"' + arg + '"' : arg;
}

WScript.Quit(main());
```

###実行したいPowerShellスクリプトの例

```powershell:runps1.ps1
echo "Hello World!"

Read-Host "続けるには Enter キーを押してください..."
```
Android Vulkan で画面回転の取り扱いのメモ

Vulkan では, いろいろ自前で処理コードをかかないといけません.

Android で, 画面が回転したり, 非アクティブになったりだと SwapChain の作り直しになります.

## Android 側で回転させる

https://developer.android.com/ndk/guides/graphics/design-notes#apply

Android のコンポジターのほうで画面回転させて表示させる方法があります(筆者は試したことありません)

GPU 負荷がかかるとありますので, できれば自前で処理したほうがよさそうです.

## 回転を固定する

AndroidManifest.xml に screenOrientation 記述でとりあえず固定して, 回転を考えるのを止める手があります.

https://developer.android.com/guide/topics/manifest/activity-element
(orientation にもいろいろパターンあってめんどいですね..)

ただ, 条件によっては回転してしまったり, OS 側の機能かなにか無理やり回転させることはできるっぽいので, Google Play できちんとしたアプリ公開するなら回転対応は必須そうです.

How to force landscape or portrait mode in apps like Instagram and others (Android)
https://www.phonearena.com/news/How-to-force-landscape-or-portrait-mode-in-apps-like-Instagram-and-others-Android_id78439


how to force landscape mode with NDK using pure c++ codes
https://stackoverflow.com/questions/12702868/how-to-force-landscape-mode-with-ndk-using-pure-c-codes

### 注意点

`<activity>` のタグに `android:screenOrientation` を記載しないといけません!

筆者は上位の `<application>` タグに記載してしまい, 設定が反映されず 1/2 営業日を浪費してしまいました :cry:  

## 回転の処理をいい感じに扱う

Handling Device Orientation Efficiently in Vulkan With Pre-Rotation
https://android-developers.googleblog.com/2020/02/handling-device-orientation-efficiently.html

めんどくさいですね...

画面が回転したかどうかの判定は, Android 10 だと `vkQueuePresentKHR` で取得できて楽です.
Android 9 or earlier だとめんどいです.


## まとめ

画面がリサイズとかしたらいずれにせよ SwapChain 作り直しになりますので, SwapChain になるべく依存しないデータ構造にしておくのがベターですね.
(UniformBufferObject とか, swapChain の枚数ぶん Descriptor 作成が必要になったりする. 画面リサイズとかで swapChain の枚数が変わるというのは基本ないですが...)
パスワードにurlをかけて知り合いに共有する方法

thinfiと言うサイトがあり、そこで対象のurlとパスワードを入れるとthinfiに誘導するurlが発行されます。それを人に渡してあげるとtinfiサイトになりパスワードを入れないと対象ページが見れないと言う流れです。

結構最近使うので共有です。

https://thinfi.com/
忙しい人向けVue.jsプロジェクト作成

# 開発環境
Visual Studio Code (Onlineでも良い)
拡張機能 Vetur（便利です。）


# 叩くコマンド

プロジェクト作成

```bash:
>vue create <project名>
```
⇒必要なオプションを選択する(今回はTypeScriptや画面遷移させるRouter等を追加)
※追記 tsc -v でバージョン見るとなぜか古いが、内部的には入ってるっぽい。

```bash:
>C:\Users\<username>>npm ls -g typescript
C:\Users\<username>\AppData\Roaming\npm
`-- @vue/cli@4.2.3
  `-- @vue/cli-ui@4.2.3
    `-- typescript@3.7.5
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/c53d1d7a-9240-e740-ebba-81cc48365ebd.png)

ここで内部的にnpmからモジュール持ってきたり、設定したり全部自動でやってくれている。（テストに出ます！）

開発サーバーの起動(出てきたURLに飛べばVueの初期画面が表示されているはずです)

```bash:
>npm run serve
```

本番用ビルド

```bash:
>npm run build
```

# Vue CLI プラグインが超優秀らしい
やってくれること
　・npmモジュールの導入
　・設定ファイル等の追加
　・Vueインスタンスへのロードetc

例えば HTTP クライアントであるaxiosの導入(APIが作れる)
これだけで[async](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function)とか[await](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/await)とかもう使える

```bash:
>vue add axios
```

UIをカッコよくしたい場合に使うライブラリ
　・[Vuetify](https://vuetifyjs.com/ja/) - マテリアルデザイン、コンポーネントが多い。
　・[Element](https://element.eleme.io/#/en-US) - 管理画面向けコンポーネントが豊富
　・[Buefy](https://buefy.org/) - BulmaというCSSフレームワークがベースで軽い
　・[Onsen UI](https://ja.onsen.io/) - モバイルアプリ向け

# Gitにあげときましょう。

Githubに新規リポジトリを追加
https://qiita.com/sodaihirai/items/caf8d39d314fa53db4db


# 参考
[株式会社ゼンアーキテクツCTO三宅さんのセッション](https://www.youtube.com/watch?v=Q0ydkN5yJTM)
Web developer roadmap 2020版のInternetの部分を3項目でまとめてみた 

# はじめに
[フロントエンジニアのロードマップ](https://roadmap.sh/frontend)の記事の、
一番初めの`Internet`の各項目を3項目でまとめてみました。

3項目のため、網羅性はありませんが、
さらっと確認して、`html`や`css`、`javascript`の学習にいち早く取り組めるようなコンテンツになっていれば幸いです。

# -Internet- 3項目解説
## How does the internet work?

* `TCP/IP`と呼ばれるプロトコルで実現
* `TCP/IP`は以下の4つの階層で構成

<table>
	<tr>
		<th>レイヤー名</th>
		<th>役割</th>
		<th>プロトコル</th>
	</tr>
	<tr>
		<td>アプリケーション層</td>
		<td>アプリケーション間のやり取り</td>
		<td>HTTP、SMTP、FTPなど</td>
	</tr>
	<tr>
		<td>トランスポート層</td>
		<td>データの分割やエラー検出など</td>
		<td>TCP、UDP</td>
	</tr>
	<tr>
		<td>インターネット層</td>
		<td>ネットワーク間のデータ通信</td>
		<td>IP、ICMPなど</td>
	</tr>
	<tr>
		<td>ネットワークインターフェース層</td>
		<td>ハードウェアまわりの規定</td>
		<td>イーサネット、PPPなど</td>
	</tr>
</table>


* `IPアドレス`と`ポート番号`を使って、インターネット上のコンピュータにアクセスする



## What is HTTP ?

* クライアントとサーバー間の`データ`のやり取りを規定したもの
* クライアントからサーバへの`HTTPリクエスト`、サーバからクライアントへの`HTTPレスポンス`でデータのやり取りを行う。
* `HTTPリクエスト`,`HTTPレスポンス`は以下で構成される

<table>
	<tr>
		<th>構成</th>
		<th>内容</th>
	</tr>
	<tr>
		<td>リクエスト、レスポンス行</td>
		<td>処理の依頼内容や結果</td>
	</tr>
	<tr>
		<td>メッセージヘッダ</td>
		<td>送信するデータの種類や、返信するデータのタイプなどデータのやり取りに必要な情報</td>
	</tr>
	<tr>
		<td>空白行</td>
		<td>メッセージヘッダの終わりを知らせる</td>
	</tr>
	<tr>
		<td>メッセージボディ</td>
		<td>送受信する際のデータが格納される</td>
	</tr>
</table>



## Browsers and how they work ?

* ブラウザはWebコンテンツを表示するためのアプリケーションで一般的なクライアントを指す
* ブラウザの役割は サーバにリクエストを出し, 利用者が選択した Web ページを表示させること
* IE、Firefox、Safari、Chrome、Opera、Edgeなどの種類がある



## DNS and how it works ?

* Webサイトを閲覧する際に指定するURLは`https://qiita.com/●●`のような構成になるがこの時の`qiita.com`がドメイン名
* `ドメイン名`を`IPアドレス`に変換する仕組みを`DNS(Domain Name System)`という
* URLにドメインが含まれる場合はDNSサーバにてIPアドレスに変換され、検索が行われる



## What is Domain Name ?

* `ドメイン`はインターネット利用者がサイトにアクセスするためのアドレス
* IPアドレスが識別番号として使われるが、人が数字列を覚えることは困難なため文字列の`ドメイン`を使用する
* `ドメイン`は一意に存在し、同じ`ドメイン`は存在しない



## What is hosting ?

* `ホスティング`とは通信事業者などが提供する、サーバコンピュータを提供するサービス
* 利用者は`ホスティング`したサーバにコンテンツを転送することでサービスを提供できる
* 一般的に3種類のホスティングサーバがある
  * `共用サーバ`：1台のサーバを複数のユーザで共有、安い
  * `VPS (Virtual Private Server)`：ホストOS上の仮想サーバを専有できる
  * `専用サーバ`：物理サーバを1台専有できる、高い

# 終わりに
一通りまとめてみました。
間違いなどのご指摘をいただけると幸いです。
jQuery attrを用いてカスタムdata属性を制御

<div id="wrapper">
	<ul class="list">
		<li id="startElement" data-test="test" data-user='{"shift":"A", "skillId":"スキル", "skill" : [1,2,3], "a-b-c" : {"hoge" : "fuga"}}'>データ1</li>
		<li id="targetElement" data-test="test2" data-user='{"shift":"B", "skillId":"スキルB", "skill" : [3,4,5], "a-b-c" : {"hoe" : "piyo"}}'>データ2</li>
	</ul>
	<p><input type="button" id="changeData">データ入れ替え</p>
	
</div>
<h4>データ入れ替えボタンクリックでdata属性が入れ替えられます。</h4>
<pre>

$(function(){
	var $doc = 	$(document);
	var PREFIX = {
		TEST : 'test',
		USER : 'user'
	};
	
	var $startElement = $('#startElement');
	var $targetElement = $('#targetElement');
	
	function getHtmlData($el, prefix) {
		var data = $el.attr('data-' + prefix),
			json = $.parseJSON(data),
			results = {};

		if (typeof json === "object") {
			$.each(json, function(k, v){
				results[k] = v;
			});
		} else if (data === 'string') {
			return data;
		}	
		return results;
	}
	
	function setHtmlData($el, data, prefix) {
		var type = typeof data;
		
		if (type === 'object') {
			$el.removeData('data-' + prefix); //cacheDataを削除
			$el.attr('data-' + prefix, JSON.stringify(data));
			
		} else if (type === 'string') {
			$el.removeData('data-' + prefix); //cacheDataを削除
			$el.attr('data-' + prefix, data);
		}	
		return $el;
	}
	
	function changeHtmlData($el, $el2, prefix) {
		var dataA = getHtmlData($el, prefix);
		var dataB = getHtmlData($el2, prefix);
		setHtmlData($el, dataB, prefix);
		setHtmlData($el2, dataA, prefix);
	}
	
	$doc.on('click','#changeData', function(e){
		changeHtmlData($startElement, $targetElement, PREFIX.USER);
	});


});

</pre>
Folding@Home をコンテナで動かす

## はじめに
コロナウィルスの蔓延で先の見えない不安が続いていますが、
[Folding@Home](https://foldingathome.org/)というプロジェクトを、ASRock JapanさんがTwitterで紹介されていて、
少しでも貢献できればとはじめてみました。

https://twitter.com/AsrockJ/status/1243107649094184960

Folding@Homeの詳しい紹介は[こちら](https://pc.watch.impress.co.jp/docs/news/1243230.html)をご覧ください。

ネイティブのクライアントもありますが、Dockerコンテナも提供されており、
今回はDockerにて参加する方法を記載します。

https://github.com/johnktims/folding-at-home


## 手順
- 適当なディレクトリに以下のファイルを用意します。
    - Dcokerがインストールされ利用できる前提です。
     
```docker-compose.yaml
version: '3.7'
services:
  folding-at-home:
    image: johnktims/folding-at-home
    restart: always
    ports:
      - 7396:7396
    command: >
　　　## --user=ユーザー名（登録する場合はコメントを解除）
      --team=252872
　　　## ASRock Japan さん が開設されているチームです。
      --gpu=false
      --smp=true
      --power=full
      --client-type=advanced
```

- `docker-compose.yaml` を設置したディレクトに移動します。

- `docker-compose up -d` と実行

- ブラウザより`http://127.0.0.1:7396/`にアクセスすると稼働状況が確認できます。

以上で細々とですが処理が実行されていきます。
ひとつひとつは小さな力かもしれませんが、多くの人が集まれば大きな力になります。


## 参考URL
https://qiita.com/Tayu0404/items/97fee464c58080b6c682
https://qiita.com/sot528/items/405daa9574e9c3a80841
venvによるPython仮想環境作成

# venvによるPython仮想環境作成
## venvとは
pythonの仮想環境作成ツール。
ソフトウェア開発を行う上で、使用するライブラリの依存関係を環境ごとに独立させておきたい。
venvを使うことでプロジェクトごとに仮想環境を作成でき、各仮想環境は独立したPythonバイナリとPythonパッケージを保持する。

## 使い方

### 仮想環境の作成
```
python -m venv [venvname]
```
※venvはpython3の標準機能なので、個別インストールは不要

### 仮想環境の有効化
```
//Linux
source [venvname]/bin/activate
//windows
[venvname]/Scripts/activate
```
有効化を行うことで、このディレクトリでのPython実行には仮想環境が使用される。
具体的には、インストールしたpipパッケージはこの仮想環境でのみ有効になり、
スクリプトの実行にはこの仮想環境のPythonインタプリタが使用される。

### パッケージの確認
```
pip list
```
その仮想環境にインストールされたパッケージが表示される。

```
Package    Version
---------- -------
package1   x.x.x
package2   x.x.x
...
```

ちなみに、venv作成時に以下のようにオプションをつけて実行すると、元のpythonにインストールされたパッケージも仮想環境に引き継がれる。

```
source [venvname]/bin/activate --system-site-packages
```

### 無効化
仮想環境の終了は、そのディレクトリ配下で以下を実行。

```
deactivate
```

## 備考: jupyter labへの適用
個人的にjupyter labを使っていて、使用するカーネルを作成したvenvのものにしたい！と思ったので、やり方をメモ。

仮想環境をactivateした状態で、

```
pip install ipykernel
```

jupyterにカーネルを追加。

```
ipython kernel install --user --name=[mame] --display-name=[display_name]
```

jupyter labでコンソールなりnotebookなりを開く際、venvのインタプリタが選択できるようになっている…はず！

削除は以下。

```
jupyter kernelspec uninstall [name]
```

## 参考
* [venv --- 仮想環境の作成](https://docs.python.org/ja/3/library/venv.html)
* [venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)
* [Jupyterで複数カーネルを簡単に選択するための設定](https://qiita.com/tomochiii/items/8b937f15c79a0c3eae0e)
C#からWordテンプレートに文字を挿入する方法


## Word側の設定
- 挿入 > クイックパーツ > フィールド
- MergeFieldを選択
- フィールド名に適当な名前をつける(c#から参照する名前。例：CustomerName)

```c#
using Microsoft.Office.Interop.Word;

// テンプレートのファイルパス
private string template = @"C:\tmp\template.docx";

public void InsertWord(string field, string word)
{
    object missing = Type.Missing;
    var app = new Application();
    var doc = app.Documents.Open(template, ref missing, true);

    foreach (Field myMergeField in doc.Fields)
    {
        Range rngFieldCode = myMergeField.Code;
        String fieldText = rngFieldCode.Text;
        if (fieldText.StartsWith(" MERGEFIELD"))
        {
            Int32 endMerge = fieldText.IndexOf("\\");
            Int32 fieldNameLength = fieldText.Length - endMerge;
            string fieldName = fieldText.Substring(11, endMerge - 11);
            fieldName = fieldName.Trim();
            if (fieldName == field)
            {
                myMergeField.Select();
                app.Selection.TypeText(word);
            }
        }
    }

    // 保存パス
    doc.SaveAs(@"C:\tmp\output.docx");

    var doc_close = (_Document)doc;
    doc_close.Close();

    var applicationclose = (_Application)app;
    applicationclose.Quit();
}
```

## 画像を差し込む場合
画像の場合は、フィールドではできないので、替わりにブックマークを使用する。
Wordで、画像を差し込みたい箇所で、メニュー>挿入>ブックマーク。
C#から参照する名前(ここではIMAGE)をつけて、追加。
ブックマークなので、Word上は何の表示もない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252335/c1ea927e-8b24-7029-0616-cab3d3b74c17.png)

C#では、doc.BookmarksからブックマークのIMAGEを取得して、AddPictureで画像を差し込んでいる。

```c#
string _imagePath = @"c:\aaa.jpg";
foreach (Bookmark b in doc.Bookmarks)
   {
        if (b.Name == "IMAGE")
        {
             doc.Bookmarks["IMAGE"].Range.InlineShapes.AddPicture(_imagePath, false, true);
        }
   }
```

## 参考
- [Add Merge Fields for Word Document and Fetch Data from C#](https://www.c-sharpcorner.com/code/1231/add-merge-fields-for-word-document-and-fetch-data-from-c-sharp.aspx)
AtCoder Grand Contest 過去問チャレンジ1

# AtCoder Grand Contest 過去問チャレンジ1

## [AGC003B - Simplified mahjong](https://atcoder.jp/contests/agc003/tasks/agc003_b)

同じカードで最大限ペアを作って、余ったら繰り越して、繰越分を優先して使ってることにする(つまり余った場合は今のカードの方を繰り越す)で OK なのだが、0枚のカードに繰越が来た場合、優先して使うカードがないので、そこで繰越分を捨てなければいけない. そこだけ気にすれば OK.

```python
N = int(input())

result = 0
remainder = 0
for _ in range(N):
    A = int(input())
    result += (A + remainder) // 2
    if A == 0:
        remainder = 0
    else:
        remainder = (A + remainder) % 2
print(result)
```

## [AGC016A - Shrinking](https://atcoder.jp/contests/agc016/tasks/agc016_a)

s の長さはたかだか100で、アルファベットの種類も26しかないので、総当りしても TLE しない. s に含まれる全てのアルファベットについて、それが最後に残るとして、長さ N の文字列 t を長さ N−1 の文字列 t' に変える操作を実際に行って、操作回数の最小値を求めることができる.

```python
s = input()


def f(s, c):
    result = 0
    while len(set(s)) != 1:
        t = ''
        for i in range(len(s) - 1):
            if s[i] == c or s[i + 1] == c:
                t += c
            else:
                t += s[i]
        s = t
        result += 1
    return result


result = float('inf')
for c in set(s):
    result = min(result, f(s, c))
print(result)
```

## [AGC017A - Biscuits](https://atcoder.jp/contests/agc017/tasks/agc017_a)

奇数個入っている袋は偶数個食べて、偶数個入っている袋は何袋でもいい. 奇数個入っている袋が a 袋、偶数個入っている袋が b 袋だとすると、答えは (<sub>a</sub>C<sub>0</sub> + <sub>a</sub>C<sub>2</sub> + ... + <sub>a</sub>C<sub>floor(a / 2) * 2</sub>) * (<sub>b</sub>C<sub>0</sub> + <sub>b</sub>C<sub>1</sub> + ... + <sub>b</sub>C<sub>b</sub>) になる. ところで <sub>b</sub>C<sub>0</sub> + <sub>b</sub>C<sub>1</sub> + ... + <sub>b</sub>C<sub>b</sub> は 2<sup>b</sup> なので、後はループを回して奇数の袋の選び方の数を求めればよい.

```python
def comb(n, k):
    if n - k < k:
        k = n - k
    if k == 0:
        return 1
    a = 1
    b = 1
    for i in range(k):
        a *= n - i
        b *= i + 1
    return a // b


N, P = map(int, input().split())
A = list(map(int, input().split()))

odds = sum(a % 2 for a in A)
evens = len(A) - odds

print(sum(comb(odds, i) for i in range(P, odds + 1, 2)) * (2 ** evens))
```

## [AGC007A - Shik and Stone](https://atcoder.jp/contests/agc007/tasks/agc007_a)

移動する過程で、駒が常に右または下に動いていたということは、移動回数が (H - 1) + (W - 1) 回になる. 開始地点を含めて # の数１が H + W - 1 個であれば、上や左には動いていないことになる.

```python
H, W = map(int, input().split())
A = [input() for _ in range(H)]

if H + W - 1 == sum(a.count('#') for a in A):
    print('Possible')
else:
    print('Impossible')
```

## [AGC031A - Colorful Subsequence](https://atcoder.jp/contests/agc031/tasks/agc031_a)

文字列 S の中に a が n 回現れていたとすると、a を使わないパターン、1つ目の a を使うパターン、2つ目の a を使うパターン、... n つ目の a を使うパターンの n + 1 パターンがある. それぞれの文字ごとに組み合わせの数は独立なので、文字ごとに出現数を数えて、出現数 + 1 を積算したのが答えになる.

```python
N = int(input())
S = input()

MOD = 1000000007

d = {}
for c in S:
    if c in d:
        d[c] += 1
    else:
        d[c] = 1

result = 1
for x in d.values():
    result *= x + 1
    result %= MOD
result += MOD - 1
result %= MOD

print(result)
```
Google App Engine（GAE）とCloudflareを使ったカスタムドメイン設定で、「Error 525 SSL handshake failed」を解決する方法

Next.jsで制作したアプリケーションをデプロイし、カスタムドメイン設定を行ったところ少々躓いたのでメモを残しておきます。

# 何を実現したかったのか
Google App EngineにNext.jsでビルドしたアプリケーションをデプロイしてカスタムドメインを設定したかった。Cloudflareを用いてSSL化を実現したかった。

例： https://exmaple.com/ を叩くとGoogle App Engineにデプロイされたアプリケーションが動くようにしたかった。

# 何が起こったのか。
![d70194c7424e7a2d8a98447f67ac1a04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/5950b418-a9cf-259c-68a7-a34cd0d20bb9.png)

GAE側のカスタムドメインで指定されたDNSレコードをCloudflareで設定して、 https://example.com/ にアクセスしたところ、上記のような表示がされました。

```
Error 525
SSL handshake failed
```

これを解決するためには、Cloudflare側で発行元専用（今回はGAE用）にSSL証明書を発行する必要がありました。

# Cloudflareで配信元証明書を発行する

![ec797e966676321927a9ab35118be5d5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/29ea5028-4f0a-9426-dda4-81a87eff72da.png)

Cloudflareのサイトにアクセスをして、
「SSL/TLS」→「配信元サーバー」→「証明書を作成」
をクリックします。

![c96d93c2584f20d9729be6e9ca278d87.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/a18714a6-e392-b7ec-a489-ef64061da5e1.png)

「配信元証明書のインストール」というモーダルが出現します。

「CloudflareにプライベートキーとCSRを作成させます」を選択し、「RSA」をプライベートキーの種類として指定します。

「次へ」をクリックします。

![651e4ecee1dea5c2ec1781d86d166fe9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/d9a3e331-b654-d833-3e59-049c18be030b.png)

「配信元証明書のインストール」という画面に切り替わります。
※「キーフォーマット」は変更せず、「PEM」のままにしておきましょう。

発行された「配信元証明書」と「プライベートキー」を使用するために、先の作業に進みましょう。

# 秘密鍵をGAEで使えるようにする

![31c807672a6aec6f71a7cc5837b91ecc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/d173434f-3956-61a6-ccfa-9823a99675f3.png)

Cloudflareから発行された「プライベートキー」はそのまま使用することができません。
（上記のように「選択した秘密鍵は有効ではないようです。」と注意書きが表示されてしまいます...）

これを回避するためには、OpenSSLのコマンドを使用して変換する必要があります。

## 秘密鍵を変換する

Cloudflareから発行された「プライベートキー」を秀丸等で新規ファイルを作成します。保存名は何でも良いですが、今回は「example.com.key」としました。

そして、OpenSSLコマンドを実行しましょう。

```
openssl rsa -in example.com.key -out example.com.nopass.key
```

実行すると「example.com.nopass.key」というキーファイルが出現します。
ここまで来れば準備は完了です。

# GAEに証明書を設定する

![c9c674272224d3b8b79b0142f383c83e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/07f9ec18-954d-14f5-45e8-9d9dfb86626d.png)

Google App Engineのページへアクセスし、「設定」→「SSL証明書」→「新しい証明書をアップロード」をクリックします。

![7e07ea06902a91a6592c97e3e7cac453.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/2cd5ceeb-1fdc-4ed2-ccd5-d7eed8d711a5.png)

「PEM でエンコードされた X.509 公開鍵証明書」にはCloudflareから発行された「配信元証明書」を貼り付けします。

「復号化された PEM でエンコードされた RSA 秘密鍵」にはOpenSSLで変換したキーの中身（秀丸等で開けます）を貼り付けします。

「アップロード」を押して証明書を追加します。

# 証明書を適用する

![a592b49897e8047b96c359394fb4d621.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/af2d7aaa-5a50-58b0-bbdc-190609231e0e.png)

対象のカスタムドメインを選択して「保存」をクリックします。

# 確認して完了！

それではサイトにアクセスしてみましょう。
正しく設定できていれば、5分以内には表示されるはずです。

※いつになっても問題解決できなければ、一度シークレットウィンドウでアクセスしてみると良いかもしれません。キャッシュが原因かも？
Raspberry Pi4のデスクトップをmacに表示する方法！！by real-vnc-server

モニターがなくてもmacのディスプレイで見れるよ。
例によって4に限らず3でもzeroでも同じやり方で行けます。

## はじめに
結論からいうと、よくおすすめされている`tightvncserver`というパッケージを使うと、Chromiumなど一部のアプリがVCN経由で起動できない現象が起きます。なので今回は`real-vnc-server`を使って行きます。
前提条件として、macと同じwifiに繋いだraspberry piにmacからsshしましょう。

## 1. RPIにreal-vnc-serverをインストール

```bash
$ sudo apt update -y
$ sudo apt-get update -y
$ sudo apt-get upgrade -y
```
必要に応じてaptやapt-getのupgradeをしてください

```bash
$ sudo apt-get install realvnc-vnc-server
```

## 2. RPIからVNCを許可
設定画面を起動

```bash
$ sudo raspi-config
```

`Interfacing Options` > `vnc` > `enabled`

## 3. mac側にvnc-viewerをインストール
caskがあれば下記で、なかったから[サイト](https://www.realvnc.com/en/connect/download/viewer/macos/)からダウンロード。

```bash

$ brew cask install vnc-viewer
```
インストールしたらvnc-viewerのアクセシビリティを許可。（mac側の入力を受け付けるようにするため）

## 4. mac側でvnc-viewerを起動してRPIのIPを入力する

RPIのIPは`ifconfig`などで確認。

ここで`Cannnot currently show the desktop` という黒い画面が出るようであれば、RPI側で画面解像度を一番高いものにすると解決します。

### 解像度を変更

```bash
$ sudo raspi-config
```
`Advanced Options` > `Resolution` > `最大のやつ(ex: 1920x1080)`

## 5. vnc-viewerでRPI側のユーザ名とパスワードを入力する
デフォルトのままなら ユーザ名`pi` と パスワード`raspberry`

## 6. わーい見えたー
![スクリーンショット 2020-03-29 0.38.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126718/a2c4a8d7-9985-8ab9-e275-76843ccf51ea.png)
これでchromiumも使えます！


## 他のもみてね
- [Raspberry Pi 4にRaspbian(OS)をインストールする for mac](https://qiita.com/aykusu/items/4ba88ec3a96595954cc3)
- [Raspberry Pi 4をOTGモードでsshする方法 for mac](https://qiita.com/aykusu/items/a44cbf49b0c24fa1b3f8)
PythonでPathを自然ソートする

# pathをソートする
pathを自然ソート（数字通りのソート）をするなら、下記の様に`key`にラムダ式を入れれば良い。

```py

natsorted(list(pathlib.Path(パス).glob("*")),key=lambda x:x.name) 
```
以下余談


## pathごとソートしたら辞書ソートになってしまう話
大量の画像をPDF化するときに画像データをソートする必要があった。画像ファイルの名前はこんな感じ。

```
1.jpg
200.jpg
12.jpg
...
```

これを数字通りに並べたいから辞書ソートじゃなくて自然ソートしたい。
`pathlib`で取得、`natsort`を使ってソートしたら、こんな感じなった。

```python
PosixPath('/Users/usrname/images/1.jpg'),
PosixPath('/Users/usrname/images/10.jpg'),
PosixPath('/Users/usrname/images/20.jpg'),
...
```

*辞書ソートやんけ*

いや`natsort`さん仕事してくださいよ。と思ったけどpathだとソートしてくれないっぽい。でもリファレンスにしっかり対策が書いてあった。

```natsortのリファレンスより抜粋.py
>>> a = ['apple2.50', '2.3apple']
>>> natsorted(a, key=lambda x: x.replace('apple', ''), alg=ns.REAL)
['2.3apple', 'apple2.50']
```

`sort`と同じ様に`key`を指定してあげれば良さそう。投げるのはソート対象のファイル名。こっちは`pathlib`のリファレンスにしっかり書かれてて、

```pathlibのリファレンスより抜粋.py
>>> PurePosixPath('my/library/setup.py').name
'setup.py'
```

つまり`.name`でpathの末尾を取れる。こいつらを組み合わせて使えばソートできそう。
式は冒頭にあるので省略。使ってみるとこんな感じになった。

```python
PosixPath('/Users/usrname/images/1.jpg'),
PosixPath('/Users/usrname/images/2.jpg'),
PosixPath('/Users/usrname/images/3.jpg'),
...
```
しっかりソートされました。めでたしめでたし
jQueryUIを使用して複数要素の同時ドラッグを実現する

# 環境

- jQuery v3.4.1
- jQuery UI 1.12.1

# 実現したいこと

![jquery-ui-drag.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602411/ff62cf2a-bcff-452f-620a-cdab1b78cf92.gif)

これです。
※実際にはイベントを発火させるなどやりたいところでしょうが、今回はまず「動かすこと」だけを目指します。

# ソースコード

```test.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style><!-- 省略 --></style>
  <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
    crossorigin="anonymous"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"
    integrity="sha256-T0Vest3yCU7pafRw9r+settMBX6JkKN06dqBnpQ8d30=" crossorigin="anonymous"></script>
  <script src="tools.js"></script>
</head>

<body>
  <div id="main-draggable" class="draggable main">main</div>
  <div id="sub-draggable-1" class="draggable sub">sub1</div>
  <div id="sub-draggable-2" class="draggable sub">sub2</div>
</body>

</html>
```

```tools.js
"use strict";

$(() => {
    // draggableの設定
    $("#main-draggable").draggable({
        drag(event, ui) {
            // dragの際に、一緒に動かす
            $('.sub').css(ui.position);
        }
    });
});
```

# 解説

jQueryUIの`draggable`は、初期化時にoptionをオブジェクトの形で渡すことができます。

キー`drag`には、dragイベント発火時に行いたい処理を関数として追加することができます。

引数に渡されるのは、

- 第一引数`event`＝jQueryの`event`と同じ
- 第二引数`ui`＝jQueryUI独自のもの

になります。さらに、`ui`はメンバとして

- helper
- position
- offset

を持ちます。（詳細な定義については、[APIドキュメント](https://api.jqueryui.com/draggable/#event-drag)をご確認ください）

positionは`{top: XX, left: XX}`の形で与えられます。
これをjQueryの`css`を使って、一緒に動かしたい要素に指定してあげることで、複数要素のドラッグが実現できます。

# github

https://github.com/AsazuTaiga/jquery-ui-multiple-dragging-sample

# 参考

https://api.jqueryui.com/draggable/#event-drag
Flutterで例外が起きるテストの書き方

FlutterのUnitTestを書いていて、忘れそうなので、メモ。

# 1. **MyException** という例外が起きるはずのチェック

```Dart:xxx_test.dart
expect(() =>　例外が起きるはずの処理,
          throwsA(TypeMatcher<MyException>()));

```

# 2. 組み込みの例外/エラーが起きるはずのチェック

## (1) FormatException

```Dart:xxx_test.dart
expect(() =>　例外が起きるはずの処理,
          throwsFormatException);
```

## (2) ArgumentError

```Dart:xxx_test.dart
expect(() =>　例外が起きるはずの処理,
          throwsArgumentError);
```

# 参考
https://sbfl.net/blog/2015/01/03/unit-testing-with-dart/