<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>python &#8211; Blog of Kliment Andreev &#8211; A place so I won&#039;t forget things</title>
	<atom:link href="https://blog.andreev.it/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.andreev.it</link>
	<description></description>
	<lastBuildDate>Sat, 24 Oct 2020 13:29:02 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>AWS, python: Find unused security groups and volumes using boto</title>
		<link>https://blog.andreev.it/2017/01/105-aws-find-unused-security-groups-volumes/</link>
					<comments>https://blog.andreev.it/2017/01/105-aws-find-unused-security-groups-volumes/#respond</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Sun, 15 Jan 2017 01:04:59 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[boto]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[unused security groups]]></category>
		<category><![CDATA[unused volumes]]></category>
		<guid isPermaLink="false">http://blog.iandreev.com/?p=3009</guid>

					<description><![CDATA[I made two scripts using Python and boto that will list all unused security&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>I made two scripts using Python and <a href="https://github.com/boto/boto" target="_blank" rel="noopener noreferrer">boto</a> that will list all unused security groups and volumes for your account. Make sure you have aws cli already installed and configured (see my other <a href="https://blog.andreev.it/?p=1905" target="_blank" rel="noopener noreferrer">post</a>). In addition, you&#8217;ll need python 2.x and boto (pip install boto). It won&#8217;t work with python 3.x and boto3. Also, you&#8217;ll need SES configured for sending e-mails. If you just want to print unused security groups and volumes, you don&#8217;t need SES. Just uncomment the print statement in lines #35 and #33. </p>
<p>Script for unused security groups.</p>
<pre class="brush: python; title: ; notranslate">
##################################################################
# Lists all unused security groups and sends an e-mail through SES
# K.Andreev - 2017 - FreeBSD license
##################################################################

# Import boto modules for ec2 and ses
import boto.ec2
import boto.ses

# Define variables here
sender = 'someone@domain.com'
# Max 50 recipients, use DLs instead of personal emails
recipients = &#x5B;'rec1@d1.com', 'rec2@d2.com']
subject = 'Unused EC2 security groups'
body = 'This is an automated e-mail. For any errors please contact klimenta@futurebit.com\n\n'
ses_region = 'us-east-1'
SES_KEY_ID = 'YOUR_KEY_ID'
SES_SECRET = 'YOUR_SECRET'

# Connect to AWS/EC2
ec2 = boto.connect_ec2()

# Get all security groups
sgs = ec2.get_all_security_groups()

# Loop through all security groups
# Empty string that contains all unused security groups
sglist = ''
for sg in sgs:
    # Get the instance count where the security group is attached
    sglen = len(sg.instances())
    # If the security group is not attached (0) it means it's not attached to an instance
    if sglen == 0 and sg.name != 'default':
        # Use the print statement below for debugging purposes only
        # print sg.name, len(sg.instances())
        # Concatenate security groups to the string
        sglist = sglist + sg.name + '\n'

# Establish a connection with SES
conn = boto.ses.connect_to_region(
        ses_region,
        aws_access_key_id = SES_KEY_ID,
        aws_secret_access_key = SES_SECRET)

# Send an email
conn.send_email(
        sender,
        subject,
        body + sglist,
        recipients)
</pre>
<p>Script for unused volumes. </p>
<pre class="brush: python; title: ; notranslate">
##########################################################
# Lists all unused volumes and sends an e-mail through SES
# K.Andreev - 2017 - FreeBSD license
##########################################################

# Import boto modules for ec2 and ses
import boto.ec2
import boto.ses

# Define variables here
sender = 'sender@whatever.com'
# Max 50 recipients, use DLs instead of personal emails
recipients = &#x5B;'rec1@d1.com', 'rec2@d2.com']
subject = 'Unused EC2 volumes'
body = 'This is an automated e-mail. For any errors please contact klimenta@futurebit.com\n\n'
ses_region = 'us-east-1'
SES_KEY_ID = 'YOUR_KEY_ID'
SES_SECRET = 'YOUR_SECRET'

# Connect to AWS/EC2
ec2 = boto.connect_ec2()

# Get all volumes
vols = ec2.get_all_volumes()

# Loop through all volumes
# Empty string that contains all unused volumes
svols = ''
for vol in vols:
    # If the volume status is available it means it's not attached to an instance
    if vol.status == 'available':
        # Use the print statement below for debugging purposes only
        # print vol.id + &quot; is unused&quot;
        # Concatenate the volume ids to the string
        svols = svols + vol.id + '\n'

# Establish a connection with SES
conn = boto.ses.connect_to_region(
        ses_region,
        aws_access_key_id = SES_KEY_ID,
        aws_secret_access_key = SES_SECRET)

# Send an email
conn.send_email(
        sender,
        subject,
        body + svols,
        recipients)
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2017/01/105-aws-find-unused-security-groups-volumes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>python: Tetris clone in python and pygame</title>
		<link>https://blog.andreev.it/2015/11/python-pygame-tetris-variant/</link>
					<comments>https://blog.andreev.it/2015/11/python-pygame-tetris-variant/#respond</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Sun, 08 Nov 2015 15:34:28 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Tetris]]></category>
		<guid isPermaLink="false">http://blog.iandreev.com/?p=2042</guid>

					<description><![CDATA[I was playing with python and pygame and decided to make a variant of&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>I was playing with python and pygame and decided to make a variant of the Tetris game (called KAtrix). This one is a little easier because the shapes do not fall automatically from the top. You have to move them with the left, right and down cursor keys and confirm the position with the space key.<br />
Here is the screenshot and the source.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2015/11/P057-01.png"><img fetchpriority="high" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2015/11/P057-01.png" alt="" width="647" height="508" class="aligncenter size-full wp-image-7389" srcset="https://blog.andreev.it/wp-content/uploads/2015/11/P057-01.png 647w, https://blog.andreev.it/wp-content/uploads/2015/11/P057-01-300x236.png 300w, https://blog.andreev.it/wp-content/uploads/2015/11/P057-01-585x459.png 585w" sizes="(max-width: 647px) 100vw, 647px" /></a></p>
<pre class="brush: plain; title: ; notranslate">
git clone https://github.com/klimenta/KAtrix
</pre>
<p>Not well documented, but it gives an idea what&#8217;s going on.</p>
<pre class="brush: python; collapse: true; light: false; title: ; toolbar: true; notranslate">
__author__ = 'Kliment Andreev'
__version__ = '20151108 15:48'

# Imports
import random
import time
import pygame
import sys
from pygame.locals import *

# Constants and dictionaries
# Frames per second
FPS = 25
# The top left column where the falling shape is positioned initially
START_COL = 4
# Represent a box or empty space for a shape
EMPTY_BOX = '-'
FULL_BOX = 'X'
# Window dimensions
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 480
# Matrix dimensions, including 4 borders (left, right, top, bottom)
MATRIX_WIDTH = 12
MATRIX_HEIGHT = 22
# Fill the matrix with zeros
MATRIX = &#x5B;&#x5B;0 for x in range(MATRIX_WIDTH)] for x in range(MATRIX_HEIGHT)]
#Box width in pixels. Each shape is composed of boxes.
BOX_SIZE = 20
# Define 16 web colors
BLACK = (0x00, 0x00, 0x00)
YELLOW = (0xff, 0xff, 0x00)
WHITE = (0xff, 0xff, 0xff)
SILVER = (0xc0, 0xc0, 0xc0)
GRAY = (0x80, 0x80, 0x80)
RED = (0xff, 0x00, 0x00)
MAROON = (0x80, 0x00, 0x00)
OLIVE = (0x80, 0x80, 0x00)
LIME = (0x00, 0xff, 0x00)
GREEN = (0x00, 0x80, 0x00)
AQUA = (0x00, 0xff, 0xff)
TEAL = (0x00, 0x80, 0x80)
BLUE = (0x00, 0x00, 0xff)
NAVY = (0x00, 0x00, 0x80)
FUCHSIA = (0xff, 0x00, 0xff)
PURPLE = (0x80, 0x00, 0x80)
# Top left coordinates of the matrix
TOP_X = 199
TOP_Y = 19
# Top left coordinates of the the box at (0,0)
# This is the top left coordinate of the top-left shape can be
TOP_BOX_X = TOP_X + BOX_SIZE
TOP_BOX_Y = TOP_Y + BOX_SIZE
# These are the shapes
# Each line represent an original position
# and three possible rotations
SHAPE_I = ((&quot;----&quot;), (&quot;XXXX&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;-X--&quot;), (&quot;-X--&quot;), (&quot;-X--&quot;), (&quot;-X--&quot;)), \
          ((&quot;----&quot;), (&quot;XXXX&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;-X--&quot;), (&quot;-X--&quot;), (&quot;-X--&quot;), (&quot;-X--&quot;))
SHAPE_J = ((&quot;--X-&quot;), (&quot;--X-&quot;), (&quot;-XX-&quot;), (&quot;----&quot;)), \
          ((&quot;-X--&quot;), (&quot;-XXX&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;-XX-&quot;), (&quot;-X--&quot;), (&quot;-X--&quot;), (&quot;----&quot;)), \
          ((&quot;-XXX&quot;), (&quot;---X&quot;), (&quot;----&quot;), (&quot;----&quot;))
SHAPE_L = ((&quot;-X--&quot;), (&quot;-X--&quot;), (&quot;-XX-&quot;), (&quot;----&quot;)), \
          ((&quot;XXX-&quot;), (&quot;X---&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;-XX-&quot;), (&quot;--X-&quot;), (&quot;--X-&quot;), (&quot;----&quot;)), \
          ((&quot;--X-&quot;), (&quot;XXX-&quot;), (&quot;----&quot;), (&quot;----&quot;))
SHAPE_O = ((&quot;-XX-&quot;), (&quot;-XX-&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;-XX-&quot;), (&quot;-XX-&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;-XX-&quot;), (&quot;-XX-&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;-XX-&quot;), (&quot;-XX-&quot;), (&quot;----&quot;), (&quot;----&quot;))
SHAPE_S = ((&quot;----&quot;), (&quot;-XX-&quot;), (&quot;XX--&quot;), (&quot;----&quot;)), \
          ((&quot;-X--&quot;), (&quot;-XX-&quot;), (&quot;--X-&quot;), (&quot;----&quot;)), \
          ((&quot;----&quot;), (&quot;-XX-&quot;), (&quot;XX--&quot;), (&quot;----&quot;)), \
          ((&quot;-X--&quot;), (&quot;-XX-&quot;), (&quot;--X-&quot;), (&quot;----&quot;))
SHAPE_T = ((&quot;XXX-&quot;), (&quot;-X--&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;--X-&quot;), (&quot;-XX-&quot;), (&quot;--X-&quot;), (&quot;----&quot;)), \
          ((&quot;-X--&quot;), (&quot;XXX-&quot;), (&quot;----&quot;), (&quot;----&quot;)), \
          ((&quot;X---&quot;), (&quot;XX--&quot;), (&quot;X---&quot;), (&quot;----&quot;))
SHAPE_Z = ((&quot;----&quot;), (&quot;-XX-&quot;), (&quot;--XX&quot;), (&quot;----&quot;)), \
          ((&quot;--X-&quot;), (&quot;-XX-&quot;), (&quot;-X--&quot;), (&quot;----&quot;)), \
          ((&quot;----&quot;), (&quot;-XX-&quot;), (&quot;--XX&quot;), (&quot;----&quot;)), \
          ((&quot;--X-&quot;), (&quot;-XX-&quot;), (&quot;-X--&quot;), (&quot;----&quot;))
# List of shapes
SHAPES = (SHAPE_I, SHAPE_J, SHAPE_L, SHAPE_O, SHAPE_S, SHAPE_T, SHAPE_Z)
# Shape Colors - Dictionary
SHAPE_COLOR = {SHAPE_I: BLUE,
               SHAPE_J: PURPLE,
               SHAPE_L: RED,
               SHAPE_O: GREEN,
               SHAPE_S: WHITE,
               SHAPE_T: FUCHSIA,
               SHAPE_Z: AQUA}
# Colors, web colors - dictionary
COLOR_COLOR = {BLACK: 0,
               YELLOW: 1,
               BLUE: 2,
               PURPLE: 3,
               RED: 4,
               GREEN: 5,
               WHITE: 6,
               FUCHSIA: 7,
               AQUA: 8}
# This is a reverse dictionary finder
find_color = dict(&#x5B;&#x5B;value, key] for key, value in COLOR_COLOR.items()])
# All possible combinations of rotations
ROTATE_0_DEGREES = 0
ROTATE_90_DEGREES = 1
ROTATE_180_DEGREES = 2
ROTATE_270_DEGREES = 3
# This is the size of one shape, 4 x 4
SHAPE_SIZE = 4


class Shape(object):
    &quot;&quot;&quot;A class for shapes&quot;&quot;&quot;
    def __init__(self, name, rotation, pos_y, pos_x):
        self.name = name            # Name of the shape, e.g. SHAPE_T
        self.rotation = rotation    # Rotation index of the shape
        self.pos_x = pos_x          # X position of the shape, it can be from 1 to 10
        self.pos_y = pos_y          # Y position of the shape, it can be from 1 to 20

    def drawShapeOnScreen(self):
        &quot;&quot;&quot;
        This method draws all boxes that form a shape on the screen
        and outline each box with a black edge line
        &quot;&quot;&quot;
        piece = self.name&#x5B;self.rotation]
        for x in range(SHAPE_SIZE):
            for y in range(SHAPE_SIZE):
                if piece&#x5B;y]&#x5B;x] != EMPTY_BOX:
                    # This line draws all the squares on the screen
                    pygame.draw.rect(DISPLAY_SURFACE, SHAPE_COLOR&#x5B;self.name],
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y,
                                      BOX_SIZE,
                                      BOX_SIZE))
                    # The following lines outline each square with 1 pixel black line
                    # Top vertical
                    pygame.draw.line(DISPLAY_SURFACE, BLACK,
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y),
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x + BOX_SIZE,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y), 1)
                    # Right horizontal
                    pygame.draw.line(DISPLAY_SURFACE, BLACK,
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x + BOX_SIZE,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y),
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x + BOX_SIZE,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y + BOX_SIZE),
                                     1)
                    # Left horizontal
                    pygame.draw.line(DISPLAY_SURFACE, BLACK,
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y),
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y + BOX_SIZE),
                                     1)
                    # Bottom vertical
                    pygame.draw.line(DISPLAY_SURFACE, BLACK,
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y + BOX_SIZE),
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x + BOX_SIZE,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y + BOX_SIZE),
                                     1)

    def deleteShapeFromScreen(self):
        &quot;&quot;&quot;
        This method deletes the shape from the screen
        &quot;&quot;&quot;
        piece = self.name&#x5B;self.rotation]
        for x in range(SHAPE_SIZE):
            for y in range(SHAPE_SIZE):
                if piece&#x5B;y]&#x5B;x] != EMPTY_BOX:
                    # This line erases all the squares
                    pygame.draw.rect(DISPLAY_SURFACE, BLACK,
                                     (x * BOX_SIZE + TOP_X + BOX_SIZE * self.pos_x,
                                      y * BOX_SIZE + TOP_Y + BOX_SIZE * self.pos_y,
                                      BOX_SIZE, BOX_SIZE))


    def deleteShapeFromMatrix(self):
        &quot;&quot;&quot;
        This method deletes the shape from the matrix
        &quot;&quot;&quot;
        piece = self.name&#x5B;self.rotation]
        for x in range(SHAPE_SIZE):
            for y in range(SHAPE_SIZE):
                if x + self.pos_x &lt; (MATRIX_WIDTH - 1) \
                        and y + self.pos_y &lt; (MATRIX_HEIGHT -1) \
                        and piece&#x5B;y]&#x5B;x] == FULL_BOX:
                    MATRIX&#x5B;y + self.pos_y]&#x5B;x + self.pos_x] = COLOR_COLOR&#x5B;BLACK]
        resetMatrix()

    def returnMaxWidth(self):
        &quot;&quot;&quot;
        Each shape is 4 x 4, but the actual width is different
        for each shape, e.g. horizontal &quot;I&quot; shape is 4 boxes in width
        but the same vertical shape is 2 boxes in width
        This method returns the width from the left. See the shape definition above
        &quot;&quot;&quot;
        max_x = 0
        piece = self.name&#x5B;self.rotation]
        for x in range(SHAPE_SIZE):
            for y in range(SHAPE_SIZE):
                if piece&#x5B;x]&#x5B;y] == FULL_BOX and y &gt; max_x :
                    max_x = y
        return max_x

    def returnMinWidth(self):
        &quot;&quot;&quot;
        Each shape is 4 x 4, but the actual width is different
        for each shape, e.g. horizontal &quot;I&quot; shape is 4 boxes in width
        but the same vertical shape is 2 boxes in width
        This method returns the width from right. See the shape definition above
        &quot;&quot;&quot;
        min_x = SHAPE_SIZE
        piece = self.name&#x5B;self.rotation]
        for x in range(SHAPE_SIZE):
            for y in range(SHAPE_SIZE):
                if piece&#x5B;x]&#x5B;y] == FULL_BOX and y &lt; min_x :
                    min_x = y
        return min_x

    def returnMaxHeight(self):
        &quot;&quot;&quot;
        Each shape is 4 x 4, but the actual height is different
        for each shape, e.g. horizontal &quot;I&quot; shape is 2 boxes in width
        but the same vertical shape is 4 boxes in height
        This method returns the height. See the shape definition above
        &quot;&quot;&quot;
        max_y = 0
        piece = self.name&#x5B;self.rotation]
        for x in range(SHAPE_SIZE):
            for y in range(SHAPE_SIZE):
                if piece&#x5B;x]&#x5B;y] == FULL_BOX and x &gt; max_y :
                    max_y = x
        return max_y

    def returnMaxHeightPerColumn(self, column):
        &quot;&quot;&quot;
        Each shape is 4 x 4, but the actual height is different per column
        for each shape, e.g. horizontal &quot;T&quot; shape can be 1 boxes or 3 boxes in height
        This method return the max height and that's the box that's the lowest in a shape
        &quot;&quot;&quot;
        max_y = 0
        piece = self.name&#x5B;self.rotation]
        for y in range(SHAPE_SIZE):
            if piece&#x5B;y]&#x5B;column] == FULL_BOX and y &gt; max_y:
                max_y = y
        return max_y

    def moveLeft(self):
        &quot;&quot;&quot;
        Move the shape left if possible
        &quot;&quot;&quot;
        if isAvailableLeft(self):
            self.deleteShapeFromMatrix()
            self.deleteShapeFromScreen()
            self.pos_x -= 1
            updateShapeInMatrix(self)
            self.drawShapeOnScreen()

    def moveRight(self):
        &quot;&quot;&quot;
        Move the shape right if possible
        &quot;&quot;&quot;
        if isAvailableRight(self):
            self.deleteShapeFromMatrix()
            self.deleteShapeFromScreen()
            self.pos_x += 1
            updateShapeInMatrix(self)
            self.drawShapeOnScreen()

    def moveDown(self):
        &quot;&quot;&quot;
        Move the shape down if possible
        &quot;&quot;&quot;
        if isAvailableDown(self):
            self.deleteShapeFromMatrix()
            self.deleteShapeFromScreen()
            self.pos_y += 1
            updateShapeInMatrix(self)
            self.drawShapeOnScreen()

    def moveRotate(self):
        &quot;&quot;&quot;
        Rotate the shape if possible
        &quot;&quot;&quot;
        if isAvailableRotate(self):
            self.deleteShapeFromMatrix()
            self.deleteShapeFromScreen()
            self.rotation += 1
            if self.rotation == 4:
                self.rotation = 0
            updateShapeInMatrix(self)
            self.drawShapeOnScreen()

