Call function at start of program before its defined - python

I have a program where a user inputs data, the data is turned into a list, and then the main function loops over the list until it has looped twice. Then the program should go back to maininput, so the user can input more data. However I can't get maininput to start before main, so main never gets the list to start the whole process. I tried calling maininput at the start of the program, obviously this can't work though since its not defined yet before line one.
Example structure:
def maininput():
userdata = input('input data: ')
list=[]
#userdata turned into a list...
def main():
counter = 0
for input in list:
counter +=1
#stuff done with input
if counter == 2:
print('Program finished')
maininput()
else:
pass
while True:
main()

I think you need some parameters in place to pass data around
def maininput():
userdata = input('input data: ')
#userdata turned into biglist1...
return biglist1
# take a list and the amount of iterations performed
def main(lst, counter=0):
if counter == 2: # change recursion when counter is reached
print('Program finished')
lst = maininput()
return main(lst) # also resetting the counter
for x in lst:
#stuff done with input
return main(lst, counter+1) # endlessly recurse
# No while loop needed, this function is recursive
main(maininput())

if the program have to run indefinitely, and if with big list you refer to the user input data, you can try this:
def maininput():
userdata = input('input data: ')
#userdata turned into a list...
return list
def main():
counter = 0
bigList = maininput()
while True:
for data in bigList:
#doing stuff
counter+=1
if counter == 2:
print('Program finished')
main()
else:
pass
main()

Why can't you just call maininput() before you hit the while True loop?
i.e:
maininput()
while True:
main()

Related

Using Python for default parameters

I am currently learning python and stuck on a coding exercise. I am trying to achieve the result as shown on the image1. I am stuck on the overall code. I also not sure how to incorporate the "quit", so that the program terminates.
Image1
def tester(result):
while tester:
if len(result)< 10:
return print(givenstring)
else:
return print(result)
def main():
givenstring = "too short"
result=input("Write something (quit ends): ")
if __name__ == "__main__":
main()
For your problem, you need to have a variable that is your Boolean (true/false) value and have your while loop reference that. currently your while loop is referencing your function. inside your main function when you get your user input you can have a check that if the input is "quit" or "end" and set you variable that is controlling your loop to false to get out of it.
you also are not calling your tester function from your main function.
You missed into main() function to call your function, like tester(result). But such basics should not be asked here.
def tester(result):
if len(result)< 10 and result != 'quit':
givenstring = "too short"
return print(givenstring)
else:
return print(result)
def main():
result=None
while True:
if result == 'quit':
print("Program ended")
break
else:
result=input("Write something (quit ends): ")
if result.lower() == 'quit':
result = result.lower()
tester(result.lower())
if __name__ == "__main__":
main()

Extracting two or three smaller functions from main() to find errors more easily

I would like to extract shorter functions from the larger main function to make this more readable and easier to find errors without removing functionality
I was thinking of splitting it down the middle like shown with "def calc_mean():. However an issue is that data amongst other things is not defined in this function. How should I change these so the original program still works despite being divided into 2?
It is a never ending loop.
user_input calls main, then main calls user_input, then user_input calls main and so on.
FIX 1
Remove filename = input(user_input()) from main function and pass filename as an argument from user_input . In this case whole script should first call user_input function.
FIX 2
Remove filename = input(user_input()) with filename = user_input() adjust user_input function so it would only ask for user input and then return that input. In this case script should first call main function.
Also, in the bottom of the script it should be
if __name__ == '__main__': # not `main`
call_some_function()
Update
def user_input(): # adjust this if you need
filename = input()
return filename
def read_data(filename):
data = dict()
with open(filename, 'r') as h:
for line in h:
four_vals = line.split(',')
batch = four_vals[0]
if not batch in data:
data[batch] = []
data[batch] += [(float(four_vals[1]), float(four_vals[2]), float(four_vals[3]))]
return data
def calc_mean(sample):
if len(sample) == 0:
return
n = 0
x_sum = 0
for (x, y, val) in sample:
if x**2 + y**2 <= 1:
x_sum += val
n += 1
average = x_sum / n
return average
def main():
'''
This is the main body of the program.
'''
filename = user_input()
data = read_data(file_name)
for batch, sample in data.items():
average = calc_mean(sample)
if average is not None:
print(f"{batch}\t{average}")
else:
print(f"{batch}\t{No data}")

