Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
12 rats tied together
Sep 7, 2006

for a lot of developers the "how a website works" knowledge domain stops at the edge of whatever the framework is, maybe it extends a little bit into the web server itself (iis, gunicorn, puma, tomcat, etc)

it's really hard to know everything but i recommend pushing this boundary whenever you can. in this case, the web browser makes an http request to your flask application. a lot of magic happens that turns the http request (which is just a big blob of text that arrives at a network address) into something interactable inside your python files/flask app

your app runs some logic and eventually does the same thing in reverse: constructs a big blob of text that represents an http response, and sends it back over the network.

because http works in this request/response fashion, chrome only speaks http, and your python only happens "after" the http part, there's no way to build a real-time web application in python.

javascript was created to be the "client side" scripting language that runs in chrome (or any other web browser). your flask app can include javascript in its response and your users will run that javascript interactively, so, you should build the synthesizer in javascript

that's an oversimplification in basically every dimension but i hope it provides some useful context

Adbot
ADBOT LOVES YOU

The March Hare
Oct 15, 2006

Je rêve d'un
Wayne's World 3
Buglord
Just you wait until I write a VST in python and throw it through it through a wasm compiler >: )

death cob for cutie
Dec 30, 2006

dwarves won't delve no more
too much splatting down on Zot:4

Gin_Rummy posted:

Definitely both, but emphasis on the former as my primary focus. Sounds like I can develop a bit of back-end development skills by working on the former, though?

I'd focus on one thing at a time - figure out how to do what you want in JavaScript, then think about how to pipe that data from the client to the server to do whatever with it.

12 rats tied together
Sep 7, 2006

The March Hare posted:

Just you wait until I write a VST in python and throw it through it through a wasm compiler >: )

if you ever do this please let me know because i have an electron app that i would much rather be python than javascript

alexandriao
Jul 20, 2019


Has anyone ever written an interface to SA in python?

QuarkJets
Sep 8, 2008

alexandriao posted:

Has anyone ever written an interface to SA in python?

I don't know but I imagine you can use the Awful app for inspiration

https://github.com/Awful/Awful.app

Looks like there is a little bit of Python code in the project but not much

NinpoEspiritoSanto
Oct 22, 2013




Given the 00s php forum and radium eldritch horror I'd imagine some combination of requests/beautifulsoup would be the first tools I'd reach for

alexandriao
Jul 20, 2019


NinpoEspiritoSanto posted:

Given the 00s php forum and radium eldritch horror I'd imagine some combination of requests/beautifulsoup would be the first tools I'd reach for

Yes, that's more or less what I was thinking too


QuarkJets posted:

I don't know but I imagine you can use the Awful app for inspiration

https://github.com/Awful/Awful.app

Looks like there is a little bit of Python code in the project but not much

I did actually take a gander at how Awful does the requests, and then I had to stop taking a gander because reading code for android is viscerally repulsive to me.

death cob for cutie
Dec 30, 2006

dwarves won't delve no more
too much splatting down on Zot:4

alexandriao posted:

Has anyone ever written an interface to SA in python?

It's probably not exactly what you're looking for, but Votefinder (a tool the Mafia community here uses to help run games) has quite a bit of code to download/parse SA posts and reply to certain threads. If you're looking to do something specific and need inspiration, you might want to poke around here.

wolrah
May 8, 2006
what?
For a long time I've thought it would make sense for there to be some kind of a standard API for forums where you could have a generic client that could view and participate in any forums implementing that standard. Something like what Tapatalk claims to offer, but not proprietary or commercial.

Obviously you'd lose any forum-specific features without further extensions to the interface, but it just seems silly that so many functionally identical forums require different apps all doing the same thing. In my mind any forum with the standard linear thread experience should be able to be supportable with a single app, then for example a Slashdot or Reddit style branching thread system would need different handling but both of those two would be similar in the end. IDFK about Discourse-style forums, honestly I hate them and wish they'd all go away.

Of course, insert xkcd standards comic here.

CarForumPoster
Jun 26, 2013

⚡POWER⚡

wolrah posted:

For a long time I've thought it would make sense for there to be some kind of a standard API for forums where you could have a generic client that could view and participate in any forums implementing that standard. Something like what Tapatalk claims to offer, but not proprietary or commercial.

Obviously you'd lose any forum-specific features without further extensions to the interface, but it just seems silly that so many functionally identical forums require different apps all doing the same thing. In my mind any forum with the standard linear thread experience should be able to be supportable with a single app, then for example a Slashdot or Reddit style branching thread system would need different handling but both of those two would be similar in the end. IDFK about Discourse-style forums, honestly I hate them and wish they'd all go away.

Of course, insert xkcd standards comic here.

ideally just add a type=json url param and get the thread in paginated json. Kinda like reddit's .json

wolrah
May 8, 2006
what?

CarForumPoster posted:

ideally just add a type=json url param and get the thread in paginated json. Kinda like reddit's .json
Exactly, working with the Reddit API for a bot at one point was what inspired that thought initially, combined with seeing what Awful has to do to make it work through screen scraping.

From what I recall about working with phpBB and vB back in the day I'd bet a basic read-only version could mostly be implemented as a theme/template without even requiring code on the forum side, obviously any kind of authenticated requests would require intentional support to be done securely.

death cob for cutie
Dec 30, 2006

dwarves won't delve no more
too much splatting down on Zot:4
Background for this question: I teach introductory Python/web development to people with 0 previous knowledge and I need to demonstrate worst-case time complexity to students and show them how something that's not a big deal if you're only working with 10 elements in a list can become a slog if you have a hundred thousand, or ten million, or etc.

I want to generate a list of one billion sorted integers. Ideally I'd do this in such a way that the list is random, but I can't seem to find a good way of doing that.

code:
minimum = 0
maximum = 2000000000
sample = list(range(minimum, maximum, 2))
This only takes a bit to generate (about five seconds to barf like, 32 gigs of garbage into RAM, not bad for a classroom), but it's not actually random. I can puke a bunch of random ints into a list, but then I have to sort them, which is going to take forever - and actually calling randint() so many times is a huge timesink too. I've tried some dumb stuff like a for loop that adds a number from 1 to 3 to the last item in the list (slow as gently caress) and a list comprehension (also slow as gently caress). Is there a good quick way of doing this that I'm missing, maybe buried somewhere in numpy, or should I just be happy with the snippet above, randomness be damned?

VictualSquid
Feb 29, 2012

Gently enveloping the target with indiscriminate love.


e: Nevermind, didn't read your post fully. Why do you even want random sorted integers?

VictualSquid fucked around with this message at 16:28 on Sep 9, 2021

D34THROW
Jan 29, 2012

RETAIL RETAIL LISTEN TO ME BITCH ABOUT RETAIL
:rant:
I can't actually test with one billion integers because I don't have enough RAM but the following worked for me:

Python code:
from numpy import *

min = 0
max = 1000000000
sample = sorted(random.randint(min, max, 1000)
EDIT: A not-insignificant portion of my day-to-day bullshit is going through PDFs and renaming them based on either part of the filename, or some predictable portion of the document (shipping documents and invoices namely, from no more than a dozen different vendors). Is this something I could reasonably automate by training some sort of machine learning model to recognize:

A) The vendor whose document it is,
B) The type of document it is,
C) Where the document number is on the document,
D) If, based on A, B, and C, it needs a bookmark for later split, and
E) If not D, to rename the document appropriately.

Am I getting in over my head? I just...despise repetition and it has led directly to most of my programming experience, in that I utilize coding to eliminate repetition.

D34THROW fucked around with this message at 16:42 on Sep 9, 2021

death cob for cutie
Dec 30, 2006

dwarves won't delve no more
too much splatting down on Zot:4

VictualSquid posted:

e: Nevermind, didn't read your post fully. Why do you even want random sorted integers?

I guess I forgot to actually mention that - specifically where I bring something like this up is when we talk about binary search. We have students try to implement it, they end up slicing their input array/list, and I like to show them how that looks fine but actually has some performance issues later on. I show them a binary search implementation that wants to slice the input vs. one that just keeps track of the leftmost/rightmost index of the array it needs to look at, and have them see how for small lists the performance difference is basically nil, but that there gets to be a fairly rapid gulf between them as the list grows in size.

