Google Sheets alternating colors via API - python

Using the sheets API with Python I'm attempting to format a sheet using alternating colors. In the UI this is found at Format > Alternating colors...
From what I've been able to find this is done via the API using banding. Unfortunately, I haven't been able to find a working example of how this is done. Below is the values dictionary I've constructed, color values aren't important at the moment, I'd just like it to colorize the sheet.
requests = {
'bandedRange': {
'bandedRangeId': 1,
'range': {
'sheetId': 0,
'startRowIndex': 0,
'endRowIndex': len(values),
'startColumnIndex': 0,
'endColumnIndex': 4,
},
'rowProperties': {
'headerColor': {
'red': 1,
'green': 0,
'blue': 1,
'alpha': 1,
},
'firstBandColor': {
'red': 1,
'green': 0,
'blue': 0,
'alpha': 0,
},
'secondBandColor': {
'red': 0,
'green': 1,
'blue': 0,
'alpha': 0,
}
},
},
'fields': '*',
}
body = {'requests': requests}
response = service.spreadsheets().batchUpdate(spreadsheetId=spreadsheet_id, body=body).execute()
This fails with the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/oauth2client/_helpers.py", line 133, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/googleapiclient/http.py", line 840, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://sheets.googleapis.com/v4/spreadsheets/$spreadsheet_id:batchUpdate?alt=json returned "Invalid JSON payload received. Unknown name "banded_range" at 'requests': Cannot find field.">
I'm fairly certain my issue is the fields value, but I can't find a valid example of what to use here. I get the same error if I omit the fields key entirely.

Per the reference docs for batchUpdate, requests takes an array of Request objects. Each Request must have exactly one field set, the available fields for banding being:
"updateBanding": {
object(UpdateBandingRequest)
},
"addBanding": {
object(AddBandingRequest)
},
"deleteBanding": {
object(DeleteBandingRequest)
},
There is no field bandedRange, which is what you're trying to set. That's what the error message (Unknown name "banded_range" at 'requests': Cannot find field.) is saying... though I have no idea why it translated bandedRange to snake_case.
Depending on if you want to add or update the banded range, you'd set either updateBanding with an UpdateBandingRequest object, or addBanding with an AddBandingRequest object.
By adding addBanding to your JSON format. As explained above you will end up creating the below JSON. Also, the key fields is optional.
{'addBanding': {
'bandedRange': {
'bandedRangeId': 1,
'range': {
'sheetId': 0,
'startRowIndex': 0,
'endRowIndex': len(values),
'startColumnIndex': 0,
'endColumnIndex': 4,
},
'rowProperties': {
'headerColor': {
'red': 1,
'green': 0,
'blue': 1,
'alpha': 1,
},
'firstBandColor': {
'red': 1,
'green': 0,
'blue': 0,
'alpha': 0,
},
'secondBandColor': {
'red': 0,
'green': 1,
'blue': 0,
'alpha': 0,
}
},
},
},
},

Related

python and Json - editing file

So, I want to change my info in json file from python, but I am having trouble.
my json file is just info that I want to edit later:
[
{
"codigo": 10,
"Nom_articulo": "jabon",
"valor": 2500,
"cantidad": 6,
"subtotal": 0,
"descuento": 0
},
{
"codigo": 20,
"Nom_articulo": "Crema",
"valor": 9800,
"cantidad": 4,
"subtotal": 0,
"descuento": 0
},
{
"codigo": 30,
"Nom_articulo": "Cepillo",
"valor": 6000,
"cantidad": 7,
"subtotal": 0,
"descuento": 0
},
{
"codigo": 40,
"Nom_articulo": "Servilletas",
"valor": 3000,
"cantidad": 2,
"subtotal": 0,
"descuento": 0
},
{
"codigo": 50,
"Nom_articulo": "Desodorante",
"valor": 5000,
"cantidad": 6,
"subtotal": 0,
"descuento": 0
}
]
I want to change the value of "subtotal" in all my dictionaries.
so basically what I did was:
for i in range(len(archivo_r)):
precio= archivo_r[i]["valor"]
cantidad=archivo_r[i]["cantidad"]
subtotal=precio*cantidad
print(archivo_r[i]["codigo"], " - " ,archivo_r[i]["Nom_articulo"], " = ", str(subtotal))
#almacenar mis subtotales en el archivo json
print("sbtotal" ,archivo_r[i]["subtotal"])
archivo_r[i]["subtotal"]=subtotal
#archivo_r[i]["subtotal"].append(subtotal)
#print(archivo_r)
write_json(**XXXXX**)
This part of the code:
archivo_r[i]["subtotal"]=subtotal does exactly what I need, but (and this could be very silly, but I am a little lost here) I do not know how to use that to re-write my json file. I mean, I have the function to write it.
def write_json(info, nombre_archivo="productos.json"):
with open(nombre_archivo, "w") as p:
json.dump(info, p)
I need to pass the information in write_json(**XXXXX**), but have been trying to storage my archivo_r[i]["subtotal"]=subtotal in a variable to pass it and other things, but nothing work. I know I am doing wrong but not sure how to solve it.
Once you're done processing the data, simply pass archivo_r to your write_json() function and you should be fine.
As an aside, you can iterate directly over the JSON objects like so:
for section in archivo_r:
precio = section["valor"]
...
You can then replace all instances of archivo_r[i] with section, or whatever you want to call the variable.