def resetMatrix():
    &quot;&quot;&quot;
    Updates the edges of the matrix in memory, that's the YELLOW borders
    &quot;&quot;&quot;
    for x in range(0, MATRIX_HEIGHT):
        MATRIX&#x5B;x]&#x5B;0] = COLOR_COLOR&#x5B;YELLOW]
        MATRIX&#x5B;x]&#x5B;MATRIX_WIDTH - 1] = COLOR_COLOR&#x5B;YELLOW]
    for y in range(0, MATRIX_WIDTH):
        MATRIX&#x5B;0]&#x5B;y] = COLOR_COLOR&#x5B;YELLOW]
        MATRIX&#x5B;MATRIX_HEIGHT - 1]&#x5B;y] = COLOR_COLOR&#x5B;YELLOW]

def isAvailable(Shape):
    &quot;&quot;&quot;
    Is the shape available to be moved in the matrix
    Checks the new position initially when dropping it for the first time
    &quot;&quot;&quot;
    allowed = True
    piece = Shape.name&#x5B;Shape.rotation]
    for x in range(SHAPE_SIZE):
        for y in range(SHAPE_SIZE):
            if piece&#x5B;y]&#x5B;x] == FULL_BOX and \
                            MATRIX&#x5B;y + Shape.pos_y]&#x5B;x + Shape.pos_x] &gt;= COLOR_COLOR&#x5B;YELLOW]:
                allowed = False
                break
    return allowed

