Rounding off floats in Python after json.dumps(), urlencode - python

This is a follow-up question to this and I looked at this one as well. My Python script collects data during every run and sends data to a URL. The URL should display data/values up to 2 decimal places. I modified my script to round off the values to 2 decimal places as shown below. After doing so, any and all print statements show that my script is rounding off to 2 decimal places. Even after urlencode, when I decode the params, it shows 2 decimal places. But at the URL, the values show up with all the decimal places - instead of 1.0, say, it shows 1.000342760436734 whereas the values should show as 1.00 and not more.
Here's the code in my script with the print outputs:
//The data that is collected by the script - a list of dicts.
y = [{'a': 80.0, 'b': 0.0786235, 'c': 10.0, 'd': 10.6742903}, {'a': 80.73246, 'b': 0.0, 'c':
10.780323, 'd': 10.0}, {'a': 80.7239, 'b': 0.7823640, 'c': 10.0, 'd': 10.0}, {'a':
80.7802313217234, 'b': 0.0, 'c': 10.0, 'd': 10.9762304}]
//The code that rounds off the decimal places to 2
class LessPrecise(float):
def __repr__(self):
return str(self)
def roundingVals_toTwoDeci(y):
for d in y:
for k, v in d.iteritems():
v = LessPrecise(round(v, 2))
print v
d[k] = v
//Json.dumps
roundingVals_toTwoDeci(y)
j = json.dumps(y)
print j
//print j gives
[{"a": 80.0, "b": 0.0, "c": 10.0, "d": 10.0}, {"a": 100.0, "b": 0.0, "c": 0.0, "d": 0.0}, {"a":
80.0, "b": 0.0, "c": 10.0, "d": 10.0}, {"a": 90.0, "b": 0.0, "c": 0.0, "d": 10.0}]
//urlencoding it
params = urllib.urlencode({'thekey': j})
//after decoding params, I get
thekey=[{"a": 80.0, "b": 0.0, "c": 10.0, "d": 10.0}, {"a": 100.0, "b": 0.0, "c": 0.0, "d":
0.0}, {"a": 80.0, "b": 0.0, "c": 10.0, "d": 10.0}, {"a": 90.0, "b": 0.0, "c": 0.0, "d": 10.0}]
//So far, so good. At the URL, however, instead of 10.0, it shows 10.000436783313897. I don't what's going on or how to fix it.
I should mention that I get the same float values at the URL even after I convert values into strings directly as in:
def roundingVals_toTwoDeci(y):
for d in y:
for k, v in d.iteritems():
d[k] = str(round(v, 2))
return
With this, print s=json.dumps() gives values like {"a": "10.0", "b": "3.1", etc.} but at the URL, values are 10.856473985798743.

Related

How to make multiindex dataframe from a nested dictionary keys and lists of values?

I have checked the advicse here: Nested dictionary to multiindex dataframe where dictionary keys are column labels
However, I couldn't get it to work in my problem.
I would like to change a dictionary into multiindexed dataframe, where 'a','b','c' are names of multiindexes, their values 12,0.8,1.8,bla1,bla2,bla3,bla4 are multiindexes and values from lists are assign to the multiindexes as in the picture of table below.
My dictionary:
dictionary ={
"{'a': 12.0, 'b': 0.8, 'c': ' bla1'}": [200, 0.0, '0.0'],
"{'a': 12.0, 'b': 0.8, 'c': ' bla2'}": [37, 44, '0.6'],
"{'a': 12.0, 'b': 1.8, 'c': ' bla3'}": [100, 2.0, '1.0'],
"{'a': 12.0, 'b': 1.8, 'c': ' bla4'}": [400, 3.0, '1.0']
}
The result DataFrame I would like to get:
The code which don't make multiindexes and set every values under each other in next row:
df_a = pd.DataFrame.from_dict(dictionary, orient="index").stack().to_frame()
df_b = pd.DataFrame(df_a[0].values.tolist(), index=df_a.index)
Use ast.literal_eval to convert each string into a dictionary and build the index from there:
import pandas as pd
from ast import literal_eval
dictionary ={
"{'a': 12.0, 'b': 0.8, 'c': ' bla1'}": [200, 0.0, '0.0'],
"{'a': 12.0, 'b': 0.8, 'c': ' bla2'}": [37, 44, '0.6'],
"{'a': 12.0, 'b': 1.8, 'c': ' bla3'}": [100, 2.0, '1.0'],
"{'a': 12.0, 'b': 1.8, 'c': ' bla4'}": [400, 3.0, '1.0']
}
keys, data = zip(*dictionary.items())
index = pd.MultiIndex.from_frame(pd.DataFrame([literal_eval(i) for i in keys]))
res = pd.DataFrame(data=list(data), index=index)
print(res)
Output
0 1 2
a b c
12.0 0.8 bla1 200 0.0 0.0
bla2 37 44.0 0.6
1.8 bla3 100 2.0 1.0
bla4 400 3.0 1.0

