setting parameters for functions and nested functions - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: setting parameters for functions and nested functions (/thread-8536.html) |
setting parameters for functions and nested functions - mepyyeti - Feb-24-2018 I feel I'm shaky on understanding the interplay between passing variables through functions (outside of classes)...Basically IDK when to use foo() vs foo(bar) especially in freestanding (OUTSIDE of a class) nested functions. PLEASE HELP I wrote this up. it's a self contained script: #!usr/bin/env python3 #defexp0.py import sys from functools import partial as p def inquire(a,type,errmsg): while True: b = input(a) if b !='': try: b == type(b) except ValueError: print('{}'.format(errmsg)) continue else: print('ok') return b else: print(f'{a:^50} must be answered.') continue the_q = p(inquire,type=str,errmsg='sorry') def foo(): while True: quit_now = the_q('\'y\' to quit anything else to continue') quit_now.strip().lower() if quit_now =='y' or quit_now =='yes': sys.exit() else: bar() continue def bar(): quest=the_q('please enter a, b, c, d or etc.') quest.strip().lower() if quest == 'a': forA(quest) elif quest == 'b': forB()#won't work elif quest == 'c': forC(quest) elif quest == 'd': forD() elif quest == 'e': forE(quest) else: forEtc() def forA(x): print(f'{x:^10}is fine.') def forB(): global someVariable print('nothing...'.format(someVariable)) '''but this WOULD work: def forB(): global someVariable print('nothing...') I don't understand ''' def forC(y): print('{} works too...'.format(y)) def forD(): print('fine') def forE(someVariable): global quest print('should work...'.format(someVariable)) #forE() global variable names must be different from parameter names??? def forEtc(): print('works') if __name__=='__main__': foo() else: print('sorry {__name__} not main')It works. Except for [input]b[/input] this triggers Perhaps someone could clarify foo() vs foo(bar) and their nuances in nested functions? Please?
RE: setting parameters for functions and nested functions - nilamo - Feb-24-2018 Think of a function as a sort of black box. You give it some data to work with, it does *something*, and then gives you a return value. A function shouldn't use any value that isn't passed to it. global should be avoided at all costs.
RE: setting parameters for functions and nested functions - mepyyeti - Feb-24-2018 (Feb-24-2018, 06:13 PM)nilamo Wrote: Think of a function as a sort of black box. You give it some data to work with, it does *something*, and then gives you a return value.Yes. And it works wonderfully well when functions are part of a class. Quote:A function shouldn't use any value that isn't passed to it. this is where I get frustrated lol. Pls see code in op above. Entire script runs off foo(). Not a single parameter, but quite a few variable gets assigned values in its body.... So this is what keeps getting me and textbooks seems to not care about the discrepency def foo(): a = 'moo' print(a) bar() def bar(): print('bar function') if __name__=='__main__': foo() else: print('choosing not to run')this script runs...this bothers me. Maybe it's a detail that comes from experience but I never feel certain when I can make do with foo() and when I need foo(param).... RE: setting parameters for functions and nested functions - snippsat - Feb-25-2018 (Feb-24-2018, 09:14 PM)mepyyeti Wrote: this script runs...this bothers me.Make it clear that foo takes a augment. def foo(bar): a = 'moo' print(a) bar() def bar(): print('bar function') if __name__=='__main__': foo(bar) else: print('choosing not to run') Quote:this is where I get frustrated lol. Pls see code in op above. Entire script runs off foo().That's normal to have a function that run whole script,the design bit can be the hard part to figure out. Clearer name(like eg menu) and never ever global ,make it clear that a function take arguments,not to long functions.Can be some tips. Example no variables in global name namespace,calling menu start it. result function takes 2 argumet,coin_flip and user_choice these function do only one task each.Always fall back to menu where can play again or Quit out. import random def coin_flip(): return random.choice(('head', 'tail')) def user_choice(): command = input("Choose Head or Tail: ").lower() return command def result(coin_flip, user_choice): ''' Doc string explain what function do''' coin = coin_flip() choice = user_choice() if coin == choice: print(f'\nComputer <{coin}> You gussed <{choice}> which is correct\n') else: print(f'\nComputer <{coin}> You gussed <{choice}> which is wrong\n') def menu(): while True: print('(1) Coin flip game') print('(Q) Quit\n') choice = input('Enter your choice: ').lower() if choice == '1': result(coin_flip, user_choice) elif choice == 'q': return False else: print(f'Not a correct choice: {choice}') if __name__ == '__main__': menu()If function get to complicated to design use a class RE: setting parameters for functions and nested functions - mepyyeti - Feb-25-2018 SO with the 1st snippet: def foo(bar): a = 'moo' print(a) bar() def bar(): print('bar function') if __name__=='__main__': foo(bar) else: print('choosing not to run')since both foo() and foo(bar) work to execute the script...is it simply a matter of best practices to just use foo(bar) to run the script? Technically, whether or not I have a parameter doesn't seem too matter... Regarding the snippet you wrote: import random def coin_flip(): return random.choice(('head', 'tail')) def user_choice(): command = input("Choose Head or Tail: ").lower() return command def result(coin_flip, user_choice): ''' Doc string explain what function do''' coin = coin_flip() choice = user_choice() if coin == choice: print(f'\nComputer <{coin}> You gussed <{choice}> which is correct\n') else: print(f'\nComputer <{coin}> You gussed <{choice}> which is wrong\n') def menu(): while True: print('(1) Coin flip game') print('(Q) Quit\n') choice = input('Enter your choice: ').lower() if choice == '1': result(coin_flip, user_choice) elif choice == 'q': return False else: print(f'Not a correct choice: {choice}') if __name__ == '__main__': menu()user_choice() clearly creates a variable, command, and gives it a value but necessitates no parameter. Yet, result(*args) also creates variables,coin and choice, and gives them the returned value of the 2 executed functions, coin_flip and user_choice. why not just say: ... def result(): ''' Doc string explain what function do''' coin = coin_flip() choice = user_choice() ...the logic works fine for ... def user_choice(): #yes I know value of command is set to user's input not the return result of a previous function command = input("Choose Head or Tail: ").lower() return command ...Question boils down to : Why do I need to set up parameters at all. user_choice() shows that I can create variables without parameters (technically just 1 positional)? this is where I get tripped up... RE: setting parameters for functions and nested functions - snippsat - Feb-25-2018 (Feb-25-2018, 03:48 AM)mepyyeti Wrote: Why do I need to set up parameters at all. user_choice() shows that I can create variables without parametersTo make it clear and more readable that a function take in code in from outside. The black box model as @nilamo talk abot crash as son as a function,variable,list,ect... magically appear in a function when is not set as parameter. As soon as this happen you wonder where dos it come from has it a relationship with this function?It can be easy to see in shorter code as my example,in larger code it can be a pain that stuff just magically appear from somewhere else. |