WoW Lua - How to get the spell rank in 1.13 (Classic) - lua

I'm trying to get the rank of a spell, but GetSpellInfo does not return the second parameter (rank). If I run:
/dump GetSpellInfo( 5782 )
I get
[1]="Fear"
[3]="136813"
[4]="1500"
[5]="0"
[6]="20"
[7]="5782"
Each combination of spell and rank seem to have a unique ID:
5185 = Healing Touch (rank1)
5186 = Healing Touch (rank2)
5187 = Healing Touch (rank3)
5188 = Healing Touch (rank4)
5189 = Healing Touch (rank5)
6778 = Healing Touch (rank6)
8903 = Healing Touch (rank7)
9758 = Healing Touch (rank8)
How do I get the spell rank given an ID?
The mod I'm working on (LunarSphere) gets a drag from the spellbook.
I'm using that with a button SetAttribute:
self:SetAttribute("*spell-S01", "Healing Touch")
For the highest rank or
self:SetAttribute("*spell-S01", "Healing Touch(rank 3)")
For a specific rank
Thanks!

They are just different spells. It makes it awkward for certain things where we tend to see them as different ranks of the same spell.
You will likely have to make a DB of the ranked spells and do a lookup in your own tables as part of the overall service provided by your addon.
https://wowwiki.fandom.com/wiki/API_GetSpellInfo
rank (string) - The rank line from the tooltip of the spell, e.g. "Rank 2". Returns some other classification (like "Summon" for a summoning
spell) or an empty string if there is no rank.
So that "rank" is for just displaying the extra line in the UI, if they wanted to add one for that spell.
Like many things in the UI API, they are just there to support the UI and mostly pragmatic and just what's necessary to display or do WoW UI functionality.
local subTextOrRank = GetSpellSubtext(spellId)
This gets the display line for rank which newer engines may not return with spell info. 'GetSpellSubtext' may or may not return the rank text if the spell is cached on the client or not, or maybe you end up seeing it works every time.
I have used this spell list for quick reference in the past:
http://kyle.13th-floor.org/wow/spells/spells_2_4_0.txt
For answering many questions about the data the client has available statically:
https://wow.tools/dbc/
Here is an example of the client SpellName table from a current version of WoW Classic:
https://wow.tools/dbc/?dbc=spellname&build=1.13.3.32836#search=&page=1
Here is the Spell table from the same WoW Classic version:
https://wow.tools/dbc/?dbc=spell&build=1.13.3.32836#search=&page=1
ID, NameSubtext_lang, Description_lang, AuraDescription_lang
1
3
4
5, , Instantly Kills the target. I hope you feel good about yourself now.....
7
10, Rank 1, Ice shards pelt the target area doing $o1 Frost damage over $d.
11
Here you can see that they literally made a table of what the UI needed for display and its no more complicated or deep than that.
And if you read down the list can see or imagine it's basically done by hand, and thus can have mistakes or may have text that helps the rank description field but breaks the consistency. This is important to note that if you are going to rely on table string fields for programmatic purposes where you will need to be aware of and add exceptions to your test for rank.
You could attempt to roll through the spell list on load and build a rank list on the fly, but be aware that there are 21,000 spells in that table. If you are only worried about player spells you could make a mini pre-built list stored as a table for your own addon, and it would be a table only in the hundreds. You could have the base English name and a min and max field for rank.
I think 'GetSpellSubtext' in a loop to spit out a Lua table on your local client, in combination with the tables and rolling a small DB may break the log jam for you.

Related

How to column sum in Airtable like excel?

