Skip to content

Commit

Permalink
solve(codewars): Lazy Init [4 kyu]
Browse files Browse the repository at this point in the history
  • Loading branch information
jestenough committed Aug 20, 2023
1 parent 59d916a commit 71dc88d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
38 changes: 38 additions & 0 deletions services/codewars/katas/4_kyu/Lazy Init/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Lazy Init

How many times we create a python class and in the init method we just write:

```
self.name1 = name1
self.name2 = name2
.....
```

for all arguments.....

How boring!!!!

Your task here is to implement a metaclass that let this instantiation be done automatically. But let's see an example:
```
class Person(metaclass=LazyInit):
def __init__(self, name, age): pass
```
When we create a Person object like:
```
a_person = Person('John', 25)
```
The expected behavior will be:
```
print(a_person.name) # this will print John
print(a_person.age) # this will print 25
```

Obviously the number of arguments might be different from class to class.

Don't worry about **kwargs you will never be given keyword arguments in this kata!!!

A little hint: a decorator could help you out doing the job!!!

Good luck lazy folks.....

[Kata link](https://www.codewars.com/kata/59b7b43b4f98a81b2d00000a/)
17 changes: 17 additions & 0 deletions services/codewars/katas/4_kyu/Lazy Init/solution_lazy_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import inspect


class LazyInit(type):
def __new__(cls, name, bases, attrs):
if init_method := attrs.get('__init__'):
init_parameters = inspect.signature(init_method).parameters
param_names = [name for name, param in init_parameters.items() if name != 'self']

def lazy_init(self, *args, **kwargs):
# TODO maybe write for kwargs too (although this is not provided for by the assignment)
for i, param_name in enumerate(param_names):
setattr(self, param_name, args[i])

attrs['__init__'] = lazy_init

return super().__new__(cls, name, bases, attrs)
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from solution_lazy_init import LazyInit


def test_lazy_init():
class Person(metaclass=LazyInit):
def __init__(self, name, age): pass

class Circle(metaclass=LazyInit):
def __init__(self, x, y, ray): pass

a_person = Person('Luke', 21)

assert a_person.name == 'Luke'
assert a_person.age == 21

a_circle = Circle(0, 0, 5)
assert a_circle.x == 0
assert a_circle.y == 0
assert a_circle.ray == 5

class Car(metaclass=LazyInit):
def __init__(self, model, color, plate, year): pass

class Nothing(metaclass=LazyInit):
def __init__(self, nothing): pass

a_car = Car('Ford Ka', 'Blue', 'AF329SZ', 1999)
a_nothing = Nothing('nothing')

assert a_car.model == 'Ford Ka'
assert a_car.color == 'Blue'
assert a_car.plate == 'AF329SZ'
assert a_car.year == 1999
assert a_nothing.nothing == 'nothing'

0 comments on commit 71dc88d

Please sign in to comment.