Найти - Пользователи
Полная версия: Графический исполнитель "Робот"
Начало » Python для новичков » Графический исполнитель "Робот"
1 2 3 4 5 6 None 28 29 30 31
Lucker
спасибо, надо еще попрактиковаться в декомпозиции. но хотя бы более-менее понятно стало.
py.user.next
Lucker
надо еще попрактиковаться в декомпозиции
Вообще, этот курс сделан по книге “Программирование для математиков” Кушниренко-Лебедев. По крайней мере парень, который ведёт лекции в МФТИ и руководит этим курсом, рассказывает пулёвую инфу из этой книги. Но в книге больше нужной инфы. В этом курсе, например, нет инвариантов и рекурсивных обходов препятствий, а в книге реально объясняется рекурсия и потом даются задания на управление путником через рекурсивные подпрограммы. А инвариант - это вообще бомба. Мне как-то помог инвариант обработать строку в программе, которую я долго не мог обработать, потому что она сликом сложная была для понимания. В этом курсе все задачки в уме решаются, а в реальном мире часто бывают задачки, которые в уме не помещаются. Когда писал реализацию алгоритма base64, тоже применил инвариант и только тогда код стал очень компактным. Потом я открыл питоновскую реализацию этого алгоритма и он оказался прямо таким же, как мой. Короче, в этой книге дают методы для составления идеальных алгоритмов - компактных, точных и максимально быстрых.

Тут, кстати, html-страница с курсом этого парня, можешь посмотреть этот курс. Я просматривал лекции и отмечал, какие просмотрел, а какие нет ещё. Мне эти лекции ничего не дали, но параллели с книгой явно видно.
Lucker
Добрый день, столкнулся с такой задачкой, следуя дальше по курсу:
Перепишите код солнечной системы, используя метод move, так, чтобы объекты не создавались каждый раз в цикле.

добавил такую функцию и дописал цикл
  
def add2(point_1, point_2):
    new_point = gr.Point(point_2.x - point_1.x, point_2.y - point_1.y)
    return new_point 
 acceleration = update_acceleration(coords, gr.Point(400, 400))
    
    coords2 = update_coords(coords, velocity)
    velocity = update_velocity(velocity, acceleration)
    movecoords = add2(coords, coords2)
    x = movecoords.getX()
    y = movecoords.getY()
    circle.move(x, y)
    
    coords = coords2
    check_coords(coords, velocity) 
через определенное количество циклов начинает колбасить шарик(


 import graphics as gr
SIZE_X = 800
SIZE_Y = 800
window = gr.GraphWin("Model", SIZE_X, SIZE_Y)
coords = gr.Point(400, 700) #начальное положение шарика (x, y)
velocity = gr.Point(2, 0) #скорость (x, y)
acceleration = gr.Point(0, 0) #ускорение
def clear_window():
    rectangle = gr.Rectangle(gr.Point(0, 0), gr.Point(SIZE_X, SIZE_Y))
    rectangle.setFill('green')
    rectangle.draw(window)
    sun = gr.Circle(gr.Point(400, 400), 50)
    sun.setFill('yellow')
    sun.draw(window)
def add(point_1, point_2):
    new_point = gr.Point(point_1.x + point_2.x, point_1.y + point_2.y)
    return new_point
def sub(point_1, point_2):
    new_point = gr.Point(point_1.x - point_2.x, point_1.y - point_2.y)
    return new_point
def draw_ball(coords):
    circle = gr.Circle(coords, 10)
    circle.setFill('red')
    circle.draw(window)
def check_coords(coords, velocity):
    if coords.x < 0 or coords.x > SIZE_X:
        velocity.x = -velocity.x
    if coords.y < 0 or coords.y >SIZE_Y:
        velocity.y = -velocity.y
def update_coords(coords, velocity):
    return add(coords, velocity)
def update_velocity(velocity, acceleration):
    return add(velocity, acceleration)
def update_acceleration(ball_coords, center_coords):
    diff = sub(ball_coords, center_coords)
    distance_2 = (diff.x ** 2 + diff.y ** 2) ** (3/2)
    G = 2000
    return gr.Point(-diff.x*G/distance_2, -diff.y*G/distance_2)
while True:
    clear_window()    
    draw_ball(coords) 
    acceleration = update_acceleration(coords, gr.Point(400, 400))
    coords = update_coords(coords, velocity)
    velocity = update_velocity(velocity, acceleration)
    check_coords(coords, velocity) 
    gr.time.sleep(0.002)
py.user.next
Тут тема про другой исполнитель - pyrob и подобные. Так что отдельный топик на форуме сделай по graphics.
Intarr
Добрый день! выполняю задачку из этого курса
http://judge.mipt.ru/mipt_cs_on_python3/labs/lab2.html#o30-task-9-3

Задача №30: task_9_3
Закрасить поле «треугольниками». Размер поля не известен, но поле всегда квадратное с нечётным количество клеток по каждой стороне.

написал такой код который работает и выполняет задачу:
 #!/usr/bin/python3
from pyrob.api import *
@task(delay=0.02)
def task_9_3():
    c = 1
    while not wall_is_on_the_right():
        c += 1
        move_right()
    else:
        move_left(c-1)
    base_sq = c
    base_tr = base_sq - 2
    def mvr(base_sq, base_tr):
        while base_sq > 1:
           base_sq -= 1
           move_right()
           while base_tr > 0:
               fill_cell()
               move_right()
               base_tr -= 1
               base_sq -= 1
    def mvd(base_sq, base_tr):
        while base_sq > 1:
           base_sq -= 1
           move_down()
           while base_tr > 0:
               fill_cell()
               move_down()
               base_tr -= 1
               base_sq -= 1
    def mvl(base_sq, base_tr):
        while base_sq > 1:
           base_sq -= 1
           move_left()
           while base_tr > 0:
               fill_cell()
               move_left()
               base_tr -= 1
               base_sq -= 1
    def mvu(base_sq, base_tr):
        while base_sq > 1:
            base_sq -= 1
            move_up()
            while base_tr > 0:
                fill_cell()
                move_up()
                base_tr -= 1
                base_sq -= 1
    stage = 1
    while stage < c:
        if base_sq < 2:
            if wall_is_beneath() and wall_is_on_the_left():
                return
            else:
                while not wall_is_beneath():
                    move_down()
                while not wall_is_on_the_left():
                    move_left()
        else:
            mvr(base_sq, base_tr)
            mvd(base_sq, base_tr)
            mvl(base_sq, base_tr)
            mvu(base_sq, base_tr)
            base_sq -= 2
            base_tr = base_sq - 2
            stage += 1
            move_down()
            move_right()
if __name__ == '__main__':
    run_tasks()

Мне показалось это криворуким, вопрос, как можно решить эту задачу проще-правильнее?
py.user.next
Intarr
Задача №30: task_9_3
Закрасить поле «треугольниками». Размер поля не известен, но поле всегда квадратное с нечётным количество клеток по каждой стороне.
Intarr
Мне показалось это криворуким, вопрос, как можно решить эту задачу проще-правильнее?
  
#!/usr/bin/python3
 
from pyrob.api import *
 
 
def draw_cycle(side_length):
    i = 0
    while i < side_length - 1:
        if i > 0:
            fill_cell()
            move_up()
        else:
            move_up()
        i += 1
    i = 0
    while i < side_length - 1:
        if i > 0:
            fill_cell()
            move_right()
        else:
            move_right()
        i += 1
    i = 0
    while i < side_length - 1:
        if i > 0:
            fill_cell()
            move_down()
        else:
            move_down()
        i += 1
    i = 0
    while i < side_length - 1:
        if i > 0:
            fill_cell()
            move_left()
        else:
            move_left()
        i += 1
 
 
@task(delay=0.05)
def task_9_3():
    side_length = 1
    while not wall_is_beneath():
        move_down()
        side_length += 1
    while side_length > 1:
        draw_cycle(side_length)
        move_right()
        move_up()
        side_length -= 2
    while not wall_is_beneath():
        move_down()
    while not wall_is_on_the_left():
        move_left()
 
 
if __name__ == '__main__':
    run_tasks()

Укоротил процедуру draw_cycle(), использовав возможности питона
  
def draw_cycle(side_length):
    for move_func in (move_up,
                      move_right,
                      move_down,
                      move_left):
        for i in range(side_length - 1):
            if i > 0:
                fill_cell()
            move_func()
Intarr
Спасибо, логика понятна.
hm_dmitry
Всем привет,
Подскажите, пожалуйста, правильно ли будет следующее решение для задачи # 13:

Условие: Закрасить клетки. Расстояние до стены не известно.


 def up_and_fill():
    move_up()
    fill_cell()
    move_down()
def down_and_fill():
    move_down()
    fill_cell()
    move_up()
@task
def task_8_10():
    if not wall_is_above():
        up_and_fill()
    if not wall_is_beneath():
        down_and_fill()
    while not wall_is_on_the_right():
        move_right()
        if not wall_is_above():
            up_and_fill()
        if not wall_is_beneath():
            down_and_fill()
py.user.next
hm_dmitry
Всем привет,
Подскажите, пожалуйста, правильно ли будет следующее решение для задачи # 13:
  
#!/usr/bin/python3
 
from pyrob.api import *
 
 
def fill_up_down():
    if not wall_is_above():
        move_up()
        fill_cell()
        move_down()
    if not wall_is_beneath():
        move_down()
        fill_cell()
        move_up()
 
 
@task(delay=0.01)
def task_8_10():
    fill_up_down()
    while not wall_is_on_the_right():
        move_right()
        fill_up_down()
 
 
if __name__ == '__main__':
    run_tasks()

Почему мы делаем вот так, а не как у тебя, - потому что это декомпозиция.

Какой принцип у декомпозиции:
1)
Нужно выделить максимальные действия, максимальные структуры и всё записать для них;
2)
Когда на них всё работает, мы спускаемся в полученные функции и проводим с ними то же самое действие - ищем всё максимальное уже на новом уровне и записываем всё для максимального;
3)
Когда для этого второго уровня всё работает, мы снова спускаемся в полученные функции (на третий уровень) и проводим там то же самое действие по поиску максимальных действий и структур;
4)
Это продолжается, пока разбивать ничего не останется, - элементы станут простейшими.

Эта декомпозиция приводит к тому, что у тебя всё получается ясно и выстроено.
А если же ты вот это всё не соблюдаешь, то у тебя получается вот такое дробление, где уже ничего поймёшь, что происходит.

Если бы функция fill_up_down() получилась слишком большой и запутанной, то её можно было бы дальше разбивать. Но так как она короткая (до 25 строк) и функционально-прочная по Майерсу (отвечает точно на вопрос “что делает эта функция?”), то мы её оставляем в таком виде. Если бы она была на полстраницы или делала бы десяток несвязанных между собой действий, то мы бы должны были её разбить на несколько разных функций, которые и короткие, и функционально-прочные. Проверяем “Что делает эта функция?”, ответ - она закрашивает клетки сверху и снизу от текущей, если это возможно сделать. Всё, ответ точный, значит функция фунционально-прочная по Майерсу.


tags: decomposition
hm_dmitry
py.user.next
Почему мы делаем вот так, а не как у тебя
Спасибо! Теперь буду знать.

py.user.next
def task_8_10():
fill_up_down()
while not wall_is_on_the_right():
Вот этот первый fill_up_down() пишем для проверки первой клетки, верно ?
Возможно ли все это дело вписать внутрь while ?

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB