忍者ブログ
  ちゃんとカテゴリ分けされておりませんので、 記事をお探しならブログ内検索が便利です。 ご活用くださいませー+.(≧∀≦)゚+.゚
Admin*Write*Comment
[1]  [2]  [3]  [4]  [5]  [6]  [7

これもすぐ忘れてしまうのよねー
ってことでメモします。


sum(1 for line in open('filename'))

試験環境
Windows7 or Linux
Python 2.7.8
Python2.6.6

参考URL
http://d.hatena.ne.jp/cafistar/20120405/1333600582
http://stackoverflow.com/questions/845058/how-to-get-line-count-cheaply-in-python

拍手

PR




久しぶりにPHPでコーディングして、不満があったので、憂さ晴らしです(ぇ

【5C問題】
よく知られたSJISの問題ですね。
これは仕方ないカナ?
Unicodeの実装をあきらめ、PHP6をすっ飛ばしてPHP7をリリースしようとしている心意気だけ評価してあげます。
がんばればaddslashes()やlocale系でたいていゴリ押しできますし。

【fgetcsv()の第二引数にstringを渡すと無視される】
これはひどいです。。。
第二引数は最大行長を指定するのですが、長さなので当然int型が正しいです。
ドキュメントにもそうありますし。。。
ですが、実際はどうでしょう?
それなりに動いているではありませんか!!!
行長を調整してみると、どうもデフォルトで動いているような気がします。。。

<?php
$fp = fopen(__file__, "rb");
while(($line=fgetcsv($fp, ','))!==false){
    var_dump($line);
}

気が振れているとしか思えません。。。
おそらくstringがintにcastされてその結果が0だったので、そういう挙動になったんだと思います。
文字長があるのだからせめて1になるのが正しい気がしますが。。。
(それなら早く気付けるし。。。)

<?php
var_dump((int)',');

腕がわるいと言われれば反撃できないのですが、これはPHPを使っているだけでバグを作っているような気がします。。。
コーダーが関数の仕様を勘違いしていたら一生気づかないし、こういうバグってコーダーが退職後に出やすいんです。
そして、今まで動いていたのが動かないってことはみんなまず最初にINPUTデータを怪しみます。
そしてトコトン現場に混乱をもたらして初めてPHPが仕掛けたトラップに気づくのです。
恐ろしい子なんです、PHPって子は…

【feof() が無限ループになることがある】
オブジェクト指向なクラスが増えたとはいえ、まだまだ手続型言語のPHP。
なのに・・・
無限ループの可能性があるなんて…
言わんとすることはわかります。
たしかに関数としての動きもそうですけど、でも無限ループは怖いので、そこはFatalで落ちてほしかったです。
今後はSplFilreObject()に期待したいですね。。。

と、いうことで皆さんは気を付けてくださいね^^

検索タグ
php5.6

拍手




データベース上で日付の計算を行いたいことはよくあります。
集計、はビッグデータ時代には必須ともいえるかもしれません。
MySQLは多くの日付計算のための仕組みを用意してくれています。
遠慮なく使わせていただきましょう^^

ですが、注意点もあります。
それはMySQLはCAST(型変換)がとても強く働くことです。
これは便利なようですが、よく理解しないまま使用すると想定しない値を返却する場合があります。
加えて、関数にたくさんのシノニム(別名:alias)が存在するので、結構現場に混乱をもたらします。
とはいえ便利ですし、レコードの解析の際はお世話になることが多いですので、覚えておいて損はありません。
大事なのは、日付の場合はこの関数。
時間の場合はこの関数。
など決めを作り、運用するのがいいかもしれませんね。
もっとも私は関数あまり使いませんけど~ (えっ

-- 今日
SELECT NOW(), CURDATE(), CURTIME();
-- 日付計算
SELECT
    NOW()
    , NOW() + INTERVAL 1 DAY
    , NOW() + INTERVAL 1 MICROSECOND
    , NOW() + INTERVAL 1 SECOND
    , NOW() + INTERVAL 1 MINUTE
    , NOW() + INTERVAL 1 HOUR
    , NOW() + INTERVAL 1 DAY
    , NOW() + INTERVAL 1 WEEK
    , NOW() + INTERVAL 1 MONTH
    , NOW() + INTERVAL 1 QUARTER
    , NOW() + INTERVAL 1 YEAR
    , NOW() + INTERVAL 1.111111 SECOND_MICROSECOND
    , NOW() + INTERVAL '01:01.111111' MINUTE_MICROSECOND
    , NOW() + INTERVAL '01:01' MINUTE_SECOND
    , NOW() + INTERVAL '01:01:01.111111' HOUR_MICROSECOND
    , NOW() + INTERVAL '01:01:01' HOUR_SECOND
    , NOW() + INTERVAL '01:01' HOUR_MINUTE
    , NOW() + INTERVAL '1 01:01:01.111111' DAY_MICROSECOND
    , NOW() + INTERVAL '1 01:01:01' DAY_SECOND
    , NOW() + INTERVAL '1 01:01' DAY_MINUTE
    , NOW() + INTERVAL '1 01' DAY_HOUR
    , NOW() + INTERVAL '1 1' YEAR_MONTH
\G

中にはMICROSECOND型で返ってくるものもあります。
当然これはこれで正ですが、見慣れた形式にしたい場合はCASTが覚えやすいと思います。

SELECT
    CAST(NOW() AS DATETIME)
    , CAST(NOW() AS DATE)
    , CAST(NOW() AS TIME)
\G

さらに細かく日付の形式を指定するならフォーマットを使います。

SELECT
    NOW()
    , DATE_FORMAT(NOW(), '%a') AS 'Abbreviated weekday name (Sun..Sat)'
    , DATE_FORMAT(NOW(), '%b') AS 'Abbreviated month name (Jan..Dec)'
    , DATE_FORMAT(NOW(), '%c') AS 'Month, numeric (0..12)'
    , DATE_FORMAT(NOW(), '%D') AS 'Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)'
    , DATE_FORMAT(NOW(), '%d') AS 'Day of the month, numeric (00..31)'
    , DATE_FORMAT(NOW(), '%e') AS 'Day of the month, numeric (0..31)'
    , DATE_FORMAT(NOW(), '%f') AS 'Microseconds (000000..999999)'
    , DATE_FORMAT(NOW(), '%H') AS 'Hour (00..23)'
    , DATE_FORMAT(NOW(), '%h') AS 'Hour (01..12)'
    , DATE_FORMAT(NOW(), '%I') AS 'Hour (01..12)'
    , DATE_FORMAT(NOW(), '%i') AS 'Minutes, numeric (00..59)'
    , DATE_FORMAT(NOW(), '%j') AS 'Day of year (001..366)'
    , DATE_FORMAT(NOW(), '%k') AS 'Hour (0..23)'
    , DATE_FORMAT(NOW(), '%l') AS 'Hour (1..12)'
    , DATE_FORMAT(NOW(), '%M') AS 'Month name (January..December)'
    , DATE_FORMAT(NOW(), '%m') AS 'Month, numeric (00..12)'
    , DATE_FORMAT(NOW(), '%p') AS 'AM or PM'
    , DATE_FORMAT(NOW(), '%r') AS 'Time, 12-hour (hh:mm:ss followed by AM or PM)'
    , DATE_FORMAT(NOW(), '%S') AS 'Seconds (00..59)'
    , DATE_FORMAT(NOW(), '%s') AS 'Seconds (00..59)'
    , DATE_FORMAT(NOW(), '%T') AS 'Time, 24-hour (hh:mm:ss)'
    , DATE_FORMAT(NOW(), '%U') AS 'Week (00..53), where Sunday is the first day of the week; WEEK() mode 0'
    , DATE_FORMAT(NOW(), '%u') AS 'Week (00..53), where Monday is the first day of the week; WEEK() mode 1'
    , DATE_FORMAT(NOW(), '%V') AS 'Week (01..53), where Sunday is the first day of the week; WEEK() mode 2; used with %X'
    , DATE_FORMAT(NOW(), '%v') AS 'Week (01..53), where Monday is the first day of the week; WEEK() mode 3; used with %x'
    , DATE_FORMAT(NOW(), '%W') AS 'Weekday name (Sunday..Saturday)'
    , DATE_FORMAT(NOW(), '%w') AS 'Day of the week (0=Sunday..6=Saturday)'
    , DATE_FORMAT(NOW(), '%X') AS 'Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V'
    , DATE_FORMAT(NOW(), '%x') AS 'Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v'
    , DATE_FORMAT(NOW(), '%Y') AS 'Year, numeric, four digits'
    , DATE_FORMAT(NOW(), '%y') AS 'Year, numeric (two digits)'
    , DATE_FORMAT(NOW(), '%%') AS 'A literal “%” character'
    , DATE_FORMAT(NOW(), '%x') AS 'x, for any “x” not listed above'
\G


時刻形式からの展開

SELECT
    NOW()
    , EXTRACT(DAY FROM NOW())
    , EXTRACT(MICROSECOND FROM NOW())
    , EXTRACT(SECOND FROM NOW())
    , EXTRACT(MINUTE FROM NOW())
    , EXTRACT(HOUR FROM NOW())
    , EXTRACT(DAY FROM NOW())
    , EXTRACT(WEEK FROM NOW())
    , EXTRACT(MONTH FROM NOW())
    , EXTRACT(QUARTER FROM NOW())
    , EXTRACT(YEAR FROM NOW())
    , EXTRACT(SECOND_MICROSECOND FROM NOW())
    , EXTRACT(MINUTE_MICROSECOND FROM NOW())
    , EXTRACT(MINUTE_SECOND FROM NOW())
    , EXTRACT(HOUR_MICROSECOND FROM NOW())
    , EXTRACT(HOUR_SECOND FROM NOW())
    , EXTRACT(HOUR_MINUTE FROM NOW())
    , EXTRACT(DAY_MICROSECOND FROM NOW())
    , EXTRACT(DAY_SECOND FROM NOW())
    , EXTRACT(DAY_MINUTE FROM NOW())
    , EXTRACT(DAY_HOUR FROM NOW())
    , EXTRACT(YEAR_MONTH FROM NOW())
\G


UNIX TIMESTAMP

SELECT
    NOW()
    , UNIX_TIMESTAMP()
    , FROM_UNIXTIME(UNIX_TIMESTAMP())
    , FROM_UNIXTIME(UNIX_TIMESTAMP()) + 0
    , FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x')
\G

月末計算
日付を含む型であること。
有効は日付形式であること

SELECT
    NOW()
    , LAST_DAY(NOW())
    , LAST_DAY(CURDATE())
    ;


時刻、日付作成
MAKETIME()は0パディングされたフォーマットは受け付けない。

SELECT
    NOW()
    , MAKEDATE(EXTRACT(YEAR FROM NOW()), 1)
    , MAKEDATE(EXTRACT(YEAR FROM NOW()), 141)
    , MAKETIME(EXTRACT(HOUR FROM NOW())+0, EXTRACT(MINUTE FROM NOW())+0, EXTRACT(SECOND FROM NOW())+0)
    , MAKETIME(EXTRACT(HOUR FROM NOW())+1, EXTRACT(MINUTE FROM NOW())+1, EXTRACT(SECOND FROM NOW())+1)
\G


いわゆるstrptime()

-- Apacheのログから拾ってみたけど、MySQLはTimezoneのフォーマットがないのね(^_^;)
SELECT STR_TO_DATE('[16/Jan/2015:10:39:13 +0900]','[%d/%b/%Y:%T +0900]');


weekday
(0 = Monday, 1 = Tuesday, … 6 = Sunday).


SELECT
    NOW()
    , WEEKDAY(NOW() + INTERVAL 0 DAY)
    , WEEKDAY(NOW() + INTERVAL 1 DAY)
    , WEEKDAY(NOW() + INTERVAL 2 DAY)
    , WEEKDAY(NOW() + INTERVAL 3 DAY)
    , WEEKDAY(NOW() + INTERVAL 4 DAY)
    , WEEKDAY(NOW() + INTERVAL 5 DAY)
    , WEEKDAY(NOW() + INTERVAL 6 DAY)
\G


その他時刻差分とか出せるみたいだけど、こちらはUNIX TIMESTAMPを中継して
整数で計算した方が良いと思うの。
わかりやすいしね。
マイクロ秒まで考慮する必要があるならいいけど、MySQLのカラム型にマイクロ秒まで
考慮できるデータがあったっけ?
という感じです (^-^;)

でわでわ

拍手




少し記事が古いですが、こんなのを見かけました。
可変変数と可変関数の使いどころがわからない'
可変関数っていうんだ~へぇ(^^;)

私はよく使いますよ^^
こんな感じで(笑)

analyze.php
<php?
$html = file_get_contents('http://php.net/');

$module_dir = implode(DIRECTORY_SEPARATOR, array(dirname(__FILE__), 'modules'));
if(!is_dir($module_dir)) Exception('No such directory.');
$dh = opendir($module_dir);
$php_files = array();
while(($file=readdir($dh))!==false){
        $l = strlen($file);
        if(substr($file, $l-4, 4) !== '.php') continue;
        $php_modules[] = substr($file, 0, $l-4);
}

libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHtml($html);
$dom = new DOMXpath($doc);
libxml_use_internal_errors(false);

$ret = array();
foreach($php_modules as $module){
        require_once(implode(DIRECTORY_SEPARATOR, array($module_dir, $module.".php")));
        $ret[$module] = $module($dom);
}
var_dump($ret);

module/leatest_version.php
<php?
$xpath = '//*[@id="intro"]//a[1]/text()';

function latest_version($dom){
        global $xpath;
        $ret = array();
        foreach($dom->query($xpath) as $elem){
                $ret[] = $elem->nodeValue;
        }
        return $ret;
}

外部ファイルを読み込んでそれに対して解析をかけています。
解析をかける関数名はファイル名と一緒にしておき、
ディレクトリの中に格納しておきます。
解析対象が何百とあり、かつ複数人で作業するときには
バッティングも起きにくいですし、対象が増えても
requre元のファイルに変更がないのがうれしいのです。
減らすのも簡単ですしね(^_^;)

と、いう感じで私は結構用途があったとさ。

余談ですが、これPythonでやるとimport_module()を
こねくり回さないといけないのでPHPってその辺に
便利さを痛感します。。。

拍手




便利そうで、そうでもなさそうな外部データラッパー。
何とか便利なシーンを探しています。
とりあえず備忘録です。

Foreign data wrappers
F.14. file_fdw
PostgreSQL: playing with foreign data wrappers (1)

拍手




redmineサーバのディスク容量がひっ迫してきたので、過去にアップロードして不要になったファイルを削除しよう!
みたいな話が出てきました。
それで何千とあるチケットの中からどうにかして、添付をしているチケット、並びにそのサイズを割り出せないか?
ということでいろいろ調べてみました。

まず、バックアップ方法を調べる。
http://redmine.jp/faq/system_management/backup/
これによりますと、
Redmineインストールディレクトリ以下のfilesディレクトリチケットやWikiに添付されたファイルが格納されています。

と、あります。
ではこれでファイルサイズがわかるわね。
でもファイルはなんだか暗号のよう。
ファイルとチケットの結びつけは、普通に考えればDBに格納されているはず!
でもまずは確定させるところから…
他に読み進めていくと。。。
添付ファイル以外の全ての情報がデータベースに格納されています。

と、あります。
ということは、やはりチケットとファイルの結びつけはDBを見ればわかるはず!!!
そこでshow tablesしてみると、、、
思ったよりテーブル数は少ない。。。
みたまんま、Issuesがチケットテーブルなのはわかるけど、、、
ここからはERもなしにたどり着くのは正直つらい…
と涙が出そうになったところで、attachmentsテーブルを発見!
見てみるとアップロードしたファイルに関する情報が!
でもそのファイルがどこに添付されたものなのかはカラム名からは推測が難しい…

かくなる手段は!
実際に添付されているチケットのページにアクセスしたときに発行されるSQLをみる!!!
と、いうことでクエリログを取ってみる。。。

attachments テーブルを使用しているログを見てみたところ、、
HITしましたぁ(*^ ^*)
container_id と container_type で引き抜いているみたいです。

  container_id: チケットのID
container_type: Issue(固定)

ちなみに attachments テーブルには filesize カラムがあるのでディスクを直接見なくても大きなサイズのファイルがすぐにわかりました。
これをもとにチケットを確認し、不要な添付ファイルの削除がなんとかできましたとさ。

そもそもメールで添付できない大きいファイルだからってなんでもかんでもRedmineを中継するような体質は何とかした方が…
とは言えないのでした…

Redmine version  2.6.0.stable

拍手




PostgreSQLのダンプとリストアって便利なやり方があったのねぇ…
と、いうことでメモでーす

ダンプ


スキーマは無理に指定する必要なし
--format で出力形式を選べます(私はdirectoryをよく使います!!)
--jobs で並列ダンプができます(便利!!)
-n でスキーマ選択できます
pg_dump -hlocalhost -p5432 -Upostgres postgres \
--blobs \
--jobs=2 \
--format=directory \
--file=`date +%Y%m%d%H%M%S`_postgresql.dump

-t オプションでテーブルを絞れます
-t include_table1 -t include_table2


-T オプションでテーブルを除外できます
-T exclude_table1 -T exclude_table2

リストア


基本的にダンプコマンドと同じオプションが使えます(わかりやすい!!)

pg_restore -hlocalhost -p5432 -Upostgres postgres \
--dbname=dbname \
--jobs=2 \
--format=directory \
[リストア用アーカイブディレクトリ]

-C でデータベースを作成できます
-c で既存のテーブルを削除できます(-C 併用でDBも!!)
-a でデータのみリストアできます
-s でテーブル定義(データなし)のみリストアできます

他にもいっぱいあるけど、まぁ、こんなものかな??

テスト環境
Centos 6.x
PostgreSQL 9.3

関連記事
【PostgreSQL】 pg_dump

拍手




これまたすぐに忘れてしまう、ポスグレでのカラム追加です。

ALTER
TABLE [table] ADD COLUMN [column_name] [data_type];

ex.)
ALTER TABLE table_a ADD COLUMN new_field varchar(255);

データ型を変えたい場合はこちら

検証)
PostgreSQL 9.3.5

拍手





「ウンコ 言語」と検索すると多くはPHPが上位独占状態…
はたしてPHPはウンコな言語なのでしょうか?

どこをウンコと感じるのでしょうか。
記事を読んでみると。。。
なんだか、クレーマーに近い感じ…

例えば、参照について。
http://ameblo.jp/nikko-inma/entry-11122429825.html
えーと、全くその仕様だったとして、困るような場面が思いつきません。。。
そんなにみなさんこんな使い方をするのでしょうか?

他にも関数が長すぎるとか。。。
子供なの?(苦笑)
オブジェクト指向ではないんですから、機能を関数だけで増やそうとした長くなってしまうのは仕方がないのでは?
無理に短縮して意味不明な記号になっても困りますし。。。

三項演算子についても苦言が多いですね。
なぜ、PHPという1言語として成り立っているのにほかの言語とわざわざ仕様を合わせないといけないのでしょうか?
「普通こういう結果が返ると思うだろ」とか言っている人はきっと上流工程とかできない人だと思う。

あと
・(new ClassName())->method()
・配列の作成がarray()
・finnaly
は最近のPHPでは実装されつつあるので、問題ないでしょう。
そもそもfinnalyってそんなに重要かしら?
Exceptionのない(いいすぎ?)言語なのに(笑)
最近はPDOとかオブジェクト指向なものも出てきているけどね。


って、ところを踏まえて私がウンコだなぁ、って感じた点
※ 結局私もそれなりに汚臭の言語だと思ってます(笑)

・php.iniがある
これのせいで、私の環境では動くけど、他では動かない、みたいなのを生む。
よく、「言語は動くようにかけ」っていうけど、、、
正直つらい(笑)
ini_set()で逃げられるものも多いけど、ini_set()に渡せるものを把握しておかなきゃならない。
でもそれをしていたら比較的敷居の低い言語ってイメージが崩れちゃう。
簡単にコーディングできる代物なのか、そうじゃないのか。
そういうあいまいさ加減が気持ち悪い=ウンコなんでしょうね。

・エラーハンドリングがしにくい
何でもかんでもfalseが返る点。
全部戻りを取って確認しなきゃいけない。
if()の嵐。
コードも増えるし、可読性もさがっちゃう。
しかもものによってはthrowだというのだから切ない。
し・か・も、なぜ失敗したのかがわからない。
falseの一言でですべて空気読んでって感じ。
そんなことされたらリアルで「ふぇ~」って言っちゃいますよ(笑)

・そして最大のウンコ
後輩が書いたスクリプトの抜粋です。
$id = $_GET["id"];
var_dump($id["id"]);
WEBアプリケーションのGETパラメータでidがわたってくるのだけど、一桁の時は正常に動作し、
10以降になると1固定になるという報告を受けました。
※後輩は一桁でしかテストをせずリリースしてから障害報告で発覚しましたTT

10分くらい考えてたどり着いた答えがこれ
GETパラメータはすべてstringでわたるので$idにはstring(numeric)が入る。
$id["id"]のキー"id"はタイポなので本来ここでwarningが出てほしいけど、PHPは出ない(int型なら出る)。
結果はすべて1になる。。。
と、いうことは2ケタの数字の左側しかとられていないかも?
現にGETパラメータに20とか渡すと仮説通りに。
と、いうことは文字列のスライスが発生している(PHPにスライスがあるとは知りませんでした…)。
左の値がとられるということはINDEXは0が指定されている。
文字列"id"は0なるののでしょうか?
var_dump((int)"id"); //0
0になった (;゚Д゚)エエー.

と、いうことでPHPは初心者に優しいようで、厳しいです。
エラーが出にくい(見えにくい)アプリケーション作成を少しでも早く開発するならうってつけだと思いますが。
ですが、その分バグは多めかもしれません(~_~;)

と、さいきんかんじましたとさ♪

拍手




postgresqlにはdescがないので、informationスキーマにあるテーブルを逐一確認しなければなりません。
仕方ないことなんだけど…

-- テーブル一覧
SELECT
  table_catalog
  , table_schema
  , table_name
  , table_type 
FROM
  information_schema.tables 
WHERE
  table_schema = '[schema_name]'; 

-- カラム一覧
SELECT
  * 
FROM
  information_schema.columns 
WHERE
  table_schema = '[schema_name]' 
ORDER BY
  table_name
  , ordinal_position; 






拍手



ブログ内検索
カレンダー
01 2018/02 03
S M T W T F S
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
カウンター
最新コメント
最新トラックバック
プロフィール
+ハンドル+
y_ayamori(purple)
+職業+
IT系エンジニア
+すまい+
さいたま
バーコード
ブログパーツ
アバター
Copyright © アナログを愛するデジタル生活館 All Rights Reserved.
photo by Kun material by Atelier Black/White Template by Kaie
忍者ブログ [PR]