OmniAICreator/Qiita-1.07M huggingface dataset:
【PHP】PHP課題・名簿の作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/67586430-6743-f98b-c9db-7134eca6ad9a.png)


```PHP

<?php

echo $aa = $_SERVER['HTTP_HOST'];

echo $bb = $_SERVER['REQUEST_URI'];

$line = [];

define('FILE_PATH', './members.csv');

  if ($_SERVER['REQUEST_METHOD'] === 'POST'){

    if (isset($_POST['submit']) === TRUE) {
      $data[] = $_POST['id'];
      $data[] = $_POST['name'];
      $data[] = $_POST['address'];
      $data[] = $_POST['tel'];
    }

    $fp = fopen(FILE_PATH, 'a');

    if ($fp !== FALSE) {
      $line = implode(',' , $data);
      $result = fwrite($fp, $line . "\n");  

      fclose($fp);
    }
    //多重リロード防止
    header("Location:http://".$aa.$bb);

  }
   
 //ファイルが読み込み可能ならば、

  $fp = fopen(FILE_PATH, 'r');
  if ($fp !== FALSE) {

    $text = fgetcsv($fp);

    while ($text !== FALSE) {
      $lines[] = $text;
      $text = fgetcsv($fp);
    }
    fclose($fp);
  }
?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>名簿管理アプリ</title>
    <style>
      label {
        display:block;
        margin-bottom: 10px;
      }
      table {
        border-collapse: collapse;
      }
      th, td {
        border: solid 1px black;
        padding: 5px;
      }
  </style>
</head>
<body>
    <h1>名簿作成アプリ</h1>

    <form method="post">
        <label>ID:<input type="text" name="id" required></label>
        <label>名前:<input type="text" name="name" required></label>
        <label>住所:<input type="text" name="address" required></label>
        <label>電話番号:<input type="text" name="tel" required></label>
        <input type="submit" name="submit" value="送信">
        
    </form>
    
    <table>
      <thead>
      <?php  if(isset($lines)){ ?>
        <tr>
          <th>ID</th>
          <th>氏名</th>
          <th>住所</th>
          <th>電話番号</th>
        </tr>
        <?php } ?>
      </thead>
      <tbody>
        <?php 
            if(isset($lines)){
              foreach ($lines as $line) { ?>
                <tr>
                    <td><?php print $line[0]; ?></td>
                    <td><?php print $line[1]; ?></td>
                    <td><?php print $line[2]; ?></td>
                    <td><?php print $line[3]; ?></td>
                </tr>
          <?php } ?>
        <?php } ?>
      </tbody>
    </table>

</body>
</html>
```

```
可搬性のあるmake install

普通に`make install`すると中間生成物も含めて`/usr`や`/usr/local`に生成される羽目になることが多い．
可搬性がないし，環境を汚したくないので，ビルド用ディレクトリで完結するようにビルドする．

Open Jtalkを例にして解説する．
## 1. ビルド用のディレクトリを作る
```sh
mkdir tmp
cd tmp
```

## 2. 依存関係のビルド
hts_engine APIがOpen JTalkのビルドに必要なのでビルド．

インストールはしない．

```sh
wget http://downloads.sourceforge.net/hts-engine/hts_engine_API-1.10.tar.gz
tar -xzf hts_engine_API-1.10.tar.gz
cd hts_engine_API-1.10

./configure
make
```

## 3. 目的物のビルド
ポイントは依存のパス指定の時に`pwd`を使って絶対パスで指定すること．

`tmp/openjtalk`にインストール．

```sh
wget http://downloads.sourceforge.net/open-jtalk/open_jtalk-1.11.tar.gz
tar -xfz open_jtalk-1.11.tar.gz
cd open_jtalk-1.11

./configure \
    --with-hts-engine-header-path=`pwd`/../hts_engine_API-1.10/include \
    --with-hts-engine-library-path=`pwd`/../hts_engine_API-1.10/lib \
    --with-charset=UTF-8 \
    --prefix="`pwd`/../openjtalk"
make
make install
```

このように生成される．

```
tmp
└── openjtalk
   ├── bin
   │  └── open_jtalk
   └── dic
```

この`openjtalk`を固めれば，持ち運ぶことができる．

## 4. 使用例

テキストを音声ファイルに変換するのにはvoiceファイルが必要なのでダウンロードする．

```
wget http://downloads.sourceforge.net/project/mmdagent/MMDAgent_Example/MMDAgent_Example-1.8/MMDAgent_Example-1.8.zip
unzip MMDAgent_Example-1.8.zip
```

そして変換する．

```sh
echo "Open JTalkのソースコードはオープンソースで修正BSDライセンスとなっていますが、
ボイスファイルはクリエイティブコモンズ3.0非移植となっています。" \
> sample.txt
openjtalk/bin/open_jtalk \
    -m ./MMDAgent_Example-1.8/Voice/mei/mei_normal.htsvoice \
    -x openjtalk/dic/ \
    -ow sample.wav \
    sample.txt
```

## 参考
[**自分でソフトウェアをビルド・インストールするときに/usrや/usr/localへインストールしない**](https://qiita.com/kuchida1981/items/d028940ade41096490de)

[**Open JTalk (テキストを音声へ変換)をインストールし、使ってみる**](https://server-setting.info/centos/open-jtalk-install.html)
M1 Mac でも Google Cloud SDK を簡単にインストールできる


M1 Mac では、`zsh`が標準のターミナルなので`zsh`を指定します。

```shell
curl https://sdk.cloud.google.com | zsh
sudo nano ~/.zshrc
```

パスを追記します。

```
source '/Users/ユーザ名/google-cloud-sdk/path.zsh.inc'
source '/Users/ユーザ名/google-cloud-sdk/completion.zsh.inc'
```

設定を反映します。

```shell
source ~/.zshrc
```

バージョンが表示されるとインストール OK です。

```shell
gcloud -v

Google Cloud SDK 342.0.0
bq 2.0.68
core 2021.05.21
gsutil 4.62
```

初期設定

```shell
gcloud init
```
エラー：The following directories are not writable by your user:/usr/local/ が出たときの対処法

##はじめに
homebrewでインストールやアップデートをするときにエラー：「 The following directories are not writable by your user: /usr/local/ 」が出る時がある。

エラー文↓

```
Error: The following directories are not writable by your user:
/usr/local/

You should change the ownership of these directories to your user.
  sudo chown -R $(whoami) /usr/local/
```

##対処法
「オーナーシップを変更してみてね」と言われているので、エラーの中にある、

```
sudo chown -R $(whoami) /usr/local/
```

を入力して、パスワードを打ち込めばOK。
エラー：homebrew-core is a shallow clone. が出た時の対処方

##はじめに
homebrewでインストールやアップデートをするときに「 homebrew-core is a shallow clone. 」のエラーが出る時がある。

```
Error: 
  homebrew-core is a shallow clone.
To `brew update`, first run:
  git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
This restriction has been made on GitHub's request because updating shallow
clones is an extremely expensive operation due to the tree layout and traffic of
Homebrew/homebrew-core and Homebrew/homebrew-cask. We don't do this for you
automatically to avoid repeatedly performing an expensive unshallow operation in
CI systems (which should instead be fixed to not use shallow clones). Sorry for
the inconvenience!
```

##解決方法
エラーの意味をざっと要約すると、**下のコマンドを打ってね、不便かけてごめんね**とのこと。
なので、長いエラーメッセージの中にある

```
git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
```
このコマンドを打ってあげれば大抵解決する。
[git]特定ファイルのみgit stashする方法

# 方法

以下のようにパスは複数指定可能です

- ディレクトリパスを指定するとその配下のファイルがstashされます
- ファイルパスを指定するとそのファイルがstashされます


```sh 
git stash -- path1 path2 ...
```

## 感想

個人的に利用頻度高めなgitコマンド
覚えておくとかなり便利です
ABC203

#はじめに
こんばんは

昨日は疲れてしまったので今日記事を書くことにしました。最近，暑くなってきましたね。京都も気温が28℃まで上がり，春の終わり梅雨の訪れを感じています。

アルゴリズムの勉強もしたいのですが，今月中に基本情報技術者試験を受けないといけないんですよね。なので，そちらが終わり次第アルゴリズムの勉強は本腰を入れることができるかなあと。

今回はこんな感じでRating耐えてくれました。1週間ぶりにコードを書いたのでこれはヤバい結果になるかなと思っていましたが，意外と何とかなりました。やはりどんな時でも毎週継続してABCコンテストは参加した方が良いですね。このまま下がりさえしなければ，今月中に緑行けそうです！
![スクリーンショット (155).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465908/e8249d13-c1ef-541c-5bc5-33409513cff4.png)


以下ABC203のリンクです[https://atcoder.jp/contests/abc203]

#全体の感想
さらっと見た感じD問題が苦手な深さ優先探索か幅優先探索のどっちかかなあ、と思ったのでA,B,C問題をすぐに終わらすことにしました。
A,B,C自体は難しくなく20分かからなくらいで終えました。そこから，80分かけてD問題を考えましたが，分からず...
中央値を求める問題でしたが，まずどこを池にするかの箇所で計算を簡単にしないといけないのかなと考えたりしてました。

#各問題の感想
###A問題
疲れていたので，脳死でそのままコードを書きました。

```python
a,b,c=map(int,input().split())

