Returning zero on edge cases is incorrect, fixed it.
def Calculator(*args): operators = { '+': lambda a, b: a + b, '-': lambda a, b: a - b, '*': lambda a, b: a * b, '/': lambda a, b: a / b if b != 0 else float('inf') } if len(args) != 3 or str(args[0]) not in operators: return float('nan') operator, operand1, operand2 = args return operators[operator](operand1, operand2)
- def Calculator(*args):
- operators = {
- '+': lambda a, b: a + b,
- '-': lambda a, b: a - b,
- '*': lambda a, b: a * b,
'/': lambda a, b: a / b if b != 0 else 0- '/': lambda a, b: a / b if b != 0 else float('inf')
- }
- if len(args) != 3 or str(args[0]) not in operators:
return 0- return float('nan')
- operator, operand1, operand2 = args
- return operators[operator](operand1, operand2)
import codewars_test as test import random from math import isnan inf = float('inf') nan = float('nan') @test.describe("Sample tests") def sample_tests(): test.assert_equals(Calculator("/", 1, 0), inf) test.assert_equals(Calculator("+", 42, 11), 53) test.assert_equals(Calculator("-", 6, 50), -44) test.assert_equals(Calculator("/", 32, 2), 16) test.assert_equals(Calculator("*", 25, 5), 125) test.assert_equals(isnan(Calculator(123, 2)), True) operators = ['+', '-', '*', '/'] @test.describe("Random tests") def random_tests(): for _ in range(2000): operator = random.choice(operators) num1 = random.uniform(0, 1000) num2 = random.uniform(1, 1000) description = f"Operator: {operator}, Num1: {num1}, Num2: {num2}" expected = float(eval(f"{num1}{operator}{num2}")) test.assert_equals(Calculator(operator, num1, num2), expected, description)
- import codewars_test as test
- import random
- from math import isnan
- inf = float('inf')
- nan = float('nan')
- @test.describe("Sample tests")
- def sample_tests():
test.assert_equals(Calculator("/", 1, 0), 0)- test.assert_equals(Calculator("/", 1, 0), inf)
- test.assert_equals(Calculator("+", 42, 11), 53)
- test.assert_equals(Calculator("-", 6, 50), -44)
- test.assert_equals(Calculator("/", 32, 2), 16)
- test.assert_equals(Calculator("*", 25, 5), 125)
test.assert_equals(Calculator(123, 2), 0)- test.assert_equals(isnan(Calculator(123, 2)), True)
- operators = ['+', '-', '*', '/']
- @test.describe("Random tests")
- def random_tests():
- for _ in range(2000):
- operator = random.choice(operators)
- num1 = random.uniform(0, 1000)
- num2 = random.uniform(1, 1000)
- description = f"Operator: {operator}, Num1: {num1}, Num2: {num2}"
- expected = float(eval(f"{num1}{operator}{num2}"))
- test.assert_equals(Calculator(operator, num1, num2), expected, description)
5/9 and 9/5 are constant values, so no need to calculate them each time.
It still has a problem - it calculates both conversions for every convertion != "both"
five_ninths = 5 / 9 nine_fifths = 9 / 5 def temperature_converter(temp: float, conversion='both') -> float: celsius = round((temp - 32) * five_ninths, 2) fahrenheit = round(temp * nine_fifths + 32, 2) conversions = { 'celsius' : celsius, 'fahrenheit' : fahrenheit, 'both' : f"{celsius}c, {fahrenheit}f" } return conversions[conversion]
- five_ninths = 5 / 9
- nine_fifths = 9 / 5
- def temperature_converter(temp: float, conversion='both') -> float:
celsius = round((temp - 32) * (5 / 9), 2)fahrenheit = round((temp * 9/5) + 32, 2)- celsius = round((temp - 32) * five_ninths, 2)
- fahrenheit = round(temp * nine_fifths + 32, 2)
- conversions = {
- 'celsius' : celsius,
- 'fahrenheit' : fahrenheit,
- 'both' : f"{celsius}c, {fahrenheit}f"
- }
- return conversions[conversion]
#is_palindrome=lambda s:(s:=[*filter(__import__('re').compile('[a-z]').search,s.lower())])==s[::-1] #import re;is_palindrome=lambda s:(s:=[*filter(re.compile('[a-z]').search,s.lower())])==s[::-1] import re expr = re.compile('[a-z]') def is_palindrome(s): return (s:=[*filter(expr.search,s.lower())])==s[::-1]
import stringdef is_palindrome(s: str) -> bool:forward = s.lower().replace(" ", "").translate(str.maketrans('', '', string.punctuation))reverse = forward[::-1]if forward == reverse:return Trueelse:return False- #is_palindrome=lambda s:(s:=[*filter(__import__('re').compile('[a-z]').search,s.lower())])==s[::-1]
- #import re;is_palindrome=lambda s:(s:=[*filter(re.compile('[a-z]').search,s.lower())])==s[::-1]
- import re
- expr = re.compile('[a-z]')
- def is_palindrome(s):
- return (s:=[*filter(expr.search,s.lower())])==s[::-1]
Try to make it shorter!
def x(s,p):s.c=('No','Yes')[len(p)and not sum(map(ord,p.lower()))%324] KumiteFoo=type('KumiteFoo',(),{'__init__':x,'solution':lambda s:s.c})
class KumiteFoo:def __init__(self, p):self.condition = ('No', 'Yes')[len(p) and not sum(map(ord, p.lower())) % 324]def solution(self):return self.condition- def x(s,p):s.c=('No','Yes')[len(p)and not sum(map(ord,p.lower()))%324]
- KumiteFoo=type('KumiteFoo',(),{'__init__':x,'solution':lambda s:s.c})
class KumiteFoo: def __init__(self, p): self.p = p self.condition = ['No', 'Yes'][len(self.p) and not sum(map(ord, self.p.lower())) % 324] def solution(self): return self.condition
- class KumiteFoo:
- def __init__(self, p):
- self.p = p
self.condition = 'Yes' if len(self.p) and not sum(map(ord, self.p.lower())) % 324 else 'No'- self.condition = ['No', 'Yes'][len(self.p) and not sum(map(ord, self.p.lower())) % 324]
- def solution(self):
- return self.condition
class TemperatureConverter: def __init__(self, temp): self.temp = temp self._k1 = 5 / 9 self._k2 = self._k1 * 32 def fahrenheit_to_celsius(self): return round(self.temp * self._k1 - self._k2, 2) def celsius_to_fahrenheit(self): return round((self.temp + self._k2) / self._k1, 2)
- class TemperatureConverter:
- def __init__(self, temp):
- self.temp = temp
- self._k1 = 5 / 9
- self._k2 = self._k1 * 32
- def fahrenheit_to_celsius(self):
return round((self.temp - 32) * 5 / 9, 2)- return round(self.temp * self._k1 - self._k2, 2)
- def celsius_to_fahrenheit(self):
return round((self.temp * 9 / 5) + 32, 2)- return round((self.temp + self._k2) / self._k1, 2)
class UserInfo: def __init__(self, *args): self.first_name, self.last_name, self.age, self.job, self.hobbies = args def __getattr__(self, name): match name: case "full_name": return f'{self.first_name} {self.last_name}' case "email": return f'{self.first_name[0]}{self.last_name}@matrix.com'
from dataclasses import dataclass, field@dataclass- class UserInfo:
first_name: strlast_name: strage: intjob: strhobbies: list@propertydef full_name(self):return f'{self.first_name} {self.last_name}'@propertydef email(self):return f'{self.first_name[0]}{self.last_name}@matrix.com'- def __init__(self, *args):
- self.first_name, self.last_name, self.age, self.job, self.hobbies = args
- def __getattr__(self, name):
- match name:
- case "full_name":
- return f'{self.first_name} {self.last_name}'
- case "email":
- return f'{self.first_name[0]}{self.last_name}@matrix.com'
The shortest solution I can imagine. I bet you can't make it any shorter (60 chars.)
This solution would be more effitient for multiple writes, because of option "preopen".
class Solution: def __init__(self, data, filename='kumite776.txt', preopen=False): self.data = data self.filename = filename if preopen: self.file = open(self.filename, 'w') else: self.file = None def write_to_file(self): if not self.file: self.file = open(self.filename, 'w') self.file.write(self.data)
- class Solution:
def __init__(self, data):- def __init__(self, data, filename='kumite776.txt', preopen=False):
- self.data = data
self.filename = 'kumite776.txt'- self.filename = filename
- if preopen:
- self.file = open(self.filename, 'w')
- else:
- self.file = None
- def write_to_file(self):
with open(self.filename, 'w') as fo:fo.write(self.data)- if not self.file:
- self.file = open(self.filename, 'w')
- self.file.write(self.data)
Slicing instead of reversed=True.
Shorter, but less efficient
def binary_to_integer(b): # I didn't know that you don't need prefix '0b' for convertion, so I wrote it like this return int(f'0b{b}', 2)
- def binary_to_integer(b):
return sum([x[0] for x in list(zip([pow(2,i) for i in range(len(b))], reversed(b))) if x[1] == '1'])- # I didn't know that you don't need prefix '0b' for convertion, so I wrote it like this
- return int(f'0b{b}', 2)
I dont't like nesting more than 2 times, so I inverted the condition.
Also, extracting the generator is more idiomatic way to convert it to list + it looks prettier for me.
def flatten_list(lst): def flatten(l): for i in l: if not isinstance(i, (list, tuple)): yield i continue for j in flatten_list(i): yield j return [*flatten(lst)]
- def flatten_list(lst):
- def flatten(l):
- for i in l:
if isinstance(i, (list, tuple)):for j in flatten_list(i):yield jelse:- if not isinstance(i, (list, tuple)):
- yield i
return list(flatten(lst))- continue
- for j in flatten_list(i):
- yield j
- return [*flatten(lst)]
def knight_move3d(pos=(0, 0, 0)) -> bool: if pos == (0, 0, 0): return True return [*sorted(map(abs, pos))] == [0, 1, 2]
def knight_move3d(position=(0, 0, 0)) -> bool:if position == (0, 0, 0):- def knight_move3d(pos=(0, 0, 0)) -> bool:
- if pos == (0, 0, 0):
- return True
_sum: int = 0mul: int = 1for i in position:if i > 2 or -2 > i:return False_sum += abs(i)mul = mul * ireturn _sum == 3 and mul == 0- return [*sorted(map(abs, pos))] == [0, 1, 2]