D34THROW posted:

I can't actually test with one billion integers because I don't have enough RAM but the following worked for me:

Python code:
from numpy import *

min = 0
max = 1000000000
sample = sorted(random.randint(min, max, 1000)

This works to get 1000 (or x) random numbers nicely put into a numpy array, but then the actual sorting takes a really long time.

death cob for cutie
Dec 30, 2006

dwarves won't delve no more
too much splatting down on Zot:4

D34THROW posted:

EDIT: A not-insignificant portion of my day-to-day bullshit is going through PDFs and renaming them based on either part of the filename, or some predictable portion of the document (shipping documents and invoices namely, from no more than a dozen different vendors). Is this something I could reasonably automate by training some sort of machine learning model to recognize:

A) The vendor whose document it is,
B) The type of document it is,
C) Where the document number is on the document,
D) If, based on A, B, and C, it needs a bookmark for later split, and
E) If not D, to rename the document appropriately.

Am I getting in over my head? I just...despise repetition and it has led directly to most of my programming experience, in that I utilize coding to eliminate repetition.

I think the idea of machine learning is probably a bit overkill - if vendors issue documents using the same template over and over again and you can identify that template, you should be able to say "vendor A has the necessary data in locations B, C and D in this document" - you'd figure out the vendor based on that data and go from there. Unfortunately, all I personally know about trying to parse PDFs is "it's not as easy as it sounds" and "god forbid any of this data somehow ends up as an image" - I'm not immediately familiar with easily parsing PDFs via Python.

e: jogged my memory a bit, a student was trying to to something similar for a project once. It might actually be easier if you can convert the PDF to HTML, if you're familiar with parsing HTML? I think he was either trying that or using pdftotree, but then he disappeared off the face of the earth and I never saw where he went with it.

death cob for cutie fucked around with this message at 17:07 on Sep 9, 2021

OnceIWasAnOstrich
Jul 22, 2006

Epsilon Plus posted:

I guess I forgot to actually mention that - specifically where I bring something like this up is when we talk about binary search. We have students try to implement it, they end up slicing their input array/list, and I like to show them how that looks fine but actually has some performance issues later on. I show them a binary search implementation that wants to slice the input vs. one that just keeps track of the leftmost/rightmost index of the array it needs to look at, and have them see how for small lists the performance difference is basically nil, but that there gets to be a fairly rapid gulf between them as the list grows in size.

This works to get 1000 (or x) random numbers nicely put into a numpy array, but then the actual sorting takes a really long time.

I'm a bit confused about what you want. If you want it sorted it is pretty not-random by definition. If you want it to be randomly generated but also sorted, you are clearly going to run into the big-O behavior you are trying to teach anyway. If you want to create a number that is some amount randomly bigger than the number before it (semi-random?), you're going to have to do N operations anyway. As you've discovered, Python functions have a bit of overhead. You'll certainly run into painful Python function-calling slowness unless you happen to find a function that does this thing you want pre-written in a faster language out of Numpy or whatever or figure out some combinations of those that gives you what you want.

Why do they need to be random and not just a sequence like you made? You could create them with a step if you wanted them not-sequential or make like a thousand sub-lists with different step sizes and concatenate them so it isn't a consistent step size and you still mostly need a binary search. Or do that with whatever the maximum size you can feasibly sort, create all the sub-ranges with appropriate min/max, then concatenate those for something approximating "random+sorted".

The March Hare
Oct 15, 2006

Je rêve d'un
Wayne's World 3
Buglord
https://medium.com/@dylan.finn/the-worst-and-most-entertaining-sorting-algorithms-96efc9025f7

DoctorTristan
Mar 11, 2006

I would look up into your lifeless eyes and wave, like this. Can you and your associates arrange that for me, Mr. Morden?
Do you want the first billion integers in a random order? numpy.random.permutation(n) will give you a random permutation of the integers up to n, but I have never tested it on a billion integers.

Sad Panda
Sep 22, 2004

I'm a Sad Panda.

That was my simple idea for teaching the importance of algorithmic efficiency. Merge v bubble v bogo on a list of 5/10/100/5000. Bogo mainly to show that beyond 10 it just takes too long and it's a fun algorithm. https://visualgo.net/en/sorting being a lovely site to help visualise them too.

