Discord.py Question with weird betting winnings - discord.py

As the title suggests, I have some trouble with the titles of my betting command. Sometimes it doesn't show up, while at other times it shows up as something with a lot of 1's and 0's. I think it might be binary, but I don't know.
Code:
https://replit.com/#jsun3/Betting-cmd#main.py
Stacks was being annoying on formatting so I did it in replit.
Ceres' answer helped, but caused another error. When I won sometimes it counted -10 won(meaning i lost 10).
IMG:
New update for code:
https://replit.com/#jsun3/Betting-cmd#main.py

The problem is that amount is a string, and in python you can multiply a string to repeat it. That is exactly what is happening.
Solve it with
#client.command(aliases=["gamble"]) # ASSUME I HAVE CLIENT DEFINED BC IN MY REAL CODE IT IS DEFINED.
async def bet(ctx, amount: int = None):
Since discord.py implements type-converters for arguments, your amount is converted to an integer, and will be multiplied like one.

Related

How to use options in discord.py?

I'm working on a discord bot that can send random memes, and I wanted to add a command for continuous feed according to a the amount of memes the user wants, for example /feed number:15, would send 15 memes.
The problem is how to make the option input work on the command, I've find some videos that helped me a little, but due to the other commands being híbrido commands, I can figure out how to make this one working.
This is what's I have so far:
#bot.hybrid_command(name = "feed", with_app_command = True, description = "Feeds a specific number of memes")
#app_commands.guilds(discord.Object(id = guild_id))
async def test1(interaction: discord.Interaction, number: int):
await interaction.response.send_message("It's working!")
The await line, obviously won't do any feed this way, I know, I did the feed part separated and it works, but I just did it this way for testing, so if I type the command and enter a number, it should return me "It's working!", But that never happens, I suppose it's maybe something to do with híbrido commands, but I really don't know, what am I missing?
I don't think the input option is the problem, because I see nothing wrong with it, but the thing that is surely wrong is that you're naming the first argument of the hybrid command interaction, which is wrong and can create confusion; the actual argument it should be is context or ctx. And that object is a discord.ext.commands.Context object.
You should rename it to ctx to avoid confusion.
#bot.hybrid_command(name = "feed", with_app_command = True, description = "Feeds a specific number of memes")
#app_commands.guilds(discord.Object(id = guild_id))
async def test1(ctx: commands.Context, number: int):
await ctx.send("It's working!")
You may want to see the official example here

totalEstimatedMatches behavior with Microsoft (Bing) Cognitive search API (v5)

Recently converted some Bing Search API v2 code to v5 and it works but I am curious about the behavior of "totalEstimatedMatches". Here's an example to illustrate my question:
A user on our site searches for a particular word. The API query returns 10 results (our page size setting) and totalEstimatedMatches set to 21. We therefore indicate 3 pages of results and let the user page through.
When they get to page 3, totalEstimatedMatches returns 22 rather than 21. Seems odd that with such a small result set it shouldn't already know it's 22, but okay I can live with that. All results are displayed correctly.
Now if the user pages back again from page 3 to page 2, the value of totalEstimatedMatches is 21 again. This strikes me as a little surprising because once the result set has been paged through, the API probably ought to know that there are 22 and not 21 results.
I've been a professional software developer since the 80s, so I get that this is one of those devil-in-the-details issues related to the API design. Apparently it is not caching the exact number of results, or whatever. I just don't remember that kind of behavior in the V2 search API (which I realize was 3rd party code). It was pretty reliable on number of results.
Does this strike anyone besides me as a little bit unexpected?
Turns out this is the reason why the response JSON field totalEstimatedMatches includes the word ...Estimated... and isn't just called totalMatches:
"...search engine index does not support an accurate estimation of total match."
Taken from: News Search API V5 paging results with offset and count
As one might expect, the fewer results you get back, the larger % error you're likely to see in the totalEstimatedMatches value. Similarly, the more complex your query is (for example running a compound query such as ../search?q=(foo OR bar OR foobar)&...which is actually 3 searches packed into 1) the more variation this value seems to exhibit.
That said, I've managed to (at least preliminarily) compensate for this by setting the offset == totalEstimatedMatches and creating a simple equivalency-checking function.
Here's a trivial example in python:
while True:
if original_totalEstimatedMatches < new_totalEstimatedMatches:
original_totalEstimatedMatches = new_totalEstimatedMatches.copy()
#set_new_offset_and_call_api() is a func that does what it says.
new_totalEstimatedMatches = set_new_offset_and_call_api()
else:
break
Revisiting the API & and I've come up with a way to paginate efficiently without having to use the "totalEstimatedMatches" return value:
class ApiWorker(object):
def __init__(self, q):
self.q = q
self.offset = 0
self.result_hashes = set()
self.finished = False
def calc_next_offset(self, resp_urls):
before_adding = len(self.result_hashes)
self.result_hashes.update((hash(i) for i in resp_urls)) #<==abuse of set operations.
after_adding = len(self.result_hashes)
if after_adding == before_adding: #<==then we either got a bunch of duplicates or we're getting very few results back.
self.complete = True
else:
self.offset += len(new_results)
def page_through_results(self, *args, **kwargs):
while not self.finished:
new_resp_urls = ...<call_logic>...
self.calc_next_offset(new_resp_urls)
...<save logic>...
print(f'All unique results for q={self.q} have been obtained.')
This^ will stop paginating as soon as a full response of duplicates have been obtained.

Ruby regular expression for asterisks/underscore to strong/em?

