Ö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.
print("** ** ** **")
print("** ** ** **")
print("** ** ** **")
...
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.
Mükemmel bir cevap ve anlatma sağolun . Ders veriyorsanız dinlerim hocam
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.
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.
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.
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()
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
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)))