【Ruby】miniテストのエラー
FJORD BOOT CAMP(フィヨルドブートキャンプ)の課題で実装しているボーリングスコア計算プログラムのテストでエラーが出たので原因をアウトプットしていきます。
エラー
- ボーリングスコア計算プログラムのテストを実行すると下記のエラーが出た
bowling_object.rb:68:in `pinfalls': undefined method `split' for nil:NilClass (NoMethodError)
「splitメソッドのクラスがnilのため見つかりません。」と解釈、しかしクラスは定義しているはず...なぜ?と思いつつ起点を調べる
- テストの起点は下記のコード
from bowling_object_test.rb:3:in `<main>'
- 上記のコードはrequire して
bowling_object.rb
を読み込む部分。このときにエラーが発生していることがわかる
require './bowling_object'
- ちなみに
bowling_object.rb
のファイルの中身は、こんな感じ
# frozen_string_literal: true class Game ... end class Frame ... end class Shot ... end puts Game.new(ARGV[0]).calculate_score
原因/改善
- 上記のコードでは、最後の
puts Game.new(ARGV[0]).calculate_score
がrequireしただけで実行されてしまう。つまりARGVが何もない状態で実行されてしまうため、最終的にエラーが発生してしまう。テストを書く際にrequireしたいことを考えると、puts Game.new(ARGV[0]).calculate_score
はこのファイル自体をrubyコマンドとして実行したときだけ走って欲しい。そんなときは以下のように書く
if __FILE__ == $PROGRAM_NAME puts Game.new(ARGV[0]).calculate_score end
__FILE__:現在のファイルの名前を含むマジック変数。rubyは__FILE__を使用して現在のソースファイル名を保持する
$PROGRAM_NAME:変数名の先頭に$を付けると、グローバル変数を示す。変数名には実行中のスクリプトの名前が含まれる。PROGRAM_NAMEは、プログラムの名前を文字列で返す定数
そもそもテストコードはクラスのメソッドをテストするだけなので、ファイルを分けるとエラーは起きないということも学んだ。クラスを使ってコードを書く時は、クラスごとにファイルを分けることが重要!
【Ruby】学んだメソッドをアウトプット
最近Rubyの問題をpaizaラーニングで解き始めたので学んだことをアウトプットしていきます。
chompメソッドで末尾の改行文字を削除
chompは文字列の末尾に改行コードがあった場合に、文字列の末尾の改行コードを削除してくれる
# 標準入力で値を取得する場合 a = gets.to_s b = gets.to_s.chomp p a p b # =>"Z\n" # =>"Z"
Array.new(n)で欲しい長さの配列を作成
- 問題:整数 n と n 個の数 a_1, ..., a_n が改行区切りで与えられる。与えられた a_1, ..., a_n の中で最も大きい数を出力する
例) 整数nが2の場合、例えば4と7が改行区切りで与えられる。そのうちの大きい数の7を出力する
n = gets.to_i # 整数で値を取得 ary = Array.new(n) # 上記で取得したn個の長さの配列を作成 n.times { |i| ary[i] = gets.to_i } # 作った配列に改行区切りで与えられる数を入れていく。 puts ary.max # 配列に入った数の中で一番大きな数を出力
joinメソッドで文字列を連結
整数 n が与えられるので、n 回、半角スペース区切りで paiza と出力する
例) 整数nが2の場合、「 paiza paiza」と出力する
n = gets.to_i # 整数で値を取得 ary = Array.new(n) # 上記で取得したn個の長さの配列を作成 n.times { |i| ary[i] = "paiza" } # 作った配列にpaizaを入れていく puts ary.join(' ') # 最後にjoinを使って文字列を連結する
splitを使って文字列を分割
問題:整数 n が与えられ、その後に n 個の整数 a_1, ..., a_n が半角スペース区切りで与えられるので、a_1, ..., a_n をそのままの順番で改行区切りで出力する
例) 整数nが2の場合、例えば1と5が半角スペース区切りで与えられる。それを「1 5」という形で出力する
splitメソッドは文字列を分割して配列にするためのメソッド
自分の回答
n = gets.to_i ary = Array.new ary << gets.to_s.split(' ') puts ary
- mapを使うと短く書くことができる
n = gets.to_i a = gets.split(' ').map(&:to_i) puts a
- map(&:to_i) は、標準入力から取得した文字列をsplitで分割したのち,全ての要素にto_iメソッドを適用している
sprintfを使って0埋めする
問題:標準出力で3桁までのランダムな値を受け取り、その値を0埋めにして3桁の数字を出す
- 自分の回答
n = gets.to_s # 文字列として値を受け取る if n.length == 1 # nが1桁の場合は2つの0を追加 puts "00#{n}" elsif n.length == 2 # nが2桁の場合は1つの0を追加 puts "0#{n}" else # nが3桁の場合はそのまま出力 puts "#{n}" end
- sprintfを使うと短く書くことができる
sprintf は「左寄せ」や、数値の「桁のゼロ埋め」や、「小数点以下の桁指定」など、文字列のフォーマットを指定したいときに便利なメソッド。
sprintf( "フォーマット", 戻したい値 )
の形式で引数を文字列で返す。
n = gets.to_i # 整数として値を受け取る puts sprintf('%03d', n) #sprintfで与えられた引数を指定フォーマットの文字列として返す
<<sprintfのフォーマット>>
\r\n :表示を改行させる
%幅d : 整数値を指定の桁数で右詰めにする
%-幅d :整数値を指定の桁数で左詰めにする
%+幅d :整数値を符号付きで表示する
%0幅d : 整数値の余った空白をゼロで埋めする
%幅.小数点以下桁数f :小数点以下の桁数を指定する
%幅s :文字列を右詰めで表示する。
%-幅s :文字列を左詰めで表示します。
もっともっとrubyのスキルを向上させたいので継続していきたい!
【JavaScript】関数を作る
今回は便利な関数をアウトプットしていきます。
関数とは?
- プログラムの一部をまとめて名前をつけたもの。関数は何度でも呼び出せるので同じ処理を繰り返したい時に便利
関数の書き方
「=>」
マークのアローを使って下記のように書く
let 変数 = () => { 関数で実行する文 };
例1) メールの文面を関数で作る
let createMail = () => { console.log( 'ABC社の山田です。' ); console.log( 'ご請求書をお送りします。' ); } ; // => 呼び出し createMail();
例2) メールの文面を引数を受け取る関数で作る
let createMail = (recv) => { console.log( recv + '様' ); console.log( 'ABC社の山田です。' ); console.log( 'ご請求書をお送りします。' ); } ; // => 呼び出し createMail('小林'); // => 小林様 // => ABC社の山田です。 // => ご請求書をお送りします。
例3) メールの文面が長文の場合
let createMail = (recv, bill) => { let msg = '${recv}様 ABC社の山田です。 ${bill}円のご請求書をお送りします。'; console.log(msg); } ; // => 呼び出し createMail('小林', 10000); // 小林様 // => ABC社の山田です。 // => 10000円のご請求書をお送りします。
例4) 戻り値を関数で返す
let addTax = (bill) => { return bill * 1.10; }; console.log(addTax(11000));
例5) オブジェクトを作る
- 複数のデータを入れる入れ物としてオブジェクトを作る。一人分のデータをオブジェクトに入れる
let data = [ { name:'小林', bill:10000, addTax:true }, { name:'木村', bill:20000, addTax:true }, ]; console.log(data[1]['name']); console.log(data[1]['bill']);
例6) メールを作る関数を組み立てる
let createMail = (recv, apoTime) => { let msg = '${recv}様 ABC社の山田です。 ${ bil }円のご請求書をお送りします。'; console.log(msg); } ; // 消費税が10%の場合 let addTax = (bill) => { return bill * 1.10; }; //送付先データ let data = [ { name:'小林', bill:10000, addTax:true }, { name:'木村', bill:20000, addTax:true }, ]; // メール実行 for(let rec of data) { // 変数dataに所属する要素を、新規作成したrecに順次入れる間、以下を繰り返す let bill = rec['bill'] //変数recのプロパティ「bill」を、新規作成した変数billに入れる if(rec['addTax']){ // もしも変数recのプロパティ「bill」が真なら以下を実行 bill = addTax(bill); // 変数billを指定して消費税を追加し、変数billに入れる } createMail(rec['name'], bill); // 変数recのプロパティ「name」と変数billを指定してメールを作成 } // 小林様 // => ABC社の山田です。 // => 11000円のご請求書をお送りします。 // 木村様 // => ABC社の山田です。 // => 22000円のご請求書をお送りします。
ようやく完成〜。
【JavaScript】繰り返し文を学ぶ
一気に覚えようとせず、毎日少しずつやっていきます。
今回はwhile
とfor
文のアウトプット
while文とは?
- while文は条件を満たす間繰り返ししてくれる処理。条件はあるが、回数が決まっていない時に向いている
例) 残高が0になるまで繰り返す
let shikin = 50000; // 資金変数に50000を代入 while( shikin >= 0 ) { // 資金が0になるまで繰り返す conole.log( shikin ); // 資金を表示 shikin = shikin - 5000; // 変数の資金から5000を引いた結果を変数資金に入れる } // => 50000 // => 45000 // => 40000 // => 35000 // . // . // . // => 0
shikin = shikin - 5000
は代入演算子を使ってshikin -= 5000
と書くことができる
※代入演算子
for文とは?
- 回数が決まった繰り返し処理。繰り返しが始まる前に数値を初期化して、継続条件が真の間繰り返される
for( 初期化; 継続条件; 最終式 ) { 繰り返したい文 }
例1) 同じ文を10回繰り返す
for( let cnt = 0; cnt < 10; cnt++ ) { console.log( 'ハロー!'); } // => ハロー! // => ハロー! // => ハロー! // => ハロー! // . // . // . // => ハロー!
例2) for文で九九の計算
for( let x = 1; x < 10; cnt < 10; x++ ) { for( let y = 1; y < 10; y++) { console.log( x + 'x' + y + '=' + x * y); } } // => 1x1=1 // => 1x2=2 // => 1x3=3 // => 1x4=4 // . // . // . // => 9x8=72 // => 9x9=81
繰り返しを脱出するとき
break
で繰り返し文から脱出。continue
で繰り返し文の先頭に戻って継続
配列を使う
- 配列は「[ ]」の中に複数値を入れられる「型」
例1)let wday = ['月', '火', '水', '木', '金'];
例2) 配列から順番に要素を1つずつ取り出して繰り返し処理をする
let wday = ['月', '火', '水', '木', '金']; // 変数wdayを作成 for( let day of wdays ) { // 変数wdayに所属する変数dayを作成 console.log( day + '曜日' ); } // => 月曜日 // => 火曜日 // => 水曜日 // => 木曜日 // => 金曜日
- 配列を使って総当たり表を作成する。同じ組み合わせを作らないようにするのが難しい。。。
let team = [ 'A', 'B', 'C', 'D', 'E' ]; let opps = [ 'A', 'B', 'C', 'D', 'E' ]; for( let t1 of team) { // 変数teamに所属する要素を、新規作成した変数t1に順次入れる間、以下を繰り返す opps.shift(); // 変数oppsの先頭要素を削除 for(let t2 of opps) { // 変数oppsに所属する要素を、新規作成した変数t2に順次入れる間、以下を繰り返す console.log( t1 + 'vs' + t2 ); } } // => AvsB // => AvsC // => AvsD // => AvsE // => BvsC //. //. //.
【JavaScript】基礎を学ぶ
最近、JavaScriptを学びはじめたのでアウトプットしていきます。
JavaScriptとは?
- Webブラウザ内で動くプログラミング言語
- ユーザが直接操作するユーザインターフェースを作るために使われる
- 具体的には、更新されたコンテンツの定期表示や、インタラクティブな地図や、2D/3D グラフィックのアニメーションや、ビデオジュークボックスのスクロールなどJavaScriptが多分使われている
- ユーザインターフェースを作成するHTMLやCSSと組み合わせて使う。JavaScriptは動的にコンテンツを更新したり、マルチメディアを管理したり、その他多くのことができるスクリプト言語
バージョンは?
- 現在で一番新しいバージョンは、ECMAScript 2021かな?
source:JavaScript って何?
JavaScript は Netscape という会社が開発を進めていたが、途中で欧州電子計算機工業会(ECMA: European Computer Manufacturers Association)が標準化を進めるようになった。なので、ECMAScript (ECMA-262)とも呼ばれる
基本的なメソッド
- 出力
console.log("Hello world!");
# => Hello world!
console.log( 10 * 5 ); # => 50 console.log( 2 * 2.5 ); # => 4.5 console.log( ( 2 + 10 ) * 5 ); # => 60 console.log( 5/ (4 * ( 1- 0.2 ) ) ); # => 1.5624
変数
- 変数を作るには、
let
を使う。英語のlet beが由来している。let
はES2015のバージョンで追加されたものでES5のバージョンではvar
が主流の書き方。ちなみに現在もvar
は多くのプログラムで使われている
let text = "Hello world!" console.log( text ); # => Hello world!
- 予約語と同じ変数名はつけられないので注意!
文字列を数値に変換する
prompt
メソッドで入力した値を数値として計算できるようにする場合、parseInt
を使う
let kakaku = prompt( "定価を入力せよ!" ); console.log( parseInt( kakaku ) + 100 );
条件分岐で年齢層を分析するプログラム
- 条件分岐はif文を使う。比較演算子を使うとより細かく条件分岐ができる
isNaN
関数を使って書いていく。isNaN
関数は、渡された値が数値に変換可能ならfalse、変換が不可能ならtrueを返す
let text = prompt( '年齢は?' ); if ( ! isNaN( text ) ) { # もしも変数textが数値に変換不可が真ならば以下を実行 let age = parseInt( text ); if (age < 20 ) { console.log( '未成年' ); if ( age >= 6 && age >= 15 ) { # もしも変数ageが数値6以上、かつ変数ageが数値15以下が真なら以下を返す console.log( '義務教育' ); } } else if( age < 65 ) { console.log( '成人' ); } else { console.log(' 高齢者' ); } }
磨穿鉄硯で学んでいきます。
【HTML】フォーム部品を作る
今回は、HTMLのフォームタグを復習したので見返して使えるように簡単な備忘録として残します。
色々なフォーム部品がある。
1行テキストのフォーム
<input type="text"> <input type="text", value="hello"> # value属性で初期値を入れておける。画像の左から2番目
パスワードのフォーム
<input type="password"> # 画像の左から3番目
複数行テキストのフォーム
<textarea name="テスト">ああああ※初期値はここに入力する</textarea> # 画像の一番右
入力例を入れておきたい場合
- 記入例を入れるには、
placeholder
を使う。placeholder
は入力をはじめると消えてしまう
<input type = "text" placeholder = "yskmtg'sブログ">
フォームにラベルをつける
- ラベルと入力フォームを紐づける必要がある。下記の「名前」を押しても入力欄で入力できるようになる
<label for = "name">名前</label> <input type = "text" id = "name">
- 一文で書くこともできる
<label >名前<input type = "text"> </label>
ドロップダウンリストをつける
<body> <label for = "side menu">サイドメニュー</label> <select id="side menu"> <option></option> <option>サラダ</option> <option>ポテト</option> <option>アイスクリーム</option> <option>ドリンクバー</option> </select> </body>
- size属性で表示数を指定できる。selectd属性でデフォルトで選択してある値を決められる。またmultiple属性で複数選択できる
<body> <label for = "side menu">サイドメニュー</label> <select id="side menu" size = "3" multiple> <option></option> <option selectd>サラダ</option> <option>ポテト</option> <option>アイスクリーム</option> <option>ドリンクバー</option> </select> </body>
チェックボックスをつける
- チェックボックスのラベルとフォームは紐付けて文字を押しただけでもチェックされるようにする。checked属性で最初にチェックしておく項目を決められる
<body> <fieldset> <legend>サイドメニュー</legend> <label><input type = "checkbox" checked>サラダ</label> <label><input type = "checkbox">ポテト</label> <label><input type = "checkbox">アイスクリーム</label> <label><input type = "checkbox">ドリンクバー</label> </fieldset> </body>
ラジオボランをつける
- 上記の"checkbox"を"radio"に変更する。checked属性で最初にチェックしておく項目を決められる。またname属性を設定するとチェックは1つだけつけられるようになる
<body> <fieldset> <legend>サイドメニュー</legend> <label><input type = "radio" name = "side menu" checked>サラダ</label> <label><input type = "radio" name = "side menu">ポテト</label> <label><input type = "radio" name = "side menu">アイスクリーム</label> <label><input type = "radio" name = "side menu">ドリンクバー</label> </fieldset> </body>
- 他にも
type = "color"
,type = "date"
,type = "number"
,type = "range"
などの入力部品がある。ただ古いブラウザだとサポートされていないので注意が必要!
ボタンをつける
- disabledでボタンを押せない設定にもできる
<body> <input type = "button" value = "OK"> <button>OK</button> <input type = "button" value = "OK" disabled> <button disabled>OK</button> </body>
【HTML】区切りを表すタグ
HTMLの区切りタグを復習したのでアウトプットをしていきます。
HTMLの区切りを表すタグの種類
header: 導入的なコンテンツ
fotter: コンテンツの締めくくりとして使われる。著作権情報などが入る
nav: ページ内のナビゲーションに使われる。メニューのリンクなど
asaide: 本文とは関連性が薄いコンテンツに使われる
article: 記事や独立したコンテンツに使われる
main: 本文の主要なコンテンツを使う処理
section: 汎用的に使えるタグ
人によって文書の解釈方法は色々なので、人によってマークアップした結果が違うことも...。
迷ったらHTML: HyperText Markup Language | MDNをチェック!
例えば、<h1>タグの子要素には<section>タグを使えない!など色々と調べることができる。
あまり考えすぎず、でもわかりやすくタグを使っていけるよう注意したい!