As part of a chat app I'm writing, I need to use regular expressions to match asterisks and underscores in chat messages and turn them into <strong> and <em> tags. Since I'm terrible with regex, I'm really stuck here. Ideally, we would have it set up such that:
One to three words, but not more, can be marked for strong/em.
Patterns such as "un*believ*able" would be matched.
Only one or the other (strong OR em) work within one line.
The above parameters are in order of importance, with only #1 being utterly necessary - the others are just prettiness. The closest I came to anything that worked was:
text = text.sub(/\*([(0-9a-zA-Z).*])\*/,'<b>\1<\/b>')
text = text.sub(/_([(0-9a-zA-Z).*])_/,'<i>\1<\/i>')
But it obviously doesn't work with any of our params.
It's odd that there's not an example of something similar already out there, given the popularity of using asterisks for bold and whatnot. If there is, I couldn't find it outside of plugins/gems (which won't work for this instance, as I really only need it in in one place in my model). Any help would be appreciated.
This should help you finish what you are doing:
sub(/\*(.*)\*/,'<b>\1</b>')
sub(/_(.*)_/,'<i>\1</i>')
Firstly, your criteria are a little strange, but, okay...
It seems that a possible algorithm for this would be to find the number of matches in a message, count them to see if there are less than 4, and then try to perform one set of substitutions.
strong_regexp = /\*([^\*]*)\*/
em_regexp = /_([^_]*)_/
def process(input)
if input ~= strong_regexp && input.match(strong_regexp).size < 4
input.sub strong_regexp, "<b>\1<\b>"
elsif input ~= em_regexp && intput.match(em_regexp).size < 4
input.sub em_regexp, "<i>\1<\i>"
end
end
Your specifications aren't entirely clear, but if you understand this, you can tweak it yourself.

mortgage calculator in Shoes but it won't divide?

I am new to Ruby and Shoes, I think I have everything. the program appears to work correctly except when I get to the last step. I, enter the loan amount, interest rate, in to edit_lines, when I press the calculate button, it performs the calculations, stores the calculated numbers to a variable. The last step is dividing the total loan (loan and interest) by the length of the loan in months to ge the monthly payment, so I can make a payment table for the entire loan, but I either get in-corredt results or I get no reeults.
I think I converted the integers to floats, etc. , but... not sure. It appears to add, multiply, subtrct, except it will not divide 2 qbjects. If I enter numbers it works ok.
What am I doing wrong. It does seem like it is that difficult. Example code of dividng the values in a varible by the value of another varible?
It looks like you're using eval(), which you almost never, ever want to use. You can do the exact same thing in normal ruby. I'm just guessing right now since the code I can see in your comment is lacking newlines, but I think this code would work:
#numberbox3.text = #totalinterest + #loadamount
#numberbox5.text = #totalloan / #lengthyears
Hope this helps!

Ruby on Rails - generating bit.ly style identifiers

I'm trying to generate UUIDs with the same style as bit.ly urls like:
http://bit [dot] ly/aUekJP
or cloudapp ones:
http://cl [dot] ly/1hVU
which are even smaller
how can I do it?
I'm now using UUID gem for ruby but I'm not sure if it's possible to limitate the length and get something like this.
I am currently using this:
UUID.generate.split("-")[0] => b9386070
But I would like to have even smaller and knowing that it will be unique.
Any help would be pretty much appreciated :)
edit note: replaced dot letters with [dot] for workaround of banned short link
You are confusing two different things here. A UUID is a universally unique identifier. It has a very high probability of being unique even if millions of them were being created all over the world at the same time. It is generally displayed as a 36 digit string. You can not chop off the first 8 characters and expect it to be unique.
Bitly, tinyurl et-al store links and generate a short code to represent that link. They do not reconstruct the URL from the code they look it up in a data-store and return the corresponding URL. These are not UUIDS.
Without knowing your application it is hard to advise on what method you should use, however you could store whatever you are pointing at in a data-store with a numeric key and then rebase the key to base32 using the 10 digits and 22 lowercase letters, perhaps avoiding the obvious typo problems like 'o' 'i' 'l' etc
EDIT
On further investigation there is a Ruby base32 gem available that implements Douglas Crockford's Base 32 implementation
A 5 character Base32 string can represent over 33 million integers and a 6 digit string over a billion.
If you are working with numbers, you can use the built in ruby methods
6175601989.to_s(30)
=> "8e45ttj"
to go back
"8e45ttj".to_i(30)
=>6175601989
So you don't have to store anything, you can always decode an incoming short_code.
This works ok for proof of concept, but you aren't able to avoid ambiguous characters like: 1lji0o. If you are just looking to use the code to obfuscate database record IDs, this will work fine. In general, short codes are supposed to be easy to remember and transfer from one medium to another, like reading it on someone's presentation slide, or hearing it over the phone. If you need to avoid characters that are hard to read or hard to 'hear', you might need to switch to a process where you generate an acceptable code, and store it.
I found this to be short and reliable:
def create_uuid(prefix=nil)
time = (Time.now.to_f * 10_000_000).to_i
jitter = rand(10_000_000)
key = "#{jitter}#{time}".to_i.to_s(36)
[prefix, key].compact.join('_')
end
This spits out unique keys that look like this: '3qaishe3gpp07w2m'
Reduce the 'jitter' size to reduce the key size.
Caveat:
This is not guaranteed unique (use SecureRandom.uuid for that), but it is highly reliable:
10_000_000.times.map {create_uuid}.uniq.length == 10_000_000
The only way to guarantee uniqueness is to keep a global count and increment it for each use: 0000, 0001, etc.

Resources