Bucketing for histogram in MongoDB

Syntax issue on line #25. Can someone please help me to spot the mistake not sure if the problem is in the code before this line.
File SyntaxError: invalid syntax, line 25
} #25
^
The line with the syntax is highlighted by #25. Thank you in advance :)
import pandas as pd
def length_vs_references(articles):
res = {"1-5" : 0, "6-10" : 0, "11-15" : 0, "16-20" : 0, "21-25" : 0, "25-30" : 0, ">30" :0}
n = {"1-5" : 0, "6-10" : 0, "11-15" : 0, "16-20" : 0, "21-25" : 0, "25-30" : 0, ">30" :0}
cursor = articles.aggregate([
{'$match': {'$and' : [{'references': {'$exists': False}
}, {'$ne':['$page_end', '']}, {'$ne':['$page_start', '']} ]}},
{'$project': {'len_refernces': {"$size": '$references'},
'pages': {'$subtract': [{"$toInt": 'page_end'},
{"$toInt" : 'page_start'}]}}},
{'$bucket' : {
'$groupBy': '$pages',
'boundaries': [ 0, 6, 11, 16, 21, 26, 31, 1000000],
'default': 'Other',
{
'output' : {"average": {"$avg" : '$len_references'}},
}
} #25
}
])
return cursor
print(length_vs_references(articles))
'default': 'Other',
{
'output' : {"average": {"$avg" : '$len_references'}},
}
That is the problem area. You have a sub-dictionary without a key name.
To illustrate the problem more simply, here is an equivalent dictionary:
mydict = {
'some_key': 5,
'other_key': 10,
'yet_another_key': 100,
3,
'final_key': 1000
}
The 3 is an error because it's just a value without a key name. Your code has a sub-dictionary instead of an integer, but it's the same kind of error.

How to get container stats details using python docker

I am trying to get the docker container stats inside my python code after running the container as shown below. I am referring to python docker SDk https://docker-py.readthedocs.io/en/stable/index.html to run and get the details of container.
container = docker_client.containers.run(image = image,entrypoint = entrypoint,detach=True,tty=False,volumes = {FILE_PATH+input_file:{'bind': '/src/input.txt', 'mode': 'rw'}})
container.wait()
data = container.stats(stream=False)
The stats which are getting doesn't have memory and few other details properly. Below are the stats details
{
'read': '0001-01-01T00:00:00Z',
'preread': '2020-04-21T10:07:54.773647854Z',
'pids_stats': {
},
'blkio_stats': {
'io_service_bytes_recursive': None,
'io_serviced_recursive': None,
'io_queue_recursive': None,
'io_service_time_recursive': None,
'io_wait_time_recursive': None,
'io_merged_recursive': None,
'io_time_recursive': None,
'sectors_recursive': None
},
'num_procs': 0,
'storage_stats': {
},
'cpu_stats': {
'cpu_usage': {
'total_usage': 0,
'usage_in_kernelmode': 0,
'usage_in_usermode': 0
},
'throttling_data': {
'periods': 0,
'throttled_periods': 0,
'throttled_time': 0
}
},
'precpu_stats': {
'cpu_usage': {
'total_usage': 208804435,
'percpu_usage': [
2260663,
0,
0,
7976886,
0,
2549616,
178168661,
1717192,
117608,
0,
1011534,
3305192,
0,
11372783,
0,
324300
],
'usage_in_kernelmode': 20000000,
'usage_in_usermode': 160000000
},
'system_cpu_usage': 98001601690000000,
'online_cpus': 16,
'throttling_data': {
'periods': 0,
'throttled_periods': 0,
'throttled_time': 0
}
},
'memory_stats': {
},
'name': '/quizzical_mcclintock',
'id': '4bb79d8468f2f91a91022b4a7086744a6b3cdefab2a98f7efa178c9aff7ed246'
}
How to get all the stats details properly using python docker SDK?
import os
os.system("docker stats $(docker ps -q) --no-stream")
if you want to get the stats of all the running container then the following command will help you. Otherwise you need to calculate the stats yourself from total used so can be tricky .

