Python ile Ekran İsmimizin Baş Harflerini Yazdırma

Örnekte verildiği gibi sadece print , for ve center komutları ile ekran M ve Y harflerini nasıl yazdırabilirim ?

art diye bir modül var.

İstediğiniz formatta yazdırabilirsiniz. Bir ara karıştırmıştım ve çok beğenmiştim.

Bu başlık altında birkaç modülü listelemiştim. İlginizi çekerse onlara da bakabilirsiniz.

attığım örnekteki gibi var mı peki bulamadım ama ?

Siz yine linkteki listeden kontrol edebilirsiniz. Ancak caligraphy fontu sizin istediğinize yakın gibi duruyor. Eğer bulamazsanız da kendiniz her harfi tasarlayarak yeni bir font oluşturmalısınız.

1 Beğeni
print("**     **               **    **")
print("**   **               **       **")
print("** **                **           **")
...
1 Beğeni

bu şekilde değil malesef

Zamanında benzer yazı oluşturmak için ben de araştırıp birkaç kod yazmıştım.
GitHub adresimdeki kodları inceleyebilirsin.
Belki işine yarar.

evet merhaba goz atmistim fakat sadece m ve y harfleri lazim sizin ki cok iyi bu arada tebrikler

Merhaba,

Ben şöyle bir yol izlerdim:

M için, [(0, 1, 0, 0), (0, 0, .5, .5), (.5, .5, 1, 0), (1, 0, 1, 1)] gibi;

Y için ise, [(0, 0, .5, .5), (.5, .5, 1, 0), (.5, .5, .5, 1)] gibi harfleri oluşturan çizgilerin birbirlerine eklemlendiği yerlerin koordinatlarını kullanırdım.

Başlangıç olarak çizimi yapacağım ekranı 2 boyutlu bir matris olarak düşünürdüm. Sonra da bu matrisin hangi koordinatlarının sembol ile doldurulacağını da harfi oluşturan doğru parçalarının başlangıç ve bitiş yerlerinin koordinatlarına göre belirlerdim.

Bu anlattıklarımın koda dökülmüş hali şöyle:

def draw_letter(letter_map, letter, symbol, n, table, start):
    if n % 2 == 0:
        return
    for i in [tuple(map(lambda i: int(i * (n - 1)), i)) for i in letter_map[letter]]:
        x1, y1, x2, y2 = i
        while x1 != x2 or y1 != y2:
            table[y1][start + x1] = symbol
            if x1 != x2:
                x1 += 1 if x1 < x2 else -1
            if y1 != y2:
                y1 += 1 if y1 < y2 else -1
        table[y1][start + x1] = symbol
        
        
def merge_letter_drawings(letter_map, letters, symbol, n):
    table = [[" " * len(symbol) for j in range(n * len(letters) + 1)] for i in range(n)]
    start = 0
    for letter in letters:
        draw_letter(letter_map, letter, symbol, n, table, start)
        start += (n + 1)
    for i in table:
        print(*i)
        

def main():
    letter_map = {
        "Y": [(0, 0, .5, .5), (.5, .5, 1, 0), (.5, .5, .5, 1)],
        "M": [(0, 1, 0, 0), (0, 0, .5, .5), (.5, .5, 1, 0), (1, 0, 1, 1)],
    }
    for i in range(5, 15, 2):    
        merge_letter_drawings(letter_map, "MY", "**", i)
        print()

    
        
main()

Bu kodları çalıştırırsanız aşağıdaki gibi bir çıktı alırsınız:

**          **    **          **
** **    ** **       **    **   
**    **    **          **      
**          **          **      
**          **          **      

**                **    **                **
** **          ** **       **          **   
**    **    **    **          **    **      
**       **       **             **         
**                **             **         
**                **             **         
**                **             **         

**                      **    **                      **
** **                ** **       **                **   
**    **          **    **          **          **      
**       **    **       **             **    **         
**          **          **                **            
**                      **                **            
**                      **                **            
**                      **                **            
**                      **                **            

**                            **    **                            **
** **                      ** **       **                      **   
**    **                **    **          **                **      
**       **          **       **             **          **         
**          **    **          **                **    **            
**             **             **                   **               
**                            **                   **               
**                            **                   **               
**                            **                   **               
**                            **                   **               
**                            **                   **               

**                                  **    **                                  **
** **                            ** **       **                            **   
**    **                      **    **          **                      **      
**       **                **       **             **                **         
**          **          **          **                **          **            
**             **    **             **                   **    **               
**                **                **                      **                  
**                                  **                      **                  
**                                  **                      **                  
**                                  **                      **                  
**                                  **                      **                  
**                                  **                      **                  
**                                  **                      **                  
                                                     

Bu kodun M ve Y harflerini sizin istediğiniz gibi oluşturup oluşturmadığından emin değilim. Ama tam olarak istediğiniz şekli oluşturmuyor olsa bile, size fikir verebileceğini sanıyorum.

İyi günler.

3 Beğeni

Mükemmel bir cevap ve anlatma sağolun . Ders veriyorsanız dinlerim hocam :slight_smile:

Belki forumda biraz vakit geçirmeniz, başkalarının sorularına cevap bulmaya çalışmanız bana ve başkalarına olduğu gibi size de faydalı olabilir. Bazı arkadaşlarımızın ilginç soruları ve cevapları oluyor. O sorulara vakit harcarken öğreniyorsunuz aslında. Bu ara çok sık sorulmuyor ama algoritmalarla alakalı sorular geliyor bazen. Yine gelir böyle sorular. Başka teknolojiler ile alakalı sorular oluyor. Sizinle alakalı olmasa bile bazen birisinin sorusundan veya o soruya verilen cevaplardan bir şeyler öğrenebiliyorsunuz.

Bu arada hoş geldiniz.

1 Beğeni

Benim de aklıma vektörel grafik kullanmak gelmişti. Ben bir de örnek harf çizimlerini vektörlere dönüştürmeyi planlamıştım:

class AsciiDrawer:
    def __init__(self, letter_map):
        self.letter_map = letter_map

    @staticmethod
    def _drawing_to_vectors(letter_drawing, dot, origin, whitespace):
        table = list(map(list, filter(None, letter_drawing.splitlines())))

        lenght_to_fill = len(max(table, key = len))
        for i in table:
            i.extend(whitespace for _ in range(lenght_to_fill - len(i)))

        def get(x, y):
            if x < 0 or y < 0: # we don't want to trip back
                return whitespace
            try:
                return table[y][x]
            except IndexError:
                return whitespace

        def rotate(x, y):
            return -y, x

        def scan_in_direction(x, y, dx, dy):
            cdx, cdy = dx, dy
            while True:
                c = get(x + cdx, y + cdy)
                if c == whitespace:
                    if cdx != dx or cdy != dy: # we need two different points for a line
                        line = (x, y, x + cdx - dx, y + cdy - dy)
                        line_variant = (line[2], line[3], line[0], line[1])
                        if line_variant in vectors:
                            return
                        vectors.append(line)
                    return
                marked.add((x + cdx, y + cdy))
                cdx += dx
                cdy += dy

        def scan(x, y):
            stepx, stepy = 1, 0
            cstepx, cstepy = 1, 1 # crosswise steps

            for _ in range(4): # four directions
                scan_in_direction(x, y, stepx, stepy)
                scan_in_direction(x, y, cstepx, cstepy)

                stepx, stepy = rotate(stepx, stepy)
                cstepx, cstepy = rotate(cstepx, cstepy)

        marked = set()
        vectors = []
        for y, row in enumerate(table):
            for x, c in enumerate(row):
                if c == origin:
                    scan(x, y)

        for y, row in enumerate(table):
            for x, c in enumerate(row):
                if get(x, y) == dot and (x, y) not in marked:
                    raise ValueError(f"unmarked dot {(x,y)}")

        # normalize
        maximum = max(j for i in vectors for j in i)
        for j, i in enumerate(vectors):
            vectors[j] = tuple(k / maximum for k in i)

        return vectors

    @classmethod
    def from_samples(cls, letter_drawings, dot = "*", origin = "O", whitespace = " "):
        return cls(dict(zip(
            letter_drawings.keys(),
            map(lambda x: cls._drawing_to_vectors(x, dot, origin, whitespace), letter_drawings.values()),
        )))

    def draw_letter_onto_table(self, letter, symbol, n, table, start):
        if n % 2 == 0:
            return
        for i in (map(lambda i: int(i * (n - 1)), i) for i in self.letter_map[letter]):
            x1, y1, x2, y2 = i
            while x1 != x2 or y1 != y2:
                table[y1][start + x1] = symbol
                if x1 != x2:
                    x1 += 1 if x1 < x2 else -1
                if y1 != y2:
                    y1 += 1 if y1 < y2 else -1
            table[y1][start + x1] = symbol
        
    
    def draw(self, letters, symbol = "*", size = 5, space_between_letters = 1, space_between_dots = 0):
        table = [[" " * len(symbol) for j in range(size * len(letters) + space_between_letters)] for i in range(size)]
        start = 0
        for letter in letters:
            self.draw_letter_onto_table(letter, symbol, size, table, start)
            start += size + space_between_letters

        space_between_dots *= " " # :P
        text = ""
        for i in table:
            text += space_between_dots.join(i) + "\n"
        return text

if __name__ == "__main__":
    letter_drawings = {
        "E": """
O***
*
O**
*
O***
""",
        "K": """
*  *
O *
**
O *  
*  * 
""",
        "R": """
O**O 
*  * 
**O  
*  * 
*  O 
""",
        "M": """
O   O
** **
* * *
*   *
*   *
"""
        }

    drawer = AsciiDrawer.from_samples(letter_drawings)
    for i in "EKREM":
        print(drawer.draw(i, "**", 5, 2, 0))
        print()

    ## print(drawer.draw("EKREM", "**", 5, 2, 0)) # hata veriyor

Bu şekilde çalışıyor lakin harfleri yan yana yazdırmaya çalışınca draw_letter_onto_table hata veriyor. İkiden fazla harf yazdırmıyor sanki. table’ın boyutlarında bir sıkıntı var.

1 Beğeni

Siz söyleyince ben de table’ı dinamik olacak şekilde değiştirdim. Bir önceki kodda, sadece MY yazdırdığım ve bu ifadede M ve Y arasında sadece bir tane boşluk olduğu için sadece o boşluğu düşünerek tabloyu oluşturmuşum. :sweat_smile:

table = [[" " * len(symbol) for j in range((n + 1) * len(letters) - 1)] for i in range(n)]

Karakter dizisini a b c şeklinde yazmak için, n * len(letters) sayısına len(letters) - 1 ekleyerek yani boşlukları da dahil ederek tablonun boyutunu optimal olacak şekilde hesaplayabiliriz.

Boşluksuz olsaydı, n * len(letters) ifadesi, tablo uzunluğunu harflere göre oluştururdu. Ama o zamanda da start’ı n + 1 ile değil n ile yükseltmemiz gerekirdi.

Deneme:

def main():
    letter_map = {
        "Y": [(0, 0, .5, .5), (.5, .5, 1, 0), (.5, .5, .5, 1)],
        "M": [(0, 1, 0, 0), (0, 0, .5, .5), (.5, .5, 1, 0), (1, 0, 1, 1)],
    }  
    merge_letter_drawings(letter_map, "MMMMYYYY", "**", 5)

          
main()
**          **    **          **    **          **    **          **    **          **    **          **    **          **    **          **
** **    ** **    ** **    ** **    ** **    ** **    ** **    ** **       **    **          **    **          **    **          **    **   
**    **    **    **    **    **    **    **    **    **    **    **          **                **                **                **      
**          **    **          **    **          **    **          **          **                **                **                **      
**          **    **          **    **          **    **          **          **                **                **                **      

1 Beğeni

Ben de bir kaç ekleme yaptım:

# see https://stackoverflow.com/questions/8749542/creating-a-defaultlist-in-python
class defaultlist(list):
    def __init__(self, fx):
        self._fx = fx
        
    def _fill(self, index):
        while len(self) <= index:
            self.append(self._fx())
            
    def __setitem__(self, index, value):
        self._fill(index)
        list.__setitem__(self, index, value)
        
    def __getitem__(self, index):
        self._fill(index)
        return list.__getitem__(self, index)

class AsciiDrawer:
    def __init__(self, letter_map):
        self.letter_map = letter_map

    @staticmethod
    def _drawing_to_vectors(letter_drawing, dot, origin, whitespace, stop):
        table = list(map(list, filter(None, letter_drawing.splitlines())))

        lenght_to_fill = len(max(table, key = len))
        for i in table:
            i.extend(whitespace for _ in range(lenght_to_fill - len(i)))

        def get(x, y):
            if x < 0 or y < 0: # we don't want to trip back
                return whitespace
            try:
                return table[y][x]
            except IndexError:
                return whitespace

        def rotate(x, y):
            return -y, x

        def scan_in_direction(x, y, dx, dy):
            cdx, cdy = dx, dy
            while True:
                c = get(x + cdx, y + cdy)
                if c == whitespace:
                    if cdx != dx or cdy != dy: # we need two different points for a line
                        line = (x, y, x + cdx - dx, y + cdy - dy)
                        line_variant = (line[2], line[3], line[0], line[1])
                        if line_variant in vectors:
                            return
                        vectors.append(line)
                    return
                elif c == stop:
                    marked.add((x + cdx, y + cdy))
                    line = (x, y, x + cdx, y + cdy)
                    vectors.append(line)
                    return
                elif c == dot:
                    marked.add((x + cdx, y + cdy))
                elif c == origin:
                    pass
                else:
                    raise ValueError

                cdx += dx
                cdy += dy

        def scan(x, y):
            stepx, stepy = 1, 0
            cstepx, cstepy = 1, 1 # crosswise steps

            for _ in range(4): # four directions
                scan_in_direction(x, y, stepx, stepy)
                scan_in_direction(x, y, cstepx, cstepy)

                stepx, stepy = rotate(stepx, stepy)
                cstepx, cstepy = rotate(cstepx, cstepy)

        # scan
        marked = set()
        vectors = []
        for y, row in enumerate(table):
            for x, c in enumerate(row):
                if c == origin:
                    scan(x, y)

        # check marked dots
        for y, row in enumerate(table):
            for x, c in enumerate(row):
                if get(x, y) in (dot, stop) and (x, y) not in marked:
                    raise ValueError(f"unmarked dot {(x,y)}")

        # normalize
        maximum = max(j for i in vectors for j in i)
        for j, i in enumerate(vectors):
            vectors[j] = tuple(k / maximum for k in i)

        return vectors

    @classmethod
    def from_samples(cls, letter_drawings, dot = "*", origin = "O", whitespace = " ", stop = "-"):
        return cls(dict(zip(
            letter_drawings.keys(),
            map(lambda x: cls._drawing_to_vectors(x, dot, origin, whitespace, stop), letter_drawings.values()),
        )))

    def _draw_letter_onto_table(self, letter, symbol, n, table, start):
        if n % 2 == 0:
            return
        for i in (map(lambda i: int(i * (n - 1)), i) for i in self.letter_map[letter]):
            x1, y1, x2, y2 = i
            while x1 != x2 or y1 != y2:
                table[y1][start + x1] = symbol
                if x1 != x2:
                    x1 += 1 if x1 < x2 else -1
                if y1 != y2:
                    y1 += 1 if y1 < y2 else -1
            table[y1][start + x1] = symbol
        
    
    def draw(self, letters, symbol = "*", size = 5, space_between_letters = 1, space_between_dots = 0):
        table = defaultlist(lambda: defaultlist(lambda: " " * len(symbol)))
        start = 0
        for letter in letters:
            self._draw_letter_onto_table(letter, symbol, size, table, start)
            start += size + space_between_letters

        space_between_dots *= " " # :P
        text = "\n".join(space_between_dots.join(i) for i in table)
        return text

if __name__ == "__main__":
    letter_drawings = {
        "E": """
O***
*
O**
*
O***
""",
        "K": """
*  O
* *
O-
* *  
*  O 
""",
        "R": """
O**O 
*  * 
**O  
*  * 
*  O 
""",
        "M": """
O   O
** **
* * *
*   *
*   *
"""
        }

    drawer = AsciiDrawer.from_samples(letter_drawings)
    print()
    print("\n\n\n".join(drawer.draw("EKREM", "**", i, 0, 0) for i in range(5, 12, 2)))

2 Beğeni