I have a program where I use input() to take input from STDIN.
I use the input to read the first word from a line and use it as a dictionary key, with every subsequent word added to a list which is the value of the aformentioned key.
The input is in a file names.txt:
Victor Bertha Amy Diane Erika Clare
Wyatt Diane Bertha Amy Clare Erika
Xavier Bertha Erika Clare Diane Amy
Yancey Amy Diane Clare Bertha Erika
Zeus Bertha Diane Amy Erika Clare
Amy Zeus Victor Wyatt Yancey Xavier
Bertha Xavier Wyatt Yancey Victor Zeus
Clare Wyatt Xavier Yancey Zeus Victor
Diane Victor Zeus Yancey Xavier Wyatt
Erika Yancey Wyatt Zeus Xavier Victor
So for instance, men["Victor"] = ["Bertha","Amy","Diane","Erika","Clare"].
The code is in the file GS.py (an implementation of Gale-Shapley):
if __name__ == "__main__":
## Data Dictionary
''' Name : Preferences '''
men = dict()
women = dict()
''' List of unmatched men '''
freeMen = list()
''' Name : How far down in preferences '''
count = dict()
''' Name : Current Match '''
wife = dict()
husband = dict()
## Reading Input
data = input("").split("\n")
print(data)
readingMen = True
for l in data:
line = l.split()
print(line)
if len(line) > 1:
newPerson = line[0]
newPersonPreferences = list()
for i in range(1,len(line)):
newPersonPreferences.append(line[i])
if readingMen:
print("man")
print(newPersonPreferences)
men[newPerson] = newPersonPreferences
wife[newPerson] = 0
count[newPerson] = 0
freeMen.append(newPerson)
else:
print("woman")
print(newPersonPreferences)
women[newPerson] = newPersonPreferences
husband[newPerson] = 0
elif len(line) == 1:
raise IOError(l + "\nis an invalid line.")
else:
readingMen = False
## Proposing
while len(freeMen) != 0:
m = freeMen[0]
w = men[m][count[m]]
count[m] += 1
if husband[w] == 0:
husband[w] = m
wife[m] = w
freeMen.remove(m)
else:
try:
if women[w].index(husband[w], women[w].index(m)):
freeMen.append(husband[w])
wife[husband[w]] = 0
husband[w] = m
wife[m] = w
freeMen.remove(m)
except ValueError:
pass
## Match Printing
print()
for m in wife:
print(m, wife[m])
When using IDLE on Windows, I just paste the contents of this file and hit enter, and it works.
But using Ubuntu, I do python3 GS.py < names.txt and I get this:
me@glados:~$ python3 GS.py < names.txt
['Victor Bertha Amy Diane Erika Clare']
['Victor', 'Bertha', 'Amy', 'Diane', 'Erika', 'Clare']
man
['Bertha', 'Amy', 'Diane', 'Erika', 'Clare']
Traceback (most recent call last):
File "GS.py", line 83, in <module>
if husband[w] == 0:
KeyError: 'Bertha'
(edited) Now when I do cat names.txt | python3 GS.py I get this:
ajg9132@glados:~$ cat names.txt | python GS.py
Traceback (most recent call last):
File "GS.py", line 50, in <module>
data = input("").split("\n")
File "<string>", line 1
Victor Bertha Amy Diane Erika Clare
^
SyntaxError: invalid syntax
I’ve no idea what to do – kind of ignorant regarding I/O. Any help?
Edit note: I thought the two different bash commands I gave were equivalent, but then again, I’m a total noob, so an explanation for why they’re different would help too…
To clear up ambiguity, this is for an Algo homework… (sad that I understand the algorithm but not the low-level details of the OS) and I need to have a specific input and output scheme. e.g.
spock $ java GS
Victor Bertha Amy Diane Erika Clare
Wyatt Diane Bertha Amy Clare Erika
Xavier Bertha Erika Clare Diane Amy
Yancey Amy Diane Clare Bertha Erika
Zeus Bertha Diane Amy Erika Clare
Amy Zeus Victor Wyatt Yancey Xavier
Bertha Xavier Wyatt Yancey Victor Zeus
Clare Wyatt Xavier Yancey Zeus Victor
Diane Victor Zeus Yancey Xavier Wyatt
Erika Yancey Wyatt Zeus Xavier Victor
Victor Amy
Wyatt Clare
Xavier Bertha
Yancy Erika
Zeus Diane
spock $
The only reason why I wasn’t doing this was because pasting several lines of text into PuTTY made bash try to interpret each line as a command. I can’t even.
The meaning of
input()has changed.In Python 3.2: http://docs.python.org/py3k/library/functions.html#input
In Python 2.7.2: http://docs.python.org/library/functions.html#input
You can see this far easier with two small testing programs. The only difference is one uses the Python 2.7 interpreter and the other uses the Python 3.2 interpreter:
Note that even though the Python 3.2 version doesn’t throw errors, it also doesn’t print all the lines in
names.txtas one might expect.I don’t think the
input()method is worth using. Easier would use the new-fangledfor line in file:approach instead:(I removed the one blank line from the
names.txtbecause it caused this simple program to throw an error. It won’t actually be an issue in your full-fledged program, because you properly handle the blank line.)I can’t explain why
input()did work under Windows, butinput()feels like a horrible enough interface (who thought running the user-supplied input throughevalwas a good idea?!? sheesh) to just re-write it.Update
Okay, I was intrigued enough to solve this all the way. I took all your debugging code back out and switched to using the
for l in sys.stdin:approach:Note that you have to hit
^Dwhen you’re done pasting in the input if you run it this way. (I much prefer IO redirection./GS.py < names.txt, but if your professor will copy and paste, then make sure your prof knows to hit^Dto signal the end of input.)