First one quick style suggestion - rather than using the for loops to generate numeric indices
for j in range(len(classes)):
...
Just pick a meaningful loop variable (eg classname) and walk that loop variable through the list with the for loop this way:
for classname in classes:
...
For your units and dates lists where you are going through them in "parallel" this is a classic use of the zip( ) function which 'zips' the two lists together and creates a virtual list of tuples which you can then use the for loop to walk two loop variables through the two values in parallel
for unit, date in zip(units, dates):
...
Together those changes will allows you to have meaningful variable names (classname, unit, date)
Finally in order to 'plug in' your variables a more recent approach called f-strings allows you to create a string with placeholders. The place holders can contain any valid Python expression and it will be computed and inserted into the larger string
For example:
name = "Fred"
age = 12
# f-string starts with f then a quote character
# anything inside curly braces { } is evaluated as a
# Python expression and substituted as text into the larger string
text = f"{name} is {age + 1} years old on his next birthday"
Then finally to add each string to a different variable you could do as as poster RufusVS suggested and append each string to a list. That would allow you to refer to each string by a number.
If you really want each string to have a brand new variable name you could do something a little more meta and create a new variable for each string by writing to the global symbol table which is just a dictionary that Python uses to keep track of its global variables.
Here is the approach where you append each message to a list:
classes = ['Math', 'English', 'History']
units = ['Unit 9', 'Unit 10', 'the Exam']
dates = ['may 11th', 'may 18th', 'may 25th']
all_messages = [] # empty list for the messages
for classname in classes:
for unit, date in zip(units, dates):
string = (f"Hello, we'll have {classname} class on {date}\n"
+ f"The topic will be {unit}\n")
print(string) # for debugging
all_messages.append(string) # to save each message
print(Message 5 is", all_messages[5])
Here is the more meta approach where you actually create a new variables of the form messagen (eg message0, message1, etc) for each message you create
classes = ['Math', 'English', 'History']
units = ['Unit 9', 'Unit 10', 'the Exam']
dates = ['may 11th', 'may 18th', 'may 25th']
symbol_table = globals() # get the global symbol table
count = 0 # counter to track which message variable we are creating
for classname in classes:
for unit, date in zip(units, dates):
string = (f"Hello, we'll have {classname} class on {date}\n"
+ f"The topic will be {unit}\n")
print(string) # for debugging
# little tricky here - create a string with the name of the
# variable you want to create (eg. 'message5')
# then use that string as the key in the globals dictionary
# the value associated with that key is the new message
# this actually creates a new global variable for each message
symbol_table[f"message{count}"] = string
count += 1
print("Message 5 is", message5)