the result printed to screen and writen to file are different - python

# coding=utf-8
def compare(arr1, arr2):
arr1 = arr1.strip()
arr2 = arr2.strip()
arr1 = arr1.split('\t')
arr2 = arr2.split('\t')
# print arr1[0], arr1[1]
arr1min = min(long(arr1[0]), long(arr1[1]))
arr1max = max(long(arr1[0]), long(arr1[1]))
arr2min = min(long(arr2[0]), long(arr2[1]))
arr2max = max(long(arr2[0]), long(arr2[1]))
# print arr1max, arr2max, arr1min, arr1min
if (arr1min < arr2min):
return -1
elif (arr1min > arr2min):
return 1
else:
if (arr1max < arr2max):
return -1
elif (arr1max > arr2max):
return 1
else:
return 0
f = open('er1000000new.txt')
fwrite = open('erzhesorted.txt', 'w')
lines = f.readlines()
lines.sort(compare)
for line in lines:
# fwrite.write(str(line))
print line
f.close()
fwrite.close()
the compare is custom sort function.
for example, when the result printed on screen, the result is
752555452697747457\t752551879448547328\t1468258301659\n
752563934733873152\t752561055289577472\t1468260508664\n
but the result printed on file is
6782762\t12\t1468248110665\n
2660899225\t12\t1468229395665\n
The two results are different, why?

The wb option when you open a file, makes python waiting for a byte object to write in that file.
Your (commented) line fwrite.write(str(line)) sends a string object.
Doesn't it produce the following error?
TypeError: a bytes-like object is required, not 'str'
Also it may come from your compare attribute in sort method.
What is it?
→ Removing the b option and removing the compare attribute produces the same outputs in term and file outputs.

Related

Naming elements of a list with `with` statement

