Data Modeling: Reversing CSV conversions

Recently, I covered the case of converting CSV data into database table format.

Ex: A | B | C
ID | Business Name | Codes
72566477 | McDonald’s | Chicken_Sandwich,Fries,Diet_Coke,etc.

The below VBA code for MS Access provides for a way to reverse this process. That is, to convert the database table format:

Ex: A | B | C
ID | Business Name | Codes
72566477 | McDonald’s | Chicken_Sandwich
72566477 | McDonald’s | Fries
72566477 | McDonald’s | Diet_Coke

back to CSV like in the above example highlighted in green from the previous article (on a side note, please notice that the above table is not properly normalized and should be so for correct database structure). A better database design would take the following structure:

The function is currently setup without arguments but it can be easily modified for that. In it’s current setup, it’s easy to understand how to use the function and adjust it for your dataset but it would be limited to one-time use, i.e. it will need to be modified for arguments to be used in a looping algorithm.

Download: MakeCSV

Public Sub MakeCSV()
On Error GoTo ErrHandler

Dim con As ADODB.Connection
Dim rst As New ADODB.Recordset
Dim rst1 As New ADODB.Recordset
Dim cat As New ADOX.Catalog
Dim fld As ADODB.Field
Dim tbl As ADOX.Table
Set con = Application.CurrentProject.Connection
Set cat.ActiveConnection = con
Dim strSQL As String, CSVKey() As String, CSVValueList As String
Dim CSVField() As String, CSVSource As String, MasterSource As String, NewTable As String
Dim NumberOfFields As Long, x As Long, y As Long, NumberGroupFields As Long
Dim LongData As Boolean, OnlyUnique As Boolean

'Set the name for the table you want to create
NewTable = "NEW_TABLE_NAME"
'Are you dealing with long data (>255 characters) or short data?
LongData = False
'Set the name of the table or query to reference
MasterSource = "EXISTING_QUERY_OR_TABLE_NAME"
'Set the number of grouping fields
NumberGroupFields = 3
'Allocate the array - //////// DO NOT ALTER THIS LINE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ReDim CSVKey(NumberGroupFields, 1)
'Set the Name of the key field you want to reference the CSV
CSVKey(1, 0) = "GROUP_FIELD_NAME_1"
CSVKey(2, 0) = "GROUP_FIELD_NAME_2"
CSVKey(3, 0) = "GROUP_FIELD_NAME_3"
'Set the number of fields you want to turn into a CSV
NumberOfFields = 2
'Allocate the array - //////// DO NOT ALTER THIS LINE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ReDim CSVField(NumberOfFields)
'Set the name of the field or fields you want to turn into CSV
CSVField(1) = "CSV_FIELD_NAME_1"
CSVField(2) = "CSV_FIELD_NAME_2"
'CSVField(3) = "CSV_FIELD_NAME_3"
'Grab Only Unique Values for the CSV?
OnlyUnique = True

'/////////////////////// DO NOT ALTER THE LINES BELOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'Check to see if the table exists - if it does, drop it
For Each tbl In cat.Tables
 If tbl.Name = NewTable Then
 cat.Tables.Delete NewTable
 End If
Next tbl
'Determine the data types for the CSVKey values
strSQL = "SELECT TOP 1"
For y = 1 To NumberGroupFields
 strSQL = strSQL & " [" & CSVKey(y, 0) & "],"
Next y
strSQL = Left(strSQL, Len(strSQL) - 1)
strSQL = strSQL & " FROM [" & MasterSource & "]"
With rst
 .Open strSQL, con, adOpenStatic, adLockReadOnly
 y = 1
 For Each fld In rst.Fields
 If fld.Type = 7 Then
 CSVKey(y, 1) = "Date"
 ElseIf fld.Type = 202 Then
 CSVKey(y, 1) = "Text"
 ElseIf fld.Type = adBigInt Then
 CSVKey(y, 1) = "Numeric"
 End If
 y = y + 1
 Next fld
 .Close
End With

