Раздел «Язык Си».PythonGeomOOP0:

Нужно скачать файл grid.py и положить в ту же директорию, где вы пишите программы.

Вспомним черепаху

Мы работали с черпахой.

import turtle

t = turtle.Turtle()
t.width(5)
t.color("blue")

# начинаем движение в точке (0, 0)
t.fd(100)
t.lt(90)
t.fd(50)

turtle.done()

Grid

Теперь можно рисовать в координатной сетке, как на математике

from grid import Grid

g = Grid()

# тут рисуем точки и линии

g.draw_dot(30, 10, 'red')
g.draw_dot(-20, 40)

g.draw_line(30, 10, 0, -50, 'violet')

g.done()     # обязательно, иначе не будет видно рисунок

grid_example.png

Классы

Хотим работать с геометрическими фигурами так же, как с черепахой.

from grid import Grid

g = Grid()

# работаем с точкой, как с черепахой
p1 = Point(50, -30, 'red')   # создаем точку
p1.draw()                    # рисуем точку
print(p1)                    # точку можно напечатать
p1.move(20)                  # двигаем точку на dx=20
p1.col = 'violet'            # изменяем цвет точки
p1.draw()                    # рисуем точку на новом месте
print(p1)                    # печатаем новые значения точки

g.done()     # обязательно, иначе не будет видно рисунок

point0.png

Создаем класс точка

Мы хранили разные переменные отдельно. Одна точка описывается координатами х у и цветом.

К точке относятся переменные x, y, col. Если точек много, таких переменных много. Легко перепутать. Будем хранить все переменные, которые относятся к одной точке в одном "ящике".

В этот же ящик положим функции, которые рисуют точку draw и двигают ее move.

Объединить переменные в один ящик - это сделать класс. Класс описывает как делать разные точки (делать разные ящики, в каждом из них хранится по точке). Одна точка - это один экземпляр класса (один конкретный ящик).

Можно делать другие ящики - для отрезка, прямоугольника, окружности, треугольника. Это потом.

Сейчас опишем как сделать ящик (класс) точка и что в нем лежит.

Назовем класс Point. В коде пишем

class Point:
    # с отступом <TAB> будем писать что в этом классе (ящике)

# кончились отступы, закончился класс Point

# тут можно его использовать

Для создания 1 конкретной точки (экземпляра класса Point) используют функцию со специальным именем __init__ от слова initialize.

Когда нужно сделать 1 точку, мы делаем ее так: Point(50, 20, 'red'). При этом вызвывается (сама) функция __init__, вам ее никогда вызывать не нужно. Это делает сам python.

class Point:
    # с отступом <TAB> будем писать что в этом классе (ящике)
    
    # функция, которая делает 1 точку. В ней описывается, какие переменные лежат в ящике
    # это мой ящик. Его называю self
    # self - обязательный первый параметр каждой функции в классе

    def __init__(self, x, y, col='blue'):
        self.x = x   # self.x и x - это разные переменные; self.x лежит в моем ящике, x - лежит где-то вне ящика
        self.y = y   # self.y и y - это разные переменные; self.y лежит в моем ящике, y - лежит где-то вне ящика
        self.col = col   # self.col и col - это разные переменные ...

    # функция рисует точку. координаты точки в ящике self
    def draw(self):
        g.draw_dot(self.x, self.y, self.col)

# кончились отступы, закончился класс Point

# тут можно его использовать
p1 = Point(50, -30, 'red')    # к ящику снаружи можно обратиться по ссылке. Переменная с именем p1 ссылается на сделанный ящик
p1.draw()                     # нарисовать точку, на которую ссылается переменная p1

Печатаем точку

Если мы будем печатать точку, то получим непонятную информацию

print(p1)    # <__main__.Point object at 0x7f6060e7e1d0>

Чтобы точку хорошо печатали, нужно написать функцию со специальным именем __repr__ от слова represent. Она должна сделать строку (которую будет печатать print) и вернуть эту строку

class Point:
    # с отступом <TAB> будем писать что в этом классе (ящике)
    
    # функция, которая делает 1 точку. В ней описывается, какие переменные лежат в ящике
    # это мой ящик. Его называю self
    # self - обязательный первый параметр каждой функции в классе

    def __init__(self, x, y, col='blue'):
        self.x = x   # self.x и x - это разные переменные; self.x лежит в моем ящике, x - лежит где-то вне ящика
        self.y = y   # self.y и y - это разные переменные; self.y лежит в моем ящике, y - лежит где-то вне ящика
        self.col = col   # self.col и col - это разные переменные ...

    # функция делает из точки строку, возвращает строку. Нужна для печати
    # у нее только свой ящик self, в котором хранятся self.x, self.y, self.col. Из них делаем строку.
    def __repr__(self):
        s = f'({self.x}, {self.y}) {self.col}'

    # функция рисует точку. координаты точки в ящике self
    def draw(self):
        g.draw_dot(self.x, self.y, self.col)

# кончились отступы, закончился класс Point

# тут можно его использовать
p1 = Point(50, -30, 'red')    # к ящику снаружи можно обратиться по ссылке. Переменная с именем p1 ссылается на сделанный ящик
p1.draw()                     # нарисовать точку, на которую ссылается переменная p1
print(p1)                     # (50, -30) red

Мы не вызваем функцию __repr__ сами, ее вызывает python.

Двигаем точку

Напишем функцию move, которая двигает точку на dx по оси Х. Сдвинем точку. Сделаем точку другого цвета и напечатаем ее.

