Square code encode and decode
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
2
down vote
favorite
I am doing some python practice and wrote a square code encoder/decoder. As described in drill #4 of Programming Practice Problems, the characters of a message are written left-to-right on a square grid, and each line of the encoded message is read by going top to bottom.
I'd like some feedback on what I wrote to see if there is anything I could have done better:
import math
def encode(message):
message = message.replace(" ", "")
square = math.ceil(math.sqrt(len(message)))
# Create the "grid"
rows =
for row in range(square):
pos = row * square
code = message[pos:pos + square]
rows.append(code)
print("The grid:n".format("n".join(rows)))
# Encode the message
coded_msg = ""
for col in range(square):
for row in range(square):
# The last column of the last row will throw an out of range error, so handle that
if col < len(rows[row]):
coded_msg += rows[row][col]
coded_msg += " "
return coded_msg.rstrip()
def decode(message):
square = math.sqrt(len(message))
col_count = math.ceil(square)
row_count = math.ceil(len(message) / col_count)
cols = message.split(" ")
decoded_msg = ""
for row in range(row_count):
for col in cols:
if row < len(col):
decoded_msg += col[row]
return decoded_msg
if __name__ == "__main__":
print("Gimme a message:")
in_message = input()
coded_message = encode(in_message)
print("--nSquare message:n".format(coded_message))
decoded_message = decode(coded_message)
#print("--nDecoded message:n".format(decoded_message))
print("--ninput: noutput: ".format(in_message, decoded_message))
python strings
add a comment |Â
up vote
2
down vote
favorite
I am doing some python practice and wrote a square code encoder/decoder. As described in drill #4 of Programming Practice Problems, the characters of a message are written left-to-right on a square grid, and each line of the encoded message is read by going top to bottom.
I'd like some feedback on what I wrote to see if there is anything I could have done better:
import math
def encode(message):
message = message.replace(" ", "")
square = math.ceil(math.sqrt(len(message)))
# Create the "grid"
rows =
for row in range(square):
pos = row * square
code = message[pos:pos + square]
rows.append(code)
print("The grid:n".format("n".join(rows)))
# Encode the message
coded_msg = ""
for col in range(square):
for row in range(square):
# The last column of the last row will throw an out of range error, so handle that
if col < len(rows[row]):
coded_msg += rows[row][col]
coded_msg += " "
return coded_msg.rstrip()
def decode(message):
square = math.sqrt(len(message))
col_count = math.ceil(square)
row_count = math.ceil(len(message) / col_count)
cols = message.split(" ")
decoded_msg = ""
for row in range(row_count):
for col in cols:
if row < len(col):
decoded_msg += col[row]
return decoded_msg
if __name__ == "__main__":
print("Gimme a message:")
in_message = input()
coded_message = encode(in_message)
print("--nSquare message:n".format(coded_message))
decoded_message = decode(coded_message)
#print("--nDecoded message:n".format(decoded_message))
print("--ninput: noutput: ".format(in_message, decoded_message))
python strings
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I am doing some python practice and wrote a square code encoder/decoder. As described in drill #4 of Programming Practice Problems, the characters of a message are written left-to-right on a square grid, and each line of the encoded message is read by going top to bottom.
I'd like some feedback on what I wrote to see if there is anything I could have done better:
import math
def encode(message):
message = message.replace(" ", "")
square = math.ceil(math.sqrt(len(message)))
# Create the "grid"
rows =
for row in range(square):
pos = row * square
code = message[pos:pos + square]
rows.append(code)
print("The grid:n".format("n".join(rows)))
# Encode the message
coded_msg = ""
for col in range(square):
for row in range(square):
# The last column of the last row will throw an out of range error, so handle that
if col < len(rows[row]):
coded_msg += rows[row][col]
coded_msg += " "
return coded_msg.rstrip()
def decode(message):
square = math.sqrt(len(message))
col_count = math.ceil(square)
row_count = math.ceil(len(message) / col_count)
cols = message.split(" ")
decoded_msg = ""
for row in range(row_count):
for col in cols:
if row < len(col):
decoded_msg += col[row]
return decoded_msg
if __name__ == "__main__":
print("Gimme a message:")
in_message = input()
coded_message = encode(in_message)
print("--nSquare message:n".format(coded_message))
decoded_message = decode(coded_message)
#print("--nDecoded message:n".format(decoded_message))
print("--ninput: noutput: ".format(in_message, decoded_message))
python strings
I am doing some python practice and wrote a square code encoder/decoder. As described in drill #4 of Programming Practice Problems, the characters of a message are written left-to-right on a square grid, and each line of the encoded message is read by going top to bottom.
I'd like some feedback on what I wrote to see if there is anything I could have done better:
import math
def encode(message):
message = message.replace(" ", "")
square = math.ceil(math.sqrt(len(message)))
# Create the "grid"
rows =
for row in range(square):
pos = row * square
code = message[pos:pos + square]
rows.append(code)
print("The grid:n".format("n".join(rows)))
# Encode the message
coded_msg = ""
for col in range(square):
for row in range(square):
# The last column of the last row will throw an out of range error, so handle that
if col < len(rows[row]):
coded_msg += rows[row][col]
coded_msg += " "
return coded_msg.rstrip()
def decode(message):
square = math.sqrt(len(message))
col_count = math.ceil(square)
row_count = math.ceil(len(message) / col_count)
cols = message.split(" ")
decoded_msg = ""
for row in range(row_count):
for col in cols:
if row < len(col):
decoded_msg += col[row]
return decoded_msg
if __name__ == "__main__":
print("Gimme a message:")
in_message = input()
coded_message = encode(in_message)
print("--nSquare message:n".format(coded_message))
decoded_message = decode(coded_message)
#print("--nDecoded message:n".format(decoded_message))
print("--ninput: noutput: ".format(in_message, decoded_message))
python strings
edited Apr 3 at 22:34
200_success
123k14142399
123k14142399
asked Apr 3 at 19:59
Spencer
1767
1767
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
In both the encoder and decoder, you append one character at a time to the resulting string using +=
. That is a bad habit for performance: since Python strings are immutable, appending a character means allocating a new string, then copying the old contents of the string plus the suffix.
These solutions can be vastly simplified using Pythonic iteration techniques.
The first trick is to note that Python strings are sequences, and therefore support slicing using the s[i:j:k]
operation to extract every kth character:
The slice of s from i to j with step k is defined as the sequence of items with index
x = i + n*k
such that0 <= n < (j-i)/k
. In other words, the indices arei
,i+k
,i+2*k
,i+3*k
and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to len(s) if they are greater. ⦠If i or j are omitted orNone
, they become âÂÂendâ values (which end depends on the sign of k).
Secondly, whenever you see a pattern like:
array =
for ⦠in â¦:
array.append(â¦)
⦠then that is an indication that you might want to use either a list comprehension or a generator expression, to define the whole array
in just one statement.
In this case, you want to join a bunch of words using a space character as a delimiter. So, you need to write it as ' '.join(some generator expression producing the columns)
.
import math
def encode(plaintext):
plaintext = plaintext.replace(" ", "")
size = math.ceil(math.sqrt(len(plaintext)))
return ' '.join(plaintext[i::size] for i in range(size))
To implement the decoder, you don't need to do any arithmetic. The trick here is to use itertools.zip_longest(*cols)
to transpose the matrix and give you the rows.
Again, I recommend using ''.join(â¦)
with some generator expressions.
from itertools import zip_longest
def decode(ciphertext):
cols = ciphertext.split(" ")
return ''.join(''.join(c for c in row if c) for row in zip_longest(*cols))
Wow, python is indeed beautiful! Fantastic answer, this teaches me a lot :)
â Spencer
Apr 4 at 16:43
Is there a reason you used "len(plaintext) ** 0.5" to get the square instead of math.sqrt(plaintext)? And sorry for the noob question but what exactly does the "*" in "*cols" do?
â Spencer
Apr 4 at 17:02
No reason for changing math.sqrt(); I've reverted it. The "splat" operator treats each element of thecols
list as a separate parameter tozip_longest()
.
â 200_success
Apr 4 at 17:17
add a comment |Â
up vote
2
down vote
Couple of pointers.
In general it's good practice to avoid putting anything other than a call to another function (such as main()
) in the if __name__ == "__main__"
function, just to aid in ease of unit testing.
Document strings for functions are also nice to have:
def foo():
'''This function does foo-all, always returns None'''
pass
A nice (ish) one liner for the decode function might be something like this:
def encode(message):
message = message.replace(" ", "")
length = math.ceil(math.sqrt(len(message)))
''.join(message[i::length] i in range(length))
Although I admit it needs a bit of refactoring as its a tad long for one line (EDIT adapted a very nice improvement from 200_success 's answer, which they explain well). It does demonstrate that you can skip building the grid though.
Thanks Drgabble! Correct me if I'm wrong, but I thought it was "cleaner" to put any "testing" code in the main block so that the functions "encode" and "decode" can just be run from another module without worrying about extra junk at runtime?
â Spencer
Apr 4 at 16:40
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
In both the encoder and decoder, you append one character at a time to the resulting string using +=
. That is a bad habit for performance: since Python strings are immutable, appending a character means allocating a new string, then copying the old contents of the string plus the suffix.
These solutions can be vastly simplified using Pythonic iteration techniques.
The first trick is to note that Python strings are sequences, and therefore support slicing using the s[i:j:k]
operation to extract every kth character:
The slice of s from i to j with step k is defined as the sequence of items with index
x = i + n*k
such that0 <= n < (j-i)/k
. In other words, the indices arei
,i+k
,i+2*k
,i+3*k
and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to len(s) if they are greater. ⦠If i or j are omitted orNone
, they become âÂÂendâ values (which end depends on the sign of k).
Secondly, whenever you see a pattern like:
array =
for ⦠in â¦:
array.append(â¦)
⦠then that is an indication that you might want to use either a list comprehension or a generator expression, to define the whole array
in just one statement.
In this case, you want to join a bunch of words using a space character as a delimiter. So, you need to write it as ' '.join(some generator expression producing the columns)
.
import math
def encode(plaintext):
plaintext = plaintext.replace(" ", "")
size = math.ceil(math.sqrt(len(plaintext)))
return ' '.join(plaintext[i::size] for i in range(size))
To implement the decoder, you don't need to do any arithmetic. The trick here is to use itertools.zip_longest(*cols)
to transpose the matrix and give you the rows.
Again, I recommend using ''.join(â¦)
with some generator expressions.
from itertools import zip_longest
def decode(ciphertext):
cols = ciphertext.split(" ")
return ''.join(''.join(c for c in row if c) for row in zip_longest(*cols))
Wow, python is indeed beautiful! Fantastic answer, this teaches me a lot :)
â Spencer
Apr 4 at 16:43
Is there a reason you used "len(plaintext) ** 0.5" to get the square instead of math.sqrt(plaintext)? And sorry for the noob question but what exactly does the "*" in "*cols" do?
â Spencer
Apr 4 at 17:02
No reason for changing math.sqrt(); I've reverted it. The "splat" operator treats each element of thecols
list as a separate parameter tozip_longest()
.
â 200_success
Apr 4 at 17:17
add a comment |Â
up vote
2
down vote
accepted
In both the encoder and decoder, you append one character at a time to the resulting string using +=
. That is a bad habit for performance: since Python strings are immutable, appending a character means allocating a new string, then copying the old contents of the string plus the suffix.
These solutions can be vastly simplified using Pythonic iteration techniques.
The first trick is to note that Python strings are sequences, and therefore support slicing using the s[i:j:k]
operation to extract every kth character:
The slice of s from i to j with step k is defined as the sequence of items with index
x = i + n*k
such that0 <= n < (j-i)/k
. In other words, the indices arei
,i+k
,i+2*k
,i+3*k
and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to len(s) if they are greater. ⦠If i or j are omitted orNone
, they become âÂÂendâ values (which end depends on the sign of k).
Secondly, whenever you see a pattern like:
array =
for ⦠in â¦:
array.append(â¦)
⦠then that is an indication that you might want to use either a list comprehension or a generator expression, to define the whole array
in just one statement.
In this case, you want to join a bunch of words using a space character as a delimiter. So, you need to write it as ' '.join(some generator expression producing the columns)
.
import math
def encode(plaintext):
plaintext = plaintext.replace(" ", "")
size = math.ceil(math.sqrt(len(plaintext)))
return ' '.join(plaintext[i::size] for i in range(size))
To implement the decoder, you don't need to do any arithmetic. The trick here is to use itertools.zip_longest(*cols)
to transpose the matrix and give you the rows.
Again, I recommend using ''.join(â¦)
with some generator expressions.
from itertools import zip_longest
def decode(ciphertext):
cols = ciphertext.split(" ")
return ''.join(''.join(c for c in row if c) for row in zip_longest(*cols))
Wow, python is indeed beautiful! Fantastic answer, this teaches me a lot :)
â Spencer
Apr 4 at 16:43
Is there a reason you used "len(plaintext) ** 0.5" to get the square instead of math.sqrt(plaintext)? And sorry for the noob question but what exactly does the "*" in "*cols" do?
â Spencer
Apr 4 at 17:02
No reason for changing math.sqrt(); I've reverted it. The "splat" operator treats each element of thecols
list as a separate parameter tozip_longest()
.
â 200_success
Apr 4 at 17:17
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
In both the encoder and decoder, you append one character at a time to the resulting string using +=
. That is a bad habit for performance: since Python strings are immutable, appending a character means allocating a new string, then copying the old contents of the string plus the suffix.
These solutions can be vastly simplified using Pythonic iteration techniques.
The first trick is to note that Python strings are sequences, and therefore support slicing using the s[i:j:k]
operation to extract every kth character:
The slice of s from i to j with step k is defined as the sequence of items with index
x = i + n*k
such that0 <= n < (j-i)/k
. In other words, the indices arei
,i+k
,i+2*k
,i+3*k
and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to len(s) if they are greater. ⦠If i or j are omitted orNone
, they become âÂÂendâ values (which end depends on the sign of k).
Secondly, whenever you see a pattern like:
array =
for ⦠in â¦:
array.append(â¦)
⦠then that is an indication that you might want to use either a list comprehension or a generator expression, to define the whole array
in just one statement.
In this case, you want to join a bunch of words using a space character as a delimiter. So, you need to write it as ' '.join(some generator expression producing the columns)
.
import math
def encode(plaintext):
plaintext = plaintext.replace(" ", "")
size = math.ceil(math.sqrt(len(plaintext)))
return ' '.join(plaintext[i::size] for i in range(size))
To implement the decoder, you don't need to do any arithmetic. The trick here is to use itertools.zip_longest(*cols)
to transpose the matrix and give you the rows.
Again, I recommend using ''.join(â¦)
with some generator expressions.
from itertools import zip_longest
def decode(ciphertext):
cols = ciphertext.split(" ")
return ''.join(''.join(c for c in row if c) for row in zip_longest(*cols))
In both the encoder and decoder, you append one character at a time to the resulting string using +=
. That is a bad habit for performance: since Python strings are immutable, appending a character means allocating a new string, then copying the old contents of the string plus the suffix.
These solutions can be vastly simplified using Pythonic iteration techniques.
The first trick is to note that Python strings are sequences, and therefore support slicing using the s[i:j:k]
operation to extract every kth character:
The slice of s from i to j with step k is defined as the sequence of items with index
x = i + n*k
such that0 <= n < (j-i)/k
. In other words, the indices arei
,i+k
,i+2*k
,i+3*k
and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to len(s) if they are greater. ⦠If i or j are omitted orNone
, they become âÂÂendâ values (which end depends on the sign of k).
Secondly, whenever you see a pattern like:
array =
for ⦠in â¦:
array.append(â¦)
⦠then that is an indication that you might want to use either a list comprehension or a generator expression, to define the whole array
in just one statement.
In this case, you want to join a bunch of words using a space character as a delimiter. So, you need to write it as ' '.join(some generator expression producing the columns)
.
import math
def encode(plaintext):
plaintext = plaintext.replace(" ", "")
size = math.ceil(math.sqrt(len(plaintext)))
return ' '.join(plaintext[i::size] for i in range(size))
To implement the decoder, you don't need to do any arithmetic. The trick here is to use itertools.zip_longest(*cols)
to transpose the matrix and give you the rows.
Again, I recommend using ''.join(â¦)
with some generator expressions.
from itertools import zip_longest
def decode(ciphertext):
cols = ciphertext.split(" ")
return ''.join(''.join(c for c in row if c) for row in zip_longest(*cols))
edited Apr 4 at 17:14
answered Apr 4 at 6:16
200_success
123k14142399
123k14142399
Wow, python is indeed beautiful! Fantastic answer, this teaches me a lot :)
â Spencer
Apr 4 at 16:43
Is there a reason you used "len(plaintext) ** 0.5" to get the square instead of math.sqrt(plaintext)? And sorry for the noob question but what exactly does the "*" in "*cols" do?
â Spencer
Apr 4 at 17:02
No reason for changing math.sqrt(); I've reverted it. The "splat" operator treats each element of thecols
list as a separate parameter tozip_longest()
.
â 200_success
Apr 4 at 17:17
add a comment |Â
Wow, python is indeed beautiful! Fantastic answer, this teaches me a lot :)
â Spencer
Apr 4 at 16:43
Is there a reason you used "len(plaintext) ** 0.5" to get the square instead of math.sqrt(plaintext)? And sorry for the noob question but what exactly does the "*" in "*cols" do?
â Spencer
Apr 4 at 17:02
No reason for changing math.sqrt(); I've reverted it. The "splat" operator treats each element of thecols
list as a separate parameter tozip_longest()
.
â 200_success
Apr 4 at 17:17
Wow, python is indeed beautiful! Fantastic answer, this teaches me a lot :)
â Spencer
Apr 4 at 16:43
Wow, python is indeed beautiful! Fantastic answer, this teaches me a lot :)
â Spencer
Apr 4 at 16:43
Is there a reason you used "len(plaintext) ** 0.5" to get the square instead of math.sqrt(plaintext)? And sorry for the noob question but what exactly does the "*" in "*cols" do?
â Spencer
Apr 4 at 17:02
Is there a reason you used "len(plaintext) ** 0.5" to get the square instead of math.sqrt(plaintext)? And sorry for the noob question but what exactly does the "*" in "*cols" do?
â Spencer
Apr 4 at 17:02
No reason for changing math.sqrt(); I've reverted it. The "splat" operator treats each element of the
cols
list as a separate parameter to zip_longest()
.â 200_success
Apr 4 at 17:17
No reason for changing math.sqrt(); I've reverted it. The "splat" operator treats each element of the
cols
list as a separate parameter to zip_longest()
.â 200_success
Apr 4 at 17:17
add a comment |Â
up vote
2
down vote
Couple of pointers.
In general it's good practice to avoid putting anything other than a call to another function (such as main()
) in the if __name__ == "__main__"
function, just to aid in ease of unit testing.
Document strings for functions are also nice to have:
def foo():
'''This function does foo-all, always returns None'''
pass
A nice (ish) one liner for the decode function might be something like this:
def encode(message):
message = message.replace(" ", "")
length = math.ceil(math.sqrt(len(message)))
''.join(message[i::length] i in range(length))
Although I admit it needs a bit of refactoring as its a tad long for one line (EDIT adapted a very nice improvement from 200_success 's answer, which they explain well). It does demonstrate that you can skip building the grid though.
Thanks Drgabble! Correct me if I'm wrong, but I thought it was "cleaner" to put any "testing" code in the main block so that the functions "encode" and "decode" can just be run from another module without worrying about extra junk at runtime?
â Spencer
Apr 4 at 16:40
add a comment |Â
up vote
2
down vote
Couple of pointers.
In general it's good practice to avoid putting anything other than a call to another function (such as main()
) in the if __name__ == "__main__"
function, just to aid in ease of unit testing.
Document strings for functions are also nice to have:
def foo():
'''This function does foo-all, always returns None'''
pass
A nice (ish) one liner for the decode function might be something like this:
def encode(message):
message = message.replace(" ", "")
length = math.ceil(math.sqrt(len(message)))
''.join(message[i::length] i in range(length))
Although I admit it needs a bit of refactoring as its a tad long for one line (EDIT adapted a very nice improvement from 200_success 's answer, which they explain well). It does demonstrate that you can skip building the grid though.
Thanks Drgabble! Correct me if I'm wrong, but I thought it was "cleaner" to put any "testing" code in the main block so that the functions "encode" and "decode" can just be run from another module without worrying about extra junk at runtime?
â Spencer
Apr 4 at 16:40
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Couple of pointers.
In general it's good practice to avoid putting anything other than a call to another function (such as main()
) in the if __name__ == "__main__"
function, just to aid in ease of unit testing.
Document strings for functions are also nice to have:
def foo():
'''This function does foo-all, always returns None'''
pass
A nice (ish) one liner for the decode function might be something like this:
def encode(message):
message = message.replace(" ", "")
length = math.ceil(math.sqrt(len(message)))
''.join(message[i::length] i in range(length))
Although I admit it needs a bit of refactoring as its a tad long for one line (EDIT adapted a very nice improvement from 200_success 's answer, which they explain well). It does demonstrate that you can skip building the grid though.
Couple of pointers.
In general it's good practice to avoid putting anything other than a call to another function (such as main()
) in the if __name__ == "__main__"
function, just to aid in ease of unit testing.
Document strings for functions are also nice to have:
def foo():
'''This function does foo-all, always returns None'''
pass
A nice (ish) one liner for the decode function might be something like this:
def encode(message):
message = message.replace(" ", "")
length = math.ceil(math.sqrt(len(message)))
''.join(message[i::length] i in range(length))
Although I admit it needs a bit of refactoring as its a tad long for one line (EDIT adapted a very nice improvement from 200_success 's answer, which they explain well). It does demonstrate that you can skip building the grid though.
edited Apr 4 at 12:12
answered Apr 3 at 23:14
Drgabble
1214
1214
Thanks Drgabble! Correct me if I'm wrong, but I thought it was "cleaner" to put any "testing" code in the main block so that the functions "encode" and "decode" can just be run from another module without worrying about extra junk at runtime?
â Spencer
Apr 4 at 16:40
add a comment |Â
Thanks Drgabble! Correct me if I'm wrong, but I thought it was "cleaner" to put any "testing" code in the main block so that the functions "encode" and "decode" can just be run from another module without worrying about extra junk at runtime?
â Spencer
Apr 4 at 16:40
Thanks Drgabble! Correct me if I'm wrong, but I thought it was "cleaner" to put any "testing" code in the main block so that the functions "encode" and "decode" can just be run from another module without worrying about extra junk at runtime?
â Spencer
Apr 4 at 16:40
Thanks Drgabble! Correct me if I'm wrong, but I thought it was "cleaner" to put any "testing" code in the main block so that the functions "encode" and "decode" can just be run from another module without worrying about extra junk at runtime?
â Spencer
Apr 4 at 16:40
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%2f191195%2fsquare-code-encode-and-decode%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