Ifs and assignments
Hi, This is my debut on this list. In many languages, such as C, one can use assignments in conditionals and expressions. The most common, and useful case turns up when you have if/else if/else if/else constructs. Consider the following non-working pseudoPython. import re r1 = re.compile("hello (\d)") r2 = re.compile("world([!?])") w = "hello world!" if m = r1.search(w): handleMatch1(m) elif m = r2.search(w): handleMatch2(m) else: print("No match") If the regular expressions are complex, running them multiple times (once to test, another to capture groups) isn't ideal. On the other hand, at present, one has to either do: m = r1.search(w) if m: handleMatch1(m) else: m = r2.search(w) if m: handleMatch2(m) else: print("No match") if not running unnecessary matches, yet capturing groups in the event of a successful match, is what is desired. If there are multiple tests, the indentation gets silly. This arises because having removed the ability to assign in an expression, there is no way to save the result of a function call that is used in a conditional at all. I am aware that this facility in C is a source of bugs, = being only a typo away from the more common ==. With exceptions and contexts, we have: with open("file") as f: doSomethingWith(f) try: trySomething() except SomethingRandomGoingWrong as e: lookAtException(e) What I am wondering is why not use a similar syntax with if, so that one could do if r1.search(w) as m: g = m.groups() print(g[1]) This would remove the risk of errors by typos since the syntax for equality testing (if x == y:) is completely different from that for assigning in a conditional (which would look like 'if y as x:' Related would be to have Nonetype work with contexts such that with None as x: doStuff(x) would do nothing. This would allow things like: with maybeGetSomething as x: doStuff(x) to call doStuff(x) within a context of maybeGetSomething returns something, or do nothing if nothing is returned. (Adding an else-like keyword to with, or possibly using else in that context, would allow one to process a non-None object if returned, or else do something in response to a None object being returned by the maybeGetSomething.) Just a thought. Or what is the current 'Pythonic' way to do something like: if x = func1(): do1(x) elif x = func2(): do2(x) elif x = func3(): do3(x) elif x = func4(): do4(x) else: do5() where each of func1,func2,func3,func4 have side effects so that func2 is tested if and only if func1 returns a false value, func1 must be called only once, and what is returned from func1 must be available to the code inside the if block? John -- https://mail.python.org/mailman/listinfo/python-list
Re: Ifs and assignments
The point of my original post was that, whilst C's if( x = 2 ) { do something } and if( x == 2 ) { do something } are easy to confuse, and a source of bugs, having a construct like follows: if x == 2: do something # what happens at present if testFunc() as x: do something with x using the 'as' syntax that appears with 'with' and 'except', would allow for the advantages of C style assignments in conditionals but without the easy confusion, since here the syntax is significantly different between assignment and equality testing (rather than a character apart as happens with C). This occurs further down in my original post (past the point where you inserted your reply). Another post suggested a workaround by defining a 'pocket' class, for which I am grateful. John On 02/01/2014 19:27, Gary Herron wrote: On 01/02/2014 09:20 AM, John Allsup wrote: Hi, This is my debut on this list. In many languages, such as C, one can use assignments in conditionals and expressions. The most common, and useful case turns up when you have if/else if/else if/else constructs. Consider the following non-working pseudoPython. import re r1 = re.compile("hello (\d)") r2 = re.compile("world([!?])") w = "hello world!" if m = r1.search(w): This kind of thing in C/C+ has always been the source of much confusion and potential errors, because the construct is so similar to an "==" test. Python does not replicate this potential for confusion. Instead, we use two lines of code, an assignment and then the test. If you find that extra line of code inconvenient than at least you can take comfort in the fact that it is clearer code. If you are still not convinced, ... then sorry, that's just the way Python is. Gary Herron handleMatch1(m) elif m = r2.search(w): handleMatch2(m) else: print("No match") If the regular expressions are complex, running them multiple times (once to test, another to capture groups) isn't ideal. On the other hand, at present, one has to either do: m = r1.search(w) if m: handleMatch1(m) else: m = r2.search(w) if m: handleMatch2(m) else: print("No match") if not running unnecessary matches, yet capturing groups in the event of a successful match, is what is desired. If there are multiple tests, the indentation gets silly. This arises because having removed the ability to assign in an expression, there is no way to save the result of a function call that is used in a conditional at all. I am aware that this facility in C is a source of bugs, = being only a typo away from the more common ==. With exceptions and contexts, we have: with open("file") as f: doSomethingWith(f) try: trySomething() except SomethingRandomGoingWrong as e: lookAtException(e) What I am wondering is why not use a similar syntax with if, so that one could do if r1.search(w) as m: g = m.groups() print(g[1]) This would remove the risk of errors by typos since the syntax for equality testing (if x == y:) is completely different from that for assigning in a conditional (which would look like 'if y as x:' Related would be to have Nonetype work with contexts such that with None as x: doStuff(x) would do nothing. This would allow things like: with maybeGetSomething as x: doStuff(x) to call doStuff(x) within a context of maybeGetSomething returns something, or do nothing if nothing is returned. (Adding an else-like keyword to with, or possibly using else in that context, would allow one to process a non-None object if returned, or else do something in response to a None object being returned by the maybeGetSomething.) Just a thought. Or what is the current 'Pythonic' way to do something like: if x = func1(): do1(x) elif x = func2(): do2(x) elif x = func3(): do3(x) elif x = func4(): do4(x) else: do5() where each of func1,func2,func3,func4 have side effects so that func2 is tested if and only if func1 returns a false value, func1 must be called only once, and what is returned from func1 must be available to the code inside the if block? John -- https://mail.python.org/mailman/listinfo/python-list
Re: How to write this as a list comprehension?
Hi, I'd agree with the advice that it's not the best idea: readability sucks here, but consider the following: import time def somefunc(a,b,c,d): # dummy function return "{} - {} - {} : {}".format(a,b,c,d) l = [(time.time(),"name {}".format(n)) for n in range(100)] # dummy data # the line in question labels = [somefunc(*(lambda t,n: (t.tm_mon,t.tm_mday,t.tm_wday,n))(time.localtime(x[0]),x[1])) for x in l] print(labels) # just to see the result If you find that hard to decipher, the consider the maintainability of code you write that uses such comprehensions. You need to include comments that explain what this does, and it is easier to write a longhand version using .append() and variable assignments. I presume performance won't be an issue determining the right approach, since then you'd be using C or C++. John On 17/01/2014 23:49, Dan Stromberg wrote: On Fri, Jan 17, 2014 at 3:19 PM, Piet van Oostrum wrote: Hi, I am looking for an elegant way to write the following code as a list comprehension: labels = [] for then, name in mylist: _, mn, dy, _, _, _, wd, _, _ = localtime(then) labels.append(somefunc(mn, day, wd, name)) My recomendation: Don't use a list comprehension. List comprehensions and generator expressions are great for quick little things, but become less readable when you have to string them over multiple physical lines. labels = [somefunc(mn, day, wd, name) for then, name in mylist for _, mn, dy, _, _, _, wd, _, _ in [localtime(then)]] -- https://mail.python.org/mailman/listinfo/python-list
Top down Python
What is needed for proper learning is near-absolute simplicity. Even one toy too many to play with is an intolerable distraction, but one too few massively hampers learning and induces boredom. I want to be able to say: 1. Put a nice picture on the background. 2. Put a terminal window with, say, 64x20 lines, dead centre. 3. Run a simple REPL program written in Python or Ruby within it. I do not really want to write any more lines of code than I need to. Why do we not have langauges and libraries that can do the above with only five lines of code (line 0 == setup, line 4 == cleanup). Programming should be that efficient if we learn to make things beautiful and not tolerate wastes of lines and characters, on a global scale as well as locally to our projects. Consider #!/usr/bin/env python3 from myappfw import app from myapp1 import repl app.background = "Moutains1" t = app.terminal.open(title="Typing commands One Oh One",position="centre", width="80%",height="72%",rows="20",columns="64") exit(t.run(repl)) What Python would I need to write, as concise but readable as practically possible, so that the above program works as desired (for any repl that obeys the basic input-process-output behaviour of a repl)? This is top-down design done right IMO (as described in Thinking Forth, by the way). -- https://mail.python.org/mailman/listinfo/python-list
Re: Top down Python
I've realised that the best way to do this is to use a web browser for the graphical front end: high end graphics are simply not a necessity here, so one does not need to leave the confines of the browser. Thus we need a simple server script. I'm still minimalist, so I guess we want xmlrpc and a python server, with a bit of javascript in the browser to sort out the drawing end. This now seems way simpler than trying to play with Gtk or Qt. Basically the lesson is to use a web browser engine as a graphics engine unless you have performance issues. Hopefully in future html rendering engines will not be so strongly coupled to browsers, or even to the html format itself, but will be a general purpose user graphics engine (an ncurses for bitmapped displays). Can anybody suggest the quickest way to learn the bits of xmlrpc (in python) that I need to do this. Once it's working, I'll stick a source code download on my website. There will be only one version released: the one that works properly. Thus there is no need to github this. All the best, def my_sig(): print("--") print(signame(['n','o','h',uppercase('j')]).written_backwards) On 12/02/2014 07:05, John Allsup wrote: What is needed for proper learning is near-absolute simplicity. Even one toy too many to play with is an intolerable distraction, but one too few massively hampers learning and induces boredom. I want to be able to say: 1. Put a nice picture on the background. 2. Put a terminal window with, say, 64x20 lines, dead centre. 3. Run a simple REPL program written in Python or Ruby within it. I do not really want to write any more lines of code than I need to. Why do we not have langauges and libraries that can do the above with only five lines of code (line 0 == setup, line 4 == cleanup). Programming should be that efficient if we learn to make things beautiful and not tolerate wastes of lines and characters, on a global scale as well as locally to our projects. Consider #!/usr/bin/env python3 from myappfw import app from myapp1 import repl app.background = "Moutains1" t = app.terminal.open(title="Typing commands One Oh One",position="centre", width="80%",height="72%",rows="20",columns="64") exit(t.run(repl)) What Python would I need to write, as concise but readable as practically possible, so that the above program works as desired (for any repl that obeys the basic input-process-output behaviour of a repl)? This is top-down design done right IMO (as described in Thinking Forth, by the way). -- https://mail.python.org/mailman/listinfo/python-list
Re: Top down Python
Hi, Current software development methods make things way more complex than they need to be. I am trying to get an idea for how simple things can be from final product down to low level implementation, hoping to recover the code density miracles that the old school Forthers turned out ages ago. They outlined a philosophy that I wish to bring back to life. This is the beginning of my first attempt, and I wish to do this in the full gaze of fellow Pythoners so that any mistakes I make can be seen by others, and any lessons learned passed on as cheaply and efficiently (in terms of real world work and energy) as possible. Hope this starts to clarify the picture I have in my head. All the best, John On 12/02/2014 07:42, Chris Angelico wrote: On Wed, Feb 12, 2014 at 6:05 PM, John Allsup wrote: 1. Put a nice picture on the background. 2. Put a terminal window with, say, 64x20 lines, dead centre. 3. Run a simple REPL program written in Python or Ruby within it. I do not really want to write any more lines of code than I need to. Why do we not have langauges and libraries that can do the above with only five lines of code (line 0 == setup, line 4 == cleanup). #!/bin/sh xfce4-terminal --geometry=64x20 -x python3 There you are, two lines. :) Seriously though, what you're asking is deceptively simple yet incredibly difficult. You're trying to recreate the entire structure of a terminal emulator or telnet client. I can show you the code for a MUD client, which does a lot of what you're looking for; in fact, this one has a REPL inbuilt (not Python or Ruby though): https://github.com/Rosuav/Gypsum/ That's roughly how much code it takes to make a reasonably usable replicant of a terminal window. (Some of that is specific to networking and MUDding, but at very least, window.pike is basically all about the visuals.) You'll do far better to make use of someone else's terminal renderer, and just put a desktop background to make your fancy image. Otherwise, you have to recreate everything - console output (complete with color, presumably), scrolling, input history (you can get most of your editing keys easily enough, but you will need command history), clipboard operations, and somewhere along the way, performance. Save yourself a whole mess of trouble and just use your OS-provided terminal program :) Actually, for what you're looking at, IDLE is probably close to what you want. You could have a look at how much code it takes to power IDLE, and/or just use it as is. It's pretty handy; I use it as my primary interactive Python on Windows. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Top down Python
Hi, I'm trying to figure out where 'simpler' stops and 'too simplistic' begins. That's what I call 'absolute simplicity'. It is a necessity in some areas of learning where even a jot of inefficiency can be costly (consider a superconducting magnet just below the critical frequency with massive amps going through, and then it heats slightly, for a picture of how this 'blow up' happens in the real world). This is an exercise in trying to 'touch the wall'. When the possibilities are not infinite, merely an unimaginably large finite number, eventually a discrete 'wall' must exists and, thus, ought to be findable. John On 12/02/2014 08:09, Ben Finney wrote: John Allsup writes: What is needed for proper learning is near-absolute simplicity. I think that's too simplistic :-) but I'll take it as merely a preference on your part for simplicity at this time. I want to be able to say: 1. Put a nice picture on the background. 2. Put a terminal window with, say, 64x20 lines, dead centre. Those are deeply dependent on exactly what operating system and desktop environment and window manager your computer is running. What exact values for those variables do you want the simple program to assume? No cross-platform standard library (such as the Python standard library) will be able to reliably do those things without making a huge amount of assumption of the operating environment, much of which will be wrong for a large number of users. If you can fix each of those things precisely so that you can ignore all other possible values, then you can probably come up with a simple program to do them. 3. Run a simple REPL program written in Python or Ruby within it. Python has its own REPL, of course; you get it when you run ‘python’ from a command line. Simple! If, on the other hand, you want a REPL that plugs into something *other than* Python, what do you want it to plug into? You have a Python REPL already, so if you want something else you'll need to be specific. I do not really want to write any more lines of code than I need to. For what goal? Python optimises your lines of code for *communicating with other programmers*, which in my view is pretty close to the most important variable to be optimising. -- https://mail.python.org/mailman/listinfo/python-list