Hello all,

I'm taking a intro computer science course, yet somehow I'm much better at c++ than python. My professor is essentially useless. Can anyone show me how to let these variables persist into global scope? I assumed declaring them globally would make them persist, yet it appears to not. Thank you.

(There are a few things that are irrelevant at this point-- just thinking ahead. Example is the strAlpha list)

# Riveter -- Justin M

strPlayer1 = ""
strPlayer2 = ""
nHeight = 0
nWidth = 0
strAlpha = "a b c d e f g h i j k l m n o p q r s t u v w x y z"
varBoard = 0

def Start():
    print("Welcome to Riveter")
    strPlayer1 = raw_input("Name of first player: ")
    strPlayer2 = raw_input("Name of second player: ")
    strInput = "not digits"
    while not(strInput.isdigit()):
        strInput = raw_input("How many rows should there be?: ")
    nHeight = int(strInput)
    strInput = "not digits"
    while not(strInput.isdigit()):
        strInput = raw_input("How many columns should there be? (Up to 26!): ")
    nWidth = int(strInput)

def Setup():
    nInsideLoop = 0
    nOutsideLoop = 0
    varBoard = [[0 for col in range(nWidth)] for row in range(nHeight)]
    while nOutsideLoop < nHeight:
        while nInsideLoop < nWidth:
            if ((0 < nInsideLoop < nWidth) and (0 < nInsideLoop < nHeight)):
                varBoard[nOutsideLoop][nInsideLoop] = 1
            nInsideLoop = nInsideLoop + 1
        nOutsideLoop = nOutsideLoop + 1


def Display():
    nInsideLoop = 0
    nOutsideLoop = 0
    nHeight = 3
    while nOutsideLoop < nHeight:
        print "inside loop"
        while nInsideLoop < nWidth:
            
            if (varBoard[nOutsideLoop][nInsideLoop] == 0):
                print "X"
            if (varBoard[nOutsideLoop][nInsideLoop] == 1):
                print " "
            nInsideLoop = nInsideLoop + 1
        nOutsideLoop = nOutsideLoop + 1

Start()
Setup()
print nWidth
print nHeight
Display()

I do not understand what you mean that you declared globally variables, which usually is not good idea for your information. You have not a single assignment in your main code only three function calls and print statements. Also you have not any global declarations. Your naming of functions and variable is totally against Python conventions BTW you have not list strAlpha but string. Ok now I saw that you had hidden your globals in beginning of the file where should be only constant definitions. I run your code and see what you are doing as by reading I can not understand. I am writing this on phone.

# Riveter -- Justin M
def Start():
    print("Welcome to Riveter")
    strPlayer1 = raw_input("Name of first player: ")
    strPlayer2 = raw_input("Name of second player: ")
    strInput = "not digits"
    while not(strInput.isdigit()):
        strInput = raw_input("How many rows should there be?: ")
    nHeight = int(strInput)
    strInput = "not digits"
    while not(strInput.isdigit()):
        strInput = raw_input("How many columns should there be? (Up to 26!): ")
    nWidth = int(strInput)
    return (nWidth, nHeight), (strPlayer1, strPlayer2)


print Start()

Fix your naming!

Edited 5 Years Ago by pyTony: n/a

Despite the wrong convention (as I said, a survey-level class), I realize using global variables is not ideal, yet with my knowledge i found it appropriate. But you say that defining them as I did, by convention, they should be constant? How do I get around this? Or must i pass all the information I collected in the Start function (height, width, and the names) to the caller?

The way I returned, you should define function for numeric input as you are repeating pattern two times. More conventional than your while is to try to convert to int and use try.. except with separate announcement when input was not accepted.

If you do not like return values from functions (if you know C you should know that stuff), you can pass one list to function and the values it insert to list are globally available (side effects, also not very good programming practice, be careful!).

If you really insist plain global variables, you should declare them as global at beginning of function otherwise you create local variable with same name.

BTW your second input did not check if the input number confirmed to stated range restriction.

Edited 5 Years Ago by pyTony: n/a

Python doesn't like global variables. If you insist on using them, be explicit. Declare them as such.
As for your current arrangement, the assignment at line 13 makes Python think that strPlayer1 is a local variable - it doesn't bother to check its global existence.
Just add

global strPlayer1

to Start()

Despite the wrong convention (as I said, a survey-level class),

Try to conform to PEP8, if you have not very important reason not to (actually when not conform to PEP8 is first part of PEP8 ;) Nice recursion!)

This does not give you freedom to learn bad habits. You most probably do not understand but naming is of utmost importance. Here one document from net which is mostly good, read it and learn it. You will not regret it! (If you read this and agree with me, let's "see hands" and upvote me) Naming is one of most important parts of programming. That is because Python philosophy 'Code is read more often than written.' is correct.

http://bayes.colorado.edu/PythonGuidelines.html

Why have coding guidelines?

As project size increases, consistency increases in importance. This project will start with isolated tasks, but we will integrate the pieces into shared libraries as they mature. Unit testing and a consistent style are critical to having trusted code to integrate. Also, guesses about names and interfaces will be correct more often.

Good code is useful to have around. Code written to these standards should be useful for teaching purposes, and also to show potential employers during interviews. Most people are reluctant to show code samples: having good code that you've written and tested will put you well ahead of the crowd. Also, reusable components make it much easier to change requirements and perform new analyses.
What should I call my variables?

Choose the name that people will most likely guess. Make it descriptive, but not too long: curr_record is better than c, or curr, or current_genbank_record_from_database. Part of the reason for having coding guidelines is so that everyone is more likely to guess the same way. Who knows: in few months, the person doing the guessing might be you.

Good names are hard to find. Don't be afraid to change names except when they are part of interfaces that other people are also using. It may take some time working with the code to come up with reasonable names for everything: if you have unit tests, it's easy to change them, especially with global search and replace.

Use singular names for individual things, plural names for collections. For example, you'd expect self.Name to hold something like a single string, but self.Names to hold something that you could loop through like a list or dict. Sometimes the decision can be tricky: is self.Index an int holding a positon, or a dict holding records keyed by name for easy lookup? If you find yourself wondering these things, the name should probably be changed to avoid the problem: try self.Position or self.LookUp.

Don't make the type part of the name. You might want to change the implementation later. Use Records rather than RecordDict or RecordList, etc. Don't use Hungarian Notation either (i.e. where you prefix the name with the type).

Make the name as precise as possible. If the variable is the name of the input file, call it infile_name, not input or file (which you shouldn't use anyway, since they're keywords), and not infile (because that looks like it should be a file object, not just its name).

Use result to store the value that will be returned from a method or function. Use data for input in cases where the function or method acts on arbitrary data (e.g. sequence data, or a list of numbers, etc.) unless a more descriptive name is appropriate.

One-letter variable names should only occur in math functions or as loop iterators with limited scope. Limited scope covers things like for k in keys: print k, where k survives only a line or two. Loop iterators should refer to the variable that they're looping through: for k in keys, i in items, or for key in keys, item in items. If the loop is long or there are several 1-letter variables active in the same scope, rename them.

Limit your use of abbreviations. A few well-known abbreviations are OK, but you don't want to come back to your code in 6 months and have to figure out what sptxck2 is. It's worth it to spend the extra time typing species_taxon_check_2, but that's still a horrible name: what's check number 1? Far better to go with something like taxon_is_species_rank that needs no explanation, especially if the variable is only used once or twice.

Acceptable abbreviations. The following abbreviations can be considered well-known and used with impunity:
full abbreviated
alignment aln
archaeal arch
auxillary aux
bacterial bact
citation cite
current curr
database db
dictionary dict
directory dir
end of file eof
eukaryotic euk
frequency freq
expected exp
index idx
input in
maximum max
minimum min
mitochondrial mt
number num
observed obs
original orig
output out
phylogeny phylo
previous prev
protein prot
record rec
reference ref
sequence seq
standard deviation stdev
statistics stats
string str
structure struct
temporary temp
taxonomic tax
variance var

(Just ignore the followin always use from module import part, import module is good practise!)

Edited 5 Years Ago by pyTony: n/a

I appreciate the advice and have tried to conform most of the code. Passing variables, not globals, better(??) naming, and proper capitalization.

Does anyone have suggestions on how to handle the board variable better? edges are x's and the middle spots are blank, as such:

XXXXXX
X    X
X    X
XXXXXX

it doesn't seem to work. Once again, thank you.

# Riveter -- Justin McBride

ALPHABET = "a b c d e f g h i j k l m n o p q r s t u v w x y z"

def start():
    print("Welcome to Riveter")
    player1 = raw_input("Name of first player: ")
    player2 = raw_input("Name of second player: ")
    response = "not digits"
    while not(response.isdigit()):
        response = raw_input("How many rows should there be?: ")
    height = int(response)
    response = "not digits"
    while not(response.isdigit()):
        response = raw_input("How many columns should there be? (Up to 26!): ")
    width = int(response)
    return (player1, player2, height, width)

def setup(height, width):
    inside_loop = 0
    outside_loop = 0
    board = [[0 for col in range(width)] for row in range(height)]
    while outside_loop < height:
        while inside_loop < width:
            if ((0 < inside_loop < width) and (0 < inside_loop < height)):
                board[outside_loop][inside_loop] = 1
            inside_loop = inside_loop + 1
        outside_loop = outside_loop + 1
    return board

def display(height, width, board):
    inside_loop = 0
    outside_loop = 0
    while outside_loop < height:
        while inside_loop < width:
            if (board[outside_loop][inside_loop] == 0):
                print "X"
            if (board[outside_loop][inside_loop] == 1):
                print " "
            inside_loop = inside_loop + 1
        outside_loop = outside_loop + 1

#### main

setup_info = start()
player1 = setup_info[0]
player2 = setup_info[1]
height = setup_info[2]
width = setup_info[3]
board = setup(height, width)
display(height, width, board)

Edited 5 Years Ago by dare599z: n/a

def display(height, width, board):
    print width * '*'
    print (height - 2) * ('*' + (width - 2) * ' ' + '*\n'),
    print width * '*'
>>> import string
>>> ALPHABET = list(' '*len(string.ascii_lowercase)*2)
>>> ALPHABET[::2] = string.ascii_lowercase
>>> ALPHABET
['a', ' ', 'b', ' ', 'c', ' ', 'd', ' ', 'e', ' ', 'f', ' ', 'g', ' ', 'h', ' ', 'i', ' ', 'j', ' ', 'k', ' ', 'l', ' ', 'm', ' ', 'n', ' ', 'o', ' ', 'p', ' ', 'q', ' ', 'r', ' ', 's', ' ', 't', ' ', 'u', ' ', 'v', ' ', 'w', ' ', 'x', ' ', 'y', ' ', 'z', ' ']
>>> ALPHABET = ''.join(ALPHABET)
>>> print ALPHABET
a b c d e f g h i j k l m n o p q r s t u v w x y z 
>>> ALPHABET = ''.join(c+' ' for c in string.ascii_lowercase)
>>> print ALPHABET
a b c d e f g h i j k l m n o p q r s t u v w x y z 
>>>

Edited 5 Years Ago by pyTony: n/a

I thank you for the assistance.
I'm getting the hang of it!
Marking as solved..

Final code(in terms of this thread!! -- still working on little functions of the game):

# Riveter

def start():
    """Initial setup function. Returns input."""
    print("Welcome to Riveter")
    player1 = raw_input("Name of first player: ")
    player2 = raw_input("Name of second player: ")
    response = "not digits"
    while not(response.isdigit()):
        response = raw_input("How many rows should there be?: ")
    height = int(response)
    response = "not digits"
    while not(response.isdigit()):
        response = raw_input("How many columns should there be?: ")
    width = int(response)
    return (player1, player2, height, width)

def setup(height, width):
    """Makes the board, accepting height and width."""
    board = []
    outside_loop = 0
    while outside_loop < height:
        inside_loop = 0
        inside_array = []
        while inside_loop < width:
            #The following removes the middle coins.
            if ((0 < inside_loop < width-1) and (0 < outside_loop < width-1) and (0 < inside_loop < width-1) and (0 < inside_loop < height-1)):
                inside_array.append(1)
            #But this keeps all others.
            else: inside_array.append(0)
            inside_loop += 1
        board.append(inside_array)
        outside_loop += 1
    return board

def display(height, width, board):
    """Displays the board. Xs represent coins.  """
    outside_loop = 0
    while outside_loop < height:
        output = ""
        inside_loop = 0
        while inside_loop < width:
            if (board[outside_loop][inside_loop] == 0):
                output = output + "X"
            if (board[outside_loop][inside_loop] == 1):
                output = output + " "
            inside_loop += 1
        print output
        outside_loop += 1

def status(height, width, board):
    """Checks to see if the game is won. When it encounters a coin,
       it proceeds to return a value, continuing the game."""
    outside_loop = 0
    while outside_loop < height:
        inside_loop = 0
        while inside_loop < width:
            if (board[outside_loop][inside_loop]):
                return 1               
            inside_loop += 1
        outside_loop += 1
    return false

def turn(player, board):
    """Allows players to make turns. Accepts the player name, and the board variable."""
    print ('\n' * 3) + "Your turn, " + player + "!"
    print
    response = "not digits"
    while not(response.isdigit()):
        response = raw_input("How many do you want to remove?: ")
    number_coins = int(response)
    #Allows removal of number_coins coins.
    looping = 0
    while (looping < number_coins):
        column = "not digits"
        while not(column.isdigit()):
            column = raw_input("What column to remove this coin from?: ")
        row = "not digits"
        while not(row.isdigit()):
            row = raw_input("What row to remove this coin from?: ")
        board[int(row)-1][int(column)-1] = 1 #The subtraction accounts for counting error.
        looping += 1
        print "Removed."
        print
    return board


#### main ####

#Initiate, and set up common variables
setup_info = start()
player1 = setup_info[0]
player2 = setup_info[1]
height = setup_info[2]
width = setup_info[3]
board = setup(height, width)

#The main game.
turn_number = 0
while (status(height, width, board)):
    print ('\n' * 60)
    display(height, width, board)
    if (turn_number % 2):
        board = turn(player2, board)
    else:
        board = turn(player1, board)
    turn_number += 1

Edited 5 Years Ago by dare599z: removed name

This question has already been answered. Start a new discussion instead.