Saturday, June 19, 2021

Creating Basic Python C Extensions

According https://realpython.com/build-python-c-extension-module/

To write Python modules in C, you’ll need to use the Python API, which defines the various functions, macros, and variables that allow the Python interpreter to call your C code. All of these tools and more are collectively bundled in the <Python.h> header file.

Testing has been done on Fedora Linux 34 . Python version is 3.9.5 

 (.env) [boris@fedora33server ]$ cat fputsmodule.c

#include <Python.h>

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;

    /* Parse arguments */

    if(!PyArg_ParseTuple(args, "ss", &str, &filename)) {

        return NULL;

    }

    FILE *fp = fopen(filename, "w");

    bytes_copied = fputs(str, fp);

    fclose(fp);

    return PyLong_FromLong(bytes_copied);

}

static PyMethodDef FputsMethods[] = {

    {"fputs", method_fputs, METH_VARARGS, "Python interface for fputs C library function"},

    {NULL, NULL, 0, NULL}

};

static struct PyModuleDef fputsmodule = {

    PyModuleDef_HEAD_INIT,

    "fputs",

    "Python interface for the fputs C library function",

    -1,

    FputsMethods

};

PyMODINIT_FUNC PyInit_fputs(void) {

    return PyModule_Create(&fputsmodule);

}

(.env) [boris@fedora33server ]$ cat setup.py

from distutils.core import setup, Extension

def main():

    setup(name="fputs",

          version="1.0.0",

          description="Python interface for the fputs C library function",

          author="Boris D",

          author_email="BorisD@gmail.com",

          ext_modules=[Extension("fputs", ["fputsmodule.c"])])

if __name__ == "__main__":

    main()

(.env) [boris@fedora33server ]$ python3 setup.py install

(.env) [boris@fedora33server ]$ ll
total 12
drwxrwxr-x. 4 boris boris  63 Jun 19 19:30 build
-rw-rw-r--. 1 boris boris 796 Jun 19 19:08 fputsmodule.c
-rw-rw-r--. 1 boris boris 153 Jun 19 19:24 MyFputs.py
-rw-rw-r--. 1 boris boris 347 Jun 19 19:09 setup.py

(.env) [boris@fedora33server ]$ cat MyFputs.py
import fputs

# Write to an empty file named `output.txt`
fputs.fputs("Python is writing to file!", "./output.txt")
with open("./output.txt", "r") as f:
     print(f.read())

(.env) [boris@fedora33server ]$ python MyFputs.py
Python is writing to file!

Runtime snapshots











































(.env) [boris@fedora33server build]$ ls -CRl
.:
total 0
drwxrwxr-x. 2 boris boris 50 Jun 19 20:01 lib.linux-x86_64-3.9
drwxrwxr-x. 2 boris boris 27 Jun 19 20:01 temp.linux-x86_64-3.9

./lib.linux-x86_64-3.9:
total 28
-rwxrwxr-x. 1 boris boris 26720 Jun 19 20:01 fputs.cpython-39-x86_64-linux-gnu.so

./temp.linux-x86_64-3.9:
total 24
-rw-rw-r--. 1 boris boris 20832 Jun 19 20:01 fputsmodule.o

However, in the link above author doesn't focus your attention on
update required in static PyMethodDef myMethods[]  still having
"METH_NOARGS" instead of "METH_VARARGS", what actually confuses inexperienced learners. Following below is working code follows up link above, but  making  code sample easy to reproduce. Notice also that outside VENV you would have problems to run `python setup install`

(.env) [boris@fedora33server FIBONACHI]$ cat test.c

#include <Python.h>

int Cfib(int n)
{
    if (n < 2)
        return n;
    else
        return Cfib(n-1)+Cfib(n-2);
}

// Our Python binding to our C function
// This will take one and only one non-keyword argument
static PyObject *fib(PyObject* self, PyObject* args)
{
    // instantiate our `n` value
    int n;
    // if our `n` value
    if(!PyArg_ParseTuple(args, "i", &n))
        return NULL;
    // return our computed fib number
    

    int result = Cfib(n);
    return Py_BuildValue("i",result);
}

// Our Module's Function Definition struct
// We require this `NULL` to signal the end of our method
// definition
static PyMethodDef myMethods[] = {
    { "fib", fib, METH_VARARGS, "Calculate fibonacii value" },
    { NULL, NULL, 0, NULL }
};

// Our Module Definition struct
static struct PyModuleDef myModule = {
    PyModuleDef_HEAD_INIT,
    "myModule",
    "Test Module",
    -1,
    myMethods
};

// Initializes our module using our above struct
PyMODINIT_FUNC PyInit_myModule(void)
{
    return PyModule_Create(&myModule);
}

(.env) [boris@fedora33server FIBONACHI]$ cat setup.py
from distutils.core import setup, Extension
setup(name = 'myModule', version = '1.0',  \
   ext_modules = [Extension('myModule', ['test.c'])])

(.env) [boris@fedora33server FIBONACHI]python3 setup.py install

(.env) [boris@fedora33server FIBONACHI]$ cat MyProg.py
import myModule
a = int(input("Input number:"))
print(myModule.fib(a))

(.env) [boris@fedora33server FIBONACHI]$ python MyProg.py
Input number:11
89


Relatively complicated sample based on
and minor refactoring just to make things clear


(.env) [boris@sever33fedora enhancePython]$ cat demo.h
unsigned long cfactorial_sum(char num_chars[]);
unsigned long ifactorial_sum(long nums[], int size);
unsigned long factorial(long n);

(.env) [boris@sever33fedora enhancePython]$ cat demolib.c
#include <stdio.h>
#include "demo.h"


unsigned long cfactorial_sum(char num_chars[]) {
    unsigned long fact_num;
    unsigned long sum = 0;

    for (int i = 0; num_chars[i]; i++) {
        int ith_num = num_chars[i] - '0';
        fact_num = factorial(ith_num);
        sum = sum + fact_num;
    }
    return sum;
}

unsigned long ifactorial_sum(long nums[], int size) {
    unsigned long fact_num;
    unsigned long sum = 0;
    for (int i = 0; i < size; i++) {
        fact_num = factorial(nums[i]);
        sum += fact_num;
    }
    return sum;
}

unsigned long factorial(long n) {
    if (n == 0)
        return 1;
    return (unsigned)n * factorial(n-1);
}

(.env) [boris@sever33fedora enhancePython]$ cat demo.c   
#include <Python.h>
#include <stdio.h>
#include "demo.h"

// wrapper function for cfactorial_sum
static PyObject *DemoLib_cFactorialSum(PyObject *self, PyObject *args) {
    char *char_nums;
    if (!PyArg_ParseTuple(args, "s", &char_nums)) {
        return NULL;
    }

    unsigned long fact_sum;
    fact_sum = cfactorial_sum(char_nums);

    return Py_BuildValue("i", fact_sum);
}

// wrapper function for ifactorial_sum
static PyObject *DemoLib_iFactorialSum(PyObject *self, PyObject *args) {

    PyObject *lst; 

    if (!PyArg_ParseTuple(args, "O", &lst)) {
        return NULL;
    }

    int n = PyObject_Length(lst);
    if (n < 0) {
        return NULL;
    }

    long nums[n];
    for (int i = 0; i < n; i++) {
        PyLongObject *item = PyList_GetItem(lst, i);
        /* long num = PyLong_AsLong(item); */

        nums[i] = PyLong_AsLong(item);
    }

    unsigned long fact_sum;
    fact_sum = ifactorial_sum(nums, n);

    return Py_BuildValue("i", fact_sum);
}

// module's function table
static PyMethodDef DemoLib_FunctionsTable[] = {
    {
        "sfactorial_sum", // name exposed to Python
        DemoLib_cFactorialSum, // C wrapper function
        METH_VARARGS, // received variable args (but really just 1)
        "Calculates factorial sum from digits in string of numbers" // documentation
    }, {
        "ifactorial_sum", // name exposed to Python
        DemoLib_iFactorialSum, // C wrapper function
        METH_VARARGS, // received variable args (but really just 1)
        "Calculates factorial sum from list of ints" // documentation
    }, {
        NULL, NULL, 0, NULL
    }
};

// modules definition
static struct PyModuleDef DemoLib_Module = {
    PyModuleDef_HEAD_INIT,
    "demo",     // name of module exposed to Python
    "Demo Python wrapper for custom C extension library.", // module documentation
    -1,
    DemoLib_FunctionsTable
};

PyMODINIT_FUNC PyInit_demo(void) {
    return PyModule_Create(&DemoLib_Module);
}

(.env) [boris@sever33fedora enhancePython]$ cat setup.py
from setuptools import Extension, setup

module = Extension("demo",
                  sources=[
                    'demo.c',
                    'demolib.c'
                  ])
setup(name='demo',
     version='1.0',
     description='Python wrapper for custom C extension',
     ext_modules=[module])
     
(.env) [boris@sever33fedora enhancePython]$ python setup.py install

(.env) [boris@sever33fedora enhancePython]$ python MyProg.py
Callng sfactorial_sum("1234567") gives 
 5913
Calling ifactorial_sum([1,2,3,4,5,6,7]) gives 
 5913

Friday, June 18, 2021

GCC build of shared library to verify calling C-function from Python 3.9.5 module on Fedora 34 Linux (Server Edition)

 1) We are using "ctype" native Python module to load the shared library.

2) The ctype Python module is available starting with Python 2.5. Make sure you have the most recent Python installed on your system


 (.env) [boris@fedora33server CPYTHON]$ cat arithmatic.h
void connect();
int randNum();
int multNum(int a, int b);

(.env) [boris@fedora33server CPYTHON]$ cat arithmatic.c
#include <stdio.h>
#include <stdlib.h>
#include "arithmatic.h"
void connect()
{
   printf("Connected to C extension\n");
}
//return random value in range of 0-100
int randNum()
{
    int nRand = rand() % 100; 
    return nRand;
}
//Multiply two integer numbers and return value
int multNum(int a, int b)
{
    int nMult = a*b;
    return nMult;
}

That is supposed to run in one line, otherwise you have to place
"\" to let gcc know that the rest of line would go after cartridge return

(.env) [boris@fedora33server CPYTHON]$ gcc -shared -o libcalci.so -fPIC arithmatic.c

(.env) [boris@fedora33server CPYTHON]$ ll
total 28
-rw-rw-r--. 1 boris boris   291 Jun 18 19:23 arithmatic.c
-rw-rw-r--. 1 boris boris    57 Jun 18 18:34 arithmatic.h
-rwxrwxr-x. 1 boris boris 16280 Jun 18 19:31 libcalci.so
-rw-rw-r--. 1 boris boris   374 Jun 18 19:21 MyTest.py

(.env) [boris@fedora33server CPYTHON]$ cat  MyTest.py

from ctypes import *
libCalc = CDLL("./libcalci.so")
 
#call C function to check connection
libCalc.connect() 
 
#calling randNum() C function
#it returns random number
varRand = libCalc.randNum()
print ("Random Number:", varRand, type(varRand))
 
#calling multNum() C function
#it returns multiplication of two numbers
varMult = libCalc.multNum(38,27)
print ("Multiplication : ", varMult)


(.env) [boris@fedora33server CPYTHON]$ python  MyTest.py
Connected to C extension
Random Number: 83 <class 'int'>
Multiplication :  1026











A bit more complicated sample

(.env) [boris@fedora33server CDEVPY]$ cat sum.c
int our_function(int num_numbers, int *numbers) {
    int i;
    int sum = 0;
    for (i = 0; i < num_numbers; i++) {
        sum += numbers[i];
    }
    return sum;
}

(.env) [boris@fedora33server CDEVPY]$ gcc -fPIC -shared -o libsum.so sum.c

(.env) [boris@fedora33server CDEVPY]$ ll
total 28
-rwxrwxr-x. 1 boris boris 16160 Jun 18 21:35 libsum.so
-rw-rw-r--. 1 boris boris   107 Jun 18 21:33 MyRun.py
-rw-rw-r--. 1 boris boris   169 Jun 18 21:29 sum.c
-rw-rw-r--. 1 boris boris   345 Jun 18 21:29 sum.py

(.env) [boris@fedora33server CDEVPY]$ cat sum.py
import ctypes

_sum = ctypes.CDLL('./libsum.so')
_sum.our_function.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_int))

def our_function(numbers):
    global _sum
    num_numbers = len(numbers)
    array_type = ctypes.c_int * num_numbers
    result = _sum.our_function(ctypes.c_int(num_numbers), array_type(*numbers))
    return int(result)

(.env) [boris@fedora33server CDEVPY]$ cat  MyRun.py
import sum
def main():
    print (sum.our_function([11,2,-3,4,-3,6]))

if __name__=="__main__":
    main()
(.env) [boris@fedora33server CDEVPY]$ python  MyRun.py
17

(.env) [boris@fedora33server CDEVPY]$ ll
total 28
-rwxrwxr-x. 1 boris boris 16160 Jun 18 21:35 libsum.so
-rw-rw-r--. 1 boris boris   107 Jun 18 21:33 MyRun.py
drwxrwxr-x. 2 boris boris    32 Jun 18 21:36 __pycache__
-rw-rw-r--. 1 boris boris   169 Jun 18 21:29 sum.c
-rw-rw-r--. 1 boris boris   345 Jun 18 21:29 sum.py

