OmniAICreator/Qiita-1.07M huggingface dataset:
『API』を基本からまとめてみた

## APIとは？
「API」とは、「Application Programming Interface」の頭文字のこと

- 英文字だけの意味だと、『アプリケーション・プログラミング・インターフェイス』で、大雑把に言うと『アプリケーションをプログラミングするためのインターフェース』という意味。

※『インターフェイス』をコンピュータ用語でいうと、「何か」と「何か」をつなぐものという意味

- アプリ内である特定のデータが欲しいとリクエストがある場合にサーバーに必要な情報を取得してアプリにかす流れ


## APIのメリット

①ソフトウェア開発の効率化
②セキュリティの向上
③最新情報を簡単に取得可能

#### ①ソフトウェア開発の効率化

APIで組み込むことができる信頼できるプログラムが世の中にすでに存在する場合、そのプログラムと連携することで、自分で1からプログラムを組む必要がなくなり、ソフトウェア開発の効率化がはかれる。プログラム開発側にとって、開発時間を短縮することができるのは大きなメリットで、時間短縮ができれば他の工程に時間を割くことができ、結果的にコスト削減が可能となる。

#### ②セキュリティの向上

各種サービスとAPI連携が行われているため、別アプリケーションログインによる、ログイン認証ができるようになっている。自社でセキュリティレベルの高い会員登録システムを入れるよりも、すでにあるセキュリティレベルの高い会員システムを導入する方がユーザーも安心で、ユーザー新たにユーザー登録をしなくても良い、という大きなメリットがあり、より多くの人に使ってもらえる、というメリットが提供側にもある。

※ちなみに、提供側は、APIの連携前に必ずユーザーの承諾を得る必要があり、ユーザー側も連携サービスを使うにはユーザー情報が共有されることを許可する必要がある。（どの情報が共有されるか、などはサービスにより異なる）

#### ③最新情報を簡単に取得可能
APIを使えば、それぞれのサービスの最新情報をこちら側が毎回更新しなくても取得、利用することができる。

## API設計の重要性

- 機能の提供
- 可読性・メンテナンス性
- エラーハンドリング・セキュリティ対策

開発者はAPIの設計がアプリの品質やユーザー体験に大きく影響することを認識した上で、開発をすることが重要

## APIの設計で気を付けること

①適切なメソッドを使う

※ RESTfulAPI
Webサービスの設計原則であるRESTを基にしたAPI