if a==b :
    print(c)
elif a==c :
    print(b)
elif b==c :
    print(a)
else :
    print(0)
```
###B問題
n階でk室の部屋が各階に存在する。各部屋番号はi階j番目だとi0jとなる。
とのことでしたので，まずは各階の百の位を足して，一の位については各階k*(k+1)//2なのでこれを足していきました。
難しくなかったのでこれもすぐ解けました。

```python
n,k=map(int,input().split())
ans=0

for i in range(n) :
    ans+=(i+1)*100*k+k*(k+1)//2
print(ans)
```
###C問題
友達の数が2*10**5なので，ソートしてからfor文で回してもO(4*10**5)で計算は間に合うだろうと思いました。
後は，友達のいる村までにかかるお金を計算し，所持金から引いて負になれば，そこまでにたどり着ける村の最大の番号を計算する．友達の村につく場合は，そこでもらえる金額分所持金を増やしました．
普通のfor文と実装力が問われている問題でした。

```python
n,k=map(int,input().split())
cnt=[]

for i in range(n) :
    a,b=map(int,input().split()) #aは村番号,bはお金
    cnt.append([a,b])
cnt.sort()

flag=0
for i in range(n) :
    if flag+k<cnt[i][0] :
        print(flag+k)
        exit()
    k-=(cnt[i][0]-flag)
    k+=cnt[i][1]
    flag=cnt[i][0]
if k+flag>10**100 :
    print(10**100)
else :
    print(k+flag)
```
###D問題
解説を読んだら，どうやら二分探索と二次元累積和を用いるようですね。正直なことを言うと**「二次元累積和」**というワードは初めて聞きました。
この問題についてはもう少し詳しく勉強してから編集したいな...と思います。

```python
N,K=map(int,input().split())
A=[]
 
for i in range(N):
  temp=list(map(int,input().split()))
  A.append(temp)
  
 
#2分探索法
ok=10**9
ng=-1
 
lim = int(K*K/2)+1

def ruise2D(border):
  # 2次元累積和
  s=[[0]*(N+1) for i in range(N+1)]
  for i in range(N):
    for j in range(N):
      s[i+1][j+1] = s[i+1][j]+s[i][j+1]-s[i][j]
      if(A[i][j] > mid):
        s[i+1][j+1] += 1
  
  for i in range(0,N-K+1):
    for j  in range(0,N-K+1):
      #累積和から2分探索。よくわかってない。
      if((s[i+K][j+K] -s[i][j+K] -s[i+K][j]+s[i][j])<lim):
        return True
  return False
  
 
while((ng+1)<ok):
  mid =(ng+ok)//2
  if(ruise2D(mid)):
    #基準より小さい物があれば、探索範囲の上側をカット
    ok=mid
  else:
    #基準よりすべて大きければ、探索範囲の下をカット
    ng=mid
print(ok)
```

###E,F問題
読む時間も解く時間もなかったですね...
前期中に果たしてE問題を解けるようになるのだろうか...

#最後に
後でAtcoder Problemの方でD問題の難易度を確認したら青レベルでした．しかし、ここが解けるかどうかで緑以降の伸びが変わってくると思います．なので，今月下旬の基本情報基礎の試験が終わり次第，アルゴリズムの勉強頑張ります！！
今月中には頑張って緑いくぞお～
再起動時にdockerの連携が外れる時の対処

ローカルにいらないpostgresを入れてしまいkillしても先同時に戻ってきてしまう時の対処

Error response from daemon: Ports are not available: listen tcp 0.0.0.0:5432: bind: address already in use
というエラーメッセージの時

Sudo lsof -i :5432とコマンドを打つとPIDが分かります。

sudo pkill -u postgres

これでdockerとぶつかっていたpostgressが削除されるので

docker compose up -d
でdocker起動
ラズパイ4にcentos7のセットアップ

この記事は書きかけです。
6/15以降に加筆、修正します。

# キーボードレイアウトの変更
usからjisに

# パーテーション拡張
centosのインストールとパーテーション拡張
https://grapho.jp/raspberrypi4/centos7-install/

# sshアクセス

# proxy設定
必要に応じて
## yum
## wget
【第1章】RailsチュートリアルでHerokuデプロイ後「Method Not Allowed」が表示された時にやったこと

[Railsチュートリアルの第1章(第6版)](https://railstutorial.jp/chapters/beginning?version=6.0#code-hello_root_route)を手順通り進めていくと、『1.5.3 Herokuにデプロイする(2)』でブラウザに表示された結果が「hello, workd!」ではなく「Method Not Allowed」だった。

#やったこと①　正しいURLを押した。
最初は、～～.gitとなっているアドレスを選択していたが、調べてみると ～～.comとなっているのが他にあったので、そちらを押下した。

#やったこと②　チュートリアルの指示に従って、参考記事を読んだ。
それでも解消せず、チュートリアルを見直してみると『1.5.2 Herokuにデプロイする(1)』を実行した際にエラーが起こることがあると補足があった。
指示に従い以下の記事を参照した。
https://qiita.com/jnchito/items/c3035cc49a9cef053549

おすすめの解決方法を試みるも、すでにGemfileの

```
ruby '2.6.3'
```
となっている箇所は削除していた。
とりあえずコミットをし直してみると、なぜか"The Ruby version you are trying to install does not exist on this stack."のエラーは出なくなった。

#やったこと③ bundle installを実行し、表示されたメッセージの通りにした。
依然として「hello, workd!」は表示されないので、参照記事にある bunndle installコマンドを実行すると、Gemfileのlistenをアップデートするよう言われた(ような気がする)ので、'3.1.5'から'3.5.1'に書き換えた。
すると、次はspringをアップデートするよう言われた(ような気がする)ので、'2.1.0'から'2.1.1'に書き換えた。

その後、デプロイすると無事「hello, workd!」が表示された。


#まとめ
やったこと①②③の流れで解決できた。
【Git】git push -u origin masterしたら、error: failed to push some refs to 'https://github.com/ユーザー名/リポジトリ名.git'と怒られたときの対処法

<h2>症状</h2>
pushしたかったディレクトリではなく、一つ下位のディレクトリでpushまでしてしまいました。
再度、pushしたかったディレクトリで設定しなおして、pushしたところ下記のエラーが表示されてしまいました。

```terminal:ターミナル
git push -u origin master
git: 'credential-cache' is not a git command. See 'git --help'.
To https://github.com/ユーザー名/リポジトリ名.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/TKWebSE/near-eats.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

エラー文章を翻訳すると、
「エラー：一部の参照を「https://github.com/ユーザー名/リポジトリ名.git」にプッシュできませんでした」

ヒントを翻訳すると、
「ヒント：リモートにあなたが行った作業が含まれているため、更新は拒否されました」
「ヒント：ローカルにはありません。これは通常、別のリポジトリがプッシュすることによって発生します」
「ヒント：同じ参照に。最初にリモートの変更を統合することをお勧めします」
「ヒント：（例： 'git pull ...'）もう一度押す前に。」
「ヒント：詳細については、「gitpush--help」の「早送りに関する注意」を参照してください。」
と書いてありました。



<h2>解消方法</h2>
以下コマンドで、リモートリポジトリを削除し、新たい作成することができました。
とはいえ、このコマンドを使用する際にはいくつか注意点が必要です。
現在のプロジェクトのバックアップをしたのにち実装すると良いでしょう。

```terminal:ターミナル
git push -f origin master
```

<h2>参考</h2>
https://www.atlassian.com/ja/git/tutorials/syncing/git-push
GitHubにpushする時にerror: failed to push some refs と表示されてpushできない時
https://qiita.com/kazuki0714/items/ceda3a6721a9a99082de
Boost Asioで空きポートを開いてみた

