title: Trying to understand optional, list and named arguments in Python
body: <p>I'm a beginner at Python, trying to understand function arguments and their types and orders.</p>
  
  <p>I tried to experiment a little with the different kinds of argument and here's my experiment</p>
  
  <pre><code>def main():
      test_a(2, 33, 44)
      test_b(2, 33)
      test_c(2)
      ## test_d(2,,44) **Produces Invalid syntax**
  
      test_e(2,33,44,55,66)
      test_f(2, 44,55,66, y = 44)
  
      test_g(2, 33, 44,55,66, rofa = 777, nard = 888)
      ##test_h(2, 33, foo = 777, boo = 888, 44,55,66)  **Invalid Syntax in Function definition
      ##test_l(2, 44,55,66 ,  foo= 777, boo = 888, y  = 900) **Invalid Syntax in Function definition
      test_m(2, 44,55,66 , y = 900, foo=77777 , boo = 88888)
  
  #############################################################
  ## NO optional arguments
  def test_a(x,y,z):
      print("test_a : x = {}, y = {}, z = {} ".format(x ,y ,z))
  
  ## One optional argument at the end
  def test_b(x, y, z = 22):
      print("test_b : x = {}, y = {}, z = {} ".format(x ,y ,z))
  
  ## TWO optional arguments at the end
  def test_c(x, y = 11, z = 22):
      print("test_c : x = {}, y = {}, z = {} ".format(x ,y ,z))
  
  ## ONE optional argument at the middle
  ## Produces Non-default argument follows default argument
  #### **** DEFAULT ARGUMENTS MUST COME AT THE END **** ####
  ## def test_d(x, y = 11, z):
  ##    print("test_d : x = {}, y = {}, z = {} ".format(x ,y ,z))
  
  #################################################################
  
  ## NO optional argument + One List argument
  def test_e(x, y, *args):
      print("test_e : x = {}, y = {} ||".format(x, y), end= " ")
      for i in args :
          print(i)
  
  ## One optional argument + One list argument
  def test_f(x, *args , y = 5):
      print("test_f : x = {}, y = {} ||".format(x, y), end= " ")
      for i in args :
          print(i)
  
  ################################################################
  
  ## No optional argument, one list, one keyword arguments
  def test_g(x,y,*args, **kwargs):
      print(x, y)
      for i in args:
          print(i)
  
      for i, v in kwargs.items():
          print(i, v)
  
  ## **kwargs befor *args produces syntax error !!!
  ##def test_h(x,y, **kwargs, *args):
  ##    print(x, y)
  ##    for i in args:
  ##        print(i)
  ##
  ##    for i, v in kwargs.items():
  ##        print(i, v)
  
  ## **kwargs befor optional argument produces syntax error !!!
  ##def test_l(x,*args,**kwargs, y = 5):
  ##    print(x, y)
  ##    for i in args:
  ##        print(i)
  ##
  ##    for i, v in kwargs.items():
  ##        print(i, v)
  ##    
  
  ## One optiona, list and keyword arguments
  def test_m(x,*args,y = 5, **kwargs):
      print(x, y)
      for i in args:
          print(i)
  
      for i, v in kwargs.items():
          print(i, v)
  
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>I really understood most of things after this experiment. But there's one issue that i can't get inside my head.</p>
  
  <p>In the function definition in <code>test_h</code> and <code>test_m</code> where <code>**kwargs</code> are defined before optional argument and list argument, when i run the program, even if i didn't use that function, just defined it.. It produces <code>Syntax Error</code> .. I'd be grateful to know why is this happening ?</p>
  
  <p>Thanks.</p>