OmniAICreator/Qiita-1.07M huggingface dataset:
nRF Connect SDK:NCSでPPI

# Nordic Connect SDKでもPPI
直近の記事ではなぜか(？)nRF Connect SDK(以下NCS)ではなくnRF SDKの記事をいくつか書いていました。もちろん理由があって、業務において消費電力を減らす工夫をしなくてはいけなくなり、その中でProgramable Peripheral Interconnect(以下PPI)という機能の存在を知ったからです。正確に言うとPPIという言葉自体はsdk_config.hやサンプルプロジェクトの中で何度も見かけているので言葉そのものは知っていましたが、具体的に何なのかは分かっていませんでしたし、必要ないと思っていたので理解しようともしませんでした。
# PPIとは
こんなところで説明するのもなんですが、PPIとはPeripheral Interconnectの名前の通りTWI(I2C)やSPI、タイマーやGPIOなどのPeripheralと呼ばれる機能をダイレクトに接続してコントロールするものです。例えば500msecで割り込みが発生するタイマーとTWIを接続して500msec毎にTWIのコマンドを発行することができます。
## なぜ消費電力が下がる？
PPIは前述のとおりPeripheral同士が直接動くのでCPUの介入がありません。通常の処理であれば、タイマー割込みが発生し、CPUがそれを割り込みとしてスタックに積み、順番が回ってきたら現在のスタックポインターの処理を中断して割り込みのスタックポインターに移動するという動きになります。その処理が必要ないので
>CPUがスリープしているのであればそのままスリープしている(ので消費電力が下がる)

副次効果としては

>CPUがスタックに積むわけではないのでディレイはほぼ0

と言ったメリットが得られます。おお、スゲーじゃん！
といいことづくめのように見えなくもないですが、実際にはそれを考慮したファームウェアの記述にしないといけないので若干めんどくさいです。例えば定期的にTWIを発行するのであれば、それは基本的にI2Cデバイスからのリードなのでコールバックを使用して処理が終わってから値を格納しに行くなどの記述が必要になります。当たり前ですが非同期処理が必須になります。
消費電力を減らす目的でなくても後者の副次効果を目当てに高精度な時間管理が必要な時にも使えます。
# サンプル
実は完全体のサンプルが最初から用意されているため、ここで特にソースコードを公開して貼り付ける必要がなかったりします(笑)

::: note
またか・・・でもそういう情報があると助かる人も・・・きっといるよね？
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340602/683624ae-d25c-9202-5042-8003abd9e9c1.png)
NCSフォルダーのzephyr/samples/boards/nrf/nrfxにあります。
# もっと詳しくPPIを知りたい
nRF SDKのサンプルですが、こちらの記事をご覧ください。

https://qiita.com/yoshihiro0709/items/b865684c2c9bdbf636af

https://qiita.com/yoshihiro0709/items/069ea9d11156de6aaaa5

https://qiita.com/yoshihiro0709/items/384dca1330137394eee7
#5　switch

# 学習内容
switch文の学習
```java
/* ソースコード */
public class Select{
   public static void main(String[] args){
      int num = 2;
      System.out.println("受ける科目は？");

      switch(num){
         case 1:  //式の値が1の場合
            System.out.println("国語");
            break;
         case 2:  //式の値が2の場合
            System.out.println("数学");
            break;
         default:  //どれにも当てはまらなかった場合
            break;
      }

      String str = "Italy";
      System.out.println("\n" + "行ってみたい国は？");

      switch(str){  //String型でもできる
         case "America":
            System.out.println("アメリカ");
            break;
         case "Italy":
            System.out.println("イタリア");
            break;
         default:
            break;
      }
   }
}
```
```
/* 実行結果
受ける科目は？
数学

行ってみたい国は？
イタリア
```

## switch
if文のように条件分岐を行う

```java
switch(式){
   case 値1:  // "セミコロン" ではなく "コロン" なので注意
      処理;
      break;  // "break" は必ず記述
   case 値2:
      処理;
      break;
   default:
      処理:
      break;
}
```
分岐して処理をした後、そのままその下の "case" の処理をしてしまうため、
処理の最後には "break" を必ずつける

### switch文で使える型
* int
* short
* char
* byte
* enum
* String

### if文との違い
__if文__
一番上からひとつずつ条件の判定をおこなう
__switch__
式と一致するcaseまでジャンプするため、
他のcaseには寄り道しない。
だから、処理速度がif文と比べて速い。

### if文との使い分け
__if文の方がいい__
* 大小関係を比べるなどの、比較演算子を使用するとき
* 論理演算子を使って、条件を複数使用するとき

__switch文の方がいい__
* 使う変数がひとつのとき
* 処理速度を速めたいとき
ノイマン型コンピュータ

広く利用されているコンピュータはほとんどがこのノイマンコンピュータです。

# ノイマン型コンピュータの特徴
## プログラム内蔵方式（プログラム記憶方式)
* 実行時にはプログラムをあらかじめ、主記憶装置上に読み込んでおく方式。
* 主記憶装置にあらかじめプログラムを移しておかなければならない。
* 補助記憶装置は主記憶装置に比べて読み書き速度がかなり遅いため。
* 主記憶装置であるメモリ上にプログラムをロードすることで、実行準備完了となる。
## 逐次制御方式
命令を一つずつ取り出して、順番に実行していく方式。

## 気づき
早い主記憶装置に移してすばたくCPUを動かすのか。

# 主記憶装置のアドレス
主記憶装置は、いろんなデータを記憶することができる。
なので明確にどこにあるのかをはっきりさせておく。
そのために
一定の区画ごとに番号を割り振る。
その番号のことを```アドレス```（または```番地```)と呼ぶ。

## 疑問 アドレス
一つの主記憶装置にいくつのアドレスが存在するのか？
イラストでは４桁があるから８進数で表せる分だろうか？

# 問題を解いた時の疑問
主記憶に記憶されたプログラムを、CPUが順に読み出しながら実行する方式はどれか？
順に読み出しながら実行する方式だから逐次制御方式かと思ったが選択肢になかった。
答えを見てみると、プログラム格納方式だった。
説明を読んだが、いまいちピンと来なかった。

### プログラム格納方式
* プログラムを主記憶装置（メインメモリ）に格納し、CPUがこれを読み取りながら実行を行う方式
* プログラムを実行するときハードディスクなどの補助記憶装置に保存してあるプログラムを主記憶装置（メインメモリ）にロード（読み込む）してから実行します。
* 別名「ストアドプログラム方式」
出典 https://medium-company.com/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E5%86%85%E8%94%B5%E6%96%B9%E5%BC%8F/

### 逐次制御方式
CPUの処理方式のひとつで、命令を1つずつ順番に処理していく方式です。
1つの命令が終わるまで次の命令を実行できないため、処理効率はよくありません。
出典 https://medium-company.com/%E9%80%90%E6%AC%A1%E5%88%B6%E5%BE%A1%E6%96%B9%E5%BC%8F/

## 気づき
もう覚えるしかないな。
```CPUがこれを読み取りながら実行```と```CPUの処理方式のひとつで、命令を1つずつ順番に処理していく```が同じように見える。

次に```命令を1つずつ順番に処理していく```と問題文に書かれていたときに逐次制御方式を選ぼう

今はこれで凌ぐ。
【TypeScript】ネストされたオブジェクト型から型を抽出&指定方法

### ネストされたオブジェクト型から型を抽出&指定方法
ネストされたオブジェクト型からプロパティを指定して、再宣言する方法で色々ググっていい方法を見つけたので備忘録で残します。
下記のようなrelay graphQLでgenerateされた型の`customerAddress`のブロックだけを型としてを再宣言したい場合、
```tsx

(alias) type DefaultAddressUpdateMutationResponse = {
    readonly customerAddressUpdate: {
        readonly customerAddress: {
            readonly address1: string | null;
            readonly address2: string | null;
            readonly city: string | null;
            readonly zip: string | null;
            readonly province: string | null;
            readonly lastName: string | null;
            readonly firstName: string | null;
            readonly id: string;
        } | null;
    } | null;
}
import DefaultAddressUpdateMutationResponse
```
```tsx
DefaultAddressUpdateMutationResponse['customerAddressUpdate']
DefaultAddressUpdateMutationResponse['customerAddressUpdate']['customerAddress']
```
と指定しても👆の様に参照先のオブジェクト型にor nullがある場合は、アクセスができないため、エラーになります。
対策としてExcludeで条件指定null削除して再宣言します

```tsx
Exclude<型, 除外したいもの>
```




```tsx
type GetCustomerAddressUpdateType = Exclude<
  DefaultAddressUpdateMutationResponse['customerAddressUpdate'],
  null
>;
type GetCustomerAddressType = Exclude<
  GetCustomerAddressUpdateType['customerAddress'],
  null
>;
```
とすれば`customerAddress`のブロックをGetCustomerAddressTypeという命名で型宣言ができます。
```tsx:type GetCustomerAddressType
       customerAddress: {
            readonly address1: string | null;
            readonly address2: string | null;
            readonly city: string | null;
            readonly zip: string | null;
            readonly province: string | null;
            readonly lastName: string | null;
            readonly firstName: string | null;
            readonly id: string;
        }

```
以上


参考：https://tutorialmore.com/questions-2425024.htm
FigmaのFileのURLは一意なのでProjectやTeamを移動させてもリンク切れにならない

## この記事の概要

タイトルがすべてです笑

