ValueError: not enough values to pack (expected 2, got 1) syntax error - python-2.x

Hello I am taking an example from learn python the hard way and working to understand python. I have already caught one error in the book and realized you need () to print out strings. So maybe there could be some more mistakes in the syntax. when I ran this file I received an error that said
ValueError: not enough values to pack (expected 2, got 1) syntax error. And another general syntax error. So I can't set prompt to raw_input.
rom sys import argv
script, user_name = argv
prompt = '>'
print ("Hi %s, I'm the $s script.") % user_name, script
print ("I'd like to ask you a few questions.")
print ("Do you like %s?") % user_name
likes = raw_input(prompt)
print ("Where do you live %s") % user_name
lives = raw_input(prompt)
print """
(Alright, so you said %r about liking me.
You live in %r. Not sure where that is.
And you have a %r computer. Nice)
"""& (likes, lives, computer)

Is there a typo in the code example? $s instead of %s in the format string?
I suspect that your actual code has this:
print ("Hi %s, I'm the %s script.") % user_name, script
And you meant to write this:
print "Hi %s, I'm the %s script." % (user_name, script)
That is, print a single string which is the result of applying the format string to two arguments.

Related

How to import defined variable from raw_input in an imported file?

I am fairly new to coding, and am currently learning my first language (python) using the book "Learn Python the Hard Way" but this is not a specific exercise in the book and I am just practicing while I am reading code for Exercise 23 and am currently am just trying to figure out if this is even possible...
My first file is pr1.py:
def func():
a = float(raw_input("Enter Your Age:"))
b = float(raw_input("Enter Your Weight:"))
c = float(raw_input("Enter Your Height:"))
age = "a"
weight = "b"
height = "c"
if __name__ == "__main__":
print("This is pr1.py")
else:
print("%s is being imported to another file") % __name__
My second file is pr2.py
import pr1
def func():
x = raw_input("Enter Your Race:")
y = raw_input("Enter Your Gender:")
z = raw_input("Enter Your Language:")
print "Lets find your numbers"
pr1.func()
print "Lets find your identity"
func()
race = "x"
gender = "y"
language = "z"
if __name__ == "__main__":
print("This is pr2.py")
else:
print("%s is being imported into another file") % __name__
This is my 3rd file pr3.py
import pr1
print "%s = a %s = b %s = c" % (age, weight, height)
import pr2
print "%s = x, %s = y, %s = z" % (race, gender, language)
When I run pr3.py and comment out the scripts to "print" line 3 and line 7 this is what i get:
python pr3.py
pr1 is being imported to another file
Lets find your numbers
Enter Your Age:25
Enter Your Weight:224
Enter Your Height:76
Lets find your identity
Enter Your Race:white
Enter Your Gender:male
Enter Your Language:english
pr2 is being imported into another file
and I am expecting the pr3.py file to print those statement's with the previously defined variable's.
but instead it comes up with this error:
pr1 is being imported to another file
Traceback (most recent call last):
File "pr3.py", line 3, in <module>
print "%s = a %s = b %s = c" % (age, weight, height)
NameError: name 'age' is not defined
Now when I run my last file in the command, I am expecting it to import the previous 2 files, so I can input the data I put into raw_input, and then use use it in other files... but it seems like once both files get imported and I input the data into their respective raw_input's, it seems as if the pr3.py forget's the raw input and their corresponding variable's.
Please forgive me if I am totally lacking some obvious knowledge that could fix all this, but I am very new to coding and not even a month ago, I didn't even know you could create a directory in the terminal.
Thank's for reading and I would appreciate any help.
Okey, here are a couple of things.
First I will say which obvious things are wrong with your code.
After that I will show you an example of your code, using classes.
So, first:
age, weight, height are all defined in pr1.py, so eiter you need to refer to them as pr1.age, pr1.weight, pr1.height, or you from pr1 import age, weight, height. Same applies for race, gender, language in pr2.py
That said, you might expect to get what you inputted to be printed out. But you only assigned the characters 'a', 'b', 'c', 'x', 'y' and 'z' to those variables.
Also you print age, weight and height before you even run func() in pr2.py
So second: how do we fix this. First you need to think about in which order things are happening, when you do imports. Also you need to think about, if the variables you refer to, really are set anywhere.
In this case you set your raw_input's to variables insde a function, and they will only be accessible inside that function.
This can be fixed by using globals, or by making an object. I will reccommend using object (classes).
Since you say you are fairly new to programming, classes might seem over your head now, but when you get it, it solves alot of these problems.
Also you will get to classes soon enough in Learn Python The Hard Way soon enough.
To take your code as example:
pr1.py:
class Numbers:
def func(self):
self.age = float(raw_input("Enter Your Age:"))
self.weight = float(raw_input("Enter Your Weight:"))
self.height = float(raw_input("Enter Your Height:"))
if __name__ == "__main__":
print("This is pr1.py")
else:
print("%s is being imported to another file") % __name__
pr2.py:
from pr1 import Numbers
class Identity:
def func(self):
self.race = raw_input("Enter Your Race:")
self.gender = raw_input("Enter Your Gender:")
self.language = raw_input("Enter Your Language:")
print "Lets find your numbers"
nrs = Numbers()
nrs.func()
print "Lets find your identity"
ids = Identity()
ids.func()
if __name__ == "__main__":
print("This is pr2.py")
else:
print("%s is being imported into another file") % __name__
pr3.py:
from pr2 import *
print "%s = a %s = b %s = c" % (nrs.age, nrs.weight, nrs.height)
print "%s = x, %s = y, %s = z" % (ids.race, ids.gender, ids.language)

