Birthday Reminder Application
The program checks whether a person has a birthday in a week and optionally sends reminders to the rest of the group. It involves the necessary functionalities for validating the input and sending emails. This repository contains 2 modules where bdayreminder.py involves these functionalities while tests.py tests the package. Please refer to Requirements for importing libraries, packages and addtional modules before looking at the Usage of the app or Functions, Tests, Cron Job and other fields.
- Table of contents
- Requirements
- Environment variables
- Authentication
- Usage
- Functions
- Datasets
- Tests
- Error
- Cron Job
- Public
- Logo
- License
Python 3.9.12 is required to properly execute package's modules, imported libraries and defined functions. Imports of several libraries like dotnet, pytest to name a few are also needed. Some required versions are found here while those that are not mentioned come with the used Python version. Also inspect environment variables and authentication before proceeding further. For proper usage of the program you might need to run python3 rather than proposed python as shown in the Usage.1
1python or python3 depends on the way how you installed python on your machine.
To be able to send emails you will need to set up environment variables. To do this locally, please create a .env
file and add two env variables to it with valid values, like this:1
USR=<youremail>
PSW=<yourpassword> or <token>
1 If you will send from gmail then to set up proper environment variable password you will need to create a token. Further info on this under authentication section.
To be able to send the email after setting Gmail email at environment variable you will need to create a token. Details on how to do it can be found here.
After the requirements are met, the app package is set at your directory and terminal is run you have four options1,2,3:
- To allow yourself to run validation or check & send providing the Python file and data file as arguments. You will then be prompted choose either option 1 (validate) or 2 (validate and send):
>>> python bdayreminder.py <data_file_path>
Choose 1 to validate if input data file is correct or 2 to check for upcoming birthdays and send respective emails
>>> 1
ERROR: Invalid email for Laura Dreyfuss at row 6
ERROR: Empty name field is for email [email protected] at row 7
ERROR: Invalid date for Anna Higgins at row 11. Date given is 02-30
ERROR: Date is in the future for Tom Brady at row 12. Date given is 2075-10-22
ERROR: Invalid email for Ching Yeung Michael Tam at row 19
'''
'''
>>> python bdayreminder.py <data_file_path>
Choose 1 to validate if input data file is correct or 2 to check for upcoming birthdays and send respective emails
>>> 2
Kai Yuen Leung will have birthday in a week.
Patrick Kienzle will have birthday in a week.
Emails sent successfully.
- To run validation or check & send providing the Python file, data file and any number other than 1 or 2 as arguments. You will then be prompted choose either option 1 (validate) or 2 (validate and send), as no other numbers are options:
>>> python bdayreminder.py <data_file_path> 3
Choose 1 to validate if input data file is correct or 2 to check for upcoming birthdays and send respective emails
>>> 3
Please choose either 1 or 2
>>> 1
ERROR: Invalid email for Laura Dreyfuss at row 6
ERROR: Empty name field is for email [email protected] at row 7
ERROR: Invalid date for Anna Higgins at row 11. Date given is 02-30
ERROR: Date is in the future for Tom Brady at row 12. Date given is 2075-10-22
ERROR: Invalid email for Ching Yeung Michael Tam at row 19
- You can avoid having the prompt displayed to you altogether. To validate birthday persons data file for errors set the second argument to be 1:
>>> python bdayreminder.py <data_file_path> 1
ERROR: Invalid email for Laura Dreyfuss at row 6
ERROR: Empty name field is for email [email protected] at row 7
ERROR: Invalid date for Anna Higgins at row 11. Date given is 02-30
ERROR: Date is in the future for Tom Brady at row 12. Date given is 2075-10-22
ERROR: Invalid email for Ching Yeung Michael Tam at row 19
- To check birthday persons data file and send emails set the second argument to be 2:
>>> python bdayreminder.py <data_file_path> 2
Kai Yuen Leung will have birthday in a week.
Patrick Kienzle will have birthday in a week.
Emails sent successfully.
1 <data_file_path> should look like this - Datasets/data_20.csv, but in your directory. The full path for me would be /Users/aurimasnausedas/Documents/Python/BirthdayReminderApp/Datasets/data_20.csv
2 Main module takes two arguments when run from console.
3 The data used for examples was data_20.csv on 23th of June 2022.
An overview of functions found inside a module - bdayreminder.py:
- validate_data_and_send_emails(input_file, send_emails) checks the validity of an input_file and whether a birthday is in a week as well as optionally sends the respective emails (send_emails).
- parse_date(date) parses the date.
- is_valid_input(date_format, item, index, to_print) validates inputs (date_format,item,index,to_print).
- send_multiple_emails(birthday_individuals, to_send) sends emails to recipients of to_send list.
- is_date_in_past(date, date_format) looks if date is in the past.
- is_valid_email(email) checks if an email is valid.
- send_email(name, bday_name, bday_date, days_left, to_email) sends an email to a recipient (name,to_email) as a reminder of a birthday (bday_name,bday_date) in advance (days_left).
- run(read_path, cron_value) takes the csv data file and runs the script without as choices are passed as arguments (read_path,cron_value).
- choose_options(read_path) asks for input (read_path) and chooses option to run.
In depth explanations of the functions can be found inside a module - bdayreminder.py.
There are three possible datasets to use. These are data_20 of 20 recipients, data_50 of 50 recipients and data_80 of 80 recipients.
An overview of functions found inside a module - tests.py:
- test_correct_parse_date_ymd() tests if the correct date is parsed.
- test_correct_parse_date_md() tests if the correct date is parsed.
- test_is_date_in_past_old() tests if the old date is in the past.
- test_is_date_in_past_future() tests if the future date is in the past.
- test_is_date_in_past_past_month_day() tests if the old date is in the past.
- test_is_valid_email_good() tests if the email address is valid.
- test_is_valid_email_bad() tests if the email address is invalid.
By navigating to the program/app folder where it is extracted - BirthdayReminderApp - one folder before where tests.py is held and one can run these test commands:
- To check source files for errors in the project folder:
>>> pyflakes .
- To check source files for errors in test file:
>>> pyflakes Tests/tests.py
- To check typing for test file:
>>> python -m pytest Tests/tests.py
There could arise a few errors like:
- 1st argument error if the provided 1st argument is of different format to the csv format:
>>> python bdayreminder.py Datasets/data_20.json 1
Traceback (most recent call last):
File "/Users/aurimasnausedas/Documents/Python/BirthdayReminderApp/bdayreminder.py", line 237, in <module>
run(arg_path, cron_input)
File "/Users/aurimasnausedas/Documents/Python/BirthdayReminderApp/bdayreminder.py", line 215, in run
raise Exception('ERROR: Wrong data format file')
Exception: ERROR: Wrong data format file
- 1st argument error if the provided 1st argument of data file doesn't exist:
>>> python bdayreminder.py Datasets/data_13.csv 1
Traceback (most recent call last):
File "/Users/aurimasnausedas/Documents/Python/BirthdayReminderApp/bdayreminder.py", line 237, in <module>
run(arg_path, cron_input)
File "/Users/aurimasnausedas/Documents/Python/BirthdayReminderApp/bdayreminder.py", line 199, in run
raise Exception('ERROR: File doesn\'t exist')
Exception: ERROR: File doesn't exist
- 2nd argument error if the provided 2nd argument is a string:
>>> python bdayreminder.py Datasets/data_20.csv versada
Argument passed not an integer
There are more yet these would be the most common.
To build cron job in mac terminal run:
>>> crontab -e
The syntax for cronjob when entering terminal could look like this:1,2,3
>>> 0 6 * * * cd <directory_to_app> && <directory_to_python> bdayreminder.py <data_file_path> 2
[Optional] >>> 0 6 * * * cd <directory_to_app> && <directory_to_python> bdayreminder.py <data_file_path> 2 >> Public/birthdays.txt
1 <directory_to_app> - should be the directory where BirthdayReminderApp folder is like /Users/aurimasnausedas/Documents/Python/BirthdayReminderApp
2 <directory_to_python> should be where you installed python on your machine like /Users/aurimasnausedas/opt/miniconda3/envs/symmetric/bin/python
3 <data_file_path> should be the dataset in the directory of app like in /Users/aurimasnausedas/Documents/Python/BirthdayReminderApp by setting it to Datasets/data_20.csv
Syntax customization for Cron Job can be checked here.
Public folder contains three files:
- birthdays.txt - the output of a Cron Job after implementing the [Optional] command as given at Cron Job field.
- todolist - the TO DO List.
The logo of the Birthday Reminder Application can be found here.
The MIT LICENSE