Doing a sort of a loop while avoiding a certain prerequisite (beginner/python)

A beginner's problem, here it goes:
I'm writing a program which keeps records of a game of darts. The user types in the players and their respective scores. It's possible to do a query about a player's scores and ask the program for the best overall score between all the players. I have the following functions:
add_score
return_players_score
return_best_score
exit_program
main
In main(), we begin by creating a new empty dictionary (say, players = {}). Then we ask the user to input a number that takes him/her to the function of choice (1: add_score etc.).
Now, once we're in add_score and have added a key:value pair (player:score), we need to go back to inputting the number taking to the function of choice. I implemented it simply by writing main() to the end of add_score.
That, however, takes us to the beginning, where there's players = {} and thus whatever data we input in add_score gets wiped out. This then affects other functions and the program remains useless as long as it forgets everything right away. How to solve this?
I'd paste the actual code but it's not in English and it's an assignment anyway...
Thanks.
Rather than calling main() from each of your other functions, you should just return (or run off the end of the function, which is equivalent to return None). Since you need the main function to run things repeatedly, you should use a loop.
def main():
players = {}
while True: # loop forever (until a break)
choice = input("what do you want to do (1-4)")
if choice == "1":
add_score(players)
elif choice == "2":
return_players_score(players)
#...
elif choice == "4":
break # break out of the loop to quit
else:
print("I didn't understand that.")
If you have a loop that does something like the following..
example:
while True:
players = {}
some code adding to players
This loop will always reset players to {}
However, if you do:
players = {}
while something:
some code adding to players
then players is not being reset at the start of each iteration through the loop
But your question is not clear
If you have something like this:
def add_score(dicccionary):
#do something with diccionary
main()
def main():
dicccionary = {}
while something:
option = input("option")
if option == 1:
addscore(dicccionary)
else:
#otherfunction
main()
your reset problem can be solve like:
dicccionary = {} #global variable
def add_score():
#do something with diccionary
main()
def main():
option = input("option")
if option == 1:
addscore()
else:
#otherfunction
main()
By the way, you shouldn't make it this way, try something as:
dicccionary = {} #global variable
def add_score():
#do something with diccionary
def main():
while somecondition:
option = input("option")
if option == 1:
addscore()
else:
#otherfunction
main()
If I was doing it for real then I would go for something like:
import sys
class ScoreKeeper(object):
def init(self):
self.scores = {}
def add_score(self, player, score):
self.scores[player] = score
def _print_player_score(self, player, score):
print 'player:', player, 'score:', score
def print_scores(self):
for player, score in self.scores.items():
self._print_player_score(player, score)
def best_score(self):
best, player = 0, "no player"
for player, score in self.scores.items():
if score > best:
best, player = score, player
self._print_player_score(player, best)
if __name__ == '__main__':
scorer = ScoreKeeper()
quit = lambda: sys.exit()
choices = quit, scorer.add_score, scorer.print_scores, scorer.best_score
def help():
print 'Enter choice:'
for index, c in enumerate(choices):
print '%d) %s' % (index, c.__name__)
def get_integer(prompt):
res = raw_input(prompt)
try:
return int(res)
except:
print 'an integer is required'
return get_integer(prompt)
def get_choice():
choice = get_integer('choice? ')
if not 0 <= choice < len(choices):
help()
return get_input()
return choice
help()
choice = get_choice()
while(choice):
args = []
if choices[choice] == scorer.add_score:
args.append(raw_input('player name? '))
args.append(get_integer('score? '))
choices[choice](*args)
choice = get_choice()
quit()

How do I have numbers increment slowly over a course of time throughout runtime

I am trying to make a text based game in which the user is a pilot in space. I want to create a movement system but am unsure how to do it. I want the user to be able to put in the desired grid coordinates, and his vehicle will begin to change its grid coords to get closer and closer to the ones he inputted.
Now, to do this I will probably need multithreading and a time element. But I am unsure how I can use a time element. Any advice is greatly appreciate, i'm just trying to learn here. Thanks guys!
from Gundam2 import Mobilesuits
#Main Variable/Object declarations:
Leo1=Mobilesuits(100,100,"Leo","leo desc","dockpit desc",100,[100,100,100])
Leo2=Mobilesuits(100,100,"Leo","leo desc","dockpit desc",100,[300,100,100])
Leo3=Mobilesuits(100,100,"Leo","leo desc","dockpit desc",100,[100,150,100])
currentmobilesuit=Leo1
#Main Function declarations
def commands(user_input,currentmobilesuit):
if user_input == "radar":
currentmobilesuit.radar()
elif user_input == "commands":
print("Command list:\nradar")
else:
print("Invalid command\nType 'commands' for a list of valid commands")
#Main execution
while True:
commands(raw_input(),currentmobilesuit)
class Mobilesuits:
#class global variables/methods here
instances = [] #grid cords here
def __init__(self,armor,speed,name,description,cockpit_description,\
radar_range, coordinates):
Mobilesuits.instances.append(self)
self.armor=armor
self.speed=speed
self.name=name
self.description=description
self.cockpit_description=cockpit_description
self.radar_range=radar_range
self.coordinates=coordinates
def can_detect(self, other):
for own_coord, other_coord in zip(self.coordinates, other.coordinates):
if abs(own_coord - other_coord) > self.radar_range:
return False
return True
def radar(self):
for other in Mobilesuits.instances:
if other is not self and self.can_detect(other):
print "%s detected at %s" % (other.description, other.coordinates)
Games typically have a "master loop" of some kind; yours does here:
#Main execution
while True:
commands(raw_input(),currentmobilesuit)
The simplest thing to do is to count in the loop:
#Main execution
turn_count = 0
while True:
commands(raw_input(),currentmobilesuit)
turn_count += 1
If you wanted the real time taken to have some impact on the counter, or be the counter, you can get the current time from the time module calling time.time().
#Main execution
import time
time_start = time.time()
time_elapsed = 0
while True:
commands(raw_input(),currentmobilesuit)
time_elapsed = time.time() - time_start
A couple other thoughts:
Make a Game class, and put the turn counter and game loop in that.
Have the commands function return a number that is the number of time units that took place during the command; for example, entering an invalid command might take 0 turns, while repairing a robot might take 5.
#Main execution
turn_count = 0
while True:
turns_taken = commands(raw_input(),currentmobilesuit)
turn_count += turns_taken
You can use non-blocking I/O. This will help you avoid the complications of threading. Here's your sample code implemented with a non-blocking read of stdin:
#!/usr/bin/python
import sys
import select
call_count = 0
#Main Function declarations
def commands(user_input):
global call_count
if len(user_input) > 0:
print('call count: ' + str(call_count) + ' user entered: ' + user_input)
def raw_input_no_block():
global call_count
call_count = call_count + 1
input_avail = select.select([sys.stdin], [], [], 0.1)[0] #wait for 0.1 seconds
if input_avail:
return sys.stdin.readline()
else:
return ''
#Main execution
while True:
commands(raw_input_no_block())

python while loop break

I am trying to make an on/off switch for my program:
(see after the ### for what I'm talking about)
while 1:
str = raw_input("insert your word: ")
n = input("insert your scalar: ")
def string_times(str, n):
return n * str
print string_times(str, n)
###
def switch(on,off):
raw_input("On or off? ")
if switch == "on":
continue
if switch == "off":
break
switch(on,off)
I get a continue not in loop error. Basically, I want to create an on or off switch after the program runs once. What do I fix?
You cannot use break and continue in a nested function. Use the return value of the function instead:
def switch():
resp = raw_input("On or off? ")
return resp == "on":
while True:
# other code
if not switch():
break
Note that there is little point in defining your functions in the loop. Define them before the loop, as creating the function object takes some performance (albeit a small amount).
The switch() function needs no arguments (you didn't use them at all), and the continue is also not needed. If you didn't break out of the loop, it'll just continue from the top when you reach the end.
You only need continue if you want the loop to start at the top again skipping the rest of the code in the loop:
count = 0
while True:
count += 1
print count
if loop % 2 == 0:
continue
print 'We did not continue and came here instead.'
if count >= 3:
break
print 'We did not break out of the loop.'

Categories

Resources