- GET(データを取得）
- POST(データを送信・作成)
- PUT(データを更新)
- DELETE(データを削除)

②命名規則を徹底する

③バージョンの管理

- アプリのバージョンと合わせてAPIのバージョンもバージョン１、バージョン２と入れておくと管理しやすい

④画面に依存しない汎用的な設計
- 情報ベースでAPIを作っていく

## API連携が必要なアプリ開発

- Swagger・・・APIの設計・構築・文書化、使用のためのオープンソースのソフトウェアフレームワーク
- Postman・・・様々なタイプのAPIリクエストを簡単に作成・送信・テストができる

## 外部APIを使う際の注意点

- 料金
- SLAの確認(サービス品質保証)
- セキュリティ
- APIの信頼性(APIが止まるとアプリが稼働しなくなる)


## 参考サイト
[今さら聞けないIT用語やたらと耳にするけど「API」って何？](https://data.wingarc.com/what-is-api-16084)
[【アプリ開発】アプリ開発におけるAPIとは？API設計でアプリの品質の９割が決まる！？](https://www.youtube.com/watch?v=E5nZyhTRL8Q&list=WL&index=2)
coc-nvimでvue3をいじれるようにする



## パッケージインストール
```
npm init @eslint/config
npm install --save-dev eslint eslint-plugin-vue -g
```

## cocのプラグインインストール
```
:CocInstall coc-prettier
:CocInstall coc-eslint
:CocInstall coc-vetur
```


## フォーマットコマンド

```
# :Formatでフォーマット
command! -nargs=0 Format :call CocAction('format')
```

## CocConfigの設定
CocConfigを表示させる
```vim
:CocConfig
```

以下を追記
```json
{
  "eslint.autoFixOnSave": true,
  "eslint.filetypes": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "vue"
  ]
}
```

## HTML閉じタグ自動補完
```
Plug 'alvan/vim-closetag'  " html閉じタグを自動補完 
```

## 参考
https://qiita.com/domodomodomo/items/36c488c1efc2fb8d1714
django-auth-ldap を用いて Django に LDAP 認証してみる

# 本記事の目的

Ubuntu20.04 上に Django を構築し、LDAP クライアントとして活用できるようにするまでの手順をまとめておく。目指すイメージは以下の通り。

![figure-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2902882/9d40d867-53a3-c526-cb7d-0bdb52deff8f.png)

LDAP サーバについては、以下記事で作成したものを流用。

https://qiita.com/shintaro-san/items/d9f5ac3fa4c8bc30a2ca

したがって、LDAP は以下のような構成になってます。

![figure-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2902882/024466b6-ce9d-cb58-5879-58e2e9b3ca83.png)

# 参考記事

* Django のインストール

https://tutorialcrawler.com/ubuntu-debian/ubuntu-20-04%E3%81%ABdjango%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/

* Django への LDAP 設定

https://django-auth-ldap.readthedocs.io/en/latest/install.html

# 手順

## インストール時のエラーについて

django-auth-ldap のインストール時にエラー発生したが、そちらの解決については以下 URL に記載している。

https://qiita.com/shintaro-san/items/44566394fb7eb065054f

## 手順詳細

基本は上の URL に従えば OK。

* django-auth-ldap のインストール
<pre>$ pip install django-auth-ldap</pre>

* settings.py に以下を追記する。
<pre>import ldap
from django_auth_ldap.config import LDAPSearch

(中略)

AUTHENTICATION_BACKENDS = [
        "django_auth_ldap.backend.LDAPBackend",
        "django.contrib.auth.backends.ModelBackend",
]
AUTH_LDAP_SERVER_URI = "ldap://192.168.56.102"
AUTH_LDAP_BIND_DN = ""
AUTH_LDAP_BIND_PASSWORD = ""
AUTH_LDAP_USER_SEARCH = LDAPSearch(
    "ou=people,dc=hoge,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"
)</pre>

※ AUTHENTICATION_BACKENDS をこのような書き方にしているのは、"django_auth_ldap.backend.LDAPBackend" だけだと全ユーザが LDAP でしかログインできなくなることを踏まえて。管理者ユーザは LDAP を使わずにログインできる仕様としたかったので、このような書き方にした。

* user001 で、Django にログイン試行する。

![figure-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2902882/4b4746b6-7759-d96c-c977-3f43ede0737d.png)

* このタイミングではおそらくログイン失敗するが、Django 上に user001 のアカウントは自動作成されているので、LDAP クライアントとしては正しく設定されている様子。

![figure-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2902882/a6b9abe5-8695-5d17-08aa-c53ed0ade452.png)

* user001 の詳細から、Staff status にチェックを入れてあげると、user001 でのログインが可能となる。


# 最後に

* ユーザのログインについては、Staff status にチェックをしているのがデフォルトで認証できると嬉しいけど今回はそこまでは確認せず。。Django の設定でできるような気はするけど、ドキュメントをもっと読まねば。
* LDAP 認証しているユーザについて、パスワード変更しようとした場合にどういう挙動になるのかも確認できてない。本格運用するとなったら、もっと細かいところまで実装見る必要ありそう。
* Active Directory とか使った場合にどうなるのかも今後みてみたい。
sakuraのレンタルサーバーにあるGitリポジトリにssh公開鍵認証で接続する方法（tortoiseGit編）

sakuraのレンタルサーバーにGitリポジトリを作成したのは良いものの、sshで接続するとプル／プッシュの時に毎回パスワードを要求されて困っていた。
Puttygenで秘密鍵・公開鍵を作成しTortoiseGitに登録する際の注意点を記載する。


# ◆大まかな手順
>　①PuTTYgenで秘密鍵・公開鍵を作成する
　②公開鍵をsakuraサーバにアップロードし公開鍵の設定をする
　③tortoiseGitにて秘密鍵を利用する

## ①PuTTYgenで秘密鍵・公開鍵を作成する
- TortoiseGitの中にあるPuTTYgenを起動
　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964854/c4ca6051-c864-f858-01cc-714ec4c287ca.png">

- Generateボタンを押下
　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964854/eb34665f-ce58-c63d-42df-a81661f01346.png">

- この辺りでマウスをグルグル動かす
　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964854/72bb12bf-8d2a-1dc0-762e-3a14bd90d452.png">

- 終わったらssh-rsaの部分を全行選択しテキストファイルにコピーし保存する
  ファイル名は「id_rsa_sakura.pub」などにする
　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964854/059b14bc-54d7-c9d0-beb4-9ecc2d2ab9bd.png">
　※公開鍵は「Save public key」で保存しないので注意

- 次に「Save private key」を押して秘密鍵を保存する
  なんか出るけど構わす「はい」を選択する（「パスフレーズ設定してないけどええ？」って聞かれている）
  ファイル名は「id_rsa_sakura.ppk」などにする（拡張子をppkにする）
　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964854/27031c15-84d5-fc8c-281e-815ebe07652f.png">


## ②公開鍵をsakuraサーバにアップロードし公開鍵の設定をする
- テキストファイルに保存した公開鍵（id_rsa_sakura.pub）を、ffftpやWinScpでsakuraサーバの
  「~/.ssh」にアップロードする
  ※アップロードする際は「テキストモード」で改行コードをCR/LFからLFに変更する

- terminal（PuttyやTeraTermなど）でsakuraサーバにログインする

- 次に~/.sshに移動
>```
>cd ~/.ssh
>```

- アップロードした公開鍵（id_rsa_sakura.pub）を~/.ssh/authorized_keysに登録する

　　［~/.ssh/authorized_keysが存在しない場合］
>```
>cat ./id_rsa_sakura.pub > ./authorized_keys
>```

　　［~/.ssh/authorized_keysが存在する場合］
>```
>cat ./id_rsa_sakura.pub >> ./authorized_keys
>```

- authorized_keysのパーミッションを変更する
>```
>chmod 600 ./authorized_keys
>```


## ③tortoiseGitにて秘密鍵を利用する
- Gitクローンする際に秘密鍵（`id_rsa_sakura.ppk`）を指定する
　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964854/baeee29e-7939-7a6f-388f-423889b57ed1.png">



  設定しなおしたい場合は、TortoiseGitの設定で秘密鍵を指定する
　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964854/8898316a-b631-c92c-5c2b-c30f1967e3db.png">


## 設定は以上で完了
[Flutter][Android] 他のアプリを抑制しつつNFC タグを読み込む

# 課題
NFCタグをアプリから読み込もうとしたが、他のアプリも反応してしまう。
アプリを開いているときは、他のアプリが反応しないようにしたい。

# 環境
- Flutter
- [nfc_manager](https://pub.dev/packages/nfc_manager) package を利用

# 対策
enableForegroundDispatch を使うことで抑制できる。
自分が前面にあることが条件。

答えは、プラグイン作者のサンプルにありました。
https://github.com/okadan/nfc-manager/blob/master/android/app/src/main/kotlin/com/naokiokada/nfcmanager/MainActivity.kt

ただし古いので、最新の　Android SDKに対応するには　PendingIntent生成時に PendingIntent.FLAG_IMMUTABLE を指定しないと起動しません。

# 後記
NFCタグは工夫次第で色々と使えそうに感じました。
ただ利用するには、タグに書き込む内容に対する Android/iOS それぞれの振る舞いはどうか、複数のタグを書き込んだ場合の振る舞いはどうか、など色々と勉強が必要ですね！
vimでhtmlの閉じタグを自動補完する


こちらのプラグインを利用させてもらう
https://github.com/alvan/vim-closetag

## インストール

```vim
Plug 'alvan/vim-closetag'
```

## 対象ファイルを指定したい場合は、vimrcに追記する

このような感じ

```
let g:closetag_filenames = '*.html,*.xhtml,*.phtml,*.vue'
```
【時系列分析/Python】statsmodelsライブラリのDeterministicProcess関数を使用して、売上予測をする。

# 今回の課題
Kaggleの[Trend](https://www.kaggle.com/code/ryanholbrook/trend)というチュートリアルでstatsmodelsライブラリを使用して、
未来の数値の予測が行われていた。

そのチュートリアルを参考に、
前回投稿した下記の記事の、未来の売上予測を行いたかった。
https://qiita.com/Ayumu-y/items/a2f3f716706a6f34028b

# statsmodelsライブラリとは
統計モデルを用いて推定や検定、探索ができるPythonライブラリ。
statsmodelsライブラリの中に`DeterministicProcess`関数があり、
この関数を使用することで未来の数値の予測ができる。

※公式ドキュメントは[こちら](https://www.statsmodels.org/dev/generated/statsmodels.tsa.deterministic.DeterministicProcess.html)



# 使用したコードの解説
作成したコードが下記の通り。

### 1)ライブラリのインポート
```python
from statsmodels.tsa.deterministic import DeterministicProcess
```

### 2)DeterministicProcess関数をインスタンス化
※公式ドキュメントに説明が書いているが、
　理解が難しいため試行錯誤しながら学ぶ必要がありそうだと感じた。
```python
dp = DeterministicProcess(
    index=trend_df.index # インデックスを指定。ここではDatetimeIndexとなっている。
    , constant=True      # 定数を含めるかどうか
    , order=1            # 含めるタイミングトレンドの順序。
    , drop=True          # 完全な共線性をチェックし、線形従属項を削除することを示すフラグ。
)

# `in_sample`は`index`引数で指定された日付に対応する特徴量を作成する。
X = dp.in_sample()
X.tail()
```
**出力結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/3cf19e60-ac9c-ad5c-bbae-de229be1e085.png)


### 3)LinearRegressionモデルに目的変数と説明変数を学習させ目的変数を予測する
```python
from sklearn.linear_model import LinearRegression

y = trend_df["sales"]

# DeterministicProcess.LinearRegressionは重複する特徴量に対して悪い振る舞いをする。
# 重複する訴訟に対して線形回帰は悪い振る舞いをするので、ここでは確実に除外する必要がある。
# fit_intercept=Falseとすると、切片０モデルになる。
model = LinearRegression(fit_intercept=False)
model.fit(X, y)

y_pred = pd.Series(model.predict(X), index=X.index)
```

### 4)Daily Salesを可視化する
```python
ax = trend_df.plot(style=".", color="0.5", title="Daily Sales - Linear Trend")
_ = y_pred.plot(ax=ax, linewidth=3, label="Trend")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/478046bc-1cd0-2b4a-4063-dcced27b5049.png)

### 5)out_of_sampleで、引数のstepの数分の未来の数値を予測する
<font color="Red">**※注意点**
**X = dp.out_of_sample**だけでは、データフレームXのインデックスがただの数字になってしまうので、
DatetimeIndexに変換するためのコードも入れる必要があった。</font>
```python
X = dp.out_of_sample(steps=365)

# indexが数値になってしまうので、下記の2行のコードでDatetimeIndexに変更しておく。
X["date"] = pd.date_range(start="2017-08-16", end="2018-08-15", freq="D")
X = X.set_index("date")

y_fore = pd.Series(model.predict(X), index=X.index)
y_fore.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/76036a49-77e4-24c7-2a93-a7d84965628e.png)


### 6)未来の売上を予測して可視化する
```python
ax = trend_df["2013-01-01":].plot(title="Tunnel Traffic - Linear Trend Forecast", **plot_params)
ax = y_pred["2013-01-01":].plot(ax=ax, linewidth=3, label="Trend")
ax = y_fore.plot(ax=ax, linewidth=3, label="Trend Forecast", color="C3")
_ = ax.legend()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/fcf2f466-93ee-395a-a099-a1690765d9ea.png)

以上です。
django-auth-ldap のインストール時にエラー発生

# 本記事の目的

以下記事をもとに、Ubuntu20.04 に構築した Django を LDAP クライアントにしようとした。

https://django-auth-ldap.readthedocs.io/en/latest/install.html

ところが、以下手順でエラーが発生しインストール失敗。

<pre># pip3 install django-auth-ldap

(中略)
Failed to build python-ldap
ERROR: Could not build wheels for python-ldap which use PEP 517 and cannot be installed directly
</pre>

本記事では、解決方法を記載しておく。

※ Django の構築自体は以下記事を参照に実施。

https://tutorialcrawler.com/ubuntu-debian/ubuntu-20-04%E3%81%ABdjango%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/

※ Ubuntu20.04 のバージョン情報
<pre>$ lsb_release -a

Distributor ID: Ubuntu
Description:    Ubuntu 20.04.5 LTS
Release:        20.04
Codename:       focal</pre>

# 解決方法

以下記事を参考にした。

https://bobbyhadz.com/blog/python-error-could-not-build-wheels-for-python-ldap

pip のバージョンが最新であることを確認後、以下実施して解決。

<pre>$ sudo apt-get install build-essential python3-dev \
    libldap2-dev libsasl2-dev slapd ldap-utils tox \
    lcov valgrind</pre>

以上で本記事はおしまいにしておく。
LaTeXコンパイラ時間比較 (Windows, Mac, iPad)

# 予想

シングルスコアが高い順にコンパイラ時間が短くなるだろう

# 比較表

|OS|機種|CPU|GHz|single|multi|TIME|
|---|---|---|---|---|---|---|
|Linux (Windows10 WSL2)|自作PC|Ryzen5 3600|3.60|1172 (1193)|6362 (8433)|2.64s|
|Mac|MacBook Air early 2015|Core i5 5250U|1.60|655 (599)|1396 (1571)|5.00s|
|iPad (a-shell) |iPad Pro 11 (3rd)|Apple M1|3.19|1686|7166|2.01s|
|iPhone (a-shell)|iPhone SE2|Apple A13 Bionic|2.66|1319|2846|2.71s|
|Mac|MacBook Pro late 2020|Apple M1|3.2|1752|7711|1.1s|
|Windows 11|Lenovo ideapad Slim5|Core i7-13620H|-|-|-|1.99s|
|Mac|MacBook Air 2020|Apple M1|-|-|-|1.08s|
|-|Overleaf|-|-|-|-|1.48s|




- スコアは Geekbench 5
- 括弧内のスコアは Cinebench R23 (10 minutes)


# テストファイル
```
\RequirePackage{l3benchmark}
\ExplSyntaxOn
\AtEndDocument { \benchmark_toc: }
\benchmark_tic:
\ExplSyntaxOff

\documentclass[12pt]{beamer}
\usepackage{mathpazo}
\newcount\K
\def\myfor#1{
  \K=0 \loop\ifnum\K<#1
    { \begin{frame}{title}Hello, world!\end{frame} }
  \advance\K by1\repeat
}

\begin{document}
\myfor{50}
\end{document}
```

- 50ページのbeamer
- .log ファイルのドキュメントの最後でコンパイラ時間が表示される



# 参考
https://tex.stackexchange.com/questions/409232/is-it-possible-to-use-gpu-acceleration-on-compiling-large-latex-documents

https://tex.stackexchange.com/questions/103565/tips-for-choosing-hardware-for-best-latex-compile-performance

>[I]t is only one thing that really makes a difference: Single-Threaded CPU power!

>[T]he result roughly is: compilation times scale nearly linear with the CPU clock. It's the fasted Core i7 that makes the run; memory and disk plays only a minor role (given that you provide modest quality and size of both). 

>To sum up: For a "LaTeX machine" it is the processor and in particularly it's single-core throughput one should look for. However, the latter is not always easy to figure out, as basically all processors nowadays are multi-core and benchmarked and advertised with their multi-core throughput. A good starting point is [the PassMark CPU Benchmarks site](https://www.cpubenchmark.net/singleThread.html), which provides a frequently updated report on "Single Thread Performance" for all current IA32e/AMD64 CPUs.
Dockerコンテナが起動しない問題について

もうすぐエンジニアキャリアが１年になります。仕事にも慣れて、開発案件にもスクラムで携わることが多くなりました。
しかし、戦力としてはまだまだ・・・ｗｗ　早く会社とチームに貢献できるだけのスキルを習得するため、日々学習を続けています！
そんな中で、最近Dockerの学習をしていたら気になることがありましたので投稿します！

# 1.Dockerコンテナが起動しない
先日、Dockerの学習をするため、Dockerイメージをプルした後に `docker run`でコンテナ作成 →　`docker start`でコンテナを起動させようとしたらコンテナが起動しませんでした...

#### 作業の流れ
````
~ $ docker pull centos             #centosのイメージをプル
~ $ docker run 5d0da3dc9764        #コンテナ作成
~ $ docker ps -a                   #作成したコンテナIDを確認
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS                      PORTS     NAMES
f1ae22864372   5d0da3dc9764           "/bin/bash"              5 minutes ago   Exited (0) 5 minutes ago              lucid_cray
````
#### コンテナを作成するところまではうまくいきました
コンテナが**exit**状態になっているので`docker start`で起動させます

````
~ $ docker start f1ae22864372   #コンテナを起動
f1ae22864372

~ $ docker ps　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　#コンテナ確認
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
````

あれ？？？　コンテナが起動していませんね・・・？そしてエラーも出てない？？
いつもだったら`docker ps`で確認するとコンテナIDや名前が出てくるはずですが、突然でした・・・

# 2.調査
ネットで調べましたが有力な情報がなかなか出てきません
困ったな・・・

# 3.解決
##### 「まてよ、もし`docker run -it 5d0da3dc9764 bash`コマンドで一気にコンテナに入ったらどうなるかな？」 
と思ったので早速実験しました。
**＊先程作ったコンテナは削除しました！**

````
~ $ docker images                                 #イメージ確認
REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
centos                        latest    5d0da3dc9764   15 months ago   231MB

~ $ docker run exec -it 5d0da3dc9764 bash         #コンテナを作成・起動した直後コンテナに入る
[root@992c4a771552 /]#
````
### お！！入れた！！
一度コンテナから抜けて、コンテナを起動・停止できるか確かめてみます！

````
[root@992c4a771552 /]# exit                #コンテナから抜ける
exit
~ $ docker ps -a                           #コンテナ確認

CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS                     PORTS     NAMES
992c4a771552   5d0da3dc9764           "bash"                   6 minutes ago   Exited (0) 6 minutes ago             recursing_galois

~ $ docker start 992c4a771552              #コンテナ起動
992c4a771552

~ $ docker ps                              #コンテナ確認（up状態のコンテナのみ）
CONTAINER ID   IMAGE          COMMAND   CREATED         STATUS              PORTS     NAMES
992c4a771552   5d0da3dc9764   "bash"    9 minutes ago   Up About a minute             recursing_galois

~ $ docker exec -it 992c4a771552 bash      #コンテナに入る
[root@992c4a771552 /]# 
````
コンテナ起動・停止やコンテナに入ったり抜けたりを試しましたが、うまく行ったようですね！！

# 4.原因
お恥ずかしながら、原因については分かりませんでした...（泣）
しかし、今回分かったことはDockerイメージからコンテナを作成する場合は`docker run -it **イメージID** bash`コマンドでコンテナを作成しないと起動ができないことです。もし、`docker run **イメージ名**`のコマンドでコンテナを作成した場合`docker start`でコンテナを起動出来なくなるようです。**作成したコンテナ使えないので捨てる以外に方法がなくなります**
以前、Dockerを使っていたときはこんなことは起きなかったのですが、突然このような現象が起きました。なんか環境が変わったのかな？？
もし、ご存知の方がいらっしゃいましたら教えていただけるとありがたいです！
【Firebase】SNS共有用のDynamicLinksを手動で構築する

「ツイートする」ボタンのようなSNS共有用のリンクはFirebaseであればDynamic Linksで容易に生成が可能です。  
Firebase×Flutterといえば基本的にFlutterFire(https://firebase.flutter.dev/) を使っておけば間違いはないわけですが、残念ながら2023年1月7日現在、FlutterFireのDynamicLinksはWebに非対応です。  
ではWebでは使えないのかというとそんなことはなく、DynamicLinksは形式に沿って記述すれば手動で生成できます。  
今回はFlutter/Dartでサンプルを作成していますが、基本的に言語関係なく同様の方法で利用可能です。  
# 完成形
![example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417009/829773fd-b23b-b833-1875-52d1f426db99.png)
黄色枠部分を生成します。  
共有すると青枠部分のような見覚えのあるフォーマットが表示されます。
# 参考
正直なところこの記事読まなくても公式のページ読めば十分です。  
https://firebase.google.com/docs/dynamic-links/link-previews
https://firebase.google.com/docs/dynamic-links/create-manually
# 流れ
1. Firebaseコンソールでサブドメインを設定しておく
2. 共有用画像のURLを用意する
3. フォーマットの通りにURLを生成する
4. 日本語や#等一部記号をURLエンコードする  
※サブドメインに指定するのは赤線部分  
<img width="300" alt="スクリーンショット 2023-01-07 105225.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417009/873fe7d8-025f-3938-80ba-a2f80ae933f1.png">

# サンプルとか
## ソースコード
パッケージなのでダウンロードして展開するか、GitHubのURLをpubspec.yamlで指定してあげれば使用できると思います。
https://github.com/esuno/manually_constructured_dynamic_link

## 動くサンプル(ツイートボタン)
https://esuno.info/ogp/?link=https://esuno.info/%23/experiments/dynamic_link_tweet_button&st=%E3%83%84%E3%82%A4%E3%83%BC%E3%83%88%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB&sd=%E3%80%90Firebase%E3%80%91SNS%E5%85%B1%E6%9C%89%E7%94%A8%E3%81%AEDynamicLinks%E3%82%92%E6%89%8B%E5%8B%95%E3%81%A7%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B%E3%80%80%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB&si=https://storage.googleapis.com/esunoinfo-ogp/dynamic_link_tweet_button.png 
ちなみに当該手法で生成したダイナミックリンクはこのとおりQiitaでは効かない模様。無念です
CodeIQ:ちょっと奇妙な足すと引くの解答

@nabetaniさんのCodeIQの問題です。
問題とテストケースはこちらのお世話になりました。解答もあります。
https://blog.goo.ne.jp/r-de-r/e/494b9fa23bc9e59bb77a2ec5685a18f2

ctol/4で文字列をリストに変換しています。
私は末尾再帰を使うことが多いのですが、右結合の計算は普通の再帰がぴったりです。
solve/2で'('のない間は3行目で普通の再帰を用いて
数式の最後から順にcalc/2で計算していきます。
'('が出てきたらbra/3で'('の後の数式を保存し')'が出たらカッコを外し、
保存した部分をsolve/2の3行目で計算し、元の位置にもどします。
　例　1+3-1->1+2->3
　　　2-(4-3)+1->2-[(]4-3)+1->2-[(4-3)]+1->2-1+1->2-0->2

```Prolog
%SWI-Prolog (7.4.2,7.6.4)
%:-initialization(start).  %ideone
%start.

calc([X,+,Y],R):-R is X+Y.
calc([X,-,Y],R):-R is X-Y.

bra([],R,R).
bra(['('|T],B,R):-bra(T,[],R1), bra(R1,B,R).
bra([')'|T],B,R):-solve(B,R1), append([R1],T,R).
bra([X|T],B,R):-append(B,[X],B1), bra(T,B1,R).

solve([X],X).
solve(['('|T],R):-bra(T,[],R1), solve(R1,R).
solve([X,F|T],R):-solve(T,R1), calc([X,F,R1],R).

start:-f(L), pre(L), !.

pre([]).
pre([[S,Q]|T]):-atom_chars(S,L1), ctol(L1,[],[],L), solve(L,R), disp(R,Q), pre(T).

ctol([],L,R1,R):-
     (L=[X] -> R2=[X|R1]; R2=R1), reverse(R2,R).
ctol([H|T],L,R1,R):-
     not(member(H,[+,-,'(',')'])), !, atom_number(H,N1),
     (L=[X] -> N2 is X*10+N1; N2=N1), ctol(T,[N2],R1,R).
ctol([H|T],L,R1,R):-
     (L=[X] -> R2=[X|R1]; R2=R1),R3=[H|R2], ctol(T,[],R3,R).

disp(R,Q):-(Q=:=R -> Str=" pass "; Str=" fail "), write(Str), writeln(R).

f([["19+2-3-4",22],
 ["19+(2-(3-4))",22],
["6-1-4-4-8-4-6-3-5-8-7-9-9-2-7-8",13],
["8-9+6+9+5+1+6-1-4-2+4+8-2+1+5+4",-29],
["3+3-1-6+7-5+5+9+2+4-8+3+1-4+5+5",-9],
["6-68-47-3-76-52-78-15-20-99-58",48],
["23+13+85-49+41+64+69-0+50-34-93",7],
["12-(3-4-(5-6-7)-8-(9-10-11))-123",128],
["9-(((((((((((((34)))))))))))))-1",-24],
["987-(12-(3-45-6)-7-8)-9-(123+45)",781],
["(9-10)-(2-5)-(7-9)-(7-45)-(3-39)",2],
["(((((((99-8)-7)-6)-5)-4)-3)-2)-9",55],
["999999999+999999999+999999999+99",3000000096],
["1000000000-(99-19-3)+(88-32-11)",999999850]]).
```
部下を持ったらやってはいけないことリスト80

# 概要

この記事は自分の経験を元に自分への戒めとして備忘録的に残すリストです。
過去の炎上プロジェクトを起こしやすい人を観察してまとめました。

部下を持つ立場になった場合及び、プロジェクトリーダーやマネージャーになった時、下記のリストの逆のことをすると大抵の物事が好転します。

# やってはいけないことリスト80

リーダーシップを持つと言うことは、下記は決してやってはいけないことと思います。

1\.うまくいかない場合は他責
2\.出る杭を打つ
3\.ホラ吹きの見栄っ張り
4\.向上心皆無
5\.感情的にしか物事を考えられない
6\.自分の経験を押し付ける
7\.物事を客観視できない
8\.論理的思考ができない
9\.「ありがとう」が言えない
10\.門地差別が激しい
11\.勘違いする。(自分が正しいと思いがち)
12\.感情を抑えられない
13\.口が軽い
14\.D言葉が多い(でも、だって、だから、どうしても)
15\.身なりがだらしない
16\.相手に誠意を持てない
17\.年下を馬鹿にする
18\.知ったかぶりをする
19\.責任感が無い
20\.自分のことばかり話して傾聴できない
21\.努力しない
22\.共感はなく決めつけ
23\.利他ではなく利己
24\.他人の成長と活躍を妬む
25\.失敗は処理せず責任の押し付け合い
26\.人を育てられない
27\.仕事を苦役に変える
28\.「やろう」と言えず「やれ」と言う
29\.信用しては裏切る
28\.相手の立場になって物事を考えられない
29\.本当に必要な時に必要な事ができない
30\.昔の武勇伝が多い
31\.未来に話を向けられない
32\.自分の意思が無い
33\.危機感を持てない
34\.精神論、根性論が激しく生産性が無い
35\.個々の能力や価値観に関心が無い
36\.人を行動させるメカニズムを知らない
37\.解決策を伝えても相手に受けれる準備が整っていないと何も伝わらない
38\.稀に暴力で支配しようとする
39\.計画性がない
40\.他人に依存する
41\.できない理由ばかり考えて可能になる理由を考えない
42\.社会人なっても勉強しない
43\.すぐ諦める
44\.派閥を作る
45\.健康に気を使わない
46\.他人を追い込む
47\.他人の暮らしを監視する
48\.よそ者を受け付けない
49\.デリカシーが無い
50\.金にがめつい
51\.男尊女卑 52:最初の印象で他人を決めつける 53:比べたがり
54\.人の良いところは探さず、人の悪いところを探す
55\.堕落物
56\.横柄な態度をとりやすい
57\.マナーが悪い
58\.ギャンブル依存
59\.妄想が激しい
60\.お局に世論がコントロールされている
61\.ケチで数々の可能性を潰している
62\.年上の発言権が強い
63\.悪口上げ足取りな噂大好き
64\.誇大妄想でプライド高い
65\.人の不幸を願っている
66\.嫌味好き
68\.人を不愉快にするのが得意
69\.頑固
70\.良心を持つ人ほど病む
71\.ことながれ主義
72\.逆ギレしやすい
73\.交友関係で個人情報ダダ漏れ
74\.マウンティング気質が横行
75\.リスクヘッジできない
76\.「今よければいいや」と考える
77\.反抗心が強い
78\.表現力が下手
79\.いい人にたかる
80\.視野が狭い
試し割り法による素数の生成

試し割り法による素数の生成です。
`prime2.py`として実行したら、素数が１行毎、次々と出力されます。
`chmod +x prime2.py`として、実行権限を付けて動かして下さい。


```prime2.py
#!/usr/bin/python3
#
#試し割り法による素数の生成
#
def trial_division(t):
  for i in range(2,t):
    if t % i == 0:
      return(0)
  return(1)
 
def nth_prime(n):
  m=2
  primes=[]
  while(1):
    if (trial_division(m)==1):
      primes.append(m)
      if (len(primes)==n):
        return(primes[n-1])
    m=m+1

n=1
while(1):
  print(nth_prime(n))
  n=n+1
```
falseからの配列自動生成が非推奨になっていたのでsqliteで困った

お絵描き掲示板[noReita](https://github.com/sakots/noReita)をつくっています、さこつです。

今回表題の件で困ったことが解決したので記事にしようと思います。

## 何が起きたのか

実はPHP8.1で起きてたらしいんですけど、([falseから配列の自動生成が非推奨になりました。](https://qiita.com/rana_kualu/items/e350b8ff80f929626eb9#automatic-conversion-of-false-into-an-empty-array-on-write-operands-is-deprecated))

自分はsqlでこういうことをしていました。

```index.php
//最新コメント取得
$sqlw = "SELECT * FROM tlog WHERE thread=0 ORDER BY tid DESC LIMIT 1";
$msgw = $db->prepare($sqlw);
$msgw->execute();
$msgwc = $msgw->fetch();
```

```index.php
$msgwc["tid"] = 0;
$msgwc["age"] = 0;
$msgwc["tree"] = 0;
```

するとここでエラーが出たんですね。

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569616/60e56138-4bb9-47bc-4302-7bd956ef93b8.png)

## falseがはいるsql文でやったこと

`tid`でfalseのエラーがでるらしい。自動生成が非推奨なら手動で生成すればいいや、ということでこうしました。

```index.php
//$msgwc["tid"] = 0;
$msgwc["tid"] == false ? 0 : 0;
```

きもちわるい三項演算子です。ifでよかったかも。

厳密でないのは厳密でないfalseの可能性もあったからです。

## 結論

true/falseからの配列の自動生成は手動でやればいい。
草莽Erlang ── 10. 関数

口で言うより行うことがErlang習得への近道と信じています。

https://qiita.com/mnishiguchi/items/9237780e849d80a85e11

## Erlangの関数

大きく分けて３種類あります。

1. モジュールに定義された関数
1. Erlangビルトイン関数（BIFs）
1. 無名関数

### モジュールに定義された関数

- 基本的に`Module:Function(Arguments)` という形で呼び出す
- モジュール内の関数、及び明示的にインポートされた関数は、モジュール名を省略して呼び出せる

一例として`io`モジュールの`format/2`関数を呼び出してみます。

```erlang
> io:format(["闘魂", $\n]).
闘魂
ok
``` 

#### 関数を宣言する方法

- 関数はセミコロン(`;`)で区切られ、ピリオド(`.`)で終端する一連の関数節で構成される
- 関数節は節頭と節胴体からなり，`->`で区切られる
- 節頭は，関数名（アトム）、引数リスト（パターン）および`when`で始まるガードからなる
- 節胴体はカンマ（`,`）で区切られた一連の式で構成される

```
関数名(引数パターン1) [when ガード1] ->
  式11,
  式12;
関数名(引数パターンN) [when ガードN] ->
  式N1,
  式N2.
```

一例として階乗の関数は以下のように宣言します。
 
```erlang
fact(N) when N > 0 ->  % 第一節 頭
  N * fact(N - 1);     % 第一節 胴体
                       % 節は「;」で区切る
fact(0) ->             % 第二節 頭
  1.                   % 第二節 胴体
                       % 終端は「.」
```

https://www.erlang.org/doc/reference_manual/modules.html

https://www.erlang.org/doc/reference_manual/functions.html

https://www.erlang.org/doc/reference_manual/expressions.html#function-calls

### Erlangビルトイン関数（BIFs）

- `erlang`モジュールに属している
- 他の関数と違って、自動的にインポートされる

```erlang
% モジュール名を省略できる
> hd([1, 2 ,3]).
1

% モジュール名を明示してもOK
> erlang:hd([1, 2 ,3]).
1
```

https://www.erlang.org/doc/man/erlang.html

### 無名関数

- `fun ... end`式で定義すること以外は、モジュールで定義する場合と同じ書き方
- 変数に束縛して使用可能

https://www.erlang.org/doc/reference_manual/expressions.html#fun-expressions

https://www.erlang.org/doc/programming_examples/funs.html

https://learnyousomeerlang.com/higher-order-functions 

https://www.ymotongpoo.com/works/lyse-ja/ja/08_higher_order_functions.html

まずは簡単なやつで練習してみます。

```erlang
> Aisatsu = fun () -> io:put_chars("元気ですかーーーーッ！\n") end.

> Aisatsu().
元気ですかーーーーッ！
ok
```

階乗は無名関数で書くとこんな感じになります。再帰処理をするには引数に関数自身を渡す必要があります。

```erlang
Fact = fun
  (Fact, N) when N > 0 ->  % 第一節 頭
    N * Fact(Fact, N - 1); % 第一節 胴体
                           % 節は「;」で区切る
  (Fact, 0) ->             % 第二節 頭
    1                      % 第二節 胴体
end.                       % 終端は「.」
```

```erlang
> Fact(Fact, 2).
2
> Fact(Fact, 3).
6
> Fact(Fact, 4).
24
```

無名関数の中で無名関数を書くこともできます。

```erlang
Factorial = fun (Number) ->
  Fun = fun
    (F, N) when N > 0 -> N * F(F, N - 1);                       
    (F, 0) -> 1                
  end, % 節胴体の式はカンマで区切る
  Fun(Fun, Number)                     
end. 
```

### Module:Name/Arity記法

`Module:Name/Arity`記法を使ってモジュールに定義された関数と同じ振る舞いをする無名関数を生成することができます。

```erlang
> MyFormat = fun io:format/2.
fun io:format/2

> MyFormat("~ts~n",["闘魂"]).
闘魂
ok
```

## Elixirにも挑戦したい

闘魂ElixirシリーズとElixir Schoolがオススメです。

https://qiita.com/torifukukaiou/items/3b65e5c04fa8c55f526e

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1
instantNeRFのevaluation

instantNeRFの推論結果についてPSNRとSSIM計算する機能の動作を確認しました。

#### run.py
parseを見ると--test_transformsを与えるとPSNRを計算するとありました。

```
	parser.add_argument("--test_transforms", default="", help="Path to a nerf style transforms json from which we will compute PSNR.")
```
216行付近が計算処理の内容でした。transform.jsonと同様に画像ファイルの名前とカメラの外部パラメータを指定するようです。
![230106_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/0c61fd9c-2022-2bc6-d847-785d65350ea8.png)

... というEllipsisオブジェクトが使用されていました。

https://qiita.com/yubessy/items/cc1ca4dbc3161f84285e

評価用の画像にalphaチャンネルがないと実行時にエラーが出ましたので、差分をとる前にalphaチャンネルを削除して回避しました。

```
				image = np.delete(image, 3, 2)		# add 230104 delete alpha 
				diffimg = np.absolute(image - ref_image)
```

#### transform.json
今回は提供されているfoxを使用しました。
ここでは0007, 0014, 0018, 0025, 0049の5枚以外を学習用としましたので、その5枚の表記部分をコメントアウトしました。

#### evaluation.json
使用するtransform.jsonを複製し、評価用の5枚の表記部分以外をコメントアウトしました。
置き場所をtransform.jsonと同じにすると処理が混ざるので、場所を別のフォルダにしました。
また評価用の画像をevaluation.jsonを置いたフォルダに作ったimagesに置きました。

![230106_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/0d7cea53-7313-3122-4fe1-b71974d3eca8.png)

#### python run.py
ここではMSAAの影響を考慮するつもりでspp=1としました。

##### 学習済みのsnapshotがない場合
このとき35000回イテレーションかけたときの評価がなされました。
ここで学習用のtransform.jsonは.\data\nerf\fox2に置きました。
またevaluation.jsonは.\data\nerf\evaluation\evaluation.jsonに置きました。
```
(ngp) PS D:\git\instant-ngpOrtho\instant-ngp> python.exe .\scripts\run.py --mode nerf --scene .\data\nerf\fox2 --test_transforms .\data\nerf\evaluation\evaluation.json --screenshot_spp 1
```

##### 学習済みのsnapshotがある場合
予めtestbed.exeで学習し保存したbase.msgpackを使用します。

```
(ngp) PS D:\git\instant-ngpOrtho\instant-ngp> python.exe .\scripts\run.py --mode nerf --load_snapshot .\data\nerf\fox2\base.msgpack --test_transforms .\data\nerf\evaluation\evaluation.json --screenshot_spp 1
```

##### 結果
各画像のPSNRとを出力するように変更しました。

```
PSNR=31.60 [min=29.08 max=33.73] SSIM=0.905
image .\data\nerf\evaluation\images/0007, PSNR=33.37 SSIM=0.929
image .\data\nerf\evaluation\images/0014, PSNR=29.08 SSIM=0.911
image .\data\nerf\evaluation\images/0018, PSNR=32.44 SSIM=0.914
image .\data\nerf\evaluation\images/0025, PSNR=33.73 SSIM=0.924
image .\data\nerf\evaluation\images/0049, PSNR=29.36 SSIM=0.845
```

それぞれの推論画像と差分画像を出力するように変更しました。
数字が比較的悪い0014と0049について確認しました。

0014のreference画像, inference画像, difference画像です。testbedで確認したところ、フローターが挟まっていたようです。
![230106_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/d0c25294-1b72-67ef-1049-61e154ba1bf9.png)

0049のreference画像, inference画像, difference画像です。毛並みの中の細かい陰が再現されていないようです。
![230106_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/f7996897-b62f-12e3-7edc-eca1745cc422.png)
enebularでnode-red その12

# 概要
enebularでnode-redやってみる。
lcdp inノードで、エラー出るので、調査してみた。

# エラーの詳細


```
SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
```
javascriptから、jsonをpostした時に、出る。

# 調査１


xhrでpost

```
var src = document.getElementById('src');
var out = document.getElementById('out');
var endpoint = "https://lcdp003.enebular.com/****/";
function run() {
	var data = JSON.parse(src.value);
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			out.value = xhr.responseText;
		}
		else
		{
			alert(xhr.readyState);
			alert(xhr.status);
		}
	};
	xhr.open("POST", endpoint, true);
	xhr.setRequestHeader('Content-Type', 'application/json');
	xhr.send(JSON.stringify(data));
}

```
エラーでる。

# 調査２

jqueryで、post

```
function put() {
	var json = {
		"text": "ok"
	};
	$.ajax({
		type: 'POST',
		url: 'https://lcdp003.enebular.com/****/',
		dataType: 'json',
		data: {
			json
		},
		success: function(data) {
			alert(data.message);
		},
		error: function(res) {
			alert("err0");
		}
	});
}
put();

```
エラー出る。

# 調査３

axiosで、post

```
let app = new Vue({
	el: '#app',
	data: {
		url: 'https://lcdp003.enebular.com/****/',
		res: '',
		name: 'aita',
		iq: '105'
	},
	methods: {
		window: onload = function() {
			app.post();
		},
		post: function() {
			let param = new URLSearchParams();
			param.append("name", app.name);
			param.append("iq", app.iq);
			axios.post(app.url, param).then(response => {
				app.res = response.data;
			}).catch(error => {
				alert(error);
			});
		},
	}
})

```

# 調査４

xhrでpost

```
var src = document.getElementById('src');
var out = document.getElementById('out');
var endpoint = "https://lcdp003.enebular.com/****/";
function run() {
	var data = JSON.parse(src.value);
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			out.value = xhr.responseText;
		}
		else
		{
			alert(xhr.readyState);
			alert(xhr.status);
		}
	};
	xhr.open("POST", endpoint, true);
	xhr.send(JSON.stringify(data));
}

