Unit I · Basics of Python Programming for Pharmaceutical Sciences (BP101T) · As per PCI B.Pharmacy Syllabus, NEP 2020
Text data is everywhere in pharmacy practice — drug names, batch numbers, patient identifiers, prescription notes, and laboratory report text all arrive as strings before a program can do anything useful with them. Python treats a string as a sequence of characters, and gives you a rich set of built-in tools for combining, slicing, cleaning, and validating that text. This article covers the essential string operations and manipulation techniques prescribed under BP101T, illustrated with examples drawn from pharmacy record-keeping.

Strings Are Immutable
The single most important fact to remember about Python strings is that they are immutable: once a string has been created it cannot be altered in place. Any operation that appears to “modify” a string — converting it to uppercase, replacing a substring, or stripping whitespace — actually builds and returns a completely new string object, leaving the original string unchanged in memory. This is why string methods must always be assigned to a variable (or printed directly) to see their effect; calling a method on its own and discarding the result changes nothing.
drug_name = "paracetamol"
drug_name.upper() # this creates "PARACETAMOL" but throws it away
print(drug_name) # still prints "paracetamol" -- original untouched
drug_name = drug_name.upper() # correct way: reassign the new string
print(drug_name) # "PARACETAMOL"
Basic String Operations
These are the core operations used to combine, repeat, or test the contents of strings.
Concatenation (+)
The plus operator joins two or more strings end to end into a single string, which is useful for building a formatted label from separate pieces of prescription data.
drug = "Paracetamol"
strength = "500mg"
label = drug + " " + strength
print(label) # Output: 'Paracetamol 500mg'
Repetition (*)
The multiplication operator repeats a string a given number of times, producing one longer string — handy for building a visual separator line in a printed report.
print("-" * 20) # Output: '--------------------'
Membership (in)
The in keyword checks whether one string occurs as a substring inside another, returning True or False — useful for a quick check of whether a drug name appears somewhere inside a longer prescription note.
note = "Tab. Paracetamol 500mg BD after food"
print("Paracetamol" in note) # Output: True
Indexing and Slicing
Python lets you access individual characters or extract portions of a string by referring to their position, called an index.
Indexing a Single Character
A positive index counts from 0 for the leftmost character and increases moving rightward. A negative index counts from -1 for the rightmost character and moves further negative going leftward — a convenient way to grab the last character of a string without knowing its length in advance.
drug = "Amoxicillin"
print(drug[0]) # Output: 'A' (first character)
print(drug[-1]) # Output: 'n' (last character)
Slicing a Range of Characters
Slicing extracts a portion of a string using the syntax string[start:stop:step], where the character at the stop position is excluded from the result.
| Slice | Meaning | Example on “Python” | Result |
|---|---|---|---|
| [0:3] | From index 0 up to, not including, index 3 | word[0:3] | ‘Pyt’ |
| [:3] | From the beginning up to index 3 | word[:3] | ‘Pyt’ |
| [3:] | From index 3 to the end | word[3:] | ‘hon’ |
| [::-1] | Step of -1 reverses the entire string | word[::-1] | ‘nohtyP’ |
batch_no = "BN2024A17"
print(batch_no[0:2]) # Output: 'BN' -- extracts the batch prefix
print(batch_no[2:6]) # Output: '2024' -- extracts the manufacturing year
stop index in a slice is exclusive. For the string “Python” (6 characters, indices 0 to 5), word[0:3] gives ‘Pyt’ — three characters, not four. Always double-check whether a question is asking for indexing (a single character, using one index) or slicing (a substring, using a colon-separated range).Essential String Methods
Methods are built-in functions attached to string objects that return a modified copy of the text without changing the original string.
Case Manipulation
.upper()/.lower()— converts every letter in the string to uppercase or lowercase respectively..title()— converts the string so that the first letter of every word is capitalised..capitalize()— capitalises only the very first letter of the entire string, leaving the rest unchanged.
drug = "amoxicillin trihydrate"
print(drug.upper()) # 'AMOXICILLIN TRIHYDRATE'
print(drug.title()) # 'Amoxicillin Trihydrate'
print(drug.capitalize()) # 'Amoxicillin trihydrate'
Cleaning and Searching
.strip()— removes any leading and trailing whitespace from the string, leaving the interior untouched. Extremely useful when reading data typed by a user or imported from a spreadsheet, which often has stray spaces at the ends..replace("old", "new")— produces a new string with every occurrence of the “old” substring swapped out for the “new” substring..find("x")— searches the string and returns the index position of the first occurrence of “x”; it returns -1 if “x” is not found anywhere in the string..count("x")— returns the total number of times the substring “x” appears in the string.
raw_entry = " Paracetamol 500mg "
clean_entry = raw_entry.strip()
print(clean_entry) # 'Paracetamol 500mg'
prescription = "Paracetamol 500mg, Paracetamol 500mg BD"
print(prescription.replace("Paracetamol", "Acetaminophen"))
print(prescription.count("Paracetamol")) # 2
print(prescription.find("BD")) # index position of "BD"
Splitting and Joining
.split(",")— breaks a string apart into a list of substrings wherever the given separator (here, a comma) occurs. This is exactly how a single line of comma-separated drug data from a CSV file is turned into separate fields."-".join(list)— takes a list of strings and merges them into a single string, inserting the given separator (here, a hyphen) between each element.
record = "Paracetamol,500mg,Tablet,BN2024A17"
fields = record.split(",")
print(fields) # Output: ['Paracetamol', '500mg', 'Tablet', 'BN2024A17']
parts = ["BN", "2024", "A17"]
batch_code = "-".join(parts)
print(batch_code) # Output: 'BN-2024-A17'
.split() and .join() are often paired in a single question — for example, split a raw prescription line into fields, process one field, and rejoin the parts into a new formatted string. Remember that .split() always returns a list, and .join() is called on the separator string, not on the list.String Validation
These methods check the composition of a string’s characters and are especially useful for validating user input, since each one returns either True or False.
.isdigit()— returnsTrueonly if every character in the string is a numeric digit..isalpha()— returnsTrueonly if every character in the string is an alphabetic letter..isalnum()— returnsTrueonly if every character in the string is either a letter or a digit (alphanumeric)..isspace()— returnsTrueonly if the string consists entirely of whitespace characters.
batch_input = input("Enter batch quantity: ")
if batch_input.isdigit():
quantity = int(batch_input)
print("Valid quantity:", quantity)
else:
print("Invalid entry -- please enter numeric digits only")
This pattern — validating with an is...() method before converting with int() — is a standard defensive-programming technique, preventing a program from crashing when a user types something unexpected, such as accidentally including a unit label with the number.
Frequently Asked Questions
If strings are immutable, how does .replace() appear to change the text?
.replace() never changes the original string object in memory. It builds an entirely new string containing the substitution and returns that new string, which is why the result must be captured in a variable (or reassigned to the same name) to actually use the changed text.
What is the difference between .find() and .index() for locating a substring?
Both search for a substring and return its starting index, but they behave differently when the substring is not found: .find() returns -1, while .index() raises a ValueError. For pharmacy scripts that need to keep running even when a search fails, .find() is usually the safer choice.
Why does “10” + “5” give “105” instead of 15?
Both values are strings, not integers, so the + operator performs string concatenation rather than arithmetic addition, joining the two pieces of text end to end. To add them numerically, each string would first need to be converted with int().
Summary
Python strings are immutable sequences of characters, so every “modification” method actually returns a new string rather than altering the original. Concatenation, repetition, and membership testing form the basic string operations, while indexing and slicing (with the crucial rule that the stop index is excluded) let you extract individual characters or substrings. Built-in methods cover case conversion, cleaning (.strip()), searching and replacing (.find(), .count(), .replace()), splitting and joining text around a separator, and validating the composition of a string before converting it to a number. Together these tools are what turn raw pharmacy text data — prescription notes, batch codes, CSV rows — into clean, usable information.
References
- Pharmacy Council of India (PCI), B.Pharm Regulations, NEP 2020 – BP101T Syllabus (Basics of Python Programming for Pharmaceutical Sciences)
- Python Software Foundation, “Text Sequence Type — str” – docs.python.org/3/library/stdtypes.html#text-sequence-type-str
- Python Software Foundation, “String Methods” – docs.python.org/3/library/stdtypes.html#string-methods
