OmniAICreator/Qiita-1.07M huggingface dataset:
PyOpenGL本を書きました

# はじめに

PyOpenGL本を書きました。PDFの電子書籍です。
以下のBOOTHサイトで購入出来ます。

[PyOpenGL入門_基礎編(BOOTH)](https://mainichipython.booth.pm/items/3144975)

以下のYouTube動画では本の内容を一部立ち読みできます。

[PyOpenGLの入門書を書きました。(YouTube)](https://youtu.be/kRhwkNjxuyI)

# 対象読者

- Pythonの基礎を習得していて、OpenGLを基礎から勉強したい
- OpenGLの知識を整理したい
- OpenGLの基礎は知っているが、PyOpenGLでも動かしてみたい
- PyOpenGLを使用して簡単なアプリケーションやゲームを作成したい

# 執筆動機

私はPythonが好きでOpenGLに興味があるのですが、PythonでOpenGLを扱えるPyOpenGLの日本語の情報がネットや書籍を探しても非常に少ないです。ネットでは断片的にはありますが、情報が古かったり基本的な部分しかなかったりします。

OpenGLの情報は、C/C++が多いです。実用的なアプリを作ろうとすると必然的にそうなると思います。しかし勉強用であれば、私はPythonの方が断然良いと考えています。
理由としては、以下が挙げられます。

1. ビルドが不要ですぐにテスト出来る
1. ビルドのための環境設定が不要
1. Pythonの色々なライブラリを利用する事でOpenGLの勉強に集中できる

そして私はゲームプログラミングに興味があるのですが、PyOpenGLではゲームに必要なアニメーションやエフェクトなどの情報はほとんどないような状態です。自分が欲しかった情報をまとめるという事と、後で自分が忘れてしまった時にリファレンスとして利用できる事を目標に執筆をしました。

簡単なゲームであればPyOpenGLだけでも作る事が出来る場合もあると思いますし、ゲームを作る際のプロトタイプを作るのに役立てる事も可能だと思います。そして、OpenGLのCのAPIを単にPythonでラップしたでけなので一対一に対応出来ます。そのため、PyOpenGLのコードをC++のOpenGLのコードに置き換える事は難しくないと思います。

ゲームグラフィックと言えば、Direct3Dと思われる方も多いかも知れませんが、あのバーチャファイター5は、OpenGLをベースに実装されてるようです。そして、私はDirect3DよりもOpenGLの方がはるかに敷居が低いと思っています。単に3Dグラフィックに興味があるのであれば、OpenGLで基礎固めをしても良いと思います。

[3Dゲームファンのための「バーチャファイター5」グラフィックス講座](https://game.watch.impress.co.jp/docs/20061025/3dvf5.htm)

# 書籍内容

内容としては、OpenGLの知識ゼロからスキニングアニメーションまでです。OpenGLの内容理解を重視しています。

サンプルは基本的にPythonのライブラリを利用しているのですが、アニメーションはAssimpライブラリを使用している章がありますが、その部分だけはPythonの既存のライブラリを使用せず自作しています。C++に移植する場合にも知識を活かせると思います。パフォーマンス重視の実装ではなく、Pythonでのテストしやすさを重視して実装しています。

全ての内容を理解する必要はありませんが、この書籍を理解出来れば、とりあえず人型の3Dキャラのアニメーションは出来るようになると思います。以下の動画でmixamoでキャラクタのアニメーションファイルであるFBXファイルを出力する方法を解説していますが、書籍付属のサンプルで問題なく動かせる事は確認しています。

[3Dモデルのアニメーション作成(YouTube)](https://www.youtube.com/watch?v=UYZBPY7KzQI&t=9s)

実はFBXなどのアニメーションファイルというのは、少々クセがあるフォーマットなのでアプリ用に完全に汎用的なコードを書くというのは意外と難しいです。ですので、glTFのバイナリ版であるglbファイルのアニメーションも内容として含めています。こちらの方が汎用性という意味では高いと思います。

またFBXやCOLLADAなどのフォーマットは問題があるゆえにVRMというフォーマットも考案されています。VRMはglbをベースとして拡張されたフォーマットです。VRMの紹介を以下の動画にまとめています。今後は特にVRなどのゲームにはこちらを利用する機会が増えるかもしれません。

[3DアバターファイルフォーマットVRMとは(YouTube)](https://www.youtube.com/watch?v=wl1pOecZUvk&t=143s)

今回の書籍は、Vol.1なのですが、Vol.2として「GPGPU・エフェクト編」を予定しており、2部作で完結したいと思っています。もしニーズや書き忘れた情報があれば、Vol.3を追加して三部作とするかもしれません。

# おわりに

本記事では私が執筆したPyOpenGLの電子書籍を紹介しました。今後、YouTubeで3Dのサンプルゲームなども制作していきたいと思っています。

YouTube動画ではPythonメインにする予定ですが、ゲーム関連にも興味がありますので、まだまだ先の予定にはなると思いますが、UnityやUnrealEngineの情報も提供していきたいと考えています。楽しくプログラミングが勉強出来る情報を提供できる事を活動の目標としています。

もし興味がありましたら、YouTube動画だけでも見て頂ければありがたいです。
JKS形式のキーストアをPKCS12形式に変換する

最近のWebSphere LibertyまたはOpen Libertyでは、キーストアの形式がJKSからPKCS12に変更になっています。JKS形式も引き続き使用できますが、server.xmlでタイプを指定する必要があることと、将来廃止になる可能性があります。

```server.xml
<keyStore id="defaultKeyStore" type="JKS" password="********" location="..."/>
```

今後のために、JKS形式のキーストアを使っている場合はPKCS12形式に変換することをお勧めします。

例えば、LinuxのJDKで使用しているJKSを変換するためには、下記のコマンドを実行します。

```
$ keytool -importkeystore -srckeystore /etc/pki/java/cacerts -srcstoretype jks -srcstorepass changeit -destkeystore key.p12 -deststoretype pkcs12 -deststorepass newpassword
```

Libertyではこのファイルを``${サーバ}/resources/security/key.p12``に置いておけば、locationの指定すら不要で、下記のようにシンプルに記述できます。

```server.xml
<keyStore id="defaultKeyStore" password="********"/>
```

Mavenを使う場合は``src/main/liberty/config/resources/security/key.p12``に置いていけばテスト時に自動的に所定の場所にコピーされます。

なお、パスワードはsecurityUtilityで暗号化しておくことを忘れずに。

```
$ ${Libertyインストールディレクトリ}/bin/securityUtility encode
テキストの入力: 
テキストの再入力: 
{xor}************
```
【Unity】JsonUtilityの[Serializable]について

## はじめに
-  リストをJSONで送信するにはクラスを囲うラッパーが必要．
-  しかし，サーバー側ではJsonUtilityがうまく働かずに空のJson```{}```が返ってきていた問題を解決．


## 開発環境
- Unity 2019.4.23f

## 動いたコード
クラス定義の部分

```class.cs
// ↓これがないと空の要素になる
[System.Serializable]
public class Tverts{
    public float x;
    public float y;
    public float z;
    public Tverts(float a,float b,float c){
        x=a;
        y=b;
        z=c;
    }
}
// ↓これがないと空の要素になる
[System.Serializable]
public class Tfaces{
    public int f1;
    public int f2;
    public int f3;
    public Tfaces(int a,int b,int c){
        f1=a;
        f2=b;
        f3=c;
    }
}
// ラッパークラス
public class Wrapper
{
    public List<Tverts> tverts;
    public List<Tfaces> tfaces;
}

```

クラスの使用部分

```_.cs
        Wrapper test = new Wrapper(); 
        test.tverts = new List<Tverts>();
        test.tfaces = new List<Tfaces>();
        test.tfaces.Add(new Tfaces(1,1,1));
        test.tverts.Add(new Tverts(1.0f,1.0f,1.0f));
        string testjson = JsonUtility.ToJson(test);
```

```_.JSON
{"tverts":[{"x":1.0,"y":1.0,"z":1.0,"weight":0.0}],"tfaces":[{"f1":1,"f2":1,"f3":1}]}
```
## つまりどういうこと？
ラッパーされる側のクラスには```[Serializable]```が無いとJSON化できない(空のJsonが返ってくる)．ただし```JsonUtility.ToJson()```に渡すクラス(Object)は```[Serializable]```されている必要がない(Publicで宣言されていればOK)．

＊ただしUnty公式ではJson化する全てのオブジェクトを[Serializable]するよう勧めているので，おとなしくすべて[Serializable]しましょう．
3.2 HTMLだけでWebページを作ってみよう

# 完成イメージ

CSSを使用していないため、文字の大きさや、色は再現できていない。また、レスポンシブなページにもなっていない。  
後々CSSも追加して参考Webページと同じようにする予定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/848c5d09-62fc-2de1-6a4a-1021b47deaa1.png)

参考Webページ
https://www.au-okinawa.com/a/j3/

# 事前準備
必要な画像ファイルを参考Webページから取得する（6ファイル）

#### 取得方法
対象の画像にカーソルを当て右クリックし、「名前を付けて画像を保存」を選択。
ファイルはリサイズしているのでこのページから取得しないこと 
ただし、6つ目のタイトルのアイコンは取得方法が異なるためこのページから取得しても良い。

1．ヘッダー
![UQ_header_logo.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/9dbadbbe-2625-2f72-454d-ff2a224cf27a.jpeg)
2．メイン画像１  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/f1ccade6-6153-1bef-baae-5b3d4bbe180c.jpeg" width="300">
3．メイン画像２  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/5a7ac743-cba3-e2f1-62fc-6e0c7e05156e.jpeg" width="300">

4．メイン画像３  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/d84d4bae-ab6f-8b95-eaf9-0bfa0b6a2304.jpeg" width="300">

5．フッター
![UQ_footer_logo.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/6dafa000-e1d0-c85b-3bd6-793f32fe1cce.jpeg)
6. タイトルのアイコン  
ブラウザのタブに画像があるためそのまま保存できない。デベロッパーツールを開きheadタグ内のlinkタグから.ionファイルを開き保存する  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/5254181a-5d0d-42d1-1c79-833903e263b4.png)


# 本文
UQのWebページを表示し、デベロッパーツールを開く。どのタグに何が設定されているかを確認し、それを参考にしながらコーディングしていく。
### headタグ
文書の作者情報、サーチエンジン向けのキーワードや説明、文書のタイトル、利用するスタイルシート等 その文書に関する情報を記述します。

#### titleタグ
ブラウザのタブに表示する文言を記述します。

```html
<title>
  UQ mobileご利用のみなさま!auでんき申し込み開始しました!｜沖縄セルラー
</title>
```


#### linkタグ
その文書ファイルと関連する別の文書ファイルを指定し、 その関係を定義するもの。
CSSのスタイルシートを設定する時などに使用します。

ブラウザのタブのアイコンは属性名`rel`に`icon`を指定して使用する。
`href`には参照したいファイルの相対パスを記載。

```html
<link rel="icon" href="./images/favicon.ico" />
```

### bodyタグ
文章や画像など、実際にブラウザの画面上に表示される内容を指定するタグです。 <body>タグの中に書かれたテキストや画像などがブラウザの画面上に表示されます。
#### headerタグ
HTML5から新たに追加され、セクションの目次や検索フォーム、あるいは、関連ロゴをまとめるために使用されます。

```html
<header>
  <img src="./images/UQ_header_logo.jpeg" alt="UQ mobile" />
</header>
```

#### mainタグ
HTML5で追加された新しい要素です。Webサイト内の各ページで繰り返し使われるヘッダーやナビゲーション、検索フォームやフッター情報などを除いた、文書内の主要なコンテンツを表します。

```html
<main>
  ここにメイン画像などを記述していきます
</main>
```

#### imgタグ、mapタグ、areaタグ
この３つのタグを組み合わせて使用することで画像に対して、指定する範囲内にリンクを設定することができる。（クライアントサイドイメージマップ）

- <b>imgタグ</b>：画像を表示するタグ（この上にマップがのせられる）  
- <b>mapタグ</b>：ひとつの画像に複数のリンクを作成するタグ（マップ全体の範囲を表す）
- <b>areaタグ</b>：イメージマップの領域を設定するタグ（マップ中のリンクを表す）

詳細は以下ページ参照。
https://code-kitchen.dev/html/map-area/

```html
<img
  src="./images/UQ_img_01.jpeg"
  usemap="#image-map1"
  alt="auでんきお申し込み開始!!でんきセット割にエントリーしている方はお申し込みをお忘れなく"
/>
<map name="image-map1">
  <area
    target="_blank"
    alt="auでんきの詳細はこちら"
    title="auでんきの詳細はこちら"
    href="https://www.au-okinawa.com/audenkicp/"
    coords="679,1688,336,1633"
    shape="rect"
  />
</map>
```

上記「クライアントサイドイメージマップ」を簡単に作成できるWebサイト。基本このサイトで作成することをおすすめします。仮に座標の指定などがあってもareaタグの属性`cordes`を手動で修正したらいいので。
https://www.image-map.net/
Manjaroでインターネットに繋がらない

# この記事は？
自宅PCのOSをWindowsからManjaroに変えた際にWifiの設定が完了してデフォルトゲートウェイまでpignが通っているのにFirefoxで見てもインターネットに繋がる気配がなく困ったので記事にしてみようと思いました。
結論としては名前解決に失敗していたのですが、どうやって気づいたかなどを残しておこうと思います。

# 試してみたこと
①googleのサーバ宛にpingを飛ばしてみる

``` shell:
 ping www.google.com
```

上記のコマンドでpingを飛ばそうとしましたが、失敗(pingが動かない状態)


②googleのDNSにpingを飛ばしてみる

``` shell:
 ping 8.8.8.8
```

上記のコマンドを実行すると普通にpingが通りました。

このことから、別に外部に出れていないんではなく単純に名前解決に失敗したんだと分かりました!


# 解決方法
## /etc/resolv.confを書き換える
よく見るとわけのわからないサーバがDNSとして登録されていたので/etc/resolv.confを以下のように書き換えます。
※ここでは仮にGoogleのネームサーバにしますが、良しなに置き換えてください

``` conf:/etc/resolv.conf
nameserver 8.8.8.8
```

上記の通りに変更を加えることで無事にネットワークつながりました！

## NetworkManagerが再起動時にresolv.confを書き換えないように修正する
NetworkManagerに何も設定しない状態だと/etc/resolv.confを再起動等で自動生成してしまいます。
PC再起動時に書き換わると厄介なので/etc/NetworkManager/NetworkManager.confに以下のように修正を加えます。

``` conf:/etc/NetworkManager/NetworkManager.conf
[main]
dns=none
```

# 終わりに
そもそもNetworkManagerが起動してなかったりとかいろいろ問題があった途中からがちゃがちゃやったので一番最後のはまりポイントしか書いてませんが、案外この件を解決する記事が少なかったので書いてみました。
慣れている人ならばあまりはまらないのかもしれませんが、誰かの構築の助けになればと思います。
Vue.jsをこれから学ぶなら抑えておきたいおすすめ書籍&サイト

はじめまして、エンジニア転職に向けてプログラミングスクールで主にRailsを学習しているパピヨンちゃんです。
Rails一筋で数ヶ月を生き抜いてきた私ですが、ある日を境にVue.js学びたい期に入りました。

有り難いことに、スクール内で実際に転職に成功された方や、ハイクオリティなPFを作りきった方、運営の方からアドバイスを頂けたことにより、自分の中でいい感じすぎる学習マップ的なものが爆誕しましたので、教えて頂いた方や新しく学ぼうとする意欲の高い方にリスペクトを込めて記事にさせて頂きます。

 
## この記事が参考になりそうな方
- これからVue.jsを学びたいと考えている方
- Vue.jsを学習しているが、より順序良く進められないか考えている方


前置きが長くなりましたが、ざっと紹介させていただきます。

## なにそれ美味しいの？状態の人
[たった1日で基本が身に付く! Vue.js 超入門](https://www.amazon.co.jp/dp/4297113775/ref=cm_sw_em_r_mt_dp_HJ34SXZV0CPMEZTKKGY6?_encoding=UTF8&psc=1)
全く知らない方はこの書籍で概要を掴むのがおすすめとのこと。
さっと読んでみた感じ２００ページでわかりやすくまとまっている印象です。

## 少しわかった人[初級〜中級レベル〜]
[基礎から学ぶVue.js [2.x対応! ]](https://www.amazon.co.jp/-/en/mio/dp/4863543239/ref=pd_lpo_2?pd_rd_i=4863543239&psc=1) 
通称「猫本」


[これからはじめるVue.js実践入門](https://www.amazon.co.jp/dp/4815601828/ref=cm_sw_em_r_mt_dp_2GCEY80WQDPTHVBWVFJS)
通称「カッパ本」
 
初級〜中級レベルとして上記の２冊がおすすめされていました。
どちらか１冊学習で十分とのことですが、コミュニティ内ではカッパ本の方が推されている印象です。

## 少しわかった人②
RUNTEQカリキュラムVue.js編

ごめんなさい！ こちらはRUNTEQ生のみ対象です。
RailsにVue.jsを組み込むなら絶対通ったほうがいいと実際PFでVue.jsを使用した先輩に伺いました。
ただ、知識０だとハードル高めで上記などで事前学習や並行しても良いかもとのことです。

## Vueについて網羅されているブログ[初級〜中級レベル]
[REFFECT](https://reffect.co.jp/vue)
現役の方は特にこちらのブログを推していました。
Vue.jsのV2を前提にこの記事を書いていますが、こちらのブログはV2とV3の内容それぞれ解説してくださっていたりします。
抑えておいた方が良いと思います。

## JavaScript(ES6)を勉強すると尚良し
[JavaScript Primer - 迷わないための入門書 WEBの記事ver](https://jsprimer.net/)
このサイトの内容をしっかり勉強していたら十分とのこと。書籍版は４０００円くらいします。

 
## 勉強のお供・検証系
お手軽・・・[JSFiddle](https://jsfiddle.net/)
お手軽&軽操作で色んなフレームワークを試せる・・・[codesandbox](https://codesandbox.io/)




## 現役の方に聞いてみてわかったこと
##### 現場ではVue.js V2系が多いのか
多いがゆくゆくはV3系に変わっていく

##### Vue.js V3を学ぶべきか
余力があればそれに越したことはなさそうだが変更点が結構多いこともあり、V2の方が書籍などの学習を活かせるため恩恵を受けやすいためV2でも良さそう

##### Vuetifyについて
現場によってはVuetifyを導入しているケースもよくあり、コンポーネントも豊富のため経験としても触ってみて損はない


## 先輩と話してわかったこと
以下はPF開発初期までに決めておいた方が良い(詳細は調べて検討！)
・SPAやSSRで実装するか。
・Vue.jsを使用するか
・CSSフレームワークの選定
 
### 最後に
RUNTEQでもよく言われますがドキュメントも積極的に読んでいきましょう。
教えてくださってありがとうございました。
Vue.jsの学習、頑張りましょう！！！！
Blender2.8以降で2.7x以前のデータを開いたときに非表示レイヤーを再表示できない問題の解消

## 発生した問題
Blender2.8以降で2.7x以前のデータを開くと、非表示にしていたレイヤーのデータが、どこを触っても表示されなくなってしまった。

2.7xでは以下のようにレイヤーを管理していた

![スクリーンショット 2021-09-26 16.04.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/18caeee7-bd6e-d75e-e7ff-b1819e58958a.png)

このデータを2.8以降で読み込ませると、非表示レイヤーにあったデータがどこを触っても表示できなくなった。

![スクリーンショット 2021-09-26 16.01.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/75ee89d4-c1c3-364c-b8fc-6efb7eabb6f5.png)

## 解決方法
グレーアウトしているデータを右クリックし、「ビューポートで有効」と「レンダーで有効」をクリックすることで表示させることができる。

![スクリーンショット 2021-09-26 16.21.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/1187ac96-927a-3c61-b6d0-f73e028e5bcb.png)

また、MacのTrackpadでの「ctrl + クリック」による右クリックだと、右クリックメニューが表示されなかった。２本指でのクリック([参考](https://developer.blender.org/T69139#762220))や、マウスによる右クリックだと表示された（これは環境と設定によるかもしれない）。


## 確認環境

- MacBook Pro (16-inch 2019)
- macOS Big Sur 11.5.2
- Blender(2.8以上) 2.92.0
- Blender(2.7x以前) 2.79b 
- トラックパッド Magic Trackpad 2 MJ2R2J/A
- マウス Logicool MX Master 2S

## 参考文献
Blender 2.83 のコレクション・ビューレイヤー操作
https://dskjal.com/blender/how-to-use-collection.html
PL/SQLの新しいFOR LOOP構文を試す(1)（Oracle Database 21c)

Oracle Database の新機能には大規模環境に対応するばかりではなく、プログラミングに関する細かい仕様の追加も含まれます。Oracle Database 21c では何十年も使われてきた PL/SQL の FOR LOOP 構文に新しいイテレータ構文が追加されました。

# 複数イテレーター
FOR LOOP 文に複数のイテレーターをカンマ（,）で区切って指定できます。最初のイテレーターが完了すると、次のイテレーターが開始されます。複数のイテレーター内の値が重なっていても問題ありません。
下記の例ではイテランドの値を 1～3 と 5～7 の２つ指定しています。 

```
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
  2    FOR i IN 1 .. 3, 5 .. 7 LOOP
  3      DBMS_OUTPUT.PUT_LINE(i);
  4    END LOOP;
  5  END;
  6  /
1
2
3
5
6
7

PL/SQLプロシージャが正常に完了しました。
```

# 逆順
イテレーターの値を逆順に出力する際には REVERSE 句を指定します。「REVERSE 5 .. 1」と記述してしまうと、ループに入らずに終了してしまいます。下記の例では 1～5 の値を逆順に指定しています。

```
SQL> BEGIN
  2    FOR i IN REVERSE 1 .. 5 LOOP
  3      DBMS_OUTPUT.PUT_LINE(i);
  4    END LOOP;
  5  END;
  6  /
5
4
3
2
1

PL/SQLプロシージャが正常に完了しました。

SQL> BEGIN
  2    FOR i IN REVERSE 5 .. 1 LOOP
  3      DBMS_OUTPUT.PUT_LINE(i);
  4    END LOOP;
  5  END;
  6  /

PL/SQLプロシージャが正常に完了しました。
```


# ステッピング
デフォルトでは FOR LOOP で指定する数値（イテランド）は「1」ずつ増加して上限まで増加します。
「BY」句に値を指定することで増分を変化させることができます。ただし BY 句に小数点を指定しただけだと整数に丸められるため、小数点を許容するデータ型を指定します。下記の例では最初に BY 句だけ指定しましたが、ループは３回で終わっています。次にデータ型としてNUMBER(5, 1)を指定し、0.5ずつイテランドを増加し、ループを６回実行しています。

```
SQL> BEGIN
  2    FOR i IN 1 .. 3 BY 0.5 LOOP
  3      DBMS_OUTPUT.PUT_LINE(i);
  4    END LOOP;
  5  END;
  6  /
1
2
3

PL/SQLプロシージャが正常に完了しました。

SQL> BEGIN
  2    FOR i NUMBER(5, 1) IN 1 .. 3 BY 0.5 LOOP
  3      DBMS_OUTPUT.PUT_LINE(i);
  4    END LOOP;
  5  END;
  6  /
1
1.5
2
2.5
3
PL/SQLプロシージャが正常に完了しました。
```

# 実行条件指定
LOOP 文に WHEN句を指定すると条件に合致した場合だけループが実行されます。下記の例では条件「MOD(i, 2) = 0」が真になる場合だけループが実行されています。

```
 SQL> BEGIN
  2    FOR i IN 1 .. 10 WHEN MOD(i, 2) = 0 LOOP
  3      DBMS_OUTPUT.PUT_LINE(i);
  4    END LOOP;
  5  END;
  6  /
2
4
6
8
10

PL/SQLプロシージャが正常に完了しました。
```

# 終了条件指定
LOOP 文に WHILE 句を指定すると、条件に一致しなくなったらループを終了します。FOR LOOP にする必要は無い気がしますが、構文としては有効です。

```
SQL> BEGIN
  2    FOR i IN 1 .. 10 WHILE i <= 5 LOOP
  3      DBMS_OUTPUT.PUT_LINE(i);
  4    END LOOP;
  5  END;
  6  /
1
2
3
4
5

PL/SQLプロシージャが正常に完了しました。
```

# 組み合わせ
上記に記載した機能は複数を組み合わせて記述できます。下記の例では複数のイテレーターと、REVERSE句、BY句を指定しています。

```
SQL> BEGIN
  2    FOR i FLOAT IN 1 .. 3, REVERSE 5 .. 7 BY 0.5 LOOP
  3      DBMS_OUTPUT.PUT_LINE(i);
  4    END LOOP;
  5  END;
  6  /
1
2
3
7
6.5
6
5.5
5

PL/SQLプロシージャが正常に完了しました。
```
AWS IOT の Device Shadow

次のページを参考にしました。
[AWS IoTのThing Shadowsを図と実行例で理解する](https://dev.classmethod.jp/articles/aws-iot-things-shadow/)

次のバージョンで確認しました。

```text
$ aws --version
aws-cli/2.2.41 Python/3.8.8 Linux/5.14.7-arch1-1 exe/x86_64.arch prompt/off
```

Thing の作成

```bash:create_thing.sh
THING="sample_sep26"
aws iot create-thing --thing-name ${THING}
```

Thing の一覧

```bash:list_things.sh
aws iot list-things | grep thingName
```

Thing の削除

```bash:delete_thing.sh
THING="sample_sep26"
aws iot delete-thing --thing-name ${THING}
```

Shadow の作成
![shadow_sep26_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a5e2af92-bece-d90d-a660-bd14eeed4b49.png)

Unnamed (classic) Shadow　を作成します。
![shadow_sep26_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/370997e1-ba72-b74b-e25f-d44769a9727e.png)

デバイスの状態が OFF であることを通知

```bash:report_off_thing.sh
THING="sample_sep26"
#
aws iot-data update-thing-shadow --thing-name ${THING} \
	--cli-binary-format raw-in-base64-out \
  --payload '{"state": {"reported" : {"led" : "off"}}}' \
  report01.json
```

デバイスの状態が ON であることを通知

```bash:report_on_thing.sh
THING="sample_sep26"
#
aws iot-data update-thing-shadow --thing-name ${THING} \
	--cli-binary-format raw-in-base64-out \
  --payload '{"state": {"reported" : {"led" : "on"}}}' \
  report02.json
```

デバイスを OFF にするように指令

```bash:command_off_thing.sh
THING="sample_sep26"
#
aws iot-data update-thing-shadow --thing-name ${THING} \
	--cli-binary-format raw-in-base64-out \
  --payload '{"state": {"desired" : {"led" : "off"}}}' \
  command01.json
```

デバイスを ON にするように指令

```bash:command_on_thing.sh
THING="sample_sep26"
#
aws iot-data update-thing-shadow --thing-name ${THING} \
	--cli-binary-format raw-in-base64-out \
  --payload '{"state": {"desired" : {"led" : "on"}}}' \
  command01.json
```

Shadow の状態を取得

```bash:get_shadow.sh
THING="sample_sep26"
#
aws iot-data get-thing-shadow --thing-name ${THING} outfile.json
```
Excelを用いたWebスクレイピングでテキストデータとして取得

はじめまして，ガンちゃんです．
Qiita初投稿です！

まず簡単に自己紹介させていただきます．
ニックネームがガンちゃん，ものづくりとアニメが大好きな大学生です．
（学生：2021年現在）
プログラミング初心者に等しいので，何卒よろしくお願いします．

##概要
最近Webスクレーピングについて勉強する機会があり，成果の一部を投稿をしました．

Excel内にスクレーピングしたいURLを保存しておき，それをスクレイピングしていきます．スクレイピングした結果は，各URLの内容がテキストファイルとして出力されます．言語はPythonを使用しています．

##引数処理
まず，スクレーピングを実施する前にExcelデータを読み込むために，コマンドライン引数を取得するようにしています．

``` 
> python hp_scraping.py List_URLs
```
3番目にある文字列が今回使用するExcelファイルの名前です．

下記にコマンドライン引数での処理を示している．

``` hp_scraping_一部.py
import sys

args = sys.argv

if len(args) < 2:
    print("Number of args is No!")
    print("Please input excel file name to args[1]!!")
    sys.exit()

excell_name = args[1]
``` 


##Excelを用いたWebスクレーピング
処理内容は下記になる．
今回スクレイピングしているのは，「body」内のテキストデータを取得している．

``` hp_scraping.py
import requests 
from bs4 import BeautifulSoup
import sys
import openpyxl

args = sys.argv

if len(args) < 2:
    print("Number of args is No!")
    print("Please input excel file name to args[1]!!")
    sys.exit()

excell_name = args[1]

# ブックを取得
book = openpyxl.load_workbook( excel_name + '.xlsx' )
# シートを取得 
sheet = book['Sheet_list']

#nameとURLの識別用の引数
num = 1

for rows in sheet.iter_rows(min_row=2):
    for cell in rows:
        if num%2 != 0:
            #出力結果を書き込む際の名前
            name = cell.value
            #print(name)
            num += 1
        elif num%2 == 0:
            #URLを取得
            url = cell.value
            if 'http' not in str(url):
                sys.exit()      
            #スクレイピング実行
            html = requests.get(url)
            soup = BeautifulSoup(html.content, "html.parser")
            a = soup.find("body").text
            #テキストファイルに書き込む
            with open("res_" + name + ".txt", mode = 'wb') as f:
                b = a.encode('cp932', 'ignore')
                f.write(b)
            num -= 1
``` 

Excell内は下記のようになっている．
![Qiita_excell.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1893155/089bc35e-a9da-732e-ddbc-a02a2337d7d3.png)

今回スクレイピングしたURLは下記の練習用とされているものを使用させていただいております．
https://scraping-for-beginner.herokuapp.com/
https://scraping-for-beginner.herokuapp.com/ranking/


スクレイピングが行なわれた後，ファイル内では下記のように「res_名前.txt」のテキストファイルできる．
![Qiita_dir.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1893155/2f16d21a-4dd8-c58e-66f6-75cc43578e2c.png)

##最後に
スクレイピングしたURK内のテキストデータ内に改行が加わってしまっています．改善が必要となっています．また，「クローリング」というWebサイトを巡回する方法もあるので，このような方法をとる必要はないかもしれません．



##参考リンク
######スクレイピング（BeautifulSoup）
10分で理解する Beautiful Soup：
https://qiita.com/Chanmoro/items/db51658b073acddea4ac
PythonでHTMLを解析してデータ収集してみる？ スクレイピングが最初からわかる『Python 2年生』：
https://codezine.jp/article/detail/12230
######コマンドライン引数
Pythonでコマンドライン引数を受け取る：
https://qiita.com/taashi/items/07bf75201a074e208ae5
######Excel処理
Python】Excelのセル範囲（数値・記号）を取得する：
https://pg-chain.com/python-excel-cell-range
PythonでExcelファイル（xlsx）を読み書きするopenpyxlの使い方：
https://note.nkmk.me/python-openpyxl-usage/
openpyxl による Excelファイル操作方法のまとめ：
https://gammasoft.jp/support/how-to-use-openpyxl-for-excel-file/
【tdmelodic】/tmpでエラーが出たので対処してみた

###### ※2021/10/26現在、公式ドキュメントにて修正済み

#はじめに
音声ボットに人間味を与える手段の一つとして、抑揚を与えるアクセント推定というものがある。
今回、日本語のアクセント推定を行う[tdmelodic](https://tdmelodic.readthedocs.io/ja/latest/index.html)を導入する際に起こったエラーについて自分が行った対処方法を記載していく。


#実行環境
- mac OS X
- Big Sur 11.5.2

#エラー内容
- [UniDic ユーザー向け辞書生成ページ](https://tdmelodic.readthedocs.io/ja/latest/pages/unidic-dicgen.html)にて、以下のコード実行の際にエラーが発生
![スクリーンショット 2021-09-26 16.04.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1789548/1a9943b9-d494-e7d1-f6f5-3d391bdbe278.png)

原因は不明だが、/tmpにアクセス出来ない模様。

```
--output /tmp/neologd_modified.csv
```

outputする先を、実行しているフォルダに変更することで成功。
（実行フォルダは{WORKDIR}で表す）

```
--output /${WORKDIR}/neologd_modified.csv
```

#おわりに
` /tmp` を認識させることさえ出来れば問題はないのだが、出来ない時のための応急処置を示した。
今回エラーが発生したページの他にも、コード内に` /tmp` が含まれている箇所でエラーが発生したので、同様の方法で実行フォルダを参照先or参照元にして試していただきたい。
PyMuPDFでページの内容をJSON形式で抜き出そうとしたら"Object of type bytes is not JSON serializable"って出たので直した

文字のフォントとかの指定を取る必要があったのでJSON形式で抜き出してみました。
んが、"Object of type bytes is not JSON serializable"ってでるので、何とか直してみたのが以下のコード。
default=format_for_jsonと指定しているのがミソ。

```Python
import base64
import json
import fitz

def format_for_json(obj):
    encoded = base64.b64encode(obj)
    decoded = encoded.decode('utf-8')
    return decoded

doc = fitz.open("hogefuga.pdf")
for page in doc:
    page_dic = page.get_text("dict")
    json_test = json.dumps(page_dic, ensure_ascii=False, default=format_for_json)
    print(json_test)
```

# 参考
この２つのページを組み合わせました
https://www.yoheim.net/blog.php?q=20170703
https://qiita.com/Haaamaaaaa/items/54bdb372d0e58a976a55
【React】2つの領域をもつボタンを実装する

<!-- =========================================================== -->
# 概要
<!-- =========================================================== -->

**2つの領域をもち、ホバーするとその領域が広がるボタン**を実装します。

![output(video-cutter-js.com) (6).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/c874e588-1b85-bd0c-6974-ebde24caf457.gif)

:::note info
本記事は、以下の動画をReactに変換したものです。（ほぼ写経です）
:::

https://www.youtube.com/watch?v=bdPXAl2mRTA

:::note info
スタイリングには、<strong>emotion/css</strong>（CSS in JS）を使用しています。
:::

https://emotion.sh/docs/@emotion/css

https://qiita.com/nemutas/items/dac73aa645f27cde92cd

<!-- =========================================================== -->
# 実装
<!-- =========================================================== -->
```.tsx
import React, { VFC } from 'react';
import { css } from '@emotion/css';

export const ClipPathButton: VFC = () => {
	return (
		<div className={styles.container}>
			<a className={styles.link} href="/">
				<span className={styles.text}>Button</span>
				<span className={styles.text}>Button</span>
			</a>
		</div>
	)
}

const styles = {
	container: css`
		position: relative;
		width: 100vw;
		height: 100vh;
		display: flex;
		justify-content: center;
		align-items: center;
		background-color: #43345d;
	`,
	link: css`
		position: relative;
		display: inline-flex;
		width: 250px;
		height: 80px;
		box-shadow: 0 5px 25px rgba(0, 0, 0, 0.25);
	`,
	text: css`
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		color: #fff;
		background-color: #6c4ba5;
		display: flex;
		justify-content: center;
		align-items: center;
		text-transform: uppercase;
		letter-spacing: 2px;
		font-size: 2rem;

		&:nth-child(2) {
			color: #6c4ba5;
			background-color: #fff;
			overflow: hidden;
			z-index: 2;
			transition: 0.5s;
			clip-path: polygon(60% 0, 100% 0%, 100% 100%, 60% 100%, 40% 50%);
		}
		&:nth-child(2):hover {
			clip-path: polygon(0 0, 100% 0%, 100% 100%, 0 100%, 0 50%);
		}
		&:nth-child(1):hover ~ :nth-child(2) {
			clip-path: polygon(100% 0, 100% 0%, 100% 100%, 100% 100%, 100% 50%);
		}
	`
}
```
* 背面と前面にColorだけ違う同じテキストを用意します。**clip-path**を使用して、その表示領域を調整しています。

https://developer.mozilla.org/ja/docs/Web/CSS/clip-path

https://bennettfeely.com/clippy/

* **一般兄弟結合子（~）**を使用して、背面のテキスト領域がhoverされたときに、前面のテキスト領域の**clip-path**が右端に寄るようにしています。

https://developer.mozilla.org/ja/docs/Web/CSS/General_sibling_combinator
MVCモデル

##はじめに
SIerに入社して、早半年が経ちました。新人研修時にWebアプリケーションのアーキテクチャとしてMVCモデルを学ぶ機会がありました。最近になって、そのMVCモデルを振り返ることがあったので、今現在の自分のMVCについての考えをまとめてみたいと思います。

#MVCモデル
システムを構成する部品の役割をModel,View,Controllerという3つに明確にして、開発効率の向上・保守性の向上を目指したシステムの設計モデル。OOP向けのアーキテクチャ。

##　Model
アプリケーションにおけるデータの保持や業務処理を実行する部品。
中でも
データの保持を行う部品を、エンティティ（RDBの表の一行と対応）やDTO（複数のエンティティからプロパティを取得したもの）と呼び、
DBにアクセスし表のCRUD操作を行う部品をDAO（データアクセスオブジェクト）と呼び、
業務処理の流れを記述する部品を（業務）LogicまたはServiceと呼ぶ。

##　View
ユーザーとシステムのインターフェースとして提供され、データの入力・表示画面となる部品。具体的には、JSPやHTMLのこと。

##　Controller
アプリケーションの動作を制御する部品。クライアントとからのリクエストを受け付けて、Modelに属する業務Logicを起動し、その結果をViewに引き渡す役割を果たす。
この部品をサーブレットと呼ぶ。

##　疑問点
**・DAOとRepositoryの違いって？**
Spring Bootでは、Repositroyパッケージに、CRUD用のインターフェースを用意していたので気になった。DAOパターンとRepositoryパターンというデザインパターンがあるらしい。

**・Modelは、OOP的なアーキテクチャなのか？**
Model中に、データとロジックがまとめられているのは、OOP向けのアーキテクチャのためらしい。確かに、Modelの中に、データとロジックがまとまっているが、実情は、DTOやServiceとしてデータとロジックは分離されているように見える。これは、OOP的なアーキテクチャなのか？
/scripts 記述ガイド

リポジトリの便利スクリプトを `/scripts` に入れるときのテクニックを紹介します。

## shebang を書く

```sh
#!/bin/bash
```

1 行目をこのようにするとで、起動するシェルを Bash に揃えることができます。Linux を対象にするときは Bash をターゲットに書くことをオススメします。 Mac やコンテナ内で動かす可能性がある場合は `/bin/sh` を対象にすることもあります。

他に `#!/usr/bin/env python3` も使うことがあります。依存が 1 つ増えることになるのでチームの状況を見ながら選択します。

## カレントディレクトリを揃える

```sh
# 起動したファイルの場所 1 つ上（/scripts ならリポジトリのルート）に移動する
cd $(dirname $0)/..
```

shebang の次にこの行を書くことが多いです。 README に「○○に移動してから起動してください」と書くより優しいスクリプトになります。

## 標準エラー出力にログ

標準出力には結果を出力して、途中のデバッグログやエラーログは標準エラー出力に出すようにすることで、結果をパイプで繋いで再利用できるように保ちましょう。

## インクルードガード

複数のスクリプトで共通して利用するなら `/scripts/lib` あたりにまとめると良いでしょう。 source で取り込んで利用します。ただし、多重に取り込まれても良いように、先頭で 2 回目以降の実行は拒否します。

```
[[ -n "$__LOGGER_SH" ]] && return || readonly __LOGGER_SH=1
```

例えば、簡易的なロガーを作るとすると下記のようになります。

```
#!/bin/bash
[[ -n "$__LOGGER_SH" ]] && return || readonly __LOGGER_SH=1

# 0: DEBUG
# 1: INFO
# 2: WARN
# 3: ERROR
declare -r LOG_LEVEL=${LOG_LEVEL:-1}

log_debug() {
    if (( $LOG_LEVEL <= 0 )); then
        echo -e "\033[1;40m DEBUG \033[00m $*"
    fi
}

log_info() {
    if (( $LOG_LEVEL <= 1 )); then
        echo -e "\033[1;44m INFO \033[00m $*"
    fi
}

log_warn() {
    if (( $LOG_LEVEL <= 2 )); then
        echo -e "\033[1;43m WARN \033[00m $*"
    fi
}

log_error() {
    if (( $LOG_LEVEL <= 3 )); then
        echo -e "\033[1;41m ERROR \033[00m $*"
    fi
}
```

## 大規模化しそうなら別プロジェクトに切り出す

シェルスクリプトは可読性が低くなりやすいので、複雑化する気配を感じたら適切にツールのプロジェクトとして切り出しましょう。
色々できる環境を作る

自宅にあるwindowsPCにクラウド環境を触る環境を作ります。

# 下記を導入して得られる環境
・linux環境
・コマンドラインで各種クラウド(AWS/GCP/Azure)を操作可能

## windowsでlinuxを使う
https://qiita.com/Aruneko/items/c79810b0b015bebf30bb

## kubectlの導入
https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/

## awscliの導入
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html
バージョンは2を入れましょう。

## eksctlの導入
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eksctl.html

## gcloudの導入
https://cloud.google.com/sdk/gcloud?hl=ja
pathを通すこと

## azコマンドの導入
https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-linux?pivots=apt&view=azure-cli-latest

## おまけ
### terraform
https://docs.uipath.com/installation-and-upgrade/lang-ja/docs/installing-terraform

terraformはインフラ環境の構築の自動化や管理を行うツールです。terraformで作成した環境は基本的に削除/再作成がローコストで行えるためdevopsが流行っている現状に非常にマッチしています。
AWS認定 ソリューションアーキテクト-プロフェッショナル 合格の流れ 1

## 概要
AWS認定 ソリューションアーキテクト-プロフェッショナルに無事合格できたときの内容のまとめ
短期間での集中は趣味ではないので気長に勉強するパターンとして挙げてみます。本格的に勉強したのは2020年4月？あたりからスタートして2021年8月30日に取得しました。
(模擬試験だけは2019年の年末に受けていました)
今回は概要だけで詳細は後日また別途記事にまとめようかと思います

## 前提条件など
* [前回の記事](https://qiita.com/dmikita/items/93a3d93ac91fb3c58641) の条件とあまり変わらず

## 資格取得のきっかけ
* ソリューションアーキテクトアソシエイトを取得したので次の資格として挑戦
    * 会社の方針というのもありましたが・・・


## 勉強方法

### 勉強から受験の流れ
1. AWS Innovate のプロフェッショナルの対策講座を受講 (2019年だったかなと)
1. 対策講座受講の特典を使って模擬試験を無料で実施
    * この段階で60%くらいでした
1. AWSの無料のデジタルトレーニングを受講
1. Udemyの模擬試験を実施して１回目で時間切れを味わい足元を固めることに方針を変更
1. Udemyの[英語の対策講座](https://www.udemy.com/course/aws-solutions-architect-professional/)を受講
    * 後述でも参考にしてますがこちらの講座の資料はいろいろまとまっていて役に立ちました
1. 並行して[AWSのBlackbelt](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)で関係することろを確認
1. 以下の参考書を購入して熟読
    1. [AWS認定ソリューションアーキテクト-プロフェッショナル ~試験特性から導き出した演習問題と詳細解説](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB-%E8%A9%A6%E9%A8%93%E7%89%B9%E6%80%A7%E3%81%8B%E3%82%89%E5%B0%8E%E3%81%8D%E5%87%BA%E3%81%97%E3%81%9F%E6%BC%94%E7%BF%92%E5%95%8F%E9%A1%8C%E3%81%A8%E8%A9%B3%E7%B4%B0%E8%A7%A3%E8%AA%AC-%E5%B9%B3%E5%B1%B1-%E6%AF%85/dp/4865942483/ref=asc_df_4865942483/?tag=jpgo-22&linkCode=df0&hvadid=342428724851&hvpos=&hvnetw=g&hvrand=17253666351252475668&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009342&hvtargid=pla-919621259218&psc=1&th=1&psc=1)
    1. [要点整理から攻略する『AWS認定 セキュリティ-専門知識』](https://www.amazon.co.jp/%E8%A6%81%E7%82%B9%E6%95%B4%E7%90%86%E3%81%8B%E3%82%89%E6%94%BB%E7%95%A5%E3%81%99%E3%82%8B%E3%80%8EAWS%E8%AA%8D%E5%AE%9A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98%E3%80%8F-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4839970947/ref=pd_bxgy_1/358-6266410-3157208?pd_rd_w=5WP7N&pf_rd_p=d8f6e0ab-48ef-4eca-99d5-60d97e927468&pf_rd_r=E3C3PW9HMMZFCVABHK7P&pd_rd_r=c2b79738-570f-40d0-bb2c-14e5b19be539&pd_rd_wg=qDerD&pd_rd_i=4839970947&psc=1)
    1. [要点整理から攻略する『AWS認定 データベース-専門知識』](https://www.amazon.co.jp/%E8%A6%81%E7%82%B9%E6%95%B4%E7%90%86%E3%81%8B%E3%82%89%E6%94%BB%E7%95%A5%E3%81%99%E3%82%8B%E3%80%8EAWS%E8%AA%8D%E5%AE%9A-%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9-%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98%E3%80%8F-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4839975078/ref=pd_bxgy_img_2/358-6266410-3157208?pd_rd_w=ImHLS&pf_rd_p=d8f6e0ab-48ef-4eca-99d5-60d97e927468&pf_rd_r=2R3AHCGMRQ57GABDVHZQ&pd_rd_r=98204e7b-16ae-4fba-bb22-d8706989ea77&pd_rd_wg=jpNce&pd_rd_i=4839975078&psc=1)
1. ソリューションアーキテクトプロフェッショナルの参考書を読み終わった段階でUdemyの模擬試験に挑戦(全体で５回分あったので３回分を対象に実施)→間違った部分の再確認して再挑戦２回ほど実施
1. 点数が50%くらいから上がらないが問題文が細かすぎるように感じたので模擬試験はいったん停止
1. Udemyの英語の対策講座の資料を確認
1. 本試験という形で実施しました
RESTful API Design Pattern

RESTful API を定義するときのパターンを列挙してみた。パターン名は別に一般用語というわけではないけど、考えるときの参考になるかも。

## Resource Pattern

- Collection & Member Resource
    - `POST /users` で追加、 `GET /users` で一覧・検索、 `GET /users/{user_id}` 取得、 `PUT /users/{user_id}` `DELETE /users/{user_id}`
- Partial Update
    - JSON Merge Patch
    - JSON Patch
    - Field Resource
        - `/users/{user_id}/name` のようにして一部を編集する
- Tree Resource
    - `/tree/{...path}`
- Implicit Resource
    - `/emails`:「自分の」ということを明示しなくて良い
- Secondary Index
    - 同一のリソースを別の体系で参照できるようにする
- Batch Task Resource
    - 作成で開始、取得で状態を返して、削除で中断する
- RPC POST
    - Sign In などの RPC 的スタイル
- Meta Resource
    - メタ情報を返す
    - `/version` で API Server のバージョンを返す
    - `/api` で OpenAPI の JSON を返す

## URL Pattern

- Major Version
    - `/{ver}/...` のように URL にバージョンを含める
- Tuple ID
    - `/earth/{latitude},{longitude}` のように座標などの二次元の情報を表す
    - `,`, `;` とかが使える
- Temporary URL
    - 画像などの一時的な URL を生成して返すパターン

## Query Pattern

- `q` Search Query
- Pagination
    - Cursor
    - Page Index
    - Limit & Offset
- Select field
    - GraphQL

## Header Pattern

- Last-Modified Cache
- ETag Cache
- Expire Cache
- Optimistic Concurrency Control
    - 読んだ時の Hash や時刻を更新時にチェックすることで編集の衝突を検知する
- Content Negotiation
- Link Header Pagination

## Response Pattern

- Async Accept
- 404 to Hide
    - 隠すための 404 エラー
- RFC 7807 Problem
    - Problem Object を返す
- Application Status
    - HTTP Status はネットワーク用途のみに使用し、アプリのステータスコードを Response に含める
    - HTTP は 200（プロキシ・アプリは処理した）、 Response は 404（アプリで無いとわかった）
- Envelope Object
    - 将来の拡張のために Array は直接返さずに Object で包む
    - 例えばページネーション情報とかが付いたりする
paramiko使って多段接続でSFTP

# paramiko

paramikoは、Pythonのライブラリで、SSH接続やSFTPなどができるもののようです。
[http://www.paramiko.org/]()

インストールは、`pip`で簡単にできました。

# 多段ではない普通のSFTP接続

「paramiko　SFTP」で検索すると、ほとんどの先人たちは、以下のように接続を行っています。

```python
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
key = paramiko.RSAKey.from_private_key_file("id_rsa", password="passphrase")
client.connect(
    "hostname",
    port=22,
    username="hoge",
    pkey=key
)
sftp = client.open_sftp()
```

参考：
[https://qiita.com/NAKA_G/items/eb6061884416209047e8]()
[http://trelab.info/python/python%E3%81%A7ssh%E6%8E%A5%E7%B6%9A%E3%82%92%E5%85%AC%E9%96%8B%E9%8D%B5%E8%AA%8D%E8%A8%BC%E3%80%81%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E8%AA%8D%E8%A8%BC%E3%81%A7%E8%A1%8C%E3%81%86%E6%96%B9%E6%B3%95/]()

あとは、`sftp`の`put`や`get`メソッドを使って、ファイルのやり取りができます。  

# 多段接続その１：ProxyCommandを使う方法

多段SSH接続するときに良く使われるProxyCommandをparamikoでも使えるようです。

```python
import paramiko
proxy = paramiko.ProxyCommand("ssh -i id_rsa.fumidai hoge@fumidai -p 22 nc hostname 22")
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
key = paramiko.RSAKey.from_private_key_file("id_rsa", password="passphrase")
client.connect(
    "hostname",
    port=22,
    username="hoge",
    pkey=key,
    sock=proxy
)
sftp = client.open_sftp()
```

二行目で、ncコマンドを使って、通信を踏み台サーバー経由で目的のサーバーにプロキシさせています。  
ncコマンドは使ったことなかったですが、多段SSH接続でsshコマンドの-Wオプションが使われるようになる前は、ProxyCommandはこのように指定していたようです。知りませんでした。

このやり方は分かりやすくて良いのですが、`id_rsa.fumidai`にパスフレーズが設定されていると、対話式でなければ実行できないという欠点があります。

ちなみに、同じことを`paramiko.SSHClient`を使わずに実現することもできるようです。

```python
import paramiko
proxy = paramiko.ProxyCommand("ssh -i id_rsa.fumidai hoge@fumidai -p 22 nc hostname 22")
t = paramiko.Transport(proxy)
key = paramiko.RSAKey.from_private_key_file("id_rsa", password="passphrase")
t.connect(username="hoge", pkey=key)
sftp = paramiko.SFPTClient.from_transport(t)
```

こっちの方が、一行だけ短いですね。（どうでもいいか。）  
なお、`paramiko.Transport`は、何かエラーを起こすと、そこでパイプが切れるようで、例えば、`t.connect`を呼び出すとProken Pipeとなりました。対話型であれこれ試すときは、ご注意ください。

# 多段接続その２：ProxyCommandを使わない方法

Pythonコード上には、コマンドを書かなくても同じようなことができます。

```python
gateway = paramiko.SSHClient()
gateway.set_missing_host_key_policy(paramiko.AutoAddPolicy)
key_fumidai = paramiko.RSAKey.from_private_key_file("id_rsa.fumidai", password="passphrase")
gateway.connect(hostname="fumidai", username="hoge", port=22, pkey=key_fumidai)
sock = gateway.get_transport().open_channel(
    "direct-tcpip", ("hostname", 22), ("", 22)
)
t = paramiko.Transport(sock)
key = paramiko.RSAKey.from_private_key_file("id_rsa", password="passphrase")
t.connect(username="hoge", pkey=key)
sftp = paramiko.SFPTClient.from_transport(t)
```

無事、パスワード付きの秘密鍵でも対話無しに実行できるコードになりました。
SP3222Eを使ったレベルコンバーター

かなり前の秋月電子の正月ジャンク袋に入っていたSipex SP3222Eを使ったレベルコンバーターを作ってみました。おそらくディスコン商品の処分品です。

このパーツはMAX3222の互換品と思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/54fe1316-380d-5906-7b51-07c291415000.png)

![IMG_20210926_144915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d65d41b5-fe18-4117-cc48-d588b0be2d36.jpeg)

結線はこんな感じになってます。

![SP3222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/bf5d264f-0919-4cdf-c150-b0d2fb7e71ab.png)

データーシートでは電解コンデンサーが指定されていますが、付属のチップタイプのセラコンを使いました。

|DSUB 25Pin|SP3222E
|:--|:--|
|3|17|
|2|16|
|7|19|

4,5と6,8,20を結線しました。

基板はAitendoのはんだ付け練習用基板を切った物です。

ストックにあったので使いましたが、MAXとかのモジュールになってるものを買ったほうが良いと思います。
HamlでBootstrapの属性を書くときにUnbalanced brackets error発生




###◆問題発生

```
.modal.fade{id: "exampleModal", tabindex: "-1", role: "dialog", aria-labelledby:  "exampleModalLabel", aria-hidden: "true"}
```
Bootstrapのモーダルを使おうと思ったら、属性を指定するところで

```
Haml::SyntaxError in Posts#show
Unbalanced brackets.
```
というエラーが出ました。
どうやらこの部分でエラーが出てしまっていたようです。

```
{... aria-labelledby: "exampleModalLabel", aria-hidden: "true"}
```

###◆Rubyではキーにハイフンが使えない


キーにハイフンが入っているとシンボルとして認識されないため、文字列に変換してあげる必要があります。
これはHamlの文法に限りません。

以下のように記述することで解決しました。

```
{... "aria-labelledby": "exampleModalLabel", "aria-hidden": "true"}
```

####◆参考
  - 『プロを目指す人のためのruby入門』(著：伊藤 淳一)
  - https://github.com/yochiyochirb/meetups/issues/384
iPad Pythonista 3：写真をリサイズするプログラム

(2021.09.26)


# はじめに
M1 iPad Pro 12.9-inch を買った。メインで使っている M1 MacBook Air よりも高価なので、それよりも働いてもらわなくてはならない。しかし、iPad では Python を Macと同等には使えない（ライブラリやアプリの安定性などのため）ので、せめてブログの更新ぐらいは iPad Pro でやろうと思った。 この場合、テキストを打ち込むくらいならどうにでもなるのであるが、iPad の標準機能では写真のリサイズができない。そこで iPad アプリである Pythonista 3 で画像サイズを変更するプログラムを作った。このプログラムではピクセルの横サイズは 800 に固定している。

この文書は、iPad Pro で作成しているが、MacBook Air と接続した 27-inch display を用いながらの文書作成と比べると、やはり窮屈な気がする。しかしながら、iPad では、文字(表示領域)の拡大などは片手でスッとできるので、慣れによっては快適になるかもしれない。


# 使い方
使い方は以下の通り。

+ リサイズしたい写真は Files アプリの中に適当なフォルダを作成しそこにコピーしておく。
+ Pythonista 3 と Files を split view で開く。
+ Files アプリから写真が保存されているフォルダを選択し写真を見て表示。
+ 共有メニューのアイコン (四角に上矢印) を開き、Run Pythonista Script => Edit Script => プログラム (この場合 py_resize.py) を選択して実行。
+ 実行結果として、プログラムが格納されている Pythonista のフォルダにリサイズされた写真が保存される。ファイル名は、元の名前の前に ‘800_’ がつき、拡張子は ’jpg’ となっているはず。
+ Pythonista でリサイズされた写真を選択肢、Open in… を選択し、Save to Files で保存したいフォルダを選択肢実行。


# 写真を回転
写真を回転させたい時は、Files アプリの機能を使う。 写真の上で右クリック (長押し) ・メニューを表示し、回転(Rotate Left or Rotate Right) を選択•実行すれば良い。


# 写真事例

iPhone SEで撮った写真を、このプログラムを使ってリサイズしたもの。 iPad Pro 12.9-inch で split view。左は Pythonista 3、右は Files の画面。 MacBook Airは開いていない！ 

![800_IMG_0072.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129300/be622325-4774-e75d-0435-7cffd6af3f10.jpeg)



# プログラム（py_resize.py）
```python
mport appex
import Image
import os

def main():

    if not appex.is_running_extension():
        print('Running in Pythonista app, using test image...')
        img = Image.open('IMG_0001.JPG')
        fpath= 'current'
    else:
        img = appex.get_image()
        fpath=appex.get_file_path()
    if img:
        # TODO: Your own logic here...
        print(fpath)
        print('(original)',img.format)
        print('(original)',img.size)
        fname=os.path.splitext(os.path.basename(fpath))[0]
        fw='800_'+fname+'.jpg'
        print(fw)
        width=800
        height=int(float(width)/float(img.size[0])*float(img.size[1]))
        img.thumbnail((width, height), Image.ANTIALIAS)
        img.save(fw, 'JPEG', quality=100, optimize=True)
        img=Image.open(fw)
        print( '(changed)',img.format)
        print('(changed)',img.size)

    else:
        print('No input image found')

if __name__ == '__main__':
    main()
```

以　上
【React】波紋が広がるボタンを実装する

<!-- ================================================================ -->
# 概要
<!-- ================================================================ -->
**ホバーするとマウス位置から波紋が広がるボタン**を実装します。
CSS in JSとして、[**emotion/css**](https://emotion.sh/docs/@emotion/css)を使用します。

![output(video-cutter-js.com) (5).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/9d80ccd6-fe0c-369e-6ef5-d429dbc8e69d.gif)

:::note info
本記事は、以下の動画をReactに変換したものです。（ほぼ写経です）
:::

https://www.youtube.com/watch?v=WOSaNbpHNqU

:::note info
emotion/css の使い方をおおまかに知りたい方は、以下を参照してください。
:::

https://qiita.com/nemutas/items/dac73aa645f27cde92cd

<!-- ================================================================ -->
# 実装
<!-- ================================================================ -->
```.tsx
import React, { useRef, VFC } from 'react';
import { css } from '@emotion/css';

export const ButtonRipple: VFC = () => {
	const btnRef = useRef<HTMLAnchorElement>(null)

	const mousemoveHandler = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
		const x = e.pageX - btnRef.current!.offsetLeft
		const y = e.pageY - btnRef.current!.offsetTop
		btnRef.current!.style.setProperty('--x', x + 'px')
		btnRef.current!.style.setProperty('--y', y + 'px')
	}

	return (
		<div className={styles.container}>
			<a ref={btnRef} className={styles.btn} href="/" onMouseMove={mousemoveHandler}>
				<span className={styles.text}>Button</span>
			</a>
		</div>
	)
}

const styles = {
	container: css`
		position: relative;
		width: 100vw;
		height: 100vh;
		display: flex;
		justify-content: center;
		align-items: center;
		background-color: #222;
	`,
	btn: css`
		position: relative;
		display: inline-flex;
		padding: 1.5em 5em;
		background-color: #363636;
		text-decoration: none;
		letter-spacing: 1px;
		overflow: hidden;

		&::before {
			content: '';
			position: absolute;
			top: var(--y);
			left: var(--x);
			transform: translate(-50%, -50%);
			width: 0;
			height: 0;
			border-radius: 50%;
			background-color: #2196f3;
			transition: width 0.5s, height 0.5s;
		}
		&:hover::before {
			width: 300px;
			height: 300px;
		}
	`,
	text: css`
		position: relative;
		color: #fff;
		font-size: 2rem;
		z-index: 1;
	`
}
```
**onMouseMove**イベントで、`setProperty`を使って、CSS変数（--x・--y）にマウス位置をセットしています。

https://developer.mozilla.org/ja/docs/Web/API/CSSStyleDeclaration/setProperty

https://developer.mozilla.org/ja/docs/Web/CSS/Using_CSS_custom_properties
ReactでSassを使いたい

# ReactでSassを使いたいとき

### 要件
reactでsassを使いたい
###解決策
1. 事前にフォルダ内にある、cssファイルの拡張子を```scss```に変更する
2. index.jsで読み込んでいる``index.css``の拡張子を``scss``に変更する
3. 再度`yarn start`  する  
※もし「2」の時点で**Cannot find module 'sass'**というエラーがでたら以下のコマンドを実行してsassをインストールする  
`npm install sass`<br>
下図の赤枠部分を触りますので、参考になればなと思います。
![スクリーンショット 2021-09-26 14.29.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1103633/3b3f27c1-a1ce-193d-0395-1db7215e39d1.png)


以上
terraformのvscodeでの設定

vscodeでterraformの設定をしたときのメモです。

## 参考

https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform

## 設定

settings.jsonに以下を書きます。

```settings.json
    // 追記
    "[terraform]": {
        "editor.defaultFormatter": "hashicorp.terraform",
        "editor.formatOnSave": true
    }
```

これで = を揃えてくれたり、インデントのときのスペースを2に統一するなどをやってくれます。
S3バケットのパブリックアクセス

#1. 概要
AWSのS3クラウドストレージへのアクセスは３つの方法でコントロール。

ACL
BucketPolicy
IAM Role

これらの制御の評価は順番があり、コントロールをよく理解ない内に意図せぬバケットの公開のリスクがある。特に開発やテスト段階では、制御ポリシーを良く計画しないうちに、バケットのPublic Accessを解除された場合は少なくないである（下記図をご参照）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1657390/04ba9eb2-737d-1f13-70a6-893d241c6741.png)

本文はPublic AccessをBlockする前提で、BucketPolicyの設定によるS3バケットへのアクセスを紹介する。

#2. 対処法

“Amazon S3 ストレージへのパブリックアクセスのブロック”のオフィシャルサイトでは、バケットポリシーに関してパブリックの意味について以下のように説明してある。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/access-control-block-public-access.html#access-control-block-public-access-policy-status

バケットポリシーを評価する場合、Amazon S3 はまずポリシーがパブリックであると想定します。その後、ポリシーを評価して非パブリックとしての資格があるかどうかを判断します。非パブリックと見なすには、バケットポリシーで、次のうち 1 つ以上の固定値 (ワイルドカードを含まない値) にのみアクセスを許可する必要があります。

aws:SourceIp を使用した一連のクラスレスドメイン間ルーティング (CIDR)。CIDR の詳細については、RFC Editor のウェブサイトで RFC 4632 を参照してください。
AWS プリンシパル、ユーザー、ロール、またはサービスプリンシパル (例: aws:PrincipalOrgID)
aws:SourceArn
aws:SourceVpc
aws:SourceVpce
aws:SourceOwner
aws:SourceAccount
s3:x-amz-server-side-encryption-aws-kms-key-id
aws:userid、「」パターンの外側AROLEID:
s3:DataAccessPointArn
s3:DataAccessPointAccount

要するに、以上項目の内一つ以上を固定値に設定しておけば、当該アクセスは非パブリックと認める。ただし、ポリシーの記述には”Condition”とする必要である。
本文は"aws:SourceVpce": "vpce-01fxxx41xxx74dxxx"、決めているVPCのエンドポイントからのアクセスを条件としてバケットポリシーの設定と動作確認をする。

#3. 動作確認

上記図の４つのPublic Accessポリシーを全部ONにした上、BucketPolicyを下記のように設定する。

```bucketpolicy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddVpceCondition",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::xxxx-dev-xxxx-batch-s3",
                "arn:aws:s3:::xxxx-dev-xxxx-batch-s3/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:SourceVpce": "vpce-xxxxxxxxxxxx"
                }
            }
        }
    ]
}
```

因みに、上記設定したResourceの”arn:aws:s3:::xxxx-xxx-xxxx-batch-s3”はバケット自体とそのSubresource(lifecycle, website, versioning, policy and acl, cors, object ownership, logging)、”arn:aws:s3:::xxxx-xxx-xxxx-batch-s3/*”はバケットObjectのResourceである。Object Resourceはacl、restoreを意味する（作者はbucketに作成されたフォルダもObjectのResourceと思う。）

以上のBucketPolicy設定でS3パケットにアクセスできたことを下記図ご参照。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1657390/bcc9c148-8bf4-efaa-c957-eb94b46bd3ac.png)

#4. まとめ
本文S3　BucketPolicyのConditionに固定値を設定するにより、アクセスを非Public Accessと扱われて、パケットのPublicAccessをBlock ONにしてもアクセスできたことを実装できた。ご実務に参照になれば幸いである。
5 Hacks to Get Rid of Spam Emails Eating Up Your Inbox

Are you facing spam email attacks on your email inbox? Welcome to the team. Almost four out of every five people receive hundreds of spams emails every day. When you respond to one of these corporate emails or email lists that you have never signed up for, you become the spammers' next most likely target or campaign. Spam can be both irritating and dangerous at times. So, here are five tips you can follow to get rid of such spam emails in the future. 

1. Never Respond to a Spam Email.
The first piece of advice would be to never respond to an unknown email, no matter what. Yes, sometimes it's tempting to respond to a spam email with a furious rant, but the moment you respond, the spammer knows that your account is active, you may result in getting spam at a storm speed. 
The famous British stand-up comedian <a href="https://veitch.me/"><b><i>James Veitch</i></b></a> shared a hilarious experience of spam emails and how just a casual reply led to a week-long conversation with the spammer. Watch his video 'This is what happens when you reply to spam email' to experience the hilarious conversation from the man himself. 

2. Don't Click on Any Unknown Links.
The offers and deals you get from unknown emails that cannot be traced is a 100% scam. Don't ever click on any links to buy anything or even the unsubscribe button thinking you are putting an end to the issue. Well, no, you are inviting more such spam, as the spammer now knows you are responding to their emails. [James Veitch](https://comedianjamesveitch.blogspot.com/), once again, is a great illustration of this. He explained in his video how he tried to unsubscribe for days, but continued getting more spam.

3. Use An Alternative Email.
Scamming has become fairly popular in today's world of the internet. You don't want to misuse your email since it contains sensitive personal information. If you must log in to any website, avoid logging in using your email ID on any unknown, suspicious websites. To keep your actual email ID safe, use another email, such as a throwaway email.

4. Set Up Email Filters.
If you are in a particular email client or app, then you must know about filters. If not, filters are used to route messages with a specific subject line or from an unknown sender to your trash folder or spam folder. Check the app's user guide to know how to use a filter more intelligently.

5. Block Spam Emails.
Blocking spam emails may sometimes lead to more spam emails, as spammers frequently utilize phony email addresses to send emails to many recipients. This stage now needs considerable attention and concentration. You should pay attention to the kind of emails you get. You may use your email client to block emails from the same email address or the same sort of email from a different email address if you see them. This will ensure that they do not end up in your email.

Try a handful of these hacks, and perhaps you'll be able to get rid of your spam pals invading your inbox
第三者によるコード生成ができるサービス（ソフトウェア）の事例

どんなアイデアや事例がありそうか個人的に想像してみました.

# プログラムの規模別
実際にあるサービスをまとめてみました.
1. OS(オペレーティングシステム)
	- Windows, Linux: C言語, Javaなどさまざまな言語を使ってプログラミングできる.
1. ローコード、ノーコードツール(GUIによるプログラミング?)
	- bubble（アプリ作成ツール）:GUIからwebサービスを作ることができる.
	- datarobot（機械学習ツール チューニング部分についてカスタマイズ可能）

1. AIによるプログラミングの自動化
	- GitHub Copilot: 関数名とコメントから関数のコードを丸ごと自動補完するAIプログラミング機能

1. プログラミング
    - ソースコードの選択部分(if文): 切り替え先を新規生成されたプログラムとみなす.
    - jinja2: Python Flaskなどと一緒によく使われる、template作成ツール
    - bash初心者向けに、単純なlinuxコマンドをPythonで作成する（web開発のlibrary Reactにインスパイアされて作ったことがあるけど、いまは使ってない... 個人用のprivateなツールです）


# 応用先
IT業界の課題に対して、コード生成によって解決できることがないかアイデアを出してみました.

1. アプリ開発（インターフェース部分）の工数が大きい
    - 解決策(アイデア):  OSSを生成するローコードツール.  OSSを生成してくれれば、リリース方法に選択肢が生まれるため工数の膨らまない得意な場所を選べる
	
1. 技術選定が難しい
    - 解決策(アイデア):  ビジネスにおける0->1（OSの選定から、なんらかのサンプル生成まで）の自動生成

1. ロジックが流出しやすい
    - 解決策(アイデア):  システムのコア部分を分離して、独自の難読化をかける. 

# 曖昧さ回避
- 第三者: 他人, AI(確率を活用したプログラム), ルールベースのプログラム, 未来の自分)
- サービス: プログラム生成される前後で、変更の発生しないソフトウェア