Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Chris Angelico Newsgroups: comp.lang.python Subject: Re: Brief Code Review Please - Learning Python Date: Mon, 7 Dec 2015 04:49:15 +1100 Lines: 48 Message-ID: References: <8fce9c71-a7bf-43fa-b8cc-f23c268e2b05@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: news.uni-berlin.de psOuMG41quUqjyiHynzRAwhRX26uURvcc46wGnrXbsbA== 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; 'subject:Python': 0.05; 'failing': 0.05; "'')": 0.07; '(b)': 0.07; 'false,': 0.07; 'false.': 0.07; 'type,': 0.07; 'width': 0.07; 'cc:addr:python-list': 0.09; 'confuse': 0.09; 'implies': 0.09; 'none.': 0.09; 'sane': 0.09; 'tuple': 0.09; 'python': 0.10; 'def': 0.13; 'expect,': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'subject:Learning': 0.16; 'unnecessary.': 0.16; 'wrote:': 0.16; 'string': 0.17; '2015': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; '(a)': 0.22; 'function,': 0.22; 'names.': 0.22; 'subject:Code': 0.22; 'am,': 0.23; '(or': 0.23; 'dec': 0.23; 'header:In-Reply-To:1': 0.24; 'mon,': 0.24; 'error': 0.27; 'checking': 0.27; 'message-id:@mail.gmail.com': 0.27; 'converting': 0.27; 'specify': 0.27; 'function': 0.28; 'this.': 0.28; 'skip:( 20': 0.28; 'regular': 0.29; 'measure': 0.29; 'multiline': 0.29; 'preceding': 0.29; 'time;': 0.29; 'unlikely': 0.29; 'raise': 0.29; 'creating': 0.30; 'code': 0.30; 'convention': 0.30; 'expensive': 0.32; 'instead,': 0.33; 'quotes': 0.33; 'true.': 0.33; 'equal': 0.34; 'received:google.com': 0.35; 'returning': 0.35; 'quite': 0.35; 'but': 0.36; 'should': 0.36; 'there': 0.36; 'received:209.85': 0.36; 'subject:: ': 0.37; 'two': 0.37; 'received:209.85.213': 0.37; 'received:209': 0.38; 'mean': 0.38; 'test': 0.39; 'sure': 0.39; 'body': 0.61; 'entire': 0.61; 'here.': 0.62; 'more': 0.63; 'here': 0.66; 'talking': 0.67; 'worth': 0.67; 'family': 0.68; 'brand': 0.75; 'counts': 0.81; "'true'": 0.84; 'chrisa': 0.84; 'generally)': 0.84; 'to:none': 0.91; 'joel': 0.91; 'widespread': 0.91; 'imagine': 0.96 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=4/yuOnDhRV7NaKb/s9dTooXccRqmkoglBapm4h3boIY=; b=pQdfHHdtXyAY0Yc/nr3gPP3YIdNbhhQJhPpMLy+Mzwu8b7hEIxdXkdPVekJHkfM/7W CGoIL2/bayG9fxFQ6S0fEXs+0yMKLr8ohlzJIMBqhxek156QlFmGfXCpUjowrPEnUB3g gYjDOrWJMLBjTB0LaWBl/PRLPFZ/wjKcZXyYupm1hP+TIdhDA5GzFMUz2YQR/mbjkuAy +PdrWjiUH/ibO0z2oJU5v9aup3fm5M879F1+32rtxv7BfXY8IBTfmv8g0gCFD7igrMQs mn4y0yhWuExI8cYeMsmKUG09yZiESAdLwlk6RV52tECNbZx1lKZIqDHk8zEa/JQC4a9J 9Mbw== X-Received: by 10.50.44.110 with SMTP id d14mr13578580igm.92.1449424155400; Sun, 06 Dec 2015 09:49:15 -0800 (PST) In-Reply-To: X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:100059 On Mon, Dec 7, 2015 at 4:34 AM, Joel Goldstick wrote: >> 5 if (desired_text != '') and \ >> 6 (desired_font_family != '') and \ >> 7 (desired_font_size != '') and \ >> 8 ((is_multi_lines == "True") or (is_multi_lines == "False")): >> > > The above test will always be True. Look up what is considered True in > Python, and what is False. I imagine you don't want quotes around True and > False. Any string will == True Not sure what you mean by this. If you're talking about boolification, then an empty string counts as false, but that's not what's happening here. It's checking that the string be equal to one of two other strings - and Python behaves exactly the way any sane person would expect, and this condition is true only if the string is exactly equal to either "True" or "False". But I think this line of code should be unnecessary. It's guarding the entire body of the function in a way that implies that failing this condition is an error - but if there is such an error, the function quietly returns None. Instead, I would go for a "fail-and-bail" model: def measure_string(text, font_family, font_size, multiline): if not text: raise ValueError("Cannot measure empty string") if not font_family: raise ValueError("No font family specified") if multiline not in ("True", "False"): raise ValueError("Must specify 'True' or 'False' for multiline flag") ... body of function here ... (Incidentally, it's quite un-Pythonic to use "True" and "False" as parameters; if the function you're calling requires this, it might be worth papering over that by having *your* function take the bools True and False, and converting to the strings on the inside.) > 16 WidthAndHeight = namedtuple("WidthAndHeight", "Width Height") You're creating a brand new namedtuple type every time you enter this function. That's expensive and messy. I would recommend either (a) constructing one "Dimension" type, outside the function, and using that every time; or (b) returning a regular tuple of width,height without the names. The convention of width preceding height (or x preceding y, more generally) is sufficiently widespread that it's unlikely to confuse people. ChrisA