はてなキーワード: defとは
先日、スマホ用の保護フィルムを買ったんだけど、とんでもない粗悪品が届いた。粗悪品という表現も本当の粗悪品に申し訳ないんじゃないかってくらい酷い物が。
その届いたものってのが、開口部に合わせて貼り付けても画面の上下左右それぞれ3~5mm以上がカバーできておらず、更に貼ったフィルム自体も上下左右3㎜~5mm位浮いてる状態。酷い不格好だし隙間はホコリを吸い寄せるんで汚らしい。
当然星1つでレビューに投稿したら、「(製品名)用に開発されたとはとても思えない」って別のレビューも投稿されてた。
それ見たらなるほど、と思った。
確かにこれ、別製品用の物を流用したってのが真相なら納得がいく。そのくらいこんな製品有り得るか?って思うものだった。
その状態で数日経った今日、自分の購入履歴のリンクを踏んでも「ページが存在しません」となる事に気付いた。
不思議に思って今度は販売元のリンクを辿ったら、販売元名を少し変化させて(例:[abc def]から[abc])全く同じ物を再出品してるのを見つけた。
当然レビューはまだない。で何故かレビューがいっこも無いのに星5つ状態で「10件のカスタマーレビュー」の表示が(リンク先は当然何も無し)。
非常に強い悪意を感じたので、amazonには既に報告済み。
出品者の住所には、CNの表記が。
最近じゃ日本の会社の倫理観も酷いもんで、CNだから悪いって訳じゃないんだろうけどね。
で、ゴミを掴まされた、無駄な買い物をしたって投稿は幾つかあったんだけど、それらは放置しておいて、今回何故ここまでの事をしたのか不思議に思って少し考えてみた。
多分、今回のレビューに「返品します」って一文があった事が、販売元にとって許し難かったんじゃないかと思ってる。
だとすると、
返品できる事がわかると困る=泣き寝入りする層には売り付けてしまおう
っていう魂胆が透けて見えるような気がして仕方ない。この予想が正しいかどうかはわからないけど。
amazonがキチンと対応する事が一番良いんだけど、イタチごっこで難しそう。
要は何を言いたいかっていうと、皆も気を付けて。
01. Gang Starr - Ex-Girl To Next Girl
02. Ill Al Skratch – Where My Homiez? (Come Around My Way)
03. Black Moon - I Gotcha Opin
04. The Pharcyde - Passin' Me By
05. Common - Breaker 1/9 (Beatnuts Remix)
06. HI-C - Sitting In The Park
07. Kool G Rap & DJ Polo - ill Street Blues
08. Black Sheep - Similak Child
09. Gang Starr - Gotta Get Over
10. Redman - Tonight's Da Night
11. Spice 1 - In My Neighborhood
12. The Pharcyde - Ya Mama
13. Arrested Development - People Everyday
15. Das EFX - Mic Checka
16. Das EFX - Real Hip Hop (Pete Rock Remix)
17. ED O.G & Da Bulldogs - I Got To Have It
19. Public Enemy - Shut Em Down
20. Eazy-E - Only If You Want It
21. 欠番(https://twitter.com/WrepRadio/status/931818391764996098)
23. Boogie Down Production - We In There
24. Dr. Dre & Snoop Dogg - Deep Cover
25. Leon Haywood - I Want'a Do Something Freaky To You
26. Dr. Dre - Nuthin' But A G Thang
27. Scraface - A Minutes To Prey
28. Brand New Heavies - Heavy Rhyme Experience Theme
29. Heavy D & The Boyz - Blue Funk
30. Above The Law - Call It What U Want
31. Digable Planets - Rebirth of Slick (Cool Like Dat)
32. Gang Starr - Take It Personal
33. 欠番(https://twitter.com/WrepRadio/status/931822759562244096)
34. Kool G Rap & DJ Polo - On The Run
35. Super Cat - Ghetto Red Hot
36. LB's - Bi*** Get A Job
37. Lords Of The Underground - Check It
38. Naughty By Nature - Hip Hop Hooray
39. Eric B. & Rakim - Paid In Full (Derek B's Urban Respray Version)
40. P.M Dawn - Set Adrift On Memory Bliss
41. Wrecks-N-Effect - Wreckx Shop (Full Crew Mix)
42. A Tribe Called Quest - Hot Sex
43. Main Source - Fakin The Funk
44. Zhiggie - Rankin' In The Dough
46. A Tribe Called Quest - Scenario
47. Black Sheep - The Choice Is Yours
48. Naughty By Nature - Uptown Anthem
49. Wrecks-N-Effect - Rump Shaker (Remix)
50. Kris Kross - Jump (Supercat Mix)
51. M.C Breed & DFC - Ain't No Future In Yo' Frontin'
52. MC Serch - Back To The Grill
53. Pete Rock & C.L. Smooth – They Reminisce Over You
54. Tom Scott and The California Dreamers - Today
55. Mary J. Blige feat. C.L. Smooth - Reminisce (Bad Boy Remix)
57. Young Black Teenagers - Tap The Bottle
58. ArtOfficial - Don't Sweat The Technique
60. EPMD - Cross Over
61. Redman - Time 4 Sum Aksion
62. House Of Pain - Jump Around
63. Wrecks-N-Effect - New Jack Swing
65. Tammy Lucas & Teddy Riley - Is It Good You
66. TLC - What About Your Friends
67. Bobby Brown - Humpin' Around
68. R. Kelly & Public Announcement - She's Got That Vibe
69. Nice & Smooth - Somethimes I Rhyme Slow
70. Jeff Redd - You Called And Told Me
72. Kris Kross - Warm It Up
73. Naughty By Nature - Everything's Gonna Be Alright
74. Ice Cube - Check Yo Self (feat. Das EFX)
---
上記の出所は WREP @WrepRadio の https://twitter.com/WrepRadio/status/931810971282059265 から https://twitter.com/WrepRadio/status/931836391440506880 までの一連のツイートより転載
本気でかっこいいとおもってやりました。実在の人物や作品に関係はありません。
・死屍の綾なす四ツ辻の、獅子も恐れる行く人の、知らぬは読者ばかりなり、綾辻行人ッ!
[中範囲に防御無視のダメージ(ダメージ量は詠唱者のHP残量に反比例)+範囲内の味方のDEFアップ]
・我が産みし死靈は天上天下に及ぶものなし! 開け、聞け、探偵三道宝階ッ! 麻耶雄嵩ッ!
[フィールドの天候がランダムに変化+各敵キャラの装備をランダムでひとつ破壊(防具や魔法による回避不可)]
・私の城は美しいお城、私の頭文字は完全なる円にして王の証ッ、死ぬまで踊れっ、舞城王太郎ッ!
・実るほど頭を垂れる稲穂かな。不燃にして不稔に非ず、エリシャの奇跡の裔と知れッ! 米澤穂信ッ!
・円心に居して惑うことなし、今宵ささめくあなたの挽歌、参ります、円居挽ッ!
・連なる城は堅固にして絢爛、三度否まず三界を紀(おさ)むッ! 連城三紀彦ッ!
・その桜の木は一本でした。桜の木は満開でした。咲いて撃ち抜けッ! 桜庭一樹ッ!
[敵全体にチキン]
・清涼のうちに流水は苔むさず、命育みメフィストフェレスの女媧とならん! 清涼 in 流水ッ!
・月光の遊戯、双頭の悪魔。国名を端から君に聞かせよう…… 英明なる都は祝福に満ちている。今出(いまいず)る川より通るがいい――アリスト(高貴なる)アリス、有栖川有栖!
[敵全体にストップ]
・朝明に白む山よッ! 一なる愛を識る永遠よッ! 枕木に憂う士(さむらい)よッ! 三位を全一なる二文字に集えッ! 乙一ッ!
・投之於冰上
鳥何燠之
何馮弓挾矢
殊能将之ッ!
・楽園の死神、その胸中に二心あり。右はくろがね、左はからかね。楽園の死神、その掌中に二刀あり。左は剔(そ)るもの、右は樵(こ)るもの。いのち捧げよッ! 汀こるものッ!
[敵全体にレベル3デス]
・占うッ、亜細亜の星を――島々の星は荘と出たッ! 島田荘司ッ!
・いちかはじめか、はじめかいちか。どんととびでて折るか祈るか、心は螺旋、折原一ッ!
[敵味方全体のうちランダムで一人にデス+ランダムで一人にレイズ(気絶キャラが存在する場合のみ)]
[敵全体に特攻大ダメージ。詠唱者は戦闘から除外(死亡ではない)]
・その本は本にして本に非ず、立体にして三次元に非ず、凶器にして狂気に非ず、どすこいどすこい京極夏彦ッ!
[中範囲の敵に大ダメージ+確率でスタン+三マス後方へノック]
関数(正確にはメソッドというのですが)は、処理を1つにまとめたものです。
print('Hello, world!') print('Good morning, world!') print('Hello, world!') print('Good morning, world!') print('Hello, world!') print('Good morning, world!')
def my_print(): print('Hello, world!') print('Good morning, world!') my_print() my_print() my_print() my_print() my_print()
python の質問になります。 - 例えばlist = [[1,あ,い,う,え,お],[2,か,き,く,... - Yahoo!知恵袋
# make csv file import csv def make_csv_file(table_data, file_path): with open(file_path, 'w') as file: for row_data in table_data: csv.writer(file).writerow(row_data) # usage list = [ ['1','a','b','c','d','e'], ['2','f','g','h','i','j'], ['3','k','l','m','n','o'] ] make_csv(list, 'sample.csv')
配信停止依頼しようにもドメインがデタラメでたぶん単純な返信メールには応じなさそうだし、
配信停止依頼にはこちらのメールアドレスを晒してメールを送らないといけないので、晒しておきますね。
※特商法ではありません
http://dkij2.b3qzt.com/special.php?special=3&s=1441443363&code=def&ssl=1441443363&ssl=1441443363
《運営者》
dkij2.b3qzt.com事務局
《メールアドレス》
info@dkij2.b3qzt.com
三角不等式なりたたんだろ。
追記
n次元空間にあるn次元ベクトルとそのm次元部分空間にあるm次元ベクトルとの距離。
結構大変だったじゃねーか。
もし本当にこれが解けなくて困ってたんなら2000円ぐらい払って欲しい。
type Vector = Array[(Int, Double)] def distanceWithProjection(p1: Vector, p2: Vector): Double = { def distance(p1: Vector, p2: Vector) = { var d = 0.0 for (i <- 0 to (p1.size - 1)) { val dp = p1(i)._2 - p2(i)._2 d += dp * dp } Math.sqrt(d) } def find(vector: Vector, i: Int): Option[(Int, Double)] = { val filterd = vector filter (v => v._1 == i) if (filterd.size == 1) Some(filterd.head) else None } def projection(from: Vector, to: Vector): Vector = { var vector = Array.fill(to.size)((0,0.0)) for (i <- 0 to (vector.size - 1)) { vector(i) = find(from, to(i)._1) match { case Some(v) => v case None => (0,0.0) } } vector } distance(projection(p1, p2), p2) }
純粋なrandom関数は、引数に渡したseed値に対して、同じseedには必ず同じ値を返す。
一つ前の乱数を再びseedにするやり方で、いくつもの乱数を純粋に取り出せるよ。
もちろん初期値が一緒なら、起動するたびに同じ答えが返るけど。
で、初期値を起動するたびに変えたいってのを純粋にやるなら、IOモナド使うことになる。
手続き系とFPどっちのが分かりやすくなるかは、ケースバイケースだから使い分けろ、ってのは正しい。
追記:
ってよく見ると、ランダム値列の作り方じゃなくて、あくまでどうやって返す関数書くか、ってことか。
それならIOモナド使うまでもないので、自分的に書きやすいScalaでfp形式で書いてしまうけど
val rands = Seq(10,20,1,6,8,0,0,0,20,10)
def f(xs: Seq[Int]) = xs.slice(0, xs.scanLeft(0){_ + _} takeWhile {_ <= 50} size)
f(rands)
でいけると思う。
... | fun x:: cmd1 x : cmd2 x : ... : cmdn x | ...
一行毎に処理する場合はxargs -Iを利用する。
$ ls *txt a.txt b.txt $ cat a.txt 1 $ cat b.txt 2 $ ls *txt | fun x:: echo x : cat x a.txt b.txt 1 2 $ ls *txt | xargs -Ix fun _:: echo x : cat x a.txt 1 b.txt 2
>と<はそれぞれ大小の不等号で置き換えてくださいな
#!/usr/bin/env python import sys from subprocess import * def take_variable(var): # check the syntax of variable (http://www.gnu.org/software/bash/manual/bash.html) # variable ::= (_|[A-z])(_|[A-z]|[0-9])* # variable contained space if len(var.split()) > 1: raise Exception('fail: the variable contained space') # check head if not (var[0].isalpha() or var[0] == '_'): raise Exception('fail: the variable contained wrong character') # check the body of variable b = True i = 0 for c in var[1:]: i += 1 # is variable contained invalid character? if not (c.isalpha() or c.isdigit() or c == '_'): b = False break # no exception if thre are only spaces after variable if not b and not var[i:].isspace(): raise Exception('fail: the variable contained wrong character') elif b: return var[0] else: return var[:i] def parse(var_to_cmds): # check the position of '::' try: pos = var_to_cmds.index('::') except Exception: raise Exception('not exists "::"') var = var_to_cmds[:pos] cmd_str = var_to_cmds[pos+2:] # check the format of variable and commands if var == '': raise Exception('fail: no variable before "::"') elif cmd_str == '': raise Exception('fail: no commands after "::"') return (take_variable(var),cmd_str) if __name__ == '__main__': # parse variable and commands try: var,cmd_str = parse(' '.join(sys.argv[1:])) except Exception, e: print >>sys.stderr, e sys.exit(1) # var -> val val = sys.stdin.read().replace('\n',' ') # mapping and split by ':' again commands = map( (lambda cmd: cmd.replace(' '+var+' ',' '+val+' ')), cmd_str.split(':')) # exec command for cmd in commands: try: # need split for remove spaces check_call(cmd.split()) except Exception,e: # print >>sys.stderr, e sys.exit(1)
本当はfunじゃなくて\(バックスラッシュ)で、:: じゃなくて→にしたかったんだけど、シェルが置き換えちゃうからしかたない
シェルの改造は禁断の手段だし
プログラムはclassに記述します。たとえばSampleという名前のclassを作る場合、Sample.csファイル内に次のように書きます。(C#の場合、ファイル名とクラス名は同一でなくても良い。複数のクラスを書いても良い)
public class Sample { }
プログラムはclass内のMainメソッドの先頭から実行されます。Mainメソッドは次のように書きます。
public class Sample { public static void Main( String[] args ) { // 処理を書く } }
Console.WriteLine( "Hello world" );
コメントです。
// 一行コメント /* 複数行コメント */
// 変数 int num;
データ型です。C#のデータ型には値型と参照型とがあります。以下は値型のデータ型です。
// int(整数)型 int num; // char(文字)型 char c; // float(単精度浮動小数点)型 float val; // double(倍精度浮動小数点)型 double val; // bool(論理)型 bool flag; // DateTime(日付)型 DateTime date;
以下は参照型のデータ型です。
// String型 String s; // 配列型 String[] array;
プログラムをコンパイルするには、コマンドラインで以下のようにします。
csc Sample.cs
プログラムを実行するには、コマンドラインで以下のようにします。
Sample.exe
mono ./Sample.exe
int、float、double型の変数に数値を代入できます。int型には整数だけ代入できます。float、double型には整数でも小数でも代入できます。
int i = 2; int i = 100000000; float num = 1.234f; double num = 1.234;
四則演算です。
num = 1 + 1; num = 1 - 1; num = 1 * 2; num = 1 / 2;
商の求め方です。割る数と割られる数が両方とも整数の場合、計算結果の小数点以下が切り捨てられます。
num = 1 / 2; // 0
割る数と割られる数のどちらかが小数の場合、計算結果の小数点以下が切り捨てられません。
num = 1.0 / 2; // 0.5 num = 1 / 2.0; // 0.5 num = 1.0 / 2.0; // 0.5
余りの求め方です。
// 余り mod = 4 % 2
インクリメントとデクリメントです。
// インクリメント ++i; // デクリメント --i;
String str = "abc";
// 結合 String join = "aaa" + "bbb"; // 分割 String[] record = "aaa,bbb,ccc".Split( "," ); // 長さ int length = "abcdef".Length(); // 切り出し "abcd".Substring( 0, 2 ) // abc // 検索 int result = "abcd".IndexOf( "cd" ) // 見つかった場合はその位置、見つからなかった場合は-1が返る
配列です。
// 配列の宣言 int[] array;
配列の生成です。配列の生成時には要素数を指定するか、初期データを指定します。
int[] array; // 要素数を指定して配列を生成 array = new int[5]; // 初期データを指定して配列を生成 array = new int[] { 1, 2, 3 }; // 宣言と同時に配列を生成 int[] array2 = new int[5];
配列の要素の参照と代入です。
// 要素の参照 array[0] array[1] // 要素の代入 array[0] = 1; array[1] = 2;
array_num = array.Length;
int[] from = new int[] { 1, 2, 3 }; int[] to = new int[5]; from.CopyTo(to, 0);
if文です。
if ( 条件 ) { }
if ~ else文です。
if ( 条件 ) { } else { }
if ~ else if文です。
if ( 条件 ) { } else if ( 条件 ) { }
while文です。
int i = 0; while ( i < 5 ) { // 処理 ++i; }
for文です。
for ( int i = 0; i < 5; ++i ) { // 処理 }
int[] fields = new int[] { 1, 2, 3 }; foreach (int field in fields) { // 処理 }
C#では関数をメソッドと言います。メソッドを作るには次のようにします。戻り値を返却するにはreturn文を使います。
static int sum( int num1, int num2 ) { int total; total = num1 + num2; return total; }
ファイル入出力です。ファイル入出力を行うには、プログラムの先頭に以下を記述します。
using System.IO;
以下がファイル入力の雛形になります。ファイルのオープンや読み込みに失敗した場合、catch節に処理が移ります。
String filename = "text.txt"; StreamReader reader = null; try { reader = new StreamReader(filename); String line; while ((line = reader.ReadLine()) != null) { } } catch (IOException e) { // エラー処理: } finally { if (reader != null) { try { reader.Close(); } catch (IOException e) { } } }
またはC#ではusing ステートメントと言うものがあり、この様にも書ける
String filename = "text.txt"; using (StreamReader reader = new StreamReader(filename)) { try { String line; while ((line = reader.ReadLine()) != null) { // 読み込んだ行を処理 } } catch (IOException e) { // エラー処理: } }
usingをつかうとCloseがなくなったことからわかるようにusing(){}を抜けるときに自動的にDisposeメソッドを呼び出し、オブジェクトを廃棄する。その分コードがスッキリするが、使いにくい場面もあるので考えて使うこと。
以下がファイル出力の雛形になります。ファイルのオープンや書き込みに失敗した場合、catch節に処理が移ります。
String filename = "text.txt"; StreamWriter writer = null; try { writer = new StreamWriter(filename)); writer.WriteLine("abc"); writer.WriteLine("def"); writer.WriteLine("fgh"); } catch (IOException e) { // エラー処理: } finally { if (writer != null) { writer.Close(); } }
こちらもusingを使って書ける。が、割愛する。
C#でよく出てくる知っておいたほうがよい文法の一覧です。
繰り返し文の途中で抜けるにはbreak文を使用します。
for ( i = 0; i < 5; ++i ) { if ( 条件 ) { break; // 条件を満たす場合、for文を抜ける。 } }
残りの部分処理をスキップし、次の繰り返しに進むにはcontinue文を使用します。
for ( i = 0; i < 5; ++i ) { if ( 条件 ) { continue; // 条件を満たす場合、残りの部分処理をスキップし、次の繰り返しに進む。 } }
例外を投げるにはthrow文を使用します。
throw new Exception( "Error messsage" );
try { // 例外が発生する可能性のある処理 } catch ( Exception e ) { // 例外発生時の処理 }
Pythonの方が弄れる対象が多いのに、なんでウェブ系だとPHPの方が流行ってんだろ
端末からのテキスト処理も楽だし、数値計算周りのライブラリも充実しているのに
PHPが優遇されているのって歴史的な経緯以外に何か他の理由でもあるのか?
けどまぁ、情弱な文系SEが大半を占めているバカだらけの日本じゃ別にPHPで困ることもないか
数値計算や端末からのテキスト処理なんてWeb系じゃ大して使わないからなあ…
Pythonに関しては、ZopeさえコケていなければWebサーバ用LLとして大成功していたはずなのに、
Railsなんかが登場したおかげで、すっかり影が薄くなってしまいますた....
ってか、railsにインスパイアされたフレームワークって今じゃ幾らでもあるよね
djangoとかCakePHPとか。rubyってRoRを使いたいユーザを除くと、
pythonやPHPの方がユーザー数は圧倒的に多いと思うんだけど
本家のrailsって、他を遥かに越えるほど良いものなんだっけ?
44
Zopeが登場した当時、「RDB+PHPはもう古い、これからはOODB+ZopeがWebの中軸になる!」と
少なくとも自分はZopeからPythonという言語を知ったし、その時点でRubyは知らなかった
そして、その後のORM(RDB)+Railsの出現と華々しい革新性への注目は、誰もが知っているだろう
今でもZopeの開発は継続されてはいるが、結果的に当初の期待が大きく裏切られたという事実は動かしがたい
djangoとCakePHPについては実際に触っていないので憶測になるが、おそらく技術水準ではRailsと同等だろう
しかしRailsはRailsでコミュニティの活動が活発だし、その進化は異常に早い
Railsに何か致命的なトラブルが発生して開発が停滞する、あるいはdjangoやCakePHPから
何かのイノベーションが提示されでもされない限り、後発のdjangoやCakePHPがRailsに追いつくのは無理
Railsは決して技術的に完璧なWebフレームワークではないんだけどね....(たとえばSeaSideのような.... )
だからこそ「もしもZopeが....だったなら」という「たら・れば」感はPythonコミュニティの潜在認識になっている
C a k e P H P は う ん こ
CakePHP使ってんの?
可哀そうにw
でもやっぱりいつもの使い慣れたLL(Python/Ruby)で
Webサービスを書きたいってのがある
求人数は
Ruby on Rails>>>>>>>>Django
http://www.indeed.com/jobtrends?q=django%2Cruby+on+rails&l=
どういうことなの?
求人数が多いのはそのためだと思うよ
なんかのミスかと思ったがアメリカでもRuby on Railsは人気があるのかなあ・・・
Pythonのほうが使いやすいと思うのだがフレームワークはRailsが優位なんだろうか
Djangoは周辺ライブラリが微妙だし本体も鈍くさい感じがする。
でも、FlaskはSinatraより好きだから、Pythonが嫌いってわけではない。むしろ好き。
ただ、いざ作り始めるとやっぱりRailsが楽だなあってなって、Railsを使い続けている。
同感だ
同じように思っている人が他にもいて安心した
PHPはフレームワークが乱立しすぎているから、RailsをPHPで実装してみようというやつが出てきた。
それに比べてPythonは、Zopeというデファクトスタンダードが既に存在していたけど、
ただ、どうやってもRailsもどきがRailsを超えることはできないのは間違いない。
パクリはオリジナルを超えられない(キリッ って定型句だけど、
これってキリッって言いたいだけだと思う。
D言語って超えたって?
B言語って超えたって?
PHPで同じ事をできないわけではないだろうけど、Ruby on Railsほど簡潔にはできない
まあくだらねえWEBサービス作って喜んでる情弱は早く死ねって事だよ
そういう理由じゃなくてRailsのほうが単純に情報もプラグインも多いからでしょ
linuxじゃデフォのツールなんだし、ツールとの連携を考えたらpython一択じゃん
わざわざ不合理で不完全な言語を使うなんて
もしも
>linuxじゃデフォのツールなんだし、ツールとの連携を考えたらpython一択じゃん
真実であるのなら、今頃はdjangoの情報とプラグインが溢れかえっているはず
yumや、gdbとgnomeの拡張がpythonであるからといって、それをwebアプリでも使いたいと思う人は少ないというだけのこと。
ソースからインストールする必要があったとしても、web開発ではrubyを使いたいという人が多いというだけのこと。
というか、世界中のPythonプログラマが Remeber Zope!! を合い言葉に
打倒RailsたるWebフレームワークを開発しているはずだけど、
Railsも登場してから、かなりの年月が経過しているんだけどなぁ....
その間にもRailsはRails 3が登場して、REST/AJAXの強化等の進化が継続しているよ
Ruby では
ary.map {|x| x**2}
map(lambda x: x**2, ary)
となり、lambda の本体が1つの式では表現しきれなくなると
.....
と書き換える必要があります。
f = lambda x:(x and f(x-1)*x)or 1
RubyにはPythonのように「lambda本体は式でなければならない」という限定がありませんから、
f = lambda{|x|if x == 0 then 1 else x*f.call(x-1) end}
または
f = lambda{|x|x == 0 ? 1 : x*f.call(x-1)}
と書けます。lambda内でreturnが使えますから、書きたければ
f = lambda{|x|if x == 0 then return 1 else return x*f.call(x-1) end}
でもOKです。
348
これはPythonをdisっているように見せかけてRubyをdisっているのか? と一瞬思ってしまったw
だってRubyのほうが長くない?CLのfuncallみたいなcall()がちょっとうざいし…
そしてどっちもlambda式の中で束縛変数の名前で再帰可能、と
print [x*2+100 for x in [1,2,3,4,5] if x > 2 and x < 5]
暗号のように見える。
puts [1,2,3,4,5].select{|i| i > 2 and i < 5}.map{|i| i*2+100}
思考の流れと、コードの流れが一致しているので書きやすい。
map(lambda x: x*2+100, filter(lambda x: x > 2 and x < 5, [1,2,3,4,5]))
pythonて可読性が高いのをうたってる割にはそこいまいちだよね
Rubyの場合には、左から右へと無名関数がデータフローあるいは
関数型プログラミングに不慣れな初心者でも、参照透明性のあるコードが自然に書ける
プログラマにとって優しい or プログラミングの楽しさを教えてくれるのがRuby
それと比較すると、Pythonのコードは、関数型プログラミングというものが
いかに高度で難解なものであるかという事をもったいぶってプログラマに押し付ける
もしもPythonしか知らないプログラマであれば、関数型 = 難解 という印象を持つだろう
階乗計算くらいだと単純すぎて、ナゼ重要なのかが分かりづらいと思うのでコードで示す
result_list = source_list.map { |elem|
x = foo(elem.x) # ここが局所宣言を書く部分
x + y # 最後に評価された式の値が、無名関数のリターン値になる
}
Rubyでは、map等に与える無名関数の中で局所的な環境(クロージャ)が作られるから、
x = foo(...) のような代入文がいくつでも(= 複雑な処理でも)書ける
このポイントは、実用的なプログラムを関数型風で書こうとした時に、威力を発揮する
余計分かりづらくなった
高卒ドカタなんだろうなぁと可哀想になる
集合の表記に似せてることが分かるから
355
>map/filterはfor/ifと同じだと言っているだけだから、難解という印象は持たない。
関数型プログラミングに慣れた、あるいは得意な人であれば、そういった印象なんだろね
Rubyの魅力はこれから関数型プログラミングを学ぼうとする初心者、 あるいはそんな初心者へ教える立場から見た、優しさ or 分かりやすさなんだ
[1,4,3,2].sort.reverse.map{|x| x.to_s}.join('-')
Pythonだと読みにくい。
'-'.join(map(str, reversed(sorted([1,4,3,2]))))
Pythonでは思考の流れと一致しないばかりか、「カッコだらけ」のコードになると.....
カッコだらけのコードを分かりやすくする基本的な方法は静的単一代入じゃないか
Rubyのやり方は基本ではなく玄人のやり方だろ
Pythonでは組み込みの型でメソッドチェインはやって欲しくないな
似たようなコレクションtuple,deque,array,queue等にも同じメソッドが必要になってくるし。
372
外部のライブラリでも列挙可能なものは、たいていEnumerableモジュールをimportしてますね
Rubyユーザーは列挙可能なものはmapやselectできて当然だろって思ってる気がします
Pythonは「何かを便利に書くためのしわ寄せ」をはっきり寄せてくる
得意と不得意を言語レベルではっきり主張するのでメリケン好みと言えなくもない
Rubyは全方位になんとなく八方美人なので、全体的になんとなく書きやすくてなんとなくキモくて遅い
「書きにくいってことはその処理に向いてないってことだから諦めろ」を地で行く
無名関数が文を使うほど複雑なら名前を付けるのが Python 流と想像。
これを読みづらいと感じるのは、左から右に流れる
もしかしてアラビア語ネイティブな人からすると逆に読みやすいのか?
トム・クルーズが若い頃、たしかトップガンの次の次ぐらいに出た作品で、アカデミー賞を取っている。
△△△
主人公のチャーリー(トム)は、父の遺産相続問題をきっかけに、自分が物心つく前から施設に入ってて存在すら知らなかった兄のレイモンド(ダスティン・ホフマン)と再会して、施設から無理やり連れ出してはみたものの、自閉症のレイモンドが次々にやらかす奇行にすっかり参ってしまう。飛行機で移動しようと空港に行けば、「ABC航空はダメ、19xx年x月x日どこどこで墜落○○人死亡。DEF航空?ノー!19xx年x月x日○○人死亡……」と百科事典のように正確な記憶力を見せて暴れ回る。
弟がいくら確率を持ち出して説得しても兄のパニックはおさまらない。
根負けしたチャーリーが数千キロもの行程を運転して行こうと高速に乗れば、今度はハイウエイの死亡事故統計を口走って「いやだー!死ぬー!」と絶叫するレイモンド。
「どうすりゃいいんだよ!」とキレたチャーリーは、名前のない田舎道ばかりを走って西をめざすことに。野原の真ん中のうらぶれた安宿で熱いバスにでもつかろうと湯の栓をひねると、「ダメーーー!そんなことしたら赤ちゃんが!」とまたしても半狂乱に。
△△△
映画だと、レイモンドのこの熱い湯船トラウマをきっかけにして幼かった兄弟の心の触れ合いの記憶が少しずつ呼び戻され、そこからしみじみと感動的なラストに向かって物語が動いていくのだけれど、別にここでなつかし映画語りがしたかったわけじゃない。
書きたかったのは、あの日以来、俺の嫁がレインマンになってしまったってことだ。
たぶん俺の嫁だけじゃない。日本中で、いや、遠く韓国や中国、欧州にも、突然たくさんのレインマンが生まれてしまったんだ。
△△△
「大丈夫だよ、この説明を見てみなよ」
「そうは言うけど、実際言われてるような事態にはなってないじゃん」
等々、いくら条理をつくして話し合ってもダメなのだ。
嫁は怖いのだ。
安心より、怖いという気持を選んだのだ。
だから、科学的にマユツバだと言われようと、自分の原始的な恐怖心にフィットするものばかりに注目し、耳を傾ける。そして言う。
「ほら、ご覧なさいよ!みんなそう言ってる」
嫁がブックマークしているサイトやフォローしているツイッターの発信者名を見て、俺は失神しそうになった。
俺のTLでは、「○ン○○」だの「○ル○」だのと認定されている名前がきら星のごとく並んでいる。そう、微生物がコロニーを作るみたいに、彼らはお互いに引かれ合って堅固なオピニオン集団を形成しているのだ。
嫁が俺じゃなくて○○○○や○o○の行進についていく。
マジかよ。
勘弁してくれ。
△△△
映画のチャーリーとレイモンドのような取っ組み合いにはならなかったけど、来る日も来る日も絶望的な言い争いが続いた。
わが家の食卓からはいくつかの食品が完全に姿を消し、子供は給食の牛乳にかえて水筒を持参するようになった。俺自身の親兄弟との関係もぎくしゃくしている。嫁が何か新しい心配の種を仕入れてくるたび、子供に新しい命令/禁止を下すたび、俺と嫁は決着のつかない論争を繰り返した。
△△△
でも。
俺には嫁を放り出すことはできなかった。
「愛してるから」かと聞かれても、正直うなずけない。
そんなきれいごとにしがみついていられるには、醜悪なものを見過ぎてしまった。
でも、俺がここで見切ったら、嫁には行くところがない。
子供は俺一人でもなんとかなる自信はあるが、子供は俺のことも嫁のことも愛している。
もちろん、俺も嫁も、それぞれの人として限られた能力の限りを尽くして子供を愛している。
△△△
四捨五入すればもう五十になろうっていうこの年で、いきなりレインマンと暮らす羽目になるとか、誰に想像できただろう。
ここで「考えや感じ方が違いすぎて落としどころさえ見つからない相手」をレインマンと呼ぶ俺には、全方向からごうごうたる非難が浴びせられるだろう。
嫁のコロニーからは「人をバカにするな!」と言われるだろうし、
俺のTLで気を吐いている闘士たちからは「ダスティン・ホフマンのようなほのぼのキャラに喩えるなどぬるいわ!」と批判されるだろう。
そしてなにより、現実に自閉症の人々と生活し、関わっている人たちからは、「偏見もいいところのとんだ愚か者」と指弾を受けるに違いない。この文章は、何の関係もないそれらの人々を引き合いに出す意図で書かれたものではないが、だからといって失礼が帳消しになるわけではない。そういった方々には心からお詫びしたい。
△△△
ただ。
映画の前半で「何やってんだよ!」ってキレまくって、少しでも兄に普通の行動を取らせようと無駄な努力にきゅうきゅうとしていたチャーリーが、レイモンドの目に映っている世界を、レイモンドの視点から理解して、彼に共感はできないものの、たった一人の肉親としてずっとそばにいようとするようになっていく過程を思った時、そこにはこれまでの俺の文字通りハゲになりそうな苦しみに、なんというか一条の光を投げかけてくれるヒントが潜んでいるんじゃないかって思ったのだ。
レインマンの奇行を迷惑がって、施設に追いやってしまうことも一つの道だけど、
そうはできない家族にとって、できることはなんだろう。
チャーリーは、自ら悩み苦しみながら、レイモンドへの愛を見つけて再生できた。
俺はまだ、嫁への愛を見つけ出していない。
△△△
うちのレインマンは、雨の日を極端に恐れている。
雨が降ると、家族全員に外出を禁止する。
雨じゃなくて、嫁に降り込められたうちの中で、俺はダスティン・ホフマンの顔をしたどこかのラスボスに祈りを捧げる。
――なあ、レインマン。
――ここに来て、歌ってくれよ。
――心に火傷を負った俺たちみんなのために。
RubyのSymbolと文字列の違いを研究室の輪講用に書いたのですが,折角なので公開したいと思います.
元々学部生に対する輪講用に書いた物なので,若干上から目線ですがご了承ください.
文字列とSymbolはよく似ています.プログラマから見ればどちらも文字列です.違いを一言で説明すると『プログラムが扱う』文字列か,『プログラマが見る』文字列かの違いです.例えば変数名は『文字列』ですが,rubyのオブジェクトである『文字列』ではないですよね?
例えば,今あなたがC言語でお絵描きライブラリを作っているとしましょう.その中に,色で塗りつぶすfillという関数があり,色を青・赤・緑の3色から選べ,fillの引数でそれを指定できるとしましょう.
fillの引数の設定方法として一番単純なのが,0を青,1を赤,2を緑として,0〜2で選択させる方法でしょう.しかし,それでは,どの数値が何色か覚えないといけないし,fill関数を知らない人から見れば,どういう意味の引数かすらさっぱり分かりません.
ではどうするかと言えば,普通はBLUE = 0, RED = 1, GREEN = 2と適当に定数を設定して,その定数を引数で指定させますよね.
こうして,fill関数の引数が意味の無い数値から意味のある文字列に変わったことによってプログラムが分かりやすい物となります.さて,ここで注意してほしいのは,ここで言う文字列はプログラムが扱うオブジェクトとしての文字列では無いということです.fill関数の引数として,"BLUE","RED", "GREEN"などとC言語の文字列を渡すということは普通しませんよね.それは,ここで言う文字列は,あくまでプログラマがプログラムコードを分かりやすくするために必要な文字列であって,プログラムがオブジェクトとして扱う(例えば,長さを求めるとかする)文字列ではないからです.
分かってきたでしょうか?
プログラムコード上では(つまりプログラマから見れば)どちらも同じ文字列(文字の列という意味で)ですが,実際に動くプログラムから見れば単なる数値と本物の文字列という大きな違いです.結局,fill関数の引数の具体的な値は何でもいいわけです.プログラマから見て文字列であればそれだけでよく,プログラムが動くときの実際のその中身は何でもいいわけです.これのために存在するのが,Symbolであり,:fooとひとたびSymbolを作成すれば:fooの実態は適当な数値となります.(この数値がいくらかなんていうことはもちろん気にする必要はありません)
そして,もちろん同じプログラム上では:foo == :fooはちゃんと成り立ちます.もうここまでくれば,Hashのkeyとして文字列でなくSymbolを使う理由が分かりますね.Hashのkeyはあくまで,プログラマが見る(プログラムコードを分かりやすくするための)文字列であってプログラムが扱うオブジェクトとしての文字列では無くて,keyの実際の値は何でもいい,からですね.(特別な場合を除いて)Hashのkeyに対してrubyのStringのメソッドを使うなんてことは無いですよね.
しかし,他の軽量言語ではSymbolなどなくHashのkeyとして普通に文字列を使うことが多いです.では,なぜrubyだけSymbolを使うのでしょうか.
その答えは一言でいうと,rubyの(プログラムコード上に直接書かれた,つまりリテラルの)文字列は他の言語と違いimmutable(不変)でない,からです.実際,pythonやjavascriptの文字列(リテラル)は破壊的に変更することはできませんが,rubyの文字列は破壊的に変更することができます. ('abc'.concat('d')の様に)
これがどういう違いを生むかというと,コード上に直接現れる文字列がimmutable(不変)であるならば,実行時に一つだけそのオブジェクトを作成し,後はそれを使いまわすという最適化ができます.
そうした時,Hashのkeyの様なプログラマから見た文字列というのは,プログラムコード上のリテラルとして現れるわけですが,これらは実行時に一つだけオブジェクトが作成され(特にコード上に現れる同じ文字列は全て一つのオブジェクトにまとめると),それらの比較はそれらに対する参照(そしてこれは大抵メモリのアドレスなど単なる数値)の比較で済むので,結局Symbolと同じ様な働きをするわけです.
本当はプログラマが見るためだけの文字列だけど,それをオブジェクトとしての文字列としても,Symbolと同じ様な働き,パフォーマンスが得られるならば,別にオブジェクトとしての文字列であってもいいわけです.
繰り返しになりますが,プログラマが見るためだけの文字列は,その中身・実態は何でもいいわけですが,その実態がオブジェクトとしての文字列でも十分なパフォーマンスが得られるならば,別にオブジェクトとしての文字列でもいいわけです.
さて,rubyに話を戻しますと,rubyはコード上に現れる文字列であっても,実行時にそのコードを通る度に毎回新たな文字列オブジェクトを作成します.
(以下のプログラムを動かすことで確認できる.)
def foo 'foo'.object_id end p foo, foo
つまり,rubyでは文字列が可変であるため,先に述べたような最適化ができない(または難しい)ので毎回新たな文字列オブジェクトが作成されるのです.
こうなると,先ほどの話とはうってかわって,プログラマが見る文字列はその実態は何でもいいのに,それを文字列リテラル(rubyのオブジェクトとしての文字列)にしてしまうと,毎回毎回文字列オブジェクトが作成されてしまうという非常にばかばかしい状況になってしまいます.我々はそれらの文字列オブジェクトに文字列としての操作は一切施さないのにも関わらず,です.
こういうわけで,rubyではプログラマが見るためだけの文字列にSymbolというruby特有のものを使うのです.
もちろん,プログラマが見るためだけの文字列を全て定数として(そしてもちろん中身は適当な値で)定義しても構わないわけですが,Hashのkeyとかで数多くのプログラマが見るためだけの文字列が現れることを考えると,とてもじゃないですけどそんなことは面倒でやってられないですよね.ですので,実行時に自動で適当な値にしてくれるSymbolというものが存在するのです.
以上で,Symbolについての説明を終えます.以下は蛇足です.
最初の方で出てきたfill関数をrubyで実装しようとしたとき,青・赤・緑の各色はその実際の値はなんでもいいのでrubyのSymbolを使って:blue, :red, :greenとしてもいいのですが,ライブラリとかでは大抵ちゃんと定数として定義されていることが多いです.
これは恐らく,定数として明示的に定義することで値の存在を明示でき,ドキュメント化の際にも役立つことによっているのでしょう.
しかし,あくまでこれは外部に公開するようなライブラリでの話であって,自分が使うちょっとしたプログラムならこういう場面でも精力的にSymbolを使っていってもいいと思います.ちなみに,僕ならSymbolを使います.
Symbolだと定義もいりませんし,定数は大文字ですから打つのが面倒ですし,あまりソースに大文字が入ると見た目がすっきりしません(主観).
Symbolは非常に便利なものですので,その意義・用途を十分に理解して,Hashのkeyにとどまらず様々な所で使えるようになりましょう.