先日解いた問題2[Ruby]

2問めは、「2から1000までの正の素数の出力」という出題

思ったやつを再度書いてみたが結果が特に出力されない
エラーはでないのだが、出力されない原因はわからない

i = 2
arr = []
while i >= 1000
  (2..1000).each do |p|
    if i % p == 0
      arr.push(p)
    end
  end
  if arr.length == 1
    puts i
  end
 i = i + 1
end

上記のような記述をした

  • iは判定する数値
  • pはiを割る数値
  • 2から1000なのでiが1000になるまで繰り返し
  • 2から1000のpでiを割り、割り切れた場合は配列に格納する
  • 配列の要素数が1つだった場合が素数であるとし、出力する

全くスマートじゃない
苦し紛れに書いた

どうやらwhileはtrueのときに繰り返し実行される模様
そのため思ったような出力がされないようである

for文で書き直してみる

for i in 2..1000 do
  arr = []
  (2..1000).each do |p|
    if i % p == 0
      arr.push(p)
    end
  end
  if arr.length == 1
    puts i
  end
end

for文だとそれっぽいのが出力された
999回の処理を999回やる処理

非常に勉強不足であることがわかるコードである
勉強して書き直したい

先日解いた問題1[Ruby]

ソースコードはこんな感じだったと記憶している

def append str, other_str
  str = str + other_str
  puts "append : #{str}"
  str
end

def append! str, other_str
  str = str.concat(other_str)
  puts "append! : #{str}"
  str
end

str1 = "Test"
str2 = "Program"

append(str1,str2)
puts "1st : #{str1}"
append!(str1,str2)
puts "2nd : #{str1}"

=begin
実行結果
append : TestProgram
1st : Test
append! : TestProgram
2ed : TestProgram
=end

上記より、「出力された 1st と 2ndの内容が違うのはなぜか」という出題

ポイントはconcat

  • 文字列の追加
  • 文字列の連結ではない
  • <<演算子(メソッド)の別名
  • +とは違い、レシーバ自身の文字列を変更する
  • 戻り値はレシーバ自身

ref.xaio.jp

ref.xaio.jp

self << other -> self
concat(other) -> self
self に文字列 other を破壊的に連結します。 other が 0 から 255 のまでの整数である場合は その 1 バイトを末尾に追加します (つまり、整数が示す ASCII コードの文字が追加されます)。
self を返します。

instance method String#<< (Ruby 2.2.0)

破壊的に上書きすると解答したが、「破壊的に連結する」というのが正答のようです

Railsチュートリアル2

実例を使ってRailsを学ぼう

railstutorial.jp

今回は1.2.4 Bundlerから1.3.4 GitHub

第1章 ゼロからデプロイまで

railstutorial.jp

1.2.4 Bundler

Railsアプリケーションを新規作成したら、次はBundlerを実行して、アプリケーションに必要なgemをインストールおよびインクルードします

Gemfileを変更します

source 'https://rubygems.org'
↓
source 'https://rubygems.org'
ruby '2.1.2'

jQueryに関するもの

gem 'jquery-rails'
↓
gem 'jquery-rails', '3.0.4'

gem 'sqlite3'
↓
group :development do
  gem 'sqlite3', '1.3.8'
end

この変更を行うと、Bundlerはsqlite3 gemの1.3.8を強制的にインストールします。ここではさらに、SQLiteをdevelopment環境 (7.1.1) でのみ使用するための指定も行なっていることに注目してください。こうすることで、Heroku (1.4) で使用するデータベースソフトウェアと衝突する可能性を避けられます。

ほかのも変更します

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.2'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
↓
gem 'sass-rails', '4.0.5'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.1'

以下gemの記述の説明の引用となります

gem 'uglifier', '>= 1.3.0'

uglifierのバージョンが1.3.0以上であれば最新バージョンのgemがインストールされます。 極端に言えばバージョンが7.2であってもそれが最新ならインストールされます。なお、uglifierはAsset Pipelineでファイル圧縮を行うためのものです。

gem 'coffee-rails', '~> 4.0.0'

coffee-rails (これもAsset Pipelineで使用するgemです) のバージョンが4.0.0より大きく、4.1より小さい場合にインストールするようになります。つまり、>=と書くとbundle installの実行時に必ずアップグレードが行われますが、~> 4.0.0と書くとマイナーなアップグレードしか行われないことになります。この場合4.0.0から4.0.1へのアップグレードは行われますが、4.0から4.1へのアップグレードは行われません。経験上、残念ながらマイナーアップグレードですら問題を引き起こすことがあります。このため、Railsチュートリアルでは基本的にすべてのgemでバージョンをピンポイントで指定しています。

Gemfileを正しく設定しましたので、bundle update と bundle install を使用して gem のインストールをします

$ bundle update
$ bundle install