class Point:
    # с отступом <TAB> будем писать что в этом классе (ящике)
    
    # функция, которая делает 1 точку. В ней описывается, какие переменные лежат в ящике
    # это мой ящик. Его называю self
    # self - обязательный первый параметр каждой функции в классе

    def __init__(self, x, y, col='blue'):
        self.x = x   # self.x и x - это разные переменные; self.x лежит в моем ящике, x - лежит где-то вне ящика
        self.y = y   # self.y и y - это разные переменные; self.y лежит в моем ящике, y - лежит где-то вне ящика
        self.col = col   # self.col и col - это разные переменные ...

    # функция делает из точки строку, возвращает строку. Нужна для печати
    # у нее только свой ящик self, в котором хранятся self.x, self.y, self.col. Из них делаем строку.
    def __repr__(self):
        s = f'({self.x}, {self.y}) {self.col}'

    # функция рисует точку. координаты точки в ящике self
    def draw(self):
        g.draw_dot(self.x, self.y, self.col)

    # двигаем точку на dx. Изменяе координаты точки, которые хранятся в ящике self
    def move(self, dx):
        self.x = self.x + dx

# кончились отступы, закончился класс Point

# тут можно его использовать
p1 = Point(50, -30, 'red')    # к ящику снаружи можно обратиться по ссылке. Переменная с именем p1 ссылается на сделанный ящик
p1.draw()                     # нарисовать точку, на которую ссылается переменная p1
print(p1)                     # (50, -30) red

p1.move(20)                   # двигаем точку на 20 по оси х
p1.col = 'violet'             # цвет точки лежит в ящике. К нему мы снаружи доступаемся по имени p1
p1.draw()                      
print(p1)                     # (70, -30) red

Задачи урока 1

Перепишите код для точки. Запустите его. Дальше делайте свой вариант.

Урок 2

Возвращаем число

Метод класса (функция) может вернуть число. Напишем функции, которые считают расстояние от точки до (0, 0) и от одной точки до другой:

class Point:
        # тут другие функции, которые написали раньше

   def dist0(self):
      # расстояние от точки до (0,0)
      dx = self.x
      dy = self.y
      res = math.sqrt(dx*dx + dy*dy)
      return res  # возвращаем число

   def dist(self, other):
      # расстояние от точки self до точки other
      dx = self.x
      dy = self.y
      res = math.sqrt(dx*dx + dy*dy)
      return res  # возвращаем число

Используем эти функции, чтобы найти расстояния:

   p2 = Point(30, 40, 'blue')
   p2.draw()
   d = p2.dist0()
   print('from (0,0) to ', p2, ' distance is ', d)

   p3 = Point(70, 70, 'green')
   p3.draw()
   d = p3.dist0()
   print(f'from (0,0) to {p3} distance is {d}')
   d = p2.dist(p3)
   print(f'from {p2} to {p3} distance is {d}')

Функция возвращает новую точку

Функция может вернуть не число, а новую точку (старая останется без изменений). Сравните метод move, который двигает саму точку и метод transform, который создает новую точку, а старая остается без изменений.

class Point:
        # другие функции класса
   def move(self, dx):
      """ Двигаем точку на dx """
      self.x = self.x + dx      # изменяем саму точку
      
   def transform(self, dx):
      """ Двигаем точку на dx и получаем НОВУЮ ТОЧКУ """
      res_point = Point(self.x + dx, self.y, self.col)   # делаем новую точку
      return res_point

используем эти функции в программе:

   p3 = Point(70, 70, 'green')
        p3.draw()
   pnew = p3.transform(20)
   pnew.col = 'yellow'
   p3.col = 'lightgreen'
   pnew.draw()
   p3.draw()

Задача 2.1 Написать функцию

В выражении y = sin(x) функция sin(x) вычисляет и возвращает число. Это число записываем в y.

Можно написать свою функцию f, которая будет вычислять и возвращать значение выражения 4*x2+3

def f(x):
    res = 4*x*x + 3   # вычисляем результат
    return res        # возвращаем результат

# функция закончилась, можно ее использовать
y = f(1)
print(y)              # напечатает 7

print(f(3))           # напечатает 39

Посчитаем площадь прямоугольника по его сторонам

def area(w, h):
    res = w*h         # вычисляем результат
    return res        # возвращаем результат

# функция закончилась, можно ее использовать
a, b = map(int, input().split())

s = area(a, b)        # функция вернула результат, его сохранили в s
print(s)

В отдельном файле написать функцию и с ее помощью посчитать:

  1. Объем прямоугльного параллепипеда по его сторонам a, b, c.
  2. Площадь круга по его радиусу r.
  3. Площадь трапеции по длинам ее оснований a, b и высоте h.
  4. Площадь равностороннего треугольника со сторой а.

Задача 2.2

Написать функцию, которая делает

новую точку

  1. Проекция точки на ось Х pnew = p.toX()
  2. Проекция точки на ось У pnew = p.toY()
  3. Точка на половине расстояния от точки до точки (0,0) pnew = p.half()
  4. Точка посередине между точками p1 и p2 pnew = p1.middle(p2)

Задача 2.3

Напишем в файле data.txt координаты и цвет точек:

3
-20 50 lightgreen
30 40 green
0 90 blue

Прочитаем их все и нарисуем

def read_and_draw():      
   x, y, color = input().split()
   x = int(x)
   y = int(y)
   
   
   p = Point(x, y, color)
   print(p)
   p.draw()

n = int(input())
for i in range(n):
   read_and_draw()

Задачи. В данных точках цветом red нарисовать

  1. Самую правую точку.
  2. Самую левую точку.
  3. Самую высокую точку.
  4. Самую низкую точку.

-- TatyanaDerbysheva - 11 Feb 2020

Attachment sort Action Size Date Who Comment
grid_example.png manage 12.4 K 11 Feb 2020 - 09:04 TatyanaDerbysheva grid example
point0.png manage 10.9 K 11 Feb 2020 - 09:17 TatyanaDerbysheva point example