QuarkJets
Sep 8, 2008

Epsilon Plus posted:

I guess I forgot to actually mention that - specifically where I bring something like this up is when we talk about binary search. We have students try to implement it, they end up slicing their input array/list, and I like to show them how that looks fine but actually has some performance issues later on. I show them a binary search implementation that wants to slice the input vs. one that just keeps track of the leftmost/rightmost index of the array it needs to look at, and have them see how for small lists the performance difference is basically nil, but that there gets to be a fairly rapid gulf between them as the list grows in size.

This works to get 1000 (or x) random numbers nicely put into a numpy array, but then the actual sorting takes a really long time.

The desire to have the numbers be random is at odds with the desire to have the numbers be sorted

You could write a little generator that A) rolls a probability to increment (say 50%) and B) rolls the increment (say between 1 and 5), then just tune these twiddle parameters and keep yielding the result. This would give you a sorted list but the randomness will be wonky. Maybe use a Gaussian to weight the increments toward 0, so you only get the occasional large increment

QuarkJets fucked around with this message at 20:08 on Sep 9, 2021

QuarkJets
Sep 8, 2008

Epsilon Plus posted:

I guess I forgot to actually mention that - specifically where I bring something like this up is when we talk about binary search. We have students try to implement it, they end up slicing their input array/list, and I like to show them how that looks fine but actually has some performance issues later on. I show them a binary search implementation that wants to slice the input vs. one that just keeps track of the leftmost/rightmost index of the array it needs to look at, and have them see how for small lists the performance difference is basically nil, but that there gets to be a fairly rapid gulf between them as the list grows in size.

This works to get 1000 (or x) random numbers nicely put into a numpy array, but then the actual sorting takes a really long time.

I think ndarray.sort() would be faster but maybe not as fast as you want?

If this is for a lesson plan then you could pregenerate the list and then load it later.

death cob for cutie
Dec 30, 2006

dwarves won't delve no more
too much splatting down on Zot:4

OnceIWasAnOstrich posted:

I'm a bit confused about what you want. If you want it sorted it is pretty not-random by definition. If you want it to be randomly generated but also sorted, you are clearly going to run into the big-O behavior you are trying to teach anyway. If you want to create a number that is some amount randomly bigger than the number before it (semi-random?), you're going to have to do N operations anyway. As you've discovered, Python functions have a bit of overhead. You'll certainly run into painful Python function-calling slowness unless you happen to find a function that does this thing you want pre-written in a faster language out of Numpy or whatever or figure out some combinations of those that gives you what you want.

Why do they need to be random and not just a sequence like you made? You could create them with a step if you wanted them not-sequential or make like a thousand sub-lists with different step sizes and concatenate them so it isn't a consistent step size and you still mostly need a binary search. Or do that with whatever the maximum size you can feasibly sort, create all the sub-ranges with appropriate min/max, then concatenate those for something approximating "random+sorted".

What I want is to get a list that sometimes starts [1, 3, 4, 7, 9...] and other times starts [1, 2, 3, 5, 8...] or maybe [2, 4, 5, 9, 12...] - the reason is about once every three months I get a student who just doesn't get that the items in the list don't matter, only that the list itself is sorted. It ends up being a timesink digression and they usually end up bringing someone else down into the muck with them. Like, I know that attempting to generate the list and then sort it is going to have some overhead (massive overhead if I want a big big list) - that's why I was wondering if there was some kind of magic bullet lurking in the standard library or numpy for this situation.

QuarkJets posted:

You could write a little generator that A) rolls a probability to increment (say 50%) and B) rolls the increment (say between 1 and 5), then just tune these twiddle parameters and keep yielding the result. This would give you a sorted list but the randomness will be wonky. Maybe use a Gaussian to weight the increments toward 0, so you only get the occasional large increment

This runs into issues of time, hitting the random number generator over and over.

QuarkJets posted:

If this is for a lesson plan then you could pregenerate the list and then load it later.

