How to use Python Kivy ③-Linkage with WebAPI (from sending and receiving requests to displaying a list of results, transitioning multiple screens)-

Summary

The past two articles ("Kv Language Basics", "[Create a Calculator](http://qiita.com/dario_okazaki/items/" 910abf09344a60dd7823) ”) I think Kivy has made it possible to create an app with a simple screen. This time, we will create a multi-screen (2-screen) application.

What to create

This time, what we will create uses WebAPI to send and receive search conditions and their results. Lists the results so that you can see the detailed contents of the selected item. Below is the actual screen.

Startup screen (list display)

1_50.jpg

Details screen

2_50.jpg

From the list view, drag the screen to the right or click the "Details" button on the action bar to slide the details screen from the side. No items are displayed because I have not searched.

Actual search results

3_50.jpg

This is the result of entering the conditions in the search form and pressing the "Search" button. A list of search results is displayed below the search form in a list of book titles. Click an item to automatically move to the details screen.

Details screen (when search results are selected)

4_50.jpg

The book title and associated information are displayed on the details screen. If you drag the screen to the left or select the "List" button at the top right of the action bar, Return to the list screen

List screen (when transitioning from search terms and details screen)

5_50.jpg

When you return to the list screen, you can see that the item selected from the list is in the selected state (red frame).

What to learn anew

The contents to be newly learned are as follows.

However, this time we will use ListView because 1.9.2 has not been released and the specification of RecycleView is not clear. Similarly, Adapters is currently not recommended because it is under development, but we will use it because no alternative API has been presented.

Reference link

I will give you a reference.

A video explanation of ListView.

About what to search

This time, we will use the External API of the National Diet Library search. If you assemble and send a search query called CQL, the collection results will be returned. However, it is quite troublesome to assemble CQL from scratch, and this time I want to mainly handle the data sent and received as a result, so I will use this. The contents of the library are to assemble a CQL search query in Python and send and receive search results using the Python library requests to display the results.

reference

About the program

There are various ways to write code using Kivy. This is just an example. Also, the source code used when writing this article is listed on Github. However, materials such as fonts and images are not placed, so please prepare and place them yourself if necessary.

Verification environment

The verification environment is as follows.

OS: Windows10 64bit Kivy:1.9.1

Python3.4※

Below, I will actually post the code and results.

code

The code on the Python side is as follows.

main.py


#-*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty, ListProperty
from kivy.uix.listview import ListItemButton
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path


#National Diet Library Search Externally Provided Interface (API)
from pyndlsearch.client import SRUClient
from pyndlsearch.cql import CQL

#Change the default font
resource_add_path('./fonts')
#resource_add_path('/storage/emulated/0/kivy/calc/fonts')
LabelBase.register(DEFAULT_FONT, 'mplus-2c-regular.ttf') #Specify a Japanese font so that Japanese can be used


class BookButton(ListItemButton):
    ''' search_Make the result (ListView) item a button'''
    book = ListProperty()

class SearchBookForm(BoxLayout):
    search_input = ObjectProperty()
    search_results = ObjectProperty()   #search on the kv file side_Monitor results (ListView)

    def __init__(self, **kwargs):
        super(SearchBookForm, self).__init__(**kwargs)


    def books_args_converter(index, data_item):
        '''Convert the search result to dictionary type with book name as key.
It is called and executed for each record of the search result.
        '''
         
        title, creater , language, publisher = data_item
        return {'book': (title, creater , language, publisher )}

    def search_book(self):
        '''Search based on search conditions and store the results in ListView'''
    
        print('search_book')
        
        cql = CQL()
        
        #★ Enter search conditions
        cql.title = self.search_input.text

        year  = self.ids['year'].text
        month = self.ids['month'].text
        day = self.ids['day'].text


        cql.fromdate = year + '-' + month + '-' + day #Publication date
        #cql.fromdate = '2000-10-10'
        #print(cql.payload())
        #cql.title = 'Python'
        #cql.fromdate = '2000-10-10'
        #NDL Search Client Settings
        
        client = SRUClient(cql)
        client.set_maximum_records(int(self.ids['number'].text))  #Maximum number of acquisitions
        #★ End of search condition input
        
        #client.set_maximum_records(10)  #Maximum number of acquisitions
        #print(client)

        # get_response()Can be obtained in xml format
        #res = client.get_response()
        #print(res.text)

        #Execute SRU (Execute search based on input conditions)
        srres = client.get_srresponse()

        #Store search results in books list
        books = [(d.recordData.title, d.recordData.creator, d.recordData.language, d.recordData.publisher) for d in srres.records]
        print(books)
        
        print("----------------")
        #Store in search results
        
        self.search_results.adapter.data.clear()       #Delete search results data (for detailed display)
        self.search_results.adapter.data.extend(books) #Add search results to data
        self.search_results._trigger_reset_populate()  # search_results(list_view) refresh
        

class BookInfo(BoxLayout):
    '''Details screen information'''
    book = ListProperty(['', '','',''])

class BookSearchRoot(BoxLayout):

    def __init__(self, **kwargs):
        super(BookSearchRoot, self).__init__(**kwargs)

    def show_book_info(self, book):
        '''Format the selected information and move to the details screen to display'''
        print('BookSearchRoot')
    
        print(book) #Book = BookButton()For checking if the value of
        
        #If None is entered in the Text of Label, an error will occur, so conversion is performed.
        book_convs = [x if x != None else '' for x in book] #If None is returned""Change to

        #Store book information on the details screen
        self.bookinfo.book = book_convs
        
        #Move to details screen
        self.carousel.load_slide(self.bookinfo)

class BookSearchApp(App):

    def __init__(self, **kwargs):
        super(BookSearchApp, self).__init__(**kwargs)

        self.title = 'National Diet Library Search'
    pass

if __name__ == '__main__':
	BookSearchApp().run()

Kv file

The Kv Language is as follows.

bookSearch.kv


#: import main main
#: import ListAdapter kivy.adapters.listadapter.ListAdapter

#Widget displayed at startup
BookSearchRoot  

<BookSearchRoot>
    #List screen
    carousel: carousel
    booklists: booklists
    bookinfo:  bookinfo

    BoxLayout:
        orientation: "vertical"
        ActionBar:
            ActionView:
                ActionPrevious:
                    title: "National Diet Library Search"
                    with_previous: False
                    app_icon: "./icon/32player.png "

                ActionButton:
                    text: "List"
                    
                    #Move to the list screen
                    on_press: app.root.carousel.load_slide(app.root.booklists)
                ActionButton:
                    text: "Details"
                    
                    #Go to the details screen
                    on_press: app.root.carousel.load_slide(app.root.bookinfo)

        Carousel:
            id: carousel
            SearchBookForm:  #List screen
                id: booklists
            BookInfo:           #Details screen
                id: bookinfo

<SearchBookForm>
    #List screen layout
    orientation: "vertical"
    search_input: search_box    #① Add a class variable. By doing this, self on the Python side.search_input can be taken
    search_results: search_results_list

    #Search form
    BoxLayout:
        height: "40dp"
        size_hint_y: None
        TextInput:
            id: search_box  #② You can pass the value with "①"
            size_hint_x: 70
        Button:
            text: "Search"
            size_hint_x: 30
            on_press: root.search_book()

    BoxLayout:
        size_hint:1,.1

        Label:
            size_hint: .2,1
            text: "Publication date"

        Spinner:    #List of years
            id: year
            size_hint: .1,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'2000'
            values: [str(y) for y in range(2000, 2018) ]

        Label:
            size_hint: .05,1
            text: "Year"

        Spinner:
            id: month   #List of months
            size_hint: .05,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'01'
            values: ['{0:02d}'.format(x)  for x in range(1,13)]

        Label:
            size_hint: .05,1
            text: "Month"

        Spinner:    #List of days
            id: day
            size_hint: .05,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'01'
            values: ['{0:02d}'.format(x)  for x in range(1,30)] #Processing that changes the day every month is required, but temporarily suspended

        Label:
            size_hint: .05,1
            text: "Day"


        Label:
            size_hint: .05,1
            text: "number"

        Spinner:    #Monthly size
            id: number
            size_hint: .05,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'10'
            values: ['1','5','10', '15', '20'] 


    ListView:
        id: search_results_list
        adapter:
            #List search results and use items as buttons
            # data =Keep a list of searches in a list
            # CLS  =List display format (This time, it is displayed as a button)
            # args_converter =Convert the display result to a list with the book name as the key.
            ListAdapter(data=[], cls=main.BookButton, args_converter=main.SearchBookForm.books_args_converter)

<BookButton>
    #Layout with search results as buttons
    text_size: self.size
    halign: 'left'

    text: self.book[0]  #Make the book name the title of the button

    height: "40dp"
    size_hint_y: None
    on_press: app.root.show_book_info(self.book)



<BookInfo>
    #search results
    book: ("","","","")
    orientation: "vertical"


    BoxLayout:
        orientation: "horizontal"
        size_hint_y: None
        height: "40dp"


    GridLayout:
        cols: 2
        rows: 4

        Label:
            text: "title"
            halign: 'left'
            valign: 'middle'
            size_hint_x: 20
            text_size:self.size

        Label:
            text_size:self.size
            halign: 'left'
            valign: 'middle'
            text:root.book[0]
            size_hint_x: 80

        Label:
            text: "author"
            halign: 'left'
            valign: 'middle'
            size_hint_x: 20
            text_size:self.size

        Label:
            text: root.book[1]
            size_hint_x: 80
            text_size:self.size
            halign: 'left'
            valign: 'middle'

        Label:
            text: "the publisher"
            halign: 'left'
            valign: 'middle'
            size_hint_x: 20
            text_size:self.size

        Label:
            text: root.book[3]
            size_hint_x: 80
            #text: "the publisher:{} ".format(root.book[3])
            text_size:self.size
            halign: 'left'
            valign: 'middle'


        Label:
            text: "language"
            halign: 'left'
            valign: 'middle'
            size_hint_x: 20
            text_size:self.size

        Label:
            text: root.book[2]
            size_hint_x: 80
            text_size: self.size
            halign: 'left'
            valign: 'middle'

Commentary

The discussion starts with Kv Language.

About "Book Search Root" widget

At startup, the "Book Search Root" widget is displayed. "Book Search Root" is roughly divided into two widgets.

The corresponding Kv is as follows.

The corresponding code is as follows.

```python
<BookSearchRoot>
 #List screen
    carousel: carousel
    booklists: booklists
    bookinfo:  bookinfo

    BoxLayout:
        orientation: "vertical"
        ActionBar:
            ActionView:
                ActionPrevious:
 title: "National Diet Library Search"
                    with_previous: False
                    app_icon: "./icon/32player.png "

                ActionButton:
 text: "list"
                    
 # Move to the list screen
                    on_press: app.root.carousel.load_slide(app.root.booklists)
                ActionButton:
 text: "Details"
                    
 # Go to the details screen
                    on_press: app.root.carousel.load_slide(app.root.bookinfo)

        Carousel:
            id: carousel
 SearchBookForm: # List screen
                id: booklists
 BookInfo: #Detail screen
                id: bookinfo

###About Carousel

Carousel is a widget that switches screens (slides) by swiping. This time, 2 screens (SearchBookForm,BookInfo) is operated. The usage is operated using the widget name and id. You can also swipe the screen you want to show automatically by doing the following.

 carousel.load_slide (id of the slide you want to display)

There are other properties such as changing the switching speed, so please refer to the API reference for details.

reference

Last time, "clear" was used to switch screens._widgets()Screen using(widget)Once deleted, "add"_widgets()Screen using(widget)is created. The problem with this method isIt is difficult to return to the previous screen. It is also difficult to keep the value because the widget is deleted. By using Carousel, you can switch between multiple screens while holding the value on each screen.

###Action bar

The action bar at the top of the screen is the following screen.

action_bar.jpg

The corresponding code is as follows.

        ActionBar:
            ActionView:
                use_separator: True
                ActionPrevious:
 title: "National Diet Library Search"
                    with_previous: False
                    app_icon: "./icon/32player.png "

                ActionButton:
 text: "list"
                    
 # Move to the list screen
                    on_press: app.root.carousel.load_slide(app.root.booklists)
                ActionButton:
 text: "Details"
                    
 # Go to the details screen
                    on_press: app.root.carousel.load_slide(app.root.bookinfo)

Of these, the title part on the left side of the screen, but this time App_A unique icon is specified for icon and displayed. As for the icon material, the size of the original Kivy icon is 32px x 32px, so I learned the size.

You can also move to each screen by pressing the button.

As you can see by running this program, even if you switch the list display or screen from the list to details, the ActionBar part will continue to be displayed without disappearing from the screen. this isThis is because BoxLayout is used to separate the ActionBar and Carousel parts. Screen switching and list display of search results are displayed on Carousel.

###About SearchBookForm

SearchBookForm can be roughly divided into two. One is the search form part for entering search conditions, and the other is the part for displaying a list of search results.

####About the search form part

The screen is as follows.

form.jpg

The Kv parts that make up the form are as follows.

 # Search form
    BoxLayout:
        height: "40dp"
        size_hint_y: None
        TextInput:
 id: search_box # ② You can pass the value with "①"
            size_hint_x: 70
        Button:
 text: "Search"
            size_hint_x: 30
            on_press: root.search_book()

    BoxLayout:
        size_hint:1,.1

        Label:
            size_hint: .2,1
 text: "Publishing date"

 Spinner: #List of years
            id: year
            size_hint: .1,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'2000'
            values: [str(y) for y in range(2000, 2018) ]

        Label:
            size_hint: .05,1
 text: "year"

        Spinner:
 id: month # Month list display
            size_hint: .05,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'01'
            values: ['{0:02d}'.format(x)  for x in range(1,13)]

        Label:
            size_hint: .05,1
 text: "Moon"

 Spinner: # List of days
            id: day
            size_hint: .05,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'01'
 values: ['{0: 02d}'. format (x) for x in range (1,30)] # Processing that changes the day every month is required, but temporarily suspended

        Label:
            size_hint: .05,1
 text: "day"


        Label:
            size_hint: .05,1
 text: "Number"

 Spinner: #Monthly size
            id: number
            size_hint: .05,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'10'
            values: ['1','5','10', '15', '20'] 

Of these, TexInput()Was explained up to the last time in the character input part. By the way, it is a bug of Kivy that IME does not open by inputting characters on Windows OS. When searching in Japanese, copy and use the value entered in Notepad.

Next, I'm using "Spinner" this time to select a list of dates. Click on Spinner to display a list from which you can select items.

6_50.jpg

The corresponding Kv of the year is as follows.


 Spinner: #List of years
            id: year
            size_hint: .1,1
            halign: 'center'
            valign: 'middle'
            text_size: self.size
            text:'2000'
            values: [str(y) for y in range(2000, 2018) ]

The values you put in Values are listed.

Please refer to the API reference for details.

Spinner

####About the list screen display part

Next, the explanation of the part displaying the list of search results

7_50.jpg

The Kv parts that make up the form are as follows.

    ListView:
        id: search_results_list
        adapter:
 #List search results and make items buttons
 # data = Keep a list of searches
 # CLS = List display format (This time, it is displayed as a button)
 # args_converter = Convert the display result to a list with the book name as the key.
            ListAdapter(data=[], cls=main.BookButton, args_converter=main.SearchBookForm.books_args_converter)

First, let's talk about ListView.

ListView

ListView is a widget for displaying data in list format. For simple usage, see "item"_Enter the list structure in a property called "strings". For example, in the case of the following code, item_The strings will contain consecutive numbers from 0 to 100, and when executed, the items from 0 to 100 will be displayed in Label format.

class MainView(ListView):
    def __init__(self, **kwargs):
        super(MainView, self).__init__(
            item_strings=[str(index) for index in range(100)])

However, since it is only a Label that is displayed in this format, it cannot be selected and operated. So this time,AdaptersUse the method called to change the list to a button display.

ListAdapter(data=[], cls=main.BookButton, args_converter=main.SearchBookForm.books_args_converter)

The explanation of the arguments is as follows.

+data: Keeps search result information in a list

I will explain it by comparing it with the file on the Python side of each item.

data

data holds the value of the search result This time, when you search, the following tuples will be returned.

The corresponding code is as follows.

    def search_book(self):
 '''Search based on search conditions and store the results in ListView'''

 ~ Omitted ~
    
 # SRU execution (search based on input conditions)
        srres = client.get_srresponse()

 #Store search results in books list
        books = [(d.recordData.title, d.recordData.creator, d.recordData.language, d.recordData.publisher) for d in srres.records]
        print(books)
        
        print("----------------")
 #Store in search results
        
 self.search_results.adapter.data.clear () # Clear search results data (for detailed display)
 self.search_results.adapter.data.extend (books) # Add search results to data
 Refresh self.search_results._trigger_reset_populate () # search_results (list_view)


The values stored in the books list are:

 [('Python introductory class to remember in 10 days','Mikio Hogari, Manabu Terata, Naoki Nakanishi, Naoki Hotta, Takashi Nagai',' jpn','Shoeisha'),

 ~ Omitted ~

 ('Operated with a robot-specific tool that controls Bluetooth-connected toys Automated with Python', None,'jpn','')]

The previous result of data is deleted and newly placed in the corresponding place below. afterwards"_trigger_reset_The display is updated with "populate".

 self.search_results.adapter.data.clear () # Clear search results data (for detailed display)
 self.search_results.adapter.data.extend (books) # Add search results to data
 Refresh self.search_results._trigger_reset_populate () # search_results (list_view)
args_converter
def books_args_converter(index, data_item):
 '''Convert search results to dictionary type with book name as key.
 It is called and executed for each record of the search result.
    ''
    title, creater , language, publisher = data_item
    return {'book': (title, creater , language, publisher )}

args_converter uses the book information of the search result as a key and args_It is stored in the converter.

cls
class BookButton(ListItemButton):
 '''Use the search_results (ListView) item as a button'''
    book = ListProperty()

cls sets the display format of the list. This time, the book information is converted into a List, stored in the book, and displayed on the Button. In addition, cls is probably an abbreviation of The clear screen and is used to mean screen erase and redisplay.

Regarding the display format, use the following properties on the Kv side.

<BookButton>
 #Layout with search results as buttons
    text_size: self.size
    halign: 'left'

 text: self.book [0] # Make the book name the title of the button

    height: "40dp"
    size_hint_y: None
    on_press: app.root.show_book_info(self.book)

The concept of Adpter is difficult to use and I don't fully understand it, but "data",「cls」,「args_Once you know that you can change the list display format setting by setting a value in "converter", it's okay.

reference

###About "Book Info" widget

This is a description of the details screen.

The screen is as follows. 4_50.jpg

The Kv file is as follows.

<BookInfo>
 # search results
    book: ("","","","")
    orientation: "vertical"


    BoxLayout:
        orientation: "horizontal"
        size_hint_y: None
        height: "40dp"


    GridLayout:
        cols: 2
        rows: 4

        Label:
 text: "Title"
            halign: 'left'
            valign: 'middle'
            size_hint_x: 20
            text_size:self.size

        Label:
            text_size:self.size
            halign: 'left'
            valign: 'middle'
            text:root.book[0]
            size_hint_x: 80

        Label:
 text: "author"
            halign: 'left'
            valign: 'middle'
            size_hint_x: 20
            text_size:self.size

        Label:
            text: root.book[1]
            size_hint_x: 80
            text_size:self.size
            halign: 'left'
            valign: 'middle'

        Label:
 text: "Publisher"
            halign: 'left'
            valign: 'middle'
            size_hint_x: 20
            text_size:self.size

        Label:
            text: root.book[3]
            size_hint_x: 80
 #text: "Publisher: {}" .format (root.book [3])
            text_size:self.size
            halign: 'left'
            valign: 'middle'


        Label:
 text: "language"
            halign: 'left'
            valign: 'middle'
            size_hint_x: 20
            text_size:self.size

        Label:
            text: root.book[2]
            size_hint_x: 80
            text_size: self.size
            halign: 'left'
            valign: 'middle'

Click the "Book Button" widget to main.show_book_info()Is executed. show_book_info() Formats the book information and displays the "BookInfo" widget (detail screen).

I'm not doing anything particularly difficult here, just displaying the results. The only new thing I'm doing is aligning the characters to the left edge and wrapping them.

Label:
    text_size:self.size
    halign: 'left'
    valign: 'middle'
    text:root.book[0]
    size_hint_x: 80

If you leave the default text of Label, if it is a long line, it will be displayed on one line beyond Label, so "text"_"size" specifies the size as the size of the label. Then use "halign" to left-justify the horizontal display and "valign" to display the vertical display in the middle.

reference

#Summary Now you know how to display multiple screens, search based on multiple input items, list results, and display details for each item. Until this time, I think you have somehow understood how to make a desktop application that uses buttons.

Next time, I will try to display it on an Android device based on this program.

By the way, it was quite difficult because the program had to be changed significantly from here to display on Android.

#Reference: About file packaging If you want to use Kivy to package your files, you can use PyInstaller to package them. Separately if you want to exe in windowsPyWin32Must be installed.

reference

#Continuation of this content I posted a new article.

Recommended Posts

How to use Python Kivy ③-Linkage with WebAPI (from sending and receiving requests to displaying a list of results, transitioning multiple screens)-
Started Python: Swap an array of values obtained from SQL results to a list type and use it in IN of another query
Summary of how to use Python list
[Introduction to Python] How to sort the contents of a list efficiently with list sort
How to get a list of files in the same directory with python
How to identify the element with the smallest number of characters in a Python list?
How to write a list / dictionary type of Python3
How to use Python Kivy ① ~ Basics of Kv Language ~
[Python] How to delete rows and columns in a table (list of drop method options)
[Python] How to create a table from list (basic operation of table creation / change of matrix name)
[Python] What is a tuple? Explains how to use without tuples and how to use it with examples.
[Python] How to make a list of character strings character by character
How to slice a block multiple array from a multiple array in Python
How to shuffle a part of a Python list (at random.shuffle)
[Python] Summary of how to use split and join functions
How to display a list of installable versions with pyenv
Comparison of how to use higher-order functions in Python 2 and 3
How to get a list of built-in exceptions in python
Python: Create a dictionary from a list of keys and values
How to get a list of links from a page from wikipedia
[Python] How to use list 1
[Python] What is a slice? An easy-to-understand explanation of how to use it with a concrete example.
[Python] What is pip? Explain the command list and how to use it with actual examples
How to make a surveillance camera (Security Camera) with Opencv and Python
How to use Python Kivy (reference) -I translated Kivy Language of API reference-
I tried to create a list of prime numbers with python
Pass a list by reference from Python to C ++ with pybind11
How to remove duplicates from a Python list while preserving order.
How to delete multiple specified positions (indexes) in a Python list
How to use Python with Jw_cad (Part 2 Command explanation and operation)
Python: How to use async with
How to use Requests (Python Library)
[Python] How to use list 3 Added
How to use FTP with Python
How to put OpenCV in Raspberry Pi and easily collect images of face detection results with Python
[Python] How to create a dictionary type list, add / change / delete elements, and extract with a for statement
[Python] Explains how to use the range function with a concrete example
[Python] How to put any number of standard inputs in a list
Connect to postgreSQL from Python and use stored procedures in a loop.
[Python] How to use list 2 Reference of list value, number of elements, maximum value, minimum value
Receive a list of the results of parallel processing in Python with starmap
How to format a list of dictionaries (or instances) well in Python
python: Tips for displaying an array (list) with an index (how to find out what number an element of an array is)
[Python] Summary of how to use pandas
How to install and use pandas_datareader [Python]
[Python] How to convert a 2D list to a 1D list
[Python2.7] Summary of how to use unittest
python: How to use locals () and globals ()
How to use Python zip and enumerate
[Python2.7] Summary of how to use subprocess
How to use is and == in Python
[Question] How to use plot_surface of python
Try to find the probability that it is a multiple of 3 and not a multiple of 5 when one is removed from a card with natural numbers 1 to 100 using Ruby and Python.
I tried to make a simple mail sending application with tkinter of Python
How to apply updlock, rowlock, etc. with a combination of SQLAlchemy and SQLServer
How to use Service Account OAuth and API with Google API Client for python
WEB scraping with python and try to make a word cloud from reviews
[Python Tips] How to retrieve multiple keys with the maximum value from the dictionary
[Python] How to create a local web server environment with SimpleHTTPServer and CGIHTTPServer
[Introduction to Python] How to get the index of data with a for statement
[Introduction to statistics] What kind of distribution is the t distribution, chi-square distribution, and F distribution? A little summary of how to use [python]