pythonzelle-graphics

Patchwork style and color arrangement


I have to do a patchwork and I need a particular colour and style arrangement. Right now I have this:

[Current image

My code:

from graphics import *
colour = ["","",""]

def main():
    size= getSize()
    colour = getColour()
    win = GraphWin("Patchwork", size*100, size*100)
    drawPatches(win, size)

def getSize():
    while True:
        size = ""
        while not(size.isdecimal()):
            size = input("Please enter a valid size between 2 - 9 for your patchwork:")
            if not(size.isdecimal()):
                print("Only digits are allowed.")
        size = eval(size)
        if size < 2 or size > 9:
            print("The valid numbers are 2 - 9.")
        else:
            return size

def getColour():
    for i in range(3):
        chosenColour = validateColour(i + 1)
        colour[i] = chosenColour
    return colour

def validateColour(colourNumber):
        while True:
            colour1 = input("Please pick 3 colours {0}:".format(colourNumber))
            if (colour1 == "red" or colour1 == "blue" or colour1 == "green" or
            colour1 == "cyan" or colour1 == "magenta"):
                if repetitiveColour(colour1):
                    return colour1
                else:
                    print("Cannot enter the same colour more than once.")
            else:
                print("The possible colours are; red, blue, green, cyan and magenta.")

def repetitiveColour(colour1):
    return(colour1 != colour[0] and colour1 != colour[1] and colour1 != colour[2])

def selectingColour(row, size, column):
    return(column * size + row)%3

def drawLine(win, p1, p2, colour):
    line = Line(p1, p2)
    line.setOutline(colour)
    line.draw(win)

def drawRectangle(win, p1, p2, colour):
    square = Rectangle(p1, p2)
    square.setFill(colour)
    square.draw(win)

def drawPatchOne(win, position, colour):
    x = position.getX()
    y = position.getY()
    for i in range(5):
        drawLine(win, Point(x + 20*i, y),
        Point(x + 100, y + 100 - 20*i), colour)
        drawLine(win, Point(x, y + 20*i),
        Point(x + 100 - 20*i , y + 100), colour)
        drawLine(win, Point(x + 100 - 20*i, y),
        Point(x, y + 100 - 20*i), colour)
        drawLine(win, Point(x + 20*i, y + 100),
        Point(x + 100, y + 20*i), colour)

def drawPatchTwo(win, position, colour):
    x = position.getX()
    y = position.getY()
    drawRectangle(win, Point(x + 0, y + 0), Point(x + 100, y + 100), colour)
    for i in range(5):
        drawRectangle(win, Point(x + 5 + 20*i, y + 0),
         Point(x + 15 + 20*i, y + 90), "white")
    for i in range(5):
        for j in range(5):
            drawRectangle(win, Point(x + j*20, y + 10 + i*20),
             Point(x + (j+1)*20, y + (i+1)*20), "white")

def drawPatches(win, size):
    for row in range(size):
        for column in range(size):
            if (row % 2 != 0 and column % 2 == 0 or
            row % 2 != 0 and column % 2 == 0):
                drawPatchTwo(win, Point(row*100, column*100),
                colour[selectingColour(row, size, column)])
            else:
                drawPatchOne(win, Point(row*100, column*100),
                colour[selectingColour(row, size, column)])  

main()

But I need this overall arrangement of patch syles and colors:

Desired output

Where 'F' indicates the second patch style of my patchwork above, the square arrangement.

I kinda understand how to do the colours as I would use only blue and orange and use a new if statement for the red. The main thing I really struggle with is the style of my final patch (diagonal or square arrangement).


Solution

  • I'm going to go out on a limb and say that I think I understand what you're asking. (I feel the communication problem is shared by both you and those who edited your question, leaving out necessary detail.) I believe we can get the pattern you desire using simple tests on the row and column values in drawPatches() and simplifying color assignment. I reworked your code to address this issue as well as a number of code style issues:

    from graphics import *
    
    VALID_COLOURS = ['red', 'blue', 'green', 'cyan', 'orange']
    
    colours = ['', '', '']
    
    def main():
        size = getSize()
        selectColours()
        win = GraphWin("Patchwork", size*100, size*100)
        drawPatches(win, size)
    
        win.getMouse()
        win.close()
    
    def getSize():
        while True:
            size = ""
    
            while not size.isdecimal():
                size = input("Please enter a valid size between 2 - 9 for your patchwork: ")
    
                if not size.isdecimal():
                    print("Only digits are allowed.")
    
            size = int(size)
    
            if 2 <= size <= 9:
                break
    
            print("The valid numbers are 2 - 9.")
    
        return size
    
    def selectColours():
        for index in range(len(colours)):
            colours[index] = validateColour(index + 1)
    
    def validateColour(colourNumber):
        colour = None
    
        while True:
            colour = input("Please pick 3 colours {0}: ".format(colourNumber))
    
            if colour in VALID_COLOURS:
                if not repetitiveColour(colour):
                    break
    
                print("Cannot enter the same colour more than once.")
            else:
                print("The possible colours are:", ", ".join(VALID_COLOURS))
    
        return colour
    
    def repetitiveColour(colour):
        return colour in colours
    
    def drawLine(win, p1, p2, colour):
        line = Line(p1, p2)
        line.setOutline(colour)
        line.draw(win)
    
    def drawRectangle(win, p1, p2, colour):
        square = Rectangle(p1, p2)
        square.setFill(colour)
        square.draw(win)
    
    def drawPatchOne(win, position, colour):
        x = position.getX()
        y = position.getY()
    
        for i in range(5):
            drawLine(win, Point(x + i*20, y), Point(x + 100, y + 100 - i*20), colour)
            drawLine(win, Point(x, y + i*20), Point(x + 100 - i*20, y + 100), colour)
            drawLine(win, Point(x + 100 - i*20, y), Point(x, y + 100 - i*20), colour)
            drawLine(win, Point(x + i*20, y + 100), Point(x + 100, y + i*20), colour)
    
    def drawPatchTwo(win, position, colour):
        x = position.getX()
        y = position.getY()
    
        drawRectangle(win, Point(x + 0, y + 0), Point(x + 100, y + 100), colour)
    
        for i in range(5):
            drawRectangle(win, Point(x + 5 + i*20, y + 0), Point(x + 15 + i*20, y + 90), 'white')
    
        for i in range(5):
            for j in range(5):
                drawRectangle(win, Point(x + j*20, y + 10 + i*20), Point(x + (j+1) * 20, y + (i+1) * 20), 'white')
    
    def drawPatches(win, size):
        for row in range(size):
            for column in range(size):
                if 0 < row < size - 1 and 0 < column < size - 1:
                    colour = colours[2]
                elif row % 2 != column % 2:
                    colour = colours[1]
                else:
                    colour = colours[0]
    
                if row == column:
                    drawPatchTwo(win, Point(row*100, column*100), colour)
                else:
                    drawPatchOne(win, Point(row*100, column*100), colour)
    
    main()
    

    USAGE

    > python3 test.py
    Please enter a valid size between 2 - 9 for your patchwork: 5
    Please pick 3 colours 1: blue
    Please pick 3 colours 2: orange
    Please pick 3 colours 3: red
    >
    

    OUTPUT

    enter image description here

    If this is not what you want, rework your question to include an illustration of correct output.