I am designing airtable.
I met some issue.
I need to column total sum like excel.
For example:
Column1 Sum(Column1)
1 1
2 3
4 7
6 13
Like this. What is solution?
Thank you.
Airtable is not a spreadsheet but a relational database, the behavior you're looking for isn't straightforward to reproduce because it's not meant to work like rows matter and aren't anything but a temporary sort - they don't, so they're not.
I know you were probably hoping for a better answer than another question, but I simply have to ask - why do you need to do this inside Airtable? Why not just use one of dozens readily available and entirely free spreadsheet/table solutions?
Generally speaking and especially if you don't need to manipulate that data afterward (a big if), Airtable already does the calculation you want on the fly and has it stored as part of its metadata.
The row-by-row addition would be doable using a combination of one autonumber field, a linked record (to another table actually polling for values) and a rollup returning data. I've done this back in the day once or twiCe and it was always an overengineered mess, even if I only had to deal with small integers like from your example.
There's Google Drive sync beta ongoing at Airtable right now. Just get that and do the calculations you need elsewhere?
The alternative is the Scripting app, but that might prove crippling in terms of how it could affect your automations quota. And recalculating fields by "hand" is... not sophisticated, to put it mildly.
But hey, don't take my word for it; Curiosity and nostalgia got the better of me so I gave this futile effort another go on your behalf, here's my best take at such an overengineered mess of a field-wide sum function that's wildly annoying to use but at least doesn't take all day to update records, even if presented with hundreds or thousands of inputs.
So, yeah... right tool for the job and all that: this ain't it, chief, but be my guest. You can clone the base from the Universe and everything will be ready for testing, just keep creating new fields or deleting the exiting few ones, then hit the "Run Script" button of the only app hooked into the base to see it recalculate the sum.
Dumping the code here as we, if anyone wants to set up a new testing environment manually:
let table = base.getTable('Table 1');
let query = await table.selectRecordsAsync()
let cellsToAdd = [];
let sum = 0;
const keepSumming = x => sum += x ;
query.records.forEach( x => cellsToAdd.push(
{
"id": x.id,
fields:{
"Column1":x.getCellValue('Column1'),
"Sum":keepSumming(x.getCellValue('Column1'))
}
}
));
//Airtable limits us to 50 table mutations per request, hence the splicing
while(cellsToAdd.length>0){
await table.updateRecordsAsync(
cellsToAdd.splice(0,50)
)
};
There appears to be a feature built-in to Airtable for this now. In the desktop app, at least, take a look down at the bottom of each column below all rows. There is a context menu for the column, in which Sum is one of several options.

How do i trace multiple XML elements with same name & without any id?

I am trying to scrape a website for financials of Indian companies as a side project & put it in Google Sheets using XPATH
Link: https://ticker.finology.in/company/AFFLE
I am able to extract data from elements that have a specific id like cash, net debt, etc. however I am stuck with extracting data for labels like Sales Growth.
tried
Copying the full xpath from console, //*[#id="mainContent_updAddRatios"]/div[13]/p/span - this works, however, i am reliable on the index of the div (13) and that may change for different companies, hence i am unable to automate it.
Please assist with a scalable solution
PS: I am a Product Manager with basic coding expertise as I was a developer few years ago.
At some point you need to "hardcode" something unless you have some other means of mapping the content of the page to your spreadsheet. In your example you appear to be targeting "Sales Growth" percentage. If you are not comfortable hardcoding the index of the div (13), you could identify it by the id of the "Sales Growth" label which is mainContent_lblSalesGrowthorCasa.
For example, change your
//*[#id="mainContent_updAddRatios"]/div[13]/p/span
to:
//*[#id = "mainContent_updAddRatios"]/div[.//span/#id = "mainContent_lblSalesGrowthorCasa"]/p/span
which is selecting the div based on the div containing a span with id="mainContent_lblSalesGrowthorCasa". Ultimately, whether you "hardcode" the exact index of the div or "hardcode" the ids of the nodes, you are still embedding assumptions regarding the structure of page.
Thanks #david, that helped.
Two questions
What if the structure of the page would change? Example: If the website decided to remove the p tag then would my sheet fail? How do we avoid failure in such cases?
Also, since every id is unique, the probability of that getting changed is lesser than the index being changed. Correct me, if I am wrong?
What do we do when the elements don't have an id like Profit Growth, RoE, RoCE etc

How to OCR scanned voting protocols