IssueにFigmaのリンクを貼って管理するシーンなどがあると思いますが、ProjectやTeamを移動してもURLを再発行する必要は無い、という話です。

TeamやProjectの整理をする際「Fileを移動させたらこれまでのURLは無効になってしまうのか？リンク切れになってしまうのか？」という疑問が社内で出ました。
実験したところ大丈夫だったため、せっかくなので記事にしました。

## 仕組み

FigmaではTeam, Project, Fileがそれぞれ以下のようなURLで表されます。

| 区分 | URL |
| --- | --- |
| Team | `https://www.figma.com/files/xxx/team/{team-id}/xxx?fuid=xxx` |
| Teamの省略形（上記にリダイレクトされる） | `https://www.figma.com/files/team/{team-id}` |
| Project | `https://www.figma.com/files/xxx/project/{project-id}/xxx?fuid=xxx` |
| Projectの省略形（上記にリダイレクトされる） | `https://www.figma.com/files/project/{project-id}` |
| File | `https://www.figma.com/file/{file-id}/xxx?node-id=xxx` |
| Fileの省略形（上記にリダイレクトされる） | `https://www.figma.com/file/{file-id}` |

見ていただけると分かるように、Fileを区分するのにProjectやTeamは関係ありません。
そのおかげだと思うのですが、Fileの属するProjectやTeamを変更してもURLは変わらないままアクセスができます。

ただ、当たり前の話かもしれませんが、公開範囲を絞っているProjectやTeamに移動させたら権限の無い方は見れなくなります。
外部のパートナーさんやクライアントさんから「急に見れなくなった」と連絡が来る可能性はるので、そこだけはご注意ください。

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox
未経験エンジニア・必須スキル 【エラーメッセージとの付き合い方】

エラーになった時に「〇〇というエラーが出ました」と報告するだけでなく、
自分で解決できるようにするのが大切だと思っています。

# 誰もがエラーに遭遇する
趣味や仕事でプログラミングをしていて、エラーになったことが無い、なんて人は1人もいません。
どんなに優秀なプログラマやエンジニアでもエラーに遭遇します。


# エラーの種類
エラーメッセージとの付き合い方の前に、そもそもどんなエラーがあるかをまとめて見ようと思います。
大きく、エラーの種類は3種類あります。
1. コンパイルエラー
1. 実行時エラー
1. 論理エラー

### 1.コンパイルエラー
ざっくり言うと、文法エラーです。
例えば、
* 未定義の変数を使ってる
* 構文や関数の書き方が間違っている

ときに発生します。

### 2.実行時エラー
プログラムが強制終了します。
「文法上は正しいのに実行できない」とはどんな状態でしょうか？

例えば、要素数3の配列に対し、4つ目の要素を指定した場合などです。
Pythonでは、```list index out of range```となります。

### 3.論理エラー
「強制終了することはないが、期待した結果と異なる」というパターンです。
動作はするので、正常に動いているように見えますが、
どこかの処理で計算などを間違えている時に発生します。

# 論理エラーの解消は得意な人が多い
3の論理エラーについては、プログラムを書くことができる人であれば、処理を追いつつ、怪しい箇所を特定できると思います。
なので、今回は、主に1と２のエラーについて付き合うときのコツをまとめてみたいと思います。

# 前提：エラーメッセージはヒント
英語で大量のメッセージが表示され、面食らってしまうかもしれないですが、
エラーメッセージには、エラーを解消するためのヒントが書いてあります。

エラーメッセージの内訳
* エラー原因
* 関連情報

下記のPythonファイルを実行した場合、
``` main.py
sample_list = [1, 2, 3]
print(sample_list[3])
```
下記のエラーになります。
```
Traceback (most recent call last):
  File "Main.py", line 4, in <module> # 関連情報
    print(sample_list[3])
IndexError: list index out of range # エラー原因
```

関連情報には、エラーの原因になっているファイル名や該当箇所（変数名、行数）が書いてあることが多いです。
また、プログラムによっては、エラーコードが書いてあることもあります。

# エラーメッセージを読むときのコツ
## 1. しっかり読む
エラー文を読みましょう。
「〇〇」というエラーが出ました、と報告する人は、エラーを読んでいません。
英語の意味が分からない時は、google翻訳を使いましょう。

## 2. 複数のエラーが出た場合は、先に表示されたエラーから解決する
最初に出たエラーが原因となって、後続のエラーが出ているケースがあります。

## 3. エラー内容が書かれた一文を特定する
上記のサンプルで言うと、下記の部分が該当します。
```
IndexError: list index out of range
```

# エラーメッセージについて調べるときのコツ
## 検索ワード１　エラー文
コツとして紹介した「3. エラー内容が書かれた一文を特定する」で特定したエラー文をそのまま使い検索する。
## 検索ワード2　エラーコード
エラーメッセージの関連情報として、エラーコードが出ている場合、それも検索ワードに使いましょう。

## 関連情報である、ファイル名や行数は含めない
当たり前ですが、環境固有の情報を検索ワードに使っても欲しい情報は得られません。

## コンテキストを特定するワードを入れる
* Pythonのプログラムであれば、「Python」
* JavaScriptのプログラムであれば「JavaScript」や「js」
* aws関連であれば、「aws」や具体的なサービス名

を入れてください。

# その他
再度、ドキュメントを確認するのも大事です。

# まとめ
エラーが出た際は、「成長のチャンス」として捉え、
知識・経験を積むきっかけにしてもらえたら幸いです。

