Asyncio project code review
Good day for everyone. I have new asyncio project which use aiohttp connector and asyncio protocols/transports for tunneling packets through Tor Network cleanly. Project called aiotor: https://github.com/torpyorg/aiotor If someone with experience in asyncio field can make code review I will be appreciated for any comments. I prepared pull request to make it convenient to review and comment on the code: https://github.com/torpyorg/aiotor/pull/1 Thanks in advance. -- https://mail.python.org/mailman/listinfo/python-list
asyncio project code review
Good day everyone. I have new asyncio project which use aiohttp connector and asyncio protocols/transports for tunneling packets through Tor Network cleanly. Project called aiotor: https://github.com/torpyorg/aiotor If someone with experience in asyncio field can make code review I will be appreciated for any comments. I prepared pull request to make it convenient to review and comment on the code: https://github.com/torpyorg/aiotor/pull/1 -- https://mail.python.org/mailman/listinfo/python-list
Re: Flask test generator code review?
2018-04-18 12:41 GMT+02:00 Albert-Jan Roskam: > Hi, > > I am writing my first unittests for a Flask app. First modest goal is to > test whether a selected subset of the templates return the expected status > 200. > I am using a nose test generator in a class for this. Is the code below > the correct way to do this? And is there a way to dynamically set the > docstring of test_generator? This would make the nosetests output a bit > more understandable. > > Thanks! > Albert-Jan > > import os > import sys > from os.path import splitext > from http import HTTPStatus as status > > import nose > > from MyFabulousApp import app > > app.testing = True > template_folder = app.config['TEMPLATE_FOLDER'] > > > class Test_MyFabulousApp_HTTP_Status_OK: > > def __init__(self): > self.setup() # with unittest, setUp is called automatically, but > not with nose > > def setup(self): > self.client = app.test_client() > self.client.post('/login', follow_redirects=True) > > def teardown(self): > self.client.post('/logout', follow_redirects=True) > > def test_generator(self): > """Does template return HTTP Status 200?""" > def the_test(self, template): > # the following line throws an error: AttributeError: > attribute '__doc__' of 'method' objects is not writable > #self.test_generator.__doc__ = 'Does template "%s" return HTTP > Status 200?' % template > respons = self.client.get('/' + template) > actual = respons.status_code > desired = status.OK.value > assert actual == desired, \ >'Template "%s" returns status code %d' % (template, actual) > templates = [splitext(item)[0] for item in > os.listdir(template_folder)] > for template in templates: > yield the_test, self, template > > > if __name__ == '__main__': > nose.run(defaultTest=__name__, argv=[sys.argv[0], '__main__', > '--verbosity=2']) > -- > https://mail.python.org/mailman/listinfo/python-list > Hi, maybe you should check PyTest https://docs.pytest.org/en/latest/ and Flas testing turorial: http://flask.pocoo.org/docs/1.0/testing/ BR, George -- https://mail.python.org/mailman/listinfo/python-list
Flask test generator code review?
Hi, I am writing my first unittests for a Flask app. First modest goal is to test whether a selected subset of the templates return the expected status 200. I am using a nose test generator in a class for this. Is the code below the correct way to do this? And is there a way to dynamically set the docstring of test_generator? This would make the nosetests output a bit more understandable. Thanks! Albert-Jan import os import sys from os.path import splitext from http import HTTPStatus as status import nose from MyFabulousApp import app app.testing = True template_folder = app.config['TEMPLATE_FOLDER'] class Test_MyFabulousApp_HTTP_Status_OK: def __init__(self): self.setup() # with unittest, setUp is called automatically, but not with nose def setup(self): self.client = app.test_client() self.client.post('/login', follow_redirects=True) def teardown(self): self.client.post('/logout', follow_redirects=True) def test_generator(self): """Does template return HTTP Status 200?""" def the_test(self, template): # the following line throws an error: AttributeError: attribute '__doc__' of 'method' objects is not writable #self.test_generator.__doc__ = 'Does template "%s" return HTTP Status 200?' % template respons = self.client.get('/' + template) actual = respons.status_code desired = status.OK.value assert actual == desired, \ 'Template "%s" returns status code %d' % (template, actual) templates = [splitext(item)[0] for item in os.listdir(template_folder)] for template in templates: yield the_test, self, template if __name__ == '__main__': nose.run(defaultTest=__name__, argv=[sys.argv[0], '__main__', '--verbosity=2']) -- https://mail.python.org/mailman/listinfo/python-list
Re: Brief Code Review Please - Learning Python
Joel Goldstick wrote: > On Sun, Dec 6, 2015 at 12:21 PM, <qualityaddict...@gmail.com> wrote: >> * Same question as right above but with the if tests on lines 5-8. >> * I've also used ( ) around the if tests, but I'm not sure if this is >> good Python style or not. >> >> 1 def measure_string(desired_text, >> 2 desired_font_family, >> 3 desired_font_size, >> 4 is_multi_lines): >> 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. How did you get that idea? > Look up what is considered True in Python, and what is False. ISTM that *you* should do that. > I imagine you don't want quotes around True and False. I imagine also that they do not want to write “== True” and “== False”. Because you can omit the former and should replace “x == False” with “not x”. This applies to many programming languages, even those that do type conversion (and have “!” instead of “not”). > Any string will == True No, Python does not do type conversion on comparison by default. $ python -c 'print("" == False)' False $ python -c 'print("True" == True)' False $ python -c 'print(True == True)' True (You have to define the __eq__() method of an object for that, and then you should also define at least __ne__().) >> 9 with Image(filename='wizard:') as temp_image: >> 10 with Drawing() as measure: >> 11 measure.font_family = desired_font_family >> 12 measure.font_size = desired_font_size >> 13 measures = measure.get_font_metrics(temp_image, >> 14 desired_text, >> 15 >> multiline=is_multi_lines) >> > > No need to set multiline = ... when is_multiline is already defined Watch for word wrap. He sets the argument for the “multiline” parameter in the measure.get_font_metrics() method call from the “is_multi_lines” parameter of the measure_string() call. Please trim your quotes to the relevant minimum. OP: Please do not post code line numbers or any other "decoration" if you want a code review. Especially with Python it is important that you post the code verbatim. -- PointedEars Twitter: @PointedEars2 Please do not cc me. / Bitte keine Kopien per E-Mail.$ -- https://mail.python.org/mailman/listinfo/python-list
Brief Code Review Please - Learning Python
[Note: Tried sending this twice to the Python-List mail list but I never saw it come through to the list.] Hello everyone, I am beginning to learn Python, and I've adapted some code from Google into the function below. I'm also looking at the PEP 8 style guide. I'd appreciate a brief code review so I can start this journey off on a solid foundation. :) * I've already changed my editor from tabs to 4 spaces. * I've also set my editor to alert me at 72 characters and don't exceed 79 characters. * I've named the function and variables with lower case, underscore separated, and meaningful words. * I've surrounded this function with two blank lines before and after. * I just recognized I need to pick a quote style and stick to it so I'll fix that (" " or ' '). * I'm not sure about the WidthAndHeight on lines 16 and 17 regarding capitalization. If I understand correctly a namedtuple is a class so the CapWords convention is correct. * Is how I've aligned the function arguments on lines 1-4 and 22-25 good style or \ is spreading these out onto fewer lines preferred? * Same question as right above but with the if tests on lines 5-8. * I've also used ( ) around the if tests, but I'm not sure if this is good Python style or not. 1 def measure_string(desired_text, 2 desired_font_family, 3 desired_font_size, 4 is_multi_lines): 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")): 9 with Image(filename='wizard:') as temp_image: 10 with Drawing() as measure: 11 measure.font_family = desired_font_family 12 measure.font_size = desired_font_size 13 measures = measure.get_font_metrics(temp_image, 14 desired_text, 15 multiline=is_multi_lines) 16 WidthAndHeight = namedtuple("WidthAndHeight", "Width Height") 17 width_and_height = WidthAndHeight(measures.text_width, \ 18measures.text_height) 19 return width_and_height 20 21 22 print(measure_string("some text\na new line", 23 "Segoe UI", 24 40, 25 "True")) Any and all feedback is much appreciated. As I said, I'm just beginning to learn Python and want to start off with a solid foundation. Thank you to everyone in advance for your time and thoughts. Jason -- https://mail.python.org/mailman/listinfo/python-list
Re: Brief Code Review Please - Learning Python
On Sun, Dec 6, 2015 at 12:21 PM, <qualityaddict...@gmail.com> wrote: > [Note: Tried sending this twice to the Python-List mail list but I never > saw it come through to the list.] > > Hello everyone, > > I am beginning to learn Python, and I've adapted some code from Google > into the function below. I'm also looking at the PEP 8 style guide. I'd > appreciate a brief code review so I can start this journey off on a solid > foundation. :) > > * I've already changed my editor from tabs to 4 spaces. > * I've also set my editor to alert me at 72 characters and don't > exceed 79 characters. > * I've named the function and variables with lower case, underscore > separated, and meaningful words. > * I've surrounded this function with two blank lines before and after. > * I just recognized I need to pick a quote style and stick to it so > I'll fix that (" " or ' '). > * I'm not sure about the WidthAndHeight on lines 16 and 17 regarding > capitalization. > You don't need the parens. If you feel it is easier to understand with them, they won't hurt > If I understand correctly a namedtuple is a class so the CapWords > convention is correct. > * Is how I've aligned the function arguments on lines 1-4 and 22-25 > good style or \ > is spreading these out onto fewer lines preferred? > If the parameters fit on one line, I think that is more common > * Same question as right above but with the if tests on lines 5-8. > * I've also used ( ) around the if tests, but I'm not sure if this is > good Python style or not. > > 1 def measure_string(desired_text, > 2 desired_font_family, > 3 desired_font_size, > 4 is_multi_lines): > 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 > 9 with Image(filename='wizard:') as temp_image: > 10 with Drawing() as measure: > 11 measure.font_family = desired_font_family > 12 measure.font_size = desired_font_size > 13 measures = measure.get_font_metrics(temp_image, > 14 desired_text, > 15 > multiline=is_multi_lines) > No need to set multiline = ... when is_multiline is already defined > 16 WidthAndHeight = namedtuple("WidthAndHeight", "Width Height") > 17 width_and_height = WidthAndHeight(measures.text_width, \ > 18measures.text_height) > 19 return width_and_height > 20 > 21 > 22 print(measure_string("some text\na new line", > 23 "Segoe UI", > 24 40, > 25 "True")) > > Any and all feedback is much appreciated. As I said, I'm just beginning > to learn Python and want to start off with a solid foundation. Thank you > to everyone in advance for your time and thoughts. > > Jason > -- > https://mail.python.org/mailman/listinfo/python-list > -- Joel Goldstick http://joelgoldstick.com/stats/birthdays -- https://mail.python.org/mailman/listinfo/python-list
Re: Brief Code Review Please - Learning Python
qualityaddict...@gmail.com wrote: > [Note: Tried sending this twice to the Python-List mail list but I never > [saw it come through to the list.] > > Hello everyone, > > I am beginning to learn Python, and I've adapted some code from Google > into the function below. I'm also looking at the PEP 8 style guide. > I'd appreciate a brief code review so I can start this journey off on > a solid foundation. :) > > * I've already changed my editor from tabs to 4 spaces. > * I've also set my editor to alert me at 72 characters and don't > exceed 79 characters. * I've named the function and variables with > lower case, underscore separated, and meaningful words. * I've > surrounded this function with two blank lines before and after. * I > just recognized I need to pick a quote style and stick to it so I'll > fix that (" " or ' '). * I'm not sure about the WidthAndHeight on > lines 16 and 17 regarding capitalization. > If I understand correctly a namedtuple is a class so the CapWords > convention is correct. > * Is how I've aligned the function arguments on lines 1-4 and 22-25 > good style or \ > is spreading these out onto fewer lines preferred? > * Same question as right above but with the if tests on lines 5-8. > * I've also used ( ) around the if tests, but I'm not sure if this is > good Python style or not. > > 1 def measure_string(desired_text, > 2 desired_font_family, > 3 desired_font_size, > 4 is_multi_lines): > 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")): > 9 with Image(filename='wizard:') as temp_image: > 10 with Drawing() as measure: > 11 measure.font_family = desired_font_family > 12 measure.font_size = desired_font_size > 13 measures = measure.get_font_metrics(temp_image, > 14 desired_text, > 15 > multiline=is_multi_lines) > 16 WidthAndHeight = namedtuple("WidthAndHeight", "Width Height") > 17 width_and_height = WidthAndHeight(measures.text_width, \ > 18measures.text_height) > 19 return width_and_height > 20 > 21 > 22 print(measure_string("some text\na new line", > 23 "Segoe UI", > 24 40, > 25 "True")) > > Any and all feedback is much appreciated. As I said, I'm just beginning > to learn Python and want to start off with a solid foundation. Thank you > to everyone in advance for your time and thoughts. > > Jason Use short variable names - the "desired_" prefix does not carry much information. Avoid unrelated but similar names: measure or measures -- what's what? Use consistent names. This is a bit tricky, but I would prefer multiline over is_multi_lines because the underlying library uses the former. Use the right datatype: multiline should be boolean, i. e. True or False, not "True" or "False". Provide defaults if possible: if the multiline argument is missing you can scan the text for "\n" and set the flag accordingly Prefer parens for line continuations (a and b) over backslashes a and \ b Move code that only should be executed once from the function to the global namespace: the namedtuple definition should be on the module level. Use qualified names if you are referring library code: wand.drawing.Drawing instead of just Drawing. Avoid spurious checks, but if you do argument validation fail noisyly, i. e. "wrong": def f(fontname): if is_valid(fontname): return meaningful_result() # implicitly return None "correct": class InvalidFontname(Exception): pass def f(fontname): if not is_valid(fontname): raise InvalidFontname(fontname) return meaningful_result() With changes along these lines your code might become from collections import namedtuple import wand.drawing import wand.image Extent = namedtuple("Extent", "width height") def get_text_extent( text, font_family, font_size, multiline=None): """Determine width and heights for `text`. """ if multiline is None: multiline = "\n" in text with wand.image.Image(filename='wizard:') as image: with wand.drawing.Drawing() as measure:
Re: Brief Code Review Please - Learning Python
On Mon, Dec 7, 2015 at 4:34 AM, Joel Goldstickwrote: >> 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 -- https://mail.python.org/mailman/listinfo/python-list
Brief Code Review Please - Learning Python
Hello List Members, I am beginning to learn Python, and I've adapted some code from Google into the function below. I'm also looking at the PEP 8 style guide. I'd appreciate a brief code review so I can start this journey off on a solid foundation. :) * I've already changed my editor from tabs to 4 spaces. * I've also set my editor to alert me at 72 characters and don't exceed 79 characters. * I've named the function and variables with lower case, underscore separated, and meaningful words. * I've surrounded this function with two blank lines before and after. * I just recognized I need to pick a quote style and stick to it so I'll fix that (" " or ' '). * I'm not sure about the WidthAndHeight on lines 16 and 17 regarding capitalization. If I understand correctly a namedtuple is a class so the CapWords convention is correct. * Is how I've aligned the function arguments on lines 1-4 and 22-25 good style or \ is spreading these out onto fewer lines preferred? * Same question as right above but with the if tests on lines 5-8. * I've also used ( ) around the if tests, but I'm not sure if this is good Python style or not. 1 def measure_string(desired_text, 2 desired_font_family, 3 desired_font_size, 4 is_multi_lines): 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")): 9 with Image(filename='wizard:') as temp_image: 10 with Drawing() as measure: 11 measure.font_family = desired_font_family 12 measure.font_size = desired_font_size 13 measures = measure.get_font_metrics(temp_image, 14 desired_text, 15 multiline=is_multi_lines) 16 WidthAndHeight = namedtuple("WidthAndHeight", "Width Height") 17 width_and_height = WidthAndHeight(measures.text_width, \ 18measures.text_height) 19 return width_and_height 20 21 22 print(measure_string("some text\na new line", 23 "Segoe UI", 24 40, 25 "True")) Any and all feedback is much appreciated. As I said, I'm just beginning to learn Python and want to start off with a solid foundation. Thank you to everyone in advance for your time and thoughts. Jason -- https://mail.python.org/mailman/listinfo/python-list
Brief Code Review Please - Learning Python
Hello List Members, I am beginning to learn Python, and I've adapted some code from Google into the function below. I'm also looking at the PEP 8 style guide. I'd appreciate a brief code review so I can start this journey off on a solid foundation. :) * I've already changed my editor from tabs to 4 spaces. * I've also set my editor to alert me at 72 characters and don't exceed 79 characters. * I've named the function and variables with lower case, underscore separated, and meaningful words. * I've surrounded this function with two blank lines before and after. * I just recognized I need to pick a quote style and stick to it so I'll fix that (" " or ' '). * I'm not sure about the WidthAndHeight on lines 16 and 17 regarding capitalization. If I understand correctly a namedtuple is a class so the CapWords convention is correct. * Is how I've aligned the function arguments on lines 1-4 and 22-25 good style or \ is spreading these out onto fewer lines preferred? * Same question as right above but with the if tests on lines 5-8. * I've also used ( ) around the if tests, but I'm not sure if this is good Python style or not. 1 def measure_string(desired_text, 2 desired_font_family, 3 desired_font_size, 4 is_multi_lines): 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")): 9 with Image(filename='wizard:') as temp_image: 10 with Drawing() as measure: 11 measure.font_family = desired_font_family 12 measure.font_size = desired_font_size 13 measures = measure.get_font_metrics(temp_image, 14 desired_text, 15 multiline=is_multi_lines) 16 WidthAndHeight = namedtuple("WidthAndHeight", "Width Height") 17 width_and_height = WidthAndHeight(measures.text_width, \ 18measures.text_height) 19 return width_and_height 20 21 22 print(measure_string("some text\na new line", 23 "Segoe UI", 24 40, 25 "True")) Any and all feedback is much appreciated. As I said, I'm just beginning to learn Python and want to start off with a solid foundation. Thank you to everyone in advance for your time and thoughts. Jason -- https://mail.python.org/mailman/listinfo/python-list
Atomic file save -- code review and comments requested
Howdy, I have a utility function for performing atomic file saves, and I'd like to ask for a code review and comments. I have published this on ActiveState: https://code.activestate.com/recipes/579097-safely-and-atomically-write-to-a-file/ under an MIT licence. You should read the version there, I discuss the use-case for the function and include an extensive doc string. Feel free to comment either here or on the ActiveState site. Here is the function, minus the docstring (for brevity): import contextlib import os import stat import tempfile @contextlib.contextmanager def atomic_write(filename, text=True, keep=True, owner=None, group=None, perms=None, suffix='.bak', prefix='tmp'): t = (uid, gid, mod) = (owner, group, perms) if any(x is None for x in t): info = os.stat(filename) if uid is None: uid = info.st_uid if gid is None: gid = info.st_gid if mod is None: mod = stat.S_IMODE(info.st_mode) path = os.path.dirname(filename) fd, tmp = tempfile.mkstemp( suffix=suffix, prefix=prefix, dir=path, text=text) try: with os.fdopen(fd, 'w' if text else 'wb') as f: yield f os.rename(tmp, filename) tmp = None os.chown(filename, uid, gid) os.chmod(filename, mod) finally: if (tmp is not None) and (not keep): # Silently delete the temporary file. Ignore any errors. try: os.unlink(tmp) except: pass Usage is: with atomic_write("mydata.txt") as f: f.write("some data") # if an error occurs in here, mydata.txt is preserved # if no error occurs and the with-block exits cleanly, # mydata.txt is atomically overwritten with the new contents. The function is written for Python 2.6, but should work on 2.7 as well. I'm looking for a review of the code, and any general comments. In particular, have I missed any ways that the function may fail and lose data? One question comes to mind -- should I perform a flush and/or sync of the file before the rename? Thanks in advance for all constructive comments. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Atomic file save -- code review and comments requested
On Wed, 2 Sep 2015 19:06 Steven D'Aprano <st...@pearwood.info> wrote: Howdy, I have a utility function for performing atomic file saves, and I'd like to ask for a code review and comments. I have published this on ActiveState: https://code.activestate.com/recipes/579097-safely-and-atomically-write-to-a-file/ under an MIT licence. You should read the version there, I discuss the use-case for the function and include an extensive doc string. Feel free to comment either here or on the ActiveState site. Here is the function, minus the docstring (for brevity): import contextlib import os import stat import tempfile @contextlib.contextmanager def atomic_write(filename, text=True, keep=True, owner=None, group=None, perms=None, suffix='.bak', prefix='tmp'): t = (uid, gid, mod) = (owner, group, perms) if any(x is None for x in t): info = os.stat(filename) if uid is None: uid = info.st_uid if gid is None: gid = info.st_gid if mod is None: mod = stat.S_IMODE(info.st_mode) path = os.path.dirname(filename) fd, tmp = tempfile.mkstemp( suffix=suffix, prefix=prefix, dir=path, text=text) try: with os.fdopen(fd, 'w' if text else 'wb') as f: yield f os.rename(tmp, filename) tmp = None os.chown(filename, uid, gid) os.chmod(filename, mod) finally: if (tmp is not None) and (not keep): # Silently delete the temporary file. Ignore any errors. try: os.unlink(tmp) except: pass Usage is: with atomic_write("mydata.txt") as f: f.write("some data") # if an error occurs in here, mydata.txt is preserved # if no error occurs and the with-block exits cleanly, # mydata.txt is atomically overwritten with the new contents. The function is written for Python 2.6, but should work on 2.7 as well. I'm looking for a review of the code, and any general comments. In particular, have I missed any ways that the function may fail and lose data? One question comes to mind -- should I perform a flush and/or sync of the file before the rename? Your with statement will close the file so that shouldn't be necessary. Not an expert on these things but maybe it makes sense to call chown/chmod before the rename so that a failure can't result in the replaced file's permissions being changed. -- Oscar -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review
- Original Message - From: C Smith illusiontechniq...@gmail.com I read that with 2.7 that I had to initialize class variables to immutable types. I think because I was working with the lists before they had been altered and were still empty lists. I will mess around tomorrow with the classes you suggested as I have yet to make use of decorators. Thanks. The problem you referring too is probably the default value in *function definition*. Never write class Foo(object): def __init__(self, bar=[]): self.bar = bar The empty list is evaluated at the function definition and will be shared by all instances of the class. What you can do is class Foo(object): def __init__(self, bar=None): # None is immutable self.bar = bar or [] On a completely unrelated topic: I think you are using too much of default values for you arguments. I tend to use them only for keeping something backward compatible. Otherwise, use positional arguments, remember that explicit is better than implicit. Rememer your Table class: class Table(object): def __init__(self,bigblind=20,PLAYERNUM=0,pot=0,PLAYERORDER=None, hand_done=0, left_to_act=None,cost_to_play=0,in_hand=None,last_raise=0,cards_in_play=None,round='preflop'): You do not need to to pass all attribute initializers to your init method. For instance PLAYERNUM, which should be lowercase by the way, is clearly not intended to be set at the Table creation, it is something changed when filling seats. Actually, since you've created your table this way: table1=Table(bingblind=1) It probably means that your table __init__ method should look like: def __init__(self, bigblind): self.bigblind= bigblind self.hand_one = False self.left_to_act = [] # etc... By the way, avoid using directly 1 and 0 for coding booleans, use True and False (see hand_one attribute). JM -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. -- https://mail.python.org/mailman/listinfo/python-list
Code review
I was wondering if I could get some feedback on the biggest thing I have done as an amateur Python coder. The sidepots algorithm isn't correct yet, but I haven't worked on it in a while and thought I would get some advice before diving back in. import random, os ## class Table(object): def __init__(self,bigblind=20,PLAYERNUM=0,pot=0,PLAYERORDER=None, hand_done=0,\ left_to_act=None,cost_to_play=0,in_hand=None,last_raise=0,cards_in_play=None,round='preflop'): if cards_in_play is None: cards_in_play = [] if in_hand is None: in_hand = [] if PLAYERORDER is None: PLAYERORDER = [] if left_to_act is None: left_to_act = [] self.hand_done = hand_done self.round = round self.cards_in_play = cards_in_play self.last_raise = last_raise self.in_hand = in_hand self.cost_to_play = cost_to_play self.left_to_act = left_to_act self.PLAYERORDER = PLAYERORDER self.bigblind = bigblind self.PLAYERNUM = PLAYERNUM self.pot = pot ## def fillseats(self,listofplayers, playas): seating = [x for x in range(1,len(listofplayers)+1)] random.shuffle(seating) for y in listofplayers: playas[y].seatnumber = seating.pop() for x in listofplayers: newx = str(playas[x].seatnumber)+x self.PLAYERORDER.append(newx) self.PLAYERORDER = sorted(self.PLAYERORDER) neworder = [] for x in self.PLAYERORDER: neworder.append(x[1:]) self.PLAYERORDER = neworder self.PLAYERNUM = len(self.PLAYERORDER) ## def postblinds(self,playas,bigblind,deck): # establish player.start_stack for sidepots for player in self.PLAYERORDER: playas[player].start_stack = playas[player].stacksize # Heads up post blinds if len(self.PLAYERORDER) == 2: if bigblind = playas[self.PLAYERORDER[1]].stacksize: if bigblind == playas[self.PLAYERORDER[1]].stacksize: playas[self.PLAYERORDER[1]].stacksize = 0 self.pot += bigblind playas[self.PLAYERORDER[1]].all_in = 1 playas[self.PLAYERORDER[1]].in_front = bigblind playas[self.PLAYERORDER[1]].put_in_pot = bigblind else: self.pot += playas[self.PLAYERORDER[1]].stacksize playas[self.PLAYERORDER[1]].in_front = playas[self.PLAYERORDER[1]].stacksize playas[self.PLAYERORDER[1]].put_in_pot = playas[self.PLAYERORDER[1]].stacksize playas[self.PLAYERORDER[1]].stacksize = 0 playas[self.PLAYERORDER[1]].all_in = 1 if (bigblind/2) = playas[self.PLAYERORDER[0]].stacksize: if bigblind == playas[self.PLAYERORDER[0]].stacksize: playas[self.PLAYERORDER[0]].in_front = bigblind/2 playas[self.PLAYERORDER[0]].put_in_pot = bigblind/2 playas[self.PLAYERORDER[0]].stacksize = 0 self.pot += bigblind/2 playas[self.PLAYERORDER[0]].all_in = 1 else: playas[self.PLAYERORDER[0]].put_in_pot = playas[self.PLAYERORDER[0]].stacksize playas[self.PLAYERORDER[0]].in_front = playas[self.PLAYERORDER[0]].stacksize playas[self.PLAYERORDER[0]].stacksize = 0 playas[self.PLAYERORDER[0]].all_in = 1 if playas[self.PLAYERORDER[0]].all_in == 0: playas[self.PLAYERORDER[0]].stacksize -= bigblind/2 playas[self.PLAYERORDER[0]].in_front = bigblind/2 playas[self.PLAYERORDER[0]].put_in_pot = bigblind/2 self.pot += bigblind/2 if playas[self.PLAYERORDER[1]].all_in == 0: playas[self.PLAYERORDER[1]].stacksize -= bigblind playas[self.PLAYERORDER[1]].in_front = bigblind playas[self.PLAYERORDER[1]].put_in_pot = bigblind self.pot += bigblind self.left_to_act = self.PLAYERORDER[:] self.cost_to_play = bigblind self.last_raise = bigblind else: # post blinds for more that 2 players # player has not enough or just enough for big blind if playas[self.PLAYERORDER[2%len(self.PLAYERORDER)]].stacksize = bigblind: if playas[self.PLAYERORDER[2%len(self.PLAYERORDER)]].stacksize bigblind: playas[self.PLAYERORDER[2%len(self.PLAYERORDER)]].put_in_pot = playas[self.PLAYERORDER[2%len(self.PLAYERORDER)]].stacksize playas[self.PLAYERORDER[2%len(self.PLAYERORDER)]].in_front =
Re: Code review
- Original Message - From: C Smith illusiontechniq...@gmail.com To: python-list@python.org Sent: Tuesday, 4 November, 2014 4:28:33 PM Subject: Code review I was wondering if I could get some feedback on the biggest thing I have done as an amateur Python coder. The sidepots algorithm isn't correct yet, but I haven't worked on it in a while and thought I would get some advice before diving back in. import random, os ## class Table(object): def __init__(self,bigblind=20,PLAYERNUM=0,pot=0,PLAYERORDER=None, hand_done=0,\ left_to_act=None,cost_to_play=0,in_hand=None,last_raise=0,cards_in_play=None,round='preflop'): if cards_in_play is None: cards_in_play = [] if in_hand is None: in_hand = [] if PLAYERORDER is None: PLAYERORDER = [] if left_to_act is None: left_to_act = [] [snip hundreds of code lines] - Most methods have too much code, split methods into more unitary logical functions. - For instance, add classes 'Hand' and 'Card' - not enough comments - have you written some tests? The code reached a reasonable size where tests would be very helpful (module unittest) - why do you use uppercase attributes ? like PLAYERORDER. These are not 'constants', you change them Example of (incomplete) Card and Hand implementation (python 2.7): class Card(object): Card implementation. def __init__(self, suit, rank): self._suit = suit self._rank = rank # write test card1 == card2 def __eq__(self, other): return (self.suit, self.rank) == (other.suit, other.rank) # use cards as dict keys def __hash__(self): return hash(self.suit, self.rank) # will allow python to sort a list of cards def __lt__(self, other): return int(self) int(other) def __int__(self): Return the numerical value of a card # the dictionary is incomplete return {'1':1,'2':2,'J':11,'Q':12}[self.rank] def __str__(self): return 'Card(%s of %s)' % (self.rank, self.suit) # alias in case card.rank has more meaning than int(card) @property def rank(self): return int(self) # read only access to suit @property def suit(self): return self._suit class Hand(object): Short incomplete example of Hand class def __init__(self): self._cards = [] def add(self, card): if not self.full: self._cards.append(card) if card.rank == 14: # it's an Ace # trick to get Ace considered as 1 as well self._cards.append(Card(card.suite, '1')) # generate the ordered sequence of cards, hiding the '1' cards @property def cards(self): return (card for card in sorted(self._cards) if card.rank 1) # allow to write len(hand) def __len__(self): return len(list(self.cards)) #property def full(self): return len(self) == 5 # allow to write 'for card in hand:' def __iter__(self): return iter(self.cards) def remove(self, card): # and so on... Otherwise: replace if left_to_act is None: left_to_act = [] self.left_to_act = left_to_act by self.left_to_act = left_to_act or [] replace if ranky == 9 or ranky == 5 by if ranky in [9,5] replace if foo == True by if foo replace if len(self.left_to_act) == 0 by if self.left_to_act And much more... but honestly, there's too much code :) I'll let you chew on this one. JM -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review
C Smith illusiontechniq...@gmail.com writes: I was wondering if I could get some feedback on the biggest thing I have done as an amateur Python coder. Comments. You need a *lot* more comments. Like, every line or two of code should have a comment explaining what is being accomplished. Seriously. Every line or two. Some blank lines wouldn't hurt either. Also it would be nice to define some of the terms you're using. What is a blind? What does in front mean? What is a muck hand? -- John Gordon Imagine what it must be like for a real medical doctor to gor...@panix.comwatch 'House', or a real serial killer to watch 'Dexter'. -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review
On Tuesday, November 4, 2014 12:35:32 PM UTC-8, John Gordon wrote: C Smith illusiontechniq...@gmail.com writes: I was wondering if I could get some feedback on the biggest thing I have done as an amateur Python coder. Comments. You need a *lot* more comments. Like, every line or two of code should have a comment explaining what is being accomplished. Seriously. Every line or two. Some blank lines wouldn't hurt either. Also it would be nice to define some of the terms you're using. What is a blind? What does in front mean? What is a muck hand? -- John Gordon Imagine what it must be like for a real medical doctor to gor...@panix.comwatch 'House', or a real serial killer to watch 'Dexter'. A blind is a required bet that the two people sitting to the left of the button have to make before a hand begins. The first player pays the small blind and the second player pays the big blind, which is double the small blind. For tournament games, the blinds increase periodically. Mucking a hand means to throw your cards away without revealing them. In professional Poker, you typically give them to the dealer. In front just refers to table position which determines play order. -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review
Jean-Michel wrote: replace if left_to_act is None: left_to_act = [] self.left_to_act = left_to_act by self.left_to_act = left_to_act or [] I read that with 2.7 that I had to initialize class variables to immutable types. I think because I was working with the lists before they had been altered and were still empty lists. I will mess around tomorrow with the classes you suggested as I have yet to make use of decorators. Thanks. I will work on putting some more comments in as well. On Tue, Nov 4, 2014 at 4:09 PM, sohcahto...@gmail.com wrote: On Tuesday, November 4, 2014 12:35:32 PM UTC-8, John Gordon wrote: C Smith illusiontechniq...@gmail.com writes: I was wondering if I could get some feedback on the biggest thing I have done as an amateur Python coder. Comments. You need a *lot* more comments. Like, every line or two of code should have a comment explaining what is being accomplished. Seriously. Every line or two. Some blank lines wouldn't hurt either. Also it would be nice to define some of the terms you're using. What is a blind? What does in front mean? What is a muck hand? -- John Gordon Imagine what it must be like for a real medical doctor to gor...@panix.comwatch 'House', or a real serial killer to watch 'Dexter'. A blind is a required bet that the two people sitting to the left of the button have to make before a hand begins. The first player pays the small blind and the second player pays the big blind, which is double the small blind. For tournament games, the blinds increase periodically. Mucking a hand means to throw your cards away without revealing them. In professional Poker, you typically give them to the dealer. In front just refers to table position which determines play order. -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Code Review for Paper, Rock, Scissors
On 10/14/2014 01:04 AM, Revenant wrote: Hi all! I'm new to Python and programming in general, and am trying to learn as much as I can about it. Anyway, for a basic first program I made a simple game of Paper, Rock, Scissors. For this program, I incorporated a main menu that presented three different options, allowed the user to play a game of Paper, Rock, Scissors, allowed them to play the game again, and most importantly checked the user's input to make sure the program doesn't fail due to errors. One thing I want to try to add is a Press any key to continue function that occurs at the end of the program when the user decides to quit. I looked at some options online, but haven't quite figured it out yet. As previously stated, I am new to Python and would also like to see if any of you programming gurus have some suggestions about how I can simplify code, and also if there are any other good starter programs to work on to improve my skills. Thanks for reading! Code is below: [snip] You've already received a lot of good advice, which I'm not going to repeat here. Rather, I'm going to show you the version that I wrote some time ago. Whether this version is good/bad/indifferent is up to someone else to say, but I'm showing it here just as an example of a different approach that you might find interesting to study. Although, being new to Python, some of the things here will probably be unfamiliar to you, particularly the new-style string formatting which I use a lot. The key to this approach is to recognize that there are only nine possible combinations. I handle these in the get_result() function by stitching together pieces of strings in a dictionary. This function is interesting because, although it has a total of 34 lines, 17 are comments or blanks, 16 are data definitions, and only 1 line is actual code. The get_rps() function is used to get the player's rock/paper/scissor choice. It also allows 'quit' as a fourth choice. This makes your proposed Press any key... unnecessary, because this version will continue automatically until you specifically tell it to stop. Also it accepts an empty input as the same as a 'quit' choice. Whether this is good or bad is debatable, but it can easily be written either way. It returns the choice as a single lower-case character, 'r', 'p', 's' or 'q'. This version also makes heavy use of the constants WIN/LOSE/DRAW, which are defined as globals at the top of the program. They help the clarity of the source. Normal convention is to make the names of constants all upper-case. This is a convention only, not a requirement. The scores are tracked in a three-element list, which use the WIN/LOSE/DRAW constants as the indexes. The instruction display in my version is very short, but it could easily be replaced with a longer version like yours. FWIW, here is my code... Note the first line is Linux-specific -- Windows will ignore it, or you can remove it. # Code starts here #!/usr/bin/env python3 # rps.py -- Rock, Paper, Scissors game from random import choice # Global constants WIN = 0 LOSE = 1 DRAW = 2 def get_result(h, c): Determine who wins this round Parameters: h: Human's selection (r, p or s) c: Computer's selection (r, p or s) Returns a tuple of the WIN/LOSE/DRAW value and the string describing the results # Strings used in results pr = 'Paper covers Rock. {}' rs = 'Rock smashes Scissors. {}' sp = 'Scissors cuts Paper. {}' ti = 'We both have {}. {}' # Win/lose/draw strings wins = ('You win', 'I win', It's a draw) # Dictionary defining the results res = { 'rr' : (DRAW, ti.format('rocks', wins[DRAW])), 'rp' : (LOSE, pr.format(wins[LOSE])), 'rs' : (WIN, rs.format(wins[WIN])), 'pr' : (WIN, pr.format(wins[WIN])), 'pp' : (DRAW, ti.format('paper', wins[DRAW])), 'ps' : (LOSE, sp.format(wins[LOSE])), 'sr' : (LOSE, rs.format(wins[LOSE])), 'sp' : (WIN, sp.format(wins[WIN])), 'ss' : (DRAW, ti.format('scissors', wins[DRAW])) } # Return the result tuple return res[h + c] def get_rps(): Get Rock/Paper/Scissor choice. while True: select = input('\nDo you choose Rock, Paper or Scissors ').lower() # Check for empty input or quit command if not select or select in ['q', 'quit']: return 'q' # return quit code # Check for valid input if select in ['r', 'rock', 'p', 'paper', 's', 'scissors']: return select[0]# return first character print('What did you say?? Try again please') #= Main Program starts here == # Keep track of results: # scores[0] = number of human wins # scores[1] = number of computer wins # scores[2] = number of draws scores = [0] *
Code Review for Paper, Rock, Scissors
Hi all! I'm new to Python and programming in general, and am trying to learn as much as I can about it. Anyway, for a basic first program I made a simple game of Paper, Rock, Scissors. For this program, I incorporated a main menu that presented three different options, allowed the user to play a game of Paper, Rock, Scissors, allowed them to play the game again, and most importantly checked the user's input to make sure the program doesn't fail due to errors. One thing I want to try to add is a Press any key to continue function that occurs at the end of the program when the user decides to quit. I looked at some options online, but haven't quite figured it out yet. As previously stated, I am new to Python and would also like to see if any of you programming gurus have some suggestions about how I can simplify code, and also if there are any other good starter programs to work on to improve my skills. Thanks for reading! Code is below: # Creates the main menu. def menu(): # Sets the scores to 0. global playerscore global compscore global draws playerscore = 0 compscore = 0 draws = 0 menuselection = input('Please enter a selection: (Play/Help/About): ') # Checks for an invalid selection. while menuselection != 'Play' and menuselection != 'play' and menuselection != 'Help' and menuselection != 'help' \ and menuselection != 'About' and menuselection != 'about': print('You have entered an invalid selection.') menuselection = input('\nPlease type a selection: (Play/Help/About): ') else: if menuselection == 'Play' or menuselection == 'play': play() elif menuselection == 'Help' or menuselection == 'help': instructions() else: about() # Creates the game. def play(): global playerscore global compscore global draws # Player chooses Paper, Rock, or Scissors. playerselect = input('\nPlease choose Paper, Rock, or Scissors: ') # Checks for an invalid selection. while playerselect != 'Paper' and playerselect != 'paper' and playerselect != 'Rock' and playerselect != 'rock' \ and playerselect != 'Scissors' and playerselect != 'scissors': print('You have entered an invalid selection.') playerselect = input('\nPlease choose Paper, Rock, or Scissors: ') else: if playerselect == 'Paper' or playerselect == 'paper': print('\nYou have selected Paper.') playerselect = 1 elif playerselect == 'Rock' or playerselect == 'rock': print('\nYou have selected Rock.') playerselect = 2 else: print('\nYou have selected Scissors.') playerselect = 3 # Computer chooses Paper, Rock, or Scissors. import random compselect = random.randint(1, 3) if compselect == 1: print('The Computer has selected Paper') elif compselect == 2: print('The Computer has selected Rock.') else: print('The Computer has selected Scissors.') # Results if player selects paper. if playerselect == 1 and compselect == 1: print('Draw!') draws += 1 score() else: if playerselect == 1 and compselect == 2: print('Paper beats rock. You win!') playerscore += 1 score() elif playerselect == 1 and compselect == 3: print('Paper is beaten by scissors. You lose!') compscore += 1 score() # Results if player selects rock. if playerselect == 2 and compselect == 2: print('Draw!') draws += 1 score() else: if playerselect == 2 and compselect == 1: print('Rock is beaten by paper. You lose!') compscore += 1 score() elif playerselect == 2 and compselect == 3: print('Rock beats scissors. You win!') playerscore += 1 score() # Results if player selects rock. if playerselect == 3 and compselect == 3: print('Draw!') draws += 1 score() else: if playerselect == 3 and compselect == 1: print('Scissors beat paper. You win!') playerscore += 1 score() elif playerselect == 3 and compselect == 2: print('Scissors are beaten by rock. You lose!') compscore += 1 score() again() # Determines if the player wants to play another game. def again(): replay = input('\nDo you want to play again (Y/N)? ') while replay != 'Y' and replay != 'y' and replay != 'N' and replay != 'n': print('You have entered an invalid selection.') replay = input('\nDo you want to play again (Y/N)? ') else: if replay == 'Y' or replay == 'y': play() else: print('\nThanks for playing!') # Creates the instructions. def instructions(): print('\nPaper,
Re: Code Review for Paper, Rock, Scissors
Hi there! Welcome to Python. On Tuesday, 14 October 2014 09:04:51 UTC+1, Revenant wrote: I am new to Python and would also like to see if any of you programming gurus have some suggestions about how I can simplify code, and also if there are any other good starter programs to work on to improve my skills. I'm sure you'll get a lot of helpful advice here. Here's a start: you have a lot of places where you're comparing variables to the capitalized and lower-case versions of the same string. You could halve that number if you converted your input to lowercase first. For example: if menuselection == 'play' or menuselection == 'Play': changes to: if menuselection.lower() == 'play': There are plenty of other string methods you might find useful. -- https://mail.python.org/mailman/listinfo/python-list
Re: Code Review for Paper, Rock, Scissors
more common would be to have self-contained functions that perform one job (in this case, displaying the instructions on the console), and have looping done in the places that want looping - probably inside menu(). Incidentally, this function doesn't *create* anything. Your comment (which would be better as a docstring, fwiw) is slightly confusing here. # Creates the about section. def about(): print('\nPaper, Rock, Scissors\n\nVersion 1.0\n\nCreated by Name, 07 October 2014\n') menu() Huh, I didn't know your name was actually Name :) # Calculates score. def score(): print('\nCurrent Scores: ') print('\nPlayer Score:', playerscore) print('\nComputer Score:', compscore) print('\nDraws:', draws) # Start of program operations. print('Welcome to Paper, Rock, Scissors!\n') menu() Suggestion: Where possible, follow a general policy of Define Before Use. For any given global name (like function names), the first occurrence in the file should be its definition, and all usage should be lower in the file than that. Once you clean up the mutual recursion, you'll be able to lay your code out like this; there'll be a single menu() function near the bottom, and functions like score() will be much higher up, as they have almost no dependencies. It'd look something like this (function bodies and blank lines elided for brevity): import random playerscore = compscore = draws = 0 def instructions(): def about(): def score(): def again(): # which will return True or False, as per Dave's suggestion def play(): def menu(): print(Welcome) menu() When someone comes looking at a program like this, s/he can see exactly what depends on what. There can be exceptions, of course (sometimes mutual recursion really is the right thing to do, especially with tree-walking routines), but those can then be noted with comments (Mutually recursive with xyz().), or in some cases may be obvious from the names. In any case, the bulk of most programs can be written in this style, and it does improve clarity. Hope that's of value. Like all advice, it's just one person's opinion, and you're most welcome to reject it; but you did ask for code review, so I'm hoping you'll at least know *why* you're rejecting any piece of advice :) All the best! ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Code review?
Hey all. New to the list. I’m working on a web app with 2.6 and Flask. I’m still relatively new to python. Is there a chance to get a code review from anyone? I really want someone to just tear up my code and tell me how to increase my efficiency and what I’m doing wrong (and how to upload images via a form in Flask, but that’s another story). Happy coding Adam -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review?
On Tue, Jan 14, 2014 at 3:29 AM, Adam sk82...@gmail.com wrote: Hey all. New to the list. I’m working on a web app with 2.6 and Flask. I’m still relatively new to python. Is there a chance to get a code review from anyone? I really want someone to just tear up my code and tell me how to increase my efficiency and what I’m doing wrong (and how to upload images via a form in Flask, but that’s another story). Definitely! Preferably, post your code in-line; if it's too long for that, post it someplace else and link to it. Be sure not to damage indentation, of course, but no matter how new you are to Python you'll know that! Incidentally, is there a reason you're using Python 2.6? You should be able to upgrade at least to 2.7, and Flask ought to work fine on 3.3 (the current stable Python). If it's the beginning of your project, and you have nothing binding you to Python 2, go with Python 3. Converting a small project now will save you the job of converting a big project in ten years' time :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review?
On Tue, 14 Jan 2014 03:40:25 +1100, Chris Angelico wrote: Incidentally, is there a reason you're using Python 2.6? You should be able to upgrade at least to 2.7, and Flask ought to work fine on 3.3 (the current stable Python). If it's the beginning of your project, and you have nothing binding you to Python 2, go with Python 3. Converting a small project now will save you the job of converting a big project in ten years' time Everything you say is correct, but remember that there is a rather large ecosystem of people writing code to run on servers where the supported version of Python is 2.6, 2.5, 2.4 and even 2.3. RedHat, for example, still has at least one version of RHEL still under commercial support where the system Python is 2.3, at least that was the case a few months back, it may have reached end-of-life by now. But 2.4 will definitely still be under support. (I don't believe there is any mainstream Linux distro still supporting versions older than 2.3.) Not everyone is willing, permitted or able to install Python other than that which their OS provides, and we ought to respect that. Hell, if somebody wants to ask questions about Python 1.5, we can answer them! The core language is still recognisably Python, a surprisingly large number of libraries were around back then (it was Python 1.4 or 1.5 which first got the reputation of batteries included), and I for one still have it installed so I can even test code for it. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review?
On Tue, Jan 14, 2014 at 7:43 AM, Steven D'Aprano st...@pearwood.info wrote: On Tue, 14 Jan 2014 03:40:25 +1100, Chris Angelico wrote: Incidentally, is there a reason you're using Python 2.6? You should be able to upgrade at least to 2.7, and Flask ought to work fine on 3.3 (the current stable Python). If it's the beginning of your project, and you have nothing binding you to Python 2, go with Python 3. Converting a small project now will save you the job of converting a big project in ten years' time Everything you say is correct, but remember that there is a rather large ecosystem of people writing code to run on servers where the supported version of Python is 2.6, 2.5, 2.4 and even 2.3. RedHat, for example, still has at least one version of RHEL still under commercial support where the system Python is 2.3, at least that was the case a few months back, it may have reached end-of-life by now. But 2.4 will definitely still be under support. Pledging that your app will run on the system Python of RHEL is something that binds you to a particular set of versions of Python. It's not just library support that does that. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review?
in 714500 20140113 233415 Chris Angelico ros...@gmail.com wrote: On Tue, Jan 14, 2014 at 7:43 AM, Steven D'Aprano st...@pearwood.info wrote: On Tue, 14 Jan 2014 03:40:25 +1100, Chris Angelico wrote: Incidentally, is there a reason you're using Python 2.6? You should be able to upgrade at least to 2.7, and Flask ought to work fine on 3.3 (the current stable Python). If it's the beginning of your project, and you have nothing binding you to Python 2, go with Python 3. Converting a small project now will save you the job of converting a big project in ten years' time Everything you say is correct, but remember that there is a rather large ecosystem of people writing code to run on servers where the supported version of Python is 2.6, 2.5, 2.4 and even 2.3. RedHat, for example, still has at least one version of RHEL still under commercial support where the system Python is 2.3, at least that was the case a few months back, it may have reached end-of-life by now. But 2.4 will definitely still be under support. Pledging that your app will run on the system Python of RHEL is something that binds you to a particular set of versions of Python. It's not just library support that does that. Does any Linux distro ship with Python 3? I haven't seen one. -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review?
On 14-01-2014 11:22, Bob Martin wrote: in 714500 20140113 233415 Chris Angelico ros...@gmail.com wrote: On Tue, Jan 14, 2014 at 7:43 AM, Steven D'Aprano st...@pearwood.info wrote: On Tue, 14 Jan 2014 03:40:25 +1100, Chris Angelico wrote: Incidentally, is there a reason you're using Python 2.6? You should be able to upgrade at least to 2.7, and Flask ought to work fine on 3.3 (the current stable Python). If it's the beginning of your project, and you have nothing binding you to Python 2, go with Python 3. Converting a small project now will save you the job of converting a big project in ten years' time Everything you say is correct, but remember that there is a rather large ecosystem of people writing code to run on servers where the supported version of Python is 2.6, 2.5, 2.4 and even 2.3. RedHat, for example, still has at least one version of RHEL still under commercial support where the system Python is 2.3, at least that was the case a few months back, it may have reached end-of-life by now. But 2.4 will definitely still be under support. Pledging that your app will run on the system Python of RHEL is something that binds you to a particular set of versions of Python. It's not just library support that does that. Does any Linux distro ship with Python 3? I haven't seen one. Debian GNU/Linux https://wiki.debian.org/Python/Python3.3 -- https://mail.python.org/mailman/listinfo/python-list
Re: Code review?
On Tue, Jan 14, 2014 at 6:22 PM, Bob Martin bob.mar...@excite.com wrote: Does any Linux distro ship with Python 3? I haven't seen one. On most Debian-based distros, you can simply 'apt-get install python3', and you'll get some 3.x version (in Debian Squeeze, that's 3.1, Debian Wheezy packages 3.2; Ubuntu since Raring gives you 3.3). Whether or not you actually have it - or python2 for that matter - installed depends on your choices, anything that depends on it will pull it in or you can grab it manually. Arch Linux ships 3.3.3 under the name python, and 2.7.6 under the name python2 - an inversion of the Debian practice. Other distros are looking toward shifting, too. I'd guess that all mainstream distributions carry both branches. It's just a question of what people get when they ask for Python in the most normal way to do that. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
[issue11869] Include information about the bug tracker Rietveld code review tool
Ezio Melotti added the comment: Closing this as duplicate of #13963. -- resolution: - duplicate stage: needs patch - committed/rejected status: open - closed superseder: - dev guide has no mention of mechanics of patch review ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue11869 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
Re: request for another code review
On 9/23/2012 9:48 PM, alex23 wrote: On Sep 23, 6:14 am, Littlefield, Tyler ty...@tysdomain.com wrote: I've gotten a bit farther into my python mud, and wanted to request another code review for style and the like. Are you familiar with codereview.stackexchange.com ? I actually wasn't, thanks! (This isn't to dissuade you from posting such requests here, just to help increase the chance of eyeballs on your code.) -- Take care, Ty http://tds-solutions.net The aspen project: a barebones light-weight mud engine: http://code.google.com/p/aspenmud He that will not reason is a bigot; he that cannot reason is a fool; he that dares not reason is a slave. -- http://mail.python.org/mailman/listinfo/python-list
Re: request for another code review
On 9/23/2012 9:48 PM, alex23 wrote: On Sep 23, 6:14 am, Littlefield, Tyler ty...@tysdomain.com wrote: I've gotten a bit farther into my python mud, and wanted to request another code review for style and the like. Are you familiar with codereview.stackexchange.com ? I actually wasn't, thanks! (This isn't to dissuade you from posting such requests here, just to help increase the chance of eyeballs on your code.) -- Take care, Ty http://tds-solutions.net The aspen project: a barebones light-weight mud engine: http://code.google.com/p/aspenmud He that will not reason is a bigot; he that cannot reason is a fool; he that dares not reason is a slave. -- http://mail.python.org/mailman/listinfo/python-list
Re: request for another code review
On Sep 23, 6:14 am, Littlefield, Tyler ty...@tysdomain.com wrote: I've gotten a bit farther into my python mud, and wanted to request another code review for style and the like. Are you familiar with codereview.stackexchange.com ? (This isn't to dissuade you from posting such requests here, just to help increase the chance of eyeballs on your code.) -- http://mail.python.org/mailman/listinfo/python-list
[issue11869] Include information about the bug tracker Rietveld code review tool
Changes by Ezio Melotti ezio.melo...@gmail.com: -- assignee: - ezio.melotti type: - enhancement ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue11869 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue11869] Include information about the bug tracker Rietveld code review tool
Ezio Melotti added the comment: See also #13963. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue11869 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
request for another code review
Hello all: I've gotten a bit farther into my python mud, and wanted to request another code review for style and the like. Mainly I'm concerned about player.py, world.py and components and other ways to handle what I'm trying to do. I didn't run pychecker just yet, so there are probably a ton of syntax errors; my problem was that world was importing room, and room imported world for functionality and that made things a mess. Ideas and suggestions for code cleanup and cleaner ways to do things would be appreciated. git clone https://code.google.com/p/pymud/ Thanks, -- Take care, Ty http://tds-solutions.net The aspen project: a barebones light-weight mud engine: http://code.google.com/p/aspenmud He that will not reason is a bigot; he that cannot reason is a fool; he that dares not reason is a slave. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
In article XnsA0927750022F4duncanbooth@127.0.0.1, Duncan Booth duncan.bo...@suttoncourtenay.org.uk wrote: Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Fri, 13 Jul 2012 12:30:47 +, Albert van der Horst wrote: The worst of is, of course, = for assignment instead of := . This is a convention that Python follows, to my dismay. *shrug* The worst is to use = for both equality and assignment, like some BASICs. At least Python does not allow assignment as an expression, so you can't make the typical C error of: if x = y: do_something() # oops meant x == y Technically of course Python doesn't have assignment, it just binds names. Albert raised the subject of Algol 68 which if I remember correctly used := for assignment and = to bind names (although unlike Python you couldn't then re-bind the name to another object in the same scope). Algol 68 is very particular about this indeed. For instance they have a whole theory behind real x; x := 17.; This is considered an abbreviation of ref real x = loc real; x:= 17; So x is a reference bound to a freshly generated local real. You see = and that means you can't ever break that relationship. On the left side of a := it is required to have a ref something. Because that generates a pretty clear context, you have considerable leeway on the right side, that is cast into the something. real x= 18.; x := 15.; is right out. If you want to rebind something you need a ref which is really a ref ref. Then you can only switch bindings between different types. So it is totally different from Python. I never thought about = in python to mean binding to set it apart from the Pascal := , instead of being a c-ism. Still my mathematical mind is bothered about the sequence ( legal in FORTRAN , C Python ) X = 1 separator X = 2 Groetjes Albert -- Duncan Booth http://kupuguy.blogspot.com Groetjes Albert -- -- Albert van der Horst, UTRECHT,THE NETHERLANDS Economic growth -- being exponential -- ultimately falters. albert@spearc.xs4all.nl =n http://home.hccnet.nl/a.w.m.van.der.horst -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Fri, 13 Jul 2012 12:30:47 +, Albert van der Horst wrote: The worst of is, of course, = for assignment instead of := . This is a convention that Python follows, to my dismay. *shrug* The worst is to use = for both equality and assignment, like some BASICs. At least Python does not allow assignment as an expression, so you can't make the typical C error of: if x = y: do_something() # oops meant x == y Technically of course Python doesn't have assignment, it just binds names. Albert raised the subject of Algol 68 which if I remember correctly used := for assignment and = to bind names (although unlike Python you couldn't then re-bind the name to another object in the same scope). -- Duncan Booth http://kupuguy.blogspot.com -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
Duncan Booth duncan.booth@invalid.invalid writes: Technically of course Python doesn't have assignment, it just binds names. Names, or other references. I'd argue that Python has assignment, and assignment in Python is identical with binding references to objects. But then, the Python documentation refers to “variables” as though they exist in Python, which I'd argue they don't. It's all very confusing :-) -- \ “Religious faith is the one species of human ignorance that | `\ will not admit of even the *possibility* of correction.” —Sam | _o__) Harris, _The End of Faith_, 2004 | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Fri, Jul 13, 2012 at 5:09 PM, Terry Reedy tjre...@udel.edu wrote: From now on, for each operator I would have to remember wether it is a supposedly comparison operator or not. I believe the following rule is true: if a op b is True or False raises, I don't follow. Raises what? then op is a potentially chained comparison operation. They are (not) equal (and (not) is), the 4 order comparisons, and (not) in. 'in' should be the only surprise and most confusing. 1 3 in {3,4} True 3 in {3,4} {4} False 'and' and 'or' are not included because they do not always return a bool, and indeed, they are not binary operators in the usual sense because of short-circuiting. The only one of those operators that can be said to always return a bool is is (not). The others (apart from and and or) all can be overloaded to return anything you want (for example, sqlalchemy overloads them to return expression objects that are later compiled into SQL), and chaining still occurs regardless of the types they are applied to. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 7/14/2012 5:26 AM, Ian Kelly wrote: On Fri, Jul 13, 2012 at 5:09 PM, Terry Reedy tjre...@udel.edu wrote: I believe the following rule is true: if a op b is True or False raises, Sorry, left out 'or' in 'or raises' I don't follow. Raises what? an Exception. then op is a potentially chained comparison operation. They are (not) equal (and (not) is), the 4 order comparisons, and (not) in. 'in' should be the only surprise and most confusing. 1 3 in {3,4} True 3 in {3,4} {4} False 'and' and 'or' are not included because they do not always return a bool, and indeed, they are not binary operators in the usual sense because of short-circuiting. The only one of those operators that can be said to always return a bool is is (not). The others (apart from and and or) all can be overloaded to return anything you want OK, add 'by default, without over-rides ;-). or 'for builtin classes'. Python's flexibility makes it really hard to make any general statement. In my book-in-progress, I am currently resorting to saying In Python*, ... whenever I know and remember that it is possibly to over-ride the customary behavior described in '...'. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
In article 4ff0f8e0$0$29988$c3e8da3$54964...@news.astraweb.com, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Sun, 01 Jul 2012 05:55:24 -0400, Terry Reedy wrote: On 7/1/2012 2:54 AM, Steven D'Aprano wrote: So no, Python has always included chained comparisons, and yes, it is shameful that a language would force you to unlearn standard notation in favour of a foolish consistency with other operators. Comparisons aren't special because they return bools. They are special because of the way they are used. C treats comparison operators as if they were arithmetic operators, and so the behaviour of a chained comparison is the same as the behaviour as a sequence of arithmetic operators: a foolish consistency. Python treats comparison operators as comparison operators, and gives them behaviour appropriate to comparisons. I considered this a great feature of Python when I first learned it. Reading about how rare it is among programming languages to treat comparisons in the standard way in mathematics reinforces that. Apart from Python, Mathematica, Perl 6, CoffeeScript, Cobra and Clay give chained comparisons the standard meaning. It is, or was, a feature request for Boo, but I can't tell whether it has been implemented or not. Algol 68 does not. It has promoted operator symbols to first class citizens. In that context chained comparison operators cannot be made to work. Both Mathematica and Perl are ad-hoc-ish languages. I would hate Python go that way. From now on, for each operator I would have to remember wether it is a supposedly comparison operator or not. Comparison operations on booleans make sense. I remember a FORTRAN compiler complaining about me comparing LOGICALS. The lack of abstraction! C-like semantics are next to useless, except perhaps for obfuscation: http://stackoverflow.com/questions/4089284/why-does-0-5-3-return-true/ And surprising: http://answers.yahoo.com/question/index?qid=20090923172909AA4O9Hx C-like semantics are a clear case of purity of implementation overruling functional usefulness. The worst of is, of course, = for assignment instead of := . This is a convention that Python follows, to my dismay. -- Steven Groetjes Albert -- -- Albert van der Horst, UTRECHT,THE NETHERLANDS Economic growth -- being exponential -- ultimately falters. albert@spearc.xs4all.nl =n http://home.hccnet.nl/a.w.m.van.der.horst -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Fri, 13 Jul 2012 12:30:47 +, Albert van der Horst wrote: Apart from Python, Mathematica, Perl 6, CoffeeScript, Cobra and Clay give chained comparisons the standard meaning. It is, or was, a feature request for Boo, but I can't tell whether it has been implemented or not. Algol 68 does not. It has promoted operator symbols to first class citizens. In that context chained comparison operators cannot be made to work. Both Mathematica and Perl are ad-hoc-ish languages. I would hate Python go that way. Perl 5 does not have chained comparisons. Perl 6, which is more designed and less ad-hoc, does. From now on, for each operator I would have to remember wether it is a supposedly comparison operator or not. Are you often in the habit of using operators *without* remembering what they do? wink I can't speak for you, but it isn't often that I've found myself not remembering whether the less-than operator means compare two values or multiply two values. Comparison operations on booleans make sense. Actually, no. Is True less than False, or is it greater? In boolean algebra, the question has no answer. It is only an implementation detail of Python that chooses False True. Of course, equality and inequality make sense for all values. But the other comparison operators, = = only make sense for values which are ordered, like real numbers (but not complex numbers), strings, and similar, or for set comparisons (subset and superset). Arbitrary types may not define comparison operators. I remember a FORTRAN compiler complaining about me comparing LOGICALS. The lack of abstraction! The opposite: LOGICALS are abstract values which do not define greater than or less than. The worst of is, of course, = for assignment instead of := . This is a convention that Python follows, to my dismay. *shrug* The worst is to use = for both equality and assignment, like some BASICs. At least Python does not allow assignment as an expression, so you can't make the typical C error of: if x = y: do_something() # oops meant x == y -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Sat, Jul 14, 2012 at 1:04 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Actually, no. Is True less than False, or is it greater? In boolean algebra, the question has no answer. It is only an implementation detail of Python that chooses False True. Maybe in boolean algebra, but in code, it's handy to have sortable bools. In SQL, for instance, I can use a boolean in an ORDER BY, perhaps followed by another criterion, and it's effectively sorting by 1 if some_boolean else 0 or in C notation some_boolean ? 0 : 1 ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Friday, July 6, 2012 9:58:10 AM UTC-4, Steven D#39;Aprano wrote: (Sadly, when I say quot;wequot; I mean collectively. Many language designers, and programmers, don#39;t have the foggiest clue as to what makes a good clean design. Hence C++ and PHP.) I'm not going to defend C++, but to be fair, a major driver of the design is that it had to be plug-compatible with C. From that you're stuck with the preprocessor and pointers. Much goes downhill when you start from there. PHP, yeah, that's just charlie-foxtrot from start to finish. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Jul 13, 8:36 pm, Chris Angelico ros...@gmail.com wrote: On Sat, Jul 14, 2012 at 1:04 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Actually, no. Is True less than False, or is it greater? In boolean algebra, the question has no answer. It is only an implementation detail of Python that chooses False True. Maybe in boolean algebra, but in code, it's handy to have sortable bools. In SQL, for instance, I can use a boolean in an ORDER BY, perhaps followed by another criterion, and it's effectively sorting by 1 if some_boolean else 0 or in C notation some_boolean ? 0 : 1 ChrisA Actually a boolean algebra is a lattice with some additional properties A lattice is a poset (partially ordered set) with suprema and infimas And so there is one natural order relation on any boolean algebra which may be defined as a ≤ b iff a ⋀ b = a tl;dr version: In a boolean algebra, False is bottom and True is top -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
From now on, for each operator I would have to remember wether it is a supposedly comparison operator or not. I believe the following rule is true: if a op b is True or False raises, then op is a potentially chained comparison operation. They are (not) equal (and (not) is), the 4 order comparisons, and (not) in. 'in' should be the only surprise and most confusing. 1 3 in {3,4} True 3 in {3,4} {4} False 'and' and 'or' are not included because they do not always return a bool, and indeed, they are not binary operators in the usual sense because of short-circuiting. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Re: code review
On Sunday, July 1, 2012 5:48:40 PM UTC+2, Evan Driscoll wrote: On 7/1/2012 4:54, Alister wrote: On Sat, 30 Jun 2012 23:45:25 -0500, Evan Driscoll wrote: If I had seen that in a program, I'd have assumed it was a bug. You would? I have only been using python for 6 - 12 months but in my past I programmed microcontrollers in assembly. as soon as i saw it i understood it thought great, like a light bulb going on. It's not a matter of I wouldn't have understood what the author was trying to do (with a small caveat), it's a matter of I'd have assumed that the author didn't understand the language semantics. I'm pretty sure it goes contrary to *every other programming language I've ever used* (and a couple that I haven't). I understand why Python does it, and it certainly is nice in that it matches typical mathematical notation, but the surprise quotient is *very* high in the PL world IMO. Evan Avoiding suprises would mean we cannot improve languages, just reshuffle features? Cheers, Lars -- http://mail.python.org/mailman/listinfo/python-list
Apology for OT posts (was: code review)
On Tue, 03 Jul 2012 23:39:20 -0600 Littlefield, Tyler ty...@tysdomain.com wrote: On 7/3/2012 10:55 PM, Simon Cropper wrote: Some questions to Tyler Littlefield, who started this thread. Q1 -- Did you get any constructive feedback on your code? I did get some, which I appreciated. someone mentioned using PyLint. From reading, I found it was really really pedantic, so I used PyFlakes instead. Q2 -- Did you feel that the process of submitting your code for review met your expectation? There wasn't much more to review, so yes. The info I got was helpful and farther than it was before I started. Q3 -- Would you recommend others doing this either on this forum or other fora? It appears to me - third party watching the ongoing dialog - that the tread has gone right off topic (some time ago) and someone should really start a new thread under a new title/subject. Most of what I have read does not appear to be discussing your code or how you could improve your code. I basically just stopped after a while. It got into a my language is better than your language, so I didn't see much constructive info. I've started reading from the bottom though, where it looks like it's back, and I do appreciate the rest of the info given, as well. Thanks again for the feedback. As one of the perpetrators, I did apologise for being OT within the body of my replies to OT posts, but I see the irony. I guess I just thought somebody else would do it eventually. I hereby apologise for not taking the correct action, and vow to do so in future: to change the subject line regardless of who initially went OT, starting now. Regards, -- John -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Jul 4, 3:39 pm, Littlefield, Tyler ty...@tysdomain.com wrote: I basically just stopped after a while. It got into a my language is better than your language, so I didn't see much constructive info. To be fair, it's more my vision of the language is better than yours :) But yes, it should've been forked into a separate thread ages okay. It did get me wondering, though, if there's much in the way of support for code review in repository sites like github? Being able to aggregate comments around the actual code itself could be really handy. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Jul 4, 11:17 am, alex23 wuwe...@gmail.com wrote: On Jul 4, 3:39 pm, Littlefield, Tyler ty...@tysdomain.com wrote: I basically just stopped after a while. It got into a my language is better than your language, so I didn't see much constructive info. To be fair, it's more my vision of the language is better than yours :) But yes, it should've been forked into a separate thread ages okay. A program is a product of a person's creativity as is a programming language. They have an analogous relation as say a sculpture to chisels. This thread is a good example of how longwindedness of a discussion correlates with its uselessness. However the reverse error is more insidious: programs are made by humans and should be critiqued, whereas programming languages (in particular python) is sacrosanct and cannot be questioned. Too often I find that responders on this list treat as personal affront anyone who questions python whereas the most appropriate response would be: Nice idea but too invasive for serious consideration. [I am saying this in general and not for this thread:Whats wrong with a b c is quite beyond me!] It did get me wondering, though, if there's much in the way of support for code review in repository sites like github? Being able to aggregate comments around the actual code itself could be really handy. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 03/07/2012 22:54, Chris Angelico wrote: On Wed, Jul 4, 2012 at 6:13 AM, Dave Angel d...@davea.name wrote: On 07/03/2012 12:05 PM, Mark Lawrence wrote: If I go to the moon I will weigh 2st 10lb (if my sums are correct :) but the equivalent Frenchman will still be 86kg. I hereby put this forward as proof that the metric system is rubbish and we should revert back to imperial goodies. 86 kg is not a weight, it's a mass. So it doesn't depend on the local gravity situation. Indeed it is, as he says. But I believe he may be right in that 'stone' is a unit of weight. Hard to be sure, though, given that it's not an SI unit (for instance, the Wikipedia article text refers to weight, but its picture shows a man measuring mass). ChrisA Stone is a unit of weight (Brits know important things like this). And with the consistency that the English language is reknowned for the plural is, yes you've guessed it, stone :) -- Cheers. Mark Lawrence. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
Mark Lawrence breamore...@yahoo.co.uk writes: On 03/07/2012 03:25, John O'Hagan wrote: On Tue, 3 Jul 2012 11:22:55 +1000 I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. John I weigh 13st 8lb - does this make me redundant? It might mean that you have some redundant weight :) -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
2012/7/4 Paul Rudin paul.nos...@rudin.co.uk Mark Lawrence breamore...@yahoo.co.uk writes: On 03/07/2012 03:25, John O'Hagan wrote: On Tue, 3 Jul 2012 11:22:55 +1000 I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Just a Test.I didn't familiar about maillist. Metric system. I don't miss hogsheads and fathoms at all. J I weigh 13st 8lb - does this make me redundant? It might mean that you have some redundant weight :) -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 04/07/2012 10:29, Paul Rudin wrote: Mark Lawrence breamore...@yahoo.co.uk writes: On 03/07/2012 03:25, John O'Hagan wrote: On Tue, 3 Jul 2012 11:22:55 +1000 I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. John I weigh 13st 8lb - does this make me redundant? It might mean that you have some redundant weight :) True indeed, although my beer free diet of the last 10 days (yes, 10 whole days) has at least got it down from 14 stone 2 pounds. -- Cheers. Mark Lawrence. -- http://mail.python.org/mailman/listinfo/python-list
Evolution (was: code review)
On Mon, Jul 2, 2012 at 1:35 PM, Rick Johnson rantingrickjohn...@gmail.com wrote: I am reminded of a story: A few years back a very nice old woman offered to give me her typewriter. She said: i might need to type a letter one day and it would good to have around. It was a nice typewriter for 1956, but she had no idea her little machine was reduced to no less than a paper weight thanks to something called the PC. Her machine had been extinct for decades. Effectually, SHE had been extinct for decades. It's called retirement, not extinction, and there's nothing at all wrong with typing out letters; it's just slower. If we ever have a nuclear war or even just get hit by a large enough coronal mass ejection, you might find yourself wishing you had that typewriter instead of your suddenly useless laptop -- just as the dinosaurs (had they been sentient) might have found themselves wishing they had not evolved to be so darn *large* 65 million years ago. When i hear people like Chris evangelizing about slavish syntax, i am reminded of the nice old lady. Her intentions where virtuous, however her logic was flawed. She is still clinging to old technology. Like the Luddites she refuses to see the importance technological advancements. And by harboring this nostalgia she is actually undermining the future evolution of an entire species. That's not nostalgia; that's lack of necessity. There is nothing so important about technological advancement that it must be thrust upon nice old ladies who have set habits and no good reason to change them. And I can't see for the life of me how people failing to jump on the email bandwagon have anything at all to do with evolution. Lifespans are limited for a very important evolutionary reason! If that is true, then when your singularity finally arrives and we all become immortal, will that not interfere with evolution? All kidding aside, evolution is a natural process, not a purpose. The ultimate point of evolution will occur when the universe is no longer entropically able to support life in any form, transcended or otherwise, and we will all finally be extinct. Then what? The universe just carries on without us, and goes through a whole series of cosmological epochs that will be observed by nobody at all, for far longer than the entirety of our brief, chaotic existence. It's often suggested that the Big Bang is the cause of our existence, but the Big Bang is much bigger than us. The Big Bang is like a rock thrown into a still pond. First there is a big splash, then there are some ripples, and after a short time the pond becomes boringly still again. We aren't really part of the pond; we're just riding the ripples, and when they vanish, so do we. You made the claim once in another thread that individuals are not important in the grand scheme of things (I disagree; from our limited societal vantage point, individuals *are* the grand scheme of things). I am trying here to demonstrate the point that the universe doesn't care one whit about evolution either. Hopefully I succeeded, because I don't want to get sucked into another huge, completely off-topic thread, and so I won't be posting on this again. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 2012-07-02, Chris Angelico ros...@gmail.com wrote: On Tue, Jul 3, 2012 at 1:57 AM, Rick Johnson rantingrickjohn...@gmail.com wrote: Poor Chris. That's because you've been brainwashed into believing you must spoon feed your interpreter to get your code working correctly. Stop applying these naive assumptions to Python code. Python knows when you reach the end of a statement, no need for redundant semicolons! Python knows when its reached the end of block and needs to drop back one level, no need for redundant road signs. Python knows Chris; Python KNOWS! Why poor, Ralph? I am poor in the essence of ignorance's bliss, rich only in the never-ending thirst for knowledge and more languages. In me there meet a combination of antithetical elements which are at eternal war with one another... I hope I make myself clear, lady? His simple eloquence goes to my very heart! -- Neil Cerutti -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
In article mailman.1734.1341295784.4697.python-l...@python.org, Dennis Lee Bieber wlfr...@ix.netcom.com wrote: On 03 Jul 2012 04:11:22 GMT, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info declaimed the following in gmane.comp.python.general: One of my favourites is the league, which in the Middle Ages was actually defined as the distance that a man, or a horse, could walk in an hour. From the Explanatory Supplement to the Astronomical Almanac [1992 University Science Books], Table 15.15, the speed of light is 1.80261750E12 furlongs/fortnight And sure enough, that's what units says: $ units 500 units, 54 prefixes You have: c You want: furlongs/fortnight * 1.8026175e+12 / 5.5474886e-13 -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Mon, 2 Jul 2012 22:10:00 -0700 (PDT) rusi rustompm...@gmail.com wrote: On Jul 3, 7:25 am, John O'Hagan resea...@johnohagan.com wrote: I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. Music is another field which could do with a metrification: I get tired of explaining to beginners why there's no B#, except when it's C. Check outhttp://musicnotation.org You assume that equal temperament is the only way to have music. Apart from the fact that there are non-tempered musics all over the world, even Bach Mozart and Beethoven did not write for/to equal temperament. In a pure/untempered C-scale A-flat is almost half a semitone sharper than G-sharp -- 8/5 vs 25/16. [...] I don't assume that at all :) If you didn't already, have look at the link. I was talking about notation of the normal everyday contemporary tempered system where there is no pitch difference between Ab and G#. But even in a just system, any difference between them depends on the system itself, the key, and whether you choose to call them that. I've never heard anyone claim that C is sharper than B#, although in the key of E the relationship would be the same. AIUI there is any number of whole number ratios which fall between seven and nine tempered semitones above the fundamental (to take your example), and in C, any one of them could be called either Ab or G# depending on the key signature or other context. IMHO, that's the aspect that could benefit from a simplified representation. To the OP, I'm deeply sorry! -- John -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 03/07/2012 03:25, John O'Hagan wrote: On Tue, 3 Jul 2012 11:22:55 +1000 I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. John I weigh 13st 8lb - does this make me redundant? -- Cheers. Mark Lawrence. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Wed, Jul 4, 2012 at 1:50 AM, Mark Lawrence breamore...@yahoo.co.uk wrote: On 03/07/2012 03:25, John O'Hagan wrote: On Tue, 3 Jul 2012 11:22:55 +1000 I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. John I weigh 13st 8lb - does this make me redundant? Yes, because somewhere in the world is someone who weighs (... pulls out calculator...) 86kg. After all, the French had a bloody revolution to get us a new system without any of the old baggage. We don't want to disappoint the French now, do we! ChrisA lemme just dislodge my tongue from my cheek, it seems to be stuck... -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 03/07/2012 07:09, Dennis Lee Bieber wrote: On 03 Jul 2012 04:11:22 GMT, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info declaimed the following in gmane.comp.python.general: One of my favourites is the league, which in the Middle Ages was actually defined as the distance that a man, or a horse, could walk in an hour. From the Explanatory Supplement to the Astronomical Almanac [1992 University Science Books], Table 15.15, the speed of light is 1.80261750E12 furlongs/fortnight +1 most useless piece of information garnered this week. -- Cheers. Mark Lawrence. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 03/07/2012 16:53, Chris Angelico wrote: On Wed, Jul 4, 2012 at 1:50 AM, Mark Lawrence breamore...@yahoo.co.uk wrote: On 03/07/2012 03:25, John O'Hagan wrote: On Tue, 3 Jul 2012 11:22:55 +1000 I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. John I weigh 13st 8lb - does this make me redundant? Yes, because somewhere in the world is someone who weighs (... pulls out calculator...) 86kg. After all, the French had a bloody revolution to get us a new system without any of the old baggage. We don't want to disappoint the French now, do we! ChrisA lemme just dislodge my tongue from my cheek, it seems to be stuck... If I go to the moon I will weigh 2st 10lb (if my sums are correct :) but the equivalent Frenchman will still be 86kg. I hereby put this forward as proof that the metric system is rubbish and we should revert back to imperial goodies. -- Cheers. Mark Lawrence. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Sat, Jun 30, 2012 at 3:34 PM, Alister alister.w...@ntlworld.com wrote: On Fri, 29 Jun 2012 09:03:22 -0600, Littlefield, Tyler wrote: On 6/29/2012 1:31 AM, Steven D'Aprano wrote: On Thu, 28 Jun 2012 20:58:15 -0700, alex23 wrote: On Jun 29, 12:57 pm, Littlefield, Tyler ty...@tysdomain.com wrote: I was curious if someone wouldn't mind poking at some code. The project page is at:http://code.google.com/p/pymud Any information is greatly appreciated. I couldn't find any actual code at that site, the git repository is currently empty. OOPS, sorry. Apparently I'm not as good with git as I thought. Everything's in the repo now. I think I may be on firmer grounds with the next few: isValidPassword can be simplified to def isValidPassword(password: count=len(password) return count= mud.minpass and count= mud.maxpass I haven't actually seen the rest of the code, but I would like to point out that applications placing maximum length limits on passwords are extremely annoying. snip -- regards, kushal -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, Jul 3, 2012 at 11:53 AM, Kushal Kumaran kushal.kumaran+pyt...@gmail.com wrote: On Sat, Jun 30, 2012 at 3:34 PM, Alister alister.w...@ntlworld.com wrote: On Fri, 29 Jun 2012 09:03:22 -0600, Littlefield, Tyler wrote: On 6/29/2012 1:31 AM, Steven D'Aprano wrote: On Thu, 28 Jun 2012 20:58:15 -0700, alex23 wrote: On Jun 29, 12:57 pm, Littlefield, Tyler ty...@tysdomain.com wrote: I was curious if someone wouldn't mind poking at some code. The project page is at:http://code.google.com/p/pymud Any information is greatly appreciated. I couldn't find any actual code at that site, the git repository is currently empty. OOPS, sorry. Apparently I'm not as good with git as I thought. Everything's in the repo now. I think I may be on firmer grounds with the next few: isValidPassword can be simplified to def isValidPassword(password: count=len(password) return count= mud.minpass and count= mud.maxpass I haven't actually seen the rest of the code, but I would like to point out that applications placing maximum length limits on passwords are extremely annoying. They're annoying when the maximum length is unreasonably small, but you have to have a maximum length to close off one DoS attack vector. Without a limit, if a user presents a 1 GB password, then guess what? Your system has to hash that GB of data before it can reject it. And if you're serious about security then it will be a cryptographic hash, and that means slow. To prevent that, the system needs to reject outright password attempts that are longer than some predetermined reasonable length, and if the system won't authenticate those passwords, then it can't allow the user to set them either. Cheers, Ian -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
In mailman.1753.1341338042.4697.python-l...@python.org Kushal Kumaran kushal.kumaran+pyt...@gmail.com writes: I haven't actually seen the rest of the code, but I would like to point out that applications placing maximum length limits on passwords are extremely annoying. As a practical matter, doesn't there have to be *some* sort of limit? For example if the (encrypted) password is stored in a database, you can't exceed the table column width. -- John Gordon A is for Amy, who fell down the stairs gor...@panix.com B is for Basil, assaulted by bears -- Edward Gorey, The Gashlycrumb Tinies -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, Jul 3, 2012 at 12:18 PM, John Gordon gor...@panix.com wrote: In mailman.1753.1341338042.4697.python-l...@python.org Kushal Kumaran kushal.kumaran+pyt...@gmail.com writes: I haven't actually seen the rest of the code, but I would like to point out that applications placing maximum length limits on passwords are extremely annoying. As a practical matter, doesn't there have to be *some* sort of limit? For example if the (encrypted) password is stored in a database, you can't exceed the table column width. Hopefully you're storing password hashes, not encrypted passwords (which can all too easily be DEcrypted), and the length of the hash is not dependent on the length of the password. But yes, there are certainly practical concerns here. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 07/03/2012 12:05 PM, Mark Lawrence wrote: On 03/07/2012 16:53, Chris Angelico wrote: On Wed, Jul 4, 2012 at 1:50 AM, Mark Lawrence breamore...@yahoo.co.uk wrote: On 03/07/2012 03:25, John O'Hagan wrote: On Tue, 3 Jul 2012 11:22:55 +1000 I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. John I weigh 13st 8lb - does this make me redundant? Yes, because somewhere in the world is someone who weighs (... pulls out calculator...) 86kg. After all, the French had a bloody revolution to get us a new system without any of the old baggage. We don't want to disappoint the French now, do we! ChrisA lemme just dislodge my tongue from my cheek, it seems to be stuck... If I go to the moon I will weigh 2st 10lb (if my sums are correct :) but the equivalent Frenchman will still be 86kg. I hereby put this forward as proof that the metric system is rubbish and we should revert back to imperial goodies. 86 kg is not a weight, it's a mass. So it doesn't depend on the local gravity situation. DaveA -- DaveA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Wed, Jul 4, 2012 at 4:27 AM, Ian Kelly ian.g.ke...@gmail.com wrote: On Tue, Jul 3, 2012 at 12:18 PM, John Gordon gor...@panix.com wrote: As a practical matter, doesn't there have to be *some* sort of limit? For example if the (encrypted) password is stored in a database, you can't exceed the table column width. Hopefully you're storing password hashes, not encrypted passwords (which can all too easily be DEcrypted), and the length of the hash is not dependent on the length of the password. But yes, there are certainly practical concerns here. With a hash length of N bits, there's not much use accepting passwords longer than about N/4 or N/2 bytes. (It would be N/8 except that most people don't invent passwords that use the entire available alphabet. And of course, this ignores issues of encodings, but I'm pretty sure all current crypto hashes work with bytes not characters anyway.) But please, don't limit password lengths too much. Make your password system XKCD 936 compliant: http://xkcd.com/936/ Permit long passwords consisting of nothing but lowercase letters. They really aren't as insecure as some people think! ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Wed, Jul 4, 2012 at 6:13 AM, Dave Angel d...@davea.name wrote: On 07/03/2012 12:05 PM, Mark Lawrence wrote: If I go to the moon I will weigh 2st 10lb (if my sums are correct :) but the equivalent Frenchman will still be 86kg. I hereby put this forward as proof that the metric system is rubbish and we should revert back to imperial goodies. 86 kg is not a weight, it's a mass. So it doesn't depend on the local gravity situation. Indeed it is, as he says. But I believe he may be right in that 'stone' is a unit of weight. Hard to be sure, though, given that it's not an SI unit (for instance, the Wikipedia article text refers to weight, but its picture shows a man measuring mass). ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
Ian Kelly ian.g.ke...@gmail.com wrote: On Tue, Jul 3, 2012 at 11:53 AM, Kushal Kumaran kushal.kumaran+pyt...@gmail.com wrote: On Sat, Jun 30, 2012 at 3:34 PM, Alister alister.w...@ntlworld.com wrote: On Fri, 29 Jun 2012 09:03:22 -0600, Littlefield, Tyler wrote: On 6/29/2012 1:31 AM, Steven D'Aprano wrote: On Thu, 28 Jun 2012 20:58:15 -0700, alex23 wrote: On Jun 29, 12:57 pm, Littlefield, Tyler ty...@tysdomain.com wrote: I was curious if someone wouldn't mind poking at some code. The project page is at:http://code.google.com/p/pymud Any information is greatly appreciated. I couldn't find any actual code at that site, the git repository is currently empty. OOPS, sorry. Apparently I'm not as good with git as I thought. Everything's in the repo now. I think I may be on firmer grounds with the next few: isValidPassword can be simplified to def isValidPassword(password: count=len(password) return count= mud.minpass and count= mud.maxpass I haven't actually seen the rest of the code, but I would like to point out that applications placing maximum length limits on passwords are extremely annoying. They're annoying when the maximum length is unreasonably small, but you have to have a maximum length to close off one DoS attack vector. Without a limit, if a user presents a 1 GB password, then guess what? Your system has to hash that GB of data before it can reject it. And if you're serious about security then it will be a cryptographic hash, and that means slow. Well, if you waited until you had the password (however long) in a variable before you applied your maximum limits, the DoS ship has probably sailed already. To prevent that, the system needs to reject outright password attempts that are longer than some predetermined reasonable length, and if the system won't authenticate those passwords, then it can't allow the user to set them either. Cheers, Ian -- regards, kushal -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Wed, Jul 4, 2012 at 12:57 PM, kushal.kumaran+pyt...@gmail.com wrote: Well, if you waited until you had the password (however long) in a variable before you applied your maximum limits, the DoS ship has probably sailed already. Only because data transfer is usually more expensive than hashing. But I'd say that'll always be true. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 04/07/12 13:53, Chris Angelico wrote: On Wed, Jul 4, 2012 at 12:57 PM, kushal.kumaran+pyt...@gmail.com wrote: Well, if you waited until you had the password (however long) in a variable before you applied your maximum limits, the DoS ship has probably sailed already. Only because data transfer is usually more expensive than hashing. But I'd say that'll always be true. ChrisA Some questions to Tyler Littlefield, who started this thread. Q1 -- Did you get any constructive feedback on your code? Q2 -- Did you feel that the process of submitting your code for review met your expectation? Q3 -- Would you recommend others doing this either on this forum or other fora? It appears to me - third party watching the ongoing dialog - that the tread has gone right off topic (some time ago) and someone should really start a new thread under a new title/subject. Most of what I have read does not appear to be discussing your code or how you could improve your code. Following the last few posts, I was wondering whether some other off-list dialog is going on or whether I am missing something. -- Cheers Simon -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 7/3/2012 10:55 PM, Simon Cropper wrote: Some questions to Tyler Littlefield, who started this thread. Q1 -- Did you get any constructive feedback on your code? I did get some, which I appreciated. someone mentioned using PyLint. From reading, I found it was really really pedantic, so I used PyFlakes instead. Q2 -- Did you feel that the process of submitting your code for review met your expectation? There wasn't much more to review, so yes. The info I got was helpful and farther than it was before I started. Q3 -- Would you recommend others doing this either on this forum or other fora? It appears to me - third party watching the ongoing dialog - that the tread has gone right off topic (some time ago) and someone should really start a new thread under a new title/subject. Most of what I have read does not appear to be discussing your code or how you could improve your code. I basically just stopped after a while. It got into a my language is better than your language, so I didn't see much constructive info. I've started reading from the bottom though, where it looks like it's back, and I do appreciate the rest of the info given, as well. Thanks again for the feedback. Following the last few posts, I was wondering whether some other off-list dialog is going on or whether I am missing something. -- Take care, Ty http://tds-solutions.net The aspen project: a barebones light-weight mud engine: http://code.google.com/p/aspenmud He that will not reason is a bigot; he that cannot reason is a fool; he that dares not reason is a slave. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Sun, 01 Jul 2012 21:50:29 -0400, Devin Jeanpierre wrote: On Sun, Jul 1, 2012 at 9:28 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Technically, in Python is left-associative: a b c first evaluates a, not b or c. But it is left-associative under the rules of comparison operator chaining, not arithmetic operator chaining. Left-associativity is when a b c is equivalent to (a b) c. You're talking about evaluation order, which can be different. For example, hypothetically, (a b) c could evaluate c first, then b, then a. However, Python always evaluates operands left-to-right. A particular case where this comes into play is the ** operator, which is right-associative but still has a left-to-right evaluation order. Yes, you are right, my mistake. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Mon, 02 Jul 2012 12:04:29 +1000, Chris Angelico wrote: Chained comparisons in the Python sense may be rare in computer languages, but it is the standard in mathematics and hardly needs to be explained to anyone over the age of twelve. That is a terrible indictment on the state of programming language design. I'd say that proves that Python is a good language for expressing mathematics in, then. That's all. No. Python is a terrible language for expressing mathematics in. As you point out, I can't do things like: x = y+2 x*3 = y*4+7 print(x = %d, y = %d,x,y) and sensibly get x = 1, y = -1. But Python is an excellent language for expressing a series of comparisons in, which has applications beyond pure maths or algebra. For example: c first_word second_word == third_word x I'm sure I don't have to explain what that means -- that standard chained notation for comparisons is obvious and simple. In Python, you write it the normal way, as above. But some other languages force you into verbosity: (c first_word) and (first_word second_word) and (second_word == third_word) and (third_word x) Worst of all are those languages which allow you to write the expression as normal, but evaluate it in a way that you almost never want: the maximum number of bugs with the minimum convenience. This has nothing to do with algebra. It is about picking semantics for chained comparisons which is sensible and useful and matches what people expect from regular language. If you write 2+2 = 2*2 = 4, nearly everyone will agree that, yes, that is true. Interpreting it as 1 == 4 is neither sensible nor useful and it is certainly not what people expect. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Mon, Jul 2, 2012 at 6:11 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: c first_word second_word == third_word x I'm sure I don't have to explain what that means -- that standard chained notation for comparisons is obvious and simple. In Python, you write it the normal way, as above. But some other languages force you into verbosity: (c first_word) and (first_word second_word) and (second_word == third_word) and (third_word x) Uhh, actually you DO have to explain that, because I interpreted it quite differently: ((c first_word) and (first_word second_word)) == (third_word x) And even if you can prove that my interpretation is wrong, it's still plausible enough that I, as a programmer, would have to dive to the manual (or test in interactive interpreter) to find out which way the language evaluates this. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 07/02/2012 02:43 AM, Steven D'Aprano wrote: On Sun, 01 Jul 2012 09:35:40 +0200, Thomas Jollans wrote: This is simply wrong. The comparisons are not acting as binary operators. Of course they are. Take this chained comparison: Technically, yes - two-input operations are happening. Syntactically, no. Read my post. 1) What is the operator in this expression? Is it or == or something else? I think I've answered this - it's the combination. 2) What double-underscore special method does it call? Where is this mysterious, secret, undocumented method implemented? 3) Why do the Python docs lie that a b == c is exactly equivalent to the short-circuit expression (a b) and (b == c) with b evaluated once? 4) And how do you explain that the compiled byte code actually calls the regular two-argument binary operators instead of your imaginary three- argument ternary operator? In this context, I don't care what actually happens. I'm talking about how the code can be parsed (by the generic reader, not necessarily the python interpreter). -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 07/02/2012 03:28 AM, Steven D'Aprano wrote: We *really did have* somebody arguing that chained comparisons are Bad because you can't stick parentheses around bits of it without changing the semantics. That was an actual argument, not a straw-man. Ahem. It may have been sub-optimally phrased in a way that opened itself up to attack, but I was arguing that Python comparisons operators are anomalous because they're not associative. (and, going back to the root of the argument, this makes them Bad because Special cases aren't special enough to break the rules.) On Sun, 01 Jul 2012 21:50:29 -0400, Devin Jeanpierre wrote: On Sun, Jul 1, 2012 at 9:28 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Technically, in Python is left-associative: a b c first evaluates a, not b or c. But it is left-associative under the rules of comparison operator chaining, not arithmetic operator chaining. Left-associativity is when a b c is equivalent to (a b) c. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 7/2/2012 1:20 AM, Dennis Lee Bieber wrote: Obviously, someone coming over from VB or R or any other single language x who hasn't read the Python reference is going to be surprised as something or other. So what. The manuals, including the tutorial, are there for a reason. The main points of the language take just a few hours to review. Perhaps my advantage learning Python was that I had written code in over 10 other languages and dialects and so had few expectations and made few assumptions. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Jul 2, 3:20 am, Chris Angelico ros...@gmail.com wrote: On Mon, Jul 2, 2012 at 6:11 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: c first_word second_word == third_word x I'm sure I don't have to explain what that means -- that standard chained notation for comparisons is obvious and simple. In Python, you write it the normal way, as above. But some other languages force you into verbosity: (c first_word) and (first_word second_word) and (second_word == third_word) and (third_word x) Uhh, actually you DO have to explain that, because I interpreted it quite differently: ((c first_word) and (first_word second_word)) == (third_word x) Poor Chris. That's because you've been brainwashed into believing you must spoon feed your interpreter to get your code working correctly. Stop applying these naive assumptions to Python code. Python knows when you reach the end of a statement, no need for redundant semicolons! Python knows when its reached the end of block and needs to drop back one level, no need for redundant road signs. Python knows Chris; Python KNOWS! -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, Jul 3, 2012 at 1:57 AM, Rick Johnson rantingrickjohn...@gmail.com wrote: Poor Chris. That's because you've been brainwashed into believing you must spoon feed your interpreter to get your code working correctly. Stop applying these naive assumptions to Python code. Python knows when you reach the end of a statement, no need for redundant semicolons! Python knows when its reached the end of block and needs to drop back one level, no need for redundant road signs. Python knows Chris; Python KNOWS! Why poor, Ralph? I am poor in the essence of ignorance's bliss, rich only in the never-ending thirst for knowledge and more languages. In me there meet a combination of antithetical elements which are at eternal war with one another... I hope I make myself clear, lady? Oops, wrong mailing list. Near enough. Python is not magic. It's not that it knows when I reach the end of a statement; it simply rules that line ends correspond to statement ends unless ordered otherwise. It has been told that the reduction of indentation level is a lexer token. Rick, do you realize that you have to spoon-feed the interpreter with spaces/tabs when other interpreters just KNOW to drop back an indentation level when you close a brace? /troll I simply need to make sure that the interpreter and I have the same understanding of the code. It will then work correctly. There's nothing special about one syntax or another, they're all just communication from my brain to a CPU, and different syntaxes are suited to different tasks. There's nothing inherently wrong with: right_length = len(x) 5, 20 being a valid way of expressing a double condition. It puts the query first and the bounds after it, so hey, it's justifiably sane. (No, I'm not advocating adding this. It's just for argument's sake.) Whatever you're writing with, you need to have the same rules in your head as the compiler/interpreter uses; beyond that there's a huge amount of personal preference (I quite like braces, myself, but many others don't) and only a relatively small amount of actual logic (use ASCII mathematical symbols to represent mathematical operations). ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Jun 30, 9:06 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sun, 01 Jul 2012 00:05:26 +0200, Thomas Jollans wrote: Yes. My sole point, really, is that normally, one would expect these two expressions to be equivalent: a b c (a b) c Good grief. Why would you expect that? You can't just arbitrarily stick parentheses around parts of expressions and expect the result to remain unchanged. Order of evaluation matters: 2**3**4 != (2**3)**4 Yes but as Chris points out in the next message, you can inject the following parenthesis without changing a thing!: py 1 + 3 * 4 13 py 1 + (3 * 4) 13 Of course i understand the rules of operator precedence, however i have never liked them AND i continue to believe that such functionality breeds bugs and is in fact bad language design. I believe all evaluations should be cumulative: py 1 + 3 * 4 should ALWAYS equal 16! With parenthesis only used for grouping: py a + (b*c) + d Which seems like the most consistent approach to me. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, Jul 3, 2012 at 1:16 AM, Rick Johnson rantingrickjohn...@gmail.com wrote: py 1 + 3 * 4 should ALWAYS equal 16! With parenthesis only used for grouping: py a + (b*c) + d Which seems like the most consistent approach to me. Oh yes, absolutely consistent. Consistency. It's a CR 1/2 monster found on page 153 of the 3.5th Edition Monster Manual. Let's see. By your principle, we should evaluate the ** before the - in: 2**-1 Have fun. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Jul 2, 11:42 am, Chris Angelico ros...@gmail.com wrote: Rick, do you realize that you have to spoon-feed the interpreter with spaces/tabs when other interpreters just KNOW to drop back an indentation level when you close a brace? Yes. And significant white space is my favorite attribute of Python source code. But the difference here is like night and day. While your getting bogged down playing match-the-brackets, i'm writing code and being productive. I don't need to put any mental effort into pressing the Enter+Tab keys. On the contrary, you must constantly break your mental focus to corral the braces, and the sad part is, you're still formatting your code like mine (with tabs and newlines!) however your simultaneously juggling superfluously archaic syntax! Why Chris? WHY? I simply need to make sure that the interpreter and I have the same understanding of the code. It will then work correctly. There's nothing special about one syntax or another, I agree in the sense of: to each his own. However. There are methods of writing code that are more productive, and methods that are less productive, and your emotive agenda of defending such nostalgic pedantry is quite self-defeating. they're all just communication from my brain to a CPU, and different syntaxes are suited to different tasks. There's nothing inherently wrong with: right_length = len(x) 5, 20 Agreed. I wish we had one language. One which had syntactical directives for scoping, blocks, assignments, etc, etc... BLOCK_INDENT_MARKER - \t BLOCK_DEDENT_MARKER - \n STATEMENT_TERMINATOR - \n ASSIGNMENT_OPERATOR - := CONDITIONAL_IF_SPELLING - IF CONDITIONAL_ELSE_SPELLING - EL ... (I quite like braces, myself, [...] and only a relatively small amount of actual logic. So you have a penchant for confinement and an aversion to logic? Hmm, interesting! -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On 07/02/2012 08:22 PM, Rick Johnson wrote: Agreed. I wish we had one language. One which had syntactical directives for scoping, blocks, assignments, etc, etc... BLOCK_INDENT_MARKER - \t BLOCK_DEDENT_MARKER - \n STATEMENT_TERMINATOR - \n ASSIGNMENT_OPERATOR - := CONDITIONAL_IF_SPELLING - IF CONDITIONAL_ELSE_SPELLING - EL ... You must be joking. In C, for example, it is possible to create your own language by going #define IF(cond) if (cond) { #define ELSE } else { #define ELIF(cond) } else if (cond) { #define ENDIF } and so on. There's a reason nobody does it. -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Sat, Jun 30, 2012 at 2:50 PM, Thomas Jollans t...@jollybox.de wrote: Which of the two comparisons is done first anyway? In the face of ambiguity, refuse the temptation to guess. I would consider that a pro, not a con, because the C-like way is much worse in this regard. Using operator chaining, is 1 2 3 equivalent to: 1 2 and 2 3 # assuming left-to-right evaluation order for and 2 3 and 1 2 The former seems pretty obvious to me (since it more closely matches the original syntax) and also turns out to be correct, but more to the point, most of the time it really doesn't matter which is evaluated first. It's only relevant if: a) your comparison operator has side-effects (bad programmer! bad!); or b) one of the comparisons is significantly faster than the other -- but since usually both comparisons will be of the same type (e.g. both comparing two numbers), this is also a corner case. On the other hand, using the C-like interpretation, is 1 2 3 equivalent to: (1 2) 3 1 (2 3) I would guess the former is more common, but I really have no basis for that guess beyond some experience with languages that use this syntax. I can see no particular advantages to either interpretation and can certainly imagine that some languages might choose the latter instead. Moreover, the distinction actually matters in this case, because the first expression is true (at least in Python) while the second is false. I will take ambiguity that is mostly unimportant over ambiguity that is critical to the meaning of the expression any day of the week. Cheers, Ian -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Jul 2, 2:06 pm, Thomas Jollans t...@jollybox.de wrote: On 07/02/2012 08:22 PM, Rick Johnson wrote: Agreed. I wish we had one language. One which had syntactical directives for scoping, blocks, assignments, etc, etc... BLOCK_INDENT_MARKER - \t BLOCK_DEDENT_MARKER - \n STATEMENT_TERMINATOR - \n ASSIGNMENT_OPERATOR - := CONDITIONAL_IF_SPELLING - IF CONDITIONAL_ELSE_SPELLING - EL ... You must be joking. Well i was slightly serious, but mostly sarcastic. Whist customizable syntax would be a great benefit to the individual, it would be a nightmare to the community -- the real solution lies in assimilation! I am reminded of a story: A few years back a very nice old woman offered to give me her typewriter. She said: i might need to type a letter one day and it would good to have around. It was a nice typewriter for 1956, but she had no idea her little machine was reduced to no less than a paper weight thanks to something called the PC. Her machine had been extinct for decades. Effectually, SHE had been extinct for decades. When i hear people like Chris evangelizing about slavish syntax, i am reminded of the nice old lady. Her intentions where virtuous, however her logic was flawed. She is still clinging to old technology. Like the Luddites she refuses to see the importance technological advancements. And by harboring this nostalgia she is actually undermining the future evolution of an entire species. Lifespans are limited for a very important evolutionary reason! -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, Jul 3, 2012 at 5:06 AM, Thomas Jollans t...@jollybox.de wrote: On 07/02/2012 08:22 PM, Rick Johnson wrote: Agreed. I wish we had one language. One which had syntactical directives for scoping, blocks, assignments, etc, etc... BLOCK_INDENT_MARKER - \t BLOCK_DEDENT_MARKER - \n STATEMENT_TERMINATOR - \n ASSIGNMENT_OPERATOR - := CONDITIONAL_IF_SPELLING - IF CONDITIONAL_ELSE_SPELLING - EL ... You must be joking. In C, for example, it is possible to create your own language by going #define IF(cond) if (cond) { #define ELSE } else { #define ELIF(cond) } else if (cond) { #define ENDIF } and so on. There's a reason nobody does it. I'll go one further. The create your own language is just a plain text file, is in fact is NO LANGUAGE. If it's that flexible, what's the use of calling it the same language? Actually there is a lot of use in having that sort of commonality, but at a different level: source control. Tools like git are language-agnostic; I can have a repository with Javascript, PHP (ugh), Pike (that atones), Python, C++, etc source files, a single makefile that in the darkness binds them, and so on. But they're still all different languages. Oh and Rick? Nice troll there with the ellipsis. You fail grammar forever, but hey, at least you win at trolling. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, 03 Jul 2012 02:55:48 +1000, Chris Angelico wrote: On Tue, Jul 3, 2012 at 1:16 AM, Rick Johnson rantingrickjohn...@gmail.com wrote: py 1 + 3 * 4 should ALWAYS equal 16! With parenthesis only used for grouping: py a + (b*c) + d Which seems like the most consistent approach to me. Oh yes, absolutely consistent. Consistency. It's a CR 1/2 monster found on page 153 of the 3.5th Edition Monster Manual. GvR is fond of quoting Ralph Waldo Emerson: A foolish consistency is the hobgoblin of little minds. Perhaps the world would be better off if mathematicians threw out the existing precedence rules and replaced them with a strict left-to-right precedence. (Personally, I doubt it.) But until they do, consistency with mathematics is far more important than the foolish consistency of left-to-right precedence. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, Jul 3, 2012 at 10:57 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Tue, 03 Jul 2012 02:55:48 +1000, Chris Angelico wrote: Oh yes, absolutely consistent. Consistency. It's a CR 1/2 monster found on page 153 of the 3.5th Edition Monster Manual. GvR is fond of quoting Ralph Waldo Emerson: A foolish consistency is the hobgoblin of little minds. Yeah, that's what I was referring to. Dungeons and Dragons has specs for a hobgoblin warrior :) Perhaps the world would be better off if mathematicians threw out the existing precedence rules and replaced them with a strict left-to-right precedence. (Personally, I doubt it.) But until they do, consistency with mathematics is far more important than the foolish consistency of left-to-right precedence. And if they ever do, it'll break consistency with past centuries of mathematical writing. Imagine (taking this to another realm) that it's decided that since Wolfram is now called Tungsten, it should have the chemical symbol 'T' instead of 'W'. This is far more consistent, right? And Iron should be I, not Fe. We'll move Iodine to Io (and Europium to Europa and Gallium to Ganymede?), and tritium (the isotope of hydrogen) can become H3. It'd make today's chemistry notes look as archaic and unreadable as those using alchemical symbols, only the actual symbols are the same, making it ambiguous. Nope. Better to stick with what's standardized. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, 3 Jul 2012 11:22:55 +1000 Chris Angelico ros...@gmail.com wrote: On Tue, Jul 3, 2012 at 10:57 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Perhaps the world would be better off if mathematicians threw out the existing precedence rules and replaced them with a strict left-to-right precedence. (Personally, I doubt it.) But until they do, consistency with mathematics is far more important than the foolish consistency of left-to-right precedence. And if they ever do, it'll break consistency with past centuries of mathematical writing. Imagine (taking this to another realm) that it's decided that since Wolfram is now called Tungsten, it should have the chemical symbol 'T' instead of 'W'. This is far more consistent, right? And Iron should be I, not Fe. We'll move Iodine to Io (and Europium to Europa and Gallium to Ganymede?), and tritium (the isotope of hydrogen) can become H3. It'd make today's chemistry notes look as archaic and unreadable as those using alchemical symbols, only the actual symbols are the same, making it ambiguous. Nope. Better to stick with what's standardized. I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. Music is another field which could do with a metrification: I get tired of explaining to beginners why there's no B#, except when it's C. Check out http://musicnotation.org If legacy systems get too far out of sync with current practice, they become an unnecessary layer of complexity and a hurdle to understanding, and at some point you have to take the plunge, old books be damned. -- John -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Tue, 03 Jul 2012 12:25:59 +1000, John O'Hagan wrote: On Tue, 3 Jul 2012 11:22:55 +1000 Chris Angelico ros...@gmail.com wrote: On Tue, Jul 3, 2012 at 10:57 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Perhaps the world would be better off if mathematicians threw out the existing precedence rules and replaced them with a strict left-to-right precedence. (Personally, I doubt it.) But until they do, consistency with mathematics is far more important than the foolish consistency of left-to-right precedence. And if they ever do, it'll break consistency with past centuries of mathematical writing. Imagine (taking this to another realm) that it's decided that since Wolfram is now called Tungsten, it should have the chemical symbol 'T' instead of 'W'. This is far more consistent, right? And Iron should be I, not Fe. We'll move Iodine to Io (and Europium to Europa and Gallium to Ganymede?), and tritium (the isotope of hydrogen) can become H3. It'd make today's chemistry notes look as archaic and unreadable as those using alchemical symbols, only the actual symbols are the same, making it ambiguous. Nope. Better to stick with what's standardized. I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. Don't mistake tradition for consistency. There's little consistency in the legacy weights and measures used before the metric system. The introduction of the Imperial system in 1824 at least got rid of *some* of the more wacky measures, and standardised the rest, but there was still damn little consistency: e.g. a finger was 7/8 of an inch, and an ell was 45 inches, meaning an ell is 39 and 3/8th fingers. One of my favourites is the league, which in the Middle Ages was actually defined as the distance that a man, or a horse, could walk in an hour. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Jul 3, 7:25 am, John O'Hagan resea...@johnohagan.com wrote: I agree to some extent, but as a counter-example, when I was a child there a subject called Weights and Measures which is now redundant because of the Metric system. I don't miss hogsheads and fathoms at all. Music is another field which could do with a metrification: I get tired of explaining to beginners why there's no B#, except when it's C. Check outhttp://musicnotation.org You assume that equal temperament is the only way to have music. Apart from the fact that there are non-tempered musics all over the world, even Bach Mozart and Beethoven did not write for/to equal temperament. In a pure/untempered C-scale A-flat is almost half a semitone sharper than G-sharp -- 8/5 vs 25/16. Similar for standardized languages: Python's indentation is nice -- except when you have to embed it into say, html -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
rusi rustompm...@gmail.com writes: Similar for standardized languages: Python's indentation is nice -- except when you have to embed it into say, html If you can't write a ‘pre’ element for pre-formatted text, you don't have HTML URL:http://www.w3.org/TR/html401/struct/text.html#h-9.3.4. -- \ “Pinky, are you pondering what I'm pondering?” “Uh, I think so, | `\ Brain, but we'll never get a monkey to use dental floss.” | _o__) —_Pinky and The Brain_ | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Sun, 01 Jul 2012 14:23:36 +1000, Chris Angelico wrote: On Sun, Jul 1, 2012 at 2:17 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Nonsense. Of course parens change the evaluation of the expression. That's what parens are for! The whole point of my example was that it wouldn't. Yes, you can find specially crafted examples where adding parentheses in certain places, but not others, doesn't change the overall evaluation of the expression. So what? IN GENERAL, adding parentheses changes the evaluation of the expression -- that is what they are for. Therefore, IN GENERAL you should expect that adding parentheses will change the result, unless you carefully place them where you know that they will have no effect. Even in C, I can't just do this: 2+3*4 = (2+3)*4 with the expectation that you can stick parentheses around the left-most term without changing the value. The fact that you can do for some expressions is irrelevant. In general, if you don't know the semantics of an expression (including the operator precedence), you cannot just assume that adding parens is harmless. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Sun, Jul 1, 2012 at 4:27 PM, Steven D'Aprano steve+use...@pearwood.info wrote: Yes, you can find specially crafted examples where adding parentheses in certain places, but not others, doesn't change the overall evaluation of the expression. My point was that adding parentheses around the tightest-binding operator is a common, clear, and usually insignificant, way of demonstrating operator precedence. So FOR THAT USE they must not change evaluation of the expression. Obviously if you put them anywhere else, they change evaluation. Nice job knocking down a straw man. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Sun, 01 Jul 2012 13:48:04 +1000, Chris Angelico wrote: On Sun, Jul 1, 2012 at 1:23 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: All the worse for those languages, since they violate the semantics of mathematical notation. Not so. It simply means that booleans are nothing special. In REXX, there are no data types at all, and 1 and 0 are your booleans. In C, boolean and comparison operations return integers, either 1 or 0. This has nothing to do with the presence of a Boolean type or not. It is about syntax, not types. Python didn't have bools until relatively recently but it still had chained comparisons. In Python2.1 and older, boolean and comparison operations return integers, either 1 or 0, precisely the same as C. You can even use chained comparisons for types that don't interpret the operators as comparisons: py class Funny: ... def __init__(self, x): ... self.x = x ... def __lt__(self, other): ... return Funny(self.x + 3*other.x) ... def __str__(self): ... return str(self.x) ... py a = Funny(2) py b = Funny(3) py c = Funny(4) py py print a b c 15 py print (a b) and (b c) 15 Although the interpretation of such may not be useful. Same was true of Python early on, if I understand correctly. It's not shameful. The first public release of Python, 0.9, included chained comparisons. This was even before the language had == for equality tests! steve@runes:~$ ./python0.9.1 print 2 3 4 1 print 2 = 2 = 2 1 print (2 = 2) = 2 0 So no, Python has always included chained comparisons, and yes, it is shameful that a language would force you to unlearn standard notation in favour of a foolish consistency with other operators. Comparisons aren't special because they return bools. They are special because of the way they are used. C treats comparison operators as if they were arithmetic operators, and so the behaviour of a chained comparison is the same as the behaviour as a sequence of arithmetic operators: a foolish consistency. Python treats comparison operators as comparison operators, and gives them behaviour appropriate to comparisons. The fact that so many languages do the wrong thing here, and so few emulate standard mathematical notation, is symptomatic of the lousy state of language design. Pascal might be verbose, but at least it makes it harder to write code that silently does the wrong thing -- it prevents you from writing chained comparisons which do the wrong thing, and forces you to be explicit. C has the worst of both worlds: - it allows the standard concise mathematical notation a x b - but it quietly changes the semantics to something that the user hardly ever wants thus giving the maximum number of bugs with the minimum amount of convenience. The more I learn about C, the less I want to know about C. What sort of crazy language designer thought that having 2 == 2 == 2 return 0 (false) was a good idea? It makes perfect sense though; Not in English-speaking countries with a culture of writing chained comparisons in mathematics and allowing them in natural language: Rock is beaten by Paper, is beaten by Scissors. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: code review
On Sun, Jul 1, 2012 at 4:54 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Not in English-speaking countries with a culture of writing chained comparisons in mathematics and allowing them in natural language: Rock is beaten by Paper, is beaten by Scissors. I would write that as: Rock is beaten by Paper, and beats Scissors. That's natural language. Unless you put a which in the middle, the grammar of English demands that the subject be common, not a promoted object. ChrisA -- http://mail.python.org/mailman/listinfo/python-list