paint-brush
Python'da Durum Desenini Kullanarak Sonsuz Uzun Bir Deneme Yazmakile@aayn
2,430 okumalar
2,430 okumalar

Python'da Durum Desenini Kullanarak Sonsuz Uzun Bir Deneme Yazmak

ile Aayush Naik10m2023/12/27
Read on Terminal Reader

Çok uzun; Okumak

Durum tasarım modeli, nesne yönelimli koddaki durum makineleridir. Deseni bir makale/cümle oluşturucu oluşturmak için kullanırız.
featured image - Python'da Durum Desenini Kullanarak Sonsuz Uzun Bir Deneme Yazmak
Aayush Naik HackerNoon profile picture
0-item

Sonsuz uzunlukta bir makale yazalım! Ama bu imkansız bir görev. Ancak sonsuza kadar çalıştırılırsa sonsuz uzunlukta bir makale üretecek bir süreç yaratabiliriz. Yeterince yakın .


Artık tek bir Python kodu satırıyla uzun ve tekrarlayan bir makale oluşturabilirsiniz:


 >>> "This is water. " * 20 'This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. This is water. '


Yaawn … yuhalıyor! Bunun yerine, bu makalede Devlet tasarım modelini kullanarak çok daha ilginç bir makale oluşturacağız.


İlk olarak durum makinelerinin ne olduğunu ve bunların Durum tasarım modeliyle nasıl ilişkili olduğunu anlayacağız. Daha sonra, (makul ölçüde) ilginç ve sonsuz bir makale üretebilecek bir durum makinesi yaratacağız. Daha sonra kısaca durum tasarım deseninin üzerinden geçeceğiz. Son olarak, durum tasarım modelini kullanarak bu durum makinesini nesne yönelimli koda çevireceğiz.


Yazılım tasarım kalıpları, yaygın olarak ortaya çıkan sorunları çözmenin etkili yollarındandır. Durum modeli gibi yazılım tasarım modelleri, uygun şekilde uygulandığında daha iyi ölçeklenebilir, bakımı yapılabilir ve test edilebilir yazılımlar yazmanıza yardımcı olabilir.

Durum Makinesi

Temelde, Durum tasarım modeli, Durum Makinesini nesne yönelimli koda dönüştürür.


Durum makinelerine aşina değilseniz, bu oldukça basit bir kavramdır. Bir durum makinesinin durumları ve geçişleri vardır. Durumlar, çıkar sistemimizin belirli özellikleridir ve durum geçişleri, bu özellikleri değiştiren ve dolayısıyla aynı zamanda durum değişikliğine neden olan eylemlerdir.


(Diğer şeylerin yanı sıra) Robotik geçmişim olduğundan ve Robotik alanında durum makineleri yaygın olarak kullanıldığından, durum makinelerinin nasıl çalıştığını göstermek için basit bir robot elektrikli süpürge örneğini kullanacağım.


Robot elektrikli süpürgeyi çalıştıracak durum makinesi.


Durum makinesi diyagramı, durum makineleriyle hiç karşılaşmamış olsanız bile, robotun nasıl çalıştığına dair sezgisel bir resim çizer. Bu işlemi adım adım inceleyelim.


  1. Robot Yerleştirilmiş durumda başlar (siyah nokta başlangıç durumunu gösterir).
  2. Robot pilinin zayıf olduğunu tespit ederse, pili dolana kadar kendi kendini şarj etmeye başlar ( Şarj durumu). Pil dolduğunda Yerleştirilmiş durumuna geri döner.
  3. Yerleştirilmiş durumda, robot zeminin kirli olduğunu (ve pilinin zayıf olmadığını) tespit ederse zemini temizlemeye başlar ( Temizleme durumu).
  4. Temizleme durumunda robotun pili azalırsa kendi kendini şarj etmeye başlar. Zemin temizse robot bağlantı istasyonuna ( Yerleştirilmiş durum) geri döner.


Bu nedenle, robot elektrikli süpürgemizin üç durumu vardır: Yerleştirildi , Temizleniyor ve Şarj Ediliyor - ve zeminin ve pilinin duyusal algılanmasına dayalı geçişler vardır.


