Skip to content

EmirDelicR/Python-all

Repository files navigation

Python-all

content

intro

Awesome-Python-Git

Awesome-Django-Git

Official page

PyCharm

Check python version on linux

$ /usr/bin/python --version
Python 2.7.15rc1
$ /usr/bin/python3 --version
Python 3.6.7

Open python console

$ python3
>> print('Hello')
/* Exit the console */
>> exit()
/* To clear console  press CTRL+l */

Install PIP and Selenium

$ sudo apt-get install python3-pip
# Use:
$ pip3 -V

$ pip3 install selenium

Open python documentation from terminal

$ python -m pydoc <name of module (math)>
$ python -m pydoc <name of type (tuple)>
$ python -m pydoc <name of function (pow)>

# search module or keyword
$ python -m pydoc -k <pattern (ftp)>

# Open pydoc on server
$ sudo python -m pydoc -p <Port number>
$ sudo python -m pydoc -g

Install PyCharm

sudo snap install pycharm-community --classic

Virtual ENV

VE

$ sudo apt-get install python3-venv
$ python3 -m venv <name>

# activate virtual env
$ source <name>/bin/activate

# Install django
$ cd <name>
$ pip install django

# deactivate virtual env
$ deactivate

TOP

basic

Print:

>> print('Hello')

Division:

>> 100/25
>> Output: 4.0
>> 100//25
>> Output: 4

Math operation:

>> 100+25
>> Output: 125

>> 100*25
>> Output: 2500

>> 10**2
>> Output: 100

/* Root */
>> 4**(1/2)
>> Output: 2.0

>> int(4**(1/2))
>> Output: 2

/* Module */
>> 7%3
>> Output: 1

Strings:

String Methods

>> 'He\'s'
>> Output: "He's"
>> "He's"
>> Output: "He's"

>> a = "testing"
>> print(b[2:len(b)])
>> Output: sting

>> a = "   Hello   "
>> print(a.strip())
>> Output: "Hello"

>> a = "Hello"
>> print(len(a))
>> 5

>> print(a.lower())
>> Output: "hello"

>> print(a.upper())
>> Output: "HELLO"

>> print(a.replace("H", "J"))
>> Output: "Jello"

>> print(a.split("e"))
>> Output: ['h', 'llo']

/* Reverse string */
>> txt = "Hello World"[::-1]
>> print(txt)

/* Formating string */
>> some_date = [2, 12, 2018]
>> print("Date: {0}/{1}/{2}".format(some_date[0], some_date[1], some_date[2]))
>> Output: Date: 2/12/2018

>> print("{x}/{y}".format(x=100, y=10))
>> Output: 100/10

/* Check if sting start with some word */
>> text = "Start the ..."
>> print(text.startswith("Start"))
>> Output: True
>> print(text.endswith("..."))
>> Output: True

Bitwise operators:

The Operators:

x << y
Returns x with the bits shifted to the left by y places
(and new bits on the right-hand-side are zeros).
This is the same as multiplying x by 2**y.

x >> y
Returns x with the bits shifted to the right by y places.
This is the same as //'ing x by 2**y.

x & y
Does a "bitwise and". Each bit of the output is 1 if the
corresponding bit of x AND of y is 1, otherwise it's 0.

x | y
Does a "bitwise or". Each bit of the output is 0 if the
corresponding bit of x AND of y is 0, otherwise it's 1.

~ x
Returns the complement of x - the number you get by
switching each 1 for a 0 and each 0 for a 1.
This is the same as -x - 1.

x ^ y
Does a "bitwise exclusive or". Each bit of the output
is the same as the corresponding bit in x if that
bit in y is 0, and it's the complement of the bit
in x if that bit in y is 1.

Just remember about that infinite series of 1 bits in a negative number, and these should all make sense.

Logical operators:

  • and

  • or

  • not

Identity and membership operator

  • is - Returns true if both variables are the same object

  • in - Returns True if a sequence with the specified value is present in the object

Accepting input:

>> input('Enter value: ')
>> Enter value:
>> print('He\n s')
>> He
>>  s

>> value = input('Enter value: ')
>> print('This is your value: ', value)
>> del value
>> print(value) // error

In place operators:

>> a=10
>> a+=1
>> a
>> Output: 11
/* Apply this to all operators (*, -, //, / ...) */

TOP

control

If statement:

a = 18
if a > 18:
    print("Greater then 18")
elif a == 18: # != not equal
    print("Equal to 18")
else:
    print("Smaller then 18")

Range:

numbers = list(range(10))
print(numbers)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

numbers = list(range(3, 10))
print(numbers)
# [3, 4, 5, 6, 7, 8, 9]

numbers = list(range(3, 10, 3))
print(numbers)
# [3, 6, 9]

Functions:

Build-in Functions

def print_name(value = "John Doo"):
    print(value)


def get_name():
    return "Some name"


print_name()
# John Doo

print_name(get_name())
# Some name

Lambdas

A lambda function is a small anonymous function.

lambda arguments : expression

x = lambda a : a + 10
print(x(5))
# 15

x = lambda a, b : a * b
print(x(5, 6))
# 30

print((lambda x: x**2)(3))
# 9

For loop:

total = 0
for num in range(1, 10):
    total += num

print(total)


