r"""
EXAMPLE OF A MODULE "DOCSTRING"
   To run this app in a web browser undeployed on the development computer
   run the following command in the Anaconda console.
streamlit run "G:\My Drive\UConn\1-Subjects\Python\STAT476\CODE\StApp1Deploy\StreamlitApp1.py"

# This code is a template for creating a python app to run in a streamlit
# webpage.
# The webpage has a familiar "toolbar on left / plot and output on right"
# layout.

"""

import streamlit as st
from streamlit import session_state as S
   # Writing S.[VarName'] is easier than  st.session_state['VarName']
import matplotlib as mpl
import os
import pandas as pd
import numpy as np
import random

import urllib.request
import urllib

from PIL import Image # Image class from Python PIL package. for 'PIL'.

import openpyxl # Flagged as unused but required for excel behind the scenes.
from io import BytesIO
from pyxlsb import open_workbook as open_xlsb

# Plotly imports. Some may be flagged as unused, but import them anyway.
import scipy  # Used by plotly figure factory behind the scenes.
import plotly
import plotly.express as px
import plotly.figure_factory as ff
import plotly.graph_objects as go

class Global_Variables():  # A class for creating all python global variables.

    ##########################################################################
    # +++ RESOURCES AND OTHER LINKS OR VARIABLES THAT MIGHT CHANGE.
    #   - The values for these variables are all initialized here.

    Debug = False

    #  DETAILS ABOUT THIS MODULE
    # RESOURCE LINKS Etc  Pictures/Videos/Files etc stored online.
    #   Where possible we base our resources in this apps repostitory
    #   at github. If github basing is not possible or inadequate
    #   we have to use another cloud storage site, eg Google drive.Youtube etc.

    # +++ DETAILS ABOUT THIS MODULE
    ThisModule_Project = "Demonstrate and Explore Streamlit and Python."
    ThisModule_Version = "7_00     2022 March 3, 10.29 am EST."
    ThisModule_About = "This module has a done of demo code.. "
    ThisModule_Author = "TB, UConn Math Dept."
    ThisModule_Purpose = ("My first Streamlit app.")
    ThisModule_Contact = "Contacts not supplied."
    ThisModule_Docstring = (__doc__)
    ThisModule_FullPath  = os.path.abspath(__file__)
    ThisModule_FileName = os.path.basename(ThisModule_FullPath)
    ThisModule_ProjectPath = os.path.dirname(ThisModule_FullPath)
    ThisModule_Docstring = (__doc__)

        #https://github.com/ProfBrockway/StreamlitApp1Deploy/raw/main/Resource_ProgramDocumentation.pdf
    # Program Help/Documentation.
    # The raw version will download the pdf automatically.
    Link01 = r"https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/main/Resource_ProgramDocumentation.pdf?raw=true"
    # This will pop up the pdf if googles pdf reader page. But no index or working links.
    Link01 = r"https://docs.google.com/viewer?url=https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/main/Resource_ProgramDocumentation.pdf?raw=true"
    # This will pop up the pdf if googles pdf reader page. But no index or working links.
    Link01 = r"https://smallpdf.com/pdf-reader?url=https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/main/Resource_ProgramDocumentation.pdf?raw=true"
    # The non raw version will go to the file at github and show it in a simple pdf viewer without index.
    Link01 = r"https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/main/Resource_ProgramDocumentation.pdf"
    # Where to report a bug..
    Link04 = r"https://www.ibm.com/us-en?ar=1"
    # A picture stored at this projects repository at github.
    # NOTE: MUST HAVE THE '?raw=true' SUFFIX to extract the pic from github.
    Link06 = r"https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/main/Resource_TigerMoth.jpg?raw=true"
    # This apps code page at Github.
    Link08 = r"https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/0bc950a80603401a54dfb1c6ebe15bc83a362d6e/StreamlitApp1.py"
    # A test pdf online somewhere.
    Link10 = r"https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
    # A RAW url to a demonstration CSV file stored at Github.
    Link11 = r"https://raw.githubusercontent.com/ProfBrockway/StreamlitApp1Deploy/main/Resource_TestCSVFile.csv"
    # A url of a video on Youtube.
    Link20 = r"https://youtu.be/nsHl48Wnudc"
    # A url of a video NOT on Youtube. Just a random website.
    Link24 = r"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4"
    # A url of a video on google drive.
    Link30 = r"https://drive.google.com/file/d/18xDRuX9lTpEuSsjtJjFHz4TNnxfKAWdI/view?usp=sharing"
	# Name of downloaded table
    Link40 = "ScreeningTestDataFrame.csv"
    # +++ END OF RESOURCES AND OTHER LINKS OR VARIABLES THAT MIGHT CHANGE.
    ###########################################################################

    # +++ USERS INPUTS (Copied from input widgets and internalized)
    RowsToGenerate = None
    AFloatNumber = None
    ShowLine3 = None
    ShowInput = None
    ShowData = None

    # +++ SUNDRY GLOBAL VARIABLES
    Fig1 = None
    Plot1 = None
    Title_1 = None
    Title_2 = None
    Msg01 = "Please fill out the input boxes and click the 'Plot Now' button."
    Msg_Current = None

    # +++ DATA TO BE PLOTTED
    x = []
    y1 = None
    y2 = None
    y3 = None

    # +++ A PANDAS DATAFRAME
    DataTable = pd.DataFrame(
    columns=["x",
             "y1",
             "y2",
             "y3",
             "random1",
             "sum with a long name",
             "sum with a longer name",
             "random2"]
                           )
# End of Global Variables
G = Global_Variables()    # Instantiate our global variables.

def MainLine():
    # Remember this app is rerun by streamlit every time the GUI is displayed.
    # So we have to keep track of the conversation state and preserve
    # or recreate variables appropriately.

    # Note: Console output from this program - like print("Whatever") - will
    # appear in the streamlit console NOT the usual python console.
    #    If this is too inconvenient, you can write debbuging information etc,
    #    to the streamlit webpage.
    ConsoleClear()  # Clear the internal IPyhon console.

    # If this the initial session create "Static/Persistent" variables
    # and do the "first load only" program initialization.
    if 'Dialog_State' not in S:
        if G.Debug: print("Debug: State=0 Initial load. Display count=1")
        Perform_First_Load_Only_Initialization()
        S.Dialog_State = 1  # Upgrade state so we don't come back here.

    else:  # We are responding to a session reply from the user.
        S.Display_Count += 1  # Count of sessions.
        if G.Debug:
           print("Debug: State=1. Display count=", S.Display_Count)

        # Initalize variables for every run.
        #   Remember nothing outside the Streamlit static/persistant dictionary
        #   is preserved across sessions. So we perform the one time
        #   program initialization once then perform the "every run"
        #   intialization.
        Perform_EveryRun_Initialization()

        # Validate and internalize users'input.
        InputOK = Validate_And_Internalize_User_Input()
        if InputOK == True:
            # Process the users input and generate the data for plotting.
            Process_Users_Data()
            # Plot the data
            Right_Panel_Build()

        else: # There is an error in the users input.
           st.error(G.Msg_Current) # Show the error in the right panel.

    # Having processed all input, we now insert the output into our GUI,
    # display the GUI and then wait for next user input.
    GUI_Build_And_Show()
    return()  # End of function: MainLine.

def Perform_First_Load_Only_Initialization():

    # Initalize variables etc.
    Perform_EveryRun_Initialization()

    # ++++ Set up a typical "About/Help" menu for the webpage.
    #  - The set_page_config command can only be used once per run.
    #  - The set_page_config command be the first Streamlit command used.
    #  - New line marker \n must be preceeded by at least two blanks to work.
    st.set_page_config  (
     page_title = "Webage Header. ",

     page_icon = ":confused:",

     layout="centered", # or "wide".
        # 'wide' gives a bigger display. 'centered' gives a smaller display
        #  Remember that plots and tables etc on the streamlit webpage
        #  can be "blownup" by the user clicking an "expand" icon.
        #  So don't worry if the normal view is too small.

     initial_sidebar_state="auto",

     # \r requires two preceeding spaces to work.
     menu_items={ # These appear as the webpage "about" menu items.
     'Get Help  ':  G.Link01,
     'Report a bug  ': G.Link04,
     'About': '  \rProgram: ' +  G.ThisModule_FileName
            + '  \rProject:  ' + G.ThisModule_Project
            + '  \rProgram Purpose:  ' + G.ThisModule_Purpose
            + '  \rAuthor:  ' +  G.ThisModule_Author
            + '  \rContacts:  ' +  G.ThisModule_Contact
            +  '  \rVersion:  ' + G.ThisModule_Version
               }
                      )

    # +++ CREATE PERSISTENT/STATIC VARIABLES.
    # https://docs.streamlit.io/library/api-reference/session-state
    # During the first load session, we create our "Persistent" variables.
    #  Persistent variables:
    #   - Are stored and created by streamlit in the streamlit
    #     'session state dictionary'
    #   - Are static (preserved) between sessions.
    #   - Are effectively global.
    #   - Have a python dictionary like syntax.
    #   - Are created using the streamlit "session_state" method.
    #      - Eg:  st.session_state['Display_Count'] = 0
    #      - In our case the st.session_State is abbreviated to Static.
    #          - from streamlit import session_state as Static
    #          - Eg: S.Input_SSN'] = 0
    #   - Can be "linked" to a streamlit widget via the widget key= parameter.
    #      - Using the key= parameter on any widget automatically
    #        creates a static variable in the 'session state dictionary'.
    #        But I prefer to declare them explicity as well.
    #      - Any change in the Static linked widget will automatically update
    #      - the linked persistant variable.
    #      - Any change in linked persistant variable will automatically
    #        update the linked widgets value in the Static dictionary.
    #      - The python type of linked variables are specifed by the
    #        linked widget's  "format=" parameter.
    #
    #      - Eg of a Linked persistent variable.
    #         In this initialization section:
    #              S.FirstName'] = "Fred"  # Create a persistant variable.
    #         In the Static creation code:
    #             st.number_input(label=:Enter first name", key="FirstName")
    #         Notice the key is the same as the persistent variable name.

    S.Dialog_State = 0    # Create session Dialog_State variable.
    S.Display_Count = 1   # A debugging Display_Count of sessions.

    # Persistant variables for the users input in the GUI
    S.MsgText = G.Msg01       # A text box for instructions & errors.
    S.RowsToGenerate = 100    # An integer variable.
    S.AFloatNumber = 123.678  # A float variable.

    # Persistant variables for checkboxes.
    S.ShowLine3 = False
    S.ShowInput = True
    S.ShowData = True

    S.UploadedFile = None

    return()  # End of function: Perform_First_Load_Only_Initialization