Navigating JSON in Python?

ANSWER: The square brackets inside data["data"]["items"] indicates a list of dictionaries. I had thought that the brackets indicated that all of those dictionaries were a list inside a list of one item (i.e. [[item1, item2]]) so I had to call a 0 index like so: data["data"]["items"][0]. That was incorrect, the [0] is unecessary, which I really should have known, but didn't realize.
I am using GAE, so you can think of the self.response.write statement as a print.
For some reason, although the user_xid prints correctly, the interpreter is giving me the error when I try to parse json_data["data"]["items"][0] in my for loop, it appears to be evaluating x as a string, because I am getting an error telling me that string indicies must be integers.
I didn't realize json_data["data"]["items"][0] would yield a string. I'm somewhat stymied. Would it have anything to do with using json_data["data"]["items"][0] as opposed to json_data["data"]["items"]?
I have also tried json.loads(json_data["data"]["items"][0]) to no avail. Any input is appreciated.
I have the following JSON, which I have broken out a bit to make it easier to read:
{"meta":
{"user_xid": "REDACTED", "message": "OK", "code": 200, "time": 1436273692},
"data":
{"items": [
{"time_completed": 1436193938, "xid": "4tLz2M3x8_E9mTPIQsQUdrj-83spikha", "title": "for 7h 40m", "time_created": 1436165067, "time_updated": 1436194828, "details":
{"body": 0, "sound": 14348, "tz": "America/Vancouver", "awakenings": 1, "light": 13258, "mind": 0, "asleep_time": 1436165760, "awake": 1265, "rem": 0, "duration": 28871, "smart_alarm_fire": 1436193000, "quality": 81, "awake_time": 1436193600, "sunrise": 1436184840, "sunset": 1436156340},
"date": 20150706, "shared": true, "sub_type": 0},
{"time_completed": 1436135400, "xid": "4tLz2M3x8_Hk71lnuSLbeq4ascwJg-J8", "title": "for 25m", "time_created": 1436133600, "time_updated": 1436135590, "details":
{"body": 0, "sound": 0, "tz": "America/Vancouver", "awakenings": 0, "light": 1500, "mind": 0, "asleep_time": 1436133600, "awake": 300, "rem": 0, "duration": 1800, "smart_alarm_fire": 0, "quality": 2, "awake_time": 1436134800, "sunrise": 0, "sunset": 0},
"date": 20150705, "shared": true, "sub_type": 2},
{"time_completed": 1436133497, "xid": "4tLz2M3x8_GIYf6G9_ZKH9xrKpuEzMjm", "title": "for 23m", "time_created": 1436131387, "time_updated": 1436135461, "details":
{"body": 0, "sound": 1391, "tz": "America/Vancouver", "awakenings": 0, "light": 0, "mind": 0, "asleep_time": 1436132100, "awake": 719, "rem": 0, "duration": 2110, "smart_alarm_fire": 1436133445, "quality": 4, "awake_time": 1436133300, "sunrise": 0, "sunset": 0},
"date": 20150705, "shared": true, "sub_type": 1},
{"time_completed": 1436117080, "xid": "4tLz2M3x8_EUZyqCoXYOJO7Hfe92eSqg", "title": "for 26m","time_created": 1436115061, "time_updated": 1436121619, "details":
{"body": 0, "sound": 480, "tz": "America/Vancouver", "awakenings": 0, "light": 1119, "mind": 0, "asleep_time": 1436115479, "awake": 420, "rem": 0, "duration": 2019, "smart_alarm_fire": 1436117069, "quality": 2, "awake_time": 1436116800, "sunrise": 1436098380, "sunset": 1436156280},
"date": 20150705, "shared": true, "sub_type": 1},
],
"links":
{"next": "REDACTED"},
"size": 10}
}
I am using the following in Python:
json_data = json.loads(user_data)
self.response.write('<br><br>x_id: ' + json_data["meta"]["user_xid"])
i = 0
for x in json_data["data"]["items"][0]:
duration = x['details']['duration']
date = x["date"]
self.response.write('<br><br>sleep number ' + str(i) + ' | duration: ' + str(duration) + ' | date: ' + str(date))
i += 1
I am using GAE, so you can think of the self.response.write statement as a print.
For some reason, although the user_xid prints correctly, the interpreter is giving me the error when I try to parse json_data["data"]["items"][0] in my for loop, it appears to be evaluating x as a string, because I am getting an error telling me that string indicies must be integers.
I didn't realize json_data["data"]["items"][0] would yield a string. I'm somewhat stymied. Would it have anything to do with using json_data["data"]["items"][0] as opposed to json_data["data"]["items"]?
I have also tried json.loads(json_data["data"]["items"][0]) to no avail. Any input is appreciated.
Thanks!
By doing some basic debugging and data examination you will find that the use of the [0] is incorrect
I quickly loaded that data and tried it
In [11]: for i in x['data']['items'][0]:
....: print i
....:
time_completed
xid
details
title
date
shared
sub_type
time_created
time_updated
And this is effectively what you got, but not what you expected.
So what is going on? If you you do the following
x['data']['items'][0]
Out[28]:
{'date': 20150706,
'details': {'asleep_time': 1436165760,
'awake': 1265,
'awake_time': 1436193600,
'awakenings': 1,
'body': 0,
'duration': 28871,
'light': 13258,
'mind': 0,
'quality': 81,
'rem': 0,
'smart_alarm_fire': 1436193000,
'sound': 14348,
'sunrise': 1436184840,
'sunset': 1436156340,
'tz': 'America/Vancouver'},
'shared': True,
'sub_type': 0,
'time_completed': 1436193938,
'time_created': 1436165067,
'time_updated': 1436194828,
'title': 'for 7h 40m',
'xid': '4tLz2M3x8_E9mTPIQsQUdrj-83spikha'}
The result is as you expect.
The answer is because you are trying to iterate over x['data']['items'][0]
When you iterate over a dictionary you will get the keys not the values by default. Hence you are getting the unexpected string.
Where as the following code will give you what you want.
In [30]: for i in x['data']['items']:
print i['details']['duration']
....:
28871
1800
2110
2019
This iterates over each item (a dictioanary) in the list of items.
I would suggest the downvote is due to a large posting of code, and no real evidence of basic debugging.

