• Advertisement
Sign in to follow this  

import issues in Python

This topic is 1902 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a program that has the majority of a games code in it called "root.py". Needless to say, the code was getting cluttered and very large so i am trying to seperate it up into different modules. My first attempt has been completely unsuccesful because there is always some type on import error.

the only other module i have is "letter.py" which has a class in it that uses parts from our main file root. in both of these, i have them importing one another (in root, i have the import letter line, and in letter i import root). They are in the same directory. the errors i keep getting involving variables within the two files.

For instance, this is the class in letter:
[source lang="python"]class Letter(pygame.sprite.Sprite):

def __init__(self, name, x, y):

pygame.sprite.Sprite.__init__(self)

self.name = name

self.x = x

self.y = y

self.image = font1.render(self.name, True, WHITE)

self.rect = self.image.get_rect()
self.rect.topleft = [x,y]

def update(self):

self.rect.x += self.change_y
self.rect.y += self.change_x

def draw(self, display):

self.display = display

display.blit(self.image, (self.x, self.y))[/source]

and with it i create these:
[source lang="python"]a = Letter('A', letters_x, letters_y)
b = Letter('B', letters_x, letters_y)
c = Letter('C', letters_x, letters_y)[/source]

When i try to use "a" in root, it says it is not defined. Plus, "letters_x" and "letters_y" are found in root, and they also don't work. This is very frustrating because i thought i knew how to import modules properly. Please help.

Share this post


Link to post
Share on other sites
Advertisement
Well, untill someone who really knows Python jumps in I will state the obvious, though I am beginner myself.

Its not clear where do you create instances of Letter class in root.py or letter py. Leave Class code in Letter.py and move code where you create instances in main or in your case root.py and with import Letter at the beginning of root.py that error should clear.
But for clearing any missunderstandig post both scripts here.

Share this post


Link to post
Share on other sites
Here is the root.py script, please excuse its sloppiness:[source lang="python"]import pygame
import sys
import textrect
import time
import letter
from letter import *
from ConfigParser import SafeConfigParser
from pygame.locals import *


pygame.init()

global DISPLAY, letters_x, letters_y, insertion, terminal, help_page_1, help_page_2, inst_prgrms_scrn, slaves_scrn


#DISPLAY
DISPLAY = pygame.display.set_mode((640, 480))
pygame.display.set_caption('Root')

#COLORS
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

#Font
font1 = pygame.font.Font('vgasys.fon', 10)

######get parser
parser = SafeConfigParser()


###############################classes########################################

######class to handle our insertion point
class I_point(pygame.sprite.Sprite):

def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)

self.image = pygame.Surface([5, 16])
self.image.fill((WHITE))

self.rect = self.image.get_rect()
self.rect.topleft = [x,y]

def update(self):
self.rect.x += self.change_y
self.rect.y += self.change_x

######insertion point x and y
i_x = 60
i_y = 16

######create the insertion point using the class we made
insertion = I_point( i_x,i_y )
insertion_point = pygame.sprite.RenderPlain((insertion))

######class to handle IP's

class IP_Address:

def __init__(self, address, difficulty):

self.address = address

self.difficulty = difficulty

def slaved(self):
slaves = open('slaves.txt', 'a')
slaves.write(self.address)
slaves.close()


######class to handle all the programs

class Program:

def __init__(self, name, level):

self.name = name

self.level = level

def installed(self):
programs = open('installed_programs.txt', 'a')
programs.write(self.name)
programs.close()





letters_x = insertion.rect.left
letters_y = insertion.rect.top

##########import letter down here to avoid not having certain
##########things necessary in letter



letters_list = pygame.sprite.RenderPlain()

######check input definition####################################
def check_input():

for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
global a
print "detection"
a.draw(DISPLAY)



