4
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import pprint

scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)

def openSheet():
    shname = str(input("Enter existing sheet name >> "))
    sheet = client.open(shname).sheet1
    term()

def createSheet():
    shnname = str(input("Enter new sheet name >> "))
    mail = str(input("Enter mail address >> "))
    sheetn = client.create(shnname)
    sheetn.share(mail, perm_type='user', role='owner')
    term()

def help():
    print("openSheet - open spreadsheet (do this befor any other command [except createSheet])")
    print("createSheet - create spreadsheet and transfer ownership")
    print("printAll - print all data from spreadsheet")
    print("printCol - print data from specified column")
    print("printRow - print data from specified row")
    print("printCell - print data from the one, specified cell")
    print("changeCell - change data in one, specified cell")
    print("help - displays all the functions and their description")
    print("exit - closes the program")
    term()

def changeCell():
    x = int(input("Enter number of col >> "))
    y = int(input("Enter number of row >> "))

    pp = pprint.PrettyPrinter()
    data = sheet.cell(y,x).value
    pp.pprint(data)

    upd = str(input("Enter data >> "))

    sheet.update_cell(y, x, upd)
    data = sheet.cell(y,x).value
    pp.pprint(data)
    term()

def printCell():
    x = int(input("Enter number of col >> "))
    y = int(input("Enter number of row >> "))

    pp = pprint.PrettyPrinter()
    data = sheet.cell(y,x).value
    pp.pprint(data)
    term()

def printRow():
    y = int(input("Enter number of row >> "))

    pp = pprint.PrettyPrinter()
    data = sheet.row_values(y)
    pp.pprint(data)
    term()

def printCol():
    x = int(input("Enter number of col >> "))

    pp = pprint.PrettyPrinter()
    data = sheet.col_values(x)
    pp.pprint(data)
    term()

def printAll():
    pp = pprint.PrettyPrinter()
    data = sheet.get_all_values()
    pp.pprint(data)
    term()

def none():
    term()

def term():
    terminal = str(input(">> "))

    if (terminal == "openSheet"):
        openSheet()
    if (terminal == "createSheet"):
        createSheet()
    if (terminal == "printAll"):
        printAll()
    if (terminal == "printCell"):
        printCell()
    if (terminal == "changeCell"):
        changeCell()
    if (terminal == "printCol"):
        printCol()
    if (terminal == "printRow"):
        printRow()
    if (terminal == "help"):
        help()
    if (terminal == "exit"):
        exit()
    else:
        none()

term()

So, when I run this in terminal, and type in openSheet, enter name of spreadsheet and type in printAll, I get this:

>> openSheet
Enter existing sheet name >> values
>> printAll
Traceback (most recent call last):
  File "/home/luky/sheets/sheets.py", line 106, in <module>
    term()
  File "/home/luky/sheets/sheets.py", line 86, in term
    openSheet()
  File "/home/luky/sheets/sheets.py", line 12, in openSheet
    term()
  File "/home/luky/sheets/sheets.py", line 90, in term
    printAll()
  File "/home/luky/sheets/sheets.py", line 75, in printAll
    data = sheet.get_all_values()
NameError: name 'sheet' is not defined

Apparently, sheet is not defined. I have no idea how to fix it. I'm thinking, that it doesn't assing anything to sheet variable, so it can't read things in it. Not sure tho. It works when I don't use openSheet as a function.

  • 1
    This has nothing to do with `gspread` not keeping a connection open, you just misunderstand scopes. Variables defined inside functions will not be available outside of that function, without `global`, and you don't want to go down that path – roganjosh Dec 02 '18 at 21:40
  • Don't use recursion, either; `term` should just contain a loop that repeatedly asks for input and calls the appropriate function. Then your other functions simply return rather than calling `term()` at the end. (Python isn't optimized for that kind of continuation-style programming, and you will eventually run out of stack space.) – chepner Dec 03 '18 at 17:57

1 Answers1

5

Use the global keyword

# Hello World program in Python


def foo():
    global bar #Define the global variable bar
    bar = "Hello world" #Set bar to hello world

foo() #Set bar
print bar #Hello world



#Second example


fo = "Initial value" #Initial value


def foobar():
    global fo
    fo = "Value changed"
    bar = "Value changed" #Global variable 'bar' isn't changed because we didn't declare bar global in this function. There is only a local variable named 'bar' created.

print fo #Initial value
print bar #Hello world

foobar() #Change value

print fo #Value changed
print bar #Hello world

http://tpcg.io/yUvZD8 (Try it out)

Never make a variable global, just declare it global at the beginning of the function and change the value.

SmileDeveloper
  • 366
  • 3
  • 10