openpyxl: How to get multiple auto-filters on a single sheet - openpyxl

How can I get multiple filters on a single sheet?
A single filter is easy:
worksheet.auto_filter.ref = "A1:D4"
I can't figure out how to do multiple filters. I tried a few things like:
worksheet.auto_filter.ref = "A1:D4,A6:D9"
worksheet.auto_filter.ref = "A1:D4;A6:D9"
but noting works.
Thanks,
Ryan

The specification says that there may be only a single auto-filter per worksheet.
As long as you're happy with working with a development version you might want to look at the 2.4 development branch which has much improved filtering and sort support. I don't use filters much myself so it could use some testing and the feedback would be very helpful.
The API has changed a bit and the best documentation is in the tests:
af = AutoFilter('A1:F1')
af.add_filter_column(5, ["0"], blank=True)
ws.auto_filter = af

Found out I can use tables to implement the sort/filter functionality. And you can have multiple tables in a single sheet. Unfortunately I can't find a way to do this in openpyxl but XlsxWriter can do this very easily.
worksheet1.add_table('A1:C4')
worksheet1.add_table('F8:H15')

Related

Why the output of Nilearn's fetch ABIDE dataset is empty?

I want to diagonse autism and one of the best autism diagnosis datasets is ABIDE (Autism Brain Imaging Data Exchange). My final goal in this part is to have a connectivity matrix which I can use for the rest of my research. At this moment I am trying to download ABIDE dataset using Nilearn library. I use the code below as mentioned in Nilearn's documentry, but unfortunately I get an empty list from dataset.func_preproc. I don't know the reason, because it works fine for other datasets of Nilearn which I tested.
dataset = nilearn.datasets.fetch_abide_pcp(derivatives=['func_preproc', 'func_mean'])
print(dataset['func_preproc'])
and the output is:
[]
as you see , dataset['func_preproc'] is an empty list.
Does anyone have any idea about this?

Simple conditional text formatting with openpyxl by text

I am using openpyxl 3.0.3 and python 3.7.3. I don't know what version of Excel I'm using since it does not seem to say anywhere. It's Office 365.
What I want to do is simple: if the cell value is "fail", make the cell one color, if "pass" another, etc. But everything I try seems to run just fine, but when I try to open the workbook with Excel, it gets the same result: Excel saying "We found a problem with some content" and offering to repair the workbook. When I let it repair, the formatting is gone. I've tried all of the following, taken from various SO answers and other examples:
cellref = 'B2'
red_font = Font(size=14, bold=True, color='ffffff')
red_fill = PatternFill(start_color='ffcccc', end_color='ffcccc', fill_type='solid')
ws2.conditional_formatting.add(cellref, CellIsRule(operator='equal', formula=['fail'], fill=red_fill, font=red_font))
ws2.conditional_formatting.add(cellref, CellIsRule(operator='containsText', formula=['fail'], fill=red_fill, font=red_font))
ws2.conditional_formatting.add(cellref, CellIsRule(operator='lessThan', formula=['0'], fill=red_fill, font=red_font))
ws2.conditional_formatting.add(cellref, FormulaRule(formula=[f'NOT(ISERROR(SEARCH("fail",{cellref})))'], stopIfTrue=True, fill=red_fill))
All get the identical bad result. I have read the documentation and examples as well as every StackOverflow answer I can find on the subject. This seems like such a simple, basic usage of the package.
I believe it has to do with the combination of options you're choosing. It's actually easier (in my opinion) to declare a Rule and then assign that a type. Your second two rules were good. Compiled fine for me. The first two had the issue. I replaced them with a Rule of 'containsText' type.
Here's what I was able to come up with based on the example you provided:
cellref = 'B1:B6' #adjusted to show more cells
red_font = Font(size=14, bold=True, color='ffffff')
red_fill = PatternFill(start_color='ffcccc', end_color='ffcccc', fill_type='solid')
ws2.conditional_formatting.add(cellref, Rule(type='containsText', operator='containsText', formula=['fail'], dxf = DifferentialStyle(fill=red_fill, font=red_font)))
ws2.conditional_formatting.add(cellref, CellIsRule(operator='lessThan', formula=['0'], fill=red_fill, font=red_font))
ws2.conditional_formatting.add(cellref, FormulaRule(formula=[f'NOT(ISERROR(SEARCH("fail",{cellref})))'], stopIfTrue=True, fill=red_fill))
Results
I had trouble with the text search condition despite #APhillips helpful answer.
The best thing I got to work was:
from openpyxl import styles, formatting
cellref = 'B1:B6' #adjusted to show more cells
red_fill = styles.PatternFill(start_color='ffcccc', end_color='ffcccc', fill_type='solid')
rule = formatting.Rule(type='expression')
rule.formula = [f'ISNUMBER(SEARCH("fail", {cellref}))']
rule.dxf = styles.differential.DifferentialStyle(fill=red_fill)
sheet_object.conditional_formatting.add(cellref, rule)

zipline: Runtime figuring out what assets/symbols are provided by a bundle?

Apologies if this has an obvious solution, but I find the API documentation of zipline quite lacking with lots of holes.
Either in the initialize(context) function or the handle_data(context, data) function, is there an easy way to get a list of all the symbols in the asset universe?
E.g. if I have a custom bundle made of a bunch of tickers from yahoo, I can't seem to find something as easy as context.get_all_assets() or so. It seems I always have to manually provide a list of symbols so that I can set, e.g. context.assets = symbols('AAPL', 'SNAP', 'FB').
Take a look at this. I found this by using pdb to go through the logic.
def initialize(context):
context.i = 0
assets = context.asset_finder.sids #something like this
assert len(assets) >= 1
context.asset = context.sid(assets[0])