for num in range(6):
    if num == 3:
        # this will skip this iteration
        continue

    print(num)


for num in range(6):
    if num == 3:
        # this will break loop
        break

While loop:

i = 1
while i < 6:
  print(i)
  i += 1

# Can use break and continue here also

TOP

types

Lists:

List is a collection which is ordered and changeable. Allows duplicate members.

List methods

some_list = ["test", "test1", "test2"]
print("test" in some_list) # Prints true

# Add element to end
some_list.append("test3")

# Length
print(len(some_list))

# Add element to specific position
some_list.insert(2, "Test#")

# Remove element
some_list.remove("Test#")

# Remove last element (can pass index)
some_list.pop()

# Empty list
some_list.clear()

# Copy list
ne_list = some_list.copy()

# Reverse list
some_list.reverse()
# OR
print(some_list[::-1])

# Sort list
some_list.sort()

# Count element in list
fruits = ['apple', 'banana', 'cherry', 'cherry']
x = fruits.count("cherry") # x is 2

# Extend list with some new list
fruits = ['apple', 'banana', 'cherry']
cars = ['Ford', 'BMW', 'Volvo']
fruits.extend(cars)
# ['apple', 'banana', 'cherry', 'Ford', 'BMW', 'Volvo']

# Index of element
print(some_list.index("Test#"))

# Remove duplicates from list
some_list = ["test", "test1", "test2", "test"]

no_duplicates = list(set(some_list))
print(no_duplicates)

# List slicing
some_list = [1, 2, 3, 4, 5, 6, 7]
print(some_list[2:6])
# [3, 4, 5, 6]

print(some_list[:3])
# [1, 2, 3]

print(some_list[3:])
# [4, 5, 6, 7]

print(some_list[1:6:2])
# [2, 4, 6]

# List comprehensions
some_list = [x**2 for x in range(5)]
print(some_list)
# [0, 1, 4, 9, 16]

some_list = [x**2 for x in range(5) if x**2 % 2 == 0]
print(some_list)
# [0, 4, 16]

# Join is string function to use with list (Must only have strings)
some_date = ["A", "B", "C"]
print("/".join(some_date))
# A/B/C

# Map:
new_list = [1, 2, 3, 4, 5]
double_list = list(map(lambda x: x*2, new_list))
print(double_list)
# [2, 4, 6, 8, 10]

# Filters
new_list = [1, 2, 3, 4, 5]
double_list = list(filter(lambda x: x % 2 == 0, new_list))
print(double_list)
# [2, 4]

# Generators
# Generate list of random words
import random
import string


def random_word(word_length, element_length):
    letters = string.ascii_lowercase
    for i in range(element_length):
        yield ''.join(random.choice(letters) for i in range(word_length))


print(list(random_word(4, 5)))
# ['dtki', 'lazt', 'ioxf', 'ysfa', 'ztpq']

Tuples

Tuple is a collection which is ordered and unchangeable. Allows duplicate members.

Tuples methods

some_tuple = ("apple", "banana", "cherry")
print(some_tuple)

print(some_tuple[1])

Sets

Set is a collection which is unordered and unindexed. No duplicate members.

Sets methods

some_set = {"apple", "banana", "cherry"}
print(some_set)
# {'cherry', 'apple', 'banana'}

some_set.add("orange")
print(some_set)
# {'cherry', 'apple', 'orange', 'banana'}

some_set.update(["orange", "mango", "grapes"])
print(some_set)
# {'apple', 'mango', 'grapes', 'cherry', 'banana', 'orange'}

Dictionaries

Dictionary is a collection which is unordered, changeable and indexed. No duplicate members.

Dictionaries methods

