Re: [Tutor] Defining variable arguments in a function in python
I have my usual off the wall answer. OK, seriously. Not exactly an answer but perhaps an experiment. The question was how to have a non-named first argument to a function with some form of default. As was pointed out, this does not fit well with being able to have python gather all positional arguments after it as well as all keyword arguments. But bear with me. Say I want to have a way to signal that I want a default for the first argument? An empty comma fails but try this: def hello(a, *n, **m) : if a == None: a=5 print(a) print(*n) print(**m) The above says "a" is required. It can be followed by any number of positional args gathered into "n" and any number of keyword args gathered into "m" But what if you define a sentinel to watch for such as None, in the above? If the first and only arg is None, it switches to the default of 5. >>> hello(None) 5 Add a few more args and it properly takes it. >>> hello(1,2,3) 1 2 3 Switch the first to None: >>> hello(None,2,3) 5 2 3 The keywords don't work for print but no biggie. But is this only for None? What I say any negative arg is replaced by 5? def hello(a, *n, **m) : if a < 0: a=5 print(a) print(*n) Seems to work fine: >>> hello(-666, 2, 3, 4) 5 2 3 4 And I wonder if we can use the darn ellipsis for something useful? def hello(a, *n, **m) : if a == ... : a=5 print(a) print(*n) >>> hello(1,2,3) 1 2 3 >>> hello(...,2,3) 5 2 3 >>> hello(...,2,...) 5 2 Ellipsis OK, all kidding aside, is this helpful? I mean if you want a function where you MUST give at least one arg and specify the first arg can be some odd choice (as above) and then be replaced by a default perhaps it would be tolerable to use None or an Ellipsis. Or on a more practical level, say a function wants an input from 1 to 10. The if statement above can be something like: >>> def hello(a, *n, **m) : if not (1 <= a <= 10) : a=5 print(a) print(*n) >>> hello(1,2,3) 1 2 3 >>> hello(21,2,3) 5 2 3 >>> hello(-5,2,3) 5 2 3 >>> hello("infinity and beyond",2,3) Traceback (most recent call last): File "", line 1, in hello("infinity and beyond",2,3) File "", line 2, in hello if not (1 <= a <= 10) : a=5 TypeError: '<=' not supported between instances of 'int' and 'str' As expected, it may take a bit more code such as checking if you got an int but the idea may be solid enough. It is NOT the same as having a default from the command line but it may satisfy some need. Other than that, I fully agree that the current python spec cannot support anything like this in the function definition. Side note: To spare others, I sent Steven alone a deeper reply about ways to select random rows from a pandas DataFrame. I am still learning how pandas works and doubt many others here have any immediate needs. -Original Message- From: Tutor On Behalf Of Steven D'Aprano Sent: Saturday, December 29, 2018 6:02 AM To: tutor@python.org Subject: Re: [Tutor] Defining variable arguments in a function in python On Sat, Dec 29, 2018 at 11:42:16AM +0530, Karthik Bhat wrote: > Hello, > > I have the following piece of code. In this, I wanted to make > use of the optional parameter given to 'a', i.e- '5', and not '1' > > def fun_varargs(a=5, *numbers, **dict): [...] > > fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333) > > How do I make the tuple 'number' contain the first element to be 1 and not 2? You can't. Python allocates positional arguments like "a" first, and only then collects whatever is left over in *numbers. How else would you expect it to work? Suppose you called: fun_varargs(1, 2, 3) wanting a to get the value 1, and numbers to get the values (2, 3). And then immediately after that you call fun_varargs(1, 2, 3) wanting a to get the default value 5 and numbers to get the values (1, 2, 3). How is the interpreter supposed to guess which one you wanted? If you can think of a way to resolve the question of when to give "a" the default value, then we can help you program it yourself: def func(*args, **kwargs): if condition: # When? a = args[0] numbers = args[1:] else: a = 5 # Default. numbers = args ... But writing that test "condition" is the hard part. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] decomposing a problem
Steven, A more practical answer about splitting a data frame is to import modules such as for machine learning. Import sklearn.model_selection Then use train_test_split() to return 4 parts. Not sure what answers you need and why here. Plenty of ways and tools exist to specify choosing percentages to partition by or other ways. Sent from AOL Mobile Mail On Saturday, December 29, 2018 Avi Gross wrote: Steven, As I head out the door, I will sketch it. Given a data.frame populated with N rows and columns you want to break it into training and test data sets. In a data.frame, you can refer to a row by using an index like 5 or 2019. You can ask for the number of rows currently in existence. You can also create an array/vector of length N consisting of instructions that can tell which random rows of the N you want and which you don't. For the purposes of this task, you choose random numbers in the range of N and either keep the numbers as indices or as a way to mark True/False in the vector. You then ask for a new data.frame made by indexing the existing one using the vector. You can then negate the vector and ask for a second new data.frame indexing it. Something close to that. Or, you can simply add the vector as a new column in the data.frame in some form. It would then mark which rows are to be used for which purpose. Later, when using the data, you include a CONDITION that row X is true, or whatever. -Original Message- From: Tutor On Behalf Of Steven D'Aprano Sent: Friday, December 28, 2018 11:12 PM To: tutor@python.org Subject: Re: [Tutor] decomposing a problem On Fri, Dec 28, 2018 at 10:39:53PM -0500, Avi Gross wrote: > I will answer this question then head off on vacation. You wrote about 140 or more lines, but didn't come close to answering the question: how to randomly split data from a dictionary into training data and reserved data. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Defining variable arguments in a function in python
Karthik Bhat wrote: > Hello, > > I have the following piece of code. In this, I wanted to make use > of the optional parameter given to 'a', i.e- '5', and not '1' > > def fun_varargs(a=5, *numbers, **dict): > print("Value of a is",a) > > for i in numbers: > print("Value of i is",i) > > for i, j in dict.items(): > print("The value of i and j are:",i,j) > > fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333) > > How do I make the tuple 'number' contain the first element to be 1 and > not 2? One option is to change the function signature to def fun_varargs(*numbers, a=5, **dict): ... which turns `a` into a keyword-only argument. >>> fun_varargs(1, 2, 3, foo="bar"): Value of a is 5 Value of i is 1 Value of i is 2 Value of i is 3 The value of i and j are: foo bar To override the default you have to specify a value like this: >>> fun_varargs(1, 2, 3, foo="bar", a=42) Value of a is 42 Value of i is 1 Value of i is 2 Value of i is 3 The value of i and j are: foo bar ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] decomposing a problem
Steven, As I head out the door, I will sketch it. Given a data.frame populated with N rows and columns you want to break it into training and test data sets. In a data.frame, you can refer to a row by using an index like 5 or 2019. You can ask for the number of rows currently in existence. You can also create an array/vector of length N consisting of instructions that can tell which random rows of the N you want and which you don't. For the purposes of this task, you choose random numbers in the range of N and either keep the numbers as indices or as a way to mark True/False in the vector. You then ask for a new data.frame made by indexing the existing one using the vector. You can then negate the vector and ask for a second new data.frame indexing it. Something close to that. Or, you can simply add the vector as a new column in the data.frame in some form. It would then mark which rows are to be used for which purpose. Later, when using the data, you include a CONDITION that row X is true, or whatever. -Original Message- From: Tutor On Behalf Of Steven D'Aprano Sent: Friday, December 28, 2018 11:12 PM To: tutor@python.org Subject: Re: [Tutor] decomposing a problem On Fri, Dec 28, 2018 at 10:39:53PM -0500, Avi Gross wrote: > I will answer this question then head off on vacation. You wrote about 140 or more lines, but didn't come close to answering the question: how to randomly split data from a dictionary into training data and reserved data. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Defining variable arguments in a function in python
On Sat, Dec 29, 2018 at 11:42:16AM +0530, Karthik Bhat wrote: > Hello, > > I have the following piece of code. In this, I wanted to make use > of the optional parameter given to 'a', i.e- '5', and not '1' > > def fun_varargs(a=5, *numbers, **dict): [...] > > fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333) > > How do I make the tuple 'number' contain the first element to be 1 and not 2? You can't. Python allocates positional arguments like "a" first, and only then collects whatever is left over in *numbers. How else would you expect it to work? Suppose you called: fun_varargs(1, 2, 3) wanting a to get the value 1, and numbers to get the values (2, 3). And then immediately after that you call fun_varargs(1, 2, 3) wanting a to get the default value 5 and numbers to get the values (1, 2, 3). How is the interpreter supposed to guess which one you wanted? If you can think of a way to resolve the question of when to give "a" the default value, then we can help you program it yourself: def func(*args, **kwargs): if condition: # When? a = args[0] numbers = args[1:] else: a = 5 # Default. numbers = args ... But writing that test "condition" is the hard part. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Defining variable arguments in a function in python
On 29/12/2018 06:12, Karthik Bhat wrote: > def fun_varargs(a=5, *numbers, **dict): > print("Value of a is",a) > > for i in numbers: > print("Value of i is",i) > > for i, j in dict.items(): > print("The value of i and j are:",i,j) > > fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333) > > How do I make the tuple 'number' contain the first element to be 1 and not > 2? You need to provide a value for a. The default 5 will only be used if the function is called without *any* arguments. Otherwise it will always take the first argument value. So, if you want a to be 5 and then provide a tuple etc you must explicitly pass a 5 in: fun_varargs(5, 1,2,3,4,5,6,7,8,9,10, Jack=111,John=222,Jimmy=333) HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Defining variable arguments in a function in python
Hello, I have the following piece of code. In this, I wanted to make use of the optional parameter given to 'a', i.e- '5', and not '1' def fun_varargs(a=5, *numbers, **dict): print("Value of a is",a) for i in numbers: print("Value of i is",i) for i, j in dict.items(): print("The value of i and j are:",i,j) fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333) How do I make the tuple 'number' contain the first element to be 1 and not 2? -- Regards, Karthik A Bhat ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor