diff --git a/LoadingIcon/README.md b/LoadingIcon/README.md new file mode 100644 index 0000000..d97f484 --- /dev/null +++ b/LoadingIcon/README.md @@ -0,0 +1,5 @@ + +# Loading Icon + +When doing a lengthy calculation, instead of staring at a blank screen, the program runs a spinner to show that it's still working. +In the threading example the spinner is running in a different thread, in the async example, the spinner is another task in the event loop. diff --git a/LoadingIcon/async_spinner.py b/LoadingIcon/async_spinner.py new file mode 100644 index 0000000..e2a8107 --- /dev/null +++ b/LoadingIcon/async_spinner.py @@ -0,0 +1,43 @@ +import asyncio +import itertools +import sys + + +async def spin(msg): + write, flush = sys.stdout.write, sys.stdout.flush + + for char in itertools.cycle('|/-\\'): + status = char + ' ' + msg + write(status) + flush() + write('\x08' * len(status)) + + try: + await asyncio.sleep(0.1) + except asyncio.CancelledError: + break + + write(' ' * len(status) + '\x08' * len(status)) + + +async def slow_function(): + await asyncio.sleep(5) + return 42 + + +async def supervisor(): + spinner = asyncio.ensure_future(spin('Thinking!')) + result = await slow_function() + spinner.cancel() + return result + + +def main(): + loop = asyncio.get_event_loop() + result = loop.run_until_complete(supervisor()) + loop.close() + print('Answer:', result) + + +if __name__ == '__main__': + main() diff --git a/LoadingIcon/threading_spinner.py b/LoadingIcon/threading_spinner.py new file mode 100644 index 0000000..a1aa20e --- /dev/null +++ b/LoadingIcon/threading_spinner.py @@ -0,0 +1,49 @@ + +import threading +import itertools +import time +import sys + + +class Signal: + go = True + + +def spin(msg, signal): + write, flush = sys.stdout.write, sys.stdout.flush + + for char in itertools.cycle('|/-\\'): + status = char + ' ' + msg + write(status) + flush() + write('\x08' * len(status)) + time.sleep(0.1) + + if not signal.go: + break + + write(' ' * len(status) + '\x08' * len(status)) + + +def slow_function(): + time.sleep(5) + return 42 + + +def supervisor(): + signal = Signal() + spinner = threading.Thread(target=spin, args=('thinking!', signal)) + spinner.start() + result = slow_function() + signal.go = False + spinner.join() + return result + + +def main(): + result = supervisor() + print('Answer:', result) + + +if __name__ == '__main__': + main()