Implemnting a Trie Data structures problem from HackerRank using Python3
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
4
down vote
favorite
I'm trying to write a better code in python. I don't know where to start checking. I want to make sure that I do write a best practice code.
This is the second problem in Hackerrank trie data structure:
Given N strings. Each string contains only lowercase letters from (both inclusive). The set of strings is said to be GOOD SET if no string is prefix of another string else, it is BAD SET. (If two strings are identical, they are considered prefixes of each other.)
For example, aab, abcde, aabcd is BAD SET because aab is prefix of aabcd.
Print GOOD SET if it satisfies the problem requirement.
Else, print BAD SET and the first string for which the condition fails.
Input Format
First line contains , the number of strings in the set.
Then next lines follow, where line contains string.
Output Format
Output GOOD SET if the set is valid.
Else, output BAD SET followed by the first string for which the condition fails.
Sample Input00
7
aab
defgab
abcde
aabcde
cedaaa
bbbbbbbbbb
jabjjjad
Sample Output00
BAD SET
aabcde
Sample Input01
4
aab
aac
aacghgh
aabghgh
Sample Output01
BAD SET
aacghgh
from sys import stdin
class Node:
def __init__(self,char):
self.character = char
self.children =
self.counter = 0
self.end_word = False
class Trie:
def __init__(self):
self.root = Node('*')
def add(self,word):
current = self.root
fail = False
for char in word:
if char not in current.children:
new_node = Node(char)
current.children[char] = new_node
current = new_node
new_node.counter += 1
else:
current = current.children[char]
current.counter += 1
if current.end_word:
fail = True
current.end_word = True
# first word > second word : second word is prefix of first word
if current.counter >=2:
fail = True
return fail
if __name__ == "__main__":
tree = Trie()
n = stdin.readlines()
for i in n[1:]:
i = i.strip()
add_check_string = tree.add(i)
if add_check_string:
print("BAD SET")
print(i)
break
if not add_check_string:
print("GOOD SET")
python algorithm python-3.x
add a comment |Â
up vote
4
down vote
favorite
I'm trying to write a better code in python. I don't know where to start checking. I want to make sure that I do write a best practice code.
This is the second problem in Hackerrank trie data structure:
Given N strings. Each string contains only lowercase letters from (both inclusive). The set of strings is said to be GOOD SET if no string is prefix of another string else, it is BAD SET. (If two strings are identical, they are considered prefixes of each other.)
For example, aab, abcde, aabcd is BAD SET because aab is prefix of aabcd.
Print GOOD SET if it satisfies the problem requirement.
Else, print BAD SET and the first string for which the condition fails.
Input Format
First line contains , the number of strings in the set.
Then next lines follow, where line contains string.
Output Format
Output GOOD SET if the set is valid.
Else, output BAD SET followed by the first string for which the condition fails.
Sample Input00
7
aab
defgab
abcde
aabcde
cedaaa
bbbbbbbbbb
jabjjjad
Sample Output00
BAD SET
aabcde
Sample Input01
4
aab
aac
aacghgh
aabghgh
Sample Output01
BAD SET
aacghgh
from sys import stdin
class Node:
def __init__(self,char):
self.character = char
self.children =
self.counter = 0
self.end_word = False
class Trie:
def __init__(self):
self.root = Node('*')
def add(self,word):
current = self.root
fail = False
for char in word:
if char not in current.children:
new_node = Node(char)
current.children[char] = new_node
current = new_node
new_node.counter += 1
else:
current = current.children[char]
current.counter += 1
if current.end_word:
fail = True
current.end_word = True
# first word > second word : second word is prefix of first word
if current.counter >=2:
fail = True
return fail
if __name__ == "__main__":
tree = Trie()
n = stdin.readlines()
for i in n[1:]:
i = i.strip()
add_check_string = tree.add(i)
if add_check_string:
print("BAD SET")
print(i)
break
if not add_check_string:
print("GOOD SET")
python algorithm python-3.x
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I'm trying to write a better code in python. I don't know where to start checking. I want to make sure that I do write a best practice code.
This is the second problem in Hackerrank trie data structure:
Given N strings. Each string contains only lowercase letters from (both inclusive). The set of strings is said to be GOOD SET if no string is prefix of another string else, it is BAD SET. (If two strings are identical, they are considered prefixes of each other.)
For example, aab, abcde, aabcd is BAD SET because aab is prefix of aabcd.
Print GOOD SET if it satisfies the problem requirement.
Else, print BAD SET and the first string for which the condition fails.
Input Format
First line contains , the number of strings in the set.
Then next lines follow, where line contains string.
Output Format
Output GOOD SET if the set is valid.
Else, output BAD SET followed by the first string for which the condition fails.
Sample Input00
7
aab
defgab
abcde
aabcde
cedaaa
bbbbbbbbbb
jabjjjad
Sample Output00
BAD SET
aabcde
Sample Input01
4
aab
aac
aacghgh
aabghgh
Sample Output01
BAD SET
aacghgh
from sys import stdin
class Node:
def __init__(self,char):
self.character = char
self.children =
self.counter = 0
self.end_word = False
class Trie:
def __init__(self):
self.root = Node('*')
def add(self,word):
current = self.root
fail = False
for char in word:
if char not in current.children:
new_node = Node(char)
current.children[char] = new_node
current = new_node
new_node.counter += 1
else:
current = current.children[char]
current.counter += 1
if current.end_word:
fail = True
current.end_word = True
# first word > second word : second word is prefix of first word
if current.counter >=2:
fail = True
return fail
if __name__ == "__main__":
tree = Trie()
n = stdin.readlines()
for i in n[1:]:
i = i.strip()
add_check_string = tree.add(i)
if add_check_string:
print("BAD SET")
print(i)
break
if not add_check_string:
print("GOOD SET")
python algorithm python-3.x
I'm trying to write a better code in python. I don't know where to start checking. I want to make sure that I do write a best practice code.
This is the second problem in Hackerrank trie data structure:
Given N strings. Each string contains only lowercase letters from (both inclusive). The set of strings is said to be GOOD SET if no string is prefix of another string else, it is BAD SET. (If two strings are identical, they are considered prefixes of each other.)
For example, aab, abcde, aabcd is BAD SET because aab is prefix of aabcd.
Print GOOD SET if it satisfies the problem requirement.
Else, print BAD SET and the first string for which the condition fails.
Input Format
First line contains , the number of strings in the set.
Then next lines follow, where line contains string.
Output Format
Output GOOD SET if the set is valid.
Else, output BAD SET followed by the first string for which the condition fails.
Sample Input00
7
aab
defgab
abcde
aabcde
cedaaa
bbbbbbbbbb
jabjjjad
Sample Output00
BAD SET
aabcde
Sample Input01
4
aab
aac
aacghgh
aabghgh
Sample Output01
BAD SET
aacghgh
from sys import stdin
class Node:
def __init__(self,char):
self.character = char
self.children =
self.counter = 0
self.end_word = False
class Trie:
def __init__(self):
self.root = Node('*')
def add(self,word):
current = self.root
fail = False
for char in word:
if char not in current.children:
new_node = Node(char)
current.children[char] = new_node
current = new_node
new_node.counter += 1
else:
current = current.children[char]
current.counter += 1
if current.end_word:
fail = True
current.end_word = True
# first word > second word : second word is prefix of first word
if current.counter >=2:
fail = True
return fail
if __name__ == "__main__":
tree = Trie()
n = stdin.readlines()
for i in n[1:]:
i = i.strip()
add_check_string = tree.add(i)
if add_check_string:
print("BAD SET")
print(i)
break
if not add_check_string:
print("GOOD SET")
python algorithm python-3.x
edited Mar 22 at 17:14
Mathias Ettinger
21.9k32876
21.9k32876
asked Mar 22 at 12:17
Mohamed Saad
212
212
add a comment |Â
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
1
down vote
- You could run
autopep8
for minor style corrections (e.g. whitespaces). Naming variables correctly is always extremely important, especially in a dynamic language, without indications about object type:
- Your
trie
is aTrie
, not just atree
. n
sounds like an integer. It could be calledlines
.i
also sounds like an integer. It could beline
orword
.
- Your
Using
for/else
syntax, you can refactor your main method without any flag.
if __name__ == "__main__":
trie = Trie()
_header, *lines = stdin.readlines()
for line in lines:
word = line.strip()
if trie.add(word):
print("BAD SET")
print(word)
break
else:
print("GOOD SET")
- If you wish, you could replace the 3 last lines of
add
byreturn fail or current.counter >= 2
add a comment |Â
up vote
0
down vote
I think the only change I would make is removing node.counter
, and instead detecting if a previous word is a prefix of the current word by checking if current.fail==True
.
Thank you for your raply. May I know Why did you mention taht there are Performance Issues?
â Mohamed Saad
Mar 22 at 20:44
oops, I combined 2 separate (and unrelated) questions in my head, and pulled out that you thought this was a bottleneck somehow. Edited.
â Oscar Smith
Mar 22 at 21:01
No Problem, Man.
â Mohamed Saad
Mar 22 at 21:06
add a comment |Â
up vote
0
down vote
There is a lot of repetition in your add
method.
This can be simplified, ditching the fail flag
to
def add_unless_prefix(self,word):
current = self.root
for char in word:
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
current.counter += 1
if current.end_word:
return True
current.end_word = True
return current.counter >=2
This can be simplified a bit using dict.setdefault
.
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
can become current = current.children.setdefault(char, Node(char))
I also tried to remove thefail
flag, but .... I failed. By returning early, you preventword
from being added to thetrie
.return fail
was just some extra piece of information, not the main purpose of theadd
method. At the very least, your new method should be called differently, e.g.add_unless_prefix
.
â Eric Duminil
Mar 25 at 19:52
Oops, small bug. That was meant to bereturn True
, signalling that it matches a prefix
â Maarten Fabré
Mar 26 at 6:51
It still doesn't add the word to the trie, though. Given the name of the class and method, it still sounds like a bug.
â Eric Duminil
Mar 26 at 6:57
this isn't mean to be a complete Trie. This is meant to detect whether there is a prefix, so in the context of this HackerRank issue, this suffices.
â Maarten Fabré
Mar 26 at 7:08
Fine, then you should change the method name to make it clear.
â Eric Duminil
Mar 26 at 7:20
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
- You could run
autopep8
for minor style corrections (e.g. whitespaces). Naming variables correctly is always extremely important, especially in a dynamic language, without indications about object type:
- Your
trie
is aTrie
, not just atree
. n
sounds like an integer. It could be calledlines
.i
also sounds like an integer. It could beline
orword
.
- Your
Using
for/else
syntax, you can refactor your main method without any flag.
if __name__ == "__main__":
trie = Trie()
_header, *lines = stdin.readlines()
for line in lines:
word = line.strip()
if trie.add(word):
print("BAD SET")
print(word)
break
else:
print("GOOD SET")
- If you wish, you could replace the 3 last lines of
add
byreturn fail or current.counter >= 2
add a comment |Â
up vote
1
down vote
- You could run
autopep8
for minor style corrections (e.g. whitespaces). Naming variables correctly is always extremely important, especially in a dynamic language, without indications about object type:
- Your
trie
is aTrie
, not just atree
. n
sounds like an integer. It could be calledlines
.i
also sounds like an integer. It could beline
orword
.
- Your
Using
for/else
syntax, you can refactor your main method without any flag.
if __name__ == "__main__":
trie = Trie()
_header, *lines = stdin.readlines()
for line in lines:
word = line.strip()
if trie.add(word):
print("BAD SET")
print(word)
break
else:
print("GOOD SET")
- If you wish, you could replace the 3 last lines of
add
byreturn fail or current.counter >= 2
add a comment |Â
up vote
1
down vote
up vote
1
down vote
- You could run
autopep8
for minor style corrections (e.g. whitespaces). Naming variables correctly is always extremely important, especially in a dynamic language, without indications about object type:
- Your
trie
is aTrie
, not just atree
. n
sounds like an integer. It could be calledlines
.i
also sounds like an integer. It could beline
orword
.
- Your
Using
for/else
syntax, you can refactor your main method without any flag.
if __name__ == "__main__":
trie = Trie()
_header, *lines = stdin.readlines()
for line in lines:
word = line.strip()
if trie.add(word):
print("BAD SET")
print(word)
break
else:
print("GOOD SET")
- If you wish, you could replace the 3 last lines of
add
byreturn fail or current.counter >= 2
- You could run
autopep8
for minor style corrections (e.g. whitespaces). Naming variables correctly is always extremely important, especially in a dynamic language, without indications about object type:
- Your
trie
is aTrie
, not just atree
. n
sounds like an integer. It could be calledlines
.i
also sounds like an integer. It could beline
orword
.
- Your
Using
for/else
syntax, you can refactor your main method without any flag.
if __name__ == "__main__":
trie = Trie()
_header, *lines = stdin.readlines()
for line in lines:
word = line.strip()
if trie.add(word):
print("BAD SET")
print(word)
break
else:
print("GOOD SET")
- If you wish, you could replace the 3 last lines of
add
byreturn fail or current.counter >= 2
edited Mar 23 at 8:52
answered Mar 23 at 8:40
Eric Duminil
1,8501613
1,8501613
add a comment |Â
add a comment |Â
up vote
0
down vote
I think the only change I would make is removing node.counter
, and instead detecting if a previous word is a prefix of the current word by checking if current.fail==True
.
Thank you for your raply. May I know Why did you mention taht there are Performance Issues?
â Mohamed Saad
Mar 22 at 20:44
oops, I combined 2 separate (and unrelated) questions in my head, and pulled out that you thought this was a bottleneck somehow. Edited.
â Oscar Smith
Mar 22 at 21:01
No Problem, Man.
â Mohamed Saad
Mar 22 at 21:06
add a comment |Â
up vote
0
down vote
I think the only change I would make is removing node.counter
, and instead detecting if a previous word is a prefix of the current word by checking if current.fail==True
.
Thank you for your raply. May I know Why did you mention taht there are Performance Issues?
â Mohamed Saad
Mar 22 at 20:44
oops, I combined 2 separate (and unrelated) questions in my head, and pulled out that you thought this was a bottleneck somehow. Edited.
â Oscar Smith
Mar 22 at 21:01
No Problem, Man.
â Mohamed Saad
Mar 22 at 21:06
add a comment |Â
up vote
0
down vote
up vote
0
down vote
I think the only change I would make is removing node.counter
, and instead detecting if a previous word is a prefix of the current word by checking if current.fail==True
.
I think the only change I would make is removing node.counter
, and instead detecting if a previous word is a prefix of the current word by checking if current.fail==True
.
edited Mar 22 at 21:00
answered Mar 22 at 20:16
Oscar Smith
2,625922
2,625922
Thank you for your raply. May I know Why did you mention taht there are Performance Issues?
â Mohamed Saad
Mar 22 at 20:44
oops, I combined 2 separate (and unrelated) questions in my head, and pulled out that you thought this was a bottleneck somehow. Edited.
â Oscar Smith
Mar 22 at 21:01
No Problem, Man.
â Mohamed Saad
Mar 22 at 21:06
add a comment |Â
Thank you for your raply. May I know Why did you mention taht there are Performance Issues?
â Mohamed Saad
Mar 22 at 20:44
oops, I combined 2 separate (and unrelated) questions in my head, and pulled out that you thought this was a bottleneck somehow. Edited.
â Oscar Smith
Mar 22 at 21:01
No Problem, Man.
â Mohamed Saad
Mar 22 at 21:06
Thank you for your raply. May I know Why did you mention taht there are Performance Issues?
â Mohamed Saad
Mar 22 at 20:44
Thank you for your raply. May I know Why did you mention taht there are Performance Issues?
â Mohamed Saad
Mar 22 at 20:44
oops, I combined 2 separate (and unrelated) questions in my head, and pulled out that you thought this was a bottleneck somehow. Edited.
â Oscar Smith
Mar 22 at 21:01
oops, I combined 2 separate (and unrelated) questions in my head, and pulled out that you thought this was a bottleneck somehow. Edited.
â Oscar Smith
Mar 22 at 21:01
No Problem, Man.
â Mohamed Saad
Mar 22 at 21:06
No Problem, Man.
â Mohamed Saad
Mar 22 at 21:06
add a comment |Â
up vote
0
down vote
There is a lot of repetition in your add
method.
This can be simplified, ditching the fail flag
to
def add_unless_prefix(self,word):
current = self.root
for char in word:
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
current.counter += 1
if current.end_word:
return True
current.end_word = True
return current.counter >=2
This can be simplified a bit using dict.setdefault
.
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
can become current = current.children.setdefault(char, Node(char))
I also tried to remove thefail
flag, but .... I failed. By returning early, you preventword
from being added to thetrie
.return fail
was just some extra piece of information, not the main purpose of theadd
method. At the very least, your new method should be called differently, e.g.add_unless_prefix
.
â Eric Duminil
Mar 25 at 19:52
Oops, small bug. That was meant to bereturn True
, signalling that it matches a prefix
â Maarten Fabré
Mar 26 at 6:51
It still doesn't add the word to the trie, though. Given the name of the class and method, it still sounds like a bug.
â Eric Duminil
Mar 26 at 6:57
this isn't mean to be a complete Trie. This is meant to detect whether there is a prefix, so in the context of this HackerRank issue, this suffices.
â Maarten Fabré
Mar 26 at 7:08
Fine, then you should change the method name to make it clear.
â Eric Duminil
Mar 26 at 7:20
add a comment |Â
up vote
0
down vote
There is a lot of repetition in your add
method.
This can be simplified, ditching the fail flag
to
def add_unless_prefix(self,word):
current = self.root
for char in word:
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
current.counter += 1
if current.end_word:
return True
current.end_word = True
return current.counter >=2
This can be simplified a bit using dict.setdefault
.
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
can become current = current.children.setdefault(char, Node(char))
I also tried to remove thefail
flag, but .... I failed. By returning early, you preventword
from being added to thetrie
.return fail
was just some extra piece of information, not the main purpose of theadd
method. At the very least, your new method should be called differently, e.g.add_unless_prefix
.
â Eric Duminil
Mar 25 at 19:52
Oops, small bug. That was meant to bereturn True
, signalling that it matches a prefix
â Maarten Fabré
Mar 26 at 6:51
It still doesn't add the word to the trie, though. Given the name of the class and method, it still sounds like a bug.
â Eric Duminil
Mar 26 at 6:57
this isn't mean to be a complete Trie. This is meant to detect whether there is a prefix, so in the context of this HackerRank issue, this suffices.
â Maarten Fabré
Mar 26 at 7:08
Fine, then you should change the method name to make it clear.
â Eric Duminil
Mar 26 at 7:20
add a comment |Â
up vote
0
down vote
up vote
0
down vote
There is a lot of repetition in your add
method.
This can be simplified, ditching the fail flag
to
def add_unless_prefix(self,word):
current = self.root
for char in word:
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
current.counter += 1
if current.end_word:
return True
current.end_word = True
return current.counter >=2
This can be simplified a bit using dict.setdefault
.
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
can become current = current.children.setdefault(char, Node(char))
There is a lot of repetition in your add
method.
This can be simplified, ditching the fail flag
to
def add_unless_prefix(self,word):
current = self.root
for char in word:
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
current.counter += 1
if current.end_word:
return True
current.end_word = True
return current.counter >=2
This can be simplified a bit using dict.setdefault
.
if char not in current.children:
current.children[char] = Node(char)
current = current.children[char]
can become current = current.children.setdefault(char, Node(char))
edited Mar 26 at 7:39
answered Mar 23 at 11:07
Maarten Fabré
3,204214
3,204214
I also tried to remove thefail
flag, but .... I failed. By returning early, you preventword
from being added to thetrie
.return fail
was just some extra piece of information, not the main purpose of theadd
method. At the very least, your new method should be called differently, e.g.add_unless_prefix
.
â Eric Duminil
Mar 25 at 19:52
Oops, small bug. That was meant to bereturn True
, signalling that it matches a prefix
â Maarten Fabré
Mar 26 at 6:51
It still doesn't add the word to the trie, though. Given the name of the class and method, it still sounds like a bug.
â Eric Duminil
Mar 26 at 6:57
this isn't mean to be a complete Trie. This is meant to detect whether there is a prefix, so in the context of this HackerRank issue, this suffices.
â Maarten Fabré
Mar 26 at 7:08
Fine, then you should change the method name to make it clear.
â Eric Duminil
Mar 26 at 7:20
add a comment |Â
I also tried to remove thefail
flag, but .... I failed. By returning early, you preventword
from being added to thetrie
.return fail
was just some extra piece of information, not the main purpose of theadd
method. At the very least, your new method should be called differently, e.g.add_unless_prefix
.
â Eric Duminil
Mar 25 at 19:52
Oops, small bug. That was meant to bereturn True
, signalling that it matches a prefix
â Maarten Fabré
Mar 26 at 6:51
It still doesn't add the word to the trie, though. Given the name of the class and method, it still sounds like a bug.
â Eric Duminil
Mar 26 at 6:57
this isn't mean to be a complete Trie. This is meant to detect whether there is a prefix, so in the context of this HackerRank issue, this suffices.
â Maarten Fabré
Mar 26 at 7:08
Fine, then you should change the method name to make it clear.
â Eric Duminil
Mar 26 at 7:20
I also tried to remove the
fail
flag, but .... I failed. By returning early, you prevent word
from being added to the trie
. return fail
was just some extra piece of information, not the main purpose of the add
method. At the very least, your new method should be called differently, e.g. add_unless_prefix
.â Eric Duminil
Mar 25 at 19:52
I also tried to remove the
fail
flag, but .... I failed. By returning early, you prevent word
from being added to the trie
. return fail
was just some extra piece of information, not the main purpose of the add
method. At the very least, your new method should be called differently, e.g. add_unless_prefix
.â Eric Duminil
Mar 25 at 19:52
Oops, small bug. That was meant to be
return True
, signalling that it matches a prefixâ Maarten Fabré
Mar 26 at 6:51
Oops, small bug. That was meant to be
return True
, signalling that it matches a prefixâ Maarten Fabré
Mar 26 at 6:51
It still doesn't add the word to the trie, though. Given the name of the class and method, it still sounds like a bug.
â Eric Duminil
Mar 26 at 6:57
It still doesn't add the word to the trie, though. Given the name of the class and method, it still sounds like a bug.
â Eric Duminil
Mar 26 at 6:57
this isn't mean to be a complete Trie. This is meant to detect whether there is a prefix, so in the context of this HackerRank issue, this suffices.
â Maarten Fabré
Mar 26 at 7:08
this isn't mean to be a complete Trie. This is meant to detect whether there is a prefix, so in the context of this HackerRank issue, this suffices.
â Maarten Fabré
Mar 26 at 7:08
Fine, then you should change the method name to make it clear.
â Eric Duminil
Mar 26 at 7:20
Fine, then you should change the method name to make it clear.
â Eric Duminil
Mar 26 at 7:20
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f190197%2fimplemnting-a-trie-data-structures-problem-from-hackerrank-using-python3%23new-answer', 'question_page');
);
Post as a guest
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
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
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