2014年9月20日土曜日

PHPmemo_day3

PHPの基本に関するメモ。参考にしているのはPHPによるWebアプリケーションスーパーサンプル第2版の第3章(変数、定数)です。

  • echoで文字列と変数の間にスペースを入れずに出すには{$var}のように{}で囲えばよい
  • 変数の型を調べるにはgettype関数を利用する
  • 変数の型変換にはsettype関数を利用する
  • var_dump関数を利用すると、変数の方に関する情報と値をまとめて出力できる
  • get_defined_vars関数を利用すると定義済みの変数情報一覧を取得できる。
  • define関数で定数を定義できる。C言語の#defineみたいなものとみてよいだろう。
  • defined関数で定数が定義済みか調べられる。
  • define("EXP", 2.718)のように定義したEXPを参照するにはEXP、あるいはconstant("EXP")とする。
  • __FILE__はPHPコードの書かれたファイル名、__LINE__はコードの行番号を表す定数である。
  • M_PIは円周率、M_SQRT2はルート2を表す定数である。
  • get_defined_constants関数で定義済みの定数一覧を取得できる。
  • get_defined_constants関数のように一覧を取得して表示したいのであれば、print_r関数が使える。print_r関数はデバッグにも使える。
  • $_SERVER["HTTP_USER_AGENT"]はブラウザの情報を、$_SERVER["HTTP_REFERER"]はリンク元を、$_SERVER["REMOTE_ADDR"]はアクセス元のIPアドレスを表す(PHP4.2.0以降)

2014年9月18日木曜日

PHPmemo_day2

PHPの基本に関するメモ。参考にしているのはPHPによるWebアプリケーションスーパーサンプル第2版の第2章前半です。 コードを書いて紹介するのは大変なので、C言語やJavaと違うところを主に取り上げていきます。

  • フォームからPOST送信された値を受け取るときには$_POST["content"]とすればnameがcontentのデータを受け取れる。
  • php.iniのregister_globalsをONにすると$contentで参照できるようになるが、セキュリティの都合上OFFにするのが一般的
  • @$_POST["content"]とすることで、contentが初期状態で何も設定されていない状態でもエラーが出なくなる
  • $_SERVER["PHP_SELF"]は現在表示中のURLを表すサーバ変数である
  • $HTTP_POST_VARS["content"]のようにPOST送信されたデータを受け取ることもできるが、php.ini-recommendedでは無効になっている。
  • php.iniにはdisplay_errorsという設定項目がある。これはエラーを画面に出すためのオプションであり、デバッグに使える。
  • $_GET["type"]などとすればGET送信されたURLのtype=の値を取得することができる。
  • フォームから送信されるデータはstring型である。
  • フォームから変数を受け取って、同じ変数名に受け取った値を設定するには、extract関数を使う。ただし、extract($_POST)のように記述すると、ユーザの入力をそのまま出すのでエスケープ処理などをした方がよいとされる。
  • フォームからある変数が飛んできているか調べるにはisset関数を利用する。if文や三項演算子を用いて変数の有無で変数を設定する際に使える。
フォームからの入力内容を確認するためによく使われる関数についても紹介しておきます。
  • function_exists
    • 引数の文字列の関数名が定義されているかを調べるための関数
  • strlen
    • 文字列の長さを調べるための関数
  • empty
    • 空、または0でTRUEを返す関数
  • isset
    • 変数が定義されていればTRUEを返す関数
  • stristr、strstr
    • 文字列のマッチングで利用する関数。前者は大文字と小文字の違いをignore(無視)するが、後者では区別している。
  • is_numeric
    • 文字列が数字として解釈できるのであればTRUEを返す関数。数字は半角でないとTRUEにならない。
  • ctype_digit
    • is_numericに似ているが、小数点が含まれるとFALSEになる点が異なる。あとは同じ。
  • ctype_loert、ctype_upper
    • 引数の文字列が小文字、あるいは大文字だけからなるかを調べる関数
  • checkdate
    • 引数で与えた月、日、年の数値がグレゴリオ暦で正しい日付か(存在する日付であるか)調べる関数

2014年9月17日水曜日

PHPmemo_day1

