Deleting items from a python dictionary
I'm trying to use a spam classification application in Python but i'm getting the errors below. I don't understand it though since i'm using the .keys method to delete items from the dictionary so that shouldn't be a problem?
I've tried removing all the functionars bar the dictionary function to try and find a cause but I can't seem to wrap my head around this
Python code
import os
import numpy as np
from collections import Counter
from sklearn.naive_bayes import MultinomialNB
from sklearn.svm import LinearSVC
from sklearn.metrics import confusion_matrix
def make_Dictionary(train_dir):
emails = [os.path.join(train_dir,f) for f in os.listdir(train_dir)]
all_words =
for mail in emails:
with open(mail) as m:
for i,line in enumerate(m):
if i == 2:
words = line.split()
all_words += words
dictionary = Counter(all_words)
list_to_remove = dictionary.keys()
for item in list_to_remove:
if item.isalpha() == False:
del dictionary[item]
elif len(item) == 1:
del dictionary[item]
dictionary = dictionary.most_common(3000)
return dictionary
def extract_features(mail_dir):
files = [os.path.join(mail_dir,fi) for fi in os.listdir(mail_dir)]
features_matrix = np.zeros((len(files),3000))
docID = 0;
for fil in files:
with open(fil) as fi:
for i,line in enumerate(fi):
if i == 2:
words = line.split()
for word in words:
wordID = 0
for i,d in enumerate(dictionary):
if d[0] == word:
wordID = i
features_matrix[docID,wordID] = words.count(word)
docID = docID + 1
return features_matrix
# Create a dictionary of words with its frequency
train_dir = r'.train-mails'
dictionary = make_Dictionary(train_dir)
# Prepare feature vectors per training mail and its labels
train_labels = np.zeros(702)
train_labels[351:701] = 1
train_matrix = extract_features(train_dir)
# Training SVM and Naive bayes classifier and its variants
model1 = LinearSVC()
model1.fit(train_matrix,train_labels)
# Test the unseen mails for Spam
test_dir = r'.test-mails'
test_matrix = extract_features(test_dir)
test_labels = np.zeros(260)
test_labels[130:260] = 1
result1 = model1.predict(test_matrix)
print (confusion_matrix(test_labels,result1))
print (confusion_matrix(test_labels,result2))
Error
RuntimeError: dictionary changed size during iteration
python
add a comment |
I'm trying to use a spam classification application in Python but i'm getting the errors below. I don't understand it though since i'm using the .keys method to delete items from the dictionary so that shouldn't be a problem?
I've tried removing all the functionars bar the dictionary function to try and find a cause but I can't seem to wrap my head around this
Python code
import os
import numpy as np
from collections import Counter
from sklearn.naive_bayes import MultinomialNB
from sklearn.svm import LinearSVC
from sklearn.metrics import confusion_matrix
def make_Dictionary(train_dir):
emails = [os.path.join(train_dir,f) for f in os.listdir(train_dir)]
all_words =
for mail in emails:
with open(mail) as m:
for i,line in enumerate(m):
if i == 2:
words = line.split()
all_words += words
dictionary = Counter(all_words)
list_to_remove = dictionary.keys()
for item in list_to_remove:
if item.isalpha() == False:
del dictionary[item]
elif len(item) == 1:
del dictionary[item]
dictionary = dictionary.most_common(3000)
return dictionary
def extract_features(mail_dir):
files = [os.path.join(mail_dir,fi) for fi in os.listdir(mail_dir)]
features_matrix = np.zeros((len(files),3000))
docID = 0;
for fil in files:
with open(fil) as fi:
for i,line in enumerate(fi):
if i == 2:
words = line.split()
for word in words:
wordID = 0
for i,d in enumerate(dictionary):
if d[0] == word:
wordID = i
features_matrix[docID,wordID] = words.count(word)
docID = docID + 1
return features_matrix
# Create a dictionary of words with its frequency
train_dir = r'.train-mails'
dictionary = make_Dictionary(train_dir)
# Prepare feature vectors per training mail and its labels
train_labels = np.zeros(702)
train_labels[351:701] = 1
train_matrix = extract_features(train_dir)
# Training SVM and Naive bayes classifier and its variants
model1 = LinearSVC()
model1.fit(train_matrix,train_labels)
# Test the unseen mails for Spam
test_dir = r'.test-mails'
test_matrix = extract_features(test_dir)
test_labels = np.zeros(260)
test_labels[130:260] = 1
result1 = model1.predict(test_matrix)
print (confusion_matrix(test_labels,result1))
print (confusion_matrix(test_labels,result2))
Error
RuntimeError: dictionary changed size during iteration
python
add a comment |
I'm trying to use a spam classification application in Python but i'm getting the errors below. I don't understand it though since i'm using the .keys method to delete items from the dictionary so that shouldn't be a problem?
I've tried removing all the functionars bar the dictionary function to try and find a cause but I can't seem to wrap my head around this
Python code
import os
import numpy as np
from collections import Counter
from sklearn.naive_bayes import MultinomialNB
from sklearn.svm import LinearSVC
from sklearn.metrics import confusion_matrix
def make_Dictionary(train_dir):
emails = [os.path.join(train_dir,f) for f in os.listdir(train_dir)]
all_words =
for mail in emails:
with open(mail) as m:
for i,line in enumerate(m):
if i == 2:
words = line.split()
all_words += words
dictionary = Counter(all_words)
list_to_remove = dictionary.keys()
for item in list_to_remove:
if item.isalpha() == False:
del dictionary[item]
elif len(item) == 1:
del dictionary[item]
dictionary = dictionary.most_common(3000)
return dictionary
def extract_features(mail_dir):
files = [os.path.join(mail_dir,fi) for fi in os.listdir(mail_dir)]
features_matrix = np.zeros((len(files),3000))
docID = 0;
for fil in files:
with open(fil) as fi:
for i,line in enumerate(fi):
if i == 2:
words = line.split()
for word in words:
wordID = 0
for i,d in enumerate(dictionary):
if d[0] == word:
wordID = i
features_matrix[docID,wordID] = words.count(word)
docID = docID + 1
return features_matrix
# Create a dictionary of words with its frequency
train_dir = r'.train-mails'
dictionary = make_Dictionary(train_dir)
# Prepare feature vectors per training mail and its labels
train_labels = np.zeros(702)
train_labels[351:701] = 1
train_matrix = extract_features(train_dir)
# Training SVM and Naive bayes classifier and its variants
model1 = LinearSVC()
model1.fit(train_matrix,train_labels)
# Test the unseen mails for Spam
test_dir = r'.test-mails'
test_matrix = extract_features(test_dir)
test_labels = np.zeros(260)
test_labels[130:260] = 1
result1 = model1.predict(test_matrix)
print (confusion_matrix(test_labels,result1))
print (confusion_matrix(test_labels,result2))
Error
RuntimeError: dictionary changed size during iteration
python
I'm trying to use a spam classification application in Python but i'm getting the errors below. I don't understand it though since i'm using the .keys method to delete items from the dictionary so that shouldn't be a problem?
I've tried removing all the functionars bar the dictionary function to try and find a cause but I can't seem to wrap my head around this
Python code
import os
import numpy as np
from collections import Counter
from sklearn.naive_bayes import MultinomialNB
from sklearn.svm import LinearSVC
from sklearn.metrics import confusion_matrix
def make_Dictionary(train_dir):
emails = [os.path.join(train_dir,f) for f in os.listdir(train_dir)]
all_words =
for mail in emails:
with open(mail) as m:
for i,line in enumerate(m):
if i == 2:
words = line.split()
all_words += words
dictionary = Counter(all_words)
list_to_remove = dictionary.keys()
for item in list_to_remove:
if item.isalpha() == False:
del dictionary[item]
elif len(item) == 1:
del dictionary[item]
dictionary = dictionary.most_common(3000)
return dictionary
def extract_features(mail_dir):
files = [os.path.join(mail_dir,fi) for fi in os.listdir(mail_dir)]
features_matrix = np.zeros((len(files),3000))
docID = 0;
for fil in files:
with open(fil) as fi:
for i,line in enumerate(fi):
if i == 2:
words = line.split()
for word in words:
wordID = 0
for i,d in enumerate(dictionary):
if d[0] == word:
wordID = i
features_matrix[docID,wordID] = words.count(word)
docID = docID + 1
return features_matrix
# Create a dictionary of words with its frequency
train_dir = r'.train-mails'
dictionary = make_Dictionary(train_dir)
# Prepare feature vectors per training mail and its labels
train_labels = np.zeros(702)
train_labels[351:701] = 1
train_matrix = extract_features(train_dir)
# Training SVM and Naive bayes classifier and its variants
model1 = LinearSVC()
model1.fit(train_matrix,train_labels)
# Test the unseen mails for Spam
test_dir = r'.test-mails'
test_matrix = extract_features(test_dir)
test_labels = np.zeros(260)
test_labels[130:260] = 1
result1 = model1.predict(test_matrix)
print (confusion_matrix(test_labels,result1))
print (confusion_matrix(test_labels,result2))
Error
RuntimeError: dictionary changed size during iteration
python
python
asked Nov 19 '18 at 23:08
user9562782
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
This doesn't work in Python 3.x because keys returns an iterator instead of a list.
Another way is to use list to force a copy of the keys to be made. This one also works in Python 3.x:
for i in list(list_to_remove):
add a comment |
dictionary.keys() is actually returning a reference to the original dictionary keys.
You can check this by doing the following:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is dict_keys(['a'])
a_dict['b'] = 2 # keys is dict_keys(['a', 'b'])
That's why you are getting the error: with del dictionary[item] you are actually affecting list_to_remove, which is forbidden during a loop.
You can avoid this by creating a copy of the original keys before looping through them. The easiest way to achieve this is using the list constructor. So changing your line
list_to_remove = dictionary.keys()
with:
list_to_remove = list(dictionary.keys())
solves the issue.
Edition after comment
Note that this behaviour only happens in python 3, in python 2, the .keys() method returned a normal list, with no reference to the dictionary:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is ['a']
a_dict['b'] = 2 # keys is still ['a']
About this on the Python 3.0 changelog:
Some well-known APIs no longer return lists:
- dict methods dict.keys(), dict.items() and dict.values() return “views” instead of lists.
thankyou for the answer! that seems to solve it. Any reason why the whole thing just crashes, aka not working. It comes straight from a github page that should work.
– user9562782
Nov 19 '18 at 23:22
Oh, yes! I forgot that. You are usingpython 3, which returns this referencedict_keysand the code you copied ispython 2, where thekeys()method returned a list. I'll add it to my answer now.
– Julian Peller
Nov 19 '18 at 23:25
awesome, that makes sense. Apart from rolling back to python 2 what would you suggest?
– user9562782
Nov 19 '18 at 23:28
This is one of the largest changes from python 2 to 3 and if it's not too much code it may work directly or with some fixes. On the other hand, typically bothpython3andpython2.7can coexist in a linux environment, so you can try to run this code withpython2.7instead ofpythonwhich is the default. Ifpython2.7is not present probably you could install it on the side of python 3. I mean, there is no need to "rollback".
– Julian Peller
Nov 19 '18 at 23:42
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383936%2fdeleting-items-from-a-python-dictionary%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
This doesn't work in Python 3.x because keys returns an iterator instead of a list.
Another way is to use list to force a copy of the keys to be made. This one also works in Python 3.x:
for i in list(list_to_remove):
add a comment |
This doesn't work in Python 3.x because keys returns an iterator instead of a list.
Another way is to use list to force a copy of the keys to be made. This one also works in Python 3.x:
for i in list(list_to_remove):
add a comment |
This doesn't work in Python 3.x because keys returns an iterator instead of a list.
Another way is to use list to force a copy of the keys to be made. This one also works in Python 3.x:
for i in list(list_to_remove):
This doesn't work in Python 3.x because keys returns an iterator instead of a list.
Another way is to use list to force a copy of the keys to be made. This one also works in Python 3.x:
for i in list(list_to_remove):
answered Nov 19 '18 at 23:12
chromaerrorchromaerror
17311
17311
add a comment |
add a comment |
dictionary.keys() is actually returning a reference to the original dictionary keys.
You can check this by doing the following:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is dict_keys(['a'])
a_dict['b'] = 2 # keys is dict_keys(['a', 'b'])
That's why you are getting the error: with del dictionary[item] you are actually affecting list_to_remove, which is forbidden during a loop.
You can avoid this by creating a copy of the original keys before looping through them. The easiest way to achieve this is using the list constructor. So changing your line
list_to_remove = dictionary.keys()
with:
list_to_remove = list(dictionary.keys())
solves the issue.
Edition after comment
Note that this behaviour only happens in python 3, in python 2, the .keys() method returned a normal list, with no reference to the dictionary:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is ['a']
a_dict['b'] = 2 # keys is still ['a']
About this on the Python 3.0 changelog:
Some well-known APIs no longer return lists:
- dict methods dict.keys(), dict.items() and dict.values() return “views” instead of lists.
thankyou for the answer! that seems to solve it. Any reason why the whole thing just crashes, aka not working. It comes straight from a github page that should work.
– user9562782
Nov 19 '18 at 23:22
Oh, yes! I forgot that. You are usingpython 3, which returns this referencedict_keysand the code you copied ispython 2, where thekeys()method returned a list. I'll add it to my answer now.
– Julian Peller
Nov 19 '18 at 23:25
awesome, that makes sense. Apart from rolling back to python 2 what would you suggest?
– user9562782
Nov 19 '18 at 23:28
This is one of the largest changes from python 2 to 3 and if it's not too much code it may work directly or with some fixes. On the other hand, typically bothpython3andpython2.7can coexist in a linux environment, so you can try to run this code withpython2.7instead ofpythonwhich is the default. Ifpython2.7is not present probably you could install it on the side of python 3. I mean, there is no need to "rollback".
– Julian Peller
Nov 19 '18 at 23:42
add a comment |
dictionary.keys() is actually returning a reference to the original dictionary keys.
You can check this by doing the following:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is dict_keys(['a'])
a_dict['b'] = 2 # keys is dict_keys(['a', 'b'])
That's why you are getting the error: with del dictionary[item] you are actually affecting list_to_remove, which is forbidden during a loop.
You can avoid this by creating a copy of the original keys before looping through them. The easiest way to achieve this is using the list constructor. So changing your line
list_to_remove = dictionary.keys()
with:
list_to_remove = list(dictionary.keys())
solves the issue.
Edition after comment
Note that this behaviour only happens in python 3, in python 2, the .keys() method returned a normal list, with no reference to the dictionary:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is ['a']
a_dict['b'] = 2 # keys is still ['a']
About this on the Python 3.0 changelog:
Some well-known APIs no longer return lists:
- dict methods dict.keys(), dict.items() and dict.values() return “views” instead of lists.
thankyou for the answer! that seems to solve it. Any reason why the whole thing just crashes, aka not working. It comes straight from a github page that should work.
– user9562782
Nov 19 '18 at 23:22
Oh, yes! I forgot that. You are usingpython 3, which returns this referencedict_keysand the code you copied ispython 2, where thekeys()method returned a list. I'll add it to my answer now.
– Julian Peller
Nov 19 '18 at 23:25
awesome, that makes sense. Apart from rolling back to python 2 what would you suggest?
– user9562782
Nov 19 '18 at 23:28
This is one of the largest changes from python 2 to 3 and if it's not too much code it may work directly or with some fixes. On the other hand, typically bothpython3andpython2.7can coexist in a linux environment, so you can try to run this code withpython2.7instead ofpythonwhich is the default. Ifpython2.7is not present probably you could install it on the side of python 3. I mean, there is no need to "rollback".
– Julian Peller
Nov 19 '18 at 23:42
add a comment |
dictionary.keys() is actually returning a reference to the original dictionary keys.
You can check this by doing the following:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is dict_keys(['a'])
a_dict['b'] = 2 # keys is dict_keys(['a', 'b'])
That's why you are getting the error: with del dictionary[item] you are actually affecting list_to_remove, which is forbidden during a loop.
You can avoid this by creating a copy of the original keys before looping through them. The easiest way to achieve this is using the list constructor. So changing your line
list_to_remove = dictionary.keys()
with:
list_to_remove = list(dictionary.keys())
solves the issue.
Edition after comment
Note that this behaviour only happens in python 3, in python 2, the .keys() method returned a normal list, with no reference to the dictionary:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is ['a']
a_dict['b'] = 2 # keys is still ['a']
About this on the Python 3.0 changelog:
Some well-known APIs no longer return lists:
- dict methods dict.keys(), dict.items() and dict.values() return “views” instead of lists.
dictionary.keys() is actually returning a reference to the original dictionary keys.
You can check this by doing the following:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is dict_keys(['a'])
a_dict['b'] = 2 # keys is dict_keys(['a', 'b'])
That's why you are getting the error: with del dictionary[item] you are actually affecting list_to_remove, which is forbidden during a loop.
You can avoid this by creating a copy of the original keys before looping through them. The easiest way to achieve this is using the list constructor. So changing your line
list_to_remove = dictionary.keys()
with:
list_to_remove = list(dictionary.keys())
solves the issue.
Edition after comment
Note that this behaviour only happens in python 3, in python 2, the .keys() method returned a normal list, with no reference to the dictionary:
a_dict = {'a': 1}
keys = a_dict.keys() # keys is ['a']
a_dict['b'] = 2 # keys is still ['a']
About this on the Python 3.0 changelog:
Some well-known APIs no longer return lists:
- dict methods dict.keys(), dict.items() and dict.values() return “views” instead of lists.
edited Nov 19 '18 at 23:28
answered Nov 19 '18 at 23:18
Julian PellerJulian Peller
8941511
8941511
thankyou for the answer! that seems to solve it. Any reason why the whole thing just crashes, aka not working. It comes straight from a github page that should work.
– user9562782
Nov 19 '18 at 23:22
Oh, yes! I forgot that. You are usingpython 3, which returns this referencedict_keysand the code you copied ispython 2, where thekeys()method returned a list. I'll add it to my answer now.
– Julian Peller
Nov 19 '18 at 23:25
awesome, that makes sense. Apart from rolling back to python 2 what would you suggest?
– user9562782
Nov 19 '18 at 23:28
This is one of the largest changes from python 2 to 3 and if it's not too much code it may work directly or with some fixes. On the other hand, typically bothpython3andpython2.7can coexist in a linux environment, so you can try to run this code withpython2.7instead ofpythonwhich is the default. Ifpython2.7is not present probably you could install it on the side of python 3. I mean, there is no need to "rollback".
– Julian Peller
Nov 19 '18 at 23:42
add a comment |
thankyou for the answer! that seems to solve it. Any reason why the whole thing just crashes, aka not working. It comes straight from a github page that should work.
– user9562782
Nov 19 '18 at 23:22
Oh, yes! I forgot that. You are usingpython 3, which returns this referencedict_keysand the code you copied ispython 2, where thekeys()method returned a list. I'll add it to my answer now.
– Julian Peller
Nov 19 '18 at 23:25
awesome, that makes sense. Apart from rolling back to python 2 what would you suggest?
– user9562782
Nov 19 '18 at 23:28
This is one of the largest changes from python 2 to 3 and if it's not too much code it may work directly or with some fixes. On the other hand, typically bothpython3andpython2.7can coexist in a linux environment, so you can try to run this code withpython2.7instead ofpythonwhich is the default. Ifpython2.7is not present probably you could install it on the side of python 3. I mean, there is no need to "rollback".
– Julian Peller
Nov 19 '18 at 23:42
thankyou for the answer! that seems to solve it. Any reason why the whole thing just crashes, aka not working. It comes straight from a github page that should work.
– user9562782
Nov 19 '18 at 23:22
thankyou for the answer! that seems to solve it. Any reason why the whole thing just crashes, aka not working. It comes straight from a github page that should work.
– user9562782
Nov 19 '18 at 23:22
Oh, yes! I forgot that. You are using
python 3, which returns this reference dict_keys and the code you copied is python 2, where the keys() method returned a list. I'll add it to my answer now.– Julian Peller
Nov 19 '18 at 23:25
Oh, yes! I forgot that. You are using
python 3, which returns this reference dict_keys and the code you copied is python 2, where the keys() method returned a list. I'll add it to my answer now.– Julian Peller
Nov 19 '18 at 23:25
awesome, that makes sense. Apart from rolling back to python 2 what would you suggest?
– user9562782
Nov 19 '18 at 23:28
awesome, that makes sense. Apart from rolling back to python 2 what would you suggest?
– user9562782
Nov 19 '18 at 23:28
This is one of the largest changes from python 2 to 3 and if it's not too much code it may work directly or with some fixes. On the other hand, typically both
python3 and python2.7 can coexist in a linux environment, so you can try to run this code with python2.7 instead of python which is the default. If python2.7 is not present probably you could install it on the side of python 3. I mean, there is no need to "rollback".– Julian Peller
Nov 19 '18 at 23:42
This is one of the largest changes from python 2 to 3 and if it's not too much code it may work directly or with some fixes. On the other hand, typically both
python3 and python2.7 can coexist in a linux environment, so you can try to run this code with python2.7 instead of python which is the default. If python2.7 is not present probably you could install it on the side of python 3. I mean, there is no need to "rollback".– Julian Peller
Nov 19 '18 at 23:42
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383936%2fdeleting-items-from-a-python-dictionary%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown