local variable 'moodsc' referenced before assignment - python

In the code below I get the following error:
"local variable 'moodsc' referenced before assignment"
I'm new to programming and python. I'm struggling with interpreting other questions on the similar topic. Any context around this specific code would be helpful.
import re
import json
import sys
def moodScore(sent, myTweets):
scores = {} # initialize an empty dictionary
new_mdsc = {} # intitalize an empty dictionary
txt = {}
for line in sent:
term, score = line.split("\t") # The file is tab-delimited. "\t" means "tab character"
scores[term] = int(score) # Convert the score to an integer.
data = [] # initialize an empty list
for line in myTweets:
tweet = json.loads(line)
if "text" in tweet and "lang" in tweet and tweet["lang"] == "en":
clean = re.compile("\W+")
clean_txt = clean.sub(" ", tweet["text"]).strip()
line = clean_txt.lower().split()
moodsc = 0
pos = 0
neg = 0
count = 1
for word in range(0, len(line)):
if line[word] in scores:
txt[word] = int(scores[line[word]])
else:
txt[word] = int(0)
moodsc += txt[word]
print txt
if any(v > 0 for v in txt.values()):
pos = 1
if any(v < 0 for v in txt.values()):
neg = 1
for word in range(0, len(line)): # score each word in line
if line[word] not in scores:
if str(line[word]) in new_mdsc.keys():
moodsc2 = new_mdsc[str(line[word])][0] + moodsc
pos2 = new_mdsc[str(line[word])][1] + pos
neg2 = new_mdsc[str(line[word])][2] + neg
count2 = new_mdsc[str(line[word])][3] + count
new_mdsc[str(line[word])] = [moodsc2, pos2, neg2, count2]
else:
new_mdsc[str(line[word])] = [moodsc, pos, neg, count]
def new_dict():
for val in new_mdsc.values():
comp = val[0] / val[3]
val.append(comp)
for key, val in new_mdsc.items():
print (key, val[4])
def main():
sent_file = open(sys.argv[1])
tweet_file = open(sys.argv[2])
moodScore(sent_file, tweet_file)
# new_dict()
if __name__ == '__main__':
main()

Ok #joshp, I think you need to globalise some variables, because the error is 'moodsc referenced before assignment', I think the code only gets as far as moodsc += txt[word] but you may also have trouble with pos and neg.
Try global moodsc and pos etc. before you define moodsc and pos etc. If this doesn't work try global moodsc before moodsc += txt[word] and so forth, you may need to use global in both places for it to work, I often find that this is needed in my code, to globalise it at definition and wherever else you use it (at the start of each function and statement where it is used).

Related

Having problem running python code (Markov Chain project)

I just got into python a few weeks ago and I've been learning the language using the PyCharm software.
I was hoping to use the following code for a project:
https://github.com/eohomegrownapps/markov-music
I installed the required library, and inserted a midi file in the mentioned folder (the input folder). I'm using the following midi file:
http://www.bachcentral.com/invent/invent1.mid
Once I run the code, nothing appears in the 'compositions' folder. Can anyone tell me what I'm doing wrong? I'll post a screenshot of the code below.
Thanks a million in advance
Updated Screenshot
import random
import midi
import datetime
class Markov(object):
"""docstring for Markov"""
def __init__(self, order=2):
super(Markov, self).__init__()
self.order = order
self.chain = {}
def add(self, key, value):
if self.chain.has_key(key):
self.chain[key].append(value)
else:
self.chain[key] = [value]
def load(self, midifile):
pattern = midi.read_midifile(midifile)
# track = pattern[1]
for track in pattern:
noteslist = []
curoffset = 0
for i in track:
if i.name == "Note On" and i.data[1] != 0:
note = (i.data[0], i.data[1], i.tick + curoffset)
# note = (i.data[0],i.data[1],i.tick)
noteslist.append(note)
curoffset = 0
else:
curoffset += i.tick
if len(noteslist) > self.order:
for j in range(self.order, len(noteslist)):
t = tuple(noteslist[j - self.order:j])
print t
print noteslist[j]
self.add(t, noteslist[j])
else:
print "Corpus too short"
def generate(self, length, filename):
pattern = midi.Pattern()
# Instantiate a MIDI Track (contains a list of MIDI events)
track = midi.Track()
# Append the track to the pattern
pattern.append(track)
tick = 0
currenttuple = random.choice(self.chain.keys())
prevnote = False
for i in range(0, self.order):
if prevnote != False:
on = midi.NoteOnEvent(tick=tick, velocity=0, pitch=prevnote)
track.append(on)
on = midi.NoteOnEvent(tick=0, velocity=currenttuple[i][1], pitch=currenttuple[i][0])
track.append(on)
tick = currenttuple[i][2]
prevnote = currenttuple[i][0]
result = random.choice(self.chain[currenttuple])
# print currenttuple
for i in range(1, length):
for j in range(0, self.order):
if prevnote != False:
if tick > 5000:
tick = 5000
on = midi.NoteOnEvent(tick=tick, velocity=0, pitch=prevnote)
track.append(on)
on = midi.NoteOnEvent(tick=0, velocity=currenttuple[j][1], pitch=currenttuple[j][0])
track.append(on)
tick = currenttuple[j][2]
prevnote = currenttuple[j][0]
currenttuple = list(currenttuple)
currenttuple.pop(0)
currenttuple.append(result)
currenttuple = tuple(currenttuple)
if self.chain.has_key(currenttuple):
result = random.choice(self.chain[currenttuple])
else:
result = random.choice(self.chain[random.choice(self.chain.keys())])
# Add the end of track event, append it to the track
eot = midi.EndOfTrackEvent(tick=1)
track.append(eot)
# Print out the pattern
print pattern
# Save the pattern to disk
midi.write_midifile(filename + ".mid", pattern)
if __name__ == '__main__':
directory = "compositions"
musicdir = "input"
musicdir += "/"
logname = directory + "/" + "{:%Y-%m-%d-%H:%M:%S}_genmusic".format(datetime.datetime.now())
m = Markov(3)
print "Loading music"
inp = raw_input('Name of midi file to load or g to generate: ')
while inp != "g":
try:
m.load(musicdir + inp)
except Exception as e:
print "File not found or corrupt"
inp = raw_input('Name of midi file to load or g to generate: ')
print "Done"
print m.chain
m.generate(1000, logname)