How to store all the outputs of loop in form of dictionary of dictionary in python?

I have created a for loop and what I want is that the end result of each iteration of the loop to be stored as a dictionary(tfdict). Now what I need is all the dicts to be combined in one dict get that final dict.
for i in range(0,len(sep)):
n=len(sep[i])
tfDict = dict.fromkeys(setwords,0)
for word in sep[i]:
tfDict[word]+=1
tfDict[word] = tfDict[word]/n
x=fin.values()
for word,val in tfDict.items():
for w,v in fin.items():
x = v
if(word==w):
tfDict[word]=val*x
print(tfDict)
here on print this inside the loop, I get the needed output
{'and': 0.0, 'document': 0.23783346831109634, 'first': 0.0, 'is': 0.16666666666666666, 'one': 0, 'second': 0.16666666666666666, 'the': 0.16666666666666666, 'third': 0, 'this': 0.16666666666666666}
{'and': 0.3193817886456925, 'document': 0.0, 'first': 0.0, 'is': 0.16666666666666666, 'one': 0.16666666666666666, 'second': 0, 'the': 0.16666666666666666, 'third': 0.16666666666666666, 'this': 0.16666666666666666}
{'and': 0.0, 'document': 0.24462871026284194, 'first': 0.3021651247531982, 'is': 0.2, 'one': 0, 'second': 0, 'the': 0.2, 'third': 0, 'this': 0.2}
Now, I want all of this outside the loop as well, in from of dict of dict or panda. Is there a way i can do this?

Finding The Biggest Key In A Python Dictionary

