This may sound a bit strange or silly but I am trying to create a dictionary or lists that can be referenced. Maybe if you look at the attached pic of my Excel would give you a better understanding.
I want the values of each row to be into a dictionary with say the key as 0 and different values as under Hostname, IP, GroupName and Port. the dictionary works with just the Hostname and IP as their length is same, but when i try to add the GroupName to the dict by using a lot of methods i found on Stackoverflow, it does not work as the length is not the same
enter image description here
Any help would be appreciated
Here is my code.
df = pd.read_excel("object.xlsx")
HostList =[]
IPList = []
for x in ExcelHostList:
for hostname in x:
if hostname not in HostList:
HostList.append(hostname)
for ips in ExcelIPList:
for ipadd in ips:
if ipadd not in IPList:
IPList.append(ipadd)
dict1 = dict(zip(HostList, IPList))
dict1
{'test1': '1.1.1.1', 'test2': '2.2.2.2', 'test3': '3.3.3.3', 'test4': '4.4.4.4', 'test5': '5.5.5.5', 'test6': '6.6.6.6'}
I have tried with making it a dict and then trying to combine them
ExcelHostList = (df["Hostname"].str.split("\n").to_dict())
ExcelIPList = (df["IP"].str.split("\n").to_dict())
ExcelGroupName = (df["GroupName"].to_dict())
dict2 = {z[0]: list(z[1:]) for z in zip(HostList, IPList, ExcelGroupName)}
dict2
{'test1': ['1.1.1.1', 'test-group-1'], 'test2': ['2.2.2.2', 'test-group-2'], 'test3': ['3.3.3.3', 'test-group-3']}
It's going to be very difficult to provide you with a good answer without more context about what exactly your end goal is for this data, but here are two ways you can consider structuring your data:
A list of dicts:
list_of_dicts = [
dict(
Hostname = ['test1', 'test2', 'test3',],
IP = ['1.1.1.1', '2.2.2.2', '3.3.3.3',],
GroupName = 'test-group-1',
Port = [443, 22, 808, 80, 161],
),
dict(
Hostname = ['test4',],
IP = ['4.4.4.4',],
GroupName = 'test-group-2',
Port = [443, 8080],
),
dict(
Hostname = ['test5', 'test6',],
IP = ['5.5.5.5', '6.6.6.6',],
GroupName = 'test-group-3',
Port = [443],
),
]
print(list_of_dicts)
print(list_of_dicts[0])
print(list_of_dicts[0]["Hostname"])
print(list_of_dicts[0]["Hostname"][0])
A dict of dicts using the GroupNames as keys:
dict_of_dicts = {
'test-group-1' : dict(
Hostname = ['test1', 'test2', 'test3',],
IP = ['1.1.1.1', '2.2.2.2', '3.3.3.3',],
Port = [443, 22, 808, 80, 161],
),
'test-group-2' : dict(
Hostname = ['test4',],
IP = ['4.4.4.4',],
Port = [443, 8080],
),
'test-group-3' : dict(
Hostname = ['test5', 'test6',],
IP = ['5.5.5.5', '6.6.6.6',],
Port = [443],
),
}
print(dict_of_dicts)
print(dict_of_dicts['test-group-1'])
print(dict_of_dicts['test-group-1']["Hostname"])
print(dict_of_dicts['test-group-1']["Hostname"][0])
examples in python tutor
Also if you already have this data in excel then I would highly recommend looking into using pandas to read this data into a DataFrame.
Related
I have this network:
r1 = dict( name = 'R1', ports = dict(p1 = 'p1', p2 = 'p2') )
r2 = dict( name = 'R2', ports = dict(p1 = 'p1', p2 = 'p2') )
r3 = dict( name = 'R3', ports = dict(p1 = 'p1', p2 = 'p2') )
routers = [r1,r2,r3]
G = nx.Graph()
[G.add_node(r['name'], name=r['name']) for r in routers]
G.add_edges_from([('R1','R2'),('R2','R3')]
The previous produces the next topology.
As you can see, each of the nodes have their ports p1 and p2. I know how to create these edges or connections in the graph:
In [53]: G.edges()
Out[53]: EdgeView([('R1', 'R2'), ('R2', 'R3')])
However I'm mostly interested in using the ports of each node as point of connection. Meaning:
In [53]: G.edges()
Out[53]: EdgeView([('R1'.'p1', 'R2'.'p2'), ('R2'.'p1', 'R3'.'p2')])
How can I accomplish that? Or, in other words, how could I model that, in the sense of having nodes+ports where the anchor points are ultimately these ports?
thanks!
Generic model for any port connection
First you need to add the ports as an attribute to your nodes:
import networkx as nx
r1 = dict( name = 'R1', ports = dict(p1 = 'p1', p2 = 'p2') )
r2 = dict( name = 'R2', ports = dict(p1 = 'p1', p2 = 'p2') )
r3 = dict( name = 'R3', ports = dict(p1 = 'p1', p2 = 'p2') )
routers = [r1,r2,r3]
G = nx.Graph()
for r in routers:
# Add ports as attributes
G.add_node(r['name'], name=r['name'], ports=r['ports'])
So, now if I do the following:
G.nodes().get('R3', None)
I get the following:
{'name': 'R3', 'ports': {'p1': 'p1', 'p2': 'p2'}}
Then, you can basically add a wrapper function for creating edges in your graph. I have assumed that you can use any port from one node to any other port of another node :
def add_edge_port(G, node1, port1, node2, port2):
node_list = [node1, node2]
port_list = [port1, port2]
edge_ports = []
for idx in range(0, 2):
node_idx = node_list[idx]
port_idx = port_list[idx]
# Sanity check to see if the nodes and ports are present in Graph
if G.nodes().get(node_idx, None) is None:
print("Node : {} is not present in Graph".format(node_idx))
return
if G.nodes(data=True)[node_idx]['ports'].get(port_idx, None) is None:
print("Port ID :{} is incorrect for Node ID : {}!".
format(node_idx, port_idx))
return
edge_ports.append(node_idx + '.' + port_idx)
# Add the anchor points as edge attributes
G.add_edge(node1, node2, anchors=edge_ports)
Now add the edges like this:
add_edge_port(G, 'R1', 'p1', 'R2', 'p2')
print(G.edges(data=True))
# Output : EdgeDataView([('R1', 'R2', {'anchors': ['R1.p1', 'R2.p2']})])
To get the anchors list, simply use:
print(nx.get_edge_attributes(G, 'anchors'))
# Output: {('R1', 'R2'): ['R1.p1', 'R2.p2']}
Now if you are sure that port p1 will always connect to port p2
def add_edge_port_modified(G, node1, node2):
# No need to check the nodes in this case
edge_ports = [node1 + '.p1', node2 + '.p2']
G.add_edge(node1, node2, anchors=edge_ports)
Then call:
add_edge_port_modified(G, 'R2', 'R3')
and the edges will be
print(nx.get_edge_attributes(G, 'anchors'))
# Output: {('R2', 'R3'): ['R2.p1', 'R3.p2']}
References:
https://networkx.github.io/documentation/networkx-2.2/reference/generated/networkx.classes.function.get_edge_attributes.html
I have a string related to a programs output, now I need to convert the string into a dictionary. I have tried it by using dict() and zip() commands but I am not able to fetch the results.
This is the code I have so far:
string = "Eth1/1 vlan-1 typemode-eth status:access eth1/2 vlan-1 type-eth status:access"
list1=string.split(' ')
print(list1)
['Eth1/1', 'vlan-1', 'typemode-access']
and further than this I have no idea:
{'eth1/1': {'Speed': '10Gb', 'Vlan': 1, 'Type Mode': 'eth', 'status': 'access'}, 'eth1/2': {'Speed': '10Gb', 'Vlan': 1, 'Type Mode': 'eth', 'status': 'access'}}
From your result to get a value see the following example. See inline comments.
import re
result = {}
string = "Eth1/1 vlan-1 typemode-eth status:access eth1/2 vlan-1 type-eth status:access"
a = re.search('access', string) # this gives 2 positions for the word access.
list1 = [string[0:a[0]], string[[a[0]+1]:]] # two substrings. a[0] is used to get
# roughly the middle of the string where the spplitpoint is of both
# substrings. Using access as key word gives flexibility if there is a third
# substring as well.
result = dict(list1) # result should be same as result2.
# y1 z1
result2 = {'eth1/1': {'Speed': '10Gb', 'Vlan': 1, 'Type Mode': 'eth', 'status': 'access'},
'eth1/2': {'Speed': '10Gb', 'Vlan': 1, 'Type Mode': 'eth', 'status': 'access'}}
# y2 = eth1/2.
# y1 y2
x = result['eth1/1']['Speed'] # replace any word at y1 or z1 to fetch another result.
print ('Got x : %s' % x) # this prints '10Gb'.
Basically what you've created is nested dictionaries. So addressing y1 first is enabling to get data from that particular dictionary. after y1 calling for z1 is getting the value from that particular key inside your first nested dictionary. If you change the keywords at x you get different different values back (regardless that it looks the same in your example; ttry with different values to see the result). Enjoy!
Try this code below:
string = "Eth1/1 vlan-1 typemode-eth status:access eth1/2 vlan-1 type-eth status:access eth1/3 vlan-1 type-eth status:access"
strList = string.split(" ")
indexPos = []
for data in range(0,len(strList)):
if strList[data].lower()[0:3] == 'eth':
print('Found',data)
indexPos.append(data)
dataDict = dict()
for i in range(0,len(indexPos)):
stringDict = dict()
stringDict['Speed'] = '10Gb'
if i is not len(indexPos)-1:
string = strList[indexPos[i]:indexPos[i+1]]
else:
string = strList[indexPos[i]:]
for i in range(0,len(string)):
if i is not 0:
if i is not 3:
valueSplit = string[i].split('-')
else:
print(i)
valueSplit = string[i].split(':')
stringDict[valueSplit[0]] = valueSplit[1]
dataDict[string[0]] = stringDict
I have written this code according the pattern in code. Please let me know if it work for you.
I just want to create a menu on the plot where I'm able to change the z-value in data only. I tried looking at other examples on here: https://plot.ly/python/dropdowns/#restyle-dropdown but it was hard since the examples were not exactly similar to my plot.
import plotly
import plotly.plotly as py
import plotly.graph_objs as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv')
data = [go.Choropleth(
locations = df['CODE'],
z = df['GDP (BILLIONS)'],
text = df['COUNTRY'],
colorscale = [
[0, "rgb(5, 10, 172)"],
[0.35, "rgb(40, 60, 190)"],
[0.5, "rgb(70, 100, 245)"],
[0.6, "rgb(90, 120, 245)"],
[0.7, "rgb(106, 137, 247)"],
[1, "rgb(220, 220, 220)"]
],
autocolorscale = False,
reversescale = True,
marker = go.choropleth.Marker(
line = go.choropleth.marker.Line(
color = 'rgb(180,180,180)',
width = 0.5
)),
colorbar = go.choropleth.ColorBar(
tickprefix = '$',
title = 'GDP<br>Billions US$'),
)]
layout = go.Layout(
title = go.layout.Title(
text = '2014 Global GDP'
),
geo = go.layout.Geo(
showframe = False,
showcoastlines = False,
projection = go.layout.geo.Projection(
type = 'equirectangular'
)
),
annotations = [go.layout.Annotation(
x = 0.55,
y = 0.1,
xref = 'paper',
yref = 'paper',
text = 'Source: <a href="https://www.cia.gov/library/publications/the-world-factbook/fields/2195.html">\
CIA World Factbook</a>',
showarrow = False
)]
)
fig = go.Figure(data = data, layout = layout)
py.iplot(fig, filename = 'd3-world-map')
It's been a while since this was asked, but I figured it was still worth answering. I can't speak to how this might have changed since it was asked in 2019, but this works today.
First, I'll provide the code I used to create the new z values and the dropdown menu, then I'll provide all of the code I used to create these graphs in one chunk (easier to cut and paste...and all that).
This is the data I used for the alternate data in the z field.
import plotly.graph_objects as go
import pandas as pd
import random
z2 = df['GDP (BILLIONS)'] * .667 + 12
random.seed(21)
random.shuffle(z2)
df['z2'] = z2 # example as another column in df
print(df.head()) # validate as expected
z3 = df['GDP (BILLIONS)'] * .2 + 1000
random.seed(231)
random.shuffle(z3) # example as a series outside of df
z4 = df['GDP (BILLIONS)']**(1/3) * df['GDP (BILLIONS)']**(1/2)
random.seed(23)
random.shuffle(z4)
z4 = z4.tolist() # example as a basic Python list
To add buttons to change z, you'll add updatemenus to your layout. Each dict() is a separate dropdown option. At a minimum, each button requires a method, a label, and args. These represent what is changing (method for data, layout, or both), what it's called in the dropdown (label), and the new information (the new z in this example).
args for changes to data (where the method is either restyle or update) can also include the trace the change applies to. So if you had a bar chart and a line graph together, you may have a button that only changes the bar graph.
Using the same structure you have:
updatemenus = [go.layout.Updatemenu(
x = 1, xanchor = 'right', y = 1.15, type = "dropdown",
pad = {'t': 5, 'r': 20, 'b': 5, 'l': 30}, # around all buttons (not indiv buttons)
buttons = list([
dict(
args = [{'z': [df['GDP (BILLIONS)']]}], # original data; nest data in []
label = 'Return to the Original z',
method = 'restyle' # restyle is for trace updates
),
dict(
args = [{'z': [df['z2']]}], # nest data in []
label = 'A different z',
method = 'restyle'
),
dict(
args = [{'z': [z3]}], # nest data in []
label = 'How about this z?',
method = 'restyle'
),
dict(
args = [{'z': [z4]}], # nest data in []
label = 'Last option for z',
method = 'restyle'
)])
)]
All code used to create this graph in one chunk (includes code shown above).
import plotly.graph_objs as go
import pandas as pd
import ssl
import random
# to collect data without an error
ssl._create_default_https_context = ssl._create_unverified_context
# data used in plot
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv')
# z values used in buttons
z2 = df['GDP (BILLIONS)'] * .667 + 12
random.seed(21)
random.shuffle(z2)
df['z2'] = z2 # example as another column in the data frame
print(df.head()) # validate as expected
z3 = df['GDP (BILLIONS)'] * .2 + 1000
random.seed(231)
random.shuffle(z3) # example as a series outside of the data frame
z4 = df['GDP (BILLIONS)']**(1/3) * df['GDP (BILLIONS)']**(1/2)
random.seed(23)
random.shuffle(z4)
z4 = z4.tolist() # example as a basic Python list
data = [go.Choropleth(
locations = df['CODE'], z = df['GDP (BILLIONS)'], text = df['COUNTRY'],
colorscale = [
[0, "rgb(5, 10, 172)"],
[0.35, "rgb(40, 60, 190)"],
[0.5, "rgb(70, 100, 245)"],
[0.6, "rgb(90, 120, 245)"],
[0.7, "rgb(106, 137, 247)"],
[1, "rgb(220, 220, 220)"]],
reversescale = True,
marker = go.choropleth.Marker(
line = go.choropleth.marker.Line(
color = 'rgb(180,180,180)', width = 0.5)),
colorbar = go.choropleth.ColorBar(
tickprefix = '$',
title = 'GDP<br>Billions US$',
len = .6) # I added this for aesthetics
)]
layout = go.Layout(
title = go.layout.Title(text = '2014 Global GDP'),
geo = go.layout.Geo(
showframe = False, showcoastlines = False,
projection = go.layout.geo.Projection(
type = 'equirectangular')
),
annotations = [go.layout.Annotation(
x = 0.55, y = 0.1, xref = 'paper', yref = 'paper',
text = 'Source: <a href="https://www.cia.gov/library/publications/the-world-factbook/fields/2195.html">\
CIA World Factbook</a>',
showarrow = False
)],
updatemenus = [go.layout.Updatemenu(
x = 1, xanchor = 'right', y = 1.15, type = "dropdown",
pad = {'t': 5, 'r': 20, 'b': 5, 'l': 30},
buttons = list([
dict(
args = [{'z': [df['GDP (BILLIONS)']]}], # original data; nest data in []
label = 'Return to the Original z',
method = 'restyle' # restyle is for trace updates only
),
dict(
args = [{'z': [df['z2']]}], # nest data in []
label = 'A different z',
method = 'restyle'
),
dict(
args = [{'z': [z3]}], # nest data in []
label = 'How about this z?',
method = 'restyle'
),
dict(
args = [{'z': [z4]}], # nest data in []
label = 'Last option for z',
method = 'restyle'
)])
)]
)
fig = go.Figure(data = data, layout = layout)
fig.show()
How do I create a dictionary from below lists, len(keys_list) = 12, len(values_list) = 24.
keys_list = ['Al','Bb','Ch','Da','Ev','Fr','Gi','Ht','Ia','Jh','Kd','Ly']
values_list = [i for i in 'VRCGVVRVCGGCCGVRGCVCGCGV']
So my output will be ['Al':'VR' or ('V','R') or ['V','R']......] either way is fine. I tried a few variations of zip(); and reached this post where they used zip_longest.
import itertools
for i in itertools.zip_longest(keys_list,values_list):
print (i)
I prefer not having to import a module.
keys_list = ['Al','Bb','Ch','Da','Ev','Fr','Gi','Ht','Ia','Jh','Kd','Ly']
values_list = [i for i in 'VRCGVVRVCGGCCGVRGCVCGCGV']
grouped_values = [values_list[i] + values_list[i+1] for i in range(len(values_list) - 1)]
d = {k :v for k,v in zip(keys_list, grouped_values)}
print(d)
output
{'Al': 'VR', 'Bb': 'RC', 'Ch': 'CG', 'Da': 'GV', 'Ev': 'VV', 'Fr': 'VR', 'Gi': 'RV', 'Ht': 'VC', 'Ia': 'CG', 'Jh': 'GG', 'Kd': 'GC', 'Ly': 'CC'}
Currently written this code that produces a bar chart but would like to add a threshold line. Could anyone help me please?
def make_bar_chart(data):
"""Takes a list of dicts with a time and price"""
# Times
chart_x = []
# Prices
chart_y = []
# Create the relevant arrays
for item in data:
chart_x.append(item["time"])
chart_y.append(item["price"])
# Make the chart
the_graph = Bar(x = chart_x, y = chart_y , name = "Stocks")
graph_data = Data([the_graph])
the_layout = Layout(title = "Stocks", xaxis = dict(title = "Time"), yaxis = dict(title = "Price"))
the_figure = Figure(data = graph_data, layout = the_layout)
plotly.offline.plot(the_figure, filename = "stocks.html")
Try something like this. In plotly it seems that lines are provided via shapes.
the_layout = Layout(title = "Stocks",
xaxis = dict(title = "Time"),
yaxis = dict(title = "Price"),
shapes=[
{
'type': 'line',
'xref': 'paper',
'x0': 0,
'y0': 100, # use absolute value or variable here
'x1': 1,
'y1': 100, # ditto
'line': {
'color': 'rgb(50, 171, 96)',
'width': 1,
'dash': 'dash',
},
},
],
)
I haven't tested this as you haven't provided sample data. Well done for supplying code on your first question, but on Stack Overflow it's best to provide a completely self-contained example that people can copy and run 'as is.'