Решение на Генератори и итератори от Павел Димитров

Обратно към всички решения

Към профила на Павел Димитров

Резултати

  • 9 точки от тестове
  • 0 бонус точки
  • 9 точки общо
  • 13 успешни тест(а)
  • 1 неуспешни тест(а)

Код

import math
from itertools import cycle
def fibonacci():
n_th_minus_two = 1
n_th_minus_one = 1
yield n_th_minus_two
yield n_th_minus_one
while True:
fibonacci = n_th_minus_one + n_th_minus_two
yield fibonacci
n_th_minus_two = n_th_minus_one
n_th_minus_one = fibonacci
def primes():
num = 2
yield num
while True:
num += 1
isprime = True
sqt = int(math.sqrt(num)) + 1
for i in range(2, sqt):
if num % i == 0:
isprime = False
break
if isprime:
yield num
alphabets = {
"bg": (u"\u0430", 32, u"\u044B", u"\u044D"),
"lat": (u"\u0061", 26)
}
def alphabet(code=None, letters=None):
if letters is not None:
letters = iter(letters)
while True:
yield next(letters)
elif letters is None:
language = alphabets[code]
letter = ord(language[0])
yield chr(letter)
range_of_letters = language[1]
for i in range(range_of_letters):
if chr(letter) not in language:
yield chr(letter)
letter += 1
def intertwined_sequences(item, generator_definitions=None):
default_generator_definition = {"fibonacci": fibonacci,
"primes": primes,
"alphabet": alphabet}
combined_definitions = {}
combined_definitions.update(default_generator_definition)
combined_definitions.update(generator_definitions or {})
iterables = {}
def _interwined_sequences(item, combined_definitions):
item = iter(item)
while True:
current_item = next(item)
sequence = current_item["sequence"]
length = current_item["length"]
if sequence not in iterables.keys():
del current_item["sequence"]
del current_item["length"]
iterables[sequence] = \
iter(combined_definitions[sequence](**current_item))
for i in range(length):
yield next(iterables[sequence])
return _interwined_sequences(item, combined_definitions)

Лог от изпълнението

.......E......
======================================================================
ERROR: test_infinite_intertwined (test.TestIntertwine)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

----------------------------------------------------------------------
Ran 14 tests in 2.200s

FAILED (errors=1)

История (4 версии и 3 коментара)

Павел обнови решението на 30.03.2015 23:15 (преди около 9 години)

+import math
+from copy import copy
+from itertools import cycle
+
+
+def fibonacci():
+ n_th_minus_two = 1
+ n_th_minus_one = 1
+ yield n_th_minus_two
+ yield n_th_minus_one
+
+ while True:
+ fibonacci = n_th_minus_one + n_th_minus_two
+ yield fibonacci
+ n_th_minus_two = n_th_minus_one
+ n_th_minus_one = fibonacci
+
+
+def primes():
+ num = 2
+ yield num
+
+ while True:
+ num += 1
+ isprime = True
+ sqt = int(math.sqrt(num)) + 1
+
+ for i in range(2, sqt):
+ if num % i == 0:
+ isprime = False
+ break
+
+ if isprime:
+ yield num
+
+
+alphabets = {
+ "bg": (u"\u0430", 32, u"\u044B", u"\u044D"),
+ "lat": (u"\u0061", 26)
+}
+
+
+def alphabet(code=None, letters=None):
+ if letters is not None:
+
+ letters = iter(letters)
+ while True:
+ yield next(letters)
+
+ elif letters is None:
+
+ language = alphabets[code]
+ letter = ord(language[0])
+ yield chr(letter)
+ range_of_letters = language[1]
+
+ for i in range(range_of_letters):
+ if chr(letter) not in language:
+ yield chr(letter)
+ letter += 1
+
+
+def intertwined_sequences(item, generator_definitions=None):
+
+ generators = {}
+
+ def _interwined_sequences(item, generator_definitions):
+ item = iter(item)
+ while True:
+ current_item = next(item)
+
+ if current_item["sequence"] not in generators.keys():
+
+ if generator_definitions is not None \
+ and current_item["sequence"] \
+ in generator_definitions.keys():
+
+ current_item["sequence"] = \
+ generator_definitions[current_item["sequence"]]. \
+ __name__
+
+ if len((list(current_item.keys()))) == 2:
+ generators[current_item["sequence"]] = \
+ eval(current_item["sequence"])()
+ elif current_item["sequence"] not in generators.keys():
+
+ sequence = current_item["sequence"]
+ _current_item = copy(current_item)
+ del _current_item["sequence"]
+ del _current_item["length"]
+ generators[sequence] = eval(sequence)(**_current_item)
+
+ current_lenght = current_item["length"]
+ current_sequence = current_item["sequence"]
+ for i in range(current_lenght):
+ yield next(generators[current_sequence])
+
+ return _interwined_sequences(item, generator_definitions)

Би ли ми казал, защо избора на eval() е лош. Питам за да разбера смисала а не като критика, че не ми даваш да го ползвам. Видях ,че може да заменя eval s globals и да ми върши същата работа, това ли имаше предвид ?

Павел обнови решението на 31.03.2015 22:07 (преди около 9 години)

import math
from copy import copy
from itertools import cycle
def fibonacci():
n_th_minus_two = 1
n_th_minus_one = 1
yield n_th_minus_two
yield n_th_minus_one
while True:
fibonacci = n_th_minus_one + n_th_minus_two
yield fibonacci
n_th_minus_two = n_th_minus_one
n_th_minus_one = fibonacci
def primes():
num = 2
yield num
while True:
num += 1
isprime = True
sqt = int(math.sqrt(num)) + 1
for i in range(2, sqt):
if num % i == 0:
isprime = False
break
if isprime:
yield num
alphabets = {
"bg": (u"\u0430", 32, u"\u044B", u"\u044D"),
"lat": (u"\u0061", 26)
}
def alphabet(code=None, letters=None):
if letters is not None:
letters = iter(letters)
while True:
yield next(letters)
elif letters is None:
language = alphabets[code]
letter = ord(language[0])
yield chr(letter)
range_of_letters = language[1]
for i in range(range_of_letters):
if chr(letter) not in language:
yield chr(letter)
letter += 1
def intertwined_sequences(item, generator_definitions=None):
generators = {}
def _interwined_sequences(item, generator_definitions):
item = iter(item)
while True:
current_item = next(item)
if current_item["sequence"] not in generators.keys():
if generator_definitions is not None \
and current_item["sequence"] \
in generator_definitions.keys():
current_item["sequence"] = \
generator_definitions[current_item["sequence"]]. \
__name__
if len((list(current_item.keys()))) == 2:
generators[current_item["sequence"]] = \
- eval(current_item["sequence"])()
+ globals()[current_item["sequence"]]()
elif current_item["sequence"] not in generators.keys():
sequence = current_item["sequence"]
_current_item = copy(current_item)
del _current_item["sequence"]
del _current_item["length"]
- generators[sequence] = eval(sequence)(**_current_item)
+ generators[sequence] = globals()[sequence](**_current_item)
current_lenght = current_item["length"]
current_sequence = current_item["sequence"]
for i in range(current_lenght):
yield next(generators[current_sequence])
return _interwined_sequences(item, generator_definitions)

Порови в интернет, има много изписани неща на тема "eval is evil". Ползването на директно оценяване на стрингове прави кода много по-труден за осмисляне, твърде силно зависещ от контекста, в който бива изъкан/дефиниран, да не говорим за редица security проблеми, които може да породи в малко по-смислен код.

Ползването на globals решава част от тези проблеми, но продължава да разчита на имплементационни детайли в езика и като цяло да прави логиката ти сложна за разбиране.

Функциите в python са first class citizens, т.е. спокойно могат да бъдат присвоявани на други имена, да бъдат стойности в списъци, tuple-и, dict и прочее. Това трябва да те наведе на мисълта как да се оттървеш от eval-а.

Павел обнови решението на 02.04.2015 18:08 (преди около 9 години)