Search Strings in a List with Loop Return Order

I'm very new to Python and I have a question.
I have a List that looks like this:
List = ["B-Guild","I-Guild","I-Guild","L-Guild","B-Gene","L-Gene","U-Car"]
All of the words with B-(I)-L belong to each other and I want to use a function to show that.
def combine(x):
foo = []
regexp_B = ("B-" + r'.*')
regexp_I = ("I-" + r'.*')
regexp_L = ("L-" + r'.*')
regexp_U = ("U-" + r'.*')
for i in range(0,len(x),1):
if re.match(regexp_B, x[i]):
print("Found B")
foo.append[i+x[i]]
if re.match(regexp_I, x[i+1]):
print("Found I")
foo.append[i+1+x[i+1]]
if re.match(regexp_I, x[i+1]):
print("Found I")
foo.append[i+1+x[i+1]]
else:
print("Found L")
foo.append[i+1+x[i+1]]
else:
print("Found L")
foo.append[i1+x[i1]]
elif re.match(regexp_L, x[i]):
print("L")
foo.append[i1+x[i1]]
elif re.match(regexp_U, x[i]):
print("Found U")
foo.append[i1+x[i1]]
return foo
List_New = combine(List)
Desired Output:
foo = ["0B-Guild","0I-Guild","0I-Guild","OL-Guild","1B-Gene","1L-Gene","2U-Car"]
Edit:
The output follows this logic: Every time a "B-" prefix appears, the words to follow are part of one "theme" until a "L-" prefix appears. These words got to have the same number before them so they can be grouped for further functions. "U-" prefixes don't follow that logic and just need a number before them to distinguish them from the other words. Think of it as a Counter that groups these word into a cluster.
def combine(some_list):
current_group = 0 # starts with 0
g_size = 0 # current group size
for elem in some_list:
g_size += 1
if elem.startswith('U-') and g_size > 1:
g_size = 1
current_group += 1
yield '{}{}'.format(current_group, elem)
if elem.startswith(('L-', 'U-')): # each L- or U- also finishes a group
g_size = 0
current_group += 1
>>> List = ["B-Guild","I-Guild","I-Guild","L-Guild","B-Gene","L-Gene","U-Car"]
>>> print(list(combine(List)))
>>> List = ["B-Guild","I-Guild","I-Guild","L-Guild","B-Guild","L-Guild","U-Guild"]
>>> print(list(combine(List)))

trying to compare two lists or one list with the same

