はてなキーワード: lenとは
% poetry cache clear --help USAGE poetry cache clear [--all] <cache> ARGUMENTS <cache> The name of the cache to clear. OPTIONS --all Clear all entries in the cache. GLOBAL OPTIONS -h (--help) Display this help message -q (--quiet) Do not output any message -v (--verbose) Increase the verbosity of messages: "-v" for normal output, "-vv" for more verbose output and "-vvv" for debug -V (--version) Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n (--no-interaction) Do not ask any interactive question
これ見ると
poetry cache clear pypi
で動きそうじゃん?
% poetry cache clear pypi RuntimeError Add the --all option if you want to clear all pypi caches at /usr/local/lib/python3.8/site-packages/poetry/console/commands/cache/clear.py:44 in handle 40│ ) 41│ 42│ if len(parts) == 1: 43│ if not self.option("all"): → 44│ raise RuntimeError( 45│ "Add the --all option if you want to clear all " 46│ "{} caches".format(parts[0]) 47│ ) 48│
ブブー
動きません
正しくはこう
poetry cache clear pypi --all
直感的には--allをついてたら全てのキャッシュを消すべきだと思うが
% poetry cache clear --all Not enough arguments (missing: "cache").
ブブー
動きません
意味不明に思ったのは俺だけではないらしくIssueが出ている
https://github.com/python-poetry/poetry/issues/521
opened this issue on 19 Oct 2018 · 18 comments
2年前ですよ2年前!
Issue700個も溜まってますよ
pipenvもアレだったけどpoetryもアレだな
もう少しマシな奴が欲しい
def myfunc(arr): if len(arr) <= 1: return arr left = [] right = [] ref = arr[0] ref_count = 0 for e in arr: if e < ref: left.append(e) elif e > ref: right.append(e) else: ref_count += 1 left = myfunc(left) right = myfunc(right) return left + [ref] * ref_count + right
1. こんな感じで使います。
$ python parser.py sample.py
import parser code = ''' a = 1 + 1 print(a) ''' graph = parser.create_graph(code) graph.render("sample")
import ast import sys import graphviz def create_graph(lines): graph = graphviz.Graph(format='png') root = ast.parse(lines) node_list = [root] _setup(graph, node_list) return graph def _setup(graph, node_list): # node node = node_list[-1] node_identity = str(len(node_list)) node_name = type(node).__name__ graph.node(node_identity, node_name) # children for child in ast.iter_child_nodes(node): node_list.append(child) child_identity = str(len(node_list)) graph.edge(node_identity, child_identity) _setup(graph, node_list) if __name__ == '__main__': file_name = sys.argv[1] with open(file_name) as file: lines = file.read() graph = create_graph(lines) graph.render(file_name)
class mystring { public: char *buffer; mystring() { buffer = (char*)""; } void operator = (const char*t) { int len = strlen(t); buffer = new char[len + 47]; strcpy(buffer, t); } void operator = (const mystring&src) { int len = strlen(src.buffer); buffer = new char[len + 47]; strcpy(buffer, src.buffer); } mystring& operator + (const char*t) { int len = strlen(buffer); int len2 = strlen(t); char *buffer2 = new char[len + len2 + 47]; strcpy(buffer2, buffer); strcpy(buffer2+len, t); buffer = buffer2; return *this; } mystring& operator + (const mystring&src) { return ((*this) + src.buffer); } };
class mystringV { public: std::vector<char> buffer; mystringV() { buffer.resize(2); buffer[0] = ' '; buffer[1] = NULL; } void operator = (const char*t) { int len = strlen(t); buffer.resize(len+1); strcpy(&buffer.at(0), t); } void operator = (const mystringV&src) { buffer = src.buffer; } mystringV& operator + (const char*t) { int len = strlen(&buffer.at(0)); int len2 = strlen(t); buffer.resize(len + len2 + 47); strcpy(&buffer.at(0) + len, t); return *this; } mystringV& operator + (const mystringV&src) { return ((*this) + &src.buffer.at(0)); } };
いろんな事をプログラマにかわってライブラリがやってしまうということ
どうなんだろうね。
この辺は あまりしっかり おしえてもらえないところではある。
でも プロならみんな 知っている
class mystring { public: char *buffer; mystring() { buffer = (char*)""; } void operator = (const char*t) { int len = strlen(t); buffer = new char[len + 47]; strcpy(buffer, t); } void operator = (const mystring&src) { int len = strlen(src.buffer); buffer = new char[len + 47]; strcpy(buffer, src.buffer); } mystring& operator + (const char*t) { int len = strlen(buffer); int len2 = strlen(t); char *buffer2 = new char[len + len2 + 47]; strcpy(buffer2, buffer); strcpy(buffer2+len, t); buffer = buffer2; return *this; } mystring& operator + (const mystring&src) { return ((*this) + src.buffer); } };
mystring my_space_org; for (int i = 0; i < 8; i++) { mystring space; space = my_space_org + " "; printf("%sHello world\n", space.buffer); my_space_org = space; }
while True: num = input() '数値ではありません' if not num.isdigit() else '4桁ではありません' if len(num) != 4 else [i for i in num]
from typing import Sequence class ReverseSequence(object): def __init__(self, sequence: Sequence): self.sequence = sequence # reference to container self.index = len(sequence) # current index # Step 1. define __iter__ method whitch returns self. def __iter__(self): return self # Step 2. define __next__ method # rasing StopIteration at the end of iteration. def __next__(self): if self.index > 0: self.index = self.index - 1 # next index return self.sequence[self.index] else: raise StopIteration class ReverseSequenceGenerator(object): def __init__(self, sequence: Sequence): self.sequence = sequence self.index = len(sequence) def __iter__(self): while self.index > 0: self.index = self.index - 1 yield self.sequence[self.index] raise StopIteration assert list.__eq__( [element for element in ReverseSequence('spam')], [element for element in ReverseSequenceGenerator('spam')] )
class Reverse: def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def __next__(self): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index] class ReverseGenerator: def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): while True: if self.index == 0: raise StopIteration self.index = self.index - 1 yield self.data[self.index] assert [s for s in Reverse('spam')] == [s for s in ReverseGenerator('spam')]
でもさ、なんか一貫性が無いように感じるんだよね。
まず、言語の大半の部分がオブジェクト指向言語っぽいデザインになってるのに、listの要素数を測る手段はlen()って*関数*なのはどうなの?
a = [1, 2, 3] len(a) # 3
俺は、sortとsortedって言う命名からこの挙動をまったく予測できなかった。
a = [1, 3, 2] a.sort() # None a # [1, 2, 3]
sorted([1, 3, 2]) # [1, 2, 3]
しかもsortedにdictを渡すとkeyがlistに変換されてソートされて返ってくる。
コードリーダビリティに関する本を開けば、どの本にだって「良い名前を選択する」ことの重要性が書かれていると思う。
「sort()が破壊的で、sorted()が非破壊的、sorted()にdictを渡すとkeyのlistがソートされて返ってくる」これって良い命名なのかな?
", ".join(['1', '2', '4', '8', '16']) # "1, 2, 4, 8, 16"
しかも、これに対する「文字列リテラル (文字列定数) のメソッドを使うのは*醜すぎる*」という意見に対しての公式の返答が、これってのも凄い。
確かにそうかも知れませんが*文字列リテラルは単なる固定された値に過ぎないというのが答えです。文字列に束縛された名前にメソッドが許されるなら、リテラルに使えないようにする論理的な理由はないでしょう。
The Zen of Pythonで「醜いより美しい方がいい」って言ってましたやん。
そもそもリテラルかどうかに関係なくstrインスタンスにこのメソッドがある事がおかしいと思った。
pythonのmapは関数として実装されている。(まただよ...)
list(map(lambda x: x*x, [1, 2, 3])) # [1, 4, 9]
なんでメソッドにしなかったの? って質問に対して公式がこう答えてる。
主な理由は歴史です。複数の型に対しての総称的な操作で、対象のオブジェクトがメソッドを全く持っていなかった (例えば、タプル) としても働くよう意図したものに関数は使われました。
(中略)
うわー、信じられねぇ…
歴史的経緯があるから一貫性が無いのは仕方ないみたいなこの感じ。
これが設計思想に「醜いより美しい方がいい」を掲げるpythonの実装なんだねぇ…
散々pythonの事を悪く言ったけど、おれ実はpythonくんの良い所もいっぱい知ってるんだ。
pythonくんの良い所:
The Zen of PythonにPythonの設計思想が色々書いてある。
「醜いより美しいほうがいい」という指針があることはさっき紹介した通りだ。
でもThe Zen of Pythonには「Although practicality beats purity.(実用性を求めると純粋さが失われることがある。)」とも書いてある。
pythonはこの設計思想を他の言語には無い高いレベルで体現してるとは思う。
pythonは、
無節操に色々取り入れた上で、「tupleからメソッドはやせないから、mapは関数にする」とか、メチャクチャな方法でそれらを統合した言語だ。
だが、そういう言語だからこそ、pythonで書いたコードを育てていく中で様々なパラダイムへとシームレスに変化させていく事ができる。
そういう「不純であるがゆえに柔軟性を持ったプログラミング」言語がpythonだと思う。
rubyの純粋性はすごいよ。イカれたくらい徹底されたオブジェクト指向。
BaseObjectをrootとする継承のツリーの中に世界のすべてが収まっている。
haskellの純粋性も凄い。「代入が無い」プログラミング言語に初めてであった時の衝撃。
score_list = [] while True: score = int(input()) if score == -1: break score_list.append(score) print(min(score_list)) print(sum(score_list) // len(score_list)) # // round off print(max(score_list))
itertools でこうか... すごい.., これが generator か..
itertools.takewhile の lambda x: x != -1 が False になると
itertools.repeat も yeild を止めるのか..
import itertools score_list = list(itertools.takewhile(lambda x: x != -1, (int(input()) for i in itertools.repeat(None)))) print(min(score_list), sum(score_list) // len(score_list), max(score_list), sep="\n")
やってることは変わらないんですよ。
例えば、数値文字列を1文字ごとに分解して、文字を数値に変換したリストを作れって言われたらこう書くとする。
僕「こう書いてみた」
a = [int(x) for x in '123'] print(a)
A君「こういう書き方も出来るよ。」
a = list(map(int, [x for x in '123'])) print(a)
B君「俺ならこうだな。」
s = '123' a = [] i = 0 while len(s) > i: a.append(int(s[i])) i += 1 print(a)
qiitaとかでこの例のような短いコードでなら、いろんな書き方を提示してくれるのはいいんだよ。歓迎する。
それ、やってること同じじゃんみたいな。
僕のもA君のもB君のでもやってる事は同じなんだよ。
そんなんでいちいちpull requestするなっていうね。
「ランダムな整数がランダムな個数引数に渡されて、それらを添字順にひとつずつ足して行き、50を超えたらそれまでの配列の中身を返す」みたいなのってどうやって書くんだろう。
手続き的に書くなら
var randoms = [10, 20, 1, 6, 8, 0, 0, 0, 20, 10];
var total = 0;
for (var i = 0, len = randoms.length; i < len; i++) {
total += randoms[i];
}
return randoms.slice(0, i);
みたいな感じですぐ思いつくんだけど、純粋な関数型って変数も許してないしこういうやつは reduce するんでしょ。
まったくわからない。できないんだとしたら何が優れてるんだ。
もちろん、関数型的に each とか map とかすると見やすくなるケースが多いのはわかってるけど。
できること、できないこと、そういうのがあるから結局マルチパラダイムな言語でいい感じに取捨選択してねーってことなのかなあ。
Option Explicit Private Const INTERNET_OPEN_TYPE_PRECONFIG = 0 Private Const INTERNET_OPEN_TYPE_DIRECT = 1 Private Const INTERNET_OPEN_TYPE_PROXY = 3 Private Const INTERNET_SERVICE_HTTP = 3 Private Const INTERNET_DEFAULT_HTTP_PORT = 80 Private Const INTERNET_FLAG_RELOAD = &amp;H80000000 Private Declare Function InternetOpenA Lib "wininet.dll" (ByVal sCallerName As String, ByVal dwAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal dwFlags As Long) As Long Private Declare Function InternetConnectA Lib "wininet.dll" (ByVal hInternetSession As Long, ByVal sServerName As String, ByVal nProxyPort As Integer, ByVal sUserName As String, ByVal sPassword As String, ByVal dwService As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long Private Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByRef sBuffer As Byte, ByVal lNumberBytesToRead As Long, ByRef lNumberOfBytesRead As Long) As Long Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInternetHandle As Long) As Long Private Declare Function HttpOpenRequestA Lib "wininet.dll" (ByVal hConnect As Long, ByVal sVerb As String, ByVal sObjectName As String, ByVal sVersion As String, ByVal sReferer As String, ByVal sAcceptTypes As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long Private Declare Function HttpSendRequestA Lib "wininet.dll" (ByVal hRequest As Long, ByVal sHeaders As String, ByVal dwHeadersLength As Long, ByVal lpOptional As String, ByVal dwOptionalLength As Long) As Long Private Function submitPost(ByRef host, ByRef url_path, ByRef sendString) As Variant Dim dataArray() As Byte, dataPosition, dataSize 'WinInet初期化 Dim hInternet hInternet = InternetOpenA(vbNullString, INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0) If hInternet = 0 Then submitPost = dataArray Exit Function End If 'サーバ接続 Dim hConnect hConnect = InternetConnectA(hInternet, host, INTERNET_DEFAULT_HTTP_PORT, vbNullString, vbNullString, INTERNET_SERVICE_HTTP, 0, 0) If hConnect = 0 Then InternetCloseHandle hInternet submitPost = dataArray Exit Function End If 'リクエストを初期化 Dim tmpURL As String * 255 tmpURL = url_path Dim hRequest hRequest = HttpOpenRequestA(hConnect, "POST", tmpURL, "HTTP/1.1", vbNullString, 0, INTERNET_FLAG_RELOAD, 0) If hRequest = 0 Then InternetCloseHandle hConnect InternetCloseHandle hInternet submitPost = dataArray Exit Function End If 'リクエストを送信 Const strHeader = "Content-Type: application/x-www-form-urlencoded" HttpSendRequestA hRequest, strHeader, Len(strHeader), sendString, Len(sendString) 'データ取得 Dim readResult, tmpArray(1023) As Byte, tmpPosition, tmpSize dataPosition = 0 dataSize = 0 Do tmpSize = 0 Erase tmpArray readResult = InternetReadFile(hRequest, tmpArray(0), 1024, tmpSize) If Not readResult = 1 Or tmpSize = 0 Then Exit Do End If dataSize = dataSize + tmpSize ReDim Preserve dataArray(dataSize - 1) For tmpPosition = 0 To tmpSize - 1 Step 1 dataArray(dataPosition) = tmpArray(tmpPosition) dataPosition = dataPosition + 1 Next Loop 'クローズ処理 InternetCloseHandle hRequest InternetCloseHandle hConnect InternetCloseHandle hInternet submitPost = dataArray End Function Public Function downloadFilePost(ByRef targetURL, ByVal sendArray, ByRef savePath) As Boolean 'URLの分解 Dim startE, endE, host, url_path startE = InStr(1, targetURL, "//") + 2 endE = InStr(startE, targetURL, "/") endE = IIf(startE > endE, Len(targetURL) + 1, endE) host = Mid(targetURL, startE, endE - startE) url_path = Mid(targetURL, endE) 'ポストデータのエンコード Dim jscript With CreateObject("ScriptControl") .Language = "JScript" Set jscript = .CodeObject End With Dim ix, sendBuffer For ix = 0 To UBound(sendArray) Step 1 sendBuffer = Split(sendArray(ix), "=") sendArray(ix) = sendBuffer(0) &amp; "=" &amp; jscript.encodeURIComponent(sendBuffer(1)) Next Set jscript = Nothing Dim data data = submitPost(host, url_path, Join(sendArray, "&amp;")) If LenB(data) <= 0 Then downloadFilePost = False Exit Function End If 'バイナリで書き込み With CreateObject("ADODB.Stream") .Type = 1 .Open .Write data .SaveToFile savePath, 2 .Close End With downloadFilePost = True End Function
... | 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じゃなくて\(バックスラッシュ)で、:: じゃなくて→にしたかったんだけど、シェルが置き換えちゃうからしかたない
シェルの改造は禁断の手段だし
via http://b.hatena.ne.jp/torin/20110614#bookmark-46762850
// ==UserScript== // ==/UserScript== (function(){ if (null != window.frameElement) return false; if (! location.pathname.match(/^\/li\//)) return false; window.addEventListener('DOMContentLoaded', function() { var curator = document.querySelector('div.balloon_box.info_prof div.balloon_img.tltip').getAttribute('title').toLowerCase(); var tweeters = document.querySelectorAll('div.tweet_box div.status div.status_right a.status_name'); var len = tweeters.length; var tweeter = ''; for (var i = 0; i < len; i++) { if(curator != tweeters.item(i).textContent.toLowerCase()) { break; } } if (i >= len) { var data = 'data:image/png;base64,'+ 'iVBORw0KGgoAAAANSUhEUgAAAKQAAAA9CAYAAAAj3MLKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAC'+ 'vUlEQVR4nO2YS27DMAxEffNerOteq0UDFEgXkinxMyN6FrOKYT0On5Ki18fX56UoLIEDKMp7Yl92'+ 'Xd9/SYWenFPFoCTtNuxFbyJkCjE7p4pByUuJKKHAErJ1UkXJEEJC9k66LNFSSMjeiX9hspTMQuoi'+ 'BHSYvZjoJbEKib4MXVK6oIglScjeKV+Sd1ESsncgi/IsS0L2DmxZuwuTkL1Td1CQlBKyd2oPC5BS'+ 'QvZO/YFOKauFHPF6g148azCHOpZUKWSWjBKTTEiPlN2ElJQkQu5KKSF7Bw/glHLlM0nJn9LS0am+'+ 'WFEX8El5jIzZi185y/Iseh4JKSHdu0DLJCGJFmY97+QZS4SsKIkhBTebQsjTxYQDrCwNzeUVstsl'+ 'fIyQJ0oZJWRUT+x9DedBA+yUjeayslbJ00lKOMBu2WguC2e1NKd0NZ0BDdClaI+QT+tqyo8G6FL0'+ 'jK3655S5p1t2NIC3aJayd4R8Yk+37GiALmWPmFC8jB2ZuNEAUWWjC5/9LCM4I8/OmGF4gdFyMRSe'+ 'yYNkjDg7Y45pP2ixMiRgYkGySUgiEVg42Jgi50rpCi1UpgwMDGzf2pFzpXS1W/ApYRASIWMrIdES'+ 'dRISJWOUkJHvsbyzrYgS8sz/RbYW8skyHi8kWp5uMjIsn5HJLSQakD0SMph5Vioajj0s39JWNnRf'+ 'Ju6T4dkWztQhG4+Z+2R4pmUzdcjGs8Q+GgANxhwJmcg+GgANxhqrjKgOmVi2+EdDoMEYsyIjokMW'+ 'DtcMo0HQYGy5Ew/dIdPFcM3BUOYJYRayi4yvWWYDoeFYYlk4qr9OMr7muRsMDQgtZ+FvRDYh0d1t'+ 'z2Mtv0syZEQJ2U3Gf0JKSruQ1ucRMkrIA+NZ+MrzktEp5FPE3F165POScUHIzlLuLj/j+Ugh0SKl'+ 'C6lwprOMr/nQAMrG0prK+JsfF3m2CCi6mVcAAAAASUVORK5CYII='; var div = document.createElement('div'); var img = document.createElement('img'); img.setAttribute('class', 'za-wa'); img.src = data; function remimg() { var rem = document.querySelector('img.za-wa'); if(rem) { window.setInterval(function() { rem.style.opacity -= 0.05; if (rem.style.opacity == 0) { document.body.removeChild(rem); return; } }, 100); } } function addimg() { var c_img = img.cloneNode(false); c_img.style.position = 'fixed'; c_img.style.top = Math.floor(Math.random() * 100) + '%'; var leftp = Math.floor(Math.random() * 100); if(leftp < 50) { leftp = Math.floor(leftp / 4); } else { leftp = 100 - Math.floor(leftp / 4); } leftp += '%'; var ratio = (120 - Math.floor(Math.random() * 70)); c_img.style.left = leftp; c_img.style.zIndex = -1; c_img.style.opacity = 1; c_img.style.width = (Math.floor(164 * ratio / 100)) + 'px'; c_img.style.height = (Math.floor(61 * ratio / 100)) + 'px'; document.body.appendChild(c_img); var r = Math.floor(Math.random() * 1000) + 1000; window.setTimeout(addimg, r); window.setTimeout(remimg, 2500); } addimg(); } }, false); })();
初音ミクのfacebookページがあるというのを海外のニュースで読んだので、どんなもんかと思って検索してみた。
そしたら、出てくる出てくる。「結果をもっとみる」を果てしなくクリックした結果、最終的にざっと600人ぐらいも出てきた。わけわかんねぇ。
Hatsune Miku 約600人
Kagamine Rin 約660人
Kagamine Lin 7人ぐらい
Kagamine Ren 約70人
Kagamine Len 約560人
Megurine Luka 約500人
MeikoやKaitoは、これを含む名前が全部出てきてしまって分離が面倒なので断念。
Kaai Yuki 15人ぐらい
Hiyama Kiyoteru 15人ぐらい
Nekomura iroha 12人ぐらい
kasane teto 180人位
Akita neru 170人ぐらい
Yowane haku 90人ぐらい
セキュリティ目的ではない。ハッシュテーブルで使うような奴でキャッシュで使いたい。
手軽なほうが良い。軽いほうが良い。推測可能でよい。数十バイトくらいの文字列にしたい。
md5が一番汎用っぽいけど、無駄に重い気がする。crc32は軽そうだしそれなりに汎用っぽいけど、ハッシュ長が短いのがめんどい。
調べた→ http://anond.hatelabo.jp/20090327015620
ベンチ用スクリプト
#!/usr/local/bin/python from sys import argv, stderr from time import time from string import ascii_letters, join from random import choice from hashlib import md5 from binascii import crc32 from itertools import izip time_fmt = '%10s: %5d ms' shift = int(argv[1]) if len(argv)>1 and argv[1].isdigit() else 2 length = 0x100 << shift cycle = 0x10000 >> shift print >> stderr, 'string length: 0x%x, cycle: 0x%x' % (length, cycle) data = tuple(''.join(choice(ascii_letters) for i in xrange(length)) for j in xrange(cycle)) start = time() md5hex = tuple(md5(s).hexdigest() for s in data) print >> stderr, time_fmt % ('md5hex', (time() - start) * 1000) start = time() crc32x4 = tuple(''.join('%08x' % abs(crc32(s[i::4])) for i in (0, 1, 2, 3)) for s in data) print >> stderr, time_fmt % ('crc32x4', (time() - start) * 1000) start = time() startend = tuple(s[:16]+s[-16:] for s in data) print >> stderr, time_fmt % ('headtail', (time() - start) * 1000) start = time() skip = tuple(s[::(len(s)/32+1)] for s in data) print >> stderr, time_fmt % ('skipover', (time() - start) * 1000) for s in izip(data, md5hex, crc32x4, startend, skip): print join(s)
実行結果
% python hashbench.py 0 > hash0.txt string length: 0x100, cycle: 0x10000 md5hex: 199 ms crc32x4: 1081 ms headtail: 30 ms skipover: 41 ms % python hashbench.py 2 > hash1.txt string length: 0x400, cycle: 0x4000 md5hex: 83 ms crc32x4: 363 ms headtail: 10 ms skipover: 20 ms % python hashbench.py 4 > hash2.txt string length: 0x1000, cycle: 0x1000 md5hex: 52 ms crc32x4: 170 ms headtail: 2 ms skipover: 5 ms
http://anond.hatelabo.jp/20090211162032
を頑張って実践中なのだけどどうも
”だれをフォローするか”
で詰まってしまうので、ある程度機械的に増やす方法を考えた。対象は5人くらいまではFollowしてもらえたけどそっから先どうすれば良いか分からない人
# フォローを返してもらえなかったらremove for f in user.followings: if not f.following(user): user.remove(f) # Following / Follower比を保っている間 while len(user.followers) * 1.5 < len(user.followings): # Followersから2人選ぶ for i in range(user.followers): for j in range(i + 1, len(user.followers)): # 共通のユーザーを選ぶ shared_users = shared(user.followers[i], user.followers[j]) for su in shared_users: # まだフォローしておらず if user.following(su): continue # フォローを返してくれそうで if len(su.followers) > len(su.followings): continue # botでなさそうなら if len(su.followings) > len(su.followers) * 1.5: continue # フォローする user.follow(su)
これを3日に一回くらい定期的に実行すれば徐々に面白くなっていく。はず。
共通のユーザーを探すのは
とか
// ==UserScript== // @name anond // @namespace http://anond.hatelabo.jp/ // @include http://anond.hatelabo.jp/?page=* // ==/UserScript== function anond(doc) { $X(".//div[@class='section'][.//h3/a[2][starts-with(@href, 'http://anond.hatelabo.jp')]]", doc, Array).forEach(function(node){ node.style.display = "none"; }); $X(".//h3/a[1]", doc, Array).forEach(function(node){ var a = document.createElement("a"); a.name = node.pathname; a.href = "#" + node.pathname + "/footer"; a.innerHTML = "V"; node.parentNode.insertBefore(a, node); }); $X(".//p[@class = 'sectionfooter']/a[1]", doc, Array).forEach(function(node){ var a = document.createElement("a"); a.name = node.pathname + "/footer"; a.href = "#" + node.pathname; a.innerHTML = "^"; node.parentNode.insertBefore(a, node); node.parentNode.insertBefore(document.createTextNode(" | "), node); }); } anond(document); if (AutoPagerize.addDocumentFilter) AutoPagerize.addDocumentFilter(anond); // by http://lowreal.net/blog/2007/11/17/1 // $X(exp); // $X(exp, context); // $X(exp, type); // $X(exp, context, type); function $X (exp, context, type /* want type */) { if (typeof context == "function") { type = context; context = null; } if (!context) context = document; var exp = (context.ownerDocument || context).createExpression(exp, function (prefix) { var o = document.createNSResolver(context).lookupNamespaceURI(prefix); if (o) return o; return (document.contentType == "application/xhtml+xml") ? "http://www.w3.org/1999/xhtml" : ""; }); switch (type) { case String: return exp.evaluate( context, XPathResult.STRING_TYPE, null ).stringValue; case Number: return exp.evaluate( context, XPathResult.NUMBER_TYPE, null ).numberValue; case Boolean: return exp.evaluate( context, XPathResult.BOOLEAN_TYPE, null ).booleanValue; case Array: var result = exp.evaluate( context, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); var ret = []; for (var i = 0, len = result.snapshotLength; i < len; i++) { ret.push(result.snapshotItem(i)); } return ret; case undefined: var result = exp.evaluate(context, XPathResult.ANY_TYPE, null); switch (result.resultType) { case XPathResult.STRING_TYPE : return result.stringValue; case XPathResult.NUMBER_TYPE : return result.numberValue; case XPathResult.BOOLEAN_TYPE: return result.booleanValue; case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: { // not ensure the order. var ret = []; var i = null; while (i = result.iterateNext()) { ret.push(i); } return ret; } } return null; default: throw(TypeError("$X: specified type is not valid type.")); } }
修正:いい加減&が変換されるのを何とかしてほしい
解説:Hatena::Bookmark::24H(http://hatebu24h.ashitano.in/)に、トップエントリの獲得したブックマーク数の推移のチャートを加えます。
// ==UserScript== // @name chart of Hatena::Bookmark::24H // @namespace http://anond.hatelabo.jp/ // @include http://hatebu24h.ashitano.in/* // ==/UserScript== var url = unescape("http://chart.apis.google.com/chart?chs=160x60%26cht=ls%26chd=t:"); url = url + $X("//div[@class='clocktxt']", Array).map(function(s){return s.firstChild.nodeValue}).join(","); //var id = $X("//h3/a/@href")[0].nodeValue; //url = url + $X("//div[@class='entrytitle' or @class='entrytitle2'][.//a[@href='"+id+"']]/../preceding-sibling::div[1]", Array).map(function(s){return s.textContent.match(/\d+/)}).join(","); var before = makeElements({ nodeName: "div", className: "sidebox", childNodes: [{ nodeName: "div", className: "sidetitle", innerHTML: "Recent top entry chart" },{ nodeName: "div", className: "sidetitle", childNodes: { nodeName: "img", src: url } }] }); var after = $X("//div[@class='sidebox']", Array)[0]; after.parentNode.insertBefore(before, after); // util // var 0.01 function makeElements(obj) { if (typeof obj != "object") return document.createTextNode(obj); if (obj instanceof Array) return obj.map(makeElements); var node = document.createElement(obj.nodeName); delete obj.nodeName; if (obj.childNodes) { [].concat(makeElements(obj.childNodes)).forEach(node.appendChild, node); delete obj.childNodes; } function extend(dst, src) { for (var i in src) { if (typeof src[i] == "object" && dst[i] && typeof dst[i] == "object") extend(dst[i], src[i]); else node[i]=obj[i]; } } extend(node, obj); return node; } // by http://lowreal.net/blog/2007/11/17/1 // $X(exp); // $X(exp, context); // $X(exp, type); // $X(exp, context, type); function $X (exp, context, type /* want type */) { if (typeof context == "function") { type = context; context = null; } if (!context) context = document; var exp = (context.ownerDocument || context).createExpression(exp, function (prefix) { var o = document.createNSResolver(context).lookupNamespaceURI(prefix); if (o) return o; return (document.contentType == "application/xhtml+xml") ? "http://www.w3.org/1999/xhtml" : ""; }); switch (type) { case String: return exp.evaluate( context, XPathResult.STRING_TYPE, null ).stringValue; case Number: return exp.evaluate( context, XPathResult.NUMBER_TYPE, null ).numberValue; case Boolean: return exp.evaluate( context, XPathResult.BOOLEAN_TYPE, null ).booleanValue; case Array: var result = exp.evaluate( context, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); var ret = []; for (var i = 0, len = result.snapshotLength; i < len; i++) { ret.push(result.snapshotItem(i)); } return ret; case undefined: var result = exp.evaluate(context, XPathResult.ANY_TYPE, null); switch (result.resultType) { case XPathResult.STRING_TYPE : return result.stringValue; case XPathResult.NUMBER_TYPE : return result.numberValue; case XPathResult.BOOLEAN_TYPE: return result.booleanValue; case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: { // not ensure the order. var ret = []; var i = null; while (i = result.iterateNext()) { ret.push(i); } return ret; } } return null; default: throw(TypeError("$X: specified type is not valid type.")); } }