def alg():
    start = 0
    koniec = start
    rozmiar_macierzy_wag = 30
    rozmiar_populacji = 30
    liczba_iteracji = 1000
    liczba_par = 9
    liczba_najlepszych_rozwiazan = 2
    prawdopodobienstwo_mutacji = 0.05
    liczba_grup = 1

    macierz = macierz_wag(rozmiar_macierzy_wag)
    populacja = populacja_startowa(rozmiar_populacji, macierz, start, koniec)
    ostatnia_odl = 10000000
    najlepsze_wyniki = []

    for i in range(liczba_iteracji):
        nowa_populacja = []

        # drogi bieżącej populacji
        wyniki = wynik_populacji(populacja, macierz)
        najlepszy = populacja[np.argmin(wyniki)]  # najkrotsza droga
        liczba_ruchow = len(najlepszy)
        odleglosc = zmierz_dlugosc(najlepszy, macierz)

        if odleglosc != ostatnia_odl:
            print('Iteracja %i: droga wynosi %f' % (i, odleglosc))

        # rozmnażanie się członków na podstawanie wyników podobieństwa/metoda ruletki
        for j in range(liczba_par):
            nowy_1 = krzyzowanie(list(populacja[znajdz_kolege(wyniki)]),
                                 list(populacja[znajdz_kolege(wyniki)]))
            nowa_populacja = nowa_populacja + [nowy_1]

        # mutacja
        for j in range(len(nowa_populacja)):
            nowa_populacja[j] = np.copy(
                mutacja(nowa_populacja[j], prawdopodobienstwo_mutacji,
                        macierz))

        # zatrzymanie członków starej populacjiw w nowej
        nowa_populacja += [populacja[np.argmin(wyniki)]]
        for j in range(1, liczba_najlepszych_rozwiazan):
            przechowawca = znajdz_kolege(wyniki)
            nowa_populacja += [populacja[przechowawca]]

        # uzupełnienianie populacji randmowymi członkami
        while len(nowa_populacja) < rozmiar_populacji:
            nowa_populacja += [nowy_osobnik(macierz, start, koniec)]

        populacja = copy.deepcopy(nowa_populacja)
        ostatnia_odl = odleglosc
        najlepsze_wyniki.append([i, odleglosc])
def hooke_jeeves(f, x1, x2, step=0.1):

    first_x1 = x1
    first_x2 = x2
    best_x1 = False
    best_x2 = False

    while best_x1 == False:
        test_x1 = np.array([[x1, x2], [x1 + step, x2], [x1 - step, x2]])

        if np.argmin([
                f(test_x1[0][0], test_x1[0][1]),
                f(test_x1[1][0], test_x1[0][1]),
                f(test_x1[2][0], test_x1[0][1])
        ]) == 1:
            x1 += step
        elif np.argmin([
                f(test_x1[0][0], test_x1[0][1]),
                f(test_x1[1][0], test_x1[0][1]),
                f(test_x1[2][0], test_x1[0][1])
        ]) == 2:
            x1 -= step
        else:
            best_x1 = True

    while best_x2 == False:
        test_x2 = np.array([[x1, x2], [x1, x2 + step], [x1, x2 - step]])

        if np.argmin([
                f(test_x2[0][0], test_x2[0][1]),
                f(test_x2[0][0], test_x2[1][1]),
                f(test_x2[0][0], test_x2[2][1])
        ]) == 1:
            x2 += step
        elif np.argmin([
                f(test_x2[0][0], test_x2[0][1]),
                f(test_x2[0][0], test_x2[1][1]),
                f(test_x2[0][0], test_x2[2][1])
        ]) == 2:
            x2 -= step
        else:
            best_x2 = True

    Difference = np.subtract([first_x1, first_x2], [x1, x2])

    print("Original x1,x2:", first_x1, first_x2, "\n", "Improved x1,x2:", x1,
          x2, "\n", "Difference:", Difference)
def return_low_value(f, x1, x2, step=0.1):

    found_center = False
    while found_center == False:
        test_points = np.array([[x1, x2], [x1 + step, x2], [x1 - step, x2],
                                [x1, x2 + step], [x1, x2 - step]])
        results = []
        for i in test_points:
            results.append(f(i[0], i[1]))

        x1 = test_points[np.argmin(results)][0]
        x2 = test_points[np.argmin(results)][1]

        if np.argmin(results) == 0:
            found_center = True

    return test_points[np.argmin(results)]
def brute_global_min(f, a, b):

    sections = np.linspace(a, b, 50)
    results = []
    for i in sections:
        results.append(f(i))

    start_value = sections[np.argmin(results)]

    min_interval = find_minimum_interval(f, x=start_value)

    return slope_min(f, min_interval[0], min_interval[1])
s.loc[] # indexing with string label
s[0:5] # select first 5 rows. This works even if you have a custom index 

#------------------ ORGANIZE / SORT -----------------#
Series.reindex(index=None) 
# index = New labels / index to conform to. Preferably an Index object to avoid duplicating data

Series.sort_index() 


pd.concat() # for combining a series to a dataframe, 
			# or concatinating multiple dataframes on to each other
bank_stocks = pd.concat(objs=[bac, c, gs], axis=1, keys=['BAC', 'C', 'GS'])

#---- minimum  / maximum
pd.argmin() # index of the minimum value
pd.argmax() # index of the maximum value 

#---- count the unique values
pd.value_counts(normalize=False,sort=True,ascending=False,bins=None,dropna=True) # Returns object containing counts of unique values.

Series.nunique() # counts number of unique values in a series 

#---- Unique values 
Series.unique() # Return np.ndarray of unique values in the object. 

#---- Rename a series
s.rename("different", inplace=True) # scalar, changes Series.name
s.rename(lambda x: x ** 2)  # function, changes labels (indeces)
s.rename({1: 3, 2: 5})  # mapping, changes labels (indeces)