```
エラーでない。

以上。
Elixirから覚えるJavaScript 〜Promise（文法遊び）〜　

僕は普段はElixirを使ってます
必要になったのでJavaScriptの勉強をはじめました
題名はElixirから覚えるJavaScriptですが、逆もできるかも？

今日はPromiseを見てみたいと思います
本来は非同期で使いますが、なんとなくElixirのパイプ風にしてみたかった
意味はあまりなく文法遊びです


お題
10を初期値
|> 結果表示
|> 10倍
|> 結果表示
|> 12足す
|> 結果表示

# Elixir

```elixir
10
|> IO.inspect()
|> then(& &1 * 10)
|> IO.inspect()
|> then(& &1 + 12)
|> IO.inspect()
```

```elixir:実行結果
10
100
112
```

# JavaScript

```javascript
const promise = new Promise((resolve, reject) => {
  resolve(10);
});

const inspect = (x) => {
  console.log(x);
  return x;
}

promise.then((x) => inspect(x)) 
.then((x) => x * 10)
.then((x) => inspect(x))
.then((x) => x + 12)
.then((x) => inspect(x));
```

```javascript:実行結果
10
100
112
```

無事に同じ結果になりました

https://qiita.com/t-yamanashi/items/263b53d889dc5f7ddf17
Googleプロジェクト管理：プロジェクト管理とは？

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/579e805c-6045-9c1c-543d-f9519b57d50c.png" width="800">

# プロジェクト管理とは？

プロジェクトには、始まりと終わりがあります。プロジェクトとは、ある結果に到達するために完了させる必要のある一連の作業です。

***<font color="MediumVioletRed">プロジェク管理とは、知識、スキル、ツール、テクニックを駆使して、プロジェクトの要求事項を満たし、望ましい結果を達成することです。</font>***

プロジェクト管理が企業にとって重要なのは、
- プロジェクトが予定通り、
- かつ予算内で、
- 期待通りの成果を出すこと

に貢献するからです。

# プロジェクトマネージャーは何をする？

プロジェクトマネージャーは通常、

- 計画と組織化
- タスク管理
- 予算とコスト管理

などを含むプロセスに従います。

 プロジェクトマネージャーは、
- プロジェクトが時間通り、予算通りに完了するよう、すべての面でサポートします。
- プロジェクトの成果が会社に価値をもたらしているかどうかを確認する必要があります。
- さまざまな方法で価値を高めることができます。
    - 例) 顧客に新しいサービスを提供する
    - 例) 既存のサービスを顧客のニーズに合わせて改良する


### 計画と組織化

- ***要求の収集:*** 例えば、チームメイトや顧客から要件を収集することが挙げられます。これは、プロジェクトが何を達成しようとしているのかを正確に把握することを意味します。キックオフミーティングを開いたり、アンケートを送ったりするかもしれません。
- ***プロジェクトプランの作成:*** プロジェクトプランの作成は、プロジェクトマネジメントの重要な部分です。プロジェクトの方向性を定め、全員のペースと足並みをそろえ、タスクを進める手助けをするのです。

### タスクの管理

プロジェクトが始まると、プロジェクトマネージャーはチームメンバーのタスクを管理し、重要なマイルストーンをより大きなチームや顧客に伝えることができます。このように、プロジェクトマネージャーはチームメンバーや顧客に対して、プロジェクトの進行状況を常に把握できるようにします。

### 予算とコストの管理

予算の管理とコストのコントロールは、プロジェクトを軌道に乗せ、予算内に収めるために、プロジェクトマネージャーが理解しなければならない共通の責任である。作成・管理した計画が変更され、予期せぬコストが発生することもあるため、これは専任の仕事となります。

:::note info
プロジェクトマネージャーの醍醐味は、プロジェクトの成長を最初から最後まで見守ることができることです。何もないところから、ゼロベースで何かを作り上げるというのは、本当に特別なことです。
:::

# プログラムマネージャーとポートフォリオマネージャーとは？

プロジェクトマネージャーとして、プロジェクトを成功させ、さらに責任ある仕事を任されるようになったら、次のステップに進むことでしょう。プロジェクトは1つのことに集中して取り組むものですが、***<font color="MediumVioletRed">プログラムはプロジェクトの集合体</font>*** です。プログラムマネージャーは、多くのプロジェクトを管理する責任を負っています。Googleでは、複数のプロジェクトを同時に管理するため、すべてのプロジェクトマネージャーをプログラムマネージャーと呼んでいます。

プログラムマネージャーとしてプログラムを成功させることで、最終的にはシニアプログラムマネージャーやポートフォリオマネージャーなど、より上級のポジションに就くことができます。***<font color="MediumVioletRed">ポートフォリオとは、組織全体にわたるプロジェクトやプログラムの集合体</font>*** のことです。ポートフォリオマネージャーは、1つのクライアントのプロジェクトやプログラムのポートフォリオを担当します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a5fc727e-5925-214d-99dc-1687d7d3dc7e.png" width="700">

- **プログラムマネージャー：**　互いに関連・類似したプロジェクトのグループを管理し、これらのプロジェクトの調整を行う。個々のプロジェクトマネージャー間の効果的なコミュニケーションを促進し、必要なサポートを提供する。また、組織の長期的な目標の作成と管理も行います。

- **ポートフォリオマネジャー：**　同じ組織内の関連するプログラム群を管理する責任者です。様々なプログラムが軌道に乗り、組織が戦略的イニシアティブを達成できるよう調整します。組織内のすべてのプロジェクトやプログラムに目を配り、必要に応じて仕事の優先順位をつけます。
AzCopy を使って Google Cloud Storage にあるオブジェクトを Azure Storage の Blob コンテナに一括でコピーしてみた

## 背景と目的

メガクラウドの一つを使っていて、会社の方針とやらで別のメガクラウドに移行しなければいけないケースに遭遇するようになってきました。その中の一つのタスクとしてオブジェクトストレージの移行は、割と多いタスクの一つなのではないかと思います。そこで今回は AzCopy を使って Google Cloud Storage にあるオブジェクトを Azure Storage の Blob コンテナに一括でコピーしてみました。

## 前提条件

- AzCopy がインストール済みであること
- Google Cloud Storage オブジェクトにアクセスできるサービスアカウントを作成しキーをローカルにダウンロード済みであること

```bash:bash
$ azcopy --version
azcopy version 10.14.0
```

## Google Cloud Storage のオブジェクト

images フォルダと test.txt があります。

![gcs2azureblob-azcopy-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/db346e09-5a6b-16a6-be2e-58452ecc6d6a.png)

images フォルダの中には sample.png があります。

![gcs2azureblob-azcopy-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/caefda93-e7b6-4734-ad0c-1b3d6e93bdde.png)

## Google Cloud Storage の認証

```bash:bash
export GOOGLE_APPLICATION_CREDENTIALS=<サービスアカウントのキー>.json
```

## AzCopy で Azure にログイン

```bash:bash
azcopy login