def isAvailableLeft(Shape):
    &quot;&quot;&quot;
    Is the shape available to be moved left in the matrix
    &quot;&quot;&quot;
    allowed = True
    piece = Shape.name&#x5B;Shape.rotation]
    for y in range(SHAPE_SIZE):
        if piece&#x5B;y]&#x5B;Shape.returnMinWidth()] == FULL_BOX \
                and MATRIX&#x5B;y + Shape.pos_y]&#x5B;Shape.pos_x +Shape.returnMinWidth() - 1] &gt;= COLOR_COLOR&#x5B;YELLOW] :
            allowed = False
            break
    return allowed

def isAvailableRight(Shape):
    &quot;&quot;&quot;
    Is the shape available to be moved right in the matrix
    &quot;&quot;&quot;
    allowed = True
    piece = Shape.name&#x5B;Shape.rotation]
    for y in range(SHAPE_SIZE):
        if piece&#x5B;y]&#x5B;Shape.returnMaxWidth()] == FULL_BOX \
                and MATRIX&#x5B;y + Shape.pos_y]&#x5B;Shape.pos_x + Shape.returnMaxWidth() + 1] &gt;= COLOR_COLOR&#x5B;YELLOW]:
            allowed = False
            break
    return allowed

def isAvailableRotate(Shape):
    &quot;&quot;&quot;
    Is the shape available to be moved rotated in the matrix
    &quot;&quot;&quot;
    allowed = True
    oldMaxWidth= Shape.returnMaxWidth()
    oldMinWidth = Shape. returnMinWidth()
    oldMaxHeight = Shape.returnMaxHeight()
    oldRotation = Shape.rotation
    Shape.rotation += 1
    if Shape.rotation == 4:
        Shape.rotation = 0
    newMaxWidth = Shape.returnMaxWidth()
    newMinWidth = Shape.returnMinWidth()
    newMaxHeight = Shape.returnMaxHeight()
    if (newMinWidth - oldMinWidth) + Shape.pos_x &lt; 0 \
            or (newMaxWidth - oldMaxWidth) + Shape.pos_x &gt;= (MATRIX_WIDTH - 2):
        allowed = False
    if (newMaxHeight - oldMaxHeight) + Shape.pos_y &gt;= (MATRIX_HEIGHT -2):
        allowed = False
    Shape.rotation = oldRotation
    return allowed

