ASCII art

Deze pagina bevat uitvoerbare code.

Belangrijke beperking bij deze opdrachten: in deze opgave mag je de string-vermenigvuldig- en string-opteloperatoren niet gebruiken. Omdat ons doel is om lusconstructies te gebruiken, moet je lussen gebruiken om te herhalen, ook als het met deze operatoren korter zou kunnen. Hier is één uitzondering op: je mag string-vermenigvuldiging gebruiken met het spatieteken.

Opdracht 1

Schrijf een functie print_rect die drie argumenten meekrijgt, width, height en symbol, en een rechthoek van width bij height met symbolen afdrukt op het scherm.

def print_rect(width, height, symbol):
    """Drukt een rechthoek van width bij height af, gevuld met symbol."""
    for row in range(height):
        for column in range(width):
            print(symbol, end=" ")
        print()


print_rect(4, 6, "%")
% % % % 
% % % % 
% % % % 
% % % % 
% % % % 
% % % % 

Om makkelijker bij te houden welke lus de rijen doorloopt en welke de kolommen, worden hier row en column als variabelenamen gebruikt in plaats van i en j.

Opdracht 2

Schrijf een functie print_triangle die drie argumenten meekrijgt: width, symbol en right_side_up, en een driehoek van symbolen op het scherm afdrukt.

def print_triangle(width, symbol, right_side_up):
    """Drukt een driehoek van symbol af met breedte width.

    right_side_up bepaalt of de punt naar boven (True) of naar
    beneden (False) wijst.
    """
    for i in range(0, width):
        if right_side_up:  # punt naar boven
            for j in range(0, i + 1):
                print(symbol, end=" ")
        else:
            for j in range(0, width - i):
                print(symbol, end=" ")
        print()


print_triangle(3, "@", True)
print()
print_triangle(3, "@", False)
@ 
@ @ 
@ @ @ 

@ @ @ 
@ @ 
@ 

Bij een punt naar boven bevat de eerste regel 1 symbool en hebben de volgende regels er elke keer 1 meer. Je kunt dit ook zien als: het regelnummer is gelijk aan het aantal symbolen dat afgedrukt moet worden. Daar maken we gebruik van door de range in de eerste j-lus (de kolomlus) af te laten hangen van i + 1. De + 1 corrigeert dat de range van i bij nul begint.

Bij de punt naar beneden werken we van breed naar smal, van het maximale aantal terug naar 1 symbool. Daarom wordt in het else-deel met width - i gewerkt in de range van de lus. Hier corrigeren we de nul van i niet, omdat elke regel dan juist een symbool te weinig zou hebben.

Opdracht 3

Gebruik nu je functie print_triangle om een functie print_bumps(num, symbol1, symbol2) te schrijven die het gegeven aantal heuvels van twee symbolen afdrukt, waarbij elke heuvel groter is dan de vorige.

def print_bumps(num, symbol1, symbol2):
    """Drukt num heuvels af van symbol1 en symbol2, elke heuvel groter dan de vorige."""
    for bumps in range(1, num + 1):
        print_triangle(bumps, symbol1, True)
        print_triangle(bumps, symbol2, False)


print_bumps(4, "%", "#")
% 
# 
% 
% % 
# # 
# 
% 
% % 
% % % 
# # # 
# # 
# 
% 
% % 
% % % 
% % % % 
# # # # 
# # # 
# # 
# 

Het aantal heuvels neemt elke keer met 1 toe. Daar kunnen we de lusvariabele voor gebruiken.

Opdracht 4

Schrijf een functie print_diamond(width, symbol) die een ruit met symbolen afdrukt waarvan de maximale breedte bepaald wordt door width. Voor deze ruitfuncties mag je string-vermenigvuldiging gebruiken, maar alleen voor strings van spaties.

def print_diamond(width, symbol):
    """Drukt een ruit van symbol af met maximale breedte width."""
    # het bovenste deel van de ruit
    for i in range(1, width + 1):
        print(" " * (width - i), end="")
        for j in range(0, i):
            print(symbol, end=" ")
        print()
    # het onderste deel van de ruit
    for i in range(1, width):
        print(" " * i, end="")
        for j in range(0, width - i):
            print(symbol, end=" ")
        print()


print_diamond(3, "&")
  & 
 & & 
& & & 
 & & 
  & 

Net als bij print_triangle maken we gebruik van de regel waarop we zitten (i) en van de vraag of we van weinig symbolen naar veel gaan (het bovenste deel) of juist andersom (het onderste deel). In dit geval beginnen we alle ranges bij 1, om zo het juiste aantal spaties vóór het eerste symbool te krijgen.

Als je moeite hebt de opdracht voor je te zien, teken de ruit dan eerst uit op ruitjespapier. Omdat we na elk symbool een spatie afdrukken, is de breedte van het symboolveld width * 2 - 1. Variabele i is de rij en variabele j is de kolom.

Opdracht 5

Schrijf nu een functie print_striped_diamond(width, sym1, sym2) die een gestreepte ruit van sym1 en sym2 afdrukt.

def print_striped_diamond(width, sym1, sym2):
    """Drukt een ruit af met maximale breedte width, waarin sym1 en sym2 elkaar afwisselen."""
    for i in range(1, width + 1):
        print(" " * (width - i), end="")
        for j in range(0, i):
            if j % 2 == 0:
                print(sym1, end=" ")
            else:
                print(sym2, end=" ")
        print()
    for i in range(1, width):
        print(" " * i, end="")
        for j in range(0, width - i):
            if i % 2 == 1:
                if j % 2 == 0:
                    print(sym2, end=" ")
                else:
                    print(sym1, end=" ")
            else:
                if j % 2 == 1:
                    print(sym2, end=" ")
                else:
                    print(sym1, end=" ")
        print()


print_striped_diamond(7, ".", "%")
      . 
     . % 
    . % . 
   . % . % 
  . % . % . 
 . % . % . % 
. % . % . % . 
 % . % . % . 
  . % . % . 
   % . % . 
    . % . 
     % . 
      . 

Deze functie is dezelfde als print_diamond, met daarbij een if die met de modulo-operator en de rij (i) en de kolom (j) bepaalt welk van de twee symbolen afgedrukt moet worden.

Opdracht 6

Schrijf een functie print_crazy_striped_diamond(width, sym1, sym2, sym1_width, sym2_width) die een gestreepte ruit van sym1 en sym2 afdrukt, waarbij de strepen verschillende breedtes kunnen hebben.

def print_crazy_striped_diamond(width, sym1, sym2, sym1_width, sym2_width):
    """Drukt een gestreepte ruit af waarin de strepen van sym1 en sym2 een eigen breedte hebben."""
    for i in range(1, width + 1):
        print(" " * (width - i), end="")
        sym1_count = 0
        sym2_count = 0
        for j in range(0, i):
            if sym1_count < sym1_width:
                print(sym1, end=" ")
                sym1_count += 1
                if sym1_count >= sym1_width:
                    sym2_count = 0
            else:
                print(sym2, end=" ")
                sym2_count += 1
                if sym2_count >= sym2_width:
                    sym1_count = 0
        print()
    for i in range(1, width):
        print(" " * i, end="")
        sym1_count = i % (sym1_width + sym2_width)
        sym2_count = 0
        if sym1_count >= sym1_width:
            sym2_count = sym1_count - sym1_width
        for j in range(0, width - i):
            if sym1_count < sym1_width:
                print(sym1, end=" ")
                sym1_count += 1
                if sym1_count >= sym1_width:
                    sym2_count = 0
            else:
                print(sym2, end=" ")
                sym2_count += 1
                if sym2_count >= sym2_width:
                    sym1_count = 0
        print()


print_crazy_striped_diamond(7, ".", "%", 2, 1)
      . 
     . . 
    . . % 
   . . % . 
  . . % . . 
 . . % . . % 
. . % . . % . 
 . % . . % . 
  % . . % . 
   . . % . 
    . % . 
     % . 
      . 

Let goed op waar je de tellers aanmaakt. Zet je ze binnen de buitenste lus, dan begint elke regel opnieuw bij de eerste streep; zet je ze erbuiten, dan lopen de strepen over de regels door.