Use custom function to populate gSpreadsheet cell based on a XML/JSON response

Ok, this one has become a little tricky for me and I really need some assistance to work through it.
Problem
I have a GSpreadsheet which has a list of data, in this case Twitter usernames. Using the API of a service provider (in this case the Klout API), I would like to retrieve information about that user to populate a cell within a spreadsheet.
Based on what I can work out so far, I would need to write a custom function to do this but I have no idea where to start, how I might construct it, or if there are any examples of doing this.
Scenario
The Klout API can return either an XML or JSON response (see http://developer.klout.com/docs/read/api/API), based on the string passed. For example, the URL:
http://api.klout.com/1/users/show.xml?key=SECRET&users=thewinchesterau
would return the following XML response:
<users>
<user>
<twitter_id>17439480</twitter_id>
<twitter_screen_name>thewinchesterau</twitter_screen_name>
<score>
<kscore>56.63</kscore>
<slope>0</slope>
<description>creates content that is spread throughout their network and drives discussions.</description>
<kclass_id>10</kclass_id>
<kclass>Socializer</kclass>
<kclass_description>You are the hub of social scenes and people count on you to find out what's happening. You are quick to connect people and readily share your social savvy. Your followers appreciate your network and generosity.</kclass_description>
<kscore_description>thewinchesterau has a low level ofinfluence.</kscore_description>
<network_score>58.06</network_score>
<amplification_score>29.16</amplification_score>
<true_reach>90</true_reach>
<delta_1day>0.3</delta_1day>
<delta_5day>0.5</delta_5day>
</score>
</user>
</users>
Based on this response, I would like to be able to populate different cells with the values returned within the XML (or JSON if easier) packet.
So, for example, I would have a spreadsheet like the following which would have custom functions to go out and retrieve the value of the relevant XML element response to populate the cell:
Cell A B C D E
1 Username kscore Network score Amplification score True reach
2 thewinchester =kscore(A2) =nscore(A2) =ascore(A2) =tscore(A2)
Questions
Are there any gSpreadsheet examples you know of that use an API to pull data in from an external source?
How would one write a custom function to fetch the result from the API and populate a cell with a result of a specific element?
Any information, examples or helpers you have are greatly appreciated.
You want the importXML function, documented here. The formula you want will look something like this:
=importXML("http://api.klout.com/1/users/show.xml?key=SECRET&users=" + A1, "//users/user/score/kscore")
You could write a custom script with Google AppScript, but there's a simple solution to this similar to what Nick Johnson posted. I've tested this against the score function, but it could be easily adapted to the show endpoint with different XPath.
=importXML("http://api.klout.com/1/klout.xml?users="&A1&"&key=YOUR_API_KEY", "//users/user/kscore")
This presumes your Twitter IDs are in the A column.
Note, Google Docs limits the number of such importXML functions to 50 per spreadsheet. You could concatenate groups of 5 userids for each importXML call, effectively putting your limit to 250 a sheet.
This could also be adapted to a similar call in Excel that doesn't have that limit. Keep in mind the Klout ToS, though, using proper attribution and rate limits.

How to display two series via Google Chart API?

I can't get the two series of numbers to scale together.
Here is sample code that you can paste into...
http://code.google.com/intl/en/apis/chart/docs/chart_playground.html
cht=lxy
chs=400x300
chd=t:20,30,40|1,4,2|24,34,44|3,7,1
chds=20,40,1,4,24,44,1,7
chxr=0,20,54,2|1,0,7,1
chxt=x,y
chxs=0,ff0000,12,0,lt
1,0000ff,10,1,lt
chco=FF0000,00FF00
chdl=Apples
Oranges
chtt=Some+Values
chts=0000ff,24
Translated:
chd=t:s,e,r,i,e,s,1|s,e,r,i,e,s,2|...ors:series1,series2,...ore:series1,series2,...
chds=<series_1_min>,<series_1_max>,...
chxr=<axis_index>,<start_val>,<end_val>,<step>|...
The three varying parameters in question are:
chd=t:20,30,40|1,4,2|24,34,44|3,7,1
chds=20,40,1,4,24,44,1,7
chxr=0,20,54,2|1,0,7,1
Can anyone get this simple example working?
The chart supports multiple series but for some reason I can't scale it so that the values are displayed within scale.
Any help appreciated,
Chris
After some practice I think I needed to make the chds values the same for both sets of data. I need to play with it more but I thought I would post a working example for posterity.
cht=lxy
chs=400x300
chd=t:20,30,40|1,4,2|24,34,44,48|3,7,1,2
chds=10,50,0,10,10,50,0,10
chxr=0,10,50|1,0,10,1
chxt=x,y
chxs=0,ff0000,12,0,lt
1,0000ff,10,1,lt
chco=FF0000,00FF00
chdl=Apples
Oranges
chtt=Some+Values
chts=0000ff,24
chm=o,0000FF,0,-1,5,0|o,ff0000,1,-1,5,0
chg=10,10
Scaling can be tricky to get right.
Try using chds='a' for automatic scaling at first.