PHPの基本に関するメモ。参考にしているのはPHPによるWebアプリケーションスーパーサンプル第2版の第1章です。 コードを書いて紹介するのは大変なので、C言語やJavaと違うところを主に取り上げていきます。

  • PHPのコードは<?~?>で囲う
  • 変数は$i=(値)のように定義する
  • echo、printで文字列出力を行う。HTMLをechoで出力する方法もある。
  • echoをダブルクォートで囲うと変数は変数の値に解釈され、シングルクォートで囲うと変数名は文字列と解釈される
  • $s = "abc";
    echo "string=$s"; // string=abcと表示される
    echo 'string=$s'; // string=$sと表示される
  • 文字列の結合はドット(.)で行う
  • 空文字、null、0も論理値のFALSEとして扱われる。それ以外はTRUEになる。
  • 関数にはデフォルト値を設定することができる。
  • func(1)とcall_user_func(func, 1)は同値になる

2014年8月17日日曜日

TopCoder SRM487 Div2 250Pts

このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文についておおまかに説明する。

ウサギたちはプログラミングは好きだが、プログラミングの試験が好きではない。黒、グレー、白の3匹のウサギは最終試験を終えた。ウサギたちが問題について議論している間に、教授がやってきて、"黒いやつ、お前は0点だ、知識を確かなものにするために、グレーと白が取った点数の最大値の合計点を計算するプログラムを書け"といった。

試験はN問からなるものであった。ウサギたちは同じ問題を提示される。各問題に対し、その答えとしてA~Zのアルファベットの大文字を書かなければならなかった。問題に対し、1つの文字のみが正しいものとされ、他の25文字は正しくない回答となっている。正解は1点となり、ウサギの得た点数は問題に正解した数に一致する。

black、gray、whiteという黒、グレー、白のウサギが書いた回答を表す文字列が与えられる。それぞれの文字列はN文字からなり、文字列のi番目の文字はそれぞれのウサギのi番目の回答を表すものとする。黒ウサギの点数が0のときに、グレーと白のウサギが獲得しうる点数の合計の最大値を返せ。

私の回答は以下の通り。

public class BunnyExamAfter {

 public int getMaximum(String black, String gray, String white) {

  int points = 0;
  for( int i=0 ; i<black.length() ; i++ ){
   if( black.charAt(i) == gray.charAt(i) &&
    black.charAt(i) == white.charAt(i) ){
    // pass
   }else if( black.charAt(i) != gray.charAt(i) &&
     black.charAt(i) == white.charAt(i) ){
    points++;
   }else if( black.charAt(i) == gray.charAt(i) &&
     black.charAt(i) != white.charAt(i) ){
    points++;
   }else if( black.charAt(i) != gray.charAt(i) &&
     black.charAt(i) != white.charAt(i) &&
     gray.charAt(i) == white.charAt(i) ){
    points += 2;
   }else if( black.charAt(i) != gray.charAt(i) &&
     gray.charAt(i) != white.charAt(i) ){
    points++;
   }
  }
  return points;
 }

}

得点は220.72/250、1回のsubmitでシステムテストクリア。

2014年8月6日水曜日

TopCoder SRM486 Div2 250Pts

このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文についておおまかに説明する。

奇妙な省略形が扱いにくい携帯機器でテキストを書くのにしばしば用いられる。アルファベットと空白からなるテキストをエンコードする方法の1つに次のものがある。

  • 空白はそのままで、各単語は単語ごとにエンコードされる。ここで単語とはアルファベットの続く連続した文字列をいう。
  • もし単語が母音のみからなる場合、それはそのまま書かれる。
  • もし単語が1つ以上の子音を含むのであれば、直前に別の子音がない子音のみ書く。母音を買い手はならない。
  • 上記の規則において、母音は'a', 'e', 'i', 'o'と'u'である。他の文字は子音と考える。

例えば、"ps i love u"というのは、"p i lv u"と省略され、一方、"please please me"は"ps ps m"と略されるであろう。 originalという文字列が引数で与えられたとき、先述の方法で省略されたメッセージを返すメソッドを作成せよ。

私の解答は以下の通り。

public class TxMsg {

 public String getMessage(String original) {
  StringBuilder msg = new StringBuilder("");
  String[] strs = original.split(" ");
  for( int i=0 ; i<strs.length ; i++){
   if( isAllVowel(strs[i]) ){
    msg.append(strs[i] + " ");
   }else{
    msg.append(makeEncodedMessage(strs[i]) + " ");
   }
  }
  // if文の後者により、最後に空白ができる可能性があるので、trimを行う
  return msg.toString().trim();
 }

