OmniAICreator/Qiita-1.07M huggingface dataset:
ClickhouseとMariaDB  columnar storage engineとでベンチとってみた。

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_89992_961e5776-abbc-a12b-cfe9-9e43d6227981[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258392/29d490f1-5a35-c3b0-2562-ae401cbd9ea2.png)

# Clickhouseについて
Qiitaの先人のみなさんが多く載せていらっしゃるので割愛。
https://qiita.com/tags/clickhouse?page=1

# 簡単な経緯
社内のDWHに適用できるDBMSを探索中、下記サイトに目が留まる。
https://www.predictiveanalyticstoday.com/top-wide-columnar-store-databases/
**無料**の記載に食いついて試してみることに。
検証にお金もかけれないのでローカル環境（Docker）で作成し、ムフッ♪っとなり。
日本ではまだ黎明期のようなので参考になればと思いこちらへ掲載。

**お世話になったサイト様**
Docker yandex/clickhouse-server
https://hub.docker.com/r/yandex/clickhouse-server/

@n-gondo123 のClickHouseの使い方とパーティションの話
https://qiita.com/n-gondo123/items/e7a29926b5a777998f08

@tomo0 のClickHouseとは【2020年3月最新】【サンプルあり】
https://qiita.com/tomo0/items/b730f479ba1b2c534f1a

# ベンチ環境

**筐体**
WindowsPC: i5-6200U(2.3GHz)/16GB/SSD(Somsung 860 EVO)
※こんなに非力な環境でベンチとれるのか？と思いながらも…

**各Dockerイメージ**
Clickhouse : v20.3.5.21-stable
MariaDB : 10.5

**検証データ**
50,000,000件(RawDataで5.1Gb)

| Column           |Column Count|
|:-----------------|------------------:|
|Total   |130|
|Date    |  1|
|String  | 39|
|Decimal | 90|

**手段**
検証データを各DBに投入後、DberverからJDBC接続をして検証。
下記、各クエリを5回実施し、その平均値で比較。
Query1：Count(*)
Query2：年、月の項目でGruopByしDecimal列を9列でSum
Query3：年、月に加え、＋6項目でGruopByしDecimal列を9列でSum

#ベンチ結果
###データ圧縮率
5.1GbのRawDataを格納した場合の各DBの利用Diskspaceを比較。
噂通りの高圧縮を叩き出してくれました。
運用の際についてまわるDiskの増設計画で頭痛くならなそう。
一方でMariaDBはRDBMSの利便性を残したまま、columnar storage engineを共存させている為、
その分、Disk spaceを使用している結果になった印象。
![Data_Size_2_patterns.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258392/b4531d46-ceaf-1c30-4cba-9b9360ad79a7.jpeg)

###処理速度
こちらもClickhouseが圧倒的に良い結果になりました。
Count(*)は体感ではさして違いはないですが、GroupBYで項目が増加するほど違いが顕著になりました。
![Performance_2_patterns.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258392/ec392daa-41cf-d3f6-5864-db3f4d46a8da.jpeg)

##所感
先人の皆様や、Official Siteも仰るとおり、データの圧縮率、検索速度ともに非常に高い製品であることが確認できました。
DWHに向かない理由jOINが1つしかできないことがよく登場していますが、BI/BA用のStore先としては優秀という印象でした。
DWHは「Master/Transactionが別々にあり、Joinして使う物」なのでそちらには適さないですが、
「分析の目的に併せてMaster/Transactionを非正規化したデータ」を処理する環境としてはありという判断です。
これはDWHを「データを収集、蓄積する層」と「分析する為のデータ配置する層」の2層に分けて使うやり方で、後者の層を指しています。
Swift:絵文字を備忘録

#Swiftでの絵文字のエンコード

```swift
func make() {
        input = textField.text!
        
        for i in input.unicodeScalars {
             var code = i
            print(code.value)
            
            if code != nil {
                textLabel.text = String(code)
            }
        }
```

絵文字から復帰するコード

```swift
     //unicodeから絵文字に変換
    func change() {
        var input = 128557
        
        var scalarView = String.UnicodeScalarView()
        
        scalarView.append(UnicodeScalar(input)!)
        
        textLabel.text = String(scalarView)
        
        print(scalarView)
        
    }
```
オンラインイベント時代の名刺交換と辞書の使い方

#楽するためのユーザー辞書が好き
正直ユーザー辞書とショートカットキーの使いこなしかたで、その人のPCのスキルがわかると思っている@nattokinです。

普段よく使う単語や文章などはどんどん登録しておくと便利です。
ユーザ辞書は使い方次第で普段の仕事の効率がグッと変わります。
一般的な辞書の使い方については、@ryoichi_obara さんの記事が非常に参考になるので、まだ使っていないという方は、まずはこちらを参考にしてみてください。
https://qiita.com/ryoichi_obara/items/f67d66e2e274ebf5e99e

オンラインの名刺交換時代の今、自分のLinkedInやEightのプロフィールURLも単語登録しておくと非常に便利です。
ECやイベントの申し込みフォームも毎回入力するのだるいですよね。そして会社の住所や代表電話番号など数知れず覚えきれない。長くて打つ気も起きないというのが本音です。

なので、私の辞書には「まい・・・」という単語を追加しています。

```
まいじゅうしょ：　会社の住所
まいでんわ：　会社の電話番号
まいけいたい：　会社の携帯電話番号
まいかいしゃ：　会社名
まいぶしょ：　部署名
まいやくしょく：　役職名
まいえいと： EightのプロフィールURL
まいりんく： LinkedInのプロフィールURL
まいちず：　会社のGoogle MapのURL

```

