[PYTHON] Jupyter Notebook unerlässlich für die Softwareentwicklung

Hallo. Ich bin ein Softwareentwickler, der verschiedene Dinge wie Einbetten, Spiele, Web-Apps, iOS-Apps und Beschilderungssteuerungssysteme herstellt. Vor ungefähr zweieinhalb Jahren dachte ich als universelle Skriptsprache, dass es in Python geschrieben werden sollte, dass es schwierig ist, nur mit der Shell zu realisieren, und ich versuchte, Python zu lernen, während ich litt. Ich benutze es nur gelegentlich, deshalb vergesse ich jedes Mal, wie man if- und for-Schleifen schreibt.

Vor ungefähr anderthalb Jahren erfuhr ich jedoch, dass es in einem Buch über maschinelles Lernen und Datenwissenschaft eine REPL namens Jupyter Notebook gibt, und als ich versuchte, sie durch Ausprobieren zu verwenden, war sie nicht auf maschinelles Lernen und Datenwissenschaft beschränkt. Ich fand, dass es für alle Aufgaben geeignet ist, die tägliches Ausprobieren erfordern, und ich schreibe diesen Artikel, um ihn zu verbreiten.

Jupyter Notebook hat ein starkes Bild der Datenanalyse.

Sie benötigen jedoch keine Echtzeitmerkmale wie das Senden eines Pakets, die Verwendung als Taschenrechner für komplizierte Aufgaben, das Konvertieren verschiedener Dateiformate, das Kopieren komplizierter Dateien usw. Sie dürfen dies nur einmal tun. Es ist sehr gut geeignet, um verschiedene Dinge zu tun, wie es sein mag, aber es kann mehr als eine Zeit geben. Sie können ein Skript schreiben, indem Sie es Satz für Satz versuchen und prüfen, ob das Ergebnis wie erwartet oder falsch ist, wie z. B. die Schrittausführung, sodass Sie schnell und mit hoher Zuverlässigkeit Code schreiben können.

Wenn Sie ein Programm in einer dynamischen Sprache schreiben, gibt es einen Nachteil, dass Sie dazu neigen, Code in einem Zustand zu schreiben, in dem die Vervollständigung nicht so gut funktioniert, aber im Fall von Jupyter Notebook, während Sie die materialisierte Instanz direkt untersuchen Da Sie Methoden und Felder vervollständigen können, funktioniert die Vervollständigung ebenso wie statische Typsprachen, und Sie können viel Zeit sparen, um die Referenz zu lesen.

Diesmal,

Ich werde die vier Genres von erklären.

Fall für die Analyse verwendet

Bei der Erstellung von Software gibt es einige Situationen, in denen Sie eine Verhaltensanalyse auf einer Skala durchführen müssen, die von einem Debugger nicht verfolgt werden kann, oder wenn Sie Nachforschungen anstellen müssen, die mit vorhandenen Tools nicht durchgeführt werden können. Geräte, die von TCP oder UDP gesteuert werden können sollen, werden manchmal gebeten, dies zu untersuchen, da sie nicht gesteuert werden können, oder ich möchte beiläufig überprüfen, welchen Wert die Sensordaten zurückgeben, ohne die Spezifikationen zu berücksichtigen. Einige Zeichen können in einer bestimmten Schriftart angezeigt werden, andere nicht. Daher wurde ich gebeten, den Zeichenbereich festzulegen, der im System verwendet werden kann.

Grundsätzlich müssen Sie das Protokoll analysieren oder die Metadaten lesen und etwas dagegen tun, aber mit Jupyter ist es bequem, mit der Ad-hoc-Überprüfung fortzufahren.

Analyse der von Wireshark erfassten Pakete

Wir erhielten eine Anfrage zur Untersuchung des Problems, dass das von TCP / UDP gesteuerte Gerät manchmal nicht gesteuert werden konnte, und untersuchten, ob die Ursache auf der Seite der Steuerungssoftware, des Netzwerks oder der Geräteseite lag. Ich musste etwas tun. Vorläufig dachte ich, dass es möglich sein würde, etwas zu tun, indem man sich die Kommunikation ansieht. Deshalb bat ich ihn, einen Switch-Hub vorzubereiten, der Port-Spiegelung ermöglicht, und mit tshark, einem Befehlszeilen-Tool von Wireshark, täglich Pakete mit mehreren GB-Levels zu sammeln. Konvertieren Sie die erhaltene Erfassungsdatei und die .pcap-Datei mit dem folgenden Code in Pandas DataFrame.

