Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all 21655 articles
Browse latest View live

初めてiOSアプリにとりかかるデザイナーさんへ、私(エンジニア)が楽するためのお願い

$
0
0

はじめに

今回はiOSアプリの開発で、私(エンジニア)がデザインをコードに落とし込む際、どういう解釈をするのかを知ってもらいよりスムーズな開発が行えるようにしたいという目的です。
私がいろいろなプロジェクトでいろいろなデザイナーさんとやりとりしながら感じた、勘所、かゆい所を共有したいと思います。
ここでは、いわゆるiOS HIG(ヒューマンインターフェースガイドライン)を踏まえた上で現場でよく使う用語、役にたった作り方やルールを記載しますので、HIGから学びたい方は、まとめやAppleの公式ページを参照することをおすすめします。
また、文字読むのが苦手な人は、iOSの純正アプリ(AppStoreだけ少々奇抜な気がしますが。)をじっくり見てみることをおすすめします。

iOS Human Interface Guidelines
https://developer.apple.com/design/human-interface-guidelines/ios/overview/themes/

お願いしたいこと

よく使うiOSのレイアウト用語を知ってください

ステータス/エリア、バー Status/Area, Bar

スクリーンショット 2020-02-04 16.22.35.png
端末上で時間や通信情報、バッテリー情報を表示している場所です。
大きく、表示・非表示LightMode・DarkModeをコントロールできます。
アプリケーション全体を通しての設定を一括で行うのが基本ですが、この場合、後述のナビゲーションエリアの色によって自動でステータスエリアの色(light or dark)が決められたりするので、少々実装コストはかかりますがページごとに色をコントロールすることもできます。
色以外のレイアウトを変更することはできません。

ナビゲーション/エリア、バー、タイトル、ボタン、遷移 Navigation/Area, Bar, Title, Button, Transition

NavigationBar_2x.png
基本的にはステータスエリアの下にくっつけて配置され、ページのタイトルや戻るボタン、完了ボタンや検索ボタン等、が置かれている場所です。
スマートフォンのUIは1ページで多くの情報を表示するために画面をスクロールさせますが、このナビゲーションは常に最前面に配置されており、画面のスクロールの影響を受けません。
これにより、スクロールして情報が変わっても、画面として普遍なものを配置することが多いです。(余談ですが、これを壊してきたのがTwitter等のアプリで、スクロールに応じてナビゲーションエリアに配置されたものや、文字が変わっていくというギミックを取り入れました)
iOSが用意するNavigationには、いくつか制約があり、ガイドラインに沿った実装は簡単に行えるのですが、少し凝った実装をすると独自に作ったNavigationを使用することになり、トータルの実装コストが上がります。
これはiOSが用意してくれているNavigationがデフォルトでいろいろな機能を実装してくれている(特に遷移の管理)ので、そちらの機能を自前で実装しないといけなくなるからです。

タブバー/エリア、ボタン TabBar/Area, Button

TabBar_2x.jpeg
最下部にあるボタンが均等に横並びになっている場所です。
デフォルトだと、アイコンと文字が縦並びになったボタンがセットになっており、均等に配置されていて、選択・非選択状態の色も自動で割り当てられます。
背景色、高さ、ボタンサイズ、選択状態の色・画像、タイトルの有無・色・位置・フォント、それぞれ変更可能です。
タブバーのシステム的利点は、タブバーでの画面遷移は他のタブの状態が保持されている、というところにあり、タブを繰り返し切り替えても、タブごとに同じ画面が表示されます。

セーフエリア SafeArea

e5aca39a-f9a2-4ab8-9f45-08fd95fb845c.png
iPhone,iPad端末は上部にノッチがあったり、時間や通信情報を表示していたり、下部にセンターボタンがあったり、HomeIndicatorがあったりします。
そこで、アプリケーションのコンテンツを表示していい領域を、全端末共通でわかりやすく区切った範囲がこのセーフエリアとなります。
端末によってセーフエリアの見た目は違うのですが、例えばシステム上でセーフエリアの左上から座標を指定すると各端末に合わせた位置に配置してくれるようになるわけです。
セーフエリア自体は外すこともできますが、設定されている場合、デフォルトでは前述のステータスエリアやHomeIndicatorが省かれたエリアになっていますが、ナビゲーションバーをおいたり、タブバーをおくと、そこが省かれたエリアに設定されます。
例えば、ナビゲーションバーを半透明にし、裏でスクロールしているアイテムが見えるようにしたい場合、セーフエリアをステータスエリアまで狭める必要があるわけです。

*SafeAreaは言葉や1枚絵だけでは伝えづらいので、Appleやまとめの記事を参照してみてください。
SafeAreaについてまとめ
https://qiita.com/gentlejkov/items/a626263d452939378b07

テーブル/ビュー、セル Table/View, Cell

1eb44f8d-1907-4949-9208-f2fb7f3ffd1b.png
垂直方向スクロールしながら情報を表示することができるレイアウトです。
大きくセクションとセルという単位に別れており、セクションは大項目(図では[A][D]だったり、何も表示されていなかったり)、セルは小項目(図ではセクションとセクションの間の一つずつ)という認識で問題ないと思います。
テーブルビューはiOSのデフォルトで、かなり多くの便利な機能が実装されており、標準から切り離し独自で実装するのはものすごい実装コストが高いです。

コレクション/ビュー、セル Collection/View, Cell

50390428-f9f2-4cbc-bd99-1cacca4f0617.png
テーブルビューより自由にセルを配置でき、垂直、水平どちらにもスクロールして情報を表示することができるレイアウトです。
セクションとセルの概念はテーブルビューと同じで、こちらもiOSデフォルトで便利機能が盛りだくさんです。
テーブルビューもですが、不規則な配置であればあるほど実装の難易度があがります。不規則の代表例として、よくPinterestのTOPページのUIがあげられます。
根本的にテーブルビューより実装コストは高いです。

モーダル(遷移、 ビュー) Modal(Transition, View)

Modality_2x.jpeg
前の画面の上に覆いかぶさり、前の画面にユーザーが干渉できないビュー(遷移)というイメージです。
iOS13より、画像のようなモーダル表示を見かけるようになりました。今まで全画面のモーダルは、表示上、他の全画面ビューと変わらず、よく見かける特徴としては、左上に←という戻るボタンではなく×という戻るボタンが表示されており、遷移のアニメーションも下からにょきっと出てくるものが多かった印象です。
iOS13も遷移、戻るボタン等はほぼ同じですが、上部の隙間から前画面がのぞいてるように見える表現がデフォルトになりました。もちろん以前のように全画面表示も可能です。

レイアウトの際のパーツ(レイヤー)を意識してください

デフォルト

Action_Sheets_2x.pngActivity_View_2x.pngRefresh_Controls_2x.png
ここまでも度々使用してきたデフォルトという言葉ですが、iOSは実装する際にレイアウトから画像も含めて標準で備えている(デザインを用意する必要がない)ものがあります。
挙げるときりがないですが、ダイアログ、アクションシート、インディケーター等々、iOSの純正アプリで使われていることが多いです。
デフォルトの実装は軽度で、デフォルトから逸脱すればするほど実装が重度になります。
また、デフォルトのUIでも、色、形、位置の変更の難易度がそれぞれ違ったりします。慣れてくると、Appleのこういうニュアンスで使ってほしいという意志を感じ取って、そこからの距離感で実装難易度を予想することができます。
逆に、iOSの純正アプリが実装していることは、やってやれないことはないはずです。(稀に例外あり)

レイアウトのサイズ、座標

レイアウトのサイズ、座標は共に整数(可能であれば2の倍数)です。
スクリーンショット 2020-02-05 11.12.57 2.jpeg
レイアウトは座標をとりやすいように、サイズ、座標ともに配置してください。サイズに関しては透明な余白を設ける方法がよく使用されます。
モノ(オブジェクト)、レイヤーの単位を意識して配置してください。ステータスエリア、ナビゲーションエリア、テーブルビューのセル、左隣のボタン、上のテキスト、X軸の中央、Y軸の中央等々。特に頻出するテーブルビューはセル単位でレイアウトを配置するようにしてください。
2020-02-05 11.12.5.jpeg
1つのアプリケーション内の様々なページに頻出するレイアウトというものが出てくると思いますが、これはデザインでも実装でも同じく再利用する可能性があります。この再利用という単位を意識することが大事です。

ボタンのタップ領域

様々なボタンが出てくると思いますが、ガイドラインにある通り、ボタンのタップ領域は最低44x44ptじゃないといけません。
これは実際やってみるとわかりますが、指でストレスなく押せる最低限のサイズです。
また、ボタンが画像である場合、画像の切り出し方ですが、可能な限りタップ領域を考慮した切り出しをしていただけると助かります。
よく使われる手法は、表示しない部分は透明な状態で画像に組み込む方法です。

画像等リソースの管理を意識してください

命名規則

・フォルダ名、ファイル名は、以下2種類のみ使用します。

  • 半角英数字
  • _(アンダースコア)

・新しく画像を作成する際に命名に困ったら、私(エンジニア)に相談してください。

・命名の法則を決めて、共有してください。
参考:よく使っている画像の命名規則 -> ファイル名のルール
https://qiita.com/manabuyasuda/items/675586be79c4a8eebbfc

共有管理

・ツールによって画像のバージョン管理(変更履歴の管理)ができているなら問題ないが、画像の変更の伝達ミスを避けるため、日付(時間)のフォルダを作り、変更したものを入れて共有するとやりやすいです。

・画像のサイズは基本的に変更しないようにし、どうしても変更する場合は、私(エンジニア)に漏れなく伝えるようにしてください。

・例えばページの名前(ホーム画面、検索画面等)、パーツの名前等のモノの呼称はチームで共通認識化してください。

・画像の名前は変更しないでください。

・不要になった画像も管理してください(可能であれば認識し、私(エンジニア)に伝達してください)。

おわりに

今回挙げたいくつかの事柄には、デザインの幅を狭めるものがあると思います。
なので、あくまで私(エンジニア)が楽する、もとい開発速度を上げるための手法というのを念頭においてください。時間をかけても実現したいデザインがある場合には、これにとらわれる必要はないと思いますし、挑戦的なデザインは時間に余裕があれば大好物です。
この記事で全てを網羅しているわけではないので開発途中で必要に応じて認識合わせを行なっていくことが大事だと思います。
その際のベースの考え方となれば幸いです。

できあがったデザインを見て、レイアウトを把握して、そこに込められた意志を感じながら実装するのが好きです!


[React]テーブルのセルを結合する

$
0
0

概要

  • Reactで配列をループさせてテーブルを描画する
  • 特定の項目についてセルを結合させたい

作成イメージ

スクリーンショット 2020-02-05 15.01.31.png

  • 共通する項目についてセルを結合する

調べたこと

<tableborder="3"><tr><tdrowspan="3">垂直方向の結合</td><td>データ1</td></tr><tr><td>データ2</td></tr><tr><td>データ3</td></tr></table>

実装

  • 表示する配列
src/constants/GroupList.js
import{nogizaka,keyakizaka,hinatazaka}from"./Color";constgroupList=[{id:1,name:"乃木坂46",color:nogizaka.color,memberList:[{id:1,name:"齋藤飛鳥",age:21}]},{id:2,name:"欅坂46",color:keyakizaka.color,memberList:[{id:1,name:"渡邉理佐",age:21},{id:2,name:"小林由依",age:20}]},{id:3,name:"日向坂46",color:hinatazaka.color,memberList:[{id:1,name:"齊藤京子",age:22},{id:2,name:"小坂菜緒",age:17},{id:3,name:"上村ひなの",age:15}]}];exportdefaultgroupList;
  • 表示するコンポーネント
src/App.js
importReactfrom"react";import{Table}from"react-bootstrap";importstyledfrom"styled-components";importgroupListfrom"./constants/GroupList";constColorTr=styled.tr`
  color: ${({color})=>color};
`;functionApp(){return(<Tablebordered><thead><tr><th>グループ</th><th>名前</th><th>年齢</th></tr></thead><tbody>{groupList.map(group=>group.memberList.map((member,i)=>i===0?(<ColorTrkey={member.id}color={group.color}><tdrowSpan={group.memberList.length}>{group.name}</td><td>{member.name}</td><td>{member.age}</td></ColorTr>):(<ColorTrkey={member.id}color={group.color}><td>{member.name}</td><td>{member.age}</td></ColorTr>)))}</tbody></Table>);}exportdefaultApp;

行ったこと

  • 配列の個数を結合させる行数としてrowspanの値に設定
src/App.js
<tdrowSpan={group.memberList.length}>{group.name}</td>
  • ループさせる配列のインデックスをとり、先頭行の場合(インデックスが0の場合)とそうでない場合を分岐