PyCharm project based ctypes wrapper

Pretty short sample in C++

[boris@fedora33server ]$ ll
total 8
-rw-rw-r--. 1 boris boris 126 Jun 19 08:46 dullmath.cpp
-rw-rw-r--. 1 boris boris  79 Jun 19 08:52 MyProg.py

[boris@fedora33server ]$ cat dullmath.cpp
extern "C" int fibonacci(int n) {
  if (n <= 0) return 0;
  if (n == 1) return 1;
  return fibonacci(n-1) + fibonacci(n-2);
}

[boris@fedora33server]$ g++ -shared  dullmath.cpp -o   libdullmath.so

[boris@fedora33server ]$ ll
total 24
-rw-rw-r--. 1 boris boris   126 Jun 19 08:46 dullmath.cpp
-rwxrwxr-x. 1 boris boris 16176 Jun 19 08:52 libdullmath.so
-rw-rw-r--. 1 boris boris    79 Jun 19 08:52 MyProg.py

[boris@fedora33server]$ cat MyProg.py
import ctypes

lib = ctypes.CDLL(f'./libdullmath.so')
print(lib.fibonacci(11))

[boris@fedora33server ]$ python MyProg.py
89

One more sample

[boris@fedora33server ]$ cat function.c
int myFunction(int num)
{
    if (num == 0)
 
        // if number is 0, do not perform any operation.
        return 0;
    else
        // if number divides by 11, return 1 else return 0
          return (num % 11 == 0 ? 1 : 0) ;
 
}
[boris@fedora33server ]$ gcc -fPIC -shared -o libfun.so function.c
[boris@fedora33server ]$ ll libfun.so
-rwxrwxr-x. 1 boris boris 16168 Jun 19 10:31 libfun.so

[boris@fedora33server ]$ cat MyProg.py

import ctypes
  
test_text = input ("Введите число: ")
test_number = int(test_text)

# libfun loaded to the python file
# using fun.myFunction(),
# C function can be accessed
# but type of argument is the problem.
                        
fun = ctypes.CDLL("./libfun.so")  

# Now whenever argument
# will be passed to the function                                                       
# ctypes will check it.
           
fun.myFunction.argtypes = [ctypes.c_int]
 
returnVale = fun.myFunction(test_number)  
print(returnVale)

[boris@fedora33server ]$ python MyProg.py
Введите число: 121
1
[boris@fedora33server ]$ python MyProg.py
Введите число: 555
0
[boris@fedora33server ]$ python MyProg.py
Введите число: 550
1


REFERENCES

Saturday, May 22, 2021

PostgreSQL 13.2 on Server Fedora 34

UPDATE 05/23/2021

As appears author@YandexZen gave the name of database to table inside it "students". I just couldn't expect such kind of database design, which breaks pretty much common approach - never give the table in database the name exactly matching database name.

END UPDATE

Original post Библиотека PyQT5. Работа с базой данных PostgreSql (библиотека psycopg2) 

Fixes have been done to mentioned above post @Yandex Zen

Critical errors have been colored blue. Code Fix in Python :-

  def con(self):

        self.conn = psycopg2.connect(user = "postgres",

                              password = "*******",

                              host = "127.0.0.1",

                              port = "5432",

                              database = "db1")


Following setup is completely skipped in original post what obviously demonstrates, that posted code has never been running on real box.  

*************************************************

 Database Setup PostgreSQL 13.2 on Server Fedora 34

*************************************************

sudo dnf module -y install postgresql:13/server

sudo postgresql-setup --initdb

sudo systemctl enable --now postgresql

$ sudo dnf install python-psycopg2

$ sudo vi /var/lib/pgsql/data/pg_hba.conf

Replacement in field auth-method  "ident" by "md5"

$ sudo systemctl restart postgresql.service

$ sudo -u postgres psql

[sudo] password for boris: 

psql (13.2)

Type "help" for help.

postgres=# create database db1 encoding 'UTF8';

CREATE DATABASE

postgres=# grant all privileges on database db1 to postgres;

GRANT

postgres=# SELECT datname FROM pg_database;

  datname  

-----------

 postgres

 template1

 template0

 db1

(4 rows)

postgres=# \c db1

db1=# create table students  ( id SERIAL PRIMARY KEY, name VARCHAR,ocenka INT);

postgres=# alter user postgres  with encrypted password '*******';

[boris@fedora33server ~]$ hostnamectl

 Static hostname: fedora33server.localdomain

       Icon name: computer-desktop

         Chassis: desktop

      Machine ID: fec5966968d24022ad7f9f058b866d8a

         Boot ID: 380bfb1a5feb4930b00c63dbb4b96891

Operating System: Fedora 34 (Server Edition)      

     CPE OS Name: cpe:/o:fedoraproject:fedora:34

          Kernel: Linux 5.12.5-300.fc34.x86_64

    Architecture: x86-64

 Hardware Vendor: ASUS

  Hardware Model: All Series

[boris@fedora33server ~]$ sudo systemctl status postgresql.service

● postgresql.service - PostgreSQL database server

     Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; vendor preset: d>

     Active: active (running) since Sat 2021-05-22 18:41:52 MSK; 1h 37min ago

    Process: 9560 ExecStartPre=/usr/libexec/postgresql-check-db-dir postgresql (code=exite>

   Main PID: 9562 (postmaster)

      Tasks: 8 (limit: 38409)

     Memory: 29.8M

        CPU: 1.207s

     CGroup: /system.slice/postgresql.service

             ├─9562 /usr/bin/postmaster -D /var/lib/pgsql/data

             ├─9563 postgres: logger

             ├─9565 postgres: checkpointer

             ├─9566 postgres: background writer

             ├─9567 postgres: walwriter

             ├─9568 postgres: autovacuum launcher                                          

             ├─9569 postgres: stats collector                                              

             └─9570 postgres: logical replication launcher

May 22 18:41:52 fedora33server.localdomain systemd[1]: Starting PostgreSQL database server>

May 22 18:41:52 fedora33server.localdomain postmaster[9562]: 2021-05-22 18:41:52.852 MSK [>

May 22 18:41:52 fedora33server.localdomain postmaster[9562]: 2021-05-22 18:41:52.852 MSK [>

May 22 18:41:52 fedora33server.localdomain systemd[1]: Started PostgreSQL database server.

lines 1-22/22 (END)

REFERENCES

https://server-gu.ru/add-user-postgres/

https://computingforgeeks.com/install-postgresql-13-on-fedora/










Saturday, May 8, 2021

Решение задачи №18 340 Варианта Ларина

 Условие



Не надо бояться частных производных у неявно заданных функций, иначе 

dy/dt =d((a^2-t^2)^(1/2))/dt = (-t)*(a^2-t^2)^(-1/2) 

принесет больше головной боли. 

Система после замены t=(x+6)

Решение :-

После замены    t=(x+6) система имеет вид

(1) |y| = -t^2 +9

(2) t^2+y^2 = a^2

Поскольку :-











В точке касания окружности и параболы

при y >0 (1) y = -t^2+9 имеем

∂y/∂t = -(∂(y^2+t^2-a^2)/∂t)/(∂(y^2+t^2-a^2)/∂y) = -t/y

-2t = -t/y => y=1/2

Из (1) t^2=9 -y , то есть

t^2 = 9-1/2 = 17/2

a^2 = t^2+y^2=17/2+1/4 = 35/4

|a| =(35)^(1/2)/2


















Ответ :  (35)^(1/2)/2 < |a| <= 3







Tuesday, April 6, 2021

SQLITE3 Database administration via PyQT5 Framework in PyCharm 3.5 Environment .

 Per https://en.wikipedia.org/wiki/PyQt

PyQt is a Python binding of the cross-platform GUI toolkit Qt, implemented as a Python plug-in. PyQt is free software developed by the British firm Riverbank Computing. It is available under similar terms to Qt versions older than 4.5; this means a variety of licenses including GNU General Public License (GPL) and commercial license, but not the GNU Lesser General Public License (LGPL). PyQt supports Microsoft Windows as well as various flavours of UNIX, including Linux and MacOS (or Darwin). PyQt implements around 440 classes and over 6,000 functions and methods including: a substantial set of GUI widgets, classes for accessing SQL databases (ODBC, MySQL, PostgreSQL, Oracle, SQLite) QScintilla, Scintilla-based rich text editor widget data aware widgets that are automatically populated from a database an XML parser SVG support classes for embedding ActiveX controls on Windows (only in commercial version)












































making minor changes to original code on Fedora 33 Server having previously enabled PyQT5 support by PyCharm

[boris@fedora33server PYQT]$ cat sqlcreate.py
import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
con = QSqlDatabase.addDatabase("QSQLITE")
con.setDatabaseName("contacts.sqlite")

if not con.open():
    print("Database Error: %s" % con.lastError().databaseText())
    sys.exit(1)

# Create a query and execute it right away using .exec()
createTableQuery = QSqlQuery()
createTableQuery.exec(
    """
    CREATE TABLE contacts (
        id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
        name VARCHAR(40) NOT NULL,
        job VARCHAR(50),
        email VARCHAR(40) NOT NULL
    )
    """
)
print(con.tables())

Loading data into created table

[boris@fedora33server PYQT]$ cat sql02.py
from PyQt5.QtSql import QSqlQuery, QSqlDatabase

con = QSqlDatabase.addDatabase("QSQLITE")
con.setDatabaseName("contacts.sqlite")
con.open()
insertDataQuery = QSqlQuery()
insertDataQuery.prepare(
    """
    INSERT INTO contacts (
        name,
        job,
        email
    )
    VALUES (?, ?, ?)
    """
)
data = [
    ("Joe", "Senior Web Developer", "joe@example.com"),
    ("Lara", "Project Manager", "lara@example.com"),
    ("David", "Data Analyst", "david@example.com"),
    ("Jane", "Senior Python Developer", "jane@example.com"),
]
# Use .addBindValue() to insert data
for name, job, email in data:
    insertDataQuery.addBindValue(name)
    insertDataQuery.addBindValue(job)
    insertDataQuery.addBindValue(email)
    insertDataQuery.exec()

[boris@fedora33server PYQT]$ cat sqliteditor.py
import sys

from PyQt5.QtCore import Qt
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel
from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QMessageBox,
    QTableView,
)
class Contacts(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("QTableView Example")
        self.resize(415, 200)
        # Set up the model
        self.model = QSqlTableModel(self)
        self.model.setTable("contacts")
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model.setHeaderData(0, Qt.Horizontal, "ID")
        self.model.setHeaderData(1, Qt.Horizontal, "Name")
        self.model.setHeaderData(2, Qt.Horizontal, "Job")
        self.model.setHeaderData(3, Qt.Horizontal, "Email")
        self.model.select()
        # Set up the view
        self.view = QTableView()
        self.view.setModel(self.model)
        self.view.resizeColumnsToContents()
        self.setCentralWidget(self.view)

def createConnection():
    con = QSqlDatabase.addDatabase("QSQLITE")
    con.setDatabaseName("contacts.sqlite")
    if not con.open():
        QMessageBox.critical(
            None,
            "QTableView Example - Error!",
            "Database Error: %s" % con.lastError().databaseText(),
        )
        return False
    return True

app = QApplication(sys.argv)
if not createConnection():
    sys.exit(1)
win = Contacts()
win.show()
sys.exit(app.exec_())


Wednesday, February 3, 2021

Решение задачи №16 Демо ЕГЭ Информатика 2021 (Python)

Единственная цель кода на Python, приведенного ниже, - не дать детям выполнять прямые вычисления, которые, на самом деле, скорее скучны, чем трудны. Я просто пытаюсь научить своих учеников довольно старому принципу «Just think first». 

Условие задачи

 









Решение 















Заметим, что вычислить F(46) так же несложно как и F(26)















Смотри детально объяснение синтаксиса

www.freecodecamp.org/news/if-name-main-python-example/#:~:text=We%20can%20use%20an%20if,name%20if%20it%20is%20imported.

https://stackoverflow.com/questions/28336627/if-name-main-python  

Saturday, January 30, 2021

Попытка решить №26,27 демо-версии КЕГЭ по информатике 2021

UPDATE 01/02/2021

Решение Джобса верно в контексте вызова f.readline().split()  я ошибся при копировании его кода. Однако, ошибка в коде Джобса всеже есть , хотя вполне тривиальная. Нарушен приоритет операций "-" и "%" :   

if p1 - p2%3 != 0 and p1 - p2 < dx:  

Корректировка :   if (p1-p2)%3 !=0 and p1 - p2 < dx:

Очевидно, что выполнение кода со скриншота ниже верного результата дать в принципе не может. Предложен другой вариант кода, обходящий вызов f.readline().split() и корректировкой описанной выше. Мое решение мне нравится, но не более того

END UPDATE 

Следую https://www.youtube.com/watch?v=zGYqPsUB-S4&feature=emb_logo



Среда Python 3.9.1 Linux Fedora 33 Server

Копирую код из видео


































Пишем другой код

Исходные данные
Выполняем


Все тоже касается задачи 26
Меняем код , который блокирует Python 3.9.1





Выполняем