1.2.5 rails server

ローカルwebサーバを起動します

$ rails server

(JavaScriptランタイムがインストールされていないというエラーが表示された場合は、GitHubのexecjsページにあるインストール可能なランタイムを確認してください。Node.jsが特にお勧めです)。

とあり、ランタイムでエラーとなりました

Node.jsのインストール

$ sudo yum install nodejs

インストール後に再度ローカルwebサーバを動かすとエラーはでなくなりました

1.3 Gitによるバージョン管理

1.3.1 インストールとセットアップ

最初のリポジトリのセットアップとして、Railsアプリケーションのルートディレクトリに移動し、新しいリポジトリの初期化を行います
ここでのルートディレクトリはfirst_appとなります

$ git init

.gitignoreに除外設定を追加します

# Ignore other unneeded files.
doc/
*.swp
*~
.project
.DS_Store
.idea
.secret

1.3.2 追加とコミット

新しく作成したRailsプロジェクトのファイルをGitに追加し、コミットします

$ git add .

ここで「.」は現在のディレクトリ (カレントディレクトリ) を指します。Gitは再帰的にファイルを追加できるので、自動的にすべてのサブディレクトリも追加されます。このコマンドにより、プロジェクトのファイルは、コミット待ちの変更が格納されている「ステージングエリア」という一種の待機場所に追加されます。ステージングエリアにあるファイルのリストを表示するには、statusコマンドを実行します。

変更を保存するには、commitコマンドを使います

$ git commit -m "Initialize repository"

-mフラグは、コミットメッセージ (コミット内容の覚書) をその場で追加する場合に使用します。-mを省略した場合、1.3.1で設定されたエディタが起動され、コミットメッセージの入力を求められます。

1.3.3 Gitのメリット

ファイルがいくつか削除されましたが、この変更が行われたのは現在の「作業ツリー」内のみなので、まだコミット (保存) されていません。つまり、以前のコミットをcheckoutコマンド (と、現在までの変更を強制的に上書きして元に戻すための-fフラグ) でチェックアウトすれば、簡単に削除前の状態に戻すことができます。

$ git checkout -f

削除されたディレクトリとファイルが復旧することができます
コミットしていなければできるみたいです

1.3.4 GitHub

ポジトリをGitHubにわざわざプッシュするのには2つの理由があります。1つ目は、ソースコード (とそのすべての変更履歴) の完全なバックアップを作成することです。2つ目は、他の開発者との共同作業をより簡単に行うことです。

GitHubソースコードをアップロードする

GitHub上でリポジトリを作成します
すでにRails new コマンドを実行してREADMEファイルを自動的に作成しているため、READMEファイルを使用してリポジトリを初期化しないでください

リポジトリを作成したら、アプリケーションをプッシュします

$ git remote add origin https://github.com/<username>/first_app.git
$ git push -u origin master

・プッシュが失敗する

error: The requested URL returned error: 403 Forbidden while accessing https://github.com/catoidrobo/first_app.git/info/refs

fatal: HTTP request failed

最初にプッシュしたマシンとは別のマシンで操作をするとHTTPS認証でエラーになる模様

blog.katsuma.tv

succi.jp

一旦先ほど登録したURLを削除します

$ git remote rm origin

git remote add コマンドを再度実行します
今回は github.com ではなく、@github.com とします

$ git remote add origin https://<username>@github.com/<username>/first_app.git
$ git push -u origin master

プッシュ実行後にパスワードが聞かれるので、GitHubのパスワードを入力します

アクセスして確認するとプッシュされたことがわかりました

github.com

Railsチュートリアル1

下記のチュートリアルを進めていきます

railstutorial.jp

今回は1.1~1.2.2 Ruby, RubyGems, Rails, Git

第1章 ゼロからデプロイまで

railstutorial.jp

デプロイ:deploy 本番環境でアプリを動かし、一般公開すること

1.1.3 この本における取り決め

Railsで作成するWebアプリケーションが置かれているディレクトリのルート(root)を、Railsルートと呼ぶことにする
多くの人がRailsルートを「Railsというアプリケーションそのものがインストールされたディレクトリのルート」だと勘違いする
この点を明確にするため、Railsチュートリアルでは、「Railsルート」については(Railsで作成した)Webアプリケーションのルートディレクトリを指す

1.2.2 Ruby, RubyGems, Rails, Git

クラウドサービスを使ってRails開発したい方は、Rails Girlsのインストールレシピをご参照くだいさい

とあり、Rails Girlsすごい

Rails Girls - Japanese

Railsをインストールします

$ gem install rails --version 4.0.5

インストール後にrailsコマンドができませんでした
uninstallして再度インストールしてもだめです

調べたところ、rbenv rehashすると解決するようなのでやってみました

qiita.com

rbenv rehashは何をやっているのか? · DQNEO起業日記

