How to reference a dictionary to fill variables in a string? - python

I am trying to work out how to complete a task that asks the following:
Create a string and use a method to generate a description of the new car as shown below. Print it – it should be formatted like the text below (including the line breaks).
Yesterday I bought a [Make] [Model].
It’s not “too” old. It was made in [year] …
I like it, though. It’s [colour], and it has [doors] doors!
The variables (make, model, year, colour and doors) need to be populated from a dictionary.
I have programmed the dictionary to look like this:
Car = {
'Make': 'Mitsubishi',
'Model': 'Lancer',
'Year': '2002',
'Colour': 'Green',
'Doors': '4',
}
How can i fill the variables in that string of text by referencing the dictionary 'Car'?
Thank you!

You can create a template string, and then burst the dictionary values to format it. Example.
fstr = "Yesterday I bought a {} {}.\n\nIt’s not “too” old. It was made in {} …\n\nI like it, though. It’s {}, and it has {} doors!"
Car = {
'Make': 'Mitsubishi',
'Model': 'Lancer',
'Year': '2002',
'Colour': 'Green',
'Doors': '4',
}
print(fstr.format(*Car.values()))
Gives an output like
Yesterday I bought a Mitsubishi Lancer.
It’s not “too” old. It was made in 2002 …
I like it, though. It’s Green, and it has 4 doors!
So, you can apply the format with any dictionary you want.
Condition: You have to make sure the key/values are in the same order of the fillers.

python uses f-strings for this. You can use f-strings to pass variables to your string, while still keep it readable.
output = f"Yesterday I bought a {Car['Make']} {Car['Model']}."
you use \n to represent a newline, and \ to escape any "" in the string itself:
output = f"Yesterday I bought a {Car['Make']} {Car['Model']}.\nIt’s not \“too\” old. It was made in {Car['Year']}"
extra: Pythons PEP8 style guides mention that variable names (like your dictionary) should always start with a lowercase.
Edit: Thanks to Timus for pointing out a small error. added '' around dict keys.

Build a string with the dictionary keys as placeholders (included in curly braces), and then use .format_map() with the dictionary as argument on it:
string = '''Yesterday I bought a {Make} {Model}.
It’s not “too” old. It was made in {Year} …
I like it, though. It’s {Colour}, and it has {Doors} doors!'''
Car = {
'Make': 'Mitsubishi',
'Model': 'Lancer',
'Year': 2002,
'Colour': 'Green',
'Doors': 4,
}
print(string.format_map(Car))
(The ordering of the dictionary is irrelvant.)

Related

Python typed dict with 1 type A value, and all others values of type B?

After looking at the TypedDictionary documentation of MyPy, I learned one can specify the types of values of specific keys with:
from typing_extensions import TypedDict
Movie = TypedDict('Movie', {'name': str, 'year': int})
movie: Movie = {'name': 'Blade Runner', 'year': 1982}
However, how does one specify the type for 1 variable, for example, the name of a movie is of type string, and whatever else you add, is of type int?
A bit like:
from typing_extensions import TypedDict
Movie = TypedDict('Movie', {'name': str, '*': int})
# Works:
movie: Movie = {'name': 'Blade Runner', 'year': 1982, 'nr_of_pancakes_in_movie': 42}
# Fails
movie: Movie = {'name': 'Blade Runner', 'year': 1982, 'nr_of_pancakes_in_movie': "seven"}
Since I received feedback on whether I should or shouldn't do this, I thought I could include the case on which I am applying this. The thing I am applying it to, is a set of graphs, of which 1 graph, the input graphis of typenetworkx.graphwhereas the others are of typenetworkx.DiGraph`. Each graph has a name, yet I do not in advance know which graphs will be added to the dictionary.
The set of graphs gets passed around and it has quite a bit of nested elements that are processed and manipulated, so I would like to keep the depth of the graphs_dict constant to make it easier to perform multiple operations on the graphs that are applied to both types.
You say you want a data type that has one element of a specific type and an open number of other elements of another type.
That sounds more like:
MyGraph = TypedDict('MyGraph ': {'graph': networkx.graph, di_graphs: List[networkx.DiGraph]})
The natural solution is to use a list for the open number of elements, it can have 0 or more elements, and the type is clear here.
It does seem like you're trying to bolt features from other languages onto Python though, which Python doesn't need - or if you do need them, you may not find Python the best choice.

Updating a value within a dictionary python [duplicate]

