# How to import images
p.img(src = "")

# Using p.select and p.option in forms

```python
option = []
data = get_data()
for player in data:
    options.append(p.option(f"{player["id"]}"),)
    THEN
    p.select(
        * options
        name = "player_1_id"),
```

* Name is used at the end of the p.select(), all the options have the same name

* If you’re getting options from a list use, for player in data thingy

* p.option only needs the option name, nothing else. a



# Using jsonhelpers

``` python
import json

import os

# empty_data should be what data we want to put in there if the file doesn't exist

# either {} or [] as we are working with json files

def create_if_not_exist(filename, empty_data):

    if not os.path.exists(filename):

        write_json_file(filename, empty_data)



def write_json_file(filename, info_to_save):

    my_file = open(filename, "w")

    json.dump(info_to_save, my_file)

    my_file.close()



def read_json_file(filename):

    my_file = open(filename, "r")

    information = json.load(my_file)

    my_file.close()

    return information
```



* Create if not exist – used when first creating file

* Read json file used to acually access the file when making any edits

* Write json file used to save changes that have been made.

* Data can be a list or a dictionary



EG. data = create_if_not_exist("tournament.json", SAMPLE_DATA)



EG.  data = read_json_file("tournament.json")

NOTE: THIS GETS THE DATA OF ALL USERS (ASSUMING LOGIN SYSTEM IS USED)



EG. write_json_file("tournament.json", data)






# Logins


## Navigation buttons that need to be displayed if user is not logged in/ logged in

```python
def get_navigation_buttons():

    list_of_nav_buttons = []



    if session.get("username", "") == "":

        list_of_nav_buttons.append(
        p.input(class_="button",type = "submit", value = "Login", formaction = "/login"),)



    else:

        list_of_nav_buttons.append(p.p(f"User: {session['username']}"))

        list_of_nav_buttons.append(p.input(class_="button", type = "submit", value = "Logout", formaction = "/logout" ))



    return list_of_nav_buttons
```

## Dashboard

* check if session.get("username") is not blank
    * if this is true, display the actual navigation to the website + navigation buttons from function

    * if this is not true, only show the navigation buttons from the function



## Main log in page


```python
error = session.get("error message", "")

if "error message"in session:

session.pop("error message")

response = p.html(

p.form(

FORM IN TYPE OF

p.label(p.b(for_="uname")("Username: ")),

p.input(class_="text", type = "text", name = "uname", id = "uname"),

FOR USERNAME AND PASSWORD


p.input(class_="button", type = "submit", value = "Login", formaction = "/submit_login"),

p.label("Don't have an account?"),

p.input(class_="button", type = "submit", value = "Sign Up", formaction = "/signup"),

p.br(),))
```



* Form needs to ask for uname, pwd, submit button or give an option to sign up.

* Session.pop(error message) only operates if they are sent back to this page during log in process



 ## Submitting log in

``` python
username = request.form.get("uname", "")

password = request.form.get("pwd", "")

create_if_not_exist(get_user_file_name(), {})

existing_users = read_json_file(get_user_file_name())


if username in existing_users:

    if password == existing_users[username]:
        session["username"] = username


    else:
        session["error message"] = "Access denied"
        return redirect("/login")



else:

    session["error message"] = "Access denied"
    return redirect("/login")

return redirect("/dashboard")
```

* Gets username and password from form

* Creates file with dict of all users and their password

* Adds this to the existing_users

* Error message applies if password is wrong or log in does not exist



## Sign up Page

``` python
error = session.get("error message", "")

if "error message" in session:

    session.pop("error message")

    FORM IN FORMAT OF :

    p.label(for_="uname")("Username: "),

    p.input(class_="text", type = "text", name = "uname", id = "uname"),

    FOR USERNAME, PASSWORD, CONFIRM PASSWORD

    p.b(error),

    SUBMIT BUTTON THAT GOES TO "/submit_signup"
```


* Asks for username, password and confirm password

* Error message pops up if pwd != confirm pwd



## Submit Signup

```python
username = request.form.get("uname", "")

password = request.form.get("pwd", "")

confirmed_password = request.form.get("cpwd", "")



if username != "" and password != "":

    if confirmed_password == password:

        user_file = get_user_file_name()

        create_if_not_exist(user_file, {})

        existing_users = read_json_file(user_file)


        if username in existing_users:

            session["error message"] = f"Username {username} already taken."

            return redirect("/signup")

        else:

            existing_users[username] = password

            write_json_file(user_file, existing_users)

            create_if_not_exist(get_user_data_file_name(), {})

            user_data = read_json_file(get_user_data_file_name())

            user_data[username] = {}

            write_json_file(get_user_data_file_name(), user_data)

            session["username"] = username

            return redirect ("/dashboard")

    else:
        session["error message"] = "Password does not match Confirmed Password"

        return redirect("/signup")



else:
    session["error message"] = "Password and Username cannot be blank"
    return redirect("/signup")
```



* Needs to check if password and username spots are blank

* And then checks is password = confirm password

* Also checks if the username already exists

* Adds username to existing users dictionary with password

* Updates json file of all users with write_json_file

* Creates the user_data json file if it already doesn’t exist

* Gets user data with read_json_file

* Adds an empty dict next to the user’s name

* Updates the json file of the user data with write_json_file again

## Log out System
```python
 session.pop("username")
    return redirect("/dashboard")
```

# COOKIES

**NEED TO SET SECRET KEY FIRST**

app.secret_key = ""

``` python
username = session.get("username")

calendar_name = request.args.get("calendar")



user_data = read_json_file(get_user_data_file_name())

user = user_data.get(username, {})



calendar = user.get(f"{calendar_name}", {})
```

Basic idea of cookies:

* session.get(“username”) gets username of user

* read_json_file gets the user data file of ALL the users

* user_data.get(username, {}) gets the dictionary of the user or creates an empty dict if it does not exist

* Then based on what is in the dictionary it can be used

IF THERE IS NO LOG IN OPTION

do the following
for example in the scarfs paper
``` python

scarfs = session.get("scarfs", [])
scarfs.append({
    "colour": scarf_colour, "length" : scarf_length})

session["scarfs"] = scarfs.
this way, there is no json file being used, as this is only necessary if there are log in systems
```


# RELATIVE PATHS

* eg. "/player/<player_id>" this is used in the route
* IMPORTANT: Function created in route must have this -  player_page(player_id: str):
* data is sent to a route which has relative paths like so:
    * /player/{player['id']} - the "< >" are not included

# CSS
* RMBR TO PUT THIS IN THE HEADER TAG BEFORE IMPLEMENTING CSS
    ```python
    p.link(rel = "stylesheet", href = "static/style.css"),
    ```
* NAV BAR NOTES
    * classes are made like so:
        ```python
         p.p(p.a(class_="nav_buttons")(link info, href = "/"))
        ```
    * Use the "nav buttons" class in navigation bar link, i.e p.a() sections
    * Use the "nav_list" class in the p.div that covers the whole navigation bar links
    * FOR NAV BUTTONS
        ```CSS
        display:block;
        PICK COLOR
        padding: 15px 25px;
        text-decoration: none; - done to avoid underlines
        ```
    * FOR NAV LIST
        ```CSS
        list-style-type: none;
        margin and padding set to 0
        pick bgd color
        display: flex;
        margin-left: auto;
        ```

    * For hover design do .nav_buttons:hover{}

* Button Design
    ```CSS
    .button{
        set bg colour
        set text colour
        padding: xpx ypx
        set border to none
        set font size and text-align as center
        set cursor as pointer, set border radius, margin, width and gap
    }


* Form Design
```CSS
    .text, select{
        width: set a percent
        padding: set some px
        margin: xpx 0px;
        box-sizing: border-box;
        border-radius: whatever
        display: flex;
        border: 1px solid
    }
```

* Box Shadow

``` CSS
box-shadow: 5px 5px 10px rgb(0 0 0 / 0.2);
Also set padding and box-sizing
```

# Navigating to a different web page with buttons

format that must be used for p.button(): onclick = 'window.location.href="/Order"'

# APIs

1) First you do
    ``` python
    import json,
     ```
    THIS IS NOT THE NAME OF THE FILE

2) THEN,
    ``` python
    with open("... .json", "r") as file:
    data = json.load(file)
    ```

* IF the information in the json fiile was stored like so :
``` python
{
    "students": [
        {
            "name": "Alice",
            "age": 15
        },
        {
            "name": "Bob",
            "age": 16
        }
    ]
}
```

3) You would do,
 students = data["students"] - basically a dictionary

4) Then you can do whatever you require.


# The 'all' function
* This function operates like so - it checks if every item in a list is in another list

``` python
list_a = [1, 2, 3]
list_b = [1, 2, 3, 4, 5]
THIS CHECKS IF ALL THE ITEMS IN A ARE IN B

# Returns True if every item in list_a is found in list_b
result = all(item in list_b for item in list_a)
print(result) # Output: True
```
# How to convert lists to strings in flask

``` python
# Lets say you have the list:
list1 = ["apples", "oranges", "bananas", "pears"]
#to print this as just numbers without the brackets you would do

list1 = ', '.join(list1)
print(list1)
```
























