Monday, April 8, 2024

 

2D Dictionaries


Remember that dictionaries are very similar to lists, except that they store data as key:value pairs. The value is what it's worth and the key is what it is called. The key is used to access the value, and keys are more meaningful than index numbers.



Dynamically Adding To A 2D Dictionary

This code dynamically adds to a 2D dictionary by starting with an empty dictionary and using an infinite loop to add user input.

clue = {}

while True:
  name = input("Name: ")
  location = input("Location: ")
  weapon = input("Weapon: ")

  clue[name] = {"location": location, "weapon":weapon} #line 7

  print(clue)

output 
Name: angshu
Location: burdwan
Weapon: hammer
{'angshu': {'location': 'burdwan', 'weapon': 'hammer'}}


The real magic happens on the 7th line of code. Instead of using .append() like we would with a list, we create a new dictionary entry.

The key is the name of the beast, but the value is a whole new dictionary that contains the details of the beast.

Each key:value pair in the dictionary is now a key that accesses a related dictionary

Pretty Printing
This example shows you how to add a prettyPrint() subroutine that works with a 2D dictionary.

clue = {}
def prettyPrint():
  print()
  
  for key, value in clue.items(): #This iterates over each key-value pair in the clue dictionary. Inside the loop
    # moves along every 'key:subDictionary' pair and outputs the key (the name of the character).
    print(key, end=": ")
    for subKey, subValue in value.items(): #This nested loop iterates over each key-value pair in the nested dictionary associated with the current key
      # (nested) `for` loop moves along every subkey and subvalue in each subDictionary.
      print(subKey, subValue, end=" | ")
    print()
    
while True:
  name = input("Name: ")
  location = input("Location: ")
  weapon = input("Weapon: ")

  clue[name] = {"location": location, "weapon":weapon} 

  prettyPrint()


Accessing a Single Item

To access a single item in a 2D dictionary, we use two square brackets just like with a 2D list.

john = {"daysCompleted": 46, "streak": 22}
janet = {"daysCompleted": 21, "streak": 21}
erica = {"daysCompleted": 75, "streak": 6}

courseProgress = {"John":john, "Janet":janet, "Erica":erica}

print(courseProgress)

print(courseProgress["Erica"])
# The bracket contains the key that references the sub dictionary.To access one item, I use two square brackets []. So to see only Erica's results, I would add this
print(courseProgress["Erica"]["daysCompleted"]): #if we only want to see how many days Erica has completed

Wednesday, April 3, 2024

2D Dynamic Lists

 

2D Dynamic Lists
Dynamic lists are lists that we populate as we go, getting user input and adding it to the list as we go.
We're combining several techniques here. I've left detailed code comments to help. Remember, comments can be found with # comment in green inside the code.

Loops, append() and break

Here's an example to get some simple user details(name, age, computer preference) and add it to a list as a full row. This list will keep taking input until the user answers 'y' to the 'exit?' question.

Once we collect the user's input in a row, we will append the entire row to the list. The columns are maintained, and we are keeping the structure of 2D lists.


Lets try this coding :

listOfShame = [] 
# Creates an empty list.

while True: 
  # Starts a never ending loop (until we end it)
  name = input("What is your name? ")
  age = input("What is your age? ")
  pref = input("What is your computer platform? ")
  # Get the user input.

  row = [name, age, pref] 
  # Assigns the 3 variables into a single row.

  listOfShame.append(row) 
  # Adds the contents of the row variable at the end of the list

  exit = input("Exit? y/n") 
  # Get user choice to quit, yes or no?

  if (exit.strip().lower()[0] == "y"): 
    # strip removes unwanted spaces from the input. lower()[0] makes sure the first character of the input is lower case so it can be compared to 'y'
    break # break ends a loop and jumps to the next line of code that is not part of the loop.
    
print(listOfShame) # Outputs the list. Note this is NOT part of the loop (not indented), it only runs once the loop ends.



Pretty Printing



Man, that print(listOfShame) output sure is ug-leeee.
In the code below, I've added a prettyPrint subroutine to beautify the output. 

def prettyPrint():
  print() 
  # Puts a blank row at the top
  for row in listOfShame: 
    #loops to the next row when the end of the current one is reached
     print(row) 
    # prints the new row
  print() 
  # prints a blank line between rows
    

listOfShame = [] 

while True: 
  name = input("What is your name? ")
  age = input("What is your age? ")
  pref = input("What is your computer platform? ")
  
  row = [name, age, pref] 

  listOfShame.append(row) 

  exit = input("Exit? y/n") 

  if (exit.strip().lower()[0] == "y"):
    break 

prettyPrint() 
# Call the prettyPrint subroutine instead of printing the list directly.


There is a bit of weirdness. The rows are printing out, but they just look like a list with all those symbols. We need one loop to extract each row and one loop to extract each item from the columns.