This question already has answers here:
find and update a value of a dictionary in list of dictionaries
(2 answers)
Closed 1 year ago.
I am trying to update the department of bob to Human Resources. I was under the impression from my readings and research that you just needed to rename the value within the key as I have done within my code but I keep getting an Assertion error. Any tips?
directory= [{'firstName': "bob", 'department': "Accounting", 'salary': 50000}, {'firstName': "alice", 'department': "Marketing", 'salary': 100000}]
#My Code
directory['department'] = 'Human Resources'
Do this:
directory= [{'firstName':"bob",'department':"Accounting",'salary':50000},{'firstName':"alice",'department':"Marketing",'salary':100000}]
for d in directory:
if 'firstName' in d and d['firstName'] == 'bob':
d['department'] = 'Human Resources'
break
print(directory) # [{'firstName': 'bob', 'salary': 50000, 'department': 'Human Resources'}, {'firstName': 'alice', 'salary': 100000, 'department': 'Marketing'}]
Your problem is that you're not actually dealing with a dictionary, but a list of dictionaries. This means you can't directly access the key, you have to access the item in the list.
To fix your current code:
directory[0]['department'] = 'Human resources'
Notice the [0].
You can tell this is the data structure because it has square brackets before and after the curly brackets. Eg. directory =[{ ... }]
For future reference, if you would like to look up someone by name, you'll need to iterate through the list and then update the appropriate dictionary.
for entry in directory:
# We're looking for Bob from accounting, not Bob the auditor.
if entry['name'] == 'bob' and entry['department'] == 'Accounting':
entry['department'] = 'Human Resources'
# break makes sure that this only happens once.
break
Since bob is a relatively common name, you might need to make your name values more unique. Bob Vila is more unique than bob, meaning you are less likely to address someone you don't mean to.
Of course, if you know that you have a unique value for each entry in the directory, then you can convert the whole thing into a dict.
# This is a dictionary comprehension. They're pretty neat.
new_directory = {employee['name']: employee for employee in directory}
new_directorr['bob']['department'] = 'Human resources'
On the linked question, the recommendation is a generator expression inside of next:
try:
bob = next(employee for employee in directory if employee['name'] == 'bob')
bob['department'] = 'Human Resources'
except StopIteration: # next will cause a exception if bob cannot be found.
pass
But you should note: the use of next with a list comprehension as well as for...in the iteration above: both are good ideas in some circumstances, but they will slow down over time as your directory gets bigger.

Can I make the age value calculable based on year of birth inside a dictionary?

I am new to Python, and I want to know if there is a way to make the age value calculated using the year of birth which is an item with the age in the same dictionary.
This is what it came to my mind, and I think there is simple way like this without using additional variables of functions.
person = {
'name': Jane,
'yearofbirth': 1995,
'yearnow': 2019,
'age': person['yearnow'] + person['yearofbirth']
}
Any help would be appreciated. Thank you!
Yes, you can
Just not decalre the whole dict in one act
person = {
'name': Jane,
'yearofbirth': 1995,
'yearnow': 2019
}
person["age"] = (lambda yearnow, yearofbirth: yearnow - yearofbirth)(**person)
But in your example you shouldn't change anything, because there is no way to simplify it(easily). My solution should be used only in complicated tasks. I just you the way to simplify it in case of a huge amount of values in dict.
Instead of hardcoding the current year, you could get python to give it to you
from datetime import datetime
currentYear = datetime.now().year
person = {
'name': 'Jane',
'yearofbirth' : 1995
}
age = currentYear - person.get( "yearofbirth", "")
person.update({'age': age})
print(person)
You can't set your age inside the dict, as it has not been defined yet.
If you do like above code, we are setting the age outside the dict, then updating the dict with the value we just calculated based on currentYear and the age
The output is:
{'name': 'Jane', 'yearofbirth': 1991, 'age': 24}
You may have self referential dictionary by using a class derived from dict but dict itself doesn't have this capability. The following code is taken from this answer.
class MyDict(dict):
def __getitem__(self, item):
return dict.__getitem__(self, item) % self
dictionary = MyDict({
'user' : 'gnucom',
'home' : '/home/%(user)s',
'bin' : '%(home)s/bin'
})
print dictionary["home"]
print dictionary["bin"]

