1624678620

# Turn a 2D Image into a 3D Print

This video tutorial will show you how to take a 2D image and turn it into a 3D object to print to your 3D printer. This first step is to convert your file to a .svg file then I will import it into Tinkercad. Tinkercad is a simple, online 3D design and 3D printing app.

Convertio: https://convertio.co/image-converter/

1669003576

## Exploring Mutable and Immutable in Python

In this Python article, let's learn about Mutable and Immutable in Python.

## Mutable and Immutable in Python

Mutable is a fancy way of saying that the internal state of the object is changed/mutated. So, the simplest definition is: An object whose internal state can be changed is mutable. On the other hand, immutable doesn’t allow any change in the object once it has been created.

Both of these states are integral to Python data structure. If you want to become more knowledgeable in the entire Python Data Structure, take this free course which covers multiple data structures in Python including tuple data structure which is immutable. You will also receive a certificate on completion which is sure to add value to your portfolio.

### Mutable Definition

Mutable is when something is changeable or has the ability to change. In Python, ‘mutable’ is the ability of objects to change their values. These are often the objects that store a collection of data.

### Immutable Definition

Immutable is the when no change is possible over time. In Python, if the value of an object cannot be changed over time, then it is known as immutable. Once created, the value of these objects is permanent.

### List of Mutable and Immutable objects

Objects of built-in type that are mutable are:

• Lists
• Sets
• Dictionaries
• User-Defined Classes (It purely depends upon the user to define the characteristics)

Objects of built-in type that are immutable are:

• Numbers (Integer, Rational, Float, Decimal, Complex & Booleans)
• Strings
• Tuples
• Frozen Sets
• User-Defined Classes (It purely depends upon the user to define the characteristics)

Object mutability is one of the characteristics that makes Python a dynamically typed language. Though Mutable and Immutable in Python is a very basic concept, it can at times be a little confusing due to the intransitive nature of immutability.

## Objects in Python

In Python, everything is treated as an object. Every object has these three attributes:

• Identity – This refers to the address that the object refers to in the computer’s memory.
• Type – This refers to the kind of object that is created. For example- integer, list, string etc.
• Value – This refers to the value stored by the object. For example – List=[1,2,3] would hold the numbers 1,2 and 3

While ID and Type cannot be changed once it’s created, values can be changed for Mutable objects.

Check out this free python certificate course to get started with Python.

## Mutable Objects in Python

I believe, rather than diving deep into the theory aspects of mutable and immutable in Python, a simple code would be the best way to depict what it means in Python. Hence, let us discuss the below code step-by-step:

#Creating a list which contains name of Indian cities

``````cities = [‘Delhi’, ‘Mumbai’, ‘Kolkata’]
``````

# Printing the elements from the list cities, separated by a comma & space

``````for city in cities:
print(city, end=’, ’)

Output [1]: Delhi, Mumbai, Kolkata
``````

#Printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(cities)))

Output [2]: 0x1691d7de8c8
``````

#Adding a new city to the list cities

``````cities.append(‘Chennai’)
``````

#Printing the elements from the list cities, separated by a comma & space

``````for city in cities:
print(city, end=’, ’)

Output [3]: Delhi, Mumbai, Kolkata, Chennai
``````

#Printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(cities)))

Output [4]: 0x1691d7de8c8
``````

The above example shows us that we were able to change the internal state of the object ‘cities’ by adding one more city ‘Chennai’ to it, yet, the memory address of the object did not change. This confirms that we did not create a new object, rather, the same object was changed or mutated. Hence, we can say that the object which is a type of list with reference variable name ‘cities’ is a MUTABLE OBJECT.

Let us now discuss the term IMMUTABLE. Considering that we understood what mutable stands for, it is obvious that the definition of immutable will have ‘NOT’ included in it. Here is the simplest definition of immutable– An object whose internal state can NOT be changed is IMMUTABLE.

Again, if you try and concentrate on different error messages, you have encountered, thrown by the respective IDE; you use you would be able to identify the immutable objects in Python. For instance, consider the below code & associated error message with it, while trying to change the value of a Tuple at index 0.

#Creating a Tuple with variable name ‘foo’

``````foo = (1, 2)
``````

#Changing the index[0] value from 1 to 3

``````foo[0] = 3

TypeError: 'tuple' object does not support item assignment
``````

## Immutable Objects in Python

Once again, a simple code would be the best way to depict what immutable stands for. Hence, let us discuss the below code step-by-step:

#Creating a Tuple which contains English name of weekdays

``````weekdays = ‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’
``````

# Printing the elements of tuple weekdays

``````print(weekdays)

Output [1]:  (‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’)
``````

#Printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(weekdays)))

Output [2]: 0x1691cc35090
``````

#tuples are immutable, so you cannot add new elements, hence, using merge of tuples with the # + operator to add a new imaginary day in the tuple ‘weekdays’

``````weekdays  +=  ‘Pythonday’,
``````

#Printing the elements of tuple weekdays

``````print(weekdays)

Output [3]: (‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’, ‘Pythonday’)
``````

#Printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(weekdays)))

``````

This above example shows that we were able to use the same variable name that is referencing an object which is a type of tuple with seven elements in it. However, the ID or the memory location of the old & new tuple is not the same. We were not able to change the internal state of the object ‘weekdays’. The Python program manager created a new object in the memory address and the variable name ‘weekdays’ started referencing the new object with eight elements in it.  Hence, we can say that the object which is a type of tuple with reference variable name ‘weekdays’ is an IMMUTABLE OBJECT.

Where can you use mutable and immutable objects:

Mutable objects can be used where you want to allow for any updates. For example, you have a list of employee names in your organizations, and that needs to be updated every time a new member is hired. You can create a mutable list, and it can be updated easily.

Immutability offers a lot of useful applications to different sensitive tasks we do in a network centred environment where we allow for parallel processing. By creating immutable objects, you seal the values and ensure that no threads can invoke overwrite/update to your data. This is also useful in situations where you would like to write a piece of code that cannot be modified. For example, a debug code that attempts to find the value of an immutable object.

Watch outs:  Non transitive nature of Immutability:

OK! Now we do understand what mutable & immutable objects in Python are. Let’s go ahead and discuss the combination of these two and explore the possibilities. Let’s discuss, as to how will it behave if you have an immutable object which contains the mutable object(s)? Or vice versa? Let us again use a code to understand this behaviour–

#creating a tuple (immutable object) which contains 2 lists(mutable) as it’s elements

#The elements (lists) contains the name, age & gender

``````person = (['Ayaan', 5, 'Male'], ['Aaradhya', 8, 'Female'])
``````

#printing the tuple

``````print(person)

Output [1]: (['Ayaan', 5, 'Male'], ['Aaradhya', 8, 'Female'])

``````

#printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(person)))

Output [2]: 0x1691ef47f88
``````

#Changing the age for the 1st element. Selecting 1st element of tuple by using indexing [0] then 2nd element of the list by using indexing [1] and assigning a new value for age as 4

``````person[0][1] = 4
``````

#printing the updated tuple

``````print(person)

Output [3]: (['Ayaan', 4, 'Male'], ['Aaradhya', 8, 'Female'])
``````

#printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(person)))

Output [4]: 0x1691ef47f88
``````

In the above code, you can see that the object ‘person’ is immutable since it is a type of tuple. However, it has two lists as it’s elements, and we can change the state of lists (lists being mutable). So, here we did not change the object reference inside the Tuple, but the referenced object was mutated.

Same way, let’s explore how it will behave if you have a mutable object which contains an immutable object? Let us again use a code to understand the behaviour–

#creating a list (mutable object) which contains tuples(immutable) as it’s elements

``````list1 = [(1, 2, 3), (4, 5, 6)]
``````

#printing the list

``````print(list1)

Output [1]: [(1, 2, 3), (4, 5, 6)]

``````

#printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(list1)))

Output [2]: 0x1691d5b13c8	``````

#changing object reference at index 0

``````list1[0] = (7, 8, 9)
``````

#printing the list

``Output [3]: [(7, 8, 9), (4, 5, 6)]``

#printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(list1)))

Output [4]: 0x1691d5b13c8
``````

As an individual, it completely depends upon you and your requirements as to what kind of data structure you would like to create with a combination of mutable & immutable objects. I hope that this information will help you while deciding the type of object you would like to select going forward.

Before I end our discussion on IMMUTABILITY, allow me to use the word ‘CAVITE’ when we discuss the String and Integers. There is an exception, and you may see some surprising results while checking the truthiness for immutability. For instance:
#creating an object of integer type with value 10 and reference variable name ‘x’

x = 10

#printing the value of ‘x’

``````print(x)

Output [1]: 10
``````

#Printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(x)))

Output [2]: 0x538fb560

``````

#creating an object of integer type with value 10 and reference variable name ‘y’

