OmniAICreator/Qiita-1.07M huggingface dataset:
【PHP】平日のみの日付リストを日数指定で取得

土日祝日を除いた平日の日付リストを日数指定で取得します。
祝日判定には以前作成した[祝日取得クラス](https://qiita.com/akebi_mh/items/82cf4dbe70ac9913beb1)を利用してみました。

```php:weekdays.php
<?php
require_once('holiday_class.php');
class Weekdays {
  private $holiday;
  private $startDate;

  public function __construct() {
    $this->holiday = new Holiday;
    $this->startDate = new DateTimeImmutable;
  }

  public function setStartDate($ymd = 'now') {
    $this->startDate = new DateTimeImmutable($ymd);
  }

  private function isHoliday($date) {
    [$y, $n, $j] = explode(',', $date->format('Y,n,j'));
    return isset($this->holiday->getHolidayOfYear($y)[$n][$j]);
  }

  public function getDateList($days = 1) {
    $days = max(1, $days);
    $currentDate = new DateTime;
    $currentDate->setTimestamp($this->startDate->getTimestamp());
    $result = [];

    do {
      while(strpos('06', $currentDate->format('w')) !== false ||
            $this->isHoliday($currentDate)) {
        $currentDate->modify('+1 day');
      }
      $result[] = $currentDate->format('Y-m-d');
      $currentDate->modify('+1 day');
    } while(--$days > 0);

    return $result;
  }
}
```

####example####

```php:
// example
$weekdays = new Weekdays;

$date_list = $weekdays->getDateList(7);
print_r($date_list);
/*
  Array
  (
      [0] => 2021-09-17
      [1] => 2021-09-21
      [2] => 2021-09-22
      [3] => 2021-09-24
      [4] => 2021-09-27
      [5] => 2021-09-28
      [6] => 2021-09-29
  )
*/

foreach($date_list as $k => $v) {
  printf("%d: %s (%s)\n",
    $k, $v, ['日','月','火','水','木','金','土'][date('w', strtotime($v))]
  );
}
/*
  0: 2021-09-17 (金)
  1: 2021-09-21 (火)
  2: 2021-09-22 (水)
  3: 2021-09-24 (金)
  4: 2021-09-27 (月)
  5: 2021-09-28 (火)
  6: 2021-09-29 (水)
*/

$weekdays->setStartDate('2021-12-20');
$date_list = $weekdays->getDateList(20);
print_r($date_list);
/*
  Array
  (
      [0] => 2021-12-20
      [1] => 2021-12-21
      [2] => 2021-12-22
      [3] => 2021-12-23
      [4] => 2021-12-24
      [5] => 2021-12-27
      [6] => 2021-12-28
      [7] => 2021-12-29
      [8] => 2021-12-30
      [9] => 2021-12-31
      [10] => 2022-01-03
      [11] => 2022-01-04
      [12] => 2022-01-05
      [13] => 2022-01-06
      [14] => 2022-01-07
      [15] => 2022-01-11
      [16] => 2022-01-12
      [17] => 2022-01-13
      [18] => 2022-01-14
      [19] => 2022-01-17
  )
*/
```
【EC-CUBE】XMLを出力したい【4系】

**経緯**

EC-CUBE4系の案件にてXMLを出力する仕様だったので対応。

#手順
Controllerは普通に書きますが、アノテーションに「defaults={"_format"="xml"}」を定義します。
XMLフォーマットは画面同様twigにて記載します。
試しに指定したidのCustomerデータを表示するようにしてみます

```php:app/Customize/XmlController.php

class XmlController extends AbstractController {

    /**
     * @Route("/xml/customer/{id}", name="xml_customer", defaults={"_format"="xml"}, requirements={"id" = "\d+"})
     * @Template("Xml/customer.twig")
     */
     public function customer(Request $request, Customer $Customer) {
         return ['Customer' => $Customer];
     }

}
```

```twig:app/template/default/Xml/customer.twig
<customer>
  <id>{{ Customer.id }}</id>
  <name>{{ Customer.name01 }} {{ Customer.name02 }}</name>
  <kana>{{ Customer.kana01 }} {{ Customer.kana02 }}</kana>
</customer>
```

#補足
標準出力はUTF-8です。
昨今は問題ないと思いますが、やっぱり環境的にShift-JIS（Win Server向け）で出力したいよねって言う場合もあると思いますが、その場合はControllerでmb_convert_encodingしてしまいます。

```php:app/Customize/XmlController.php

class XmlController extends AbstractController {

    /**
     * @Route("/xml/customer/{id}", name="xml_customer", defaults={"_format"="xml"}, requirements={"id" = "\d+"})
     * @Template("Xml/customer.twig")
     */
     public function customer(Request $request, Customer $Customer) {
         $res = $this->render('Xml/customer.twig', ['Customer' => $Customer]);
         $content = mb_convert_encoding($res->getContent(), 'SJIS-Win', mb_internal_encoding());
         $response->setContent($content);
         return $response;
     }

}
```
ポリゴンの向き判定とかのメモ 

hole や自己交差のあるポリゴンは考えないとする.

## convex(凸) か concave(凹か)

convex の場合は e1 x e0 (e1 = v1 - v0, e0 = vN-1 - v0) の符号がすべて同じ.

https://mathworld.wolfram.com/ConvexPolygon.html

## concave

内角が 180 度以上であると concave である. エッジの cross-product(cos(theta))が負でれば concave.


## signed area

https://www.element84.com/blog/determining-the-winding-of-a-polygon-given-as-a-set-of-ordered-points

Shoelace Formula により, convex, concave どちらでも求まる(hole や self-intersect などのポリゴンは除く)

面の定義順(clockwise, counter-clockwise)が決まっている場合は, これにより面の向きも求めることができる
【悪用ダメ】簡単★ポートスキャンまとめ

# 初めに

こんにちは、初投稿です。
未経験エンジニアのクソ雑魚です。

何を思い立ってか、内気で引きこもってた僕が記事を書こうかなと思い始めました。
記念すべき初投稿内容は、公開サーバへのポートスキャン方法を書いてみようかなと。
___※悪用するのはやめてください。あくまでペネトレーションテストなどの社会への貢献のためにこれらの技術を使用してください。法に触れるので。___


# 目次

+ Openポート調査に役立つサイト
+ Nmapでのポートスキャン
    + 基礎編
    + 応用編
+ まとめ
　

# Openポート調査に役立つサイト
調査サイトは以下の二つです。
IoT機器のセキュリティ強化のために作られたサイトですね。

+ [Shodan](https://www.shodan.io/)
+ [Censys](https://censys.io/ipv4)


### Shodan
左上のSearch欄（灰色）に調べたいサイトのURLやIPを叩き込めばそのサイトの情報が見えます。

![shoda2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/c8b18930-cf7e-0939-5206-1e5c30b196e2.png)



### Censys
Search欄にIPv4アドレスを入れれば調査できます。
出てきたレポートにOpenポートが記載されているので、Shodanほどではないですが、いろいろ情報が見れます。

![censys1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/84db1128-110f-6249-773c-2a3a74ee8668.png)


# Nmapでのポートスキャン
今度はコマンドラインで実際にポートスキャンを行っていきます。
私が使用する環境は以下です。

+ Virtual Box 6.1.26
+ Kali Linux 2021-03

今回の調査対象例：XXX.XXX.XXX
※実際に「XXX.XXX.XXX」にはドメインやIPを入力します。
　検証する場合は自身のローカル環境に仮想でサーバを立てましょう。

## 基礎編

### SYNスキャン
コネクションを確立しない一般的なコマンドで、「-sS」オプションを指定します。
今回は「-p」オプションを使ってポート番号80をスキャンしています。

```
# nmap XXX.XXX.XXX -sS -p 80
```

### OSスキャン
サーバOS特定するときのスキャンです。

```
# nmap XXX.XXX.XXX -O
```

### コネクトスキャン
サーバとTCP接続を行ってスキャンします。

```
# nmap XXX.XXX.XXX -sT
```

### UDPスキャン
UDPでのスキャンです。フルポートスキャンすると大変時間がかかるので、「-p」でポートを指定すること 「-v」オプションのVerboseモードで進捗をターミナルに表示するようにしましょう。
※今回はSNMPプロトコルを優先的に調査します。


```
# nmap XXX.XXX.XXX -sU -p 161, 162 -v
```

## 応用編
実際に脆弱性検査を行う場合は、Kali Linuxで用意されているLuaで書かれたスクリプトを用います。

### vulnスクリプト
「-script vuln」オプションを使います。
そのほかのオプションとしては、「-p-」オプションを使って全ポートスキャンします。時間がかかるので「-v」オプションは必須です。また、脆弱性あるVersion特定のために「-sV」オプションも使用しましょう

```
# nmap XXX.XXX.XXX -v -p- -sV -script vuln
```

### safeスクリプト
「-script safe」オプションを使用します。
サーバに負荷がかかりすぎないようにスキャンするときに使用します。

```
# nmap XXX.XXX.XXX -v -p- -script safe
```



# まとめ
今回の初投稿はいかがでしたでしょうか？
一部のポートスキャンの方法をまとめてみましたので、セキュリティエンジニアの皆さんの助けになればなと思います。
【競プロ典型90問】010の解説（python）

## 概要
[競プロ典型90問](https://atcoder.jp/contests/typical90)の解説記事です。
解説の画像を見ても分からない（~~理解力が足りない~~）ことが多々あったので、後で解き直した際に確認できるようまとめました。

※順次、全ての問題の解説記事を挙げていく予定です。
※★５以上の問題は難易度的に後回しにしているため、投稿時期が遅くなる可能性があります。（~~代わりに丁寧に解説してくれる方いたらぜひお願いします~~）

## [問題010-Score Sum Queries](https://atcoder.jp/contests/typical90/tasks/typical90_i)

### 問題概要
N人の生徒が2つの組に分けられている時、各クラスの学籍番号L~R番の合計点を求める。
これをQ個のクエリにて行う。

### 解き方
まず初めに、愚直にQ個のクエリ1つ1つに対して、L~R番までの合計を都度求める方法が考えられますが、
この考えでは、L~R番までの合計を求める処理で、最大N回、
これを最大Q回行うと $O(QN)$ となり、TLEになってしまいます。

そこで今回は、**累積和**を用います。
※累積和について知りたい方は[こちら](https://qiita.com/drken/items/56a6b68edef8fc605821)をご確認ください。

そうすると、
１. 各組の累積和Sを求める(N回)

２. Q個のクエリに対して、$S[R]-S[L-1]$を求める。（$O(1)$をQ回）

となり、これは$O(N+Q)$の計算量で十分に高速に求められます。

![参考画像](https://raw.githubusercontent.com/E869120/kyopro_educational_90/main/editorial/010.jpg "公式解説画像")

引用元：[競プロ典型90問 Github](https://github.com/E869120/kyopro_educational_90)

### 実装

```python:answer.py

N = int(input())

# 1組、2組で分けて得点を格納する
c1 = [0]*N
c2 = [0]*N

for i in range(N):
  c, p = map(int, input().split())
  if c == 1:
    c1[i] = p
  else:
    c2[i] = p

# 各組で累積和 s1, s2を求める
s1 = [0]*(N+1)
s2 = [0]*(N+1)

for i in range(N):
  s1[i+1] = s1[i] + c1[i]
  s2[i+1] = s2[i] + c2[i]

# Q個のクエリに対し、L~R番までの合計を求める
# L番は和に含めるため、L-1番までの合計をマイナスする
Q = int(input())

for _ in range(Q):
  l, r = map(int, input().split())
  sum1 = s1[r] - s1[l-1]
  sum2 = s2[r] - s2[l-1]
  print(sum1, sum2)

```

## 最後に
問題の解説を読んでも他の人のコードを見てもさっぱり分からないという方の
力に少しでもなれれば幸いです。
コードの改善点やその他、ご意見などあれば、気軽にコメントください。
また、この記事を読んで理解できた方はぜひLGTMを押していただけると嬉しいです。
（~~記事投稿のモチベになります。~~）

ここまでお読みいただきありがとうございました。
【pytorch備忘録】multi-target not supported at なんちゃら/ClassNLLCriterion.cu:15というCrossEntropyLoss()のエラー対策

絶賛pytorch勉強中の人間の備忘録です。
あるデータに対しては動いていたはずの学習/検証のための関数を別のデータに適用したら```CrossEntropyLoss()```の部分が```multi-target not supported at なんちゃら/ClassNLLCriterion.cu:15```というエラーを吐くようになりました。
# 修正前
(不慣れで冗長なコードですすみません・・・・)

```train_valid_loop.pyの一部
def train_valid_loop(
    train_loader, valid_loader, valid_data_tensor, valid_label_tensor, model,
    n_epoch, optimizer):
    train_acc_list = []
    train_loss_list = []
    valid_acc_list = []
    valid_loss_list = []
    auc_score_list = []

    for epoch in range(n_epoch):
        train_loss = 0
        train_acc = 0
        valid_loss = 0
        valid_acc = 0
        best_auc_score = 0

        model.train()
        for xt, yt in train_loader:
            xt = xt.to(device)
            yt = yt.to(device)

            y_pred = model.forward(xt)
            loss = loss_fn(y_pred, yt)
            # errorの原因はここ↑
            # どういうわけかこの第２引数をyvのまま入力すると
            # multi-target(?)だと怒られる

            train_loss += loss.item() * xt.size(0)
            train_acc += (y_pred.max(1)[1] == yt).sum().item()

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        avg_train_loss = train_loss / len(train_loader.dataset)
        avg_train_acc = train_acc / len(train_loader.dataset)

        model.eval()
        with torch.no_grad():
            for xv, yv in valid_loader:
                xv = xv.to(device)
                yv = yv.to(device)

                y_pred = model.forward(xv)
                loss = loss_fn(y_pred, yv)
                # 同上のエラー

                valid_loss += loss.item() * xv.size(0)
                valid_acc += (y_pred.max(1)[1] == yv).sum().item()

            avg_valid_loss = valid_loss / len(valid_loader.dataset)
            avg_valid_acc = valid_acc / len(valid_loader.dataset)

        if epoch == 0 or (epoch + 1 ) % 10 == 0:
            train_acc_list.append(avg_train_acc)
            train_loss_list.append(avg_train_loss)
            valid_acc_list.append(avg_valid_acc)
            valid_loss_list.append(avg_valid_loss)
        # 出来たモデルでauc scoreを計算
        _,prediction = torch.max(
            model.forward(valid_data_tensor.to(device)),dim=1)#fold全体の予測値
        # tensor配列からnumpy配列に戻すときはdetach()を挟む必要アリ
        auc_score = roc_auc_score(valid_label_tensor.detach().numpy().copy(),prediction.to('cpu').detach().numpy().copy())
        if auc_score > best_auc_score:
            model_path = 'model_pth'
            torch.save(model.state_dict(), model_path)
        auc_score_list.append(auc_score)
    return train_acc_list, train_loss_list, valid_acc_list, valid_loss_list, auc_score_list
```
# 解決策
元のpd.DataFrameの訓練用ラベルをtensorに変換する手順で次元に冗長な部分があったっぽい？です。データの整形が甘かったのかも。
よってただ単に損失関数を計算する前に正解ラベル```yt,yv```を```squeeze_()```にぶち込む。

```修正後
# 該当箇所1
yt = yt.squeeze_()
loss = loss_fn(y_pred, yt)

# 該当箇所2
yv = yv.squeeze_()
loss = loss_fn(y_pred, yv)
```

これで正常に動いてくれました。

### 参考ページ
- [pytorch error: multi-target not supported in CrossEntropyLoss()](https://stackoverflow.com/questions/49206550/pytorch-error-multi-target-not-supported-in-crossentropyloss/49209628)
matplotlibの2DヒストグラムでX軸、Y軸、Z軸をログ表示する方法

# 使い所

matplotlib の 2Dヒストグラムで、全軸(X, Y, Z) をログ表示する方法を紹介する。 (横縦軸が log-log の 2dhist で zscale も log の図という意味です。)

## 注意点

[Matplotlib 2D histogram seems transposed]( https://stackoverflow.com/questions/43568370/matplotlib-2d-histogram-seems-transposed) によくまとまっているが、

- plt.hist2d は内部的に numpy.histogram2d を使っており、x, y は直感的な順番と同じ
- **matplotlib always expects y to be the first dimenstion** であるため、pcolormesh などは、転置した配列を入れる必要がある。

この違いについては理解しておこう。

## pcolormesh を使う方法

``` python:
# -*- coding: utf-8 -*-
"""2dhist_log_log_log.ipynb
Original file is located at    https://colab.research.google.com/drive/1VGo0WdmmUfxqnLdrWVJ98ZO4rJj0oX58
xscale log, yscale log, zscale log, for 2dhist using pcolormesh
"""

import numpy as np
from matplotlib.colors import LogNorm
import matplotlib.cm as cm
import matplotlib.pyplot as plt

# create sample data
x, y = np.random.exponential(size=(2, 100000))
x = x * 10 + 100
y = y * 2 

plt.figure(figsize =(10, 7))

# create uniform x, y range in a log space. 
xmin = np.log10(x.min())
xmax = np.log10(x.max())
ymin = np.log10(y.min())
ymax = np.log10(y.max())
print(xmin, xmax, ymin, ymax)
xbins = np.logspace(xmin, xmax, 100) # <- make a range from 10**xmin to 10**xmax
ybins = np.logspace(ymin, ymax, 50) # <- make a range from 10**ymin to 10**ymax

# create 2D hist using numpy.histogram2d
counts, _, _ = np.histogram2d(x, y, bins=(xbins, ybins))

# plot 2d hist
pcm = plt.pcolormesh(xbins, ybins, counts.T, norm=LogNorm(vmin=1, vmax=counts.max()), cmap='PuBu_r')
plt.colorbar(pcm)
plt.xscale('log')
plt.yscale('log')
plt.xlim(xmin=xbins[0])
plt.xlim(xmax=xbins[-1])
plt.ylim(ymin=ybins[0])
plt.ylim(ymax=ybins[-1])
```

生成される図がこちら。

![スクリーンショット 2021-10-13 2.04.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179652/9eff34e9-33e8-67b5-98c2-f1e9ca6645dd.png)


コードは、[google Colab](https://colab.research.google.com/drive/1VGo0WdmmUfxqnLdrWVJ98ZO4rJj0oX58?usp=sharing) 上にもあります。

## その他

エラーがでないのでわかりにくいのが、**plt**.pcolormesh を用いるか、**ax**.pcolormesh を用いるか、設定が不適切な適切な場合、エラーなく表示されてしまうのであるが、log にならなかったり、表示範囲が設定されないことがある。(ax の使い方が適切であれば動くのかもしれない。。)
仕事なんてパワプロと一緒

## 働く上で自分が大切にしている考え方

毎日毎日仕事で覚えることもわからないこともいっぱいだし、
失敗したら先輩や上司に怒られるし、自信無くしちゃうという考えが昔ありました。

もちろん怒ることが好きでやっている上司も世の中にはいますが、
自分がそうならないように、もしそうなった場合に自分への戒めとして、
普段から働く際に意識してることを記事にします。

## 仕事なんてパワプロと一緒
![ダウンロード (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653004/73bb2488-0338-c8b0-eae2-f01fd9ceeff2.jpeg)

パワプロ知ってますか？

KONAMIから発売されているゲームで1994年にスーパーファミコンで発売されてから現代まで続く人気ゲームです。

[実況パワフルプロ野球 wiki](https://ja.wikipedia.org/wiki/%E5%AE%9F%E6%B3%81%E3%83%91%E3%83%AF%E3%83%95%E3%83%AB%E3%83%97%E3%83%AD%E9%87%8E%E7%90%83)

要は、野球選手を育てて自分だけの野球チームを作るのがパワプロです。

## 前提
まず前提として仕事をする際、自分がコントローラーを持っていて、自分を操作してるイメージを持ってください。(これが大事です)

パワプロは育成の際に、どのトレーニングするかを選択し、
ステータスをどんどん上げていき選手を育てていきます。
![images (2).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653004/34d6ab83-1b95-f604-cbab-d1f69afde8af.jpeg)

練習をしすぎると体力が減っていき、体力が減った状態で練習すると怪我をし、
ステータスは下がるは、ターンを無駄にするわでいいことなんて一つもありません。
![images (3).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653004/b15e2a78-1eb8-dc78-fee7-7f7715969f71.jpeg)

ターン終了時には会話イベントが発生し、選択する項目によって、ステータスに変化があります。
![images (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653004/4d060432-0106-c676-7a0d-6d67c7fd012c.jpeg)

さらに、イベントや条件によってスキルを身につけることができます。
![images (5).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653004/84d517bf-665f-c2f9-ebf7-72fba55e27e0.jpeg)


仕事はこれと同じで、
最初はステータスも低いし、試合に勝てなくてもしょうがない。
毎日の積み重ねで徐々に試合に勝てていくものですし、
一人じゃ試合にすらなりません。チームで試合するものです。

## パワプロと一緒だと思う点

- 今日はどのトレーニング(仕事)をしようかなと選択し、ステータスを上げる。
- 疲れたら休む。回復してから仕事した方が、ステータスも上がる(仕事が進む)。怪我もしない。
- イベントで難しい仕事が入ってきた場合、「聞いた方が早い。」 or 「自分でやってみる。」 or 「断る」という選択肢があった場合、
    - 聞いた場合 →体力(時間)の消費が少ない、失敗する確率が低い、+α のスキルを教えてもらえる可能性ある。
    - 自分でやった場合 → 体力(時間)の消費が多いし、失敗する確率も高いが、調査スキルが上がる、自信に繋がる、スキルを取得できる。
    - 断った場合 → 別のトレーニングに時間を使える。
- 難しいミッションに挑戦したら、スキルが身につく。周りの評価も上がる。やる気も上がる。

なので、聞いたら怒られるかも、失敗したらどうしようなんて考える必要はなく、

ケガしたら休んで体力を回復させて、自分のステータスを向上させることだけ考えてください。

わからないことがあったら、聞くのか、自分でやるのか現状どっちのステータスが欲しいのかで考えてください。

怒られてやる気が下がっても、俺はダメなやつだ・・・。失敗しちゃった・・・。なんて考えない。

くそーと思いながら、ステータスを向上させることを考えてください。
(ゲームやってて上司キャラに怒られてもヘコまないですよね笑)

難しく考える必要はないです。
自分がゲームのプレイヤーで、自分というキャラを操作してるだけです。

## 上司やチームをリードするようになった人
どのポジションにどのキャラを配置すれば、チームが強くなることを考えますよね。
仕事も同じです。
ピッチャーの調子が悪かったら、休ませる、交代する、やる気出させるための行動を取りますよね。
仕事も同じです。
ただただ怒るだけなんて意味がありません。キャラのステータスをあげるプレイヤーになってください。

## 最後に
ネガティブな人が完全にポジティブになれるなんて思ってません。
ただ、ネガティブな人がネガティブな部分を出さないように我慢できるようになるとは思ってます。

みんながみんなこういう考えで働くことができるように、
毎日楽しく働ける職場を作りたいです。

毎日なんとなくとか誰かのためじゃなく、
仕事を自分の成長に繋げるものだと考えて働けるといいですね。
ドロップダウンでboolean型の値を扱う方法

基本的にboolean型の値をドロップダウンで表示することはないと思うんですが、仕事でそうしないといけない状況があり、手こずったので書き留めておきます。
したいこと：”１０日”と”１日”のドロップダウンを作る。10日を選んだ時はtrue、1日を選んだ時はfalseをデータベースに送信する。

まずはerbファイル。最初はrequired: trueを書いていたのだけど、うまく動作せずinclude_blankに変更。

```ruby:qiita.html.erb
<div class="form-group">
  <%= f.label :pay_day %>
  <%= f.select :pay_day, payment_day, { include_blank: false }, class: "form-control" %>
</div>
```
modelファイルにメソッドを追加。trueとfalseはkeyとして使えないのでinvertを使って逆に書くことに。これをしないとrubocopエラーが、、、

```ruby:qiita.rb
PAYMENTDAY = { "10日": "true", "1日": "false" }.invert.freeze
```
erbに記載していたpayment_dayメソッドをapplication_helperに追加。
select_fieldは配列で値を受け取る必要があるため、keyとvalueをループさせmapメソッドに入れる。


```ruby:application_helper.rb
def payment_day
    QIITA::PAYMENTDAY.map { |k, v| [v, k] }
  end
```
Dart 自分的！と？の使い方まとめ

Flutterをやっています。Dartは不可欠です。今回は、DartのNull Safeとか言うややこしいけど多分ものすごく良いものだろう仕組みで使われる、！と？について自分的にまとめてみました。

## Null Safeとは？

一時期「ぬるぽ」なる言葉が流行りまして、これはプログラムがNullを指した時にでるメッセージ[Null Pointer]から来たものですが、プログラマーはつねにNullと隣り合わせです。それを解決しようとしたのが、Null Safeですね。ここぐらいまでが、私の頭の限界ですので、とっととまとめます。

### 次の2つがある

:::note
2021年9月30日　コメントでご指摘いただきましたので、以下は実行時に変数を変換しているのでは無くコンパイラに知らせているだけだと追記させていただきます。
:::


１. 絶対Nullじゃないことを前提とした変数や返り値
２. Nullかも知れないことを想定した変数や返り値

これらをそれぞれ変換するには

？：１から２へ
！：２から１へ

つまり

１. 絶対Nullじゃないことを前提とした変数や返り値
　　　↑！　　　　　　↓？
２. Nullかも知れないことを想定した変数や返り値

と言う具合に変換できます。


## ？について

### 宣言

Nullかもしれない変数は、型名の後に？つけます。

```dart
int? i;
```

すると、こうなります。

```dart
int nullJanaiyo() {
  return 1;
}

int? nullKamo() {
  return null;
}

main() {
  int keppeki = nullJanaiyo(); //OK
  int? hoge = nullKamo(); //OK

  int keppeki2 = nullKamo(); //Error
  int? hoge2 = nullJanaiyo(); //OK
}

```

### 判定

#### ？が２つ。変数判定

？が２つ並んでいるのは、左辺をnullかどうか判定しています。次のような場合に用います。

```dart
  int? hoge = null;
  int keppeki = hoge; //Error
  int keppeki2 = hoge ?? 1; //OK
  print(keppeki2); //1がプリントされる
```


#### オブジェクトに？.　オブジェクト判定

オブジェクトの右に？.をつけることで、オブジェクトがNullでない場合に、.以降のメソッドを実行できます。オブジェクトがnullなら、メソッドは実行されません。


#### 

```dart
class ItsMe {
  void say() => print("hello");
}

ItsMe nullJanaiyo() {
  return ItsMe();
}

ItsMe? nullKamo() {
  return null;
}

main() {
  ItsMe me = nullJanaiyo();
  ItsMe? who = nullKamo();

  me.say(); //OK。helloがプリントされる
  who.say(); //Error
  who?.say(); //OK。何もプリントされない
}
```

## ！について

### しっかりしなさい！

#### 変数に！

Nullかも知れない変数は、実は！でNullじゃない変数に変換できます。次の３行目です。

```dart
  int? hoge = null;
  print(hoge); //nullがプリントされる
  int keppeki = hoge!; //文法は通る
  print(keppeki); //Error
```

このように、Nullかも知れない変数の後に！をつけると、Nullじゃない変数になります。ところがNullじゃないと言ったにも関わらずNullだったために、その後のprint文でエラーとなってしまいます。一方初めからNullかも知れないと言っていたhogeは、エラーになっていません。


#### 関数に！

変数同様、関数も！でNullじゃない関数にできます。

```dart
class You {
  late Function say;
  late Function? hya;

  setFunction(func) {
    this.say = func;
  }
}

main() {
  You you = You();

  you.setFunction(() => print("Hello"));
  you.say(); //OK
  you.hya(); //文法Error
  you.hya!(); //Error
}
```


## 終わりに

以上、自分の理解を深める意味も込めて、ダダダと書いてみました。参考になりましたら幸いです。
CCNA　イーサネット

今回はイーサネットに関する記述です。
イーサネットとはレイヤ1の物理層とレイヤ2のデータリンク層に
関することになります。

イーサネットには2つの規格があります。
DIXとIEEE802.3です。
イーサネットで主に使われているのはDIXです。

IEEEは2種類に分かれます。
データリンク層で、物理層に依存するMAC輻輳とデータリンク層独自のLLC副層になります。
MAC副層では802.3が使われ、802.2は共通の規格となっています。

イーサネットのフレームの中身を見てみましょう。
まず、宛先MACアドレスが6バイト、送信MACアドレスが6バイトです。
DIXだと、タイプと言って上位のプロトコルを表しています。
データは46~1500バイトです。そこにエラーチェック用のトレーラが付与されます。
IEEEだとタイプの代わりにデータの長さを表すフィールドがあり、
DIXのタイプに代わる部分はデータの中に制御情報として含まれています。

一度に送るとができるデータの量をMTU(Maximum Transmission Unit)と言います。

では、データリンク層で使うMACアドレスについて見てみましょう。
これは48ビットで16進数で表されています。0~9ABCDEFで表します。
そして、ネットワークの各ネットワーク機器のポートに製造時に重複無しで
割り当てられる番号です。物理アドレスとも呼ばれています。

前半が製造会社を表すベンダーコードで、OUIで
後半が製造会社が割り当てるシリアルコードと呼ばれています。

特別なMACアドレスとして3種類あります。
１：１をユニキャスト1:全をブロードキャストMACアドレス、1:多を
マルチキャストMACアドレスを指定します。
ブロードキャストMACアドレスはFFFF.FFFF.FFFFを指定し、
その時はブロードキャストフレームになります。

イーサネットの命名規則としては
最初が通信速度、単位はMbps。次が通信方式で、基本的には
デジタルを表すBASEです。最後はケーブルの種類を表します。
2や5は長さになります。２だと185メートル、5は500メートルです。
Tはツイストペアケーブルで、Fは光ファイバーケーブルになります。
Xは特別な技術使用を表します。
100MbpsがファストイーサネットでCat5以上を表します。
1000Mbpsは1ギガビットイーサネットでCat5e以上、
10Gbpsは10ギガビットイーサネットでCat6以上を表します。

この通信規格を自動で合わせる方法をオードネゴシエーションと言います。
自身の通信規格を知らせるFLP(Fast Link Pulse)を送り合うことで
擦り合わせを行います。

交通ルールとしてはCSMA-CD方式を使っています。

CSはCarrier Sense略で、データを送信できるか確認することを言います。
通信データ(キャリア)が全くない状態をアイドル状態と言います。
これが一定時間続くことをIFGで、これを確認するとデータを送ります。
MAはMultiple Accessで、全てのホストに送る権利があります。
CDはCollision Dectiveです。これは衝突があると、全てのホストに
ジャム信号が送られます。一定時間経つと再送する。これをバックオフと言います。

通信の方式は全二重通信と半二重通信に分かれます。
ハブの時は半二重通信ですが、スイッチの時は全二重通信になります。
全二重通信だと受信と送信が同時に行えます。半二重通信だと
どちらかしかできないので、コリジョンが起こります。
全二重通信は1:1の時になります。

その他のネットワーク機器として、リピータがあります。
これはレイヤ1の装置で、集線装置の機能はなく、リピータ機能のみの機器になります。

レイヤ2の機器としてブリッジがあります。
これは2つしか繋ぐことはできませんが、スイッチと同様に学習できる機器になります。
これにはフィルタリングという機能がついています。
これは正しい宛先以外は遮断するイメージになります。
MACアドレステーブルを用いますが、その様子をみてみましょう。

まず、フレームの流入があるとその送信元のポートとMACアドレスと
覚えます。これにはエージングタイムがあるので、
一定時間で消えます。
テーブルにないときは全部に送ります。
このテーブルはCAMテーブルと呼ばれることもあります。
登録方法は2つでダイナミック(自動)とスタティック(手動)に分かれます。

コリジョンの起こる範囲をコリジョンドメインと言います。
これは全二重通信だとそのリンクの範囲だけですが、
半二重通信やハブとハブを繋ぐ(カスケード接続　）と範囲が拡大します。

ですので、スイッチやブリッジはコリジョンドメインを分割する機能もあります。
これをマイクロセグメンテーションと言います。

スイッチを周状に繋ぐとブロードキャストドメインを引き起こすので、
こちらも注意しましょう。

#最後に

自分のアウトプットとして知識を出していますので、分かりにくい点等があると
思いますが、良ければ見て頂けると幸いです。
勉強中の身ですので、もし不明点や間違った点がありましたら是非コメント下さい。
3.1.Docker / docker-compose インストール・初期設定

# 概略

### なぜDockerを使うのか
皆さんは開発環境はWindows・検証/本番環境がLinuxのため、単体テスト自動化を行った場合開発環境ではうまくいったのに検証環境では動かないという経験はないでしょうか？環境差異があることによる開発の難しさです。
それらの諸問題解消するためには現時点ではDockerを使用するのが一番手っ取り早いでしょう
DockerをWindows開発環境で利用し、ほぼ本番環境と同じ環境を構築することにより、環境差異をなくし、テストを容易にします。

### Dockerとは
アプリケーションサービスを1つの仮想環境として実行するアプリケーションです。基本的には1環境1サービスとして「Dockerイメージ」を作成します。そして、下図のようにイメージをサービスとして1つ、または、複数起動します。起動したサービスを「Dockerコンテナ」といいます。

![Docker on WSL環境俯瞰図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96681/e72b8302-ebb8-4a2d-c453-3b9d699ef725.png)

細かい技術については説明を省きますがLinuxの仮想環境として同じ技術を使用した「LXD」（LXCの後継アプリケーション）がありますが、こちらはサービスを実行するOSを仮想環境として起動します。
Dockerの利点として下記の点が挙げられます。

* Docker仮想環境はコンテナ型と呼ばれるもので、Linuxカーネルに直接アクセスするためオーバーヘッドが少ない。
* 各アプリケーションの公式が[DockerHub](https://hub.docker.com/)と呼ばれるリポジトリサイトにDockerイメージを提供しているためサービスを利用しやすい。
* 環境のバージョンや詳細な設定はDockerfileやdocker-compose.yml等のファイルに記載している（環境のコード化：Infrastructure as Code）ためバージョンアップやサービス環境のリリース・配布が容易。
* Dockerイメージさえ作成できていればDockerコンテナを起動するのは数秒もかからない。必要なサービスを必要な時に起動できるためメモリやCPUの消費が少ない。

### docker-composeとは
Dockerは1つのサービス仮想環境を実行するためのアプリケーションでDockerfileは1つのDockerイメージをビルドするための設定ファイルですが、通常Webアプリケーション等は複数のDockerfileで定義されたDockerイメージを同時に起動してシステムを構築する必要があります。
そういった場合、docker-composeで複数のDockerコンテナの起動をサポートします。
上図にあるようなシステムを構築する場合、RDB、AP、Webコンテナの順に起動したり、各コンテナの永続化データ（コンテナが停止してもコンテナ内のデータを残す）の設定を行います。

インフラの構築と言えばプログラミングとは全く別の世界を想像するかもしれませんが、Dockerはプログラミングができる人ならばマスターするのも容易かと思います。失敗しても環境の作り直しが可能ですのでとにかく使ってみましょう。

# Docker関連アプリケーションのインストールと設定

#### 1.Docker (Community Edition) インストール
下記のコマンドをWSL端末で実行します。

```bash:Dockerインストール
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
$ sudo apt update && sudo apt upgrade -y && sudo apt install -y docker-ce
```

#### 2.Dockerコマンドの権限設定
デフォルトユーザ(develop)でdocker daemonを操作可能にします。
下記のコマンドをWSL端末で実行します。

```bash:dockerユーザ設定
$ sudo groupadd docker	
$ sudo usermod -aG docker $USER
```

#### 3.docker-composeインストール

1. [docker-composeの最新リリース](https://github.com/docker/compose/releases)のバージョンをリンク先のサイトで確認します。

1. 下記のコマンドをWSL端末で実行します。

```bash:docker-composeインストール
$ sudo curl -L "https://github.com/docker/compose/releases/download/<「1.」で調べたバージョン番号>/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```

#### 4.docker-composeコマンドの権限設定
下記のコマンドをWSL端末で実行します。

```bash:docker-composeコマンド権限設定
$ sudo chmod +x /usr/local/bin/docker-compose
```

#### 5.インストールバージョンの確認
下記のコマンドをWSL端末で実行します。

```bash:バージョン確認
$ docker --version
例) Docker version 20.10.8, build 3967b7d

$ docker-compose --version
例) docker-compose version 1.29.2, build 5becea4c
```

---

[3.Docker in WSL環境構築](https://qiita.com/boss_ape/items/fe48e4d7b69e83bed7c8) < 前 **3.1.Docker / docker-compose インストール・初期設定** 次 > 3.2.Docker環境構成検討
RailsのScaffoldを使って3分でwebアプリを作ってみる

Ruby on Railsのscaffoldを使って最速でwebアプリケーションを構築してみます。

#Scaffoldとは

まずはRuby on Railsのscaffoldとは何かについて解説します。

scaffoldとは、Railsに備わっているコマンドの１つで、ルーティングやコントローラー(controller)、ビュー(view)、モデル(model)とテーブル（データベース）の記述やファイルなどを自動で作成してくれるコマンドです。

本来、scaffoldは建築現場の足場やビルの窓を拭くときに使用される吊り足場を意味しているそうです。
Ruby on Railsのscaffoldにおいても、アプリケーションの足場であるMVC（上記で紹介したModel-View-Controller）等を指し示し、それらを簡単に自動生成してくれるそうです。

つまり、scaffold を使用することで、コントローラーやモデルを作成する手間を省くことができます。

scaffoldを使って作成されるルーティングは、Railsが定める７つのアクションになります。（index・show・new・edit・create・update・destroyアクションの７つです。）

以上がRails scaffoldについての簡単な説明になりますが、さすがにこれだけでは分かりにくいので、以下からは実際にRailsのscaffoldを使って、WEBアプリケーションを作ってみます。

#実装
実際にScaffoldを使ってアプリケーションを作ってみます。

まずはターミナル上で次のコマンドを打ち込みます。
すでに作成中のアプリがある場合は飛ばしてしまっても問題ないです。

```
rails new testapp
```

次にディレクトリを移動します。

```
cd testapp
```


ここからScaffoldを利用します


【scaffoldのコマンド書式】

```
rails g scaffold モデル名 カラム名①:データの型① カラム名②:データの型②・・・
```
上記の書式に沿って、モデル、カラムを設定しましょう。
今回は簡単にTweetモデルにcontentカラムのみが実装されるように記述していきます。

```
rails g scaffold Tweet content:string
```
このコマンドでmodel、controller、viewすべてが作成されました。
最後に

```
rails db:migrate
```
こちらを打ち込みmigreteします。
これで完成です。とっても簡単ですね。


#動作確認
最後に、どんなものが完成したのかを確認します。
まずは、アプリのディレクトリ上で

```
rails s
```
と打ち込みます。

起動が確認できたら、Chromeなどのブラウザで

```
http://localhost:3000/tweets
```
上記のURLを直接入力します。

![スクリーンショット 2021-09-17 0.05.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661164/4ece543c-c40e-71f9-1533-1d04560c1233.png)

このような画面が出たら成功です。
画面上の NewTweetから飛び、
なにか投稿を入力してみましょう。

投稿がうまくいけば下記のような画面になるはずです。
![スクリーンショット 2021-09-17 0.05.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661164/be22b32b-e90a-5770-18eb-7fcd3f27c3d0.png)

編集や削除などの機能も勝手に実装されていることが分かります。

##まとめ
今回Scaffoldを使ったwebアプリケーション構築の簡単な例を示してみました。

大規模なアプリ開発時にはあまり使えませんが、軽くテスト用のアプリを作りたかったり、　個人開発の小規模なアプリであれば開発スピートに大きく貢献してくれる便利な機能だと思います、ぜひ活用して効率的な実装をしてみて下さい。

ただ、個人的にはMVCモデルの流れやScaffoldでどんなコードが自動で実装されるのかを理解しないまま使ってしまうと今後の開発が大変になってしまうので、初めてアプリを作る方などは自分でひとつひとつ実装するのも良い手かなと思います。
Unity2020でNewtonsoft.Jsonを入れる

# この記事について

Unity2020でNewtonsoft.Jsonをプロジェクトに入れると`Multiple precompiled assemblies with the same name Newtonsoft.Json.dll included or the current platform. Only one assembly with the same name is allowed per platform.`のようなエラーが発生することがあります。

これの回避法メモです。



# 原因
Unity2020以降のVersionControl(旧UnityCollaborate)がNewtonsoft.Jsonを利用するようになり、すでにNewtonsoft.Json.dllが含まれているため。



# 対処法
## Newtonsoft.Json.dllを消す

単純に自前のNewtonsoft.Json.dllを消せば解決します。
__Unity2020, Unity2021では何もせずとも最初からNewtonsoft.Jsonが使えます。__

また、Newtonsoft.Jsonへの依存を明示するためにPackageManagerでパッケージを追加しておくといいです。
PackageManager左上の+ボタンから、「Add package from git URL...」で`com.unity.nuget.newtonsoft-json`を追加します。

これでNewtonsoft Jsonのパッケージが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31952/8deb117f-198e-4d4d-e672-55f03833865e.png)

["com.unity.nuget.newtonsoft-json"](https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@2.0/manual/index.html#jsonnet-is-a-popular-json-framework-for-net)というのはVersionControlが依存しているNewtonsoft.Json.dllを含むパッケージです。



## VersionControlを消す

Unityのバージョン管理機能を使っていなければVersionControlパッケージを消しても大丈夫です。
PackageManagerからVersion ControlをRemoveするだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31952/57c9aaac-8183-3a4a-ef25-b11495ef54f5.png)



## com.unity.nuget.newtonsoft-jsonのNewtonsoft.Json.dllを消す

VersionControlは消さずにパッケージ内のdllだけを消すこともできます。

`Library/PackageCache/com.unity.nuget.newtonsoft-json@2.0.0`ディレクトリをPackagesディレクトリ内にコピーします。
こうするとcom.unity.nuget.newtonsoft-jsonの中身を編集できるようになります。

あとはその中の不要なdllを消せば、自分で必要なdllを使えます。
rails newしてからsourcetreeを用いたGitの管理方法

##CLIは初心者殺し
誰しも最初に思うこと
####ターミナルでコマンド打ちながらGit管理するの普通に無理。
最近Gitについておぼろげながら理解してきたけど、初心者はGUIを用いて管理した方が精神衛生上良い。異論は認める。
なんとなく理解できてきたのはsourcetreeくんのおかげと言っても過言ではない。
この記事では、初心者向けにsourcetreeを用いたGitの管理手順をザックリとご紹介します。
あくまでも個人的なやり方なので、参考程度に。

##rails newからsourcetreeとGitHubの紐付けまで
- プロジェクトを作成
```
rails new 任意名
```
- （バージョンを指定しながらnewをするには以下を実行する
```
rails _6.0.4.1_ new 任意名
```）
- ディレクトリをVSCodeで開く
```
code .
```
- sourcetreeを開いて「メニューバー→開く」からディレクトリを参照
- 全てのファイルを選択してコミット
```
initial commit
```
- GitHubで新規リポジトリを作成「プロジェクト名→ディスクリプション→create」
- リポジトリのSSHをコピー
- sourcetreeを開き「設定→リモート→追加」から、リモートの名前：origin・URL/パス：コピーしたSSHとする
- mainブランチを右クリックしてoriginにプッシュ
- GitHubを開いてリポジトリにRailsのファイル群が追加されていれば完了

##おわり
これでハッカーが使う黒い画面（）を触らなくてもGUIで管理できるよ。
みんなも毎日一緒に草を生やそうね。
【LeetCode】アルゴリズム体操 9. Palindrome Number

# <a href="https://leetcode.com/problems/palindrome-number/">9. Palindrome Number</a>

**問題文**
> Given an integer x, return true if x is palindrome integer.

> An integer is a palindrome when it reads the same backward as forward. For example, 121 is palindrome while 123 is not.

**超訳**
与えられたint xが回文ならtrueを返してくれよな！
ちな121は回文で、123は回文ちゃうよ。

# 解答
### Stringで確認する
```java:Solution.java
class Solution {
    public boolean isPalindrome(int x) {
        String original = String.valueOf(x);
        String reversed = new StringBuilder().append(x).reverse().toString();
        return original.equals(reversed);
    }
}
```

### intで頑張る
```java:Solution.java
class Solution {
    public boolean isPalindrome(int x) {
        int num = x, reversed = 0;
        
        while (num > 0) {
            reversed = (reversed * 10) + (num % 10);
            num /= 10;
        }
        
        return x == reversed;
    }
}
```
マイナスの時は無条件falseになるので、while内を通らないかつfalseを返すのでよし！
としていいのか、最初に明示的にif文ではじいた方がいいのか…。でもif文を入れると実行速度が若干落ちるしなぁと。
このアルゴリズム問題を解く時、先輩方の場合はどうしますか。コメントいただけると幸いです。

# 実行結果
|Title      |Runtime |Memory |
|-----------|--------|-------|
|Stringで確認|14ms    |42.9MB |
|intで頑張る |11ms     |41.2MB |

# ひとこと
最近Java Silverを取得して、勉強が落ち着いたので新しい方面の勉強をしたいなと思って手を出しました。
まだまだひよっこですが頑張るドン！！！！！！
Typescript: TS2322: Type 'string' is not assignable to type '"xxx" | "yyy" | "zzz"'

引数やオプションの型指定で、`"xxx" | "yyy" | "zzz"` とされているときに、
タイトルのエラーに出会ったので備忘録

```typescript
{
  option: 'xxx' as 'xxx'
}
```

このようにキャストしてあげれば良いらしいです。

参考: https://bleepcoder.com/typescript/181851965/ts2322-type-string-is-not-assignable-to-type-absolute
ABC60 B - Choose Integers / C - Sentou 両方 diff 茶だった

https://atcoder.jp/contests/abc060/tasks/abc060_b

![abc60b_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/857310be-0790-0a9e-d7ea-ff3e5ace9d1d.png)
![abc60b_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/343fe36b-de2e-69b0-a785-a01a45346335.png)
![abc60b_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/f3653598-3736-7af4-598b-ed8ebc8f2dc1.png)
![abc60b_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/4a13a6fe-68c6-0acd-121b-90901f138dde.png)

**(B*n + C)%A == 0** を満たす、n を探そうと思った。
具体的には n を 1 から 10**6 まで全探索すれば一通り探索するイメージ。
Amax100,Bmax100,C<B　だから、行けるでしょ。

```ChooseIntegers.py
A,B,C = map(int,input().split())

for n in range(1,1+10**6):
    if (B*n+C)%A == 0:
        print("YES")
        exit()
print("NO")
```

https://atcoder.jp/contests/abc060/tasks/arc073_a

![abc60c_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/7cff8185-be1b-f758-f1f7-5b62b8a63c16.png)
![abc60c_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/aff8fd46-c990-e94d-f50b-fe958544c0b7.png)
![abc60c_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/c2b7cb5e-a4a5-e41c-d99a-82b9fd5b48a6.png)
![abc60c_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/60ba9232-07f7-a12d-71a3-c5a5d5de6f7f.png)

うん。文章をそのまま書いてみた。

```Sentou.py
N,T = map(int,input().split())
t = list(map(int,input().split()))

score = 0

for i in range(N-1):
    if t[i+1]-t[i] < T:
        score += t[i+1]-t[i]
    else:
        score += T

print(score+T)
```
Git branch で作業を分割しよう

#今回やりたいこと

Gitでプロジェクト管理。
AWSを使ったメール送信機能を追加するのですが...

Masterでpushするのは怖いので、branchで分岐させて正しい挙動をするのか確かめたいと思います。
<br>
# Git Master ブランチから分岐


```
$ git branch ブランチ名
```
で、ブランチを作れるのですがここでエラーが発生。
<br>

```
--> fatal: Not a valid object name: 'master'
```
とのこと。
  

<br>
<br>

どうやらMasterブランチが有効じゃないと怒られている模様。
---
原因は、エラーメッセージどおりの
<br>
「このMasterブランチで一度もコミットされていないよ。」
<br>

というもの
<br>
解決するには、空コミットしてやればいいのです。

```
$ git add .
$ git commit -a
$ git log 　　　　　// log確認は心配なら見ておく
```

---

問題なければ、もう一回

```
$ git branch ブランチ名
```
<br>
成功したら、一覧表示で確認
---

```
$ git branch -a

--> * master
      <new branch>

```

<br>
のような感じになっているはずです。

新しいブランチに移動するためにcheckoutします

```
$ git checkout <new branch>
```

<br>
これで新しいブランチの作成と移動が完了です!!

#参考資料
[BitBucket](https://www.atlassian.com/ja/git/tutorials/using-branches)
【メモ】初回コミット, pushを取り消したいとき


commit, push の取り消しコマンドの備忘録（忘備録）です。

### 初回のコミットを取り消す

```php
git update-ref -d HEAD
```

↑だけだとGithubなどのリモートリポジトリにはプッシュされたままなので、そちらを強制的に上書きするにはコチラ（変更点をローカルでコミットしてから行う）↓

```php
git push -f
// または
git push -f origin main
// main となっているのは任意のブランチ名
```

#### その他のpush取り消し方法

↓ローカルのソースの変更箇所はそのままでpushを取り消せる。

```php
git reset --soft HEAD^
```
ただし初回コミット・pushには通用しないのと、reset系のコマンドでは履歴を残さず修正することになるので注意。


```php
git reset --hard HEAD^
```
↑このコマンドでは add, commit ほかコード変更を丸っと取り消せるが、ローカルで苦労して変更した箇所も水の泡となるので注意。初回コミット・pushには通用しないのは同上。

##### 参考URL
[初回のコミットを取り消したいときにはgit update-refを使う](https://suzuken.hatenablog.jp/entry/2014/03/28/100311)
[git pushを取り消す方法](https://qiita.com/S42100254h/items/db435c98c2fc9d4a68c2)
[【git】最初のgit commitを取り消す - git update-ref -d HEAD もしくは git filter-branch](https://www.tweeeety.blog/entry/2017/04/18/000621)
ABC73 C - Write and Erase を解いた

https://atcoder.jp/contests/abc073/tasks/abc073_c

![abc73_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/fe024a20-5a34-b8c1-be4b-29fd0eb9cb9c.png)
![abc73_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/8b388a4c-be12-9297-d524-6d32693ab366.png)
![abc73_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/53753097-4d74-fe79-86a3-75e1fdc26a95.png)

配列を 10^9 用意して
True,False で最終的な True を数えようと思った。
だがしかし Memory error.

じゃあ辞書 or collection counter で
A の要素を数えて偶数 or 奇数で判断するしかないな。

```WriteAndErase.py
N = int(input())
dic = {}

for _ in range(N):
    a = int(input())
    if a not in dic:
        dic[a] = 0
    dic[a] += 1

cnt = 0
for i in dic.keys():
    if dic[i]%2 != 0:
        cnt += 1

print(cnt)
```
GitHubにSQLを認識させる方法

SQLファイルをGitHubにプッシュしても認識してくれなかったので、認識させる方法をメモ

# 手順
1. .gitattributesをリポジトリに追加
2. .gitattributesの内容に以下を追加

```.gitattributes
*.sql linguist-detectable=true
*.sql linguist-language=sql
```

# 結果
![スクリーンショット 2021-10-06 23.12.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455240/05b3ed70-93f9-2135-b8b1-50433c99a378.png)

無事認識してくれました。

# 参考
https://github.com/Thomas-George-T/HackerRank-SQL-Challenges-Solutions
位置情報を持つデバイスの管理を、Azure IoT Central のマップ表示を使ってやってみる

# はじめに
位置情報を持つデバイスのデバイス管理を手軽にやってみる為、Azure IoT Central のマップ表示を使ってみます。
想定しているデバイスは、数時間に数回程度しかデータを送ってこず、特定の場所に設置したままが基本運用となるデバイスを考えています。それでも、どのデバイスがどのタイミングでちゃんと通信出来ているかどうかを確認できるようにしておくことはとても大切なので、今回は、マップ表示を使ってデバイス管理をしやすくなる環境を作ります。




# この記事で分かること
* デバイスの位置情報を Azure IoT Central にアップロードするデータ形式
* Azure IoT Central のマップ表示を使って、デバイスの状態を一目で分かるようにする

こんなイメージです。
12時間以内に受信したデータの位置を表示するようにしているので、あるタイミングで数が減っていたりすると、通信不具合やバッテリなしになっているかが一目で分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/f404888e-23e1-72ec-e133-77723d81142f.png)




# Azure IoT Central 側の設定

## 1. デバイステンプレート：モデルの設定
* [表示名]　　　　　　　：任意（今回は、DeviceLocationとしています）
* [名前]　　　　　　　　：任意（今回は、DeviceLocationとしています）
* [機能の種類]　　　　　：Telemetry
* [セマンティックの種類]：**Location** ←これ大切（ここで位置情報を受けるテレメトリを指定します）
* [スキーマ]　　　　　　：Geopoint（セマンティックの種類で、Location を選択するとこれが入ると思います）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/4bc9bd00-b118-af0d-4ac9-9e032cd8ee7d.png)

## 2. デバイステンプレート：ビューの設定
[デバイスの視覚化] から、デバイス毎のマップ表示のビューを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/9feddc00-d884-404d-644e-30add3f08194.png)

[マップ(プロパティ)] [マップ(テレメトリ)] の２種類がありますが、今回はテレメトリを使用します。（デバイス側からも位置情報はテレメトリとしてアップロードします)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/135d3964-91ec-3a16-ed06-231a5092a7ec.png)

[設定] から [マップの構成] を開きます。
[場所] を選択すると、先ほど [セマンティックの種類] で **Location** を指定したモデルのみが選択できます。
ここに何も出てこない場合は、上記の設定が正しくできていないと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/7e759dc0-f232-b70c-3c44-d4bd49b1ab53.png)

上記の手順でデバイステンプレートに、位置情報のテレメトリを作成して、デバイス管理がしやすくなるように [ビュー] にマップ情報を可視化できるような準備ができました。あとは、デバイステンプレートから、デバイスの生成は行っておきます。

# デバイス側
デバイス側から送信するペイロードは、次のようなJSON形式とする必要があります。

```
{
  "DeviceLocation": {
    "lat": 47.64263,
    "lon": -122.13035,
    "alt": 0
  }
}
```

以下は、Node.js で記述したサンプルになります。
本来はデバイスの位置情報を入れるのですが、今回は例ということで適当な固定値を入れています。

```javascript
var latitude = 36.571120795849;
var longitude = 136.6644938866354;
var DeviceLocation = '{"lat":' + latitude + ', "lon":' + longitude + ', "alt": 0}';
var telemetryPayload = '{"DeviceLocation":' + DeviceLocation + '}';
```

# Azure IoT Central のデバイス情報
各デバイスのデバイス情報から、デバイステンプレートで設定したマップ情報を見ることができます。
こんな感じで見れます（マップ自体は少し寂しい気はしますがｗ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/54e00c96-8fdc-6248-e19b-556e0e7bd895.png)

# Azure IoT Central のダッシュボード
複数デバイスがある場合は、１つのマップ表示で複数台の位置情報をマッピングすることもできます。
地図がまだまだ発展途上ですが、これだけでもどのあたりに設置したデバイスがちゃんと通信出来ているかどうかを一目で確認することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/f404888e-23e1-72ec-e133-77723d81142f.png)

# まとめ
位置情報を持つデバイスのデバイス管理を、Azure IoT Central のマップ機能を使って試してみました。
数時間に数回程度しかデータを送ってこないような特定の場所に設置するデバイスならば、このような管理を行うことでどのあたりに設置したデバイスが正常に動いているかどうかは一目で確認できるようになります。
また、日本における地図自体の向上はまだまだ期待したいところではありますが、そのうち更新されていくことを記載しながらも現状でもそれなりには使えるシーンがあると思います。

私の場合は、少なくてもこれで設置した３台が無事に過去12時間以内に通信があったかどうかが一目で確認できるようになったので、使い勝手は良いと思っています。

# 公式ドキュメント

https://docs.microsoft.com/ja-jp/azure/iot-central/core/howto-use-location-data
ciscoSWの enable password と enable secret の違い

## 勉強前イメージ

基本的に使うのは enable secretだけど・・・・
違いは平文と暗号化されて表示されるかのだと思ってたけど、
password-encryption 使うと暗号化されて secret 使うのはよくわからん

## 調査

### enable password とは

パスワードを暗号化しない特権モードへのパスワードの設定で、
`#enable password [パスワード]` で設定を行います。
設定方法とconfigの表示は以下になります。


- 設定

```
Switch(config)#enable password pass
```

- config

```
...
!
enable password pass
!
...
```

この場合だとconfigは平文で表示されてしまいます。

### enable secret とは

特権モードのパスワード設定で暗号化してパスワード設定するコマンドになります。
`#enable secret [パスワード]` で設定を行います。
設定方法とconfigの表示は以下になります。


- 設定

```
Switch(config)#enable secret pass
```

- config

```
...
!
enable secret 5 $1$mERr$WWYFDFflcd5FpJh6NNHr41
!
...
```

暗号化されて表示されます。

### 違い

- 気になったこと

気になったこととして、 `service password-encryption` コマンドを使えば
以下のように enable secret でも config上暗号化は可能です。
なぜ enable secret 使うのか確認します。

```
!
enable password 7 08314D5D1A
!
```

- enable password と enable secret の違い

enable secretはMD5アルゴリズムを使用してハッシュ処理されているので、
enable secret を復元することは不可能になります。

## 勉強後イメージ

暗号化されてるかされてないかぐらいだと思ってたけど
その違いがあったのね。
あとciscoのサイトにはsecret使えって書いてあった

## 参考

- [Cisco IOS のパスワード暗号化情報](https://www.cisco.com/c/ja_jp/support/docs/security-vpn/remote-authentication-dial-user-service-radius/107614-64.html)
- [◆パスワードを設定する](http://atnetwork.info/ccna/password.html)
TLA+ のインストール方法

<a href="https://twitter.com/riita10069"><img src="https://img.shields.io/badge/Author-riita10069-4FC08D.svg?logo=&style=plastic"></a>

## environment

MacBook Pro (13-inch, M1, 2020)
Apple M1
16GB

## Java

```
brew install java
```

## TLA+

https://github.com/tlaplus/tlaplus/releases/download/v1.7.1/TLAToolbox-1.7.1-macosx.cocoa.x86_64.zip
↑
これをインストール

## PT Library

```
git clone https://github.com/Apress/practical-tla-plus.git
```

![](https://storage.googleapis.com/zenn-user-upload/b5e2b596a601f53f8127b690.png)

Add Directory で clone したディレクトリからPTディレクトリを指定してApply

## TLA+チートシート

こちらは、TLA+の学習法などをまとめ、さらに基本構文がまとまっている記事です。
https://zenn.dev/riita10069/articles/bc689cae1c7bc0
opencsvのCSV書き出し(CSVWriter)で囲み文字をなくす

# 結論

CSVWriterの引数多いほうのコンストラクタにICSVWriter.NO_QUOTE_CHARACTERを渡す。
char型で定義されているので`¥u0000`を渡してもいいはず。

# 実例

```java
Path p = Paths.of('xxx');
try (
BufferedWriter bw = Files.newBufferedWriter(p, StandardCharsets.UTF_8);
CSVWriter writer = new CSVWriter(writer
    , CSVWriter.DEFAULT_SEPARATOR
    , CSVWriter.NO_QUOTE_CHARACTER
    , CSVWriter.DEFAULT_ESCAPE_CHARACTER
    , CSVWriter.DEFAULT_LINE_END) {
    // ... 
}
```

# 参考

http://opencsv.sourceforge.net/apidocs/com/opencsv/CSVWriter.html#CSVWriter-java.io.Writer-char-char-char-java.lang.String-
GitHub ⇄ CircleCI 連携時に「This build was not run because no followers were detected. This may be due to a VCS name change.」というエラーが発生

## 背景

私が今携わっているプロジェクトの開発においては、CI/CD環境の構築にCircleCIを利用しています。

GitHubのリポジトリと連携し、変更内容をプッシュすれば後は「ビルド → テスト →　デプロイ」といったフローを自動で行ってくれるように設定しているのですが、ある日急にCircleCIが動かなくなるといった事象に遭遇。

![スクリーンショット 2021-10-06 22.09.09_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/ada8d5a9-0a03-4f23-62b6-fe6be469a6e4.jpeg)

ダッシュボードを見てみると、

> <font color="Red">We did not test this push because nobody is following the project Troubleshoot</font>
<font color="Red">This build was not run because no followers were detected. This may be due to a VCS name change. This should resolve soon, or your admin can reset the webhooks.</font>

という見慣れないエラーが発生していたのですが、ググっても解決方法がパッと出てこなかったため非常にてこずりました。

今回はコイツの解決方法についてメモ書きしておきます。

## 原因

![スクリーンショット 2021-10-06 22.38.08_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/6f37dd13-154b-e7c6-75e5-6d7c668ac9bf.jpeg)

単刀直入に結論から言うと、該当のプロジェクトをフォローしているユーザーが1人も居なかったから。（Project Settingsからフォロー可）

エラー文の

- We did not test this push because nobody is following the project.
- This build was not run because no followers were detected.

という箇所はこの事を言っていたわけですね。冷静に考えれば「確かになぁ」といった感じなのですが、あまりにも意外なところだったので見落としてしまいました。

実は、そのプロジェクトはここ最近メンバーの大幅な入れ替わりが生じ、前任の中枢メンバーが先月末で会社を退職してしまったという背景があります。

で、ちょうど代わりに自分がアサインされたわけですが、その過程において「前任者によるプロジェクトへのフォローが外れる + 自分はまだフォローしていない = プロジェクトへのフォロワーが0人になる」といった結果になってしまっというのが事の顛末...。

引継ぎが上手く行われなかった事と、CircleCIへの自分の理解が足りなかった事が主な要因といった感じです。（「プロジェクトをフォローしている人が0人だとビルドが回らない」という仕様を知りませんでした...。）

![スクリーンショット 2021-10-06 22.58.37_censored_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/6b76fd33-7ec7-1894-aaa3-0428833d2faa.jpeg)

プロジェクトをフォローし、再度GitHubにプッシュしたところ、無事ビルドが走り始めました。

## あとがき

以上、

> <font color="Red">We did not test this push because nobody is following the project Troubleshoot</font>
<font color="Red">This build was not run because no followers were detected. This may be due to a VCS name change. This should resolve soon, or your admin can reset the webhooks.</font>

に対する対処法でした。

割としょうもない部分で時間を食ってしまった感が強いので、今後は注意したいです。
setodaNoteCTF - Redacted 150 

#問題

https://ctf.setodanote.net/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/63ab01b7-cb12-d365-4aba-02859dc65af2.png)

#解いてみた

見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/deb0e0f0-645c-3874-4952-1b6fe5e1ff6e.png)

PDFです。
この黒塗りの部分にflagが書かれているということでしょうか。

wordで開くと黒塗りのところが削除できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c44b4cb7-29e8-b4f1-eb73-d2c29306671e.png)
rails 7.0で`Enumerable.sum`を使用した時に発生するdeprecated warning (Rails 7.0 has deprecated  Enumerable.sum in favor of Ruby's native implementation available since 2.4.)について

rails 7.0では数値以外のArrrayで第一引数を指定せずに`Enumerable.sum`を使用していた場合に以下のdeprecated warningが発生します。

``` 
Rails 7.0 has deprecated  Enumerable.sum in favor of Ruby's native implementation available since 2.4.
Sum of non-numeric elements requires an initial argument.
```

# 理由

rails 7.1からrails実装の`Enumerable.sum`がなくなりrubyの`Enumerable.sum`を呼び出すようになる為、数値以外のArrayに対し`sum`メソッドを呼び出す場合には第一引数が必須となります。

# 詳細
rubyの`Enumerable.sum`は第一引数に対して`+`メソッドを実行します。
この第一引数のデフォルトが`0`なので数値の場合はそのまま処理ができますが例えば文字列の場合は`0`に対して`String`を`+`しようとするため`TypeError`発生します。

https://docs.ruby-lang.org/ja/latest/method/Array/i/sum.html

## rails 7.1以前
`inject(:+)`された結果を返すので文字列の場合も結合可能

```ruby
> ["a", "b"].sum
=> "ab"
```

## rails 7.1以降
初期値0に対して文字列を+しようとしてエラーになる

```ruby
> ['a', 'b'].sum
(irb):94:in `+': String can't be coerced into Integer (TypeError)
```

```ruby
> ['a', 'b'].sum('')
=> "ab"
```
UISceneで最初に開くControllerを分岐させる

#今回の内容

* 状況に合わせて、最初に開く`Controller`を分岐させる。

#コードと簡単解説

* `func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {}`内で、`UserDefaults`で保存した`Bool値`によって開くControllerを選択します。

* `.rootViewController`で最初に表示する`Controller`を設定します。

```Swift:
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
       
        if (UserDefaults.standard.object(forKey: "selectViewBool") != nil) == true{
            
            window = UIWindow(windowScene: scene as! UIWindowScene)
            window?.makeKeyAndVisible()
            window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "AAAAA") as! AAAAAViewController
        }else{
            
            window = UIWindow(windowScene: scene as! UIWindowScene)
            window?.makeKeyAndVisible() 
            window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "BBBBB") as! BBBBBViewController
        }
      
        guard let _ = (scene as? UIWindowScene) else { return }
    }
```

# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
LinuxへのQt6インストール + CMakeによるビルド

# LinuxへのQt6インストール + CMakeによるビルド

LinuxにQt6をインストールした際の自分用メモです。
確認した環境は、Ubuntu 20.04 LTS (Windows10 WSL2)になります。

## Qtのインストール

https://www.qt.io/download を開いてQtアカウントを作成します。

「Downloads for open source users」->「Downloads the Qt Online installer」-> 
「View Other Options」-> 「Qt Online Installer for Linux (64-bit)」を選択します。

qt-unified-linux-x64-\<version\>-online.runがダウンロードされるので、以下のコマンドでインストーラを起動します。

```bash
$ chmod u+x ./qt-unified-linux-x64-<version>-online.run
$ ./qt-unified-linux-x64-<version>-online.run
```

インストーラ上の操作
* 「Installation Folder」タブでは「Custom installation」を選択
* 「Select Components」タブでは「Qt 6.2.0」->「Desktop gcc 64-bit」のみを選択

## Qt Creatorの起動確認

次に、Qt Creatorの起動確認を行います。
※ここでは起動確認のみで、実際のビルドはコマンドライン上で行えるようにします。

```bash
$ <install path>/Tools/QtCreator/bin/qtcreator
```

Qt Creatorを起動させようとしますが、エラーが発生してしまいます。

```bash
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found
```

調べたところ、こちらのページに解決策が記載されていました。
https://forum.qt.io/topic/93247/qt-qpa-plugin-could-not-load-the-qt-platform-plugin-xcb-in-even-though-it-was-found

```bash
$ QT_DEBUG_PLUSINS=1 <install path>/Tools/QtCreator/bin/qtcreator
```

を実行すると、ライブラリが見つからないとのデバッグメッセージが出力されます。

```bash
Cannot load library <install path>/Tools/QtCreator/lib/Qt/plugins/platforms/libqxcb.so: (libxcb-xinerama.so.0: cannot open shared object file: No such file or directory)
```

libxcb-xinerama0というライブラリのインストールによりエラーは発生しなくなり、GUIの起動が確認できました。

```bash
$ sudo apt update
$ sudo apt search libxcb-xinerama
$ sudo apt install libxcb-xinerama0
$ <install path>/Tools/QtCreator/bin/qtcreator
```

## CMakeを使ったビルド

CMakeを使ってコマンドライン上でビルドできるようにします。
以下のページを参考にしています。
https://doc.qt.io/qt-6/cmake-get-started.html


CMakeのfind_pakcageでQtのパッケージを見つけられるように、.bashrcにPATHを追加しておきます。

```bash:.bashrc
export CMAKE_PREFIX_PATH=<install_path>/6.2.0/gcc_64/lib/cmake
```

CMakeLists.txtと簡単なサンプルプログラムを作成します。

```cmake:CMakeLists.txt
cmake_minimum_required(VERSION 3.16)

project(hello VERSION 0.0.1 LANGUAGES CXX)

set(CMAKE_VERBOSE_MAKEFILE TRUE)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

find_package(Qt6 COMPONENTS Widgets REQUIRED)

set(CMAKE_CXX_FLAGS "\
-Werror -Wall -Wextra -pedantic -Wcast-align \
-Wcast-qual -Wconversion -Wdisabled-optimization \
-Wendif-labels -Wfloat-equal -Winit-self -Winline \
-Wlogical-op -Wmissing-include-dirs -Wnon-virtual-dtor \
-Wold-style-cast -Woverloaded-virtual -Wpacked -Wpointer-arith \
-Wredundant-decls -Wshadow -Wswitch-default -Wswitch-enum \
-Wunsafe-loop-optimizations -Wvariadic-macros \
-Wwrite-strings -Wno-missing-field-initializers"
)

add_executable(hello hello.cc)
target_link_libraries(hello PRIVATE Qt6::Widgets)
target_compile_features(hello PRIVATE cxx_std_17)
target_compile_definitions(hello PRIVATE $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
```

```cpp:hello.cc
#include <QApplication>
#include <QLabel>

int main(int argv, char *args[])
{
    QApplication app(argv, args);
    QLabel label("Hello World!");
    label.show();

    return app.exec();
}
```

makeしてバイナリを実行すると、無事にGUIのウィンドウが表示されました。

```bash
$ mkdir build; cd build
$ cmake ..; make
$ ./hello
```
setodaNoteCTF - i_knew_it 120 

#問題

https://ctf.setodanote.net/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/343d84b6-bffc-a5a8-d226-21d06779c280.png)

#解いてみた

ファイルを見ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6de30303-56dc-596d-bf67-2b774ed34393.png)

idaの画面ですね。
暗号化のロジックはわからないです。

問題文の「このアセンブリ、見た瞬間あなただと分かりましたよ。」があやしげなのでいろいろ検索してみると「見た瞬間 暗号化」で以下のサイトが出てきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/26e496d8-944d-2f85-3e7f-c4cfb937a513.png)

わからんからとりあえずこれを入力してみたら正解でした。