Prettier Printing?

This version of prettyPrint() uses fStrings to further line up the tabs.
Note: this only shows the updated subroutine.

def prettyPrint():
  print() 
  for row in listOfShame: 
    for item in row: 
      # item refers to each item in the column for that row
     print(f"{item:^10}", end=" | ") 
    

listOfShame = [] 

while True: 
  name = input("What is your name? ")
  age = input("What is your age? ")
  pref = input("What is your computer platform? ")
  
  row = [name, age, pref] 

  listOfShame.append(row) 

  exit = input("Exit? y/n") 

  if (exit.strip().lower()[0] == "y"):
    break 

prettyPrint() 
# Call the prettyPrint subroutine instead of printing the list directly.


Add or Remove?

We can add records, but let's expand to give the user the choice of whether to add or remove. Do we want to remove the entire row or just one item?

We ask the user to choose between adding and removing. If they choose remove, we 
-ask for a name on the list (make sure it is spelled correctly)
-extract each row, one at a time, from the list
-check the row to see if it contains the name
-if the name is in the row, use the .remove() method to remove the whole row, not just the name.

def prettyPrint():
  print() 
  for row in listOfShame: 
    for item in row: 
      # item refers to each item in the column for that row
     print(f"{item:^10}", end=" | ") 
listOfShame = [] 

while True: 
  menu = input("Add or Remove?") # Gives the user a choice prompt and stores their input.

  if(menu.strip().lower()[0]=="a"): # Uses selection to run the 'add' code if user inputs 'a'. I've "sanitized" the input here too.[0]: This indexing operation accesses the first character of the modified string obtained after stripping whitespace and converting to lowercase. Indexing in Python starts from 0, so [0] accesses the first character of the string.
    
    name = input("What is your name? ")
    age = input("What is your age? ")
    pref = input("What is your computer platform? ")
    
    row = [name, age, pref] 
  
    listOfShame.append(row) 
    # All the 'add' code is now indented, so it's part of the 'add' branch and will only run if the user enters 'a'.

  else: # If the user doesn't choose 'a', run this new remove code instead.
    name = input("What is the name of the record to delete?") # Get the input of a name
    for row in listOfShame: # Use a loop to extract one row at a time
      
      if name in row: # Check if the name is in the extracted row.
        listOfShame.remove(row) # remove the whole row if name is in it

  prettyPrint()



Coding Challenge

1. Have a menu that asks if you want to add, view, move or edit a 'to do'.


2.If you choose 'add' then the system should:Prompt you to input what the to do is, when it is due by and the priority (high, medium or low).
Add the 'to do' to the list.


3. 'View' should give two options:View all - shows all 'to dos' with a pretty print.
View priority - allows you to search for high, medium or low priority and only see matching tasks.


4.'Edit' allows you to change any of the information within one of the 'to dos'.

5. 'Remove' lets you completely remove a 'to do' when it is 'to done'.

STEP-1

# Function to add a to do
def add_todo():
task = input("Enter the task: ")
due_date = input("Enter the due date: ")
priority = input("Enter the priority (high, medium, low): ")
todo_list.append({'Task': task, 'Due Date': due_date, 'Priority': priority})
print("Task added successfully.")


# Function to view all todos
def view_all():
print("All To Dos:")

print(f"{index}. Task: {todo['Task']}, Due Date: {todo['Due Date']}, Priority: {todo['Priority']}")


# Function to view todos by priority
def view_priority(priority):
print(f"To Dos with priority {priority}:")
for index, todo in enumerate(todo_list, start=1):
if todo['Priority'].lower() == priority.lower():
print(f"{index}. Task: {todo['Task']}, Due Date: {todo['Due Date']}, Priority: {todo['Priority']}")


# Function to edit a todo
def edit_todo():
view_all()
index = int(input("Enter the index of the task you want to edit: ")) - 1
if 0 <= index < len(todo_list):
task = input("Enter the new task: ")
due_date = input("Enter the new due date: ")
priority = input("Enter the new priority (high, medium, low): ")
todo_list[index] = {'Task': task, 'Due Date': due_date, 'Priority': priority}
print("Task edited successfully.")
else:
print("Invalid index.")


# Function to remove a todo
def remove_todo():
view_all()
index = int(input("Enter the index of the task you want to remove: ")) - 1
if 0 <= index < len(todo_list):
del todo_list[index]
print("Task removed successfully.")
else:
print("Invalid index.")


# Main program
todo_list = []


while True:
print("\nMenu:")
print("1. Add a To Do")
print("2. View To Dos")
print("3. Edit a To Do")
print("4. Remove a To Do")
print("5. Exit")


choice = input("Enter your choice: ")