``````y = 10
``````

#printing the value of ‘y’

``````print(y)

Output [3]: 10
``````

#Printing the location of the object created in the memory address in hexadecimal format

``````print(hex(id(y)))

Output [4]: 0x538fb560
``````

As per our discussion and understanding, so far, the memory address for x & y should have been different, since, 10 is an instance of Integer class which is immutable. However, as shown in the above code, it has the same memory address. This is not something that we expected. It seems that what we have understood and discussed, has an exception as well.

Quick checkPython Data Structures

### Immutability of Tuple

Tuples are immutable and hence cannot have any changes in them once they are created in Python. This is because they support the same sequence operations as strings. We all know that strings are immutable. The index operator will select an element from a tuple just like in a string. Hence, they are immutable.

## Exceptions in immutability

Like all, there are exceptions in the immutability in python too. Not all immutable objects are really mutable. This will lead to a lot of doubts in your mind. Let us just take an example to understand this.

Consider a tuple ‘tup’.

Now, if we consider tuple tup = (‘GreatLearning’,[4,3,1,2]) ;

We see that the tuple has elements of different data types. The first element here is a string which as we all know is immutable in nature. The second element is a list which we all know is mutable. Now, we all know that the tuple itself is an immutable data type. It cannot change its contents. But, the list inside it can change its contents. So, the value of the Immutable objects cannot be changed but its constituent objects can. change its value.

## FAQs

#### 2. What are the mutable and immutable data types in Python?

• Some mutable data types in Python are:

list, dictionary, set, user-defined classes.

• Some immutable data types are:

int, float, decimal, bool, string, tuple, range.

#### 3. Are lists mutable in Python?

Lists in Python are mutable data types as the elements of the list can be modified, individual elements can be replaced, and the order of elements can be changed even after the list has been created.
(Examples related to lists have been discussed earlier in this blog.)

#### 4. Why are tuples called immutable types?

Tuple and list data structures are very similar, but one big difference between the data types is that lists are mutable, whereas tuples are immutable. The reason for the tuple’s immutability is that once the elements are added to the tuple and the tuple has been created; it remains unchanged.

A programmer would always prefer building a code that can be reused instead of making the whole data object again. Still, even though tuples are immutable, like lists, they can contain any Python object, including mutable objects.

#### 5. Are sets mutable in Python?

A set is an iterable unordered collection of data type which can be used to perform mathematical operations (like union, intersection, difference etc.). Every element in a set is unique and immutable, i.e. no duplicate values should be there, and the values can’t be changed. However, we can add or remove items from the set as the set itself is mutable.

#### 6. Are strings mutable in Python?

Strings are not mutable in Python. Strings are a immutable data types which means that its value cannot be updated.

Original article source at: https://www.mygreatlearning.com

1672928580

## How to Bash Read Command

Bash has no built-in function to take the user’s input from the terminal. The read command of Bash is used to take the user’s input from the terminal. This command has different options to take an input from the user in different ways. Multiple inputs can be taken using the single read command. Different ways of using this command in the Bash script are described in this tutorial.

## Syntax

The read command can be used without any argument or option. Many types of options can be used with this command to take the input of the particular data type. It can take more input from the user by defining the multiple variables with this command.

## Some Useful Options of the Read Command

Some options of the read command require an additional parameter to use. The most commonly used options of the read command are mentioned in the following:

## Different Examples of the Read Command

The uses of read command with different options are shown in this part of this tutorial.

Example 1: Using Read Command without Any Option and variable

Create a Bash file with the following script that takes the input from the terminal using the read command without any option and variable. If no variable is used with the read command, the input value is stored in the \$REPLY variable. The value of this variable is printed later after taking the input.

``````#!/bin/bash
#Print the prompt message
echo "Enter your favorite color: "
#Take the input
#Print the input value

Output:

The following output appears if the “Blue” value is taken as an input:

Example 2: Using Read Command with a Variable

Create a Bash file with the following script that takes the input from the terminal using the read command with a variable. The method of taking the single or multiple variables using a read command is shown in this example. The values of all variables are printed later.

``````#!/bin/bash
#Print the prompt message
echo "Enter the product name: "
#Take the input with a single variable

#Print the prompt message
echo "Enter the color variations of the product: "
#Take three input values in three variables

#Print the input value
echo "The product name is \$item."
#Print the input values
echo "Available colors are \$color1, \$color2, and \$color3."``````

Output:

The following output appears after taking a single input first and three inputs later:

Example 3: Using Read Command with -p Option

Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -p option. The input value is printed later.

``````#!/bin/bash
#Take the input with the prompt message
read -p "Enter the book name: " book
#Print the input value
echo "Book name: \$book"``````

Output:

The following output appears after taking the input:

Example 4: Using Read Command with -s Option

Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -s option. The input value of the password will not be displayed for the -s option. The input values are checked later for authentication. A success or failure message is also printed.

``````#!/bin/bash
#Take the input with the prompt message
#Take the secret input with the prompt message

echo ""

#Check the email and password for authentication
then
#Print the success message
echo "Authenticated."
else
#Print the failure message
echo "Not authenticated."
fi``````

Output:

The following output appears after taking the valid and invalid input values:

Example 5: Using Read Command with -a Option

Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -a option. The array values are printed later after taking the input values from the terminal.

``````#!/bin/bash
echo "Enter the country names: "
#Take multiple inputs using an array

echo "Country names are:"
for country in \${countries[@]}
do
echo \$country
done``````

Output:

The following output appears after taking the array values:

Example 6: Using Read Command with -n Option

Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -n option.

``````#!/bin/bash
#Print the prompt message
echo "Enter the product code: "
#Take the input of five characters
echo ""
#Print the input value
echo "The product code is \$code"``````

Output:

The following output appears if the “78342” value is taken as input:

Example 7: Using Read Command with -t Option

Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -t option.

``````#!/bin/bash
#Print the prompt message
echo -n "Write the result of 10-6: "
#Take the input of five characters

#Check the input value
if [[ \$answer == "4" ]]
then
else
fi``````

Output:

The following output appears after taking the correct and incorrect input values:

## Conclusion

The uses of some useful options of the read command are explained in this tutorial using multiple examples to know the basic uses of the read command.

Original article source at: https://linuxhint.com/

1653123600

## EasyMDE - Markdown Editor

This repository is a fork of SimpleMDE, made by Sparksuite. Go to the dedicated section for more information.

A drop-in JavaScript text area replacement for writing beautiful and understandable Markdown. EasyMDE allows users who may be less experienced with Markdown to use familiar toolbar buttons and shortcuts.

In addition, the syntax is rendered while editing to clearly show the expected result. Headings are larger, emphasized words are italicized, links are underlined, etc.

EasyMDE also features both built-in auto saving and spell checking. The editor is entirely customizable, from theming to toolbar buttons and javascript hooks.

Try the demo

## Install EasyMDE

Via npm:

``````npm install easymde
``````

Via the UNPKG CDN:

``````<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">
<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script>
``````

Or jsDelivr:

``````<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
<script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
``````

## How to use

After installing and/or importing the module, you can load EasyMDE onto the first `textarea` element on the web page:

``````<textarea></textarea>
<script>
const easyMDE = new EasyMDE();
</script>
``````

Alternatively you can select a specific `textarea`, via JavaScript:

``````<textarea id="my-text-area"></textarea>
<script>
const easyMDE = new EasyMDE({element: document.getElementById('my-text-area')});
</script>
``````

### Editor functions

Use `easyMDE.value()` to get the content of the editor:

``````<script>
easyMDE.value();
</script>
``````

Use `easyMDE.value(val)` to set the content of the editor:

``````<script>
easyMDE.value('New input for **EasyMDE**');
</script>
``````

## Configuration

### Options list

