Решение на Генератори и итератори от Мартин Пацов

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

Към профила на Мартин Пацов

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 11 успешни тест(а)
  • 3 неуспешни тест(а)

Код

import types
def fibonacci(end=0):
init1 = 0
init2 = 1
counter = 0
while counter < end or not end:
yield init2
init2 += init1
init1 = init2 - init1
counter += 1
raise StopIteration
def primes(end=0):
counter = 0
prime = 2
yield 2
counter += 1
if counter < end or not end:
prime = 3
yield 3
counter += 1
if counter < end or not end:
while counter < end or not end:
prime += 2
if is_prime(prime):
yield prime
counter += 1
raise StopIteration
def is_prime(number):
for i in range(3, int(number ** 0.5 + 1), 2):
if number % i == 0:
return False
return True
def alphabet(*, code='', letters='', end=0):
counter = 0
if not (letters is ''):
for cur_let in letters:
if counter < end or not end:
yield cur_let
counter += 1
elif not (code is ''):
if code == "bg":
cur_let = 1072
while cur_let < 1104:
if (counter < end or not end) \
and not cur_let == 1099 and not cur_let == 1101:
yield chr(cur_let)
counter += 1
cur_let += 1
elif code == "lat":
cur_let = 97
while cur_let < 123:
if counter < end or not end:
yield chr(cur_let)
counter += 1
cur_let += 1
raise StopIteration
def intertwined_sequences(iterable, *, generator_definitions={}):
fibonacci_numbers = fibonacci()
prime_numbers = primes()
cur_alphabet = 0
if isinstance(iterable, types.GeneratorType):
generator = iterable
return create_generator(generator, fibonacci_numbers,
prime_numbers)
else:
return create_iterable_object(iterable,
fibonacci_numbers,
prime_numbers,
generator_definitions,
cur_alphabet
)
def create_generator(generator, fib, pr, generator_definitions={}):
while 1:
iterable = (dict(next(generator)),)
iterable = create_iterable_object(iterable,
fib,
pr,
generator_definitions
)
for item in iterable:
yield item
def create_iterable_object(iterable, fib, pr,
generator_definitions, cur_alphabet={}):
return_list = []
for sequence in iterable:
for key, value in sequence.items():
if key == 'sequence' and value == 'fibonacci':
for i in range(sequence['length']):
return_list.append(next(fib))
elif key == 'sequence' and value == 'primes':
for i in range(sequence['length']):
return_list.append(next(pr))
elif key == 'sequence' and value == 'alphabet':
try:
code = sequence['code']
letters = sequence['letters']
except KeyError as err:
if err.args[0] == 'letters':
end = sequence['length']
for i in range(end):
if cur_alphabet:
return_list.append(next(cur_alphabet))
else:
cur_alphabet = alphabet(code=code)
return_list.append(next(cur_alphabet))
elif err.args[0] == 'code':
letters = sequence['letters']
end = sequence['length']
for i in range(end):
if cur_alphabet:
return_list.append(next(cur_alphabet))
else:
cur_alphabet = alphabet(letters=letters)
return_list.append(next(cur_alphabet))
else:
for key2 in generator_definitions:
if value == key2:
custom_iter = generator_definitions[key2]()
for i in range(sequence['length']):
return_list.append(next(custom_iter))
return iter(return_list)

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

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

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

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

----------------------------------------------------------------------
Ran 14 tests in 6.187s

FAILED (errors=3)

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

Мартин обнови решението на 03.04.2015 04:40 (преди около 9 години)

