| Conditions | 14 |
| Total Lines | 60 |
| Code Lines | 39 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like euler.start_problem() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | """ |
||
| 28 | def start_problem(selection): |
||
| 29 | """ Create a template solution Python file for a selected Project Euler problem |
||
| 30 | |||
| 31 | The Python file will be populated by the problem description and boilerplate needed by this project. |
||
| 32 | """ |
||
| 33 | |||
| 34 | template = _load_templates() # load templates for Python and rst files |
||
| 35 | |||
| 36 | # Ask user for the problem number (if it wasn't specified on command line) |
||
| 37 | if selection is None: |
||
| 38 | selection = input("Select a problem: ") |
||
| 39 | |||
| 40 | # Parse the specified problem number |
||
| 41 | err_msg = "Error: you must enter a positive decimal number." |
||
| 42 | try: |
||
| 43 | problem_number = int(selection) |
||
| 44 | except ValueError: |
||
| 45 | print(err_msg) |
||
| 46 | return |
||
| 47 | if problem_number <= 0: |
||
| 48 | print(err_msg) |
||
| 49 | return |
||
| 50 | |||
| 51 | # Fetch the problem URL |
||
| 52 | url = "{}problem={}".format(BASE_URL, problem_number) |
||
| 53 | with urllib.request.urlopen(url) as fp: |
||
| 54 | soup = BeautifulSoup(fp, "html.parser") |
||
| 55 | |||
| 56 | # Extract the problem title, capitalise it |
||
| 57 | title = soup.find("h2").text |
||
| 58 | title = " ".join([word if word.isupper() else word.title() for word in title.split(" ")]) |
||
| 59 | |||
| 60 | # Extract the problem statement |
||
| 61 | problem = soup.find("div", attrs={"class": "problem_content"}) |
||
| 62 | paragraphs = problem.text.split("\n") |
||
| 63 | problem_statement = "" |
||
| 64 | for paragraph in [paragraph for paragraph in paragraphs if paragraph != ""]: |
||
| 65 | problem_statement += wrap(paragraph, 0, 120) |
||
| 66 | problem_statement += "\n\n" |
||
| 67 | problem_statement = problem_statement.rstrip("\n") |
||
| 68 | |||
| 69 | problem_statement = problem_statement.encode("ascii", "ignore").decode() |
||
| 70 | |||
| 71 | # Write the problem templates (if they don't already exist) |
||
| 72 | path = _build_template_paths(problem_number) |
||
| 73 | if not os.path.exists(path["py"]): |
||
| 74 | with open(path["py"], "w") as op: |
||
| 75 | uline = "=" * len("Project Euler Problem {id}: {title}".format(id=problem_number, title=title)) |
||
| 76 | op.write(template["py"].format(id=problem_number, title=title, underline=uline, problem=problem_statement)) |
||
| 77 | else: |
||
| 78 | print("Error: {} already exists.".format(path["py"])) |
||
| 79 | return |
||
| 80 | if not os.path.exists(path["rst"]): |
||
| 81 | with open(path["rst"], "w") as op: |
||
| 82 | op.write(template["rst"].format(id=problem_number)) |
||
| 83 | else: |
||
| 84 | print("Error: {} already exists.".format(path["rst"])) |
||
| 85 | return |
||
| 86 | |||
| 87 | _fetch_downloads(problem) |
||
| 88 | |||
| 219 |