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
baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

You might have other sites using your service (if you're providing an API), which aren't really any different from a mobile app. Also I guess it's possible that even if you only have your own frontend accessing it, people might have 'stale' pages loaded that make calls to the old API, and there's a possibility of losing data if they can't talk to the server anymore

Adbot
ADBOT LOVES YOU

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

There's two subtly different things going on there that you probably haven't noticed

Different types of object have different functions you can invoke on an instance of that object, called methods. It's like a button you can press on an object you created. So in your first example, you create a list object and then call that list's sort() method by using the dot notation - cars.sort(). You're explicitly acting on the cars list by pushing its button

In your second version you're using a standalone function called sorted(), which works sort of like a service - it does something useful, but you have to give it the object it's going to work with. Which makes sense - what are you sorting? You need to provide a list object as a parameter so it can do its thing, like sorted(cars). Your broken version didn't do that, so you weren't actually telling it what to sort

Without complicating stuff talking about self, those are the two different ways you'll work with objects - either calling methods on the object or passing them into a function, so get used to seeing it!

Knowing that lists have a sort() method that reorders your list elements in-place, or that the sorted() function takes a list and spits out a new list without changing the original one, those require familiarity by reading the documentation. So like someone said, get used to looking stuff up to see how it works - it'll also tell you what the required and optional parameters are so you can see what's possible. Definitely get familiar with Python's basic types and all the stuff you can do with them, refer to the docs often!

Here's a bunch of built-in functions - these are the things where you need to pass in any objects the function will be working with

e- beaten by my own lost post bug :negative:

baka kaba fucked around with this message at 04:58 on Mar 12, 2017

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Boris Galerkin posted:

For reasons that I can't seem to articulate, this example doesn't make sense to me as something I would do. In my mind it's pretty clear that "rotate" is a function that does the rotation. It's a function, so I would be 100% fine with calling it like a function, eg old_tensor.rotate().

code:
# Call old_tensor to rotate itself against a rotation matrix and return the rotated tensor.
new_tensor = old_tensor.rotate()

# Call old_tensor to retrieve an already rotated tensor and return it.
# ... Maybe I pre-computed the rotated tensor in __init__ for better memory management.
# ... Maybe when I called the rotate() method it also saved a copy of it for retrieval later.
new_tensor2 = old_tensor.rotated

I might be missing something, but are these meant to return the same value? Or do multiple calls to rotate() stack additional rotations, and the .rotated property just returns the last calculated one (meaning you're keeping internal state about how many rotations have been applied)?

If you're not maintaining state, and you just want that extra property to avoid recalculating the rotated version of the tensor every time you want to access it, you can just have one method and lazily calculate it - have a result variable (initially set to None), and when you call rotate(), check if the result is empty and calculate it if necessary, then return it.

Just a single method, no need to worry about whether it's already been called or not, and you can change the implementation in the class (like calculating rotations in init or allowing optional rotation matrix parameters in the rotate() call, with multiple cached values) without the callers needing to care. Newer pythons give you a free LRU cache decorator if you want instant no-worries memoization of results. This is one of the things OOP gives you, you can encapsulate state and behaviour and wall it off behind the interface - so long as the interface stays consistent, nothing outside of the class needs to know anything about how it works. You can treat it as a black box

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

You could also do next(filter(checker, generator)) if you're into that

e- whoooooops

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

You've got a few for loops in there where you repeatedly assign the same variables, so they'll end up with whatever the last value was. If you're trying to write multiple records to the CSV file, you need to write one inside the loop each time around (or store them in say a list and then write the whole lot at the end)

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

FingersMaloy posted:



I think you mean these two sections:
Python code:
		
for date_and_time in soup.findAll(class_="timeago"):
			date_posted = date_and_time.get("datetime")

for apt in soup.findAll(id="map"):
			lat = apt.get("data-latitude")
			lon = apt.get("data-longitude")
Without going back and finding the full bit of HTML, I'm trying to pull "datetime", "data-longitude", and "data-latitude" from the HTML, but I couldn't figure out how to make it happen without pulling the whole tag which has several variables and then breaking it out.

I'm going to work making the whole thing create a list and then write the list to the CSV, if I can figure that out. Thanks again all!

What I mean is you're doing a for loop, which assumes you're (possibly) working with multiple items. So in your first bit of code, you call that method that finds all the elements with a "timeago" class. Then the for loop iterates over each of those elements in turn, tries to get the value of its "datetime" attribute, and assigns that to your date_posted variable

So if you have multiple "timeago"-class elements, you'll rewrite the value of date_posted each time, and in the end it will be set to whatever the last element said, and you'll lose the previous values. If that's what you want to do, there are better ways to go about getting the last element of a sequence. If you're only expecting one "timeago" element on the page, so you'll only write to your variable once, you don't need the for loop! (plus your intent is clearer)

Python code:
# using the 'find' method which returns only the first matching element
date_and_time = soup.find(class_="timeago")
# if it wasn't found date_and_time will be None, so check before calling a method on it!
if date_and_time:
	date_posted = date_and_time.get("datetime")
Also you're doing the right thing pulling out tags and then extracting the different attributes you need, it's just what you gotta do. There are some nice tricks to help you find certain tags though, so if you ever find yourself getting a tag just so you can find another tag within it, you can probably pull out the one you want with a single find call

baka kaba fucked around with this message at 10:45 on Mar 24, 2017

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

From a quick look at the documentation extract() returns a list of things that match your selector, and extract_first() pulls out a single element

You're probably getting lists with a single item when you really just wanted the item on its own

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Wouldn't it be better to use a dictionary of allowed strings mapping to their lists? So instead of checking the line is in an allowed string, and then comparing it to those strings again by hand, you can just look up each line in the dictionary and append to its related list, with an if value or try/except bit for handling the missing lines

(Or at least use a constant if you're comparing the same string literal multiple times, for your health!)

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

The Fool posted:

I feel like I might be saying this too often at this point, but have you considered VSCode accepted Christ as your Lord and Savior

https://code.visualstudio.com/docs/languages/python

Haven't used it but this REST client extension for it might be useful too

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

laxbro posted:

Newbie question: I'm trying to build a web scraper with Beautiful Soup that pulls table rows off of the roster pages for a variety of college sports teams. I've got it working with regular HTML pages, but it doesn't seem to work with what appear to be Angular pages. Some quick googling makes it seem like I will need to use a python library like selenium to virtually load the page in order to scrape the html tables on the page. Would a work around be to first use Beautiful Soup, but if a table row returns as None, then call a function to try scraping the page using something like selenium. Or, should I just try to scrape all of the pages with selenium or a similar library?

In my experience Selenium isn't exactly fast, but really it depends on how many pages you need to scrape and how often, and also how heavy they are (like does it take a full 20 seconds for all the jabbascripts to render). In the worst case you'll have a browser window literally opening and loading the page, and you'll have code waiting and checking if it's ready yet

Honestly it depends on the pages you're loading, unless they all happen to share the same structure (these are separate sites right) you'll have to hand craft some code to pull out the relevant table on each page. Ideally that's as simple as writing a selector tailored to that page's html, but if you're doing that anyway, you might as well explicitly set the type of scraping while you're at it

I don't remember the syntax but you could make a class that takes a selector and handles normal parsing (normal GET, pulls out selector using Beautiful Soup). Then you could do a similar one that does the same, but loads the page with selenium, keeps trying to find the element described by the selector (might not be in the DOM yet), and eventually times out

That way you have two basic kinds of behaviour, and you can list all your sites as Normal(url, '#cool-table') or Webdev(url2, '.stuff > table') and iterate over them calling the parse method on each. This might not be the best design but it's pretty simple if it works for you?!

Also I forget but you might be able to just get away with using Selenium and running its selector functions (which are a lot like Beautiful Soup's) on plain http responses, so no need for BS in that case. Also Selenium was a real pain last time I used it, they updated something so the Firefox webdriver wasn't included anymore and everything broke. There might be a better scraper out there?

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

CheckIo is pretty great for problems once you get into it. I tried HackerRank for a bit with Java 8 and some of the questions were shockingly bad, like they were taking community submissions with no quality control. No idea what the Python section's like though!

But those kinds of things tend to be isolated problems, Eela's suggestion is good because you get practice actually designing and building an application in Python, working with classes and messing with command-line args and whatever else. So you're ready to just dive in and build whatever the interviewer wants, without being unfamiliar with some of the basic language stuff

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

pathlib is cool, Path.iterdir() is not because it's not sorted. Is there a natural sort I'm missing (where 'file2' < 'file10') or do I need to screw around parsing numbers from filenames here

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

HardDiskD posted:

How does it deal with a folder that has file1, file9, file10 and so on?

Badly, I was using sorted() until I realised my data was out of order, tracked it down to the files coming in all file1, file10, file11. That's why I was hoping a natural sort was lurking in the standard library :bahgawd:

Oh well, maybe I can work around it with that split tuple suggestion up there, thanks! It just feels bad because it's brittle and Windows does natural sort ordering, missed opportunities

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Cheers Eela! I ended up doing a regex to grab the digits and everything else from the filename, but it's good to see other solutions because it feels like there should be a neat way of solving it in general

HardDiskD posted:

Just had a quick glance at it, but you could use os.path.splitext to check the file extension. use the suffix property from Path.

Yeah that and stem are handy (I've been messing around in that drat library for a couple of days)

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Vivian Darkbloom posted:

I wish I had any completed applications to port! I've been messing around with small projects so I won't have nothing to show off, but I have not been great, historically, at finishing personal projects.

Hell it's less about finishing them and more about starting them - I'm just thinking of an interview situation where they want you to model some data where you need a class, or they want a basic command-line tool that handles arguments, or they want you to to create a simple utility library where you only expose certain functions. Are you comfortable hitting the ground running with that stuff?

A lot of problem sites are more like 'here's some input and your function needs to provide a result' and you just write a function or two - which is great, but it doesn't touch on the design side of things too much. So I was just thinking it would be good to do some stuff where you have to handle that side of things, just for the practice and so you're not lost if they start expecting that kind of thing

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Oh yeah, that's swish as hell

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

End?

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Your first version should be fine, you just need to realise that find_all returns a list (even if there's only 1 or even 0 results). So once you get your list of matching elements, then you need to pull out the data you want from each of them, like with a for loop or a list comprehension


Python code:

symbols = [x.attrs['data-symbol'] for x in soup.find_all("a", class_="Fw(b)")]

This assumes the attr is always present, if you want safety you should use the get method on the attrs dictionary and handle the None values, or filter your find/select so it only returns elements with that attr, something like that. CSS selectors are great

baka kaba fucked around with this message at 12:12 on May 6, 2017

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

That doesn't have the id you're looking for though? Like Munkeymon says the <tr> elements you're looking for have been commented out

Go to the page, hit f12 to open your browser's web developer tools, and do a search on the source with ctrl+f or whatever. You can search by CSS selector, so look for #per_minute.2016 and it won't find anything, because there's no element with that id. Then try it without the # (so you're just searching for plain text) and you'll see where it's gone

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

ButtWolf posted:

It's not commented out when I inspect it. Looks like regular old code. I see the same thing commented out, but then the actual code.


I click on View Source, ctrl f, per_game.2016 It's there.

edit: but per_minute ones are commented out! That's the confusion between us. only the per_games are there.

Oh sorry, my bad, Chrome doesn't seem to like searching for an id selector with a . in the name :shobon:

But yeah they're doing some silly stuff with the html, your only option really is to get around it. Don't worry, same thing happens to me whenever I see some F# 'type providers are awesome!' article, so I try and use it to scrape a site and yep... they did something to make the easy way impossible

Munkeymon's comments idea is probably easiest - grab all the comments, iterate over them looking for the id bit, when you find the comment with that make it a document and then select the element. Stick that in a function and you can just change that one line in your script to call the function instead. Selenium's pretty straightforward once you get the webdriver installed, its API is a lot like BeautifulSoup and honestly it's worth learning, this won't be the last site you run into that needs to javascript to render the page

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Sounds like it's not installed properly. Did you actually install it to System32?

Anaconda includes Python and when you install it you can choose to make it the default Python installation for the system - so whenever you run python bla.py it'll use the one in your Anaconda folder and have access to all the packages you installed there etc. Personally I'd just uninstall it and try again, following these instructions - I think the default install location is under AppData

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

I don't know anything about their special shell, I have it added to my $PATH (there's like 3 folders) and I just use the normal command line

By the way have they got around to making activate actually work in PowerShell yet? They've been sitting on that issue for years and now it's the default shell in Windows 10 so it would be nice if they could get around to it

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Because it's the default shell so it would be nice if it Just Worked

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

^^^ :v:

LochNessMonster posted:

Awesome, that is exactly what I need. I haven't come across the conn, cur = connect_to_db() before. Does this mean that whenever conn or cur are used below that line, it'll run the connect_to_db() function to get those variables filled? Not sure if I should call them variables, they're more like connections/handlers right?

connect_to_db() returns 2 values, as a tuple (you don't explicitly need parentheses, it's the comma separation that does it). When you do conn, cur = connect_to_db(), you're unpacking the two values in that tuple and assigning them to those two variables. There's basically two things coming out, so you can specify a pair of variable names to assign to

And those names are variables, they just point to objects representing a particular connection etc. What you want to call them depends on whether you're talking about the variable itself (if its value changes) or the thing it represents (if you assign it once and just want to refer to that specific thing). So in this case I think calling them variables makes sense, since you're specifically talking about assigning a value to the label. You'd probably just call it a handler after that though, since you're talking about what it represents now

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

No you fool they're too powerful!!

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Seventh Arrow posted:

2) I'm still kind of new to programming and there's a lot of stuff to take in/remember. I assume that people usually don't just code things from scratch - do you keep cheat sheets around or what?

This depends what you're doing - generally yes, you code things from scratch, but because there's a bit of 'boilerplate' (stuff you have to keep writing, like the __main__ function, or class definitions, etc) then you might want to create some templates. IDEs and fancy editors can often generate 'snippets' that are like smart templates for things where you can tab between the parts you need to fill in. That said, Python isn't as verbose as something like Java so there isn't as much need for it. Look at your IDE/editor and see what it offers! There's code completion too, much less typing for you

The other side of not coding things from scratch is using libraries - learning what's available and not reinventing the wheel. A lot of projects involve bolting together a few useful libraries and writing the code to do something with them. And again, if you keep making the same kinds of projects over and over (say a web server, or a twitter bot) you might want to create some skeleton projects with that basic setup already done, or a module that you can import with all that stuff in it

There can be more than that (applications that generate basic projects for you, or repositories you can basically clone and get building on top of) but it depends on the language

Best recommendation I can give you for remembering stuff is to get familiar with the docs. Whenever you find yourself wanting to do a thing (like manipulating a string in some way), go look at the docs for that type or module and see what methods and functions it offers. Even if you don't find something you need, you'll probably see some cool useful stuff. A lot of learning to program in a language is getting familiar with the standard library and what it can do for you

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

One day you'll reach a point where all the Google results are for 3.x docs no you won't

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT


:thumbsup:

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

It's like with decimal, you can do however many tenths and hundredths and so on you like, but there are some numbers you just can't represent perfectly, like 1/3. You can get close, and the more decimal places you have the less it matters, but eventually you run out and have to settle for 0.3333333, which is as accurate as you're gonna get in base 10

Base 2 has similar issues, just with different numbers - your fractions have to have a denominator that's a power of 2 instead of a power of 10, and that's a no-go way more often

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

When you get down to the low levels and it's all discrete values like energy quanta... can some numbers even exist? #whoa

I say we ban these false numbers

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Nippashish posted:

Floating point weirdness is also one of those topics that programmers love to expand on at length when it comes up (I'm slightly surprised no one has warned you about storing currency in floats yet) and my suggestion to "not worry about it" should be taken in the context of your post triggering a page of responses. The fact that you went away from the discussion with the impression that you should "watch out" when using floats is exactly what I was trying to mitigate.

But you should worry about it though? To the point that you're aware that there are some basic pitfalls, and then keep them in mind when you're using floats. The poster you're replying to was already not worrying about it, that's why they hit a problem and had no idea what was going wrong

I mean yeah, the other extreme is the 'you can't trust floats' one, where people pretend they're full of gremlins adding random inaccuracy when your back is turned, but that's not the same as being wary and knowing what does and doesn't work

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

On the other hand, if those tiny floating point inaccuracies are leading to your results being 10% out, you definitely need to know what's up

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

LochNessMonster posted:

I thought I had a pretty easy use case: figuring out how long and on which intervals my script should run.

Is that an unusual way to calculate it, and if so what would a regular way of solving that be?

There's nothing wrong with what you were doing (and the results you were printing were still correct to a very high accuracy) - you just need to be aware that you might get some awkward numbers. Really what you needed to do was format your print output to a fixed number of decimal places, that's all, same as you would if you were doing some awkward division where you knew the answer would be like 7.4042780206425627001183

For other stuff, it really depends. If you're doing a test and you want to compare a result to an expected answer, and that answer is the result of a particular calculation (like a ratio), you can perform that calculation and compare to that instead of the literal result you expect. That way your expected answer will have the same error as the actual answer (because they represent the same floating point calculation) and they'll be equal

If your expected answer is a little harder to express, and you want to just say what the value you expect is, accept that the actual answer might not be exactly what you're looking for, but within a certain tolerance - like a real-world measurement. Usually in that case you'd specify an acceptable error amount and make sure the difference between the expected and actual answers doesn't exceed that

There's a python section on this stuff and it gives you some handy ways to deal with all these things

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Dunno about the C stuff but you're repeating a few calculations in there

Python code:
def wait_time(self, time_seconds):
        current_x1 = self.x1
        current_x2 = self.x2
        current_x3 = self.x3
        current_xeo = self.xeo

	x1k10 = current_x1 * self.k10
	x1k12 = current_x1 * self.k12
	x1k13 = current_x1 * self.k13
	x2k21 = current_x2 * self.k21
	x3k31 = current_x3 * self.k31

        self.x1 = current_x1 + (x2k21 - x1k12 + x3k31 -x1k13 - x1k10) * time_seconds
        self.x2 = current_x2 + (x1k12 - x2k21) * time_seconds
        self.x3 = current_x3 + (x1k13 - x3k31) * time_seconds
        self.xeo = current_xeo + (-self.keo * current_xeo + self.keo * current_x1) * time_seconds
And you could cut it down a bit more (maybe it's getting less readable here)
Python code:
def wait_time(self, time_seconds):
	# skipping the temp variables
	x1k10 = self.x1 * self.k10
	x1k12 = self.x1 * self.k12
	x1k13 = self.x1 * self.k13
	x2k21 = self.x2 * self.k21
	x3k31 = self.x3 * self.k31

        self.x1 = self.x1 + (x2k21 - x1k12 + x3k31 - x1k13 - x1k10) * time_seconds
        self.x2 = self.x2 + (x1k12 - x2k21) * time_seconds
        self.x3 = self.x3 + (x1k13 - x3k31) * time_seconds
	# factoring out self.keo so you multiply once
        self.xeo = self.xeo + self.keo * (self.x1 - self.xeo) * time_seconds
It might run a little faster (also make sure I didn't mess it up!)
You might want to look into memoisation too, if that's appropriate to what you're working with

e- thanks code formatting, I ain't fixing that

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Loving Africa Chaps posted:

So it's a 3 compartment pharmacokinetic model. I have a 600 patient dataset where i'm modelling the predicted concentration in the central compartment (x1) and seeing how it matches up to the model.

Uh yeah definitely check my working pls and thx :v:

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Mirthless posted:

Thanks, that's heartening at least.

I knew I needed to learn and practice with classes more and this was all due for a rewrite anyway, back to the drawing board

You've got a fairly complex system going on here, you need to be able to break it down into useful generic parts you can bolt together, and handy functions that hide the mechanics and make your objects easier to work with. Ideally you'll avoid repeating the same bit of work in multiple places, and you'll abstract it to a single function that everything calls with some parameters

Being able to do this takes experience, you need to spot patterns and be aware of how you can abstract them and what classes can do for you. Really you just need to dive in and try it, maybe with a simpler example (like just a human or whatever) and see how you can improve it. It won't be perfect, but realising why means you'll do better next time - That's Programming :frogbon:

And your code looks fine, you're just bumping up against the limitations of what you know and it's getting a bit complex. There has to be a better way!

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

I'll give you one tip though - those places where you're using a string literal like 'sword' or whatever? Any value you're going to reuse, add it as a constant somewhere (like SWORD = 'Sword') so you can refer to SWORD in your code for key lookups and comparisons and the like

That way you can't make a typo without python going 'hmmm dunno what a SWARD is explain yourself', whereas a typo in a string literal will pass silently and cause problems until you discover it. Also helps with refactoring like renaming (only one place to change it) and code completion

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

^^^ or if there's a library, hell yeah. I always forget about dictionaries :shobon:

Does the structure vary or get more complex than that? If it's just a bunch of objects holding arrays you might as well just do a keys, values for loop

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

QuarkJets posted:

It's fine code but I'd have written it like this:

code:
	with open(self.ini_path, 'w') as ini:
		ini.write('[{key_name}]\n{val_names}\n'.format(
				key_name=key, 
				val_names='\n'.join(val)))
but with better indentation (4-spaces instead of whatever the forums is expanding tab to)

You can do this too

Python code:
with open(self.ini_path, 'w') as ini:
    for k, v in json.items():
        print(k, *v, sep='\n', end='\n\n', file=ini)
f-strings are nice too but apparently you can't have backslashes in the expressions, so no one-liner with "\n".join(v) :ohdear:

Adbot
ADBOT LOVES YOU

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Might be a bit complicated if you're using predicate functions, but singledispatch is an option too

Python code:
from functools import singledispatch
import re

@singledispatch
def find_thing(arg):
    print('finding a whatever this is! Or not!')

@find_thing.register(int)
def _(arg):
    print('finding an int!')

@find_thing.register(tuple)
def _(arg):
    print("it's a tuple!")

@find_thing.register(re._pattern_type)
def _(arg):
    print("it's a regex! You monster")

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