Re: Function to determine list max without itertools
On Tue, Apr 23, 2019 at 12:45 AM Grant Edwards wrote: > At the very top level _sometimes_ you want to have one single, global, > try/except to catch all exceptions and handle the nofication and exit > in a non-default way. For example: in a GUI application, it's > possible that nobody will see an excption message and stack trace > that's sent to stderr. A good GUI framework would already handle > that, but not all do. I describe that as a "boundary". You can sometimes have those inside an application, too; for instance, a web server will often want to catch any unhandled exception during a request handler, log it somewhere, send an HTTP 500 back to the client, and go back to serving requests. General principle: a boundary layer will catch EVERY exception and log them as part of handling them; everything else will catch only what it can actually handle (and recover from), and usually won't log them. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 2019-04-20, Michael Torrie wrote: > On 04/19/2019 04:01 AM, Sayth Renshaw wrote: >> def max_try(listarg): >> myMax = listarg[0] >> try: >> for item in listarg: >> if item > myMax: >> myMax = item >> except TypeError: >> print(f'Only numbers are supported, this entry "{item}" was not') >> pass >> >> return myMax > > If I were you I wouldn't catch that exception. The reason is that a > non-number is something your code just can't handle correctly anyway, so > better to let that original exception bubble up to the caller who can > deal with it. By catching this exception, your code will fail, but > still return as if it succeeded. > > Others may disagree. But I rarely catch exceptions in my code unless my > code specifically wants or needs to deal with them. I agree: In general, in a function, you only catch an exception if you can _fix_ the problem. [Though there may be some some cases where you want to log the exception in some specific manner and re-raise it.] If the function can't fix the problem, then leave it to the caller to decide what to do about it. At the very top level _sometimes_ you want to have one single, global, try/except to catch all exceptions and handle the nofication and exit in a non-default way. For example: in a GUI application, it's possible that nobody will see an excption message and stack trace that's sent to stderr. A good GUI framework would already handle that, but not all do. -- Grant Edwards grant.b.edwardsYow! How many retured at bricklayers from FLORIDA gmail.comare out purchasing PENCIL SHARPENERS right NOW?? -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 04/19/2019 04:01 AM, Sayth Renshaw wrote: > def max_try(listarg): > myMax = listarg[0] > try: > for item in listarg: > if item > myMax: > myMax = item > except TypeError: > print(f'Only numbers are supported, this entry "{item}" was not') > pass > > return myMax If I were you I wouldn't catch that exception. The reason is that a non-number is something your code just can't handle correctly anyway, so better to let that original exception bubble up to the caller who can deal with it. By catching this exception, your code will fail, but still return as if it succeeded. Others may disagree. But I rarely catch exceptions in my code unless my code specifically wants or needs to deal with them. -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 4/19/19 5:34 PM, MRAB wrote: [snip] How would you avoid comparing the initial max with list[0]? By slicing the list? By using 'iter' and 'next'? Do you expect that doing either of those to avoid a single comparison would make it faster? Is a comparison very expensive? You could, of course, do some benchmarks to see if it makes a difference, but, personally, I'd just leave it. Personally yes, but because it allows it to execute on non-sequence iterables rather than because it saves a single near-instantaneous comparison. -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix. -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 2019-04-20 00:24, DL Neil wrote: On 20/04/19 4:41 AM, Rob Gaddi wrote: On 4/19/19 12:23 AM, Sayth Renshaw wrote: On Friday, 19 April 2019 17:01:33 UTC+10, Sayth Renshaw wrote: Set the first item in the list as the current largest. Compare each subsequent integer to the first. if this element is larger, set integer. def maxitwo(listarg): myMax = listarg[0] for item in listarg: if item > myMax: myMax = item return myMax When you understand what it is you intend to write (barring DL Neil's comments), and THEN write it, you write the correct thing. Thus endith the lesson. +1, Rob's guidance saves time and embarrassment... [snip] Regarding 'optimisation': rather than 'disappearing' into high-volume and 'exotic' situations (see earlier comment), why not stick with the simple stuff? For example, once 'max' is initialised, is there a need to compare max with 'list[ 0 ]'? Is that really a problem? How would you avoid comparing the initial max with list[0]? By slicing the list? By using 'iter' and 'next'? Do you expect that doing either of those to avoid a single comparison would make it faster? Is a comparison very expensive? You could, of course, do some benchmarks to see if it makes a difference, but, personally, I'd just leave it. -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 19Apr2019 05:38, Dan Sommers <2qdxy4rzwzuui...@potatochowder.com> wrote: On 4/19/19 4:01 AM, Sayth Renshaw wrote: Now, what happens when the code is tested with various (different) sets of test-data? (remember the last question from my previous msg!?) It fails on any list entry that isn't a float or an int, giving a TypeError. What if the *first* entry isn't a float or an int? For instance, what if the list is ['a', 'b', 'c']? What about ['a', 'b', 3]? Maybe it doesn't matter. Consider: the notion of a maximum implies that all the items are comparable, otherwise you can't tell if one item is the max versus another. Provided all elements are mutually comparable eg all numeric or all strings, his code is fine. As soon as you want to mix values, you are making a _policy_ decision. Are mixed values ok at all? If not, his code is fine. Should values all be mutually comparable, _except_ for some special values? Such as None or the values NaN float values? Should failing comparisons be ignored? (In which case the first element might dictate the definition of a valid comparison.) Should they raise an exception (which his code will, for free)? All these questions are policy because the assume some greater context not provided in the problem definition. Sayth has only one decision to make here: Is the basic algorithm all that is required: assume all values are mutually comparable? In many situations that will do very well. Or should the basic algorithm "handle" noncomparable values? Unfortunately the meaning of "handle" might go several ways: at least the basic form alerts you to the fact that there are noncomparable values. Personally, I'd go one of 2 paths: - leave the code alone - it a simple and understandable and assumes _nothing_ about the values other than comparableness - provide a test for _expected_ incomparable values as an additional argument and use it to filter out these: any other values which fail to compare represent bad input, and the function _should_ fail But for the latter Python already has a builtin filter() function which the caller could trivially use to pre-filter the input data, avoiding any need to pointlessly complicate the basic maximum function. So I'd say Sayth has attained the target goal. Cheers, Cameron Simpson Q: How does a hacker fix a function which doesn't work for all of the elements in its domain? A: He changes the domain. - Rich Wareham -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 20/04/19 4:41 AM, Rob Gaddi wrote: On 4/19/19 12:23 AM, Sayth Renshaw wrote: On Friday, 19 April 2019 17:01:33 UTC+10, Sayth Renshaw wrote: Set the first item in the list as the current largest. Compare each subsequent integer to the first. if this element is larger, set integer. def maxitwo(listarg): myMax = listarg[0] for item in listarg: if item > myMax: myMax = item return myMax When you understand what it is you intend to write (barring DL Neil's comments), and THEN write it, you write the correct thing. Thus endith the lesson. +1, Rob's guidance saves time and embarrassment... Upon opening a new module in one's text-editor/IDE one of the first steps should be to write an explanatory docstring. Similarly, after typing the letters "def" or "class"! On the basis of this conversation, you might also benefit from reading about the use of doctests! (seeing we're talking docstrings - can always move to other test methods later) I find this a useful habit, particularly if I am outlining an entire module or class, and only later coming back to flesh-out the code. Further reading: Test-Driven Development Of course all the comments in the world won't help if code != comment!!! Before congratulating ourselves that the code 'works': did you spot the difference in the better-developed 'English' description and the implementation in Python? Regarding 'testing': Start with the scope and your objectives [as yet unstated, so we can only imagine what they might be]. When should it work, eg data-types. Why doesn't the code work with string data? Does it work if the list mixes different data-types? Should it work if a list element is itself a collection/class? Regarding 'optimisation': rather than 'disappearing' into high-volume and 'exotic' situations (see earlier comment), why not stick with the simple stuff? For example, once 'max' is initialised, is there a need to compare max with 'list[ 0 ]'? Extension: if, instead of merely finding the largest value in the list (cf which element of the list is the largest!), what if the code also 'moved' that element to the end of the list? Then, what if that function was called again but this time to operate on all of the list EXCEPT the last (which we already know is the largest) - and if this 'outer loop' were repeated 'len( list )' number of times (either by loop or (perhaps a later coding exercise) by recursion; what would be the final condition of the 'list'? -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 4/19/19 12:23 AM, Sayth Renshaw wrote: On Friday, 19 April 2019 17:01:33 UTC+10, Sayth Renshaw wrote: Set the first item in the list as the current largest. Compare each subsequent integer to the first. if this element is larger, set integer. def maxitwo(listarg): myMax = listarg[0] for item in listarg: if item > myMax: myMax = item return myMax Sayth When you understand what it is you intend to write (barring DL Neil's comments), and THEN write it, you write the correct thing. Thus endith the lesson. -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix. -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
Sayth Renshaw writes: >> Now, what happens when the code is tested with various (different) sets >> of test-data? >> (remember the last question from my previous msg!?) >> > It fails on any list entry that isn't a float or an int, giving a TypeError. > >> Once you are happy with the various test-runs, do you have any ideas for >> making the code more efficient? >> -- >> Regards =dn > > Efficient No, but resistant to error I can buy using try except to > pass through TypeErrors. > > def max_try(listarg): > myMax = listarg[0] > try: > for item in listarg: > if item > myMax: > myMax = item > except TypeError: > print(f'Only numbers are supported, this entry "{item}" was not') > pass > > return myMax > > Thanks. 'pass' does not do what you think! To re-raise the exception, use 'raise'. 'pass' is a null statement that does nothing. But catching an exception just to print a message from a utility function like this is not really a good idea. It would be annoying to many used of this function whilst adding little value over and above what the traceback will show anyway. There is another error case where you /could/ add a little value by catching it in your function and raising a more appropriate exception. What test cases have you used so far? > PS Since I am going through the list fully the only optimisation I can > think of a generator to feed it seems sort of redundant. Unless of > course it was a list of 10,000 numbers then maybe its useful. I'm not sure what was meant here. I can think of one micro-optimisation but I'd want to test to see if really makes and difference. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 4/19/19 4:01 AM, Sayth Renshaw wrote: Now, what happens when the code is tested with various (different) sets of test-data? (remember the last question from my previous msg!?) It fails on any list entry that isn't a float or an int, giving a TypeError. What if the *first* entry isn't a float or an int? For instance, what if the list is ['a', 'b', 'c']? What about ['a', 'b', 3]? Dan -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
> Now, what happens when the code is tested with various (different) sets > of test-data? > (remember the last question from my previous msg!?) > It fails on any list entry that isn't a float or an int, giving a TypeError. > Once you are happy with the various test-runs, do you have any ideas for > making the code more efficient? > -- > Regards =dn Efficient No, but resistant to error I can buy using try except to pass through TypeErrors. def max_try(listarg): myMax = listarg[0] try: for item in listarg: if item > myMax: myMax = item except TypeError: print(f'Only numbers are supported, this entry "{item}" was not') pass return myMax Thanks. PS Since I am going through the list fully the only optimisation I can think of a generator to feed it seems sort of redundant. Unless of course it was a list of 10,000 numbers then maybe its useful. Maybe a generator with a condition that if list length is greater than 500 to chunk it into 250 lengths. But then If we go along this path then you could say if every other task in an application waited on it could be very important so then async await might be an option. Sayth -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
> On 19/04/19 7:23 PM, Sayth Renshaw wrote: In English: Set the first item in the list as the current largest. Compare each subsequent integer to the first. if this element is larger, set integer. Criticism: (because this does NOT match the code, below!) - should the algorithm "Compare each subsequent integer to the first" or is the comparison with 'the current largest', ie 'the largest so-far'? NB IIRC this was (likely) why it was suggested that you explain the method in English, first! In code: def maxitwo(listarg): myMax = listarg[0] for item in listarg: if item > myMax: myMax = item return myMax Well done! Now, what happens when the code is tested with various (different) sets of test-data? (remember the last question from my previous msg!?) Once you are happy with the various test-runs, do you have any ideas for making the code more efficient? -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On Friday, 19 April 2019 17:01:33 UTC+10, Sayth Renshaw wrote: > Set the first item in the list as the current largest. > Compare each subsequent integer to the first. > if this element is larger, set integer. def maxitwo(listarg): myMax = listarg[0] for item in listarg: if item > myMax: myMax = item return myMax Sayth -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
Set the first item in the list as the current largest. Compare each subsequent integer to the first. if this element is larger, set integer. -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 19/04/19 5:22 PM, Sayth Renshaw wrote: In English rather than Python, how do you find the maximum element in a list? -- Rob Gaddi, Highland Technology Get first 1 item in the list and compare it to the rest. If it is larger than rest its the max. However if another list member is larger it replaces the first item and comparison continues. A good first effort! Is it sufficiently-detailed to say "compare it to the rest"? Is it being compared with ALL of the other elements of the list at once? How about this outline: Set the first item in the list as the current largest. Compare ... if this element is larger, set ... How could we fill in the gaps (...) of that description? Also, what types of data are you expecting as elements within the list? -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
> > In English rather than Python, how do you find the maximum element in a > list? > > -- > Rob Gaddi, Highland Technology Get first 1 item in the list and compare it to the rest. If it is larger than rest its the max. However if another list member is larger it replaces the first item and comparison continues. Sayth -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 2019-04-18, Rob Gaddi wrote: > On 4/18/19 4:35 PM, Sayth Renshaw wrote: > >> This is where I have ended up. Without itertools and max its what I got >> currently. >> >> def maximum(listarg): >> myMax = listarg[0] >> for item in listarg: >> for i in listarg[listarg.index(item)+1:len(listarg)]: >> if myMax < i: >> myMax = i >> >> return myMax >> >> How would you simplify it? > > In English rather than Python, how do you find the maximum element > in a list? Hint: "greater than" is transitive. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 4/18/19 4:35 PM, Sayth Renshaw wrote: It's still overly complicated. This is where I have ended up. Without itertools and max its what I got currently. def maximum(listarg): myMax = listarg[0] for item in listarg: for i in listarg[listarg.index(item)+1:len(listarg)]: if myMax < i: myMax = i return myMax How would you simplify it? In English rather than Python, how do you find the maximum element in a list? -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix. -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
> > > It's still overly complicated. > This is where I have ended up. Without itertools and max its what I got currently. def maximum(listarg): myMax = listarg[0] for item in listarg: for i in listarg[listarg.index(item)+1:len(listarg)]: if myMax < i: myMax = i return myMax How would you simplify it? -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 2019-04-18 08:39, Sayth Renshaw wrote: Thank you for the advice everyone. The first thing to try is find every place where you update myMax, and This was actually where I was going wrong. I was setting max but then overwriting it with item. Then kept checking item only to return myMax. I went looking for other solutions as I thought I must be well off the path in the shrubs but I was actually close. This is how I ended up. There may be better solutions but this works. def maximum(listarg): items = list(listarg) myMax = items[0] for item in items: for i in items[items.index(item)+1:len(items)]: if myMax < i: myMax = i else: pass return myMax It's still overly complicated. if __name__ == "__main__": print(maximum([4,3,6,2,1,4])) -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On Thu, Apr 18, 2019 at 5:41 PM Sayth Renshaw wrote: > > Thank you for the advice everyone. > > > > > The first thing to try is find every place where you update myMax, and > > This was actually where I was going wrong. I was setting max but then > overwriting it with item. Then kept checking item only to return myMax. > > I went looking for other solutions as I thought I must be well off the path > in the shrubs but I was actually close. > > This is how I ended up. There may be better solutions but this works. > > def maximum(listarg): > items = list(listarg) > myMax = items[0] > for item in items: > for i in items[items.index(item)+1:len(items)]: > if myMax < i: > myMax = i > else: > pass > > return myMax > > > if __name__ == "__main__": > print(maximum([4,3,6,2,1,4])) > This is where I would strongly recommend printing lots of stuff out, to explore what the algorithm is doing at each point. See if you can figure out when myMax is being updated. (Also: items.index(item) will potentially give the wrong result if you have duplicates.) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
Thank you for the advice everyone. > > The first thing to try is find every place where you update myMax, and This was actually where I was going wrong. I was setting max but then overwriting it with item. Then kept checking item only to return myMax. I went looking for other solutions as I thought I must be well off the path in the shrubs but I was actually close. This is how I ended up. There may be better solutions but this works. def maximum(listarg): items = list(listarg) myMax = items[0] for item in items: for i in items[items.index(item)+1:len(items)]: if myMax < i: myMax = i else: pass return myMax if __name__ == "__main__": print(maximum([4,3,6,2,1,4])) Cheers Sayth -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On 18/04/19 4:10 PM, Sayth Renshaw wrote: I have created a function that takes a list as an argument. Without using itertools I want to compare each item in the list to find the max. However instead of the max I keep getting the last item in the list. Where is my logic wrong here? ... Seems like it should work but doesn't. I'd recommend rethinking your algorithm first, and then thinking about debugging your actual code. You should be able to find the largest in a collection without making many many passes over the items - a single pass should be sufficient. Most I am finding either use the max function or itertools. Both of which I am trying not to use so that I actually do it myself. Did you understand the advice? Have you simply dropped the first-attempt and gone looking for another canned-solution? Whilst you seem to be on-the-right-track, there is a definite error in the algorithm/the code. What debugging did you perform? Do you only assume, or can you see example (pertinent) values during each "pass" (time through the loop)? If not, why not? -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
wrote: > > > > > > I have created a function that takes a list as an argument. > > Without using itertools I want to compare each item in the list to find the > > max. > > > > However instead of the max I keep getting the last item in the list. Where > > is my logic wrong here? > > > > def maximum(listarg): > > items = list(listarg) > > myMax = 0 > > for index, item in enumerate(items): > > for otheritem in items[index + 1 :]: > > if item < otheritem: > > myMax = otheritem > > elif item > otheritem: > > myMax = item > > else: > > myMax = myMax > > > > Seems like it should work but doesn't. > > > > I'd recommend rethinking your algorithm first, and then thinking about > debugging your actual code. You should be able to find the largest in > a collection without making many many passes over the items - a single > pass should be sufficient. > > ChrisA Most I am finding either use the max function or itertools. Both of which I am trying not to use so that I actually do it myself. This one on SO is where I was going https://stackoverflow.com/a/3990826/461887 def maxelements(seq): ''' Return list of position(s) of largest element ''' max_indices = [] if seq: max_val = seq[0] for i,val in ((i,val) for i,val in enumerate(seq) if val >= max_val): if val == max_val: max_indices.append(i) else: max_val = val max_indices = [i] return max_indices This is probably the nicest one but still uses Max. >>> a=[5,4,3,2,1] >>> def eleMax(items, start=0, end=None): ... return max(items[start:end]) Thanks Sayth -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to determine list max without itertools
On Thu, Apr 18, 2019 at 9:31 AM Sayth Renshaw wrote: > > > I have created a function that takes a list as an argument. > Without using itertools I want to compare each item in the list to find the > max. > > However instead of the max I keep getting the last item in the list. Where > is my logic wrong here? > > def maximum(listarg): > items = list(listarg) > myMax = 0 > for index, item in enumerate(items): > for otheritem in items[index + 1 :]: > if item < otheritem: > myMax = otheritem > elif item > otheritem: > myMax = item > else: > myMax = myMax > > Seems like it should work but doesn't. > I'd recommend rethinking your algorithm first, and then thinking about debugging your actual code. You should be able to find the largest in a collection without making many many passes over the items - a single pass should be sufficient. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Function to determine list max without itertools
I have created a function that takes a list as an argument. Without using itertools I want to compare each item in the list to find the max. However instead of the max I keep getting the last item in the list. Where is my logic wrong here? def maximum(listarg): items = list(listarg) myMax = 0 for index, item in enumerate(items): for otheritem in items[index + 1 :]: if item < otheritem: myMax = otheritem elif item > otheritem: myMax = item else: myMax = myMax Seems like it should work but doesn't. Cheers Sayth -- https://mail.python.org/mailman/listinfo/python-list