弊社では未経験からエンジニアになった方が活躍している会社です。
未経験者の新卒・中途採用も実施していますので、ご興味ある方は[こちら](https://www.recruit.nuco.co.jp/)より。
Python の Dataflow SDKで repeated なschema定義をBigQueryに対して行う

- [WriteToBigquery](https://beam.apache.org/releases/pydoc/2.9.0/apache_beam.io.gcp.bigquery.html#apache_beam.io.gcp.bigquery.WriteToBigQuery)の実行時、テーブルの新規作成したい場合は、schemaを指定する必要がある
- python SDKでのテーブルの指定は　`'field1:type1,field2:type2,field3:type3'` のようなシンプルな文字列で指定する方法と [TableSchema](https://beam.apache.org/releases/pydoc/2.13.0/apache_beam.io.gcp.bigquery.html#apache_beam.io.gcp.bigquery.WriteToBigQuery.get_table_schema_from_string) を利用する方法がある
- シンプルな文字列でのschema指定はrepeatedなschema定義は指定できないので、基本TableSchemaオブジェクトで指定する必要がある
- 以下にJsonからTableSchemaオブジェクトを生成する簡易スクリプトを紹介する


# 実装

```py
import json
from google.cloud import bigquery
from apache_beam.io.gcp.internal.clients import bigquery as beam_bq


class BQUtils:
    # jsonからbigquery.SchemaFieldを生成する
    def _get_field_schema(self, field) -> list[beam_bq.TableFieldSchema]:
        name = field['name']
        field_type = field.get('type', 'STRING')
        mode = field.get('mode', 'NULLABLE')
        description = field.get('description', '')
        fields = field.get('fields', [])

        if fields:
            subschema = []
            for f in fields:
                fields_res = self._get_field_schema(f)
                subschema.append(fields_res)
        else:
            subschema = []

        field_schema = beam_bq.TableFieldSchema()
        field_schema.name = name
        field_schema.type = field_type
        field_schema.mode = mode
        field_schema.description = description
        field_schema.fields = subschema

        return field_schema

    # jsonを読み込んで TableSchema を返す
    def get_schema(self, path_to_schema_file) -> beam_bq.TableSchema:
        table_schema = beam_bq.TableSchema()
        with open(path_to_schema_file, 'r') as f:
            jsonschema = json.load(f)

        for field in jsonschema:
            table_schema.fields.append(self._get_field_schema(field))

        return table_schema
```

# 参照

https://github.com/apache/beam/blob/master/sdks/python/apache_beam/examples/cookbook/bigquery_schema.py
line-bot-sdk-nodejsのFlex Massageがアップデートされてた

# はじめに

久しぶりにline-bot-sdk-nodejsのレポジトリをみたら[Flex message update 3 #329](https://github.com/line/line-bot-sdk-nodejs/pull/329)というプルリクがマージされていてFlex Massageコンポーネント用の型にいくつかアップデートがあった。3ヶ月くらい前ののものだけど少し見ていこうと思います。

# Videoコンポーネントが追加された

[Videoコンポーネント](https://developers.line.biz/en/reference/messaging-api/#f-video)が新たに追加されました。Videoコンポーネントを使うことでFlex Messageの[ヒーローブロックに動画を表示](https://developers.line.biz/ja/docs/messaging-api/create-flex-message-including-video/)することができます。

[ソース](https://github.com/line/line-bot-sdk-nodejs/commit/5bf1d4e0375a4a9368848794513f8ecee8ed1f5f#diff-af9e5e8969ffd0322ef4acda0e127e2817951b9a0475cd9d9b6f86326f85d865R1513)をみるかぎり`altContent`を含むすべてのプロパティが網羅されています。

# BoxコンポーネントにmaxWidth maxHeightが追加された

[Boxコンポーネント](https://developers.line.biz/en/reference/messaging-api/#box)に`maxWidth`, `maxHeight`が追加されました。[コメント](https://github.com/line/line-bot-sdk-nodejs/pull/329#issue-1167328250)では`We can specifiy maxHeight and maxHeight in box component.`と書いてあって`maxHeight`がかぶってますが正しくは`maxWidth and maxHeight`ですね。

`maxWidth`, `maxHeight`ともに`string`で `flexBox.maxWidth ='120px'`のように指定します。

# TextコンポーネントにlineSpacingが追加された

[Textコンポーネント](https://developers.line.biz/en/reference/messaging-api/#f-text)に`lineSpacing`が追加されました。テキストの行間を広げるやつです。`flexTextBase.lineSpacing = '20px'`のように指定します。

# おわりに

地味なアップデートの紹介でしたが個人的にはFlex Massageの型付けが厳密になるのはとても歓迎です。Bot開発の中でもFlex Messageのレイアウトが複雑になってくるとデバッグが難しくなってくるからです。何がどう入れ子になってるとか。

Flex Massageのレイアウトにあたってはできるだけ細かいハマりどころがなくなればストレスが減るのでこのあたりは積極的にアップデートされていくとありがたいですね。
JavaScript メモ

# 関数メモ

## JS　即時関数の書き方とアロー関数の比較
```diff_JavaScript
//通常
(function(引数){処理内容}(返り値));

//アロー関数
((引数)=>{処理内容})(返り値);
```

## Don't make functions with in a loop.
繰り返し文（for）のなかで関数を書き込んだら警告文が表示された。
問題なく動くようだが、気になる。
```diff_javascript
for (let i = 0;i < janken.length; i++){
    const tmpButton = document.createElement('button');
    tmpButton.id = 'j_button' + i ;
    tmpButton.innerText = janken[i] + '!!';
//***********************************
//この部分で警告文が表示
    tmpButton.onclick = (e) => {
      const you = e.target.id.replace('j_button', '');
      const com = (you + 2) % janken.length;
      jankenSpace.innerText = 'あなた'+ janken[you]+'\nあいて'+janken[com]+'\nもう一度やりますか？';
    };
//***********************************

}
```

for文の外で定義すれば警告文が出ないようだが、改善の再現ができない。。。


## for-in の繰り返し文
オブジェクトから
1回ごとにプロパティを1つずつ変数に代入して処理で利用できるようになる
```diff_javascript
//構文
for(変数 in オブジェクト){
  //処理
}
```

「プロパティ」なので
hogeだけだと属性のみが表示される。

data[hoge]とすることで値を表示することができる。
```diff_javascript
//オブジェクト
let data= {
  name:'あんぱん'
  number:5
  price:300
}
//for-in文
for(let hoge in data){
  console.log(hoge);
  console.log(data[hoge]);
}

//出力結果
name
あんぱん
number
5
price
300
```
videoタグでレスポンシブに動画を再生仕分ける（JavaScriptなし）

```
<video controls width="100%" poster="サムネイル画像.jpg">
<!-- 縦画像 -->
<source media="(max-width: 991px)" src="SP用縦動画.mp4" alt="説明"  type="video/mp4">
<!-- 横画像 -->
<source src="PC用横動画.mp4" alt="説明"  type="video/mp4">
</video>
```
CPUとコンピュータの５大装置

# CPUとは
```中央処理装置```とも言われる。
中には```制御装置```と演算そうち(ALU)がある。
しかし
自分では動くことはできない。
```プログラム(ソフトウェア)```という名の指示書が必要になる。

## 気づき
プログラマーはこのCPUに指示を与える仕事なのか。
もっと頑張ろう。

## コンピュータの中身
コンピュータはハードウェアに「こう動け」と命令することで動く機械です。
CPUは演算をしたりと実際の処理を行うのはCPUの役割です。
しかし入力を受け入れる装置、プログラムや演算を記憶するための装置、何らかの出力装置が必要だったりと他にも大切な装置が存在する。

### 気づき
CPUだけでは動かないのか。
他の装置と連携することでコンピュータは制御されているんだな。

## ５大装置とそれぞれの役割
```制御装置```、```演算装置```、```記憶装置```、```入力装置```、```出力装置```
### 中央処理装置
その中に```制御装置```、```演算装置```がある
#### 制御装置
プログラムの```命令を解釈```して、```コンピュータ全体の動作を制御```します。
#### 演算装置
```四則演算```、```データの演算処理```を行う。```算術論理演算装置（ALU Arithmeitc and Login Unit)```とも呼ばれる。

### 記憶装置
その中に```主記憶装置```、```補助記憶装置```がある。
#### 主記憶装置
```一時的```に記憶する装置。コンピュータの電源を切ると、その```内容は消えてしまいます```。
#### 補助記憶装置
```長期```に亘り記憶する装置。電源を切ることで```内容が破棄されない```。
### 入力装置
コンピュータに```データを入力```するための装置。　
例　キーボード、マウス、スキャナ
### 出力装置
コンピュータの```データを出力```するための装置。
例 ディスプレイ、プリンタ

# 制御の流れ
制御装置は演算装置、主記憶装置、補助記憶装置、入力装置、出力装置に伝令される。
演算装置は```データを演算するして主記憶装置に渡す。```

主記憶装置は```一時的保存されているプログラムを制御装置に渡す。``` ```演算装置からデータの演算結果が渡される。``` ```補助記憶装置にプログラムやデータの読み書きをする。``` ```出力装置には処理結果を出力する。```

入力装置は```入力を主記憶装置に読み込ませる。```

CPUと各装置を結ぶ回線を```バス```と呼びます。

# 問題を解いた時の気づき
## AR
現実の映像に仮想のコンテンツを貼り付け動かす技術です。
## DVI
液晶ディスプレイなどのディスプレイ装置で使われる映像入出力インタフェースです。
### 疑問 インタフェースとは？
英単語の「Interface」の直訳は「境界面」「接点」であり、ビジネス用語の「インターフェース」はここから「異なる2つのものを仲介する」という意味で使われます。
出典 https://gakumado.mynavi.jp/freshers/articles/43476

#### 気づき
形式、形状、操作手順などのことを言うのか。いろいろインタフェースがあるんだな。

## GPU
画像処理用のCPU。膨大な並列して実行される計算処理も得意。AI分野でも使われている。
## MPEG
ディジタル動画を圧縮する技術です。

## 気づき
知らない単語ばかりだ。
まだまだ勉強しよう。
Unityの視点移動の速度が遅いとき

〇結論
マウス右を押しながらホイールで倍数を調節

〇概要
UnityのScene Viewの視点を移動するときに
右クリックをしながらWASDキーを押すと自由自在に移動できます。

しかし、急に速度が遅くなってすごいストレスになりました。
マウス右を押しながらホイールを動かすと倍率が出ます。
1以下になっていたのが原因でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262130/a1eab5de-0f61-f7a0-c39e-147912f1f658.png)

〇参考記事
https://someiyoshino.info/entry/2020/12/06/120146
SlackでグループメンションのIDを取得したい。Webhookで必要だから。

Webhookでグループメンションの記法に関する記事はネットでいくらでも出てくるが、肝心のグループIDの取得の仕方がわからない。

ちなみに無料版ではグループ機能はないらしい。

なんか裏技的なやり方だけど、Slackをブラウザで開いて、開発者ツールで見ればできた。
ワークスペースの管理者権限とかも要らない。

- アクセス→https://slack.com/intl/ja-jp/
- 該当のワークスペースの「SLACKを起動する」
- Slack.appを起動しますか？→「キャンセル」
- （フランス語で失礼！）`Cliquez sur « Ouvrir Slack » pour lancer l’application pour ordinateur.
Cela ne fonctionne pas ? Vous pouvez également utiliser Slack dans votre navigateur web.`をクリック。日本語だと`「ブラウザで開く」`とかになるのかな？
- どっかでIDを取得したいグループメンションを表示。
- 開発者ツールを開いて、グループメンションを選択。
- ↓こんな感じでdata-idの中に書いてある英数字がグループメンションのID。

```html
<ts-mention data-id="グループメンションIDの英数字" data-label="@hoge" spellcheck="false" class="c-member_slug c-member_slug--link ts_tip_texty c-member_slug--mention" dir="ltr">@hoge</ts-mention>
```

あとは、こんな感じで使えばOK。

```ruby:ruby
group_id = ENV["SLACK_GROUP_ID"]
#
#
#
"text": "<!subteam^#{group_id}> おつかれさまです。時間です。"
```
楽にDockerで日本語Pandocする

いろいろな方法があるかも知れないが、学習コストを支払う余裕がなく、もともと知識もないため細かいことがしたいわけでもなく、なおかつ3年後でも再利用できるようなロバストそうな方法を求めた結果、公式のDockerイメージに追加で日本語関連をインストールするのが楽だろうという結論。

https://hub.docker.com/r/pandoc/latex

## 公式のDockerに日本語関連パッケージを入れる

こんな感じのDockefileを作ることにした。まるで何もしていない。tlmgrで日本語のパッケージ入れているだけ。

```dockerfile:Dockerfile
FROM "pandoc/latex"
LABEL maintainer="kojix2 <piyo@piyo.com>"
RUN apk --update --no-cache add make msttcorefonts-installer fontconfig && \
    update-ms-fonts && \
    fc-cache -f && \
    tlmgr update --self --all && \
    tlmgr install collection-langjapanese
```

1. Pandoc公式はUbuntu版のDockerも公開しているが、なぜかうまく動作しなかった。また、Alpine版が数日前にアップデートされていたのに対して、Ubuntu版はアップデートが数ヶ月前で、メンテナンス状況がいまいちのように思えたので、Alpine版を使うことにした。
1. `tlmgr` コマンドが動作するので雑に `collection-langjapanese` を入れる。
1. Pandocコマンドを直打ちすると長くなるので、MakefileでPandocコマンドを動かしているが、Alpineさんは最小限なので `make` は付属していない。自分で入れる必要がある。

適当にビルド

```sh
docker build -t kojix2/pandoc-japanese .
```

素の状態ではentrypointがpandocコマンドになっている。

```sh
docker run --rm kojix2/pandoc-japanese --version
```

```
pandoc 2.18
Compiled with pandoc-types 1.22.2, texmath 0.12.5, skylighting 0.12.3,
citeproc 0.7, ipynb 0.2, hslua 2.1.0
Scripting engine: Lua 5.3
User data directory: /root/.local/share/pandoc
Copyright (C) 2006-2022 John MacFarlane. Web:  https://pandoc.org
This is free software; see the source for copying conditions. There is no
warranty, not even for merchantability or fitness for a particular purpose.
```

このままでは不便な場合もある。
コマンドでシェルに入りたい場合、エントリーポイントをshに上書きする。

```sh
docker run --rm --entrypoint="sh" -v $(pwd):/data -it kojix2/pandoc-japanese
```

これでシェル上で操作できる。最初から`make`を呼びたいときは、`sh`ではなく`make`を指定してやればよい。

```sh
docker run --rm --entrypoint="make" -v $(pwd):/data -it kojix2/pandoc-japanese
```

Gitlab CIで動かしたい場合は、

https://gitlab.com/pandoc/pandoc-ci-example


```yaml:.gitlab-ci.yml 
  image:
    name: "pandoc/latex"
    entrypoint: ["/bin/sh", "-c"]
  script:
    - apk --update add make
    - tlmgr update --self --all
    - tlmgr install collection-langjapanese
    - make # MakefileからPandocを呼ぶ
  ```

みたいにしておけばいいらしい。
ちなみにMakefileはこんな感じにしてみた。

```sh
# ファイルの配置
.
├── hoge-huga-piyo.bib
├── hoge-huga-piyo.md
└── Makefile
```

```makefile:Makefile
PANDOC = pandoc
ENGINE = lualatex

NAME   = hoge-huga-piyo

SOURCE = $(NAME).md
BIBTEX = $(NAME).bib
TARGET = $(NAME).pdf

$(TARGET): $(SOURCE) $(BIBTEX)
	$(PANDOC) $(SOURCE) -o $(TARGET) -C --pdf-engine=$(ENGINE) -V linkcolor=blue -V documentclass=ltjsarticle -V luatexjapresetoptions=fonts-noto-cjk

all: clean $(TARGET)

clean:
	rm -f $(TARGET)
```

引用文献もちゃんと載るようだ。
この記事は以上です。

参考文献：

https://zenn.dev/sky_y/articles/pandoc-advent-2020-bib2
Numpy形式でインデックスの行列を取得


# 概要

画像処理なんかで行列要素の位置同士の演算をしたかった．
つまり以下のようなインデックスの行列が欲しかったので，その取得方法．
![hoge.png](https://jp.mathworks.com/help/examples/matlab/win64/nddemo_01.gif)

# 取得方法

追記: スマートなやり方をコメントしてくださったので，こちらがおすすめです．

https://qiita.com/JJJiro/items/7e04314a1c105ab0a92d#comment-84c8d74d2dd2cd4c98b6

----

```python
np.array(np.meshgrid(*[np.arange(i) for i in (n_rows,n_columns)])).T
```
以上

参考：https://www.delftstack.com/ja/howto/numpy/python-numpy-combinations/#python-%E3%81%AE-numpy-meshgrid-%E9%96%A2%E6%95%B0%E3%81%A7-numpy-%E9%85%8D%E5%88%97%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B
初心者　MySQL8に挑戦する 8

# 教師データの足りてないAI

　MySQL寝てる問題を乗り越え、再びFlutterでの本題に戻る。つまりこれ。

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

　なんせ２fileしかない、ビデオ６分しかない。速攻写経。もちろん繋ぐデータベースが違うので、その辺は少し書き直す。

- 元・ボタンを押したら社員ID10番の人のメールアドレスを取ってきて表示。
- 新・ボタンを押したら845年に起こった事件名を取ってきて表示。

　て、変えたのはこれだけ。Androidstudioには赤も黄色もない。ちゃんとUIもあるからsimulator起動して、ビルド。画面出た。さあ、ボタンを押してみよう。

　･･･変化なし(>_<)

 さあ困った。エラーが出るのは辛いが、それでも、エラーだとわかる。検索もできる。が、ビルドは通っていて、ボタンも生きていて、consoleにはconnectedと表示されているけど、見本でメールアドレスが表示されるところに、･･･・なにも出ない。

　試しにSequelAceを見てみる。「クエリの状態:エラーはありませんでした」と書かれているだけで、だれかに接続されたぞとか、変なこと頼まれたぞ、とか、機嫌を損ねているようでもない。

　ともかく今回も、接続はできた(connectedって表示されたからね)らしい。前回の公式サンプルでも、繋いでテーブルを作るところまではできてた。前回は新しいデータを挿入できずに、エラー文がいっぱい出たところで放置。今回は「取ってきて表示」ができない。公式サンプルでは挿入の後になる「取ってきて表示」と見比べて、ぜんぜん同じことをしてる気分のしないコードを見比べる。あ、似てるところもあるか。

これが公式。

```
  // Query the database using a parameterized query
  var results = await conn.query(
      'select name, email, age from users where id = ?', [result.insertId]);
  for (var row in results) {
    print('Name: ${row[0]}, email: ${row[1]} age: ${row[2]}');
  }
```

こっちが今日のビデオのGitHub。Flutterサンプルのカウンターアプリで､「ボタン押したらインクリメント」を「ボタン押したらクエリ」に変えてあるだけらしい。

```
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  var db = new Mysql();
  var mail = '';

  void _getCustomer() {
    db.getConnection().then((conn) {
      String sql = 'select mail from company.customer where id = 10;';
      conn.query(sql).then((results) {
        for(var row in results){
          setState(() {
            mail = row[0];
          });
        }
      });
      conn.close();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'mail:',
            ),
            Text(
              '$mail',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _getCustomer,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
```

　基礎力のない私には、このたった二つのサンプルから正解を見つけることはできない。ので、教師データ三つ目、明日は間にphpが挟まってるヤツに挑戦しよう。
　

https://qiita.com/dongri727/items/f36bf2155bd98e7449d0

https://qiita.com/dongri727/items/4c5071f8dfb8b479d7b4
【ES2015】Javascript一括処理系の配列メソッド使いどころイメージ

# 配列メソッド使いこなせている？
配列を処理するときに毎回`for (let i=0; i<n; i++)`ってループ使っていませんか？
Javascriptの一般的な配列メソッドには`pop`や`push`、`shift`、`unshift`、`slice`、`splice`などの配列自体の操作系もありますが、上記のように配列内の全ての要素に処理を行うことができるメソッドがあります。（モダンJavascript）
配列の処理は頻繁に出てくるかと思うので、息をするように使えるようになりたいです。
# ES2015（ES6）の一括処理系の配列メソッドの使いどころ
全てに<font color="Red">**何かしらの**</font>同一の処理する系
`map`、`forEach`
全てに同一の<font color="Red">**条件一致を**</font>処理する系
`filter`、`find`、`some`、`every`
左から<font color="Red">**順番に**</font>処理する系（おまけ）
`reduce`
|メソッド|処理|返り値|
|:-:|:-:|:-:|
|`map`|全てに同じ処理|処理結果を配列に|
|`forEach`|全てに同じ処理|なし（順番に処理を行う）|
|`filter`|条件に一致するかを確認|一致するもののみを配列に|
|`find`|条件に一致するかを確認|一致するものの最初のみ|
|`some`|条件に一致するかを確認|1つでも一致していれば`true`|
|`every`|条件に一致するかを確認|全て一致していれば`true`|
|`reduce`|左から順番に処理|最終結果|

#### 使いどころチャート
こんなところでしょうか？（`reduce`を除く）
```mermaid
graph TD;
    条件一致を確認/全てに同じ処理-->値で返す/bool値で返す;
    条件一致を確認/全てに同じ処理-->処理を配列/順番に処理;
    値で返す/bool値で返す-->値を配列に/最初の1つだけ;
    値を配列に/最初の1つだけ-->filter;
    値を配列に/最初の1つだけ-->find;
    値で返す/bool値で返す-->1つでもtrueならtrue/全部trueならtrue;
    1つでもtrueならtrue/全部trueならtrue-->some;
    1つでもtrueならtrue/全部trueならtrue-->every;
    処理を配列/順番に処理-->map;
    処理を配列/順番に処理-->forEach;
```
# ES2015（ES6）の一括処理系の配列メソッドの使い方
#### `map` 処理：全てに同じ処理 / 返り値：処理結果を配列に
```javascript
const nums = [1, 5, 10, 30]
double = nums.map((num) => {
  return num * 2
})
console.log(double) 
// [2, 10, 20, 60]
```
#### `forEach` 処理：全てに同じ処理 / 返り値：なし（順番に処理を行う）
```javascript
const nums = [1, 5, 10, 30]
nums.forEach((num) => {
  console.log(num)
})
// 1
// 5
// 10
// 30
```
#### `filter` 処理：条件に一致するかを確認	 / 返り値：一致するもののみを配列に
```javascript
const nums = [1, 5, 10, 30]
const big = nums.filter((num) => {
  return num >= 10
})
console.log(big)
// [ 10, 30 ]
```
#### `find` 処理：条件に一致するかを確認	 / 返り値：一致するものの最初のみ
```javascript
const nums = [1, 5, 10, 30]
const big = nums.find((num) => {
  return num >= 10
})
console.log(big)
// 10
```
#### `some` 処理：条件に一致するかを確認	 / 返り値：1つでも一致していればtrue
```javascript
const nums = [1, 5, 10, 30]
const isSomeOver15 = nums.some((num) => {
  return num >= 15
})
console.log(isSomeOver15)
// true
```
#### `every` 処理：条件に一致するかを確認	 / 返り値：全て一致していればtrue
```javascript
const nums = [1, 5, 10, 30]
const isEveryOver15 = nums.every((num) => {
  return num >= 15
})
console.log(isEveryOver15)
// false
```
#### `reduce` 処理：左から順番に処理 / 返り値：最終結果
```javascript
const nums = [1, 5, 10, 30]
const result = nums.reduce((pre, cur) => {
  pre + cur * 2, 0  // ,の後の0は初期値
})
console.log(result)
// 92
// 2 + 10 + 20 + 60 の結果
// 「pre + cur * 2」はコールバック関数
```

# 補足
意外と配列メソッド少ないので全部覚えることできそうですね！

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array
Cookieとは？

---


# はじめに
<!-- プログラミング学習をしていると日々初めて聞くフレーズので知らない言葉を調べて自分なりに解釈をしアウトプットしたい思いましたの記事にさせていただきます-->

# 目次
<!-- タイトルとアンカー名を編集 -->
1. Cookieとは？
1.  Cookieがないとどういうことになるのか？
1.  Cookieのメリット
1. 補足



# Cookieとは？
⇨ブラウザーにユーザー情報(テキスト情報)を一時的に覚えておくための仕組み
Amazonで言うと気に入った商品をカートに入れてアプリを閉じても次アプリを開いた時にカートのにお気に入りの商品が残っている状態なのはクッキーという仕組みがあるおかげ。


# クッキーがないとどういうことになるのか？
例　amazon 
![スクリーンショット 2022-07-17 14.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602256/c280dcf5-fd41-f3a2-55af-4e1f8147f1ec.png)


左　私たち

右　サーバー

左　Amazonのサイト見せてーとお願いをする

右　わかったーamazonのサイトこれだよー

その後に　amazon内でプロテインの商品を見つけその詳細が知りたくなり
商品をクリックすると
２回目のアクセス

![スクリーンショット 2022-07-17 14.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602256/30ef0558-bc3c-63e2-83c4-e8d0c5c56c84.png)


つまりhttpの通信では１回１回の処理が終わると
サーバーとの通信が途切れるから処理が終わるたびに。あなた誰状態になりログインしないとあかん。⇨そこで開発されたのがクッキー。


# クッキーのメリット
自分のことを覚えておいてくれる。
持続的な通信が可能になり便利


# 補足

テキスト情報＝ユーザーidやパスワードなど個人を特定するもの

ブラウザー＝WEBサイトを閲覧するために使うソフトのこと
例　appleのsafariやgoogleのgoogle Chromeなど
httpとhttpsの違い

# はじめに
URLを確認してみると、`http`から始まるものと、`https`から始まるものがあります。
これらにはどのような違いがあるのかまとめていきたいと思います。

# httpとは
httpは`Hyper Text Transfer Protocol`の略です。
インターネット上で、HTML(Hyper Text Markup Language)というWebページを作るための言語で書かれた文章などの情報を、Webページを公開しているサーバと利用者である私達クライアントでやりとりする時に使われる通信手段(protocol)を意味します。

# httpとhttpsの違い
httpとhttpsの違いは通信が暗号化されているかという違いです。
httpsのsは`Secure`を意味し、サーバとクライアントでのやり取りが暗号化されて行われています。
`https`を用いると、通信内容を盗聴されても、暗号化されているため、内容を知られることがな無く、第三者が通信内容を改竄してもそれを検知することができます。
暗号化を行うために、httpsでは`SSLサーバ証明書`が必ず導入されています。

# httpとhttpsの見分け方
httpsを用いているサイトでは、アドレスバーの1番左に鍵マークがついています。
このマークが付いていないサイトでは、httpが用いられており、通信が暗号化されていないため、クレジットカードを登録すると違法利用される危険性があるため、注意しておきましょう。
![スクリーンショット 2022-07-19 14.17.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2268072/d7d9e273-ccc7-07d9-6922-343bc28d7957.png)

# SSLサーバ証明書
SSLサーバ証明書はサーバとクライアント間で暗号化通信を行うための電子証明書で、認証局から発行されます。
SSLサーバ証明書は`ドメイン認証`、`企業実在認証`、`EV認証`の三種類が存在します。
|   | 認証レベル | 費用 | 利用例　|
|:-:|:-:|:-:|:-:|
| 認証レベル | 低 | 安価 | 個人ブログやホームページ |
| 費用　| 中 | 普通 | 企業のコーポレートサイト |
| 利用例 | 高 | 高価 | ECサイト、オンラインバンキング |


SSLサーバ証明書は誰でも確認することができ、先ほどのアドレスバーの鍵マークから確認することができます。
![スクリーンショット 2022-07-19 14.15.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2268072/42c663af-93ba-79f3-17a0-521b84a36172.png)

# 参考資料
https://jp.globalsign.com/ssl/about/

https://www.itmanage.co.jp/column/about-http-https/
【Flutter】Dividerが表示されないことがある

`Row > Column` の構成でColumnのchildrenの要素にDividerを使ったらDividerが表示されなかった。
たぶんサイズ計算の関係で。
解決方法としては `Row > Expanded > Column` としてColumnを目一杯広がるように指定する。

参考
https://stackoverflow.com/questions/49088934/flutter-divider-widget-not-appearing
PostgreSQL備忘録

# copyと\copy
copyと\copyで挙動が変わる。

`copy`コマンドはサーバー側、つまりLinuxのユーザ`postgres`で実行される。`file.csv`に対して`postgres`ユーザーの権限がないとエラーになる。

```sh:NG
db=# copy split from 'file.csv' with csv;
ERROR:  ファイルを読み取り用にオープンできませんでした: 許可がありません
```


`\copy`コマンドはクライアント側、`psql`を実行しているユーザーの権限で実行される。`file.csv`に対して`psql`を実行しているユーザーの権限があれば実行できる。
```sh:OK
db=# \copy split from 'file.csv' with csv;
```

# 外部接続

二段階の認証になっていて、2つの設定ファイルがある
- pg_hba.conf
    - データベースやユーザ単位で設定できる
- postgresql.conf
    - IPアドレスで接続元を制限する


```conf:pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# localは同一ホスト内通信
local   all             all                                     peer
# 以下TYPEがhostなのでTCP/IPの設定
host    all             all             127.0.0.1/32            trust
```

| METHOD | 意味   |
| ---- | ---- |
|  trust  |  認証なし  |
|  peer  |  postgresqlのユーザー名とlinuxのユーザー名が同じでないと拒否する  |
|  md5  |  md5（ハッシュ値）を使ったパスワード認証  |
Reactでmap関数について勉強したのでまとめてみる



<h1>まずは、箇条書きの形式でyamanoteLineを表示したい</h1>


```React
function App() {
  const yamanoteLine = ["駒込", "田端", "西日暮里", "日暮里", "鶯谷"];   // (A)

  const listItem = yamanoteLine.map((nameOfStation) => (   // (B)
    <li>{nameOfStation}</li>
  )); 

  return <ul>{listItem}</ul>;   // (C)
}
```

(A)
>今回使う`yaemanoteLine`配列を作成。

(B)
>`yamanoteLine`の各要素を`<li>`要素に入れた、新しい配列`listItem`を作成。

(C)
>その配列`listItem`を`<ul>`要素に入れる。

<h2>結果</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666100/76ad0598-5d0f-c933-172b-c0635de2ab21.png)
とりあえず最初にやりたかったことはできた。
しかし、


```
Warning: Each child in a list should have a unique "key" prop.

Check the render method of `App`. See https://reactjs.org/link/warning-keys for more information.
    at li
    at App
```

このような警告文が出てくる。和訳すると、

> リストの各子要素はユニークなkey要素を持っていないといけません。

map関数の第二引数にindexを追加し、`<li>`タグに`key={index}`を追加。

<h3>訂正後</h3>

```React
function App() {
  const yamanoteLine = ["駒込", "田端", "西日暮里", "日暮里", "鶯谷"];

  const listItem = yamanoteLine.map((nameOfStation, index) => (
    <li key={index}>{nameOfStation}</li>
  ));

  return <ul>{listItem}</ul>;
}
```

これで警告文は出なくなった。

<h1>次に、「〇番目は〇〇」と表示したい</h1>

山手線に順序をつけることがどうなのかは置いといて、とりあえずやってみる。

```React
function App() {
  const yamanoteLine = ["駒込", "田端", "西日暮里", "日暮里", "鶯谷"];

  const listItem = yamanoteLine.map((nameOfStation, index) => (
    <li key={index}>{index+1}番目は{nameOfStation}</li>
  ));

  return <ul>{listItem}</ul>;
}
```

<h2>結果</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666100/1e7f8d69-08f9-cac9-e567-c7255db1b819.png)

特にエラーもなく、理想通りに動いてくれた。

<h1>map関数についてわかったことまとめ</h1>
<ul>
<li>map関数は配列の中身をすべて取り出し、新しい配列を作ってくれる。</li>
<li>第１引数は配列の要素、第２引数は要素の添字である。</li>
<li>楽！</li>
ABC183 C-Travel解説

# 解説しようと思ったきっかけ
競プロを初めてまだ間もないですが、競プロをやってきて初めて(標準)ライブラリを使ったため、新鮮味があって楽しかったから。使わなくても当然解けますが...

# 問題
[ABC183 Travel](https://atcoder.jp/contests/abc183/tasks/abc183_c)
>N 個の都市があります。都市 i から都市 j へ移動するには Ti,jの時間がかかります。
都市 1 を出発し、全ての都市をちょうど 1 度ずつ訪問してから都市 1 に戻るような経路のうち、移動時間の合計がちょうど K になるようなものはいくつありますか？

>**入力例**
4 330
0 1 10 100
1 0 20 200
10 20 0 300
100 200 300 0
**出力例**
2

```Python
import itertools

#入力を受け取る
N, K = map(int, input().split())
T = [ [None] for i in range(N) ]
for i in range(N):
    T[i] = list(map(int, input().split()))
```

# 発想
スタートは都市1固定で、最後も都市1に帰ってこなければならないので、
Nまでの順列を考え、全組み合わせの中で最後の要素が1である組み合わせのみ考えれば良い。
例としてN=3のときの並べ方の組み合わせを見てみる。
```Python
for i in itertools.permutations(range(1, 3+1)):
    print(i)
```
>**出力**
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1) <-最後に都市1へ帰る組
(3, 1, 2)
(3, 2, 1) <-最後に都市1へ帰る組

最初に都市1が来たらまずいと思うが、はじめは都市1スタート固定かつ最後の要素が都市1で条件分岐しているので、問題ない。よって、コードは以下のようになる。
```Python
res = 0

for i in itertools.permutations(range(1, N+1)):
    i = list(i) #itertoolはタプル型なのでリストに変換
    if i[-1] == 1: #最後の要素が1の時(最後に都市1に帰ってくる)のみ通過
        tmp = T[0][i[0]-1] #スタートは都市1固定なので初めだけ処理
        for j in range(1, N):
            tmp += T[i[j-1]-1][i[j]-1]
        if tmp == K: #合計が目的のKならカウント
            res += 1
```

# まとめ
二重目のfor文の中身はややこしいのでノートに実際に書いたり、デバックを走らせればわかると思います。自分もノートに書いてやってました!
「レガシーコードからの脱却」読了

https://www.oreilly.co.jp/books/9784873118864/
# 感想
DDDをかじって弊社レガシーコードをリファクタリングしてみたはいいものの、テストの書き方について悩んでいたので、テストファースト開発はとりあえず挑戦してみたい。
最近、弊社が1人エンジニアから2人エンジニアになったのでエクストリームプログラミングももう少し調べてやってみたいなあ。
組織文化や考え方の記述が多く、数年後経験を積んだ後にまた読み返したい。
# 印象に残った部分
### プロジェクトがなぜ失敗するのか
> いつも使われる、もしくは、よく使われる機能は20%にすぎず、45%もの機能は**まったく使われない**ことがわかった
> (中略)だが、開発者にも作りすぎの罪はある。**コードにちょっとした機能を足すくらい数分で終わるし、コストもかからないと思っている。** だが、コストがかからないように見える機能追加でも、将来的に保守に大金がかかるかもしれないのだ。
### 芸術と技能のバランスを保つ
> ソフトウェア開発は左脳(客観的で論理的、つまり**技能**)と右脳(主観的で創造的、つまり**芸術**)の両側を使う数少ない領域の１つだ。
> (中略)コードを書く私たちは良いコードを書くには独創力や想像力が必要とされることを知っている。
### 守破離
> ルールを破り、新境地に達するためには、まずルールをマスターしなければならないのだ。
OWASPから学ぶWAF〜その1〜

# 初めに
昨今、脆弱性に関する記事（情報漏えいなど）を見かけることが多くなりました。

技術が進化していく中でも、結局は人間が作るシステムなので、どこかに脆弱性があるのは仕方ない事なのかもしれません。
ただ、当たり前ですが、手を抜いて言い訳ではないです！

脆弱性を流出してしまうことは、損害賠償だけでなく、サービス、企業としての信頼を失うことになります。
そんなことを頭の片隅にはおいておく必要があると思います。

自分自身、Webアプリを開発するエンジニアとして、最大限のセキュリティ対策をしておくべきであり、またその知識を有しておきべきと思いました。

ということで、OWASP TOP10毎に、どのような攻撃があって、どのようなことを気をつけるべきか学び直しも含めて、まとめてみました。
（今回はTOP1〜3です）

# A01:2021 – アクセス制御の不備
## どんな攻撃がある？
### 認可
* 権限によって利用可能な機能があるが、誰でもその機能が利用できてしまう。
（例えば、直リンクで対象機能にアクセスするなど）
* URLパラメーターを改ざんして、他ユーザー情報にアクセスできてしまう。
### 認証
* ログインが必要なシステムにおいて、ログインせずに機能が利用できてしまう。
（例えば、ログイン必要な機能に直リンクでアクセスするなど）
### CORSの誤設定
* WebAPIを利用する際に、サーバーサイドのアクセス許可設定がパブリックになっているなど、アクセス元の制限がされていない。
（例えば、本来許可されていないアクセス元から、WebAPI通信できてしまう）

※CORSってなにって方はこちら（[なにそれから学ぶCORS](https://qiita.com/ragner_k/items/783a797c47a348490a66)）へお願いします。

## チェックポイント
- [ ] ログイン必要な機能にログインしていないユーザーがアクセスできないようになっているか
- [ ] ユーザーがアカウントの権限を超える機能が利用できないようになっているか
- [ ] ユーザーの権限に基づき、他ユーザー情報にアクセスできないようになっているか
- [ ] WebAPIでアクセス許可する接続元のみがアクセス可能になっているか


## 参考
https://owasp.org/Top10/ja/A01_2021-Broken_Access_Control/

# A02:2021 – 暗号化の失敗
## どんな攻撃がある？
### パスワードの暗号化、ハッシュ化
* パスワードデータが流出した際に平文やハッシュ化されておらず、パスワード復号化されて不正アクセスできてしまう。

## チェックポイント
- [ ] パスワードが平文で保存されていないか
- [ ] パスワードが暗号化のみ（ハッシュ化をしていない）でDBデータが流出すると、復号できてしまわないか
- [ ] 古いハッシュ化アルゴリズムを使用していないか（推奨は、Argon2、 PBKDF2、 scrypt、 bcrypt等）
- [ ] ソルトを使用しているか

## 参考
https://owasp.org/Top10/ja/A02_2021-Cryptographic_Failures/

# A03:2021 – インジェクション
## どんな攻撃がある？
### SQL
* 画面の入力項目もしくは、パラメータを改ざんして、内部で実行されるクエリを不正なものに変えることができてしまう。
（例えば、`or 0 = 0`みたいな条件が足されると、条件が正しく機能しない）

## チェックポイント
- [ ] アプリケーションからDB操作を行う際のユーザーが必要な権限以上の与えられていないか。
- [ ] クエリのパラメーターは、エスケープされているか
- [ ] サーバーサイドで入力検証されているか

## 参考
https://owasp.org/Top10/ja/A03_2021-Injection/
混同しやすいwebとインターネットを説明してみた

---

# 
---
# 目次
- webとは？
- ハイパーリンクとは？
- インターネットとは？


#  webとは
イメージとしては『宇宙と星』
宇宙という無限の空間（webの世界）に無数の星（Webページ）が散りばめられているイメージ。


# ハイパーリンクとは
このWebの中（宇宙の中）では星（webページ）と星（webページ）の間には橋がかけられており繋がっている。
この時星と星を結んでいる橋をかける仕組みをwebの中ではハイパーリンクと呼ぶ。　
ハイパーリンクとは⇨下記の画像で言う「文献や情報源』のようにクリックできるものをハイパーリンクと呼ぶ。
![スクリーンショット 2022-07-16 15.57.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602256/edd07325-f3ab-5754-4a24-d7c2a5d57d2e.png)

この青文字をクリックすると今現在のwebページ（星）から
クリックしたページ（星）を結び付けてくれる（橋をかけてくれる）仕組みをハイパーリンクと呼ぶ。
注意点；ここであるもの（乗り物）がないとクリックしてもクリックしたページは表示されない（星と星に橋をかけただけでは行きたい星（行きたいページ）に行けない）。


# インターネットとは
⇨ロケットのようなもの
⇨宇宙に散りばめられた星（webページ）と星（webページ）を自由自在に行き来する手段
2つの日付の差を求める（土日は除く）


```
CASE(MOD(  DATEVALUE( Time_to_Qualify_Start_date__c )  - DATE(1985,6,24),7),    
0 ,CASE( MOD( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) ,7),1,2,2,3,3,4,4,5,5,5,6,5,1),    
1 ,CASE( MOD( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) ,7),1,2,2,3,3,4,4,4,5,4,6,5,1),    
2 , CASE( MOD( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) ,7),1,2,2,3,3,3,4,3,5,4,6,5,1),    
3 ,CASE( MOD( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) ,7),1,2,2,2,3,2,4,3,5,4,6,5,1),    
4 ,CASE( MOD( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) ,7),1,1,2,1,3,2,4,3,5,4,6,5,1),    
5 ,CASE( MOD( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) ,7),1,0,2,1,3,2,4,3,5,4,6,5,0),    
6 ,CASE( MOD( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) ,7),1,1,2,2,3,3,4,4,5,5,6,5,0),    
999) -1

+(FLOOR(( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) )/7)*5) 
```

この部分で何週間差があるかをもとめて、5日分だけを得ている（土日を除くため）
```
+(FLOOR(( DATEVALUE( Time_to_Qualify_End_date__c ) - DATEVALUE( Time_to_Qualify_Start_date__c ) )/7)*5) 
```

残りの上の部分で曜日のずれからその週の中での日数を求めている感じ

何故か解説を求める質問がありました。

[質問](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HENeb)


これでも動作する？
```
EndDate__c-StartDate__c-
(
FLOOR((EndDate__c-StartDate__c)/7)*2
+
IF(AND(WEEKDAY(StartDate__c)=1,WEEKDAY(EndDate__c)<>7),1,
IF(CASE(WEEKDAY(StartDate__c),1,8,WEEKDAY(StartDate__c))>CASE(WEEKDAY(EndDate__c),1,8,WEEKDAY(EndDate__c)),2,
IF(OR(WEEKDAY(EndDate__c)=7,WEEKDAY(StartDate__c)=1),1,
IF(OR(WEEKDAY(EndDate__c)=1,WEEKDAY(StartDate__c)=7),2,
0))))
)
```
Java　SrtingBuilderの使い方


久しぶりにJava SkillCheckを解いていたら恐ろしく忘れていたので、、
備忘録として復習しながら記録しておくことにします。

【skillCkeckの設問】
Javaの標準入力から任意の文字列を入力し、取得した文字列を反転させた文字列を出力

A.　StringBuilder.reverseを使用

ここからは　Java　SrtingBuilderについてのまとめ

JavaのSrtingBuilderは文字列を扱うクラスのこと
StringとはJavaに用意された標準クラスの一つ「java.lang」というパッケージ
Stringクラスに格納されたデータは一度代入されると変更はできない。
例）String str = "いぬ" のあと値に　str ="ねこ"と入力しても出力はされるが
strが格納された”いぬ”のメモリ領域を参照しているのではなく、新たなstrとしてstr"ねこ"メモリ領域に格納される。

基本コード
```php:Main.java
public class Main {

    public static void main(String[] args) {
		StringBuilder sb =  new StringBuilder();
			sb.append("ABC");

			System.out.println(sb.toString());
```






各メソッドは個別で実行

```php:main.java
public class Main {

    public static void main(String[] args) {
        /*
         * StringBuilderクラスをインスタンス化
         * デフォルトで16文字分の容量（バッファ）を持つ。
         */
        StringBuilder sb = new StringBuilder();

        //文字列や他の値を追加する(StringBuilder.append)

        sb.append("ABCdefGHI");
        System.out.println(sb.toString());  // ABCdefGHI

        //格納されている文字列の並びを逆にする(StringBuilder.reverse)
        
        sb.reverse();
        System.out.println(sb.toString());  // IHGfedCBA
        
        //指定範囲の部分文字列を別の文字列に置換する(StringBuilder.replace)
        //public StringBuilder replace(int start, int end, String sb)

        sb.replace(3, 6, "DEF");
        System.out.println(sb.toString());  // ABCDEFGHI

       	sb.replace(1, sb.length() - 1, "-");
        System.out.println(sb.toString());  // A-I

        //指定した位置に文字列を挿入する(StringBuilder.insert)
        //StringBuilder insert(int offset, String str)

        sb.insert(2,"XYZ");
        System.out.println(sb.toString());    //ABXYZCDEFGHI

        //指定範囲の部分文字列を削除する(StringBuilder.delete)

        sb.delete(2, 5);
        System.out.println(sb.toString());    //ABCDEFGHI
       
        //指定範囲の部分文字列を取得する(StringBuilder.substring)
       
        System.out.println(sb.substring(3, 6));  // DEF
        
        //格納されている文字列の長さを取得する(StringBuilder.length)
       
        System.out.println(sb.length());    //9

    }
}

```





参照
https://it-kyujin.jp/article/detail/1285/
https://www.javadrive.jp/start/stringbuilder/index3.html
脱jQueryによるcocoonの使い方

## 概要
1対多のテーブル構造において、小テーブルのフォームを複数作成するためのGem。
また、公式には、「このgemはjQueryに依存しているので、すでにjQueryを使用しているRailsプロジェクトで最も有効」とあるが、脱jQueryを実施しているプロジェクトでは[Vanilla JS版](https://github.com/oddcamp/cocoon-vanilla-js)もある。
今回は脱jQueryで実装する。
導入が違うだけで実装方法はごく普通のcocoon。

## テーブル設計
投稿(post)が1に対してジャンル(genre)が多

## 導入手順
まずはGemfileに追加。
```
gem 'cocoon'
```
<br>
<br>

CDNにて導入。
私はimportmap採用でnode.js/yarnを極力排除したので、CDNにて導入。
(他に何かいい方法があれば教えてください)
```
<script src='https://unpkg.com/@oddcamp/cocoon-vanilla-js'></script>
or
<%= javascript_include_tag 'https://cdn.jsdelivr.net/npm/@oddcamp/cocoon-vanilla-js@1.1.3/index.min.js' %>
```
<br>

ちなみに公式だと
```
yarn add @oddcamp/cocoon-vanilla-js
```
が推奨されている。

## model
#### Post
```
class Post < ApplicationRecord
  has_many :genres, dependent: :destroy
  accepts_nested_attributes_for :genres, allow_destroy: true
end
```

#### Genre
```
class Genre < ApplicationRecord
  belongs_to :post
end
```

### accepts_nested_attributes_for
accepts_nested_attributes_forを使用することで、指定したモデルのデータを配列としてパラメーターに含めることができる。
[引用元](https://qiita.com/kmjooh/items/a1613531873a22fa7862)

## controller
子モデルも作成してあげること、子モデルもパラメーターとして受け取ってあげること。
```
class PostsController < ApplicationController

  def new
    @post = Post.new
    //子モデルも作成してあげる
    @post.genres.build
  end

  def create
    @post = Post.new(post_params)
    if @post.save
      redirect_to 
    else
      render :new
    end
  end

  private

  def recipe_params
    params.require(:recipe).permit(:title, 
                                   :content, 
                                   //子モデルもパラメーターとして受け取ってあげる
                                   genres_attributes: [:name]
                                   )
  end
end
```

## view
子モデルのgenreの部分のみ抜粋。
```
// フォームの追加ボタン
<%= link_to_add_association '追加' %>

// 追加ボタンを押すと、以下が複製されていく
<%= form.fields_for :genres do | genre | %>
 <%= genre.file_field :name %>
 // フォームの削除ボタン
 <%= link_to_remove_association '削除' %>
<% end %>
```
2022Windows環境構築メモ

# 2022Windows環境構築メモ

## これはなに？

windowsマシンで、自分が最低限やっておきたい開発環境構築メモ  
会社のネットワーク下や会社支給端末では認証プロキシ等で躓くケースがあり、金輪際同じ戸惑いをしたくないのでメモにした  

具体的には下記のセットアップをする
- WSL2
- hyper
- zsh
- VSCode
- Docker

## やること

### WSL2

WSL2を下記制約の元でインストールしたい
- Windows Storeが使えない

ダウンロードしてインストールする

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

https://wslstorestorage.blob.core.windows.net/wslblob/Ubuntu2204-220620.AppxBundle

AppxBundel実行してエラーになる場合は下記対応をする
1. AppxBundleをzip展開（AppxBundleはzip形式なので展開できる）
1. 適切なアーキテクチャの.appxもzip展開
1. 展開した中に含まれるexe実行

インストール終わったらWSL2にしておく
`wsl --set-version Ubuntu 2`

%USERPROFILE%\\.wslconfigにこれを書く
```
[wsl2]
memory=3GB
processors=2
```

### hyper

https://hyper.is/

shellのパスはこれを指定する
```json
{
        shell: `C:\\Windows\\System32\\wsl.exe`,
        shellArgs: ['~'],
}
```

### zsh

preztoが便利なのでこれ使う

https://github.com/sorin-ionescu/prezto

認証プロキシ対策で.zshprofileにこれかいとく
```zsh
export PROXY_ENDPOINT='http://ユーザID:パスワード@ホスト:ポート'
export HTTP_PROXY=$PROXY_ENDPOINT
export HTTPS_PROXY=$PROXY_ENDPOINT
export http_proxy=$PROXY_ENDPOINT
export https_proxy=$PROXY_ENDPOINT
export no_proxy=localhost
```

vimとgitめちゃ使うのでaliasほしい、.zshrcにこれかいとく
```
alias v=vim
alias g=git
```

.wgetrcにこれかいとく
```
check-certificate = off
```
プロキシ環境下など仕方ないときはこれしないとVSCodeの拡張が内部で呼んでるwgetでエラー出して困る

### VSCode

https://code.visualstudio.com/

インストールする

拡張は
- wsl
- vim

を入れる

setting.jsonを書く
```json
{
    "workbench.colorTheme": "Default Dark+",
    "window.zoomLevel": 2,
    "http.proxy": "見せられないよ！",
    "http.proxyStrictSSL": false,
    "editor.minimap.enabled": false,

    "vim.useSystemClipboard": true,
    "vim.insertModeKeyBindings": [
        {
            "before": ["j", "j"],
            "after": ["<Esc>"]
        }
    ],
    "vim.hlsearch": true
}
```

keybindings.jsonも書く
```json
[
    {
        "key": "ctrl+p",
        "command": "cursorUp",
        "when": "terminalFocus"
    },
    {
        "key": "ctrl+n",
        "command": "cursorDown",
        "when": "terminalFocus"
    },
    {
        "key": "ctrl+f",
        "command": "cursorRight",
        "when": "terminalFocus"
    },
    {
        "key": "ctrl+b",
        "command": "cursorLeft",
        "when": "terminalFocus"
    },
    {
        "key": "ctrl+a",
        "command": "cursorHome",
        "when": "terminalFocus"
    },
    {
        "key": "ctrl+e",
        "command": "cursorEnd",
        "when": "terminalFocus"
    },
    {
        "key": "ctrl+d",
        "command": "deleteRight",
        "when": "terminalFocus"
    },
]
```
参考にしたもの： 

https://qiita.com/cointoss1973/items/aa4d188cb68e3c162150

### Docker

Docker Desktop for Windowsは（ライセンス的に）使いづらいのでWSL2に入れる

https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository

これに書いてある通りにする

認証プロキシ下では`/etc/default/docker`に追記する
```
export PROXY_ENDPOINT=''
export HTTP_PROXY=$PROXY_ENDPOINT
export HTTPS_PROXY=$PROXY_ENDPOINT
export http_proxy=$PROXY_ENDPOINT
export https_proxy=$PROXY_ENDPOINT
export no_proxy=localhost
```

---

以上で最低限の環境が出来上がり
配列内の数字の合計（同じ数字を除く）再考察

# はじめに
前回、配列内の数字の合計（同じ数字を除く）の記事を書いたところ、コメントをいただきました。

[配列内の数字の合計（同じ数字を除く）](https://qiita.com/pipiyoyoyo/items/7d3229d051302ee64d8b)

ありがとうございます！
今回はそのコメントを元に気づいた点をまとめていきたいと思います。

# 環境
ruby 2.6.5

# 学んだこと
私の記述した模範解答だと、線形探索で配列内の数字が多くなればなるほど負荷が大きくなるそうです。
そこで、Hashを用いる方法を教えていただきました。

## 使用するメソッド
### tallyメソッド
[instance method Enumerable#tally](https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/tally.html)
``` ruby
["a", "b", "c", "b"].tally  #=> {"a"=>1, "b"=>2, "c"=>1}
```
自身に含まれる要素を数え上げた結果をHashで返してくれるメソッドです。
注意すべきはrubyの **version2.7から追加されたメソッド** であるという点です。
私の環境では使えませんでした。
`NoMethodError`が出てきてあたふたしました。

### sumメソッド
[instance method Enumerable#sum](https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/sum.html)

要素の合計を返すメソッドです。
``` ruby
{ 1 => 10, 2 => 20 }.sum {|k, v| k * v }  # => 50
```

ブロックが与えられた場合は、加算する前に各要素にブロックが適用されます。
つまり、この例では、
`( 1 * 10 ) + ( 2 * 20 )`が計算され、`50`が返り値となっています。

## 条件演算子

コメントいただいたコードをここで表記します。
``` ruby
def lone_sum(ary)
  counts = ary.tally
  counts.sum { |n, count| count == 1 ? n : 0 }
end
```

与えられたブロックは　`count == 1`なら n (key)を足し、それ以外は0を足すというコードになっているようですが、ここがよくわからなかったので調べました。

条件演算子というものだそうです。
[リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html#cond)

``` ruby
式1 ? 式2 : 式3
```
式1がtrueなら式2の値を返し、falseなら式3の値を返すというもののようです。

なるほど。
`count == 1`の時にはkeyの数字が計算される数字となるようになり、それ以外は値0が計算される数字になっているということですね！！
# 終わりに
rubyのバージョンも今の安定版は3.1.2となっていました。
[Ruby](https://www.ruby-lang.org/ja/downloads/)

常に進化を続けているので、キャッチアップを怠らないようにしないといけないということですね。
tkinterとpostgreSQLで釣果記録表を作成


# 背景
PythonのtkinterとpostgreSQLの学習を兼ねて
趣味の釣りで使える、釣果記録表を作成。
個人的に使用する目的で作成したので、
postgreSQLはローカルホストで使用しています。

# ディレクトリ構成
```
.
├── Fishing_log_app
│   ├── __init__.py
│   ├── __pycache__
│   ├── main_window.py・・・釣果テーブル画面に関するコード
│   ├── pgsql_method.py・・・DBへの登録、DBからの情報取得に関するコード
│   └── regist_window.py・・・釣果入力フォームに関するコード
├── README.md
├── __pycache__
├── main.py
├── venv
│   └── Pyenv_postgreSQL
└── デモ動画.mov・・・プログラムの操作している様子を撮影しました。
```

main.py実行で釣果テーブルが表示されます。

# デモ画面<br>
![デモ画像.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158871/3b31ad81-9e46-ea64-e74c-765eed141195.gif)


「更新」ボタンクリックでデータベースに登録されている、 釣果情報を釣果テーブルに表示。<br> 「登録」ボタンクリックで釣果入力フォームが表示され、 釣果情報を入力できます。 
釣果入力フォームの「登録」ボタンをクリックすることで、 入力した釣果情報をデータベースに登録できます。

# コード内容
GitHubのリポジトリはこちらになります。
https://github.com/yuuta-git12/Fishing_log.git
エンジニアとして長期インターンをして分かったこと

# 自己紹介
- 早稲田大学4年生（理工系、非情報系）
- インターン参加から5ヶ月程
- 元々プログラミング実務経験はなし

プログラミングに関しては授業で基礎を勉強したり、少しだけ趣味で基礎を勉強する程度でした。その時はC言語やC++などを独学で勉強していました。

# 長期インターンに応募した理由
自分のここまでの大学生活で楽しかったことはいろいろありますが、その中のひとつにプログラミングを使って試行錯誤していた時間があります。

よく聞く「自分のやりたいこと」「ワクワクすること」は何かと考えた時に、自分はプログラミングが思いつきました。
それを実務として経験できる場所はないかと考えた時に、友達が行っていたインターンに自分も参加させてもらったという形です。

# 具体的な業務内容
- アプリのサーバーサイドのシステム開発
機械学習を用いたレコメンドシステムの評価・開発に携わっています。実際にSQLやPythonを用いてコードを書くことで、データを解析したりシステムの評価をしています。
- ユーザーデータの解析
アプリを使用しているユーザーのログをSQL・Pythonを用いてデータとして成形することで、ユーザーの動向を解析しレコメンドシステムに取り入れています。
- コードや機械学習に関する勉強
実際に使われている機械学習手法に関して本や業務上のコードなどで勉強させて頂いています。言語に関しても同様に勉強させて頂いています。

# インターンをして得られたもの
ここからはインターンに参加して３ヶ月の自分が現在進行形ではありますが得られていると感じたことを書いていきます。
#### エンジニアとしての知識
上記で述べた機械学習やコードに関する知識を中心とした、IT分野に関する知識を得ることができています。

さらにそれらが蓄積されていくことで、**普段目にする情報に対して自分のアンテナが広がりました**。
Twitter, Note, Qiitaなどで目にする専門的な情報は前提となる知識がないと読みにくいものです。それらを自分の中に落とし込むには、独学だけではなく実務での経験が役に立つと感じています。

#### 頭の動かし方
コードを書いて実現させるものは、どれも自分のやったことのないことばかりです。
はじめはどうすれば実現できるのか想像できないことが多いですが、そこに辿り着くまでに必要な過程を分解して、筋道立てて考える力が現在進行形で鍛えられています。

さらにその中で上手くいかない過程が発生します。そこで
- 上手くいかない原因、ボトルネックとなっているのがどこなのかを考える力。
- どのような出力をしたらボトルネックが見つけられるのかを考える力。
- それらに対して仮説を立て、評価できる力。
- 自分だけで解決できないときに、何が上手くいっていないのかを伝える力。

これらが日々必要とされるため、鍛えられていると感じています。
まだまだ自分に足りていない能力であり、常に意識してこれからも成長していきたい部分でもあります。

#### サービスにおける膨大なデータ、ログの扱い方
エンジニアとしての知識に含まれる部分でもあるのですが、実際に使用されているアプリのデータを扱わせてもらっているのは貴重な経験だと考えています。

膨大なデータがどのようにテーブルとして分けられているのか、そのテーブル同士がどのように関連付けされているのか、これらが自分の書くコードに直接影響している部分でもあるので、身を持って学ばせてもらえています。

データの管理は現代のサービスにおいて重要です。普段使っているサービスにおいてもデータがどのように管理されているか考えるなど、サービスに対する解像度も上がったように感じています。

# まとめ
大学生のうちからエンジニアとしての経験を積ませてもらうと、得た知識経験からさらに拾える情報の幅が広がります。

これは余談ですが、大学生の自分でさえ色んな人と関わっていく中で、やりたいことに対してエンジニアが不足しているという人やサービスをたくさん見かけます。

そんな世の中自分にエンジニアとしての強みを作れると、自分の可能性が広がるのではないでしょうか。（何も考えずコードの勉強だけをしていても、逆に可能性が狭まってしまうと思います。）

偉そうなことばかり書いてしまいましたが、自分への自戒も込めてインターンに参加して感じたことを述べさせていただきました。