def isAvailableDown(Shape):
    &quot;&quot;&quot;
    Is the shape available to be moved down in the matrix
    &quot;&quot;&quot;
    allowed = True
    piece = Shape.name&#x5B;Shape.rotation]
    for x in range(SHAPE_SIZE):
        if piece&#x5B;Shape.returnMaxHeightPerColumn(x)]&#x5B;x] == FULL_BOX and \
                        MATRIX&#x5B;Shape.pos_y + Shape.returnMaxHeightPerColumn(x) + 1]&#x5B;x + Shape.pos_x] &gt;= COLOR_COLOR&#x5B;YELLOW] :
            allowed = False
            break
    return allowed

def updateShapeInMatrix(Shape):
    &quot;&quot;&quot;
    Updates the matrix with the moved shape
    &quot;&quot;&quot;
    piece = Shape.name&#x5B;Shape.rotation]
    for x in range(SHAPE_SIZE):
        for y in range(SHAPE_SIZE):
            if piece&#x5B;y]&#x5B;x] == &quot;X&quot; and (y + Shape.pos_y) in range (1, MATRIX_HEIGHT - 1) \
                    and (x + Shape.pos_x) in range(1, MATRIX_WIDTH - 1) \
                    and MATRIX&#x5B;y + Shape.pos_y]&#x5B;x + Shape.pos_x] == COLOR_COLOR&#x5B;BLACK]:
                MATRIX&#x5B;y + Shape.pos_y]&#x5B;x + Shape.pos_x] = COLOR_COLOR&#x5B;SHAPE_COLOR&#x5B;Shape.name]]
    resetMatrix()

def drawMatrixOnScreen():
    &quot;&quot;&quot;
    Draws four bars where the game occurs
    &quot;&quot;&quot;
    # Left bar
    pygame.draw.rect(DISPLAY_SURFACE, YELLOW, (TOP_X,
                                               TOP_Y,
                                               BOX_SIZE,
                                               MATRIX_HEIGHT * BOX_SIZE + 1))
    # Right bar
    pygame.draw.rect(DISPLAY_SURFACE, YELLOW, (TOP_X + (MATRIX_WIDTH - 1) * BOX_SIZE + 1,
                                               TOP_Y,
                                               BOX_SIZE,
                                               MATRIX_HEIGHT * BOX_SIZE + 1))
    # Bottom bar
    pygame.draw.rect(DISPLAY_SURFACE, YELLOW, (TOP_X + BOX_SIZE,
                                               TOP_Y + (MATRIX_HEIGHT - 1) * BOX_SIZE + 1,
                                               (MATRIX_WIDTH - 2) * BOX_SIZE + 1,
                                               BOX_SIZE))
    # Top bar
    pygame.draw.rect(DISPLAY_SURFACE, YELLOW, (TOP_X + BOX_SIZE,
                                               TOP_Y,
                                               (MATRIX_WIDTH - 2) * BOX_SIZE + 1,
                                               BOX_SIZE))