Parsing CSV file with \n in double quoted fields

I'm parsing a CSV file that has a break line in double quoted fields. I'm reading the file line by line with a groovy script but I get an ArrayIndexOutBoundException when I tried to get access the missing tokens.
I was trying to pre-process the file to remove those characters and I was thinking to do that with some bash script or with groovy itself.
Could you, please suggest any approach that I can use to resolve the problem?
This is how the CSV looks like:
header1,header2,header3,header4
timestamp, "abcdefghi", "abcdefghi","sdsd"
timestamp, "zxcvb
fffffgfg","asdasdasadsd","sdsdsd"
This is the groovy script I'm using
def csv = new File(args[0]).text
def bufferString = ""
def parsedFile = new File("Parsed_" + args[0]);
csv.eachLine { line, lineNumber ->
def splittedLine = line.split(',');
retString += new Date(splittedLine[0]) + ",${splittedLine[1]},${splittedLine[2]},${splittedLine[3]}\n";
if(lineNumber % 1000 == 0){
parsedFile.append(retString);
retString = "";
}
}
parsedFile.append(retString);
UPDATE:
Finally I did this and it works, (I needed format the first column from timestamp to a human readable date):
gawk -F',' '{print strftime("%Y-%m-%d %H:%M:%S", substr( $1, 0, length($1)-3 ) )","($2)","($3)","($4)}' TobeParsed.csv > Parsed.csv
Thank you #karakfa
If you use a proper CSV parser rather than trying to do it with split (which as you can see doesn't work with any form of quoting), then it works fine:
#Grab('com.xlson.groovycsv:groovycsv:1.1')
import static com.xlson.groovycsv.CsvParser.parseCsv
def csv = '''header1,header2,header3,header4
timestamp, "abcdefghi", "abcdefghi","sdsd"
timestamp, "zxcvb
fffffgfg","asdasdasadsd","sdsdsd"'''
def data = parseCsv(csv)
data.eachWithIndex { line, index ->
println """Line $index:
| 1:$line.header1
| 2:$line.header2
| 3:$line.header3
| 4:$line.header4""".stripMargin()
}
Which prints:
Line 0:
1:timestamp
2:abcdefghi
3:abcdefghi
4:sdsd
Line 1:
1:timestamp
2:zxcvb
fffffgfg
3:asdasdasadsd
4:sdsdsd
awk to the rescue!
this will merge the newline split fields together, you process can take it from there
$ awk -F'"' '!(NF%2){getline remainder;$0=$0 OFS remainder}1' splitted.csv
header1,header2,header3
xxxxxx, "abcdefghi", "abcdefghi"
yyyyyy, "zxcvb fffffgfg","asdasdasadsd"
assumes that odd number of quotes mean split field and replace new line with OFS. If you want to simple delete new line (the split parts will combine) remove OFS.

Why did the order of my script give a Divide by Zero error?

I'm working on some beginner Python exercises. I have the following, working code:
# Use the file name mbox-short.txt as the file name
fname = raw_input("Enter file name: ")
fh = open(fname)
inp=fh.readlines()
count=0
total=0.0
for line in inp:
line=line.rstrip()
if not line.startswith("X-DSPAM-Confidence:"):
continue
value=line[19:]
value=float(value)
count=count+1
total=total + value
print "Average spam confidence:",total/count
When I first wrote this, I put the "count" line before the "value" line like this:
# Use the file name mbox-short.txt as the file name
fname = raw_input("Enter file name: ")
fh = open(fname)
inp=fh.readlines()
count=0
total=0.0
for line in inp:
line=line.rstrip()
if not line.startswith("X-DSPAM-Confidence:"):
continue
count=count+1
value=line[19:]
value=float(value)
total=total + value
print "Average spam confidence:",total/count
This resulted in a divide by zero error. Why?

Moving chunks of data in a file with awk

I'm moving my bookmarks from kippt.com to pinboard.in.
I exported my bookmarks from Kippt and for some reason, they were storing tags (preceded by #) and description within the same field. Pinboard keeps tags and description separated.
This is what a Kippt bookmark looks like after export:
<DT>This is a title
<DD>#tag1 #tag2 This is a description
This is what it should look like before importing into Pinboard:
<DT>This is a title
<DD>This is a description
So basically, I need to replace #tag1 #tag2 by TAGS="tag1,tag2" and move it on the first line within <A>.
I've been reading about moving chunks of data here: sed or awk to move one chunk of text betwen first pattern pair into second pair?
I haven't been to come up with a good recipe so far. Any insight?
Edit:
Here's an actual example of what the input file looks like (3 entries out of 3500):
<DT>Phabricator
<DD>#bug #tracking
<DT>The hidden commands for diagnosing and improving your Netflix streaming quality – Quartz
<DT>Icelandic Farm Holidays | Local experts in Iceland vacations
<DD>#iceland #tour #car #drive #self Self-driving tour of Iceland
This might not be the most beautiful solution, but since it seems to be a one-time-thing it should be sufficient.
import re
dt = re.compile('^<DT>')
dd = re.compile('^<DD>')
with open('bookmarks.xml', 'r') as f:
for line in f:
if re.match(dt, line):
current_dt = line.strip()
elif re.match(dd, line):
current_dd = line
tags = [w for w in line[4:].split(' ') if w.startswith('#')]
current_dt = re.sub('(<A[^>]+)>', '\\1 TAGS="' + ','.join([t[1:] for t in tags]) + '">', current_dt)
for t in tags:
current_dd = current_dd.replace(t + ' ', '')
if current_dd.strip() == '<DD>':
current_dd = ""
else:
print current_dt
print current_dd
current_dt = ""
current_dd = ""
print current_dt
print current_dd
If some parts of the code are not clear, just tell me. You can of course use python to write the lines to a file instead of printing them, or even modify the original file.
Edit: Added if-clause so that empty <DD> lines won't show up in the result.
script.awk
BEGIN{FS="#"}
/^<DT>/{
if(d==1) print "<DT>"s # for printing lines with no tags
s=substr($0,5);tags="" # Copying the line after "<DT>". You'll know why
d=1
}
/^<DD>/{
d=0
m=match(s,/>/) # Find the end of the HREF descritor first match of ">"
for(i=2;i<=NF;i++){sub(/ $/,"",$i);tags=tags","$i} # Concatenate tags
td=match(tags,/ /) # Parse for tag description (marked by a preceding space).
if(td==0){ # No description exists
tags=substr(tags,2)
tagdes=""
}
else{ # Description exists
tagdes=substr(tags,td)
tags=substr(tags,2,td-2)
}
print "<DT>" substr(s,1,m-1) ", TAGS=\"" tags "\"" substr(s,m)
print "<DD>" tagdes
}
awk -f script.awk kippt > pinboard
INPUT
<DT>Phabricator
<DD>#bug #tracking
<DT>The hidden commands for diagnosing and improving your Netflix streaming quality – Quartz
<DT>Icelandic Farm Holidays | Local experts in Iceland vacations
<DD>#iceland #tour #car #drive #self Self-driving tour of Iceland
OUTPUT:
<DT>Phabricator
<DD>
<DT>The hidden commands for diagnosing and improving your Netflix streaming quality – Quartz
<DT>Icelandic Farm Holidays | Local experts in Iceland vacations
<DD> Self-driving tour of Iceland

mysterious "'str' object is not callable" python error

I am currently making my first python effort, a modification of some code written by a friend. I am using python 2.6.6. The original piece of code, which works, extracts information from a log file of data from donations made by credit card to my nonprofit. My new version, should it one day work, will perform the same task for donations that were made by paypal. The log files are similar, but have different field names and other differences.
The error messages I'm getting are:
Traceback (most recent call last):
File "../logparse-paypal-1.py", line 196, in
convert_log(sys.argv[1], sys.argv[2], access_ids)
File "../logparse-paypal-1.py", line 170, in convert_log
output = [f(record, access_ids) for f in output_fns]
TypeError: 'str' object is not callable
I've read some of the posts on this forum related to this error message, but so far I'm still at sea. I can't find any consequential differences between the portions of my code that related to the likely problem object (access_ids) and the code that I started with. All I did related to the access_ids table was to remove some lines that printed problems the script finds with the table that caused it to ignore some data. Perhaps I changed a character or something while doing that, but I've looked and so far can't find anything.
The portion of the code that is producing these error messages is the following:
# Use the output functions configured above to convert the
# transaction record into a list of outputs to be emitted to
# the CSV output file.
print "Converting %s at %s to CSV" % (record["type"], record["time"])
output = [f(record, access_ids) for f in output_fns]
j = 0
while j < len(output):
os.write(csv_fd, output[j])
if j < len(output) - 1:
os.write(csv_fd, ",")
else:
os.write(csv_fd, "\n")
j += 1
convert_count += 1
print "Converted %d approved transactions to CSV format, skipped %d non-approved transactions" % (convert_count, skip_count)
if __name__ == '__main__':
if len(sys.argv) < 3:
print "Usage: logparse.py INPUT_FILE OUTPUT_FILE [ACCESS_IDS_FILE]"
print
print " INPUT_FILE Silent post log containing transaction records (must exist)"
print " OUTPUT_FILE Filename for the CSV file to be created (must not exist, will be created)"
print " ACCESS_IDS_FILE List of Access IDs and email addresses (optional, must exist if specified)"
sys.exit(-1)
access_ids = {}
if len(sys.argv) > 3:
access_ids = load_access_ids(sys.argv[3])
convert_log(sys.argv[1], sys.argv[2], access_ids)
Line 170 is this one:
output = [f(record, access_ids) for f in output_fns]
and line 196 is this one:
convert_log(sys.argv[1], sys.argv[2], access_ids)
The access_ids definition, possibly related to the problem, is this:
def access_id_fn(record, access_ids):
if "payer_email" in record and len(record["payer_email"]) > 0:
if record["payer_email"] in access_ids:
return '"' + access_ids[record["payer_email"]] + '"'
else:
return ""
else:
return ""
AND
def load_access_ids(filename):
print "Loading Access IDs from %s..." % filename
access_ids = {}
for line in open(filename, "r"):
line = line.rstrip()
access_id, email = [s.strip() for s in line.split(None, 1)]
if not email_address.match(email):
continue
if email in access_ids:
access_ids[string.strip(email)] = string.strip(access_id)
return access_ids
Thanks in advance for any advice with this.
Dave
I'm not seeing anything right off hand, but you did mention that the log files were similar and I take that to mean that there are differences between the two.
Can you post a line from each?
I would double check the data in the log files and make sure what you think is being read in is correct. This definitely appears to me like a piece of data is being read in, but somewhere it is breaking what the code is expecting.

Resources