1 Востаннє редагувалося DimONN (26.03.2018 11:11:28)

Тема: Задача для опанування підпрограм №2

Доброго дня!

Є задача для опанування підпрограм:
https://replace.org.ua/extensions/om_images/img/5ab7f9fec24da/1.jpg

Написав наступний код:

import random
import math

n = int(input('Введіть кількість елементів послідовності '))
max = int(input('Введіть максимальне натуральне число послідовності '))
X = random.sample(range(1, max), n)

print(X)

def issqr(val):
    if int(val**0.5) == val**0.5:
        return True
    else:
        return False

def islog(val):
    if int(math.log(val,5)) == math.log(val,5):
        return True
    else:
        return False

def isprime(val):
    val = abs(int(val))
    if val < 2:
        return False
    if val == 2:
        return True
    if not val & 1:
        return False
    for x in range(3, int(val**0.5)+1, 2):
        if val % x == 0:
            return False
    return True

def check_value(i):
    if issqr(i):
        print(i,'є квадратом числа',int(i**0.5))
    if islog(i):
        print(i,'є ступенем числа 5: 5^',math.log(i,5))
    if isprime(i):
        print(i,'є простим числом')

for i in range(0,len(X)):
    check_value(X[i])

Будь ласка, підкажіть як можна оптимізувати код, але залишити підпрограми.

2

Re: Задача для опанування підпрограм №2

Оптимізувати за якою характеристикою? "Оптимізувати" без уточнення - безглузда дія.

3

Re: Задача для опанування підпрограм №2

В моєму розумінні "оптимізувати" це зменьшити кількість літер у коді. Я на цьому етапі ).

4

Re: Задача для опанування підпрограм №2

Це зветься "мініфікація". Почніть зі скорочення імен змінних та видалення зайвих пробілів :D
У вашій попередній темі пробігала функція перевірки на простоту в один рядок, чому ви її не взяли?
Нема сенсу повертати True/False розгалуженням: те, що ви перевіряєте в if, вже має значення True/False:

def issqr(val):
    return int(val**0.5) == val**0.5

Перевіряти на цілість можна так:

def issqr(val):
    return val**.5%1==0
Подякували: leofun01, DimONN2

5 Востаннє редагувалося leofun01 (26.03.2018 14:45:26)

Re: Задача для опанування підпрограм №2

DimONN написав:

... оптимізувати код, але залишити підпрограми.
... зменьшити кількість літер у коді.

Мініфікація має йти в останню чергу. У вас не завершені інші оптимізації.
Можете взяти цей приклад:

import random
import math

def is_sqr(val):
    return math.isclose(math.sqrt(val) % 1, 0)

def is_log(val, base):
    return math.isclose(math.log(val, base) % 1, 0)

def is_prime(val):
    return val > 1 and all(val % p != 0 for p in range(2, int(math.sqrt(val)) + 1))

def check_value(val):
    if is_sqr(val):
        print(val, 'є квадратом числа', int(math.sqrt(val)))
    if is_log(val, 5):
        print(val, 'є ступенем числа 5: 5^', int(math.log(val, 5)))
    if is_prime(val):
        print(val, 'є простим числом')

n = int(input('Введіть кількість елементів послідовності'))
maxV = int(input('Введіть максимальне натуральне число послідовності'))
X = random.sample(range(1, maxV), n)

print(X)

for i in X:
    check_value(i)
+ мініфікований
import random
import math
def is_sqr(v):return math.isclose(math.sqrt(v)%1,0)
def is_log(v,b):return math.isclose(math.log(v,b)%1,0)
def is_prime(v):return v>1 and all(v%p!=0 for p in range(2,int(math.sqrt(v))+1))
def check_value(v):
    if is_sqr(v):print(v,'є квадратом числа',int(math.sqrt(v)))
    if is_log(v,5):print(v,'є ступенем числа 5: 5^',int(math.log(v,5)))
    if is_prime(v):print(v,'є простим числом')
n=int(input('Введіть кількість елементів послідовності'))
m=int(input('Введіть максимальне натуральне число послідовності'))
X=random.sample(range(1,m),n)
print(X)
for i in X:check_value(i)

Реалізації is_prime з різними кроками перевірки

import math

def is_prime_1(val):
    return val > 1 and all(val % p != 0 for p in range(2, int(math.sqrt(val)) + 1))

def is_prime_2(val):
    return val > 2 and val & 1 and all(val % p != 0 for p in range(3, int(math.sqrt(val)) + 1, 2)) or val == 2

def is_prime_6(val):
    return val > 4 and val & 1 and val % 3 != 0 and all(val % p != 0 and val % (p + 2) != 0 for p in range(5, int(math.sqrt(val)) + 1, 6)) or val == 2 or val == 3
Подякували: DimONN1

6

Re: Задача для опанування підпрограм №2

val == 2 or val == 3 -> val in [2,3]

Подякували: DimONN, leofun012

7

Re: Задача для опанування підпрограм №2

isclose нічим не кращий за == для цих цілей. Неціла похибка при обчислені кореня на double не виникне, доки мантиса  вміщує всі цифри (бо корінь менший за число), а як не вмістить - то isclose її не помітить.

   math.isclose((1e18+1)**.5%1,0)
=> True

Хочете, щоб на великих числах працювало - реалізуйте метод Ньютона чи аналоги.

Подякували: DimONN, leofun012

8

Re: Задача для опанування підпрограм №2

Ну і взагалі Python лаконічний, але не задля лаконічності, а задля виразності. Мініфікація вбиває виразність.

9 Востаннє редагувалося koala (26.03.2018 18:58:15)

Re: Задача для опанування підпрограм №2

math.sqrt(x) => x**.5
Оскільки числа можна неявно перетворювати на булеві значення (0 - False, решта - True), то

def is_prime(x):return x>1 and all(x%p for p in range(2,int(x**.5+1))
Подякували: leofun011