学習記録 (2月7-11日 )

2/8

  • Ajax (Asynchronous Javascript and XLS) Javascrpitによるサーバとの通信通信、画面遷移を伴わない ブラウザ上は部分的に更新される 画面遷移のタイミング(セキュリティ上の注意点)がわかりづらくなる WebアプリケーションもAjaxを利用するものとしないものがある
  • Ajaxは外部サイトとの連携に用いられる
  • JSONP:JSONデータのクロスドメインでの通信を可能にする可能にする技術 HTML/XHTMLは"script"タグの異なるドメインでのデータの取得ができる

2/9

  • バイナリーセーフ %00のような制御文字をデコードできる。
  • パーセントエンコードはマルチバイト文字(日本語)や制御文字を表現できる。%と16進法の文字で表示
  • HTTPレスポンスはライン、ヘッダ、ボディで構成されている
  • 3xxで示されるステータスコードはレスポンスヘッダの情報をもとにリダイレクトを行う。"Location"ヘッダーへ転送される。
  • ヘッダに改行を入れると任意のヘッダを追加することができる。
  • SQLインジェクション: アプリケーションが想定しないSQL文を実行させる
  • 能動的攻撃: ターゲットのサーバにコードを挿入、サーバの情報の取得、改ざん、不正利用
  • 受動的(誘導型)攻撃: サーバ上に罠を仕掛けユーザが実行することを強要する。
  • セッション管理 WebアプリケーションあるいはWebサーバレベルで管理番号を発行して、複数に渡る通信間の関連性を実現している。共有するしくみはCookieを利用するものと、GET/POSTパラメタなどを利用するものがある。
  • サーバがセッションIDを発行し、自身にも格納する
  • トークンと呼ばれるセッション管理用のパラメータがPOSTパラメータでも使われる
  • セッション変数:ログインIDを格納する。
  • 格納の形態はファイル、データベース、メモリ上で行われる
  • セッション変数は認証管理に利用されることが多い。
  • 入力値の検証?エスケープ?
  • 入力と出力の異なるwebアプリケーションはツールによる脆弱性の自動検知は難しい。
  • 脆弱性:セッションフィクセーション、攻撃者がユーザに指定したセッションIDを使わせる。ログインのセッションが乗っ取られてしまうので、多くのサイトでは成功時のIDを破棄して再発行する。

2/11

  • Telnet(teletype network) :
  • TelnetクライアントとTelnetサーバの間でソケットを開き的ステベースの通信を行う、暗号化せずに通信を行う。同様な機能を持ち、通信内容を暗号化する"SSH"プロトコル
  • CGI (Common Gateway Interface) : サーバ上でプログラムを動かすための仕組み、プログラムがその場でページを作って返す。
  • telnet (wwwサーバ名) (ポート番号)
  • CGIに渡した環境変数がレスポンスのbodyに入って返ってきている。

Mac標準のターミナルからApacheを起動する Apacheの起動 sudo apachectl start

ブラウザで http://127.0.0.1/ を確認すると、「It works!」と表示されるかと思います。ソース - 起動した後にtelnet localhot 80で接続できた。 - 同様にtelnet localhot 127.0.0.1 80でも接続できた。続いて

GET / HTTP/1.1
Host: localhost

を入力して

HTTP/1.1 200 OK
Date: Fri, 11 Feb 2022 08:12:32 GMT
Server: Apache/2.4.34 (Unix)
Content-Location: index.html.en
Vary: negotiate
TCN: choice
Last-Modified: Fri, 09 Sep 2016 05:02:59 GMT
ETag: "2c-53c0c0f6366c0"
Accept-Ranges: bytes
Content-Length: 44
Content-Type: text/html

<html><body><h1>It works!</h1></body></html>Connection closed by foreign host.

が戻ってきた。

  • HTTPSのサイトに接続したい場合はopensslコマンドを利用する

    openssl s_client -connect ホスト名:443 -crlf

  • 0-1023番までのポートをウェルノウンポートという
  • URLの入力、リンクのクリック、テクストの送信これらの操作がGETやPOSTを送信している。
  • burp suiteのローカルでブラウザの挙動をモニターすることができる。

学習記録 (2月6日 )

<作業と学んだこと>

ボウリング課題コード解説

メソッドの複数の引数が別々の箇所に参照されている。

def add_bonus(rolls, following_pinfalls)
  if strike?(rolls)
    following_pinfalls.first(2).sum
  elsif spare?(rolls)
    following_pinfalls.first
  else
    0
  end
end

様々な式が入っているが、最終的に出力する値として最後に変数を記述され、.sumされている。

def calc_score(pinfall_text)
  pinfalls = parse_pinfall_text(pinfall_text)
  frames = []
  pinfalls.each_with_index.sum do |pinfall, index|
    frames << [] if next_frame?(frames)
    rolls = frames.last
    rolls << pinfall
    following_pinfalls = pinfalls[index.succ..]
    last_frame?(frames) ? pinfall : pinfall + add_bonus(rolls, following_pinfalls)
  end