import random
b=[]
o=[]
v=0
g=2
y=0
V=0
q=0
compat=0
alex=[]
zach=[]
while v != 5:
name="name"
position="position"
answers=[]
for i in range(10):
answer=random.randint(1,4)
answers.append(answer)
b.append(name)
b.append(position)
b.append(answers)
v+=1
print(b)
for ii in range(0,5):
t=b[g]
o.append(t)
g+=3
l=len(o)
for iii in list(o):
C = o[y]
y = y + 1
alex = []
for iiii in range(5):
I = 0
compat=0
R=o[q]
V=0
Y = C[V]
for iiiii in range(10):
r=R[I]
if r == Y:
compat+=1
else:
compat=compat
I+=1
V += 1
print(compat)
alex.append(compat)
print(alex)
zach.append(alex)
q+=1
w=len(zach)
print(zach)
print(w)
this is my code and it works pretty well. but it should put every single value against every other one but it doesnt it just put the same Y value and does not change. i have put v+=1 in tons of different places and moved around the a couple variable but it doesnt change. there should be 25 different answers for 5 people but it doesnt it just prints the same number 5 times then restarts.
any help would be appreciared
Edit: this is what i will intergrat the code above into
global compatability
import sqlite3
with sqlite3.connect("Questionare.db") as db:
cursor = db.cursor()
class mentee: # these classes are made to create a place where atributes can be filled with variables
def __init__(self,mentee_name,mentee_position):
self._mentee_posisition=mentee_position
self._mentee_name=mentee_name
def menteereport(self):
return{"mentee name:":self._mentee_name,"mentee position":self._mentee_posisition}
class mentor:
def __init__(self,mentor_name,mentor_position):
self._mentor_position=mentor_position
self._mentor_name=mentor_name
def mentorreport(self): # these are methods and they use a function with the variables instanciated within the class to make this appen
return {"mentor name":self._mentor_name,"mentor position":self._mentor_position}
class calculation:
def __init__(self,number_of_questions,compatability,mentoranswers,menteeanwers):
self._question_number= 1
self._number_of_questions=number_of_questions
self._compatability=compatability
self._mentor_values=mentoranswers
self._mentee_values=menteeanwers
def calc(self):
compat=0
c=0
for i in range(0,self._number_of_questions):
if self._mentee_values[c] == self._mentor_answers[c]:
compat += 1
c+=1
else:
compat += 0
c+=0
compatability=compat/self._number_of_questions
self._compatability=compatability
compatability=compatability*100
print(self._mentee_answers)
print(self._mentor_answers)
print("\n{:0.2f}%.\n".format(compatability))
def mentoranswer(self):
self._number_of_questions = int(self._number_of_questions)
self._question_number=1
for i in range(0,self._number_of_questions):
answer=input("Q{}".format(self._question_number))
self._question_number+=1
self._mentor_answers.append(answer)
def menteeanswer(self):
self._number_of_questions = int(self._number_of_questions)
self._question_number=1
for i in range(0,self._number_of_questions):
answer=input("Q{}".format(self._question_number))
self._question_number+=1
self._mentee_answers.append(answer)
class timerequirements:
def __init__(self,mentor_time_allotment,mentee_time_allotment,ideal_length_of_mentoring,ideal_length_of_being_mentored):
self._mentor_time_allotment=mentor_time_allotment
self._mentee_time_allotment=mentee_time_allotment
self._ideal_length_of_mentoring=ideal_length_of_mentoring
self._ideal_length_of_being_mentored=ideal_length_of_being_mentored
def main(): # this function is created to put the variables into the artibutes so that everything will work.
v = True
mentoranswers = []
menteeanswers = []
no_of_q = int(input("numebr of questions"))
while v == True:
morm = input("are your a mentor or a mentee")
if morm.lower() == "mentor":
name = input("name")
position = input("position")
answers = []
for i in range(0, no_of_q):
answer = int(input("1 or 2"))
answers.append(answer)
mentoranswers.append(name)
mentoranswers.append(position)
mentoranswers.append(answers)
print(mentoranswers)
elif morm.lower() == "mentee":
name = input("name")
position = input("position")
answers = []
for i in range(0, no_of_q):
answer = int(input("1 or 2"))
answers.append(answer)
menteeanswers.append(name)
mentoranswers.append(position)
menteeanswers.append(answers)
print(menteeanswers)
elif morm.lower() == "q":
v = False
else:
print("try again")
print(mentoranswers.mentorreport())
print(menteeanswers.menteereport())
main()
you are adding way too much noise.
for iii in list(o):
C = o[y]
y = y + 1
why don't you simply use the variable you just created? it will be incremented automatically
for iii in list(o):
C = o[iii]
you should learn how to use a loop and a few other basics. there are good tutorials on the official python site. here the for-loop one. most of your variables exist just to repeat what you are already doing.
i've avoided some high-level constructs, but i left zip.
import random
mentees = []
names = ['zach', 'alex', 'fred', 'jane', 'sara']
for name in names:
mentee = dict()
mentee['name'] = name
mentee['compatibility'] = []
answers = []
for i in range(10):
answers.append(random.randint(1,4))
mentee['answers'] = answers
mentees.append(mentee)
for mentee1 in mentees:
m1_answers = mentee1['answers']
for mentee2 in mentees:
m2_answers = mentee2['answers']
compat = 0
# zip fuses both lists into one
for m1_answer, m2_answer in zip(m1_answers, m2_answers):
if m1_answer == m2_answer:
compat += 1
mentee1['compatibility'].append((mentee2['name'], compat))
print(mentees)