def makeDfFromPcap(filename):
    p = dpkt.pcapng.Reader(open(filename, 'rb'))

    dDict = {'t':[], 'src':[], 'dst':[], 'type':[], 'srcport':[], 'dstport':[], 'length':[]}
    count = 0
    for ti,buf in p:
        try:
            eth = dpkt.ethernet.Ethernet(buf)
        except dpkt.NeedData:
            pass
        if type(eth.data) == dpkt.ip.IP:
            ip = eth.data
            src = ip.src
            dst = ip.dst
            src_a = socket.inet_ntoa(src)
            dst_a = socket.inet_ntoa(dst)
            t = 'IP'
            srcPort = 0
            dstPort = 0
            if type(ip.data) == dpkt.udp.UDP:
                srcPort = ip.data.sport
                dstPort = ip.data.dport
                t = 'UDP'
            elif type(ip.data) == dpkt.tcp.TCP:
                srcPort = ip.data.sport
                dstPort = ip.data.dport
                t = 'TCP'
            dDict['t'].append(ti)
            dDict['src'].append(src_a)
            dDict['dst'].append(dst_a)
            dDict['type'].append(t)
            dDict['srcport'].append(srcPort)
            dDict['dstport'].append(dstPort)
            dDict['length'].append(ip.len)
            count += 1
            if count % 10000 == 0:
                print(count)

    df = pd.DataFrame(dDict, columns=['t','src','dst','type','srcport','dstport','length'])
    
    return df
df = makeDfFromPcap('cap_00001_20191216.pcap')
df
スクリーンショット 2019-12-18 10.55.24.png

Danach können Sie überprüfen, wie viel Kommunikation zwischen der Quell-IP-Adresse und der Ziel-IP-Adresse stattfindet, indem Sie mit DataFrame gruppieren und summieren.

pd.DataFrame(df.groupby(['src','dst'])['length'].sum().sort_values(ascending=False) * 8 / (df.t.max() - df.t.min()))
#Band benutzt(Einheit: bps)
スクリーンショット 2019-12-18 10.56.49.png
pd.DataFrame(df.groupby(['src','dst']).size().sort_values(ascending=False) / (df.t.max() - df.t.min()))
#Anzahl der Pakete pro Zeiteinheit(Einheit: tps)
スクリーンショット 2019-12-18 10.56.58.png

In diesem Fall scheint die Kommunikation zwischen 10.100.45.26 und 10.100.45.39 häufig zu erfolgen. Haben Sie also nur für den Fall einen Hub, der nur 10.100.45.26 und 10.100.45.39 verbindet, die vom Haupt-Hub kaskadiert sind, und das Problem ist Ich habe den Übergang beobachtet, um zu sehen, ob

Natürlich denke ich, dass es viele Tools gibt, mit denen Pakete dieser Ebene zusammengefasst werden können, aber der große Vorteil war, dass Sie, wenn Sie Kenntnisse über Pandas hätten, nicht lernen müssten, wie man spezielle Tools verwendet.

Visualisierung von Sensordaten von IoT-Geräten, die von TeraTerm erfasst wurden

Ich denke, dass es viele Fälle gibt, in denen Sie ein Gefühl dafür bekommen möchten, was die Sensordaten des Geräts zurückgeben, und dann mit der vollständigen Implementierung fortfahren möchten. Es musste schnell untersucht werden, wie die Werte des am IoT-Gerät angebrachten 3-Achsen-Erdmagnetsensors mit der Drehung des Geräts zusammenhängen und welche Art der Datenverarbeitung durchgeführt werden sollte, wenn Sie die Ausrichtung extrahieren möchten. .. Glücklicherweise gab es einen Beispielcode für den geomagnetischen Sensor, der die Sensordaten seriell ausgab. Deshalb habe ich beschlossen, das Textprotokoll mit TeraTerm zu speichern und zu visualisieren.

スクリーンショット 2019-12-18 10.58.59.png

Weil es sich um solche Protokolldaten handelt

def parse_mag_str(line):
    try:
        splitted = line[5:].replace(' ', '').split(',')
        return [float(n) for n in splitted]
    except:
        return None

Lassen Sie uns eine geeignete perspektivische Funktion wie erstellen.

スクリーンショット 2019-12-18 11.00.05.png

Das Verhalten scheint also in Ordnung zu sein

mags = [parse_mag_str(l) for l in log[2:]][0:-1]

Lassen Sie uns ein Float-3D-Array erstellen.

Wenn Sie die Daten anschließend in eine interaktive 3D-Visualisierungsbibliothek wie ipyvolume einfügen, können Sie sie einfach mit der Maus in ein 3D-Diagramm konvertieren. Du kannst nachschauen.

import ipyvolume as ipv

start = 250
end = 8000
t = np.array(range(start,end))
x = np.array([m[0] for m in mags[start:end]])
y = np.array([m[1] for m in mags[start:end]])
z = np.array([m[2] for m in mags[start:end]])
x_n = np.array([m[0] for m in mags[start+10:end+10]])
y_n = np.array([m[1] for m in mags[start+10:end+10]])
z_n = np.array([m[2] for m in mags[start+10:end+10]])
u = x_n - x
v = y_n - y
w = z_n - z


ipv.figure()
quiver = ipv.quiver(x, y, z, u, v, w, size=3, size_selected=20)
ipv.show()

ipyvolume.gif

In diesem Fall habe ich festgestellt, dass ich nur die Koordinatenwerte der xy-Ebene atan2 muss, um die Ausrichtung zu erhalten. Da die Zeitreihe der Daten auch durch die Richtung des Kegels bekannt ist, kann das Vorzeichen richtig eingestellt werden.

Viele Pakete, die mit ipy beginnen, sind nützlich, weil sie die Sichtbarkeit und Interaktivität von Jupyter verbessern. Es gibt ipyleaflet, das Daten auf einer interaktiven Karte anzeigen kann, ipywidgets, die eine Benutzeroberfläche mit Schaltflächen erstellen können usw.

Analysezusammenfassung

Wenn Sie das Protokoll umfassend überprüfen und das Ausgabeergebnis der Datenverarbeitung visualisieren / aussprechen müssen, scheint das Schreiben eines Verarbeitungswerkzeugs bis jetzt problematisch zu sein (nur wenn es wirklich notwendig ist). (Ich habe es mit openFrameworks geschrieben), aber ich habe mich mit einer Verifizierung getäuscht, ohne viel zu tun, aber auf dem Gebiet der Datenanalyse und -visualisierung, dem Hauptpunkt von Jupyter Notebook, können die meisten Dinge reibungslos erledigt werden, und mein Verstand ist nervös. Sie können einen Schritt nach vorne machen, um das Problem zu lösen, ohne es zu verwenden. Da das Ergebnis von Versuch und Irrtum ohne Erlaubnis als Notizbuch verbleibt, ist es sehr zeit- und arbeitsaufwendig, wenn Sie es später erneut mit anderen Daten überprüfen müssen. Ich mag es, Metadaten für Nachforschungen zu protokollieren und zu extrahieren. Wenn ich den Code in einer Atmosphäre schreibe, kann ich einen Umfragebericht erstellen, der über die manuelle Überprüfung hinausgeht, die ich bisher nur ungern mit überwältigender Genauigkeit und Quantität durchgeführt habe, und ich habe das Gefühl, etwas erreicht zu haben.

Fall habe ich versucht, als Taschenrechner zu verwenden

Haben Sie jemals ein UI-Design implementiert und die gleiche Multiplikation und Addition entsprechend der Bildschirmgröße basierend auf der Designzeichnung viele Male erlebt? Wenn Sie eine Bildverarbeitung durchführen und eine kleine Matrixberechnung (inverse Matrix, Diagonalisierung usw.) durchführen möchten, möchten Sie eine Rotationsmatrix in Ihrer bevorzugten Rotationsreihenfolge erstellen. Eine etwas komplizierte inverse Matrix ist algebraisch Gibt es etwas, wonach Sie fragen möchten?

Einfache Matrixberechnung

Numerische Berechnung

Es ist notwendig, das Farbsehen einer Person mit Farbsehstörungen zu reproduzieren und nach der Konvertierung des RGB-Farbraums in den LMS-Farbraum (es handelt sich um eine lineare Konvertierung) eine Matrixoperation im LMS-Farbraum durchzuführen und in den RGB-Raum zurückzukehren. Als Ergebnis mussten wir herausfinden, welche Art der linearen Konvertierung im RGB-Farbraum durchgeführt werden sollte. Die Formel lautet wie folgt.

\begin{eqnarray}
\mathbf{c^{'}}_\mathrm{RGB} & = & \mathbf{M}_\mathrm{LMStoRGB} \cdot \mathbf{M}_\mathrm{protanopia} \cdot \mathbf{M}_\mathrm{RGBtoLMS} \cdot \mathbf{c}_\mathrm{RGB} \\
 & = & ( \mathbf{M}^{-1}_\mathrm{RGBtoLMS} \cdot \mathbf{M}_\mathrm{protanopia} \cdot \mathbf{M}_\mathrm{RGBtoLMS}) \cdot \mathbf{c}_\mathrm{RGB}
\end{eqnarray}

Sie müssen nur den in Klammern auf der rechten Seite eingeschlossenen Matrixteil berechnen. Fügen Sie ihn also fast so wie er ist in Numpy ein und er wird mit dem folgenden Code vervollständigt.

import numpy as np

rgb2lms = np.array([0.31399022, 0.63951294,
            0.04649755, 0.15537241, 0.75789446, 0.08670142, 0.01775239,
            0.10944209, 0.87256922]).reshape((3,3))

lms2rgb = np.linalg.inv(rgb2lms)
スクリーンショット 2019-12-18 11.08.26.png

Während ich überprüfte, ob rgb2lms und lms2rgb richtig gemacht wurden (ich wusste nicht, ob Numpy Column Major oder Row Major ist, also fuhr ich fort, während ich Jupyter überprüfte). Die resultierende Matrix könnte unten berechnet werden.

protanopia = np.array([0.0, 1.05118294,-0.05116099, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]).reshape((3,3))

lms2rgb.dot(protanopia).dot(rgb2lms)
スクリーンショット 2019-12-18 11.09.08.png

Algebraische Berechnung

Ich denke, dass die Rotationsmatrix im 3D-Raum häufig verwendet wird, wenn Spiele erstellt, Koordinaten mit 3DCG verarbeitet und der Bewegungssensor eines Smartphones berührt werden. Abhängig von der Reihenfolge, in der die X-, Y- und Z-Achse gedreht werden, gibt es 6 Rotationsmatrizenmuster. Bis jetzt habe ich viel verschwendet, indem ich Wikipedia einzeln durchsucht und gesagt habe, dass das, das ich ausgewählt habe, falsch ist und nicht funktioniert. Tatsächlich ist es jedoch am zuverlässigsten und schnellsten, von links nacheinander zu multiplizieren, während genau erfasst wird, wie der Vektor vom lokalen Koordinatensystem in das globale Koordinatensystem konvertiert wird. Deshalb berechne ich auch die Rotationsmatrix selbst. Nur in Python gibt es eine Bibliothek namens Sympy, die algebraische Berechnungen durchführt.

from sympy import *
#Drehung der x-Achse
theta = Symbol('theta')
Rx = Matrix([[1, 0, 0], [0, cos(theta), -sin(theta)], [0, sin(theta), cos(theta)]])

#Drehung in Richtung der y-Achse
yaw = Symbol('yaw')
Ry = Matrix([[cos(yaw), 0, sin(yaw)], [0, 1, 0], [-sin(yaw), 0, cos(yaw)]])

#Drehung der Z-Achse
phi = Symbol('phi')
Rz = Matrix([[cos(phi), -sin(phi), 0], [sin(phi), cos(phi), 0], [0, 0, 1]])

R = Ry * Rx * Rz
R
スクリーンショット 2019-12-18 11.10.41.png

Das Ergebnis wird auch in einer schönen Form angezeigt, die mit TeX gerendert wurde, sodass es leicht zu überprüfen ist. Da ich die Rotationsmatrix selbst erstelle, versuchen Sie, die Reihenfolge zu ändern oder die Rotationsmatrix um eins zu reduzieren, auch wenn etwas nicht stimmt. Das können Sie leicht tun.

Komplizierte inverse Matrixberechnung

Ich habe die Anforderung erhalten, ein Bild von Projektionskonvertierung ohne Bibliothek auf einem IoT-Gerät anzuzeigen. Es war. Der Ableitungsprozess ist nicht das Hauptthema, daher werde ich ihn weglassen (obwohl das Format etwas anders ist, handelt es sich im Wesentlichen um Homographie - Shogo Computing Laboratory. Dieselbe Berechnung sollte durchgeführt werden), aber als Ergebnis wurde jedes Element der 3-mal-3-Projektionstransformationsmatrix zu einem 9-dimensionalen Vektor, als die inverse Matrix der folgenden 9-mal-9-Matrix gelöst und mit dem Vektor multipliziert wurde. Sie können das Ding X finden.

from sympy import *

# x0 = Symbol('x0')Substitution wie x0- x3, y0 -Tun Sie für y3
for i in range(4):
    for c in "xy":
        globals().update({c + str(i): Symbol(c + str(i))})

u0 = 640
v0 = 0
u1 = 640
v1 = 480
u2 = 0
v2 = 480
u3 = 0
v3 = 0

A = Matrix([
            [ x0, y0, 1, 0, 0, 0, -x0*u0, -y0*u0, 0 ],
            [ 0, 0, 0, x0, y0, 1, -x0*v0, -y0*v0, 0 ],
            [ x1, y1, 1, 0, 0, 0, -x1*u1, -y1*u1, 0 ],
            [ 0, 0, 0, x1, y1, 1, -x1*v1, -y1*v1, 0 ],
            [ x2, y2, 1, 0, 0, 0, -x2*u2, -y2*u2, 0 ],
            [ 0, 0, 0, x2, y2, 1, -x2*v2, -y2*v2, 0 ],
            [ x3, y3, 1, 0, 0, 0, -x3*u3, -y3*u3, 0 ],
            [ 0, 0, 0, x3, y3, 1, -x3*v3, -y3*v3, 0 ],
            [ 0, 0, 0,  0,  0, 0,      0,      0, 1 ],
            ])
A
スクリーンショット 2019-12-18 11.12.04.png
B = Matrix([u0, v0, u1, v1, u2, v2, u3, v3, 1])
B
スクリーンショット 2019-12-18 11.12.24.png
X = A.inv() * B
スクリーンショット 2019-12-18 11.13.27.png

Es scheint, dass es in etwa 5 Sekunden berechnet werden könnte. Es scheint jedoch, dass jedes Element von X viele Begriffe enthält. Wenn Sie versuchen, es anzuzeigen, wird das Kompilieren von TeX viel Zeit in Anspruch nehmen, sodass ich es als Zeichenfolge extrahieren werde.

X_strs = [str(simplify(X[i])) for i in range(9)]
スクリーンショット 2019-12-18 11.14.29.png

Es dauerte fast 2 Minuten, wahrscheinlich weil die Vereinfachung lange gedauert hat. Ich möchte es so wie es ist in C-Code konvertieren, also benenne ich den Begriff x0 ** 2 in x0p2 um.

list(zip([v + str(i) + '**2' for v in 'xy' for i in range(4)],[v + str(i) + 'p2' for v in 'xy' for i in range(4)]))
スクリーンショット 2019-12-18 11.14.41.png

Es scheint, dass wir es so umbenennen können, also werden wir es sofort durch Reduzieren ersetzen.

X_strs2 = [functools.reduce(lambda s, t: s.replace(*t), list(zip([v + str(j) + '**2' for v in 'xy' for j in range(4)],[v + str(j) + 'p2' for v in 'xy' for j in range(4)])), X_strs[i]) for i in range(9)]

Die endgültige Konvertierung in C-Code erfolgt mit folgendem Code:

for v in 'xy':
    for i in range(4):
        print('float %s%dp2 = %s%d * %s%d;\n' % (v, i, v, i, v, i))

for i in range(9):
    print('float X%d = ' % i + X_strs2[i] + ';\n')
スクリーンショット 2019-12-18 11.25.03.png スクリーンショット 2019-12-18 11.24.04.png

Jetzt wird die Projektionskonvertierungsfunktion mit beliebigen Parametern für eingebettete Geräte in einer Form erstellt, die von keiner Bibliothek abhängig ist. An einer Stelle gab es eine Konvertierungsauslassung, aber als ich sie korrigierte, funktionierte sie wie erwartet.

Ich fand auch die Umkehrung dieser Projektionstransformationsmatrix mit einem ähnlichen Gefühl.

スクリーンショット 2019-12-18 11.26.08.png

Es ist einfach, denn wenn Sie die Formel fast so schreiben, wie sie ist, wird sie vervollständigt.

Einfacher Taschenrechner

Es wird auch verwendet, um die Größe von UI-Elementen zu berechnen, die mit unterschiedlichen Bildschirmgrößen entworfen wurden. Es ist nicht wirklich eine große Sache, aber ich bin froh, dass es leicht zu sehen und zu reparieren ist.

l.png

Ein Fall, in dem ich Binärdaten erstellt und ein Paket ausgegeben habe

Gerätesteuerungsexperiment durch Ausgabe von UDP-Paketen

Ich mache ein Beschilderungssteuerungssystem, und ein bestimmtes Leistungssteuerungsgerät sollte mit UDP-Binärpaketen funktionieren. Deshalb habe ich versucht, ein Paket gemäß den Spezifikationen zu erstellen und es per UDP zu senden.

Machen Sie zuerst ein Paket.

switches = [True, False, True, True, False]

model_id = 3 # LA-5R
unit_id = 0b00001111 ^ 0

def make_send_bytes(model_id, unit_id, switches):
    return bytes([0xf0 | unit_id, switches[4] << 4 | switches[3] << 3 | switches[2] << 2 | switches[1] << 1 | switches[0]])

send_bytes = make_send_bytes(model_id, unit_id, switches)
[format(send_bytes[i], '02x') for i in [0, 1]]
スクリーンショット 2019-12-18 16.31.39.png

Es scheint, dass das Paket erstellt wurde, also werde ich es tatsächlich senden.

switches = [random.random() < 0.5 for i in range(0, 5)]

send_bytes = make_send_bytes(model_id, unit_id, switches)
[format(send_bytes[i], '02x') for i in [0, 1]]

s.sendto(send_bytes, (HOST, PORT))

Ich kann keine Screenshots erstellen, konnte jedoch bestätigen, dass dies funktioniert, wenn ich ein Paket sende.

Überprüfen Sie als nächstes, ob das Ein- und Ausschalten aller 5-Kanal-Muster und 32-Muster gesteuert werden kann.

sl = 0.08
l = 0.08 / sl
for j in range(0, int(l)):
    for i in range(0, 32):
        switches = [c == '1' for c in format(i, '05b')]
        send_bytes = make_send_bytes(model_id, unit_id, switches)
        [format(send_bytes[i], '02x') for i in [0, 1]]
        s.sendto(send_bytes, (HOST, PORT))
        time.sleep(sl)
スクリーンショット 2019-12-18 16.32.07.png

Wenn man nur das Ergebnis des Schreibens betrachtet, ist es fast dasselbe wie das Schreiben in C, aber ohne daran gewöhnt zu sein, Bit-Arithmetik, Versuch und Irrtum, ob das Paket korrekt erstellt wurde oder nicht, es tatsächlich zu senden und zu versuchen, es zu funktionieren Es stellt sich heraus, dass die schnelle Schleife von sehr wichtig für die Implementierungseffizienz ist.

Gleichzeitig habe ich auch die Steuerung über die TCP-Verbindung überprüft. Wenn Sie dem Notizbuch jedoch eine Tabelle hinzufügen, befindet sich diese nicht in einem Zustand voller mysteriöser Kommentare, sodass Sie die Teile sortieren können, die zwischen TCP und UDP umgeleitet werden können, und die Teile, die nicht umgeleitet werden können. , Sie können später zurückblicken und die Verwendung des Codes vereinfachen.

Fall der Formatkonvertierung

Dies kann der typischste Fall sein. Als Softwareentwickler gibt es viele Fälle, in denen Sie ein einfaches Skript schreiben und verschiedene Formatkonvertierungen lösen möchten, um die Rohstoffdaten abzurufen und zum endgültigen Formular zu machen. Selbst in einem solchen Fall ist die Stärke von Jupyter Notebook, dass Sie versuchen können, Fehler zu machen, während Sie es betrachten, sehr nützlich.

Konvertieren Sie den aus AfterEffects exportierten JSON, um Objekterstellungscode zu erstellen, der von Unity's Immediate ausgeführt werden kann

Während der Spieleentwicklung wollte ich manchmal Bilder portieren, die mithilfe der 3D-Ebenenfunktion in After Effects in Unity platziert wurden. Natürlich kann dies realisiert werden, indem ein Unity Quad-Objekt erstellt wird, während die numerischen Werte schichtweise betrachtet werden, aber ich möchte keine so einfache Aufgabe ausführen, obwohl es ungefähr 50 Ebenen gibt. Also habe ich zuerst alle Informationen der After Effects-Ebene in JSON mit ESTK geschrieben und dann in Jupyter Notebook verarbeitet.

Überprüfen Sie zunächst, welcher Wert enthalten ist.

import json
import codecs
from operator import itemgetter

with codecs.open('transforms.json', 'r', encoding='shift-jis') as f:
    root = json.load(f)

root
スクリーンショット 2019-12-18 11.29.15.png

Nehmen Sie eine Schicht heraus,

layer = root['9']
layer
スクリーンショット 2019-12-18 11.29.32.png

Position, Ankerpunkt, Breite, Höhe, Maßstab usw. werden für jedes Element von X und Y zusammengefasst.

list(zip(layer['Position'],layer['Ankerpunkt'],[layer['width'], layer['height']], [layer['Rahmen'][0], layer['Rahmen'][1]]))
スクリーンショット 2019-12-18 11.29.38.png

Wir werden die Positionsspezifikation und Vergrößerung / Verkleinerung, die die Ankerpunktkriterien sind, als zentrale Referenz verwenden.

[ps[0] - ps[1] * ps[3] + ps[2] * ps[3] / 2 for ps in zip(
    layer['Position'],
    layer['Ankerpunkt'],
    [layer['width'], layer['height'], 0], 
    [layer['Rahmen'][0] / 100, layer['Rahmen'][1] / 100, 1])]
スクリーンショット 2019-12-18 11.29.47.png

Nachdem wir nun wissen, wie man mit einer Ebene umgeht, wenden wir sie auf alle Ebenen an. Der Grund für die Umkehrung ist, dass die überlappende Reihenfolge zwischen After Effects und Unity umgekehrt ist.

t_list = [([ps[0] - ps[1] * ps[3] + ps[2] * ps[3] / 2 for ps in zip(layer['Position'],layer['Ankerpunkt'],[layer['width'], layer['height'], 0], [layer['Rahmen'][0], layer['Rahmen'][1], 1])], 
 [layer['width'] * layer['Rahmen'][0] / 100, layer['height'] * layer['Rahmen'][1] / 100], layer['name']) for layer in root.values()]
t_list.reverse()
t_list
スクリーンショット 2019-12-18 11.30.16.png

Nachdem wir die Koordinaten, die Breite und die Höhe für alle Ebenen kennen, geben wir den Bereich "Sofort" des Unity-Editors ein und generieren den C # -Code, um die Objekte in der Szene zu erstellen.

cs_str = '''{GameObject q = GameObject.CreatePrimitive(PrimitiveType.Quad);
q.name = "%s";
q.transform.position = new Vector3(%ff, %ff, %ff);
q.transform.localScale = new Vector3(%ff, %ff, 1.0f);
var m = (q.GetComponent<Renderer>().material = UnityEditor.AssetDatabase.LoadAssetAtPath<Material>("Assets/Textures/Background/_Materials/%s.mat"));
if (m != null) m.renderQueue = %d;
}'''
sss = '\n'.join([cs_str % (t[2].replace('.psd', ''),
                           t[0][0] / 1000, -t[0][1] / 1000, t[0][2] / 1000, 
                           t[1][0] / 1000, t[1][1] / 1000, t[2].replace('.psd', ''),
                           3000 + i + start) for i, t in 
                 enumerate(sorted(t_list, key=lambda t: int(t[0][2]), reverse=True)[start:start + lll])])
print(sss)
スクリーンショット 2019-12-18 11.30.56.png

Durch Eingabe des Codes in den Bereich "Sofort" wurde die After Effects-Szene neu erstellt. Ich denke, es hat bis zu 50 Mal gedauert, aber ich denke, es ist ab dem zweiten Mal viel einfacher, weil der Designer mechanisch damit umgehen kann, selbst wenn er mit der After Effects-Szene spielt. Leider sagte der Designer: "Ich möchte nicht mehr mit so komplizierten und schwer zu bedienenden AE-Dateien spielen."

Generieren Sie HTML-Teile

Gelegentlich codiere ich auch HTML, aber manchmal muss ich einen Teil wie eine Liste von Artikeln in einem Blog von Hand schreiben, in dem die Titelzeichenfolge usw. fast wiederholt oft vorkommt. Es ist die Rede davon, dass Sie CMS einfügen und mit einem statischen Website-Generator verwenden können, aber in den meisten Fällen müssen Sie der Veröffentlichung Vorrang vor dem HTML-Editor geben, wenn der sich wiederholende Teil insgesamt ein wenig ist Ich habe das Gefühl, dass es schneller ist, direkt zu schreiben (obwohl dies auch ein wichtiger Grund dafür ist, dass ich wenig Erfahrung mit HTML / CSS habe). Selbst in einem solchen Fall ist es mühsam und mühsam, dieselbe Zeichenkette an mehreren Stellen zu kopieren, und es ist nervenaufreibend, so dass der Programmierer das Gefühl hat, dass er sie überspringen möchte. Sobald ich es in Klammern schreibe und es gut angezeigt wird, werde ich eine Vorlage erstellen und sie ersetzen.

news_template='''                <article class="news-box">
                  <div class="news-photo-box"><img src="assets/image/news/###image_name###"></div>
                  <div class="news-date">###date_str###</div>
                  <div class="news-title">###title_str###</div>
                  <button class="news-more" alt="MORE"></button>
                  <div class="news-description news-description-hidden">
                    <button class="close-button"></button>
                    <button class="news-prev-button"></button>
                    <button class="news-next-button"></button>
                    <div class="news-description-inner">
                      <div class="news-description-pdt-box">
                        <div class="news-description-photo-box"><img src="assets/image/news/###image_name###"></div>
                        <div class="news-description-dt-box">
                          <div class="news-description-date">###date_str###</div>
                          <div class="news-description-title">###title_str###</div>
                        </div>
                      </div>
                      <div class="news-description-body">
                        ###body_str###
                      </div>
                    </div>
                  </div>
                </article>
'''

def make_news(date_str, title_str, body_str, image_name='default.png'):
    return news_template \
        .replace('###date_str###', date_str) \
        .replace('###title_str###', title_str) \
        .replace('###body_str###', body_str) \
        .replace('###image_name###', image_name)
スクリーンショット 2019-12-18 16.14.49.png

Jetzt können Sie definitiv HTML erstellen, indem Sie die erforderlichen Elemente eingeben. Es ist großartig, dies ohne Lernkosten tun zu können. Wenn ich gebeten werde, in Zukunft Neuigkeiten hinzuzufügen, denke ich, dass das Öffnen dieses Notizbuchs mich an alles erinnert, was ein guter Punkt in dem Sinne ist, dass es in Zukunft keine Schulden mehr hinterlassen wird, obwohl es nicht klar dokumentiert ist. Überlegen.

Andere

Außerdem,

Das Lesen und Konvertieren erfolgt meistens mit Jupyter Notebook, es sei denn, es kann mit einem einzigen Befehl ausgeführt werden.

Ich denke, es gibt viele Dinge, die Sie mit herkömmlichen Befehlszeilentools tun können, aber es ist mühsam, herauszufinden, wie die Tools verwendet werden, und über das Übergeben von Daten zwischen Tools nachzudenken, und es ist fast sicher, dass Datensätze erhalten bleiben und Sie von vorne beginnen müssen. Ich muss mir darüber keine Sorgen machen, deshalb verwende ich weiterhin Jupyter Notebook anstelle von Muscheln.

Denken Sie, Sie wurden getäuscht und versuchen Sie, das Jupyter-Notizbuch zu verwenden. Ich denke, dass es sehr gut für Leute geeignet ist, die von Projekt zu Projekt viel nicht standardisierte Arbeit haben.

Recommended Posts

Jupyter Notebook unerlässlich für die Softwareentwicklung
Snippet-Einstellungen für Python Jupyter Notebook
[MEMO] [Aufbau der Entwicklungsumgebung] Jupyter Notebook
Jupyter Notebook-Erweiterung, nbextensions-Einstellungen für mich
Jupyter Notizbuch Memo
Einführung in Jupyter Notebook
Leistungsstarkes Jupyter-Notizbuch
Jupyter Notebook Passwort
Jupyter Notizbuch Memo
Datenanalyse zur Verbesserung von POG 2 ~ Analyse mit Jupiter-Notebook ~
[Für die Datenwissenschaft] Oreore Jupyter Spickzettel [Jupyter Notebook / Lab]
Starten Sie Jupyter Notebook
Probieren Sie grundlegende Operationen mit Pandas DataFrame auf Jupyter Notebook aus
Mac-Anwendung zum Öffnen von Jupyter Notebook (* .ipynb) durch Doppelklick
3 Jupyter Notebook (Python) Tricks
Neben Excel jupyter Notebook vorerst
[Cloud103] # 3 Jupyter Notebook wieder
Empfehlung von Jupyter Notebook, einer Codierungsumgebung für Datenwissenschaftler
<Python> Erstellen Sie einen Server für die Datenanalyse mit Jupyter Notebook
[Remotte-Entwicklung] Funktionen für Entwickler
Einführung des Jupyter Notebook in CentOS7
HTML in Jupyter-Notizbuch anzeigen
Für ArcPy geeignete Entwicklungsumgebung
Verwenden Sie pip mit Jupyter Notebook
Mehrfachverarbeitungsfehler in Jupyter Notebook
Sieben Trends in der Softwareentwicklung im Jahr 2020
Versuchen Sie, Jupyter Notebook dynamisch zu verwenden
[Super Basics] Über jupyter Notebook
Hohe Charts im Jupyter-Notizbuch
PDF auf Jupyter Notebook anzeigen
Verwenden Sie Cython mit Jupyter Notebook
Homebrew, Pyenv, Anaconda, Jupyter Notebook
Spielen Sie mit Jupyter Notebook (IPython Notebook)
[Komplette Ausgabe] Jupyter Notebook Shortcut
[Zum Organisieren] Python-Entwicklungsumgebung
Führen Sie Jupyter Notebook unter Windows aus
So verwenden Sie Jupyter Notebook
jupyter notebook in python3.8 venv umgebung