Browse Source

Merge branch 'master' into readmes

pull/92/head
Frenchris 5 years ago committed by GitHub
parent
commit
5ee1fd9e09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 220
      docs/modular-steps-management.md
  2. 162
      docs/object-attribute-system.md
  3. 33
      docs/object-child-creation.md
  4. 53
      docs/object-creation.md
  5. 34
      docs/object-edit.md
  6. 29
      docs/objects.md
  7. 64
      docs/ubuntu-installation.md
  8. 88
      examples/call-graphql.go
  9. 59
      scripts/bash_tweaks.sh
  10. 55
      scripts/clean.sh
  11. 64
      scripts/common_packages.txt
  12. 131
      scripts/dconfig.txt
  13. 15
      scripts/firewall.sh
  14. 9
      scripts/fx.sh
  15. 24
      scripts/go.sh
  16. 25
      scripts/grub.sh
  17. 87
      scripts/install_client.sh
  18. 10
      scripts/nodejs.sh
  19. 34
      scripts/set.sh
  20. 25
      scripts/ssh.sh
  21. 17
      scripts/sublime.sh
  22. 74
      scripts/system/etc/gdm3/PostLogin/Default
  23. 25
      scripts/system/etc/gdm3/PostSession/Default
  24. 1
      scripts/system/etc/udev/rules.d/10-local.rules
  25. 13
      scripts/system/usr/local/bin/lock_screen
  26. 13
      scripts/system/usr/local/bin/suspend_session
  27. 8
      scripts/system/usr/share/applications/lock_screen.desktop
  28. 8
      scripts/system/usr/share/applications/suspend_session.desktop
  29. 22
      scripts/system/usr/share/initramfs-tools/hooks/copy_mkfs
  30. 20
      scripts/system/usr/share/initramfs-tools/scripts/init-premount/reformat
  31. 118
      scripts/ubuntu_tweaks.sh
  32. 35
      scripts/vscode.sh
  33. 18
      subjects/abort.en.md
  34. 19
      subjects/activebits.en.md
  35. 42
      subjects/advancedsortwordarr.en.md
  36. 42
      subjects/advancedsortwordarr.fr.md
  37. 1
      subjects/advancedsortwordtab.en.md
  38. 29
      subjects/alphamirror.en.md
  39. 48
      subjects/any.en.md
  40. 48
      subjects/any.fr.md
  41. 48
      subjects/appendrange.en.md
  42. 47
      subjects/appendrange.fr.md
  43. 77
      subjects/atoi.en.md
  44. 77
      subjects/atoi.fr.md
  45. 59
      subjects/atoibase.en.md
  46. 59
      subjects/atoibase.fr.md
  47. 57
      subjects/basicatoi.en.md
  48. 57
      subjects/basicatoi.fr.md
  49. 62
      subjects/basicatoi2.en.md
  50. 62
      subjects/basicatoi2.fr.md
  51. 40
      subjects/basicjoin.en.md
  52. 40
      subjects/basicjoin.fr.md
  53. 20
      subjects/bool.en.md
  54. 18
      subjects/btreeapplybylevel.en.md
  55. 48
      subjects/btreeapplyinorder.en.md
  56. 47
      subjects/btreeapplypostorder.en.md
  57. 47
      subjects/btreeapplypreorder.en.md
  58. 17
      subjects/btreedeletenode.en.md
  59. 52
      subjects/btreeinsertdata.en.md
  60. 20
      subjects/btreeisbinary.en.md
  61. 18
      subjects/btreelevelcount.en.md
  62. 18
      subjects/btreemax.en.md
  63. 18
      subjects/btreemin.en.md
  64. 48
      subjects/btreeprintroot.en.md
  65. 74
      subjects/btreesearchitem.en.md
  66. 18
      subjects/btreetransplant.en.md
  67. 41
      subjects/capitalize.en.md
  68. 41
      subjects/capitalize.fr.md
  69. 16
      subjects/cat.en.md
  70. 21
      subjects/cl-camp1.en.md
  71. 21
      subjects/cl-camp1.fr.md
  72. 17
      subjects/cl-camp2.en.md
  73. 17
      subjects/cl-camp2.fr.md
  74. 15
      subjects/cl-camp3.en.md
  75. 15
      subjects/cl-camp3.fr.md
  76. 24
      subjects/cl-camp4.en.md
  77. 24
      subjects/cl-camp4.fr.md
  78. 26
      subjects/cl-camp5.en.md
  79. 26
      subjects/cl-camp5.fr.md
  80. 15
      subjects/cl-camp6.en.md
  81. 15
      subjects/cl-camp6.fr.md
  82. 15
      subjects/cl-camp7.en.md
  83. 15
      subjects/cl-camp7.fr.md
  84. 11
      subjects/cl-camp8.en.md
  85. 11
      subjects/cl-camp8.fr.md
  86. 21
      subjects/cl.en.md
  87. 18
      subjects/collatzcountdown.en.md
  88. 9
      subjects/comcheck.en.md
  89. 114
      subjects/commandments.en.md
  90. 12
      subjects/compact.en.md
  91. 43
      subjects/compare.en.md
  92. 43
      subjects/compare.fr.md
  93. 40
      subjects/concat.en.md
  94. 40
      subjects/concat.fr.md
  95. 44
      subjects/concatparams.en.md
  96. 44
      subjects/concatparams.fr.md
  97. 43
      subjects/convertbase.en.md
  98. 43
      subjects/convertbase.fr.md
  99. 10
      subjects/countdown.en.md
  100. 44
      subjects/countif.en.md
  101. Some files were not shown because too many files changed in this diff diff.show_more

220
docs/modular-steps-management.md

@ -0,0 +1,220 @@
# Sign up & onboarding's Administration section - Modular steps management
## Usage
> After their first authentication in the app, every candidate has to do his **sign up** and his **onboarding**. The steps that compose the **sign up** and the **administration** section of the onboarding are either:
> * Forms (identification, medical information, etc.)
> * Documents to sign (general conditions, charts, regulations, etc.)
>
> All the sections are modular: you can add, update, delete and order them as you wish.
>
> This documentation explains how to manage these steps.
## Create your step child object
### Create a new object for your step in the admin
> Information is available for object's creation: [Object creation](https://github.com/01-edu/public/blob/master/doc/object-creation.md)
* This object must have the same type as its future parent object (*signup* or *onboarding*).
> Your step is then available in the *Admin*. You can find it in the section of its type (*SignUp* or *Onboarding*) or thanks to the search bar of the cursus object's page.
### Add this new object as a child of your parent's object
* Edit the parent object: *Sign up* or *Administration*
> Information is available for object's creation: [Child object creation](https://github.com/01-edu/public/blob/master/doc/child-object-creation.md)
## Settings for a `form` step
> In the step object you have created, 2 attributes must be filled:
> 1. Subtype
> 2. Form
### Description
#### Edit the step object you have created :
> in *Object attributes*
<img width="1073" alt="Capture d’écran 2019-04-22 à 15 59 33" src="https://user-images.githubusercontent.com/35296671/56507445-3936ef00-6519-11e9-90c8-d85056e9330b.png">
* Add a new key **subtype** of type `String` with the exact value 'form-step'
* Add a new key **form** of type `Object`
* Form can have several sections. Each section is displayed with a title, and its inputs.
> NB: The submission of the form will check the required inputs of all the sections created for the form.
* To create a section, add a new key to the form object, of type `Object`, that contains:
* A **title** key of type `String`. The value of this property will be the title displayed in the top of the form section.
> If there is only one section in the form step, and no section title is needed, this property can be ignored.
* An **inputs** key of type `Object`, which will contain all the inputs of the section. For each wanted input, add a new `Object` element in the "inputs" object.
> The key of this object will be used as the "name" attribute of your input.
> The values will be considered as the properties of your input.
#### Defining an input:
* A **type** key of type `String` must be declared. It defines the type of the input : `tel`, `text`, `date`, `select`, `radio`, `switch`, `checkbox`, `textarea`, `countries`.
* All other attributes needed for the input can be added to the object, according to the input type: `placeholder`, `id`, `required`, `label`, `items`, `emptyItems`, `index`, etc...
#### Important indication:
* The **index** property is used to order the inputs. It will not be passed onto the input. Be mindful not to set the same index twice.
* The **type** property is required. It will be used to determine the kind of input should be generated. It is passed onto the input only if the input type attribute is required (type 'tel' or 'text' for example, but not for type 'select' - in this case, we will generate a select element)
* A special type 'countries' has been added to the classicals. It generate a `Select` (containing all the countries) with a search bar. 'Items' property is handled by the app.
* It's recommended to add 'min' and 'max' properties to input type 'date' (no default value are set).
* `onChange` prop are ignored as the event is handled by the app.
* For `switch` and `checkbox` input types, the default value has to be set as a boolean property named **value**.
* More information for each inputs is available in the design documentation:
* [textInput documentation](https://alem.01-edu.org/design/Components/FormInputs/TextInput) - used for inputs type 'text', 'tel', and 'date'
* [textArea documentation](https://alem.01-edu.org/design/Components/FormInputs/TextArea)
* [select documentation](https://alem.01-edu.org/design/Components/FormControls/Select)
* [radio button documentation](https://alem.01-edu.org/design/Components/FormControls/Radio)
* [switch documentation](https://alem.01-edu.org/design/Components/FormControls/Switch)
* [checkbox documentation](https://alem.01-edu.org/design/Components/FormControls/Checkbox)
### Examples
Here is an example of the form step's attributes. It presents a form with two sections, and an example of each kind of input type.
> NB : this example object is provided in the admin, in the onboarding section: 'Form step example'.
```json
{
"subtype": "form-step",
"form": {
"identification": {
"title": "Identification",
"inputs": {
"firstName": {
"index": 0,
"placeholder": "First name",
"maxLength": 50,
"type": "text",
"required": true
},
"tel": {
"index": 1,
"required": true,
"type": "tel",
"label": "Phone number",
"placeholder": "+333 33 33 33 33",
"pattern": "[+][3][0-9]{2}[0-9]{2}[0-9]{2}[0-9]{2}[0-9]{2}"
},
"medicalInfo": {
"label": "Medical informations",
"placeholder": "Your medical Informations",
"index": 7,
"maxLength": 250,
"type": "textarea"
},
"dateOfBirth": {
"index": 2,
"required": true,
"type": "date",
"label": "Date of birth",
"min": "1621-07-08",
"max": "1900-01-01",
"value": "2000-01-01"
},
"country": {
"index": 4,
"id": "countries",
"type": "countries",
"required": true,
"emptyItem": { "label": "Select your country label" }
},
"gender": {
"index": 3,
"type": "select",
"id": "genders",
"required": true,
"emptyItem": { "label": "Select your gender" },
"items": [
{ "label": "Male", "data": "male" },
{ "label": "Female", "data": "female" }
]
},
"environment": {
"index": 5,
"type": "radio",
"required": true,
"label": "Which environment do you live in ?",
"inlineBlock": true,
"items": [
{ "label": "City", "data": "city" },
{ "label": "Countryside", "data": "countryside" }
]
},
"programmingAbilities": {
"index": 6,
"type": "switch",
"label": "I am new in programming",
"value": true
},
"generalConditions": {
"index": 8,
"type": "checkbox",
"label": "I have read and I accept the general conditions",
"value": false
}
}
},
"moreAboutYou": {
"title": "More about you",
"inputs": {
"favoriteColor": {
"index": 0,
"placeholder": "Your favorite color",
"type": "text",
"required": true
}
}
}
}
}
```
This 'form' step would look like this:
![form step example](https://user-images.githubusercontent.com/35296671/56816457-7cf06800-683b-11e9-9003-6f83b4545033.png)
## Settings for a `document to sign` step
The newly created child can be customized with these attributes :
| name | fullfillment |
| ---------- | --------- |
| subtype | **required** |
| text | **required** |
| buttonText | optionnal |
| checkbox | optionnal |
### Description
#### To set up the child object you have created with these elements:
1. Edit you step object
2. Go to *Object attributes*
3. Add the following attributes:
* Add a new key **subtype** of type `String` with the exact value 'sign-step'
* Add a new key **text** of type `String` with the text of your document to sign as value
* Add a new key **buttonText** of type `String` with the text that you want to display in the submit button of your step. Default value for this attribute is 'Sign'.
* Add a new key **checkbox** of type `Object`, if the user has to be forced to click on a checkbox before validating his document (ex: 'I have read and accepted the conditions'). In the checkbox object, the following attributes should be defined:
* A **label** key of type `String`, for the text associated to the checkbox
* A **required** key of type `Boolean`, set at true if the user has to check it
* A **name** key of type `String`
* All other attributes wanted for the checkbox.
### Examples
Here is an example of the structure a 'document to sign' step could have:
```json
{
"subtype": "sign-step",
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent ornare non sem eu pretium. Integer porttitor risus eget nibh iaculis, ac lacinia orci dictum. Nunc ullamcorper consequat enim in posuere. Aliquam volutpat est odio, vel maximus arcu maximus sit amet. Donec ultricies faucibus magna id luctus. Duis et dapibus elit. In vestibulum ipsum erat, at commodo tortor convallis vel. Nunc ut ultrices nulla. Etiam lorem justo, consequat a consectetur a, porttitor non turpis. Mauris eu mollis nisl, id dignissim quam. Curabitur condimentum sollicitudin rutrum. Aenean blandit, arcu nec ullamcorper rhoncus, lectus sem lacinia lorem, venenatis dignissim velit mi et sapien. Nullam posuere augue ut magna ullamcorper dignissim. Ut rhoncus sapien vel nulla commodo finibus. Cras non leo vel urna finibus volutpat. Praesent et ex eget diam tincidunt suscipit. Phasellus bibendum neque vel placerat iaculis. Vestibulum bibendum ultrices ipsum, non sodales lectus. Cras eget orci eget elit blandit scelerisque at ut nulla. Integer ligula eros, eleifend quis sodales a, porttitor sit amet neque. Fusce mollis magna at lectus varius, quis suscipit mi cursus. Etiam id imperdiet metus, in malesuada quam. Aliquam facilisis nunc non sapien condimentum, quis iaculis nisl auctor. Nunc lorem sapien, interdum vel efficitur ac, dapibus a diam. Ut ante urna, sodales in bibendum vel, lacinia ut mauris. In vel placerat leo. In libero dui, tincidunt at sem id, faucibus sollicitudin elit.",
"buttonText": "Sign chart",
"checkbox": {
"name":"acceptChart",
"label":"I have read and accepted the Chart 01",
"required":true
}
}
```
This 'document to sign' step would look like this:
![document to sign step example](https://user-images.githubusercontent.com/35296671/56504782-8f079900-6511-11e9-9a0e-bb638b6d7d03.png)

162
docs/object-attribute-system.md

@ -0,0 +1,162 @@
# Object Attributes System
> This document cover two notions, the edition of attributes and the impact it has relatively to the others Objects.
## Edition of Attributes
> There is no limit to how many attributes can be defined to an Object.
In the "Object Attributes" section of the "Object Edit" Page, the first row is a form to create and append a new attribute. It requires two elements, the name of the attribute and its type (`String`, `Number`, `Boolean`, `Array`, `Object`, `Function`, `Null`). Click 'Add' to create the attribute.
> Within a same Object, each attribute's name must be unique.
Once created, the new attributes appears right bellow and the ability to associate a value to it is now available. Depending on the type of the attribute, the interface will vary.
- String value input is type String.
- Number value input is type Number.
- Booleans value input appears as a switch, true by default.
- Arrays and Objects content are hideable / showable via the "Show/Hide content" button on the right of the attribute. There is no limit on the depth of Object/Array, however, after a certain level, the interface will start to feel narrow.
- String value input is type String.
- Null will not display any input.
- Function will offer to select from all available functions, save on select.
Any attribute can be delete by clicking on the 'trash' icon on the right hand of it.
Here an example of how the section looks like.
![object-attributes](https://user-images.githubusercontent.com/15313830/56677487-88675600-66b8-11e9-9781-26dc0ee6301d.png)
## Attributes and RelationShips
When an attributes is set to an Object, other Objects, associated to this particular Object, will have access to it. Which means that, if an Object A is added as a child of an Object B, A will embed its attributes within the instance of B.
Object's attributes follow a hierarchy when associated to an other Object.
The **defaults attributes** of a child, the ones defined in the original Object are the weakest ones. A **children attribute** is applied to all the children and override the default attributes. Finally, **relation attribute** is the strongest one, it override Default Attributes and Children Attributes.
When an object and its relationship are resolved, the three structures (`attrs`, `childrenAttrs`, `childAttrs`) are merged.
The following json shows how the object would be represented:
```json
{
"children": {
"printalphabet": {
"duration": 3600,
"xp": 800,
"isBonus": true
}
}
}
```
Children
![children](https://user-images.githubusercontent.com/15313830/56679319-b189e580-66bc-11e9-8f2a-3d51eb1486d4.png)
Child
![chilld-capture](https://user-images.githubusercontent.com/15313830/56679320-b189e580-66bc-11e9-90ab-c8f69f531876.png)
## Detailed example
Let's create a few `exercises` objects
> swap
```js
{
"id": 12344,
"title": "swap",
"attrs": {
"language": "go",
"duration": 7200
}
}
```
> printalphabet
```js
{
"id": 12345,
"title": "printalphabet-v2",
"attrs": {
"language": "go",
"duration": 3600
}
}
```
We can now create a parent object that will reference them and link them.
This allow you to specify the structuration of your pedagocial content.
I'll make a quest that regroup those 2 exercises:
> quest-03
```js
{
"id": 12346,
"title": "quest-03",
"attrs": {},
"childrenAttrs": {
"xp": 800,
"duration": 4800,
},
"children": {
"printalphabet": {
"ref": 12345,
"index": 0,
"attrs": {
"duration": 7200
}
},
"swap": {
"ref": 12344,
"index": 1,
"attrs": {}
}
}
}
```
All done, now when rendering an object, attributes are merged like so:
> rendered quest object
```js
{
"id": 12346,
"title": "quest-03",
"attrs": {},
"children": {
"printalphabet": {
"ref": 12345,
"index": 0,
"attrs": {
"language": "go",
"xp": 800,
"duration": 7200
}
},
"swap": {
"ref": 12344,
"index": 1,
"attrs": {
"language": "go",
"xp": 800,
"duration": 4800
}
}
}
}
```
First we apply the **default attributes** from the referenced object.
> Here `duration` and `language` are applied.
Then we apply the **children attributes** to every child.
> In this case we override every `duration` to 4800 and add the new `xp` attribute.
After that we apply the **relation attributes**, that are the most specific and as such,
override all others attributes.
> In this case only the `printalphabet` relation had attributes and so we apply
the given `duration` to the final merged object.

33
docs/object-child-creation.md

@ -0,0 +1,33 @@
# Admin object's management - create a child object
## Usage
> Objects of the Admin can be configured :
> * By setting particular **attributes** to the object
> * By associating **children** to the object
>
> Children can be added, deleted, reordered in the list. Also, it's possible to configure it in a special way for the parent object, by setting children attributes for all the children.
>
> This documentation explains how to associate a child to a parent object.
### Create a new object for your child in the admin
> Information is available for object's creation: [Modular step management](https://github.com/01-edu/public/blob/master/doc/object-creation.md)
### Add this new object as a child of your parent's object
#### 1. Edit the parent object
<img width="640" alt="Capture d’écran 2019-04-22 à 19 24 23" src="https://user-images.githubusercontent.com/35296671/56517407-cb98bc00-6534-11e9-98d6-a2b1c0193a38.png">
<img width="640" alt="Capture d’écran 2019-04-22 à 19 24 10" src="https://user-images.githubusercontent.com/35296671/56517421-d0f60680-6534-11e9-86ef-97fb9e59786e.png">
#### 2. Go to *Children* > *Add a child*
![add child to parent object](https://user-images.githubusercontent.com/35296671/56506977-de50c800-6517-11e9-9c71-d19a1ec4e5cd.png)
#### 3. Set up the new child:
* Enter its name in the input "Add a child name"
* Select your step object in the select input
* Click on "ADD"
> Your step is then related to its parent. You can see it in the *Children* section of the parent's object. There, you can now:
> * Delete the child from its parent (the actual object of your child will not be deleted).
> * Reorder it in the children's list, by dragging it to the place you want.
> * Update its original settings by clicking on the eye icon of its reference (redirection to object edit page of the child).
<img width="1229" alt="Capture d’écran 2019-04-22 à 19 51 12" src="https://user-images.githubusercontent.com/35296671/56518936-a1e19400-6538-11e9-81c7-520ffd365cff.png">

53
docs/object-creation.md

@ -0,0 +1,53 @@
# Admin object's management - create an object
## Usage
> Elements of the app are managed through objects in *Admin*.
> Objects of the Admin are first created and defined:
> * By their **title**,
> * By their **type**.
> Then it can be configured through:
> * Attributes,
> * Children.
> This documentation explains how to create an object.
### Create a new object in the admin
> (in *Admin* > *Add new object*)
<img width="664" alt="Capture d’écran 2019-04-22 à 15 57 37" src="https://user-images.githubusercontent.com/35296671/56507169-6505a500-6518-11e9-89bb-04c7fd9b41ca.png">
<img width="450" alt="Capture d’écran 2019-04-22 à 15 58 21" src="https://user-images.githubusercontent.com/35296671/56507180-6afb8600-6518-11e9-97a5-4dcff8f0a069.png">
* The **title** of your object will be the title displayed to your candidates. Use an intellegible title for your user.
> NB: you can always edit it in the *Admin*
* The **type** depends on the nature of your object:
* **Campus** is used to declare a school.
* Examples: *Alem*, *Madeira*, etc.
* Campus can contains cursus: *Alem* contains for example *01-classical* and *Piscine Go*.
* **Cursus** is used to declare a course.
* Examples: *01-classical*, *Piscine Go*, etc.
* Cursuses can contains cursuses: the main cursus *01-classical*, for example, contains cursuses like *Piscine Go*, but also all the branches that the student have access to, as *Web*, *Security*, *Algorythm*, *Design*, etc.
* Cursuses can contains quests: *Piscine Go* of *01-classical* contains quests like *Quest 1* or *Quest 2*.
* **Quest** is used to declare a project.
* Examples: *Quest 1*, *Quest 2*, etc.
* Quest contains exercises: *Quest 1* of *Piscine Go* contains exercises like *printalphabet* or *printcomb*.
* Exercise is used to declare exercises
* Examples: *printalphabet*, *printcomb*, *atoi*, etc.
* Exercises doesn't contains any children.
* Signup is used to declare steps of the registration.
* Examples: *Using our services*, *Tell us more about you*, etc.
* One major object *Sign up* contains all the sign up's modular steps : *Using our services*, *Tell us more about you*, etc.
* Onbaording is used to declare steps of the onbaording.
* Examples: *Toad*, *Administration*, *Additional Informations*, *Chart 01*, etc.
* Three main objects define the major steps of the onboarding : *Toad*, *Administration*, *Piscine*.
* *Administration* contains modular steps: *Additional Informations*, *Chart 01*, etc.
> The child object is then available in the *Admin*. It can be found in the section of its type or thanks to the search bar of the cursus object's page.
> More information is available:
> * for setting attributes of an object: (soon available)
> * for setting children of an object: [Child object creation](https://github.com/01-edu/public/blob/master/doc/child-object-creation.md)
> * for creation of modular steps in Sign up and onboarding's Administration object: [Modular step management](https://github.com/01-edu/public/blob/master/doc/modular-steps-management.md)

34
docs/object-edit.md

@ -0,0 +1,34 @@
# Objects Edition
> Allow you to edit an object, see and manage its relations.
## Page Composition
![object-edit-overview](https://user-images.githubusercontent.com/15313830/56667480-ceff8500-66a5-11e9-98c7-792d598f2394.png)
### Pin 1
- Link back to the "Objects" page ;
- Editable name field, hit 'enter' or 'cmd + s' or click on the floppy-disk icon to save ;
- Major dependencies visualisation, (where my object is used as a child), click the label to navigate to the dependence ;
- External URL, this is an optional parameter, it's use to point at an other source of content or information needed by the object. We generaly use to point at a Git repository ;
### Pin 2
- Delete Button, Warning there, it will destroy your object! ;
- Type of your Object (`organisation`, `campus`, `onboarding`, `cursus`, `quest`, `exercise`), save on select ;
- Status of your Object (`draft`, `online`, `offline`), save on select ;
- The first and last name of the original author ;
### Pin 3
- Object Attribute edition area, manage all the attributes relative to this Object. These attributes will be exposed to its relationship ;
### Pin 4
- Object Children edition area ;
- Children Attributes edition area, these attributes impact and overload all the following children. Works the same way as standard attributes ;
- Add a child, allows to add a child to the children list, more information here -> [Object Child creation](https://github.com/01-edu/public/blob/master/doc/object-child-creation.md) ;
- Children List, allows you to reorganise, delete and edit child. Each child can be overload with its own attributes, the edition works the same way as the original attributes ;
More informations about attribute overload system [here] ((https://github.com/01-edu/public/blob/master/doc/object-attribute-overload-system.md)

29
docs/objects.md

@ -0,0 +1,29 @@
# Objects
> Allow you to create, manage and organize your pedagical and onboarding content.
## Definition
An Object is an highly customizable element, which can be use in many situations. We use it to compose cursuses and onboarding processes.
Objects can be associated together and then share a vertical or horizontal relationship, which allows to build complex structure of multiple objects.
It structure can be visualized in two parts. The first one is the definition of the object itself and attributes, called `attrs`. The second part is the definition of minor relationships, called `children` and attributes applied to them, called `childrenAttrs`.
This is the minimal structure of an object:
- name
- type (`organisation`, `campus`, `onboarding`, `cursus`, `quest`, `exercise`)
- status (`draft`, `online`, `offline`)
- attrs {}
- childrenAttrs {}
- children {}
## Browse Objects:
To access your Objects, go to the admin dashboard and then click on the _manage object_ link within the "Object" card.
![go-to-objects](https://user-images.githubusercontent.com/15313830/56653756-46bdb780-6686-11e9-98ba-18e382987e9c.png)
Objects are sorted by type in different sections. This page offer a search bar that allow you query the objects by name. In the top-right corner, click the _add a new object_ button to create a new object. Fill a name, select a type and click _create_ to validate your creation. You will be redirected to the Object Edition page (document is here).
![all-object-page](https://user-images.githubusercontent.com/15313830/56654475-137c2800-6688-11e9-880b-75092397890d.png)

64
docs/ubuntu-installation.md

@ -0,0 +1,64 @@
# Ubuntu
## OS Installation
Download and boot the [last Ubuntu release](http://releases.ubuntu.com/19.04/ubuntu-19.04-desktop-amd64.iso).
Follow the steps :
![img1](https://user-images.githubusercontent.com/32063953/56804679-85867580-681e-11e9-8965-e87c6a89fac0.png)
![img2](https://user-images.githubusercontent.com/32063953/56963599-3eb3bb00-6b51-11e9-9778-4f3bb9993c74.png)
![img3](https://user-images.githubusercontent.com/32063953/56963600-3eb3bb00-6b51-11e9-94cc-279406f37def.png)
The partitioning is :
- 256 MB : EFI partition
- 20 GB : system partition
- 32 GB : unused partition (will be used later)
- rest : unused partition (will be used later)
![img4](https://user-images.githubusercontent.com/32063953/56963602-3eb3bb00-6b51-11e9-8977-38e4e67d6ce1.png)
![img5](https://user-images.githubusercontent.com/32063953/56963603-3f4c5180-6b51-11e9-9349-46ab90287691.png)
![img6](https://user-images.githubusercontent.com/32063953/56963604-3f4c5180-6b51-11e9-8df2-5016771e6e07.png
)
Remove the installation disk and then reboot.
Skip the welcoming window.
Don't install updates if Ubuntu asks to. The scripts will.
![img8](https://user-images.githubusercontent.com/32063953/56804701-8d461a00-681e-11e9-8825-dfc69f8268bf.png)
![img9](https://user-images.githubusercontent.com/32063953/56804703-8d461a00-681e-11e9-840c-498ccab7d911.png)
![img10](https://user-images.githubusercontent.com/32063953/56804704-8ddeb080-681e-11e9-96ff-6c8783c5aacc.png)
![img11](https://user-images.githubusercontent.com/32063953/56804706-8ddeb080-681e-11e9-85e1-20c5b6956a36.png)
## OS configuration
```shell
student@tmp-hostname:~$ wget github.com/01-edu/public/archive/master.zip
student@tmp-hostname:~$ unzip master.zip
student@tmp-hostname:~$ cd public-master/scripts
student@tmp-hostname:~$ sudo ./install_client.sh
[...]
Ask for student user password (will be removed later)
[...]
Ask to set the root password
[...]
Long installation/configuration process
[...]
student@tmp-hostname:~$ cat dconfig.txt | dconf load /
student@tmp-hostname:~$ reboot
```
The system is now read-only, every data is written to a temporary partition.
The session is password-less.
To gain a superuser terminal with read/write access to the filesystem, type these commands:
```shell
student@tmp-hostname:~$ su -
Password:
root@tmp-hostname:~# overlayroot-chroot
```

88
examples/call-graphql.go

@ -0,0 +1,88 @@
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
)
func jsonPrettyPrint(in []byte) string {
var out bytes.Buffer
err := json.Indent(&out, in, "", " ")
if err != nil {
return string(in)
}
return out.String()
}
var HASURA_GRAPHQL_ADDRESS = os.Getenv("HASURA_GRAPHQL_ADDRESS")
var HASURA_GRAPHQL_ADMIN_SECRET = os.Getenv("HASURA_GRAPHQL_ADMIN_SECRET")
type GraphqlQuery struct {
Data interface{}
}
var client = &http.Client{Transport: http.DefaultTransport}
func hasura(query string, variables interface{}, data interface{}) (err error) {
variablesBytes, err := json.Marshal(variables)
if err != nil {
return
}
v := string(variablesBytes)
requestBody := []byte(`{"query":"` + query + `","variables":` + v + `}`)
requestBytes := bytes.NewBuffer(requestBody)
req, err := http.NewRequest("POST", HASURA_GRAPHQL_ADDRESS, requestBytes)
if err != nil {
return
}
req.Header.Add("X-Hasura-Admin-Secret", HASURA_GRAPHQL_ADMIN_SECRET)
resp, err := client.Do(req)
if err != nil {
return
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
// loggin the answer for debugging purposes
fmt.Println(jsonPrettyPrint(b))
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return errors.New(http.StatusText(resp.StatusCode))
}
return json.Unmarshal(b, &GraphqlQuery{Data: data})
}
type User struct {
GithubLogin string
}
const userQuery = `
query {
user {
githubLogin
}
}`
func getUsers() (users []User, err error) {
var data map[string][]User
err = hasura(userQuery, nil, &data)
return data["user"], err
}
func main() {
fmt.Println(getUsers())
}
// HASURA_GRAPHQL_ADMIN_SECRET=VERYVERYSECRET HASURA_GRAPHQL_ADDRESS=http://localhost/graphql-engine/v1alpha1/graphql go run call-graphql.go

59
scripts/bash_tweaks.sh

@ -0,0 +1,59 @@
#!/bin/bash
# Configure Terminal
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
# Makes bash case-insensitive
cat <<EOF>> /etc/inputrc
set completion-ignore-case On
EOF
# Enhance Linux prompt
cat <<EOF> /etc/issue
Kernel build: \v
Kernel package: \r
Date: \d \t
IP address: \4
Terminal: \l@\n.\O
EOF
# Enable Bash completion
apt-get -y install bash-completion
cat <<EOF>> /etc/bash.bashrc
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
EOF
# Set-up all users
for DIR in $(ls -1d /root /home/* 2>/dev/null || true)
do
# Hide login informations
touch $DIR/.hushlogin
# Add convenient aliases & behaviors
cat <<-'EOF'>> $DIR/.bashrc
HISTCONTROL=ignoreboth
export HISTFILESIZE=
export HISTSIZE=
export HISTTIMEFORMAT="%F %T "
alias l="ls $LS_OPTIONS -al --si"
alias df="df --si"
alias du="du -cs --si"
alias free="free -h --si"
alias pstree="pstree -palU"
EOF
# Fix rights
USR=$(echo "$DIR" | rev | cut -d/ -f1 | rev)
chown -R $USR:$USR $DIR || true
done

55
scripts/clean.sh

@ -0,0 +1,55 @@
#!/bin/bash
# Clean system
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
# Purge useless packages
apt-get -y autoremove --purge
apt-get autoclean
apt-get clean
apt-get install
rm -rf /root/.local
# Remove connection logs
> /var/log/lastlog
> /var/log/wtmp
> /var/log/btmp
# Remove machine ID
> /etc/machine-id
# Remove logs
cd /var/log
rm -rf alternatives.log*
rm -rf apt/*
rm -rf auth.log
rm -rf dpkg.log*
rm -rf gpu-manager.log
rm -rf installer
rm -rf journal/d6e982aa8c9d4c1dbcbdcff195642300
rm -rf kern.log
rm -rf syslog
rm -rf sysstat
# Remove random seeds
rm -rf /var/lib/systemd/random-seed
rm -rf /var/lib/NetworkManager/secret_key
# Remove network configs
rm -rf /etc/NetworkManager/system-connections/*
rm -rf /var/lib/bluetooth/*
rm -rf /var/lib/NetworkManager/*
# Remove caches
rm -rf /var/lib/gdm3/.cache/*
rm -rf /root/.cache
rm -rf /home/student/.cache
rm -rf /home/student/.sudo_as_admin_successful /home/student/.bash_logout
rm -rf /tmp/*
rm -rf /tmp/.* || true

64
scripts/common_packages.txt

@ -0,0 +1,64 @@
apache2-utils
apt-utils
arp-scan
autossh
bash-completion
binutils
build-essential
console-data
console-setup
cron
curl
dialog
dmidecode
dnsutils
file
firmware-linux-nonfree
git
hdparm
iftop
ifupdown
iotop
iptables
iputils-ping
isc-dhcp-client
isc-dhcp-common
jq
less
linux-headers-amd64
linux-image-amd64
lm-sensors
locales
lsb-release
lshw
lsof
lzop
man
mc
mdadm
moreutils
nano
net-tools
nmap
ntpdate
nvme-cli
pciutils
psmisc
python
python3
rsync
rsyslog
ssh
stress
sudo
sysstat
telnet
tig
traceroute
tree
tzdata
unzip
usbutils
wget
zerofree
zip

131
scripts/dconfig.txt

@ -0,0 +1,131 @@
[org/gnome/desktop/calendar]
show-weekdate=true
[org/gnome/desktop/wm/preferences]
resize-with-right-button=true
[org/gnome/desktop/peripherals/keyboard]
delay=uint32 350
[desktop/ibus/panel/emoji]
unicode-hotkey=@as []
hotkey=@as []
[org/gnome/desktop/peripherals/touchpad]
two-finger-scrolling-enabled=true
disable-while-typing=false
[org/gnome/login-screen]
enable-smartcard-authentication=false
enable-fingerprint-authentication=false
[org/gnome/desktop/privacy]
report-technical-problems=false
remember-recent-files=false
[org/gnome/desktop/screensaver]
lock-enabled=false
[org/gnome/desktop/search-providers]
disable-external=true
[org/gnome/desktop/interface]
gtk-im-module='gtk-im-context-simple'
clock-show-seconds=true
enable-animations=false
cursor-blink=false
clock-show-weekday=true
gtk-theme='Yaru-dark'
[org/gnome/terminal/legacy]
menu-accelerator-enabled=false
[org/gnome/desktop/media-handling]
automount-open=false
automount=false
autorun-never=true
[org/gnome/terminal/legacy/keybindings]
reset-and-clear='<Primary>l'
[org/gnome/terminal/legacy/profiles:/:b1dcc9dd-5262-4d8d-a863-c897e6d979b9]
allow-bold=false
default-size-rows=48
bold-is-bright=true
audible-bell=false
scrollback-lines=2147483647
cursor-shape='ibeam'
default-size-columns=160
[org/gnome/desktop/background]
show-desktop-icons=false
[org/gnome/desktop/peripherals/mouse]
accel-profile='flat'
[org/gnome/settings-daemon/plugins/color]
night-light-enabled=true
night-light-schedule-automatic=true
[org/gnome/desktop/lockdown]
disable-print-setup=true
disable-printing=true
disable-user-switching=true
user-administration-disabled=true
[org/gnome/settings-daemon/plugins/media-keys]
custom-keybindings=['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']
screensaver=''
[org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0]
binding='<Super>l'
command='lock_screen'
name='Lock screen'
[org/gnome/settings-daemon/plugins/smartcard]
active=false
[org/gnome/settings-daemon/plugins/remote-display]
active=false
[org/gnome/settings-daemon/plugins/sharing]
active=false
[org/gnome/settings-daemon/plugins/screensaver-proxy]
active=false
[org/gnome/settings-daemon/plugins/gsdwacom]
active=false
[org/gnome/settings-daemon/plugins/power]
sleep-inactive-ac-type='nothing'
sleep-inactive-ac-timeout=0
[org/gnome/shell]
enable-hot-corners=true
favorite-apps=['firefox.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Terminal.desktop', 'sublime_text.desktop', 'vscodium.desktop', 'org.gnome.Calculator.desktop', 'gnome-control-center.desktop', 'org.gnome.tweaks.desktop', 'lock_screen.desktop', 'suspend_session.desktop', 'yelp.desktop']
[org/gnome/system/location]
enabled=false
[org/gnome/desktop/session]
idle-delay=uint32 0
[org/gnome/mutter]
center-new-windows=true
[org/gnome/calculator]
source-currency=''
source-units='degree'
button-mode='advanced'
word-size=64
show-zeroes=false
base=10
angle-units='degrees'
accuracy=9
show-thousands=false
window-position=(1906, 826)
refresh-interval=604800
target-units='radian'
number-format='fixed'
target-currency=''

15
scripts/firewall.sh

@ -0,0 +1,15 @@
#!/bin/bash
# Install firewall
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
SSH_PORT=${1:-521}
apt-get -y install ufw
ufw logging off
ufw allow in "$SSH_PORT"/tcp
ufw --force enable

9
scripts/fx.sh

@ -0,0 +1,9 @@
#!/bin/bash
# Install FX: command-line JSON processing tool (https://github.com/antonmedv/fx)
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
npm install -g fx

24
scripts/go.sh

@ -0,0 +1,24 @@
#!/bin/bash
# Install Go
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
apt-get -y install golang
# Set-up all users
for DIR in $(ls -1d /root /home/* 2>/dev/null || true)
do
# Add convenient aliases & behaviors
cat <<-'EOF'>> $DIR/.bashrc
GOPATH=$HOME/go
PATH=$PATH:$GOPATH/bin
alias gobuild='CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w"'
EOF
# Fix rights
USR=$(echo "$DIR" | rev | cut -d/ -f1 | rev)
chown -R $USR:$USR $DIR || true
done

25
scripts/grub.sh

@ -0,0 +1,25 @@
#!/bin/bash
# Install Grub
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
DISK=$1
apt-get -y install grub-efi-amd64
sed -i -e 's/message=/message_null=/g' /etc/grub.d/10_linux
cat <<EOF>> /etc/default/grub
GRUB_TIMEOUT=0
GRUB_RECORDFAIL_TIMEOUT=0
GRUB_TERMINAL=console
GRUB_DISTRIBUTOR=``
GRUB_DISABLE_OS_PROBER=true
GRUB_DISABLE_SUBMENU=y
EOF
update-grub
grub-install $DISK

87
scripts/install_client.sh

@ -0,0 +1,87 @@
#!/bin/bash
# Configure Z01 client
# Log stdout & stderr
exec > >(tee -i /tmp/install_client.log)
exec 2>&1
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
# Set root password
passwd root
# Remove user password
passwd -d student
cp /etc/shadow /etc/shadow-
SSH_PORT=521
DISK=$(lsblk -o tran,kname,hotplug,type,fstype -pr |
grep -e nvme -e sata |
grep '0 disk' |
cut -d' ' -f2 |
sort |
head -n1)
apt-get update
apt-get -y upgrade
apt-get -y autoremove --purge
. bash_tweaks.sh
. ssh.sh
. firewall.sh
. ubuntu_tweaks.sh
. grub.sh "$DISK"
. go.sh
. nodejs.sh
. fx.sh
. sublime.sh
. vscode.sh
# Install additional packages
PKGS="
emacs
f2fs-tools
golang-mode
vim
xfsprogs
"
apt-get -y install $PKGS
# Remove fsck because the system partition will be read-only (overlayroot)
rm /usr/share/initramfs-tools/hooks/fsck
# Copy system files
cp -r system /tmp
cd /tmp/system
sed -i -e "s|::DISK::|$DISK|g" etc/udev/rules.d/10-local.rules
# Fourth local partition
PART=$(lsblk -o tran,kname,hotplug,type,fstype -pr |
grep -v usb |
grep '0 part' |
cut -d' ' -f2 |
sort |
head -n4 |
tail -n1)
sed -i -e "s|::PART::|$PART|g" usr/share/initramfs-tools/scripts/init-premount/reformat
apt-get -y install overlayroot
echo overlayroot=\"device:dev=$PART,recurse=0\" >> /etc/overlayroot.conf
# Fix permissions
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
find . -type f -exec /bin/sh -c "file {} | grep -q 'shell script' && chmod +x {}" \;
cp --preserve=mode -RT . /
cd $SCRIPT_DIR
rm -rf /tmp/system
update-initramfs -u
. clean.sh

10
scripts/nodejs.sh

@ -0,0 +1,10 @@
#!/bin/bash
# Install Node.js
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
curl -sL https://deb.nodesource.com/setup_10.x | bash -
apt-get -y install nodejs

34
scripts/set.sh

@ -0,0 +1,34 @@
#!/bin/bash
# Set scripting variables
# Treat unset variables as an error when substituting.
set -u
# Exit immediately if a command exits with a non-zero status.
set -e
# Set the variable corresponding to the return value of a pipeline is the status
# of the last command to exit with a non-zero status, or zero if no command
# exited with a non-zero status
set -o pipefail
# Separate tokens on newlines only
IFS='
'
# The value of this parameter is expanded like PS1 and the expanded value is the
# prompt printed before the command line is echoed when the -x option is set
# (see The Set Builtin). The first character of the expanded value is replicated
# multiple times, as necessary, to indicate multiple levels of indirection.
# \D{%F %T} prints date like this : 2019-12-31 23:59:59
PS4='-\D{%F %T} '
# Print commands and their arguments as they are executed.
set -x
# Skip dialogs during apt-get install commands
export DEBIAN_FRONTEND=noninteractive # DEBIAN_PRIORITY=critical
export LC_ALL=C LANG=C
export SHELL=/bin/bash

25
scripts/ssh.sh

@ -0,0 +1,25 @@
#!/bin/bash
# Install OpenSSH
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
SSH_PORT=${1:-521}
# Install dependencies
apt-get -y install ssh
cat <<EOF>> /etc/ssh/sshd_config
Port $SSH_PORT
PasswordAuthentication no
AllowUsers root
EOF
mkdir -p /root/.ssh
chmod -f 700 /root/.ssh
# echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH30lZP4V26RVWWvAW91jM7UBSN68+xkuJc5cRionpMc' >> /root/.ssh/authorized_keys
chmod -f 600 /root/.ssh/authorized_keys || true
systemctl restart sshd.service

17
scripts/sublime.sh

@ -0,0 +1,17 @@
#!/bin/bash
# Install Sublime Text & Sublime Merge
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
wget -qO - https://download.sublimetext.com/sublimehq-pub.gpg | apt-key add -
apt-get install -y apt-transport-https
cat <<EOF> /etc/apt/sources.list.d/sublime-text.list
deb https://download.sublimetext.com/ apt/stable/
EOF
apt-get update
apt-get install -y sublime-text sublime-merge libgtk2.0-0

74
scripts/system/etc/gdm3/PostLogin/Default

@ -0,0 +1,74 @@
#!/bin/bash
# Mount home as an overlay filesystem
# Log stdout & stderr
exec > >(tee -i /tmp/gdm3_postlogin.log)
exec 2>&1
# Treat unset variables as an error when substituting.
set -u
# Exit immediately if a command exits with a non-zero status.
set -e
# Separate tokens on newlines only
IFS='
'
# The value of this parameter is expanded like PS1 and the expanded value is the
# prompt printed before the command line is echoed when the -x option is set
# (see The Set Builtin). The first character of the expanded value is replicated
# multiple times, as necessary, to indicate multiple levels of indirection.
# \D{%F %T} prints date like this : 2019-12-31 23:59:59
PS4='-\D{%F %T} '
# Print commands and their arguments as they are executed.
set -x
sleep 0.5
# Find the first removable F2FS partition
PART=$(lsblk -o tran,kname,hotplug,type,fstype -pr |
grep -e '1 part f2fs' -e '1 disk f2fs' |
cut -d' ' -f2 |
sort |
head -n1)
# Make sure the mountpoints are free
(
lsof -t $HOME | xargs kill -9
umount $HOME
umount /mnt
) || true
if test "$PART"
then
mount -o noatime "$PART" /mnt
else
# No removable F2FS partition found, use the third local partition instead
PART=$(lsblk -o tran,kname,hotplug,type,fstype -pr |
grep -v usb |
grep '0 part' |
cut -d' ' -f2 |
sort |
head -n3 |
tail -n1)
if test -z "$PART"
then
# No local partition found, error
exit 1
fi
# We don't care about data consistency since the partition is temporary
/sbin/mke2fs -t ext4 -O ^has_journal -F "$PART"
mount -o noatime,nobarrier "$PART" /mnt
fi
USER_PATH=/mnt/.01/$USER
TEMP_PATH=/mnt/.01/tmp
mkdir -p $USER_PATH $TEMP_PATH
chown -R $USER:$USER $USER_PATH $TEMP_PATH
mount -t overlay -o lowerdir=$HOME,upperdir=$USER_PATH,workdir=$TEMP_PATH overlay $HOME

25
scripts/system/etc/gdm3/PostSession/Default

@ -0,0 +1,25 @@
#!/bin/bash
# Log stdout & stderr
exec > >(tee -i /tmp/gdm3_postsession.log)
exec 2>&1
# Exit immediately if a command exits with a non-zero status.
set -e
# The value of this parameter is expanded like PS1 and the expanded value is the
# prompt printed before the command line is echoed when the -x option is set
# (see The Set Builtin). The first character of the expanded value is replicated
# multiple times, as necessary, to indicate multiple levels of indirection.
# \D{%F %T} prints date like this : 2019-12-31 23:59:59
PS4='-\D{%F %T} '
# Print commands and their arguments as they are executed.
set -x
passwd -d $USER
sync
sleep 0.5
lsof -t $HOME | xargs kill || true
umount -l $HOME
umount -l /mnt

1
scripts/system/etc/udev/rules.d/10-local.rules

@ -0,0 +1 @@
KERNEL=="::DISK::*", ENV{UDISKS_IGNORE}="1"

13
scripts/system/usr/local/bin/lock_screen

@ -0,0 +1,13 @@
#!/bin/bash
# Exits if a command fails
set -e
if passwd -S | grep NP
then
# No password set, so ask user to set one
gnome-terminal.real -t "" --geometry=40x10 --wait -- passwd
sleep 1
fi
i3lock -c000000

13
scripts/system/usr/local/bin/suspend_session

@ -0,0 +1,13 @@
#!/bin/bash
# Exits if a command fails
set -e
if passwd -S | grep NP
then
# No password set, so ask user to set one
gnome-terminal.real -t "" --geometry=40x10 --wait -- passwd
sleep 1
fi
systemctl suspend

8
scripts/system/usr/share/applications/lock_screen.desktop

@ -0,0 +1,8 @@
[Desktop Entry]
Name=Lock Screen
Comment=Sets a password if needed and then lock screen
Exec=/usr/local/bin/lock_screen
Icon=system-lock-screen
Terminal=false
Type=Application
StartupNotify=true

8
scripts/system/usr/share/applications/suspend_session.desktop

@ -0,0 +1,8 @@
[Desktop Entry]
Name=Suspend session
Comment=Sets a password if needed and then suspend session
Exec=/usr/local/bin/suspend_session
Icon=media-playback-pause
Terminal=false
Type=Application
StartupNotify=true

22
scripts/system/usr/share/initramfs-tools/hooks/copy_mkfs

@ -0,0 +1,22 @@
#!/bin/sh
set -e
PREREQ=""
prereqs () {
echo "${PREREQ}"
}
case "${1}" in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
copy_exec /sbin/mke2fs /bin
exit 0

20
scripts/system/usr/share/initramfs-tools/scripts/init-premount/reformat

@ -0,0 +1,20 @@
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /scripts/functions
/bin/mke2fs -F -t ext4 -O ^has_journal ::PART:: > /dev/null 2>&1
exit 0

118
scripts/ubuntu_tweaks.sh

@ -0,0 +1,118 @@
#!/bin/bash
# Configure ubuntu desktop systems
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd "$SCRIPT_DIR"
. set.sh
# Install dependencies
apt-get -y install lz4
# Change ext4 default mount options
sed -i -e 's/ errors=remount-ro/ noatime,nodelalloc,errors=remount-ro/g' /etc/fstab
# Disable GTK hidden scroll bars
echo GTK_OVERLAY_SCROLLING=0 >> /etc/environment
# Reveal boot messages
sed -i -e 's/TTYVTDisallocate=yes/TTYVTDisallocate=no/g' /etc/systemd/system/getty.target.wants/getty@tty1.service
# Speedup boot
sed -i 's/MODULES=most/MODULES=dep/g' /etc/initramfs-tools/initramfs.conf
sed -i 's/COMPRESS=gzip/COMPRESS=lz4/g' /etc/initramfs-tools/initramfs.conf
# Reveal autostart services
sed -i 's/NoDisplay=true/NoDisplay=false/g' /etc/xdg/autostart/*.desktop
# Remove password complexity constraints
sed -i 's/ obscure / minlen=1 /g' /etc/pam.d/common-password
# Remove splash screen (plymouth) and hide kernel output
sed -i 's/quiet splash/quiet vt.global_cursor_default=0 console=ttyS0/g' /etc/default/grub
update-initramfs -u
update-grub
# Disable swapfile
swapoff /swapfile || true
rm -f /swapfile
sed -i '/swapfile/d' /etc/fstab
# Prevent gnome-shell segfault from happening
sed -i 's/#WaylandEnable=false/WaylandEnable=false/g' /etc/gdm3/custom.conf
# Purge unused Ubuntu packages
PKGS="
apport
bind9
bolt
cups*
exim*
fprintd
friendly-recovery
gnome-initial-setup
gnome-online-accounts
gnome-power-manager
gnome-software
gnome-software-common
memtest86+
orca
popularity-contest
python3-update-manager
secureboot-db
snapd
spice-vdagent
ubuntu-report
ubuntu-software
unattended-upgrades
update-inetd
update-manager-core
update-notifier
update-notifier-common
whoopsie
xdg-desktop-portal
"
apt-get -y purge $PKGS
apt-get -y autoremove --purge
SERVICES="
apt-daily-upgrade.timer
apt-daily.timer
console-setup.service
keyboard-setup.service
motd-news.timer
remote-fs.target
"
systemctl disable $SERVICES
SERVICES="
grub-common.service
NetworkManager-wait-online.service
plymouth-quit-wait.service
"
systemctl mask $SERVICES
# Install packages
PKGS="$(cat common_packages.txt)
baobab
blender
chromium-browser
dconf-editor
firefox
gimp
gnome-calculator
gnome-system-monitor
gnome-tweaks
i3lock
mpv
zenity
"
# Replace debian packages with ubuntu's
PKGS=${PKGS/linux-image-amd64/linux-image-generic}
PKGS=${PKGS/linux-headers-amd64/linux-headers-generic}
PKGS=${PKGS/firmware-linux-nonfree}
apt-get -y install $PKGS

35
scripts/vscode.sh

@ -0,0 +1,35 @@
#!/bin/bash
# Install VSCode
SCRIPT_DIR="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $SCRIPT_DIR
. set.sh
wget -qO - https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg | apt-key add -
echo 'deb https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/repos/debs/ vscodium main' > /etc/apt/sources.list.d/vscodium.list
apt-get update && apt-get -y install vscodium
# Set-up all users
for DIR in $(ls -1d /home/* 2>/dev/null || true)
do
# Disable most of the telemetry and auto-updates
mkdir -p $DIR/.config/VSCodium/User
cat <<-'EOF'> $DIR/.config/VSCodium/User/settings.json
{
"telemetry.enableCrashReporter": false,
"update.enableWindowsBackgroundUpdates": false,
"update.mode": "none",
"update.showReleaseNotes": false,
"extensions.autoCheckUpdates": false,
"extensions.autoUpdate": false,
"workbench.enableExperiments": false,
"workbench.settings.enableNaturalLanguageSearch": false,
"npm.fetchOnlinePackageInfo": false
}
EOF
# Fix rights
USR=$(echo "$DIR" | rev | cut -d/ -f1 | rev)
chown -R $USR:$USR $DIR || true
done

18
subjects/abort.md → subjects/abort.en.md

@ -1,20 +1,20 @@
# abort
## Instructions
## abort
### Instructions
Write a function that returns the the value in the middle of 5 five arguments.
This function must have the following signature.
## Expected function
### Expected function
```go
func Abort(a, b, c, d, e int) int {
}
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -22,8 +22,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -38,5 +38,5 @@ And its output :
student@ubuntu:~/student/abort$ go build
student@ubuntu:~/student/abort$ ./abort
5
student@ubuntu:~/student/abort$
student@ubuntu:~/student/abort$
```

19
subjects/activebits.md → subjects/activebits.en.md

@ -1,21 +1,20 @@
# activebits
## Instructions
## activebits
### Instructions
Write a function, ActiveBitsthat, that returns the number of active bits (bits with the value 1) in the binary representation of an integer number.
The function must have the next signature.
## Expected function
### Expected function
```go
func ActiveBits(n int) uint {
func ActiveBits(n int) uint {
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -23,8 +22,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -39,5 +38,5 @@ And its output :
student@ubuntu:~/student/activebits$ go build
student@ubuntu:~/student/activebits$ ./activebits
10
student@ubuntu:~/student/activebits$
student@ubuntu:~/student/activebits$
```

42
subjects/advancedsortwordarr.en.md

@ -0,0 +1,42 @@
## advancedsortwordarr
### Instructions
Write a function `AdvancedSortWordArr` that sorts a `string` array, based on the function `f` passed in parameter.
### Expected function
```go
func AdvancedSortWordTab(array []string, f func(a, b string) int) {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
result := []string{"a", "A", "1", "b", "B", "2", "c", "C", "3"}
piscine.AdvancedSortWordTab(result, piscine.Compare)
fmt.Println(result)
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
[1 2 3 A B C a b c]
student@ubuntu:~/piscine/test$
```

42
subjects/advancedsortwordarr.fr.md

@ -0,0 +1,42 @@
## advancedsortwordarr
### Instructions
Écrire une fonction `AdvancedSortWordArr` qui trie un tableau de `string`, basé sur la fonction `f` passée en paramètre.
### Fonction attendue
```go
func AdvancedSortWordTab(array []string, f func(a, b string) int) {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
result := []string{"a", "A", "1", "b", "B", "2", "c", "C", "3"}
piscine.AdvancedSortWordTab(result, piscine.Compare)
fmt.Println(result)
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
[1 2 3 A B C a b c]
student@ubuntu:~/piscine/test$
```

1
subjects/advancedsortwordtab.en.md

@ -0,0 +1 @@
## advancedsortwordtab

29
subjects/alphamirror.en.md

@ -0,0 +1,29 @@
## alphamirror
### Instructions
Write a program called alphamirror that takes a string as argument and displays this string
after replacing each alphabetical character with the opposite alphabetical
character.
The case of the letter stays the same, for example :
'a' becomes 'z', 'Z' becomes 'A'
'd' becomes 'w', 'M' becomes 'N'
The final result will be followed by a newline.
If the number of arguments is not 1, the program will display only a newline.
Example of output :
```console
student@ubuntu:~/student/alphamirror$ go build
student@ubuntu:~/student/alphamirror$ ./alphamirror "abc"
zyx
student@ubuntu:~/student/alphamirror$ ./alphamirror "My horse is Amazing." | cat -e
Nb slihv rh Znzarmt.$
student@ubuntu:~/student/alphamirror$ ./alphamirror | cat -e
$
student@ubuntu:~/student/alphamirror$
```

48
subjects/any.en.md

@ -0,0 +1,48 @@
## any
### Instructions
Write a function `Any` that returns `true`, for a `string` array:
- if, when that `string` array is passed through an `f` function, at least one element returns `true`.
### Expected function
```go
func Any(f func(string) bool, arr []string) bool {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
tab1 := []string{"Hello", "how", "are", "you"}
tab2 := []string{"This", "is", "4", "you"}
result1 := piscine.Any(piscine.IsNumeric, tab1)
result2 := piscine.Any(piscine.IsNumeric, tab2)
fmt.Println(result1)
fmt.Println(result2)
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
false
true
student@ubuntu:~/piscine/test$
```

48
subjects/any.fr.md

@ -0,0 +1,48 @@
## any
### Instructions
Écrire une fonction `Any` qui retournes `true`, pour un tableau de `string`:
- si, lorsque ce tableau de `string` est passé à travers une fonction `f`, au moins un element retournes `true`.
### Fonction attendue
```go
func Any(f func(string) bool, arr []string) bool {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
tab1 := []string{"Hello", "how", "are", "you"}
tab2 := []string{"This", "is", "4", "you"}
result1 := piscine.Any(piscine.IsNumeric, tab1)
result2 := piscine.Any(piscine.IsNumeric, tab2)
fmt.Println(result1)
fmt.Println(result2)
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
false
true
student@ubuntu:~/piscine/test$
```

48
subjects/appendrange.en.md

@ -0,0 +1,48 @@
## appendrange
### Instructions
Write a function that takes an `int` min and an `int` max as parameters.
That function returns a slice of `int` with all the values between min and max.
Min is included, and max is excluded.
If min is superior or equal to max, a `nil` slice is returned.
`make` is not allowed for this exercise.
### Expected function
```go
func AppendRange(min, max int) []int {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.AppendRange(5, 10))
fmt.Println(piscine.AppendRange(10, 5))
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
[5 6 7 8 9]
[]
student@ubuntu:~/piscine/test$
```

47
subjects/appendrange.fr.md

@ -0,0 +1,47 @@
## appendrange
### Instructions
Écrire une fonction qui prend un `int` minimum et un `int` maximum comme paramètres. Cette fonction retournes une slice d'`int` avec toutes les valeurs comprises entre le minimum et le maximum.
Le minimum est inclus, le maximum est exclu.
Si le minimum est supérieur ou égal au maximum, une slice `nil` est retournée.
`make` n'est pas autorisé pour cet exercice.
### Fonction attendue
```go
func AppendRange(min, max int) []int {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.AppendRange(5, 10))
fmt.Println(piscine.AppendRange(10, 5))
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
[5 6 7 8 9]
[]
student@ubuntu:~/piscine/test$
```

77
subjects/atoi.en.md

@ -0,0 +1,77 @@
## atoi
### Instructions
- Write a [function](TODO-LINK) that simulates the behaviour of the `Atoi` function in Go. `Atoi` transforms a number represented as a `string` in a number represented as an `int`.
- Atoi returns `0` if the `string` is not considered as a valid number. For this exercise **non-valid `string` chains will be tested**. Some will contain non-digits characters.
- For this exercise the handling of the signs + or - **does have** to be taken into account.
- This function will **only** have to return the `int` `nbr`. For this exercise the `error` return of atoi is not required.
### Format required
```go
func Atoi(s string) int {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
s := "12345"
s2 := "0000000012345"
s3 := "012 345"
s4 := "Hello World!"
s5 := "+1234"
s6 := "-1234"
s7 := "++1234"
s8 := "--1234"
n := piscine.Atoi(s)
n2 := piscine.Atoi(s2)
n3 := piscine.Atoi(s3)
n4 := piscine.Atoi(s4)
n5 := piscine.Atoi(s5)
n6 := piscine.Atoi(s6)
n7 := piscine.Atoi(s7)
n8 := piscine.Atoi(s8)
fmt.Println(n)
fmt.Println(n2)
fmt.Println(n3)
fmt.Println(n4)
fmt.Println(n5)
fmt.Println(n6)
fmt.Println(n7)
fmt.Println(n8)
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
12345
12345
0
0
1234
-1234
0
0
student@ubuntu:~/piscine/test$
```

77
subjects/atoi.fr.md

@ -0,0 +1,77 @@
## atoi
### Instructions
- Écrire une fonction qui reproduit le comportement de la fonction atoi en Go. Atoi transforme un nombre représenté en `string` (chaîne de caractères) en `int` (entier).
- Atoi retourne `0` si la `string` n'est pas considéré un nombre valide. Pour cet exercice des **`string` non valides seront testées!**. Certaines contiendront d'autres charactères que des chiffres.
- Pour cet exercice la gestion des signes + ou - **doit être** prise en compte.
- Cette fonction aura **seulement** à retourner l'`int` (entier) `nbr`. Pour cet exercice le retour d'erreur d'atoi de go n'est pas demandé.
### Fonction attendue
```go
func Atoi(s string) int {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
s := "12345"
s2 := "0000000012345"
s3 := "012 345"
s4 := "Hello World!"
s5 := "+1234"
s6 := "-1234"
s7 := "++1234"
s8 := "--1234"
n := piscine.Atoi(s)
n2 := piscine.Atoi(s2)
n3 := piscine.Atoi(s3)
n4 := piscine.Atoi(s4)
n5 := piscine.Atoi(s5)
n6 := piscine.Atoi(s6)
n7 := piscine.Atoi(s7)
n8 := piscine.Atoi(s8)
fmt.Println(n)
fmt.Println(n2)
fmt.Println(n3)
fmt.Println(n4)
fmt.Println(n5)
fmt.Println(n6)
fmt.Println(n7)
fmt.Println(n8)
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
12345
12345
0
0
1234
-1234
0
0
student@ubuntu:~/piscine/test$
```

59
subjects/atoibase.en.md

@ -0,0 +1,59 @@
## atoibase
### Instructions
Write a function that takes a `string` number and its `string` base in parameters and returns its conversion as an `int`.
If the base or the `string` number is not valid it returns `0`:
Validity rules for a base :
- A base must contain at least 2 characters.
- Each character of a base must be unique.
- A base should not contain `+` or `-` characters.
Only valid `string` numbers will be tested.
The function **does not have** to manage negative numbers.
### Expected function
```go
func AtoiBase(s string, base string) int {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.AtoiBase("125", "0123456789"))
fmt.Println(piscine.AtoiBase("1111101", "01"))
fmt.Println(piscine.AtoiBase("7D", "0123456789ABCDEF"))
fmt.Println(piscine.AtoiBase("uoi", "choumi"))
fmt.Println(piscine.AtoiBase("bbbbbab", "-ab")
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
125
125
125
125
0
student@ubuntu:~/piscine/test$
```

59
subjects/atoibase.fr.md

@ -0,0 +1,59 @@
## atoibase
### Instructions
Écrire une fonction qui prend un nombre `string` et sa base `string` en paramètres et retournes sa convertion en `int`.
Si la base n'est pas valide elle retournes `0`:
Régles de validité d'une base :
- Une base doit contenir au moins 2 charactères.
- Chaque charactère d'une base doit être unique.
- Une base ne doit pas contenir les charactères `+` ou `-`.
Seuls des nombres en `string` valides seront testés.
La fonction **ne doit pas** gérer les nombres négatifs.
### Fonction attendue
```go
func AtoiBase(s string, base string) int {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.AtoiBase("125", "0123456789"))
fmt.Println(piscine.AtoiBase("1111101", "01"))
fmt.Println(piscine.AtoiBase("7D", "0123456789ABCDEF"))
fmt.Println(piscine.AtoiBase("uoi", "choumi"))
fmt.Println(piscine.AtoiBase("bbbbbab", "-ab")
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
125
125
125
125
0
student@ubuntu:~/piscine/test$
```

57
subjects/basicatoi.en.md

@ -0,0 +1,57 @@
## basicatoi
### Instructions
- Write a function that simulates the behaviour of the atoi function in Go. Atoi transforms a number defined as a `string` in a number defined as an `int`.
- Atoi returns `0` if the `string` is not considered as a valid number. For this exercise **only valid** `string` chains will be tested. They will only contain one or several digits as characters.
- For this exercise the handling of the signs + or - does not have to be taken into account.
- This function will **only** have to return the `int` `nbr`. For this exercise the `error` return of atoi is not required.
### Expected function
```go
func BasicAtoi(s string) int {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
s := "12345"
s2 := "0000000012345"
s3 := "000000"
n := piscine.BasicAtoi(s)
n2 := piscine.BasicAtoi(s2)
n3 := piscine.BasicAtoi(s3)
fmt.Println(n)
fmt.Println(n2)
fmt.Println(n3)
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
12345
12345
0
student@ubuntu:~/piscine/test$
```

57
subjects/basicatoi.fr.md

@ -0,0 +1,57 @@
## basicatoi
### Instructions
- Écrire une fonction qui reproduit le comportement de la fonction atoi en Go. Atoi transforme un nombre représenté en `string` (chaîne de caractères) en `int` (entier).
- Atoi retourne `0` si la `string` n'est pas considéré un nombre valide. Pour cet exercice **seulement des** `string` **valides** seront testé. Elles ne contiendront que un ou plusieurs chiffres comme charact.
- Pour cet exercice la gestion des signes + ou - ne doit pas être prise en compte.
- Cette fonction aura **seulement** à retourner l'`int` (entier) `nbr`. Pour cet exercice le retour d'erreur d'atoi de go n'est pas demandé.
### Fonction attendue
```go
func BasicAtoi(s string) int {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
s := "12345"
s2 := "0000000012345"
s3 := "000000"
n := piscine.BasicAtoi(s)
n2 := piscine.BasicAtoi(s2)
n3 := piscine.BasicAtoi(s3)
fmt.Println(n)
fmt.Println(n2)
fmt.Println(n3)
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
12345
12345
0
student@ubuntu:~/piscine/test$
```

62
subjects/basicatoi2.en.md

@ -0,0 +1,62 @@
## basicatoi2
### Instructions
- Write a function that simulates the behaviour of the atoi function in Go. Atoi transforms a number defined as a `string` in a number defined as an `int`.
- Atoi returns `0` if the `string` is not considered as a valid number. For this exercise **non-valid `string` chains will be tested**. Some will contain non-digits characters.
- For this exercise the handling of the signs + or - does not have to be taken into account.
- This function will **only** have to return the `int` `nbr`. For this exercise the `error` return of atoi is not required.
### Expected Function
```go
func BasicAtoi2(s string) int {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
s := "12345"
s2 := "0000000012345"
s3 := "012 345"
s4 := "Hello World!"
n := piscine.BasicAtoi2(s)
n2 := piscine.BasicAtoi2(s2)
n3 := piscine.BasicAtoi2(s3)
n4 := piscine.BasicAtoi2(s4)
fmt.Println(n)
fmt.Println(n2)
fmt.Println(n3)
fmt.Println(n4)
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
12345
12345
0
0
student@ubuntu:~/piscine/test$
```

62
subjects/basicatoi2.fr.md

@ -0,0 +1,62 @@
## basicatoi2
### Instructions
- Écrire une fonction qui reproduit le comportement de la fonction atoi en Go. Atoi transforme un nombre représenté en `string` (chaîne de caractères) en `int` (entier).
- Atoi retourne `0` si la `string` n'est pas considéré un nombre valide. Pour cet exercice des **`string` non valides seront testées!**. Certaines contiendront d'autres charactères que des chiffres.
- Pour cet exercice la gestion des signes + ou - ne doit pas être prise en compte.
- Cette fonction aura **seulement** à retourner l'`int` (entier) `nbr`. Pour cet exercice le retour d'erreur d'atoi de go n'est pas demandé.
### Fonction attendue
```go
func BasicAtoi2(s string) int {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
s := "12345"
s2 := "0000000012345"
s3 := "012 345"
s4 := "Hello World!"
n := piscine.BasicAtoi2(s)
n2 := piscine.BasicAtoi2(s2)
n3 := piscine.BasicAtoi2(s3)
n4 := piscine.BasicAtoi2(s4)
fmt.Println(n)
fmt.Println(n2)
fmt.Println(n3)
fmt.Println(n4)
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
12345
12345
0
0
student@ubuntu:~/piscine/test$
```

40
subjects/basicjoin.en.md

@ -0,0 +1,40 @@
## basicjoin
### Instructions
Write a function that returns the concatenation of all the `string` of a table of `string` passed in argument.
### Expected function
```go
func basicJoin(strs []string) string {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
toConcat := []string{"Hello!", " How", " are", " you?"}
fmt.Println(piscine.BasicJoin(toConcat))
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
Hello! How are you?
student@ubuntu:~/piscine/test$
```

40
subjects/basicjoin.fr.md

@ -0,0 +1,40 @@
## basicjoin
### Instructions
Écrire une fonction qui retourne la concaténation de toutes les `string` d'un slice de `string` passées en paramètres.
### Fonction attendue
```go
func BasicJoin(strs []string) string {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
toConcat := []string{"Hello!", " How", " are", " you?"}
fmt.Println(piscine.BasicJoin(toConcat))
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
Hello! How are you?
student@ubuntu:~/piscine/test$
```

20
subjects/bool.md → subjects/bool.en.md

@ -1,13 +1,12 @@
# Boolean
## Boolean
## Instructions
### Instructions
Create a `.go` file and copy the code below into our file
- The main task is to return a working program.
```go
func printStr(str string) {
arrayStr := []rune(str)
@ -18,7 +17,6 @@ func printStr(str string) {
}
func isEven(nbr int) boolean {
if even(nbr) == 1 {
return yes
} else {
@ -27,7 +25,6 @@ func isEven(nbr int) boolean {
}
func main() {
if isEven(lengthOfArg) == 1 {
printStr(EvenMsg)
} else {
@ -36,11 +33,14 @@ func main() {
}
```
## Expected output
```go
### Expected output
```console
I have an even number of arguments
```
## Or
```go
### Or
```console
I have an odd number of arguments
```
```

18
subjects/btreeapplybylevel.md → subjects/btreeapplybylevel.en.md

@ -1,20 +1,20 @@
# btreeapplybylevel
## Instructions
## btreeapplybylevel
### Instructions
Write a function, BTreeApplyByLevel, that applies the function given by fn to each node of the tree given by root.
This function must have the following signature.
## Expected function
### Expected function
```go
func BTreeApplyByLevel(root *TreeNode, fn interface{}) {
}
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -22,8 +22,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -44,5 +44,5 @@ student@ubuntu:~/student/btreeapplybylevel$ ./btreeapplybylevel
1
7
5
student@ubuntu:~/student/btreeapplybylevel$
student@ubuntu:~/student/btreeapplybylevel$
```

48
subjects/btreeapplyinorder.en.md

@ -0,0 +1,48 @@
## btreeinsertdata
### Instructions
Write a function that applies a function in order to each element in the tree
(see in order tree walks)
### Expected function
```go
func BTreeApplyInorder(root *piscine.TreeNode, f func(...interface{}) (int, error)) {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine "."
)
func main() {
root := &piscine.TreeNode{Data: "4"}
piscine.BTreeInsertData(root, "1")
piscine.BTreeInsertData(root, "7")
piscine.BTreeInsertData(root, "5")
BTreeApplyInorder(root, fmt.Println)
}
```
And its output :
```console
student@ubuntu:~/piscine/btreeinsertdata$ go build
student@ubuntu:~/piscine/btreeinsertdata$ ./btreeinsertdata
1
4
5
7
student@ubuntu:~/piscine/btreeinsertdata$
```

47
subjects/btreeapplypostorder.en.md

@ -0,0 +1,47 @@
## btreeinsertdata
### Instructions
Write a function that applies a function using a postorder walk to each element in the tree
### Expected function
```go
func BTreeApplyPostorder(root *piscine.TreeNode, f func(...interface{}) (int, error)) {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine "."
)
func main() {
root := &piscine.TreeNode{Data: "4"}
piscine.BTreeInsertData(root, "1")
piscine.BTreeInsertData(root, "7")
piscine.BTreeInsertData(root, "5")
BTreeApplyPostorder(root, fmt.Println)
}
```
And its output :
```console
student@ubuntu:~/piscine/btreeinsertdata$ go build
student@ubuntu:~/piscine/btreeinsertdata$ ./btreeinsertdata
1
5
7
4
student@ubuntu:~/piscine/btreeinsertdata$
```

47
subjects/btreeapplypreorder.en.md

@ -0,0 +1,47 @@
## btreeinsertdata
### Instructions
Write a function that applies a function using a preorder walk to each element in the tree
### Expected function
```go
func BTreeApplyPreorder(root *piscine.TreeNode, f func(...interface{}) (int, error)) {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine "."
)
func main() {
root := &piscine.TreeNode{Data: "4"}
piscine.BTreeInsertData(root, "1")
piscine.BTreeInsertData(root, "7")
piscine.BTreeInsertData(root, "5")
BTreeApplyPreorder(root, fmt.Println)
}
```
And its output :
```console
student@ubuntu:~/piscine/btreeinsertdata$ go build
student@ubuntu:~/piscine/btreeinsertdata$ ./btreeinsertdata
4
1
7
5
student@ubuntu:~/piscine/btreeinsertdata$
```

17
subjects/btreedeletenode.md → subjects/btreedeletenode.en.md

@ -1,5 +1,6 @@
# btreedeletenode
## Instructions
## btreedeletenode
### Instructions
Write a function, BTreeDeleteNode, that deletes 'node' from the tree given by root.
@ -7,16 +8,16 @@ The resulting tree should still follow the binary search tree rules.
This function must have the following signature.
## Expected function
### Expected function
```go
func BTreeDeleteNode(root, node *TreeNode) *TreeNode {
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -24,8 +25,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -56,5 +57,5 @@ After delete:
1
5
7
student@ubuntu:~/student/btreedeletenode$
student@ubuntu:~/student/btreedeletenode$
```

52
subjects/btreeinsertdata.en.md

@ -0,0 +1,52 @@
## btreeinsertdata
### Instructions
Write a function that inserts new data in a binary search tree
following the properties of binary search trees.
The nodes must be defined as follows:
### Expected function
```go
type TreeNode struct {
Left, Right, Parent *TreeNode
Data string
}
func BTreeInsertData(root *TreeNode, data string) *TreeNode {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
func main() {
root := &TreeNode{data: "4"}
BTreeInsertData(root, "1")
BTreeInsertData(root, "7")
BTreeInsertData(root, "5")
fmt.Println(root.left.data)
fmt.Println(root.data)
fmt.Println(root.right.left.data)
fmt.Println(root.right.data)
}
```
And its output :
```console
student@ubuntu:~/piscine/btreeinsertdata$ go build
student@ubuntu:~/piscine/btreeinsertdata$ ./btreeinsertdata
1
4
5
7
student@ubuntu:~/piscine/btreeinsertdata$
```

20
subjects/btreeisbinary.md → subjects/btreeisbinary.en.md

@ -1,20 +1,20 @@
# btreeisbinary
## Instructions
## btreeisbinary
### Instructions
Write a function, BTreeIsBinary, that returns true only if the tree given by root follows the binary search tree properties.
This function must have the following signature.
## Expected function
### Expected function
```go
func BTreeIsBinary(root *TreeNode) bool {
}
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -22,8 +22,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -39,7 +39,7 @@ And its output :
```console
student@ubuntu:~/student/btreeisbinary$ go build
student@ubuntu:~/student/btreeisbinary$ ./btreeisbinary
student@ubuntu:~/student/btreeisbinary$ ./btreeisbinary
true
student@ubuntu:~/student/btreeisbinary$
student@ubuntu:~/student/btreeisbinary$
```

18
subjects/btreelevelcount.md → subjects/btreelevelcount.en.md

@ -1,18 +1,18 @@
# btreelevelcount
## Instructions
## btreelevelcount
Write a function, BTreeLevelCount, that return the number of levels of the tree (height of the tree)
### Instructions
## Expected function
Write a function, BTreeLevelCount, that return the number of levels of the tree (height of the tree)
### Expected function
```go
func BTreeLevelCount(root *piscine.TreeNode) int {
}
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -20,8 +20,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {

18
subjects/btreemax.md → subjects/btreemax.en.md

@ -1,20 +1,20 @@
# btreemax
## Instructions
## btreemax
### Instructions
Write a function, BTreeMax, that returns the node with the maximum value in the tree given by root
This function must have the following signature.
## Expected function
### Expected function
```go
func BTreeMax(root *TreeNode) *TreeNode {
}
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -22,8 +22,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -42,5 +42,5 @@ And its output :
student@ubuntu:~/student/btreemax$ go build
student@ubuntu:~/student/btreemax$ ./btreemax
7
student@ubuntu:~/student/btreemax$
student@ubuntu:~/student/btreemax$
```

18
subjects/btreemin.md → subjects/btreemin.en.md

@ -1,20 +1,20 @@
# btreemin
## Instructions
## btreemin
### Instructions
Write a function, BTreeMin, that returns the node with the minimum value in the tree given by root
This function must have the following signature.
## Expected function
### Expected function
```go
func BTreeMin(root *TreeNode) *TreeNode {
}
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -22,8 +22,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -42,5 +42,5 @@ And its output :
student@ubuntu:~/student/btreemin$ go build
student@ubuntu:~/student/btreemin$ ./btreemin
1
student@ubuntu:~/student/btreemin$
student@ubuntu:~/student/btreemin$
```

48
subjects/btreeprintroot.en.md

@ -0,0 +1,48 @@
## printroot
### Instructions
Write a function to print the value of the root node of a binary tree.
You have to create a new number and print the value of data
The nodes must be defined as follows:
### Expected function
```go
type TreeNode struct {
left, right *TreeNode
data string
}
func PrintRoot(root *TreeNode){
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
func main() {
//rootNode initialized with the value "who"
//rootNode1 initialized with the value "are"
//rootNode2 initialized with the value "you"
printRoot(rootNode)
printRoot(rootNode1)
printRoot(rootNode2)
}
```
And its output :
```console
student@ubuntu:~/piscine/printroot$ go build
student@ubuntu:~/piscine/printroot$ ./printroot
who
are
you
student@ubuntu:~/piscine/test$
```

74
subjects/btreesearchitem.en.md

@ -0,0 +1,74 @@
## btreeinsertdata
### Instructions
Write a function that searches for an item with a data element equal to elem and return that node
### Expected function
```go
func BTreeSearchItem(root *piscine_test.TreeNode, elem string) *piscine_test.TreeNode {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine "."
)
func main() {
root := &piscine_test.TreeNode{Data: "4"}
piscine_test.BTreeInsertData(root, "1")
piscine_test.BTreeInsertData(root, "7")
piscine_test.BTreeInsertData(root, "5")
selected := BTreeSearchItem(root, "7")
fmt.Print("Item selected -> ")
if selected != nil {
fmt.Println(selected.Data)
} else {
fmt.Println("nil")
}
fmt.Print("Parent of selected item -> ")
if selected.Parent != nil {
fmt.Println(selected.Parent.Data)
} else {
fmt.Println("nil")
}
fmt.Print("Left child of selected item -> ")
if selected.Left != nil {
fmt.Println(selected.Left.Data)
} else {
fmt.Println("nil")
}
fmt.Print("Right child of selected item -> ")
if selected.Right != nil {
fmt.Println(selected.Right.Data)
} else {
fmt.Println("nil")
}
}
```
And its output :
```console
student@ubuntu:~/piscine/btreesearchitem$ go build
student@ubuntu:~/piscine/btreesearchitem$ ./btreesearchitem
Item selected -> 7
Parent of selected item -> 4
Left child of selected item -> 5
Right child of selected item -> nil
student@ubuntu:~/piscine/btreesearchitem$
```

18
subjects/btreetransplant.md → subjects/btreetransplant.en.md

@ -1,20 +1,20 @@
# btreetransplant
## Instructions
## btreetransplant
### Instructions
In order to move subtrees around within the binary search tree, write a function, BTreeTransplant, which replaces the subtree started by node with the node called 'rplc' in the tree given by root.
This function must have the following signature.
## Expected function
### Expected function
```go
func BTreeTransplant(root, node, rplc *TreeNode) *TreeNode {
}
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -22,8 +22,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -47,5 +47,5 @@ student@ubuntu:~/student/btreetrandsplant$ ./btreetransplant
4
5
7
student@ubuntu:~/student/btreetrandsplant$
student@ubuntu:~/student/btreetrandsplant$
```

41
subjects/capitalize.en.md

@ -0,0 +1,41 @@
## capitalize
### Instructions
Write a function that capitalizes the first letter of each word **and** lowercases the rest of each word of a `string`.
A word is a sequence of **alphanumerical** characters.
### Expected function
```go
func Capitalize(s string) string {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.Capitalize("Hello! How are you? How+are+things+4you?"))
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
Hello! How Are You? How+Are+Things+4you?
student@ubuntu:~/piscine/test$
```

41
subjects/capitalize.fr.md

@ -0,0 +1,41 @@
## capitalize
### Instructions
Écrire une fonction qui met en majuscule la premiere lettre de chaque mot et en minuscule les autres lettres du reste du mot d'une `string`.
Un mot est une suite de caractères **alphanumériques**.
### Fonction attendue
```go
func Capitalize(s string) string {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.Capitalize("Hello! How are you? How+are+things+4you?"))
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
Hello! How Are You? How+Are+Things+4you?
student@ubuntu:~/piscine/test$
```

16
subjects/cat.md → subjects/cat.en.md

@ -1,26 +1,26 @@
# Cat
## Cat
## Instructions
### Instructions
Write a program that does the same thing as the system's `cat` command-line.
- You don't have to handle options.
- But if just call the program with out arguments it should take a input and print it back
- But if just call the program with out arguments it should take a input and print it back
- In the program folder create two files named `quest8.txt` and `quest8T.txt`.
- Copy to the `quest8.txt` file this :
- "Programming is a skill best acquired by pratice and example rather than from books" by Alan Turing
- Copy to the `quest8T.txt` file this :
- "Programming is a skill best acquired by pratice and example rather than from books" by Alan Turing
- "Alan Mathison Turing was an English mathematician, computer scientist, logician, cryptanalyst. Turing was highly influential in the development of theoretical computer science, providing a formalisation of the concepts of algorithm and computation with the Turing machine, which can be considered a model of a general-purpose computer. Turing is widely considered to be the father of theoretical computer science and artificial intelligence."
- Copy to the `quest8T.txt` file this :
- "Alan Mathison Turing was an English mathematician, computer scientist, logician, cryptanalyst. Turing was highly influential in the development of theoretical computer science, providing a formalisation of the concepts of algorithm and computation with the Turing machine, which can be considered a model of a general-purpose computer. Turing is widely considered to be the father of theoretical computer science and artificial intelligence."
- In case of error it should print the error.
## Output:
### Output:
```console
student@ubuntu:~/student/test$ go build

21
subjects/cl-camp1.en.md

@ -0,0 +1,21 @@
## cl-camp1
### Instructions
A little voice speaks in your head:
"Now that you know who you are. You need to remember what you can do..."
The instincts are coming back...
Put in a file `mastertheLS` the command line that will:
- list the files and folders of the current folder.
- Ignore the hidden files, the "." and the "..".
- Separates the resuls with commas.
- Order them by ascending order of creation date.
- Have the folders have a `/` in front of them.
### Hint
Read the man...

21
subjects/cl-camp1.fr.md

@ -0,0 +1,21 @@
## cl-camp1
### Instructions
Une petite voix dans votre esprit vous dit:
"Maintenant que tu sais qui tu es. Tu dois te souvenir de ce que tu peux faire..."
Les instincts resurgissent...
Mettez dans un fichier `mastertheLS` la ligne de commande qui:
- listera les fichiers et dossiers dans le dossier courant.
- Ignorera les fichiers cachés, le "." et le "..".
- Separarera le resultat avec des virgules.
- Les triera pas ordre croissant de date de création.
- Placera un `/` en face des dossiers.
### Indice
Lisez le man...

17
subjects/cl-camp2.en.md

@ -0,0 +1,17 @@
## cl-camp2
### Instructions
"keep training ..."
Create a file `r`, which shows `R` on a line when the `cat` command is executed
A line is a sequence of characters preceding the [end of line](https://en.wikipedia.org/wiki/Newline) character (`'\n'`).
### Usage
```console
student@ubuntu:~/piscine/test$ cat -e r
R$
student@ubuntu:~/piscine/test$
```

17
subjects/cl-camp2.fr.md

@ -0,0 +1,17 @@
## cl-camp2
### Instructions
"Continue l'entrainement ..."
Créez un fichier `r`, qui affiche `R` sur une ligne quand la commande `cat` command est exécutée.
Une ligne est une suite de caractères précédant le caractère [fin de ligne](https://en.wikipedia.org/wiki/Newline) (`'\n'`).
### Utilisation
```console
student@ubuntu:~/piscine/test$ cat -e r
R$
student@ubuntu:~/piscine/test$
```

15
subjects/cl-camp3.en.md

@ -0,0 +1,15 @@
## cl-camp3
### Instructions
"start looking ..."
Create a file `look`, which will look for and show, in the current directory and its sub-folders all the files :
- starting with an `a` and,
- all the files ending with a `z` and,
- all files starting with `z` and ending with `a!`.
### Hint
Read the `find` man...

15
subjects/cl-camp3.fr.md

@ -0,0 +1,15 @@
## cl-camp3
### Instructions
"commences à chercher ..."
Créer un fichier `look`, qui cherchera et montrera, dans le répertoire courant et ses sous-répertoires, tous les fichiers qui:
- commence avec `a` et,
- tous les fichiers qui se terminent avec `z` et,
- tous les fichiers qui commencent avec `z` et qui se finissenLisezele man dea!`.
#Indice
Lisez le man de `find`...

24
subjects/cl-camp4.en.md

@ -0,0 +1,24 @@
## cl-camp4
### Instructions
"someone familiar"
Create a file `myfamily.sh`, which will show a subject's family (key: relatives).
- The quotes have to be removed.
- The subject will be decided depending on his ID which will be contained in the environment variable HERO_ID.
* Where to look : https://raw.githubusercontent.com/kigiri/superhero-api/master/api/all.json
* What to use : curl, jq and others...
### Usage
```console
student@ubuntu:~/piscine/test$ export HERO_ID=1
student@ubuntu:~/piscine/test$ ./myfamily.sh
Marlo Chandler-Jones (wife); Polly (aunt); Mrs. Chandler (mother-in-law); Keith Chandler, Ray Chandler, three unidentified others (brothers-in-law); unidentified father (deceased); Jackie Shorr (alleged mother; unconfirmed)
student@ubuntu:~/piscine/test$
```

24
subjects/cl-camp4.fr.md

@ -0,0 +1,24 @@
## cl-camp4
### Instructions
"quelqu'un de familier"
Créer un fichier `myfamily.sh`, qui montrera qui affichera la famille d'un individu (clef: relatives).
- Les guillemets doivent être enlevés.
- L'invidu sera choisi en fonction de son ID qui sera contenu dans la variable d'environment HERO_ID.
* Où chercher : https://raw.githubusercontent.com/kigiri/superhero-api/master/api/all.json
* Quoi utiliser : `curl`, `jq` et d'autres...
### Utilisation
```console
student@ubuntu:~/piscine/test$ export HERO_ID=1
student@ubuntu:~/piscine/test$ ./myfamily.sh
Marlo Chandler-Jones (wife); Polly (aunt); Mrs. Chandler (mother-in-law); Keith Chandler, Ray Chandler, three unidentified others (brothers-in-law); unidentified father (deceased); Jackie Shorr (alleged mother; unconfirmed)
student@ubuntu:~/piscine/test$
```

26
subjects/cl-camp5.en.md

@ -0,0 +1,26 @@
## cl-camp5
### Instructions
"keep looking..."
Create a file `lookagain.sh`, which will look for, from the current directory and its sub-folders all the files:
- all the files ending with `.sh`.
That command will only show the name of the files without the `.sh`.
### Usage
```console
student@ubuntu:~/piscine/test$ export HERO_ID=1
student@ubuntu:~/piscine/test$ ./lookagain.sh | cat -e
file1$
file2$
file3$
student@ubuntu:~/piscine/test$
```
### Hint
A little `cut`ing might be useful...

26
subjects/cl-camp5.fr.md

@ -0,0 +1,26 @@
## cl-camp5
### Instructions
"continues à chercher..."
Créer un fichier `lookagain.sh`, qui cherchera et montrera, dans le répertoire courant et ses sous-répertoires, tous les fichiers qui:
- qui finissent avec `.sh`.
Cette commande montrera le nom des fichiers sans le`.sh`.
### Utilisation
```console
student@ubuntu:~/piscine/test$ export HERO_ID=1
student@ubuntu:~/piscine/test$ ./lookagain.sh | cat -e
file1$
file2$
file3$
student@ubuntu:~/piscine/test$
```
### Indice
Un petit `cut`ter pourrait être utile...

15
subjects/cl-camp6.en.md

@ -0,0 +1,15 @@
## cl-camp6
### Instructions
"Now, do your inventory"
Create a file `countfiles.sh`, which will print the number **(and only the number)** of regular files and folders cointaned in the current directory and its sub-folders :
### Usage
```console
student@ubuntu:~/piscine/test$ ./countfiles.sh | cat -e
12$
student@ubuntu:~/piscine/test$
```

15
subjects/cl-camp6.fr.md

@ -0,0 +1,15 @@
## cl-camp6
### Instructions
"Maintenant, fais ton inventaire"
Créer un fichier `countfiles.sh`, qui affichera will lenombre **(et seulement le nombre)** de fichiers réguliers et répertoires contenu dans le répertoire courant et ses sous-répertoires :
### Utilisation
```console
student@ubuntu:~/piscine/test$ ./countfiles.sh | cat -e
12$
student@ubuntu:~/piscine/test$
```

15
subjects/cl-camp7.en.md

@ -0,0 +1,15 @@
## cl-camp7
### Instructions
"Be accurate"
Create a file `"\?$*'ChouMi'*$?\"` that will contain "01" and **nothing else**.
### Usage
```console
student@ubuntu:~/piscine/test$ ls | cat -e
"\?$*'ChouMi'*$?\" $
student@ubuntu:~/piscine/test$
```

15
subjects/cl-camp7.fr.md

@ -0,0 +1,15 @@
## cl-camp7
### Instructions
"Sois précis"
Créer un fichier `"\?$*'ChouMi'*$?\"` qui contiendra "01" et **rien d'autre**.
### Utilisation
```console
student@ubuntu:~/piscine/test$ ls | cat -e
"\?$*'ChouMi'*$?\" $
student@ubuntu:~/piscine/test$
```

11
subjects/cl-camp8.en.md

@ -0,0 +1,11 @@
## cl-camp8
### Instructions
"pick your equipment"
Write a command line in a `skip.sh` file that prints the result of a `ls -l` skipping 1 line out of 2, starting with the **first** one.
### Hint
`awk` or `sed` can do the job.

11
subjects/cl-camp8.fr.md

@ -0,0 +1,11 @@
## cl-camp8
### Instructions
"Choisis ton équipement"
écrire une ligne dans un fichier `skip.sh` qui affiche le résultat d'un `ls -l` qui saute 1 ligne sur 2, en commençant pas la **première**.
### Indice
`awk` ou `sed` peuvent faire le travail.

21
subjects/cl.en.md

@ -0,0 +1,21 @@
## cl-camp1
### Instructions
A little voice speaks in your head:
"Now that you know who you are. You need to remember what you can do..."
The instincts are coming back...
Put in a file `mastertheLS` the command line that will:
- list the files and folders of the current folder.
- Ignore the hidden files, the "." and the "..".
- Separates the resuls with commas.
- Order them by ascending order of creation date.
- Have the folders have a `/` in front of them.
### Hint
Read the man...

18
subjects/collatzcountdown.md → subjects/collatzcountdown.en.md

@ -1,20 +1,20 @@
# collatzcountdown
## Instructions
## collatzcountdown
### Instructions
Write a function, CollatzCountdown, that returns the number of steps to reach 1 using the collatz countdown.
The function must have the following signature.
## Expected function
### Expected function
```go
func CollatzCountdown(start int) int {
}
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -22,8 +22,8 @@ Here is a possible [program](TODO-LINK) to test your function :
package main
import (
"fmt"
student ".."
"fmt"
student ".."
)
func main() {
@ -38,5 +38,5 @@ And its output :
student@ubuntu:~/student/collatzcountdown$ go build
student@ubuntu:~/student/collatzcountdown$ ./collatzcountdown
10
student@ubuntu:~/student/collatzcountdown$
student@ubuntu:~/student/collatzcountdown$
```

9
subjects/comcheck.md → subjects/comcheck.en.md

@ -1,19 +1,20 @@
# ROT 14
## ROT 14
## Instructions
### Instructions
Write a function `rot14` that returns the string within the parameter but transformed into a rot14 string.
- If you not certain what we are talking about, there is a rot13 already.
## Expected function
### Expected function
```go
func rot14(str string) string {
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :

114
subjects/commandments.en.md

@ -0,0 +1,114 @@
---
tier: 0
team: 1
duration: 1 hour
objectives: reading the rules
skills: git, github, reading
---
## commandments
A few basic principles to follow
<p align="center">
<img width="476" height="600" src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/MCC-31231_Mozes_toont_de_wetstafelen_%281%29.tif/lossy-page1-476px-MCC-31231_Mozes_toont_de_wetstafelen_%281%29.tif.jpg">
</p>
### The Commandements _(read them)_
- Le numérique est ta passion.
- Ton objectif à 42 : développer ton talent et tes compétences pour le marché du numérique.
- L’objectif de 42 pour toi : te faire accéder au marché de l’emploi, à une longue et pérenne carrière dans le numérique, et te faire progresser socialement.
- L’ambition de 42 pour toi : être un pionnier du numérique de demain.
- Il est de ta responsabilité de gérer ta progression : 42 te propose un parcours individualisé adapté à ton rythme.
- Des challenges jalonnent ton parcours. 42 ne fournira aucun élément de solution. C’est ton rôle de chercher et trouver par toi-même ces solutions pour atteindre l’objectif.
- Sois actif. N’attend pas que les choses se fassent pour toi. 42 est un parcours 100% pratique.
- Sois autonome dans ton cursus. N’attend pas que l’on te dise quoi faire.
- Sois collaboratif, autant sur les projets solos que les projets de groupe. Face aux challenges à resoudre, l’échange et le debat sont tes meilleures armes.
- Ne "crois" pas. Sois sûr. Techniquement, relationnelement, organisationellement, administrativement.
- Pour être sûr, teste, contrôle.
- N’ai pas peur de te tromper, d’échouer. L’échec est une étape normale vers le succès.
- Teste à nouveau. Collabore davantage pour tester davantage.
- Ose. Le risque est de se tromper. Voir le commandement 12.
- Sois rigoureux dans ton travail.
- Sois investi dans ton cursus : 50 heures par semaine est un minimum. Ta capacité de travail est une valeur. L’école est ouverte 24h/24 et 7j/7.
- Sois régulier dans ton travail. Un jour oui, un jour non, un coup nocturne, un coup diurne... le chaos t’empêche d’avancer.
- Prévois un groupe de travail large et hétérogène pour y trouver facilement des idées neuves et des groupes de projet.
- Pour tes collaborations et ton travail en groupe, privilégie des étudiants qui n’ont pas déjà la solution au problème.
- Sois investi dans ton groupe de projet, et ne le laisse pas faire ton travail à ta place.
- Ton groupe de projet est solidaire, son succès comme son échec est de la responsabilité de tous, et les conflits se règlent en interne.
- Travaille à l’école. Faire du peer-learning, collaborer, cela demande d’être physiquement avec les autres. A distance cela ne fonctionne pas.
- Implique toi dans les évaluations de tes projets. Elles te permettent de prendre du recul.
- Implique toi dans tes évaluations des projets des autres. La qualité de la communauté en dépend.
- Sois juste et teste rigoureusement tes projets comme ceux des autres en évaluation avec tes propres jeux de tests.
- Joue pleinement le jeu de ta scolarité dans l’état d’esprit demandé, fait tous les exercices et projets demandés.
- Ne cherche pas des biais et des failles dans le système. Tu vas fausser ta propre formation et ta valeur sur le marché.
- Ne triche pas intentionellement. C’est amoral, cela contredit le commandement 12, et c’est du temps inutilement passé à ne pas développer tes compétences pour faire croire aux autres que tu sais coder alors que ce n’est pas le cas.
- Ne rends pas un projet que tu ne serais pas capable de reproduire seul à huis clos. Même si c’est parfois involontaire, c’est aussi de la triche.
- C’est pas pour tes parents que tu travailles, ni pour le staff. C’est pour toi.
- Participe à la vie de la communauté, à son épanouissement, et sa qualité en sortie de formation.
- Aide au respect de ces commandements par la communauté.
- Sois bienveillant et empathique vis à vis de tes camarades comme des personnes avec qui tu interagis, échanges, débats.
- N’ai pas peur du monde professionnel.
- Respecte le matériel. Des consignes spécifiques sont données en ce sens.
- Respecte les locaux. Des consignes spécifiques sont données en ce sens.
- Respecte les gens, étudiants, staffs, partenaires, visiteurs.
- Respecte la loi en vigueur dans le pays.
- Respecte les lois et consignes en vigueur liées à la consommation d’alcool.
- Respecte les lois et consignes en vigueur liées à la consommation de tabac, stupéfiants, ou produits assimilés.
- N’hésite pas à interagir avec le staff, pour parler de tes problèmes, pour remonter des problèmes dans le cursus, pour contribuer au cursus.
- Si tu t’interroges ou ne comprends pas nos choix pédagogiques, demande nous. On ne fait généralement rien au hasard.
### Required
You [clone](http://lmgtfy.com/?q=git+clone) your [fork](http://lmgtfy.com/?q=github+fork) of this [repository](http://lmgtfy.com/?q=git+repository)
and in it, you must create a file named `turn_in` () in which you write EXACTLY the following sentence ending by a line break.
<p align="center">
<img width="600" height="300" src="https://i.imgur.com/2PPQ2iZ.png">
</p>
### Submiting your solution
Your work should be commited and pushed in the master branch of your own fork of this repository.

12
subjects/compact.md → subjects/compact.en.md

@ -1,19 +1,20 @@
# Compact
## Compact
## Instructions
### Instructions
Write a function that will take a pointer to a array as parameter and overwrites any element that points to `nil`.
- If you not sure what the function does. It exists in Ruby.
- If you not sure what the function does. It exists in Ruby.
## Expected functions
### Expected functions
```go
func Compact(ptr *[]string, length int) int {
}
```
## Usage
### Usage
Here is a possible [program](TODO-LINK) to test your function :
@ -28,7 +29,6 @@ func main() {
ptr := &array
fmt.Println(Compact(ptr, len(array)))
}
```
And its output :

43
subjects/compare.en.md

@ -0,0 +1,43 @@
## compare
### Instructions
Write a function that behaves like the [`Compare`](https://golang.org/pkg/strings/#Compare) function.
### Expected function
```go
func Compare(a, b string) int {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.Compare("Hello!", "Hello!"))
fmt.Println(piscine.Compare("Salut!", "lut!"))
fmt.Println(piscine.Compare("Ola!", "Ol"))
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
0
-1
1
student@ubuntu:~/piscine/test$
```

43
subjects/compare.fr.md

@ -0,0 +1,43 @@
## compare
### Instructions
Écrire une fonction qui se comporte comme la fonction [`Compare`](https://golang.org/pkg/strings/#Compare).
### Fonction attendue
```go
func Compare(a, b string) int {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.Compare("Hello!", "Hello!"))
fmt.Println(piscine.Compare("Salut!", "lut!"))
fmt.Println(piscine.Compare("Ola!", "Ol"))
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
0
-1
1
student@ubuntu:~/piscine/test$
```

40
subjects/concat.en.md

@ -0,0 +1,40 @@
## concat
### Instructions
Write a function that returns the concatenation of two `string` passed in arguments.
### Expected function
```go
func Concat(str1 string, str2 string) string {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.Concat("Hello!", " How are you?"))
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
Hello! How are you?
student@ubuntu:~/piscine/test$
```

40
subjects/concat.fr.md

@ -0,0 +1,40 @@
## concat
### Instructions
Écrire une fonction qui retourne la concaténation de deux `string` passées en paramètres.
### Fonction attendue
```go
func Concat(str1 string, str2 string) string {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
fmt.Println(piscine.Concat("Hello!", " How are you?"))
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
Hello! How are you?
student@ubuntu:~/piscine/test$
```

44
subjects/concatparams.en.md

@ -0,0 +1,44 @@
## concatparams
### Instructions
Write a function that takes the arguments reveived in parameters and returns them as a `string`.
The arguments must be **separated** by a `\n`.
### Expected function
```go
func ConcatParams(args []string) string {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
test := []string{"Hello", "how", "are", "you?"}
fmt.Println(piscine.ConcatParams(test))
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
Hello
how
are
you?
student@ubuntu:~/piscine/test$
```

44
subjects/concatparams.fr.md

@ -0,0 +1,44 @@
## concatparams
### Instructions
Écrire une fonction qui prend les arguments en paramètres et les retournes dans une `string`.
Les arguments doivent être **séparés** par un `\n`.
### Fonction attendue
```go
func ConcatParams(args []string) string {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
test := []string{"Hello", "how", "are", "you?"}
fmt.Println(piscine.ConcatParams(test))
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
Hello
how
are
you?
student@ubuntu:~/piscine/test$
```

43
subjects/convertbase.en.md

@ -0,0 +1,43 @@
## convertbase
### Instructions
Write a function that returns the convertion of a `string` number from one `string` baseFrom to one `string` baseTo.
Only valid bases will be tested.
Negative numbers will not be tested.
### Expected function
```go
func ConvertBase(nbr, baseFrom, baseTo string) string {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
result := piscine.ConvertBase("101011", "01", "0123456789")
fmt.Println(result)
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
43
student@ubuntu:~/piscine/test$
```

43
subjects/convertbase.fr.md

@ -0,0 +1,43 @@
## convertbase
### Instructions
Écrire une fonction qui retourne la convertion d'un nombre `string` d'une baseFrom `string` à une baseTo `string`.
Seules des bases valides seront testées.
Les nombres négatifs ne seront pas testés.
### Fonction attendue
```go
func ConvertBase(nbr, baseFrom, baseTo string) string {
}
```
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
result := piscine.ConvertBase("101011", "01", "0123456789")
fmt.Println(result)
}
```
Et son résultat :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
43
student@ubuntu:~/piscine/test$
```

10
subjects/countdown.md → subjects/countdown.en.md

@ -1,17 +1,17 @@
# countdown
## countdown
## Instructions
### Instructions
Write a program that displays all digits in descending order, followed by a
newline.
## Expected main and function for the program
### Expected main and function for the program
## Expected output
### Expected output
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
9876543210
student@ubuntu:~/piscine/test$
```
```

44
subjects/countif.en.md

@ -0,0 +1,44 @@
## countif
### Instructions
Write a function `CountIf` that returns the number of elements of a `string` array for which the `f` function returns `true`.
### Expected function
```go
func CountIf(f func(string) bool, tab []string) int {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
piscine ".."
)
func main() {
tab1 := []string{"Hello", "how", "are", "you"}
tab2 := []string{"This","1", "is", "4", "you"}
answer1 := piscine.CountIf(piscine.IsNumeric, tab1)
answer2 := piscine.CountIf(piscine.IsNumeric, tab2)
fmt.Println(answer1)
fmt.Println(answer2)
}
```
And its output :
```console
student@ubuntu:~/piscine/test$ go build
student@ubuntu:~/piscine/test$ ./test
0
2
student@ubuntu:~/piscine/test$
```

Some files were not shown because too many files changed in this diff diff.show_more

Loading…
Cancel
Save