OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】NavigationBarのタイトルをカスタマイズ

SwiftでNavigationBarのタイトルをカスタマイズする方法。

## 実際のコード

```swift
//タイトルの文言
self.title = "タイトル"
self.navigationController?.navigationBar.titleTextAttributes = [
    //タイトルの文字色
    NSAttributedString.Key.foregroundColor: UIColor.white
    //タイトルのフォントと文字サイズ
    NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 30)
]
```
今回は文字色とフォント・文字サイズについて触れましたが、他にも種類はたくさんあります。

> static let attachment: NSAttributedString.Key
The attachment for the text.

>static let backgroundColor: NSAttributedString.Key
The color of the background behind the text.

>static let baselineOffset: NSAttributedString.Key
The vertical offset for the position of the text.

>static let cursor: NSAttributedString.Key
The cursor object.

>static let expansion: NSAttributedString.Key
The expansion factor of the text.

>static let font: NSAttributedString.Key
The font of the text.

>static let foregroundColor: NSAttributedString.Key
The color of the text.

>static let glyphInfo: NSAttributedString.Key
The name of a glyph info object.

>static let kern: NSAttributedString.Key
The kerning of the text.
>static let ligature: NSAttributedString.Key
The ligature of the text.

>static let link: NSAttributedString.Key
The link for the text.

>static let markedClauseSegment: NSAttributedString.Key
The index of the marked clause segment.

>static let obliqueness: NSAttributedString.Key
The obliqueness of the text.

>static let paragraphStyle: NSAttributedString.Key
The paragraph style of the text.

>static let shadow: NSAttributedString.Key
The shadow of the text.

>static let spellingState: NSAttributedString.Key
The spelling state of the text.

>static let strikethroughColor: NSAttributedString.Key
The color of the strikethrough.

>static let strikethroughStyle: NSAttributedString.Key
The strikethrough style of the text.

>static let strokeColor: NSAttributedString.Key
The color of the stroke.

>static let strokeWidth: NSAttributedString.Key
The width of the stroke.

>static let superscript: NSAttributedString.Key
The superscript of the text.

>static let textAlternatives: NSAttributedString.Key
The alternatives for the text.

>static let textEffect: NSAttributedString.Key
The text effect.

>static let toolTip: NSAttributedString.Key
The tooltip text.

>static let underlineColor: NSAttributedString.Key
The color of the underline.

>static let underlineStyle: NSAttributedString.Key
The underline style of the text.

>static let verticalGlyphForm: NSAttributedString.Key
The vertical glyph form of the text.

>static let writingDirection: NSAttributedString.Key
The writing direction of the text.

>https://developer.apple.com/documentation/foundation/nsattributedstring/key

## 参考
https://developer.apple.com/documentation/foundation/nsattributedstring/key

https://developer.apple.com/documentation/uikit/uinavigationbar/1624953-titletextattributes

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
【一度は読んでおきたい】PSR について見ていく

## はじめに
前回は自動的に規約に従ってコードを検知・整形してくれるライブラリの紹介をしました。

https://qiita.com/suzu12/items/1f1502375c3ad4753ebb

今回はコーディング規約について見ていきます。

- コーディング規約に沿ってレビューができる
- 保守性が高くなる
- 開発で迷いが少なくなる
- 社内ルールをつくる上でのベースとすることができる
- コードを統一化することができる

ざっとあげただけでもこのように多くのメリットがあります。

コーディング規約を意識してコードを書くことで
無駄な指摘をなくしたり
社内共通認識（社外に出ても）として持つことができたりするので
覚えておいて損はないかと思います。


## 対象読者

- 複数書き方があるけどどちらのほうが良いのかわからない
- 初学者でどのような規約があるのか知りたい方
- 復習したい方

## 目次

