-3

So, I'm working on a project, which requires me to find how many 'objects' are in a list, which I accomplished via len(), however, now I need to make it where there is a choice (in easygui's choicebox()) for every entry in that list, without raising an 'out of range' exception.

Basically, if there are 3 entries in the list, then I need choicebox(msg="",title="",choices=[e[1]) to become choicebox(msg="",title="",choices=[e[1],e[2],e[3]]), and if there are 5 choices, I need it to become choicebox(msg="",title="",choices=[e[1],e[2],e[3],e[4],e[5]])and so on.

Notes: I need e[0] to be skipped, that being either .DS_Store, desktop.ini, or thumbs.db.
I'm listing directories just before that, so if you could tell me how to only make the directories end up on the list, or even how to limit the entries to 22, that'd be greatly appreciated as well!!

Sorry for the noobish question! I couldn't think of how to search for something like this, or a suiting title even.....

EDIT: Here's my script due to request. It is almost bugless, but very incomplete and broken;

#imports
from easygui import *
import os
#variables
storyname = None
#get user action
def selectaction():
    d = str(buttonbox(msg="What would you to do?",title="Please Select an Action.",choices=["View Program Info","Start Reading!","Exit"]))
    if d == "View Program Info":
        msgbox(msg="This program was made solely by Thecheater887. Program Version 1.0.0.               Many thanks to the following Story Authors;                                                Thecheater887 (Cheet)",title="About",ok_button="Oh.")
        selectaction()
    elif d == "Exit":
        exit
    else:
        enterage()
#get reader age
def enterage():
    c = os.getcwd()
#   print c
    b = str(enterbox(msg="Please enter your age",title="Please enter your age",default="Age",strip=True))
#   print str(b)
    if b == "None":
        exit()
    elif b == "Age":
        msgbox(msg="No. Enter your age. Not 'Age'...",title="Let's try that again...",ok_button="Fine...")
        enterage()
    elif b == "13":
#       print "13"
        choosetk()
    elif b >= "100":
        msgbox(msg="Please enter a valid age between 0 and 100.",title="Invalid Age!")
        enterage()
    elif b >= "14":
#       print ">12"
        choosema()
    elif b <= "12":
#       print "<12"
        choosek()
    else:
        fatalerror()
#choose a kids' story
def choosek():
    os.chdir("./Desktop/Stories/Kid")
    f = str(os.getlogin())
    g = "/Users/"
    h = "/Desktop/Stories/Kid"
    i = g+f+h
    e = os.listdir(i)
    names = [name for name in e if name not in ('.DS_Store', 'desktop.ini', 'thumbs.db')]
    limit = 22 # maximum entries in the choicebox --> e[1] until e[22]
    for i in xrange(1, len(e)): # starting from 1 because you don't want e[0] in there
        if(i > limit):
            break # so if you have 100 files, it will only list the first 22
        else:
            names.append(e[i])
        #names = e[1:23]
    choicebox(msg="Please select a story.",title="Please Select a Story",choices=names)
#choose a mature story
def choosema():
    os.chdir("./Desktop/Stories/Mature")
#choose a teen's story
def choosetk():
    os.chdir("./Desktop/Stories/Teen")
def fatalerror():
    msgbox(msg="A fatal error has occured. The program must now exit.",title="Fatal Error!",ok_button="Terminate Program")
#select a kids' story
def noneavailable():
    msgbox(msg="No stories are available at this time. Please check back later!",title="No Stories Available",ok_button="Return to Menu")
    enterage()
selectaction()
x otikoruk x
  • 422
  • 1
  • 6
  • 16

2 Answers2

2

So here is my solution (now that I have the code):

def choosek():
    os.chdir("./Desktop/Stories/Kid")
    f = str(os.getlogin())
    g = "/Users/"
    h = "/Desktop/Stories/Kid"
    i = g+f+h
    e = os.listdir(i)
    names = [] # the list with the file names
    limit = 22 # maximum entries in the choicebox --> e[1] until e[22]
    for i in xrange(1, len(e)): # starting from 1 because you don't want e[0] in there
        if(i > limit):
            break # so if you have 100 files, it will only list the first 22
        else:
            names.append(e[i])
    choicebox(msg="Please select a story.",title="Please Select a Story",choices=names)

I hope this is what you were looking for.

ProgrammingIsAwsome
  • 1,109
  • 7
  • 15
0

If you want to create a new list from an existing one, except that it shouldn't contain the first element, then you can use slice notation: list[start:end]. If you leave out the start, it'll start at the first element. If you leave out the end, it'll continue to the end of the list.

So, to leave out the first element, you can write:

names = e[1:]

If you want a maximum of 22 elements, write:

names = e[1:23]

If the original list contains less than 23 elements, then the new list will simply contain as many elements as it could get. If it contains more, then you'll get at most 22 elements (23 - 1).

If you want to skip certain elements, you can use list comprehensions for that: [item-expression for item in list (if filter-expression)], where the filter-expression part is optional.

This can also be used to make a copy of a list:

names = [name for name in e]

You can add a filter that excludes unwanted elements as following:

names = [name for name in e if name not in ('.DS_Store', 'desktop.ini', 'thumbs.db')]

Pieter Witvoet
  • 2,773
  • 1
  • 22
  • 33
  • Ok, so, thank you for that filter thing, but, it only filters out the first item in the list, meaning, in this case, it filters out `.DS_Store`. How can I make it filter out all 3? – x otikoruk x Jan 11 '15 at 21:18
  • If you wrote exactly what I wrote, then it should filter out all 3. The parentheses are important (though you could replace them with square brackets, as the `in` operator works on any sequence type). – Pieter Witvoet Jan 11 '15 at 21:26
  • Nope. Still doesn't work. Well... It works enough to filter out the first one, but not the second and third ones. I updated my script in the OP if you want to test it yourself. – x otikoruk x Jan 11 '15 at 22:22
  • That's because you're appending all items from `e` to `names` after you ran the list comprehension. To filter and limit the list to 22 items, combine the list comprehension with the slice notation: `names = [name for name in e if name not in ('.DS_Store', 'desktop.ini', 'thumbs.db')][1:23]`. And then don't append anything to `names`. – Pieter Witvoet Jan 11 '15 at 22:29
  • But I need it to have 3 choices if theres 3 directories, and 15 choices if there's 15 directories. How would I do that without appending then? – x otikoruk x Jan 12 '15 at 15:58
  • The list comprehension takes care of that. It creates a new list and appends all items from an existing list to it, if they match the given filter. It's just a lot shorter to write, as you don't need to spell out the exact details. But it works similar to the longer create-an-empty-list-and-append code. – Pieter Witvoet Jan 12 '15 at 16:13
  • Ok, so, I tried that, but, it still only filters out the first result. Are you talking about python 3? – x otikoruk x Jan 12 '15 at 16:42
  • Nope, this already works in Python 2.5 (just tested it). If you run `[name for name in ['a', 'b', 'c', 'd'] if name not in ('a', 'b')]`, what do you see? You should get `['c', 'd']`. (and with 'run' I mean, just type it into a Python command-line, or in IDLE, or in a new, otherwise empty, Python file, so you are certain there's no other code, as in the code you've shown). – Pieter Witvoet Jan 12 '15 at 19:27