Why does Python allow out-of-range slice indexes for sequences?
So I just came across what seems to me like a strange Python feature and wanted some clarification about it.
The following array manipulation somewhat makes sense:
p = [1,2,3]
p[3:] = 4
p = [1,2,3,4]
I imagine it is actually just appending this value to the end, correct?
Why can I do this, however?
p[20:22] = [5,6]
p = [1,2,3,4,5,6]
And even more so this:
p[20:100] = [7,8]
p = [1,2,3,4,5,6,7,8]
This just seems like wrong logic. It seems like this should throw an error!
Any explanation?
-Is it just a weird thing Python does?
-Is there a purpose to it?
-Or am I thinking about this the wrong way?
python python-3.x sequence slice range-checking
add a comment |
So I just came across what seems to me like a strange Python feature and wanted some clarification about it.
The following array manipulation somewhat makes sense:
p = [1,2,3]
p[3:] = 4
p = [1,2,3,4]
I imagine it is actually just appending this value to the end, correct?
Why can I do this, however?
p[20:22] = [5,6]
p = [1,2,3,4,5,6]
And even more so this:
p[20:100] = [7,8]
p = [1,2,3,4,5,6,7,8]
This just seems like wrong logic. It seems like this should throw an error!
Any explanation?
-Is it just a weird thing Python does?
-Is there a purpose to it?
-Or am I thinking about this the wrong way?
python python-3.x sequence slice range-checking
add a comment |
So I just came across what seems to me like a strange Python feature and wanted some clarification about it.
The following array manipulation somewhat makes sense:
p = [1,2,3]
p[3:] = 4
p = [1,2,3,4]
I imagine it is actually just appending this value to the end, correct?
Why can I do this, however?
p[20:22] = [5,6]
p = [1,2,3,4,5,6]
And even more so this:
p[20:100] = [7,8]
p = [1,2,3,4,5,6,7,8]
This just seems like wrong logic. It seems like this should throw an error!
Any explanation?
-Is it just a weird thing Python does?
-Is there a purpose to it?
-Or am I thinking about this the wrong way?
python python-3.x sequence slice range-checking
So I just came across what seems to me like a strange Python feature and wanted some clarification about it.
The following array manipulation somewhat makes sense:
p = [1,2,3]
p[3:] = 4
p = [1,2,3,4]
I imagine it is actually just appending this value to the end, correct?
Why can I do this, however?
p[20:22] = [5,6]
p = [1,2,3,4,5,6]
And even more so this:
p[20:100] = [7,8]
p = [1,2,3,4,5,6,7,8]
This just seems like wrong logic. It seems like this should throw an error!
Any explanation?
-Is it just a weird thing Python does?
-Is there a purpose to it?
-Or am I thinking about this the wrong way?
python python-3.x sequence slice range-checking
python python-3.x sequence slice range-checking
edited 10 mins ago
Raymond Hettinger
133k39254348
133k39254348
asked 43 mins ago
Akaisteph7Akaisteph7
655
655
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
Slice logic automatically clips the indices to the length of the sequence.
Allowing slice indices to extend past end points was done for convenience. It would be a pain to have to range check every expression and then adjust the limits manually, so Python does it for you.
Consider the use case of wanting to display no more than the first 50 characters of a text message.
The easy way (what Python does now):
preview = msg[:50]
Or the hard way (do the limit checks yourself):
n = len(msg)
preview = msg[:50] if n > 50 else msg
Manually implementing that logic for adjustment of end points would be easy to forget, would be easy to get wrong (updating the 50 in two places), would be wordy, and would be slow. Python moves that logic to its internals where it is succint, automatic, fast, and correct. This is one of the reasons I love Python :-)
add a comment |
The documentation has your answer:
s[i:j]
: slice ofs
fromi
toj
(note (4))
(4) The slice of
s
fromi
toj
is defined as the sequence of items
with indexk
such thati <= k < j
. Ifi
orj
is greater than
len(s)
, uselen(s)
. Ifi
is omitted orNone
, use0
. Ifj
is omitted orNone
, uselen(s)
. Ifi
is greater than or equal to
j
, the slice is empty.
The documentation of IndexError
confirms this behavior:
exception
IndexError
Raised when a sequence subscript is out of range. (Slice indices are silently truncated to fall in the allowed range; if an index is
not an integer,TypeError
is raised.)
Essentially, stuff like p[20:100]
is being reduced to p[len(p):len(p]
. p[len(p):len(p]
is an empty slice at the end of the list, and assigning a list to it will modify the end of the list to contain said list. Thus, it works like appending/extending the original list.
This behavior is the same as what happens when you assign a list to an empty slice anywhere in the original list. For example:
In [1]: p = [1, 2, 3, 4]
In [2]: p[2:2] = [42, 42, 42]
In [3]: p
Out[3]: [1, 2, 42, 42, 42, 3, 4]
1
I don't think OP is asking how slicing works, he's asking for the rationale behind the design choice.
– Primusa
24 mins ago
@Primusa - I believe they're asking both. This explains the how, which is good to know because it explains why the behavior isn't broken. The why is probably buried in the depths of one of the mailing lists somewhere.
– g.d.d.c
20 mins ago
Good answer but this doesn't explain why the new numbers get appended to the end of the list.
– Atirag
20 mins ago
1
@Atirag I added a small blurb about it for completeness.
– Tomothy32
13 mins ago
It is a bit confusing though that p[len(p):len(p)] is empty but p[len(p)] is out of range. Following the logic from the former I would assume p[len(p)] =[c,d] would also append the values but it won't of course.
– Atirag
6 mins ago
|
show 2 more comments
[20:22]--> this way is called slicing in python
Look when you insert the value in array of python at index 20 to 22 in above case python has created indexes till to 22 but when you require it the output you will get the all numbers with series but it has created the space in array
**for example
arr = [1,2,3]
arr[9:11]=[10,11]
arr[3:8]=[4,5,6,7,8,9]
your output array will be
[1,2,3,4,5,6,7,8,9,10,11]**
New contributor
add a comment |
Presumably, you missed the around p[3:] = 4 (should be p[3:] = [4]), but that aside...
p[20:22] adds the values to the 20th, 21st and 22nd elements of the list, or the end if it is shorter.
Similarly, p[20:100] adds the values 7 and 8 at the end of your list because your list is shorter than the specified amount.
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%2f54613753%2fwhy-does-python-allow-out-of-range-slice-indexes-for-sequences%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Slice logic automatically clips the indices to the length of the sequence.
Allowing slice indices to extend past end points was done for convenience. It would be a pain to have to range check every expression and then adjust the limits manually, so Python does it for you.
Consider the use case of wanting to display no more than the first 50 characters of a text message.
The easy way (what Python does now):
preview = msg[:50]
Or the hard way (do the limit checks yourself):
n = len(msg)
preview = msg[:50] if n > 50 else msg
Manually implementing that logic for adjustment of end points would be easy to forget, would be easy to get wrong (updating the 50 in two places), would be wordy, and would be slow. Python moves that logic to its internals where it is succint, automatic, fast, and correct. This is one of the reasons I love Python :-)
add a comment |
Slice logic automatically clips the indices to the length of the sequence.
Allowing slice indices to extend past end points was done for convenience. It would be a pain to have to range check every expression and then adjust the limits manually, so Python does it for you.
Consider the use case of wanting to display no more than the first 50 characters of a text message.
The easy way (what Python does now):
preview = msg[:50]
Or the hard way (do the limit checks yourself):
n = len(msg)
preview = msg[:50] if n > 50 else msg
Manually implementing that logic for adjustment of end points would be easy to forget, would be easy to get wrong (updating the 50 in two places), would be wordy, and would be slow. Python moves that logic to its internals where it is succint, automatic, fast, and correct. This is one of the reasons I love Python :-)
add a comment |
Slice logic automatically clips the indices to the length of the sequence.
Allowing slice indices to extend past end points was done for convenience. It would be a pain to have to range check every expression and then adjust the limits manually, so Python does it for you.
Consider the use case of wanting to display no more than the first 50 characters of a text message.
The easy way (what Python does now):
preview = msg[:50]
Or the hard way (do the limit checks yourself):
n = len(msg)
preview = msg[:50] if n > 50 else msg
Manually implementing that logic for adjustment of end points would be easy to forget, would be easy to get wrong (updating the 50 in two places), would be wordy, and would be slow. Python moves that logic to its internals where it is succint, automatic, fast, and correct. This is one of the reasons I love Python :-)
Slice logic automatically clips the indices to the length of the sequence.
Allowing slice indices to extend past end points was done for convenience. It would be a pain to have to range check every expression and then adjust the limits manually, so Python does it for you.
Consider the use case of wanting to display no more than the first 50 characters of a text message.
The easy way (what Python does now):
preview = msg[:50]
Or the hard way (do the limit checks yourself):
n = len(msg)
preview = msg[:50] if n > 50 else msg
Manually implementing that logic for adjustment of end points would be easy to forget, would be easy to get wrong (updating the 50 in two places), would be wordy, and would be slow. Python moves that logic to its internals where it is succint, automatic, fast, and correct. This is one of the reasons I love Python :-)
edited 12 mins ago
answered 18 mins ago
Raymond HettingerRaymond Hettinger
133k39254348
133k39254348
add a comment |
add a comment |
The documentation has your answer:
s[i:j]
: slice ofs
fromi
toj
(note (4))
(4) The slice of
s
fromi
toj
is defined as the sequence of items
with indexk
such thati <= k < j
. Ifi
orj
is greater than
len(s)
, uselen(s)
. Ifi
is omitted orNone
, use0
. Ifj
is omitted orNone
, uselen(s)
. Ifi
is greater than or equal to
j
, the slice is empty.
The documentation of IndexError
confirms this behavior:
exception
IndexError
Raised when a sequence subscript is out of range. (Slice indices are silently truncated to fall in the allowed range; if an index is
not an integer,TypeError
is raised.)
Essentially, stuff like p[20:100]
is being reduced to p[len(p):len(p]
. p[len(p):len(p]
is an empty slice at the end of the list, and assigning a list to it will modify the end of the list to contain said list. Thus, it works like appending/extending the original list.
This behavior is the same as what happens when you assign a list to an empty slice anywhere in the original list. For example:
In [1]: p = [1, 2, 3, 4]
In [2]: p[2:2] = [42, 42, 42]
In [3]: p
Out[3]: [1, 2, 42, 42, 42, 3, 4]
1
I don't think OP is asking how slicing works, he's asking for the rationale behind the design choice.
– Primusa
24 mins ago
@Primusa - I believe they're asking both. This explains the how, which is good to know because it explains why the behavior isn't broken. The why is probably buried in the depths of one of the mailing lists somewhere.
– g.d.d.c
20 mins ago
Good answer but this doesn't explain why the new numbers get appended to the end of the list.
– Atirag
20 mins ago
1
@Atirag I added a small blurb about it for completeness.
– Tomothy32
13 mins ago
It is a bit confusing though that p[len(p):len(p)] is empty but p[len(p)] is out of range. Following the logic from the former I would assume p[len(p)] =[c,d] would also append the values but it won't of course.
– Atirag
6 mins ago
|
show 2 more comments
The documentation has your answer:
s[i:j]
: slice ofs
fromi
toj
(note (4))
(4) The slice of
s
fromi
toj
is defined as the sequence of items
with indexk
such thati <= k < j
. Ifi
orj
is greater than
len(s)
, uselen(s)
. Ifi
is omitted orNone
, use0
. Ifj
is omitted orNone
, uselen(s)
. Ifi
is greater than or equal to
j
, the slice is empty.
The documentation of IndexError
confirms this behavior:
exception
IndexError
Raised when a sequence subscript is out of range. (Slice indices are silently truncated to fall in the allowed range; if an index is
not an integer,TypeError
is raised.)
Essentially, stuff like p[20:100]
is being reduced to p[len(p):len(p]
. p[len(p):len(p]
is an empty slice at the end of the list, and assigning a list to it will modify the end of the list to contain said list. Thus, it works like appending/extending the original list.
This behavior is the same as what happens when you assign a list to an empty slice anywhere in the original list. For example:
In [1]: p = [1, 2, 3, 4]
In [2]: p[2:2] = [42, 42, 42]
In [3]: p
Out[3]: [1, 2, 42, 42, 42, 3, 4]
1
I don't think OP is asking how slicing works, he's asking for the rationale behind the design choice.
– Primusa
24 mins ago
@Primusa - I believe they're asking both. This explains the how, which is good to know because it explains why the behavior isn't broken. The why is probably buried in the depths of one of the mailing lists somewhere.
– g.d.d.c
20 mins ago
Good answer but this doesn't explain why the new numbers get appended to the end of the list.
– Atirag
20 mins ago
1
@Atirag I added a small blurb about it for completeness.
– Tomothy32
13 mins ago
It is a bit confusing though that p[len(p):len(p)] is empty but p[len(p)] is out of range. Following the logic from the former I would assume p[len(p)] =[c,d] would also append the values but it won't of course.
– Atirag
6 mins ago
|
show 2 more comments
The documentation has your answer:
s[i:j]
: slice ofs
fromi
toj
(note (4))
(4) The slice of
s
fromi
toj
is defined as the sequence of items
with indexk
such thati <= k < j
. Ifi
orj
is greater than
len(s)
, uselen(s)
. Ifi
is omitted orNone
, use0
. Ifj
is omitted orNone
, uselen(s)
. Ifi
is greater than or equal to
j
, the slice is empty.
The documentation of IndexError
confirms this behavior:
exception
IndexError
Raised when a sequence subscript is out of range. (Slice indices are silently truncated to fall in the allowed range; if an index is
not an integer,TypeError
is raised.)
Essentially, stuff like p[20:100]
is being reduced to p[len(p):len(p]
. p[len(p):len(p]
is an empty slice at the end of the list, and assigning a list to it will modify the end of the list to contain said list. Thus, it works like appending/extending the original list.
This behavior is the same as what happens when you assign a list to an empty slice anywhere in the original list. For example:
In [1]: p = [1, 2, 3, 4]
In [2]: p[2:2] = [42, 42, 42]
In [3]: p
Out[3]: [1, 2, 42, 42, 42, 3, 4]
The documentation has your answer:
s[i:j]
: slice ofs
fromi
toj
(note (4))
(4) The slice of
s
fromi
toj
is defined as the sequence of items
with indexk
such thati <= k < j
. Ifi
orj
is greater than
len(s)
, uselen(s)
. Ifi
is omitted orNone
, use0
. Ifj
is omitted orNone
, uselen(s)
. Ifi
is greater than or equal to
j
, the slice is empty.
The documentation of IndexError
confirms this behavior:
exception
IndexError
Raised when a sequence subscript is out of range. (Slice indices are silently truncated to fall in the allowed range; if an index is
not an integer,TypeError
is raised.)
Essentially, stuff like p[20:100]
is being reduced to p[len(p):len(p]
. p[len(p):len(p]
is an empty slice at the end of the list, and assigning a list to it will modify the end of the list to contain said list. Thus, it works like appending/extending the original list.
This behavior is the same as what happens when you assign a list to an empty slice anywhere in the original list. For example:
In [1]: p = [1, 2, 3, 4]
In [2]: p[2:2] = [42, 42, 42]
In [3]: p
Out[3]: [1, 2, 42, 42, 42, 3, 4]
edited 10 mins ago
answered 26 mins ago
Tomothy32Tomothy32
5,7501425
5,7501425
1
I don't think OP is asking how slicing works, he's asking for the rationale behind the design choice.
– Primusa
24 mins ago
@Primusa - I believe they're asking both. This explains the how, which is good to know because it explains why the behavior isn't broken. The why is probably buried in the depths of one of the mailing lists somewhere.
– g.d.d.c
20 mins ago
Good answer but this doesn't explain why the new numbers get appended to the end of the list.
– Atirag
20 mins ago
1
@Atirag I added a small blurb about it for completeness.
– Tomothy32
13 mins ago
It is a bit confusing though that p[len(p):len(p)] is empty but p[len(p)] is out of range. Following the logic from the former I would assume p[len(p)] =[c,d] would also append the values but it won't of course.
– Atirag
6 mins ago
|
show 2 more comments
1
I don't think OP is asking how slicing works, he's asking for the rationale behind the design choice.
– Primusa
24 mins ago
@Primusa - I believe they're asking both. This explains the how, which is good to know because it explains why the behavior isn't broken. The why is probably buried in the depths of one of the mailing lists somewhere.
– g.d.d.c
20 mins ago
Good answer but this doesn't explain why the new numbers get appended to the end of the list.
– Atirag
20 mins ago
1
@Atirag I added a small blurb about it for completeness.
– Tomothy32
13 mins ago
It is a bit confusing though that p[len(p):len(p)] is empty but p[len(p)] is out of range. Following the logic from the former I would assume p[len(p)] =[c,d] would also append the values but it won't of course.
– Atirag
6 mins ago
1
1
I don't think OP is asking how slicing works, he's asking for the rationale behind the design choice.
– Primusa
24 mins ago
I don't think OP is asking how slicing works, he's asking for the rationale behind the design choice.
– Primusa
24 mins ago
@Primusa - I believe they're asking both. This explains the how, which is good to know because it explains why the behavior isn't broken. The why is probably buried in the depths of one of the mailing lists somewhere.
– g.d.d.c
20 mins ago
@Primusa - I believe they're asking both. This explains the how, which is good to know because it explains why the behavior isn't broken. The why is probably buried in the depths of one of the mailing lists somewhere.
– g.d.d.c
20 mins ago
Good answer but this doesn't explain why the new numbers get appended to the end of the list.
– Atirag
20 mins ago
Good answer but this doesn't explain why the new numbers get appended to the end of the list.
– Atirag
20 mins ago
1
1
@Atirag I added a small blurb about it for completeness.
– Tomothy32
13 mins ago
@Atirag I added a small blurb about it for completeness.
– Tomothy32
13 mins ago
It is a bit confusing though that p[len(p):len(p)] is empty but p[len(p)] is out of range. Following the logic from the former I would assume p[len(p)] =[c,d] would also append the values but it won't of course.
– Atirag
6 mins ago
It is a bit confusing though that p[len(p):len(p)] is empty but p[len(p)] is out of range. Following the logic from the former I would assume p[len(p)] =[c,d] would also append the values but it won't of course.
– Atirag
6 mins ago
|
show 2 more comments
[20:22]--> this way is called slicing in python
Look when you insert the value in array of python at index 20 to 22 in above case python has created indexes till to 22 but when you require it the output you will get the all numbers with series but it has created the space in array
**for example
arr = [1,2,3]
arr[9:11]=[10,11]
arr[3:8]=[4,5,6,7,8,9]
your output array will be
[1,2,3,4,5,6,7,8,9,10,11]**
New contributor
add a comment |
[20:22]--> this way is called slicing in python
Look when you insert the value in array of python at index 20 to 22 in above case python has created indexes till to 22 but when you require it the output you will get the all numbers with series but it has created the space in array
**for example
arr = [1,2,3]
arr[9:11]=[10,11]
arr[3:8]=[4,5,6,7,8,9]
your output array will be
[1,2,3,4,5,6,7,8,9,10,11]**
New contributor
add a comment |
[20:22]--> this way is called slicing in python
Look when you insert the value in array of python at index 20 to 22 in above case python has created indexes till to 22 but when you require it the output you will get the all numbers with series but it has created the space in array
**for example
arr = [1,2,3]
arr[9:11]=[10,11]
arr[3:8]=[4,5,6,7,8,9]
your output array will be
[1,2,3,4,5,6,7,8,9,10,11]**
New contributor
[20:22]--> this way is called slicing in python
Look when you insert the value in array of python at index 20 to 22 in above case python has created indexes till to 22 but when you require it the output you will get the all numbers with series but it has created the space in array
**for example
arr = [1,2,3]
arr[9:11]=[10,11]
arr[3:8]=[4,5,6,7,8,9]
your output array will be
[1,2,3,4,5,6,7,8,9,10,11]**
New contributor
New contributor
answered 25 mins ago
Muhammad Moid ShamsMuhammad Moid Shams
1
1
New contributor
New contributor
add a comment |
add a comment |
Presumably, you missed the around p[3:] = 4 (should be p[3:] = [4]), but that aside...
p[20:22] adds the values to the 20th, 21st and 22nd elements of the list, or the end if it is shorter.
Similarly, p[20:100] adds the values 7 and 8 at the end of your list because your list is shorter than the specified amount.
add a comment |
Presumably, you missed the around p[3:] = 4 (should be p[3:] = [4]), but that aside...
p[20:22] adds the values to the 20th, 21st and 22nd elements of the list, or the end if it is shorter.
Similarly, p[20:100] adds the values 7 and 8 at the end of your list because your list is shorter than the specified amount.
add a comment |
Presumably, you missed the around p[3:] = 4 (should be p[3:] = [4]), but that aside...
p[20:22] adds the values to the 20th, 21st and 22nd elements of the list, or the end if it is shorter.
Similarly, p[20:100] adds the values 7 and 8 at the end of your list because your list is shorter than the specified amount.
Presumably, you missed the around p[3:] = 4 (should be p[3:] = [4]), but that aside...
p[20:22] adds the values to the 20th, 21st and 22nd elements of the list, or the end if it is shorter.
Similarly, p[20:100] adds the values 7 and 8 at the end of your list because your list is shorter than the specified amount.
answered 13 mins ago
hd1hd1
24.5k35568
24.5k35568
add a comment |
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%2f54613753%2fwhy-does-python-allow-out-of-range-slice-indexes-for-sequences%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