Automatic completion of a medical form

The first humans set foot on the moon in 1969. It’s now 2021 and the routine completion medical forms is still done with pen and paper…

Let’s take the case of a death declaration. With pen and paper this takes about 5 to 10 minutes of your time if you’re lucky. But if you’re doing it in the middle of the night and you make a mistake because your head is still dreaming about that nice vacation on the beautiful Maldives it can take longer. (If you are reading this as an outsider to the medical field,  you can’ t correct mistakes on medical forms, you have to start all over again…)

Let’s make this easier for ourselves. This is the workflow:

Before we get started we need to install some packages with the following lines:

  1. pip install selenium
  2. pip install pandas
  3. pip install xlml # we need this one to make pandas read html function work
  4. pip install reportlab

Now we can import the necessary modules and search for the patient file. I have made a fake patient file to practice:

from selenium import webdriver
import pandas as pd
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm
from datetime import datetime

driver = webdriver.Chrome()
driver.get("https://medicalprogress.dev/patient_file/")

Next we are gonna download the html code and read the table with pandas read_html function and close the browser:

html = driver.page_source
data = pd.read_html(html) #needs lxml to work, make first row the header
driver.close()

We have to clean the data a little bit, but after that we can define our variables for writing to pdf with the iloc function of pandas:

data = data[0]
df = pd.DataFrame(data)
name = df.iloc[0,1]
first_name = df.iloc[1,1]
gender = df.iloc[2,1]
birthdate = df.iloc[3,1]
birth_date_place = df.iloc[4,1]
location = df.iloc[5,1]
address = df.iloc[6,1]
postal_code = df.iloc[7,1]
place = df.iloc[5,1]

 We create variables a couple of variables with our personal information:

MD = "I.M.You"
specialty = "SuperDoc!"

We create a simple “x” variable for filling in answers on the form:

answer = "x"

We make a input prompt for getting the time of death of the patient:

time_value = input("what is the time of death?")

Create a canvas for writing on with the file name “deat_certificate.pdf”:

canvas = canvas.Canvas
path_pdf = "death_certificate.pdf"
c = canvas(path_pdf)

From this moment on we let the computer do a lot of writing on different pages of the canvas. Computers are happy to do accurate, routine and protocolized work, it’s their strength! This is the perfect moment to make use of that opportunity. 

In the following long text of code, the script is writing all the input information on the three different pages of the death declaration. The script uses the functions “drawString” and “drawText”. The latter is used in some occasions because certain strings need extra spacing between letters to fit the layout of the form. This can only be achieved with the functions drawText and linking it through a text object to the function “setCharSpace”.


# Create a background variable for first page of decleration form and draw it on the canvas (try to open de file as a check to see if you get the first page of the death decleration form)
background = "https://medicalprogress.dev/patient_file/Form_B1.jpg"
draw_width, draw_height = A4
c.drawImage(background, 0, 0, width=draw_width, height=draw_height)

# Write text on form B1
c.drawString(1.9 * cm, 25.7 * cm, place)
c.drawString(1.9 * cm, 23.3 * cm, answer)
c.drawString(1.9 * cm, 20.5 * cm, answer)
if gender == "Male":
c.drawString(1.9 * cm, 13.3 * cm, answer)
else:
c.drawString(1.9 * cm, 12.8 * cm, answer)
c.drawString(1.9 * cm, 11.3 * cm, answer)
birthdate_without_dash = birthdate.replace("-", " ")
textobject = c.beginText(4.3 * cm, 10.3 * cm)
textobject.setCharSpace(6.3)
textobject.textLine(birthdate_without_dash)
c.drawText(textobject)
textobject = c.beginText(4.3 * cm, 9.0 * cm)
textobject.setCharSpace(6.3)
textobject.textLine(datetime.now().strftime("%d %m %Y"))
c.drawText(textobject)

# Go to next page
c.showPage()

# Create a background variable for first page of decleration form and draw it on the canvas
background = "https://medicalprogress.dev/patient_file/Form_B2.jpg"
draw_width, draw_height = A4
c.drawImage(background, 0, 0, width=draw_width, height=draw_height)

# Write text on form B2
c.drawString(3.0 * cm, 12.6 * cm, MD)
c.drawString(3.0 * cm, 11.9 * cm, location)
c.drawString(3.0 * cm, 11.1 * cm, specialty)
c.drawString(3.0 * cm, 10.4 * cm, address)
c.drawString(6.0 * cm, 9.6 * cm, place)
c.drawString(2.8 * cm, 7.0 * cm, answer)
c.drawString(12.5 * cm, 12.6 * cm, "Specialist")
c.drawString(12.5 * cm, 11.9 * cm, "See on the left")
textobject = c.beginText(2.9 * cm, 9.6 * cm)
textobject.setCharSpace(3.8)
textobject.textLine(postal_code)
c.drawText(textobject)
c.drawString(11.5 * cm, 7.3 * cm, datetime.now().strftime("%d %m %y"))
c.showPage()

# Create a background variable for third page of decleration form and draw it on the canvas
background = "https://medicalprogress.dev/patient_file/Form_A.jpg"
draw_width, draw_height = A4
c.drawImage(background, 0, 0, width=draw_width, height=draw_height)

# Write text on form A
c.drawString(3.5 * cm, 22.9 * cm, MD)
c.drawString(3.5 * cm, 21.8 * cm, place)
c.drawString(5.3 * cm, 19.5 * cm, name)
c.drawString(5.3 * cm, 18.4 * cm, first_name)
c.drawString(7.3 * cm, 17.2 * cm, birthdate + " " + birth_date_place)
c.drawString(7.3 * cm, 15.5 * cm, datetime.now().strftime("%d-%m-%Y"))
c.drawString(10.3 * cm, 15.5 * cm, place)
c.drawString(7.3 * cm, 14.4 * cm, time_value)
c.drawString(3.5 * cm, 4.0 * cm, datetime.now().strftime("%d-%m-%Y"))


# Save forms
c.save()

 

After running this code the file should be on your hard drive under the name death_certificate.pdf. In the case of a pdf of a real patient information, you of course want to do the procedure from a save computer on your work. 

This is how the automatically filled in version of the Dutch death declaration looks like:

Death Declaration pdf file

For now, the only thing that’s left to do is check the content/layout and print the pdf. To make a pdf with text that can be printed on the paper declaration form you have to remove the drawing on the background of the canvas (remove the c.drawImage function). Sometimes you have to adjust the position of the text a little bit to let the printed text fit the layout of the paper medical form. You can do this with the translate function (here the word translate refers to mathematical form ‘translation’, meaning the moving of an object through space). If you move the text with this function, just remember that measurement of distance starts from the lower-left corner of the page. This is how I use the function to fit the text to the layout:

c.translate(-0.10*cm, 0*cm). 

Well, that’s it! You’ve automated filling in a medical form and reduced the time from 5–15 minutes with pen and paper to a procedure of 5–15 seconds with a computer! And it wasn’t that hard to do right? If you want to have the notebook with the full code to practice you can find it on my github page. You can also check out my website to stay up to date on more about automation and machine learning in health care. There is also a google colab version on my github that let’s you practice without the hussle of installing software on your computer. Just to make it even more easy 😉