 private static boolean isAllVowel(String s){ // 入力がすべて母音か判断
  char[] vowels = {'a', 'e', 'i', 'o', 'u'};
  for( int i=0 ; i<s.length() ; i++ ){
   boolean isvowel = false;
   for( int j=0 ; j<vowels.length ; j++ ){
    if( s.charAt(i) == vowels[j] ){
     isvowel = true;
     break;
    }
   }
   if( ! isvowel ) return false;
  }
  return true;
 }

 private static String makeEncodedMessage(String s){
  char[] vowels = {'a', 'e', 'i', 'o', 'u'};
  StringBuilder sb = new StringBuilder();
  boolean prevConsonant = false;
  boolean currentConsonant = true;

  for( int i=0 ; i<s.length() ; i++ ){
   currentConsonant = true;
   for( int j=0 ; j<vowels.length ; j++ ){
    if( s.charAt(i) == vowels[j] ){
     currentConsonant = false;
     break;
    }
   }
   if( !prevConsonant && currentConsonant ){
    sb.append(s.charAt(i));
   }
   prevConsonant = currentConsonant;
  }
  return sb.toString();
 }

}

得点は158.01/250、1回のsubmitでシステムテストクリア。

2014年7月30日水曜日

Raspberry PIでSSHの初期設定時に発生したエラーを回復する方法

Raspberry PIの初期設定中に、「Initial ssh key generation still running. Please wait and try again.」 というメッセージが出てきて困ったことがありました。何が原因で発生したのかよく分からないのですが、 最初の起動時に接触が悪かったのため、一度設定前に電源を落とすなどしたことが可能性として考えられました。 さて、この状態になった場合、次の鍵を作り直すためのコマンドを入力することによってSSHが使えるようになります。

作業時には初期状態(User:pi、Password:Raspberry)のアカウントを利用しました。なのでsudoでコマンドが実行ができます。

# rm /var/log/regen_ssh_keys.log
# sudo rm /etc/ssh/ssh_host*
# sudo ssh-keygen -A

個人的にはログを消すとうまく動作するというのはあまり納得できません。 logではなくlockという拡張子のファイルを削除するのであれば理解できるのですが。

2014年7月19日土曜日

Firefoxで戻るボタンを押した際に二重送信防止を解除する

今回はFirefox(テストで利用したバージョンは30.0)における厄介な挙動をJavaScriptで解決しようというお話。 IE 11や最新のChrome(35系)では特に気にする必要はないものです。

フォームで二重押下を防止するために、1度ボタンを押すとボタンの状態をdisabledにするということがあります。 そこまでは何も問題ないのですが、Firefoxではボタンを押してsubmitをした後に、戻るボタンを押すとdisabledの状態が継続しており、 再度submitができない状態になってしまいます。もう一度戻るボタンを押すとsubmitできるようになるのですが、 その挙動は一般的にユーザが想定していないものであるはず。

そこで、jQuery(利用したバージョンは1.11.0)を利用して、 一度戻るボタンを押すだけでdisabledの状態が解除できるようにしてみました。コードは以下のようになります。

<script type="text/javascript"><!--
$(document).ready(function() {
    $(window).unload(function(){});
    $('#button').attr('disabled', false);
});
--></script>

1行目はDOMを構築した後に実行せよという意味です(おまじないと思って差し支えないでしょう)。 2行目はBackForwardCacheを無効にせよという意味になります。元のページに遷移した際にキャッシュを使うなという意味になります。 つまり、ボタンを押したという状態を使うなということになります。 3行目はボタンにdisabled属性をfalseにせよという意味で、ボタンを利用可能にするという意味になります。 初期状態はfalseでなければならないので、明示的に設定しました。

これにより、ボタンを1度叩いてdisabledになった状態でブラウザの戻るボタンを押しても、disabledの状態にならなくなります。 ただし、フォームにあった情報(入力したテキスト等)はすべて落ちてしまうので、再入力が必要になります。 もっとも、それは仕様としてしまっても良いとは思いますが。

フォロワー

ページビューの合計