+last_fib = []
+last_prime = 0
+last_letter = 0
+
+
+def fibonacci(end=0):
+ global last_fib
+ if not last_fib:
+ init1 = 0
+ init2 = 1
+ last_fib.append(init1)
+ last_fib.append(init2)
+ else:
+ init1 = last_fib[0]
+ init2 = last_fib[1]
+ counter = 0
+ while counter < end or not end:
+ yield init2
+ init2 += init1
+ init1 = init2 - init1
+ last_fib[0] = init1
+ last_fib[1] = init2
+ counter += 1
+ raise StopIteration
+
+
+def primes(end=0):
+ counter = 0
+ global last_prime
+ if not last_prime:
+ prime = 2
+ yield 2
+ last_prime = prime
+ counter += 1
+ else:
+ prime = last_prime
+ if counter < end or not end:
+ while counter < end or not end:
+ prime += 1
+ if is_prime(prime):
+ yield prime
+ last_prime = prime
+ counter += 1
+ raise StopIteration
+
+
+def is_prime(number):
+ for i in range(2, number // 2 + 2):
+ if number % i == 0:
+ return False
+ return True
+
+
+def alphabet(code='', letters='', end=0):
+ counter = 0
+ if not (letters is ''):
+ for cur_let in letters:
+ if counter < end or not end:
+ yield cur_let
+ counter += 1
+ elif not (code is ''):
+ if code == "bg":
+ cur_let = 1072
+ while cur_let < 1099:
+ if counter < end or not end:
+ yield chr(cur_let)
+ counter += 1
+ cur_let += 1
+ cur_let += 1
+ if counter < end or not end:
+ yield chr(cur_let)
+ counter += 1
+ cur_let += 2
+ while cur_let < 1104:
+ if counter < end or not end:
+ yield chr(cur_let)
+ counter += 1
+ cur_let += 1
+ elif code == "lat":
+ cur_let = 97
+ while cur_let < 123:
+ if counter < end or not end:
+ yield chr(cur_let)
+ counter += 1
+ cur_let += 1
+ raise StopIteration
+
+
+def intertwined_sequences(iterable, generator_definitions=0):
+ return_list = []
+ for sequence in iterable:
+ for key, value in sequence.items():
+ if key == 'sequence' and value == 'fibonacci':
+ return_list.extend(list(fibonacci(sequence['length'])))
+ elif key == 'sequence' and value == 'primes':
+ return_list.extend(list(primes(sequence['length'])))
+ elif key == 'sequence' and value == 'alphabet':
+ try:
+ return_list.extend(
+ list(
+ alphabet(
+ sequence['code'],
+ sequence['letters'],
+ sequence['length']
+ )
+ )
+ )
+ except KeyError as err:
+ if err.args[0] == 'letters':
+ return_list.extend(
+ list(
+ alphabet(
+ sequence['code'],
+ '',
+ sequence['length']
+ )
+ )
+ )
+ elif err.args[0] == 'code':
+ return_list.extend(
+ list(
+ alphabet(
+ '',
+ sequence['letters'],
+ sequence['length']
+ )
+ )
+ )
+ global last_fib
+ global last_letter
+ global last_prime
+ last_fib = []
+ last_letter = 0
+ last_prime = 0
+ return return_list
  • Опитваш се да върнеш списък вместо да yield-ваш стойности.
  • Ползваш global което е меко казано ужасно.
  • Плашещо многото нива на влагане трябва да те наведат на мисълта, че нещо странно се случва и има по-лесен начин.
  • iterable може да бъде безкраен и тогава този for никога няма да приключи.

Мартин обнови решението на 03.04.2015 16:07 (преди около 9 години)

-last_fib = []
-last_prime = 0
-last_letter = 0
+import types
+from itertools import cycle
def fibonacci(end=0):
- global last_fib
- if not last_fib:
- init1 = 0
- init2 = 1
- last_fib.append(init1)
- last_fib.append(init2)
- else:
- init1 = last_fib[0]
- init2 = last_fib[1]
+ init1 = 0
+ init2 = 1
counter = 0
while counter < end or not end:
yield init2
init2 += init1
init1 = init2 - init1
- last_fib[0] = init1
- last_fib[1] = init2
counter += 1
raise StopIteration
def primes(end=0):
counter = 0
- global last_prime
- if not last_prime:
- prime = 2
- yield 2
- last_prime = prime
- counter += 1
- else:
- prime = last_prime
+ prime = 2
+ yield 2
+ counter += 1
if counter < end or not end:
+ prime = 3
+ yield 3
+ counter += 1
+ if counter < end or not end:
while counter < end or not end:
- prime += 1
+ prime += 2
if is_prime(prime):
yield prime
- last_prime = prime
counter += 1
raise StopIteration
def is_prime(number):
- for i in range(2, number // 2 + 2):
+ for i in range(3, int(number ** 0.5 + 1), 2):
if number % i == 0:
return False
return True
-def alphabet(code='', letters='', end=0):
+def alphabet(*, code='', letters='', end=0):
counter = 0
if not (letters is ''):
for cur_let in letters:
if counter < end or not end:
yield cur_let
counter += 1
elif not (code is ''):
if code == "bg":
cur_let = 1072
- while cur_let < 1099:
- if counter < end or not end:
- yield chr(cur_let)
- counter += 1
- cur_let += 1
- cur_let += 1
- if counter < end or not end:
- yield chr(cur_let)
- counter += 1
- cur_let += 2
while cur_let < 1104:
- if counter < end or not end:
+ if (counter < end or not end) \
+ and not cur_let == 1099 and not cur_let == 1101:
yield chr(cur_let)
counter += 1
cur_let += 1
elif code == "lat":
cur_let = 97
while cur_let < 123:
if counter < end or not end:
yield chr(cur_let)
counter += 1
cur_let += 1
raise StopIteration
-def intertwined_sequences(iterable, generator_definitions=0):
+def intertwined_sequences(iterable, *, generator_definitions={}):
+ fibonacci_numbers = fibonacci()
+ prime_numbers = primes()
+ cur_alphabet = 0
+ if isinstance(iterable, types.GeneratorType):
+ generator = iterable
+ return create_generator(generator, fibonacci_numbers,
+ prime_numbers)
+ else:
+ return create_iterable_object(iterable,
+ fibonacci_numbers,
+ prime_numbers,
+ cur_alphabet)
+
+
+def create_generator(generator, fib, pr):
+ while 1:
+ iterable = (dict(next(generator)),)
+ iterable = create_iterable_object(iterable,
+ fib,
+ pr)
+ for item in iterable:
+ yield item
+
+
+def create_iterable_object(iterable, fib, pr, cur_alphabet={}):
return_list = []
for sequence in iterable:
for key, value in sequence.items():
if key == 'sequence' and value == 'fibonacci':
- return_list.extend(list(fibonacci(sequence['length'])))
+ for i in range(sequence['length']):
+ return_list.append(next(fib))
elif key == 'sequence' and value == 'primes':
- return_list.extend(list(primes(sequence['length'])))
+ for i in range(sequence['length']):
+ return_list.append(next(pr))
elif key == 'sequence' and value == 'alphabet':
try:
- return_list.extend(
- list(
- alphabet(
- sequence['code'],
- sequence['letters'],
- sequence['length']
- )
- )
- )
+ code = sequence['code']
+ letters = sequence['letters']
+ end = sequence['length']
except KeyError as err:
if err.args[0] == 'letters':
- return_list.extend(
- list(
- alphabet(
- sequence['code'],
- '',
- sequence['length']
- )
- )
- )
+ end = sequence['length']
+ for i in range(end):
+ if cur_alphabet:
+ return_list.append(next(cur_alphabet))
+ else:
+ cur_alphabet = alphabet(code=code)
+ return_list.append(next(cur_alphabet))
elif err.args[0] == 'code':
- return_list.extend(
- list(
+ letters = sequence['letters']
- alphabet(
+ end = sequence['length']
- '',
+ for i in range(end):
- sequence['letters'],
+ if cur_alphabet:
- sequence['length']
+ return_list.append(next(cur_alphabet))
- )
+ else:
- )
+ cur_alphabet = alphabet(letters=letters)
- )
+ return_list.append(next(cur_alphabet))
- global last_fib
+ return iter(return_list)
- global last_letter
+
- global last_prime
+
- last_fib = []
+def endless_growing_sequences():
- last_letter = 0
+ for i, generator_key in enumerate(cycle(['fibonacci', 'primes'])):
- last_prime = 0
+ yield {'sequence': generator_key, 'length': i + 1}
- return return_list

Мартин обнови решението на 03.04.2015 16:42 (преди около 9 години)

import types
-from itertools import cycle
def fibonacci(end=0):
init1 = 0
init2 = 1
counter = 0
while counter < end or not end:
yield init2
init2 += init1
init1 = init2 - init1
counter += 1
raise StopIteration
def primes(end=0):
counter = 0
prime = 2
yield 2
counter += 1
if counter < end or not end:
prime = 3
yield 3
counter += 1
if counter < end or not end:
while counter < end or not end:
prime += 2
if is_prime(prime):
yield prime
counter += 1
raise StopIteration
def is_prime(number):
for i in range(3, int(number ** 0.5 + 1), 2):
if number % i == 0:
return False
return True
def alphabet(*, code='', letters='', end=0):
counter = 0
if not (letters is ''):
for cur_let in letters:
if counter < end or not end:
yield cur_let
counter += 1
elif not (code is ''):
if code == "bg":
cur_let = 1072
while cur_let < 1104:
if (counter < end or not end) \
and not cur_let == 1099 and not cur_let == 1101:
yield chr(cur_let)
counter += 1
cur_let += 1
elif code == "lat":
cur_let = 97
while cur_let < 123:
if counter < end or not end:
yield chr(cur_let)
counter += 1
cur_let += 1
raise StopIteration
def intertwined_sequences(iterable, *, generator_definitions={}):
fibonacci_numbers = fibonacci()
prime_numbers = primes()
cur_alphabet = 0
if isinstance(iterable, types.GeneratorType):
generator = iterable
return create_generator(generator, fibonacci_numbers,
prime_numbers)
else:
return create_iterable_object(iterable,
fibonacci_numbers,
prime_numbers,
- cur_alphabet)
+ generator_definitions,
+ cur_alphabet
+ )
-def create_generator(generator, fib, pr):
+def create_generator(generator, fib, pr, generator_definitions={}):
while 1:
iterable = (dict(next(generator)),)
iterable = create_iterable_object(iterable,
fib,
- pr)
+ pr,
+ generator_definitions
+ )
for item in iterable:
yield item
-def create_iterable_object(iterable, fib, pr, cur_alphabet={}):
+def create_iterable_object(iterable, fib, pr,
+ generator_definitions, cur_alphabet={}):
return_list = []
for sequence in iterable:
for key, value in sequence.items():
if key == 'sequence' and value == 'fibonacci':
for i in range(sequence['length']):
return_list.append(next(fib))
elif key == 'sequence' and value == 'primes':
for i in range(sequence['length']):
return_list.append(next(pr))
elif key == 'sequence' and value == 'alphabet':
try:
code = sequence['code']
letters = sequence['letters']
- end = sequence['length']
except KeyError as err:
if err.args[0] == 'letters':
end = sequence['length']
for i in range(end):
if cur_alphabet:
return_list.append(next(cur_alphabet))
else:
cur_alphabet = alphabet(code=code)
return_list.append(next(cur_alphabet))
elif err.args[0] == 'code':
letters = sequence['letters']
end = sequence['length']
for i in range(end):
if cur_alphabet:
return_list.append(next(cur_alphabet))
else:
cur_alphabet = alphabet(letters=letters)
return_list.append(next(cur_alphabet))
+ else:
+ for key2 in generator_definitions:
+ if value == key2:
+ custom_iter = generator_definitions[key2]()
+ for i in range(sequence['length']):
+ return_list.append(next(custom_iter))
return iter(return_list)
-
-
-def endless_growing_sequences():
- for i, generator_key in enumerate(cycle(['fibonacci', 'primes'])):
- yield {'sequence': generator_key, 'length': i + 1}