[GO] Erste Schritte mit Android!

Einführung

Hallo, Ende der Schule diese Woche voll, verbringe die Sommerferien ohne Inhalt ab nächster Woche ist mein. Dieses Mal möchte ich die Android-App für die HTTP-Kommunikation mit der Django-API verwenden, die in Vorheriger Artikel erstellt wurde.

Die Qualität ist übrigens nicht so hoch, weil sie an einem Tag implementiert wurde, obwohl sie abgedeckt war. (Obwohl es ungefähr 16 Stunden dauert)

Grundlagen!

Hier hatte ich die meisten Probleme. Ich habe die Ausführungskonfiguration überhaupt nicht verstanden, ich konnte überhaupt nicht das ganze Bild sehen, wie man das Frontend implementiert. etc. Erstens, wenn Sie nicht das ganze Bild erfassen können, wissen Sie nicht, womit Sie beginnen sollen. Daher ist es zunächst notwendig zu verstehen, aus welcher Art von Struktur es besteht und was es tun kann.

Außerdem gibt es kürzlich Kotlin und React Native bei der Entwicklung von Android-Apps, aber dieses Mal werden wir Java verwenden, das [Owacon Legacy Language] ist (https://www.youtube.com/watch?v=Xlf7TN3Hcnw).

Wichtige Dinge

Hier sind einige wichtige Dinge, die beim Erstellen einer Android-App zu tun sind. Zumindest möchte ich, dass Sie diese Konfiguration verstehen. Bitte verzeihen Sie mir.

--Aktivität

Wenn ein Webliebhaber es mit MVC vergleicht, befindet sich das Modell diesmal auf dem Django-Server, und der Java-Code, aus dem Android besteht, ist der Controller, und der in XML geschriebene Teil ist die Ansicht.

Ausführungskonfiguration

Dieses Mal ist der Teil hier, den ich am meisten über HTTP-Kommunikation nicht verstanden habe. Welche Klasse wird überhaupt in Android ausgeführt? Ich war in Schwierigkeiten, weil es so war. Als wichtige Voraussetzung ** Wenn Sie Android ausführen, wird die im Manifest angegebene Klasse ausgeführt. ** **. Mit anderen Worten, selbst wenn Sie andere Klassen definieren, müssen Sie diese eventuell dort aggregieren. (Ich habe das nicht verstanden)

Das Bild sieht wie in der Abbildung unten aus. image.png

Es ist eine schmutzige Figur, aber da die einzige Klasse, die endgültig ausgeführt wird, die Hauptklasse ist, selbst wenn es viele andere Klassen gibt, wird die Verarbeitung, die Sie ausführen möchten, nur in der Hauptklasse ausgeführt. Sie können einen Umweg machen, also kommen wir zum Haupt! !! !!

Lassen Sie uns den Code tatsächlich schreiben.

Die diesmal verwendeten Klassen sind wie folgt.

Klasse Verwenden
ExSample.java Hauptausführungsklasse
AsyncHttpRequestGet.java Holen Sie sich alle Daten
AsyncHttpRequestPost.java Benachrichtigung über den Abschluss der Lieferung senden
ListAndView.java Klasse zum Einstellen der Listenansicht im linearen Layout

Dieses Mal werde ich eine Android-Anwendung mit diesen vier machen.

erstellen!

Lass uns schreiben.

Punkte im Beispiel

--Konstruieren Sie ein Programm, indem Sie die AppCompatActivity-Klasse erben.

ExSample.java


package es.exsample;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

public class ExSample extends AppCompatActivity {

    //Klasse zeigen
    private static final String TAG = "ExSample";
    //Variablen zum Verweisen auf den Kontext in verschiedenen Klassen
    private static ExSample context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_item);
        context = this;
        //Lauf
        AsyncHttpRequestGet task = new AsyncHttpRequestGet(context);
        task.execute("http://localhost:8000/get_shop");
        Log.d(TAG, "created");
    }

    //Funktionen zur Verwendung von Context in anderen Klassen
    public static ExSample getInstance(){
        return context;
    }
}

Punkt von AsyncHttpRequestGet

--ExSample führt dies nur aus, daher ist der Betrag in dieser Klasse ziemlich groß. --Async Task wird vererbt und asynchrone Verarbeitung durchgeführt. --Initialisieren Sie, was übergeben wird, indem Sie die ID des XML-Teils im Konstruktor angeben. --URL url = neue URL (params [0]); kann verwendet werden, um die in der Hauptklasse definierte URL abzurufen.

AsyncHttpRequestGet.java



package es.exsample;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;

public class AsyncHttpRequestGet extends AsyncTask<String, Void, String> {
    //Logger-Tag
    private static final String TAG = "AsyncHttpRequestGet";

    //Ansicht vom UI-Thread aus bedient
    private TextView titleView;
    private TextView beforUserContent;
    private TextView doneUserContent;
    private ListView beforUser;
    private ListView doneUser;
    public static Map<String, String> data;
    public static List<Map<String, String>> dataList;
    public static ListView listView;
    public static ListAndView adapter;

    //Set Konstruktor, Ansicht
    public AsyncHttpRequestGet(Context context) {
        super();
        ExSample sample = (ExSample) context;
        titleView = (TextView)sample.findViewById(R.id.title);
        beforUserContent = (TextView)sample.findViewById(R.id.befor);
        doneUserContent = (TextView)sample.findViewById(R.id.done);
        beforUser = (ListView)sample.findViewById(R.id.beforUser);
        doneUser = (ListView)sample.findViewById(R.id.doneUser);

        listView = (ListView)sample.findViewById(R.id.beforUser);
    }

    //Bearbeiten Sie Anfragen und Antworten hier
    @Override
    protected String doInBackground(String... params) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        HttpsURLConnection connection = null;

        try {
            //Die URL wird festgelegt, der Header-Wert wird hier verwaltet und das Token kann beim Anmelden abgerufen werden.
            URL url = new URL(params[0]);
            connection = (HttpsURLConnection)url.openConnection();
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", "Geben Sie den von JWT Django erhaltenen Schlüssel an");
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(3000);

            // GET
            connection.setRequestMethod("GET");
            connection.connect();

            //Überprüfen Sie den Antwortcode
            int responseCode = connection.getResponseCode();
            if(responseCode != HttpsURLConnection.HTTP_OK) {
                throw new IOException("HTTP responseCode: " + responseCode);
            }

            //Stringifizierung
            inputStream = connection.getInputStream();
            if(inputStream != null) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(connection != null) {
                connection.disconnect();
            }
        }
        return sb.toString();
    }

    //Erstellen Sie hier eine Ansicht
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onPostExecute(String result) {

        List<String> userListOrderDone = new ArrayList<String>();
        List<String> userListBeforOrder = new ArrayList<String>();
        List<String> idList = new ArrayList<String>();

        //Eine Funktion, die dies nur in ExSample zurückgibt (ich weiß nicht, ob es sinnvoll ist)
        Context context = ExSample.getInstance().getApplicationContext();
        ArrayAdapter<String> beforUserList = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, userListBeforOrder);
        ArrayAdapter<String> doneUserList = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, userListOrderDone);


        Log.d(TAG, result);
        titleView.setText("Motodeli");
        beforUserContent.setText("Vor der Auslieferung");
        doneUserContent.setText("Lieferung abgeschlossen");
        beforUser.setAdapter(beforUserList);
        doneUser.setAdapter(doneUserList);


        try{
            //Erhalten Sie alle Antworten mit JSONArray
            JSONArray all = new JSONArray(result);
            dataList = new ArrayList<Map<String, String>>();
            for(int i = 0; i < all.length(); i++){
                data = new HashMap<String, String>();
                //Sie können jeden gewünschten Wert erhalten
                JSONObject json = all.getJSONObject(i);
                String email = json.getString("user");
                String total = json.getString("total");
                String status = json.getString("status");
                String id = json.getString("id");
                //Beurteilen Sie, ob es gemäß den Bedingungen des Benutzers geliefert wurde oder geliefert wurde (ein Bild, das viele Anfänger süchtig nach dem Vergleich von Java-Zeichenfolgen sind).
                if(status.equals("true")){
                    data.put("text1", email);
                    data.put("text2", id);
                    dataList.add(data);
                }
                else{
                    userListOrderDone.add(String.format("%s: %s Yen", email, total));
                }
            }
        }
        catch (JSONException e){
            System.out.println(e);
        }

        //Geben Sie den Wert basierend auf den zuvor extrahierten Daten ein
        adapter = new ListAndView(
                context,
                dataList,
                R.layout.row,
                new String[] {
                        "text1",
                        "text2",
                    },
                new int[] {
                        android.R.id.text1,
                        android.R.id.text2,
                });
        //In der Listenansicht wiedergegeben
        listView.setAdapter(adapter);
        listView.setTextFilterEnabled(false);
    }
}