Getting only the keys but indexing producing error

def swiss_pairings(self):
players = self.player_standings()
players_paired = []
i = 0
// name = players.keys()[i]
match_player = 1
while match_player < range(len(players)):
// name_match_player = players.keys()[match_player]
player_one_id = Player.objects.get(name=name)
player_two_id = Player.objects.get(
name=name_match_player)
if self.has_played_before(player_one_id, player_two_id):
match_player += 1
else:
self.report_match(player_one_id, player_two_id)
players_paired.append(player_one_id.name, player_two_id.name)
del players[name]
del players[name_match_player]
break
return players_paired
The commented lines are producing that dictionaries are not indexed. What can be the replacement for those two lines?? I want only the "keys".

Parsing Data from live website in Python Enumerate problem!

The following script is supposed to fetch a specific line number and parse it from a live website. It works for like 30 loops but then it seems like enumerate(f) stops working correctly... the "i" in the for loop seems to stop at line 130 instead of like 200 something. Could this be due to the website I'm trying to fetch data from or something else? Thanks!!
import sgmllib
class MyParser(sgmllib.SGMLParser):
"A simple parser class."
def parse(self, s):
"Parse the given string 's'."
self.feed(s)
self.close()
def __init__(self, verbose=0):
"Initialise an object, passing 'verbose' to the superclass."
sgmllib.SGMLParser.__init__(self, verbose)
self.divs = []
self.descriptions = []
self.inside_div_element = 0
def start_div(self, attributes):
"Process a hyperlink and its 'attributes'."
for name, value in attributes:
if name == "id":
self.divs.append(value)
self.inside_div_element = 1
def end_div(self):
"Record the end of a hyperlink."
self.inside_div_element = 0
def handle_data(self, data):
"Handle the textual 'data'."
if self.inside_div_element:
self.descriptions.append(data)
def get_div(self):
"Return the list of hyperlinks."
return self.divs
def get_descriptions(self, check):
"Return a list of descriptions."
if check == 1:
self.descriptions.pop(0)
return self.descriptions
def rm_descriptions(self):
"Remove all descriptions."
self.descriptions.pop()
import urllib
import linecache
import sgmllib
tempLine = ""
tempStr = " "
tempStr2 = ""
myparser = MyParser()
count = 0
user = ['']
oldUser = ['none']
oldoldUser = [' ']
array = [" ", 0]
index = 0
found = 0
k = 0
j = 0
posIndex = 0
a = 0
firstCheck = 0
fCheck = 0
while a < 1000:
print a
f = urllib.urlopen("SITE")
a = a+1
for i, line in enumerate(f):
if i == 187:
print i
tempLine = line
print line
myparser.parse(line)
if fCheck == 1:
result = oldUser[0] is oldUser[1]
u1 = oldUser[0]
u2 = oldUser[1]
tempStr = oldUser[1]
if u1 == u2:
result = 1
else:
result = user is oldUser
fCheck = 1
user = myparser.get_descriptions(firstCheck)
tempStr = user[0]
firstCheck = 1
if result:
array[index+1] = array[index+1] +0
else:
j = 0
for z in array:
k = j+2
tempStr2 = user[0]
if k < len(array) and tempStr2 == array[k]:
array[j+3] = array[j+3] + 1
index = j+2
found = 1
break
j = j+1
if found == 0:
array.append(tempStr)
array.append(0)
oldUser = user
found = 0
print array
elif i > 200:
print "HERE"
break
print array
f.close()
Perhaps the number of lines on that web page are fewer than you think? What does this give you?:
print max(i for i, _ in enumerate(urllib.urlopen("SITE")))
Aside: Your indentation is stuffed after the while a < 1000: line. Excessive empty lines and one-letter names don't assist the understanding of your code.
enumerate is not broken. Instead of such speculation, inspect your data. Suggestion: replace
for i, line in enumerate(f):
by
lines = list(f)
print "=== a=%d linecount=%d === % (a, len(lines))
for i, line in enumerate(lines):
print " a=%d i=%d line=%r" % (a, i, line)
Examine the output carefully.

Categories