'Create a table to hold the CSV values
strSQL = "CREATE TABLE [" & NewTable & "]"
strSQL = strSQL & " ([" & CSVKey(1, 0) & "] TEXT(255),"
If NumberGroupFields >= 2 Then
 For y = 2 To NumberGroupFields
 strSQL = strSQL & " [" & CSVKey(y, 0) & "] TEXT(255),"
 Next y
End If
For x = 1 To NumberOfFields
 If LongData = True Then
 strSQL = strSQL & " [" & CSVField(x) & "] MEMO,"
 Else
 strSQL = strSQL & " [" & CSVField(x) & "] TEXT(255),"
 End If
Next x
strSQL = Left(strSQL, Len(strSQL) - 1)
strSQL = strSQL & ")"
'Create the table
con.Execute strSQL

'Get the unique source items
For x = 1 To NumberOfFields
 'Get the distinct CSVKeys
 strSQL = "SELECT DISTINCT"
 For y = 1 To NumberGroupFields
 strSQL = strSQL & " [" & CSVKey(y, 0) & "],"
 Next y
 strSQL = Left(strSQL, Len(strSQL) - 1)
 strSQL = strSQL & " FROM [" & MasterSource & "]"
 With rst
 .Open strSQL, con, adOpenStatic, adLockReadOnly
 .MoveFirst
 While Not .EOF
 'Retrieve the values for the CSV list
 If OnlyUnique = False Then
 strSQL = "SELECT [" & CSVField(x) & "] FROM [" & MasterSource & "]"
 Else
 strSQL = "SELECT DISTINCT [" & CSVField(x) & "] FROM [" & MasterSource & "]"
 End If
 For y = 1 To NumberGroupFields
 If y = 1 Then
 If CSVKey(1, 1) = "Text" Then
 strSQL = strSQL & " WHERE ((([" & CSVKey(1, 0) & "]) = " & Chr(34) & rst.Fields(CSVKey(1, 0)) & Chr(34) & ")"
 ElseIf CSVKey(1, 1) = "Numeric" Then
 strSQL = strSQL & " WHERE ((([" & CSVKey(1, 0) & "]) = " & rst.Fields(CSVKey(1, 0)) & ")"
 ElseIf CSVKey(1, 1) = "Date" Then
 strSQL = strSQL & " WHERE ((([" & CSVKey(1, 0) & "]) = #" & rst.Fields(CSVKey(1, 0)) & "#)"
 End If
 Else
 If CSVKey(y, 1) = "Text" Then
 strSQL = strSQL & " AND (([" & CSVKey(y, 0) & "]) = " & Chr(34) & rst.Fields(CSVKey(y, 0)) & Chr(34) & ")"
 ElseIf CSVKey(y, 1) = "Numeric" Then
 strSQL = strSQL & " AND (([" & CSVKey(y, 0) & "]) = " & rst.Fields(CSVKey(y, 0)) & ")"
 ElseIf CSVKey(y, 1) = "Date" Then
 strSQL = strSQL & " AND (([" & CSVKey(y, 0) & "]) = #" & rst.Fields(CSVKey(y, 0)) & "#)"
 End If
 End If
 Next y
 strSQL = strSQL & ")"
 With rst1
 .Open strSQL, con, adOpenStatic, adLockReadOnly
 .MoveFirst
 'Create the CSV list
 While Not .EOF
 CSVValueList = CSVValueList & .Fields(CSVField(x)) & ", "
 .MoveNext
 Wend
 CSVValueList = Left(CSVValueList, Len(CSVValueList) - 2)
 .Close
 End With
 'Now insert the CSV values
 strSQL = "SELECT [" & CSVField(x) & "],"
 For y = 1 To NumberGroupFields
 strSQL = strSQL & " [" & CSVKey(y, 0) & "],"
 Next y
 strSQL = Left(strSQL, Len(strSQL) - 1)
 strSQL = strSQL & " FROM [" & NewTable & "]"
 strSQL = strSQL & " WHERE ((([" & CSVKey(1, 0) & "]) = " & Chr(34) & rst.Fields(CSVKey(1, 0)) & Chr(34) & ")"
 If NumberGroupFields >= 2 Then
 For y = 2 To NumberGroupFields
 strSQL = strSQL & " AND (([" & CSVKey(y, 0) & "]) = " & Chr(34) & rst.Fields(CSVKey(y, 0)) & Chr(34) & ")"
 Next y
 strSQL = strSQL & ")"
 Else
 strSQL = strSQL & ")"
 End If
 With rst1
 .Open strSQL, con, adOpenDynamic, adLockOptimistic
 If .BOF = True And .EOF = True Then
 'Add a new record
 .AddNew CSVKey(1, 0), rst.Fields(CSVKey(1, 0))
 For y = 2 To NumberGroupFields
 .Update CSVKey(y, 0), rst.Fields(CSVKey(y, 0))
 Next y
 .Update CSVField(x), CSVValueList
 Else
 'Record Exists
 .Update CSVField(x), CSVValueList
 End If
 .Close
 End With
 'Clear the CSV value
 CSVValueList = ""
 'Move to the next CSVKey
 .MoveNext
 Wend
 .Close
 End With