Sonsuz makale için basit durum makinesi

Artık durum makinelerini temel düzeyde anladığımıza göre, sonsuz bir makale yazabilen bir durum makinesi oluşturalım.


Sonsuz deneme oluşturmak için durum makinesi - sürüm 1


Yukarıda kısa, basit cümlelerden oluşan bir makale oluşturmak için İngilizce dilbilgisini kullanan bir durum makinesi bulunmaktadır. Çok yakında daha ilginç bir versiyona ulaşacağımıza söz veriyorum ama bu, konuyu anlamak için iyi bir başlangıç noktası olmalı. Nasıl çalıştığını gözden geçirelim.


  1. İsim durumundan başlayarak, önceden tanımlanmış bazı isimler listesinden seçim yaparak bir isim üretiriz. İsmimizin “Dünya” olduğunu varsayalım. (şimdiye kadarki cümle: “Dünya”)
  2. Daha sonra Fiil durumuna geçiyoruz ve bir sonraki fiili üretiyoruz (“havlıyor” diyelim). (şimdiye kadarki cümle: “Dünya havlıyor”)
  3. Sıfat durumunda bir sıfat (“kırmızı” diyelim) üretiriz. (şimdiye kadarki cümle: “Dünya kırmızı havlıyor”)
  4. Daha sonra Endmark durumunda son noktalama işaretlerinden birini oluşturuyoruz, “!” diyoruz. (cümle: “Dünya kırmızı havlıyor!”)
  5. Sonunda makaledeki bir sonraki cümleyi oluşturmak için İsim durumuna geri döndük.


Bu durum makinesi buna benzeyen (saçma) bir makale üretebilir.


Dünya kırmızı havlıyor! Kuzen Harry faul mü yağdırıyor? Kaplanlar eğlenceli bir şekilde parlıyor. …


Sonsuz deneme için deterministik olmayan durum makinesi

Her ne kadar "deterministik olmayan" kulağa karmaşık gelse de bizim amaçlarımız açısından bu sadece biraz rastgelelik eklemek anlamına geliyor. Temel olarak bazı eyaletlere geçmeden önce bir tür yazı-tura atışı ekliyoruz. Ne demek istediğimi anlayacaksın.

Sonsuz deneme oluşturmak için deterministik olmayan durum makinesi - sürüm 2


Yukarıdaki deterministik olmayan durum makinesi öncekine çok benzer. Tek farklar şunlardır:

  • Olumsuzluklar "hayır" veya "değil" gibi kelimelerdir ve bağlaçlar "ve" ve "ama" gibi kelimelerdir.
  • Fiil durumunda, bir fiil üretiriz ve ardından yazı tura atarız. Eğer tura gelirse (%50 olasılık), Olumsuzluk durumuna gideriz; aksi takdirde Sıfat durumuna gideriz.
  • Benzer şekilde, Sıfat durumunda, bir sıfat üretiriz ve sonra yazı tura atarız. Eğer tura gelirse, Kavuşum durumuna gideriz; eğer yazı ise o zaman Endmark durumuna gideriz.


Rastgeleliğin, olumsuzluğun ve bağlaçların devreye girmesiyle artık daha ilginç ve değişken uzunlukta cümleler oluşturabiliyoruz.


Durum Tasarım Deseni

Şimdi durum tasarım modelinin nasıl çalıştığını anlayalım. Bir kez daha, bir durum makinesini nesne yönelimli koda çevirmeye çalıştığımızı unutmayın.


Makale oluşturma durum makinesinde, her durumun iki şey yapması gerektiğini gözlemleyin.

  1. Biraz eylem gerçekleştirin. Bu durumda bir kelime (isim, sıfat vb.) üretiliyor.
  2. Bir sonraki duruma geçiş. İsimden Fiile vb .


Belirli bir devletin bakış açısından, bilmesi veya yapması gereken başka hiçbir şey yoktur. Tüm sistemin (tüm durumları ve geçişleri) karmaşıklığı nedeniyle çıkmaza girmek yerine, her seferinde yalnızca bir duruma odaklanabiliriz. Benim görüşüme göre, bu tür bir izolasyon ve ayrışma , Devlet modelinin en büyük çekiciliğidir.


