I'm a relatively new python coder and I am having problems attempting to print successful_trades/unsuccessful_trades after a 10 second simulation. The only thing I can think of is making the line of code saying 'print("Successful ender pearl trade")' an operator (which obviously won't work). Any help would be greatly appreciated, code is below. Thank you!
import multiprocessing
import time
import random
successful_trades = 0
unsuccessful_trade = 0
# Your foo function
def foo(n):
for i in range(10000 * n):
print ("Tick")
time.sleep(1)
if __name__ == '__main__':
# Start foo as a process
p = multiprocessing.Process(target=foo, name="Foo", args=(10,))
p.start()
# Wait 10 seconds for foo
time.sleep(10)
# Terminate foo
p.terminate()
# Cleanup
p.join()
user_input = input()
if user_input == "o":
while True:
import random
k = random.randint(1, 109)
number = random.randint(1, 109)
if str(number) == str(k):
print("Successful ender pearl trade")
(str(successful_trades) + str(1))
if str(number) != str(k):
print("Unsuccessful ender pearl trade")
(str(unsuccessful_trade) + str(1))
It works for me
One theory is your infinite while loop is locking up the screen output.
You can test this by changing your while true loop to
for i in range(100):
Related
import time
import random
def timer():
correct = 1
x = 0
while correct != 2:
time.sleep(0.1)
x = x + 0.1
def round1():
numb = random.randint(1, 100)
print(numb)
timer()
ans = input(">")
if ans == numb:
correct = 2
x = round(x)
print("you did that in", x ,"seconds!")
round1()
I was trying to get both functions to run together (have the game playing and the timer going in the background) but as soon as the timer started it would let me continue the game.
In the given program, I have created two different functions that will work at the same time. I have used threading to create thread of functions and sleep to limit the printing speed. In similar manner you can use game and timer function together.
from threading import Thread
from time import sleep
#sleep is used in functions to delay the print
#the below functions has infinite loop that will run together
#defining functions
def func1():
for x in range(20):
sleep(1)
print("This is function 1.")
def func2():
for x in range(10):
sleep(2)
print("This is function 2.")
#creating thread
thread1=Thread(target=func1)
thread2=Thread(target=func2)
#running thread
thread1.start()
thread2.start()
So I wanted to make my own Omegle interface in Python to get some practice with the language, and also it just sounded like fun. In order to handle the inputs and outputs at the same time, I've decided to use multithreading. This is my first time working with multithreading, so I don't really know what I am doing. Whenever I try and use input() while in a multithreaded function, it returns an EOF error. Any idea how to get around it, or if I'm going about this the entirely wrong way, what is a better way to do this?
Code:
from python_omegle import InterestsChat
from python_omegle import ChatEvent
from multiprocessing import Process
import sys
def start_chat_loop():
interests = input("Please input interests: ").split
chat = InterestsChat(interests)
chat_loop(chat=chat)
p2 = Process(target = take_input)
p2.start()
def take_input():
while True:
i = input()
if(i == "/next"):
chat.disconnect()
else:
print("You: typing...")
chat.send(i)
print("You: "+i)
def chat_loop(chat):
while True:
# Start a new chat every time the old one ends
print("- Starting chat -")
chat.start()
while True:
event, argument = chat.get_event()
if event == ChatEvent.CHAT_WAITING:
print("- Waiting for a partner -")
elif event == ChatEvent.CHAT_READY:
common_interests = argument
print("- Connected, common interests: {} -".format(*common_interests))
break
# Connected to a partner
while True:
event, argument = chat.get_event()
if event == ChatEvent.GOT_SERVER_NOTICE:
notice = argument
print("- Server notice: {} -".format(notice))
elif event == ChatEvent.PARTNER_STARTED_TYPING:
print("- Partner started typing -")
elif event == ChatEvent.PARTNER_STOPPED_TYPING:
print("- Partner stopped typing -")
elif event == ChatEvent.GOT_MESSAGE:
message = argument
print("Partner: {}".format(message))
elif event == ChatEvent.CHAT_ENDED:
print("- Chat ended -")
break
if __name__ == "__main__":
p1 = Process(target = start_chat_loop)
p1.start()
Problem spots:
def start_chat_loop():
interests = input("Please input interests: ").split
chat = InterestsChat(interests)
chat_loop(chat=chat)
p2 = Process(target = take_input)
p2.start()
def take_input():
m = False
while True:
i = input()
if(i == "/next"):
chat.disconnect()
else:
print("You: typing...")
caht.send(i)
print("You: "+i)
Does your chat.disconnect() method have a way of escaping an endless loop? I'm not too advanced with this but I believe you should either do:
if(i == "/next"):
chat.disconnect()
break
or
def take_input():
m = False
while not m:
i = input()
if(i == "/next"):
chat.disconnect()
m = True
else:
print("You: typing...")
chat.send(i)
print("You: "+i)
I also noticed in the 2nd block of code that its written:
caht.send(i) instead of chat.send(i). A syntax error might be preventing the loop of ending as well thus resulting in EOF.
I am trying out multiprocessing for my Monty Hall game simulation for improved performance. The game is payed 10mm times and takes ~17 seconds when directly run, however, my multiprocessing implementation is taking significantly longer to run. I am clearly doing something wrong but I can't figure out what.
import multiprocessing
from MontyHall.game import Game
from MontyHall.player import Player
from Timer.timer import Timer
def doWork(input, output):
while True:
try:
f = input.get(timeout=1)
res = f()
output.put(res)
except:
break
def main():
# game setup
player_1 = Player(True) # always switch strategy
game_1 = Game(player_1)
input_queue = multiprocessing.Queue()
output_queue = multiprocessing.Queue()
# total simulations
for i in range(10000000):
input_queue.put(game_1.play_game)
with Timer('timer') as t:
# initialize 5 child processes
processes = []
for i in range(5):
p = multiprocessing.Process(target=doWork, args=(input_queue, output_queue))
processes.append(p)
p.start()
# terminate the processes
for p in processes:
p.join()
results = []
while len(results) != 10000000:
r = output_queue.get()
results.append(r)
win = results.count(True) / len(results)
loss = results.count(False) / len(results)
print(len(results))
print(win)
print(loss)
if __name__ == '__main__':
main()
This is my first post. Advice on posting etiquette is also appreciated. Thank you.
Code for the Classes:
class Player(object):
def __init__(self, switch_door=False):
self._switch_door = switch_door
#property
def switch_door(self):
return self._switch_door
#switch_door.setter
def switch_door(self, iswitch):
self._switch_door = iswitch
def choose_door(self):
return random.randint(0, 2)
class Game(object):
def __init__(self, player):
self.player = player
def non_prize_door(self, door_with_prize, player_choice):
"""Returns a door that doesn't contain the prize and that isn't the players original choice"""
x = 1
while x == door_with_prize or x == player_choice:
x = (x + 1) % 3 # assuming there are only 3 doors. Can be modified for more doors
return x
def switch_function(self, open_door, player_choice):
"""Returns the door that isn't the original player choice and isn't the opened door """
x = 1
while x == open_door or x == player_choice:
x = (x + 1) % 3 # assuming there are only 3 doors. Can be modified for more doors
return x
def play_game(self):
"""Game Logic"""
# randomly places the prize behind one of the three doors
door_with_prize = random.randint(0, 2)
# player chooses a door
player_choice = self.player.choose_door()
# host opens a door that doesn't contain the prize
open_door = self.non_prize_door(door_with_prize, player_choice)
# final player choice
if self.player.switch_door:
player_choice = self.switch_function(open_door, player_choice)
# Result
return player_choice == door_with_prize
Code for running it without multiprocessing:
from MontyHall.game import Game
from MontyHall.player import Player
from Timer.timer import Timer
def main():
# Setting up the game
player_2 = Player(True) # always switch
game_1 = Game(player_2)
# Testing out the hypothesis
with Timer('timer_1') as t:
results = []
for i in range(10000000):
results.append(game_1.play_game())
win = results.count(True) / len(results)
loss = results.count(False) / len(results)
print(
f'When switch strategy is {player_2.switch_door}, the win rate is {win:.2%} and the loss rate is {loss:.2%}')
if __name__ == '__main__':
main()
As you did not give the full code that we can run locally, I can only speculate. My guess is that you are passing an object(a method from your game) to other processes so pickling and unpickling took too much time. Unlike multithreading where you can "share" data, in multiprocessing, you need to pack the data and send to the other process.
However, there's a rule I always follow when I try to optimize my code - profile before optimizing! It would be much better to KNOW what's slow than GUESS.
It's a multiprocessing program so there are not a lot of options in the market. You could try viztracer which supports multiprocessing.
pip install viztracer
viztracer --log_multiprocess your_program.py
It will generate a result.html that you can open with chrome. Or you can just do
vizviewer result.html
I would suggest to reduce the iteration number so you can have a view of the whole picture(because viztracer uses a circular buffer and 10 million iterations will definitely overflow). But, you can still get the last piece of your code executing if you don't, which should be helpful enough for you to figure out what's going on.
I used viztracer as you gave the whole code.
This is one of your iteration in your worker process. As you can tell, the actual working part is very small(the yellow-ish slice in the middle p...). Most of the time has been spent on receiving and putting data, which eliminates the advantage of parallelization.
The correct way to do this is do it in batches. Also as this game does not actually require any data, you should just sent "I want to do it 1000 times" to the process, and let it do it, instead of sending the method one by one.
There's another interesting problem that you can easily find with viztracer:
This is the big picture of your worker process. Notice the large "nothing" in the end? Because your worker needs a timeout to finish, and that's when they are waiting. You should come up with a better idea to elegantly finish your worker process.
Updated my code. I fundamentally misunderstood the multiprocessing method.
def do_work(input, output):
"""Generic function that takes an input function and argument and runs it"""
while True:
try:
f, args = input.get(timeout=1)
results = f(*args)
output.put(results)
except:
output.put('Done')
break
def run_sim(game, num_sim):
"""Runs the game the given number of times"""
res = []
for i in range(num_sim):
res.append(game.play_game())
return res
def main():
input_queue = multiprocessing.Queue()
output_queue = multiprocessing.Queue()
g = Game(Player(False)) # set up game and player
num_sim = 2000000
for i in range(5):
input_queue.put((run_sim, (g, num_sim))) # run sim with game object and number of simulations passed into
# the queue
with Timer('Monty Hall Timer: ') as t:
processes = [] # list to save processes
for i in range(5):
p = multiprocessing.Process(target=do_work, args=(input_queue, output_queue))
processes.append(p)
p.start()
results = []
while True:
r = output_queue.get()
if r != 'Done':
results.append(r)
else:
break
# terminate processes
for p in processes:
p.terminate()
# combining the five returned list
flat_list = [item for sublist in results for item in sublist]
print(len(flat_list))
print(len(results))
I am running a script with multiprocessing map_async. what I need to do is to get the uncomplete result of AsyncResult object (assuming it already finished calculating some of the cases given) after terminating Pool with terminate(). using get() would just hang the script, how can I do this?
I know this can be done with apply_sync with some manipulation, but can it be done somehow with map_async?
working example of the situation:
import multiprocessing
import time
def example_run(i):
time.sleep(0.7)
return i
if __name__ == '__main__':
terminate = False
pool = multiprocessing.Pool(10)
result_async = pool.map_async(example_run,range(100))
i = 0
while True:
time.sleep(1.0)
if i == 70:
terminate = True
print(result_async.ready(),terminate)
if result_async.ready():
break
elif terminate:
pool.terminate()
break
i += 10
result = result_async.get() # The problem is here, it will just wait
print(result)
pool.close()
pool.join()
I found a solution to the problem; with some digging, AsyncResult._value seem to hold the values of the execution, with None in case it is not evaluated yet
import multiprocessing
import time
def example_run(i):
time.sleep(0.7)
return i
if __name__ == '__main__':
terminate = False
pool = multiprocessing.Pool(10)
result_async = pool.map_async(example_run,range(100))
i = 0
while True:
time.sleep(1.0)
if i == 70:
terminate = True
print(result_async.ready(),terminate)
if result_async.ready():
break
elif terminate:
pool.terminate()
break
i += 10
result = []
for value in result_async._value:
if value is not None:
result.append(value)
else:
result.append("failed")
print(result)
pool.close()
pool.join()
I was wondering if it was possible to perform an action at any given point in a basic python script, so say when it is close. I have the following code to find prime numbers (Just for fun)
number = 1
primelist = []
nonprime = []
while number < 1000:
number += 1
for i in range(number):
if i != 1 and i != number and i !=0:
if number%i == 0:
nonprime.append(number)
else:
primelist.append(number)
nonprimes = open("nonprimes.txt", "w")
for nonprime in set(primelist) & set(nonprime):
nonprimes.write(str(nonprime) + ", ")
nonprimes.close()
So basically i wanted to run the last part as the script is stopped. If this isn't possible is there a way where say i press "space" while the program is running and then it saves the list?
Cheers in advance :)
EDIT:
I've modified the code to include the atexit module as suggested, but it doesn't appear to be working. Here it is:
import time, atexit
class primes():
def __init__(self):
self.work(1)
def work(self, number):
number = 1
self.primelist = []
self.nonprime = []
while number < 20:
time.sleep(0.1)
print "Done"
number += 1
for i in range(number):
if i != 1 and i != number and i !=0:
if number%i == 0:
self.nonprime.append(number)
else:
self.primelist.append(number)
nonprimes = open("nonprimes.txt", "w")
for nonprime in set(self.primelist) & set(self.nonprime):
nonprimes.write(str(nonprime) + ", ")
nonprimes.close()
def exiting(self, primelist, nonprimelist):
primelist = self.primelist
nonprimelist = self.nonprime
nonprimes = open("nonprimes.txt", "w")
for nonprime in set(self.primelist) & set(self.nonprime):
nonprimes.write(str(nonprime) + ", ")
nonprimes.close()
atexit.register(exiting)
if __name__ == "__main__":
primes()
While I'm pretty certain the file object does cleanup and flushes the stuff to file when it is reclaimed. The best way to go about this is to use a with statement.
with open("nonprimes.txt", "w") as nonprimes:
for nonprime in set(primelist) & set(nonprime):
nonprimes.write(str(nonprime) + ", ")
The boiler plate code of closing the file and such is performed automatically when the statement ends.
Python has an atexit module that allows you to register code you want executed when a script exits:
import atexit, sys
def doSomethingAtExit():
print "Doing something on exit"
atexit.register(doSomethingAtExit)
if __name__ == "__main__":
sys.exit(1)
print "This won't get called"