General:
I need help finding a way in python to get the max N items in a multi-dimensional python dictionary. For example:
things = {
"car": { "weight": 100 },
"apple": { "weight": 1 },
"spanner": { "weight": 10 }
}
In this case, I would want to find the 2 highest-weighted items in the dictionary, specifically the keys of these items. So in this case, it should return ["car", "spanner"]
Actual Problem:
Note: This is my first attempt at a genetic algorithm, so I might not be doing it correctly. At all.
As I am British, I am searching for the best cup of tea I can imagine, so I am writing a python program that generates 10 random cups of tea, then uses natural selection to find the top 5 in that ten and so on.
A cup of tea is modelled as a python dictionary, with 5 keys:
{
"brew_time": Some Number,
"milk": Some Number,
"sweeteners": Some Number,
"fitness": Some Number (This is what I'm interested in),
"name": Some randomly generated name (Doesn't really matter)
}
A cup of tea my program will spit out will look something like this:
{'brew_time': 2.0, 'milk': 0.5, 'sweeteners': 3.0, 'name': 'bold cup', 'fitness': 0}
It then generates 10 cups of tea, stored in the teas variable. This is an example of an output of that:
{0: {'brew_time': 2.0, 'milk': 0.4, 'sweeteners': 1.0, 'name': 'unafraid brew', 'fitness': 0}, 1: {'brew_time': 3.0, 'milk': 0.5, 'sweeteners': 3.0, 'name': 'fire-eating blend', 'fitness': 0}, 2: {'brew_time': 2.0, 'milk': 0.6, 'sweeteners': 2.0, 'name': 'fearless drink', 'fitness': 0}, 3: {'brew_time': 2.0, 'milk': 0.9, 'sweeteners': 3.0, 'name': 'fire-eating blend', 'fitness': 0}, 4: {'brew_time': 2.0, 'milk': 0.8, 'sweeteners': 2.0, 'name': 'fire-eating cuppa', 'fitness': 0}, 5: {'brew_time': 3.0, 'milk': 0.3, 'sweeteners': 1.0, 'name': 'fire-eating drink', 'fitness': 0}, 6: {'brew_time': 4.0, 'milk': 0.7, 'sweeteners': 2.0, 'name': 'dauntless medley', 'fitness': 0}, 7: {'brew_time': 3.0, 'milk': 0.3, 'sweeteners': 2.0, 'name': 'dauntless cuppa', 'fitness': 0}, 8: {'brew_time': 3.0, 'milk': 0.9, 'sweeteners': 2.0, 'name': 'epic drink', 'fitness': 0}, 9: {'brew_time': 2.0, 'milk': 0.4, 'sweeteners': 2.0, 'name': 'gusty drink', 'fitness': 0}}
I'm now trying to code a function called selection() that will remove the 5 least fit teas from the dictionary. (The fitness of a tea is set by me, using the rank_tea() function, which takes an array and sets all the teas fitnesses, which is a number between 0 - 1 that represents the quality of the tea)
This is what I've got so far, but it doesn't work:
def selection():
teaCopy = teas.copy()
fitnesses = []
for i in range(0, len(teaCopy)):
fitnesses.append(teas[i]["fitness"])
print(fitnesses)
max_fitnesses_indicies = sorted(range(len(fitnesses)), key=lambda x: fitnesses[x])
print(max_fitnesses_indicies)
len_array = []
print(len_array)
for i in range(0, len(teas)):
len_array.append(i)
to_be_del = list( set(max_fitnesses_indicies) - set(len_array) )
print(to_be_del)
This is the full code. Sorry for the length of the question, I just didn't want to miss anything.
Any help would be appreciated
You can simply use:
>>> sorted(things.keys(),key=lambda x:things[x]['weight'],reverse=True)
['car', 'spanner', 'apple']
To obtain a list of items sorted by their weight (here in reversed order such that the more heavy things are sorted first). So if you call:
>>> sorted(things.keys(),key=lambda x:things[x]['weight'],reverse=True)[:2]
['car', 'spanner']
you get the two heaviest. But this will run in O(n log n). In case the number of values k you wish to obtain is small (compared to the total number). You can use heapq:
from heapq import nlargest
result = nlargest(k,things.keys(),key=lambda x:things[x]['weight'])
which will - as far as I know - run in O(n log k) (k the numbers of items you want to pick).

finding probability of values in dictionary

I have a default dict which looks like this:
my_dict = default(dict, {"K": {"k": 2, "x": 1.0}, "S": {"_":1.0, "s":1}, "EH": {"e":1.0}})
The keys are phonemes, and values that are dictionaries themselves are graphemes which occur a certain amount of times, which are the respective numbers in the default dict.
The function should return another default dict containing the probabilities, which will look like this:
defaultdict(<class 'dict'>, {'EH': {'e': 1.0}, 'K': {'k': 0.6666666666666666, 'x': 0.3333333333333333}, 'S': {'_': 0.5, 's': 0.5}})
'e' remains the same, as 1.0/1 = 1.0. 'K' has values of 0.66666 and 0.33333 because 2/3 = 0.66666 and 1/3 = 0.3333333. 'S' has values of 0.5 and 0.5, because 1/2=0.5 for each of them. The probabilities in the return dict must always sum to one.
so far I have this:
from collections import defaultdict
my_dict = default(dict, {"K": {"k": 2, "x": 1.0}, "S": {"_":1.0, "s":1}, "EH": {"e":1.0}})
def dict_probability(my_dict):
return_dict = defaultdict(dict)
for char in my_dict.values():
For each of your subdictionnaries, you would like to divide each value by the sum of the subdictionnary values:
my_dict = {"K": {"k": 2, "x": 1.0}, "S": {"_":1.0, "s":1}, "EH": {"e":1.0}}
{k:{k1:v1/sum(v.values()) for k1,v1 in v.iteritems()} for k,v in my_dict.iteritems()}
{'EH': {'e': 1.0},
'K': {'k': 0.6666666666666666, 'x': 0.3333333333333333},
'S': {'_': 0.5, 's': 0.5}}
example_dict = {"A": 1, "B": 2, "C": 3}
prob_dict = {}
for k, v in test_dict.items():
prob_dict[k] = v / sum(example_dict.values())
print(prob_dict)
{'A': 0.16666666666666666, 'B': 0.3333333333333333, 'C': 0.5}

Finding the mean of nodes in an undirected graph

I have written a program which gives me the following outputs for five nodes which is the shortest path from each node to different nodes :
G1= {'D': 3.0, 'E': 4.0, 'B': 1.0, 'C': 5.0, 'A': 0}
G1={'D': 2.0, 'E': 3.0, 'B': 0, 'C': 4.0, 'A': 1.0}
G1={'D': 2.0, 'E': 3.0, 'B': 4.0, 'C': 0, 'A': 5.0}
G1={'D': 0, 'E': 1.0, 'B': 2.0, 'C': 2.0, 'A': 3.0}
G1={'D': 1.0, 'E': 0, 'B': 3.0, 'C': 3.0, 'A': 4.0}
I am trying to find the mean of all of the nodes from the above output. I tried the following code :
for s in G:
G1=ShortestPaths(G,s)#this gives the output i mentioned above
mean= sum([G1[s] for s in G1])/(len(G1)-1)# this is where i am not getting result
return float(mean)
But it is giving mean of only the last line.I need sum of all the values in the dictionary(sum of 25 values) and divide by 20(since there is a zero in every line of my output.I should not consider that). Can anyone help me with this with a simple code?? I am not suppose to .items and other built-in functions.
Calculate the mean at the end, after the loop:
total = 0.0
count = 0.0
for s in G:
G1=ShortestPaths(G,s)
total += sum([G1[s] for s in G1])
count += (len(G1)-1)
return float(total / count) if count else None

Categories