Aşağıda, Durum tasarım deseni için bir UML diyagramımız var. Her bir durumun içinde çalıştığı, Context sınıfı tarafından gösterilen bir bağlam vardır. Bağlam nesnesi, eylemini gerçekleştirmek üzere geçerli durumu çağırmak için kullandığı özel bir durum özniteliğine sahiptir. Her durum, eylemini veya işlemini gerçekleştirmek ve bir sonraki duruma geri dönmek için yöntemler içeren bir State arayüzünü uygular.


Durum tasarım modeli UML diyagramı


Bunu makale oluşturma örneğine eşlersek, UML diyagramı şöyle görünür.


Makale üretimi için uygulanan durum modeli


WordState artık bir arayüz yerine soyut bir sınıftır (italik ile gösterilir). Soyut sınıflar bazı soyut (gerçekleştirilmemiş) yöntem ve niteliklere sahip olabilirken diğerleri tanımlanabilir. Arayüzler tamamen soyuttur: tüm yöntemleri soyuttur. Bu değişikliği yaptım çünkü generateWord uygulaması tüm eyaletlerde aynı ve mükerrer kodlardan kaçınmak iyi bir şey.


Yukarıdaki özelliklerin ve yöntemlerin her birini ayrı ayrı inceleyelim. EssayContext sınıfında şunlara sahibiz:

  • state : Geçerli WordState nesnesine referans.
  • essayBody : Şu ana kadar oluşturulan tüm kelimelerin listesi.
  • setState() : state niteliğini değiştiren ayarlayıcı.
  • addWord() : Bir sonraki sözcüğü makale gövdesine ekleme yöntemi.
  • generateEssay() : Makalemizi oluşturmak için bu metodu çağırıyoruz; essayBody uzunluğu length büyük olduğunda dururuz.
  • printEssay() : Oluşturulan makalenin bir dizesini döndürür.


Soyut WordState sınıfında elimizde:

  • wordList : Oluşturulacak kelimeleri seçtiğimiz kelimelerin listesi için soyut özellik (italik ile gösterilir).
  • generateWord() : Oluşturulan kelimeyi makale bağlamına ekleyen yöntem.
  • nextState() : Sonraki durumu döndürmek için soyut yöntem.


NounState WordState devralınan diğer tüm somut durumlar için temsili bir örnek olarak kullanacağız.

  • wordList : Oluşturulacak kelimeleri seçtiğimiz isimlerin listesi.
  • nextState() : Sonraki durumu döndürür.


Artık bunu kodda uygulamak için ihtiyacımız olan her şeye sahibiz. Devam edelim ve aynen bunu yapalım!


Python Kodu

Öncelikle EssayContext sınıfını essay_context.py adlı bir dosyaya yazalım. Deve vakasını bir kenara bırakıp yılan vakasına geçeceğiz çünkü Python bir... yılandır (kusura bakmayın).


 from word_state import WordState class EssayContext: def __init__(self, state: WordState): self.state = state self.essay_body: list[str] = [] def set_state(self, state: WordState): self.state = state def add_word(self, word: str): self.essay_body.append(word) def generate_essay(self, length: int): while len(self.essay_body) < length: self.state.generate_word(self) def print_essay(self) -> str: return " ".join(self.essay_body)


Daha sonra durumları word_state.py adlı bir dosyaya ekleyelim.


 import abc import numpy as np class WordState(abc.ABC): word_list: list[str] @classmethod def generate_word(cls, context: "EssayContext"): word = np.random.choice(cls.word_list) context.add_word(word) context.set_state(cls.next_state()) @classmethod @abc.abstractmethod def next_state(cls) -> "WordState": pass class NounState(WordState): word_list: list[str] = ["everything", "nothing"] @classmethod def next_state(cls): return VerbState class VerbState(WordState): word_list: list[str] = ["is", "was", "will be"] @classmethod def next_state(cls): heads = np.random.rand() < 0.5 if heads: return NegationState return AdjectiveState class NegationState(WordState): word_list: list[str] = ["not"] @classmethod def next_state(cls): return AdjectiveState class AdjectiveState(WordState): word_list: list[str] = ["fantastic", "terrible"] @classmethod def next_state(cls): heads = np.random.rand() < 0.5 if heads: return ConjunctionState return EndmarkState class ConjunctionState(WordState): word_list: list[str] = ["and", "but"] @classmethod def next_state(cls): return NounState class EndmarkState(WordState): word_list: list[str] = [".", "!"] @classmethod def next_state(cls): return NounState


Son olarak main.py dosyasındaki her şeyi çalıştıracak kodu ekleyelim.


 from essay_context import EssayContext from word_state import NounState if __name__ == '__main__': ctx = EssayContext(NounState) ctx.generate_essay(100) print(ctx.print_essay())


python main.py çalıştırmak bize aşağıdaki çıktıyı verir (determinizm olmadığı için her seferinde farklıdır):


 'everything is not terrible and nothing was terrible ! everything will be not fantastic but everything is fantastic . everything will be fantastic . nothing will be fantastic and nothing will be terrible ! everything was not fantastic and everything will be not terrible . everything was terrible . nothing was terrible but nothing will be fantastic ! nothing is not terrible . nothing was not fantastic but everything was not fantastic ! everything will be not fantastic but everything will be terrible ! everything will be not fantastic . everything is fantastic but nothing will be not terrible ! everything will be not fantastic but nothing was not fantastic !'


Bu kadar basit bir sistem için fena değil! Ayrıca makale oluşturmayı daha karmaşık hale getirmek için çeşitli kelime listelerini genişletebilir veya daha fazla durum ekleyebiliriz. Makalelerimizi bir sonraki seviyeye taşımak için bazı LLM API'lerini bile tanıtabiliriz.


Son düşünceler

Durum makineleri ve Durum modeli, iyi tanımlanmış bir "durum" kavramıyla sistemleri modellemek ve yaratmak için mükemmel bir uyum sağlar. Yani her durumla ilişkilendirilen belirli davranışlar ve özellikler vardır. Robot elektrikli süpürge temizliyor, yerleştirilmiş veya şarj oluyor. TV'niz AÇIK veya KAPALI olabilir ve TV'nin uzaktan kumanda düğmeleri TV'nin durumuna göre farklı şekilde hareket edecektir.


Aynı zamanda iyi tanımlanmış bir modele sahip dizileri oluşturmak veya tanımlamak için de iyi bir seçimdir. Bu, makale oluşturma örneğimiz için geçerlidir.


Son olarak şunu sorabilirsiniz: "Bütün bunların amacı ne?" Bu "sonsuz" makaleyi oluşturmak için neden çeşitli durumları ve sınıfları tanımlama zahmetine katlandık? Aynı davranışı elde etmek için 20 (veya daha az) satırlık Python kodu yazabilirdik.


Kısa cevap daha iyi ölçeklenebilirlik içindir.


Sadece üç veya beş eyalet yerine 50 veya 500 eyaletimiz olduğunu hayal edin. Bu abartı değil; gerçek kurumsal sistemler bu seviyede bir karmaşıklığa sahiptir. Birdenbire Devlet modeli, ayrıştırılması ve izolasyonu nedeniyle çok daha çekici görünüyor. Tüm sistemi kafamızda tutmak zorunda kalmadan, aynı anda yalnızca bir duruma odaklanabiliriz. Bir durum diğerlerini etkilemeyeceği için değişiklik yapmak daha kolaydır. Ayrıca ölçeklenebilir ve bakımı yapılabilir bir sistemin büyük bir parçası olan birim testlerinin daha kolay yapılmasına da olanak tanır.


Sonuçta Devlet modeli yalnızca devletleri yönetmekle ilgili değildir; Tüm tasarım modelleri gibi, karmaşık olduğu kadar ölçeklenebilir ve bakımı da yapılabilir bina sistemleri için bir plandır.