some_dictionary =	{
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
print(some_dictionary)
print(some_dictionary["model"])


for x in some_dictionary.values():
    print(x)
# Ford Mustang 1964


for x, y in some_dictionary.items():
    print(x, y)

# brand Ford model Mustang year 1964

# Check if key exist
if "model" in thisdict:

TOP

oop

Classes-documentation

Class

class Person:

    # Initial object
    def __init__(self, name, text):
        self.name = name
        self.text = text

    def __getitem__(self, name):
        return getattr(self, name)

    def __setitem__(self, name, value):
        return setattr(self, name, value)

    def __delitem__(self, name):
        return delattr(self, name)

    def __contains__(self, name):
        return hasattr(self, name)

    def __add__(self, num):
        return "Sum of {0} and {1} is {2}".format(num[0], num[1], num[0] + num[1])

    def print_data(self):
        print("My name is {0} and text is {1}".format(self.name, self.text))


person = Person('Emir', 'This is text')

print("Name: " + person["name"])
# Name: Emir

print("Text: " + person["text"])
# Text: This is text

person['name'] = 'Emir Delic';
print("Item name: " + person["name"])
# Item name: Emir Delic

person.print_data()
# My name is Emir Delic and text is This is text

print("Contains key text: {0}".format('text' in person))
# Contains key text: True
del(person["text"])
print("Contains key text: {0}".format('text' in person))
# Contains key text: False

# Operator overloading (__add__ and all different function)
# is to change the behavior of operator

print(person + [2, 3])

Inheritance

class Student(Person):

    def __init__(self, obj):
        self.grades = obj
        # call constructor of super class
        super().__init__()


grades = {'Math': '5', 'Bio': '4'}
student = Student(grades)
print(student['grades'])
# {'Math': '5', 'Bio': '4'}

Private in class

class SomeClass:
    ## Just append __ before variable
    __hidden_variable = 0

TOP

modules

List of build-in modules

# my_module.py
def greeting(name):
  print("Hello, " + name)

person1 = {
  "name": "John",
  "age": 36,
  "country": "Norway"
}

# some_file.py
import my_module
my_module.greeting("Jonathan")
my_module.person1["age"]

# OR
import my_module as mx
mx.person1["age"]

# OR
from my_module import person1
person1["age"]


# List all modules (need to import)
help('modules')

# Print all existing build in modules
print(dir(__builtins__))

TOP

exception

Errors and Exceptions

try:
  print(x)
except:
  print("Something went wrong")
finally:
  print("The 'try except' is finished")

# Output:
# "Something went wrong"
# "The 'try except' is finished"

try:
  print(10/0)
except ZeroDivisionError as err:
    print("Zero error: {0}".format(err))
finally:
  print("The 'try except' is finished")

# Zero error: division by zero
# The 'try except' is finished

# Look file-reader for example

# manually rise exception
raise Exception('This is the error message.')

TOP

regex

Regex-documentation

import re

pattern = r"eggs"

# Must start with pattern
if re.match(pattern, "eggs eggs test"):
    print('Match found')
else:
    print('Match Not found')

# can be anywhere in string
if re.search(pattern, "eggs eggs test"):
    print('Match found')
else:
    print('Match Not found')

print(re.findall(pattern, "eggs eggs test"))
# ['eggs', 'eggs']

text = "My name is Emir, Hi Emir"
# . can replac any string exc(\n)
print(re.findall(r"E..r", text))
# ['Emir', 'Emir']

# ^ - means start of string and $ - is end of string

TOP

json

JSON Documentation

import json

# some string:
text = '{ "name":"John", "age":30, "city":"New York"}'
print("Type of variable text is: {0}".format(type(text)))
# parse text to JSON:
json_data = json.loads(text)
print(json_data)
print("Type of variable json_data is: {0}".format(type(json_data)))

# Convert back to string
json_dumps = json.dumps(json_data)
print(json_dumps)
print("Type of variable json_data is: {0}".format(type(json_dumps)))

# Print in nice way
print("Formatted json: ")
print(json.dumps(json_data, sort_keys=True, indent=4))


with open('test.json') as data_file:
    print("Type of variable data_file is: {0}".format(type(data_file)))
    data = json.load(data_file)

print("Type of variable data is: {0}".format(type(data)))
print(data)

test.json

{
  "maps": [
    {
      "id": "blabla",
      "iscategorical": "0"
    },
    {
      "id": "blabla",
      "iscategorical": "0"
    }
  ],
  "masks": {
    "id": "valore"
  },
  "om_points": "value",
  "parameters": {
    "id": "valore"
  }
}

TOP

url

# https://www.youtube.com/watch?v=LosIGgon_KM&index=2&list=LLXTQOhCUnflnafxq6fz73iQ

# Protocol: https, http, ftp ...

# Host: www.youtube.com

# Path: /watch

# Querystring: v=LosIGgon_KM&index=2&list=LLXTQOhCUnflnafxq6fz73iQ

# Fragment: comes after # - to navigate through single page

# python -m pydoc urllib

# contains

# request: open URLs
# response: (used internally)
# error: request exceptions
# parse: useful URL functions

# in console run python3
# import urllib
# dir(urllib)

TOP

date

DateTime Documentation

DateTime w3School

import datetime

x = datetime.datetime.now()
print(x.year)
print(x.strftime("%A"))

Scheduling Tasks

from datetime import datetime, timedelta
from threading import Timer

def calculate_schedule_time(time_to_schedule_in={'days':1, 'hours':0, 'minutes':0, 'seconds':0 }):
  current_date=datetime.now()

  delta = timedelta(
    days=time_to_schedule_in['days'],
    hours=time_to_schedule_in['hours'],
    minutes=time_to_schedule_in['minutes'],
    seconds=time_to_schedule_in['seconds'],
    microseconds=0,
  )

  to_execute_date = current_date + delta
  delta_t=to_execute_date-current_date

  print('Timer set in: ', delta_t)
  total_in_seconds=delta_t.total_seconds()

  return total_in_seconds

def schedule(time_in_secs, calback):
  t = Timer(time_in_secs, calback)
  t.start()

def hello_world():
    print("hello world")
    #...

time_to_schedule={'days':0, 'hours':0, 'minutes':0, 'seconds':30 }
timer = calculate_schedule_time(time_to_schedule)
schedule(timer, hello_world)

TOP

files

    create_path = os.path.join('usr', 'bin', 'spam') # usr/bin/spam

    print(os.path.abspath(path))

    print(os.path.basename(path)) # spam
    print(os.path.dirname(path)) # usr/bin
    print(os.path.split(path)) # returns tuple ('usr/bin', 'spam')
    print(path.split(os.path.sep)) # ['usr', 'bin', 'spam'] # os.path.sep = /


    cwd = os.getcwd() # current working directory
    os.chdir('C:/Data/Test')
    cwd = os.getcwd() # C:/Data/Test
    os.makedirs('C:/delicious/walnut/waffles')

    # set permissions on file
    import stat
    os.chmod(
        'waffles',
        stat.S_IRUSR |
        stat.S_IWUSR |
        stat.S_IRGRP |
        stat.S_IWGRP |
        stat.S_IROTH
    )

    os.getsize('C:/delicious/walnut/waffles.txt')
    os.listdir(cwd) # return array of directories

    os.path.exists(path) # return True or False # isdir, isfile

    # Read file
    with open(main, 'a+') as some_file: # r- read, w- write, a- append
        content_of_file = some_file.read()
        some_file.write('Text')
        print(content)

        # ctx = some_file.readlines() # return array of lines with \n
        # print(ctx)
        # for line in some_file: # can use loop also
        #  print(line)


    # r -   Opens a file for reading only. The file pointer is placed at
    #       the beginning of the file. This is the default mode.
    # rb -  Opens a file for reading only in binary format. The file
    #       pointer is placed at the beginning of the file. This is the default mode.
    # r+ -  Opens a file for both reading and writing. The file pointer will be at
    #       the beginning of the file.
    # rb+ - Opens a file for both reading and writing in binary format. The file pointer
    #       will be at the beginning of the file.
    # w -   Opens a file for writing only. Overwrites the file if the file exists. If the
    #       file does not exist, creates a new file for writing.
    # wb -  Opens a file for writing only in binary format. Overwrites the file if the file
    #       exists. If the file does not exist, creates a new file for writing.
    # w+ -  Opens a file for both writing and reading. Overwrites the existing file if the
    #       file exists. If the file does not exist, creates a new file for reading and writing.
    # wb+ - Opens a file for both writing and reading in binary format. Overwrites the existing
    #       file if the file exists. If the file does not exist, creates a new file for reading and writing.
    # a -   Opens a file for appending. The file pointer is at the end of the file if the file exists.
    #       That is, the file is in the append mode. If the file does not exist, it creates a new file for writing.
    # ab -  Opens a file for appending in binary format. The file pointer is at the end of the file
    #       if the file exists. That is, the file is in the append mode. If the file does not exist,
    #       it creates a new file for writing.
    # a+ -  Opens a file for both appending and reading. The file pointer is at the end of the file
    #       if the file exists. The file opens in the append mode. If the file does not exist,
    #       it creates a new file for reading and writing.
    # ab+ - Opens a file for both appending and reading in binary format. The file pointer is at the
    #       end of the file if the file exists. The file opens in the append mode. If the file does
    #       not exist, it creates a new file for reading and writing.

    # To store variables into file and not plain text use shelve module

    import shelve
    shelfFile = shelve.open('fileName')
    cats = ['Zophie', 'Pooka', 'Simon']
    shelfFile['cats'] = cats
    shelfFile.close()

    shelfFile = shelve.open('fileName')
    type(shelfFile) # <class 'shelve.DbfilenameShelf'>
    shelfFile['cats'] # ['Zophie', 'Pooka', 'Simon']
    shelfFile.close()

    shelfFile = shelve.open('fileName')
    list(shelfFile.keys()) # ['cats']
    list(shelfFile.values()) # [['Zophie', 'Pooka', 'Simon']]
    shelfFile.close()

Organizing Files

The shutil module provides functions for copying files, as well as entire folders.

import shutil, os

# copy single file
shutil.copy('C:/spam.txt', 'C:/delicious') # 'C:/delicious/spam.txt'
shutil.copy('eggs.txt', 'C:/delicious/eggs2.txt') # 'C:/delicious/eggs2.txt'

# copy all in folder
shutil.copytree('C:/bacon', 'C:/bacon_backup') # (from, to)

# move folder/rename
shutil.move('C:/bacon.txt', 'C:/eggs') # 'C:/eggs/bacon.txt'

# delete file
os.unlink(path)  # Calling os.unlink(path) will delete the file at path.

os.rmdir(path) # Calling os.rmdir(path) will delete the folder at path. This folder must be empty of any files or folders.

shutil.rmtree(path) # Calling shutil.rmtree(path) will remove the folder at path, and all files and folders it contains will also be deleted.

for filename in os.listdir():
    if filename.endswith('.txt'):
        #os.unlink(filename)
        print(filename)


# A much better way to delete files and folders is with the third-party send2trash module.
pip install send2trash

# check folder tree
for folderName, subfolders, filenames in os.walk(path):
    print('The current folder is ' + folderName)

    for subfolder in subfolders:
        print('SUBFOLDER OF ' + folderName + ': ' + subfolder)
    for filename in filenames:
        print('FILE INSIDE ' + folderName + ': '+ filename)

    print('')

ZIP

import zipfile, os

os.chdir('C:/') # move to the folder with example.zip
exampleZip = zipfile.ZipFile('example.zip')
exampleZip.namelist() # .zip file content ['spam.txt', 'cats/', 'cats/catnames.txt', 'cats/zophie.jpg']
spamInfo = exampleZip.getinfo('spam.txt')
spamInfo.file_size # 13908
spamInfo.compress_size # 3828

exampleZip.extractall() # extract all files in current directory, you can pass path

exampleZip.extract('spam.txt') # Extract single file in current directory
exampleZip.extract('spam.txt', 'C:/some/new/folders') # Extract to path
exampleZip.close()

# ZIP more files into already exiting ZIP file
newZip = zipfile.ZipFile('new.zip', 'w')
newZip.write('spam.txt', compress_type=zipfile.ZIP_DEFLATED)
newZip.close()

EXCEL

# TODO https://automatetheboringstuff.com/chapter12/
# https://openpyxl.readthedocs.io/en/stable/
# Add docs and small example

PDF and WORD

# TODO https://automatetheboringstuff.com/chapter13/
# http://www.blog.pythonlibrary.org/2018/06/07/an-intro-to-pypdf2/

CSV and JSON

# TODO https://automatetheboringstuff.com/chapter14/

TOP

trace

def memoize(f):
  cache = {}
  def helper(x):
      if x not in cache:
          cache[x] = f(x)
      return cache[x]
  return helper

def trace(f):
  f.indent = 0
  def helper(x):
      print('|  ' * f.indent + '|--', f.__name__, x)
      f.indent += 1
      value = f(x)
      print('|  ' * f.indent + '|--', 'return', repr(value))
      f.indent -= 1
      return value
  return helper

# this is same as calling trace(fib)
@memoize  # Order of decorators is important (executed first)
@trace # (excecuted second)
def fib(n):
    if n == 0 or n == 1:
      return 1

    return fib(n-1) + fib(n-2)

print(fib(4))

TOP

desktop

Tkinter documentation

Widget list

Tutorial

Install tkinter

$ sudo apt-get install python3-tk

** Look file Desktop-app **

TOP

django

Django docks Django CDRF

Navigate to folder like (Desktop)

(See django-project folder)

# Instal VE if you dont have
$ sudo apt-get install python3-venv
# Create VE with name of project
$ python3 -m venv <name>

# activate virtual env
$ source <name>/bin/activate

# Install django
$ cd <name>
$ pip install django

# check version
$ python -m django --version

# install django rest framework
$ pip install djangorestframework

# create django project
$ django-admin startproject <name (mysite)>
$ cd <name>

# create django app
# django-admin startapp - command ; app - name of app
$ django-admin startapp app

# folder structure
- mysite (rename this to server)
--- app
--- mysite
--- env

# copy urls folder from mysite to app

# deactivate virtual env
$ deactivate

TOP

urls

Set up URL

in mysite/urls

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include("app.urls")),
]

in app/urls

from django.urls import path
from django.views.decorators.csrf import csrf_exempt

from rest_auth.views import LogoutView, PasswordChangeView
from rest_framework import routers
from rest_framework.authtoken.views import obtain_auth_token

from . import views

router = routers.DefaultRouter()

urlpatterns = router.urls

urlpatterns += [
    path('', views.home, name='home'),
    path('admin/login/', obtain_auth_token),
    path('logout/', csrf_exempt(LogoutView.as_view())),
    path('password/change/', PasswordChangeView.as_view()),
    # To pass id to route
    # path('route/<str:id>', views.SomeView.as_view()),
]

Note - install missing dependency and add simple view

pip install django-rest-auth

TOP

view

Create an view

in app/views.py

def home(req):
    return HttpResponse("<h>This is home page</h>")

view-docs

ApiView

APIView

NOTE: Use this only if the view have GET function

from rest_framework.views import APIView
# in view.py check
class TestApiView(APIView):

Generic views

GenericView

from rest_framework import generics
# in view.py check
class ListCreateTodoView(generics.ListAPIView):
class TodoDetailView(generics.RetrieveUpdateDestroyAPIView):

View Set

ViewSet

from rest_framework import viewsets
# in view.py check
class TestModelViewSet(viewsets.ModelViewSet):

# in urls.py
router.register('test-model-view-set/', views.TestModelViewSet)
urlpatterns = router.urls

# To have access to default methods (list, create ...) add line above
| NAME          | METHOD        | CLIENT CALL                |
| ------------- |:-------------:| --------------------------:|
| list          | GET all       | "test-model-view-set/"     |
| create        | POST          | "test-model-view-set/"     |
| retrieve      | GET by ID     | "test-model-view-set/<id>" |
| update        | PUT           | "test-model-view-set/<id>" |
| partial_update| PATCH         | "test-model-view-set/<id>" |
| destroy       | DELETE        | "test-model-view-set/<id>" |

# To create an custom action
@action(detail=True, methods=['post'])
def set_todo(self, request, pk=None):
    return Response(status=status.HTTP_200_OK)

# form client call this URL
# `${baseUrl}test-model-view-set/${todoItem.id}/set_todo/`,
# If you have function
def save(self, *args, **kwargs):
# And you call function as
save(1,2,3,4,a=20,b=30,c=40)
# args = (1,2,3,4) # Tuple
# kwargs = {'a':20,'b':30,'c':40} # Dictionary

# *args - list of unnamed arguments
# **kwargs - dictionary (named arguments)

TOP

migrations

Applying migrations

python3 manage.py migrate

TOP

superuser

Create Superuser

python3 manage.py createsuperuser --email admin@example.com --username admin

TOP

requirements

Store and install requirements

$ pip freeze > requirements.txt
pip install -r requirements.txt

TOP

dependency

Add dependency

in mysite/settings.py

# Application definition

INSTALLED_APPS = [
    'app.apps.AppConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Add this
    'rest_framework',
    'rest_framework.authtoken',
    'rest_auth',
    'app.apps.AppConfig', # Form step django-admin startapp app
]