Next x

'Close the connections
con.Close
Set rst = Nothing
Set rst1 = Nothing
Set cat = Nothing
Set tbl = Nothing
Set fld = Nothing
Set con = Nothing
Exit Sub

ErrHandler:
'Close the connections
MsgBox "MakeCSV encountered error " & Err.Number & " : " & Err.Description, vbCritical + vbOKOnly, "MakeCSV Encountered Error " & Err.Number
If rst.State = adStateOpen Then
 rst.Close
End If
If rst1.State = adStateOpen Then
 rst1.Close
End If
con.Close
Set rst = Nothing
Set rst1 = Nothing
Set cat = Nothing
Set tbl = Nothing
Set fld = Nothing
Set con = Nothing
Exit Sub

End Sub
Share

The next time you read a medical article

Think about the following the next time you read a medical journal.

“Rethinking the Admissibility of Medical Treatises as Evidence” . JP Lipton, M O’Connor, BD Sales. American J Law & Medicine 1991 17:209-248

“…there are scarcely any bars to eventual publication. There seems to be no study too fragmented, no hypothesis too trivial, no literature citation too biased or too egotistical, no design too warped, no methodology too bungled, no presentation of results too inaccurate, too obscure, and too contradictory, no analysis too self-serving, no argument too circular, no conclusions too trifling or too justified, and no grammar and syntax too offensive for a paper to end up in print.”

Sheps & Schecter: The assessment of diagnostic tests: a survey of current medical research. JAMA 1984, 2418:2420-21. This paper found a great potential for plagiarism and fraud. I’m sure there are many other examples, these are just the first two that come to mind for me.

The moral of the story? Read carefully and take the time to see if the article is really credible and, also importantly, passes the “so what?” test. Was there a sufficient sample size? Were the appropriate methodologies used? Where the correct statistical tests used? Do they support the conclusion? Does the conclusion matter, i.e. is it adding something important to the literature? If the conclusion seems suspicious, does the author have a history of publishing research in the field supporting the theory or method of thinking?

Follow the above questions each time you read a journal article and you may be amazed at some of the things that stand out in the literature.

As a side note, another good way to look at scientific claims is the 10 questions of the Baloney Detection Kit from Michael Shermer which are:

1. How reliable is the source of the claim?
2. Does the source make similar claims?
3. Have the claims been verified by somebody else?
4. Does this fit with the way the world works?
5. Has anyone tried to disprove the claim?
6. Where does the preponderance of the evidence point?
7. Is the claimant playing by the rules of science?
8. Is the claimant providing positive evidence?
9. Does the new theory account for as many phenomena as the old theory?
10. Are personal beliefs driving the claim?

Share

Data Modeling: When to use a linear model

As you probably know, Excel lacks many sophisticated analytic techniques and not everyone has access to a true analytics package like STATA or SPSS. So what can you do if you’re modeling data and trying to decide of the type of model? Will a linear model work or do you need to consider an exponential or polynomial model to explain your dataset? Picking the wrong model is a mistake that sometimes even the best-intentioned researchers make and the incorrect model can even end up being published. I’m going to cover one technique called the Durbin-Watson test and explain how to use it to tell if a linear regression model is a valid model for your dataset.

First off, you can use Excel to add a linear trendline to your data. Make sure you have Excel give you the equation for the trendline – we’ll need this to compute the Durbin-Watson.