As part of a hobby project I'm trying to digitalise all the voting records of the Swedish parliament to see if I can extract any interesting statistics (yes a strange hobby I know).
From 1983 to 2001 the voting records look something like in the example. They are printed from some kind of voting machine and only exist on paper (that are now scanned and on my disk).
Every vote consists of three pages with two columns each of members and votes as in the example.
Some translations from Swedish: (Plats = Seat, Ledamöter = Members, Parti = party, Röst = Vote).
The list is sorted on the party column and then alphabetically on the member column.
After an election a member stays on their seat until next election or that the member quits parliament and is replaced by a replacement member. There can also be temporary replacements.
Replacements are also sorted into the list.
The Parti/Party column contains the party abbreviation and can only be one of nine letters (since there are only nine different parties in that time period). Members stay with their party but can technically change between or during election periods.
The Röst/vote column can be one of J,N,A,F (Ja = Yey, Nej = Ney, Avstår = Pass, Frånvarande = Absent) and are also aligned in a four sub-columns.
The columns and rows are not always in the same place in the picture. It can both be slightly translated and/or rotated. The quality of the scan is also not always this good.
At the top of the first page (not shown i the example) there is a summation of votes per party that can be checked against.
There are about 18.000 votes in total.
For votes before to 1983 the layout was different and I was able to make a custom program in node.js (although most languages would be ok for me) that semi-automatically could scan the votes but this looks like something that should be easy to do with tesseract or something similar.
My question is really if its possible to hint tesseract about the layout so that it can do some better guesses of what the text is. I'm aware one can make a custom wordlist (where I could for example add all members names manually).
I'm guessing that there might be a way to make a custom pattern list but I haven't figured that out.
Does anyone have any good suggestions on how to tackle this?

Query JIRA Story Point HISTORY

We used JIRA on-demand to manage an Agile project. Sometimes a story may be preliminarily sized in story points, but is then re-sized before commitment. I would like a query which shows the history of each story's status and point value.
For example:
Story 99 history:
1/1/2014 -- Status = Open; Points = Null
1/15/2014 -- Status = Reviewed; Points = 5
2/15/2014 -- Status = Committed; Points = 8
My goal (and maybe there is another way to do this) is to see how often we change our story sizes.
Thanks.
I thought I had a solution for you in using the "changed" JQL query (https://confluence.atlassian.com/display/JIRA/Advanced+Searching#AdvancedSearching-WAS), but unfortunately it looks like that is not supported currently in Jira. I received the following error from our hosted Jira instance:
History searches do not support the 'Story Points' field.
So as a user on demand query I don't think it is currently possible.
The only way I see of doing this would be to have a set day/time where you would run a query to get the current story points, export it as an excel file and then do it again after you review a set of stories and write some excel functions to show the change.
The larger question would be around your agile/scrum processes as to why estimated would change so frequently as to need tracking. If the team as a whole decides the points its ok if it doesn't match the reality once we start working on it. Or is this a case where it is updated on more than one occasion before its actually being worked on? If thats the case then I'd say that the story isn't well defined and need more information before it can be estimated?
Adding to Michael's answer, the daily monitoring for a given set of results to a query can be semi-automated using a JIRA filter subscription. You will still need to extract the issues from the results manually but at least in principle you can be sure not to miss any resizing that happens.

Logic of fixed number of records per page alphabetical pagination structure

The easiest way to explain this question is by example. See the following two images of the browse links on a particular website:
Basically, the way that it works is that there are a set number of records per page, and it works "backwards" in some manner to break down the browse pages into an appropriate number of ranges. So when there are relatively more records (as in the case of those starting with an "A"), there are more ranges, and more pages, than when there are fewer records ("X"). I am developing in Ruby on Rails, but would also be interested in some perspective on the logic here. Thanks!
The simplest way to visualize this is to think about the "deepest" groups all having 10 elements each, so split all your records into groups of 10.
Now, each group of 10 should be referenced to by an upper level group.
Each group of 10 of those should be referenced to by an even higher level group.
Finally, you'll reach the highest level group.
For any group, you take the n first letters of the first and last elements in their tree where n is it's depth. So for a group in depth 1, you take the 1st character of the very first element (recursively go deeper until you are at the sparsest branches) as the start of its range and the 1st char of the last elements as the end of it's range.
I could mock it up in PHP if you would be able to get what you need from it, but can't quite grasp the concept here.

Resources