Should I be using two dictionaries or is there a better way? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I want to create a new file based on a JamBarcode which looks up the Price from JamPrice and the rest of the information from JamDetails and puts it into a new file.
I've got (at the moment) two dictionaries like the following:
JamPrice = {
"JamBarcode": "1234", "Price": "1",
} print JamPrice
and
JamDetails = {
"JamBarcode": "1234", "Colour": "red", "Size": "small"
} print JamDetails
Is this the right data structure to be using, and am I going about it the right way or is there a much easier way to do it? I've been looking at http://www.pythonforbeginners.com/dictionary/how-to-use-dictionaries-in-python to help.
Conceptually, I'd separate these into two tables in a database: product info, and product retail info. The latter should contain all the info necessary to sell the item, which in addition to retail price is probably going to be something like which department to count it under, how many units are sold, any restrictions on the product (is it alcohol? Do you need to age-verify the sale?)
The latter should also contain a foreignkey to point back to the former, or in the case of a dictionary should contain some matching information (e.g. barcode, like you have).
I think you need two data: products and prices
These are linked by the barcode. Then they can vary independently:
products = {
"1234": dict(name="jam", colour="red", size="small")
"5678": dict(name="marmalade", colour="orange", size="medium")
}
prices = {
"1234": "1.5",
"5678": "1.75"
}
I'd suggest combining all the jam details into a unified dictionary, and accessing the contents using your JamBarcode. In other words, there is effectively an object associated with each barcode key inside the dictionary.
e.g.
# create a dictionary called jam:
jam_dictionary = {}
# insert items into your dictionary using index notation:
jam_dictionary['1234'] = {'Colour': 'red', 'Size': 'small', 'Price': '1'}
# you can also use the index key to retrieve the information
print(jam_dictionary['1234'])
# {'Colour': 'red', 'Size': 'small', 'Price': '1'}
# and specific sub-fields
print(jam_dictionary['1234']['Colour'])
# red
jam_dictionary['1234']['Colour'] = 'blue'
print(jam_dictionary['1234']['Colour'])
# blue
You can also construct your dictionary like this:
jam_dictionary = {
'1234': {'Colour': 'red', 'Size':'small', 'Price': '1'},
'5678': {'Colour': 'blue', 'etc':'etc'}
}
But this is more convoluted and since you'll likely add or remove things after the dictionary is already created, you may as well do it the first way.
If you would benefit from having associated functions for handling or processing the data, then you should start thinking about possibly creating a Jam Class
It seems to me that you really want a collection of Jams and that you are using the barcode information to keep track of which one you are specifically referencing.
It looks to me like you would have a dict:
Jams = { '1234':[1, "red", "small"]}
you could then add more jams to the dict using the barcode as the key.
You are not far enough in the book to "get" this but you will find that keeping the information in the list "right"_will get tricky and you will want to use a "named tuple" instead
import collections
JamTuple = collections.namedtuple('Jam', ['barcode', 'price', 'color', 'size'])
a_jam = JamTiuple(1234, price=1,color='red', size='Small')
JamsDict = {1234:a_jam}
But really, it depends a lot on what you want to do next.

Code to extract text fields from a mongodb collection and append it to a list in python using pymongo

I have created an if statement to cycle through a mongodb collection of json objects and extract the text field from each and append it to a list. Here is the code below.
appleSentimentText = []
for record in db.Apple.find():
if record.get('text'):
appleSentimentText.append(record.get("text"))
This works grand but I have 20 collections to do this to and I fear the code may start to get a little messy and unmanageable with another 19 variations of this code. I have started to write a piece of code that may accomplish this. Firstly I have created an array with the names of the 20 collections in it shown below.
filterKeywords = ['IBM', 'Microsoft', 'Facebook', 'Yahoo', 'Apple','Google', 'Amazon', 'EBay', 'Diageo',
'General Motors', 'General Electric', 'Telefonica', 'Rolls Royce', 'Walmart', 'HSBC', 'BP',
'Investec', 'WWE', 'Time Warner', 'Santander Group']
I then use this array in an if statement to cycle through each collection
for word in filterKeywords:
for record in db[word].find():
if db[word].get('text'):
I now want it to create a list variable based on the collection name (ie AppleSentimentText if collection is apple, FacebookSentimentText if it is Facebook collection, etc) though im unsure of what to do next. Any help is welcome
You may use $exists and limit the returned field to "text" so it doesn't need to go through all records, in pymongo it should be something like this:
Edited:
As #BarnieHackett pointed out, you can filter out the _id as well.
for word in filterKeywords:
for r in db[word].find({'text': {'$exists': True}}, {'text': 1, '_id': False}):
appleSentimentText.append(r['text'])
The key is to use $exists and then limit the return field to 'text', unfortunately since pymongo returns the cursor which includes the '_id' & 'text' field, you need to filter this out.
Hope this helps.

Categories

Resources