I want to refer to an element (mem[0]) of a list (mem) with a different name (fetch):
mem = [0]
f = open("File.lx", "rb").read()
for b in f: mem += [b]
size = len(mem)
while mem[0] < size: #using mem[0]
char = (mem[0]*2)+1
source = mem[char]
target = mem[char + 1]
mem[0] += 1
mem[target] = mem[source]
And I tried that with the with statement:
mem = [0]
f = open("File.lx", "rb").read()
for b in f: mem += [b]
size = len(mem)
with mem[0] as fetch: #with statement
while fetch < size: #using mem[0] as fetch
char = (fetch*2)+1
source = mem[char]
target = mem[char + 1]
fetch += 1
mem[target] = mem[source]
But I got an error:
Traceback (most recent call last):
File "C:\documents\test.py", line 6, in <module>
with mem[0] as fetch:
AttributeError: __enter__
I thought this would be the way because that's how it's done with file objects:
with open("File.lx", "rb") as file:
fileBytes = file.read()
I read the docs for the with statement and it says that the __exit()__ and __enter()__ methods are loaded. According to what I understood after reading that and from the AttributeError, my guess is that sequence elements (mem[0]) do not have an __enter()__ method.
as the comments already mentioned, mem[0] is a literal integer, which doesn't have __enter__ and __exit__ which are required for the as keyword to work and it would be indeed simpler if you just used mem[0]
but that would be too easy, what you CAN do (as an exercise don't actually do this)
is extend the int class and add __enter__ and __exit__ like so:
class FancyInt(int):
def __enter__(self):
return self
def __exit__(self, *args):
pass
mem = [FancyInt(0)]
with mem[0] as fetch:
print(fetch)
this is neat but fetch is an alias to a LITERAL! if you change fetch, mem[0] will not change!
You seem to want a mutable object which functions as an alias for a specific location in a list. I could see some utility in that (since explicit indices are somewhat ugly in Python). You could create such a class. Here is a proof of concept, implementing the three things that you tried to do with fetch in your code:
class Fetcher:
def __init__(self,target_list, index):
self._list = target_list
self._i = index
def __iadd__(self,v):
self._list[self._i] += v
return self
def __mul__(self,v):
return self._list[self._i] * v
def __lt__(self,v):
return self._list[self._i] < v
For example,
mem = [0,1,2]
fetch = Fetcher(mem,0)
print(fetch < 2) #true
mem[0] = 1
print(fetch < 2) #still true
fetch += 1
print(fetch < 2) #false!
print(mem[0]) #2, showing that mem[0] was changed
print(fetch*2) #4 -- but 2*fetch won't work!
The last line shows that there is a limit to what you could achieve here. To make this really useful, you would want to implement many more magic methods (beyond __iadd__ etc.). Whether or not all this is useful just to avoid [0], you be the judge.

TypeError: 'str' object is not callable

This is my code:
class Parser(object):
def __init__(self, inputFile): # initalizer / constructor
#open input file and gets ready to parse it
f = open(inputFile, "r")
self.commands = list(f)
f.close()
print(self.commands)
self.currentCommand = 0
self.index = 0
def hasMoreCommands(self):
#are there any more commands in the input
#returns boolean
if (self.commands[self.currentCommand][self.index] == "\\") and (self.commands[self.currentCommand][self.index+1] == "n"): # checks for "/n", alluding that the command has ended and we can advance to the next command
return True
else:
return False
def advance(self):
#reads next command and makes it current command
#called only if hasMoreCommands is true
if self.hasMoreCommands():
self.currentCommand += 1
def commandType(self):
#returns type of current command A_COMMAND, C_COMMAND, L_COMMAND
#C A or L(psuedo command for (XxX))
#dest=comp; jmp, #, ()
self.type = self.commands[self.currentCommand][0]
if self.type == "#":
return "A_COMMAND"
elif self.type == "(":
return "L_COMMAND"
else:
return "C_COMMAND"
def dest(self):
#returns dest mnemoic of current C instruction - 8 Poss
#called when command type is C
#return string
if (self.commandType() == "C_COMMAND") and ("=" in self.commands[self.currentCommand]):
return self.commands[self.currentCommand][0:(self.commands[self.currentCommand].index("="))]
def main(inputFile):
d = Parser(inputFile)
d.commandType = "C_COMMAND"
d.commands = ["D=A+2\\n", "AMD=A+5\\n"]
d.currentCommand = 0
print(d.dest())
main("/Users/user1/Desktop/filelocation/projects/06/add/add.asm")
The file in question:
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/06/add/Add.asm
// Computes R0 = 2 + 3
#2
D=A
#3
D=D+A
#0
M=D
Error returned:
['// This file is part of www.nand2tetris.org\n', '// and the book "The Elements of Computing Systems"\n', '// by Nisan and Schocken, MIT Press.\n', '// File name: projects/06/add/Add.asm\n', '\n', '// Computes R0 = 2 + 3\n', '\n', '#2\n', 'D=A\n', '#3\n', 'D=D+A\n', '#0\n', 'M=D\n']
Traceback (most recent call last):
File "/Users/user1/Desktop/Python/filelocation/assembler.py", line 104, in <module>
main("/Users/user1Desktop/filelocation/projects/06/add/add.asm")
File "/Users/user1/Desktop/Python/filelocation/assembler.py", line 99, in main
print(d.dest())
File "/Users/user1/Desktop/Python/filelocation/assembler.py", line 50, in dest
if (self.commandType() == "C_COMMAND") and ("=" in self.commands[self.currentCommand]):
TypeError: 'str' object is not callable
[Finished in 0.1s with exit code 1]
I was attempting to test dest.
This is a part of the Nand 2 Tetris / Elements of Computing Systems curriculum at Chapter 6.
In your main, you are replacing the method def commandType(self) with d.commandType = "C_COMMAND", which is a str and therefore cannot be called like a method.
For your class....
class Parser(object):
def __init__(self, inputFile): # initalizer / constructor
#open input file and gets ready to parse it
f = open(inputFile, "r")
self.commands = list(f)
f.close()
You already set self.commands from the file
And note: index and currentCommand appear to serve the exact same purpose
Your function uses that list.
def commandType(self):
#returns type of current command A_COMMAND, C_COMMAND, L_COMMAND
#C A or L(psuedo command for (XxX))
#dest=comp; jmp, #, ()
self.type = self.commands[self.currentCommand][0]
Therefore, you do not need these lines
def main(inputFile):
d = Parser(inputFile)
# d.commandType = "C_COMMAND"
# d.commands = ["D=A+2\\n", "AMD=A+5\\n"]
# d.currentCommand = 0
So you only need this main assuming the input file is correct.
def main(inputFile):
d = Parser(inputFile)
print(d.dest())
Your error is that d.commandType = "C_COMMAND" cannot be "called" by "C_COMMAND()", (i.e. d.commandType())

Binary search coming to error in tkinter gui python 2.7

This code is appearing to give me an error to my arguments i don't know what i have done wrong in this code. When attempting to run a binary search inside tkinter using python 2.7 The programs works fine if i don't use the gui just line code. This is the code I have based my program on
http://www.pythonschool.net/data-structures-algorithms/binary-search/
The error is: Exception in Tkinter callback Traceback (most recent call last): File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in call return self.func(*args) TypeError: binarySearch() takes exactly 2 arguments (0 given)
from Tkinter import *
import csv
with open('scoresRecord.csv', 'rb') as f:
reader = csv.reader(f)
your_list = list(reader)
root = Tk()
root.resizable(0,0)
root.title("Score Board")
def binarySearch(myitem,myList):
found = False
bottom = 0
top = len(myList)-1
while bottom<=top and not found:
middle = (bottom+top)//2
if myList[middle]== myitem:
found = True
elif myList[middle] < myitem:
bottom = middle + 1
else:
top = middle-1
return found
if __name__=="__main__":
Scorelist = [row[0] for row in your_list]
Dismissallist =[row[1] for row in your_list] # create a list of only the dismissal
Venuelist =[row[2] for row in your_list] # create a list of only the venue
item = int(input(entScore.get()))
Scorelist = map(int, Scorelist)
rowPos = Scorelist.index(item)
isitFound = binarySearch(item,Scorelist)
if isitFound:
Score= Scorelist[rowPos]
Dismissal= Dismissallist[rowPos]
Venue= Venuelist[rowPos]
else:
Score= ("Not Found")
Dismissal= ("Not Found")
Venue= ("Not Found")
numScoreLbl.configure(text=Score)
numDismissal.configure(text=Dismissal)
outVenue.configure(text=Venue)
#==========GUI Section==================#
First of all, make sure your list is ordered, otherwise the results may be wrong.
Second, do this
Scorelist = list(map(int, Scorelist))#convert to list
isitFound = binarySearch(item,Scorelist)
Although, if you are using .index method, then you can do something like this for better performance:
try:
index = Scorelist.index(item)
isitFound = True
except ValueError:
isitFound = False
It takes out the binary search part, but you were using .index anyways. So this is better. Hope it helps :)

