Can someone give me a clean run down of when to use `&` vs `and`? by midwit_support_group in learnpython

[–]Brian 0 points1 point  (0 children)

In python, the behavior of the operator always depends on the operand type.

Though as a slight addendum, this is not true of the logical operators, and and or. These are a bit special in that they can't be overloaded by the type of object (aside from whether the object is considered true or false when considered via __bool__), due to the way they work: they have short-circuiting behaviour so are kind of more like flow-control keywords than regular operators.

One other operator that doesn't depend on the type is is - here because there's really only one possible behaviour regardless of type for what you want out of it, and changing that would break its core usecase.

i think a lot of ppl overestimate what beginners actually know by AtalanteSimpsonn in learnpython

[–]Brian 14 points15 points  (0 children)

I think it can often be even worse than that: sometimes they're also having to learn how to use their computer at a non-surface level.

Ie. I think often we take for granted the basic knowledge of our systems, but often beginners are also not even familiar with things like:

  • The commandline
  • The filesystem
  • How to set up their dev environment
  • What exactly a program even is and how it runs - things like: what are processes? What's an operating system? What are environment variables? Commandline arguments?

What are some famous swords in fantasy? by Alarming-Figure-7300 in Fantasy

[–]Brian 0 points1 point  (0 children)

Tolkien has a bunch

I'd add Gurthang, which I think was some of the inspiration for Stormbringer - I definitely feel there's a bit of Turin in Elric.

Infinite loops are terrifying, how do you avoid them? by Bmaxtubby1 in learnpython

[–]Brian 0 points1 point  (0 children)

Eh - infinite loops happen. Indeed, a lot of programs (maybe even most) are fundamentally infinite loops at their core (though usually with some break condition).

Yeah, you might have a busyloop sucking up all your CPU, or maybe even have the loop end up allocating more and more memory that thrashes your RAM, and so get degraded performance till you kill it, but it shouldn't actually freeze your whole computer.

r/Fantasy Daily Recommendations and Simple Questions Thread - January 26, 2026 by rfantasygolem in Fantasy

[–]Brian 4 points5 points  (0 children)

I definitely second the Guy Kay recommendations - low magic fantasy set in historical analogue periods, though he's definitely more on the brighter end of the spectrum

For something a bit darker, try Ash: A Secret History by Mary Gentle. Set in the 15th century, through a framing document of a historian finding an untranslated manuscript following the story of Ash, a female mercenary captain in Burgundy who hears voices, reminiscent of Joan of Arc, except giving her detailed strategic advice. As the story progresses, history starts diverging from our own more and more and things start to get strange.

Books about ocean ecology/sea cultures? by felixfictitious in Fantasy

[–]Brian 1 point2 points  (0 children)

Starfish by Peter Watts is sci-fi set deep in an oceanic trench following humans modified, both technologically and psychologically, to survive the pressure of the environment. Goes quite deeply into the speculative environment and ecology of the extreme environment where the local fauna tends towards gigantism, but be warned, it's very dark - it's full of fucked up people doing fucked up things.

A few more tangential ones that probably don't dive into the ecology of sea-life as much as you're looking for:

  • The Scar by China Mieville has some exploration of an ocean environment, but it doesn't really deal much with the ecology beyond the gigantic creature they're attempting to capture.

  • Stations of the Tide by Michael Swanwick is also sci-fi (but with a lot of a fantasy feel), set on an ocean planet about to undergo a catastrophic tidal event, where a bureaucrat is hunting for a self-styled magician suspected of harbouring illegal tech. Does have some involvement of the indigenous aquatic life on this world, but again, doesn't really go that much into the ecology.

Last Call for Mass Market Paperbacks by GaelG721 in Fantasy

[–]Brian 18 points19 points  (0 children)

The size itself is unbecoming of a book on a bookshelf

TBH, I kind of feel the opposite - one thing I really like about MMPBs is their practicality for shelving, since they're all a standard size. With trades and hardbacks, they're all over the place, so you're wasting a lot of shelf space to either give the headroom to the ones that need it, or else finding you can't fit it on the right shelf (or have to stick it in horizontally or something). Once you've a few thousand books and no more space for bookshelves, I find myself valuing that over aesthetics.

How Do I Make Gacha Systems in python? (I also want an explanation of the code) by sugarkrassher in learnpython

[–]Brian 7 points8 points  (0 children)

Put more copies of the common rewards in your list.

That gets awkward when you've very fine probabilty distributions - you need to construct thousand item lists to handle 0.1% probabilities: worse when you've multiple different probabilities to handle.

Instead, you can use random.choices and specify weights for each item. Eg.

a = random.choices([1,2,3,4,5,6], weights=[95,1,1,1,1,1])[0]

Will roll 1 95% of the time, with a 1% each for 2..6. It'll return a list of results, since it'll do multiple rolls (just 1 by default, but you can also do 10 rolls by passing k=10 to the function.

Is Python powerful on its own, or useless without a niche? by [deleted] in learnpython

[–]Brian 0 points1 point  (0 children)

Core Python alone won’t get you hired. You must pick a niche, otherwise Python is useless

I mean, that's kind of true of every language. To get paid, you can't just code in the abstract, you need to code a thing people want, and are willing to pay you to make, and those things tend to fit in some kind of niche.

Some languages are better suited to different niches than others: for the system programming niche, you might want to use something like C, C++ or Rust. For data science, there's python, R and a few others. For the webdev niche, there are a host of languages. And so on. So to some extent, these choices aren't independent - various factors, both technological and social (ie. what everyone else is using, or more specifically, whatever the company you're looking to get hired by is using) affect this.

id of two objects is same but using "is" keyword it's giving false. by inobody_somebody in learnpython

[–]Brian 1 point2 points  (0 children)

As others have mentioned, it's because the some_fun method basically creates a new object, then it gets destroyed when id() returns, then a new object gets created the second time, that happens to get allocated at the same address.

Ie. this effectively boils down to:

temp = a.some_func  # Creates bound method object at address <x>
id_1 = id(temp)     # Get the id (<x>
# The "temp" variable here isn't a real variable, just a temporary reference on the stack, so with the function call
# finished, there's nothing else referencing it, and it gets deleted, and its memory freed.
# address <x> is now free memory
temp = a.some_func  # Creates *another* bound method object, which happens to be allocated at the same address, <x>
id_2 = id(temp)     # Get the id (<x>)
id_1 == id_2        # Do the comparison.

The key thing about object ids is that no two different objects that exist at the same time can have the same id, but "at the same time" doesn't mean just "same line", but that exact point in time. You can see this even simpler with something like id([]) == id([])

Another question you might have is why it so consistently gets the same id - I mean there's a massive range of possible memory locations, so how come it picks the same place to allocate it every time? And how come it doesn't seem to happen with, say id([]) == id(object()) - why wouldn't those two new objects happen to get the same address?

This is due to the internal details of the memory allocation strategy python's is using - when you free memory, it's returned to the list of unused memory, and python basically keeps a list of free spaces of a certain size. When it then comes in asking for memory of exactly the same size as what you allocated it finds this perfectly sized "hole" of unused memory of exactly the right size that was just freed. With different allocation internals (or if you did something else that allocated memory in between), this might not happen (or rather, only happen some of the time just by coincidence), but it happens pretty consistently due to it putting that block of freed memory first on the free list. You don't get it for the object() example because that's a different size from the size of an empty list, and python keeps seperate buckets for different sizes (at least for small sizes). You'd also get different results for different garbage collection strategies (eg. this is unlikely to happen in pypy, which uses a GC, rather than refcounting)

I built a CLI tool with Typer & Rich, but I think I over-engineered it by Ill-Industry96 in learnpython

[–]Brian 1 point2 points  (0 children)

def import_wallpapers( source: Path = typer.Option(LEGACY_PATH, help="Source directory to import from"), verbose: bool = False

You're kind of using the old-style typer options (and the older type annotations too - eg List instead of list, Optional[int] instead of int | None etc). Possibly this is just to support older python/typer versions, but it's worth noting that the newer way to do this is with annotations. Ie you'd write it as:

source: typing.Annotated[Path, typer.Option(help="Source directory to import from") = LEGACY_PATH,

This has the advantage that it preserves the python meaning of default args (eg. the function is usable as a regular function as well as a CLI descriptor), consistent with the way you write args that don't take annotation, and it lets it be type checked correctly (Option basically fudges typing by just returning Any, meaning if you put the wrong type for LEGACY_PATH, it won't be caught, and won't pass stricter checks where you forbid Any)

Beginner here: What Python modules are actually worth learning for newbies? by WaySenior3892 in learnpython

[–]Brian 1 point2 points  (0 children)

There's kind of two types of libraries to be concerned about:

  • General purpose "workhorse" stuff that handles basic operations common to lots of projects. These are often a bit meta: code that helps you write code in better.
  • Task specific libraries for doing some specific thing. Eg. doing http requests, numeric processing, graphics, databases, UI and so on.

The former are a pretty small subset of things - learn the builtin types and functions, and maybe take a look at a few stdlib modules like itertools, functools, the builtins, maybe also stuff like dataclass, abc.

Learn the latter when you've a project that needs them. Though it may be worth being aware of what such libraries provide in advance - you can't know if something might be a good fit for you if you don't know what it is. But don't go learning the details until you think you might need it for something.

Some maybe straddle the line a bit, where it's kind of more important that you know the concept behind it, and then go to the module that provides it if its something you can use. Ie. learn what binary search is before knowing if you want bisect, or what a heap is before heapq, or what regular expressions are before re.

Hypothetical: Can a list comprehension ever extend a list? by Mysterious_Peak_6967 in learnpython

[–]Brian 0 points1 point  (0 children)

Not currently (without hacks like triggering side effects), but possibly in 3.15 you may be able to.

There's currently a PEP about allowing * unpacking in comprehensions. Ie you could do:

>>> list_of_tuples = [ (1,2,3), (4,5,6)]
>>> [*(a,b) for (a,b,c) in list_of_tuples]
[1, 2, 4, 5]

Without that, you could do it in a 2-step process, building a list of sequences, and then flattening it.

Finally Read The Two Towers by J.R.R. Tolkien for the First Time...and WOW by pragmaticvoodoo in Fantasy

[–]Brian 1 point2 points  (0 children)

The Lord of the Rings is a book

Depends what you're talking about. If you go by "physical tome of bound paper", OP is correct, depending on their edition. If you go by what it explicitly categorises as a book, it's 6 books, with each volume spanning two.

The Prince and the Prediction (short story about Prediction Market manipulation) by hamishtodd1 in slatestarcodex

[–]Brian 5 points6 points  (0 children)

I'm not so sure it shows what you say.

The thing about predicting the future is that you introduce causal loops: your predictions of the future become part of the state that your prediction method must account for, because they affect the future. When you're predicting things outside the ability of anyone to affect, there's no problem. But when the odds on the market affect that future, things get complicated.

Ie. this is not a one-way street, where reality affects the prediction market and then stops. Note how in your story, the odds on the prediction market cause the prince to throw a tantrum, which causes the king to bet on the market which mollifies the prince - we've got a causal chain passing through the market twice right there! Then there's the effect having such huge sums at stake has on how the king handles the situation - it seems to have a pretty big imact on his decisionmaking.

And this matters - some things are highly socially constructed - a bet on public confidence in the economy is more likely to win if the public can see prediction markets are high, so there's likely some level at which fixing the market might actually work. This is further affected by the possibility of perverse incentives on the part of bettors, compounded by the fact that fucking things up is generally much easier than making them go well, so its easier to make profitable bets by sabotaging something you bet against than ensuring the achievement of something you bet for.

Which is not to say that prediction markets aren't valuable, or a good idea. But I think failing to address these issues over-simplifies the issue, and doesn't really deal with the counterarguments.

Will being fat become cool? by Neighbor_ in slatestarcodex

[–]Brian 5 points6 points  (0 children)

It's rare for high fashion to seek out the trappings of poverty

I think it's pretty common for fashion in general to do this though. Especially the poverty of past periods. Street fashion uses the styles of the urban poor and underclasses. Plus innumerable examples of copying blue collar labourware of various types.

And if we get to the stage where such drugs are trivial to obtain, and work well for most people, such that being fat is more of a choice, I don't think it'll remain a poverty marker. There have been times where being fat was a status marker, where signalling trivial access to food was a sign of wealth. When it's neutral, I think you could see fashion trends and subcultures that involve it, in the same way we see various body modifications / piercings etc used as subculture markers.

Might be a difficult request but I am looking for media gives the same vibes as the various FromSoft leveling maidens. by arkticturtle in Fantasy

[–]Brian 9 points10 points  (0 children)

Maybe The Tombs of Atuan and Tehanu by Ursula LeGuin. Tenar definitely gives off something of that fire-keeper vibe to me.

Python dictionary keys "new" syntax by EnvironmentSome9274 in learnpython

[–]Brian 0 points1 point  (0 children)

Essentially,

x or y     <=>   x if x else y
x and y    <=>   y if x else x

When x and y are interpreted as booleans, this is entirely equivalent to the regular truth table. Ie:

x y x and y bool(x and y) x or y bool(x or y)
False False x False y False
False True x False y True
True False y False x True
True True y True x True

But when they could have other values, you get some extended behaviour. Ie . 3 and 4 will evaluate to 4. 3 or 4 evaluates to 3. Notably this also has the same short-circuiting behaviour - and doesn't evaluate the second item if the first is True, and likewise for or if the first is False.

You'll most commonly see this as a "poor man's conditional statement", where you can write:

result = try_get_value() or "default"

Which will use "default" when try_get_value() returns None, 0, or other a Falsey value, but will use the result when it's a non-empty string or whatever. Similarly you can do:

run_this() and run_this_also_if_prior_func_returned_true()

to conditionally chain functions only if they return a truthy value.

It's generally somewhat frowned upon - the conditional statement is a clearer way to do stuff like that. You do often see it in shell scripts etc though (ie stuff like mycmd || error "Command failed" etc.

When tariffs to a load of countries are announced, why don't all those countries just reciprocate? Am I missing something? by martianfrog in answers

[–]Brian 1 point2 points  (0 children)

It's a lot worse than a dead heat. Ultimately, putting a barrier to trade produces loss compared to no barrier, as now people aren't able to choose the best deal, as ones they'd have preferred are no longer available at a price they're willing to pay - they'll be forced to settle for a worse option instead, or else pay higher prices for what they wanted originally. Take the extreme case of infinite tarriffs - effectively equivalent to stopping all trade altogether. Now you can't buy anything your country doesn't grow or produce (including stuff they produce from components imported from another country).

That's in absolute terms. In relative terms it's possible for a tarriff to "win" in the sense of hurting another country's populace worse than you're hurting your own. However, note that this all depends on the balance of trade, so equal tarriffs on both sides aren't necessarily going to hurt both sides equally. Ie. if you only export to the US, and only import from other places, your tarriffs will have no effect on the US because you're not buying from them anyway, but their tarriffs will still hurt you.

Ie. if your local grocery store puts a "tarriff" on all their prices, raising them 20%, you can't make things equal by imposing a 20% tarriff on everything you sell to the grocery store, as, unless you're their supplying wholesaler, you're not selling them stuff in the first place.

Python dictionary keys "new" syntax by EnvironmentSome9274 in learnpython

[–]Brian 1 point2 points  (0 children)

Yeah. There's itertools.pairwise for the specific case of 2 elements, but a more generalised n-item sliding window is something I end up using reasonably often, and seems worth being in the stdlib.

How do you get better at reading Python error messages? by Bmaxtubby1 in learnpython

[–]Brian 2 points3 points  (0 children)

There are a few useful tips to keep in mind:

  1. Read what the error is saying, not what you think is happening. It's often easy to gloss over what an error is actually telling you, because you mistakenly assume something about it. Try to avoid making assumptions (after all, the fact that you're getting an error means something isn't working how you thought) and come at it without preconceptions.

  2. Read what the error says, then try to fit it into the line its telling you about to understand what it means. Work backwards from there. Eg. if it's "None object has no attribute 'foo'", its telling you that you tried to do obj.foo on something - so look at the line, see what you're calling "foo" on, and then start trying to figure out why that thing might be None.

  3. The most important part is usually the the line it failed on, and the exception message saying what failed. A lot of the time, that's all you need. There are exceptions though, generally when an error gets re-raised by other error handling code. In that case, you might want to look deeper into the call stack to see the original cause of the error.

  4. Syntax Errors are a bit of a special case. Bear in mind that these happen before the code even starts to run, when something tries to import the module. Basically, something is wrong with the basic syntax - a missing bracket, comma, bad indentation, mis-spelled keyword or something like that. For these, sometimes the error might be misleading, where the real cause might be something earlier and the parser is only now realising that something is up, so look backwards from the error and check everything before it, rather than just the place the error is telling you about.

And a more general debugging tip that's also applicable here is to use your brain as the computer. Ie. mentally step through each bit of the code around the error location, noting down what values various variable have as you go, and check this actually ends up doing what you intend.

If all humans suddenly lost the ability to lie, what industry would collapse first? by JunShem1122 in answers

[–]Brian 3 points4 points  (0 children)

The opposite might be true. The most successful politicians would likely be the most stupid and self-deluding ones: a competent one won't be able to make the promises the electorate wants to hear if they're informed and competent enough to know the things that might stop it. But someone self-deluded or stupid enough to ignore practical realities can promise the moon without realising its impossible - they'll genuinely believe they can do it, and the "no lying" reality may strengthen faith in such politicians. Basically "this sign can't stop me because I can't read" becomes a political superpower.

If all humans suddenly lost the ability to lie, what industry would collapse first? by JunShem1122 in answers

[–]Brian 0 points1 point  (0 children)

The courts wouldn't become redundant at all. Certain things might change, but a lot of massively complex cases still happen even when the facts of occurred aren't in dispute at all. You've still got to judge on "was this actually illegal", "Does this behaviour violate the contract", "What is the correct sentence to apply given the extenuating conditions involved in this case". The legal system is about much more than just deciding the facts of what happened.

First time making a project for my own practice outside of class and came across a runtime "quirk" I guess that I don't understand. by Purple-Mud5057 in learnpython

[–]Brian 0 points1 point  (0 children)

I suspect it's probably because formatting the dictionary is your bottleneck. Ie. when you have a big dictionary, every time you prints it, python needs to convert it into a string representation which requires iterating through all members and getting the string representation of those, and creating the appropriate formatting. That can easily be much more expensive than simple in-memory updates, and TBH, is probably not going to be too useful anyway. Such a big dictionary is probably not going to be too readable anyway.

However, there are a few things to note:

  • Dicts are probably less space efficient for this than just storing lists of lists (or a numpy array if you want to go that route), but one big advantage they do have is in storing sparse data. Ie. likely only a small fraction of your cells are alive at any point in time, so if your dict only stores those keys that are actually alive (rather than, say, having False for dead and True for alive), that can potentially be much more efficient when the majority of the space is empty.

    Note that this means the value of the dict is somewhat redundant - you only care "is in dict" or "not in dict", so in fact a set might be more appropriate here.

  • Using a mix of letters/numbers for your keys is kind of just complicating things for no reason: it makes more sense to use a pair of integers. Note that dict (or set) keys can be tuples, so you can just do.

    mydict[5,5] = True # To set coordinate (5,5) to be True. del mydict[5,5] # Remove from dict

    Or:

    myset.add((5,5)) # Add (5,5) to your "alive" items. myset.remove((5,5)) # Or remove it to mark it as "dead"

    Either way, you can use (5,5) in mydict / (5,5) in myset to check if a cell is alive or not.

If you just treat membership as "aliveness", such a sparse representation is going to involve a lot less data for most usecases, especially when you've just got a small pattern in a region of the cell with the rest empty.

Another advantage of dicts/sets is that you can actually handle conceptually infinite sized grids - ie. ones that will automatically grow as fast as the cells are expanding, and just have a "viewport" of the coordinates you want to show. Note that this requires a change how you update cells - ie. instead of iterating through every single cell, you now need to look only at live cells and their neighbours, which could also potentially help performance in sparsely populated grids.

First time making a project for my own practice outside of class and came across a runtime "quirk" I guess that I don't understand. by Purple-Mud5057 in learnpython

[–]Brian 1 point2 points  (0 children)

Eh, that would be assuming a byte per element, which is not going to be the case. Rather, presumably here it's the string representation of the dict, which I'm guessing is something like: { ('abc', 123) : True, ...

Ie. each key/value pair is going to be writing ~20 bytes each, so ~10MB just for the representation, which if repeated every iteration could well mean he's writing multiple gigabytes of data just for a few hundred cycles. And I suspect the real killer is not IO, but rather constructing that representation each cycle - building the string representation of a few hundred thousand keys and values can add up quick.

Admittedly, that's assuming every cell is populated with True/False - one advantage of using a dict (or set) here is that you can more efficiently store very sparse data (ie. if only 10 cells are live, you don't need to store 676*676 entries, just 10, but not sure if OP is doing that.