if choice == '1':
add_todo()
elif choice == '2':
print("\nView Options:")
print("1. View All")
print("2. View by Priority")
view_choice = input("Enter your choice: ")
if view_choice == '1':
view_all()
elif view_choice == '2':
priority = input("Enter the priority (high, medium, low): ")
view_priority(priority)
else:
print("Invalid choice.")
elif choice == '3':
edit_todo()
elif choice == '4':
remove_todo()
elif choice == '5':
print("Exiting program.")
break
else:
print("Invalid choice. Please enter a number from 1 to 5.")

STEP-2

# | Name | Date | Priority
import os, time
todo = []

def add():
  time.sleep(1)
  os.system("clear")
  name = input("Name > ")
  date = input("Due Date > ")
  priority = input("Priority > ").capitalize()
  row = [name, date, priority]
  todo.append(row)
  print("Added")

def view():
  time.sleep(1)
  os.system("clear")
  options = input("1: All\n2: By Priority\n> ")
  if options=="1":
    for row in todo:
      for item in row:
        print(item, end=" | ")
      print()
    print()
  else:
    priority = input("What priority? > ").capitalize()
    for row in todo:
      if priority in row:
        for item in row:
          print(item, end=" | ")
        print()
    print()
  time.sleep(1)

def edit():
  time.sleep(1)
  os.system("clear")
  find = input("Name of todo to edit > ")
  found = False
  for row in todo:
    if find in row:
      found = True
  if not found:
    print("Couldn't find that")
    return
  for row in todo:
    if find in row:
      todo.remove(row)
  name = input("Name > ")
  date = input("Due Date > ")
  priority = input("Priority > ").capitalize()
  row = [name, date, priority]
  todo.append(row)
  print("Added")

def remove():
  time.sleep(1)
  os.system("clear")
  find = input("Name of todo to remove > ")
  for row in todo:
    if find in row:
      todo.remove(row)

while True:
  menu = input("1: Add\n2: View\n3: Edit\n4: Remove\n> ")
  if menu == "1":
    add()
  elif menu == "2":
    view()
  elif menu == "3":
    edit()
  else:
    remove()

  time.sleep(1)
  os.system("clear")

Tuesday, April 2, 2024

Two-Dimensional List

 Two-Dimensional List

Pay close attention, folks, because 2D lists are basically tables.
Tables are two-dimensional data structures where we can store data both vertically and horizontally.
Usually this means that vertical data is used for fields (one category - name, ID, favorite biscuit, etc.) and horizontal data is used for records (all the data for each category).
Behind the scenes, we see a list inside a list. Forget what you know about reading a table with math or geography: 'across the corridor (x-axis) first and then down the stairs (y-axis)'.

Here, we will do row index first and then the column index.

Remember...
Here's a 1D list. We have the list name as a variable, single equals to set the value, and sqaure brackets to show this is a list. 2D lists are very similar.

my1DList = ["Johnny", 21, "Mac"]

Adding The Second Dimension

To add the second dimension, we put lists inside the first list.

Each new list has its own set of square brackets and is separated by a comma. This layout of code is nice to help us visualise the 2D list as a table, but...

my2DList = [ ["Johnny", 21, "Mac"],
                       ["Sian", 19, "PC"],
                       ["Gethin", 17, "PC"] ]

...you can also lay it out like this below:

my2DList = [ ["Johnny", 21, "Mac"], ["Sian", 19, "PC"], ["Gethin", 17, "PC"] ]

Now, let's print this list.

Printing From a 2D List

Remember, any comments about the code are written in green like this:

the entire list

We can print an entire 2D list just like we do with a 1D list. However, this will output (print) all of the square brackets, commas, etc.

print(my2DList)

a single row
To print a single row, use a single square bracket [] in the print command. However, you will still get all of those square brackets and commas.

In this example, I'm outputting the first row (index 0) - all of the data about Johnny.

print(my2DList[0])

a single piece of data
The first square bracket references the list, while the second references the item inside that list.
Here are a couple of examples:

my2DList = [ ["Johnny", 21, "Mac"],
             ["Sian", 19, "PC"],
             ["Gethin", 17, "PC"] ]

print(my2DList[0][0])
# This code outputs 'Johnny'. It's Johnny's name from list 0 (first square bracket), item 0 (second square bracket)

print(my2DList[1][2])
# This code outputs 'PC'. It's Sian's computing preferene from list 1 (first square bracket), item 2 (second square bracket)

Editing a 2D List
We can edit values in a 2D list in the same way as variables and 1D lists. You just need to change the value to the new row and column index numbers.
In this example, Sian has joined the dark side, so we're updating her computing preference to Linux.

my2DList = [ ["Johnny", 21, "Mac"],
             ["Sian", 19, "PC"],
             ["Gethin", 17, "PC"] ]

my2DList[1][2] = "Linux"
# The line above changes list 1, item 2 from PC to Linux