def Perform_EveryRun_Initialization():
    # Initalize variables for every run.
    #   Remember nothing is preserved across sessions, except variables in
    #   the Static streamlit "session_state" dictionary in its
    #   static/persistant variables.
    #
    #   On the first run we perform the one time program initialization.
    #   On subsequent runs we perform the "every run" intialization to
    #   initialize or reinitialize anything not preserved across
    #   the display/response dialog.
    #
    # Alternatives to repeating initialization here are:
    # (1) Save static/persistant variables in the streamlit "session_state".
    # (2) Make the initialization "static" using streamlit st.cache.
    #      - Use st.cache if the initialization is very time consuming.
    # (3) Initialize in our Global_Variables class (above)
    #     The Global_Variables class is run everytime the app is run.
    #     So it initializes every time streamlit reruns this app.
    #
    # However having an "Every Time" initialization function is good practice.
    # It may be neccessary to make the logic work.
    # Also its less vulnerable to the subtle misbehaviors of alternatives
    # (1) and (2).

    # No code needed here right now. All initialization done in
    # class Global_Variables.

    return()

def Validate_And_Internalize_User_Input():
    # - This function validates the users input.
    # - This function also internalizes the users input.
    #     -Internalization isolates the data processing from the GUI.
    #     -Internalization is achieved by transfering the input values
    #      from the streamlit persistant session_state dictionary to
    #      regular python variables in our global variable class.
    #    - We are using streamlit for our GUI but that may be replaced.
    #      Also streamlit has some nasty bugs we don't want complicating
    #      the data processing code.
    #
    # - The Streamlit input widgets perform validation for data type
	#   and values ranges.
    #      - Eg: A widget can be set up to disallow a number input
	#        that is not numeric.
    #      - So most of the following validations are duplicative.
    #        But I have left them in as belt and suspenders.

    Msg_Set("")

    # Validate and internalize population.
    G.RowsToGenerate, InputOK = Validate_Integer(S.RowsToGenerate)
    if InputOK == False:
        Msg_Set("Error 1006:\n'Rows to Generate' must be an integer.")
        return(False)
    if (G.RowsToGenerate < 50):
        Msg_Set("Error 1008:\n'Rows To Generate' must be [50,150] but not 99.")
        return (False)
    if S.RowsToGenerate == 99:
       Msg_Set("Error 1010:\n'Rows to Generate' is 99 which is not ok.")
       return(False)
    G.AFloatNumber, InputOK= Validate_Float(S.AFloatNumber)
    if G.AFloatNumber == 9:
       Msg_Set("Error 1012:\n'A FloatNumber' is exactly 9 which is not ok.")
       return(False)

    # Internalize checkbox options.
    G.ShowLine3 = S.ShowLine3
    G.ShowInput = S.ShowInput
    G.ShowData = S.ShowData

    # If we fall through here the users input is all valid.
    Msg_Set(G.Msg01)    # The "Please enter test specs" message.
    return(True)  # End of function: Validate_And_Internalize_User_Input

def Process_Users_Data():
    # Process the users input and create the data to be plotted/output.
    G.x = list(range(0, G.RowsToGenerate))
    G.y1 = G.x
    G.y2 = [item ** 1.2 for item in G.x]
    G.y3 = [item * -1 for item in G.x]

    # Create an example Pandas dataframe for plotting etc
    # The values are meaningless.

    i = -1
    for  xvalue in (G.x):
       i = i + 1
       newrow = {'x' : xvalue,
                 'y1':   G.y1[i],
                 'y2':   G.y2[i],
                 'y3':   G.y3[i],
                 'random1': random.random(),
                 'sum with a long name': G.y1[i] + G.y2[i],
                 'sum with a longer name': G.y1[i] + G.y2[i] + + G.y3[i],
                 'random2': random.randint(1,100)
               }
       G.DataTable = G.DataTable.append(newrow, ignore_index=True)

    # Temporary code only.
    # csvfullpath = os.path.join(G.ThisModule_ProjectPath,"TestCSVFile.csv")
    # G.DataTable.to_csv(csvfullpath)

    # End for
    return()  # End of function: Generate_Data_To_Be_Plotted

def Right_Panel_Build():  # Build the main panel on the right. Plot, pics etc.

###############################################################################
    FullScreenIcon_Enlarge() # Make the streamlit full screen icon larger.

###############################################################################
    #  +++ SHOW A CLICKABLE WEBLINK ON OUR WEBPAGE Static.
    #   There are several ways to do this.
    st.markdown("### LINK TO THIS APPS CODE. (DOWNLOADABLE). ")
    st.markdown(f" [Link To Source Code]({G.Link08})"  )
    # Also works: st.write("[Link To The Source Code](%s)" % G.Link08)

###############################################################################
    # +++ CREATE A MATPLOTLIB FIGURE.
    G.Fig1 = mpl.figure.Figure()

    # Create a plot object within the main figure with multiple lines.
    G.Plot1 = G.Fig1.add_subplot(111)
    G.Plot1.clear()  # Clear any current plot in G.Plot1. Just to be sure.

    # Add two lines to the plot
    G.Plot1.plot(G.x, G.y1, label="Y = X", color="red")
    G.Plot1.plot(G.x, G.y2, label="Y = X**2", color="blue")

    # The following shows how the plot can be modified by users requests.
    if G.ShowLine3 == True:
        G.Plot1.plot(G.x, G.y3, label="Y = - X", color="green")

    # Prettyfy the plot.
    G.Plot1.minorticks_on()
    G.Plot1.legend(loc="best", fontsize=14, prop={"weight": "bold"})
    G.Plot1.set_title(Title_Build("long"),fontsize=10,fontweight="bold" )
    G.Plot1.grid(visible=True, which='major', axis="both")
    G.Plot1.set_xlabel("A sample x axis. x=[0,100]")
    G.Plot1.set_ylabel("Y Values Value")

    # Put header(s) before the plot.
    st.subheader(" This Is The Static 'Output Display Panel' On The Right")
    if G.ShowInput == True:
        temptext = f"""
             ### The Values You Entered Are Listed Below.  \r
            {Title_Build()}  \r
            \r
            More Stuff:
            1. Blah blah.
            1. More Blah Blah.
            1. HOW TO ENLARGE OR SAVE THE PLOT :
                1. You can enlarge the plot using the View fullscreen icon. The icon is above and to the right of the plot.
                2. You can save the plot to your computer. Right click on the plot, then use 'save image' or 'copy image'.
            1. Great stuff !
            """
        st.info(temptext )
    else:
        st.subheader("The Values You Entered Are Not Displayed.")

    # Show the plot on the streamlit webpage.
    st.pyplot(G.Fig1)  # st.write(G.Fig1) also Displays a Matplotlib figure.

###############################################################################
    # +++ PROVE EXTERIOR HELPER FUNCTIONS WORK IN STREAMLIT
    st.info("PROVE EXTERIOR HELPER FUNCTIONS WORK IN STREAMLIT")
    from HelperFunctions import Exterior_Helper_Function1
    from HelperFunctions import Exterior_Helper_Function2
    st.text(Exterior_Helper_Function1())
    st.text(Exterior_Helper_Function2())

###############################################################################
   # +++ SHOW A PANDAS DATAFRAME IF USER REQUESTED IT.
    if G.ShowData == True:
       st.markdown("#### The Pandas Data Table You Requested Follows:")
       st.dataframe(data=G.DataTable, width=None, height=None)
       st.write("The data shown is just filler to demonstrate a Pandas "
                      "dataframe.")
       st.write("The dataframe display will automatically offer vertical "
                    "and horizontal scroll bars if required.")
       st.write("You can expand the datatable using the 'View fullscreen' "
                    "icon. The icon is above and to the right of the table.")

###############################################################################
    #  +++ ADD A "DOWNLOAD TO CSV" DATAFRAME BUTTON.
       # - The dataframe is converted to a csv file.
       # - That file is downloaded to the browsers download location.
       #  - There is no "save as" menu. The file name is hard coded.
       DataFrame_CSV = G.DataTable.to_csv().encode('utf-8')
       st.markdown("#### Download The Pandas DataFrame As A CSV File.")
       helpstr = f"""You can save the data frame to your computer using this button.  \r
                    The file will be called {G.Link40}.   \r
                     The file will be saved in your browser's default 'download' location on your computer.
	             """
       st.download_button(label="⚙ Download The DataFrame",
            data=DataFrame_CSV,
            file_name=G.Link40,
            mime= "text/csv",
            key="DownloadCSV_Button",
            help=helpstr,
            on_click=None,
            args=None,
            kwargs=None,
            disabled=False)

###############################################################################
   # +++ SHOW A PRETTYFIED PANDAS DATAFRAME +++++++++++++++++++++++++++++++++++
    # https://towardsdatascience.com/style-pandas-dataframe-like-a-master-6b02bf6468b0
    st.markdown("#### Here is the same dataframe Sorted descending on 'x', with titles and interesting data cells highlighted:")

    # We do this by creating a pandas styling object.
    # Styling should be performed after the data in a DataFrame has been processed.
    # https://pandas.pydata.org/pandas-docs/stable/user_guide/style.html

    def PdFormat_Align(s, props="text_align: center;"):
        return props

    def PdFormat_Max(s):  # Highlight the maximum value in all cols
        is_max = s == s.max()  # Create list of joint max vals.
        return ['background-color: lightblue' if v else '' for v in is_max]

    def PdFormat_ByVal(v):
        if v < 0 :    color="red"
        if v == 0:    color="blue"
        if v > 0:     color="green"
        if v == 96:   color = "yellow"
        style = f"color: {color};"
        return (style)

    # Sort and apply color styles to particular col and values of that col.
    # Since this looks at each element in turn we use applymap
    Styler1 = G.DataTable.sort_values(["x"], ascending=False).reset_index(drop=True).style.applymap(PdFormat_ByVal, subset=["x"])

    # Apply color styles to particular col and values of that col.
    # Since this looks at each element in turn we use applymap
    Styler2 = G.DataTable.style.applymap(PdFormat_ByVal, subset=["x"])

    # Apply color styles to all values.
    # Since this looks at each element in turn we use applymap
    Styler3 = G.DataTable.style.applymap(PdFormat_ByVal)

    st.dataframe(Styler1, width=None, height=None)

###############################################################################
    #  +++ ADD A "DOWNLOAD TO EXCEL" DATAFRAME BUTTON. IT KEEPS FORMATING
    #      COLORS ETC.
    def DataFrame_To_Excel(df):
        output = BytesIO()
        writer = pd.ExcelWriter(output, engine="xlsxwriter")
        df.to_excel(writer, index=False, sheet_name="Sheet1")
        workbook = writer.book
        worksheet = writer.sheets["Sheet1"]
        format1 = workbook.add_format({"num_format": '0.00'})
        worksheet.set_column("A:A", None, format1)
        writer.save()
        processed_data = output.getvalue()
        return (processed_data)

    # NOTE !! If we use a styler on the grid we can pass that instead
    #         of the dataframe and preserve all stylings in the excel file.
    df_xlsx = DataFrame_To_Excel(Styler1)
    st.download_button(label="📥 Download DataFrame To An Excel File",
     data=df_xlsx ,
     help="In an Excel file any cell highlighting or other "
          "styling will be preserved.",
     file_name= "df_CSV_To_Excel.xlsx")

###############################################################################
    # Use a styler to format and alter value of columns.
    Styler4 = G.DataTable.style.format(
        na_rep='MISSING', thousands=",",
        formatter={
          ("y1", "random1")        : "{:.6f}",
          ("sum with a long name" ): "{:.2f}",
          ("y2")                   : lambda x: "$ {:,.1f}".format(x*1000),
          ("y3")                   : PdFormat_ByVal
                  })

    #Styler4.set_table_styles([cell_hover, index_names, headers])
    st.dataframe(Styler4)

###############################################################################
    #  +++ SHOW FONT CHANGES IN TEXT USING HTML.
    MDText = StMarkdown(
        "This Demonstrates That We Can Format Text Using HTML.",
         fontsize=22,bold=True,color="blue")
    st.markdown(MDText, unsafe_allow_html=True)

###############################################################################
    # +++ DEMONSTRATE SHOWING A PICTURE FROM THE APPS GITHUB REPOSITORY.
    #   We must get our picture (and other resources) from a web address
    #   because streamlit does NOT have a full backend on its server from
    #   which server disk we might otherwise get resources.
    #   The obvious online repository for resources like pictures is the
    #   github repository for the project. Streamlit drives itself from
    #   the github repository. However github cannot as yet support some
    #   resources. For example a pdf displayed at github does not support
    #   pdf features like indexing or links.
    # Also the video storage is very  limited at github. S
    # So we will be using other online sites to store web
    #   accessable resources. (Eg Youtube)
    # - How to user github to host media for display
    #     https://www.labnol.org/internet/free-file-hosting-github/29092/
    st.markdown("#### DEMONSTRATE SHOWING A PICTURE FROM THE APPS GITHUB REPOSITORY.")
    st.image(G.Link06,
        caption="We used a github url address to get this picture from "
       "  github.   \n"
        "  NOTE: THE URL MUST HAVE THE '?raw=true' SUFFIX to extract the pic"
        "from github.")
    st.write("You can enlarge the picture by clicking the pop up symbol "
             "that appears when you mouse near the top right of the image.")

###############################################################################
    st.markdown("#### DEMONSTRATE SHOWING A SIZED PICTURE .")
    urllib.request.urlretrieve(G.Link06,"img.jpg") # Get image from web.
    img = Image.open("img.jpg")
    img.thumbnail((500, 500)) # Set the desired size. Its one tuple parameter.
    st.image(img)  # Show the resized image.

###############################################################################
    # # +++ DEMONSTRATE DOWNLOADING A PICTURE USING A DOWNLOAD BUTTON.
    # with open(G.Link06, "rb") as file:
    #  btn = st.download_button(
    #          label="Download image",
    #          data=file,
    #          file_name="Resource_TigerMoth.jpg",
    #          mime="image/png"
    #        )

###############################################################################
    # +++ DEMONSTRATE SHOWING A VIDEO FROM YOUTUBE.
    #  Github basing of videos does not allow raw address of large files.
    #  Google basing of videos  does not work because it downloads too slowly.
    #  So until I can figure out how to base videos at github we use Youtube.
    st.markdown("#### DEMONSTRATE SHOWING A VIDEO FROM YOUTUBE.")
    FullURL = G.Link20
    st.video(FullURL)

###############################################################################
    # +++ DEMONSTRATE SHOWING A VIDEO FROM AN ONLINE SOURCE OTHER THAN YOUTUBE.
    #  Github basing of videos does not allow raw address of large files.
    #  Google basing of videos  does not work because it downloads too slowly.
    st.markdown("#### DEMONSTRATE SHOWING A VIDEO AN ONLINE SOURCE OTHER THAN YOUTUBE.")
    st.write("The following video is just on a website somewhere.")
    st.video(G.Link24)

###############################################################################
    # # +++ DEMONSTRATE SHOWING A VIDEO FROM GOOGLE DRIVE.
    # #  Github does not allow raw address of large files.
    # #  Google basing of videos  does not work because it downloads too slowly.
    # st.subheader("DEMONSTRATE SHOWING A VIDEO FROM GOOGLE DRIVE.")
    # st.write("")
    # st.video(G.Link30)

###############################################################################
    # +++ DEMONSTRATE EASY SHOWING A PYTHON DICTIONARY ON A STREAMLIT WEBPAGE.
    df4 ={1: {'name': 'John', 'age': '27', 'sex': 'Male'},
          2: {'name': 'Marie', 'age': '22', 'sex': 'Female'},
          3: {'name': 'Luna', 'age': '24', 'sex': 'Female', 'married': 'No'},
          4: {'name': 'Peter', 'age': '29', 'sex': 'Male', 'married': 'Yes'}}

    st.info("DEMONSTRATE SHOWING A PYTHON DICTIONARY ON A STREAMLIT WEBPAGE.")
    st.text("Pretty printing python dictionarys is easy using streamlit.  \n"
                 "We use the st.dataframe feature.")
    st.dataframe(df4)

###############################################################################
    #  +++ SHOW A PLOT USING PLOTLY WHICH HAS GREAT INTERACTIVE CONTROLS
    st.info("DEMONSTRATE A 'PLOTLY' PLOT WITH GREAT INTERACTIVE CONTROLS.")
    st.write("""See my program 'screening test' for a much better example
             of using plotly graphs which are MUCH better than
             matplotlib in screenlit because the plotly plots are
             interactive.              """)
    # Add histogram data
    x1 = np.random.randn(200) - 2
    x2 = np.random.randn(200)
    x3 = np.random.randn(200) + 2
    # Group data together
    hist_data = [x1, x2, x3]
    group_labels = ['Group 1', 'Group 2', 'Group 3']
    # Create distplot with custom bin_size
    fig = ff.create_distplot(
             hist_data, group_labels, bin_size=[.1, .25, .5])
    st.plotly_chart(fig, use_container_width=True)   # Plot!

    #  +++ SHOW A PDF AT GITHUB USING POP UP NEW WEB PAGE
    ###########################################################################
    # +++ MAKE THIS APPS DOCUMENTATION AVAILABLE.
    #   We  base the pdf file in the github repository for the project.
    #   The github using the github link to the address displays
    #   the pdf file in the primitive github pdf view which does not
    #   have basic features, especially the pdf document index.
    #   I have not been able to fix this problem so for now, the pdf
    #   is displayed and the user advised to download it a use a
    #   proper pdf viewer.
    st.info("🟢 THIS APP'S DOCUMENTATION.")

    col1, col2 = st.columns(2)
    with col1:
        st.write(" [ Link To This App's Documentation.]"  "(%s)" % G.Link01)

    with col2:
        # Here we use a trick to display a pop up help message.
        # We use an st.button and load its help parameter with our popup.
        # This works fine when the user hovers the mouse over the button.
        # But when the user clicks the button (as is reasonable) the
        # app is rerun. This doesn't produce any errors but is obviously
        # inefficient. We have to live with this until we find a better
        # method for pop up messages.
        tempstr = ("""You can read this app's documentation at the
        provided link using a primitive pdf reader.  \r
        But by downloading the documentation PDF and viewing it
        on your computer you will be able to navigate the document using
        an index, search, etc.  \r
        You can also see the program documentation by using
        the menu in the top right of this webpage '≡' (3 horizontal lines) then
        select 'GET HELP'. """)
        st.button(label="Help", key="ButtonH1", help=tempstr )

###############################################################################
    # DEMONSTRATE HOW TO USE AN ICON
    # https://share.streamlit.io/streamlit/emoji-shortcodes
    # Just copy and paste the icon from the list.
    # Not all of the :whatever: codes work so best avoid that method.
    st.write("✔  ❌  How to include icons in any text",help="help text here" )

###############################################################################
    # +++ SHOW DEBUGGING INFORMATION.
    if G.Debug:
      st.subheader("Debugging Information Follows.")
      st.write(" The streamlit st.session_state persistant/static "
                    "variables follow.")
      st.write(S)    #  Show all streamlit persistent variables.
                # st.write(G)  # ?v fix so this works For debugging. Show global variables.

###############################################################################
    # +++ DEMONSTRATE AN EXPANDER
    st.subheader("DEMONSTRATE AN EXPANDER.")
    with st.expander("An expanding section that shows debugging information"):
        st.write(""" Write or display anything here. """)
        st.write("You can call any Streamlit command.")
        st.subheader("Debugging Information Follows.")
        st.write(" The streamlit st.session_state persistant/static "
                      "variables follow.")
        st.write(S)    #  Show all streamlit persistent variables.
        # st.write(G)  # ?v fix so this works For  Show global variables.

###############################################################################
    # +++ DEMONSTRATE A CONTAINER, ALLOWS GROUPING OF ITEMS
    st.subheader("DEMONSTRATE A CONTAINER.")
    with st.container():
        st.write("This is inside the container")
        st.write(""" Inserts an invisible container into your app that
                 can be used to hold multiple elements. This allows you to,
                 for example, insert multiple elements into your
                 app out of order.""")
    st.write("This is outside the container")

###############################################################################
    # +++ DEMONSTRATE COLUMN LAYOUT.
    st.subheader("DEMONSTRATE COLUMN LAYOUT. ")
    col1, col2, col3 = st.columns(3)
    with col1:
        st.header("A cat")
        st.image("https://static.streamlit.io/examples/cat.jpg")
    with col2:
        st.header("A dog")
        st.image("https://static.streamlit.io/examples/dog.jpg")
    with col3:
        st.header("An owl")
        st.image("https://static.streamlit.io/examples/owl.jpg")

