Linux: Ubuntu 24: Stały adres IP

2024-09-09

W Ubuntu 24 do konfiguracji sieci nie używa się Network Managera, tylko NetPlan https://netplan.io/

Konfiguracja znajduje sie w plikach yaml w /etc/netplan

Najprawdopodobniej po instalacji znajdziesz w tym katalogu jakiś plik konfiguracyjny. U mnie był to 50-cloud-init.yaml

Domyślnie w tym pliku znajduje się zapis:

network:
    ethernets:
        eth0:
            dhcp4: true
    version: 2

co oznacza, że adres IP i ustawienia sieciowe dla interfejsu sieciowego mają być pobierane z DHCP

Jeśli chcesz mieć stały adres IP, zmień zawartość pliku np. na:

network:
    ethernets:
        eth0:
            dhcp4: no
            addresses:
              - 192.168.100.100/24
            gateway4: 192.168.100.1
            nameservers:
              addresses:
                - 8.8.8.8
    version: 2

Jeśli serwer korzysta z cloud-init, to zgodnie z instrukcją należy jeszcze wyłączyć automatyczą konfiguracje sieci, co robi się umieszczając w pliku /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

network: {config: disabled}

Potem pozostaje jeszcze zaaplikować zmiany:

sudo netplan apply
By Rafał Kraik in Linuxy

PowerShell: Uruchomienie programu „jako administrator”

2024-09-06

Czasami możesz chcieć uruchomić jakiś program z poziomu linii komend „Jako administrator”. Da się to zrobić za pomocą powershellowej komendy Start-Process, która ma parametr -verb. Jeśli przekażesz wartość parameteru „RunAs” to uruchamiany proces będzie działał „jako administrator”. Oto i przykład polecenia uruchamianego w linii komend, która już wcześniej została uruchomiona jako administrator:

pwsh -command "start-process pwsh -verb runas"

Jeśli chcesz się przekonać, czy rzeczywiście jesteś teraz administratorem użyj:

$user = [Security.Principal.WindowsIdentity]::GetCurrent();
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)

By Rafał Kraik in Power Shell

Linux: Instalacja serwera SSH

2024-08-09

Podczas instalacji serwera Linux Ubuntu można zdecydować się nie zainstalować serwera Open SSH. Jak go doinstalować później?

Zaczynamy od instalacji pakietu

sudo apt-get update
sudo apt-get upgrade
sudo apt-get intall openssh-client
sudo apt-get install openssh-server

Potem włączamy usługę i konfigurujemy ją do startu. Warto też sprawdzić status usługi, żeby sie upewnić, że wszystko działa, jak trzeba:

sudo systemctl enable ssh
sudo ufw allow ssh
sudo systemctl start ssh
sudo systemctl status ssh

I już można zacząć korzystać z ssh:

ssh username@server.address

A gdyby tak chcieć usunąć serwer SSH:

sudo systemctl stopssh
sudosystemctl disable ssh
sudo apt-get remove openssh-server
sudo ufw delete allow ssh
By Rafał Kraik in Linuxy

Helpdesk: Wolne menu kontekstowe

2024-08-04

Fajnie by było gdyby stare komputery pracowały z taką prędkością jak wtedy, gdy były nowe. Zresztą, to powinno być całkiem wykonywalne, bo przecież to nie jest tak, że starszy komputer rdzewieje i przez to robi się wolny. Spowolnienie wynika często z tego, że w swojej historii na komputerze było instalowane mnóstwo oprogramowania, które zostawiło po sobie ślady. Jednym z takich śladów mogą być niewykorzystywane pozycje w menu pod prawym przyciskiem myszy. Takie rozbudowane menu spowalnia reakcję komputera na kliknięcie prawym przyciskiem myszy.

To w jaki sposób usunąć takie niepotrzebne pozycje? Trzeba będzie zrobić to z pozycji edytora rejestru. Wystarczy uruchomić regedit i usunąć wpisy z następujących gałęzi:

HKEY_CLASSES_ROOT\*\shell
HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers
HKEY_CLASSES_ROOT\AllFileSystemObjects\ShellEx

HKEY_CLASSES_ROOT\Drive\shell 
HKEY_CLASSES_ROOT\Drive\shellex\ContextMenuHandlers 
HKEY_CLASSES_ROOT\Folder\shell 
HKEY_CLASSES_ROOT\Folder\shellex\ContextMenuHandlers 

By Rafał Kraik in Helpdesk

Terraform – przekazywanie wartości JSON

2024-07-14

Niektóre zasoby w Terraform wymagają przekazywania parametru w formacie JSON. Tak jest np. dla azurerm_virtual_machine_extension i dla właściwości settings (azurerm_virtual_machine_extension | Resources | hashicorp/azurerm | Terraform | Terraform Registry):

resource "azurerm_virtual_machine_extension" "example" {
  name                 = "hostname"
  virtual_machine_id   = azurerm_virtual_machine.example.id
  publisher            = "Microsoft.Azure.Extensions"
  type                 = "CustomScript"
  type_handler_version = "2.0"

  settings = <<SETTINGS
 {
  "commandToExecute": "hostname && uptime"
 }
SETTINGS
}

Pojawia sie tutaj tzw. heredoc SETTINGS. Jest to po prostu metoda na „wstrzyknięcie” do skryptu poprawnie sformatowanego jako JSON tekstu.

Na upartego można to zrobić inaczej – settings można by opisać tak:

  settings = jsonencode({
    "commandToExecute": "hostname && uptime"
  })

A jeśli masz alergię również na jsonencode, to da się też tak:

 settings = "{ \"commandToExecute\": \"hostname && uptime\"}"
 

No i tak na oko: wydaje się, że heredoc jest dosyć zgrabne. Nie ma potrzeby wywoływania funkcji, liczenia nawiasów, albo co gorsza cytowania każdego cudzysłowa, czy znaku nowej linii.

By Rafał Kraik in Azure

Python: TOP 10 skorelowanych kolumn

2024-07-07

W analizie danych zależy nam na wykryciu ukrytych relacji między różnymi cechami danych. Pomocne są w tym wykresy w rodzaju „heat-map” i wszystko ładnie, póki dane, które przetwarzamy są w miarę małe. A co jeśli mamy, dajmy na to 100 kolumn? Oczywiście znajdowanie najbardziej skorelowanych danych i wybieranie tych najbardziej skorelowanych da się zautomatyzować. Zobaczymy taki przykład:

import pandas as pd
import numpy as np
# Create a sample DataFrame (replace with your actual data)
shape = (50, 100) # 50 rows, 100 columns
data = np.random.normal(size=shape)
data[:, 10] += data[:, 20]
# Introduce some correlation
df = pd.DataFrame(data)

Ten przykładowy zestaw danych ma 50 wierszy i 100 kolumn. Część kolumn została ze sobą sztucznie skorelowana. W następnym kroku możemy wyznaczyć macierz korelacji:

# Calculate the correlation matrix
correlation_matrix = df.corr().abs()

Ta macierz ma już 100 wierszy i 100 kolumn. Trudno by było jednak wyszukiwać maksymalnej wartości w tablicy 100×100. Łatwiej będziem jeśli wszystkie wartości umieścimy w jednej kolumnie

Pobawmy się tą tablicą korelacji, nim zbudujemy finalne rozwiazanie. Pozwoli to nam zrozumieć, co tutaj pod spodem się dzieje. To polecenie zamieni tablicę 100×100 na tablicę z indeksem, jedną kolumną i 10000 wierszami.

correlation_matrix.unstack()

Ten obiekt ma też ciekawy indeks, tzw. multiindeks:

correlation_matrix.unstack().index

Wygląda on mniej więcej tak:

MultiIndex([( 0,  0),
            ( 0,  1),
            ( 0,  2),
            ( 0,  3),
            ( 0,  4),
            ( 0,  5),
            ( 0,  6),
            ( 0,  7),
            ( 0,  8),
            ( 0,  9),
            ...
            (99, 90),
            (99, 91),
            (99, 92),
            (99, 93),
            (99, 94),
            (99, 95),
            (99, 96),
            (99, 97),
            (99, 98),
            (99, 99)],
           length=10000)

Każdy wiersz tej dłuuugiej listy jest adresowany dwiema wartościami, które odpowiadają numerowi wiersza i numerowi kolumny z oryginalnego data frame, od którego wystartowaliśmy.

Nas interesują najbardziej skorelowane kolumny, dlatego posortujemy dane w oparciu o wartości, pewnie wolelibyśmy też widzieć największe wartości na początku:

correlation_matrix.unstack().sort_values(kind="quicksort", ascending=False)

Wynik wygląda mniej więcej tak:

46  46    1.000000
99  99    1.000000
0   0     1.000000
45  45    1.000000
26  26    1.000000
            ...   
81  95    0.000093
21  75    0.000010
75  21    0.000010
19  70    0.000001
70  19    0.000001
Length: 10000, dtype: float64

Jak widać największa korelacja pojawia się między kolumną a nią samą… w wyjściowej matrycy korelacji te wartości znajdowały się na przekątnej. Mają one numer wiersza i kolumny taki sam. Trzeba by je wykluczyć. Na dodatek, matryca korelacji wykazuje taką samą wartość dla kolumn 3 i 13 oraz 13 i 3. Dlatego możnaby wyrzucić z danych jakie będziemy analizować te wartości, które znajdowałyby się na przekątnej lub są wartościami zdublowanymi:

m = correlation_matrix.unstack()
first = m[m.index.get_level_values(0) < m.index.get_level_values(1)]

No to teraz już będzie z górki. Wystarczy posortować dane, tak jak robiliśmy to wcześniej i wybrać tych dajmy na to 10 „naj”:

first.sort_values(kind=”quicksort”, ascending=False).head(10)

Oto wynik:

10  20    0.839781
13  36    0.485660
40  52    0.481521
11  77    0.479348
26  66    0.474195
69  93    0.471580
20  26    0.462138
53  72    0.456067
47  94    0.444600
8   74    0.443435
dtype: float64
By Rafał Kraik in SQL

Python: Pandas: melt na kolumnie z multi-indeksem

2024-07-02

Załóżmy, że dotarły do nas dane w takiej oto postaci:

Mamy więc „sztuczny” indeks wierszy 'MF’ o wartościach 0,1,2,3,4 oraz kolumny, które są opisane muli-indeksem.

  • piersza kolumna to („Age”,), bo jakakolwiek nazwa pojawia się tylko w zerowym poziomie nagłówka.
  • druga kolumna to („HalfSeconds”,”F”),
  • trzecia to („HalfSeconds”,”M”),
  • czwarta to („TotalSeconds”,”F”)
  • i ostatnia to („TotalSeconds”,”M”).

Chcielibyśmy taką pivot-table czyli tabelę przestawną „odpivotować” i zobaczyć ją w tzw. długim formacie:

Jeśli chcesz samodzilnie sobie takie dane wyczarować to użyj poniższego kodu:

import pandas as pd
import numpy as np
from datetime import datetime
from datetime import timedelta
import time

df = pd.read_csv('./marathon_results_2016.csv',
index_col='Bib',
usecols=['Bib','40K','Half','Pace','Age','M/F',
'Country','State','City'])

df['40K'] = df['40K'].apply(pd.to_timedelta, errors='coerce')
df['Half'] = df['Half'].apply(pd.to_timedelta, errors='coerce')
df = df[df['40K'].notna() & df['Half'].notna()]
df['TotalSeconds'] = df['40K'].apply(lambda x: timedelta.total_seconds(x))
df['HalfSeconds'] = df['Half'].apply(lambda x: timedelta.total_seconds(x))

df = df.pivot_table(index="Age",columns="M/F",values="TotalSeconds")

df.reset_index(inplace=True)
df.head()

Plik zdanymi można pobrać stąd

W wersji Pandasa 2.2.0 dało się bez problemu uruchomić polecenie:

df.melt(id_vars="Age", value_name='Time')

Niestety, coś tam chłopaki namieszali: https://github.com/pandas-dev/pandas/issues/57663 i komenda kończy się błędem:

KeyError: „The following id_vars or value_vars are not present in the DataFrame: [’Age’]”


Wprawdzie w wersji 2.2.2 problem miał być rzekomo usunięty, ale u mnie nadal występuje. Ponieważ ostatnie czego bym chciał, to uzależniać działanie od tego w jakiej wersji bibliotek ten program jest uruchamiany, a może jeszcze nakłaniać do korzystania ze starych bibliotek, bo na nowych coś nie działa, to proponuję przekształcenie danych. Zobacz jakie:

Błąd KeyError poniekad ma rację. W kolumnie widocznej jako Age, kluczem jest („Age”,) i jakby nie patrzeć nie jest to po prostu napis „Age”. Może wobec tego by tak przed „odpiwotowaniem” spłaszczyć ten multiindex? No właśnie, da się to zrobić!

Jest sobie sprytna metoda to_flat_index, powoduje, że MultiIndex zostanie zamieniony na Index. Pozycjami nadal są tuple, ale przynajmniej pozbyliśmy się tego „Multi”:


Ale to jest ciągle coś dziwnego! Chcielibyśmy w kolumnach widzieć po prostu napisy. Da się to zrobić!

W następnym kroku można użyć str i wyciągnąć z tego obiektu wartości zrzutowane na string i połączyć je ze sobą pustym napisem. Oto, co dostaniemy patrząc tylko na wynik:

O rety! Mamy po prostu napisy! Tak, to jest to, czego nam było trzeba. Dlatego do osiągnięcia pożądanej formy „odpivotowanej” tabeli można teraz użyć kodu:

df.columns = df.columns.to_flat_index().str.join(”)
df.melt(id_vars=”Age”, value_name=’Time’).head()

No i proszę – trochę na piechotę, ale przynajmniej bez dodawania w instrukcji informacji „upewnij się, że pracujesz ze starą wersją Pandasa”.

By Rafał Kraik in Python