今日[yumetodoちゃん](https://qiita.com/yumetodo)とSkypeしてたらおもむろにこんなこと言われました

boost asioで指定したポートが使えない時に自動的に別のポートを開く方法考えてくれ。ただし常に排他モードとする

いやいや、急に言われてもって思いましたね
まあ…私も今でこそhttplibでしか通信書いてないですけど、昔はboost asio使ってたので、手法自体が思い浮かばなかったわけではないんですね

```cpp
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), 0)
```

はい、endpointクラスのコンストラクターの第２引数を0にして、あとはacceptorに渡してやればいいだけなんです
とりあえず排他の話は置いといて、指定ポートが使えない時にっていうのがちょっとどうすっかなってなりましたね
だって引数でポート0渡した後にどのポートが空いてるのか知る術を私は知らなかったわけですから
そんなこんなで始まったググりTime
目的の情報はくっそあっさり見つかりました

まあ絶対誰かしらやろうと思うよね
StackOverflowで私がやりたいことドンピシャで質問されてましたｗｗｗｗｗ
[How do I correctly randomly assign a port to a test HTTP server using boost asio?](https://stackoverflow.com/questions/18183174/how-do-i-correctly-randomly-assign-a-port-to-a-test-http-server-using-boost-asio/19923459)

ほうほう…。鍵はここか…

```cpp
// (前略)
acceptor.bind(endPoint);

m_acceptor.listen();        

boost::asio::ip::tcp::endpoint le = acceptor.local_endpoint(); //THIS LINE SOLVES IT
port = le.port();
```

試しにやってみた結果、どのポートが使われてるのかコンソールでちゃんと確認することができました
さて、今回の課題は「指定したポートが使えない時に自動的に別のポートを開く」
つまり、一度は指定ポートでトライしないといけないんです。
じゃあどうやってトライするのって話ですね。
答えはシンプル

```cpp
boost::asio::ip::tcp::acceptor acceptor(ios, tcp::endpoint(tcp::v4(), default_port));
```

もし空いてなければこいつが例外投げるので、そいつをcatchしてやるだけです。
つまりこういうことですね

```cpp
inline boost::asio::ip::tcp::acceptor create_acceptor(boost::asio::io_service& ios, const unsigned short& default_port) {
	try {
		return boost::asio::ip::tcp::acceptor(ios, tcp::endpoint(tcp::v4(), default_port), reuse_address);
	}
	catch (std::exception) {
		return boost::asio::ip::tcp::acceptor(ios, tcp::endpoint(tcp::v4(), 0), reuse_address);
	}
}
```
try-catch書かずに行けたらもっと良かったけど、まあしゃあないな
そして、排他モードという課題も込みで書き上げたコードがこれです

```cpp
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <stdexcept>
namespace asio = boost::asio;
using asio::ip::tcp;

void on_accept(const boost::system::error_code& error) {
	if (error) {
		std::cout << "accept failed: " << error.message() << std::endl;
	}
	else {
		std::cout << "accept correct!" << std::endl;
	}
}

inline tcp::acceptor create_acceptor(asio::io_service& ios, const unsigned short& default_port, const bool reuse_address = true) {
	try {
		return tcp::acceptor(ios, tcp::endpoint(tcp::v4(), default_port), reuse_address);
	}
	catch (std::exception) {
		return tcp::acceptor(ios, tcp::endpoint(tcp::v4(), 0), reuse_address);
	}
}

int main() {
	try {
		asio::io_service ios{};
		tcp::acceptor acceptor = create_acceptor(ios, 3306, false);
		acceptor.listen();
		tcp::endpoint e = acceptor.local_endpoint();
		std::cout << e.port() << std::endl; // ここでポートを表示する
		tcp::socket socket(ios);
		acceptor.async_accept(socket, boost::bind(&on_accept, asio::placeholders::error));
		ios.run();
	}
	catch (const std::exception& er) {
		std::cout << er.what() << std::endl;
	}
	return 0;
}
```

以上！
スネークケースで書いたのもう６年ぶりじゃないかな…
Java始めて以来、全部キャメルケースで書いてるからなぁ…
え？lambda使え？文句はyumetodoちゃんへどうぞ。言ってない話がもう１個隠れてるから
Kotlin勉強記録

▼乱数
乱数とは、ランダムな数値のこと。
kotlinでの書き方
![スクリーンショット 2021-05-24 4.32.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1187927/ce2d44aa-fe70-8732-d6f5-64d7ab7cc69c.png)
変数に乱数を使ってランダムな数値にすることもできる

var r = (10..100).random()

▼ループ処理
繰り返す処理で回数なども入れられる
![スクリーンショット 2021-05-24 4.52.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1187927/6535c711-2290-9e47-1da8-57ecb637f4ee.png)

「break」をいれることで、ループ処理を抜けられえる(終わらす）

▼配列
変数を連番で管理すること。
![スクリーンショット 2021-05-31 22.23.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1187927/14397c44-f212-d001-d11e-25ec61ced75f.png)

乱数と組み合わせると何が出るかわからないという変化を出せる
基本の型に例として
var i = (0..3).random()
println(a[i])
を作ることで、ランダムに表示させることができる

ループ処理（for）と相性がいい
画像のみかん、りんご、いちごをすべて順に表示させるには、
for(s in a){
    println(s)
}
にすることでできる。

aは変数、sはaのものを受け取って表示させている

▼関数
処理をまとめて利用しやすくする
関数は１つ作っておくと何度でも呼び出すことができる
そのため、よく使うものは関数にして作っておくと便利

▼引数
関数に変化をつける
![スクリーンショット 2021-05-31 23.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1187927/998c3411-e947-0b59-014f-28ab134c0f80.png)

画像のように作った関数「attack()」に変数で作成した部分を入れる（varを抜いた全部）
入れた上で、mainの中のattackの（）内を変更すると順に変更することができ、１つだけじゃなくちょっとした変化を出せる

:point_up:このとき（）内に入れる変数はちゃんと型を入れないと反応しないかも。
入れずにやったらエラーになったので、多分そう。

▼戻り値
関数からの値を取得できる
returnの後ろの数値を返すことができる
![スクリーンショット 2021-05-31 23.26.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1187927/27714b3c-7c0b-2083-c33d-3daaffbddc69.png)

戻り値は、指定している型が重要
Intであれば、整数のみ。
Stringであれば文字のみ。などと区別をつける必要がある。

戻り値を使うメリットは、ゲームなどで合計ダメージを表示させたいみたいな場面で使う

例
まず受けるダメージをランダムで表示させる関数を作成する
合計ダメージを最後に出したいから「return r」と書いておく
![スクリーンショット 2021-05-31 23.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1187927/37d07dc2-907e-148c-6f34-18d2d94bb202.png)

次に、ダメージを合計させるための式を書き、受けたダメージを合計させ表示させる
![スクリーンショット 2021-05-31 23.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1187927/fa6d0ea5-1b7e-560b-7d8b-c4add24640c9.png)
C#で自身のクラス名や関数名を取得する

##実際のクラス名・メソッド名を使用して取得する場合

```
nameof(クラス名);

```


##クラス名・メソッド名を使用せずに取得する場合

```
GetType().Namespace;　// ネームスペース取得

GetType().Name;　// クラス名取得

System.Reflection.MethodBase.GetCurrentMethod().Name;　// メソッド名取得
```
Serum dưỡng ẩm thần thánh, không thể bỏ qua  

[52bff6dd8db14099cc5fe7f083d92399.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1554589/26b2c7ef-05a5-2118-c1a9-d0189cd32408.jpeg)
http://5bcosmetics.com/2021/05/30/serum-suong-am-lam-diu-da-centella-hyalu-cica-khong-the-bo-qua/
HomebrewをLinuxサーバーにinstallする - git,curlのエラー

# 概要
sudoが使えない環境でLinuxサーバーにHomebrewをinstallする。Gitとcurlがアップデートできない問題を解決！

# 環境
CentOS 7
Linux


# レベル
導入レベル



# 解説

### 問題

Homebrewをinstallしようとしても、cURLとGitが古いと言われる。

```
Error: Please update your system curl.
Minimum required version: 7.41.0
Your curl version: 7.29.0
Your curl executable: /usr/bin/curl

Error: Please update your system Git.
Minimum required version: 2.7.0
Your Git version: 1.8.3.1
Your Git executable: /usr/bin/git
```
これは、Linuxシステムに元々入っていた古いversionのcURLとGitを読み込んでいるからである。

そのため、先にcURLとGitの最新版をインストールする必要がある。

以降の手順は参考を確認。


## 参考
https://astropengu.in/posts/33/
PWAでインストール可能にするための最小構成

## はじめに

多分これが一番小さいと思います

[実際のコード](https://github.com/k42un0k0-sandbox/pwa-sandbox/tree/%E6%9C%80%E5%B0%8F%E6%A7%8B%E6%88%90)

とりあえずPWAをインストールするための最小構成なので、個々の細かい仕様には触れません

## 検証環境

- OS: Windows
- ブラウザ: Chrome

## PWAをインストール可能にするために必要なこと

[MDNのサイト](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Installable_PWAs)に書いてあるものの意訳をします

1, 正しい記述のウェブマニフェスト
2. セキュアドメイン(https)
3. デバイス上のアプリを表すアイコン
4. アプリをオフラインで動かすためのサービスワーカー

上記を満たせばインストール可能になります

## 必要なファイル

必要なファイルは以下の通りです

以下を用意すれば要件の 1, 3, 4 を満たすことができます

- index.html
- sw.js
- manifest.json
- icon.png


```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <!-- マニフェストファイルを読み込むためのlinkタグ -->
  <link rel="manifest" href="manifest.json">
  <title>最小構成 PWA</title>
</head>
<body>
  <h1>最小構成 PWA</h1>
  <!-- サービスワーカーを登録するためのscriptタグ -->
  <script>
      navigator.serviceWorker.register("./sw.js");
  </script>
</body>
</html>
```

```sw.js
// fetchイベントのリスナーだけあれば「オフラインで動かすためのサービスワーカー」の要件を満たすようです
self.addEventListener("fetch", (e) => {});
```

```manifest.json
{
  "name": "最小構成 PWA",
  "short_name": "minimum installable pwa",
  "description": "インストール可能なPWAの最小構成",
  "icons": [
    {
      "src": "icon.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "/index.html",
  "display": "fullscreen",
  "theme_color": "#B12A34",
  "background_color": "#B12A34"
}

```

アイコンはサイズが512x512のものを用意して下さい

## localhostでのhttps対応

最後に要件の 2 に対応します

awsなどを使う場合は適当にボタンポチポチして下さい

今回はhttpsをlocalhostで使う方法をまとめます

以下のツールを使います

- [serve](https://www.npmjs.com/package/serve)
- [mkcert](https://github.com/FiloSottile/mkcert)

### 証明書の作成

まずはSSL証明書を作成します

mkcertはローカルに認証局をインストールして、コマンドで証明書を発行するためのツールです

[README](https://github.com/FiloSottile/mkcert#installation)を読んで自身の環境にあった方法でインストールしてください

インストール出来たら下記のように認証局のインストールと証明書の作成をします

```sh
$ mkcert -install
Created a new local CA 💥
The local CA is now installed in the system trust store! ⚡️
The local CA is now installed in the Firefox trust store (requires browser restart)! 🦊

$ mkcert localhost

Created a new certificate valid for the following names 📜
 - "localhost"

The certificate is at "./localhost.pem" and the key at "./localhost-key.pem"
```

### httpsでwebサーバーを起動

次にserveを使ってwebサーバーを起動します

まずはserveをインストールします

```
$ yarn init
$ yarn add serve
```


[#必要なファイル](#必要なファイル)で作ったファイルと先ほど生成した証明書をすべて同じディレクトリに置いたうえで以下を実行してください

```sh
yarn serve --ssl-cert ./localhost.pem --ssl-key ./localhost-key.pem
```

これで`https://localhost:5000`にアクセスすればインストール可能になってるはずです

## 終わり

なぜfetchイベントのリスナーだけで「オフラインで動かすためのサービスワーカー」の要件を満たすのかとか、アイコンのサイズは512以外なら何が使えるのかとか、調べきれてないところはありますがとりあえずPWAをインストールできました
Serverless frameworkでAWS Lambda構築から配布まで

# はじめに

プロジェクトでAWS Lambdaを使用することになりましたが、簡単に配布できる方法を探して共有したいと思います。

Serverless FrameworkでAWS Lambdaを簡単に配布する方法を開始します。

# Serverless Framework

サーバレスを構成することになれば、それぞれの関数を作成するのはもちろん、それに合った環境設定を毎回変えることも仕事です。

この時、Serverless Frameworkを使用すれば、簡単に配布することができます。

https://www.serverless.com

> Serverless Frameworkは、AWS、Google Cloud Platform、Microsoft Azureなどのクラウドサービスで、手軽にアプリケーションを作成·配布できるツールです。

# 手順概要
1. serverless のインストール
2. IAMユーザの作成
3. serverlessテンプレートを活用してアプリケーションを作成
4. 配布前にテスト
5. serverless.yml設定
6. 配布

## 1) serverlessのインストール

```jsx
npm install -g serverless
```

## 2) IAMユーザの作成

serverlessを通じてコードを配布するためにAWSの権限を持っていなければならない。

AWS IAMにアクセスし、ユーザ追加をクリックします。

![IAM사용자추가 일어.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1374635/47ee204f-8389-e22d-ff56-109b98ce5a8d.png)

- ユーザー名を入力します。
- ServerlessがAWSにアクセスするために"プログラムによるアクセス"を選択します。

![IAM사용자 전체 권한 추가 일어.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1374635/a8f8640a-cd66-b6f9-3f50-02417dccb07d.png)

- スピーディな進行のため、"AdministratorAccess" を選択します。
- 実際のサービスには、すべてのアクセス権限を持つポリシーの使用は推奨されません。

IAMユーザーが追加されました。

- アクセスキーID、シークレットアクセスキーをコピーするか.csvファイルをダウンロードします。
- AWS にアクセスできるキーですので、管理を心がけましょう。

### Serverless Frameworkの権限設定

```jsx
serverless config credentials --provider aws --key {アクセスキーID} --secret {シークレットアクセスキー}
```

## 3) serverlessテンプレートを活用してアプリケーションを作成

- Serverlessでサポートしているテンプレートを確認

```jsx
sls create -t
```

- 希望するテンプレートでserverlessプロジェクト作成

```jsx
serverless create -t {テンプレート} -p {プロジェクト名}
```

```jsx
$ serverless create -t aws-nodejs -p test
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "C:\Users\mhkim\node.js\test"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v2.28.7
 -------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs"
```

### 作成されたディレクトリー確認

- .gitignore
    - Gitバージョン管理から除外するファイルリストを指定するファイル
- handler.js
    - Lambda実行関数ファイル
- serverless.yml
    - Lambda関数およびAPi GatewayなどServerlessFrameworkの設定ファイル

## 4) 配布前にテスト

```jsx
serverless invoke local --function hello
```

## 5) serverless.yml 設定

```jsx
provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: ap-northeast-1
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
```

- 地域を東京（`ap-northeast-1`）に設定し、`dev`ステージに配布
- `hello`という関数はhandler.helloとつながっており、`http`の`GET`を通じて実行可能

つまり、私たちがAWS Consoleで一つ一つ設定していたものをたった数行に設定することができます。

詳しい説明はReferenceでご確認ください。
https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml

## 6) 配布

```jsx
serverless deploy
```

- 配布に要する時間は、関数に使用したパッケージ容量によって異なります。
- 配布が終了すると、AWS Lambda コンソールにアクセスすると、関数が生成されたことを確認することができます。

# 結論
次はAWS LambdaでS3にファイルアップロード方法を出力します。
フィードバックはコメントでお願いします！
Re:新人視点から感じる炎上PJの火消し

初投稿になります:spy_tone3:

軽い自己紹介として20年卒のクソガキSEであることでしょうか…
何卒よろしくお願いします。

Qiitaを始めようと思ったきっかけは、以下になります。
・普段の業務でコーディングや知識関連で行き詰った際にQiitaを使うことが多い
・自分のアウトプットの場としても、使っていきたい

業務では主にjava（最近は専らspringの虜）、学生時代はpython（機械学習etc）を主に学習していました。
※コーディングに関する小ネタ？なんかも書いていく予定です。
# 現状について
~~詳細は置いといて約3，4か月の遅延（仕様変更モリモリ）~~
◇PJ作業はウォーターフォール型:anchor:（と思いたい）

◇月によるがメンバーは15人ほど（平均残業：40~50h?/人）

◇新規参画者の引継ぎや環境設定に時間がかかりがち…


## 日々感じる問題点
### [問題1]<font color="Red">言った言わない問題</font>
これはどこのPJでもあるのかなと…
対策として、自分やPJメンバが行っていることを以下にまとめてみました。
### [対策1]<font color="Blue">ドキュメントを残す</font>
利点としては後任者が確認できるのが第一にあるかなと思います。
よく私も感じるのですが、自身で確認できるのも強みですね。
これに関しては面倒な要素が先行しがちですが、間違いなく後ほどの手助けになると日々感じます…

### [問題2]<font color="Red">共通処理の重要さ</font>
少し具体的な例になってしまいます。
私はプログラミング経験が比較的浅いほうですが、今のPJに配属されてから共通処理に魅力と重要性を感じています。
### [対策2]<font color="Blue">周知の徹底</font>
設計時点で提案されている共通処理を用いるのももちろんですが、開発の段階で
:information_desk_person:これ共通で使えるのでは？
となったときには積極的に上司や技術強めな方に相談するようにしています。
今のPJではjunitに触れていることもあり、共通処理を導入することでテスト工程の省略にもつながることを知りました。
junitを知るにあたってPJの方から紹介された記事のリンクです↓
[Spring Bootでテストコードを書いてみる](https://qiita.com/a-pompom/items/3f834119c756e5286730)

### [問題3]<font color="Red">進捗の把握</font>
私はまだPMのような立場ではないので、これについて触れるのはどうかと思いますが…
結論、_進捗の悪さは炎上PJの共通点_であるといえます。
上司から話を聞く限りこんな要因が背景にあると考えます。

①<font color="Green">単純にクライアントの要求が辛い</font>

②<font color="Green">作業の進め方に問題がある</font>

③<font color="Green">コミュニケーション、情報の共有不足</font>
### [対策3]<font color="Blue">それぞれへのアプローチ</font>
私なりにそれぞれへの意見を書いてみます。
①<font color="Green">単純にクライアントの要求が辛い</font>
∟これに関しては進捗に対して_やばい_のyの時点で:robot:~~PJの上位層やクライアントとの相談の場を設けることが最重要？(ry~~

②<font color="Green">作業の進め方に問題がある</font>
∟これにはいろいろと思い当たる節があるのですが、自身の体験の中で最重要だと考える2点をまとめてみます。

・作業の順番を考える
 ∟自タスクが遅延手前になるようなときに後悔しがちなこととして
:imp:あーこれ先にやれば共通にできた～～と感じることが多いです。
設計書の読み込みが甘いが故に起きることや開発対象の全貌を把握しきれずに着手してしまうときにありがちです。
（今後に活かします…）

・有識者に相談する
まだまだ未熟な身なので賢い実装~~（語彙力）~~ができないことが多々あります。
レビューやテスト工程を通して気づくことも多いですが、自身の中で実装方法に択が生まれた時点で聞くようにしています。

③<font color="Green">コミュニケーション、情報の共有不足</font>
∟これは難しいですよね…
実際に現場に配属される前から<font color="MediumVioletRed">口を辛くしてコミュニケーション！！！大事！！！</font>と諭されていました…
私自身、人当たりには自信がありますが、仕事を始めて友達と話すのとは違って話すのって難しい！
と感じる毎日が続いています。

状況をうまく伝えること＆自分が何を知りたいのか簡単なようで難しい:scream_cat:
~~正直なんで伝わらないんだと思うことなんて日常茶飯事…~~
👆これに関しては壁にぶつかったときは一歩離れた視点から問題を考えることで改善されてきたと思います…

また、情報の共有不足はPJの進捗に大きく影響を与えていると確信しています。
***
　こんな事例をよく目にするからです:thinking:
　∟　AさんはBさんに気軽に質問できるけど
　　　<font color="MediumVioletRed">AさんからCさんにはBさんを介さないと…</font>
***
これって人間が仕事をするうえで大きな課題ですよね。
ポン！と即解決するのは難しいですが、残業にもまれたある日、帰りの電車でこんな記事を目にしました。
[アンジャッシュとエンジニア～コミュニケーションの桃源郷を目指して～](https://qiita.com/mymt/items/8cb6c974ab2af553931b)

小中学生のころ、よく目にしていた記憶があるアンジャッシュが取りあげられています。
彼らのようなやり取りが仕事で起こるのはまずいなと感じ、
上記のような例でいうところのAさんとCさんを巻き込んで、自身の問題について尋ねてみるなど私なりの工夫を凝らしています。

# まとめ
・共通処理を提案できる人材は全王様であり全ちゃん:man_with_turban_tone3:
・問題①～③に共通して少しでも悩んだら発言してみる
・PJ全体で目指すゴールは1つであり、コミュニケーションにも体力を割く
人と話すって大事:clap:
CakePHP4でTwigテンプレートエンジンを使う方法

CakePHP4は標準ではテンプレートエンジンが使えないため、Viewでは生PHPで出力処理を書きます。
CookBook（公式ドキュメント）でもテンプレートエンジンについての記載はなく、一見使用できないように思えますが、実はCakePHP4には元々`cakephp/twig-view`というパッケージが含まれており、設定変更すればTwigをテンプレートエンジンとして使用できます。
https://github.com/cakephp/twig-view

Twigを使うための手順は以下のとおりです。

## 1. AppView.phpを変更
・AppViewの継承元クラスをTwigViewに変更
・use Cake\TwigView\View\TwigViewに変更
・initialize()メソッド内で親クラスのinitialize()を呼び出し

```diff_php:src/View/AppView.php
<?php
declare(strict_types=1);

namespace App\View;

- use Cake\View\View;
+ use Cake\TwigView\View\TwigView;

- class AppView extends View
+ class AppView extends TwigView
{
    public function initialize(): void
    {
+       parent::initialize();
        // オプション設定する場合はここに記述
    }
}
```
※コメント部分は省略しています。

## 2. テンプレートの拡張子を変更
各テンプレートファイル（templates/）の拡張子を`.php`から`.twig`に変更します。

例：`default.php` => `default.twig`

## 3. テンプレートの内容をTwigでの記述に変更
テンプレートの内容を全てTwig記法で書き換えます。
以下、動作確認を兼ねた簡単な記述例です。

```twig:layout/default.twig
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ title }}</title>
</head>
<body>
    {{ fetch('content') }}
</body>
</html>
```

```twig:Posts/index.twig
<h2>{{ title }}</h2>

{% for post in posts %}
    {% if post.isPublished %}
        <h4>{{ post.title }}</h4>
        <p>{{ post.body }}</p>
        <hr>
    {% endif %}
{% endfor %}
```

```php:PostsController.php
<?php
declare(strict_types=1);

namespace App\Controller;

class PostsController extends AppController
{
    public function index()
    {
        $title = 'Twig表示テスト';
        $posts = [
            [
                'title' => '記事タイトル 1',
                'body' => '本文テキスト 1',
                'isPublished' => true,
            ],
            [
                'title' => '記事タイトル 2',
                'body' => '本文テキスト 2',
                'isPublished' => false,
            ],
            [
                'title' => '記事タイトル 3',
                'body' => '本文テキスト 3',
                'isPublished' => true,
            ],
        ];
        $this->set(compact('title', 'posts'));
    }
}
```

上記コードの場合、以下スクリーンショットのような表示になります。
正常に表示されていれば、Twigでの描画に切り替わっています。
![2021-05-29-Twig表示テスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345139/82baf147-3051-4cc5-7243-363c2a7f64fc.png)

## 参考情報
cakephp/twig-viewの設定方法・オプション機能などの詳細については、以下URLのReadmeに記載されています。
https://github.com/cakephp/twig-view

Twigテンプレートエンジンの公式ドキュメントです。
https://twig.symfony.com/doc/3.x/
Google Cloud Translation - Document Translation APIを試してみた

## 概要
Googleが2021年5月12日、機械学習を用いて翻訳を行う「[Translation API](https://cloud.google.com/translate/docs/intro-to-v3#document)」の新機能として、PDF、Word、Excel、PowerPointのファイルを読み込み、レイアウトなどを保ちつつ内容だけを別の言語へ翻訳して出力する「Document Translation」を発表しました。
https://www.publickey1.jp/blog/21/pdfwordexcelgoogle_translation_api.html

早速触ってみましたので使い方などをご紹介したいと思います。
特に認証周りが複雑でドキュメントも少なかったのでそのあたりを解説したいと思います。

## GCPでAPIを有効化
[公式サイト](https://cloud.google.com/translate/docs/basic/setup-basic?hl=ja)を参考にAPIを有効化し、サービス アカウントを作成、JSON として秘密鍵をダウンロードします。

## 認証情報の取得
秘密鍵の情報をもとにHTTPリクエストヘッダーに付加する認証トークンを取得します。
Google Cloud SDKが利用できる環境の場合、[インストール後](https://cloud.google.com/translate/docs/basic/setup-basic?hl=ja)に

```powershell
gcloud auth application-default print-access-token
```
で取得することができます。

ただし、この方法で取得したトークンは一定時間経過後に失効してしまうのでそのたびに取得する必要があります。
サービスとしてプログラムから呼び出す場合は秘密鍵をサーバーなどに配置しておき、Google Cloudの各言語ライブラリから読み取って認証する方法が無難です。

一例としてPythonでJWTに署名してトークンを取得する方法もあるのでプログラムを記載しておきます。
※各パラメータは秘密鍵のJSONから転記

```python
import jwt
import time
import os

iat = time.time()
exp = iat + 3600
key = 'private_key'
payload = {'iss': 'client_email',
           'sub': 'client_email',
           'aud': 'https://translation.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': 'private_key_id'}
signed_jwt = jwt.encode(payload, key, headers=additional_headers, algorithm='RS256')

print(signed_jwt)
```

## API実行
HTTPメソッドとURL

```
POST https://translation.googleapis.com/v3beta1/projects/PROJECT_NUMBER_OR_ID/locations/LOCATION:translateDocument

ヘッダー
Authorization: Bearer <認証トークン>
```

JSON本文

```
{
  "source_language_code": "SOURCE_LANGUAGE",
  "target_language_code": "TARGET_LANGUAGE",
  "document_input_config": {
    "mimeType": "MIME_TYPE",
    "content": "INPUT_BYTE_STREAM"
  }
}
```

- PROJECT_NUMBER_OR_ID: Google Cloud プロジェクト番号または ID。
- LOCATION: このオペレーションを実行するリージョン。例: us-central1
- SOURCE_LANGUAGE: （省略可）入力ドキュメントの言語コード。言語コードがわかっている場合は、[言語サポート](https://cloud.google.com/translate/docs/languages)に記載されている言語コードのいずれかを設定します。
- TARGET_LANGUAGE: 入力ドキュメントの翻訳先のターゲット言語。[言語サポート](https://cloud.google.com/translate/docs/languages)に記載されているいずれかの言語コードを設定します。
- MIME_TYPE: ソース ドキュメントの形式（application/pdf など）。
- INPUT_BYTE_STREAM: バイト ストリームで表現した入力ドキュメントのコンテンツ。

入力ドキュメントをBase64エンコードした形式で直接指定していますが、Google Cloud　Storageのパスを使用することも可能です（アウトプットも同様）
詳細は[公式ドキュメント](https://cloud.google.com/translate/docs/advanced/translate-documents)を参照してください。

## おわりに
GoogleのAPIサービスは認証周りが複雑でサクッと試すのにハードルがありますが、一回わかってしまえば他のAPIサービスにも応用できるのでまずは根気強く認証周りを勉強していくと知識の幅が広がるのではないでしょうか？

ドキュメント翻訳の機能自体はDeepLやAzureなどもリリースしていますが、今後はそちらも触ってみて比較などができればと考えています。
Pennylane-braket でqueueに積まれたAWSタスクを読み込む方法

# Pennylane-braket

Pennylane-braket は、Pennylane SDK からAmazon braket 上のマシンを呼び出せるプラグインです。
Amazon braket 上には量子コンピュータ実機もありますが、実機の場合は結果がすぐ帰ってこず順番待ちとなります。
この場合、タスクはQueueに積まれた状態となり、後で回収が必要です。
braket単体の場合はチュートリアルに回収の仕方が書いてありますが、Pennylaneから操作した場合にどうしたら良いのかは書いていません。
ずっと、できないと思っていました。

結論から言えばとても簡単なのですが、つまずいたので書いておきます。

# code

braket単体の場合のチュートリアルを9割コピペして、以下の関数を作っておきます。
タスクidを与えて、タスクを取ってきて、ヒストグラムプロットします。

```python

def Retrieve_task(task_id):
    from braket.aws import AwsQuantumTask
    # recover task
    task_load = AwsQuantumTask(arn=task_id)

    # print status
    status = task_load.state()
    print('Status of (reconstructed) task:', status)
    print('\n')
    # wait for job to complete
    # terminal_states = ['COMPLETED', 'FAILED', 'CANCELLED']
    if status == 'COMPLETED':
        # get results
        results = task_load.result()
        # print(rigetti_results)

        # get all metadata of submitted task
        metadata = task_load.metadata()
        # example for metadata
        shots = metadata['shots']
        machine = metadata['deviceArn']
        # print example metadata
        print("{} shots taken on machine {}.\n".format(shots, machine))

        # get measurement counts
        counts = results.measurement_counts
        print('Measurement counts:', counts)

        # plot results: see effects of noise
        plt.bar(counts.keys(), counts.values());
        plt.xlabel('bitstrings');
        plt.ylabel('counts');
        plt.tight_layout();
        plt.xticks(rotation=90);

    elif status in ['FAILED', 'CANCELLED']:
        # print terminal message 
        print('Your task is in terminal status, but has not completed.')

    else:
        # print current status
        print('Sorry, your task is still being processed and has not been finalized yet.')

```

出力イメージは以下の通り。

`Status of (reconstructed) task: COMPLETED
1024 shots taken on machine arn:aws:braket:::device/qpu/ionq/ionQdevice.
Measurement counts: Counter({'0101': 317, '1010': 201, '0110': 91, '1100': 83, '0011': 62, '1001': 54, '0100': 38, '1000': 26, '1110': 24, '0000': 23, '0010': 20, '0001': 20, '1011': 20, '1101': 16, '1111': 16, '0111': 13})`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878664/bf654642-21c2-95d0-dce1-ab8a25413051.png)

次に、Pennylane経由でタスクを投げるときの注意点です。
Pennylaneはタスクがすぐ返ってくることを期待しますので、Queueに積まれると止まってしまいます。
これを避けるために、タイムアウトを設定する必要があります。(まぁ、無理やり抜けても良いんですが）
また、タスクのidを控えておく必要があります。
そのためには、以下のようにします。

まず、タイムアウト設定です。
以下では3秒としています。

```python
dev_remote_ionq = qml.device(
    "braket.aws.qubit",
    device_arn=device_arn_ionq,
    wires=n_qubits,
    s3_destination_folder=s3_folder,
    shots = 1024,
    poll_timeout_seconds = 3
)
```

次に、タスクidですが、
タスク（回路）を投げてタイムアウトした**後に**

```python
ionq_task_id = dev_remote_ionq.task.id
```

とします。実はdevにはtask属性というものが存在していて、
そのidやstateを呼ぶことができます。ioqやrigettiを使った場合、
ちゃんとこの id はaws上のタスクのidになります。（最も新しいもののidが取られます）
ibmqの場合は確認していないのですが、おそらくibmq上のタスクのidになると思います。
ただしibmqはretrieveのコマンドが違うので、上記関数 Retrieve_task では動きません。
qiskitにtaskを取ってくる関数があるので、それを使ってしまえばいいと思います。

# 結論

細かいところは自分で埋めるしかなし。。
RxSwiftのDisposeBagは何をしてくれているのか

# はじめに
RxSwiftを利用したコード内で以下の定義がされていることがよくある。

```swift
/// RXのゴミ箱
let disposeBag = DisposeBag()

/*
* 省略
*/

func bind() {
   hogehoge.subscribe(onNext: { [weak self] value in
     // 何らかの処理
   }).disposed(by: disposeBag)
}
```

このコードはおまじないのように書かれており、コメントには`Rxのゴミ箱`と記述されていたりすることがあってRx初心者にとっては意味がわからなかった。

そしてsubscribeしているところでメソッドチェーンで`.disposed(by: disposeBag)`という定義がされており、ゴミ箱に捨てられてるな？？みたいな感じになってフワフワしたままだったので、今一度見直すことにした。

# DisposeBag
## 役割
適当なObservableを`subscribe`したとき、戻り値は`Disposableオブジェクト`なので、`dispose()`を呼び出せば講読解除できる。

講読解除をしないとメモリリークの原因となるので、解除はしておきたい。
しかし`dispose()`は自分の好きなタイミングで呼ぶことができるので、一つのクラスで大量のObservableを監視していた場合、都度disposeしてあげなければいけないし、ヒューマンエラー等で抜け漏れる可能性がある。

そこで使用するのが`DisposeBag`である。
[公式のコード](https://github.com/ReactiveX/RxSwift/blob/main/RxSwift/Disposables/DisposeBag.swift)上のコメントには下記のように記されている。

```
Thread safe bag that disposes added disposables on `deinit`.
```

要するに、`deinit`時に自動的にDisposeBagに格納されているDisposableオブジェクトを解放してくれるようだ。
## 書き方
```swift
let disposeBag = DisposeBag() //(1)

//(2-1)
hogehoge.subscribe(onNext: { [weak self] value in
    // 何らかの処理
}).disposed(by: disposeBag)

// or

//(2-2)
let disposable = hogehoge.subscribe(onNext: { [weak self] value in
    // 何らかの処理
})

/*
* 任意の場所↓↓↓
*/
disposable.disposed(by: disposeBag) 
```

(1)で定義をする。DisposeBagはDisposableオブジェクトを格納してくれるので一つだけ定義すれば良い。
これがゴミ箱の定義。

(2-1),(2-2)はやっていることは変わらない。
メソッドチェーンを使って`disposed(by: disposeBag)`を繋げて記述しても良いし、一度プロパティとしてから別途任意な場所で記述するのもOK。

個人的には、コードが散らばらずsubscribeしている箇所を見ればまとまっており、どこで`disposed`しているかを探す必要がなくなるメソッドチェーンを使った(2-1)が推し。

## 講読解除(dispose)されるタイミング

- 講読対象（Observable）を監視しているとき、`onCompleted`もしくは`onError`が発生してイベントが終了したら
- （DisposeBagに監視対象を渡している前提で、） その監視をしているクラスが解放されたら

後者のクラスが解放される時というのは以下のような流れのイメージである。

1. 画面AからBに遷移する（**Bのインスタンスが作成される**）
1. Bで何かしらの値を監視する（**Bのファイル内でsubscribeが行われる**）
1. 画面Bを閉じる（**ARCにより参照カウントが0になることでBのインスタンスが解放される**）

3のタイミングのBのインスタンス解放時にDisposaBagに格納されているオブジェクトが解放される。

# 終わりに
普段何気なく使っていたDisposeBagですが、監視しているオブジェクトをまとめて解放してくれてメモリリークの原因となることを回避してくれているということがわかりました。

もし、ここが違うよとかがあればご教授頂ければ幸いです。

# 参照
1. [RxSwift/DisposeBag.swift at main · ReactiveX/RxSwift · GitHub ](https://github.com/ReactiveX/RxSwift/blob/main/RxSwift/Disposables/DisposeBag.swift)
1. [dispose()とdisposed(by: DisposeBag)を使いこなす - 野生のプログラマZ](http://harumi.sakura.ne.jp/wordpress/2019/02/05/dispose%E3%81%A8disposedby-disposebag%E3%82%92%E4%BD%BF%E3%81%84%E3%81%93%E3%81%AA%E3%81%99/)
1. [RxSwiftの動作を深く理解する - Qiita](https://qiita.com/k5n/items/643cc07e3973dd1fded4)
AWS Backupを使ってCMKで暗号化したバックアップをクロスリージョンで作成してみた

# はじめに
### この記事は
AWS Backupを使って、**KMSのCMKで暗号化した**状態で、**クロスリージョン**にEC2のAMIを保存する方法を紹介します。

### やりたいこと： EC2のバックアップ(AMI)をクロスリージョンで取得する。その際CMKで暗号化する。
大阪リージョンができて、バックアップを大阪に保持したいという要件が増えてきそうです。
単純にバックアップを取るだけであれば、公式ドキュメントを読めばかんたんに作成可能です。
しかし暗号化して、更に任意のCMKを指定するとなると、公式ドキュメントの記載がいまいち分かりづらかったため、検証して確認してみました。
ポイントは単にバックアップを取るのではなく、

* クロスリージョンにコピー
* CMKで暗号化する

点です。

### 結果：　出力先ボールトにCMKを指定することで、CMKで暗号化される
検証の結果、**出力先のボールト**にCMKを設定すれば、そのCMKで暗号化されました。
KMSのキーが指定されていない場合、デフォルトのキーとしてAWS管理のサービスごとのキーを利用して暗号化します。

# 検証
### 準備
![AWS Backup 検証-準備.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43015/69d859ce-8eca-b027-1c14-f3303116f2f5.png)

* 東京リージョンと大阪リージョンにそれぞれCMKを作成
* 東京リージョンに暗号化インスタンスAと、暗号化なしインスタンスBの2つを用意
* 大阪リージョンにバックアップボールトを作成
    * 作成したCMKを指定
* 東京リージョンでAWS Backupにバックアッププランを作成
    * バックアップリソースとして2つのインスタンスを指定
    * コピー先として大阪を指定し、コピー先ボールトに作成したボールトを指定

### 検証結果
![AWS Backup 検証-結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43015/32a1d250-3ee6-ff50-2614-c0572bc57902.png)
もとのインスタンスの暗号化有無に関わらず、2つともCMKで暗号化された状態でバックアップが取得されました。
詳細は省きますが、こんな感じです。206から始まるCMKで無事暗号化されています。
![AWS_Backup_ボールト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43015/30befbcc-7336-e9ad-8173-95257500e8b0.png)
![EC2_Management_Console_encripted.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43015/9fbf0885-9353-c325-c53c-154c3d0761b1.png)
![EC2_Management_Console_not_encripted.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43015/4587922b-dd25-8d0b-ce50-24985d0b7475.png)

# 参考文献
### AWS Backupについて
DevelopersIOさんが、AWS Backupについてわかりやすく整理なさってました。
流石のクオリティで、ボールトとかルールとかプランとか一発で理解できます。
ありがとうございました。
https://dev.classmethod.jp/articles/aws-backup-perfect-understand/

### 公式ドキュメントの記載
https://docs.aws.amazon.com/aws-backup/latest/devguide/encryption.html
暗号化されたリソースのバックアップを取得する場合、もともとのリソースで使用されたキーを使って暗号化されると記載があります。
一方でクロスリージョンの場合は、もともとのリージョンで使用していたKMSキーは利用できませんとも記載があります。

ではその場合どうなるかという点については明記がないのですが、2021/5/31時点では関連した記載があります。
https://docs.aws.amazon.com/aws-backup/latest/devguide/encryption.html#encryption-cross-region-copies
要約するとこんな感じです。

> 暗号化していないリソースをバックアップする場合でも、下記の法則でデフォルトで暗号化しようとする。
> 1. 鍵の指定がない場合は、そのボールトに登録されている**AWS管理の**デフォルトのキーで暗号化する。
> 2. AWS Storage Gatewayの場合、ボールトに登録されている**カスタマーマネージド(CMK)**のキーで暗号化する。

ということでEC2の場合1が適用されてデフォルトのキーで暗号化されるのかなと思いつつ、もともと暗号化されていたものかつクロスリージョンだとどうなるのか試してみたところ、この記事のような結果になりました。
sudoでパスワード入力を省略する

# sudoでパスワードを入力しない方法

## 背景
* sudo を行うたびにパスワードを入力するのが煩わしいので、パスワードを入力しないようにしたい。参考の方が詳しいのであえて書く必要はなかったかもしれないが、自分の気づきもあったので書いてみた。

## 環境
* Ubuntu 18.04.5(LTS)

## 解説
* sudoers ファイルにパスワード入力しなくても良い設定を記載すればよい。
* ただし、viやnanoでファイルを編集するのは危険なので、visudoを使用する。
* また、今回の方法はすべてのコマンドでパスワードを入力しなくなるので、若干、危険である。
気になる場合は、パスワードを入力しないコマンドを指定することもできるらしい。

## 手順
1. sudoersファイルを開く
```
$sudo visudo
```

1. Allow members of group sudo to execute any commandの後に設定を追加する。（場所が大事！）
 
```
# Allow members of group sudo to execute any command
%sudo	ALL=(ALL:ALL) ALL
user-name ALL=(ALL) NOPASSWD:ALL ##追加！
```

## 参考
https://phpraxis.wordpress.com/2016/09/27/enable-sudo-without-password-in-ubuntudebian/
https://qiita.com/RyodoTanaka/items/e9b15d579d17651650b7
輪読メモ｜JavaScript｜目的のプロパティをプロトタイプチェーンで辿る

[開眼！ JavaScript――言語仕様から学ぶJavaScriptの本質](https://www.oreilly.co.jp/books/9784873116211/)を輪読会で読み進めている最中です。

本書の中で紹介されていたプロトタイプチェーンを辿って目的のプロパティを探している部分をChromeのデベロッパーツールを利用して、復習のため確認した📝になります。

JavaScriptでプロパティを呼び出す場合、JavaScript側では、呼び出されたプロパティが自身のプロパティに存在しない場合は、プロトタイプチェーンを辿ってプロパティが存在しないか確認して、存在する場合は存在したプロパティを呼び出す。プロトタイプチェーンを最後まで辿っても目的のプロパティが存在しない場合は、`undefined`を返す。
* * *
#### 本書に沿って、配列型の変数を宣言する。

```js
var myArray2 = ['foo', 'test'];
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/567376ee-dcee-81dc-578b-72f021d39685.png)
* * *
#### `join`メソッドを利用する

```js
console.log(myArray2.join());
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/049e71d4-23d6-1dcb-5ba3-3c54f4241cdd.png)
* * *
#### `join`メソッドがあるかどうか`hasOwnProperty`と`in句`を利用して確認する。

```js
myArray2.hasOwnProperty('join');
'join' in myArray2;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/89b7f91d-45a0-e545-7297-bc6d54653580.png)

`hasOwnProperty`の場合は`false`で、`in句`の場合は`true`
`hasOwnProperty`は純粋に自身のプロパティにいるかどうかを確認して、
`in句`の場合は、プロトタイプチェーンまで遡って存在確認した結果を返している。
⇒つまりプロトタイプチェーンのどこかのプロパティに`join`は存在するが、自身は`join`プロパティを保持していないことを指す。
* * *
#### プロトタイプチェーンを辿る
```js
myArray2.__proto__
myArray2.__proto__.constructor
```
`__proto__`はインスタンスを生成したコンストラクタ関数のprototypeプロパティにリンクする秘密のプロパティ。
`myArray2`の場合は、`Array()`でインスタンス化されているため、`Array()`のprototypeオブジェクトを指す。

```js
myArray2.__proto__.__proto__
```
↑の場合はさらにプロトタイプチェーンを遡って`Object()`のプロトタイプチェーン。JavaScriptは全て`Object()`に通ず…的な感じ。

`myArray2`　→　`Array()`　→　`Object()`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/44d9bebf-9b53-a796-af3a-2ac9f52d7e8b.png)
* * *
#### プロトタイプチェーンからjoinメソッドを探す
```js
myArray2.__proto__.hasOwnProperty('join');
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/fafac98a-c661-ba55-3b50-f23cd57a1def.png)
⇒プロトタイプチェーンのプロパティに`join`が存在することが確認できるため、ここまで遡って指定したプロパティに紐づくメソッドが実行されていた。
* * *
そのあと本書で紹介されいている`toLocaleString`は、`Array()`にも`Object()`のプロパティにも存在していて、この場合`Array()`でプロトタイプチェーンの検索は終了なのかな…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/6afd8e90-3fcb-1212-c53e-baab0f0eadcd.png)
* * *

#### インスタンスに同名のメソッドが存在する場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/da9c2302-3566-63ce-3cf8-4c906005d4cf.png)
インスタンスのメソッドが呼び出される。

* * *
##### Object().toLocaleString()
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/toLocaleString

##### Array().toLocaleString()
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString

* * *

理解しないまま使っていたことだらけで、とても勉強になっています。
このまま継続して輪読会を実施していきます…。
phtmlのrequireをtwigで書く方法

# 概要
phtmlファイルをtwigファイルに変更する過程で詰まったのでメモ
phtmlでrequireしているところはincludeで置き換える

* 以下のphtml形式のファイルをtwigに変換する    

#### phtml

```
<?php
    require 'hogehoge.phtml';  
?>
```

#### twig
```
{% include 'hogehoge.twig' %}
```

* 遷移先にパラメータをもたせたい場合はkeyとvalueを設定する  

```
{% include 'hogehoge.twig' with {key: value} %}
```
Oracle Analytics Cloudことはじめ：Oracle Analytics Desktopのレポート共有

皆さんこんにちは。
Oracle Analytics Cloudという名前だけにクラウド版では情報共有は、みんなが参照可能なフォルダ内にレポートを保存すれば心配は何もせずに情報共有を簡単に行うことができます。
一方で、デスクトップ版をご利用されている方のレポート共有の方法についてご紹介します。

Analytics CloudまたはOracle Analytics Desktopからエクスポートされたプロジェクト・ファイル(.dva file)をインポートできます。Oracle Fusion Applicationsからエクスポートされたプロジェクトもインポートできます。

ファイルのエクスポート方法によっては、プロジェクトのデータの復号またはプロジェクトのデータ・ソースへのアクセスを行うためにパスワードの入力を求められます。
インポートには、関連付けられているデータ・セット、接続文字列、接続資格証明および保存されたデータなど、プロジェクトの使用に必要なすべてのものが含まれています。

データも一緒にエクスポート/インポートできるためある時点でのスナップショットとしての役割も期待できます。
[C#/xaml] OxyPlotでTrackerを使う3

# oxyplot関連記事

https://tera1707.com/entry/2022/02/06/144447#oxyplot

# やりたいこと

[前回の記事](https://qiita.com/tera1707/items/e6952fbced5527eb9941)で、Trackerの見た目を改造したが、それを表示するために、線グラフの近くでマウスを左クリックしないといけない。

それを、マウスオーバーしただけで表示するようにしたい。

# やりかた

PlotViewにバインドしてるControllerに対して下記を行う。

```cs
controller.UnbindMouseDown(OxyMouseButton.Left);
controller.BindMouseEnter(PlotCommands.HoverSnapTrack);
```

# サンプルコード

[前回記事](https://qiita.com/tera1707/items/8c37f986f3935084927f)のコードに、上記2行を入れればOK。


# 参考

ここに書いてる。

https://qiita.com/laughter/items/422e25a6b3150a3199e7#tracker%E3%81%AE%E8%A1%A8%E7%A4%BA%E3%81%AB%E5%B7%A6%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%8C%E5%BF%85%E8%A6%81%E3%81%A0%E3%81%8C%E3%83%9E%E3%82%A6%E3%82%B9%E3%82%AB%E3%83%BC%E3%82%BD%E3%83%AB%E3%81%8C%E9%87%8D%E3%81%AA%E3%81%A3%E3%81%9F%E6%99%82%E3%81%AB%E8%A1%A8%E7%A4%BA%E3%81%97%E3%81%A6%E3%81%BB%E3%81%97%E3%81%84

https://github.com/oxyplot/oxyplot/issues/1116

https://shikaku-sh.hatenablog.com/entry/oxyplot-simple-usage
Oracle Analytics Cloudことはじめ：データ・フローを使用したデータ・セットの編集

皆さんこんにちは。
データ・フローでは、データを整理および統合して、ユーザーが分析できるキュレートされたデータ・セットを作成できます。
たとえば、オーダー・データを含む2つのデータ・セットをマージし、必要のない列を取り除き、オーダーの値を集計して、Order Summaryという名前の新しいデータ・セットに結果を保存します。

データフローの動画
https://youtu.be/p99qZ0oyF5A

データ・フローを使用してキュレートされたデータ・セットを作成するための一般的なタスクは以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/e731c824-7f86-dfcf-90f8-2f3bdd224616.png)

具体的な利用方法については別の機会にお伝えしますね
Qiitaを毎日投稿して1年経ったので振り返る

#プログラミング勉強日記
2021年5月31日
2020年5月23日に初めてQiitaを投稿して、(ほぼ)毎日投稿した。3回はインターネット回線が悪くなってしまい、その日中に投稿できなかったことがあったが、それでも毎日記事を投稿し続けました。
投稿して半年経ったときにも振り返っているので内容は被ることがあるかと思いますが、読んでいただけると幸いです。([Qiitaを毎日投稿して半年たったので半年間を振り返る](https://qiita.com/mzmz__02/items/024c4f57f0095df21275))

#簡単な自己紹介
　情報系の学部の大学4年生です。大学3年生の4月頃から就職活動を初めて、そのきっかけとしてプログラミングを独学で学び始めました。

#Qiitaを始めた理由と毎日投稿のきっかけ
　最初はProgateで勉強をしてその記録としてQiitaを始めたのがきっかけだった。プログラミングの勉強を始めた理由は就職活動のためで、Qiitaで勉強の記録を形に残せるのが就職活動において強みになると思って始めた。ただ、<b>始めた当初は毎日投稿するつもりはなかった</b>。「勉強したら記事を書く」という習慣が気付いたら毎日投稿していて、「毎日投稿すれば継続力がつくのではないか？自信になるのではないか？大学生で毎日Qiitaを投稿している人なんていないのでは？」と思い始めた。
　


#毎日投稿するためにしたこと

## 記事のハードルを下げた
　毎日投稿するにあたって、「すべての記事の内容が濃くて完璧な記事を書く」と認識しなかった。時間があるときや1週間かけて超大作記事を書いたこともあったが、毎日そのクオリティで記事を書き続けるのは自分には無理だった。そのため、備忘録や勉強メモとして自分が何をやったか・何を学んだかわかるように投稿した。

##記事を出す優先順位を付けた
　自分が困ったこと・解決策がネットで調べてもなかったことは優先して投稿するようにした。(読んでくださった方からお礼を言われることもあり、非常に嬉しかったです。)

##記事のストックを作った
　予定があって1日パソコンに触れられないときや、課題やテストに追われているときのために記事をストックすることもあった。完成した状態で下書きに保存し、日付が変わったら投稿するようにした。

##ネタを探す
　勉強したこと以外でも気になったことを調べてまとめるということもしていた。そのため、QiitaのネタになるものをTwitterやQiitaのトレンドを見て調べるようにした。


#毎日投稿のメリット

- 学習の定着
- 備忘録としての機能
- モチベーションの向上

　毎日欠かさず投稿しようと思っていたので、学習の定着になった。疲れてる日でも毎日投稿を途切れさせるわけにはいかないという想いから少しでもパソコンに触れるようになった。これによって、1日30分でも勉強する習慣がついた。
　また、備忘録としても記録しているので、「このエラー見たことあるな～」といったときに自分のQiitaを振り返ることで解決することがある。
　毎日投稿した記録が残り、投稿数自体がモチベーションになる。また、記事が増えることで自分で書いた前の記事をリンクに貼ることができるのも、モチベーションにつながった。

#毎日投稿のデメリット
　(個人的な意見です)

- Qiitaを書くためのネタ探しになる
- 時間が割かれる

　勉強のアウトプットとして記事を書いていたが、「Qiitaを書く」ということが目的になってしまったときがある。これによって、インプットの質が落ちてしまったような気がする…
　Qiitaを書くには最低30分の時間がかかる。基本的には約1時間かけて書いているが、毎日限られた時間でインプットの時間をとっているにも関わらずアウトプットに時間を割きすぎてしまうことがある。Qiitaを書く分インプットの時間が減ってしまっいる。 

#毎日投稿して嬉しかったこと
　ユーザランキングに自分の名前があったことや、トレンドに自分の記事があったときはとっても嬉しかった！他にも、Twitterやコメントでお礼の言葉を頂いたこともとっても嬉しく記事を書くモチベーションになった。
　私が`プログラミング勉強日記`というタグを作成した。当たり前だが、最初は私しかこのタグをつけて投稿している人はいなかったが、だんだんとこのタグを利用してくださる方が増えてきた。このタグが広まることも大変うれしかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/c5e1bed4-b45f-c6c6-dfdd-8d10d9c83a9d.png)

#これから
　しばらくは毎日投稿を続けようかと思う。毎日投稿をやめたとしても、1000記事投稿を目指して継続して記事を書こうと思う。投稿頻度を少なくした場合は、記事の内容を濃くしていこうと思う。


#最後に
　Qiitaの毎日投稿は大変でしたが、力になったと思います。毎日継続して投稿することで自信にもなったし、勉強する時間を確保することができました。

　1年間毎日投稿をすることで、Twitterを通して知り合った方やコメントしていただいた方、就職活動のサポートをしてくださった方、面接・面談をしてくださった方など、Qiitaの記事がきっかけで関わることのできた方々に大変感謝しております。この度は本当にありがとうございました。