12

You seem to be jumping through some unnecessary hoops. Just format a string directly: from timeit import timeit def _channel_to_hex(color_val: int) -> str: raw: str = hex(color_val)[2:] return raw.zfill(2) def rgb_to_hex(red: int, green: int, blue: int) -> str: return "#" + _channel_to_hex(red) + _channel_to_hex(green) + _channel_to_hex(...


11

Your code can be simplified using a simple loop, eliminating most of the duplicated code: def game_of_cups(zipcode, rules): total_points = 0 for num, rule in enumerate(rules, 1): rule_passes = rule(zipcode) points = num + 4 if rule_passes else 0 total_points += points print(f"Rule {num} got {points} points, so total ...


10

Welcome to code review, and good job for your first program I suppose. Style Docstrings: Python documentation strings (or docstrings) provide a convenient way of associating documentation with Python modules, functions, classes, and methods. As you can see, even for a relatively simple function, documenting using comments quickly makes it unpleasant and ...


9

Your app function is just the same as the print function. So there is no need for it to exist at the moment. When working with files you should always use the with keyword to ensure the file is properly closed (even in the case of exceptions). The pathlib module has a Path object which makes handling file paths a lot easier. You are doing a lot of ...


7

Another approach to generate the hex string is to directly reuse methods of format strings rather than writing your own function. rgb_to_hex = "#{:02x}{:02x}{:02x}".format # rgb_to_hex(r, g, b) expands to "...".format(r, g, b) rgb_tup_to_hex = "#%02x%02x%02x".__mod__ # rgb_tup_to_hex((r, g, b)) expands to "..." % (r, g, b) These are faster (...


5

memoization The _channel_to_hex is called 3 times per pixel. It only takes 256 different inputs, so a logical first step would be to memoize the results. This can be done with either functools.lru_cache from functools import lru_cache @lru_cache(None) def _channel_to_hex(color_val: int) -> str: raw: str = hex(color_val)[2:] return raw.zfill(2) ...


4

Numpy is your best friend. Given your comment: The tuples are produced by "color scheme" functions. The functions take the (real, imaginary) coordinates of the pixel and how many iterations it took that pixel to fail, and return a three-tuple. They could return anything to indicate the color (that code is completely in my control), I just thought a three-...


4

Type hints The parameters to your MazeSolver.__init__ should get type hints, particularly for things that don't have defaults. For instance, maze_path: str. Separate input You shouldn't be calling input from __init__. Just accept it as another parameter, and do the input and validation at a higher level. In-band logic Baking 'a' as a special condition ...


4

First, there's very little point in using a class like you are here. You're essentially just using the constructor as a function to ask for input. You're also needlessly making some variables attributes of the object, like self.features, self.x, and self.d. The only use of features is to be iterated over within the constructor, and the only use of the latter ...


4

"""DocStrings""" +1 for adding a doc string to the wordBreak() method, but -1 for not having any content in it. PEP-008 Your code diverges from the PEP-008 guidelines in several areas: Use snake_case for functions and variables, not mixedCase. Use a single space around operators (elif i > len(s):), not 2 spaces, and then no spaces. Add a blank line ...


4

Just a modification on AJNeufeld's def game_of_cups(zipcode, rules): for num, rule in enumerate(rules, 1): points = rule(zipcode) total_points += points ... def rule1(zipcode): return 5 if (zipcode[0] == zipcode[-1]) else 0 def rule2(zipcode): a, b, c, d, e = map(int, zipcode) return 6 if (b == 2 * a and c > min(b, d)) else 0 ... ...


3

I see two race conditions. When you write the file, two processes may write it at the same time and one entry will be lost. Between reading the user list and adding a new user, i.e. in the time when the user chooses a password, another process could add the same user, so the user is added twice even when you checked that the user is not in the list when ...


3

counter = Counter() for string in strings: for char in string: counter[char] +=1 You are flattening your strings list to count each individual characters. For starter, if you were to extract letters individually, you could feed it to the Counter constructor and avoid the += 1 operation. Second, flattening an iterable is best done using itertools....


3

Ignoring threading, it's usually best to benchmark your code on a single thread first, then move to multiple threads as necessary. Some glaring things that could yield slower performance: You are not using a Session for requests. There is not a guarantee that sessions are thread-safe, but you could allocate a session for each thread, giving each thread it's ...


3

Whitespace formatting Apply a linter that will give you PEP8 suggestions. Among other things, it will suggest the following: import os,gc,queue There should be spaces after those commas. It'll also suggest that there be one line per import. class add_line: should be class AddLine: and have a couple of newlines before it. else : shouldn't have a ...


3

Using @classmethod for constructors is perfectly fine. It is basically the only reason you ever need to use them. Classes create a namespace (and Namespaces are one honking great idea -- let's do more of those!). You don't need to preface all your methods and classes with my_. Your code becomes much more readable if you just name them according to what they ...


3

Python compilers for performance Nuitka Nuitka compiles any and all Python code into faster architecture-specific C++ code. Nuitka's generated code is faster. Cython Cython can compiles any and all Python code into platform-indepndent C code. However, where it really shines is because you can annotate your Cython functions with C types and get a ...


3

Personally, I think it's excessive to have a function for each of the rules. IMO, if you only need the function in a single context, you probably don't need to make a function out of it unless it's sufficiently complex to warrant one - and even then, make sure it's "private." Because the values for the rule set start at 5 and simply increment in value from ...


3

I think this is a beautiful opportunity to put them all in a dictionary. """ RULES +5 when first and last digit match +6 when second digit is twice the first AND third digit is greater than second or fourth digit +7 if any 7 is in the zipcode +8 when there's no "13" in MIDDLE the zipcode +9 when all three middle digits match +10 when ...


2

I disagree on you with the need for a wrapper around the stdlib argparse, but that's a matter of taste. And I don't see anything wrong with your implementation of the rather thin wrapper. Classmethod as Constructor This is NOT what you're doing. A constructor creates an instance in a way somehow different from the standard and returns it. An example: ...


2

Like other answers, this one uses a separate function for each rule. Unlike the others it automatically collects the rules, so you don't need to keep a list or dictionary of all the rules. Each function implementing a rule has a name that matches a pattern -- it ends with "_rule". calculate_score() the scans globals() looking for the names of functions ...


2

Your code is a straight-line solution to a straight-line problem. So congratulations! You are off to a much better start than you might feel. Here are some obvious issues: Why did you separate your docblock from your code? And why is the rationale not included in the docblock? One of the ways to become a better programmer is to try to show empathy to "...


2

An empty container like a list or deque is False, so it isn't necessary to use len() on them. This is more "pythonic" while queue: ... if not adjacency_nodes: ... It seems wasteful to add a path to the queue only to discard it because it is too long. It would be better to check the length before making a copy of the path and adding it to ...


2

I'll show an example implementation first, and then describe it: from typing import Iterable import re def case_rank1_naming(proteins_available: Iterable[str], best_match_protein_name: str) -> str: # extract the three-letter pattern protein_pattern = re.search(r"[A-Z][a-z]{2}", best_match_protein_name).group() # extract the numbers ...


2

Instead of creating an empty list and appending the values to it, try using list comprehension. so instead of y_location = [] x_location = [] for each in range(-size, size+1): y_location.append(parabola(each, size)) x_location.append(each) try y_location = [parabola(each,size) for each in range(-size,size+1)] x_location = list(range(-size,size+1))...


2

A very short review, as I don't have the time for a more extensive one. Enumerate Some things I see right off the bat is range(len()). Instead of writing this, consider using enumerate. This will allow you to work with any iterable, not just countable, indexable objects. Unnecessary else I see this piece of code next: if needle_output == None: ...


2

It took me a few reads to understand what's going on here, but I think I do, now. You're best to separate this into at least two parts: one part that generates the percentage and alignment result, and one part that applies the max function to get the best percentage-result tuple. This can be done easily with a function that yields whenever it gets such a ...


1

The stuff with counter_one and counter_two is rather oblique, and it seems that it would break if someone were to choose the same password as someone else (or username, but you do have safeguards against that). If I understand what you're trying to do correctly, you could just do account_match = any([(f"'{user_name}'" in line) and (f"'{password}'" in line) ...


1

Threading I'd like to join the others in recommending you drop your threading. You're also doing it wrong - you're only grabbing the semaphore for creating the thread, but you never acquire it inside of the thread when executing. If you use a lock of semaphore, do it with a context manager: with my_semaphore: # code... And if you can't, you're doing ...


1

I suggest some correction and simplification of your update method. Result: def update(self, rate=1, **kwargs): self_dict = asdict(self) self_dict.update(kwargs) for k, v in self_dict.items(): if k != 'sale': v = self.round(v * rate) setattr(self, k, float(v)) Explanation: The rate = kwargs.get('rate', 1) can be replaced to the rate=...


Only top voted, non community-wiki answers of a minimum length are eligible