end

すごいなー、数列を変えずにそのまま足しておしまい。 全部順に足していけばいいけれど、rolls(直近のフレーム)によって動きが変わる。それを一気に配列から新しい配列に流し込む。 add bonus、終わったフレーム終わっていないのフレームの間で投球の加点計算している。メソッドの中に定義した変数をその中に呼び出したメソッドに代入している。配列を別の形の配列に作り変えるメソッドを作る、ということがカレンダー、ボーリング、lsそれぞれのプラクティス共通していた。

メインのメソッドとそれに付随するメソッド、という構造という形式。 lsメソッドの参考にさせていただきました。

学んだこと

ボウリング課題メンター提出コード学習 その2 - succメソッド : 与えた値の次の値。+1

  • 組み込みライブラリの中にクラスやモジュールが含まれる
  • const_getメソッド : nameで指定されている定数の値を取り出す。
module Bar
  BAR = 1
end

class Object
  include Bar
end

p Object.const_get(:BAR) #=>1

モジュールとクラスの関係 クラスやモジュールのネストは::で表現される。

module Parent
 class Child
 end
end

# Parent.class #=> Module
# Parent::Child.class #=> Class

defined?(クラス名/モジュール名)メソッドでtrueであれば"constant"が戻る。クラスやモジュールが定義された時、Objectクラスにコンスタント(定数)が追加され、定義されたクラスあるいはモジュールのクラスインスタンスが値として格納される。

  • ボーリング課題、メンター提出物のメソッド定義のやり方を参考に、ls課題を改善。

  • dupメソッド(:instance method Objecct#clone) オブジェクトを複製して返す

  • object_copy = object_original.dup 複製されたオブジェクトは新しいIdを保つため、複製元の変更の影響を受けない(代入による新しい変数は影響を受ける。=オブジェクトid共有)
  • clearメソッド:(instance methos Array#clear): 配列の要素を空にする
  • ||= 演算子 a||=b a||(a=b) aが未設定 or falseの時にbを代入 "数値が存在すればそれ、なければ代入"ができる
  • frame, next_frame, after_next_frame = frames.slice(n, 3) 配列名を複数用意し、sliceの戻り値をそれぞれに代入
  • fetchメソッド:(instance method Array#fetch) ハッシュに対してはキーを渡して値を取得 a = [1,2,3] a[0]とa.fetch(0)は同じ

HTTP関連 - 仮装ホスト:同じサーバの中に仮装のホストを設定し、別コンテンツを設置する - クロスサイトスクリプティング,SQLインジェクション - MacOSからtelneを使う。homebrewでインストール - GET / HTTP/1.1 - HOST : www.example.com - はブラウザに www.example.comと入力したのとほぼ同じ - まずは open www.example.com それにくわえてHTTPリクエスト。 - メソッドの後のURIはURLの中の絶対パス以降の部分。 - GETメソッドは最後に改行のみを送ることで、HTTPリクエストが終了となる

2/5 学習記録

学習したこと - メンバ変数とは

  • アクセサメソッドの復習
class User
  def initialize(name)
    @name = name
  end

  def name # arr_reader部分 .nameで呼び出し
    @name
  end

  def name = (value) #attr_writer部分 name= で書き込み
    @name = value
  end

は以下と同じ

class User

  attr_accessor :name

  der initialize(name)
    @name = name
  end

end
  • pushメソッド :配列後尾に要素追加
  • transposeメソッド:行列を入れ替える/.to_hを使うことでハッシュに変換できるソース
  • zipメソッド:別々の配列をハッシュにまとめる
  • flattenメソッド:入れ子になった配列を平坦にする,mapと組み合わせたflat_map
  • injectメソッド:
numbers = [1,2,3,4]
sum = numbers.inject(0){ [result,n] result + n }
sum #=> 10

0をresultの初期値として、ブロックの第2引数(配列の各要素)との戻り値をresultに返して繰り返す。

  • each_slice(n) : n個の要素ずつブロックに渡して、配列にして返す。
  • each_slice(n).to_a : 配列をn個の要素に分けるて配列にして返す。
  • 配列[n..m]: 配列のn~m番目の配列を取り出す。 頭からnこの場合は配列.first(2)
  • each_with_index : ブロック|n,i|の第2引数は0から始まるインデックス
  • pushは文字列を指定、複数要素の配列を追加する場合は'concat'メソッド
  • select/find : 配列の中の要件を満たすものを抽出、rejectはその逆
  • たぶ文字の表記はバックスラッシュ記法で\t。""で囲まなければバックスラッシュが認識されない。  ''の場合はバックスラッシュのまま表現できる。
  • 文字列の足し算と同じように * を使えば複数回入力できる。
  • max:配列の最大値、引数nをつけると最大からn個を配列で返す。ブロックに渡した場合ブロックの戻り値(配列を)を
  • <=> : 基本的な比較演算子 左が大きければ1、等しければ0、右が大きければ-1
  • floor : 切り捨て(Floatクラス) 引数nで少数点以下n桁を出力
  • ceil : 切り上げ(Floatクラス)
  • round : 四捨五入 マイナス引数で整数分四の捨五入。
  • 命名規則:メソッド名、変数名はすべて小文字、スネークケース

クラスを使う

  • クラスを定義 : データの種類/キーを定義
  • データを作成 : インスタンスを生成し、配列にする
  • インスタンスの中のメソッドを呼び出してメソッドを作る
  • あるいはクラスの中にメソッドを作っておく

1/19 学習記録 (ボーリングスコア計算プログラム)

🔶 ボウリングスコア計算プログラム


///昨日まで/// 考え方 それぞれのフレームのスコアを
[1投目+2投目,ストライク/スペアの際の追加点,ストライクの際の追加点]
で考えて、10フレーム分合算する。
入力はカンマ区切りの文字列、出力は数値(integer/string)
0. shellの文字列入力(optparse)
1. 文字列を10フレームの配列に変換(Xは10に変換)
2. (スペア)フレームの合計 == 10 の場合次要素の0番目の数値を取得し合計
3. (ストライク)一投目が10の場合は次要素の合計を取得

調べる必要があるメソッド:配列の要素を合計するメソッド
注意点:1フレーム目が0番目の要素

0. shellの文字列入力(optparse)

1. 文字列を10フレームの配列に変換(Xは10に変換)

str = "123456"
array = str.split("34")
p array

=>["12", "56"]

これでカンマ区切りで要素に分ける

///今日はここから/// 調べる必要のあるもの - 配列の要素の指定の仕方と取り出し方(超入門 p.196) 配列の要素の取得 配列名[順番] 配列の作成配列名=[要素,要素,,,,] 配列の繰り返し処理 配列名.each do

これで配列から要素を取り出せる。 計算する際には整数に変換

indexメソッド 配列あるいは数値の中で所定の数値の最初に位置を出力

= "ROMACECARVSEMSEEXEGSE"

p s.index("CE")

これは最初の文字列を置換した方が良さそうだ。

オプション無しのシェル引数入力

puts ARGV[0]

Argument Vector配列の1番目という意味。 だけ。。。

文字列の置換

  • subは最初の一文字、gsubは全部の文字を置換。subはindexメソッドみたいだな。
string = "ruby ruby ruby"
puts string.gsub(/ruby/, 'python')

ということは、、、

6,3,9,0,0,3,8,2,7,3,10,9,1,8,0,10,6,4,5

できた!置換したい文字列は""でも’’でも行けるようです。 これで数値は全部変換できているはず。 gsubは破壊的ではないので変数に代入。

フレームごとの配列を作る

  • と思ったら、10の回はフレームに1投しかないから、2投目を入れる置換に変更 あれ、でも2投目に10が出たら?
  • 配列の最初の2投を取得し,その2投をshift
  • ただし1つ目が10の場合は、1つめを取得し,2つめは0,1つ目をshift まずは文字列を配列に変換。
throw1=scores_array[0,1]

かな。

throw1=scores_array[0],scores_array[1]

だった。それから先頭2要素削除、shiftは先頭のみなのでslice!を使う。

#要素序列から要素数
a = ["a", "b", "c", "d", "e"]
a.slice!(1, 3)
print a # ["a", "e"]

#要素序列から要素序列
a = ["a", "b", "c", "d", "e"]
a.slice!(1..3)
print a # ["a", "e"]

自分の場合は(0..1)あるいは(0,2)。 !入れないと反映してくれないのね。 ではこの調子で、10投目まで。最後に1投残るwww 繰り返し 苦手なやつ,,,n=1 から初めて、、、while n<11か irbよろしく。って言うかその前に超入門! 配列を順番に名前をつけながら生成するのってどうやるの。。。

名前に連番をつける => give up

eval変数? obj.instance_variable_set(name, val)? 手入力します。

配列の調整

一投目が10の場合は["10",0]になるように 投球数が変わるだけなのに、これが長い。。。ダメ回答だと思う。 でも先に進む。

2. (スペア)フレームの合計

10 の場合次要素の0番目の数値を取得し合計 今度は数値の計算だけど、n投目がストライクの時、n+1投目の、、、という指定ができなかった。。と言うことは配列の中でやるのいいのかな。 そうなると、配列を分けずに、の中で配列を調整していくのが正解だったと言うことか、、、

それは後でやるとして。(多分作ったif式が後で役にたつ) とりあえず、配列を合体させる。

???後でn番目の配列のn番目としておいたほうがいいから、配列に配列を入れたほうが使いやすいかも。

今まで作った配列の中に配列を入れてみる。 (オブジェクト名)=オブジェクト,オブジェクト,,, 自分の得意技とかでできそう。。。好みというか。 これを整数に直しておく。

出てきた整数がおかしい、、、変数の名前を入れ間違えていた。

気を取り直してもう一度計算

n投目 if (n投目の要素0) == 10
10 +(n+1投目の要素0)+(n+1投目の要素1)"
elsif (n投目の要素0)+(n投目の要素1) == 10
(n投目の要素0)+(n投目の要素1) +(n+1投目の要素0)
else (n投目の要素0)+(n投目の要素)

  • 二次元配列
`ary = Array.new(3, Array.new(3, "a") )
ary[0][0] = 1
p ary
#=> [[1, "a", "a"], [1, "a", "a"], [1, "a", "a"]]

ary = Array.new(3).map{Array.new(3,0)}
ary[0][0] = 1
p ary
#=> [[1, "a", "a"], ["a", "a", "a"], ["a", "a", "a"]]`

これでいける


ここでほうぼうで出てくるmapをおさらい。 eachに似ているが、eachは一つずつ処理をするだけ。

array = [1, 2, 3]
array.each do |item|
  p item * 2
end
2
4
6
#array = [1, 2, 3]は変わらず
array = [1, 2, 3]
result = array.map do |item|
  item * 2
end
array = [1, 2, 3]
result = array.map do |item|
  item * 2
end
p array #=> [1, 2, 3]
p result  #=> [2, 4, 6]

超入門もう一度読み直す必要あり。


ガチャガチャやって、ようやくできたー。 ひたすら場合分けでした!

RUBYのバージョン切り替え

$ which ruby
/usr/bin/ruby

これはrubybashで実行した時のパス。 rbenvのrubyではなくmacデフォルトのrubyを実行していることがわかる。

$ echo $PATH 

現在通っているパスの名称

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin

rbenvはこの前にshimsが入っていてほしい

~/.rbenv/shims:/usr/local/bin:/usr/bin:/bin

rubocopでチェック

  • 以下のコマンドを実行すると、設定ファイル(.rubocop.yml)を作成してくれ、かつ検出された規約違反を読み飛ばすための設定を(.rubocop_todo.yml)に記載してくれます。 $ rubocop --auto-gen-config <ソース>

生成されたファイルにrubyプログラムの場合(非rails) rubocop-fjordをインストールした上で.rubocop.ymlに下記の設定を追加する。

inherit_gem:
  rubocop-fjord:
    - "config/rubocop.yml"

改めて実行すると、

1 file inspected, no offenses detected

ノーマルrubocopだと152offencesだったのに。 これで良さそうなので提出!

1/18 学習記録 (カレンダープログラム/gem/bundler/debug/ボーリングスコア計算)

<目標>

  • カレンダープログラム終了する
  • 丁寧に作業する ペースを守る
  • モチベーションをキープする
  • 12ポモドーロ
  • 日報の時間を測る
  • privateに関する技術書を読む
  • 他の方の日報を読む

<メモ>

🔶カレンダープログラム作成(今日で終わりにしたい)

月によってカレンダーの行数が変わる。 行数を固定すると空行ができてしまうので対応してみる。

< 1 > color-echo?

色をつける. colorechoというgemを使ってみると反転はできるみたい。。。

< 2 > ASNIの世界 (20分)

print "\e[31mhello\e[0m"

これによりターミナル上に赤文字で「hello」と出力されます。この”\e[31m” “\e[0m”の部分がエスケープシーケンスです。”\e[31m”はそれ以降を赤文字で出力する制御命令、”\e[0m”はそれ以降を初期状態へリセットする制御命令です。 シーケンス中の数字において、30~37は文字色、40~47は背景色、0~9は文字装飾に割り振られています。

40-47は背景色か、、、47が白。

print "\e[30m\e[47mhello\e[0m"

これで背景白、文字黒になった。文字がややこし感じる人間の頭。。。

< 3 > 文字の置換

  • .subはstringに使われるので、置換される文字もstringである。 とにかく文字の認識 //や""や’’は厳密に。。。 見当たらない場合は空を返す。。。

35分経過

a=102

array = [101,102,103]
array2 = array.join
puts array2
puts array2.sub!(/#{a}/,"\e[30m\e[47m#{a}\e[0m")
taku-no-MacBook-Pro:02.calendar takunaka$ ruby test.rb
101102103
101102103#(実際は102の色が反転している)

ここまでできた。置換は一致しないと空が帰ってくる。 それに時間がかかる。。。

< 4 > subについて 5min

一致しない場合は空の文字列を返す、、、

< 5 > 配列の要素の変換 35m

配列の中の要素を置換することはできるか。

(余談) 途中でチェックしたい時には binding.pryを入れる。 irbと同じようなことができる。

array = ["foo","bar","baz"]

# arrayから"bar"を検索して"hoge"で置換します。
array.map!{|x| x=="bar" ? "hoge" : x}

puts array
#=> ["foo","hoge","baz"]
array = ["foo","bar","baz"]

# arrayから"bar"を検索して"hoge"で置換します。
array[array.index("bar")] = "hoge"

puts array
#=> ["foo","hoge","baz"]

晴れて色の反転できました。

コードの書き換え完了

ここまで。

文字列で扱えればもっとスマートだったんだけれど。。。 課題文字列を幅を決めて改行したい。 subの空行はまだ勉強必要。 色の反転までできてよかった!

< 6 > GITで提出 (25min)

  • branchを指定してpush。branchによって保存されているファイルが異なることがわかった。

< 7 > 課題のレビュー (20min)

binding.irb (15min) binding.irbを使わなかったので、後で学習。 確かにこれは使わないといけない。使ってたらもっと早く終わってた。 次回のコーディングからしっかり使おう。 15分の手間。。。

Rubyドキュメント (30min)

Enumerator

参考資料のおさらい、他の方のコード (10min) RUBYドキュメント。読み方がまだはっきりわからない。 超入門の理解が不徹底だからだと思う。 他の方のコードはまだ見れません。。。

🔶 RUBYGEMの基本を理解する

What is A Gem 20分

公式ページ、丁寧に描かれている。15分、また来ます。 libにコードが入っていて、binに実行コマンドが入っている。 gemspecにgemの内容が書いてある。

よく使うGEMのコマンドオプション

gem search -r

^ と $ を用いることで完全一致検索ができます.

gem search -r ^rails$ REMOTE GEMS rails (3.2.12)

インストール済みの GEMを表示

gem list

インストール済みのGEMのパスをか確認

gem which rails

-dは詳細の表示

RUBYライブラリ(5min)

公式ページ

The Ruby Toolbox は、オープンソースRuby プロジェクトを探索しやすくするプロジェクトです。

るびま (15min)

パッケージマネジメント環境の標準の話

Byebugチュートリアル (120min)

デバッガ - c(continue)行数で指定の行へ - step(s)で実行の止まっている行へ -> finish(fin)で最後までスキップして止まる、数値を入れるとその回数実行 - restartで最初に戻る - nestで次の行へ、リターンで再入力 - break (行数)でブレークポイントを設定(cで止まる) - 他のファイルにもブレークポイントを設定できる break ./lib/fizz_buzz.rb:2 - ブレークポイントの管理i binfo breakpoints - ブレークポイントのon/offen b/dis bdisable/enable breakpoints <ID> infoの Enbが y/nで切り替わる - delete (ID)でブレークポイントの消去 - if n == 4 引数nに4が渡された時に止まる行にブレークポイントを追加 - listで周辺コードを表示 - quit``q!で終了 - コマンドラインからbyebugを実行できない場合はプログラムの中に require 'byebug'; byebug書き込むことで実行できる。 - -rbyebugオプションでrequire 'byebug'; byebugbyebugに省略できる - $ ruby -rbyebug ./test/fizz_buzz_test.rb

pry-byebug

  • help Byebugでコマンドの確認
  • !!!で強制終了

byebugコマンド

コマンド 短縮形 説明 continue c または cont プログラムの実行を再開する help h コマンドのヘルプを表示する step s ステップ実行する(ステップイン) finish fin ステップアウトする restart プログラムを最初からやり直す next n ステップ実行する(ステップオーバー) (リターン) 直前のコマンドを繰り返す break b ブレークポイントの追加 info breakpoints i b ブレークポイントの一覧表示 enable breakpoints en b ブレークポイントの有効化 disable breakpoints dis b ブレークポイントの無効化 delete del ブレークポイントの削除 eval 変数やメソッドの値を確認する list l 停止中の周辺コードを表示する quit q Byebugの終了(確認あり) quit unconditionally q! Byebugの終了(確認なし)

次回からbyebug導入

後もうちょっと。 デバッグ解説動画. 先輩の肉声解説!とても勉強になりました。 better-errors GEM コードのファイルをリアルタイムプレビューできる、デバッグもできる RubyMineでデバッグをする テストコードを作る。 質問ができるのは stackoverflow/tratrail/QA@IT

このプラクティス終わりで、休みいれます。15分。

🔶 RUBYGEMの基本を理解する(30min)

🔶 bundlerの基本を理解する(15min)

ACTIVE SUPPORTは便利 .

今までbundlerでGEMのインストールをしてきたので理解できた。 Gemfileの中身の解説があって勉強になった。

🔶 rubocop の使い方を知る(40min)

  • コーディング規則というものがある。rubocopでチェック
  • rubocop-fjordはrubocopのfijord向け設定
  • インストールできず焦る。。。

🔶 ボウリングスコア計算プログラム

考え方

それぞれのフレームのスコアを[1投目+2投目,ストライク/スペアの際の追加点,ストライクの際の追加点] で考えて、10フレーム分合算する。 入力はカンマ区切りの文字列、出力は数値(integer/string)

  1. shellの文字列入力(optparse)
  2. 文字列を10フレームの配列に変換(Xは10に変換)
  3. (スペア)フレームの合計 == 10 の場合次要素の0番目の数値を取得し合計
  4. (ストライク)一投目が10の場合は次要素の合計を取得

調べる必要があるメソッド:配列の要素を合計するメソッド 注意点:1フレーム目が0番目の要素

0. shellの文字列入力(optparse)

1. 文字列を10フレームの配列に変換(Xは10に変換)

str = "123456"
array = str.split("34")
p array

=>["12", "56"]

これでカンマ区切りで要素に分ける

今日はここまで

1/17 学習記録 (カレンダープログラム)

<目標>

  • カレンダープログラム終了する
  • 丁寧に作業する ペースを守る
  • モチベーションをキープする
  • 12ポモドーロ
  • 日報の時間を測る
  • privateに関する技術書を読む
  • 他の方の日報を読む

<メモ>

カレンダープログラム作成

$ ./cal.rb -y 2020 -m 11 
      11月 2020        
日 月 火 水 木 金 土  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
15 16 17 18 19 20 21  
22 23 24 25 26 27 28  
29 30

これを表示させる。全然わからない。

クリアすべきこと(おそらく)。

  1. shell コマンドでのオプション設定 (-y&-m)OK 3
  2. 1行目の?月 ?年の表示 OK 2
  3. 2行目の曜日表示 OK 4
  4. カレンダー表示コマンドを探す OK 1
  5. 日にちの横並び表示OK 6
  6. 日にちの7日ごとの折り返し表示OK 7
  7. 1日目を表示する曜日の設定OK 5

  8. shellでのruby入力を省略するOK 8

でしょうか。。。

順番

  1. カレンダー表示コマンドを探す
  2. 1行目の?月 ?年の表示
  3. shell コマンドでのオプション設定 (-y&-m)
    • シェルコマンドから数値入力できた
  4. 2行目の曜日表示

  5. 日にちの横並び表示

  6. 日にちの7日ごとの折り返し表示

<1> shell コマンドでのオプション設定 (-y&-m)

.

引数付きショートネームオプションの処理.

  • オプションに:をつける
#!/usr/bin/env ruby
require 'optparse'

options = ARGV.getopts('a:')
puts options
% ./arg.rb -a 111
{"a"=>"111"}
#!/usr/bin/env ruby

これ何?、、、shebangでした!直接ファイルに書いてよし! なるほどー。ほんとかなー。

#!/usr/bin/env ruby
require 'optparse'
options = ARGV.getopts('y:','m:')
puts options
puts options["y"]
puts options["m"]
{"y"=>"2020", "m"=>"11"}
2020
11

よっしゃー。ARGV.getopts('y:','m:')はハッシュを出力してたんですねー。これでシェルとRubyが繋がった! で持ってハッシュから取り出した数字はSTRINGだったので、それをINTEGERに変更。


< 2 > 1行目の?月?年の表示.

time = Time.now
 
p time
p time.strftime("%Y年%-m月%-d日 %-H時%-M分%-S秒")

実行結果

2018-01-02 03:04:05 +0900
"2018年1月2日 3時4分5秒"
time = Time.now
p time.strftime("%-m月%Y")

この時間入力を

date = Date.new(2020,11.1)
p date.strftime("%-m月%Y")

に変更して

"11月2020" 

が得られる。 これにシェルから入力できるようにする。 pではなくputsメソッドでダブルクオーテーションが取れた :) (p (数値)は""なしで出力される)


<4> カレンダー表示コマンドを探す

Date.parseの使い方

date = Date.parse("2018/02/26")
p date
#=>#<Date: 2018-02-26 ((2458176j,0s,0n),+0s,2299161j)>
date = Date.parse("2018/3/3")
p date
#=#<Date: 2018-03-03 ((2458181j,0s,0n),+0s,
2299161j)>
>date = Date.parse("20181126")
p date
#= #<Date: 2018-11-26 ((2458449j,0s,0n),+0s,2299161j)>

Dateクラス.

require 'date'

a = Date.new(1993, 2, 24)
b = Date.parse('1993-02-24')
b += 10

b - a            #=> 10
b.year           #=> 1993
b.strftime('%a') #=> "Sat"

yesterday = Date.today - 1

曜日が出てきた! これを入力したらその月の初めの日が何曜日が特定できる

.strftimeメソッド

表示を選べる

入力した日付と曜日を表示

require 'date'
a = Date.new(2020, 11, 1)
p a.strftime('%a') #=> "Sat"

曜日の日本語表示.

require 'date'
 
date = Date.today
 
weeks = ["","","","","","",""]
 
index = date.strftime("%u").to_i
 
p date.strftime("%Y年%-m月%-d日 %u")
p date.strftime("%Y年%-m月%-d日 #{weeks[index - 1]}曜日")

<5> 日にちの横並び表示

n=0
while n<10
n += 1 
printf "#{n} "
end
printf "\n"

\で改行

7. 1日目を表示する曜日の設定

一日目を表示する曜日の設定

day = date.strftime('%a')
p day
case day
    when "Mon"
    puts"00"
    when "Tue"
    puts"0000"
    when "Wed"
    puts"000000"
    when "Thu"
    puts"00000000"
    when "Fri"
    puts"0000000000"
    when "Sat"
    puts"000000000000"
end

この後に一日目からの文字列を入れる

if
n=0
while n<10
n += 1 
printf "#{n} "

end

whileの上限は閏年を分けて月ごとに設定

if year%4==0 and year%400!=0 
    case 
    when month == 4 , month == 6 , month == 9 ,month == 11
    puts "30" 
    when month == 1 , month == 3 , month == 5 , month == 7 , month == 8 ,month == 10||month == 12
    puts "31 "
    when month == 2
    puts "29 "
    end
else
    case 
    when month == 4 , month == 6 , month == 9 ,month == 11
    puts "30" 
    when month == 1 , month == 3 , month == 5 , month == 7 , month == 8 ,month == 10||month == 12
    puts "31"
    when month == 2
    puts "28"
    end
end

whenのor設定は

case month
    when 4 , 6 , 9 , 11

case 
when month == 4 , month == 6 , month == 9 ,month == 11

のどちらか。比較演算子

month = 6

puts month == 5 || month == 6

month ==表記のみ、当たり前か。caseの条件表記が簡素化されている。

つなげて表示

if year%4==0 and year%400!=0 
    case month
    when 4 , 6 , 9 , 11
    last = "30" 
    when 1 , 3 , 5 , 7 , 8 , 10, 12
    last = "31 "
    when 2
    last = "29 "
    end
else
    case month
    when 4 , 6 , 9 , 11
    last = "30" 
    when 1 , 3 , 5 , 7 , 8 , 10, 12
    last = "31"
    when 2
    last = "28"
     end
end

n=0
while n<last.to_i
n += 1 
printf " #{n}"
end
printf "\n"

カレンダーは1桁の数字も2桁表示。 でも全部の文字列の前にスペースが表示される。。。1桁なら2桁スペース。2桁なら3桁。。。バカっぽいけどマニュアルで付け足す

n += 1 
    if n < 10
    printf "  #{n}"
    else
    printf " #{n}"
    end
end

できた。次は00123..の文字列を連結。Joinだっけ?

array = ["GSE", "VSE", "MSE"]

puts array.join

#=>

GSEVSEMSE

違った。ちなみに、

array = ["GSE", "VSE", "MSE"]
puts array.join(",")

#=>

GSE,VSE,MSE

って足し算でよかったみたい。。。 ちなみにいろいろな文字列連結 メソッドによって処理スピードが700倍差が出るそうです。

と思ったら、printfは文字列を作っているのではく、改行せずに文字を出力しているから、文字列に見えていただけで、これを文字列にすることができず、一度配列にpush。

n=0
while n<31
n += 1 
    if n < 10
    monthly_date.push("  #{n}")
    else 
    monthly_date.push(" #{n}")  
    end
end

puts monthly_date

ここで.joinの出番?

puts monthly_date.join

で 横並びの文字列を取得!

0はあとでスペースにかえるとして、いよいよ切り分けて改行!

6. 日にちの7日ごとの折り返し表示

色付き出力.

配列を文字列にしてから分割するのは、改行が思いの外難しい。 配列を分割してから文字列にしてみよう。

Enamerable#Each.sliceなら分割できる?

data_2 = (0..100000).to_a
puts data_2[69762]

を範囲指定[1..7]、[8..14],,, 文字列の一番左の文字を削除.

str = "あいうえお"
str[1..-1] # => "いうえお" 

できたっぽい! 途中で見つけた .center()で年月をセンター寄せ。

8. shellでのruby入力を省略する

  • 実行権限を与える

年月の入力がなかった場合、今日の日付を表示する

begin rescue endを使用 rescueした先のファイル

日付の取得は.mdayメソッド 付きの最終日はlastdate = Date.new(year, month, -1)

Rubocopインストール 

Gemfileに追加(ローカルフォルダに保存されている)。

gem "pry" <=以前インストールしたもの。
gem 'rubocop', require:false
gem 'rubocop-rails', require:false
gem 'rubocop-performance', require:false

### その前にbundlerをインストール まだインストールしてなかった。

それにしても掘れば掘るほど右もわからない。。。

結局rubocopインストールできず。。。

また明日。。。

1/16 学習記録 Ruby入門 4日目(最終回)〜FizzBuzz〜カレンダー

<目標>

  • RUBY入門終了する
  • 丁寧に作業する ペースを守る
  • モチベーションをキープする
  • 8ポモドーロ
  • 日報の時間を測る

<メモ>

第11章 クラス

正規表現

  • .match? 文字列検索して true/falseを返す
  • gub 置換する

    ブロック

引数はオブジェクトを渡しているが、ブロックは処理を渡してる。

  • yeildをに書いたメソッドはメソッドの中で実行できる。

  • ブロックを引数(&をつける)で渡して、.callで実行できる

  • Procオブジェクトブロックの処理をオブジェクト化したもの

FIZZBUZZ提出

### GITの復習

レポジトリをクローンするとフォルダごとクローンされる。

カレンダープログラム作成

$ ./cal.rb -y 2020 -m 11 
      11月 2020        
日 月 火 水 木 金 土  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
15 16 17 18 19 20 21  
22 23 24 25 26 27 28  
29 30

これを表示させる。全然わからない。

クリアすべきこと(おそらく)。

  1. shell コマンドでのオプション設定 (-y&-m)OK 3
  2. 1行目の?月 ?年の表示 OK 2
  3. 2行目の曜日表示 OK 4
  4. カレンダー表示コマンドを探す OK 1
  5. 日にちの横並び表示
  6. 日にちの7日ごとの折り返し表示
  7. 1日目を表示する曜日の設定

  8. shellでのruby入力を省略する

でしょうか。。。

順番

  1. カレンダー表示コマンドを探す OK 1
  2. 1行目の?月 ?年の表示 OK 2
  3. shell コマンドでのオプション設定 (-y&-m)OK 3
    • シェルコマンドから数値入力できた
  4. 2行目の曜日表示 OK 4

    • ダブルクオテーションが木になるけれどとりあえず表示しているから次へ
  5. 日にちの横並び表示 <=イマココ

  6. 日にちの7日ごとの折り返し表示 <=イマココ

1 shell コマンドでのオプション設定 (-y&-m)

.

引数付きショートネームオプションの処理.

  • オプションに:をつける
#!/usr/bin/env ruby
require 'optparse'

options = ARGV.getopts('a:')
puts options
% ./arg.rb -a 111
{"a"=>"111"}
#!/usr/bin/env ruby

これ何?、、、shebangでした!直接ファイルに書いてよし! なるほどー。ほんとかなー。

#!/usr/bin/env ruby
require 'optparse'
options = ARGV.getopts('y:','m:')
puts options
puts options["y"]
puts options["m"]
{"y"=>"2020", "m"=>"11"}
2020
11

よっしゃー。ARGV.getopts('y:','m:')はハッシュを出力してたんですねー。これでシェルとRubyが繋がった!でもってハッシュから取り出した数字はSTRINGだったので、それをINTEGERに変更。


2. 1行目の?月?年の表示.

time = Time.now
 
p time
p time.strftime("%Y年%-m月%-d日 %-H時%-M分%-S秒")

実行結果

2018-01-02 03:04:05 +0900
"2018年1月2日 3時4分5秒"
time = Time.now
p time.strftime("%-m月%Y")

この時間入力を

date = Date.new(2020,11.1)
p date.strftime("%-m月%Y")

に変更して

"11月2020" 

が得られる。 これにシェルから入力できるようにする。 pではなくputsメソッドでダブルクオーテーションが取れた :) (p (数値)は""なしで出力される)


4 カレンダー表示コマンドを探す

require 'date'

a = Date.new(1993, 2, 24)
b = Date.parse('1993-02-24')
b += 10

b - a            #=> 10
b.year           #=> 1993
b.strftime('%a') #=> "Sat"

yesterday = Date.today - 1

曜日が出てきた! これを入力したらその月の初めの日が何曜日が特定できる

.strftimeメソッド

表示を選べる

入力した日付と曜日を表示

require 'date'
a = Date.new(2020, 11, 1)
p a.strftime('%a') #=> "Sat"

曜日の日本語表示.

require 'date'
 
date = Date.today
 
weeks = ["月","火","水","木","金","土","日"]
 
index = date.strftime("%u").to_i
 
p date.strftime("%Y年%-m月%-d日 %u")
p date.strftime("%Y年%-m月%-d日 #{weeks[index - 1]}曜日")

5. 日にちの横並び表示

6. 日にちの7日ごとの折り返し表示

きっとこれらは一緒にできる。 多分、日曜日から第一日までは空白で、その月の月末までの文字列をつくって、それを7文字ごとに改行する。 。。。感じかな。

明日やろう。楽しみです。