###############################################################################
    # +++ DEMONSTRATE HOW THE ST.TEXT FEATURE FORMATS TEXT..
    st.info("Demonstrate using st.text with end of line characters")
    Anumber = 678.4325
    helpstr = f"""
    This shows how st.text shows fixed width preformatted text.\r
      A number. {Anumber}    \r
      This will appear on a new line.   \r
      The will be on another line."""
    st.text(helpstr)

    # +++ DEMONSTRATE A STREAMLIT 'INFO' Box.
    st.info("ℹ  This is a Streamlit 'info' box.")

    # +++ DEMONSTRATE A STREAMLIT 'WARNING' Box.
    st.warning("⚠ This is a Streamlit 'warning' box.")

    # +++ DEMONSTRATE A STREAMLIT 'ERROR' Box.
    st.error("❌ This is a Streamlit 'error' box.")

    # +++ DEMONSTRATE A STREAMLIT 'SUCCESS' Box.
    st.success("✅	This is a Streamlit 'success' box.")

    # +++ DEMONSTRATE A STREAMLIT 'EXCEPTION' Box.
    st.exception("This is a Streamlit 'exception' box.")

    # +++ DEMONSTRATE EMOJIS
    # The emojis supported by streamlit
    #    https://share.streamlit.io/streamlit/emoji-shortcodes
    # Just include the emojis markdown code in any output.
    st.info("The demonstates how easy it is to include emojis in any text:  \n"
            "  \n'white_check_mark ' :white_check_mark: "
            "  \n'pushpin ' :pushpin: " )

###############################################################################
    # DEMONSTRATE READING A CSV FILE FROM THE PROJECT'S GITHUB REPOSITORY.
    temptext = """
    ### DEMONSTRATE READING A CSV FILE FROM THE PROJECT'S GITHUB REPOSITORY.  \n
          THIS ALLOWS YOU TO HAVE A DATABASE AVAILABLE TO THE DEPLOYED
          APP WITHOUT THE NEED OF A WEB HOSTING BACKEND.  \n
            """
    st.info(temptext)
    df2 = pd.read_csv(G.Link11)
    st.dataframe(data=df2, width=None, height=None)

###############################################################################
    # +++ DEMONSTRATE A STREAMLIT FILE UPLOAD BUTTON.
    # https://pythonwife.com/file-upload-download-with-streamlit/
    st.info("DEMONSTRATE A STREAMLIT FILE UPLOAD BUTTON")
    UploadedFiles = st.file_uploader("Upload a file why not",
                    key="UploadedFile",  #?V Add to static dictionary
                    type="", # Let the user upload any file type
                    help = "Help text appears here.",
                    accept_multiple_files=True,
                    on_change = None, # Callback event
                    args =(), # optional tuple of args to pass to the callback.
                    kwargs = (), # A doctionary of kwargs to pass to  callback.
                    )

    if st.button("Process The Files"):
        # List details of the files uploaded.
        if UploadedFiles is not None:
           # The UploadedFile class is a subclass of BytesIO, and therefore it is
           # "file-like". This means you can pass them anywhere where a file
           # is expected
           i = 0
           for Uploaded_File in UploadedFiles:
    		   # Create a dictionary of the file details, which prints pretty.
               file_details = {"File Index In List Of Files":i,
                               "Filename":Uploaded_File.name,
                               "FileType":Uploaded_File.type,
                               "FileSize":Uploaded_File.size,
                               "InteralID":Uploaded_File.id}
               st.write(file_details)
               i = i + 1

###############################################################################
    ###########################################################################
    # +++ SHOW THIS APPS DOCSTRING
    #  Github basing of videos does not allow raw address of large files.
    #  Google basing of videos  does not work because it downloads too slowly.
    #  So until I can figure out how to base videos at github we use Youtube.
    st.info("🟢  THIS APP's DOCUMENT STRING FOLLOWS.")
    st.text(G.ThisModule_Docstring)

###############################################################################
    # # +++ DEMONSTRATE AN EMPTY CONTAINER. ALLOWS REMOVAL OF ITEMS
    # import time
    # st.subheader("DEMONSTRATE AN EMPTY CONTAINER.ALLOWS REMOVAL OF ITEMS.")
    # with st.empty():
    #     for seconds in range(20):
    #         st.write(f"⏳ {seconds} seconds have passed")
    #         time.sleep(1)
    #     st.write("✔ 1 minute over!")

################################################################################
    # +++ SHOW A TEXT OR CODE FILE STORED ONLINE.

    st.info("🟢  DISPLAY A TEXT OR CODE FILE STORED ONLINE (Github).")
    # At github be sure to get the github 'raw' url for the target file note
    # the regular url. You'll see the 'raw' option when at github.
    CodeUrl ="https://raw.githubusercontent.com/ProfBrockway/StreamlitApp1Deploy/main/HelperFunctions.py"
    file = urllib.request.urlopen(CodeUrl)
    content =  file.read().decode(file.headers.get_content_charset())
    st.text(content)

###############################################################################
    # +++ DEMONSTRATE USING AN EXCEL FILE (Upload then make it a pandas dataframe.")
    # https://towardsdatascience.com/how-to-work-with-excel-files-in-pandas-c584abb67bfb
    st.info("DEMONSTRATE USING AN EXCEL FILE BASED ONLINE IN THE GITHUB REPOSTIORY")
    st.write("Be sure that that remote url of the excel file includes the 'raw' suffix ?raw=true")
    st.write("For pandas to input an excel file you must install a pandas slave program xlrd. pip install xlrd  ")
    xPath = r"https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/main/Resource_TestExcelFile.xlsx?raw=true"
    df_sheet = pd.read_excel(xPath, sheet_name=0)
    st.write("EXCEL FILE FOLLOWS:\n",df_sheet)

    st.info("""########################################################   \r
             STREAMLIT,  PANDAS DATAFRAMES AND EXCEL SECTION FOLLOWS. """)
    #  FOR INSTRUCTION READ THIS LINK:
        # https://coderzcolumn.com/tutorials/python/simple-guide-to-style-display-of-pandas-dataframes#3
    # - set_table_styles(table_styles,axis=0,overwrite=True)  Format whole table
    # - set_td_classes(classes_dataframe) Format individual cells
    #   - set_td_classes works in combination with set_table_styles()
    # - apply(func,axis=0,subset=None) - Well suited for row-wise or column-wise decoration.
    # - applymap(func,subset=None) - Well suited for the decoration of individual cells based on some conditions.
    #
    # https://pandas.pydata.org/pandas-docs/stable/user_guide/style.html
    #
    # - USING functions TO STYLE:  https://pandas.pydata.org/pandas-docs/version/0.25.1/user_guide/style.html
    #     Styler.applymap: elementwise
    #     Styler.apply: column-/row-/table-wise

    # - Using Styler to manipulate the display is a useful feature because
    #   maintaining the indexing and datavalues for other purposes gives
    #   greater control. You do NOT have to overwrite your DataFrame to
    #   display it how you like including sorting.

###############################################################################
    # Get a local csv file and read it into a pandas dataframe.
    fpath=r"G:\My Drive\UConn\1-Subjects\Python\STAT476\CODE\StApp1Deploy\TestData1.csv"
    DFS1 = pd.read_csv (fpath)
    # Show the freshly loaded dataframe.
    st.info("DFS1: As read in from 'TestData1.csv'.")
    st.dataframe(DFS1)

###############################################################################
    st.info("DFS1: Lots of DIFFERENT FORMATTING APPLIED ALL AT ONCE.  \r"
            "Highlight min/max/NaN. Also color by sign. Also color columns."
            "Also apply precision. Also alter output eg decimal percent to percent.")
    # Hide does not work.       .apply(PD_Col_Color)\ not working
    StylerA = DFS1.style\
      .hide_columns(["TP","TN"])\
      .format({  # Format cells in each column.
        "Country": "{:s}" ,
        "Prevalence": lambda x: "{:.3f}%".format(x*100), # Alter val to %.
        "ColA": lambda x: "{:.5f}".format(abs(x)),  # Remove sign.
        "ColC": "{:+.2f}",
        "Column DDD": "{:-.2f}",
        "TP": "{:.7f}",
        "TN": "{:+4.0f}",  # integer
            })\
      .set_properties(subset=["Country"],**{"background-color": "red", "color": "white"})\
      .set_properties(subset=["TN"],**{"background-color": "black", "color": "white"})\
      .applymap(PDFormat_Numeric_By_Sign)\
      .highlight_max(color = "lightgreen")\
      .highlight_min(color = "coral")\
      .highlight_null(null_color="yellow")
    st.dataframe(StylerA)

###############################################################################
    st.info("DFS1: DOWNLOAD CSV DATAFRAME TO EXCEL FILE  \r"
            "This download will preserve the colors and stylings of the "
            "displayed dataframe. Usefull if we have highlighted (say) "
            "cells with errors.")
    def to_excel(df):
        output = BytesIO()
        writer = pd.ExcelWriter(output, engine="xlsxwriter")
        df.to_excel(writer, index=False, sheet_name="Sheet1")
        workbook = writer.book
        worksheet = writer.sheets["Sheet1"]
        format1 = workbook.add_format({"num_format": '0.00'})
        worksheet.set_column("A:A", None, format1)
        writer.save()
        processed_data = output.getvalue()
        return (processed_data)

    df_xlsx = to_excel(StylerA)
    st.download_button(label="📥 Download DataFrame To An Excel File",
                       data=df_xlsx ,
                       file_name= "df_CSV_To_Excel.xlsx")

###############################################################################
    st.info("DFS1: HIGHLIGHT ROW(S) ")
    def highlight_rows(row):
        f1 = ""
        value = row.loc["Country"]
        if value == "Canada":
            backcolor = "blue"
            color = "white"
        elif value == "Mexico":
            backcolor = "green"
            color = "white"
        else:
            backcolor = "white"
            color = "black"
        f1 =[f"background-color:{backcolor};color:{color}" for col in row]
        return (f1)

    StylerP = DFS1.style.apply(highlight_rows, axis=1)
    st.dataframe(StylerP)

###############################################################################
    st.info("DFS1: HIGHLIGHT COLUMNS(S) ")
    def highlight_cols(currentcol):
        f1 = ""
        if currentcol.name == "Country":
            backcolor = "blue"
            color = "white"
        elif currentcol.name == "Prevalence":
            backcolor = "green"
            color = "white"
        else:
            backcolor = "white"
            color = "black"
        f1 =[f"background-color:{backcolor};color:{color}" for row in currentcol]
        return (f1)

    StylerQ = DFS1.style.apply(highlight_cols, axis=0)
    st.dataframe(StylerQ)

###############################################################################
    st.info("DFS1: Save the styled dataframe above to a similarly styled xcel file. See 'styled.xlsx' in this programs project folder.")
    StylerR = DFS1.style\
      .applymap(PDFormat_Numeric_By_Sign)\
      .highlight_max(color = "lightgreen")\
      .highlight_min(color = "coral")\
      .highlight_null(null_color="yellow")\
      .to_excel("styled.xlsx", engine="openpyxl")

###############################################################################
    st.info("DFS1: Highlight Pos/Neg/Zero. On JUST 'ColA' and 'ColC'.")
    StylerC = DFS1.style.applymap(PDFormat_Numeric_By_Sign, subset=["ColA","ColC"])
    st.dataframe(StylerC)

###############################################################################
    st.info("DFS1: Highlight Pos/Neg/Zero. On ALL CELLS")
    StylerD = DFS1.style.applymap(PDFormat_Numeric_By_Sign)
    st.dataframe(StylerD)

###############################################################################
    st.info("DFS1: Format cells by column membership.")
    # ‘d’ for integers
    # ‘f’ for floating-point numbers
    # ‘b’ for binary numbers
    # ‘o’ for octal numbers
    # ‘x’ for octal hexadecimal numbers
    # ‘s’ for string
    # ‘e’ for floating-point in an exponent format
    StylerF = DFS1.style.format(
        {
        "Country": "{:s} color:yellow",
        "Prevalence": "{:> 0.5f}",
        "ColA": lambda x: "{:.5f}".format(abs(x)), # Apply a function to alter value.
        "ColC": "{:+.2f}",
        "Column DDD": "{:-.2f}",
        "TP": "{:.7f}",
        "TN": "{:+4.0f}",  # integer
        })
    st.dataframe(StylerF)

###############################################################################
    st.info("DFS1: READ AN ONLNE EXCEL FILE INTO A PANDAS DATAFRAME. USING NATIVE PANDAS") #
    # The excel file is stored at github so we must use the github 'raw' url.
    # Github does not offer the 'raw' url for all files. In that case
    # use the files regular github page then add '?raw=true' to the end.
    urlexcel = "https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/main/Resource_TestExcelFile.xlsx?raw=true"
    df=pd.read_excel(urlexcel, sheet_name="Resource_TestExcelSheet")
    st.dataframe(df)

###############################################################################
    st.info("DFS1: READ A POORLY SUITED ONLINE EXCEL FILE INTO A PANDAS "
         "DATAFRAME. USING NATIVE PANDAS AND openpyxl. "
         "We can specify where the header row is, the cols we want etc, etc.")

    # Native pandas does a great job reading simple xcel files/worksheets.
    # But in cases where the data is not a continuous table starting at
    # cell A1, the results may not be good.
    # Details here:
        # https://pbpython.com/pandas-excel-range.html

    # The excel file is stored at github so we must use the github 'raw' url.
    # Github does not offer the 'raw' url for all files. In that case
    # use the files regular github page then add '?raw=true' to the end.
    urlexcel = "https://github.com/ProfBrockway/StreamlitApp1Deploy/blob/main/Resource_TestExcelFile.xlsx?raw=true"
    df=pd.read_excel(
        urlexcel,
        sheet_name="Resource_TestExcelSheet",
        header=0, # Specify row of the headers (Might not be the first row).
        usecols=["x","y1","y2","y3","random2",]) # Pick cols.
    st.dataframe(df)

def PD_Col_Color (cols):
    ForColor = "yellow"
    BgColor = "pink"
    formstring = ""
    # for col in cols: #.iteritems():
    #     columnSeriesObj = cols[col]
    #     if col.name=="Country":
    #         formstring = f"background-color:{BgColor};color:{ForColor}"
    return (formstring)

    # We do this by creating a pandas styling object.
    # Styling should be performed after the data in a DataFrame has been processed.
    # https://pandas.pydata.org/pandas-docs/stable/user_guide/style.html

def PdFormat_Align(s, props="text_align: center;"):
    return props

def PdFormat_Max(s):  # Highlight the maximum value in all cols
    is_max = s == s.max()  # Create list of joint max vals.
    return ['background-color: lightblue' if v else '' for v in is_max]

def PDFormat_Numeric_By_Sign(v):
    # Style numeric cells depending on positive/negative/zero value.
    # Each cell in the dataframe is passed as v, one by one.
    style= "" # In case the item is not a number.
    color=""  # In case the item is not a number.
    if isinstance(v, (int, float)):
        if v < 0.0 :     color="red"
        if v == 0.0:     color="blue"
        if v > 0.0:      color="green"
        if v == -23.0:   color = "yellow"
        style = f"color: {color};"
    return (style)

    return  # End of function: Right_Panel_Build

def GUI_Build_And_Show():        # Build the GUI.
    # - Our GUI is a streamlit web page with widgets in a vertical toolbar
    #   on the left and a plot and display area on the right.
    #
    # - !!!!! DON'T ADD A "value=" parameter to any input widget. !!!!!!
    #     The "val=" causes error messages about duplicate initialization.
    #
    #  - Widget values are stored in "linked" streamlit persistent variables.
    #     The value input/output to/from each widget is stored in/retrieved
    #     from a streamlit "linked" persistant variable linked to the
    #     widget's by the widgets "key=" parameter. See elsewhere in this
    #     program for an explanation of "linked" static variables.

    # - We now make the sidebar a single form with a single submit button.
    #    With st.form and its form_submit_button, this app only reruns
    #    when you hit the form submit button, NOT at each widget interaction.
    #    https://blog.streamlit.io/introducing-submit-button-and-forms/
    Form1 = st.sidebar.form(key="Form1", clear_on_submit=False)

    with Form1:
        # Add a title to the toolbar on the left.
        MDText = StMarkdown("THIS IS THE TOOLBAR",
           color="green",bold=True,italic=True,fontsize=16,align="center")
        st.write(MDText, unsafe_allow_html=True)

		# Add a form submit button.
        # Every "form" must have exactly one form_submit_button.
        st.form_submit_button(
                    label='Plot Now',
                    on_click=PlotNowButton_Click_Event,
                    help="When you have entered the parameters  \r"
                    "for the calculations click  \r"
                    "this button to draw your plot.",
                    args=(),
                    kwargs=())

        st.warning("The demonstates how easy it is to include emojis in "
                " any text:  \n"
                "  \n'white_check_mark ' :white_check_mark: "
                "  \n'pushpin ' :pushpin: " )

        # Create a textbox for displaying instructions and error messages.
        st.text_area(
            key="MsgText",   # Value will be placed in S.MsgText'].
            label="INSTRUCTIONS",
            height=150,
            max_chars=None,
            help="Watch here for instructions and error messages",
            on_change=None)

        # Create input boxes in the toolbar for our user specifed variables.

        #  Have the user input an integer from a widget.
        st.number_input(
            key="RowsToGenerate", # Value  linked to S.RowsToGenerate'].
            label="Table Rows To Generate",
            min_value=1,       # Be sure all values for this variable are
            max_value=1000,    # specified as integers.
            step=None,         # else streamlit throws an error.
            format="%i",       # Make this variable an integer.
            help="Enter the RowsToGenerate.\nValue [50,150] but not 99",
            on_change=None,
            args=None,
            kwargs=None,
            disabled=False)

        #  Have the user input a float number from a widget.
        st.number_input(
            key="AFloatNumber",  # Linked to placed in S.AFloatNumber'].
            label="A float number",
            min_value=0.00,         # Always add a number after the point
            max_value=80000000.0,   # since the variable is a float.
            step=100.0,            # else streamlit throws an error.
            format="%f",            # Make this variable a float.
            help="Enter any number.\nValue 99 NOT permitted.",
            on_change=None)

        # Add checkboxes for selecting the lines to be shown on plot.
        st.checkbox(key="ShowLine3", label="Show the Line_3 in plot.")
        st.checkbox(key="ShowInput", label="Show The Variables I Input.")
        st.checkbox(key="ShowData", label="Show The Pandas Data Frame.")

    # End of 'with form'.

    return()  # End of function: GUI_Build_And_Show

def PlotNowButton_Click_Event():
    # Not used.
    # This function is Included to demonstrate that streamlit widgets have a
    # typical "callback" event option.
    return()  # End of function: PlotNowButton_Click_Event

def ConsoleClear():  # Clear all output in console.
    try:     # This works regardless of Operating System prevailing.
        from IPython import get_ipython
        get_ipython().magic("clear")
        get_ipython().magic("reset -f")
    except:
        pass
    return()  # End of function: Console_Clear

def Validate_Float(TextString):
    try:
        tempvar = float(TextString)
    except:
        return (0,False)
    else:
        return(tempvar,True)

def Validate_Integer(TextString):
    try:
        tempvar = int(TextString)
    except:
        return (0,False)
    else:
        return(tempvar,True)

def Msg_Set(TextString):
    FormattedText = TextString
    ErrStr = TextString[0:5].upper()
    if ErrStr == "ERROR":
        FormattedText = f"❌ There is an error in your input.    \n{FormattedText}   \nPlease correct and try again."
    S.MsgText = FormattedText
    G.Msg_Current = FormattedText
    return()

def Title_Build(TitleLength = "short"):
    G.Title_1 = str(
                   "Rows To Generate = {:d}   \r".format(G.RowsToGenerate)  +
                   "AFloatNumber = {:.5f}".format(G.AFloatNumber) + "."
                   )
    return(G.Title_1)   #  End of function: Title_Build

def StMarkdown(TextToBeFormated="", color="black",
    fontsize=14,bold=False,italic=False,fontname="Courier",align="left" ):
    # Set a particular font for display as html markdown text.
    weight = ""
    weightend = ""
    if bold:
        weight = "<strong>"
        weightend = "</strong>"
    if italic:
        weight = "<em>"
        weightend = "</em>"
    if bold and italic:
        weight = "<em><strong>"
        weightend = "</em></strong>"

    fs = str(fontsize).strip() + "px"
    md = " ".join(
                  ["<p",
                      "style='",
                              "font-family:", fontname, ";",
                              "color:", color, ";",
                              "font-size: ",  fs, ";",
                              "text-align: ",  align, ";",
                           "'"
                  ">",
                        weight + TextToBeFormated + weightend ,
                  "</p>"]
               )
    return(md)  # End of function: StMarkdown

def FullScreenIcon_Enlarge():
    # This function increases the visibility of the Streamlit
    # full page icon. It injects css code using markdown.
    css = """
         button[title="View fullscreen"]
         {background-color: #004170cc; left: 2; color: white; }

         button[title="View fullscreen"]:hover
         {background-color: #004170; color: white; } """

    st.markdown( "<style>" + css + "</styles>", unsafe_allow_html=True)
    return() # End of function: FullScreenIcon_Enlarge

MainLine()   # Start this program.


from django.urls import path

from rest_framework.routers import SimpleRouter

