OmniAICreator/Qiita-1.07M huggingface dataset:
ネットワークの基礎知識

# 目的
ネットワークの基礎知識について理解を深める。

# 目次

1. [Webとは](#webとは)
1. [プロトコル](#プロトコル)
1. [TCP/IP](#tcpip)
1. [IPアドレス](#ipアドレス)
1. [ドメイン](#ドメイン)
1. [DNS](#dns)
1. [ポート番号](#ポート番号)

# Webとは

そもそもWebとは何かというと、
`World Wide Web`の略で、コンピュータを使って文書と文書を結びつける仕組みのことです。
ここで言う文書とは、HTMLで記述された文書のことで、正式には`ハイパーテキスト`と呼びます。
`ハイパーテキスト`は、別の`ハイパーテキスト`への参照を埋め込むことができます。例えばaタグを使った文字リンクなどです。
この参照を`ハイパーリンク`と呼び、この`ハイパーリンク`によって、`ハイパーテキスト`同士が世界中でクモの巣状に繋がっている様子から`World Wide Web`と命名されたようです！

# プロトコル

続いてネットワークについてのルールや手順について理解を深めていきます。
ネットワークに接続された機器同士の共通のルールや手順のことを`プロトコル`といいます。
特に現在のインターネット通信においてよく利用されている通信プロトコルに`TCP/IP`というものがあります。

# TCP/IP

`TCP/IP`とは、インターネット通信において最も利用されている通信プロトコルの総称です。
正確に言うと、インターネット通信は複数のプロトコルから構成されるため、TCPやIPもそのうちの1つに過ぎませんが、
様々なプロトコルの中でもインターネット通信において中心的な役割を果たすのがTCPとIPであることから、総称して`TCP/IP`と呼ばれるようになったようです。

# IPアドレス

インターネット上の住所のことを`IPアドレス`といいます。
`IPアドレス`は数字とドットで表現され、表示したいWebサイトやアプリに接続するために必要になります。

しかし、普段私たちは`IPアドレス`ではなく、「https://〇〇〇.com」のようなURLを入力して、目的のサイトにアクセスしています。
これには`ドメイン`と`DNS`という概念が大きく関わっています。

# ドメイン

`ドメイン`とは数値とドットからなるIPアドレスを「人間が覚えやすいように文字列に変換したもの」です。
`IPアドレスとドメインを関連付ける`ことで、検索欄に`ドメイン`を入力するだけで目的のサイトにアクセスすることができるようになります。

そしてこの`IPアドレス`と`ドメイン`を結びつけるシステムのことを`DNS`と呼びます。

# DNS

DNSとは`Domain Name System`の略であり、ドメインをIPアドレスに変換する仕組みのことを指します。
そして`DNS`のサービスを提供するサーバーを`DNSサーバー`と呼びます。
`DNSサーバー`は、ブラウザから入力されたドメインに対して、紐付けられたIPアドレスを返します。

# ポート番号

`ポート番号`とは、サーバーとアプリケーション間で通信する際に割り振られる番号です。
サーバの中ではたくさんのアプリケーションが同時に動いています。
IPアドレスだけでは、同じサーバーの中でもどのアプリケーションと通信するかを決められません。それを決めるのが`ポート番号`です。
利用する側は、IPアドレスに加えて`ポート番号`を指定することで意図したアプリケーションにリクエストを送ることができます。

Webサーバーをマンションに例えると、IPアドレスは住所の番地まで、ポート番号は部屋番号と考えるとわかりやすいです!
PostgreSQL: security definerは「関数定義者で実行する」という設定である

PostgreSQLは`create function`で関数を定義できます。通常、関数の実行はPostgreSQLに接続したユーザーの権限で行われます。関数定義時に`security definer`を指定すると、この通常の振る舞いではなく、関数の定義者ユーザーの権限で実行されます。

## security definerのユースケース

security definerの使い道としては、あるスキーマやテーブルにはアクセスさせたくないユーザーに対して、特定の操作のときだけそのテーブルなどの使用を認めたい場合です。

例えば、`account`テーブルにはパスワードやメールアドレスが入っていて、一般ユーザーには`select`や`update`をさせたくないとします。しかし、アカウント新規登録は一般ユーザー権限でもできるようにしたい場合があります。こういったケースでは、アカウント新規登録用の関数を、`account`テーブルへのCRUD権限があるユーザーで定義しておくと便利です。

アカウント登録関数の例:


```sql
create function register_author(name text, email text, password text) returns authors as
$$
declare
  author authors;
begin
  insert into authors
    (name)
    values
      (name)
    returning * into author;
  insert into private.account
    (id, email, password_hash)
    values
      (author.id, email, crypt(password, gen_salt('bf')));
  return author;
end;
$$ language plpgsql strict
                    security definer
```
ぼくたちのKotlinにはonEachがある

#Javaでたまに見る
```java
List<Something> updated = list.stream().map(ele -> {
    ele.setFoo("bar");
    return ele;
}).collect(Collectors.toList());
```
なるほど、
1. listの各要素のプロパティを更新
2. **変更後の要素そのもの**を格納したリストを返す
ということがやりたい訳ですね。

**...コットリ～～～～～ン！！！！！！！**
# KotlinにはonEachがある
```kotlin
val updated = list.onEach{ ele -> ele.setFoo("bar") } // { it.setFoo("bar") } でもイケる
```
####Kotlinの世界に来たら１行や！！
**onEach** は返り値ナシ相当の `forEach` とは違い、実行後にメソッド呼び出し元のcollectionのインスタンス(の参照)を返してくれます。**ｽｺﾞｲ･ｽﾃｷ**


#####Kotlinにもmapはある

Kotlinの世界にはおなじみの `map` メソッドもあります。
実行後にlistを返してくれるという点では `onEach` と同じ…ですが、引数に渡したlambdaの実行結果が集計される(javaのstream.mapと同様)ので、onEachと同じ結果を得るにはやはり迂回が要ります。

```kotlin
// 参考：(kotlin) onEachを使わずに同等の結果を得る
val updated = list.apply{ map{ ele -> ele.setFoo("bar") } }
// ...または
val updated = list.apply{ forEach{ ele -> ele.setFoo("bar") } }
```

**javaよりはスマート**に書けますが、onEachがある以上この**例のような書きどころはまず無さそう**です。
`apply` はあらゆる変数に付加できる[Kotlin特有の関数](https://developer.android.com/courses/kotlin-bootcamp/overview?hl=ja)です。引数に渡したlambda(例でいう {} 内のロジック)の実行後、もともとの変数と同じ参照を返します。

※上記のforEachを使った例では、IDEに[IntelliJ](https://www.jetbrains.com/ja-jp/idea/)を利用なら**”onEachを使え”**と怒られます(mapを使うとスルーなのは謎)

# Kotlinは爽快
**Kotlin**は学習中の身ですが、痒い所に手が届く構文・APIが数多く用意されていて **『書いていて楽しい』** です。私が元々Javaのコード書きだったせいか、ひとつひとつの言語仕様にすごく、納得感に似た心地よさを覚えます。
[Google提供のしっかりしたBootcamp](https://developer.android.com/courses/kotlin-bootcamp/overview?hl=ja)もあるので、ちょっと触ってみたいかも…という方は是非。
PostGraphile: クエリー名をシンプルにする方法

[PostGraphile](https://qiita.com/suin/items/b4c5526ec9884a4031bc)で、GraphQLのクエリー名をシンプルにする方法です。次の図のようになります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/c740fe6d-c567-8e33-cd4c-0a61cd1b8884.png)

## PostGraphileのクエリー名をシンプルにする方法

PostGraphileでクエリー名をシンプルにするには、`@graphile-contrib/pg-simplify-inflector`プラグインを使います。

https://github.com/graphile/pg-simplify-inflector

まず、このプラグインをインストールします:

```bash
yarn add @graphile-contrib/pg-simplify-inflector
```

そして、postgraphileを起動するときに次のCLIオプションを指定して、このプラグインを使うようにします。

```bash
--append-plugins @graphile-contrib/pg-simplify-inflector

# 起動例
pnpx postgraphile \
  --connection postgres:///postgres \
  --append-plugins @graphile-contrib/pg-simplify-inflector
```

これで、GraphQLのクエリー名がシンプルになります。

ちなみに、このプラグインを使うのは[推奨されている](https://www.graphile.org/postgraphile/usage-cli/#recommended-options)ようです。
【Android】Jetpack ComposeでAdMobのバナー広告を表示する

Jetpack Composeを使ったアプリで、[AdMobのバナー広告](https://developers.google.com/admob/android/banner?hl=ja)を表示する方法です。

↓のような感じで、画面下部にバナーを表示します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/fa7bae73-0fcd-9073-3590-cca953835815.gif" width=250 />

# :file: コード

現時点（2021/08/13）では、Jetpack Compose用に用意されたAdMobのバナー広告（ `AdView` ）はなさそうなので、 `AndroidView` を使って対応しています。
（既存のViewも使えるので `AndroidView` 便利ですね :relaxed:）

```kotlin
@Composable
fun SampleScreen() {
    Scaffold {
        Column {
            // 適当にリストを作成
            LazyColumn(
                modifier = Modifier.weight(1F),
            ) {
                items(100) { item ->
                    Text("item: $item")
                    Divider(thickness = 0.8.dp)
                }
            }

            AndroidView(
                modifier = Modifier.fillMaxWidth(),
                factory = { context ->
                    val adView = AdView(context)
                    adView.adSize = AdSize.BANNER
                    adView.adUnitId = "ca-app-pub-3940256099942544/6300978111" // テストID
                    adView.loadAd(AdRequest.Builder().build())
                    adView
                },
            )
        }
    }
}
```

# :bulb: ポイント
1. `AndroidView` の `modifier` に `Modifier.fillMaxWidth()` を指定することで、横幅いっぱいになるようにします。（ `AdSize.Banner` の場合は余白が出来てしまいます。）
1. `AndroidView` の `factory` で `AdView` を生成します。 `AdView` には `Context` が必要ですが、 `factory` で `Context` が渡ってくるので、それを使えばOKでした。

※ `factory` の部分は、 `apply` を使うとちょっとスッキリ書けそうな感じはあります。

```kotlin
AndroidView(
    modifier = Modifier.fillMaxWidth(),
    factory = { context ->
        AdView(context).apply {
            adSize = AdSize.BANNER
            adUnitId = "ca-app-pub-3940256099942544/6300978111" // テストID
            loadAd(AdRequest.Builder().build())
        }
    },
)
```

# :muscle_tone1: その他
[アダプティブ バナー](https://developers.google.com/admob/android/banner/adaptive?hl=ja)を表示することも可能でした。（アダプティブ バナーなら左右の余白がなくなりました。）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/12e2a2ea-8b28-3669-df35-05f6e28d73b9.png" width=250 />

```kotlin
AndroidView(
    modifier = Modifier.fillMaxWidth(),
    factory = { context ->
        val adView = AdView(context)
        val displayMetrics = Resources.getSystem().displayMetrics
        val width = (displayMetrics.widthPixels / displayMetrics.density).toInt()
        adView.adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, width)
        adView.adUnitId = "ca-app-pub-3940256099942544/6300978111" // テストID
        adView.loadAd(AdRequest.Builder().build())
        adView
    },
)
```

`DisplayMetrics` から `width` を計算して、`AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize` メソッドを使ってサイズを取得している感じです。
[React]Contextという仕組みについて

# Contextとは
使い所によって少し意味は変化するのですが、、

- Propsを利用せずに様々な階層のコンポーネントに値を共有するReactの仕組み
- Propsを利用せずに様々な階層のコンポーネントに値を共有するReactのAPI
- Contextオブジェクトのこと
- Contextオブジェクトの値のこと

のいずれかを指します。

## Contextを使うために
Contextを利用するには、3つの要素が必要なので、一つずつ見ていきましょう。

### Contextオブジェクト
Contextオブジェクトとは、`React.createContext`というReactのAPIの戻り値のことです。

以下の例で言うと、MyContextがContextオブジェクトになります。
ここで保持した値がProviderで共有できます。

```react
const MyContext = React.createContext();
```

### Provider
Providerとは、Contextオブジェクトが保持しているコンポーネントのことです。
以下の例で言うと、MyContext.ProviderがProviderコンポーネントがProviderになります。

```react
// ここで使用するフックをインポートしておく
import React, { createContext } from 'react';

// Contextオブジェクトを生成する
const MyContext = createContext();

export default function App() {
  const name = 'Tanaka';

  return (
    <div>
      { // valueプロパティの値を共有する }
      <MyContext.Provider value={name}>
        { // Providerでラップされているのでvalueプロパティの値を取得できる }
        <Child />
      </MyContext.Provider>

      { // Providerでラップされていないのでvalueプロパティの値を取得できない }
      <Brother />
    </div>
  );
}
```

### Consumer
Consumerとは、Contextオブジェクトから値を取得しているコンポーネントのことです。

```react
// ここで使用するフックをインポートしておく
import React, { createContext, useContext } from 'react';

// Contextオブジェクトを生成する
const MyContext = createContext();

// MyContextから値を取得しているのでこれはConsumer
function Child() {
  // MyContextの中にはnameが入っている
  const text = useContext(MyContext);
  return <h1>{text}</h1>;
}

export default App() {
  const name = 'React';

  return (
    <MyContext.Provider value={name}>
      { // Providerでラップされているのでvalueプロパティの値を取得できる }
      <Child />
    </MyContext.Provider>
  )
}
```

## 利用するメリット
- グローバルなstateを作成できる
    - どのコンポーネントからでもアクセス可能なstateを作成できるので、複数のコンポーネントで共通利用するデータなどを渡すのに便利
- Prop drilling問題を解消できる
    - Reactの「単方向データフロー(高い階層のコンポーネントから一方向にデータを流す)」と言う原則があるため、この問題が発生しやすいが、利用することで解消できる
【Ruby on Rails】指定した日の記録（投稿数）を非同期で検索する方法


#対象者

* 検索機能をransackなしで実装したい方
* 検索を非同期通信で行いたい方


#目的

* 非同期で検索結果を作成する

#実際の手順と実例
###1.前提

* Rails 5.2.5
* userコントローラーにsearchアクション加えることで実装
* 本(bookモデル)とUserモデルを実装済
* アソシエーション設定(ユーザー：本 = 1：N)
* 本の一覧ページに検索結果を表示

イメージこんな感じ

![スクリーンショット 2021-07-27 16.41.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/64d932b6-5f25-15ee-830f-af46a15c4e31.png)

###2.Controllerとルーティングの設定

Userコントローラーに下記を追記します


````Users_controller.rb
#一部抜粋
  def search
    @user = User.find(params[:user_id])
    @books = @user.books 
    @book = Book.new
    if params[:created_at] == ""
      @search_book = "日付を選択してください"#①
    else
      create_at = params[:created_at]
      @search_book = @books.where(['created_at LIKE ? ', "#{create_at}%"]).count#②
    end
  end
````

①if文で分岐させて空欄なら日付を選択するように表示します
②.countメソッドで検索してヒットした本を投稿した日付の投稿数を@search_bookで定義します。


ルーティングは下記の通り

```routes.rb
resources :users, only: [:index, :show, :edit, :update] do
    get "search", to: "users#search"
  end
```

ユーザーを親要素としてネストさせてます。

###3.Viewの設定

ここでは本の一覧ページに表示します。

````index.html.erb

<%= form_with url: user_search_path(@user), method: :get do |f| %>
  <%= f.date_field :created_at %>　#①
  <%= f.submit '検索', class: 'btn btn-primary'  %>
<% end %>

<div id="search_result"> #②
  <% if @search_book.present? %>
    <%= render 'search', search_book: @search_book %>　#③
  <% end %>
</div>

````
①このフィールドで年/月/日が表示されます
②これでjsファイルを呼び出します。
③検索結果を部分テンプレート化しています。

検索結果は以下の通り
Usersフォルダ内に_search.html.erbを作成してます

```app/views/users/_search.html.erb
<h4>検索結果</h4>
  <table class='table table-bordered'>
    <thead>
      <tr> 
        <th>投稿数</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><%= search_book %></td>
      </tr>
    </tbody>
  </table>
```

###4.非同期通信設定

Viewで設定したsearch_resultを呼び出します

````app/views/users/search.js.erb
$("#search_result").html("<%= j(render 'search', search_book: @search_book) %>");
````

これで実装完了です。


####投稿者コメント

これcount以外もできるかなと挑戦するために、
まず、手順思い出そうと思ってアウトプットしてみました。

####My Profile
プログラミング学習歴３ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。
PostGraphileでGraphiQLのExplorerを表示するには「--enhance-graphiql」オプションをつける

[PostGraphile](https://qiita.com/suin/items/b4c5526ec9884a4031bc)には、GraphiQLが付属しています。この投稿では、そのGraphiQLでExplorerを使えるようにする方法を説明します。


## `--enhance-graphiql`オプションをつけて起動する

PostGraphileを起動するときに、`--enhance-graphiql`オプションを指定すると、GraphiQLのExplorerが出るようになります。

```bash
pnpx postgraphile \
  --connection postgres:///postgres \
  --enhance-graphiql
```

![PostGraphileでGraphiQLのExplorerが表示される様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/5d7deb32-cd07-c89e-97d2-1ccf557f54cc.jpeg)
応用情報技術者試験　午前問題で回答に迷った時に当たる確率の高い選択肢をElasticsearchとKibanaで可視化してみた

今年の秋の応用情報技術者合格に向けてお勉強中です。

しかし、過去問題を解いていても全く知らない言葉や、やる気のでない計算問題など、敵は多いです。

当然ながら、これらについては暗記をしたり計算方法をしっかり勉強するべきなのは分かっています。

しかし、本番でもうどうにもわからん！となった時に、何を選べば当たる確率が高いのかを分析してみようと思います。

お勉強の息抜き的な感じですが、何の根拠もなく「迷ったらアで固定だぜ！」みたいにするよりはいいかなぁと思って作ってみました。

# 環境

* Windows10 + Docker 
* Elasticsearch 7.1.1 + kibana 7.1.1

なんで7.1.1を選択したかというと、kibana上からjsonファイルやcsvファイルをElasticsearchにインポート出来るんですよね。

サーバログを監視するとか実業務ではlogstashで組んで自動化するべきなのですが、例えば家で家計簿代わりに使うなどの手段であれば、ブラウザ上で完結するので便利かと思います。

# 今回のソース

* IPAホームページに公開されている応用情報技術者試験午前問題の過去3回分の回答をインポートデータに設定しました。
* 単純なカンマ区切りファイルにしました。
* 文字コードはUTF-8に設定しました。（SJISだと文字化けしちゃいました。）

# ズバリ何を選べば当たる確率が高いの？

過去三回の試験結果を元にすると、 「ウ」 を選択するのが一番よさそうです。

![ouyou003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620300/5d5fc385-0a32-b7f8-47ec-3a5370bc7710.png)
 ウ：69回  エ：63回  ア：55回  イ：53回

試験分野別に見てみましょう。

---

テクノロジ系
![ouyou004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620300/a2fcc387-c335-9e69-34b1-e9862294f778.png)
これも「ウ」が多いですね。

---

ストラテジ系
![ouyou005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620300/3f0bf02a-924d-6c93-dfe2-b710c4672668.png)
これは「エ」が多い傾向です。

---

マネジメント系
![ouyou006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620300/a40afa01-ade4-c632-cf11-c289906d52df.png)
こちらも「ウ」が多いですね。

# まとめ

迷ったら「ウ」か「エ」を選ぼうと思います。

二択くらいまで絞れたら更に可能性が高まると思います。

しかし、こんな事に時間を使っていないで過去問を解いて勉強をしたほうが良いですね。

---

##### 免責事項

本内容はあくまでも投稿者本人の個人的な分析、意見であり、次回の情報技術者試験の回答傾向にも必ず当てはまることを保証するものではございません。
また本内容のコンテンツ・情報について、できる限り正確な情報を提供するように努めておりますが、正確性や安全性を保証するものではありません。
掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。
閏年の判定方法について

こんにちは！
前回「『閏年判定アプリ』を作った」にて
`new Date()`を使用した判定方法をコメントで教えていただきました。
時間が関係する処理を書くとき、何かと閏年の判定は必要になると思うのでメモとしてここに残します。

<b>詳しくは　[前回記事](https://qiita.com/huwg2787x/items/c3265f89d0f9ff74e155)　のコメント欄をご参照ください。</b>

<hr>

まず一般的な方法として

```javascript
const isLeapYear = year => year%4 === 0 && year%100 !== 0 || year%400 === 0;
```

という方法があります。
<b>年数が　４で割り切れて　かつ　１００で割り切れない　または　４００で割り切れる</b>
閏年の定義をそのまま当てはめて、判定する方法です。

<hr>

それとは異なり`new Date()`を使用した方法は以下のようになります。

```javascript
const isLeapYear = year => new Date(year, 1, 29).getDate() === 29;
```

<b>`new Date()`に変数yearと２月の２９番目を指定し、それが存在する場合29を返すのでtrueになるという方法です。</b>

確認してみましょう。
閏年の場合

```javascript
const 閏年です= new Date(1996, 1, 29).getDate();
console.log(閏年です);
```
出力結果
![uiop.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820236/4cab1e3c-d3d6-39ba-b4df-34cb5273a595.jpeg)

閏年でない場合

```javascript
const 閏年ではありません= new Date(1995, 1, 29).getDate();
console.log(閏年ではありません);
```
出力結果
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820236/eda3097a-253a-1907-8c20-84c0e5989aca.jpeg)
２９と厳密等価演算子で結ばれるのは閏年の場合だけというのがわかりました。

<hr>
ちなみに`new Date()`を使用した方法には別の書き方もあります。


以下の記事を参照にしました。
[JavaScriptで｢うるう年｣の判定はnew Date(y, 2, 0)を使用する](https://iwb.jp/javascript-leap-year-function-new-date/)

```javascript
const isLeapYear = year => new Date(year, 2, 0).getDate() === 29;
```

どちらも２月の２９日を確認しています。３月０番目を設定して２月２９日を確認する方法もあるんですね。
ちなみにこちらの場合、閏年の時は２９を返しますが、閏年でない場合は２８を返します。

```javascript
const 閏年ではありません= new Date(1995, 2, 0).getDate();
console.log(閏年ではありません);
```

出力結果
![yuu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820236/d5b31712-379f-984c-e626-b42cd350fa56.jpeg)
気を付けたほうがよさそうですね。
基礎⑥〜関数について〜　php

#はじめに

関数の作り方について書いてみる。

#内容

##関数とは

プログラミングにおける関数は、実行したい一連の処理をまとめ、機能を表わす名前をつけて定義したものであり、プログラム中で関数を呼び出すと、関数に記述された処理を実行して呼び出し元に戻る。
　関数の書き方や形式は、プログラミング言語によって異なるが、一般に引数（ひきすう）を使って呼び出し元から関数に情報を渡し、戻り値（もどりち）や引数で関数から呼び出し元に処理の成否や結果を返すことができる。

　C言語や PHP など多くのプログラミング言語で、処理内容を「関数」として記述し、関数でプログラムを構成する。汎用性のある機能群は、標準関数として標準ライブラリに提供されている。

参考：https://edu.clipper.co.jp/wd-43.html

例：

```php
echo strlen ('ringo');

//結果：5
```

上の例を説明すると

・strlenという関数をしようしています。これは文字列の文字数を返す組み込み関数です。
・その後ろの('ringo')が引数となります。引数は変数を入れることもできます。
・そして('ringo')の文字数が結果として５となります。

#まとめ
定義をしてその呼び出しを実行するものなので、どんな関数があるかを把握することで効率化を測れる
PhoenixでのLocale・言語設定の実装

# 概要
こちらの記事が参考になり、要所をまとめました。

https://lokalise.com/blog/localization-of-phoenix-applications/

# 実装
## Localeを定義する

```elixir
config :appname,
  AppnameWeb.Gettext,
  locales: ~w(en ja),
  default_locale: "ja"
```

```bash
mix gettext.extract
mix gettext.merge priv/gettext
mix gettext.merge priv/gettext --locale ja
```


```
$ mix gettext.merge priv/gettext
Wrote priv/gettext/en/LC_MESSAGES/errors.po (0 new translations, 0 removed, 21 unchanged, 0 reworded (fuzzy))

$ mix gettext.merge priv/gettext --locale ja
Created directory priv/gettext/ja/LC_MESSAGES
Wrote priv/gettext/ja/LC_MESSAGES/errors.po (21 new translations, 0 removed, 0 unchanged, 0 reworded (fuzzy))

```

```html
<h2><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h2>
```

```priv/gettext/default.pot
## This file is a PO Template file.
##
## `msgid`s here are often extracted from source code.
## Add new translations manually only if they're dynamic
## translations that can't be statically extracted.
##
## Run `mix gettext.extract` to bring this file up to
## date. Leave `msgstr`s empty as changing them here as no
## effect: edit them in PO (`.po`) files instead.
msgid ""
msgstr ""
#, elixir-format
#: lib/lokalise_demo_web/templates/page/index.html.eex:2
msgid "Welcome to %{name}!"
msgstr ""
```


```priv/gettext/en/LC_MESSAGES/default.po
# ... some other stuff goes here ...
#, elixir-format
#: lib/lokalise_demo_web/templates/page/index.html.eex:2
msgid "Welcome to %{name}!"
msgstr "Вас приветствует %{name}"
```

# Localeを切り替える

### パッケージをインストールします

https://github.com/smeevil/set_locale#setup

こちらのREADMEに記載されていることを実施します。

Add set_locale to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [{:set_locale, "~> 0.2.1"}]
end
```

Ensure set_locale is started before your application:

```elixir
def application do
  [applications: [:set_locale]]
end
```


### router.exファイルに新しいプラグを追加します

```elixir
defmodule MyApp.Router do
  use MyApp.Web, :router

  pipeline :browser do
    plug :accepts, ["html"]
    ...
    # cookie_key and additional_locales are optional
    plug(SetLocale,
      gettext: MyApp.Gettext,
      default_locale: "en",
      cookie_key: "project_locale",
      additional_locales: ["ja"]
    )
  end
```


## LocaleをCookieに保存する

```elixir
def call(%Plug.Conn{params: %{"locale" => locale}} = conn, _options) when locale in @supported_locales do
  LokaliseDemoWeb.Gettext
  |> Gettext.put_locale(locale)
  
  conn
  |> put_resp_cookie "locale", locale, max_age: 365*24*60*60
end
```

ref:
https://github.com/smeevil/set_locale#setup


## Localeを制御
下記の実装で言語設定を切り替えます。

```elixir
defmodule LokaliseDemoWeb.LayoutView do
  use LokaliseDemoWeb, :view
  def new_locale(conn, locale, language_title) do
    "<a href=\"#{page_path(conn, :index, locale: locale)}\">#{language_title}</a>" |> raw
  end
end
```

```html
<body>
  <div class="container">
    <header class="header">
      <%= new_locale @conn, :en, "English" %>
      <%= new_locale @conn, :ru, "Russian" %>
    </header>
    <!-- other stuff -->
  </div>
</body>
```



ref:
https://lokalise.com/blog/localization-of-phoenix-applications/
59日後にITパスポートを受けるFラン私大文系既卒(16日目)

# OS(Opning System)
* OSとは?
 * ソフトウェアの一つ
 * アプリケーションソフトウェアとハードウェアをつなぐもの

# マルチタスク
* マルチタスクとは?
 * 複数のプロセスを頻繁に素早く切り替えることによって、同時に処理しているように見せる機能
 * OSがCPUを操作することで実現する

# BIOS(Basic Input Output System)
* BIOSとは？
 * PCの初期設定をするソフトウェア
 * OSが立ち上がるよりも先に起動する

# データ管理
* データ管理とは?
 * コンピュータが処理するデータを管理する機能
 * ファイルシステムやバックアップなど

# ファイルシステム
* ファイルシステムとは?
 * データのまとまりをファイルとして扱うことで、データを管理しやすくする機能

# バックアップ
* バックアップとは?
 * 通常使用している補助記憶装置とは別の補助記憶装置上にデータの複製を取っておくこと
* バックアップの種類
 * フルバックアップ
 * 差分バックアップ
 * 増分バックアップ

# フルバックアップ
* フルバックアップとは?
 * 常にすべてのデータをバックアップすることです
* メリット
 * 全部バックアップしてあるから、切り替えるのが楽
* デメリット
 * 時間がかかる

# 差分バックアップ
* 差分バックアップとは?
 * フルバックアップ以降、新たに追加されたデータをバックアップすること
* メリット
 * バックアップをとる時間が短い
* デメリット
 * 復旧作業が楽  

# 増分バックアップ
* 増分バックアップとは?
 * 前回のバックアップから新たに追加されたデータをバックアップすること
* メリット
 * 差分バックアップよりも速い
* デメリット
 * 復旧作業が、差分バックアップよりも大変  

# レプリケーション
* レプリケーションとは?
 * データの複製(複製)を別のコンピュータ上に作成して、リアルタイムで内容を同期すること

# アーカイブ
* アーカイブとは?
 * データを保管庫(アーカイブ)にコピーして長期間保存すること

# 表計算ソフト
* 表計算ソフトとは?
 * 表に書き込まれた数値の計算をするソフトウェア

# 絶対参照
* 絶対参照とは?
 * 固定された参照のこと

# 相対参照
* 相対参照とは?
 * 固定されていない参照のこと

# ユニバーサルデザイン
* ユニバーサルデザインとは?
 * できるだけ多くの人が利用できることを目指したデザイン

# アクセシビリティ
* アクセシビリティとは?
 * 高齢者や障害者を含む、すべての人がサービスを制限なく使える度合い

# ユーザビリティ
* ユーザビリティとは?
 * 利用者がストレスを感じずに、目標とする要求を達成できる度合い

# オープンソースソフトウェア
* オープンソースソフトウェアとは?
 * ソースコードが公開されていて、改良や再配布が自由に行えるソフトウェア
windowsコマンドのmakecabメモ

makecabのヘルプオプションは英語表記で分かりにくいし、インターネット上の情報も少なかったので、ここで試行錯誤のメモを残す。

#### makecabで圧縮したcabファイルをexpandで展開したときのエラー0x80070032
```
c:\>expand hoge.cab -F:* .
Microsoft (R) File Expansion Utility
Copyright (c) Microsoft Corporation. All rights reserved.


ファイル hoge.cab の解凍は完了していません。エラー コード = 0x80070032
エラーの説明: この要求はサポートされていません。
```
【原因】
どうやらmakecabが出力するcabファイルのサイズの初期値はそれほど大きくないらしい。
合わせて数M程度のファイル群であっても、規定サイズを超えた部分を切り捨てたcabファイルを作り、これをexpandしようとしてもファイルが変だよと0x80070032を返した模様。

【対策】
MaxDiskSize変数で最大値を指定する。
 makecab /D MaxDiskSize=1024000000
とコマンドラインのDオプションで指定してもよいし、
ddfファイルを使うならば、その中に
 .Set MaxDiskSize=1024000000
と書いてもいい。


#### ファイル階層構造の指定の仕方。
ddfファイルを使う。
例えば、
uno\dos\tres.dll
uno\cuatro\cinco.inf
uno\seis ciete\ocho.exe
という階層構造のファイルを圧縮し、解凍したら再現したい場合。

```
.Set DestinationDir=uno\dos
uno\dos\tres.dll
.Set DestinationDir=uno\cuatro
uno\cuatro\cinco.inf
.Set DestinationDir="uno\seis ciete"
"uno\seis ciete\ocho.exe"
```
DestinationDir変数で作成して欲しいフォルダ名を指定する。
スペース等が入ったパスの場合は、例のごとくダブルクォテーションで囲う。


#### setup.infとsetup.rtn（makecabの実行ログ）
makecabを実行するとデフォルトではsetup.infとsetup.rtnを出力する。
これを抑止するにはRptFileName、InfFileName変数を使う。
コマンドラインであれば
  /D RptFileName=NUL /D InfFileName=NUL
DDFファイルであれば
  .Set RptFileName=NUL
  .Set InfFileName=NUL
など。
そもそもmongoDBの拡張子「.wt」とは？

「.wt」の「wt」とは、**WiredTiger**の略称。

**WiredTiger**とはmongoDBでアプリケーションとストレージの間でデータの読み書きを行うストレージエンジンのこと。[^1]
[^1]: https://www.slideshare.net/tetsutarowatanabe/wired-tiger-79913237
**MongoDB 3.2では、WiredTigerがデフォルトのストレージエンジン**[^2]である。
[^2]: https://docs.mongodb.com/manual/core/wiredtiger/
<br />
MongoDBで設定ファイルを調べているうちに見たことない拡張子が目に入って気になったので、調べてみました。
MongoDBデフォルトのストレージエンジンであるWiredTigerがデータを読み書きするときに使っている（データそのもの？）ファイルということで、現状では特に気にしなくてよいことがわかりました。
ESXi Arm Edition version 1.5 — JAug 6, 2021 の登場

VMware Flings で提供されている、ESXi Arm Edition の最新版、ESXi Arm Edition version 1.5 Build 18427252 が公開されました。
詳細はこちらのブログに書きました。
[ESXi Arm Edition version 1.5 — Aug 6, 2021 の登場](https://imaisato.hatenablog.jp/entry/2021/08/13/091137)
Codesandboxの動作がおかしくなった際の対応


Codesandboxはすごくいいサービスですが、なんか時々動作が不安定になることがあり残念だなーと思っていました。

>安定すれば有償コース申し込むのに・・・といつも思ってます。

## おかしくなる現象

Codesandboxではソースを変更しSaveすると即座に結果が反映されます。が、時折、それが行われなくなり、一度そうなってしまうと後は何をしてもうんともすんとも言わない状態になります（プロジェクトを捨てるしかない）。

> Node.js系かつプロジェクト名称を変更した際に多い気がします。


## 動かなくなった際の対応

ずっと放置していたのですが、本家のissuesに対症療法的解決案っぽいのがあり、それを試したところ動いたのでメモしておきます。

* 参考にした元記事
  * https://github.com/codesandbox/codesandbox-client/issues/4381
  *

私なりの検証情報を付け加えてまとめると

* codesandbox.ioにアクセスしている状態でApplicationのStorageを消す（記事通り）
* 一度codesandboxをログアウトする（認証エラーが出るので）
* 再度ログインし、利用する

とすることでなんとかコードの変更が反映されるようになりました。
Codesandboxはローカルにもいろいろ情報を保持しているようで、それと矛盾が発生するとおかしくなるのかもしません。
【Android】Jetpack DataStoreのproguard設定（Proto DataStore編）

[Jetpack DataStore](https://developer.android.com/topic/libraries/architecture/datastore) の **Proto DataStore**（`androidx.datastore:datastore`）を使ったアプリで、難読化を有効にした場合にクラッシュが発生したので、proguard設定をメモがてら記載したいと思います。

※ エラーの内容は下記で、いかにも難読化の設定が不十分っぽい感じがしました。

```
java.lang.RuntimeException: Field showCompleted_ for e1.a not found. Known fields are [public boolean e1.a.i, public int e1.a.j, public static final e1.a e1.a.k, public static volatile k2.a1 e1.a.l]
```

# proguard設定
下記の内容を、proguardに記述すればOKでした。

```proto
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
    <fields>;
}
```

※ protobuf-javaの内容を参考にしました。
https://github.com/protocolbuffers/protobuf/blob/8a3c4948a49d3b38effea499fd9dee66f28cb0c4/java/lite/proguard.pgcfg

# （解説）
Proto DataStoreの場合、Protocol buffersを利用して保存用クラス（ `GeneratedMessageLite` を継承したクラス）が生成されます。
難読化を有効にすると、保存用クラスも難読化され読み込みに失敗するようなので、前述したproguardの記述を行うことで、保存用クラスが難読化されるのを防ぐ形となっています。
【画像処理解説】判別分析法（Javaソース付き）

#はじめに
画像処理を簡単に解説していきます。
下部にはJavaでのソースコードも載せているのでぜひご参照ください。
不定期にはなりますが、随時更新していく予定です。

#判別分析法とは？
二値化のしきい値を自動で決める手法の一つです。
別名として大津の二値化という名称もよく知られています。

どういう方法かというと、二値化した時の画像の白黒のバランスが良くなるように計算します。
具体的には白画素領域と黒画素領域のクラス内分散を小さく、かつ、クラス間分散を大きくするようにしてくれます。
画像ヒストグラムを想像するとわかりやすいと思います。

#画像ヒストグラムとは？
画像ヒストグラムとは画像内の画素数を、画素値ごとにカウントしたグラフです。
グレースケール画像の場合、横軸が0から255になり、縦軸がそれぞれの画素数です。
つまり、山が右寄りなら明るい画像、左寄りならば暗い画像となります。
これを知っていると、イメージがしやすくなるので覚えておくことをお勧めします。

二値化というのは、画像ヒストグラム状に一本の縦線を引くという処理です。
引いたうえで、線の左は黒、右は白にしてしまうというわけです。
判別分析法では、この縦線を引く個所を最適になるように計算してくれるのです。

#判別式はどんな式なの？
判別式は、判別分析法で用いられる評価式です。
判別式が最大となるときのしきい値が最適なしきい値として採用されます。

実際の式としては以下の通りです。
導出過程を載せると長くなりますので、最終的な式だけ載せます。
途中式を見たい方はちょっと調べればすぐに出てくると思います。

$\sigma = \frac{黒画素数}{全画素数} × \frac{白画素数}{全画素数} × \left(\frac{黒領域の画素値合計}{黒画素数}-\frac{白領域の画素値合計}{白画素数}\right)^2$

#アルゴリズム
1. カラー画像はグレースケール変換する。
2. しきい値と最大判別式を保存する変数を用意する。
3. しきい値を1から255まで移動しながら、4から9の処理を行う。
4. 判別式計算用の変数（画素数合計、画素値合計）を初期化する。
5. グレースケール画像をラスタスキャンし、各画素に対して6と7の処理を行う。
6. 画素のグレー値を取得し、3のしきい値より大きければ白を、そうでなければ黒とする。
7. 6で求めた色に応じて、4で用意した合計変数をカウントアップする。
8. ラスタスキャン後、前述の判別式を4の変数を用いて計算する。
9. 8で求めた判別式が、2で作成した最大判別式より大きければ、しきい値と最大判別式を更新する。
10. 3のループが終了後に得られた最適なしきい値で二値化する。

#判別分析法による二値化の例
元画像（グレースケール画像）
![out002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655420/2e452324-cec3-2e00-9c94-28f85312b75d.png)

結果画像（二値化画像）
![out004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655420/ba777b55-ef6e-ea94-94a4-7379c94440ea.png)

#ソースコード
画像がグレースケールであることの判定なども入れるべきなのですが、複雑になると考えたので省略しています。
また、高速化などは一切入れていないので、処理は早くないのであらかじめご了承ください。

```Color.java
public static SImage discriminantAnalysisMethod(SImage grayImg) {
    // グレースケール画像でない場合、まずグレースケール変換する
    if (grayImg.channel != 1)
        return discriminantAnalysisMethod(toGray(grayImg));

    // しきい値
    int threshold = 0;

    // 判別式の最大値
    double sigmaMax = Double.MIN_VALUE;

    // 暫定しきい値tを1から255まで移動
    for (int t = 1; t <= 255; t++) {
        // 計算用の変数初期化
        int[] count = {0, 0};
        int[] sum = {0, 0};

        // 画像をラスタスキャン
        for (int x = 0; x < grayImg.width(); x++)
            for (int y = 0; y < grayImg.height(); y++) {

                // グレー値を取得
                int gray = grayImg.getGray(x, y);

                // 暫定しきい値を超えた場合1を、そうでない場合0をインデックスにセット
                int index = gray >= t ? 1 : 0;

                // 計算用の変数を更新
                count[index]++;
                sum[index] += gray;
            }

        // 判別式を用いた更新
        if (count[0] > 0 && count[1] > 0) {
            // 判別式計算
            double sigma = ((double) count[0] / (count[0] + count[1])) * ((double) count[1] / (count[0] + count[1])) * Math.pow((double) sum[0] / count[0] - (double) sum[1] / count[1], 2);

            // 判別式が更新された場合、しきい値を更新
            if (sigma >= sigmaMax) {
                sigmaMax = sigma;
                threshold = t;
            }
        }
    }

    // 計算結果のしきい値で二値化
    return binarize(grayImg, threshold);
}
```
arduinoでfdev_setup_stream その2

#概要

arduinoでfdev_setup_streamやってみた。
stdin実装して、scanfやってみた。

#サンプルコード


```
int serial_getchar(FILE * f) {
	int c;
	while (Serial.available() == 0);
	c = Serial.read();
	return c;
}

FILE serial_stdin;

void setup() {
	Serial.begin(9600);
	fdev_setup_stream(&serial_stdin, NULL, serial_getchar, _FDEV_SETUP_READ);
	stdin = &serial_stdin;
	Serial.println("ok");
}

void loop() {
	char str[10];
	scanf("%s", str);
	Serial.println(str);
}


```

以上。
arduinoでfdev_setup_stream

#概要

arduinoでfdev_setup_streamやってみた。
stdout実装して、printfやってみた。

#サンプルコード


```
int serial_putchar(char c, FILE * f) {
	if (c == '\n') 
		serial_putchar('\r', f);
	return Serial.write(c) == 1 ? 0 : 1;
}

FILE serial_stdout;

void setup() {
	Serial.begin(9600);
	fdev_setup_stream(&serial_stdout, serial_putchar, NULL, _FDEV_SETUP_WRITE);
	stdout = &serial_stdout;
	printf("Hello, world!\r\n", NULL);
	printf("data=%d %x %c\r\n", 65, 65, 65);
	printf("data=%d ", 65);
	printf("%x ", 65);
	printf("%c\r\n", 65);
	printf("%05d\r\n", 123);
	printf("%s\r\n", "ok");
}

void loop() {
}

```

以上。
よく間違えるCISCとRISCの違いを説明してみた

<img src="https://itmanabi.com/wp-content/uploads/2018/12/cisc-risc.png">
CISCとRISCは、共にプロセッサ（CPU）の方式です。


CPUについておさらいすると、CPUとはデータの演算や変換などコンピュータの中心的な装置です。

プロセッサ＝CPUではなく、CPUはプロセッサの一種です。

他にも、MPU（マイクロプロセッサ）、マルチコアプロセッサ（プロセッサ内部に複数の処理装置を実装）、DSP（ディジタルシグナルプロセッサ：ディジタル信号に特化したマイクロプロセッサ）などがある。



#CISC(Complex Instruction Set Computer)
・伝統的なCPU方式
・命令ごとに命令の長さが異なる、一つひとつが長い。（可変長）
・高機能命令を実装可能
・命令後のながさがバラバラなので、処理速度は低下する。
・マイクロプログラムで実行


#RISC(Reduced Instruction Set Computer)
・CISCの処理能力の悪さを改善するために提案された。
・極力単純で短い機械語命令だけを実装し、専用の論理回路で高速に実行。
　→パイプライン処理などの処理速度向上技術を実装しやすくなった。
・用意される命令は単純な分プログラミングの手間は増える。
・１命令当たりおよそ1クロックで実行
・レジスターレジスタ間
・ワイヤー度ロジックで命令を実行
[Swift5] FireStoreでカスタムオブジェクトを扱う

# はじめに
[Cloud Firestore](https://firebase.google.com/docs/firestore?hl=ja)にデータを追加する際に、`Codable`を使用したいと思ったところ、サポートされているようなので確認してみました。備忘録です。

>Map または Dictionary オブジェクトを使うとドキュメントを表しにくいことが多いため、Cloud Firestore では、カスタムクラスを使ったドキュメント作成をサポートしています。Cloud Firestore は、オブジェクトをサポートされているデータ型に変換します。

参考: [Cloud Firestore にデータを追加する](https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja)

# 実装方法
以下、[公式ドキュメント](https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja)のコードを引用しています。

```swift
public struct City: Codable {

    let name: String
    let state: String?
    let country: String?
    let isCapital: Bool?
    let population: Int64?

    enum CodingKeys: String, CodingKey {
        case name
        case state
        case country
        case isCapital = "capital"
        case population
    }

}
```


```swift
let city = City(name: "Los Angeles",
                state: "CA",
                country: "USA",
                isCapital: false,
                population: 5000000)

do {
    try db.collection("cities").document("LA").setData(from: city)
} catch let error {
    print("Error writing city to Firestore: \(error)")
}
```
上記コードのように、複雑なデータも綺麗にまとめて追加することができます。
**ここで一点注意が必要です**。
今回、私はプロジェクトにFirestoreをCocoaPodsでインストールしてFirebaseモジュールをインポートしていたのですが、これでは上記のコードにもあるsetData(from:)メソッドは使用できません。
方法としては、まずpodfileに以下を追加します。

```:Podfile
pod FirebaseFirestoreSwift
```
あとは、

```Swift
import FirebaseFirestoreSwift
```

で使用できるようになります。

# 最後に
カスタムなデータ型をFirestoreに追加したいケースは結構ありそうなので役立てば良いなと思います。

# 参考文献
以下の情報を参考にしました
[公式の方法でFirestoreでCodable #firebase #firestore #codable](https://qiita.com/fromkk/items/33357fc6aa90e1098b48)
Not allowed to access vertex data on mesh 'Body' at array index 0


## 問題点: Not allowed to access vertex data

Burstコンパイラなどで、SkinnedMeshの読み取り専用のスナップショットを取得する際に、AcquireReadOnlyMeshDataという関数を以下のように取得するのですが（参考は、Keijiro氏の[Smrvfx](https://github.com/keijiro/Smrvfx) ）、

```
var dataArray = Mesh.AcquireReadOnlyMeshData(meshes)
```

そうすると、

```
InvalidOperationException: Not allowed to access vertex data on mesh 'Body' at array index 0 (isReadable is false; Read/Write must be enabled in import settings)
```

というように、MeshのVertexにアクセスできないと言われます。

## 解決法

この問題は、アクセスしようとしているSkinnedMeshやMeshの元となるFBXファイルの「Read/Write」をオンにすることで解決しました！

![ReadWriteFromScript.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1771055/7f391d5e-b3b2-6613-1aa1-61b2b1d299a8.png)

## 最後に
ぜひ、フォローよろしくお願いいたします！

- [Twitterアカウント](https://twitter.com/supertask_jp)
- [YouTubeアカウント](https://www.youtube.com/c/TasukuTAKAHASHI)
OpenSSLでパスワード作成-Ansibleで設定するパスワードについて-

# Ansibleでパスワードを設定したい
Ansibleでリモートマシンにパスワードを設定したい時、平文で送ってもダメポなので、ここはOpenSSLの力を借りてパスワードを生成して送りつけましょう。
## OpenSSLでのパスワード生成方法
OpenSSLではこのようにすればパスワードが生成できるようです。

```:bash
$ openssl passwd --help
Usage: passwd [options]
Valid options are:
 -help               Display this summary
 -in infile          Read passwords from file
 -noverify           Never verify when reading password from terminal
 -quiet              No warnings
 -table              Format output as table
 -reverse            Switch table columns
 -salt val           Use provided salt
 -stdin              Read passwords from stdin
 -6                  SHA512-based password algorithm
 -5                  SHA256-based password algorithm
 -apr1               MD5-based password algorithm, Apache variant
 -1                  MD5-based password algorithm
 -aixmd5             AIX MD5-based password algorithm
 -crypt              Standard Unix password algorithm (default)
 -rand val           Load the file(s) into the random number generator
 -writerand outfile  Write random data to the specified file
```
とりあえず強度が強そうな SHA512 で作りましょう。

こんな感じ。

```:bash
$ openssl passwd -6
Password: 
Verifying - Password: 
$6$dWEZ1Y/sNA3XMwWh$kyDNas6/gsq7Vy5HaAsWHSEQdXmC5JLrdvH7vckv7gKAfOpP4lJTvVuAc略
```

これでもいいですが、saltで少し遊んでみましょう。
saltの設定方法は

```:bash
$ openssl passwd -6 -salt=salt 
Password: 
$6$salt$RI5GdyZIyW7xvU0UR7.Y0UCl1tjahnVIePvmc/Aynwm5SFRY0JdwGZYc8p8sOYEsmP0zXjAR略
```

となっています。
もう少し遊んでみましょう。

###ちょっと冒険

毎回、saltの値を替えて遊ぶには

```:bash
$ openssl passwd -6 -salt=$RANDOM 
Password: 
$6$16043$86yLt7.CVehA7lWR5H5pA543nLz6U4CzEUwikNQmRRSwvIa0dmOW0O9ICEUqKjSwg3iBG/g略
$ openssl passwd -6 -salt=$RANDOM 
Password: 
$6$25764$yybCGULsCXBn4Iq1P1KIrS2MWimA8ODIpYKwysZxO3xMYxPj1c4QJ/j6YcatEDmFJk6FzImO略
```

これで多少のことでは破られない…はず。

### Ansibleで使う

あとはこれを、ansibleのplaybookにいれます。こんな感じ。

```ansible:main.yml

- name: adduser(user1)
# password generate via "openssl passwd -6 -salt=$RANDOM "
  user:
    name: user1
    uid: 1001
    state: present
    password: $6$16502$1uE67kAZsw9S06fTsFpOkiZimfT.Dkc6/RHRB8u4TaR4ZPzJWWAL232gy略
    comment: Nanashino Gonbei
```

以上でございます。
MacでSoftEtherに接続する時の面倒なコマンドをexpectで自動化し、一つのコマンドで接続できるようにしてみた

# はじめに

最近、自宅の回線がIPv6に対応したことにより、今まで使用していたVPNの接続方法が利用できなくなってしまいました。

ついては、他に方法がないかなと探していたらSoftEther VPNが良さそうだということでこちらを利用することに。

https://ja.softether.org

しかし、Macで使用するには接続と切断に少々面倒なコマンドを入力せねばならず、使い勝手が悪い。

ということで、これを簡単にする方法を以下にまとめます。

# 必要なもの

- SoftEther VPN
- expect

expectについては以下をご参照下さい。
https://qiita.com/Mskmemory/items/013dff1a76e58fcdc364

# 接続

以下のスクリプトを作成。

```sh:connect.sh
#!/usr/bin/env bash

sudo /usr/local/vpnclient/vpnclient start

expect -c "
  set timeout 2
  
  spawn /usr/local/vpnclient/vpncmd
    
    expect \"1 - 3 を選択:\"
    send \"2\n\"
    
    expect \"IP アドレス:\"
    send \"\n\"
    
    expect \"VPN Client>\"
    send \"AccountConnect\n\"
    
    expect \"接続設定の名前:\"
    send \"[各自の接続名]\n\"
    
    expect \"VPN Client>\"
    send \"exit\n\"

  interact
"
```

実行権限を付与。

```sh:
chmod a+x connect.sh
```

実行。

```sh:
./connect.sh
```

# 切断

```sh:disconnect.sh
#!/usr/bin/env bash

expect -c "
  set timeout 2
  
  spawn /usr/local/vpnclient/vpncmd
    
    expect \"1 - 3 を選択:\"
    send \"2\n\"
    
    expect \"IP アドレス:\"
    send \"\n\"
    
    expect \"VPN Client>\"
    send \"AccountDisconnect\n\"
    
    expect \"接続設定の名前:\"
    send \"[各自の接続名]\n\"
    
    expect \"VPN Client>\"
    send \"exit\n\"

  interact
"

sudo /usr/local/vpnclient/vpnclient stop
```

実行権限を付与。

```sh:
chmod a+x disconnect.sh
```

実行。

```sh:
./disconnect.sh
```

できた！
[Swift5] セルの選択状態をカスタムする

# はじめに
UITableViewCellを使用しているときなどに、選択状態によって背景色やセル上のviewの表示/非表示を切り替えたいときがあると思います。
便利なメソッドがあるのでご参考までに。
内容が間違っていたり、もっと便利なやり方があればぜひ教えていただけると幸いです。

#実装方法
結論、[setSelected(_:animated:)](https://developer.apple.com/documentation/uikit/uitableviewcell/1623255-setselected)を使用するだけです。
以下のコードは、カスタムなUITableViewCellの選択状態によって背景色とラベルの表示/非表示を切り替えています。
selectedプロパティがセルの選択状態を持っているので、簡単に処理を切り替えられます。

```swift
import UIKit

class CustomCell: UITableViewCell {

    @IBOutlet private weak var titleLabel: UILabel!
    @IBOutlet private weak var selectedLabel: UILabel! //セルが選択されているときに表示する

    override func prepareForReuse() {
        super.prepareForReuse()
        titleLabel.text = nil
        selectedLabel.text = nil
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        DispatchQueue.main.async {
            self.backgroundColor = selected ? .systemGray6 : .systemBackground
            self.contentView.backgroundColor = selected ? .systemGray6 : .systemBackground
            self.selectedLabel.isHidden = selected ? false : true
        }
    }
}

```

また[setHighlighted(_:animated:)](https://developer.apple.com/documentation/uikit/uitableviewcell/1623280-sethighlighted)メソッドもあり、選択されたときのハイライトをカスタムすることもできます。

似たようなプロパティとして、セルの選択状態を示す[isSelected](https://developer.apple.com/documentation/uikit/uitableviewcell/1623263-isselected)や[isHighlighted](https://developer.apple.com/documentation/uikit/uicontrol/1618231-ishighlighted)がありますが、これをtrueにするとセルの外観をアニメーション遷移させることはできないので、セルの選択状態によってUIを遷移させるようなケースではsetSelected(_:animated:)を使用するのが推奨されているようです。

#最後に
セルの選択状態を簡単にカスタムできることがわかりました。
カスタムなセルは利用シーンが多いので、また便利な方法を学んだら追記していきます。

#参考文献
以下の情報を参考にしました。

- [Apple Developer](https://developer.apple.com/documentation/uikit/uitableviewcell/1623255-setselected)
GitLab(またはGitHub)でIssue Templateを作る

## GitLabの場合

https://gitlab-docs.creationline.com/ee/user/project/description_templates.html#creating-issue-templates

### テンプレートを用意する

> Creating issue templates
> Create a new Markdown (.md) file inside the .gitlab/issue_templates/ directory in your repository. Commit and push to your default branch.

リポジトリに `.gitlab/issue_templates/(任意の名称).md` という形でディレクトリ及びファイルを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/e320ed27-c821-6b1a-6f41-7560d7addda0.png)

### デフォルトブランチにコミットする

> Name your directory issue_templates and commit to your default branch.
> To check if this has worked correctly, create a new issue and see if you can choose a description template.

コミットしたら、Issueを作成してうまく動作するか試してみましょう。

### 完成

以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/b42f33dd-86a3-e5c9-08ed-a329d3dd39da.png)


## GitHubの場合

https://docs.github.com/ja/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository



## テンプレート集

https://github.com/stevemao/github-issue-templates

https://qiita.com/yasu99/items/87924164b5d538979a2b

https://qiita.com/janus_wel/items/ba47259f107b161c5727


以上、参考になればさいわいです。
AWSで最初のIAMユーザー管理者Administratorを作った話

#目標
AWS IAMユーザーでbillingが見られるようになる
#経緯
##vCPU=0
（１）古い写真に色付けをするとして話題になったGithubプロジェクトであるDeOldifyをAWS EC2上で動かそうとした際、GPU利用を目的にインスタンスを無料枠のt2.microからp2.xlarge(USD0.75/h)[https://qiita.com/m0ch1m0ch1/items/81b136b8eac1395c82ba] に変更してstartしようとしたところ、失敗したよ~との赤いバナーがでました:cactus:
なんでも現在利用可能なvCPUが0コでその上限を上げるにはリクエスト用URLにて申請が必要とのことです。（※2021/8/13追記：t3と m5は互換性があるそうですが、t2とp系は判りません）
![redbanner_AWS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242973/1b473580-d626-87e8-3198-7f73821573a8.png)


##見えない
（２）リクエスト用URL[http://aws.amazon.com/contact-us/ec2-request] からのリダイレクト先へ行くと、リクエスト用のボタンが３つ表示されるものの、その先に行けない仕組みとなっていました。
実はこのときまで、AWSサービス登録日以来唯一つのIAMユーザー dev-mokochanでEC2上滞りなく作業してきたものの、設定周りでは随所で表示変更権限が無いとして請求書情報も見ない・見られないままやってきていました。
Dockerイメージビルドに際してストレージを増やしていたのですが、この記事の操作をしたことで本日までにUSD$13が確定、月末にはUSD$30請求されそうなことが判りました。

##IAMユーザー Administratorを作成する
（３）AWS EC2 でrootユーザー以外に権限を与えていないのでそのIAMユーザーで各種項目を見られないのは当然と思っていましたが、root代わりにAdministratorというIAMユーザーおよび administrator groupを作るのですね。素通りして半年過ぎてしまいました....
![210813_Administrator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242973/26ca1fad-fedc-d234-a6d7-4856bccd68d0.png)

以下こちらのページ[https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html] の紹介手順通りに作成進めます

(1)IAM Consoleへログイン
rootとして登録メールアドレスでログインしてからIAMコンソールに進みます

(2)アクセス解禁
a.My Account下をスクロールしていき
 b.「IAM User and Role Access to Billing Information」の右方向にある Editを選択します。このときrootユーザーでコンソールにログインしていないと表示されません。
c.「Activate IAM Access」のチェックボックスに印をつけてUpdateの青ボタンをクリックします。
d.ここまでが済んだらおなじみ左上の [Services▼]プルダウンからIAMを選択してIAMダッシュボードに戻ります

（３）Administratorユーザーを追加する
![210813_Step4AddAdministrator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242973/ff063707-8ba9-0636-eb0a-7e90d8baf736.png)
IAM>Usersで既存ユーザーリスト一覧右上の青ボタンからAdministratorを追加していきます。詳しくは上記の紹介手順ページにてご確認ください。

+ 途中でOptional項目として出てくるタグ-キー付与については[https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html]、ユーザーの使用履歴をトラックできたりするとのこと
+ 最後に表示されるユーザーごとのクレデンシャルのcsvを[Download csv]にて保管しておくことをどうぞ忘れずに。

##結果
AWSフルアクセス権限を持つAdministratorアカウントが出来た。既存IAMユーザーをAdministratorsグループに追加して請求や設定など各種情報にアクセスできるようにした。


#参考
こちらを参考とさせていただきました。
AWS GPUインスタンスのスペック・価格比較
https://qiita.com/m0ch1m0ch1/items/81b136b8eac1395c82ba

AWSのEC2インスタンスタイプについて｜それぞれの解説と用途別の選定：（株）夢テクノロジー様
https://www.yume-tec.co.jp/column/trend/4585

AWS UserGuide:Creating an administrator IAM user and user group (console)
https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html
Record of trying Cloudflare CDN

#Setup
1. copy **ALL** existing entries of your domain from current DNS server to Cloudflare DNS server (Please check carefully if all entries is copied, otherwise services using missing entries will be inaccessable)
2. on your domain name registrar, set DNS server serving your domain name to Cloudflare DNS server
3. wait **at most 48 hours** for DNS servers cache expires, Cloudflare also periodly checks if domain name moves to Cloudflare or not
4. turn on websites under your domain to use Cloudflare CDN

#Default caching behavior
Assume that *free* plan is joined, and no *page rule* is setup

1. only file extension is consider, not "Content-Type" response header
2. html file will not be cached (file with "htm", "html" or "php" extension), file without extension also will not be cached
3. [here](https://support.cloudflare.com/hc/en-us/articles/200172516-Understanding-Cloudflare-s-CDN) shows file with which extension will be cached
4. for cached file, "Cache-Control" response header will be rewrite to value of "Browser Cache TTL" setting
5. file with "Set-Cookie" response header will not be cached, although which is cached file extension
6. value of "Caching Level" setting is "Standard", it means that the cached content becomes invalid if the query string changes

You can refer "cf-cache-status" response header returned by Cloudflare's edge server to know if the request is cached or not.

Under the default caching behavior, you may observe that **there is a noticeable delay** between domain name is entered and content starts to display on the browser (html file is not cached by default). Then content rendering is fast due to the help of caching image, javascript and css files of Cloudflare CDN.
【1行野郎】あるファイルに対して、fzfで絞り込みしてからCtrl-kでクリップボードにコピーする


## 内容

下右図の「**後**」の状態で Ctrl-k を押すと、(行番号は除外して)
「`  - ./PV/py/app:/usr/src/app/`」がクリップボードに入る. 

このあとは、(環境次第だが) Shift + Insert などでペーストできる.

　

**図: fzf による絞り込み前後の状態**

|前|後|
|:--|:--|
| cat **-n** docker-compose.yml を実行した直後 | fzf で絞り込みした状態 |
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/621c9bd2-bb26-4aa1-3e5a-1450b4853669.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/d6c5c102-bbce-9e0b-e674-ce47000400ac.png)|


## コマンド

```bash
$ cat -n docker-compose.yml | 
    fzf --tac "--color=hl:#ff00b0,bg+:#666666" \
        --bind 'ctrl-k:execute-silent( echo -n `echo -n {} | cut -f2-` | sed 's/\r\n//g' | xclip ; tput rc )+abort'
```

　

以下の環境で確認した

|項目|バージョン|
|:--|:--|
|Ubuntu|18.04|
|fzf|0.17.3|
|ncurses|6.1.20180127|
|xclip|0.12|

　

上記実行例は、fzf を使った各種ツールの基本原理だと思うので、
「cat -n docker-compose.yml」を「find の結果」などに変えれば色々と転用できる.

fzf に感謝👍

　

以上.
Ubuntu20.04にnvidia-docker runtimeをインストールする



- 前提条件
    - [Ubuntu20.04にNVIDIA GPUドライバをインストール](https://qiita.com/routerman/items/99083317a69fd846c54f)
    - dockerがインストールされていること


公式: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/nvidia-docker.html 　　

```bash
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
    && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
    && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
    sudo tee /etc/apt/sources.list.d/nvidia-docker.list
curl -s -L https://nvidia.github.io/nvidia-container-runtime/experimental/$distribution/nvidia-container-runtime.list | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list

sudo apt-get update -y
sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker
```

イメージは公式の[dockerhub](https://hub.docker.com/r/nvidia/cuda)から選ぶ。

```
# 動作確認
sudo docker run --rm --gpus all nvidia/cuda:11.4.1-runtime-ubuntu20.04 nvidia-smi
```

docker-composeで扱いたい場合は [nvidia-dockerをdocker-composeで動かす(ver3系)](https://qiita.com/routerman/items/c5f9d7b6d03e44de6be2) を参考に。
ubuntu20.04にNVIDIA GPUドライバをインストール


- 動作環境
    - OS: Ubuntu 20.04.2 LTS (focal)
    - GPU: GeForce GTX 960

## 忙しい人のために
結果から言うと、以下のコマンドを叩けばインストールされる

```
sudo apt update -y
sudo apt install -y ubuntu-drivers-common
driver=$(ubuntu-drivers devices | grep recommended | awk '{print $3}')
sudo apt install -y --no-install-recommends $driver
```

## インストール方法

今回はaptでインストールする方法について書く。
※ ソースビルドやアンインストールの方法については書かない。

まずは、推奨ドライバを調べる。
調べるためのubuntu-driversコマンドを入れて、コマンドを叩く。

```
$ sudo apt install -y ubuntu-drivers-common
$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:03.1/0000:0e:00.0 ==
modalias : pci:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
vendor   : NVIDIA Corporation
model    : GM206 [GeForce GTX 960]
driver   : nvidia-driver-460-server - distro non-free
driver   : nvidia-driver-418-server - distro non-free
driver   : nvidia-driver-460 - distro non-free recommended
driver   : nvidia-driver-390 - distro non-free
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-450 - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin
```

この中から"recommended"が付いているものをインストールする。
--no-install-recommendsをつけて、余計なパッケージ（デスクトップ・オフィス等）が入らないようにする。

```
sudo apt install -y --no-install-recommends nvidia-driver-460
```

OSを再起動し、nvidia-smiコマンドでインストールされていることを確認。

```
$ nvidia-smi 
Mon Mar 15 17:41:20 2021       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.39       Driver Version: 460.39       CUDA Version: 11.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  GeForce GTX 960     Off  | 00000000:0E:00.0 Off |                  N/A |
| 30%   54C    P2    38W / 130W |    652MiB /  4042MiB |     47%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A   1998526      C   /usr/bin/ffmpeg                   215MiB |
|    0   N/A  N/A   2011374      C   /usr/bin/ffmpeg                   215MiB |
|    0   N/A  N/A   2011908      C   /usr/bin/ffmpeg                   215MiB |
+-----------------------------------------------------------------------------+
```
read big-endian 32bit float data using ruby numo/narray

# TL;DR
big-endian 32bit floatのデータをファイルから読み込み、Narrayオブジェクト化する。

# Version
- Ruby: 3.0.2p107
- numo-narray: 0.9.2.0

# Install

```
gem install numo-narray
```

# Code

```ruby
require "numo/narray"
include Numo

file_name = "PSEA.f32"
io = open(file_name, "rb")

grid = {:x => 481, :y => 505}

#読み込み
data = SFloat.from_string(io.read(grid[:x] * grid[:y] * 4))

#エンディアン変換
data = data.swap_byte

#整形
data.reshape!(grid[:x], grid[:y])

p data

io.close
```

# 参考

- https://qiita.com/kojix2/items/0bc5efda0f65e58693a0
- http://ruby-numo.github.io/numo-narray/yard/Numo/NArray.html#swap_byte-instance_method