python api call using JSON data

Pretty new to Python API calls I Have the JSON data sample below
I can get data calling for example (swell.*) or (swell.minBreakingHeight) and it returns all the swell data no worries. So ok with a working request
I can't seem to narrow it down with success example swell.primary.height
Obviously the format above here is incorrect and keeps returning []
How do I get in that extra level?
[{
timestamp: 1366902000,
localTimestamp: 1366902000,
issueTimestamp: 1366848000,
fadedRating: 0,
solidRating: 0,
swell: {
minBreakingHeight: 1,
absMinBreakingHeight: 1.06,
maxBreakingHeight: 2,
absMaxBreakingHeight: 1.66,
unit: "ft",
components: {
combined: {
height: 1.1,
period: 14,
direction: 93.25,
compassDirection: "W"
},
primary: {
height: 1,
period: 7,
direction: 83.37,
compassDirection: "W"
},
Working with your data snippet:
data = [{
'timestamp': 1366902000,
'localTimestamp': 1366902000,
'issueTimestamp': 1366848000,
'fadedRating': 0,
'solidRating': 0,
'swell': {
'minBreakingHeight': 1,
'absMinBreakingHeight': 1.06,
'maxBreakingHeight': 2,
'absMaxBreakingHeight': 1.66,
'unit': "ft",
'components': {
'combined': {
'height': 1.1,
'period': 14,
'direction': 93.25,
'compassDirection': "W"
},
'primary': {
'height': 1,
'period': 7,
'direction': 83.37,
'compassDirection': "W"
}
}
}
}
]
In [54]: data[0]['timestamp']
Out[54]: 1366902000
In [55]: data[0]['swell']['components']['primary']['height']
Out[55]: 1
So using your dot notation, you should be calling:
swell.components.primary.height
For furhter insight on parsing json files refer to this other stackoverflow question

Categories

Resources