{"id":"reading-files-open-and-read","slug":"open-and-read","title":"Opening and reading a file","text":"So far, a program's data has come from the keyboard with `input`, or it was written in the code itself. Most real data lives in **files**: the contacts in a phone, the scores of a game, the measurements a weather station has saved. A program that reads its data from a file handles ten lines or a million lines just as easily.\n\nThis course works with **text files**: files that hold nothing but lines of text, like the ones you'd write in a plain text editor. (A word processor's document is not one: it also stores fonts, layout and more, in a format of its own.)\n\n### open and with\n\nHere is a file called `motto.txt`, with two lines of text in it:\n\n```file motto.txt\nPractice a little every day.\nSmall steps add up.\n```\n\nThis program opens the file, reads everything in it and prints it:\n\n```python\nwith open(\"motto.txt\") as file:\n    contents = file.read()\n    print(contents)\n```\n\n```output\nPractice a little every day.\nSmall steps add up.\n```\n\n- `open(\"motto.txt\")` opens the file with that name.\n- The **`with`** statement keeps the file open while its indented block runs, and closes it when the block ends. `as file` gives the open file a name. That variable is called a **file handle**: the program reaches the file through it. Any variable name works; `file` is simply clear.\n- The method `read()` reads the whole file and returns it as one string.\n\nClosing files matters: an open file uses up resources, and a file that is written but never closed can lose data. With `with`, Python closes the file for you, even when something goes wrong inside the block.\n\n### Where the file must be\n\n`open(\"motto.txt\")` looks for the file in the folder the program runs in. On your own computer, which folder that is depends on how you start Python, which is a common source of confusion. On this site it's simple: the files a task gives are in the same folder as your program, so the file name alone is enough.\n\nWhen there is no file of that name, Python stops with a `FileNotFoundError` that names the file it looked for. Check the spelling then: `Motto.txt`, `motto.text` and `motto.txt` are three different names. A later module shows how a program can handle such errors itself.\n\n### What read gives you\n\nThe string that `read()` returns has the line breaks of the file in it, each written `\\n` in Python. You can do with it anything you can do with a string. The file is closed after the `with` block, but the string stays in its variable:\n\n```file reminder.txt\nWater the plants.\nCall grandma on Sunday.\n```\n\n```python\nwith open(\"reminder.txt\") as file:\n    contents = file.read()\n\nprint(len(contents))\nprint(\"Sunday\" in contents)\nprint(\"sunday\" in contents)\n```\n\n```output\n42\nTrue\nFalse\n```\n\nThe 42 characters include the two line breaks, one at the end of each line. And as always with strings, capital letters matter.\n\nOne more thing about the tasks on this site: a test can give your program a different file under the same name, so the program must really read the file. Printing text copied from the task won't pass.\n","task":"Fill in the blanks so the program opens the file `welcome.txt`, reads all of it and prints it. With this file\n\n```text\nWelcome to the reading room.\nPlease speak quietly.\n```\n\nthe program prints:\n\n```\nWelcome to the reading room.\nPlease speak quietly.\n```\n","kind":"fill","seed":"with [[open]](\"welcome.txt\") as file:\n    text = file.[[read]]()\nprint(text)\n","solution":"with open(\"welcome.txt\") as file:\n    text = file.read()\nprint(text)\n","hints":["The first blank is the function that opens a file, and the second is the file handle's method that reads all of it. The lesson's first example has both.","Fill in `open` and `read`. The parentheses after `read` are already there: a method call always needs them."],"tests":[{"name":"Test 1","stdin":"","files":{"welcome.txt":"Welcome to the reading room.\nPlease speak quietly.\n"},"expect":"Welcome to the reading room.\nPlease speak quietly.","hidden":false},{"name":"Test 2","stdin":"","files":{"welcome.txt":"Opening hours are from 9 to 17.\nClosed on Sundays.\nHave a nice day!\n"},"expect":"Opening hours are from 9 to 17.\nClosed on Sundays.\nHave a nice day!","hidden":true}],"require":[],"forbid":[],"more":[{"task":"The file `journal.txt` is someone's journal. Write a program that asks for a word, reads the whole file and prints `Found it` if the word appears anywhere in the file, or `Not there` if it doesn't. Capital letters matter, as they do with `in`.\n\nWith this file\n\n```text\nMonday: sunny and warm.\nTuesday: rain all day.\nWednesday: windy.\n```\n\na run looks like this:\n\n```\nSearch for: rain\nFound it\n```\n","kind":"code","seed":"word = input(\"Search for: \")\n","solution":"word = input(\"Search for: \")\nwith open(\"journal.txt\") as file:\n    contents = file.read()\nif word in contents:\n    print(\"Found it\")\nelse:\n    print(\"Not there\")\n","hints":["Open `journal.txt` with `with open(...) as file:` and read it all into a variable with `file.read()`.","The whole file is now one string, so `word in contents` tells whether the word is somewhere in it.","Then an `if` with an `else` prints one of the two messages."],"tests":[{"name":"Test 1","stdin":"rain\n","files":{"journal.txt":"Monday: sunny and warm.\nTuesday: rain all day.\nWednesday: windy.\n"},"expect":"Search for: rain\nFound it","hidden":false},{"name":"Test 2","stdin":"snow\n","files":{"journal.txt":"Monday: sunny and warm.\nTuesday: rain all day.\nWednesday: windy.\n"},"expect":"Search for: snow\nNot there","hidden":true},{"name":"Test 3","stdin":"cat\n","files":{"journal.txt":"Fed the cat at seven.\nRead a book about birds.\n"},"expect":"Search for: cat\nFound it","hidden":true}],"require":[],"forbid":[]},{"task":"This program should print `Shopping list:` and then the contents of the file `shopping.txt`, but it has two mistakes. Fix them. With this file\n\n```text\neggs\nrice\ntomatoes\n```\n\nthe program prints:\n\n```\nShopping list:\neggs\nrice\ntomatoes\n```\n","kind":"code","seed":"with open(\"Shopping.txt\") as file:\n    items = file.read\nprint(\"Shopping list:\")\nprint(items)\n","solution":"with open(\"shopping.txt\") as file:\n    items = file.read()\nprint(\"Shopping list:\")\nprint(items)\n","hints":["Run it and read the error. A `FileNotFoundError` names the file Python looked for. Compare that name with the task's, letter by letter.","Once the file opens, look at what gets printed. `file.read` without parentheses is the method itself, not a call to it: add `()`."],"tests":[{"name":"Test 1","stdin":"","files":{"shopping.txt":"eggs\nrice\ntomatoes\n"},"expect":"Shopping list:\neggs\nrice\ntomatoes","hidden":false},{"name":"Test 2","stdin":"","files":{"shopping.txt":"coffee\noat milk\n"},"expect":"Shopping list:\ncoffee\noat milk","hidden":true}],"require":[],"forbid":[]}]}