diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..74570cd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +name: CI + +on: + push: + branches: [ main, feature/radaev ] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: pip install pytest + + - name: Run tests + run: pytest diff --git a/.github/workflows/github-actions-demo.yml b/.github/workflows/github-actions-demo.yml deleted file mode 100644 index b00f8e9..0000000 --- a/.github/workflows/github-actions-demo.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: GitHub Actions Demo -run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 -on: [push] -jobs: - Explore-GitHub-Actions: - runs-on: ubuntu-latest - steps: - - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - name: Check out repository code - uses: actions/checkout@v5 - - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3e6afc8 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,22 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build project + run: echo "Собираем проект..." + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + name: Release ${{ github.ref_name }} + body: Автоматический релиз новой версии diff --git a/.github/workflows/test-pipeline.yml b/.github/workflows/test-pipeline.yml deleted file mode 100644 index b16d2ae..0000000 --- a/.github/workflows/test-pipeline.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Test pipeline -run-name: Testing our repository -on: [push] -jobs: - Build: - runs-on: ubuntu-latest - steps: - - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - name: Check out repository code - uses: actions/checkout@v5 - - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/design_patterns/abstract_factory.py b/design_patterns/abstract_factory.py new file mode 100644 index 0000000..d5ea41c --- /dev/null +++ b/design_patterns/abstract_factory.py @@ -0,0 +1,15 @@ +from abc import ABC, abstractmethod + +class Button(ABC): + @abstractmethod + def paint(self): pass + +class WinButton(Button): + def paint(self): return "Windows button" + +class GUIFactory(ABC): + @abstractmethod + def create_button(self): pass + +class WinFactory(GUIFactory): + def create_button(self): return WinButton() diff --git a/design_patterns/builder.py b/design_patterns/builder.py new file mode 100644 index 0000000..24a318d --- /dev/null +++ b/design_patterns/builder.py @@ -0,0 +1,19 @@ +class Car: + def __init__(self): + self.engine = None + self.seats = None + +class CarBuilder: + def __init__(self): + self.car = Car() + + def set_engine(self, engine): + self.car.engine = engine + return self + + def set_seats(self, seats): + self.car.seats = seats + return self + + def build(self): + return self.car diff --git a/design_patterns/factory_method.py b/design_patterns/factory_method.py new file mode 100644 index 0000000..df5208b --- /dev/null +++ b/design_patterns/factory_method.py @@ -0,0 +1,18 @@ +from abc import ABC, abstractmethod + +class Transport(ABC): + @abstractmethod + def deliver(self): pass + +class Truck(Transport): + def deliver(self): return "Доставка грузовиком" + +class Logistics(ABC): + @abstractmethod + def create_transport(self): pass + + def plan(self): + return self.create_transport().deliver() + +class RoadLogistics(Logistics): + def create_transport(self): return Truck() diff --git a/design_patterns/singleton.py b/design_patterns/singleton.py new file mode 100644 index 0000000..7a835a3 --- /dev/null +++ b/design_patterns/singleton.py @@ -0,0 +1,6 @@ +class Singleton: + _instance = None + def __new__(cls): + if not cls._instance: + cls._instance = super().__new__(cls) + return cls._instance diff --git a/main.py b/main.py new file mode 100644 index 0000000..3bddbbe --- /dev/null +++ b/main.py @@ -0,0 +1,2 @@ +def hello(): + return "Hello, CI/CD!" diff --git a/patterns2/adapter.py b/patterns2/adapter.py new file mode 100644 index 0000000..9ff9698 --- /dev/null +++ b/patterns2/adapter.py @@ -0,0 +1,36 @@ +cat > adapter.py << 'EOF' +class EuropeanSocket: + def voltage(self): + return 220 + + def plug(self): + return "Европейская вилка" + +class AmericanSocket: + def voltage(self): + return 110 + + def plug_type(self): + return "Американская вилка" + +class Adapter: + def __init__(self, socket): + self.socket = socket + + def voltage(self): + return self.socket.voltage() + + def plug(self): + if hasattr(self.socket, 'plug_type'): + return f"Адаптер для {self.socket.plug_type()}" + return self.socket.plug() + +# Пример +if __name__ == "__main__": + eu_socket = EuropeanSocket() + print(f"Европа: {eu_socket.voltage()}V, {eu_socket.plug()}") + + us_socket = AmericanSocket() + adapter = Adapter(us_socket) + print(f"США через адаптер: {adapter.voltage()}V, {adapter.plug()}") +EOF \ No newline at end of file diff --git a/patterns2/bridge.py b/patterns2/bridge.py new file mode 100644 index 0000000..6c977a7 --- /dev/null +++ b/patterns2/bridge.py @@ -0,0 +1,39 @@ +cat > bridge.py << 'EOF' +class Device: + def turn_on(self): + pass + + def turn_off(self): + pass + +class TV(Device): + def turn_on(self): + return "TV включен" + + def turn_off(self): + return "TV выключен" + +class Radio(Device): + def turn_on(self): + return "Radio включен" + + def turn_off(self): + return "Radio выключен" + +class Remote: + def __init__(self, device): + self.device = device + + def toggle_power(self): + pass + +class BasicRemote(Remote): + def toggle_power(self): + return self.device.turn_on() + +# Пример +if __name__ == "__main__": + tv = TV() + remote = BasicRemote(tv) + print(remote.toggle_power()) +EOF \ No newline at end of file diff --git a/patterns2/chain.py b/patterns2/chain.py new file mode 100644 index 0000000..26c290c --- /dev/null +++ b/patterns2/chain.py @@ -0,0 +1,41 @@ +cat > chain_of_responsibility.py << 'EOF' +class Handler: + def __init__(self): + self.next = None + + def set_next(self, handler): + self.next = handler + return handler + + def handle(self, request): + if self.next: + return self.next.handle(request) + return None + +class TechnicalSupport(Handler): + def handle(self, request): + if request == "": + return " " + return super().handle(request) + +class BillingSupport(Handler): + def handle(self, request): + if request == "": + return " " + return super().handle(request) + +class GeneralSupport(Handler): + def handle(self, request): + return " " + +# +if __name__ == "__main__": + tech = TechnicalSupport() + billing = BillingSupport() + general = GeneralSupport() + + tech.set_next(billing).set_next(general) + + print(tech.handle("")) + print(tech.handle("")) +EOF \ No newline at end of file diff --git a/patterns2/iterator.py b/patterns2/iterator.py new file mode 100644 index 0000000..22be342 --- /dev/null +++ b/patterns2/iterator.py @@ -0,0 +1,32 @@ +cat > iterator.py << 'EOF' +class BookCollection: + def __init__(self): + self.books = [] + + def add_book(self, book): + self.books.append(book) + + def __iter__(self): + return BookIterator(self.books) + +class BookIterator: + def __init__(self, books): + self.books = books + self.index = 0 + + def __next__(self): + if self.index < len(self.books): + book = self.books[self.index] + self.index += 1 + return book + raise StopIteration + +# +if __name__ == "__main__": + library = BookCollection() + library.add_book(" ") + library.add_book(" ") + + for book in library: + print(f": {book}") +EOF \ No newline at end of file diff --git a/patterns2/proxy.py b/patterns2/proxy.py new file mode 100644 index 0000000..3a21d49 --- /dev/null +++ b/patterns2/proxy.py @@ -0,0 +1,32 @@ +cat > proxy.py << 'EOF' +class Image: + def display(self): + pass + +class RealImage(Image): + def __init__(self, filename): + self.filename = filename + self.load_from_disk() + + def load_from_disk(self): + print(f" {self.filename}") + + def display(self): + print(f" {self.filename}") + +class ProxyImage(Image): + def __init__(self, filename): + self.filename = filename + self.real_image = None + + def display(self): + if not self.real_image: + self.real_image = RealImage(self.filename) + self.real_image.display() + +# +if __name__ == "__main__": + image = ProxyImage("photo.jpg") + image.display() # + image.display() # ( ) +EOF \ No newline at end of file diff --git a/patterns2/strategy.py b/patterns2/strategy.py new file mode 100644 index 0000000..52a5f77 --- /dev/null +++ b/patterns2/strategy.py @@ -0,0 +1,37 @@ +cat > strategy.py << 'EOF' +class PaymentStrategy: + def pay(self, amount): + pass + +class CreditCardPayment(PaymentStrategy): + def pay(self, amount): + return f"Оплата {amount} руб. кредитной картой" + +class PayPalPayment(PaymentStrategy): + def pay(self, amount): + return f"Оплата {amount} руб. через PayPal" + +class ShoppingCart: + def __init__(self): + self.items = [] + self.strategy = None + + def set_payment_strategy(self, strategy): + self.strategy = strategy + + def add_item(self, item): + self.items.append(item) + + def checkout(self): + total = sum(self.items) + return self.strategy.pay(total) + +# Пример +if __name__ == "__main__": + cart = ShoppingCart() + cart.add_item(100) + cart.add_item(200) + + cart.set_payment_strategy(CreditCardPayment()) + print(cart.checkout()) +EOF \ No newline at end of file diff --git a/radaev/README.md b/radaev/README.md new file mode 100644 index 0000000..dfb2a4a Binary files /dev/null and b/radaev/README.md differ diff --git a/test_file.txt b/test_file.txt new file mode 100644 index 0000000..3a37543 --- /dev/null +++ b/test_file.txt @@ -0,0 +1 @@ +# Test for CI diff --git a/test_main.py b/test_main.py new file mode 100644 index 0000000..c49be78 --- /dev/null +++ b/test_main.py @@ -0,0 +1,4 @@ +from main import hello + +def test_hello(): + assert hello() == "Hello, CI/CD!"