I am trying to get the instance id of ec2 that I created. But I get 2 different outputs, why? Please check the print outputs.
print (a)
i-0ae514dcs36chb154
print (instance)
ec2.Instance(id='i-0ae514dcs36chb154')
ec=ec2.create_instances(
ImageId=ami,
InstanceType=type,
MinCount=size,
MaxCount=size,
KeyName=keyname,
SecurityGroupIds=[sg],
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'Name',
'Value': name,
},
],
},
],
)
a= ec[0].id
print (a) # Output: i-0ae514dcs36chb154
instance = ec2.Instance(a)
print (instance) # Output : ec2.Instance(id='i-0ae514dcs36chb154')
Thansks.
As seen here:
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.ServiceResource.create_instances
When you call create_instances() it returns a list of ec2.Instance() which is an object with an attribute id.
When you write,
a = ec[0].id # Create a variable called "a" that points to the value of the "id" attribute of the first element in the list
print(a) # print the id
When you write,
a = ec[0].id # Create a variable called "a" that points to the value of the "id" attribute of the first element in the list
print(ec2.Instance(a)) # Create a new instance of ec2.Instance() with id equal to the value at a, then call the .__str__ method, and print
^ this is actually redundant.
Calling print(ec[0]) should yield ec2.Instance(id='i-0ae514dcs36chb154')
So, the reason they are different is that in the first you are printing the value of the attribute id of the ec2.Instance() object. In the second you are printing the ec2.Instance() object itself, which will call the private method __str__ on the ec2.Instance() object in order to produce a string to print.
Related
I have a list of dicts based on user selections from a GUI (Plotly returns.) When a user clicks a data point (or group of data points), the datapoint(s) is added to the list.
However, if the user clicks the same data point (or selects a group of datapoints, which includes a datapoint already selected) then redundant dictionaries appear in the list for the redundant data point(s).
I.e.
[
{
"clicked": true,
"selected": true,
"hovered": false,
"x": 0,
"y": 71100.0988957607,
"selected_xcol": "injection_id",
"xvalue": "e54112f9-4497-4a7e-91cd-e26842a4092f",
"selected_ycol": "peak_area",
"yvalue": 71100.0988957607,
"injection_id": "e54112f9-4497-4a7e-91cd-e26842a4092f"
},
{
"clicked": true,
"selected": true,
"hovered": false,
"x": 0,
"y": 75283.2386064552,
"selected_xcol": "injection_id",
"xvalue": "e54112f9-4497-4a7e-91cd-e26842a4092f",
"selected_ycol": "peak_area",
"yvalue": 75283.2386064552,
"injection_id": "e54112f9-4497-4a7e-91cd-e26842a4092f"
},
{ # Redundant, same as first item
"clicked": true,
"selected": true,
"hovered": false,
"x": 0,
"y": 71100.0988957607,
"selected_xcol": "injection_id",
"xvalue": "e54112f9-4497-4a7e-91cd-e26842a4092f",
"selected_ycol": "peak_area",
"yvalue": 71100.0988957607,
"injection_id": "e54112f9-4497-4a7e-91cd-e26842a4092f"
}
]
Because users can select one or multiple datapoints in one GUI stroke, and the code doesn't know which, I simply add the returned list to the cumulative list like so...
LOCAL["selected_data"] += selectable_data_chart(LOCAL["df"],
key = "st_react_plotly_control_main_chart",
custom_data_columns = custom_data_columns,
hovertemplate = hovertemplate,
svgfilename = svgfilename)
I have tried filtering out the redundant items with ...
LOCAL["selected_data"] = list(set(LOCAL["selected_data"]))
...but it raises an error...
TypeError: unhashable type: 'dict'
I have also tried...
result = []
LOCAL["selected_data"] = [result.append(d) for d in LOCAL["selected_data"] if d not in result]
...but it returns null no matter what.
[
null,
null
]
You can't add a mutable value to a set (or use it as a dictionary key)...what if, after adding an item to a set, you changed the values so that it was identical to another set member? That would invalidate the guarantees provided by the set data type.
One possible solution is to transform your dictionaries into a structured type. For example, using the dataclasses module, we could write (assuming that your sample data is contained in the file data.json):
import json
import dataclasses
#dataclasses.dataclass(frozen=True)
class Event:
clicked: bool
selected: bool
hovered: bool
x: float
y: float
selected_xcol: str
xvalue: float
selected_ycol: str
yvalue: float
injection_id: str
with open("data.json") as fd:
data = json.load(fd)
events = set(Event(**item) for item in data)
As #lemon pointed out in a comment, this won't actually work for the sample data in your question, because the third item in the list is not identical to the first item (in the first item, x=0, but in the third item, x="e54112f9-4497-4a7e-91cd-e26842a4092f"). If this was just a typo when entering your question, the solution here will work just fine.
A less structured solution would be to transform each dictionary into a list of tuples using the items() method, turn that into a tuple, and then add those to your "unique" set:
import json
with open("data.json") as fd:
data = json.load(fd)
events = set(tuple(item.items()) for item in data)
In this case, events is a set of tuples; you could transform it back into a list of dictionaries like this:
dict_events = [dict(item) for item in events]
I am doing some parse work with hl7apy parse, and i occurred with one problem.
I use hl7apy to parse hl7 message, which can be parse:
from hl7apy.parser import parse_message
message = "MSH|^~\&|HIS|HIS|MediII|MediII|20170902141711||ORM^O01^ORM_O01|15b 37e7132504a0b95ade4654b596dc5|P|2.4\r"
msg = parse_message(message, find_groups=False)
print(msg.msh.msh_3.msh_3_1.value)
output:
'HIS'
so, how can i get field value dynamically according to field config?
for example, the msh field config :
{
"field": "msh",
"field_index": [3,1]
}
so the value can be find with:
msg.msh.msh_3.msh_3_1.value
and if config change to:
{
"field": "pid",
"field_index": [2,4]
}
the get field line will be:
msg.pid.pid_2.pid_2_4.value
You could combine a few list comprehensions and use getattr recursively.
# recursively get the methods from a list of names
def get_method(method, names):
if names:
return get_method(getattr(method, names[0]), names[1:])
return method
field_config = {
'field': 'msh',
'field_index': [3, 1]
}
# just get the field
field = field_config['field']
# get a list of the indexes as string. ['3', '1']
indexes = [str(i) for i in field_config['field_index']]
# join the indexes with a '_' starting with nothing
# and put it in a list of names. ['msh', 'msh_3', 'msh_3_1']
names = ['_'.join([field] + indexes[:i]) for i in range(len(indexes) + 1)]
# get the method from the recursive function
method = get_method(msg, names)
print(method.value)
As a disclaimer, I had no way of testing it so it may not work exactly as you expect it. But this should be a good starting point.
how to make a Multidimensional Dictionary with multiple keys and value and how to print its keys and values?
from this format:
main_dictionary= { Mainkey: {keyA: value
keyB: value
keyC: value
}}
I tried to do it but it gives me an error in the manufacturer. here is my code
car_dict[manufacturer] [type]= [( sedan, hatchback, sports)]
Here is my error:
File "E:/Programming Study/testupdate.py", line 19, in campany
car_dict[manufacturer] [type]= [( sedan, hatchback, sports)]
KeyError: 'Nissan'
And my printing code is:
for manufacuted_by, type,sedan,hatchback, sports in cabuyao_dict[bgy]:
print("Manufacturer Name:", manufacuted_by)
print('-' * 120)
print("Car type:", type)
print("Sedan:", sedan)
print("Hatchback:", hatchback)
print("Sports:", sports)
Thank you! I'm new in Python.
I think you have a slight misunderstanding of how a dict works, and how to "call back" the values inside of it.
Let's make two examples for how to create your data-structure:
car_dict = {}
car_dict["Nissan"] = {"types": ["sedan", "hatchback", "sports"]}
print(car_dict) # Output: {'Nissan': {'types': ['sedan', 'hatchback', 'sports']}}
from collections import defaultdict
car_dict2 = defaultdict(dict)
car_dict2["Nissan"]["types"] = ["sedan", "hatchback", "sports"]
print(car_dict2) # Output: defaultdict(<class 'dict'>, {'Nissan': {'types': ['sedan', 'hatchback', 'sports']}})
In both examples above, I first create a dictionary, and then on the row after I add the values I want it to contain. In the first example, I give car_dict the key "Nissan" and set it's values to a new dictionary containing some values.
In the second example I use defaultdict(dict) which basically has the logic of "if i am not given a value for key then use the factory (dict) to create a value for it.
Can you see the difference of how to initiate the values inside of both of the different methods?
When you called car_dict[manufacturer][type] in your code, you hadn't yet initiated car_dict["Nissan"] = value, so when you tried to retrieve it, car_dict returned a KeyError.
As for printing out the values, you can do something like this:
for key in car_dict:
manufacturer = key
car_types = car_dict[key]["types"]
print(f"The manufacturer '{manufacturer}' has the following types:")
for t in car_types:
print(t)
Output:
The manufacturer 'Nissan' has the following types:
sedan
hatchback
sports
When you loop through a dict, you are looping through only the keys that are contained in it by default. That means that we have to retrieve the values of key inside of the loop itself to be able to print them correctly.
Also as a side note: You should try to avoid using Built-in's names such as type as variable names, because you then overwrite that functions namespace, and you can have some problems in the future when you have to do comparisons of types of variables.
I have just started learning python and i have been given an assignment to create a list of players and stats using different loops.
I cant work out how to create a function that searches the player list and gives an output of the players name and the players stat.
Here is the assignment:
Create an empty list called players
Use two input() statements inside a for loop to collect the name
and performance of each player (the name will be in the form of a
string and the performance as an integer from 0 – 100.) Add both
pieces of information to the list (so in the first iteration of the
loop players[0] will contain the name of the first player and
players[1] will contain their performance.) You are not required to
validate this data.
Use a while loop to display all the player information in the
following form:
Player : Performance
Use a loop type of your choice to copy the performance values from
the players list and store these items in a new list called results
Write a function that accepts the values “max” or “min” and
returns the maximum or minimum values from the results list
Write a function called find_player() that accepts a player name
and displays their name and performance from the players list, or an
error message if the player is not found.
Here is what I have so far:
print ("Enter 11 Player names and stats")
# Create player list
playerlist = []
# Create results list
results = []
# for loop setting amount of players and collecting input/appending list
for i in range(11):
player = (input("Player name: "))
playerlist.append(player)
stats = int(input("Player stats: "))
playerlist.append(stats)
# While loop printing player list
whileLoop = True
while whileLoop == True:
print (playerlist)
break
# for loop append results list, [start:stop:step]
for i in range(11):
results.append(playerlist[1::2])
break
# max in a custom function
def getMax(results):
results = (playerlist[1::2])
return max(results)
print ("Max Stat",getMax(results))
# custom function to find player
def find_player(playerlist):
list = playerlist
name = str(input("Search keyword: "))
return (name)
for s in list:
if name in str(s):
return (s)
print (find_player(playerlist))
I have tried many different ways to create the find player function without success.
I think I am having problems because my list consists of strings and integers eg. ['john', 6, 'bill', 8]
I would like it to display the player that was searched for and the stats ['John', 6]
Any help would be greatly appreciated.
PS:
I know there is no need for all these loops but that is what the assignment seems to be asking for.
Thank you
I cut down on the fat and made a "dummy list", but your find_player function seems to work well, once you remove the first return statement! Once you return something, the function just ends.
All it needs is to also display the performance like so:
# Create player list
playerlist = ["a", 1, "b", 2, "c", 3]
# custom function to find player
def find_player(playerlist):
name = str(input("Search keyword: "))
searchIndex = 0
for s in playerlist:
try:
if name == str(s):
return ("Player: '%s' with performance %d" % (name, playerlist[searchIndex+1]))
except Exception as e:
print(e)
searchIndex += 1
print (find_player(playerlist))
>>Search keyword: a
>>Player: 'a' with performance 1
I also added a try/except in case something goes wrong.
Also: NEVER USE "LIST" AS A VARIABLE NAME!
Besides, you already have an internal name for it, so why assign it another name. You can just use playerlist inside the function.
Your code didn't work because you typed a key and immediately returned it. In order for the code to work, you must use the key to find the value. In this task, it is in the format of '' key1 ', value1,' key2 ', value2, ...]. In the function, index is a variable that stores the position of the key. And it finds the position of key through loop. It then returns list [index + 1] to return the value corresponding to the key.
playerlist = []
def find_player(playerlist):
list = playerlist
name = str(input("Search keyword: "))
index = 0
for s in list:
if name == str(s):
return ("This keyword's value: %d" % (list[index+1]))
index+=1
print (find_player(playerlist))
I have HTML form input field that returns a list of dictionaries I want to get values from using PYthon in Django View.
The form returns:
request.POST['tags'] returns => [{"value":"summer"},{"value":"winter"}]
When I try interating through it using [tag['value'] for tag in request.POST['tags']] to get values, I get TypeError: string indices must be integers.
However, if I manually copy the input field results to command line and go line by line it works as expected:
>>> test = [{"value":"summer"},{"value":"winter"}]
>>> test
>>> [{'value':'summer'},{'value':'winter'}]
>>> [tag['value'] for tag in test]
>>> ['summer', 'winter']
What is happening?
Updated to add print of 3 different request.POST results:
request.POST => <QueryDict: {'tags': ['[{"value":"summer"},{"value":"winter"}]']}>
request.POST.values => <bound method MultiValueDict.values of <QueryDict: {
'tags': ['[{"value":"summer"},{"value":"winter"}]']}>>
request.POST[tags] => [{"value":"summer"},{"value":"winter"}]
https://docs.djangoproject.com/en/2.2/ref/request-response/#querydict-objects
QueryDict.__getitem__(key)
Returns the value for the given key. If the key has more than one value, it returns the last value. Raises django.utils.datastructures.MultiValueDictKeyError if the key does not exist. (This is a subclass of Python’s standard KeyError, so you can stick to catching KeyError.)
You will have to user getlist() when you have multiple values for the same key:
[tag['value'] for tag in request.POST.getlist('tags')]
https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.QueryDict.getlist
QueryDict.getlist(key, default=None)
Returns a list of the data with the requested key. Returns an empty list if the key doesn’t exist and a default value wasn’t provided. It’s guaranteed to return a list unless the default value provided isn’t a list.
EDIT
Okay, I can see the issue now. You are not sending a list to your arg tags, you are sending a string that represents a list.
If I am not missing anything else the following should work:
import json
tags = json.loads(request.POST['tags'])
[tag.get('value') for tag in tags]