From 1bacc91b456461d62753751732e3cbcd66f617b5 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 09:25:12 +0200 Subject: [PATCH 01/78] updating make-html.py --- basics/getting-started.md | 2 +- make-html.py | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/basics/getting-started.md b/basics/getting-started.md index 57c0e97..e52c8a3 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -63,7 +63,7 @@ worked just fine. Later we'll learn what `(3, 14)` is. ## Using Python as a calculator ```diff --WARNING: This part contains boring math. Be careful! +-WARNING: This part contains boring math. Be careful!- ``` Let's type some math stuff into Python and see what it does. diff --git a/make-html.py b/make-html.py index 0a06260..af6ce35 100755 --- a/make-html.py +++ b/make-html.py @@ -135,8 +135,29 @@ def block_code(self, code, lang=None): formatter = pygments.formatters.HtmlFormatter( style=self.pygments_style, noclasses=True) return pygments.highlight(code, lexer, formatter) - # we can't highlight it - return super().block_code(code, lang) + + elif lang == 'diff': + # http://stackoverflow.com/a/39413824 + result = [] + for line in code.split('\n'): + line = line.strip() + if not line: + continue + + if line.startswith('+'): + result.append('

%s

' + % line.strip('+')) + elif line.startswith('-'): + result.append('

%s

' + % line.strip('-')) + else: + result.append('

%s

' % line) + + return '\n'.join(result) + + else: + # we can't highlight it + return super().block_code(code, lang) def image(self, src, title, text): """Return an image inside a link.""" From 0fde0eb3e429aee127250942e783af247a2a2fa2 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 09:27:01 +0200 Subject: [PATCH 02/78] little tweaks --- basics/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/getting-started.md b/basics/getting-started.md index e52c8a3..fbc1595 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -63,7 +63,7 @@ worked just fine. Later we'll learn what `(3, 14)` is. ## Using Python as a calculator ```diff --WARNING: This part contains boring math. Be careful!- +---------- WARNING: This part contains boring math. Be careful! ---------- ``` Let's type some math stuff into Python and see what it does. From a03a2020457e142b8cc4660202e7accfb38476d3 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 09:33:17 +0200 Subject: [PATCH 03/78] more comment stuff --- basics/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/basics/getting-started.md b/basics/getting-started.md index fbc1595..150960f 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -139,8 +139,8 @@ back to `>>>` when we press Enter again. ## Summary -[comment]: # (the first line in this summary is exactly same as in -what-is-programming.md, and it's supposed to be like this) +[comment]: # (the first line in this summary is exactly same as in) +[comment]: # (what-is-programming.md, and it's supposed to be like this) - Error messages are our friends. - We can enter any Python commands to the interactive `>>>` prompt, and From b4b951f9d110cd413be6bb809b2a7659f7c698d9 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 11:25:19 +0200 Subject: [PATCH 04/78] fix weird ordering crap --- basics/getting-started.md | 50 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/basics/getting-started.md b/basics/getting-started.md index 150960f..52d7eb0 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -60,6 +60,31 @@ We didn't get an error... but `(3, 14)` is not at all what we expected! So from now on, let's use a dot with decimal numbers, because `3.14` worked just fine. Later we'll learn what `(3, 14)` is. +## Comments + +We can also type a `#` and then whatever we want after that. These bits +of text are known as **comments**, and we'll find uses for them later. + +```python +>>> 1 + 2 # can you guess what the result is? +3 +>>> +``` + +Again, I put a space after the `#` and multiple spaces before it just to +make things easier to read. + +If we write comment on a line with no code on it, the prompt changes +from `>>>` to `...`. To be honest, I have no idea why it does that and I +think it would be better if it would just stay as `>>>`. The prompt goes +back to `>>>` when we press Enter again. + +```python +>>> # hello there +... +>>> +``` + ## Using Python as a calculator ```diff @@ -112,31 +137,6 @@ time you don't need them. Actually you don't need even these calculations most of the time, but these calculations are probably enough when you need to calculate something. -## Comments - -We can also type a `#` and then whatever we want after that. These bits -of text are known as **comments**, and we'll find uses for them later. - -```python ->>> 1 + 2 # can you guess what the result is? -3 ->>> -``` - -Again, I put a space after the `#` and multiple spaces before it just to -make things easier to read. - -If we write comment on a line with no code on it, the prompt changes -from `>>>` to `...`. To be honest, I have no idea why it does that and I -think it would be better if it would just stay as `>>>`. The prompt goes -back to `>>>` when we press Enter again. - -```python ->>> # hello there -... ->>> -``` - ## Summary [comment]: # (the first line in this summary is exactly same as in) From ddd21492b3056ffc45ed92bf01ae3777ee26bf4a Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 11:39:07 +0200 Subject: [PATCH 05/78] make-html.py stuff --- html-style.css | 4 ++-- make-html.py | 29 ++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/html-style.css b/html-style.css index e2e9337..b9524a9 100644 --- a/html-style.css +++ b/html-style.css @@ -1,9 +1,9 @@ /* This file is used by the HTML files that make-html.py creates. Customize this if you want to create HTML files with different - colors. See also make-html.py's --pygments-theme option. */ + colors. See also make-html.py's --pygments-style option. */ body { color: white; - background-color: #333333; + background-color: #222222; } a { color: orange; diff --git a/make-html.py b/make-html.py index af6ce35..a15343d 100755 --- a/make-html.py +++ b/make-html.py @@ -49,7 +49,9 @@ try: import pygments.formatters import pygments.lexers + import pygments.style import pygments.styles + import pygments.token except ImportError: # we can work without pygments, but we won't get colors pygments = None @@ -57,6 +59,18 @@ import common +if pygments is not None: + class TutorialStyle(pygments.style.Style): + background_color = '#111111' + styles = { + pygments.token.Comment: 'italic #336666', + pygments.token.Keyword: 'bold #6699cc', + pygments.token.Name.Builtin: '#9966ff', + pygments.token.String: '#ffff33', + pygments.token.Name.Exception: 'bold #ff0000', + } + + HTML_TEMPLATE = """\ @@ -129,9 +143,9 @@ def block_code(self, code, lang=None): if lang == 'python' and pygments is not None: # we can highlight it if code.startswith('>>> '): - lexer = pygments.lexers.PythonConsoleLexer() + lexer = pygments.lexers.PythonConsoleLexer(python3=True) else: - lexer = pygments.lexers.PythonLexer() + lexer = pygments.lexers.Python3Lexer() formatter = pygments.formatters.HtmlFormatter( style=self.pygments_style, noclasses=True) return pygments.highlight(code, lexer, formatter) @@ -198,10 +212,10 @@ def main(): help="write the HTML files here, defaults to %(default)r") if pygments is not None: parser.add_argument( - '--pygments-style', metavar='STYLE', default='native', + '--pygments-style', metavar='STYLE', default=TutorialStyle, choices=list(pygments.styles.get_all_styles()), help=("the Pygments color style (see above), " - "%(default)r by default")) + "defaults to a custom style")) args = parser.parse_args() if pygments is None: @@ -215,6 +229,7 @@ def main(): if not common.askyesno("Continue without pygments?"): print("Interrupt.") return + args.pygments_style = None if os.path.exists(args.outdir): if not common.askyesno("%s exists. Do you want to remove it?" @@ -228,8 +243,8 @@ def main(): print("Generating HTML files...") for markdownfile in common.get_markdown_files(): - fixed_markdownfile = fix_filename(markdownfile) - htmlfile = posixpath.join(args.outdir, fixed_markdownfile) + fixed_file = fix_filename(markdownfile) + htmlfile = posixpath.join(args.outdir, fixed_file) print(' %-30.30s --> %-30.30s' % (markdownfile, htmlfile), end='\r') with common.slashfix_open(markdownfile, 'r') as f: @@ -237,7 +252,7 @@ def main(): renderer = TutorialRenderer(args.pygments_style) body = mistune.markdown(markdown, renderer=renderer) stylefile = posixpath.relpath( - 'style.css', posixpath.dirname(fixed_markdownfile)) + 'style.css', posixpath.dirname(fixed_file)) html = HTML_TEMPLATE.format( title=renderer.title, From e8bb94d1ec0fa4bb988d2e9fba252b72cb8592fe Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 11:45:00 +0200 Subject: [PATCH 06/78] important fixes --- basics/classes.md | 119 ++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 61 deletions(-) diff --git a/basics/classes.md b/basics/classes.md index 50649b1..b0b35b6 100644 --- a/basics/classes.md +++ b/basics/classes.md @@ -5,10 +5,6 @@ tkinter GUI's before I understood how they work. Everything I did with classes worked, but I didn't understand how. Hopefully you'll first learn to understand classes, and then learn to use them. -This tutorial assumes that you know [how functions work](using-functions.md) -and [how to create your own functions](defining-functions.md). If you -don't I highly recommend learning that first, and then moving to classes. - ## Why should I use custom classes in my projects? Python comes with a lot of classes that you are already familiar with. @@ -89,34 +85,34 @@ names for your classes. Now we can make a Website instance by calling the class. ```python ->>> stackoverflow = Website() ->>> stackoverflow +>>> github = Website() +>>> github <__main__.Website object at 0x7f36e4c456d8> ->>> type(stackoverflow) +>>> type(github) >>> ``` -We can say that `stackoverflow` is "a Website instance", "a Website +We can say that `github` is "a Website instance", "a Website object" or "a Website". All of these mean the same thing. -Now we can attach more information about stackoverflow to our Website. +Now we can attach more information about github to our Website. ```python ->>> stackoverflow.url = 'http://stackoverflow.com/' ->>> stackoverflow.founding_year = 2008 ->>> stackoverflow.free_to_use = True +>>> github.url = 'https://github.com/' +>>> github.founding_year = 2008 +>>> github.free_to_use = True >>> ``` We can also access the information easily. ```python ->>> stackoverflow.url -'http://stackoverflow.com/' ->>> stackoverflow.founding_year +>>> github.url +'https://github.com/' +>>> github.founding_year 2008 ->>> stackoverflow.free_to_use +>>> github.free_to_use True >>> ``` @@ -153,10 +149,10 @@ recommended to use it for code that needs to be reliable, but it's a handy way to see which attributes the instance contains. ```python ->>> stackoverflow.__dict__ +>>> github.__dict__ {'free_to_use': True, 'founding_year': 2008, - 'url': 'http://stackoverflow.com/'} + 'url': 'https://github.com/'} >>> effbot.__dict__ {} >>> @@ -177,7 +173,7 @@ True Seems to be working, but what happened to the instances? ```python ->>> stackoverflow.is_online +>>> github.is_online True >>> effbot.is_online True @@ -185,17 +181,17 @@ True ``` What was that? Setting `Website.is_online` to a value also set -`stackoverflow.is_online` and `effbot.is_online` to that value! +`github.is_online` and `effbot.is_online` to that value! -Actually, `is_online` is still not in stackoverflow's or effbot's -`__dict__`. stackoverflow and effbot get that attribute directly from +Actually, `is_online` is still not in github's or effbot's +`__dict__`. github and effbot get that attribute directly from the `Website` class. ```python ->>> stackoverflow.__dict__ +>>> github.__dict__ {'free_to_use': True, 'founding_year': 2008, - 'url': 'http://stackoverflow.com/'} + 'url': 'https://github.com/'} >>> effbot.__dict__ {} >>> @@ -203,13 +199,14 @@ the `Website` class. `Website.is_online` is `Website`'s class attribute, and in Python you can access class attributes through instances also, so in this case -`stackoverflow.is_online` points to `Website.is_online`. That can be +`github.is_online` points to `Website.is_online`. That can be confusing, which is why it's not recommended to use class attributes like -this. Use instance attributes instead, e.g. `stackoverflow.is_online = True`. +this. Use instance attributes instead, e.g. `github.is_online = True`. ## Functions and methods -Let's define a function that prints information about a website. +Let's [define a function](defining-functions.md) that prints information +about a website. ```python >>> def website_info(website): @@ -217,8 +214,8 @@ Let's define a function that prints information about a website. ... print("Founding year:", website.founding_year) ... print("Free to use:", website.free_to_use) ... ->>> website_info(stackoverflow) -URL: http://stackoverflow.com/ +>>> website_info(github) +URL: https://github.com/ Founding year: 2008 Free to use: True >>> @@ -230,49 +227,49 @@ Website class? ```python >>> Website.info = website_info ->>> Website.info(stackoverflow) -URL: http://stackoverflow.com/ +>>> Website.info(github) +URL: https://github.com/ Founding year: 2008 Free to use: True >>> ``` -It's working, but `Website.info(stackoverflow)` is a lot of typing, so -wouldn't `stackoverflow.info()` be much better? +It's working, but `Website.info(github)` is a lot of typing, so +wouldn't `github.info()` be much better? ```python ->>> stackoverflow.info() -URL: http://stackoverflow.com/ +>>> github.info() +URL: https://github.com/ Founding year: 2008 Free to use: True >>> ``` -What the heck happened? We didn't define a `stackoverflow.info`, it just +What the heck happened? We didn't define a `github.info`, it just magically worked! -`Website.info` is our `website_info` function, so `stackoverflow.info` +`Website.info` is our `website_info` function, so `github.info` should also be the same function. But `Website.info` takes a `website` -argument, which we didn't give it when we called `stackoverflow.info()`! +argument, which we didn't give it when we called `github.info()`! -But is `stackoverflow.info` the same thing as `Website.info`? +But is `github.info` the same thing as `Website.info`? ```python >>> Website.info ->>> stackoverflow.info +>>> github.info > >>> ``` It's not. -Instead, `stackoverflow.info` is a **method**. If we set a function as a +Instead, `github.info` is a **method**. If we set a function as a class attribute, the instances will have a method with the same name. Methods are "links" to the class attribute functions. So -`Website.info(stackoverflow)` does the same thing as `stackoverflow.info()`, -and when `stackoverflow.info()` is called it automatically gets -`stackoverflow` as an argument. +`Website.info(github)` does the same thing as `github.info()`, +and when `github.info()` is called it automatically gets +`github` as an argument. In other words, **`Class.method(instance)` does the same thing as `instance.method()`**. This also works with built-in classes, for @@ -285,23 +282,23 @@ it later? ```python >>> class Website: -... def info(self): # self will be stackoverflow +... def info(self): # self will be github ... print("URL:", self.url) ... print("Founding year:", self.founding_year) ... print("Free to use:", self.free_to_use) ... ->>> stackoverflow = Website() ->>> stackoverflow.url = 'http://stackoverflow.com/' ->>> stackoverflow.founding_year = 2008 ->>> stackoverflow.free_to_use = True ->>> stackoverflow.info() -URL: http://stackoverflow.com/ +>>> github = Website() +>>> github.url = 'https://github.com/' +>>> github.founding_year = 2008 +>>> github.free_to_use = True +>>> github.info() +URL: https://github.com/ Founding year: 2008 Free to use: True >>> ``` -It's working. The `self` argument in `Website.info` was `stackoverflow`. +It's working. The `self` argument in `Website.info` was `github`. You could call it something else too such as `me`, `this` or `instance`, but use `self` instead. Other Python users have gotten used to it, and the official style guide recommens it also. @@ -320,10 +317,10 @@ Maybe we could add a method to do that? ... print("Founding year:", self.founding_year) ... print("Free to use:", self.free_to_use) ... ->>> stackoverflow = Website() ->>> stackoverflow.initialize('http://stackoverflow.com/', 2008, True) ->>> stackoverflow.info() -URL: http://stackoverflow.com/ +>>> github = Website() +>>> github.initialize('https://github.com/', 2008, True) +>>> github.info() +URL: https://github.com/ Founding year: 2008 Free to use: True >>> @@ -331,9 +328,9 @@ Free to use: True That works. The attributes we defined in the initialize method are also available in the info method. We could also access them directly from -`stackoverflow`, for example with `stackoverflow.url`. +`github`, for example with `github.url`. -But we still need to call `stackoverflow.initialize`. In Python, there's +But we still need to call `github.initialize`. In Python, there's a "magic" method that runs when we create a new Website by calling the Website class. It's called `__init__` and it does nothing by default. If our `__init__` method takes other arguments than self we can call the @@ -350,9 +347,9 @@ class with arguments and they will be given to `__init__`. Like this: ... print("Founding year:", self.founding_year) ... print("Free to use:", self.free_to_use) ... ->>> stackoverflow = Website('http://stackoverflow.com/', 2008, True) ->>> stackoverflow.info() -URL: http://stackoverflow.com/ +>>> github = Website('https://github.com/', 2008, True) +>>> github.info() +URL: https://github.com/ Founding year: 2008 Free to use: True >>> From 4255b8ad077cd6fbff997469d1338561ed489f6b Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 11:55:17 +0200 Subject: [PATCH 07/78] oops --- advanced/functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advanced/functions.md b/advanced/functions.md index ff097ae..d48dcc0 100644 --- a/advanced/functions.md +++ b/advanced/functions.md @@ -222,7 +222,7 @@ moving file1.txt to file2.txt Oh crap, that's not what we wanted at all. We have just lost the original `file2.txt`! -The problem was that now `overwrite` was `'file2.txt'`, and the +The problem was that now `overwrite` was `'file3.txt'`, and the `if overwrite` part [treated the string as True](../basics/what-is-true.md) and deleted the file. That's not nice. From 4613129b461e0d2900d7a0eed4e92bab0f079ade Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 11:58:01 +0200 Subject: [PATCH 08/78] explicit is better than implicit --- advanced/functions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/advanced/functions.md b/advanced/functions.md index d48dcc0..6accb1e 100644 --- a/advanced/functions.md +++ b/advanced/functions.md @@ -34,7 +34,7 @@ wherever the function is called: ```python def login(): ... - return username, password + return (username, password) username, password = login() @@ -55,7 +55,7 @@ def get_new_info(username): password = input("New password: ") fullname = input("Full name: ") phonenumber = input("Phone number: ") - return username, password, fullname, phonenumber + return (username, password, fullname, phonenumber) ``` ...you could do this: From 20ba81b2c7a9723cc6fb3a0d487a02aa4717b748 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 12:09:11 +0200 Subject: [PATCH 09/78] empty lines --- basics/larger-program.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/basics/larger-program.md b/basics/larger-program.md index 4b88be1..521cf3c 100644 --- a/basics/larger-program.md +++ b/basics/larger-program.md @@ -74,6 +74,7 @@ and then testing and fixing. Here are my versions of them: def ask_questions(answers): correct = [] wrong = [] + for question, answer in answers.items(): if input(question + ' = ').strip() == answer: print("Correct!") @@ -81,19 +82,26 @@ def ask_questions(answers): else: print("Wrong! The correct answer is %s." % answer) wrong.append(question) + return (correct, wrong) + def stats(correct, wrong, answers): print("\n**** STATS ****\n") print("You answered", len(correct), "questions correctly and", len(wrong), "questions wrong.") + if wrong: print("These would have been the correct answers:") for question in wrong: print(' ', question, '=', answers[question]) ``` -Let's try them out. +Note that these functions have some empty lines in them and there are +two empty lines between the functions. This makes the code a bit longer, +but it's a lot easier to read this way. + +Let's try out the functions. ```python >>> answers = read_questions('questions.txt') @@ -165,9 +173,11 @@ def read_questions(filename): answers[question.strip()] = answer.strip() return answers + def ask_questions(answers): correct = [] wrong = [] + for question, answer in answers.items(): if input('%s = ' % question).strip() == answer: print("Correct!") @@ -175,17 +185,21 @@ def ask_questions(answers): else: print("Wrong! The correct answer is %s." % answer) wrong.append(question) + return (correct, wrong) + def stats(correct, wrong, answers): print("\n**** STATS ****\n") print("You answered", len(correct), "questions correctly and", len(wrong), "questions wrong.") + if wrong: print("These would have been the correct answers:") for question in wrong: print(' ', question, '=', answers[question]) + def main(): filename = input("Name of the question file: ") answers = read_questions(filename) From 729d2818b0597f143fbdb826b9bd80ffd5f6ba78 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 14:45:51 +0200 Subject: [PATCH 10/78] way better link checker --- advanced/datatypes.md | 2 +- linkcheck.py | 116 +++++++++++++++++++++++++++++++----------- 2 files changed, 86 insertions(+), 32 deletions(-) diff --git a/advanced/datatypes.md b/advanced/datatypes.md index 12a670f..1a67a99 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -55,7 +55,7 @@ True We can also convert anything [iterable](../basics/loops.md#summary) to a set [by calling the -class](../basics/classes.md#why-should-I-use-custom-classes-in-my-projects). +class](../basics/classes.md#why-should-i-use-custom-classes-in-my-projects). ```python >>> set('hello') diff --git a/linkcheck.py b/linkcheck.py index 4b271ef..35ced72 100755 --- a/linkcheck.py +++ b/linkcheck.py @@ -38,7 +38,7 @@ [some website](http://github.com/) [another website](https://github.com/) - [local header](#some-header) + [local link](#some-title) """ import os @@ -47,7 +47,7 @@ import common -def check(filepath, target): +def check(this_file, target, title, titledict): """Check if a link's target is like it should be. Return an error message string or "ok". @@ -57,45 +57,99 @@ def check(filepath, target): # be added later. return "ok" - if '#' in target: - where = target.index('#') - if where == 0: - # It's a link to a title in the same file, we need to skip it. - return "ok" - target = target[:where] + path = posixpath.join(posixpath.dirname(this_file), target) + path = posixpath.normpath(path) + real_path = common.slashfix(path) - path = posixpath.join(posixpath.dirname(filepath), target) - realpath = common.slashfix(path) - if not os.path.exists(realpath): + if not os.path.exists(real_path): return "doesn't exist" + if target.endswith('/'): # A directory. - if os.path.isdir(realpath): - return "ok" - return "not a directory" + if not os.path.isdir(real_path): + return "not a directory" else: # A file. - if os.path.isfile(realpath): - return "ok" - return "not a file" + if not os.path.isfile(real_path): + return "not a file" + + if title is not None and title not in titledict[path]: + return "no title named %s" % title + return "ok" + + +def find_titles(filename): + """Read titles of a markdown file and return a list of them.""" + result = [] + + with common.slashfix_open(filename, 'r') as f: + for line in f: + if line.startswith('```'): + # it's a code block, let's skip to the end of it to + # avoid detecting comments as titles + while f.readline().rstrip() != '```': + pass + if line.startswith('#'): + # found a title + result.append(common.header_link(line.lstrip('#').strip())) + + return result + + +def find_links(this_file): + """Read links of a markdown file. + + Return a list of (target, title, lineno) pairs where title can be None. + """ + result = [] + + with common.slashfix_open(this_file, 'r') as f: + for match, lineno in common.find_links(f): + target = match.group(2) + if '#' in target: + file, title = target.split('#', 1) + if not file: + # link to this file, [blabla](#hi) + file = posixpath.basename(this_file) + else: + file = target + title = None + + result.append((file, title, lineno)) + + return result + + +def get_line(filename, lineno): + """Return the lineno'th line of a file.""" + with common.slashfix_open(filename, 'r') as f: + for lineno2, line in enumerate(f, start=1): + if lineno == lineno2: + return line + raise ValueError("%s is less than %d lines long" % (filename, lineno)) def main(): - print("Searching and checking links...") - broken = 0 - total = 0 + print("Searching for titles and links...") + titledict = {} # {filename: [title1, title2, ...]} + linkdict = {} # {filename: [(file, title, lineno), ...]) for path in common.get_markdown_files(): - with common.slashfix_open(path, 'r') as f: - for match, lineno in common.find_links(f): - text, target = match.groups() - status = check(path, target) - if status != "ok": - # The .group(0) is not perfect, but it's good enough. - print(" file %s, line %d: %s" % (path, lineno, status)) - print(" " + match.group(0)) - print() - broken += 1 - total += 1 + titledict[path] = find_titles(path) + linkdict[path] = find_links(path) + + print("Checking the links...") + total = 0 + broken = 0 + + for filename, linklist in linkdict.items(): + for target, title, lineno in linklist: + status = check(filename, target, title, titledict) + if status != "ok": + print(" file %s, line %d: %s" % (filename, lineno, status)) + print(" %s" % get_line(filename, lineno)) + broken += 1 + total += 1 + print("%d/%d links seem to be broken." % (broken, total)) From f7fe8755f4d037f3e75d2219da1633be2a32b195 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Mar 2017 15:12:25 +0200 Subject: [PATCH 11/78] small things --- advanced/datatypes.md | 2 +- basics/classes.md | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/advanced/datatypes.md b/advanced/datatypes.md index 1a67a99..824f209 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -55,7 +55,7 @@ True We can also convert anything [iterable](../basics/loops.md#summary) to a set [by calling the -class](../basics/classes.md#why-should-i-use-custom-classes-in-my-projects). +class](../basics/classes.md#what-are-classes). ```python >>> set('hello') diff --git a/basics/classes.md b/basics/classes.md index b0b35b6..ac6b2bf 100644 --- a/basics/classes.md +++ b/basics/classes.md @@ -1,13 +1,13 @@ -# Defining and using custom classes in Python +# Defining and using custom classes When I was getting started in Python I learned to make classes for tkinter GUI's before I understood how they work. Everything I did with classes worked, but I didn't understand how. Hopefully you'll first learn to understand classes, and then learn to use them. -## Why should I use custom classes in my projects? +## What are classes? -Python comes with a lot of classes that you are already familiar with. +Python comes with many classes that we know already. ```python >>> str @@ -51,11 +51,11 @@ We can also get an instance's class with `type()`: >>> ``` -Let's say you make a program that processes data about websites. With a -custom class, you're not limited to `str`, `int` and other classes -Python comes with. Instead you can define a Website class, and make -Websites and process information about websites directly. Defining your -own object types like this is called **object-orientated programming**. +Let's say that we make a program that processes data about websites. +With a custom class, we're not limited to `str`, `int` and other classes +Python comes with. Instead we can define a Website class, and make +Websites and process information about websites directly. Defining our +own types like this is called **object-orientated programming**. ## First class From df1066c21df9e1e5b8ec664d2a3de5a34ce9117f Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 1 Apr 2017 19:41:19 +0300 Subject: [PATCH 12/78] some day gonna drop the way of the program thingy --- TODO.md | 3 ++ basics/getting-started.md | 61 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/TODO.md b/TODO.md index 6cca320..53b2bc3 100644 --- a/TODO.md +++ b/TODO.md @@ -35,6 +35,9 @@ This tutorial is not complete. It still needs: - "What the heck is this?" section for stuff i haven't talked about - regexes +- add a screenshot about geany's running settings to + basics/editor-setup.md + *** If you have trouble with this tutorial please [tell me about diff --git a/basics/getting-started.md b/basics/getting-started.md index 52d7eb0..1fd40d9 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -62,8 +62,9 @@ worked just fine. Later we'll learn what `(3, 14)` is. ## Comments -We can also type a `#` and then whatever we want after that. These bits -of text are known as **comments**, and we'll find uses for them later. +**Comments are text that does nothing.** They can be created by typing a +`#` and then some text after it, and they are useful when our code would +be hard to understand without them. ```python >>> 1 + 2 # can you guess what the result is? @@ -74,7 +75,7 @@ of text are known as **comments**, and we'll find uses for them later. Again, I put a space after the `#` and multiple spaces before it just to make things easier to read. -If we write comment on a line with no code on it, the prompt changes +If we write a comment on a line with no code on it, the prompt changes from `>>>` to `...`. To be honest, I have no idea why it does that and I think it would be better if it would just stay as `>>>`. The prompt goes back to `>>>` when we press Enter again. @@ -85,6 +86,56 @@ back to `>>>` when we press Enter again. >>> ``` +## Strings + +Strings are small pieces of text that we can use in our programs. We can +create strings by simply writing some text in quotes. + +```python +>>> 'hello' +'hello' +>>> 'this is a test' +'this is a test' +>>> +``` + +String's can also be written using "double quotes" instead of 'single quotes'. +This is useful when the string needs to contain single quotes. + +```python +>>> "hello there" +'hello there' +>>> "it's sunny" +"it's sunny" +>>> +``` + +It's also possible to add single quotes and double quotes into the same +string, but most of the time we don't need to do that so I'm not going +to talk about it now. + +It doesn't matter which quotes you use when the string doesn't need to +contain any quotes. If you think that one of the quote types looks nicer +than the other or you find it faster to type, go ahead and use that. + +Strings can be joined together easily with `+` or repeated with `*`: + +```python +>>> "hello" + "world" +'helloworld' +>>> "hello" * 3 +'hellohellohello' +>>> +``` + +Note that a `#` inside a string doesn't create a comment. + +```python +>>> "strings can contain # characters" +'strings can contain # characters' +>>> +``` + ## Using Python as a calculator ```diff @@ -146,7 +197,9 @@ enough when you need to calculate something. - We can enter any Python commands to the interactive `>>>` prompt, and it will echo back the result. - `+`, `-`, `*` and `/` work in Python just like in math. -- Pieces of text starting with a `#` are comments. +- Pieces of text starting with a `#` are comments and pieces of text in + quotes are strings. +- You can use single quotes and double quotes however you want. *** From 6aff76f416ce96d4629e7031e22c01c86248acaf Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 1 Apr 2017 20:55:16 +0300 Subject: [PATCH 13/78] stuffs --- README.md | 22 ++++++++++++++-------- basics/lists-and-tuples.md | 4 ---- basics/loops.md | 4 ---- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 3fa6ac2..e8fc469 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,25 @@ # Python programming tutorial -This is a Python 3 programming tutorial for beginners. If you have never -programmed before click [here](basics/what-is-programming.md) to find -out what programming is like and get started. +This is a concise Python 3 programming tutorial for people who think +that reading is boring. I try to show everything with simple code +examples; there are no long and complicated explanations with fancy +words. If you have never programmed before click +[here](basics/what-is-programming.md) to find out what programming is +like and get started. This tutorial is aimed at people with no programming experience at all or very little programming experience. If you have programmed a lot in the past using some other language you may want to read [the official tutorial](https://docs.python.org/3/tutorial/) instead. -You can use Python 3.2 or any newer Python with this tutorial. Don't use -Python 2. If you write a Python 2 program now someone will need to port -it to Python 3 later, so it's best to just write Python 3 to begin with. -Python 3 code will work just fine in Python 4, so you don't need to -worry about that. +You can use Python 3.3 or any newer Python with this tutorial. **Don't +use Python 2.** If you write a Python 2 program now someone will need to +convert it to Python 3 later, so it's best to just write Python 3 to +begin with. Python 3 code will work just fine in Python 4, so you don't +need to worry about that. Python 2 also has horrible +[Unicode](http://www.unicode.org/standard/WhatIsUnicode.html) problems, +so it's difficult to write Python 2 code that works correctly with +non-English characters (like π and ♫). ## List of contents diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index 6726a46..5a5ed36 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -230,10 +230,6 @@ like this: ![Different lists.](../images/differentlist.png) -If you're using Python 3.2 or older you need to do `a[:]` instead -of `a.copy()`. `a[:]` is a slice of the whole list, just like -`a[0:]`. - ## Tuples Tuples are a lot like lists, but they're immutable so they diff --git a/basics/loops.md b/basics/loops.md index 9a72b90..3c99707 100644 --- a/basics/loops.md +++ b/basics/loops.md @@ -300,10 +300,6 @@ Or if we just want to clear a list, we can use the `clear` >>> ``` -If you're using Python 3.2 or older you need to use `stuff[:]` instead -of `stuff.copy()` and `stuff[:] = []` instead of `stuff.clear()`. -`stuff[:]` is a slice of the whole list, just like `stuff[0:]`. - ## Summary - A loop means repeating something multiple times. From 824fffb20c19e5918727a5350a3aa5bd73140188 Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 5 Apr 2017 22:00:29 +0300 Subject: [PATCH 14/78] reading is boring --- basics/what-is-programming.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/basics/what-is-programming.md b/basics/what-is-programming.md index e02a853..ce917a5 100644 --- a/basics/what-is-programming.md +++ b/basics/what-is-programming.md @@ -135,8 +135,10 @@ have learned, and create something with it. ## But reading is boring! -Yes, I know. You can just try the code examples yourself and read the -rest of this tutorial only if you don't understand the code. +This chapter is probably the most boring chapter in the whole tutorial. +Other chapters contain much less text and much more code. You can also +get pretty far by just reading the code, and then reading the text only +if you don't understand the code. ## Summary From 89b17d24f2509bec5a0859e759cbeffb40b5e4f7 Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 5 Apr 2017 22:02:14 +0300 Subject: [PATCH 15/78] explaining pass thanks Esxiel --- basics/classes.md | 3 +++ basics/defining-functions.md | 11 ++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/basics/classes.md b/basics/classes.md index ac6b2bf..f53b45b 100644 --- a/basics/classes.md +++ b/basics/classes.md @@ -77,6 +77,9 @@ Let's use it to define an empty class. >>> ``` +The `pass` is needed here, just like [when defining functions that do +nothing](defining-functions.md#first-functions). + Note that I named the class `Website`, not `website`. This way we know that it's a class. Built-in classes use lowercase names (like `str` instead of `Str`) because they are faster to type, but use CapsWord diff --git a/basics/defining-functions.md b/basics/defining-functions.md index b17b28b..9e52e68 100644 --- a/basics/defining-functions.md +++ b/basics/defining-functions.md @@ -68,9 +68,14 @@ Let's use it to define a function that does nothing. >>> ``` -Seems to be working so far, we have a function. Actually it's just -a value that is assigned to a variable called `do_nothing`. Let's see -what happens if we call it. +Seems to be working so far, we have a function. It's just a value that +is assigned to a variable called `do_nothing`. + +The `pass` is needed here because without it, Python doesn't know when +the function ends and it gives us a syntax error. We don't need the +`pass` when our functions contain something else. + +Let's see what happens if we call our function. ```python >>> do_nothing() From bd21f17059a43df06c666362df31f2bc472939aa Mon Sep 17 00:00:00 2001 From: Akuli Date: Thu, 6 Apr 2017 22:07:29 +0300 Subject: [PATCH 16/78] explaining function stuff --- basics/defining-functions.md | 78 ++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/basics/defining-functions.md b/basics/defining-functions.md index 9e52e68..cee0d60 100644 --- a/basics/defining-functions.md +++ b/basics/defining-functions.md @@ -44,9 +44,9 @@ In this tutorial we'll learn to define a `print_box` function that prints text in a box. We can write the code for printing the box once, and then use it multiple times anywhere in the program. -Dividing a long program into simple functions also makes the code -easier to work with. If there's a problem with the code we can -test the functions one by one and find the problem easily. +[Dividing a long program into simple functions](larger-program.md) also +makes the code easier to work with. If there's a problem with the code +we can test the functions one by one and find the problem easily. ## First functions @@ -69,7 +69,8 @@ Let's use it to define a function that does nothing. ``` Seems to be working so far, we have a function. It's just a value that -is assigned to a variable called `do_nothing`. +is assigned to a variable called `do_nothing`. You can ignore the +`0xblablabla` stuff for now. The `pass` is needed here because without it, Python doesn't know when the function ends and it gives us a syntax error. We don't need the @@ -181,15 +182,15 @@ integer because immutable values cannot be modified in-place. Fortunately, Python will tell us if something's wrong. ```python ->>> foo = 1 ->>> def bar(): -... foo += 1 +>>> thing = 1 +>>> def stuff(): +... thing += 1 ... ->>> bar() +>>> stuff() Traceback (most recent call last): File "", line 1, in - File "", line 2, in bar -UnboundLocalError: local variable 'foo' referenced before assignment + File "", line 2, in stuff +UnboundLocalError: local variable 'thing' referenced before assignment >>> ``` @@ -288,8 +289,8 @@ def print_box(message, character): print(character * len(message)) ``` -Then we could change our existing code to always call `print_box` with -a star as the second argument: +Then we could change our code to always call `print_box` with a star as +the second argument: ```python print_box("Hello World", "*") @@ -360,11 +361,11 @@ need to: ## Output The built-in input function [returns a value](using-functions.md#return-values). -Can our function return a value also? +Can our function return a value too? ```python ->>> def times_two(x): -... return x * 2 +>>> def times_two(thing): +... return thing * 2 ... >>> times_two(3) 6 @@ -417,7 +418,7 @@ None ## Return or print? -There's two ways to output information from functions. They can print +There are two ways to output information from functions. They can print something or they can return something. So, should we print or return? Most of the time **returning makes functions much easier to use**. Think @@ -440,6 +441,47 @@ hi >>> ``` +## Common problems + +Functions are easy to understand, but you need to pay attention to how +you're calling them. Note that `some_function` and `some_function()` do +two completely different things. + +```python +>>> def say_hi(): +... print("howdy hi") +... +>>> say_hi # just checking what it is, doesn't run anything + +>>> say_hi() # this runs it +howdy hi +>>> +``` + +Typing `say_hi` just gives us the value of the `say_hi` variable, which +is the function we defined. But `say_hi()` **calls** that function, so +it runs and gives us a return value. The return value is None so the +`>>>` prompt [doesn't show it](#variables.md#none). + +But we know that the print function shows None, so what happens if we +wrap the whole thing in `print()`? + +```python +>>> print(say_hi) # prints the function, just like plain say_hi + +>>> print(say_hi()) # runs the function and then prints the return value +howdy hi +None +>>> +``` + +The `print(say_hi())` thing looks a bit weird at first, but it's easy to +understand. There's a print insnde `say_hi` and there's also the print +we just wrote, so two things are printed. Python first ran `say_hi()`, +and it returned None so Python did `print(None)`. Adding an extra +`print()` around a function call is actually a common mistake, and I +have helped many people with this problem. + ## Examples Ask yes/no questions. @@ -468,7 +510,7 @@ def ask_until_correct(prompt, correct_options, while True: answer = input(prompt + ' ') if answer in correct_options: - return answer # returning ends the function + return answer print(error_message) @@ -494,6 +536,8 @@ print("Your favorite color is %s!" % choice) function does. Returning also ends the function immediately. - Return a value instead of printing it if you need to do something with it after calling the function. +- Remember that `thing`, `thing()`, `print(thing)` and `print(thing())` + do different things. ## Exercises From 28d5779c81ed817e011111e314da3026b8d0c932 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 7 Apr 2017 23:10:06 +0300 Subject: [PATCH 17/78] small stuff --- basics/modules.md | 11 +++++++++-- getting-help.md | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/basics/modules.md b/basics/modules.md index b9e3e00..44cacba 100644 --- a/basics/modules.md +++ b/basics/modules.md @@ -53,6 +53,11 @@ All of these `.py` files can be imported like we just imported so we can use its randint variable with `random.randint` after importing it. +You're probably wondering how a computer can generate random numbers. +The random module does different things on different operating systems, +but on most systems it reads random noise that several programs on the +computer produce and creates random numbers based on that. + ## Where do modules come from? Create a `random.py` file with the following content: @@ -97,7 +102,7 @@ AttributeError: 'module' object has no attribute 'randint' >>> ``` -So first of all, what is that random variable? +So first of all, what is that `random` variable? ```python >>> random @@ -285,7 +290,7 @@ The official documentation for the time module is >>> time.time() # return time in seconds since beginning of the year 1970 1474896325.2394648 >>> time.strftime('%d.%m.%Y %H:%M:%S') # format current time nicely -'26.09.2016 16:33:58' +'07.04.2017 19:08:33' >>> ``` @@ -482,6 +487,8 @@ section at the bottom. - Python comes with many modules, and we can install even more modules if we want to. +**TODO:** exercises + *** If you have trouble with this tutorial please [tell me about diff --git a/getting-help.md b/getting-help.md index 11cd9dd..6080b67 100644 --- a/getting-help.md +++ b/getting-help.md @@ -5,7 +5,7 @@ places to ask for help in. ## IRC -IRC is the oldest chatting service I know, but as of 2016, it's still +IRC is the oldest chatting service I know, but as of 2017, it's still in use, and a great way to get help in Python. You don't need to register anywhere, just click one of the links below and you're good to go. From 4a9810550abd3b8b2f3a8ee2efc17a96bc1ba614 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 19 May 2017 15:00:03 +0300 Subject: [PATCH 18/78] 1 + 2*3 and some other stuff --- basics/getting-started.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/basics/getting-started.md b/basics/getting-started.md index 1fd40d9..5f482d3 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -99,8 +99,8 @@ create strings by simply writing some text in quotes. >>> ``` -String's can also be written using "double quotes" instead of 'single quotes'. -This is useful when the string needs to contain single quotes. +Strings can also be written with "double quotes" instead of 'single +quotes'. This is useful when we need to put quotes inside the string. ```python >>> "hello there" @@ -183,6 +183,15 @@ and `)` also work the same way. >>> ``` +You can also leave out spaces to show what's calculated first. Python +ignores it, but our code will be easier to read for people. + +```python +>>> 1 + 2*3 # now it looks like 2*3 is calculated first +7 +>>> +``` + Python also supports many other kinds of calculations, but most of the time you don't need them. Actually you don't need even these calculations most of the time, but these calculations are probably From aa7a962d136d7032a0c5f13b002852c72e7107b3 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 26 May 2017 14:15:10 +0300 Subject: [PATCH 19/78] examples for neutralboy :) --- basics/loops.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/basics/loops.md b/basics/loops.md index 9a72b90..01b9d57 100644 --- a/basics/loops.md +++ b/basics/loops.md @@ -381,7 +381,13 @@ while True: option = input("Choose an option: ") # Things like option == 0 don't work because option is a string - # and it needs to be compared with a string. + # and it needs to be compared with a string: + # >>> 0 == 0 + # True + # >>> '0' == '0' + # True + # >>> 0 == '0' + # False if option == '0': print("Bye!") break From 2129673d8e052cedb58045f73fa89049c08163e3 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 26 May 2017 19:42:46 +0300 Subject: [PATCH 20/78] thanks pb122-two --- basics/answers.md | 9 +++++++-- basics/lists-and-tuples.md | 13 +++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/basics/answers.md b/basics/answers.md index e4a313d..e05d77d 100644 --- a/basics/answers.md +++ b/basics/answers.md @@ -158,7 +158,12 @@ isn't exactly like mine but it works just fine it's ok, and you can ## Lists and tuples -1. When we run the program we get a weird error: +1. Look carefully. The `namelist` is written in `()` instead of `[]`, + so it's actually a tuple, not a list. Using confusing variable names + is of course a bad idea, but you shouldn't be surprised if someone + is doing that. Replace the `()` with `[]` and the code will work. + +2. When we run the program we get a weird error: Hello! Enter your name: my name @@ -189,7 +194,7 @@ isn't exactly like mine but it works just fine it's ok, and you can Python created a tuple automatically, but that's not what we wanted. If we remove the comma, everything works just fine. -2. Again, the code gives us a weird error message. +3. Again, the code gives us a weird error message. Enter your name: my name Traceback (most recent call last): diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index 5a5ed36..f19fcfe 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -320,7 +320,16 @@ else: ## Exercises -1. Fix this program. +1. Fix this program: + + ```python + namelist = ('wub_wub', 'RubyPinch', 'go|dfish', 'Nitori') + namelist.append('Akuli') + if 'Akuli' in namelist: + print("Now I know Akuli!") + ``` + +2. Fix this program. ```python print("Hello!") @@ -328,7 +337,7 @@ else: print("Your name is " + name + ".") ``` -2. Fix this program. +3. Fix this program. ```python namelist = ['wub_wub', 'RubyPinch', 'go|dfish', 'Nitori'] From d9ba3d8b9b854346126ed46bda9818454e907d00 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 26 May 2017 19:45:01 +0300 Subject: [PATCH 21/78] thanks pb122-two :) --- basics/lists-and-tuples.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index f19fcfe..4b9d194 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -324,8 +324,8 @@ else: ```python namelist = ('wub_wub', 'RubyPinch', 'go|dfish', 'Nitori') - namelist.append('Akuli') - if 'Akuli' in namelist: + namelist.append('pb122-two') + if 'pb122-two' in namelist: print("Now I know Akuli!") ``` From da21d3a612347810db65610e859f9e8b691e19ce Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 26 May 2017 19:46:59 +0300 Subject: [PATCH 22/78] horrible mistake :( --- basics/lists-and-tuples.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index 4b9d194..fa651b6 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -324,8 +324,8 @@ else: ```python namelist = ('wub_wub', 'RubyPinch', 'go|dfish', 'Nitori') - namelist.append('pb122-two') - if 'pb122-two' in namelist: + namelist.append('pb122') + if 'pb122' in namelist: print("Now I know Akuli!") ``` From 6bafc6876bb867b15406e3f6caef49dae9051291 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 26 May 2017 19:48:19 +0300 Subject: [PATCH 23/78] horrible mistake #2 --- basics/lists-and-tuples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index fa651b6..77ea0ca 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -326,7 +326,7 @@ else: namelist = ('wub_wub', 'RubyPinch', 'go|dfish', 'Nitori') namelist.append('pb122') if 'pb122' in namelist: - print("Now I know Akuli!") + print("Now I know pb122!") ``` 2. Fix this program. From fdd3d7ef22fbd14f2d5197caae43118ff7696d98 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 18 Jun 2017 00:55:10 +0300 Subject: [PATCH 24/78] learn to count to 3 --- basics/dicts.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/basics/dicts.md b/basics/dicts.md index ec4bf7e..093b1fb 100644 --- a/basics/dicts.md +++ b/basics/dicts.md @@ -111,10 +111,10 @@ Dictionaries have some similarities with lists. For example, both lists and dictionaries have a length. ```python ->>> len(names_and_pets) # contains two elements -2 ->>> len(favorite_pets) # contains two key:value pairs -2 +>>> len(names_and_pets) # contains three elements +3 +>>> len(favorite_pets) # contains three key:value pairs +3 >>> ``` From 7f3972c8148897f569254caa49e74b5832814bc3 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 24 Jun 2017 20:22:36 +0300 Subject: [PATCH 25/78] docstring tutorial for zaab1t --- README.md | 1 + advanced/datatypes.md | 2 +- basics/README.md | 1 + basics/classes.md | 2 +- basics/docstrings.md | 228 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 basics/docstrings.md diff --git a/README.md b/README.md index e8fc469..feef6cc 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ to learn more about whatever you want after studying it. 18. [Modules](basics/modules.md) 19. [Exceptions](basics/exceptions.md) 20. [Classes](basics/classes.md) +21. [Docstrings](basics/docstrings.md) ### Advanced diff --git a/advanced/datatypes.md b/advanced/datatypes.md index 824f209..7dd7574 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -398,5 +398,5 @@ star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See [LICENSE](../LICENSE). -[Previous](../basics/classes.md) | [Next](functions.md) | +[Previous](../basics/docstrings.md) | [Next](functions.md) | [List of contents](../README.md#advanced) diff --git a/basics/README.md b/basics/README.md index 283cc57..24f8547 100644 --- a/basics/README.md +++ b/basics/README.md @@ -26,6 +26,7 @@ to learn more about whatever you want after studying it. 18. [Modules](modules.md) 19. [Exceptions](exceptions.md) 20. [Classes](classes.md) +21. [Docstrings](docstrings.md) *** diff --git a/basics/classes.md b/basics/classes.md index f53b45b..aac9139 100644 --- a/basics/classes.md +++ b/basics/classes.md @@ -424,5 +424,5 @@ star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See [LICENSE](../LICENSE). -[Previous](exceptions.md) | [Next](../advanced/datatypes.md) | +[Previous](exceptions.md) | [Next](docstrings.md) | [List of contents](../README.md#basics) diff --git a/basics/docstrings.md b/basics/docstrings.md new file mode 100644 index 0000000..b75adc3 --- /dev/null +++ b/basics/docstrings.md @@ -0,0 +1,228 @@ +# Help and Docstrings + +In this tutorial we have used `help()` a few times. It's great and you +can use it as much as you want to. For example, running `help(str)` +displays a nice list of all string methods and explanations of what they +do, and `help(list.extend)` explains what extending something to a list +does. + +You can get help of many other things too. For example: + +```python +>>> stuff = [] +>>> help(stuff.append) +Help on built-in function append: + +append(object, /) method of builtins.list instance + Append object to the end of the list. + +>>> help(print) +Help on built-in function print in module builtins: + +print(...) + print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) + + Prints the values to a stream, or to sys.stdout by default. + Optional keyword arguments: + ... +``` + +## Docstrings + +Let's see what happens if we [define a function](defining-functions.md) +and call `help()` on that. + +```python +>>> def thing(stuff): +... return stuff * 2 +... +>>> help(thing) +Help on function thing in module __main__: + +thing(stuff) +>>> +``` + +That sucked! We have no idea about what it does based on this. All we +know is that it takes a `thing` argument. + +This is when documentation strings or docstrings come in. All we need to +do is to add a string to the beginning of our function and it will show +up in `help(the_function)`. Like this: + +```python +>>> def thing(stuff): +... "hello there" +... return stuff * 2 +... +>>> help(thing) +Help on function thing in module __main__: + +thing(stuff) + hello there +``` + +Note that docstrings are not comments. If you add a `# comment` to the +beginning of the function it won't show up in `help()`. + +## Multi-line strings + +When we did `help(print)`, we got more than one line of help. Maybe we +could do that in our own docstring too? + +```python +>>> def thing(): +... "This thing does stuff.\n\nIt always returns None." +... +>>> help(thing) +Help on function thing in module __main__: + +thing() + This thing does stuff. + + It always returns None. +>>> +``` + +That's better, but how what if we want to do 5 lines of prints? Our +`"stuff\n\nstuff\nstuff"` thing would be really long and hard to work +with. But Python has multi-line strings too. They work like this: + +```python +>>> """bla bla bla +... +... bla bla +... bla bla bla""" +'bla bla bla\n\nbla bla\nbla bla bla' +>>> +``` + +So we can write documented functions like this: + +```python +>>> def thing(): +... """This thing does stuff. +... +... It always returns None. +... """ +... +>>> help(thing) +Help on function thing in module __main__: + +thing() + This thing does stuff. + + It always returns None. + +>>> +``` + +It's recommended to always use `"""strings like this"""` for docstrings, +even if the docstring is only one line long. This way it's easy to add +more stuff to it later. + +## Documenting other stuff + +Docstrings aren't actually limited to functions. You can use them for +documenting [classes](classes.md) and their methods too. For example, +let's make a file like this and save it to `test.py`: + +```python +"""A test module. + +It contains a class and a function. +""" + + +class Thing: + """This is a test class.""" + + def thingy(self): + """This is a test method.""" + print("hello") + + +def do_hello(): + """This is a test function.""" + thing = Thing() + thing.thingy() +``` + +Then we can import it and call help on it: + +```python +>>> import test +>>> help(test) +Help on module testie: + +NAME + testie - A test module. + +DESCRIPTION + It contains a class and a function. + +CLASSES + builtins.object + Thing + + class Thing(builtins.object) + | This is a test class. + | + | Methods defined here: + | + | thingy(self) + | This is a test method. + | + | ---------------------------------------------------------------------- + | Data descriptors defined here: + | + | __dict__ + | dictionary for instance variables (if defined) + | + | __weakref__ + | list of weak references to the object (if defined) + +FUNCTIONS + do_hello() + This is a test function. + +FILE + /home/akuli/testie.py +``` + +That's pretty cool. We just added docstrings to our code and Python made +this thing out of it. + +You might be wondering what `__weakref__` is. You don't need to care +about it, and I think it would be better if `help()` would hide it. + +## When should we use docstrings? + +Always use docstrings when writing code that other people will import. +The `help()` function is awesome, so it's important to make sure it's +actually helpful. + +If your code is not meant to be imported, docstrings are usually a good +idea anyway. Other people reading your code will understand what it's +doing without having to read through all of the code. + +## Summary + +- `help()` is awesome. +- A `"""triple-quoted string"""` string in the beginning of a function, + class or file is a docstring. It shows up in `help()`. +- Docstrings are not comments. +- Usually it's a good idea to add docstrings everywhere + +*** + +If you have trouble with this tutorial please [tell me about +it](../contact-me.md) and I'll make this tutorial better. If you +like this tutorial, please [give it a +star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). + +You may use this tutorial freely at your own risk. See +[LICENSE](../LICENSE). + +[Previous](classes.md) | [Next](../advanced/datatypes.md) | +[List of contents](../README.md#basics) From 9ef7bd366ce27a532b5fe3f239add10d6986c664 Mon Sep 17 00:00:00 2001 From: Akuli Date: Thu, 6 Jul 2017 21:18:17 +0300 Subject: [PATCH 26/78] remove old poop and add in something not so poop --- basics/editor-setup.md | 234 +++++++---------------------------------- 1 file changed, 38 insertions(+), 196 deletions(-) diff --git a/basics/editor-setup.md b/basics/editor-setup.md index cf09f2f..32286a5 100644 --- a/basics/editor-setup.md +++ b/basics/editor-setup.md @@ -14,224 +14,66 @@ like automatically displaying different things with different colors. If you are on Windows or Mac OSX you have probably noticed that your Python came with an editor called IDLE. We are not going to use it because it's lacking some important features, and most experienced -programmers (including me) don't use it or recommend it to anyone. +programmers (including me) don't use it or recommend it. -In this chapter we'll download, install, set up and learn to use a -better editor. The setup part will take some time, but it's worth it and -correct settings will help you avoid many problems later. +## Which editor? -## Which editor should I use? +The choice of an editor is a very personal thing. There are many +editors, and most programmers have a favorite editor that they use for +everything and recommend to everyone. -These instructions are written for an editor called Geany. Its default -settings are actually not very good for writing Python code, but you -will learn to change the settings so you won't have trouble with -switching to another editor later if you need to. +If you aren't sure about which editor you should use, I recommend +Porcupine. It's a simple editor I wrote in Python; it lets you edit +files and it doesn't have too many other featues. [Install it with these +instructions](https://github.com/Akuli/porcupine/wiki/Installing-and-Running-Porcupine), +and then [learn to use it by writing the classic Hello World +program](https://github.com/Akuli/porcupine/wiki/First-Program). Then +you can [skip the rest of this chapter](TODO). -Different programmers have different favorite editors that they use, and -the choice of editor is a very personal thing. You can use almost any -editor you want if you make sure that you change its settings the same -way we change Geany's settings in this tutorial. +Note that most other editors come with settings that are not suitable +for writing Python code. **TODO:** *add a link to the old editor setup +tutorial here* -## Bad editors - -**[Skip this part](#installing-your-new-editor) if you are going to use -Geany.** - -But some editors are not good enough for actually making something with -them. These editors cannot be set up using these instructions because -they don't have some of the features we need, so **don't use these -editors for writing Python**: +Most of these editors are lacking some important features, they have so +many features that they would confuse you or they aren't free. You can +use these editors if you like them, but **I dont recommend these editors +for getting started with programming**: +- Emacs - Gedit - IDLE - Nano +- NetBeans - Notepad - Pluma -- Wingware - -On the other hand, some editors have too many features for getting -started with programming. They are not bad, but they are not meant for -beginners. So **I don't recommend using these editors yet**: - -- Emacs -- NetBeans - PyCharm - Spyder - Vim +- Wingware -These lists don't contain all bad editors, but these are editors that +This list doesn't contain all bad editors, but these are editors that people often try to use. If you know a bad editor and you think I should mention it here, please [let me know](../contact-me.md). -## Installing your new editor - -Installing Geany is easy. If you are using Windows or Mac OSX, go to -[the official Geany download -page](http://www.geany.org/Download/Releases) and click the correct -download link. If you are using Linux, just install Geany from the -package manager like any other program. For example, on Debian-based -distributions (e.g. Ubuntu) you can type `sudo apt install geany` on a -terminal. - -When you have Geany installed, you can launch it like any other program. -By default, it has a big sidebar and bottom area, but we don't need them -so you can start by dragging them away. Geany should look roughly like -this after that: - -![Geany without the sidebar and bottom area.](../images/geany.png) - -## Dark background - -Geany has a white background by default, but we'll tell Geany to use a -black background instead. Your eyes will thank you for doing this when -you have been programming for a few hours. - -1. Click *Edit* at top and click *Preferences*. -2. Click *Editor* at left. -3. Click *Display* at top right. -4. Check *Invert syntax highlighting colors*. -5. Click *OK*. - -If you don't like the colors, you can install more [color -schemes](https://github.com/geany/geany-themes/) and then go to *View* -at top and click *Change Color Scheme*. - -## Opening and saving files - -Now it's time to create our first file. Geany creates a new file when -you open it for the first time, but it doesn't know that it's going to -be a Python file. We need to tell that to Geany by saving the file -first. You can use the *File* menu at top or the buttons below the -menus, just like in most other programs. +## Editor or `>>>` prompt? -Save the empty file on your desktop as `test.py`. The `.py` at the end -of the name is important, it tells Geany and other programs that it's a -Python file. +So far we have used the `>>>` prompt for everything. But now we also +have an editor that lets us write longer programs. So why not just +always use the editor? -## Automatic tab expanding +The `>>>` prompt is meant to be used for experimenting with things. For +example, if you want to know what `"hello" + 123` does, just open the +prompt and run it. -Open a Python file in your editor. Then press the tab key, and the -cursor should move right. Now press the left arrow key. See how the -cursor jumps over the empty space? The empty space is actually a tab -character, but Python's style guide recommends using four spaces instead -of tab characters so we'll need to change Geany's settings. +If you want to write something once and then run it many times, write +the code to a file. For example, if you want to make a program that asks +the user to enter a word and then echoes it back, write a program that +does that in a file and run it as many times as you want to. -1. Click *Edit* at top, then click Preferences. -2. Click *Editor* at left. -3. Click *Indentation* at top. -4. Select *Spaces* instead of *Tabs*. -5. Click *OK*. -6. Click *Project* at top and click *Apply Default Indentation*. - -Delete the whitespace, then press tab and press the arrow left again. -Now the cursor should move one space at a time. - -**TODO:** animated gifs that show what's going on. - -## Stripping spaces when pressing Enter - -Press Tab and then press Enter, and Geany should add spaces to the new -line automatically for you. If you are not using Geany, make sure that -your editor does this too. - -Now press the arrow up and then move left and right. You'll notice that -the previous line has spaces left over on it. Leaving useless spaces to -ends of lines like this is usually considered bad style, but it's easy -to tell Geany to get rid of them: - -1. Click *Edit* at top and click *Preferences* -2. Click *Editor* at left. -3. Click *Features* at top. -4. Check *Newline strips trailing spaces*. -5. Click *OK*. - -Press tab and Enter again. If you go back to the previous line now there -is no whitespace on it. - -**TODO:** again, animated gifs - -## Maximum line length - -You have probably noticed that Geany displays a thin, green-ish line at -right from where you type. The idea is that you should avoid writing -anything longer than where this line is. Your programs will work if they -contain lines that go past this marker, but it's not recommended because -shorter lines are nicer to work with in general. People with small -screens can work with your code, and people with large screens can have -multiple files opened at the same time. - -By default, there's room for 72 characters before the marker. Staying in -72 characters is not always easy, and that's why Python's style guide -recommends 79 instead of 72. Let's move Geany's marker to 79 characters: - -1. Click *Edit* at top and click *Preferences* -2. Click *Editor* at left. -3. Click *Display* at top. -4. Change 72 to 79. -5. Click *OK*. - -## Running things from the editor - -This setting up stuff is boring! Let's write some code. - -We'll use this program to check if our editor is set up correctly. -Create a new file and type this into it: - -```python -import sys -print(sys.version) -``` - -You don't need to understand this program yet, you'll learn what it does -later in this tutorial. You can type this program on the `>>>` prompt to -see what it does if you want to. - -Now save the program somewhere as `test.py`. It doesn't matter what the -name of the file is, but it needs to end with `.py`. This way Geany -knows that it's a Python file. - -Next we'll need to change Geany's settings so that it runs the program -correctly. You need to have a Python file opened to change these -settings. - -1. Click *Build* at top, then click *Set Build Commands*. -2. The *Execute* command is probably `python "%f"`. Change it to - `py "%f"` if you are using Windows and `python3 "%f"` if you are - using Linux or Mac OSX. -3. Click *OK*. - -Note that the first part of our *Execute* is the same thing [we type on -a PowerShell or terminal](installing-python.md#running-python). Actually -the whole command means "run this file using my Python". - -Now press the F5 key at the top of your keyboard to run the file we -wrote. It should open up in a terminal or command prompt and print the -same Python version as the `>>>` prompt prints when we open it. If the -version starts with 2 it's too old, and you can [ask -me](../contact-me.md) or some other experienced programmer for help. - -## Important notes - -Now your editor is ready to go. There are a couple important things that -you need to keep in mind when reading the rest of this tutorial: - -- When a code example starts with `>>>`, type it to the `>>>` prompt. If - it doesn't, create or open a `.py` file with your editor, type the - code into it and run the file. -- When we type some code to the `>>>` prompt it [echoes back the - result](getting-started.md) [when it's not None](variables.md#none), - but code in a file does nothing to the result. For example, typing - `1 + 2` to the `>>>` prompt makes it echo `3`, but we need to do - `print(1 + 2)` if we want to do the same thing in a file. -- The editor doesn't replace the `>>>` prompt. The prompt is good for - trying things out quickly, and the editor is better when we want to - write longer programs. - -## You're done! - -This probably felt like a lot of work, but don't worry, there will be no -more things like this in the future. Now we have installed and set up -all the tools we need and we can continue learning Python. +Note that if you write something like `'hello'` to the `>>>` prompt it +echoes it back, but if you make a file that contains nothing but a +`'hello'` it won't do anything when you run it. You need to use +`print('hello')` instead when your code is in a file. *** From f59f8c2e3ee86d4adf60fe5c52ecfb5e429f40c3 Mon Sep 17 00:00:00 2001 From: Akuli Date: Thu, 6 Jul 2017 21:22:05 +0300 Subject: [PATCH 27/78] more stuff --- basics/editor-setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/basics/editor-setup.md b/basics/editor-setup.md index 32286a5..9a6e0bd 100644 --- a/basics/editor-setup.md +++ b/basics/editor-setup.md @@ -28,11 +28,11 @@ files and it doesn't have too many other featues. [Install it with these instructions](https://github.com/Akuli/porcupine/wiki/Installing-and-Running-Porcupine), and then [learn to use it by writing the classic Hello World program](https://github.com/Akuli/porcupine/wiki/First-Program). Then -you can [skip the rest of this chapter](TODO). +you can [skip the rest of this chapter](#editor-or--prompt). Note that most other editors come with settings that are not suitable -for writing Python code. **TODO:** *add a link to the old editor setup -tutorial here* +for writing Python code. _**TODO:** add a link to the old editor setup +tutorial here._ Most of these editors are lacking some important features, they have so many features that they would confuse you or they aren't free. You can From ae85a404bb60d5012194c760cd7d72d7088e4d23 Mon Sep 17 00:00:00 2001 From: Akuli Date: Thu, 6 Jul 2017 21:27:12 +0300 Subject: [PATCH 28/78] more stuff thanks theelous3 --- basics/editor-setup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/basics/editor-setup.md b/basics/editor-setup.md index 9a6e0bd..0a4d8df 100644 --- a/basics/editor-setup.md +++ b/basics/editor-setup.md @@ -36,17 +36,17 @@ tutorial here._ Most of these editors are lacking some important features, they have so many features that they would confuse you or they aren't free. You can -use these editors if you like them, but **I dont recommend these editors -for getting started with programming**: +use these editors if you like them, but in my experience **these editors +are BAD for getting started with programming**: +- PyCharm +- IDLE - Emacs - Gedit -- IDLE - Nano - NetBeans - Notepad - Pluma -- PyCharm - Spyder - Vim - Wingware From cc0a36bce4a6db8cbc5f13ce65eb2b4db930e2ec Mon Sep 17 00:00:00 2001 From: Akuli Date: Thu, 6 Jul 2017 21:28:40 +0300 Subject: [PATCH 29/78] remove useless shit --- basics/editor-setup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/basics/editor-setup.md b/basics/editor-setup.md index 0a4d8df..4176cf4 100644 --- a/basics/editor-setup.md +++ b/basics/editor-setup.md @@ -34,10 +34,10 @@ Note that most other editors come with settings that are not suitable for writing Python code. _**TODO:** add a link to the old editor setup tutorial here._ -Most of these editors are lacking some important features, they have so -many features that they would confuse you or they aren't free. You can -use these editors if you like them, but in my experience **these editors -are BAD for getting started with programming**: +Most of these editors lack some important features, they have so many +features that confuse people or they aren't free. You can use these +editors if you like them, but **these editors are BAD for getting +started with programming**: - PyCharm - IDLE From ac4de8ca5a819d0efdc461693e5100ae705e49f1 Mon Sep 17 00:00:00 2001 From: Akuli Date: Thu, 20 Jul 2017 22:02:18 +0300 Subject: [PATCH 30/78] thanks socio :) --- basics/larger-program.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/basics/larger-program.md b/basics/larger-program.md index 521cf3c..f8f9bfa 100644 --- a/basics/larger-program.md +++ b/basics/larger-program.md @@ -13,6 +13,8 @@ text displaying function = print text asking function = input ``` +**Save this example file to questions.txt**, we'll need it later. + This might seem useless to you right now, but a program like this can actually be really useful for learning different kinds of things. I originally wrote a program like this to study words of a foreign From c792fc04c797d531217bcdcb71d935c8b09f82f7 Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 23 Aug 2017 19:26:00 +0300 Subject: [PATCH 31/78] better warning --- basics/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/getting-started.md b/basics/getting-started.md index 5f482d3..facdccf 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -139,7 +139,7 @@ Note that a `#` inside a string doesn't create a comment. ## Using Python as a calculator ```diff ----------- WARNING: This part contains boring math. Be careful! ---------- +---------- WARNING: This part contains boring math. Proceed with caution. ---------- ``` Let's type some math stuff into Python and see what it does. From bcec00ea3161187329754701dd298f5e7c753fa3 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 5 Jan 2018 21:16:14 +0200 Subject: [PATCH 32/78] blank lines --- basics/answers.md | 10 ++++++---- basics/if.md | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/basics/answers.md b/basics/answers.md index e05d77d..c4e3b41 100644 --- a/basics/answers.md +++ b/basics/answers.md @@ -27,12 +27,14 @@ isn't exactly like mine but it works just fine it's ok, and you can 2. The broken code has mostly the same issues as exercise 1. Here are the problems that excercise 1 doesn't have: + - The if-elif-else has a blank line at a confusing place. Delete it. + - After deleting the code, it looks quite dense. Add a new blank + line before the `if`. - The elif line is missing a `:` at the end. - On the last line the comma is on the wrong side. `"bla bla,"` is - a string that **contains** a comma, but `"bla bla",` is a - string and a **separate** comma. In this exercise, the last - line should be - `print("I don't know what", something, "means.")` + a string that **contains** a comma, but `"bla bla",` is a + string and a **separate** comma. In this exercise, the last + line should be `print("I don't know what", something, "means.")` 3. We can simply ask the word with input and print `word * 1000`. diff --git a/basics/if.md b/basics/if.md index f509d1e..a1fed8e 100644 --- a/basics/if.md +++ b/basics/if.md @@ -245,7 +245,20 @@ else: Now the `else` belongs to the `if 1 == 2` part and **it has nothing to do with the `if 1 == 1` part**. On the other hand, the elif version **grouped the multiple ifs together** and the `else` belonged to all of -them. +them. Adding a blank line makes this obvious: + +```python +if 1 == 1: + print("hello") + +if 1 == 2: + print("this is weird") +else: + print("world") +``` + +In general, adding blank lines to appropriate places is a good idea. If +you are asked to "fix code", feel free to add missing blank lines. ## Summary @@ -276,6 +289,7 @@ them. something = input("Enter something: ") if something = 'hello': print("Hello for you too!") + elif something = 'hi' print('Hi there!') else: From 60c2d7817099e25c2b801dcf28fa71d5088cbba1 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 5 Jan 2018 22:42:40 +0200 Subject: [PATCH 33/78] fixes --- basics/answers.md | 12 ++++++------ basics/defining-functions.md | 22 +++++++--------------- getting-help.md | 2 +- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/basics/answers.md b/basics/answers.md index c4e3b41..de739c3 100644 --- a/basics/answers.md +++ b/basics/answers.md @@ -66,7 +66,7 @@ isn't exactly like mine but it works just fine it's ok, and you can ```python no_space = input("Enter a word: ") yes_space = no_space + " " - print(yes_space * 999 + no_space) + print(yes_space*999 + no_space) ``` 5. Like this: @@ -79,12 +79,12 @@ isn't exactly like mine but it works just fine it's ok, and you can ``` 6. We can compare the word against an empty string (`""` or `''`) to - check if it's empty. In this example, the password is "s3cr3t". + check if it's empty. In this example, the password is "seKr3t". ```python word = input("Enter your password: ") - if word == "s3cr3t": + if word == "seKr3t": print("Welcome!") elif word == "": print("You didn't enter anything.") @@ -92,8 +92,7 @@ isn't exactly like mine but it works just fine it's ok, and you can print("Access denied.") ``` - This is not a good way to ask a password from the user because the - password isn't hidden in any way, but this is just an example. + Again, this is not a good way to ask a real password from the user. ## Handy stuff: Strings @@ -219,7 +218,8 @@ isn't exactly like mine but it works just fine it's ok, and you can problems and solutions: - `namelist` is None. It should be `namelist.extend('theelous3')`, - not `namelist = namelist.extend('theelous3')`. + not `namelist = namelist.extend('theelous3')`. See [this + thing](using-functions.md#return-values). - Now the namelist is like `['wub_wub', ..., 't', 'h', 'e', 'e', ...]`. Python treated `'theelous3'` like a list so it added each of its characters to `namelist`. We can use `namelist.append('theelous3')` diff --git a/basics/defining-functions.md b/basics/defining-functions.md index cee0d60..faba43f 100644 --- a/basics/defining-functions.md +++ b/basics/defining-functions.md @@ -177,20 +177,16 @@ However, modifying a global variable in-place from a function is easy. >>> ``` -This doesn't work if the value is of an immutable type, like string or -integer because immutable values cannot be modified in-place. -Fortunately, Python will tell us if something's wrong. +This only works for changing in-place, we cannot assign a new value to +the variable. ```python ->>> thing = 1 ->>> def stuff(): -... thing += 1 +>>> def set_stuff_to_something_new(): +... stuff = ['more local stuff'] ... ->>> stuff() -Traceback (most recent call last): - File "", line 1, in - File "", line 2, in stuff -UnboundLocalError: local variable 'thing' referenced before assignment +>>> set_stuff_to_something_new() +>>> stuff +['global stuff', 'local stuff'] >>> ``` @@ -262,10 +258,6 @@ This function can be called in two ways: because `message = "hi"` and `some_function(message="hi")` do two completely different things. -Personally, I would use this function with a positional argument. It -only takes one argument, so I don't need to worry about which argument -is which. - Now it's time to solve our box printing problem: ```python diff --git a/getting-help.md b/getting-help.md index 6080b67..c621433 100644 --- a/getting-help.md +++ b/getting-help.md @@ -5,7 +5,7 @@ places to ask for help in. ## IRC -IRC is the oldest chatting service I know, but as of 2017, it's still +IRC is the oldest chatting service I know, but as of 2018, it's still in use, and a great way to get help in Python. You don't need to register anywhere, just click one of the links below and you're good to go. From d8bdbee65b037abe4ed9099c6e89f9ec43e02382 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 10 Jun 2018 22:00:15 +0300 Subject: [PATCH 34/78] pip.main is gone in new pips --- make-html.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/make-html.py b/make-html.py index a15343d..4ae6d5a 100755 --- a/make-html.py +++ b/make-html.py @@ -39,11 +39,16 @@ try: import mistune except ImportError: + import platform + if platform.system() == 'Windows': + python = 'py' + else: + python = 'python3' print("mistune isn't installed.", file=sys.stderr) - print("You can install it like this:") + print("You can install it by running this command on a terminal or ") + print("command prompt:") print() - print(">>> import pip") - print(">>> pip.main(['install', '--user', 'mistune'])") + print(" %s -m pip install --user mistune" % python) sys.exit(1) try: From 796a91fc4bf1ca3cd4495f341e963bf73f5947f4 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 10 Jun 2018 22:00:43 +0300 Subject: [PATCH 35/78] fix --- basics/dicts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/dicts.md b/basics/dicts.md index 093b1fb..9784c5d 100644 --- a/basics/dicts.md +++ b/basics/dicts.md @@ -61,7 +61,7 @@ favorite_pets = { ``` Here `'horusr'` and `'caisa64'` are **keys** in the dictionary, and -`'cats'` and `'cats and docs'` are their **values**. Dictionaries are +`'cats'` and `'cats and dogs'` are their **values**. Dictionaries are often named by their values. This dictionary has favorite pets as its values so I named the variable `favorite_pets`. From a765c7fbc0b33aa807c3d38bb2251eabaffcd55c Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 15 Jun 2018 22:32:56 +0300 Subject: [PATCH 36/78] tvN fixes --- advanced/datatypes.md | 2 +- basics/defining-functions.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/advanced/datatypes.md b/advanced/datatypes.md index 7dd7574..5e1bf26 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -4,7 +4,7 @@ work because they're not as simple as the things that are here and i don't actually use them that much) -Now we know how to ues lists, tuples and dictionaries. They are commonly +Now we know how to use lists, tuples and dictionaries. They are commonly used data types in Python, and there's nothing wrong with them. In this chapter we'll learn more data types that make some things easier. You can always do everything with lists and dictionaries, but these data diff --git a/basics/defining-functions.md b/basics/defining-functions.md index faba43f..ebe9e12 100644 --- a/basics/defining-functions.md +++ b/basics/defining-functions.md @@ -468,7 +468,7 @@ None ``` The `print(say_hi())` thing looks a bit weird at first, but it's easy to -understand. There's a print insnde `say_hi` and there's also the print +understand. There's a print inside `say_hi` and there's also the print we just wrote, so two things are printed. Python first ran `say_hi()`, and it returned None so Python did `print(None)`. Adding an extra `print()` around a function call is actually a common mistake, and I From da471a5893ed9d8ff80c9c9b1661e41b4afe7ed5 Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 27 Jun 2018 22:10:55 +0300 Subject: [PATCH 37/78] markdown comment fix, thanks xqb :) --- advanced/datatypes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/advanced/datatypes.md b/advanced/datatypes.md index 5e1bf26..c385ab1 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -1,8 +1,8 @@ # Handy data types in the standard library -[](this doesn't explain how dict.setdefault and collections.defaultdict - work because they're not as simple as the things that are here and i - don't actually use them that much) +[](this doesn't explain how dict.setdefault and collections.defaultdict) +[](work because they're not as simple as the things that are here and i) +[](don't actually use them that much) Now we know how to use lists, tuples and dictionaries. They are commonly used data types in Python, and there's nothing wrong with them. In this From 5bed65ae4796f2ce76c3425dfaf6fcd125eb51bc Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 27 Jun 2018 22:12:11 +0300 Subject: [PATCH 38/78] try to actually fix it --- advanced/datatypes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/advanced/datatypes.md b/advanced/datatypes.md index c385ab1..b3519b0 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -1,8 +1,8 @@ # Handy data types in the standard library -[](this doesn't explain how dict.setdefault and collections.defaultdict) -[](work because they're not as simple as the things that are here and i) -[](don't actually use them that much) +[comment]: # (this doesn't explain how dict.setdefault and collections.defaultdict) +[comment]: # (work because they're not as simple as the things that are here and i) +[comment]: # (don't actually use them that much) Now we know how to use lists, tuples and dictionaries. They are commonly used data types in Python, and there's nothing wrong with them. In this From 3cd2abb5bd8ebc6fbc8aa74b59de844cb26d8fce Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 27 Jun 2018 22:14:27 +0300 Subject: [PATCH 39/78] we didn't lose any h's --- advanced/datatypes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advanced/datatypes.md b/advanced/datatypes.md index b3519b0..1477564 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -65,7 +65,7 @@ class](../basics/classes.md#what-are-classes). >>> ``` -When we did `set('hello')` we lost one `h` and the set ended up in a +When we did `set('hello')` we lost one `l` and the set ended up in a different order because sets don't contain duplicates or keep track of their order. From 6b9d7f138cf4eca2fdefacfb7d9a068d3cbbfbec Mon Sep 17 00:00:00 2001 From: Once Date: Tue, 9 Oct 2018 11:06:44 +0800 Subject: [PATCH 40/78] fixed typo --- basics/classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/classes.md b/basics/classes.md index aac9139..3c1f27d 100644 --- a/basics/classes.md +++ b/basics/classes.md @@ -304,7 +304,7 @@ Free to use: True It's working. The `self` argument in `Website.info` was `github`. You could call it something else too such as `me`, `this` or `instance`, but use `self` instead. Other Python users have gotten used to it, and -the official style guide recommens it also. +the official style guide recommends it also. We still need to set `url`, `founding_year` and `free_to_use` manually. Maybe we could add a method to do that? From 98b8253b0b8fda51b17e43605bbd98bb352bee7a Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 24 Oct 2018 20:50:28 +0300 Subject: [PATCH 41/78] babu fix --- basics/loops.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/loops.md b/basics/loops.md index 57f6b50..4abb172 100644 --- a/basics/loops.md +++ b/basics/loops.md @@ -426,7 +426,7 @@ while True: ## Exercises -1. This code is supposed to print each number between 1 and 5. Fix it. +1. This code is supposed to print the numbers 1,2,3,4,5. Fix it. ```python things = str([1, 2, 3, 4, 5]) From 011b01ffb71058e878519904455dee7992c6aac6 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 30 Nov 2018 14:18:21 +0200 Subject: [PATCH 42/78] update year, lol i'm so late with this --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 3d067ad..e9c652f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ The instructions and text in this tutorial (the "software") are licensed under the zlib License. - (C) 2016-2017 Akuli + (C) 2016-2018 Akuli This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages From 926928595fa7cddec772f273f6ab93eda87eb4f5 Mon Sep 17 00:00:00 2001 From: Debdut Goswami Date: Wed, 9 Oct 2019 23:02:23 +0530 Subject: [PATCH 43/78] Update iters.md I have added a new application of the iter() function. I have shown how we can check if an object in python is iterable or not. --- advanced/iters.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/advanced/iters.md b/advanced/iters.md index 58cebbc..7174a57 100644 --- a/advanced/iters.md +++ b/advanced/iters.md @@ -443,6 +443,24 @@ does the same thing as our `count()`. - [The itertools module](https://docs.python.org/3/library/itertools.html) contains many useful iterator-related things. +## Checking if object is iterable or not + +There is an easy way of checking if an object in python is iterable or not. The following code will do the needful. +```python +>>> def check(A): +... try: +... st = iter(A) +... print('yes') +... except: +... print('no') +... +>>> check(25) +no +>>> check([25,35]) +yes +>>> +``` +Here you can observe that the 25 is an integer, so it is not iterable, but [25,35] is a list which is iterable so it outputs no and yes respectively. *** If you have trouble with this tutorial please [tell me about From 50148537c9f6d52abb532176427c4771c8405883 Mon Sep 17 00:00:00 2001 From: Debdut Goswami Date: Mon, 14 Oct 2019 19:41:38 +0530 Subject: [PATCH 44/78] Update iters.md --- advanced/iters.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/advanced/iters.md b/advanced/iters.md index 7174a57..3be970e 100644 --- a/advanced/iters.md +++ b/advanced/iters.md @@ -246,6 +246,25 @@ while True: print(thing) ``` +## Checking if object is iterable or not + +There is an easy way of checking if an object in python is iterable or not. The following code will do the needful. +```python +>>> def check(A): +... try: +... st = iter(A) +... print('yes') +... except TypeError: +... print('no') +... +>>> check(25) +no +>>> check([25,35]) +yes +>>> +``` +Here you can observe that the 25 is an integer, so it is not iterable, but [25,35] is a list which is iterable so it outputs no and yes respectively. + ## Generators It's possible to create a custom iterator with a class that defines an @@ -442,25 +461,6 @@ does the same thing as our `count()`. generator runs it to the next yield and gives us the value it yielded. - [The itertools module](https://docs.python.org/3/library/itertools.html) contains many useful iterator-related things. - -## Checking if object is iterable or not - -There is an easy way of checking if an object in python is iterable or not. The following code will do the needful. -```python ->>> def check(A): -... try: -... st = iter(A) -... print('yes') -... except: -... print('no') -... ->>> check(25) -no ->>> check([25,35]) -yes ->>> -``` -Here you can observe that the 25 is an integer, so it is not iterable, but [25,35] is a list which is iterable so it outputs no and yes respectively. *** If you have trouble with this tutorial please [tell me about From 894a607c05e0bbddb7bf3230081c44f096db9972 Mon Sep 17 00:00:00 2001 From: sayar mendis Date: Mon, 21 Oct 2019 14:53:15 +0530 Subject: [PATCH 45/78] Added docstring popular formats --- basics/docstrings.md | 126 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/basics/docstrings.md b/basics/docstrings.md index bbebfa3..e3053e0 100644 --- a/basics/docstrings.md +++ b/basics/docstrings.md @@ -121,6 +121,132 @@ It's recommended to always use `"""strings like this"""` for docstrings, even if the docstring is only one line long. This way it's easy to add more stuff to it later. +## Popular Docstrings Format + +There might be different documentation strings available. You need not need to worry about the fact that you have to reinvent the wheel to study all. The formats of all the Documentation strings are nearly similar. The patterns are similar, but there are only nitty-gritty changes in each format. + +##### 1) Sphinx Style : + +Sphinx is the easy and traditional style, verbose and was initially created specifically for the Python Documentation. Sphinx uses a reStructuredText which is similar in usage to Markdown. + +```python +class Vehicle(object): + ''' + The Vehicle object contains lots of vehicles + :param arg: The arg is used for ... + :type arg: str + :param `*args`: The variable arguments are used for ... + :param `**kwargs`: The keyword arguments are used for ... + :ivar arg: This is where we store arg + :vartype arg: str + ''' + + + def __init__(self, arg, *args, **kwargs): + self.arg = arg + + def cars(self, distance, destination): + '''We can't travel a certain distance in vehicles without fuels, so here's the fuels + + :param distance: The amount of distance traveled + :type amount: int + :param bool destinationReached: Should the fuels be refilled to cover required distance? + :raises: :class:`RuntimeError`: Out of fuel + + :returns: A Car mileage + :rtype: Cars + ''' + pass + +``` + +##### 2) Google Style : +Google Style is easier and more intuitive to use. It can be used for the shorter form of documentation. A configuration of python file needs to be done to get started, so you need to add either sphinx.ext.napoleon or sphinxcontrib.napoleon to the extensions list in conf.py. + +```python +class Vehicles(object): + ''' + The Vehicle object contains a lot of vehicles + + Args: + arg (str): The arg is used for... + *args: The variable arguments are used for... + **kwargs: The keyword arguments are used for... + + Attributes: + arg (str): This is where we store arg, + ''' + + def __init__(self, arg, *args, **kwargs): + self.arg = arg + + def cars(self, distance,destination): + '''We can't travel distance in vehicles without fuels, so here is the fuels + + Args: + distance (int): The amount of distance traveled + destination (bool): Should the fuels refilled to cover the distance? + + Raises: + RuntimeError: Out of fuel + + Returns: + cars: A car mileage + ''' + pass + +``` + +##### 3) Numpy Style : + +Numpy style has a lot of details in the documentation. It is more verbose than other documentation, but it is an excellent choice if you want to do detailed documentation, i.e., extensive documentation of all the functions and parameters. + +```python +class Vehicles(object): + ''' + The Vehicles object contains lots of vehicles + + Parameters + ---------- + arg : str + The arg is used for ... + *args + The variable arguments are used for ... + **kwargs + The keyword arguments are used for ... + + Attributes + ---------- + arg : str + This is where we store arg, + ''' + + def __init__(self, arg, *args, **kwargs): + self.arg = arg + + def cars(self, distance, destination): + '''We can't travel distance in vehicles without fuels, so here is the fuels + + Parameters + ---------- + distance : int + The amount of distance traveled + destination : bool + Should the fuels refilled to cover the distance? + + Raises + ------ + RuntimeError + Out of fuel + + Returns + ------- + cars + A car mileage + ''' + pass +``` + ## Documenting other stuff Docstrings aren't actually limited to functions. You can use them for From 2d1b2f1cb050597a2025fc35b8da440bc97a3118 Mon Sep 17 00:00:00 2001 From: Akuli Date: Tue, 31 Dec 2019 13:18:24 +0200 Subject: [PATCH 46/78] grammar fixes for #15 --- README.md | 2 +- basics/what-is-programming.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index feef6cc..73f7d34 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ section. Most of the techniques explained here are great when you're working on a large project, and your code would be really repetitive without these things. -You can experient with these things freely, but please **don't use these +You can experiment with these things freely, but please **don't use these techniques just because you know how to use them.** Prefer the simple techniques from the Basics part instead when possible. Simple is better than complex. diff --git a/basics/what-is-programming.md b/basics/what-is-programming.md index ce917a5..40e37a6 100644 --- a/basics/what-is-programming.md +++ b/basics/what-is-programming.md @@ -104,7 +104,7 @@ should you do if you have a problem with the tutorial? 1. Try the example code yourself. 2. Read the code and the explanation for it again. 3. If there's something you haven't seen before in the tutorial and it's - not explained, try to find it from the previous chapters. + not explained, try to find it in the previous chapters. 4. If you can't find what you're looking for or you still have trouble understanding the tutorial or any other problems with the tutorial, please [tell me about it](../contact-me.md). I want to improve this From bdf156dd776fb1b3940d0807a2e14eeb75dd8b9b Mon Sep 17 00:00:00 2001 From: Damian Herfkens Date: Thu, 29 Aug 2019 18:29:45 +0200 Subject: [PATCH 47/78] Changes a few things in some files, to fit better or to correct grammar. --- .vs/ProjectSettings.json | 3 +++ .vs/slnx.sqlite | Bin 0 -> 90112 bytes basics/editor-setup.md | 5 +++-- basics/getting-started.md | 6 +++--- basics/variables.md | 5 +++-- 5 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 .vs/ProjectSettings.json create mode 100644 .vs/slnx.sqlite diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 0000000..f8b4888 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..a2756a77f287b651384e873271b306beee9f8cf0 GIT binary patch literal 90112 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 prompt. Then we can save the programs to files and +write on the `>>>` prompt. With an editor we can save the programs to files and run them as many times as we want without writing them again. When programmers say "editor" they don't mean programs like Microsoft @@ -9,7 +9,8 @@ Word or LibreOffice/OpenOffice Writer. These programs are for writing text documents, not for programming. **Programming editors don't support things like bigger font sizes for titles or underlining bits of text**, but instead they have features that are actually useful for programming, -like automatically displaying different things with different colors. +like automatically displaying different things with different colors, +but also highlighting mistakes in the code, and coloring syntax. If you are on Windows or Mac OSX you have probably noticed that your Python came with an editor called IDLE. We are not going to use it diff --git a/basics/getting-started.md b/basics/getting-started.md index facdccf..720af5a 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -62,9 +62,9 @@ worked just fine. Later we'll learn what `(3, 14)` is. ## Comments -**Comments are text that does nothing.** They can be created by typing a -`#` and then some text after it, and they are useful when our code would -be hard to understand without them. +**Comments are text that don't do anything when they're run.** +They can be created by typing a `#` and then some text after it, +and they are useful when our code would be hard to understand without them. ```python >>> 1 + 2 # can you guess what the result is? diff --git a/basics/variables.md b/basics/variables.md index 4b9c25b..a272424 100644 --- a/basics/variables.md +++ b/basics/variables.md @@ -86,8 +86,9 @@ Variable names are case-sensitive, like many other things in Python. ``` There are also words that cannot be used as variable names -because they have a special meaning. They are called **keywords**, and -we can run `help('keywords')` to see the full list if we want to. +because they are reserved by Python itself and have a special meaning. +They are called **keywords**, and we can run `help('keywords')` +to see the full list if we want to. We'll learn to use most of them later in this tutorial. Trying to use a keyword as a variable name causes a syntax error. From 9802dcfa1286226c384698dabb98e9f25200f031 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 25 Jul 2020 22:19:09 +0300 Subject: [PATCH 48/78] remove editor files from #11 --- .vs/ProjectSettings.json | 3 --- .vs/slnx.sqlite | Bin 90112 -> 0 bytes 2 files changed, 3 deletions(-) delete mode 100644 .vs/ProjectSettings.json delete mode 100644 .vs/slnx.sqlite diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json deleted file mode 100644 index f8b4888..0000000 --- a/.vs/ProjectSettings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "CurrentProjectSetting": null -} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100644 index a2756a77f287b651384e873271b306beee9f8cf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90112 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 Date: Sat, 25 Jul 2020 22:22:43 +0300 Subject: [PATCH 49/78] python 2 is legacy now --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 73f7d34..629b10d 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,7 @@ the past using some other language you may want to read [the official tutorial](https://docs.python.org/3/tutorial/) instead. You can use Python 3.3 or any newer Python with this tutorial. **Don't -use Python 2.** If you write a Python 2 program now someone will need to -convert it to Python 3 later, so it's best to just write Python 3 to -begin with. Python 3 code will work just fine in Python 4, so you don't -need to worry about that. Python 2 also has horrible -[Unicode](http://www.unicode.org/standard/WhatIsUnicode.html) problems, -so it's difficult to write Python 2 code that works correctly with -non-English characters (like π and ♫). +use Python 2 because it's no longer supported.** ## List of contents From 7e732f7f1f944d26dac4efc2be3431548752f7d0 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 25 Jul 2020 22:23:00 +0300 Subject: [PATCH 50/78] less confusing "don't remove python 2" text --- basics/installing-python.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/basics/installing-python.md b/basics/installing-python.md index cc693bf..755e509 100644 --- a/basics/installing-python.md +++ b/basics/installing-python.md @@ -40,8 +40,9 @@ me](../contact-me.md). ### Linux You already have Python 3, **there's no need to install anything**. You -may also have Python 2, but don't try to remove it. Some of your -programs are probably written in Python 2, so removing Python 2 would +may also have Python 2, but don't try to remove it. +Some of the programs that came with your operating system +are probably written in Python 2, so removing Python 2 would break them. ## Running Python From 52073d86ee6b75ac7fa542e3fe03dbec1f13a312 Mon Sep 17 00:00:00 2001 From: Varian Caesar Date: Sun, 13 Oct 2019 00:37:53 +0700 Subject: [PATCH 51/78] feat: Add list comprehension in list tutorial --- basics/lists-and-tuples.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index 77ea0ca..2bb4dff 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -141,6 +141,17 @@ We'll talk more about loops [in the next chapter](loops.md). >>> ``` +Another useful things about list is **comprehension**. +**Comprehension** is a way to loop the list in single line. It makes our code more pythonic. + +```python +>>> numbers = [1,2,3,4,5] +>>> numbers_squared = [ number ** 2 for number in numbers ] +>>> numbers_squared +[1, 4, 9, 16, 25] +>>> +``` + We can also use slicing and indexing to change the content: ```python From 93a00c20bbb905f79e6b52a8dc88d0f02af44dce Mon Sep 17 00:00:00 2001 From: Varian Caesar Date: Mon, 21 Oct 2019 00:50:06 +0700 Subject: [PATCH 52/78] Add example with vs without list comprehension --- basics/lists-and-tuples.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index 2bb4dff..41f7ad9 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -142,7 +142,7 @@ We'll talk more about loops [in the next chapter](loops.md). ``` Another useful things about list is **comprehension**. -**Comprehension** is a way to loop the list in single line. It makes our code more pythonic. +**Comprehension** is a way to construct a list in single line. It makes our code more clean, shorter and easier to read. ```python >>> numbers = [1,2,3,4,5] @@ -152,6 +152,18 @@ Another useful things about list is **comprehension**. >>> ``` +without comprehension: + +```python +>>> numbers = [1,2,3,4,5] +>>> numbers_squared = [] +>>> for number in numbers: +... numbers_squared.append(number**2) +>>> numbers_squared +[1, 4, 9, 16, 25] +>>> +``` + We can also use slicing and indexing to change the content: ```python From 4c220ea5a8b1f3c3d873a40c560a5527ee3c185a Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 25 Jul 2020 22:30:57 +0300 Subject: [PATCH 53/78] small changes after #13 --- basics/lists-and-tuples.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index 41f7ad9..a231de9 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -141,18 +141,18 @@ We'll talk more about loops [in the next chapter](loops.md). >>> ``` -Another useful things about list is **comprehension**. -**Comprehension** is a way to construct a list in single line. It makes our code more clean, shorter and easier to read. +Another useful thing about lists is **list comprehension**. +It's a handy way to construct a list in single line. It often makes code cleaner, shorter and easier to read. ```python >>> numbers = [1,2,3,4,5] ->>> numbers_squared = [ number ** 2 for number in numbers ] +>>> numbers_squared = [number ** 2 for number in numbers] >>> numbers_squared [1, 4, 9, 16, 25] >>> ``` -without comprehension: +Without a list comprehension, doing the same thing looks like this: ```python >>> numbers = [1,2,3,4,5] From d02904b5f54ba4bf3aef9478cebca93892dd8404 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 25 Jul 2020 22:50:10 +0300 Subject: [PATCH 54/78] wip #14 stuff --- basics/docstrings.md | 51 ++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/basics/docstrings.md b/basics/docstrings.md index e3053e0..9dbe858 100644 --- a/basics/docstrings.md +++ b/basics/docstrings.md @@ -121,28 +121,34 @@ It's recommended to always use `"""strings like this"""` for docstrings, even if the docstring is only one line long. This way it's easy to add more stuff to it later. -## Popular Docstrings Format +## Popular Docstring Formats -There might be different documentation strings available. You need not need to worry about the fact that you have to reinvent the wheel to study all. The formats of all the Documentation strings are nearly similar. The patterns are similar, but there are only nitty-gritty changes in each format. +There are different styles for writing docstrings. If you are contributing to +another Python project, make sure to use the same style as rest of that project +is using. -##### 1) Sphinx Style : +If you are starting a new project, then you can use whichever style you +want, but don't "reinventing the wheel"; use an existing style instead instead of +making up your own. Here are some examples of popular docstring styles to choose +from: -Sphinx is the easy and traditional style, verbose and was initially created specifically for the Python Documentation. Sphinx uses a reStructuredText which is similar in usage to Markdown. +### Sphinx Style + +[Sphinx](https://www.sphinx-doc.org/en/master/) is the Python documentation tool +that [the official Python documentation](https://docs.python.org/3/) uses. +By default, sphinx expects you to write docstrings like this: ```python class Vehicle(object): ''' - The Vehicle object contains lots of vehicles + The Vehicle object contains lots of vehicles. :param arg: The arg is used for ... :type arg: str - :param `*args`: The variable arguments are used for ... - :param `**kwargs`: The keyword arguments are used for ... :ivar arg: This is where we store arg :vartype arg: str ''' - - def __init__(self, arg, *args, **kwargs): + def __init__(self, arg): self.arg = arg def cars(self, distance, destination): @@ -156,12 +162,14 @@ class Vehicle(object): :returns: A Car mileage :rtype: Cars ''' - pass - + ... ``` -##### 2) Google Style : -Google Style is easier and more intuitive to use. It can be used for the shorter form of documentation. A configuration of python file needs to be done to get started, so you need to add either sphinx.ext.napoleon or sphinxcontrib.napoleon to the extensions list in conf.py. +### Google Style + +Google Style is meant to be easier to read and use without a tool like sphinx. +Sphinx can be configured to use that with +[sphinx.ext.napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html). ```python class Vehicles(object): @@ -170,17 +178,15 @@ class Vehicles(object): Args: arg (str): The arg is used for... - *args: The variable arguments are used for... - **kwargs: The keyword arguments are used for... Attributes: arg (str): This is where we store arg, ''' - def __init__(self, arg, *args, **kwargs): + def __init__(self, arg): self.arg = arg - def cars(self, distance,destination): + def cars(self, distance, destination): '''We can't travel distance in vehicles without fuels, so here is the fuels Args: @@ -193,13 +199,16 @@ class Vehicles(object): Returns: cars: A car mileage ''' - pass + ... ``` -##### 3) Numpy Style : +### Numpy Style -Numpy style has a lot of details in the documentation. It is more verbose than other documentation, but it is an excellent choice if you want to do detailed documentation, i.e., extensive documentation of all the functions and parameters. +[Numpy](https://numpy.org/) is a large and popular Python library, +and numpy developers have their own docstring style. +It is an excellent choice if you want to do detailed documentation, +i.e., extensive documentation of all the functions and parameters. ```python class Vehicles(object): @@ -221,7 +230,7 @@ class Vehicles(object): This is where we store arg, ''' - def __init__(self, arg, *args, **kwargs): + def __init__(self, arg): self.arg = arg def cars(self, distance, destination): From 5c145942e3d95fe57c74fcb2ca21eaa581d79229 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 25 Jul 2020 23:09:50 +0300 Subject: [PATCH 55/78] drop support for old pythons --- README.md | 2 +- advanced/datatypes.md | 67 ++++++++----------------------------------- basics/exceptions.md | 7 +++-- basics/modules.md | 24 ++++++++-------- 4 files changed, 30 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 629b10d..a4886c9 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ or very little programming experience. If you have programmed a lot in the past using some other language you may want to read [the official tutorial](https://docs.python.org/3/tutorial/) instead. -You can use Python 3.3 or any newer Python with this tutorial. **Don't +You can use Python 3.5 or any newer Python with this tutorial. **Don't use Python 2 because it's no longer supported.** ## List of contents diff --git a/advanced/datatypes.md b/advanced/datatypes.md index 1477564..74df310 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -316,68 +316,25 @@ TypeError: unsupported operand type(s) for +: 'dict' and 'dict' >>> ``` -Dictionaries have an `update` method that adds everything from another -dictionary into it. So we can merge dictionaries like this: +Usually it's easiest to do this: ```python ->>> merged = {} ->>> merged.update({'a': 1, 'b': 2}) ->>> merged.update({'c': 3}) ->>> merged -{'c': 3, 'b': 2, 'a': 1} ->>> -``` - -Or we can [write a function](../basics/defining-functions.md) like this: - -```python ->>> def merge_dicts(dictlist): -... result = {} -... for dictionary in dictlist: -... result.update(dictionary) -... return result -... ->>> merge_dicts([{'a': 1, 'b': 2}, {'c': 3}]) -{'c': 3, 'b': 2, 'a': 1} ->>> +>>> dict1 = {'a': 1, 'b': 2} +>>> dict2 = {'c': 3} +>>> {**dict1, **dict2} +{'a': 1, 'b': 2, 'c': 3} ``` -Kind of like counting things, merging dictionaries is also a commonly -needed thing and there's a class just for it in the `collections` -module. It's called ChainMap: +Dictionaries also have an `update` method that adds everything from another +dictionary into it, and you can use that too. This was the most common way to +do it before Python supported `{**dict1, **dict2}`. ```python ->>> import collections ->>> merged = collections.ChainMap({'a': 1, 'b': 2}, {'c': 3}) +>>> merged = {} +>>> merged.update({'a': 1, 'b': 2}) +>>> merged.update({'c': 3}) >>> merged -ChainMap({'b': 2, 'a': 1}, {'c': 3}) ->>> -``` - -Our `merged` is kind of like the Counter object we created earlier. It's -not a dictionary, but it behaves like a dictionary. - -```python ->>> for key, value in merged.items(): -... print(key, value) -... -c 3 -b 2 -a 1 ->>> dict(merged) -{'c': 3, 'b': 2, 'a': 1} ->>> -``` - -Starting with Python 3.5 it's possible to merge dictionaries like this. -**Don't do this unless you are sure that no-one will need to run your -code on Python versions older than 3.5.** - -```python ->>> first = {'a': 1, 'b': 2} ->>> second = {'c': 3, 'd': 4} ->>> {**first, **second} -{'d': 4, 'c': 3, 'a': 1, 'b': 2} +{'a': 1, 'b': 2, 'c': 3} >>> ``` diff --git a/basics/exceptions.md b/basics/exceptions.md index 946d4f1..4ca3603 100644 --- a/basics/exceptions.md +++ b/basics/exceptions.md @@ -319,7 +319,7 @@ it's usually better to use `sys.stderr` and `sys.exit`. ## Exception hierarchy Exceptions are organized like this. I made this tree with [this -program](https://github.com/Akuli/classtree/) on Python 3.4. You may +program](https://github.com/Akuli/classtree/) on Python 3.7. You may have more or less exceptions than I have if your Python is newer or older than mine, but they should be mostly similar. @@ -333,6 +333,7 @@ older than mine, but they should be mostly similar. ├── BufferError ├── EOFError ├── ImportError + │ └── ModuleNotFoundError ├── LookupError │ ├── IndexError │ └── KeyError @@ -357,7 +358,9 @@ older than mine, but they should be mostly similar. │ └── TimeoutError ├── ReferenceError ├── RuntimeError - │ └── NotImplementedError + │ ├── NotImplementedError + │ └── RecursionError + ├── StopAsyncIteration ├── StopIteration ├── SyntaxError │ └── IndentationError diff --git a/basics/modules.md b/basics/modules.md index 44cacba..be39945 100644 --- a/basics/modules.md +++ b/basics/modules.md @@ -28,17 +28,17 @@ gave us? ```python >>> random - + >>> ``` So it's a module, and it comes from a path... but what does all that mean? -Now open the folder that contains your `random.py` is. On my -system it's `/usr/lib/python3.4`, but yours will probably be +Now open the folder that contains your `random.py`. On my +system it's `/usr/lib/python3.7`, but yours will probably be different. To open a folder in your file manager you can press -Windows-R on Windows or Alt+F2 on most GNU/Linux distributions, +Windows-R on Windows or Alt+F2 on most Linux distributions, and just type your path there. I don't have an up-to-date copy of OSX so unfortunately I have no idea what you need to do on OSX. @@ -138,11 +138,11 @@ places that modules are searched from: >>> sys.path ['', - '/usr/lib/python3.4', - '/usr/lib/python3.4/plat-i386-linux-gnu', - '/usr/lib/python3.4/lib-dynload', - '/home/akuli/.local/lib/python3.4/site-packages', - '/usr/local/lib/python3.4/dist-packages', + '/usr/lib/python37.zip', + '/usr/lib/python3.7', + '/usr/lib/python3.7/lib-dynload', + '/home/akuli/.local/lib/python3.7/site-packages', + '/usr/local/lib/python3.7/dist-packages', '/usr/lib/python3/dist-packages'] >>> ``` @@ -234,9 +234,9 @@ hello >>> >>> # information about Python's version, behaves like a tuple >>> sys.version_info -sys.version_info(major=3, minor=4, micro=2, releaselevel='final', serial=0) ->>> sys.version_info[:3] # this is Python 3.4.2 -(3, 4, 2) +sys.version_info(major=3, minor=7, micro=3, releaselevel='final', serial=0) +>>> sys.version_info[:3] # this is Python 3.7.3 +(3, 7, 3) >>> >>> sys.exit() # exit out of Python ``` From 036908852121fd0c73d6797d2b1d61a4c9535801 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 25 Jul 2020 23:10:47 +0300 Subject: [PATCH 56/78] tell people to search on pypi themselves instead of recommending a couple funny modules, also GNU/Linux --> Linux --- basics/modules.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/basics/modules.md b/basics/modules.md index be39945..b8dccbf 100644 --- a/basics/modules.md +++ b/basics/modules.md @@ -241,7 +241,7 @@ sys.version_info(major=3, minor=7, micro=3, releaselevel='final', serial=0) >>> sys.exit() # exit out of Python ``` -**TODO:** why stderr instead of stdout. +**TODO:** why stderr instead of stdout, when to use `sys.stdin.readline()` instead of `input()` `sys.exit()` does the same thing as `sys.exit(0)`. The zero means that the program succeeded, and everything's fine. If our program has an @@ -461,17 +461,14 @@ then typing in what you want to search for. - [webbrowser](https://pymotw.com/3/webbrowser/): open a web browser from Python -I also use these modules, but they don't come with Python so you'll -need to install them yourself if you want to use them: - -- [appdirs](https://github.com/activestate/appdirs): - an easy way to find out where to put setting files -- [requests](http://docs.python-requests.org/en/master/user/quickstart/): - an awesome networking library +There are also lots of awesome modules that don't come with Python. +You can search for those on the [Python package index](https://pypi.org/), +or PyPI for short. It's often better to find a library that does something +difficult than to spend a lot of time trying to do it yourself. I recommend reading [the official documentation about installing -modules](https://docs.python.org/3/installing/). If you're using -GNU/Linux also read the "Installing into the system Python on Linux" +modules](https://docs.python.org/3/installing/) from PyPI. If you're using +Linux, then also read the "Installing into the system Python on Linux" section at the bottom. ## Summary From 2f42a70dca41084676c7fe59ab12bd44ba173e58 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 25 Jul 2020 23:55:45 +0300 Subject: [PATCH 57/78] changes after merging #14 --- basics/docstrings.md | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/basics/docstrings.md b/basics/docstrings.md index 9dbe858..5abc94f 100644 --- a/basics/docstrings.md +++ b/basics/docstrings.md @@ -139,20 +139,20 @@ that [the official Python documentation](https://docs.python.org/3/) uses. By default, sphinx expects you to write docstrings like this: ```python -class Vehicle(object): - ''' - The Vehicle object contains lots of vehicles. +class Vehicles: + """ + The Vehicles object contains lots of vehicles. :param arg: The arg is used for ... :type arg: str :ivar arg: This is where we store arg :vartype arg: str - ''' + """ def __init__(self, arg): self.arg = arg def cars(self, distance, destination): - '''We can't travel a certain distance in vehicles without fuels, so here's the fuels + """We can't travel a certain distance in vehicles without fuels, so here's the fuels :param distance: The amount of distance traveled :type amount: int @@ -161,7 +161,7 @@ class Vehicle(object): :returns: A Car mileage :rtype: Cars - ''' + """ ... ``` @@ -172,22 +172,22 @@ Sphinx can be configured to use that with [sphinx.ext.napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html). ```python -class Vehicles(object): - ''' - The Vehicle object contains a lot of vehicles +class Vehicles: + """ + The Vehicles object contains lots of vehicles. Args: arg (str): The arg is used for... Attributes: - arg (str): This is where we store arg, - ''' + arg (str): This is where we store arg. + """ def __init__(self, arg): self.arg = arg def cars(self, distance, destination): - '''We can't travel distance in vehicles without fuels, so here is the fuels + """We can't travel distance in vehicles without fuels, so here is the fuels Args: distance (int): The amount of distance traveled @@ -198,7 +198,7 @@ class Vehicles(object): Returns: cars: A car mileage - ''' + """ ... ``` @@ -207,13 +207,11 @@ class Vehicles(object): [Numpy](https://numpy.org/) is a large and popular Python library, and numpy developers have their own docstring style. -It is an excellent choice if you want to do detailed documentation, -i.e., extensive documentation of all the functions and parameters. ```python -class Vehicles(object): - ''' - The Vehicles object contains lots of vehicles +class Vehicles: + """ + The Vehicles object contains lots of vehicles. Parameters ---------- @@ -227,14 +225,14 @@ class Vehicles(object): Attributes ---------- arg : str - This is where we store arg, - ''' + This is where we store arg. + """ def __init__(self, arg): self.arg = arg def cars(self, distance, destination): - '''We can't travel distance in vehicles without fuels, so here is the fuels + """We can't travel distance in vehicles without fuels, so here is the fuels Parameters ---------- @@ -252,7 +250,7 @@ class Vehicles(object): ------- cars A car mileage - ''' + """ pass ``` From 4491466486f0058fc4da9cad68dff0d7c467dd47 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 25 Jul 2020 23:56:52 +0300 Subject: [PATCH 58/78] swap "Popular Docstring Formats" and "Documenting other stuff" sections --- basics/docstrings.md | 154 +++++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/basics/docstrings.md b/basics/docstrings.md index 5abc94f..e0e83a7 100644 --- a/basics/docstrings.md +++ b/basics/docstrings.md @@ -121,6 +121,83 @@ It's recommended to always use `"""strings like this"""` for docstrings, even if the docstring is only one line long. This way it's easy to add more stuff to it later. +## Documenting other stuff + +Docstrings aren't actually limited to functions. You can use them for +documenting [classes](classes.md) and their methods too. For example, +let's make a file like this and save it to `test.py`: + +```python +"""A test module. + +It contains a class and a function. +""" + + +class Thing: + """This is a test class.""" + + def thingy(self): + """This is a test method.""" + print("hello") + + +def do_hello(): + """This is a test function.""" + thing = Thing() + thing.thingy() +``` + +Then we can import it and call help on it: + +[comment]: # (github screws up syntax highlighting here) + +``` +>>> import test +>>> help(test) +Help on module testie: + +NAME + testie - A test module. + +DESCRIPTION + It contains a class and a function. + +CLASSES + builtins.object + Thing + + class Thing(builtins.object) + | This is a test class. + | + | Methods defined here: + | + | thingy(self) + | This is a test method. + | + | ---------------------------------------------------------------------- + | Data descriptors defined here: + | + | __dict__ + | dictionary for instance variables (if defined) + | + | __weakref__ + | list of weak references to the object (if defined) + +FUNCTIONS + do_hello() + This is a test function. + +FILE + /home/akuli/testie.py +``` + +That's pretty cool. We just added docstrings to our code and Python made +this thing out of it. + +You might be wondering what `__weakref__` is. You don't need to care +about it, and I think it would be better if `help()` would hide it. + ## Popular Docstring Formats There are different styles for writing docstrings. If you are contributing to @@ -254,83 +331,6 @@ class Vehicles: pass ``` -## Documenting other stuff - -Docstrings aren't actually limited to functions. You can use them for -documenting [classes](classes.md) and their methods too. For example, -let's make a file like this and save it to `test.py`: - -```python -"""A test module. - -It contains a class and a function. -""" - - -class Thing: - """This is a test class.""" - - def thingy(self): - """This is a test method.""" - print("hello") - - -def do_hello(): - """This is a test function.""" - thing = Thing() - thing.thingy() -``` - -Then we can import it and call help on it: - -[comment]: # (github screws up syntax highlighting here) - -``` ->>> import test ->>> help(test) -Help on module testie: - -NAME - testie - A test module. - -DESCRIPTION - It contains a class and a function. - -CLASSES - builtins.object - Thing - - class Thing(builtins.object) - | This is a test class. - | - | Methods defined here: - | - | thingy(self) - | This is a test method. - | - | ---------------------------------------------------------------------- - | Data descriptors defined here: - | - | __dict__ - | dictionary for instance variables (if defined) - | - | __weakref__ - | list of weak references to the object (if defined) - -FUNCTIONS - do_hello() - This is a test function. - -FILE - /home/akuli/testie.py -``` - -That's pretty cool. We just added docstrings to our code and Python made -this thing out of it. - -You might be wondering what `__weakref__` is. You don't need to care -about it, and I think it would be better if `help()` would hide it. - ## When should we use docstrings? Always use docstrings when writing code that other people will import. From 330f10bc11c7589baf60ed869d0a1fccf990e3ea Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 26 Jul 2020 00:01:28 +0300 Subject: [PATCH 59/78] replace outdated authors list with github stats link --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a4886c9..0e6a739 100644 --- a/README.md +++ b/README.md @@ -104,11 +104,8 @@ pull with git and run `make-html.py` again. ## Authors -I'm Akuli and I have written most of this tutorial, but these people -have helped me with it: -- [SpiritualForest](https://github.com/SpiritualForest): Lots of typing - error fixes. -- [theelous3](https://github.com/theelous3): Small improvements and fixes. +I'm Akuli and I have written most of this tutorial, but other people have helped me with it. +See [github's contributors page](https://github.com/Akuli/python-tutorial/graphs/contributors) for details. *** From d0e9978c146979fceb0245cc3a61988711498542 Mon Sep 17 00:00:00 2001 From: Anjali Mishra <47514556+Anjali4rl@users.noreply.github.com> Date: Sat, 3 Oct 2020 01:20:38 +0530 Subject: [PATCH 60/78] Improvement in Heading (#23) * Clarified Heading * Update README.md Co-authored-by: Akuli Co-authored-by: Akuli --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e6a739..8b40094 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Python programming tutorial +# Python programming tutorial for begineers This is a concise Python 3 programming tutorial for people who think that reading is boring. I try to show everything with simple code From 126ec0e8286b057a987102c1d7c72e754a9d0f4f Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 3 Oct 2020 16:34:56 +0300 Subject: [PATCH 61/78] small fixes --- basics/docstrings.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/basics/docstrings.md b/basics/docstrings.md index e0e83a7..db571db 100644 --- a/basics/docstrings.md +++ b/basics/docstrings.md @@ -205,7 +205,7 @@ another Python project, make sure to use the same style as rest of that project is using. If you are starting a new project, then you can use whichever style you -want, but don't "reinventing the wheel"; use an existing style instead instead of +want, but don't "reinvent the wheel"; use an existing style instead instead of making up your own. Here are some examples of popular docstring styles to choose from: @@ -333,9 +333,8 @@ class Vehicles: ## When should we use docstrings? -Always use docstrings when writing code that other people will import. -The `help()` function is awesome, so it's important to make sure it's -actually helpful. +I recommend using docstrings when writing code that other people will import. +The `help()` function is awesome, so it's good to make sure it's actually helpful. If your code is not meant to be imported, docstrings are usually a good idea anyway. Other people reading your code will understand what it's @@ -347,7 +346,7 @@ doing without having to read through all of the code. - A `"""triple-quoted string"""` string in the beginning of a function, class or file is a docstring. It shows up in `help()`. - Docstrings are not comments. -- Usually it's a good idea to add docstrings everywhere +- Usually it's a good idea to add docstrings everywhere. *** From 7b1c8f01007e4b788cb4bd2c8edc4d92849d906e Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 4 Oct 2020 16:29:56 +0300 Subject: [PATCH 62/78] fix typo introduced in #23 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b40094..f201dbf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Python programming tutorial for begineers +# Python programming tutorial for beginners This is a concise Python 3 programming tutorial for people who think that reading is boring. I try to show everything with simple code From 6af5196e39dfa91fcca2553b6ebb86dbe5725481 Mon Sep 17 00:00:00 2001 From: Akuli Date: Thu, 20 May 2021 23:53:14 +0300 Subject: [PATCH 63/78] typo fix --- basics/docstrings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/docstrings.md b/basics/docstrings.md index db571db..7158bb3 100644 --- a/basics/docstrings.md +++ b/basics/docstrings.md @@ -44,7 +44,7 @@ thing(stuff) ``` That sucked! We have no idea about what it does based on this. All we -know is that it takes a `thing` argument. +know is that it takes a `stuff` argument. This is when documentation strings or docstrings come in. All we need to do is to add a string to the beginning of our function and it will show From 18c7cea0c47566965b71eb8dfc85a53346a82b21 Mon Sep 17 00:00:00 2001 From: George Rahul <75750164+georgerahul24@users.noreply.github.com> Date: Sat, 31 Jul 2021 01:03:54 +0530 Subject: [PATCH 64/78] New Excercises (#30) --- LICENSE | 2 +- basics/answers.md | 42 +++++++++++++++++++++++++++++++++-- basics/handy-stuff-strings.md | 2 ++ basics/if.md | 1 + basics/loops.md | 20 ++++++++++++++++- 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/LICENSE b/LICENSE index e9c652f..93baa59 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ The instructions and text in this tutorial (the "software") are licensed under the zlib License. - (C) 2016-2018 Akuli + (C) 2016-2021 Akuli This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/basics/answers.md b/basics/answers.md index de739c3..f2fcdf1 100644 --- a/basics/answers.md +++ b/basics/answers.md @@ -92,7 +92,7 @@ isn't exactly like mine but it works just fine it's ok, and you can print("Access denied.") ``` - Again, this is not a good way to ask a real password from the user. + Again, this is not a good way to ask a real password from the user. ## Handy stuff: Strings @@ -156,7 +156,15 @@ isn't exactly like mine but it works just fine it's ok, and you can print(message, "!!!") print(message, "!!!") ``` - +3. In the code below, `palindrome_input[::-1]` is the string `palindrome_input` reversed. + For example, if `palindrome_input` is `"hello"`, then `palindrome_input[::-1]` is `"olleh"`. + ```python + palindrome_input=input("Type the number to check:") + if palindrome_input == palindrome_input[::-1]: + print("This string is a palindrome") + else: + print("This string is not a palindrome") + ``` ## Lists and tuples 1. Look carefully. The `namelist` is written in `()` instead of `[]`, @@ -296,6 +304,36 @@ isn't exactly like mine but it works just fine it's ok, and you can print(converted_numbers) ``` +5. ``` python + row_count = int(input("Type the number of rows needed:")) + for column_count in range(1, row_count+1): + # Print numbers from 1 to column_count + for number in range(1, column_count+1): + print(number, end=" ") + print() # creates a new line for the next row + ``` + If the user enters 5, we want to do a row with 1 column, then 2 columns, and so on until 5 columns. + That would be `for column_count in range(1, 6)`, because the end of the range is excluded. + In general, we need to specify `row_count + 1` so that it actually ends at `row_count`. + The second loop is similar. + + Usually `print(number)` puts a newline character at the end of the line, so that the next print goes to the next line. + To get all numbers on the same line, we use a space instead of a newline character, + but we still need `print()` to add a newline character once we have printed the entire row. + + + +6. ```python + row_count=int(input("Type the number of rows needed:")) + + for line_number in range(1, row_count + 1): + for number in range(line_number, row_count+1): + print(number, end=' ') + print() + ``` + Just like in the previous exercise, if the user enters 5, the first `for` loop gives the line numbers `1, 2, 3, 4, 5`.
+ For example, on line 2, we should print numbers from 2 to 5, as in `range(2, 6)`, or in general, `range(line_number, row_count+1)`. + ## Trey Hunner: zip and enumerate 1. Read some lines with `input` into a list and then enumerate it. diff --git a/basics/handy-stuff-strings.md b/basics/handy-stuff-strings.md index be89c55..c8458ce 100644 --- a/basics/handy-stuff-strings.md +++ b/basics/handy-stuff-strings.md @@ -424,6 +424,8 @@ ValueError: could not convert string to float: 'hello' print(message, "!!!") print(message, "!!!") ``` +3. Make a program to take the input from the user and check if it is a palindrome.
+ (Hint: A string is a palindrome if it is the same when reversed. Google how to reverse a string.) The answers are [here](answers.md#handy-stuff-strings). diff --git a/basics/if.md b/basics/if.md index a1fed8e..9247ed6 100644 --- a/basics/if.md +++ b/basics/if.md @@ -312,6 +312,7 @@ you are asked to "fix code", feel free to add missing blank lines. the user entered the correct password, a wrong password, or nothing at all by pressing Enter without typing anything. + The answers are [here](answers.md#if-else-and-elif). *** diff --git a/basics/loops.md b/basics/loops.md index 4abb172..4e69c60 100644 --- a/basics/loops.md +++ b/basics/loops.md @@ -470,7 +470,25 @@ while True: number = int(number) print(numbers) ``` - +5. Make a program that prints a pyramid like shown below. Ask the user to type the number of rows needed. + ``` + OUTPUT for 5 rows + 1 + 1 2 + 1 2 3 + 1 2 3 4 + 1 2 3 4 5 + ``` + +6. Make a program to get a pyramid like shown below where user can type the number of rows needed. + ``` + OUTPUT for 5 rows + 1 2 3 4 5 + 2 3 4 5 + 3 4 5 + 4 5 + 5 + ``` The answers are [here](answers.md#loops). *** From 0f840ff1b2be0355798ab8b4bd4bbe90558ddb87 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 30 Jul 2021 22:36:07 +0300 Subject: [PATCH 65/78] small tweaks --- basics/answers.md | 10 +++++----- basics/handy-stuff-strings.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/basics/answers.md b/basics/answers.md index f2fcdf1..7b53969 100644 --- a/basics/answers.md +++ b/basics/answers.md @@ -159,7 +159,7 @@ isn't exactly like mine but it works just fine it's ok, and you can 3. In the code below, `palindrome_input[::-1]` is the string `palindrome_input` reversed. For example, if `palindrome_input` is `"hello"`, then `palindrome_input[::-1]` is `"olleh"`. ```python - palindrome_input=input("Type the number to check:") + palindrome_input = input("Enter a string: ") if palindrome_input == palindrome_input[::-1]: print("This string is a palindrome") else: @@ -326,10 +326,10 @@ isn't exactly like mine but it works just fine it's ok, and you can 6. ```python row_count=int(input("Type the number of rows needed:")) - for line_number in range(1, row_count + 1): - for number in range(line_number, row_count+1): - print(number, end=' ') - print() + for line_number in range(1, row_count+1): + for number in range(line_number, row_count+1): + print(number, end=' ') + print() ``` Just like in the previous exercise, if the user enters 5, the first `for` loop gives the line numbers `1, 2, 3, 4, 5`.
For example, on line 2, we should print numbers from 2 to 5, as in `range(2, 6)`, or in general, `range(line_number, row_count+1)`. diff --git a/basics/handy-stuff-strings.md b/basics/handy-stuff-strings.md index c8458ce..03f2208 100644 --- a/basics/handy-stuff-strings.md +++ b/basics/handy-stuff-strings.md @@ -424,7 +424,7 @@ ValueError: could not convert string to float: 'hello' print(message, "!!!") print(message, "!!!") ``` -3. Make a program to take the input from the user and check if it is a palindrome.
+3. Make a program to ask a string from the user and check if it is a palindrome.
(Hint: A string is a palindrome if it is the same when reversed. Google how to reverse a string.) The answers are [here](answers.md#handy-stuff-strings). From 20e3248717ffefa74fb818e1e93622d206472f21 Mon Sep 17 00:00:00 2001 From: Ha Bach Date: Sat, 9 Jul 2022 04:52:09 -0700 Subject: [PATCH 66/78] redirect Porcupine install link to Porcupine GitHub README (#36) --- basics/editor-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/editor-setup.md b/basics/editor-setup.md index 2ad224b..ccf71ce 100644 --- a/basics/editor-setup.md +++ b/basics/editor-setup.md @@ -26,7 +26,7 @@ everything and recommend to everyone. If you aren't sure about which editor you should use, I recommend Porcupine. It's a simple editor I wrote in Python; it lets you edit files and it doesn't have too many other featues. [Install it with these -instructions](https://github.com/Akuli/porcupine/wiki/Installing-and-Running-Porcupine), +instructions](https://github.com/Akuli/porcupine/#installing-porcupine), and then [learn to use it by writing the classic Hello World program](https://github.com/Akuli/porcupine/wiki/First-Program). Then you can [skip the rest of this chapter](#editor-or--prompt). From 0e00c85d7c262e4b4e553c30e4e3dc0be04c085c Mon Sep 17 00:00:00 2001 From: Tushar Khatri Date: Sat, 10 Sep 2022 18:31:41 +0530 Subject: [PATCH 67/78] Write documentation for zip & enumerate (#37) Co-authored-by: Akuli --- README.md | 2 +- basics/dicts.md | 2 +- basics/loops.md | 2 +- basics/trey-hunner-zip-and-enumerate.md | 147 -------------- basics/zip-and-enumerate.md | 247 ++++++++++++++++++++++++ 5 files changed, 250 insertions(+), 150 deletions(-) delete mode 100644 basics/trey-hunner-zip-and-enumerate.md create mode 100644 basics/zip-and-enumerate.md diff --git a/README.md b/README.md index f201dbf..ce76d98 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ to learn more about whatever you want after studying it. 9. [Handy stuff with strings](basics/handy-stuff-strings.md) 10. [Lists and tuples](basics/lists-and-tuples.md) 11. [Loops](basics/loops.md) -12. [Trey Hunner: zip and enumerate](basics/trey-hunner-zip-and-enumerate.md) +12. [zip and enumerate](basics/zip-and-enumerate.md) 13. [Dictionaries](basics/dicts.md) 14. [Defining functions](basics/defining-functions.md) 15. [Writing a larger program](basics/larger-program.md) diff --git a/basics/dicts.md b/basics/dicts.md index 9784c5d..1c271cb 100644 --- a/basics/dicts.md +++ b/basics/dicts.md @@ -332,5 +332,5 @@ star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See [LICENSE](../LICENSE). -[Previous](trey-hunner-zip-and-enumerate.md) | [Next](defining-functions.md) | +[Previous](zip-and-enumerate.md) | [Next](defining-functions.md) | [List of contents](../README.md#basics) diff --git a/basics/loops.md b/basics/loops.md index 4e69c60..5412257 100644 --- a/basics/loops.md +++ b/basics/loops.md @@ -501,5 +501,5 @@ star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See [LICENSE](../LICENSE). -[Previous](lists-and-tuples.md) | [Next](trey-hunner-zip-and-enumerate.md) | +[Previous](lists-and-tuples.md) | [Next](zip-and-enumerate.md) | [List of contents](../README.md#basics) diff --git a/basics/trey-hunner-zip-and-enumerate.md b/basics/trey-hunner-zip-and-enumerate.md deleted file mode 100644 index 3a211de..0000000 --- a/basics/trey-hunner-zip-and-enumerate.md +++ /dev/null @@ -1,147 +0,0 @@ -# Trey Hunner: zip and enumerate - -Now we know how [for loops](loops.md#for-loops) work in Python. But -for loops aren't limited to printing each item in a list, they can -do a lot more. - -To be able to understand for loop tricks we need to first know -assigning values to multiple variables at once. It works like this: - -```python ->>> a, b = 1, 2 ->>> a -1 ->>> b -2 ->>> -``` - -We can use `()` and `[]` around these values however we want and -everything will still work the same way. `[]` creates a list, and -`()` creates a tuple. - -```python ->>> [a, b] = (1, 2) ->>> a -1 ->>> b -2 ->>> -``` - -We can also have `[]` or `()` on one side but not on the other -side. - -```python ->>> (a, b) = 1, 2 ->>> a -1 ->>> b -2 ->>> -``` - -Python created a tuple automatically. - -```python ->>> 1, 2 -(1, 2) ->>> -``` - -If we're for looping over a list with pairs of values in it we -could do this: - -```python ->>> items = [('a', 1), ('b', 2), ('c', 3)] ->>> for pair in items: -... a, b = pair -... print(a, b) -... -a 1 -b 2 -c 3 ->>> -``` - -Or we can tell the for loop to unpack it for us. - -```python ->>> for a, b in items: -... print(a, b) -... -a 1 -b 2 -c 3 ->>> -``` - -Now you're ready to read [this awesome looping -tutorial](http://treyhunner.com/2016/04/how-to-loop-with-indexes-in-python/). -Read it now, then come back here and do the exercises. - -## Exercises - -1. Create a program that works like this. Here I entered everything - after the `>` prompt that the program displayed. - - ``` - Enter something, and press Enter without typing anything when you're done. - >hello there - >this is a test - >it seems to work - > - Line 1 is: hello there - Line 2 is: this is a test - Line 3 is: it seems to work - ``` - -2. Create a program that prints all letters from A to Z and a to z - next to each other: - - ``` - A a - B b - C c - ... - X x - Y y - Z z - ``` - - Start your program like this: - - ```python - uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - lowercase = 'abcdefghijklmnopqrstuvwxyz' - ``` - - **Hint:** how do strings behave with `zip`? Try it out on the - `>>>` prompt and see. - -3. Can you make it print the indexes also? - - ``` - 1 A a - 2 B b - 3 C c - ... - 24 X x - 25 Y y - 26 Z z - ``` - -The answers are [here](answers.md). - -*** - -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a -star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). - -You may use this tutorial freely at your own risk. See -[LICENSE](../LICENSE). - -[Previous](loops.md) | [Next](dicts.md) | -[List of contents](../README.md#basics) diff --git a/basics/zip-and-enumerate.md b/basics/zip-and-enumerate.md new file mode 100644 index 0000000..07c36ad --- /dev/null +++ b/basics/zip-and-enumerate.md @@ -0,0 +1,247 @@ +# zip and enumerate + +Now we know how [for loops](loops.md#for-loops) work in Python. But +for loops aren't limited to printing each item in a list, they can +do a lot more. + +To be able to understand for loop tricks we need to first know +assigning values to multiple variables at once. It works like this: + +```python +>>> a, b = 1, 2 +>>> a +1 +>>> b +2 +>>> +``` + +We can use `()` and `[]` around these values however we want and +everything will still work the same way. `[]` creates a list, and +`()` creates a tuple. + +```python +>>> [a, b] = (1, 2) +>>> a +1 +>>> b +2 +>>> +``` + +We can also have `[]` or `()` on one side but not on the other +side. + +```python +>>> (a, b) = 1, 2 +>>> a +1 +>>> b +2 +>>> +``` + +Python created a tuple automatically. + +```python +>>> 1, 2 +(1, 2) +>>> +``` + +If we're for looping over a list with pairs of values in it we +could do this: + +```python +>>> items = [('a', 1), ('b', 2), ('c', 3)] +>>> for pair in items: +... a, b = pair +... print(a, b) +... +a 1 +b 2 +c 3 +>>> +``` + +Or we can tell the for loop to unpack it for us. + +```python +>>> for a, b in items: +... print(a, b) +... +a 1 +b 2 +c 3 +>>> +``` + +This feature is often used with Python's built-in `zip()` and `enumerate()` functions. + + +## zip + +What comes to your mind when you hear the word `zip`? A mechanism extensively used to tie two parts of something, e.g. shirt or jacket. Python's `zip()` functions does pretty much the same, it helps us tie corresponding items together. + +```python +>>> users = ["Tushar", "Aman", "Anurag", "Sohit"] +>>> uids = ["usr122", "usr123", "usr124", "usr125"] +>>> user_details = zip(uids, users) +>>> print(list(user_details)) +[('usr122', 'Tushar'), ('usr123', 'Aman'), ('usr124', 'Anurag'), ('usr125', 'Sohit')] +>>> +``` + +Note that `print(user_details)` doesn't work as expected: + +``` +>>> print(user_details) + +>>> +``` + +This is because `zip()` is an iterator, i.e. lazy: it gives the items as needed, instead of calculating them and storing them into memory all at once like a list. So the zip object cannot show its elements before the elements are used, because it hasn't computed them yet. + +```python +>>> users = ["Tushar", "Aman", "Anurag", "Sohit"] +>>> uids = ["usr122", "usr123", "usr124", "usr125"] +>>> user_details = zip(uids, users) +``` + +If the lists are of different lengths, some items from the end of the longer list will be ignored. +```python +>>> users = ["Tushar", "Aman", "Anurag"] +>>> emails = ["tushar@example.com", "aman@example.com", "anurag@example.com", "sohit@example.com"] +>>> users_contact = zip(users, emails) +>>> print(list(users_contact)) +[('Tushar', 'tushar@example.com'), ('Aman', 'aman@example.com'), ('Anurag', 'anurag@example.com')] +>>> +``` + + +Here the shortest list is `users`, with length 3, so `zip(users, emails)` only takes the first 3 emails. +We do not recommend calling `zip()` with lists of different lengths, because ignoring items is usually not what you intended to do. + +### Using zip in a `for` loop + +It is very common to `for` loop over a `zip()`, and unpack the returned tuples in the `for` loop. +This is why we introduced unpacking in the beginning of this page. +When used this way, there's no need to convert the result of `zip(...)` to a list. + +```python +>>> roll_nums = [20, 25, 28] +>>> students = ["Joe", "Max", "Michel"] +>>> for roll_num, student in zip(roll_nums, students): +... print(f"Roll number of {student} is {roll_num}") +... +Roll number of Joe is 20 +Roll number of Max is 25 +Roll number of Michel is 28 +>>> +``` + +## enumerate + +`enumerate()` is an amazing Built-in function offered by python. When used, gives us the index and the item combined. + +```python +>>> even_nums = [2, 4, 6, 8, 10, 12] +>>> for index, item in enumerate(even_nums): +... print(f"Index of {item} is {index}") +... +Index of 2 is 0 +Index of 4 is 1 +Index of 6 is 2 +Index of 8 is 3 +Index of 10 is 4 +Index of 12 is 5 +>>> +``` + +It is also possible (but more difficult) to do this without `enumerate()`: + +```python +>>> even_nums = [2, 4, 6, 8, 10, 12] +>>> for index in range(0, len(even_nums)): +... print(f"Index of {even_nums[index]} is {index}") +... +Index of 2 is 0 +Index of 4 is 1 +Index of 6 is 2 +Index of 8 is 3 +Index of 10 is 4 +Index of 12 is 5 +>>> +``` + +Here: +* `range(0, len(even_nums))` gives 0,1,2,3,4,5, with the list length 6 excluded. These are the indexes of our list of length 6. +* `even_nums[index]` prints each element of `even_nums`, because `index` comes from the range of all indexes into that list. + +Because this is complicated to think about and easy to get wrong, it is better to use `enumerate()`. + +## Exercises + +1. Create a program that works like this. Here I entered everything + after the `>` prompt that the program displayed. + + ``` + Enter something, and press Enter without typing anything when you're done. + >hello there + >this is a test + >it seems to work + > + Line 1 is: hello there + Line 2 is: this is a test + Line 3 is: it seems to work + ``` + +2. Create a program that prints all letters from A to Z and a to z + next to each other: + + ``` + A a + B b + C c + ... + X x + Y y + Z z + ``` + + Start your program like this: + + ```python + uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + lowercase = 'abcdefghijklmnopqrstuvwxyz' + ``` + + **Hint:** how do strings behave with `zip`? Try it out on the + `>>>` prompt and see. + +3. Can you make it print the indexes also? + + ``` + 1 A a + 2 B b + 3 C c + ... + 24 X x + 25 Y y + 26 Z z + ``` + +The answers are [here](answers.md). + +*** + +If you have trouble with this tutorial please [tell me about +it](../contact-me.md) and I'll make this tutorial better. If you +like this tutorial, please [give it a +star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). + +You may use this tutorial freely at your own risk. See +[LICENSE](../LICENSE). + +[Previous](loops.md) | [Next](dicts.md) | +[List of contents](../README.md#basics) From e1bd0fccde433fda86e99965ebc0175a975cec20 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 10 Sep 2022 16:07:55 +0300 Subject: [PATCH 68/78] Fix make-html.py --- make-html.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/make-html.py b/make-html.py index 4ae6d5a..cf51e71 100755 --- a/make-html.py +++ b/make-html.py @@ -30,25 +30,26 @@ import argparse import os +import platform import posixpath import shutil import sys import textwrap import webbrowser +if platform.system() == 'Windows': + python = 'py' +else: + python = 'python3' + try: import mistune except ImportError: - import platform - if platform.system() == 'Windows': - python = 'py' - else: - python = 'python3' print("mistune isn't installed.", file=sys.stderr) print("You can install it by running this command on a terminal or ") print("command prompt:") print() - print(" %s -m pip install --user mistune" % python) + print(" %s -m pip install mistune" % python) sys.exit(1) try: @@ -112,7 +113,7 @@ def fix_filename(filename): return filename -class TutorialRenderer(mistune.Renderer): +class TutorialRenderer(mistune.HTMLRenderer): def __init__(self, pygments_style): super().__init__() @@ -226,8 +227,7 @@ def main(): if pygments is None: print("Pygments isn't installed. You can install it like this:") print() - print(">>> import pip") - print(">>> pip.main(['install', '--user', 'pygments'])") + print(" %s -m pip install pygments" % python) print() print("You can also continue without Pygments, but the code examples") print("will not be colored.") From d8317c90ab3578bfdabeffdc0e9bc788b6361f6d Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 10 Sep 2022 16:12:59 +0300 Subject: [PATCH 69/78] Delete unnecessary slashfix functions --- common.py | 10 ---------- linkcheck.py | 13 ++++++------- make-html.py | 13 ++++++------- update-ends.py | 6 +++--- 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/common.py b/common.py index 51c22eb..7180739 100644 --- a/common.py +++ b/common.py @@ -122,16 +122,6 @@ def askyesno(question, default=True): print("Please type y, n or nothing at all.") -def slashfix(path): - """Replace / with os.sep.""" - return path.replace('/', os.sep) - - -def slashfix_open(file, mode): - """An easy way to use slashfix() and open() together.""" - return open(slashfix(file), mode) - - @contextlib.contextmanager def backup(filename): """A context manager that backs up a file.""" diff --git a/linkcheck.py b/linkcheck.py index 35ced72..2dcd4c5 100755 --- a/linkcheck.py +++ b/linkcheck.py @@ -59,18 +59,17 @@ def check(this_file, target, title, titledict): path = posixpath.join(posixpath.dirname(this_file), target) path = posixpath.normpath(path) - real_path = common.slashfix(path) - if not os.path.exists(real_path): + if not os.path.exists(path): return "doesn't exist" if target.endswith('/'): # A directory. - if not os.path.isdir(real_path): + if not os.path.isdir(path): return "not a directory" else: # A file. - if not os.path.isfile(real_path): + if not os.path.isfile(path): return "not a file" if title is not None and title not in titledict[path]: @@ -82,7 +81,7 @@ def find_titles(filename): """Read titles of a markdown file and return a list of them.""" result = [] - with common.slashfix_open(filename, 'r') as f: + with open(filename, 'r') as f: for line in f: if line.startswith('```'): # it's a code block, let's skip to the end of it to @@ -103,7 +102,7 @@ def find_links(this_file): """ result = [] - with common.slashfix_open(this_file, 'r') as f: + with open(this_file, 'r') as f: for match, lineno in common.find_links(f): target = match.group(2) if '#' in target: @@ -122,7 +121,7 @@ def find_links(this_file): def get_line(filename, lineno): """Return the lineno'th line of a file.""" - with common.slashfix_open(filename, 'r') as f: + with open(filename, 'r') as f: for lineno2, line in enumerate(f, start=1): if lineno == lineno2: return line diff --git a/make-html.py b/make-html.py index cf51e71..b40ec3a 100755 --- a/make-html.py +++ b/make-html.py @@ -92,12 +92,11 @@ class TutorialStyle(pygments.style.Style): """ -def mkdir_slashfix_open(filename, mode): - """Like common.slashfix_open(), but make directories as needed.""" - real_filename = common.slashfix(filename) - directory = os.path.dirname(real_filename) +def mkdir_and_open(filename, mode): + """Like open(), but make directories as needed.""" + directory = os.path.dirname(filename) os.makedirs(directory, exist_ok=True) - return open(real_filename, mode) + return open(filename, mode) def fix_filename(filename): @@ -252,7 +251,7 @@ def main(): htmlfile = posixpath.join(args.outdir, fixed_file) print(' %-30.30s --> %-30.30s' % (markdownfile, htmlfile), end='\r') - with common.slashfix_open(markdownfile, 'r') as f: + with open(markdownfile, 'r') as f: markdown = f.read() renderer = TutorialRenderer(args.pygments_style) body = mistune.markdown(markdown, renderer=renderer) @@ -264,7 +263,7 @@ def main(): body=body, stylefile=stylefile, ) - with mkdir_slashfix_open(htmlfile, 'w') as f: + with mkdir_and_open(htmlfile, 'w') as f: print(html, file=f) print() diff --git a/update-ends.py b/update-ends.py index 820ef6a..2214644 100755 --- a/update-ends.py +++ b/update-ends.py @@ -85,7 +85,7 @@ def update_end(filename, end): separator. """ end = '\n***\n\n' + end - with common.slashfix_open(filename, 'r') as f: + with open(filename, 'r') as f: content = f.read() if content.endswith(end): # No need to do anything. @@ -96,11 +96,11 @@ def update_end(filename, end): # We need to remove the old ending first. print(" Removing old end:", filename) where = content.index('\n***\n') - with common.slashfix_open(filename, 'w') as f: + with open(filename, 'w') as f: f.write(content[:where]) print(" Adding end:", filename) - with common.slashfix_open(filename, 'a') as f: + with open(filename, 'a') as f: f.write(end) From 0a3536c41eb3592bfcff8461ef4ba59c1d70b635 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 10 Sep 2022 16:13:40 +0300 Subject: [PATCH 70/78] Run update-readmes.py and update-ends.py --- advanced/README.md | 2 +- basics/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/advanced/README.md b/advanced/README.md index cfa964c..f8dfd9a 100644 --- a/advanced/README.md +++ b/advanced/README.md @@ -8,7 +8,7 @@ section. Most of the techniques explained here are great when you're working on a large project, and your code would be really repetitive without these things. -You can experient with these things freely, but please **don't use these +You can experiment with these things freely, but please **don't use these techniques just because you know how to use them.** Prefer the simple techniques from the Basics part instead when possible. Simple is better than complex. diff --git a/basics/README.md b/basics/README.md index 24f8547..a9e0f8b 100644 --- a/basics/README.md +++ b/basics/README.md @@ -17,7 +17,7 @@ to learn more about whatever you want after studying it. 9. [Handy stuff with strings](handy-stuff-strings.md) 10. [Lists and tuples](lists-and-tuples.md) 11. [Loops](loops.md) -12. [Trey Hunner: zip and enumerate](trey-hunner-zip-and-enumerate.md) +12. [zip and enumerate](zip-and-enumerate.md) 13. [Dictionaries](dicts.md) 14. [Defining functions](defining-functions.md) 15. [Writing a larger program](larger-program.md) From af85e38a14794bb1ac2594885c3dcd04f1012723 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 10 Sep 2022 16:16:00 +0300 Subject: [PATCH 71/78] Fix broken links with linkcheck.py --- advanced/iters.md | 2 +- basics/defining-functions.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/advanced/iters.md b/advanced/iters.md index 3be970e..1461118 100644 --- a/advanced/iters.md +++ b/advanced/iters.md @@ -74,7 +74,7 @@ twice. >>> ``` -We have also used [enumerate](../basics/trey-hunner-zip-and-enumerate.md) +We have also used [enumerate](../basics/zip-and-enumerate.md) before, and it actually remembers its position also: ```python diff --git a/basics/defining-functions.md b/basics/defining-functions.md index ebe9e12..850def7 100644 --- a/basics/defining-functions.md +++ b/basics/defining-functions.md @@ -453,7 +453,7 @@ howdy hi Typing `say_hi` just gives us the value of the `say_hi` variable, which is the function we defined. But `say_hi()` **calls** that function, so it runs and gives us a return value. The return value is None so the -`>>>` prompt [doesn't show it](#variables.md#none). +`>>>` prompt [doesn't show it](variables.md#none). But we know that the print function shows None, so what happens if we wrap the whole thing in `print()`? From 6729ee3dc4163026ba6630de81998cc3ac8ac441 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 10 Sep 2022 16:40:34 +0300 Subject: [PATCH 72/78] Update asking help instructions --- contact-me.md | 2 +- getting-help.md | 63 +++++++++++++++++++------------------ images/discord-explore.png | Bin 0 -> 15770 bytes 3 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 images/discord-explore.png diff --git a/contact-me.md b/contact-me.md index 0f5aeea..0e23e96 100644 --- a/contact-me.md +++ b/contact-me.md @@ -13,7 +13,7 @@ it, there are a few ways to contact me: - Tell me on IRC. - I'm usually on ##learnpython and ##python-friendly on freenode. See + I'm regularly on ##learnpython on libera. See [Getting help](getting-help.md) for instructions to getting there. *** diff --git a/getting-help.md b/getting-help.md index c621433..a37ba33 100644 --- a/getting-help.md +++ b/getting-help.md @@ -3,52 +3,55 @@ When you have a problem with Python, you're not alone! There are many places to ask for help in. +Regardless of where you ask for help, please: +- Don't ask "does someone know ...". Just ask about your problem right away. +- Make your question short. +- Include everything that other people will need to answer your question. + For example, if you are getting an error, include your code and the error message. + + ## IRC -IRC is the oldest chatting service I know, but as of 2018, it's still -in use, and a great way to get help in Python. You don't need to -register anywhere, just click one of the links below and you're good to -go. - -- [##learnpython](https://kiwiirc.com/client/chat.freenode.net/##learnpython) and - [##python-friendly](https://kiwiirc.com/client/chat.freenode.net/##python-friendly) - are beginner-friendly Python support channels. In my experience, - people here tend to understand beginners' problems better, so you - probably want to go to one of these. -- [#python](https://kiwiirc.com/client/chat.freenode.net/#python) is - the official Python channel. If you have questions about advanced - topics or you need help quickly, go there. However, this channel - requires - [registering on freenode](http://www.wikihow.com/Register-a-Nickname-on-Freenode). - -Make your question short. If you want to post a code example that is -more than two lines long, post it [here](http://dpaste.com/) first. +IRC is the oldest chatting service I know, but as of 2022, it's still +in use, and a good way to get help in Python. +An advantage with IRC is that you don't need to create an account to use it. + +To get started, go to https://web.libera.chat/ and type `##learnpython` or `#python` for the channel name. + +- `##learnpython` is a channel where I am regularly, but there's usually only about 20 people there, + so it could be that nobody answers your question, depending on what time it is. + I'm on `##learnpython` at about 7PM to 10PM UTC. + If you see `Akuli` in the user list, that's me :) +- `#python` is an active channel that I don't use much, but someone will likely answer your question pretty quickly. + +If you want to post more than 3 lines of code, +put it to [dpaste.com](https://dpaste.com/) first. Just copy-paste your code to the big text area and click the "Paste it" button, and then post a link to your paste on IRC. +Otherwise every line of your code will appear as a separate message on IRC, +so if your code is 15 lines, just pasting it in will produce 15 different messages. +This would be annoying. + + +## Discord -Do this: +If you have a discord account, you can click the "Explore Public Servers" button at bottom left. - i'm trying to check if this variable equals one but i keep - getting an error http://dpaste.com/yourpaste +![Discord's explore public servers button](images/discord-explore.png) -Don't do this: +You can then search for e.g. Python, and you should find many servers to choose from. +I am currently @Akuli on a server called "The Programmer's Hangout". - HEEEEELP MEEEEEEEEEEEEEEE!!! - File "hello.py", line 3 - if a = b: - ^ - SyntaxError: invalid syntax ## Websites to ask help on Personally, I've never asked a question on any of these sites. Getting help on IRC is much faster. -- [stackoverflow](http://stackoverflow.com/) is a question/answer site +- [stackoverflow](https://stackoverflow.com/) is a question/answer site for programmers. Search for your question first, maybe someone has already asked that and it has been answered. -- At the time of writing this, - [the learnpython subreddit](https://www.reddit.com/r/learnpython/) +- [The learnpython subreddit](https://www.reddit.com/r/learnpython/) is another good place to ask Python questions on. *** diff --git a/images/discord-explore.png b/images/discord-explore.png new file mode 100644 index 0000000000000000000000000000000000000000..1162495a09e4797dbe36ced8da629e047d7f38ea GIT binary patch literal 15770 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

0sX-Mcs=SQ~QaQTu$~T)ktWHF=v!h?|gVn25X& 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 Date: Sat, 10 Sep 2022 16:44:32 +0300 Subject: [PATCH 73/78] Update footer --- README.md | 7 ++++--- TODO.md | 7 ++++--- advanced/README.md | 7 ++++--- advanced/answers.md | 7 ++++--- advanced/datatypes.md | 7 ++++--- advanced/functions.md | 7 ++++--- advanced/iters.md | 7 ++++--- advanced/magicmethods.md | 7 ++++--- basics/README.md | 7 ++++--- basics/answers.md | 7 ++++--- basics/classes.md | 7 ++++--- basics/defining-functions.md | 7 ++++--- basics/dicts.md | 7 ++++--- basics/docstrings.md | 7 ++++--- basics/editor-setup.md | 7 ++++--- basics/exceptions.md | 7 ++++--- basics/files.md | 7 ++++--- basics/getting-started.md | 7 ++++--- basics/handy-stuff-strings.md | 7 ++++--- basics/if.md | 7 ++++--- basics/installing-python.md | 7 ++++--- basics/larger-program.md | 7 ++++--- basics/lists-and-tuples.md | 7 ++++--- basics/loops.md | 7 ++++--- basics/modules.md | 7 ++++--- basics/the-way-of-the-program.md | 7 ++++--- basics/using-functions.md | 7 ++++--- basics/variables.md | 7 ++++--- basics/what-is-programming.md | 7 ++++--- basics/what-is-true.md | 7 ++++--- basics/zip-and-enumerate.md | 7 ++++--- classes.md | 7 ++++--- contact-me.md | 7 ++++--- getting-help.md | 7 ++++--- update-ends.py | 7 ++++--- what-next.md | 7 ++++--- 36 files changed, 144 insertions(+), 108 deletions(-) diff --git a/README.md b/README.md index ce76d98..f35c025 100644 --- a/README.md +++ b/README.md @@ -109,9 +109,10 @@ See [github's contributors page](https://github.com/Akuli/python-tutorial/graphs *** -If you have trouble with this tutorial please [tell me about -it](./contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](./contact-me.md) and I'll make this tutorial better, +or [ask for help online](./getting-help.md). +If you like this tutorial, please [give it a star](./README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/TODO.md b/TODO.md index 53b2bc3..ff1ecde 100644 --- a/TODO.md +++ b/TODO.md @@ -40,9 +40,10 @@ This tutorial is not complete. It still needs: *** -If you have trouble with this tutorial please [tell me about -it](./contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](./contact-me.md) and I'll make this tutorial better, +or [ask for help online](./getting-help.md). +If you like this tutorial, please [give it a star](./README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/advanced/README.md b/advanced/README.md index f8dfd9a..bbb46e5 100644 --- a/advanced/README.md +++ b/advanced/README.md @@ -20,9 +20,10 @@ than complex. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/advanced/answers.md b/advanced/answers.md index d6a4371..ca52c7f 100644 --- a/advanced/answers.md +++ b/advanced/answers.md @@ -1,9 +1,10 @@ *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/advanced/datatypes.md b/advanced/datatypes.md index 74df310..456d777 100644 --- a/advanced/datatypes.md +++ b/advanced/datatypes.md @@ -347,9 +347,10 @@ do it before Python supported `{**dict1, **dict2}`. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/advanced/functions.md b/advanced/functions.md index 6accb1e..f1f176b 100644 --- a/advanced/functions.md +++ b/advanced/functions.md @@ -290,9 +290,10 @@ does, so using keyword-only arguments makes sense. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/advanced/iters.md b/advanced/iters.md index 1461118..450e763 100644 --- a/advanced/iters.md +++ b/advanced/iters.md @@ -463,9 +463,10 @@ does the same thing as our `count()`. contains many useful iterator-related things. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/advanced/magicmethods.md b/advanced/magicmethods.md index c7f6e28..a6bb5f5 100644 --- a/advanced/magicmethods.md +++ b/advanced/magicmethods.md @@ -235,9 +235,10 @@ are not meant to be imported. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/README.md b/basics/README.md index a9e0f8b..23d1059 100644 --- a/basics/README.md +++ b/basics/README.md @@ -30,9 +30,10 @@ to learn more about whatever you want after studying it. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/answers.md b/basics/answers.md index 7b53969..b766cbf 100644 --- a/basics/answers.md +++ b/basics/answers.md @@ -473,9 +473,10 @@ isn't exactly like mine but it works just fine it's ok, and you can *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/classes.md b/basics/classes.md index 3c1f27d..0b2a284 100644 --- a/basics/classes.md +++ b/basics/classes.md @@ -416,9 +416,10 @@ print("You entered " + word + ".") *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/defining-functions.md b/basics/defining-functions.md index 850def7..8d3aa97 100644 --- a/basics/defining-functions.md +++ b/basics/defining-functions.md @@ -572,9 +572,10 @@ Answers for the first, second and third exercise are *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/dicts.md b/basics/dicts.md index 1c271cb..597d1eb 100644 --- a/basics/dicts.md +++ b/basics/dicts.md @@ -324,9 +324,10 @@ Running the program might look like this: *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/docstrings.md b/basics/docstrings.md index 7158bb3..c30cd7c 100644 --- a/basics/docstrings.md +++ b/basics/docstrings.md @@ -350,9 +350,10 @@ doing without having to read through all of the code. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/editor-setup.md b/basics/editor-setup.md index ccf71ce..06f3301 100644 --- a/basics/editor-setup.md +++ b/basics/editor-setup.md @@ -78,9 +78,10 @@ echoes it back, but if you make a file that contains nothing but a *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/exceptions.md b/basics/exceptions.md index 4ca3603..25cc3f3 100644 --- a/basics/exceptions.md +++ b/basics/exceptions.md @@ -461,9 +461,10 @@ except OSError: *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/files.md b/basics/files.md index 82705d0..5a8f7dd 100644 --- a/basics/files.md +++ b/basics/files.md @@ -365,9 +365,10 @@ else: *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/getting-started.md b/basics/getting-started.md index 720af5a..9f00625 100644 --- a/basics/getting-started.md +++ b/basics/getting-started.md @@ -212,9 +212,10 @@ enough when you need to calculate something. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/handy-stuff-strings.md b/basics/handy-stuff-strings.md index 03f2208..d3e80a9 100644 --- a/basics/handy-stuff-strings.md +++ b/basics/handy-stuff-strings.md @@ -431,9 +431,10 @@ The answers are [here](answers.md#handy-stuff-strings). *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/if.md b/basics/if.md index 9247ed6..71655f2 100644 --- a/basics/if.md +++ b/basics/if.md @@ -317,9 +317,10 @@ The answers are [here](answers.md#if-else-and-elif). *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/installing-python.md b/basics/installing-python.md index 755e509..249cc4b 100644 --- a/basics/installing-python.md +++ b/basics/installing-python.md @@ -78,9 +78,10 @@ Now you should have Python installed, and you should be able run it. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/larger-program.md b/basics/larger-program.md index f8f9bfa..ef28393 100644 --- a/basics/larger-program.md +++ b/basics/larger-program.md @@ -228,9 +228,10 @@ something else when it's imported. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/lists-and-tuples.md b/basics/lists-and-tuples.md index a231de9..379d019 100644 --- a/basics/lists-and-tuples.md +++ b/basics/lists-and-tuples.md @@ -375,9 +375,10 @@ The answers are [here](answers.md#lists-and-tuples). *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/loops.md b/basics/loops.md index 5412257..855f43d 100644 --- a/basics/loops.md +++ b/basics/loops.md @@ -493,9 +493,10 @@ The answers are [here](answers.md#loops). *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/modules.md b/basics/modules.md index b8dccbf..80d0e61 100644 --- a/basics/modules.md +++ b/basics/modules.md @@ -488,9 +488,10 @@ section at the bottom. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/the-way-of-the-program.md b/basics/the-way-of-the-program.md index ebb44bc..7def31a 100644 --- a/basics/the-way-of-the-program.md +++ b/basics/the-way-of-the-program.md @@ -38,9 +38,10 @@ learned everything. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/using-functions.md b/basics/using-functions.md index 123910a..c8255ff 100644 --- a/basics/using-functions.md +++ b/basics/using-functions.md @@ -228,9 +228,10 @@ should work normally. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/variables.md b/basics/variables.md index a272424..f1a8030 100644 --- a/basics/variables.md +++ b/basics/variables.md @@ -301,9 +301,10 @@ what you are doing. We'll learn more about it later. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/what-is-programming.md b/basics/what-is-programming.md index 40e37a6..269ce3f 100644 --- a/basics/what-is-programming.md +++ b/basics/what-is-programming.md @@ -157,9 +157,10 @@ if you don't understand the code. *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/what-is-true.md b/basics/what-is-true.md index 495aea6..a344239 100644 --- a/basics/what-is-true.md +++ b/basics/what-is-true.md @@ -213,9 +213,10 @@ if value is None: ... # best *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/basics/zip-and-enumerate.md b/basics/zip-and-enumerate.md index 07c36ad..f1332d3 100644 --- a/basics/zip-and-enumerate.md +++ b/basics/zip-and-enumerate.md @@ -235,9 +235,10 @@ The answers are [here](answers.md). *** -If you have trouble with this tutorial please [tell me about -it](../contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](../contact-me.md) and I'll make this tutorial better, +or [ask for help online](../getting-help.md). +If you like this tutorial, please [give it a star](../README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/classes.md b/classes.md index 42ecdc6..0306c61 100644 --- a/classes.md +++ b/classes.md @@ -2,9 +2,10 @@ This file has been moved [here](basics/classes.md). *** -If you have trouble with this tutorial please [tell me about -it](./contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](./contact-me.md) and I'll make this tutorial better, +or [ask for help online](./getting-help.md). +If you like this tutorial, please [give it a star](./README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/contact-me.md b/contact-me.md index 0e23e96..eff6885 100644 --- a/contact-me.md +++ b/contact-me.md @@ -18,9 +18,10 @@ it, there are a few ways to contact me: *** -If you have trouble with this tutorial please [tell me about -it](./contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](./contact-me.md) and I'll make this tutorial better, +or [ask for help online](./getting-help.md). +If you like this tutorial, please [give it a star](./README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/getting-help.md b/getting-help.md index a37ba33..e56e7a2 100644 --- a/getting-help.md +++ b/getting-help.md @@ -56,9 +56,10 @@ help on IRC is much faster. *** -If you have trouble with this tutorial please [tell me about -it](./contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](./contact-me.md) and I'll make this tutorial better, +or [ask for help online](./getting-help.md). +If you like this tutorial, please [give it a star](./README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/update-ends.py b/update-ends.py index 2214644..9b2d1ef 100755 --- a/update-ends.py +++ b/update-ends.py @@ -35,9 +35,10 @@ END_TEMPLATE = """\ -If you have trouble with this tutorial please [tell me about -it]({toplevel}/contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it]({toplevel}/contact-me.md) and I'll make this tutorial better, +or [ask for help online]({toplevel}/getting-help.md). +If you like this tutorial, please [give it a star]({toplevel}/README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See diff --git a/what-next.md b/what-next.md index bd2de84..8437d95 100644 --- a/what-next.md +++ b/what-next.md @@ -31,9 +31,10 @@ is a way to create generators *** -If you have trouble with this tutorial please [tell me about -it](./contact-me.md) and I'll make this tutorial better. If you -like this tutorial, please [give it a +If you have trouble with this tutorial, please +[tell me about it](./contact-me.md) and I'll make this tutorial better, +or [ask for help online](./getting-help.md). +If you like this tutorial, please [give it a star](./README.md#how-can-i-thank-you-for-writing-and-sharing-this-tutorial). You may use this tutorial freely at your own risk. See From 22725a44d7c8a1f18c16aba0b84bcf9f93b92115 Mon Sep 17 00:00:00 2001 From: Tushar Khatri Date: Mon, 19 Sep 2022 01:50:21 +0530 Subject: [PATCH 74/78] Replace older formatting methods with f-strings (#39) --- README.md | 2 +- basics/handy-stuff-strings.md | 75 +++-------------------------------- 2 files changed, 6 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index f35c025..e3bcca7 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ or very little programming experience. If you have programmed a lot in the past using some other language you may want to read [the official tutorial](https://docs.python.org/3/tutorial/) instead. -You can use Python 3.5 or any newer Python with this tutorial. **Don't +You can use Python 3.6 or any newer Python with this tutorial. **Don't use Python 2 because it's no longer supported.** ## List of contents diff --git a/basics/handy-stuff-strings.md b/basics/handy-stuff-strings.md index d3e80a9..b22bf9c 100644 --- a/basics/handy-stuff-strings.md +++ b/basics/handy-stuff-strings.md @@ -241,82 +241,17 @@ Instead it's recommended to use string formatting. It means putting other things in the middle of a string. Python has multiple ways to format strings. One is not necessarily -better than others, they are just different. Here's a few ways to solve -our problem: +better than others; they each have their own advantages and disadvantages. +In this tutorial, we will focus on f-strings, which is the most common and usually the easiest way. -- `.format()`-formatting, also known as new-style formatting. This - formatting style has a lot of features, but it's a little bit more - typing than `%s`-formatting. - - ```python - >>> "Hello {}.".format(name) - 'Hello Akuli.' - >>> "My name is {} and I'm on the {} channel on {}.".format(name, channel, network) - "My name is Akuli and I'm on the ##learnpython channel on freenode." - >>> - ``` - -- `%s`-formatting, also known as old-style formatting. This has less - features than `.format()`-formatting, but `'Hello %s.' % name` is - shorter and faster to type than `'Hello {}.'.format(name)`. I like - to use `%s` formatting for simple things and `.format` when I need - more powerful features. - - ```python - >>> "Hello %s." % name - 'Hello Akuli.' - >>> "My name is %s and I'm on the %s channel on %s." % (name, channel, network) - "My name is Akuli and I'm on the ##learnpython channel on freenode." - >>> - ``` - - In the second example we had `(name, channel, network)` on the right - side of the `%` sign. It was a tuple, and we'll talk more about them - [later](lists-and-tuples.md#tuples). - - If we have a variable that may be a tuple we need to wrap it in another - tuple when formatting: - - ```python - >>> thestuff = (1, 2, 3) - >>> "we have %s" % thestuff - Traceback (most recent call last): - File "", line 1, in - TypeError: not all arguments converted during string formatting - >>> "we have %s and %s" % ("hello", thestuff) - 'we have hello and (1, 2, 3)' - >>> "we have %s" % (thestuff,) - 'we have (1, 2, 3)' - >>> - ``` - - Here `(thestuff,)` was a tuple that contained nothing but `thestuff`. - -- f-strings are even less typing, but new in Python 3.6. **Use this only if - you know that nobody will need to run your code on Python versions older - than 3.6.** Here the f is short for "format", and the content of the - string is same as it would be with `.format()` but we can use variables - directly. - - ```python - >>> f"My name is {name} and I'm on the {channel} channel on {network}." - "My name is Akuli and I'm on the ##learnpython channel on freenode." - >>> - ``` - -All of these formatting styles have many other features also: +`f` in f-strings stands for "format", f-strings are string literals that have an `f` at the beginning and curly braces containing expressions that will be replaced with their values at runtime. To create f-strings, you have to add an `f` or an `F` before the opening quotes of a string. ```python ->>> 'Three zeros and number one: {:04d}'.format(1) -'Three zeros and number one: 0001' ->>> 'Three zeros and number one: %04d' % 1 -'Three zeros and number one: 0001' +>>> f"My name is {name} and I'm on the {channel} channel on {network}." +"My name is Akuli and I'm on the ##learnpython channel on freenode." >>> ``` -If you need to know more about formatting I recommend reading -[this](https://pyformat.info/). - ## Other things We can use `in` and `not in` to check if a string contains another From 78504ac5ef9f737897af7fb1456d5cb8d98eb0f1 Mon Sep 17 00:00:00 2001 From: Tushar Khatri Date: Tue, 20 Sep 2022 00:43:29 +0530 Subject: [PATCH 75/78] Replace % with f-string in basics/modules.md (#40) --- basics/modules.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/basics/modules.md b/basics/modules.md index 80d0e61..59159cd 100644 --- a/basics/modules.md +++ b/basics/modules.md @@ -369,8 +369,8 @@ for thing in things: ``` Measure how long it takes for the user to answer a question. -The `%.2f` rounds to 2 decimals, and you can find more formatting -tricks [here](https://pyformat.info/). +The `{:.2f}` rounds to 2 decimals, and you can find more formatting +tricks [here](https://docs.python.org/3/tutorial/inputoutput.html#formatted-string-literals). ```python import time @@ -381,7 +381,7 @@ end = time.time() difference = end - start if answer == '3': - print("Correct! That took %.2f seconds." % difference) + print(f"Correct! That took {difference:.2f} seconds.") else: print("That's not correct...") ``` @@ -410,7 +410,7 @@ Check what a path points to. import os import sys -print("You are currently in %s." % os.getcwd()) +print(f"You are currently in {os.getcwd()}.") while True: path = input("A path, or nothing at all to quit: ") From 5183b3dcf791eef1e575e30ab3e83f12e48ed97b Mon Sep 17 00:00:00 2001 From: Tushar Khatri Date: Sat, 24 Sep 2022 00:06:58 +0530 Subject: [PATCH 76/78] Replace % with f-strings in multiple files mentioned in issue #19 (#41) --- advanced/functions.md | 4 ++-- advanced/magicmethods.md | 13 ++++--------- basics/answers.md | 11 +---------- basics/defining-functions.md | 2 +- basics/exceptions.md | 6 +++--- basics/larger-program.md | 6 +++--- basics/loops.md | 2 +- 7 files changed, 15 insertions(+), 29 deletions(-) diff --git a/advanced/functions.md b/advanced/functions.md index f1f176b..8f54e60 100644 --- a/advanced/functions.md +++ b/advanced/functions.md @@ -50,7 +50,7 @@ For example, instead of this... ```python def get_new_info(username): - print("Changing user information of %s." % username) + print(f"Changing user information of {username}.") username = input("New username: ") password = input("New password: ") fullname = input("Full name: ") @@ -66,7 +66,7 @@ class User: # them here def change_info(self): - print("Changing user information of %s." % self.username) + print(f"Changing user information of {self.username}.") self.username = input("New username: ") self.password = input("New password: ") self.fullname = input("Full name: ") diff --git a/advanced/magicmethods.md b/advanced/magicmethods.md index a6bb5f5..c333bbe 100644 --- a/advanced/magicmethods.md +++ b/advanced/magicmethods.md @@ -112,13 +112,10 @@ the message is 'hello' Combining `repr()` with [string formatting](../basics/handy-stuff-strings.md#string-formatting) is also -easy. `%` formatting has a `%r` formatter, and `.format()` formatting -has a `!r` flag. +easy. ```python ->>> print("the message is %r" % (message,)) -the message is 'hello' ->>> print("the message is {!r}".format(message)) +>>> print(f"the message is {repr(message)}") the message is 'hello' >>> ``` @@ -155,8 +152,7 @@ follow one of these styles: ... self.name = name ... self.founding_year = founding_year ... def __repr__(self): - ... return 'Website(name=%r, founding_year=%r)' % ( - ... self.name, self.founding_year) + ... return f'Website(name={repr(self.name)}, founding_year={repr(self.founding_year)})' ... >>> github = Website('GitHub', 2008) >>> github @@ -174,8 +170,7 @@ follow one of these styles: ... self.name = name ... self.founding_year = founding_year ... def __repr__(self): - ... return '' % ( - ... self.name, self.founding_year) + ... return f'' ... >>> github = Website('GitHub', 2008) >>> github diff --git a/basics/answers.md b/basics/answers.md index b766cbf..2e7f51a 100644 --- a/basics/answers.md +++ b/basics/answers.md @@ -100,16 +100,7 @@ isn't exactly like mine but it works just fine it's ok, and you can just fine if we run it, but there's a problem. The last line is really long and it's hard to see what it does. - The solution is string formatting. At the time of writing this, I - recommend replacing the last line with one of these: - - ```python - print("You entered %s, %s, %s and %s." % (word1, word2, word3, word4)) - print("You entered {}, {}, {} and {}.".format(word1, word2, word3, word4)) - ``` - - In the future when most people will have Python 3.6 or newer, you - can also use this: + The solution is string formatting. I recommend replacing the last line with this: ```python print(f"You entered {word1}, {word2}, {word3} and {word4}.") diff --git a/basics/defining-functions.md b/basics/defining-functions.md index 8d3aa97..9b78b94 100644 --- a/basics/defining-functions.md +++ b/basics/defining-functions.md @@ -510,7 +510,7 @@ colors = ['red', 'yellow', 'blue', 'green', 'orange', 'pink', 'black', 'gray', 'white', 'brown'] choice = ask_until_correct("What's your favorite color?", colors, error_message="I don't know that color.") -print("Your favorite color is %s!" % choice) +print(f"Your favorite color is {choice}!") ``` ## Summary diff --git a/basics/exceptions.md b/basics/exceptions.md index 25cc3f3..785fb18 100644 --- a/basics/exceptions.md +++ b/basics/exceptions.md @@ -249,9 +249,9 @@ text = input("Enter a number: ") try: number = int(text) except ValueError: - print("'%s' is not a number." % text, file=sys.stderr) + print(f"'{text}' is not a number.", file=sys.stderr) sys.exit(1) -print("Your number doubled is %d." % (number * 2)) +print(f"Your number doubled is {(number * 2)}.") ``` ## Raising exceptions @@ -452,7 +452,7 @@ def greet(): try: greet() except OSError: - print("Cannot read '%s'!" % filename, file=sys.stderr) + print(f"Cannot read '{filename}'!", file=sys.stderr) if askyesno("Would you like to create a default greeting file?"): with open(filename, 'w') as f: print(default_greeting, file=f) diff --git a/basics/larger-program.md b/basics/larger-program.md index ef28393..4cd0cda 100644 --- a/basics/larger-program.md +++ b/basics/larger-program.md @@ -82,7 +82,7 @@ def ask_questions(answers): print("Correct!") correct.append(question) else: - print("Wrong! The correct answer is %s." % answer) + print(f"Wrong! The correct answer is {answer}.") wrong.append(question) return (correct, wrong) @@ -181,11 +181,11 @@ def ask_questions(answers): wrong = [] for question, answer in answers.items(): - if input('%s = ' % question).strip() == answer: + if input(f'{question} = ').strip() == answer: print("Correct!") correct.append(question) else: - print("Wrong! The correct answer is %s." % answer) + print(f"Wrong! The correct answer is {answer}.") wrong.append(question) return (correct, wrong) diff --git a/basics/loops.md b/basics/loops.md index 855f43d..7f693e1 100644 --- a/basics/loops.md +++ b/basics/loops.md @@ -416,7 +416,7 @@ while True: print("I don't know anybody yet.") else: for name in namelist: - print("I know %s!" % name) + print(f"I know {name}!") else: print("I don't understand :(") From 48a2e2472bb0bcaf06e75976db3ebfd244d4ab99 Mon Sep 17 00:00:00 2001 From: Sarvesh Kumar Dwivedi Date: Sun, 2 Oct 2022 23:12:55 +0530 Subject: [PATCH 77/78] Fix a few typos (#43) --- README.md | 2 +- basics/answers.md | 2 +- basics/editor-setup.md | 2 +- basics/handy-stuff-strings.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e3bcca7..f8e350d 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ than complex. - **Important:** [getting help](getting-help.md) - [Contact me](contact-me.md) -- Answers for excercises in [basics](basics/answers.md) and +- Answers for exercises in [basics](basics/answers.md) and [advanced](advanced/answers.md) sections - [The TODO list](TODO.md) diff --git a/basics/answers.md b/basics/answers.md index 2e7f51a..766ec70 100644 --- a/basics/answers.md +++ b/basics/answers.md @@ -25,7 +25,7 @@ isn't exactly like mine but it works just fine it's ok, and you can `print('You entered:', something)`. 2. The broken code has mostly the same issues as exercise 1. Here are - the problems that excercise 1 doesn't have: + the problems that exercise 1 doesn't have: - The if-elif-else has a blank line at a confusing place. Delete it. - After deleting the code, it looks quite dense. Add a new blank diff --git a/basics/editor-setup.md b/basics/editor-setup.md index 06f3301..c9dad39 100644 --- a/basics/editor-setup.md +++ b/basics/editor-setup.md @@ -25,7 +25,7 @@ everything and recommend to everyone. If you aren't sure about which editor you should use, I recommend Porcupine. It's a simple editor I wrote in Python; it lets you edit -files and it doesn't have too many other featues. [Install it with these +files and it doesn't have too many other features. [Install it with these instructions](https://github.com/Akuli/porcupine/#installing-porcupine), and then [learn to use it by writing the classic Hello World program](https://github.com/Akuli/porcupine/wiki/First-Program). Then diff --git a/basics/handy-stuff-strings.md b/basics/handy-stuff-strings.md index b22bf9c..98d5cc4 100644 --- a/basics/handy-stuff-strings.md +++ b/basics/handy-stuff-strings.md @@ -327,7 +327,7 @@ ValueError: could not convert string to float: 'hello' - Python has many string methods. Use [the documentation](https://docs.python.org/3/library/stdtypes.html#string-methods) - or `help(str)` when you don't rememeber something about them. + or `help(str)` when you don't remember something about them. - String formatting means adding other things to the middle of a string. There are multiple ways to do this in Python. You should know how to use at least one of these ways. From e1127026eac08cb06ef5be1da8887d15e5457d5b Mon Sep 17 00:00:00 2001 From: George Rahul <75750164+georgerahul24@users.noreply.github.com> Date: Mon, 12 Dec 2022 15:19:57 +0530 Subject: [PATCH 78/78] Rewrite editor lists in editor-setup.md (#46) Co-authored-by: Akuli --- basics/editor-setup.md | 79 +++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/basics/editor-setup.md b/basics/editor-setup.md index c9dad39..be13ea5 100644 --- a/basics/editor-setup.md +++ b/basics/editor-setup.md @@ -13,9 +13,8 @@ like automatically displaying different things with different colors, but also highlighting mistakes in the code, and coloring syntax. If you are on Windows or Mac OSX you have probably noticed that your -Python came with an editor called IDLE. We are not going to use it -because it's lacking some important features, and most experienced -programmers (including me) don't use it or recommend it. +Python came with an editor called IDLE. You can use IDLE, but we recommend exploring other options first. + ## Which editor? @@ -23,38 +22,48 @@ The choice of an editor is a very personal thing. There are many editors, and most programmers have a favorite editor that they use for everything and recommend to everyone. -If you aren't sure about which editor you should use, I recommend -Porcupine. It's a simple editor I wrote in Python; it lets you edit -files and it doesn't have too many other features. [Install it with these -instructions](https://github.com/Akuli/porcupine/#installing-porcupine), -and then [learn to use it by writing the classic Hello World -program](https://github.com/Akuli/porcupine/wiki/First-Program). Then -you can [skip the rest of this chapter](#editor-or--prompt). - -Note that most other editors come with settings that are not suitable -for writing Python code. _**TODO:** add a link to the old editor setup -tutorial here._ - -Most of these editors lack some important features, they have so many -features that confuse people or they aren't free. You can use these -editors if you like them, but **these editors are BAD for getting -started with programming**: - -- PyCharm -- IDLE -- Emacs -- Gedit -- Nano -- NetBeans -- Notepad -- Pluma -- Spyder -- Vim -- Wingware - -This list doesn't contain all bad editors, but these are editors that -people often try to use. If you know a bad editor and you think I should -mention it here, please [let me know](../contact-me.md). +The editors can be broadly divided into three categories: + +#### The Basic Text Editors +These editors usually come with the operating system. They do not have features like +running code, auto-completion, etc. that make programming easier. They are usually used for relatively simple +text editing. Most programmers do not use these editors for programming. + +A few popular ones in this category are: +- Notepad (Windows) +- Gedit (Linux) +- Notepad ++ (Windows) +- Nano (Linux/Mac OS) + +#### Smart Text Editors +The text editors in this category have features like auto-completion, syntax highlighting, +running and debugging code, highlighting errors, etc. They are relatively easy to learn and have the necessary features +to start your programming journey. + +A few popular ones in this category are: +- Visual Studio Code / VS Code (Windows/Linux/Mac OS) +- IDLE (Usually comes with Python) (Windows/Linux/Mac OS) +- Thonny (Windows/Linux/Mac OS) +- [Porcupine](https://github.com/Akuli/porcupine) (created by the author of this tutorial) (Windows/Linux/Mac OS) +- Geany (Windows/Linux/Mac OS) + +**We recommend that you look into a few of these editors and install your favorite one.** + +#### IDEs and advanced editors +This category of text editors are usually professional grade pieces of software. They are mostly proprietary and paid. They have a steep +learning curve because of how many features they have. +These types of editors are generally not preferred +in the beginning stage. They are meant to be used for writing complex and large pieces of software. + +A few popular ones in this category are: +- Visual Studio (Not be confused with *Visual Studio Code*) (Windows) +- Pycharm (Windows/Linux/Mac OS) +- Vim (Windows/Linux/Mac OS) +- Emacs (Windows/Linux/Mac OS) + +As already mentioned, there are no "right" or "wrong" editors. The preference of an editor +is a personal choice and we recommend trying different editors. +The lists on this page don't contain all editors, but just a few of the most popular ones. ## Editor or `>>>` prompt?