• autoDownloadFontAwesome: If set to `true`, force downloads Font Awesome (used for icons). If set to `false`, prevents downloading. Defaults to `undefined`, which will intelligently check whether Font Awesome has already been included, then download accordingly.
• autofocus: If set to `true`, focuses the editor automatically. Defaults to `false`.
• autosave: Saves the text that's being written and will load it back in the future. It will forget the text when the form it's contained in is submitted.
• enabled: If set to `true`, saves the text automatically. Defaults to `false`.
• delay: Delay between saves, in milliseconds. Defaults to `10000` (10 seconds).
• submit_delay: Delay before assuming that submit of the form failed and saving the text, in milliseconds. Defaults to `autosave.delay` or `10000` (10 seconds).
• uniqueId: You must set a unique string identifier so that EasyMDE can autosave. Something that separates this from other instances of EasyMDE elsewhere on your website.
• timeFormat: Set DateTimeFormat. More information see DateTimeFormat instances. Default `locale: en-US, format: hour:minute`.
• text: Set text for autosave.
• autoRefresh: Useful, when initializing the editor in a hidden DOM node. If set to `{ delay: 300 }`, it will check every 300 ms if the editor is visible and if positive, call CodeMirror's `refresh()`.
• blockStyles: Customize how certain buttons that style blocks of text behave.
• bold: Can be set to `**` or `__`. Defaults to `**`.
• code: Can be set to ````` or `~~~`. Defaults to `````.
• italic: Can be set to `*` or `_`. Defaults to `*`.
• unorderedListStyle: can be `*`, `-` or `+`. Defaults to `*`.
• scrollbarStyle: Chooses a scrollbar implementation. The default is "native", showing native scrollbars. The core library also provides the "null" style, which completely hides the scrollbars. Addons can implement additional scrollbar models.
• element: The DOM element for the `textarea` element to use. Defaults to the first `textarea` element on the page.
• forceSync: If set to `true`, force text changes made in EasyMDE to be immediately stored in original text area. Defaults to `false`.
• hideIcons: An array of icon names to hide. Can be used to hide specific icons shown by default without completely customizing the toolbar.
• indentWithTabs: If set to `false`, indent using spaces instead of tabs. Defaults to `true`.
• initialValue: If set, will customize the initial value of the editor.
• previewImagesInEditor: - EasyMDE will show preview of images, `false` by default, preview for images will appear only for images on separate lines.
• imagesPreviewHandler: - A custom function for handling the preview of images. Takes the parsed string between the parantheses of the image markdown `![]( )` as argument and returns a string that serves as the `src` attribute of the `<img>` tag in the preview. Enables dynamic previewing of images in the frontend without having to upload them to a server, allows copy-pasting of images to the editor with preview.
• insertTexts: Customize how certain buttons that insert text behave. Takes an array with two elements. The first element will be the text inserted before the cursor or highlight, and the second element will be inserted after. For example, this is the default link value: `["[", "](http://)"]`.
• horizontalRule
• image
• table
• lineNumbers: If set to `true`, enables line numbers in the editor.
• lineWrapping: If set to `false`, disable line wrapping. Defaults to `true`.
• minHeight: Sets the minimum height for the composition area, before it starts auto-growing. Should be a string containing a valid CSS value like `"500px"`. Defaults to `"300px"`.
• maxHeight: Sets fixed height for the composition area. `minHeight` option will be ignored. Should be a string containing a valid CSS value like `"500px"`. Defaults to `undefined`.
• onToggleFullScreen: A function that gets called when the editor's full screen mode is toggled. The function will be passed a boolean as parameter, `true` when the editor is currently going into full screen mode, or `false`.
• parsingConfig: Adjust settings for parsing the Markdown during editing (not previewing).
• allowAtxHeaderWithoutSpace: If set to `true`, will render headers without a space after the `#`. Defaults to `false`.
• strikethrough: If set to `false`, will not process GFM strikethrough syntax. Defaults to `true`.
• underscoresBreakWords: If set to `true`, let underscores be a delimiter for separating words. Defaults to `false`.
• overlayMode: Pass a custom codemirror overlay mode to parse and style the Markdown during editing.
• mode: A codemirror mode object.
• combine: If set to `false`, will replace CSS classes returned by the default Markdown mode. Otherwise the classes returned by the custom mode will be combined with the classes returned by the default mode. Defaults to `true`.
• placeholder: If set, displays a custom placeholder message.
• previewClass: A string or array of strings that will be applied to the preview screen when activated. Defaults to `"editor-preview"`.
• previewRender: Custom function for parsing the plaintext Markdown and returning HTML. Used when user previews.
• promptURLs: If set to `true`, a JS alert window appears asking for the link or image URL. Defaults to `false`.
• promptTexts: Customize the text used to prompt for URLs.
• image: The text to use when prompting for an image's URL. Defaults to `URL of the image:`.
• link: The text to use when prompting for a link's URL. Defaults to `URL for the link:`.
• uploadImage: If set to `true`, enables the image upload functionality, which can be triggered by drag and drop, copy-paste and through the browse-file window (opened when the user click on the upload-image icon). Defaults to `false`.
• imageMaxSize: Maximum image size in bytes, checked before upload (note: never trust client, always check the image size at server-side). Defaults to `1024 * 1024 * 2` (2 MB).
• imageAccept: A comma-separated list of mime-types used to check image type before upload (note: never trust client, always check file types at server-side). Defaults to `image/png, image/jpeg`.
• imageUploadFunction: A custom function for handling the image upload. Using this function will render the options `imageMaxSize`, `imageAccept`, `imageUploadEndpoint` and `imageCSRFToken` ineffective.
• The function gets a file and `onSuccess` and `onError` callback functions as parameters. `onSuccess(imageUrl: string)` and `onError(errorMessage: string)`
• imageUploadEndpoint: The endpoint where the images data will be sent, via an asynchronous POST request. The server is supposed to save this image, and return a JSON response.
• if the request was successfully processed (HTTP 200 OK): `{"data": {"filePath": "<filePath>"}}` where filePath is the path of the image (absolute if `imagePathAbsolute` is set to true, relative if otherwise);
• otherwise: `{"error": "<errorCode>"}`, where errorCode can be `noFileGiven` (HTTP 400 Bad Request), `typeNotAllowed` (HTTP 415 Unsupported Media Type), `fileTooLarge` (HTTP 413 Payload Too Large) or `importError` (see errorMessages below). If errorCode is not one of the errorMessages, it is alerted unchanged to the user. This allows for server-side error messages. No default value.
• imagePathAbsolute: If set to `true`, will treat `imageUrl` from `imageUploadFunction` and filePath returned from `imageUploadEndpoint` as an absolute rather than relative path, i.e. not prepend `window.location.origin` to it.
• imageCSRFToken: CSRF token to include with AJAX call to upload image. For various instances like Django, Spring and Laravel.
• imageCSRFName: CSRF token filed name to include with AJAX call to upload image, applied when `imageCSRFToken` has value, defaults to `csrfmiddlewaretoken`.
• imageCSRFHeader: If set to `true`, passing CSRF token via header. Defaults to `false`, which pass CSRF through request body.
• imageTexts: Texts displayed to the user (mainly on the status bar) for the import image feature, where `#image_name#`, `#image_size#` and `#image_max_size#` will replaced by their respective values, that can be used for customization or internationalization:
• sbInit: Status message displayed initially if `uploadImage` is set to `true`. Defaults to `Attach files by drag and dropping or pasting from clipboard.`.
• sbOnDragEnter: Status message displayed when the user drags a file to the text area. Defaults to `Drop image to upload it.`.
• sbOnDrop: Status message displayed when the user drops a file in the text area. Defaults to `Uploading images #images_names#`.
• sbProgress: Status message displayed to show uploading progress. Defaults to `Uploading #file_name#: #progress#%`.
• sbOnUploaded: Status message displayed when the image has been uploaded. Defaults to `Uploaded #image_name#`.
• sizeUnits: A comma-separated list of units used to display messages with human-readable file sizes. Defaults to `B, KB, MB` (example: `218 KB`). You can use `B,KB,MB` instead if you prefer without whitespaces (`218KB`).
• errorMessages: Errors displayed to the user, using the `errorCallback` option, where `#image_name#`, `#image_size#` and `#image_max_size#` will replaced by their respective values, that can be used for customization or internationalization:
• noFileGiven: The server did not receive any file from the user. Defaults to `You must select a file.`.
• typeNotAllowed: The user send a file type which doesn't match the `imageAccept` list, or the server returned this error code. Defaults to `This image type is not allowed.`.
• fileTooLarge: The size of the image being imported is bigger than the `imageMaxSize`, or if the server returned this error code. Defaults to `Image #image_name# is too big (#image_size#).\nMaximum file size is #image_max_size#.`.
• importError: An unexpected error occurred when uploading the image. Defaults to `Something went wrong when uploading the image #image_name#.`.
• errorCallback: A callback function used to define how to display an error message. Defaults to `(errorMessage) => alert(errorMessage)`.
• renderingConfig: Adjust settings for parsing the Markdown during previewing (not editing).
• codeSyntaxHighlighting: If set to `true`, will highlight using highlight.js. Defaults to `false`. To use this feature you must include highlight.js on your page or pass in using the `hljs` option. For example, include the script and the CSS files like:
`<script src="https://cdn.jsdelivr.net/highlight.js/latest/highlight.min.js"></script>`
`<link rel="stylesheet" href="https://cdn.jsdelivr.net/highlight.js/latest/styles/github.min.css">`
• hljs: An injectible instance of highlight.js. If you don't want to rely on the global namespace (`window.hljs`), you can provide an instance here. Defaults to `undefined`.
• markedOptions: Set the internal Markdown renderer's options. Other `renderingConfig` options will take precedence.
• singleLineBreaks: If set to `false`, disable parsing GitHub Flavored Markdown (GFM) single line breaks. Defaults to `true`.
• sanitizerFunction: Custom function for sanitizing the HTML output of Markdown renderer.
• shortcuts: Keyboard shortcuts associated with this instance. Defaults to the array of shortcuts.
• showIcons: An array of icon names to show. Can be used to show specific icons hidden by default without completely customizing the toolbar.
• spellChecker: If set to `false`, disable the spell checker. Defaults to `true`. Optionally pass a CodeMirrorSpellChecker-compliant function.
• inputStyle: `textarea` or `contenteditable`. Defaults to `textarea` for desktop and `contenteditable` for mobile. `contenteditable` option is necessary to enable nativeSpellcheck.
• nativeSpellcheck: If set to `false`, disable native spell checker. Defaults to `true`.
• sideBySideFullscreen: If set to `false`, allows side-by-side editing without going into fullscreen. Defaults to `true`.
• status: If set to `false`, hide the status bar. Defaults to the array of built-in status bar items.
• Optionally, you can set an array of status bar items to include, and in what order. You can even define your own custom status bar items.
• styleSelectedText: If set to `false`, remove the `CodeMirror-selectedtext` class from selected lines. Defaults to `true`.
• syncSideBySidePreviewScroll: If set to `false`, disable syncing scroll in side by side mode. Defaults to `true`.
• tabSize: If set, customize the tab size. Defaults to `2`.
• theme: Override the theme. Defaults to `easymde`.
• toolbar: If set to `false`, hide the toolbar. Defaults to the array of icons.
• toolbarTips: If set to `false`, disable toolbar button tips. Defaults to `true`.
• direction: `rtl` or `ltr`. Changes text direction to support right-to-left languages. Defaults to `ltr`.

### Options example

Most options demonstrate the non-default behavior:

``````const editor = new EasyMDE({
autofocus: true,
autosave: {
enabled: true,
uniqueId: "MyUniqueID",
delay: 1000,
submit_delay: 5000,
timeFormat: {
locale: 'en-US',
format: {
year: 'numeric',
month: 'long',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
},
},
text: "Autosaved: "
},
blockStyles: {
bold: "__",
italic: "_",
},
unorderedListStyle: "-",
element: document.getElementById("MyID"),
forceSync: true,
indentWithTabs: false,
initialValue: "Hello world!",
insertTexts: {
horizontalRule: ["", "\n\n-----\n\n"],
image: ["![](http://", ")"],
table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text     | Text      | Text     |\n\n"],
},
lineWrapping: false,
minHeight: "500px",
parsingConfig: {
strikethrough: false,
underscoresBreakWords: true,
},
placeholder: "Type here...",

previewClass: "my-custom-styling",
previewClass: ["my-custom-styling", "more-custom-styling"],

previewRender: (plainText) => customMarkdownParser(plainText), // Returns HTML from a custom parser
previewRender: (plainText, preview) => { // Async method
setTimeout(() => {
preview.innerHTML = customMarkdownParser(plainText);
}, 250);

},
promptURLs: true,
promptTexts: {
image: "Custom prompt for URL:",
},
renderingConfig: {
singleLineBreaks: false,
codeSyntaxHighlighting: true,
sanitizerFunction: (renderedHTML) => {
// Using DOMPurify and only allowing <b> tags
return DOMPurify.sanitize(renderedHTML, {ALLOWED_TAGS: ['b']})
},
},
shortcuts: {
drawTable: "Cmd-Alt-T"
},
showIcons: ["code", "table"],
spellChecker: false,
status: false,
status: ["autosave", "lines", "words", "cursor"], // Optional usage
status: ["autosave", "lines", "words", "cursor", {
className: "keystrokes",
defaultValue: (el) => {
el.setAttribute('data-keystrokes', 0);
},
onUpdate: (el) => {
const keystrokes = Number(el.getAttribute('data-keystrokes')) + 1;
el.innerHTML = `\${keystrokes} Keystrokes`;
el.setAttribute('data-keystrokes', keystrokes);
},
}], // Another optional usage, with a custom status bar item that counts keystrokes
styleSelectedText: false,
sideBySideFullscreen: false,
syncSideBySidePreviewScroll: false,
tabSize: 4,
toolbar: false,
toolbarTips: false,
});
``````

### Toolbar icons

Below are the built-in toolbar icons (only some of which are enabled by default), which can be reorganized however you like. "Name" is the name of the icon, referenced in the JavaScript. "Action" is either a function or a URL to open. "Class" is the class given to the icon. "Tooltip" is the small tooltip that appears via the `title=""` attribute. Note that shortcut hints are added automatically and reflect the specified action if it has a key bind assigned to it (i.e. with the value of `action` set to `bold` and that of `tooltip` set to `Bold`, the final text the user will see would be "Bold (Ctrl-B)").

Additionally, you can add a separator between any icons by adding `"|"` to the toolbar array.

### Toolbar customization

Customize the toolbar using the `toolbar` option.

Only the order of existing buttons:

``````const easyMDE = new EasyMDE({
toolbar: ["bold", "italic", "heading", "|", "quote"]
});
``````

``````const easyMDE = new EasyMDE({
toolbar: [
{
name: "bold",
action: EasyMDE.toggleBold,
className: "fa fa-bold",
title: "Bold",
},
"italics", // shortcut to pre-made button
{
name: "custom",
action: (editor) => {
},
className: "fa fa-star",
title: "Custom Button",
attributes: { // for custom attributes
id: "custom-id",
"data-value": "custom value" // HTML5 data-* attributes need to be enclosed in quotation marks ("") because of the dash (-) in its name.
}
},
"|" // Separator
// [, ...]
]
});
``````

Put some buttons on dropdown menu

``````const easyMDE = new EasyMDE({
toolbar: [{
},
"|",
{
name: "others",
className: "fa fa-blind",
title: "others buttons",
children: [
{
name: "image",
action: EasyMDE.drawImage,
className: "fa fa-picture-o",
title: "Image",
},
{
name: "quote",
action: EasyMDE.toggleBlockquote,
className: "fa fa-percent",
title: "Quote",
},
{
}
]
},
// [, ...]
]
});
``````

### Keyboard shortcuts

EasyMDE comes with an array of predefined keyboard shortcuts, but they can be altered with a configuration option. The list of default ones is as follows:

Here is how you can change a few, while leaving others untouched:

``````const editor = new EasyMDE({
shortcuts: {
"toggleOrderedList": "Ctrl-Alt-K", // alter the shortcut for toggleOrderedList
"toggleCodeBlock": null, // unbind Ctrl-Alt-C
"drawTable": "Cmd-Alt-T", // bind Cmd-Alt-T to drawTable action, which doesn't come with a default shortcut
}
});
``````

Shortcuts are automatically converted between platforms. If you define a shortcut as "Cmd-B", on PC that shortcut will be changed to "Ctrl-B". Conversely, a shortcut defined as "Ctrl-B" will become "Cmd-B" for Mac users.

The list of actions that can be bound is the same as the list of built-in actions available for toolbar buttons.

### Event handling

You can catch the following list of events: https://codemirror.net/doc/manual.html#events

``````const easyMDE = new EasyMDE();
easyMDE.codemirror.on("change", () => {
console.log(easyMDE.value());
});
``````

### Removing EasyMDE from text area

You can revert to the initial text area by calling the `toTextArea` method. Note that this clears up the autosave (if enabled) associated with it. The text area will retain any text from the destroyed EasyMDE instance.

``````const easyMDE = new EasyMDE();
// ...
easyMDE.toTextArea();
easyMDE = null;
``````

If you need to remove registered event listeners (when the editor is not needed anymore), call `easyMDE.cleanup()`.

### Useful methods

The following self-explanatory methods may be of use while developing with EasyMDE.

``````const easyMDE = new EasyMDE();
easyMDE.isPreviewActive(); // returns boolean
easyMDE.isSideBySideActive(); // returns boolean
easyMDE.isFullscreenActive(); // returns boolean
easyMDE.clearAutosavedValue(); // no returned value
``````

## How it works

EasyMDE is a continuation of SimpleMDE.

SimpleMDE began as an improvement of lepture's Editor project, but has now taken on an identity of its own. It is bundled with CodeMirror and depends on Font Awesome.

CodeMirror is the backbone of the project and parses much of the Markdown syntax as it's being written. This allows us to add styles to the Markdown that's being written. Additionally, a toolbar and status bar have been added to the top and bottom, respectively. Previews are rendered by Marked using GitHub Flavored Markdown (GFM).

## SimpleMDE fork

I originally made this fork to implement FontAwesome 5 compatibility into SimpleMDE. When that was done I submitted a pull request, which has not been accepted yet. This, and the project being inactive since May 2017, triggered me to make more changes and try to put new life into the project.

Changes include:

• FontAwesome 5 compatibility
• Guide button works when editor is in preview mode
• Links are now `https://` by default
• Small styling changes
• Support for Node 8 and beyond
• Lots of refactored code
• Links in preview will open in a new tab by default
• TypeScript support

My intention is to continue development on this project, improving it and keeping it alive.

## Hacking EasyMDE

You may want to edit this library to adapt its behavior to your needs. This can be done in some quick steps:

1. Follow the prerequisites and installation instructions in the contribution guide;
3. Run `gulp` command, which will generate files: `dist/easymde.min.css` and `dist/easymde.min.js`;
4. Copy-paste those files to your code base, and you are done.

## Contributing

Want to contribute to EasyMDE? Thank you! We have a contribution guide just for you!

Author: Ionaru
Source Code: https://github.com/Ionaru/easy-markdown-editor

1635844603

## पायथन में ट्रांसफॉर्मर के साथ संवादी एआई चैटबॉट

जानें कि पाइथन में प्री-ट्रेन्ड DialoGPT मॉडल के साथ संवादी प्रतिक्रियाएं उत्पन्न करने के लिए हगिंगफेस ट्रांसफॉर्मर लाइब्रेरी का उपयोग कैसे करें।

हाल के वर्षों में चैटबॉट्स ने बहुत लोकप्रियता हासिल की है, और जैसे-जैसे व्यवसाय के लिए चैटबॉट्स का उपयोग करने में रुचि बढ़ती है, शोधकर्ताओं ने संवादी एआई चैटबॉट्स को आगे बढ़ाने पर भी बहुत अच्छा काम किया है।

इस ट्यूटोरियल में, हम संवादी प्रतिक्रिया पीढ़ी के लिए पूर्व-प्रशिक्षित DialoGPT मॉडल को नियोजित करने के लिए हगिंगफेस ट्रांसफॉर्मर लाइब्रेरी का उपयोग करेंगे ।

DialoGPT एक बड़े पैमाने पर ट्यून करने योग्य तंत्रिका संवादी प्रतिक्रिया पीढ़ी मॉडल है जिसे रेडिट से निकाले गए 147M वार्तालापों पर प्रशिक्षित किया गया था, और अच्छी बात यह है कि आप स्क्रैच से प्रशिक्षण की तुलना में बेहतर प्रदर्शन प्राप्त करने के लिए इसे अपने डेटासेट के साथ ठीक कर सकते हैं।

आरंभ करने के लिए, आइए ट्रांसफॉर्मर स्थापित करें :

``\$ pip3 install transformers``

एक नई पायथन फ़ाइल या नोटबुक खोलें और निम्न कार्य करें:

``````from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# model_name = "microsoft/DialoGPT-large"
model_name = "microsoft/DialoGPT-medium"
# model_name = "microsoft/DialoGPT-small"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)``````

DialoGPT के तीन संस्करण हैं; छोटा, मध्यम और बड़ा। बेशक, जितना बड़ा बेहतर होगा, लेकिन अगर आप इसे अपनी मशीन पर चला रहे हैं, तो मुझे लगता है कि छोटा या मध्यम आपकी याददाश्त को बिना किसी समस्या के फिट करता है। बड़े वाले को आज़माने के लिए आप Google Colab का भी उपयोग कर सकते हैं।

## लालची खोज के साथ प्रतिक्रिया उत्पन्न करना

इस खंड में, हम प्रतिक्रिया उत्पन्न करने के लिए लालची खोज एल्गोरिथ्म का उपयोग करेंगे । यही है, हम चैटबॉट प्रतिक्रिया का चयन करते हैं जिसमें प्रत्येक समय चरण पर चुने जाने की सबसे अधिक संभावना होती है।

आइए लालची खोज का उपयोग करके हमारे AI के साथ चैट करने के लिए कोड बनाएं:

``````# chatting 5 times with greedy search
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")``````

आइए इस कोड के मूल की व्याख्या करें:

• हम सबसे पहले चैटिंग के लिए यूजर से इनपुट लेते हैं।
• हम `input_ids`DialoGPT टोकननाइज़र का उपयोग करने के लिए टेक्स्ट को एन्कोड करते हैं , हम स्ट्रिंग टोकन के अंत को भी जोड़ते हैं और इसे पाइटोरच टेंसर के रूप में वापस करते हैं।
• अगर यह पहली बार बॉट के साथ चैट कर रहा है, तो हम `input_ids`एक पीढ़ी के लिए सीधे अपने मॉडल को फीड करते हैं। अन्यथा, हम `torch.cat()`मेथड की मदद से कॉन्सटेनेशन का उपयोग करके चैट हिस्ट्री को जोड़ देते हैं ।
• उसके बाद, हम `model.generate()`चैटबॉट प्रतिक्रिया उत्पन्न करने के लिए विधि का उपयोग करते हैं ।
• अंत में, जैसा कि लौटा हुआ आउटपुट एक टोकन अनुक्रम भी है, हम अनुक्रम का उपयोग करके डीकोड करते हैं `tokenizer.decode()`और यह सुनिश्चित `skip_special_tokens`करने के `True`लिए सेट करते हैं कि हमें कोई कष्टप्रद विशेष टोकन जैसे कि `<|endoftext|>`. साथ ही, चूंकि मॉडल पूरे अनुक्रम को लौटाता है, हम पिछले चैट इतिहास को छोड़ देते हैं और केवल नए जेनरेट किए गए चैटबॉट उत्तर को प्रिंट करते हैं।

नीचे बॉट के साथ एक नमूना चर्चा है:

``````>> You:How can you be rich so quickly?
DialoGPT: I'm not rich, I'm just a rich man.
>> You:Ok, you don't make sense, how old are you ?
DialoGPT: I'm not a rich man, I'm just a rich man.
>> You:How can you be happy ?
DialoGPT: I'm not happy, I'm just a rich man.
>> You:But they say money buys happiness!
DialoGPT: Money buys happiness, but not happiness itself.
>> You:You don't make sense again!
DialoGPT: I'm not happy, I'm just a rich man.``````

आप देखते हैं कि मॉडल बहुत सारी प्रतिक्रियाओं को दोहराता है, क्योंकि ये सबसे अधिक संभावना है और यह हर बार इसे चुन रहा है।

डिफ़ॉल्ट रूप से, `model.generate()`लालची खोज एल्गोरिथ्म का उपयोग करता है जब कोई अन्य पैरामीटर सेट नहीं किया जाता है, अगले अनुभागों में, हम इस पद्धति में कुछ तर्क जोड़ेंगे कि क्या हम पीढ़ी में सुधार कर सकते हैं।

## बीम खोज के साथ प्रतिक्रिया उत्पन्न करना

बीम खोज हमें `num_beams`हर समय कदम पर परिकल्पना की सबसे अधिक संभावना रखते हुए उच्च संभावना अनुक्रमों के लापता होने के जोखिम को कम करने की अनुमति देता है और फिर उन अनुक्रमों को लेकर जिनकी समग्र उच्चतम संभावना है, नीचे दिए गए कोड बीम खोज के साथ चैटबॉट प्रतिक्रियाएं उत्पन्न करेंगे:

``````# chatting 5 times with beam search
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
num_beams=3,
early_stopping=True,
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")``````

सेट करते समय `num_beams`के लिए `3`में `model.generate()`विधि है, तो हम हर बार कदम पर 3 शब्दों का चयन और अनुक्रम के उच्चतम समग्र संभावना खोजने के लिए उन्हें विकसित करने के लिए जा रहे हैं, की स्थापना `num_beams`1 के लिए लालची खोज के समान है।

नीचे बीम खोज का उपयोग करके चैटबॉट के साथ एक नमूना चर्चा है:

``````>> You:How can I be rich?
DialoGPT: You can't.
>> You:Why not?
DialoGPT: Because you can't.
>> You:Then how am I supposed to live well?
DialoGPT: You can't.
>> You:So basically, you want me to be a poor guy?
DialoGPT: No, I want you to be a rich guy.
>> You:Ok how to be rich, then?
DialoGPT: I don't know.``````

## नमूनाकरण के साथ प्रतिक्रिया उत्पन्न करना

पिछले अनुभागों में, हमने उच्चतम संभाव्यता अनुक्रम उत्पन्न करने के लिए बीम और लालची खोज का उपयोग किया था। अब यह मशीनी अनुवाद या टेक्स्ट सारांश जैसे कार्यों के लिए बहुत अच्छा है जहां आउटपुट अनुमानित है। हालाँकि, चैटबॉट्स की तरह ओपन-एंडेड पीढ़ी के लिए यह सबसे अच्छा विकल्प नहीं है।

एक बेहतर पीढ़ी के लिए, हमें कुछ यादृच्छिकता पेश करने की आवश्यकता है जहां हम संभावनाओं के आधार पर उम्मीदवार अनुक्रमों की एक विस्तृत श्रृंखला से नमूना लेते हैं:

``````# chatting 5 times with sampling
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_k=0,
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")``````

इस बार, हमने नमूनाकरण के लिए सेट `do_sample`किया `True`है, और हम यह इंगित करने के `top_k`लिए सेट हैं `0`कि हम सभी संभावित संभावनाओं का चयन कर रहे हैं, हम बाद में `top_k`पैरामीटर पर चर्चा करेंगे ।

यहाँ इन मापदंडों के साथ बातचीत है:

``````>> You:Hello, how can I be rich?
DialoGPT: You can't
>> You:Really? then how others get rich?
DialoGPT: They work as money artists
>> You:How to be a money artist?
DialoGPT: I don't know, I don't have enough knowledge on artists
>> You:Alright, thank you!
DialoGPT: No problem, if you need tips pm me.
>> You:Great, you're my savior!
DialoGPT: Thank you for helping a stranger out like me!``````

स्पष्ट रूप से कुछ सुधार हैं। हालांकि, कम संभावनाओं वाले अनुक्रमों की एक विस्तृत सूची पर नमूना लेने से यादृच्छिक पीढ़ी हो सकती है (जैसा कि आप अंतिम वाक्य में देखते हैं)।

इसे और बेहतर बनाने के लिए, हम यह कर सकते हैं:

• नमूनाकरण कम करें `temperature`, जिससे हमें कम संभावना वाले शब्दों को चुनने की संभावना कम करने में मदद मिलती है और उच्च संभावना वाले शब्दों को चुनने की संभावना बढ़ जाती है।
• सभी संभावित घटनाओं को चुनने के बजाय टॉप-के नमूने का उपयोग करें, इससे हमें कम संभावना वाले शब्दों को चुनने से रोकने में मदद मिलेगी।
``````# chatting 5 times with Top K sampling & tweaking temperature
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_k=100,
temperature=0.75,
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")``````

अब, हम संभाव्यता द्वारा अवरोही क्रम में शीर्ष शब्दों से नमूना लेने के लिए सेट `top_k`करते हैं । हम उच्च संभावना वाले शब्दों को चुनने का एक उच्च मौका देने के लिए (डिफ़ॉल्ट है ) पर भी सेट करते हैं , तापमान को लालची खोज के समान ही सेट करते हैं, इसे अनंत पर सेट करना पूरी तरह से यादृच्छिक के समान है।`100100temperature0.751.00.0`

यहाँ इन मापदंडों के साथ एक चर्चा है:

``````>> You:How can I get rich?
DialoGPT: I'd also like to know this.
>> You:So you don't know it?
DialoGPT: I know it, but it doesn't matter.
>> You:Really? money matters, man!
DialoGPT: Well, money is money and I gotta get my money.
>> You:Yeah how to get them?
DialoGPT: Well, that's a question. I'd like to know more, just for curiosity's sake, to know what other people have said about how I should get rich.
>> You:Some robots like you told me you have to buy gold, silver or stocks.
DialoGPT: I think my wallet is empty.``````

जैसा कि आप देख सकते हैं, यह अब बहुत बेहतर है, बेझिझक ट्विक करें `temperature`और `top_k`पैरामीटर देखें और देखें कि क्या यह इसमें सुधार कर सकता है।

## न्यूक्लियस सैंपलिंग

न्यूक्लियस सैंपलिंग या टॉप-पी सैंपलिंग उन सबसे छोटे संभव शब्दों में से चुनता है जिनकी संचयी संभावना `p`हमारे द्वारा निर्धारित पैरामीटर से अधिक होती है ।

टॉप-पी सैंपलिंग का उपयोग करते हुए एक उदाहरण नीचे दिया गया है:

``````# chatting 5 times with nucleus sampling & tweaking temperature
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_p=0.95,
top_k=0,
temperature=0.75,
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")``````

हमने टॉप-के सैंपलिंग को अक्षम `top_k`करने के `0`लिए सेट किया है, लेकिन आप दोनों विधियों का उपयोग कर सकते हैं जो बेहतर काम करती हैं। यहाँ एक चैट है:

``````>> You:How can I be rich fast?
DialoGPT: Inflation and free money
>> You:lol, but that takes time, I need fast money.
DialoGPT: Your post makes no sense. You just need a lot of money to be rich fast
>> You:Ok how to get a lot of money?
>> You:Hmm, I got your point, thanks.
DialoGPT: No problem. You have to have money to buy gold, but its only good for trading it.
>> You:Yeah, I understand, thank you so much.
DialoGPT: Ok, let me know if you need help``````

अब चैटबॉट कई मामलों में स्पष्ट रूप से समझ में आता है।

अब एक से अधिक चैटबॉट प्रतिक्रिया उत्पन्न करने के लिए कुछ कोड जोड़ते हैं, और फिर हम चुनते हैं कि अगले इनपुट में किस प्रतिक्रिया को शामिल करना है:

``````# chatting 5 times with nucleus & top-k sampling & tweaking temperature & multiple
# sentences
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids_list = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_p=0.95,
top_k=50,
temperature=0.75,
num_return_sequences=5,
)
#print the outputs
for i in range(len(chat_history_ids_list)):
output = tokenizer.decode(chat_history_ids_list[i][bot_input_ids.shape[-1]:], skip_special_tokens=True)
print(f"DialoGPT {i}: {output}")
choice_index = int(input("Choose the response you want for the next input: "))
chat_history_ids = torch.unsqueeze(chat_history_ids_list[choice_index], dim=0)``````

मैंने एक बार में 5 वाक्यों को वापस `num_return_sequences`करने के `5`लिए निर्धारित किया है, हमें एक को चुनना होगा जिसे अगले अनुक्रम में शामिल किया जाएगा। यहां बताया गया है कि यह कैसे चला गया:

``````>> You:Hello, friend.
DialoGPT 0: Hey there!
DialoGPT 1: I am your friend, and I am also your friend.
DialoGPT 2: Hello. :
DialoGPT 3: Hiya! How are you?
Choose the response you want for the next input: 3
>> You:Fine, thanks, what about you?
DialoGPT 0: Good. Not much to do.
DialoGPT 1: Not much, you?
DialoGPT 2: Fine, thanks.
DialoGPT 3: I'm okay, thank you for asking.
DialoGPT 4: I'm fine too.
Choose the response you want for the next input: 2
>> You:Can you tell me how can I get rich quickly?
DialoGPT 0: Yes, I can!
DialoGPT 1: Yes, just look up how to get rich on Google.
DialoGPT 2: Just keep doing your thing. You'll get rich.
DialoGPT 3: No, I can't.
DialoGPT 4: no, i have no money
Choose the response you want for the next input: 1
>> You:Yeah, but I thought you have an answer...
DialoGPT 0: I'm getting married in the morning.
DialoGPT 1: How do you get rich?
DialoGPT 2: I think there are many good answers, but I could send you one, if you want.
DialoGPT 3: I will, thanks!
DialoGPT 4: I thought you have an answer.
Choose the response you want for the next input: 2
DialoGPT 0: You can send me link.
DialoGPT 1: I am very interested
DialoGPT 2: I sent you a PM
DialoGPT 3: I'll send you a PM
DialoGPT 4: I am always interested in new ideas.
Choose the response you want for the next input: 2``````

## निष्कर्ष

और आप वहां जाएं, मुझे आशा है कि इस ट्यूटोरियल ने आपको DialoGPT और इसी तरह के मॉडल पर टेक्स्ट जेनरेट करने में मदद की। टेक्स्ट जेनरेट करने के तरीके के बारे में अधिक जानकारी के लिए, मैं आपको ट्रांसफॉर्मर्स गाइड के साथ टेक्स्ट जेनरेट करने का तरीका पढ़ने की अत्यधिक सलाह देता हूं ।

यह देखने के लिए कि क्या आप बॉट को बेहतर प्रदर्शन कर सकते हैं, मैं आपको मापदंडों को बदलना छोड़ दूँगा।

साथ ही, आप इसे टेक्स्ट-टू-स्पीच और स्पीच-टू-टेक्स्ट ट्यूटोरियल्स के साथ जोड़कर एक वर्चुअल असिस्टेंट जैसे एलेक्सा , सिरी , कोरटाना आदि बना सकते हैं।

#python #chatbot #ai

1646796864

## Sắp Xếp Danh Sách Trong Python Với Python.sort ()

Trong bài viết này, bạn sẽ học cách sử dụng phương pháp danh sách của Python `sort()`.

Bạn cũng sẽ tìm hiểu một cách khác để thực hiện sắp xếp trong Python bằng cách sử dụng `sorted()`hàm để bạn có thể thấy nó khác với nó như thế nào `sort()`.

Cuối cùng, bạn sẽ biết những điều cơ bản về sắp xếp danh sách bằng Python và biết cách tùy chỉnh việc sắp xếp để phù hợp với nhu cầu của bạn.

## Phương pháp `sort()` - Tổng quan về cú pháp

Phương pháp `sort()` này là một trong những cách bạn có thể sắp xếp danh sách trong Python.

Khi sử dụng `sort()`, bạn sắp xếp một danh sách tại chỗ . Điều này có nghĩa là danh sách ban đầu được sửa đổi trực tiếp. Cụ thể, thứ tự ban đầu của các phần tử bị thay đổi.

Cú pháp chung cho phương thức `sort()` này trông giống như sau:

``````list_name.sort(reverse=..., key=... )
``````

Hãy chia nhỏ nó:

• `list_name` là tên của danh sách bạn đang làm việc.
• `sort()`là một trong những phương pháp danh sách của Python để sắp xếp và thay đổi danh sách. Nó sắp xếp các phần tử danh sách theo thứ tự tăng dần hoặc giảm dần .
• `sort()`chấp nhận hai tham số tùy chọn .
• `reverse` là tham số tùy chọn đầu tiên. Nó chỉ định liệu danh sách sẽ được sắp xếp theo thứ tự tăng dần hay giảm dần. Nó nhận một giá trị Boolean, nghĩa là giá trị đó là True hoặc False. Giá trị mặc định là False , nghĩa là danh sách được sắp xếp theo thứ tự tăng dần. Đặt nó thành True sẽ sắp xếp danh sách ngược lại, theo thứ tự giảm dần.
• `key` là tham số tùy chọn thứ hai. Nó có một hàm hoặc phương pháp được sử dụng để chỉ định bất kỳ tiêu chí sắp xếp chi tiết nào mà bạn có thể có.

Phương `sort()`thức trả về `None`, có nghĩa là không có giá trị trả về vì nó chỉ sửa đổi danh sách ban đầu. Nó không trả về một danh sách mới.

## Cách sắp xếp các mục trong danh sách theo thứ tự tăng dần bằng phương pháp `sort()`

Như đã đề cập trước đó, theo mặc định, `sort()`sắp xếp các mục trong danh sách theo thứ tự tăng dần.

Thứ tự tăng dần (hoặc tăng dần) có nghĩa là các mặt hàng được sắp xếp từ giá trị thấp nhất đến cao nhất.

Giá trị thấp nhất ở bên trái và giá trị cao nhất ở bên phải.

Cú pháp chung để thực hiện việc này sẽ giống như sau:

``````list_name.sort()
``````

Hãy xem ví dụ sau đây cho thấy cách sắp xếp danh sách các số nguyên:

``````# a list of numbers
my_numbers = [10, 8, 3, 22, 33, 7, 11, 100, 54]

#sort list in-place in ascending order
my_numbers.sort()

#print modified list
print(my_numbers)

#output

#[3, 7, 8, 10, 11, 22, 33, 54, 100]
``````

Trong ví dụ trên, các số được sắp xếp từ nhỏ nhất đến lớn nhất.

Bạn cũng có thể đạt được điều tương tự khi làm việc với danh sách các chuỗi:

``````# a list of strings
programming_languages = ["Python", "Swift","Java", "C++", "Go", "Rust"]

#sort list in-place in alphabetical order
programming_languages.sort()

#print modified list
print(programming_languages)

#output

#['C++', 'Go', 'Java', 'Python', 'Rust', 'Swift']
``````

Trong trường hợp này, mỗi chuỗi có trong danh sách được sắp xếp theo thứ tự không tuân theo.

Như bạn đã thấy trong cả hai ví dụ, danh sách ban đầu đã được thay đổi trực tiếp.

## Cách sắp xếp các mục trong danh sách theo thứ tự giảm dần bằng phương pháp `sort()`

Thứ tự giảm dần (hoặc giảm dần) ngược lại với thứ tự tăng dần - các phần tử được sắp xếp từ giá trị cao nhất đến thấp nhất.

Để sắp xếp các mục trong danh sách theo thứ tự giảm dần, bạn cần sử dụng `reverse` tham số tùy chọn với phương thức `sort()` và đặt giá trị của nó thành `True`.

Cú pháp chung để thực hiện việc này sẽ giống như sau:

``````list_name.sort(reverse=True)
``````

Hãy sử dụng lại cùng một ví dụ từ phần trước, nhưng lần này làm cho nó để các số được sắp xếp theo thứ tự ngược lại:

``````# a list of numbers
my_numbers = [10, 8, 3, 22, 33, 7, 11, 100, 54]

#sort list in-place in descending order
my_numbers.sort(reverse=True)

#print modified list
print(my_numbers)

#output

#[100, 54, 33, 22, 11, 10, 8, 7, 3]
``````

Bây giờ tất cả các số được sắp xếp ngược lại, với giá trị lớn nhất ở bên tay trái và giá trị nhỏ nhất ở bên phải.

Bạn cũng có thể đạt được điều tương tự khi làm việc với danh sách các chuỗi.

``````# a list of strings
programming_languages = ["Python", "Swift","Java", "C++", "Go", "Rust"]

#sort list in-place in  reverse alphabetical order
programming_languages.sort(reverse=True)

#print modified list
print(programming_languages)

#output

#['Swift', 'Rust', 'Python', 'Java', 'Go', 'C++']
``````

Các mục danh sách hiện được sắp xếp theo thứ tự bảng chữ cái ngược lại.

## Cách sắp xếp các mục trong danh sách bằng cách sử dụng `key` tham số với phương thức `sort()`

Bạn có thể sử dụng `key` tham số để thực hiện các thao tác sắp xếp tùy chỉnh hơn.

Giá trị được gán cho `key` tham số cần phải là thứ có thể gọi được.

Callable là thứ có thể được gọi, có nghĩa là nó có thể được gọi và tham chiếu.

Một số ví dụ về các đối tượng có thể gọi là các phương thức và hàm.

Phương thức hoặc hàm được gán cho `key` này sẽ được áp dụng cho tất cả các phần tử trong danh sách trước khi bất kỳ quá trình sắp xếp nào xảy ra và sẽ chỉ định logic cho tiêu chí sắp xếp.

Giả sử bạn muốn sắp xếp danh sách các chuỗi dựa trên độ dài của chúng.

Đối với điều đó, bạn chỉ định `len()`hàm tích hợp cho `key` tham số.

Hàm `len()`sẽ đếm độ dài của từng phần tử được lưu trong danh sách bằng cách đếm các ký tự có trong phần tử đó.

``````programming_languages = ["Python", "Swift","Java", "C++", "Go", "Rust"]

programming_languages.sort(key=len)

print(programming_languages)

#output

#['Go', 'C++', 'Java', 'Rust', 'Swift', 'Python']
``````

Trong ví dụ trên, các chuỗi được sắp xếp theo thứ tự tăng dần mặc định, nhưng lần này việc sắp xếp xảy ra dựa trên độ dài của chúng.

Chuỗi ngắn nhất ở bên trái và dài nhất ở bên phải.

Các `key``reverse` tham số cũng có thể được kết hợp.

Ví dụ: bạn có thể sắp xếp các mục trong danh sách dựa trên độ dài của chúng nhưng theo thứ tự giảm dần.

``````programming_languages = ["Python", "Swift","Java", "C++", "Go", "Rust"]

programming_languages.sort(key=len, reverse=True)

print(programming_languages)

#output

#['Python', 'Swift', 'Java', 'Rust', 'C++', 'Go']
``````

Trong ví dụ trên, các chuỗi đi từ dài nhất đến ngắn nhất.

Một điều cần lưu ý nữa là bạn có thể tạo một chức năng sắp xếp tùy chỉnh của riêng mình, để tạo các tiêu chí sắp xếp rõ ràng hơn.

Ví dụ: bạn có thể tạo một hàm cụ thể và sau đó sắp xếp danh sách theo giá trị trả về của hàm đó.

Giả sử bạn có một danh sách các từ điển với các ngôn ngữ lập trình và năm mà mỗi ngôn ngữ lập trình được tạo ra.

``````programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]
``````

Bạn có thể xác định một hàm tùy chỉnh nhận giá trị của một khóa cụ thể từ từ điển.

💡 Hãy nhớ rằng khóa từ điển và `key` tham số `sort()`chấp nhận là hai thứ khác nhau!

Cụ thể, hàm sẽ lấy và trả về giá trị của `year` khóa trong danh sách từ điển, chỉ định năm mà mọi ngôn ngữ trong từ điển được tạo.

Giá trị trả về sau đó sẽ được áp dụng làm tiêu chí sắp xếp cho danh sách.

``````programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]

def get_year(element):
return element['year']
``````