src/App.js
{groupList.map(group=>group.memberList.map((member,i)=>i===0?(<ColorTrkey={member.id}color={group.color}><tdrowSpan={group.memberList.length}>{group.name}</td>      // 省略
      </ColorTr>):(   // 省略)))}

終わりに

  • とりあえず実現してみたけど何だか冗長・・・
  • もっと良い方法をご存知の方いましたらコメントください

余談

本題とは全く関係ありませんが、今回使用したカラーコードはそれぞれ以下を参考にしています。

JPPUG758 #4 Power Apps Q&A補足

$
0
0

Japan Power Platform User Group 名古屋 #4に参加・登壇してきました。

Japan Power Platform User Group 名古屋 とは?

Power Platform の仲間である、Power BI、Power Apps、Power Automate(旧 Microsoft Flow)のコミュニティ勉強会が名古屋には各々存在しておりました。

 ・Power BI 勉強会@名古屋支部/ハッシュタグ #PBIJP758
 ・PowerApps + Flow アプリ作成研究所 in 名古屋/ハッシュタグ #EasyApp758

はじめに誕生したのは Power BI 勉強会@名古屋 で、調べてみると2018年2月に勉強会を実施しています。当時のコンパスはこちらですね。当方、初の勉強会主催でした。

その後、東京で Power Platform User Group (略称 JPPUG)が誕生して、強力なコミュニティとして発展してきました。昨年の Ignite で Power Virtual Agents が新たに加わり、さらに勢いが加速していることを感じた名古屋の運営メンバー。相談した結果、装いも新たに「Japan Power Platform User Group 名古屋(略称:JPPUG758)」として再発進をすると決めました。冒頭の勉強会は、その記念すべき第1回(EasyAppとしては4回目なので、#4)です。

この記事は?

前述、JPPUG758 #4 で当方が担当したセッションについての補足です。セッション内容は「参加者皆さんの困ったをその場で解決する(カモ?)」というテーマです。最終セッションだったのですが、それまでに Sli.do でQ&Aも集めていたので、それもまとめて運営や参加者の皆さんと協力して回答しました。そんなセッションのなかで「当方が回答した内容を少し補足しておこう」という試みです。
”実はよくわからなかった”状態で帰ってしまった参加者の方々の一助になれば幸いです。

JPPUG758 #4 QA補足

さて、本題のQ&A補足です。

Power Apps の有償ライセンス

下記URLへアクセスいただくと価格が把握できます。

https://powerapps.microsoft.com/ja-jp/pricing/

「単一アプリの実行」と「無制限のアプリの実行」の2種類が存在しています。注意点としては「単一アプリの実行」ライセンスでは”2つのアプリと1つのポータル”しか作れません。詳しくは、提供企業の営業さんなどにご確認をお願いします。
利用するアプリと利用人数、データソースの種類によって組み合わせが変わりますので「よくわからん!」という方はお仕事としてサポート可能な方々へお問い合わせください(;^ω^)

委任の警告について

Power Apps で関数を書いた際に三角に!マークが出てくるアレです。「委任されない警告」です。まず、公式のDocsをご確認ください。データソース、および利用する関数や式によって委任される・されない、がありますので利用しているデータソースにあわせてリンク先を辿ってください。

キャンバス アプリでの委任について

Power Apps チャンピオンの @KodamaJnさんが書いた記事が非常にわかりやすいので、こちらもあわせて参照ください。(そして、勉強になったと思ったら”いいね”しましょうネ!)

PowerAppsで遭遇する5つの委任問題とちょっと強引な回避方法

非IT系の方だと「データ?委任(。´・ω・)?」となるかと思います。上記の”怒れるDB”の図がとても参考になるので、イメージだけでも持ってもらうと良いかと。

なお、記事投稿時点で、SharePoint Online の List をデータソースに利用した場合、参照列はほぼ必ず「委任されない警告」が表示されます。ご注意ください。

コンテキスト変数(ローカル変数) と グローバル変数

まず、こちらも公式Docsの紹介から。

変数の種類

プログラミング経験のある方であれば”スコープ”と言えば伝わるかと思います。しかし、Power Platform は市民開発者もアプリ作成ができる素敵な道具なので、全ての方が把握しているとは限りませんよね。ってコトで、スコープのイメージを簡単にイメージ化しましたので下記を参照ください。

image.png

 ・コンテキスト変数 = その画面だけで利用可能
 ・グローバル変数 = そのアプリ全体で利用可能

グローバル変数は便利な半面、別の画面で保持している値を変更されると全てに影響が発生します。チョッとしたミスで事故が起こる可能性がありますよね。そのため「コンテキスト変数で済むならソレを使う」という判断基準を覚えていただければOKだと思います。グローバル変数は、例えば「アプリ起動時間を全Screenで利用したい」などアプリ全体で必要なモノを格納する場所だと思ってください。※初学者向けの指針なので、中級者以上の方々は、各々の適切だと思う判断でどうぞ

コンテキスト変数を別の画面に渡せないの?

Navigate 関数を利用すれば実現可能です。

Navigate

image.png

Navigate(スクリーン名, 画面切替, {変数名:値})

よく考えると、グローバル変数で管理したい値は極限まで少なくできると思います。繰り返しになりますが「コンテキスト変数で済むのであればソレにする」という方針が基本です。

さいごに

後1つQ&Aを補足したいのですが、長くなってきたので次回をお待ちください!

今回の勉強会は、社内情報システム部門や個人事業主なども含めたエンドユーザーサイドの参加者が半数以上となり、運営側としては非常に感謝と感激をしておりました。名古屋のIT系勉強会は、参加者が同業者ばっかりになりがちなのです。このエンドユーザーの皆さんから頂戴した勢いを、今後も維持していきたいな、と強く思う次第です。

JPPUG758 として再出発しました!としていますが、コミュニティ勉強会としては以前とやってるコトはあんまり変わりませんw
そして、これからも不定期ながら名古屋を中心に中部地区で Power Platform に関するコミュニティイベントを計画していこうと考えております。興味のある方は、記事冒頭の Connnpass からメンバー参加いただければ幸いです!

それでは、皆さま。素晴らしい Power Platform Life を!

【PHP】配列を文字列(EDI情報)化

$
0
0

はじめに

EDI情報作成時に使ったロジックなので備忘録として残します。

サンプルコード

classTestA{publicfunction__construct(){$this->test1="00";$this->test2="          ";$this->test3="00";$this->test4="          ";$this->test5="GG";}publicfunctiongetTest1(){return$this->test1;}publicfunctionsetTest1($test1){$this->test1=$$test1;return$this;}・・・(省略)}classTestB{$test;publicfunctionbuild(){$this->setTest(newTestA());$test=$this->getTest();$testMessage='AAA'.'|'.$test->getTest1().'|'.$test->getTest2().'|'.$test->getTest3().'|'.$test->getTest4().'|'.$test->getTest5();var_dump($testMessage);}publicfunctiongetTest(){return$this->test;}publicfunctionsetTest(){$this->test=$test;return$test;}

var_dumpの結果

"AAA|00|          |00|          |GG"

【お手軽Python】pandasによるExcelファイル読み込み

$
0
0

pandasとは

pandasとは、Pythonのライブラリです。
pandasは、主にデータを操作する時に使われます。AIや機械学習にpandasは必須です。
ですが、Excelのファイルを操作する機能も搭載されています。
今回は、pandasを使ったExcelファイルの読み込みの仕方について説明していきます。

Excelファイル読み込み

最初のシートのみの読み込み

sample.xlsxの中身が
bandicam 2020-01-20 16-36-57-804.jpg
だった場合

main.py
importpandasaspddf=pd.read_excel('sample.xlsx')print(df)

上記のmain.pyを実行すると
bandicam 2020-01-20 16-44-46-679.jpg
となり、無事Excelファイルを読み込む事に成功しました。

全シートから読み込み

因みに、main.pyの二行目を

df=pd.read_excel('sample.xlsx',sheet_name=None)

とすれば、sample.xlsxの全てのシートからデータを取ってくる事ができます。

指定したシート読み込み

番号で指定

sheet_nameをNoneにすると、全シート読み込みとなりました。
sheet_nameに0から始まる番号を指定することで、[指定した数字+1]番目のシートを読み込むことができます。

df=pd.read_excel('sample.xlsx',sheet_name=0)#1枚目のシート読み込み
df=pd.read_excel('sample.xlsx',sheet_name=2)#3枚目のシート読み込み

名前で指定

sheet_nameに文字列を指定することで、その文字列をシート名に持つシートを読み込むことができます。

df=pd.read_excel('sample.xlsx',sheet_name='sheet1')#名前が'sheet1'のシート読み込み

まとめ

pandasを使ってExcelファイルを読み込む方法を紹介しました。
この機能はpandasの全機能の氷山の一角に過ぎません。

非常に様々な場面で使われるライブラリなので、気になった方は是非詳しいサイトなどを調べてみてください。

Rubyの基礎まとめ[メモ]

$
0
0

コーディングテスト用のメモ。

基礎文法

繰り返し

  • for
foriin1..3doputsiend

※配列でも可

fornumin[1,2,3]doputsnumend
  • each
[1,2,3,4].eachdo|num|pnumend
  • while
num=0#初期値whilenum<=12do#条件pnum#処理num+=3#値の更新end
  • times
3.timesdo|num|pnumend

各桁の和

a=11putsa.to_s.split('').map{|x|x.to_i}.inject(:+)#=> 2

条件分岐(書き換えパターン)

  • pattern(1)
s="hoge"ifs==hogeputs"YES"elseputs"NO"end#=>YES
  • pattern(2)
s="hoge"putss==hoge?"YES":"NO"#=>YES
  • pattern(3)
s="hoge"caseswhen"hoge"thenputs"YES"when"no_hoge"thenputs"NO"#=>YES

.gsub(パターンマッチング)

string="ruby ruby ruby"putsstring.gsub(/ruby/,'python')#=> python python python

配列の操作

配列の割り算

a=[2,4,6]b=a.map(|x|x/2)putsb#=> [1, 2, 3]

配列の合計

a=[1,2,3]putsa.inject(:+)#=> 6

奇数or偶数番目要素の取得

ary=('a'..'j').to_a#=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]# 偶数番目ary.select.with_index{|_,i|i.even?}#=> ["a", "c", "e", "g", "i"]# 奇数番目ary.select.with_index{|_,i|i.odd?}#=> ["b", "d", "f", "h", "j"] 

並べ替え

ary=[2,4,1,5,3]# 昇順 ary.sort#=> [1, 2, 3, 4, 5]# 降順ary.sort.reverse#=> [5, 4, 3, 2, 1]

重複要素を統一

ary=[1,2,2,3,3]ary.uniq#=> [1, 2, 3]

配列→文字列

ary=[1,2,3,4,5]ary.join(' ')#=> '1 2 3 4 5'

要素の追加

ary=['a','b','c']ary<<'d'#=> ['a', 'b', 'c', 'd']

テクニック

メソッドを定義

defmethod(n)n+=1endmethod(3)#=> 4

"色違いポケモンシミュレータ"

$
0
0

乱数を使う練習①
アイテムなしで色違い孵化厳選を行った場合のシミュレーション

import java.util.Random;

public class Irochigai
{
public static void main(String[] args)
{
System.out.println("色違いシミュレータ");

    Random r = new Random();
    int randomValue = r.nextInt(4096);

    if (randomValue == 4096) {
        System.out.println("Irochi");
    }
    else {
        System.out.println("normal");
        }
    System.out.println(randomValue);
}

}

Ruby 変数に格納された文字列の開始文字数と終了文字数を指定して表示する

$
0
0

目的

  • 変数に格納された文字列の開始文字数と終了文字数を指定して表示する方法をまとめる

書き方の例

  • 下記に変数Aに格納された文字列を開始文字数と終了文字数を指定して表示する方法を記載する。

    puts変数A.slice(開始文字数..終了文字数)

より具体的な書き方の例

  • 変数todayに格納された文字列の0文字目から10文字目までを表示する方法を記載する。

    today="2020-02-04 09:01:35"putstoday.slice(0..10)2020-02-04

while構文

$
0
0

while構文

繰り返す条件を作るための初期化処理
while (繰り返す条件){
  繰り返したい処理
  更新処理
}

↓↓↓↓↓

$i = 1;
while ($i <= 365){
     print $i . PHP_EOL;
     $i = $i + 1;
}
  • 一番重要なところは「繰り返す条件」($i <= 365)
    • ◯◯が△△になったら繰り返してください、◯◯が△△ではなくなったら繰り返しをやめてください、といった条件を記述する
    • 上記の場合は『$iという変数の内容が365以下の間繰り返す』と言った条件になっている
  • $iは最初どういう状態なのか?
    • 「初期化処理」$i = 1;の部分で行われる
    • $i = 1として数字の1を代入しているので、最初の$iの状態は 1 であることがわかる
    • while構文の条件である『$iが365以下』に該当するので、while構文の中括弧に入って「繰り返したい処理」が行われる
    • while構文は「繰り返したい処理」が終わると、元の部分に戻るという性格がある
    • $iが365以下の場合は、画面に数字が表示された後、またwhile構文に戻ってくる
    • ここで更新処理を書かないと、$iには1が代入されたままとなり無限ループとなってしまう。
  • 更新処理
    • 繰り返す条件に使っている変数などは、最終的に条件から外れるような計算などを行う必要がある
    • 「更新処理」$i = $i + 1;
      • $i$i+1を代入する。
    • 1 を画面に表示した後、$iには1+1である 2 が代入される
    • またwhile構文の最初に戻るので$iが365以下であることは変わらないが、$iの内容自体は変わっている。(1が2になっている)
    • 2 が画面に表示された後、$iは2+1である 3 が代入される
      • 3が画面に表示されて4・・・5・・・6と1ずつ増えていく
    • 364が画面に表示された後、365になった$iのままwhile構文に戻る。
      • 条件は「365以下」なので365も含まれる
    • 画面には365と表示され、$iが366になった後while構文に戻るが、この時点で条件から外れる。
    • 画面には365が表示されて処理が終わる。(条件から外れたので)

※参考:Udemy/Webサーバーサイドプログラミング入門

jQueryの次にJavaScriptを学びはじめたキミのための記事!

$
0
0

記事の目的

この記事は、プログラミング初学者の中でも、
HTML → CSS → jQuery と学んできて、次のステップとしてJavaScriptを学び始めた人が、
技術的な話の前に知っておいたほうが助かりそうな事情や背景をまとめた記事です。

JavaScriptをちょっと初めてみたけど、よくわからん!と混乱しているタイミングで、読んでいただけたらと思います。

「そんなことわかってるよ」と言いたくなるような初歩的な説明もあると思うので、読み飛ばしていただければと思います。

執筆者もプログラミング歴1年程度の初心者なので、知識の浅い部分があります。
また、初心者ながらJavaScriptを学んでしばらくたっているので、当事者目線からずれた説明をしてしまう部分もあるかもしれません。
そのため、この記事のコメント欄で、ターゲットとなる当事者の方や、執筆者よりも博識な方などから、
いろいろな意見を頂きながら成長していくコミュニティにしたいと思っていますので、ご協力よろしくおねがいします!

jQueryの立ち位置

そもそも、HTML、CSS、jQuery、JavaScriptというのは、何が違くて、どういう風に活躍する言語たちなんでしょうか。

HTML・CSSの立ち位置

HTMLは、WEBサイトの構成を表すための言語です。
<head>では主に、WEBサイトの構成に必要な設定の記述や、ファイルの読み込みを行い、
<body>では主に、どんな構成で要素を配置していくかを表します。

CSSは、WEBサイトのデザインを表すための言語です。
HTMLで配置した要素を、どんなデザインでユーザーに見せたいか記述します。

この2つは、jQueryやJavaScriptと違ってプログラミング言語ではありません。
プログラムというのは、機能的な処理をするものの事ですが、
この2つは書いたとおりに表現をしてくれるものですので、マークアップ言語と呼ばれ、違うものとして考えるのが一般的です。

ただし近年では、HTMLやCSSだけでもある程度機能的な部分を実装できるようになりつつあります。
例えば、HTMLだけで入力欄入力された文字のチェックをすることも出来ますし
CSSだけでハンバーガーメニューの実装をすることなど出来ますね

このように、HTMLやCSSだけで出来ることについて深く知ることは、
過度にJavaScriptやjQueryへ依存してしまわないためには必要なので、
どんどん情報収集した方がよいと思います。

JavaScriptの立ち位置

JavaScriptは、WEBサイト上(=ブラウザ上)で動かすことができるプログラミング言語です。
プログラミング言語って、つまりどんな事ができるの?という話をしだすとキリがないのですが、
要は、HTMLとCSSだけでは出来ない事は、全てプログラミングで実装していると理解していればオッケーです。
そして、そのように何でもできる技術だからこそ、何でもできるようになるためには、沢山の知識が必要になります。
(ブラウザ上で動くJavaScriptの他にも、サーバー上で動くサーバーサイドのプログラミング言語も存在するので、
 全てJavaScriptという訳ではないのですが、それはもう少し先のお話になります。)

jQueryの立ち位置

jQueryは「JavaScriptでWEBサイトの見た目や動き方を指定したいけど、あまり深い知識まで学んでいられない人」とか、
「できるだけわかりやすく書きたい人」とか、「パパっと仕上げたい人」のために作られた仕組みです。
HTMLとCSSだけでは出来ない事を、簡単に実装したい人のための仕組み、と考えてもいいです。

実は、見た目や動き方だけではなく、もっと機能的な処理も簡単に実装できるようにと作られている機能もありますが、
本記事を読みたいと思う方で、そういうところまで使いこなしている方は少ないと思うので、深くは触れません。

jQueryって何なんだっけ?

jQueryとはどういうものか、についての説明です。
jQueryを学んだ際にも同じような話を聞いたかと思いますが、再び思い出してみて、より深く理解しましょう。

jQueryは、JavaScriptのライブラリ

jQueryは、JavaScriptのライブラリです。
ライブラリとは、まとまった機能を切り出して、再利用できる形に保存してあるコードのことです。

CSSで例えるならば

ライブラリ.css
.button{borde:1pxsolidblack;border-radius:5px;}

という内容のファイルを作成して、これをHTMLの<link>タグで読み込んで、
このデザインを適用したいボタンにclass="button"と指定してあげれば、
いつでもボタンを同じデザインに統一することができますよね。
JavaScriptで、これと同じような事をしたものがライブラリです。

つまり…

jQueryでやっている事は、JavaScriptでやっている。

jQueryはJavaScriptのライブラリという言葉の真意は、
jQueryの中身はJavaScriptで書かれているということであり、
jQueryでやっている事は、JavaScriptでやっている。
という事になります。

jQueryの中でJavaScriptも使える。

違う言い方をすると
jQueryの中でJavaScriptをバリバリ使ったプログラムを書いていくことも可能ということです。
というよりも、なんなら既にバリバリ使っていると思います。
簡単なところで言うとvarletを使った変数宣言や、=を使った変数への代入、
forforEachなどを使ったループ処理、ifをつかった条件分岐などもそうですね。
jQueryのメソッドではない部分の処理は、すべてJavaScriptの処理だということです。

そうは言っても、jQueryとJavaScriptが同じ書き方には見えない、という方も居るかもしれませんね。

jQueryの独特な書き方について

jQueryが本来のJavaScriptと違った書き方をしているように見えるなら、それはjQueryが以下の仕組みを積極的に使用しているからだと思います。

  1. 「\$」という名付け
  2. メソッドチェーン
  3. コールバック関数

これらの詳しいところは、JavaScriptについて分かってきた後に、やっと理解できるようなレベルの話だったりしますが、
現時点で知っておいた方がいい要点だけ、説明させていただきます。
(わりと長い説明になってしまうので、理解できなければ飛ばしても構いません。)

「$」という名付け

jQueryの使用を開始するために使う$( function() { ...という書き方や、
jQueryでHTMLの要素を操作するために使用する$('セレクタ')という書き方など、
jQueryを使用する場合では頻繁に目にする「\$」という文字があります。
$()ではなくjQuery()と書くことでもjQueryを使う事ができるので、
 そちらの書き方のイメージが強い方であれば、飛ばしていただいて構いません。)

この「\$」はjQuery独特の書き方に感じるかもしれませんね。
しかし、JavaScriptのプログラムにおいて「\$」という文字に特別な意味はないという事を覚えといてください。
「a」「b」「c」と同じように、普通に使えるただの文字です。

そうは言っても、人間から見れば特殊な文字なので、
大半のプログラマーは、特別な理由がない限り「\$」という文字を名前に使うことはありません。

jQueryを使っているという、特別な理由がある場合じゃないと使わないような文字なので、
かなり独特に見えるとおもいますが、要はただの変わった名前でキラキラネームみたいなものです。

メソッドチェーン

$('ooo').hide()$('xxx').val()のように、処理を続けて書くような書き方をメソッドチェーンと呼びますが、
これもJavaScriptの学び始めではなかなか見かけないかもしれません。
しかし紐解いて分析してみると、なんてことのないJavaScriptの標準的な使い方だと気づくことが出来ます。

JavaScriptにはオブジェクト型というデータ型がありますね。複数のデータをまとめて保管できる便利なデータ型です。
(学習環境によっては連想配列だとかObjectオブジェクトという呼び方で学んだ人もいるかもしれませんが、どれも同じものを指しています。)

オブジェクト型のデータが持っている中身のデータから、あなたが選んだ一つのデータ(=任意のキーの値)を取り出したい場合、
オブジェクト.データのように、.で区切って記述します。
(本来、オブジェクトというのは、もっと色んなものを指す言葉なので、そこは誤解されないよう注意してください。)
そして、このデータに入る値が、文字列や数値などではなく関数だった場合、
実行するにはオブジェクト.データ()と書きます。

そうです。jQueryで使われる$('引数')がオブジェクトなら、
$('引数').データで、中身の関数を実行することができるのです。

え?
$()はオブジェクトじゃなくて関数だろうって?
鋭いですね。

次に必要になる知識が関数の戻り値(返り値)という概念です。
関数を実行すると、関数の中で設定した戻り値(=returnの値)が、その関数の位置に置き換わります。
(JavaScriptの学びはじめだとreturnは処理を終了させるための記述だと教えられる人もいるかもしれませんが、
 それはあくまで副作用です。本来は、戻り値を指定することが目的の記述になります。)

では、$という名前の関数を作って、戻り値にshowという名前の関数が入っているオブジェクトにした場合は…?
そう、$().show();と書いてあげることで、$()の戻り値に入っているshowという関数データが実行される事になります。

では、$()という関数に、引数を渡してあげると…

$('引数').show();

なんということでしょう。
一見、見慣れないプログラミング言語かのようだったJavaScriptが、
匠の手によって、jQueryと同じような記述に生まれ変わりました。

jQueryは、引数として渡された文字列(セレクタ)を、いい感じに処理した上で、
jQueryメソッドと呼ばれる関数を持っているオブジェクトを戻り値にしてくれているんだと、
なんとなくイメージできたでしょうか?
(ちなみに、メソッドというのは、オブジェクトや関数などの、何かの中に入ってる関数という意味です。)

jQueryが、きちんとJavaScriptで出来ていることがわかってきたかと思います。

コールバック関数

最後に説明するのは、
jQueryをはじめる際に現れる
$( function(){ ...という書き方についてです。

これはコールバック関数と呼ばれる使い方で、調べると結構ややこしい情報がでてきたりしますが
今回の説明に限っていえば簡単なことです。

JavaScriptは、基本的には上から順番に処理を実行してくれるので、
関数の中の、特定のタイミングで別の処理を実行させたい場合の書き方は、下のようになります。

function(){//事前の処理ooo();//事後の処理}

しかしこの書き方には、この関数を定義するよりも前にooo()を定義しておかなければならないという弱点があります。
それを回避するために、引数に関数を渡すという策があります。

function(xxx){//事前の処理xxx();//事後の処理}

こうする事で、引数に渡された関数が、jQueryの都合のいいタイミングで実行されてくれるのです。
つまり、$()の引数に、関数を渡しているのが、$( function(){ ...の正体だということです。

まとめ

ちょっと長い説明になってしまいましたが、結局何が言いたいかというと、
jQueryは、JavaScript学び始めの段階ではまだまだ使い慣れていない仕組みを積極的に使用しているせいで、
なんだかJavaScriptとは違う書き方をしているように見える事があると思いますが、
全てJavaScriptでも使われる書き方だと言うことです。

jQueryが皆に愛された理由

次は「とりあえずjQuery」と言われるほどに、
jQueryが皆から愛された理由について説明します。
これは、次の章にも関連する内容になります。

ブラウザ間の動作の違い

JavaScriptはブラウザ用のプログラミング言語です。
ブラウザとはInternetExplorerEdgeSafariGoogleChromeFirefoxなどのインターネットを見るためのアプリですが、
これらのアプリの中身は別々の人達が作っているのでJavaScriptはブラウザごとに細かい動作の違いがありました。
(ブラウザ用の言語でなくても、WindowsMacなどのOSによって動作が違う言語はあるようなので、JavaScript特有の問題というわけではないかもしれませんが。)

「細かい動作の違い」と言いましたが、jQueryが流行った当時は、無視できないくらい大きな違いだったそうです。
単純な処理を実行したいだけなのに、ブラウザの数だけ条件分岐した処理を書かなければいけないとしたらどうでしょう?
趣味でやるなら「頑張れ〜!」で済む話かもしれませんが、仕事であれば時間に対して給料が発生していますので、
小さな処理でも何か書く度に何パターンも考えなければいけないなんて、たまったものじゃありませんね。

それをjQueryは、あらかじめそれぞれのブラウザで狙った処理になるようにまとめてくれているそうです。

以前のJavaScriptは、今より不便だった。

JavaScriptを最近学びはじめた人であっても「ES5」と「ES6」のバージョンの違いがあることはご存知かと思うので、
想像に容易いかと思いますが、
JavaScriptは日々進化し続けています。

それは裏を返すと、少し前の時代のJavaScriptはものすごく不便だったということです。
JavaScriptを駆使する「フロントエンドエンジニア」という職種も最近現れた職種だということからわかるように、
以前はJavaScriptで色々やるなんて想像もできなかったというか、
そこまでのパワーは無かったものだと思います。

jQueryから皆が離れはじめた理由

前章を受けて、そんなに愛されたjQueryから、なぜ人々が離れ始めてしまったのかについて説明します。

ファイルサイズの肥大化

JavaScriptと同じように、jQueryも時代とともに進化しています。
JavaScriptは元々ブラウザに組み込まれているものですが、
jQueryはライブラリという一つのファイルですので、
jQueryが進化するということは、jQueryのファイルサイズが肥大化するということです。
サイトで読み込むファイルのサイズが肥大化するということは、
サイトを表示するスピードが遅くなるということです。

読み込むだけで30秒とか1分とか遅くなるっていうことはないのですが、
jQueryの処理ひとつひとつもそんなに処理速度が早いわけでは無いようで、
jQueryの読込と処理の遅さに加えて、
低スペックスマホや通信速度の遅いフリーWi-Fiなどの環境問題、
さらにGoogleがページ表示速度の高速化を推奨しているなど、
いろんな要素が合わさることによって、ページの表示速度がかなり気にされる要素となってきています。

InternetExplorer離れ

先程の章でブラウザ間の動作の違いについて説明しましたが、
最近学びはじめた方からすると「そんなに違うか?」と思われたかもしれません。
これはなぜかというと、
ブラウザ間で最も動作が違っていたのが、InternetExplorerだからです。
今となってはWindowsの標準ブラウザはEdgeに変わったので、ほとんどの人は使っていないかと思います。

このInternetExplorerはCSSでも色々面倒な問題を起こしてくれていたブラウザですが、
同じようにJavaScriptにおいても、色々面倒な存在だったみたいです。

そのInternetExplorerが主要ブラウザの座から引退してくれたおかげで、
InternetExplorerの動作の違いを解決するためにやっていた色々なことが不要になり、たくさんのエンジニアが救われたそうです。
ただ、そうなると、その問題の解決をしたくて流行っていたjQueryは、必要のない処理が沢山記述されている重いライブラリ、という立ち位置になってしまうわけですね。
世知辛い世の中です…。

DOM操作系の充実

先程の章で以前のJavaScriptは、今より不便だった。と説明しましたが、
その最たるものが、皆様がjQueryで一番よく使われていると思われるDOM操作についての機能です。

DOM操作というのは、JavaScriptでHTMLの要素をいじったり、値を取得したりする処理のことです。
(HTMLをJavaScriptで扱えるデータに変換したものをDOMと呼ぶのですが、
 難しければ「DOMというのはHTMLのことだ」と思っていても問題ないかと思います。)

これ、jQueryじゃないと出来ないと思っていませんでしたか?
これは余談になるのですが、筆者が使っていた、とある学習サービスでは、
JavaScriptのレッスン中にDOM操作の方法を教えてくれるレッスンが存在していなくて、
最初はJavaScriptを学んでも「だから何?」という状態がしばらく続いていました。
jQueryを学ぶことで、はじめて「あ、これをうまく使えばサイトをいい感じに動かせるんだな」と理解したのです。
そのサービス自体は愛用させていただいてるので名前は伏せますが、同じサービスを使って勉強されている方は、
JavaScriptでDOM操作ができるという事実を知らないかもしれませんね…。

おっと、話が脱線しました。
以前のJavaScriptは、今より不便だったと言いましたが、
特に衝撃だったのがdocument.querySelectorAll()という関数の誕生だと思います。
(おそらくjQueryをリスペクトして作られた関数ではないかと予想します。)
「JavaScript DOM操作」とググっていただければ色々な記事がヒットするのでサラッとしか説明しませんが、
この関数の引数に、jQueryの$()と同じようにセレクタを指定してあげることで、指定した要素のDOMが取得できる関数です。

あとは、取得したDOMのプロパティを取得したり書き換えたりすれば、HTMLに関する処理はできちゃうというわけですね。
ぶっちゃけ、このDOM操作を普通に扱えるようになれば、
大体のアプリはjQueryを使わずに作成することができますし、
それが出来るようになれば「なんでjQuery使ってたんだっけ?」とも思うようになります。笑

仮想DOM操作ライブラリの誕生

と、ここまでjQuery離れをしている理由をいろいろ挙げてみましたが、実はこちらが大本命です。
この理由に該当しない案件であれば、まだまだjQueryが現役で使われまくっている事も珍しくはないです。

jQueryや、ライブラリを使わないJavaScript(=バニラJS)でDOM操作をする場合、
当然、なにかデータを書き換えたらHTMLに反映、という処理を繰り返しています。
細かく言うと、JavaScriptで1つ処理をする→HTMLに反映する→JavaScriptで1つ処理をする…という処理を延々繰り返しています。

しかし、近年現れたAngularReactVue.jsHyperappなどのライブラリは、
仮想DOMという仕組みを利用しており、JavaScriptの処理をまとめてする→HTMLに反映するという処理になっています。
これによって、もちろん処理速度が向上するといった裏側のメリットももちろんあるのですが、
仮想DOMで操作している最中に通常のDOM操作をしてしまうと、処理がおかしなことになる危険性を孕んでいます。

もちろん、HTMLに処理を反映しないような処理(テキストの取得など)であればjQueryを使用しても問題はないですが、
その程度の処理であればバニラJSのDOM操作で十分対応できますし、
上記ライブラリたちの特徴であるデータバインディング(JavaScriptのデータとHTMLの内容をリンクしてくれる機能)のおかげで、そもそもDOMを操作する必要すらない場面も増えました。

(さきほどから仮想DOM操作のライブラリと言っていますが、正確には一部はフレームワークと呼ばれています。
 この2つはJavaScriptにおいては規模感が違うだけなので、今は意識しなくて大丈夫です。)

実際に置き換えてみる

さて、ここまでjQueryを使う理由、使わない理由、JavaScriptとの違いなどの話をしてみましたが、
最後は実践的にjQueryをJavaScriptに置き換えて使ってみたいと思います。
これをマスターすれば、jQueryを使わなくても簡単にいろんな事が出来るようになりますよ!

エレメントを取得する

エレメントというのは、実際に取得したDOMひとつひとつのデータのことです。

document.querySelector系の関数

querySelector系の引数には、jQueryと同じように、CSSセレクタと同じ形の文字列を渡します。

document.querySelector();

セレクタにヒットするHTML要素がいくつあっても、最初の1つだけ取得します。
基本的には、1つしかヒットしないはずのものを取得したい時に使います。
例: document.querySelector('body');document.querySelector('#id');

document.querySelectorAll();

セレクタにヒットするHTML要素が入っている配列のようなものを取得します。
注意点として、要素がひとつしかなかったとしても、取得するのは配列のようなものなので、
実際にHTMLの処理をしたいときは、取得したデータの中身にアクセスして処理する必要があります。
例: document.querySelectorAll('div');document.querySelectorAll('.class');

document.getElement系の関数

document.getElement系の関数は、id属性やclass属性など、HTMLのどの属性から探して取得してくるかは予め決まっているので、
引数としては文字の部分のみを渡します。

document.getElementById();

指定した文字列と一致するid属性を持っている要素を取得します。
idは固有のものにするというルールがあるため、関数名はgetElementと単数形になっています。
例: document.getElementById('id');document.getElementById('menu');

document.getElementsByClassName();

指定した文字列と一致するclass属性を持っている要素が入っている配列のようなものを取得します。
classをはじめとする、id以外のものは複数ヒットする可能性があるため、関数名はgetElementsと複数形になっています。
例: document.getElementsByClassName('class');document.getElementsByClassName('icon');

類似する関数に、name属性の値で取得するgetElementsByNameや、
HTMLタグの名前で取得するgetElementsByTagNameもあります。

「配列のようなもの」について

先程がら太字にしている配列のようなものについてですが、なぜこのような言い方をしているかというと、
実際に配列と言っていいのは配列型のデータのみだからです。
(学習環境によってはArrayオブジェクトという呼び方で学んだ人もいるかもしれませんが、同じものを指しています。)

複数のデータが入っているとか、[]を使って任意のindex番号にアクセスできるところは配列と同じなのですが、
配列では使えるような、特有の関数が使えなかったりします。

また、querySelectorAllgetElements系の関数では
取得してくる配列のようなものの正体が違います。
querySelectorAll が取得してくる配列にはNodeListという名前がつけられており、
getElements系 が取得してくる配列にはHTMLCollectionという名前がつけられています。

この2つの違いについて調べると、HTMLCollectionは中身のデータがHTMLと連動しており、
NodeListは中身のデータは取得した時点で内容が固定されているという話が出てきますが、
こちらの環境でテストしてみたところ、NodeListの中身も、しっかりとHTMLと連動していたので、
最近は改善されたのか、もしくは実行環境によって動作が違うのかもしれません。

DOM操作してみる

お疲れさまでした。おもったより長文になってしまいました。
ここまで読み切ったあなたは、立派なJavaScript入門者です!

つぎは、実際にDOM操作してみましょう。
プログラミング言語を学ぶ上で大事なのは、実践です。

ブラウザの検証ツールのconsoleから、DOM操作系の処理を試してみてください。
この記事でできることの一例を挙げてみようと思ったのですが、出来ることが多すぎるので、ぜひGoogle先生に聞いてみてください。
プログラミング言語を使う上で大事なのは、検索です。笑

「JavaScript DOM操作」や「JavaScript DOM操作 やりたいこと」などで検索したら沢山ヒットするかと思いますが、
最終的に全てが載っているのはMDNのドキュメントになります。

[Python 入門] pandasを使ってみよう

$
0
0

[Python 入門] pandasを使ってみよう

前回の続きと改善していきたい点を紹介します。
さてこんな感じで図ができていました。
2020-02-06 (2).png
(前回は"matplotlib"の設定がわからず軸名に日本語が使えていませんでした。今回は修正したため、図の軸名が日本語で表示できています。)

さてもう少しこのデータで遊んでみましょう。前回の続きのコードとなります。

nikkei.corr()

とすると相関関係の表が得ることができます。

ax = sns.heatmap(nikkei.corr(), annot=True)

さらにとすればヒートマップというものを作ることができます。こんな感じ...
2020-02-06 (1).png

少ないですが今回のコード部分は以上です。

改善点と反省

技術的な面はさておき、なぜヒートマップを選んだ...というのが非常に大きな反省点ですね。
見てのとおり相関係数はほとんど1です。いったい何してるんだという感じですね。
こういうのは別の題材でやったほうがいいでしょう。
日経平均を題材としているのは、ただの好みです。改善点を含め次回以降できたらいいなというのを載せておきます。やるかどうかは未定ですが...

  • 日経平均をローソクチャートで表示する
  • NYダウもプロットしてみる
  • 回帰分析させてみる
  • 別の特徴量を加えてみる

などがあるでしょう。初心者レベルで内容は薄いですが、なんとか頑張って続けていきたいですね

Vue.js初心者がaxiosを利用しAPIを叩きデータを表示させるまで

$
0
0

はじめに

Vue.js は学習コストが低いと言われていますが初学者の方からしたら、
理解するのになかなか時間がかかってしまうと思います。
私も深く理解できているわけではありませんが、
これから紹介する書き方のみで
フロントのコーディングやアプリケーションを作る速さが格段にアップしたので、
この記事でVue.jsのコツを掴んでいただけたら幸いです。

Vue CLIのダウンロード

$ npm install -g @vue/cli

プロジェクトを作る

まずは以下のコマンドで vue のファイルを作ります。

$ vue create new-project

※この場合 new-project というディレクトリが作成されます。
スクリーンショット 2020-02-05 11.48.57.png
ファイルの内容をデフォルトで作るか自分でカスタマイズするか聞かれます。
今回は Router、 Vuex という機能を使うので
Manually select featuresを選択します。
スクリーンショット 2020-02-05 11.50.45.png
spaceキーRouterVuexを選択しEnterキーを押します。
以後も質問形式で設定を聞かれますが特にこだわりがなければ全て Enterキーで構いません。

$ cd new-project
$ npm run serve

http://localhost:8080/ このようなurlが出てきたら、
ブラウザからアクセスし以下のような画面が出れば準備完了です。
スクリーンショット 2020-02-05 17.09.31.png

Hello Worldを赤色で表示

早速Vueをいじっていきます。

Vue は単一ファイルコンポーネントでコードを記述するのが基本です。
以下のような形式を単一ファイルコンポーネントと言います。

<template></template>
<script></script>
<style></style>

見てわかるように
<template>には HTML
<script>には JavaScript
<style>には css
を記述していきます。

Home.vueの <template><script><style>の中身を全て削除し以下のコードを書きます。
templatehomeクラスタグのみ残しておいてください。
・スタイルタグは追加してください。

<template>
  <div class="home">
    <h1>Hello World</h1>
  </div>
</template>

<script></script>

<style scoped>
  .home{
    color: red;
  }
</style>

マスタッシュ記法

ここからスクリプトタグを使っていきます。
データバインディングという操作を行います。
以下のようなコードを書きます

<template>
  <div class="home">
    <h1>{{hoge}}</h1>
  </div>
</template>

<script>
  export default{
    data(){
      return{
        hoge: "ハローワールド"
      }
    }
  }
</script>

h1タグの中身がハローワールドに変わったのが確認できたと思います。

マスタッシュ リスト表示方法

<template>
  <div class="home">
    <p>{{Vegetable.name}}</p>
    <p>{{Vegetable.price}}</p>
  </div>
</template>

<script>
  export default{
    data(){
      return{
        Vegetable: {
          name: "にんじん",
          price: 3000000
        }
      }
    }
  }
</script>

Vegetableリストの中の namepriceというように取り出します。

v-bind スタイル付与

h1タグを青色にします。

<template>
  <div class="home">
    <h1 v-bind:style="vStyle">{{hoge}}</h1>
  </div>
</template>

<script>
  export default{
    data(){
      return{
        hoge: "ハローワールド",
        vStyle: {
          color: "blue"
        }
      }
    }
  }
</script>

filter 小数点をつける

高級なにんじんの値段に小数点をつけます。

<template>
  <div class="home">
    <p>{{Vegetables.price | filter}}</p>
  </div>
</template>

<script>
  export default{
    data(){
      return{
        Vegetables: {
          price: 3000000
        }
      }
    },
    filters: {
      filter(val) {
        return val.toLocaleString();
      }
    }
  }
</script>

数字以外に、文字にも適用できるfilterがあります。

v-if else 表示 非表示の切り替え

<template>
  <div class="home">
    <p v-if="false">on</p>
    <p v-else>off</p>
  </div>
</template>

v-if の条件が
・true であれば on
・false であれば off
が表示されます

v-model inputタグと同期

input に入力した内容を pタグに表示させます。

<template>
  <div class="home">
    <input v-model="text" type="text">
    <p>{{text}}</p>
  </div>
</template>

<script>
  export default{
    data(){
      return{
        text: "",
      }
    }
  }
</script>

inputに入力されたデータを入れるために空のデータを用意してあげます。
textデータから値、テキストを取得して描画されます。

v-on clickイベント

<template>
  <div class="home">
    <div @click="push()">click me!!</div>
  </div>
</template>

<script>
  export default{
    methods:{
      push(){
        console.log("click year!!!!")
      }
    }
  }
</script>

検証画面のコンソールから確認してください。
click イベント以外にもイベントはあります。

v-for 配列でタグの複製

<template>
  <div class="home">
      <div v-for="data in Vegetables" :key="data.key">
      <p>{{data.name}}</p>
      <p>{{data.price}}</p>
    </div>
  </div>
</template>

<script>
  export default{
    data(){
      return{
        Vegetables:[
          {name: "じゃがいも", price: 300, key: "imo"},
          {name: "イチゴ", price: 400, key: "strawberry"},
          {name: "カボチャ", price: 500, key: "pumpkin"},
        ]
      }
    }
  }
</script>

Vegetables配列の中のデータと同じ数タグを複製しそれぞれ該当するマスタッシュ記法で書かれたタグにデータ(name、price、key)が格納されます。

イメージ図

Vegetables配列/
 ├ data/
 │ ├ name/ じゃがいも
 │ ├ price/ 300
 │ └ key/ imo
 ├ data/
 │ ├ name/ イチゴ
 │ ├ price/ 400
 │ └ key/ strawberry
 └ data/
   ├ name/ カボチャ
   ├ price/ 500
   └ key/ pumpkin

component の使い方 一例

components ディレクトリの中の HelloWorld.vue のそれぞれ
<template> <script> <style>
の中身を消して以下のコードを記述します。
※helloクラスタグのみ残してください。

HelloWorld.vue

<template>
  <div class="hello">
    <h2>僕は子コンポーネント</h2>
  </div>
</template>

<script>
</script>

<style scoped>
  h2{
    font-size: 50px;
  }
</style>

Home.vue

<template>
  <div class="home">
    <HelloWorld></HelloWorld>
  </div>
</template>

<script>
import HelloWorld from "../components/HelloWorld"

  export default{
    components: {
      HelloWorld
    }
  }
</script>

importcomponentsの中の HelloWorld.vueを呼び出します。
※HelloWorld.vue を呼び出す際拡張子の .vueをつける必要はありません。
・components プロパティに登録します。
・登録したものは template タグ内で使用できるようになるのでコードを記述します。

components ディレクトリにファイルを作り上記の方法をたどると同じようにコンポーネントを作ることができます。

props 親から子コンポーネントにデータを渡す

この記事では、Home.vue の中にある HelloWorld.vue が子コンポーネントにあたります。

Home.vue

<template>
  <div class="home">
    <HelloWorld v-bind:parentText="sendChild"></HelloWorld>
  </div>
</template>

<script>
import HelloWorld from "../components/HelloWorld"

  export default{
    data(){
      return{
        sendChild: "親のコンポーネントからテキストを受けっとたよ!"
      }
    }
    components: {
      HelloWorld
    }
  }
</script>

・子に渡すデータに名前をつけて(parenText)親のデータ(sendChild)をバインディングします。

HelloWorld.vue

<template>
  <div class="hello">
    <p>{{parentText}}</p>
  </div>
</template>

<script>
export default {
  props: ['parentText'],
}
</script>

props プロパティで値を受け取った物は data として扱うことができるのでマスタッシュ記法で表示します。

Router Link(Vue Router) ページ遷移

views ディレクトリの中に RouterLink.vue ファイルを作成します。
以下のように記述します。

<template>
  <div class="router">
    <p>Router Link の使用ができました!!</p>
  </div>
</template>

Router Link を使用するために router ディレクトリの中の index.js に
RouterLink.vue を登録します。
以下のようなコードを記述します。

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import RouterLink from '../views/RouterLink.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  {
    path: '/routerlink',
    name: 'routerlink',
    component: RouterLink
  },
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

最後にリンクを使いたいファイルに以下のようなコードを記述していきます。
ここでは Home.vue に記述します。

<template>
  <div class="home">
    <router-link to="/routerlink">router-link</router-link>
  </div>
</template>

to でページのリンク先を指定します
router-link をクリックすることでページ遷移をすることができます。
webページのリンクの方を見てもらうと http://localhost:8080/routerlink
このようにリンクの末尾が変わっていることが確認できると思います。

ぐるなびAPI お店のデータを取得から表示

axios を用いてレストラン検索APIを叩き Vuex の store という機能を使って表示まで行います。
まずは axios のインストールから行います。
以下のコマンドを順に実行していってください。

$ npm install --save axios
$ npm install --save

次に、ぐるなびAPIを使用するためにこちらのサイトで会員登録をします。
登録することができたら以下のような画面に行き、
仕様書ページ、レストラン検索APIを参考にパラメータと値を入れていきます。
・左側にパラメータ(例 keyid)
・右側に値

スクリーンショット 2020-02-05 23.53.37.png

この記事では、
・表示件数
・wifiの有無
を条件に絞ります。

スクリーンショット 2020-02-06 1.03.59.png

入力ができたらクエリを送信ボタンを押し URL を、コピーします。
store ディレクトリの中の index.js ファイルに、以下のようなコードを入力し
コピーした URL をここに挿入とういう部分にペーストしてください。

store / index.js

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    dataSet: []
  },
  mutations: {
    mutateDataSet(state, payload) {
      state.dataset = payload
    }
  },
  actions: {
    commitDataSet(store) {
      return axios.get("ここに挿入")
        .then(response => {
          store.commit('mutateDataSet', response.data.rest)
        })
        .catch((reason) => {
          console.log(reason.message)
        })
    }
  }
})

importでaxiosを使えるようにします。
表示させたいページ(RouterLink.vue)に以下のコードを記述します。

RouterLink.vue

<template>
  <div class="about">
    <ul v-for="(value, index) in shopName" :key="index">
      <li>{{value}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      shopName: ""
    };
  },
  created() {
    this.$store.dispatch('commitDataSet')
  },
  mounted() {
    var list = [];
    this.$store.state.dataSet.forEach(function(value) {
      list.push(value.name);
    });
    this.shopName = list;
  }
};
</script>

・created 内で store にアクセスして dispatch メソッドで action 内の関数を実行します。
・store の action メソッドが実行され値が取得されます。
・commit で mutations にアクセスし、データを入れます。
・mutations から state にアクセスし dataSetにデータが入ります。
・mounted で state 内のデータにアクセスし、forEach メソッドでデータが一個ずつ配列として list に入ります。
・list を shopName に代入することで RouterLink.vue 内で data として扱うことができるようになります。
・配列 shopName を v-for で表示させれば実装完了です。

いろいろ条件を変えて遊んでみてください。

イメージ

RouterLink.vue      store / index.js
 └ created ーー> action(commitDataSet)実行
                ↓
               mutation
                ↓
   mounted     <ーー state
     ↓
   描画

【java】クラスとはOS、インスタンスとは仮想コンピュータだ

$
0
0

0. オブジェクト指向という「新しい概念」

 プログラミングの初心者で、今までC言語を使ったコーディングの経験しかない人にJavaを教えるのは、思いのほか難しい。(情報系の大学を想定。1年次にC、2年次にJavaをやる場合が多いそう。)
「クラスとは何か」と聞かれたら「オブジェクト指向で使う」と説明するが、
「ではオブジェクト指向とは何か」と聞かれたらどうだろう。

「世の中にはいろんなモノゴトがある。そしてモノゴトには状態と振る舞いがある。
だからいろんなモノゴトに対して、状態と振る舞いを集めてクラスの中にコーディングしていく。これがオブジェクト指向だ」
と答えて、相手は納得するかもしれない。
しかし、この後に続く「カプセル化」、「継承」の説明を聞いて、相手は混乱するかもしれない。
いきなり「状態と振る舞いを集めてモノゴトを表現する」と教わったかと思えば、次に「状態を振る舞いに閉じ込める」、「具体的なモノゴトは抽象的なモノゴトをケイショウする」と教わるなど、覚えることが多い。「理論より実践」な人にとっては『苦痛』だろう。
こうして、オブジェクト指向によるコーディングに苦手意識を持ち、プログラミング界隈から離れていく人が、後を絶たないようである。

 『苦痛』の正体は、「オブジェクト指向とは、つまり何か」が一言で説明されないことにある。

 憶測だが、人は新しい概念を、既存の概念になぞらえて考え、誤差の部分は実践により覚える。
天空の城ラピュタで、空に浮かぶ伝説の島ラピュタの発見のために、主人公パズーとシータが政府専用機ゴリアテを尾行するくだりで、一度ゴリアテを見失いそうになる。
そのとき、協力者ドーラは「見張り台」と呼ばれる凧を使って追跡の続行を試みる。
このときパズーは次のよう指示される。

(凧の)操縦は体で覚えるんだ!

命懸けの無茶ぶりを、難なくこなすパズーの勇敢さが引き立つシーンではあるが、
ドーラも何も考えずにパズーに指示したのではない。ゴリアテ尾行の前、半ば脅されて政府に連行されたシータを救出すべく、ドーラはパズーを乗せてシータの居場所へと小型船を出した。この際、事故の衝撃でドーラは気を失い、小型船は危うく墜落するところであったが、パズーが操縦を急遽代行したことで、九死に一生を得たのだ。
凧の操縦(新しい概念)の指示は、極度に緊迫した状況で小型船を妥当に操縦(既存の概念)したパズーの実績を見込んでのことだろう。

 オブジェクト指向も、同じことではないだろうか。
皆が知っているような何かでオブジェクト指向をたとえ、違いの部分は実践をもとに各々が学習していけばそれでよい。少なくともイメージをつかめずに、手を動かすことすらできないよりはよっぽど。
本記事ではこのようなアプローチでJavaによるプログラミング、およびオブジェクト指向を解説していく。

 最後に補足すると、「プログラムとは何か」、「コンピュータ(計算機でもよい)とは何か」を定義に立ち返って考えれば、
クラスが「コンピュータを構成できるプログラム」であること、インスタンスがコンピュータであることは論理的に証明可能である

1. Javaとは「『仮想コンピュータ』を作りまくる言語」だ

 クラスを一言で説明するなら「コンピュータを構成できるプログラム」である。
このことは論理的に証明できる。

 同じように、インスタンスが「仮想コンピュータ」であることも証明可能だ。

1-1. クラスが「コンピュータを構成できるプログラム」であることの証明

 まず、ベーム・ヤコピーニの定理[1]にあるプログラムの3要素
「順次」、「反復」、「分岐」を、クラス内のメソッドですべて行える。
ということはもちろん、メソッドもプログラムといってよいのであるが、
残念なことにメソッドは「記憶領域」を持たない。
(蛇足:メソッド内でのみ有効な「ローカル変数」は、メソッド終了時に寿命が尽きるので、「記憶」したとは言えない)
そのためチューリングマシン[2]における「ヘッダ」を作ることができないため、
メソッドはプログラムにはなれても、コンピュータにはなれないのだ。
その点、クラスであれば「フィールド」(java以外の言語なら「プロパティ」などと呼ぶ)を持っていて、これを記憶領域として使うことができるため、
クラスはコンピュータを構築することが可能なのだ。(証明終わり)
別の言い方をするならば、クラスとはコンピュータの設計図だ。

1-2. インスタンスが「仮想コンピュータ」であることの証明

クラスそのものは、インスタンスという「実体」を作るための型である。
クラスという設計図をもとにインスタンスが生成されるのであるから、
インスタンスは、「クラスという設計図をもとに作った何か」である。
1-1節で証明したことをここに適用すると、
インスタンスとは、
「『コンピュータの設計図』という設計図をもとに作った何か」
である。それは(設計図通りに作れば)コンピュータである。(証明終わり)

2. OSと仮想コンピュータを作って遊ぼう

第1章のことより、クラスとは「コンピュータを構成できるプログラム」であり。インスタンスとは「コンピュータ」のことであることが分かった。
「コンピュータを構成できるプログラム」とは、まさにOSである。
不思議かもしれないが、javaでプログラミングするたびに、プログラマはOSを作っているし、newするたびに仮想コンピュータを作っているのである。

例えば、次のコードを考えよう。

「Mindows」OSと「computer」コンピュータ
publicclassMindows{privatebyte[]ram;publicbytegetRam(intaddress){returnthis.ram[address];}publicvoidsetRam(intaddress,bytevalue){this.ram[address]=value;}publicMindows(intram_size){this.ram=newbyte[ram_size];}}classMain{publicstaticvoidmain(String...args){Mindowscomputer=newMindows(64);//64byteのRAMを持つコンピュータの作成inti=0;for(chareach_char:"hello world".toCharArray())computer.setRam(i++,(byte)each_char);//0~10番地に「hello world」を書き込むfor(intj=0;j<11;j++)System.out.print((char)computer.getRam(j));//0~10番地を(charとして)表示//→コンソールに「hello world」と表示される。}}

このコードではMindows OSを定義し、このOSの入った仮想コンピュータcomputerを作って、
RAMを操作している。computer(インスタンス)を使ってできることを定義しているのはOS(クラス)であるが、OSが直接何かするわけではなく、実際に動作する実体はcomputer(インスタンス)の方である。

この他にも、
final定数フィールドでROMを作ったり、
finalメソッドでBIOSを作ったり、
ファイル入出力の機能を使ってストレージを持たせたりすることなどが考えられる。

3. javaの「実際」に当てはめて考える

3-1. ArrayListクラス

ArrayList<T>型インスタンスは記憶領域に順番付けてT型オブジェクトを格納しておくことのできる仮想コンピュータである。

3-2. Listインタフェース

List<T>インタフェースは、記憶領域にT型オブジェクトを記憶しておくプログラムの「宣言」に過ぎない。記憶領域の使い方を「おおよそ」決めるものといってよいだろう。
ArrayList<T>LinkedList<T>は、このインタフェースを「実装」している。
この事実は、ArrayList<T>LinkedList<T>が「記憶領域を、T型オブジェクトの格納に使う」と宣言していることを意味する。
インタフェースを実装した有言...クラスは、インタフェースに定義された空っぽのメソッドをオーバロードし、具体的に定義しなくてはならない。...実行

 インターフェースによる宣言は、家電を想像すれば理解しやすい。炊飯器や洗濯機(や、いまの時代では、掃除機も)は、どれもコンピュータといってよいだろう。
炊飯器はコメや水の重さから、炊き上がりの米の硬さや残り時間などを計算してくれる。洗濯機も、自動で判断する場面がある。掃除機は、ルンバをみれば分かるだろう。
今から作るクラス(プログラム)が炊飯器なのか洗濯機なのかはたまた掃除機なのかをはっきり言っておくことは重要だ。また、場合によっては「特定のインタフェースを実装したクラスにだけ、特別な使い方を認める」といったことも出来る。(例えば例外クラスなどがそれである。)

3-3. カプセル化

 「コンピュータ内部の回路をお客様にお見せしたくない」―それがカプセル化だ。
第2章に示したコードをもう一度見てみよう。
computerのRAMに書き込むとき、わざわざsetRam(アドレス, 書き込む値)というメソッドを呼んでいる。
そんなことをしなくても、ram[アドレス]=書き込む値ではダメなのだろうか。
もちろん、原理的にはそれで問題ないが、実際には、やりにくくなっている。
「Mindows」開発者は、メモリへの書き込み機能としてsetRam(アドレス, 書き込む値)を作ってはいるが、メモリそのものを剥き出しにはしていないのだ。実際のコンピュータが、メモリを鉄の内側に閉じ込めているように、javaのコード上でprivateというアクセス修飾子を付けている。
このようにすることで、記憶領域をユーザに勝手にいじられないようにして、誤作動の可能性を低減させている。

4. OSとコンピュータが自由に作れれば、オブジェクト指向プログラミングが可能

 残念ながらOSをクラスとみることは必ずしもできない。
クラスの持たない概念を持つOSが存在する(というか、ほとんどだ)からだ。
(例: マルチタスクOS、仮想メモリなど。またクロックやCPUを考えなければならない場合は、これをクラスで(実用的に)表現するのは困難であろう)
そこで、クラスが表現できるOSを「クラスOS」、インスタンスが表現できるコンピュータを「インスタンスコンピュータ」あるいは「クラスOSのコンピュータ」と呼ぶことにしよう。

 逆に、クラスの持つ概念(フィールド、メソッドのみとする)のどれかを持たないOSは存在しない。(クラスがOSとみなせることの証明から、明らかである)

 OSを自由に設計し、そのOSを入れた仮想コンピュータを生成・利用できる環境では、オブジェクト指向による開発が少なくとも部分的に可能である。(「半オブジェクト指向定理」とでも呼ぼう)
これは、すべてのOSがクラスの概念をすべて持っているため、当然のことである。
エラー発生時には、どのコンピュータ(OS)に不具合が生じたかを確認すればよいためエラーの特定が容易であるし、また仕様変更にも柔軟に対応する。
但し、アクセス制限の仕組みがなければカプセル化は利用できず、コピーの仕組みがなければ継承は不可能だ。

n.参考

[1]http://s150001.skr.u-ryukyu.ac.jp/lectures/index.php?ProgrammingAbility
[2]http://e-words.jp/w/%E3%83%81%E3%83%A5%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%83%9E%E3%82%B7%E3%83%B3.html

figmaを使って既存ホームページをデザインに起こすンゴよ〜

$
0
0

はじめに

Figmaではプラグインを使うことにより、既存画面からデザインを起こすことが可能です。

そのため既存デザインがないプロジェクトにアサインされ、追加画面や画面修正を頼まれたときに大活躍します。(多分)

注意事項

  • jsでモーダル等を表示制御している場合は表示が崩れる場合がある。
  • たまにテキストが出力されないことがある。
  • スクロールが必要なサイトは全部表示されないかも
  • divの数だけrectangleがあるのか、不要な図形が出力されることがある
  • 一切グループ化、フレーム化されない状態で出力されるので、インポート後こちらで適切な形に修正しなければいけない
  • ログイン後のUIが欲しい場合や、セキュリティ制限があるサイトの場合は、chrome拡張機能を使う必要あり。ニュースサイトなど誰から見ても同じUIの場合は必要ない。

手順

1. HTML To Figmaの導入

スクリーンショット 2020-02-06 17.12.05.png

スクリーンショット 2020-02-06 17.12.23.png

1.5. (必要に応じて)

右上のこのアイコンをクリック

スクリーンショット 2020-02-06 17.11.40.png

スクリーンショット 2020-02-06 17.19.24.png

  • 該当ページを開き、Chrome ExtensionのHTML To Figmaアイコンをクリックし、表示されるボタンをクリック。
  • jsonが保存される

2. デザインをインポートする

スクリーンショット 2020-02-06 17.21.20.png

  • Figmaで[Plugins]→[HTML To Figma]を開き、urlを打ち込む。1.5の手順を踏んでいる場合はupload hereをクリックし、jsonを選択する

3. インポート完了

なんかちょっと壊れてる気がしなくもないですができました。
あとは煮るなり焼くなり好きにしましょう。

地獄のグループ化、フレーム化作業が待っているぞ!

スクリーンショット 2020-02-06 17.22.31.png

おわり

ページ全体を使うのでなく、あるサイトのあるコンポーネントのつくりを参考にしたいとかそういう役割で使うほうがコスト低くてよさそうです。

Reactチュートリアルプログラム

$
0
0

目的

Reactの学習のため、下記のチュートリアルプログラムを作成してみる。
https://ja.reactjs.org/tutorial/tutorial.html

環境

Windows10Home
node v10.16.0
npm 6.9.0

記述

create-react-app

テキストエディタを使用するので、ベースとしてcreate-react-appを使用。
下記を実行し土台を作成。

npm
npx create-react-app test
cd test
npm start

その後作成したtest\src配下のファイルを全て削除し、index.css,index.jsを作成。

cssの記述

index.css
body {
  font: 14px "Century Gothic", Futura, sans-serif;
  margin: 20px;
}

ol, ul {
  padding-left: 30px;
}

.board-row:after {
  clear: both;
  content: "";
  display: table;
}

.status {
  margin-bottom: 10px;
}

.square {
  background: #fff;
  border: 1px solid #999;
  float: left;
  font-size: 24px;
  font-weight: bold;
  line-height: 34px;
  height: 34px;
  margin-right: -1px;
  margin-top: -1px;
  padding: 0;
  text-align: center;
  width: 34px;
}

.square:focus {
  outline: none;
}

.kbd-navigation .square:focus {
  background: #ddd;
}

.game {
  display: flex;
  flex-direction: row;
}

.game-info {
  margin-left: 20px;
}

Reactの記述

index.js
importReactfrom'react';importReactDOMfrom'react-dom';import'./index.css';functionSquare(props){return(<buttonclassName="square"onClick={props.onClick}>{props.value}</button>
);}classBoardextendsReact.Component{renderSquare(i){return(<Squarevalue={this.props.squares[i]}onClick={()=>this.props.onClick(i)}/>
);}render(){return(<div><divclassName="board-row">{this.renderSquare(0)}{this.renderSquare(1)}{this.renderSquare(2)}</div>
<divclassName="board-row">{this.renderSquare(3)}{this.renderSquare(4)}{this.renderSquare(5)}</div>
<divclassName="board-row">{this.renderSquare(6)}{this.renderSquare(7)}{this.renderSquare(8)}</div>
</div>
);}}classGameextendsReact.Component{constructor(props){super(props);this.state={history:[{squares:Array(9).fill(null)}],stepNumber:0,xIsNext:true};}handleClick(i){consthistory=this.state.history.slice(0,this.state.stepNumber+1);constcurrent=history[history.length-1];constsquares=current.squares.slice();if(calculateWinner(squares)||squares[i]){return;}squares[i]=this.state.xIsNext?"X":"O";this.setState({history:history.concat([{squares:squares}]),stepNumber:history.length,xIsNext:!this.state.xIsNext});}jumpTo(step){this.setState({stepNumber:step,xIsNext:(step%2)===0});}render(){consthistory=this.state.history;constcurrent=history[this.state.stepNumber];constwinner=calculateWinner(current.squares);constmoves=history.map((step,move)=>{constdesc=move?'Go to move #'+move:'Go to game start';return(<likey={move}><buttononClick={()=>this.jumpTo(move)}>{desc}</button>
</li>
);});letstatus;if(winner){status="Winner: "+winner;}else{status="Next player: "+(this.state.xIsNext?"X":"O");}return(<divclassName="game"><divclassName="game-board"><Boardsquares={current.squares}onClick={i=>this.handleClick(i)}/>
</div>
<divclassName="game-info"><div>{status}</div>
<ol>{moves}</ol>
</div>
</div>
);}}// ========================================ReactDOM.render(<Game/>,document.getElementById("root"));functioncalculateWinner(squares){constlines=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];for(leti=0;i<lines.length;i++){const[a,b,c]=lines[i];if(squares[a]&&squares[a]===squares[b]&&squares[a]===squares[c]){returnsquares[a];}}returnnull;}

追加課題

1.履歴内のそれぞれの着手の位置を (col, row) というフォーマットで表示する。

 historyにマスの情報を追加し、値を呼び出せるように変更。

index.js(handleClick)
handleClick(i){consthistory=this.state.history.slice(0,this.state.stepNumber+1);constcurrent=history[history.length-1];constsquares=current.squares.slice();if(calculateWinner(squares)||squares[i]){return;}squares[i]=this.state.xIsNext?"X":"O";this.setState({history:history.concat([{squares:squares,col:(i%3)+1,//追加row:Math.floor(i/3)+1, //追加}]),stepNumber:history.length,xIsNext:!this.state.xIsNext});}

遷移リストにマスの位置を表示するようにstep.col,step.row追加

index.js(render)
render(){consthistory=this.state.history;constcurrent=history[this.state.stepNumber];constwinner=calculateWinner(current.squares);constmoves=history.map((step,move)=>{constdesc=move?'Go to move #'+move+'('+step.col+','+step.row+')'://変更'Go to game start';return(<likey={move}><buttononClick={()=>this.jumpTo(move)}>{desc}</button>
</li>
);});

2.着手履歴のリスト中で現在選択されているアイテムをボールドにする。

GameコンポーネントstepNumberをステートとして保持しているので、これを利用してstepNumberhistoryのindexの役割をするmoveが一致した際にboldというclassを付与

index.js(render)
render(){consthistory=this.state.history;constcurrent=history[this.state.stepNumber];constwinner=calculateWinner(current.squares);constmoves=history.map((step,move)=>{constdesc=move?'Go to move #'+move+'('+step.col+','+step.row+')':'Go to game start';return(<likey={move}><buttononClick={()=>this.jumpTo(move)}className={this.state.stepNumber===move?'bold':''}>{desc}</button>
</li>
);});

boldclass付与時に太字が有効になるようにcssに追加

index.css
.bold{font-weight:bold;}

3.Board でマス目を並べる部分を、ハードコーディングではなく 2 つのループを使用するように書き換える。

keyを追加し、map関数を二重で使用する。

index.js(Board)
classBoardextendsReact.Component{renderSquare(i){return(<Squarevalue={this.props.squares[i]}onClick={()=>this.props.onClick(i)}key={i}/>
);}render(){return(<div>{Array(3).fill(0).map((row,i)=>{return(<divclassName="board-row"key={i}>{Array(3).fill(0).map((col,j)=>{return(this.renderSquare(i*3+j))})}</div>
)})}</div>
);}}

4.着手履歴のリストを昇順・降順いずれでも並べかえられるよう、トグルボタンを追加する。

Gameコンポーネントに昇順・降順を並べ替えるボタンを追加し、昇順か降順かどうかを保持するstateを新しく定義することで遷移リストをレンダリングする際にstateの状態によって昇順か降順を切り替えを行う。

index.js(Game)
classGameextendsReact.Component{constructor(props){super(props);this.state={history:[{squares:Array(9).fill(null)}],stepNumber:0,xIsNext:true};}handleClick(i){consthistory=this.state.history.slice(0,this.state.stepNumber+1);constcurrent=history[history.length-1];constsquares=current.squares.slice();if(calculateWinner(squares)||squares[i]){return;}squares[i]=this.state.xIsNext?"X":"O";this.setState({history:history.concat([{squares:squares,col:(i%3)+1,row:Math.floor(i/3)+1,}]),stepNumber:history.length,xIsNext:!this.state.xIsNext});}jumpTo(step){this.setState({stepNumber:step,xIsNext:(step%2)===0,isAsc:true});}toggleAsc(){this.setState({asc:!this.state.asc,});}render(){consthistory=this.state.history;constcurrent=history[this.state.stepNumber];constwinner=calculateWinner(current.squares);constmoves=history.map((step,move)=>{constdesc=move?'Go to move #'+move+'('+step.col+','+step.row+')':'Go to game start';return(<likey={move}><buttononClick={()=>this.jumpTo(move)}className={this.state.stepNumber===move?'bold':''}>{desc}</button>
</li>
);});letstatus;if(winner){status="Winner: "+winner;}else{status="Next player: "+(this.state.xIsNext?"X":"O");}return(<divclassName="game"><divclassName="game-board"><Boardsquares={current.squares}onClick={i=>this.handleClick(i)}/>
</div>
<divclassName="game-info"><div>{status}</div>
<div><buttononClick={()=>this.toggleAsc()}>{(this.state.asc?"desc":"asc")}</button></div><ol>{this.state.asc?moves:moves.reverse()}</ol>
</div>
</div>
);}}

5.どちらかが勝利した際に、勝利につながった 3 つのマス目をハイライトする。

calculateWinner関数に勝者の判定だけでなくどのマスの列が揃ったかの配列も返すように変更を加える。

index.js(calculateWinner)
functioncalculateWinner(squares){constlines=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];for(leti=0;i<lines.length;i++){const[a,b,c]=lines[i];if(squares[a]&&squares[a]===squares[b]&&squares[a]===squares[c]){return{winner:squares[a],line:[a,b,c]};}}returnnull;}

calculateWinner関数の帰り値を変更したため、Gameコンポーネントの修正とBoardコンポーネントに揃った列のマスを渡すように変更。

index.js(Game)
classGameextendsReact.Component{constructor(props){super(props);this.state={history:[{squares:Array(9).fill(null)}],stepNumber:0,xIsNext:true};}handleClick(i){consthistory=this.state.history.slice(0,this.state.stepNumber+1);constcurrent=history[history.length-1];constsquares=current.squares.slice();if(calculateWinner(squares)||squares[i]){return;}squares[i]=this.state.xIsNext?"X":"O";this.setState({history:history.concat([{squares:squares,col:(i%3)+1,row:Math.floor(i/3)+1,}]),stepNumber:history.length,xIsNext:!this.state.xIsNext});}jumpTo(step){this.setState({stepNumber:step,xIsNext:(step%2)===0,isAsc:true});}toggleAsc(){this.setState({asc:!this.state.asc,});}render(){consthistory=this.state.history;constcurrent=history[this.state.stepNumber];constsettlement=calculateWinner(current.squares);constmoves=history.map((step,move)=>{constdesc=move?'Go to move #'+move+'('+step.col+','+step.row+')':'Go to game start';return(<likey={move}><buttononClick={()=>this.jumpTo(move)}className={this.state.stepNumber===move?'bold':''}>{desc}</button>
</li>
);});letstatus;if(settlement){status="Winner: "+settlement.winner;}else{status="Next player: "+(this.state.xIsNext?"X":"O");}return(<divclassName="game"><divclassName="game-board"><Boardsquares={current.squares}onClick={i=>this.handleClick(i)}highlightCells={settlement?settlement.line:[]}/>
</div>
<divclassName="game-info"><div>{status}</div>
<div><buttononClick={()=>this.toggleAsc()}>{(this.state.asc?"desc":"asc")}</button></div><ol>{this.state.asc?moves:moves.reverse()}</ol>
</div>
</div>
);}}

Boardコンポーネントに揃った列のマスの配列を受け取り、マスをレンダリング時に揃ったマスをハイライトするか否をisHighlightで判定。

index.js(Board)
classBoardextendsReact.Component{renderSquare(i,isHighlight=false){return(<Squarevalue={this.props.squares[i]}onClick={()=>this.props.onClick(i)}key={i}isHighlight={isHighlight}/>
);}render(){return(<div>{Array(3).fill(0).map((row,i)=>{return(<divclassName="board-row"key={i}>{Array(3).fill(0).map((col,j)=>{return(this.renderSquare(i*3+j,this.props.highlightCells.indexOf(i*3+j)!==-1))})}</div>
)})}</div>
);}}

SquareコンポーネントisHighlighttrueのときのみhighlightクラスを付与するように変更。

index.js(Square)
functionSquare(props){return(<buttonclassName={`square ${props.isHighlight?'highlight':''}`}onClick={()=>props.onClick()}>{props.value}</button>
);}

最後にhighlightクラスがついたときに背景色が変わるようにcssに追加。

index.css
.highlight{background-color:yellow;}

6.どちらも勝利しなかった場合、結果が引き分けになったというメッセージを表示する。

calculateWinner関数に引き分けかどうかの情報も渡すように変更。

index.js(calculateWinner
functioncalculateWinner(squares){constlines=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];for(leti=0;i<lines.length;i++){const[a,b,c]=lines[i];if(squares[a]&&squares[a]===squares[b]&&squares[a]===squares[c]){return{winner:squares[a],line:[a,b,c],isDraw:false};}}if(squares.filter((e)=>!e).length===0){return{isDraw:true,winner:null,line:[]}}returnnull;}

Gameコンポーネントrenderメソッドを書き換えていきます。

index.js(Game)
classGameextendsReact.Component{constructor(props){super(props);this.state={history:[{squares:Array(9).fill(null)}],stepNumber:0,xIsNext:true};}handleClick(i){consthistory=this.state.history.slice(0,this.state.stepNumber+1);constcurrent=history[history.length-1];constsquares=current.squares.slice();if(calculateWinner(squares)||squares[i]){return;}squares[i]=this.state.xIsNext?"X":"O";this.setState({history:history.concat([{squares:squares,col:(i%3)+1,row:Math.floor(i/3)+1,}]),stepNumber:history.length,xIsNext:!this.state.xIsNext});}jumpTo(step){this.setState({stepNumber:step,xIsNext:(step%2)===0,isAsc:true});}toggleAsc(){this.setState({asc:!this.state.asc,});}render(){consthistory=this.state.history;constcurrent=history[this.state.stepNumber];constsettlement=calculateWinner(current.squares);constmoves=history.map((step,move)=>{constdesc=move?'Go to move #'+move+'('+step.col+','+step.row+')':'Go to game start';return(<likey={move}><buttononClick={()=>this.jumpTo(move)}className={this.state.stepNumber===move?'bold':''}>{desc}</button>
</li>
);});letstatus;if(settlement){if(settlement.isDraw){status="Draw";}else{status="Winner: "+settlement.winner;}}else{status="Next player: "+(this.state.xIsNext?"X":"O");}return(<divclassName="game"><divclassName="game-board"><Boardsquares={current.squares}onClick={i=>this.handleClick(i)}highlightCells={settlement?settlement.line:[]}/>
</div>
<divclassName="game-info"><div>{status}</div>
<div><buttononClick={()=>this.toggleAsc()}>{(this.state.asc?"desc":"asc")}</button></div><ol>{this.state.asc?moves:moves.reverse()}</ol>
</div>
</div>
);}}

[Python 入門] pandasを使ってみよう

$
0
0

[Python 入門] pandasを使ってみよう

第3回になります。今回は題材の日経平均らしいことをやっていきます。
まずいつもどおりcsvデータを読み込んでおきます。

import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets

plt.style.use('ggplot') #おまじない
font = {'family' : 'meiryo'}

nikkei = pd.read_csv("nikkei.csv", parse_dates=['データ日付']) #csvデータを読み込む
nikkei.head() #概要を見てみる

日時収益変動率とヒストグラム

最初に日時収益変動率を計算して、図に表してみます。

nikkei['Day. Change P'] = (nikkei['終値'] - nikkei['始値']) / nikkei['始値'] #日時収益変動率を計算する
plt.figure(figsize=(22, 8))
plt.hist(nikkei['Day. Change P'], bins = 100)

2020-02-06 (3).png

こんな感じになります。だいたい正規分布に近くなりましたね。日経平均の変動があまりない日が多い、といった感じですかね。分析等は各自の判断でしてみてください。ここではあくまでこんな風にできたよ、ということで...

ロウソクチャートを描画する

では次はロウソクチャートを書く方法です。案外簡単にいけました。ちょうどいいものがあるんですね。

import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

#Create OHLC (open-high-low-close) charts
trace = go.Ohlc(x = nikkei['データ日付'], 
               open = nikkei['始値'], 
               high = nikkei['高値'], 
               low = nikkei['安値'], 
               close = nikkei['終値'])
data = [trace]
iplot(data)

2020-02-06 (5).png

移動平均を描画する

最後に移動平均を計算してプロットしてみましょう。

nikkei['5dayma'] = nikkei['終値'].rolling(window = 5).mean()
nikkei['25dayma'] = nikkei['終値'].rolling(window = 25).mean()
nikkei['50dayma'] = nikkei['終値'].rolling(window = 50).mean()

nikkei.tail()

上のように計算させてデータフレイムに追加しておきます。ここで.head()では1~4日目まではNaNの表示で5日目になって初めて'5dayma'が計算されるといったようにちゃんと計算できているのか確認しづらいため、.tail()を使っています。

trace_close = go.Scatter(x = nikkei['データ日付'][-200:], 
                        y = nikkei['終値'][-200:], 
                        name = "close", 
                        line = dict(color = '#000000'), #黒色の線にする
                        opacity = 0.8)

trace_5day = go.Scatter(x = nikkei['データ日付'][-200:], 
                        y = nikkei['5dayma'][-200:], 
                        name = "5day", 
                        opacity = 0.8)

trace_25day = go.Scatter(x = nikkei['データ日付'][-200:], 
                        y = nikkei['25dayma'][-200:], 
                        name = "25day", 
                        opacity = 0.8)

trace_50day = go.Scatter(x = nikkei['データ日付'][-200:], 
                        y = nikkei['50dayma'][-200:], 
                        name = "50day", 
                        opacity = 0.8)

data = [trace_close, trace_5day, trace_25day, trace_50day]
layout = dict(title = "Moving averages:5, 25, 50  for 200days", )
fig = dict(data = data, layout=layout)
iplot(fig)

2020-02-06 (6).png
こんな感じになりました。注意としては各軸の設定に当たり、"[-200:]"とスライスして200日分を表示してます。見栄えを重視しただけですのでしなくてもOKです。その場合は全期間となります。

おわりに

前回のヒートマップと比べ、今回はまともなものができました。まだ大したことはしていませんが、もう少しこの日経平均という題材で遊べたらいいなと考えています。

【初心者向け】開発環境:Angular + VSCode in Windows

$
0
0

はじめに

  • Angularかじったときの備忘録です
  • 意外と開発環境のセットアップに手間取ったのメモを残しておきます
    • 手間取ったというより、情報が多く、何がシンプルでベストなのか特定するのに時間がかかりました。
  • VSCodeのインストール手順は割愛します

まずはAngularを用意

  • 結局本家のサイトが一番でした。
  • ここもミニマムで分かりやすかったです。
  • Node.jsインストールして、AngularCLIインストールするだけでOKです。
    • Node.jsはLTS版となる12.14.1 (同梱 npm 6.13.4)
    • AngularCLIは8.3.24
  • ここまでは、VSCode関係無いです。この時点でAngular開発できるようになります。上記サイトのTutorialは一通り試せます
    • ng newでプロジェクト作って、ng serveでローカル起動すれば、動作確認することができます。

VSCodeの設定

  • エディタはVSCodeが使いやすく情報も多いです。
    • バージョンは1.41.1
  • ng newして生成したフォルダを選択して、それぞれのファイルを編集しながら開発していきます。それなりにコード補完もしてくれます。
  • AngularCLIはVSCode上のTerminalから直接叩けばいいでしょう。ng serveして、chromeでlocalhost:4200にアクセスして、画面を開いておけば、コードの更新毎に画面も更新してくれます。画面が表示されない!?みたい場合は、chromeの開発者ツールでエラー確認できます。
  • componentやserviceをVSCodeコンテキストメニューから生成するような拡張が欲しいような気がしますが、AngularCLIのコマンド覚えればいいだけの話です。
  • 結論として、何も設定する必要が無いのか、というわけではなく下記の拡張はおススメです。
    • Angular Language Service
      • コード補完がかなり強化されます。特にhtmlファイル内。

終わりに

  • 内容の薄い記事となってしまいました。
  • VSCodeの拡張機能情報をもう少し追記予定です

Railsチュートリアル 第14章 ユーザーをフォローする - followingアクションおよびfollowersアクションの統合テストに存在する不具合の修正

$
0
0

followingアクションおよびfollowersアクションの統合テストにおける、Railsチュートリアル本文記載のテストの不具合

実は、Railsチュートリアル本文のリスト 14.29に記述されているテストには、1つの不具合があります。

例えば、app/views/users/show_follow.html.erbに以下の欠落がある場合を考えてみましょう。

app/views/users/show_follow.html.erb
<% provide(:title, @title) %>
  <div class="row">
    <aside class="col-md-4">
      <section class="user_info">
        ...略
      </section>
      <section class="stats">
        <%= render'shared/stats' %>
        <% if @users.any? %>
          <div class="user_avatars">
            <% @users.each do |user|%>
              <%= link_to gravatar_for(user, size: 30), user %>
            <% end %>
          </div>
        <% end %>
      </section>
    </aside>
    <div class="col-md-8">
      <h3><%= @title %></h3>
      <% if @users.any? %>
        <ul class="users follow">
-         <%= render @users %>
</ul>
        <%= will_paginate %>
      <% end %>
    </div>
  </div>

の場合、例えば users/1/following のWebブラウザにおける表示は以下のようになります。

スクリーンショット 2020-02-06 8.09.39.png

ページ右側にフォローしているユーザー一覧が描画されていません。明らかに意図した表示内容ではないですね。

しかしながら、Railsチュートリアル本文のリスト 14.29に記述されているテストの場合、この状態でもテストは成功してしまうのです。

# rails test test/integration/following_test.rb
Running via Spring preloader in process 1248
Started with run options --seed 41256

  2/2: [===================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.66436s
2 tests, 10 assertions, 0 failures, 0 errors, 0 skips

同様に、app/views/users/show_follow.html.erbに以下の欠落がある場合でも、Railsチュートリアル本文のリスト 14.29に記述されているテストは成功してしまいます。

app/views/users/show_follow.html.erb
<% provide(:title, @title) %>
  <div class="row">
    <aside class="col-md-4">
      <section class="user_info">
        ...略
      </section>
      <section class="stats">
        <%= render'shared/stats' %>
        <% if @users.any? %>
          <div class="user_avatars">
            <% @users.each do |user|%>
              <%= link_to gravatar_for(user, size: 30), user %>
            <% end %>
          </div>
        <% end %>
      </section>
    </aside>
    <div class="col-md-8">
      <h3><%= @title %></h3>
      <% if @users.any? %>
        <ul class="users follow">
-         <%= render @users %>
</ul>
        <%= will_paginate %>
      <% end %>
    </div>
  </div>

不具合の原因は、テストの実装が「ユーザーのプロフィールページへのリンクが1つ以上あればOK」という内容になっているためです。単一ユーザーのプロフィールページへのリンクは、「サイドバーのアイコンで1つ、FollowingまたはFollowersの一覧で1つ〜2つ1」存在します。そのため、「リンクが1つ以上」というテストの実装では、「サイドバー」「FollowingまたはFollowersの一覧」いずれか片方の欠落ではテストをすり抜けてしまうのです。

followingアクションおよびfollowersアクションの統合テストの不具合を修正する

ユーザーのプロフィールページへのリンクの存在によって「サイドバー」「FollowingまたはFollowersの一覧」両方が正しく描画されていることを確認するためには、「ユーザーのプロフィールページへのリンクが2つ以上存在すること」をテストする必要があります。assert_selectで「要素が2つ以上存在すること」をテストするためには、オプションハッシュにminimum: 2という設定を与えればOKです。

上記を踏まえ、test/integration/following_test.rbの修正内容は以下のようになります。

 
  require 'test_helper'

  class FollowingTest < ActionDispatch::IntegrationTest
    def setup
      @user = users(:rhakurei)
      log_in_as(@user)
    end

    test "following page" do
      get following_user_path(@user)
      assert_not @user.following.empty?
      assert_match @user.following.count.to_s, response.body
      @user.following.each do |user|
-       assert_select "a[href=?]", user_path(user)
+       assert_select "a[href=?]", user_path(user), minimum: 2
      end
    end

    test "followers page" do
      get followers_user_path(@user)
      assert_not @user.followers.empty?
      assert_match @user.followers.count.to_s, response.body
      @user.followers.each do |user|
-       assert_select "a[href=?]", user_path(user)
+       assert_select "a[href=?]", user_path(user), minimum: 2
      end
    end
  end

上記修正は本当に正しいのか

上記修正を行ったtest/integration/following_test.rbを対象に、改めて以下のコードのテストを行ってみます。

app/views/users/show_follow.html.erb
<% provide(:title, @title) %>
  <div class="row">
    <aside class="col-md-4">
      <section class="user_info">
        ...略
      </section>
      <section class="stats">
        <%= render'shared/stats' %>
        <% if @users.any? %>
          <div class="user_avatars">
            <% @users.each do |user|%>
              <%= link_to gravatar_for(user, size: 30), user %>
            <% end %>
          </div>
        <% end %>
      </section>
    </aside>
    <div class="col-md-8">
      <h3><%= @title %></h3>
      <% if @users.any? %>
        <ul class="users follow">
-         <%= render @users %>
</ul>
        <%= will_paginate %>
      <% end %>
    </div>
  </div>

結果は以下のようになります。

# rails test test/integration/following_test.rb
Running via Spring preloader in process 1235
Started with run options --seed 28029

 FAIL["test_followers_page", FollowingTest, 2.6110920999926748]
 test_followers_page#FollowingTest (2.61s)
        Expected at least 2 elements matching "a[href="/users/919532091"]", found 1..
        Expected 1 to be >= 2.
        test/integration/following_test.rb:23:in `block (2 levels) in <class:FollowingTest>'
        test/integration/following_test.rb:22:in `block in <class:FollowingTest>'

 FAIL["test_following_page", FollowingTest, 2.699444500001846]
 test_following_page#FollowingTest (2.70s)
        Expected at least 2 elements matching "a[href="/users/314048677"]", found 1..
        Expected 1 to be >= 2.
        test/integration/following_test.rb:14:in `block (2 levels) in <class:FollowingTest>'
        test/integration/following_test.rb:13:in `block in <class:FollowingTest>'

  2/2: [===================================] 100% Time: 00:00:02, Time: 00:00:02

Finished in 2.71399s
2 tests, 8 assertions, 2 failures, 0 errors, 0 skips

Expected 1 to be >= 2.というのがポイントですね。「ユーザーのプロフィールページへのリンクが2つ以上存在すること」に対する正しいテストが書けているようです。


  1. ログインユーザーがAdmin属性である場合、ユーザーを削除するためのリンクも、リンク先のURLは当該ユーザーのプロフィールページへのリンクのURLと同じになります。違うのは、発行されるアクションがGETであるかDELETEであるかです。 

決定木(分類)

$
0
0

決定木とは

機械学習の分野においては決定木は予測モデルであり、ある事項に対する観察結果から、その事項の目標値に関する結論を導く。内部の節点は変数に対応し、子である節点への枝はその変数の取り得る値を示す。 葉(端点)は、根(root)からの経路によって表される変数値に対して、目的変数の予測値を表す。wikipedia

これだと分かりづらいので実際に図にして表すとこんな感じです。
207486.jpg

これはテニスをするかどうかを判定する決定木の分類です。このように日常の意思決定も決定木で表すことができます。

決定木の深さについて

 決定木には深さという深さというものがあってテニスをするかどうかの例だとさらに天気→湿度というのが決定木の深さに該当します。ここに対して湿度が低いだけではなく、「湿気が多いというのは前日に雨が降ったのかも、コートの状態が今どうなのか」というケースに対して、「前日の天気は?」という様な質問をすることによってより厳密に出来ます。しかし、上記のような手法でどんどん分類規則を追加していくと、最終的には大量のノードが存在し、とても深い決定木が出来上がってしまいます。これは訓練データに対する過学習(過剰適合も適切)を示し、高バリアンス(予測値のばらつきの大きさ)なモデルが出来上がっているというわけです。

max_depth(決定木の深さ)とAccuracyの関係

 max_depthが3~4の時、Accuracyは最大となるが、max_depthが4以降はAccuracyが低下していく。これは、max_depthを大きくしすぎたことによる過学習が起きているためである。この様に決定木は適切な木の深さになる様に剪定(木を切ること)をしなければなりません。剪定することによってモデルの汎化性能を上げる事ができます。なお、プログラム上、Accuracyが最大となるmax_depthは3の時である。

download.png

データについての説明

乳がんの診断データがまとめられたデータセットです。各ケースは検査値を含む32の値を持っており、変数の多いデータセットになっています。各ケースには、良性腫瘍か悪性腫瘍の診断結果が付いており、これを目的変数とする分類学習になります。

コード

%%timeimportmatplotlib.pyplotaspltfromsklearn.datasetsimportload_breast_cancerfromsklearn.treeimportDecisionTreeClassifierfromsklearnimporttreefromsklearn.model_selectionimporttrain_test_splitfromsklearn.metricsimportf1_score#乳癌データの読み込み
cancer_data=load_breast_cancer()#トレーニングデータ、テストデータの分離
train_X,test_X,train_y,test_y=train_test_split(cancer_data.data,cancer_data.target,random_state=0)#条件設定
max_score=0accuracy=[]depth_list=[iforiinrange(1,15)]#決定木の実行
fordepthintqdm(depth_list):clf=DecisionTreeClassifier(criterion="entropy",splitter="random",max_depth=depth,min_samples_split=4,min_samples_leaf=1,random_state=56)clf.fit(train_X,train_y)accuracy.append(clf.score(test_X,test_y))ifmax_score<clf.score(test_X,test_y):max_score=clf.score(test_X,test_y)depth_=depth#決定木をdotファイルに変換
clf=DecisionTreeClassifier(criterion="entropy",splitter="random",max_depth=depth_,min_samples_split=4,min_samples_leaf=1,random_state=56)clf.fit(train_X,train_y)tree.export_graphviz(clf,out_file="tree.dot",feature_names=cancer_data.feature_names,class_names=cancer_data.target_names,filled=True)#グラフのプロット
plt.plot(depth_list,accuracy)plt.title("Accuracy change")plt.xlabel("max_depth")plt.ylabel("Accuracy")plt.show()print("max_depth:{}".format(depth_))print("ベストスコア:{}".format(max_score))

出力

max_depth:3
ベストスコア:0.9300699300699301
CPU times: user 228 ms, sys: 6.02 ms, total: 234 ms
Wall time: 237 ms

まとめ

 決定木は機械学習の中でもかなり理解しやすいアルゴリズムだと思うので、機械学習がわからない人などに説明するときに使いやすいのかなと思いました。
 

27歳、未経験です あっ・・・(察し)

$
0
0

はじめに

なんだこのオッサン!?(驚愕)

近年半導体業界が不景気になり業界丸ごとタイタニック並みに沈没しました。

請負先も「クビだクビだクビだ」ということでお仕事なくなってしまったので

学生時代に興味があったWebエンジニアとして働きたく転職活動を始めました。

インプットした事を忘れないようにする為Qiitaでサボらずアウトプットして行きます。

あっ! 遅れましたがQiita初投稿になります。

今後は生暖かく見守もってください!

本日のアウトプット

divタグとfloatの仕組みを理解する。

divタグに関して

divタグはブロック要素のため縦並びになる。
親要素内の子要素は抱合され、また親要素どうしは互いを抱合しない。
スクリーンショット 2020-02-06 22.49.16.png

index.html
<!DOCTYPE html><htmllang="ja"><head><metacharset="UTF-8"><title>  float  </title><linkrel="stylesheet"href="style.css"></head><body><divclass="parent1"><divclass ="child1"></div></div><divclass="parent2"><divclass ="child2"></div></div></body></html>
style.css
.parent1{width:100px;height:100px;background-color:black;}.child1{width:50px;height:50px;background-color:blue;}.parent2{width:100px;height:100px;background-color:red;}.child2{width:50px;height:50px;background-color:yellow;}
floatに関して

divタグはブロック要素のため縦並びになるが横並びにする際はfloat:left;を使用する。
親要素を横並びに変更してみる(.parent1,2にfloat: left)。
スクリーンショット 2020-02-06 23.08.39.png

style.css
.parent1{width:100px;height:100px;background-color:black;float:left;}.child1{width:50px;height:50px;background-color:blue;}.parent2{width:100px;height:100px;background-color:red;float:left;}.child2{width:50px;height:50px;background-color:yellow;}

子要素に(.child1,2にfloat: right)させた場合floatの範囲は親要素内である。
スクリーンショット 2020-02-07 0.11.39.png

style.css
.parent1{width:100px;height:100px;background-color:black;float:left;}.child1{width:50px;height:50px;background-color:blue;float:right;}.parent2{width:100px;height:100px;background-color:red;float:left;}.child2{width:50px;height:50px;background-color:yellow;float:right;}

おわりに

今回はfloatのみでしたが次はfloatの解除方法が
複数あるのでどれを使えば良いかを調べて行きます。

Viewing all 21655 articles
Browse latest View live