0

So I have been searching on Overflow for a few days now for a problem that I am working on. I understand the communities efforts to curb the homework questions, but I am stumped and would like to learn this concept and move on to learn more programming.

In Python I am developing a Matrices or 2D Array.

Here are the Array's Programming requirements from the user and comparing the value to the arrays value:

Then ask the user to enter both the first name and last name of one of the users in the matrix, then print the corresponding information (entire row) for that person if found; if not found, print 'User Not Found!'

Here's what I have so far on that array.

rows = 5
cols = 7
names_matrix = ([['lname', 'fname', 'city', 'state', 'zipcode'],
                 ['Zdolfalos', 'Johnson', 'Terrell', 'Wilson', 'Key', 'Smith',     
                  'Alfonso'], 
                 ['Fred', 'Malcom', 'Monkey', 'Wilson', 'LeDoor', 'Jim Bob', 'Ralph'],
                 ['Charlotte', 'Monroe', 'Broken Pine', 'Hogwart', 'Spot in Road',  
                  'Denver','Gastonia'], 
                 ['NC', 'NC', 'SC', 'VA', 'AL', 'NC', 'NC' ],
                 ['28210', '28337', '28974', '27457', '36827', '28037', '28559'] ])

print names_matrix

#Create a Boolean variable flag.
found = False

#Create a variable to use as a loop counter.
index = 0

#Get the strings to search for.

for in names_matrix:  #Having problems here with what goes here in For In Loop
    userFirstName = raw_input('What is the user first name?')
    userLastName =  raw_input('What is the user last name?')

    if userFirstName == names_matrix [1] and userLastName == names_matrix [0]:
        print('')
    #I want to print the Matrix value from the user input
    else
        print('User Not Found!')
# nested find columns
# https://stackoverflow.com/questions/7845165/how-to-take-input-in-an-array-python

I'm new to python and programming and have seen in the book how they made this with a While Loop with the false and index. I was having difficulty understand pass by values and references I think as well.

# Get the string to search for.
searchValue = raw_input('Enter a name to search for in the list: ')
# Step through the list searching for the
# specified name.
while found == False and index < len(names):
    if names[index] == searchValue:
        found = True
    else:
        index = index + 1
# Display the search results.
if found:
    print 'That name was found in element ' + str(index + 1)
else:
    print 'That name was not found in the list.'

I was wondering how to do this with a For In Range Loop. It might be a Nested Loop and those are a bit more tricky.

I don't believe I need the boolean flag or index part at the beginning of my coding for a For In range loop. I was just showing my progress so far and was trying to get this program to work better.

I researched the following helpful links for For In Range but was getting stumped.

For In input in an Array

Array For In

Testing User Input in Array

Python If Else Nested Statements

We haven't gone over Class and Objects and did see how to do that, and we also haven't gone over numpy and tried using import numpy and was having some problems with that as I'm new to numpy as well. I am reading Think Like a CS with Python as additional help with the class as well as Learn Python the Hard Way.

Thanks for your time.

Community
  • 1
  • 1
MeachamRob
  • 363
  • 3
  • 8
  • 19
  • 1
    Does the `names_matrix` data have to be arranged the way it is? I think a lot of the reason you are having trouble is because of the way this is layed out. – Jon Betts Apr 30 '14 at 19:33

3 Answers3

2

The correct syntax for a for loop iteration is:

for x in iterable_object:
    # do something with each x

In english, take each item in your iterable_object, call it x, and perform some code involving x.

for range objects:

for i in range(0,10,1):
    print i 

This will print the numbers from 0-9, i.e. i will have the value 0 and is incremented by the third argument 1 until it is of value 10 and will not reenter the loop which means the last printed value will be 9.

Python allows for some shorthand calls for this:

for i in range(10):
    print i

does the same thing. When one argument is provided is it interpreted as the upper limit.

ref: range()

In your case you have this data:

names_matrix = ([['lname', 'fname', 'city', 'state', 'zipcode'],
             ['Zdolfalos', 'Johnson', 'Terrell', 'Wilson', 'Key', 'Smith',     
              'Alfonso'], 
             ['Fred', 'Malcom', 'Monkey', 'Wilson', 'LeDoor', 'Jim Bob', 'Ralph'],
             ['Charlotte', 'Monroe', 'Broken Pine', 'Hogwart', 'Spot in Road',  
              'Denver','Gastonia'], 
             ['NC', 'NC', 'SC', 'VA', 'AL', 'NC', 'NC' ],
             ['28210', '28337', '28974', '27457', '36827', '28037', '28559'] ])

You probably want information by column correct and ignoring the headers?

iteration 1 - Zdolfalos, Fred, Charlotte, NC, 28210
iteration 2 - Johnson, Malcom, Monroe, NC, 28337
etc ...

This means you want to iterate across the size of your names_matrix[1], the second object in your list.