Python ValueError: chr() arg not in range(256)

So I am learning python and redoing some old projects. This project involves taking in a dictionary and a message to be translated from the command line, and translating the message. (For example: "btw, hello how r u" would be translated to "by the way, hello how are you".
We are using a scanner supplied by the professor to read in tokens and strings. If necessary I can post it here too. Heres my error:
Nathans-Air-4:py1 Nathan$ python translate.py test.xlt test.msg
Traceback (most recent call last):
File "translate.py", line 26, in <module>
main()
File "translate.py", line 13, in main
dictionary,count = makeDictionary(commandDict)
File "/Users/Nathan/cs150/extra/py1/support.py", line 12, in makeDictionary
string = s.readstring()
File "/Users/Nathan/cs150/extra/py1/scanner.py", line 105, in readstring
return self._getString()
File "/Users/Nathan/cs150/extra/py1/scanner.py", line 251, in _getString
if (delimiter == chr(0x2018)):
ValueError: chr() arg not in range(256)
Heres my main translate.py file:
from support import *
from scanner import *
import sys
def main():
arguments = len(sys.argv)
if arguments != 3:
print'Need two arguments!\n'
exit(1)
commandDict = sys.argv[1]
commandMessage = sys.argv[2]
dictionary,count = makeDictionary(commandDict)
message,messageCount = makeMessage(commandMessage)
print(dictionary)
print(message)
i = 0
while count < messageCount:
translation = translate(message[i],dictionary,messageCount)
print(translation)
count = count + 1
i = i +1
main()
And here is my support.py file I am using...
from scanner import *
def makeDictionary(filename):
fp = open(filename,"r")
s = Scanner(filename)
lyst = []
token = s.readtoken()
count = 0
while (token != ""):
lyst.append(token)
string = s.readstring()
count = count+1
lyst.append(string)
token = s.readtoken()
return lyst,count
def translate(word,dictionary,count):
i = 0
while i != count:
if word == dictionary[i]:
return dictionary[i+1]
i = i+1
else:
return word
i = i+1
return 0
def makeMessage(filename):
fp = open(filename,"r")
s = Scanner(filename)
lyst2 = []
string = s.readtoken()
count = 0
while (string != ""):
lyst2.append(string)
string = s.readtoken()
count = count + 1
return lyst2,count
Does anyone know whats going on here? I've looked through several times and i dont know why readString is throwing this error... Its probably something stupid i missed
chr(0x2018) will work if you use Python 3.
You have code that's written for Python 3 but you run it with Python 2. In Python 2 chr will give you a one character string in the ASCII range. This is an 8-bit string, so the maximum parameter value for chris 255. In Python 3 you'll get a unicode character and unicode code points can go up to much higher values.
The issue is that the character you're converting using chr isn't within the range accepted (range(256)). The value 0x2018 in decimal is 8216.
Check out unichr, and also see chr.

Error always on line 102 of my code

So I am creating a module, and I am importing it to a python shell and running some stuff to make sure all features work and such.
For some reason every time I run the code, it gives the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/ryansaxe/Desktop/Code/python/modules/pymaps.py", line 102, in url_maker
#anything can be here
AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
So where the #anything can be here is, is whatever is on line 102 of my code. Originally line 102 was:
if isinstance(startindex,datetime.datetime):
and I got the error above. I put a quick print statement on line 102 to check and it gave the same error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/ryansaxe/Desktop/Code/python/modules/pymaps.py", line 102, in url_maker
print 'Hello'
AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Is this some sort of bug? Why is it telling me there is an error with datetime on the line print 'Hello'?
Because it may be helpful, I will give you the function I am having trouble with since I have no clue how this is possible. I am keeping the print 'Hello' line so you can see where line 102 is:
def url_maker(latitudes,longitudes,times=None,color='red',label=' ',zoom=12,center=None,start=None,end=None,by=None,size='600x300'):
urls = []
import datetime
if isinstance(times[0],str) or isinstance(times[0],datetime.datetime):
from dateutil import parser
if isinstance(times[0],str):
times = [parser.parse(x) for x in times]
if isinstance(start,str):
startindex = parser.parse(start)
else:
startindex = start
if isinstance(end,str):
endindex = parse.parse(end)
else:
endindex = end
print 'Hello'
if isinstance(startindex,datetime.datetime):
startpos = between_times(times,startindex,by='start')
elif isinstance(startindex,int):
if isinstance(endindex,datetime.datetime):
startpos = between_times(times,endindex,by='end') - start
else:
startpos = start
else:
pass
if isinstance(endindex,datetime.datetime):
endpos = between_times(times,endindex,by='end')
elif isinstance(endindex,int):
if isinstance(startindex,datetime.datetime):
endpos = between_times(times,startindex,by='start') + end
else:
endpos = end
else:
pass
else:
times = range(1,len(latitudes) + 1)
if isinstance(start,int):
startpos = start
else:
startpos = None
if isinstance(end,int):
endpos = end
else:
endpos = None
if isinstance(by,str):
lat,lon,t = latitudes[startpos:endpos],latitudes[startpos:endpos],times[startpos:endpos]
print lat
t,lats,lons = time_sample(t,by,lat,lon)
elif isinstance(by,int):
lats,lons,t = latitudes[startpos:endpos:by],latitudes[startpos:endpos:by],times[startpos:endpos:by]
else:
lats,lons,t= latitudes[startpos:endpos],latitudes[startpos:endpos],times[startpos:endpos]
print t
print len(t)
if center == None:
latit = [str(i) for i in lats]
longi = [str(i) for i in lons]
center = '&center=' + common_finder(latit,longi)
else:
center = '&center=' + '+'.join(center.split())
zoom = '&zoom=' + str(zoom)
for i in range(len(lats)):
#label = str(i)
x,y = str(lats[i]),str(lons[i])
marker = '&markers=color:' + color + '%7Clabel:' + label + '%7C' + x + ',' + y
url = 'http://maps.googleapis.com/maps/api/staticmap?maptype=roadmap&size=' + size + zoom + center + marker + '&sensor=true'
urls.append(url)
#print i
return urls,t
You are running with a stale bytecode cache or are re-running the code in an existing interpreter without restarting it.
The traceback code has only bytecode to work with, which contains filename and linenumber information. When an exception occurs, the source file is loaded to retrieve the original line of code, but if the source file has changed, that leads to the wrong line being shown.
Restart the interpreter and/or remove all *.pyc files; the latter will be recreated when the interpreter imports the code again.
As for your specific exception; you probably imported the datetime class from the datetime module somewhere:
from datetime import datetime
The datetime class does not have a datetime attribute, only the module does.

Categories

Resources