timeit

Програмиране с Python

Курс във Факултета по Математика и Информатика към СУ

Решение на Работа с картинки от Димитър Керезов

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

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

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 12 успешни тест(а)
  • 0 неуспешни тест(а)

Код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from collections import defaultdict

_WHITE_MAXIMUM_VALUE = 255


def rotate_left(image):
    width = len(image[0])
    height = len(image)
    return [[image[j][i] for j in range(height)] for i in range(width)][::-1]


def rotate_right(image):
    width = len(image[0])
    height = len(image)
    return [
        [image[j][i] for j in range(height - 1, -1, -1)] for i in range(width)
    ]


def invert(image):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [invert_rgb(image[i][j]) for j in inner_range] for i in outer_range
    ]


def lighten(image, coef):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [lighten_rgb(image[i][j], coef) for j in inner_range] for i in outer_range
    ]


def darken(image, coef):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [darken_rgb(image[i][j], coef) for j in inner_range] for i in outer_range
    ]


def create_histogram(image):
    red_dict = defaultdict(int)
    green_dict = defaultdict(int)
    blue_dict = defaultdict(int)
    for i in range(len(image)):
        for j in range(len(image[0])):
            red, green, blue = image[i][j]
            red_dict[red] += 1
            green_dict[green] += 1
            blue_dict[blue] += 1

    return {
        'red': red_dict,
        'green': green_dict,
        'blue': blue_dict
    }


def invert_rgb(rgb_tuple):
    red, green, blue = rgb_tuple
    return (
        get_inverse_pixel_value(red),
        get_inverse_pixel_value(green),
        get_inverse_pixel_value(blue)
    )


def lighten_rgb(rgb_tuple, coef):
    red, green, blue = rgb_tuple
    return (
        red + int(coef * get_inverse_pixel_value(red)),
        green + int(coef * get_inverse_pixel_value(green)),
        blue + int(coef * get_inverse_pixel_value(blue))
    )


def darken_rgb(rgb_tuple, coef):
    red, green, blue = rgb_tuple
    return (
        red - int(coef * red),
        green - int(coef * green),
        blue - int(coef * blue)
    )


def get_inverse_pixel_value(value):
    return _WHITE_MAXIMUM_VALUE - value

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

............
----------------------------------------------------------------------
Ran 12 tests in 0.085s

OK

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

Димитър обнови решението на 10.03.2016 15:33 (преди почти 2 години)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
_WHITE_MAXIMUM_VALUE = 255


# Transponse, then reverse
def rotate_left(image):
    # the explicit list creation seems to be mandatory
    # for passing the sample_test.py
    # otherwise TypeError: 'list_reverseiterator' object is not subscriptable
    # is thrown
    return list(reversed([
        [image[j][i] for j in range(len(image))] for i in range(len(image[0]))
    ]))


def rotate_right(image):
    # needed in order to shorten return statement < 79 symbols
    reverse_image_len = range(len(image) - 1, -1, -1)
    return [
        [image[j][i] for j in reverse_image_len] for i in range(len(image[0]))
    ]


def invert(image):
    # managed to get it going like this too

    # return list(map(invert_tuple_list, image))

    # I really wanted to give map a try
    # didn't manage to do a nested map though
    # along with the fact that a lot of code would be redundant
    # since I'd have to write two functions for all of
    # invert, lighten, darken
    # it can probably be done with lambdas or a dict
    # containing those functions but I don't feel so advanced
    # ...yet
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [invert_rgb(image[i][j]) for j in inner_range] for i in outer_range
    ]


def lighten(image, coef):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [lighten_rgb(image[i][j], coef) for j in inner_range] for i in outer_range
    ]


def darken(image, coef):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [darken_rgb(image[i][j], coef) for j in inner_range] for i in outer_range
    ]