print(my2DList[1])
# I'm using this line to output list 1 to check that the change has happened correctly.

Coding Challenge


Randomly generate a series of number between 0 and 90.
Allocate each number to a place in a 2D list.
The numbers should be in numerical order, left to right.
Numbers should not be repeated.
The center square should not contain a number. It should contain the word 'BINGO!'.


import random

bingo = []

def ran():
  number = random.randint(1,90)
  return number

def prettyPrint():
  for row in bingo:
    print(row)

numbers = []
for i in range(8):
  numbers.append(ran())

numbers.sort()

bingo = [ [ numbers[0], numbers[1], numbers[2]],
          [ numbers[3], "BINGO", numbers[4] ],
          [ numbers [5], numbers[6], numbers[7]]
        ]

prettyPrint()

Wednesday, March 27, 2024

Dictionaries With Loops

 

Dictionaries With Loops
Loops and lists are a perfect pair. Dictionaries and loops are a bit trickier. This is because each dictionary item is made up of two parts - the name of the key and the actual value of that key.

I've Lost My Keys!
Let's set up a looped dictionary.
Using a for loop, like we would with a list, will output the values, but not the keys. Not ideal.

myDictionary = {"name" : "Ian", "health": 219, "strength": 199, "equipped": "Axe"}

for i in myDictionary:
  print(myDictionary[i])

This loop uses the values() method, which can be run on a data type. We still only get the value, and not the key.

myDictionary = {"name" : "Ian", "health": 219, "strength": 199, "equipped": "Axe"}

for value in myDictionary.values():
  print(value)

I've Got The Key...I've Got The Secret

There is a better way!
Here's a loop that will output both key and value.
The .items() function returns the key name and value. Note that I've supplied the loop with two arguments: 'name' and 'value').
This example will just output the names and values using an fString.

myDictionary = {"name" : "Ian", "health": 219, "strength": 199, "equipped": "Axe"}

for name,value in myDictionary.items():
  print(f"{name}:{value}")

A Bit Iffy
Let's go one step further and use some if statements inside the loop.
This example makes a comment about the strength key.

myDictionary = {"name" : "Ian", "health": 219, "strength": 199, "equipped": "Axe"}

for name,value in myDictionary.items():
  print(f"{name}:{value}")

  if (name == "strength"):
    print("Whoa, SO STRONG!")

This example uses nested if statements to react to the key name and the value stored within it.

myDictionary = {"name" : "David the Mildy Terrifying", "health": 186, "strength": 4, "equipped":"l33t haxx0r p0werz"}

for name, value in myDictionary.items():
print(f"{name}: {value}")

if (name == "strength"): 
if value > 100: # This nested if wasn't indented properly
  print("Whoa, SO STRONG")
else:
  print("Looks like you skipped leg day, arm day, chest day and, well, gym day entirely bro!")


Coding Challenge

Create a dictionary that stores the following information about a website: name, URL, description and a star rating (out of 5).
Use a loop to output the names of the keys, ask the user to type in the details and store the input in the dictionary.
Finally, output the whole dictionary (keys and values).

website = {"name": None, "url": None, "desc": None, "rating": None}

for name in website.keys():
  website[name] = input(f"{name}: ")

print()
for name, value in website.items():
  print(f"{name}: {value}")


Coding Challenge

Create a dictionary to store the details of your, ahem, MokéBeast.
Ask the user to input the following details: name, type (earth, fire, air, water or spirit), special move, starting HP and starting MP. For now we're just taking in one set of values for one beast.
Output the beast's details.
Check the beast's type and change the color of the text accordingly. Fire is red, water is blue, air is white. You decide on the others.

mokedex = {"Beast Name": None, "Type": None, "Special Move": None, "HP": None, "MP": None}

print("MokéBeast")
print()

for name, value in mokedex.items():
  mokedex[name] = input(f"{name}:\t").strip().title()

if mokedex["Type"]=="Earth":
  print("\033[32m", end="")
elif mokedex["Type"]=="Air":
  print("\033[37m", end="")
elif mokedex["Type"]=="Fire":
  print("\033[31m", end="")
elif mokedex["Type"]=="Water":
  print("\033[34m", end="")
else:
  print("\033[33m", end="")

for name, value in mokedex.items():
  print(f"{name:<15}: {value}")

Tuesday, March 26, 2024

Dictionaries

 

Dictionaries
As you might have guessed, we love lists. However, list items are accessed in order by index number. This isn't always the way we want it to work.

Dictionaries are a slightly different type of list that access data by giving each item a key. This creates what we call key:value pairs.

Now we can access each item through its key, instead of having to remember what index it is at in the list.

Creating a dictionary - brace!
Curly, curly braces...
To create a dictionary we start just like a list, except with curly braces {}. This dictionary will store data about a user.
The data is inserted in key value pairs like this. Each pair is separated by a comma:


The first key:value pair below has "name" as the key and "David" as the value. Try it out:

myUser = {"name": "David", "age": 128}

Printing the keys
To output (print) from a dictionary, we can use the key instead of the index. Note that we still use square brackets for accessing items (ex: ["name"]).

Let's print "name".

myUser = {"name": "David", "age": 128}
print(myUser["name"])

# This code outputs 'David'.

Changing an item
You can use the = syntax to change key values.

myUser = {"name": "David", "age": 128}

myUser["name"] = "The legendary David"
print(myUser)

# This code outputs 'name:'the legendary David', 'age':'128.

Note that we have to put the keys in single quotation marks '' inside the fString when using this technique.
This is because we've already used double quotes to start and end the fString. So, using "" for the dictionary value would get Python all confuzzled.


myUser = {"name": "David", "age": 128}

print(f"Your name is {myUser['name']} and your age is {myUser['age']}")

# This code outputs 'Your name is David and your age is 128'.

Syntax error?

Why are you getting a syntax error on the print statement line?
The print statement uses square brackets. Curly braces {} are only used to call the value.

Wrong 
myUser = {"name": "David", "age": 128}

print(myUser{"name"})

Correct 
myUser = {"name": "David", "age": 128}

print(myUser["name"])

Undefined?

The key, name, in the dictionary should be inside quotes.

Wrong
myUser = {name: "David", "age": 128}

print(myUser["name"])


Correct 
myUser = {"name": "David", "age": 128}

print(myUser["name"])

Spare Key?
A dictionary can't have two keys with the same name. It always overrides the previous one. Therefore, the 129 overrides the age, 128.

Wrong
myUser = {name:"David", "age": 128, "age" = 129}

print(myUser)

Correct 
myUser = {"name":"David", "age": 128}

myUser["age"] = 129

print(myUser)


Coding Challenge 
Ask the user to input their name, date of birth, telephone number, email and physical address.
Store it all in a dictionary.
Print it out in a nice way once its stored.

x = input("Input your name >")
y = input("Input your date of birth >")
z = input("Input your telephone number >")
a = input("Input your email >")
b = input("Input your address >")


myUser = {"name":x, "DOB": y , "phone": z, "email": a, "address": b}

print(f"Hi {myUser['name']}. Our dictionary says that you were born on {myUser['DOB']}, we can call you on {myUser['phone']}, email {myUser['email']}, or write to {myUser['address']}.")

print(myUser)

Thursday, March 21, 2024

Strings and Loops

 

Strings and Loops
Now that we know that strings are basically lists in disguise, we can start to harness the power of loops with them.

Let's look a bit further into string slicing.

Using a for loop
This for loop creates a variable called letter. It is used to store each character in the string as the loop goes through it, starting at the first character.

The print statement uses the letter variable and will output the string one character at a time (like a list).

myString = "Day 21"
for letter in myString:
print(letter)

output 
D
a
y
 
2
1

This means that we can do certain things to certain characters inside the loop.

if statement inside the loop

This code will examine the lower-case version of each character. If it's an 'a', the computer will change the font colour to yellow before printing.

Outside of the loop, the last line sets the font colour back to default for the next character in the loop.

myString = "Day 38"
for letter in myString:
if letter.lower() == "a":
print('\033[33m', end='') #yellow
print(letter)
print('\033[0m', end='')

Using a list to specify search items:-
If the letters are in my list called vowels, they will print out in yellow.
I changed the print statement on the last line back to the default color with the ending system.

vowels = ["a","e","i","o","u"]
myString = "Will my vowels now be yellow?"
for letter in myString:  
  if letter.lower() in vowels:
    print('\033[33m', end='') #yellow    
  print(letter, end="")
  print('\033[0m', end='') #back to default

Coding challenge :
Ask the user to input any sentence (string).
Now we'll rainbow-ize (nope, me neither) it.
As soon as the string contains an 'r', every letter from that point on should be red.
When the computer encounters a 'b', 'g', 'p' or 'y', from there the output should be blue for 'b', green for 'g'...you get the idea.
Loop through the string and output it (so the color continues through the loop).
The output should change color every time it encounters a new r,g,b,p or y.

Extra points for resetting the output color back to default every time there's a space.

It would be like this........

#import os, time
def colorChange(color):
  if color=="r":
    return ("\033[31m")
  elif color=="w":
    return ("\033[0m")
  elif color=="b":
    return ("\033[34m")
  elif color=="":
    return ("\033[33m")
  elif color == "g":
    return ("\033[32m")
  elif color == "p":
    return ("\033[35m")

while True:
  #os.system("clear")
  listofWords= input("Tell me what do want: ").split()
  print(listofWords)
  i=0
  for i in listofWords:
    if i[0]=="r":
      print(colorChange('r'),i,end="" )
    elif i[0] == "w":
      print(colorChange('w'),i,end="")
    elif i[0] == "b":
      print(colorChange('b'),i,end="")
    elif i[0] == "g":
      print(colorChange('g'),i,end="")
  print()
  print(colorChange('w'))


More better way :- 

import os

def colorChange(color):
    colors = {
        'r': '\033[91m',  # Red
        'w': '\033[0m',   # White (reset)
        'b': '\033[94m',  # Blue
        'g': '\033[92m'   # Green
    }
    return colors.get(color, '\033[0m')  # Default to white if color not found

while True:
    os.system("clear")  # Clear the console (uncomment this line if you want to clear the console before each input)
    listofWords = input("Tell me what you want: ").split()
    print(listofWords)
    
    for word in listofWords:
        if word[0] == "r":
            print(colorChange('r') + word, end=" ")
        elif word[0] == "w":
            print(colorChange('w') + word, end=" ")
        elif word[0] == "b":
            print(colorChange('b') + word, end=" ")
        elif word[0] == "g":
            print(colorChange('g') + word, end=" ")
        else:
            print(word, end=" ")  # Print the word without color change if it doesn't start with a recognized letter

    print()
    print(colorChange('w'))  # Reset color to white after printing the words

Picking from a list randomly

Random.choice() picks a random item from a list.

listOfWords = ["british", "suave", "integrity", "accent", "evil", "genius", "Downton"]
wordChosen = random.choice(listOfWords)

Coding Challenges
Prompt the user to type in a letter.
Check if the letter is in the word.
If it does, output the word with all blanks apart from the letter(s) they've already guessed.
Keep a running list of the letters they've used.
Count how many times they've picked a letter that isn't in the word - more than 6 and they lose.
Output a 'win' message if they reveal all the letters.



import random, os, time
listOfWords = ["apple", "orange", "grapes", "pear"]
letterPicked = []
lives = 6
word = random.choice(listOfWords)
while True:
time.sleep(5)
os.system("clear")
letter = input("Choose a letter: ").lower()
if letter in letterPicked:
print("You've tried that before")
continue
letterPicked.append(letter)
if letter in word:
print("You found a letter")
else:
print("Nope, not in there")
lives -= 1
allLetters = True
print()
for i in word:
if i in letterPicked:
print(i, end="")
else:
print("_", end="")
allLetters = False
print()
if allLetters:
print(f"You won with {lives} left!")
break


if lives<=0:
print(f"You ran out of lives! The answer was {word}")
break
else:
print(f"Only {lives} left")

String Manipulation

 

String Manipulation
Let's do some string manipulation to make if statements even easier.

name = input("What's your name? ")
if name == "David" or name == "david":
  print("Hello Baldy!")
else: 
  print("What a beautiful head of hair!")

Right now, if the user writes "DAVID" or "david", the if statement works correctly. However, "DaVID" does not give the correct output.
To the computer, " david", "dAviD", and "david" are completely different.
To simplify what the user typed in, we can add these functions to the end of the name of the variable:


  • .lower = all letters are lower case
    .upper = all letters are upper case
    .title = capital letter for the first letter of every word
    .capitalize = capital letter for the first letter of only the first word

lower

The computer is converting everything to lowercase before it compares my if statements.
You need to type your if statement in lower case when you use .lower. The if statement needs to be written in upper case when you use .upper, etc.

name = input("What's your name? ")
if name.lower() == "david": 
  print("Hello Baldy!")
else: 
  print("What a beautiful head of hair!")

What if we put a space first?
Adding .strip() removes any spaces on either side of the word.

name = input("What's your name? ")
if name.lower().strip() == "david": 
  print("Hello Baldy!")
else: 
  print("What a beautiful head of hair!")

No Duplicates
This is a simple program that creates a list with a simple subroutine. In the while True loop, the user is adding something to the list. (This is nowhere near as complicated as what you have done).

myList = []

def printList():
  print()
  for i in myList:
    print(i)
  print()

while True:
  addItem = input("Item > ").strip().capitalize()
  if addItem not in myList:
    myList.append(addItem)
  printList()

Note: Whatever you do after the . will happen to the string. If you use .lower, then the string will print in lower case.

Coding Challenge :- 
Create a list of people's names. Ask for first and last name (surname) separately.
Strip any extra spaces.
Store names in a capitalized version.
Create a new string using an fString that combines the tidied up version of the first name and tidied up version of the last name.
Add those new versions to a list.
Do not allow duplicates.
Each time you add a new name, you should print out the full list.

import os,time
yourName=[]

def prettyPrint():
  os.system('clear')
  print("Chart of All People")
  print()
  for i in yourName:
    print(i)
    time.sleep(1)

while True:
  os.system('clear')
  firstName=input("First Name please:").strip().capitalize()
  lastName=input("Last Name please:").strip().capitalize()
  name =f"{firstName} {lastName}"
  if name in yourName:
    print("already in the list")
  elif name not in yourName:
    yourName.append(name)
  prettyPrint()

String Slicing

However, sometimes we might want to take part of a string to use it somewhere else. Sometimes, we might want to look at just the first letter of a string or chop it into chunks.

To do this, we use string slicing.

A string isn't just one big lump of text. In fact it's a list of individual characters. 

By giving our program an index, we can specify which part of the string to chop out. 

Slicing

To slice a single character from a string, you use the index of that character in square brackets [] just like you'd use with a list!

myString = "Hello there my friend."
print(myString[0])

# This code outputs the 'H' from 'Hello'


To slice more than one character, you use two indices (yes that is the plural form of 'index'): the start character and one after your desired end character.

myString = "Hello there my friend."
print(myString[6:11])
# This code outputs 'there'.

Leaving the first index blank defaults to 'start from index 0'.
myString = "Hello there my friend."
print(myString[:11])
# This code outputs 'Hello there'.

Leaving the last index blank defaults to 'go to the end'.
myString = "Hello there my friend."
print(myString[12:])
# This code outputs 'my friend.'.

The Secret Third Argument

Adding a third argument to the square brackets [] specifies the gap left between characters.



Try to print every other character in the word 'hello':
myString = "Hello there my friend."
print(myString[0:6:2])

# This code outputs 'Hlo' (every second character from 'Hello').

Can you print every third character in the whole string?

myString = "Hello there my friend."
print(myString[::3])

# This code outputs 'Hltrmfe!' (every third character from the whole string).

Using a negative number in the third argument can be super useful. It starts the slice from the end of the string instead of the beginning.

myString = "Hello there my friend."
print(myString[::-1])

#This code reverses the string, outputting '.dneirf ym ereht olleH'

Split

split lets us split a string into a list of individual words by separating it at the space characters.

myString = "Hello there my friend."
print(myString.split())

#This code outputs ['Hello', 'there', 'my', 'friend.']

It stops printing too early

Why is it printing 'Hell' instead of 'Hello'?

myString = "Hello there my friend."
print(myString[0:4])

The second argument should always be one more than the index of the final character.

myString = "Hello there my friend."
print(myString[0:5])

It won't stop printing the same character

myString = "Hello there my friend."
print(myString[0:4:0])---- wrong code

The 0 in the third argument means 'move on 0 characters in the string each time'. You've told it to print the same character again and again and again....

The third argument should be at least 1.

CODING CHALLENGE
Ask the user to input their first & last names.
Slice the first 3 letters of the first name.
Slice the first 3 letters of the last name (surname).
Join them together. Ideally change the case so that it looks good - think fStrings or .upper()/.lower(). This is the user's Star Wars first name.
Now ask the user for their mother's maiden name and the city where they were born. (Maiden name is the last name they had before they got married. If you are not sure, make up a last name.)
Combine the first two letters of the maiden name with the last 3 letters of the city to make the user's Star Wars last name. Remember, fStrings and .upper()/.lower().
Finally, print them both as part of a sentence.

 Extra points for getting all the inputs with just one input command and the split function.

import os,time
starWars=[]


while True:
  os.system('clear')
  print("🌟Star Wars Name Generator🌟")
  print()
  print()
  input_all= input("Input your first name., Input your last name,Input your Mother's name,Input your city name with a space in each word:").slipt().upper()
  input1= input("Input your first name:").strip().upper()
  input2= input("Input your last name:").strip().upper()
  #output1= f"star wars first name is {input1[0:3]} {input2[0:3]}"   
  #print(output1)
  input3= input("Input your Mother's name:").strip().upper()
  input4= input("Input your city name:").strip().upper()
  #output2= f"star wars second name is {input3[0:2]}{input4[0:3:-1]}"
  #data = f"{input1[0:3]}{input2[0:3]}  {input3[0:2]}{input4[-3:]}"
  #print(f"{input1[0:3]}{input2[0:3]}  {input3[0:2]}{input4[-3:]}")
  
  #starWars.append(f"{input_all[0][0:3]}{input_all[1][0:3]}  {input_all[2][0:2]}{input_all[3][-3:]}")
  starWars.append(f"{input1[0:3]}{input2[0:3]}  {input3[0:2]}{input4[-3:]}")
  print(input_all)
  print(starWars)
  time.sleep(2)


More better version :-  


print("STAR WARS NAME GENERATOR")

all = input("Enter your first name, last name, Mum's maiden name and the city you were born in").split()

first = all[0].strip()
last = all[1].strip()
maiden = all[2].strip()
city = all[3].strip()

name = f"{first[:3].title()}{last[:3].lower()} {maiden[:2].title()}{city[-3:].lower()}"

print(f"Your Star Wars name is {name}")

Wednesday, March 20, 2024

Pretty print Functions

 

Pretty print Functions
Let's build a pretty print subroutine! 
When we have a list of data, being able to print out that data in pretty ways is something we need to be able to do. So "pretty printing" is actually a thing.

import os, time
listOfEmail = []

def prettyPrint():
  os.system("clear") # start by clearing the screen
  print("listofEmail") # print the title of my program
  print() # print a blank line
  for email in listOfEmail: # use for loop to access list
    print(email)
  time.sleep(1)

while True:
  print("SPAMMER Inc.")
  menu = input("1. Add email\n2: Remove email\n3. Show emails\n4. Get SPAMMING\n> ")
  if menu == "1":
    email = input("Email > ")
    listOfEmail.append(email)
  elif menu =="2":
    email = input ("Email > ")
    if email in listOfEmail:
      listOfEmail.remove(email)
    prettyPrint()  
  time.sleep(1)
  os.system("clear")

Creating a Numbered List

We can also ensure our list prints as a numbered list. Let's make this happen by making these few changes below to our subroutine. This code snippet only shows the subroutine so we can focus on the changes there:

import os, time
listOfEmail = []


def prettyPrint():
os.system("clear")
print("listofEmail")
print()
counter = 1
for email in listOfEmail:
print(f"{counter}: {email}")
counter += 1
time.sleep(1)

while True:
print("SPAMMER Inc.")
menu = input("1. Add email\n2: Remove email\n3. Show emails\n4. Get SPAMMING\n> ")
if menu == "1":
email = input("Email > ")
listOfEmail.append(email)
elif menu =="2":
email = input ("Email > ")
if email in listOfEmail:
listOfEmail.remove(email)
elif menu == "3": # we added this elif
prettyPrint() # called our subroutine here
time.sleep(1)
os.system("clear")


len counts how many items are in a list. In this case, it is starting at 0 and then keeps going until it reaches the end of our data inside our list. We can now eliminate the counter variable because we are counting with index.

We do need to access email in a different way now. We are going to use the actual list name itself and then [index] to access the index.


Coding Challenge :
 Print out the first 10 email addresses with a custom email sent to each of those people.
Print one email at a time, pause, and then clear the screen before the next email is printed.

import os, time
listOfEmail = []

def prettyPrint():
  os.system("clear")
  print("listOfEmail")
  print()
  counter = 1
  for email in listOfEmail:
    print(f"{counter}: {email}")
    counter+=1
  time.sleep(1)

def spam(max):
  for i in range(0,max):
    print(f"""Email {i+1}

Dear {listOfEmail[i]}
It has come to our attention that you're missing out on the amazing Replit 100 days of code. We insist you do it right away. If you don't we will pass on your email address to every spammer we've ever encountered and also sign you up to the My Little Pony newsletter, because that's neat. We might just do that anyway.

Love and hugs,

Ian Spammington III""")
    time.sleep(1)
    os.system("clear")
while True:
  print("SPAMMER Inc.")
  menu = input("1: Add email\n2: Remove email\n3: Show emails\n4: Get SPAMMING\n> ")
  if menu == "1":
    email = input("Email > ")
    listOfEmail.append(email)
  elif menu== "2":
    email = input("Email > ")
    if email in listOfEmail:
      listOfEmail.remove(email)
  elif menu == "3":
    prettyPrint()
  elif menu =="4":
    spam(10)
  time.sleep(1)
  os.system("clear")

Coding Challenge : 
Build a really cool to do list manager. 
We are going to upgrade the last to do list manager we created: Create a menu where the user can view, add, or remove an item.
The user should be able to edit the text of an item on the list too.
Don't allow the user to add duplicates.
Double check with the user they want to remove an item from the list before it is actually removed. (Is this the item they really want to remove?)
Give the user the option to completely erase the to do list. 

import os, time
toDoList = []

def printList():
  print()
  for items in toDoList:
    print(items)
  print()

while True:
  menu = input("ToDo List Manager\nDo you want to view, add, edit, remove or delete the todo list?\n")
  if menu=="view":
    printList()
  elif menu=="add":
    item = input("What do you want to add?\n").title()
    toDoList.append(item)
  elif menu=="remove":
    item = input("What do you want to remove?\n").title()
    check = input("Are you sure you want to remove this?\n")
    if check[0]=="y":
      if item in toDoList:
        toDoList.remove(item)
  elif menu=="edit":
    item = input("What do you want to edit?\n").title()
    new = input("What do you want to change it to?\n").title()
    for i in range(0,len(toDoList)):
      if toDoList[i]==item:
        toDoList[i]=new
  elif menu=="delete":
    toDoList = []
  time.sleep(1)
  os.system('clear')

  2D Dictionaries Remember that dictionaries are very similar to lists, except that they store data as key:value pairs. The value is what it...