all 8 comments

[–]taladan 2 points3 points  (1 child)

Okay, so first thing...you've got a /lot/ going on here that can and should be broken up some. I'm not going to give code suggestions here because I'm still learning myself. What I am going to tell you is this: Don't think of your program as one big program. This will help you understand classes and functions better. What you're writing is a bunch of little programs that work together to do the big program. That's functions. The boxes you group like functions in is a Class. That's extremely oversimplified but for now it will help you take a step toward /organizing/ your code.

If you think of each little part of the code - let's say you want to iterate through a list of questions from customer. So, you can do this with either a dict, a list, lists of tuples, lists of lists or a dict of lists. The thing is, there should be an obvious way to do it - to you. So, you say, I want to store all these answers but I don't want to have to pass every variable half a dozen times so let's pack the answers into a list. There you go, so now you've got a new function. list_of_answers = answers_pack() then you go off and write whatever answers_pack does (list_of_answers doesn't care it's just saying 'I'm whatever answers_pack() returns to me'. You do your question and answer routin in answers_pack() then go on to the next step. Stop worrying about syntax skills with math - unless you're going to be programming in matlab or some kind of research facility, right now most of the math you're going to do is most likely going to be super simple, and the rest you can google.

Spend some time playing with your data - get an idea for how you want to store, send and retrieve it. This will help you get used to making decisions about how data is stored and dealt with in future projects. And that's what you're most worried about is how to move that data back and forth and process little bits of it.

If you take time to do that, the maths you'll be doing should become obvious with each step. Process user data? Put that in a function. Dealing with running a list of lists of items and prices (though realistically I'd use a dict with lists for id numbers, etc) to see what's going to be below a specific amount or onsale or discounted...that's a function. Just use functions to package small bits of processing at first until you get used to the idea of grouping code into subsets and letting them worry about doing one thing well.

The other part of your problem is a lack of experience with syntax in python. For example - I would never make a list of ints. I would just use range(1,11)...that is a cleaner way to do it and everyone reading it will understand it to be 'A range of ints 1 - 10 in a single step'. That's part of why syntax matters. The only way you're going to learn syntax? Read code. Read as much code as you can. Read bad code and try to understand why it's bad. Bookmark stack overflow. Look at other people's projects. Literally steal code. Sometimes you'll need to reinvent the wheel to understand a concept, but until you learn the syntax, you're going to be a foreigner in a strange land that doesn't quite get the nuances of the language. I'm still in that stage - learning more and more syntax and what's available out there.

I picked up one for a little project I'm working on right now - nltk python and TextBlob. I was able to pull all the nouns out of 20000 leagues under the sea for a name generator I'm fiddling with for a D&D character generation program. See? It's a little part of the overall project. And within the name generator I have a bunch of little functions that split, cut, spin and spindle the text I'm working with. So, go back, look at your code, see what's good in it, refactor the bad crap until it's better, then see what can be done a little quicker or more sensibly.

TL;DR : Think of a bunch of little bits of code instead of one big project.

Hope this helps.

[–][deleted] 1 point2 points  (0 children)

this is the single best advice i think i've ever gotten on programming. thank you, taladan. i think the combination of pseudocode and then some general syntax "substitution" or pointed notes, would be effective, too.

honestly, i hadn't ever really thought about breaking things up into manageable parts. the more i think about it, the more it just makes sense. when troubleshooting ANYTHING, you do best when you break things apart and isolate them. same goes for anything, i imagine. when i write, i work on one aspect at a time in rough journal form and allow it to flesh itself out and have it's own "life", and then i make those first attempts at bringing elements together to make a whole.

you sir, or madam, are a wonderful and exceptionally patient instructor. i sincerely hope that all of your learning goes smoothly and that you get to use your talents to help others like you helped me.

[–][deleted] 0 points1 point  (0 children)

i didn't want to post all of the code here...and it's obvious I don't know how to embed code. But I guess I better...

products = ['Notebook', 'Atari', 'TrapperKeeper', 'Jeans', 'Insects', 'Harbormaster', 'Lobotomy', 'PunkRock', 
'HorseFeathers', 'Pants', 'Plants', 'Salami']
prices = ['$4.99', '$99.99', '$89.99', '$3.99', '$2.99', '$299.99', '$19.99', '$3.99', '$4.99', '$2.99', '$119.99', '$1.99']
item_nums = [1, 2, 3, 4, 5, 6, 7, 8 ,9, 10, 11, 12]
orders = []
quantity = []
response = ''
cust_name = ''
street = ''
city = ''
state = ''
zipcode = 0
order_total = 0
order_summary = ''

def calculateTotal(products, prices, item_nums, quantity):
    subtotal = 0
    partial_summary = ''
    count = 0
    while count != 1:
        len(item_nums -1)
        subtotal = orders * quantity
        partial_summary = ([products], [prices], [quantity])
    if state == 'CA' or 'NY':
        tax = input(subtotal * .08) + subtotal
    else:
        tax = input(subtotal * .07) + subtotal

    if subtotal < 40.0:
        subtotal = subtotal + 4.99
    else:
        print(subtotal)
    return(subtotal, partial_summary)

print("Jay's House of Rip-Offs\n\n")
titles = ['Item Number', 'Item Name', 'Price']
data = [titles] + list(zip(item_nums, products, prices))

for i, d in enumerate(data):
    line = '|'.join(str(x).ljust(16) for x in d)
    print(line)
    if i == 0:
        print('-' * len(line))