Punkt von AsyncHttpRequestPost

AsyncHttpRequestPost.java


package es.exsample;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;

public class AsyncHttpRequestPost extends AsyncTask<String, Void, String> {
    private static final String TAG = "AsyncHttpRequestPost";
    private TextView textView;

    public AsyncHttpRequestPost(Context context) {
        super();
    }

    @Override
    protected String doInBackground(String... params) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        HttpsURLConnection connection = null;

        try {
            //Legen Sie die URL-Zeichenfolge fest.
            URL url = new URL(params[0]);
            connection = (HttpsURLConnection)url.openConnection();
            connection.setConnectTimeout(3000); //Zeitüberschreitung 3 Sekunden
            connection.setReadTimeout(3000);

            // POST
             connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo2LCJ1c2VybmFtZSI6ImIxODA2NDI5QHBsYW5ldC5rYW5hemF3YS1pdC5hYy5qcCIsImV4cCI6MTU5NTIzMTIzNiwiZW1haWwiOiJiMTgwNjQyOUBwbGFuZXQua2FuYXphd2EtaXQuYWMuanAifQ.18LotiLgemUmSXTqmdcjjD3eKLSL1B13N87msbQswoE");
            OutputStream outputStream = connection.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
            writer.write(params[1]);
            writer.close();
            connection.connect();

            //Antwortcode.
            int responseCode = connection.getResponseCode();
            if(responseCode != HttpsURLConnection.HTTP_OK) {
                throw new IOException("HTTP responseCode: " + responseCode);
            }

            //Stringifizierung
            inputStream = connection.getInputStream();
            if(inputStream != null) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(connection != null) {
                connection.disconnect();
            }
        }
        return sb.toString();
    }

}

ListAndView-Punkte

ListAndView.java


package es.exsample;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.content.ContentValues.TAG;

public class ListAndView extends SimpleAdapter {

    private LayoutInflater inflater;
    private List<? extends Map<String, ?>> listData;

    //Datenaufbewahrungsklasse, die von jeder Zeile gehalten wird
    public class ViewHolder {
        TextView text1;
        TextView text2;
    }

    public ListAndView(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
        this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.listData = data;
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;

        //Erhalten Sie eine Ansicht
        View view = convertView;

        if (view == null) {
            view = inflater.inflate(R.layout.row, parent, false);

            holder = new ViewHolder();
            holder.text1 = (TextView) view.findViewById(android.R.id.text1);
            holder.text2 = (TextView) view.findViewById(android.R.id.text2);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        //Daten im Halter einstellen
        String text1 = ((HashMap<?, ?>) listData.get(position)).get("text1").toString();
        String text2 = ((HashMap<?, ?>) listData.get(position)).get("text2").toString();
        holder.text1.setText(text1);
        holder.text2.setText(text2);

        //Ausführen, wenn Sie die Taste drücken
        Button btn = (Button) view.findViewById(R.id.rowbutton);
        btn.setTag(position);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                String id = holder.text2.getText().toString();
                Context context = ExSample.getInstance().getApplicationContext();
                AsyncHttpRequestPost task = new AsyncHttpRequestPost(context);
                String url = "http://localhost:8000/post_shop/" + id;
                task.execute(url, "hi");
                Log.d(TAG, "created");
            }
        });

        return view;
    }

}

XML

image.png

list_item.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    card_view:cardBackgroundColor="#ffffff"
    card_view:cardCornerRadius="7dp"
    card_view:cardElevation="5dp">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="1542dp">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textSize="24sp"
            card_view:layout_constraintBottom_toBottomOf="parent"
            card_view:layout_constraintEnd_toEndOf="parent"
            card_view:layout_constraintHorizontal_bias="0.498"
            card_view:layout_constraintStart_toStartOf="parent"
            card_view:layout_constraintTop_toTopOf="parent"
            card_view:layout_constraintVertical_bias="0.01"
            />

        <TextView
            android:id="@+id/befor"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:text="TextView"
            card_view:layout_constraintTop_toBottomOf="@+id/title"
            tools:layout_editor_absoluteX="189dp"
            />

        <ListView
            android:id="@+id/beforUser"
            android:layout_width="402dp"
            android:layout_height="130dp"
            android:background="#7A7A7A"
            card_view:layout_constraintEnd_toEndOf="parent"
            card_view:layout_constraintStart_toStartOf="parent"
            card_view:layout_constraintTop_toBottomOf="@+id/befor" />



        <TextView
            android:id="@+id/done"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="TextView"
            card_view:layout_constraintTop_toBottomOf="@+id/beforUser"
            tools:layout_editor_absoluteX="189dp" />

        <ListView
            android:id="@+id/doneUser"
            android:layout_width="402dp"
            android:layout_height="364dp"
            android:layout_marginTop="12dp"
            android:background="#777777"
            card_view:layout_constraintEnd_toEndOf="parent"
            card_view:layout_constraintStart_toStartOf="parent"
            card_view:layout_constraintTop_toBottomOf="@+id/done" />

        <TextView
            android:id="@+id/tag"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="60dp"
            android:text="TextView"
            card_view:layout_constraintTop_toBottomOf="@+id/doneUser"
            tools:layout_editor_absoluteX="98dp" />

        <TextView
            android:id="@+id/desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="100dp"
            android:layout_marginTop="60dp"
            android:text="TextView"
            card_view:layout_constraintStart_toEndOf="@+id/tag"
            card_view:layout_constraintTop_toBottomOf="@+id/doneUser" />

    </android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>

image.png

row.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        tools:ignore="MissingConstraints">

        <TextView
            android:id="@android:id/text1"
            android:layout_width="278dp"
            android:layout_height="80dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:text="Text1"
            android:textSize="18dp" />

        <TextView
            android:id="@android:id/text2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical|right"
            android:text="Text2"
            android:textSize="18dp" />

        <Button
            android:id="@+id/rowbutton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:text="Geliefert!" />

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

Es ist ein bisschen chaotisch, aber ich hoffe, Sie können es tatsächlich kopieren und verwenden!

Änderungen am Django-Backend (nach der Ausführung)

--Erstellte eine Funktion, um den Administrator zu benachrichtigen, wenn die Lieferung abgeschlossen ist.

shop/views.py


######
###Kürzung###

#Fügen Sie Folgendes hinzu

from rest_framework.decorators import api_view

@api_view(['POST'])
def order_done_post_request(request, pk):
    user_info = UserInfomation.objects.get(id=pk)
    user = User.objects.get(email=user_info)
    if request.method == 'POST':
        cart = Cart.objects.get(cart_id=user_info.cart.cart_id)

        order_done(request, str(cart))
    
        user = user_info
        #Die Wagenverwaltung wird durch Eingabe eines negativen Werts anstelle einer logischen Löschung (Rätsel) implementiert.
        cart.cart_id = -cart.cart_id
        user.status = None
        cart.save()
        user.save()
        return Response(None) #Sie müssen nichts zurückgeben

###Kürzung###

Geben Sie die Warenkorb-ID an, indem Sie den int-Typ pk angeben

shop/urls.py