if event.key != pygame.K_RETURN and event.key != pygame.K_BACKSPACE and event.key != pygame.K_ESCAPE and event.key != pygame.K_LSHIFT and event.key != pygame.K_RSHIFT and event.key != pygame.K_CAPSLOCK and event.key != pygame.K_RALT and event.key != pygame.K_LALT and event.key != pygame.K_HOME and event.key != pygame.K_F1 and event.key != pygame.K_F2 and event.key != pygame.K_F3 and event.key != pygame.K_LEFT and event.key != pygame.K_UP and event.key != pygame.K_DOWN and event.key != pygame.K_F5 and event.key != pygame.K_SLASH:
insertion.rect.left += insertion.rect.width

if event.key == pygame.K_RETURN:
admn_y += 16
insertion.rect.top += insertion.rect.height

if event.key == pygame.K_BACKSPACE and insertion.rect.x >= 65:
insertion.rect.right -= insertion.rect.width

if event.key == pygame.K_LEFT and insertion.rect.x >= 65:
insertion.rect.right -= insertion.rect.width

if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()

if event.key == pygame.K_F1:
terminal = False
inst_prgrms_scrn = True

if event.key == pygame.K_F5:
terminal = False
slaves_scrn = True

if event.key == pygame.K_SLASH:
terminal = False
help_page_1 = True


if event.type == QUIT:
pygame.quit()
sys.exit()






######admin text x and y
admn_x = 0
admn_y = 16

#words
admin = font1.render('::admin\>', True, WHITE)
admin_rect = admin.get_rect()

guest = font1.render('::guest\>', True, WHITE)
guest_rect = admin.get_rect()


######help
help_file_1 = open('help_1.txt').read()

help_1_rect = pygame.Rect((40, 40, 640, 480))

help_1 = textrect.render_textrect(help_file_1, font1, help_1_rect, WHITE, BLACK)



help_file_2 = open('help_2.txt').read()

help_2_rect = pygame.Rect((40, 40, 640, 480))

help_2 = textrect.render_textrect(help_file_2, font1, help_1_rect, WHITE, BLACK)


######header
header_file = open('header.txt').read()

header = font1.render(header_file, True, WHITE)
header_rect = header.get_rect()


######installed programs
programs_file = open('installed_programs.txt').read()

programs_rect = pygame.Rect((40, 40, 640, 480))

inst_programs = textrect.render_textrect(programs_file, font1, programs_rect, WHITE, BLACK)

inst_programs_header = font1.render('The Programs you currently have installed', True, WHITE)


######slaves
slaves_file = open('slaves.txt').read()

slaves_rect = pygame.Rect((40, 40, 640, 480))

slaves = textrect.render_textrect(slaves_file, font1, slaves_rect, WHITE, BLACK)

slaves_header = font1.render('The slaves you currently have control of:', True, WHITE)



######clock control
clock = pygame.time.Clock()


########################ig things the player interacts with######################

######ip's
ip_1 = IP_Address('255.0.0.1', 1)


slaves_making_bank = 0
######programs
passcrack_1 = Program('n00b_passCrack.bat', 1)




while True:

terminal = True
help_page_1 = False
help_page_2 = False
inst_prgrms_scrn = False
slaves_scrn = False


while terminal:

DISPLAY.fill(BLACK)
DISPLAY.blit(header, (0, 0))
DISPLAY.blit(admin, (admn_x, admn_y))
insertion_point.draw(DISPLAY)
check_input()



pygame.display.flip()



while help_page_1:

DISPLAY.fill(BLACK)
DISPLAY.blit(help_1, (0, 0))

pygame.display.flip()

for event in pygame.event.get():

if event.type == pygame.KEYDOWN:

if event.key == pygame.K_2:
help_page_1 = False
help_page_2 = True

if event.type == QUIT:
pygame.quit()
sys.exit()
while help_page_2:
DISPLAY.fill(BLACK)
DISPLAY.blit(help_2, (0, 0))

pygame.display.flip()

for event in pygame.event.get():

if event.type == pygame.KEYDOWN:

