does anybody have any idea why this code on run says "AttributeError: 'dict' object has no attribute 'append'". And also, how to make these tests pass? I'm trying to help a friend but we both are pretty new to Python
def complete_with_default(dictionary, keys, default_value):
"""If `dictionary` is missing a key from `keys`, the function
adds the key to `dictionary` with a default value.
Changes the dictionary in-place and returns `None`.
"""
for k in keys:
if k in dictionary:
dictionary.append(default_value)
d1 = {'a': 1, 'b' : 2}
ks1 = ['c', 'd']
def_val1 = None
d2 = {'a': 1, 'b' : 2}
ks2 = ['b', 'c']
def_val2 = None
d3 = {'a': 1, 'b' : 2}
ks3 = ['a', 'b', 'c']
def_val3 = 321
d4 = {'a': 1, 'b' : 2}
ks4 = []
def_val4 = None
complete_with_default(d1, ks1, def_val1)
complete_with_default(d2, ks2, def_val2)
complete_with_default(d3, ks3, def_val3)
complete_with_default(d4, ks4, def_val4)
def run_test(obtained, expected, number):
if len(obtained) != len(expected):
print("Test ", number, " failed!")
print(obtained)
return
if obtained != expected:
print("Test ", number, " failed!")
print(obtained)
return
print("Test ", number, " succeeded!")
run_test(d1, {'a': 1, 'b' : 2, 'c': None, 'd': None}, 1)
run_test(d2, {'a': 1, 'b' : 2, 'c': None}, 2)
run_test(d3, {'a': 1, 'b' : 2, 'c': 321}, 3)
run_test(d4, {'a': 1, 'b' : 2}, 4)
Looks like you're looking to use the subscript ([]) operator:
dictionary[key] = default_value
Related
So I want to draw directory structures as tree graphs. I'm using NetworkLayout.jl. I'm stuck on Step 1, but I can do Step 2 and Step 3.
Build a list of links between files and folders, to produce something like this (hand-made) one:
links = Pair[
"/" => "System",
"/" => "Library",
"/" => "Users",
"System" => "sys1",
"System" => "sys2",
"System" => "sys3",
"Library" => "lib1",
"Library" => "lib2",
"Library" => "lib3",
"Users" => "u1",
"Users" => "u2",
"Users" => "u3",
"Users" => "u4",
"Users" => "u5",
"u5" => "MyFolder"]
Create an adjacency list. This is easy enough if all the links are unique (also handmade):
adjlist = [
[2, 3, 4],
[5, 6, 7],
[8, 9, 10],
[],
[11],
[],
[],
[11, 12, 13, 14],
[],
[],
[15],
[],
[],
[],
[]]
Make a layout. This is the easy bit, because NetworkLayout.jl does it all for you:
using NetworkLayout
NetworkLayout.Buchheim.layout(adjlist)
...>
GeometryTypes.Point{2,Float64}[[0.0, -0.0], [-2.0, -2.0], [1.0, -2.0],
[2.0, -2.0], [-3.0, -4.0], [-2.0, -4.0], [-1.0, -4.0], [0.0, -4.0],
[1.0, -4.0], [2.0, -4.0], [-1.5, -6.0], [-0.5, -6.0], [0.5, -6.0],
[1.5, -6.0], [-1.5, -8.0]]
So my question is, in Step 1, how to build the initial list of links between files. Some files may have identical names?
# get links with full path
function read_sub_dirs(path::AbstractString)
try # avoid access issue
a = readdir(path)
return a[isdir.((path*"/").*a)]
catch
return String[]
end
end
function deepreaddir_raw(working_dir_path::AbstractString,search_depth::Int=2)
links = Array{Pair,1}()
previous_dirs = [working_dir_path]
for i in 1:search_depth
if length(previous_dirs) > 0
next_dirs = String[]
for each_dir in previous_dirs
if each_dir[end] == '/'
sub_dirs = each_dir.*read_sub_dirs(each_dir)
else
sub_dirs = (each_dir*"/").*read_sub_dirs(each_dir)
end
append!(links,each_dir.=>sub_dirs)
append!(next_dirs,sub_dirs)
end
deleteat!(previous_dirs,1:length(previous_dirs))
append!(previous_dirs,next_dirs)
else
break
end
end
return links
end
# generate list of links
function deepreaddir(working_dir_path::AbstractString,search_depth::Int=2)
links_raw = deepreaddir_raw(working_dir_path,2)
links = Pair[]
for each_p in links_raw
a = split(each_p[1],"/")[end]; b = split(each_p[2],"/")[end];
a == "" ? a = working_dir_path : nothing
push!(links,a=>b)
end
links
end
links = deepreaddir(".")
# construct relationships
tree_dic = Dict{String,Array}()
[tree_dic[x] = String[] for x in map(x->x[1],links)]
for p in links
push!(tree_dic[p[1]],p[2])
end
# "System" ==> 1
str2id_dic = Dict{String,Int64}()
[str2id_dic[links[i][2]] = i for i in 1:length(links)]
# loop through col2 of `links`, guess it's the output you want?
str_res = map(xx->haskey(tree_dic,xx) ? tree_dic[xx] : String[], map(x->x[2],links))
# to ids
res = [map(k->str2id_dic[k],x) for x in str_res]
julia> res = [map(k->str2id_dic[k],x) for x in str_res]
15-element Array{Array{T,1} where T,1}:
[4, 5, 6]
[7, 8, 9]
[10, 11, 12, 13, 14]
Any[]
Any[]
Any[]
Any[]
Any[]
Any[]
Any[]
Any[]
Any[]
Any[]
[15]
Any[]
I’m biased here, but why not use MetaGraphs.jl instead of rolling your own graph structure? Also, for files with the same name, a combination of file system ID and inode should be globally unique at a given point in time.
I would create the Metagraph and populate it with output from stat: https://docs.julialang.org/en/v1/base/file/#Base.stat
In order to avoid displaying empty graph axes when no information is available to plot, I replaced a dcc.Graph return object with a html.Div() which gets an Output callback of either [] or [dcc.Graph(...)].
Now, I'd like to enable other actions on the selectedData (if the Div has a child Graph). Previously I could do this like:
#app.callback(Output('something', 'children'),
[Input('graph', 'selectedData')])
def do_stuff(selectedData):
pass
Now that I've changed the layout item from a dcc.Graph(...) to a html.Div([dcc.Graph(...)]), I can't figure out how to access the selectedData:
#app.callback(Output('something', 'children'),
[Input('graph_div', 'children')])
def do_stuff(children):
if len(children) > 0:
graph = children[0]
# wheres the selectedData now?
Alternatively, it might be easier if there's a way to get the Input id directly to nested dcc.Graph's id? When I try this I get an error saying no components with this id exist in the app's layout.
For each component, it should be possible to register a callback in Dash,
Here is a simple example which replicates what you are trying to do,
import dash
import dash_core_components as dcc
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div(id="graph-div",
children=[
dcc.Graph(
id='graph',
figure={
'data': [
{
'x': [1, 2, 3, 4],
'y': [4, 1, 3, 5],
'text': ['a', 'b', 'c', 'd'],
'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
'name': 'Trace 1',
'mode': 'markers',
'marker': {'size': 12}
},
{
'x': [1, 2, 3, 4],
'y': [9, 4, 1, 4],
'text': ['w', 'x', 'y', 'z'],
'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
'name': 'Trace 2',
'mode': 'markers',
'marker': {'size': 12}
}
],
'layout': {
'clickmode': 'event+select'
}
}
),
]
),
html.Div(id="output")
])
#app.callback(Output('output', 'children'),
[Input('graph', 'selectedData')])
def do_stuff(selectedData):
print(selectedData)
if __name__ == '__main__':
app.run_server(debug=True)
If you can post a simple re-creatable code it will be easier to debug.
Update:
If you are dynamically trying to load the component you might face the mentioned issue,
https://community.plot.ly/t/dcc-tabs-filling-tabs-with-dynamic-content-how-to-organize-the-callbacks/6377/2
One easy way to solve it would be to set this app configuration,
app.config['suppress_callback_exceptions']=True
Here is the working example,
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
#
#https://stackoverflow.com/questions/57580240/access-selecteddata-from-html-div-children
#
graph_layout = dcc.Graph(
id='graph',
figure={
'data': [
{
'x': [1, 2, 3, 4],
'y': [4, 1, 3, 5],
'text': ['a', 'b', 'c', 'd'],
'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
'name': 'Trace 1',
'mode': 'markers',
'marker': {'size': 12}
},
{
'x': [1, 2, 3, 4],
'y': [9, 4, 1, 4],
'text': ['w', 'x', 'y', 'z'],
'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
'name': 'Trace 2',
'mode': 'markers',
'marker': {'size': 12}
}
],
'layout': {
'clickmode': 'event+select'
}
}
)
app = dash.Dash(__name__)
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Dropdown(id="toggle-graph",
options=[
{'label': 'on', 'value': 'on'},
{'label': 'off', 'value': 'off'},
],
value='on'
) ,
html.Div(id="graph-div",
children=[
]
),
html.Div(id="output")
])
#app.callback(Output('graph-div', 'children'),
[Input('toggle-graph', 'value')])
def do_stuff(value):
if(value == 'on'):
return graph_layout
else:
return []
#app.callback(Output('output', 'children'),
[Input('graph', 'selectedData')])
def do_stuff(selectedData):
print(selectedData)
if __name__ == '__main__':
app.run_server(debug=True)
Looks like what I needed was a way to toggle the graph display rather than conditionally returning the entire graph object:
#app.callback(Output('graph', 'style'), [Input('drop-down', 'value')])
def toggle_container(dropdown_value):
if something
return {'display': 'none'}
else:
return {'display': 'block'}
Good day:
would like to ask a simple question regarding my code on Python 3.6
I want to count all the characters that repeats itself
here is the sample of the code that i worked on:
name01 = input("1st Name: ")
ch_name01 = []
bl_char = False
i = 0
for ch in name01:
i = 0
for ich in ch_name01:
bl_char = False
if ich[i][0] == ch:
bl_char = True
#ch_name01[i][1] = ch_name01[i][1] + 1
#print(str(ch_name01[i][0]) + " - " + str(ch_name01[i][1]))
if not bl_char:
i = i + 1
if bl_char == False:
ch_name01.append([ch, 1])
print(ch_name01)
#print(ch_name01)
for example input "aabbccddef"
would like to return a = 2, b = 2, c = 2, d = 2
but it will return error message
"TypeError: 'int' object is not subscriptable"
on if ich[i][0] == ch:
Using a dictionary will make your life so much easier here.
name01 = input("1st Name: ")
ch_name01 = {} # New dictionary
for ch in name01: # For every char in the input string
if ch in ch_name01: # If that char already has an entry in the dictionary
ch_name01[ch] += 1 # increment that char's entry's integer value
else: # the char hasn't been added to the dictionary yet
ch_name01[ch] = 1 # add a new dictionary entry with an integer value of 1
print(ch_name01)
Supplying input of aabbccddef produces:
{'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 1, 'f': 1}
Edit:
I added code comments to explain what each line is doing
I am trying to map a result to an angular-chart but am confused on how to map my labels and map my data. My service returns an object that looks like this:
Object {0: 5, 4: 1, 9: 1, 14: 2}
Question
How do I map my labels to the 0, 4, 9, 14 so that I can use it to put into a bar graph and data like below:
angular.module("app", ["chart.js"]).controller("BarCtrl", function ($scope) {
$scope.labels = ['0', '4', '9', '14'];
$scope.data = [
[5, 1, 1, 2]
];
});
Question 2 -- instead of using the numbers can I type in names for the labels?
I resolved this by mapping the value to an array.
var array = $.map($scope.count, function (value, index) {
return [value];
});
console.log(array);
Then using array on my chart.
I have a list as below
def qresultList = [
[location: 'a', txs: 10],
[location: 'b', txs: 20],
[location: 'a', txs: 30]
]
I want to get distinct list of locations with sum of txs for same location.. so I am doing groupby on location like this:
def totalsByLocation1 = qresultList.groupBy{ it.location }.
collectEntries{ key, vals -> [key, vals*.txs.sum()] }
The above code is inside SummaryUtilsService/getWorldSummary function
I am getting the following error
No signature of method: java.util.LinkedHashMap.collectEntries() is applicable for argument types: (summary.SummaryUtilsService$_getWorldSummary_closure3) values: [summary.SummaryUtilsService$_getWorldSummary_closure3#2750e6c9]
Update: the actual result from the query is
def qresultList = [
['a', 10],
['b', 20],
['a', 30]
]
so Its a list of lists..
From earlier questions, I assume you're using Grails 1.3.7 or something
The pre-groovy 1.8.X way of doing this is:
def totalsByLocation1 = qresultList.groupBy{ it.location }.inject([:]) { map, val ->
map << [ (val.key): val.value*.txs.sum() ]
}
Edit
If your input list is:
def qresultList = [
['a', 10],
['b', 20],
['a', 30]
]
Then you will need something like:
qresultList.groupBy { it[ 0 ] }.collectEntries { k, v ->
[ (k): v*.getAt( 1 ).sum() ]
}
For a list of maps:
assert [[a:40], [b:20]] == qresultList.groupBy {it.location}.collect {[(it.key): it.value.sum{it.txs}]}
For a map:
def locationTransactionSums = [:]
qresultList.groupBy {it.location}.each {
locationTransactionSums.(it.key) = it.value.sum{it.txs}
}
assert [a:40, b:20] == locationTransactionSums