def create_histogram(image):
    red_dict = {}
    green_dict = {}
    blue_dict = {}
    for i in range(len(image)):
        for j in range(len(image[0])):
            red, green, blue = image[i][j]
            insert_pixel_value(red_dict, red)
            insert_pixel_value(green_dict, green)
            insert_pixel_value(blue_dict, blue)

    return {
        'red': red_dict,
        'green': green_dict,
        'blue': blue_dict
    }

# see invert function for more details on this
# def invert_tuple_list(tuple_list):
#     return list(map(invert_rgb, tuple_list))


def invert_rgb(rgb_tuple):
    red, green, blue = rgb_tuple
    return (
        get_inverse_pixel_value(red),
        get_inverse_pixel_value(green),
        get_inverse_pixel_value(blue)
    )


def lighten_rgb(rgb_tuple, coef):
    red, green, blue = rgb_tuple
    return (
        red + int(coef * get_inverse_pixel_value(red)),
        green + int(coef * get_inverse_pixel_value(green)),
        blue + int(coef * get_inverse_pixel_value(blue))
    )


def darken_rgb(rgb_tuple, coef):
    red, green, blue = rgb_tuple
    return (
        red - int(coef * red),
        green - int(coef * green),
        blue - int(coef * blue)
    )


def insert_pixel_value(pixel_dict, pixel_value):
    if pixel_value in pixel_dict:
        pixel_dict[pixel_value] += 1
    else:
        pixel_dict[pixel_value] = 1


def get_inverse_pixel_value(pixel_value):
    return _WHITE_MAXIMUM_VALUE - pixel_value
  • Можеш да избереш по-значещи неща да изнесеш в променливи

[image[j][i] for j in reverse_image_len] for i in range(len(image[0]))

[image[j][i] for j in range(height - 1, -1, -1] for i in range(width)

Мисля, че второто е малко по-четимо и нямаш нужда от коментар :)

  • Махни коментарите от кода, ако имаш въпроси, по-добре ги напиши като коментар на решението си
  • Махни типовете от имената (pixel_dict не е по-добро от pixels)
  • Можеш ли да избереш по-подходяща структура за create_histogram, така че да не ти се налата да използваш допълнителна функция?
  • Ако не искаш да използваш reversed има начин да обърнеш функция и чрез slice-ване :)

Димитър обнови решението на 12.03.2016 18:42 (преди почти 2 години)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
_WHITE_MAXIMUM_VALUE = 255


def rotate_left(image):
    width = len(image[0])
    height = len(image)
    return [[image[j][i] for j in range(height)] for i in range(width)][::-1]


def rotate_right(image):
    width = len(image[0])
    height = len(image)
    return [
        [image[j][i] for j in range(height - 1, -1, -1)] for i in range(width)
    ]


def invert(image):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [invert_rgb(image[i][j]) for j in inner_range] for i in outer_range
    ]


def lighten(image, coef):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [lighten_rgb(image[i][j], coef) for j in inner_range] for i in outer_range
    ]


def darken(image, coef):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [darken_rgb(image[i][j], coef) for j in inner_range] for i in outer_range
    ]


def create_histogram(image):
    red_dict = {}
    green_dict = {}
    blue_dict = {}
    for i in range(len(image)):
        for j in range(len(image[0])):
            red, green, blue = image[i][j]
            insert_pixel_value(red_dict, red)
            insert_pixel_value(green_dict, green)
            insert_pixel_value(blue_dict, blue)

    return {
        'red': red_dict,
        'green': green_dict,
        'blue': blue_dict
    }


def invert_rgb(rgb_tuple):
    red, green, blue = rgb_tuple
    return (
        get_inverse_pixel_value(red),
        get_inverse_pixel_value(green),
        get_inverse_pixel_value(blue)
    )


def lighten_rgb(rgb_tuple, coef):
    red, green, blue = rgb_tuple
    return (
        red + int(coef * get_inverse_pixel_value(red)),
        green + int(coef * get_inverse_pixel_value(green)),
        blue + int(coef * get_inverse_pixel_value(blue))
    )