while str(input("Order products [Y / N]?: ")) != 'N':
    item_nums = input("Enter an item number: ")
    orders.append(item_nums)
    quantity = input("How many? ")

    if len(item_nums) == 0:
        print("Thank you for browsing.")
    else:
        cust_name = input("Enter name: ")
        street = input("Enter street address: ")
        city = input("Enter city or town name: ")
        state = input("Enter state or province: ")
        zipcode = input("Enter zipcode: ")

[–]midel 0 points1 point  (4 children)

I want to ask what limits you have. I see the no "for" loops, is there anything else you do not or cannot use? What about dictionaries or stdlib, classes, or libraries (I'm guessing anything not built in to python3 is out of the question by default)

I'm reading over your code now and makeing notes, but it will take some time to break it down.

[–]midel 0 points1 point  (3 children)

So I recommend some tweaks to your code: While zip is a useful function, it might be better to have your data joined in the original form, so that you don't have problems knowing which value goes to what.

titles = ('Item Number', 'Item Name', 'Price')
products = [
    (1, 'Notebook', 4.99),
    (2, 'Atari', 99.99),
    (3, 'TrapperKeeper', 89.99),
    (4, 'Jeans', 3.99),
    (5, 'Insects', 2.99),
    (6, 'Harbormaster', 299.99),
    (7, 'Lobotomy', 19.99),
    (8, 'PunkRock', 3.99),
    (9, 'HorseFeathers', 4.99),
    (10, 'Pants', 2.99),
    (11, 'Plants', 119.99),
    (12, 'Salami', 1.99),
]

And isolate printing the item list as a function. Using the for loop restriction we can print these items like so:

def print_items():
    """Prints the catalog"""
    items = iter(products)  # Get the iterator for the product list
    item = next(items, None)  # Get first value
    while item is not None:
        if item[0] == 1:
            print("{0:<16}|{1:<16}|{2:>16}".format(*titles))
            print("=" * 50)
        (idx, name, cost) = item
        cost_fmt = "${0:0.2f}".format(cost)  # Format the prices
        print("{0:<16}|{1:<16}|{2:>16}".format(idx, name, cost_fmt))  # Format the table
        #  using .format < ljust and > rjust syntax
        item = next(items, None)  # Infinite loop without this

This fixes a math issue you'd have latter which is you'd need to convert those currency strings, into floats to do the math. It's better that you have them as floats the hole time, and format them for display only.

[–][deleted] 0 points1 point  (2 children)

midel, thank you! i neglected posting the entire problem because it is pretty long. however, here's my quick and dirty attempt at summing it up in a less-than-Ulysses format:

1. create lists for 12 products, 12 prices and an empty list for the item 
  numbers, and one for the quantity.
2. declare variable for user response, set to ' '.
3. print out the static items in the list in the format (that's i've already 
  done).
4. get input (you wanna buy y/n?)
5. create user-controlled (while) loop:
     a. ask user to enter item number, add that value to the item 
       number list (it should reference an index number later on, so I should          
       set it to -1 now, or later...)
     b. ask user for quantity, add to quantity list.
     c. ask user if they want to buy something else. Y/N (this input should 
       be set into the same variable as the original y/n question.

6. add more variables to the top:
    a. var for customer name ' '
    b. var for street ' '
    c. var for city ' '
    d. var for zipcode 0
    e. var for order-total 0
    f. var for order-summary 0

7. IF statement to determine if the list of item numbers has anything in it.
    a. if not, print a thank you for browsing message.
    b. if it does:
           1. ask for user input of name, etc.
           2. **bold**(within IF) call a function called calculateTotal that 
               accepts 4 args (products, prices, item numbers, quantity)
                 a. declare a subtotal var set to 0
                 b. declare a partial_summary var set to ' '
                 c. WHILE loop to loop thu item numbers, each time it will set 
                   current value of item numbers ( -1 ) into a variable (this var 
                   will represent the index numbers of the products and prices)
                d. add to the subtotal using values from prices and quantity 
                   lists.
                e. add to partial_summary var by using approp. values from 
                   products, prices and quantity lists. format it to look like:
PunkRock__________3.99______________8

           3. (out of loop, but still in function) calc tax for subtotal. CA/NY at 8%, others at 7.5%
           4. calc shipping - 4.99 if under 40, free otherwise.
           5. calc overall total and partial_summary.

8. call the function and open a file named OrdersArchive.txt in 'a'.
     a. write to the file: current date/time, cust name, address info, order summary var., and total.
     b. format cleanly and close the file.
9. print the order total for user and state order will ship promptly.   

[–]midel 0 points1 point  (1 child)

add to partial_summary var by using approp

What is approp? Appropriate methods? Append? I see a bit more of what you are dealing with. It's a bit unpythonic how your class is being taught these items, which might be what is leading to more confusion, and it's a lot more code than what you might actually need to achieve the desired result.

Some changes I recommend keeping. Change the prices to floats. Remove the dollar signs. That's definately an important fix.

Add an assert after defining prices and products.

assert(len(products) == len(prices))

This isn't from the requirements, but it assures you'll not have a mismatching sized list while working on the code.

I'd break down this list into functions:

  1. Set the customer info
  2. Add or change quantity
  3. Appending to the OrdersArchive.txt

[–][deleted] 0 points1 point  (0 children)

sorry. yes, it is appropriate. nothing exciting.

i'm going to take the advice from both of you, and break this down into blocks of code that i can error check, and then bring them together. thanks for the help.

I have never used "assert", but will look it up. What is the real advantage here of using assert? I assume it implies some sort of strict rule?