OmniAICreator/Qiita-1.07M huggingface dataset:
CentOS における sudo コマンド実行許可

* CentOS7 において、一般ユーザ(ここでは testuser とする)で sudo コマンドを実行しようとすると以下のようなエラーに出くわす。

```
[testuser@centos7 ~]$ sudo hogehoge
[sudo] testuser のパスワード:
testuser は sudoers ファイル内にありません。この事象は記録・報告されます。
```

* ネットで調べればいくらでも解決法は出てくるのだけど、備忘のため書き留めておく。
今回は一般ユーザで sudo コマンドが使えるようになりさえすればいい。

* 以下、対処方法。

1. CentOS7 に root ユーザにてログイン、visudo コマンドを実施。
2. 以下の通り、sudo 許可したいユーザ(今回は testuser)を追記
(testuser... で始まる箇所)

```
## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL
testuser  ALL=(ALL)       ALL
```

* 上記実施すれば、一般ユーザ testuser にて sudo の実施可能。
* ここで書いたことは最低限のことだが、wheel というグループの概念などそれなりに深く突き詰められそうなので、機会があればまた調べてみる。
サーバーとクライアント

# 勉強の記録
サーバーとクライアント 1/24
## 勉強した内容
- tmux   コマンド　サーバーとクライアントの両方を操作できるようになる
- nc     コマンド  TCP UDPの読み書きを行う。（よくわからない！）
- telnet コマンド  リモートコンピューターにアクセスする。

## 何をベースに勉強してるか
- [N予備校 プログラミング入門](https://www.nnn.ed.nico/courses/668/chapters/9515)

## 内容の詳細
- サーバーとクライアントの通信について。

### わかったことについて
- これってもしかしてHPやアプリにアクセスしたら、毎回同じ反応が返ってくるのと同じことなのだろうか？って思ってます

### むずかしかったよ
- しいて言うなら nc

## 次回やる予定のこと
- 次回はHTTP通信についての授業だそうです。
Swift5 UserDefaultsを使ってみた

#はじめに
現在Swiftの勉強です。
UserDefaultsの使い方に毎回悩みます。
そのため、今回サンプルを用いてUserDefaultsを使い学習しました。

#環境
Xcode12.3
Swift5.3.2
macOS Catalina 10.15.4

#インスタンス生成
```swift
//インスタンス生成
let userDefaults = UserDefaults.standard
```

#UserDafaultsに値を保存(今回はInt型を保存)
```swift
 //UserDafaultsに値を保存
//forKeyに保存したい名前を付ける
  userDefaults.set(hogeNumber, forKey: "hogeIntKey")
```

#UserDafaultsから値を取り出す（今回はInt型を保存）
```swift
//UserDefaultsの値の取り出し
//先ほど付けたforKeyの名前をforKeyに入れる
 let hogeIntValue = UserDefaults.standard.integer(forKey: "hogeIntKey")
```

#補足
UserDefaultsの値を取り出す時は、型によって書き方が変わります。

#サンプル画面
![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683624/378386d9-356b-3e72-594d-a119f29b65a7.gif)

#コード全文

```ViewContoller.swift
import UIKit

class ViewController: UIViewController {
    
  
    @IBOutlet weak var hogeLabel: UILabel!
    
    let userDefaults = UserDefaults.standard
    
    //ラベルに入れる値を設定
    var hogeNumber = 100
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //ラベルに値を表示
        hogeLabel.text = String(hogeNumber)
        
        //インスタンス化
        let userDefaults = UserDefaults.standard
        
        //UserDafaultsに値を保存
         userDefaults.set(hogeNumber, forKey: "hogeIntKey")
    }
}
```

```NextViewContoller.swift
import UIKit

class NextViewController: UIViewController {
    
    @IBOutlet weak var hogeNextLabel: UILabel!
    

    override func viewDidLoad() {
        super.viewDidLoad()

        //UserDefaultsの値の取り出し
        let hogeIntValue = UserDefaults.standard.integer(forKey: "hogeIntKey")
        
        hogeNextLabel.text = String(hogeIntValue)
    }
}

```
#終わりに
もし間違いがあれば、優しく教えていただけると嬉しいです。

#参照サイト
https://qiita.com/uhooi/items/429cac9b798b9c0937ae
https://majintools.com/2018/11/11/userdefaults/


Twitterやっています。
[Twitter](https://twitter.com/koara1237)
Storyboardを使わずにコードベースでプロジェクトを作成する方法

#はじめに
iOSアプリを複数人で開発する際、Storyboardを使用すると、ソースコードに意図せぬ差分が出やすく管理がめんどくさい・・・。
~~だったらUIKitじゃなくてSwiftUI使いましょう~~

ということで、Storyboardを使わずにコードベースで開発する方法をまとめます。

なお、iOS13以降とそれ以前では設定の方法が大きく異なります。
今記事では、iOS1４での設定方法をまとめます。

#バージョン情報
Xcode 12.3
Swift 5.3.2

#プロジェクト作成
####1.Xcodeを起動してプロジェクトを作成
通常時と同様の手順でプロジェクトを作成します。

1. [Create a new Xcode project]
1. [Single View App]を選択して[Next]
1. 任意のプロジェクト名を入力
1. プロジェクト設定
  1. Interface -->　Storyboard
  1. Life Cycle --> UIKit
  1. Language --> Swift
1. プロジェクトを保存

####2.Storyboardの削除
上記の手順で作成したプロジェクトからStoryboardを消していきます

1. Main.Storyboardを削除。


1. Info.plistの項目[Storyboard Name]を -ボタンで削除
![説明１](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824096/93e84c09-bb10-7e1a-dbbc-efde93a20947.png)


1. [プロジェクト]>TARGETS>ProjectName>General>Development Info>Main Interfaceを空白にする。
![説明２](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824096/8218e905-f2bd-de15-19c2-5aa40efc763e.png)


1. SceneDelegate.swiftに初期画面情報を設定

  以下のように編集。

```SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        if let windowScene = scene as? UIWindowScene{
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = ViewController.init()
            self.window = window
            window.makeKeyAndVisible()
        }
    }
```

![説明３](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824096/e00599cc-49b7-0491-a596-5f079e5b89a1.png)

####3.ビルド
1. ViewController.swiftを以下のように編集

```ViewController.swift
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
        
        let titleLabel: UILabel = {
            let view = UILabel.init()
            view.text = "はろーわーるど★"
            view.textColor = .yellow
            view.translatesAutoresizingMaskIntoConstraints = false
            return view
        }()
        
        view.addSubview(titleLabel)
        
        NSLayoutConstraint.activate([
            titleLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0),
            titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0)
        ])
    }


}
```

![説明４](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824096/e718c4f4-3b17-ae54-5ba5-19b55cf6e2ca.png)

目に悪そうな色ですが、意図通りです。
![説明５](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824096/f0459877-4714-a288-b69e-3a39ad65756c.png)

#おわりに
今回は、iOS14での、Storyboardを使用しないプロジェクトの作成〜ビルドまでをまとめました。
コードでAutoLayoutを使用する場合は、以下のコードでAutoresizingを無効にする必要があリますのでお気をつけください。

```ViewController.swift
view.translatesAutoresizingMaskIntoConstraints = false
```
How to check log of specific service in Linux


## List units and see log of units.
When you have some trouble in http, you want to see httpd log. Then, you can see httpd log by `journalctl -u httpd`. You can check which service is running by `systemctl list-units`.

```
systemctl list-units # you can see list of running services. 
journalctl -u httpd
journalctl -u mysqld 
# ...etc
```

## Make log persistent
When you want to keep log after server shutdown, you should edit `/etc/systemd/journald.conf` and add line  `Storage=persistent` .


```/etc/systemd/journald.conf
[Journal]
#Storage=auto
Storage=persistent
#Compress=yes
```
【Swift UI】ObservableObjectとObservedObjectを理解するための時計アプリ

#この記事は何か
SwiftUIフレームワークによるアプリ開発におけるデータフローを理解するために、シンプルな時計アプリを作成します。


###環境
macOS 11.1
Xcode 12.3
Swift 5.3

#コード

````Swift:アプリのエントリーポイント
@main
struct WatchApp: App {
    let clock = Clock()
    
    var body: some Scene {
        WindowGroup {
            ContentView(clock: clock)
        }
    }
}
````

````Swift:ObservableObjectのクラス
class Clock: ObservableObject {
    var timer = Timer()
    @Published var currentTime = ""
    
    init() {
        start()
    }
    
    func start() {
        let formatter = DateFormatter()
        formatter.timeStyle = .medium
        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { (_) in
            self.currentTime = formatter.string(from: Date())
        })
    }
    
    func stop() {
        timer.invalidate()
    }
}
````


````Swift:ContentView
import SwiftUI

struct ContentView: View {
    @ObservedObject var clock = Clock()
    
    var body: some View {
        Text("\(clock.currentTime)")
            .font(.title)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView(clock: Clock())
        }
    }
}
````

![スクリーンショット 2021-01-24 3.21.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/f5db6fc8-2fc1-68df-a87f-d70053fb722c.png)
【iOS】個人開発で使って気分がよかったライブラリ5選【個人開発】

## [Yalantis/ColorMatchTabs: This is a Review posting app that let user find interesting places near them](https://github.com/Yalantis/ColorMatchTabs)
綺麗な上タブが作れるライブラリ！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138063/d08fce99-47c3-3cb6-af6e-7a920c196f20.png)

## [janselv/fave-button: FaveButton is an iOS cute animated like button written in Swift.](https://github.com/janselv/fave-button)
素敵なボタンが簡単に実装できる！
![fave-button1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138063/8a1d4108-b46a-8295-38ab-21f3cb7c453a.gif)

## [Ramotion/paper-onboarding: PaperOnboarding is a material design UI slider. Swift UI library by @Ramotion](https://github.com/Ramotion/paper-onboarding)
ウォークスルー（解説画面）が簡単に実装できる！

![paper-onboarding.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138063/6aa70d70-8241-b8cc-3e7d-a6a48dcb2fab.gif)

## [varabeis/SPPermissions: Ask permissions on Swift. Available List, Dialog & Native interface. Can check state permission.](https://github.com/varabeis/SPPermissions)
権限のリクエストがお洒落になるよ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138063/15d66b81-86e0-b13a-fbab-30e1e5b07f2c.png)

[iOSライセンス一覧を生成するツールLicensePlistが便利 | kazyブログ](https://kazyblog.com/ios-license-plist-library)
ライセンス表示もこれで安心！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138063/ee921212-ca1b-85aa-cf95-479bdab67628.png)

#　まとめ
エンジョイ個人開発！
すでに回答がなされたGoogleFormを作成する

# すでに回答がなされたGoogleFormを作成する

URLを押したら回答の初期値が記入されてるリンクが欲しい
よくあるでしょう
最近安直に記事を書くことにしたのでとりあえずかきます

# 今回使ったもの

-Google App Script　
-Google Form


#全容
単純なフォームを作ってスクリプトを開きます

#####実行前
<img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698479/90f7c827-7b60-8147-5c59-d0bbfef8c002.png" alt="">
#####実行後
<img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698479/b0ddd2e7-51d4-4f5b-339a-85e5225d0bcf.png" alt="">

#####スクリプト全容
```js
function myFunction() {
  var form = FormApp.getActiveForm();
  var item = form.getItems()[0].asTextItem();
  var item_response = item.createResponse("hello");
  var create_response = form.createResponse();
  console.log(create_response.withItemResponse(item_response).toPrefilledUrl());
  // ->https://docs.google.com/forms/d/e/<formID>/viewform?usp=pp_url&entry.<ID>=hello
}
```
ログに出てきたものを開くとなります．
いろんなサイトを見ると検証からフォームの回答欄のIDを調べるとかいろいろありますが，GASでまわすとなるとこんな感じで後はうまくやればできそうですね

## まとめ
半年前，めっちゃ調べたけど無理だったのに...
ちゃんと公式APIをみるべきらしい
いろいろ見たけどGoogleAppScriptAPI見やすすぎる

## 参考リンク
#### GAS公式( .withItemResponse(response) )
https://developers.google.com/apps-script/reference/forms/form-response#withitemresponseresponse
#### Formにスクリプトからsubmitする (Google Apps Script試行錯誤 Blog Google)
https://www.pre-practice.net/2017/11/google-formsubmit.html
LogDNAのAPIを使ってログをエクスポートする

LogDNAではREST APIを利用してログのエクスポートができる。もちろんGUIからもログの検索やエクスポートができるが、環境によっては(たとえばIBM Cloudで利用できるLogDNAのサービスでは)GUIの操作がモッサリしていることがあるので、APIを利用したほうが早かったりする。

## サービスキーの登録
これはGUIから行う。すでに登録済であれば不要だが、無い場合は"Generate Service Key"を押下して作成する。

![スクリーンショット 2021-01-24 2.07.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449737/916e0991-57a4-1d21-3404-cfd47b3e54af.png)

## API呼び出し

[公式のAPIリファレンス](https://docs.logdna.com/reference#v1export-1)を参照し、必要なパラメータをセットする。
fromとtoは必須パラメータとなる。なお、UNIX時間で入力する必要がある。

以下のようにコマンドを実行する。

```bash
curl -sS "https://api.jp-tok.logging.cloud.ibm.com/v1/export?from=$(($(date +%s)-2592000))000&to=$(date +%s)000&hosts=<対象ホスト>&apps=<対象ログ名など>&query=<検索キーワード>&size=20000" \
-u "SERVICE_KEY:<サービスキー>" | jq -r '._line'
```

* この例では、IBM Cloud東京リージョンにデプロイしたインスタンスをターゲットとし、現在時刻から30日前まで(IBM CloudのLogDNAサービスの最大保管日数）、サイズは2万行で指定している。
* 公式のAPIリファレンスではsizeは最大10000との記載があるが、実際には20000まで有効。
* JSONL形式でエクスポートされる。ログ本文のみを抜き出すには、jqコマンドで`._line`を抽出するのがよい。
* どういうわけか、from=30日前、to=現在という指定でも、新→旧の順番で結果が返却されるので、逆順にしたい場合は`tac`コマンドを使うのがよいと思う。
* query部分はGUIを利用しているときと同じように、ORやAND、マイナス条件を指定することが可能。URLエンコードする必要があるため、例えば`ABC OR XYZ`という条件で指定したい場合は`ABC+OR+XYZ`と記載する。
* appsの箇所は、appと指定しても動作する。というか、私の経験ではappsとするかappとするかによって、異なる結果が返却されることがあった…(appsではヒットしないことも)。両方試してみることをおすすめします。
モーダルで画像・動画を表示！「fancybox3」を使ってみた

自身のポートフォリオ作品（画像）を、ページ遷移ではなくモーダル表示にしたかったので、探してみたところ、「Fancybox3」というモバイルも対応している超優れものを見つけたので、さっそく実装してみました。

◆Fancybox3のサイトはこちら
[https://fancyapps.com/fancybox/3/](https://fancyapps.com/fancybox/3/)


## ①ダウンロード
まずは「fancyBox3」のサイトから、データをダウンロードします。
ダウンロード後、自身のローカルリポジトリ内へ読み込み。

ちなみに、

```HTML:HTML
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>
```

こちらをHTML内に記述しても実装できました。


## ②HTMLを記述

```HTML:HTML
<a data-fancybox="gallery" href="big_1.jpg"><img src="small_1.jpg"></a>
<a data-fancybox="gallery" href="big_2.jpg"><img src="small_2.jpg"></a>
```

こちらをHTML内に記述したら、なんということでしょう、、あっという間に実装されました！

私はモーダルを表示させた後にキャプションをつけたかったので、

```HTML:HTML
<a data-fancybox="gallery" href="big_1.jpg" data-caption="****"><img src="small_1.jpg"></a>
```
と`data-caption`をつけてあげたら、表示されました◎




## 参考サイト様
[モーダルで閲覧できるギャラリーを実装するのにfancyBox3が便利過ぎる。](https://arakaze.ready.jp/archives/5210)
Elasticsearch > kotlin > es-kotlin-clinent マニュアル（意訳）4 - CRUD 操作




Elasticsearchをサーバーサイドで操作する[Kotlin版ライブラリ](https://www.jillesvangurp.com/es-kotlin-manual/index.html)
がよく出来ていたのでその動作確認をしつつ[マニュアル](https://www.jillesvangurp.com/es-kotlin-manual/index.html)を日本語にしつつメモしています。

全10回です。

[es\-kotlin\-clinent マニュアル（意訳）1 - 序章](https://qiita.com/sugasaki/items/cfc501e21dcb03e4dac3)
[es\-kotlin\-clinent マニュアル（意訳）2 - Getting Started](https://qiita.com/sugasaki/items/91869aa9a66df5d58cfe) 
[es\-kotlin\-clinent マニュアル（意訳）3 - indexRepository](https://qiita.com/sugasaki/items/c0d0a753fb362d7c3349)
[es\-kotlin\-clinent マニュアル（意訳）4 - CRUD 操作](https://qiita.com/sugasaki/items/3c0e8ad6366a46124f3b) <-  ここ
[es\-kotlin\-clinent マニュアル（意訳）5 - 楽観的ロック](https://qiita.com/sugasaki/items/700dd9bd1e36dd8be4d6)
[es\-kotlin\-clinent マニュアル（意訳）6 - 検索](https://qiita.com/sugasaki/items/5c6e87af670a19310ff2)
[es\-kotlin\-clinent マニュアル（意訳）7 \- Kotlin Query DSL](https://qiita.com/sugasaki/items/747912b0e86049084aa6)
es-kotlin-clinent マニュアル（意訳）8 - Asynchronous
es-kotlin-clinent マニュアル（意訳）9 - DSLs
es-kotlin-clinent マニュアル（意訳）10 - Example



# 3. CRUD 操作

これまでインデックスができたので、CRUD操作を使うことができるようになりました。

### 1. ドキュメント追加


```
val id = "first"
println("Object does not exist: ${repo.get(id)}")

// so lets store something
repo.index(id, Thing("A thing", 42))

println("Now we get back our object: ${repo.get(id)}")
```

結果確認：キャプチャされた出力

```
Object does not exist: null
Now we get back our object: Thing(name=A thing, amount=42)
```

### 2. ドキュメント上書き

上書きされることをオプトインしない限り、オブジェクトに2回インデックスを付けることはできません。

オプトイン = `, create = false`


```
val id = "first"
try {
  repo.index(id, Thing("A thing", 40))
} catch (e: ElasticsearchStatusException) {
  println("we already had one of those and es returned ${e.status().status}")
}

// this how you do upserts
repo.index(id, Thing("Another thing", 666), create = false)
println("It was changed: ${repo.get(id)}")
```

結果確認：キャプチャされた出力

```
we already had one of those and es returned 409
It was changed: Thing(name=Another thing, amount=666)
```

### 3. ドキュメント削除

もちろん、オブジェクトを削除することも可能です。

```
repo.delete("1")
println(repo.get("1"))
```

結果確認：キャプチャされた出力

```
null
```
【Sass】別Sassファイルからimport

Sassで現在詰まっている場所について質問をしようとしていましたが、質問文を考えてる間に解決したパターンですｗ

結論、「**パスではなくurlで指定したら解決しました。**」

## 解決したいこと

**「別の階層に存在する、変数をまとめたscssファイルを読み込みたいです。」**

作業中にファイル数が多くなリ見通しがわるくなった為、フォルダ分けして整頓した結果、変数をまとめたファイル(variables.scss)をインポートができなくなりました。

指定先を変更しましたが一向に読み込まれず、解決が難しく感じたので、アドバイスや解決策を教えて頂けますと幸いです。

### 発生している問題・エラー

以下の画像の階層で、トップ画面のファイル(top.scss)から、変数をまとめたファイル(variables.scss)をインポートしようと試みています。

![scss_sitsumon.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/9a946352-5938-e433-772f-dbb5b8a925db.jpeg)

すると以下のようなメッセージが出力され、読み込まれません。

![70f2ab52d22ade5f86940d91f5e3dd9b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/695c6e83-6271-cb39-d97f-0b233a7ceeec.png)

```:OUTPUT
Error: File "/CSS/styles/variables" not found
        on line 2 of sass/Users/mac/Library/Mobile Documents/com~apple~CloudDocs/プログラミング/Web開発用/QuizApp-1/CSS/pages/top/top.scss
>> @import "/CSS/styles/variables";
```

和訳すると

```:和訳
エラーが発生しています。ファイル "/CSS/styles/variables" が見つかりません。
        sass/Users/mac/Library/Mobile Documents/com~apple~CloudDocs/プログラミング/Web開発用/QuizApp-1/CSS/pages/top/top.scssの2行目にあります。 >> @import "/CSS/styles/variables "です。
```

### 該当するソースコード

こちらがtop.scssファイル冒頭に記述しておりますimport文です。(一度同じ階層においておいた記述に直してあります。)

```sass:top.scss
//すべてのスタイルに共通する事項を取り決めるSCSSファイルです。
@import "_variables";
```

### 自分で試したこと
ここに問題・エラーに対して試したことを記載してください。

- top.scssから_variablesscssを読み込むには、以下の指定だと考えましが、失敗。

> Error: File "/QuizApp-1/CSS/pages/top/top.scss> @import "CSS/styles/variables";

```sass:top.scss
@import "CSS/styles/_variables.scss";
```

- VSCodeの予測変換からたどりましたが失敗しました。

> Error: File "/QuizApp-1/CSS/pages/top/top.scss
>> @import "/CSS/styles/variables";
   --------^

```sass:top.scss
@import "/CSS/styles/variables";
```

その他、同じ階層に設置して動作を確認して、一段階ずつ上げていって調べつ方を試しました。
こちらの時点で、/や../などでも読み込まれなかったことから、階層が違うとインポートができない

## 解決

冒頭に述べたように、urlで指定することで解決できました。

```sass:top.sass
//すべてのスタイルに共通する事項を取り決めるSCSSファイルです。
@import url("_variables.scss");
```

## 参考

こちらのサイトを参考にしました。

- [｢SCSS入門講座｣ @importでSCSSファイルの読み込みとgulp-sassの導入
](https://spyweb.media/2017/12/30/scss-import-and-gulp-sass/)

おつかれさまでした！
【JSP/サーブレット】　サーブレットクラスを使ってブラウザに「Hello World」を表示させてみた！

#１，環境設定:pencil2:

>Eclipse2020 Full Edition
Java11
Tomcat9

#２，動的プロジェクト作成::blue_book:

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/fbe44c94-aeb3-e2af-f739-d10cccc618fd.png" width="600">

#３，サーブレットクラスの作成場所:card_box:
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/d6f4bdce-a6f0-d858-3261-417e62dd3a9b.png" width="600">

#４、ディレクトリ構造とソースコード:notepad_spiral:

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/99dec7b0-d098-36d2-4205-b558f52c14c6.png" width="600">

#５、ブラウザをGoogle Chromeに設定:beginner:

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/44b1ef84-dee6-8104-6744-02685fe1cd4c.png" width="600">

#６、サーバーの起動とブラウザ表示:tada:

>サーバー起動（Tomcat)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/9b04ab10-7303-75e9-8571-920d948d5ea4.png" width="600">

>ブラウザ表示（Google Chrome）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/5a5ce955-a569-2572-ea1f-42e6f9804abb.png" width="600">

**表示することができました！！**

URLとリクエストメソッドにも注目すると、
　URL ⇨ **localhot:8080/JSP_Servlet/HelloServlet**
　Request Method : **GET**
となっています.

#７、次のステップ:airplane:
次回は、[JSPファイルからブラウザ表示](https://qiita.com/iwasaki-hub/items/3c17d694930e2fcffb33 "JSP")をさせてみたいと思います！
ActiveRecordの複数条件でのwhere notの挙動

#はじめに
普段、RailsはActiveRecord使っているんですが、条件を複数書いたときに、
where.not()の挙動が直感と反しており、なかなかバグに気づかなかったので、共有します。
#環境
Ruby : 2.7.1
Rails : 6.0.2
Posgresql : 13.1
#where.notの挙動
まず、where.not()の単数条件で名字が山田以外のuserを取得したい時を考えてみます。
発行されるSQLは以下のようになります。

```rb
User.where.not(last_name: '山田')
=> SELECT "users".* FROM "users" WHERE "users"."last_name" != $1 
 [["last_name", "山田"]]
```
これは期待通りに`last name`が**山田でない**userを取得してくれます。

では次に**「名字が山田」かつ「名前が太郎」(山田 太郎)以外**のuserを取得するとしましょう。
僕の直感では以下のような記述で取得できると思ってましたが...

```rb
User.where.not(last_name: '山田', first_name: '太郎')
=> SELECT "users".* FROM "users"
WHERE "users"."last_name" != $1 AND "users"."first_name" != $2 
[["last_name", "山田"], ["first_name", "太郎"]]
```
上記、SQLを見てみると、**「山田ではない」かつ「太郎ではない」**というSQLが発行されています。でも欲しかったのは**`「名字が山田」かつ「名前が太郎」`ではない** userです。集合記号を使うと以下のようにかけます。


```math
\overline{ 山田 \cap 太郎} \neq \overline {山田} \cap \overline {太郎}
```

![スクリーンショット 2021-01-24 1.37.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388573/1ada00be-d1f2-5192-a10a-9fe60df06c30.png)
取得したいuserは**赤と青の共通部分(山田太郎）以外**の箇所です。
しかし、発行されるSQLで取得しているのは、**赤と青以外**、すなわち白の部分のuserです。
悲しいかな、「山田孝之」や「麻生太郎」は取得してくれません。
#解決
では、山田孝之や麻生太郎を取得するにはどうすれば良いかというと、以下のようになります。

```rb
User.where.not(last_name: '山田').or(User.where.not(first_name:'太郎'))
=> SELECT "users".* FROM "users"
WHERE ("users"."last_name" != $1 OR "users"."first_name" != $2)
[["name", "山田"], ["public_id", "太郎"]]
```
上記は、書き方的には**「山田ではない」または「太郎ではない」**になります。これはドモルガンの法則を用いて

```math
\overline{A \cap B} = \overline A \cup \overline B
```
となることを使っています。A={山田},B={太郎}です。
よって、山田孝之は「山田ではある」ものの「太郎ではない」ので取得することができます。

もっとスマートに書きたいんじゃ！と思っておりますので、良い方法あったら教えてくだされー！
kotlin on heroku & spring getting started



A barebones Kotlin app, which can easily be deployed to Heroku.


HerokuでKotlin Webを動作する備忘録です


ソースは以下に保存しています。
https://github.com/sugasaki/start-kotlin-heroku


---

## Spring Initializr


まずは、プロジェクトの雛形を[Spring Initializr](https://start.spring.io/)から作成します。


<img width="1496" alt="スクリーンショット 2021-01-24 1 40 07" src="https://user-images.githubusercontent.com/1316886/105608632-6b107000-5de7-11eb-8628-d2552b22df3f.png">


当時とはUIが変わっていますが、以下を参考に
[Kotlin \+ Spring Boot でHello\! World\! \- Qiita](https://qiita.com/sugasaki/items/d42d017961a97f5363ee)



## Procfile

Procfileファイルをルートに作成


```
web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/demo-0.0.1-SNAPSHOT.jar
```

or 

```
web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/*.jar
```



## javaを11に変更

Spring InitializrでJava11を選択したので、HerokuのJavamo11に変更する

Javaバージョンの指定するには、`system.properties`を追加する必要がある。

[アクティベーションHeroku の Java サポート \| Heroku Dev Center](https://devcenter.heroku.com/ja/articles/java-support#specifying-a-java-version)

system.properties

```:system.properties
java.runtime.version=11
```



## git

```
git init
git add .
git commit  -m 'first commit'
```


## heroku

```
heroku create
heroku apps
git push heroku master
```


## run

```
heroku open /hello

heroku open /hello?name=jon
```



## on local 

```
http://localhost:8080/hello
```


## on heroku

```
https://shielded-crag-62835.herokuapp.com/hello
```


## trouble shout


```
heroku logs --tail
```


```
heroku run console
```



```
2021-01-23T13:29:09.479056+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/hello" host=sheltered-bastion-78347.herokuapp.com request_id=0b22f443-e210-4efa-bc09-4cd3ccf1023b fwd="121.113.51.72" dyno= connect= service= status=503 bytes= protocol=https
2021-01-23T13:29:10.404987+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=sheltered-bastion-78347.herokuapp.com request_id=1777303e-eab5-45e2-a21b-7745107c8172 fwd="121.113.51.72" dyno= connect= service= status=503 bytes= protocol=https
^
```

heroku local web

```
[WARN] ENOENT: no such file or directory, open 'Procfile'
[FAIL] No Procfile and no package.json file found in Current Directory - See run-foreman.js --help
```





# 参考

[Deploying Gradle Apps on Heroku \| Heroku Dev Center](https://devcenter.heroku.com/articles/deploying-gradle-apps-on-heroku)

[Heroku—Ktor](https://ktor.io/docs/heroku.html)

[Heroku \- サーバー \- Ktor](https://jp.ktor.work/servers/deploy/hosting/heroku.html)
【Rails】ルーティングの基礎的な書き方【Ruby】

# ルーティングの役割

railsガイド（ https://railsguides.jp/routing.html )によると
> Railsのルーターは受け取ったURLを認識し、適切なコントローラ内アクションやRackアプリケーションに割り当てます。

とのこと。

「route」を直訳すると「経路」ですから、リクエストの道案内役といったところでしょうか。

基礎的な書き方について記してみたいと思います。

***
[基本の書き方](#基本の書き方)
[rootの指定](#rootの指定)
[resourcesを用いた書き方](#resourcesを用いた書き方)

***

# 基本の書き方

`HTTPリクエスト 'URIパターン', to: 'コントローラー名#アクション名'`
もしくは
`HTTPリクエスト 'URIパターン', controller: 'コントローラ名', action: 'アクション名'`

```
Rails.application.routes.draw do
  get 'profile', to: 'users#show'
  post 'tweets', controller: 'tweets', action: 'create'
end
```

# rootの指定
root(ルート)とは、Railsアプリを実行する上で基本となる場所（パス）のことです。
例えばローカル環境にてアプリを実行した時に、「 http://localhost:3000 」のURLを指定した際に遷移するページを設定することができます。
`root to: 'コントローラー名#アクション名'`
もしくは
`root 'pages#main'`

```
Rails.application.routes.draw do
  root to: 'pages#main'
  root 'pages#main'
end
```

# resourcesを用いた書き方
resourcesメソッドを使用すると、`index, new, create, edit, update, show, delete`の七つのアクションへの割り当てを自動的に行うことができます。

```
Rails.application.routes.draw do
  resources :articles
end
```
こちらは、以下の7行のルーティングと同義になります。

```
get    '/articles',          to: 'articles#index'
get    '/articles/:id',      to: 'articles#show'
get    '/articles/new',      to: 'articles#new
get    '/articles/:id/edit', to: 'articles#edit
post   '/articles',          to: 'articles#create
patch  '/articles/:id',      to: 'articles#update'
delete '/articles/:id',      to: 'articles#destroy'
```


# 参考文献
https://railsguides.jp/routing.html
https://web-camp.io/magazine/archives/16815
PHP ログイン認証の作成手順⑤　〜ログイン機能作成②とセッションハイジャック〜

今回は
・emailと一致するユーザ検索
・passwordが一致するか検証
・ユーザ情報をセッションに格納してログイン
を実装する

###パスワード照会の方法
ユーザ入力とDBの値を照会
しかし、パスワードはハッシュ化されている→照会できる関数がある
`password_verify(パス、ハッシュ）`
パスワードがハッシュにマッチするかを判定する
マッチしたらtrue、しなかったらfalseを返す

###セッションハイジャック対策
セッションIDを盗まれて、なりすましをされること
対策：セッションIDを再作成する

#手順
##ログインロジック作成
前回までに作成したUserLogicクラスの中にログイン専用のメソッドを作成していく。
`login`メソッドとする。
top.phpがログインフォーム後のページだから、ここでログインの処理を記述する。

```php:top.php
<?php

require_once('../classes/UserLogic.php');

session_start();

// エラーメッセージ
$err = [];

// バリデーション
if(!$email = filter_input(INPUT_POST, 'email')){
    $err['email'] = 'メールアドレスを記入してください';
}

if(!$password = filter_input(INPUT_POST, 'password')){
    $err['password'] = 'パスワードを記入してください';
}

if(count($err) > 0){
    // エラーがあった場合は戻す
    $_SESSION = $err;
    header('Location: login.php');
    return;
}
// ログイン成功時の処理
$result = UserLogic::login($email, $password);
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザ登録完了画面</title>
</head>
<body>
<?php if (count($err) > 0) : ?>
<!-- エラーがある場合にforeachで該当エラーを表示させる -->
    <?php foreach($err as $e) : ?>
    <p><?php echo $e ?></p>
    <?php endforeach; ?>
<!-- $err配列に何もない＝エラーがない　から完了画面を表示させる -->
<?php else: ?>
    <p>ユーザー登録が完了しました。</p>
<?php endif ; ?>
<a href="login.php">戻る</a>
</body>
</html>
```

`$result = UserLogic::login($email, $password);`の部分。

そして、その`login`メソッドを以下の通りに記述する。

```php:UserLogic.php
/**
     * ログイン処理
     * @param string $email
     * @param string $password
     * @return bool $result
     */
    public static function login($email, $password)
    {
        // 結果
        $result = false;
        // ユーザをemailから検索して取得
        $user = self::getUserByEmail($email);
    }
```

##emailからユーザ取得ロジック作成
loginメソッドとは別に、emailの照会のためのメソッドを作成する。

```php:UserLogic.php
/**
     * ログイン処理
     * @param string $email
     * @param string $password
     * @return bool $result
     */
    public static function login($email, $password)
    {
        // 結果
        $result = false;
        // ユーザをemailから検索して取得
        $user = self::getUserByEmail($email);
        return $user;
    }

    /**
     * emailからユーザを取得
     * @param string $email
     * @return array|bool $user|false
     */
    public static function getUserByEmail($email)
    {
        // SQLの準備
        // SQLの実行
        // SQLの結果を返す
        $sql = 'SELECT * FROM users WHERE email = ?';

        // ユーザデータを配列に入れる
        $arr = [];
        $arr[] = $email;
        try{
            $stmt = connect()->prepare($sql);
            $stmt->execute($arr);
            //SQLの結果を返す
            $user = $stmt->fetch();
            return $user;
        }catch(\Exception $e){
            return false;
        }
        
    }
```

##パスワード照会とセッションハイジャック対策
サブ配列の最大値抽出（最大部分配列）

###趣旨
以前、転職活動のコーディングテストで
最大部分配列をreturnで返す問題を出題されたため
pythonで書いてみました。

```python:python
def maxSubArray(self, nums: List[int]) -> int:
    dp = [0 for _ in range(len(nums))]
    dp[0] = nums[0]
    for i in range(1, len(nums)):
        dp[i] = max(dp[i-1]+nums[i], nums[i])
    return max(dp)
```
学生おすすめのクラウドサービス学習

# 学生こそクラウドサービスを勉強すべき
- 多くの企業がクラウドサービスを導入しており、多くの企業が求めているスキルの１つ
- 大学の授業で学ばないため、利用している学生が少ない
- 利用することで簡単に成果物ができ、短期間で完成度の高いものが作成できる

以上の理由から学生こそクラウドサービスを学んだ方がいいと考える。

# e-Learning形式の学習ツール
## [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/)
- Microsoftが提供するe-Learning形式の学習ツール
- 無料で利用可能（社会人も）
- Microsoftが提供する多くの製品やサービスの概要を学ぶことができる
- Microsoftの認定試験に向けた自習用ツールとしても利用できる
- [ユーザーグループ（Japan Microsoft Learn User Group）](https://mslearn.connpass.com/)も存在

## [AWS Educate クラウドキャリアパス](https://aws.amazon.com/jp/education/awseducate/pathways-and-badges/)
- AWSが提供するe-Learning形式の学習ツール
- 無料で利用可能（学生限定）
- AWSが提供する多くの製品やサービスの概要を学ぶことができる
- 様々な技術の基礎的な部分を学ぶことが可能
- 将来目標とする職業に合わせてデザインされた学習コースも用意されている

# クラウドサービス
## [IBM Cloud](https://www.ibm.com/cloud)
- AIプラットフォームのIBM WatsonやフローベースプログラミングツールのNode-REDなど、幅広い製品・サービスを提供
- クレジットカード登録不要（無料アカウント）

## [Microsoft Azure](https://azure.microsoft.com/ja-jp/)
- 多彩なAIサービスをWeb API形式で提供するCognitive Servicesやさまざまな種類のWebアプリケーションを管理することなく簡単にホストできるApp Serviceなど、幅広い製品・サービスを提供
- 1年間多くのサービスを無料で利用可能
- [Microsoft Learn Student Ambassadors Japan（旧 Microsoft Student Partners Japan）](https://mspjp.connpass.com/)がAzureを学習するイベント[MS Tech Camp](https://www.youtube.com/channel/UCbYatXqIz_h_Qp0y3AHqoQg)を開催

### [Azure for Students](https://azure.microsoft.com/ja-jp/free/students/)
- 学生限定のAzureアカウント
- 年間100ドル分無料
- クレジット登録不要
- 学生期間中は何度でも更新可能

## [AWS](https://aws.amazon.com/jp/)
- 仮想サーバー構築を行うAmazon EC2や開発者向けの機械学習サービスであるAmazon Personalizeなど、幅広い製品・サービスを提供
- 1年間多くのサービスを無料で利用可能

### [AWS Educate Starter アカウント](https://aws.amazon.com/jp/education/awseducate/students)
- 学生限定のAWSアカウント
- 年間100ドル分無料（加盟校でない場合は40ドル）
- クレジット登録不要
Vuetifyのデータテーブルのソートボタンを自由な場所に配置する方法（外部ソート）

データテーブル・コンポーネントのデフォルトでのソート機能のUIは以下のようになっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578233/02742ecc-3353-b9df-f1b2-85d2966ce09f.png)

このソートボタンを別の場所で使いたい場合や、
デザインを自由に変更したい場合の実装方法について。
## 実装方法
script内のdata内で以下プロパティを定義。
sortByプロパティは、対象にしたいカラム名を指定する。

```
sortBy: 'name',
sortDesc: false
```

method内で以下の関数を定義。（名前は自由）
sortDescの真偽値を反転させている。

```
methods: {
  toggleOrder () {
    this.sortDesc = !this.sortDesc
  }
}
```

template内のv-data-tableタグに、
sort-by.syncオプションと
sort-desc.syncオプションを追加。

```
<v-data-table
  :headers="headers"
  :items="items"
  :sort-by.sync="sortBy"
  :sort-desc.sync="sortDesc"
></v-data-table>
```

あとは適当にボタンなどを配置し、
クリックイベントなどで、先ほどmethodで定義した関数（toggleOrder）
を発火させることでソートが切り替わるようになる。
以下のサンプルでは、v-iconを二つ配置し、
ソートの昇順と降順でアイコンを切り替えている（上矢印と下矢印）

```
<v-btn
  icon
  small
  color="grey darken-1"
  class="ml-3"
  @click="toggleOrder"
  ><v-icon v-if="sortDesc">mdi-arrow-down</v-icon
  ><v-icon v-else>mdi-arrow-up</v-icon></v-btn
>
```
bundle installしてもエラーが続き沼にハマる。（備忘録として）

### bundle installしてもエラーが続き沼にハマる。（備忘録として）

rails newしてbundle installすると

 ```
Make sure that `gem install #### -v '"#.#.#' --source https:・・・・`
```

のようなエラーが延々と続く。

gemを指定してinstallしてもエラーは解消されず。
ググった情報を頼りにカタカタするも、エラーは解消されず。


結局解決方法は以下でした。

>1rbenvでrubyを管理する
2xcodeのupdateをする

###１rbenvでrubyを管理する。
デフォルトのrubyを使っていたが、toolのアップデートかなにかで齟齬が出てしまった？のかもしれない。
標準rubyは一つしか入っていないためrbenvでrubyのバージョンを管理する。
基本的に開発ではrbenvを用いてrubyを管理する。
参考：https://qiita.com/hujuu/items/3d600f2b2384c145ad12

###2xcodeのupdateをする。
これが今回最も遠いようで近いエラーの原因でした。
エラー分には
you have to ....のような文字があったがなんのことやらと無視していた。
しかしそれはtoolをupdateしてくれと言うメッセージでした。
xcodeをupdateしないとだめだった。

------
bundle installでめっちゃ変更が多くなった。。
3k+!?

gitignoreに
/vendor/bundle/*/
vendor配下のbundleを追加してあげることで解決
Vuetifyのデータテーブルに、「何件中何件」を表示する方法

Vuetifyのデフォルトのデータテーブル・コンポーネントは以下のようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578233/08a58fc8-d86d-972e-742a-22f9fd7af812.png)

この時点で「1-5 of 10」という表示がされるようになっているが、
今回はこの文字を自由に変更させたい場合の方法について。

## 実装方法
v-data-table 内でテンプレートタグを作成し、
v-slotに**footer.page-text**を指定。
↓サンプル

```
<template v-slot:footer.page-text="props">
    {{ props.itemsLength }} 件中 {{ props.pageStart }} 件から
    {{ props.pageStop }} 件までを表示
</template>
```

するとこんな感じの表示になる。

![スクリーンショット 2021-01-22 4.43.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578233/2c002c97-a73c-35d3-6ebc-dccabd03bfe6.png)

ちなみに「1-5 of 10」の左右に表示されている要素を消したい場合は、
Vuetifyのオプションでは消せないので（正確には「1-5 of 10」を残して他のものを削除したい場合）、
CSSを使えば消すことができる。
Chrome Developer Toolで確認するとそれぞれ以下のようなclassが付与されていたので、
そのclass名を指定してdisplay: none;すれば消える。

```
  .v-data-footer__select {
    display: none;
  }
  .v-data-footer__icons-before {
    display: none;
  }
  .v-data-footer__icons-after {
    display: none;
  }
```
平面上におけるポテンシャルデータの補間

#１．はじめに
　平面地図上における標高マップの様に、二つの独立関数x, yに従属変数zが測定されるケースを考える。データの取得作業を最小限にし、補間することで情報量を確保したい。[scipy.interpolate.Rbf](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.Rbf.html)による補間をfanctionを変え実施し、結果を比較する。今回は、平板のポテンシャルデータ（歪み変形量）を離散的に測定し、測定間を補間していく。

#２．データ
　測定した平板の歪変形データを散布図化する。![scatter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781118/74caf989-0dc5-30a2-3bac-c5cfd31b455c.png)

#３．scipy.interpolate.Rbf 補間
　測定したデータに対し、scipy.interpolate.Rbfを用い、測定値を補間していく。fanctionとして、"cubic", "gaussian", "linear", "thin_plate"の4種を試す。コードは下記。

```python
import numpy as np
import pandas as pd
from scipy.interpolate import Rbf
import matplotlib.pyplot as plt

#データの読み込み
df = pd.read_csv('./data/test.csv')
x = np.array(df['x'])
y = np.array(df['y'])
displacement = np.array(df['displacement'])

#補間するエリアを指定
xi = np.linspace(0, 10, 100)
yi = np.linspace(0, 6, 60)
xx, yy = np.meshgrid(xi, yi)

#cubicで補間
rbf_c = Rbf(x, y, displacement, function='cubic')
zz_c = rbf_c(xx, yy)
#gaussianで補間
rbf_g = Rbf(x, y, displacement, function='gaussian')
zz_g = rbf_g(xx, yy)
#linearで補間
rbf_l = Rbf(x, y, displacement, function='linear')
zz_l = rbf_l(xx, yy)
#thin_plateで補間
rbf_t = Rbf(x, y, displacement, function='thin_plate')
zz_t = rbf_t(xx, yy)
```

#４．結果の比較
　Rbfで補間したデータをグラフ化すると下図。測定値も一緒にプロットしている。
![cubic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781118/1858e42d-26f0-4eaa-e9dd-ba05119aae7c.png)
"gaussian"で違いが分かるが、あとは似たような感じ。y=4の断面を抽出して下にグラフ化する。
![cross_section.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781118/b7a53c92-b31d-9e2c-e062-1229d8e1a722.png)
・"cubic"は"gaussian"の分布と似ているが、外挿の分布が異なる。
・"gaussian"はいわゆる正規分布を匂わせる分布に見える。
・"linear"は明らかにカクカクしているように見える。
・"thin_plate"は他の分布より歪量は小さいが、外挿の分布が平板に近い。

#５．まとめ
・平板の歪変形量を題材とした場合、scipy.interpolate.Rbfのfanctionは"thin_plate"が一番自然な補間のように思える。
・もっと細かい測定値を取得し、補間データと比較したい。
VeeValidateで正規表現を使ったバリデーションをかける方法

ドキュメント参照 (VeeValidate 2系3系）
[Validation Rules [regex]](https://vee-validate.logaretm.com/v2/guide/rules.html#regex) 

VeeValidateのregexオプションを使うと、自分で作成した正規表現でバリデーションをかけてくれる。
注意点としては、validateに**オブジェクト形式**で渡さないといけない。

↓サンプル

```
:validate="{
   required: true,
   max: 15,
   regex: '^(070|080|090)-\\d{4}-\\d{4}$'
}"
```
Qiita で ES2015+ を意識せずにコーディングしている記事が 25% 程度ある

2021 年。JavaScript (ECMAScript) は常に進化し続けているが、初学者含めて日本の JavaScript 使用者は何割ぐらいの人が ES2015+ を意識してコーディングしているのか気になったので調べてみる。

# 動機

変数は `var` ではなく `const` や `let` を使った方がスコープを安心して使用できるし、関数は `function App () {}` ではなく　`const App = () => {}` で良い。
分割代入やテンプレート文字列、スプレッド構文、`map` なんかも便利だと思う。
どんどん使っていけばいいし、新しく学ぶ人は当然 ES2015+ で学んだほうが良いと思う。
でも、それを知らずに学び始める人、知らずに居続ける人もいるのかもしれない、とふと気になった。

# 調査方法
Qiita に投稿された記事から ES2015+ を意識してコーディングしている／意識せずにコーディングしている記事数（※）を Qiita の検索機能から抽出し、母数に対する割合を求める。

ES2015+ を意識しているか否かは、記事内のコードにおいて、変数宣言時に ES2015+ で最も基本的な要素といえる `const` を使っているか否かを基準に判断する。（後述）

※　記事数ではなく、そこからユーザ数を拾って調査した方が正確なのでそうしたかったが、時間の都合上で記事数とする。

# 調査対象
Qiita に投稿された記事の内、次の条件に合致するものを対象とする。

- 作成が 2020 年の 1 年間（ `2020-01-01` 以降 `2020-12-31` 以前）の記事
- タグに `JavaScript` が含まれる記事

# ES2015+ を意識してコーディングしているか／していないかの基準
記事中のコードに `var` と `const` のどちらを使用しているか。

- 母数： `var` または `const` が含まれる
- ES2015+ を意識してコーディングしている： `const` が含まれる
- ES2015+ を意識せずコーディングしている： `var` が含まれる かつ `const` が含まれない

# 調査結果

- 母数（`var` または `const` が含まれる）
  - 5698 ( 4270 + 1428 ) 記事
  - 検索： ES2015+ を意識してコーディングしている、意識せずコーディングしている記事の合計
- ES2015+ を意識してコーディングしている（`const` が含まれる）
  - 4270 記事 ... 全体の約 75 %
  - 検索： `tag:JavaScript created:>=2020-01-01 created:<=2020-12-31 code:const`
- ES2015+ を意識せずコーディングしている（`var` が含まれる かつ `const` が含まれない）
  - 1428 記事 ... 全体の約 25 %
  - 検索： `tag:JavaScript created:>=2020-01-01 created:<=2020-12-31 code:var -code:const`

# 結論

調査結果から全体の約 25 % の記事は ES2015+ を意識せずコーディングしている記事と考えられる。

# 追伸

記事数ではなくユーザ割合をどなたか調査してみてほしいです。
パーシャルで繰り返し処理

教えていただいたことの備忘録として残します。

```ruby:bar.html.erb
<%= render partial: 'foo', hoges: @hoges %>
```

```ruby:_foo.html.erb
<% hoges.each do |hoge| %>
 <% hoge.name %>
 <% hoge.price %>
<% end %>
```

これでも動作確認はできましたが、以下のようにします。

```ruby:bar.html.erb
<%= render partial: 'foo', collection: @hoges, as: 'hoge' %>
```

```ruby:_foo.html.erb
 <% hoge.name %>
 <% hoge.price %>
```

こうすることで読み込み速度が向上します。
collectionオプションを使うと1回しか読み込まれないみたいです。
AWS java SDKでDynamoDBテーブル情報を取得してみる

# この記事について

将来的に書く予定の「JavaFX で DynamoDB Viewer作ってみた」記事の１ステップ。
結構大きな話になると思うので、少しずつ技術ポイント毎に記事を書いて、ある一定程度の要件を満たせた段階で前述まとめ記事書く予定。

第一回記事：[DynamoDBの情報を読み込んでJavaFXで表示してみる](https://qiita.com/silverbox/items/eba824a9f003df67181e)
第二回記事：[JavaFXで動的にテーブル列を設定する](https://qiita.com/silverbox/items/904a01d561014d800696)

※前回の記事が基本になってます。メソッドなど再説明していない部分があります。

# 今回の進捗

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530376/0f9e40cd-a84f-efe2-87a4-4111008b1fc8.png)

今回終了時のソースはこちら。[Github](https://github.com/silverbox/dynamodbtool/tree/3rd-tablelist)

# 今回つけた機能

- localDynamoDb対応
- テーブルリスト表示
- 選択したテーブルの構造から検索条件に主キー情報を自動設定
- ついでにレコード件数とテーブルサイズも表示
- 検索条件無指定も可能に
- パーティションキーとソートキーを表の冒頭に表示

# それぞれのポイント

## localDynamoDb対応

各dynamoDB機能（Scan、Query）のベースとなるAbstructクラスを準備し、そのクラス中でConnectorの分岐を行う。それぞれの継承先では気にしなくて良い様に。

## テーブルリスト表示

基本は[公式サンプル](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/ListTables.java)。読み込みクラスである ListTablesRequest では検索条件が指定できなさそうなので、java側でフィルタリング。
※読み込み条件を指定できる手法が見つかったら変更予定。

## 選択したテーブルの構造から検索条件に主キー情報を自動設定（ついでにレコード件数とテーブルサイズも表示）

同じく[公式サンプル](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/DescribeTable.java) から DescribeTable 機能を使用。
TableDescription 形式の情報が取得可能。以下の情報が解る。

- tableName：テーブル名
- tableArn：ARN
- tableStatus：ステータス
- itemCount：レコード数
- tableSizeBytes：テーブルサイズ
- provisionedThroughput：プロビジョン済みスループット
- readCapacityUnits：読み込みキャパシティ
- writeCapacityUnits：書き込みキャパシティ
- attributeDefinitions：属性定義のリスト
- keySchema：キー情報

## 検索条件無指定も可能

検索条件がある時はQuery、全読み込みはScanを使う

## パーティションキーとソートキーを頭に表示

今回一番面倒だった部分。
DynamoDBは、RDBの様にテーブル構造が明確に定義されているわけではない。取得されるデータのフィールド順は不定。そのままだと表にした時にデータの把握がしにくい。パーティションキー、ソートキーを冒頭にセットしたい。
その為にフィールド情報を以下の情報から組み立てる必要がある。今回はキーのフィールド名とデータ型情報は最初の２つから。それ以外のフィールド名とデータ型は実データから取得するようにした。

- TableDescription.keySchema から取得できるKeySchemaElementクラス。  
KeySchemaElement.keyTypeでpartitionKey（HASH）とsortKey（RANGE）が解る。  
KeySchemaElement.attributeNameでフィールド名が解る。
- TableDescription.attributeDefinitions から取得できる各フィールドのAttributeDefinitionクラス。  
AttributeDefinition.attributeTypeでEnumのScalarAttributeTypeクラスで文字列か数値かが解る。  
AttributeDefinition.attributeNameでフィールド名が解る。  
※全フィールドがある訳ではない。キーやインデックスに使用していないフィールドは無いと思われる。
- 検索結果（QueryResponse、ScanResponseのitems）から List<Map<String, AttributeValue>>が取得できる。  
AttributeValueにはhasSs,hasNsなどがあり、ある程度のデータ型が解る。  
しかし文字型と数値型などが解らず、一旦```toString```で文字列を取得後「AttributeValue(N=」で始まるかなどで判断。

# 次回予定

- テーブル表示内容のコピー（キー値の取得など）
- 検索結果の複数表示（タブ表示で複数テーブル検索結果切り替え）
openSUSEにTeamViewer入れてみた

備忘録

縁あって８０００円でi5のノートパソコンをバッテリー劣化のみの
症状だけで手に入れることができたのでopenSUSEを入れてある。

外出先とかで操作できたら便利だと思ってTeamViewerを入れることにした。

# 動作環境

- openSUSE Tumbleweed 20210121

# 早速操作

公式サイトをたよりに作業開始
[How to install TeamViewer on Red Hat and CentOS - TeamViewer Support](https://community.teamviewer.com/English/kb/articles/30708-how-to-install-teamviewer-on-red-hat-and-centos)

## つまづいてたところ

実はインストールはRPMパッケージを導入するだけの簡単なものだったのだけれど、
「signature verification fails」が頻繁に発生し、鬱陶しかったので、
インストールの項目を読み直して理解した。

>📌Note: To install on RPM systems (including Fedora), if signature verification fails,
>and for general installation instructions on RHEL or CentOS, see
>[How to install TeamViewer on Red Hat and CentOS](https://community.teamviewer.com/English/kb/articles/30708-how-to-install-teamviewer-on-red-hat-and-centos)

そしてリンク先での内容

>*All RPM systems (including Fedora)*
>When installing a TeamViewer on a RPM system for the first time via command line, it might complain about a missing key to verify the signature of the package. You can either ignore / override this, or install our public key first. [Download the public key file here](https://download.teamviewer.com/download/linux/signature/TeamViewer2017.asc) and import the key by using the following command as an administrator:
```
rpm --import TeamViewer_Linux_PubKey.asc 
```

つまるところ RPMシステムのOSはKey入れてねってことみたい
なので

```
まずはダウンロード
wget https://download.teamviewer.com/download/linux/signature/TeamViewer2017.asc
リネーム（リネームしてダウンロードするオプション忘れてしまいました
mv TeamViewer2017.asc TeamViewer_Linux_PubKey.asc
インポート
sudo rpm --import TeamViewer_Linux_PubKey.asc
```


## インストール

パッケージをダウンロードします
[ここから](https://www.teamviewer.com/ja/download/linux/) ダウンロードできます

```
wget https://download.teamviewer.com/download/linux/teamviewer-host-suse.x86_64.rpm
```
上記のコマンドでもいいです

続いてインストール

```
zypper install ./teamviewer-host-suse_13.x.yyy.rpm
```

これでインストール作業は完了です。
皆様の快適なリモートワークを祈っております。では。
MongoDBのWindowsサービス登録で地味にハマる場合

### 概要
Windows環境でMongoDB使う場合に、都度手動で起動するのめ面倒なのでサービスに登録して自動で起動するようにしたい。手順はネット上にたくさん落ちているが、超初歩的なポイントでハマったのでシェア。

### 環境
 - Windows10 HOME ( 10.0.19041 )
 - MongoDB: ver4.2
 
### サービスの起動に失敗する場合のよくあるパターン
MongoDBの起動に失敗する場合、よくあるのがdbPathの指定ミスなのでそこをチェックする。特に、標準のdbPathではないフォルダをdbPathに指定しようとした場合に、それが上手く反映されず、起動時に標準のdbPathを読みに行ってコケる…というパターンが多い。

### サービス登録時は必ずConfigファイルを指定する
サービスとして登録するときに、必要な諸情報は必ずConfigファイルに定義し、インストール時にそれを指定するようにする。Web上の手順にはConfigファイルを指定せず、--dbPath形式でインストールしている例もあるが、その場合はサービス起動時にちゃんと指定したdbPathを見に行っているか確認すること。
[参考：MongodbのWindowsインストールとサービス設定とRobomongo](https://qiita.com/boss_ape/items/e4c5024c00de25d3b1b6)

サービス登録後、サービスのプロパティにきちんとConfigファイルも登録されていればOK
![スクリーンショット 2021-01-24 003839.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285378/bc929b83-2744-08cd-0b8c-9c821313bc9e.png)

### Configファイルの編集も注意
ConfigファイルはMongoDBの実行ファイルがある場所に配置することが多いが、当然管理者権限を持ったアプリケーションからでないとファイルの上書きや作成に失敗するので注意する。特にTeraPadとかメモ帳アプリでやってると書き込み失敗のエラーが出ない場合があり、Configファイルの編集が全然反映されずに焦ったりする。落ち着いて管理者権限で起動しましょう。
EC2インスタンスにパブリックIPが付与されなかった話

<h1>EC2にパブリックIPが付与されてない</h1>
ある時EC2をパブリックサブネットに立ち上げた時のこと。
EC2インスタンスにPublic IPが付与されていないことを発見↓![スクリーンショット 2021-01-23 23.50.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049410/c2f55c09-7f43-8ac4-0b78-a915a710f313.png)


AWS認定のソリューションアーキテクトでもよく出てくるこの事象。
この原因について、試験での答えは大体こう⇨「サブネットのパブリックIPv4アドレスの自動割り当てが有効になっていない」

了解了解、座学で知ってます。サブネットを確認しましょう。 
あれ、サブネットの設定では自動割り当てが有効になっているな、、、↓
![スクリーンショット 2021-01-24 0.07.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049410/99f152b8-9846-f7c6-9eb9-65e31ad54728.png)
<h1>原因</h1>
EC2インスタンスの起動時の設定が間違ってました。
押し間違えで自動割り当てパブリックIPを「無効化」にしてしまってたようです。
![スクリーンショット 2021-01-24 0.10.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049410/796c7df4-1f88-0e3c-8696-924a12aae097.png)
悩んだ挙句しょうもないミス。あるあるですね。

<h1>対処法</h1>
EC2のコンソールで有効化するとこを探します。が、、、、ない！
EC2のバブリックIPの自動割り当て設定は後から変更できないようです。
そうなると、対処法は2つ。
<p>1. 　今のEC2を終了して、新しいEC2を正しい設定で起動。</p>
<p>2.　 ElasticIPアドレスをEC2にアタッチする</p>

今回は ElasticIPを付与することにします。
ElasticIPを付与後、無事パブリックIPアドレスが付与されました↓
![スクリーンショット 2021-01-24 0.19.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049410/afc54613-7f8a-d704-827c-b323fbb26dde.png)


<h1>感想</h1>
たかが自動割り当ての初期設定を間違えただけで、静的IPである必要もないのにElasticIPをアタッチしないといけないのは若干大袈裟な気が、、、
ElasticIPは一応有料で、EC2からデタッチした後に解放をしないと料金が発生しますしね。
参考: https://aws.amazon.com/jp/premiumsupport/knowledge-center/elastic-ip-charges/

EC2のみならず、リソースの作成時でないと変更できない設定が色々とあるので、意外と初期設定は大事だと感じました。

(今回スクショしたリソースなどは全て削除済なので、IPやIDが丸出しですがご心配なく)
CloudHSM とは

## 勉強前イメージ

確かなんかセキュリティの証明書的ななにかの話やった気がするけど
覚えてない....

## 調査

### CloudHSM とは

HSMは `Hardware Security Module` の略で、
暗号化のための鍵を管理する専用サーバーを、指定したVPC上にAWS側で用意してくれるサービスになります。

CloudHSMから提供される鍵によって安全にデータを保護できシングルテナントで、またAWSアカウント専用のため他のAWSアカウントとは分離しています。
暗号モジュールに関しては、米国連邦標準規格である `FIPS 140-2 レベル3認証済み` のHSMを利用したサービスです。

`FIPS 140-2 レベル3認証済み` とは暗号モジュールに関する規格であり、以下が必要になります。

- すべてのコンポーネントの品質が担保されている
- 物理的な改ざんの痕跡を残すこと
- オペレータのIDベースでの認証が必要
- セキュリティパラメータはモジュールに入出力するインタフェースとその他のものを物理的・論理的に分離すること

それくらい `FIPS 140-2 レベル3認証済み` は厳しい規格である認識です。

### 特徴

- 利用するにはVPCが必要で、VPC外からのアクセスはできないのでルーティングさせる必要がある
- 高可用性・高耐久性が求められるアプリケーションでも利用できる
- 連携サービスはKMSを通じてAWSサービスと連携できる
- 暗号処理のオフロードもできる


## 勉強後イメージ

鍵を管理するサービスもあるのか・・・
これはシングルテナントだから、要件厳しいサービスなどでも使用できそうなイメージもある

## 参考

- [AWS CloudHSM](https://tech.blog.surbiton.jp/aws-cloudhsm-1-get-started/)
- [[新機能] AWS CloudHSMが東京リージョンにやってきました！](https://dev.classmethod.jp/articles/aws-cloudhsm-is-now-available-in-tokyo/)
- [【AWS】CloudHSMの使い方について](https://www.acrovision.jp/service/aws/?p=2414)
[AtCoder]AtCoder Beginner Contest 189 A~D問題

# A問題
1文字目が２、３文字目と等しいかどうか調べる。

```c++
#include <bits/stdc++.h>
using namespace std;

int main()
{
    string n;
    cin >> n;
    
    if(n[0] == n[1] && n[0] == n[2]){
        cout << "Won" << endl;
    }else{
        cout << "Lost" << endl;
    }
    
    return 0;
}
```
# B問題
各iごとのアルコール量(ml)を整数で計算すると除算で誤差が発生するため、閾値(X)の方に x 100して計算する。

```c++
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n,x;
    cin >> n >> x;
    x *= 100;

    int sum = 0;
    for(int i =0; i < n; i++){
        int v,p;
        cin >> v >> p;
        sum += v * p;
        if(x < sum){
            cout << i + 1 << endl;
            return 0;
        }
    }

    cout << -1 << endl;

    return 0;
}
```
# C問題
※O(n^2)でも間に合うそうなので正攻法じゃないかもしれません。

1. ある範囲におけるみかんを食べられる個数は 範囲 x 範囲内の最小値で求まる
2. 1の最小値を範囲に含める限り範囲を広める以外にみかんを食べる個数を増やせない

上記のことから範囲1~Nを初期値として範囲内の最小値を境に前後で範囲を分割し二分探索法で最大値を再帰的に算出する。

```c++
#include <bits/stdc++.h>
using namespace std;

int n;
vi a(1000000);
 
int solve(int l ,int r){
    if(l < 0 || l >= r || r > n) return 0;
    auto min_itr = min_element(a.begin() + l, a.begin() + r); 
    int min_index = distance(a.begin(), min_itr);
    return max(max(solve(l, min_index), solve(min_index + 1, r)), (r-l) * (*min_itr));
}

int main()
{
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }
 
    cout << solve(0, n) << endl;

    return 0;
}
```

# D問題
Y<sub>i</sub>がTrueまたはFalseになる組み合わせはそれぞれ、Y<sub>i-1</sub>がTrueまたはFalseになる組み合わせをもとに再帰的に求まる。
制約上、STLのpowではオーバーフローするので注意(※私はそれにハマってタイムアップしました)

```c++
#include <bits/stdc++.h>
using namespace std;
#define ll long long

vector<string> s(100);

ll pow2(ll a){
    ll ret = 1;
    for(int i = 0; i < a; i++) ret *= 2;
    return ret;
}

ll solve(bool y, ll i){
    if(i==0) 
        return 1;
    if(s[i] == "AND"){
        if(y == true)
            return solve(true, i-1);
        else
            return pow2(i+1) - solve(true, i-1);
    }
    else{
        if(y == true)
            return pow2(i+1) - solve(false, i-1);
        else
            return solve(false, i-1);
    }
}

int main()
{
    int n;
    cin >> n;

    for(int i = 0; i < n; i++){
        cin >> s[i+1];
    }

    cout << solve(true, n) << endl;

    return 0;
}
```
RSpecでJavaScript等で挿入されるiframe内のコンテンツを確認する

# 概要
RSpecでテストを書いている時に、Twitter、Youtube等のリンクを貼り付けた時に、JavaScript等で時間差で挿入されるiframe内のコンテンツを確認する際に詰まったのでメモ。

# 方法

以下の通り。

```ruby
# iframeがあるか確認。この場合、挿入されるまでデフォルトのwait timeだけ待ってくれる
expect(page).to have_selector 'iframe'
# iframe内のコンテンツを確認
within_frame find('iframe') do
  expect(page).to have_content 'コンテンツ'
end
```

デフォルトのwait time内で挿入されない場合は以下の様に待ち時間を指定する。

```ruby
expect(page).to have_selector 'iframe', wait: 5
```

１行目はチェックする必要がなければ`until`でJavaScriptでiframeが挿入されるまで待ってもいい。