##辞書の登録方法
Windows, Mac公式のサイトを参考にしていみてください。
[Windows IMEの場合](https://support.microsoft.com/ja-jp/help/4462244/microsoft-ime)
[Windows IME一括登録方法] (https://support.microsoft.com/ja-jp/help/881925)
[Macのユーザー辞書を登録する] (https://support.apple.com/ja-jp/guide/japanese-input-method/jpim10228/mac)
[Google IMEの辞書を登録する] (https://support.google.com/ime/japanese/answer/166765?hl=ja)



#EightのプロフィールURLの調べ方
![eight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563351/5932d490-2143-6582-4e17-f79763ca61e6.png)

[良い公式ブログ](https://blog.8card.net/2020/03/03/advancedtips-vol32/?fbclid=IwAR35zgoehmsImRwlnu0pSC9xF29NPhWunbMwkC83LmgQPgje0LE7-amL-7U)があったのでこちらに紹介譲ります。

#これで準備はととった
あとはオンラインイベントに参加して、チャットで自分の名刺を"まいえいと"（変換）してhttps://8card.net/p/xxxxxxxxxxx　を一発で呼び出してスマートに名刺交換しましょう。

#面白そうなイベントに参加してみる
それ以外にもたくさんあるので、仕事仲間や友人と企画したイベントやConnpass, TechPlayでも面白いオンライン交流会があるので、参加しています。

Eightにもコミュニティというのがあり、Eightをたくさんつかっていると招待が送られてくるらしいです。

オンラインイベント時代の名刺交換方法いかがでしたでしょうか？　仕事も効率化しつつEightやLinkedInで繋がる世界は、ますます広がっていきそうです。Eightコミュニティでは新しい時代の名刺交換方法を模索するイベントがあり、そちらでお会いできることを楽しみにしています。

もっと良い方法あったらぜひコメントください。
では！
【C#】IEnumerable<IMyInterface<任意の型>> の実装方法

記事のタイトルどう書けばいいか悩みました。どういう状況かイメージしにくいと思います。下記「やりたいこと」をご参照ください。
いろいろ試行錯誤しているうちに、まあまあベターなやり方じゃないかなと思う方法に行き当たったので記しておきます。
より良い方法があればご教授いただけると幸いです。

## やりたいこと

ジェネリクスをとるインターフェースがあったとします

```cs
interface MyInterface<T> {
  T Value { get; set; }
  string GetValueAsString();
}
```

`<T>`の型に制約はないため、好きな型をとることができます。

```cs
class MyObjectClass : MyInterface<object> {
  public object Value { get; set; }
  public string GetValueAsString() => Value.ToString();
}

class MyDateTimeClass : MyInterface<DateTime> {
  public DateTime Value { get; set; }
  public string GetValueAsString() => Value.ToString("yyyy/MM/dd");
}
```

ここで、`MyInterface<T>` の一覧が欲しくなったとします。`<T>` の型は問いません。

```cs
var list = new List<MyInterface</* ? */>>();
```

ところが、この変数の型の定義でつまづきます。

```cs
var list = new List<MyInterface<object>>(); // あらゆる型はobjectの派生系だからこれでいいでしょと思っても…

list.Add(new MyIntClass()); // コンパイルエラー！！
list.Add(new MyObjectClass()); // これは通る。つまり T はobjectの派生型では駄目で、本当にobject型でなければならない
```

さあどうしたものかというのがここでの課題です。

## 限定的な状況下で使える正しい解決法

`<T>`が引数または戻り値のいずれか**のみ**に使われている場合、`in T` や `out T` という定義方法が可能です（詳細は「C# ジェネリック 共変 反変」で調べてみてください…）

しかし、この方法は上記の例では使えません。in, out どちらも使われる変数には

```cs
// T を in T にしてみる
interface MyInterface<in T> {
  T Value { get; set; } // 戻り値(プロパティのgetter)にも T 型が使われているため、コンパイルエラー
  string GetValueAsString();
}

// T を out T にしてみる
interface MyInterface<out T> {
  T Value { get; set; } // 引数(プロパティのsetter)にも T 型が使われているため、コンパイルエラー
  string GetValueAsString();
}

// in, out の併用は不可
interface MyInterface<in out T> { // こんな書き方はできない
  T Value { get; set; }
  string GetValueAsString();
}
```

## 結論
上記の例でもジェネリクスを使うにはどうしたらいいかと試行錯誤した結果**「インターフェースのうちジェネリクスに関係ないメンバーだけ抽出し、ジェネリクスなしのインターフェースを別途定義する」**のがベターかなと感じました。

```cs
// ジェネリクスに関係ないメンバーのみのインターフェース
interface MyInterface {
  string GetValueAsString();
}

// ジェネリクスに関係あるメンバー（ジェネリクスなしの方を継承する）
interface MyInterface<T> : MyInterface {
  T Value { get; set; }
}
```

すると最初の例の`list`はこのようになります。

```cs
// ジェネリクスなしの方のインターフェースで型引数をとる
var list = new List<MyInterface>();

list.Add(new MyIntClass()); // OK!
list.Add(new MyObjectClass()); // OK!

// 型引数なしの方で定義されたメンバーのみ参照可能
list.ForEach(item => Console.WriteLine(item.GetValueAsString()));
```

より良い方法があればご教授いただけると幸いです。
PHPのよく使う書き方・文法集(基礎編)

# 背景
PHPを使うための必須基礎知識をまとめてみました。

## よく使う文法
・PHPの書き方のルール
~の中に記述する。

```php5

<?php ~ ?>
```

・コメントアウト
//を最初につける。

```php5

// コメントアウト
```

・出力の仕方
echo “文字列”or 値;

```php
echo “name”;
```

・変数の定義の仕方
$変数名=値;

```php
$name="tanaka";
```

・文字列等の連結
“文字列”.”文字列”のようにドット(.)で連結する。

```php
"tanaka"."様"
```

・変数展開
文字列の中に変数を使用したいときに、”{$変数名}”と書く。

```php
"${name}です"
```

・if文
条件分岐をしたい時

```php

if (条件式){
    処理;
}
else{
    処理;
}
```

・switch文
ループ文の実装がしたい時

```php
switch(変数名){
    case 値:
        処理;
        break;
    default:
        処理;
        break;
}
```

・配列の作成方法
$配列名=array()

```php
$name = array("tanaka","sato")
```

・連想配列の作成方法
$連想配列名 = array(キー=>バリュー)

```php
$friend = array(name => "tanaka")
```

・for文
繰り返しの処理の回数があらかじめ決まっているループ文の実装

```php

for(変数の定義;条件式;変数の更新){
    繰り返し処理;
}
```

・while文
何回繰り返し処理すれば良いかわからない。特定の条件の間のみ実施したいループ文

```php

$変数名=値;
while(条件式){
    繰り返し処理;
    変数の更新;
}
```

・foreach文
配列＋繰り返し(for)文のような文法

```php

foreach(配列名 as 変数名){
    繰り返し処理;
}
```

・関数の作り方(メソッド)

```php

function 関数名(){
    処理;
}
```

・クラスの作り方

```php

class クラス名(大文字で始める){
    処理;
}
```

・インスタンスの作り方

```php

$変数名=new クラス名();
```

・プロパティの作り方
※インスタンス->プロパティでアクセス。

```php

public $変数名
```

・メソッドの作り方
※インスタンス->メソッド名()でアクセス。

```php

public function メソッド名(){
    処理;
}
```

・＄this
メソッド内で擬似変数$thisを定義できる。

```php

$this->変数名
```

・コンストラクタの作り方

```php

public function __construct(){
    処理;
}
```

・ファイルの継承方法
require_once(‘ファイル名’)で他ファイルで使用できる。

```php

require_once(‘ファイル名’)
```

・クラスの継承方法

```php

require_once(‘ファイル名’)

class 子クラス名 extends 親クラス名{

}

```
VM環境用自宅サーバーの構築

仮想マシンやコンテナを使って実験できるように、まずはサーバーを作るところから始める。


#環境
##ハードウェア（Intel ベアボーンサーバー）
- CPU: Core i3
- RAM: 32GB
- Disk: SSD 500GB (PCIe3.0 NVMe) + SSD 1TB (SATA)

PCIe3.0の高速ディスクを、ホストのOSとゲストVMディスクを置く場所とする。
SATAの中速ディスクを、その他（nfsのデータファイル保存領域、OSインストールのISO等）の大きなファイルを置く場所とする。2TBの容量のディスクを用意しているのは、データベースのデータ領域としても運用したいため。

##ソフトウェア
- OS: CentOS 8
- VM: KVM + QEMU + oVirt


KVM + QEMUを使う理由は、VMのテンプレート機能を使いたいため。

このマシンで最初は無料版ESXiを動かしていたが、新たにVMを作るたびに、OSのインストールから始めないといけないのが面倒になった。
最初はそんなものかと思っていたが、UdemyのハンズオンコースでVirtualBoxを使いテンプレートから何度も操作環境を作った際に、便利さに気付いてしまった。

KVMの運用管理にoVirtを使うのは、最初は慣れるまでGUIベースで操作するため。ゆくゆくはCLIベースで操作し、devOpsな方向まで持っていきたい。

#OSセットアップ
CentOSは、特にkickstart等でカスタマイズ版インストーラーを作らない限り、GUIベースの操作となる。（それがVMテンプレート無しだと面倒な理由の一つでもある。）
一般的な操作については、さまざまなページでまとめられている。その中でも、このHacker's Highさんのページ（[画像で分かる！CentOS 8 のインストール方法](https://hackers-high.com/linux/centos8-installation/)）が一番わかりやすいと思われる。

で、私が行ったインストールで、よくあるまとめと違う点は、下記の2点：
##ソフトウェアの選択
最小限（Minimal）でインストールする例が多いが、私の場合は仮想マシンの実験環境として作る事を目的としているので、仮想化ホストを選択。
##ストレージの設定
せっかく高速なPCIe3.0のSSDと中速なSATA SSDの2本の構成にしてあるので、高速アクセスのメリットを活かしたいので、自動を選ばず下記のように設定した。
####PCIe3.0 SSDを選択
/boot　
/
swap
####SATA SSDを選択
/var  

2TBもvarに用意するが、nfsのファイル保存領域やVMのISO格納領域として使ったら、意外と早く空きがなくなるかも。
なぜ/varという名前にしたかというと、2TBもあるが、[Linuxの標準的なディレクトリ構成](https://ja.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)的に適切そうな名前を考えたら、/varかなと。
/dataも考えたけど、oVirtで仮想マシンのディスクを格納する領域をData Domainという名前で呼ぶので、それを/dataとして速いPCIe3.0 SSDに用意したかったから。

で、まずはOSのインストールは問題なく完了。
Docker+PostgreSQLで立ち上げたDBにPosticoでアクセスする

# はじめに
前回記事でRails＋PostgreSQL＋docker-composeででローカル環境構築を行いました。

前回記事-> https://qiita.com/Rick516/items/c9e829f48f3ee0be26df

今回は前回記事で立ち上げたDBにPosticoというツールで操作できるようにしたいと思います。

# 環境
- macOS Catalina 10.15.4
- ruby 2.6.3
- rails 2.5.3
- docker for mac 2.2.0.4
- PostgreSQL 12.2

# Posticoとは？

Posticoは簡単にいうとPostgreSQLをGUIで直感的に操作できるツールです。

ぽちぽち入力していくだけでデータを追加できたり、コピーできたり、書き換えられたりできるので最高に便利です。

インストールはこちら -> https://eggerapps.at/postico/

今回は前回記事(https://qiita.com/Rick516/items/c9e829f48f3ee0be26df)で立ち上げたDBを題材とします。

# 前回立ち上げたDB

前回docker-composeでDBの設定を行いました。

振り返ってみたいと思います。

```:docker-compose.yml
version: '3'
services:
  postgres:
    image: postgres
    ports:
      - "5432:5432"
    volumes:
      - ./tmp/db:/var/lib/postgresql/data #MacOSの場合
    environment:
      POSTGRES_USER: 'admin'
      POSTGRES_PASSWORD: 'admin-pass'
      POSTGRES_HOST: 'postgres'
      POSTGRES_PORT: 5432
    restart: always
  web:
    build: .
    image: rails
    container_name: 'web'
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    ports:
      - "3000:3000"
    environment:
      VIRTUAL_PORT: 3000
    volumes:
      - .:/app
    depends_on:
      - postgres
    restart: always

```


```:./config/database.yml
...
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: admin #追加
  password: admin-pass #追加
  host: postgres #追加
...
```

これらの情報を元にDBが立ち上がっているわけですね。

# Posticoでアクセスしてみる

Posticoでアクセスを試みます。

が、なぜか素直に入力するとアクセスできません。

<img width="405" alt="Screen Shot 2020-04-20 at 18.30.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520769/d9f1b77f-c4fb-6fb6-07b0-e277337379b0.png">

ここでは、docker-compose.ymlとdatabase.ymlで指定したHostである```postgres```でアクセスしようとするとなぜかエラーが出ます。
<img width="406" alt="Screen Shot 2020-04-20 at 18.33.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520769/8f93d4c9-89d4-b27e-4007-878cc75f52d4.png">

そこで、下記のようにHost名を```localhost```にしてアクセスしてみます。

<img width="649" alt="Screen Shot 2020-04-20 at 18.06.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520769/2ce4e657-4952-8816-0ea7-4463029c3f2e.png">

すると、アクセスできました！！！

この理由についてはもっと勉強して判明すれば追記したいと思います。

理由がわかる方はご教示いただければ幸いです。

<img width="943" alt="Screen Shot 2020-04-20 at 18.35.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520769/bc5decf6-3b13-deb4-8de0-fadcde6950bf.png">

操作方法については、@junara様のこの記事がとてもわかりやすいです。

https://qiita.com/junara/items/8ee572151727288f6576

今回はここまでにしたいと思います。

ここまでくれば、サクサクローカル開発を進めることができますね。

頑張ります。

# 参考記事
- https://qiita.com/junara/items/8ee572151727288f6576
- http://uozias.hatenablog.com/entry/2016/08/15/OSX%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8Bpostgresql%E3%81%AEGUI%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88
- https://eggerapps.at/postico/
LaravelでAmazon SESを使ってメール送信してみました

#Amazon SESとは
SES（Simple Email Service）
AWSが提供するメール送受信に特化したサービスです。
本来メール送信するには、サーバーにSMTPサーバー（Postfixとか）を設置して、迷惑メールにならないようにSPFやDKIMなどセキリュティ面も考慮して構築しなければいけません。
SESならAWSマネジメントコンソール上で簡単にメール送信することができます。

#前提
- DNSはRoute 53を使用しています。
- メール送信機能はLaravelで作成してます。

#構築

###リージョンを選択
東京リージョンはサービス提供していないのでバージニアリージョンを選択します。

###テスト用メールアドレスを登録
[Email Addresses]を選択し、受信可能なメールアドレスを登録します。
登録したメールアドレス宛に検証メールが届くので、開いてリンクをクリックします。
クリックすることで承認されて、テスト用メールアドレスの登録完了です。

#テストメール送信
現段階では登録したメールアドレスしか送信できない制限がかかっているので
from と to に検証したメールアドレスを指定し、メールが届くことを確認します。

#ドメインを登録する
[Dmaions]を選択し、[verify a New Domain]から登録します。

####SPF設定
TXTレコードが生成される。
Route 53の場合のみ[Use Route 53]ボタンを押すと自動的に登録されます。

####DKIM設定
CNAMEレコードが生成される。
Route 53の場合のみ[Use Route 53]ボタンを押すと自動的に登録されます。

#SMTP設定
[SMTP Settings]から[Create My SMTP Credentials]を選択します。
そのまま作成ボタン押すことでSMTP専用のIAMが作られます。
その設定をLaravelの.envファイルに書き込みます。


```:.env
MAIL_MAILER=smtp
MAIL_HOST=email-smtp.us-east-1.amazonaws.com
MAIL_PORT=587
MAIL_USERNAME=****************
MAIL_PASSWORD=***************************
MAIL_ENCRYPTION=TLS

```

Laravelのメール設定で送信先メールアドレスと受信先メールアドレスに先程登録したメールアドレスまたはドメインのものをセットすれば送信できます。

#SES送信制限の解除申請
解除しなければ、登録したメールアドレスまたはドメインしか使用できません。
任意の項目が多いが空欄で申請すると受理されないのでなるべく埋めてください。
（受理されるまで１営業日ほどかかります。）
受理されると存在するメールアドレスなら何でも送信できます。


#バウンス率に注意する
バウンスとは - 送信したメールメッセージが何等かの理由で目的の送信先に正常に配信されなかったことです。
バウンス率が10%以上になるとAmazon SESサービスが利用できなくなります。
ユーザーの入力したメールアドレスを送信メールアドレスに使用する場合は、ある程度のバリデーションを用意し、存在しないメールアドレスに送信しないような実装が必要です。


#確認
メール送信後、受信したメールのメールヘッダを確認することでSPF、DKIMが適用されているか確認できます。
音声ファイルの動画化(GoogleDrive向け)

COVID-19対応でオンラインコンテンツをガシガシ作っている中，細かいですがGoogleDriveで音声ファイルを配信する際の問題対応策のひとつです．

## ◆音声をダウンロード禁止にできないGoogleDrive

GoogleDriveでは動画と音声では扱いが異なるようだ．

* 音声ファイルをアップてストリーミング再生させる際，共有設定を**「ダウンロード禁止」**ににすると再生できない．
  - ※プレビュー再生しようとすると「再生できません」と叱られる．↓は一例

![再生エラー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441159/bbc2e327-9c87-e690-5cc0-bfd04d36b6d1.png)

* 一方，動画ではダウンロード禁止にした上でストリーム再生ができる．

ので，音声をダウンロードさせたくない場合，対策としては**「音声ファイルを動画化する」**のが手っ取り早いと思う．

動画を作るとなると面倒のように思うが，いまは変換サイトがあるのでそれを利用すればいい．

が，ここで引っかかるのが，GoogleDriveでの動画の条件．それは，

### 「背景情報つきの動画」

だ．こうでないと，ファイルをアップした後，G.Drvがストリーム用の処理をしてくれず，プレビュー再生できない．

しかし，多くの変換サイトでは，mp3を純粋(?)にmp4等に変換するだけなので，背景画像をつけない．そのためにサイズもほとんど変わらないというメリットがあるが，どうやらGoogleDriveは背景情報のない動画は動画とみなさないようだ．

まあ，「動画は画があるのが当然」と考えれば納得できなくもない．

>※豆知識：GoogleDriveでは，動画をアップしたらしばらく時間を経て，そのファイルのアイコンがサムネイル化される．それが出たら再生可能の合図．出なかったら再生できない．

**白でも黒でもいいから静止画を1枚つけて動画作成．**

これがGoogldDriveで音声をストリーミング配信するコツというわけだ．

で，画像つき動画の簡単な方法は，やっぱりweb変換サイトを使う．例えばここ．

* [Make a One Image Music Video](https://www.oneimagevideo.com/)

![MakeaOneImageMusicVideo](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441159/7d21790e-9f9a-9a66-fb6b-c60d637ac308.png)

ここでは，画像1枚と音ファイルを指定すれば，その画像だけの動画を作ってくれる．すごく便利．

## ◆Window Movie Makerも手軽
※Webではなく，オフラインでやりたい方は，動画作成ソフトを使うことになります．Windows標準では「フォト」アプリが簡単な動画作成に対応しています．
が，私はWindows8までの「Windows Movie Maker」が簡単でいいなと思います．
Movie MakerはMicrosoftの無償アプリですが，Window8以降は標準でついてこないので，探し出してダウンロードする必要があります．

※普通に検査してでてくる「Windows Movie Maker」はニセモノです．
本物はMicrosoftのサイトで検索するしかありません．
　　※このメモの前のバージョンまではニセモノを提示していました．m(_ _)m

いずれにせよ，やることは，
　1. 画像を取り込んで
　2. 音ファイルを挿入し
　3. 映像の長さを音の長さに合わせ
　4. できたら保存．画面サイズはどうせ画面はみせないので，小さくてもいいです(「電子メール」サイズが一番小さいです)

以上です．

![WindowMovieMakerを使う](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441159/6553b115-64ca-3b3a-1d97-a09c428f6d53.png)


**「GoogleDrive向けに音声ファイルを動画化するなら画像を1枚いれてね」**
というお話でした．
Markdownでスライドを速攻作成するスニペット

1. Markdownでメモを取る
2. メモの先頭に下記のスニペットを貼る
3. メモのファイル拡張子をhtmlにする
4. ブラウザでhtmlファイルを開く

```html
<!DOCTYPE html><meta charset="utf-8"><title>x</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.6.0/css/reveal.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.6.0/css/theme/solarized.min.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.8.2/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.6.0/js/reveal.min.js"></script>
<script>onload=function(){b=document.body;s='section>';a='<'+s;e='</'+s;c='<div class="';
d='</div>';m=b.innerHTML.replace(/\n\s*\n\s*\n/gm,'<<>>').replace(/<<>>/gm,'\n\n'+e+a+'\n\n');
h=c+'reveal">'+c+'slides">'+a+marked(m)+e+d+d;b.innerHTML=h.replace(/<a /g,'<a target="_blank" ');
Reveal.initialize();document.title=/([^>]*?)<\/h1>/m.exec(h)[1];}</script>
```

なお、ページ区切りは水平方向のみ対応。
2連続の空行でページ区切りになる。
【超簡単】firebaseを使ってWebアプリケーションをインターネットに公開する

firebaseのHosting機能を利用して、アプリケーションをインターネットに公開する方法を記載します。

ここでは、ターミナルを使ってアプリをデプロイする手順を記載します。
前提として、作成したアプリはVue.jsを使っており、Firebaseプロジェクトは既に作成済みとします。

それでは、手順を記載していきます。

1. firebase-toolsのインストール
---

まず最初に、firebase-toolsをインストールします。
firebase-toolsをインストールすることで、firebaseプロジェクトの管理、表示、デプロイを可能にします。

```terminal
npm install -g firebase-tools
```

2.firebaseにログイン
---
firebaseプロジェクトを扱うため、firebaseにログインが必要です。

```terminal
firebase login
```

3.プロジェクトの設定
---

ここでホスティングの設定を行います。

```terminal
firebase init
```

コマンド実行後に出てくる最初の選択肢は、十字キーで移動ができます。
そして、スペースボタンを押すことで選択をすることができます。
エンターボタンで決定です。
複数選択肢がありますが、ここではHostingを選択しましょう。

```terminal
○Hosting: Configure and deploy Firebase Hosting sites
○他の選択肢
・・・
```
次に公開ディレクトリを聞かれます。
ここでは、distと回答しましょう。
その後、シングルアプリケーションの設定をするか聞かれるので、yと回答します。

```terminal
? What do you want to use as your public directory? (public) dist
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) y 
```
これで設定が完了です。

4.アプリのビルド
---

この記事では、Vue.jsでアプリを作成しています。
このアプリをビルドすれば、先ほど設定したdistディレクトリに、コンパイルされたファイルが置かれます。

```terminal
npm run build
```
5.firebaseにデプロイする
---

先ほど作成したアプリをインタネット上に公開するため、デプロイを行います。
デプロイが成功すると、Hosting URLと記載した場所にアプリが公開されます。

```terminal
firebase deploy
...

Hosting URL:https://□□□□□□□□□□□□
```

6.まとめ
---

このようにfirebaseは、簡単にアプリをインタネット上に公開できます。
フリープランでは、コンテンツのサイズなどに制限があることに注意してください。
[Laravel] オフラインでjQueryを使う

# Laravelでの開発 "オフライン"でjQueryを使いたい!

### STEP 1： npmでjQueryをインストール

ターミナルにて、プロジェクトディレクトリに移動し、下記のコマンドを実行する。

```terminal:terminal　プロジェクトディレクトリ
$ npm install jquery
```

### STEP ２： コンパイル

コードエディタに戻り、プロジェクトのファイル**package.json**を開いてみよう。
"devDependencies"配下に "jquery": "^3.5.0"が入っているのが確認できます。

```php:package.json
"devDependencies": {
        "axios": "^0.19",
        "bootstrap": "^4.4.1",
        "cross-env": "^7.0",
        "jquery": "^3.5.0",
        "laravel-mix": "^5.0.1",
        "lodash": "^4.17.13",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.1",
        "sass": "^1.20.1",
        "sass-loader": "^8.0.0",
        "vue": "^2.5.17",
        "vue-template-compiler": "^2.6.10"
    }
```

再び、ターミナルに移動します。下記のコマンドを実行して、コンパイル（一つのファイルを形成）します。

```terminal:terminal　プロジェクトディレクトリ
npm run dev
```

### STEP ３： viewファイル（XXXX.blade.php)での呼び出し

jQueryを使いたいviewファイルを開き、app.jsファイルを呼び出します。

```php：XXXX.blade.php
<body>
　　　<script src="/js/app.js"></script>
</body>
</html>
```

### 以上の３ステップで終了です。
【Pega Platform】temporary caseの利用

## はじめに

BPM製品である[Pega Platform](https://www.pega.com/ja/products/pega-platform)で、「temporary case」について記載します。

なお、この記事では、Pega Platform バージョン8.2.2を利用しています。

## temporary caseとは

ケースデータは通常、Pegaデータベースに保存されます。
ケースを新規作成した時点でケースIDが採番され、ルーティングが可能となります。

一方、以下の例のような場面で、「temporary case」を利用すると、ストレージ容量の節約ができます。

- ユーザが画面入力した情報が妥当である場合のみケースデータを保存する
- ユーザにケース起票に関する留意事項を表示し、同意する場合のみケースデータを永続化する
- ユーザが画面入力した情報によって、別ケースタイプのデータを作成する

「temporary case」の特徴は以下の通りです。

- データは、クリップボード上に保持される
- データは、Pegaデータベースには保持されない(一時保存不可。Auditにも残らない。)
- ケースIDは採番されない
- データを永続化するためには、「Persist Case」シェイプを利用する

## temporary caseを利用した際の挙動

実装例：

- 「Apply Infomation」ステップで、ユーザが画面に値を入力
- 「Persist Case?」ステップで、画面内容が妥当であればケースデータを永続化する
<img width="561" alt="スクリーンショット 2020-04-20 16.31.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546125/d02c7e4b-693b-f653-b2a3-b2de6644d9d1.png">

挙動例：

- ケースを新規作成する。ケースIDが採番されていないことがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546125/6aa979af-e4ff-a171-d053-5598a4edf9d6.png)

- クリップボードにて、「pyWorkPage」にケースのプロパティが存在することがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546125/aa631907-fa6d-2429-f328-5f67fd1e2872.png)

- 画面のSubmitボタンを押下し、フローを先に進める。「Persist Case」ステップ実行によりケースデータが永続化され、ケースIDが採番されていることがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546125/f39193f9-54f8-862b-dc05-33126d13b137.png)


## temporary caseの設定手順

Case TypeエディタのSettingsタブを開き、以下の項目にチェックを入れます。

- 「Create temporary case that is not saved until a 'Persist case' step is reached」![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546125/d7e2abae-858b-d34c-e0e2-18ce68986aa0.png)

なお、「pyStartCase」のProcessタブ-Case creation settingsでも同じ設定が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546125/f6d71d04-dba3-1e05-ed24-b9be544062e3.png)


データを永続化する場合は、ステップに「Persist Case」シェイプを設定します（キャプチャは前章をご参照ください）。

## おわりに

前述の通り、「temporary case」の設定自体は簡単にできます。
実装するケースタイプの特性に合わせて利用してみてください。
PHPで末尾の「ー（伸ばし棒）」が文字化けした話

##はじめに
このページをご覧ということは、PHPの文字化けにハマってる方かもしれません。
私もハマりましたので、解決策をメモしておきます。
PHPは色んな原因で文字化けするみたいで、調べるだけでも一苦労ですよね。


さて先日、お客様先に、作ったアプリを納品しました。
私は現地に行かず、別の人間が現地に行き、アプリをリリースしてもらいました。

LAMP環境構築にあたり、
インターネットで外に出られない環境だったりで、すったもんだあったそうですが、
大きな問題はなく、無事に作業を終えたようです。

で、その時に聞いた環境が以下の通りでした。

###環境
・RedHutLinux Enterprise 7.7
・Apache2.4.6
・PHP 5.7
・MariaDB 5.6


##お客様から連絡！　「文字化けしますね」
そんでもってある日、メールを開くと、
「先日のアプリですが、一部文字化けが発生します」とのこと！

状況を聞くと、
DBから値を取得して、テキストボックスに表示する値が、
「ユーザー」などの末尾の伸ばし棒が文字化けするとのこと。

でも、検証環境では一向に再現しないので、どうしたもんかなーと思ってました。
（そもそも検証環境はRedHutLinuxはなく、CentOSやubuntuしかないので、完全な再現が不可だったんですね）



###調査
「php 文字化け 原因」などで検索しても、それっぽい情報は一切出ない。。

頑張って実機を動かして調査を進めると、
どうやら、**mb_ereg_replace**関数を使用している部分が怪しそう。

Google先生に聞いてみると、**mb_ereg_replace関数使用での文字化けが発生することがある**ことがわかりました！
・参考URL
http://fanblogs.jp/itblogger/archive/14/0

なるほど、つまり、文字コードの設定が原因で文字化けが発生することがあるそう。

作ったアプリはUTF-8で動くことを想定していました。
試しに、mb_ereg_replace関数を使用する直前で以下の記述を追加。

```
mb_regex_encoding( "EUC-JP" );
```
すると。

・
・
・
**文字化けが発生しました！**
**事象の再現ができました！**
<img width="729" alt="スクリーンショット 2020-04-20 17.20.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167745/95eb6e28-e947-b274-97e0-0573b9c2191e.png">
こんな感じで文字化けします。
皆さんも、文字化けの内容が同一なら、これが原因かもしれません。


##文字化けの原因と対策
つまり、現地で設定したPHPは、**EUC-JP**がデフォルトの文字コードであることが考えられます。
こちらの検証環境では、**UTF-8**がデフォルトの文字コードです。

ということで、どうやって現場でのPHPのデフォルト文字コードをUTF-8にしようかと調べたところ。
php.iniで設定ができるみたいですね。

お客様にご連絡して、現場サーバのphp.iniに、以下の2行を追加してもらいました。

```
default_charset = "UTF-8"
mbstring.internal_encoding = UTF-8
```

apacheを再起動して、現場でも文字化けがなくなったとのこと。
**めでたしめでたし！！**

ただ、以下のサイトを確認すると、このように記載がありました。
[mb_regex_encodingのマニュアル](https://www.php.net/manual/ja/function.mb-regex-encoding.php)
「5.6.0　　　デフォルトのエンコーディングが EUC-JP から UTF-8 に変わりました。」

現場、PHP5.7て聞いたんですけどね??
そんなこともあるのかー、と思った春の出来事でした。

~~セキュリティ的にphp5.7でいいのか?とも思ってるんですが、向こうが用意した環境なので、目を瞑ることにしました。。~~
[React]パスパラメータを使ってページ遷移した際、リロードしたときにパスで困った場合

##環境
node：v8.11.3

## 起こったこと
例えば、パスパラメータを使って何かのページを表示する際、URLが
http://localhost:5000/user_detail/hoge
だとしたら、これをリロードすると、画像などのパスはホームディレクトリのpubフォルダにあるのに、
http://localhost:5000/user_detail/pub/hoge.png
みたいになってしまって画像が見つからない状態になってしまった。

ウーン...ウーン...ファ！？ウーン...

##解決方法
index.htmlにbaseタグを追加する
baseタグとは、「相対パスの基準URIを指定する」ものです。
これを、index.htmlに追記したら改善された。

```javascript:anime-suko.js
<base href="/" />

```


## 感想
baseタグなんて知らんかったわw
いいもの知ったw
plunkerでd3 その7

#概要

plunkerでd3やってみた。
感染者数 予測API、読んでみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5d668c68-ad9d-bdd3-ea2b-9c414c3e215c.png)

#サンプルコード


```

var url = "https://covid19-japan-web-api.now.sh/api/v1/total?predict=true";

d3.json(url, function(data) {
  var values = [];
  for (var i = 0; i < data.length; i++)
  {
    values.push({
      x: i,
      //x: data[i]["date"],
      y: data[i]["positive"],
      z: data[i]["death"]
    });
  }
  const spec = {
    '$schema': 'https://vega.github.io/schema/vega-lite/v2.json',
    'width': 300,
    'height': 300,
    'data': {
      'values': values
    },
    'layer': [{
      'mark': 'point',
      'encoding': {
        'x': {
          'field': 'x', 
          'type': 'quantitative'
        },
        'y': {
          'field': 'y', 
          'type': 'quantitative'
        }
      }
    }, {
      'mark': 'line',
      'encoding': {
        'x': {
          'field': 'x', 
          'type': 'quantitative'
        },
        'y': {
          'field': 'z', 
          'type': 'quantitative'
        },
        'color': {
          'value': 'tomato'
        }
      }
    }]
  };
  vegaEmbed('#vis', spec);
});




```

#成果物

https://embed.plnkr.co/plunk/FraF3VjVEiGeqAkd

以上。
眺めて覚える C# Xamarin　(6) 音声合成

#早い話がAndroidにしゃべらすプログラムです。
##なるべくちょいちょいとやるためには、Nugetでプラグインをインストールします。
#Step1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/27bf828e-c058-2f5c-2a61-c1a5249e8d4e.png)
#Step2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/9b8a593f-3dc1-46e2-1aa1-09237ad908d2.png)
#Step3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/7b6bf33b-ab16-c7a3-02ce-01b75b5c489d.png)
#Step4
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/2590e1fb-a848-4904-7a4d-94d415a8bae4.png)
#Step5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/9136673c-c241-8b17-c876-4dd87262abc3.png)
##nugetの追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/5acdcef5-f82b-aabc-7382-d509ce9e5ede.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/5d8d139c-06df-d5d8-d95d-14d6296837c4.png)
**Xam.Plugins.TextToSpeechの導入**

```MainPage.xaml.cs
using Plugin.TextToSpeech; //プラグインの導入
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Text2Speech
{

    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            //ボタンの定義
            var btn = new Button() { Text = "話す",FontSize=48 };
            btn.Clicked += Btn_Clicked;
            Content = btn;
        }
        /// <summary>
        /// ボタンクリック時の動作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_Clicked(object sender, EventArgs e)
        {
            //喋らせる
            CrossTextToSpeech.Current.Speak("ソシアル ディスタンス。\n2メートル以上離れてください。\nソシアル ディスタンス。\n2メートル以上離れてください。\n");
        }
    }
}
```

##実行結果

後からエレベータに駆け込んだお兄さんがおりた!
homebrew-cask から Java8 をインストールする

## 問題点

下記の記事を参考にインストールを試みたが、単純には入らなかった。

[homebrew-caskでJava8をインストールする - Qiita](https://qiita.com/d_forest/items/290bb05bb929e5d74647)

```zsh:zsh
% brew cask install adoptopenjdk8
Error: Cask 'adoptopenjdk8' is unavailable: No Cask with this name exists.
```

調べてみると、 homebrew から Java8 をインストールする方法は最近色々と変遷があったらしい。

[HomeBrew で AdoptOpenJDK をインストールしてみた（訂正版） - Qiita](https://qiita.com/gishi_yama/items/9cdb3d95ee7f25b8018f)

## 解決方法

adoptopenjdk のリポジトリの手順に従ってインストールした所上手くいった。

https://github.com/AdoptOpenJDK/homebrew-openjdk

```zsh:zsh
brew tap AdoptOpenJDK/openjdk
brew cask install adoptopenjdk8
```
Django3.x + heroku + cloudinaryを使用する方法

# 背景
* Djangoをherokuにデプロイするにあたり、画像データを保存するにはS3とcloudinaryが知られている。
* cloudinaryを簡単に扱うには、`django-cloudinary-storage`がよく利用されているが、django2.x系のみ対応

# 概要
* Django3.x系を使うには、[dj3-cloudinary-storage](https://github.com/tiagocordeiro/dj3-cloudinary-storage)を使ってみよう。
    * `django-cloudinary-storage`のソースのままでほぼ使用可能

# 動作確認
* <font color="green">動作確認OK

```django:blog.html
<a href="{% url 'blog:post_detail' post.id %}">
     <img class="card-img-top" src="{{ post.image.url }}" alt="{{ post.title }}">
</a>
```

* <font color="red">画像表示されず</font>

```django:blog.html
<a href="{% url 'blog:post_detail' post.id %}">
     <img class="card-img-top" src="{{ test_model_instance.image.url }}" alt="{{ test_model_instance.image.name }}">
</a>
```
Android 11 Labs Day 1 メモ書き

[Android 11 Labs](https://developersonair.withgoogle.com/events/android11labsjp) の Day 1 で気になったところだけメモ。
（Day 2 は[こちら](https://qiita.com/koichi-ozaki/items/98176da5b2eaeaec0d8d)）

# はじめに
  - 2020年02月に Developer Preview 開始
  - 3月、4月も Developer Preview、5月に Beta版 Pixcel にインストール可能
  - 7月 - 9月 に正式版リリース予定、たぶん9月ごろかなあ
  - 正式版用意できたら Pixel にはすぐ配信される

# パーミッションについての開発者向け最新技術情報
  - 位置情報、マイク、カメラのパーミッション取得に「今回だけ許可する」Only this timeが追加される
  - コード上は許可は許可だけど、ストレージに「許可済」とかいうのを保持して実装したりしてたらおかしくなるかもね
  - なぜパーミッションの取得をしようとしているのか、説明しようね
  - 一度拒否されたかどうか判定できる shouldShowRequestPermissionRationale()
  - 位置情報
    - フォアグラウンド、バックグラウンドでそれぞれパーミッションが分かれる（10 では任意だったけど 11 から必須）
    - フォアグラウンドのパーミッションがないとバックグラウンドのパーミッションは取れない
    - バックグラウンドのパーミッションは OS の設定画面でおこなうようになる
    - 同時に取得できない
  - パーミッション取得のダイアログの表示回数に制限（2回）があって、何回も許可ダイアログだせなくなる

# 端末上の他のアプリの情報取得の制限について
  - getPackageManager().getInstalledPackages() のことについてはなす
  - 端末内にインストールされているアプリ一覧の取得に一部制限がかかる
  - manifest に記載されている条件に一致するアプリだけ取得できるようになる
  - 現状のコードを壊さないようにしてくれているらしい
  - アプリのアプリケーションID（自分のアプリ以外）を指定すると Exception がでる（コードこんな感じ getPackageInfo("another.app", 0)）
  - manifest に \<queries\> が書ける
    - getPackage したいアプリケーションID を書く
    - intent-filter を指定することもできる
  - QUERY_ALL_PACKAGES というパーミッションを取得すれば、今までどおりすべてのアプリ情報が取得できる

# MACアドレス取得制限、System Alert Window 利用制限などについて
  - mac アドレスの取得ができなくなる
  - ネットワークインターフェイスのリスト取得では IPv4 のみが返されるようになる
  - NETWORK_ROUTE の bind() というメソッドは呼び出せなくなるので ConnectionManager のやつを使ってね

# Q&A
  - Android 10 から 11 にアップグレードした場合、既に許可済みのパーミッションはリセットされるのか
    - 再度要求されることはない
    - 実際に試した方がいいかもね
  - Only this time で許可された場合、プロセスが生きてる限り有効なのか
    - そういうわけじゃない
    - アプリがフォアグラウンドにある状態なら許可状態
    - ただしバックグラウンドにいった瞬間に破棄されるわけではなく、いくらかの猶予期間がある
  - パーミッション取得ダイアログの表示回数制限はいつリセットされるのか
    - リセットされない
  - 位置情報パーミッション取得のとき「利用中のみ許可」はアプリがバックグラウンドにいくと取得できなくなるのか（カーナビアプリで位置情報つかってて音楽アプリを起動したとき）
    - アプリから起動するサービスがフォアグラウンドサービスなら、フォアグラウンドのパーミッションが許可されていればOK
    - アプリがバックグラウンドにいってもサービスは動いているから大丈夫らしい
  - 「今回だけ許可する」は、位置情報、マイク、カメラのみなのか
    - そうです
  - Bluetooth LE スキャンにも位置情報パーミッションの「今回だけ許可」とかバックグラウンドパーミッションは影響するか
    - しないはず
  - 許可されたパーミッションが「今回だけ許可」で許可されたのかどうか判定する方法はあるか
    - ない
  - パーミッションダイアログの表示制限を超えたとき、ユーザーが許可するにはどうすればいいのか
    - OS のアプリの設定から許可してもらうしかなさそう
  - パーミッションダイアログの「今後表示しない」はなくなるか
    - まだわからない
  - MACアドレス取得は端末をユニークに特定するために利用しているが、そのような目的の API は用意されているか
    - ある
    - Advertising ID（ユーザーがリセットできちゃうけどね）
  - パーミッションダイアログの表示制限はインストールスコープでしょうか
    - そうです
  - カメラ撮影で位置情報が許可されていないと GPS メタデータは付与されない
    - そうです
  - パーミッションまわりの変更でコードの変更する必要があるか
    - 基本的にはないけどちゃんとなぜパーミッション取得しようとしてるのかとか説明してね
  - パーミッションダイアログのメッセージを変更できるようにしたい
    - 似たようなものはたぶん作れるから（チュートリアルとか）がんばって
    - 自由に変更できちゃうとユーザーが「このダイアログをアプリが出してるのか OS が出してるのか」判断できなくなっちゃうからなあ
Spring Cloud ConfigのEmbedding the Config Server

Spring Cloud Configは基本的にはserverとclientに分かれて使うもの（と思う）が、組み込みモードで起動することも出来る。

リファレンス的には[Spring Cloud Config - Embedding the Config Server](https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.2.RELEASE/reference/html/#_serving_plain_text)のあたり。

# ソースコード

```gradle:build.gradle
plugins {
  id 'org.springframework.boot' version '2.2.6.RELEASE'
  id 'io.spring.dependency-management' version '1.0.9.RELEASE'
  id 'java'
}

sourceCompatibility = '11'
repositories {
  mavenCentral()
}
ext {
  set('springCloudVersion', "Hoxton.SR3")
}
dependencies {
  implementation 'org.springframework.cloud:spring-cloud-config-server'
  implementation 'org.springframework.boot:spring-boot-starter-web'

  testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
  }
}
dependencyManagement {
  imports {
    mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
  }
}
test {
  useJUnitPlatform()
}
```

依存性としてはserver側だけで良い。上は動作確認用にwebも入れている。

```yaml:/src/main/resources/bootstrap.yaml
spring:
  application:
    name: sample
  profiles:
    active: composite
  cloud:
    config:
      server:
        composite:
          - type: native
            search-locations: file:///C:/configtest/
        bootstrap: true
      prefix: config
```

<code>appplication.yaml</code><b><font color="red">ではなく</font></b>```bootstrap.yaml```に設定を記述する。

以下は動作確認用のcontroller。

```java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@EnableConfigServer
@SpringBootApplication
@RestController
public class Application {
	@Value("${hoge.message}")
	private String message;

	@RequestMapping("/")
	public String home() {
		return "Hello World!" + message;
	}

	public static void main(String[] args) {
		new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);
	}
}
```
Nature Remo Cloud APIで400 Bad Requestが出る件

通常、Nature APIで照明をオンにするには以下のようにPOSTする。

```sh
curl -X POST 'https://api.nature.global/1/appliances/{applianceID}/light' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Authorization: Bearer {TOKEN}' \
-d 'button=on'
```

これをPythonで実行しようとした場合、`urllib.error.HTTPError: HTTP Error 400: Bad Request`というエラーが出た。

```python
from urllib.request import *
import json

token = 'XXXXXX'
headers = {
    'accept': 'application/json',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Bearer {}'.format(token),
}
data = json.dumps({"button":"on"}).encode()
url = 'https://api.nature.global/1/appliances/902dee41-491c-4588-ba15-966e99c46c4b/light'

req = Request(url=url, data=data, headers=headers, method='POST')

with urlopen(req) as res:
    body = res.read().decode()
    print(body)
```

# 解決策

HTTPレスポンスの400とは、パラメーターに不正がある場合に生じる。
curlでは正常に動作したので、データの部分をJSON形式ではなく、クエリ文字列で指定したところ、うまく動作した。

```python
data = b'button=on'
```

Nature APIのサーバー側がJSONに対応していないのか？
深層学習／MobileNet

#1.はじめに
　今回は、 スマホなどの容量が少ない小型端末にCNNを載せるために開発された MobileNet についてまとめます。

#2.MobileNet.V1
![スクリーンショット 2020-04-20 16.29.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/824f2dc2-afed-16fc-e40e-5e80b3d85ef2.png)

　通常の**Convolution**の模式図です。$(h,w,C_i)\to(h,w,C_o)$となるstride1のk×k Convolutionを考えると、パラメータ数は $hw*C_i*k^2*C_o$が必要となります。

![スクリーンショット 2020-04-20 16.36.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/6c83e6dc-387d-f7ee-e014-1d01ecce472e.png)

　**Depthhwise Separable Convolution** の模式図です。通常のConvolutionは空間方向とチャンネル方向の畳み込みを同時に行いますが、このモデルは空間方向の畳み込み(Depthwise Conv)を行なってから、チャンネル方向の畳み込み(Pointwise Conv)を行うという様に２段階で行います。これによって、パラメータ数は、$\frac{k^2+C_o}{k^2*C_o}=\frac{1}{k^2}+\frac{1}{C_o}$に減らすことが出来ます。

#3.MobileNet.V2
　**MobileNet.V2**は、**Inverted Residual**というResNetで使われるResidual Blockを応用したブロックを持っているのが特徴です。Residual Blockは入力からチャネル方向に注目すると、広い -> 狭い -> 広いという構造(Bottleneck構造)になってますが、Inverted Residualでは狭い -> 広い -> 狭いとしています。

![スクリーンショット 2020-04-20 17.02.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/a06e279e-4d6b-385a-b4b2-7035951fb9c5.png)


　3×3Depthwise Conv.を1x1Conv.(Pointwise Conv.)で挟む構造です。この構成によってパラメータを増加させる最大要因である**出力チャンネル数**を大幅に減らすことができます。

　出力チャネル数を大幅に減らすことは、その分情報量を十分に抽出できなく精度が出なくなってしまうのですが、Inverted Residual Blockの中で**チャネル数を一旦増やして畳み込みを行いチャンネル数を戻す**ことで解決しています。

#4.MobileNetのV1とV2の比較
![スクリーンショット 2020-04-20 17.08.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/0194d449-1591-6159-3b5a-bc762a32c5d5.png)
　V2の方がV1より圧倒的に少ないチャンネル数で成立していることが分かります。
2020年のソフトウェア開発企業トップ5

1. High-Tech Systems & Software
ソフトウェアソリューションの開発と実装、およびハードウェアインフラストラクチャの提供の経験を持つチームで、HTSSが提供するソリューションは、ERP（エンタープライズリソースプランニング）、WMS（倉庫管理システム）、BI（ビジネスインテリジェンス）などのアプリケーションと、さまざまな分野向けに開発され、独自のブランドDataKlasに統合された独自のアプリケーションスイート。パフォーマンスは私たちの活動の決定的な要素であり、製品の品質と多くの機能を保証します。 DataKlasソリューションは、ビジネスを実行および開発するための基本的なツールとして設計されています。この会社は、会社ごとに手順や作業システムが異なることを知っています。そのため、DataKlas製品では、ビジネス管理に適した独自のソリューションパッケージを自由に作成できます。会社の優先事項は、クライアントの目標を達成し、コストを削減し、提供されるサービスの品質を継続的に改善することです。スペシャリストは常に一歩先を行き、市場のトレンドに素早く適応します。同社は現場で最新のテクノロジーを使用しており、ソリューションとサービスを理解して適切に使用するためにクライアントに永続的な支援を提供しています。
2. Flat Rock Technology
Flat Rock Technologyは、10年以上の専門的な経験を持つ信頼できるソフトウェア開発会社です。 企業の分野における豊富な専門知識により、あらゆる規模と業種の企業と長期的なパートナーシップを構築する機会が得られます。 Flat Rock Technologyは、すべての企業には異なるニーズがあることを理解しており、最適なオプションをご案内します。

会社のクライアントは、製造、保険、運輸、人事、小売などにまたがっています。140人を超える多様な専門家が強力な技術的スキルとビジネス知識を持ち、あらゆる規模と複雑さのソフトウェアプロジェクトを効果的に処理できます。
3. S-PRO
S-PROは、分析とコンサルティングから配信と立ち上げまで、カスタム開発ソリューションを提供します。 同社は、企業や新興企業の技術パートナーとして機能し、製品開発を担当しています。

S-PROの主な事実：
– 5年間のエンドツーエンドの開発経験。
– 150人以上の専任の社内専門家。
–世界27か国の顧客。
– 90以上のITソリューションが提供されます。

チームのメンバーは毎年、最新のテクノロジーに関する新しい専門知識を身に付けています。 この利点により、一歩先を行くことができます。 常に。

会社のチームメンバーは社内従業員です。 彼らは第三者にプロジェクトを外部委託しません。 S-PROには2段階の開発アプローチがあり、プロジェクトの見積もりを提供できます。

チームは、製品成果物の予算とタイムラインの両方の責任を負うことができます。 彼らは顧客にこだわることに誇りを持っています。

S-PROは、製品が完全かつ予定どおりに納品されることを保証します。会社は、テクノロジーおよびそれ以降の生涯にわたるパートナーです。
4. Pagination
2009年以降のページネーションは、カタログと価格表作成ソフトウェアの開発に完全に焦点を当てています。 ページネーションは、ヨーロッパで最も輸出志向の高い地域の1つであるイタリアのヴェネト地方に設立されました。 ここでは、中規模および大規模企業のコミュニケーションプロジェクトのグローバリゼーションを支援するソフトウェアとベストプラクティスの要求が常に強くなっています。 この要求により、ページネーションは今日、ビジネスデータドライバードキュメントの発行における世界のリーダーになりました。 ページネーションは、世界中のあらゆる業界の顧客が、オンプレミスとサービスの両方で、カタログ作成および価格表ソフトウェアのシステムを調整するのに役立ちます。

今日、ドキュメントの情報のほとんどはスプレッドシート、データベース、またはその他のビジネスアプリケーションからのものであり、この情報は成長し、変化し続けています。 この環境では、マーケティング担当者とデザイナーは、この情報を迅速かつ正確に公開するための柔軟なツールを必要としています。
5. Lvivity
Lvivityは、ソフトウェア開発、モバイルアプリ、ウェブポータル、サービスを専門とするウクライナのIT企業です。 同社は、自社の強みと発売される製品の品質に自信を持っているため、複雑なプロジェクトに対処する準備ができています。

Lvivityは、世界中のIT企業に完全に管理可能なオフショア専用開発チームサービスを提供し、ビジネスインテリジェンス、ヘルスケア、教育を含む幅広い業界にカスタムソフトウェア開発サービスを提供します。

ビジネスの規模に関係なく、彼らはあなたのタスクに最適なソリューションを提供し、目標の達成を支援する準備ができています。

こちらにベトナム オフショア記事のソースをご参照ください: https://bap-software.net/knowledge/vietnam-offshore/
Azure DevOps Pipelines で使用可能な変数

# はじめに

[Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/) を利用する時はかなり使うことが多いと思われる変数を紹介したいと思います。

- [Build.SourcesDirectory (Build.Repository.LocalPath)](#buildsourcesdirectory-buildrepositorylocalpath)
- [Build.BinariesDirectory](#buildbinariesdirectory)
- [Build.StagingDirectory (Build.ArtifactStagingDirectory)](#buildstagingdirectory-buildartifactstagingdirectory)

ちなみに Microsoft の公式サイトは以下です。
[Use predefined variables](https://docs.microsoft.com/ja-jp/azure/devops/pipelines/build/variables?view=azure-devops&viewFallbackFrom=azdevops&tabs=yaml)

## 注意点
事前に覚えておいてほしいことは、この後に紹介する Build.～ で取得可能なパスは**全て絶対パス**です。

##Build.SourcesDirectory (Build.Repository.LocalPath)

ソースコードが配置されるディレクトリパスを指します。
『**リポジトリをクローンしてきた時のルートディレクトリ**』になります。

Build.SourcesDirectory も Build.Repository.LocalPath も同じパスを指します。
(※Build.Repository にはリポジトリに関する他の情報が含まれています)

Unity プロジェクトをリポジトリにそのまま配置した場合、Assets などが配置される所です。

```
例)
/- Unity プロジェクトルートディレクトリ
 |- Assets
 |- Packages
 |- ProjectSettings
```

リポジトリ直下に Unity などのプロジェクトを配置していない場合でも、この変数にサブディレクトリのパスを書けばいいだけです。

```
$(Build.SourcesDirectory)/Sources
```

##Build.BinariesDirectory

ビルド後の結果が出力されるディレクトリを指します。
Unity の場合、バッチビルド内で出力先を指定しますので、これを使って出力先を決定すれば良いと思います。
([Unity Tools for Azure DevOps](https://qiita.com/akiojin/items/cf85eee9ddd11780e209) でも outputPath にこいつを指定)

```yml
- task: UnityBuildTask@3
  displayName: 'Building.'
  inputs:
    buildTarget: '$(Unity.TargetBuild)'
    unityProjectPath: '$(Unity.ProjectPath)'
    outputPath: '$(Build.BinariesDirectory)'
```

※実際にビルドの出力先にこれを利用しなくても問題はないのですが、Pipelines で用意されているものですので便利に使えればそれでいいんじゃないかと思います。

##Build.StagingDirectory (Build.ArtifactStagingDirectory)

ビルドパイプラインで成果物を最終的に出力する先です。
Publish build artifacts で成果物として公開されます。

```yml
- task: CopyFiles@2
  displayName: 'Copying builds...'
  condition: succeeded()
  inputs:
    SourceFolder: '$(Build.BinariesDirectory)'
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)'
    CleanTargetFolder: true
    OverWrite: true

- task: PublishBuildArtifacts@1
  displayName: 'Publish builds...'
  condition: succeeded()
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'Release'
    publishLocation: 'Container'
```

※これも Build.BinariesDirectory と同じでここじゃなくてもいいです。

# おわりに

結構使えそうな変数は他にも色々あるのですが、ビルドするだけであればこの辺りの変数さえ知っておけば問題なく [Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/) 用の YAML はかけるんじゃないと思います。
SSHでSequelpro接続時にパーミッションエラーが出る


Sequelproの接続エラーの詳細を見るとこのエラーが出てる。
<img width="567" alt="スクリーンショット 2020-02-21 18.54.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534114/88975a96-6b10-b198-b697-47c790a5bf61.png">


どのディレクトリでもOKなので、下記のコマンドでパーミッションの変更を実行する。

```
chmod 600 【SSH鍵】.pem
```

参考
https://yuichon.com/2013/04/privatekey-permissions/
Docker-compose run web rails c 日本語が表示できない件について

##参考記事
https://qiita.com/yuudevelop/items/9818e43145223a077997

```
Docker-compose run web rails c
```


Docker環境でrailsを扱うことに慣れるため復習しているとコンソールで日本語が表示できない。

文字化けならびにエンターを押すと入力されないという悲劇。

まだプログラミングに不慣れ（もはや1年経とうとしているのに…）なので心臓が止まりそうになる。

のだが、少しは成長したのか息をするかの如くググれた。

https://yatta47.hateblo.jp/entry/2016/10/15/114701

↑これも試したりしたけど本質は最初の記事です。

Dockerfileに追加

コンソールの日本語化できなくて困ったので追加

ENV LANG C.UTF-8

これが正義。
【Python】2つ以上の複数ファイルを同時にopenする方法

Pythonで2つ以上の複数ファイルを同時にopenしたい場合があると思います。
例えば、あるファイルを読み込んで何かしらの処理をし、結果を別のファイルに書き込むというような場合です。

素直にプログラムを書くと、

``` python
with open('./output.txt', mode='w') as fw:
    with open('./input.txt', mode='r') as fi:
        for line in fi:
            i = int(line.strip())
            i += 1 # 1を足すだけの処理
            fw.write(str(i) + '\n')
```

となると思います。

`input.txt`が

```
1
2
3
```

だとすると、`output.txt`は

```
2
3
4
```

となります。

ただ、前記のプログラムは`with`句が入れ子になっており、インデントが深くなりスマートではありません。
実はこのプログラム、次のように`with`句を一つにまとめて書くことができます。

``` python
with open('./input.txt', mode='r') as fi, open('./output.txt', mode='w') as fw:
    for line in fi:
        i = int(line.strip())
        i += 1 # 1を足すだけの処理
        fw.write(str(i) + '\n')
```

インデントも浅くなり少し（？）スマートになったと思います。
【JS】指定行数を越えたら全文が表示されるボタンをつける

JSで指定した行数を越えたら、全文を表示するボタンを出す処理を作っていきたいと思います。

## 指定した行の高さにするには
例えば、5行分の高さにしたくて `height: 5rem;` にしても、5行にはうまいことなりません。行の高さは**`font-size`と`line-height`から計算される**ためです。

## 対処法
そこで今回はCSSの`line-height`の値を取得し、`font-size`と掛け合わせ実際の行の高さを求めます。

注意点としては、JSで取得できる`line-height`は**ピクセルで返ってくる**ので注意が必要です。

[デモ](https://codepen.io/mtoutside/pen/oNjzbyN)

```html
<div class="wrapper">
  <p class="text">
    1行目<br>
    2行目<br>
    3行目<br>
    4行目<br>
    5行目<br>
    6行目<br>
  </p>
  <div class="more-button">More</div>  
</div>
```

```style.scss
.wrapper {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

}
.text {
  font-size: 18px;
  line-height: 1.8;
  overflow: hidden;
  
  // 全行表示
  &.is-open {
    height: 100% !important;
  }
}

.more-button {
  background-color: #666;
  width: 100px;
  padding: 15px 0;
  border-radius: 4px;
  line-height: 16px;
  text-align: center;
  font-size: 16px;
  color: #fff;
}
```

```script.js
const textContents = document.querySelector('.text');
const moreButton = document.querySelector('.more-button');

// テキスト要素の高さを取得
const textHeight = textContents.clientHeight;
// テキスト要素のline-heightを取得
let lineHeight = getComputedStyle(textContents).getPropertyValue('line-height');
// [32.4px]のようなピクセル値が返ってくるので、数字だけにする
lineHeight = lineHeight.replace(/[^-\d\.]/g, '');

// メニューが6行以上だったら高さを5行にする
if(textHeight > lineHeight * 5) {
  textContents.style.height = `${lineHeight * 5}px`;
} else {
  // メニューが5行以下ならMoreボタン非表示
  moreButton.style.display = 'none';
}

// Moreボタンを押したら、テキスト要素のis-openクラスを切り替え
moreButton.addEventListener('click', () => {
  textContents.classList.toggle('is-open');
});

```

Moreボタンを押すと全行が表示されます。また5行以下だとMoreボタンは表示されません。

**参考**
[テキストエリアの高さを行数で指定する本当に正しい方法](https://pisuke-code.com/css-set-textarea-row-num/)
RailsへのBootstrap導入手順について

# 背景
Bootstrapをよく使うため、備忘録として書き残しておこうと思った。

## 手順
1.Gemfileに必要なgemを追加してbundle installを実行する。

```ruby

gem 'bootstrap', '~> 4.4.1'
gem 'jquery-rails'
```
```ruby
$ bundle install
```

2.app/assets/stylesheets/appcation.cssの拡張子を.scssに直し以下を記述する。
（既存の記述は消して良い）

```ruby
　@import "bootstrap-sprockets";
　@import "bootstrap";
```

3.app/assets/javascript/appcation.jsの中の、「//= require~」と書いてる部分の以下を追記する。

```javascript


(中略)
//
//= require rails-ujs
//= require activestorage
//= require turbolinks

//以下3行を追記する。

//= require jquery3
//= require popper
//= require bootstrap-sprockets

//一番下にこのコードが来るようにする
//= require_tree .
```

これで導入完了したはずです。
正しく導入されているか一度確認してみましょう❗️

## 参考サイト
https://github.com/twbs/bootstrap-rubygem
AtCoderで使える！Pythonで短くコードを描くテクニック集！

##はじめに
この記事はAtCoder灰色の初心者がまとめたメモ書き程度のものです。あまり参考にできないこともあるかもしれません。ごめんなさい。

これらのコードはすべてAtCoder上のPython3(3.4.3)および新ジャッジ版Python(3.8.2)で動作することを確認しています。

また、この記事ではコードは以下のように記載しています。

```python
#入力
#コード
#出力
```

また、基本的には、コードを短く書くということは、可読性を低くし、読む人に誤解を与えやすく、**<font color="red">推奨されていない</font>**ことであることに注意してください。

なので基本的には読みやすいコードを書くことをお勧めします。Python で全言語 Shortest Code やPython 内 Shortest Code を目指したい!!という人にはこの記事はおすすめかもしれません。

#1.0 入力基本操作
###1.1 よく使われる関数
######eval()
文字列を実行してくれる関数です。[](～などで活用できるかもしれません)

```python
# 1 + 2
a = input()
print(eval(a))
# 3
```

######replace()
第一関数の文字列を第二引数の文字列に置き換えてくれます。
以下の例では空白を"2"という文字列に置き換えています。

```python
# 1 3 4
a = input()
print(a.replace('4','5'))
# 1 3 5
```

また、前述のeval()関数と組み合わせてこのようなことができます。

```python
# 10 3
print(eval(input().replace(' ','-'))) #10-3を実行してくれる
# 7
```
[](～などで活用できるかもしれません)

###1.2 よく使われる演算子
#####+=,-=などの代入演算子
みなさんおなじみの代入演算子ですね！！このようなものはコードが短くなるうえに処理が速くなるのでおすすめです！！

```python
# 45
a = int(input())
a = a + 5
print(a)
# 50
```
上のコードは下のコードと全く同じことをしています。

```python
# 45
a = int(input())
a += 5
print(a)
# 50
```

#####~- や -~
~はビットを反転させるビット演算子です。一般的に整数をビット反転させると、その数を負にして-1した数になることが知られています。たとえば、以下の例では、

```python
a = 9
print(~a)
# -10
```
という風に負にして-1の数が出力されました。これについてもっと詳しく知りたい方は「2の補数」でググってみましょう！！

それを生かして、a-1やa+1をより短いコードで書くことができます。ただし、注意点としては、先ほどの代入演算子とは異なり、変数自体は変化しないということです。

```python
a = 9
print(~-a)
print(-~a)
print(a)
# 8
# 10
# 9
```
ちなみに、実行順序はこの通りです。

```python
a = 9
print(~(-a))
print(-(~a))
# 8
# 10
```
###1.3 その他のテクニック
######変数に関数を代入
Pythonでは変数に関数を代入することができます。こうするとよく使う長い名前の関数をdefを用いずにより短く使うことができます。

```python
p = print
p(3)
# 3
```

#####boolを整数として使う
基本的にPythonではそのような場所でFalse=0,True=1にコンパイラくんが読み替えてくれます。
なので以下のような事もすることができます。

```python
mylist = [0,3,5,4]
print(mylist[True])#mylist[1]を出力している
print(mylist[False])#mylist[0]を出力している
# 3
# 0
```

#2.0 出力基本操作
###listの出力
Pythonでは通常はlistを出力しちゃうと、カンマやかっこがついてしまうのでそのままでは出力ができません。なので以下のような工夫をする必要があります。
#####アスタリスクを使う方法
listの前にアスタリスクを付けるときれいに出力できます。また、簡潔に書くことができます。

```python
mylist = ['Alice','Bob',,4]
print(mylist)
print(*mylist)#きれいにできた
# [0, 3, 5, 4]
# 0 3 5 4
```



#10.0 さいごに
実はこの記事、僕の初記事です＞＜
まだまだQiitaに慣れていないところもあると思います。なので誤字脱字、見にくいところ、わかりにくいことがあったら、どんどんコメントしていってください。また、新たにさまざまなコードやテクニックを追加するかもしれません。さいごに、この記事を読んでくださってありがとうございました！