from . import views
from .api.api_views import CustomUserViewSet, PostViewSet

# Rotas geredas para api
router = SimpleRouter()
router.register('users', CustomUserViewSet)
router.register('posts', PostViewSet)

urlpatterns = [
    path('', views.IndexListView.as_view(), name='index'),
    path('user/cadastro/', views.UserCadastroCreateView.as_view(), name='user_new'),
    path('user/edit/<str:username>/<int:user_id>/', views.UserEditUpdateView.as_view(), name='user_edit'),

    path('post/new/', views.PostCreateView.as_view(), name='post_new'),
    path('post/<str:username>/<int:post_id>/', views.PostDetailView.as_view(), name='post_detail'),
    path('post/<str:username>/update/<int:post_id>/', views.PostUpdateView.as_view(), name='post_update'),
    path('post/<str:username>/delete/<int:post_id>/', views.PostDeleteView.as_view(), name='post_delete'),
    path('user/<str:username>/', views.user_perfil, name='user_perfil'),
]


import logging
from threading import Thread

class TaskResult(object):
    """
    A class for a task's result
    """
    def __init__(self):
        self.verdict = False
        self.result_value = None

class Task(object):
    """
    A class to represent a task
    """
    _thread: Thread
    result: TaskResult

    def __init__(self, name, func, args=None):
        """
        :param name: name of the task
        :param func: the method for executing the class
        :param args: any arguments needed to start the task
        """
        self.name = name
        self._thread = None
        self._func = func
        self._args = args
        self.running = True
        self.result = None

    def _task_execution(self):
        logging.info(f"{self.name} is now running")
        if self._args:
            self.result = self._func(*self._args)
        else:
            self.result = self._func()
        self.running = False
        logging.info(f"{self.name} is now done!")

    def start_task(self):
        """
        Start executing the task
        """
        logging.info(f"Starting task: {self.name}")
        self._thread = Thread(target=self._task_execution)
        self._thread.start()
        logging.info(f"Started task: {self.name}")


import socket
import threading
import inspect
import ctypes
import json
import time
from queue import Queue

class Send_data(threading.Thread):
    ip, port = "127.0.0.1", 25001
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    datas = Queue()
    data_is_convey = True

    def __init__(self, con):
        self.con = con
        self.server.bind((self.ip, self.port))
        self.server.listen(5)
        print("[*]成功创建线程!")
        super().__init__()

    def run(self):
        self.con.acquire()
        print("执行socket调用")
        client, addr = self.server.accept()  # 如果有客户端链接
        print("[*]成功建立连接于 %s:%d" % (addr[0], addr[1]))

        received_data = client.recv(1024).decode(
            "UTF-8")  # receiveing data in Byte fron C#, and converting it to String
        print(received_data)

        while not self.datas.empty() or self.data_is_convey:
            self.con.notify()
            self.con.wait()
            if not self.datas.empty():
                data_string = json.dumps(self.datas.get())
                client.send(data_string.encode("UTF-8"))

        client.send(json.dumps({"data_type": "string", "sign": "FINISH"}).encode("UTF-8"))
        client.shutdown(socket.SHUT_RDWR)
        client.close()
        print("通信结束")
        self.con.release()

    def data_save(self, data):
        self.datas.put(data)

    def data_finish(self):
        self.data_is_convey = False


#!/usr/bin/env python3

from collections import Counter
import urllib.request
from lxml import etree

import numpy as np

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import cross_val_score
from sklearn import model_selection

alphabet="abcdefghijklmnopqrstuvwxyzäö-"
alphabet_set = set(alphabet)

# Returns a list of Finnish words
def load_finnish():
    finnish_url="https://www.cs.helsinki.fi/u/jttoivon/dap/data/kotus-sanalista_v1/kotus-sanalista_v1.xml"
    filename="src/kotus-sanalista_v1.xml"
    load_from_net=False
    if load_from_net:
        with urllib.request.urlopen(finnish_url) as data:
            lines=[]
            for line in data:
                lines.append(line.decode('utf-8'))
        doc="".join(lines)
    else:
        with open(filename, "rb") as data:
            doc=data.read()
    tree = etree.XML(doc)
    s_elements = tree.xpath('/kotus-sanalista/st/s')
    return list(map(lambda s: s.text, s_elements))

def load_english():
    with open("src/words", encoding="utf-8") as data:
        lines=map(lambda s: s.rstrip(), data.readlines())
    return list(lines)

def get_features(a):
    cv = CountVectorizer(token_pattern='(?u)\\w|-', analyzer='char', vocabulary=alphabet_set)
    arr = cv.fit_transform(a).toarray() #From first column to last
    return np.roll(arr, -1, axis=1)

def contains_valid_chars(s):
    for c in s.lower():
        if c not in alphabet_set:
            return False
    return True

def get_features_and_labels():
    fi_words = load_finnish() #np.char.lower(load_finnish())
    en_words = list( filter( lambda x: x[0].islower(), load_english() ))

    fi_words = list(filter(lambda x: contains_valid_chars(x), fi_words))
    en_words = list(filter(lambda x: contains_valid_chars(x), en_words))

    feature = np.concatenate( (get_features(fi_words), get_features(en_words)) )
    label = np.concatenate( (np.zeros(len(fi_words)), np.ones(len(en_words))) )
    return feature, label

def word_classification():
    feature, label = get_features_and_labels()
    cross_val = model_selection.KFold(n_splits=5, shuffle=True, random_state=0)
    return cross_val_score(MultinomialNB(), X=feature, y=label, cv=cross_val)

def main():
    # L = ["-Achilles", "Achilles's", "Aconcagua", "Aconcagua's", "Acosta", "Acosta's", "Acropolis", "Acrux", "Acrux's", "Actaeon", "Actaeon's"]
    # print(get_features(L)) # PART 1
    # for s in L:
    #     print(contains_valid_chars(s)) # PART 2
    # f, t = get_features_and_labels() # PART 3
    # print(len(f))
    print("Accuracy scores are:", word_classification()) # PART 4

if __name__ == "__main__":
    main()


from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.utils import timezone
import json
import six

from accounts.tasks import send_email, mail_encoded_body, account_activation_token
from .models import Royalty

def get_verififcation_details(request, royalty, song):
    return {
        'domain': get_current_site(request),
        'artist': request.user,
        'song': song,
        'royalty': royalty
    }

def get_or_create_royalty(royalty_data):
    status = False
    try:
        royalty = Royalty.objects.get(
            username=royalty_data['email'])

        royalty.phone = royalty_data['phone']
        royalty.save()

    except Royalty.DoesNotExist:
        royalty = Royalty.objects.create(
            username=royalty_data['email'], phone=royalty_data['phone'])
        status = True

    return royalty, status

def get_or_create_royalties(request, royalties, song_title):
    royalty = None
    returned_royalties = []

    for r in royalties:

        royalty, created = get_or_create_royalty(royalty)
        returned_royalties.append(royalty)

        confirm_royalty_mail(get_verififcation_details(
            request, r, song_title))

    return returned_royalties

def confirm_royalty_mail(params):
    current_site = params['domain']

    royalty = params['royalty']
    email = royalty['email']
    artist = params['artist']
    song = params['song']

    mail_subject = 'Royalty from Gocreate'
    encode_details = {
        'pk': email,
        'song': str(song.id),
        'split_id': royalty['id'],
        'assignment_timestamp': str(timezone.now())
    }
    uid = urlsafe_base64_encode(force_bytes(json.dumps(encode_details)))
    token = account_activation_token.make_token(artist)

    message = render_to_string('royalty/royalty.html', {
        'title': mail_subject,
        'fullname': royalty['fullname'],
        "description": royalty['description'],
        'artist': artist,
        "share": royalty['share'],
        'song_title': song.title,
        'domain': current_site,
        'uid': uid,
        'token': token,
    })

    print("uid ", uid)
    print("token ", token)
    send_email(mail_subject, message, email)

def verify_royalty_email(uidb64, token):
    content = None
    try:
        decoded_content = force_str(urlsafe_base64_decode(uidb64))
        content = json.loads(decoded_content)

        try:
            user = Royalty.objects.get(username=content['pk'])
        except Royalty.DoesNotExsit:
            user = None

    except Exception as e:
        user = None

    return user, user is not None, content['split_id'] if content is not None else None


from collections import deque

def solution(priorities, location):
    answer = 0
    imp_max = max(priorities)
    priorities = deque(priorities)
    while 1:
        if len(priorities) == 0:
            break
        if priorities[0] < imp_max:
            if location == 0:
                priorities.append(priorities.popleft())
                location = len(priorities) - 1
            else:
                priorities.append(priorities.popleft())
                location -= 1
        if priorities[0] == imp_max:
            if location == 0:
                answer += 1
                return answer
            else:
                priorities.popleft()
                imp_max = max(priorities)
                location -= 1
                answer += 1

print(solution([2, 1, 3, 2], 2))
print(solution([1, 1, 9, 1, 1, 1], 0))


import requests
from bs4 import BeautifulSoup

#URL format
#https://remoteok.io/remote-dev+python-jobs

def extract_jobs(keyword):
    jobs_list = []
    url = f"https://remoteok.io/remote-dev+{keyword}-jobs"
    print(f"Scrapping remoteok")
    result = requests.get(url)
    soup = BeautifulSoup(result.text, "html.parser")
    results = soup.find("table", {"id": "jobsboard"}).find_all("tr", {"class": "job"})

    for result in results:
      job = extract_job_detail(result)
      #print(job)
      jobs_list.append(job)
    return jobs_list

def extract_job_detail(html):
    #print("start extracting details")
    title = html.find("td", {"class":"company position company_and_position"}).find("h2").string
    company = html.find("td", {"class":"company position company_and_position"}).find("h3").string
    link = html.find("td", {"class":"company position company_and_position"}).find("a", {"itemprop": "url"})["href"]

    return {
        'title': title,
        'company': company,
        'link': f"https://remoteok.io/{link}"
    }

def search_jobs(keyword):
  jobs_list = extract_jobs(keyword)
  return jobs_list


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import argparse
import os
import shutil
import subprocess
import sys
import sysconfig

from Cython.Distutils import build_ext
from pkg_resources import get_distribution
from setuptools import Extension
from setuptools import setup

CUDA_VERSION = subprocess.check_output(
    'nvcc -V | grep -oP "release\s([0-9\.]+)" | grep -oP "([0-9\.]+)"',
    shell=True).decode('utf-8').strip()

def create_extensions():
    sourcefiles = [
        'pynvvl/_nvvl.pyx',
    ]

    # List up include paths
    include_dirs = [
        os.path.join(os.getcwd(), 'docker/include'),
        '/usr/local/cuda/include',
        sysconfig.get_config_var('INCLUDEPY'),
    ]
    if 'CPATH' in os.environ:
        include_dirs.insert(1, os.environ['CPATH'])

    # List up library paths
    library_dirs = [
        os.path.join(os.getcwd(), 'docker/lib/cuda-{}'.format(CUDA_VERSION)),
    ]
    if 'LD_LIBRARY_PATH' in os.environ:
        library_dirs.append(os.environ['LD_LIBRARY_PATH'])
    if 'LIBRARY_PATH' in os.environ:
        library_dirs.append(os.environ['LIBRARY_PATH'])

    # List up libraries
    libraries = [
        'nvvl',
    ]

    # RPATH which will be set to pynvvl.so
    rpath = [
        '$ORIGIN/_lib',
    ]

    extensions = [
        Extension(
            'pynvvl._nvvl',
            sourcefiles,
            include_dirs=include_dirs,
            library_dirs=library_dirs,
            libraries=libraries,
            language='c++',
            extra_compile_args=['-std=c++11'],
            extra_link_args=['-std=c++11'],
            runtime_library_dirs=rpath,
        )
    ]
    return extensions

def prepare_package_data():
    wheel_libs = [
        'docker/lib/cuda-{}/libnvvl.so'.format(CUDA_VERSION),
        'docker/lib/cuda-{}/libavformat.so.57'.format(CUDA_VERSION),
        'docker/lib/cuda-{}/libavcodec.so.57'.format(CUDA_VERSION),
        'docker/lib/cuda-{}/libavutil.so.55'.format(CUDA_VERSION),
    ]
    lib_dir = 'pynvvl/_lib'
    if not os.path.exists(lib_dir):
        os.makedirs(lib_dir)
    libs = []
    for lib in wheel_libs:
        libname = os.path.basename(lib)
        libpath = os.path.join(lib_dir, libname)
        shutil.copy2(lib, libpath)
        libs.append(os.path.join('_lib', libname))

    package_data = {
        'pynvvl': libs
    }

    return package_data

parser = argparse.ArgumentParser()
parser.add_argument('--package-name', type=str, default='pynvvl')
args, sys.argv = parser.parse_known_args(sys.argv)

package_data = prepare_package_data()
extensions = create_extensions()

cupy_package_name = None
try:
    cupy_package_name = get_distribution(
        'cupy-cuda{}'.format(CUDA_VERSION.replace('.', '')))
    cupy_package_name = cupy_package_name.project_name
except Exception:
    cupy_package_name = 'cupy'

print('=' * 30)
print('CuPy Package Name:', cupy_package_name)
print('=' * 30)

description = \
    'PyNVVL: A Python wrapper for NVIDIA Video Loader (NVVL) with CuPy'

setup(
    name=args.package_name,
    url='https://github.com/mitmul/pynvvl',
    version='0.0.2a5',
    author='Shunta Saito',
    author_email='shunta.saito@gmail.com',
    description=description,
    long_description=open('README.md').read(),
    long_description_content_type='text/markdown',
    license='MIT License',
    packages=['pynvvl'],
    package_data=package_data,
    install_requires=[
        '{}>=4.0.0'.format(cupy_package_name),
    ],
    setup_requires=[
        'cython>=0.27.3',
    ],
    ext_modules=extensions,
    cmdclass={'build_ext': build_ext},
)


import imutils
from imutils.video import VideoStream
import time
import cv2

print("[INFO] starting video stream...")
vs = VideoStream(src=2).start()
time.sleep(2.0)
num = 1

while True:
    frame = vs.read()
    # show the output frame
    frame = cv2.flip(frame, 1)
    cv2.imshow("Frame", frame)
    key = cv2.waitKey(1) & 0xFF
    # if the `q` key was pressed, break from the loop
    if key == ord("q"):
        cv2.imwrite(f"calsLogitechCharuco2/Charcuo_cal_{num}.jpg", frame)
        num += 1


# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import

from django import template
from django.core.exceptions import ObjectDoesNotExist
from django.utils.safestring import mark_safe

register = template.Library()

@register.filter
def iconic(value):
    if isinstance(value, bool):
        if value:
            return mark_safe(''
                             ''
                             '')
        return mark_safe(''
                         ''
                         '')
    return value

@register.filter
def is_reviewer(user):
    """Checks if the user is a reviewer."""
    if user.is_superuser:
        return True
    if user.is_authenticated:
        try:
            _ = user.reviewer
        except ObjectDoesNotExist:
            return False
        return True
    return False


from typing import Callable, List

# ***** Get list with items divided by 3 but not divided by 6 using List Comprehension *****
# 10 -> [0, 3, 9]

c1 = [x for x in range(0, 20) if x % 3 == 0 and not (x // 6 > 0 and x % 6 == 0)]
# print(c1)

# Function implementation:
def dev_3_not_dev_6(number):
    return [
        x
        for x in range(0, number + 1)
        if x % 3 == 0 and not (x // 6 > 0 and x % 6 == 0)
    ]

# print(dev_3_not_dev_6(30))

# ***** Get list with items divided by 3 but not divided by 6 using filter() *****

f = filter(lambda x: x % 3 == 0 and not (x // 6 > 0 and x % 6 == 0), range(0, 11))
# print(list(f))

# Function implementation:
def dev_3_not_dev_6_filter(number):
    return list(
        filter(
            lambda x: x % 3 == 0 and not (x // 6 > 0 and x % 6 == 0),
            range(0, number + 1),
        )
    )

# print(dev_3_not_dev_6_filter(20))

# ***** Implement filter() using list comprehension *****

# filter() example
filter_mehod = filter(lambda x: x >= 5, range(3, 8))
# print(list(filter_mehod))

# List comprehension usage
filter_compr_method = [x for x in range(3, 8) if x >= 5]
# print(filter_compr_method)

# function implementation
def filter_comprehension(func: Callable, iterable: [List, range]) -> list:
    """
    Filter the list by condition from the function
    :param func: Function with condition to verify
    :param iterable: List of elements you want to check for condition
    :return: List of elements which satisfies the condition
    """
    return [x for x in iterable if func(x)]

res_f = filter_comprehension(lambda x: x >= 5, range(3, 8))
# print(res_f)

# ***** Implement map() using list comprehension *****

# map() example
map_method = map(lambda x: x % 3 == 0 and not (x // 6 > 0 and x % 6 == 0), range(0, 20))
# print(list(map_method))

# List comprehension usage
map_compr_method = [
    x % 3 == 0 and not (x // 6 > 0 and x % 6 == 0) for x in range(0, 11)
]
# print(map_compr_method)

# function implementation
def map_comprehension(func: Callable, iterable: [List, range]) -> list:
    """
    Apply function to each element in the list
    :param func: Function you want to apply
    :param iterable: List of elements you want to apply function on
    :return: List of the new elements processed by the function
    """
    return [func(x) for x in iterable]

res = map_comprehension(
    lambda x: x % 3 == 0 and not (x // 6 > 0 and x % 6 == 0), range(0, 11)
)
# print(res)

# ***** Implement enumerate() using list comprehension *****

# enumerate() example
grocery = ["bread", "milk", "butter"]
enumerate_res = enumerate(grocery)
# print(list(enumerate_res))

# Implementation with for loop
enumerate_for_res = []
pos = 0
for val in grocery:
    enumerate_for_res.append((pos, val))
    pos += 1

# List comprehension usage
enumerate_compr_res = [(grocery.index(val), val) for val in grocery]
# print(enumerate_compr_res)

# function implementation
def enumerate_comprehension(collection: [range, list], start: int = 0) -> list:
    """
    Enumerate list of elements
    :param collection: List of elements you want to enumerate
    :param start: The number from which enumeration should start, default 0
    :return: List of tuples with enumeration
    """
    return [(collection.index(x) + start, x) for x in collection]

# enumerate_func_res = enumerate_comprehension(grocery, 15)
enumerate_func_res = enumerate_comprehension(range(5), 15)
# print(enumerate_func_res)


# -*- coding: utf-8 -*-
import numpy as np
import io
import time

#CONSTANTS
H=0                 #Horitzontal
V=1                 #Vertical
#per accedir de manera més clara al array de paraules utilitzarem les següents variables:
X=0         #coord x
Y=1         #coord y
SIZE=2      #mida paraula
DIR=3       #orientacio paraula

class crossWord:
    count = 0
    #llegeix el fitxer que conté el crossword i guarda la informació en una matriu n x m (soluciona lectura de caracters \n, \t)
    def llegirTauler1(self, fileName):
        taulerArray=[]
        a=[]
        text_file = open(fileName, 'r')
        lines = text_file.read().split('\n')
        for index, i in enumerate(lines):
            taulerArray.append(i.split('\t'))
            a.append(i.split('\t'))
            for index2, casella in enumerate(taulerArray[index]):
                if(taulerArray[index][index2] == '#'):
                   taulerArray[index][index2] = int(-1)
                else:
                   taulerArray[index][index2] = int(0)

        if taulerArray[-1] == [0]:
            taulerArray.remove([0])

        tauler = np.asarray(taulerArray, dtype=int)
        a = np.asarray(a, dtype=str)
        return tauler, a

    def llegirTauler(self, fileName):
        taulerArray=self.tauler

        contParaula=1
        for fila,f in enumerate(taulerArray):

            col=0
            mida=0
            colIni= col #primera casella de cada fila

            while(col<taulerArray.shape[1]):                                                #comprovem que no hem arribat al final de la fila
                if(f[col] == -1):                                              #si ens trobem coixinet
                    if(mida > 1):                                               #si la paraula fins ara te mes duna lletra, l'afegim a la llista de paraules creant una nova instancia
                        self.paraules=np.append(self.paraules,[[fila,colIni,mida,H]], axis=0)
                        contParaula+=1
                        self.colisions.append([])
                    elif (mida == 1):
                        taulerArray[fila][col-1] = 0
                    colIni=col+1                                   #actualitzem novves coordenades i mida nova paraula
                    mida = 0
                else:
                    if(col+1>=taulerArray.shape[1]):
                        mida+=1                                       #no hi ha coixinet i hem arribat al final de la fila
                        if(mida > 1):                                           #tornem a comprovar si cumpleix amb els requisits de la mida
                            self.paraules=np.append(self.paraules,[[fila,colIni,mida,H]], axis=0)
                            self.colisions.append([])
                            mida=0
                            if(taulerArray[fila][col] == 0):                #Si equesta casella està buida, hi assignem la paraula actual
                                taulerArray[fila][col] = contParaula
                            contParaula+=1
                    else:
                        mida += 1                                               #passem a la seguent columna i actualitzem mida
                        if(taulerArray[fila][col] == 0):                #Si equesta casella està buida, hi assignem la paraula actual
                            taulerArray[fila][col] = contParaula
                col += 1

        for fila,f in enumerate(taulerArray.T):
            col=0
            mida=0
            colIni=col
             #primera casella de cada fila
            while(col<taulerArray.shape[0]):                                                #comprovem que no hem arribat al final de la fila
                if(f[col] == -1):                                              #si ens trobem coixinet                                        #comprovem que el coixinet no sigui la ultima casella
                    if(mida > 1):
                        self.paraules=np.append(self.paraules,[[colIni,fila,mida,V]], axis=0)
                        contParaula+=1
                        self.colisions.append([])
                    colIni=col+1
                    mida = 0
                else:
                    if(col+1>=taulerArray.shape[0]):

                        if (taulerArray[col][fila] == 0):  # Si aquesta casella està buida, hi assignem la paraula actual
                            taulerArray[col][fila] = contParaula
                        elif (f[col - 1] != -1): # (mida > 1) or ((mida <= 1) and (f[col - 1] == -1)):
                            self.colisions[contParaula].append((int(taulerArray[col][fila]), col - colIni, fila - self.paraules[int(taulerArray[col][fila])][Y]))  # Desem a la llista de colisions una tupla amb l'index de la paraula amb qui colisiona, la posició de la paraula en concret i la posicio de l'altre paraula
                            self.colisions[int(taulerArray[col][fila])].append(((contParaula), fila - self.paraules[int(taulerArray[col][fila])][Y], col - colIni))

                        mida+=1                                       # no hi ha coixinet i hem arribat al final de la fila
                        if(mida > 1):                                           # tornem a comprovar si cumpleix amb els requisits de la mida
                            self.paraules=np.append(self.paraules,[[colIni,fila,mida,V]], axis=0)
                            contParaula+=1
                            self.colisions.append([])
                            mida=0
                    else:
                        if (taulerArray[col][fila] == 0):  # Si aquesta casella està buida, hi assignem la paraula actual
                            taulerArray[col][fila] = contParaula
                        elif (mida >= 1) or ((col == 0) and (f[col+1] != -1)) or ((mida < 1) and ((f[col - 1] == -1) and (f[col+1] != -1))):
                            self.colisions[contParaula].append((int(taulerArray[col][fila]), col - colIni, fila - self.paraules[int(taulerArray[col][fila])][Y]))  # Desem a la llista de colisions una tupla amb l'index de la paraula amb qui colisiona i la posició
                            self.colisions[int(taulerArray[col][fila])].append(((contParaula), fila - self.paraules[int(taulerArray[col][fila])][Y], col - colIni))
                        mida += 1                                               # passem a la seguent columna i actualitzem mida

                col += 1

    def llegirDiccionari(self, fileName):
        llista = [linia.rstrip() for linia in io.open(fileName,'r',errors='replace')] # elimina les \n finals a cada paraula
        diccionari={}
        for paraula in llista:                                  # organitzem les paraules per longitud en un diccionari
            if len(paraula) in diccionari:
                diccionari[len(paraula)].append(list(paraula))
            else:
                diccionari[len(paraula)]=[list(paraula)]
        """if(fileName == 'diccionari_A.txt'):
            for i in diccionari:
                diccionari[i] = diccionari[i][::100, :]
        """
        return diccionari

    def checkColisio(self, head, paraula, LVA):
        colisionsCorrectes = 0
        for colisio in self.colisions[head]:
            if LVA is None:
                break
            #colisio[0] es el numero de la paraula amb la que colisiona
            if LVA[colisio[0]] is not None:   #Si hi ha colisio comprovar la lletra de les dues paraules
                lletraParaula1 = paraula[colisio[1]]
                paraula2 = LVA[colisio[0]]
                colisioParaula2 = colisio[2]
                lletraParaula2 = paraula2[colisioParaula2]
                if lletraParaula1 == lletraParaula2:
                    colisionsCorrectes += 1
                else:
                    return False
            else:
                colisionsCorrectes += 1
        if colisionsCorrectes == len(self.colisions[head]):
            return True
        return False

    def backtracking(self, LVA, LVNA):
        if None not in LVA:
            return LVA
        else:
            head = LVNA[0]
            for paraula in self.diccionari[self.paraules[head][SIZE]]:  #iterem només a les paraules del diccionari que tenen la mateixa mida que la variable que volem omplir
                if self.checkColisio(head, paraula, LVA):
                    LVA[head] = paraula
                    resultat = self.backtracking(LVA, LVNA[1:])
                    if LVA is None:
                        pass
                    elif None not in LVA:
                        return resultat

        return None

    def updateDomain(self, head, paraula, D):
        for colisio in self.colisions[head]:
            D[colisio[0]] = D[colisio[0]][D[colisio[0]][:, colisio[2]] == paraula[colisio[1]], :]       #D[k] = D[k][D[k][:, c] == 'A', :]
        return D

    def backtrackingFC(self, LVA, LVNA, D):
        if all(v is not None for v in LVA):
            return LVA
        else:
            head = LVNA[0]
            if D[head].size != 0:
                for paraula in D[head]:
                    if self.checkColisio(head, paraula, LVA):
                        LVA[head] = paraula
                        DPrev = D[:]
                        D = self.updateDomain(head, paraula, D)
                        resultat = self.backtrackingFC(LVA, LVNA[1:], D)
                        D=DPrev[:]
                        if LVA is None:
                            pass
                        elif (all(v is not None for v in LVA)):
                            return resultat

        return None

    def generaDomain(self):
        D = []
        D.append(np.zeros((1,1), dtype= str))
        for paraula in self.paraules[1:]:
            D.append(np.asarray(self.diccionari[paraula[SIZE]]))
        return D

    def calcula(self, algorisme):

        b = np.zeros((self.paraules.shape[0], self.paraules.shape[1] + 1), dtype= int)
        b[:, :-1] = self.paraules
        b[:,4] = np.arange(0,self.paraules.shape[0])
        b = np.flip(sorted(b, key=lambda a_entry: a_entry[2]), axis=0)[:-1]

        LVNA = b[:,4]
        D = self.generaDomain()

        lva = [None] * (self.paraules.shape[0])
        lva[0] = "empty"
        if algorisme:
            lva = self.backtracking(lva, LVNA)
        else:
            lva = self.backtrackingFC(lva, LVNA, D)

        for index, paraula in enumerate(lva[1:]):

            if self.paraules[index][DIR]==H:
                x = self.paraules[index+1][X]
                y = self.paraules[index+1][Y]
                for lletra in paraula:
                    self.taulerResultats[x][y] = lletra
                    y+=1
            elif self.paraules[index][DIR]==V:
                x = self.paraules[index+1][X]
                y = self.paraules[index+1][Y]
                for lletra in paraula:
                    self.taulerResultats[x][y] = lletra
                    x+=1
        print("\nSOLUCIÓ GUARDADA EN crossword_Resolt.txt \n")
        np.savetxt('crossword_Resolt.txt', self.taulerResultats, delimiter='\t', fmt='%s') #escriu el resultat a un fitxer

    def __init__(self, dic, tauler):
        self.paraules = np.zeros((1,4), dtype=int)
        self.colisions = [[],[]]
        self.diccionari = self.llegirDiccionari(dic)
        self.tauler, self.taulerResultats = self.llegirTauler1(tauler)
        self.llegirTauler(tauler)

def main():
    solucio = crossWord('diccionari_CB.txt','crossword_CB.txt')

    print("Resolució mitjançant BackTracking (1) o ForwardChecking (0) ?")
    alg = input()
    while (alg != '1') and (alg != '0'):
        print("Tria una opció correcta: ")
        alg=input()

    if alg == 1:
        msg = "BackTracking"
    else:
        msg = "ForwardChecking"

    start_time = time.time()
    solucio.calcula(alg)
    print(solucio.taulerResultats)
    print("")
    print("Temps transcorregut en segons utilitzant " + msg + ": ")
    print(time.time() - start_time)

if __name__ == "__main__":
    main()


import urllib.request, urllib.parse, urllib.error
import json

# http://py4e-data.dr-chuck.net/comments_42.json
# http://py4e-data.dr-chuck.net/comments_458724.json

address = input("Enter webite: ")
uh = urllib.request.urlopen(address)
data = uh.read().decode()
print("Retrieved", len(data), 'characters')

js = json.loads(data)
#print(data)

counter = 0
for item in js["comments"]:
    #print(item["count"])
    counter = counter +int(item["count"])

print(counter)


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wx
from misc import MyException

class SimpleGrid(wx.FlexGridSizer):

	def __init__(self, parent, entries, rowlabels=None, collabels=None, colors=None):
		numRows = len(entries)
		if rowlabels is None:
			haveRowLabels = 0
		else:
			haveRowLabels = 1
			if not len(rowlabels) == numRows:
				raise MyException('Number of row labels ({0:d}) must match number of rows ({1:d}).'.format(len(rowlabels), numRows), 3)
		numCols = len(entries[0])
		if collabels is None:
			haveColLabels = 0
		else:
			haveColLabels = 1
			if not len(collabels) == numCols:
				raise MyException('Number of column labels ({0:d}) must match number of columns ({1:d}).'.format(len(collabels), numCols), 3)

		self.border = 5

		wx.FlexGridSizer.__init__(self, numRows + haveColLabels, numCols + haveRowLabels, self.border, self.border)

		firstColAlign = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT
		otherColAlign = wx.EXPAND

		# if we have row and column labels, we need an empty element in top left corner
		if (rowlabels is not None) and (collabels is not None):
			self.Add(wx.StaticText(parent, label=''), 0, firstColAlign, self.border)
		# if we have column labels, print a row of column labels
		if collabels is not None:
			for l in collabels:
				self.Add(wx.StaticText(parent, label=l), 0, otherColAlign, self.border)
		for i in range(numRows):
			# if we have row labels, print label of current row first
			if rowlabels is not None:
				self.Add(wx.StaticText(parent, label=rowlabels[i]), 0, firstColAlign, self.border)
			# print entries itself
			for j in range(numCols):
				entry = wx.TextCtrl(parent, -1, entries[i][j], style=wx.TE_READONLY)
				if colors is not None:
					if colors[i][j] is not None:
						entry.SetBackgroundColour(colors[i][j])
				self.Add(entry, 0, otherColAlign, self.border)

		# make all columns growable (except first one if we have row labels)
		for i in range(haveRowLabels, haveRowLabels + numCols):
			self.AddGrowableCol(i)