L = len(names_matrix[1])
print names_matrix[0][0],names_matrix[0][2],names_matrix[0][2],names_matrix[0][3],names_matrix[0][4]
for i in range(L):
    print names_matrix[1][i],names_matrix[2][i],names_matrix[3][i],names_matrix[4][i],names_matrix[5][i]

will give you:

lname fname city state zipcode
Zdolfalos Fred Charlotte NC 28210
Johnson Malcom Monroe NC 28337
Terrell Monkey Broken Pine SC 28974
Wilson Wilson Hogwart VA 27457
Key LeDoor Spot in Road AL 36827
Smith Jim Bob Denver NC 28037
Alfonso Ralph Gastonia NC 28559

It looks like you are trying to perform a search for someone in your data. I would say to perform the user input before the loop, and then compare as you have done with the slight change to the indexing performed above.

One note here, I find your data to be arranged in a rather strange manner. I like it would make more sense to structure it as:

names_matrix = (
   [['lname',     'fname',   'city', 'state', 'zipcode'],               
    ['Zdolfalos', 'Fred',    'Charlotte','NC','28210'],
    ['Malcom',    'Johnson', 'Monroe', 'NC', '28337',],
    ['Monkey',    'Terrell', 'Broken Pine', 'SC','28974',],
    # ...etc...
   ] 

Making the iterations rather simple to iterate through your entries:

for user in names_matrix[1:]: # [1:] means take the list from the 1st element to the end, noted by the lack of a number after the colon (on a 0 based index)
    print user

python being the awesomeness that it is, provides very quick and easy operations for such transformations:

names_matrix = zip(*names_matrix[1:])

The zip function in this case tells python to take the matrix, excluding the first entry which are your headers.

([['lname', 'fname', 'city', 'state', 'zipcode'],
             ['Zdolfalos', 'Johnson', 'Terrell', 'Wilson', 'Key', 'Smith',     
              'Alfonso'], 
             ['Fred', 'Malcom', 'Monkey', 'Wilson', 'LeDoor', 'Jim Bob', 'Ralph'],
             ['Charlotte', 'Monroe', 'Broken Pine', 'Hogwart', 'Spot in Road',  
              'Denver','Gastonia'], 
             ['NC', 'NC', 'SC', 'VA', 'AL', 'NC', 'NC' ],
             ['28210', '28337', '28974', '27457', '36827', '28037', '28559'] ])

upzip it by each entry, which are your categories

zip(  ['Zdolfalos', 'Johnson', 'Terrell', 'Wilson', 'Key', 'Smith','Alfonso'],
      ['Fred', 'Malcom', 'Monkey', 'Wilson', 'LeDoor', 'Jim Bob', 'Ralph'],
      ['Charlotte', 'Monroe', 'Broken Pine', 'Hogwart', 'Spot in Road','Denver','Gastonia'], 
      ['NC', 'NC', 'SC', 'VA', 'AL', 'NC', 'NC' ],
      ['28210', '28337', '28974', '27457', '36827', '28037', '28559'] )

and pair across each of these lists by their indexes into tuples:

[ ('Zdolfalos', 'Fred', 'Charlotte', 'NC', '28210'),
  ('Johnson', 'Malcom', 'Monroe', 'NC', '28337'),
  ('Terrell', 'Monkey', 'Broken Pine', 'SC', '28974'),
# ... etc ...
]

Now you can iterate across the user and not have to deal with the more complex indexing that you would need with your current setup.

This can be done as a temporary step for ease of use if you would rather keep the original data in the format you have it in currently.

Of course you can still do it if you prefer not to alter the data.

userFirstName = raw_input('What is the user first name?')
userLastName =  raw_input('What is the user last name?')
L = len(names_matrix[1])
for i in range(L):
    if userFirstName == names_matrix[0][i] and userLastName == names_matrix[1][i]:
        print('Found!')
    else
        print('User Not Found!')

This format could perhaps give you some ideas for how to implement what you are asking

Farmer Joe
  • 6,020
  • 1
  • 30
  • 40
1

The way your names_matrix is laid out does not correspond with the first list in it. The first list in the names_matrix is ['lname', 'fname', 'city', 'state', 'zipcode'] which makes one think that the subsequent lists in it follow that order.

Where as the subsequent lists in names_matrix are list of last names followed by list of first names followed by a list of cities followed by a list of states followed by a list of zip codes.

We can transform it to follow the header (first list in names_matrix) using zip() like:

fixed_names = zip(*names_matrix[1:])

This gives value of fixed_names as:

[('Zdolfalos', 'Fred', 'Charlotte', 'NC', '28210'), ('Johnson', 'Malcom', 'Monroe', 'NC', '28337'), ('Terrell', 'Monkey', 'Broken Pine', 'SC', '28974'), ('Wilson', 'Wilson', 'Hogwart', 'VA', '27457'), ('Key', 'LeDoor', 'Spot in Road', 'AL', '36827'), ('Smith', 'Jim Bob', 'Denver', 'NC', '28037'), ('Alfonso', 'Ralph', 'Gastonia', 'NC', '28559')]

Now get the user input. No need of a for loop to get the user input:

userFirstName = raw_input('What is the user first name?')
userLastName =  raw_input('What is the user last name?')

Now iterate through fixed_names and see if userFirstName and userLastName are in them. If so output the entire row:

found = False
for row in fixed_names:
    if userLastName in row and userFirstName in row:
        found = True
        print(list(row))
        break
if not found:
    print('User Not Found!')

Demo:

>>> names_matrix = ([['lname', 'fname', 'city', 'state', 'zipcode'],
...              ['Zdolfalos', 'Johnson', 'Terrell', 'Wilson', 'Key', 'Smith',
...               'Alfonso'],
...              ['Fred', 'Malcom', 'Monkey', 'Wilson', 'LeDoor', 'Jim Bob', 'Ralph'],
...              ['Charlotte', 'Monroe', 'Broken Pine', 'Hogwart', 'Spot in Road',
...               'Denver','Gastonia'],
...              ['NC', 'NC', 'SC', 'VA', 'AL', 'NC', 'NC' ],
...              ['28210', '28337', '28974', '27457', '36827', '28037', '28559'] ])
>>> fixed_names = zip(*names_matrix[1:])
[('Zdolfalos', 'Fred', 'Charlotte', 'NC', '28210'), ('Johnson', 'Malcom', 'Monroe', 'NC', '28337'), ('Terrell', 'Monkey', 'Broken Pine', 'SC', '28974'), ('Wilson', 'Wilson', 'Hogwart', 'VA', '27457'), ('Key', 'LeDoor', 'Spot in Road', 'AL', '36827'), ('Smith', 'Jim Bob', 'Denver', 'NC', '28037'), ('Alfonso', 'Ralph', 'Gastonia', 'NC', '28559')]
>>> userFirstName = 'Fred'
>>> userLastName = 'Zdolfalos'
>>> for row in fixed_names:
...     if userLastName in row and userFirstName in row:
...         print(list(row))
...     else:
...         print('User Not Found!')
...
['Zdolfalos', 'Fred', 'Charlotte', 'NC', '28210']
shaktimaan
  • 11,962
  • 2
  • 29
  • 33
  • Okay, great answer. So is there a break that can be added that stops the extra User Not Founds. Edit. Add Break after print(list(row)) However it now prints the User Not Founds Before. We are close. Might have to change the for loop to fix that. – MeachamRob May 01 '14 at 02:24
0

Your names_matrix is a list of lists - each item in ```names_matrix`` is a list.

for thing in names_matrix:
    print thing

## ['lname', 'fname', 'city', 'state', 'zipcode']
## ['Zdolfalos', 'Johnson', 'Terrell', 'Wilson', 'Key', 'Smith', 'Alfonso']
## ['Fred', 'Malcom', 'Monkey', 'Wilson', 'LeDoor', 'Jim Bob', 'Ralph']
## ['Charlotte', 'Monroe', 'Broken Pine', 'Hogwart', 'Spot in Road', 'Denver', 'Gastonia']
## ['NC', 'NC', 'SC', 'VA', 'AL', 'NC', 'NC']
## ['28210', '28337', '28974', '27457', '36827', '28037', '28559']

```enumerate()`` is useful if you also need the index of the item:

for idx, thing in enumerate(names_matrix):
    print ' ', idx, ':', thing

##  0 : ['lname', 'fname', 'city', 'state', 'zipcode']
##  1 : ['Zdolfalos', 'Johnson', 'Terrell', 'Wilson', 'Key', 'Smith', 'Alfonso']
##  2 : ['Fred', 'Malcom', 'Monkey', 'Wilson', 'LeDoor', 'Jim Bob', 'Ralph']
##  3 : ['Charlotte', 'Monroe', 'Broken Pine', 'Hogwart', 'Spot in Road', 'Denver', 'Gastonia']
##  4 : ['NC', 'NC', 'SC', 'VA', 'AL', 'NC', 'NC']
##  5 : ['28210', '28337', '28974', '27457', '36827', '28037', '28559']

Try this for indices of each individual item in the sub-lists:

for idx, thing in enumerate(names_matrix):
    for ndx, item in enumerate(thing):
        print ' ', idx, ':', ndx, ':', item

zip() is also pretty handy, it preforms an operation similar to transposition. In the following, the asterisk before names_matrix unpacks the sub-lists.

for idx, thing in enumerate(zip(*names_matrix)):
    print ' ', idx, ':', thing[1:]

##  0 : ('Zdolfalos', 'Fred', 'Charlotte', 'NC', '28210')
##  1 : ('Johnson', 'Malcom', 'Monroe', 'NC', '28337')
##  2 : ('Terrell', 'Monkey', 'Broken Pine', 'SC', '28974')
##  3 : ('Wilson', 'Wilson', 'Hogwart', 'VA', '27457')
##  4 : ('Key', 'LeDoor', 'Spot in Road', 'AL', '36827')
wwii
  • 23,232
  • 7
  • 37
  • 77