TOP

server

Run server

# navigate to startproject <name> (mysite)
$ .../mysite$ python3 manage.py runserver

go to : http://127.0.0.1:8000/api/

or go to : http://127.0.0.1:8000/admin/

TOP

models

Creating models

Django-models

in app/models.py

Create an base model look in todo-app/server/api/models

class Photo(models.Model):
    name = models.CharField(max_length=100)
    creator = models.CharField(max_length=100)
    price = models.CharField(max_length=100)

Register model to admin interface

Django-admin-site

in app/admin.py

# Register your models here.
from .models import Photo

# Use decorator to register
@admin.register(Photo)
class PhotoAdmin(admin.ModelAdmin):
    list_display = ('name', 'creator')
    search_fields = ('name')

# Other way to register
# admin.site.register(Photo)
# Every model can have function that returns string representation of any object
def __str__(self):
    # f"" is short way to format string
    return f"{self.city}"

Relations in models

address = models.OneToOneField(
    Address, verbose_name="user address" on_delete=models.SET_NULL, null=True, blank=True, related_name='user'
)
# verbose_name="user address" --> name in Django Admin
# on_delete=models.CASCADE || SET_NULL
# related_name='user' --> How to access from other model address.user

# ForeignKey (ManyToOne) goes on child like `One User Have Multi Todo`
# So put this on Todo model class
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='todo')

# ManyToMany
from django.db import models

class Topping(models.Model):
    # ...
    pass

class Pizza(models.Model):
    # ...
    toppings = models.ManyToManyField(Topping)

# In the above example, toppings is in Pizza (rather than Topping having a pizzas ManyToManyField )
# because it’s more natural to think about a pizza having toppings than a topping being on multiple pizzas.
# The way it’s set up above, the Pizza form would let users select the toppings.

Creating Abstract user

# in mytodoapp/settings.py
AUTH_USER_MODEL = 'api.User'

# in api/models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):

    def __str__(self):
        return f"{self.username}"

TOP

db

Set up postgres DB

pgadmin III

vim /etc/postgresql/10/main/pg_hba.conf


# Database administrative login by Unix domain socket
# TODO: set to trust
local   all             postgres                                trust

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
# TODO: set to trust
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 md5

service postgresql restart

login to

sudo -u postgres psql

Create DB

postgres=# CREATE DATABASE dbtest;

List all DB

postgres=# \l

Create user

postgres=# CREATE USER user WITH PASSWORD 'password';

Alter user role

postgers=# ALTER ROLE user SET client_encoding TO 'utf8';
postgers=# ALTER ROLE user SET default_transaction_isolation TO 'read committed';
postgers=# ALTER ROLE user SET timezone TO 'UTC';
postgres=# ALTER USER user CREATEDB;

postgres=# GRANT ALL PRIVILEGES ON DATABASE dbtest TO user;

Connect to DB

postgres=# \c testdb

List DB content

postgres=# \d

List data from table

postgres=# select * from <table-name>;

Exit from psql

postgres=# \q;

Make settings in settings.py file

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': OPTIONS['DATABASE_NAME'],
        'USER': '', # User created in upper step
        'PASSWORD': '', # User created in upper step
        'HOST': '',
        'PORT': '',
        'TEST': {
            'NAME': 'test_' + OPTIONS['DATABASE_NAME'],
        },
    }
}

Install postgres engine

pip install psycopg2-binary

If necessery

pip install psycopg2

migrate

Make and run new migration

Run command in terminal

# mysite$ is an folder
mysite$ python3 MY_ENV="DEVELOP" manage.py makemigrations app
# Output: app/migrations/0001_initial.py

# Run migration
mysite$ MY_ENV="DEVELOP" python3 manage.py migrate

TOP

terminal

Adding data from terminal

# mysite$ is an folder
mysite$ python manage.py shell

>>> from app.models import Photo

>>> Photo.objects.all()
>>> photo = Photo()
>>> photo.name = "Test"
>>> ... add rest
>>> photo.save()
>>> photo.name
>>> Output: 'Test'

Calling function from terminal

# in utils.py create function
def test_command(arg_1, arg_2):
    print("This is {} , and this is {}".format(arg_1, arg_2))
# mysite$ is an folder
mysite$ python manage.py shell

>>> from app.utils import test_command
>>> test_command('X', 'Y')

TOP

serializer

Creating serializer for model

Django-serializers

Rest-Framework-serializers

in app/models.py

Create an file app/serializers.py

from rest_framework import serializers
from .models import Photo


class PhotoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Photo
        fields = ("name", "creator", "price")

Some feature with serilizer

# in view add
class TestSerializerView(viewsets.ModelViewSet):
    # Adding ModelViewSet you get automaticly update, create, partial_update ect.
    # Now you can overwrite this function in serilizer

# Register route in urls.py
router.register('test-serializer', views.TestSerializerView)

# Create serilizer

class AddressSerializer(serializers.ModelSerializer):
    def create(self, validated_data):
        return Address.objects.create(**validated_data)

TOP

endpoint

Creating view for this endpoint

rest-generic-view

from rest_framework import generics
from .models import Photo
from .serializers import PhotoSerializer

class ListPhotoView(generics.ListAPIView):
    """
    Provides a get method handler.
    """
    queryset = Photo.objects.all()
    serializer_class = PhotoSerializer

Add route to urls.py

urlpatterns += [
  path('photos/', views.ListTodoView.as_view(), name="photos-all")
]

TOP

testing

Testing App

Look server/api/tests.py file

python3 manage.py test

TOP

decorators

Create decorators

Create decorators.py file

from rest_framework.response import Response
from rest_framework.views import status

def validate_request_data(fn):
    def decorated(*args, **kwargs):
        name = args[0].request.data.get("name", "")
        creator = args[0].request.data.get("creator", "")
        price = args[0].request.data.get("price", "")
        if not name and not creator and not price:
            return Response(
                data={
                    "message": "All fields for photo are necessary"
                },
                status=status.HTTP_400_BAD_REQUEST
            )
        return fn(*args, **kwargs)
    return decorated

TOP

tasks

Create custom tasks

Create management/commands/test.py file

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    def handle(self, *args, **kwargs):
        print("Execute helper function from commands")

To execute (! how you call file you need to call here)

python3 manage.py test

TOP

settings

Customize settings in main app

Set Environment on app

# in mysite/settings.py
MY_ENV = os.environ.get('MY_ENV')

if MY_ENV == 'DEVELOP' or MY_ENV == 'LOCAL':
    OPTIONS = {
        'DEBUG': True,
        'DATABASE_NAME': 'Some Db Name',
        'LOGPATH': '/var/log/log-file-name/',
    }
elif MY_ENV == 'PRODUCTION':
    OPTIONS = {
        'DEBUG': False,
        'DATABASE_NAME': 'rlb_essensmarken_production',
        'LOGPATH': '/var/log/rlb_essensmarken_production/',
    }
else:
    raise ValueError('Environment variable "MY_ENV" must be defined to be either DEVELOP or PRODUCTION. Current value: ' + str(MY_ENV))
MY_ENV='DEVELOP' python3 manage.py runserver

Can pass multi arguments

DEBUG_MODE=xxx API_SECRET=yyy python manage.py runserver

TOP

sentry

Set Sentry on app

Sentry-docks

Set-logger-with-sentry

Sign in to Sentry

pip install --upgrade sentry-sdk
import sentry_sdk
from sentry_sdk import configure_scope
from sentry_sdk.integrations.django import DjangoIntegration

sentry_sdk.init(
    dsn="DNS_KEY",
    integrations=[DjangoIntegration()],
    environment=MY_ENV.lower()
)

with configure_scope() as scope:
    scope.set_tag("API_VERSION", "SOME_API_VERSION")

TOP

setting

Set rest of the settings

DEBUG = OPTIONS['DEBUG']
ALLOWED_HOSTS = ['*']
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# Create other paths
MEDIA_ROOT = os.path.join('/data/media', 'file_name')
MEDIA_URL = '/media/'

MEDIA_PUBLIC_ROOT = os.path.join(MEDIA_ROOT, 'public')

Set rest_framework in the settings

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
    	# 'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
    	'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

TOP

swagger

Set Swagger REST API documentation

Swagger-docs

pip install -U drf-yasg
# in settings.py
INSTALLED_APPS = [
   ...
   'drf_yasg',
   ...
]

# in urls.py
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
   openapi.Info(
      title="Snippets API",
      default_version='v1',
      description="Test description",
      terms_of_service="",
      contact=openapi.Contact(email=""),
      license=openapi.License(name=""),
   ),
   public=True,
   permission_classes=(permissions.AllowAny,),
)

# Swagger documentation
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),

TOP

functions

Some useful functions

from django.db import connection

def print_sql_queries():
	indentation = 2
	print("%s\033[33mThe number of SQL Queries is: %s \n" % (" " * indentation, len(connection.queries)))

	if len(connection.queries) > 0:
		width = 240
		total_time = 0.0
		for query in connection.queries:
			nice_sql = query['sql'].replace('"', '').replace(',', ', ')
			sql = "\033[33mTime: \033[31m [%s]\n \033[33m Query: \033[34m%s" % (query['time'], nice_sql)
			total_time = total_time + float(query['time'])
			while len(sql) > width - indentation:
				print("%s%s" % (" " * indentation, sql[:width - indentation]))
				sql = sql[width - indentation:]
			print("%s%s\n" % (" " * indentation, sql))
		replace_tuple = (" " * indentation, str(total_time))
		print("%s\033[1;32m[TOTAL TIME: %s seconds]\033[0m" % replace_tuple)

# To use:
from app.utils import print_sql_queries
print_sql_queries()

TOP

client

Create an client side app

# mysite$ is an folder
mysite$ vue create client

mysite$ cd client

mysite$/client/ npm run serve

Set cors on server

pip install django-cors-headers
# in settings.py

from corsheaders.defaults import default_headers

INSTALLED_APPS = [
    ...
    'corsheaders'
]

# NOTE - Must be before 'django.middleware.common.CommonMiddleware',
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

CORS_ORIGIN_ALLOW_ALL = OPTIONS['CORS_ALLOWED'] # True or False

# If Up is True this will be ignored

CORS_ORIGIN_WHITELIST = [
    'http://localhost:8080',
]

# Need for Chrome

CORS_ALLOW_HEADERS = list(default_headers) + [
    'access-control-allow-origin',
]

links

extend-tutorial

tutorial

best-practice

heroku-publish

sql-queries-django

TOP

tips

Multi assignment

>>> x = y = z = 2
>>> x, y, z
(2, 2, 2)
>>> x, y, z = 2, 4, 8
>>> x
2
>>> y
4
>>> z
8
>>> x, *y, z = 2, 4, 8, 16
>>> x
2
>>> y
[4, 8]
>>> z
16

Merge Dictionaries

>>> x = {'u': 1}
>>> y = {'v': 2}
>>> z = {**x, **y, 'w': 4}
>>> z
{'u': 1, 'v': 2, 'w': 4}

Iterations

>>> for i, item in enumerate(['u', 'v', 'w']):
... print('index:', i, 'element:', item)
...
index: 0 element: u
index: 1 element: v
index: 2 element: w

Reversed Iteration

>>> for item in reversed(['u', 'v', 'w']):
... print(item)
...
w
v
u

Aggregate Elements

>>> x = [1, 2, 4]
>>> y = ('u', 'v', 'w')
>>> z = zip(x, y)
>>> z

>>> list(z)
[(1, 'u'), (2, 'v'), (4, 'w')]

Transpose Matrices

>>> x = [(1, 2, 4), ('u', 'v', 'w')]
>>> y = zip(*x)
>>> z = list(y)
>>> z
[(1, 'u'), (2, 'v'), (4, 'w')]

Unique Values

>>> x = [1, 2, 1, 4, 8]
>>> y = set(x)
>>> y
{8, 1, 2, 4}
>>> z = list(y)
>>> z
[8, 1, 2, 4]

Sort Sequences

>>> x = (1, 'v')
>>> y = (4, 'u')
>>> z = (2, 'w')
>>> sorted([x, y, z])
[(1, 'v'), (2, 'w'), (4, 'u')]

# OR SORT ON SECOND ELEMENT
>>> sorted([x, y, z], key=lambda item: item[1])
[(4, 'u'), (1, 'v'), (2, 'w')]

# REVERSED
>>> sorted([x, y, z], key=lambda item: item[1], reverse=True)
[(2, 'w'), (1, 'v'), (4, 'u')]

# SORT DICTIONARIES (KEYS)
>>> x = {'u': 4, 'w': 2, 'v': 1}
>>> sorted(x.items())
[('u', 4), ('v', 1), ('w', 2)]

# SORT DICTIONARIES (VALUES)
>>> sorted(x.items(), key=lambda item: item[1])
[('v', 1), ('w', 2), ('u', 4)]
>>> sorted(x.items(), key=lambda item: item[1], reverse=True)
[('u', 4), ('w', 2), ('v', 1)]

Anagrams

from collections import Counter

def anagram(first, second):
    return Counter(first) == Counter(second)


anagram("abcd3", "3acdb") # True

Memory

import sys

variable = 30
print(sys.getsizeof(variable)) # 24

Byte Size

def byte_size(string):
    return(len(string.encode('utf-8')))

byte_size('πŸ˜€') # 4
byte_size('Hello World')

Capitalize first letters

s = "programming is awesome"

print(s.title())

Chunk

This method chunks a list into smaller lists of a specified size.

def chunk(list, size):
    return [list[i:i+size] for i in range(0,len(list), size)]

Compact

This method removes falsy values (False, None, 0 and β€œβ€) from a list by using filter().

def compact(lst):
    return list(filter(None, lst))

compact([0, 1, False, 2, '', 3, 'a', 's', 34]) # [ 1, 2, 3, 'a', 's', 34 ]

Get vowels

def get_vowels(string):
    return [each for each in string if each in 'aeiou']

get_vowels('foobar') # ['o', 'o', 'a']
get_vowels('gym') # []

Decapitalize

def decapitalize(str):
    return str[:1].lower() + str[1:]

decapitalize('FooBar') # 'fooBar'
decapitalize('FooBar') # 'fooBar'

Flatten

The following methods flatten a potentially deep list using recursion.

def spread(arg):
    ret = []
    for i in arg:
        if isinstance(i, list):
            ret.extend(i)
        else:
            ret.append(i)
    return ret

def deep_flatten(xs):
    flat_list = []
    [flat_list.extend(deep_flatten(x)) for x in xs] if isinstance(xs, list) else flat_list.append(xs)
    return flat_list

deep_flatten([1, [2], [[3], 4], 5]) # [1,2,3,4,5]

Difference

This method finds the difference between two iterables by keeping only the values that are in the first one.

def difference(a, b):
    set_a = set(a)
    set_b = set(b)
    comparison = set_a.difference(set_b)
    return list(comparison)


difference([1,2,3], [1,2,4]) # [3]

Difference by

The following method returns the difference between two lists after applying a given function to each element of both lists.

def difference_by(a, b, fn):
    b = set(map(fn, b))
    return [item for item in a if fn(item) not in b]


from math import floor
difference_by([2.1, 1.2], [2.3, 3.4], floor) # [1.2]
difference_by([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], lambda v : v['x']) # [ { x: 2 } ]

Calculator without if-else

import operator
action = {
    "+": operator.add,
    "-": operator.sub,
    "/": operator.truediv,
    "*": operator.mul,
    "**": pow
}
print(action['-'](50, 25)) # 25

TOP