def checkFullLine():
    &quot;&quot;&quot;
    Check if there is a full horizontal line in the matrix.
    &quot;&quot;&quot;
    for x in range(MATRIX_HEIGHT - 2, 0, - 1):
        if 0 not in MATRIX&#x5B;x]:
            return x

def printText(msg, FONT, x_cor, y_cor, b_color, f_color):
    &quot;&quot;&quot;
    Writes Text on the screen
    &quot;&quot;&quot;
    text = FONT.render(msg, True, b_color, f_color)
    textRect = text.get_rect()
    textRect.centerx = x_cor
    textRect.centery = y_cor
    DISPLAY_SURFACE.blit(text, textRect)

def drawRectangle(x_cor, y_cor, width, height, color):
    &quot;&quot;&quot;
    Draws rectangle on the screen
    &quot;&quot;&quot;
    pygame.draw.rect(DISPLAY_SURFACE, color, (x_cor, y_cor, width, height))

def printScore(score):
    &quot;&quot;&quot;
    Prints score on the screen
    &quot;&quot;&quot;
    printText('SCORE:', FONT_SMALL, 490, 240, WHITE, BLACK)
    printText(str(score), FONT_SMALL, 580, 240, WHITE, BLACK)

def shiftShapesOnScreen(row):
    &quot;&quot;&quot;
    Shift shapes down on the screen when one line is full and collapses
    &quot;&quot;&quot;
    for col in range(1, MATRIX_WIDTH -1):
        pygame.draw.rect(DISPLAY_SURFACE,
                         find_color&#x5B;MATRIX&#x5B;row]&#x5B;col]],
                         (TOP_X + BOX_SIZE * col,
                          TOP_Y + BOX_SIZE * row,
                          BOX_SIZE,
                          BOX_SIZE))

        # This line outlines each square with 1 pixel black line
        # Top vertical
        pygame.draw.line(DISPLAY_SURFACE, BLACK,
            (TOP_X + BOX_SIZE * col,
            TOP_Y + BOX_SIZE * row),
            (TOP_X + BOX_SIZE * col + BOX_SIZE,
            TOP_Y + BOX_SIZE * row), 1)
        # Right horizontal
        pygame.draw.line(DISPLAY_SURFACE, BLACK,
            (TOP_X + BOX_SIZE * col + BOX_SIZE,
            TOP_Y + BOX_SIZE * row),
            (TOP_X + BOX_SIZE * col + BOX_SIZE,
            TOP_Y + BOX_SIZE * row + BOX_SIZE),
            1)
        # Left horizontal
        pygame.draw.line(DISPLAY_SURFACE, BLACK,
            (TOP_X + BOX_SIZE * col,
            TOP_Y + BOX_SIZE * row),
            (TOP_X + BOX_SIZE * col,
            TOP_Y + BOX_SIZE * row + BOX_SIZE),
            1)
        # Bottom vertical
        pygame.draw.line(DISPLAY_SURFACE, BLACK,
            (TOP_X + BOX_SIZE * col,
            TOP_Y + BOX_SIZE * row + BOX_SIZE),
            (TOP_X + BOX_SIZE * col + BOX_SIZE,
            TOP_Y + BOX_SIZE * row + BOX_SIZE),
            1)