This is a killer idea though (or OnceIWasAnOstrich's idea of generating a lot of smaller lists and just stitching them together once sorted) - although I'm loathe to think how much space on disk that list would take once it's pickle'd or marshal'd or shelve'd or whatever.

Really though I think my problem is that I'm looking for a technical solution to a problem that can't be fixed with a technical solution - I'm trying to catch the edge case of the one student that's having difficulty comprehending it, but if 98% of my class is getting it just fine...

Wallet
Jun 19, 2006

Epsilon Plus posted:

This works to get 1000 (or x) random numbers nicely put into a numpy array, but then the actual sorting takes a really long time.
Do you actually need a billion? My computer, at least, doesn't want to do that without at least dumping them out of ram in chunks, but this generates 100 million in ~30 seconds which seems faster than trying to sort things based on my extremely limited testing:

Python code:
from random import randint
from typing import List


def get_random_int_list_of_length(target_length: int, repeats: bool = False) -> List[int]:
    def get_random_by_digits(digits):
        return map(int, str(randint(10 ** (digits - 1), (10 ** digits) - 1)))

    current_length = 0
    last_number = 0
    result = []
    while current_length < target_length:
        for i in get_random_by_digits(1000):
            if not repeats:
                if i == 0:
                    i = 1
            last_number += i
            result.append(last_number)
            current_length += 1
    return result
Obviously they aren't fully random but they are probably close enough (and there's a bunch of things I'm too lazy to do that would let you make the increments less fixed). As a bonus there's some interesting performance stuff that happens if you mess with the number of digits it requests at a time.

Ed: Needs an extra check in there if you want to use it with a target length that isn't divisible by 1,000 probably.

Wallet fucked around with this message at 00:27 on Sep 10, 2021

DoctorTristan
Mar 11, 2006

I would look up into your lifeless eyes and wave, like this. Can you and your associates arrange that for me, Mr. Morden?

Epsilon Plus posted:

What I want is to get a list that sometimes starts [1, 3, 4, 7, 9...] and other times starts [1, 2, 3, 5, 8...] or maybe [2, 4, 5, 9, 12...]


If that’s all you want then just generate a sequence of random integers between 1 and 5 (or whatever you want the maximum difference to be) then take the cumulative sum of that sequence ( np.cumsum will do the job ).

Wallet
Jun 19, 2006

DoctorTristan posted:

If that’s all you want then just generate a sequence of random integers between 1 and 5 (or whatever you want the maximum difference to be) then take the cumulative sum of that sequence ( np.cumsum will do the job ).

It appears to be faster to generate less larger random numbers and just use the digits which is what the code above is doing. Not sure if generating them and then running them through cumsum would be faster or not.

QuarkJets
Sep 8, 2008

I like the cumsum idea, pretty cool

Foxfire_
Nov 8, 2010

The first lesson of using Python on bigish datasets is "Don't". It's slow and python objects have huge amounts of overhead.

Only use python as a glue language to manipulate non-PyObject things with not-python implemented code


(this is an old i5-2500K and the dataset is only ~4GB)

e: If you want a python list of python integers at the end, it's O(x) to go back to that. It'll get enormous though because each 4 byte integer is going to turn into a full PyObject. Doing the 'ndarray of a billion integers' -> 'python list of a billion python integers' conversion is slower than generating and sorting the ndarray.

Foxfire_ fucked around with this message at 05:39 on Sep 10, 2021

D34THROW
Jan 29, 2012

RETAIL RETAIL LISTEN TO ME BITCH ABOUT RETAIL
:rant:
Using PyQt5, what's my best option for a widget to use a QPainter on to generate a drawing? I'm using a separate QWidget window for drawing; should I just stick a QWidget with a white background on it for the drawing, or would an OpenGL widget or QGraphicsView be better for that?

Mycroft Holmes
Mar 26, 2010

by Azathoth
ugh, more homework trouble. I'm trying to create a linear search function that prints the variables in the list up to the target number or returns the whole list and target not found". I'm getting all kinds of errors and I have no idea why!

code:
class Search(object):

    def __init__(self):
        self.myList = [2, 5, 7, 9, 14, 27]
        self.target = 0
        self.length = 1

    def linearSearchSorted(self):
        position = 0
        while position < len(self.myList):
            if self.target == self.myList[position]:
                print("Elements visited: ")
                for item in self.myList[:position]:
                    print(item)
                print("Target found at position " + str(position))
                quit
            elif self.target < self.myList[position]:
                print("Elements visited: ")
                for item in self.myList[0:position]:
                    print(item)
                print("Target not found")
                quit
            position += 1
            self.length += 1

    def getTarget(self):
        self.target = int(input("Search Target: "))

def main():
    s = Search()
    s.getTarget()
    s.linearSearchSorted()

if __name__ == "__main__":
    main()

Sad Panda
Sep 22, 2004

I'm a Sad Panda.

Mycroft Holmes posted:

ugh, more homework trouble. I'm trying to create a linear search function that prints the variables in the list up to the target number or returns the whole list and target not found". I'm getting all kinds of errors and I have no idea why!

code:
class Search(object):

    def __init__(self):
        self.myList = [2, 5, 7, 9, 14, 27]
        self.target = 0
        self.length = 1

    def linearSearchSorted(self):
        position = 0
        while position < len(self.myList):
            if self.target == self.myList[position]:
                print("Elements visited: ")
                for item in self.myList[:position]:
                    print(item)
                print("Target found at position " + str(position))
                quit
            elif self.target < self.myList[position]:
                print("Elements visited: ")
                for item in self.myList[0:position]:
                    print(item)
                print("Target not found")
                quit
            position += 1
            self.length += 1

    def getTarget(self):
        self.target = int(input("Search Target: "))

def main():
    s = Search()
    s.getTarget()
    s.linearSearchSorted()

if __name__ == "__main__":
    main()

What errors are you getting?

Mycroft Holmes
Mar 26, 2010

by Azathoth
Lots! If I search for 2, I get this:

code:
Search Target: 2
Elements visited: 
Target found at position 0
Elements visited: 
2
Target not found
Elements visited: 
2
5
Target not found
Elements visited: 
2
5
7
Target not found
Elements visited: 
2
5
7
9
Target not found
Elements visited: 
2
5
7
9
14
Target not found
If I search for something not on the list, I get nothing, it just ends!

death cob for cutie
Dec 30, 2006

dwarves won't delve no more
too much splatting down on Zot:4
I can't test it right now (in bed, too lazy to pull up repl.it on my phone) but isn't quit a function in python? i.e. you need
code:

quit()

Mycroft Holmes
Mar 26, 2010

by Azathoth

Epsilon Plus posted:

I can't test it right now (in bed, too lazy to pull up repl.it on my phone) but isn't quit a function in python? i.e. you need
code:
quit()

Okay, that's fixed a lot. However, it's not printing the items in the list it has gone over. That should include itself.

Mycroft Holmes
Mar 26, 2010

by Azathoth
It's also not showing "target not found"

QuarkJets
Sep 8, 2008

Mycroft Holmes posted:

ugh, more homework trouble. I'm trying to create a linear search function that prints the variables in the list up to the target number or returns the whole list and target not found". I'm getting all kinds of errors and I have no idea why!

code:
class Search(object):

    def __init__(self):
        self.myList = [2, 5, 7, 9, 14, 27]
        self.target = 0
        self.length = 1

    def linearSearchSorted(self):
        position = 0
        while position < len(self.myList):
            if self.target == self.myList[position]:
                print("Elements visited: ")
                for item in self.myList[:position]:
                    print(item)
                print("Target found at position " + str(position))
                quit
            elif self.target < self.myList[position]:
                print("Elements visited: ")
                for item in self.myList[0:position]:
                    print(item)
                print("Target not found")
                quit
            position += 1
            self.length += 1

    def getTarget(self):
        self.target = int(input("Search Target: "))

def main():
    s = Search()
    s.getTarget()
    s.linearSearchSorted()

if __name__ == "__main__":
    main()

I recommend reading a book like Robert C Martin's Clean Code for some coding practices, it's targeted for Java but its lessons are widely applicable

Anyway, here are more specific suggestions

  • Use f-strings: print(f"Target found at position {position}")
  • Use sys.exit() instead of quit()
  • self.length doesn't appear to do anything. I mean, it's occasionally incremented, but that doesn't have any effect on anything
  • It seems like you want elif self.target < self.myList[position]: to be else:. Right? This elif only triggers if the target is less than an element in the list, so if your target is greater than 27 your code just exits. Then it needs to be modified further, but I think this explains why your code seems to just exit

QuarkJets fucked around with this message at 09:03 on Sep 13, 2021

Mycroft Holmes
Mar 26, 2010

by Azathoth
okay, I've fixed everything. Thanks for the help.

Loezi
Dec 18, 2012

Never buy the cheap stuff
I need to associate Things (below: strings) with float ranges, s.t. some of the ranges go to either negative or positive infinity. The "trivial" implementation would probably be something like this:

Python code:
thresholds = {
    "low": (float('-inf'), 0),
    "medium": (0, 10),
    "high": (10, float('inf'))
}

def find(x: float) -> str:
    for key, (lower_bound, upper_bound) in thresholds.items():
        if lower_bound <= x < upper_bound: 
            return key
But I dislike find having to know stuff about what I feel like are the internals of thresholds. I could, instead, do this with lambdas:

Python code:
thresholds = {
    "low": lambda x: x < 0,
    "medium": lambda x: 0 <= x < 10,
    "high": lambda x: 10 <= x
}

def find(x: float) -> str:
    for key, check in thresholds.items():
        if check(x): 
            return key
but I'm not thrilled about that either, because lambdas seem like a great recipe to ensure that I get some hard-to-debug bug later on.

Naturally, I could add a custom class, perhaps along the lines of following:
Python code:
class Bounds:
    def __init__(self, lower_bound, upper_bound) -> None:
        self.lower_bound = lower_bound if lower_bound is not None else float('-inf')
        self.upper_bound = upper_bound if upper_bound is not None else float('inf')

    def __contains__(self, value: float) -> bool:
        return self.lower_bound <= value < self.upper_bound

thresholds = {
    "low": Bounds(None, 0),
    "medium": Bounds(0, 10),
    "high": Bounds(10, None)
}

def find(x: float) -> str:
    for key, bounds in thresholds.items():
        if x in bounds: 
            return key
This feels like I'm making a custom implementation of range which I dislike immensely.

Is there some part of the stdlib that I'm missing here, that would make this pattern nice and concise without going all lambda?

Adbot
ADBOT LOVES YOU

cinci zoo sniper
Mar 15, 2013




Loezi posted:

I need to associate Things (below: strings) with float ranges, s.t. some of the ranges go to either negative or positive infinity. The "trivial" implementation would probably be something like this:

Python code:
thresholds = {
    "low": (float('-inf'), 0),
    "medium": (0, 10),
    "high": (10, float('inf'))
}

def find(x: float) -> str:
    for key, (lower_bound, upper_bound) in thresholds.items():
        if lower_bound <= x < upper_bound: 
            return key
But I dislike find having to know stuff about what I feel like are the internals of thresholds. I could, instead, do this with lambdas:

Python code:
thresholds = {
    "low": lambda x: x < 0,
    "medium": lambda x: 0 <= x < 10,
    "high": lambda x: 10 <= x
}

def find(x: float) -> str:
    for key, check in thresholds.items():
        if check(x): 
            return key
but I'm not thrilled about that either, because lambdas seem like a great recipe to ensure that I get some hard-to-debug bug later on.

Naturally, I could add a custom class, perhaps along the lines of following:
Python code:
class Bounds:
    def __init__(self, lower_bound, upper_bound) -> None:
        self.lower_bound = lower_bound if lower_bound is not None else float('-inf')
        self.upper_bound = upper_bound if upper_bound is not None else float('inf')

    def __contains__(self, value: float) -> bool:
        return self.lower_bound <= value < self.upper_bound

thresholds = {
    "low": Bounds(None, 0),
    "medium": Bounds(0, 10),
    "high": Bounds(10, None)
}

def find(x: float) -> str:
    for key, bounds in thresholds.items():
        if x in bounds: 
            return key
This feels like I'm making a custom implementation of range which I dislike immensely.

Is there some part of the stdlib that I'm missing here, that would make this pattern nice and concise without going all lambda?

PEP-636 if you’re on 3.10, otherwise I would subclass dictionary to implement range checking inside dictionary key.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply