The Software Engineering Rule of 3
erikbern.com
erikbern.com
Of course there are many other places such as the mentioned C2: http://wiki.c2.com/?RuleOfThree , my point is just that the Erik authoritatively says he is postulating it, but it's already all around the internet.
It's kind of fortunate that it worked out this way; I like seeing people comment on a well-established idea as if it's newly postulated.
Also, I have misused rip-off here; I didn't mean to say you defrauded/cheated/stole anything, just that it's an old idea already going around. I apologize for incorrectly using this verb and accusing you of ripping off this idea.
If you want to be able to build something that works with any bank ever, then you need to think from a higher level: you have a login operation that creates a session, and then a fetch-statement operation (that takes the session as a parameter), and so on, and those are your general building blocks that make up your interface.
No, you may not get it perfectly correct, and you may need to rethink and refactor at some point if you come across something different from what you could imagine. But that's not really a big deal, and you shouldn't be so afraid of refactoring that your go-to strategy is to always copy and paste similar code everywhere.
The awareness of this sort of thing perhaps isn't inherent; it comes with experience, but I don't think the take-away is to shy away from general functions. I've found that it makes things easier in the long run to think in terms of high-level operations and interfaces that you implement. Clean APIs aren't just for customers; you should architect your own "internal" code in the same way as if you intended to make it a public interface that random people could use. There's certainly a pitfall in trying to make things too generic, but after a while you develop an intuition around finding where the best balance lies.
Having a generic callback interface exec(Map(object,object)) is ugly, but better than changing 76 upstream and downstream modules' interfaces with code ownership and release cycles across different vendors/organizations.
https://erikbern.com/2017/08/29/the-software-engineering-rul...
to get site that's a little easier to read in a desktop browser.
It seems like nobody wants to build a function to do the thing thats needed, they have to build an abstraction or a framework.
Seems like this will be true regardless of the number of units we're breaking down at. There can always be a new outlier later, and trying to predict future use cases is usually a losing battle. It's not like you can't refactor yet again later.
In this case almost none of the lines contain any superfluous information. At best you could try to simplify things slightly by writing it as follows:
class ChaseScraper:
def __init__(self, username, password):
self.credentials = {'username': username,
'password': password }
def scrape(self):
session = requests.Session()
sessions.get('https://chase.com/rest/login.aspx', data = credentials)
sessions.get('https://chase.com/rest/download_current_statement.aspx')
class CitibankScraper:
def __init__(self, username, password):
self.credentials = {'user': username,
'pass': password }
def scrape(self):
session = requests.Session()
sessions.get('https://citibank.com/cgi-bin/login.pl', data = credentials)
sessions.get('https://citibank.com/cgi-bin/download-stmt.pl')- actually identical, but by coincidence
- perceptually identical, but not
- perceptually identical, but technically unrelated
- arbitrarily different in special cases
Instead of waiting until the third, I evaluate by asking myself if the duplication is accidental, how likely is it for the next instance to be different, and what will any extra arguments look like. If it doesn't feel right I leave the repetition.
#1 – It should be swift and easy to extract code, if not that's a different problem.
#2 – You need to be patient and research ahead. You don't really have an option if you're in a big project. You get used to it.
The problem is really: we're allowing the requirements to change just because it seems possible (in software). But it leads to crappy code. Managers should understand this.
Software is so tremendously successful because it's much easier to adapt it to changing requirements.
>seems possible
but in software a better statement is that it is possible. Once you've built a bridge you can't just raise all its base pillars by half a meter, but leave everything else the same. I mean there is literally no physical way to 'change one line of code'. Someone would have to go out there and start tearing it apart or doing something physically.
In software you can certainly do that: that doesn't mean it's a good idea. But if you have good test coverage and a good architecture it's even possible for nothing to break.
So it's not that it seems that way - it is that way. There are people running popular, live applications who SSH into production and change a line of code that changes live behavior. Every day this happens.
So it's not just that it seems possible. It is possible. Software is just different from architecture, or the automotive industry in that regard.