# 以下のメッセージが表示されます
INFO: Login succeeded.
```

## AzCopy でオブジェクトをコピー

--recursive オプション付きでやってみました。

```bash:bash
azcopy copy \
  https://storage.cloud.google.com/mnrsdev \
  https://mnrlabo.blob.core.windows.net \
  --recursive=true
```

以下のような実行結果が出力され、ファイルが 2 つコピーされたようです。

```bash:bash
INFO: Scanning...
INFO: Authenticating to destination using Azure AD
INFO: Google Cloud Storage to Azure Blob copy is currently in preview. Validate the copy operation carefully before removing your data at source.
INFO: Authenticating to source using GoogleAppCredentials
INFO: azcopy: A newer version 10.16.2 is available to download

INFO: Any empty folders will not be processed, because source and/or destination doesn't have full folder support

Job 9b8f0fc2-0924-ed4c-65a9-6068ad4e1fb2 has started
Log file is located at: /Users/testuser/.azcopy/9b8f0fc2-0924-ed4c-65a9-6068ad4e1fb2.log

0.0 %, 0 Done, 0 Failed, 2 Pending, 0 Skipped, 2 Total, 


Job 9b8f0fc2-0924-ed4c-65a9-6068ad4e1fb2 summary
Elapsed Time (Minutes): 0.0334
Number of File Transfers: 2
Number of Folder Property Transfers: 0
Total Number of Transfers: 2
Number of Transfers Completed: 2
Number of Transfers Failed: 0
Number of Transfers Skipped: 0
TotalBytesTransferred: 429
Final Job Status: Completed
```

## Azure Storage の Blob コンテナの中身

mnrsdev というコンテナが作成され images フォルダと test.txt があります。

![gcs2azureblob-azcopy-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/36dd2855-2b9f-23c2-1543-c4995224ec4a.png)

images フォルダの中には sample.png があります。

![gcs2azureblob-azcopy-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/539605a3-2912-57db-ea56-32e48cd1fa6d.png)

## 参考

https://learn.microsoft.com/ja-jp/azure/storage/common/storage-use-azcopy-google-cloud

https://learn.microsoft.com/ja-jp/azure/storage/common/storage-use-azcopy-authorize-azure-active-directory
【目の疲労】ブルーライトカット対応メガネよりも、夜間モード設定で対策

～長時間のパソコン作業による疲れ目対策の備忘録～

去年は、いろいろなパソコンの作業時間が長かった。つまり、目の疲労を一層感じた年でもあった。
眼鏡にブルーライトカット対応でもしようかと思い、ブルーライトについての検索をしたところ

「パソコン・端末の設定で夜間モードをＯＮにすれば、ブルーライトは軽減できる」

という、結論に至った。

夜間モードって、そういう機能だったのか。
家族に「パソコンの画面が黄色になって困る」という相談を受け、みてみたら夜間モードだったという件を思い出した。

夜間モードは、光の調整だけでなくブルーライトも軽減してくれる。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759593/6580b2dc-c2b9-00e1-b4b8-2847b2156799.png)


これなら、ブルーライトカット眼鏡を買ったり、ディスプレイにシートを張ったりしなくてもいいので、コスパもいい。

昼間でも夜間モードONにしておくと吉、ということでデフォルト設定にすることにした。目の疲労感が軽減できることを祈りつつ。
VideoPlayerで説明動画を埋め込む

ボタン操作を説明するのに、文字だけじゃわかりにくいなと思ったので
動画を作ったはいいものの、意外とVideoPlayerが判りづらく
忘れそうなのでメモです。

https://xr-hub.com/archives/15798

## 動画側の設定
今回は操作が判ればいいので、画質は低めで設定しました。
あとコーデックは確かＨ264が軽いとかなんとか昔勉強したことがあったので設定してみています。
（うろ覚え

![bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/dc452785-6ecd-c7cd-8115-d628f3cbdc59.png)


Transcodeはプラットフォームによって適用外となる可能性があるとのことでしたが、どうなんだろう...

https://docs.unity3d.com/ja/2021.3/Manual/VideoSources-FileCompatibility.html

ざっと読みましたが、Androidの場合、APIレベルだけ気を付ければよさそうなのでスルーします。

## Planeへの設定、呼出
PlaneにVideoPlayerのコンポーネントをつけて
ビデオを配置します。
今回は音をならさないのでAudioはNoneにしています。

![cc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/9d721de2-5fd9-7b2c-e6dc-b73dfa0a9c4f.png)

また、メッシュコライダーの削除とマテリアルの調整をしています。
マテリアルは当たり前ですが、真っ黒にすると
動画みれなくなりました....なので、デフォルトの灰色から真っ白にしています。

```cs
using UnityEngine.Video;

[SerializeField] VideoPlayer videoPlayer;

    public void ShowVideo()
    {
        videoPlayer.Play();
    }

```

Getcompornentはあまり使いたくないので直接Playしてしまいます。

![dd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/0dbb56f3-4001-7082-87e0-dd5423c3e39f.png)

あとはFungus先生に管理をお任せしてしまえば完成です。

https://twitter.com/hidaka_2022/status/1611527881611698177?s=20&t=XfXER7v9OmAHnnZyraDYmg

Planeの出し入れを忘れていましたが、とりあえずは実装できたのでよしとします...
色味がついてしまうのはシャドウとかの設定でしょうか（悩
WalletConnect Providerで、接続をキャンセルした事をキャッチする

## 問題
WalletConnectでMetamaskを立ち上げ、Metamaskから接続をキャンセルした場合に、それ以降の処理が実行されなかった。

```.ts
const provider = new WalletConnectProvider({.....省略});

// Modalを立ち上げて、Metamaskを開く
await provider.enable();
// Metamaskでキャンセルした場合、これ以降の処理が実行されない
```
エラーをキャッチできれば問題ないが、`try catch`や`enable().catch()`などを試しても、このエラーをキャッチ出来なかった。

## 解決方法

`provider.wc.on('disconnect',()=>{})`を使うことで接続のキャンセルを検知することが出来た。

```.ts
provider.wc.on('disconnect', (error, payload) => {
  if (error) {
    throw error
  }
  console.log("Cancel")
})
```

## 具体的使い方

```.ts
const provider = new WalletConnectProvider({.....省略});

provider.wc.on('disconnect', (error, payload) => {
  if (error) {
    throw error
  }
  console.log("Cancel")
  setLoading(false)
})

setLoading(true)
await provider.enable();
setLoading(false)
```

ボタンをクリックした時にボタンがローディング状態になるような場合に、`provider.wc.on('disconnect',()=>{})`を使わないと、永遠にローディング状態になってしまうが、使うことでローディングを終了することが出来る。

## 参考
https://snyk.io/advisor/npm-package/@walletconnect/web3-provider/functions/@walletconnect%2Fweb3-provider
Delta LakeにおけるZ-orderインデックスを用いたデータスキッピング

[Data skipping with Z\-order indexes for Delta Lake \| Databricks on AWS](https://docs.databricks.com/delta/data-skipping.html) [2022/10/28時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

Deltaテーブルにデータを書き込む際、データスキップに関する情報が自動的に収集されます。DatabricksにおけるDelta Lakeでは、クエリーを高速化するためにクエリー実行時にこの情報(最小値と最大値)を活用します。データスキップの設定を行う必要はありません。利用できる際には常にこの機能は有効化されます。しかし、この効果はデータのレイアウトに依存します。ベストな結果を得るには、[Z-ordering](#z-orderingとは)を適用します。

DatabricksにおけるDelta Lakeはデフォルトでは、テーブルのスキーマに定義されている最初の32カラムの統計情報を収集します。この値は[テーブルプロパティ](https://docs.databricks.com/delta/table-properties.html)の`delta.dataSkippingNumIndexedCols`で変更することができます。統計情報を収集するカラムを増やすと、ファイルに書き込む際のオーバーヘッドが増加します。

長い文字列から統計情報を収集することは高コストなオペレーションとなります。長い文字列からの統計情報の収集を避けるには、長い文字列を含むカラムを避けるようにテーブルプロパティ`delta.dataSkippingNumIndexedCols`を指定するか、`ALTER TABLE ALTER COLUMN`を用いて長い文字列のカラムを`delta.dataSkippingNumIndexedCols`より大きい場所に移動します。[ALTER TABLE](https://docs.databricks.com/sql/language-manual/sql-ref-syntax-ddl-alter-table.html)をご覧ください。

統計情報を収集するために、ネストされたカラムのフィールドは個別のカラムとみなされます。

# Z-orderingとは？

Z-orderingは、関連する情報を同じファイルセットに配置する[テクニック](https://en.wikipedia.org/wiki/Z-order_curve)です。この局所性は、自動でDatabricksのDelta Lakeによるデータスキッピングアルゴリズムによって使用されます。この挙動によって、DatabricksのDelta Lakeの読み込むデータ量を劇的に削減します。データをZ-orderするには、`ZORDER BY`句で並び替えるカラムを指定します。

```sql:SQL
OPTIMIZE events
WHERE date >= current_timestamp() - INTERVAL 1 day
ZORDER BY (eventType)
```

あるカラムが頻繁にクエリー条件に指定され、そのカラムが高いカーディナリティを持っている(すなわち、大量の固有値を持つ)のであれば`ZORDER BY`を使いましょう。

カンマ区切りで複数のカラムを`ZORDER BY`に指定することができます。しかし、カラムを追加するごとに局所性の効果は失われます。統計情報が収集されていないカラムに対するZ-orderingは効果がなく、リソースの無駄となります。これは、データスキッピングでは、min、max、countのようなカラムローカルの統計情報が必要となるためです。スキーマでカラムを再度並び替える、あるいは統計情報を収集するカラムの数を増やすことで、特定のカラムに対して統計情報を収集するように設定することができます。

:::note
**注意**
- Z-orderingは*冪等性がありません*が、インクリメントなオペレーションで使用することができます。複数回実行してもZ-orderingに要する時間が削減することは保証されません。しかし、Z-orderされたばかりのパーティションに新規データが追加されない場合、そのパーティションを再度Z-orderingしても効果はありません。
- Z-orderingはタプルの数が均等にバランスされたデータファイルを生成しようとしますが、ディスク上のデータサイズが均等になるとは限りません。これら2つの指標は多くの場合相関しますが、そうではない場合もあり最適化タスクの処理時間に偏りが生じることがあります。

    例えば、`ZORDER BY date`を行い、最新のレコードがすべて前回のZORDERのものよりも幅が広い(長い配列や文字列など)場合、`OPTIMIZE`ジョブのタスク時間や結果ファイルのサイズに偏りが生じることになります。しかし、これは`OPTIMIZE`コマンド自身のみの問題です。以降のクエリーにネガティブなインパクトを起こすことはありません。
:::


### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Databricks Account Consoleでタグベースの使用量を確認出来るようになった話

:::note
Unity CatalogのSystem Tableがリリースされた事で、[こちらの方法](https://qiita.com/maroon-db/items/b89d47009948206ac064)でも確認出来るようになりました。
:::

# はじめに

今まではワークスペース単位もしくはSKU単位でのみUI上で確認出来ましたが、期間指定やタグベースでのフィルタリングが出来なかったので、以前紹介した「[Databricksの利用料金データを使って分析してみた](https://qiita.com/maroon-db/items/a4bf8c7ba16288924640)」のように課金ログを集計して分析しておりましたが、ついにUI上でも確認出来るようになりました。

Azure Databricksでの使用料を確認する方法については[こちらをご覧ください。](https://qiita.com/maroon-db/items/c5638916a55f67968585)

# 何が出来るか？

- SKU/Workspace/タグ　ベースで表示ができる。
- フィルタリングも可能
- 表示期間を指定出来る
- 結果をCSVにダウンロード出来る
- DBUもしくは $USD で表示できる


# タグベースでの表示

タグは独自のものを付与出来ますが、デフォルトでも用意されております。Cluster単位や作成者毎などで使用量を確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/335001b1-40db-ac5f-f1df-9156cd07a2d8.png)

# 期間の指定

時間範囲も指定できます。（これは以前も出来てたと思いますが）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/8cb92507-c341-f7ed-0b61-6bdc5ba9157e.png)

# フィルタリング

特定の値をクリックすると表示のON/OFFをセット出来ます。これで特定の値のみに絞ることが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/820a89a6-a68e-8dec-4e96-1f0e93af504d.png)

# CSVダウンロード

右上にダウンロードボタンがあるので結果をダウンロード出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/ade2d904-a42a-8f2b-1083-4db96a4e1600.png)

ただし、フィルター条件は反映されないようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/97e9244d-316a-bb4e-9a72-3d6f95fa0d79.png)

# 最後に

UIで確認できる範囲がかなり拡張され運用し易くなりました。
それでも課金データは以下のように保存しておくことをお勧めします。

Databricks 利用料金データを S3に保存するように設定するには？
https://qiita.com/maroon-db/items/3b8f6216d29ce8f7baec
AI × 家畜 を調べてみた

# AI × 家畜について調べた動機
インフレ、円安による飼料の価格高騰で家畜業者が廃業の危機に追い込まれているというニュースをよくみかけます。
そもそも家畜業者は年々減っていると思われる中で、AI技術によって解決できないかと考え、既にあるAIを使った家畜向けサービスを調べてみることにしました。

# 実例：AI × 家畜
## 乳用牛
　1.　赤外線等のカメラによる行動分析/個体識別

 https://www.titech.ac.jp/public-relations/research/stories/ai-and-cattle

 https://openhub.ntt.com/project/3763.html

 https://newswitch.jp/p/24691

https://www.alic.go.jp/joho-c/joho05_002308.html

　2.　飼料成分の推定分析

https://www.agrinews.co.jp/news/index/115117

https://www.tokyo-np.co.jp/article/84222

　3.　発情期検出

https://www.nikkei.com/article/DGXZQOJC053C20V01C21A1000000/

https://www.itmedia.co.jp/news/articles/1912/02/news091.html

　4.　分娩予測/検知

https://www.jacom.or.jp/niku/news/2022/07/220705-60091.php

https://www.itmedia.co.jp/news/articles/1907/01/news114.html

https://ushi-waka.noritsu-precision.com/


## 肉用牛

　1.　発情期検出

http://www.tohoku-hightech.jp/file/seminar/kouen5.pdf

　2.　肉質評価

https://www.pref.fukushima.lg.jp/uploaded/attachment/441449.pdf

　3.　病気検知/診療費補償

https://newswitch.jp/p/24500

　4.　分娩検知

https://newswitch.jp/p/31105


## 豚

　1.　発情検知

https://www.nttdata.com/jp/ja/news/release/2022/100500/

　2.　個体識別/体重管理

https://xtrend.nikkei.com/atcl/contents/casestudy/00012/00691/

https://prtimes.jp/main/html/rd/p/000000020.000047724.html


## 鶏

　1.　個体管理

https://tohoku-hightech.jp/file/seminar/r4_220217_4.pdf

https://newswitch.jp/p/28175

　2.　死亡鶏検知

https://www.nikkei.com/article/DGXMZO31040780Y8A520C1X20000/

https://www.taihos.co.jp/img/news/20190801.pdf

https://www.maff.go.jp/j/kanbo/needs/attach/pdf/tsunagi_chicken-1.pdf

https://agrijournal.jp/renewableenergy/55474/

　3.　飼料最適化

https://soreike.jp/info/5194.html



※他参考

https://www.maff.go.jp/j/kanbo/smart/smart_agri_technology/smartagri_catalog_chikusan.html
【CpawCTF】Level 1 writeup

CTF完全初心者による記事です。備忘録を兼ねてます。
環境はmacです。
上から順にやってます。
[CpawCTF](https://ctf.cpaw.site/index.php)（サイトの読み込み遅め）

[Level 2 writeup](https://qiita.com/shuki/items/f6f11a624f843b31f0dd)

# Q1.[Misc] Test Problem

cpaw{this_is_Cpaw_CTF}とそのまま入力しSubmit

# Q6.[Crypto] Classical Cipher

**シーザー暗号 変換** とかで調べて一番上に出てきたサイトを使った。
https://dencode.com/ja/cipher/caesar
**ROT13**といってアルファベット26文字の半分をずらしたものも有名らしい。

# Q7.[Reversing] Can you execute ?
`file`コマンドを使って情報を見る。
しかし、Linux環境でないと実行できないファイルだと判明したため飛ばした。

# Q8.[Misc] Can you open this file ?
とりあえず`file`コマンドを使う。**Name of Creating Application: Microsoft Office Word**と記載されているので、Wordで開いて解決。拡張子を変える必要すらなかった。

# Q9.[Web] HTML Page
chromeの開発者ツールを使ってHTMLの中を探せば良い。cpawで検索かけたら一発だった。

# Q10.[Forensics] River
[EXIF確認君](http://exif-check.org/)などを用いても良さそうだがmacの場合はプレビューで直接確認できる。![スクリーンショット 2023-01-07 6.07.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1790537/b1acc2ad-40c6-495c-fdee-4a1422fb7f82.png)
GPSというタブに`"マップ"で表示`ボタンがあるのでそこを押せばマップが開く。
ローマ字はヘボン式であることに注意。

# Q11.[Network]pcap
Wiresharkでpcapファイルを開くと16進の機械語が見られる。その右にflagが書かれている。
![スクリーンショット 2023-01-07 6.12.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1790537/d82cf6f5-6644-8e9f-7566-25ebfa2f8961.png)

# Q12.[Crypto]HashHashHash!
**sha1 decrypt** とかでググる。一番上のサイトを使った。CTFは、英語で検索できたほうが良さそう。
https://md5decrypt.net/en/Sha1/

# Q14.[PPC]並べ替えろ!
競プロチックな問題
~~~python: example.py
a = [15, 1, 93, 52, 66, 31, 87, 0, 42, 77, 46, 24, 99, 10, 19, 36, 27, 4, 58, 76, 2, 81, 50, 102, 33, 94, 20, 14, 80, 82, 49, 41, 12, 143, 121, 7, 111, 100,
     60, 55, 108, 34, 150, 103, 109, 130, 25, 54, 57, 159, 136, 110, 3, 167, 119, 72, 18, 151, 105, 171, 160, 144, 85, 201, 193, 188, 190, 146, 210, 211, 63, 207]

a.sort(reverse=True)

print("".join([str(_) for _ in a]))
# print("".join(map(str, a))) でもいける
~~~
でOK。