From fa07a8509f4d2c3a54c15934792f1b2f6139d592 Mon Sep 17 00:00:00 2001 From: Ioannis Doganos Date: Tue, 7 Nov 2023 18:28:32 +0100 Subject: [PATCH] Job Application Tracker Version 0.1 --- Job Application Tracker logo.png | Bin 0 -> 17565 bytes Job_Application_Tracker.py | 164 +++++++++++++++++++++++++++++++ README.md | 52 ++++++++++ 3 files changed, 216 insertions(+) create mode 100644 Job Application Tracker logo.png create mode 100644 Job_Application_Tracker.py create mode 100644 README.md diff --git a/Job Application Tracker logo.png b/Job Application Tracker logo.png new file mode 100644 index 0000000000000000000000000000000000000000..39b6662113e111a479813b2d2db4a51255864ff0 GIT binary patch literal 17565 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 literal 0 HcmV?d00001 diff --git a/Job_Application_Tracker.py b/Job_Application_Tracker.py new file mode 100644 index 0000000..f3b78c3 --- /dev/null +++ b/Job_Application_Tracker.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python3 + +######################################################################## +# Job Aplication Tracker # +# Easily track the job applications you have done. # +# Written in Pyton. # +# # +# Version 0.1 # +#----------------------------------------------------------------------# +# Licence: Apache License 2.0 # +# # +# Creator: Ioannis Doganos, github: https://github.com/Ioannis-D # +######################################################################## + +# ------------ LIBRARIES USED ------------ +from datetime import date # For the current day +from pathlib import Path # To check if the spreadsheet exists +import pandas as pd # To manipulate the data and the spreadsheet +import time # For the sleep operation +import readline # To pre-print the Job and Company already given if the user wants to modify them +import argparse # For the help message + +# ------------ HELP MESSAGE ------------ +help_message = """ +This is a program written in Python for letting you store your job applications nicely and tidy into a spreadsheet (.xlsx). + +It is easy and fast to use: + Firstly, the program will ask you to insert the url of the job position you have applied. + Secondly, it will ask you for the Job Title and the Company's name. +Please note that empty cells are not allowed which means you will have to provide all three components else the tracking is stopped. + +You can leave the program open until you are done with all your applications for the day. +At the end, your new registrations will be shown to you in order to make possible changes in case of an error. +The program automatically records the date and inserts it in the spreadsheet. + +You do not have to create any spreadsheet yourself. Once run, the program creates everything for you! + +So, good luck with your job hunting and be sure to track it! +""" + +parser = argparse.ArgumentParser(prog="Job Application Tracker", + formatter_class=argparse.RawDescriptionHelpFormatter, + description=help_message + ) +args = parser.parse_args() + +# ------------ FUNCTIONS ------------ + +# Make sure no job title or company is added empty. In this case, ask the user if he wants to exit the program. +def titles(_input): + title = input(_input) + if title != "": + return title + else: + print(f"You didn't provide a {_input}.") + print("Press Enter if you wanna exit the program") + title = input(_input) + if title != "": + return title + else: + return + +# Stop the process of job applications recording if the user wants it. +def empty_titles(title): + if title != None: return False + else: return True + +# Write the dataframe to Excel +def write_spreadsheet(path, df): + df.to_excel( + "./Job_Aplications.xlsx", + sheet_name="Job Applications", + index=False + ) + +# Check the input when the user gives a number to modify the data given +def check_input(position_number,df_temp): + try: + df_temp.iloc[int(position_number)] + except: + return False + else: + return True +# Change the input +def change_input(position_number, title, df_temp): + given_title = df_temp[title].iloc[int(position_number)] + new_title = input_with_prefill(f"{title}: ", given_title) + return new_title + +# Return the given job or company name if to be modified +def input_with_prefill(prompt, text): + def hook(): + readline.insert_text(text) + readline.redisplay() + readline.set_pre_input_hook(hook) + result = input(prompt) + readline.set_pre_input_hook() + return result + + +# ------------ MAIN PROGRAM ------------ + +# Register the date in the form dd/mm/yy +today = date.today().strftime("%d/%m/%y") + +# Create an empty df to store the new data. Later on, it is added to the existing data in excel +df_temp = pd.DataFrame(columns=['Company', 'Job Title', 'url', 'Date of Aplication']) + +# Keep the program alive until the user does not give a url or until empty job title or company name is given twice. +while True: + + # Ask for the url, the job title and the company's name + url = input("URL: (press ENTER to finish) ") + if(url == ""): # If url is given empty it means the user wants to exit. + print("Exiting.\nGood luck with the applications\n") + break + + job_title = titles("Job Title: ") + if empty_titles(job_title): break + + company_name = titles("Company Name: ") + if empty_titles(company_name): break + + # Insert the data into the dataframe + df_temp.loc[len(df_temp)] = [company_name, job_title, url, today] + print(f"\n{job_title} in {company_name} has been recorded\n") + print("----------------------------------\n") + +# Check if the user has given some data, else exit +if df_temp.empty: + exit() + +while True: + # Show the data to confirm or to modidy them + print("These are the data: \n") + print(df_temp[['Company', 'Job Title']]) + + # Ask the user if he wants to change something + position_number = input("Give number of a job to change, else save with Enter: ") + if position_number == "": break + else: + if check_input(position_number, df_temp): + for title in ['Job Title', 'Company']: + df_temp[title].iloc[int(position_number)] = change_input(position_number, title, df_temp) + else: + print(f"\nYou must give a number between 0 and {len(df_temp)-1}\n") + time.sleep(1) # Make sure the user sees the message + +# If spreadsheet exists, read it and add the new data. +spreadsheet = Path("./Job_Aplications.xlsx") # The excel file's path +if spreadsheet.exists(): + df_original = pd.read_excel(spreadsheet) + + # Join the two dataframes + df_original = pd.concat([df_temp, df_original], ignore_index=True) + + df_original[['Company', 'Job Title']].dropna() # Remove if Company or Job Title is not provided + + # Write the new df into the spreadsheet + write_spreadsheet(spreadsheet, df_original) + +# If it does not exist, create it +else: + write_spreadsheet(spreadsheet, df_temp) diff --git a/README.md b/README.md new file mode 100644 index 0000000..07aaf4c --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +

+ +

+ +### ABOUT +--- + +Searching for a job can be challenging and it is a 'job' by itself. Sometimes, especially recently graduates, apply for a number of jobs everyday just to start their career. But also, recently unemployed or even senior professionals that search for a new opportunity tend to be lost after some days of applications without being sure where and when they have applied. + +This program helps everyone track their job applications fast and easily. The only thing the user has to do is to provide the url, the job title and the company's name for every applied position. Then, the program automatically creates or modifies a spreadsheet application. + +The user doesn't have to create anything, the program does it. + +Run the program and make sure you track your process of job applications! Oh, and good luck with it!. + +### HOW TO USE IT +--- +It is advised to create a new directory (for example Job Applications) and save the program there. Then, from that directory you can run the Job Applications Tracker. + +First, it asks for a url* and then for the job title and the company's name. You can leave it running while you apply for different job positions. + +The program stops when an empty url, job title or company's name is given. + +Once you have done with the applications, give an empty url and the program will show you all the last instances created. If you have made a mistake, fear not. Once you have finished, you will be shown your contributions and you can modify any mistaken instance. + +After you have checked that everything is as it should, all the records are passed to the spreadsheet, including the Company, the Job Title, the URL and the Day of Application. + + +(*apart from being able to review the job description, the url is asked for the future versions of the program with which some job applications will be automatically filled. See the [Future Lines](#future-lines) section for more details) + +### DEPENDENCIES +--- +The program is written completely in Python. Different libraries are used but the majority of them are already included in basic Python3. + +- [Pandas](https://pandas.pydata.org/) is used for reading and writing the spreadsheet. Also the registers are passed in a DataFrame. + +##### Pre-installed libraries used +- datetime +- pathlib +- re +- readline +- argparse + +### FUTURE LINES +--- +This version (0.1) is not the final version of the program. The program is to been designed to automate even more the process. + +The next version (0.2) will automatically insert the Job Title and the Company's name if the url given will be either from Linkedin or InfoJobs (a commonly used job-searching website in Spain). + +Even then, the program will not be complete. My first idea was to include a LLM (specifically, the Llama2 of Meta) to summarise the job description in one or two paragraphs. Version 1.0 will include this feature but it will be optional as Llama2 will have to run on the user's local machine. + +Version 1.1 will also make optional the use of ChatGPT (with the user's credentials) for doing the summary.