$ rbenv rehash
$ rails -v
Rails 4.0.5

このチュートリアルではRubyをRVMでインストールしましたが、すでにrbenvでインストールしていました

rbenvでは、gemを追加したときは.rvm/shimsを更新する必要があるようです

次回は1.2.3 最初のアプリケーションから

新規Windowで開く[Javascript]

<!DOCTYPE html>
<html>
  <head>
    <script language="JavaScript">
    function opWin(prm) {
      var url = prm;
      var opWind = window.open(url,'opWind','width=960,height=850, resizable=yes, scrollbars=yes');
    }
    </script>
  </head>
  <body>
    <a href="#" onclick="opWin('test.php')">新規ウィンドウで開く</a>
    <a href="test.php" target="_blank">新規タブで開く</a>
  </body>
</html>

遷移先を新規Windowで開きたい場合は window.open() をつかいます
今回はonclickをつかって実行しました

新規タブで開きたい場合は target="_blank" を用いるとできます

文字列を削る[PHP]

値を生成したが余分な部分ができてしまい削りたいときがあります
今回は日付の時間の部分を削りたいと思います

$arr = array(
         array("id"=>1, "reg_date"=>"2015-04-24 00:00:00", "upd_date"=>"2015-06-17 16:15:15"),
         array("id"=>2, "reg_date"=>"2015-05-25 00:00:00", "upd_date"=>"2015-05-28 00:00:00"),
         array("id"=>3, "reg_date"=>"2015-04-26 00:00:00", "upd_date"=>"2015-06-22 16:15:42")
       );
print_r($arr);
/*
Array
(
    [0] => Array
        (
            [id] => 1
            [reg_date] => 2015-04-24 00:00:00
            [upd_date] => 2015-06-17 16:15:15
        )

    [1] => Array
        (
            [id] => 2
            [reg_date] => 2015-05-25 00:00:00
            [upd_date] => 2015-05-28 00:00:00
        )

    [2] => Array
        (
            [id] => 3
            [reg_date] => 2015-04-26 00:00:00
            [upd_date] => 2015-06-22 16:15:42
        )

)
*/

// 日付の時間部分を削る
$date_arr = array("reg_date","upd_date");

$i = 0;
while (count($arr) > $i) {
  foreach($date_arr as $v){
    if(isset($arr[$i][$v])){
      $arr[$i][$v] = substr($arr[$i][$v], 0, 10);
    }
  }
  ++$i;
}
print_r($arr);
/*
Array
(
    [0] => Array
        (
            [id] => 1
            [reg_date] => 2015-04-24
            [upd_date] => 2015-06-17
        )

    [1] => Array
        (
            [id] => 2
            [reg_date] => 2015-05-25
            [upd_date] => 2015-05-28
        )

    [2] => Array
        (
            [id] => 3
            [reg_date] => 2015-04-26
            [upd_date] => 2015-06-22
        )

    )
    */

このように表示につかいたくない部分を削ることができます

PHP: substr - Manual

リファレンスには文字列の一部分を返すとありますね
ほかには下記のようなサンプルがリファレンスにあります

<?php
$rest = substr("abcdef", -1);    // "f" を返す
$rest = substr("abcdef", -2);    // "ef" を返す
$rest = substr("abcdef", -3, 1); // "d" を返す

$rest = substr("abcdef", 0, -1);  // "abcde" を返す
$rest = substr("abcdef", 2, -1);  // "cde" を返す
$rest = substr("abcdef", 4, -4);  // false を返す
$rest = substr("abcdef", -3, -1); // "de" を返す
?>

配列の順番を変えずに値を変える[PHP]

配列の順番を変えずに、値を変えたい場合があります

下記のような配列があります

print_r($arr);
/*
Array
(
    [0] => red
    [1] => light_green
    [2] => deep_blue
    [3] => pink
    [4] => white
)
*/

これをこのような配列にしたいとします

print_r($arr);
/*
Array
(
    [0] => red
    [1] => green
    [2] => blue
    [3] => pink
    [4] => black
)
*/

これを解決するために2つの関数をつかいます

$arr = array("red", "light_green", "deep_blue", "pink", "white");

$replacements = array(
                    array_search("light_green", $arr) => "green",
                    array_search("deep_blue", $arr) => "blue",
                    array_search("white", $arr) => "black"
                );

$arr_replace = array_replace($arr, $replacements);

print_r($arr_replace);
/*
Array
(
    [0] => red
    [1] => green
    [2] => blue
    [3] => pink
    [4] => black
)
*/
  • array_search()
    hogeがvalueのとき、添字のkeyを取得できます

  • array_replace()
    valueを別の値に変えられます
    配列の順番(添字)を変えたくないときに重宝します

これらを組み合わせると添字配列のvalueを別の値にできます