<jupyter_start><jupyter_text>StopWatch IntroductionEver tried to measure how long does it take for your code to execute?Soon after you start, you find your precious code full of dirty "prints" and filthy "time.time()" lines.Does it need to be that ugly to quickly time your code? Fear no more, **StopWatch** is here.<jupyter_code>import time
from nanoprobe.cronos import StopWatch

s = StopWatch()<jupyter_output><empty_output><jupyter_text>StopWatch's beauty relies on its simplicity. It works like a real stopwatch would, you start it when you want and you stop it when you desire<jupyter_code>s.start()
time.sleep(2)
s.stop()<jupyter_output><empty_output><jupyter_text>You can check the elapsed time between the two checkpoints like this:<jupyter_code>s.elapsed_time<jupyter_output><empty_output><jupyter_text>Well, this wasn't *that* exciting, was it?Bear with me here, cool stuff is about to happen. Clicks and probes, a love storyThe most useful feature of StopWatch are *clicks* and *probes*<jupyter_code>s = StopWatch(autostart=True) #You can start your stopwatch automatically

time.sleep(2)
s.click("sleep1")
time.sleep(3)
s.click("sleep2")
time.sleep(1)
s.click() #Default format goes like 'click-X'
s.stop()

s.pprint_probes() #"Pretty" prints all recorded probes<jupyter_output>TAG    		ELAPSED TIME

start  		1517682330.624907
sleep1 		2.002435
sleep2 		5.005860
click-0		6.007235
stop   		1517682336.632258<jupyter_text>Although this example is pretty self-explanatory lets walk through it together.**Probes** are checkpoints which record the period in seconds from the start of the stopwatch until that exact moment.You can record probes calling the **click** method, which creates a probe and identifies it with a tag you can define.If you don't feel like defining anything fine! Leave it blank! StopWatch will create a default tag for you.As you can see, *start* and *stop* probes are a little bit different as they don't save any elapsed time, they store the time they were called.  Tag like a champ with custom tagsDid you ever find yourself declaring a variable and appending it to the stopwatch' click function?<jupyter_code>s = StopWatch(autostart=True)

i = 0
for a in range(100): #You could use the 'a' variable here, but come on, im trying to explain something here!
    o = 2 ** 3
    s.click("For-{}".format(i))
s.pprint_probes()<jupyter_output>TAG  		ELAPSED TIME

start		1517682336.649342
For-0		0.000440<jupyter_text>God damn that was ugly. Let's not do that anymore.To solve this, StopWatch supports the so-called **custom tags**. Custom tags<jupyter_code>s = StopWatch(autostart=True)

for _ in range(10):
    o = 2 ** 3
    s.click("For-{{for1}}")
s.pprint_probes()<jupyter_output>TAG  		ELAPSED TIME

start		1517682336.732782
For-0		0.000176
For-1		0.000218
For-2		0.000240
For-3		0.000260
For-4		0.000280
For-5		0.000300
For-6		0.000319
For-7		0.000337
For-8		0.000511
For-9		0.000540<jupyter_text>That was refreshing!The thing about **custom tags** is that you can stack as many as your heart can handle<jupyter_code>s = StopWatch(autostart=True)

s.click("For {{a}} - {{b}}")
s.click("{{a}}")
s.click("{{a}} - {{b}}")

s.pprint_probes()<jupyter_output>TAG      		ELAPSED TIME

start    		1517682336.853547
For 0 - 0		0.000099
1        		0.000221
2 - 1    		0.000313<jupyter_text>If for some reason you want a custom tag to not autoincrement at a certain time you can use non-incremental custom tags (I know, good naming skills right there)<jupyter_code>s = StopWatch(autostart=True, rounding_precision=4)
for _ in range(2):
    s.click("Reached for {{a}}")
    for _ in range(5):
        s.click("Reached for {{b}} inside for {a}") #Notice how {a} is not supposed to increment on each iteration
s.pprint_probes()<jupyter_output>TAG                       		ELAPSED TIME

start                     		1517682336.957227
Reached for 0             		0.000200
Reached for 0 inside for 1		0.000300
Reached for 1 inside for 1		0.000300
Reached for 2 inside for 1		0.000300
Reached for 3 inside for 1		0.000400
Reached for 4 inside for 1		0.000400
Reached for 1             		0.000400
Reached for 5 inside for 2		0.000400
Reached for 6 inside for 2		0.000500
Reached for 7 inside for 2		0.000500
Reached for 8 inside for 2		0.000500
Reached for 9 inside for 2		0.000600<jupyter_text>Save data from a StopWatchYou can save the data in a CSV format easily<jupyter_code>s.csv_dump("cronos_example.csv") #Saves to a file
s.csv_dumps() #Gets csv info in string format<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08716814159292036, 'fraction_numerical': 0.07964601769911504, 'mean_word_length': 4.196551724137931, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 1, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '195106', 'license': 'MIT', 'n_tokens_mistral': 1797, 'n_tokens_neox': 1560, 'n_words': 562, 'path': 'examples/StopWatch.ipynb', 'repo_name': 'OrbitalAds/nanoprobe', 'size': '4520'}