urlpatterns = [
    ###Kürzung###
    path('post_shop/<int:pk>', views.order_done_post_request,),  #hinzufügen
]

Das Obige ist der Inhalt, an dessen Implementierung ich einen Tag nach der Wiederbelebung von Android Studio hart gearbeitet habe. Als ich versuchte, einen Artikel auf diese Weise zu schreiben, wurde die Anzahl der Sätze sehr groß, obwohl viele Teile weggelassen wurden.

Zusammenfassung

Es dauert nur einen Tag, um eine so einfache Anwendung zu erstellen, und die Umgebungskonstruktion ist umständlich, sodass die Ingenieure jedes Mal beeindruckt sind. Diesmal war es Android, aber ich würde gerne bald mit iOS arbeiten. Es ist unmöglich, wenn Sie keinen neuen Computer kaufen. Es ist ein ziemlich chaotischer Artikel. Wenn Sie also Fragen haben, senden Sie diese bitte in den Kommentaren oder DM auf Twitter und wir werden sie beantworten! Bitte kommentieren Sie danach, ob Fehler oder Auslassungen vorliegen!

Gute Sommerferien für alle Studenten! !! !!

Recommended Posts

Erste Schritte mit Android!
1.1 Erste Schritte mit Python
Erste Schritte mit apache2
Erste Schritte mit Python
Erste Schritte mit Django 1
Einführung in die Optimierung
Erste Schritte mit Numpy
Erste Schritte mit Spark
Erste Schritte mit Python
Erste Schritte mit Pydantic
Erste Schritte mit Jython
Erste Schritte mit Django 2
Übersetzen Erste Schritte mit TensorFlow
Einführung in Python-Funktionen
Einführung in Tkinter 2: Button
Erste Schritte mit Go Assembly
Erste Schritte mit PKI mit Golang ―― 4
Erste Schritte mit Python Django (1)
Erste Schritte mit Python Django (4)
Erste Schritte mit Python Django (3)
Einführung in Python Django (6)
Erste Schritte mit Django mit PyCharm
Erste Schritte mit Python Django (5)
Erste Schritte mit Python Responder v2
Einführung in Git (1) History-Speicher
Erste Schritte mit Sphinx. Generieren Sie Docstring mit Sphinx
Erste Schritte mit Python-Webanwendungen
Erste Schritte mit Python für PHPer-Klassen
Erste Schritte mit Sparse Matrix mit scipy.sparse
Erste Schritte mit Julia für Pythonista
Erste Schritte mit Python Grundlagen von Python
Erste Schritte mit der Cisco Spark REST-API
Beginnend mit USD unter Windows
Erste Schritte mit genetischen Python-Algorithmen
Erste Schritte mit Python 3.8 unter Windows
Erste Schritte mit Python für PHPer-Funktionen
Erste Schritte mit der CPU-Diebstahlzeit
Grale fangen an
Erste Schritte mit Python3 # 1 Grundkenntnisse erlernen
Erste Schritte mit Python Web Scraping Practice
Erste Schritte mit Python für PHPer-Super Basics
Erste Schritte mit Python Web Scraping Practice
Erste Schritte mit Dynamo von Python Boto
Erste Schritte mit Lisp für Pythonista: Ergänzung
Erste Schritte mit Heroku, Bereitstellen der Flaschen-App
Erste Schritte mit TDD mit Cyber-dojo bei MobPro
Erste Schritte mit Python mit 100 Klopfen bei der Sprachverarbeitung
Django 1.11 wurde mit Python3.6 gestartet
MongoDB-Grundlagen: Erste Schritte mit CRUD mit JAVA
Erste Schritte mit dem Zeichnen mit matplotlib: Schreiben einfacher Funktionen
Erste Schritte mit der japanischen Übersetzung des Keras Sequential-Modells
[Übersetzung] Erste Schritte mit Rust für Python-Programmierer
Django Erste Schritte Teil 2 mit dem Eclipse Plugin (PyDev)
Beginnen Sie mit MicroPython
Erste Schritte mit AWS IoT in Python