Sau đó, bạn có thể sắp xếp theo giá trị trả về của hàm bạn đã tạo trước đó bằng cách gán nó cho `key` tham số và sắp xếp theo thứ tự thời gian tăng dần mặc định:

``````programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]

def get_year(element):
return element['year']

programming_languages.sort(key=get_year)

print(programming_languages)
``````

Đầu ra:

``````[{'language': 'C++', 'year': 1985}, {'language': 'Python', 'year': 1991}, {'language': 'Java', 'year': 1995}, {'language': 'Go', 'year': 2007}, {'language': 'Rust', 'year': 2010}, {'language': 'Swift', 'year': 2014}]
``````

Nếu bạn muốn sắp xếp từ ngôn ngữ được tạo gần đây nhất đến ngôn ngữ cũ nhất hoặc theo thứ tự giảm dần, thì bạn sử dụng `reverse=True`tham số:

``````programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]

def get_year(element):
return element['year']

programming_languages.sort(key=get_year, reverse=True)

print(programming_languages)
``````

Đầu ra:

``````[{'language': 'Swift', 'year': 2014}, {'language': 'Rust', 'year': 2010}, {'language': 'Go', 'year': 2007}, {'language': 'Java', 'year': 1995}, {'language': 'Python', 'year': 1991}, {'language': 'C++', 'year': 1985}]
``````

Để đạt được kết quả chính xác, bạn có thể tạo một hàm lambda.

Thay vì sử dụng hàm tùy chỉnh thông thường mà bạn đã xác định bằng `def` từ khóa, bạn có thể:

• tạo một biểu thức ngắn gọn một dòng,
• và không xác định tên hàm như bạn đã làm với `def` hàm. Các hàm lambda còn được gọi là các hàm ẩn danh .
``````programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]

programming_languages.sort(key=lambda element: element['year'])

print(programming_languages)
``````

Hàm lambda được chỉ định với dòng `key=lambda element: element['year']`sắp xếp các ngôn ngữ lập trình này từ cũ nhất đến mới nhất.

## Sự khác biệt giữa `sort()`và `sorted()`

Phương `sort()`thức hoạt động theo cách tương tự như `sorted()`hàm.

Cú pháp chung của `sorted()`hàm trông như sau:

``````sorted(list_name,reverse=...,key=...)
``````

Hãy chia nhỏ nó:

• `sorted()`là một hàm tích hợp chấp nhận một có thể lặp lại. Sau đó, nó sắp xếp nó theo thứ tự tăng dần hoặc giảm dần.
• `sorted()`chấp nhận ba tham số. Một tham số là bắt buộc và hai tham số còn lại là tùy chọn.
• `list_name` là tham số bắt buộc . Trong trường hợp này, tham số là danh sách, nhưng `sorted()`chấp nhận bất kỳ đối tượng có thể lặp lại nào khác.
• `sorted()`cũng chấp nhận các tham số tùy chọn `reverse``key`, đó là các tham số tùy chọn tương tự mà phương thức `sort()` chấp nhận.

Sự khác biệt chính giữa `sort()``sorted()``sorted()`hàm nhận một danh sách và trả về một bản sao được sắp xếp mới của nó.

Bản sao mới chứa các phần tử của danh sách ban đầu theo thứ tự được sắp xếp.

Các phần tử trong danh sách ban đầu không bị ảnh hưởng và không thay đổi.

Vì vậy, để tóm tắt sự khác biệt:

• Phương `sort()`thức không có giá trị trả về và trực tiếp sửa đổi danh sách ban đầu, thay đổi thứ tự của các phần tử chứa trong nó.
• Mặt khác, `sorted()`hàm có giá trị trả về, là một bản sao đã được sắp xếp của danh sách ban đầu. Bản sao đó chứa các mục danh sách của danh sách ban đầu theo thứ tự được sắp xếp. Cuối cùng, danh sách ban đầu vẫn còn nguyên vẹn.

Hãy xem ví dụ sau để xem nó hoạt động như thế nào:

``````#original list of numbers
my_numbers = [10, 8, 3, 22, 33, 7, 11, 100, 54]

#sort original list in default ascending order
my_numbers_sorted = sorted(my_numbers)

#print original list
print(my_numbers)

#print the copy of the original list that was created
print(my_numbers_sorted)

#output

#[10, 8, 3, 22, 33, 7, 11, 100, 54]
#[3, 7, 8, 10, 11, 22, 33, 54, 100]
``````

Vì không có đối số bổ sung nào được cung cấp `sorted()`, nó đã sắp xếp bản sao của danh sách ban đầu theo thứ tự tăng dần mặc định, từ giá trị nhỏ nhất đến giá trị lớn nhất.

Và khi in danh sách ban đầu, bạn thấy rằng nó vẫn được giữ nguyên và các mục có thứ tự ban đầu.

Như bạn đã thấy trong ví dụ trên, bản sao của danh sách đã được gán cho một biến mới `my_numbers_sorted`,.

Một cái gì đó như vậy không thể được thực hiện với `sort()`.

Hãy xem ví dụ sau để xem điều gì sẽ xảy ra nếu điều đó được thực hiện với phương thức `sort()`.

``````my_numbers = [10, 8, 3, 22, 33, 7, 11, 100, 54]

my_numbers_sorted = my_numbers.sort()

print(my_numbers)
print(my_numbers_sorted)

#output

#[3, 7, 8, 10, 11, 22, 33, 54, 100]
#None
``````

Bạn thấy rằng giá trị trả về của `sort()``None`.

Cuối cùng, một điều khác cần lưu ý là các `reverse``key` tham số mà `sorted()`hàm chấp nhận hoạt động giống hệt như cách chúng thực hiện với phương thức `sort()` bạn đã thấy trong các phần trước.

### Khi nào sử dụng `sort()`và`sorted()`

Dưới đây là một số điều bạn có thể muốn xem xét khi quyết định có nên sử dụng `sort()`vs. `sorted()`

Trước tiên, hãy xem xét loại dữ liệu bạn đang làm việc:

• Nếu bạn đang làm việc nghiêm ngặt với một danh sách ngay từ đầu, thì bạn sẽ cần phải sử dụng `sort()`phương pháp này vì `sort()`chỉ được gọi trong danh sách.
• Mặt khác, nếu bạn muốn linh hoạt hơn và chưa làm việc với danh sách, thì bạn có thể sử dụng `sorted()`. Hàm `sorted()`chấp nhận và sắp xếp mọi thứ có thể lặp lại (như từ điển, bộ giá trị và bộ) chứ không chỉ danh sách.

Tiếp theo, một điều khác cần xem xét là liệu bạn có giữ được thứ tự ban đầu của danh sách mà bạn đang làm việc hay không:

• Khi gọi `sort()`, danh sách ban đầu sẽ bị thay đổi và mất thứ tự ban đầu. Bạn sẽ không thể truy xuất vị trí ban đầu của các phần tử danh sách. Sử dụng `sort()`khi bạn chắc chắn muốn thay đổi danh sách đang làm việc và chắc chắn rằng bạn không muốn giữ lại thứ tự đã có.
• Mặt khác, `sorted()`nó hữu ích khi bạn muốn tạo một danh sách mới nhưng bạn vẫn muốn giữ lại danh sách bạn đang làm việc. Hàm `sorted()`sẽ tạo một danh sách được sắp xếp mới với các phần tử danh sách được sắp xếp theo thứ tự mong muốn.

Cuối cùng, một điều khác mà bạn có thể muốn xem xét khi làm việc với các tập dữ liệu lớn hơn, đó là hiệu quả về thời gian và bộ nhớ:

• Phương `sort()`pháp này chiếm dụng và tiêu tốn ít bộ nhớ hơn vì nó chỉ sắp xếp danh sách tại chỗ và không tạo ra danh sách mới không cần thiết mà bạn không cần. Vì lý do tương tự, nó cũng nhanh hơn một chút vì nó không tạo ra một bản sao. Điều này có thể hữu ích khi bạn đang làm việc với danh sách lớn hơn chứa nhiều phần tử hơn.

## Phần kết luận

Và bạn có nó rồi đấy! Bây giờ bạn đã biết cách sắp xếp một danh sách trong Python bằng `sort()`phương pháp này.

Bạn cũng đã xem xét sự khác biệt chính giữa sắp xếp danh sách bằng cách sử dụng `sort()``sorted()`.

Tôi hy vọng bạn thấy bài viết này hữu ích.

Để tìm hiểu thêm về ngôn ngữ lập trình Python, hãy xem Chứng chỉ Máy tính Khoa học với Python của freeCodeCamp .

Bạn sẽ bắt đầu từ những điều cơ bản và học theo cách tương tác và thân thiện với người mới bắt đầu. Bạn cũng sẽ xây dựng năm dự án vào cuối để áp dụng vào thực tế và giúp củng cố những gì bạn đã học được.