Let’s say you’ve run the regression and ended up with the formula y = 0.1897x + 5.0517. The next step is to calculate your fitted values.

For the next two steps (Yhat and residuals), you can either get these with Excel or calculate them manually. I’ll cover the manual approach.

If you first point was (2, 6) then the Yhat (fitted value) is 2*.1897 + 5.0517 = 5.4311. Do this for all of your data points.

The next step is to calculate residual values. The residual value is simply the real value minus the fitted value. So, for our above example, the residual value is 6 – 5.4311 = 0.5689.

The next step is to calculate the squared difference between successive residuals, summed from the second observation to the nth observation. So, for all the residuals in your list starting with the second one, take that residual, subtract out the previous residual, and square the result. Then sum all of these values.

The next to last step is to calculate the sum of squares residual. For this, calculate the square of each individual residual and the sum the entire range. This is your sum of squares.

Finally, to calculate the Durbin-Watson statistic, divide the squared difference of successive residuals by the sum of squares. This value can then be compared to online lookup tables (such as at http://www.paolocoletti.it/statistics/exercises/Durbin-Watson.html) to see if a linear model is appropriate.

For example, if you have one independent variable and 15 observations (k = 1, n = 15), then dL = 1.08 and dU = 1.36. If your value is between this range, then a linear model is probably appropriate for your data.

However, if your value was for example 0.9, then your model exhibits positive autocorrelation (i.e. the errors are not independent) and you can not use a linear model to describe the data. You then have to consider other models or transform the data to normality (natural log, square root, etc.) before modeling and re-compute the Durbin-Watson.

Thanks for reading this brief tutorial on data modeling and good luck with your analyses!

Share

Data Modeling: CSV conversions

I’m still on a programming kick with my blog, so here’s another article. I used to run into this problem a lot so for those of you that are or know Excel users, here’s my solution. The below code is run as a VBA script in Excel.

Here’s a problem you may face. You ask someone for information and they send it to you in an Excel sheet. You then happily open the sheet only to find that it’s not in an easy-to-use format.

For example, let’s say you had an Excel sheet with several hundred business IDs and each business ID has a code set that you need to use.

Ex: A | B | C
ID | Business Name | Codes
72566477 | McDonald’s | Chicken_Sandwich,Fries,Diet_Coke,etc.

If you wanted to make a table out of these, you could do a text-to-column and then transpose but, obviously, this isn’t a good approach for any but the smallest datasets.The code below will take these lists, create a new excel sheet, and then match up the static values with each item in the comma-seperated list. Within seconds, you can have a useable dataset instead of a bunch of CSVs.

The function can be called as such:

Public Function CallF()

Dim Keys(0 To 2) As Long
Keys(0) = 1
Keys(1) = 2
Keys(2) = 3

CSVToTable "Sheet to Convert", 4, 4, Keys, True, 3

End Function

In the converting function, the StartRow is the row the data starts on, the CSVColumn is the column number (A = 1, B = 2, etc.) containing the CSV data, the KeyColumns are the column numbers that need to repeat, and the HasHeader and HeaderRow variables tell the script if and where you column headers are.

Here’s the converting function:

Public Function CSVToTable(WkSheetName As String, StartRow As Long, CSVColumn As Long, KeyColumns As Variant, Optional HasHeader As Boolean = False, Optional HeaderRow As Long = 0)

Dim x As Long, y As Long, z As Long, sSheetRow As Long
Dim ParsedValues As Variant
Dim LockValues() As String
Dim sSheet As Worksheet
Dim tSheet As Worksheet
Set sSheet = Worksheets(WkSheetName)
Application.Worksheets.Add after:=Application.Worksheets(Application.Worksheets.Count)
Set tSheet = Worksheets(Application.Worksheets.Count)
tSheet.Name = "Table"
y = 1

'Read the columns to the new sheet
If HasHeader = True And HeaderRow > 0 Then
'Add the header columns
For x = LBound(KeyColumns) To UBound(KeyColumns)
'Format the column
tSheet.Columns.EntireColumn.NumberFormat = "@"
tSheet.Cells(1, y).Value = sSheet.Cells(HeaderRow, KeyColumns(x)).Value
y = y + 1
Next x
'Add the CSV column
tSheet.Cells(1, y).Value = sSheet.Cells(HeaderRow, CSVColumn).Value
'Reset y for row values
y = 2
End If

'Now read off the data
sSheetRow = HeaderRow + 1
Do While IsNull(sSheet.Cells(sSheetRow, KeyColumns(0))) = False And sSheet.Cells(sSheetRow, KeyColumns(0)) <> ""
ReDim LockValues(UBound(KeyColumns))
'Read in the lock values
For z = LBound(KeyColumns) To UBound(KeyColumns)
LockValues(z) = CStr(sSheet.Cells(sSheetRow, KeyColumns(z)))
Next z
'Parse the CSV
ParsedValues = Split(sSheet.Cells(sSheetRow, CSVColumn), ",")
If IsArray(ParsedValues) And UBound(ParsedValues) <> -1 Then
For x = LBound(ParsedValues) To UBound(ParsedValues)
'For each entry, print the static values and the parsed CSV value
'Print the lock values first
For z = 1 To UBound(LockValues) + 1
tSheet.Cells(y, z) = Trim(CStr(LockValues(z - 1)))
Next z
'Now print the CSV value - y is the row number, z is the column number
tSheet.Cells(y, z) = Trim(CStr(ParsedValues(x)))
'Increment the row
y = y + 1
Next x
Else
'Increment the table sheet row
y = y + 1
End If
'Increment the source sheet row
sSheetRow = sSheetRow + 1
Loop

'Format the table
With tSheet.Cells.EntireColumn
.Font.Name = "Arial"
.Font.Size = 8
.AutoFit
End With

'Close the objects
Set sSheet = Nothing
Set tSheet = Nothing

End Function

Share

Medical Literature and Classes of Physicians

Bennet’s Classification for Reading the Medical Literature JAMA 1992, 267:920

Med student
Reads entire article, doesn’t understand what any of it means

Intern
Uses journals as pillows during nights on call [osmosis technique]

Resident
Wants to read entire article, eats dinner instead

Chief resident
Skips articles entirely, reads classified ads for jobs

Junior attending
Reads & analyzes everything so he can pimp the med students (See Imagining the Possibilities)

Senior attending
Reads abstracts only, quotes liberally to impress students and housestaff

Research attending
Reads and analyzes everything, including stats, in lieu of sex

Chief of service
Reads references only to see if he was referenced anywhere

Private attending
Reads Time & Newsweek for medical articles to keep up with patients

Emeritus attending
Reads entire article, doesn’t understand what any of it means

Share

Providing security with Active Directory

As any database designer knows, MS Access is a quick and easy way to get a user application up and running. It’s intuitive, easy to use, easy to learn and provides a good, low-cost user experience. However, the built-in security for Access is often cumbersome and easy to beat. If you are in an active directory domain environment, the best course of action is to use the active directory to allocate access based on users and security groups.

The script below will allow you to authenticate users via the active directory. While you may not have access to create security groups, you can authenticate and then match against an encrypted user table (MD5, AES, Blowfish, etc though MD5 should not be considered without using a salt). The security advantage here is that you are limiting potential logins both via the active diretory and the user table. Also, users will not have to remember a password for your system and for the network. As the user updates his/her network password, that same update is reflected with your database system login.

Here’s the code for my solution to this problem (using the Active DS Type Library)

Public Function ADSAuth(ByVal ADSDomain As String, ByVal ADSUsername As String, ByVal ADSPassword As String) As Boolean
On Error GoTo ErrHandler

Dim dso As IADsOpenDSObject
Dim Domain As IADsDomain
Set dso = GetObject("WinNT:")
Set Domain = dso.OpenDSObject("WinNT://" & ADSDomain, ADSUsername, ADSPassword, ADS_SECURE_AUTHENTICATION)
Set Domain = Nothing
Set dso = Nothing
ADSAuth = True
Exit Function

ErrHandler:
If Err.Number = -2147023570 Then
 MsgBox "Login Failure: Unknown user name or bad password.", vbCritical + vbOKOnly, "Login Failure"
Else
 MsgBox "Program encountered error number " & Err.Number & " : " & Err.Description & ".", vbCritical + vbOKOnly, "Program Error"
End If
Set Domain = Nothing
Set dso = Nothing
ADSAuth = False

End Function

This is just a brief, single purpose script I threw together so if anyone has a faster/better way of doing this or has the code for a more comprehensive manipulation of the active directory, post it in the comments. Thanks for reading and happy coding!

Share

Medical fun with Gilbert and Sullivan

By: Brian Wells

I am the very model of a modern medico general,
I’ve information diagnosable, mucosal and gangrenal
I know the cells of squamous and I quote the tests explorable
from MRI to TSH in order categorical.

I’m very well aquainted too with matters metastatical
I understand blood tests, both the simple and coaguable
About fibrocystic disease, I’m teeming with a lot of news
with many cheerful facts about the cysts with the domes of blue.

with many cheerful facts about the cysts with the domes of blue.
with many cheerful facts about the cysts with the domes of blue.

with many cheerful facts about the cysts with the domes of domes of blue.

I’m well adept at listening and I often do asseverate
that I’ll screen for TB before it can disseminate
In short, in matters diagnosable, mucosal and gangrenal,
I am the very model of a modern medico general.

In short, in matters diagnosable, mucosal and gangrenal,
He is the very model of a modern medico general.

I can write out glycolysis on the wall of your dorm
and tell you every detail of albuterol’s isoform
With my stethoscope I can listen for whisper pectoriloquy
and then rattle off eponyms as if they were a symphony.

I can catalog white blood cells as if I were a PhD
and then check the abdomen for size, shape and symmetry
Scars and swelling too before I use the otoscope and tuning fork
and see if your hearing loss is real or just somatoform.

and see if your hearing loss is real or just somatoform.
and see if your hearing loss is real or just somatoform.
and see if your hearing loss is real or just somatomatoform.

Then I can write reports in structured history-taking form
and tell you every patient test that was well within the norm
In short, in matters diagnosable, mucosal and gangrenal,
I am the very model of a modern medico general.

In short, in matters diagnosable, mucosal and gangrenal,
He is the very model of a modern medico general.

Share

If I ran the zoo…

“It’s a pretty good zoo,” Said young Gerald McGrew,
“And the fellow who runs it seems proud of it, too.”
“But if I ran the zoo,” Said young Gerald McGrew,
“I’d make a few changes, that’s just what I’d do.”

This Dr. Seuss book is a story about a young boy imagining the kind of zookeeper he would be. He would get rid of all the “old-fashioned” animals like lions and tigers, then he would stock his zoo with such never-before-heard-of creatures as an Elephant-cat, a scraggle-foot Mulligatawny, a Thwerll, and an obsk.

A lot of times criticism is like this. Sure, we have the right to criticize. Criticism is healthy and it helps to identify problem areas allowing us to improve. McGrew thinks the zoo should be improved but he doesn’t provide a workable solution. I don’t know about you, but I haven’t seen many scraggle-foot Mulligatawnys lately. Taken out of the context of a children’s story, this type of criticism would be useless in the real world (if you need a more concrete example, think about the health care proposals that do nothing to control costs or improve quality. Yeah, the McGrew  example is more fun).

However, there is a difference between useful criticism and useless criticism. Allow me to explain.

Useless criticism can be identified quite easily. It finds a flaw in a system, action or idea and, without providing feedback or any kind of solution, it dwells upon the flaw to call into question the observed item. For example, an audience member at the movies may say “Transformers was a terrible movie. All those explosions made the movie monotonous and boring.” Great, excellent point. But… what should have been done differently?

How about turning that criticism into creative energy? For example, “Transformers was a terrible movie. All those explosions made the movie monotonous and boring. They really should have focused more on the storyline to setup an enthralling sequel and leave the audience with a memorable experience.” Now, instead of being pointless criticism, that simple idea can be turned into a short story or even a full blown movie proposal. It may improve an industry. You borrow some basic plot ideas, add in your own, write it all up as a screenplay and see what happens. Maybe nothing, maybe something crazy… right Good Will Hunting?

So keep this simple point in mind. The next time you have a criticism, be sure to attach advice or a solution to the criticism. Criticism with advice is healthy and often needed. No one can be perfect at all times; we each need this feedback in order to improve which is why your attached advice or solution is so vital.

Otherwise, you’re just Gerald McGrew with a scraggle-foot Mulligatawny.

Share

Someone to watch over us

I’ll be honest. When it came to believing in God, a higher power, whatever you want to call it – I really tried. I know it would be comforting to think there’s someone out there watching over me, someone that wants only the best for me. I think that deep down we all want to know that someone is watching over us, helping us through the hard times and giving us strength when we need it most.

But I never saw it.

Maybe I didn’t look hard enough. Maybe my mind is so full of questions and doubts, biology and physics, a need for proof and explanation that I can’t see it. Maybe I’m wrong… and maybe I’m not.

But I do have something I believe in, something I have faith in, something that gives me comfort and hope when I’m feeling down. I have faith in the promise and goodness of humanity and in the power of individuals or small groups of people to change the world for the better. I believe that deep down people really are good at heart. For me, there’s no other explanation – we simply had to be in order to survive. Sure, we make mistakes. We go left when we should have gone right, or we say a careless word that sticks with and stings those who care about us. However, we can also give two of the most powerful words that, when meant, show our goodness: I’m sorry. We acknowledge our own shortcomings and we make amends for offenses.

We cooperate.

We forgive.

But it doesn’t end there. People show their goodness every day whether it’s stopping to help someone change a flat tire, volunteering at a soup kitchen or offering to share their umbrella on a rainy day. I’m sure you can think of a time that a total stranger did something nice for you, not because they were expecting something in return but because it was the right thing to do.

Richard Dawkins noted that “[the brain’s] rules of thumb influence us still, not in a Calvinistically deterministic way but filtered through the civilizing influences of literature and custom, law and tradition – and, of course, religion. Just as the primitive brain rules of sexual lust passes through the filter of civilization to emerge in the love scenes of Romeo and Juliet, so primitive brain rules of us-versus-them vendetta emerge in the running battles between Capulets and Montagues; while primitive brain rules of altruism and empathy end up in the misfiring that cheers us in the chastened reconciliation of Shakespeare’s final scene.”

Perhaps the desire to do good, to be generous and compassionate is hard-wired into us as a result of our evolutionary history. This makes perfect sense in my view and makes me stronger in my faith in humanity. It’s enjoyable to think that within each of us is this desire and even more thrilling when that desire is manifest into action.

I often dream of a day when humanity will wake up and realize that we’re all in this together. When we’ll all realize that we must care for one another because each voice gained enriches us and each voice lost diminishes us. When we realize that the world speaks with many languages but with one voice. The world speaks with the voice of hope, honor, strength, integrity, compassion and togetherness.

My faith tells me that humanity has this power all within itself. I believe that one day we will all be able to work together to resolve our differences peacefully without resorting to the derogatory distinctions and old hatreds that only serve to keep us apart.

I know that I will likely never live to see this day but I can dream, I can believe and I can have faith. I can do everything in my power to help make this dream a reality through my work as a doctor and hopefully through my future work in politics. My belief in humanity’s potential and my belief in the power of individuals or small groups of people to change the world for the better helps me go on when times are hardest. It gives me the strength to continue on my path and the hope that one day I can make a difference.

And for me, this dream is my “someone to watch over us.”

 

Share

Decisions, Decisions

Exams are over, weekend fun is over and it’s time to get back to work. This time work includes selecting hospitals for 3rd year clinicals with the full knowledge that I may or may not get the site I want. Apparently, the assignment isn’t quite random if you have family ties to the area but other than that it’s… well, random is a good enough word.

So I’m doing what any good 2nd year student would do… asking a highly trusted 4th year friend for advice! After all, who better to comment on this than someone who has already been through it?

Hopefully, I’ll have the hospital picking done in the next day or so and I can go back to the waiting game to see if any of my picks end up being my preliminary placement. Exciting times! Knowing that I’ll be in the hospital in less than a year makes everything seem so much more real. I have a good feeling that the next couple years are going to be awesome!

%d bloggers like this: