Python Libraries - Easy Splinterlands Card Monitoring

avatar
(Edited)

image.jpg

I don’t tend to write scripts for the sake of it; they need to accomplish something useful. As the Splinterlands Sets are going to rotate in early December, I noticed players are starting to dump their cards from the 'Dice' and 'Untamed' sets.

I have had my eye on several legendary cards from the latter set for a while now, and wanted to pick up a few 1 BCX units. I could keep checking but that's too much effort. I wanted to click a shortcut and see all my possible targets easily.


image.png
...'some of the most powerful summoners are rapidly falling in value, I want to check on these and a few more at the click of a button'...

@bozz has been asking me a few things regarding Python lately, and this is a little diversion using the Splinterlands API as opposed to the now deprecated BEEM library which he was been using.

The lack of examples is typically abysmal on the internet, but I found an old article by @ecko-fresh who appears to have vacated HIVE. His article amassed a pitiful reward of $0.00.

image.png

I dropped a comment on his post, and promised to donate a FULL comment vote if he ever comes back and sees this. I note there is a Python Community which I have now joined, hosted by @emrebeyler. I will be posting all my crap in there going forward.

My script is simple, it’s not multi-file, has no ‘dunder’ statements, or functions. I know about all these, but if you are trying to lay some basics out, then I say ditch that style for the moment.

import requests
import os

os.system('cls')

# Define BCX, Default is set to 1
BCX = 1

# Add More cards to the tuple if desired on new lines
shopping_list = (
{"Card": "Cornealus", "ID": "199", "Gold": "false", "Edition": "4"},
{"Card": "Phantom of the Abyss", "ID": "177", "Gold": "false", "Edition": "4"},
{"Card": "Sea Wreck", "ID": "558", "Gold": "false", "Edition": "8"},
{"Card": "Immolation", "ID": "559", "Gold": "false", "Edition": "8"}
)

print("--Current Lowest Prices--")
print()

for card in shopping_list:
    lowest_buy_price = float('inf')

    getstring = "https://api.splinterlands.io/market/for_sale_by_card?card_detail_id=" + card["ID"] + "&gold=" + card["Gold"] + "&edition=" + card["Edition"]
    response = requests.get(getstring)
    cards = response.json()

    for foundcard in cards:
        if foundcard["bcx"] == BCX:
            buy_price = foundcard["buy_price"]
            if buy_price < lowest_buy_price:
                lowest_buy_price = buy_price

    print("Card:", card["Card"])
    print(f'Lowest Buy Price: ${lowest_buy_price}, BCX: {BCX}, Gold Foil: {card["Gold"]}')
    print()

os.system('pause')

Thirty eight lines of code including spaces, comments and you have the desired objective. Hopefully @bozz and some others can follow this, and add more content to @emrebeyler’s community.

As usual I will go through this and try and explain how it works, with a link to my GitHub repository at the foot of the post.

import requests
import os

os.system('cls')

Import statements are adding references to other libraries. ‘requests’ is used to manipulate the JSON data from the Splinterlands API call, and ‘os’ allows us to use commands similar to those in a Windows CMD shell.

Eg.. 'cls' clears the screen, easy right?

Next we have the user defined areas of the script.

# Define BCX, Default is set to 1
BCX = 1

# Add More cards to the tuple if desired on new lines
shopping_list = (
{"Card": "Cornealus", "ID": "199", "Gold": "false", "Edition": "4"},
{"Card": "Phantom of the Abyss", "ID": "177", "Gold": "false", "Edition": "4"},
{"Card": "Sea Wreck", "ID": "558", "Gold": "false", "Edition": "8"},
{"Card": "Immolation", "ID": "559", "Gold": "false", "Edition": "8"}
)

BCX = 1 means, the script will only look for single cards, not combined.

The ‘shopping_list’ tuple contains several dictionary lists within it.

Card": "Cornealus"

The name of the card you potentially are checking on.

"ID": "199"

Each Splinterland card has a unique ID. To find the card’s ID, issue this command in a browser.

https://api.splinterlands.io/cards/get_details

image.png

What you get back is overwhelming but you can search for cards easily within the content. Look at the top left corner and you will see:

[{"id":1,"name":"Goblin Shaman"

‘Goblin Shaman’ has the prestigious title of being ID:1.

"Gold": "false"

Is the card you are searching for a Gold Foil or not? This is a Boolean value and can be toggled to ‘true’.

"Edition": "8"

Finally, the Edition is the set identifier. Alpha =1, Untamed = 4, RiftWatchers = 8. You can probably figure out the ones in between.

print("--Current Lowest Prices--")
print()

I am not going to explain what ‘print’ does, as it may blow your mind and render you a quivering, gibbering halfwit.

for card in shopping_list:
    lowest_buy_price = float('inf')

    getstring = "https://api.splinterlands.io/market/for_sale_by_card?card_detail_id=" + card["ID"] + "&gold=" + card["Gold"] + "&edition=" + card["Edition"]
    response = requests.get(getstring)
    cards = response.json()

    for foundcard in cards:
        if foundcard["bcx"] == BCX:
            buy_price = foundcard["buy_price"]
            if buy_price < lowest_buy_price:
                lowest_buy_price = buy_price

The main engine of the script is this For loop. Let's break it down some.

lowest_buy_price = float('inf')

This is an interesting placeholder, which effectively sets the value of ‘lowest_buy_price’ to positive infinity. We want to set this high value for every search.

getstring = "https://api.splinterlands.io/market/for_sale_by_card?card_detail_id=" + card["ID"] + "&gold=" + card["Gold"] + "&edition=" + card["Edition"]

The API call, returns a JSON string with ALL the parameters sent to it.

image.png

A lot of data and not so useful yet as we are only looking for one return value, the cheapest!

response = requests.get(getstring)
cards = response.json()

These lines make use of the ‘requests’ library and format the data into something a little more usable. You don't need to know the intricacies of other library functions unless you are willing to deep-dive.

for foundcard in cards:
    if foundcard["bcx"] == BCX:
        buy_price = foundcard["buy_price"]
        if buy_price < lowest_buy_price:
            lowest_buy_price = buy_price

This routine loops through all the data and adds a single float into the ‘lowest_buy_price’ variable if it's the lowest price

for foundcard in cards:
    if foundcard["bcx"] == BCX:
        buy_price = foundcard["buy_price"]

        print(buy_price)

        if buy_price < lowest_buy_price:
            lowest_buy_price = buy_price

If you want to know what all the prices are, then add a print statement such as this sandwiched in between the other code statements. This is generally how I debug my code.

. All we need to do now is present the data to the instigator of this script.

print("Card:", card["Card"])
print(f'Lowest Buy Price: ${lowest_buy_price}, BCX: {BCX}, Gold Foil: {card["Gold"]}')
print()

Using f’ strings, we can mix text with variable data for easy ingestion.

os.system('pause')

Remember what I said about the 'os' library and shell commands? As we will be running this in a shell then it needs to pause so we can read the screen.

image.png

Assign a Shortcut and add it to your other Python Launchers. Mine has the parameters of:
E:\Anaconda3\python.exe "E:\Anaconda3\Scripts\FindCheapSPLCards\FindCheapSPLCards.py

image.png
... and there you have it, info with a simple click! All of them are still too bloody expensive for me. I will bide my time and wait a little longer.

This is the script in its basic form. A lot more could done such as colour coding the output, recording the values into a file, importing the previous ones on subsequent runs, comparing the prices, separating the data into a separate file and importing it, using dunder main!

if __name__ == "__main__":

See, you now are all confused. This is the reason I didn’t include it!

This and other equally useless code can be found on my personal GitHub here

RedLine.png


CurieCurator.jpg



0
0
0.000
23 comments
avatar
(Edited)

some of the most powerful summoners are rapidly falling in value

The player base of Splinterlands also rapidly fallen in the recent past. This results in less demand for the cards. Currently I am in the top 40 000 Bronze players. I remember the time, when the top 100 000 was hard to reach. By the way, I also stopped playing it for a long time. I returned to the game in the previous week.

The lack of examples is typically abysmal on the internet, but I found an old article by @ecko-fresh who appears to have vacated HIVE. His article amassed a pitiful reward of $0.00.

This is a very sad example that both in the past and nowadays too are too many content creators, and too little content consumers on the Hive blockchain. Most people focus on posting. Many people post, and a lot of content gets ignored/overlooked.

Some people say that I am negative if I mention this. But I am not negative. I am realistic. And this is obvious. It can be backed up by a lot of examples.

The Hive blockchain needs a lot more content consumers. And to reach that, a proper marketing, which is not focused on money earning.

Either way, good luck and have fun in Splinterlands.

0
0
0.000
avatar

And to reach that, a proper marketing, which is not focused on money earning.

I think we all know what happened to that attempt.

This is a very sad example that both in the past and nowadays too are too many content creators

If I had known about this author, I would have sent some support. The search facilities on HIVE are as good as they were in the Steemit days.

The player base of Splinterlands also rapidly fallen in the recent past. This results in less demand for the cards. Currently I am in the top 40 000 Bronze players. I remember the time, when the top 100 000 was hard to reach. By the way, I also stopped playing it for a long time. I returned to the game in the previous week.

The fact you returned shows promise. Modern = No BOTS. It's still a tough game though, in Bronze. I have tried.

0
0
0.000
avatar

I didn't know that you are also a code writer except exploring urban areas :)

0
0
0.000
avatar

Exploring is an attempt to stop me getting too fat, this is what I do professionally, though code development is only part of it.

0
0
0.000
avatar

Your explanation is clear, making it easy for even a newbie to Python to understand the code but to be honest, they went over my head as I'm far far away from Python after I gave HTML a try long ago which seemed like a disaster.

I appreciate your dedication to the Splinterlands community and your willingness to help others. This sense of community is what makes blockchain platforms like Hive so special.

0
0
0.000
avatar

Understanding some of it is a start. It needs to be broken down into parts like everything else.

and your willingness to help others.

I would like to see more open source code relating to HIVE, this is the idea.

0
0
0.000
avatar

Yeah, that is really quite over my head right now. I get some of it and I am learning more as I go. This is pretty cool what you did though. It sure does beat scrolling through pages of cards if you are just looking for a couple specific ones!

0
0
0.000
avatar

For the moment, grab the code and add some of your own 'views' to it. I made it as simple as possible, without any fancy stuff that make it 'standard' and digestible for regular coders.

I could do a lot more with this, and you could too. Try some experimentation, such as file access, maybe a lookup table to convert the Editions to something more readable.., such as Beta = 2. Make it a function, you can send an Int and get a String back, for the print functions.

I get some of it..

It's a start.

0
0
0.000
avatar

Time is the big factor for me right now. This is really cool though. I can definitely see the potential. Can you have it return who the owner of the card is that is being sold? I'm guessing that's probably just another function or something.

0
0
0.000
avatar
(Edited)

Yes, there's a bunch of info in the foundcard dictionary, so you need to create a new variable during the loop and add it. Then you can append it to the f' string print statement.

image.png

image.png

That might be tough to understand, but if you add a print(foundcard) directly after the for statement, you can see what other stuff you can extract.

0
0
0.000
avatar

Ah, okay. I gotcha.

0
0
0.000
avatar

I can see that you so much love Splinterlands all the time
You talk about it so many times and I can see how loyal and dedicated you are to it
That's lovely!

0
0
0.000
avatar
(Edited)

I have a large investment in it, sometimes I wish I hadn't.

0
0
0.000
avatar

Congratulations @slobberchops! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You distributed more than 135000 upvotes.
Your next target is to reach 140000 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

0
0
0.000
avatar

Great work and explanation, i ma not a python dev but reading quickly i cand understand what r you doing. :D

0
0
0.000
avatar

I had to leave a comment on this so I can find it for later. Always wanting to read code examples for blockchain interaction

0
0
0.000
avatar

Thanks for this👍 !PGM

0
0
0.000
avatar

Sent 0.1 PGM - 0.1 LVL- 1 STARBITS - 0.05 DEC - 1 SBT - 0.1 THG - 0.000001 SQM - 0.1 BUDS - 0.01 WOO - 0.005 SCRAP tokens

remaining commands 3

BUY AND STAKE THE PGM TO SEND A LOT OF TOKENS!

The tokens that the command sends are: 0.1 PGM-0.1 LVL-0.1 THGAMING-0.05 DEC-15 SBT-1 STARBITS-[0.00000001 BTC (SWAP.BTC) only if you have 2500 PGM in stake or more ]

5000 PGM IN STAKE = 2x rewards!

image.png
Discord image.png

Support the curation account @ pgm-curator with a delegation 10 HP - 50 HP - 100 HP - 500 HP - 1000 HP

Get potential votes from @ pgm-curator by paying in PGM, here is a guide

I'm a bot, if you want a hand ask @ zottone444


0
0
0.000
avatar

At least we've learned our lesson and stayed away from Rebellion!

0
0
0.000
avatar
(Edited)

You talked me into it, 100 packs my arse!

image.png

0
0
0.000
avatar

I wholeheartedly agree that more open-source contributions can only benefit the Hive community. It's tools like these that can make the platform more robust and user-friendly.

0
0
0.000