- [はじめに](#はじめに)
- [対象読者](#対象読者)
- [目次](#目次)
- [PSRってなに？](#psrってなに)
- [絶対守りたい規約](#絶対守りたい規約)
    - [Basic Coding Standard](#basic-coding-standard)
    - [Files](#files)
    - [Indenting](#indenting)
    - [Extends and Implements](#extends-and-implements)
    - [Methods and Functions](#methods-and-functions)
    - [Method and Function Arguments](#method-and-function-arguments)
- [Control Structures](#control-structures)
    - [if, elseif, else](#if-elseif-else)
    - [for](#for)
    - [foreach](#foreach)
- [おわりに](#おわりに)
- [参考文献](#参考文献)

## PSRってなに？

`PHP Standards Recommendations` のことでコーディング規約と呼ばれているもののひとつです。
PSRを守ることで PHP や PHPフレームワーク を使用するときには
同じような意識でコーディングすることができ、品質を保つことができるようになります。


こちらがドキュメントです。

https://www.php-fig.org/psr/psr-12/

↑は英語なので読めないという方はまずは日本語訳してくださっているサイトを参考にすると
理解しやすいかもしれません。

https://www.ritolab.com/entry/208


## 絶対守りたい規約

基本的には PHP_CodeSniffer などの静的解析ツールを使用していればあまり意識しなくてもコードを整形してくれます。
しかし、規約を知らなくて良いということにはならないので以下の点に着目していくつか規約の内容を見ていきます。
他のものも気になるという方はドキュメントをご覧ください。

- すぐに改善できるもの
- これだけは守っておきたい


### Basic Coding Standard

PSR-1 で解説されている規約に従う。
(※ PSR-12 は PSR-1 （コーディング標準）に準拠が必要になる。）

PSR-12 と比べるとボリュームが少なく読みやすいと思います。

https://www.php-fig.org/psr/psr-1/

https://www.ritolab.com/entry/91


### Files

- すべてのPHPファイルは単一のラインフィードで終了する必要がある
- PHP のみのファイルの場合は終了タグ(`?>`)を省略する


https://www.ritolab.com/entry/208#aj_2_2

cf. ラインフィード
https://wa3.i-3-i.info/word11579.html


### Indenting

- インデントはスペース4つ分にする。
- インデントにタブを使用しない。

https://www.ritolab.com/entry/208#aj_2_4

### Extends and Implements

- `Extends` と `Implements` は class と同じ行に書く。
- class の `{` と `}` は独自の行で書く。前後に空白はいれない。

https://www.ritolab.com/entry/208#aj_4_1


### Methods and Functions

https://www.ritolab.com/entry/208#aj_4_4



### Method and Function Arguments

- メソッドのカンマの前にスペースをいれない。
- メソッドの引数のカンマのあとにスペースをいれる。

https://www.ritolab.com/entry/208#aj_4_5

## Control Structures

https://www.ritolab.com/entry/208#aj_5

### if, elseif, else

https://www.ritolab.com/entry/208#aj_5_1

### for

https://www.ritolab.com/entry/208#aj_5_4

### foreach

https://www.ritolab.com/entry/208#aj_5_5

## おわりに

規約を意識してコードを書くことは非常に重要なので
たまにはドキュメントを読むのも良いかもしれません。


## 参考文献

- [PSR-12: Extended Coding Style](https://www.php-fig.org/psr/psr-12/)

- [【PHP】PSR-12 Extended Coding Style（拡張コーディングスタイル）](https://www.ritolab.com/entry/208)

- [【PHP】PHP_CodeSniffer でコードを整形する](https://qiita.com/suzu12/items/1f1502375c3ad4753ebb)
muttによるGMailの送受信のための設定

基本的にこちらの記事の通りで動きます。

https://www.makeuseof.com/install-configure-mutt-with-gmail-on-linux/

```
mkdir -p ~/.mutt/cache/headers
mkdir ~/.mutt/cache/bodies
touch ~/.mutt/certificates
touch ~/.mutt/muttrc
```

~/.mutt/muttrc を編集します。usernameをユーザー名に置き換えてください。

```
set from = "username@gmail.com"
set realname = "First Last"
# IMAP settings
set imap_user = "username@gmail.com"
set imap_pass = "<mailbox password>"
# SMTP settings
set smtp_url = "smtps://username@smtp.gmail.com"
set smtp_pass = "<mailbox password>"
# Remote Gmail folders
set folder = "imaps://imap.gmail.com/"
set spoolfile = "+INBOX"
set postponed = "+[Gmail]/Drafts"
set record = "+[Gmail]/Sent Mail"
set trash = "+[Gmail]/Trash"
```

ここで、最大のハマりどころは、パスワードです。

<mailbox password>はGmailの普段のパスワードではなく、アプリパスワードを設定します。

Googleアカウント　＞　セキュリティ　＞　Google へのログイン　＞「アプリパスワード」の生成が必要です。

これで便利にCUIからGメールを送信できるようになるはずです。
以上です。
M1チップでdocker build時にエラー発生

## はじめに

満を持して購入したMac Book Air M1。
アプリケーションのインストールをAnsibleで行ってみるなど、新しい試みにも挑戦しました。
その中で、インストールできないアプリケーションがあったのです。
今回その対処方法を記録に残しておきます。

## 何が起きたのか？

AnsibleでDockerとCleanArchiverのインストールでエラーとなりました。
Ansibleではなく、Terminalで直接実行してもエラーになります。
調べてみたところ、どうやらM1チップは色々癖があるようでインストールできないアプリケーションがいくつもあるようです。
仕方がないのでDockerは手動でDocker Desktopをインストール、CreanArchiverは一旦保留。
aws-cliを使いたいので母艦のMac miniからコンテナ情報をMac Book Air M1にコピー。
そして、「docker build」を実行。
で、ここでまさかのエラーが発生したのです！

```
:
------
failed to solve: rpc error: code = Unknown desc = executor failed running [/bin/sh -c apt-get update && apt-get install terraform]: exit code: 100
:
```

どうもterraformのモジュールのインストール段階でエラーが発生しているようです。
試しのこの行をコメントにして再実行してみたのですが、他の箇所でも同様のエラーが発生していました。
これはterraformだからエラーになったわけではなさそうだ、何か他に理由がありそうだというところまでは想像つきました。

でも、基本的にはコンテナの構成情報をコピーすれば同じように使えるはずでは？
なぜMac Book Air M1だとエラーになる？

## 原因

原因はdockerのimageがまだARMプロセッサに対応していないためのようです。

## 参考

[M1 MacによるDocker開発環境構築エラー](https://qiita.com/prkrsign890/items/10ecb57e0387a673b3a2)

## 対処

docker-compose.ymlに以下の一文を加えればよいそうです。

```
platform: linux/amd64
```

## おわりに

これまで母艦のMacで色々やってきた経験を活かせるのでMac Book Air M1でもやっていけると思っていましたが、思いがけないトラブルに巻き込まれてしまいました。
とはいえ、調べてみると先駆者の方々がたくさんの情報を残してくださっているので前に感謝しかありません。
じつは、このMac Book Air M1でWindows10の環境をUTMで稼働させることも計画していたのですが、どうもベータ版のような位置づけらしく、一筋縄ではいかない雰囲気です。
優先度は一旦落として、少し落ち着いてからチャレンジしてみようと思います。
基本情報（FE）より応用情報（AP）が簡単に取得可能です。

筆者は2年前、応用情報技術者試験を受験し、学習時間 約1ヶ月で合格しました。

私はコンサルティング、バイオエンジニアを仕事にしており、本職のプログラマやITエンジニアではなく、**世間一般の所謂文系人材と同じ**ような立場の人間です。

本記事では、基本情報技術者試験（以下FE）と比べ応用情報技術者試験（以下AP）のほうが、ITに関係のない一般人にとっては取得がしやすいことを伝える記事です。

# それぞれの資格について
試験を実施しているIPAにはそれぞれの試験区分概要ページにて、以下のことが記載されています。

まずはFE。
>ITエンジニアとしてキャリアをスタートするには、まず基本情報技術者試験から受験することをお勧めします。しっかりとした基礎を身に付けることにより、その後の応用力の幅が格段に広がります。

>業務と役割:基本戦略立案又はITソリューション・製品・サービスを実現する業務に従事し、上位者の指導の下に、次のいずれかの役割を果たす。

>引用元：[IPA 基本情報技術者試験(FE)](https://www.jitec.ipa.go.jp/1_11seido/fe.html)

APでは以下のように記載されています。

>ITエンジニアとしてのレベルアップを図るには、応用情報技術者試験がお勧めです。技術から管理、経営まで、幅広い知識と応用力が身に付き、システム開発、IT基盤構築などの局面で、高いパフォーマンスを発揮することができます。

>業務と役割：基本戦略立案又はITソリューション・製品・サービスを実現する業務に従事し、独力で次のいずれかの役割を果たす。

>引用：[IPA 応用情報技術者試験(AP)](https://www.jitec.ipa.go.jp/1_11seido/ap.html)

試験実施元としては、APの方が高難易度、高度な試験として位置付けていることは間違いありません。

# 出題傾向・範囲について
APが一般人にとって、取得が簡単な理由。それは試験科目に**プログラミングを選択しなくて良い**こと、そしていわゆる**業務知識を問う問題を複数選択できる**こと。この２つです。

午前問題の難易度については受験検討時、確認しましたがほとんど難易度に差はありません。

午後問題は、FEでは「情報セキュリティ、データ構造とアルゴリズム、プログラミング言語」が必須です。

一方、APでは「情報セキリュティ」のみ必須。その上、経営戦略、プロジェクトマネジメント、サービスマネジメント、システム監査など、**ITに関する知識が多くなくとも回答可能な設問を多く選択することが可能**です。

また、どちらも過去問からの使い回しが多く、ほとんど暗記だけで勝負可能です。単語、パターンこれを覚えるだけです。記述があるからAPは難しいなどとされていますが、そちらも**単語とパターンを押さえれば問題ありません。**

また、FEは令和2年春期試験から午後の試験形式が変更され、長文形式の問題となりました。そのため過去問を使った傾向と対策を行い、試験に挑む場合、**2021年現在、よりAPの方が取得が楽な状況**になっています。

この対策にはこちらのnoteにて、非常に素敵な資料が販売されています。知り合いから教えてもらいましたが、この教材はかなりおすすめです。

[【暗記リスト】応用情報技術者試験 〔A4用紙 40枚〕](https://note.com/sakurakocake/n/nebe315971813)

## 特にITオタクは簡単に取得可能
さらにAPの試験問題は、ITオタクが自分の環境を整える程度の情報でも答えられる範囲が多いとも思います。

単語も日常的にガジェットなどを触っているとスペックシートや設定などで出てくる言葉ばかり。例としてUSB端子の形状、DHCPの仕組みといった、日常的なことなども問われたりします。

そうなると覚えるべきものは、数学・経営程度となり、楽勝です。

# そもそもプログラミングなどは試験後にやるべき
ただでさえ、IT系の資格は独占業務があるわけでもない資格です。人事的な評価や自己研鑽につながるものであれば、**FEではなくもAPの方が楽な上、評価もされます。**

そもそもプログラミング言語を試験として導入すること自体、個人的にはありえないと考えています。

試験向けで勉強するなら、当然傾向・対策が行いやすい、そんな言語で選んでしまいます。例えばそのような観点で選ばれた言語が、一般人にとって直接いいことに繋がりますでしょうか。

我々一般人がプログラミングに触れる良さは、**自分がこんなことしたい、あんなことあったらいいなを自分で実装できるところ**にあると思います。

実際に自分がプログラミングでやりたいことがあったとしても、それに繋がらないことを勉強しても仕方ありません。

それならば、ぜひ今回の企画会社であるUdemyの教材で学習することをおすすめします。

# 個人的に購入したプログラミング教材

以下、個人的に購入して、自分で使うツールの作成を行った教材です。初心者でもわかりやすく、おすすめです。

https://www.udemy.com/course/python-wc/

https://www.udemy.com/course/python-scraping-application/

https://www.udemy.com/course/python-scraping-beginner/

私はPythonが個人的には書きやすく、自分がやりたいことにfitした言語でした。Excelの自動操作や、Webから一気に情報を集める方法など、業務的にも使えるものがたくさんあります。

ぜひ皆様も、資格は最適な勉強方法・目標で確実に取得し、せっかくなら自分が楽しめることを学習してみてください。

:::note info
本記事はアドベントカレンダー「IT資格取得をテーマに学びをシェアしよう！【PR】Udemy」への参加記事です。
:::

https://qiita.com/advent-calendar/2021/udemy
インターン日記 #1 目的整理

#はじめに
はじめまして。Kotと申します。
先月からとあるスタートアップで期限なしのインターンをしているのですが、そこでの振り返りを日記でまとめておいたほうが良いと思い、学びがあった際には書いていこうと思います。

#目的
今回はインターンをなぜ始めたのかについて書き綴ろうと思います。
目的は3つ。
1. 自分の技術力をもっと高めたい
2. 自分の技術で価値創造をして何を感じるか知りたい
3. ユーザーを喜ばせるエンジニアになるための一歩を進めたい

##自分の技術をもっと高めたい
大学に入ってから授業でPythonを用いて初めてプログラミングを学び、大学2年時には大学内の友だちができずに困っている1年生のための友達つくりサービスを作って広めようとしたり、などしてきました。
ここ数ヶ月はCS50( https://online-learning.harvard.edu/course/cs50-introduction-computer-science?delta=0 )を用いてコンピュータ・サイエンスの基礎を勉強したりしていました。

大学で所属している学科は少し領域が異なっていたので、webにおける技術はすべて独学でしてきました。チーム開発も経験はしてきましたが、自分と同等のレベルの友だちとが多かったです。
そんな中、段々と**実際にプロと一緒に働いて自分の技術力をもっと高めたい**と思うようになり、プロと一緒に働ける場所を探しました。
わからないことはすぐに聞けるしコードレビューも行っていただけるので、このインターンでどんどん技術をつけていきたいと感じている所存です。

##自分の技術で価値創造をして何を感じるか知りたい
少し堅苦しいですが、エンジニアのお試し体験のような目的もあります。
大学内に向けて作った友だち作りサービスを企画・開発する中で「誰の課題を解決するのか、原因はどこにあるのか、そのための解決策は何が最適か」を考えて、自分の技術で解決策を創るのが非常に楽しく感じました。その中で自分の技術でユーザーの課題のための解決策を創るのは非常に面白いのではないかと思い、エンジニアを目指して勉強してきました。
今後十数年はエンジニアとしてのキャリアを進めていく予定ですが、経験したことない状態で自分の人生の選択をするのは少し危険なのではと思い、エンジニアとして働くことに対しての理解度を深めていけたらと考えています。そのためのインターンで、**技術を通してユーザーに価値を届けることで楽しさや苦しさをどれくらい感じるのかを知りたい**と考えています。

##ユーザーを喜ばせるエンジニアになるための一歩を進めたい
2つ目でも書いた大学内に向けて作ったサービスは結果としては失敗でした。ターゲットが何に困っていてその原因は何なのかを突き止めることができず登録者は目標の100人にはるか届かない形となってしまいました。
自分の無力感を感じるとともにいつかユーザーを喜ばせるエンジニアになりたいという思いを持つようになりました。**自分が開発しようとしているこの機能は本当に必要なのか、ユーザーが持っている課題の原因と作ろうとしている機能が合致しているかを考えることができるエンジニアになりたい**と思っています。

この「ユーザーを喜ばせるエンジニアになる」という目標はおそらく長く掲げるかと思います。そのための一歩をこのインターンで踏み出すことができればと考えています。

#インターンでやること
参加させてもらっているインターンは小規模のスタートアップのため、エンジニア自体の数は少ないですが裁量が大きく、開発だけでなく仕様や設計もやらせてもらっています。(入って1ヶ月も経ってないのにこんな経験できるの貴重すぎる...)

今は社内向けツールの仕様設計、開発を行っていますが、技術力をさらに身につけてユーザーに直接関わるところにも参加できればと思っています。

#おわりに
Qiitaでは週1ペースでインターンで何を学んだかを振り返っていこうと思います。
- エンジニアとのコミュニケーションで難しかったこと
- 社内向けツールの仕様設計で非エンジニアとのコミュニケーションで苦労したこと
- 技術面で苦労したこと
などを書くことができればと思っています。
Macのターミナルでよく使うコマンド一覧 ファイル操作編

## ファイルやディレクトリの参照 ls(List)

lsコマンドはファイル、ディレクトリを指定して一覧の情報を取得するためのコマンド。
オプション、ファイル名、ディレクトリ名の省略が可能で、その場合は現在のディレクトリの情報を取得する。

**ls**
**ls [オプション] ファイル名**
**ls [オプション] ディレクトリ名**  

**書式例**

```shell:ls
ls abc.txt
```

**オプション**

```shell:-a
ls -a # 隠しファイルも含めて出力。
      # ファイル名の初めピリオドがあるようなファイルも出力される(.gitignoreファイル等)
```

```shell:-l
ls -l # 詳細な属性を出力
      # ファイルの種類、許可属性、所有者、グループ、タイムスタンプ等が確認可能
```

```shell:-t
ls -t # 更新順でソートして出力
```

```shell:-r
ls -r # ファイル名の逆順にソートして出力
```

オプションは複数使用可能
(例)

```shell:-lt
ls -lt # 現在のディレクトリにある全てのファイル、ディレクトリを詳細な属性を更新順に出力
```

**ワイルドカード(*,?)**
lsコマンドを使用する際にワイルドカードを使用して絞り込みが可能
(例1)

```shell:*
ls *.txt # 拡張子がtxtのファイルを絞り込んで出力
```
(例2)

```shell:?
ls ???.txt # ファイル名部分が3文字で拡張子がtxtのファイルを絞り込んで出力
```

## ファイルのコピー cp(copy)

cpコマンドはファイルを複製するコマンド。複製したファイル名を同時に指定することも可能。

**cp [オプション] コピー元 コピー先**  

**書式例**

```shell:cp
cp before after
```
ファイルを別名でコピー
　afterが存在しないファイルの場合、beforeのコピーとして作成  

ファイルをディレクトリにコピー
　beforeがファイル名でafterがディレクトリの場合はafterの下にbeforeファイルのコピーが作成

ファイルを新しいファイルで上書き
　afterが存在するファイルの場合、beforeの内容で上書き

**オプション**

```shell:-i
cp -i before after # 処理時に確認の問い合わせあり。誤って上書きする事を防ぐ。
```

```shell:-r
cp -r before/ after/ # ディレクトリをコピー。ディレクトリ内の全てのファイル、ディレクトリをコピーする。
```

```shell:-p
cp -p before after # コピー元のファイルの情報を保存。所有者、属性、更新日時を保持してコピー。
```

## ファイルの移動 mv(move)

mvコマンドはファイルを移動する時に使用するコマンド。また。ファイル名の変更も可能。

**mv 移動元ファイル 移動先ファイル**

**書式例**

```shell:mv
mv before after
```
ファイルを別のディレクトリに移動
　beforeがファイル名でafterが存在するディレクトリの場合、afterディレクトリにbeforeファイルが移動。
ディレクトリを別のディレクトリに移動

ディレクトリを別のディレクトリに移動
　両方共に存在するディレクトリの場合はafterディレクトリの下にbeforeディレクトリが移動

ファイル名の変更
　beforeがファイル名でafterが存在しないファイル名の場合、afterにファイル名が変更

ディレクトリ名の変更
　beforeがディレクトリ名でafterが存在しないディレクトリの場合はディレクトリ名がafterに変更

**オプション**

```shell:-i
mv -i before after # 処理時に確認の問い合わせあり。誤って上書きする事を防ぐ。
```
```shell:-f
mv -f before after # 強制的に処理を実行。
```

## ファイルの削除 rm(remove)

作成したファイル、ディレクトリを削除する際に使用するコマンド。一度削除したファイルは復活させることが出来ない

**rm ファイル名**

**書式例**

```shell:rm
rm abc
```

**オプション**

```shell:-i
rm -i abc # 処理時に確認の問い合わせあり。誤って削除する事を防ぐ。
```
```shell:-f
mv -f abc # 強制的に処理を実行。
```
```shell:-r
mv -r abc/ # ディレクトリを削除する際に使用。ディレクトリ内のファイルも削除される。
```
コーディング試験の初級レベルのSQL問題チートシート

コーディング試験でよくある初級レベルのSQL問題を解くために必要なチートシートです．

【！注意！】
あくまでチートシートです．
__しっかりと勉強して解いた方が得なので，まじめに勉強しましょう．__
また，これがわかれば完答できるというわけではないので，参考程度に．
そもそも筆者も初学者で備忘録的に書いています．
間違っていたらご指摘ください．

## 前提条件
カラムとして

- id （固有のid）
- name （名前）
- salary （給料）

という属性を持ったテーブル「Job」を想定して解説していきます．

## 目次
<!-- @import "[TOC]" {cmd="toc" depthFrom=2 depthTo=3 orderedList=false} -->
<!-- code_chunk_output -->
- [レコードの追加](#レコードの追加)
- [レコードに対して四則演算を行う](#特定の条件を持ったレコードに対して，四則演算を行う)
  - [簡単な例](#簡単な例)
  - [特定の条件を指定したレコードに対して四則演算を行う場合](#特定の条件を指定したレコードに対して四則演算を行う場合)
- [レコードの取得]()
    - [重複なく取得する場合](#重複なく取得する場合)
    - [特定の条件を指定してレコードを取得する場合](#特定の条件を指定してレコードを取得する場合)

<!-- /code_chunk_output -->

## レコードの追加
```
INSERT INTO Job(id, name, salary)
VALUES (1, 'Sato Takuma', 1500);
```
とすればレコードが追加されます．
自動採番が設定されている場合は以下の命令を実行することで自動でidが設定されテーブルの最後尾にレコードが追加されます．

```
INSERT INTO Job(name, salary)
VALUES ('Sato Takuma', 1500);
```

### この章のまとめ
レコードの追加は以下の命令で実行．

```
INSERT INTO テーブル名(カラム名_1, カラム名_2, ……)
VALUES (値_1, 値_2)
```

## レコードに対して四則演算を行う

### 簡単な例
```
SELECT id, name, salary*2
FROM Job
```
とすると，salaryが2倍された状態で出力されます．

カラム内のすべてのフィールドに四則演算を行いたいときは簡単です．

### 特定の条件を指定したレコードに対して四則演算を行う場合
例えば，特定のidの人の給料を2倍にしたい場合は以下のような命令をすればOKです．

```
UPDATE Job
SET salary = salary*2
WHERE id >= 5
```

こうすることでidが5以上の人の給料を2倍にする処理ができました．

### この章のまとめ
レコードに対して四則演算を行うには以下の命令で実行．

```
UPDATE テーブル名
SET 四則演算
WHERE 条件
```

## レコードの取得

### 重複なく取得する場合
例えば salary が何種類あるか知りたいときはDISTICTを使います．
~~種類を知るだけならCountでもいいとか突っ込んだら負けです．いい例が思いつきませんでした．~~

```
SELECT DISTINCT salary
FROM Job
```
このように命令すれば，salaryカラムのみの出力となりますが重複は削除されて出力されます．

### 特定の条件を指定してレコードを取得する場合
例えばsalaryが3000以上の人を表示させたい場合は以下の命令を実行すればOKです．

```
SELECT *
FROM Job
WHERE salary >= 3000
```

### この章のまとめ
重複なく取得したい場合

```
SELECT DISTINCT カラム名
FROM テーブル名
```

条件指定してレコードを取得したい場合

```
SELECT カラム名
FROM テーブル名
WHERE 条件
```

## まとめ
以上でチートシートは終わりです．
ざっくりのまとめになるので，何かご指摘がありましたら遠慮なくコメント欄にてお願いいたします．
WindowsでNode.jsをセットアップウィザードなしで使用する方法

## はじめに
 - Node.jsアプリケーションを、実行可能ファイルにまとめたい。

 - Node.jsをUSBに入れて、持ち運びたい。

 - Node.jsを環境にインストールしなくてもNode.jsアプリケーションが動作するようにしたい。

上記事項をするためにポータブル化する方法


## 手順
環境 Windows11 64ビット

### 1. Node.js のサイトから利用したいバージョンを選ぶ

https://nodejs.org/dist/

v16.13.0を使いたい --> https://nodejs.org/dist/v16.13.0/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946490/bc612d62-fc60-2f0d-5d8e-3e109ddf7d4c.png)

### 2. node-v＊.＊.＊-win-x64.zip をダウンロードする

v16.13.0 --> node-v16.13.0-win-x64.zip
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946490/f840bfb8-c456-791c-019b-f90933074c29.png)


### 3, ダウンロードしたzipファイルを展開する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946490/aca7c991-4441-f290-f23a-426e3ac673ca.png)

### 4. 不要だと思うファイルを削除する
:::note warn
必要だと思うファイルを残しといてください。
:::
:::note alert
node.exeを削除しないでください。Node.jsを実行できないよ。（念のため...）
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946490/1c1ba32f-96fb-2add-18f0-794c6df642b6.png)

### 5. `node.cmd` or `node.bat` のファイルを作成し、以下のコードを貼り付ける。
```bat
@echo off
"%~dp0\node.exe" %1 %2 %3 %4 %5 %6 %7 %8 %9
```

### 6. `run.cmd` or `run.bat` のファイルを作成し、以下のコードを貼り付ける
```bat
@echo off
set PATH=%~dp0
set NODE_PATH=%~dp0\node_modules
cd /d "%~dp0"
node.cmd %~dp0run.js
```

### 7. `run.js` のファイルを作成し、以下のコードを貼り付ける
```js
console.log("run.cmd --> run.js")
console.log("Hello!")
console.log("end")
```

### 8. 動作するかを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946490/f2df2cbf-db3a-0d21-173d-018794dd99ad.png)

### 仕組みが理解できたら、必要な人のみコードを書き換える
例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946490/12ff47af-0510-225d-d39c-84c08bcacc6c.png)


## 完成
ソースコード(必要な人のみコードを書き換えたもの)

https://github.com/Neko7sora/Node.js-Portable
M1 Mac(Big Sur)でmysql2をインストール

いつもエラー出て
調べて
全く違う記事が出るので

2021/11/07時点で良さそうな対応

```
brew install openssl
bundle config --global build.mysql2 "--with-opt-dir="$(brew --prefix openssl) --with-ldflags=-L/opt/homebrew/Cellar/zstd/1.5.0/lib""
```
pythonで日付時間を名前先頭に入れたバックアップフォルダを作成


```python:
# shutilがフォルダのコピーライブラリ
import shutil,datetime

# 現在時間
dt_now=datetime.datetime.now()
# 月日時分秒
dt_now=dt_now.strftime("%m%d%H%M%S")


send_fold="D:\\元フォルダ\\"
send_file="元ファイル名"
rece_fold="C:\\Users\\aaa\\Dropbox\\バックアップ先フォルダ\\"
rece_file=dt_now+send_file

send=send_fold+send_file
rece=rece_fold+rece_file

shutil.copytree(send,rece)
```
テックキャンプを卒業しての感想

▪︎  感想

私はテックキャンプで出会った人々等を通してプログラミングを学べたことを心の底から感謝しています。心の底から感謝している理由として３つのポイントがあります。1つ目のポイントはテックキャンプ学習カリキュラムの分かりやすさ、読みやすさにあります。私はテックキャンプに入る前プログラミング学習を行っていましたが、学習を進めて行くに連れて分からない所が増え何度もやめたい、やりたくないという気持ちが強まっていき、最終的に挫折してしまいました。ですが、どうしても自分の武器としてプログラミングを学習したいと思いテックキャンプに入学しました。学習を進めていくと分からない所が増え、また挫折するのではないかという気持ちでいっぱいでしたが、テックキャンプに入ってからは分からない所が増えても学習カリキュラム等の説明の分かりやすさ・読みやすさがあったので挫折せず学習を進められたのだと心から感じています。
２つ目のポイントはメンターの方達に質問ができる手厚いサポートです。学習も応用や発展の段階に入ると、詰まる所が多くなっていきました。その際、カリキュラムやインターネット検索などを用いて答えを探し解決していました。ですが、時々カリキュラムやインターネット内で調べても分からない場合はメンターさんに質問をする手段を取っていました。メンターさんに質問を投げかけると分かりやすく優しく教えてくださったので開発や学習がスムーズに進めることができたのだと思います。
３つ目はテックキャンプで出会えた仲間達です。１つ目のポイントと２つ目のポイントでも述べましたが、カリキュラムの分かりやすさ、読みやすさとメンターの方達に質問が出来る手厚いサポートがあったからこそ挫折せずプログラミングを学べたと感じています。ですが、それよりもテックキャンプに入学した時に出会った仲間達がいたからこそ、挫折せずプログラミングを学べたのだと改めて感じています。学習で分からない所、開発で詰まった所等を共有し、一緒に教えあったり、また一緒に考えたりしたことが学習中や開発中での心の支えになったと感じています。そして、もし仲間に頼らずひとりで学習を進めていたらテックキャンプに入学する前みたいに絶対挫折をしていたと思います。
以上の３つのポイントから私はテックキャンプで出会った人々等を通してプログラミングを学べたことを心の底から感謝しています。そしてこれらの経験を生かして今後活躍していきたいと思います。今までありがとうございました。
Javascript fetchを使えるようになろう

## はじめに
初学者
基本は備忘録

## 追加
```js
// Axiosの方が簡単
const await axios.get("url")

const await axios.post("url", body)

const await axios.delete("url", body)

const await axios.put("url", body)
```

## fetch APIとは
[詳しくはこちらのサイト](https://ja.javascript.info/fetch)
HTTPリクエストをサーバーに送るための関数
解決時にResponseオブジェクトを取得できるPromiseを返す
thenに渡す関数の引数はresponseにする(暗黙)

**thenを利用した場合の例**

```js
const result = fetch('取得したAPIのURL');
result.then((response) => response.json())
.then((info) => console.log(info[0].プロパティ名))
```

## 少し説明
JavaScript は、必要に応じていつでもサーバへリクエストを送信し、新しい情報を読み込むことができます。

例えば、次のようなことができます:

注文を送信する
ユーザ情報を読み込む
サーバから最新の更新情報を受け取る
…など
…そしてこれらはすべてページをリロードすることなく行うことができます。
**基本構文**

```js
let promise = fetch(url, [options])
```

---

**例** APIが取得できたら情報をjson形式にしてjsonに代入

```js
async function f() {
  let response = await fetch(url);

  if (response.ok) { // HTTP ステータスが 200-299 の場合
    // レスポンスの本文を取得(後述)
    let json = await response.json();
  } else {
    alert("HTTP-Error: " + response.status);
  }
}
f()
```

## 実際に取得してみる
レスポンスの本文を取得するには、追加のメソッド呼び出しが必要です。

`Response`は様々な形式で本文にアクセスするための、複数の promise ベースのメソッドを提供しています。:

`response.json()` – レスポンスを JSON オブジェクトとしてパースします
`response.text()` – レスポンスをテキストとして返します

*例えば、ここでは Github から最新のコミットの JSON オブジェクトを取得します。*

```js
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');

let commits = await response.json(); // レスポンスの本文を読み JSON としてパースする

alert(commits[0].author.login);
```

*純粋なPromise構文*

```js
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits')
  .then(response => response.json())
  .then(commits => alert(commits[0].author.login));
```

## JSON配列


*決まり*
シングルクオーテーションで囲んではいけない
プロパティに対してもダブルクオーテーションで囲む
格納されている要素の一番最後に,をつけてはいけない

### 例

```js
fetch('js/users.json')
.then((response) => response.json())
.then((json) => {
  console.log(json)
  for(const user of json) {
    console.log(`I'm ${user.name}, ${user.age} years old`)
  }
})
```

**jsonはこれ**

```json
[
  {
    "name": "Bob",
    "age": 23
  },
  {
    "name": "Tim",
    "age": 30
  },
  {
    "name": "Sun",
    "age": 25
  }
]
```
Async/Awaitを完全に理解した

## 初めに
ちょっとできるになりたい 伝わるかな？
1年前は長時期よくわからなかったAsync/Awaitさんですが、この度理解できましたので、Qiitaの記事を更新します。
`Async`ってなんて読むか知ってます？
「エイシンク」です。 「アシンクじゃないよ!!」


## Async/Awaitとは
Promiseの結果がreturnされるまで一時停止する
Asyncの関数の中でしか使えない

## 基本
```js
// この関数はPromiseを返す関数になる
async function() {}
```
```js
// awaitはPromiseの結果が返るまえ一時停止する
// awaitはasyncで定義した関数の中で使える
await Promise処理
```

## 実例
- Promiseを返す関数を定義
- asyncが頭にある関数の中で上記の関数をawaitを頭につけて実行する
- asyncが頭にある関数を実行()

*上記の手順で、asyncの中の関数は同期処理のように上から順に実行されるようになる*
```js
// promiseを返す関数を作成 returnを忘れずに
let time = () => {
  return new Promise((resolve) => {
    setTimeout(() => resolve("tee"), 1000)
  })
}


let myAsync = async () => {
  // resolveの結果がわかるまで停止できる
  const result = await time() // time()は上で定義したPromiseを返す関数
  
  // resultに値が入ったあと下記を実行
  console.log(result)
}

myAsync()
```

## resolveの実引数を繋げる
```js
const mypromise = () => {
  return new Promise((resolve) => {
    setTimeout(() => resolve("tee"), 1000)
  })
}

const main = async () => {
  // promiseと比べてreturnを書く手間がない
  console.log(await mypromise())
  console.log(await mypromise())
}

main()
```
Promiseを完全に理解した

## はじめに
ちょっとできるになりたいです。 伝わるかな？

## なんで書いた？
1年前にPromiseを学習したときは、なんとなくの理解だったが、この度使う機会があり理解できた。
当時作成していたPromiseのメモをリファクタリングしたのでQiita上でも更新しようと思う

## Promiseとは？
非同期処理を同期処理のように扱える(上から順に実行)
Promiseが動かない場合resolveを実行しているか確認する

## 基本
```js
let promise = () => {
  return new Promise(resolve, reject) => {
    // ここで時間のかかる非同期処理をする
    // 最後にresolve()する
    // resolveの実引数をthenに渡せる
  }
}

promise()
.then(() => {
  // 処理
})

// thenの処理はpromiseを含む関数がresolveを
// returnした後に実行される
```

## 関数化しない方法
*説明も詳しく*
```js
// 下記のように書く場合returnは不要
// const promise = は省略可能 いきなりnew Promiseから始めても可
// 基本で紹介したように関数にする場合はPromiseの結果を外にreturnする必要があった
const promise = new Promise(resolve, reject) => {
  // executor (時間のかかる処理)
}
.then(() => {
  // 処理
})
```

## catch
エラーの場合のみ呼び出される
```js
new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error("エラー!!"))
  }, 1000)
})
.catch(alert) //1秒後に "エラー!!" を表示
```

## fainally
Promiseの最後に必ず実行される
```js
new Promise((resolve, reject) => {
  setTimeout(() => resolve(console.log('1秒たった')), 1000)
})
// 結果が確定したら最後に必ず実行される
.finally(() => {
  console.log('done')
})
```

## resolveの実引数を繋げる
```js
new Promise((resolve, reject) => {
  setTimeout(() => resolve("tee"), 1000)
})
.then((data) => {
  console.log(data)

// 次のthenでresolveの結果を使うにはreturnする
  return data
})
.then((data) => {
  console.log(data)
})
```
BFSをrustで実装

タイトルの通り。
勉強がてら実装してみたという話
参考：https://qiita.com/drken/items/996d80bcae64649a6580#1-2-bfs-%E3%81%AE%E5%AE%9F%E8%A3%85

2次元ベクターの行数は確保したいが列の中身は無い状態にしたいという書き方が
vec![vec![0;0]; n];
で書けるのが発見でした。

22/10/19 : キューがベクタで実装されているのに1年たってから気づいた。修正。たまに時間がかかるときがあると思ったら・・・

```rust:main.rs
use proconio::input;

fn main() {
input!{
n:usize,
m:usize,
t:[[usize; 2]; m],
}
let mut gra = vec![vec![0;0]; n];
let mut dist = vec![-1;n];
let mut queue =VecDeque::new();
dist[0]=0;
queue.push_back(0);

for i in &t{
    gra[i[0]].push(i[1]);
    gra[i[1]].push(i[0]);
}


while !queue.is_empty(){
    let v = queue.pop_front().unwrap();

    for nv in &gra[v]{

        if dist[*nv] != -1{continue}

        dist[*nv] = dist[v] + 1;
        queue.push_back(*nv);

    }


}

println!("{:?}",dist)


}
```

追記
distの保存をするところを連想配列にした。大きさが大きすぎるときはこちらを使う必要がある
```rust
fn main() {
  input!{
    m:usize,
    mut t:[[usize; 2]; m],
    }
    
    let mut map = HashMap::new();
    //let mut dist = vec![-1;n];
    let mut queue =VecDeque::new();
    let mut max = 1;
    let mut map2 = HashMap::new();
    queue.push_back(1);
    
    for i in &t{
      map.entry(i[0]).or_insert(vec![i[1]]).push(i[1]);
      map.entry(i[1]).or_insert(vec![i[0]]).push(i[0]) ;

      }
    
    while !queue.is_empty(){
        let v = queue.pop_front().unwrap();
        if map.get(&v) == None{
          continue
        }
        for nv in map.get(&v).unwrap(){
    
            if map2.get(nv) != None{
              continue
            }
            map2.entry(*nv).or_insert(1);
            max = max.max(*nv);
            queue.push_back(*nv);
    
        }
    
    
    }

    println!("{}",max)
  }
```
非同期処理　Promise

## はじめに
`Promise`について学習したので取り上げる
初学者
基本は備忘録

## Promise
実行完了を待たない
並行して次の処理を実行(時間がかかるから)

時間のかかる処理が終了した後に行う処理を登録できる

[詳しくはこちらのサイトで確認する](https://ja.javascript.info/promise-basics)
Promiseの復習は合わせてPromise + αも確認する(別のファイル)

**Promiseの構成要素は3つしかない**
- 処理
- 処理成功時の値
- 処理失敗時の値

## 基本の構文
```js
let promise = new Promise(function(resolve, reject) {
// executor (生成コード)
})
```
new Promise へ渡される関数は executor(執行者) と呼ばれます。promise が作成されると、自動的に呼ばれます。それは最終的に結果と一緒に終了する生成コードを含んでいます。

例

```js
 let promise = new Promise(function(resolve, reject) {
  // promise が作られたとき、関数は自動的に実行されます

  // 1秒後、ジョブが "done!" という結果と一緒に完了したことを合図します
  setTimeout(() => resolve("done!"), 1000);
});
 ```
 
## 覚える基本
new Promiseに渡す関数はexecutorと呼ばれpromiseが作成されると自動的に実行する
executorはresolve,rejectの二つの引数を持っている
executorの中で関数(job)を定義(大抵は時間のかかる処理)する
jobの中では最後にresolveを実行する
成功時にはresolveの引数が結果に返る　失敗時はrejectの引数が返る
jobに複数のresolveがある場合最初のresolve以外無視される

## then系統について押さえる
**使い方はこれ**
thenはexecutorの実行が終了し、Promiseの状態が確定した後に行われる
thenに渡した関数の最初の引数にはresolveの実引数が入る
thenを複数繋げた場合先のthenが終了するまで次のthenは実行されない
resolveの実引数を2個目以降のthenで利用するには直前のthenでreturnする

```js
let promise = new Promise(resolve => {
  setTimeout(() => resolve("done!"), 1000);
});

promise.then(() => alert; // 1秒後に "done!" を表示
```

## catch
エラーの場合のみ呼び出される

```js
let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("Whoops!")), 1000);
});

// .catch(f) は promise.then(null, f) と同じです
promise.catch(alert); // 1秒後に "Error: Whoops!" を表示
```

## fainally

通常の try {...} catch {...} に finally 節があるように、Promise にも finally があります。

.finally(f) 呼び出しは、Promise が決着したとき(解決または拒否になったとき)に必ず実行されるという意味で .then(f, f) に似ています。

finally はクリーンアップを実行するのに便利なハンドラです。例えば、結果がどちらであっても、もう不要となったので読み込み中のインジケータを停止するなどです。

このようになります:

```js
new Promise((resolve, reject) => {
  /* 時間のかかる処理を行い、その後 resolve/reject を呼び出す */
})
  // 成功か失敗かは関係なく、promise が確定したときに実行されます
  .finally(() => 読込中のインジケータを停止する )
  .then(result => 結果を表示する, err => エラーを表示する)
```

## Promiseを利用した例
```js
//msに渡した秒数分待ってから.thenを実行する
const delay = (ms) => {
  return new Promise((resolve, reject) => {
    settimeout(resolve, ms)
  })
}

delay(3000).then(() => alert('run afeter 3 seconds'));
```

## Promiseのチェーンを繋ぐ場合

*最初のthenで受け取った引数を後ろで使いたい場合returnで送る必要がある*

```js
.then((data) => {
console.log('1回目: ' + data)
return data;
})
.then((data) => console.log('2回目' + data))
```

thenの中で`throw new Error()`でエラーを起こせる

## returnさせるとき
thenの戻り値としてPromiseが**実行**される場合にはその処理が解決するまで次のthenは待機する

## 使用時のポイント
非同期処理を含む関数を作りたいときは、関数を作成したらすぐにreturn new PromiseでPromiseオブジェクトを返す関数を作成するとスムーズ

## 終わりに
基本的に`async`等を使って記述するが、Promiseの理解は必要
PythonからデフォルトのブラウザでWebページを開く。

#こんにちは
PythonからChromeなどのブラウザでWebページを開く方法を紹介します。

#デフォルトのブラウザを設定
Macの場合はシステム環境設定の一般から変更可能です。
![スクリーンショット 2021-11-07 11.54.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2236248/b6b4dc03-9646-371b-e69e-e7d12515f9cd.png)
この記事では[Firefox Developer Edition](https://www.mozilla.org/ja/firefox/developer/)を使っています。
ブラウザ自体はChromeでもSafariでも問題ないです。
![スクリーンショット 2021-11-07 11.53.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2236248/177a7885-61a6-4dee-af56-2b8039cd94c6.png)

#本編
それではやっていきます。
まずモジュールをインポートします。

```python
import webbrowser
```

でオッケーです。
ブラウザでWebブラウザを開く処理は

```python
webbrowser.open("ここにURLを入力")
```

サンプルとしてGoogleを開いてみます。
GoogleのURLは```https://www.google.co.jp/```なので、こんな感じになります。

プログラム全文

```web_google.py
import webbrowser
webbrowser.open("https://www.google.co.jp")
```

実行結果
![スクリーンショット 2021-11-07 12.08.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2236248/d4eead5b-24ee-425b-a14c-1f3298014830.png)

##変数も
変数からの指定でもこんなかんじで動作します。

```python
google_url = "https://www.google.co.jp/"
webbrowser.open(google_url)
```

#終わりに
webbrowserの使い方でした。

Python 3.10.0で動作確認済みです。
【Project Euler】Problem 69: ファイ関数の最大値

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題：ファイ関数の最大値

原文 [Problem 69:Totient maximum](https://projecteuler.net/problem=69)


**問題の要約：**　$n\leqq 10^6$ で $n/φ(n)$が最大になる$n$を求めよ

これを素直にインプリすると、以下のようになりますがPythonでは76秒かかってしまいました。


```python
from sympy import totient
N, npmax = 10**6, 0
for n in range(1,N+1):
  np = n / totient(n)
  if np > npmax:
    npmax, npmaxN = np, n
print(npmaxN, npmax)
```
そこで以下のファイ関数の定義に従って考えてみたいと思います。$n$の素因数を$p_k$とすると

$\displaystyle φ(n) = n \prod_{i=1}^{k}(1-\frac {1}{p_i}) = 
n(1-\frac {1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_k})
$</br>

従って

$\displaystyle n/φ(n) = \frac{p_1}{p_1-1}\*\frac{p_2}{p_2-1}\*...\*\frac{p_k}{p_k-1}$</br>

これを最大化するということは、以下のような条件が必要と思われます。

* なるべく小さな素因数を選ぶ
* １つの素因数は1回のみ使う（ファイ関数は2回以上同じ素因数を使っても変わらない）

従ってアルゴリズムはこのようになります。Pythonのコードも載せましたが、電卓でも計算できそうですね。

* 素数を小さい順に掛けていって$10^6$を超える直前のが答え

```python
from sympy import  nextprime
N = 10**6
p, n1, phi = 2, 2, 1
while n1 < N:
  n = n1
  phi *= p-1
  p = nextprime(p)
  n1 *= p 
print(f"n = {n}, phi = {phi}, n/phi = {n/phi}")
```
WordPressでパーマリンクにindex.phpが入ってしまう問題の解決

この記事は、
htt*://wordpress.qiita/index.php/contact/
のようにパーマリンクでindex.phpが入ってしまっている場合に有効です。
環境：Ubuntu-Server20.04、apache2
<h2>mod_rewrite.soが読み込まれているか確認</h2>
mod_rewrite.soがないと.htaccessの内容がパーマリンクに反映されないのでmod_rewrite.soが有効になっているか確認します。
最初に以下を実行：

```
 sudo a2enmod rewrite 
```

```
Enabling module rewrite.
To activate the new configuration, you need to run:
  systemctl restart apache2
```
上記のようになったらrewriteが読み込まれていなかったので今読み込んだということになります。読み込まれたのを確認したら次に進みます。
<h2>Apache2を再起動</h2>
以下のコマンドでApache2だけを再起動することができます。

```
sudo systemctl restart apache2
```
<h2>Wordpressで設定</h2>
WordPressでパーマリンクの設定画面を開き、パーマリンク内のindex.phpの部分だけを削除します。
初心者による初心者のためのC＋＋｜製作途中だからどんどん書き加えていくよ

#初心者のためのC++
初めてC++をやるので、間違っていたら教えてください

##標準出力

```c++
#include <iostream>

int main()
{
    std::cout << "HELLO WORLD" << std::endl;

    return 0;
}
````

##コマンドライン引数
```c++
#include <iostream>

int main(int argc, char *argv[])
{
	std::cout << argv[1] << std::endl;

	return 0;
}
```
ファイル名とかが```argv[0]```になるので、それ以降が引数である


##条件式

OR演算やAND演算をするには、以下のような感じ。

```c++
if (<条件１> || <条件２>)
if (<条件１> && <条件２>)
```
ORには`||`、ANDには`&&`を使用する。

##ToUpper
```c++
std::toupper(<文字>);
```
YARNのインストールができない【Error：EACCES】

## 環境
OS：macOS Monterey 12.0.1

## 問題
ターミナルで　`npm install --global yarn`　を実行すると、以下のようなEACCESエラーが発生

```
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/local/lib/node_modules/yarn
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/yarn'
npm ERR!  [Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/yarn'] {
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'mkdir',
npm ERR!   path: '/usr/local/lib/node_modules/yarn'
npm ERR! }
npm ERR! 
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR! 
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/miyu/.npm/_logs/2021-11-06T14_30_15_414Z-debug.log
```

## 解決方法
以下のnpm公式ドキュメントの通りに２つの解決手順を踏んでいく

https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally

<details>
<summary>手順１：まずnpmの再インストールを試みる</summary>

ターミナルで　`npm install -g npm`　を実行するも、再びEACCESエラーが発生
<div>

```
npm ERR! code EACCES
npm ERR! syscall rename
npm ERR! path /usr/local/lib/node_modules/npm
npm ERR! dest /usr/local/lib/node_modules/.npm-i9nnxROI
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, rename '/usr/local/lib/node_modules/npm' -> '/usr/local/lib/node_modules/.npm-i9nnxROI'
npm ERR!  [Error: EACCES: permission denied, rename '/usr/local/lib/node_modules/npm' -> '/usr/local/lib/node_modules/.npm-i9nnxROI'] {
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'rename',
npm ERR!   path: '/usr/local/lib/node_modules/npm',
npm ERR!   dest: '/usr/local/lib/node_modules/.npm-i9nnxROI'
npm ERR! }
npm ERR! 
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR! 
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/<ユーザ名>/.npm/_logs/2021-11-06T23_07_02_519Z-debug.log
```
</div></details>
<details>
<summary>手順２：うまくいかなかったのでnpmのデフォルトディレクトリを変える</summary>
<div>

:::note warn
こちらはWindowsには対応していないので注意
:::
</div>
さきほどのnpm公式ドキュメントの「1. Back up your computer.」〜「5.On the command line, update your system variables:...」をやってみる
（ちなみに2〜5は、実行しても何も表示されない）
</details>

以上を踏まえて、　`npm install --global yarn`　を実行すると、

```
added 1 package, and audited 2 packages in 1s
```
成功！！！
そもそもHTTPって何？

こんにちは。今回はHTTPのことについてまとめてみました。初心者向けです。また、記事投稿は初めてなので、至らぬ点があると思いますがご指摘いただけると有り難いです。


#### そもそもHTTPって？
![client-server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676976/4f3cb00a-a5e0-308d-ccaf-0a6759cb82e8.png)

HTTPはクライアント（Webブラウザ）とサーバー（Webサーバー）の通信プロトコル。
通信プロトコルは細かいいくつものルールで構成されています。

代表的なルールを上げると
　・クライアントとサーバーはリクエストとレスポンスで情報をやり取りする。
　・ポート番号は８０番を使用する。
　・リクエストするときは予め決まった８つのメソッドを使用する。
などがあります。

ちなみに、ブラウザがリクエストをする際は以下の８つのメソッドを使います。
　　　・GET
　　　・POST
　　　・PUT
　　　・HEAD
　　　・DELETE
　　　・OPTIONS
　　　・TRACE
　　　・CONNECT

![HTTPって何？_page-0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676976/2020fae5-bd61-c3d7-baac-ef54ab033547.jpeg)



Javaでは数え切れないくらいのメソッドが用意されていますが、HTTPでは
８つしかありません（しかもこの中でよく使うのはGETとPOSTだけ）。
この８つのメソッドだけで世界中のWebにおける通信プロトコルが成り立っています。

ルールがとてもシンプルで単純なので世界中の人にHTTPが受け入れたれた→結果、
世界各地でHTTPで通信する人が徐々に増えて、今があるという経緯になります。

なので、どこかの国のお偉いさんが法律を決めて、「通信はHTTPにする」と決めて広まったわけではありません。影響力が次第に大きくなり、最終的に皆に受け入れられて広まった感じです。
（以下、個人的な想いですが、基本、プログラミング言語も同じ感じです。これは、裏を返せば普及しているプログラミング言語は、今後登場するであろう更に使いやすい言語に置き換わる可能性があるということです。プログラミング言語を始めとしたITのトレンドについて考えるときは、この考え方は基本となるとおもいます。）

HTTPという通信プロトコルをもとに張り巡らされたネットワーク全体のことをWWW（World Wide Web つまり Web）といいます。

#### リクエスト・レスポンス情報について

では、リクエストでは具体的に何をサーバーに送信しているのでしょうか？
サーバーはクライアントに何をレスポンスしているのでしょうか？

具体的には、リクエストではリクエストメッセージをサーバーに送信して、
レスポンスではレスポンスメッセージをクライアントに送信しています。

![HTTPって何？_page-0002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676976/05ddbe50-7781-95ce-b34b-5dd639cfb283.jpeg)

このリクエストメッセージとレスポンスメッセージはHTTPにおいて重要な概念なので
以下では、これらについて焦点を当てて解説します。

#### リクエストメッセージ

![HTTPって何？_page-0003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676976/2b939b2f-50a6-97df-2a52-f4f18dddff38.jpeg)

クライアントからサーバーにメソッドを使って送られた情報を「リクエストメッセージ」と言います。
「リクエスト情報」、単に「リクエスト」とも呼ばれることもあります。文脈に応じて読み解いてください。



では、リクエストメッセージの中身を見てみましょう。

１行目を「リクエストライン」といいます。リクエストラインは「メソッド名」「コンテンツへのパス」「プロトコルのバージョン」から構成されています。

![HTTPって何？_page-0005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676976/88dd69e8-3709-a8a4-9a11-63a175d34187.jpeg)
↓リクエストラインは「メソッド名」「コンテンツへのパス」「プロトコルのバージョン」から構成されている。
![HTTPって何？ (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676976/62c9bad3-a283-83a9-bddc-06f056b94c89.png)

２行目から、次の空行までをリクエストヘッダといいます。
![HTTPって何？_page-0006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676976/0c098965-d0a5-71d2-277f-bf95c50153eb.jpeg)
今回は全体像を理解してもらうために、リクエストヘッダの中身は今回は触れません。

リクエストヘッダの終わりには空行が入ります。空行の下は「リクエストボディ」といいます。
![HTTPって何？_page-0007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676976/33a5d602-d763-4bd0-d2b1-bc4315c7f316.jpeg)
htmlでformタグを使ってPOST送信した場合にはリクエストボディにその情報が書かれます。例えば下記のようなhtmlのフォームタグを作成して、テキストボックスに「山田」と入力しsubmit送信すると上記の画像の
リクエストボディが https://example.com/ に送信されます。

```html
<form method="POST" action="https://example.com/">
    <input type="text" name="name"/>
    <input type="submit" value="送信"/>
</form>
```
今回はここまで。次回は実際に、htmlを作成して、Chromeの開発者ツールで
formのデータを確認してみましょう!
Dell Optiplex 5060 SFFにLubuntuをインストールする

# はじめに
職場のOptiplex 5060 SFF（Ubuntu 18.04）がクラッシュしました。xrdp経由でWindowsのリモートデスクトップ接続で使用していましたが、Lubuntu 18.04のインストールにチャレンジしました。

# 環境
- Dell Optiplex 5060 SFF (2019), core i5 8400, M.2 256GB SSD, 32GB RAM 
- Lubuntu 18.04

# BIOS設定
- F12でブートオプションを出す→BIOS setupを選択する。
- General→Boot Sequenceで、UEFIにチェックが入っていることを確認する。
- General→Advanced OptionsでEnable Legacy option ROMSのチェックが入っていないことを確認する。
- Secure boot→Secure boot enableでEnableにチェックする（今回インストール時は一旦無効に設定）。

# USBキーの作成
- RufusでLubuntu 18.04のブータブルUSBキーを作成する。
- ほとんどデフォルト（MBR）だが、NTFSで焼いた。

# Lubuntu 18.04のインストール
- F12でブートオプションを出す。
- USBキーの選択肢が出ているので選択。
- Install Lubuntuであとはデフォルト。

# 参考
- [Dellのインストールサポートページ](https://www.dell.com/support/kbdoc/ja-jp/000141125/xps-13-9343-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB-ubuntu-developer-edition-14-04-a-%E7%B5%B1%E5%90%88%E5%9E%8B-dell-pc-%E7%B5%B1%E5%90%88%E5%8F%AF%E8%83%BD%E3%81%AA%E3%83%95%E3%82%A1%E3%83%BC%E3%83%A0%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9-uefi-bios)
CloudFront使用時、ELBのリスナールールを使用して、IPアドレスでのアクセス制限

#はじめに
`CloudFront→ALB→サーバー`という構築において、パス`/admin/users.php`へのIPアドレスでのアクセス制限をする簡易な方法について説明します。

結論を言うと、`ALBのリスナールールで送信元IPアドレスを判定し、アクセス制御`できます。

他の方法として、`WAF`や`サーバーのapacheやnginx`によるアクセス制御は、ありますが、WAFだとお金がかかる、サーバーだとSSH接続など手間がかかりますので、ALBのコンソールで設定できる方法が適切だと考えます。

ちなみにサーバーでのIP制限の方法も記事にまとめていますので、参考になればと思います。

https://qiita.com/holdout0521/items/c76b6890a65866905663


#構成図
![スクリーンショット 2021-11-07 10.32.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0590b7b9-6ab9-49f7-1c76-943bb98b93e0.png)



#ALBのルール
以下のように設定しました。
送信元IPが`111.111.111.111`の場合のみ、パス`admin/users.php`にアクセスできます。
リスナールールには、`X-Forwarded-Forが111.111.111.111`としています。

![スクリーンショット 2021-11-07 10.31.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/27ac3ed0-be03-d63e-b42b-fdc415f15298.png)


#X-Forwarded-Forとは
X-Forwarded-For (XFF) ヘッダーは、 HTTP プロキシ又はロードバランサーを通過してウェブサーバーへ接続したクライアントの、送信元 IP アドレスを特定するために事実上の標準となっているヘッダーです。
クライアントとサーバーとの間でトラフィックに何かが介在すると、サーバーのアクセスログにはプロキシ又はロードバランサーのアドレスしか残りません。
クライアントの元 IP アドレスを記録するために、 X-Forwarded-For 要求ヘッダーが使用されます。

##今回X-Forwarded-For使用した理由
`CloudFront`や`ALB`を通してサーバーにアクセスすると、サーバーから見た送信元IPは、`ALB`のものになってしまいます。
同様に、`ALB`から見たクライアントIPは、`CloudFront`になってしまいます。
それを解決するために、HTTP Headerの`X-Forwarded-For` に送信元IP を記録して、サーバーや`ALB`ではその値を見ることで送信元IPを取得できるようになります。

#参考

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/x-forwarded-headers.html

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Forwarded-For
PythonでiCalendar形式のファイルを書き出す

iCalendarはカレンダーアプリなどで使われるスケジュールデータの標準フォーマット。
iCalendarファイルを使ってGoogleカレンダーやOutlookなどのアプリにスケジュールをインポートすることもできる。

iCalendarファイルは単純なテキストファイルなので、その気になれば一行一行書き出す処理を書いて作ることもできそう。

https://developers.worksmobile.com/jp/document/1007011?lang=ja

PythonでiCalendarファイルを読み書きできるライブラリがあるのでこれを使ってみる。

https://pypi.org/project/ics/

[クイックスタート](https://icspy.readthedocs.io/en/stable/)を見ながら試してみる。

まずはファイルの書き出しから。

```python:ics_write.py
from ics import Calendar, Event
import arrow

# カレンダーの生成
cal = Calendar()
cal.creator = 'Me' # 作成者

# イベントの生成
event1 = Event()
event1.name = "A社と打ち合わせ" # タイトル
event1.begin = arrow.get("2021-11-08 12:00:00" ,"YYYY-MM-DD HH:mm:ss").replace(tzinfo="Asia/Tokyo") # 開始
event1.end = arrow.get("2021-11-08 13:00:00" ,"YYYY-MM-DD HH:mm:ss").replace(tzinfo="Asia/Tokyo") # 終了
event1.description = '○○について\n××について' # 説明
cal.events.add(event1) # カレンダーにイベント追加

event2 = Event()
event2.name = "有給休暇"
event2.begin = arrow.get("2021-11-10 00:00:01" ,"YYYY-MM-DD HH:mm:ss").replace(tzinfo="Asia/Tokyo")
event2.end = arrow.get("2021-11-11 23:59:59" ,"YYYY-MM-DD HH:mm:ss").replace(tzinfo="Asia/Tokyo")
cal.events.add(event2)

print(cal.events)

with open('my.ics', 'w', encoding='utf-8') as f:
    f.write(str(cal))
```

注意点としてそのまま日時をセットするとUTCで扱われるのでタイムゾーンを指定している。

```
python ics_write.py
{<Event '有給休暇' begin:2021-11-10T00:00:01+09:00 end:2021-11-11T23:59:59+09:00>, <Event 'A社と打ち合わせ' begin:2021-11-08T12:00:00+09:00 end:2021-11-08T13:00:00+09:00>}
```

出力されたファイル。

```my.ics
BEGIN:VCALENDAR

VERSION:2.0

PRODID:Me

BEGIN:VEVENT

DTEND:20211111T145959Z

DTSTART:20211109T150001Z

SUMMARY:有給休暇

UID:f95dbfd9-5b65-4feb-93d9-8fb85221e14e@f95d.org

END:VEVENT

BEGIN:VEVENT

DESCRIPTION:○○について\n××について

DTEND:20211108T040000Z

DTSTART:20211108T030000Z

SUMMARY:A社と打ち合わせ

UID:529095df-3716-4f78-ada7-485cbf1456a7@5290.org

END:VEVENT

END:VCALENDAR
```

Googleカレンダーに取り込んでみるとちゃんと予定が反映されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96507/319dd47d-def6-d5f1-4ca5-1cf4d9404d1f.png)

次にファイルの読み込み。

```python:ics_read.py
from ics import Calendar

with open('my.ics', 'r', encoding='utf-8') as f:
    ics_str = f.read()

cal = Calendar(ics_str)

print(cal.events)
```

```
python ics_read.py
{<Event '有給休暇' begin:2021-11-09T15:00:01+00:00 end:2021-11-11T14:59:59+00:00>, <Event 'A社と打ち合わせ' begin:2021-11-08T03:00:00+00:00 end:2021-11-08T04:00:00+00:00>}
```

読み込み時もUTCになってしまうのでそこのケアが必要。

その他細かいライブラリの仕様も公式ドキュメントに書かれてる。

https://icspy.readthedocs.io/en/stable/api.html
C#：条件文

- if文
    - それが正しいかどうか判定する　trueかfalseで判定
        - if(条件となるもの) { 正しい時に実行する処理内容 }
        - else if(条件となるもの) {正しい時に実行する処理内容} //必須ではない
        - else {上記の条件に当てはまらない場合の処理内容} //必須ではない 記載は一つまで
        
    - 条件の作り方
        - 基本的に比較演算子で作成
        - A == B, A != B, A > B, A >= B, A < B, A <= B
        
    - 偶数か奇数かの判断方法
        - x = 6の場合　条件分を x % 2 == 0 とする。
        
    ```csharp
    //[if文]
    
    /* if(条件となるもの trueかfalseで判定できるもの)
    {
      正しい時の処理
    }
    else
    {
      正しくない時の処理
    }
　*/

    
    //例
    int x = 12345;
    string s = "「" + x + "」は、";
    
    if(x % 2 == 0)
    {
      //変数宣言を上記ではなくここですると変数宣言範囲によりエラーが起きる
      s += "偶数です。";
    }
    else
    {
      s += "奇数です。";
    }
    Debug.Log(s);
    ```

- switch文
    - 複数の分岐を作るときに使用
        - switch(チェックする値){case 値:   処理内容  break;}
        - 処理内容の後にはbreak;をつける　つけない場合は、caseが一致したところから、break;がある部分まで、処理が実行される。
        - 最後はcase 値の部分を default にする　不要ならばつける必要はなく、caseが見つからなければ実行せず構文を抜ける。
        
    


    ```csharp
    //[switch文]
    int month = 1;
        string s = "「" + month + "月」は、";
    
        switch (month)
        {
            case 1:
                s += "睦月";
                break;
            case 2:
                s += "如月";
                break;
            case 3:
                s += "弥生";
                break;
            default:
                s += "何だかわからない";
                break;
        }
        s += "です";
        Debug.Log(s); //「1月」は、睦月です
    ```
【Flutter×FirebaseAuth】email認証が完了したら画面遷移する方法

# はじめに
最近した業務でFirebaseAuthのEmail認証が完了したタイミングで画面遷移をする必要があり方法がわからなくて困ったため私と同じように困っている方のために残しておきたいと思います。


# 結論
 - FirebaseAuthの`currentUser`に用意されている`reload`関数を毎秒実行することで解決しました。
 
:::note warn
2021/11/7時点の情報のため、FlutterやFirebase関連のバージョンにより実装方法が大きく変更されることがございます。
:::


# なぜFirebaseAuthのauthStateChangesを使わなかったのか
### authStateChangesを使わない理由
@tsuzuki817 さんから質問頂いたので追記

* トリガーが発火する条件が以下にあり、メール認証をしたかどうかをリアルタイムに検知できないため
 
[FlutterFireより引用](https://firebase.flutter.dev/docs/auth/usage/#authentication-state)

> Events are fired when the following occurs:
> ・　Right after the listener has been registered.
> ・　When a user is signed in.
> ・　When the current user is signed out.

[GitHubのissueより引用](https://github.com/FirebaseExtended/flutterfire/issues/6403)
> The stream is not expected to fire when the user is verified. You can read what each of the streams do from the documentation here:
https://firebase.flutter.dev/docs/auth/usage#authentication-state


# 執筆時の環境
- Flutter2.5.2
- `flutter_riverpod`を使用

# 前提

- Flutter web
- Firebaseの設定が完了していること。
- FirebaseAuthの`sendEmailVerification`メソッドが実行されていてメール認証が未完了であること。


# 実装方法
### View


```:dart(最初の画面)
class SamplePage extends ConsumerWidget {
  const SamplePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final model = watch(sendEmailModelProvider);
// emailVerifiedがtrueへ変わったらSampleSecondPageへ遷移
    if (model.emailVerified == true) {
      return const SampleSecondPage();
    }
    return const Scaffold(
      body: Center(
        child: Text('最初の画面'),
      ),
    );
  }
}

```
### ViewModel
毎秒実行している処理を`timer.cancel()`で止めないと遷移後も遷移前の最初の画面で実行し続けてしまうため、今回は`emailVerified`が`true`になったらcancelしています。

```:dart
final sampleModelProvider =
    ChangeNotifierProvider((_) => SampleModel()..timerReading());

class SampleModel extends ChangeNotifier {
  bool emailVerified = false;

  // 毎秒reload関数を実行してAuthのemailVerifiedの状態を監視している
  void timerReading() {
    Timer.periodic(const Duration(seconds: 1), (Timer timer) async {
      await FirebaseAuth.instance.currentUser!.reload();
      emailVerified = FirebaseAuth.instance.currentUser!.emailVerified;
// emailVerifiedがtrueに変更されたタイミングで毎秒処理を止めています。
      if (emailVerified == true) {
        timer.cancel();
      }
      notifyListeners();
    });
  }
}


```

# 参考にしたサイト
 
[FlutterFire](https://firebase.flutter.dev/docs/auth/usage/)
[Timer.periodic constructor](https://api.flutter.dev/flutter/dart-async/Timer/Timer.periodic.html)
今までの流れ


今までの流れ（アプリ開発）
１バックエンドの導入<a>（支援者あり）<a href="https://twitter.com/jackpot__hide">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2231259/2d935ccd-a74a-16c3-8b7e-e68182576c07.png)

スマホでweb開発できるようなバックエンドシステムを借りてプログラムを勉強しはじめました。

２html css javascriptの簡単な入力
<a>過去投稿<a href="https://qiita.com/_7L_7l_22/items/cf124011dc93e6ceb362">

のような形で勉強をつづけました。

３必要な情報の検索とコードの追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2231259/6d18bea3-7698-f5e0-eb3a-cc135e41a4d9.png)


４CSSの学習（メニュー、キャンバス、プルダウン）

５開発環境の設置（terminal ubuntu)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2231259/fb1690b0-8064-8100-2e66-fc32cdca3bd3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2231259/3a9f63cf-b8a7-8d8b-39a5-c09ee80e8fa1.png)


６サーバーの設置(php)←いまここ
フォームを使い出力するためにPHPの導入をしpythonで機械学習と分析のために
若干進歩？してきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2231259/14d65ae4-7016-41df-f9bb-db602f9ff1c2.png)