if event.key == pygame.K_HOME:
help_page_2 = False
terminal = True

if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()

if event.type == QUIT:
pygame.quit()
sys.exit()


while inst_prgrms_scrn:
DISPLAY.fill(BLACK)
DISPLAY.blit(inst_programs_header, (0, 0))
DISPLAY.blit(inst_programs, (0, 50))

pygame.display.flip()

for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_HOME:
inst_prgrms_scrn = False
terminal = True

if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()

if event.type == QUIT:
pygame.quit()
sys.exit()

while slaves_scrn:
DISPLAY.fill(BLACK)
DISPLAY.blit(slaves_header, (0, 0))
DISPLAY.blit(slaves, (0, 50))

pygame.display.flip()

for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_HOME:
slaves_scrn = False
terminal = True

if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()

if event.type == QUIT:
pygame.quit()
sys.exit()




clock.tick(30)


pygame.display.flip()

[/source]


Here is letter.py:

[source lang="python"]import pygame
from root import *

pygame.init()




class Letter(pygame.sprite.Sprite):

def __init__(self, name, x, y):

pygame.sprite.Sprite.__init__(self)

self.name = name

self.x = x

self.y = y

self.image = font1.render(self.name, True, WHITE)

self.rect = self.image.get_rect()
self.rect.topleft = [x,y]

def update(self):

self.rect.x += self.change_y
self.rect.y += self.change_x

def draw(self, display):

self.display = display

display.blit(self.image, (self.x, self.y))


global letters_x, letters_y, a


a = Letter('A', letters_x, letters_y)
b = Letter('B', letters_x, letters_y)
c = Letter('C', letters_x, letters_y)

[/source]

Share this post


Link to post
Share on other sites

Well, untill someone who really knows Python jumps in I will state the obvious, though I am beginner myself.

Its not clear where do you create instances of Letter class in root.py or letter py. Leave Class code in Letter.py and move code where you create instances in main or in your case root.py and with import Letter at the beginning of root.py that error should clear.
But for clearing any missunderstandig post both scripts here.


I brought my objects (a, b, c) over into root.py but i get the following error message:

Traceback (most recent call last):
File "E:\Root\root.py", line 5, in <module>
import letter
File "E:\Root\letter.py", line 2, in <module>
from root import *
File "E:\Root\root.py", line 97, in <module>
a = Letter('A', letters_x, letters_y)
NameError: name 'Letter' is not defined

Share this post


Link to post
Share on other sites
Ok, I tried. Created both files and run root.py but now i am missing textrect because i get error at the line import textrect
Since Letter.py is not so big file I would suggest you first try moving everything in one file till it works and then separate class letter in its own file after that. Well that was what I did in myPong and it worked. Edited by Zed McJack

Share this post


Link to post
Share on other sites

Ok, I tried. Created both files and run root.py but now i am missing textrect because i get error at the line import textrect
Since Letter.py is not so big file I would suggest you first try moving everything in one file till it works and then separate class letter in its own file after that. Well that was what I did in myPong and it worked.


the suggestion you gave earlier worked after i changed around some stuff. now im having problems with the most basic things in my program like switching while loops which doesnt work at all now.

Share this post


Link to post
Share on other sites

the suggestion you gave earlier worked after i changed around some stuff. now im having problems with the most basic things in my program like switching while loops which doesnt work at all now.

Post the part that is problematic with error lines

Share this post


Link to post
Share on other sites

[quote name='K1NNY' timestamp='1352399784' post='4998966']
the suggestion you gave earlier worked after i changed around some stuff. now im having problems with the most basic things in my program like switching while loops which doesnt work at all now.

Post the part that is problematic with error lines
[/quote]

i wish i could but it doesn't show an error. it gets the input, it just doesn't switch while loops. the code for detecting the input is in my check_input definition here:

[source lang="python"]######check input definition####################################
def check_input():

for event in pygame.event.get():

if event.type == pygame.KEYDOWN:

if event.key == pygame.K_a:
global a
print "detection"
a.draw(DISPLAY)


if event.key == pygame.K_F1:
terminal = False
inst_prgrms_scrn = True

if event.key == pygame.K_F5:
terminal = False
slaves_scrn = True

if event.key == pygame.K_SLASH:
terminal = False
help_page_1 = True

[/source]

none of these work including when i try to draw "a" to the screen, but it does detect some input because it will print "detection".

Share this post


Link to post
Share on other sites
I was reading your code a bit and even if I didnt find out why it does not display text I find that you have to better organize your code. You have parts of capturing input in check_input() function and part in several while loops.
Whenever you find code that repeats move it in the function or class, add parameters and make it reusable. It wil be cleaner and easier to look at and find problematic spots.
btw I still have uncorrected version of your code so I dont have a clue what you corrected to make root.py work again.
hth
Z

Share this post


Link to post
Share on other sites
I think that I found where is the problem...
In the begining of the root.py you define screen area with
[source='lang="python"']DISPLAY = pygame.display.set_mode((640, 480))[/source]
then in class Letter you have draw metod
[source='lang="python"']
def draw(self, display):
self.display = display
display.blit(self.image, (self.x, self.y))[/source]
where you recieve as parameter what to display
and in while loop you have
[source='lang="python"']
if event.key == pygame.K_a:
global a
print "detection"
a.draw(DISPLAY)[/source]
where you actually send your whole display to draw method of the letter class and with it you draw only your screan again overwriting whole screen.

Share this post


Link to post
Share on other sites
Your import problem is due to a circular dependency (root need letter and letter need root). This could be solved by putting all the shared variables into a third module that you could call common.py and import this common module in both root.py and letter.py.

The problem with your check_input function is that it does not use the global terminal variable but a local copy. Ensure you put the global keyword before using any global variable in a function/method.

If the previous suggestions does not help, upload your complete source package so that we can review it and debug it more comfortably.

Also, from a quick look at your code, I noticed the following problems:

  • you use too much global variables than what is really needed. That makes the code messy and prone to errors and side effects. Makes function and pass the needed variable to those functions

    • using


      from x import *
      my_function() # it's not clear that my_function come from x.py

      makes the code dirty and unreadable. It's hard to tell that you are actually using variables from root.py into your letter module. Prefer using the following form:

      import x
      x.my_function() # its clear that we use a function from the x module.

      • you should avoid copy pasting code blocks all over the place by putting them into functions . That will improve your code robustness and organisation. ( If you find a bug in a code block that is copy-pasted all over your project, you will have to apply the correction in everywhere the code blocks is copied. If this code blocks is put in a function you just have to fix the body of the function)
      • your code is poorly organised. The idea behind modules is to group common functionnality together. You might have an input module for all your input handling functions, a render module for all your render functions, a config module for your app configuration data and so on...
      • Is root.py the main file? Usually we use the following pattern to define the application entry point:


        def main():
        print "This the app entry point"

        if __name__ == "__main": # only the main script (the one passed to the python interpreter) have __name__ defined to "__main__"
        main() # call the main function


        Again, this makes the code easier to read. Someone that does not know your project needs to know where the program starts to be able to follow its flow.
        I personnaly try to always put code into functions/methods (except the import and global variables obviously).

        You could rewrite the beginning of root.py like this:


        import pygame
        import sys
        import textrect
        import time
        import letter
        from letter import *
        from ConfigParser import SafeConfigParser
        from pygame.locals import *

        def main():
        pygame.init()
        # DISPLAY
        DISPLAY = pygame.display.set_mode((640, 480))
        pygame.display.set_caption('Root')
        # and so on...


        if __name__ == "__main__":
        main()

Share this post


Link to post
Share on other sites
Thanks for the help. I planned on moving all the keyboard input events into check_input() i was just testing it first. And i'm still not sure whats causing the display (or the while loops) to update.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement