I'd like to send pre-defined messages to certain study groups with information regarding classes, dates and the units to be studied while only changing minor things. To do so, I've created three lists as follows:
classes = ['Math', 'English', 'History']
units = ['Unit 9', 'Unit 10', 'the Exam']
dates = ['may 11th', 'may 18th', 'may 25th']
In order to call each list item, I've used for statements (minimal example below):
for j in range(len(classes)):
for i in range(len(units)):
text = ''' Hello, we'll have %s classes on %s.
The topic will be %s.
''' % (classes[j], dates[i], units[i])
print(text)
This code prints my desired message for each group. However, I don't know how to associate each of these texts to a different variable so that I can call upon it later on, when I tell my code to write each email.
CodePudding user response:
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)