HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Pygame menu to launch games

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
pygamelaunchmenugames

Problem

I made a menu to display a list of games and their info so that they can be uniformly launched from an arcade cabinet like set up. I was asked to do it in Python so I learned python using this and this. I have a Java background but no prior Python experience.

I have a working product but I realize that my code doesn't quite look like other Python I've seen. Mainly there is no main and there is no use of self. I just used the structure of the pygame tutorial. I'm looking for feedback on code correctness, best practices and design pattern usage.

If you propose major changes, what are the tools to help make them in Python? I'm used to Eclipse's refactoring tools for Java. Right now, I'm switching between Notepad++ and Sublime for Python. Other than find and replace, I don't know how to error free rename variables. How do I extract a method?

This is how it looks like:

```
import pygame
import json
import collections
import os

pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
done = False

_image_library = {}

def create_image(path):
global _image_library
image = _image_library.get(path)
if image == None:
image = pygame.image.load(path)
_image_library[path] = image

def get_image(path):
global _image_library
image = _image_library.get(path)
if image == None:
image = pygame.image.load(path)
_image_library[path] = image
return image

def draw_image(image, x, y):
screen.blit(image, (x, y))

#font = pygame.font.SysFont("comicsansms", 72)
#text = font.render("Hello, World", True, (0, 128, 0))
size = 20
font = pygame.font.Font(None, size)
_text_library = {}

def creat_text(text, color):
global _text_library
color = (0, 128, 0)
_text_library[text] = font.render(text, True, color)

def get_text(text):
global _text_library
color = (0, 128, 0)
s = _text_library.get(text)
if s == None:
s = font.render(text, True, color

Solution

Global variables

Global variables are bad. Avoid them as much as possible.

One way to avoid them is by making them method parameters.
But I see that it would make create_image and get_image inconvenient if you had to add _image_library in every call.
A good solution can be to create an ImageLibrary class,
which can contain _image_library,
hitting two birds with one stone:
  1. no more global variable; 2. still convenient



Similarly, you could create a TextLibrary.

For more on classes, see the Python tutorial (version 3),
or version 2 if that's a requirement of pygame.

Code organization

As you noticed yourself,
you don't have a main method.
It's not a requirement,
but a common place to put the glue-code that configures the main objects and launches the main activity of the program.

It's not good to have any code in the global namespace,
except some global constants.
This way the module cannot be imported and thus reused by other modules.
So it's better to move the main glue code inside a main function,
and add this boilerplate to call it:

if __name__ == '__main__':
    main()


This condition will only be true when running the script in a shell,
it won't be true when importing as a module.

File I/O

Instead of this:

f = open('./games.json')
s = f.read()
f.close()


The recommended pattern is this:

with open('./games.json') as fh:
    content = fh.read()


Notice that you don't need to close the file handle,
it gets closed automatically when execution leaves the with block.

Also, s was a poor name, it's better to use meaningful names.

IDE and tools for Python

I recommend PyCharm, by the same company that makes IntelliJ.
It's awesome,
and would help your learning if you follow its warnings about your code.
It would certainly help with refactoring operations.

PEP8 is the official coding style guide for Python,
and there is a command line tools named pep8 (install with pip install pep8)
which can check your entire project for violations.

Another tool is pyflakes (install with pip install pyflakes),
which can detect some bad practices and potential bugs.

Code Snippets

if __name__ == '__main__':
    main()
f = open('./games.json')
s = f.read()
f.close()
with open('./games.json') as fh:
    content = fh.read()

Context

StackExchange Code Review Q#64000, answer score: 3

Revisions (0)

No revisions yet.