import math
from copy import copy
from itertools import cycle
def fibonacci():
n_th_minus_two = 1
n_th_minus_one = 1
yield n_th_minus_two
yield n_th_minus_one
while True:
fibonacci = n_th_minus_one + n_th_minus_two
yield fibonacci
n_th_minus_two = n_th_minus_one
n_th_minus_one = fibonacci
def primes():
num = 2
yield num
while True:
num += 1
isprime = True
sqt = int(math.sqrt(num)) + 1
for i in range(2, sqt):
if num % i == 0:
isprime = False
break
if isprime:
yield num
alphabets = {
"bg": (u"\u0430", 32, u"\u044B", u"\u044D"),
"lat": (u"\u0061", 26)
}
def alphabet(code=None, letters=None):
if letters is not None:
letters = iter(letters)
while True:
yield next(letters)
elif letters is None:
language = alphabets[code]
letter = ord(language[0])
yield chr(letter)
range_of_letters = language[1]
for i in range(range_of_letters):
if chr(letter) not in language:
yield chr(letter)
letter += 1
def intertwined_sequences(item, generator_definitions=None):
- generators = {}
+ generators = {"fibonacci": fibonacci,
+ "primes": primes,
+ "alphabet": alphabet}
def _interwined_sequences(item, generator_definitions):
+
item = iter(item)
+
while True:
+
current_item = next(item)
+ sequence = current_item["sequence"]
+ length = current_item["length"]
+ del current_item["sequence"]
+ del current_item["length"]
- if current_item["sequence"] not in generators.keys():
+ if sequence not in generators.keys() and \
+ generator_definitions is not None:
- if generator_definitions is not None \
- and current_item["sequence"] \
- in generator_definitions.keys():
+ generators[sequence] = \
+ iter(generator_definitions[sequence](**current_item))
- current_item["sequence"] = \
- generator_definitions[current_item["sequence"]]. \
- __name__
+ elif sequence in generators.keys() and \
+ str(type(generators[sequence])) == "<class 'function'>":
- if len((list(current_item.keys()))) == 2:
- generators[current_item["sequence"]] = \
- globals()[current_item["sequence"]]()
- elif current_item["sequence"] not in generators.keys():
+ generators[sequence] = \
+ iter(generators[sequence](**current_item))
- sequence = current_item["sequence"]
- _current_item = copy(current_item)
- del _current_item["sequence"]
- del _current_item["length"]
- generators[sequence] = globals()[sequence](**_current_item)
-
- current_lenght = current_item["length"]
- current_sequence = current_item["sequence"]
- for i in range(current_lenght):
- yield next(generators[current_sequence])
+ for i in range(length):
+ yield next(generators[sequence])
return _interwined_sequences(item, generator_definitions)

Павел обнови решението на 03.04.2015 13:27 (преди около 9 години)

import math
-from copy import copy
from itertools import cycle
def fibonacci():
n_th_minus_two = 1
n_th_minus_one = 1
yield n_th_minus_two
yield n_th_minus_one
while True:
fibonacci = n_th_minus_one + n_th_minus_two
yield fibonacci
n_th_minus_two = n_th_minus_one
n_th_minus_one = fibonacci
def primes():
num = 2
yield num
while True:
num += 1
isprime = True
sqt = int(math.sqrt(num)) + 1
for i in range(2, sqt):
if num % i == 0:
isprime = False
break
if isprime:
yield num
alphabets = {
"bg": (u"\u0430", 32, u"\u044B", u"\u044D"),
"lat": (u"\u0061", 26)
}
def alphabet(code=None, letters=None):
if letters is not None:
letters = iter(letters)
while True:
yield next(letters)
elif letters is None:
language = alphabets[code]
letter = ord(language[0])
yield chr(letter)
range_of_letters = language[1]
for i in range(range_of_letters):
if chr(letter) not in language:
yield chr(letter)
letter += 1
def intertwined_sequences(item, generator_definitions=None):
- generators = {"fibonacci": fibonacci,
- "primes": primes,
- "alphabet": alphabet}
+ default_generator_definition = {"fibonacci": fibonacci,
+ "primes": primes,
+ "alphabet": alphabet}
- def _interwined_sequences(item, generator_definitions):
+ combined_definitions = {}
+ combined_definitions.update(default_generator_definition)
+ combined_definitions.update(generator_definitions or {})
+ iterables = {}
+
+ def _interwined_sequences(item, combined_definitions):
+
item = iter(item)
while True:
current_item = next(item)
sequence = current_item["sequence"]
length = current_item["length"]
- del current_item["sequence"]
- del current_item["length"]
- if sequence not in generators.keys() and \
- generator_definitions is not None:
+ if sequence not in iterables.keys():
- generators[sequence] = \
- iter(generator_definitions[sequence](**current_item))
+ del current_item["sequence"]
+ del current_item["length"]
- elif sequence in generators.keys() and \
- str(type(generators[sequence])) == "<class 'function'>":
+ iterables[sequence] = \
+ iter(combined_definitions[sequence](**current_item))
- generators[sequence] = \
- iter(generators[sequence](**current_item))
-
for i in range(length):
- yield next(generators[sequence])
+ yield next(iterables[sequence])
- return _interwined_sequences(item, generator_definitions)
+ return _interwined_sequences(item, combined_definitions)