def darken_rgb(rgb_tuple, coef):
    red, green, blue = rgb_tuple
    return (
        red - int(coef * red),
        green - int(coef * green),
        blue - int(coef * blue)
    )


def insert_pixel_value(pixels, pixel_value):
    if pixel_value in pixels:
        pixels[pixel_value] += 1
    else:
        pixels[pixel_value] = 1


def get_inverse_pixel_value(pixel_value):
    return _WHITE_MAXIMUM_VALUE - pixel_value

@Виктория Благодаря за коментарите. Коментарите в кода ги бях сложил за себе си - махнах ги. Не съм сигурен какво имаш предвид за create_hist - там съм го направил така, за да не се налага да обикалям по повече пъти през пикселите.

On a side note: видях, че имаше нещо споменато в лекциите, но не съм присъствал на тази - ако махаме типовете на пробменливите (e.g. pixels, а не pixel_dict) тогава не се ли забавя работата, защото ще трябва за всяка променлива да ровя в кода по-нагоре лист ли е, речник ли е, tuple и прочие?

Не съм сигурен какво имаш предвид за create_hist - там съм го направил така, за да не се налага да обикалям по повече пъти през пикселите.

Има се предвид, че можеш да минеш без нея, ако речникът ти има стойности по подразбиране.

On a side note: видях, че имаше нещо споменато в лекциите, но не съм присъствал на тази - ако махаме типовете на пробменливите (e.g. pixels, а не pixel_dict) тогава не се ли забавя работата, защото ще трябва за всяка променлива да ровя в кода по-нагоре лист ли е, речник ли е, tuple и прочие?

Това се решава с документиране на функцията, ако има такъв проблем. В този ред на мисли и pixel_value не ми харесва особено :)

Димитър обнови решението на 12.03.2016 23:51 (преди почти 2 години)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from collections import defaultdict

_WHITE_MAXIMUM_VALUE = 255


def rotate_left(image):
    width = len(image[0])
    height = len(image)
    return [[image[j][i] for j in range(height)] for i in range(width)][::-1]


def rotate_right(image):
    width = len(image[0])
    height = len(image)
    return [
        [image[j][i] for j in range(height - 1, -1, -1)] for i in range(width)
    ]


def invert(image):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [invert_rgb(image[i][j]) for j in inner_range] for i in outer_range
    ]


def lighten(image, coef):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [lighten_rgb(image[i][j], coef) for j in inner_range] for i in outer_range
    ]


def darken(image, coef):
    outer_range = range(len(image))
    inner_range = range(len(image[0]))
    return [
        [darken_rgb(image[i][j], coef) for j in inner_range] for i in outer_range
    ]


def create_histogram(image):
    red_dict = defaultdict(int)
    green_dict = defaultdict(int)
    blue_dict = defaultdict(int)
    for i in range(len(image)):
        for j in range(len(image[0])):
            red, green, blue = image[i][j]
            red_dict[red] += 1
            green_dict[green] += 1
            blue_dict[blue] += 1

    return {
        'red': red_dict,
        'green': green_dict,
        'blue': blue_dict
    }


def invert_rgb(rgb_tuple):
    red, green, blue = rgb_tuple
    return (
        get_inverse_pixel_value(red),
        get_inverse_pixel_value(green),
        get_inverse_pixel_value(blue)
    )


def lighten_rgb(rgb_tuple, coef):
    red, green, blue = rgb_tuple
    return (
        red + int(coef * get_inverse_pixel_value(red)),
        green + int(coef * get_inverse_pixel_value(green)),
        blue + int(coef * get_inverse_pixel_value(blue))
    )


def darken_rgb(rgb_tuple, coef):
    red, green, blue = rgb_tuple
    return (
        red - int(coef * red),
        green - int(coef * green),
        blue - int(coef * blue)
    )


def get_inverse_pixel_value(value):
    return _WHITE_MAXIMUM_VALUE - value