Skip to content

Commit e35f6bd

Browse files
committed
more classes
1 parent 011b01f commit e35f6bd

8 files changed

+632
-4
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ to learn more about whatever you want after studying it.
5050
18. [Modules](basics/modules.md)
5151
19. [Exceptions](basics/exceptions.md)
5252
20. [Classes](basics/classes.md)
53-
21. [Docstrings](basics/docstrings.md)
53+
21. [More Classes](basics/more-classes.md)
54+
22. [Docstrings](basics/docstrings.md)
5455

5556
### Advanced
5657

basics/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ to learn more about whatever you want after studying it.
2626
18. [Modules](modules.md)
2727
19. [Exceptions](exceptions.md)
2828
20. [Classes](classes.md)
29-
21. [Docstrings](docstrings.md)
29+
21. [More Classes](more-classes.md)
30+
22. [Docstrings](docstrings.md)
3031

3132
***
3233

basics/answers.md

+108
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,114 @@ isn't exactly like mine but it works just fine it's ok, and you can
433433
>>>
434434
```
435435
436+
437+
## More Classes
438+
439+
1. Delete all global variables, and use arguments and return values. We also
440+
need to handle the `len(words) == 0` case differently, and returning `None`
441+
makes sense now.
442+
443+
```python
444+
import random
445+
446+
447+
# returns None if the sentence contains 0 words
448+
def change_words_order(sentence):
449+
no_dots_sentence = sentence.replace('.', '')
450+
words = no_dots_sentence.split()
451+
if len(words) == 0:
452+
return None
453+
454+
lowercase_words = []
455+
for word in words:
456+
lowercase_words.append(word.lower())
457+
random.shuffle(lowercase_words)
458+
459+
# in lowercase_words[0], first character uppercase, rest lowercase
460+
# note that empty_list_or_empty_string[0] doesn't work
461+
# lowercase_words is not empty because len(words) == 0 was handled separately
462+
# lowercase_words[0] is not empty because it came from .split()
463+
lowercase_words[0] = lowercase_words[0][0].upper() + lowercase_words[0][1:]
464+
return ' '.join(lowercase_words) + '.'
465+
466+
467+
def main():
468+
print("This program changes the order of the words of a sentence randomly.")
469+
print()
470+
471+
while True:
472+
sentence = input('Enter a sentence: ')
473+
new_sentence = change_words_order(sentence)
474+
if new_sentence is not None:
475+
print(new_sentence)
476+
477+
if __name__ == '__main__':
478+
main()
479+
```
480+
481+
2. This answer doesn't contain any code because I haven't seen your
482+
program, and I don't know what your program does. You can
483+
[show your program to me](../contact-me.md) if you want to.
484+
485+
If your program is short, the cleaned program that uses arguments and
486+
return values is probably cleaner.
487+
488+
3. See 2.
489+
490+
4. One way is to replace all the allowed characters with empty strings (delete
491+
them), and see what is left. Of course, add `import string` to the beginning
492+
of the program.
493+
494+
```python
495+
bad_characters = user_name
496+
for good_character in (string.ascii_letters + string.digits + '-'):
497+
bad_characters = bad_characters.replace(good_character, '')
498+
499+
if bad_characters != '':
500+
return "Username must not contain these characters: " + bad_characters
501+
```
502+
503+
For phone numbers, you need to decide how they have to be entered. The code
504+
below accepts `xxx-xxx-xxxx`, where each `x` means a digit. The code ended
505+
up being quite long, so I put it to a separate function.
506+
507+
I'm assuming that all phone numbers are 10 digits long. This is probably
508+
wrong, and in a real program you should instead figure out what's the
509+
correct way to validate a phone number, or find someone else's code that
510+
does it correctly and use that.
511+
512+
```python
513+
def validate_phone_number(phone_number):
514+
# split 'xxx-yyy-zzzz' to ['xxx', 'yyy', 'zzzz']
515+
parts = phone_number.split('-')
516+
if len(parts) != 3:
517+
return False
518+
if len(parts[0]) != 3 or len(parts[1]) != 3 or len(parts[2]) != 4:
519+
return False
520+
521+
for part in parts:
522+
for character in part:
523+
if character not in string.digits:
524+
return False
525+
526+
return True
527+
```
528+
529+
Now you can use this function like this:
530+
531+
```python
532+
if not validate_phone_number(self.work_phone_number):
533+
return "work phone number must be entered as xxx-xxx-xxxx"
534+
if not validate_phone_number(self.personal_phone_number):
535+
return "personal phone number must be entered as xxx-xxx-xxxx"
536+
```
537+
538+
It's also important to tell the user how to enter the phone numbers.
539+
For example, you can replace `input("Work phone number: ")` with
540+
`input("Work phone number (xxx-xxx-xxxx, each x is a digit): ")` or
541+
something like that.
542+
543+
436544
***
437545
438546
If you have trouble with this tutorial please [tell me about

basics/classes.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -424,5 +424,5 @@ star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial).
424424
You may use this tutorial freely at your own risk. See
425425
[LICENSE](../LICENSE).
426426

427-
[Previous](exceptions.md) | [Next](docstrings.md) |
427+
[Previous](exceptions.md) | [Next](more-classes.md) |
428428
[List of contents](../README.md#basics)

basics/docstrings.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -226,5 +226,5 @@ star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial).
226226
You may use this tutorial freely at your own risk. See
227227
[LICENSE](../LICENSE).
228228

229-
[Previous](classes.md) | [Next](../advanced/datatypes.md) |
229+
[Previous](more-classes.md) | [Next](../advanced/datatypes.md) |
230230
[List of contents](../README.md#basics)

0 commit comments

Comments
 (0)