House password (Check iO > Home)
どんな問題?
説明文が英語長文で読む気がしないが、要するに、与えられたパスワードが有効かどうかを判定すればよい。
有効なパスワードとは、
- 10文字以上
- 1文字以上の数字を含む
- 1文字以上の英字大文字を含む
- 1文字以上の英字小文字を含む
というもの。
例題はこんな感じ。
checkio('A1213pokl')==False # 10文字未満
checkio('bAse730onE')==True
checkio('asasasasasasasaas')==False # 数字、大文字がない
checkio('QWERTYqwerty')==False # 数字がない
checkio('123456123456')==False # 大文字、小文字がない
checkio('QwErTy911poqqqq')==True
どうやって解くか?
10文字以上は len(data)をチェックすればよいとして、1文字以上の○○を含む、というのは、dataをループさせて1文字ずつ調べるしかないだろう。
文字(char)が数字かどうかは、c in '0123456789' でチェックできるが、 'abcdefghijklmnopqrstuvwxyz' と書くのは、ちょっとみっともない。もっとスマートな方法はないだろうか?
というわけで、charの比較を使ってみたのがこちら。
def checkio(data): return len(data) >= 10 and \ any('0' <= c <= '9' for c in data) and \ any('A' <= c <= 'Z' for c in data) and \ any('a' <= c <= 'z' for c in data)
ちなみに、Pythonで文中で改行するのってどうやるんだっけ?と慌ててしまった。行の終わりに \ を追加すればいいんだった。
いままでC#を使っていた身としては、a < b and b < c じゃなくて a < b < c と書けるのが地味に嬉しい。
他の人の答え
正規表現を使っている人が多い。正規表現っていつまでたっても苦手意識を持ってしまう。dataにa-zが含まれているかどうかは、re.serch('[a-z]', data) でいいのか。
おっと、私と同じアプローチで、もっとスマートな書き方を見つけた。 '0123456789' や 'abcdefghijklmnopqrstuvwxyz' などは、stringモジュールで定義されているらしい。知らなかった。....〆(・ω・。)メモメモ
import string def checkio(data): return len(data) >= 10 and \ any(c in string.digits for c in data) and \ any(c in string.ascii_uppercase for c in data) and \ any(c in string.ascii_lowercase for c in data)
さらに見ていくと、isupper()とかisdigit()というメソッドを使っている人もいた。
def checkio(data): return len(data) >= 10 and \ any(c.isdigit() for c in data) and \ any(c.isupper() for c in data) and \ any(c.islower() for c in data)
こんなのあったのねー。
しかし、isdigit()とかisnumeric()とかisdecimal()とか、いろいろあって違いがわからない。ググってみた↓
http://kk6.hateblo.jp/entry/20110526/1306395713
ふむふむ、全角数字はどれも対応、ローマ数字や漢数字への対応に違いがあるのか。ん、っていうか isupper() も全角に対応かよ。
となると、パスワード 'ABCdef12345' でも通ってしまうじゃないか。
たしかに、問題文の条件に、渡されるパスワードはASCII文字のみ、とはあるけど、現実的なパスワードバリデータとしてはちょっと・・・。
ところで、一番評価の高い答えが、わけわからん。。。
checkio = lambda s: not( len(s) < 10 or s.isdigit() or s.isalpha() or s.islower() or s.isupper() )
なんかラムダ式だし。
えーっと、sが、not (10文字未満 or 全て数字 or 全て英字 or 全て大文字 or 全て小文字) なら、Trueってことか。
「全て数字でも英字でも大文字でも小文字でもない」イコール「数字と大文字と小文字が1つ以上は含まれている」ということなのね。うーん、わかりにくいが、言われてみればそうなのかな。こんなの私には思いつかないな。
と今回も勉強になりました。