Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'python,': 0.02; 'essentially': 0.04; 'anyway.': 0.05; 'argument': 0.05; 'classes,': 0.05; 'that?': 0.05; 'args': 0.07; 'error:': 0.07; 'explicit': 0.07; 'pypy': 0.07; 'arguments': 0.09; 'etc).': 0.09; 'expected.': 0.09; 'inherited': 0.09; 'occurrences': 0.09; 'percentage': 0.09; 'subset': 0.09; 'sure,': 0.09; 'url:github': 0.09; 'python': 0.11; 'missed': 0.12; '3.3,': 0.16; 'attempted': 0.16; 'cool.': 0.16; 'curious.': 0.16; 'ensured': 0.16; 'exercise:': 0.16; 'ops': 0.16; 'optional': 0.16; 'optional.': 0.16; 'semantics': 0.16; 'stats': 0.16; 'stumbled': 0.16; 'wouldn\x92t': 0.16; '(not': 0.18; 'discussion': 0.18; 'library': 0.18; 'bit': 0.19; 'module': 0.19; 'trying': 0.19; 'basically': 0.19; 'split': 0.19; 'load': 0.23; 'error': 0.23; '(such': 0.24; 'directory.': 0.24; 'instead.': 0.24; 'module,': 0.24; 'parse': 0.24; 'nearly': 0.26; 'asking': 0.27; 'tried': 0.27; 'function': 0.29; 'leave': 0.29; 'scanned': 0.29; 'nature': 0.30; 'especially': 0.30; 'code': 0.31; 'getting': 0.31; 'that.': 0.31; 'awards': 0.31; 'extract': 0.31; 'implicit': 0.31; 'inspect': 0.31; 'libraries': 0.31; 'reflected': 0.31; 'table,': 0.31; 'though.': 0.31; 'anyone': 0.31; 'probably': 0.32; 'entirely': 0.33; 'not.': 0.33; 'table': 0.34; 'core': 0.34; 'maybe': 0.34; 'could': 0.34; 'subject:with': 0.35; 'tool': 0.35; 'objects': 0.35; 'one,': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'fun,': 0.36; 'doing': 0.36; 'method': 0.36; 'possible': 0.36; 'half': 0.37; 'wrong': 0.37; 'message- id:@gmail.com': 0.38; 'branch': 0.38; 'writes': 0.38; 'to:addr :python-list': 0.38; 'little': 0.38; 'recent': 0.39; 'ability': 0.39; 'bad': 0.39; 'environment.': 0.39; 'flow': 0.39; 'sure': 0.39; 'to:addr:python.org': 0.39; 'enough': 0.39; 'how': 0.40; 'easy': 0.60; 'problems.': 0.60; 'most': 0.60; 'black': 0.61; 'introduced': 0.61; 'first': 0.61; 'here:': 0.62; 'header:Message- Id:1': 0.63; 'kind': 0.63; 'more': 0.64; 'love': 0.65; 'finally': 0.65; 'charset:windows-1252': 0.65; 'results': 0.69; 'default': 0.69; 'led': 0.72; 'obvious': 0.74; 'haven\x92t': 0.84; 'isolate': 0.84; 'it\x92s': 0.84; 'i\x92ve': 0.84; 'resulted': 0.84; 'routines': 0.84; 'short,': 0.84; 'can\x92t': 0.91; 'thing,': 0.91; 'opt': 0.97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:content-type:content-transfer-encoding:subject:message-id:date :to:mime-version; bh=5PJwWJSd1XeLPhL6S1W9iyQhsJCN/Y2AESTsqc2FnYM=; b=FZKtI+ALXRJxqvdD2t3j3YddfOU49SX1CjppzeRL5TUy8FZvhHh5MZstFReSWTvc8w 2D9ol+1BviDy5luryStGbH8vFu2113n2hoKEgFRk2mKlmJZF0TQ9NNDeQlAQNn0X1Qqs OrekcZ5VNP8YI2dPsEnRwkHcRxwTRlolH6ntXqDSDL1Pn/TpCzYphD9s8O8Z+2LB+dua LmckOlZbxaRXhlsZYcp32l4jOk2IY38PozUyTLKW3aGT31sexMewhAVsicdmNccQSU0+ xRfWWe0s/4qRlD9FO5ftihf+ib+O2Hr20d7+sjb/OQIdtvM2un4fGlODBbHC6IeWNqkI hsIw== X-Received: by 10.66.250.202 with SMTP id ze10mr13994617pac.153.1392165246982; Tue, 11 Feb 2014 16:34:06 -0800 (PST) From: Travis Griggs Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Subject: Fun with function argument counts Date: Tue, 11 Feb 2014 16:34:03 -0800 To: python-list@python.org Mime-Version: 1.0 (Mac OS X Mail 7.1 \(1827\)) X-Mailer: Apple Mail (2.1827) X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 85 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1392165250 news.xs4all.nl 2885 [2001:888:2000:d::a6]:45708 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:65967 After the recent discussion about the classic error: if self.isFooBar: return 42 Among many thing, the OPs contention was that the ability to have this = kind of error was a Bad Thing (tm). Which led to me asking about code = smells and parameterless functions/methods. So I got curious. Semantics of implicit objects aside, how often is it = possible to write code like that. In short, how frequent are = methods/functions that have zero explicit args (not implicit, because = while fun, that=92s not how we code them). It was a fun experiment, I=92ve= been doing python for a little over a year now, and I thought it would = be enjoyable/educational to do a bit of metaprogramming. First the = results though. Below is a histogram of function argument count: argCount x occurrences (% of total) -1 x 10426 ( 3.2%) # these are where I stuffed all of the routines I = couldn=92t extract the argspecs for 0 x 160763 (48.7%) 1 x 109028 (33.0%) 2 x 40473 (12.3%) 3 x 7059 ( 2.1%) 4 x 2383 ( 0.7%) 5 x 141 ( 0.0%) 6 x 46 ( 0.0%) 7 x 12 ( 0.0%) 10 x 1 ( 0.0%) 16 x 1 ( 0.0%) 19 x 2 ( 0.0%) Nearly half of the functions/methods I scanned were zero args (48.7). = Which was more than I expected. I haven=92t dug enough to see if there=92s= a flock of canaries in there or not. The code to produce that table is = here: https://gist.github.com/anonymous/8947229. Yes, it=92s hacky. = Wasn=92t trying to win any style/idiom awards with this one. To get this table, I used PyPy 3-2.1 beta for OSX. I basically attempted = to parse all of the modules found in it=92s lib-python directory. A = subset of the modules wouldn=92t load, I=92m not sure whether to write = that off as the work-in-progress nature of pypy or what. And I black = listed some of them (such as idlelib.idle, ctypes.test.*, etc). But from = the counts, I was able to get a pretty large corpus of them. I learned a number of fun things as part of the exercise: 1) I did not want to try load all modules at once into my environment. I = suspect that would create problems. Using os.fork() to isolate the = load/analysis of each module was a handy way to deal with that. The = trick of using if pid: branch to split of the flow of execution was = cool. Maybe it=92s the wrong tool for the job and I missed an obvious = one, but I thought it was kinda clever. 2) Using cpython, a lot of the core library can=92t be reflected on. I = tried to use the inspect module, and found that things like = inspect.getmembers(datetime.datetime, inspect.ismethod) resulted in a = big surprise. Especially if you leave off the predicate, and see that = there are a lot of things in there that claim they ARE methods). I = finally stumbled into inspect.isroutine, but found that most of the = results couldn=92t be reified using inspect.signature anyway. The =93it=92= s all python, all the way down, well mostly=94 ideology of pypy ensured = that a higher percentage opt the base libraries could be analyzed. 3) It=92s easy to take 3.3.x for granted. I found right away that = signature was introduced in 3.3, so I had to use = inspect.getfullargspec() instead. 4) optional arguments were an interesting dillema. I chose to reduce the = argument count of a signature by the number of default arguments. Since = they are essentially optional. So the stats there have a bias to the = =93minimal=94 call signature. 5) my method of scanning loadable modules is probably very naive/brute = force/stupid. I would love it if there was a better way to do that. 6) Who writes a function with 19 mandatory arguments anyway???? = subprocess._execute_child() and = distutils.cygwincompiler._execute_child() 7) I=92m not entirely sure, given #6, that I=92m not seeing inherited = methods for all classes, so getting an overinflated count from them. Can = anyone answer that?=