def shiftShapesInMatrix(row):
    &quot;&quot;&quot;
    Shift shapes down in the matrix when one line is full and collapses
    &quot;&quot;&quot;
    while row &gt; 1:
        for xx in range(1, MATRIX_WIDTH):
            MATRIX&#x5B;row]&#x5B;xx] = MATRIX&#x5B;row - 1]&#x5B;xx]
        shiftShapesOnScreen(row)
        row -= 1

def main():
    global FPS_CLOCK, DISPLAY_SURFACE, FONT_BIG, FONT_SMALL, FONT_SUPER_SMALL, SCORE
    pygame.init()
    FPS_CLOCK = pygame.time.Clock()
    DISPLAY_SURFACE = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    pygame.display.set_caption('KAtrix')
    FONT_BIG = pygame.font.SysFont(None, 44)
    FONT_SMALL = pygame.font.SysFont(None, 24)
    FONT_SUPER_SMALL = pygame.font.SysFont(None, 12)
    DISPLAY_SURFACE.fill(BLACK)
    resetMatrix()
    drawMatrixOnScreen()
    SCORE = 0
    printScore(SCORE)
    printText('Program by: Kliment ANDREEV, 2015', FONT_SUPER_SMALL, 320, 470, SILVER, BLACK)
    # MAIN GAME LOOP
    while True:
        new_shape = Shape(SHAPES&#x5B;random.randint(0, len(SHAPES) - 1)], ROTATE_0_DEGREES, 1, START_COL)
        NewPiece = True
        if isAvailable(new_shape):
            Shape.drawShapeOnScreen(new_shape)
            updateShapeInMatrix(new_shape)
        else:
            NewPiece=False
            Shape.drawShapeOnScreen(new_shape)
            drawRectangle(TOP_X, WINDOW_HEIGHT / 2 - 50, 241, 160, BLUE)
            printText(&quot;G A M E  O V E R&quot;, FONT_BIG, WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 + 30, YELLOW, BLUE)
            pygame.display.update()
            pygame.time.delay(3000)
            pygame.quit()
            sys.exit()
        while NewPiece:
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == KEYDOWN:
                    if (event.key == K_LEFT):
                        Shape.moveLeft(new_shape)
                    elif (event.key == K_RIGHT):
                        Shape.moveRight(new_shape)
                    elif (event.key == K_UP):
                        Shape.moveRotate(new_shape)
                    elif (event.key == K_DOWN):
                        Shape.moveDown(new_shape)
                    elif (event.key == K_SPACE):
                        while isAvailableDown(new_shape):
                            Shape.moveDown(new_shape)
                        NewPiece = False
                        while checkFullLine() &gt; 0:
                            SCORE += 10
                            printScore(SCORE)
                            shiftShapesInMatrix(checkFullLine())
            pygame.display.update()
            FPS_CLOCK.tick(FPS)

if __name__ == '__main__':
    main()
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2015/11/python-pygame-tetris-variant/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
