Skip to content

Instantly share code, notes, and snippets.

@icychocolate98
Created January 14, 2022 19:22
Show Gist options
  • Save icychocolate98/a4afe5ea59d350844f4a262631746451 to your computer and use it in GitHub Desktop.
Save icychocolate98/a4afe5ea59d350844f4a262631746451 to your computer and use it in GitHub Desktop.
Python "write_edit_save" files introduction
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<center>\n",
" <img src=\"https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/IDSNlogo.png\" width=\"300\" alt=\"cognitiveclass.ai logo\" />\n",
"</center>\n",
"\n",
"# Write and Save Files in Python\n",
"\n",
"Estimated time needed: **25** minutes\n",
"\n",
"## Objectives\n",
"\n",
"After completing this lab you will be able to:\n",
"\n",
"* Write to files using Python libraries\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2>Table of Contents</h2>\n",
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n",
" <ul>\n",
" <li><a href=\"https://write/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">Writing Files</a></li>\n",
" <li><a href=\"https://append/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">Appending Files</a></li>\n",
" <li><a href=\"https://add/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">Additional File modes</a></li>\n",
" <li><a href=\"https://copy/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">Copy a File</a></li>\n",
" </ul>\n",
"\n",
"</div>\n",
"\n",
"<hr>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 id=\"write\">Writing Files</h2>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can open a file object using the method <code>write()</code> to save the text file to a list. To write to a file, the mode argument must be set to **w**. Let’s write a file **Example2.txt** with the line: **“This is line A”**\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# Write line to file\n",
"exmp2 = 'Example2.txt'\n",
"with open(exmp2, 'w') as writefile:\n",
" writefile.write(\"This is line A\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can read the file to see if it worked:\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is line A\n"
]
}
],
"source": [
"# Read file\n",
"\n",
"with open(exmp2, 'r') as testwritefile:\n",
" print(testwritefile.read())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can write multiple lines:\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# Write lines to file\n",
"\n",
"with open(exmp2, 'w') as writefile:\n",
" writefile.write(\"This is line A\\n\")\n",
" writefile.write(\"This is line B\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The method <code>.write()</code> works similar to the method <code>.readline()</code>, except instead of reading a new line it writes a new line. The process is illustrated in the figure. The different colour coding of the grid represents a new line added to the file after each method call.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%204/images/WriteLine.png\" width=\"500\" />\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can check the file to see if your results are correct\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is line A\n",
"This is line B\n",
"\n"
]
}
],
"source": [
"# Check whether write to file\n",
"\n",
"with open(exmp2, 'r') as testwritefile:\n",
" print(testwritefile.read())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We write a list to a **.txt** file as follows:\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['This is line A\\n', 'This is line B\\n', 'This is line C\\n']"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Sample list of text\n",
"\n",
"Lines = [\"This is line A\\n\", \"This is line B\\n\", \"This is line C\\n\"]\n",
"Lines"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is line A\n",
"\n",
"This is line B\n",
"\n",
"This is line C\n",
"\n"
]
}
],
"source": [
"# Write the strings in the list to text file\n",
"\n",
"with open('Example2.txt', 'w') as writefile:\n",
" for line in Lines:\n",
" print(line)\n",
" writefile.write(line)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can verify the file is written by reading it and printing out the values:\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is line A\n",
"This is line B\n",
"This is line C\n",
"\n"
]
}
],
"source": [
"# Verify if writing to file is successfully executed\n",
"\n",
"with open('Example2.txt', 'r') as testwritefile:\n",
" print(testwritefile.read())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"However, note that setting the mode to **w** overwrites all the existing data in the file.\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Overwrite\n",
"\n"
]
}
],
"source": [
"with open('Example2.txt', 'w') as writefile:\n",
" writefile.write(\"Overwrite\\n\")\n",
"with open('Example2.txt', 'r') as testwritefile:\n",
" print(testwritefile.read())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<hr>\n",
"<h2 id=\"Append\">Appending Files</h2>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can write to files without losing any of the existing data as follows by setting the mode argument to append: **a**. you can append a new line as follows:\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# Write a new line to text file\n",
"\n",
"with open('Example2.txt', 'a') as testwritefile:\n",
" testwritefile.write(\"This is line C\\n\")\n",
" testwritefile.write(\"This is line D\\n\")\n",
" testwritefile.write(\"This is line E\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can verify the file has changed by running the following cell:\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Overwrite\n",
"This is line C\n",
"This is line D\n",
"This is line E\n",
"\n"
]
}
],
"source": [
"# Verify if the new line is in the text file\n",
"\n",
"with open('Example2.txt', 'r') as testwritefile:\n",
" print(testwritefile.read())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<hr>\n",
"<h2 id=\"add\">Additional modes</h2> \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It's fairly ineffecient to open the file in **a** or **w** and then reopening it in **r** to read any lines. Luckily we can access the file in the following modes:\n",
"\n",
"* **r+** : Reading and writing. Cannot truncate the file.\n",
"* **w+** : Writing and reading. Truncates the file.\n",
"* **a+** : Appending and Reading. Creates a new file, if none exists.\n",
"\n",
"You dont have to dwell on the specifics of each mode for this lab.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's try out the **a+** mode:\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"with open('Example2.txt', 'a+') as testwritefile:\n",
" testwritefile.write(\"This is line E\\n\")\n",
" print(testwritefile.read())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There were no errors but <code>read()</code> also did not output anything. This is because of our location in the file.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most of the file methods we've looked at work in a certain location in the file. <code>.write() </code> writes at a certain location in the file. <code>.read()</code> reads at a certain location in the file and so on. You can think of this as moving your pointer around in the notepad to make changes at specific location.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Opening the file in **w** is akin to opening the .txt file, moving your cursor to the beginning of the text file, writing new text and deleting everything that follows.\n",
"Whereas opening the file in **a** is similiar to opening the .txt file, moving your cursor to the very end and then adding the new pieces of text. <br>\n",
"It is often very useful to know where the 'cursor' is in a file and be able to control it. The following methods allow us to do precisely this -\n",
"\n",
"* <code>.tell()</code> - returns the current position in bytes\n",
"* <code>.seek(offset,from)</code> - changes the position by 'offset' bytes with respect to 'from'. From can take the value of 0,1,2 corresponding to beginning, relative to current position and end\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now lets revisit **a+**\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Initial Location: 70\n",
"Read nothing\n",
"\n",
"New Location : 0\n",
"Overwrite\n",
"This is line C\n",
"This is line D\n",
"This is line E\n",
"This is line E\n",
"\n",
"Location after read: 70\n"
]
}
],
"source": [
"with open('Example2.txt', 'a+') as testwritefile:\n",
" print(\"Initial Location: {}\".format(testwritefile.tell()))\n",
" \n",
" data = testwritefile.read()\n",
" if (not data): #empty strings return false in python\n",
" print('Read nothing') \n",
" else: \n",
" print(testwritefile.read())\n",
" \n",
" testwritefile.seek(0,0) # move 0 bytes from beginning.\n",
" \n",
" print(\"\\nNew Location : {}\".format(testwritefile.tell()))\n",
" data = testwritefile.read()\n",
" if (not data): \n",
" print('Read nothing') \n",
" else: \n",
" print(data)\n",
" \n",
" print(\"Location after read: {}\".format(testwritefile.tell()) )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, a note on the difference between **w+** and **r+**. Both of these modes allow access to read and write methods, however, opening a file in **w+** overwrites it and deletes all pre-existing data. <br>\n",
"To work with a file on existing data, use **r+** and **a+**. While using **r+**, it can be useful to add a <code>.truncate()</code> method at the end of your data. This will reduce the file to your data and delete everything that follows. <br>\n",
"In the following code block, Run the code as it is first and then run it with the <code>.truncate()</code>.\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Line 1\n",
"Line 2\n",
"Line 3\n",
"finished\n",
"is line D\n",
"This is line E\n",
"This is line E\n",
"\n"
]
}
],
"source": [
"with open('Example2.txt', 'r+') as testwritefile:\n",
" data = testwritefile.readlines()\n",
" testwritefile.seek(0,0) #write at beginning of file\n",
" \n",
" testwritefile.write(\"Line 1\" + \"\\n\")\n",
" testwritefile.write(\"Line 2\" + \"\\n\")\n",
" testwritefile.write(\"Line 3\" + \"\\n\")\n",
" testwritefile.write(\"finished\\n\")\n",
" #Uncomment the line below\n",
" #testwritefile.truncate()\n",
" testwritefile.seek(0,0)\n",
" print(testwritefile.read())\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<hr>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 id=\"copy\">Copy a File</h2> \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's copy the file **Example2.txt** to the file **Example3.txt**:\n"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"# Copy file to another\n",
"\n",
"with open('Example2.txt','r') as readfile:\n",
" with open('Example3.txt','w') as writefile:\n",
" for line in readfile:\n",
" writefile.write(line)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can read the file to see if everything works:\n"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Line 1\n",
"Line 2\n",
"Line 3\n",
"finished\n",
"is line D\n",
"This is line E\n",
"This is line E\n",
"\n"
]
}
],
"source": [
"# Verify if the copy is successfully executed\n",
"\n",
"with open('Example3.txt','r') as testwritefile:\n",
" print(testwritefile.read())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"After reading files, we can also write data into files and save them in different file formats like **.txt, .csv, .xls (for excel files) etc**. You will come across these in further examples\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now go to the directory to ensure the **.txt** file exists and contains the summary data that we wrote.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<hr>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2> Exercise </h2>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Your local university's Raptors fan club maintains a register of its active members on a .txt document. Every month they update the file by removing the members who are not active. You have been tasked with automating this with your Python skills. <br>\n",
"Given the file currentMem, Remove each member with a 'no' in their Active coloumn. Keep track of each of the removed members and append them to the exMem file. Make sure the format of the original files in preserved. (*Hint: Do this by reading/writing whole lines and ensuring the header remains* ) <br>\n",
"Run the code block below prior to starting the exercise. The skeleton code has been provided for you, Edit only the cleanFiles function.\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"#Run this prior to starting the exercise\n",
"from random import randint as rnd\n",
"\n",
"memReg = 'members.txt'\n",
"exReg = 'inactive.txt'\n",
"fee =('yes','no')\n",
"\n",
"def genFiles(current,old):\n",
" with open(current,'w+') as writefile: \n",
" writefile.write('Membership No Date Joined Active \\n')\n",
" data = \"{:^13} {:<11} {:<6}\\n\"\n",
"\n",
" for rowno in range(20):\n",
" date = str(rnd(2015,2020))+ '-' + str(rnd(1,12))+'-'+str(rnd(1,25))\n",
" writefile.write(data.format(rnd(10000,99999),date,fee[rnd(0,1)]))\n",
"\n",
"\n",
" with open(old,'w+') as writefile: \n",
" writefile.write('Membership No Date Joined Active \\n')\n",
" data = \"{:^13} {:<11} {:<6}\\n\"\n",
" for rowno in range(3):\n",
" date = str(rnd(2015,2020))+ '-' + str(rnd(1,12))+'-'+str(rnd(1,25))\n",
" writefile.write(data.format(rnd(10000,99999),date,fee[1]))\n",
"\n",
"genFiles(memReg,exReg)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Start your solution below:\n"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Active Members: \n",
"\n",
"\n",
"Membership No Date Joined Active \n",
" 72339 2015-9-20 yes \n",
" 16520 2016-4-23 yes \n",
" 15114 2016-7-13 yes \n",
" 98959 2015-11-23 yes \n",
" 85863 2019-10-24 yes \n",
" 26338 2020-4-14 yes \n",
" 48733 2016-5-6 yes \n",
" 66914 2016-8-12 yes \n",
" 13455 2020-1-24 yes \n",
" 27611 2015-12-3 yes \n",
"\n",
"Inactive Members: \n",
"\n",
"\n",
"Membership No Date Joined Active \n",
" 32401 2020-5-8 no \n",
" 84377 2015-8-7 no \n",
" 77359 2017-6-15 no \n",
" 11000 2017-6-24 no \n",
" 80238 2015-12-9 no \n",
" 34300 2015-1-15 no \n",
" 37085 2016-2-9 no \n",
" 35418 2016-7-4 no \n",
" 86541 2020-4-23 no \n",
" 71254 2015-6-6 no \n",
" 37992 2020-8-12 no \n",
" 26401 2018-2-18 no \n",
" 32680 2015-8-15 no \n",
"\n"
]
}
],
"source": [
"\n",
"def cleanFiles(currentMem,exMem):\n",
" '''\n",
" currentMem: File containing list of current members\n",
" exMem: File containing list of old members\n",
" \n",
" Removes all rows from currentMem containing 'no' and appends them to exMem\n",
" '''\n",
" \n",
" # Open current members file in r+ mode.\n",
" with open(currentMem,'r+') as currentMembersFile:\n",
" \n",
" # Open ex members file in append mode, we will only add removed members.\n",
" with open(exMem,'a+') as exMembersFile:\n",
" inactive_members = []\n",
" \n",
" # Get the data\n",
" currentMembersFile.seek(0)\n",
" current_members = currentMembersFile.readlines()\n",
" \n",
" # Remove header\n",
" header = current_members[0]\n",
" current_members.pop(0)\n",
" \n",
" # Get inactive current members list.\n",
" for member in current_members:\n",
" if 'no' in member:\n",
" inactive_members.append(member)\n",
" \n",
" # inactive = [member for member in current_members if ('no' in member)]\n",
" \n",
" #go to the beginning of the write file\n",
" currentMembersFile.seek(0) \n",
" currentMembersFile.write(header)\n",
" \n",
" for member in current_members:\n",
" if (member in inactive_members):\n",
" exMembersFile.write(member)\n",
" else:\n",
" currentMembersFile.write(member)\n",
" \n",
" currentMembersFile.truncate()\n",
"\n",
"\n",
"# Code to help you see the files\n",
"# Leave as is\n",
"memReg = 'members.txt'\n",
"exReg = 'inactive.txt'\n",
"cleanFiles(memReg,exReg)\n",
"\n",
"\n",
"headers = \"Membership No Date Joined Active \\n\"\n",
"with open(memReg,'r') as readFile:\n",
" print(\"Active Members: \\n\\n\")\n",
" print(readFile.read())\n",
" \n",
"with open(exReg,'r') as readFile:\n",
" print(\"Inactive Members: \\n\\n\")\n",
" print(readFile.read())\n",
" \n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Run the following to verify your code:\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test Passed\n"
]
}
],
"source": [
"def testMsg(passed):\n",
" if passed:\n",
" return 'Test Passed'\n",
" else :\n",
" return 'Test Failed'\n",
"\n",
"testWrite = \"testWrite.txt\"\n",
"testAppend = \"testAppend.txt\" \n",
"passed = True\n",
"\n",
"genFiles(testWrite,testAppend)\n",
"\n",
"with open(testWrite,'r') as file:\n",
" ogWrite = file.readlines()\n",
"\n",
"with open(testAppend,'r') as file:\n",
" ogAppend = file.readlines()\n",
"\n",
"try:\n",
" cleanFiles(testWrite,testAppend)\n",
"except:\n",
" print('Error')\n",
"\n",
"with open(testWrite,'r') as file:\n",
" clWrite = file.readlines()\n",
"\n",
"with open(testAppend,'r') as file:\n",
" clAppend = file.readlines()\n",
" \n",
"# checking if total no of rows is same, including headers\n",
"\n",
"if (len(ogWrite) + len(ogAppend) != len(clWrite) + len(clAppend)):\n",
" print(\"The number of rows do not add up. Make sure your final files have the same header and format.\")\n",
" passed = False\n",
" \n",
"for line in clWrite:\n",
" if 'no' in line:\n",
" passed = False\n",
" print(\"Inactive members in file\")\n",
" break\n",
" else:\n",
" if line not in ogWrite:\n",
" print(\"Data in file does not match original file\")\n",
" passed = False\n",
"print (\"{}\".format(testMsg(passed)))\n",
" \n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<details><summary>Click here for the solution</summary>\n",
"\n",
"```python\n",
"def cleanFiles(currentMem,exMem):\n",
" with open(currentMem,'r+') as writeFile: \n",
" with open(exMem,'a+') as appendFile:\n",
" #get the data\n",
" writeFile.seek(0)\n",
" members = writeFile.readlines()\n",
" #remove header\n",
" header = members[0]\n",
" members.pop(0)\n",
" \n",
" inactive = [member for member in members if ('no' in member)]\n",
" '''\n",
" The above is the same as \n",
"\n",
" for member in members:\n",
" if 'no' in member:\n",
" inactive.append(member)\n",
" '''\n",
" #go to the beginning of the write file\n",
" writeFile.seek(0) \n",
" writeFile.write(header)\n",
" for member in members:\n",
" if (member in inactive):\n",
" appendFile.write(member)\n",
" else:\n",
" writeFile.write(member) \n",
" writeFile.truncate()\n",
" \n",
"memReg = 'members.txt'\n",
"exReg = 'inactive.txt'\n",
"cleanFiles(memReg,exReg)\n",
"\n",
"# code to help you see the files\n",
"\n",
"headers = \"Membership No Date Joined Active \\n\"\n",
"\n",
"with open(memReg,'r') as readFile:\n",
" print(\"Active Members: \\n\\n\")\n",
" print(readFile.read())\n",
" \n",
"with open(exReg,'r') as readFile:\n",
" print(\"Inactive Members: \\n\\n\")\n",
" print(readFile.read())\n",
" \n",
"```\n",
"\n",
"</details>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<hr>\n",
"<h2>The last exercise!</h2>\n",
"<p>Congratulations, you have completed your first lesson and hands-on lab in Python. \n",
"<hr>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Author\n",
"\n",
"<a href=\"https://www.linkedin.com/in/joseph-s-50398b136/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\" target=\"_blank\">Joseph Santarcangelo</a>\n",
"\n",
"### Other Contributors\n",
"\n",
"<a href=\"https://www.linkedin.com/in/jiahui-mavis-zhou-a4537814a?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">Mavis Zhou</a>\n",
"\n",
"## Change Log\n",
"\n",
"| Date (YYYY-MM-DD) | Version | Changed By | Change Description |\n",
"| ----------------- | ------- | ----------- | ----------------------------------- |\n",
"| 2022-01-10 | 2.1 | Malika | Removed the readme for GitShare |\n",
"| 2020-10-16 | 1.3 | Arjun Swani | Added exercise |\n",
"| 2020-10-16 | 1.2 | Arjun Swani | Added section additional file modes |\n",
"| 2020-10-16 | 1.1 | Arjun Swani | Made append a different section |\n",
"| 2020-08-28 | 0.2 | Lavanya | Moved lab to course repo in GitLab |\n",
"\n",
"<hr>\n",
"\n",
"## <h3 align=\"center\"> © IBM Corporation 2020. All rights reserved. <h3/>\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python",
"language": "python",
"name": "conda-env-python-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment