Re: Python3 - How do I import a class from another file
Terry, > Not really. The resulting global objects do not normally take enough > space to worry about on normal modern desktops. For some reason I still aim to keep my (running) programs as small as possible - even though the ammount of memory has grown more than a thousandfold since I started programming. Old habits die hard. > Standard for in-file test is [snip] Any reason to put the testcode in a procedure instead of just have it directly follow the "if __name__ == '__main__' " test ? > The PEP 8 convention (except for basic builtin data structures like int, > str, list, tuple, set, and dict) is TitleCase. Thanks. > Follow or not as you wish. :-) If I ever want/need to share my code with others (or post here as part of a question) it is a good idea to conform to certain standards to keep it easily readable. It will take some getting acustomed to though, as every language seems to have its own way to do it (I myself prefer single prefix chars to indicate the variables intended type). Regards, Rudy Wieser -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
DL, > Some of this you will know. (Hopefully) some will be 'new': Some of it is known to me, and indeed I do hope that there will be new stuff in there too. Its why I took up Python. :-) Thanks for the explanation (including the aliassing I wasn't aware of) and the links. Regards, Rudy Wieser -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
Greg, >>> Are you sure there's a difference between classes and functions here? >> >> Yes, quite sure. > > And we're even more sure that there isn't. :-) As it turned out "we're" are right, and I was thrown off by the error message. :-p The problem is that I had no idea why I got that (rather explicit) error message, and took it by its face-value - sending me of in the wrong direction. The actual caise ? I made a mistake by, in the testcode (which I had not blocked off) in the imported file creating an instance with the exact same name as the class. The deleting of that instance at the end of the testcode somehow caused the class to disappear as well, resulting in the "can't find it" error. To be honest, I was not aware/did not assume that I could delete a class definition that way (I even find it a bit weird, but as I'm a newbie in regard to Python that does not say much). Bottom line: I was caught by my own choice to give the instance the exact same name as the class. :-\ >You'll find that *any* form of import executes all the top-level code. Thats certainly something I did not expect. Regards, Rudy Wieser -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
On 9/12/19 9:15 pm, R.Wieser wrote: To be honest, I was not aware/did not assume that I could delete a class definition that way (I even find it a bit weird, but as I'm a newbie in regard to Python that does not say much). Python is very dynamic. The class statement is actually an executable statement that creates a class object and binds it to a name. There's nothing stopping you from subsequently rebinding that name to some other object, or deleting it altogether. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
On 12/9/2019 2:36 AM, R.Wieser wrote: Terry, Standard for in-file test is [snip] Any reason to put the testcode in a procedure instead of just have it directly follow the "if __name__ == '__main__' " test ? One can, for instance, interactively do >>> import mod >>> mod.test() and explore the contents of mod, perhaps depending on the result of test() def test(): ... also marks the code as test code rather than, for instance, command-line or setup code. Putting such alternative code in function 'main' has the same effect. For instance, 3.x has idlelib.__main__, which has something like from idlelib.pyshell import main main() so than one can run 3.x IDLE from a command line with 'python -m idlelib'. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
Python, > Child *depends* on Parent. I'm sorry, but without any kind of underbuilding statements like that are of no value to me I'm afraid. Also: if I can just copy-and-paste the class into the file which origionally included it and have the whole program run without a problem than that dependency upon its origional parent doesn't seem to mean all too much (if anything at all). Regards, Rudy Wieser -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
Greg, > There's nothing stopping you from subsequently rebinding that name to some > other object, or deleting it altogether. Which is something I did not expect. But running into is what makes doing something new interesting. :-) And I just realized something else: I just assumed that the "del instance" command did something more than it should, but there is a good chance that the mere action of creating an instance with the same name as the class made the classname disappear from the internal availability list, and not return after the instance (and I assume its name too) got deleted. Regards, Rudy Wieser -- https://mail.python.org/mailman/listinfo/python-list
python 3 prefix to infix without too many parethesis
Hi, I have got a problem. I wrote a code for prefix to infix. It works, but I need improve it so on input there will be only necessary parentheses. Can u help me? Here is the code: import re a = input() class Calculator: def __init__ (self): self.stack = [] def push (self, p): if p in ['+', '-', '*', '/', "**"]: op1 = self.stack.pop () op2 = self.stack.pop () self.stack.append ('(%s%s%s)' % (op1, p, op2)) print("op1 =", op1) print("op2 =", op2) print("p=", p) print(self.stack) else: self.stack.append (p) def convert (self, l): l.reverse () for e in l: self.push (e) return self.stack.pop () c = Calculator () print (c.convert (re.findall(r'\d+|\*\*|[-+*/]', a))) input is like /-*+*++**85 27 39 87 65 65 37 63 91 -- https://mail.python.org/mailman/listinfo/python-list
More efficient/elegant branching
Hello, I have a function with a long if/elif chain that sets a couple of variables according to a bunch of test expressions, similar to function branch1() below. I never liked that approach much because it is clumsy and repetetive, and pylint thinks so as well. I've come up with two alternatives which I believe are less efficient due to the reasons given in the respective docstrings. Does anybody have a better idea? def branch1(a, b, z): """Inelegant, unwieldy, and pylint complains about too many branches""" if a > 4 and b == 0: result = "first" elif len(z) < 2: result = "second" elif b + a == 10: result = "third" return result def branch2(a, b, z): """Elegant but inefficient because all expressions are pre-computed althogh the first one is most likely to hit""" decision = [ (a > 4 and b == 0, "first"), (len(z) < 2, "second"), (b + a == 10, "third")] for (test, result) in decision: if test: return result def branch3(a, b, z): """Elegant but inefficient because expressions need to be parsed each time""" decision = [ ("a > 4 and b == 0", "first"), ("len(z) < 2", "second"), ("b + a == 10", "third")] for (test, result) in decision: if eval(test): return result (env) [dh@deham01in015:~/python/rscl_fdc/devel]$ -- https://mail.python.org/mailman/listinfo/python-list
Re: More efficient/elegant branching
On Mon, Dec 9, 2019 at 10:36 PM Musbur wrote: > > Hello, > > I have a function with a long if/elif chain that sets a couple of > variables according to a bunch of test expressions, similar to function > branch1() below. I never liked that approach much because it is clumsy > and repetetive, and pylint thinks so as well. I've come up with two > alternatives which I believe are less efficient due to the reasons given > in the respective docstrings. Does anybody have a better idea? > > def branch1(a, b, z): > """Inelegant, unwieldy, and pylint complains > about too many branches""" > if a > 4 and b == 0: > result = "first" > elif len(z) < 2: > result = "second" > elif b + a == 10: > result = "third" > return result If the branches are completely independent, there's not really a lot you can do differently. I'd rewrite these as return statements rather than assigning to a variable and returning it at the end (which also allows you to make them 'if' rather than 'elif'), but that's a marginal gain. This is the sort of thing that tends to fall into the category of "inherent complexity" - the code is complex because the problem it's solving is complex. Imagine trying to write a function that tells you whether to hold or tap a button: def button_action(color, word): if color == "blue" and word == "Abort": return "Hold" if battery_count() > 1 and word == "Detonate": return "Tap" if color == "white" and "CAR" in indicators: return "Hold" if battery_count() > 2 and "FRK" in indicators: return "Tap" if color == "yellow": return "Hold" if color == "red" and word == "Hold": return "Tap" return "Hold" You might be able to simplify this very slightly, but the conditions are sufficiently varied that you can't really gain much, and they are strictly ordered. The code here has as much complexity as the problem it's solving, so you may as well just silence your linter's warnings and carry on. And yes, this sort of thing happens ALL THE TIME in real-world code. https://thedailywtf.com/articles/The-Mythical-Business-Layer IMO your code's fine. :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: More efficient/elegant branching
Musbur wrote: > Hello, > > I have a function with a long if/elif chain that sets a couple of > variables according to a bunch of test expressions, similar to function > branch1() below. I never liked that approach much because it is clumsy > and repetetive, and pylint thinks so as well. I've come up with two > alternatives which I believe are less efficient due to the reasons given > in the respective docstrings. Does anybody have a better idea? > > def branch1(a, b, z): > """Inelegant, unwieldy, and pylint complains > about too many branches""" > if a > 4 and b == 0: > result = "first" > elif len(z) < 2: > result = "second" > elif b + a == 10: > result = "third" > return result I agree with Chris that this is the way to go. pylint be damned ;) > > def branch2(a, b, z): > """Elegant but inefficient because all expressions > are pre-computed althogh the first one is most likely > to hit""" Also, it doesn't work in the general case, like decision = [ (a == 0, "first"), (b/a > 1, "second"), ... > decision = [ > (a > 4 and b == 0, "first"), > (len(z) < 2, "second"), > (b + a == 10, "third")] > for (test, result) in decision: > if test: return result > > def branch3(a, b, z): > """Elegant but inefficient because expressions > need to be parsed each time""" > decision = [ > ("a > 4 and b == 0", "first"), > ("len(z) < 2", "second"), > ("b + a == 10", "third")] > for (test, result) in decision: > if eval(test): return result You can shave off most of the overhead by precompiling the expressions: DECISIONS = [ ("a > 4 and b == 0", "first"), ("len(z) < 2", "second"), ("b + a == 10", "third") ] DECISIONS4 = [ (compile(expr, "", "eval"), result) for expr, result in DECISIONS ] def branch4(a, b, z): for test, result in DECISIONS4: if eval(test): return result raise ValueError Using lambdas instead of precompiled expressions is a tad faster: DECISIONS5 = [ (eval("lambda a, b, z: " + expr), result) for expr, result in DECISIONS ] def branch5(a, b, z): for test, result in DECISIONS5: if test(a, b, z): return result raise ValueError This is is a slippery slope as you might now consider building branch1() from the DECISIONS list... -- https://mail.python.org/mailman/listinfo/python-list
Re: Regarding problem in python 3.8.0 installation
On 08/12/2019 18:08, alok singh wrote: Sir, My system is windows 7 SP1 32-bit . after installing python in my system,when i try to launch it using command prompt then a message is shown. I am attaching a screenshot of the following. kindly look seriously into my problem and tell me the solution.. I'm afraid this is a text-only mailing list, so your screenshot has been stripped off before any of us could see it. Please could you copy and paste the text of the error message you receive. -- Rhodri James *-* Kynesim Ltd -- https://mail.python.org/mailman/listinfo/python-list
Re: More efficient/elegant branching
On 2019-12-09 12:27, Musbur wrote: > def branch1(a, b, z): > """Inelegant, unwieldy, and pylint complains > about too many branches""" > if a > 4 and b == 0: > result = "first" > elif len(z) < 2: > result = "second" > elif b + a == 10: > result = "third" > return result Because of the diversity of test-types, I tend to agree with ChrisA and be strongly tempted to ignore linting warning. I have some ETL code that has umpty-gazillion odd if-conditions like this and they all update some global-to-the-if/local-to-the-loop state, and if I split each out somehow, I'd either be passing an object around that I mutate, or I would do a lot of copy-the-data-updating-one-field per function. Alternatively, ... > def branch2(a, b, z): > """Elegant but inefficient because all expressions > are pre-computed althogh the first one is most likely > to hit""" > def branch3(a, b, z): > """Elegant but inefficient because expressions > need to be parsed each time""" If you really want to do lazy evaluation, you can create a function for each, which might (or might not) make it easier to read: def something_descriptive(a, b, z): return a > 4 and b == 0 def z_is_short(a, b, z): return len(z) < 2 def proper_total(a, b, z) return b + a == 10 def branch4(a, b, z): for test, result in [ (something_descriptive, "first"), (z_is_short, "second"), (proper_total, "third"), ]: if test(a, b, z): return result return "some default" or possibly def something_descriptive(a, b): return a > 4 and b == 0 def z_is_short(z): return len(z) < 2 def proper_total(a, b) return b + a == 10 def branch5(a, b, z): for test, params, result in [ (something_descriptive, (a, b), "first"), (z_is_short, (z,), "second"), (proper_total, (a, b), "third"), ]: if test(*params): return result return "some default" I'm not sure either of those is necessarily *better*, but they're at least options that you can try and see if it improves readability in your particular case. -tkc -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
Le 09/12/2019 à 09:15, R.Wieser a écrit : ... You'll find that *any* form of import executes all the top-level code. Thats certainly something I did not expect. How could it be otherwise? Consider a module defining two classes: Parent and Child, Child inheriting from Parent. if you do "from the_module import Child", how could it not execute the code defining Parent as well? Child *depends* on Parent. -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
Greg Ewing wrote: > On 8/12/19 9:30 pm, songbird wrote: >>wouldn't it make more sense to just go back and fix the >> converter program than to have to manually convert all this >> python2 code? > > Anything that isn't already fixed by 2to3 is probably > somewhere between very difficult and impossible to fix > using an automated process. It sounds like an interesting > project, but be aware that it's probably an AI-complete > problem. if the program already exists and is working then that implies a parser already exists for it. this is not a general AI or CS issue. songbird -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
jf...@ms4.hinet.net wrote: ... > Even string is hard to be handled by the AI:-) > > Quoted from https://portingguide.readthedocs.io/en/latest/strings.html > " ... This means that you need to go through the entire codebase, and decide > which value is what type. Unfortunately, this process generally cannot be > automated." i don't agree. if the language is already parsed then you have the strings. the contents of the strings will have to be finite if they are fixed strings. so to convert a fixed string you can choose a type for the value and run a test to see if it works. if it does then you've picked the correct type, if it doesn't you pick the next type. there are only a finite number of types. yes it is brute force but it would find something that worked eventually if there was something to be found. for programs using indefinite strings via input you can't predict what those would be doing, but then of course you would be able to say the most general type could be tried first and then run tests to see if it worked. the overall patterns to try for a string could be driven by examining code which has already been converted that contains similar patterns - eventually you would have enough of an idea of which things to try first to speed things up. yes, this is a generally hard issue if you are talking random strings and not sure what is what, but in the case of a computer language it is already specified and parsers already exist. songbird -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
On Tue, Dec 10, 2019 at 5:05 AM songbird wrote: > > jf...@ms4.hinet.net wrote: > ... > > Even string is hard to be handled by the AI:-) > > > > Quoted from https://portingguide.readthedocs.io/en/latest/strings.html > > " ... This means that you need to go through the entire codebase, and > > decide which value is what type. Unfortunately, this process generally > > cannot be automated." > > i don't agree. if the language is already parsed then > you have the strings. the contents of the strings will > have to be finite if they are fixed strings. so to convert > a fixed string you can choose a type for the value and run > a test to see if it works. if it does then you've picked > the correct type, if it doesn't you pick the next type. > there are only a finite number of types. > Here's an example piece of code. sock = socket.socket(...) name = input("Enter your username: ") code = input("Enter the base64 code: ") code = base64.b64decode(code) sock.write("""GET /foo HTTP/1.0 Authentication: Demo %s/%s """ % (name, code)) match = re.search(r"#[A-Za-z0-9]+#", sock.read()) if match: print("Response: " + match.group(0)) Your challenge: Figure out which of those strings should be a byte string and which should be text. Or alternatively, prove that this is a hard problem. There are only a finite number of types - two, to be precise - so by your argument, this should be straightforward, right? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
On 12/9/19 9:55 AM, songbird wrote: jf...@ms4.hinet.net wrote: ... Even string is hard to be handled by the AI:-) Quoted from https://portingguide.readthedocs.io/en/latest/strings.html " ... This means that you need to go through the entire codebase, and decide which value is what type. Unfortunately, this process generally cannot be automated." i don't agree. if the language is already parsed then you have the strings. the contents of the strings will have to be finite if they are fixed strings. so to convert a fixed string you can choose a type for the value and run a test to see if it works. if it does then you've picked the correct type, if it doesn't you pick the next type. there are only a finite number of types. And how exactly do you propose to determine whether the constant I've enclosed in quotation marks in Python2 represents "text" or "binary data"? Not all text is words; think of SQL queries. And some words are binary data, think SCPI commands being sent to a serial port. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
Dennis, > "del instance" only deletes the NAME. [snip] Yep, I already assumed that that would happen. Just wanted to keep it simple. > "instance" xyz does not shadow "class" xyz... instead, the name "xyz" > only exists in the binding to the instance. That is what I tried to say: the name-binding to the class is removed. > However, that instance has a binding to the class object, And than when the instance is deleted the binding to the class is lost, and as a result it is garbage-collected. Right ? Regards, Rudy Wieser -- https://mail.python.org/mailman/listinfo/python-list
Re: python 3 prefix to infix without too many parethesis
On 12/9/2019 6:21 AM, jezka...@gmail.com wrote: Hi, I have got a problem. Is this homework? I wrote a code for prefix to infix. It works, but I need improve it so on input there will be only necessary parentheses. Define 'necessary'; give multiple input/output examples. Put them in a test function. Here is the code: import re a = input() class Calculator: def __init__ (self): self.stack = [] def push (self, p): if p in ['+', '-', '*', '/', "**"]: op1 = self.stack.pop () op2 = self.stack.pop () self.stack.append ('(%s%s%s)' % (op1, p, op2)) print("op1 =", op1) print("op2 =", op2) print("p=", p) print(self.stack) else: self.stack.append (p) def convert (self, l): l.reverse () for e in l: self.push (e) return self.stack.pop () c = Calculator () print (c.convert (re.findall(r'\d+|\*\*|[-+*/]', a))) input is like /-*+*++**85 27 39 87 65 65 37 63 91 Since '*' and '**' are both allowed operators (see 'p in' above), spaces are needed between operators to disambiguate. In any case, what output does your code produce now, and what do you want it to produce. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: python 3 prefix to infix without too many parethesis
On 10/12/19 8:40 AM, Terry Reedy wrote: On 12/9/2019 6:21 AM, jezka...@gmail.com wrote: Hi, I have got a problem. Is this homework? Same question - that way we know that our task is to help you learn to code in Python, cf a problem with Python itself... Similarly, you may like to know that there is a separate Python-Tutor Discussion List. I wrote a code for prefix to infix. It works, but I need improve it so on input there will be only necessary parentheses. The example code processes, like a calculator (um, yes, well...). What do you mean by "prefix to infix"? Define 'necessary'; give multiple input/output examples. Put them in a test function. +1 Here is the code: Question: with abbreviated variableNMs, eg "p", "a", even "op"; how easily will you comprehend the code in six month's time? How easy do you think it is for someone else to read the code now? NB the print functions are no help because the labels are equally-abbreviated, plus my aged-eyes start to strain when following lists of %s-es and regexps - mea culpa! import re a = input() class Calculator: def __init__ (self): self.stack = [] def push (self, p): if p in ['+', '-', '*', '/', "**"]: op1 = self.stack.pop () op2 = self.stack.pop () self.stack.append ('(%s%s%s)' % (op1, p, op2)) print("op1 =", op1) print("op2 =", op2) print("p=", p) print(self.stack) else: self.stack.append (p) def convert (self, l): l.reverse () for e in l: self.push (e) return self.stack.pop () c = Calculator () print (c.convert (re.findall(r'\d+|\*\*|[-+*/]', a))) input is like /-*+*++**85 27 39 87 65 65 37 63 91 ALWAYS, ALWAYS, ALWAYS, document a RegExp with a comment!!! After 'translating' the abbreviations according to my recollection of this form of a frequently-used ComSc course problem, I was then surprised by the format of the input - using an infix calculator we enter a value, then an operator, and then another value, etc; and using a postfix calculator one usually inputs a couple of values and then an operator, another value, and then an operator, and so on - rather than receiving it all at once. Is this 'all at once' a feature of an infix calculator or am I missing/forgetting something? For which I am obviously not the only one with a confused expression on my face... Since '*' and '**' are both allowed operators (see 'p in' above), spaces are needed between operators to disambiguate. In any case, what output does your code produce now, and what do you want it to produce. I hate RegExps because it is so easy to write a wrong 'un. However, because the "\*\*" selection precedes the "[-+*/]", it appears (rheumy eyes allowing) to enact arithmetic priority correctly. However, as mentioned before, most of us will have created a serial and algorithmic approach to this problem, back-when; so it does seem a little strange. OK, let's address your actual question: the parentheses! How do you plan to make them work? As elsewhere: please provide example input and expected output, so that we can be sure of the code's objective. Multiple examples can only help, especially if there are exceptions and "edge-cases". Also, if your progress in Python is ready for it, we can talk PyTest (or equivalent), plus such a plan enables you to practice Test-Driven Development... These problems stretch one's mental acuities. It would seem that I am not the only one looking forward to hearing back from you... -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3 - How do I import a class from another file
It might be becoming 'long', but this discussion contains much of profit to many people! Us 'silver surfers' do need to periodically question those beliefs we hold as 'tenets' of ComSc. Amongst them is RAM (or "core"!) conservation. It remains a virtue somewhat, but at the same time, storage costs are considerably cheaper than they were four decades ago, whereas the relative-cost of your time (to think about such things) has increased! That said, many of our more youthful (and in their own words "better in every way", harrumph!) colleagues should also review their own beliefs from time-to-time, eg working with IoT devices certainly requires a more conservative and considerate approach to resources! (and in such applications, we tend to enjoy significant advantage because we've 'been there, done that'!) Similarly, it is a serious fallacy to attempt to directly 'translate' a 'command' from one language into an 'equivalent' in another/a new language. Whilst the syntax may appear similar, such superficiality doesn't allow for subtleties of meaning! In the same way, if you ask one person to translate the English word "preserve" into German, and then another person to translate that German word into English, what are the chances that the 'answer' will be "preserve"? Given that "preserve" could mean a jam/jelly/conserve (noun) or (verb) 'maintain the meaning', with a similar range of synonyms (etc) on the German side; the word "preserve" is unlikely to be preserved! (with all due apologies for such terrible humor and word-play!) On 9/12/19 11:32 PM, Terry Reedy wrote: On 12/9/2019 2:36 AM, R.Wieser wrote: Terry, Standard for in-file test is [snip] Any reason to put the testcode in a procedure instead of just have it directly follow the "if __name__ == '__main__' " test ? One can, for instance, interactively do >>> import mod >>> mod.test() ... I went through this cycle of thinking, first using if __name__... to 'hide' testing, then adding test functions within the module, and now keep test code quite separate from 'the real thing'. In fact, PyTest (for example) will auto-magically look for test-code in sub-directories of the project directory, eg "projectNM/tests". So, for every (Python) file in my projectDIR, you should be able to find at least one corresponding Python test-file in the tests sub-dir! This fits with your philosophy of keeping (imported) modules small, perhaps to the point of separating each class into its own module - if 'efficiency' is the goal, why would you want to include test-code within a 'production system'? On which point, if we had a class Person(); and then decided that in certain cases we wanted specific methods that didn't apply to every (type of) Person, we would likely create a sub-class, eg class Man( Person ); - although some might dispute the accuracy of such an "is a" relationship... That being the case, were you to put the Man class' code into (say) a module called "man.py" and Person()'s code into "person.py", then a point made earlier is that you can't merely import man.py;! You must also ensure that person.py is imported, somewhere along the line. Thus, because it names (and requires the logic of) the super-class, the sub-class cannot be imported 'alone'. (regardless of saving-space objectives, etc) Expanding on 'names' and del(): the first point is that there is seldom much to be gained by using del(), ie becoming your own 'garbage collector'. That said, there are some very specific times when it becomes absolutely necessary (otherwise the Python 'gods' would not have given us the functionality!). Once again, RAM is (relatively) plentiful, and when you need to replicate many multiples of an object, it is likely within a loop and therefore the same instanceNM is being 're-used' and the garbage-collector takes care of 'recycling' the storage space auto-magically. Regarding 'names', yes some languages are "strongly typed" and (mostly) for that reason include an indicator of "type" within the name. Python enables you to play fast-and-loose, eg >>> x = 1 >>> x = "abc" >>> x = 2.3 >>> x = [ 1, 2, 3 ] >>> x = ( 1, 2, 3 ) >>> x = 1, 2, 3 constitutes a perfectly legal program (where "legal" != "useful"). There again, there are times when values are processed into a different data structure, eg we start with a list of values, but only want to use unique values/process each representative-member once. A Python-list will handle the former (wow, that's a bit of 'rocket science'!?) whereas a Python-set will only contain unique values. So, rather than using a somewhat-bland varNM such as "letters", I would choose to be more explicit: >>> letters_list = [ "a", "b", "a", "c", "a", "d", "a" ] >>> len( letters_list ) 7 >>> letters_set = set( letters_list ) >>> len( letters_set ) 4 >>> letters_set {'b', 'a', 'd', 'c'} There is no question whether "letters" is a list, or a set, (or ...), because
Re: python 2 to 3 converter
Rob Gaddi wrote: ... > And how exactly do you propose to determine whether the constant I've > enclosed > in quotation marks in Python2 represents "text" or "binary data"? Not all > text > is words; think of SQL queries. And some words are binary data, think SCPI > commands being sent to a serial port. why not assume one, see if it works and then if it doesn't you know it is the other? if those are the only two choices then that speeds things up. songbird -- https://mail.python.org/mailman/listinfo/python-list
Randomizing Strings In A Microservices World
I ran across a kind of fun problem today that I wanted to run past you Gentle Geniuses (tm): - Imagine an environment in which there may be multiple instances of a given microservice written in Python. - Each of these services needs to produce a string of ten digits guaranteed to be unique on a per service instance basis AND to not collide for - oh, let's say - forever :)s Can anyone suggest a randomization method that might achieve this efficiently? My first thought was to something like nanonseconds since the epoch plus something unique about the service instance - like it's IP? (This is in a K8s cluster) - to see the randomization and essentially eliminate the string being repeated. Ideas welcome .. P.S. I do not want to resort to a number generation service that each instance asks for a new number. The network and service call overhead militates against this in my application. -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
Chris Angelico wrote: ... > > Here's an example piece of code. > > sock = socket.socket(...) > name = input("Enter your username: ") > code = input("Enter the base64 code: ") > code = base64.b64decode(code) > sock.write("""GET /foo HTTP/1.0 > Authentication: Demo %s/%s > > """ % (name, code)) > match = re.search(r"#[A-Za-z0-9]+#", sock.read()) > if match: print("Response: " + match.group(0)) > > Your challenge: Figure out which of those strings should be a byte > string and which should be text. Or alternatively, prove that this is > a hard problem. There are only a finite number of types - two, to be > precise - so by your argument, this should be straightforward, right? this isn't a process of looking at isolated code. this is a process of looking at the code, but also the test cases or working examples. so the inputs are known and the code itself gives clues about what it is expecting. regular expressions can be matched in finite time as well as a fixed length text of any type can be scanned as a match or rejected. if you examined a thousand uses of match and found the pattern used above and then examined what those programs did with that match what would you select as the first type, the one used the most first, if that doesn't work go with the 2nd, etc. songbird -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
On Tue, Dec 10, 2019 at 12:11 PM songbird wrote: > > Rob Gaddi wrote: > ... > > And how exactly do you propose to determine whether the constant I've > > enclosed > > in quotation marks in Python2 represents "text" or "binary data"? Not all > > text > > is words; think of SQL queries. And some words are binary data, think SCPI > > commands being sent to a serial port. > > why not assume one, see if it works and then if it doesn't you > know it is the other? if those are the only two choices then > that speeds things up. > What if neither works, because there are assumptions that don't work? I get the very strong impression that you've never tried this. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
On Tue, Dec 10, 2019 at 12:15 PM songbird wrote: > > Chris Angelico wrote: > ... > > > > Here's an example piece of code. > > > > sock = socket.socket(...) > > name = input("Enter your username: ") > > code = input("Enter the base64 code: ") > > code = base64.b64decode(code) > > sock.write("""GET /foo HTTP/1.0 > > Authentication: Demo %s/%s > > > > """ % (name, code)) > > match = re.search(r"#[A-Za-z0-9]+#", sock.read()) > > if match: print("Response: " + match.group(0)) > > > > Your challenge: Figure out which of those strings should be a byte > > string and which should be text. Or alternatively, prove that this is > > a hard problem. There are only a finite number of types - two, to be > > precise - so by your argument, this should be straightforward, right? > > this isn't a process of looking at isolated code. this > is a process of looking at the code, but also the test cases > or working examples. so the inputs are known and the code > itself gives clues about what it is expecting. Okay. The test cases are also written in Python, and they use unadorned string literals to provide mock values for input() and the socket response. Now what? What if the test cases are entirely ASCII characters? What if the test cases are NOT entirely ASCII characters? > regular expressions can be matched in finite time as well > as a fixed length text of any type can be scanned as a match > or rejected. > > if you examined a thousand uses of match and found the > pattern used above and then examined what those programs did > with that match what would you select as the first type, the > one used the most first, if that doesn't work go with the 2nd, > etc. > That's not really the point. Are your regular expressions working with text or bytes? Does your socket return text or bytes? I've deliberately chosen these examples because they are hard. And I didn't even get into an extremely hard problem, with the inclusion of text inside binary data inside of text inside of bytes. (It does happen.) These problems are fundamentally hard because there is insufficient information in the source code alone to determine the programmer's intent. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: More efficient/elegant branching
I agree with you, so I'm going to ignore def branch2(a, b, z): and def branch3(a, b, z) because they appear too contrived - and I guess that's fair, in that you've contrived to satisfy pylint. Question: are there other people/factors who/which should be regarded as more important than the linter's opinion? The usual dictionary-controlled construct I've seen (and used) involves using functions as the dict's values: def branch1( *args): pass ... alternative[ x ] = branch1 and thus: alternative[ choice ]( *args ) On 10/12/19 12:27 AM, Musbur wrote: I have a function with a long if/elif chain that sets a couple of variables according to a bunch of test expressions, similar to function branch1() below. I never liked that approach much because it is clumsy and repetetive, and pylint thinks so as well. I've come up with two alternatives which I believe are less efficient due to the reasons given in the respective docstrings. Does anybody have a better idea? def branch1(a, b, z): """Inelegant, unwieldy, and pylint complains about too many branches""" if a > 4 and b == 0: result = "first" elif len(z) < 2: result = "second" elif b + a == 10: result = "third" return result Is it ironic that the language does not have a form of case/switch statement (despite many pleas and attempts to add it), yet the linter objects to an if-elif-else nesting??? One reason why this code looks a bit strange (and possibly why PyLint reacts?) is because it is trivial. When we look at the overall picture, the question becomes: what will the 'mainline' do with "result" (the returned value)? Immediately one suspects it will be fed into another decision, eg: if result == "first": # do the first-thing... if result == "second": # do the second-thing... When found 'in real life', the above structure with such decisions is almost certainly followed by a second decision to select which 'action(s)' will be carried-out. The original-code rarely stands-alone, because all we've achieved is a labelling of the circumstances according to the arguments provided. Rather than using a variable for 'labelling', (all other things being equal) I'd prefer to go straight to a function which 'does the business' - and use the function's name as a documenting 'label'! A quick reflection shows that I have vacillated between two approaches: 1 put the decision-making in the 'mainline' and call a variety of functions/methods to do 'the first thing' etc. ie more-or-less what you have here, except the cascade of decisions is not separated from 'what came before'. def calculation( value, operator, operand): if operator == "+": add( value, operand) elif operator == "-": sub( value, operand) 2 arrange/call a series of functions each dealing with a single circumstance, eg (borrowing from @Chris) should I "tap"?. Thus each function will firstly check if the circumstances demand that action, ie the applicable one of the if-clauses above, and if they do, then implement that action: 'do the first thing' (etc). value = handle_add( value, operator, operand ) value = handle_sub( value, operator, operand ) where: def handle_add( value, operator, operand): if operator == "+": return value + operand return value Ugh - the example is no less contrived and grossly artificial... The second of those appears somewhat 'cleaner' - in that we have 'hidden away' all those pesky if-constructs; BUT it is NOT immediately obvious exactly how many of the series of functions will actually result in any 'action' (if not, all of them). So, perhaps that raises the (earlier/elsewhere) question of whether the various action-functions are dependent or independent/exclusive of each other? It also requires carefully choosing descriptive function names! -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Testing a TestPyPI package with dependencies
I'm a novice packager, trying to test a package I built and uploaded to TestPyPI. It has dependencies and I want to make sure my setup.py works before uploading to the real PyPI. https://packaging.python.org/guides/using-testpypi/ says that if a package has dependencies, to use this command to get the package from TestPyPI while getting dependencies from PyPI: pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple your-package That doesn't seem to work, though. It seems like it never checks pypi.org and looks for everything in test.pypi.org. Here's what I'm doing, starting from a new virtualenv: .. $ python3 -m venv /tmp/test3env $ source /tmp/test3env/bin/activate (test3env) $ pip install wheel Collecting wheel Using cached https://files.pythonhosted.org/packages/00/83/b4a77d044e78ad1a45610eb88f745be2fd2c6d658f9798a15e384b7d57c9/wheel-0.33.6-py2.py3-none-any.whl Installing collected packages: wheel Successfully installed wheel-0.33.6 (test3env) $ pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple pytopo==1.6.1 Looking in indexes: https://test.pypi.org/simple/, https://pypi.org/simple Collecting pytopo Using cached https://test-files.pythonhosted.org/packages/1d/dd/f46722bed2296676053b333a97babf05cb31b20e4a621161d44399a3ed18/pytopo-1.6.1-py3-none-any.whl Collecting simplejson (from pytopo) Could not install packages due to an EnvironmentError: 404 Client Error: Not Found for url: https://test.pypi.org/simple/simplejson/ .. I can pip install simplejson without errors, so I know it's in PyPI. (If I then try the install again, it fails on pycairo, same error.) Am I misunderstanding that packaging.python.org guide, or making some silly typo? Is there a trick it doesn't mention to getting pip to use both PyPI and TestPyPI? Thanks for any suggestions! ...Akkana -- https://mail.python.org/mailman/listinfo/python-list
Re: Randomizing Strings In A Microservices World
On Tue, 10 Dec 2019 at 12:12, Tim Daneliuk wrote: > - Each of these services needs to produce a string of ten digits > guaranteed to be unique > on a per service instance basis AND to not collide for - oh, let's say - > forever :)s > > Can anyone suggest a randomization method that might achieve this > efficiently? > > My first thought was to something like nanonseconds since the epoch plus > something > unique about the service instance - like it's IP? (This is in a K8s > cluster) - to > see the randomization and essentially eliminate the string being repeated. > 10 digits is only 9. That's not a very big number. Forget nanoseconds since the epoch, that won't currently give you seconds since the epoch - let alone combining with any other identifier. $ date '+%s' 1575942612 Tim Delaney -- https://mail.python.org/mailman/listinfo/python-list
Re: Randomizing Strings In A Microservices World
On 12/9/19 8:50 PM, Paul Rubin wrote: > Tim Daneliuk writes: >> - Imagine an environment in which there may be multiple instances of a given >> microservice written in Python. > > Decide the maximum number of microservice instances, say 1000. Chop up > the 10 digit range into 1000 pieces, so 0..99, 100-199, etc. > Give one range to each microservice instance. Then have the > microservices give out the numbers sequentially, but treating them as 10 > digit numbers and encrypting each one under a 10 digit pseudorandom > permutation shared by all the instances. Look up "format preserving > encryption" for how to do this. > > Obvious variants of the above are obvious, and maybe you need some way > to hand around chunks of range if some instance gives out more than a > million numbers. > The problem here is that the services are ephemeral and the number of said services is not fixed. -- https://mail.python.org/mailman/listinfo/python-list
Re: Randomizing Strings In A Microservices World
On 12/9/19 8:54 PM, Dennis Lee Bieber wrote: > On Mon, 9 Dec 2019 18:52:11 -0600, Tim Daneliuk > declaimed the following: > >> >> - Each of these services needs to produce a string of ten digits guaranteed >> to be unique >> on a per service instance basis AND to not collide for - oh, let's say - >> forever :)s >> >> Can anyone suggest a randomization method that might achieve this >> efficiently? >> >> My first thought was to something like nanonseconds since the epoch plus >> something >> unique about the service instance - like it's IP? (This is in a K8s >> cluster) - to >> see the randomization and essentially eliminate the string being repeated. >> >> Ideas welcome .. >> > > Well, 10 digits is rather short, but studying > https://en.wikipedia.org/wiki/Universally_unique_identifier might provide > some ideas. > > For a variety of reasons the length of this string cannot exceed 10 digits. It is believed that - in this application - the consumption of values will be sparse over time. All I really need is a high entropy way to select from among the billion possible values to minimize the possibility of collisions (which require retry and time we don't want to burn). -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
Chris Angelico wrote: ... > What if neither works, because there are assumptions that don't work? then you get stuck doing it by hand, but you would have been stuck doing it before for sure by hand so if you can write something which might get some of the easy cases done then at least you're saving your efforts for the harder stuff. > I get the very strong impression that you've never tried this. of course not! i don't have that kind of pipeline or machine power and i'm several years away from being where i'd like to be in terms of understanding the language itself. i hope to have the time over the next few years to learn enough but i don't know how that will go. i'm glad in looking around more the past few evenings that the conversion effort is making progress and things are not as dire as some have made it out to be. i just hope the lessons have been learned going forwards. songbird -- https://mail.python.org/mailman/listinfo/python-list
Re: python 2 to 3 converter
On Tue, Dec 10, 2019 at 4:41 PM songbird wrote: > > Chris Angelico wrote: > ... > > What if neither works, because there are assumptions that don't work? > > then you get stuck doing it by hand, but you would have > been stuck doing it before for sure by hand so if you can > write something which might get some of the easy cases > done then at least you're saving your efforts for the > harder stuff. The easy cases are easy for anything, and don't need AI. > > I get the very strong impression that you've never tried this. > > of course not! i don't have that kind of pipeline > or machine power and i'm several years away from being > where i'd like to be in terms of understanding the > language itself. i hope to have the time over the > next few years to learn enough but i don't know how > that will go. > > i'm glad in looking around more the past few evenings > that the conversion effort is making progress and > things are not as dire as some have made it out to be. > i just hope the lessons have been learned going > forwards. Never even done it manually, I mean. It's very difficult to try to design an AI to do something that you can't do yourself and don't even understand the problem. ChrisA -- https://mail.python.org/mailman/listinfo/python-list