<jupyter_start><jupyter_text>Welcome to the Utilities PackageThis package contains some boilerplate, fairly general-purpose utility code that you might find useful. The package currently can do one thing:* Easily send email or text messages on completion of a code block.  Sending notificationsWARNING: To use this feature, your code will have to provide login information for an email provider. Be careful with this information -- hard-coding a username and password into a notebook that you might share is a good way to leak private information. You may wish to have your program read username and password information from another source (such as a file or the command line). Even better, you can create a separate email account for automated notifications, so that your program never has access to your "real" credentials.(Please don't use the lab email account. If you accidentally release that information, it will be a pain for all of us to deal with.)The Utilities package includes a wrapper for sending automated email alerts when a piece of code is done running. To do this, it will need to log into an email account, for which you must provide a username and password. It will also need to know where you want your alerts sent. This is done with the `set_credentials` and `set_destionation` functions. You only need to run these functions once per script.Setting up an automatic message looks like this:<jupyter_code>import murraylab_tools.utilities as mt_utils
import time

mt_utils.set_credentials("put_your_username_here", "put_your_password_here")
mt_utils.set_destination("<EMAIL>")

with mt_utils.notify_when_done("A block"):
    print("I'm doing a thing.")
    print("I'm doing a second thing.")
    time.sleep(3)
    print("I'm done.")<jupyter_output>/home/sclamons/Downloads/murraylab_tools_local/murraylab_tools/utilities/utilities.py:51: RuntimeWarning: Connection to email server failed. Run will continue without notifications.
  warnings.warn("Connection to email server failed. "\<jupyter_text>The login above will fail, since I'm not providing real credentials here, but you can see how the program behaves when a login fails -- it will notify you that it didn't connect, and will keep running. If you want to see more information about how the connection went wrong, you can set that with the debug_connection flag:<jupyter_code>with mt_utils.notify_when_done("A block", debug_connection = True):
    print("I'm doing a thing.")
    print("I'm doing a second thing.")
    time.sleep(3)
    print("I'm done.")<jupyter_output>Connection error is:
Traceback (most recent call last):
  File "/home/sclamons/Downloads/murraylab_tools_local/murraylab_tools/utilities/utilities.py", line 49, in __enter__
    server = self.connect_to_server()
  File "/home/sclamons/Downloads/murraylab_tools_local/murraylab_tools/utilities/utilities.py", line 90, in connect_to_server
    server.login(_username, _password)
  File "/usr/lib/python3.8/smtplib.py", line 734, in login
    raise last_exception
  File "/usr/lib/python3.8/smtplib.py", line 723, in login
    (code, resp) = self.auth(
  File "/usr/lib/python3.8/smtplib.py", line 646, in auth
    raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8  https://support.google.com/mail/?p=BadCredentials 128sm1531430pfx.187 - gsmtp')

I'm doing a thing.
I'm doing a second thing.
I'm done.<jupyter_text>By default, the `notify_when_done` class sends notifications to gmail's public smtp server at port 587. If you use another email provider, or if you want to use a different port for some reason, you can change the server and port in the call to `notify_when_done`:<jupyter_code>with mt_utils.notify_when_done("A block", server = "my.email.server", port = "777"):
    print("I'm doing a thing.")
    print("I'm doing a second thing.")
    time.sleep(3)
    print("I'm done.")<jupyter_output>I'm doing a thing.
I'm doing a second thing.
I'm done.<jupyter_text>If you'd rather receive a text than an email, you can probably do so by setting your destination correctly. Most phone providers have an email service that will convert emails sent to some address into a text, using the following format:* AT&T: <EMAIL> (SMS), <EMAIL> (MMS)* T-Mobile: <EMAIL> (SMS & MMS)* Verizon: <EMAIL> (SMS), <EMAIL> (MMS)* Sprint: <EMAIL> (SMS), <EMAIL> (MMS)* Republic Wireless: <EMAIL> (SMS)* Google Fi (Project Fi): <EMAIL> (SMS & MMS)So, for example, if your phone number is 555-432-1098 and you get your phone service through Republic Wireless, you would set your code to send you a text by running:<jupyter_code>mt_utils.set_destination("<EMAIL>")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0849036629261063, 'fraction_numerical': 0.013127249629472792, 'mean_word_length': 4.934673366834171, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '331336', 'license': 'MIT', 'n_tokens_mistral': 1424, 'n_tokens_neox': 1356, 'n_words': 584, 'path': 'examples/Utilities Usage Examples.ipynb', 'repo_name': 'dr3y/murraylab_tools', 'size': '4893'}